@cannymindstech/file-viewers 0.28.0 → 0.28.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/chunk-2BLHLWNN.js +299 -0
  2. package/dist/chunk-2BLHLWNN.js.map +1 -0
  3. package/dist/chunk-4HVU224A.js +2454 -0
  4. package/dist/chunk-4HVU224A.js.map +1 -0
  5. package/dist/chunk-6BRYDA3B.js +329 -0
  6. package/dist/chunk-6BRYDA3B.js.map +1 -0
  7. package/dist/chunk-6L72TJIW.mjs +2454 -0
  8. package/dist/chunk-6L72TJIW.mjs.map +1 -0
  9. package/dist/chunk-7PMZ4GN5.mjs +290 -0
  10. package/dist/chunk-7PMZ4GN5.mjs.map +1 -0
  11. package/dist/chunk-B5NNB4KD.mjs +268 -0
  12. package/dist/chunk-B5NNB4KD.mjs.map +1 -0
  13. package/dist/chunk-CIWCHSAA.js +309 -0
  14. package/dist/chunk-CIWCHSAA.js.map +1 -0
  15. package/dist/chunk-D7SDEVDM.js +268 -0
  16. package/dist/chunk-D7SDEVDM.js.map +1 -0
  17. package/dist/chunk-EKNP342T.mjs +299 -0
  18. package/dist/chunk-EKNP342T.mjs.map +1 -0
  19. package/dist/chunk-EM63H4SA.js +290 -0
  20. package/dist/chunk-EM63H4SA.js.map +1 -0
  21. package/dist/chunk-IJMNPAXX.mjs +309 -0
  22. package/dist/chunk-IJMNPAXX.mjs.map +1 -0
  23. package/dist/chunk-JKX5RSLF.mjs +871 -0
  24. package/dist/chunk-JKX5RSLF.mjs.map +1 -0
  25. package/dist/chunk-KJNOBIUZ.mjs +36 -0
  26. package/dist/chunk-KJNOBIUZ.mjs.map +1 -0
  27. package/dist/chunk-KQLIG6WK.js +871 -0
  28. package/dist/chunk-KQLIG6WK.js.map +1 -0
  29. package/dist/chunk-KWHXS7I4.mjs +615 -0
  30. package/dist/chunk-KWHXS7I4.mjs.map +1 -0
  31. package/dist/chunk-NELCZBZV.js +489 -0
  32. package/dist/chunk-NELCZBZV.js.map +1 -0
  33. package/dist/chunk-OPJOCUSL.js +36 -0
  34. package/dist/chunk-OPJOCUSL.js.map +1 -0
  35. package/dist/chunk-S5KXYKBX.js +615 -0
  36. package/dist/chunk-S5KXYKBX.js.map +1 -0
  37. package/dist/chunk-W2P6JHTQ.mjs +489 -0
  38. package/dist/chunk-W2P6JHTQ.mjs.map +1 -0
  39. package/dist/chunk-XJQ5J2UF.mjs +329 -0
  40. package/dist/chunk-XJQ5J2UF.mjs.map +1 -0
  41. package/dist/components/viewers/AudioViewer.d.mts +6 -0
  42. package/dist/components/viewers/AudioViewer.d.ts +6 -0
  43. package/dist/components/viewers/AudioViewer.js +10 -0
  44. package/dist/components/viewers/AudioViewer.js.map +1 -0
  45. package/dist/components/viewers/AudioViewer.mjs +10 -0
  46. package/dist/components/viewers/AudioViewer.mjs.map +1 -0
  47. package/dist/components/viewers/DefaultViewer.d.mts +6 -0
  48. package/dist/components/viewers/DefaultViewer.d.ts +6 -0
  49. package/dist/components/viewers/DefaultViewer.js +10 -0
  50. package/dist/components/viewers/DefaultViewer.js.map +1 -0
  51. package/dist/components/viewers/DefaultViewer.mjs +10 -0
  52. package/dist/components/viewers/DefaultViewer.mjs.map +1 -0
  53. package/dist/components/viewers/ImageViewer.d.mts +6 -0
  54. package/dist/components/viewers/ImageViewer.d.ts +6 -0
  55. package/dist/components/viewers/ImageViewer.js +10 -0
  56. package/dist/components/viewers/ImageViewer.js.map +1 -0
  57. package/dist/components/viewers/ImageViewer.mjs +10 -0
  58. package/dist/components/viewers/ImageViewer.mjs.map +1 -0
  59. package/dist/components/viewers/PDFViewer.d.mts +51 -0
  60. package/dist/components/viewers/PDFViewer.d.ts +51 -0
  61. package/dist/components/viewers/PDFViewer.js +11 -0
  62. package/dist/components/viewers/PDFViewer.js.map +1 -0
  63. package/dist/components/viewers/PDFViewer.mjs +11 -0
  64. package/dist/components/viewers/PDFViewer.mjs.map +1 -0
  65. package/dist/components/viewers/TIFFViewer.d.mts +6 -0
  66. package/dist/components/viewers/TIFFViewer.d.ts +6 -0
  67. package/dist/components/viewers/TIFFViewer.js +10 -0
  68. package/dist/components/viewers/TIFFViewer.js.map +1 -0
  69. package/dist/components/viewers/TIFFViewer.mjs +10 -0
  70. package/dist/components/viewers/TIFFViewer.mjs.map +1 -0
  71. package/dist/components/viewers/TextViewer.d.mts +6 -0
  72. package/dist/components/viewers/TextViewer.d.ts +6 -0
  73. package/dist/components/viewers/TextViewer.js +10 -0
  74. package/dist/components/viewers/TextViewer.js.map +1 -0
  75. package/dist/components/viewers/TextViewer.mjs +10 -0
  76. package/dist/components/viewers/TextViewer.mjs.map +1 -0
  77. package/dist/components/viewers/VideoViewer.d.mts +6 -0
  78. package/dist/components/viewers/VideoViewer.d.ts +6 -0
  79. package/dist/components/viewers/VideoViewer.js +10 -0
  80. package/dist/components/viewers/VideoViewer.js.map +1 -0
  81. package/dist/components/viewers/VideoViewer.mjs +10 -0
  82. package/dist/components/viewers/VideoViewer.mjs.map +1 -0
  83. package/dist/index.d.mts +75 -0
  84. package/dist/index.d.ts +75 -0
  85. package/dist/index.js +305 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/index.mjs +305 -0
  88. package/dist/index.mjs.map +1 -0
  89. package/dist/types-DMF9gANJ.d.mts +101 -0
  90. package/dist/types-DMF9gANJ.d.ts +101 -0
  91. package/package.json +3 -2
