@embedpdf/plugin-annotation 1.0.11 → 1.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/dist/index.cjs +2 -693
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.ts +1 -266
  4. package/dist/index.js +509 -164
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/actions.d.ts +104 -0
  7. package/dist/lib/annotation-plugin.d.ts +34 -0
  8. package/dist/lib/helpers.d.ts +18 -0
  9. package/dist/lib/index.d.ts +12 -0
  10. package/dist/lib/manifest.d.ts +4 -0
  11. package/dist/lib/patching/derived-rect.d.ts +2 -0
  12. package/dist/lib/patching/index.d.ts +4 -0
  13. package/dist/lib/patching/line-ending-handlers.d.ts +20 -0
  14. package/dist/lib/patching/line-endings.d.ts +13 -0
  15. package/dist/lib/patching/patch-utils.d.ts +7 -0
  16. package/dist/lib/reducer.d.ts +5 -0
  17. package/dist/lib/selectors.d.ts +25 -0
  18. package/dist/lib/types.d.ts +168 -0
  19. package/dist/lib/utils.d.ts +11 -0
  20. package/dist/lib/variant-key.d.ts +8 -0
  21. package/dist/preact/adapter.d.ts +8 -0
  22. package/dist/preact/core.d.ts +1 -0
  23. package/dist/preact/index.cjs +2 -1038
  24. package/dist/preact/index.cjs.map +1 -1
  25. package/dist/preact/index.d.ts +1 -28
  26. package/dist/preact/index.js +2150 -539
  27. package/dist/preact/index.js.map +1 -1
  28. package/dist/preact/interaction-manager.d.ts +1 -0
  29. package/dist/preact/selection.d.ts +1 -0
  30. package/dist/react/adapter.d.ts +2 -0
  31. package/dist/react/core.d.ts +1 -0
  32. package/dist/react/index.cjs +2 -0
  33. package/dist/react/index.cjs.map +1 -0
  34. package/dist/react/index.d.ts +1 -0
  35. package/dist/react/index.js +2624 -0
  36. package/dist/react/index.js.map +1 -0
  37. package/dist/react/interaction-manager.d.ts +1 -0
  38. package/dist/react/selection.d.ts +1 -0
  39. package/dist/shared-preact/components/annotation-container.d.ts +24 -0
  40. package/dist/shared-preact/components/annotation-layer.d.ts +13 -0
  41. package/dist/shared-preact/components/annotations/circle-paint.d.ts +10 -0
  42. package/dist/shared-preact/components/annotations/circle.d.ts +29 -0
  43. package/dist/shared-preact/components/annotations/ink-highlight-paint.d.ts +0 -0
  44. package/dist/shared-preact/components/annotations/ink-paint.d.ts +18 -0
  45. package/dist/shared-preact/components/annotations/ink.d.ts +25 -0
  46. package/dist/shared-preact/components/annotations/line-paint.d.ts +10 -0
  47. package/dist/shared-preact/components/annotations/line.d.ts +33 -0
  48. package/dist/shared-preact/components/annotations/polygon-paint.d.ts +9 -0
  49. package/dist/shared-preact/components/annotations/polygon.d.ts +17 -0
  50. package/dist/shared-preact/components/annotations/polyline-paint.d.ts +10 -0
  51. package/dist/shared-preact/components/annotations/polyline.d.ts +17 -0
  52. package/dist/shared-preact/components/annotations/square-paint.d.ts +10 -0
  53. package/dist/shared-preact/components/annotations/square.d.ts +29 -0
  54. package/dist/shared-preact/components/annotations.d.ts +11 -0
  55. package/dist/shared-preact/components/counter-rotate-container.d.ts +32 -0
  56. package/dist/shared-preact/components/index.d.ts +1 -0
  57. package/dist/shared-preact/components/render-annotation.d.ts +11 -0
  58. package/dist/shared-preact/components/resize-handles.d.ts +9 -0
  59. package/dist/shared-preact/components/text-markup/highlight.d.ts +13 -0
  60. package/dist/shared-preact/components/text-markup/squiggly.d.ts +13 -0
  61. package/dist/shared-preact/components/text-markup/strikeout.d.ts +13 -0
  62. package/dist/shared-preact/components/text-markup/underline.d.ts +13 -0
  63. package/dist/shared-preact/components/text-markup.d.ts +6 -0
  64. package/dist/shared-preact/components/vertex-editor.d.ts +19 -0
  65. package/dist/shared-preact/hooks/index.d.ts +1 -0
  66. package/dist/shared-preact/hooks/use-annotation.d.ts +11 -0
  67. package/dist/shared-preact/hooks/use-drag-resize.d.ts +31 -0
  68. package/dist/shared-preact/index.d.ts +2 -0
  69. package/dist/shared-preact/patch-ink.d.ts +16 -0
  70. package/dist/shared-preact/patchers.d.ts +9 -0
  71. package/dist/shared-preact/types.d.ts +12 -0
  72. package/dist/shared-preact/vertex-patchers.d.ts +10 -0
  73. package/dist/shared-react/components/annotation-container.d.ts +24 -0
  74. package/dist/shared-react/components/annotation-layer.d.ts +13 -0
  75. package/dist/shared-react/components/annotations/circle-paint.d.ts +10 -0
  76. package/dist/shared-react/components/annotations/circle.d.ts +29 -0
  77. package/dist/shared-react/components/annotations/ink-highlight-paint.d.ts +0 -0
  78. package/dist/shared-react/components/annotations/ink-paint.d.ts +17 -0
  79. package/dist/shared-react/components/annotations/ink.d.ts +25 -0
  80. package/dist/shared-react/components/annotations/line-paint.d.ts +10 -0
  81. package/dist/shared-react/components/annotations/line.d.ts +33 -0
  82. package/dist/shared-react/components/annotations/polygon-paint.d.ts +9 -0
  83. package/dist/shared-react/components/annotations/polygon.d.ts +17 -0
  84. package/dist/shared-react/components/annotations/polyline-paint.d.ts +10 -0
  85. package/dist/shared-react/components/annotations/polyline.d.ts +17 -0
  86. package/dist/shared-react/components/annotations/square-paint.d.ts +10 -0
  87. package/dist/shared-react/components/annotations/square.d.ts +29 -0
  88. package/dist/shared-react/components/annotations.d.ts +11 -0
  89. package/dist/shared-react/components/counter-rotate-container.d.ts +32 -0
  90. package/dist/shared-react/components/index.d.ts +1 -0
  91. package/dist/shared-react/components/render-annotation.d.ts +11 -0
  92. package/dist/shared-react/components/resize-handles.d.ts +9 -0
  93. package/dist/shared-react/components/text-markup/highlight.d.ts +13 -0
  94. package/dist/shared-react/components/text-markup/squiggly.d.ts +13 -0
  95. package/dist/shared-react/components/text-markup/strikeout.d.ts +13 -0
  96. package/dist/shared-react/components/text-markup/underline.d.ts +13 -0
  97. package/dist/shared-react/components/text-markup.d.ts +6 -0
  98. package/dist/shared-react/components/vertex-editor.d.ts +19 -0
  99. package/dist/shared-react/hooks/index.d.ts +1 -0
  100. package/dist/shared-react/hooks/use-annotation.d.ts +11 -0
  101. package/dist/shared-react/hooks/use-drag-resize.d.ts +31 -0
  102. package/dist/shared-react/index.d.ts +2 -0
  103. package/dist/shared-react/patch-ink.d.ts +16 -0
  104. package/dist/shared-react/patchers.d.ts +9 -0
  105. package/dist/shared-react/types.d.ts +12 -0
  106. package/dist/shared-react/vertex-patchers.d.ts +10 -0
  107. package/package.json +17 -15
  108. package/dist/index.d.cts +0 -266
  109. package/dist/preact/index.d.cts +0 -28
