@cannyminds/dms-file-viewers 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/chunk-42VHR3EK.mjs +714 -0
  2. package/dist/chunk-42VHR3EK.mjs.map +1 -0
  3. package/dist/{chunk-J3JKVSAM.js → chunk-AYVTSFZA.js} +2 -1
  4. package/dist/chunk-AYVTSFZA.js.map +1 -0
  5. package/dist/chunk-C4L2R2QY.mjs +277 -0
  6. package/dist/chunk-C4L2R2QY.mjs.map +1 -0
  7. package/dist/chunk-DBXSX2B6.js +277 -0
  8. package/dist/chunk-DBXSX2B6.js.map +1 -0
  9. package/dist/chunk-DPSRGULQ.mjs +247 -0
  10. package/dist/chunk-DPSRGULQ.mjs.map +1 -0
  11. package/dist/chunk-FK6RYOAZ.mjs +297 -0
  12. package/dist/chunk-FK6RYOAZ.mjs.map +1 -0
  13. package/dist/chunk-FZVXQGA7.mjs +466 -0
  14. package/dist/chunk-FZVXQGA7.mjs.map +1 -0
  15. package/dist/chunk-GSRAK2YV.js +266 -0
  16. package/dist/chunk-GSRAK2YV.js.map +1 -0
  17. package/dist/chunk-HYRQBGAX.js +466 -0
  18. package/dist/chunk-HYRQBGAX.js.map +1 -0
  19. package/dist/chunk-RKDOWWQD.js +247 -0
  20. package/dist/chunk-RKDOWWQD.js.map +1 -0
  21. package/dist/chunk-TMAHQICY.mjs +1842 -0
  22. package/dist/chunk-TMAHQICY.mjs.map +1 -0
  23. package/dist/chunk-VBJVOB45.mjs +266 -0
  24. package/dist/chunk-VBJVOB45.mjs.map +1 -0
  25. package/dist/{chunk-DFBVN4MO.mjs → chunk-WR5SJ3LM.mjs} +2 -1
  26. package/dist/chunk-WR5SJ3LM.mjs.map +1 -0
  27. package/dist/chunk-XSXOX4MV.js +297 -0
  28. package/dist/chunk-XSXOX4MV.js.map +1 -0
  29. package/dist/chunk-XWWMHRVU.js +1842 -0
  30. package/dist/chunk-XWWMHRVU.js.map +1 -0
  31. package/dist/chunk-YU535XRJ.js +714 -0
  32. package/dist/chunk-YU535XRJ.js.map +1 -0
  33. package/dist/components/viewers/AudioViewer.d.mts +1 -1
  34. package/dist/components/viewers/AudioViewer.d.ts +1 -1
  35. package/dist/components/viewers/AudioViewer.js +3 -3
  36. package/dist/components/viewers/AudioViewer.mjs +2 -2
  37. package/dist/components/viewers/DefaultViewer.d.mts +1 -1
  38. package/dist/components/viewers/DefaultViewer.d.ts +1 -1
  39. package/dist/components/viewers/DefaultViewer.js +3 -3
  40. package/dist/components/viewers/DefaultViewer.mjs +2 -2
  41. package/dist/components/viewers/ImageViewer.d.mts +1 -1
  42. package/dist/components/viewers/ImageViewer.d.ts +1 -1
  43. package/dist/components/viewers/ImageViewer.js +3 -3
  44. package/dist/components/viewers/ImageViewer.mjs +2 -2
  45. package/dist/components/viewers/PDFViewer.d.mts +1 -1
  46. package/dist/components/viewers/PDFViewer.d.ts +1 -1
  47. package/dist/components/viewers/PDFViewer.js +3 -3
  48. package/dist/components/viewers/PDFViewer.mjs +2 -2
  49. package/dist/components/viewers/TIFFViewer.d.mts +1 -1
  50. package/dist/components/viewers/TIFFViewer.d.ts +1 -1
  51. package/dist/components/viewers/TIFFViewer.js +3 -3
  52. package/dist/components/viewers/TIFFViewer.mjs +2 -2
  53. package/dist/components/viewers/TextViewer.d.mts +1 -1
  54. package/dist/components/viewers/TextViewer.d.ts +1 -1
  55. package/dist/components/viewers/TextViewer.js +3 -3
  56. package/dist/components/viewers/TextViewer.mjs +2 -2
  57. package/dist/components/viewers/VideoViewer.d.mts +1 -1
  58. package/dist/components/viewers/VideoViewer.d.ts +1 -1
  59. package/dist/components/viewers/VideoViewer.js +3 -3
  60. package/dist/components/viewers/VideoViewer.mjs +2 -2
  61. package/dist/index.d.mts +2 -2
  62. package/dist/index.d.ts +2 -2
  63. package/dist/index.js +9 -9
  64. package/dist/index.mjs +8 -8
  65. package/dist/{types-DNrkDJdK.d.mts → types-DxRCbIFP.d.mts} +4 -2
  66. package/dist/{types-DNrkDJdK.d.ts → types-DxRCbIFP.d.ts} +4 -2
  67. package/package.json +1 -1
  68. package/dist/chunk-7QRYWFCO.js +0 -639
  69. package/dist/chunk-7QRYWFCO.js.map +0 -1
  70. package/dist/chunk-7R2KG3PE.mjs +0 -210
  71. package/dist/chunk-7R2KG3PE.mjs.map +0 -1
  72. package/dist/chunk-CFYOPDCG.mjs +0 -235
  73. package/dist/chunk-CFYOPDCG.mjs.map +0 -1
  74. package/dist/chunk-D74R4IKW.mjs +0 -341
  75. package/dist/chunk-D74R4IKW.mjs.map +0 -1
  76. package/dist/chunk-DFBVN4MO.mjs.map +0 -1
  77. package/dist/chunk-EXZCEYLI.js +0 -247
  78. package/dist/chunk-EXZCEYLI.js.map +0 -1
  79. package/dist/chunk-J3JKVSAM.js.map +0 -1
  80. package/dist/chunk-NXVIRFGL.mjs +0 -247
  81. package/dist/chunk-NXVIRFGL.mjs.map +0 -1
  82. package/dist/chunk-P2VNW6OE.mjs +0 -180
  83. package/dist/chunk-P2VNW6OE.mjs.map +0 -1
  84. package/dist/chunk-P5FH7LK7.mjs +0 -639
  85. package/dist/chunk-P5FH7LK7.mjs.map +0 -1
  86. package/dist/chunk-PZJSY6OF.mjs +0 -1736
  87. package/dist/chunk-PZJSY6OF.mjs.map +0 -1
  88. package/dist/chunk-RVHIXSUP.js +0 -235
  89. package/dist/chunk-RVHIXSUP.js.map +0 -1
  90. package/dist/chunk-TGVFAAIP.js +0 -341
  91. package/dist/chunk-TGVFAAIP.js.map +0 -1
  92. package/dist/chunk-VOLQW3NF.js +0 -1736
  93. package/dist/chunk-VOLQW3NF.js.map +0 -1
  94. package/dist/chunk-VSGX22FQ.js +0 -180
  95. package/dist/chunk-VSGX22FQ.js.map +0 -1
  96. package/dist/chunk-WCAXWJE7.js +0 -210
  97. package/dist/chunk-WCAXWJE7.js.map +0 -1
