@papyrus-sdk/ui-react-native 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,2912 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // index.ts
30
+ var index_exports = {};
31
+ __export(index_exports, {
32
+ AnnotationEditor: () => AnnotationEditor_default,
33
+ BottomBar: () => BottomBar_default,
34
+ PageRenderer: () => PageRenderer_default,
35
+ RightSheet: () => RightSheet_default,
36
+ SettingsSheet: () => SettingsSheet_default,
37
+ ToolDock: () => ToolDock_default,
38
+ Topbar: () => Topbar_default,
39
+ Viewer: () => Viewer_default
40
+ });
41
+ module.exports = __toCommonJS(index_exports);
42
+
43
+ // components/Viewer.tsx
44
+ var import_react2 = require("react");
45
+ var import_react_native2 = require("react-native");
46
+ var import_core2 = require("@papyrus-sdk/core");
47
+
48
+ // components/PageRenderer.tsx
49
+ var import_react = require("react");
50
+ var import_react_native = require("react-native");
51
+ var import_core = require("@papyrus-sdk/core");
52
+ var import_engine_native = require("@papyrus-sdk/engine-native");
53
+ var import_jsx_runtime = require("react/jsx-runtime");
54
+ var PageRenderer = ({
55
+ engine,
56
+ pageIndex,
57
+ scale = 1,
58
+ PageViewComponent = import_engine_native.PapyrusPageView,
59
+ availableWidth,
60
+ horizontalPadding = 16,
61
+ spacing = 24
62
+ }) => {
63
+ const viewRef = (0, import_react.useRef)(null);
64
+ const [layout, setLayout] = (0, import_react.useState)({ width: 0, height: 0 });
65
+ const [pageSize, setPageSize] = (0, import_react.useState)(null);
66
+ const { width: windowWidth } = (0, import_react_native.useWindowDimensions)();
67
+ const isAndroid = import_react_native.Platform.OS === "android";
68
+ const isNative = import_react_native.Platform.OS === "android" || import_react_native.Platform.OS === "ios";
69
+ const {
70
+ zoom,
71
+ rotation,
72
+ pageTheme,
73
+ annotations,
74
+ annotationColor,
75
+ addAnnotation,
76
+ setDocumentState,
77
+ accentColor,
78
+ selectedAnnotationId,
79
+ setSelectedAnnotation,
80
+ removeAnnotation,
81
+ searchResults,
82
+ activeSearchIndex,
83
+ setSelectionActive
84
+ } = (0, import_core.useViewerStore)();
85
+ const pageAnnotations = (0, import_react.useMemo)(
86
+ () => annotations.filter((ann) => ann.pageIndex === pageIndex),
87
+ [annotations, pageIndex]
88
+ );
89
+ const pageSearchHits = (0, import_react.useMemo)(
90
+ () => searchResults.map((result, index) => ({ result, index })).filter(({ result }) => result.pageIndex === pageIndex),
91
+ [searchResults, pageIndex]
92
+ );
93
+ const [selectionRect, setSelectionRect] = (0, import_react.useState)(null);
94
+ const [selectionRects, setSelectionRects] = (0, import_react.useState)([]);
95
+ const [selectionBounds, setSelectionBounds] = (0, import_react.useState)(null);
96
+ const [selectionText, setSelectionText] = (0, import_react.useState)("");
97
+ const [isSelecting, setIsSelecting] = (0, import_react.useState)(false);
98
+ const selectionStart = (0, import_react.useRef)(null);
99
+ const selectionRectRef = (0, import_react.useRef)(null);
100
+ const selectionBoundsRef = (0, import_react.useRef)(null);
101
+ const selectionBoundsStart = (0, import_react.useRef)(null);
102
+ const lastTapRef = (0, import_react.useRef)(null);
103
+ const pinchRef = (0, import_react.useRef)(null);
104
+ (0, import_react.useEffect)(() => {
105
+ if (!layout.width || !layout.height) return;
106
+ const viewTag = (0, import_react_native.findNodeHandle)(viewRef.current);
107
+ if (viewTag) {
108
+ const renderScale = isAndroid ? scale / Math.max(zoom, 0.5) : scale;
109
+ void engine.renderPage(pageIndex, viewTag, renderScale);
110
+ }
111
+ }, [engine, pageIndex, scale, zoom, rotation, layout.width, layout.height, isAndroid]);
112
+ (0, import_react.useEffect)(() => {
113
+ let active = true;
114
+ const loadDimensions = async () => {
115
+ const dims = await engine.getPageDimensions(pageIndex);
116
+ if (!active) return;
117
+ if (dims.width > 0 && dims.height > 0) {
118
+ setPageSize({ width: dims.width, height: dims.height });
119
+ }
120
+ };
121
+ void loadDimensions();
122
+ return () => {
123
+ active = false;
124
+ };
125
+ }, [engine, pageIndex]);
126
+ const handleLayout = (event) => {
127
+ const { width, height } = event.nativeEvent.layout;
128
+ if (width !== layout.width || height !== layout.height) {
129
+ setLayout({ width, height });
130
+ }
131
+ };
132
+ const addAnnotationAt = (x, y, width, height, type) => {
133
+ addAnnotation({
134
+ id: Math.random().toString(36).slice(2, 9),
135
+ pageIndex,
136
+ type,
137
+ rect: { x, y, width, height },
138
+ color: annotationColor,
139
+ content: type === "text" || type === "comment" ? "" : void 0,
140
+ createdAt: Date.now()
141
+ });
142
+ };
143
+ const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
144
+ const getBoundsFromRects = (rects) => {
145
+ let minX = 1;
146
+ let minY = 1;
147
+ let maxX = 0;
148
+ let maxY = 0;
149
+ rects.forEach((rect) => {
150
+ minX = Math.min(minX, rect.x);
151
+ minY = Math.min(minY, rect.y);
152
+ maxX = Math.max(maxX, rect.x + rect.width);
153
+ maxY = Math.max(maxY, rect.y + rect.height);
154
+ });
155
+ if (maxX <= minX || maxY <= minY) return null;
156
+ return {
157
+ x: clamp(minX, 0, 1),
158
+ y: clamp(minY, 0, 1),
159
+ width: clamp(maxX - minX, 0, 1),
160
+ height: clamp(maxY - minY, 0, 1)
161
+ };
162
+ };
163
+ const clearSelection = () => {
164
+ setSelectionRect(null);
165
+ selectionRectRef.current = null;
166
+ setSelectionRects([]);
167
+ setSelectionBounds(null);
168
+ selectionBoundsRef.current = null;
169
+ setSelectionText("");
170
+ setIsSelecting(false);
171
+ selectionStart.current = null;
172
+ selectionBoundsStart.current = null;
173
+ setSelectionActive(false);
174
+ };
175
+ const applySelectionResult = (selection) => {
176
+ if (!selection || !selection.rects || selection.rects.length === 0) {
177
+ clearSelection();
178
+ return;
179
+ }
180
+ setSelectionRects(selection.rects);
181
+ setSelectionText(selection.text || "");
182
+ const bounds = getBoundsFromRects(selection.rects);
183
+ if (!bounds) {
184
+ clearSelection();
185
+ return;
186
+ }
187
+ setSelectionBounds(bounds);
188
+ selectionBoundsRef.current = bounds;
189
+ setSelectionActive(true);
190
+ };
191
+ const selectFromBounds = async (bounds) => {
192
+ const selection = await engine.selectText?.(pageIndex, bounds);
193
+ applySelectionResult(selection ?? null);
194
+ };
195
+ const selectAtPoint = async (x, y) => {
196
+ if (!layout.width || !layout.height) return;
197
+ const size = 26;
198
+ const half = size / 2;
199
+ const left = clamp(x - half, 0, Math.max(0, layout.width - size));
200
+ const top = clamp(y - half, 0, Math.max(0, layout.height - size));
201
+ const bounds = {
202
+ x: left / layout.width,
203
+ y: top / layout.height,
204
+ width: size / layout.width,
205
+ height: size / layout.height
206
+ };
207
+ await selectFromBounds(bounds);
208
+ };
209
+ const getTouchDistance = (touches) => {
210
+ if (touches.length < 2) return 0;
211
+ const [a, b] = touches;
212
+ return Math.hypot(b.pageX - a.pageX, b.pageY - a.pageY);
213
+ };
214
+ const shouldHandlePinch = (touches) => isNative && touches.length === 2;
215
+ const handlePinchStart = (touches) => {
216
+ if (!shouldHandlePinch(touches)) return;
217
+ pinchRef.current = { distance: getTouchDistance(touches), zoom };
218
+ };
219
+ const handlePinchMove = (touches) => {
220
+ if (!shouldHandlePinch(touches) || !pinchRef.current) return;
221
+ const distance = getTouchDistance(touches);
222
+ if (!distance) return;
223
+ const scale2 = distance / pinchRef.current.distance;
224
+ const nextZoom = clamp(pinchRef.current.zoom * scale2, 0.5, 4);
225
+ setDocumentState({ zoom: nextZoom });
226
+ engine.setZoom(nextZoom);
227
+ };
228
+ const handlePinchEnd = () => {
229
+ pinchRef.current = null;
230
+ };
231
+ const handlePress = (event) => {
232
+ if (!layout.width || !layout.height) return;
233
+ if (selectionRects.length > 0 || selectionBounds) {
234
+ clearSelection();
235
+ return;
236
+ }
237
+ setSelectedAnnotation(null);
238
+ if (!isNative) return;
239
+ const { locationX, locationY } = event.nativeEvent;
240
+ const now = Date.now();
241
+ const lastTap = lastTapRef.current;
242
+ lastTapRef.current = { time: now, x: locationX, y: locationY };
243
+ if (!lastTap) return;
244
+ const timeDelta = now - lastTap.time;
245
+ const distance = Math.hypot(locationX - lastTap.x, locationY - lastTap.y);
246
+ if (timeDelta < 280 && distance < 24) {
247
+ void selectAtPoint(locationX, locationY);
248
+ }
249
+ };
250
+ const selectionEnabled = import_react_native.Platform.OS === "web";
251
+ void selectionText;
252
+ const panResponder = (0, import_react.useMemo)(
253
+ () => import_react_native.PanResponder.create({
254
+ onStartShouldSetPanResponder: () => selectionEnabled,
255
+ onMoveShouldSetPanResponder: () => selectionEnabled,
256
+ onPanResponderGrant: (event) => {
257
+ if (!selectionEnabled || !layout.width || !layout.height) return;
258
+ const { locationX, locationY } = event.nativeEvent;
259
+ selectionStart.current = { x: locationX, y: locationY };
260
+ setIsSelecting(true);
261
+ const rect = { x: locationX, y: locationY, width: 0, height: 0 };
262
+ selectionRectRef.current = rect;
263
+ setSelectionRect(rect);
264
+ },
265
+ onPanResponderMove: (_, gestureState) => {
266
+ if (!selectionEnabled || !selectionStart.current) return;
267
+ const start = selectionStart.current;
268
+ const currentX = start.x + gestureState.dx;
269
+ const currentY = start.y + gestureState.dy;
270
+ const left = Math.max(0, Math.min(start.x, currentX));
271
+ const top = Math.max(0, Math.min(start.y, currentY));
272
+ const right = Math.min(layout.width, Math.max(start.x, currentX));
273
+ const bottom = Math.min(layout.height, Math.max(start.y, currentY));
274
+ const rect = { x: left, y: top, width: right - left, height: bottom - top };
275
+ selectionRectRef.current = rect;
276
+ setSelectionRect(rect);
277
+ },
278
+ onPanResponderRelease: async () => {
279
+ const rect = selectionRectRef.current;
280
+ if (!selectionEnabled || !rect || !layout.width || !layout.height) {
281
+ setIsSelecting(false);
282
+ selectionStart.current = null;
283
+ return;
284
+ }
285
+ setIsSelecting(false);
286
+ selectionStart.current = null;
287
+ const minSize = 6;
288
+ if (rect.width < minSize || rect.height < minSize) {
289
+ clearSelection();
290
+ return;
291
+ }
292
+ const normalized = {
293
+ x: rect.x / layout.width,
294
+ y: rect.y / layout.height,
295
+ width: rect.width / layout.width,
296
+ height: rect.height / layout.height
297
+ };
298
+ await selectFromBounds(normalized);
299
+ setSelectionRect(null);
300
+ }
301
+ }),
302
+ [selectionEnabled, layout.width, layout.height, engine, pageIndex]
303
+ );
304
+ const selectionBoundsPx = (0, import_react.useMemo)(() => {
305
+ if (!selectionBounds || !layout.width || !layout.height) return null;
306
+ return {
307
+ x: selectionBounds.x * layout.width,
308
+ y: selectionBounds.y * layout.height,
309
+ width: selectionBounds.width * layout.width,
310
+ height: selectionBounds.height * layout.height
311
+ };
312
+ }, [selectionBounds, layout.width, layout.height]);
313
+ const createHandleResponder = (handle) => import_react_native.PanResponder.create({
314
+ onStartShouldSetPanResponder: () => true,
315
+ onMoveShouldSetPanResponder: () => true,
316
+ onPanResponderGrant: () => {
317
+ selectionBoundsStart.current = selectionBoundsRef.current;
318
+ },
319
+ onPanResponderMove: (_, gestureState) => {
320
+ const start = selectionBoundsStart.current;
321
+ if (!start || !layout.width || !layout.height) return;
322
+ const dx = gestureState.dx / layout.width;
323
+ const dy = gestureState.dy / layout.height;
324
+ const minSize = 0.01;
325
+ let next = { ...start };
326
+ if (handle === "start") {
327
+ const newX = clamp(start.x + dx, 0, start.x + start.width - minSize);
328
+ const newY = clamp(start.y + dy, 0, start.y + start.height - minSize);
329
+ next = {
330
+ x: newX,
331
+ y: newY,
332
+ width: start.x + start.width - newX,
333
+ height: start.y + start.height - newY
334
+ };
335
+ } else {
336
+ const maxX = clamp(start.x + start.width + dx, start.x + minSize, 1);
337
+ const maxY = clamp(start.y + start.height + dy, start.y + minSize, 1);
338
+ next = {
339
+ x: start.x,
340
+ y: start.y,
341
+ width: maxX - start.x,
342
+ height: maxY - start.y
343
+ };
344
+ }
345
+ selectionBoundsRef.current = next;
346
+ setSelectionBounds(next);
347
+ },
348
+ onPanResponderRelease: async () => {
349
+ const next = selectionBoundsRef.current;
350
+ selectionBoundsStart.current = null;
351
+ if (!next) return;
352
+ await selectFromBounds(next);
353
+ },
354
+ onPanResponderTerminate: () => {
355
+ selectionBoundsStart.current = null;
356
+ }
357
+ });
358
+ const startHandleResponder = (0, import_react.useMemo)(
359
+ () => createHandleResponder("start"),
360
+ [layout.width, layout.height, engine, pageIndex]
361
+ );
362
+ const endHandleResponder = (0, import_react.useMemo)(
363
+ () => createHandleResponder("end"),
364
+ [layout.width, layout.height, engine, pageIndex]
365
+ );
366
+ const applySelection = (type) => {
367
+ if (selectionRects.length === 0) return;
368
+ if (type === "comment") {
369
+ const first = selectionRects[0];
370
+ addAnnotationAt(first.x, first.y, Math.max(0.08, first.width), Math.max(0.06, first.height), "comment");
371
+ clearSelection();
372
+ return;
373
+ }
374
+ selectionRects.forEach((rect) => {
375
+ addAnnotationAt(rect.x, rect.y, rect.width, rect.height, type);
376
+ });
377
+ clearSelection();
378
+ };
379
+ const themeOverlayStyle = (0, import_react.useMemo)(() => {
380
+ switch (pageTheme) {
381
+ case "sepia":
382
+ return styles.themeSepia;
383
+ case "dark":
384
+ return styles.themeDark;
385
+ case "high-contrast":
386
+ return styles.themeContrast;
387
+ default:
388
+ return styles.themeNone;
389
+ }
390
+ }, [pageTheme]);
391
+ const aspectRatio = pageSize && pageSize.width > 0 && pageSize.height > 0 ? pageSize.width / pageSize.height : 0.77;
392
+ const containerWidth = availableWidth ?? windowWidth;
393
+ const baseWidth = containerWidth * 0.92;
394
+ const pageWidth = isAndroid ? baseWidth * zoom : baseWidth;
395
+ const pageHeight = pageWidth / aspectRatio;
396
+ const scrollEnabled = isAndroid && zoom > 1;
397
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
398
+ import_react_native.ScrollView,
399
+ {
400
+ horizontal: true,
401
+ scrollEnabled,
402
+ showsHorizontalScrollIndicator: false,
403
+ contentContainerStyle: [styles.scrollContent, { paddingHorizontal: horizontalPadding }],
404
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
405
+ import_react_native.Pressable,
406
+ {
407
+ ...panResponder.panHandlers,
408
+ style: [styles.container, { width: pageWidth, height: pageHeight, marginBottom: spacing }],
409
+ onLayout: handleLayout,
410
+ onPress: handlePress,
411
+ onStartShouldSetResponder: (event) => shouldHandlePinch(event.nativeEvent.touches),
412
+ onMoveShouldSetResponder: (event) => shouldHandlePinch(event.nativeEvent.touches),
413
+ onResponderGrant: (event) => handlePinchStart(event.nativeEvent.touches),
414
+ onResponderMove: (event) => handlePinchMove(event.nativeEvent.touches),
415
+ onResponderRelease: handlePinchEnd,
416
+ onResponderTerminate: handlePinchEnd,
417
+ children: [
418
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PageViewComponent, { ref: viewRef, style: styles.page }),
419
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { pointerEvents: "none", style: [styles.themeOverlay, themeOverlayStyle] }),
420
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { pointerEvents: "box-none", style: styles.selectionLayer, children: [
421
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { pointerEvents: "none", children: selectionRects.map((rect, index) => {
422
+ const style = {
423
+ left: `${rect.x * 100}%`,
424
+ top: `${rect.y * 100}%`,
425
+ width: `${rect.width * 100}%`,
426
+ height: `${rect.height * 100}%`
427
+ };
428
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: [styles.selectionHighlight, style] }, `sel-${index}`);
429
+ }) }),
430
+ selectionBoundsPx ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
431
+ import_react_native.View,
432
+ {
433
+ pointerEvents: "box-none",
434
+ style: [
435
+ styles.selectionOutline,
436
+ {
437
+ left: selectionBoundsPx.x,
438
+ top: selectionBoundsPx.y,
439
+ width: selectionBoundsPx.width,
440
+ height: selectionBoundsPx.height,
441
+ borderColor: accentColor
442
+ }
443
+ ],
444
+ children: [
445
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
446
+ import_react_native.View,
447
+ {
448
+ ...startHandleResponder.panHandlers,
449
+ style: [styles.selectionHandle, { left: -8, top: -8, borderColor: accentColor }]
450
+ }
451
+ ),
452
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
453
+ import_react_native.View,
454
+ {
455
+ ...endHandleResponder.panHandlers,
456
+ style: [styles.selectionHandle, { right: -8, bottom: -8, borderColor: accentColor }]
457
+ }
458
+ )
459
+ ]
460
+ }
461
+ ) : null,
462
+ isSelecting && selectionRect ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
463
+ import_react_native.View,
464
+ {
465
+ pointerEvents: "none",
466
+ style: [
467
+ styles.selectionOutline,
468
+ {
469
+ left: selectionRect.x,
470
+ top: selectionRect.y,
471
+ width: selectionRect.width,
472
+ height: selectionRect.height,
473
+ borderColor: accentColor
474
+ }
475
+ ]
476
+ }
477
+ ) : null
478
+ ] }),
479
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { pointerEvents: "none", style: styles.searchLayer, children: pageSearchHits.map(({ result, index }) => {
480
+ if (!result.rects || result.rects.length === 0) return null;
481
+ return result.rects.map((rect, rectIndex) => {
482
+ if (rect.width <= 0 || rect.height <= 0) return null;
483
+ const isActive = index === activeSearchIndex;
484
+ const highlightStyle = {
485
+ left: `${rect.x * 100}%`,
486
+ top: `${rect.y * 100}%`,
487
+ width: `${rect.width * 100}%`,
488
+ height: `${rect.height * 100}%`
489
+ };
490
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
491
+ import_react_native.View,
492
+ {
493
+ style: [
494
+ styles.searchHighlight,
495
+ { borderColor: accentColor, backgroundColor: `${accentColor}26` },
496
+ isActive && styles.searchHighlightActive,
497
+ isActive && { borderColor: accentColor, backgroundColor: `${accentColor}40` },
498
+ highlightStyle
499
+ ]
500
+ },
501
+ `${index}-${rectIndex}`
502
+ );
503
+ });
504
+ }) }),
505
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { pointerEvents: "box-none", style: styles.annotationLayer, children: pageAnnotations.map((ann) => {
506
+ const isSelected = selectedAnnotationId === ann.id;
507
+ const style = {
508
+ left: `${ann.rect.x * 100}%`,
509
+ top: `${ann.rect.y * 100}%`,
510
+ width: `${ann.rect.width * 100}%`,
511
+ height: `${ann.rect.height * 100}%`,
512
+ backgroundColor: ann.type === "highlight" ? `${ann.color}66` : "transparent",
513
+ borderBottomWidth: ann.type === "strikeout" ? 3 : 0,
514
+ borderBottomColor: ann.type === "strikeout" ? ann.color : "transparent"
515
+ };
516
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
517
+ import_react_native.Pressable,
518
+ {
519
+ onPress: () => setSelectedAnnotation(ann.id),
520
+ style: [
521
+ styles.annotation,
522
+ style,
523
+ isSelected && styles.annotationSelected,
524
+ isSelected && { borderColor: accentColor }
525
+ ],
526
+ children: [
527
+ (ann.type === "comment" || ann.type === "text") && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: [styles.annotationBadge, { borderColor: ann.color }], children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: [styles.annotationDot, { backgroundColor: ann.color }] }) }),
528
+ isSelected && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Pressable, { onPress: () => removeAnnotation(ann.id), style: styles.deleteButton, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: styles.deleteDot }) })
529
+ ]
530
+ },
531
+ ann.id
532
+ );
533
+ }) }),
534
+ selectionRects.length > 0 && selectionBoundsPx ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
535
+ import_react_native.View,
536
+ {
537
+ pointerEvents: "box-none",
538
+ style: [
539
+ styles.selectionToolbar,
540
+ {
541
+ left: selectionBoundsPx.x,
542
+ top: selectionBoundsPx.y + selectionBoundsPx.height + 8 > layout.height - 56 ? Math.max(8, selectionBoundsPx.y - 52) : selectionBoundsPx.y + selectionBoundsPx.height + 8
543
+ }
544
+ ],
545
+ children: [
546
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Pressable, { onPress: () => applySelection("comment"), style: styles.selectionAction, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: styles.selectionActionDot }) }),
547
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Pressable, { onPress: () => applySelection("highlight"), style: styles.selectionAction, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: [styles.selectionSwatch, { backgroundColor: annotationColor }] }) }),
548
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.Pressable, { onPress: () => applySelection("strikeout"), style: [styles.selectionAction, styles.selectionActionLast], children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: [styles.selectionStrike, { backgroundColor: annotationColor }] }) })
549
+ ]
550
+ }
551
+ ) : null
552
+ ]
553
+ }
554
+ )
555
+ }
556
+ );
557
+ };
558
+ var styles = import_react_native.StyleSheet.create({
559
+ scrollContent: {
560
+ alignItems: "center"
561
+ },
562
+ container: {
563
+ alignSelf: "center",
564
+ borderRadius: 14,
565
+ backgroundColor: "#ffffff",
566
+ shadowColor: "#000000",
567
+ shadowOpacity: 0.12,
568
+ shadowRadius: 12,
569
+ shadowOffset: { width: 0, height: 6 },
570
+ elevation: 4
571
+ },
572
+ page: {
573
+ ...import_react_native.StyleSheet.absoluteFillObject,
574
+ backgroundColor: "#ffffff",
575
+ borderRadius: 14,
576
+ overflow: "hidden"
577
+ },
578
+ annotationLayer: {
579
+ position: "absolute",
580
+ left: 0,
581
+ top: 0,
582
+ right: 0,
583
+ bottom: 0
584
+ },
585
+ searchLayer: {
586
+ position: "absolute",
587
+ left: 0,
588
+ top: 0,
589
+ right: 0,
590
+ bottom: 0
591
+ },
592
+ selectionLayer: {
593
+ position: "absolute",
594
+ left: 0,
595
+ top: 0,
596
+ right: 0,
597
+ bottom: 0
598
+ },
599
+ selectionHighlight: {
600
+ position: "absolute",
601
+ backgroundColor: "rgba(245, 158, 11, 0.28)",
602
+ borderRadius: 4
603
+ },
604
+ selectionOutline: {
605
+ position: "absolute",
606
+ borderWidth: 2,
607
+ borderStyle: "dashed",
608
+ borderColor: "rgba(37, 99, 235, 0.9)",
609
+ borderRadius: 6
610
+ },
611
+ selectionHandle: {
612
+ position: "absolute",
613
+ width: 16,
614
+ height: 16,
615
+ borderRadius: 8,
616
+ backgroundColor: "#ffffff",
617
+ borderWidth: 2,
618
+ borderColor: "#2563eb"
619
+ },
620
+ searchHighlight: {
621
+ position: "absolute",
622
+ backgroundColor: "rgba(59, 130, 246, 0.2)",
623
+ borderWidth: 1,
624
+ borderColor: "rgba(59, 130, 246, 0.35)",
625
+ borderRadius: 4
626
+ },
627
+ searchHighlightActive: {
628
+ backgroundColor: "rgba(59, 130, 246, 0.35)",
629
+ borderColor: "#3b82f6"
630
+ },
631
+ themeOverlay: {
632
+ ...import_react_native.StyleSheet.absoluteFillObject,
633
+ borderRadius: 14
634
+ },
635
+ themeNone: {
636
+ backgroundColor: "transparent"
637
+ },
638
+ themeSepia: {
639
+ backgroundColor: "rgba(244, 236, 216, 0.35)"
640
+ },
641
+ themeDark: {
642
+ backgroundColor: "rgba(0, 0, 0, 0.2)"
643
+ },
644
+ themeContrast: {
645
+ backgroundColor: "rgba(0, 0, 0, 0.35)"
646
+ },
647
+ annotation: {
648
+ position: "absolute"
649
+ },
650
+ annotationSelected: {
651
+ borderWidth: 1,
652
+ borderColor: "#3b82f6"
653
+ },
654
+ annotationBadge: {
655
+ position: "absolute",
656
+ left: 4,
657
+ top: 4,
658
+ width: 14,
659
+ height: 14,
660
+ borderRadius: 7,
661
+ borderWidth: 1,
662
+ backgroundColor: "#ffffff",
663
+ alignItems: "center",
664
+ justifyContent: "center"
665
+ },
666
+ annotationDot: {
667
+ width: 6,
668
+ height: 6,
669
+ borderRadius: 3
670
+ },
671
+ deleteButton: {
672
+ position: "absolute",
673
+ right: -8,
674
+ top: -8,
675
+ width: 20,
676
+ height: 20,
677
+ borderRadius: 10,
678
+ backgroundColor: "#ef4444",
679
+ alignItems: "center",
680
+ justifyContent: "center"
681
+ },
682
+ deleteDot: {
683
+ width: 8,
684
+ height: 2,
685
+ backgroundColor: "#ffffff",
686
+ borderRadius: 2
687
+ },
688
+ selectionToolbar: {
689
+ position: "absolute",
690
+ paddingHorizontal: 10,
691
+ paddingVertical: 8,
692
+ borderRadius: 14,
693
+ backgroundColor: "#111827",
694
+ flexDirection: "row",
695
+ alignItems: "center"
696
+ },
697
+ selectionAction: {
698
+ width: 28,
699
+ height: 28,
700
+ borderRadius: 10,
701
+ backgroundColor: "#1f2937",
702
+ alignItems: "center",
703
+ justifyContent: "center",
704
+ marginRight: 10
705
+ },
706
+ selectionActionLast: {
707
+ marginRight: 0
708
+ },
709
+ selectionActionDot: {
710
+ width: 8,
711
+ height: 8,
712
+ borderRadius: 4,
713
+ backgroundColor: "#f9fafb"
714
+ },
715
+ selectionSwatch: {
716
+ width: 14,
717
+ height: 14,
718
+ borderRadius: 7,
719
+ borderWidth: 1,
720
+ borderColor: "#ffffff"
721
+ },
722
+ selectionStrike: {
723
+ width: 14,
724
+ height: 3,
725
+ borderRadius: 3
726
+ }
727
+ });
728
+ var PageRenderer_default = PageRenderer;
729
+
730
+ // components/Viewer.tsx
731
+ var import_jsx_runtime2 = require("react/jsx-runtime");
732
+ var Viewer = ({ engine }) => {
733
+ const { pageCount, currentPage, scrollToPageSignal, setDocumentState, uiTheme, viewMode } = (0, import_core2.useViewerStore)();
734
+ const listRef = (0, import_react2.useRef)(null);
735
+ const isDark = uiTheme === "dark";
736
+ const { width: windowWidth } = (0, import_react_native2.useWindowDimensions)();
737
+ const isDouble = viewMode === "double";
738
+ const isSingle = viewMode === "single";
739
+ const pages = (0, import_react2.useMemo)(() => Array.from({ length: pageCount }).map((_, i) => i), [pageCount]);
740
+ const rows = (0, import_react2.useMemo)(() => {
741
+ if (!isDouble) return [];
742
+ const result = [];
743
+ for (let i = 0; i < pageCount; i += 2) {
744
+ result.push({ left: i, right: i + 1 < pageCount ? i + 1 : null });
745
+ }
746
+ return result;
747
+ }, [isDouble, pageCount]);
748
+ (0, import_react2.useEffect)(() => {
749
+ if (scrollToPageSignal === null) return;
750
+ if (pageCount === 0) return;
751
+ if (scrollToPageSignal < 0 || scrollToPageSignal >= pageCount) return;
752
+ if (isSingle) {
753
+ setDocumentState({ currentPage: scrollToPageSignal + 1, scrollToPageSignal: null });
754
+ return;
755
+ }
756
+ const targetIndex = isDouble ? Math.floor(scrollToPageSignal / 2) : scrollToPageSignal;
757
+ listRef.current?.scrollToIndex({ index: targetIndex, animated: true });
758
+ setDocumentState({ scrollToPageSignal: null });
759
+ }, [scrollToPageSignal, pageCount, setDocumentState, isDouble, isSingle]);
760
+ const onViewableItemsChanged = (0, import_react2.useCallback)(
761
+ ({ viewableItems }) => {
762
+ const first = viewableItems[0];
763
+ if (!first) return;
764
+ if (isDouble) {
765
+ const item = first.item;
766
+ if (!item) return;
767
+ const page = item.left + 1;
768
+ if (page !== currentPage) {
769
+ setDocumentState({ currentPage: page });
770
+ }
771
+ return;
772
+ }
773
+ if (first.index !== null && first.index !== void 0) {
774
+ const page = first.index + 1;
775
+ if (page !== currentPage) {
776
+ setDocumentState({ currentPage: page });
777
+ }
778
+ }
779
+ },
780
+ [currentPage, isDouble, setDocumentState]
781
+ );
782
+ if (isSingle) {
783
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: [styles2.container, isDark && styles2.containerDark], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
784
+ import_react_native2.ScrollView,
785
+ {
786
+ contentContainerStyle: styles2.singleContent,
787
+ showsVerticalScrollIndicator: false,
788
+ scrollEnabled: true,
789
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PageRenderer_default, { engine, pageIndex: Math.max(0, currentPage - 1), spacing: 32 })
790
+ }
791
+ ) });
792
+ }
793
+ const columnGap = 12;
794
+ const horizontalPadding = 16;
795
+ const columnWidth = isDouble ? (windowWidth - horizontalPadding * 2 - columnGap) / 2 : windowWidth;
796
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: [styles2.container, isDark && styles2.containerDark], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
797
+ import_react_native2.FlatList,
798
+ {
799
+ ref: listRef,
800
+ data: isDouble ? rows : pages,
801
+ keyExtractor: (item) => isDouble ? `row-${item.left}` : `page-${item}`,
802
+ contentContainerStyle: styles2.listContent,
803
+ renderItem: ({ item }) => isDouble ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: [styles2.row, { paddingHorizontal: horizontalPadding }], children: [
804
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: { width: columnWidth }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
805
+ PageRenderer_default,
806
+ {
807
+ engine,
808
+ pageIndex: item.left,
809
+ availableWidth: columnWidth,
810
+ horizontalPadding: 8,
811
+ spacing: 20
812
+ }
813
+ ) }),
814
+ item.right !== null ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: { width: columnWidth }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
815
+ PageRenderer_default,
816
+ {
817
+ engine,
818
+ pageIndex: item.right,
819
+ availableWidth: columnWidth,
820
+ horizontalPadding: 8,
821
+ spacing: 20
822
+ }
823
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: { width: columnWidth } })
824
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PageRenderer_default, { engine, pageIndex: item, spacing: 28 }),
825
+ onViewableItemsChanged,
826
+ viewabilityConfig: { itemVisiblePercentThreshold: 60 },
827
+ scrollEnabled: true,
828
+ onScrollToIndexFailed: ({ index, averageItemLength }) => {
829
+ if (index < 0 || index >= pageCount) return;
830
+ const offset = Math.max(0, averageItemLength * index);
831
+ listRef.current?.scrollToOffset({ offset, animated: true });
832
+ },
833
+ showsVerticalScrollIndicator: false
834
+ }
835
+ ) });
836
+ };
837
+ var styles2 = import_react_native2.StyleSheet.create({
838
+ container: {
839
+ flex: 1,
840
+ backgroundColor: "#e9ecef"
841
+ },
842
+ containerDark: {
843
+ backgroundColor: "#0f1115"
844
+ },
845
+ listContent: {
846
+ paddingTop: 18,
847
+ paddingBottom: 120
848
+ },
849
+ singleContent: {
850
+ paddingTop: 18,
851
+ paddingBottom: 140
852
+ },
853
+ row: {
854
+ flexDirection: "row",
855
+ justifyContent: "space-between"
856
+ }
857
+ });
858
+ var Viewer_default = Viewer;
859
+
860
+ // components/Topbar.tsx
861
+ var import_react3 = require("react");
862
+ var import_react_native3 = require("react-native");
863
+ var import_core3 = require("@papyrus-sdk/core");
864
+
865
+ // icons.tsx
866
+ var import_react_native_svg = __toESM(require("react-native-svg"));
867
+ var import_jsx_runtime3 = require("react/jsx-runtime");
868
+ var defaultColor = "#111827";
869
+ var IconDocument = ({ size = 20, color = defaultColor, strokeWidth = 2 }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg.default, { width: size, height: size, viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
870
+ import_react_native_svg.Path,
871
+ {
872
+ d: "M10 3v4a1 1 0 0 1-1 1H5m14-4v16a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V7.914a1 1 0 0 1 .293-.707l3.914-3.914A1 1 0 0 1 9.914 3H18a1 1 0 0 1 1 1Z",
873
+ stroke: color,
874
+ strokeWidth,
875
+ strokeLinejoin: "round"
876
+ }
877
+ ) });
878
+ var IconGrid = ({ size = 20, color = defaultColor, strokeWidth = 2 }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg.default, { width: size, height: size, viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
879
+ import_react_native_svg.Path,
880
+ {
881
+ d: "M9.143 4H4.857A.857.857 0 0 0 4 4.857v4.286c0 .473.384.857.857.857h4.286A.857.857 0 0 0 10 9.143V4.857A.857.857 0 0 0 9.143 4Zm10 0h-4.286a.857.857 0 0 0-.857.857v4.286c0 .473.384.857.857.857h4.286A.857.857 0 0 0 20 9.143V4.857A.857.857 0 0 0 19.143 4Zm-10 10H4.857a.857.857 0 0 0-.857.857v4.286c0 .473.384.857.857.857h4.286a.857.857 0 0 0 .857-.857v-4.286A.857.857 0 0 0 9.143 14Zm10 0h-4.286a.857.857 0 0 0-.857.857v4.286c0 .473.384.857.857.857h4.286a.857.857 0 0 0 .857-.857v-4.286a.857.857 0 0 0-.857-.857Z",
882
+ stroke: color,
883
+ strokeWidth,
884
+ strokeLinecap: "round",
885
+ strokeLinejoin: "round"
886
+ }
887
+ ) });
888
+ var IconSearch = ({ size = 20, color = defaultColor, strokeWidth = 2 }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg.default, { width: size, height: size, viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
889
+ import_react_native_svg.Path,
890
+ {
891
+ d: "m21 21-3.5-3.5M17 10a7 7 0 1 1-14 0 7 7 0 0 1 14 0Z",
892
+ stroke: color,
893
+ strokeWidth,
894
+ strokeLinecap: "round"
895
+ }
896
+ ) });
897
+ var IconZoomIn = ({ size = 18, color = defaultColor, strokeWidth = 2 }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg.default, { width: size, height: size, viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg.Path, { d: "M5 12h14m-7 7V5", stroke: color, strokeWidth, strokeLinecap: "round", strokeLinejoin: "round" }) });
898
+ var IconZoomOut = ({ size = 18, color = defaultColor, strokeWidth = 2 }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg.default, { width: size, height: size, viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg.Path, { d: "M5 12h14", stroke: color, strokeWidth, strokeLinecap: "round", strokeLinejoin: "round" }) });
899
+ var IconSettings = ({ size = 20, color = defaultColor, strokeWidth = 2 }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native_svg.default, { width: size, height: size, viewBox: "0 0 24 24", fill: "none", children: [
900
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
901
+ import_react_native_svg.Path,
902
+ {
903
+ d: "M21 13v-2a1 1 0 0 0-1-1h-.757l-.707-1.707.535-.536a1 1 0 0 0 0-1.414l-1.414-1.414a1 1 0 0 0-1.414 0l-.536.535L14 4.757V4a1 1 0 0 0-1-1h-2a1 1 0 0 0-1 1v.757l-1.707.707-.536-.535a1 1 0 0 0-1.414 0L4.929 6.343a1 1 0 0 0 0 1.414l.536.536L4.757 10H4a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h.757l.707 1.707-.535.536a1 1 0 0 0 0 1.414l1.414 1.414a1 1 0 0 0 1.414 0l.536-.535 1.707.707V20a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1v-.757l1.707-.708.536.536a1 1 0 0 0 1.414 0l1.414-1.414a1 1 0 0 0 0-1.414l-.535-.536.707-1.707H20a1 1 0 0 0 1-1Z",
904
+ stroke: color,
905
+ strokeWidth,
906
+ strokeLinecap: "round",
907
+ strokeLinejoin: "round"
908
+ }
909
+ ),
910
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
911
+ import_react_native_svg.Path,
912
+ {
913
+ d: "M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z",
914
+ stroke: color,
915
+ strokeWidth,
916
+ strokeLinecap: "round",
917
+ strokeLinejoin: "round"
918
+ }
919
+ )
920
+ ] });
921
+ var IconComment = ({ size = 20, color = defaultColor, strokeWidth = 2 }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg.default, { width: size, height: size, viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
922
+ import_react_native_svg.Path,
923
+ {
924
+ d: "M7.556 8.5h8m-8 3.5H12m7.111-7H4.89a.896.896 0 0 0-.629.256.868.868 0 0 0-.26.619v9.25c0 .232.094.455.26.619A.896.896 0 0 0 4.89 16H9l3 4 3-4h4.111a.896.896 0 0 0 .629-.256.868.868 0 0 0 .26-.619v-9.25a.868.868 0 0 0-.26-.619.896.896 0 0 0-.63-.256Z",
925
+ stroke: color,
926
+ strokeWidth,
927
+ strokeLinecap: "round",
928
+ strokeLinejoin: "round"
929
+ }
930
+ ) });
931
+ var IconChevronRight = ({ size = 18, color = defaultColor, strokeWidth = 2 }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg.default, { width: size, height: size, viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
932
+ import_react_native_svg.Path,
933
+ {
934
+ d: "m9 5 7 7-7 7",
935
+ stroke: color,
936
+ strokeWidth,
937
+ strokeLinecap: "round",
938
+ strokeLinejoin: "round"
939
+ }
940
+ ) });
941
+ var IconChevronLeft = ({ size = 18, color = defaultColor, strokeWidth = 2 }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg.default, { width: size, height: size, viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
942
+ import_react_native_svg.Path,
943
+ {
944
+ d: "m15 19-7-7 7-7",
945
+ stroke: color,
946
+ strokeWidth,
947
+ strokeLinecap: "round",
948
+ strokeLinejoin: "round"
949
+ }
950
+ ) });
951
+
952
+ // components/Topbar.tsx
953
+ var import_jsx_runtime4 = require("react/jsx-runtime");
954
+ var Topbar = ({ engine, onOpenSettings }) => {
955
+ const {
956
+ currentPage,
957
+ pageCount,
958
+ uiTheme,
959
+ setDocumentState,
960
+ triggerScrollToPage,
961
+ accentColor
962
+ } = (0, import_core3.useViewerStore)();
963
+ const [pageLabel, setPageLabel] = (0, import_react3.useState)(`${currentPage}`);
964
+ const isDark = uiTheme === "dark";
965
+ const navIconColor = isDark ? "#e5e7eb" : "#111827";
966
+ (0, import_react3.useEffect)(() => {
967
+ setPageLabel(`${currentPage}`);
968
+ }, [currentPage]);
969
+ const handlePageChange = (delta) => {
970
+ const next = Math.max(1, Math.min(pageCount, currentPage + delta));
971
+ engine.goToPage(next);
972
+ setDocumentState({ currentPage: next });
973
+ triggerScrollToPage(next - 1);
974
+ };
975
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native3.View, { style: [styles3.container, isDark && styles3.containerDark], children: [
976
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native3.View, { style: styles3.leftGroup, children: [
977
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native3.View, { style: [styles3.logoBadge, { backgroundColor: accentColor }], children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native3.Text, { style: styles3.logoText, children: "P" }) }),
978
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native3.Text, { style: [styles3.brandText, isDark && styles3.brandTextDark], children: "Papyrus" })
979
+ ] }),
980
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native3.View, { style: styles3.pageGroup, children: [
981
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native3.Pressable, { onPress: () => handlePageChange(-1), style: [styles3.pageButton, isDark && styles3.pageButtonDark], children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconChevronLeft, { size: 16, color: navIconColor }) }),
982
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native3.Text, { style: [styles3.pageIndicator, isDark && styles3.pageIndicatorDark], children: [
983
+ pageLabel,
984
+ "/",
985
+ pageCount
986
+ ] }),
987
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native3.Pressable, { onPress: () => handlePageChange(1), style: [styles3.pageButton, isDark && styles3.pageButtonDark], children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconChevronRight, { size: 16, color: navIconColor }) })
988
+ ] }),
989
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native3.View, { style: styles3.rightGroup, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
990
+ import_react_native3.Pressable,
991
+ {
992
+ onPress: () => onOpenSettings?.(),
993
+ style: [styles3.iconButton, isDark && styles3.iconButtonDark],
994
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconSettings, { size: 16, color: isDark ? "#e5e7eb" : "#111827" })
995
+ }
996
+ ) })
997
+ ] });
998
+ };
999
+ var styles3 = import_react_native3.StyleSheet.create({
1000
+ container: {
1001
+ paddingHorizontal: 14,
1002
+ paddingVertical: 8,
1003
+ backgroundColor: "#ffffff",
1004
+ borderBottomWidth: 1,
1005
+ borderBottomColor: "#e5e7eb",
1006
+ flexDirection: "row",
1007
+ alignItems: "center"
1008
+ },
1009
+ containerDark: {
1010
+ backgroundColor: "#0f1115",
1011
+ borderBottomColor: "#1f2937"
1012
+ },
1013
+ leftGroup: {
1014
+ flexDirection: "row",
1015
+ alignItems: "center",
1016
+ flex: 1
1017
+ },
1018
+ logoBadge: {
1019
+ width: 26,
1020
+ height: 26,
1021
+ borderRadius: 8,
1022
+ alignItems: "center",
1023
+ justifyContent: "center",
1024
+ backgroundColor: "#2563eb",
1025
+ marginRight: 8
1026
+ },
1027
+ logoText: {
1028
+ color: "#ffffff",
1029
+ fontWeight: "800",
1030
+ fontSize: 13
1031
+ },
1032
+ brandText: {
1033
+ fontSize: 14,
1034
+ fontWeight: "800",
1035
+ color: "#111827"
1036
+ },
1037
+ brandTextDark: {
1038
+ color: "#f9fafb"
1039
+ },
1040
+ pageGroup: {
1041
+ flexDirection: "row",
1042
+ alignItems: "center",
1043
+ flex: 1,
1044
+ justifyContent: "center"
1045
+ },
1046
+ pageButton: {
1047
+ width: 26,
1048
+ height: 26,
1049
+ borderRadius: 10,
1050
+ alignItems: "center",
1051
+ justifyContent: "center",
1052
+ backgroundColor: "#f3f4f6"
1053
+ },
1054
+ pageButtonDark: {
1055
+ backgroundColor: "#111827"
1056
+ },
1057
+ pageButtonText: {
1058
+ fontSize: 11,
1059
+ fontWeight: "600",
1060
+ color: "#111827"
1061
+ },
1062
+ pageButtonTextDark: {
1063
+ color: "#e5e7eb"
1064
+ },
1065
+ pageIndicator: {
1066
+ fontSize: 12,
1067
+ color: "#374151",
1068
+ minWidth: 52,
1069
+ textAlign: "center",
1070
+ marginHorizontal: 6,
1071
+ fontWeight: "700"
1072
+ },
1073
+ pageIndicatorDark: {
1074
+ color: "#d1d5db"
1075
+ },
1076
+ rightGroup: {
1077
+ flexDirection: "row",
1078
+ alignItems: "center",
1079
+ justifyContent: "flex-end",
1080
+ flex: 1
1081
+ },
1082
+ iconButton: {
1083
+ paddingHorizontal: 10,
1084
+ paddingVertical: 6,
1085
+ borderRadius: 10,
1086
+ backgroundColor: "#f3f4f6",
1087
+ marginLeft: 6
1088
+ },
1089
+ iconButtonDark: {
1090
+ backgroundColor: "#111827"
1091
+ },
1092
+ iconButtonActive: {
1093
+ backgroundColor: "#2563eb"
1094
+ },
1095
+ iconButtonText: {
1096
+ fontSize: 11,
1097
+ fontWeight: "700",
1098
+ color: "#111827"
1099
+ },
1100
+ iconButtonTextDark: {
1101
+ color: "#e5e7eb"
1102
+ },
1103
+ iconButtonTextActive: {
1104
+ color: "#ffffff"
1105
+ },
1106
+ iconRow: {
1107
+ flexDirection: "row",
1108
+ alignItems: "center"
1109
+ },
1110
+ iconRowSpacer: {
1111
+ width: 6
1112
+ }
1113
+ });
1114
+ var Topbar_default = Topbar;
1115
+
1116
+ // components/ToolDock.tsx
1117
+ var import_react_native4 = require("react-native");
1118
+ var import_core4 = require("@papyrus-sdk/core");
1119
+
1120
+ // strings.ts
1121
+ var STRINGS = {
1122
+ en: {
1123
+ pages: "Pages",
1124
+ search: "Search",
1125
+ notes: "Notes",
1126
+ read: "Read",
1127
+ edit: "Edit",
1128
+ done: "Done",
1129
+ page: "Page",
1130
+ summary: "Summary",
1131
+ pagesTab: "Pages",
1132
+ summaryTab: "Summary",
1133
+ searchPlaceholder: "Search text...",
1134
+ searchGo: "Go",
1135
+ results: "results",
1136
+ searching: "Searching...",
1137
+ noResults: "No results yet.",
1138
+ noSummary: "No summary available.",
1139
+ noAnnotations: "No annotations yet.",
1140
+ untitled: "Untitled",
1141
+ pageTransition: "Page transition",
1142
+ continuous: "Continuous",
1143
+ pageByPage: "Page by page",
1144
+ layout: "Layout",
1145
+ singlePage: "Single page",
1146
+ doublePage: "Double page",
1147
+ rotate: "Rotate",
1148
+ clockwise: "Clockwise",
1149
+ counterclockwise: "Counterclockwise",
1150
+ zoom: "Zoom",
1151
+ highlight: "Highlight",
1152
+ strike: "Strike",
1153
+ text: "Text",
1154
+ note: "Note",
1155
+ editNote: "Edit note",
1156
+ notePlaceholder: "Write your note...",
1157
+ cancel: "Cancel",
1158
+ save: "Save",
1159
+ language: "Language",
1160
+ english: "English",
1161
+ portuguese: "Portuguese (BR)",
1162
+ appearance: "Appearance",
1163
+ light: "Light",
1164
+ dark: "Dark",
1165
+ pageTheme: "Page theme",
1166
+ themeOriginal: "Original",
1167
+ themeSepia: "Sepia",
1168
+ themeDark: "Dark",
1169
+ themeContrast: "High contrast"
1170
+ },
1171
+ "pt-BR": {
1172
+ pages: "Paginas",
1173
+ search: "Buscar",
1174
+ notes: "Notas",
1175
+ read: "Ler",
1176
+ edit: "Editar",
1177
+ done: "Concluir",
1178
+ page: "Pagina",
1179
+ summary: "Sumario",
1180
+ pagesTab: "Paginas",
1181
+ summaryTab: "Sumario",
1182
+ searchPlaceholder: "Pesquisar texto...",
1183
+ searchGo: "Buscar",
1184
+ results: "resultados",
1185
+ searching: "Pesquisando...",
1186
+ noResults: "Nenhum resultado.",
1187
+ noSummary: "Sem sumario.",
1188
+ noAnnotations: "Sem anotacoes.",
1189
+ untitled: "Sem titulo",
1190
+ pageTransition: "Transicao de pagina",
1191
+ continuous: "Continuo",
1192
+ pageByPage: "Pagina por pagina",
1193
+ layout: "Layout",
1194
+ singlePage: "Pagina unica",
1195
+ doublePage: "Pagina dupla",
1196
+ rotate: "Girar",
1197
+ clockwise: "Sentido horario",
1198
+ counterclockwise: "Sentido anti-horario",
1199
+ zoom: "Zoom",
1200
+ highlight: "Marca texto",
1201
+ strike: "Risco",
1202
+ text: "Texto",
1203
+ note: "Nota",
1204
+ editNote: "Editar nota",
1205
+ notePlaceholder: "Escreva sua nota...",
1206
+ cancel: "Cancelar",
1207
+ save: "Salvar",
1208
+ language: "Idioma",
1209
+ english: "Ingles",
1210
+ portuguese: "Portugues (BR)",
1211
+ appearance: "Aparencia",
1212
+ light: "Claro",
1213
+ dark: "Escuro",
1214
+ pageTheme: "Tema da pagina",
1215
+ themeOriginal: "Original",
1216
+ themeSepia: "Sepia",
1217
+ themeDark: "Escuro",
1218
+ themeContrast: "Contraste"
1219
+ }
1220
+ };
1221
+ var getStrings = (locale) => STRINGS[locale ?? "en"] ?? STRINGS.en;
1222
+
1223
+ // components/ToolDock.tsx
1224
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1225
+ var COLOR_SWATCHES = [
1226
+ "#fbbf24",
1227
+ "#f97316",
1228
+ "#ef4444",
1229
+ "#10b981",
1230
+ "#22d3ee",
1231
+ "#3b82f6",
1232
+ "#8b5cf6",
1233
+ "#ec4899",
1234
+ "#f3f4f6",
1235
+ "#111827"
1236
+ ];
1237
+ var ToolDock = () => {
1238
+ const { selectionActive, uiTheme, locale, annotationColor, setAnnotationColor, accentColor } = (0, import_core4.useViewerStore)();
1239
+ const isDark = uiTheme === "dark";
1240
+ const isVisible = selectionActive;
1241
+ const t = getStrings(locale);
1242
+ if (!isVisible) return null;
1243
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native4.View, { style: [styles4.container, isDark && styles4.containerDark], children: [
1244
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native4.Text, { style: [styles4.title, isDark && styles4.titleDark], children: t.highlight }),
1245
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native4.View, { style: styles4.paletteRow, children: COLOR_SWATCHES.map((color) => {
1246
+ const isSelected = annotationColor === color;
1247
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1248
+ import_react_native4.Pressable,
1249
+ {
1250
+ onPress: () => setAnnotationColor(color),
1251
+ style: [
1252
+ styles4.swatch,
1253
+ { backgroundColor: color },
1254
+ isSelected && styles4.swatchSelected,
1255
+ isSelected && { borderColor: accentColor }
1256
+ ]
1257
+ },
1258
+ color
1259
+ );
1260
+ }) })
1261
+ ] });
1262
+ };
1263
+ var styles4 = import_react_native4.StyleSheet.create({
1264
+ container: {
1265
+ position: "absolute",
1266
+ left: 16,
1267
+ right: 16,
1268
+ bottom: 72,
1269
+ paddingVertical: 10,
1270
+ paddingHorizontal: 12,
1271
+ borderRadius: 16,
1272
+ backgroundColor: "#ffffff",
1273
+ borderWidth: 1,
1274
+ borderColor: "#e5e7eb",
1275
+ shadowColor: "#000000",
1276
+ shadowOpacity: 0.15,
1277
+ shadowRadius: 14,
1278
+ shadowOffset: { width: 0, height: 6 },
1279
+ elevation: 6
1280
+ },
1281
+ containerDark: {
1282
+ backgroundColor: "#0f1115",
1283
+ borderColor: "#1f2937"
1284
+ },
1285
+ title: {
1286
+ fontSize: 11,
1287
+ fontWeight: "800",
1288
+ color: "#111827",
1289
+ marginBottom: 8
1290
+ },
1291
+ titleDark: {
1292
+ color: "#e5e7eb"
1293
+ },
1294
+ paletteRow: {
1295
+ flexDirection: "row",
1296
+ flexWrap: "wrap"
1297
+ },
1298
+ swatch: {
1299
+ width: 20,
1300
+ height: 20,
1301
+ borderRadius: 10,
1302
+ marginRight: 8,
1303
+ marginBottom: 8,
1304
+ borderWidth: 1,
1305
+ borderColor: "#e5e7eb"
1306
+ },
1307
+ swatchSelected: {
1308
+ borderColor: "#2563eb",
1309
+ borderWidth: 2
1310
+ }
1311
+ });
1312
+ var ToolDock_default = ToolDock;
1313
+
1314
+ // components/RightSheet.tsx
1315
+ var import_react4 = require("react");
1316
+ var import_react_native5 = require("react-native");
1317
+ var import_core5 = require("@papyrus-sdk/core");
1318
+ var import_engine_native2 = require("@papyrus-sdk/engine-native");
1319
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1320
+ var withAlpha = (hex, alpha) => {
1321
+ const normalized = hex.replace("#", "").trim();
1322
+ const value = normalized.length === 3 ? normalized.split("").map((c) => c + c).join("") : normalized;
1323
+ if (value.length !== 6) return hex;
1324
+ const r = parseInt(value.slice(0, 2), 16);
1325
+ const g = parseInt(value.slice(2, 4), 16);
1326
+ const b = parseInt(value.slice(4, 6), 16);
1327
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
1328
+ };
1329
+ var PageThumbnail = ({ engine, pageIndex, isActive, isDark, zoom, cardWidth, frameWidth, frameHeight, accentColor, onPress }) => {
1330
+ const viewRef = (0, import_react4.useRef)(null);
1331
+ const [layoutReady, setLayoutReady] = (0, import_react4.useState)(false);
1332
+ (0, import_react4.useEffect)(() => {
1333
+ if (!layoutReady) return;
1334
+ const viewTag = (0, import_react_native5.findNodeHandle)(viewRef.current);
1335
+ if (!viewTag) return;
1336
+ const renderScale = 2 / Math.max(zoom, 0.5);
1337
+ void engine.renderPage(pageIndex, viewTag, renderScale);
1338
+ }, [engine, pageIndex, layoutReady, zoom]);
1339
+ const handleLayout = (event) => {
1340
+ if (event.nativeEvent.layout.width && event.nativeEvent.layout.height) {
1341
+ setLayoutReady(true);
1342
+ }
1343
+ };
1344
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1345
+ import_react_native5.Pressable,
1346
+ {
1347
+ onPress,
1348
+ style: [
1349
+ styles5.thumbCard,
1350
+ { width: cardWidth },
1351
+ isDark && styles5.thumbCardDark,
1352
+ isActive && styles5.thumbCardActive,
1353
+ isActive && { borderColor: accentColor }
1354
+ ],
1355
+ children: [
1356
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.View, { onLayout: handleLayout, style: [styles5.thumbFrame, { width: frameWidth, height: frameHeight }], children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_engine_native2.PapyrusPageView, { ref: viewRef, style: styles5.thumbView }) }),
1357
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.Text, { style: [styles5.thumbLabel, isDark && styles5.thumbLabelDark], children: pageIndex + 1 })
1358
+ ]
1359
+ }
1360
+ );
1361
+ };
1362
+ var OutlineNode = ({ item, depth = 0, isDark, onSelect, untitledLabel }) => {
1363
+ const hasChildren = item.children && item.children.length > 0;
1364
+ const isClickable = item.pageIndex >= 0;
1365
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native5.View, { children: [
1366
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1367
+ import_react_native5.Pressable,
1368
+ {
1369
+ onPress: () => {
1370
+ if (isClickable) onSelect(item.pageIndex);
1371
+ },
1372
+ style: [styles5.outlineRow, { paddingLeft: 12 + depth * 12 }],
1373
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1374
+ import_react_native5.Text,
1375
+ {
1376
+ style: [
1377
+ styles5.outlineText,
1378
+ isDark && styles5.outlineTextDark,
1379
+ !isClickable && styles5.outlineTextMuted
1380
+ ],
1381
+ numberOfLines: 2,
1382
+ children: item.title || untitledLabel
1383
+ }
1384
+ )
1385
+ }
1386
+ ),
1387
+ hasChildren && item.children.map((child, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1388
+ OutlineNode,
1389
+ {
1390
+ item: child,
1391
+ depth: depth + 1,
1392
+ isDark,
1393
+ onSelect,
1394
+ untitledLabel
1395
+ },
1396
+ `${child.title}-${index}`
1397
+ ))
1398
+ ] });
1399
+ };
1400
+ var RightSheet = ({ engine }) => {
1401
+ const {
1402
+ sidebarRightOpen,
1403
+ sidebarRightTab,
1404
+ toggleSidebarRight,
1405
+ outline,
1406
+ searchResults,
1407
+ searchQuery,
1408
+ activeSearchIndex,
1409
+ nextSearchResult,
1410
+ prevSearchResult,
1411
+ annotations,
1412
+ uiTheme,
1413
+ setSearch,
1414
+ setDocumentState,
1415
+ triggerScrollToPage,
1416
+ setSelectedAnnotation,
1417
+ pageCount,
1418
+ currentPage,
1419
+ zoom,
1420
+ locale,
1421
+ accentColor
1422
+ } = (0, import_core5.useViewerStore)();
1423
+ const [pagesMode, setPagesMode] = (0, import_react4.useState)("thumbnails");
1424
+ const [query, setQuery] = (0, import_react4.useState)("");
1425
+ const [isSearching, setIsSearching] = (0, import_react4.useState)(false);
1426
+ const searchService = (0, import_react4.useMemo)(() => new import_core5.SearchService(engine), [engine]);
1427
+ const isDark = uiTheme === "dark";
1428
+ const accentSoft = withAlpha(accentColor, 0.2);
1429
+ const accentStrong = withAlpha(accentColor, 0.35);
1430
+ const t = getStrings(locale);
1431
+ const sheetHeight = Math.min(640, import_react_native5.Dimensions.get("window").height * 0.72);
1432
+ const windowWidth = import_react_native5.Dimensions.get("window").width;
1433
+ const gridGutter = 12;
1434
+ const gridPadding = 16;
1435
+ const cardWidth = (windowWidth - gridPadding * 2 - gridGutter) / 2;
1436
+ const frameWidth = cardWidth - 16;
1437
+ const frameHeight = frameWidth * 1.28;
1438
+ const closeSheet = () => toggleSidebarRight();
1439
+ const handleSearch = async () => {
1440
+ const trimmed = query.trim();
1441
+ if (!trimmed) {
1442
+ setSearch("", []);
1443
+ return;
1444
+ }
1445
+ setIsSearching(true);
1446
+ try {
1447
+ const results = await searchService.search(trimmed);
1448
+ setSearch(trimmed, results);
1449
+ } finally {
1450
+ setIsSearching(false);
1451
+ }
1452
+ };
1453
+ const pages = (0, import_react4.useMemo)(() => Array.from({ length: pageCount }, (_, i) => i), [pageCount]);
1454
+ const renderHighlightedSnippet = (text, isActive) => {
1455
+ const trimmedQuery = searchQuery.trim();
1456
+ if (trimmedQuery.length < 2) {
1457
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1458
+ import_react_native5.Text,
1459
+ {
1460
+ style: [
1461
+ styles5.resultText,
1462
+ isDark && styles5.resultTextDark,
1463
+ isActive && styles5.resultTextActive,
1464
+ isActive && { color: accentColor }
1465
+ ],
1466
+ children: [
1467
+ "...",
1468
+ text,
1469
+ "..."
1470
+ ]
1471
+ }
1472
+ );
1473
+ }
1474
+ const lowerText = text.toLowerCase();
1475
+ const lowerQuery = trimmedQuery.toLowerCase();
1476
+ const parts = [];
1477
+ let cursor = 0;
1478
+ while (cursor < text.length) {
1479
+ const index = lowerText.indexOf(lowerQuery, cursor);
1480
+ if (index === -1) {
1481
+ parts.push({ text: text.slice(cursor), match: false });
1482
+ break;
1483
+ }
1484
+ if (index > cursor) {
1485
+ parts.push({ text: text.slice(cursor, index), match: false });
1486
+ }
1487
+ parts.push({ text: text.slice(index, index + trimmedQuery.length), match: true });
1488
+ cursor = index + trimmedQuery.length;
1489
+ }
1490
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1491
+ import_react_native5.Text,
1492
+ {
1493
+ style: [
1494
+ styles5.resultText,
1495
+ isDark && styles5.resultTextDark,
1496
+ isActive && styles5.resultTextActive,
1497
+ isActive && { color: accentColor }
1498
+ ],
1499
+ children: parts.map((part, idx) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1500
+ import_react_native5.Text,
1501
+ {
1502
+ style: [
1503
+ part.match && styles5.matchText,
1504
+ part.match && isDark && styles5.matchTextDark,
1505
+ part.match && isActive && styles5.matchTextActive,
1506
+ part.match && isActive && { backgroundColor: accentStrong, color: accentColor }
1507
+ ],
1508
+ children: part.text
1509
+ },
1510
+ `${idx}-${part.text}`
1511
+ ))
1512
+ }
1513
+ );
1514
+ };
1515
+ if (!sidebarRightOpen) return null;
1516
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.Modal, { visible: true, transparent: true, animationType: "slide", onRequestClose: closeSheet, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native5.View, { style: styles5.modalRoot, children: [
1517
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.Pressable, { style: styles5.backdrop, onPress: closeSheet }),
1518
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native5.View, { style: [styles5.sheet, { height: sheetHeight }, isDark && styles5.sheetDark], children: [
1519
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.View, { style: [styles5.handle, isDark && styles5.handleDark] }),
1520
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.View, { style: styles5.tabs, children: ["pages", "search", "annotations"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1521
+ import_react_native5.Pressable,
1522
+ {
1523
+ onPress: () => toggleSidebarRight(tab),
1524
+ style: [
1525
+ styles5.tabButton,
1526
+ isDark && styles5.tabButtonDark,
1527
+ sidebarRightTab === tab && styles5.tabButtonActive,
1528
+ sidebarRightTab === tab && { backgroundColor: accentColor }
1529
+ ],
1530
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1531
+ import_react_native5.Text,
1532
+ {
1533
+ style: [
1534
+ styles5.tabText,
1535
+ isDark && styles5.tabTextDark,
1536
+ sidebarRightTab === tab && styles5.tabTextActive
1537
+ ],
1538
+ children: tab === "pages" ? t.pages : tab === "search" ? t.search : t.notes
1539
+ }
1540
+ )
1541
+ },
1542
+ tab
1543
+ )) }),
1544
+ sidebarRightTab === "pages" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native5.View, { style: styles5.pagesContent, children: [
1545
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native5.View, { style: styles5.pageHeader, children: [
1546
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native5.Text, { style: [styles5.pageStatus, isDark && styles5.pageStatusDark], children: [
1547
+ t.page,
1548
+ " ",
1549
+ currentPage,
1550
+ " / ",
1551
+ pageCount
1552
+ ] }),
1553
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native5.View, { style: [styles5.segmented, isDark && styles5.segmentedDark], children: [
1554
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1555
+ import_react_native5.Pressable,
1556
+ {
1557
+ onPress: () => setPagesMode("thumbnails"),
1558
+ style: [
1559
+ styles5.segmentButton,
1560
+ pagesMode === "thumbnails" && styles5.segmentButtonActive,
1561
+ pagesMode === "thumbnails" && { backgroundColor: accentColor }
1562
+ ],
1563
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1564
+ import_react_native5.Text,
1565
+ {
1566
+ style: [
1567
+ styles5.segmentText,
1568
+ isDark && styles5.segmentTextDark,
1569
+ pagesMode === "thumbnails" && styles5.segmentTextActive
1570
+ ],
1571
+ children: t.pagesTab
1572
+ }
1573
+ )
1574
+ }
1575
+ ),
1576
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1577
+ import_react_native5.Pressable,
1578
+ {
1579
+ onPress: () => setPagesMode("summary"),
1580
+ style: [
1581
+ styles5.segmentButton,
1582
+ pagesMode === "summary" && styles5.segmentButtonActive,
1583
+ pagesMode === "summary" && { backgroundColor: accentColor }
1584
+ ],
1585
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1586
+ import_react_native5.Text,
1587
+ {
1588
+ style: [
1589
+ styles5.segmentText,
1590
+ isDark && styles5.segmentTextDark,
1591
+ pagesMode === "summary" && styles5.segmentTextActive
1592
+ ],
1593
+ children: t.summaryTab
1594
+ }
1595
+ )
1596
+ }
1597
+ )
1598
+ ] })
1599
+ ] }),
1600
+ pagesMode === "thumbnails" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1601
+ import_react_native5.FlatList,
1602
+ {
1603
+ data: pages,
1604
+ keyExtractor: (item) => `thumb-${item}`,
1605
+ numColumns: 2,
1606
+ contentContainerStyle: styles5.thumbGrid,
1607
+ columnWrapperStyle: styles5.thumbRow,
1608
+ showsVerticalScrollIndicator: false,
1609
+ initialNumToRender: 6,
1610
+ renderItem: ({ item }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1611
+ PageThumbnail,
1612
+ {
1613
+ engine,
1614
+ pageIndex: item,
1615
+ isActive: item + 1 === currentPage,
1616
+ isDark,
1617
+ zoom,
1618
+ cardWidth,
1619
+ frameWidth,
1620
+ frameHeight,
1621
+ accentColor,
1622
+ onPress: () => {
1623
+ engine.goToPage(item + 1);
1624
+ setDocumentState({ currentPage: item + 1 });
1625
+ triggerScrollToPage(item);
1626
+ closeSheet();
1627
+ }
1628
+ }
1629
+ )
1630
+ }
1631
+ ) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.ScrollView, { contentContainerStyle: styles5.summaryContent, showsVerticalScrollIndicator: false, children: outline.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.Text, { style: [styles5.emptyText, isDark && styles5.emptyTextDark], children: t.noSummary }) : outline.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1632
+ OutlineNode,
1633
+ {
1634
+ item,
1635
+ isDark,
1636
+ untitledLabel: t.untitled,
1637
+ onSelect: (pageIndex) => {
1638
+ engine.goToPage(pageIndex + 1);
1639
+ setDocumentState({ currentPage: pageIndex + 1 });
1640
+ triggerScrollToPage(pageIndex);
1641
+ closeSheet();
1642
+ }
1643
+ },
1644
+ `${item.title}-${index}`
1645
+ )) })
1646
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.ScrollView, { contentContainerStyle: styles5.content, showsVerticalScrollIndicator: false, children: sidebarRightTab === "search" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native5.View, { children: [
1647
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native5.View, { style: [styles5.searchBox, isDark && styles5.searchBoxDark], children: [
1648
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1649
+ import_react_native5.TextInput,
1650
+ {
1651
+ value: query,
1652
+ onChangeText: setQuery,
1653
+ placeholder: t.searchPlaceholder,
1654
+ placeholderTextColor: isDark ? "#9ca3af" : "#6b7280",
1655
+ style: [styles5.searchInput, isDark && styles5.searchInputDark],
1656
+ onSubmitEditing: handleSearch,
1657
+ returnKeyType: "search"
1658
+ }
1659
+ ),
1660
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.Pressable, { onPress: handleSearch, style: [styles5.searchButton, { backgroundColor: accentColor }], children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.Text, { style: styles5.searchButtonText, children: t.searchGo }) })
1661
+ ] }),
1662
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native5.View, { style: styles5.searchMeta, children: [
1663
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native5.Text, { style: [styles5.searchCount, isDark && styles5.searchCountDark, { color: accentColor }], children: [
1664
+ searchResults.length,
1665
+ " ",
1666
+ t.results
1667
+ ] }),
1668
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native5.View, { style: styles5.searchNav, children: [
1669
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1670
+ import_react_native5.Pressable,
1671
+ {
1672
+ onPress: prevSearchResult,
1673
+ disabled: searchResults.length === 0,
1674
+ style: [
1675
+ styles5.searchNavButton,
1676
+ isDark && styles5.searchNavButtonDark,
1677
+ searchResults.length === 0 && styles5.searchNavButtonDisabled
1678
+ ],
1679
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconChevronLeft, { size: 14, color: isDark ? "#e5e7eb" : "#111827" })
1680
+ }
1681
+ ),
1682
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1683
+ import_react_native5.Pressable,
1684
+ {
1685
+ onPress: nextSearchResult,
1686
+ disabled: searchResults.length === 0,
1687
+ style: [
1688
+ styles5.searchNavButton,
1689
+ isDark && styles5.searchNavButtonDark,
1690
+ searchResults.length === 0 && styles5.searchNavButtonDisabled
1691
+ ],
1692
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconChevronRight, { size: 14, color: isDark ? "#e5e7eb" : "#111827" })
1693
+ }
1694
+ )
1695
+ ] })
1696
+ ] }),
1697
+ isSearching && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native5.View, { style: styles5.searchStatus, children: [
1698
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.ActivityIndicator, { size: "small", color: accentColor }),
1699
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.Text, { style: [styles5.searchStatusText, isDark && styles5.searchStatusTextDark], children: t.searching })
1700
+ ] }),
1701
+ !isSearching && searchResults.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.Text, { style: [styles5.emptyText, isDark && styles5.emptyTextDark], children: t.noResults }),
1702
+ !isSearching && searchResults.map((res, idx) => {
1703
+ const isActive = idx === activeSearchIndex;
1704
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1705
+ import_react_native5.Pressable,
1706
+ {
1707
+ onPress: () => {
1708
+ setDocumentState({ activeSearchIndex: idx });
1709
+ triggerScrollToPage(res.pageIndex);
1710
+ closeSheet();
1711
+ },
1712
+ style: [
1713
+ styles5.resultCard,
1714
+ isDark && styles5.resultCardDark,
1715
+ isActive && styles5.resultCardActive,
1716
+ isActive && { borderColor: accentColor }
1717
+ ],
1718
+ children: [
1719
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native5.Text, { style: [styles5.resultPage, isDark && styles5.resultPageDark, { color: accentColor }], children: [
1720
+ t.page,
1721
+ " ",
1722
+ res.pageIndex + 1
1723
+ ] }),
1724
+ renderHighlightedSnippet(res.text, isActive)
1725
+ ]
1726
+ },
1727
+ `${res.pageIndex}-${idx}`
1728
+ );
1729
+ })
1730
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.View, { children: annotations.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.Text, { style: [styles5.emptyText, isDark && styles5.emptyTextDark], children: t.noAnnotations }) : annotations.map((ann) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1731
+ import_react_native5.Pressable,
1732
+ {
1733
+ onPress: () => {
1734
+ setSelectedAnnotation(ann.id);
1735
+ triggerScrollToPage(ann.pageIndex);
1736
+ closeSheet();
1737
+ },
1738
+ style: [styles5.noteCard, isDark && styles5.noteCardDark],
1739
+ children: [
1740
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native5.View, { style: styles5.noteHeader, children: [
1741
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.View, { style: [styles5.noteDot, { backgroundColor: ann.color }] }),
1742
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native5.Text, { style: [styles5.noteTitle, isDark && styles5.noteTitleDark], children: [
1743
+ t.page,
1744
+ " ",
1745
+ ann.pageIndex + 1
1746
+ ] })
1747
+ ] }),
1748
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.Text, { style: [styles5.noteType, isDark && styles5.noteTypeDark, { color: accentColor }], children: ann.type === "comment" || ann.type === "text" ? t.note.toUpperCase() : ann.type.toUpperCase() }),
1749
+ ann.content ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native5.Text, { style: [styles5.noteContent, isDark && styles5.noteContentDark], children: ann.content }) : null
1750
+ ]
1751
+ },
1752
+ ann.id
1753
+ )) }) })
1754
+ ] })
1755
+ ] }) });
1756
+ };
1757
+ var styles5 = import_react_native5.StyleSheet.create({
1758
+ modalRoot: {
1759
+ flex: 1,
1760
+ backgroundColor: "transparent"
1761
+ },
1762
+ backdrop: {
1763
+ ...import_react_native5.StyleSheet.absoluteFillObject,
1764
+ backgroundColor: "rgba(0, 0, 0, 0.4)"
1765
+ },
1766
+ sheet: {
1767
+ position: "absolute",
1768
+ left: 0,
1769
+ right: 0,
1770
+ bottom: 0,
1771
+ backgroundColor: "#ffffff",
1772
+ borderTopLeftRadius: 20,
1773
+ borderTopRightRadius: 20,
1774
+ borderTopWidth: 1,
1775
+ borderTopColor: "#e5e7eb",
1776
+ paddingBottom: 16
1777
+ },
1778
+ sheetDark: {
1779
+ backgroundColor: "#0f1115",
1780
+ borderTopColor: "#1f2937"
1781
+ },
1782
+ handle: {
1783
+ width: 44,
1784
+ height: 4,
1785
+ borderRadius: 999,
1786
+ backgroundColor: "#cbd5f5",
1787
+ alignSelf: "center",
1788
+ marginTop: 10,
1789
+ marginBottom: 12
1790
+ },
1791
+ handleDark: {
1792
+ backgroundColor: "#374151"
1793
+ },
1794
+ tabs: {
1795
+ flexDirection: "row",
1796
+ alignItems: "center",
1797
+ paddingHorizontal: 16,
1798
+ marginBottom: 10
1799
+ },
1800
+ tabButton: {
1801
+ paddingVertical: 6,
1802
+ paddingHorizontal: 14,
1803
+ borderRadius: 999,
1804
+ marginRight: 8,
1805
+ backgroundColor: "#e5e7eb"
1806
+ },
1807
+ tabButtonDark: {
1808
+ backgroundColor: "#111827"
1809
+ },
1810
+ tabButtonActive: {
1811
+ backgroundColor: "#2563eb"
1812
+ },
1813
+ tabText: {
1814
+ fontSize: 12,
1815
+ fontWeight: "700",
1816
+ color: "#111827"
1817
+ },
1818
+ tabTextDark: {
1819
+ color: "#e5e7eb"
1820
+ },
1821
+ tabTextActive: {
1822
+ color: "#ffffff"
1823
+ },
1824
+ pagesContent: {
1825
+ paddingHorizontal: 16,
1826
+ flex: 1
1827
+ },
1828
+ pageHeader: {
1829
+ flexDirection: "row",
1830
+ alignItems: "center",
1831
+ justifyContent: "space-between",
1832
+ marginBottom: 10
1833
+ },
1834
+ pageStatus: {
1835
+ fontSize: 12,
1836
+ fontWeight: "700",
1837
+ color: "#111827"
1838
+ },
1839
+ pageStatusDark: {
1840
+ color: "#e5e7eb"
1841
+ },
1842
+ segmented: {
1843
+ flexDirection: "row",
1844
+ backgroundColor: "#e5e7eb",
1845
+ borderRadius: 999,
1846
+ padding: 2
1847
+ },
1848
+ segmentedDark: {
1849
+ backgroundColor: "#111827"
1850
+ },
1851
+ segmentButton: {
1852
+ paddingHorizontal: 10,
1853
+ paddingVertical: 5,
1854
+ borderRadius: 999
1855
+ },
1856
+ segmentButtonActive: {
1857
+ backgroundColor: "#2563eb"
1858
+ },
1859
+ segmentText: {
1860
+ fontSize: 11,
1861
+ fontWeight: "700",
1862
+ color: "#111827"
1863
+ },
1864
+ segmentTextDark: {
1865
+ color: "#e5e7eb"
1866
+ },
1867
+ segmentTextActive: {
1868
+ color: "#ffffff"
1869
+ },
1870
+ thumbGrid: {
1871
+ paddingHorizontal: 16,
1872
+ paddingBottom: 16
1873
+ },
1874
+ thumbRow: {
1875
+ justifyContent: "space-between",
1876
+ marginBottom: 12
1877
+ },
1878
+ thumbCard: {
1879
+ padding: 8,
1880
+ borderRadius: 14,
1881
+ backgroundColor: "#f9fafb",
1882
+ borderWidth: 1,
1883
+ borderColor: "#e5e7eb",
1884
+ alignItems: "center"
1885
+ },
1886
+ thumbCardDark: {
1887
+ backgroundColor: "#111827",
1888
+ borderColor: "#1f2937"
1889
+ },
1890
+ thumbCardActive: {
1891
+ borderColor: "#2563eb"
1892
+ },
1893
+ thumbFrame: {
1894
+ borderRadius: 10,
1895
+ backgroundColor: "#ffffff",
1896
+ overflow: "hidden"
1897
+ },
1898
+ thumbView: {
1899
+ width: "100%",
1900
+ height: "100%"
1901
+ },
1902
+ thumbLabel: {
1903
+ marginTop: 6,
1904
+ fontSize: 11,
1905
+ fontWeight: "700",
1906
+ color: "#111827"
1907
+ },
1908
+ thumbLabelDark: {
1909
+ color: "#e5e7eb"
1910
+ },
1911
+ content: {
1912
+ paddingHorizontal: 16,
1913
+ paddingBottom: 16
1914
+ },
1915
+ summaryContent: {
1916
+ paddingBottom: 24
1917
+ },
1918
+ outlineRow: {
1919
+ paddingVertical: 8,
1920
+ borderBottomWidth: 1,
1921
+ borderBottomColor: "rgba(148, 163, 184, 0.18)"
1922
+ },
1923
+ outlineText: {
1924
+ fontSize: 12,
1925
+ fontWeight: "600",
1926
+ color: "#111827"
1927
+ },
1928
+ outlineTextDark: {
1929
+ color: "#e5e7eb"
1930
+ },
1931
+ outlineTextMuted: {
1932
+ color: "#9ca3af"
1933
+ },
1934
+ searchBox: {
1935
+ flexDirection: "row",
1936
+ alignItems: "center",
1937
+ borderRadius: 10,
1938
+ backgroundColor: "#f3f4f6",
1939
+ paddingHorizontal: 12,
1940
+ paddingVertical: 8,
1941
+ borderWidth: 1,
1942
+ borderColor: "#e5e7eb"
1943
+ },
1944
+ searchBoxDark: {
1945
+ backgroundColor: "#111827",
1946
+ borderColor: "#1f2937"
1947
+ },
1948
+ searchInput: {
1949
+ flex: 1,
1950
+ fontSize: 12,
1951
+ color: "#111827"
1952
+ },
1953
+ searchInputDark: {
1954
+ color: "#e5e7eb"
1955
+ },
1956
+ searchButton: {
1957
+ paddingHorizontal: 10,
1958
+ paddingVertical: 4,
1959
+ borderRadius: 6,
1960
+ backgroundColor: "#2563eb"
1961
+ },
1962
+ searchButtonText: {
1963
+ fontSize: 11,
1964
+ fontWeight: "700",
1965
+ color: "#ffffff"
1966
+ },
1967
+ searchStatus: {
1968
+ marginTop: 12,
1969
+ flexDirection: "row",
1970
+ alignItems: "center"
1971
+ },
1972
+ searchStatusText: {
1973
+ marginLeft: 8,
1974
+ fontSize: 11,
1975
+ color: "#4b5563"
1976
+ },
1977
+ searchStatusTextDark: {
1978
+ color: "#9ca3af"
1979
+ },
1980
+ searchMeta: {
1981
+ marginTop: 12,
1982
+ flexDirection: "row",
1983
+ alignItems: "center",
1984
+ justifyContent: "space-between"
1985
+ },
1986
+ searchCount: {
1987
+ fontSize: 11,
1988
+ fontWeight: "700",
1989
+ color: "#2563eb"
1990
+ },
1991
+ searchCountDark: {
1992
+ color: "#60a5fa"
1993
+ },
1994
+ searchNav: {
1995
+ flexDirection: "row",
1996
+ alignItems: "center"
1997
+ },
1998
+ searchNavButton: {
1999
+ width: 28,
2000
+ height: 28,
2001
+ borderRadius: 10,
2002
+ backgroundColor: "#e5e7eb",
2003
+ alignItems: "center",
2004
+ justifyContent: "center",
2005
+ marginLeft: 6
2006
+ },
2007
+ searchNavButtonDark: {
2008
+ backgroundColor: "#111827"
2009
+ },
2010
+ searchNavButtonDisabled: {
2011
+ opacity: 0.5
2012
+ },
2013
+ emptyText: {
2014
+ marginTop: 16,
2015
+ fontSize: 12,
2016
+ color: "#6b7280"
2017
+ },
2018
+ emptyTextDark: {
2019
+ color: "#9ca3af"
2020
+ },
2021
+ resultCard: {
2022
+ marginTop: 12,
2023
+ padding: 12,
2024
+ borderRadius: 12,
2025
+ backgroundColor: "#f9fafb",
2026
+ borderWidth: 1,
2027
+ borderColor: "#e5e7eb"
2028
+ },
2029
+ resultCardDark: {
2030
+ backgroundColor: "#111827",
2031
+ borderColor: "#1f2937"
2032
+ },
2033
+ resultCardActive: {
2034
+ borderColor: "#2563eb"
2035
+ },
2036
+ resultPage: {
2037
+ fontSize: 10,
2038
+ fontWeight: "800",
2039
+ color: "#2563eb",
2040
+ marginBottom: 6
2041
+ },
2042
+ resultPageDark: {
2043
+ color: "#60a5fa"
2044
+ },
2045
+ resultText: {
2046
+ fontSize: 11,
2047
+ color: "#374151"
2048
+ },
2049
+ resultTextDark: {
2050
+ color: "#d1d5db"
2051
+ },
2052
+ resultTextActive: {
2053
+ color: "#1d4ed8"
2054
+ },
2055
+ matchText: {
2056
+ backgroundColor: "rgba(245, 158, 11, 0.3)",
2057
+ color: "#111827",
2058
+ fontWeight: "700"
2059
+ },
2060
+ matchTextDark: {
2061
+ backgroundColor: "rgba(245, 158, 11, 0.25)",
2062
+ color: "#fde68a"
2063
+ },
2064
+ matchTextActive: {
2065
+ backgroundColor: "rgba(59, 130, 246, 0.35)",
2066
+ color: "#1d4ed8"
2067
+ },
2068
+ noteCard: {
2069
+ padding: 12,
2070
+ borderRadius: 12,
2071
+ backgroundColor: "#f9fafb",
2072
+ borderWidth: 1,
2073
+ borderColor: "#e5e7eb",
2074
+ marginBottom: 12
2075
+ },
2076
+ noteCardDark: {
2077
+ backgroundColor: "#111827",
2078
+ borderColor: "#1f2937"
2079
+ },
2080
+ noteHeader: {
2081
+ flexDirection: "row",
2082
+ alignItems: "center",
2083
+ marginBottom: 6
2084
+ },
2085
+ noteDot: {
2086
+ width: 8,
2087
+ height: 8,
2088
+ borderRadius: 4,
2089
+ marginRight: 6
2090
+ },
2091
+ noteTitle: {
2092
+ fontSize: 11,
2093
+ fontWeight: "700",
2094
+ color: "#111827"
2095
+ },
2096
+ noteTitleDark: {
2097
+ color: "#e5e7eb"
2098
+ },
2099
+ noteType: {
2100
+ fontSize: 10,
2101
+ fontWeight: "800",
2102
+ color: "#2563eb"
2103
+ },
2104
+ noteTypeDark: {
2105
+ color: "#60a5fa"
2106
+ },
2107
+ noteContent: {
2108
+ marginTop: 6,
2109
+ fontSize: 11,
2110
+ color: "#4b5563"
2111
+ },
2112
+ noteContentDark: {
2113
+ color: "#9ca3af"
2114
+ }
2115
+ });
2116
+ var RightSheet_default = RightSheet;
2117
+
2118
+ // components/AnnotationEditor.tsx
2119
+ var import_react5 = require("react");
2120
+ var import_react_native6 = require("react-native");
2121
+ var import_core6 = require("@papyrus-sdk/core");
2122
+ var import_jsx_runtime7 = require("react/jsx-runtime");
2123
+ var AnnotationEditor = () => {
2124
+ const { annotations, selectedAnnotationId, updateAnnotation, setSelectedAnnotation, uiTheme, locale, accentColor } = (0, import_core6.useViewerStore)();
2125
+ const annotation = annotations.find((ann) => ann.id === selectedAnnotationId);
2126
+ const isEditable = annotation && (annotation.type === "text" || annotation.type === "comment");
2127
+ const [draft, setDraft] = (0, import_react5.useState)("");
2128
+ const isDark = uiTheme === "dark";
2129
+ const t = getStrings(locale);
2130
+ (0, import_react5.useEffect)(() => {
2131
+ if (isEditable) {
2132
+ setDraft(annotation?.content ?? "");
2133
+ }
2134
+ }, [annotation?.id, isEditable]);
2135
+ if (!isEditable || !annotation) return null;
2136
+ const handleClose = () => setSelectedAnnotation(null);
2137
+ const handleSave = () => {
2138
+ updateAnnotation(annotation.id, { content: draft });
2139
+ setSelectedAnnotation(null);
2140
+ };
2141
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native6.Modal, { visible: true, transparent: true, animationType: "fade", onRequestClose: handleClose, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native6.View, { style: styles6.overlay, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native6.View, { style: [styles6.card, isDark && styles6.cardDark], children: [
2142
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native6.Text, { style: [styles6.title, isDark && styles6.titleDark], children: t.editNote }),
2143
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2144
+ import_react_native6.TextInput,
2145
+ {
2146
+ style: [styles6.input, isDark && styles6.inputDark],
2147
+ value: draft,
2148
+ onChangeText: setDraft,
2149
+ placeholder: t.notePlaceholder,
2150
+ placeholderTextColor: isDark ? "#9ca3af" : "#6b7280",
2151
+ multiline: true
2152
+ }
2153
+ ),
2154
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native6.View, { style: styles6.actions, children: [
2155
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native6.Pressable, { onPress: handleClose, style: [styles6.actionButton, styles6.actionCancel], children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native6.Text, { style: styles6.actionText, children: t.cancel }) }),
2156
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native6.Pressable, { onPress: handleSave, style: [styles6.actionButton, styles6.actionSave, { backgroundColor: accentColor }], children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native6.Text, { style: [styles6.actionText, styles6.actionTextLight], children: t.save }) })
2157
+ ] })
2158
+ ] }) }) });
2159
+ };
2160
+ var styles6 = import_react_native6.StyleSheet.create({
2161
+ overlay: {
2162
+ flex: 1,
2163
+ alignItems: "center",
2164
+ justifyContent: "center",
2165
+ backgroundColor: "rgba(0, 0, 0, 0.4)",
2166
+ padding: 24
2167
+ },
2168
+ card: {
2169
+ width: "100%",
2170
+ borderRadius: 16,
2171
+ padding: 16,
2172
+ backgroundColor: "#ffffff",
2173
+ borderWidth: 1,
2174
+ borderColor: "#e5e7eb"
2175
+ },
2176
+ cardDark: {
2177
+ backgroundColor: "#0f1115",
2178
+ borderColor: "#1f2937"
2179
+ },
2180
+ title: {
2181
+ fontSize: 14,
2182
+ fontWeight: "700",
2183
+ color: "#111827",
2184
+ marginBottom: 12
2185
+ },
2186
+ titleDark: {
2187
+ color: "#f9fafb"
2188
+ },
2189
+ input: {
2190
+ minHeight: 100,
2191
+ borderRadius: 12,
2192
+ padding: 12,
2193
+ backgroundColor: "#f3f4f6",
2194
+ color: "#111827",
2195
+ fontSize: 12
2196
+ },
2197
+ inputDark: {
2198
+ backgroundColor: "#111827",
2199
+ color: "#e5e7eb"
2200
+ },
2201
+ actions: {
2202
+ marginTop: 16,
2203
+ flexDirection: "row",
2204
+ justifyContent: "flex-end"
2205
+ },
2206
+ actionButton: {
2207
+ paddingHorizontal: 12,
2208
+ paddingVertical: 8,
2209
+ borderRadius: 8,
2210
+ marginLeft: 8
2211
+ },
2212
+ actionCancel: {
2213
+ backgroundColor: "#e5e7eb"
2214
+ },
2215
+ actionSave: {
2216
+ backgroundColor: "#2563eb"
2217
+ },
2218
+ actionText: {
2219
+ fontSize: 11,
2220
+ fontWeight: "700",
2221
+ color: "#111827"
2222
+ },
2223
+ actionTextLight: {
2224
+ color: "#ffffff"
2225
+ }
2226
+ });
2227
+ var AnnotationEditor_default = AnnotationEditor;
2228
+
2229
+ // components/BottomBar.tsx
2230
+ var import_react_native7 = require("react-native");
2231
+ var import_core7 = require("@papyrus-sdk/core");
2232
+ var import_jsx_runtime8 = require("react/jsx-runtime");
2233
+ var BottomBar = () => {
2234
+ const { sidebarRightOpen, sidebarRightTab, toggleSidebarRight, setDocumentState, uiTheme, locale, accentColor } = (0, import_core7.useViewerStore)();
2235
+ const isDark = uiTheme === "dark";
2236
+ const t = getStrings(locale);
2237
+ const isActive = (tab) => sidebarRightOpen && sidebarRightTab === tab;
2238
+ const iconColor = (active) => {
2239
+ if (active) return "#ffffff";
2240
+ return isDark ? "#e5e7eb" : "#111827";
2241
+ };
2242
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native7.View, { style: [styles7.container, isDark && styles7.containerDark], children: [
2243
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2244
+ import_react_native7.Pressable,
2245
+ {
2246
+ onPress: () => toggleSidebarRight("pages"),
2247
+ style: [styles7.item, isActive("pages") && styles7.itemActive],
2248
+ children: [
2249
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2250
+ import_react_native7.View,
2251
+ {
2252
+ style: [
2253
+ styles7.itemIcon,
2254
+ isDark && styles7.itemIconDark,
2255
+ isActive("pages") && styles7.itemIconActive,
2256
+ isActive("pages") && { backgroundColor: accentColor }
2257
+ ],
2258
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconGrid, { size: 16, color: iconColor(isActive("pages")) })
2259
+ }
2260
+ ),
2261
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2262
+ import_react_native7.Text,
2263
+ {
2264
+ style: [
2265
+ styles7.itemLabel,
2266
+ isDark && styles7.itemLabelDark,
2267
+ isActive("pages") && styles7.itemLabelActive,
2268
+ isActive("pages") && { color: accentColor }
2269
+ ],
2270
+ children: t.pages
2271
+ }
2272
+ )
2273
+ ]
2274
+ }
2275
+ ),
2276
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2277
+ import_react_native7.Pressable,
2278
+ {
2279
+ onPress: () => toggleSidebarRight("search"),
2280
+ style: [styles7.item, isActive("search") && styles7.itemActive],
2281
+ children: [
2282
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2283
+ import_react_native7.View,
2284
+ {
2285
+ style: [
2286
+ styles7.itemIcon,
2287
+ isDark && styles7.itemIconDark,
2288
+ isActive("search") && styles7.itemIconActive,
2289
+ isActive("search") && { backgroundColor: accentColor }
2290
+ ],
2291
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconSearch, { size: 16, color: iconColor(isActive("search")) })
2292
+ }
2293
+ ),
2294
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2295
+ import_react_native7.Text,
2296
+ {
2297
+ style: [
2298
+ styles7.itemLabel,
2299
+ isDark && styles7.itemLabelDark,
2300
+ isActive("search") && styles7.itemLabelActive,
2301
+ isActive("search") && { color: accentColor }
2302
+ ],
2303
+ children: t.search
2304
+ }
2305
+ )
2306
+ ]
2307
+ }
2308
+ ),
2309
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2310
+ import_react_native7.Pressable,
2311
+ {
2312
+ onPress: () => setDocumentState({ sidebarRightOpen: false }),
2313
+ style: [styles7.item, !sidebarRightOpen && styles7.itemActive],
2314
+ children: [
2315
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2316
+ import_react_native7.View,
2317
+ {
2318
+ style: [
2319
+ styles7.itemIcon,
2320
+ isDark && styles7.itemIconDark,
2321
+ !sidebarRightOpen && styles7.itemIconActive,
2322
+ !sidebarRightOpen && { backgroundColor: accentColor }
2323
+ ],
2324
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconDocument, { size: 16, color: iconColor(!sidebarRightOpen) })
2325
+ }
2326
+ ),
2327
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2328
+ import_react_native7.Text,
2329
+ {
2330
+ style: [
2331
+ styles7.itemLabel,
2332
+ isDark && styles7.itemLabelDark,
2333
+ !sidebarRightOpen && styles7.itemLabelActive,
2334
+ !sidebarRightOpen && { color: accentColor }
2335
+ ],
2336
+ children: t.read
2337
+ }
2338
+ )
2339
+ ]
2340
+ }
2341
+ ),
2342
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2343
+ import_react_native7.Pressable,
2344
+ {
2345
+ onPress: () => toggleSidebarRight("annotations"),
2346
+ style: [styles7.item, isActive("annotations") && styles7.itemActive],
2347
+ children: [
2348
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2349
+ import_react_native7.View,
2350
+ {
2351
+ style: [
2352
+ styles7.itemIcon,
2353
+ isDark && styles7.itemIconDark,
2354
+ isActive("annotations") && styles7.itemIconActive,
2355
+ isActive("annotations") && { backgroundColor: accentColor }
2356
+ ],
2357
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconComment, { size: 16, color: iconColor(isActive("annotations")) })
2358
+ }
2359
+ ),
2360
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2361
+ import_react_native7.Text,
2362
+ {
2363
+ style: [
2364
+ styles7.itemLabel,
2365
+ isDark && styles7.itemLabelDark,
2366
+ isActive("annotations") && styles7.itemLabelActive,
2367
+ isActive("annotations") && { color: accentColor }
2368
+ ],
2369
+ children: t.notes
2370
+ }
2371
+ )
2372
+ ]
2373
+ }
2374
+ )
2375
+ ] });
2376
+ };
2377
+ var styles7 = import_react_native7.StyleSheet.create({
2378
+ container: {
2379
+ flexDirection: "row",
2380
+ justifyContent: "space-around",
2381
+ alignItems: "center",
2382
+ paddingVertical: 10,
2383
+ paddingHorizontal: 12,
2384
+ backgroundColor: "#ffffff",
2385
+ borderTopWidth: 1,
2386
+ borderTopColor: "#e5e7eb"
2387
+ },
2388
+ containerDark: {
2389
+ backgroundColor: "#0f1115",
2390
+ borderTopColor: "#1f2937"
2391
+ },
2392
+ item: {
2393
+ alignItems: "center",
2394
+ paddingHorizontal: 6
2395
+ },
2396
+ itemActive: {
2397
+ transform: [{ translateY: -2 }]
2398
+ },
2399
+ itemIcon: {
2400
+ width: 28,
2401
+ height: 28,
2402
+ borderRadius: 10,
2403
+ backgroundColor: "#e5e7eb",
2404
+ alignItems: "center",
2405
+ justifyContent: "center",
2406
+ marginBottom: 4
2407
+ },
2408
+ itemIconDark: {
2409
+ backgroundColor: "#111827",
2410
+ color: "#e5e7eb"
2411
+ },
2412
+ itemIconActive: {
2413
+ backgroundColor: "#2563eb",
2414
+ color: "#ffffff"
2415
+ },
2416
+ itemLabel: {
2417
+ fontSize: 10,
2418
+ fontWeight: "700",
2419
+ color: "#6b7280"
2420
+ },
2421
+ itemLabelDark: {
2422
+ color: "#9ca3af"
2423
+ },
2424
+ itemLabelActive: {
2425
+ color: "#2563eb"
2426
+ }
2427
+ });
2428
+ var BottomBar_default = BottomBar;
2429
+
2430
+ // components/SettingsSheet.tsx
2431
+ var import_react_native8 = require("react-native");
2432
+ var import_core8 = require("@papyrus-sdk/core");
2433
+ var import_jsx_runtime9 = require("react/jsx-runtime");
2434
+ var SettingsSheet = ({ engine, visible, onClose }) => {
2435
+ const { viewMode, uiTheme, zoom, setDocumentState, locale, accentColor, pageTheme } = (0, import_core8.useViewerStore)();
2436
+ const isDark = uiTheme === "dark";
2437
+ const isPaged = viewMode === "single";
2438
+ const isDouble = viewMode === "double";
2439
+ const t = getStrings(locale);
2440
+ const handleTransition = (mode) => {
2441
+ if (mode === "paged") {
2442
+ setDocumentState({ viewMode: "single" });
2443
+ return;
2444
+ }
2445
+ setDocumentState({ viewMode: isDouble ? "double" : "continuous" });
2446
+ };
2447
+ const handleLayout = (layout) => {
2448
+ if (layout === "double") {
2449
+ setDocumentState({ viewMode: "double" });
2450
+ return;
2451
+ }
2452
+ if (viewMode === "double") {
2453
+ setDocumentState({ viewMode: "continuous" });
2454
+ }
2455
+ };
2456
+ const handleRotate = (direction) => {
2457
+ engine.rotate(direction);
2458
+ setDocumentState({ rotation: engine.getRotation() });
2459
+ };
2460
+ const handleZoom = (delta) => {
2461
+ const next = Math.max(0.5, Math.min(4, zoom + delta));
2462
+ engine.setZoom(next);
2463
+ setDocumentState({ zoom: next });
2464
+ };
2465
+ if (!visible) return null;
2466
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native8.Modal, { visible: true, transparent: true, animationType: "slide", onRequestClose: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.View, { style: styles8.modalRoot, children: [
2467
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native8.Pressable, { style: styles8.backdrop, onPress: onClose }),
2468
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.View, { style: [styles8.sheet, isDark && styles8.sheetDark], children: [
2469
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native8.View, { style: [styles8.handle, isDark && styles8.handleDark] }),
2470
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.View, { style: styles8.section, children: [
2471
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native8.Text, { style: [styles8.sectionTitle, isDark && styles8.sectionTitleDark], children: t.appearance }),
2472
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.View, { style: styles8.optionRow, children: [
2473
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2474
+ import_react_native8.Pressable,
2475
+ {
2476
+ onPress: () => setDocumentState({ uiTheme: "light" }),
2477
+ style: [
2478
+ styles8.optionButton,
2479
+ isDark && styles8.optionButtonDark,
2480
+ uiTheme === "light" && styles8.optionButtonActive,
2481
+ uiTheme === "light" && { backgroundColor: accentColor }
2482
+ ],
2483
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2484
+ import_react_native8.Text,
2485
+ {
2486
+ style: [
2487
+ styles8.optionText,
2488
+ isDark && styles8.optionTextDark,
2489
+ uiTheme === "light" && styles8.optionTextActive
2490
+ ],
2491
+ children: t.light
2492
+ }
2493
+ )
2494
+ }
2495
+ ),
2496
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2497
+ import_react_native8.Pressable,
2498
+ {
2499
+ onPress: () => setDocumentState({ uiTheme: "dark" }),
2500
+ style: [
2501
+ styles8.optionButton,
2502
+ isDark && styles8.optionButtonDark,
2503
+ uiTheme === "dark" && styles8.optionButtonActive,
2504
+ uiTheme === "dark" && { backgroundColor: accentColor }
2505
+ ],
2506
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2507
+ import_react_native8.Text,
2508
+ {
2509
+ style: [
2510
+ styles8.optionText,
2511
+ isDark && styles8.optionTextDark,
2512
+ uiTheme === "dark" && styles8.optionTextActive
2513
+ ],
2514
+ children: t.dark
2515
+ }
2516
+ )
2517
+ }
2518
+ )
2519
+ ] })
2520
+ ] }),
2521
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.View, { style: styles8.section, children: [
2522
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native8.Text, { style: [styles8.sectionTitle, isDark && styles8.sectionTitleDark], children: t.pageTheme }),
2523
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.View, { style: styles8.optionRow, children: [
2524
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2525
+ import_react_native8.Pressable,
2526
+ {
2527
+ onPress: () => setDocumentState({ pageTheme: "normal" }),
2528
+ style: [
2529
+ styles8.optionButton,
2530
+ isDark && styles8.optionButtonDark,
2531
+ pageTheme === "normal" && styles8.optionButtonActive,
2532
+ pageTheme === "normal" && { backgroundColor: accentColor }
2533
+ ],
2534
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2535
+ import_react_native8.Text,
2536
+ {
2537
+ style: [
2538
+ styles8.optionText,
2539
+ isDark && styles8.optionTextDark,
2540
+ pageTheme === "normal" && styles8.optionTextActive
2541
+ ],
2542
+ children: t.themeOriginal
2543
+ }
2544
+ )
2545
+ }
2546
+ ),
2547
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2548
+ import_react_native8.Pressable,
2549
+ {
2550
+ onPress: () => setDocumentState({ pageTheme: "sepia" }),
2551
+ style: [
2552
+ styles8.optionButton,
2553
+ isDark && styles8.optionButtonDark,
2554
+ pageTheme === "sepia" && styles8.optionButtonActive,
2555
+ pageTheme === "sepia" && { backgroundColor: accentColor }
2556
+ ],
2557
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2558
+ import_react_native8.Text,
2559
+ {
2560
+ style: [
2561
+ styles8.optionText,
2562
+ isDark && styles8.optionTextDark,
2563
+ pageTheme === "sepia" && styles8.optionTextActive
2564
+ ],
2565
+ children: t.themeSepia
2566
+ }
2567
+ )
2568
+ }
2569
+ ),
2570
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2571
+ import_react_native8.Pressable,
2572
+ {
2573
+ onPress: () => setDocumentState({ pageTheme: "dark" }),
2574
+ style: [
2575
+ styles8.optionButton,
2576
+ isDark && styles8.optionButtonDark,
2577
+ pageTheme === "dark" && styles8.optionButtonActive,
2578
+ pageTheme === "dark" && { backgroundColor: accentColor }
2579
+ ],
2580
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2581
+ import_react_native8.Text,
2582
+ {
2583
+ style: [
2584
+ styles8.optionText,
2585
+ isDark && styles8.optionTextDark,
2586
+ pageTheme === "dark" && styles8.optionTextActive
2587
+ ],
2588
+ children: t.themeDark
2589
+ }
2590
+ )
2591
+ }
2592
+ ),
2593
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2594
+ import_react_native8.Pressable,
2595
+ {
2596
+ onPress: () => setDocumentState({ pageTheme: "high-contrast" }),
2597
+ style: [
2598
+ styles8.optionButton,
2599
+ isDark && styles8.optionButtonDark,
2600
+ pageTheme === "high-contrast" && styles8.optionButtonActive,
2601
+ pageTheme === "high-contrast" && { backgroundColor: accentColor }
2602
+ ],
2603
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2604
+ import_react_native8.Text,
2605
+ {
2606
+ style: [
2607
+ styles8.optionText,
2608
+ isDark && styles8.optionTextDark,
2609
+ pageTheme === "high-contrast" && styles8.optionTextActive
2610
+ ],
2611
+ children: t.themeContrast
2612
+ }
2613
+ )
2614
+ }
2615
+ )
2616
+ ] })
2617
+ ] }),
2618
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.View, { style: styles8.section, children: [
2619
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native8.Text, { style: [styles8.sectionTitle, isDark && styles8.sectionTitleDark], children: t.pageTransition }),
2620
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.View, { style: styles8.optionRow, children: [
2621
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2622
+ import_react_native8.Pressable,
2623
+ {
2624
+ onPress: () => handleTransition("continuous"),
2625
+ style: [
2626
+ styles8.optionButton,
2627
+ isDark && styles8.optionButtonDark,
2628
+ (!isPaged || isDouble) && styles8.optionButtonActive,
2629
+ (!isPaged || isDouble) && { backgroundColor: accentColor }
2630
+ ],
2631
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2632
+ import_react_native8.Text,
2633
+ {
2634
+ style: [
2635
+ styles8.optionText,
2636
+ isDark && styles8.optionTextDark,
2637
+ (!isPaged || isDouble) && styles8.optionTextActive
2638
+ ],
2639
+ children: t.continuous
2640
+ }
2641
+ )
2642
+ }
2643
+ ),
2644
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2645
+ import_react_native8.Pressable,
2646
+ {
2647
+ onPress: () => handleTransition("paged"),
2648
+ style: [
2649
+ styles8.optionButton,
2650
+ isDark && styles8.optionButtonDark,
2651
+ isPaged && styles8.optionButtonActive,
2652
+ isPaged && { backgroundColor: accentColor }
2653
+ ],
2654
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2655
+ import_react_native8.Text,
2656
+ {
2657
+ style: [
2658
+ styles8.optionText,
2659
+ isDark && styles8.optionTextDark,
2660
+ isPaged && styles8.optionTextActive
2661
+ ],
2662
+ children: t.pageByPage
2663
+ }
2664
+ )
2665
+ }
2666
+ )
2667
+ ] })
2668
+ ] }),
2669
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.View, { style: styles8.section, children: [
2670
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native8.Text, { style: [styles8.sectionTitle, isDark && styles8.sectionTitleDark], children: t.layout }),
2671
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.View, { style: styles8.optionRow, children: [
2672
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2673
+ import_react_native8.Pressable,
2674
+ {
2675
+ onPress: () => handleLayout("single"),
2676
+ style: [
2677
+ styles8.optionButton,
2678
+ isDark && styles8.optionButtonDark,
2679
+ !isDouble && styles8.optionButtonActive,
2680
+ !isDouble && { backgroundColor: accentColor }
2681
+ ],
2682
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2683
+ import_react_native8.Text,
2684
+ {
2685
+ style: [
2686
+ styles8.optionText,
2687
+ isDark && styles8.optionTextDark,
2688
+ !isDouble && styles8.optionTextActive
2689
+ ],
2690
+ children: t.singlePage
2691
+ }
2692
+ )
2693
+ }
2694
+ ),
2695
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2696
+ import_react_native8.Pressable,
2697
+ {
2698
+ onPress: () => handleLayout("double"),
2699
+ style: [
2700
+ styles8.optionButton,
2701
+ isDark && styles8.optionButtonDark,
2702
+ isDouble && styles8.optionButtonActive,
2703
+ isDouble && { backgroundColor: accentColor }
2704
+ ],
2705
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2706
+ import_react_native8.Text,
2707
+ {
2708
+ style: [
2709
+ styles8.optionText,
2710
+ isDark && styles8.optionTextDark,
2711
+ isDouble && styles8.optionTextActive
2712
+ ],
2713
+ children: t.doublePage
2714
+ }
2715
+ )
2716
+ }
2717
+ )
2718
+ ] })
2719
+ ] }),
2720
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.View, { style: styles8.section, children: [
2721
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native8.Text, { style: [styles8.sectionTitle, isDark && styles8.sectionTitleDark], children: t.rotate }),
2722
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.View, { style: styles8.optionRow, children: [
2723
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2724
+ import_react_native8.Pressable,
2725
+ {
2726
+ onPress: () => handleRotate("counterclockwise"),
2727
+ style: [styles8.optionButton, isDark && styles8.optionButtonDark],
2728
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native8.Text, { style: [styles8.optionText, isDark && styles8.optionTextDark], children: t.counterclockwise })
2729
+ }
2730
+ ),
2731
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2732
+ import_react_native8.Pressable,
2733
+ {
2734
+ onPress: () => handleRotate("clockwise"),
2735
+ style: [styles8.optionButton, isDark && styles8.optionButtonDark],
2736
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native8.Text, { style: [styles8.optionText, isDark && styles8.optionTextDark], children: t.clockwise })
2737
+ }
2738
+ )
2739
+ ] })
2740
+ ] }),
2741
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.View, { style: styles8.section, children: [
2742
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native8.Text, { style: [styles8.sectionTitle, isDark && styles8.sectionTitleDark], children: t.zoom }),
2743
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.View, { style: styles8.optionRow, children: [
2744
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native8.Pressable, { onPress: () => handleZoom(-0.1), style: [styles8.optionButton, isDark && styles8.optionButtonDark], children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(IconZoomOut, { size: 16, color: isDark ? "#e5e7eb" : "#111827" }) }),
2745
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native8.View, { style: styles8.zoomValue, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.Text, { style: [styles8.zoomText, isDark && styles8.zoomTextDark], children: [
2746
+ Math.round(zoom * 100),
2747
+ "%"
2748
+ ] }) }),
2749
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native8.Pressable, { onPress: () => handleZoom(0.1), style: [styles8.optionButton, isDark && styles8.optionButtonDark], children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(IconZoomIn, { size: 16, color: isDark ? "#e5e7eb" : "#111827" }) })
2750
+ ] })
2751
+ ] }),
2752
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.View, { style: styles8.section, children: [
2753
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native8.Text, { style: [styles8.sectionTitle, isDark && styles8.sectionTitleDark], children: t.language }),
2754
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native8.View, { style: styles8.optionRow, children: [
2755
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2756
+ import_react_native8.Pressable,
2757
+ {
2758
+ onPress: () => setDocumentState({ locale: "en" }),
2759
+ style: [
2760
+ styles8.optionButton,
2761
+ isDark && styles8.optionButtonDark,
2762
+ locale === "en" && styles8.optionButtonActive,
2763
+ locale === "en" && { backgroundColor: accentColor }
2764
+ ],
2765
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2766
+ import_react_native8.Text,
2767
+ {
2768
+ style: [
2769
+ styles8.optionText,
2770
+ isDark && styles8.optionTextDark,
2771
+ locale === "en" && styles8.optionTextActive
2772
+ ],
2773
+ children: t.english
2774
+ }
2775
+ )
2776
+ }
2777
+ ),
2778
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2779
+ import_react_native8.Pressable,
2780
+ {
2781
+ onPress: () => setDocumentState({ locale: "pt-BR" }),
2782
+ style: [
2783
+ styles8.optionButton,
2784
+ isDark && styles8.optionButtonDark,
2785
+ locale === "pt-BR" && styles8.optionButtonActive,
2786
+ locale === "pt-BR" && { backgroundColor: accentColor }
2787
+ ],
2788
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2789
+ import_react_native8.Text,
2790
+ {
2791
+ style: [
2792
+ styles8.optionText,
2793
+ isDark && styles8.optionTextDark,
2794
+ locale === "pt-BR" && styles8.optionTextActive
2795
+ ],
2796
+ children: t.portuguese
2797
+ }
2798
+ )
2799
+ }
2800
+ )
2801
+ ] })
2802
+ ] })
2803
+ ] })
2804
+ ] }) });
2805
+ };
2806
+ var styles8 = import_react_native8.StyleSheet.create({
2807
+ modalRoot: {
2808
+ flex: 1,
2809
+ backgroundColor: "transparent"
2810
+ },
2811
+ backdrop: {
2812
+ ...import_react_native8.StyleSheet.absoluteFillObject,
2813
+ backgroundColor: "rgba(0, 0, 0, 0.45)"
2814
+ },
2815
+ sheet: {
2816
+ position: "absolute",
2817
+ left: 0,
2818
+ right: 0,
2819
+ bottom: 0,
2820
+ paddingHorizontal: 18,
2821
+ paddingBottom: 24,
2822
+ backgroundColor: "#ffffff",
2823
+ borderTopLeftRadius: 24,
2824
+ borderTopRightRadius: 24,
2825
+ borderTopWidth: 1,
2826
+ borderTopColor: "#e5e7eb"
2827
+ },
2828
+ sheetDark: {
2829
+ backgroundColor: "#0f1115",
2830
+ borderTopColor: "#1f2937"
2831
+ },
2832
+ handle: {
2833
+ width: 44,
2834
+ height: 4,
2835
+ borderRadius: 999,
2836
+ backgroundColor: "#cbd5f5",
2837
+ alignSelf: "center",
2838
+ marginTop: 10,
2839
+ marginBottom: 12
2840
+ },
2841
+ handleDark: {
2842
+ backgroundColor: "#374151"
2843
+ },
2844
+ section: {
2845
+ marginBottom: 16
2846
+ },
2847
+ sectionTitle: {
2848
+ fontSize: 12,
2849
+ fontWeight: "800",
2850
+ color: "#111827",
2851
+ marginBottom: 8
2852
+ },
2853
+ sectionTitleDark: {
2854
+ color: "#e5e7eb"
2855
+ },
2856
+ optionRow: {
2857
+ flexDirection: "row",
2858
+ alignItems: "center",
2859
+ flexWrap: "wrap"
2860
+ },
2861
+ optionButton: {
2862
+ paddingHorizontal: 12,
2863
+ paddingVertical: 8,
2864
+ borderRadius: 12,
2865
+ backgroundColor: "#e5e7eb",
2866
+ marginRight: 8,
2867
+ marginBottom: 8
2868
+ },
2869
+ optionButtonDark: {
2870
+ backgroundColor: "#111827"
2871
+ },
2872
+ optionButtonActive: {
2873
+ backgroundColor: "#2563eb"
2874
+ },
2875
+ optionText: {
2876
+ fontSize: 11,
2877
+ fontWeight: "700",
2878
+ color: "#111827"
2879
+ },
2880
+ optionTextDark: {
2881
+ color: "#e5e7eb"
2882
+ },
2883
+ optionTextActive: {
2884
+ color: "#ffffff"
2885
+ },
2886
+ zoomValue: {
2887
+ minWidth: 52,
2888
+ alignItems: "center",
2889
+ justifyContent: "center"
2890
+ },
2891
+ zoomText: {
2892
+ fontSize: 12,
2893
+ fontWeight: "700",
2894
+ color: "#111827"
2895
+ },
2896
+ zoomTextDark: {
2897
+ color: "#e5e7eb"
2898
+ }
2899
+ });
2900
+ var SettingsSheet_default = SettingsSheet;
2901
+ // Annotate the CommonJS export names for ESM import in node:
2902
+ 0 && (module.exports = {
2903
+ AnnotationEditor,
2904
+ BottomBar,
2905
+ PageRenderer,
2906
+ RightSheet,
2907
+ SettingsSheet,
2908
+ ToolDock,
2909
+ Topbar,
2910
+ Viewer
2911
+ });
2912
+ //# sourceMappingURL=index.js.map