@@ -0,0 +1,2454 @@
1
+ "use client";
2
+ import {
3
+ toolbarStyles
4
+ } from "./chunk-KWHXS7I4.mjs";
5
+ import {
6
+ getFileExtension
7
+ } from "./chunk-KJNOBIUZ.mjs";
8
+ import {
9
+ FileIcon_default,
10
+ mergeToolbarConfig
11
+ } from "./chunk-7PMZ4GN5.mjs";
12
+
13
+ // src/components/viewers/PDFViewer.tsx
14
+ import {
15
+ useCallback,
16
+ useEffect as useEffect4,
17
+ useMemo,
18
+ useRef as useRef3,
19
+ useState as useState4,
20
+ forwardRef,
21
+ useImperativeHandle
22
+ } from "react";
23
+
24
+ // src/components/viewers/pdf/StablePDFViewer.tsx
25
+ import React from "react";
26
+ import { PDFViewer as HeadlessPDFViewerImport } from "@cannymindstech/pdf-viewer";
27
+ import { jsx } from "react/jsx-runtime";
28
+ var HeadlessPDFViewer = HeadlessPDFViewerImport;
29
+ var StablePDFViewer = React.memo(({
30
+ pdfBuffer,
31
+ onPasswordRequest,
32
+ pdfViewerRef,
33
+ showAnnotations,
34
+ userDetails,
35
+ annotationSelectionMenu,
36
+ isHighlighterActive,
37
+ isStampActive,
38
+ onHighlighterClick,
39
+ onStampClick,
40
+ onSignatureClick,
41
+ onNoteClick,
42
+ permissions,
43
+ hideInternalLoading,
44
+ isAnnotationForeign,
45
+ onAnnotationNoteClick,
46
+ isAnnotationInteractive,
47
+ twoPageMode,
48
+ scrollStrategy
49
+ }) => {
50
+ return /* @__PURE__ */ jsx(
51
+ HeadlessPDFViewer,
52
+ {
53
+ ref: pdfViewerRef,
54
+ pdfBuffer,
55
+ onPasswordRequest,
56
+ showAnnotations,
57
+ userDetails,
58
+ annotationSelectionMenu,
59
+ isHighlighterActive,
60
+ isStampActive,
61
+ onHighlighterClick,
62
+ onStampClick,
63
+ onSignatureClick,
64
+ onNoteClick,
65
+ permissions,
66
+ hideInternalLoading,
67
+ isAnnotationForeign,
68
+ onAnnotationNoteClick,
69
+ isAnnotationInteractive,
70
+ twoPageMode,
71
+ scrollStrategy
72
+ }
73
+ );
74
+ });
75
+ StablePDFViewer.displayName = "StablePDFViewer";
76
+
77
+ // src/components/viewers/pdf/PDFToolbar.tsx
78
+ import React2, { useState, useRef, useEffect } from "react";
79
+ import { Tooltip } from "@mui/material";
80
+ import FirstPageIcon from "@mui/icons-material/FirstPage";
81
+ import LastPageIcon from "@mui/icons-material/LastPage";
82
+ import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
83
+ import ChevronRightIcon from "@mui/icons-material/ChevronRight";
84
+ import RemoveIcon from "@mui/icons-material/Remove";
85
+ import AddIcon from "@mui/icons-material/Add";
86
+ import FitScreenIcon from "@mui/icons-material/FitScreen";
87
+ import AspectRatioIcon from "@mui/icons-material/AspectRatio";
88
+ import TuneIcon from "@mui/icons-material/Tune";
89
+ import SearchIcon from "@mui/icons-material/Search";
90
+ import FullscreenIcon from "@mui/icons-material/Fullscreen";
91
+ import DownloadIcon from "@mui/icons-material/Download";
92
+ import PrintIcon from "@mui/icons-material/Print";
93
+ import InfoIcon from "@mui/icons-material/Info";
94
+ import DescriptionIcon from "@mui/icons-material/Description";
95
+ import RotateLeftIcon from "@mui/icons-material/RotateLeft";
96
+ import RotateRightIcon from "@mui/icons-material/RotateRight";
97
+ import HistoryIcon from "@mui/icons-material/History";
98
+ import { LocalOffer } from "@mui/icons-material";
99
+ import HighlightIcon from "@mui/icons-material/Highlight";
100
+ import DrawIcon from "@mui/icons-material/Draw";
101
+ import ApprovalIcon from "@mui/icons-material/Approval";
102
+ import StickyNote2Icon from "@mui/icons-material/StickyNote2";
103
+ import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
104
+ import PortraitIcon from "@mui/icons-material/Portrait";
105
+ import MenuBookIcon from "@mui/icons-material/MenuBook";
106
+ import VerticalSplitIcon from "@mui/icons-material/VerticalSplit";
107
+ import SwapVertIcon from "@mui/icons-material/SwapVert";
108
+ import SwapHorizIcon from "@mui/icons-material/SwapHoriz";
109
+ import AutoFixHighIcon from "@mui/icons-material/AutoFixHigh";
110
+ import { ScrollStrategy } from "@cannymindstech/pdf-viewer";
111
+ import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
112
+ var PDFToolbar = React2.memo(
113
+ ({
114
+ currentPage,
115
+ totalPages,
116
+ zoom,
117
+ isSidebarOpen,
118
+ showPageNavigation,
119
+ showPageCount,
120
+ showZoomControls,
121
+ showSearch,
122
+ showMetadata,
123
+ showProperties,
124
+ showTags,
125
+ showHistory,
126
+ showDownload,
127
+ showPrint,
128
+ showRotation,
129
+ showAnnotations,
130
+ // Layout and Sidebar controls
131
+ twoPageMode = false,
132
+ onTwoPageModeChange,
133
+ scrollStrategy = ScrollStrategy.Vertical,
134
+ onScrollStrategyChange,
135
+ showThumbnails = false,
136
+ onToggleThumbnails,
137
+ // Destructure new props with defaults
138
+ showAnnotate = true,
139
+ disabledAnnotate = false,
140
+ showPrintOriginal = true,
141
+ showPrintWithAnnotations = true,
142
+ showDownloadOriginal = true,
143
+ showDownloadWithAnnotations = true,
144
+ isHighlighterActive,
145
+ isStampActive,
146
+ disabledRotateLeft,
147
+ disabledRotateRight,
148
+ disabledMetadata,
149
+ disabledProperties,
150
+ disabledTags,
151
+ disabledHistory,
152
+ disabledDownload,
153
+ disabledPrint,
154
+ disabledCopy,
155
+ disabledHighlighter,
156
+ disabledStamp,
157
+ disabledSignature,
158
+ disabledNote,
159
+ onFirstPage,
160
+ onPreviousPage,
161
+ onNextPage,
162
+ onLastPage,
163
+ onPageInput,
164
+ onPageInputKeyPress,
165
+ onZoomIn,
166
+ onZoomOut,
167
+ onFitToWidth,
168
+ onFitToPage,
169
+ onToggleSidebar,
170
+ onToggleFullScreen,
171
+ onRotateLeft,
172
+ onRotateRight,
173
+ onDownloadClick,
174
+ onDownloadWithAnnotations,
175
+ onDownloadWithoutAnnotations,
176
+ onPrintClick,
177
+ onPrintWithAnnotations,
178
+ onPrintWithoutAnnotations,
179
+ onCopyClick,
180
+ onMetadataClick,
181
+ onPropertiesClick,
182
+ onTagsClick,
183
+ onHistoryClick,
184
+ onHighlighterClick,
185
+ onStampClick,
186
+ onSignatureClick,
187
+ onNoteClick,
188
+ // Save functionality
189
+ hasUnsavedAnnotations,
190
+ isSavingAnnotations,
191
+ canSaveAnnotations,
192
+ onSaveAnnotations,
193
+ // Toolbar mode state
194
+ activeMode = "view",
195
+ onActiveModeChange
196
+ }) => {
197
+ const [isPrintMenuOpen, setIsPrintMenuOpen] = useState(false);
198
+ const [isDownloadMenuOpen, setIsDownloadMenuOpen] = useState(false);
199
+ const [isAnnotationMenuOpen, setIsAnnotationMenuOpen] = useState(false);
200
+ const [isViewMenuOpen, setIsViewMenuOpen] = useState(false);
201
+ const printMenuRef = useRef(null);
202
+ const downloadMenuRef = useRef(null);
203
+ const annotationMenuRef = useRef(null);
204
+ const viewMenuRef = useRef(null);
205
+ useEffect(() => {
206
+ const handleClickOutside = (event) => {
207
+ if (printMenuRef.current && !printMenuRef.current.contains(event.target)) {
208
+ setIsPrintMenuOpen(false);
209
+ }
210
+ if (downloadMenuRef.current && !downloadMenuRef.current.contains(event.target)) {
211
+ setIsDownloadMenuOpen(false);
212
+ }
213
+ if (annotationMenuRef.current && !annotationMenuRef.current.contains(event.target)) {
214
+ setIsAnnotationMenuOpen(false);
215
+ }
216
+ if (viewMenuRef.current && !viewMenuRef.current.contains(event.target)) {
217
+ setIsViewMenuOpen(false);
218
+ }
219
+ };
220
+ document.addEventListener("mousedown", handleClickOutside);
221
+ return () => document.removeEventListener("mousedown", handleClickOutside);
222
+ }, []);
223
+ const handlePrintWithAnnotations = () => {
224
+ setIsPrintMenuOpen(false);
225
+ onPrintWithAnnotations?.();
226
+ };
227
+ const handlePrintWithoutAnnotations = () => {
228
+ setIsPrintMenuOpen(false);
229
+ onPrintWithoutAnnotations?.();
230
+ };
231
+ const handleDownloadWithAnnotations = () => {
232
+ setIsDownloadMenuOpen(false);
233
+ onDownloadWithAnnotations?.();
234
+ };
235
+ const handleDownloadWithoutAnnotations = () => {
236
+ setIsDownloadMenuOpen(false);
237
+ onDownloadWithoutAnnotations?.();
238
+ };
239
+ return /* @__PURE__ */ jsx2("div", { className: "pdf-viewer-toolbar-container", children: /* @__PURE__ */ jsxs("div", { className: "pdf-viewer-toolbar", children: [
240
+ /* @__PURE__ */ jsxs("div", { className: "toolbar-left", children: [
241
+ /* @__PURE__ */ jsx2(Tooltip, { title: "Toggle Page Previews", children: /* @__PURE__ */ jsx2(
242
+ "button",
243
+ {
244
+ className: `toolbar-button ${showThumbnails ? "toolbar-button-active" : ""}`,
245
+ onClick: onToggleThumbnails,
246
+ style: { marginRight: "8px" },
247
+ children: /* @__PURE__ */ jsx2(VerticalSplitIcon, { fontSize: "small" })
248
+ }
249
+ ) }),
250
+ showPageNavigation && /* @__PURE__ */ jsxs("div", { className: "toolbar-section", children: [
251
+ /* @__PURE__ */ jsx2(Tooltip, { title: "First Page", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsx2(
252
+ "button",
253
+ {
254
+ className: "toolbar-button",
255
+ onClick: onFirstPage,
256
+ disabled: currentPage <= 1,
257
+ children: /* @__PURE__ */ jsx2(FirstPageIcon, { fontSize: "small" })
258
+ }
259
+ ) }) }),
260
+ /* @__PURE__ */ jsx2(Tooltip, { title: "Previous Page", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsx2(
261
+ "button",
262
+ {
263
+ className: "toolbar-button",
264
+ onClick: onPreviousPage,
265
+ disabled: currentPage <= 1,
266
+ children: /* @__PURE__ */ jsx2(ChevronLeftIcon, { fontSize: "small" })
267
+ }
268
+ ) }) }),
269
+ /* @__PURE__ */ jsxs("span", { className: "page-info", style: { display: "flex", alignItems: "center", margin: "0 8px", fontSize: "14px", fontWeight: 500 }, children: [
270
+ currentPage,
271
+ " ",
272
+ showPageCount && /* @__PURE__ */ jsxs("span", { style: { color: "#6b7280", marginLeft: "4px" }, children: [
273
+ "/ ",
274
+ totalPages || "..."
275
+ ] })
276
+ ] }),
277
+ /* @__PURE__ */ jsx2(Tooltip, { title: "Next Page", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsx2(
278
+ "button",
279
+ {
280
+ className: "toolbar-button",
281
+ onClick: onNextPage,
282
+ disabled: currentPage >= totalPages,
283
+ children: /* @__PURE__ */ jsx2(ChevronRightIcon, { fontSize: "small" })
284
+ }
285
+ ) }) }),
286
+ /* @__PURE__ */ jsx2(Tooltip, { title: "Last Page", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsx2(
287
+ "button",
288
+ {
289
+ className: "toolbar-button",
290
+ onClick: onLastPage,
291
+ disabled: currentPage >= totalPages,
292
+ children: /* @__PURE__ */ jsx2(LastPageIcon, { fontSize: "small" })
293
+ }
294
+ ) }) })
295
+ ] }),
296
+ showZoomControls && /* @__PURE__ */ jsxs(Fragment, { children: [
297
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-separator" }),
298
+ /* @__PURE__ */ jsxs("div", { className: "toolbar-section", children: [
299
+ /* @__PURE__ */ jsx2(Tooltip, { title: "Zoom Out", children: /* @__PURE__ */ jsx2(
300
+ "button",
301
+ {
302
+ className: "toolbar-button",
303
+ onClick: onZoomOut,
304
+ children: /* @__PURE__ */ jsx2(RemoveIcon, { fontSize: "small" })
305
+ }
306
+ ) }),
307
+ /* @__PURE__ */ jsxs("span", { className: "zoom-display", children: [
308
+ zoom,
309
+ "%"
310
+ ] }),
311
+ /* @__PURE__ */ jsx2(Tooltip, { title: "Zoom In", children: /* @__PURE__ */ jsx2(
312
+ "button",
313
+ {
314
+ className: "toolbar-button",
315
+ onClick: onZoomIn,
316
+ children: /* @__PURE__ */ jsx2(AddIcon, { fontSize: "small" })
317
+ }
318
+ ) })
319
+ ] })
320
+ ] }),
321
+ (showZoomControls || showRotation) && /* @__PURE__ */ jsxs(Fragment, { children: [
322
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-separator" }),
323
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-section", children: /* @__PURE__ */ jsxs("div", { className: "toolbar-dropdown-container", ref: viewMenuRef, children: [
324
+ /* @__PURE__ */ jsx2(Tooltip, { title: "View Options", children: /* @__PURE__ */ jsxs(
325
+ "button",
326
+ {
327
+ className: `toolbar-button toolbar-dropdown-button ${isViewMenuOpen ? "toolbar-button-active" : ""}`,
328
+ onClick: () => setIsViewMenuOpen(!isViewMenuOpen),
329
+ children: [
330
+ /* @__PURE__ */ jsx2(TuneIcon, { fontSize: "small" }),
331
+ /* @__PURE__ */ jsx2(KeyboardArrowDownIcon, { fontSize: "small", style: { marginLeft: -4 } })
332
+ ]
333
+ }
334
+ ) }),
335
+ isViewMenuOpen && /* @__PURE__ */ jsxs("div", { className: "toolbar-dropdown-menu", style: { width: "240px" }, children: [
336
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-dropdown-header", children: "SPREAD MODE" }),
337
+ /* @__PURE__ */ jsxs(
338
+ "button",
339
+ {
340
+ className: `toolbar-dropdown-item ${!twoPageMode ? "toolbar-dropdown-item-active" : ""}`,
341
+ onClick: () => {
342
+ setIsViewMenuOpen(false);
343
+ onTwoPageModeChange?.(false);
344
+ },
345
+ children: [
346
+ /* @__PURE__ */ jsx2(PortraitIcon, { fontSize: "small" }),
347
+ /* @__PURE__ */ jsx2("span", { children: "Single Page" })
348
+ ]
349
+ }
350
+ ),
351
+ /* @__PURE__ */ jsxs(
352
+ "button",
353
+ {
354
+ className: `toolbar-dropdown-item ${twoPageMode ? "toolbar-dropdown-item-active" : ""}`,
355
+ onClick: () => {
356
+ setIsViewMenuOpen(false);
357
+ onTwoPageModeChange?.(true);
358
+ },
359
+ children: [
360
+ /* @__PURE__ */ jsx2(MenuBookIcon, { fontSize: "small" }),
361
+ /* @__PURE__ */ jsx2("span", { children: "Two-Page Spread" })
362
+ ]
363
+ }
364
+ ),
365
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-dropdown-divider" }),
366
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-dropdown-header", children: "SCROLL LAYOUT" }),
367
+ /* @__PURE__ */ jsxs(
368
+ "button",
369
+ {
370
+ className: `toolbar-dropdown-item ${scrollStrategy !== ScrollStrategy.Horizontal ? "toolbar-dropdown-item-active" : ""}`,
371
+ onClick: () => {
372
+ setIsViewMenuOpen(false);
373
+ onScrollStrategyChange?.(ScrollStrategy.Vertical);
374
+ },
375
+ children: [
376
+ /* @__PURE__ */ jsx2(SwapVertIcon, { fontSize: "small" }),
377
+ /* @__PURE__ */ jsx2("span", { children: "Vertical Scroll" })
378
+ ]
379
+ }
380
+ ),
381
+ /* @__PURE__ */ jsxs(
382
+ "button",
383
+ {
384
+ className: `toolbar-dropdown-item ${scrollStrategy === ScrollStrategy.Horizontal ? "toolbar-dropdown-item-active" : ""}`,
385
+ onClick: () => {
386
+ setIsViewMenuOpen(false);
387
+ onScrollStrategyChange?.(ScrollStrategy.Horizontal);
388
+ },
389
+ children: [
390
+ /* @__PURE__ */ jsx2(SwapHorizIcon, { fontSize: "small" }),
391
+ /* @__PURE__ */ jsx2("span", { children: "Horizontal Scroll" })
392
+ ]
393
+ }
394
+ ),
395
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-dropdown-divider" }),
396
+ /* @__PURE__ */ jsxs("button", { className: "toolbar-dropdown-item", onClick: () => {
397
+ setIsViewMenuOpen(false);
398
+ onFitToWidth?.();
399
+ }, children: [
400
+ /* @__PURE__ */ jsx2(AspectRatioIcon, { fontSize: "small" }),
401
+ /* @__PURE__ */ jsx2("span", { children: "Fit to Width" })
402
+ ] }),
403
+ /* @__PURE__ */ jsxs("button", { className: "toolbar-dropdown-item", onClick: () => {
404
+ setIsViewMenuOpen(false);
405
+ onFitToPage?.();
406
+ }, children: [
407
+ /* @__PURE__ */ jsx2(FitScreenIcon, { fontSize: "small" }),
408
+ /* @__PURE__ */ jsx2("span", { children: "Fit to Page" })
409
+ ] }),
410
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-dropdown-divider" }),
411
+ showRotation && /* @__PURE__ */ jsxs(Fragment, { children: [
412
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-dropdown-header", children: "PAGE ROTATION" }),
413
+ /* @__PURE__ */ jsxs(
414
+ "button",
415
+ {
416
+ className: "toolbar-dropdown-item",
417
+ onClick: () => {
418
+ setIsViewMenuOpen(false);
419
+ onRotateRight?.();
420
+ },
421
+ disabled: false,
422
+ children: [
423
+ /* @__PURE__ */ jsx2(RotateRightIcon, { fontSize: "small" }),
424
+ /* @__PURE__ */ jsx2("span", { children: "Rotate Clockwise" })
425
+ ]
426
+ }
427
+ ),
428
+ /* @__PURE__ */ jsxs(
429
+ "button",
430
+ {
431
+ className: "toolbar-dropdown-item",
432
+ onClick: () => {
433
+ setIsViewMenuOpen(false);
434
+ onRotateLeft?.();
435
+ },
436
+ disabled: disabledRotateLeft,
437
+ children: [
438
+ /* @__PURE__ */ jsx2(RotateLeftIcon, { fontSize: "small" }),
439
+ /* @__PURE__ */ jsx2("span", { children: "Rotate Counter-Clockwise" })
440
+ ]
441
+ }
442
+ )
443
+ ] }),
444
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-dropdown-divider" }),
445
+ /* @__PURE__ */ jsxs(
446
+ "button",
447
+ {
448
+ className: "toolbar-dropdown-item",
449
+ onClick: () => {
450
+ setIsViewMenuOpen(false);
451
+ onToggleFullScreen();
452
+ },
453
+ children: [
454
+ /* @__PURE__ */ jsx2(FullscreenIcon, { fontSize: "small" }),
455
+ /* @__PURE__ */ jsx2("span", { children: "Fullscreen" })
456
+ ]
457
+ }
458
+ )
459
+ ] })
460
+ ] }) })
461
+ ] }),
462
+ showSearch && /* @__PURE__ */ jsxs(Fragment, { children: [
463
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-separator" }),
464
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-section", children: /* @__PURE__ */ jsx2(Tooltip, { title: "Search", children: /* @__PURE__ */ jsx2(
465
+ "button",
466
+ {
467
+ className: `toolbar-button ${isSidebarOpen ? "toolbar-button-active" : ""}`,
468
+ onClick: onToggleSidebar,
469
+ children: /* @__PURE__ */ jsx2(SearchIcon, { fontSize: "small" })
470
+ }
471
+ ) }) })
472
+ ] })
473
+ ] }),
474
+ /* @__PURE__ */ jsxs("div", { className: "toolbar-center", children: [
475
+ /* @__PURE__ */ jsx2(
476
+ "button",
477
+ {
478
+ className: `toolbar-tab ${activeMode === "view" ? "toolbar-tab-active" : ""}`,
479
+ onClick: () => onActiveModeChange?.("view"),
480
+ children: "View"
481
+ }
482
+ ),
483
+ showAnnotate && /* @__PURE__ */ jsxs(
484
+ "button",
485
+ {
486
+ className: `toolbar-tab ${activeMode === "annotate" ? "toolbar-tab-active" : ""}`,
487
+ onClick: () => !disabledAnnotate && onActiveModeChange?.("annotate"),
488
+ style: {
489
+ position: "relative",
490
+ opacity: disabledAnnotate ? 0.5 : 1,
491
+ cursor: disabledAnnotate ? "not-allowed" : "pointer"
492
+ },
493
+ children: [
494
+ "Annotate",
495
+ hasUnsavedAnnotations && /* @__PURE__ */ jsx2("span", { style: {
496
+ position: "absolute",
497
+ top: "4px",
498
+ right: "4px",
499
+ width: "6px",
500
+ height: "6px",
501
+ backgroundColor: "#ef4444",
502
+ borderRadius: "50%"
503
+ } })
504
+ ]
505
+ }
506
+ )
507
+ ] }),
508
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-right", children: (hasUnsavedAnnotations || showDownload || showPrint || showMetadata || showProperties || showTags || showHistory) && /* @__PURE__ */ jsxs(Fragment, { children: [
509
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-separator" }),
510
+ /* @__PURE__ */ jsxs("div", { className: "toolbar-section", children: [
511
+ showDownload && /* @__PURE__ */ jsx2("div", { className: "toolbar-dropdown-container", ref: downloadMenuRef, children: showDownloadOriginal && showDownloadWithAnnotations ? (
512
+ // RENDER DROPDOWN if BOTH are enabled
513
+ /* @__PURE__ */ jsxs(Fragment, { children: [
514
+ /* @__PURE__ */ jsx2(Tooltip, { title: "Download", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsxs(
515
+ "button",
516
+ {
517
+ className: `toolbar-button toolbar-dropdown-button ${isDownloadMenuOpen ? "toolbar-button-active" : ""}`,
518
+ onClick: () => setIsDownloadMenuOpen(!isDownloadMenuOpen),
519
+ disabled: disabledDownload,
520
+ children: [
521
+ /* @__PURE__ */ jsx2(DownloadIcon, { fontSize: "small" }),
522
+ /* @__PURE__ */ jsx2(KeyboardArrowDownIcon, { fontSize: "small", style: { marginLeft: -4 } })
523
+ ]
524
+ }
525
+ ) }) }),
526
+ isDownloadMenuOpen && /* @__PURE__ */ jsxs("div", { className: "toolbar-dropdown-menu toolbar-dropdown-menu-right", children: [
527
+ /* @__PURE__ */ jsx2(
528
+ "button",
529
+ {
530
+ className: "toolbar-dropdown-item",
531
+ onClick: handleDownloadWithoutAnnotations,
532
+ children: /* @__PURE__ */ jsx2("span", { children: "Download Document Only" })
533
+ }
534
+ ),
535
+ /* @__PURE__ */ jsx2(
536
+ "button",
537
+ {
538
+ className: "toolbar-dropdown-item",
539
+ onClick: handleDownloadWithAnnotations,
540
+ children: /* @__PURE__ */ jsx2("span", { children: "Download with Annotations" })
541
+ }
542
+ )
543
+ ] })
544
+ ] })
545
+ ) : (
546
+ // RENDER SINGLE BUTTON if ONLY ONE is enabled
547
+ (showDownloadOriginal || showDownloadWithAnnotations) && /* @__PURE__ */ jsx2(Tooltip, { title: "Download", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsx2(
548
+ "button",
549
+ {
550
+ className: "toolbar-button",
551
+ onClick: showDownloadOriginal ? handleDownloadWithoutAnnotations : handleDownloadWithAnnotations,
552
+ disabled: disabledDownload,
553
+ children: /* @__PURE__ */ jsx2(DownloadIcon, { fontSize: "small" })
554
+ }
555
+ ) }) })
556
+ ) }),
557
+ showPrint && /* @__PURE__ */ jsx2("div", { className: "toolbar-dropdown-container", ref: printMenuRef, children: showPrintOriginal && showPrintWithAnnotations ? (
558
+ // RENDER DROPDOWN if BOTH are enabled
559
+ /* @__PURE__ */ jsxs(Fragment, { children: [
560
+ /* @__PURE__ */ jsx2(Tooltip, { title: "Print", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsxs(
561
+ "button",
562
+ {
563
+ className: `toolbar-button toolbar-dropdown-button ${isPrintMenuOpen ? "toolbar-button-active" : ""}`,
564
+ onClick: () => setIsPrintMenuOpen(!isPrintMenuOpen),
565
+ disabled: disabledPrint,
566
+ children: [
567
+ /* @__PURE__ */ jsx2(PrintIcon, { fontSize: "small" }),
568
+ /* @__PURE__ */ jsx2(KeyboardArrowDownIcon, { fontSize: "small", style: { marginLeft: -4 } })
569
+ ]
570
+ }
571
+ ) }) }),
572
+ isPrintMenuOpen && /* @__PURE__ */ jsxs("div", { className: "toolbar-dropdown-menu toolbar-dropdown-menu-right", children: [
573
+ /* @__PURE__ */ jsx2(
574
+ "button",
575
+ {
576
+ className: "toolbar-dropdown-item",
577
+ onClick: handlePrintWithoutAnnotations,
578
+ children: /* @__PURE__ */ jsx2("span", { children: "Print Document Only" })
579
+ }
580
+ ),
581
+ /* @__PURE__ */ jsx2(
582
+ "button",
583
+ {
584
+ className: "toolbar-dropdown-item",
585
+ onClick: handlePrintWithAnnotations,
586
+ children: /* @__PURE__ */ jsx2("span", { children: "Print with Annotations" })
587
+ }
588
+ )
589
+ ] })
590
+ ] })
591
+ ) : (
592
+ // RENDER SINGLE BUTTON if ONLY ONE is enabled
593
+ (showPrintOriginal || showPrintWithAnnotations) && /* @__PURE__ */ jsx2(Tooltip, { title: "Print", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsx2(
594
+ "button",
595
+ {
596
+ className: "toolbar-button",
597
+ onClick: showPrintOriginal ? handlePrintWithoutAnnotations : handlePrintWithAnnotations,
598
+ disabled: disabledPrint,
599
+ children: /* @__PURE__ */ jsx2(PrintIcon, { fontSize: "small" })
600
+ }
601
+ ) }) })
602
+ ) }),
603
+ showMetadata && /* @__PURE__ */ jsx2(Tooltip, { title: "Metadata", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsx2(
604
+ "button",
605
+ {
606
+ className: "toolbar-button",
607
+ onClick: onMetadataClick,
608
+ disabled: disabledMetadata,
609
+ children: /* @__PURE__ */ jsx2(DescriptionIcon, { fontSize: "small" })
610
+ }
611
+ ) }) }),
612
+ showProperties && /* @__PURE__ */ jsx2(Tooltip, { title: "Properties", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsx2(
613
+ "button",
614
+ {
615
+ className: "toolbar-button",
616
+ onClick: onPropertiesClick,
617
+ disabled: disabledProperties,
618
+ children: /* @__PURE__ */ jsx2(InfoIcon, { fontSize: "small" })
619
+ }
620
+ ) }) }),
621
+ showTags && /* @__PURE__ */ jsx2(Tooltip, { title: "Tags", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsx2(
622
+ "button",
623
+ {
624
+ className: "toolbar-button",
625
+ onClick: onTagsClick,
626
+ disabled: disabledTags,
627
+ children: /* @__PURE__ */ jsx2(LocalOffer, { fontSize: "small" })
628
+ }
629
+ ) }) }),
630
+ showHistory && /* @__PURE__ */ jsx2(Tooltip, { title: "Version History", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsx2(
631
+ "button",
632
+ {
633
+ className: "toolbar-button",
634
+ onClick: onHistoryClick,
635
+ disabled: disabledHistory,
636
+ children: /* @__PURE__ */ jsx2(HistoryIcon, { fontSize: "small" })
637
+ }
638
+ ) }) })
639
+ ] })
640
+ ] }) })
641
+ ] }) });
642
+ }
643
+ );
644
+ PDFToolbar.displayName = "PDFToolbar";
645
+ var PDFSecondaryToolbar = React2.memo(({
646
+ activeMode,
647
+ showAnnotations,
648
+ isHighlighterActive,
649
+ isStampActive,
650
+ disabledHighlighter,
651
+ disabledStamp,
652
+ disabledSignature,
653
+ disabledNote,
654
+ onHighlighterClick,
655
+ onStampClick,
656
+ onSignatureClick,
657
+ onNoteClick,
658
+ hasUnsavedAnnotations,
659
+ isSavingAnnotations,
660
+ canSaveAnnotations,
661
+ onSaveAnnotations
662
+ }) => {
663
+ if (!showAnnotations) return null;
664
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
665
+ activeMode === "annotate" && /* @__PURE__ */ jsxs("div", { className: "pdf-viewer-secondary-toolbar", children: [
666
+ /* @__PURE__ */ jsx2(Tooltip, { title: "Highlight", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsx2(
667
+ "button",
668
+ {
669
+ className: `toolbar-button ${isHighlighterActive ? "toolbar-button-active" : ""}`,
670
+ onClick: onHighlighterClick,
671
+ disabled: disabledHighlighter,
672
+ children: /* @__PURE__ */ jsx2(HighlightIcon, { fontSize: "small" })
673
+ }
674
+ ) }) }),
675
+ /* @__PURE__ */ jsx2(Tooltip, { title: "Stamp", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsx2(
676
+ "button",
677
+ {
678
+ className: `toolbar-button ${isStampActive ? "toolbar-button-active" : ""}`,
679
+ onClick: onStampClick,
680
+ disabled: disabledStamp,
681
+ children: /* @__PURE__ */ jsx2(ApprovalIcon, { fontSize: "small" })
682
+ }
683
+ ) }) }),
684
+ /* @__PURE__ */ jsx2(Tooltip, { title: "Signature", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsx2(
685
+ "button",
686
+ {
687
+ className: "toolbar-button",
688
+ onClick: onSignatureClick,
689
+ disabled: disabledSignature,
690
+ children: /* @__PURE__ */ jsx2(DrawIcon, { fontSize: "small" })
691
+ }
692
+ ) }) }),
693
+ onNoteClick && /* @__PURE__ */ jsx2(Tooltip, { title: "Sticky Note", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsx2(
694
+ "button",
695
+ {
696
+ className: "toolbar-button",
697
+ onClick: onNoteClick,
698
+ disabled: disabledNote,
699
+ children: /* @__PURE__ */ jsx2(StickyNote2Icon, { fontSize: "small" })
700
+ }
701
+ ) }) }),
702
+ hasUnsavedAnnotations && canSaveAnnotations !== false && onSaveAnnotations && /* @__PURE__ */ jsxs(Fragment, { children: [
703
+ /* @__PURE__ */ jsx2("div", { style: { width: 1, height: 24, backgroundColor: "#e5e7eb", margin: "0 8px" } }),
704
+ /* @__PURE__ */ jsx2(Tooltip, { title: "Save Annotations", children: /* @__PURE__ */ jsx2("span", { children: /* @__PURE__ */ jsxs(
705
+ "button",
706
+ {
707
+ className: "toolbar-button",
708
+ onClick: onSaveAnnotations,
709
+ disabled: isSavingAnnotations,
710
+ style: {
711
+ color: hasUnsavedAnnotations ? "#2563eb" : "inherit",
712
+ padding: "6px 16px",
713
+ border: hasUnsavedAnnotations ? "1px solid #2563eb" : "1px solid transparent",
714
+ borderRadius: "6px",
715
+ display: "flex",
716
+ alignItems: "center",
717
+ gap: "6px",
718
+ backgroundColor: hasUnsavedAnnotations ? "#eff6ff" : "transparent",
719
+ fontSize: "14px",
720
+ fontWeight: 500,
721
+ width: "auto",
722
+ cursor: isSavingAnnotations ? "not-allowed" : "pointer"
723
+ },
724
+ children: [
725
+ isSavingAnnotations ? /* @__PURE__ */ jsx2("svg", { width: "16", height: "16", viewBox: "0 0 24 24", style: { animation: "spin 1s linear infinite" }, children: /* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "3", fill: "none", strokeDasharray: "31.4", strokeDashoffset: "10" }) }) : /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
726
+ /* @__PURE__ */ jsx2("path", { d: "M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z" }),
727
+ /* @__PURE__ */ jsx2("polyline", { points: "17 21 17 13 7 13 7 21" }),
728
+ /* @__PURE__ */ jsx2("polyline", { points: "7 3 7 8 15 8" })
729
+ ] }),
730
+ /* @__PURE__ */ jsx2("span", { children: isSavingAnnotations ? "Saving..." : "Save" })
731
+ ]
732
+ }
733
+ ) }) })
734
+ ] })
735
+ ] }),
736
+ activeMode === "redact" && /* @__PURE__ */ jsx2("div", { className: "pdf-viewer-secondary-toolbar", children: /* @__PURE__ */ jsx2(Tooltip, { title: "Redact Text", children: /* @__PURE__ */ jsx2("button", { className: "toolbar-button", children: /* @__PURE__ */ jsx2(AutoFixHighIcon, { fontSize: "small" }) }) }) })
737
+ ] });
738
+ });
739
+ PDFSecondaryToolbar.displayName = "PDFSecondaryToolbar";
740
+ PDFToolbar.displayName = "PDFToolbar";
741
+
742
+ // src/components/viewers/pdf/PDFHeader.tsx
743
+ import React3 from "react";
744
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
745
+ var PDFHeader = React3.memo(({ fileName, fileExtension }) => {
746
+ return /* @__PURE__ */ jsxs2("div", { className: "pdf-viewer-header", children: [
747
+ /* @__PURE__ */ jsx3(FileIcon_default, { ext: fileExtension, size: 26 }),
748
+ /* @__PURE__ */ jsx3("div", { className: "header-file-name", title: fileName, children: fileName })
749
+ ] });
750
+ });
751
+ PDFHeader.displayName = "PDFHeader";
752
+
753
+ // src/components/viewers/pdf/SearchSidebar.tsx
754
+ import { useState as useState2, useLayoutEffect, useEffect as useEffect2, useRef as useRef2 } from "react";
755
+ import {
756
+ Box,
757
+ Typography,
758
+ TextField,
759
+ IconButton,
760
+ InputAdornment,
761
+ Divider,
762
+ CircularProgress
763
+ } from "@mui/material";
764
+ import SearchIcon2 from "@mui/icons-material/Search";
765
+ import CloseIcon from "@mui/icons-material/Close";
766
+ import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
767
+ import KeyboardArrowDownIcon2 from "@mui/icons-material/KeyboardArrowDown";
768
+ import ClearIcon from "@mui/icons-material/Clear";
769
+ import FindInPageIcon from "@mui/icons-material/FindInPage";
770
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
771
+ var SearchSidebar = ({
772
+ isOpen,
773
+ onClose,
774
+ onSearch,
775
+ onSearchResultClick,
776
+ onNextResult,
777
+ onPreviousResult,
778
+ currentResultIndex,
779
+ totalResults,
780
+ searchKeyword,
781
+ searchResults = [],
782
+ isSearching = false,
783
+ isSyntheticResults = false
784
+ }) => {
785
+ const [searchTerm, setSearchTerm] = useState2(searchKeyword || "");
786
+ const [hasSearched, setHasSearched] = useState2(false);
787
+ const contentRef = useRef2(null);
788
+ useEffect2(() => {
789
+ if (searchKeyword && searchKeyword !== searchTerm) {
790
+ setSearchTerm(searchKeyword);
791
+ }
792
+ }, [searchKeyword]);
793
+ useLayoutEffect(() => {
794
+ const element = contentRef.current;
795
+ if (!element) return;
796
+ const handleMouseMove = (e) => {
797
+ const rect = element.getBoundingClientRect();
798
+ const distanceFromRight = rect.right - e.clientX;
799
+ const distanceFromBottom = rect.bottom - e.clientY;
800
+ if (distanceFromRight <= 15 || distanceFromBottom <= 15) {
801
+ element.classList.add("scrollbar-hover");
802
+ } else {
803
+ element.classList.remove("scrollbar-hover");
804
+ }
805
+ };
806
+ const handleMouseLeave = () => element.classList.remove("scrollbar-hover");
807
+ element.addEventListener("mousemove", handleMouseMove);
808
+ element.addEventListener("mouseleave", handleMouseLeave);
809
+ return () => {
810
+ element.removeEventListener("mousemove", handleMouseMove);
811
+ element.removeEventListener("mouseleave", handleMouseLeave);
812
+ };
813
+ }, []);
814
+ useLayoutEffect(() => {
815
+ const style = document.createElement("style");
816
+ style.id = "search-sidebar-scrollbar";
817
+ style.textContent = `
818
+ @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+Tamil:wght@400;600&family=Noto+Sans+Devanagari:wght@400;600&display=swap');
819
+
820
+ .search-sidebar-content::-webkit-scrollbar {
821
+ width: 12px;
822
+ height: 12px;
823
+ }
824
+ .search-sidebar-content::-webkit-scrollbar-track {
825
+ background-color: transparent;
826
+ }
827
+ .search-sidebar-content::-webkit-scrollbar-thumb {
828
+ background-color: rgba(128, 128, 128, 0.3);
829
+ border-radius: 8px;
830
+ border: 4px solid transparent;
831
+ background-clip: padding-box;
832
+ transition: all 0.15s ease;
833
+ }
834
+ .search-sidebar-content.scrollbar-hover::-webkit-scrollbar-thumb {
835
+ background-color: rgba(128, 128, 128, 0.5);
836
+ border: 2px solid transparent;
837
+ }
838
+ .search-sidebar-content::-webkit-scrollbar-thumb:active {
839
+ background-color: rgba(25, 118, 210, 0.8);
840
+ border: 1px solid transparent;
841
+ }
842
+
843
+ @media (prefers-color-scheme: dark) {
844
+ .search-sidebar-content::-webkit-scrollbar-thumb {
845
+ background-color: rgba(255, 255, 255, 0.2);
846
+ }
847
+ .search-sidebar-content.scrollbar-hover::-webkit-scrollbar-thumb {
848
+ background-color: rgba(255, 255, 255, 0.35);
849
+ }
850
+ }
851
+
852
+ /* Tamil font support for search results */
853
+ .search-result-text {
854
+ font-family: 'Noto Sans Tamil', 'Noto Sans Devanagari', Arial, sans-serif !important;
855
+ }
856
+ `;
857
+ document.head.appendChild(style);
858
+ return () => {
859
+ const el = document.getElementById("search-sidebar-scrollbar");
860
+ if (el) el.remove();
861
+ };
862
+ }, []);
863
+ useLayoutEffect(() => {
864
+ setSearchTerm(searchKeyword || "");
865
+ if (searchKeyword || searchResults.length > 0) {
866
+ setHasSearched(true);
867
+ }
868
+ }, [searchKeyword, searchResults]);
869
+ const handleSearchSubmit = (e) => {
870
+ if (e) e.preventDefault();
871
+ if (searchTerm.trim()) {
872
+ setHasSearched(true);
873
+ onSearch(searchTerm.trim());
874
+ }
875
+ };
876
+ const handleSearchChange = (e) => {
877
+ const value = e.target.value;
878
+ setSearchTerm(value);
879
+ if (!value.trim()) {
880
+ setHasSearched(false);
881
+ onSearch("");
882
+ }
883
+ };
884
+ const handleClearSearch = () => {
885
+ setSearchTerm("");
886
+ setHasSearched(false);
887
+ onSearch("");
888
+ };
889
+ const resultsByPage = searchResults.reduce((acc, result) => {
890
+ if (!acc[result.pageNumber]) {
891
+ acc[result.pageNumber] = [];
892
+ }
893
+ acc[result.pageNumber].push(result);
894
+ return acc;
895
+ }, {});
896
+ const highlightText = (text, keyword) => {
897
+ if (!keyword) return text;
898
+ const textString = typeof text === "string" ? text : String(text || "");
899
+ if (!textString) return text;
900
+ try {
901
+ const escapedKeyword = keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
902
+ const regex = new RegExp(`(${escapedKeyword})`, "gi");
903
+ const parts = textString.split(regex);
904
+ return parts.map(
905
+ (part, index) => regex.test(part) ? /* @__PURE__ */ jsx4(
906
+ Box,
907
+ {
908
+ component: "span",
909
+ sx: {
910
+ color: "primary.main",
911
+ fontWeight: 600,
912
+ fontSize: "inherit"
913
+ },
914
+ children: part
915
+ },
916
+ index
917
+ ) : part
918
+ );
919
+ } catch (error) {
920
+ return textString;
921
+ }
922
+ };
923
+ if (!isOpen) return null;
924
+ return /* @__PURE__ */ jsxs3(
925
+ Box,
926
+ {
927
+ sx: {
928
+ display: "flex",
929
+ flexDirection: "column",
930
+ height: "100%",
931
+ width: "320px",
932
+ backgroundColor: "background.paper",
933
+ borderLeft: "1px solid",
934
+ borderColor: "divider",
935
+ overflow: "hidden"
936
+ },
937
+ children: [
938
+ /* @__PURE__ */ jsxs3(Box, { sx: { px: 3, py: 2.5, backgroundColor: "background.default" }, children: [
939
+ /* @__PURE__ */ jsxs3(Box, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 2 }, children: [
940
+ /* @__PURE__ */ jsx4(Typography, { variant: "h6", sx: { fontSize: "1.125rem", fontWeight: 600, color: "text.primary" }, children: "Search" }),
941
+ /* @__PURE__ */ jsx4(
942
+ IconButton,
943
+ {
944
+ size: "small",
945
+ onClick: onClose,
946
+ sx: {
947
+ color: "text.secondary",
948
+ padding: "6px"
949
+ },
950
+ children: /* @__PURE__ */ jsx4(CloseIcon, { fontSize: "small" })
951
+ }
952
+ )
953
+ ] }),
954
+ /* @__PURE__ */ jsx4("form", { onSubmit: handleSearchSubmit, children: /* @__PURE__ */ jsx4(
955
+ TextField,
956
+ {
957
+ fullWidth: true,
958
+ size: "medium",
959
+ placeholder: "Search in document...",
960
+ value: searchTerm,
961
+ onChange: handleSearchChange,
962
+ autoComplete: "off",
963
+ InputProps: {
964
+ startAdornment: /* @__PURE__ */ jsx4(InputAdornment, { position: "start", children: /* @__PURE__ */ jsx4(SearchIcon2, { sx: { color: "text.disabled", fontSize: 20 } }) }),
965
+ endAdornment: searchTerm && /* @__PURE__ */ jsx4(InputAdornment, { position: "end", children: /* @__PURE__ */ jsx4(
966
+ IconButton,
967
+ {
968
+ size: "small",
969
+ onClick: handleClearSearch,
970
+ sx: {
971
+ color: "text.secondary",
972
+ padding: "4px",
973
+ "&:hover": {
974
+ backgroundColor: "action.hover"
975
+ }
976
+ },
977
+ children: /* @__PURE__ */ jsx4(ClearIcon, { sx: { fontSize: 18 } })
978
+ }
979
+ ) })
980
+ },
981
+ sx: {
982
+ "& .MuiOutlinedInput-root": {
983
+ fontSize: "0.9375rem",
984
+ backgroundColor: "background.paper",
985
+ borderRadius: "8px",
986
+ "& fieldset": {
987
+ borderColor: "divider"
988
+ },
989
+ "&.Mui-focused fieldset": {
990
+ borderColor: "primary.main",
991
+ borderWidth: "2px"
992
+ }
993
+ },
994
+ "& .MuiInputBase-input": {
995
+ padding: "10px 14px"
996
+ }
997
+ }
998
+ }
999
+ ) }),
1000
+ totalResults > 0 && /* @__PURE__ */ jsxs3(
1001
+ Box,
1002
+ {
1003
+ sx: {
1004
+ display: "flex",
1005
+ alignItems: "center",
1006
+ justifyContent: "space-between",
1007
+ mt: 2,
1008
+ pt: 2,
1009
+ borderTop: "1px solid",
1010
+ borderColor: "divider"
1011
+ },
1012
+ children: [
1013
+ /* @__PURE__ */ jsxs3(Typography, { variant: "body2", sx: { color: "text.secondary", fontSize: "0.875rem", fontWeight: 500 }, children: [
1014
+ currentResultIndex + 1,
1015
+ " of ",
1016
+ totalResults,
1017
+ " results"
1018
+ ] }),
1019
+ /* @__PURE__ */ jsxs3(Box, { sx: { display: "flex", alignItems: "center", gap: 0.5 }, children: [
1020
+ /* @__PURE__ */ jsx4(
1021
+ IconButton,
1022
+ {
1023
+ size: "small",
1024
+ onClick: onPreviousResult,
1025
+ disabled: currentResultIndex <= 0,
1026
+ sx: {
1027
+ color: currentResultIndex <= 0 ? "text.disabled" : "primary.main",
1028
+ padding: "6px",
1029
+ borderRadius: "6px",
1030
+ border: "1px solid",
1031
+ borderColor: currentResultIndex <= 0 ? "divider" : "primary.main"
1032
+ },
1033
+ children: /* @__PURE__ */ jsx4(KeyboardArrowUpIcon, { sx: { fontSize: 20 } })
1034
+ }
1035
+ ),
1036
+ /* @__PURE__ */ jsx4(
1037
+ IconButton,
1038
+ {
1039
+ size: "small",
1040
+ onClick: onNextResult,
1041
+ disabled: currentResultIndex >= totalResults - 1,
1042
+ sx: {
1043
+ color: currentResultIndex >= totalResults - 1 ? "text.disabled" : "primary.main",
1044
+ padding: "6px",
1045
+ borderRadius: "6px",
1046
+ border: "1px solid",
1047
+ borderColor: currentResultIndex >= totalResults - 1 ? "divider" : "primary.main"
1048
+ },
1049
+ children: /* @__PURE__ */ jsx4(KeyboardArrowDownIcon2, { sx: { fontSize: 20 } })
1050
+ }
1051
+ )
1052
+ ] })
1053
+ ]
1054
+ }
1055
+ )
1056
+ ] }),
1057
+ /* @__PURE__ */ jsx4(Divider, {}),
1058
+ /* @__PURE__ */ jsxs3(Box, { ref: contentRef, className: "search-sidebar-content", sx: {
1059
+ flex: 1,
1060
+ overflow: "auto",
1061
+ backgroundColor: "background.default"
1062
+ }, children: [
1063
+ !searchTerm && !hasSearched && /* @__PURE__ */ jsxs3(Box, { sx: { p: 4, textAlign: "center", mt: 6 }, children: [
1064
+ /* @__PURE__ */ jsx4(
1065
+ Box,
1066
+ {
1067
+ sx: {
1068
+ width: 80,
1069
+ height: 80,
1070
+ borderRadius: "50%",
1071
+ backgroundColor: "action.hover",
1072
+ display: "flex",
1073
+ alignItems: "center",
1074
+ justifyContent: "center",
1075
+ margin: "0 auto",
1076
+ mb: 3
1077
+ },
1078
+ children: /* @__PURE__ */ jsx4(SearchIcon2, { sx: { fontSize: 40, color: "text.disabled" } })
1079
+ }
1080
+ ),
1081
+ /* @__PURE__ */ jsx4(Typography, { variant: "body1", sx: { color: "text.primary", fontWeight: 500, mb: 1 }, children: "Search in Document" }),
1082
+ /* @__PURE__ */ jsx4(Typography, { variant: "body2", sx: { color: "text.secondary", lineHeight: 1.6 }, children: "Enter keywords to find text within the PDF document" })
1083
+ ] }),
1084
+ searchTerm && !hasSearched && !isSearching && /* @__PURE__ */ jsxs3(Box, { sx: { p: 4, textAlign: "center", mt: 6 }, children: [
1085
+ /* @__PURE__ */ jsx4(
1086
+ Box,
1087
+ {
1088
+ sx: {
1089
+ width: 80,
1090
+ height: 80,
1091
+ borderRadius: "50%",
1092
+ backgroundColor: "primary.light",
1093
+ display: "flex",
1094
+ alignItems: "center",
1095
+ justifyContent: "center",
1096
+ margin: "0 auto",
1097
+ mb: 3,
1098
+ opacity: 0.2
1099
+ },
1100
+ children: /* @__PURE__ */ jsx4(FindInPageIcon, { sx: { fontSize: 40, color: "primary.main" } })
1101
+ }
1102
+ ),
1103
+ /* @__PURE__ */ jsx4(Typography, { variant: "body1", sx: { color: "text.primary", fontWeight: 500, mb: 1 }, children: "Ready to Search" }),
1104
+ /* @__PURE__ */ jsx4(Typography, { variant: "body2", sx: { color: "text.secondary", mb: 2, lineHeight: 1.6 }, children: "Press Enter to find" }),
1105
+ /* @__PURE__ */ jsxs3(
1106
+ Typography,
1107
+ {
1108
+ variant: "body2",
1109
+ sx: {
1110
+ color: "white",
1111
+ fontWeight: 600,
1112
+ backgroundColor: (theme) => theme.palette.mode === "dark" ? "rgba(144, 202, 249, 0.16)" : "primary.light",
1113
+ padding: "6px 16px",
1114
+ borderRadius: "16px",
1115
+ display: "inline-block",
1116
+ opacity: 0.9
1117
+ },
1118
+ children: [
1119
+ '"',
1120
+ searchTerm,
1121
+ '"'
1122
+ ]
1123
+ }
1124
+ )
1125
+ ] }),
1126
+ isSearching && /* @__PURE__ */ jsxs3(Box, { sx: { p: 4, textAlign: "center", mt: 6 }, children: [
1127
+ /* @__PURE__ */ jsx4(
1128
+ Box,
1129
+ {
1130
+ sx: {
1131
+ display: "flex",
1132
+ alignItems: "center",
1133
+ justifyContent: "center",
1134
+ margin: "0 auto",
1135
+ mb: 3
1136
+ },
1137
+ children: /* @__PURE__ */ jsx4(CircularProgress, { size: 60, thickness: 4 })
1138
+ }
1139
+ ),
1140
+ /* @__PURE__ */ jsx4(Typography, { variant: "body1", sx: { color: "text.primary", fontWeight: 500, mb: 1 }, children: "Searching..." }),
1141
+ /* @__PURE__ */ jsxs3(Typography, { variant: "body2", sx: { color: "text.secondary", lineHeight: 1.6 }, children: [
1142
+ 'Finding matches for "',
1143
+ searchTerm,
1144
+ '"'
1145
+ ] })
1146
+ ] }),
1147
+ hasSearched && totalResults === 0 && !isSearching && /* @__PURE__ */ jsxs3(Box, { sx: { p: 4, textAlign: "center", mt: 6 }, children: [
1148
+ /* @__PURE__ */ jsx4(
1149
+ Box,
1150
+ {
1151
+ sx: {
1152
+ width: 80,
1153
+ height: 80,
1154
+ borderRadius: "50%",
1155
+ backgroundColor: (theme) => theme.palette.mode === "dark" ? "rgba(255, 152, 0, 0.12)" : "warning.light",
1156
+ display: "flex",
1157
+ alignItems: "center",
1158
+ justifyContent: "center",
1159
+ margin: "0 auto",
1160
+ mb: 3,
1161
+ opacity: 0.6
1162
+ },
1163
+ children: /* @__PURE__ */ jsx4(SearchIcon2, { sx: { fontSize: 40, color: "warning.main" } })
1164
+ }
1165
+ ),
1166
+ /* @__PURE__ */ jsx4(Typography, { variant: "body1", sx: { color: "text.primary", fontWeight: 500, mb: 1 }, children: "No Results Found" }),
1167
+ /* @__PURE__ */ jsxs3(Typography, { variant: "body2", sx: { color: "text.secondary", lineHeight: 1.6 }, children: [
1168
+ "No matches found for ",
1169
+ /* @__PURE__ */ jsxs3("strong", { children: [
1170
+ '"',
1171
+ searchTerm,
1172
+ '"'
1173
+ ] })
1174
+ ] })
1175
+ ] }),
1176
+ totalResults > 0 && /* @__PURE__ */ jsx4(Box, { sx: { p: 2 }, children: Object.keys(resultsByPage).sort((a, b) => parseInt(a) - parseInt(b)).map((pageNum) => {
1177
+ const pageNumber = parseInt(pageNum);
1178
+ const pageResults = resultsByPage[pageNumber];
1179
+ return /* @__PURE__ */ jsxs3(Box, { sx: { mb: 3 }, children: [
1180
+ /* @__PURE__ */ jsxs3(
1181
+ Typography,
1182
+ {
1183
+ variant: "subtitle2",
1184
+ sx: {
1185
+ color: "text.secondary",
1186
+ mb: 1.5,
1187
+ px: 1,
1188
+ fontSize: "0.8125rem",
1189
+ fontWeight: 600,
1190
+ textTransform: "uppercase",
1191
+ letterSpacing: "0.5px"
1192
+ },
1193
+ children: [
1194
+ "Page ",
1195
+ pageNumber
1196
+ ]
1197
+ }
1198
+ ),
1199
+ pageResults.map((result, index) => /* @__PURE__ */ jsx4(
1200
+ Box,
1201
+ {
1202
+ onClick: () => onSearchResultClick(result.pageNumber, result.index),
1203
+ sx: {
1204
+ p: 2,
1205
+ mx: 1,
1206
+ mb: 1.5,
1207
+ borderRadius: "8px",
1208
+ border: "2px solid",
1209
+ borderColor: result.index === currentResultIndex ? "primary.main" : "divider",
1210
+ backgroundColor: "background.paper",
1211
+ cursor: "pointer",
1212
+ transition: "all 0.2s ease",
1213
+ boxShadow: (theme) => theme.palette.mode === "dark" ? "0 1px 3px rgba(0, 0, 0, 0.3)" : "0 1px 3px rgba(0, 0, 0, 0.05)",
1214
+ "&:hover": {
1215
+ borderColor: "primary.main",
1216
+ boxShadow: (theme) => theme.palette.mode === "dark" ? "0 2px 8px rgba(255, 255, 255, 0.15)" : "0 2px 8px rgba(0, 0, 0, 0.1)",
1217
+ transform: "translateY(-1px)"
1218
+ }
1219
+ },
1220
+ children: /* @__PURE__ */ jsx4(
1221
+ Typography,
1222
+ {
1223
+ variant: "body2",
1224
+ className: "search-result-text",
1225
+ sx: {
1226
+ fontSize: "0.875rem",
1227
+ lineHeight: 1.6,
1228
+ color: result.index === currentResultIndex ? "text.primary" : "text.secondary"
1229
+ },
1230
+ children: highlightText(result.context, searchTerm)
1231
+ }
1232
+ )
1233
+ },
1234
+ index
1235
+ ))
1236
+ ] }, pageNumber);
1237
+ }) })
1238
+ ] })
1239
+ ]
1240
+ }
1241
+ );
1242
+ };
1243
+
1244
+ // src/components/viewers/pdf/PasswordDialog.tsx
1245
+ import { useState as useState3, useEffect as useEffect3 } from "react";
1246
+ import {
1247
+ Dialog,
1248
+ DialogTitle,
1249
+ DialogContent,
1250
+ DialogActions,
1251
+ TextField as TextField2,
1252
+ Button,
1253
+ Typography as Typography2,
1254
+ InputAdornment as InputAdornment2,
1255
+ Box as Box2,
1256
+ Alert,
1257
+ IconButton as IconButton2,
1258
+ CircularProgress as CircularProgress2
1259
+ } from "@mui/material";
1260
+ import LockIcon from "@mui/icons-material/Lock";
1261
+ import VisibilityIcon from "@mui/icons-material/Visibility";
1262
+ import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
1263
+ import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1264
+ var PasswordDialog = ({
1265
+ open,
1266
+ fileName,
1267
+ onSubmit,
1268
+ onCancel,
1269
+ error,
1270
+ isLoading = false
1271
+ }) => {
1272
+ const [password, setPassword] = useState3("");
1273
+ const [showPassword, setShowPassword] = useState3(false);
1274
+ useEffect3(() => {
1275
+ if (open && !isLoading) {
1276
+ if (error) {
1277
+ setPassword("");
1278
+ }
1279
+ }
1280
+ }, [open, error, isLoading]);
1281
+ useEffect3(() => {
1282
+ if (open) {
1283
+ setShowPassword(false);
1284
+ if (!error) {
1285
+ setPassword("");
1286
+ }
1287
+ }
1288
+ }, [open]);
1289
+ const handleSubmit = (e) => {
1290
+ e.preventDefault();
1291
+ if (password.trim() && !isLoading) {
1292
+ onSubmit(password);
1293
+ }
1294
+ };
1295
+ const handleTogglePasswordVisibility = () => {
1296
+ setShowPassword(!showPassword);
1297
+ };
1298
+ const handleKeyPress = (e) => {
1299
+ if (e.key === "Enter" && password.trim() && !isLoading) {
1300
+ handleSubmit(e);
1301
+ }
1302
+ };
1303
+ return /* @__PURE__ */ jsxs4(
1304
+ Dialog,
1305
+ {
1306
+ open,
1307
+ disableEscapeKeyDown: true,
1308
+ onClose: (event, reason) => {
1309
+ if (reason === "backdropClick") return;
1310
+ },
1311
+ maxWidth: "sm",
1312
+ fullWidth: true,
1313
+ slotProps: {
1314
+ backdrop: {
1315
+ sx: {
1316
+ backdropFilter: "blur(8px)",
1317
+ backgroundColor: "rgba(0, 0, 0, 0.6)"
1318
+ }
1319
+ }
1320
+ },
1321
+ PaperProps: {
1322
+ sx: {
1323
+ borderRadius: 2
1324
+ }
1325
+ },
1326
+ children: [
1327
+ /* @__PURE__ */ jsx5(DialogTitle, { sx: { pb: 1 }, children: /* @__PURE__ */ jsxs4(Box2, { sx: { display: "flex", alignItems: "center", gap: 1.5 }, children: [
1328
+ /* @__PURE__ */ jsx5(
1329
+ Box2,
1330
+ {
1331
+ sx: {
1332
+ width: 40,
1333
+ height: 40,
1334
+ borderRadius: "50%",
1335
+ backgroundColor: "primary.light",
1336
+ display: "flex",
1337
+ alignItems: "center",
1338
+ justifyContent: "center",
1339
+ opacity: 0.9
1340
+ },
1341
+ children: /* @__PURE__ */ jsx5(LockIcon, { sx: { color: "white", fontSize: 20 } })
1342
+ }
1343
+ ),
1344
+ /* @__PURE__ */ jsx5(Typography2, { variant: "h6", component: "div", sx: { fontWeight: 600 }, children: "Password Protected" })
1345
+ ] }) }),
1346
+ /* @__PURE__ */ jsxs4(DialogContent, { sx: { pt: 2 }, children: [
1347
+ /* @__PURE__ */ jsxs4(Typography2, { variant: "body2", sx: { color: "text.secondary", mb: 3 }, children: [
1348
+ "This PDF is password protected. Please enter the password to view",
1349
+ " ",
1350
+ fileName && /* @__PURE__ */ jsxs4("strong", { children: [
1351
+ '"',
1352
+ fileName,
1353
+ '"'
1354
+ ] })
1355
+ ] }),
1356
+ error && /* @__PURE__ */ jsx5(Alert, { severity: "error", sx: { mb: 2 }, children: error }),
1357
+ /* @__PURE__ */ jsx5("form", { onSubmit: handleSubmit, children: /* @__PURE__ */ jsx5(
1358
+ TextField2,
1359
+ {
1360
+ fullWidth: true,
1361
+ autoFocus: true,
1362
+ type: showPassword ? "text" : "password",
1363
+ label: "Password",
1364
+ placeholder: "Enter password",
1365
+ value: password,
1366
+ onChange: (e) => setPassword(e.target.value),
1367
+ onKeyPress: handleKeyPress,
1368
+ error: Boolean(error),
1369
+ disabled: isLoading,
1370
+ InputProps: {
1371
+ endAdornment: /* @__PURE__ */ jsx5(InputAdornment2, { position: "end", children: /* @__PURE__ */ jsx5(
1372
+ IconButton2,
1373
+ {
1374
+ onClick: handleTogglePasswordVisibility,
1375
+ edge: "end",
1376
+ size: "small",
1377
+ "aria-label": showPassword ? "Hide password" : "Show password",
1378
+ disabled: isLoading,
1379
+ children: showPassword ? /* @__PURE__ */ jsx5(VisibilityOffIcon, {}) : /* @__PURE__ */ jsx5(VisibilityIcon, {})
1380
+ }
1381
+ ) })
1382
+ },
1383
+ sx: {
1384
+ "& .MuiOutlinedInput-root": {
1385
+ borderRadius: 2
1386
+ }
1387
+ }
1388
+ }
1389
+ ) })
1390
+ ] }),
1391
+ /* @__PURE__ */ jsx5(DialogActions, { sx: { px: 3, pb: 3, pt: 2 }, children: /* @__PURE__ */ jsx5(
1392
+ Button,
1393
+ {
1394
+ onClick: handleSubmit,
1395
+ variant: "contained",
1396
+ disabled: !password.trim() || isLoading,
1397
+ sx: {
1398
+ borderRadius: 2,
1399
+ textTransform: "none",
1400
+ px: 3,
1401
+ boxShadow: 2,
1402
+ minWidth: 120
1403
+ },
1404
+ children: isLoading ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
1405
+ /* @__PURE__ */ jsx5(CircularProgress2, { size: 16, color: "inherit", sx: { mr: 1 } }),
1406
+ "Verifying..."
1407
+ ] }) : "Unlock PDF"
1408
+ }
1409
+ ) })
1410
+ ]
1411
+ }
1412
+ );
1413
+ };
1414
+
1415
+ // src/components/viewers/PDFViewer.tsx
1416
+ import { ScrollStrategy as ScrollStrategy2, PdfThumbnailSidebar } from "@cannymindstech/pdf-viewer";
1417
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1418
+ var PDFViewerContent = forwardRef(
1419
+ (props, ref) => {
1420
+ const {
1421
+ file,
1422
+ onLoad,
1423
+ onError,
1424
+ fileName,
1425
+ showPageCount = true,
1426
+ showPageNavigation = true,
1427
+ showZoomControls = true,
1428
+ showRotation = true,
1429
+ showDownload = true,
1430
+ showPrint = true,
1431
+ showSearch = true,
1432
+ showMetadata = true,
1433
+ showProperties = true,
1434
+ showTags = true,
1435
+ showHistory = true,
1436
+ onMetadataClick,
1437
+ onPropertiesClick,
1438
+ onTagsClick,
1439
+ onHistoryClick,
1440
+ onDownloadClick,
1441
+ onDownloadWithAnnotations,
1442
+ onDownloadWithoutAnnotations,
1443
+ onPrintClick,
1444
+ onPrintWithAnnotations,
1445
+ onPrintWithoutAnnotations,
1446
+ initialSearchText,
1447
+ initialSearchPages,
1448
+ showAnnotations,
1449
+ userDetails,
1450
+ annotationSelectionMenu,
1451
+ isHighlighterActive,
1452
+ isStampActive,
1453
+ onHighlighterClick,
1454
+ onStampClick,
1455
+ onSignatureClick,
1456
+ onNoteClick,
1457
+ isAnnotationForeign,
1458
+ onAnnotationNoteClick,
1459
+ isAnnotationInteractive,
1460
+ // New granular toolbar props
1461
+ showAnnotate,
1462
+ disabledAnnotate,
1463
+ showPrintOriginal,
1464
+ showPrintWithAnnotations,
1465
+ showDownloadOriginal,
1466
+ showDownloadWithAnnotations,
1467
+ // Annotation save props
1468
+ hasUnsavedAnnotations,
1469
+ isSavingAnnotations,
1470
+ canSaveAnnotations,
1471
+ onSaveAnnotations,
1472
+ loading,
1473
+ themeMode = "light"
1474
+ } = props;
1475
+ const [pdfBuffer, setPdfBuffer] = useState4(null);
1476
+ const [state, setState] = useState4("idle");
1477
+ const [error, setError] = useState4(null);
1478
+ const pdfViewerRef = useRef3(null);
1479
+ const [isInternalReady, setIsInternalReady] = useState4(false);
1480
+ const [internalHighlighterActive, setInternalHighlighterActive] = useState4(false);
1481
+ const [internalStampActive, setInternalStampActive] = useState4(false);
1482
+ const highlighterActive = isHighlighterActive !== void 0 ? isHighlighterActive : internalHighlighterActive;
1483
+ const stampActive = isStampActive !== void 0 ? isStampActive : internalStampActive;
1484
+ const resolvedFileName = useMemo(() => {
1485
+ if (fileName) return fileName;
1486
+ if (file instanceof File) return file.name;
1487
+ if (typeof file === "string") {
1488
+ const urlParts = file.split("/");
1489
+ return urlParts[urlParts.length - 1] || "document.pdf";
1490
+ }
1491
+ return "document.pdf";
1492
+ }, [file, fileName]);
1493
+ const fileExtension = useMemo(
1494
+ () => getFileExtension(resolvedFileName),
1495
+ [resolvedFileName]
1496
+ );
1497
+ const [currentPage, setCurrentPage] = useState4(1);
1498
+ const [totalPages, setTotalPages] = useState4(0);
1499
+ const [zoom, setZoom] = useState4(122);
1500
+ const [searchQuery, setSearchQuery] = useState4("");
1501
+ const [isSearching, setIsSearching] = useState4(false);
1502
+ const [pdfContainer, setPdfContainer] = useState4(null);
1503
+ const [isSidebarOpen, setIsSidebarOpen] = useState4(false);
1504
+ const [searchResults, setSearchResults] = useState4([]);
1505
+ const [currentSearchResultIndex, setCurrentSearchResultIndex] = useState4(0);
1506
+ const [totalSearchResults, setTotalSearchResults] = useState4(0);
1507
+ const [autoExecuteSearch, setAutoExecuteSearch] = useState4(
1508
+ !!initialSearchText
1509
+ );
1510
+ const [isFullScreen, setIsFullScreen] = useState4(false);
1511
+ const [twoPageMode, setTwoPageMode] = useState4(false);
1512
+ const [scrollStrategy, setScrollStrategy] = useState4(ScrollStrategy2.Vertical);
1513
+ const [showThumbnails, setShowThumbnails] = useState4(true);
1514
+ const [activeMode, setActiveMode] = useState4("view");
1515
+ const containerRef = useRef3(null);
1516
+ const [isPasswordDialogOpen, setIsPasswordDialogOpen] = useState4(false);
1517
+ const [passwordError, setPasswordError] = useState4("");
1518
+ const [isVerifyingPassword, setIsVerifyingPassword] = useState4(false);
1519
+ const [passwordResolve, setPasswordResolve] = useState4(null);
1520
+ const passwordTimeoutRef = useRef3(null);
1521
+ const hasExecutedInitialSearch = useRef3(false);
1522
+ const handleToggleFullScreen = useCallback(() => {
1523
+ if (!isFullScreen && containerRef.current?.requestFullscreen) {
1524
+ containerRef.current.requestFullscreen();
1525
+ setIsFullScreen(true);
1526
+ } else if (isFullScreen && document.exitFullscreen) {
1527
+ document.exitFullscreen();
1528
+ setIsFullScreen(false);
1529
+ }
1530
+ }, [isFullScreen]);
1531
+ useEffect4(() => {
1532
+ const handleFullscreenChange = () => {
1533
+ const isCurrentlyFullscreen = !!document.fullscreenElement;
1534
+ setIsFullScreen(isCurrentlyFullscreen);
1535
+ };
1536
+ document.addEventListener("fullscreenchange", handleFullscreenChange);
1537
+ return () => {
1538
+ document.removeEventListener("fullscreenchange", handleFullscreenChange);
1539
+ };
1540
+ }, []);
1541
+ const handleSidebarClose = useCallback(() => {
1542
+ setIsSidebarOpen(false);
1543
+ setSearchQuery("");
1544
+ setSearchResults([]);
1545
+ setTotalSearchResults(0);
1546
+ setCurrentSearchResultIndex(0);
1547
+ pdfViewerRef.current?.search.stopSearch();
1548
+ }, []);
1549
+ const toolbar = mergeToolbarConfig({
1550
+ showDownload,
1551
+ showPrint,
1552
+ showMetadata,
1553
+ showProperties,
1554
+ showTags,
1555
+ showHistory,
1556
+ showRotation,
1557
+ onDownloadClick,
1558
+ onPrintClick,
1559
+ onMetadataClick,
1560
+ onPropertiesClick,
1561
+ onTagsClick,
1562
+ onHistoryClick,
1563
+ toolbarActions: props.toolbarActions
1564
+ });
1565
+ const toolbarHandlers = useMemo(
1566
+ () => ({
1567
+ handleZoomIn: () => {
1568
+ pdfViewerRef.current?.zoom.zoomIn();
1569
+ requestAnimationFrame(() => {
1570
+ const zoomValue = pdfViewerRef.current?.zoom.getZoom();
1571
+ if (typeof zoomValue === "number") {
1572
+ setZoom(Math.round(zoomValue * 100));
1573
+ }
1574
+ });
1575
+ },
1576
+ handleZoomOut: () => {
1577
+ pdfViewerRef.current?.zoom.zoomOut();
1578
+ requestAnimationFrame(() => {
1579
+ const zoomValue = pdfViewerRef.current?.zoom.getZoom();
1580
+ if (typeof zoomValue === "number") {
1581
+ setZoom(Math.round(zoomValue * 100));
1582
+ }
1583
+ });
1584
+ },
1585
+ handleFitToWidth: () => {
1586
+ pdfViewerRef.current?.zoom.fitToWidth();
1587
+ requestAnimationFrame(() => {
1588
+ const zoomValue = pdfViewerRef.current?.zoom.getZoom();
1589
+ if (typeof zoomValue === "number") {
1590
+ setZoom(Math.round(zoomValue * 100));
1591
+ }
1592
+ });
1593
+ },
1594
+ handleFitToPage: () => {
1595
+ pdfViewerRef.current?.zoom.fitToPage();
1596
+ requestAnimationFrame(() => {
1597
+ const zoomValue = pdfViewerRef.current?.zoom.getZoom();
1598
+ if (typeof zoomValue === "number") {
1599
+ setZoom(Math.round(zoomValue * 100));
1600
+ }
1601
+ });
1602
+ },
1603
+ handlePreviousPage: () => {
1604
+ pdfViewerRef.current?.navigation.previousPage();
1605
+ requestAnimationFrame(() => {
1606
+ const current = pdfViewerRef.current?.navigation.getCurrentPage() || 1;
1607
+ setCurrentPage(current);
1608
+ });
1609
+ },
1610
+ handleNextPage: () => {
1611
+ pdfViewerRef.current?.navigation.nextPage();
1612
+ requestAnimationFrame(() => {
1613
+ const current = pdfViewerRef.current?.navigation.getCurrentPage() || 1;
1614
+ setCurrentPage(current);
1615
+ });
1616
+ },
1617
+ handleFirstPage: () => {
1618
+ pdfViewerRef.current?.navigation.goToFirstPage();
1619
+ requestAnimationFrame(() => {
1620
+ const current = pdfViewerRef.current?.navigation.getCurrentPage() || 1;
1621
+ setCurrentPage(current);
1622
+ });
1623
+ },
1624
+ handleLastPage: () => {
1625
+ pdfViewerRef.current?.navigation.goToLastPage();
1626
+ requestAnimationFrame(() => {
1627
+ const current = pdfViewerRef.current?.navigation.getCurrentPage() || 1;
1628
+ setCurrentPage(current);
1629
+ });
1630
+ },
1631
+ toggleSidebar: () => {
1632
+ if (isSidebarOpen) {
1633
+ handleSidebarClose();
1634
+ } else {
1635
+ setIsSidebarOpen(true);
1636
+ }
1637
+ },
1638
+ handlePageInput: (e) => {
1639
+ const value = e.target.value;
1640
+ if (/^\d*$/.test(value)) {
1641
+ return;
1642
+ }
1643
+ const page = parseInt(value, 10);
1644
+ if (!isNaN(page) && page >= 1 && (totalPages === 0 || page <= totalPages)) {
1645
+ pdfViewerRef.current?.navigation.goToPage(page);
1646
+ setCurrentPage(page);
1647
+ }
1648
+ },
1649
+ handlePageInputKeyPress: (e) => {
1650
+ if (e.key === "Enter") {
1651
+ const value = e.target.value;
1652
+ const page = parseInt(value, 10);
1653
+ if (!isNaN(page) && page >= 1 && (totalPages === 0 || page <= totalPages)) {
1654
+ pdfViewerRef.current?.navigation.goToPage(page);
1655
+ setCurrentPage(page);
1656
+ }
1657
+ }
1658
+ },
1659
+ handleRotateLeft: () => {
1660
+ pdfViewerRef.current?.rotate?.rotateBackward();
1661
+ },
1662
+ handleRotateRight: () => {
1663
+ pdfViewerRef.current?.rotate?.rotateForward();
1664
+ },
1665
+ handlePrint: () => {
1666
+ pdfViewerRef.current?.print?.print();
1667
+ },
1668
+ handlePrintWithAnnotations: async () => {
1669
+ if (onPrintWithAnnotations) {
1670
+ await onPrintWithAnnotations();
1671
+ } else {
1672
+ await pdfViewerRef.current?.print?.printWithAnnotations?.();
1673
+ }
1674
+ },
1675
+ handlePrintWithoutAnnotations: async () => {
1676
+ if (onPrintWithoutAnnotations) {
1677
+ await onPrintWithoutAnnotations();
1678
+ } else {
1679
+ await pdfViewerRef.current?.print?.printWithoutAnnotations?.();
1680
+ }
1681
+ },
1682
+ handleDownloadWithAnnotations: async () => {
1683
+ if (onDownloadWithAnnotations) {
1684
+ onDownloadWithAnnotations();
1685
+ } else {
1686
+ await pdfViewerRef.current?.download?.downloadWithAnnotations?.(resolvedFileName);
1687
+ }
1688
+ },
1689
+ handleDownloadWithoutAnnotations: async () => {
1690
+ if (onDownloadWithoutAnnotations) {
1691
+ onDownloadWithoutAnnotations();
1692
+ } else {
1693
+ await pdfViewerRef.current?.download?.downloadWithoutAnnotations?.(resolvedFileName);
1694
+ }
1695
+ },
1696
+ handleHighlighterClick: () => {
1697
+ if (highlighterActive) {
1698
+ pdfViewerRef.current?.annotation?.deactivateHighlighter();
1699
+ setInternalHighlighterActive(false);
1700
+ } else {
1701
+ if (stampActive) {
1702
+ pdfViewerRef.current?.annotation?.deactivateStamp();
1703
+ setInternalStampActive(false);
1704
+ }
1705
+ pdfViewerRef.current?.annotation?.activateHighlighter();
1706
+ setInternalHighlighterActive(true);
1707
+ }
1708
+ },
1709
+ handleStampClick: () => {
1710
+ if (stampActive) {
1711
+ pdfViewerRef.current?.annotation?.deactivateStamp();
1712
+ setInternalStampActive(false);
1713
+ } else {
1714
+ if (highlighterActive) {
1715
+ pdfViewerRef.current?.annotation?.deactivateHighlighter();
1716
+ setInternalHighlighterActive(false);
1717
+ }
1718
+ pdfViewerRef.current?.annotation?.activateStamp("");
1719
+ setInternalStampActive(true);
1720
+ }
1721
+ },
1722
+ handleSignatureClick: () => {
1723
+ },
1724
+ handleCopy: () => {
1725
+ pdfViewerRef.current?.selection.copy();
1726
+ },
1727
+ handleToggleFullScreen
1728
+ }),
1729
+ [isSidebarOpen, totalPages, handleToggleFullScreen, highlighterActive, stampActive, onDownloadWithAnnotations, onDownloadWithoutAnnotations, onPrintWithAnnotations, onPrintWithoutAnnotations]
1730
+ );
1731
+ useEffect4(() => {
1732
+ if (!initialSearchText || hasExecutedInitialSearch.current) return;
1733
+ const isPDFReady = state === "ready";
1734
+ const isPagesInitialized = totalPages > 0;
1735
+ const isViewerAvailable = !!pdfViewerRef.current;
1736
+ const isSearchAPIReady = !!pdfViewerRef.current?.search?.searchText;
1737
+ const canExecuteSearch = isPDFReady && isPagesInitialized && isViewerAvailable && isSearchAPIReady;
1738
+ if (!canExecuteSearch) return;
1739
+ hasExecutedInitialSearch.current = true;
1740
+ const SEARCH_INITIALIZATION_DELAY = 100;
1741
+ setTimeout(() => {
1742
+ if (!pdfViewerRef.current?.search?.searchText) {
1743
+ hasExecutedInitialSearch.current = false;
1744
+ return;
1745
+ }
1746
+ requestAnimationFrame(() => {
1747
+ requestAnimationFrame(() => {
1748
+ setIsSidebarOpen(true);
1749
+ handleSidebarSearch(initialSearchText, initialSearchPages);
1750
+ setAutoExecuteSearch(false);
1751
+ });
1752
+ });
1753
+ }, SEARCH_INITIALIZATION_DELAY);
1754
+ }, [
1755
+ state,
1756
+ totalPages,
1757
+ pdfViewerRef.current,
1758
+ initialSearchText,
1759
+ initialSearchPages
1760
+ ]);
1761
+ useEffect4(() => {
1762
+ setSearchQuery("");
1763
+ setSearchResults([]);
1764
+ setCurrentSearchResultIndex(0);
1765
+ setTotalSearchResults(0);
1766
+ setIsSearching(false);
1767
+ setIsSidebarOpen(false);
1768
+ hasExecutedInitialSearch.current = false;
1769
+ setCurrentPage(1);
1770
+ setTotalPages(0);
1771
+ setZoom(122);
1772
+ setState("idle");
1773
+ setError(null);
1774
+ setPdfBuffer(null);
1775
+ }, [file]);
1776
+ useEffect4(() => {
1777
+ if (state !== "ready") return;
1778
+ const container = document.querySelector(
1779
+ '[data-pdf-viewer], .embedpdf-viewport, [role="document"]'
1780
+ );
1781
+ if (container) {
1782
+ setPdfContainer(container);
1783
+ return;
1784
+ }
1785
+ const observer = new MutationObserver(() => {
1786
+ const foundContainer = document.querySelector(
1787
+ '[data-pdf-viewer], .embedpdf-viewport, [role="document"]'
1788
+ );
1789
+ if (foundContainer) {
1790
+ setPdfContainer(foundContainer);
1791
+ observer.disconnect();
1792
+ }
1793
+ });
1794
+ observer.observe(document.body, { childList: true, subtree: true });
1795
+ return () => observer.disconnect();
1796
+ }, [state]);
1797
+ useEffect4(() => {
1798
+ if (state !== "ready") return;
1799
+ const checkInternalReadiness = async () => {
1800
+ if (!pdfViewerRef.current) return;
1801
+ try {
1802
+ const count = pdfViewerRef.current.navigation?.getTotalPages?.();
1803
+ if (count && count > 0) {
1804
+ setTotalPages(count);
1805
+ setIsInternalReady(true);
1806
+ return;
1807
+ }
1808
+ const docInfo = pdfViewerRef.current?.document?.getDocumentInfo?.();
1809
+ if (docInfo && docInfo.totalPages > 0) {
1810
+ setTotalPages(docInfo.totalPages);
1811
+ setIsInternalReady(true);
1812
+ return;
1813
+ }
1814
+ } catch (e) {
1815
+ }
1816
+ };
1817
+ const pollInterval = setInterval(checkInternalReadiness, 100);
1818
+ return () => clearInterval(pollInterval);
1819
+ }, [state]);
1820
+ useEffect4(() => {
1821
+ if (isInternalReady && pdfViewerRef.current) {
1822
+ try {
1823
+ pdfViewerRef.current.zoom.setZoom(1.22);
1824
+ setZoom(122);
1825
+ } catch (e) {
1826
+ }
1827
+ }
1828
+ }, [isInternalReady]);
1829
+ useEffect4(() => {
1830
+ if (state !== "ready" || totalPages > 0) return;
1831
+ const initializePageCount = async () => {
1832
+ const waitForViewer = async (maxAttempts = 10) => {
1833
+ for (let i = 0; i < maxAttempts; i++) {
1834
+ if (pdfViewerRef.current) return pdfViewerRef.current;
1835
+ await new Promise(
1836
+ (resolve) => requestAnimationFrame(
1837
+ () => setTimeout(resolve, Math.min(100 * Math.pow(2, i), 1e3))
1838
+ )
1839
+ );
1840
+ }
1841
+ return null;
1842
+ };
1843
+ const viewer = await waitForViewer();
1844
+ if (!viewer) return;
1845
+ await new Promise((resolve) => requestAnimationFrame(resolve));
1846
+ try {
1847
+ const count = viewer.navigation?.getTotalPages?.();
1848
+ if (count && count > 0) {
1849
+ setTotalPages(count);
1850
+ setIsInternalReady(true);
1851
+ return;
1852
+ }
1853
+ } catch (e) {
1854
+ }
1855
+ };
1856
+ initializePageCount();
1857
+ }, [state, totalPages]);
1858
+ useEffect4(() => {
1859
+ if (state === "ready") {
1860
+ const updateInfo = () => {
1861
+ if (!pdfViewerRef.current) return;
1862
+ const current = pdfViewerRef.current?.navigation.getCurrentPage() || 1;
1863
+ const docInfo = pdfViewerRef.current?.document?.getDocumentInfo?.();
1864
+ const navTotal = pdfViewerRef.current?.navigation?.getTotalPages?.();
1865
+ let total = 0;
1866
+ if (docInfo && docInfo.totalPages > 0) {
1867
+ total = docInfo.totalPages;
1868
+ } else if (typeof navTotal === "number" && navTotal > 0) {
1869
+ total = navTotal;
1870
+ }
1871
+ const zoomValue = pdfViewerRef.current?.zoom.getZoom();
1872
+ const currentSearchState = pdfViewerRef.current?.search.getSearchState();
1873
+ setCurrentPage(current);
1874
+ if (total > 0 && total !== totalPages) {
1875
+ setTotalPages(total);
1876
+ }
1877
+ if (typeof zoomValue === "number") {
1878
+ setZoom(Math.round(zoomValue * 100));
1879
+ }
1880
+ };
1881
+ updateInfo();
1882
+ const pollInterval = totalPages === 0 ? 50 : 300;
1883
+ const interval = setInterval(updateInfo, pollInterval);
1884
+ return () => clearInterval(interval);
1885
+ }
1886
+ }, [state, totalPages]);
1887
+ useImperativeHandle(
1888
+ ref,
1889
+ () => ({
1890
+ zoomIn: () => {
1891
+ pdfViewerRef.current?.zoom.zoomIn();
1892
+ updateZoomDisplay();
1893
+ },
1894
+ zoomOut: () => {
1895
+ pdfViewerRef.current?.zoom.zoomOut();
1896
+ updateZoomDisplay();
1897
+ },
1898
+ setZoom: (level) => {
1899
+ pdfViewerRef.current?.zoom.setZoom(level);
1900
+ updateZoomDisplay();
1901
+ },
1902
+ resetZoom: () => {
1903
+ pdfViewerRef.current?.zoom.resetZoom();
1904
+ updateZoomDisplay();
1905
+ },
1906
+ getZoom: () => {
1907
+ const zoom2 = pdfViewerRef.current?.zoom.getZoom();
1908
+ return typeof zoom2 === "number" ? zoom2 : 1;
1909
+ },
1910
+ goToPage: (page) => {
1911
+ pdfViewerRef.current?.navigation.goToPage(page);
1912
+ setCurrentPage(page);
1913
+ },
1914
+ getCurrentPage: () => pdfViewerRef.current?.navigation.getCurrentPage() || 1,
1915
+ getTotalPages: () => pdfViewerRef.current?.navigation.getTotalPages() || 0,
1916
+ nextPage: () => {
1917
+ pdfViewerRef.current?.navigation.nextPage();
1918
+ updatePageDisplay();
1919
+ },
1920
+ previousPage: () => {
1921
+ pdfViewerRef.current?.navigation.previousPage();
1922
+ updatePageDisplay();
1923
+ },
1924
+ goToFirstPage: () => {
1925
+ pdfViewerRef.current?.navigation.goToFirstPage();
1926
+ updatePageDisplay();
1927
+ },
1928
+ goToLastPage: () => {
1929
+ pdfViewerRef.current?.navigation.goToLastPage();
1930
+ updatePageDisplay();
1931
+ },
1932
+ searchText: async (keyword) => {
1933
+ setIsSearching(true);
1934
+ const results = await pdfViewerRef.current?.search.searchText(
1935
+ keyword
1936
+ );
1937
+ setIsSearching(false);
1938
+ setSearchQuery(keyword);
1939
+ return results;
1940
+ },
1941
+ nextResult: () => {
1942
+ const index = pdfViewerRef.current?.search.nextResult() || -1;
1943
+ return index;
1944
+ },
1945
+ previousResult: () => {
1946
+ const index = pdfViewerRef.current?.search.previousResult() || -1;
1947
+ return index;
1948
+ },
1949
+ goToResult: (index) => pdfViewerRef.current?.search.goToResult(index) || -1,
1950
+ stopSearch: () => {
1951
+ pdfViewerRef.current?.search.stopSearch();
1952
+ setSearchQuery("");
1953
+ },
1954
+ getSearchState: () => pdfViewerRef.current?.search.getSearchState() || null,
1955
+ getSelectedText: async () => {
1956
+ return await pdfViewerRef.current?.selection.getSelectedText() || "";
1957
+ },
1958
+ clearSelection: () => pdfViewerRef.current?.selection.clearSelection(),
1959
+ copy: () => pdfViewerRef.current?.selection.copy(),
1960
+ rotateForward: () => pdfViewerRef.current?.rotate?.rotateForward(),
1961
+ rotateBackward: () => pdfViewerRef.current?.rotate?.rotateBackward(),
1962
+ getRotation: () => pdfViewerRef.current?.rotate?.getRotation() || 0,
1963
+ print: () => pdfViewerRef.current?.print?.print(),
1964
+ printWithAnnotations: async () => {
1965
+ await pdfViewerRef.current?.print?.printWithAnnotations?.();
1966
+ },
1967
+ printWithoutAnnotations: async () => {
1968
+ await pdfViewerRef.current?.print?.printWithoutAnnotations?.();
1969
+ },
1970
+ downloadWithAnnotations: async (filename) => {
1971
+ await pdfViewerRef.current?.download?.downloadWithAnnotations?.(filename);
1972
+ },
1973
+ downloadWithoutAnnotations: async (filename) => {
1974
+ await pdfViewerRef.current?.download?.downloadWithoutAnnotations?.(filename);
1975
+ },
1976
+ get annotation() {
1977
+ return pdfViewerRef.current?.annotation;
1978
+ },
1979
+ get download() {
1980
+ return pdfViewerRef.current?.download;
1981
+ }
1982
+ }),
1983
+ []
1984
+ );
1985
+ const updatePageDisplay = () => {
1986
+ requestAnimationFrame(() => {
1987
+ const current = pdfViewerRef.current?.navigation.getCurrentPage() || 1;
1988
+ setCurrentPage(current);
1989
+ });
1990
+ };
1991
+ const updateZoomDisplay = () => {
1992
+ requestAnimationFrame(() => {
1993
+ const zoomValue = pdfViewerRef.current?.zoom.getZoom();
1994
+ if (typeof zoomValue === "number") {
1995
+ setZoom(Math.round(zoomValue * 100));
1996
+ }
1997
+ });
1998
+ };
1999
+ const handleSearch = async () => {
2000
+ if (!searchQuery.trim()) return;
2001
+ setIsSearching(true);
2002
+ const results = await pdfViewerRef.current?.search.searchText(
2003
+ searchQuery
2004
+ );
2005
+ setIsSearching(false);
2006
+ if (results?.results && Array.isArray(results.results) && results.results.length > 0) {
2007
+ const formattedResults = formatSearchResults(results.results);
2008
+ updateSearchState(formattedResults);
2009
+ } else {
2010
+ clearSearchResults();
2011
+ }
2012
+ };
2013
+ const handleSearchKeyPress = (e) => {
2014
+ if (e.key === "Enter") {
2015
+ handleSearch();
2016
+ }
2017
+ };
2018
+ const handleSidebarSearch = async (keyword, pageNumbers) => {
2019
+ setSearchQuery(keyword);
2020
+ if (!keyword.trim()) {
2021
+ setSearchResults([]);
2022
+ setTotalSearchResults(0);
2023
+ setCurrentSearchResultIndex(0);
2024
+ pdfViewerRef.current?.search.stopSearch();
2025
+ return;
2026
+ }
2027
+ if (!pdfViewerRef.current?.search?.searchText) {
2028
+ console.warn("Search functionality not yet available");
2029
+ return;
2030
+ }
2031
+ setIsSearching(true);
2032
+ try {
2033
+ const results = await pdfViewerRef.current.search.searchText(keyword);
2034
+ setIsSearching(false);
2035
+ const hasValidResults = results?.results && Array.isArray(results.results) && results.results.length > 0;
2036
+ if (hasValidResults) {
2037
+ const formattedResults = formatSearchResults(results.results);
2038
+ updateSearchState(formattedResults);
2039
+ navigateToFirstResult(formattedResults);
2040
+ } else if (pageNumbers && pageNumbers.length > 0) {
2041
+ const fallbackResults = createFallbackResults(pageNumbers, keyword);
2042
+ updateSearchState(fallbackResults);
2043
+ navigateToPage(pageNumbers[0]);
2044
+ } else {
2045
+ clearSearchResults();
2046
+ }
2047
+ } catch (error2) {
2048
+ console.error("Search failed:", error2);
2049
+ setIsSearching(false);
2050
+ clearSearchResults();
2051
+ }
2052
+ };
2053
+ const formatSearchResults = (results) => {
2054
+ return results.map((result, index) => {
2055
+ let textContent = "";
2056
+ let contextContent = "";
2057
+ if (result.context && typeof result.context === "object") {
2058
+ const { before = "", match = "", after = "" } = result.context;
2059
+ textContent = match;
2060
+ contextContent = `${before}${match}${after}`;
2061
+ } else if (typeof result === "string") {
2062
+ textContent = result;
2063
+ contextContent = result;
2064
+ } else {
2065
+ textContent = String(result.match || result.text || "");
2066
+ contextContent = textContent;
2067
+ }
2068
+ return {
2069
+ pageNumber: (result.pageIndex ?? result.pageNumber ?? 0) + 1,
2070
+ text: textContent,
2071
+ context: contextContent,
2072
+ index
2073
+ };
2074
+ });
2075
+ };
2076
+ const createFallbackResults = (pageNumbers, keyword) => {
2077
+ return pageNumbers.map((pageNum, index) => ({
2078
+ pageNumber: pageNum,
2079
+ text: keyword,
2080
+ context: `"${keyword}" found on this page ${pageNum}`,
2081
+ index
2082
+ }));
2083
+ };
2084
+ const updateSearchState = (results) => {
2085
+ setSearchResults(results);
2086
+ setTotalSearchResults(results.length);
2087
+ setCurrentSearchResultIndex(0);
2088
+ };
2089
+ const clearSearchResults = () => {
2090
+ setSearchResults([]);
2091
+ setTotalSearchResults(0);
2092
+ setCurrentSearchResultIndex(0);
2093
+ };
2094
+ const navigateToFirstResult = (results) => {
2095
+ if (results.length > 0) {
2096
+ navigateToPage(results[0].pageNumber);
2097
+ }
2098
+ };
2099
+ const navigateToPage = (pageNumber) => {
2100
+ requestAnimationFrame(() => {
2101
+ pdfViewerRef.current?.navigation.goToPage(pageNumber);
2102
+ setCurrentPage(pageNumber);
2103
+ });
2104
+ };
2105
+ const handleSearchResultClick = (pageNumber, resultIndex) => {
2106
+ pdfViewerRef.current?.navigation.goToPage(pageNumber);
2107
+ setCurrentSearchResultIndex(resultIndex);
2108
+ setCurrentPage(pageNumber);
2109
+ pdfViewerRef.current?.search.goToResult(resultIndex);
2110
+ };
2111
+ const handleNextSearchResult = () => {
2112
+ if (currentSearchResultIndex < totalSearchResults - 1) {
2113
+ const nextIndex = currentSearchResultIndex + 1;
2114
+ setCurrentSearchResultIndex(nextIndex);
2115
+ pdfViewerRef.current?.search.nextResult();
2116
+ if (searchResults[nextIndex]) {
2117
+ const pageNumber = searchResults[nextIndex].pageNumber;
2118
+ pdfViewerRef.current?.navigation.goToPage(pageNumber);
2119
+ setCurrentPage(pageNumber);
2120
+ }
2121
+ }
2122
+ };
2123
+ const handlePreviousSearchResult = () => {
2124
+ if (currentSearchResultIndex > 0) {
2125
+ const prevIndex = currentSearchResultIndex - 1;
2126
+ setCurrentSearchResultIndex(prevIndex);
2127
+ pdfViewerRef.current?.search.previousResult();
2128
+ if (searchResults[prevIndex]) {
2129
+ const pageNumber = searchResults[prevIndex].pageNumber;
2130
+ pdfViewerRef.current?.navigation.goToPage(pageNumber);
2131
+ setCurrentPage(pageNumber);
2132
+ }
2133
+ }
2134
+ };
2135
+ useEffect4(() => {
2136
+ if (!file) {
2137
+ setState("error");
2138
+ setError("No file provided");
2139
+ return;
2140
+ }
2141
+ const loadPDF = async () => {
2142
+ try {
2143
+ setState("loading");
2144
+ setError(null);
2145
+ let arrayBuffer;
2146
+ if (file instanceof File) {
2147
+ arrayBuffer = await file.arrayBuffer();
2148
+ } else if (typeof file === "string") {
2149
+ const response = await fetch(file);
2150
+ if (!response.ok) {
2151
+ throw new Error(`Failed to load PDF: ${response.statusText}`);
2152
+ }
2153
+ arrayBuffer = await response.arrayBuffer();
2154
+ } else if (file instanceof ArrayBuffer) {
2155
+ arrayBuffer = file;
2156
+ } else {
2157
+ throw new Error("Unsupported file type");
2158
+ }
2159
+ setPdfBuffer(arrayBuffer);
2160
+ setState("ready");
2161
+ onLoad?.();
2162
+ } catch (err) {
2163
+ const errorMessage = err.message || "Failed to load PDF";
2164
+ setState("error");
2165
+ setError(errorMessage);
2166
+ onError?.(err);
2167
+ }
2168
+ };
2169
+ loadPDF();
2170
+ }, [file, onLoad, onError]);
2171
+ const handlePasswordRequest = useCallback(
2172
+ async (fileName2, isRetry) => {
2173
+ return new Promise((resolve) => {
2174
+ setPasswordResolve(() => resolve);
2175
+ if (isRetry) {
2176
+ setPasswordError("Incorrect password. Please try again.");
2177
+ } else {
2178
+ setPasswordError("");
2179
+ }
2180
+ setIsPasswordDialogOpen(true);
2181
+ });
2182
+ },
2183
+ []
2184
+ );
2185
+ const handlePasswordSubmit = useCallback(
2186
+ (password) => {
2187
+ if (passwordResolve) {
2188
+ passwordResolve(password);
2189
+ }
2190
+ setIsPasswordDialogOpen(false);
2191
+ setPasswordResolve(null);
2192
+ setPasswordError("");
2193
+ },
2194
+ [passwordResolve]
2195
+ );
2196
+ const handlePasswordCancel = useCallback(() => {
2197
+ if (passwordResolve) {
2198
+ passwordResolve(null);
2199
+ setPasswordResolve(null);
2200
+ setIsPasswordDialogOpen(false);
2201
+ setPasswordError("");
2202
+ }
2203
+ }, [passwordResolve]);
2204
+ const LoadingSpinner = ({ fileName: fileName2 }) => /* @__PURE__ */ jsxs5("div", { style: {
2205
+ position: "absolute",
2206
+ inset: 0,
2207
+ zIndex: 50,
2208
+ backgroundColor: "#fff",
2209
+ display: "flex",
2210
+ flexDirection: "column",
2211
+ alignItems: "center",
2212
+ justifyContent: "center"
2213
+ }, children: [
2214
+ /* @__PURE__ */ jsx6("div", { className: "dms-loading-spinner", style: {
2215
+ width: "40px",
2216
+ height: "40px",
2217
+ border: "3px solid #f3f3f3",
2218
+ borderTop: "3px solid #3498db",
2219
+ borderRadius: "50%",
2220
+ animation: "spin 1s linear infinite"
2221
+ } }),
2222
+ fileName2 && /* @__PURE__ */ jsxs5("p", { style: { marginTop: "16px", color: "#666", fontSize: "14px" }, children: [
2223
+ "Loading ",
2224
+ fileName2,
2225
+ "..."
2226
+ ] }),
2227
+ /* @__PURE__ */ jsx6("style", { children: `@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }` })
2228
+ ] });
2229
+ if (state === "error" || error) {
2230
+ return /* @__PURE__ */ jsx6(
2231
+ "div",
2232
+ {
2233
+ style: {
2234
+ display: "flex",
2235
+ flexDirection: "column",
2236
+ alignItems: "center",
2237
+ justifyContent: "center",
2238
+ height: "100%",
2239
+ padding: "24px"
2240
+ },
2241
+ children: /* @__PURE__ */ jsxs5(
2242
+ "div",
2243
+ {
2244
+ style: {
2245
+ maxWidth: "400px",
2246
+ padding: "16px",
2247
+ backgroundColor: "#fee",
2248
+ border: "1px solid #fcc",
2249
+ borderRadius: "4px"
2250
+ },
2251
+ children: [
2252
+ /* @__PURE__ */ jsx6("h3", { style: { marginTop: 0 }, children: "Failed to Load PDF" }),
2253
+ /* @__PURE__ */ jsx6("p", { children: error || "Unknown error occurred" })
2254
+ ]
2255
+ }
2256
+ )
2257
+ }
2258
+ );
2259
+ }
2260
+ const isReady = pdfBuffer && state === "ready";
2261
+ const showOverlay = loading || !isReady || !isInternalReady;
2262
+ return /* @__PURE__ */ jsxs5("div", { ref: containerRef, className: `pdf-viewer-container ${themeMode === "dark" ? "dark-theme" : ""}`, style: { position: "relative", height: "100%", width: "100%" }, children: [
2263
+ /* @__PURE__ */ jsx6("style", { children: toolbarStyles }),
2264
+ showOverlay && /* @__PURE__ */ jsx6(LoadingSpinner, { fileName: resolvedFileName }),
2265
+ /* @__PURE__ */ jsxs5("div", { style: { opacity: !showOverlay ? 1 : 0, height: "100%", display: "flex", flexDirection: "column" }, children: [
2266
+ /* @__PURE__ */ jsx6(PDFHeader, { fileName: resolvedFileName, fileExtension }),
2267
+ /* @__PURE__ */ jsx6(
2268
+ PDFToolbar,
2269
+ {
2270
+ currentPage,
2271
+ totalPages,
2272
+ zoom,
2273
+ isSidebarOpen,
2274
+ showPageNavigation,
2275
+ showPageCount,
2276
+ showZoomControls,
2277
+ showSearch,
2278
+ showRotation: !toolbar.isHidden("rotation"),
2279
+ showMetadata: !toolbar.isHidden("metadata"),
2280
+ showProperties: !toolbar.isHidden("properties"),
2281
+ showDownload: !toolbar.isHidden("download"),
2282
+ showPrint: !toolbar.isHidden("print"),
2283
+ showTags: !toolbar.isHidden("tags"),
2284
+ showHistory: !toolbar.isHidden("history"),
2285
+ disabledRotateLeft: toolbar.isDisabled("rotateLeft"),
2286
+ disabledRotateRight: false,
2287
+ disabledMetadata: toolbar.isDisabled("metadata"),
2288
+ disabledTags: toolbar.isDisabled("tags"),
2289
+ disabledProperties: toolbar.isDisabled("properties"),
2290
+ disabledHistory: toolbar.isDisabled("history"),
2291
+ disabledDownload: toolbar.isDisabled("download"),
2292
+ disabledPrint: toolbar.isDisabled("print"),
2293
+ onFirstPage: toolbarHandlers.handleFirstPage,
2294
+ onPreviousPage: toolbarHandlers.handlePreviousPage,
2295
+ onNextPage: toolbarHandlers.handleNextPage,
2296
+ onLastPage: toolbarHandlers.handleLastPage,
2297
+ onPageInput: toolbarHandlers.handlePageInput,
2298
+ onPageInputKeyPress: toolbarHandlers.handlePageInputKeyPress,
2299
+ onZoomIn: toolbarHandlers.handleZoomIn,
2300
+ onZoomOut: toolbarHandlers.handleZoomOut,
2301
+ onFitToWidth: toolbarHandlers.handleFitToWidth,
2302
+ onFitToPage: toolbarHandlers.handleFitToPage,
2303
+ onToggleSidebar: toolbarHandlers.toggleSidebar,
2304
+ onToggleFullScreen: toolbarHandlers.handleToggleFullScreen,
2305
+ onRotateLeft: toolbarHandlers.handleRotateLeft,
2306
+ onRotateRight: toolbarHandlers.handleRotateRight,
2307
+ onDownloadClick: toolbar.getHandler("download", onDownloadClick),
2308
+ onDownloadWithAnnotations: toolbarHandlers.handleDownloadWithAnnotations,
2309
+ onDownloadWithoutAnnotations: toolbarHandlers.handleDownloadWithoutAnnotations,
2310
+ onPrintClick: toolbar.getHandler("print", onPrintClick || toolbarHandlers.handlePrint),
2311
+ onPrintWithAnnotations: toolbarHandlers.handlePrintWithAnnotations,
2312
+ onPrintWithoutAnnotations: toolbarHandlers.handlePrintWithoutAnnotations,
2313
+ onCopyClick: toolbarHandlers.handleCopy,
2314
+ onMetadataClick: toolbar.getHandler("metadata", onMetadataClick),
2315
+ onPropertiesClick: toolbar.getHandler(
2316
+ "properties",
2317
+ onPropertiesClick
2318
+ ),
2319
+ onTagsClick: toolbar.getHandler("tags", onTagsClick),
2320
+ onHistoryClick: toolbar.getHandler("history", onHistoryClick),
2321
+ showAnnotations,
2322
+ isHighlighterActive: highlighterActive,
2323
+ isStampActive: stampActive,
2324
+ disabledHighlighter: toolbar.isDisabled("highlighter"),
2325
+ disabledStamp: toolbar.isDisabled("stamp"),
2326
+ disabledSignature: toolbar.isDisabled("signature"),
2327
+ disabledNote: toolbar.isDisabled("note"),
2328
+ onHighlighterClick: toolbar.getHandler("highlighter", onHighlighterClick || toolbarHandlers.handleHighlighterClick),
2329
+ onStampClick: toolbar.getHandler("stamp", onStampClick || toolbarHandlers.handleStampClick),
2330
+ onSignatureClick: toolbar.getHandler("signature", onSignatureClick || toolbarHandlers.handleSignatureClick),
2331
+ onNoteClick: toolbar.getHandler("note", onNoteClick),
2332
+ showAnnotate,
2333
+ disabledAnnotate,
2334
+ showPrintOriginal,
2335
+ showPrintWithAnnotations,
2336
+ showDownloadOriginal,
2337
+ showDownloadWithAnnotations,
2338
+ twoPageMode,
2339
+ onTwoPageModeChange: setTwoPageMode,
2340
+ scrollStrategy,
2341
+ onScrollStrategyChange: setScrollStrategy,
2342
+ showThumbnails,
2343
+ onToggleThumbnails: () => setShowThumbnails(!showThumbnails),
2344
+ hasUnsavedAnnotations,
2345
+ isSavingAnnotations,
2346
+ canSaveAnnotations,
2347
+ onSaveAnnotations,
2348
+ activeMode,
2349
+ onActiveModeChange: setActiveMode
2350
+ }
2351
+ ),
2352
+ /* @__PURE__ */ jsxs5("div", { className: "pdf-viewer-main", children: [
2353
+ showThumbnails && pdfBuffer && /* @__PURE__ */ jsx6(
2354
+ PdfThumbnailSidebar,
2355
+ {
2356
+ pdfBuffer,
2357
+ totalPages,
2358
+ currentPage,
2359
+ onPageClick: (pageNum) => pdfViewerRef.current?.navigation.goToPage(pageNum),
2360
+ onClose: () => setShowThumbnails(false),
2361
+ twoPageMode: false
2362
+ }
2363
+ ),
2364
+ /* @__PURE__ */ jsxs5("div", { className: "pdf-viewer-viewer-area", children: [
2365
+ /* @__PURE__ */ jsx6(
2366
+ PDFSecondaryToolbar,
2367
+ {
2368
+ activeMode,
2369
+ showAnnotations,
2370
+ isHighlighterActive: highlighterActive,
2371
+ isStampActive: stampActive,
2372
+ disabledHighlighter: toolbar.isDisabled("highlighter"),
2373
+ disabledStamp: toolbar.isDisabled("stamp"),
2374
+ disabledSignature: toolbar.isDisabled("signature"),
2375
+ disabledNote: toolbar.isDisabled("note"),
2376
+ onHighlighterClick: onHighlighterClick || toolbarHandlers.handleHighlighterClick,
2377
+ onStampClick: onStampClick || toolbarHandlers.handleStampClick,
2378
+ onSignatureClick: onSignatureClick || toolbarHandlers.handleSignatureClick,
2379
+ onNoteClick,
2380
+ hasUnsavedAnnotations,
2381
+ isSavingAnnotations,
2382
+ canSaveAnnotations,
2383
+ onSaveAnnotations
2384
+ }
2385
+ ),
2386
+ /* @__PURE__ */ jsx6(
2387
+ StablePDFViewer,
2388
+ {
2389
+ pdfBuffer: pdfBuffer || new ArrayBuffer(0),
2390
+ onPasswordRequest: handlePasswordRequest,
2391
+ pdfViewerRef,
2392
+ hideInternalLoading: true,
2393
+ showAnnotations,
2394
+ userDetails,
2395
+ annotationSelectionMenu,
2396
+ isHighlighterActive: highlighterActive,
2397
+ isStampActive: stampActive,
2398
+ onHighlighterClick: onHighlighterClick || toolbarHandlers.handleHighlighterClick,
2399
+ onStampClick: onStampClick || toolbarHandlers.handleStampClick,
2400
+ onSignatureClick: onSignatureClick || toolbarHandlers.handleSignatureClick,
2401
+ onNoteClick,
2402
+ permissions: props.permissions,
2403
+ isAnnotationForeign,
2404
+ onAnnotationNoteClick,
2405
+ isAnnotationInteractive,
2406
+ twoPageMode,
2407
+ scrollStrategy
2408
+ }
2409
+ )
2410
+ ] }),
2411
+ /* @__PURE__ */ jsx6(
2412
+ SearchSidebar,
2413
+ {
2414
+ isOpen: isSidebarOpen,
2415
+ onClose: handleSidebarClose,
2416
+ onSearch: handleSidebarSearch,
2417
+ onSearchResultClick: handleSearchResultClick,
2418
+ onNextResult: handleNextSearchResult,
2419
+ onPreviousResult: handlePreviousSearchResult,
2420
+ currentResultIndex: currentSearchResultIndex,
2421
+ totalResults: totalSearchResults,
2422
+ searchKeyword: searchQuery,
2423
+ searchResults,
2424
+ isSearching
2425
+ }
2426
+ )
2427
+ ] }),
2428
+ /* @__PURE__ */ jsx6(
2429
+ PasswordDialog,
2430
+ {
2431
+ open: isPasswordDialogOpen,
2432
+ fileName: resolvedFileName,
2433
+ onSubmit: handlePasswordSubmit,
2434
+ onCancel: handlePasswordCancel,
2435
+ error: passwordError,
2436
+ isLoading: isVerifyingPassword
2437
+ }
2438
+ )
2439
+ ] })
2440
+ ] });
2441
+ }
2442
+ );
2443
+ PDFViewerContent.displayName = "PDFViewerContent";
2444
+ var PDFViewer = forwardRef(
2445
+ (props, ref) => {
2446
+ return /* @__PURE__ */ jsx6(PDFViewerContent, { ...props, sourceDescription: "doc.pdf", ref });
2447
+ }
2448
+ );
2449
+ PDFViewer.displayName = "PDFViewer";
2450
+
2451
+ export {
2452
+ PDFViewer
2453
+ };
2454
+ //# sourceMappingURL=chunk-6L72TJIW.mjs.map