@@ -0,0 +1,1842 @@
1
+ "use client";
2
+ import {
3
+ toolbarStyles
4
+ } from "./chunk-GMDRDOWP.mjs";
5
+ import {
6
+ getFileExtension
7
+ } from "./chunk-M57PSU4O.mjs";
8
+ import {
9
+ FileIcon_default,
10
+ mergeToolbarConfig
11
+ } from "./chunk-WR5SJ3LM.mjs";
12
+
13
+ // src/components/viewers/PDFViewer.tsx
14
+ import {
15
+ useCallback,
16
+ useEffect as useEffect3,
17
+ useMemo,
18
+ useRef as useRef2,
19
+ useState as useState3,
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 "@cannyminds/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
+ }) => {
34
+ return /* @__PURE__ */ jsx(
35
+ HeadlessPDFViewer,
36
+ {
37
+ ref: pdfViewerRef,
38
+ pdfBuffer,
39
+ onPasswordRequest
40
+ }
41
+ );
42
+ });
43
+ StablePDFViewer.displayName = "StablePDFViewer";
44
+
45
+ // src/components/viewers/pdf/PDFToolbar.tsx
46
+ import React2 from "react";
47
+ import FirstPageIcon from "@mui/icons-material/FirstPage";
48
+ import LastPageIcon from "@mui/icons-material/LastPage";
49
+ import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
50
+ import ChevronRightIcon from "@mui/icons-material/ChevronRight";
51
+ import ZoomInIcon from "@mui/icons-material/ZoomIn";
52
+ import ZoomOutIcon from "@mui/icons-material/ZoomOut";
53
+ import FitScreenIcon from "@mui/icons-material/FitScreen";
54
+ import AspectRatioIcon from "@mui/icons-material/AspectRatio";
55
+ import SearchIcon from "@mui/icons-material/Search";
56
+ import FullscreenIcon from "@mui/icons-material/Fullscreen";
57
+ import DownloadIcon from "@mui/icons-material/Download";
58
+ import PrintIcon from "@mui/icons-material/Print";
59
+ import InfoIcon from "@mui/icons-material/Info";
60
+ import DescriptionIcon from "@mui/icons-material/Description";
61
+ import RotateLeftIcon from "@mui/icons-material/RotateLeft";
62
+ import RotateRightIcon from "@mui/icons-material/RotateRight";
63
+ import { LocalOffer } from "@mui/icons-material";
64
+ import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
65
+ var PDFToolbar = React2.memo(
66
+ ({
67
+ currentPage,
68
+ totalPages,
69
+ zoom,
70
+ isSidebarOpen,
71
+ showPageNavigation,
72
+ showPageCount,
73
+ showZoomControls,
74
+ showSearch,
75
+ showMetadata,
76
+ showProperties,
77
+ showTags,
78
+ showDownload,
79
+ showPrint,
80
+ showRotation,
81
+ disabledRotateLeft,
82
+ disabledRotateRight,
83
+ disabledMetadata,
84
+ disabledProperties,
85
+ disabledTags,
86
+ disabledDownload,
87
+ disabledPrint,
88
+ onFirstPage,
89
+ onPreviousPage,
90
+ onNextPage,
91
+ onLastPage,
92
+ onPageInput,
93
+ onPageInputKeyPress,
94
+ onZoomIn,
95
+ onZoomOut,
96
+ onFitToWidth,
97
+ onFitToPage,
98
+ onToggleSidebar,
99
+ onToggleFullScreen,
100
+ onRotateLeft,
101
+ onRotateRight,
102
+ onDownloadClick,
103
+ onPrintClick,
104
+ onMetadataClick,
105
+ onPropertiesClick,
106
+ onTagsClick
107
+ }) => {
108
+ return /* @__PURE__ */ jsxs("div", { className: "pdf-viewer-toolbar", children: [
109
+ showPageNavigation && /* @__PURE__ */ jsxs(Fragment, { children: [
110
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-separator" }),
111
+ /* @__PURE__ */ jsxs("div", { className: "toolbar-section", children: [
112
+ /* @__PURE__ */ jsx2(
113
+ "button",
114
+ {
115
+ className: "toolbar-button",
116
+ onClick: onFirstPage,
117
+ disabled: currentPage <= 1,
118
+ title: "First Page",
119
+ children: /* @__PURE__ */ jsx2(FirstPageIcon, { fontSize: "small" })
120
+ }
121
+ ),
122
+ /* @__PURE__ */ jsx2(
123
+ "button",
124
+ {
125
+ className: "toolbar-button",
126
+ onClick: onPreviousPage,
127
+ disabled: currentPage <= 1,
128
+ title: "Previous Page",
129
+ children: /* @__PURE__ */ jsx2(ChevronLeftIcon, { fontSize: "small" })
130
+ }
131
+ ),
132
+ /* @__PURE__ */ jsx2(
133
+ "input",
134
+ {
135
+ type: "number",
136
+ className: "page-input",
137
+ value: currentPage,
138
+ onChange: onPageInput,
139
+ onKeyPress: onPageInputKeyPress,
140
+ min: 1,
141
+ max: totalPages || void 0
142
+ }
143
+ ),
144
+ showPageCount && /* @__PURE__ */ jsxs("span", { className: "page-info", children: [
145
+ "of ",
146
+ totalPages || "..."
147
+ ] }),
148
+ /* @__PURE__ */ jsx2(
149
+ "button",
150
+ {
151
+ className: "toolbar-button",
152
+ onClick: onNextPage,
153
+ disabled: currentPage >= totalPages,
154
+ title: "Next Page",
155
+ children: /* @__PURE__ */ jsx2(ChevronRightIcon, { fontSize: "small" })
156
+ }
157
+ ),
158
+ /* @__PURE__ */ jsx2(
159
+ "button",
160
+ {
161
+ className: "toolbar-button",
162
+ onClick: onLastPage,
163
+ disabled: currentPage >= totalPages,
164
+ title: "Last Page",
165
+ children: /* @__PURE__ */ jsx2(LastPageIcon, { fontSize: "small" })
166
+ }
167
+ )
168
+ ] })
169
+ ] }),
170
+ showZoomControls && /* @__PURE__ */ jsxs(Fragment, { children: [
171
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-separator" }),
172
+ /* @__PURE__ */ jsxs("div", { className: "toolbar-section", children: [
173
+ /* @__PURE__ */ jsx2(
174
+ "button",
175
+ {
176
+ className: "toolbar-button",
177
+ onClick: onZoomOut,
178
+ title: "Zoom Out",
179
+ children: /* @__PURE__ */ jsx2(ZoomOutIcon, { fontSize: "small" })
180
+ }
181
+ ),
182
+ /* @__PURE__ */ jsxs("span", { className: "zoom-display", children: [
183
+ zoom,
184
+ "%"
185
+ ] }),
186
+ /* @__PURE__ */ jsx2(
187
+ "button",
188
+ {
189
+ className: "toolbar-button",
190
+ onClick: onZoomIn,
191
+ title: "Zoom In",
192
+ children: /* @__PURE__ */ jsx2(ZoomInIcon, { fontSize: "small" })
193
+ }
194
+ ),
195
+ /* @__PURE__ */ jsx2(
196
+ "button",
197
+ {
198
+ className: "toolbar-button",
199
+ onClick: onFitToWidth,
200
+ title: "Fit to Width",
201
+ children: /* @__PURE__ */ jsx2(AspectRatioIcon, { fontSize: "small" })
202
+ }
203
+ ),
204
+ /* @__PURE__ */ jsx2(
205
+ "button",
206
+ {
207
+ className: "toolbar-button",
208
+ onClick: onFitToPage,
209
+ title: "Fit to Page",
210
+ children: /* @__PURE__ */ jsx2(FitScreenIcon, { fontSize: "small" })
211
+ }
212
+ )
213
+ ] })
214
+ ] }),
215
+ showRotation && /* @__PURE__ */ jsxs(Fragment, { children: [
216
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-separator" }),
217
+ /* @__PURE__ */ jsxs("div", { className: "toolbar-section", children: [
218
+ /* @__PURE__ */ jsx2(
219
+ "button",
220
+ {
221
+ className: "toolbar-button",
222
+ onClick: onRotateLeft,
223
+ disabled: disabledRotateLeft,
224
+ title: "Rotate Counterclockwise",
225
+ children: /* @__PURE__ */ jsx2(RotateLeftIcon, { fontSize: "small" })
226
+ }
227
+ ),
228
+ /* @__PURE__ */ jsx2(
229
+ "button",
230
+ {
231
+ className: "toolbar-button",
232
+ onClick: onRotateRight,
233
+ disabled: disabledRotateRight,
234
+ title: "Rotate Clockwise",
235
+ children: /* @__PURE__ */ jsx2(RotateRightIcon, { fontSize: "small" })
236
+ }
237
+ )
238
+ ] })
239
+ ] }),
240
+ showSearch && /* @__PURE__ */ jsxs(Fragment, { children: [
241
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-separator" }),
242
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-section", children: /* @__PURE__ */ jsx2(
243
+ "button",
244
+ {
245
+ className: "toolbar-button",
246
+ onClick: onToggleSidebar,
247
+ title: "Search in PDF",
248
+ style: {
249
+ backgroundColor: isSidebarOpen ? "#e3f2fd" : "transparent",
250
+ color: isSidebarOpen ? "#1976d2" : "inherit"
251
+ },
252
+ children: /* @__PURE__ */ jsx2(SearchIcon, { fontSize: "small" })
253
+ }
254
+ ) })
255
+ ] }),
256
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-separator" }),
257
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-section", children: /* @__PURE__ */ jsx2(
258
+ "button",
259
+ {
260
+ className: "toolbar-button",
261
+ onClick: onToggleFullScreen,
262
+ title: "Fullscreen",
263
+ children: /* @__PURE__ */ jsx2(FullscreenIcon, { fontSize: "small" })
264
+ }
265
+ ) }),
266
+ (showMetadata || showProperties || showDownload || showPrint || showTags) && /* @__PURE__ */ jsxs(Fragment, { children: [
267
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-separator" }),
268
+ /* @__PURE__ */ jsxs("div", { className: "toolbar-section", children: [
269
+ showDownload && /* @__PURE__ */ jsx2(
270
+ "button",
271
+ {
272
+ className: "toolbar-button",
273
+ onClick: onDownloadClick,
274
+ disabled: disabledDownload,
275
+ title: "Download PDF",
276
+ children: /* @__PURE__ */ jsx2(DownloadIcon, { fontSize: "small" })
277
+ }
278
+ ),
279
+ showPrint && /* @__PURE__ */ jsx2(
280
+ "button",
281
+ {
282
+ className: "toolbar-button",
283
+ onClick: onPrintClick,
284
+ disabled: disabledPrint,
285
+ title: "Print PDF",
286
+ children: /* @__PURE__ */ jsx2(PrintIcon, { fontSize: "small" })
287
+ }
288
+ ),
289
+ showMetadata && /* @__PURE__ */ jsx2(
290
+ "button",
291
+ {
292
+ className: "toolbar-button",
293
+ onClick: onMetadataClick,
294
+ disabled: disabledMetadata,
295
+ title: "Document Metadata",
296
+ children: /* @__PURE__ */ jsx2(DescriptionIcon, { fontSize: "small" })
297
+ }
298
+ ),
299
+ showProperties && /* @__PURE__ */ jsx2(
300
+ "button",
301
+ {
302
+ className: "toolbar-button",
303
+ onClick: onPropertiesClick,
304
+ disabled: disabledProperties,
305
+ title: "Document Properties",
306
+ children: /* @__PURE__ */ jsx2(InfoIcon, { fontSize: "small" })
307
+ }
308
+ ),
309
+ showTags && /* @__PURE__ */ jsx2(
310
+ "button",
311
+ {
312
+ className: "toolbar-button",
313
+ onClick: onTagsClick,
314
+ disabled: disabledTags,
315
+ title: "Document Tags",
316
+ children: /* @__PURE__ */ jsx2(LocalOffer, { fontSize: "small" })
317
+ }
318
+ )
319
+ ] })
320
+ ] })
321
+ ] });
322
+ }
323
+ );
324
+ PDFToolbar.displayName = "PDFToolbar";
325
+
326
+ // src/components/viewers/pdf/PDFHeader.tsx
327
+ import React3 from "react";
328
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
329
+ var PDFHeader = React3.memo(({ fileName, fileExtension }) => {
330
+ return /* @__PURE__ */ jsxs2("div", { className: "pdf-viewer-header", children: [
331
+ /* @__PURE__ */ jsx3(FileIcon_default, { ext: fileExtension, size: 26 }),
332
+ /* @__PURE__ */ jsx3("div", { className: "header-file-name", title: fileName, children: fileName })
333
+ ] });
334
+ });
335
+ PDFHeader.displayName = "PDFHeader";
336
+
337
+ // src/components/viewers/pdf/SearchSidebar.tsx
338
+ import { useState, useLayoutEffect, useEffect, useRef } from "react";
339
+ import {
340
+ Box,
341
+ Typography,
342
+ TextField,
343
+ IconButton,
344
+ InputAdornment,
345
+ Divider,
346
+ CircularProgress
347
+ } from "@mui/material";
348
+ import SearchIcon2 from "@mui/icons-material/Search";
349
+ import CloseIcon from "@mui/icons-material/Close";
350
+ import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
351
+ import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
352
+ import ClearIcon from "@mui/icons-material/Clear";
353
+ import FindInPageIcon from "@mui/icons-material/FindInPage";
354
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
355
+ var SearchSidebar = ({
356
+ isOpen,
357
+ onClose,
358
+ onSearch,
359
+ onSearchResultClick,
360
+ onNextResult,
361
+ onPreviousResult,
362
+ currentResultIndex,
363
+ totalResults,
364
+ searchKeyword,
365
+ searchResults = [],
366
+ isSearching = false,
367
+ isSyntheticResults = false
368
+ }) => {
369
+ const [searchTerm, setSearchTerm] = useState(searchKeyword || "");
370
+ const [hasSearched, setHasSearched] = useState(false);
371
+ const contentRef = useRef(null);
372
+ useEffect(() => {
373
+ if (searchKeyword && searchKeyword !== searchTerm) {
374
+ setSearchTerm(searchKeyword);
375
+ }
376
+ }, [searchKeyword]);
377
+ useLayoutEffect(() => {
378
+ const element = contentRef.current;
379
+ if (!element) return;
380
+ const handleMouseMove = (e) => {
381
+ const rect = element.getBoundingClientRect();
382
+ const distanceFromRight = rect.right - e.clientX;
383
+ const distanceFromBottom = rect.bottom - e.clientY;
384
+ if (distanceFromRight <= 15 || distanceFromBottom <= 15) {
385
+ element.classList.add("scrollbar-hover");
386
+ } else {
387
+ element.classList.remove("scrollbar-hover");
388
+ }
389
+ };
390
+ const handleMouseLeave = () => element.classList.remove("scrollbar-hover");
391
+ element.addEventListener("mousemove", handleMouseMove);
392
+ element.addEventListener("mouseleave", handleMouseLeave);
393
+ return () => {
394
+ element.removeEventListener("mousemove", handleMouseMove);
395
+ element.removeEventListener("mouseleave", handleMouseLeave);
396
+ };
397
+ }, []);
398
+ useLayoutEffect(() => {
399
+ const style = document.createElement("style");
400
+ style.id = "search-sidebar-scrollbar";
401
+ style.textContent = `
402
+ @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+Tamil:wght@400;600&family=Noto+Sans+Devanagari:wght@400;600&display=swap');
403
+
404
+ .search-sidebar-content::-webkit-scrollbar {
405
+ width: 12px;
406
+ height: 12px;
407
+ }
408
+ .search-sidebar-content::-webkit-scrollbar-track {
409
+ background-color: transparent;
410
+ }
411
+ .search-sidebar-content::-webkit-scrollbar-thumb {
412
+ background-color: rgba(128, 128, 128, 0.3);
413
+ border-radius: 8px;
414
+ border: 4px solid transparent;
415
+ background-clip: padding-box;
416
+ transition: all 0.15s ease;
417
+ }
418
+ .search-sidebar-content.scrollbar-hover::-webkit-scrollbar-thumb {
419
+ background-color: rgba(128, 128, 128, 0.5);
420
+ border: 2px solid transparent;
421
+ }
422
+ .search-sidebar-content::-webkit-scrollbar-thumb:active {
423
+ background-color: rgba(25, 118, 210, 0.8);
424
+ border: 1px solid transparent;
425
+ }
426
+
427
+ @media (prefers-color-scheme: dark) {
428
+ .search-sidebar-content::-webkit-scrollbar-thumb {
429
+ background-color: rgba(255, 255, 255, 0.2);
430
+ }
431
+ .search-sidebar-content.scrollbar-hover::-webkit-scrollbar-thumb {
432
+ background-color: rgba(255, 255, 255, 0.35);
433
+ }
434
+ }
435
+
436
+ /* Tamil font support for search results */
437
+ .search-result-text {
438
+ font-family: 'Noto Sans Tamil', 'Noto Sans Devanagari', Arial, sans-serif !important;
439
+ }
440
+ `;
441
+ document.head.appendChild(style);
442
+ return () => {
443
+ const el = document.getElementById("search-sidebar-scrollbar");
444
+ if (el) el.remove();
445
+ };
446
+ }, []);
447
+ useLayoutEffect(() => {
448
+ setSearchTerm(searchKeyword || "");
449
+ if (searchKeyword || searchResults.length > 0) {
450
+ setHasSearched(true);
451
+ }
452
+ }, [searchKeyword, searchResults]);
453
+ const handleSearchSubmit = (e) => {
454
+ if (e) e.preventDefault();
455
+ if (searchTerm.trim()) {
456
+ setHasSearched(true);
457
+ onSearch(searchTerm.trim());
458
+ }
459
+ };
460
+ const handleSearchChange = (e) => {
461
+ const value = e.target.value;
462
+ setSearchTerm(value);
463
+ if (!value.trim()) {
464
+ setHasSearched(false);
465
+ onSearch("");
466
+ }
467
+ };
468
+ const handleClearSearch = () => {
469
+ setSearchTerm("");
470
+ setHasSearched(false);
471
+ onSearch("");
472
+ };
473
+ const resultsByPage = searchResults.reduce((acc, result) => {
474
+ if (!acc[result.pageNumber]) {
475
+ acc[result.pageNumber] = [];
476
+ }
477
+ acc[result.pageNumber].push(result);
478
+ return acc;
479
+ }, {});
480
+ const highlightText = (text, keyword) => {
481
+ if (!keyword) return text;
482
+ const textString = typeof text === "string" ? text : String(text || "");
483
+ if (!textString) return text;
484
+ try {
485
+ const escapedKeyword = keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
486
+ const regex = new RegExp(`(${escapedKeyword})`, "gi");
487
+ const parts = textString.split(regex);
488
+ return parts.map(
489
+ (part, index) => regex.test(part) ? /* @__PURE__ */ jsx4(
490
+ Box,
491
+ {
492
+ component: "span",
493
+ sx: {
494
+ color: "primary.main",
495
+ fontWeight: 600,
496
+ fontSize: "inherit"
497
+ },
498
+ children: part
499
+ },
500
+ index
501
+ ) : part
502
+ );
503
+ } catch (error) {
504
+ return textString;
505
+ }
506
+ };
507
+ if (!isOpen) return null;
508
+ return /* @__PURE__ */ jsxs3(
509
+ Box,
510
+ {
511
+ sx: {
512
+ display: "flex",
513
+ flexDirection: "column",
514
+ height: "100%",
515
+ width: "320px",
516
+ backgroundColor: "background.paper",
517
+ borderLeft: "1px solid",
518
+ borderColor: "divider",
519
+ overflow: "hidden"
520
+ },
521
+ children: [
522
+ /* @__PURE__ */ jsxs3(Box, { sx: { px: 3, py: 2.5, backgroundColor: "background.default" }, children: [
523
+ /* @__PURE__ */ jsxs3(Box, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 2 }, children: [
524
+ /* @__PURE__ */ jsx4(Typography, { variant: "h6", sx: { fontSize: "1.125rem", fontWeight: 600, color: "text.primary" }, children: "Search" }),
525
+ /* @__PURE__ */ jsx4(
526
+ IconButton,
527
+ {
528
+ size: "small",
529
+ onClick: onClose,
530
+ sx: {
531
+ color: "text.secondary",
532
+ padding: "6px"
533
+ },
534
+ children: /* @__PURE__ */ jsx4(CloseIcon, { fontSize: "small" })
535
+ }
536
+ )
537
+ ] }),
538
+ /* @__PURE__ */ jsx4("form", { onSubmit: handleSearchSubmit, children: /* @__PURE__ */ jsx4(
539
+ TextField,
540
+ {
541
+ fullWidth: true,
542
+ size: "medium",
543
+ placeholder: "Search in document...",
544
+ value: searchTerm,
545
+ onChange: handleSearchChange,
546
+ autoComplete: "off",
547
+ InputProps: {
548
+ startAdornment: /* @__PURE__ */ jsx4(InputAdornment, { position: "start", children: /* @__PURE__ */ jsx4(SearchIcon2, { sx: { color: "text.disabled", fontSize: 20 } }) }),
549
+ endAdornment: searchTerm && /* @__PURE__ */ jsx4(InputAdornment, { position: "end", children: /* @__PURE__ */ jsx4(
550
+ IconButton,
551
+ {
552
+ size: "small",
553
+ onClick: handleClearSearch,
554
+ sx: {
555
+ color: "text.secondary",
556
+ padding: "4px",
557
+ "&:hover": {
558
+ backgroundColor: "action.hover"
559
+ }
560
+ },
561
+ children: /* @__PURE__ */ jsx4(ClearIcon, { sx: { fontSize: 18 } })
562
+ }
563
+ ) })
564
+ },
565
+ sx: {
566
+ "& .MuiOutlinedInput-root": {
567
+ fontSize: "0.9375rem",
568
+ backgroundColor: "background.paper",
569
+ borderRadius: "8px",
570
+ "& fieldset": {
571
+ borderColor: "divider"
572
+ },
573
+ "&.Mui-focused fieldset": {
574
+ borderColor: "primary.main",
575
+ borderWidth: "2px"
576
+ }
577
+ },
578
+ "& .MuiInputBase-input": {
579
+ padding: "10px 14px"
580
+ }
581
+ }
582
+ }
583
+ ) }),
584
+ totalResults > 0 && /* @__PURE__ */ jsxs3(
585
+ Box,
586
+ {
587
+ sx: {
588
+ display: "flex",
589
+ alignItems: "center",
590
+ justifyContent: "space-between",
591
+ mt: 2,
592
+ pt: 2,
593
+ borderTop: "1px solid",
594
+ borderColor: "divider"
595
+ },
596
+ children: [
597
+ /* @__PURE__ */ jsxs3(Typography, { variant: "body2", sx: { color: "text.secondary", fontSize: "0.875rem", fontWeight: 500 }, children: [
598
+ currentResultIndex + 1,
599
+ " of ",
600
+ totalResults,
601
+ " results"
602
+ ] }),
603
+ /* @__PURE__ */ jsxs3(Box, { sx: { display: "flex", alignItems: "center", gap: 0.5 }, children: [
604
+ /* @__PURE__ */ jsx4(
605
+ IconButton,
606
+ {
607
+ size: "small",
608
+ onClick: onPreviousResult,
609
+ disabled: currentResultIndex <= 0,
610
+ sx: {
611
+ color: currentResultIndex <= 0 ? "text.disabled" : "primary.main",
612
+ padding: "6px",
613
+ borderRadius: "6px",
614
+ border: "1px solid",
615
+ borderColor: currentResultIndex <= 0 ? "divider" : "primary.main"
616
+ },
617
+ children: /* @__PURE__ */ jsx4(KeyboardArrowUpIcon, { sx: { fontSize: 20 } })
618
+ }
619
+ ),
620
+ /* @__PURE__ */ jsx4(
621
+ IconButton,
622
+ {
623
+ size: "small",
624
+ onClick: onNextResult,
625
+ disabled: currentResultIndex >= totalResults - 1,
626
+ sx: {
627
+ color: currentResultIndex >= totalResults - 1 ? "text.disabled" : "primary.main",
628
+ padding: "6px",
629
+ borderRadius: "6px",
630
+ border: "1px solid",
631
+ borderColor: currentResultIndex >= totalResults - 1 ? "divider" : "primary.main"
632
+ },
633
+ children: /* @__PURE__ */ jsx4(KeyboardArrowDownIcon, { sx: { fontSize: 20 } })
634
+ }
635
+ )
636
+ ] })
637
+ ]
638
+ }
639
+ )
640
+ ] }),
641
+ /* @__PURE__ */ jsx4(Divider, {}),
642
+ /* @__PURE__ */ jsxs3(Box, { ref: contentRef, className: "search-sidebar-content", sx: {
643
+ flex: 1,
644
+ overflow: "auto",
645
+ backgroundColor: "background.default"
646
+ }, children: [
647
+ !searchTerm && !hasSearched && /* @__PURE__ */ jsxs3(Box, { sx: { p: 4, textAlign: "center", mt: 6 }, children: [
648
+ /* @__PURE__ */ jsx4(
649
+ Box,
650
+ {
651
+ sx: {
652
+ width: 80,
653
+ height: 80,
654
+ borderRadius: "50%",
655
+ backgroundColor: "action.hover",
656
+ display: "flex",
657
+ alignItems: "center",
658
+ justifyContent: "center",
659
+ margin: "0 auto",
660
+ mb: 3
661
+ },
662
+ children: /* @__PURE__ */ jsx4(SearchIcon2, { sx: { fontSize: 40, color: "text.disabled" } })
663
+ }
664
+ ),
665
+ /* @__PURE__ */ jsx4(Typography, { variant: "body1", sx: { color: "text.primary", fontWeight: 500, mb: 1 }, children: "Search in Document" }),
666
+ /* @__PURE__ */ jsx4(Typography, { variant: "body2", sx: { color: "text.secondary", lineHeight: 1.6 }, children: "Enter keywords to find text within the PDF document" })
667
+ ] }),
668
+ searchTerm && !hasSearched && !isSearching && /* @__PURE__ */ jsxs3(Box, { sx: { p: 4, textAlign: "center", mt: 6 }, children: [
669
+ /* @__PURE__ */ jsx4(
670
+ Box,
671
+ {
672
+ sx: {
673
+ width: 80,
674
+ height: 80,
675
+ borderRadius: "50%",
676
+ backgroundColor: "primary.light",
677
+ display: "flex",
678
+ alignItems: "center",
679
+ justifyContent: "center",
680
+ margin: "0 auto",
681
+ mb: 3,
682
+ opacity: 0.2
683
+ },
684
+ children: /* @__PURE__ */ jsx4(FindInPageIcon, { sx: { fontSize: 40, color: "primary.main" } })
685
+ }
686
+ ),
687
+ /* @__PURE__ */ jsx4(Typography, { variant: "body1", sx: { color: "text.primary", fontWeight: 500, mb: 1 }, children: "Ready to Search" }),
688
+ /* @__PURE__ */ jsx4(Typography, { variant: "body2", sx: { color: "text.secondary", mb: 2, lineHeight: 1.6 }, children: "Press Enter to find" }),
689
+ /* @__PURE__ */ jsxs3(
690
+ Typography,
691
+ {
692
+ variant: "body2",
693
+ sx: {
694
+ color: "white",
695
+ fontWeight: 600,
696
+ backgroundColor: (theme) => theme.palette.mode === "dark" ? "rgba(144, 202, 249, 0.16)" : "primary.light",
697
+ padding: "6px 16px",
698
+ borderRadius: "16px",
699
+ display: "inline-block",
700
+ opacity: 0.9
701
+ },
702
+ children: [
703
+ '"',
704
+ searchTerm,
705
+ '"'
706
+ ]
707
+ }
708
+ )
709
+ ] }),
710
+ isSearching && /* @__PURE__ */ jsxs3(Box, { sx: { p: 4, textAlign: "center", mt: 6 }, children: [
711
+ /* @__PURE__ */ jsx4(
712
+ Box,
713
+ {
714
+ sx: {
715
+ display: "flex",
716
+ alignItems: "center",
717
+ justifyContent: "center",
718
+ margin: "0 auto",
719
+ mb: 3
720
+ },
721
+ children: /* @__PURE__ */ jsx4(CircularProgress, { size: 60, thickness: 4 })
722
+ }
723
+ ),
724
+ /* @__PURE__ */ jsx4(Typography, { variant: "body1", sx: { color: "text.primary", fontWeight: 500, mb: 1 }, children: "Searching..." }),
725
+ /* @__PURE__ */ jsxs3(Typography, { variant: "body2", sx: { color: "text.secondary", lineHeight: 1.6 }, children: [
726
+ 'Finding matches for "',
727
+ searchTerm,
728
+ '"'
729
+ ] })
730
+ ] }),
731
+ hasSearched && totalResults === 0 && !isSearching && /* @__PURE__ */ jsxs3(Box, { sx: { p: 4, textAlign: "center", mt: 6 }, children: [
732
+ /* @__PURE__ */ jsx4(
733
+ Box,
734
+ {
735
+ sx: {
736
+ width: 80,
737
+ height: 80,
738
+ borderRadius: "50%",
739
+ backgroundColor: (theme) => theme.palette.mode === "dark" ? "rgba(255, 152, 0, 0.12)" : "warning.light",
740
+ display: "flex",
741
+ alignItems: "center",
742
+ justifyContent: "center",
743
+ margin: "0 auto",
744
+ mb: 3,
745
+ opacity: 0.6
746
+ },
747
+ children: /* @__PURE__ */ jsx4(SearchIcon2, { sx: { fontSize: 40, color: "warning.main" } })
748
+ }
749
+ ),
750
+ /* @__PURE__ */ jsx4(Typography, { variant: "body1", sx: { color: "text.primary", fontWeight: 500, mb: 1 }, children: "No Results Found" }),
751
+ /* @__PURE__ */ jsxs3(Typography, { variant: "body2", sx: { color: "text.secondary", lineHeight: 1.6 }, children: [
752
+ "No matches found for ",
753
+ /* @__PURE__ */ jsxs3("strong", { children: [
754
+ '"',
755
+ searchTerm,
756
+ '"'
757
+ ] })
758
+ ] })
759
+ ] }),
760
+ totalResults > 0 && /* @__PURE__ */ jsx4(Box, { sx: { p: 2 }, children: Object.keys(resultsByPage).sort((a, b) => parseInt(a) - parseInt(b)).map((pageNum) => {
761
+ const pageNumber = parseInt(pageNum);
762
+ const pageResults = resultsByPage[pageNumber];
763
+ return /* @__PURE__ */ jsxs3(Box, { sx: { mb: 3 }, children: [
764
+ /* @__PURE__ */ jsxs3(
765
+ Typography,
766
+ {
767
+ variant: "subtitle2",
768
+ sx: {
769
+ color: "text.secondary",
770
+ mb: 1.5,
771
+ px: 1,
772
+ fontSize: "0.8125rem",
773
+ fontWeight: 600,
774
+ textTransform: "uppercase",
775
+ letterSpacing: "0.5px"
776
+ },
777
+ children: [
778
+ "Page ",
779
+ pageNumber
780
+ ]
781
+ }
782
+ ),
783
+ pageResults.map((result, index) => /* @__PURE__ */ jsx4(
784
+ Box,
785
+ {
786
+ onClick: () => onSearchResultClick(result.pageNumber, result.index),
787
+ sx: {
788
+ p: 2,
789
+ mx: 1,
790
+ mb: 1.5,
791
+ borderRadius: "8px",
792
+ border: "2px solid",
793
+ borderColor: result.index === currentResultIndex ? "primary.main" : "divider",
794
+ backgroundColor: "background.paper",
795
+ cursor: "pointer",
796
+ transition: "all 0.2s ease",
797
+ boxShadow: (theme) => theme.palette.mode === "dark" ? "0 1px 3px rgba(0, 0, 0, 0.3)" : "0 1px 3px rgba(0, 0, 0, 0.05)",
798
+ "&:hover": {
799
+ borderColor: "primary.main",
800
+ boxShadow: (theme) => theme.palette.mode === "dark" ? "0 2px 8px rgba(255, 255, 255, 0.15)" : "0 2px 8px rgba(0, 0, 0, 0.1)",
801
+ transform: "translateY(-1px)"
802
+ }
803
+ },
804
+ children: /* @__PURE__ */ jsx4(
805
+ Typography,
806
+ {
807
+ variant: "body2",
808
+ className: "search-result-text",
809
+ sx: {
810
+ fontSize: "0.875rem",
811
+ lineHeight: 1.6,
812
+ color: result.index === currentResultIndex ? "text.primary" : "text.secondary"
813
+ },
814
+ children: highlightText(result.context, searchTerm)
815
+ }
816
+ )
817
+ },
818
+ index
819
+ ))
820
+ ] }, pageNumber);
821
+ }) })
822
+ ] })
823
+ ]
824
+ }
825
+ );
826
+ };
827
+
828
+ // src/components/viewers/pdf/PasswordDialog.tsx
829
+ import { useState as useState2, useEffect as useEffect2 } from "react";
830
+ import {
831
+ Dialog,
832
+ DialogTitle,
833
+ DialogContent,
834
+ DialogActions,
835
+ TextField as TextField2,
836
+ Button,
837
+ Typography as Typography2,
838
+ IconButton as IconButton2,
839
+ InputAdornment as InputAdornment2,
840
+ Box as Box2,
841
+ Alert
842
+ } from "@mui/material";
843
+ import CloseIcon2 from "@mui/icons-material/Close";
844
+ import LockIcon from "@mui/icons-material/Lock";
845
+ import VisibilityIcon from "@mui/icons-material/Visibility";
846
+ import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
847
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
848
+ var PasswordDialog = ({
849
+ open,
850
+ fileName,
851
+ onSubmit,
852
+ onCancel,
853
+ error
854
+ }) => {
855
+ const [password, setPassword] = useState2("");
856
+ const [showPassword, setShowPassword] = useState2(false);
857
+ useEffect2(() => {
858
+ if (open) {
859
+ setPassword("");
860
+ setShowPassword(false);
861
+ }
862
+ }, [open]);
863
+ const handleSubmit = (e) => {
864
+ e.preventDefault();
865
+ if (password.trim()) {
866
+ onSubmit(password);
867
+ }
868
+ };
869
+ const handleTogglePasswordVisibility = () => {
870
+ setShowPassword(!showPassword);
871
+ };
872
+ const handleKeyPress = (e) => {
873
+ if (e.key === "Enter" && password.trim()) {
874
+ handleSubmit(e);
875
+ }
876
+ };
877
+ return /* @__PURE__ */ jsxs4(
878
+ Dialog,
879
+ {
880
+ open,
881
+ onClose: onCancel,
882
+ maxWidth: "sm",
883
+ fullWidth: true,
884
+ PaperProps: {
885
+ sx: {
886
+ borderRadius: 2
887
+ }
888
+ },
889
+ children: [
890
+ /* @__PURE__ */ jsx5(DialogTitle, { sx: { pb: 1 }, children: /* @__PURE__ */ jsxs4(Box2, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
891
+ /* @__PURE__ */ jsxs4(Box2, { sx: { display: "flex", alignItems: "center", gap: 1.5 }, children: [
892
+ /* @__PURE__ */ jsx5(
893
+ Box2,
894
+ {
895
+ sx: {
896
+ width: 40,
897
+ height: 40,
898
+ borderRadius: "50%",
899
+ backgroundColor: "primary.light",
900
+ display: "flex",
901
+ alignItems: "center",
902
+ justifyContent: "center",
903
+ opacity: 0.9
904
+ },
905
+ children: /* @__PURE__ */ jsx5(LockIcon, { sx: { color: "white", fontSize: 20 } })
906
+ }
907
+ ),
908
+ /* @__PURE__ */ jsx5(Typography2, { variant: "h6", component: "div", sx: { fontWeight: 600 }, children: "Password Protected" })
909
+ ] }),
910
+ /* @__PURE__ */ jsx5(
911
+ IconButton2,
912
+ {
913
+ size: "small",
914
+ onClick: onCancel,
915
+ sx: { color: "text.secondary" },
916
+ "aria-label": "Close dialog",
917
+ children: /* @__PURE__ */ jsx5(CloseIcon2, { fontSize: "small" })
918
+ }
919
+ )
920
+ ] }) }),
921
+ /* @__PURE__ */ jsxs4(DialogContent, { sx: { pt: 2 }, children: [
922
+ /* @__PURE__ */ jsxs4(Typography2, { variant: "body2", sx: { color: "text.secondary", mb: 3 }, children: [
923
+ "This PDF is password protected. Please enter the password to view",
924
+ " ",
925
+ fileName && /* @__PURE__ */ jsxs4("strong", { children: [
926
+ '"',
927
+ fileName,
928
+ '"'
929
+ ] })
930
+ ] }),
931
+ error && /* @__PURE__ */ jsx5(Alert, { severity: "error", sx: { mb: 2 }, children: error }),
932
+ /* @__PURE__ */ jsx5("form", { onSubmit: handleSubmit, children: /* @__PURE__ */ jsx5(
933
+ TextField2,
934
+ {
935
+ fullWidth: true,
936
+ autoFocus: true,
937
+ type: showPassword ? "text" : "password",
938
+ label: "Password",
939
+ placeholder: "Enter password",
940
+ value: password,
941
+ onChange: (e) => setPassword(e.target.value),
942
+ onKeyPress: handleKeyPress,
943
+ error: Boolean(error),
944
+ InputProps: {
945
+ endAdornment: /* @__PURE__ */ jsx5(InputAdornment2, { position: "end", children: /* @__PURE__ */ jsx5(
946
+ IconButton2,
947
+ {
948
+ onClick: handleTogglePasswordVisibility,
949
+ edge: "end",
950
+ size: "small",
951
+ "aria-label": showPassword ? "Hide password" : "Show password",
952
+ children: showPassword ? /* @__PURE__ */ jsx5(VisibilityOffIcon, {}) : /* @__PURE__ */ jsx5(VisibilityIcon, {})
953
+ }
954
+ ) })
955
+ },
956
+ sx: {
957
+ "& .MuiOutlinedInput-root": {
958
+ borderRadius: 2
959
+ }
960
+ }
961
+ }
962
+ ) })
963
+ ] }),
964
+ /* @__PURE__ */ jsxs4(DialogActions, { sx: { px: 3, pb: 3, pt: 2 }, children: [
965
+ /* @__PURE__ */ jsx5(
966
+ Button,
967
+ {
968
+ onClick: onCancel,
969
+ variant: "outlined",
970
+ sx: {
971
+ borderRadius: 2,
972
+ textTransform: "none",
973
+ px: 3
974
+ },
975
+ children: "Cancel"
976
+ }
977
+ ),
978
+ /* @__PURE__ */ jsx5(
979
+ Button,
980
+ {
981
+ onClick: handleSubmit,
982
+ variant: "contained",
983
+ disabled: !password.trim(),
984
+ sx: {
985
+ borderRadius: 2,
986
+ textTransform: "none",
987
+ px: 3,
988
+ boxShadow: 2
989
+ },
990
+ children: "Unlock PDF"
991
+ }
992
+ )
993
+ ] })
994
+ ]
995
+ }
996
+ );
997
+ };
998
+
999
+ // src/components/viewers/PDFViewer.tsx
1000
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1001
+ var PDFViewerContent = forwardRef(
1002
+ (props, ref) => {
1003
+ const {
1004
+ file,
1005
+ onLoad,
1006
+ onError,
1007
+ fileName,
1008
+ showPageCount = true,
1009
+ showPageNavigation = true,
1010
+ showZoomControls = true,
1011
+ showRotation = true,
1012
+ showDownload = true,
1013
+ showPrint = true,
1014
+ showSearch = true,
1015
+ showMetadata = true,
1016
+ showProperties = true,
1017
+ showTags = true,
1018
+ onMetadataClick,
1019
+ onPropertiesClick,
1020
+ onTagsClick,
1021
+ onDownloadClick,
1022
+ onPrintClick,
1023
+ initialSearchText,
1024
+ initialSearchPages
1025
+ } = props;
1026
+ const [pdfBuffer, setPdfBuffer] = useState3(null);
1027
+ const [state, setState] = useState3("idle");
1028
+ const [error, setError] = useState3(null);
1029
+ const pdfViewerRef = useRef2(null);
1030
+ const resolvedFileName = useMemo(() => {
1031
+ if (fileName) return fileName;
1032
+ if (file instanceof File) return file.name;
1033
+ if (typeof file === "string") {
1034
+ const urlParts = file.split("/");
1035
+ return urlParts[urlParts.length - 1] || "document.pdf";
1036
+ }
1037
+ return "document.pdf";
1038
+ }, [file, fileName]);
1039
+ const fileExtension = useMemo(
1040
+ () => getFileExtension(resolvedFileName),
1041
+ [resolvedFileName]
1042
+ );
1043
+ const [currentPage, setCurrentPage] = useState3(1);
1044
+ const [totalPages, setTotalPages] = useState3(0);
1045
+ const [zoom, setZoom] = useState3(100);
1046
+ const [searchQuery, setSearchQuery] = useState3("");
1047
+ const [isSearching, setIsSearching] = useState3(false);
1048
+ const [pdfContainer, setPdfContainer] = useState3(null);
1049
+ const [isSidebarOpen, setIsSidebarOpen] = useState3(false);
1050
+ const [searchResults, setSearchResults] = useState3([]);
1051
+ const [currentSearchResultIndex, setCurrentSearchResultIndex] = useState3(0);
1052
+ const [totalSearchResults, setTotalSearchResults] = useState3(0);
1053
+ const [autoExecuteSearch, setAutoExecuteSearch] = useState3(
1054
+ !!initialSearchText
1055
+ );
1056
+ const [isFullScreen, setIsFullScreen] = useState3(false);
1057
+ const containerRef = useRef2(null);
1058
+ const [isPasswordDialogOpen, setIsPasswordDialogOpen] = useState3(false);
1059
+ const [passwordError, setPasswordError] = useState3("");
1060
+ const [passwordResolve, setPasswordResolve] = useState3(null);
1061
+ const hasExecutedInitialSearch = useRef2(false);
1062
+ const handleToggleFullScreen = useCallback(() => {
1063
+ if (!isFullScreen && containerRef.current?.requestFullscreen) {
1064
+ containerRef.current.requestFullscreen();
1065
+ setIsFullScreen(true);
1066
+ } else if (isFullScreen && document.exitFullscreen) {
1067
+ document.exitFullscreen();
1068
+ setIsFullScreen(false);
1069
+ }
1070
+ }, [isFullScreen]);
1071
+ const handleSidebarClose = useCallback(() => {
1072
+ setIsSidebarOpen(false);
1073
+ setSearchQuery("");
1074
+ setSearchResults([]);
1075
+ setTotalSearchResults(0);
1076
+ setCurrentSearchResultIndex(0);
1077
+ pdfViewerRef.current?.search.stopSearch();
1078
+ }, []);
1079
+ const toolbar = mergeToolbarConfig({
1080
+ showDownload,
1081
+ showPrint,
1082
+ showMetadata,
1083
+ showProperties,
1084
+ showTags,
1085
+ showRotation,
1086
+ onDownloadClick,
1087
+ onPrintClick,
1088
+ onMetadataClick,
1089
+ onPropertiesClick,
1090
+ onTagsClick,
1091
+ toolbarActions: props.toolbarActions
1092
+ });
1093
+ const toolbarHandlers = useMemo(
1094
+ () => ({
1095
+ handleZoomIn: () => {
1096
+ pdfViewerRef.current?.zoom.zoomIn();
1097
+ requestAnimationFrame(() => {
1098
+ const zoomValue = pdfViewerRef.current?.zoom.getZoom();
1099
+ if (typeof zoomValue === "number") {
1100
+ setZoom(Math.round(zoomValue * 100));
1101
+ }
1102
+ });
1103
+ },
1104
+ handleZoomOut: () => {
1105
+ pdfViewerRef.current?.zoom.zoomOut();
1106
+ requestAnimationFrame(() => {
1107
+ const zoomValue = pdfViewerRef.current?.zoom.getZoom();
1108
+ if (typeof zoomValue === "number") {
1109
+ setZoom(Math.round(zoomValue * 100));
1110
+ }
1111
+ });
1112
+ },
1113
+ handleFitToWidth: () => {
1114
+ pdfViewerRef.current?.zoom.fitToWidth();
1115
+ requestAnimationFrame(() => {
1116
+ const zoomValue = pdfViewerRef.current?.zoom.getZoom();
1117
+ if (typeof zoomValue === "number") {
1118
+ setZoom(Math.round(zoomValue * 100));
1119
+ }
1120
+ });
1121
+ },
1122
+ handleFitToPage: () => {
1123
+ pdfViewerRef.current?.zoom.fitToPage();
1124
+ requestAnimationFrame(() => {
1125
+ const zoomValue = pdfViewerRef.current?.zoom.getZoom();
1126
+ if (typeof zoomValue === "number") {
1127
+ setZoom(Math.round(zoomValue * 100));
1128
+ }
1129
+ });
1130
+ },
1131
+ handlePreviousPage: () => {
1132
+ pdfViewerRef.current?.navigation.previousPage();
1133
+ requestAnimationFrame(() => {
1134
+ const current = pdfViewerRef.current?.navigation.getCurrentPage() || 1;
1135
+ setCurrentPage(current);
1136
+ });
1137
+ },
1138
+ handleNextPage: () => {
1139
+ pdfViewerRef.current?.navigation.nextPage();
1140
+ requestAnimationFrame(() => {
1141
+ const current = pdfViewerRef.current?.navigation.getCurrentPage() || 1;
1142
+ setCurrentPage(current);
1143
+ });
1144
+ },
1145
+ handleFirstPage: () => {
1146
+ pdfViewerRef.current?.navigation.goToFirstPage();
1147
+ requestAnimationFrame(() => {
1148
+ const current = pdfViewerRef.current?.navigation.getCurrentPage() || 1;
1149
+ setCurrentPage(current);
1150
+ });
1151
+ },
1152
+ handleLastPage: () => {
1153
+ pdfViewerRef.current?.navigation.goToLastPage();
1154
+ requestAnimationFrame(() => {
1155
+ const current = pdfViewerRef.current?.navigation.getCurrentPage() || 1;
1156
+ setCurrentPage(current);
1157
+ });
1158
+ },
1159
+ toggleSidebar: () => {
1160
+ if (isSidebarOpen) {
1161
+ handleSidebarClose();
1162
+ } else {
1163
+ setIsSidebarOpen(true);
1164
+ }
1165
+ },
1166
+ handlePageInput: (e) => {
1167
+ const value = e.target.value;
1168
+ if (/^\d*$/.test(value)) {
1169
+ return;
1170
+ }
1171
+ const page = parseInt(value, 10);
1172
+ if (!isNaN(page) && page >= 1 && (totalPages === 0 || page <= totalPages)) {
1173
+ pdfViewerRef.current?.navigation.goToPage(page);
1174
+ setCurrentPage(page);
1175
+ }
1176
+ },
1177
+ handlePageInputKeyPress: (e) => {
1178
+ if (e.key === "Enter") {
1179
+ const value = e.target.value;
1180
+ const page = parseInt(value, 10);
1181
+ if (!isNaN(page) && page >= 1 && (totalPages === 0 || page <= totalPages)) {
1182
+ pdfViewerRef.current?.navigation.goToPage(page);
1183
+ setCurrentPage(page);
1184
+ }
1185
+ }
1186
+ },
1187
+ handleRotateLeft: () => {
1188
+ pdfViewerRef.current?.rotate?.rotateBackward();
1189
+ },
1190
+ handleRotateRight: () => {
1191
+ pdfViewerRef.current?.rotate?.rotateForward();
1192
+ },
1193
+ handleToggleFullScreen
1194
+ }),
1195
+ [isSidebarOpen, totalPages, handleToggleFullScreen]
1196
+ );
1197
+ useEffect3(() => {
1198
+ console.log(
1199
+ "came",
1200
+ initialSearchText,
1201
+ pdfViewerRef.current,
1202
+ hasExecutedInitialSearch.current,
1203
+ "state:",
1204
+ state,
1205
+ "totalPages:",
1206
+ totalPages
1207
+ );
1208
+ if (!initialSearchText || hasExecutedInitialSearch.current) return;
1209
+ const isPDFReady = state === "ready";
1210
+ const isPagesInitialized = totalPages > 0;
1211
+ const isViewerAvailable = !!pdfViewerRef.current;
1212
+ const isSearchAPIReady = !!pdfViewerRef.current?.search?.searchText;
1213
+ const canExecuteSearch = isPDFReady && isPagesInitialized && isViewerAvailable && isSearchAPIReady;
1214
+ if (!canExecuteSearch) return;
1215
+ hasExecutedInitialSearch.current = true;
1216
+ const SEARCH_INITIALIZATION_DELAY = 100;
1217
+ setTimeout(() => {
1218
+ if (!pdfViewerRef.current?.search?.searchText) {
1219
+ console.warn(
1220
+ "Search API became unavailable, skipping initial search"
1221
+ );
1222
+ hasExecutedInitialSearch.current = false;
1223
+ return;
1224
+ }
1225
+ requestAnimationFrame(() => {
1226
+ requestAnimationFrame(() => {
1227
+ setIsSidebarOpen(true);
1228
+ handleSidebarSearch(initialSearchText, initialSearchPages);
1229
+ setAutoExecuteSearch(false);
1230
+ });
1231
+ });
1232
+ }, SEARCH_INITIALIZATION_DELAY);
1233
+ }, [
1234
+ state,
1235
+ totalPages,
1236
+ pdfViewerRef.current,
1237
+ initialSearchText,
1238
+ initialSearchPages
1239
+ ]);
1240
+ useEffect3(() => {
1241
+ setSearchQuery("");
1242
+ setSearchResults([]);
1243
+ setCurrentSearchResultIndex(0);
1244
+ setTotalSearchResults(0);
1245
+ setIsSearching(false);
1246
+ setIsSidebarOpen(false);
1247
+ hasExecutedInitialSearch.current = false;
1248
+ setCurrentPage(1);
1249
+ setTotalPages(0);
1250
+ setZoom(100);
1251
+ setState("idle");
1252
+ setError(null);
1253
+ setPdfBuffer(null);
1254
+ }, [file]);
1255
+ useEffect3(() => {
1256
+ if (state !== "ready") return;
1257
+ const container = document.querySelector(
1258
+ '[data-pdf-viewer], .embedpdf-viewport, [role="document"]'
1259
+ );
1260
+ if (container) {
1261
+ setPdfContainer(container);
1262
+ return;
1263
+ }
1264
+ const observer = new MutationObserver(() => {
1265
+ const foundContainer = document.querySelector(
1266
+ '[data-pdf-viewer], .embedpdf-viewport, [role="document"]'
1267
+ );
1268
+ if (foundContainer) {
1269
+ setPdfContainer(foundContainer);
1270
+ observer.disconnect();
1271
+ }
1272
+ });
1273
+ observer.observe(document.body, { childList: true, subtree: true });
1274
+ return () => observer.disconnect();
1275
+ }, [state]);
1276
+ useEffect3(() => {
1277
+ if (state !== "ready" || totalPages > 0) return;
1278
+ const initializePageCount = async () => {
1279
+ const waitForViewer = async (maxAttempts = 10) => {
1280
+ for (let i = 0; i < maxAttempts; i++) {
1281
+ if (pdfViewerRef.current) return pdfViewerRef.current;
1282
+ await new Promise(
1283
+ (resolve) => requestAnimationFrame(
1284
+ () => setTimeout(resolve, Math.min(100 * Math.pow(2, i), 1e3))
1285
+ )
1286
+ );
1287
+ }
1288
+ return null;
1289
+ };
1290
+ const viewer = await waitForViewer();
1291
+ if (!viewer) return;
1292
+ await new Promise((resolve) => requestAnimationFrame(resolve));
1293
+ try {
1294
+ const count = viewer.navigation?.getTotalPages?.();
1295
+ if (count && count > 1) {
1296
+ setTotalPages(count);
1297
+ return;
1298
+ }
1299
+ } catch (e) {
1300
+ }
1301
+ try {
1302
+ const results = await viewer.search?.searchText?.("e");
1303
+ if (results?.results && results.results.length > 0) {
1304
+ const pageIndices = results.results.map((m) => m.pageIndex).filter((idx) => typeof idx === "number");
1305
+ const count = Math.max(...pageIndices) + 1;
1306
+ viewer.search?.stopSearch?.();
1307
+ setTotalPages(count);
1308
+ return;
1309
+ }
1310
+ } catch (error2) {
1311
+ }
1312
+ await new Promise((resolve) => setTimeout(resolve, 200));
1313
+ try {
1314
+ const selectors = [
1315
+ "[data-page-index]",
1316
+ "[data-page-number]",
1317
+ ".embedpdf-page",
1318
+ '[role="article"]',
1319
+ "canvas[data-page]",
1320
+ ".react-pdf__Page"
1321
+ ];
1322
+ for (const selector of selectors) {
1323
+ const pages = document.querySelectorAll(selector);
1324
+ if (pages.length > 0) {
1325
+ setTotalPages(pages.length);
1326
+ return;
1327
+ }
1328
+ }
1329
+ } catch (error2) {
1330
+ }
1331
+ try {
1332
+ const count = viewer.navigation?.getTotalPages?.();
1333
+ if (count && count > 0) {
1334
+ setTotalPages(count);
1335
+ return;
1336
+ }
1337
+ } catch (e) {
1338
+ }
1339
+ console.warn(
1340
+ "Could not determine total pages, using fallback value of 1"
1341
+ );
1342
+ setTotalPages(1);
1343
+ };
1344
+ initializePageCount();
1345
+ }, [state, totalPages]);
1346
+ useEffect3(() => {
1347
+ if (state === "ready" && pdfViewerRef.current) {
1348
+ const updateInfo = () => {
1349
+ const current = pdfViewerRef.current?.navigation.getCurrentPage() || 1;
1350
+ const total = pdfViewerRef.current?.navigation.getTotalPages() || 0;
1351
+ const zoomValue = pdfViewerRef.current?.zoom.getZoom();
1352
+ const currentSearchState = pdfViewerRef.current?.search.getSearchState();
1353
+ setCurrentPage(current);
1354
+ if (total > 0 && total !== totalPages) {
1355
+ setTotalPages(total);
1356
+ }
1357
+ if (typeof zoomValue === "number") {
1358
+ setZoom(Math.round(zoomValue * 100));
1359
+ }
1360
+ };
1361
+ updateInfo();
1362
+ const interval = setInterval(updateInfo, 300);
1363
+ return () => clearInterval(interval);
1364
+ }
1365
+ }, [state, totalPages]);
1366
+ useImperativeHandle(
1367
+ ref,
1368
+ () => ({
1369
+ zoomIn: () => {
1370
+ pdfViewerRef.current?.zoom.zoomIn();
1371
+ updateZoomDisplay();
1372
+ },
1373
+ zoomOut: () => {
1374
+ pdfViewerRef.current?.zoom.zoomOut();
1375
+ updateZoomDisplay();
1376
+ },
1377
+ setZoom: (level) => {
1378
+ pdfViewerRef.current?.zoom.setZoom(level);
1379
+ updateZoomDisplay();
1380
+ },
1381
+ resetZoom: () => {
1382
+ pdfViewerRef.current?.zoom.resetZoom();
1383
+ updateZoomDisplay();
1384
+ },
1385
+ getZoom: () => {
1386
+ const zoom2 = pdfViewerRef.current?.zoom.getZoom();
1387
+ return typeof zoom2 === "number" ? zoom2 : 1;
1388
+ },
1389
+ goToPage: (page) => {
1390
+ pdfViewerRef.current?.navigation.goToPage(page);
1391
+ setCurrentPage(page);
1392
+ },
1393
+ getCurrentPage: () => pdfViewerRef.current?.navigation.getCurrentPage() || 1,
1394
+ getTotalPages: () => pdfViewerRef.current?.navigation.getTotalPages() || 0,
1395
+ nextPage: () => {
1396
+ pdfViewerRef.current?.navigation.nextPage();
1397
+ updatePageDisplay();
1398
+ },
1399
+ previousPage: () => {
1400
+ pdfViewerRef.current?.navigation.previousPage();
1401
+ updatePageDisplay();
1402
+ },
1403
+ goToFirstPage: () => {
1404
+ pdfViewerRef.current?.navigation.goToFirstPage();
1405
+ updatePageDisplay();
1406
+ },
1407
+ goToLastPage: () => {
1408
+ pdfViewerRef.current?.navigation.goToLastPage();
1409
+ updatePageDisplay();
1410
+ },
1411
+ searchText: async (keyword) => {
1412
+ setIsSearching(true);
1413
+ const results = await pdfViewerRef.current?.search.searchText(
1414
+ keyword
1415
+ );
1416
+ setIsSearching(false);
1417
+ setSearchQuery(keyword);
1418
+ return results;
1419
+ },
1420
+ nextResult: () => {
1421
+ const index = pdfViewerRef.current?.search.nextResult() || -1;
1422
+ return index;
1423
+ },
1424
+ previousResult: () => {
1425
+ const index = pdfViewerRef.current?.search.previousResult() || -1;
1426
+ return index;
1427
+ },
1428
+ goToResult: (index) => pdfViewerRef.current?.search.goToResult(index) || -1,
1429
+ stopSearch: () => {
1430
+ pdfViewerRef.current?.search.stopSearch();
1431
+ setSearchQuery("");
1432
+ },
1433
+ getSearchState: () => pdfViewerRef.current?.search.getSearchState() || null,
1434
+ getSelectedText: () => pdfViewerRef.current?.selection.getSelectedText() || "",
1435
+ clearSelection: () => pdfViewerRef.current?.selection.clearSelection(),
1436
+ rotateForward: () => pdfViewerRef.current?.rotate?.rotateForward(),
1437
+ rotateBackward: () => pdfViewerRef.current?.rotate?.rotateBackward(),
1438
+ getRotation: () => pdfViewerRef.current?.rotate?.getRotation() || 0
1439
+ }),
1440
+ []
1441
+ );
1442
+ const updatePageDisplay = () => {
1443
+ requestAnimationFrame(() => {
1444
+ const current = pdfViewerRef.current?.navigation.getCurrentPage() || 1;
1445
+ setCurrentPage(current);
1446
+ });
1447
+ };
1448
+ const updateZoomDisplay = () => {
1449
+ requestAnimationFrame(() => {
1450
+ const zoomValue = pdfViewerRef.current?.zoom.getZoom();
1451
+ if (typeof zoomValue === "number") {
1452
+ setZoom(Math.round(zoomValue * 100));
1453
+ }
1454
+ });
1455
+ };
1456
+ const handleSearch = async () => {
1457
+ if (!searchQuery.trim()) return;
1458
+ setIsSearching(true);
1459
+ const results = await pdfViewerRef.current?.search.searchText(
1460
+ searchQuery
1461
+ );
1462
+ setIsSearching(false);
1463
+ if (results?.results && Array.isArray(results.results) && results.results.length > 0) {
1464
+ const formattedResults = formatSearchResults(results.results);
1465
+ updateSearchState(formattedResults);
1466
+ } else {
1467
+ clearSearchResults();
1468
+ }
1469
+ };
1470
+ const handleSearchKeyPress = (e) => {
1471
+ if (e.key === "Enter") {
1472
+ handleSearch();
1473
+ }
1474
+ };
1475
+ const handleSidebarSearch = async (keyword, pageNumbers) => {
1476
+ setSearchQuery(keyword);
1477
+ if (!keyword.trim()) {
1478
+ setSearchResults([]);
1479
+ setTotalSearchResults(0);
1480
+ setCurrentSearchResultIndex(0);
1481
+ pdfViewerRef.current?.search.stopSearch();
1482
+ return;
1483
+ }
1484
+ if (!pdfViewerRef.current?.search?.searchText) {
1485
+ console.warn("Search functionality not yet available");
1486
+ return;
1487
+ }
1488
+ setIsSearching(true);
1489
+ try {
1490
+ const results = await pdfViewerRef.current.search.searchText(keyword);
1491
+ console.log("Search completed:", results);
1492
+ setIsSearching(false);
1493
+ const hasValidResults = results?.results && Array.isArray(results.results) && results.results.length > 0;
1494
+ if (hasValidResults) {
1495
+ const formattedResults = formatSearchResults(results.results);
1496
+ updateSearchState(formattedResults);
1497
+ navigateToFirstResult(formattedResults);
1498
+ } else if (pageNumbers && pageNumbers.length > 0) {
1499
+ const fallbackResults = createFallbackResults(pageNumbers, keyword);
1500
+ updateSearchState(fallbackResults);
1501
+ navigateToPage(pageNumbers[0]);
1502
+ } else {
1503
+ clearSearchResults();
1504
+ }
1505
+ } catch (error2) {
1506
+ console.error("Search failed:", error2);
1507
+ setIsSearching(false);
1508
+ clearSearchResults();
1509
+ }
1510
+ };
1511
+ const formatSearchResults = (results) => {
1512
+ return results.map((result, index) => {
1513
+ let textContent = "";
1514
+ let contextContent = "";
1515
+ if (result.context && typeof result.context === "object") {
1516
+ const { before = "", match = "", after = "" } = result.context;
1517
+ textContent = match;
1518
+ contextContent = `${before}${match}${after}`;
1519
+ } else if (typeof result === "string") {
1520
+ textContent = result;
1521
+ contextContent = result;
1522
+ } else {
1523
+ textContent = String(result.match || result.text || "");
1524
+ contextContent = textContent;
1525
+ }
1526
+ return {
1527
+ pageNumber: (result.pageIndex ?? result.pageNumber ?? 0) + 1,
1528
+ text: textContent,
1529
+ context: contextContent,
1530
+ index
1531
+ };
1532
+ });
1533
+ };
1534
+ const createFallbackResults = (pageNumbers, keyword) => {
1535
+ return pageNumbers.map((pageNum, index) => ({
1536
+ pageNumber: pageNum,
1537
+ text: keyword,
1538
+ context: `"${keyword}" found on this page ${pageNum}`,
1539
+ index
1540
+ }));
1541
+ };
1542
+ const updateSearchState = (results) => {
1543
+ setSearchResults(results);
1544
+ setTotalSearchResults(results.length);
1545
+ setCurrentSearchResultIndex(0);
1546
+ };
1547
+ const clearSearchResults = () => {
1548
+ setSearchResults([]);
1549
+ setTotalSearchResults(0);
1550
+ setCurrentSearchResultIndex(0);
1551
+ };
1552
+ const navigateToFirstResult = (results) => {
1553
+ if (results.length > 0) {
1554
+ navigateToPage(results[0].pageNumber);
1555
+ }
1556
+ };
1557
+ const navigateToPage = (pageNumber) => {
1558
+ requestAnimationFrame(() => {
1559
+ pdfViewerRef.current?.navigation.goToPage(pageNumber);
1560
+ setCurrentPage(pageNumber);
1561
+ });
1562
+ };
1563
+ const handleSearchResultClick = (pageNumber, resultIndex) => {
1564
+ pdfViewerRef.current?.navigation.goToPage(pageNumber);
1565
+ setCurrentSearchResultIndex(resultIndex);
1566
+ setCurrentPage(pageNumber);
1567
+ pdfViewerRef.current?.search.goToResult(resultIndex);
1568
+ };
1569
+ const handleNextSearchResult = () => {
1570
+ if (currentSearchResultIndex < totalSearchResults - 1) {
1571
+ const nextIndex = currentSearchResultIndex + 1;
1572
+ setCurrentSearchResultIndex(nextIndex);
1573
+ pdfViewerRef.current?.search.nextResult();
1574
+ if (searchResults[nextIndex]) {
1575
+ const pageNumber = searchResults[nextIndex].pageNumber;
1576
+ pdfViewerRef.current?.navigation.goToPage(pageNumber);
1577
+ setCurrentPage(pageNumber);
1578
+ }
1579
+ }
1580
+ };
1581
+ const handlePreviousSearchResult = () => {
1582
+ if (currentSearchResultIndex > 0) {
1583
+ const prevIndex = currentSearchResultIndex - 1;
1584
+ setCurrentSearchResultIndex(prevIndex);
1585
+ pdfViewerRef.current?.search.previousResult();
1586
+ if (searchResults[prevIndex]) {
1587
+ const pageNumber = searchResults[prevIndex].pageNumber;
1588
+ pdfViewerRef.current?.navigation.goToPage(pageNumber);
1589
+ setCurrentPage(pageNumber);
1590
+ }
1591
+ }
1592
+ };
1593
+ useEffect3(() => {
1594
+ if (!file) {
1595
+ setState("error");
1596
+ setError("No file provided");
1597
+ return;
1598
+ }
1599
+ const loadPDF = async () => {
1600
+ try {
1601
+ setState("loading");
1602
+ setError(null);
1603
+ let arrayBuffer;
1604
+ if (file instanceof File) {
1605
+ arrayBuffer = await file.arrayBuffer();
1606
+ } else if (typeof file === "string") {
1607
+ const response = await fetch(file);
1608
+ if (!response.ok) {
1609
+ throw new Error(`Failed to load PDF: ${response.statusText}`);
1610
+ }
1611
+ arrayBuffer = await response.arrayBuffer();
1612
+ } else if (file instanceof ArrayBuffer) {
1613
+ arrayBuffer = file;
1614
+ } else {
1615
+ throw new Error("Unsupported file type");
1616
+ }
1617
+ setPdfBuffer(arrayBuffer);
1618
+ setState("ready");
1619
+ onLoad?.();
1620
+ } catch (err) {
1621
+ const errorMessage = err.message || "Failed to load PDF";
1622
+ setState("error");
1623
+ setError(errorMessage);
1624
+ onError?.(err);
1625
+ }
1626
+ };
1627
+ loadPDF();
1628
+ }, [file, onLoad, onError]);
1629
+ const handlePasswordRequest = useCallback(
1630
+ async (fileName2) => {
1631
+ return new Promise((resolve) => {
1632
+ setPasswordResolve(() => resolve);
1633
+ setPasswordError("");
1634
+ setIsPasswordDialogOpen(true);
1635
+ });
1636
+ },
1637
+ []
1638
+ );
1639
+ const handlePasswordSubmit = useCallback(
1640
+ (password) => {
1641
+ if (passwordResolve) {
1642
+ passwordResolve(password);
1643
+ setPasswordResolve(null);
1644
+ setIsPasswordDialogOpen(false);
1645
+ setPasswordError("");
1646
+ }
1647
+ },
1648
+ [passwordResolve]
1649
+ );
1650
+ const handlePasswordCancel = useCallback(() => {
1651
+ if (passwordResolve) {
1652
+ passwordResolve(null);
1653
+ setPasswordResolve(null);
1654
+ setIsPasswordDialogOpen(false);
1655
+ setPasswordError("");
1656
+ }
1657
+ }, [passwordResolve]);
1658
+ if (state === "loading") {
1659
+ return /* @__PURE__ */ jsxs5(
1660
+ "div",
1661
+ {
1662
+ style: {
1663
+ display: "flex",
1664
+ flexDirection: "column",
1665
+ alignItems: "center",
1666
+ justifyContent: "center",
1667
+ height: "100%",
1668
+ gap: "16px"
1669
+ },
1670
+ children: [
1671
+ /* @__PURE__ */ jsx6(
1672
+ "div",
1673
+ {
1674
+ className: "spinner",
1675
+ style: {
1676
+ width: "48px",
1677
+ height: "48px",
1678
+ border: "4px solid #f3f3f3",
1679
+ borderTop: "4px solid #3498db",
1680
+ borderRadius: "50%",
1681
+ animation: "spin 1s linear infinite"
1682
+ }
1683
+ }
1684
+ ),
1685
+ /* @__PURE__ */ jsx6("p", { children: "Loading PDF..." }),
1686
+ /* @__PURE__ */ jsx6("style", { children: `
1687
+ @keyframes spin {
1688
+ 0% { transform: rotate(0deg); }
1689
+ 100% { transform: rotate(360deg); }
1690
+ }
1691
+ ` })
1692
+ ]
1693
+ }
1694
+ );
1695
+ }
1696
+ if (state === "error" || error) {
1697
+ return /* @__PURE__ */ jsx6(
1698
+ "div",
1699
+ {
1700
+ style: {
1701
+ display: "flex",
1702
+ flexDirection: "column",
1703
+ alignItems: "center",
1704
+ justifyContent: "center",
1705
+ height: "100%",
1706
+ padding: "24px"
1707
+ },
1708
+ children: /* @__PURE__ */ jsxs5(
1709
+ "div",
1710
+ {
1711
+ style: {
1712
+ maxWidth: "400px",
1713
+ padding: "16px",
1714
+ backgroundColor: "#fee",
1715
+ border: "1px solid #fcc",
1716
+ borderRadius: "4px"
1717
+ },
1718
+ children: [
1719
+ /* @__PURE__ */ jsx6("h3", { style: { marginTop: 0 }, children: "Failed to Load PDF" }),
1720
+ /* @__PURE__ */ jsx6("p", { children: error || "Unknown error occurred" })
1721
+ ]
1722
+ }
1723
+ )
1724
+ }
1725
+ );
1726
+ }
1727
+ if (!pdfBuffer || state !== "ready") {
1728
+ return /* @__PURE__ */ jsx6(
1729
+ "div",
1730
+ {
1731
+ style: {
1732
+ display: "flex",
1733
+ alignItems: "center",
1734
+ justifyContent: "center",
1735
+ height: "100%"
1736
+ },
1737
+ children: /* @__PURE__ */ jsx6("p", { children: "Preparing PDF..." })
1738
+ }
1739
+ );
1740
+ }
1741
+ return /* @__PURE__ */ jsxs5("div", { ref: containerRef, className: "pdf-viewer-container", children: [
1742
+ /* @__PURE__ */ jsx6("style", { children: toolbarStyles }),
1743
+ /* @__PURE__ */ jsx6(PDFHeader, { fileName: resolvedFileName, fileExtension }),
1744
+ /* @__PURE__ */ jsx6(
1745
+ PDFToolbar,
1746
+ {
1747
+ currentPage,
1748
+ totalPages,
1749
+ zoom,
1750
+ isSidebarOpen,
1751
+ showPageNavigation,
1752
+ showPageCount,
1753
+ showZoomControls,
1754
+ showSearch,
1755
+ showRotation: !toolbar.isHidden("rotation"),
1756
+ showMetadata: !toolbar.isHidden("metadata"),
1757
+ showProperties: !toolbar.isHidden("properties"),
1758
+ showDownload: !toolbar.isHidden("download"),
1759
+ showPrint: !toolbar.isHidden("print"),
1760
+ showTags: !toolbar.isHidden("tags"),
1761
+ disabledRotateLeft: toolbar.isDisabled("rotateLeft"),
1762
+ disabledRotateRight: toolbar.isDisabled("rotateRight"),
1763
+ disabledMetadata: toolbar.isDisabled("metadata"),
1764
+ disabledTags: toolbar.isDisabled("tags"),
1765
+ disabledProperties: toolbar.isDisabled("properties"),
1766
+ disabledDownload: toolbar.isDisabled("download"),
1767
+ disabledPrint: toolbar.isDisabled("print"),
1768
+ onFirstPage: toolbarHandlers.handleFirstPage,
1769
+ onPreviousPage: toolbarHandlers.handlePreviousPage,
1770
+ onNextPage: toolbarHandlers.handleNextPage,
1771
+ onLastPage: toolbarHandlers.handleLastPage,
1772
+ onPageInput: toolbarHandlers.handlePageInput,
1773
+ onPageInputKeyPress: toolbarHandlers.handlePageInputKeyPress,
1774
+ onZoomIn: toolbarHandlers.handleZoomIn,
1775
+ onZoomOut: toolbarHandlers.handleZoomOut,
1776
+ onFitToWidth: toolbarHandlers.handleFitToWidth,
1777
+ onFitToPage: toolbarHandlers.handleFitToPage,
1778
+ onToggleSidebar: toolbarHandlers.toggleSidebar,
1779
+ onToggleFullScreen: toolbarHandlers.handleToggleFullScreen,
1780
+ onRotateLeft: toolbarHandlers.handleRotateLeft,
1781
+ onRotateRight: toolbarHandlers.handleRotateRight,
1782
+ onDownloadClick: toolbar.getHandler("download", onDownloadClick),
1783
+ onPrintClick: toolbar.getHandler("print", onPrintClick),
1784
+ onMetadataClick: toolbar.getHandler("metadata", onMetadataClick),
1785
+ onPropertiesClick: toolbar.getHandler(
1786
+ "properties",
1787
+ onPropertiesClick
1788
+ ),
1789
+ onTagsClick: toolbar.getHandler("tags", onTagsClick)
1790
+ }
1791
+ ),
1792
+ /* @__PURE__ */ jsxs5("div", { className: "pdf-viewer-main", children: [
1793
+ /* @__PURE__ */ jsx6("div", { className: "pdf-viewer-viewer-area", children: /* @__PURE__ */ jsx6(
1794
+ StablePDFViewer,
1795
+ {
1796
+ pdfBuffer,
1797
+ onPasswordRequest: handlePasswordRequest,
1798
+ pdfViewerRef
1799
+ }
1800
+ ) }),
1801
+ /* @__PURE__ */ jsx6(
1802
+ SearchSidebar,
1803
+ {
1804
+ isOpen: isSidebarOpen,
1805
+ onClose: handleSidebarClose,
1806
+ onSearch: handleSidebarSearch,
1807
+ onSearchResultClick: handleSearchResultClick,
1808
+ onNextResult: handleNextSearchResult,
1809
+ onPreviousResult: handlePreviousSearchResult,
1810
+ currentResultIndex: currentSearchResultIndex,
1811
+ totalResults: totalSearchResults,
1812
+ searchKeyword: searchQuery,
1813
+ searchResults,
1814
+ isSearching
1815
+ }
1816
+ )
1817
+ ] }),
1818
+ /* @__PURE__ */ jsx6(
1819
+ PasswordDialog,
1820
+ {
1821
+ open: isPasswordDialogOpen,
1822
+ fileName: resolvedFileName,
1823
+ onSubmit: handlePasswordSubmit,
1824
+ onCancel: handlePasswordCancel,
1825
+ error: passwordError
1826
+ }
1827
+ )
1828
+ ] });
1829
+ }
1830
+ );
1831
+ PDFViewerContent.displayName = "PDFViewerContent";
1832
+ var PDFViewer = forwardRef(
1833
+ (props, ref) => {
1834
+ return /* @__PURE__ */ jsx6(PDFViewerContent, { ...props, sourceDescription: "doc.pdf", ref });
1835
+ }
1836
+ );
1837
+ PDFViewer.displayName = "PDFViewer";
1838
+
1839
+ export {
1840
+ PDFViewer
1841
+ };
1842
+ //# sourceMappingURL=chunk-TMAHQICY.mjs.map