@turinhub/atomix-common-ui 0.4.0 → 0.5.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.
- package/README.md +20 -2
- package/dist/AuthPanel-C_2JBE7t.cjs +2 -0
- package/dist/AuthPanel-C_2JBE7t.cjs.map +1 -0
- package/dist/AuthPanel-D2HFX8eN.js +656 -0
- package/dist/AuthPanel-D2HFX8eN.js.map +1 -0
- package/dist/auth.cjs +2 -0
- package/dist/auth.cjs.map +1 -0
- package/dist/auth.d.ts +11 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +9 -0
- package/dist/auth.js.map +1 -0
- package/dist/components/AuthLoginPanel.d.ts +55 -0
- package/dist/components/AuthLoginPanel.d.ts.map +1 -0
- package/dist/components/AuthPageShell.d.ts +11 -0
- package/dist/components/AuthPageShell.d.ts.map +1 -0
- package/dist/components/AuthPanel.d.ts +20 -0
- package/dist/components/AuthPanel.d.ts.map +1 -0
- package/dist/components/AuthRegisterPanel.d.ts +34 -0
- package/dist/components/AuthRegisterPanel.d.ts.map +1 -0
- package/dist/components/AuthVisualCarousel.d.ts +20 -0
- package/dist/components/AuthVisualCarousel.d.ts.map +1 -0
- package/dist/components/DataTable.d.ts +2 -2
- package/dist/components/DataTable.d.ts.map +1 -1
- package/dist/components/ImageReader.d.ts +44 -0
- package/dist/components/ImageReader.d.ts.map +1 -0
- package/dist/components/VideoReader.d.ts +39 -0
- package/dist/components/VideoReader.d.ts.map +1 -0
- package/dist/components/media-utils.d.ts +9 -0
- package/dist/components/media-utils.d.ts.map +1 -0
- package/dist/data-table.cjs +1 -1
- package/dist/data-table.cjs.map +1 -1
- package/dist/data-table.js +83 -73
- package/dist/data-table.js.map +1 -1
- package/dist/image-reader.cjs +2 -0
- package/dist/image-reader.cjs.map +1 -0
- package/dist/image-reader.d.ts +3 -0
- package/dist/image-reader.d.ts.map +1 -0
- package/dist/image-reader.js +214 -0
- package/dist/image-reader.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/media-utils-5UPuocc1.js +23 -0
- package/dist/media-utils-5UPuocc1.js.map +1 -0
- package/dist/media-utils-X1dDYP9W.cjs +2 -0
- package/dist/media-utils-X1dDYP9W.cjs.map +1 -0
- package/dist/pdf-reader.cjs +1 -1
- package/dist/pdf-reader.cjs.map +1 -1
- package/dist/pdf-reader.js +1 -1
- package/dist/pdf-reader.js.map +1 -1
- package/dist/simple-pdf-reader.cjs +1 -1
- package/dist/simple-pdf-reader.cjs.map +1 -1
- package/dist/simple-pdf-reader.js +1 -1
- package/dist/simple-pdf-reader.js.map +1 -1
- package/dist/types/component-types.d.ts +1 -0
- package/dist/types/component-types.d.ts.map +1 -1
- package/dist/video-reader.cjs +2 -0
- package/dist/video-reader.cjs.map +1 -0
- package/dist/video-reader.d.ts +3 -0
- package/dist/video-reader.d.ts.map +1 -0
- package/dist/video-reader.js +158 -0
- package/dist/video-reader.js.map +1 -0
- package/package.json +31 -1
- package/dist/index-BiA_tnaq.cjs +0 -13
- package/dist/index-BiA_tnaq.cjs.map +0 -1
- package/dist/index-BypbGNpR.js +0 -18821
- package/dist/index-BypbGNpR.js.map +0 -1
package/dist/pdf-reader.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pdf-reader.cjs","sources":["../src/components/PDFReader.tsx"],"sourcesContent":["import {\n ChevronLeft as ChevronLeftIcon,\n ChevronRight as ChevronRightIcon,\n FileText as FileTextIcon,\n Maximize2 as Maximize2Icon,\n Minimize2 as Minimize2Icon,\n PanelLeft as PanelLeftIcon,\n RotateCw as RotateCwIcon,\n ScrollText as ScrollTextIcon,\n ZoomIn as ZoomInIcon,\n ZoomOut as ZoomOutIcon,\n} from 'lucide-react';\nimport { useState, useCallback, useEffect, useMemo, useRef } from 'react';\nimport type { HTMLAttributes } from 'react';\n\nimport type {\n CardComponent,\n ButtonComponent,\n InputComponent,\n SkeletonComponent,\n} from '../types/component-types';\n\nimport type { PDFDocumentProxy } from './PDFSidebar';\nimport { PDFSidebar } from './PDFSidebar';\n\n/**\n * PDFReader UI 组件接口\n */\nexport interface PDFReaderUIComponents {\n /** Card 组件 (必需) */\n Card: CardComponent;\n /** CardContent 组件 (必需) */\n CardContent: React.ComponentType<HTMLAttributes<HTMLDivElement>>;\n /** Button 组件 (必需) */\n Button: ButtonComponent;\n /** Input 组件 (必需) */\n Input: InputComponent;\n /** Skeleton 组件 (必需) */\n Skeleton: SkeletonComponent;\n /** Tabs 组件 (showSidebar=true 时必需) */\n Tabs?: React.ComponentType<{\n value?: string;\n onValueChange?: (value: string) => void;\n children?: React.ReactNode;\n defaultValue?: string;\n }>;\n /** TabsList 组件 (showSidebar=true 时必需) */\n TabsList?: React.ComponentType<HTMLAttributes<HTMLDivElement>>;\n /** TabsTrigger 组件 (showSidebar=true 时必需) */\n TabsTrigger?: React.ComponentType<{\n value: string;\n children?: React.ReactNode;\n }>;\n /** TabsContent 组件 (showSidebar=true 时必需) */\n TabsContent?: React.ComponentType<{\n value: string;\n children?: React.ReactNode;\n }>;\n /** ScrollArea 组件 (showSidebar=true 时必需) */\n ScrollArea?: React.ComponentType<HTMLAttributes<HTMLDivElement>>;\n}\n\n/**\n * PDFReader 组件 Props\n */\nexport interface PDFReaderProps {\n // ==================== 基础配置 ====================\n /** PDF 文件 URL (必需) */\n url: string;\n\n // ==================== 初始状态 ====================\n /** 初始页码 (默认 1) */\n initialPage?: number;\n /** 初始缩放比例 (默认 1.0) */\n initialScale?: number;\n /** 初始旋转角度 (默认 0) */\n initialRotation?: number;\n\n // ==================== 受控模式 ====================\n /** 当前页码 (受控) */\n currentPage?: number;\n /** 页码变化回调 */\n onPageChange?: (page: number) => void;\n /** 缩放比例 (受控) */\n scale?: number;\n /** 缩放变化回调 */\n onScaleChange?: (scale: number) => void;\n /** 旋转角度 (受控) */\n rotation?: number;\n /** 旋转变化回调 */\n onRotationChange?: (rotation: number) => void;\n\n // ==================== 缩放限制 ====================\n /** 最小缩放比例 (默认 0.5) */\n minScale?: number;\n /** 最大缩放比例 (默认 2.5) */\n maxScale?: number;\n\n // ==================== 功能开关 ====================\n /** 显示工具栏 (默认 true) */\n showToolbar?: boolean;\n /** 显示侧边栏 (默认 true) */\n showSidebar?: boolean;\n /** 显示旋转按钮 (默认 true) */\n showRotation?: boolean;\n /** 显示模式切换按钮 (默认 true) */\n showModeToggle?: boolean;\n /** 显示全屏按钮 (默认 true) */\n showFullscreen?: boolean;\n /** 启用键盘快捷键 (默认 true) */\n enableHotkeys?: boolean;\n /** 启用移动端导航 (默认 true) */\n enableMobileNav?: boolean;\n\n // ==================== 显示模式 ====================\n /** 显示模式: 'scroll' 显示所有页面, 'single' 单页模式 (默认 'single') */\n displayMode?: 'scroll' | 'single';\n\n // ==================== 样式定制 ====================\n /** 容器类名 */\n className?: string;\n /** 工具栏类名 */\n toolbarClassName?: string;\n /** 内容区域类名 */\n contentClassName?: string;\n /** 阅读区域高度限制 (默认 '80vh') */\n contentHeight?: string | number;\n /** 页面类名 */\n pageClassName?: string;\n\n // ==================== Worker 配置 ====================\n /** Worker 文件 URL (可选,默认使用 CDN) */\n workerUrl?: string;\n /** CMap 文件 URL (可选,默认使用 CDN) */\n cMapUrl?: string;\n /** 标准字体数据 URL (可选,默认使用 CDN) */\n standardFontDataUrl?: string;\n\n // ==================== UI 组件注入 ====================\n /** UI 组件 */\n components: PDFReaderUIComponents;\n\n // ==================== 回调函数 ====================\n /** 加载成功回调 */\n onLoadSuccess?: (pdf: PDFDocumentProxy) => void;\n /** 加载错误回调 */\n onLoadError?: (error: Error) => void;\n /** 页面渲染回调 */\n onPageRender?: (pageIndex: number) => void;\n\n // ==================== 文本配置 ====================\n /** 加载文本 (默认 '正在加载PDF文档...') */\n loadingText?: string;\n /** 错误文本 (默认 'PDF加载失败') */\n errorText?: string;\n}\n\n/**\n * debounce hook (替代 lodash.debounce)\n */\nfunction useDebounce<T extends (...args: any[]) => any>(\n callback: T,\n delay: number\n): T {\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined\n );\n return useCallback(\n (...args: Parameters<T>) => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n timeoutRef.current = setTimeout(() => callback(...args), delay);\n },\n [callback, delay]\n ) as T;\n}\n\n/**\n * PDFReader 组件\n *\n * 功能完整的 PDF 阅读器组件,支持侧边栏导航、页面旋转、显示模式切换等高级特性。\n *\n * @example\n * ```tsx\n * import { PDFReader } from '@turinhub/atomix-common-ui/pdf-reader';\n * import { Card, Button, Input, Label, Skeleton } from '@/components/ui';\n * import { Tabs, ScrollArea } from '@/components/ui';\n *\n * <PDFReader\n * url=\"/documents/sample.pdf\"\n * components={{\n * Card,\n * CardContent: Card.Content,\n * Button,\n * Input,\n * Label,\n * Skeleton,\n * Tabs,\n * TabsList: Tabs.List,\n * TabsTrigger: Tabs.Trigger,\n * TabsContent: Tabs.Content,\n * ScrollArea,\n * }}\n * initialPage={1}\n * initialScale={1.0}\n * showSidebar={true}\n * showRotation={true}\n * showModeToggle={true}\n * enableHotkeys={true}\n * />\n * ```\n */\nexport function PDFReader({\n url,\n initialPage = 1,\n initialScale = 1.0,\n initialRotation = 0,\n currentPage: controlledPage,\n onPageChange,\n scale: controlledScale,\n onScaleChange,\n rotation: controlledRotation,\n onRotationChange,\n minScale = 0.5,\n maxScale = 2.5,\n showToolbar = true,\n showSidebar = true,\n showRotation = true,\n showModeToggle = true,\n showFullscreen = true,\n enableHotkeys = true,\n enableMobileNav = true,\n displayMode: initialDisplayMode = 'single',\n className,\n toolbarClassName,\n contentClassName,\n contentHeight = '80vh',\n pageClassName,\n workerUrl,\n cMapUrl,\n standardFontDataUrl,\n components,\n onLoadSuccess,\n onLoadError,\n onPageRender,\n loadingText = '正在加载PDF文档...',\n errorText = 'PDF加载失败',\n}: PDFReaderProps) {\n // ==================== 状态管理 ====================\n const [pdfDocument, setPdfDocument] = useState<PDFDocumentProxy | null>(null);\n const [internalPage, setInternalPage] = useState(initialPage);\n const [internalScale, setInternalScale] = useState(initialScale);\n const [internalRotation, setInternalRotation] = useState(initialRotation);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [totalPages, setTotalPages] = useState(0);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const [showAllPages, setShowAllPages] = useState(\n initialDisplayMode === 'scroll'\n );\n const [showSidebarState, setShowSidebarState] = useState(showSidebar);\n\n // Sync showSidebarState with prop changes\n useEffect(() => {\n setShowSidebarState(showSidebar);\n }, [showSidebar]);\n\n const [pageWidth, setPageWidth] = useState<number | undefined>(undefined);\n\n // 动态导入 react-pdf\n const [ReactPDF, setReactPDF] = useState<any>(null);\n\n const readerRef = useRef<HTMLDivElement>(null);\n const pdfContainerRef = useRef<HTMLDivElement>(null);\n const pageRefs = useRef<Map<number, HTMLDivElement>>(new Map());\n\n // 使用受控或非受控模式\n const currentPage = controlledPage ?? internalPage;\n const scale = controlledScale ?? internalScale;\n const rotation = controlledRotation ?? internalRotation;\n const isPageControlled = controlledPage !== undefined;\n const isScrollMode = showAllPages;\n\n // ==================== 组件解构 ====================\n const { Card, CardContent, Button, Input, Skeleton } = components || {};\n\n useEffect(() => {\n setPdfDocument(null);\n setTotalPages(0);\n setError(null);\n setIsLoading(false);\n if (!isPageControlled) {\n setInternalPage(Math.max(1, initialPage));\n }\n }, [url, initialPage, isPageControlled]);\n\n // ==================== PDF 选项 ====================\n const pdfOptions = useMemo(() => {\n const options: Record<string, unknown> = {\n withCredentials: false,\n };\n\n if (cMapUrl) {\n options.cMapUrl = cMapUrl;\n options.cMapPacked = true;\n }\n\n if (standardFontDataUrl) {\n options.standardFontDataUrl = standardFontDataUrl;\n }\n\n return options;\n }, [cMapUrl, standardFontDataUrl]);\n\n // ==================== 动态导入 react-pdf ====================\n useEffect(() => {\n let isMounted = true;\n\n const loadReactPDF = async () => {\n try {\n // 动态导入 react-pdf\n const pdfModule = await import('react-pdf');\n\n // 设置 worker\n if (typeof window !== 'undefined') {\n const pdfjs = (pdfModule as any).pdfjs;\n const workerVersion = pdfjs?.version;\n\n if (pdfjs?.GlobalWorkerOptions && workerVersion) {\n if (workerUrl) {\n pdfjs.GlobalWorkerOptions.workerSrc = workerUrl;\n } else {\n // 使用 CDN\n pdfjs.GlobalWorkerOptions.workerSrc = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${workerVersion}/build/pdf.worker.min.mjs`;\n }\n\n // 如果没有提供自定义 URL,使用 CDN 默认值\n if (!cMapUrl && pdfjs.GlobalWorkerOptions) {\n (pdfjs.GlobalWorkerOptions as any).cMapUrl =\n `https://unpkg.com/pdfjs-dist@${workerVersion}/cmaps/`;\n }\n if (!standardFontDataUrl && pdfjs.GlobalWorkerOptions) {\n (pdfjs.GlobalWorkerOptions as any).standardFontDataUrl =\n `https://unpkg.com/pdfjs-dist@${workerVersion}/standard_fonts/`;\n }\n }\n }\n\n if (isMounted) {\n setReactPDF(pdfModule);\n }\n } catch (err) {\n if (isMounted) {\n const loadError =\n err instanceof Error ? err : new Error('无法加载 react-pdf 库');\n setError(loadError);\n setIsLoading(false);\n onLoadError?.(loadError);\n }\n }\n };\n\n loadReactPDF();\n\n return () => {\n isMounted = false;\n };\n }, [workerUrl, cMapUrl, standardFontDataUrl, onLoadError]);\n\n // ==================== 处理加载错误 ====================\n const onDocumentLoadError = useCallback(\n (err: Error) => {\n console.error('PDF加载失败:', err);\n console.error('PDF URL:', url);\n setPdfDocument(null);\n setTotalPages(0);\n setError(\n new Error(`${errorText}: ${err.message || '请检查文件路径或网络连接'}`)\n );\n setIsLoading(false);\n onLoadError?.(err);\n },\n [url, errorText, onLoadError]\n );\n\n const onDocumentLoadSuccess = useCallback(\n (pdf: PDFDocumentProxy) => {\n setPdfDocument(pdf);\n setTotalPages(pdf.numPages);\n setError(null);\n setIsLoading(false);\n\n if (!isPageControlled) {\n setInternalPage((page) =>\n Math.max(1, Math.min(page, Math.max(pdf.numPages, 1)))\n );\n }\n\n onLoadSuccess?.(pdf);\n },\n [isPageControlled, onLoadSuccess]\n );\n\n // ==================== 页面导航 ====================\n const goToPage = useCallback(\n (page: number) => {\n if (!Number.isFinite(page)) return;\n const newPage =\n totalPages > 0\n ? Math.max(1, Math.min(Math.trunc(page), totalPages))\n : Math.max(1, Math.trunc(page));\n if (!isPageControlled) {\n setInternalPage(newPage);\n }\n if (newPage !== currentPage) {\n onPageChange?.(newPage);\n }\n },\n [totalPages, isPageControlled, currentPage, onPageChange]\n );\n\n const setPageRef = useCallback(\n (pageNumber: number, element: HTMLDivElement | null) => {\n if (element) {\n pageRefs.current.set(pageNumber, element);\n } else {\n pageRefs.current.delete(pageNumber);\n }\n },\n []\n );\n\n const syncScrollModeCurrentPage = useCallback(() => {\n const container = pdfContainerRef.current;\n if (!container || !isScrollMode || totalPages <= 0) return;\n\n const containerTop = container.getBoundingClientRect().top;\n let closestPage = currentPage;\n let closestDistance = Number.POSITIVE_INFINITY;\n\n pageRefs.current.forEach((element, pageNumber) => {\n const distance = Math.abs(\n element.getBoundingClientRect().top - containerTop\n );\n if (distance < closestDistance) {\n closestDistance = distance;\n closestPage = pageNumber;\n }\n });\n\n if (closestPage !== currentPage) {\n goToPage(closestPage);\n }\n }, [currentPage, goToPage, isScrollMode, totalPages]);\n\n // ==================== 缩放控制 ====================\n const zoom = useCallback(\n (delta: number) => {\n const newScale = Math.max(minScale, Math.min(maxScale, scale + delta));\n if (controlledScale === undefined) {\n setInternalScale(newScale);\n }\n onScaleChange?.(newScale);\n },\n [scale, minScale, maxScale, controlledScale, onScaleChange]\n );\n\n // ==================== 旋转控制 ====================\n const rotate = useCallback(() => {\n const newRotation = (rotation + 90) % 360;\n if (controlledRotation === undefined) {\n setInternalRotation(newRotation);\n }\n onRotationChange?.(newRotation);\n }, [rotation, controlledRotation, onRotationChange]);\n\n // ==================== 处理窗口大小变化 ====================\n const debouncedUpdatePageWidth = useDebounce((width: number) => {\n setPageWidth(width);\n }, 100);\n\n // Use ResizeObserver to track container size changes\n useEffect(() => {\n if (!pdfContainerRef.current) return;\n\n const container = pdfContainerRef.current;\n const updateWidth = () => {\n debouncedUpdatePageWidth(container.clientWidth);\n };\n\n // Initial measurement\n updateWidth();\n\n // Set up ResizeObserver\n const resizeObserver = new ResizeObserver(() => {\n updateWidth();\n });\n\n resizeObserver.observe(container);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [debouncedUpdatePageWidth]);\n\n // ==================== 键盘快捷键 ====================\n useEffect(() => {\n if (!enableHotkeys) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement | null;\n const activeElement =\n typeof document !== 'undefined'\n ? (document.activeElement as HTMLElement | null)\n : null;\n const focusedElement = target || activeElement;\n const role = focusedElement?.getAttribute('role');\n\n if (\n focusedElement &&\n (focusedElement.tagName === 'INPUT' ||\n focusedElement.tagName === 'TEXTAREA' ||\n focusedElement.tagName === 'SELECT' ||\n focusedElement.isContentEditable ||\n role === 'textbox' ||\n role === 'spinbutton')\n ) {\n return;\n }\n\n // Ctrl/Cmd + 加号: 放大\n if ((e.ctrlKey || e.metaKey) && (e.key === '=' || e.key === '+')) {\n e.preventDefault();\n zoom(0.1);\n }\n // Ctrl/Cmd + 减号: 缩小\n else if ((e.ctrlKey || e.metaKey) && e.key === '-') {\n e.preventDefault();\n zoom(-0.1);\n }\n // 左箭头: 上一页\n else if (!isScrollMode && e.key === 'ArrowLeft') {\n e.preventDefault();\n goToPage(currentPage - 1);\n }\n // 右箭头: 下一页\n else if (!isScrollMode && e.key === 'ArrowRight') {\n e.preventDefault();\n goToPage(currentPage + 1);\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [enableHotkeys, currentPage, goToPage, isScrollMode, zoom]);\n\n // ==================== 全屏切换 ====================\n const toggleFullscreen = useCallback(async () => {\n if (typeof document === 'undefined') return;\n\n if (!document.fullscreenElement) {\n try {\n await readerRef.current?.requestFullscreen?.();\n setIsFullscreen(true);\n } catch (err) {\n console.error('Error attempting to enable fullscreen:', err);\n }\n } else {\n if (document.exitFullscreen) {\n await document.exitFullscreen();\n setIsFullscreen(false);\n }\n }\n }, []);\n\n // ==================== 监听全屏状态变化 ====================\n useEffect(() => {\n if (typeof document === 'undefined') return;\n\n const handleFullscreenChange = () => {\n setIsFullscreen(!!document.fullscreenElement);\n };\n\n document.addEventListener('fullscreenchange', handleFullscreenChange);\n return () => {\n document.removeEventListener('fullscreenchange', handleFullscreenChange);\n };\n }, []);\n\n // ==================== 处理侧边栏页面点击 ====================\n const handleSidebarPageClick = useCallback(\n (pageNumber: number) => {\n goToPage(pageNumber);\n setShowAllPages(false);\n },\n [goToPage]\n );\n\n // ==================== 渲染工具栏 ====================\n const renderToolbar = () => {\n if (!showToolbar) return null;\n\n return (\n <div\n className={`flex items-center justify-between gap-4 border-b px-4 py-2 ${toolbarClassName || ''}`}\n >\n <div className=\"flex items-center gap-2\">\n {/* 侧边栏切换 */}\n {showSidebar && (\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setShowSidebarState(!showSidebarState)}\n title={showSidebarState ? '隐藏侧边栏' : '显示侧边栏'}\n >\n <PanelLeftIcon />\n </Button>\n )}\n\n {/* 缩放控制 */}\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => zoom(-0.1)}\n disabled={scale <= minScale}\n >\n <ZoomOutIcon />\n </Button>\n <span className=\"min-w-[3rem] text-center text-sm\">\n {Math.round(scale * 100)}%\n </span>\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => zoom(0.1)}\n disabled={scale >= maxScale}\n >\n <ZoomInIcon />\n </Button>\n\n {/* 旋转控制 */}\n {showRotation && (\n <Button variant=\"outline\" size=\"icon\" onClick={rotate}>\n <RotateCwIcon />\n </Button>\n )}\n\n {/* 显示模式切换 */}\n {showModeToggle && (\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setShowAllPages(!showAllPages)}\n title={showAllPages ? '单页模式' : '滚动模式'}\n >\n {showAllPages ? <ScrollTextIcon /> : <FileTextIcon />}\n </Button>\n )}\n\n {/* 全屏切换 */}\n {showFullscreen && (\n <Button variant=\"outline\" size=\"icon\" onClick={toggleFullscreen}>\n {isFullscreen ? <Minimize2Icon /> : <Maximize2Icon />}\n </Button>\n )}\n </div>\n\n <div className=\"flex items-center gap-2\">\n {!isScrollMode && (\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => goToPage(currentPage - 1)}\n disabled={currentPage <= 1}\n >\n <ChevronLeftIcon />\n </Button>\n )}\n\n <Input\n type=\"number\"\n min={1}\n max={totalPages}\n value={currentPage}\n onChange={(e) => goToPage(parseInt(e.target.value) || 1)}\n disabled={isScrollMode}\n readOnly={isScrollMode}\n title={isScrollMode ? '滚动模式下页码仅显示当前位置' : undefined}\n className=\"w-16 text-center\"\n />\n <span className=\"text-sm text-muted-foreground\">/ {totalPages}</span>\n\n {!isScrollMode && (\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => goToPage(currentPage + 1)}\n disabled={totalPages > 0 && currentPage >= totalPages}\n >\n <ChevronRightIcon />\n </Button>\n )}\n </div>\n </div>\n );\n };\n\n // ==================== 渲染加载状态 ====================\n const renderLoading = () => (\n <div className=\"flex h-full items-center justify-center\">\n <p className=\"text-muted-foreground\">{loadingText}</p>\n </div>\n );\n\n // ==================== 渲染错误状态 ====================\n const renderError = () => (\n <div className=\"flex h-full min-h-[400px] items-center justify-center px-4 text-center text-destructive\">\n <div className=\"max-w-md\">\n <p className=\"mb-2 text-lg font-medium\">文件加载失败</p>\n <p className=\"text-sm opacity-80\">{error?.message}</p>\n </div>\n </div>\n );\n\n // ==================== 渲染 PDF 文档 ====================\n const renderPDFDocument = () => {\n if (!ReactPDF) return renderLoading();\n\n const { Document, Page } = ReactPDF;\n\n return (\n <div\n ref={pdfContainerRef}\n onScroll={isScrollMode ? syncScrollModeCurrentPage : undefined}\n className={`pdf-container flex-1 overflow-y-auto ${contentClassName || ''}`}\n >\n <div className=\"flex min-h-full justify-center px-4\">\n <Document\n key={url}\n file={url}\n onLoadError={onDocumentLoadError}\n options={pdfOptions}\n loading={renderLoading()}\n error={renderError()}\n onLoadSuccess={onDocumentLoadSuccess}\n >\n {error ? (\n renderError()\n ) : showAllPages ? (\n // 显示所有页面模式\n Array.from(new Array(totalPages), (_el, index) => (\n <div\n key={`page_${index + 1}`}\n ref={(element) => setPageRef(index + 1, element)}\n data-page-number={index + 1}\n className={`mb-4 ${pageClassName || ''}`}\n >\n <Page\n pageNumber={index + 1}\n renderTextLayer={false}\n renderAnnotationLayer={false}\n width={pageWidth}\n scale={scale}\n rotate={rotation}\n onRenderSuccess={() => onPageRender?.(index + 1)}\n />\n </div>\n ))\n ) : (\n // 单页模式\n <div className={pageClassName || ''}>\n <Page\n pageNumber={currentPage}\n renderTextLayer={false}\n renderAnnotationLayer={false}\n width={pageWidth}\n scale={scale}\n rotate={rotation}\n onRenderSuccess={() => onPageRender?.(currentPage)}\n />\n </div>\n )}\n </Document>\n </div>\n </div>\n );\n };\n\n // ==================== 渲染侧边栏 ====================\n const renderSidebar = () => {\n if (!showSidebar || !showSidebarState || !pdfDocument) return null;\n\n // 使用导入的 PDFSidebar 组件\n const PDFSidebarComponent = PDFSidebar;\n\n return (\n <PDFSidebarComponent\n pdfDocument={pdfDocument}\n currentPage={currentPage}\n onPageClick={handleSidebarPageClick}\n components={{\n Tabs: components.Tabs!,\n TabsList: components.TabsList!,\n TabsTrigger: components.TabsTrigger!,\n TabsContent: components.TabsContent!,\n ScrollArea: components.ScrollArea!,\n Skeleton,\n }}\n />\n );\n };\n\n // ==================== 渲染移动端导航 ====================\n const renderMobileNav = () => {\n if (!enableMobileNav || isScrollMode) return null;\n\n return (\n <div className=\"fixed bottom-4 left-1/2 z-50 flex -translate-x-1/2 gap-2 md:hidden\">\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => goToPage(currentPage - 1)}\n disabled={isScrollMode || currentPage <= 1}\n title={isScrollMode ? '滚动模式下通过滚动定位页面' : undefined}\n >\n <ChevronLeftIcon />\n <span className=\"ml-1\">上一页</span>\n </Button>\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => goToPage(currentPage + 1)}\n disabled={isScrollMode || currentPage >= totalPages}\n title={isScrollMode ? '滚动模式下通过滚动定位页面' : undefined}\n >\n <span className=\"mr-1\">下一页</span>\n <ChevronRightIcon />\n </Button>\n </div>\n );\n };\n\n // ==================== 组件验证 ====================\n if (!components) {\n return (\n <div className=\"p-4 text-center text-destructive\">\n 错误:请通过 components prop 注入 UI 组件\n </div>\n );\n }\n\n // 验证侧边栏所需的所有组件\n if (showSidebar) {\n const missingComponents: string[] = [];\n if (!components.Tabs) missingComponents.push('Tabs');\n if (!components.TabsList) missingComponents.push('TabsList');\n if (!components.TabsTrigger) missingComponents.push('TabsTrigger');\n if (!components.TabsContent) missingComponents.push('TabsContent');\n if (!components.ScrollArea) missingComponents.push('ScrollArea');\n\n if (missingComponents.length > 0) {\n const missingComponentsText =\n missingComponents.length === 1\n ? missingComponents[0]\n : `${missingComponents.slice(0, -1).join('、')} 和 ${missingComponents[missingComponents.length - 1]}`;\n return (\n <div className=\"p-4 text-center text-destructive\">\n 错误:侧边栏功能需要注入 {missingComponentsText} 组件\n </div>\n );\n }\n }\n\n return (\n <div ref={readerRef}>\n <Card className={className}>\n {renderToolbar()}\n <CardContent\n className=\"p-0\"\n style={{ height: isFullscreen ? '100vh' : contentHeight }}\n >\n <div className=\"flex h-full flex-col\">\n {/* PDF 显示区域 */}\n <div className=\"flex flex-1 overflow-hidden\">\n {renderSidebar()}\n {isLoading\n ? renderLoading()\n : error\n ? renderError()\n : renderPDFDocument()}\n </div>\n </div>\n </CardContent>\n </Card>\n {renderMobileNav()}\n </div>\n );\n}\n"],"names":["useDebounce","callback","delay","timeoutRef","useRef","useCallback","args","PDFReader","url","initialPage","initialScale","initialRotation","controlledPage","onPageChange","controlledScale","onScaleChange","controlledRotation","onRotationChange","minScale","maxScale","showToolbar","showSidebar","showRotation","showModeToggle","showFullscreen","enableHotkeys","enableMobileNav","initialDisplayMode","className","toolbarClassName","contentClassName","contentHeight","pageClassName","workerUrl","cMapUrl","standardFontDataUrl","components","onLoadSuccess","onLoadError","onPageRender","loadingText","errorText","pdfDocument","setPdfDocument","useState","internalPage","setInternalPage","internalScale","setInternalScale","internalRotation","setInternalRotation","isLoading","setIsLoading","error","setError","totalPages","setTotalPages","isFullscreen","setIsFullscreen","showAllPages","setShowAllPages","showSidebarState","setShowSidebarState","useEffect","pageWidth","setPageWidth","ReactPDF","setReactPDF","readerRef","pdfContainerRef","pageRefs","currentPage","scale","rotation","isPageControlled","isScrollMode","Card","CardContent","Button","Input","Skeleton","pdfOptions","useMemo","options","isMounted","pdfModule","pdfjs","workerVersion","err","loadError","onDocumentLoadError","onDocumentLoadSuccess","pdf","page","goToPage","newPage","setPageRef","pageNumber","element","syncScrollModeCurrentPage","container","containerTop","closestPage","closestDistance","distance","zoom","delta","newScale","rotate","newRotation","debouncedUpdatePageWidth","width","updateWidth","resizeObserver","handleKeyDown","e","target","activeElement","focusedElement","role","toggleFullscreen","_b","_a","handleFullscreenChange","handleSidebarPageClick","renderToolbar","jsxs","jsx","PanelLeftIcon","ZoomOutIcon","ZoomInIcon","RotateCwIcon","ScrollTextIcon","FileTextIcon","Minimize2Icon","Maximize2Icon","ChevronLeftIcon","ChevronRightIcon","renderLoading","renderError","renderPDFDocument","Document","Page","_el","index","renderSidebar","PDFSidebarComponent","PDFSidebar","renderMobileNav","missingComponents","missingComponentsText"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pdf-reader.cjs","sources":["../src/components/PDFReader.tsx"],"sourcesContent":["import {\n ChevronLeft as ChevronLeftIcon,\n ChevronRight as ChevronRightIcon,\n FileText as FileTextIcon,\n Maximize2 as Maximize2Icon,\n Minimize2 as Minimize2Icon,\n PanelLeft as PanelLeftIcon,\n RotateCw as RotateCwIcon,\n ScrollText as ScrollTextIcon,\n ZoomIn as ZoomInIcon,\n ZoomOut as ZoomOutIcon,\n} from 'lucide-react';\nimport { useState, useCallback, useEffect, useMemo, useRef } from 'react';\nimport type { HTMLAttributes } from 'react';\n\nimport type {\n CardComponent,\n ButtonComponent,\n InputComponent,\n SkeletonComponent,\n} from '../types/component-types';\n\nimport type { PDFDocumentProxy } from './PDFSidebar';\nimport { PDFSidebar } from './PDFSidebar';\n\n/**\n * PDFReader UI 组件接口\n */\nexport interface PDFReaderUIComponents {\n /** Card 组件 (必需) */\n Card: CardComponent;\n /** CardContent 组件 (必需) */\n CardContent: React.ComponentType<HTMLAttributes<HTMLDivElement>>;\n /** Button 组件 (必需) */\n Button: ButtonComponent;\n /** Input 组件 (必需) */\n Input: InputComponent;\n /** Skeleton 组件 (必需) */\n Skeleton: SkeletonComponent;\n /** Tabs 组件 (showSidebar=true 时必需) */\n Tabs?: React.ComponentType<{\n value?: string;\n onValueChange?: (value: string) => void;\n children?: React.ReactNode;\n defaultValue?: string;\n }>;\n /** TabsList 组件 (showSidebar=true 时必需) */\n TabsList?: React.ComponentType<HTMLAttributes<HTMLDivElement>>;\n /** TabsTrigger 组件 (showSidebar=true 时必需) */\n TabsTrigger?: React.ComponentType<{\n value: string;\n children?: React.ReactNode;\n }>;\n /** TabsContent 组件 (showSidebar=true 时必需) */\n TabsContent?: React.ComponentType<{\n value: string;\n children?: React.ReactNode;\n }>;\n /** ScrollArea 组件 (showSidebar=true 时必需) */\n ScrollArea?: React.ComponentType<HTMLAttributes<HTMLDivElement>>;\n}\n\n/**\n * PDFReader 组件 Props\n */\nexport interface PDFReaderProps {\n // ==================== 基础配置 ====================\n /** PDF 文件 URL (必需) */\n url: string;\n\n // ==================== 初始状态 ====================\n /** 初始页码 (默认 1) */\n initialPage?: number;\n /** 初始缩放比例 (默认 1.0) */\n initialScale?: number;\n /** 初始旋转角度 (默认 0) */\n initialRotation?: number;\n\n // ==================== 受控模式 ====================\n /** 当前页码 (受控) */\n currentPage?: number;\n /** 页码变化回调 */\n onPageChange?: (page: number) => void;\n /** 缩放比例 (受控) */\n scale?: number;\n /** 缩放变化回调 */\n onScaleChange?: (scale: number) => void;\n /** 旋转角度 (受控) */\n rotation?: number;\n /** 旋转变化回调 */\n onRotationChange?: (rotation: number) => void;\n\n // ==================== 缩放限制 ====================\n /** 最小缩放比例 (默认 0.5) */\n minScale?: number;\n /** 最大缩放比例 (默认 2.5) */\n maxScale?: number;\n\n // ==================== 功能开关 ====================\n /** 显示工具栏 (默认 true) */\n showToolbar?: boolean;\n /** 显示侧边栏 (默认 true) */\n showSidebar?: boolean;\n /** 显示旋转按钮 (默认 true) */\n showRotation?: boolean;\n /** 显示模式切换按钮 (默认 true) */\n showModeToggle?: boolean;\n /** 显示全屏按钮 (默认 true) */\n showFullscreen?: boolean;\n /** 启用键盘快捷键 (默认 true) */\n enableHotkeys?: boolean;\n /** 启用移动端导航 (默认 true) */\n enableMobileNav?: boolean;\n\n // ==================== 显示模式 ====================\n /** 显示模式: 'scroll' 显示所有页面, 'single' 单页模式 (默认 'single') */\n displayMode?: 'scroll' | 'single';\n\n // ==================== 样式定制 ====================\n /** 容器类名 */\n className?: string;\n /** 工具栏类名 */\n toolbarClassName?: string;\n /** 内容区域类名 */\n contentClassName?: string;\n /** 阅读区域高度限制 (默认 '80vh') */\n contentHeight?: string | number;\n /** 页面类名 */\n pageClassName?: string;\n\n // ==================== Worker 配置 ====================\n /** Worker 文件 URL (可选,默认使用 CDN) */\n workerUrl?: string;\n /** CMap 文件 URL (可选,默认使用 CDN) */\n cMapUrl?: string;\n /** 标准字体数据 URL (可选,默认使用 CDN) */\n standardFontDataUrl?: string;\n\n // ==================== UI 组件注入 ====================\n /** UI 组件 */\n components: PDFReaderUIComponents;\n\n // ==================== 回调函数 ====================\n /** 加载成功回调 */\n onLoadSuccess?: (pdf: PDFDocumentProxy) => void;\n /** 加载错误回调 */\n onLoadError?: (error: Error) => void;\n /** 页面渲染回调 */\n onPageRender?: (pageIndex: number) => void;\n\n // ==================== 文本配置 ====================\n /** 加载文本 (默认 '正在加载PDF文档...') */\n loadingText?: string;\n /** 错误文本 (默认 'PDF加载失败') */\n errorText?: string;\n}\n\n/**\n * debounce hook (替代 lodash.debounce)\n */\nfunction useDebounce<T extends (...args: any[]) => any>(\n callback: T,\n delay: number\n): T {\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined\n );\n return useCallback(\n (...args: Parameters<T>) => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n timeoutRef.current = setTimeout(() => callback(...args), delay);\n },\n [callback, delay]\n ) as T;\n}\n\n/**\n * PDFReader 组件\n *\n * 功能完整的 PDF 阅读器组件,支持侧边栏导航、页面旋转、显示模式切换等高级特性。\n *\n * @example\n * ```tsx\n * import { PDFReader } from '@turinhub/atomix-common-ui/pdf-reader';\n * import { Card, Button, Input, Label, Skeleton } from '@/components/ui';\n * import { Tabs, ScrollArea } from '@/components/ui';\n *\n * <PDFReader\n * url=\"/documents/sample.pdf\"\n * components={{\n * Card,\n * CardContent: Card.Content,\n * Button,\n * Input,\n * Label,\n * Skeleton,\n * Tabs,\n * TabsList: Tabs.List,\n * TabsTrigger: Tabs.Trigger,\n * TabsContent: Tabs.Content,\n * ScrollArea,\n * }}\n * initialPage={1}\n * initialScale={1.0}\n * showSidebar={true}\n * showRotation={true}\n * showModeToggle={true}\n * enableHotkeys={true}\n * />\n * ```\n */\nexport function PDFReader({\n url,\n initialPage = 1,\n initialScale = 1.0,\n initialRotation = 0,\n currentPage: controlledPage,\n onPageChange,\n scale: controlledScale,\n onScaleChange,\n rotation: controlledRotation,\n onRotationChange,\n minScale = 0.5,\n maxScale = 2.5,\n showToolbar = true,\n showSidebar = true,\n showRotation = true,\n showModeToggle = true,\n showFullscreen = true,\n enableHotkeys = true,\n enableMobileNav = true,\n displayMode: initialDisplayMode = 'single',\n className,\n toolbarClassName,\n contentClassName,\n contentHeight = '80vh',\n pageClassName,\n workerUrl,\n cMapUrl,\n standardFontDataUrl,\n components,\n onLoadSuccess,\n onLoadError,\n onPageRender,\n loadingText = '正在加载PDF文档...',\n errorText = 'PDF加载失败',\n}: PDFReaderProps) {\n // ==================== 状态管理 ====================\n const [pdfDocument, setPdfDocument] = useState<PDFDocumentProxy | null>(null);\n const [internalPage, setInternalPage] = useState(initialPage);\n const [internalScale, setInternalScale] = useState(initialScale);\n const [internalRotation, setInternalRotation] = useState(initialRotation);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [totalPages, setTotalPages] = useState(0);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const [showAllPages, setShowAllPages] = useState(\n initialDisplayMode === 'scroll'\n );\n const [showSidebarState, setShowSidebarState] = useState(showSidebar);\n\n // Sync showSidebarState with prop changes\n useEffect(() => {\n setShowSidebarState(showSidebar);\n }, [showSidebar]);\n\n const [pageWidth, setPageWidth] = useState<number | undefined>(undefined);\n\n // 动态导入 react-pdf\n const [ReactPDF, setReactPDF] = useState<any>(null);\n\n const readerRef = useRef<HTMLDivElement>(null);\n const pdfContainerRef = useRef<HTMLDivElement>(null);\n const pageRefs = useRef<Map<number, HTMLDivElement>>(new Map());\n\n // 使用受控或非受控模式\n const currentPage = controlledPage ?? internalPage;\n const scale = controlledScale ?? internalScale;\n const rotation = controlledRotation ?? internalRotation;\n const isPageControlled = controlledPage !== undefined;\n const isScrollMode = showAllPages;\n\n // ==================== 组件解构 ====================\n const { Card, CardContent, Button, Input, Skeleton } = components || {};\n\n useEffect(() => {\n setPdfDocument(null);\n setTotalPages(0);\n setError(null);\n setIsLoading(false);\n if (!isPageControlled) {\n setInternalPage(Math.max(1, initialPage));\n }\n }, [url, initialPage, isPageControlled]);\n\n // ==================== PDF 选项 ====================\n const pdfOptions = useMemo(() => {\n const options: Record<string, unknown> = {\n withCredentials: false,\n };\n\n if (cMapUrl) {\n options.cMapUrl = cMapUrl;\n options.cMapPacked = true;\n }\n\n if (standardFontDataUrl) {\n options.standardFontDataUrl = standardFontDataUrl;\n }\n\n return options;\n }, [cMapUrl, standardFontDataUrl]);\n\n // ==================== 动态导入 react-pdf ====================\n useEffect(() => {\n let isMounted = true;\n\n const loadReactPDF = async () => {\n try {\n // 动态导入 react-pdf\n const pdfModule = await import('react-pdf');\n\n // 设置 worker\n if (typeof window !== 'undefined') {\n const pdfjs = (pdfModule as any).pdfjs;\n const workerVersion = pdfjs?.version;\n\n if (pdfjs?.GlobalWorkerOptions && workerVersion) {\n if (workerUrl) {\n pdfjs.GlobalWorkerOptions.workerSrc = workerUrl;\n } else {\n // 使用 CDN\n pdfjs.GlobalWorkerOptions.workerSrc = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${workerVersion}/build/pdf.worker.min.mjs`;\n }\n\n // 如果没有提供自定义 URL,使用 CDN 默认值\n if (!cMapUrl && pdfjs.GlobalWorkerOptions) {\n (pdfjs.GlobalWorkerOptions as any).cMapUrl =\n `https://unpkg.com/pdfjs-dist@${workerVersion}/cmaps/`;\n }\n if (!standardFontDataUrl && pdfjs.GlobalWorkerOptions) {\n (pdfjs.GlobalWorkerOptions as any).standardFontDataUrl =\n `https://unpkg.com/pdfjs-dist@${workerVersion}/standard_fonts/`;\n }\n }\n }\n\n if (isMounted) {\n setReactPDF(pdfModule);\n }\n } catch (err) {\n if (isMounted) {\n const loadError =\n err instanceof Error ? err : new Error('无法加载 react-pdf 库');\n setError(loadError);\n setIsLoading(false);\n onLoadError?.(loadError);\n }\n }\n };\n\n loadReactPDF();\n\n return () => {\n isMounted = false;\n };\n }, [workerUrl, cMapUrl, standardFontDataUrl, onLoadError]);\n\n // ==================== 处理加载错误 ====================\n const onDocumentLoadError = useCallback(\n (err: Error) => {\n console.error('PDF加载失败:', err);\n console.error('PDF URL:', url);\n setPdfDocument(null);\n setTotalPages(0);\n setError(\n new Error(`${errorText}: ${err.message || '请检查文件路径或网络连接'}`)\n );\n setIsLoading(false);\n onLoadError?.(err);\n },\n [url, errorText, onLoadError]\n );\n\n const onDocumentLoadSuccess = useCallback(\n (pdf: PDFDocumentProxy) => {\n setPdfDocument(pdf);\n setTotalPages(pdf.numPages);\n setError(null);\n setIsLoading(false);\n\n if (!isPageControlled) {\n setInternalPage((page) =>\n Math.max(1, Math.min(page, Math.max(pdf.numPages, 1)))\n );\n }\n\n onLoadSuccess?.(pdf);\n },\n [isPageControlled, onLoadSuccess]\n );\n\n // ==================== 页面导航 ====================\n const goToPage = useCallback(\n (page: number) => {\n if (!Number.isFinite(page)) return;\n const newPage =\n totalPages > 0\n ? Math.max(1, Math.min(Math.trunc(page), totalPages))\n : Math.max(1, Math.trunc(page));\n if (!isPageControlled) {\n setInternalPage(newPage);\n }\n if (newPage !== currentPage) {\n onPageChange?.(newPage);\n }\n },\n [totalPages, isPageControlled, currentPage, onPageChange]\n );\n\n const setPageRef = useCallback(\n (pageNumber: number, element: HTMLDivElement | null) => {\n if (element) {\n pageRefs.current.set(pageNumber, element);\n } else {\n pageRefs.current.delete(pageNumber);\n }\n },\n []\n );\n\n const syncScrollModeCurrentPage = useCallback(() => {\n const container = pdfContainerRef.current;\n if (!container || !isScrollMode || totalPages <= 0) return;\n\n const containerTop = container.getBoundingClientRect().top;\n let closestPage = currentPage;\n let closestDistance = Number.POSITIVE_INFINITY;\n\n pageRefs.current.forEach((element, pageNumber) => {\n const distance = Math.abs(\n element.getBoundingClientRect().top - containerTop\n );\n if (distance < closestDistance) {\n closestDistance = distance;\n closestPage = pageNumber;\n }\n });\n\n if (closestPage !== currentPage) {\n goToPage(closestPage);\n }\n }, [currentPage, goToPage, isScrollMode, totalPages]);\n\n // ==================== 缩放控制 ====================\n const zoom = useCallback(\n (delta: number) => {\n const newScale = Math.max(minScale, Math.min(maxScale, scale + delta));\n if (controlledScale === undefined) {\n setInternalScale(newScale);\n }\n onScaleChange?.(newScale);\n },\n [scale, minScale, maxScale, controlledScale, onScaleChange]\n );\n\n // ==================== 旋转控制 ====================\n const rotate = useCallback(() => {\n const newRotation = (rotation + 90) % 360;\n if (controlledRotation === undefined) {\n setInternalRotation(newRotation);\n }\n onRotationChange?.(newRotation);\n }, [rotation, controlledRotation, onRotationChange]);\n\n // ==================== 处理窗口大小变化 ====================\n const debouncedUpdatePageWidth = useDebounce((width: number) => {\n setPageWidth(width);\n }, 100);\n\n // Use ResizeObserver to track container size changes\n useEffect(() => {\n if (!pdfContainerRef.current) return;\n\n const container = pdfContainerRef.current;\n const updateWidth = () => {\n debouncedUpdatePageWidth(container.clientWidth);\n };\n\n // Initial measurement\n updateWidth();\n\n // Set up ResizeObserver\n const resizeObserver = new ResizeObserver(() => {\n updateWidth();\n });\n\n resizeObserver.observe(container);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [debouncedUpdatePageWidth]);\n\n // ==================== 键盘快捷键 ====================\n useEffect(() => {\n if (!enableHotkeys) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement | null;\n const activeElement =\n typeof document !== 'undefined'\n ? (document.activeElement as HTMLElement | null)\n : null;\n const focusedElement = target || activeElement;\n const role = focusedElement?.getAttribute('role');\n\n if (\n focusedElement &&\n (focusedElement.tagName === 'INPUT' ||\n focusedElement.tagName === 'TEXTAREA' ||\n focusedElement.tagName === 'SELECT' ||\n focusedElement.isContentEditable ||\n role === 'textbox' ||\n role === 'spinbutton')\n ) {\n return;\n }\n\n // Ctrl/Cmd + 加号: 放大\n if ((e.ctrlKey || e.metaKey) && (e.key === '=' || e.key === '+')) {\n e.preventDefault();\n zoom(0.1);\n }\n // Ctrl/Cmd + 减号: 缩小\n else if ((e.ctrlKey || e.metaKey) && e.key === '-') {\n e.preventDefault();\n zoom(-0.1);\n }\n // 左箭头: 上一页\n else if (!isScrollMode && e.key === 'ArrowLeft') {\n e.preventDefault();\n goToPage(currentPage - 1);\n }\n // 右箭头: 下一页\n else if (!isScrollMode && e.key === 'ArrowRight') {\n e.preventDefault();\n goToPage(currentPage + 1);\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [enableHotkeys, currentPage, goToPage, isScrollMode, zoom]);\n\n // ==================== 全屏切换 ====================\n const toggleFullscreen = useCallback(async () => {\n if (typeof document === 'undefined') return;\n\n if (!document.fullscreenElement) {\n try {\n await readerRef.current?.requestFullscreen?.();\n setIsFullscreen(true);\n } catch (err) {\n console.error('Error attempting to enable fullscreen:', err);\n }\n } else {\n if (document.exitFullscreen) {\n await document.exitFullscreen();\n setIsFullscreen(false);\n }\n }\n }, []);\n\n // ==================== 监听全屏状态变化 ====================\n useEffect(() => {\n if (typeof document === 'undefined') return;\n\n const handleFullscreenChange = () => {\n setIsFullscreen(!!document.fullscreenElement);\n };\n\n document.addEventListener('fullscreenchange', handleFullscreenChange);\n return () => {\n document.removeEventListener('fullscreenchange', handleFullscreenChange);\n };\n }, []);\n\n // ==================== 处理侧边栏页面点击 ====================\n const handleSidebarPageClick = useCallback(\n (pageNumber: number) => {\n goToPage(pageNumber);\n setShowAllPages(false);\n },\n [goToPage]\n );\n\n // ==================== 渲染工具栏 ====================\n const renderToolbar = () => {\n if (!showToolbar) return null;\n\n return (\n <div\n className={`flex items-center justify-between gap-4 border-b px-4 py-2 ${toolbarClassName || ''}`}\n >\n <div className=\"flex items-center gap-2\">\n {/* 侧边栏切换 */}\n {showSidebar && (\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setShowSidebarState(!showSidebarState)}\n title={showSidebarState ? '隐藏侧边栏' : '显示侧边栏'}\n >\n <PanelLeftIcon />\n </Button>\n )}\n\n {/* 缩放控制 */}\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => zoom(-0.1)}\n disabled={scale <= minScale}\n >\n <ZoomOutIcon />\n </Button>\n <span className=\"min-w-[3rem] text-center text-sm\">\n {Math.round(scale * 100)}%\n </span>\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => zoom(0.1)}\n disabled={scale >= maxScale}\n >\n <ZoomInIcon />\n </Button>\n\n {/* 旋转控制 */}\n {showRotation && (\n <Button variant=\"outline\" size=\"icon\" onClick={rotate}>\n <RotateCwIcon />\n </Button>\n )}\n\n {/* 显示模式切换 */}\n {showModeToggle && (\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setShowAllPages(!showAllPages)}\n title={showAllPages ? '单页模式' : '滚动模式'}\n >\n {showAllPages ? <ScrollTextIcon /> : <FileTextIcon />}\n </Button>\n )}\n\n {/* 全屏切换 */}\n {showFullscreen && (\n <Button variant=\"outline\" size=\"icon\" onClick={toggleFullscreen}>\n {isFullscreen ? <Minimize2Icon /> : <Maximize2Icon />}\n </Button>\n )}\n </div>\n\n <div className=\"flex items-center gap-2\">\n {!isScrollMode && (\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => goToPage(currentPage - 1)}\n disabled={currentPage <= 1}\n >\n <ChevronLeftIcon />\n </Button>\n )}\n\n <Input\n type=\"number\"\n min={1}\n max={totalPages}\n value={currentPage}\n onChange={(e) => goToPage(parseInt(e.target.value) || 1)}\n disabled={isScrollMode}\n readOnly={isScrollMode}\n title={isScrollMode ? '滚动模式下页码仅显示当前位置' : undefined}\n className=\"w-16 text-center\"\n />\n <span className=\"text-sm text-muted-foreground\">/ {totalPages}</span>\n\n {!isScrollMode && (\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => goToPage(currentPage + 1)}\n disabled={totalPages > 0 && currentPage >= totalPages}\n >\n <ChevronRightIcon />\n </Button>\n )}\n </div>\n </div>\n );\n };\n\n // ==================== 渲染加载状态 ====================\n const renderLoading = () => (\n <div className=\"flex h-full items-center justify-center\">\n <p className=\"text-muted-foreground\">{loadingText}</p>\n </div>\n );\n\n // ==================== 渲染错误状态 ====================\n const renderError = () => (\n <div className=\"flex h-full min-h-[400px] items-center justify-center px-4 text-center text-destructive\">\n <div className=\"max-w-md\">\n <p className=\"mb-2 text-lg font-medium\">文件加载失败</p>\n <p className=\"text-sm opacity-80\">{error?.message}</p>\n </div>\n </div>\n );\n\n // ==================== 渲染 PDF 文档 ====================\n const renderPDFDocument = () => {\n if (!ReactPDF) return renderLoading();\n\n const { Document, Page } = ReactPDF;\n\n return (\n <div\n ref={pdfContainerRef}\n onScroll={isScrollMode ? syncScrollModeCurrentPage : undefined}\n className={`pdf-container flex-1 overflow-y-auto ${contentClassName || ''}`}\n >\n <div className=\"flex min-h-full justify-center px-4\">\n <Document\n key={url}\n file={url}\n onLoadError={onDocumentLoadError}\n options={pdfOptions}\n loading={renderLoading()}\n error={renderError()}\n onLoadSuccess={onDocumentLoadSuccess}\n >\n {error ? (\n renderError()\n ) : showAllPages ? (\n // 显示所有页面模式\n Array.from(new Array(totalPages), (_el, index) => (\n <div\n key={`page_${index + 1}`}\n ref={(element) => setPageRef(index + 1, element)}\n data-page-number={index + 1}\n className={`mb-4 ${pageClassName || ''}`}\n >\n <Page\n pageNumber={index + 1}\n renderTextLayer={false}\n renderAnnotationLayer={false}\n width={pageWidth}\n scale={scale}\n rotate={rotation}\n onRenderSuccess={() => onPageRender?.(index + 1)}\n />\n </div>\n ))\n ) : (\n // 单页模式\n <div className={pageClassName || ''}>\n <Page\n pageNumber={currentPage}\n renderTextLayer={false}\n renderAnnotationLayer={false}\n width={pageWidth}\n scale={scale}\n rotate={rotation}\n onRenderSuccess={() => onPageRender?.(currentPage)}\n />\n </div>\n )}\n </Document>\n </div>\n </div>\n );\n };\n\n // ==================== 渲染侧边栏 ====================\n const renderSidebar = () => {\n if (!showSidebar || !showSidebarState || !pdfDocument) return null;\n\n // 使用导入的 PDFSidebar 组件\n const PDFSidebarComponent = PDFSidebar;\n\n return (\n <PDFSidebarComponent\n pdfDocument={pdfDocument}\n currentPage={currentPage}\n onPageClick={handleSidebarPageClick}\n components={{\n Tabs: components.Tabs!,\n TabsList: components.TabsList!,\n TabsTrigger: components.TabsTrigger!,\n TabsContent: components.TabsContent!,\n ScrollArea: components.ScrollArea!,\n Skeleton,\n }}\n />\n );\n };\n\n // ==================== 渲染移动端导航 ====================\n const renderMobileNav = () => {\n if (!enableMobileNav || isScrollMode) return null;\n\n return (\n <div className=\"fixed bottom-4 left-1/2 z-50 flex -translate-x-1/2 gap-2 md:hidden\">\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => goToPage(currentPage - 1)}\n disabled={isScrollMode || currentPage <= 1}\n title={isScrollMode ? '滚动模式下通过滚动定位页面' : undefined}\n >\n <ChevronLeftIcon />\n <span className=\"ml-1\">上一页</span>\n </Button>\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => goToPage(currentPage + 1)}\n disabled={isScrollMode || currentPage >= totalPages}\n title={isScrollMode ? '滚动模式下通过滚动定位页面' : undefined}\n >\n <span className=\"mr-1\">下一页</span>\n <ChevronRightIcon />\n </Button>\n </div>\n );\n };\n\n // ==================== 组件验证 ====================\n if (!components) {\n return (\n <div className=\"p-4 text-center text-destructive\">\n 错误:请通过 components prop 注入 UI 组件\n </div>\n );\n }\n\n // 验证侧边栏所需的所有组件\n if (showSidebar) {\n const missingComponents: string[] = [];\n if (!components.Tabs) missingComponents.push('Tabs');\n if (!components.TabsList) missingComponents.push('TabsList');\n if (!components.TabsTrigger) missingComponents.push('TabsTrigger');\n if (!components.TabsContent) missingComponents.push('TabsContent');\n if (!components.ScrollArea) missingComponents.push('ScrollArea');\n\n if (missingComponents.length > 0) {\n const missingComponentsText =\n missingComponents.length === 1\n ? missingComponents[0]\n : `${missingComponents.slice(0, -1).join('、')} 和 ${missingComponents[missingComponents.length - 1]}`;\n return (\n <div className=\"p-4 text-center text-destructive\">\n 错误:侧边栏功能需要注入 {missingComponentsText} 组件\n </div>\n );\n }\n }\n\n return (\n <div ref={readerRef}>\n <Card className={className}>\n {renderToolbar()}\n <CardContent\n className=\"p-0\"\n style={{ height: isFullscreen ? '100vh' : contentHeight }}\n >\n <div className=\"flex h-full flex-col\">\n {/* PDF 显示区域 */}\n <div className=\"flex flex-1 overflow-hidden\">\n {renderSidebar()}\n {isLoading\n ? renderLoading()\n : error\n ? renderError()\n : renderPDFDocument()}\n </div>\n </div>\n </CardContent>\n </Card>\n {renderMobileNav()}\n </div>\n );\n}\n"],"names":["useDebounce","callback","delay","timeoutRef","useRef","useCallback","args","PDFReader","url","initialPage","initialScale","initialRotation","controlledPage","onPageChange","controlledScale","onScaleChange","controlledRotation","onRotationChange","minScale","maxScale","showToolbar","showSidebar","showRotation","showModeToggle","showFullscreen","enableHotkeys","enableMobileNav","initialDisplayMode","className","toolbarClassName","contentClassName","contentHeight","pageClassName","workerUrl","cMapUrl","standardFontDataUrl","components","onLoadSuccess","onLoadError","onPageRender","loadingText","errorText","pdfDocument","setPdfDocument","useState","internalPage","setInternalPage","internalScale","setInternalScale","internalRotation","setInternalRotation","isLoading","setIsLoading","error","setError","totalPages","setTotalPages","isFullscreen","setIsFullscreen","showAllPages","setShowAllPages","showSidebarState","setShowSidebarState","useEffect","pageWidth","setPageWidth","ReactPDF","setReactPDF","readerRef","pdfContainerRef","pageRefs","currentPage","scale","rotation","isPageControlled","isScrollMode","Card","CardContent","Button","Input","Skeleton","pdfOptions","useMemo","options","isMounted","pdfModule","pdfjs","workerVersion","err","loadError","onDocumentLoadError","onDocumentLoadSuccess","pdf","page","goToPage","newPage","setPageRef","pageNumber","element","syncScrollModeCurrentPage","container","containerTop","closestPage","closestDistance","distance","zoom","delta","newScale","rotate","newRotation","debouncedUpdatePageWidth","width","updateWidth","resizeObserver","handleKeyDown","e","target","activeElement","focusedElement","role","toggleFullscreen","_b","_a","handleFullscreenChange","handleSidebarPageClick","renderToolbar","jsxs","jsx","PanelLeftIcon","ZoomOutIcon","ZoomInIcon","RotateCwIcon","ScrollTextIcon","FileTextIcon","Minimize2Icon","Maximize2Icon","ChevronLeftIcon","ChevronRightIcon","renderLoading","renderError","renderPDFDocument","Document","Page","_el","index","renderSidebar","PDFSidebarComponent","PDFSidebar","renderMobileNav","missingComponents","missingComponentsText"],"mappings":"8qBAgKA,SAASA,GACPC,EACAC,EACG,CACH,MAAMC,EAAaC,EAAAA,OACjB,MAAA,EAEF,OAAOC,EAAAA,YACL,IAAIC,IAAwB,CACtBH,EAAW,SACb,aAAaA,EAAW,OAAO,EAEjCA,EAAW,QAAU,WAAW,IAAMF,EAAS,GAAGK,CAAI,EAAGJ,CAAK,CAChE,EACA,CAACD,EAAUC,CAAK,CAAA,CAEpB,CAqCO,SAASK,GAAU,CACxB,IAAAC,EACA,YAAAC,EAAc,EACd,aAAAC,EAAe,EACf,gBAAAC,EAAkB,EAClB,YAAaC,EACb,aAAAC,EACA,MAAOC,EACP,cAAAC,EACA,SAAUC,EACV,iBAAAC,EACA,SAAAC,EAAW,GACX,SAAAC,EAAW,IACX,YAAAC,GAAc,GACd,YAAAC,EAAc,GACd,aAAAC,GAAe,GACf,eAAAC,GAAiB,GACjB,eAAAC,GAAiB,GACjB,cAAAC,EAAgB,GAChB,gBAAAC,GAAkB,GAClB,YAAaC,GAAqB,SAClC,UAAAC,GACA,iBAAAC,GACA,iBAAAC,GACA,cAAAC,GAAgB,OAChB,cAAAC,EACA,UAAAC,EACA,QAAAC,EACA,oBAAAC,EACA,WAAAC,EACA,cAAAC,EACA,YAAAC,EACA,aAAAC,EACA,YAAAC,GAAc,eACd,UAAAC,EAAY,SACd,EAAmB,CAEjB,KAAM,CAACC,GAAaC,CAAc,EAAIC,EAAAA,SAAkC,IAAI,EACtE,CAACC,GAAcC,CAAe,EAAIF,EAAAA,SAASnC,CAAW,EACtD,CAACsC,GAAeC,EAAgB,EAAIJ,EAAAA,SAASlC,CAAY,EACzD,CAACuC,GAAkBC,EAAmB,EAAIN,EAAAA,SAASjC,CAAe,EAClE,CAACwC,GAAWC,CAAY,EAAIR,EAAAA,SAAS,EAAK,EAC1C,CAACS,EAAOC,CAAQ,EAAIV,EAAAA,SAAuB,IAAI,EAC/C,CAACW,EAAYC,CAAa,EAAIZ,EAAAA,SAAS,CAAC,EACxC,CAACa,GAAcC,CAAe,EAAId,EAAAA,SAAS,EAAK,EAChD,CAACe,EAAcC,EAAe,EAAIhB,EAAAA,SACtCjB,KAAuB,QAAA,EAEnB,CAACkC,EAAkBC,EAAmB,EAAIlB,EAAAA,SAASvB,CAAW,EAGpE0C,EAAAA,UAAU,IAAM,CACdD,GAAoBzC,CAAW,CACjC,EAAG,CAACA,CAAW,CAAC,EAEhB,KAAM,CAAC2C,GAAWC,EAAY,EAAIrB,EAAAA,SAA6B,MAAS,EAGlE,CAACsB,GAAUC,EAAW,EAAIvB,EAAAA,SAAc,IAAI,EAE5CwB,GAAYhE,EAAAA,OAAuB,IAAI,EACvCiE,EAAkBjE,EAAAA,OAAuB,IAAI,EAC7CkE,EAAWlE,EAAAA,OAAoC,IAAI,GAAK,EAGxDmE,EAAc3D,GAAkBiC,GAChC2B,EAAQ1D,GAAmBiC,GAC3B0B,EAAWzD,GAAsBiC,GACjCyB,EAAmB9D,IAAmB,OACtC+D,EAAehB,EAGf,CAAE,KAAAiB,GAAM,YAAAC,GAAa,OAAAC,EAAQ,MAAAC,GAAO,SAAAC,EAAA,EAAa5C,GAAc,CAAA,EAErE2B,EAAAA,UAAU,IAAM,CACdpB,EAAe,IAAI,EACnBa,EAAc,CAAC,EACfF,EAAS,IAAI,EACbF,EAAa,EAAK,EACbsB,GACH5B,EAAgB,KAAK,IAAI,EAAGrC,CAAW,CAAC,CAE5C,EAAG,CAACD,EAAKC,EAAaiE,CAAgB,CAAC,EAGvC,MAAMO,GAAaC,EAAAA,QAAQ,IAAM,CAC/B,MAAMC,EAAmC,CACvC,gBAAiB,EAAA,EAGnB,OAAIjD,IACFiD,EAAQ,QAAUjD,EAClBiD,EAAQ,WAAa,IAGnBhD,IACFgD,EAAQ,oBAAsBhD,GAGzBgD,CACT,EAAG,CAACjD,EAASC,CAAmB,CAAC,EAGjC4B,EAAAA,UAAU,IAAM,CACd,IAAIqB,EAAY,GA8ChB,OA5CqB,SAAY,CAC/B,GAAI,CAEF,MAAMC,EAAY,KAAM,QAAO,WAAW,EAG1C,GAAI,OAAO,OAAW,IAAa,CACjC,MAAMC,EAASD,EAAkB,MAC3BE,EAAgBD,GAAA,YAAAA,EAAO,QAEzBA,GAAA,MAAAA,EAAO,qBAAuBC,IAC5BtD,EACFqD,EAAM,oBAAoB,UAAYrD,EAGtCqD,EAAM,oBAAoB,UAAY,2CAA2CC,CAAa,4BAI5F,CAACrD,GAAWoD,EAAM,sBACnBA,EAAM,oBAA4B,QACjC,gCAAgCC,CAAa,WAE7C,CAACpD,GAAuBmD,EAAM,sBAC/BA,EAAM,oBAA4B,oBACjC,gCAAgCC,CAAa,oBAGrD,CAEIH,GACFjB,GAAYkB,CAAS,CAEzB,OAASG,EAAK,CACZ,GAAIJ,EAAW,CACb,MAAMK,EACJD,aAAe,MAAQA,EAAM,IAAI,MAAM,kBAAkB,EAC3DlC,EAASmC,CAAS,EAClBrC,EAAa,EAAK,EAClBd,GAAA,MAAAA,EAAcmD,EAChB,CACF,CACF,GAEA,EAEO,IAAM,CACXL,EAAY,EACd,CACF,EAAG,CAACnD,EAAWC,EAASC,EAAqBG,CAAW,CAAC,EAGzD,MAAMoD,GAAsBrF,EAAAA,YACzBmF,GAAe,CACd,QAAQ,MAAM,WAAYA,CAAG,EAC7B,QAAQ,MAAM,WAAYhF,CAAG,EAC7BmC,EAAe,IAAI,EACnBa,EAAc,CAAC,EACfF,EACE,IAAI,MAAM,GAAGb,CAAS,KAAK+C,EAAI,SAAW,cAAc,EAAE,CAAA,EAE5DpC,EAAa,EAAK,EAClBd,GAAA,MAAAA,EAAckD,EAChB,EACA,CAAChF,EAAKiC,EAAWH,CAAW,CAAA,EAGxBqD,GAAwBtF,EAAAA,YAC3BuF,GAA0B,CACzBjD,EAAeiD,CAAG,EAClBpC,EAAcoC,EAAI,QAAQ,EAC1BtC,EAAS,IAAI,EACbF,EAAa,EAAK,EAEbsB,GACH5B,EAAiB+C,GACf,KAAK,IAAI,EAAG,KAAK,IAAIA,EAAM,KAAK,IAAID,EAAI,SAAU,CAAC,CAAC,CAAC,CAAA,EAIzDvD,GAAA,MAAAA,EAAgBuD,EAClB,EACA,CAAClB,EAAkBrC,CAAa,CAAA,EAI5ByD,EAAWzF,EAAAA,YACdwF,GAAiB,CAChB,GAAI,CAAC,OAAO,SAASA,CAAI,EAAG,OAC5B,MAAME,EACJxC,EAAa,EACT,KAAK,IAAI,EAAG,KAAK,IAAI,KAAK,MAAMsC,CAAI,EAAGtC,CAAU,CAAC,EAClD,KAAK,IAAI,EAAG,KAAK,MAAMsC,CAAI,CAAC,EAC7BnB,GACH5B,EAAgBiD,CAAO,EAErBA,IAAYxB,IACd1D,GAAA,MAAAA,EAAekF,GAEnB,EACA,CAACxC,EAAYmB,EAAkBH,EAAa1D,CAAY,CAAA,EAGpDmF,GAAa3F,EAAAA,YACjB,CAAC4F,EAAoBC,IAAmC,CAClDA,EACF5B,EAAS,QAAQ,IAAI2B,EAAYC,CAAO,EAExC5B,EAAS,QAAQ,OAAO2B,CAAU,CAEtC,EACA,CAAA,CAAC,EAGGE,GAA4B9F,EAAAA,YAAY,IAAM,CAClD,MAAM+F,EAAY/B,EAAgB,QAClC,GAAI,CAAC+B,GAAa,CAACzB,GAAgBpB,GAAc,EAAG,OAEpD,MAAM8C,EAAeD,EAAU,sBAAA,EAAwB,IACvD,IAAIE,EAAc/B,EACdgC,EAAkB,OAAO,kBAE7BjC,EAAS,QAAQ,QAAQ,CAAC4B,EAASD,IAAe,CAChD,MAAMO,GAAW,KAAK,IACpBN,EAAQ,sBAAA,EAAwB,IAAMG,CAAA,EAEpCG,GAAWD,IACbA,EAAkBC,GAClBF,EAAcL,EAElB,CAAC,EAEGK,IAAgB/B,GAClBuB,EAASQ,CAAW,CAExB,EAAG,CAAC/B,EAAauB,EAAUnB,EAAcpB,CAAU,CAAC,EAG9CkD,EAAOpG,EAAAA,YACVqG,GAAkB,CACjB,MAAMC,EAAW,KAAK,IAAIzF,EAAU,KAAK,IAAIC,EAAUqD,EAAQkC,CAAK,CAAC,EACjE5F,IAAoB,QACtBkC,GAAiB2D,CAAQ,EAE3B5F,GAAA,MAAAA,EAAgB4F,EAClB,EACA,CAACnC,EAAOtD,EAAUC,EAAUL,EAAiBC,CAAa,CAAA,EAItD6F,GAASvG,EAAAA,YAAY,IAAM,CAC/B,MAAMwG,GAAepC,EAAW,IAAM,IAClCzD,IAAuB,QACzBkC,GAAoB2D,CAAW,EAEjC5F,GAAA,MAAAA,EAAmB4F,EACrB,EAAG,CAACpC,EAAUzD,EAAoBC,CAAgB,CAAC,EAG7C6F,GAA2B9G,GAAa+G,GAAkB,CAC9D9C,GAAa8C,CAAK,CACpB,EAAG,GAAG,EAGNhD,EAAAA,UAAU,IAAM,CACd,GAAI,CAACM,EAAgB,QAAS,OAE9B,MAAM+B,EAAY/B,EAAgB,QAC5B2C,EAAc,IAAM,CACxBF,GAAyBV,EAAU,WAAW,CAChD,EAGAY,EAAA,EAGA,MAAMC,EAAiB,IAAI,eAAe,IAAM,CAC9CD,EAAA,CACF,CAAC,EAED,OAAAC,EAAe,QAAQb,CAAS,EAEzB,IAAM,CACXa,EAAe,WAAA,CACjB,CACF,EAAG,CAACH,EAAwB,CAAC,EAG7B/C,EAAAA,UAAU,IAAM,CACd,GAAI,CAACtC,EAAe,OAEpB,MAAMyF,EAAiBC,GAAqB,CAC1C,MAAMC,EAASD,EAAE,OACXE,EACJ,OAAO,SAAa,IACf,SAAS,cACV,KACAC,EAAiBF,GAAUC,EAC3BE,EAAOD,GAAA,YAAAA,EAAgB,aAAa,QAGxCA,IACCA,EAAe,UAAY,SAC1BA,EAAe,UAAY,YAC3BA,EAAe,UAAY,UAC3BA,EAAe,mBACfC,IAAS,WACTA,IAAS,iBAMRJ,EAAE,SAAWA,EAAE,WAAaA,EAAE,MAAQ,KAAOA,EAAE,MAAQ,MAC1DA,EAAE,eAAA,EACFV,EAAK,EAAG,IAGAU,EAAE,SAAWA,EAAE,UAAYA,EAAE,MAAQ,KAC7CA,EAAE,eAAA,EACFV,EAAK,GAAI,GAGF,CAAC9B,GAAgBwC,EAAE,MAAQ,aAClCA,EAAE,eAAA,EACFrB,EAASvB,EAAc,CAAC,GAGjB,CAACI,GAAgBwC,EAAE,MAAQ,eAClCA,EAAE,eAAA,EACFrB,EAASvB,EAAc,CAAC,GAE5B,EAEA,gBAAS,iBAAiB,UAAW2C,CAAa,EAC3C,IAAM,CACX,SAAS,oBAAoB,UAAWA,CAAa,CACvD,CACF,EAAG,CAACzF,EAAe8C,EAAauB,EAAUnB,EAAc8B,CAAI,CAAC,EAG7D,MAAMe,GAAmBnH,EAAAA,YAAY,SAAY,SAC/C,GAAI,SAAO,SAAa,KAExB,GAAK,SAAS,kBAQR,SAAS,iBACX,MAAM,SAAS,eAAA,EACfqD,EAAgB,EAAK,OATvB,IAAI,CACF,OAAM+D,GAAAC,EAAAtD,GAAU,UAAV,YAAAsD,EAAmB,oBAAnB,YAAAD,EAAA,KAAAC,IACNhE,EAAgB,EAAI,CACtB,OAAS8B,EAAK,CACZ,QAAQ,MAAM,yCAA0CA,CAAG,CAC7D,CAOJ,EAAG,CAAA,CAAE,EAGLzB,EAAAA,UAAU,IAAM,CACd,GAAI,OAAO,SAAa,IAAa,OAErC,MAAM4D,EAAyB,IAAM,CACnCjE,EAAgB,CAAC,CAAC,SAAS,iBAAiB,CAC9C,EAEA,gBAAS,iBAAiB,mBAAoBiE,CAAsB,EAC7D,IAAM,CACX,SAAS,oBAAoB,mBAAoBA,CAAsB,CACzE,CACF,EAAG,CAAA,CAAE,EAGL,MAAMC,GAAyBvH,EAAAA,YAC5B4F,GAAuB,CACtBH,EAASG,CAAU,EACnBrC,GAAgB,EAAK,CACvB,EACA,CAACkC,CAAQ,CAAA,EAIL+B,GAAgB,IACfzG,GAGH0G,EAAAA,kBAAAA,KAAC,MAAA,CACC,UAAW,8DAA8DjG,IAAoB,EAAE,GAE/F,SAAA,CAAAiG,EAAAA,kBAAAA,KAAC,MAAA,CAAI,UAAU,0BAEZ,SAAA,CAAAzG,GACC0G,EAAAA,kBAAAA,IAACjD,EAAA,CACC,QAAQ,UACR,KAAK,OACL,QAAS,IAAMhB,GAAoB,CAACD,CAAgB,EACpD,MAAOA,EAAmB,QAAU,QAEpC,iCAACmE,EAAAA,UAAA,CAAA,CAAc,CAAA,CAAA,EAKnBD,EAAAA,kBAAAA,IAACjD,EAAA,CACC,QAAQ,UACR,KAAK,OACL,QAAS,IAAM2B,EAAK,GAAI,EACxB,SAAUjC,GAAStD,EAEnB,iCAAC+G,EAAAA,QAAA,CAAA,CAAY,CAAA,CAAA,EAEfH,EAAAA,kBAAAA,KAAC,OAAA,CAAK,UAAU,mCACb,SAAA,CAAA,KAAK,MAAMtD,EAAQ,GAAG,EAAE,GAAA,EAC3B,EACAuD,EAAAA,kBAAAA,IAACjD,EAAA,CACC,QAAQ,UACR,KAAK,OACL,QAAS,IAAM2B,EAAK,EAAG,EACvB,SAAUjC,GAASrD,EAEnB,iCAAC+G,EAAAA,OAAA,CAAA,CAAW,CAAA,CAAA,EAIb5G,IACCyG,EAAAA,kBAAAA,IAACjD,EAAA,CAAO,QAAQ,UAAU,KAAK,OAAO,QAAS8B,GAC7C,SAAAmB,EAAAA,kBAAAA,IAACI,EAAAA,SAAA,CAAA,CAAa,CAAA,CAChB,EAID5G,IACCwG,EAAAA,kBAAAA,IAACjD,EAAA,CACC,QAAQ,UACR,KAAK,OACL,QAAS,IAAMlB,GAAgB,CAACD,CAAY,EAC5C,MAAOA,EAAe,OAAS,OAE9B,SAAAA,EAAeoE,wBAACK,EAAAA,WAAA,CAAA,CAAe,0BAAMC,EAAAA,SAAA,CAAA,CAAa,CAAA,CAAA,EAKtD7G,IACCuG,EAAAA,kBAAAA,IAACjD,EAAA,CAAO,QAAQ,UAAU,KAAK,OAAO,QAAS0C,GAC5C,YAAeO,EAAAA,kBAAAA,IAACO,YAAA,CAAA,CAAc,EAAKP,wBAACQ,EAAAA,YAAc,CAAA,CACrD,CAAA,EAEJ,EAEAT,EAAAA,kBAAAA,KAAC,MAAA,CAAI,UAAU,0BACZ,SAAA,CAAA,CAACnD,GACAoD,EAAAA,kBAAAA,IAACjD,EAAA,CACC,QAAQ,UACR,KAAK,OACL,QAAS,IAAMgB,EAASvB,EAAc,CAAC,EACvC,SAAUA,GAAe,EAEzB,iCAACiE,EAAAA,YAAA,CAAA,CAAgB,CAAA,CAAA,EAIrBT,EAAAA,kBAAAA,IAAChD,GAAA,CACC,KAAK,SACL,IAAK,EACL,IAAKxB,EACL,MAAOgB,EACP,SAAW,GAAMuB,EAAS,SAAS,EAAE,OAAO,KAAK,GAAK,CAAC,EACvD,SAAUnB,EACV,SAAUA,EACV,MAAOA,EAAe,iBAAmB,OACzC,UAAU,kBAAA,CAAA,EAEZmD,EAAAA,kBAAAA,KAAC,OAAA,CAAK,UAAU,gCAAgC,SAAA,CAAA,KAAGvE,CAAA,EAAW,EAE7D,CAACoB,GACAoD,EAAAA,kBAAAA,IAACjD,EAAA,CACC,QAAQ,UACR,KAAK,OACL,QAAS,IAAMgB,EAASvB,EAAc,CAAC,EACvC,SAAUhB,EAAa,GAAKgB,GAAehB,EAE3C,iCAACkF,EAAAA,aAAA,CAAA,CAAiB,CAAA,CAAA,CACpB,CAAA,CAEJ,CAAA,CAAA,CAAA,EAtGqB,KA4GrBC,EAAgB,IACpBX,EAAAA,kBAAAA,IAAC,MAAA,CAAI,UAAU,0CACb,SAAAA,EAAAA,kBAAAA,IAAC,IAAA,CAAE,UAAU,wBAAyB,SAAAvF,EAAA,CAAY,EACpD,EAIImG,EAAc,IAClBZ,EAAAA,kBAAAA,IAAC,MAAA,CAAI,UAAU,0FACb,SAAAD,EAAAA,kBAAAA,KAAC,MAAA,CAAI,UAAU,WACb,SAAA,CAAAC,EAAAA,kBAAAA,IAAC,IAAA,CAAE,UAAU,2BAA2B,SAAA,SAAM,EAC9CA,EAAAA,kBAAAA,IAAC,IAAA,CAAE,UAAU,qBAAsB,0BAAO,OAAA,CAAQ,CAAA,CAAA,CACpD,CAAA,CACF,EAIIa,GAAoB,IAAM,CAC9B,GAAI,CAAC1E,GAAU,OAAOwE,EAAA,EAEtB,KAAM,CAAE,SAAAG,EAAU,KAAAC,CAAA,EAAS5E,GAE3B,OACE6D,EAAAA,kBAAAA,IAAC,MAAA,CACC,IAAK1D,EACL,SAAUM,EAAewB,GAA4B,OACrD,UAAW,wCAAwCrE,IAAoB,EAAE,GAEzE,SAAAiG,EAAAA,kBAAAA,IAAC,MAAA,CAAI,UAAU,sCACb,SAAAA,EAAAA,kBAAAA,IAACc,EAAA,CAEC,KAAMrI,EACN,YAAakF,GACb,QAAST,GACT,QAASyD,EAAA,EACT,MAAOC,EAAA,EACP,cAAehD,GAEd,SAAAtC,EACCsF,IACEhF,EAEF,MAAM,KAAK,IAAI,MAAMJ,CAAU,EAAG,CAACwF,EAAKC,IACtCjB,EAAAA,kBAAAA,IAAC,MAAA,CAEC,IAAM7B,GAAYF,GAAWgD,EAAQ,EAAG9C,CAAO,EAC/C,mBAAkB8C,EAAQ,EAC1B,UAAW,QAAQhH,GAAiB,EAAE,GAEtC,SAAA+F,EAAAA,kBAAAA,IAACe,EAAA,CACC,WAAYE,EAAQ,EACpB,gBAAiB,GACjB,sBAAuB,GACvB,MAAOhF,GACP,MAAAQ,EACA,OAAQC,EACR,gBAAiB,IAAMlC,GAAA,YAAAA,EAAeyG,EAAQ,EAAC,CAAA,CACjD,EAbK,QAAQA,EAAQ,CAAC,EAAA,CAezB,EAGDjB,EAAAA,kBAAAA,IAAC,MAAA,CAAI,UAAW/F,GAAiB,GAC/B,SAAA+F,EAAAA,kBAAAA,IAACe,EAAA,CACC,WAAYvE,EACZ,gBAAiB,GACjB,sBAAuB,GACvB,MAAOP,GACP,MAAAQ,EACA,OAAQC,EACR,gBAAiB,IAAMlC,GAAA,YAAAA,EAAegC,EAAW,CAAA,CACnD,CACF,CAAA,EA1CG/D,CAAA,CA4CP,CACF,CAAA,CAAA,CAGN,EAGMyI,GAAgB,IAAM,CAC1B,GAAI,CAAC5H,GAAe,CAACwC,GAAoB,CAACnB,GAAa,OAAO,KAG9D,MAAMwG,EAAsBC,GAAAA,WAE5B,OACEpB,EAAAA,kBAAAA,IAACmB,EAAA,CACC,YAAAxG,GACA,YAAA6B,EACA,YAAaqD,GACb,WAAY,CACV,KAAMxF,EAAW,KACjB,SAAUA,EAAW,SACrB,YAAaA,EAAW,YACxB,YAAaA,EAAW,YACxB,WAAYA,EAAW,WACvB,SAAA4C,EAAA,CACF,CAAA,CAGN,EAGMoE,GAAkB,IAClB,CAAC1H,IAAmBiD,EAAqB,KAG3CmD,EAAAA,kBAAAA,KAAC,MAAA,CAAI,UAAU,qEACb,SAAA,CAAAA,EAAAA,kBAAAA,KAAChD,EAAA,CACC,QAAQ,YACR,KAAK,KACL,QAAS,IAAMgB,EAASvB,EAAc,CAAC,EACvC,SAAUI,GAAgBJ,GAAe,EACzC,MAAOI,EAAe,gBAAkB,OAExC,SAAA,CAAAoD,EAAAA,kBAAAA,IAACS,EAAAA,YAAA,EAAgB,EACjBT,EAAAA,kBAAAA,IAAC,OAAA,CAAK,UAAU,OAAO,SAAA,KAAA,CAAG,CAAA,CAAA,CAAA,EAE5BD,EAAAA,kBAAAA,KAAChD,EAAA,CACC,QAAQ,YACR,KAAK,KACL,QAAS,IAAMgB,EAASvB,EAAc,CAAC,EACvC,SAAUI,GAAgBJ,GAAehB,EACzC,MAAOoB,EAAe,gBAAkB,OAExC,SAAA,CAAAoD,EAAAA,kBAAAA,IAAC,OAAA,CAAK,UAAU,OAAO,SAAA,MAAG,0BACzBU,EAAAA,aAAA,CAAA,CAAiB,CAAA,CAAA,CAAA,CACpB,EACF,EAKJ,GAAI,CAACrG,EACH,OACE2F,EAAAA,kBAAAA,IAAC,MAAA,CAAI,UAAU,mCAAmC,SAAA,kCAElD,EAKJ,GAAI1G,EAAa,CACf,MAAMgI,EAA8B,CAAA,EAOpC,GANKjH,EAAW,MAAMiH,EAAkB,KAAK,MAAM,EAC9CjH,EAAW,UAAUiH,EAAkB,KAAK,UAAU,EACtDjH,EAAW,aAAaiH,EAAkB,KAAK,aAAa,EAC5DjH,EAAW,aAAaiH,EAAkB,KAAK,aAAa,EAC5DjH,EAAW,YAAYiH,EAAkB,KAAK,YAAY,EAE3DA,EAAkB,OAAS,EAAG,CAChC,MAAMC,EACJD,EAAkB,SAAW,EACzBA,EAAkB,CAAC,EACnB,GAAGA,EAAkB,MAAM,EAAG,EAAE,EAAE,KAAK,GAAG,CAAC,MAAMA,EAAkBA,EAAkB,OAAS,CAAC,CAAC,GACtG,OACEvB,EAAAA,kBAAAA,KAAC,MAAA,CAAI,UAAU,mCAAmC,SAAA,CAAA,gBAClCwB,EAAsB,KAAA,EACtC,CAEJ,CACF,CAEA,OACExB,EAAAA,kBAAAA,KAAC,MAAA,CAAI,IAAK1D,GACR,SAAA,CAAA0D,EAAAA,kBAAAA,KAAClD,IAAK,UAAAhD,GACH,SAAA,CAAAiG,GAAA,EACDE,EAAAA,kBAAAA,IAAClD,GAAA,CACC,UAAU,MACV,MAAO,CAAE,OAAQpB,GAAe,QAAU1B,EAAA,EAE1C,iCAAC,MAAA,CAAI,UAAU,uBAEb,SAAA+F,EAAAA,kBAAAA,KAAC,MAAA,CAAI,UAAU,8BACZ,SAAA,CAAAmB,GAAA,EACA9F,GACGuF,EAAA,EACArF,EACEsF,EAAA,EACAC,GAAA,CAAkB,CAAA,CAC1B,CAAA,CACF,CAAA,CAAA,CACF,EACF,EACCQ,GAAA,CAAgB,EACnB,CAEJ"}
|
package/dist/pdf-reader.js
CHANGED
|
@@ -69,7 +69,7 @@ function ot({
|
|
|
69
69
|
let e = !0;
|
|
70
70
|
return (async () => {
|
|
71
71
|
try {
|
|
72
|
-
const i = await import("
|
|
72
|
+
const i = await import("react-pdf");
|
|
73
73
|
if (typeof window < "u") {
|
|
74
74
|
const n = i.pdfjs, l = n == null ? void 0 : n.version;
|
|
75
75
|
n != null && n.GlobalWorkerOptions && l && (_ ? n.GlobalWorkerOptions.workerSrc = _ : n.GlobalWorkerOptions.workerSrc = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${l}/build/pdf.worker.min.mjs`, !N && n.GlobalWorkerOptions && (n.GlobalWorkerOptions.cMapUrl = `https://unpkg.com/pdfjs-dist@${l}/cmaps/`), !k && n.GlobalWorkerOptions && (n.GlobalWorkerOptions.standardFontDataUrl = `https://unpkg.com/pdfjs-dist@${l}/standard_fonts/`));
|
package/dist/pdf-reader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pdf-reader.js","sources":["../src/components/PDFReader.tsx"],"sourcesContent":["import {\n ChevronLeft as ChevronLeftIcon,\n ChevronRight as ChevronRightIcon,\n FileText as FileTextIcon,\n Maximize2 as Maximize2Icon,\n Minimize2 as Minimize2Icon,\n PanelLeft as PanelLeftIcon,\n RotateCw as RotateCwIcon,\n ScrollText as ScrollTextIcon,\n ZoomIn as ZoomInIcon,\n ZoomOut as ZoomOutIcon,\n} from 'lucide-react';\nimport { useState, useCallback, useEffect, useMemo, useRef } from 'react';\nimport type { HTMLAttributes } from 'react';\n\nimport type {\n CardComponent,\n ButtonComponent,\n InputComponent,\n SkeletonComponent,\n} from '../types/component-types';\n\nimport type { PDFDocumentProxy } from './PDFSidebar';\nimport { PDFSidebar } from './PDFSidebar';\n\n/**\n * PDFReader UI 组件接口\n */\nexport interface PDFReaderUIComponents {\n /** Card 组件 (必需) */\n Card: CardComponent;\n /** CardContent 组件 (必需) */\n CardContent: React.ComponentType<HTMLAttributes<HTMLDivElement>>;\n /** Button 组件 (必需) */\n Button: ButtonComponent;\n /** Input 组件 (必需) */\n Input: InputComponent;\n /** Skeleton 组件 (必需) */\n Skeleton: SkeletonComponent;\n /** Tabs 组件 (showSidebar=true 时必需) */\n Tabs?: React.ComponentType<{\n value?: string;\n onValueChange?: (value: string) => void;\n children?: React.ReactNode;\n defaultValue?: string;\n }>;\n /** TabsList 组件 (showSidebar=true 时必需) */\n TabsList?: React.ComponentType<HTMLAttributes<HTMLDivElement>>;\n /** TabsTrigger 组件 (showSidebar=true 时必需) */\n TabsTrigger?: React.ComponentType<{\n value: string;\n children?: React.ReactNode;\n }>;\n /** TabsContent 组件 (showSidebar=true 时必需) */\n TabsContent?: React.ComponentType<{\n value: string;\n children?: React.ReactNode;\n }>;\n /** ScrollArea 组件 (showSidebar=true 时必需) */\n ScrollArea?: React.ComponentType<HTMLAttributes<HTMLDivElement>>;\n}\n\n/**\n * PDFReader 组件 Props\n */\nexport interface PDFReaderProps {\n // ==================== 基础配置 ====================\n /** PDF 文件 URL (必需) */\n url: string;\n\n // ==================== 初始状态 ====================\n /** 初始页码 (默认 1) */\n initialPage?: number;\n /** 初始缩放比例 (默认 1.0) */\n initialScale?: number;\n /** 初始旋转角度 (默认 0) */\n initialRotation?: number;\n\n // ==================== 受控模式 ====================\n /** 当前页码 (受控) */\n currentPage?: number;\n /** 页码变化回调 */\n onPageChange?: (page: number) => void;\n /** 缩放比例 (受控) */\n scale?: number;\n /** 缩放变化回调 */\n onScaleChange?: (scale: number) => void;\n /** 旋转角度 (受控) */\n rotation?: number;\n /** 旋转变化回调 */\n onRotationChange?: (rotation: number) => void;\n\n // ==================== 缩放限制 ====================\n /** 最小缩放比例 (默认 0.5) */\n minScale?: number;\n /** 最大缩放比例 (默认 2.5) */\n maxScale?: number;\n\n // ==================== 功能开关 ====================\n /** 显示工具栏 (默认 true) */\n showToolbar?: boolean;\n /** 显示侧边栏 (默认 true) */\n showSidebar?: boolean;\n /** 显示旋转按钮 (默认 true) */\n showRotation?: boolean;\n /** 显示模式切换按钮 (默认 true) */\n showModeToggle?: boolean;\n /** 显示全屏按钮 (默认 true) */\n showFullscreen?: boolean;\n /** 启用键盘快捷键 (默认 true) */\n enableHotkeys?: boolean;\n /** 启用移动端导航 (默认 true) */\n enableMobileNav?: boolean;\n\n // ==================== 显示模式 ====================\n /** 显示模式: 'scroll' 显示所有页面, 'single' 单页模式 (默认 'single') */\n displayMode?: 'scroll' | 'single';\n\n // ==================== 样式定制 ====================\n /** 容器类名 */\n className?: string;\n /** 工具栏类名 */\n toolbarClassName?: string;\n /** 内容区域类名 */\n contentClassName?: string;\n /** 阅读区域高度限制 (默认 '80vh') */\n contentHeight?: string | number;\n /** 页面类名 */\n pageClassName?: string;\n\n // ==================== Worker 配置 ====================\n /** Worker 文件 URL (可选,默认使用 CDN) */\n workerUrl?: string;\n /** CMap 文件 URL (可选,默认使用 CDN) */\n cMapUrl?: string;\n /** 标准字体数据 URL (可选,默认使用 CDN) */\n standardFontDataUrl?: string;\n\n // ==================== UI 组件注入 ====================\n /** UI 组件 */\n components: PDFReaderUIComponents;\n\n // ==================== 回调函数 ====================\n /** 加载成功回调 */\n onLoadSuccess?: (pdf: PDFDocumentProxy) => void;\n /** 加载错误回调 */\n onLoadError?: (error: Error) => void;\n /** 页面渲染回调 */\n onPageRender?: (pageIndex: number) => void;\n\n // ==================== 文本配置 ====================\n /** 加载文本 (默认 '正在加载PDF文档...') */\n loadingText?: string;\n /** 错误文本 (默认 'PDF加载失败') */\n errorText?: string;\n}\n\n/**\n * debounce hook (替代 lodash.debounce)\n */\nfunction useDebounce<T extends (...args: any[]) => any>(\n callback: T,\n delay: number\n): T {\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined\n );\n return useCallback(\n (...args: Parameters<T>) => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n timeoutRef.current = setTimeout(() => callback(...args), delay);\n },\n [callback, delay]\n ) as T;\n}\n\n/**\n * PDFReader 组件\n *\n * 功能完整的 PDF 阅读器组件,支持侧边栏导航、页面旋转、显示模式切换等高级特性。\n *\n * @example\n * ```tsx\n * import { PDFReader } from '@turinhub/atomix-common-ui/pdf-reader';\n * import { Card, Button, Input, Label, Skeleton } from '@/components/ui';\n * import { Tabs, ScrollArea } from '@/components/ui';\n *\n * <PDFReader\n * url=\"/documents/sample.pdf\"\n * components={{\n * Card,\n * CardContent: Card.Content,\n * Button,\n * Input,\n * Label,\n * Skeleton,\n * Tabs,\n * TabsList: Tabs.List,\n * TabsTrigger: Tabs.Trigger,\n * TabsContent: Tabs.Content,\n * ScrollArea,\n * }}\n * initialPage={1}\n * initialScale={1.0}\n * showSidebar={true}\n * showRotation={true}\n * showModeToggle={true}\n * enableHotkeys={true}\n * />\n * ```\n */\nexport function PDFReader({\n url,\n initialPage = 1,\n initialScale = 1.0,\n initialRotation = 0,\n currentPage: controlledPage,\n onPageChange,\n scale: controlledScale,\n onScaleChange,\n rotation: controlledRotation,\n onRotationChange,\n minScale = 0.5,\n maxScale = 2.5,\n showToolbar = true,\n showSidebar = true,\n showRotation = true,\n showModeToggle = true,\n showFullscreen = true,\n enableHotkeys = true,\n enableMobileNav = true,\n displayMode: initialDisplayMode = 'single',\n className,\n toolbarClassName,\n contentClassName,\n contentHeight = '80vh',\n pageClassName,\n workerUrl,\n cMapUrl,\n standardFontDataUrl,\n components,\n onLoadSuccess,\n onLoadError,\n onPageRender,\n loadingText = '正在加载PDF文档...',\n errorText = 'PDF加载失败',\n}: PDFReaderProps) {\n // ==================== 状态管理 ====================\n const [pdfDocument, setPdfDocument] = useState<PDFDocumentProxy | null>(null);\n const [internalPage, setInternalPage] = useState(initialPage);\n const [internalScale, setInternalScale] = useState(initialScale);\n const [internalRotation, setInternalRotation] = useState(initialRotation);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [totalPages, setTotalPages] = useState(0);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const [showAllPages, setShowAllPages] = useState(\n initialDisplayMode === 'scroll'\n );\n const [showSidebarState, setShowSidebarState] = useState(showSidebar);\n\n // Sync showSidebarState with prop changes\n useEffect(() => {\n setShowSidebarState(showSidebar);\n }, [showSidebar]);\n\n const [pageWidth, setPageWidth] = useState<number | undefined>(undefined);\n\n // 动态导入 react-pdf\n const [ReactPDF, setReactPDF] = useState<any>(null);\n\n const readerRef = useRef<HTMLDivElement>(null);\n const pdfContainerRef = useRef<HTMLDivElement>(null);\n const pageRefs = useRef<Map<number, HTMLDivElement>>(new Map());\n\n // 使用受控或非受控模式\n const currentPage = controlledPage ?? internalPage;\n const scale = controlledScale ?? internalScale;\n const rotation = controlledRotation ?? internalRotation;\n const isPageControlled = controlledPage !== undefined;\n const isScrollMode = showAllPages;\n\n // ==================== 组件解构 ====================\n const { Card, CardContent, Button, Input, Skeleton } = components || {};\n\n useEffect(() => {\n setPdfDocument(null);\n setTotalPages(0);\n setError(null);\n setIsLoading(false);\n if (!isPageControlled) {\n setInternalPage(Math.max(1, initialPage));\n }\n }, [url, initialPage, isPageControlled]);\n\n // ==================== PDF 选项 ====================\n const pdfOptions = useMemo(() => {\n const options: Record<string, unknown> = {\n withCredentials: false,\n };\n\n if (cMapUrl) {\n options.cMapUrl = cMapUrl;\n options.cMapPacked = true;\n }\n\n if (standardFontDataUrl) {\n options.standardFontDataUrl = standardFontDataUrl;\n }\n\n return options;\n }, [cMapUrl, standardFontDataUrl]);\n\n // ==================== 动态导入 react-pdf ====================\n useEffect(() => {\n let isMounted = true;\n\n const loadReactPDF = async () => {\n try {\n // 动态导入 react-pdf\n const pdfModule = await import('react-pdf');\n\n // 设置 worker\n if (typeof window !== 'undefined') {\n const pdfjs = (pdfModule as any).pdfjs;\n const workerVersion = pdfjs?.version;\n\n if (pdfjs?.GlobalWorkerOptions && workerVersion) {\n if (workerUrl) {\n pdfjs.GlobalWorkerOptions.workerSrc = workerUrl;\n } else {\n // 使用 CDN\n pdfjs.GlobalWorkerOptions.workerSrc = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${workerVersion}/build/pdf.worker.min.mjs`;\n }\n\n // 如果没有提供自定义 URL,使用 CDN 默认值\n if (!cMapUrl && pdfjs.GlobalWorkerOptions) {\n (pdfjs.GlobalWorkerOptions as any).cMapUrl =\n `https://unpkg.com/pdfjs-dist@${workerVersion}/cmaps/`;\n }\n if (!standardFontDataUrl && pdfjs.GlobalWorkerOptions) {\n (pdfjs.GlobalWorkerOptions as any).standardFontDataUrl =\n `https://unpkg.com/pdfjs-dist@${workerVersion}/standard_fonts/`;\n }\n }\n }\n\n if (isMounted) {\n setReactPDF(pdfModule);\n }\n } catch (err) {\n if (isMounted) {\n const loadError =\n err instanceof Error ? err : new Error('无法加载 react-pdf 库');\n setError(loadError);\n setIsLoading(false);\n onLoadError?.(loadError);\n }\n }\n };\n\n loadReactPDF();\n\n return () => {\n isMounted = false;\n };\n }, [workerUrl, cMapUrl, standardFontDataUrl, onLoadError]);\n\n // ==================== 处理加载错误 ====================\n const onDocumentLoadError = useCallback(\n (err: Error) => {\n console.error('PDF加载失败:', err);\n console.error('PDF URL:', url);\n setPdfDocument(null);\n setTotalPages(0);\n setError(\n new Error(`${errorText}: ${err.message || '请检查文件路径或网络连接'}`)\n );\n setIsLoading(false);\n onLoadError?.(err);\n },\n [url, errorText, onLoadError]\n );\n\n const onDocumentLoadSuccess = useCallback(\n (pdf: PDFDocumentProxy) => {\n setPdfDocument(pdf);\n setTotalPages(pdf.numPages);\n setError(null);\n setIsLoading(false);\n\n if (!isPageControlled) {\n setInternalPage((page) =>\n Math.max(1, Math.min(page, Math.max(pdf.numPages, 1)))\n );\n }\n\n onLoadSuccess?.(pdf);\n },\n [isPageControlled, onLoadSuccess]\n );\n\n // ==================== 页面导航 ====================\n const goToPage = useCallback(\n (page: number) => {\n if (!Number.isFinite(page)) return;\n const newPage =\n totalPages > 0\n ? Math.max(1, Math.min(Math.trunc(page), totalPages))\n : Math.max(1, Math.trunc(page));\n if (!isPageControlled) {\n setInternalPage(newPage);\n }\n if (newPage !== currentPage) {\n onPageChange?.(newPage);\n }\n },\n [totalPages, isPageControlled, currentPage, onPageChange]\n );\n\n const setPageRef = useCallback(\n (pageNumber: number, element: HTMLDivElement | null) => {\n if (element) {\n pageRefs.current.set(pageNumber, element);\n } else {\n pageRefs.current.delete(pageNumber);\n }\n },\n []\n );\n\n const syncScrollModeCurrentPage = useCallback(() => {\n const container = pdfContainerRef.current;\n if (!container || !isScrollMode || totalPages <= 0) return;\n\n const containerTop = container.getBoundingClientRect().top;\n let closestPage = currentPage;\n let closestDistance = Number.POSITIVE_INFINITY;\n\n pageRefs.current.forEach((element, pageNumber) => {\n const distance = Math.abs(\n element.getBoundingClientRect().top - containerTop\n );\n if (distance < closestDistance) {\n closestDistance = distance;\n closestPage = pageNumber;\n }\n });\n\n if (closestPage !== currentPage) {\n goToPage(closestPage);\n }\n }, [currentPage, goToPage, isScrollMode, totalPages]);\n\n // ==================== 缩放控制 ====================\n const zoom = useCallback(\n (delta: number) => {\n const newScale = Math.max(minScale, Math.min(maxScale, scale + delta));\n if (controlledScale === undefined) {\n setInternalScale(newScale);\n }\n onScaleChange?.(newScale);\n },\n [scale, minScale, maxScale, controlledScale, onScaleChange]\n );\n\n // ==================== 旋转控制 ====================\n const rotate = useCallback(() => {\n const newRotation = (rotation + 90) % 360;\n if (controlledRotation === undefined) {\n setInternalRotation(newRotation);\n }\n onRotationChange?.(newRotation);\n }, [rotation, controlledRotation, onRotationChange]);\n\n // ==================== 处理窗口大小变化 ====================\n const debouncedUpdatePageWidth = useDebounce((width: number) => {\n setPageWidth(width);\n }, 100);\n\n // Use ResizeObserver to track container size changes\n useEffect(() => {\n if (!pdfContainerRef.current) return;\n\n const container = pdfContainerRef.current;\n const updateWidth = () => {\n debouncedUpdatePageWidth(container.clientWidth);\n };\n\n // Initial measurement\n updateWidth();\n\n // Set up ResizeObserver\n const resizeObserver = new ResizeObserver(() => {\n updateWidth();\n });\n\n resizeObserver.observe(container);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [debouncedUpdatePageWidth]);\n\n // ==================== 键盘快捷键 ====================\n useEffect(() => {\n if (!enableHotkeys) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement | null;\n const activeElement =\n typeof document !== 'undefined'\n ? (document.activeElement as HTMLElement | null)\n : null;\n const focusedElement = target || activeElement;\n const role = focusedElement?.getAttribute('role');\n\n if (\n focusedElement &&\n (focusedElement.tagName === 'INPUT' ||\n focusedElement.tagName === 'TEXTAREA' ||\n focusedElement.tagName === 'SELECT' ||\n focusedElement.isContentEditable ||\n role === 'textbox' ||\n role === 'spinbutton')\n ) {\n return;\n }\n\n // Ctrl/Cmd + 加号: 放大\n if ((e.ctrlKey || e.metaKey) && (e.key === '=' || e.key === '+')) {\n e.preventDefault();\n zoom(0.1);\n }\n // Ctrl/Cmd + 减号: 缩小\n else if ((e.ctrlKey || e.metaKey) && e.key === '-') {\n e.preventDefault();\n zoom(-0.1);\n }\n // 左箭头: 上一页\n else if (!isScrollMode && e.key === 'ArrowLeft') {\n e.preventDefault();\n goToPage(currentPage - 1);\n }\n // 右箭头: 下一页\n else if (!isScrollMode && e.key === 'ArrowRight') {\n e.preventDefault();\n goToPage(currentPage + 1);\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [enableHotkeys, currentPage, goToPage, isScrollMode, zoom]);\n\n // ==================== 全屏切换 ====================\n const toggleFullscreen = useCallback(async () => {\n if (typeof document === 'undefined') return;\n\n if (!document.fullscreenElement) {\n try {\n await readerRef.current?.requestFullscreen?.();\n setIsFullscreen(true);\n } catch (err) {\n console.error('Error attempting to enable fullscreen:', err);\n }\n } else {\n if (document.exitFullscreen) {\n await document.exitFullscreen();\n setIsFullscreen(false);\n }\n }\n }, []);\n\n // ==================== 监听全屏状态变化 ====================\n useEffect(() => {\n if (typeof document === 'undefined') return;\n\n const handleFullscreenChange = () => {\n setIsFullscreen(!!document.fullscreenElement);\n };\n\n document.addEventListener('fullscreenchange', handleFullscreenChange);\n return () => {\n document.removeEventListener('fullscreenchange', handleFullscreenChange);\n };\n }, []);\n\n // ==================== 处理侧边栏页面点击 ====================\n const handleSidebarPageClick = useCallback(\n (pageNumber: number) => {\n goToPage(pageNumber);\n setShowAllPages(false);\n },\n [goToPage]\n );\n\n // ==================== 渲染工具栏 ====================\n const renderToolbar = () => {\n if (!showToolbar) return null;\n\n return (\n <div\n className={`flex items-center justify-between gap-4 border-b px-4 py-2 ${toolbarClassName || ''}`}\n >\n <div className=\"flex items-center gap-2\">\n {/* 侧边栏切换 */}\n {showSidebar && (\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setShowSidebarState(!showSidebarState)}\n title={showSidebarState ? '隐藏侧边栏' : '显示侧边栏'}\n >\n <PanelLeftIcon />\n </Button>\n )}\n\n {/* 缩放控制 */}\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => zoom(-0.1)}\n disabled={scale <= minScale}\n >\n <ZoomOutIcon />\n </Button>\n <span className=\"min-w-[3rem] text-center text-sm\">\n {Math.round(scale * 100)}%\n </span>\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => zoom(0.1)}\n disabled={scale >= maxScale}\n >\n <ZoomInIcon />\n </Button>\n\n {/* 旋转控制 */}\n {showRotation && (\n <Button variant=\"outline\" size=\"icon\" onClick={rotate}>\n <RotateCwIcon />\n </Button>\n )}\n\n {/* 显示模式切换 */}\n {showModeToggle && (\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setShowAllPages(!showAllPages)}\n title={showAllPages ? '单页模式' : '滚动模式'}\n >\n {showAllPages ? <ScrollTextIcon /> : <FileTextIcon />}\n </Button>\n )}\n\n {/* 全屏切换 */}\n {showFullscreen && (\n <Button variant=\"outline\" size=\"icon\" onClick={toggleFullscreen}>\n {isFullscreen ? <Minimize2Icon /> : <Maximize2Icon />}\n </Button>\n )}\n </div>\n\n <div className=\"flex items-center gap-2\">\n {!isScrollMode && (\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => goToPage(currentPage - 1)}\n disabled={currentPage <= 1}\n >\n <ChevronLeftIcon />\n </Button>\n )}\n\n <Input\n type=\"number\"\n min={1}\n max={totalPages}\n value={currentPage}\n onChange={(e) => goToPage(parseInt(e.target.value) || 1)}\n disabled={isScrollMode}\n readOnly={isScrollMode}\n title={isScrollMode ? '滚动模式下页码仅显示当前位置' : undefined}\n className=\"w-16 text-center\"\n />\n <span className=\"text-sm text-muted-foreground\">/ {totalPages}</span>\n\n {!isScrollMode && (\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => goToPage(currentPage + 1)}\n disabled={totalPages > 0 && currentPage >= totalPages}\n >\n <ChevronRightIcon />\n </Button>\n )}\n </div>\n </div>\n );\n };\n\n // ==================== 渲染加载状态 ====================\n const renderLoading = () => (\n <div className=\"flex h-full items-center justify-center\">\n <p className=\"text-muted-foreground\">{loadingText}</p>\n </div>\n );\n\n // ==================== 渲染错误状态 ====================\n const renderError = () => (\n <div className=\"flex h-full min-h-[400px] items-center justify-center px-4 text-center text-destructive\">\n <div className=\"max-w-md\">\n <p className=\"mb-2 text-lg font-medium\">文件加载失败</p>\n <p className=\"text-sm opacity-80\">{error?.message}</p>\n </div>\n </div>\n );\n\n // ==================== 渲染 PDF 文档 ====================\n const renderPDFDocument = () => {\n if (!ReactPDF) return renderLoading();\n\n const { Document, Page } = ReactPDF;\n\n return (\n <div\n ref={pdfContainerRef}\n onScroll={isScrollMode ? syncScrollModeCurrentPage : undefined}\n className={`pdf-container flex-1 overflow-y-auto ${contentClassName || ''}`}\n >\n <div className=\"flex min-h-full justify-center px-4\">\n <Document\n key={url}\n file={url}\n onLoadError={onDocumentLoadError}\n options={pdfOptions}\n loading={renderLoading()}\n error={renderError()}\n onLoadSuccess={onDocumentLoadSuccess}\n >\n {error ? (\n renderError()\n ) : showAllPages ? (\n // 显示所有页面模式\n Array.from(new Array(totalPages), (_el, index) => (\n <div\n key={`page_${index + 1}`}\n ref={(element) => setPageRef(index + 1, element)}\n data-page-number={index + 1}\n className={`mb-4 ${pageClassName || ''}`}\n >\n <Page\n pageNumber={index + 1}\n renderTextLayer={false}\n renderAnnotationLayer={false}\n width={pageWidth}\n scale={scale}\n rotate={rotation}\n onRenderSuccess={() => onPageRender?.(index + 1)}\n />\n </div>\n ))\n ) : (\n // 单页模式\n <div className={pageClassName || ''}>\n <Page\n pageNumber={currentPage}\n renderTextLayer={false}\n renderAnnotationLayer={false}\n width={pageWidth}\n scale={scale}\n rotate={rotation}\n onRenderSuccess={() => onPageRender?.(currentPage)}\n />\n </div>\n )}\n </Document>\n </div>\n </div>\n );\n };\n\n // ==================== 渲染侧边栏 ====================\n const renderSidebar = () => {\n if (!showSidebar || !showSidebarState || !pdfDocument) return null;\n\n // 使用导入的 PDFSidebar 组件\n const PDFSidebarComponent = PDFSidebar;\n\n return (\n <PDFSidebarComponent\n pdfDocument={pdfDocument}\n currentPage={currentPage}\n onPageClick={handleSidebarPageClick}\n components={{\n Tabs: components.Tabs!,\n TabsList: components.TabsList!,\n TabsTrigger: components.TabsTrigger!,\n TabsContent: components.TabsContent!,\n ScrollArea: components.ScrollArea!,\n Skeleton,\n }}\n />\n );\n };\n\n // ==================== 渲染移动端导航 ====================\n const renderMobileNav = () => {\n if (!enableMobileNav || isScrollMode) return null;\n\n return (\n <div className=\"fixed bottom-4 left-1/2 z-50 flex -translate-x-1/2 gap-2 md:hidden\">\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => goToPage(currentPage - 1)}\n disabled={isScrollMode || currentPage <= 1}\n title={isScrollMode ? '滚动模式下通过滚动定位页面' : undefined}\n >\n <ChevronLeftIcon />\n <span className=\"ml-1\">上一页</span>\n </Button>\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => goToPage(currentPage + 1)}\n disabled={isScrollMode || currentPage >= totalPages}\n title={isScrollMode ? '滚动模式下通过滚动定位页面' : undefined}\n >\n <span className=\"mr-1\">下一页</span>\n <ChevronRightIcon />\n </Button>\n </div>\n );\n };\n\n // ==================== 组件验证 ====================\n if (!components) {\n return (\n <div className=\"p-4 text-center text-destructive\">\n 错误:请通过 components prop 注入 UI 组件\n </div>\n );\n }\n\n // 验证侧边栏所需的所有组件\n if (showSidebar) {\n const missingComponents: string[] = [];\n if (!components.Tabs) missingComponents.push('Tabs');\n if (!components.TabsList) missingComponents.push('TabsList');\n if (!components.TabsTrigger) missingComponents.push('TabsTrigger');\n if (!components.TabsContent) missingComponents.push('TabsContent');\n if (!components.ScrollArea) missingComponents.push('ScrollArea');\n\n if (missingComponents.length > 0) {\n const missingComponentsText =\n missingComponents.length === 1\n ? missingComponents[0]\n : `${missingComponents.slice(0, -1).join('、')} 和 ${missingComponents[missingComponents.length - 1]}`;\n return (\n <div className=\"p-4 text-center text-destructive\">\n 错误:侧边栏功能需要注入 {missingComponentsText} 组件\n </div>\n );\n }\n }\n\n return (\n <div ref={readerRef}>\n <Card className={className}>\n {renderToolbar()}\n <CardContent\n className=\"p-0\"\n style={{ height: isFullscreen ? '100vh' : contentHeight }}\n >\n <div className=\"flex h-full flex-col\">\n {/* PDF 显示区域 */}\n <div className=\"flex flex-1 overflow-hidden\">\n {renderSidebar()}\n {isLoading\n ? renderLoading()\n : error\n ? renderError()\n : renderPDFDocument()}\n </div>\n </div>\n </CardContent>\n </Card>\n {renderMobileNav()}\n </div>\n );\n}\n"],"names":["useDebounce","callback","delay","timeoutRef","useRef","useCallback","args","PDFReader","url","initialPage","initialScale","initialRotation","controlledPage","onPageChange","controlledScale","onScaleChange","controlledRotation","onRotationChange","minScale","maxScale","showToolbar","showSidebar","showRotation","showModeToggle","showFullscreen","enableHotkeys","enableMobileNav","initialDisplayMode","className","toolbarClassName","contentClassName","contentHeight","pageClassName","workerUrl","cMapUrl","standardFontDataUrl","components","onLoadSuccess","onLoadError","onPageRender","loadingText","errorText","pdfDocument","setPdfDocument","useState","internalPage","setInternalPage","internalScale","setInternalScale","internalRotation","setInternalRotation","isLoading","setIsLoading","error","setError","totalPages","setTotalPages","isFullscreen","setIsFullscreen","showAllPages","setShowAllPages","showSidebarState","setShowSidebarState","useEffect","pageWidth","setPageWidth","ReactPDF","setReactPDF","readerRef","pdfContainerRef","pageRefs","currentPage","scale","rotation","isPageControlled","isScrollMode","Card","CardContent","Button","Input","Skeleton","pdfOptions","useMemo","options","isMounted","pdfModule","pdfjs","workerVersion","err","loadError","onDocumentLoadError","onDocumentLoadSuccess","pdf","page","goToPage","newPage","setPageRef","pageNumber","element","syncScrollModeCurrentPage","container","containerTop","closestPage","closestDistance","distance","zoom","delta","newScale","rotate","newRotation","debouncedUpdatePageWidth","width","updateWidth","resizeObserver","handleKeyDown","e","target","activeElement","focusedElement","role","toggleFullscreen","_b","_a","handleFullscreenChange","handleSidebarPageClick","renderToolbar","jsxs","jsx","PanelLeftIcon","ZoomOutIcon","ZoomInIcon","RotateCwIcon","ScrollTextIcon","FileTextIcon","Minimize2Icon","Maximize2Icon","ChevronLeftIcon","ChevronRightIcon","renderLoading","renderError","renderPDFDocument","Document","Page","_el","index","renderSidebar","PDFSidebarComponent","PDFSidebar","renderMobileNav","missingComponents","missingComponentsText"],"mappings":";;;;AAgKA,SAASA,GACPC,GACAC,GACG;AACH,QAAMC,IAAaC;AAAA,IACjB;AAAA,EAAA;AAEF,SAAOC;AAAA,IACL,IAAIC,MAAwB;AAC1B,MAAIH,EAAW,WACb,aAAaA,EAAW,OAAO,GAEjCA,EAAW,UAAU,WAAW,MAAMF,EAAS,GAAGK,CAAI,GAAGJ,CAAK;AAAA,IAChE;AAAA,IACA,CAACD,GAAUC,CAAK;AAAA,EAAA;AAEpB;AAqCO,SAASK,GAAU;AAAA,EACxB,KAAAC;AAAA,EACA,aAAAC,IAAc;AAAA,EACd,cAAAC,IAAe;AAAA,EACf,iBAAAC,IAAkB;AAAA,EAClB,aAAaC;AAAA,EACb,cAAAC;AAAA,EACA,OAAOC;AAAA,EACP,eAAAC;AAAA,EACA,UAAUC;AAAA,EACV,kBAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,UAAAC,IAAW;AAAA,EACX,aAAAC,KAAc;AAAA,EACd,aAAAC,IAAc;AAAA,EACd,cAAAC,KAAe;AAAA,EACf,gBAAAC,KAAiB;AAAA,EACjB,gBAAAC,KAAiB;AAAA,EACjB,eAAAC,IAAgB;AAAA,EAChB,iBAAAC,KAAkB;AAAA,EAClB,aAAaC,KAAqB;AAAA,EAClC,WAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,eAAAC,KAAgB;AAAA,EAChB,eAAAC;AAAA,EACA,WAAAC;AAAA,EACA,SAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,eAAAC;AAAA,EACA,aAAAC;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC,KAAc;AAAA,EACd,WAAAC,KAAY;AACd,GAAmB;AAEjB,QAAM,CAACC,IAAaC,CAAc,IAAIC,EAAkC,IAAI,GACtE,CAACC,IAAcC,CAAe,IAAIF,EAASnC,CAAW,GACtD,CAACsC,IAAeC,EAAgB,IAAIJ,EAASlC,CAAY,GACzD,CAACuC,IAAkBC,EAAmB,IAAIN,EAASjC,CAAe,GAClE,CAACwC,IAAWC,CAAY,IAAIR,EAAS,EAAK,GAC1C,CAACS,GAAOC,CAAQ,IAAIV,EAAuB,IAAI,GAC/C,CAACW,GAAYC,CAAa,IAAIZ,EAAS,CAAC,GACxC,CAACa,IAAcC,CAAe,IAAId,EAAS,EAAK,GAChD,CAACe,GAAcC,EAAe,IAAIhB;AAAA,IACtCjB,OAAuB;AAAA,EAAA,GAEnB,CAACkC,GAAkBC,EAAmB,IAAIlB,EAASvB,CAAW;AAGpE,EAAA0C,EAAU,MAAM;AACd,IAAAD,GAAoBzC,CAAW;AAAA,EACjC,GAAG,CAACA,CAAW,CAAC;AAEhB,QAAM,CAAC2C,IAAWC,EAAY,IAAIrB,EAA6B,MAAS,GAGlE,CAACsB,IAAUC,EAAW,IAAIvB,EAAc,IAAI,GAE5CwB,KAAYhE,EAAuB,IAAI,GACvCiE,IAAkBjE,EAAuB,IAAI,GAC7CkE,IAAWlE,EAAoC,oBAAI,KAAK,GAGxDmE,IAAc3D,KAAkBiC,IAChC2B,IAAQ1D,KAAmBiC,IAC3B0B,IAAWzD,KAAsBiC,IACjCyB,IAAmB9D,MAAmB,QACtC+D,IAAehB,GAGf,EAAE,MAAAiB,IAAM,aAAAC,IAAa,QAAAC,GAAQ,OAAAC,IAAO,UAAAC,GAAA,IAAa5C,KAAc,CAAA;AAErE,EAAA2B,EAAU,MAAM;AACd,IAAApB,EAAe,IAAI,GACnBa,EAAc,CAAC,GACfF,EAAS,IAAI,GACbF,EAAa,EAAK,GACbsB,KACH5B,EAAgB,KAAK,IAAI,GAAGrC,CAAW,CAAC;AAAA,EAE5C,GAAG,CAACD,GAAKC,GAAaiE,CAAgB,CAAC;AAGvC,QAAMO,KAAaC,GAAQ,MAAM;AAC/B,UAAMC,IAAmC;AAAA,MACvC,iBAAiB;AAAA,IAAA;AAGnB,WAAIjD,MACFiD,EAAQ,UAAUjD,GAClBiD,EAAQ,aAAa,KAGnBhD,MACFgD,EAAQ,sBAAsBhD,IAGzBgD;AAAA,EACT,GAAG,CAACjD,GAASC,CAAmB,CAAC;AAGjC,EAAA4B,EAAU,MAAM;AACd,QAAIqB,IAAY;AA8ChB,YA5CqB,YAAY;AAC/B,UAAI;AAEF,cAAMC,IAAY,MAAM,OAAO,qBAAW;AAG1C,YAAI,OAAO,SAAW,KAAa;AACjC,gBAAMC,IAASD,EAAkB,OAC3BE,IAAgBD,KAAA,gBAAAA,EAAO;AAE7B,UAAIA,KAAA,QAAAA,EAAO,uBAAuBC,MAC5BtD,IACFqD,EAAM,oBAAoB,YAAYrD,IAGtCqD,EAAM,oBAAoB,YAAY,2CAA2CC,CAAa,6BAI5F,CAACrD,KAAWoD,EAAM,wBACnBA,EAAM,oBAA4B,UACjC,gCAAgCC,CAAa,YAE7C,CAACpD,KAAuBmD,EAAM,wBAC/BA,EAAM,oBAA4B,sBACjC,gCAAgCC,CAAa;AAAA,QAGrD;AAEA,QAAIH,KACFjB,GAAYkB,CAAS;AAAA,MAEzB,SAASG,GAAK;AACZ,YAAIJ,GAAW;AACb,gBAAMK,IACJD,aAAe,QAAQA,IAAM,IAAI,MAAM,kBAAkB;AAC3D,UAAAlC,EAASmC,CAAS,GAClBrC,EAAa,EAAK,GAClBd,KAAA,QAAAA,EAAcmD;AAAA,QAChB;AAAA,MACF;AAAA,IACF,GAEA,GAEO,MAAM;AACX,MAAAL,IAAY;AAAA,IACd;AAAA,EACF,GAAG,CAACnD,GAAWC,GAASC,GAAqBG,CAAW,CAAC;AAGzD,QAAMoD,KAAsBrF;AAAA,IAC1B,CAACmF,MAAe;AACd,cAAQ,MAAM,YAAYA,CAAG,GAC7B,QAAQ,MAAM,YAAYhF,CAAG,GAC7BmC,EAAe,IAAI,GACnBa,EAAc,CAAC,GACfF;AAAA,QACE,IAAI,MAAM,GAAGb,EAAS,KAAK+C,EAAI,WAAW,cAAc,EAAE;AAAA,MAAA,GAE5DpC,EAAa,EAAK,GAClBd,KAAA,QAAAA,EAAckD;AAAA,IAChB;AAAA,IACA,CAAChF,GAAKiC,IAAWH,CAAW;AAAA,EAAA,GAGxBqD,KAAwBtF;AAAA,IAC5B,CAACuF,MAA0B;AACzB,MAAAjD,EAAeiD,CAAG,GAClBpC,EAAcoC,EAAI,QAAQ,GAC1BtC,EAAS,IAAI,GACbF,EAAa,EAAK,GAEbsB,KACH5B;AAAA,QAAgB,CAAC+C,MACf,KAAK,IAAI,GAAG,KAAK,IAAIA,GAAM,KAAK,IAAID,EAAI,UAAU,CAAC,CAAC,CAAC;AAAA,MAAA,GAIzDvD,KAAA,QAAAA,EAAgBuD;AAAA,IAClB;AAAA,IACA,CAAClB,GAAkBrC,CAAa;AAAA,EAAA,GAI5ByD,IAAWzF;AAAA,IACf,CAACwF,MAAiB;AAChB,UAAI,CAAC,OAAO,SAASA,CAAI,EAAG;AAC5B,YAAME,IACJxC,IAAa,IACT,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,MAAMsC,CAAI,GAAGtC,CAAU,CAAC,IAClD,KAAK,IAAI,GAAG,KAAK,MAAMsC,CAAI,CAAC;AAClC,MAAKnB,KACH5B,EAAgBiD,CAAO,GAErBA,MAAYxB,MACd1D,KAAA,QAAAA,EAAekF;AAAA,IAEnB;AAAA,IACA,CAACxC,GAAYmB,GAAkBH,GAAa1D,CAAY;AAAA,EAAA,GAGpDmF,KAAa3F;AAAA,IACjB,CAAC4F,GAAoBC,MAAmC;AACtD,MAAIA,IACF5B,EAAS,QAAQ,IAAI2B,GAAYC,CAAO,IAExC5B,EAAS,QAAQ,OAAO2B,CAAU;AAAA,IAEtC;AAAA,IACA,CAAA;AAAA,EAAC,GAGGE,KAA4B9F,EAAY,MAAM;AAClD,UAAM+F,IAAY/B,EAAgB;AAClC,QAAI,CAAC+B,KAAa,CAACzB,KAAgBpB,KAAc,EAAG;AAEpD,UAAM8C,IAAeD,EAAU,sBAAA,EAAwB;AACvD,QAAIE,IAAc/B,GACdgC,IAAkB,OAAO;AAE7B,IAAAjC,EAAS,QAAQ,QAAQ,CAAC4B,GAASD,MAAe;AAChD,YAAMO,KAAW,KAAK;AAAA,QACpBN,EAAQ,sBAAA,EAAwB,MAAMG;AAAA,MAAA;AAExC,MAAIG,KAAWD,MACbA,IAAkBC,IAClBF,IAAcL;AAAA,IAElB,CAAC,GAEGK,MAAgB/B,KAClBuB,EAASQ,CAAW;AAAA,EAExB,GAAG,CAAC/B,GAAauB,GAAUnB,GAAcpB,CAAU,CAAC,GAG9CkD,IAAOpG;AAAA,IACX,CAACqG,MAAkB;AACjB,YAAMC,IAAW,KAAK,IAAIzF,GAAU,KAAK,IAAIC,GAAUqD,IAAQkC,CAAK,CAAC;AACrE,MAAI5F,MAAoB,UACtBkC,GAAiB2D,CAAQ,GAE3B5F,KAAA,QAAAA,EAAgB4F;AAAA,IAClB;AAAA,IACA,CAACnC,GAAOtD,GAAUC,GAAUL,GAAiBC,CAAa;AAAA,EAAA,GAItD6F,KAASvG,EAAY,MAAM;AAC/B,UAAMwG,KAAepC,IAAW,MAAM;AACtC,IAAIzD,MAAuB,UACzBkC,GAAoB2D,CAAW,GAEjC5F,KAAA,QAAAA,EAAmB4F;AAAA,EACrB,GAAG,CAACpC,GAAUzD,GAAoBC,CAAgB,CAAC,GAG7C6F,KAA2B9G,GAAY,CAAC+G,MAAkB;AAC9D,IAAA9C,GAAa8C,CAAK;AAAA,EACpB,GAAG,GAAG;AAGN,EAAAhD,EAAU,MAAM;AACd,QAAI,CAACM,EAAgB,QAAS;AAE9B,UAAM+B,IAAY/B,EAAgB,SAC5B2C,IAAc,MAAM;AACxB,MAAAF,GAAyBV,EAAU,WAAW;AAAA,IAChD;AAGA,IAAAY,EAAA;AAGA,UAAMC,IAAiB,IAAI,eAAe,MAAM;AAC9C,MAAAD,EAAA;AAAA,IACF,CAAC;AAED,WAAAC,EAAe,QAAQb,CAAS,GAEzB,MAAM;AACX,MAAAa,EAAe,WAAA;AAAA,IACjB;AAAA,EACF,GAAG,CAACH,EAAwB,CAAC,GAG7B/C,EAAU,MAAM;AACd,QAAI,CAACtC,EAAe;AAEpB,UAAMyF,IAAgB,CAACC,MAAqB;AAC1C,YAAMC,IAASD,EAAE,QACXE,IACJ,OAAO,WAAa,MACf,SAAS,gBACV,MACAC,IAAiBF,KAAUC,GAC3BE,IAAOD,KAAA,gBAAAA,EAAgB,aAAa;AAE1C,MACEA,MACCA,EAAe,YAAY,WAC1BA,EAAe,YAAY,cAC3BA,EAAe,YAAY,YAC3BA,EAAe,qBACfC,MAAS,aACTA,MAAS,mBAMRJ,EAAE,WAAWA,EAAE,aAAaA,EAAE,QAAQ,OAAOA,EAAE,QAAQ,QAC1DA,EAAE,eAAA,GACFV,EAAK,GAAG,MAGAU,EAAE,WAAWA,EAAE,YAAYA,EAAE,QAAQ,OAC7CA,EAAE,eAAA,GACFV,EAAK,IAAI,KAGF,CAAC9B,KAAgBwC,EAAE,QAAQ,eAClCA,EAAE,eAAA,GACFrB,EAASvB,IAAc,CAAC,KAGjB,CAACI,KAAgBwC,EAAE,QAAQ,iBAClCA,EAAE,eAAA,GACFrB,EAASvB,IAAc,CAAC;AAAA,IAE5B;AAEA,oBAAS,iBAAiB,WAAW2C,CAAa,GAC3C,MAAM;AACX,eAAS,oBAAoB,WAAWA,CAAa;AAAA,IACvD;AAAA,EACF,GAAG,CAACzF,GAAe8C,GAAauB,GAAUnB,GAAc8B,CAAI,CAAC;AAG7D,QAAMe,KAAmBnH,EAAY,YAAY;;AAC/C,QAAI,SAAO,WAAa;AAExB,UAAK,SAAS;AAQZ,QAAI,SAAS,mBACX,MAAM,SAAS,eAAA,GACfqD,EAAgB,EAAK;AAAA;AATvB,YAAI;AACF,kBAAM+D,KAAAC,IAAAtD,GAAU,YAAV,gBAAAsD,EAAmB,sBAAnB,gBAAAD,EAAA,KAAAC,KACNhE,EAAgB,EAAI;AAAA,QACtB,SAAS8B,GAAK;AACZ,kBAAQ,MAAM,0CAA0CA,CAAG;AAAA,QAC7D;AAAA,EAOJ,GAAG,CAAA,CAAE;AAGL,EAAAzB,EAAU,MAAM;AACd,QAAI,OAAO,WAAa,IAAa;AAErC,UAAM4D,IAAyB,MAAM;AACnC,MAAAjE,EAAgB,CAAC,CAAC,SAAS,iBAAiB;AAAA,IAC9C;AAEA,oBAAS,iBAAiB,oBAAoBiE,CAAsB,GAC7D,MAAM;AACX,eAAS,oBAAoB,oBAAoBA,CAAsB;AAAA,IACzE;AAAA,EACF,GAAG,CAAA,CAAE;AAGL,QAAMC,KAAyBvH;AAAA,IAC7B,CAAC4F,MAAuB;AACtB,MAAAH,EAASG,CAAU,GACnBrC,GAAgB,EAAK;AAAA,IACvB;AAAA,IACA,CAACkC,CAAQ;AAAA,EAAA,GAIL+B,KAAgB,MACfzG,KAGH0G,gBAAAA,EAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,8DAA8DjG,MAAoB,EAAE;AAAA,MAE/F,UAAA;AAAA,QAAAiG,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAU,2BAEZ,UAAA;AAAA,UAAAzG,KACC0G,gBAAAA,EAAAA;AAAAA,YAACjD;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAMhB,GAAoB,CAACD,CAAgB;AAAA,cACpD,OAAOA,IAAmB,UAAU;AAAA,cAEpC,gCAACmE,IAAA,CAAA,CAAc;AAAA,YAAA;AAAA,UAAA;AAAA,UAKnBD,gBAAAA,EAAAA;AAAAA,YAACjD;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAM2B,EAAK,IAAI;AAAA,cACxB,UAAUjC,KAAStD;AAAA,cAEnB,gCAAC+G,IAAA,CAAA,CAAY;AAAA,YAAA;AAAA,UAAA;AAAA,UAEfH,gBAAAA,EAAAA,KAAC,QAAA,EAAK,WAAU,oCACb,UAAA;AAAA,YAAA,KAAK,MAAMtD,IAAQ,GAAG;AAAA,YAAE;AAAA,UAAA,GAC3B;AAAA,UACAuD,gBAAAA,EAAAA;AAAAA,YAACjD;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAM2B,EAAK,GAAG;AAAA,cACvB,UAAUjC,KAASrD;AAAA,cAEnB,gCAAC+G,IAAA,CAAA,CAAW;AAAA,YAAA;AAAA,UAAA;AAAA,UAIb5G,MACCyG,gBAAAA,EAAAA,IAACjD,GAAA,EAAO,SAAQ,WAAU,MAAK,QAAO,SAAS8B,IAC7C,UAAAmB,gBAAAA,EAAAA,IAACI,IAAA,CAAA,CAAa,EAAA,CAChB;AAAA,UAID5G,MACCwG,gBAAAA,EAAAA;AAAAA,YAACjD;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAMlB,GAAgB,CAACD,CAAY;AAAA,cAC5C,OAAOA,IAAe,SAAS;AAAA,cAE9B,UAAAA,IAAeoE,gBAAAA,MAACK,IAAA,CAAA,CAAe,0BAAMC,IAAA,CAAA,CAAa;AAAA,YAAA;AAAA,UAAA;AAAA,UAKtD7G,MACCuG,gBAAAA,EAAAA,IAACjD,GAAA,EAAO,SAAQ,WAAU,MAAK,QAAO,SAAS0C,IAC5C,eAAeO,gBAAAA,EAAAA,IAACO,IAAA,CAAA,CAAc,IAAKP,gBAAAA,MAACQ,MAAc,EAAA,CACrD;AAAA,QAAA,GAEJ;AAAA,QAEAT,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,UAAA,CAACnD,KACAoD,gBAAAA,EAAAA;AAAAA,YAACjD;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAMgB,EAASvB,IAAc,CAAC;AAAA,cACvC,UAAUA,KAAe;AAAA,cAEzB,gCAACiE,IAAA,CAAA,CAAgB;AAAA,YAAA;AAAA,UAAA;AAAA,UAIrBT,gBAAAA,EAAAA;AAAAA,YAAChD;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,KAAK;AAAA,cACL,KAAKxB;AAAA,cACL,OAAOgB;AAAA,cACP,UAAU,CAAC,MAAMuB,EAAS,SAAS,EAAE,OAAO,KAAK,KAAK,CAAC;AAAA,cACvD,UAAUnB;AAAA,cACV,UAAUA;AAAA,cACV,OAAOA,IAAe,mBAAmB;AAAA,cACzC,WAAU;AAAA,YAAA;AAAA,UAAA;AAAA,UAEZmD,gBAAAA,EAAAA,KAAC,QAAA,EAAK,WAAU,iCAAgC,UAAA;AAAA,YAAA;AAAA,YAAGvE;AAAA,UAAA,GAAW;AAAA,UAE7D,CAACoB,KACAoD,gBAAAA,EAAAA;AAAAA,YAACjD;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAMgB,EAASvB,IAAc,CAAC;AAAA,cACvC,UAAUhB,IAAa,KAAKgB,KAAehB;AAAA,cAE3C,gCAACkF,IAAA,CAAA,CAAiB;AAAA,YAAA;AAAA,UAAA;AAAA,QACpB,EAAA,CAEJ;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,IAtGqB,MA4GrBC,IAAgB,MACpBX,gBAAAA,EAAAA,IAAC,OAAA,EAAI,WAAU,2CACb,UAAAA,gBAAAA,EAAAA,IAAC,KAAA,EAAE,WAAU,yBAAyB,UAAAvF,GAAA,CAAY,GACpD,GAIImG,IAAc,MAClBZ,gBAAAA,EAAAA,IAAC,OAAA,EAAI,WAAU,2FACb,UAAAD,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,IAAAC,gBAAAA,EAAAA,IAAC,KAAA,EAAE,WAAU,4BAA2B,UAAA,UAAM;AAAA,IAC9CA,gBAAAA,EAAAA,IAAC,KAAA,EAAE,WAAU,sBAAsB,iCAAO,QAAA,CAAQ;AAAA,EAAA,EAAA,CACpD,EAAA,CACF,GAIIa,KAAoB,MAAM;AAC9B,QAAI,CAAC1E,GAAU,QAAOwE,EAAA;AAEtB,UAAM,EAAE,UAAAG,GAAU,MAAAC,EAAA,IAAS5E;AAE3B,WACE6D,gBAAAA,EAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAK1D;AAAA,QACL,UAAUM,IAAewB,KAA4B;AAAA,QACrD,WAAW,wCAAwCrE,MAAoB,EAAE;AAAA,QAEzE,UAAAiG,gBAAAA,EAAAA,IAAC,OAAA,EAAI,WAAU,uCACb,UAAAA,gBAAAA,EAAAA;AAAAA,UAACc;AAAA,UAAA;AAAA,YAEC,MAAMrI;AAAA,YACN,aAAakF;AAAA,YACb,SAAST;AAAA,YACT,SAASyD,EAAA;AAAA,YACT,OAAOC,EAAA;AAAA,YACP,eAAehD;AAAA,YAEd,UAAAtC,IACCsF,MACEhF;AAAA;AAAA,cAEF,MAAM,KAAK,IAAI,MAAMJ,CAAU,GAAG,CAACwF,GAAKC,MACtCjB,gBAAAA,EAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,KAAK,CAAC7B,MAAYF,GAAWgD,IAAQ,GAAG9C,CAAO;AAAA,kBAC/C,oBAAkB8C,IAAQ;AAAA,kBAC1B,WAAW,QAAQhH,MAAiB,EAAE;AAAA,kBAEtC,UAAA+F,gBAAAA,EAAAA;AAAAA,oBAACe;AAAA,oBAAA;AAAA,sBACC,YAAYE,IAAQ;AAAA,sBACpB,iBAAiB;AAAA,sBACjB,uBAAuB;AAAA,sBACvB,OAAOhF;AAAA,sBACP,OAAAQ;AAAA,sBACA,QAAQC;AAAA,sBACR,iBAAiB,MAAMlC,KAAA,gBAAAA,EAAeyG,IAAQ;AAAA,oBAAC;AAAA,kBAAA;AAAA,gBACjD;AAAA,gBAbK,QAAQA,IAAQ,CAAC;AAAA,cAAA,CAezB;AAAA;AAAA;AAAA,cAGDjB,gBAAAA,EAAAA,IAAC,OAAA,EAAI,WAAW/F,MAAiB,IAC/B,UAAA+F,gBAAAA,EAAAA;AAAAA,gBAACe;AAAA,gBAAA;AAAA,kBACC,YAAYvE;AAAA,kBACZ,iBAAiB;AAAA,kBACjB,uBAAuB;AAAA,kBACvB,OAAOP;AAAA,kBACP,OAAAQ;AAAA,kBACA,QAAQC;AAAA,kBACR,iBAAiB,MAAMlC,KAAA,gBAAAA,EAAegC;AAAA,gBAAW;AAAA,cAAA,EACnD,CACF;AAAA;AAAA,UAAA;AAAA,UA1CG/D;AAAA,QAAA,EA4CP,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN,GAGMyI,KAAgB,MAAM;AAC1B,QAAI,CAAC5H,KAAe,CAACwC,KAAoB,CAACnB,GAAa,QAAO;AAG9D,UAAMwG,IAAsBC;AAE5B,WACEpB,gBAAAA,EAAAA;AAAAA,MAACmB;AAAA,MAAA;AAAA,QACC,aAAAxG;AAAA,QACA,aAAA6B;AAAA,QACA,aAAaqD;AAAA,QACb,YAAY;AAAA,UACV,MAAMxF,EAAW;AAAA,UACjB,UAAUA,EAAW;AAAA,UACrB,aAAaA,EAAW;AAAA,UACxB,aAAaA,EAAW;AAAA,UACxB,YAAYA,EAAW;AAAA,UACvB,UAAA4C;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAGN,GAGMoE,KAAkB,MAClB,CAAC1H,MAAmBiD,IAAqB,OAG3CmD,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAU,sEACb,UAAA;AAAA,IAAAA,gBAAAA,EAAAA;AAAAA,MAAChD;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,SAAS,MAAMgB,EAASvB,IAAc,CAAC;AAAA,QACvC,UAAUI,KAAgBJ,KAAe;AAAA,QACzC,OAAOI,IAAe,kBAAkB;AAAA,QAExC,UAAA;AAAA,UAAAoD,gBAAAA,EAAAA,IAACS,IAAA,EAAgB;AAAA,UACjBT,gBAAAA,EAAAA,IAAC,QAAA,EAAK,WAAU,QAAO,UAAA,MAAA,CAAG;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAE5BD,gBAAAA,EAAAA;AAAAA,MAAChD;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,SAAS,MAAMgB,EAASvB,IAAc,CAAC;AAAA,QACvC,UAAUI,KAAgBJ,KAAehB;AAAA,QACzC,OAAOoB,IAAe,kBAAkB;AAAA,QAExC,UAAA;AAAA,UAAAoD,gBAAAA,EAAAA,IAAC,QAAA,EAAK,WAAU,QAAO,UAAA,OAAG;AAAA,gCACzBU,IAAA,CAAA,CAAiB;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EACpB,GACF;AAKJ,MAAI,CAACrG;AACH,WACE2F,gBAAAA,EAAAA,IAAC,OAAA,EAAI,WAAU,oCAAmC,UAAA,mCAElD;AAKJ,MAAI1G,GAAa;AACf,UAAMgI,IAA8B,CAAA;AAOpC,QANKjH,EAAW,QAAMiH,EAAkB,KAAK,MAAM,GAC9CjH,EAAW,YAAUiH,EAAkB,KAAK,UAAU,GACtDjH,EAAW,eAAaiH,EAAkB,KAAK,aAAa,GAC5DjH,EAAW,eAAaiH,EAAkB,KAAK,aAAa,GAC5DjH,EAAW,cAAYiH,EAAkB,KAAK,YAAY,GAE3DA,EAAkB,SAAS,GAAG;AAChC,YAAMC,IACJD,EAAkB,WAAW,IACzBA,EAAkB,CAAC,IACnB,GAAGA,EAAkB,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG,CAAC,MAAMA,EAAkBA,EAAkB,SAAS,CAAC,CAAC;AACtG,aACEvB,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAU,oCAAmC,UAAA;AAAA,QAAA;AAAA,QAClCwB;AAAA,QAAsB;AAAA,MAAA,GACtC;AAAA,IAEJ;AAAA,EACF;AAEA,SACExB,gBAAAA,EAAAA,KAAC,OAAA,EAAI,KAAK1D,IACR,UAAA;AAAA,IAAA0D,gBAAAA,EAAAA,KAAClD,MAAK,WAAAhD,IACH,UAAA;AAAA,MAAAiG,GAAA;AAAA,MACDE,gBAAAA,EAAAA;AAAAA,QAAClD;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,EAAE,QAAQpB,KAAe,UAAU1B,GAAA;AAAA,UAE1C,gCAAC,OAAA,EAAI,WAAU,wBAEb,UAAA+F,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAU,+BACZ,UAAA;AAAA,YAAAmB,GAAA;AAAA,YACA9F,KACGuF,EAAA,IACArF,IACEsF,EAAA,IACAC,GAAA;AAAA,UAAkB,EAAA,CAC1B,EAAA,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,IACF,GACF;AAAA,IACCQ,GAAA;AAAA,EAAgB,GACnB;AAEJ;"}
|
|
1
|
+
{"version":3,"file":"pdf-reader.js","sources":["../src/components/PDFReader.tsx"],"sourcesContent":["import {\n ChevronLeft as ChevronLeftIcon,\n ChevronRight as ChevronRightIcon,\n FileText as FileTextIcon,\n Maximize2 as Maximize2Icon,\n Minimize2 as Minimize2Icon,\n PanelLeft as PanelLeftIcon,\n RotateCw as RotateCwIcon,\n ScrollText as ScrollTextIcon,\n ZoomIn as ZoomInIcon,\n ZoomOut as ZoomOutIcon,\n} from 'lucide-react';\nimport { useState, useCallback, useEffect, useMemo, useRef } from 'react';\nimport type { HTMLAttributes } from 'react';\n\nimport type {\n CardComponent,\n ButtonComponent,\n InputComponent,\n SkeletonComponent,\n} from '../types/component-types';\n\nimport type { PDFDocumentProxy } from './PDFSidebar';\nimport { PDFSidebar } from './PDFSidebar';\n\n/**\n * PDFReader UI 组件接口\n */\nexport interface PDFReaderUIComponents {\n /** Card 组件 (必需) */\n Card: CardComponent;\n /** CardContent 组件 (必需) */\n CardContent: React.ComponentType<HTMLAttributes<HTMLDivElement>>;\n /** Button 组件 (必需) */\n Button: ButtonComponent;\n /** Input 组件 (必需) */\n Input: InputComponent;\n /** Skeleton 组件 (必需) */\n Skeleton: SkeletonComponent;\n /** Tabs 组件 (showSidebar=true 时必需) */\n Tabs?: React.ComponentType<{\n value?: string;\n onValueChange?: (value: string) => void;\n children?: React.ReactNode;\n defaultValue?: string;\n }>;\n /** TabsList 组件 (showSidebar=true 时必需) */\n TabsList?: React.ComponentType<HTMLAttributes<HTMLDivElement>>;\n /** TabsTrigger 组件 (showSidebar=true 时必需) */\n TabsTrigger?: React.ComponentType<{\n value: string;\n children?: React.ReactNode;\n }>;\n /** TabsContent 组件 (showSidebar=true 时必需) */\n TabsContent?: React.ComponentType<{\n value: string;\n children?: React.ReactNode;\n }>;\n /** ScrollArea 组件 (showSidebar=true 时必需) */\n ScrollArea?: React.ComponentType<HTMLAttributes<HTMLDivElement>>;\n}\n\n/**\n * PDFReader 组件 Props\n */\nexport interface PDFReaderProps {\n // ==================== 基础配置 ====================\n /** PDF 文件 URL (必需) */\n url: string;\n\n // ==================== 初始状态 ====================\n /** 初始页码 (默认 1) */\n initialPage?: number;\n /** 初始缩放比例 (默认 1.0) */\n initialScale?: number;\n /** 初始旋转角度 (默认 0) */\n initialRotation?: number;\n\n // ==================== 受控模式 ====================\n /** 当前页码 (受控) */\n currentPage?: number;\n /** 页码变化回调 */\n onPageChange?: (page: number) => void;\n /** 缩放比例 (受控) */\n scale?: number;\n /** 缩放变化回调 */\n onScaleChange?: (scale: number) => void;\n /** 旋转角度 (受控) */\n rotation?: number;\n /** 旋转变化回调 */\n onRotationChange?: (rotation: number) => void;\n\n // ==================== 缩放限制 ====================\n /** 最小缩放比例 (默认 0.5) */\n minScale?: number;\n /** 最大缩放比例 (默认 2.5) */\n maxScale?: number;\n\n // ==================== 功能开关 ====================\n /** 显示工具栏 (默认 true) */\n showToolbar?: boolean;\n /** 显示侧边栏 (默认 true) */\n showSidebar?: boolean;\n /** 显示旋转按钮 (默认 true) */\n showRotation?: boolean;\n /** 显示模式切换按钮 (默认 true) */\n showModeToggle?: boolean;\n /** 显示全屏按钮 (默认 true) */\n showFullscreen?: boolean;\n /** 启用键盘快捷键 (默认 true) */\n enableHotkeys?: boolean;\n /** 启用移动端导航 (默认 true) */\n enableMobileNav?: boolean;\n\n // ==================== 显示模式 ====================\n /** 显示模式: 'scroll' 显示所有页面, 'single' 单页模式 (默认 'single') */\n displayMode?: 'scroll' | 'single';\n\n // ==================== 样式定制 ====================\n /** 容器类名 */\n className?: string;\n /** 工具栏类名 */\n toolbarClassName?: string;\n /** 内容区域类名 */\n contentClassName?: string;\n /** 阅读区域高度限制 (默认 '80vh') */\n contentHeight?: string | number;\n /** 页面类名 */\n pageClassName?: string;\n\n // ==================== Worker 配置 ====================\n /** Worker 文件 URL (可选,默认使用 CDN) */\n workerUrl?: string;\n /** CMap 文件 URL (可选,默认使用 CDN) */\n cMapUrl?: string;\n /** 标准字体数据 URL (可选,默认使用 CDN) */\n standardFontDataUrl?: string;\n\n // ==================== UI 组件注入 ====================\n /** UI 组件 */\n components: PDFReaderUIComponents;\n\n // ==================== 回调函数 ====================\n /** 加载成功回调 */\n onLoadSuccess?: (pdf: PDFDocumentProxy) => void;\n /** 加载错误回调 */\n onLoadError?: (error: Error) => void;\n /** 页面渲染回调 */\n onPageRender?: (pageIndex: number) => void;\n\n // ==================== 文本配置 ====================\n /** 加载文本 (默认 '正在加载PDF文档...') */\n loadingText?: string;\n /** 错误文本 (默认 'PDF加载失败') */\n errorText?: string;\n}\n\n/**\n * debounce hook (替代 lodash.debounce)\n */\nfunction useDebounce<T extends (...args: any[]) => any>(\n callback: T,\n delay: number\n): T {\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined\n );\n return useCallback(\n (...args: Parameters<T>) => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n timeoutRef.current = setTimeout(() => callback(...args), delay);\n },\n [callback, delay]\n ) as T;\n}\n\n/**\n * PDFReader 组件\n *\n * 功能完整的 PDF 阅读器组件,支持侧边栏导航、页面旋转、显示模式切换等高级特性。\n *\n * @example\n * ```tsx\n * import { PDFReader } from '@turinhub/atomix-common-ui/pdf-reader';\n * import { Card, Button, Input, Label, Skeleton } from '@/components/ui';\n * import { Tabs, ScrollArea } from '@/components/ui';\n *\n * <PDFReader\n * url=\"/documents/sample.pdf\"\n * components={{\n * Card,\n * CardContent: Card.Content,\n * Button,\n * Input,\n * Label,\n * Skeleton,\n * Tabs,\n * TabsList: Tabs.List,\n * TabsTrigger: Tabs.Trigger,\n * TabsContent: Tabs.Content,\n * ScrollArea,\n * }}\n * initialPage={1}\n * initialScale={1.0}\n * showSidebar={true}\n * showRotation={true}\n * showModeToggle={true}\n * enableHotkeys={true}\n * />\n * ```\n */\nexport function PDFReader({\n url,\n initialPage = 1,\n initialScale = 1.0,\n initialRotation = 0,\n currentPage: controlledPage,\n onPageChange,\n scale: controlledScale,\n onScaleChange,\n rotation: controlledRotation,\n onRotationChange,\n minScale = 0.5,\n maxScale = 2.5,\n showToolbar = true,\n showSidebar = true,\n showRotation = true,\n showModeToggle = true,\n showFullscreen = true,\n enableHotkeys = true,\n enableMobileNav = true,\n displayMode: initialDisplayMode = 'single',\n className,\n toolbarClassName,\n contentClassName,\n contentHeight = '80vh',\n pageClassName,\n workerUrl,\n cMapUrl,\n standardFontDataUrl,\n components,\n onLoadSuccess,\n onLoadError,\n onPageRender,\n loadingText = '正在加载PDF文档...',\n errorText = 'PDF加载失败',\n}: PDFReaderProps) {\n // ==================== 状态管理 ====================\n const [pdfDocument, setPdfDocument] = useState<PDFDocumentProxy | null>(null);\n const [internalPage, setInternalPage] = useState(initialPage);\n const [internalScale, setInternalScale] = useState(initialScale);\n const [internalRotation, setInternalRotation] = useState(initialRotation);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [totalPages, setTotalPages] = useState(0);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const [showAllPages, setShowAllPages] = useState(\n initialDisplayMode === 'scroll'\n );\n const [showSidebarState, setShowSidebarState] = useState(showSidebar);\n\n // Sync showSidebarState with prop changes\n useEffect(() => {\n setShowSidebarState(showSidebar);\n }, [showSidebar]);\n\n const [pageWidth, setPageWidth] = useState<number | undefined>(undefined);\n\n // 动态导入 react-pdf\n const [ReactPDF, setReactPDF] = useState<any>(null);\n\n const readerRef = useRef<HTMLDivElement>(null);\n const pdfContainerRef = useRef<HTMLDivElement>(null);\n const pageRefs = useRef<Map<number, HTMLDivElement>>(new Map());\n\n // 使用受控或非受控模式\n const currentPage = controlledPage ?? internalPage;\n const scale = controlledScale ?? internalScale;\n const rotation = controlledRotation ?? internalRotation;\n const isPageControlled = controlledPage !== undefined;\n const isScrollMode = showAllPages;\n\n // ==================== 组件解构 ====================\n const { Card, CardContent, Button, Input, Skeleton } = components || {};\n\n useEffect(() => {\n setPdfDocument(null);\n setTotalPages(0);\n setError(null);\n setIsLoading(false);\n if (!isPageControlled) {\n setInternalPage(Math.max(1, initialPage));\n }\n }, [url, initialPage, isPageControlled]);\n\n // ==================== PDF 选项 ====================\n const pdfOptions = useMemo(() => {\n const options: Record<string, unknown> = {\n withCredentials: false,\n };\n\n if (cMapUrl) {\n options.cMapUrl = cMapUrl;\n options.cMapPacked = true;\n }\n\n if (standardFontDataUrl) {\n options.standardFontDataUrl = standardFontDataUrl;\n }\n\n return options;\n }, [cMapUrl, standardFontDataUrl]);\n\n // ==================== 动态导入 react-pdf ====================\n useEffect(() => {\n let isMounted = true;\n\n const loadReactPDF = async () => {\n try {\n // 动态导入 react-pdf\n const pdfModule = await import('react-pdf');\n\n // 设置 worker\n if (typeof window !== 'undefined') {\n const pdfjs = (pdfModule as any).pdfjs;\n const workerVersion = pdfjs?.version;\n\n if (pdfjs?.GlobalWorkerOptions && workerVersion) {\n if (workerUrl) {\n pdfjs.GlobalWorkerOptions.workerSrc = workerUrl;\n } else {\n // 使用 CDN\n pdfjs.GlobalWorkerOptions.workerSrc = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${workerVersion}/build/pdf.worker.min.mjs`;\n }\n\n // 如果没有提供自定义 URL,使用 CDN 默认值\n if (!cMapUrl && pdfjs.GlobalWorkerOptions) {\n (pdfjs.GlobalWorkerOptions as any).cMapUrl =\n `https://unpkg.com/pdfjs-dist@${workerVersion}/cmaps/`;\n }\n if (!standardFontDataUrl && pdfjs.GlobalWorkerOptions) {\n (pdfjs.GlobalWorkerOptions as any).standardFontDataUrl =\n `https://unpkg.com/pdfjs-dist@${workerVersion}/standard_fonts/`;\n }\n }\n }\n\n if (isMounted) {\n setReactPDF(pdfModule);\n }\n } catch (err) {\n if (isMounted) {\n const loadError =\n err instanceof Error ? err : new Error('无法加载 react-pdf 库');\n setError(loadError);\n setIsLoading(false);\n onLoadError?.(loadError);\n }\n }\n };\n\n loadReactPDF();\n\n return () => {\n isMounted = false;\n };\n }, [workerUrl, cMapUrl, standardFontDataUrl, onLoadError]);\n\n // ==================== 处理加载错误 ====================\n const onDocumentLoadError = useCallback(\n (err: Error) => {\n console.error('PDF加载失败:', err);\n console.error('PDF URL:', url);\n setPdfDocument(null);\n setTotalPages(0);\n setError(\n new Error(`${errorText}: ${err.message || '请检查文件路径或网络连接'}`)\n );\n setIsLoading(false);\n onLoadError?.(err);\n },\n [url, errorText, onLoadError]\n );\n\n const onDocumentLoadSuccess = useCallback(\n (pdf: PDFDocumentProxy) => {\n setPdfDocument(pdf);\n setTotalPages(pdf.numPages);\n setError(null);\n setIsLoading(false);\n\n if (!isPageControlled) {\n setInternalPage((page) =>\n Math.max(1, Math.min(page, Math.max(pdf.numPages, 1)))\n );\n }\n\n onLoadSuccess?.(pdf);\n },\n [isPageControlled, onLoadSuccess]\n );\n\n // ==================== 页面导航 ====================\n const goToPage = useCallback(\n (page: number) => {\n if (!Number.isFinite(page)) return;\n const newPage =\n totalPages > 0\n ? Math.max(1, Math.min(Math.trunc(page), totalPages))\n : Math.max(1, Math.trunc(page));\n if (!isPageControlled) {\n setInternalPage(newPage);\n }\n if (newPage !== currentPage) {\n onPageChange?.(newPage);\n }\n },\n [totalPages, isPageControlled, currentPage, onPageChange]\n );\n\n const setPageRef = useCallback(\n (pageNumber: number, element: HTMLDivElement | null) => {\n if (element) {\n pageRefs.current.set(pageNumber, element);\n } else {\n pageRefs.current.delete(pageNumber);\n }\n },\n []\n );\n\n const syncScrollModeCurrentPage = useCallback(() => {\n const container = pdfContainerRef.current;\n if (!container || !isScrollMode || totalPages <= 0) return;\n\n const containerTop = container.getBoundingClientRect().top;\n let closestPage = currentPage;\n let closestDistance = Number.POSITIVE_INFINITY;\n\n pageRefs.current.forEach((element, pageNumber) => {\n const distance = Math.abs(\n element.getBoundingClientRect().top - containerTop\n );\n if (distance < closestDistance) {\n closestDistance = distance;\n closestPage = pageNumber;\n }\n });\n\n if (closestPage !== currentPage) {\n goToPage(closestPage);\n }\n }, [currentPage, goToPage, isScrollMode, totalPages]);\n\n // ==================== 缩放控制 ====================\n const zoom = useCallback(\n (delta: number) => {\n const newScale = Math.max(minScale, Math.min(maxScale, scale + delta));\n if (controlledScale === undefined) {\n setInternalScale(newScale);\n }\n onScaleChange?.(newScale);\n },\n [scale, minScale, maxScale, controlledScale, onScaleChange]\n );\n\n // ==================== 旋转控制 ====================\n const rotate = useCallback(() => {\n const newRotation = (rotation + 90) % 360;\n if (controlledRotation === undefined) {\n setInternalRotation(newRotation);\n }\n onRotationChange?.(newRotation);\n }, [rotation, controlledRotation, onRotationChange]);\n\n // ==================== 处理窗口大小变化 ====================\n const debouncedUpdatePageWidth = useDebounce((width: number) => {\n setPageWidth(width);\n }, 100);\n\n // Use ResizeObserver to track container size changes\n useEffect(() => {\n if (!pdfContainerRef.current) return;\n\n const container = pdfContainerRef.current;\n const updateWidth = () => {\n debouncedUpdatePageWidth(container.clientWidth);\n };\n\n // Initial measurement\n updateWidth();\n\n // Set up ResizeObserver\n const resizeObserver = new ResizeObserver(() => {\n updateWidth();\n });\n\n resizeObserver.observe(container);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [debouncedUpdatePageWidth]);\n\n // ==================== 键盘快捷键 ====================\n useEffect(() => {\n if (!enableHotkeys) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement | null;\n const activeElement =\n typeof document !== 'undefined'\n ? (document.activeElement as HTMLElement | null)\n : null;\n const focusedElement = target || activeElement;\n const role = focusedElement?.getAttribute('role');\n\n if (\n focusedElement &&\n (focusedElement.tagName === 'INPUT' ||\n focusedElement.tagName === 'TEXTAREA' ||\n focusedElement.tagName === 'SELECT' ||\n focusedElement.isContentEditable ||\n role === 'textbox' ||\n role === 'spinbutton')\n ) {\n return;\n }\n\n // Ctrl/Cmd + 加号: 放大\n if ((e.ctrlKey || e.metaKey) && (e.key === '=' || e.key === '+')) {\n e.preventDefault();\n zoom(0.1);\n }\n // Ctrl/Cmd + 减号: 缩小\n else if ((e.ctrlKey || e.metaKey) && e.key === '-') {\n e.preventDefault();\n zoom(-0.1);\n }\n // 左箭头: 上一页\n else if (!isScrollMode && e.key === 'ArrowLeft') {\n e.preventDefault();\n goToPage(currentPage - 1);\n }\n // 右箭头: 下一页\n else if (!isScrollMode && e.key === 'ArrowRight') {\n e.preventDefault();\n goToPage(currentPage + 1);\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [enableHotkeys, currentPage, goToPage, isScrollMode, zoom]);\n\n // ==================== 全屏切换 ====================\n const toggleFullscreen = useCallback(async () => {\n if (typeof document === 'undefined') return;\n\n if (!document.fullscreenElement) {\n try {\n await readerRef.current?.requestFullscreen?.();\n setIsFullscreen(true);\n } catch (err) {\n console.error('Error attempting to enable fullscreen:', err);\n }\n } else {\n if (document.exitFullscreen) {\n await document.exitFullscreen();\n setIsFullscreen(false);\n }\n }\n }, []);\n\n // ==================== 监听全屏状态变化 ====================\n useEffect(() => {\n if (typeof document === 'undefined') return;\n\n const handleFullscreenChange = () => {\n setIsFullscreen(!!document.fullscreenElement);\n };\n\n document.addEventListener('fullscreenchange', handleFullscreenChange);\n return () => {\n document.removeEventListener('fullscreenchange', handleFullscreenChange);\n };\n }, []);\n\n // ==================== 处理侧边栏页面点击 ====================\n const handleSidebarPageClick = useCallback(\n (pageNumber: number) => {\n goToPage(pageNumber);\n setShowAllPages(false);\n },\n [goToPage]\n );\n\n // ==================== 渲染工具栏 ====================\n const renderToolbar = () => {\n if (!showToolbar) return null;\n\n return (\n <div\n className={`flex items-center justify-between gap-4 border-b px-4 py-2 ${toolbarClassName || ''}`}\n >\n <div className=\"flex items-center gap-2\">\n {/* 侧边栏切换 */}\n {showSidebar && (\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setShowSidebarState(!showSidebarState)}\n title={showSidebarState ? '隐藏侧边栏' : '显示侧边栏'}\n >\n <PanelLeftIcon />\n </Button>\n )}\n\n {/* 缩放控制 */}\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => zoom(-0.1)}\n disabled={scale <= minScale}\n >\n <ZoomOutIcon />\n </Button>\n <span className=\"min-w-[3rem] text-center text-sm\">\n {Math.round(scale * 100)}%\n </span>\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => zoom(0.1)}\n disabled={scale >= maxScale}\n >\n <ZoomInIcon />\n </Button>\n\n {/* 旋转控制 */}\n {showRotation && (\n <Button variant=\"outline\" size=\"icon\" onClick={rotate}>\n <RotateCwIcon />\n </Button>\n )}\n\n {/* 显示模式切换 */}\n {showModeToggle && (\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setShowAllPages(!showAllPages)}\n title={showAllPages ? '单页模式' : '滚动模式'}\n >\n {showAllPages ? <ScrollTextIcon /> : <FileTextIcon />}\n </Button>\n )}\n\n {/* 全屏切换 */}\n {showFullscreen && (\n <Button variant=\"outline\" size=\"icon\" onClick={toggleFullscreen}>\n {isFullscreen ? <Minimize2Icon /> : <Maximize2Icon />}\n </Button>\n )}\n </div>\n\n <div className=\"flex items-center gap-2\">\n {!isScrollMode && (\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => goToPage(currentPage - 1)}\n disabled={currentPage <= 1}\n >\n <ChevronLeftIcon />\n </Button>\n )}\n\n <Input\n type=\"number\"\n min={1}\n max={totalPages}\n value={currentPage}\n onChange={(e) => goToPage(parseInt(e.target.value) || 1)}\n disabled={isScrollMode}\n readOnly={isScrollMode}\n title={isScrollMode ? '滚动模式下页码仅显示当前位置' : undefined}\n className=\"w-16 text-center\"\n />\n <span className=\"text-sm text-muted-foreground\">/ {totalPages}</span>\n\n {!isScrollMode && (\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => goToPage(currentPage + 1)}\n disabled={totalPages > 0 && currentPage >= totalPages}\n >\n <ChevronRightIcon />\n </Button>\n )}\n </div>\n </div>\n );\n };\n\n // ==================== 渲染加载状态 ====================\n const renderLoading = () => (\n <div className=\"flex h-full items-center justify-center\">\n <p className=\"text-muted-foreground\">{loadingText}</p>\n </div>\n );\n\n // ==================== 渲染错误状态 ====================\n const renderError = () => (\n <div className=\"flex h-full min-h-[400px] items-center justify-center px-4 text-center text-destructive\">\n <div className=\"max-w-md\">\n <p className=\"mb-2 text-lg font-medium\">文件加载失败</p>\n <p className=\"text-sm opacity-80\">{error?.message}</p>\n </div>\n </div>\n );\n\n // ==================== 渲染 PDF 文档 ====================\n const renderPDFDocument = () => {\n if (!ReactPDF) return renderLoading();\n\n const { Document, Page } = ReactPDF;\n\n return (\n <div\n ref={pdfContainerRef}\n onScroll={isScrollMode ? syncScrollModeCurrentPage : undefined}\n className={`pdf-container flex-1 overflow-y-auto ${contentClassName || ''}`}\n >\n <div className=\"flex min-h-full justify-center px-4\">\n <Document\n key={url}\n file={url}\n onLoadError={onDocumentLoadError}\n options={pdfOptions}\n loading={renderLoading()}\n error={renderError()}\n onLoadSuccess={onDocumentLoadSuccess}\n >\n {error ? (\n renderError()\n ) : showAllPages ? (\n // 显示所有页面模式\n Array.from(new Array(totalPages), (_el, index) => (\n <div\n key={`page_${index + 1}`}\n ref={(element) => setPageRef(index + 1, element)}\n data-page-number={index + 1}\n className={`mb-4 ${pageClassName || ''}`}\n >\n <Page\n pageNumber={index + 1}\n renderTextLayer={false}\n renderAnnotationLayer={false}\n width={pageWidth}\n scale={scale}\n rotate={rotation}\n onRenderSuccess={() => onPageRender?.(index + 1)}\n />\n </div>\n ))\n ) : (\n // 单页模式\n <div className={pageClassName || ''}>\n <Page\n pageNumber={currentPage}\n renderTextLayer={false}\n renderAnnotationLayer={false}\n width={pageWidth}\n scale={scale}\n rotate={rotation}\n onRenderSuccess={() => onPageRender?.(currentPage)}\n />\n </div>\n )}\n </Document>\n </div>\n </div>\n );\n };\n\n // ==================== 渲染侧边栏 ====================\n const renderSidebar = () => {\n if (!showSidebar || !showSidebarState || !pdfDocument) return null;\n\n // 使用导入的 PDFSidebar 组件\n const PDFSidebarComponent = PDFSidebar;\n\n return (\n <PDFSidebarComponent\n pdfDocument={pdfDocument}\n currentPage={currentPage}\n onPageClick={handleSidebarPageClick}\n components={{\n Tabs: components.Tabs!,\n TabsList: components.TabsList!,\n TabsTrigger: components.TabsTrigger!,\n TabsContent: components.TabsContent!,\n ScrollArea: components.ScrollArea!,\n Skeleton,\n }}\n />\n );\n };\n\n // ==================== 渲染移动端导航 ====================\n const renderMobileNav = () => {\n if (!enableMobileNav || isScrollMode) return null;\n\n return (\n <div className=\"fixed bottom-4 left-1/2 z-50 flex -translate-x-1/2 gap-2 md:hidden\">\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => goToPage(currentPage - 1)}\n disabled={isScrollMode || currentPage <= 1}\n title={isScrollMode ? '滚动模式下通过滚动定位页面' : undefined}\n >\n <ChevronLeftIcon />\n <span className=\"ml-1\">上一页</span>\n </Button>\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => goToPage(currentPage + 1)}\n disabled={isScrollMode || currentPage >= totalPages}\n title={isScrollMode ? '滚动模式下通过滚动定位页面' : undefined}\n >\n <span className=\"mr-1\">下一页</span>\n <ChevronRightIcon />\n </Button>\n </div>\n );\n };\n\n // ==================== 组件验证 ====================\n if (!components) {\n return (\n <div className=\"p-4 text-center text-destructive\">\n 错误:请通过 components prop 注入 UI 组件\n </div>\n );\n }\n\n // 验证侧边栏所需的所有组件\n if (showSidebar) {\n const missingComponents: string[] = [];\n if (!components.Tabs) missingComponents.push('Tabs');\n if (!components.TabsList) missingComponents.push('TabsList');\n if (!components.TabsTrigger) missingComponents.push('TabsTrigger');\n if (!components.TabsContent) missingComponents.push('TabsContent');\n if (!components.ScrollArea) missingComponents.push('ScrollArea');\n\n if (missingComponents.length > 0) {\n const missingComponentsText =\n missingComponents.length === 1\n ? missingComponents[0]\n : `${missingComponents.slice(0, -1).join('、')} 和 ${missingComponents[missingComponents.length - 1]}`;\n return (\n <div className=\"p-4 text-center text-destructive\">\n 错误:侧边栏功能需要注入 {missingComponentsText} 组件\n </div>\n );\n }\n }\n\n return (\n <div ref={readerRef}>\n <Card className={className}>\n {renderToolbar()}\n <CardContent\n className=\"p-0\"\n style={{ height: isFullscreen ? '100vh' : contentHeight }}\n >\n <div className=\"flex h-full flex-col\">\n {/* PDF 显示区域 */}\n <div className=\"flex flex-1 overflow-hidden\">\n {renderSidebar()}\n {isLoading\n ? renderLoading()\n : error\n ? renderError()\n : renderPDFDocument()}\n </div>\n </div>\n </CardContent>\n </Card>\n {renderMobileNav()}\n </div>\n );\n}\n"],"names":["useDebounce","callback","delay","timeoutRef","useRef","useCallback","args","PDFReader","url","initialPage","initialScale","initialRotation","controlledPage","onPageChange","controlledScale","onScaleChange","controlledRotation","onRotationChange","minScale","maxScale","showToolbar","showSidebar","showRotation","showModeToggle","showFullscreen","enableHotkeys","enableMobileNav","initialDisplayMode","className","toolbarClassName","contentClassName","contentHeight","pageClassName","workerUrl","cMapUrl","standardFontDataUrl","components","onLoadSuccess","onLoadError","onPageRender","loadingText","errorText","pdfDocument","setPdfDocument","useState","internalPage","setInternalPage","internalScale","setInternalScale","internalRotation","setInternalRotation","isLoading","setIsLoading","error","setError","totalPages","setTotalPages","isFullscreen","setIsFullscreen","showAllPages","setShowAllPages","showSidebarState","setShowSidebarState","useEffect","pageWidth","setPageWidth","ReactPDF","setReactPDF","readerRef","pdfContainerRef","pageRefs","currentPage","scale","rotation","isPageControlled","isScrollMode","Card","CardContent","Button","Input","Skeleton","pdfOptions","useMemo","options","isMounted","pdfModule","pdfjs","workerVersion","err","loadError","onDocumentLoadError","onDocumentLoadSuccess","pdf","page","goToPage","newPage","setPageRef","pageNumber","element","syncScrollModeCurrentPage","container","containerTop","closestPage","closestDistance","distance","zoom","delta","newScale","rotate","newRotation","debouncedUpdatePageWidth","width","updateWidth","resizeObserver","handleKeyDown","e","target","activeElement","focusedElement","role","toggleFullscreen","_b","_a","handleFullscreenChange","handleSidebarPageClick","renderToolbar","jsxs","jsx","PanelLeftIcon","ZoomOutIcon","ZoomInIcon","RotateCwIcon","ScrollTextIcon","FileTextIcon","Minimize2Icon","Maximize2Icon","ChevronLeftIcon","ChevronRightIcon","renderLoading","renderError","renderPDFDocument","Document","Page","_el","index","renderSidebar","PDFSidebarComponent","PDFSidebar","renderMobileNav","missingComponents","missingComponentsText"],"mappings":";;;;AAgKA,SAASA,GACPC,GACAC,GACG;AACH,QAAMC,IAAaC;AAAA,IACjB;AAAA,EAAA;AAEF,SAAOC;AAAA,IACL,IAAIC,MAAwB;AAC1B,MAAIH,EAAW,WACb,aAAaA,EAAW,OAAO,GAEjCA,EAAW,UAAU,WAAW,MAAMF,EAAS,GAAGK,CAAI,GAAGJ,CAAK;AAAA,IAChE;AAAA,IACA,CAACD,GAAUC,CAAK;AAAA,EAAA;AAEpB;AAqCO,SAASK,GAAU;AAAA,EACxB,KAAAC;AAAA,EACA,aAAAC,IAAc;AAAA,EACd,cAAAC,IAAe;AAAA,EACf,iBAAAC,IAAkB;AAAA,EAClB,aAAaC;AAAA,EACb,cAAAC;AAAA,EACA,OAAOC;AAAA,EACP,eAAAC;AAAA,EACA,UAAUC;AAAA,EACV,kBAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,UAAAC,IAAW;AAAA,EACX,aAAAC,KAAc;AAAA,EACd,aAAAC,IAAc;AAAA,EACd,cAAAC,KAAe;AAAA,EACf,gBAAAC,KAAiB;AAAA,EACjB,gBAAAC,KAAiB;AAAA,EACjB,eAAAC,IAAgB;AAAA,EAChB,iBAAAC,KAAkB;AAAA,EAClB,aAAaC,KAAqB;AAAA,EAClC,WAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,eAAAC,KAAgB;AAAA,EAChB,eAAAC;AAAA,EACA,WAAAC;AAAA,EACA,SAAAC;AAAA,EACA,qBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,eAAAC;AAAA,EACA,aAAAC;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC,KAAc;AAAA,EACd,WAAAC,KAAY;AACd,GAAmB;AAEjB,QAAM,CAACC,IAAaC,CAAc,IAAIC,EAAkC,IAAI,GACtE,CAACC,IAAcC,CAAe,IAAIF,EAASnC,CAAW,GACtD,CAACsC,IAAeC,EAAgB,IAAIJ,EAASlC,CAAY,GACzD,CAACuC,IAAkBC,EAAmB,IAAIN,EAASjC,CAAe,GAClE,CAACwC,IAAWC,CAAY,IAAIR,EAAS,EAAK,GAC1C,CAACS,GAAOC,CAAQ,IAAIV,EAAuB,IAAI,GAC/C,CAACW,GAAYC,CAAa,IAAIZ,EAAS,CAAC,GACxC,CAACa,IAAcC,CAAe,IAAId,EAAS,EAAK,GAChD,CAACe,GAAcC,EAAe,IAAIhB;AAAA,IACtCjB,OAAuB;AAAA,EAAA,GAEnB,CAACkC,GAAkBC,EAAmB,IAAIlB,EAASvB,CAAW;AAGpE,EAAA0C,EAAU,MAAM;AACd,IAAAD,GAAoBzC,CAAW;AAAA,EACjC,GAAG,CAACA,CAAW,CAAC;AAEhB,QAAM,CAAC2C,IAAWC,EAAY,IAAIrB,EAA6B,MAAS,GAGlE,CAACsB,IAAUC,EAAW,IAAIvB,EAAc,IAAI,GAE5CwB,KAAYhE,EAAuB,IAAI,GACvCiE,IAAkBjE,EAAuB,IAAI,GAC7CkE,IAAWlE,EAAoC,oBAAI,KAAK,GAGxDmE,IAAc3D,KAAkBiC,IAChC2B,IAAQ1D,KAAmBiC,IAC3B0B,IAAWzD,KAAsBiC,IACjCyB,IAAmB9D,MAAmB,QACtC+D,IAAehB,GAGf,EAAE,MAAAiB,IAAM,aAAAC,IAAa,QAAAC,GAAQ,OAAAC,IAAO,UAAAC,GAAA,IAAa5C,KAAc,CAAA;AAErE,EAAA2B,EAAU,MAAM;AACd,IAAApB,EAAe,IAAI,GACnBa,EAAc,CAAC,GACfF,EAAS,IAAI,GACbF,EAAa,EAAK,GACbsB,KACH5B,EAAgB,KAAK,IAAI,GAAGrC,CAAW,CAAC;AAAA,EAE5C,GAAG,CAACD,GAAKC,GAAaiE,CAAgB,CAAC;AAGvC,QAAMO,KAAaC,GAAQ,MAAM;AAC/B,UAAMC,IAAmC;AAAA,MACvC,iBAAiB;AAAA,IAAA;AAGnB,WAAIjD,MACFiD,EAAQ,UAAUjD,GAClBiD,EAAQ,aAAa,KAGnBhD,MACFgD,EAAQ,sBAAsBhD,IAGzBgD;AAAA,EACT,GAAG,CAACjD,GAASC,CAAmB,CAAC;AAGjC,EAAA4B,EAAU,MAAM;AACd,QAAIqB,IAAY;AA8ChB,YA5CqB,YAAY;AAC/B,UAAI;AAEF,cAAMC,IAAY,MAAM,OAAO,WAAW;AAG1C,YAAI,OAAO,SAAW,KAAa;AACjC,gBAAMC,IAASD,EAAkB,OAC3BE,IAAgBD,KAAA,gBAAAA,EAAO;AAE7B,UAAIA,KAAA,QAAAA,EAAO,uBAAuBC,MAC5BtD,IACFqD,EAAM,oBAAoB,YAAYrD,IAGtCqD,EAAM,oBAAoB,YAAY,2CAA2CC,CAAa,6BAI5F,CAACrD,KAAWoD,EAAM,wBACnBA,EAAM,oBAA4B,UACjC,gCAAgCC,CAAa,YAE7C,CAACpD,KAAuBmD,EAAM,wBAC/BA,EAAM,oBAA4B,sBACjC,gCAAgCC,CAAa;AAAA,QAGrD;AAEA,QAAIH,KACFjB,GAAYkB,CAAS;AAAA,MAEzB,SAASG,GAAK;AACZ,YAAIJ,GAAW;AACb,gBAAMK,IACJD,aAAe,QAAQA,IAAM,IAAI,MAAM,kBAAkB;AAC3D,UAAAlC,EAASmC,CAAS,GAClBrC,EAAa,EAAK,GAClBd,KAAA,QAAAA,EAAcmD;AAAA,QAChB;AAAA,MACF;AAAA,IACF,GAEA,GAEO,MAAM;AACX,MAAAL,IAAY;AAAA,IACd;AAAA,EACF,GAAG,CAACnD,GAAWC,GAASC,GAAqBG,CAAW,CAAC;AAGzD,QAAMoD,KAAsBrF;AAAA,IAC1B,CAACmF,MAAe;AACd,cAAQ,MAAM,YAAYA,CAAG,GAC7B,QAAQ,MAAM,YAAYhF,CAAG,GAC7BmC,EAAe,IAAI,GACnBa,EAAc,CAAC,GACfF;AAAA,QACE,IAAI,MAAM,GAAGb,EAAS,KAAK+C,EAAI,WAAW,cAAc,EAAE;AAAA,MAAA,GAE5DpC,EAAa,EAAK,GAClBd,KAAA,QAAAA,EAAckD;AAAA,IAChB;AAAA,IACA,CAAChF,GAAKiC,IAAWH,CAAW;AAAA,EAAA,GAGxBqD,KAAwBtF;AAAA,IAC5B,CAACuF,MAA0B;AACzB,MAAAjD,EAAeiD,CAAG,GAClBpC,EAAcoC,EAAI,QAAQ,GAC1BtC,EAAS,IAAI,GACbF,EAAa,EAAK,GAEbsB,KACH5B;AAAA,QAAgB,CAAC+C,MACf,KAAK,IAAI,GAAG,KAAK,IAAIA,GAAM,KAAK,IAAID,EAAI,UAAU,CAAC,CAAC,CAAC;AAAA,MAAA,GAIzDvD,KAAA,QAAAA,EAAgBuD;AAAA,IAClB;AAAA,IACA,CAAClB,GAAkBrC,CAAa;AAAA,EAAA,GAI5ByD,IAAWzF;AAAA,IACf,CAACwF,MAAiB;AAChB,UAAI,CAAC,OAAO,SAASA,CAAI,EAAG;AAC5B,YAAME,IACJxC,IAAa,IACT,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,MAAMsC,CAAI,GAAGtC,CAAU,CAAC,IAClD,KAAK,IAAI,GAAG,KAAK,MAAMsC,CAAI,CAAC;AAClC,MAAKnB,KACH5B,EAAgBiD,CAAO,GAErBA,MAAYxB,MACd1D,KAAA,QAAAA,EAAekF;AAAA,IAEnB;AAAA,IACA,CAACxC,GAAYmB,GAAkBH,GAAa1D,CAAY;AAAA,EAAA,GAGpDmF,KAAa3F;AAAA,IACjB,CAAC4F,GAAoBC,MAAmC;AACtD,MAAIA,IACF5B,EAAS,QAAQ,IAAI2B,GAAYC,CAAO,IAExC5B,EAAS,QAAQ,OAAO2B,CAAU;AAAA,IAEtC;AAAA,IACA,CAAA;AAAA,EAAC,GAGGE,KAA4B9F,EAAY,MAAM;AAClD,UAAM+F,IAAY/B,EAAgB;AAClC,QAAI,CAAC+B,KAAa,CAACzB,KAAgBpB,KAAc,EAAG;AAEpD,UAAM8C,IAAeD,EAAU,sBAAA,EAAwB;AACvD,QAAIE,IAAc/B,GACdgC,IAAkB,OAAO;AAE7B,IAAAjC,EAAS,QAAQ,QAAQ,CAAC4B,GAASD,MAAe;AAChD,YAAMO,KAAW,KAAK;AAAA,QACpBN,EAAQ,sBAAA,EAAwB,MAAMG;AAAA,MAAA;AAExC,MAAIG,KAAWD,MACbA,IAAkBC,IAClBF,IAAcL;AAAA,IAElB,CAAC,GAEGK,MAAgB/B,KAClBuB,EAASQ,CAAW;AAAA,EAExB,GAAG,CAAC/B,GAAauB,GAAUnB,GAAcpB,CAAU,CAAC,GAG9CkD,IAAOpG;AAAA,IACX,CAACqG,MAAkB;AACjB,YAAMC,IAAW,KAAK,IAAIzF,GAAU,KAAK,IAAIC,GAAUqD,IAAQkC,CAAK,CAAC;AACrE,MAAI5F,MAAoB,UACtBkC,GAAiB2D,CAAQ,GAE3B5F,KAAA,QAAAA,EAAgB4F;AAAA,IAClB;AAAA,IACA,CAACnC,GAAOtD,GAAUC,GAAUL,GAAiBC,CAAa;AAAA,EAAA,GAItD6F,KAASvG,EAAY,MAAM;AAC/B,UAAMwG,KAAepC,IAAW,MAAM;AACtC,IAAIzD,MAAuB,UACzBkC,GAAoB2D,CAAW,GAEjC5F,KAAA,QAAAA,EAAmB4F;AAAA,EACrB,GAAG,CAACpC,GAAUzD,GAAoBC,CAAgB,CAAC,GAG7C6F,KAA2B9G,GAAY,CAAC+G,MAAkB;AAC9D,IAAA9C,GAAa8C,CAAK;AAAA,EACpB,GAAG,GAAG;AAGN,EAAAhD,EAAU,MAAM;AACd,QAAI,CAACM,EAAgB,QAAS;AAE9B,UAAM+B,IAAY/B,EAAgB,SAC5B2C,IAAc,MAAM;AACxB,MAAAF,GAAyBV,EAAU,WAAW;AAAA,IAChD;AAGA,IAAAY,EAAA;AAGA,UAAMC,IAAiB,IAAI,eAAe,MAAM;AAC9C,MAAAD,EAAA;AAAA,IACF,CAAC;AAED,WAAAC,EAAe,QAAQb,CAAS,GAEzB,MAAM;AACX,MAAAa,EAAe,WAAA;AAAA,IACjB;AAAA,EACF,GAAG,CAACH,EAAwB,CAAC,GAG7B/C,EAAU,MAAM;AACd,QAAI,CAACtC,EAAe;AAEpB,UAAMyF,IAAgB,CAACC,MAAqB;AAC1C,YAAMC,IAASD,EAAE,QACXE,IACJ,OAAO,WAAa,MACf,SAAS,gBACV,MACAC,IAAiBF,KAAUC,GAC3BE,IAAOD,KAAA,gBAAAA,EAAgB,aAAa;AAE1C,MACEA,MACCA,EAAe,YAAY,WAC1BA,EAAe,YAAY,cAC3BA,EAAe,YAAY,YAC3BA,EAAe,qBACfC,MAAS,aACTA,MAAS,mBAMRJ,EAAE,WAAWA,EAAE,aAAaA,EAAE,QAAQ,OAAOA,EAAE,QAAQ,QAC1DA,EAAE,eAAA,GACFV,EAAK,GAAG,MAGAU,EAAE,WAAWA,EAAE,YAAYA,EAAE,QAAQ,OAC7CA,EAAE,eAAA,GACFV,EAAK,IAAI,KAGF,CAAC9B,KAAgBwC,EAAE,QAAQ,eAClCA,EAAE,eAAA,GACFrB,EAASvB,IAAc,CAAC,KAGjB,CAACI,KAAgBwC,EAAE,QAAQ,iBAClCA,EAAE,eAAA,GACFrB,EAASvB,IAAc,CAAC;AAAA,IAE5B;AAEA,oBAAS,iBAAiB,WAAW2C,CAAa,GAC3C,MAAM;AACX,eAAS,oBAAoB,WAAWA,CAAa;AAAA,IACvD;AAAA,EACF,GAAG,CAACzF,GAAe8C,GAAauB,GAAUnB,GAAc8B,CAAI,CAAC;AAG7D,QAAMe,KAAmBnH,EAAY,YAAY;;AAC/C,QAAI,SAAO,WAAa;AAExB,UAAK,SAAS;AAQZ,QAAI,SAAS,mBACX,MAAM,SAAS,eAAA,GACfqD,EAAgB,EAAK;AAAA;AATvB,YAAI;AACF,kBAAM+D,KAAAC,IAAAtD,GAAU,YAAV,gBAAAsD,EAAmB,sBAAnB,gBAAAD,EAAA,KAAAC,KACNhE,EAAgB,EAAI;AAAA,QACtB,SAAS8B,GAAK;AACZ,kBAAQ,MAAM,0CAA0CA,CAAG;AAAA,QAC7D;AAAA,EAOJ,GAAG,CAAA,CAAE;AAGL,EAAAzB,EAAU,MAAM;AACd,QAAI,OAAO,WAAa,IAAa;AAErC,UAAM4D,IAAyB,MAAM;AACnC,MAAAjE,EAAgB,CAAC,CAAC,SAAS,iBAAiB;AAAA,IAC9C;AAEA,oBAAS,iBAAiB,oBAAoBiE,CAAsB,GAC7D,MAAM;AACX,eAAS,oBAAoB,oBAAoBA,CAAsB;AAAA,IACzE;AAAA,EACF,GAAG,CAAA,CAAE;AAGL,QAAMC,KAAyBvH;AAAA,IAC7B,CAAC4F,MAAuB;AACtB,MAAAH,EAASG,CAAU,GACnBrC,GAAgB,EAAK;AAAA,IACvB;AAAA,IACA,CAACkC,CAAQ;AAAA,EAAA,GAIL+B,KAAgB,MACfzG,KAGH0G,gBAAAA,EAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,8DAA8DjG,MAAoB,EAAE;AAAA,MAE/F,UAAA;AAAA,QAAAiG,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAU,2BAEZ,UAAA;AAAA,UAAAzG,KACC0G,gBAAAA,EAAAA;AAAAA,YAACjD;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAMhB,GAAoB,CAACD,CAAgB;AAAA,cACpD,OAAOA,IAAmB,UAAU;AAAA,cAEpC,gCAACmE,IAAA,CAAA,CAAc;AAAA,YAAA;AAAA,UAAA;AAAA,UAKnBD,gBAAAA,EAAAA;AAAAA,YAACjD;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAM2B,EAAK,IAAI;AAAA,cACxB,UAAUjC,KAAStD;AAAA,cAEnB,gCAAC+G,IAAA,CAAA,CAAY;AAAA,YAAA;AAAA,UAAA;AAAA,UAEfH,gBAAAA,EAAAA,KAAC,QAAA,EAAK,WAAU,oCACb,UAAA;AAAA,YAAA,KAAK,MAAMtD,IAAQ,GAAG;AAAA,YAAE;AAAA,UAAA,GAC3B;AAAA,UACAuD,gBAAAA,EAAAA;AAAAA,YAACjD;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAM2B,EAAK,GAAG;AAAA,cACvB,UAAUjC,KAASrD;AAAA,cAEnB,gCAAC+G,IAAA,CAAA,CAAW;AAAA,YAAA;AAAA,UAAA;AAAA,UAIb5G,MACCyG,gBAAAA,EAAAA,IAACjD,GAAA,EAAO,SAAQ,WAAU,MAAK,QAAO,SAAS8B,IAC7C,UAAAmB,gBAAAA,EAAAA,IAACI,IAAA,CAAA,CAAa,EAAA,CAChB;AAAA,UAID5G,MACCwG,gBAAAA,EAAAA;AAAAA,YAACjD;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAMlB,GAAgB,CAACD,CAAY;AAAA,cAC5C,OAAOA,IAAe,SAAS;AAAA,cAE9B,UAAAA,IAAeoE,gBAAAA,MAACK,IAAA,CAAA,CAAe,0BAAMC,IAAA,CAAA,CAAa;AAAA,YAAA;AAAA,UAAA;AAAA,UAKtD7G,MACCuG,gBAAAA,EAAAA,IAACjD,GAAA,EAAO,SAAQ,WAAU,MAAK,QAAO,SAAS0C,IAC5C,eAAeO,gBAAAA,EAAAA,IAACO,IAAA,CAAA,CAAc,IAAKP,gBAAAA,MAACQ,MAAc,EAAA,CACrD;AAAA,QAAA,GAEJ;AAAA,QAEAT,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,UAAA,CAACnD,KACAoD,gBAAAA,EAAAA;AAAAA,YAACjD;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAMgB,EAASvB,IAAc,CAAC;AAAA,cACvC,UAAUA,KAAe;AAAA,cAEzB,gCAACiE,IAAA,CAAA,CAAgB;AAAA,YAAA;AAAA,UAAA;AAAA,UAIrBT,gBAAAA,EAAAA;AAAAA,YAAChD;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,KAAK;AAAA,cACL,KAAKxB;AAAA,cACL,OAAOgB;AAAA,cACP,UAAU,CAAC,MAAMuB,EAAS,SAAS,EAAE,OAAO,KAAK,KAAK,CAAC;AAAA,cACvD,UAAUnB;AAAA,cACV,UAAUA;AAAA,cACV,OAAOA,IAAe,mBAAmB;AAAA,cACzC,WAAU;AAAA,YAAA;AAAA,UAAA;AAAA,UAEZmD,gBAAAA,EAAAA,KAAC,QAAA,EAAK,WAAU,iCAAgC,UAAA;AAAA,YAAA;AAAA,YAAGvE;AAAA,UAAA,GAAW;AAAA,UAE7D,CAACoB,KACAoD,gBAAAA,EAAAA;AAAAA,YAACjD;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAMgB,EAASvB,IAAc,CAAC;AAAA,cACvC,UAAUhB,IAAa,KAAKgB,KAAehB;AAAA,cAE3C,gCAACkF,IAAA,CAAA,CAAiB;AAAA,YAAA;AAAA,UAAA;AAAA,QACpB,EAAA,CAEJ;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,IAtGqB,MA4GrBC,IAAgB,MACpBX,gBAAAA,EAAAA,IAAC,OAAA,EAAI,WAAU,2CACb,UAAAA,gBAAAA,EAAAA,IAAC,KAAA,EAAE,WAAU,yBAAyB,UAAAvF,GAAA,CAAY,GACpD,GAIImG,IAAc,MAClBZ,gBAAAA,EAAAA,IAAC,OAAA,EAAI,WAAU,2FACb,UAAAD,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAU,YACb,UAAA;AAAA,IAAAC,gBAAAA,EAAAA,IAAC,KAAA,EAAE,WAAU,4BAA2B,UAAA,UAAM;AAAA,IAC9CA,gBAAAA,EAAAA,IAAC,KAAA,EAAE,WAAU,sBAAsB,iCAAO,QAAA,CAAQ;AAAA,EAAA,EAAA,CACpD,EAAA,CACF,GAIIa,KAAoB,MAAM;AAC9B,QAAI,CAAC1E,GAAU,QAAOwE,EAAA;AAEtB,UAAM,EAAE,UAAAG,GAAU,MAAAC,EAAA,IAAS5E;AAE3B,WACE6D,gBAAAA,EAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAK1D;AAAA,QACL,UAAUM,IAAewB,KAA4B;AAAA,QACrD,WAAW,wCAAwCrE,MAAoB,EAAE;AAAA,QAEzE,UAAAiG,gBAAAA,EAAAA,IAAC,OAAA,EAAI,WAAU,uCACb,UAAAA,gBAAAA,EAAAA;AAAAA,UAACc;AAAA,UAAA;AAAA,YAEC,MAAMrI;AAAA,YACN,aAAakF;AAAA,YACb,SAAST;AAAA,YACT,SAASyD,EAAA;AAAA,YACT,OAAOC,EAAA;AAAA,YACP,eAAehD;AAAA,YAEd,UAAAtC,IACCsF,MACEhF;AAAA;AAAA,cAEF,MAAM,KAAK,IAAI,MAAMJ,CAAU,GAAG,CAACwF,GAAKC,MACtCjB,gBAAAA,EAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBAEC,KAAK,CAAC7B,MAAYF,GAAWgD,IAAQ,GAAG9C,CAAO;AAAA,kBAC/C,oBAAkB8C,IAAQ;AAAA,kBAC1B,WAAW,QAAQhH,MAAiB,EAAE;AAAA,kBAEtC,UAAA+F,gBAAAA,EAAAA;AAAAA,oBAACe;AAAA,oBAAA;AAAA,sBACC,YAAYE,IAAQ;AAAA,sBACpB,iBAAiB;AAAA,sBACjB,uBAAuB;AAAA,sBACvB,OAAOhF;AAAA,sBACP,OAAAQ;AAAA,sBACA,QAAQC;AAAA,sBACR,iBAAiB,MAAMlC,KAAA,gBAAAA,EAAeyG,IAAQ;AAAA,oBAAC;AAAA,kBAAA;AAAA,gBACjD;AAAA,gBAbK,QAAQA,IAAQ,CAAC;AAAA,cAAA,CAezB;AAAA;AAAA;AAAA,cAGDjB,gBAAAA,EAAAA,IAAC,OAAA,EAAI,WAAW/F,MAAiB,IAC/B,UAAA+F,gBAAAA,EAAAA;AAAAA,gBAACe;AAAA,gBAAA;AAAA,kBACC,YAAYvE;AAAA,kBACZ,iBAAiB;AAAA,kBACjB,uBAAuB;AAAA,kBACvB,OAAOP;AAAA,kBACP,OAAAQ;AAAA,kBACA,QAAQC;AAAA,kBACR,iBAAiB,MAAMlC,KAAA,gBAAAA,EAAegC;AAAA,gBAAW;AAAA,cAAA,EACnD,CACF;AAAA;AAAA,UAAA;AAAA,UA1CG/D;AAAA,QAAA,EA4CP,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN,GAGMyI,KAAgB,MAAM;AAC1B,QAAI,CAAC5H,KAAe,CAACwC,KAAoB,CAACnB,GAAa,QAAO;AAG9D,UAAMwG,IAAsBC;AAE5B,WACEpB,gBAAAA,EAAAA;AAAAA,MAACmB;AAAA,MAAA;AAAA,QACC,aAAAxG;AAAA,QACA,aAAA6B;AAAA,QACA,aAAaqD;AAAA,QACb,YAAY;AAAA,UACV,MAAMxF,EAAW;AAAA,UACjB,UAAUA,EAAW;AAAA,UACrB,aAAaA,EAAW;AAAA,UACxB,aAAaA,EAAW;AAAA,UACxB,YAAYA,EAAW;AAAA,UACvB,UAAA4C;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAGN,GAGMoE,KAAkB,MAClB,CAAC1H,MAAmBiD,IAAqB,OAG3CmD,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAU,sEACb,UAAA;AAAA,IAAAA,gBAAAA,EAAAA;AAAAA,MAAChD;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,SAAS,MAAMgB,EAASvB,IAAc,CAAC;AAAA,QACvC,UAAUI,KAAgBJ,KAAe;AAAA,QACzC,OAAOI,IAAe,kBAAkB;AAAA,QAExC,UAAA;AAAA,UAAAoD,gBAAAA,EAAAA,IAACS,IAAA,EAAgB;AAAA,UACjBT,gBAAAA,EAAAA,IAAC,QAAA,EAAK,WAAU,QAAO,UAAA,MAAA,CAAG;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAE5BD,gBAAAA,EAAAA;AAAAA,MAAChD;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,SAAS,MAAMgB,EAASvB,IAAc,CAAC;AAAA,QACvC,UAAUI,KAAgBJ,KAAehB;AAAA,QACzC,OAAOoB,IAAe,kBAAkB;AAAA,QAExC,UAAA;AAAA,UAAAoD,gBAAAA,EAAAA,IAAC,QAAA,EAAK,WAAU,QAAO,UAAA,OAAG;AAAA,gCACzBU,IAAA,CAAA,CAAiB;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EACpB,GACF;AAKJ,MAAI,CAACrG;AACH,WACE2F,gBAAAA,EAAAA,IAAC,OAAA,EAAI,WAAU,oCAAmC,UAAA,mCAElD;AAKJ,MAAI1G,GAAa;AACf,UAAMgI,IAA8B,CAAA;AAOpC,QANKjH,EAAW,QAAMiH,EAAkB,KAAK,MAAM,GAC9CjH,EAAW,YAAUiH,EAAkB,KAAK,UAAU,GACtDjH,EAAW,eAAaiH,EAAkB,KAAK,aAAa,GAC5DjH,EAAW,eAAaiH,EAAkB,KAAK,aAAa,GAC5DjH,EAAW,cAAYiH,EAAkB,KAAK,YAAY,GAE3DA,EAAkB,SAAS,GAAG;AAChC,YAAMC,IACJD,EAAkB,WAAW,IACzBA,EAAkB,CAAC,IACnB,GAAGA,EAAkB,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG,CAAC,MAAMA,EAAkBA,EAAkB,SAAS,CAAC,CAAC;AACtG,aACEvB,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAU,oCAAmC,UAAA;AAAA,QAAA;AAAA,QAClCwB;AAAA,QAAsB;AAAA,MAAA,GACtC;AAAA,IAEJ;AAAA,EACF;AAEA,SACExB,gBAAAA,EAAAA,KAAC,OAAA,EAAI,KAAK1D,IACR,UAAA;AAAA,IAAA0D,gBAAAA,EAAAA,KAAClD,MAAK,WAAAhD,IACH,UAAA;AAAA,MAAAiG,GAAA;AAAA,MACDE,gBAAAA,EAAAA;AAAAA,QAAClD;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,EAAE,QAAQpB,KAAe,UAAU1B,GAAA;AAAA,UAE1C,gCAAC,OAAA,EAAI,WAAU,wBAEb,UAAA+F,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAU,+BACZ,UAAA;AAAA,YAAAmB,GAAA;AAAA,YACA9F,KACGuF,EAAA,IACArF,IACEsF,EAAA,IACAC,GAAA;AAAA,UAAkB,EAAA,CAC1B,EAAA,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,IACF,GACF;AAAA,IACCQ,GAAA;AAAA,EAAgB,GACnB;AAEJ;"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./jsx-runtime-BB_1_6y_.cjs"),
|
|
1
|
+
"use strict";var fe=Object.create;var V=Object.defineProperty;var pe=Object.getOwnPropertyDescriptor;var je=Object.getOwnPropertyNames;var ve=Object.getPrototypeOf,Re=Object.prototype.hasOwnProperty;var Ee=(a,c,d,x)=>{if(c&&typeof c=="object"||typeof c=="function")for(let l of je(c))!Re.call(a,l)&&l!==d&&V(a,l,{get:()=>c[l],enumerable:!(x=pe(c,l))||x.enumerable});return a};var he=(a,c,d)=>(d=a!=null?fe(ve(a)):{},Ee(c||!a||!a.__esModule?V(d,"default",{value:a,enumerable:!0}):d,a));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./jsx-runtime-BB_1_6y_.cjs"),R=require("lucide-react"),n=require("react");function ye({url:a,initialPage:c=1,initialScale:d=1,scale:x,onScaleChange:l,minScale:g=.5,maxScale:D=3,currentPage:E,onPageChange:k,showToolbar:q=!0,showPagination:K=!0,enableHotkeys:A=!0,className:J,containerClassName:Q,pageClassName:X,components:C,onLoadSuccess:b,onLoadError:f,loadingText:Y="加载中...",errorText:_="加载失败"}){const[Z,H]=n.useState(null),[L,$]=n.useState(c),[S,G]=n.useState(d),[ee,w]=n.useState(!0),[N,P]=n.useState(null),[o,te]=n.useState(0),[U,se]=n.useState(!1),F=n.useRef(null),h=n.useRef(null),[j,ne]=n.useState(null),i=E??L,m=x??S,re=n.useMemo(()=>{const e=[i];return i>1&&e.push(i-1),i<o&&e.push(i+1),e},[i,o]),v=n.useCallback(e=>{const s=Math.max(o,1),r=Math.min(Math.max(e,1),s);E===void 0&&$(r),k==null||k(r)},[o,E,k]),M=n.useCallback(()=>{i>1&&v(i-1)},[i,v]),I=n.useCallback(()=>{i<o&&v(i+1)},[i,o,v]),T=n.useCallback(()=>{const e=Math.min(m+.25,D);x===void 0&&G(e),l==null||l(e)},[m,D,x,l]),z=n.useCallback(()=>{const e=Math.max(m-.25,g);x===void 0&&G(e),l==null||l(e)},[m,g,x,l]),O=n.useCallback(async()=>{var e,s,r;if(!(typeof document>"u")){if(!document.fullscreenElement){await((s=(e=F.current)==null?void 0:e.requestFullscreen)==null?void 0:s.call(e));return}await((r=document.exitFullscreen)==null?void 0:r.call(document))}},[]);if(n.useEffect(()=>{let e=!0;return(async()=>{try{const r=await import("react-pdf");if(typeof window<"u"){const u=r.pdfjs,p=u==null?void 0:u.version;u!=null&&u.GlobalWorkerOptions&&p&&(u.GlobalWorkerOptions.workerSrc=`https://cdn.jsdelivr.net/npm/pdfjs-dist@${p}/build/pdf.worker.min.mjs`)}e&&ne(r)}catch(r){if(e){const u=r instanceof Error?r:new Error("无法加载 react-pdf 库");P(u),w(!1),f==null||f(u)}}})(),()=>{e=!1}},[]),n.useEffect(()=>{if(!j||!a)return;let e=!0;return(async()=>{w(!0),P(null);try{const{Document:r}=j;if(!r)throw new Error("react-pdf Document 组件不可用");const u=j.pdfjs.getDocument(a);h.current=u;const p=await u.promise;e&&(H(p),te(p.numPages),E===void 0&&$(de=>Math.max(1,Math.min(de,p.numPages))),w(!1),b==null||b(p))}catch(r){if(e){const u=r instanceof Error?r:new Error("PDF 加载失败");P(u),w(!1),f==null||f(u)}}})(),()=>{e=!1,h.current&&typeof h.current.destroy=="function"&&(h.current.destroy(),h.current=null)}},[j,a,E,b,f]),n.useEffect(()=>{if(typeof document>"u")return;const e=()=>{se(document.fullscreenElement===F.current)};return document.addEventListener("fullscreenchange",e),()=>{document.removeEventListener("fullscreenchange",e)}},[]),n.useEffect(()=>{if(!A)return;const e=s=>{const r=document.activeElement;r&&(r.tagName==="INPUT"||r.getAttribute("role")==="input")||((s.ctrlKey||s.metaKey)&&(s.key==="="||s.key==="+")?(s.preventDefault(),T()):(s.ctrlKey||s.metaKey)&&s.key==="-"?(s.preventDefault(),z()):s.key==="ArrowLeft"?(s.preventDefault(),M()):s.key==="ArrowRight"?(s.preventDefault(),I()):(s.key==="f"||s.key==="F")&&(s.preventDefault(),O()))};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[A,T,z,M,I,O]),!C)return t.jsxRuntimeExports.jsx("div",{className:"p-4 text-center text-destructive",children:"错误:请通过 components prop 注入 UI 组件"});const{Card:ie,CardContent:ue,Button:y,Input:W,Skeleton:B}=C,ae=()=>q?t.jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-2",children:[t.jsxRuntimeExports.jsx(y,{variant:"outline",size:"sm",onClick:z,disabled:m<=g,children:t.jsxRuntimeExports.jsx(R.ZoomOut,{})}),t.jsxRuntimeExports.jsxs("span",{className:"text-sm",children:[Math.round(m*100),"%"]}),t.jsxRuntimeExports.jsx(y,{variant:"outline",size:"sm",onClick:T,disabled:m>=D,children:t.jsxRuntimeExports.jsx(R.ZoomIn,{})}),t.jsxRuntimeExports.jsx(y,{variant:"outline",size:"icon",onClick:()=>{O()},children:U?t.jsxRuntimeExports.jsx(R.Minimize2,{}):t.jsxRuntimeExports.jsx(R.Maximize2,{})})]}):null,le=()=>K?t.jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-2",children:[t.jsxRuntimeExports.jsx(y,{variant:"outline",size:"icon",onClick:M,disabled:i<=1,children:t.jsxRuntimeExports.jsx(R.ChevronLeft,{})}),W?t.jsxRuntimeExports.jsx(W,{type:"number",min:1,max:Math.max(o,1),value:i,onChange:e=>v(parseInt(e.target.value,10)||1),className:"w-16 text-center"}):t.jsxRuntimeExports.jsx("input",{type:"number",min:1,max:Math.max(o,1),value:i,onChange:e=>v(parseInt(e.target.value,10)||1),className:"w-16 rounded-md border border-input bg-background px-2 text-center text-sm"}),t.jsxRuntimeExports.jsxs("span",{className:"text-sm text-muted-foreground",children:["/ ",o]}),t.jsxRuntimeExports.jsx(y,{variant:"outline",size:"icon",onClick:I,disabled:i>=o,children:t.jsxRuntimeExports.jsx(R.ChevronRight,{})})]}):null,ce=()=>!q&&!K?null:t.jsxRuntimeExports.jsxs("div",{"data-testid":"pdf-operations-bar",className:"flex items-center justify-between gap-4 border-b px-4 py-2",children:[ae(),le()]}),oe=()=>t.jsxRuntimeExports.jsxs("div",{className:"flex flex-col items-center justify-center space-y-4 p-8",children:[t.jsxRuntimeExports.jsx(B,{className:"h-8 w-32"}),t.jsxRuntimeExports.jsx(B,{className:"h-64 w-full max-w-2xl"}),t.jsxRuntimeExports.jsx("p",{className:"text-sm text-muted-foreground",children:Y})]}),xe=()=>t.jsxRuntimeExports.jsx("div",{className:"flex flex-col items-center justify-center space-y-4 p-8",children:t.jsxRuntimeExports.jsxs("div",{className:"text-center text-destructive",children:[t.jsxRuntimeExports.jsx("p",{className:"font-medium",children:_}),N&&t.jsxRuntimeExports.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:N.message})]})}),me=()=>{if(!j||!Z)return null;const{Page:e}=j;return t.jsxRuntimeExports.jsx("div",{className:`flex flex-col items-center justify-center ${U?"h-[calc(100vh-56px)] overflow-auto":"overflow-visible"}`,children:re.map(s=>t.jsxRuntimeExports.jsx("div",{className:X,style:{display:s===i?"block":"none"},children:t.jsxRuntimeExports.jsx(e,{pdf:Z,pageNumber:s,scale:m,renderTextLayer:!1,renderAnnotationLayer:!1,className:"shadow-md"})},s))})};return t.jsxRuntimeExports.jsx("div",{ref:F,children:t.jsxRuntimeExports.jsxs(ie,{className:J,children:[ce(),t.jsxRuntimeExports.jsx(ue,{className:Q,children:ee?oe():N?xe():me()})]})})}exports.SimplePDFReader=ye;
|
|
2
2
|
//# sourceMappingURL=simple-pdf-reader.cjs.map
|