@@ -0,0 +1,2624 @@
1
+ import { usePlugin, useCapability } from "@embedpdf/core/react";
2
+ import { AnnotationPlugin, patching, getAnnotationsByPageIndex, getSelectedAnnotationByPageIndex, isInk, isSquare, isCircle, isUnderline, isStrikeout, isSquiggly, isHighlight, isLine, isPolyline, isPolygon, makeVariantKey } from "@embedpdf/plugin-annotation";
3
+ import { jsx, jsxs, Fragment as Fragment$1 } from "react/jsx-runtime";
4
+ import { restoreOffset, rectEquals, PdfAnnotationBorderStyle, PdfAnnotationSubtype, expandRect, rectFromPoints, blendModeToCss, PdfBlendMode } from "@embedpdf/models";
5
+ import { usePointerHandlers } from "@embedpdf/plugin-interaction-manager/react";
6
+ import { useSelectionCapability } from "@embedpdf/plugin-selection/react";
7
+ import { Fragment, useState, useRef, useEffect, useLayoutEffect, useMemo, useCallback } from "react";
8
+ const useAnnotationPlugin = () => usePlugin(AnnotationPlugin.id);
9
+ const useAnnotationCapability = () => useCapability(AnnotationPlugin.id);
10
+ function getCounterRotation(rect, rotation) {
11
+ const { width: w, height: h } = rect.size;
12
+ switch (rotation % 4) {
13
+ case 1:
14
+ return {
15
+ matrix: `matrix(0, -1, 1, 0, 0, ${h})`,
16
+ width: h,
17
+ height: w
18
+ };
19
+ case 2:
20
+ return {
21
+ matrix: `matrix(-1, 0, 0, -1, ${w}, ${h})`,
22
+ width: w,
23
+ height: h
24
+ };
25
+ case 3:
26
+ return {
27
+ matrix: `matrix(0, 1, -1, 0, ${w}, 0)`,
28
+ width: h,
29
+ height: w
30
+ };
31
+ default:
32
+ return {
33
+ matrix: `matrix(1, 0, 0, 1, 0, 0)`,
34
+ width: w,
35
+ height: h
36
+ };
37
+ }
38
+ }
39
+ function CounterRotate({ children, ...props }) {
40
+ const { rect, rotation } = props;
41
+ const { matrix, width, height } = getCounterRotation(rect, rotation);
42
+ const menuWrapperStyle = {
43
+ position: "absolute",
44
+ left: rect.origin.x,
45
+ top: rect.origin.y,
46
+ transform: matrix,
47
+ transformOrigin: "0 0",
48
+ width,
49
+ height,
50
+ pointerEvents: "none",
51
+ zIndex: 3
52
+ };
53
+ const menuWrapperProps = {
54
+ style: menuWrapperStyle,
55
+ onPointerDown: (e) => e.stopPropagation()
56
+ };
57
+ return /* @__PURE__ */ jsx(Fragment, { children: children({
58
+ menuWrapperProps,
59
+ matrix,
60
+ rect: {
61
+ origin: { x: rect.origin.x, y: rect.origin.y },
62
+ size: { width, height }
63
+ }
64
+ }) });
65
+ }
66
+ function VertexEditor({
67
+ rect,
68
+ rotation,
69
+ scale,
70
+ vertices,
71
+ onEdit,
72
+ onCommit,
73
+ handleSize = 12
74
+ }) {
75
+ const [dragIdx, setDragIdx] = useState(null);
76
+ const startScreen = useRef(null);
77
+ const startVerts = useRef([]);
78
+ const applyDelta = (deltaScreen) => {
79
+ const deltaPdf = restoreOffset(deltaScreen, rotation, scale);
80
+ const next = [...startVerts.current];
81
+ if (dragIdx !== null) {
82
+ next[dragIdx] = {
83
+ x: next[dragIdx].x + deltaPdf.x,
84
+ y: next[dragIdx].y + deltaPdf.y
85
+ };
86
+ }
87
+ return next;
88
+ };
89
+ const handleDown = (idx) => (e) => {
90
+ e.stopPropagation();
91
+ e.preventDefault();
92
+ setDragIdx(idx);
93
+ startScreen.current = { x: e.clientX, y: e.clientY };
94
+ startVerts.current = vertices;
95
+ e.target.setPointerCapture(e.pointerId);
96
+ };
97
+ const handleMove = (e) => {
98
+ if (dragIdx === null || !startScreen.current) return;
99
+ const deltaRaw = {
100
+ x: e.clientX - startScreen.current.x,
101
+ y: e.clientY - startScreen.current.y
102
+ };
103
+ onEdit(applyDelta(deltaRaw));
104
+ };
105
+ const handleUp = (e) => {
106
+ if (dragIdx === null || !startScreen.current) return;
107
+ e.target.releasePointerCapture(e.pointerId);
108
+ const deltaRaw = {
109
+ x: e.clientX - startScreen.current.x,
110
+ y: e.clientY - startScreen.current.y
111
+ };
112
+ onCommit(applyDelta(deltaRaw));
113
+ setDragIdx(null);
114
+ };
115
+ return /* @__PURE__ */ jsx(Fragment, { children: vertices.map((v, i) => {
116
+ const left = (v.x - rect.origin.x) * scale - handleSize / 2;
117
+ const top = (v.y - rect.origin.y) * scale - handleSize / 2;
118
+ return /* @__PURE__ */ jsx(
119
+ "div",
120
+ {
121
+ style: {
122
+ position: "absolute",
123
+ left,
124
+ top,
125
+ width: handleSize,
126
+ height: handleSize,
127
+ borderRadius: "50%",
128
+ background: "#2196f3",
129
+ cursor: "pointer",
130
+ pointerEvents: "auto",
131
+ zIndex: 4
132
+ },
133
+ onPointerDown: handleDown(i),
134
+ onPointerMove: handleMove,
135
+ onPointerUp: handleUp
136
+ },
137
+ i
138
+ );
139
+ }) });
140
+ }
141
+ function useDragResize({
142
+ scale,
143
+ pageWidth,
144
+ pageHeight,
145
+ rotation,
146
+ tracked,
147
+ isSelected,
148
+ isDraggable,
149
+ isResizable,
150
+ computePatch,
151
+ computeVertices,
152
+ currentRect,
153
+ setCurrentRect,
154
+ setCurrentVertices,
155
+ setPreviewObject,
156
+ commit
157
+ }) {
158
+ const drag = useRef("idle");
159
+ const dir = useRef("none");
160
+ const startPos = useRef(null);
161
+ const startRect = useRef(null);
162
+ const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
163
+ const pageW = pageWidth / scale;
164
+ const pageH = pageHeight / scale;
165
+ const applyDelta = (dx, dy) => {
166
+ if (!startRect.current) return currentRect;
167
+ let { origin, size } = startRect.current;
168
+ let ox = origin.x;
169
+ let oy = origin.y;
170
+ let w = size.width;
171
+ let h = size.height;
172
+ if (drag.current === "dragging") {
173
+ ox += dx;
174
+ oy += dy;
175
+ } else if (drag.current === "resizing") {
176
+ if (dir.current.includes("right")) w += dx;
177
+ else if (dir.current.includes("left")) {
178
+ ox += dx;
179
+ w -= dx;
180
+ }
181
+ if (dir.current.includes("bottom")) h += dy;
182
+ else if (dir.current.includes("top")) {
183
+ oy += dy;
184
+ h -= dy;
185
+ }
186
+ }
187
+ if (w < 1 || h < 1) return currentRect;
188
+ w = clamp(w, 1, pageW);
189
+ h = clamp(h, 1, pageH);
190
+ ox = clamp(ox, 0, pageW - w);
191
+ oy = clamp(oy, 0, pageH - h);
192
+ return { origin: { x: ox, y: oy }, size: { width: w, height: h } };
193
+ };
194
+ const onPointerDown = (e) => {
195
+ if (!isSelected || !isDraggable) return;
196
+ e.stopPropagation();
197
+ e.preventDefault();
198
+ drag.current = "dragging";
199
+ startPos.current = { x: e.clientX, y: e.clientY };
200
+ startRect.current = currentRect;
201
+ e.currentTarget.setPointerCapture(e.pointerId);
202
+ };
203
+ const onPointerMove = (e) => {
204
+ if (drag.current === "idle" || !startPos.current) return;
205
+ const disp = {
206
+ x: e.clientX - startPos.current.x,
207
+ y: e.clientY - startPos.current.y
208
+ };
209
+ const { x, y } = restoreOffset(disp, rotation, scale);
210
+ const nextRect = applyDelta(x, y);
211
+ let patch = { rect: nextRect };
212
+ if (computePatch) {
213
+ patch = computePatch(tracked.object, {
214
+ rect: nextRect,
215
+ direction: drag.current === "resizing" ? dir.current : "bottom-right"
216
+ });
217
+ if (computeVertices) setCurrentVertices(computeVertices({ ...tracked.object, ...patch }));
218
+ }
219
+ setCurrentRect(patch.rect ?? nextRect);
220
+ setPreviewObject(patch);
221
+ };
222
+ const onPointerUp = () => {
223
+ if (drag.current === "idle") return;
224
+ const usedDir = dir.current || "bottom-right";
225
+ drag.current = "idle";
226
+ let patch = { rect: currentRect };
227
+ if (computePatch) {
228
+ patch = computePatch(tracked.object, {
229
+ rect: currentRect,
230
+ direction: usedDir
231
+ });
232
+ }
233
+ commit(patch);
234
+ startPos.current = null;
235
+ startRect.current = null;
236
+ dir.current = "none";
237
+ setPreviewObject(null);
238
+ };
239
+ const startResize = (direction) => (e) => {
240
+ if (!isSelected || !isResizable) return;
241
+ e.stopPropagation();
242
+ e.preventDefault();
243
+ drag.current = "resizing";
244
+ dir.current = direction;
245
+ startPos.current = { x: e.clientX, y: e.clientY };
246
+ startRect.current = currentRect;
247
+ e.currentTarget.setPointerCapture(e.pointerId);
248
+ };
249
+ useEffect(() => {
250
+ drag.current = "idle";
251
+ dir.current = "none";
252
+ startPos.current = null;
253
+ startRect.current = null;
254
+ }, [tracked]);
255
+ return {
256
+ rootHandlers: {
257
+ onPointerDown,
258
+ onPointerMove,
259
+ onPointerUp
260
+ },
261
+ startResize
262
+ };
263
+ }
264
+ const commonStyle = (o) => ({
265
+ position: "absolute",
266
+ width: 13,
267
+ height: 13,
268
+ background: "blue",
269
+ borderRadius: "50%"
270
+ });
271
+ function ResizeHandles({ rotation, outlineOffset = 1, startResize }) {
272
+ const o = outlineOffset;
273
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
274
+ /* @__PURE__ */ jsx(
275
+ "div",
276
+ {
277
+ style: {
278
+ ...commonStyle(),
279
+ top: -7 - o,
280
+ left: -7 - o,
281
+ cursor: rotation % 2 ? "nesw-resize" : "nwse-resize"
282
+ },
283
+ onPointerDown: startResize("top-left")
284
+ }
285
+ ),
286
+ /* @__PURE__ */ jsx(
287
+ "div",
288
+ {
289
+ style: {
290
+ ...commonStyle(),
291
+ top: -7 - o,
292
+ right: -7 - o,
293
+ cursor: rotation % 2 ? "nwse-resize" : "nesw-resize"
294
+ },
295
+ onPointerDown: startResize("top-right")
296
+ }
297
+ ),
298
+ /* @__PURE__ */ jsx(
299
+ "div",
300
+ {
301
+ style: {
302
+ ...commonStyle(),
303
+ bottom: -7 - o,
304
+ left: -7 - o,
305
+ cursor: rotation % 2 ? "nwse-resize" : "nesw-resize"
306
+ },
307
+ onPointerDown: startResize("bottom-left")
308
+ }
309
+ ),
310
+ /* @__PURE__ */ jsx(
311
+ "div",
312
+ {
313
+ style: {
314
+ ...commonStyle(),
315
+ bottom: -7 - o,
316
+ right: -7 - o,
317
+ cursor: rotation % 2 ? "nesw-resize" : "nwse-resize"
318
+ },
319
+ onPointerDown: startResize("bottom-right")
320
+ }
321
+ )
322
+ ] });
323
+ }
324
+ function AnnotationContainer({
325
+ scale,
326
+ pageIndex,
327
+ rotation,
328
+ pageWidth,
329
+ pageHeight,
330
+ trackedAnnotation,
331
+ children,
332
+ style,
333
+ outlineOffset = 1,
334
+ isSelected = false,
335
+ isDraggable = true,
336
+ isResizable = true,
337
+ computeVertices,
338
+ computePatch,
339
+ selectionMenu,
340
+ ...props
341
+ }) {
342
+ const { provides: annotationProvides } = useAnnotationCapability();
343
+ const [currentRect, setCurrentRect] = useState(trackedAnnotation.object.rect);
344
+ const [currentVertices, setCurrentVertices] = useState(
345
+ (computeVertices == null ? void 0 : computeVertices(trackedAnnotation.object)) ?? []
346
+ );
347
+ const [previewObject, setPreviewObject] = useState(null);
348
+ const { rootHandlers, startResize } = useDragResize({
349
+ scale,
350
+ pageWidth,
351
+ pageHeight,
352
+ rotation,
353
+ tracked: trackedAnnotation,
354
+ isSelected,
355
+ isDraggable,
356
+ isResizable,
357
+ computePatch,
358
+ computeVertices,
359
+ currentRect,
360
+ setCurrentRect,
361
+ setCurrentVertices,
362
+ setPreviewObject,
363
+ commit: (patch) => annotationProvides == null ? void 0 : annotationProvides.updateAnnotation(pageIndex, trackedAnnotation.localId, patch)
364
+ });
365
+ useLayoutEffect(() => {
366
+ if (!rectEquals(trackedAnnotation.object.rect, currentRect)) {
367
+ setCurrentRect(trackedAnnotation.object.rect);
368
+ setPreviewObject((prev) => prev ? { ...prev, rect: trackedAnnotation.object.rect } : null);
369
+ setCurrentVertices((computeVertices == null ? void 0 : computeVertices(trackedAnnotation.object)) ?? []);
370
+ }
371
+ }, [trackedAnnotation]);
372
+ const currentObject = previewObject ? { ...trackedAnnotation.object, ...previewObject } : trackedAnnotation.object;
373
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
374
+ /* @__PURE__ */ jsxs(
375
+ "div",
376
+ {
377
+ ...rootHandlers,
378
+ style: {
379
+ position: "absolute",
380
+ outline: isSelected ? "1px solid #007ACC" : "none",
381
+ outlineOffset: isSelected ? `${outlineOffset}px` : "0px",
382
+ left: `${currentRect.origin.x * scale}px`,
383
+ top: `${currentRect.origin.y * scale}px`,
384
+ width: `${currentRect.size.width * scale}px`,
385
+ height: `${currentRect.size.height * scale}px`,
386
+ pointerEvents: isSelected ? "auto" : "none",
387
+ cursor: isSelected && isDraggable ? "move" : "default",
388
+ ...style
389
+ },
390
+ ...props,
391
+ children: [
392
+ typeof children === "function" ? children(currentObject) : children,
393
+ isSelected && currentVertices.length > 0 && /* @__PURE__ */ jsx(
394
+ VertexEditor,
395
+ {
396
+ rect: currentRect,
397
+ rotation,
398
+ scale,
399
+ vertices: currentVertices,
400
+ onEdit: (v) => {
401
+ setCurrentVertices(v);
402
+ if (computePatch) {
403
+ const patch = computePatch(trackedAnnotation.object, {
404
+ rect: currentRect,
405
+ vertices: v
406
+ });
407
+ setPreviewObject(patch);
408
+ setCurrentRect(patch.rect || currentRect);
409
+ }
410
+ },
411
+ onCommit: (v) => {
412
+ if (annotationProvides && computePatch) {
413
+ const patch = computePatch(trackedAnnotation.object, {
414
+ rect: currentRect,
415
+ vertices: v
416
+ });
417
+ annotationProvides.updateAnnotation(pageIndex, trackedAnnotation.localId, patch);
418
+ }
419
+ }
420
+ }
421
+ ),
422
+ isSelected && isResizable && /* @__PURE__ */ jsx(
423
+ ResizeHandles,
424
+ {
425
+ rotation,
426
+ outlineOffset,
427
+ startResize
428
+ }
429
+ )
430
+ ]
431
+ }
432
+ ),
433
+ /* @__PURE__ */ jsx(
434
+ CounterRotate,
435
+ {
436
+ rect: {
437
+ origin: { x: currentRect.origin.x * scale, y: currentRect.origin.y * scale },
438
+ size: { width: currentRect.size.width * scale, height: currentRect.size.height * scale }
439
+ },
440
+ rotation,
441
+ children: ({ rect, menuWrapperProps }) => selectionMenu && selectionMenu({
442
+ annotation: trackedAnnotation,
443
+ selected: isSelected,
444
+ rect,
445
+ menuWrapperProps
446
+ })
447
+ }
448
+ )
449
+ ] });
450
+ }
451
+ function Highlight({
452
+ color = "#FFFF00",
453
+ opacity = 0.5,
454
+ rects,
455
+ rect,
456
+ scale,
457
+ onClick,
458
+ style,
459
+ ...props
460
+ }) {
461
+ return /* @__PURE__ */ jsx(Fragment$1, { children: rects.map((b, i) => /* @__PURE__ */ jsx(
462
+ "div",
463
+ {
464
+ onMouseDown: onClick,
465
+ style: {
466
+ position: "absolute",
467
+ left: (rect ? b.origin.x - rect.origin.x : b.origin.x) * scale,
468
+ top: (rect ? b.origin.y - rect.origin.y : b.origin.y) * scale,
469
+ width: b.size.width * scale,
470
+ height: b.size.height * scale,
471
+ background: color,
472
+ opacity,
473
+ pointerEvents: onClick ? "auto" : "none",
474
+ cursor: onClick ? "pointer" : "default",
475
+ zIndex: onClick ? 1 : void 0,
476
+ ...style
477
+ },
478
+ ...props
479
+ },
480
+ i
481
+ )) });
482
+ }
483
+ function Underline({
484
+ color = "#FFFF00",
485
+ opacity = 0.5,
486
+ rects,
487
+ rect,
488
+ scale,
489
+ onClick,
490
+ style,
491
+ ...props
492
+ }) {
493
+ const thickness = 2 * scale;
494
+ return /* @__PURE__ */ jsx(Fragment$1, { children: rects.map((r, i) => /* @__PURE__ */ jsx(
495
+ "div",
496
+ {
497
+ onMouseDown: onClick,
498
+ style: {
499
+ position: "absolute",
500
+ left: (rect ? r.origin.x - rect.origin.x : r.origin.x) * scale,
501
+ top: (rect ? r.origin.y - rect.origin.y : r.origin.y) * scale,
502
+ width: r.size.width * scale,
503
+ height: r.size.height * scale,
504
+ background: "transparent",
505
+ pointerEvents: onClick ? "auto" : "none",
506
+ cursor: onClick ? "pointer" : "default",
507
+ zIndex: onClick ? 1 : 0,
508
+ ...style
509
+ },
510
+ ...props,
511
+ children: /* @__PURE__ */ jsx(
512
+ "div",
513
+ {
514
+ style: {
515
+ position: "absolute",
516
+ left: 0,
517
+ bottom: 0,
518
+ width: "100%",
519
+ height: thickness,
520
+ background: color,
521
+ opacity,
522
+ pointerEvents: "none"
523
+ }
524
+ }
525
+ )
526
+ },
527
+ i
528
+ )) });
529
+ }
530
+ function Strikeout({
531
+ color = "#FFFF00",
532
+ opacity = 0.5,
533
+ rects,
534
+ rect,
535
+ scale,
536
+ onClick,
537
+ style,
538
+ ...props
539
+ }) {
540
+ const thickness = 2 * scale;
541
+ return /* @__PURE__ */ jsx(Fragment$1, { children: rects.map((r, i) => /* @__PURE__ */ jsx(
542
+ "div",
543
+ {
544
+ onMouseDown: onClick,
545
+ style: {
546
+ position: "absolute",
547
+ left: (rect ? r.origin.x - rect.origin.x : r.origin.x) * scale,
548
+ top: (rect ? r.origin.y - rect.origin.y : r.origin.y) * scale,
549
+ width: r.size.width * scale,
550
+ height: r.size.height * scale,
551
+ background: "transparent",
552
+ pointerEvents: onClick ? "auto" : "none",
553
+ cursor: onClick ? "pointer" : "default",
554
+ zIndex: onClick ? 1 : 0,
555
+ ...style
556
+ },
557
+ ...props,
558
+ children: /* @__PURE__ */ jsx(
559
+ "div",
560
+ {
561
+ style: {
562
+ position: "absolute",
563
+ left: 0,
564
+ top: "50%",
565
+ width: "100%",
566
+ height: thickness,
567
+ background: color,
568
+ opacity,
569
+ transform: "translateY(-50%)",
570
+ pointerEvents: "none"
571
+ }
572
+ }
573
+ )
574
+ },
575
+ i
576
+ )) });
577
+ }
578
+ function Squiggly({
579
+ color = "#FFFF00",
580
+ opacity = 0.5,
581
+ rects,
582
+ rect,
583
+ scale,
584
+ onClick,
585
+ style,
586
+ ...props
587
+ }) {
588
+ const amplitude = 2 * scale;
589
+ const period = 6 * scale;
590
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${period}" height="${amplitude * 2}" viewBox="0 0 ${period} ${amplitude * 2}">
591
+ <path d="M0 ${amplitude} Q ${period / 4} 0 ${period / 2} ${amplitude} T ${period} ${amplitude}"
592
+ fill="none" stroke="${color}" stroke-width="${amplitude}" stroke-linecap="round"/>
593
+ </svg>`;
594
+ const svgDataUri = `url("data:image/svg+xml;utf8,${encodeURIComponent(svg)}")`;
595
+ return /* @__PURE__ */ jsx(Fragment$1, { children: rects.map((r, i) => /* @__PURE__ */ jsx(
596
+ "div",
597
+ {
598
+ onMouseDown: onClick,
599
+ style: {
600
+ position: "absolute",
601
+ left: (rect ? r.origin.x - rect.origin.x : r.origin.x) * scale,
602
+ top: (rect ? r.origin.y - rect.origin.y : r.origin.y) * scale,
603
+ width: r.size.width * scale,
604
+ height: r.size.height * scale,
605
+ background: "transparent",
606
+ pointerEvents: onClick ? "auto" : "none",
607
+ cursor: onClick ? "pointer" : "default",
608
+ zIndex: onClick ? 1 : 0,
609
+ ...style
610
+ },
611
+ ...props,
612
+ children: /* @__PURE__ */ jsx(
613
+ "div",
614
+ {
615
+ style: {
616
+ position: "absolute",
617
+ left: 0,
618
+ bottom: 0,
619
+ width: "100%",
620
+ height: amplitude * 2,
621
+ backgroundImage: svgDataUri,
622
+ backgroundRepeat: "repeat-x",
623
+ backgroundSize: `${period}px ${amplitude * 2}px`,
624
+ opacity,
625
+ pointerEvents: "none"
626
+ }
627
+ }
628
+ )
629
+ },
630
+ i
631
+ )) });
632
+ }
633
+ function Ink({
634
+ color = "#000000",
635
+ opacity = 1,
636
+ strokeWidth,
637
+ inkList,
638
+ rect,
639
+ scale,
640
+ onClick,
641
+ cursor
642
+ }) {
643
+ const paths = useMemo(() => {
644
+ return inkList.map(({ points }) => {
645
+ let d = "";
646
+ points.forEach(({ x, y }, i) => {
647
+ const lx = x - rect.origin.x;
648
+ const ly = y - rect.origin.y;
649
+ d += (i === 0 ? "M" : "L") + lx + " " + ly + " ";
650
+ });
651
+ return d.trim();
652
+ });
653
+ }, [inkList, rect]);
654
+ const width = rect.size.width * scale;
655
+ const height = rect.size.height * scale;
656
+ return /* @__PURE__ */ jsx(
657
+ "svg",
658
+ {
659
+ style: {
660
+ position: "absolute",
661
+ width,
662
+ height,
663
+ pointerEvents: "none",
664
+ zIndex: 2,
665
+ overflow: "visible"
666
+ },
667
+ width,
668
+ height,
669
+ viewBox: `0 0 ${rect.size.width} ${rect.size.height}`,
670
+ children: paths.map((d, i) => /* @__PURE__ */ jsx(
671
+ "path",
672
+ {
673
+ d,
674
+ fill: "none",
675
+ opacity,
676
+ onMouseDown: onClick,
677
+ style: {
678
+ cursor,
679
+ pointerEvents: "visibleStroke",
680
+ stroke: color,
681
+ strokeWidth,
682
+ strokeLinecap: "round",
683
+ strokeLinejoin: "round"
684
+ }
685
+ },
686
+ i
687
+ ))
688
+ }
689
+ );
690
+ }
691
+ function Square({
692
+ color = "#000000",
693
+ strokeColor,
694
+ opacity = 1,
695
+ strokeWidth,
696
+ strokeStyle = PdfAnnotationBorderStyle.SOLID,
697
+ strokeDashArray,
698
+ rect,
699
+ scale,
700
+ onClick,
701
+ cursor
702
+ }) {
703
+ const { width, height, x, y } = useMemo(() => {
704
+ const outerW = rect.size.width;
705
+ const outerH = rect.size.height;
706
+ const innerW = Math.max(outerW - strokeWidth, 0);
707
+ const innerH = Math.max(outerH - strokeWidth, 0);
708
+ return {
709
+ width: innerW,
710
+ height: innerH,
711
+ x: strokeWidth / 2,
712
+ y: strokeWidth / 2
713
+ };
714
+ }, [rect, strokeWidth]);
715
+ const svgWidth = (width + strokeWidth) * scale;
716
+ const svgHeight = (height + strokeWidth) * scale;
717
+ return /* @__PURE__ */ jsx(
718
+ "svg",
719
+ {
720
+ style: {
721
+ position: "absolute",
722
+ width: svgWidth,
723
+ height: svgHeight,
724
+ pointerEvents: "none",
725
+ zIndex: 2
726
+ },
727
+ width: svgWidth,
728
+ height: svgHeight,
729
+ viewBox: `0 0 ${width + strokeWidth} ${height + strokeWidth}`,
730
+ children: /* @__PURE__ */ jsx(
731
+ "rect",
732
+ {
733
+ x,
734
+ y,
735
+ width,
736
+ height,
737
+ fill: color,
738
+ opacity,
739
+ onMouseDown: onClick,
740
+ style: {
741
+ cursor,
742
+ pointerEvents: color === "transparent" ? "visibleStroke" : "visible",
743
+ stroke: strokeColor ?? color,
744
+ strokeWidth,
745
+ ...strokeStyle === PdfAnnotationBorderStyle.DASHED && {
746
+ strokeDasharray: strokeDashArray == null ? void 0 : strokeDashArray.join(",")
747
+ }
748
+ }
749
+ }
750
+ )
751
+ }
752
+ );
753
+ }
754
+ function Circle({
755
+ color = "#000000",
756
+ strokeColor,
757
+ opacity = 1,
758
+ strokeWidth,
759
+ strokeStyle = PdfAnnotationBorderStyle.SOLID,
760
+ strokeDashArray,
761
+ rect,
762
+ scale,
763
+ onClick,
764
+ cursor
765
+ }) {
766
+ const { width, height, cx, cy, rx, ry } = useMemo(() => {
767
+ const outerW = rect.size.width;
768
+ const outerH = rect.size.height;
769
+ const innerW = Math.max(outerW - strokeWidth, 0);
770
+ const innerH = Math.max(outerH - strokeWidth, 0);
771
+ return {
772
+ width: outerW,
773
+ height: outerH,
774
+ // Centre of the fill sits strokeWidth/2 in from the edges
775
+ cx: strokeWidth / 2 + innerW / 2,
776
+ cy: strokeWidth / 2 + innerH / 2,
777
+ rx: innerW / 2,
778
+ ry: innerH / 2
779
+ };
780
+ }, [rect, strokeWidth]);
781
+ const svgWidth = width * scale;
782
+ const svgHeight = height * scale;
783
+ return /* @__PURE__ */ jsx(
784
+ "svg",
785
+ {
786
+ style: {
787
+ position: "absolute",
788
+ width: svgWidth,
789
+ height: svgHeight,
790
+ pointerEvents: "none",
791
+ zIndex: 2
792
+ },
793
+ width: svgWidth,
794
+ height: svgHeight,
795
+ viewBox: `0 0 ${width} ${height}`,
796
+ children: /* @__PURE__ */ jsx(
797
+ "ellipse",
798
+ {
799
+ cx,
800
+ cy,
801
+ rx,
802
+ ry,
803
+ fill: color,
804
+ opacity,
805
+ onMouseDown: onClick,
806
+ style: {
807
+ cursor,
808
+ pointerEvents: color === "transparent" ? "visibleStroke" : "visible",
809
+ stroke: strokeColor ?? color,
810
+ strokeWidth,
811
+ ...strokeStyle === PdfAnnotationBorderStyle.DASHED && {
812
+ strokeDasharray: strokeDashArray == null ? void 0 : strokeDashArray.join(",")
813
+ }
814
+ }
815
+ }
816
+ )
817
+ }
818
+ );
819
+ }
820
+ const patchInk = (original, ctx) => {
821
+ if (original.type !== PdfAnnotationSubtype.INK) {
822
+ throw new Error("resizeInkAnnotation: original is not an ink annotation");
823
+ }
824
+ const oldRect = original.rect;
825
+ let scaleX = ctx.rect.size.width / oldRect.size.width;
826
+ let scaleY = ctx.rect.size.height / oldRect.size.height;
827
+ const minSize = 10;
828
+ if (ctx.rect.size.width < minSize || ctx.rect.size.height < minSize) {
829
+ scaleX = Math.max(scaleX, minSize / oldRect.size.width);
830
+ scaleY = Math.max(scaleY, minSize / oldRect.size.height);
831
+ ctx.rect = {
832
+ origin: ctx.rect.origin,
833
+ size: {
834
+ width: oldRect.size.width * scaleX,
835
+ height: oldRect.size.height * scaleY
836
+ }
837
+ };
838
+ }
839
+ if (ctx.uniform) {
840
+ const minScale = Math.min(scaleX, scaleY);
841
+ scaleX = minScale;
842
+ scaleY = minScale;
843
+ ctx.rect.size = {
844
+ width: oldRect.size.width * minScale,
845
+ height: oldRect.size.height * minScale
846
+ };
847
+ }
848
+ const newInkList = original.inkList.map((stroke) => ({
849
+ points: stroke.points.map((p) => ({
850
+ x: ctx.rect.origin.x + (p.x - oldRect.origin.x) * scaleX,
851
+ y: ctx.rect.origin.y + (p.y - oldRect.origin.y) * scaleY
852
+ }))
853
+ }));
854
+ const avgScale = (scaleX + scaleY) / 2;
855
+ const newStrokeWidth = Math.round(original.strokeWidth * avgScale);
856
+ return {
857
+ rect: ctx.rect,
858
+ inkList: newInkList,
859
+ strokeWidth: newStrokeWidth
860
+ };
861
+ };
862
+ function Line({
863
+ color = "transparent",
864
+ opacity = 1,
865
+ strokeWidth,
866
+ strokeColor = "#000000",
867
+ strokeStyle = PdfAnnotationBorderStyle.SOLID,
868
+ strokeDashArray,
869
+ rect,
870
+ linePoints,
871
+ lineEndings,
872
+ scale,
873
+ onClick,
874
+ isSelected
875
+ }) {
876
+ const { x1, y1, x2, y2 } = useMemo(() => {
877
+ return {
878
+ x1: linePoints.start.x - rect.origin.x,
879
+ y1: linePoints.start.y - rect.origin.y,
880
+ x2: linePoints.end.x - rect.origin.x,
881
+ y2: linePoints.end.y - rect.origin.y
882
+ };
883
+ }, [linePoints, rect]);
884
+ const endings = useMemo(() => {
885
+ const angle = Math.atan2(y2 - y1, x2 - x1);
886
+ return {
887
+ start: patching.createEnding(lineEndings == null ? void 0 : lineEndings.start, strokeWidth, angle + Math.PI, x1, y1),
888
+ end: patching.createEnding(lineEndings == null ? void 0 : lineEndings.end, strokeWidth, angle, x2, y2)
889
+ };
890
+ }, [lineEndings, strokeWidth, x1, y1, x2, y2]);
891
+ const width = rect.size.width * scale;
892
+ const height = rect.size.height * scale;
893
+ return /* @__PURE__ */ jsxs(
894
+ "svg",
895
+ {
896
+ style: {
897
+ position: "absolute",
898
+ width,
899
+ height,
900
+ pointerEvents: "none",
901
+ zIndex: 2,
902
+ overflow: "visible"
903
+ },
904
+ width,
905
+ height,
906
+ viewBox: `0 0 ${rect.size.width} ${rect.size.height}`,
907
+ children: [
908
+ /* @__PURE__ */ jsx(
909
+ "line",
910
+ {
911
+ x1,
912
+ y1,
913
+ x2,
914
+ y2,
915
+ opacity,
916
+ onMouseDown: onClick,
917
+ style: {
918
+ cursor: isSelected ? "move" : "pointer",
919
+ pointerEvents: "visibleStroke",
920
+ stroke: strokeColor,
921
+ strokeWidth,
922
+ strokeLinecap: "butt",
923
+ ...strokeStyle === PdfAnnotationBorderStyle.DASHED && {
924
+ strokeDasharray: strokeDashArray == null ? void 0 : strokeDashArray.join(",")
925
+ }
926
+ }
927
+ }
928
+ ),
929
+ endings.start && /* @__PURE__ */ jsx(
930
+ "path",
931
+ {
932
+ d: endings.start.d,
933
+ transform: endings.start.transform,
934
+ onMouseDown: onClick,
935
+ stroke: strokeColor,
936
+ style: {
937
+ cursor: isSelected ? "move" : "pointer",
938
+ strokeWidth,
939
+ strokeLinecap: "butt",
940
+ pointerEvents: endings.start.filled ? "visible" : "visibleStroke",
941
+ ...strokeStyle === PdfAnnotationBorderStyle.DASHED && {
942
+ strokeDasharray: strokeDashArray == null ? void 0 : strokeDashArray.join(",")
943
+ }
944
+ },
945
+ fill: endings.start.filled ? color : "none"
946
+ }
947
+ ),
948
+ endings.end && /* @__PURE__ */ jsx(
949
+ "path",
950
+ {
951
+ d: endings.end.d,
952
+ transform: endings.end.transform,
953
+ stroke: strokeColor,
954
+ onMouseDown: onClick,
955
+ style: {
956
+ cursor: isSelected ? "move" : "pointer",
957
+ strokeWidth,
958
+ strokeLinecap: "butt",
959
+ pointerEvents: endings.end.filled ? "visible" : "visibleStroke",
960
+ ...strokeStyle === PdfAnnotationBorderStyle.DASHED && {
961
+ strokeDasharray: strokeDashArray == null ? void 0 : strokeDashArray.join(",")
962
+ }
963
+ },
964
+ fill: endings.end.filled ? color : "none"
965
+ }
966
+ )
967
+ ]
968
+ }
969
+ );
970
+ }
971
+ function Polyline({
972
+ rect,
973
+ vertices,
974
+ color = "transparent",
975
+ strokeColor = "#000000",
976
+ opacity = 1,
977
+ strokeWidth,
978
+ scale,
979
+ isSelected,
980
+ onClick,
981
+ lineEndings
982
+ }) {
983
+ const localPts = useMemo(
984
+ () => vertices.map(({ x, y }) => ({ x: x - rect.origin.x, y: y - rect.origin.y })),
985
+ [vertices, rect]
986
+ );
987
+ const pathData = useMemo(() => {
988
+ if (!localPts.length) return "";
989
+ const [first, ...rest] = localPts;
990
+ return `M ${first.x} ${first.y} ` + rest.map((p) => `L ${p.x} ${p.y} `).join("").trim();
991
+ }, [localPts]);
992
+ const endings = useMemo(() => {
993
+ if (localPts.length < 2) return { start: null, end: null };
994
+ const toAngle = (a, b) => Math.atan2(b.y - a.y, b.x - a.x);
995
+ const startRad = toAngle(localPts[1], localPts[0]);
996
+ const endRad = toAngle(localPts[localPts.length - 2], localPts[localPts.length - 1]);
997
+ const start = patching.createEnding(
998
+ lineEndings == null ? void 0 : lineEndings.start,
999
+ strokeWidth,
1000
+ startRad + Math.PI,
1001
+ // tip points outward from first segment start
1002
+ localPts[0].x,
1003
+ localPts[0].y
1004
+ );
1005
+ const end = patching.createEnding(
1006
+ lineEndings == null ? void 0 : lineEndings.end,
1007
+ strokeWidth,
1008
+ endRad,
1009
+ localPts[localPts.length - 1].x,
1010
+ localPts[localPts.length - 1].y
1011
+ );
1012
+ return { start, end };
1013
+ }, [localPts, lineEndings, strokeWidth]);
1014
+ const width = rect.size.width * scale;
1015
+ const height = rect.size.height * scale;
1016
+ return /* @__PURE__ */ jsxs(
1017
+ "svg",
1018
+ {
1019
+ style: {
1020
+ position: "absolute",
1021
+ width,
1022
+ height,
1023
+ pointerEvents: "none",
1024
+ zIndex: 2,
1025
+ overflow: "visible"
1026
+ },
1027
+ width,
1028
+ height,
1029
+ viewBox: `0 0 ${rect.size.width} ${rect.size.height}`,
1030
+ children: [
1031
+ /* @__PURE__ */ jsx(
1032
+ "path",
1033
+ {
1034
+ d: pathData,
1035
+ onMouseDown: onClick,
1036
+ opacity,
1037
+ style: {
1038
+ fill: "none",
1039
+ stroke: strokeColor ?? color,
1040
+ strokeWidth,
1041
+ cursor: isSelected ? "move" : "pointer",
1042
+ pointerEvents: "visibleStroke",
1043
+ strokeLinecap: "butt",
1044
+ strokeLinejoin: "miter"
1045
+ }
1046
+ }
1047
+ ),
1048
+ endings.start && /* @__PURE__ */ jsx(
1049
+ "path",
1050
+ {
1051
+ d: endings.start.d,
1052
+ transform: endings.start.transform,
1053
+ stroke: strokeColor,
1054
+ fill: endings.start.filled ? color : "none",
1055
+ onMouseDown: onClick,
1056
+ style: {
1057
+ cursor: isSelected ? "move" : "pointer",
1058
+ strokeWidth,
1059
+ pointerEvents: endings.start.filled ? "visible" : "visibleStroke",
1060
+ strokeLinecap: "butt"
1061
+ }
1062
+ }
1063
+ ),
1064
+ endings.end && /* @__PURE__ */ jsx(
1065
+ "path",
1066
+ {
1067
+ d: endings.end.d,
1068
+ transform: endings.end.transform,
1069
+ stroke: strokeColor,
1070
+ fill: endings.end.filled ? color : "none",
1071
+ onMouseDown: onClick,
1072
+ style: {
1073
+ cursor: isSelected ? "move" : "pointer",
1074
+ strokeWidth,
1075
+ pointerEvents: endings.end.filled ? "visible" : "visibleStroke",
1076
+ strokeLinecap: "butt"
1077
+ }
1078
+ }
1079
+ )
1080
+ ]
1081
+ }
1082
+ );
1083
+ }
1084
+ function Polygon({
1085
+ rect,
1086
+ vertices,
1087
+ color = "transparent",
1088
+ strokeColor = "#000000",
1089
+ opacity = 1,
1090
+ strokeWidth,
1091
+ strokeStyle = PdfAnnotationBorderStyle.SOLID,
1092
+ strokeDashArray,
1093
+ scale,
1094
+ isSelected,
1095
+ onClick
1096
+ }) {
1097
+ const localPts = useMemo(
1098
+ () => vertices.map(({ x, y }) => ({ x: x - rect.origin.x, y: y - rect.origin.y })),
1099
+ [vertices, rect]
1100
+ );
1101
+ const pathData = useMemo(() => {
1102
+ if (!localPts.length) return "";
1103
+ const [first, ...rest] = localPts;
1104
+ return (`M ${first.x} ${first.y} ` + rest.map((p) => `L ${p.x} ${p.y} `).join("") + "Z").trim();
1105
+ }, [localPts]);
1106
+ const width = rect.size.width * scale;
1107
+ const height = rect.size.height * scale;
1108
+ return /* @__PURE__ */ jsx(
1109
+ "svg",
1110
+ {
1111
+ style: {
1112
+ position: "absolute",
1113
+ width,
1114
+ height,
1115
+ pointerEvents: "none",
1116
+ zIndex: 2,
1117
+ overflow: "visible"
1118
+ },
1119
+ width,
1120
+ height,
1121
+ viewBox: `0 0 ${rect.size.width} ${rect.size.height}`,
1122
+ children: /* @__PURE__ */ jsx(
1123
+ "path",
1124
+ {
1125
+ d: pathData,
1126
+ onMouseDown: onClick,
1127
+ opacity,
1128
+ style: {
1129
+ fill: color,
1130
+ stroke: strokeColor ?? color,
1131
+ strokeWidth,
1132
+ cursor: isSelected ? "move" : "pointer",
1133
+ pointerEvents: color === "transparent" ? "visibleStroke" : "visible",
1134
+ strokeLinecap: "butt",
1135
+ strokeLinejoin: "miter",
1136
+ ...strokeStyle === PdfAnnotationBorderStyle.DASHED && {
1137
+ strokeDasharray: strokeDashArray == null ? void 0 : strokeDashArray.join(",")
1138
+ }
1139
+ }
1140
+ }
1141
+ )
1142
+ }
1143
+ );
1144
+ }
1145
+ const patchLine = (orig, ctx) => {
1146
+ if (ctx.vertices && ctx.vertices.length >= 2) {
1147
+ const rect = patching.lineRectWithEndings(ctx.vertices, orig.strokeWidth, orig.lineEndings);
1148
+ return {
1149
+ rect,
1150
+ linePoints: { start: ctx.vertices[0], end: ctx.vertices[1] }
1151
+ };
1152
+ }
1153
+ const dx = ctx.rect.origin.x - orig.rect.origin.x;
1154
+ const dy = ctx.rect.origin.y - orig.rect.origin.y;
1155
+ return {
1156
+ rect: ctx.rect,
1157
+ linePoints: {
1158
+ start: { x: orig.linePoints.start.x + dx, y: orig.linePoints.start.y + dy },
1159
+ end: { x: orig.linePoints.end.x + dx, y: orig.linePoints.end.y + dy }
1160
+ }
1161
+ };
1162
+ };
1163
+ const patchPolyline = (orig, ctx) => {
1164
+ if (ctx.vertices && ctx.vertices.length) {
1165
+ return {
1166
+ rect: patching.lineRectWithEndings(ctx.vertices, orig.strokeWidth, orig.lineEndings),
1167
+ vertices: ctx.vertices
1168
+ };
1169
+ }
1170
+ const dx = ctx.rect.origin.x - orig.rect.origin.x;
1171
+ const dy = ctx.rect.origin.y - orig.rect.origin.y;
1172
+ const moved = orig.vertices.map((p) => ({ x: p.x + dx, y: p.y + dy }));
1173
+ return {
1174
+ rect: ctx.rect,
1175
+ vertices: moved
1176
+ };
1177
+ };
1178
+ const patchPolygon = (orig, ctx) => {
1179
+ if (ctx.vertices && ctx.vertices.length) {
1180
+ const pad = orig.strokeWidth / 2;
1181
+ return {
1182
+ rect: expandRect(rectFromPoints(ctx.vertices), pad),
1183
+ vertices: ctx.vertices
1184
+ };
1185
+ }
1186
+ const dx = ctx.rect.origin.x - orig.rect.origin.x;
1187
+ const dy = ctx.rect.origin.y - orig.rect.origin.y;
1188
+ const moved = orig.vertices.map((p) => ({ x: p.x + dx, y: p.y + dy }));
1189
+ return {
1190
+ rect: ctx.rect,
1191
+ vertices: moved
1192
+ };
1193
+ };
1194
+ function Annotations(annotationsProps) {
1195
+ const { pageIndex, scale, selectionMenu } = annotationsProps;
1196
+ const { provides: annotationProvides } = useAnnotationCapability();
1197
+ const { provides: selectionProvides } = useSelectionCapability();
1198
+ const [annotations, setAnnotations] = useState([]);
1199
+ const { register } = usePointerHandlers({ pageIndex });
1200
+ const [selectionState, setSelectionState] = useState(null);
1201
+ useEffect(() => {
1202
+ if (annotationProvides) {
1203
+ annotationProvides.onStateChange((state) => {
1204
+ setAnnotations(getAnnotationsByPageIndex(state, pageIndex));
1205
+ setSelectionState(getSelectedAnnotationByPageIndex(state, pageIndex));
1206
+ });
1207
+ }
1208
+ }, [annotationProvides]);
1209
+ const handlers = useMemo(
1210
+ () => ({
1211
+ onPointerDown: (_, pe) => {
1212
+ if (pe.target === pe.currentTarget && annotationProvides) {
1213
+ annotationProvides.deselectAnnotation();
1214
+ }
1215
+ }
1216
+ }),
1217
+ [annotationProvides]
1218
+ );
1219
+ const handleClick = useCallback(
1220
+ (e, annotation) => {
1221
+ e.stopPropagation();
1222
+ if (annotationProvides && selectionProvides) {
1223
+ annotationProvides.selectAnnotation(pageIndex, annotation.localId);
1224
+ selectionProvides.clear();
1225
+ }
1226
+ },
1227
+ [annotationProvides, selectionProvides, pageIndex]
1228
+ );
1229
+ useEffect(() => {
1230
+ return register(handlers);
1231
+ }, [register, handlers]);
1232
+ return /* @__PURE__ */ jsx(Fragment$1, { children: annotations.map((annotation) => {
1233
+ const isSelected = (selectionState == null ? void 0 : selectionState.localId) === annotation.localId;
1234
+ if (isInk(annotation)) {
1235
+ return /* @__PURE__ */ jsx(
1236
+ AnnotationContainer,
1237
+ {
1238
+ trackedAnnotation: annotation,
1239
+ isSelected,
1240
+ isDraggable: true,
1241
+ isResizable: true,
1242
+ selectionMenu,
1243
+ computePatch: patchInk,
1244
+ style: {
1245
+ mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1246
+ },
1247
+ ...annotationsProps,
1248
+ children: (obj) => /* @__PURE__ */ jsx(
1249
+ Ink,
1250
+ {
1251
+ cursor: isSelected ? "move" : "pointer",
1252
+ color: obj.color,
1253
+ opacity: obj.opacity,
1254
+ strokeWidth: obj.strokeWidth,
1255
+ inkList: obj.inkList,
1256
+ rect: obj.rect,
1257
+ scale,
1258
+ onClick: (e) => handleClick(e, annotation)
1259
+ }
1260
+ )
1261
+ },
1262
+ annotation.localId
1263
+ );
1264
+ }
1265
+ if (isSquare(annotation)) {
1266
+ return /* @__PURE__ */ jsx(
1267
+ AnnotationContainer,
1268
+ {
1269
+ trackedAnnotation: annotation,
1270
+ isSelected,
1271
+ isDraggable: true,
1272
+ isResizable: true,
1273
+ selectionMenu,
1274
+ style: {
1275
+ mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1276
+ },
1277
+ ...annotationsProps,
1278
+ children: (obj) => /* @__PURE__ */ jsx(
1279
+ Square,
1280
+ {
1281
+ cursor: isSelected ? "move" : "pointer",
1282
+ rect: obj.rect,
1283
+ color: obj.color,
1284
+ opacity: obj.opacity,
1285
+ strokeWidth: obj.strokeWidth,
1286
+ strokeColor: obj.strokeColor,
1287
+ strokeStyle: obj.strokeStyle,
1288
+ strokeDashArray: obj.strokeDashArray,
1289
+ scale,
1290
+ onClick: (e) => handleClick(e, annotation)
1291
+ }
1292
+ )
1293
+ },
1294
+ annotation.localId
1295
+ );
1296
+ }
1297
+ if (isCircle(annotation)) {
1298
+ return /* @__PURE__ */ jsx(
1299
+ AnnotationContainer,
1300
+ {
1301
+ trackedAnnotation: annotation,
1302
+ isSelected,
1303
+ isDraggable: true,
1304
+ isResizable: true,
1305
+ selectionMenu,
1306
+ style: {
1307
+ mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1308
+ },
1309
+ ...annotationsProps,
1310
+ children: (obj) => /* @__PURE__ */ jsx(
1311
+ Circle,
1312
+ {
1313
+ cursor: isSelected ? "move" : "pointer",
1314
+ rect: obj.rect,
1315
+ color: obj.color,
1316
+ opacity: obj.opacity,
1317
+ strokeWidth: obj.strokeWidth,
1318
+ strokeColor: obj.strokeColor,
1319
+ strokeStyle: obj.strokeStyle,
1320
+ strokeDashArray: obj.strokeDashArray,
1321
+ scale,
1322
+ onClick: (e) => handleClick(e, annotation)
1323
+ }
1324
+ )
1325
+ },
1326
+ annotation.localId
1327
+ );
1328
+ }
1329
+ if (isUnderline(annotation)) {
1330
+ return /* @__PURE__ */ jsx(
1331
+ AnnotationContainer,
1332
+ {
1333
+ trackedAnnotation: annotation,
1334
+ isSelected,
1335
+ isDraggable: false,
1336
+ isResizable: false,
1337
+ selectionMenu,
1338
+ style: {
1339
+ mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1340
+ },
1341
+ ...annotationsProps,
1342
+ children: (obj) => /* @__PURE__ */ jsx(
1343
+ Underline,
1344
+ {
1345
+ rect: obj.rect,
1346
+ color: obj.color,
1347
+ opacity: obj.opacity,
1348
+ rects: obj.segmentRects,
1349
+ scale,
1350
+ onClick: (e) => handleClick(e, annotation)
1351
+ }
1352
+ )
1353
+ },
1354
+ annotation.localId
1355
+ );
1356
+ }
1357
+ if (isStrikeout(annotation)) {
1358
+ return /* @__PURE__ */ jsx(
1359
+ AnnotationContainer,
1360
+ {
1361
+ trackedAnnotation: annotation,
1362
+ isSelected,
1363
+ isDraggable: false,
1364
+ isResizable: false,
1365
+ selectionMenu,
1366
+ style: {
1367
+ mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1368
+ },
1369
+ ...annotationsProps,
1370
+ children: (obj) => /* @__PURE__ */ jsx(
1371
+ Strikeout,
1372
+ {
1373
+ rect: obj.rect,
1374
+ color: obj.color,
1375
+ opacity: obj.opacity,
1376
+ rects: obj.segmentRects,
1377
+ scale,
1378
+ onClick: (e) => handleClick(e, annotation)
1379
+ }
1380
+ )
1381
+ },
1382
+ annotation.localId
1383
+ );
1384
+ }
1385
+ if (isSquiggly(annotation)) {
1386
+ return /* @__PURE__ */ jsx(
1387
+ AnnotationContainer,
1388
+ {
1389
+ trackedAnnotation: annotation,
1390
+ isSelected,
1391
+ isDraggable: false,
1392
+ isResizable: false,
1393
+ selectionMenu,
1394
+ style: {
1395
+ mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1396
+ },
1397
+ ...annotationsProps,
1398
+ children: (obj) => /* @__PURE__ */ jsx(
1399
+ Squiggly,
1400
+ {
1401
+ color: obj.color,
1402
+ opacity: obj.opacity,
1403
+ rects: obj.segmentRects,
1404
+ rect: obj.rect,
1405
+ scale,
1406
+ onClick: (e) => handleClick(e, annotation)
1407
+ }
1408
+ )
1409
+ },
1410
+ annotation.localId
1411
+ );
1412
+ }
1413
+ if (isHighlight(annotation)) {
1414
+ return /* @__PURE__ */ jsx(
1415
+ AnnotationContainer,
1416
+ {
1417
+ trackedAnnotation: annotation,
1418
+ isSelected,
1419
+ isDraggable: false,
1420
+ isResizable: false,
1421
+ selectionMenu,
1422
+ style: {
1423
+ mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Multiply)
1424
+ },
1425
+ ...annotationsProps,
1426
+ children: (obj) => /* @__PURE__ */ jsx(
1427
+ Highlight,
1428
+ {
1429
+ color: obj.color,
1430
+ opacity: obj.opacity,
1431
+ rects: obj.segmentRects,
1432
+ scale,
1433
+ rect: obj.rect,
1434
+ onClick: (e) => handleClick(e, annotation)
1435
+ }
1436
+ )
1437
+ },
1438
+ annotation.localId
1439
+ );
1440
+ }
1441
+ if (isLine(annotation)) {
1442
+ return /* @__PURE__ */ jsx(
1443
+ AnnotationContainer,
1444
+ {
1445
+ trackedAnnotation: annotation,
1446
+ isSelected,
1447
+ isDraggable: true,
1448
+ isResizable: false,
1449
+ selectionMenu,
1450
+ computePatch: patchLine,
1451
+ computeVertices: (annotation2) => [
1452
+ annotation2.linePoints.start,
1453
+ annotation2.linePoints.end
1454
+ ],
1455
+ style: {
1456
+ mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1457
+ },
1458
+ ...annotationsProps,
1459
+ children: (obj) => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
1460
+ Line,
1461
+ {
1462
+ isSelected,
1463
+ rect: obj.rect,
1464
+ color: obj.color,
1465
+ opacity: obj.opacity,
1466
+ linePoints: obj.linePoints,
1467
+ lineEndings: obj.lineEndings,
1468
+ strokeWidth: obj.strokeWidth,
1469
+ strokeColor: obj.strokeColor,
1470
+ strokeStyle: obj.strokeStyle,
1471
+ strokeDashArray: obj.strokeDashArray,
1472
+ scale,
1473
+ onClick: (e) => handleClick(e, annotation)
1474
+ }
1475
+ ) })
1476
+ },
1477
+ annotation.localId
1478
+ );
1479
+ }
1480
+ if (isPolyline(annotation)) {
1481
+ return /* @__PURE__ */ jsx(
1482
+ AnnotationContainer,
1483
+ {
1484
+ trackedAnnotation: annotation,
1485
+ isSelected,
1486
+ isDraggable: true,
1487
+ isResizable: false,
1488
+ selectionMenu,
1489
+ computePatch: patchPolyline,
1490
+ computeVertices: (annotation2) => annotation2.vertices,
1491
+ style: {
1492
+ mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1493
+ },
1494
+ ...annotationsProps,
1495
+ children: (obj) => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
1496
+ Polyline,
1497
+ {
1498
+ isSelected,
1499
+ rect: obj.rect,
1500
+ color: obj.color,
1501
+ opacity: obj.opacity,
1502
+ vertices: obj.vertices,
1503
+ lineEndings: obj.lineEndings,
1504
+ strokeWidth: obj.strokeWidth,
1505
+ strokeColor: obj.strokeColor,
1506
+ scale,
1507
+ onClick: (e) => handleClick(e, annotation)
1508
+ }
1509
+ ) })
1510
+ },
1511
+ annotation.localId
1512
+ );
1513
+ }
1514
+ if (isPolygon(annotation)) {
1515
+ return /* @__PURE__ */ jsx(
1516
+ AnnotationContainer,
1517
+ {
1518
+ trackedAnnotation: annotation,
1519
+ isSelected,
1520
+ isDraggable: true,
1521
+ isResizable: false,
1522
+ selectionMenu,
1523
+ computeVertices: (annotation2) => annotation2.vertices,
1524
+ computePatch: patchPolygon,
1525
+ style: {
1526
+ mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
1527
+ },
1528
+ ...annotationsProps,
1529
+ children: (obj) => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
1530
+ Polygon,
1531
+ {
1532
+ isSelected,
1533
+ rect: obj.rect,
1534
+ color: obj.color,
1535
+ opacity: obj.opacity,
1536
+ vertices: obj.vertices,
1537
+ strokeWidth: obj.strokeWidth,
1538
+ strokeColor: obj.strokeColor,
1539
+ strokeStyle: obj.strokeStyle,
1540
+ strokeDashArray: obj.strokeDashArray,
1541
+ scale,
1542
+ onClick: (e) => handleClick(e, annotation)
1543
+ }
1544
+ ) })
1545
+ },
1546
+ annotation.localId
1547
+ );
1548
+ }
1549
+ return null;
1550
+ }) });
1551
+ }
1552
+ function TextMarkup({ pageIndex, scale }) {
1553
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
1554
+ const { provides: selectionProvides } = useSelectionCapability();
1555
+ const { provides: annotationProvides } = useAnnotationCapability();
1556
+ const [rects, setRects] = useState([]);
1557
+ const [boundingRect, setBoundingRect] = useState(null);
1558
+ const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
1559
+ useEffect(() => {
1560
+ if (!selectionProvides) return;
1561
+ const off = selectionProvides.onSelectionChange(() => {
1562
+ setRects(selectionProvides.getHighlightRectsForPage(pageIndex));
1563
+ setBoundingRect(selectionProvides.getBoundingRectForPage(pageIndex));
1564
+ });
1565
+ return off;
1566
+ }, [selectionProvides, pageIndex]);
1567
+ useEffect(() => {
1568
+ if (!annotationProvides) return;
1569
+ const off = annotationProvides.onActiveToolChange(setActiveTool);
1570
+ return off;
1571
+ }, [annotationProvides]);
1572
+ if (!boundingRect) return null;
1573
+ switch (activeTool.variantKey) {
1574
+ case makeVariantKey(PdfAnnotationSubtype.UNDERLINE):
1575
+ return /* @__PURE__ */ jsx(
1576
+ "div",
1577
+ {
1578
+ style: {
1579
+ mixBlendMode: blendModeToCss(((_a = activeTool.defaults) == null ? void 0 : _a.blendMode) ?? PdfBlendMode.Normal),
1580
+ pointerEvents: "none",
1581
+ position: "absolute",
1582
+ inset: 0
1583
+ },
1584
+ children: /* @__PURE__ */ jsx(
1585
+ Underline,
1586
+ {
1587
+ color: (_b = activeTool.defaults) == null ? void 0 : _b.color,
1588
+ opacity: (_c = activeTool.defaults) == null ? void 0 : _c.opacity,
1589
+ rects,
1590
+ scale
1591
+ }
1592
+ )
1593
+ }
1594
+ );
1595
+ case makeVariantKey(PdfAnnotationSubtype.HIGHLIGHT):
1596
+ return /* @__PURE__ */ jsx(
1597
+ "div",
1598
+ {
1599
+ style: {
1600
+ mixBlendMode: blendModeToCss(((_d = activeTool.defaults) == null ? void 0 : _d.blendMode) ?? PdfBlendMode.Multiply),
1601
+ pointerEvents: "none",
1602
+ position: "absolute",
1603
+ inset: 0
1604
+ },
1605
+ children: /* @__PURE__ */ jsx(
1606
+ Highlight,
1607
+ {
1608
+ color: (_e = activeTool.defaults) == null ? void 0 : _e.color,
1609
+ opacity: (_f = activeTool.defaults) == null ? void 0 : _f.opacity,
1610
+ rects,
1611
+ scale
1612
+ }
1613
+ )
1614
+ }
1615
+ );
1616
+ case makeVariantKey(PdfAnnotationSubtype.STRIKEOUT):
1617
+ return /* @__PURE__ */ jsx(
1618
+ "div",
1619
+ {
1620
+ style: {
1621
+ mixBlendMode: blendModeToCss(((_g = activeTool.defaults) == null ? void 0 : _g.blendMode) ?? PdfBlendMode.Normal),
1622
+ pointerEvents: "none",
1623
+ position: "absolute",
1624
+ inset: 0
1625
+ },
1626
+ children: /* @__PURE__ */ jsx(
1627
+ Strikeout,
1628
+ {
1629
+ color: (_h = activeTool.defaults) == null ? void 0 : _h.color,
1630
+ opacity: (_i = activeTool.defaults) == null ? void 0 : _i.opacity,
1631
+ rects,
1632
+ scale
1633
+ }
1634
+ )
1635
+ }
1636
+ );
1637
+ case makeVariantKey(PdfAnnotationSubtype.SQUIGGLY):
1638
+ return /* @__PURE__ */ jsx(
1639
+ "div",
1640
+ {
1641
+ style: {
1642
+ mixBlendMode: blendModeToCss(((_j = activeTool.defaults) == null ? void 0 : _j.blendMode) ?? PdfBlendMode.Normal),
1643
+ pointerEvents: "none",
1644
+ position: "absolute",
1645
+ inset: 0
1646
+ },
1647
+ children: /* @__PURE__ */ jsx(
1648
+ Squiggly,
1649
+ {
1650
+ color: (_k = activeTool.defaults) == null ? void 0 : _k.color,
1651
+ opacity: (_l = activeTool.defaults) == null ? void 0 : _l.opacity,
1652
+ rects,
1653
+ scale
1654
+ }
1655
+ )
1656
+ }
1657
+ );
1658
+ default:
1659
+ return null;
1660
+ }
1661
+ }
1662
+ const InkPaint = ({ pageIndex, scale, pageWidth, pageHeight }) => {
1663
+ var _a, _b, _c, _d, _e;
1664
+ const { provides: annotationProvides } = useAnnotationCapability();
1665
+ const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
1666
+ useEffect(() => {
1667
+ if (!annotationProvides) return;
1668
+ const off = annotationProvides.onActiveToolChange(setActiveTool);
1669
+ return off;
1670
+ }, [annotationProvides]);
1671
+ if (!activeTool.defaults) return null;
1672
+ if (activeTool.defaults.subtype !== PdfAnnotationSubtype.INK) return null;
1673
+ const toolColor = ((_a = activeTool.defaults) == null ? void 0 : _a.color) ?? "#000000";
1674
+ const toolOpacity = ((_b = activeTool.defaults) == null ? void 0 : _b.opacity) ?? 1;
1675
+ const toolStrokeWidth = ((_c = activeTool.defaults) == null ? void 0 : _c.strokeWidth) ?? 2;
1676
+ const toolBlendMode = ((_d = activeTool.defaults) == null ? void 0 : _d.blendMode) ?? PdfBlendMode.Normal;
1677
+ const intent = (_e = activeTool.defaults) == null ? void 0 : _e.intent;
1678
+ const { register } = usePointerHandlers({ modeId: "ink", pageIndex });
1679
+ const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
1680
+ const [currentStrokes, setCurrentStrokes] = useState([]);
1681
+ const [isDrawing, setIsDrawing] = useState(false);
1682
+ const timerRef = useRef(null);
1683
+ const pageWidthPDF = pageWidth / scale;
1684
+ const pageHeightPDF = pageHeight / scale;
1685
+ const handlers = useMemo(
1686
+ () => ({
1687
+ onPointerDown: (pos, evt) => {
1688
+ var _a2, _b2;
1689
+ const curX = clamp(pos.x, 0, pageWidthPDF);
1690
+ const curY = clamp(pos.y, 0, pageHeightPDF);
1691
+ setIsDrawing(true);
1692
+ if (timerRef.current) {
1693
+ clearTimeout(timerRef.current);
1694
+ timerRef.current = null;
1695
+ setCurrentStrokes((prev) => [...prev, { points: [{ x: curX, y: curY }] }]);
1696
+ } else {
1697
+ setCurrentStrokes([{ points: [{ x: curX, y: curY }] }]);
1698
+ }
1699
+ (_b2 = (_a2 = evt.target) == null ? void 0 : _a2.setPointerCapture) == null ? void 0 : _b2.call(_a2, evt.pointerId);
1700
+ },
1701
+ onPointerMove: (pos) => {
1702
+ if (!isDrawing) return;
1703
+ const curX = clamp(pos.x, 0, pageWidthPDF);
1704
+ const curY = clamp(pos.y, 0, pageHeightPDF);
1705
+ setCurrentStrokes((prev) => {
1706
+ if (!prev.length) return prev;
1707
+ const last = prev[prev.length - 1];
1708
+ const newLast = { points: [...last.points, { x: curX, y: curY }] };
1709
+ return [...prev.slice(0, -1), newLast];
1710
+ });
1711
+ },
1712
+ onPointerUp: (_, evt) => {
1713
+ var _a2, _b2;
1714
+ setIsDrawing(false);
1715
+ (_b2 = (_a2 = evt.target) == null ? void 0 : _a2.releasePointerCapture) == null ? void 0 : _b2.call(_a2, evt.pointerId);
1716
+ if (timerRef.current) clearTimeout(timerRef.current);
1717
+ timerRef.current = setTimeout(() => {
1718
+ if (currentStrokes.length && annotationProvides) {
1719
+ const allPoints2 = currentStrokes.flatMap((s) => s.points);
1720
+ if (!allPoints2.length) return;
1721
+ const rect2 = expandRect(rectFromPoints(allPoints2), toolStrokeWidth / 2);
1722
+ if (rect2.size.width < 1 || rect2.size.height < 1) return;
1723
+ const anno = {
1724
+ type: PdfAnnotationSubtype.INK,
1725
+ intent,
1726
+ blendMode: toolBlendMode,
1727
+ rect: rect2,
1728
+ inkList: currentStrokes,
1729
+ color: toolColor,
1730
+ opacity: toolOpacity,
1731
+ strokeWidth: toolStrokeWidth,
1732
+ pageIndex,
1733
+ id: Date.now() + Math.random()
1734
+ };
1735
+ annotationProvides.createAnnotation(pageIndex, anno);
1736
+ annotationProvides.setActiveVariant(null);
1737
+ annotationProvides.selectAnnotation(pageIndex, anno.id);
1738
+ }
1739
+ setCurrentStrokes([]);
1740
+ timerRef.current = null;
1741
+ }, 3e3);
1742
+ },
1743
+ onPointerCancel: (_, evt) => {
1744
+ var _a2, _b2;
1745
+ setIsDrawing(false);
1746
+ (_b2 = (_a2 = evt.target) == null ? void 0 : _a2.releasePointerCapture) == null ? void 0 : _b2.call(_a2, evt.pointerId);
1747
+ setCurrentStrokes([]);
1748
+ if (timerRef.current) {
1749
+ clearTimeout(timerRef.current);
1750
+ timerRef.current = null;
1751
+ }
1752
+ }
1753
+ }),
1754
+ [
1755
+ pageWidthPDF,
1756
+ pageHeightPDF,
1757
+ currentStrokes,
1758
+ annotationProvides,
1759
+ pageIndex,
1760
+ toolColor,
1761
+ toolOpacity,
1762
+ toolStrokeWidth,
1763
+ isDrawing
1764
+ ]
1765
+ );
1766
+ useEffect(() => {
1767
+ if (!register) return;
1768
+ return register(handlers);
1769
+ }, [register, handlers]);
1770
+ useEffect(() => {
1771
+ return () => {
1772
+ if (timerRef.current) clearTimeout(timerRef.current);
1773
+ };
1774
+ }, []);
1775
+ if (!currentStrokes.length) return null;
1776
+ const allPoints = currentStrokes.flatMap((s) => s.points);
1777
+ if (!allPoints.length) return null;
1778
+ const rect = expandRect(rectFromPoints(allPoints), toolStrokeWidth / 2);
1779
+ const paths = currentStrokes.map(({ points }) => {
1780
+ let d = "";
1781
+ points.forEach(({ x, y }, i) => {
1782
+ const lx = x - rect.origin.x;
1783
+ const ly = y - rect.origin.y;
1784
+ d += (i === 0 ? "M" : "L") + lx + " " + ly + " ";
1785
+ });
1786
+ return d.trim();
1787
+ });
1788
+ return /* @__PURE__ */ jsx(
1789
+ "svg",
1790
+ {
1791
+ style: {
1792
+ position: "absolute",
1793
+ left: rect.origin.x * scale,
1794
+ top: rect.origin.y * scale,
1795
+ width: rect.size.width * scale,
1796
+ height: rect.size.height * scale,
1797
+ pointerEvents: "none",
1798
+ zIndex: 2
1799
+ },
1800
+ width: rect.size.width * scale,
1801
+ height: rect.size.height * scale,
1802
+ viewBox: `0 0 ${rect.size.width} ${rect.size.height}`,
1803
+ children: paths.map((d, i) => /* @__PURE__ */ jsx(
1804
+ "path",
1805
+ {
1806
+ d,
1807
+ fill: "none",
1808
+ opacity: toolOpacity,
1809
+ style: {
1810
+ stroke: toolColor,
1811
+ strokeWidth: toolStrokeWidth,
1812
+ strokeLinecap: "round",
1813
+ strokeLinejoin: "round"
1814
+ }
1815
+ },
1816
+ i
1817
+ ))
1818
+ }
1819
+ );
1820
+ };
1821
+ const CirclePaint = ({
1822
+ pageIndex,
1823
+ scale,
1824
+ pageWidth,
1825
+ pageHeight,
1826
+ cursor
1827
+ }) => {
1828
+ const { provides: annotationProvides } = useAnnotationCapability();
1829
+ const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
1830
+ useEffect(() => {
1831
+ if (!annotationProvides) return;
1832
+ return annotationProvides.onActiveToolChange(setActiveTool);
1833
+ }, [annotationProvides]);
1834
+ if (!activeTool.defaults) return null;
1835
+ if (activeTool.defaults.subtype !== PdfAnnotationSubtype.CIRCLE) return null;
1836
+ const toolColor = activeTool.defaults.color ?? "#000000";
1837
+ const toolOpacity = activeTool.defaults.opacity ?? 1;
1838
+ const toolStrokeWidth = activeTool.defaults.strokeWidth ?? 2;
1839
+ const toolStrokeColor = activeTool.defaults.strokeColor ?? "#000000";
1840
+ const toolStrokeStyle = activeTool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID;
1841
+ const toolStrokeDashArray = activeTool.defaults.strokeDashArray ?? [];
1842
+ const { register } = usePointerHandlers({ modeId: "circle", pageIndex });
1843
+ const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
1844
+ const pageWidthPDF = pageWidth / scale;
1845
+ const pageHeightPDF = pageHeight / scale;
1846
+ const [start, setStart] = useState(null);
1847
+ const [current, setCurrent] = useState(null);
1848
+ const handlers = useMemo(
1849
+ () => ({
1850
+ onPointerDown: (pos, evt) => {
1851
+ var _a, _b;
1852
+ const x = clamp(pos.x, 0, pageWidthPDF);
1853
+ const y = clamp(pos.y, 0, pageHeightPDF);
1854
+ setStart({ x, y });
1855
+ setCurrent({ x, y });
1856
+ (_b = (_a = evt.target) == null ? void 0 : _a.setPointerCapture) == null ? void 0 : _b.call(_a, evt.pointerId);
1857
+ },
1858
+ onPointerMove: (pos) => {
1859
+ if (!start) return;
1860
+ const x = clamp(pos.x, 0, pageWidthPDF);
1861
+ const y = clamp(pos.y, 0, pageHeightPDF);
1862
+ setCurrent({ x, y });
1863
+ },
1864
+ onPointerUp: (_, evt) => {
1865
+ var _a, _b;
1866
+ if (start && current && annotationProvides) {
1867
+ const minX2 = Math.min(start.x, current.x);
1868
+ const minY2 = Math.min(start.y, current.y);
1869
+ const maxX2 = Math.max(start.x, current.x);
1870
+ const maxY2 = Math.max(start.y, current.y);
1871
+ if (maxX2 - minX2 >= 1 && maxY2 - minY2 >= 1) {
1872
+ const halfStroke2 = toolStrokeWidth / 2;
1873
+ const rect = {
1874
+ origin: { x: minX2 - halfStroke2, y: minY2 - halfStroke2 },
1875
+ size: {
1876
+ width: maxX2 - minX2 + toolStrokeWidth,
1877
+ height: maxY2 - minY2 + toolStrokeWidth
1878
+ }
1879
+ };
1880
+ const anno = {
1881
+ type: PdfAnnotationSubtype.CIRCLE,
1882
+ rect,
1883
+ flags: ["print"],
1884
+ color: toolColor,
1885
+ opacity: toolOpacity,
1886
+ strokeWidth: toolStrokeWidth,
1887
+ strokeColor: toolStrokeColor,
1888
+ strokeStyle: toolStrokeStyle,
1889
+ strokeDashArray: toolStrokeDashArray,
1890
+ pageIndex,
1891
+ id: Date.now() + Math.random()
1892
+ };
1893
+ annotationProvides.createAnnotation(pageIndex, anno);
1894
+ annotationProvides.setActiveVariant(null);
1895
+ annotationProvides.selectAnnotation(pageIndex, anno.id);
1896
+ }
1897
+ }
1898
+ (_b = (_a = evt.target) == null ? void 0 : _a.releasePointerCapture) == null ? void 0 : _b.call(_a, evt.pointerId);
1899
+ setStart(null);
1900
+ setCurrent(null);
1901
+ },
1902
+ onPointerCancel: (_, evt) => {
1903
+ var _a, _b;
1904
+ (_b = (_a = evt.target) == null ? void 0 : _a.releasePointerCapture) == null ? void 0 : _b.call(_a, evt.pointerId);
1905
+ setStart(null);
1906
+ setCurrent(null);
1907
+ }
1908
+ }),
1909
+ [
1910
+ start,
1911
+ current,
1912
+ annotationProvides,
1913
+ pageIndex,
1914
+ pageWidthPDF,
1915
+ pageHeightPDF,
1916
+ toolColor,
1917
+ toolOpacity,
1918
+ toolStrokeWidth
1919
+ ]
1920
+ );
1921
+ useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
1922
+ if (!start || !current) return null;
1923
+ const minX = Math.min(start.x, current.x);
1924
+ const minY = Math.min(start.y, current.y);
1925
+ const maxX = Math.max(start.x, current.x);
1926
+ const maxY = Math.max(start.y, current.y);
1927
+ const halfStroke = toolStrokeWidth / 2;
1928
+ const svgMinX = minX - halfStroke;
1929
+ const svgMinY = minY - halfStroke;
1930
+ const width = maxX - minX;
1931
+ const height = maxY - minY;
1932
+ const dw = width + toolStrokeWidth;
1933
+ const dh = height + toolStrokeWidth;
1934
+ const cx = halfStroke + width / 2;
1935
+ const cy = halfStroke + height / 2;
1936
+ const rx = width / 2;
1937
+ const ry = height / 2;
1938
+ return /* @__PURE__ */ jsx(
1939
+ "svg",
1940
+ {
1941
+ style: {
1942
+ position: "absolute",
1943
+ left: svgMinX * scale,
1944
+ top: svgMinY * scale,
1945
+ width: dw * scale,
1946
+ height: dh * scale,
1947
+ pointerEvents: "none",
1948
+ zIndex: 2
1949
+ },
1950
+ width: dw * scale,
1951
+ height: dh * scale,
1952
+ viewBox: `0 0 ${dw} ${dh}`,
1953
+ children: /* @__PURE__ */ jsx(
1954
+ "ellipse",
1955
+ {
1956
+ cx,
1957
+ cy,
1958
+ rx,
1959
+ ry,
1960
+ fill: toolColor,
1961
+ opacity: toolOpacity,
1962
+ style: {
1963
+ cursor,
1964
+ stroke: toolStrokeColor,
1965
+ strokeWidth: toolStrokeWidth,
1966
+ ...toolStrokeStyle === PdfAnnotationBorderStyle.DASHED && {
1967
+ strokeDasharray: toolStrokeDashArray.join(",")
1968
+ }
1969
+ }
1970
+ }
1971
+ )
1972
+ }
1973
+ );
1974
+ };
1975
+ const SquarePaint = ({
1976
+ pageIndex,
1977
+ scale,
1978
+ pageWidth,
1979
+ pageHeight,
1980
+ cursor
1981
+ }) => {
1982
+ const { provides: annotationProvides } = useAnnotationCapability();
1983
+ const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
1984
+ useEffect(() => {
1985
+ if (!annotationProvides) return;
1986
+ return annotationProvides.onActiveToolChange(setActiveTool);
1987
+ }, [annotationProvides]);
1988
+ if (!activeTool.defaults) return null;
1989
+ if (activeTool.defaults.subtype !== PdfAnnotationSubtype.SQUARE) return null;
1990
+ const toolColor = activeTool.defaults.color ?? "#000000";
1991
+ const toolOpacity = activeTool.defaults.opacity ?? 1;
1992
+ const toolStrokeWidth = activeTool.defaults.strokeWidth ?? 2;
1993
+ const toolStrokeColor = activeTool.defaults.strokeColor ?? "#000000";
1994
+ const toolStrokeStyle = activeTool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID;
1995
+ const toolStrokeDashArray = activeTool.defaults.strokeDashArray ?? [];
1996
+ const { register } = usePointerHandlers({ modeId: "square", pageIndex });
1997
+ const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
1998
+ const pageWidthPDF = pageWidth / scale;
1999
+ const pageHeightPDF = pageHeight / scale;
2000
+ const [start, setStart] = useState(null);
2001
+ const [current, setCurrent] = useState(null);
2002
+ const handlers = useMemo(
2003
+ () => ({
2004
+ onPointerDown: (pos, evt) => {
2005
+ var _a, _b;
2006
+ const x = clamp(pos.x, 0, pageWidthPDF);
2007
+ const y = clamp(pos.y, 0, pageHeightPDF);
2008
+ setStart({ x, y });
2009
+ setCurrent({ x, y });
2010
+ (_b = (_a = evt.target) == null ? void 0 : _a.setPointerCapture) == null ? void 0 : _b.call(_a, evt.pointerId);
2011
+ },
2012
+ onPointerMove: (pos) => {
2013
+ if (!start) return;
2014
+ const x = clamp(pos.x, 0, pageWidthPDF);
2015
+ const y = clamp(pos.y, 0, pageHeightPDF);
2016
+ setCurrent({ x, y });
2017
+ },
2018
+ onPointerUp: (_, evt) => {
2019
+ var _a, _b;
2020
+ if (start && current && annotationProvides) {
2021
+ const minX2 = Math.min(start.x, current.x);
2022
+ const minY2 = Math.min(start.y, current.y);
2023
+ const maxX2 = Math.max(start.x, current.x);
2024
+ const maxY2 = Math.max(start.y, current.y);
2025
+ if (maxX2 - minX2 >= 1 && maxY2 - minY2 >= 1) {
2026
+ const halfStroke2 = toolStrokeWidth / 2;
2027
+ const rect = {
2028
+ origin: { x: minX2 - halfStroke2, y: minY2 - halfStroke2 },
2029
+ size: {
2030
+ width: maxX2 - minX2 + toolStrokeWidth,
2031
+ height: maxY2 - minY2 + toolStrokeWidth
2032
+ }
2033
+ };
2034
+ const anno = {
2035
+ type: PdfAnnotationSubtype.SQUARE,
2036
+ rect,
2037
+ flags: ["print"],
2038
+ color: toolColor,
2039
+ opacity: toolOpacity,
2040
+ strokeWidth: toolStrokeWidth,
2041
+ strokeColor: toolStrokeColor,
2042
+ strokeStyle: toolStrokeStyle,
2043
+ strokeDashArray: toolStrokeDashArray,
2044
+ pageIndex,
2045
+ id: Date.now() + Math.random()
2046
+ };
2047
+ annotationProvides.createAnnotation(pageIndex, anno);
2048
+ annotationProvides.setActiveVariant(null);
2049
+ annotationProvides.selectAnnotation(pageIndex, anno.id);
2050
+ }
2051
+ }
2052
+ (_b = (_a = evt.target) == null ? void 0 : _a.releasePointerCapture) == null ? void 0 : _b.call(_a, evt.pointerId);
2053
+ setStart(null);
2054
+ setCurrent(null);
2055
+ },
2056
+ onPointerCancel: (_, evt) => {
2057
+ var _a, _b;
2058
+ (_b = (_a = evt.target) == null ? void 0 : _a.releasePointerCapture) == null ? void 0 : _b.call(_a, evt.pointerId);
2059
+ setStart(null);
2060
+ setCurrent(null);
2061
+ }
2062
+ }),
2063
+ [
2064
+ start,
2065
+ current,
2066
+ annotationProvides,
2067
+ pageIndex,
2068
+ pageWidthPDF,
2069
+ pageHeightPDF,
2070
+ toolColor,
2071
+ toolOpacity,
2072
+ toolStrokeWidth
2073
+ ]
2074
+ );
2075
+ useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
2076
+ if (!start || !current) return null;
2077
+ const minX = Math.min(start.x, current.x);
2078
+ const minY = Math.min(start.y, current.y);
2079
+ const maxX = Math.max(start.x, current.x);
2080
+ const maxY = Math.max(start.y, current.y);
2081
+ const halfStroke = toolStrokeWidth / 2;
2082
+ const svgMinX = minX - halfStroke;
2083
+ const svgMinY = minY - halfStroke;
2084
+ const width = maxX - minX;
2085
+ const height = maxY - minY;
2086
+ const dw = width + toolStrokeWidth;
2087
+ const dh = height + toolStrokeWidth;
2088
+ return /* @__PURE__ */ jsx(
2089
+ "svg",
2090
+ {
2091
+ style: {
2092
+ position: "absolute",
2093
+ left: svgMinX * scale,
2094
+ top: svgMinY * scale,
2095
+ width: dw * scale,
2096
+ height: dh * scale,
2097
+ pointerEvents: "none",
2098
+ zIndex: 2
2099
+ },
2100
+ width: dw * scale,
2101
+ height: dh * scale,
2102
+ viewBox: `0 0 ${dw} ${dh}`,
2103
+ children: /* @__PURE__ */ jsx(
2104
+ "rect",
2105
+ {
2106
+ x: halfStroke,
2107
+ y: halfStroke,
2108
+ width,
2109
+ height,
2110
+ fill: toolColor,
2111
+ opacity: toolOpacity,
2112
+ style: {
2113
+ cursor,
2114
+ stroke: toolStrokeColor,
2115
+ strokeWidth: toolStrokeWidth,
2116
+ ...toolStrokeStyle === PdfAnnotationBorderStyle.DASHED && {
2117
+ strokeDasharray: toolStrokeDashArray.join(",")
2118
+ }
2119
+ }
2120
+ }
2121
+ )
2122
+ }
2123
+ );
2124
+ };
2125
+ const PolylinePaint = ({
2126
+ pageIndex,
2127
+ scale,
2128
+ pageWidth,
2129
+ pageHeight,
2130
+ cursor
2131
+ }) => {
2132
+ const { provides: annotationProvides } = useAnnotationCapability();
2133
+ const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
2134
+ useEffect(() => {
2135
+ if (!annotationProvides) return;
2136
+ return annotationProvides.onActiveToolChange(setActiveTool);
2137
+ }, [annotationProvides]);
2138
+ if (!activeTool.defaults) return null;
2139
+ if (activeTool.defaults.subtype !== PdfAnnotationSubtype.POLYLINE) return null;
2140
+ const toolColor = activeTool.defaults.color ?? "#000000";
2141
+ const toolOpacity = activeTool.defaults.opacity ?? 1;
2142
+ const toolStrokeWidth = activeTool.defaults.strokeWidth ?? 2;
2143
+ const toolStrokeColor = activeTool.defaults.strokeColor ?? "#000000";
2144
+ const toolLineEndings = activeTool.defaults.lineEndings;
2145
+ const toolStrokeStyle = activeTool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID;
2146
+ const toolStrokeDashArray = activeTool.defaults.strokeDashArray;
2147
+ const { register } = usePointerHandlers({ modeId: "polyline", pageIndex });
2148
+ const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
2149
+ const pageWidthPDF = pageWidth / scale;
2150
+ const pageHeightPDF = pageHeight / scale;
2151
+ const [vertices, setVertices] = useState([]);
2152
+ const [current, setCurrent] = useState(null);
2153
+ const commitPolyline = (pts) => {
2154
+ if (pts.length < 2) return;
2155
+ const rect2 = patching.lineRectWithEndings(pts, toolStrokeWidth, toolLineEndings);
2156
+ const anno = {
2157
+ type: PdfAnnotationSubtype.POLYLINE,
2158
+ rect: rect2,
2159
+ vertices: pts,
2160
+ color: toolColor,
2161
+ opacity: toolOpacity,
2162
+ strokeWidth: toolStrokeWidth,
2163
+ strokeColor: toolStrokeColor,
2164
+ strokeStyle: toolStrokeStyle,
2165
+ strokeDashArray: toolStrokeDashArray,
2166
+ lineEndings: toolLineEndings,
2167
+ pageIndex,
2168
+ id: Date.now() + Math.random()
2169
+ };
2170
+ annotationProvides.createAnnotation(pageIndex, anno);
2171
+ annotationProvides.setActiveVariant(null);
2172
+ annotationProvides.selectAnnotation(pageIndex, anno.id);
2173
+ };
2174
+ const handlers = useMemo(
2175
+ () => ({
2176
+ onClick: (pos) => {
2177
+ const x = clamp(pos.x, 0, pageWidthPDF);
2178
+ const y = clamp(pos.y, 0, pageHeightPDF);
2179
+ setVertices((prev) => [...prev, { x, y }]);
2180
+ setCurrent({ x, y });
2181
+ },
2182
+ onDoubleClick: () => {
2183
+ if (vertices.length >= 1 && annotationProvides) {
2184
+ commitPolyline(vertices);
2185
+ }
2186
+ setVertices([]);
2187
+ setCurrent(null);
2188
+ },
2189
+ onPointerMove: (pos) => {
2190
+ if (!vertices.length) return;
2191
+ const x = clamp(pos.x, 0, pageWidthPDF);
2192
+ const y = clamp(pos.y, 0, pageHeightPDF);
2193
+ setCurrent({ x, y });
2194
+ },
2195
+ onPointerCancel: () => {
2196
+ setVertices([]);
2197
+ setCurrent(null);
2198
+ }
2199
+ }),
2200
+ [vertices, annotationProvides, pageWidthPDF, pageHeightPDF]
2201
+ );
2202
+ useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
2203
+ if (!vertices.length || !current) return null;
2204
+ const allPts = [...vertices, current];
2205
+ const rect = patching.lineRectWithEndings(allPts, toolStrokeWidth, toolLineEndings);
2206
+ return /* @__PURE__ */ jsx(
2207
+ "div",
2208
+ {
2209
+ style: {
2210
+ position: "absolute",
2211
+ left: rect.origin.x * scale,
2212
+ top: rect.origin.y * scale,
2213
+ width: rect.size.width * scale,
2214
+ height: rect.size.height * scale,
2215
+ pointerEvents: "none",
2216
+ zIndex: 2,
2217
+ overflow: "visible",
2218
+ cursor
2219
+ },
2220
+ children: /* @__PURE__ */ jsx(
2221
+ Polyline,
2222
+ {
2223
+ rect,
2224
+ vertices: allPts,
2225
+ strokeWidth: toolStrokeWidth,
2226
+ scale,
2227
+ isSelected: false,
2228
+ color: toolColor,
2229
+ strokeColor: toolStrokeColor,
2230
+ opacity: toolOpacity,
2231
+ lineEndings: toolLineEndings
2232
+ }
2233
+ )
2234
+ }
2235
+ );
2236
+ };
2237
+ const LinePaint = ({ pageIndex, scale, pageWidth, pageHeight, cursor }) => {
2238
+ const { provides: annotationProvides } = useAnnotationCapability();
2239
+ const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
2240
+ useEffect(() => {
2241
+ if (!annotationProvides) return;
2242
+ return annotationProvides.onActiveToolChange(setActiveTool);
2243
+ }, [annotationProvides]);
2244
+ if (!activeTool.defaults) return null;
2245
+ if (activeTool.defaults.subtype !== PdfAnnotationSubtype.LINE) return null;
2246
+ const toolColor = activeTool.defaults.color ?? "#000000";
2247
+ const toolOpacity = activeTool.defaults.opacity ?? 1;
2248
+ const toolStrokeWidth = activeTool.defaults.strokeWidth ?? 2;
2249
+ const toolStrokeColor = activeTool.defaults.strokeColor ?? "#000000";
2250
+ const toolStrokeStyle = activeTool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID;
2251
+ const toolStrokeDashArray = activeTool.defaults.strokeDashArray;
2252
+ const toolLineEndings = activeTool.defaults.lineEndings;
2253
+ const intent = activeTool.defaults.intent;
2254
+ const { register } = usePointerHandlers({ modeId: ["line", "lineArrow"], pageIndex });
2255
+ const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
2256
+ const pageWidthPDF = pageWidth / scale;
2257
+ const pageHeightPDF = pageHeight / scale;
2258
+ const [start, setStart] = useState(null);
2259
+ const [current, setCurrent] = useState(null);
2260
+ const commitLine = (p1, p2) => {
2261
+ if (Math.abs(p2.x - p1.x) < 1 && Math.abs(p2.y - p1.y) < 1) return;
2262
+ const rect2 = patching.lineRectWithEndings([p1, p2], toolStrokeWidth, toolLineEndings);
2263
+ const anno = {
2264
+ type: PdfAnnotationSubtype.LINE,
2265
+ rect: rect2,
2266
+ linePoints: { start: p1, end: p2 },
2267
+ color: toolColor,
2268
+ opacity: toolOpacity,
2269
+ strokeWidth: toolStrokeWidth,
2270
+ strokeColor: toolStrokeColor,
2271
+ strokeStyle: toolStrokeStyle,
2272
+ strokeDashArray: toolStrokeDashArray,
2273
+ lineEndings: toolLineEndings,
2274
+ intent,
2275
+ pageIndex,
2276
+ id: Date.now() + Math.random()
2277
+ };
2278
+ annotationProvides.createAnnotation(pageIndex, anno);
2279
+ annotationProvides.setActiveVariant(null);
2280
+ annotationProvides.selectAnnotation(pageIndex, anno.id);
2281
+ };
2282
+ const handlers = useMemo(
2283
+ () => ({
2284
+ onPointerDown: (pos, evt) => {
2285
+ var _a, _b;
2286
+ const x = clamp(pos.x, 0, pageWidthPDF);
2287
+ const y = clamp(pos.y, 0, pageHeightPDF);
2288
+ setStart({ x, y });
2289
+ setCurrent({ x, y });
2290
+ (_b = (_a = evt.target) == null ? void 0 : _a.setPointerCapture) == null ? void 0 : _b.call(_a, evt.pointerId);
2291
+ },
2292
+ onPointerMove: (pos) => {
2293
+ if (!start) return;
2294
+ const x = clamp(pos.x, 0, pageWidthPDF);
2295
+ const y = clamp(pos.y, 0, pageHeightPDF);
2296
+ setCurrent({ x, y });
2297
+ },
2298
+ onPointerUp: (_, evt) => {
2299
+ var _a, _b;
2300
+ if (start && current && annotationProvides) {
2301
+ commitLine(start, current);
2302
+ }
2303
+ (_b = (_a = evt.target) == null ? void 0 : _a.releasePointerCapture) == null ? void 0 : _b.call(_a, evt.pointerId);
2304
+ setStart(null);
2305
+ setCurrent(null);
2306
+ },
2307
+ onPointerCancel: (_, evt) => {
2308
+ var _a, _b;
2309
+ (_b = (_a = evt.target) == null ? void 0 : _a.releasePointerCapture) == null ? void 0 : _b.call(_a, evt.pointerId);
2310
+ setStart(null);
2311
+ setCurrent(null);
2312
+ }
2313
+ }),
2314
+ [start, current, annotationProvides, pageWidthPDF, pageHeightPDF]
2315
+ );
2316
+ useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
2317
+ if (!start || !current) return null;
2318
+ const rect = patching.lineRectWithEndings([start, current], toolStrokeWidth, toolLineEndings);
2319
+ return /* @__PURE__ */ jsx(
2320
+ "div",
2321
+ {
2322
+ style: {
2323
+ position: "absolute",
2324
+ left: rect.origin.x * scale,
2325
+ top: rect.origin.y * scale,
2326
+ width: rect.size.width * scale,
2327
+ height: rect.size.height * scale,
2328
+ pointerEvents: "none",
2329
+ zIndex: 2,
2330
+ overflow: "visible",
2331
+ cursor
2332
+ },
2333
+ children: /* @__PURE__ */ jsx(
2334
+ Line,
2335
+ {
2336
+ rect,
2337
+ linePoints: { start, end: current },
2338
+ strokeWidth: toolStrokeWidth,
2339
+ scale,
2340
+ isSelected: false,
2341
+ color: toolColor,
2342
+ strokeColor: toolStrokeColor,
2343
+ opacity: toolOpacity,
2344
+ lineEndings: toolLineEndings,
2345
+ strokeStyle: toolStrokeStyle,
2346
+ strokeDashArray: toolStrokeDashArray
2347
+ }
2348
+ )
2349
+ }
2350
+ );
2351
+ };
2352
+ const HANDLE_SIZE_PX = 14;
2353
+ const PolygonPaint = ({
2354
+ pageIndex,
2355
+ scale,
2356
+ pageWidth,
2357
+ pageHeight,
2358
+ cursor
2359
+ }) => {
2360
+ const { provides: annotationProvides } = useAnnotationCapability();
2361
+ const [activeTool, setActiveTool] = useState({ variantKey: null, defaults: null });
2362
+ useEffect(() => annotationProvides == null ? void 0 : annotationProvides.onActiveToolChange(setActiveTool), [annotationProvides]);
2363
+ if (!activeTool.defaults || activeTool.defaults.subtype !== PdfAnnotationSubtype.POLYGON)
2364
+ return null;
2365
+ const toolColor = activeTool.defaults.color ?? "#000000";
2366
+ const toolOpacity = activeTool.defaults.opacity ?? 1;
2367
+ const toolStrokeWidth = activeTool.defaults.strokeWidth ?? 2;
2368
+ const toolStrokeColor = activeTool.defaults.strokeColor ?? "#000000";
2369
+ const toolStrokeStyle = activeTool.defaults.strokeStyle ?? PdfAnnotationBorderStyle.SOLID;
2370
+ const toolStrokeDashArray = activeTool.defaults.strokeDashArray;
2371
+ const { register } = usePointerHandlers({ modeId: "polygon", pageIndex });
2372
+ const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
2373
+ const pageWidthPDF = pageWidth / scale;
2374
+ const pageHeightPDF = pageHeight / scale;
2375
+ const [vertices, setVertices] = useState([]);
2376
+ const [current, setCurrent] = useState(null);
2377
+ const commitPolygon = (pts) => {
2378
+ const xs2 = pts.map((p) => p.x), ys2 = pts.map((p) => p.y);
2379
+ const minX2 = Math.min(...xs2), minY2 = Math.min(...ys2);
2380
+ const maxX2 = Math.max(...xs2), maxY2 = Math.max(...ys2);
2381
+ if (maxX2 - minX2 < 1 || maxY2 - minY2 < 1) return;
2382
+ const half2 = toolStrokeWidth / 2;
2383
+ const rect = {
2384
+ origin: { x: minX2 - half2, y: minY2 - half2 },
2385
+ size: { width: maxX2 - minX2 + toolStrokeWidth, height: maxY2 - minY2 + toolStrokeWidth }
2386
+ };
2387
+ const anno = {
2388
+ type: PdfAnnotationSubtype.POLYGON,
2389
+ rect,
2390
+ vertices: pts,
2391
+ color: toolColor,
2392
+ opacity: toolOpacity,
2393
+ strokeWidth: toolStrokeWidth,
2394
+ strokeColor: toolStrokeColor,
2395
+ strokeStyle: toolStrokeStyle,
2396
+ strokeDashArray: toolStrokeDashArray,
2397
+ pageIndex,
2398
+ id: Date.now() + Math.random()
2399
+ };
2400
+ annotationProvides.createAnnotation(pageIndex, anno);
2401
+ annotationProvides.setActiveVariant(null);
2402
+ annotationProvides.selectAnnotation(pageIndex, anno.id);
2403
+ };
2404
+ const isInsideStartHandle = (x, y) => {
2405
+ if (vertices.length < 2) return false;
2406
+ const sizePDF = HANDLE_SIZE_PX / scale;
2407
+ const half2 = sizePDF / 2;
2408
+ const v0 = vertices[0];
2409
+ return x >= v0.x - half2 && x <= v0.x + half2 && y >= v0.y - half2 && y <= v0.y + half2;
2410
+ };
2411
+ const handlers = useMemo(
2412
+ () => ({
2413
+ onClick: (pos) => {
2414
+ const x = clamp(pos.x, 0, pageWidthPDF);
2415
+ const y = clamp(pos.y, 0, pageHeightPDF);
2416
+ if (isInsideStartHandle(x, y) && vertices.length >= 3 && annotationProvides) {
2417
+ commitPolygon(vertices);
2418
+ setVertices([]);
2419
+ setCurrent(null);
2420
+ return;
2421
+ }
2422
+ setVertices((prev) => [...prev, { x, y }]);
2423
+ setCurrent({ x, y });
2424
+ },
2425
+ onDoubleClick: () => {
2426
+ if (vertices.length >= 3 && annotationProvides) {
2427
+ commitPolygon(vertices);
2428
+ setVertices([]);
2429
+ setCurrent(null);
2430
+ } else {
2431
+ setVertices([]);
2432
+ setCurrent(null);
2433
+ }
2434
+ },
2435
+ onPointerMove: (pos) => {
2436
+ if (!vertices.length) return;
2437
+ const x = clamp(pos.x, 0, pageWidthPDF);
2438
+ const y = clamp(pos.y, 0, pageHeightPDF);
2439
+ setCurrent({ x, y });
2440
+ },
2441
+ onPointerCancel: () => {
2442
+ setVertices([]);
2443
+ setCurrent(null);
2444
+ }
2445
+ }),
2446
+ [vertices, current, annotationProvides, pageWidthPDF, pageHeightPDF]
2447
+ );
2448
+ useEffect(() => register ? register(handlers) : void 0, [register, handlers]);
2449
+ if (!vertices.length || !current) return null;
2450
+ const allPts = [...vertices, current];
2451
+ const xs = allPts.map((p) => p.x), ys = allPts.map((p) => p.y);
2452
+ const minX = Math.min(...xs), minY = Math.min(...ys);
2453
+ const maxX = Math.max(...xs), maxY = Math.max(...ys);
2454
+ const half = toolStrokeWidth / 2;
2455
+ const svgMinX = minX - half;
2456
+ const svgMinY = minY - half;
2457
+ const svgMaxX = maxX + half;
2458
+ const svgMaxY = maxY + half;
2459
+ const dw = svgMaxX - svgMinX;
2460
+ const dh = svgMaxY - svgMinY;
2461
+ const mainPath = useMemo(() => {
2462
+ let d = "";
2463
+ allPts.forEach(({ x, y }, i) => {
2464
+ d += (i === 0 ? "M" : "L") + (x - svgMinX) + " " + (y - svgMinY) + " ";
2465
+ });
2466
+ return d.trim();
2467
+ }, [allPts, svgMinX, svgMinY]);
2468
+ const dottedPath = vertices.length >= 2 ? (() => {
2469
+ const curLx = current.x - svgMinX;
2470
+ const curLy = current.y - svgMinY;
2471
+ const firstLx = vertices[0].x - svgMinX;
2472
+ const firstLy = vertices[0].y - svgMinY;
2473
+ return `M ${curLx} ${curLy} L ${firstLx} ${firstLy}`;
2474
+ })() : null;
2475
+ const handleSizePDF = HANDLE_SIZE_PX / scale;
2476
+ const hHalf = handleSizePDF / 2;
2477
+ const hx = vertices[0].x - hHalf - svgMinX;
2478
+ const hy = vertices[0].y - hHalf - svgMinY;
2479
+ return /* @__PURE__ */ jsxs(
2480
+ "svg",
2481
+ {
2482
+ style: {
2483
+ position: "absolute",
2484
+ left: svgMinX * scale,
2485
+ top: svgMinY * scale,
2486
+ width: dw * scale,
2487
+ height: dh * scale,
2488
+ pointerEvents: "none",
2489
+ // we handle clicks at the page layer
2490
+ zIndex: 2,
2491
+ overflow: "visible"
2492
+ },
2493
+ width: dw * scale,
2494
+ height: dh * scale,
2495
+ viewBox: `0 0 ${dw} ${dh}`,
2496
+ children: [
2497
+ /* @__PURE__ */ jsx(
2498
+ "path",
2499
+ {
2500
+ d: mainPath,
2501
+ fill: toolColor,
2502
+ opacity: toolOpacity,
2503
+ style: {
2504
+ cursor,
2505
+ stroke: toolStrokeColor,
2506
+ strokeWidth: toolStrokeWidth,
2507
+ ...toolStrokeStyle === PdfAnnotationBorderStyle.DASHED && {
2508
+ strokeDasharray: toolStrokeDashArray == null ? void 0 : toolStrokeDashArray.join(",")
2509
+ }
2510
+ }
2511
+ }
2512
+ ),
2513
+ dottedPath && /* @__PURE__ */ jsx(
2514
+ "path",
2515
+ {
2516
+ d: dottedPath,
2517
+ fill: "none",
2518
+ style: { stroke: toolStrokeColor, strokeWidth: toolStrokeWidth, strokeDasharray: "4,4" }
2519
+ }
2520
+ ),
2521
+ vertices.length >= 3 && /* @__PURE__ */ jsx(
2522
+ "rect",
2523
+ {
2524
+ x: hx,
2525
+ y: hy,
2526
+ width: handleSizePDF,
2527
+ height: handleSizePDF,
2528
+ fill: toolStrokeColor,
2529
+ opacity: 0.4,
2530
+ stroke: toolStrokeColor,
2531
+ strokeWidth: toolStrokeWidth / 2,
2532
+ style: { pointerEvents: "none" }
2533
+ }
2534
+ )
2535
+ ]
2536
+ }
2537
+ );
2538
+ };
2539
+ function AnnotationLayer({
2540
+ pageIndex,
2541
+ scale,
2542
+ pageWidth,
2543
+ pageHeight,
2544
+ rotation,
2545
+ selectionMenu,
2546
+ style,
2547
+ ...props
2548
+ }) {
2549
+ return /* @__PURE__ */ jsxs(
2550
+ "div",
2551
+ {
2552
+ style: {
2553
+ ...style
2554
+ },
2555
+ ...props,
2556
+ children: [
2557
+ /* @__PURE__ */ jsx(
2558
+ Annotations,
2559
+ {
2560
+ selectionMenu,
2561
+ pageIndex,
2562
+ scale,
2563
+ rotation,
2564
+ pageWidth,
2565
+ pageHeight
2566
+ }
2567
+ ),
2568
+ /* @__PURE__ */ jsx(TextMarkup, { pageIndex, scale }),
2569
+ /* @__PURE__ */ jsx(InkPaint, { pageIndex, scale, pageWidth, pageHeight }),
2570
+ /* @__PURE__ */ jsx(
2571
+ CirclePaint,
2572
+ {
2573
+ pageIndex,
2574
+ scale,
2575
+ pageWidth,
2576
+ pageHeight
2577
+ }
2578
+ ),
2579
+ /* @__PURE__ */ jsx(
2580
+ SquarePaint,
2581
+ {
2582
+ pageIndex,
2583
+ scale,
2584
+ pageWidth,
2585
+ pageHeight
2586
+ }
2587
+ ),
2588
+ /* @__PURE__ */ jsx(
2589
+ PolygonPaint,
2590
+ {
2591
+ pageIndex,
2592
+ scale,
2593
+ pageWidth,
2594
+ pageHeight
2595
+ }
2596
+ ),
2597
+ /* @__PURE__ */ jsx(
2598
+ PolylinePaint,
2599
+ {
2600
+ pageIndex,
2601
+ scale,
2602
+ pageWidth,
2603
+ pageHeight
2604
+ }
2605
+ ),
2606
+ /* @__PURE__ */ jsx(
2607
+ LinePaint,
2608
+ {
2609
+ pageIndex,
2610
+ scale,
2611
+ pageWidth,
2612
+ pageHeight
2613
+ }
2614
+ )
2615
+ ]
2616
+ }
2617
+ );
2618
+ }
2619
+ export {
2620
+ AnnotationLayer,
2621
+ useAnnotationCapability,
2622
+ useAnnotationPlugin
2623
+ };
2624
+ //# sourceMappingURL=index.js.map