@embedpdf/plugin-annotation 2.7.0 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +1131 -203
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/annotation-plugin.d.ts +2 -0
  6. package/dist/lib/geometry/cloudy-border.d.ts +90 -0
  7. package/dist/lib/geometry/index.d.ts +1 -0
  8. package/dist/lib/handlers/index.d.ts +4 -0
  9. package/dist/lib/handlers/insert-text.handler.d.ts +8 -0
  10. package/dist/lib/handlers/replace-text.handler.d.ts +9 -0
  11. package/dist/lib/handlers/selection-utils.d.ts +7 -0
  12. package/dist/lib/handlers/text-markup.handler.d.ts +7 -0
  13. package/dist/lib/handlers/text.handler.d.ts +3 -0
  14. package/dist/lib/handlers/types.d.ts +14 -1
  15. package/dist/lib/helpers.d.ts +2 -1
  16. package/dist/lib/selectors.d.ts +6 -1
  17. package/dist/lib/tools/default-tools.d.ts +141 -45
  18. package/dist/lib/tools/tools-utils.d.ts +2 -0
  19. package/dist/lib/tools/types.d.ts +34 -1
  20. package/dist/lib/types.d.ts +1 -0
  21. package/dist/preact/index.cjs +1 -1
  22. package/dist/preact/index.cjs.map +1 -1
  23. package/dist/preact/index.js +621 -274
  24. package/dist/preact/index.js.map +1 -1
  25. package/dist/react/index.cjs +1 -1
  26. package/dist/react/index.cjs.map +1 -1
  27. package/dist/react/index.js +621 -274
  28. package/dist/react/index.js.map +1 -1
  29. package/dist/shared/annotation-bounds.d.ts +14 -0
  30. package/dist/shared/components/annotation-container.d.ts +4 -2
  31. package/dist/shared/components/annotations/caret.d.ts +24 -0
  32. package/dist/shared/components/annotations/circle.d.ts +8 -4
  33. package/dist/shared/components/annotations/free-text.d.ts +2 -2
  34. package/dist/shared/components/annotations/ink.d.ts +2 -2
  35. package/dist/shared/components/annotations/line.d.ts +2 -2
  36. package/dist/shared/components/annotations/link.d.ts +2 -2
  37. package/dist/shared/components/annotations/polygon.d.ts +5 -3
  38. package/dist/shared/components/annotations/polyline.d.ts +8 -4
  39. package/dist/shared/components/annotations/square.d.ts +8 -4
  40. package/dist/shared/components/annotations/stamp.d.ts +2 -2
  41. package/dist/shared/components/annotations/text.d.ts +14 -0
  42. package/dist/shared/components/text-markup/highlight.d.ts +2 -2
  43. package/dist/shared/components/text-markup/squiggly.d.ts +2 -2
  44. package/dist/shared/components/text-markup/strikeout.d.ts +2 -2
  45. package/dist/shared/components/text-markup/underline.d.ts +2 -2
  46. package/dist/shared/components/types.d.ts +8 -4
  47. package/dist/shared-preact/annotation-bounds.d.ts +14 -0
  48. package/dist/shared-preact/components/annotation-container.d.ts +4 -2
  49. package/dist/shared-preact/components/annotations/caret.d.ts +24 -0
  50. package/dist/shared-preact/components/annotations/circle.d.ts +8 -4
  51. package/dist/shared-preact/components/annotations/free-text.d.ts +2 -2
  52. package/dist/shared-preact/components/annotations/ink.d.ts +2 -2
  53. package/dist/shared-preact/components/annotations/line.d.ts +2 -2
  54. package/dist/shared-preact/components/annotations/link.d.ts +2 -2
  55. package/dist/shared-preact/components/annotations/polygon.d.ts +5 -3
  56. package/dist/shared-preact/components/annotations/polyline.d.ts +8 -4
  57. package/dist/shared-preact/components/annotations/square.d.ts +8 -4
  58. package/dist/shared-preact/components/annotations/stamp.d.ts +2 -2
  59. package/dist/shared-preact/components/annotations/text.d.ts +14 -0
  60. package/dist/shared-preact/components/text-markup/highlight.d.ts +2 -2
  61. package/dist/shared-preact/components/text-markup/squiggly.d.ts +2 -2
  62. package/dist/shared-preact/components/text-markup/strikeout.d.ts +2 -2
  63. package/dist/shared-preact/components/text-markup/underline.d.ts +2 -2
  64. package/dist/shared-preact/components/types.d.ts +8 -4
  65. package/dist/shared-react/annotation-bounds.d.ts +14 -0
  66. package/dist/shared-react/components/annotation-container.d.ts +4 -2
  67. package/dist/shared-react/components/annotations/caret.d.ts +24 -0
  68. package/dist/shared-react/components/annotations/circle.d.ts +8 -4
  69. package/dist/shared-react/components/annotations/free-text.d.ts +2 -2
  70. package/dist/shared-react/components/annotations/ink.d.ts +2 -2
  71. package/dist/shared-react/components/annotations/line.d.ts +2 -2
  72. package/dist/shared-react/components/annotations/link.d.ts +2 -2
  73. package/dist/shared-react/components/annotations/polygon.d.ts +5 -3
  74. package/dist/shared-react/components/annotations/polyline.d.ts +8 -4
  75. package/dist/shared-react/components/annotations/square.d.ts +8 -4
  76. package/dist/shared-react/components/annotations/stamp.d.ts +2 -2
  77. package/dist/shared-react/components/annotations/text.d.ts +14 -0
  78. package/dist/shared-react/components/text-markup/highlight.d.ts +2 -2
  79. package/dist/shared-react/components/text-markup/squiggly.d.ts +2 -2
  80. package/dist/shared-react/components/text-markup/strikeout.d.ts +2 -2
  81. package/dist/shared-react/components/text-markup/underline.d.ts +2 -2
  82. package/dist/shared-react/components/types.d.ts +8 -4
  83. package/dist/shared-vue/annotation-bounds.d.ts +14 -0
  84. package/dist/svelte/components/annotations/Caret.svelte.d.ts +13 -0
  85. package/dist/svelte/components/annotations/Circle.svelte.d.ts +4 -2
  86. package/dist/svelte/components/annotations/FreeText.svelte.d.ts +1 -1
  87. package/dist/svelte/components/annotations/Ink.svelte.d.ts +1 -1
  88. package/dist/svelte/components/annotations/Line.svelte.d.ts +1 -1
  89. package/dist/svelte/components/annotations/Link.svelte.d.ts +1 -1
  90. package/dist/svelte/components/annotations/Polygon.svelte.d.ts +2 -1
  91. package/dist/svelte/components/annotations/Polyline.svelte.d.ts +4 -2
  92. package/dist/svelte/components/annotations/Square.svelte.d.ts +4 -2
  93. package/dist/svelte/components/annotations/Stamp.svelte.d.ts +1 -1
  94. package/dist/svelte/components/annotations/Text.svelte.d.ts +10 -0
  95. package/dist/svelte/components/annotations/index.d.ts +1 -0
  96. package/dist/svelte/components/renderers/CaretRenderer.svelte.d.ts +5 -0
  97. package/dist/svelte/components/renderers/TextRenderer.svelte.d.ts +5 -0
  98. package/dist/svelte/components/text-markup/Highlight.svelte.d.ts +1 -1
  99. package/dist/svelte/components/text-markup/Squiggly.svelte.d.ts +1 -1
  100. package/dist/svelte/components/text-markup/Strikeout.svelte.d.ts +1 -1
  101. package/dist/svelte/components/text-markup/Underline.svelte.d.ts +1 -1
  102. package/dist/svelte/components/types.d.ts +2 -1
  103. package/dist/svelte/context/types.d.ts +7 -3
  104. package/dist/svelte/index.cjs +1 -1
  105. package/dist/svelte/index.cjs.map +1 -1
  106. package/dist/svelte/index.js +831 -416
  107. package/dist/svelte/index.js.map +1 -1
  108. package/dist/vue/components/annotation-container.vue.d.ts +9 -8
  109. package/dist/vue/components/annotation-layer.vue.d.ts +1 -1
  110. package/dist/vue/components/annotations/caret.vue.d.ts +24 -0
  111. package/dist/vue/components/annotations/circle.vue.d.ts +7 -3
  112. package/dist/vue/components/annotations/free-text.vue.d.ts +2 -2
  113. package/dist/vue/components/annotations/index.d.ts +1 -0
  114. package/dist/vue/components/annotations/ink.vue.d.ts +2 -2
  115. package/dist/vue/components/annotations/line.vue.d.ts +2 -2
  116. package/dist/vue/components/annotations/link.vue.d.ts +2 -2
  117. package/dist/vue/components/annotations/polygon.vue.d.ts +4 -2
  118. package/dist/vue/components/annotations/polyline.vue.d.ts +8 -3
  119. package/dist/vue/components/annotations/square.vue.d.ts +7 -3
  120. package/dist/vue/components/annotations/stamp.vue.d.ts +2 -2
  121. package/dist/vue/components/annotations/text.vue.d.ts +14 -0
  122. package/dist/vue/components/annotations.vue.d.ts +9 -10
  123. package/dist/vue/components/renderers/caret-renderer.vue.d.ts +6 -0
  124. package/dist/vue/components/renderers/text-renderer.vue.d.ts +6 -0
  125. package/dist/vue/components/text-markup/highlight.vue.d.ts +2 -2
  126. package/dist/vue/components/text-markup/squiggly.vue.d.ts +2 -2
  127. package/dist/vue/components/text-markup/strikeout.vue.d.ts +2 -2
  128. package/dist/vue/components/text-markup/underline.vue.d.ts +2 -2
  129. package/dist/vue/context/types.d.ts +7 -3
  130. package/dist/vue/index.cjs +1 -1
  131. package/dist/vue/index.cjs.map +1 -1
  132. package/dist/vue/index.js +778 -354
  133. package/dist/vue/index.js.map +1 -1
  134. package/package.json +10 -10
@@ -1,14 +1,15 @@
1
1
  import { createPluginPackage } from "@embedpdf/core";
2
- import { initialDocumentState, AnnotationPlugin, patching, getAnnotationsByPageIndex, getSelectedAnnotationIds, resolveInteractionProp, AnnotationPluginPackage as AnnotationPluginPackage$1 } from "@embedpdf/plugin-annotation";
2
+ import { initialDocumentState, AnnotationPlugin, generateCloudyRectanglePath, generateCloudyEllipsePath, patching, generateCloudyPolygonPath, getAnnotationsByPageIndex, getSelectedAnnotationIds, resolveInteractionProp, AnnotationPluginPackage as AnnotationPluginPackage$1 } from "@embedpdf/plugin-annotation";
3
3
  export * from "@embedpdf/plugin-annotation";
4
4
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
5
5
  import { createContext, useState, useCallback, useContext, useRef, useEffect, useMemo, useLayoutEffect, Fragment as Fragment$1 } from "react";
6
6
  import { createPortal } from "react-dom";
7
7
  import { useCapability, usePlugin, useDocumentPermissions, useDocumentState } from "@embedpdf/core/react";
8
- import { inferRotationCenterFromRects, boundingRectOrEmpty, PdfAnnotationBorderStyle, PdfVerticalAlignment, textAlignmentToCss, standardFontCssProperties, ignore, PdfErrorCode, PdfAnnotationSubtype, blendModeToCss, PdfBlendMode } from "@embedpdf/models";
8
+ import { inferRotationCenterFromRects, boundingRectOrEmpty, PdfAnnotationBorderStyle, getContrastStrokeColor, PdfVerticalAlignment, textAlignmentToCss, standardFontCssProperties, ignore, PdfErrorCode, PdfBlendMode, PdfAnnotationSubtype, blendModeToCss } from "@embedpdf/models";
9
9
  import { usePointerHandlers } from "@embedpdf/plugin-interaction-manager/react";
10
10
  import { useSelectionCapability } from "@embedpdf/plugin-selection/react";
11
11
  import { useInteractionHandles, useDoublePressProps, CounterRotate } from "@embedpdf/utils/react";
12
+ import { getCounterRotation } from "@embedpdf/utils";
12
13
  const suppressContentEditableWarningProps = {
13
14
  suppressContentEditableWarning: true
14
15
  };
@@ -114,6 +115,7 @@ function AnnotationContainer({
114
115
  isRotatable = true,
115
116
  lockAspectRatio = false,
116
117
  style = {},
118
+ blendMode,
117
119
  vertexConfig,
118
120
  selectionMenu,
119
121
  outlineOffset = 1,
@@ -151,6 +153,11 @@ function AnnotationContainer({
151
153
  [annotationCapability, documentId]
152
154
  );
153
155
  const currentObject = preview ? { ...trackedAnnotation.object, ...preview } : trackedAnnotation.object;
156
+ const annoFlags = trackedAnnotation.object.flags ?? [];
157
+ const hasNoZoom = annoFlags.includes("noZoom");
158
+ const hasNoRotate = annoFlags.includes("noRotate");
159
+ const visualScale = hasNoZoom ? 1 : scale;
160
+ const effectivePageRotation = hasNoRotate ? 0 : rotation;
154
161
  const HANDLE_COLOR = (resizeUI == null ? void 0 : resizeUI.color) ?? "#007ACC";
155
162
  const VERTEX_COLOR = (vertexUI == null ? void 0 : vertexUI.color) ?? "#007ACC";
156
163
  const ROTATION_COLOR = (rotationUI == null ? void 0 : rotationUI.color) ?? "white";
@@ -343,17 +350,21 @@ function AnnotationContainer({
343
350
  return () => unsubs.forEach((u) => u());
344
351
  }, [plugin, documentId, trackedAnnotation.object]);
345
352
  const showOutline = isSelected && !isMultiSelected;
346
- const aabbWidth = currentObject.rect.size.width * scale;
347
- const aabbHeight = currentObject.rect.size.height * scale;
348
- const innerWidth = effectiveUnrotatedRect.size.width * scale;
349
- const innerHeight = effectiveUnrotatedRect.size.height * scale;
353
+ const aabbWidth = currentObject.rect.size.width * visualScale;
354
+ const aabbHeight = currentObject.rect.size.height * visualScale;
355
+ const innerWidth = effectiveUnrotatedRect.size.width * visualScale;
356
+ const innerHeight = effectiveUnrotatedRect.size.height * visualScale;
350
357
  const usesCustomPivot = Boolean(explicitUnrotatedRect) && annotationRotation !== 0;
351
- const innerLeft = usesCustomPivot ? (effectiveUnrotatedRect.origin.x - currentObject.rect.origin.x) * scale : (aabbWidth - innerWidth) / 2;
352
- const innerTop = usesCustomPivot ? (effectiveUnrotatedRect.origin.y - currentObject.rect.origin.y) * scale : (aabbHeight - innerHeight) / 2;
353
- const innerTransformOrigin = usesCustomPivot && rotationPivot ? `${(rotationPivot.x - effectiveUnrotatedRect.origin.x) * scale}px ${(rotationPivot.y - effectiveUnrotatedRect.origin.y) * scale}px` : "center center";
354
- const centerX = rotationPivot ? (rotationPivot.x - currentObject.rect.origin.x) * scale : aabbWidth / 2;
355
- const centerY = rotationPivot ? (rotationPivot.y - currentObject.rect.origin.y) * scale : aabbHeight / 2;
358
+ const innerLeft = usesCustomPivot ? (effectiveUnrotatedRect.origin.x - currentObject.rect.origin.x) * visualScale : (aabbWidth - innerWidth) / 2;
359
+ const innerTop = usesCustomPivot ? (effectiveUnrotatedRect.origin.y - currentObject.rect.origin.y) * visualScale : (aabbHeight - innerHeight) / 2;
360
+ const innerTransformOrigin = usesCustomPivot && rotationPivot ? `${(rotationPivot.x - effectiveUnrotatedRect.origin.x) * visualScale}px ${(rotationPivot.y - effectiveUnrotatedRect.origin.y) * visualScale}px` : "center center";
361
+ const centerX = rotationPivot ? (rotationPivot.x - currentObject.rect.origin.x) * visualScale : aabbWidth / 2;
362
+ const centerY = rotationPivot ? (rotationPivot.y - currentObject.rect.origin.y) * visualScale : aabbHeight / 2;
356
363
  const guideLength = Math.max(300, Math.max(aabbWidth, aabbHeight) + 80);
364
+ const counterRot = hasNoRotate ? getCounterRotation(
365
+ { origin: { x: 0, y: 0 }, size: { width: aabbWidth, height: aabbHeight } },
366
+ rotation
367
+ ) : null;
357
368
  const childObject = useMemo(() => {
358
369
  if (explicitUnrotatedRect) {
359
370
  return { ...currentObject, rect: explicitUnrotatedRect };
@@ -361,237 +372,250 @@ function AnnotationContainer({
361
372
  return currentObject;
362
373
  }, [currentObject, explicitUnrotatedRect]);
363
374
  const apActive = !!(appearance == null ? void 0 : appearance.normal) && !gestureActive && !isEditing && !trackedAnnotation.dictMode;
375
+ const layerBaseStyle = {
376
+ position: "absolute",
377
+ left: currentObject.rect.origin.x * scale,
378
+ top: currentObject.rect.origin.y * scale,
379
+ width: counterRot ? counterRot.width : aabbWidth,
380
+ height: counterRot ? counterRot.height : aabbHeight,
381
+ pointerEvents: "none",
382
+ zIndex,
383
+ // noRotate: apply counter-rotation matrix so the annotation stays upright
384
+ ...counterRot && {
385
+ transform: counterRot.matrix,
386
+ transformOrigin: "0 0"
387
+ }
388
+ };
389
+ const innerDivBaseStyle = {
390
+ position: "absolute",
391
+ left: innerLeft,
392
+ top: innerTop,
393
+ width: innerWidth,
394
+ height: innerHeight,
395
+ transform: annotationRotation !== 0 ? `rotate(${annotationRotation}deg)` : void 0,
396
+ transformOrigin: innerTransformOrigin
397
+ };
364
398
  return /* @__PURE__ */ jsxs("div", { "data-no-interaction": true, children: [
365
- /* @__PURE__ */ jsxs(
399
+ /* @__PURE__ */ jsx(
366
400
  "div",
367
401
  {
368
402
  style: {
369
- position: "absolute",
370
- left: currentObject.rect.origin.x * scale,
371
- top: currentObject.rect.origin.y * scale,
372
- width: aabbWidth,
373
- height: aabbHeight,
374
- pointerEvents: "none",
375
- zIndex,
403
+ ...layerBaseStyle,
404
+ ...blendMode && { mixBlendMode: blendMode },
376
405
  ...style
377
406
  },
378
- ...props,
379
- children: [
380
- rotationActive && /* @__PURE__ */ jsxs(Fragment, { children: [
381
- /* @__PURE__ */ jsx(
382
- "div",
383
- {
384
- style: {
385
- position: "absolute",
386
- left: centerX - guideLength / 2,
387
- top: centerY,
388
- width: guideLength,
389
- height: 1,
390
- backgroundColor: ROTATION_CONNECTOR_COLOR,
391
- opacity: 0.35,
392
- pointerEvents: "none"
393
- }
394
- }
395
- ),
396
- /* @__PURE__ */ jsx(
407
+ children: /* @__PURE__ */ jsxs("div", { style: { ...innerDivBaseStyle, pointerEvents: "none" }, children: [
408
+ (() => {
409
+ const childrenRender = typeof children === "function" ? children(childObject, { appearanceActive: apActive }) : children;
410
+ const customRender = customAnnotationRenderer == null ? void 0 : customAnnotationRenderer({
411
+ annotation: childObject,
412
+ children: childrenRender,
413
+ isSelected,
414
+ scale,
415
+ rotation,
416
+ pageWidth,
417
+ pageHeight,
418
+ pageIndex,
419
+ onSelect
420
+ });
421
+ return customRender ?? childrenRender;
422
+ })(),
423
+ (appearance == null ? void 0 : appearance.normal) && /* @__PURE__ */ jsx(
424
+ AppearanceImage,
425
+ {
426
+ appearance: appearance.normal,
427
+ style: { display: apActive ? "block" : "none" }
428
+ }
429
+ )
430
+ ] })
431
+ }
432
+ ),
433
+ /* @__PURE__ */ jsxs("div", { style: layerBaseStyle, ...props, children: [
434
+ rotationActive && /* @__PURE__ */ jsxs(Fragment, { children: [
435
+ /* @__PURE__ */ jsx(
436
+ "div",
437
+ {
438
+ style: {
439
+ position: "absolute",
440
+ left: centerX - guideLength / 2,
441
+ top: centerY,
442
+ width: guideLength,
443
+ height: 1,
444
+ backgroundColor: ROTATION_CONNECTOR_COLOR,
445
+ opacity: 0.35,
446
+ pointerEvents: "none"
447
+ }
448
+ }
449
+ ),
450
+ /* @__PURE__ */ jsx(
451
+ "div",
452
+ {
453
+ style: {
454
+ position: "absolute",
455
+ left: centerX,
456
+ top: centerY - guideLength / 2,
457
+ width: 1,
458
+ height: guideLength,
459
+ backgroundColor: ROTATION_CONNECTOR_COLOR,
460
+ opacity: 0.35,
461
+ pointerEvents: "none"
462
+ }
463
+ }
464
+ ),
465
+ /* @__PURE__ */ jsx(
466
+ "div",
467
+ {
468
+ style: {
469
+ position: "absolute",
470
+ left: centerX - guideLength / 2,
471
+ top: centerY,
472
+ width: guideLength,
473
+ height: 1,
474
+ transformOrigin: "center center",
475
+ transform: `rotate(${annotationRotation}deg)`,
476
+ backgroundColor: ROTATION_CONNECTOR_COLOR,
477
+ opacity: 0.8,
478
+ pointerEvents: "none"
479
+ }
480
+ }
481
+ )
482
+ ] }),
483
+ isSelected && effectiveIsRotatable && rotationHandle && ((rotationUI == null ? void 0 : rotationUI.component) ? /* @__PURE__ */ jsx(
484
+ "div",
485
+ {
486
+ onPointerEnter: () => setIsHandleHovered(true),
487
+ onPointerLeave: () => {
488
+ setIsHandleHovered(false);
489
+ setCursorScreen(null);
490
+ },
491
+ onPointerMove: (e) => {
492
+ if (!rotationActive) setCursorScreen({ x: e.clientX, y: e.clientY });
493
+ },
494
+ style: { display: "contents" },
495
+ children: rotationUI.component({
496
+ ...rotationHandle.handle,
497
+ backgroundColor: ROTATION_COLOR,
498
+ iconColor: ROTATION_ICON_COLOR,
499
+ connectorStyle: {
500
+ ...rotationHandle.connector.style,
501
+ backgroundColor: ROTATION_CONNECTOR_COLOR,
502
+ opacity: rotationActive ? 0 : 1
503
+ },
504
+ showConnector: SHOW_CONNECTOR,
505
+ opacity: rotationActive ? 0 : 1,
506
+ border: {
507
+ color: ROTATION_BORDER_COLOR,
508
+ width: ROTATION_BORDER_WIDTH,
509
+ style: ROTATION_BORDER_STYLE
510
+ }
511
+ })
512
+ }
513
+ ) : /* @__PURE__ */ jsxs(
514
+ "div",
515
+ {
516
+ onPointerEnter: () => setIsHandleHovered(true),
517
+ onPointerLeave: () => {
518
+ setIsHandleHovered(false);
519
+ setCursorScreen(null);
520
+ },
521
+ onPointerMove: (e) => {
522
+ if (!rotationActive) setCursorScreen({ x: e.clientX, y: e.clientY });
523
+ },
524
+ style: { display: "contents" },
525
+ children: [
526
+ SHOW_CONNECTOR && /* @__PURE__ */ jsx(
397
527
  "div",
398
528
  {
399
529
  style: {
400
- position: "absolute",
401
- left: centerX,
402
- top: centerY - guideLength / 2,
403
- width: 1,
404
- height: guideLength,
530
+ ...rotationHandle.connector.style,
405
531
  backgroundColor: ROTATION_CONNECTOR_COLOR,
406
- opacity: 0.35,
407
- pointerEvents: "none"
532
+ opacity: rotationActive ? 0 : 1
408
533
  }
409
534
  }
410
535
  ),
411
536
  /* @__PURE__ */ jsx(
412
537
  "div",
413
538
  {
414
- style: {
415
- position: "absolute",
416
- left: centerX - guideLength / 2,
417
- top: centerY,
418
- width: guideLength,
419
- height: 1,
420
- transformOrigin: "center center",
421
- transform: `rotate(${annotationRotation}deg)`,
422
- backgroundColor: ROTATION_CONNECTOR_COLOR,
423
- opacity: 0.8,
424
- pointerEvents: "none"
425
- }
426
- }
427
- )
428
- ] }),
429
- isSelected && effectiveIsRotatable && rotationHandle && ((rotationUI == null ? void 0 : rotationUI.component) ? /* @__PURE__ */ jsx(
430
- "div",
431
- {
432
- onPointerEnter: () => setIsHandleHovered(true),
433
- onPointerLeave: () => {
434
- setIsHandleHovered(false);
435
- setCursorScreen(null);
436
- },
437
- onPointerMove: (e) => {
438
- if (!rotationActive) setCursorScreen({ x: e.clientX, y: e.clientY });
439
- },
440
- style: { display: "contents" },
441
- children: rotationUI.component({
442
539
  ...rotationHandle.handle,
443
- backgroundColor: ROTATION_COLOR,
444
- iconColor: ROTATION_ICON_COLOR,
445
- connectorStyle: {
446
- ...rotationHandle.connector.style,
447
- backgroundColor: ROTATION_CONNECTOR_COLOR,
540
+ style: {
541
+ ...rotationHandle.handle.style,
542
+ backgroundColor: ROTATION_COLOR,
543
+ border: `${ROTATION_BORDER_WIDTH}px ${ROTATION_BORDER_STYLE} ${ROTATION_BORDER_COLOR}`,
544
+ boxSizing: "border-box",
545
+ display: "flex",
546
+ alignItems: "center",
547
+ justifyContent: "center",
548
+ pointerEvents: "auto",
448
549
  opacity: rotationActive ? 0 : 1
449
550
  },
450
- showConnector: SHOW_CONNECTOR,
451
- opacity: rotationActive ? 0 : 1,
452
- border: {
453
- color: ROTATION_BORDER_COLOR,
454
- width: ROTATION_BORDER_WIDTH,
455
- style: ROTATION_BORDER_STYLE
456
- }
457
- })
458
- }
459
- ) : /* @__PURE__ */ jsxs(
460
- "div",
461
- {
462
- onPointerEnter: () => setIsHandleHovered(true),
463
- onPointerLeave: () => {
464
- setIsHandleHovered(false);
465
- setCursorScreen(null);
466
- },
467
- onPointerMove: (e) => {
468
- if (!rotationActive) setCursorScreen({ x: e.clientX, y: e.clientY });
469
- },
470
- style: { display: "contents" },
471
- children: [
472
- SHOW_CONNECTOR && /* @__PURE__ */ jsx(
473
- "div",
474
- {
475
- style: {
476
- ...rotationHandle.connector.style,
477
- backgroundColor: ROTATION_CONNECTOR_COLOR,
478
- opacity: rotationActive ? 0 : 1
479
- }
480
- }
481
- ),
482
- /* @__PURE__ */ jsx(
483
- "div",
484
- {
485
- ...rotationHandle.handle,
486
- style: {
487
- ...rotationHandle.handle.style,
488
- backgroundColor: ROTATION_COLOR,
489
- border: `${ROTATION_BORDER_WIDTH}px ${ROTATION_BORDER_STYLE} ${ROTATION_BORDER_COLOR}`,
490
- boxSizing: "border-box",
491
- display: "flex",
492
- alignItems: "center",
493
- justifyContent: "center",
494
- pointerEvents: "auto",
495
- opacity: rotationActive ? 0 : 1
496
- },
497
- children: /* @__PURE__ */ jsxs(
498
- "svg",
499
- {
500
- width: Math.round(ROTATION_SIZE * 0.6),
501
- height: Math.round(ROTATION_SIZE * 0.6),
502
- viewBox: "0 0 24 24",
503
- fill: "none",
504
- stroke: ROTATION_ICON_COLOR,
505
- strokeWidth: "2",
506
- strokeLinecap: "round",
507
- strokeLinejoin: "round",
508
- children: [
509
- /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" }),
510
- /* @__PURE__ */ jsx("path", { d: "M21 3v5h-5" })
511
- ]
512
- }
513
- )
514
- }
515
- )
516
- ]
517
- }
518
- )),
519
- /* @__PURE__ */ jsxs(
520
- "div",
521
- {
522
- ...effectiveIsDraggable && isSelected ? dragProps : {},
523
- ...doubleProps,
524
- style: {
525
- position: "absolute",
526
- left: innerLeft,
527
- top: innerTop,
528
- width: innerWidth,
529
- height: innerHeight,
530
- transform: annotationRotation !== 0 ? `rotate(${annotationRotation}deg)` : void 0,
531
- transformOrigin: innerTransformOrigin,
532
- outline: showOutline ? `${outlineWidth}px ${outlineStyle} ${outlineColor}` : "none",
533
- outlineOffset: showOutline ? `${outlineOff}px` : "0px",
534
- pointerEvents: isSelected && !isMultiSelected ? "auto" : "none",
535
- touchAction: "none",
536
- cursor: isSelected && effectiveIsDraggable ? "move" : "default"
537
- },
538
- children: [
539
- (() => {
540
- const childrenRender = typeof children === "function" ? children(childObject, { appearanceActive: apActive }) : children;
541
- const customRender = customAnnotationRenderer == null ? void 0 : customAnnotationRenderer({
542
- annotation: childObject,
543
- children: childrenRender,
544
- isSelected,
545
- scale,
546
- rotation,
547
- pageWidth,
548
- pageHeight,
549
- pageIndex,
550
- onSelect
551
- });
552
- return customRender ?? childrenRender;
553
- })(),
554
- (appearance == null ? void 0 : appearance.normal) && /* @__PURE__ */ jsx(
555
- AppearanceImage,
551
+ children: /* @__PURE__ */ jsxs(
552
+ "svg",
556
553
  {
557
- appearance: appearance.normal,
558
- style: { display: apActive ? "block" : "none" }
554
+ width: Math.round(ROTATION_SIZE * 0.6),
555
+ height: Math.round(ROTATION_SIZE * 0.6),
556
+ viewBox: "0 0 24 24",
557
+ fill: "none",
558
+ stroke: ROTATION_ICON_COLOR,
559
+ strokeWidth: "2",
560
+ strokeLinecap: "round",
561
+ strokeLinejoin: "round",
562
+ children: [
563
+ /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" }),
564
+ /* @__PURE__ */ jsx("path", { d: "M21 3v5h-5" })
565
+ ]
559
566
  }
560
- ),
561
- isSelected && effectiveIsResizable && !rotationActive && resize.map(
562
- ({ key, ...hProps }) => (resizeUI == null ? void 0 : resizeUI.component) ? resizeUI.component({
563
- key,
564
- ...hProps,
565
- backgroundColor: HANDLE_COLOR
566
- }) : /* @__PURE__ */ jsx(
567
- "div",
568
- {
569
- ...hProps,
570
- style: { ...hProps.style, backgroundColor: HANDLE_COLOR }
571
- },
572
- key
573
- )
574
- ),
575
- isSelected && canModifyAnnotations && !isMultiSelected && !rotationActive && vertices.map(
576
- ({ key, ...vProps }) => (vertexUI == null ? void 0 : vertexUI.component) ? vertexUI.component({
577
- key,
578
- ...vProps,
579
- backgroundColor: VERTEX_COLOR
580
- }) : /* @__PURE__ */ jsx(
581
- "div",
582
- {
583
- ...vProps,
584
- style: { ...vProps.style, backgroundColor: VERTEX_COLOR }
585
- },
586
- key
587
- )
588
567
  )
589
- ]
590
- }
591
- )
592
- ]
593
- }
594
- ),
568
+ }
569
+ )
570
+ ]
571
+ }
572
+ )),
573
+ /* @__PURE__ */ jsxs(
574
+ "div",
575
+ {
576
+ ...effectiveIsDraggable && isSelected ? dragProps : {},
577
+ ...doubleProps,
578
+ style: {
579
+ ...innerDivBaseStyle,
580
+ outline: showOutline ? `${outlineWidth}px ${outlineStyle} ${outlineColor}` : "none",
581
+ outlineOffset: showOutline ? `${outlineOff}px` : "0px",
582
+ pointerEvents: isSelected && !isMultiSelected ? "auto" : "none",
583
+ touchAction: "none",
584
+ cursor: isSelected && effectiveIsDraggable ? "move" : "default"
585
+ },
586
+ children: [
587
+ isSelected && effectiveIsResizable && !rotationActive && resize.map(
588
+ ({ key, ...hProps }) => (resizeUI == null ? void 0 : resizeUI.component) ? resizeUI.component({
589
+ key,
590
+ ...hProps,
591
+ backgroundColor: HANDLE_COLOR
592
+ }) : /* @__PURE__ */ jsx(
593
+ "div",
594
+ {
595
+ ...hProps,
596
+ style: { ...hProps.style, backgroundColor: HANDLE_COLOR }
597
+ },
598
+ key
599
+ )
600
+ ),
601
+ isSelected && canModifyAnnotations && !isMultiSelected && !rotationActive && vertices.map(
602
+ ({ key, ...vProps }) => (vertexUI == null ? void 0 : vertexUI.component) ? vertexUI.component({
603
+ key,
604
+ ...vProps,
605
+ backgroundColor: VERTEX_COLOR
606
+ }) : /* @__PURE__ */ jsx(
607
+ "div",
608
+ {
609
+ ...vProps,
610
+ style: { ...vProps.style, backgroundColor: VERTEX_COLOR }
611
+ },
612
+ key
613
+ )
614
+ )
615
+ ]
616
+ }
617
+ )
618
+ ] }),
595
619
  selectionMenu && !isMultiSelected && !rotationActive && /* @__PURE__ */ jsx(
596
620
  CounterRotate,
597
621
  {
@@ -601,13 +625,13 @@ function AnnotationContainer({
601
625
  y: currentObject.rect.origin.y * scale
602
626
  },
603
627
  size: {
604
- width: currentObject.rect.size.width * scale,
605
- height: currentObject.rect.size.height * scale
628
+ width: currentObject.rect.size.width * visualScale,
629
+ height: currentObject.rect.size.height * visualScale
606
630
  }
607
631
  },
608
632
  rotation,
609
633
  children: (counterRotateProps) => {
610
- const effectiveAngle = ((annotationRotation + rotation * 90) % 360 + 360) % 360;
634
+ const effectiveAngle = ((annotationRotation + effectivePageRotation * 90) % 360 + 360) % 360;
611
635
  const handleNearMenuSide = effectiveIsRotatable && effectiveAngle > 90 && effectiveAngle < 270;
612
636
  return selectionMenu({
613
637
  ...counterRotateProps,
@@ -652,6 +676,57 @@ function AnnotationContainer({
652
676
  )
653
677
  ] });
654
678
  }
679
+ function mapCounterRotatePoint(x, y, width, height, rotation) {
680
+ switch (rotation) {
681
+ case 1:
682
+ return { x: y, y: height - x };
683
+ case 2:
684
+ return { x: width - x, y: height - y };
685
+ case 3:
686
+ return { x: width - y, y: x };
687
+ default:
688
+ return { x, y };
689
+ }
690
+ }
691
+ function getAnnotationScreenBounds(annotation, scale, rotation) {
692
+ const flags = annotation.object.flags ?? [];
693
+ const hasNoZoom = flags.includes("noZoom");
694
+ const hasNoRotate = flags.includes("noRotate");
695
+ const left = annotation.object.rect.origin.x * scale;
696
+ const top = annotation.object.rect.origin.y * scale;
697
+ const width = annotation.object.rect.size.width * (hasNoZoom ? 1 : scale);
698
+ const height = annotation.object.rect.size.height * (hasNoZoom ? 1 : scale);
699
+ if (!hasNoRotate || rotation === 0) {
700
+ return {
701
+ left,
702
+ top,
703
+ right: left + width,
704
+ bottom: top + height
705
+ };
706
+ }
707
+ const corners = [
708
+ mapCounterRotatePoint(0, 0, width, height, rotation),
709
+ mapCounterRotatePoint(width, 0, width, height, rotation),
710
+ mapCounterRotatePoint(0, height, width, height, rotation),
711
+ mapCounterRotatePoint(width, height, width, height, rotation)
712
+ ];
713
+ let minX = Infinity;
714
+ let minY = Infinity;
715
+ let maxX = -Infinity;
716
+ let maxY = -Infinity;
717
+ for (const corner of corners) {
718
+ if (corner.x < minX) minX = corner.x;
719
+ if (corner.y < minY) minY = corner.y;
720
+ if (corner.x > maxX) maxX = corner.x;
721
+ if (corner.y > maxY) maxY = corner.y;
722
+ }
723
+ return {
724
+ left: left + minX,
725
+ top: top + minY,
726
+ right: left + maxX,
727
+ bottom: top + maxY
728
+ };
729
+ }
655
730
  function GroupSelectionBox({
656
731
  documentId,
657
732
  pageIndex,
@@ -859,8 +934,29 @@ function GroupSelectionBox({
859
934
  if (selectedAnnotations.length < 2) {
860
935
  return null;
861
936
  }
862
- const groupBoxWidth = previewGroupBox.size.width * scale;
863
- const groupBoxHeight = previewGroupBox.size.height * scale;
937
+ let visualLeft = Infinity;
938
+ let visualTop = Infinity;
939
+ let visualRight = -Infinity;
940
+ let visualBottom = -Infinity;
941
+ for (const ta of selectedAnnotations) {
942
+ const bounds = getAnnotationScreenBounds(ta, scale, rotation);
943
+ visualLeft = Math.min(visualLeft, bounds.left);
944
+ visualTop = Math.min(visualTop, bounds.top);
945
+ visualRight = Math.max(visualRight, bounds.right);
946
+ visualBottom = Math.max(visualBottom, bounds.bottom);
947
+ }
948
+ const initialLogicalLeft = groupBox.origin.x * scale;
949
+ const initialLogicalTop = groupBox.origin.y * scale;
950
+ const initialLogicalRight = (groupBox.origin.x + groupBox.size.width) * scale;
951
+ const initialLogicalBottom = (groupBox.origin.y + groupBox.size.height) * scale;
952
+ const leftCorrection = visualLeft - initialLogicalLeft;
953
+ const topCorrection = visualTop - initialLogicalTop;
954
+ const rightCorrection = visualRight - initialLogicalRight;
955
+ const bottomCorrection = visualBottom - initialLogicalBottom;
956
+ const groupBoxLeft = previewGroupBox.origin.x * scale + leftCorrection;
957
+ const groupBoxTop = previewGroupBox.origin.y * scale + topCorrection;
958
+ const groupBoxWidth = previewGroupBox.size.width * scale + (rightCorrection - leftCorrection);
959
+ const groupBoxHeight = previewGroupBox.size.height * scale + (bottomCorrection - topCorrection);
864
960
  const groupCenterX = groupBoxWidth / 2;
865
961
  const groupCenterY = groupBoxHeight / 2;
866
962
  const groupGuideLength = Math.max(300, Math.max(groupBoxWidth, groupBoxHeight) + 80);
@@ -870,8 +966,8 @@ function GroupSelectionBox({
870
966
  {
871
967
  style: {
872
968
  position: "absolute",
873
- left: previewGroupBox.origin.x * scale,
874
- top: previewGroupBox.origin.y * scale,
969
+ left: groupBoxLeft,
970
+ top: groupBoxTop,
875
971
  width: groupBoxWidth,
876
972
  height: groupBoxHeight,
877
973
  pointerEvents: "none",
@@ -1080,17 +1176,17 @@ function GroupSelectionBox({
1080
1176
  ),
1081
1177
  document.body
1082
1178
  ),
1083
- groupSelectionMenu && /* @__PURE__ */ jsx(
1179
+ groupSelectionMenu && !rotationActive && /* @__PURE__ */ jsx(
1084
1180
  CounterRotate,
1085
1181
  {
1086
1182
  rect: {
1087
1183
  origin: {
1088
- x: previewGroupBox.origin.x * scale,
1089
- y: previewGroupBox.origin.y * scale
1184
+ x: groupBoxLeft,
1185
+ y: groupBoxTop
1090
1186
  },
1091
1187
  size: {
1092
- width: previewGroupBox.size.width * scale,
1093
- height: previewGroupBox.size.height * scale
1188
+ width: groupBoxWidth,
1189
+ height: groupBoxHeight
1094
1190
  }
1095
1191
  },
1096
1192
  rotation,
@@ -1121,6 +1217,7 @@ function createRenderer(entry) {
1121
1217
  render: (props) => entry.render(props),
1122
1218
  vertexConfig: entry.vertexConfig,
1123
1219
  zIndex: entry.zIndex,
1220
+ defaultBlendMode: entry.defaultBlendMode,
1124
1221
  containerStyle: entry.containerStyle,
1125
1222
  interactionDefaults: entry.interactionDefaults,
1126
1223
  useAppearanceStream: entry.useAppearanceStream,
@@ -1180,7 +1277,6 @@ function Ink({
1180
1277
  stroke: "transparent",
1181
1278
  strokeWidth: hitStrokeWidth,
1182
1279
  onPointerDown: onClick,
1183
- onTouchStart: onClick,
1184
1280
  style: {
1185
1281
  cursor: isSelected ? "move" : "pointer",
1186
1282
  pointerEvents: isSelected ? "none" : "visibleStroke",
@@ -1222,8 +1318,11 @@ function Square({
1222
1318
  rect,
1223
1319
  scale,
1224
1320
  onClick,
1225
- appearanceActive = false
1321
+ appearanceActive = false,
1322
+ cloudyBorderIntensity,
1323
+ rectangleDifferences
1226
1324
  }) {
1325
+ const isCloudy = (cloudyBorderIntensity ?? 0) > 0;
1227
1326
  const { width, height, x, y } = useMemo(() => {
1228
1327
  const outerW = rect.size.width;
1229
1328
  const outerH = rect.size.height;
@@ -1236,8 +1335,17 @@ function Square({
1236
1335
  y: strokeWidth / 2
1237
1336
  };
1238
1337
  }, [rect, strokeWidth]);
1239
- const svgWidth = (width + strokeWidth) * scale;
1240
- const svgHeight = (height + strokeWidth) * scale;
1338
+ const cloudyPath = useMemo(() => {
1339
+ if (!isCloudy) return null;
1340
+ return generateCloudyRectanglePath(
1341
+ { x: 0, y: 0, width: rect.size.width, height: rect.size.height },
1342
+ rectangleDifferences,
1343
+ cloudyBorderIntensity,
1344
+ strokeWidth
1345
+ );
1346
+ }, [isCloudy, rect, rectangleDifferences, cloudyBorderIntensity, strokeWidth]);
1347
+ const svgWidth = rect.size.width * scale;
1348
+ const svgHeight = rect.size.height * scale;
1241
1349
  const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$4 / scale);
1242
1350
  return /* @__PURE__ */ jsxs(
1243
1351
  "svg",
@@ -1251,10 +1359,23 @@ function Square({
1251
1359
  },
1252
1360
  width: svgWidth,
1253
1361
  height: svgHeight,
1254
- viewBox: `0 0 ${width + strokeWidth} ${height + strokeWidth}`,
1362
+ viewBox: `0 0 ${rect.size.width} ${rect.size.height}`,
1255
1363
  overflow: "visible",
1256
1364
  children: [
1257
- /* @__PURE__ */ jsx(
1365
+ isCloudy && cloudyPath ? /* @__PURE__ */ jsx(
1366
+ "path",
1367
+ {
1368
+ d: cloudyPath.path,
1369
+ fill: "transparent",
1370
+ stroke: "transparent",
1371
+ strokeWidth: hitStrokeWidth,
1372
+ onPointerDown: onClick,
1373
+ style: {
1374
+ cursor: isSelected ? "move" : "pointer",
1375
+ pointerEvents: isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible"
1376
+ }
1377
+ }
1378
+ ) : /* @__PURE__ */ jsx(
1258
1379
  "rect",
1259
1380
  {
1260
1381
  x,
@@ -1265,14 +1386,26 @@ function Square({
1265
1386
  stroke: "transparent",
1266
1387
  strokeWidth: hitStrokeWidth,
1267
1388
  onPointerDown: onClick,
1268
- onTouchStart: onClick,
1269
1389
  style: {
1270
1390
  cursor: isSelected ? "move" : "pointer",
1271
1391
  pointerEvents: isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible"
1272
1392
  }
1273
1393
  }
1274
1394
  ),
1275
- !appearanceActive && /* @__PURE__ */ jsx(
1395
+ !appearanceActive && (isCloudy && cloudyPath ? /* @__PURE__ */ jsx(
1396
+ "path",
1397
+ {
1398
+ d: cloudyPath.path,
1399
+ fill: color,
1400
+ opacity,
1401
+ style: {
1402
+ pointerEvents: "none",
1403
+ stroke: strokeColor ?? color,
1404
+ strokeWidth,
1405
+ strokeLinejoin: "round"
1406
+ }
1407
+ }
1408
+ ) : /* @__PURE__ */ jsx(
1276
1409
  "rect",
1277
1410
  {
1278
1411
  x,
@@ -1290,7 +1423,7 @@ function Square({
1290
1423
  }
1291
1424
  }
1292
1425
  }
1293
- )
1426
+ ))
1294
1427
  ]
1295
1428
  }
1296
1429
  );
@@ -1307,8 +1440,11 @@ function Circle({
1307
1440
  scale,
1308
1441
  onClick,
1309
1442
  isSelected,
1310
- appearanceActive = false
1443
+ appearanceActive = false,
1444
+ cloudyBorderIntensity,
1445
+ rectangleDifferences
1311
1446
  }) {
1447
+ const isCloudy = (cloudyBorderIntensity ?? 0) > 0;
1312
1448
  const { width, height, cx, cy, rx, ry } = useMemo(() => {
1313
1449
  const outerW = rect.size.width;
1314
1450
  const outerH = rect.size.height;
@@ -1323,6 +1459,15 @@ function Circle({
1323
1459
  ry: innerH / 2
1324
1460
  };
1325
1461
  }, [rect, strokeWidth]);
1462
+ const cloudyPath = useMemo(() => {
1463
+ if (!isCloudy) return null;
1464
+ return generateCloudyEllipsePath(
1465
+ { x: 0, y: 0, width: rect.size.width, height: rect.size.height },
1466
+ rectangleDifferences,
1467
+ cloudyBorderIntensity,
1468
+ strokeWidth
1469
+ );
1470
+ }, [isCloudy, rect, rectangleDifferences, cloudyBorderIntensity, strokeWidth]);
1326
1471
  const svgWidth = width * scale;
1327
1472
  const svgHeight = height * scale;
1328
1473
  const hitStrokeWidth = Math.max(strokeWidth, MIN_HIT_AREA_SCREEN_PX$3 / scale);
@@ -1341,7 +1486,20 @@ function Circle({
1341
1486
  viewBox: `0 0 ${width} ${height}`,
1342
1487
  overflow: "visible",
1343
1488
  children: [
1344
- /* @__PURE__ */ jsx(
1489
+ isCloudy && cloudyPath ? /* @__PURE__ */ jsx(
1490
+ "path",
1491
+ {
1492
+ d: cloudyPath.path,
1493
+ fill: "transparent",
1494
+ stroke: "transparent",
1495
+ strokeWidth: hitStrokeWidth,
1496
+ onPointerDown: onClick,
1497
+ style: {
1498
+ cursor: isSelected ? "move" : "pointer",
1499
+ pointerEvents: isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible"
1500
+ }
1501
+ }
1502
+ ) : /* @__PURE__ */ jsx(
1345
1503
  "ellipse",
1346
1504
  {
1347
1505
  cx,
@@ -1352,14 +1510,26 @@ function Circle({
1352
1510
  stroke: "transparent",
1353
1511
  strokeWidth: hitStrokeWidth,
1354
1512
  onPointerDown: onClick,
1355
- onTouchStart: onClick,
1356
1513
  style: {
1357
1514
  cursor: isSelected ? "move" : "pointer",
1358
1515
  pointerEvents: isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible"
1359
1516
  }
1360
1517
  }
1361
1518
  ),
1362
- !appearanceActive && /* @__PURE__ */ jsx(
1519
+ !appearanceActive && (isCloudy && cloudyPath ? /* @__PURE__ */ jsx(
1520
+ "path",
1521
+ {
1522
+ d: cloudyPath.path,
1523
+ fill: color,
1524
+ opacity,
1525
+ style: {
1526
+ pointerEvents: "none",
1527
+ stroke: strokeColor ?? color,
1528
+ strokeWidth,
1529
+ strokeLinejoin: "round"
1530
+ }
1531
+ }
1532
+ ) : /* @__PURE__ */ jsx(
1363
1533
  "ellipse",
1364
1534
  {
1365
1535
  cx,
@@ -1377,7 +1547,7 @@ function Circle({
1377
1547
  }
1378
1548
  }
1379
1549
  }
1380
- )
1550
+ ))
1381
1551
  ]
1382
1552
  }
1383
1553
  );
@@ -1441,7 +1611,6 @@ function Line({
1441
1611
  stroke: "transparent",
1442
1612
  strokeWidth: hitStrokeWidth,
1443
1613
  onPointerDown: onClick,
1444
- onTouchStart: onClick,
1445
1614
  style: {
1446
1615
  cursor: isSelected ? "move" : "pointer",
1447
1616
  pointerEvents: isSelected ? "none" : "visibleStroke",
@@ -1458,7 +1627,6 @@ function Line({
1458
1627
  stroke: "transparent",
1459
1628
  strokeWidth: hitStrokeWidth,
1460
1629
  onPointerDown: onClick,
1461
- onTouchStart: onClick,
1462
1630
  style: {
1463
1631
  cursor: isSelected ? "move" : "pointer",
1464
1632
  pointerEvents: isSelected ? "none" : endings.start.filled ? "visible" : "visibleStroke",
@@ -1475,7 +1643,6 @@ function Line({
1475
1643
  stroke: "transparent",
1476
1644
  strokeWidth: hitStrokeWidth,
1477
1645
  onPointerDown: onClick,
1478
- onTouchStart: onClick,
1479
1646
  style: {
1480
1647
  cursor: isSelected ? "move" : "pointer",
1481
1648
  pointerEvents: isSelected ? "none" : endings.end.filled ? "visible" : "visibleStroke",
@@ -1550,6 +1717,8 @@ function Polyline({
1550
1717
  strokeColor = "#000000",
1551
1718
  opacity = 1,
1552
1719
  strokeWidth,
1720
+ strokeStyle = PdfAnnotationBorderStyle.SOLID,
1721
+ strokeDashArray,
1553
1722
  scale,
1554
1723
  isSelected,
1555
1724
  onClick,
@@ -1612,7 +1781,6 @@ function Polyline({
1612
1781
  stroke: "transparent",
1613
1782
  strokeWidth: hitStrokeWidth,
1614
1783
  onPointerDown: onClick,
1615
- onTouchStart: onClick,
1616
1784
  style: {
1617
1785
  cursor: isSelected ? "move" : "pointer",
1618
1786
  pointerEvents: isSelected ? "none" : "visibleStroke",
@@ -1630,7 +1798,6 @@ function Polyline({
1630
1798
  stroke: "transparent",
1631
1799
  strokeWidth: hitStrokeWidth,
1632
1800
  onPointerDown: onClick,
1633
- onTouchStart: onClick,
1634
1801
  style: {
1635
1802
  cursor: isSelected ? "move" : "pointer",
1636
1803
  pointerEvents: isSelected ? "none" : endings.start.filled ? "visible" : "visibleStroke",
@@ -1647,7 +1814,6 @@ function Polyline({
1647
1814
  stroke: "transparent",
1648
1815
  strokeWidth: hitStrokeWidth,
1649
1816
  onPointerDown: onClick,
1650
- onTouchStart: onClick,
1651
1817
  style: {
1652
1818
  cursor: isSelected ? "move" : "pointer",
1653
1819
  pointerEvents: isSelected ? "none" : endings.end.filled ? "visible" : "visibleStroke",
@@ -1667,7 +1833,10 @@ function Polyline({
1667
1833
  strokeWidth,
1668
1834
  pointerEvents: "none",
1669
1835
  strokeLinecap: "butt",
1670
- strokeLinejoin: "miter"
1836
+ strokeLinejoin: "miter",
1837
+ ...strokeStyle === PdfAnnotationBorderStyle.DASHED && {
1838
+ strokeDasharray: strokeDashArray == null ? void 0 : strokeDashArray.join(",")
1839
+ }
1671
1840
  }
1672
1841
  }
1673
1842
  ),
@@ -1681,7 +1850,10 @@ function Polyline({
1681
1850
  style: {
1682
1851
  pointerEvents: "none",
1683
1852
  strokeWidth,
1684
- strokeLinecap: "butt"
1853
+ strokeLinecap: "butt",
1854
+ ...strokeStyle === PdfAnnotationBorderStyle.DASHED && {
1855
+ strokeDasharray: strokeDashArray == null ? void 0 : strokeDashArray.join(",")
1856
+ }
1685
1857
  }
1686
1858
  }
1687
1859
  ),
@@ -1695,7 +1867,10 @@ function Polyline({
1695
1867
  style: {
1696
1868
  pointerEvents: "none",
1697
1869
  strokeWidth,
1698
- strokeLinecap: "butt"
1870
+ strokeLinecap: "butt",
1871
+ ...strokeStyle === PdfAnnotationBorderStyle.DASHED && {
1872
+ strokeDasharray: strokeDashArray == null ? void 0 : strokeDashArray.join(",")
1873
+ }
1699
1874
  }
1700
1875
  }
1701
1876
  )
@@ -1719,8 +1894,10 @@ function Polygon({
1719
1894
  onClick,
1720
1895
  currentVertex,
1721
1896
  handleSize = 14,
1722
- appearanceActive = false
1897
+ appearanceActive = false,
1898
+ cloudyBorderIntensity
1723
1899
  }) {
1900
+ const isCloudy = (cloudyBorderIntensity ?? 0) > 0;
1724
1901
  const allPoints = currentVertex ? [...vertices, currentVertex] : vertices;
1725
1902
  const localPts = useMemo(
1726
1903
  () => allPoints.map(({ x, y }) => ({ x: x - rect.origin.x, y: y - rect.origin.y })),
@@ -1732,6 +1909,10 @@ function Polygon({
1732
1909
  const isPreview = !!currentVertex;
1733
1910
  return (`M ${first.x} ${first.y} ` + rest.map((p) => `L ${p.x} ${p.y}`).join(" ") + (isPreview ? "" : " Z")).trim();
1734
1911
  }, [localPts, currentVertex]);
1912
+ const cloudyPath = useMemo(() => {
1913
+ if (!isCloudy || allPoints.length < 3) return null;
1914
+ return generateCloudyPolygonPath(allPoints, rect.origin, cloudyBorderIntensity, strokeWidth);
1915
+ }, [isCloudy, allPoints, rect.origin, cloudyBorderIntensity, strokeWidth]);
1735
1916
  const isPreviewing = currentVertex && vertices.length > 0;
1736
1917
  const width = rect.size.width * scale;
1737
1918
  const height = rect.size.height * scale;
@@ -1754,12 +1935,11 @@ function Polygon({
1754
1935
  /* @__PURE__ */ jsx(
1755
1936
  "path",
1756
1937
  {
1757
- d: pathData,
1938
+ d: isCloudy && cloudyPath ? cloudyPath.path : pathData,
1758
1939
  fill: "transparent",
1759
1940
  stroke: "transparent",
1760
1941
  strokeWidth: hitStrokeWidth,
1761
1942
  onPointerDown: onClick,
1762
- onTouchStart: onClick,
1763
1943
  style: {
1764
1944
  cursor: isSelected ? "move" : "pointer",
1765
1945
  pointerEvents: isSelected ? "none" : color === "transparent" ? "visibleStroke" : "visible",
@@ -1768,7 +1948,20 @@ function Polygon({
1768
1948
  }
1769
1949
  }
1770
1950
  ),
1771
- !appearanceActive && /* @__PURE__ */ jsxs(Fragment, { children: [
1951
+ !appearanceActive && /* @__PURE__ */ jsx(Fragment, { children: isCloudy && cloudyPath ? /* @__PURE__ */ jsx(
1952
+ "path",
1953
+ {
1954
+ d: cloudyPath.path,
1955
+ opacity,
1956
+ style: {
1957
+ fill: color,
1958
+ stroke: strokeColor ?? color,
1959
+ strokeWidth,
1960
+ pointerEvents: "none",
1961
+ strokeLinejoin: "round"
1962
+ }
1963
+ }
1964
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
1772
1965
  /* @__PURE__ */ jsx(
1773
1966
  "path",
1774
1967
  {
@@ -1815,11 +2008,62 @@ function Polygon({
1815
2008
  style: { pointerEvents: "none" }
1816
2009
  }
1817
2010
  )
1818
- ] })
2011
+ ] }) })
1819
2012
  ]
1820
2013
  }
1821
2014
  );
1822
2015
  }
2016
+ function Text({
2017
+ isSelected,
2018
+ color = "#facc15",
2019
+ opacity = 1,
2020
+ onClick,
2021
+ appearanceActive = false
2022
+ }) {
2023
+ const lineColor = getContrastStrokeColor(color);
2024
+ return /* @__PURE__ */ jsx(
2025
+ "div",
2026
+ {
2027
+ style: {
2028
+ position: "absolute",
2029
+ inset: 0,
2030
+ zIndex: 2,
2031
+ pointerEvents: isSelected ? "none" : "auto",
2032
+ cursor: isSelected ? "move" : "pointer"
2033
+ },
2034
+ onPointerDown: onClick,
2035
+ children: !appearanceActive && /* @__PURE__ */ jsxs(
2036
+ "svg",
2037
+ {
2038
+ style: {
2039
+ position: "absolute",
2040
+ inset: 0,
2041
+ pointerEvents: "none"
2042
+ },
2043
+ viewBox: "0 0 20 20",
2044
+ width: "100%",
2045
+ height: "100%",
2046
+ children: [
2047
+ /* @__PURE__ */ jsx(
2048
+ "path",
2049
+ {
2050
+ d: "M 0.5 15.5 L 0.5 0.5 L 19.5 0.5 L 19.5 15.5 L 8.5 15.5 L 6.5 19.5 L 4.5 15.5 Z",
2051
+ fill: color,
2052
+ opacity,
2053
+ stroke: lineColor,
2054
+ strokeWidth: "1",
2055
+ strokeLinejoin: "miter"
2056
+ }
2057
+ ),
2058
+ /* @__PURE__ */ jsx("line", { x1: "2.5", y1: "4.25", x2: "17.5", y2: "4.25", stroke: lineColor, strokeWidth: "1" }),
2059
+ /* @__PURE__ */ jsx("line", { x1: "2.5", y1: "8", x2: "17.5", y2: "8", stroke: lineColor, strokeWidth: "1" }),
2060
+ /* @__PURE__ */ jsx("line", { x1: "2.5", y1: "11.75", x2: "17.5", y2: "11.75", stroke: lineColor, strokeWidth: "1" })
2061
+ ]
2062
+ }
2063
+ )
2064
+ }
2065
+ );
2066
+ }
1823
2067
  function FreeText({
1824
2068
  documentId,
1825
2069
  isSelected,
@@ -1887,7 +2131,6 @@ function FreeText({
1887
2131
  opacity: appearanceActive ? 0 : 1
1888
2132
  },
1889
2133
  onPointerDown: onClick,
1890
- onTouchStart: onClick,
1891
2134
  children: /* @__PURE__ */ jsx(
1892
2135
  "span",
1893
2136
  {
@@ -2014,7 +2257,6 @@ function Stamp({
2014
2257
  cursor: "pointer"
2015
2258
  },
2016
2259
  onPointerDown: onClick,
2017
- onTouchStart: onClick,
2018
2260
  children: /* @__PURE__ */ jsx(
2019
2261
  RenderAnnotation,
2020
2262
  {
@@ -2077,7 +2319,6 @@ function Link({
2077
2319
  height,
2078
2320
  fill: "transparent",
2079
2321
  onPointerDown: hasIRT ? void 0 : onClick,
2080
- onTouchStart: hasIRT ? void 0 : onClick,
2081
2322
  style: {
2082
2323
  cursor: hasIRT ? "default" : isSelected ? "move" : "pointer",
2083
2324
  pointerEvents: hasIRT ? "none" : isSelected ? "none" : "visible"
@@ -2139,7 +2380,6 @@ function Highlight({
2139
2380
  "div",
2140
2381
  {
2141
2382
  onPointerDown: onClick,
2142
- onTouchStart: onClick,
2143
2383
  style: {
2144
2384
  position: "absolute",
2145
2385
  left: (rect ? b.origin.x - rect.origin.x : b.origin.x) * scale,
@@ -2173,7 +2413,6 @@ function Underline({
2173
2413
  "div",
2174
2414
  {
2175
2415
  onPointerDown: onClick,
2176
- onTouchStart: onClick,
2177
2416
  style: {
2178
2417
  position: "absolute",
2179
2418
  left: (rect ? r.origin.x - rect.origin.x : r.origin.x) * scale,
@@ -2221,7 +2460,6 @@ function Strikeout({
2221
2460
  "div",
2222
2461
  {
2223
2462
  onPointerDown: onClick,
2224
- onTouchStart: onClick,
2225
2463
  style: {
2226
2464
  position: "absolute",
2227
2465
  left: (rect ? r.origin.x - rect.origin.x : r.origin.x) * scale,
@@ -2276,7 +2514,6 @@ function Squiggly({
2276
2514
  "div",
2277
2515
  {
2278
2516
  onPointerDown: onClick,
2279
- onTouchStart: onClick,
2280
2517
  style: {
2281
2518
  position: "absolute",
2282
2519
  left: (rect ? r.origin.x - rect.origin.x : r.origin.x) * scale,
@@ -2310,6 +2547,74 @@ function Squiggly({
2310
2547
  i
2311
2548
  )) });
2312
2549
  }
2550
+ function Caret({
2551
+ isSelected,
2552
+ strokeColor = "#000000",
2553
+ opacity = 1,
2554
+ rect,
2555
+ scale,
2556
+ onClick,
2557
+ appearanceActive = false
2558
+ }) {
2559
+ const { width, height, path } = useMemo(() => {
2560
+ const w = rect.size.width;
2561
+ const h = rect.size.height;
2562
+ const midX = w / 2;
2563
+ const d = [
2564
+ `M 0 ${h}`,
2565
+ `C ${w * 0.27} ${h} ${midX} ${h - h * 0.44} ${midX} 0`,
2566
+ `C ${midX} ${h - h * 0.44} ${w - w * 0.27} ${h} ${w} ${h}`,
2567
+ "Z"
2568
+ ].join(" ");
2569
+ return { width: w, height: h, path: d };
2570
+ }, [rect]);
2571
+ const svgWidth = width * scale;
2572
+ const svgHeight = height * scale;
2573
+ return /* @__PURE__ */ jsxs(
2574
+ "svg",
2575
+ {
2576
+ style: {
2577
+ position: "absolute",
2578
+ width: svgWidth,
2579
+ height: svgHeight,
2580
+ pointerEvents: "none",
2581
+ zIndex: 2
2582
+ },
2583
+ width: svgWidth,
2584
+ height: svgHeight,
2585
+ viewBox: `0 0 ${width} ${height}`,
2586
+ overflow: "visible",
2587
+ children: [
2588
+ /* @__PURE__ */ jsx(
2589
+ "path",
2590
+ {
2591
+ d: path,
2592
+ fill: "transparent",
2593
+ stroke: "transparent",
2594
+ strokeWidth: 4,
2595
+ onPointerDown: onClick,
2596
+ style: {
2597
+ cursor: isSelected ? "move" : "pointer",
2598
+ pointerEvents: isSelected ? "none" : "visible"
2599
+ }
2600
+ }
2601
+ ),
2602
+ !appearanceActive && /* @__PURE__ */ jsx(
2603
+ "path",
2604
+ {
2605
+ d: path,
2606
+ fill: strokeColor,
2607
+ stroke: strokeColor,
2608
+ strokeWidth: 0.5,
2609
+ opacity,
2610
+ fillRule: "evenodd",
2611
+ style: { pointerEvents: "none" }
2612
+ }
2613
+ )
2614
+ ]
2615
+ }
2616
+ );
2617
+ }
2313
2618
  const builtInRenderers = [
2314
2619
  // --- Drawing ---
2315
2620
  createRenderer({
@@ -2434,9 +2739,7 @@ const builtInRenderers = [
2434
2739
  ),
2435
2740
  zIndex: 0,
2436
2741
  interactionDefaults: { isDraggable: false, isResizable: false, isRotatable: false },
2437
- containerStyle: (a) => ({
2438
- mixBlendMode: blendModeToCss(a.blendMode ?? PdfBlendMode.Multiply)
2439
- })
2742
+ defaultBlendMode: PdfBlendMode.Multiply
2440
2743
  }),
2441
2744
  createRenderer({
2442
2745
  id: "underline",
@@ -2483,6 +2786,38 @@ const builtInRenderers = [
2483
2786
  zIndex: 0,
2484
2787
  interactionDefaults: { isDraggable: false, isResizable: false, isRotatable: false }
2485
2788
  }),
2789
+ // --- Text Comment ---
2790
+ createRenderer({
2791
+ id: "text",
2792
+ matches: (a) => a.type === PdfAnnotationSubtype.TEXT && !a.inReplyToId,
2793
+ render: ({ currentObject, isSelected, onClick, appearanceActive }) => /* @__PURE__ */ jsx(
2794
+ Text,
2795
+ {
2796
+ isSelected,
2797
+ color: currentObject.strokeColor ?? currentObject.color,
2798
+ opacity: currentObject.opacity,
2799
+ onClick,
2800
+ appearanceActive
2801
+ }
2802
+ ),
2803
+ interactionDefaults: { isDraggable: true, isResizable: false, isRotatable: false }
2804
+ }),
2805
+ // --- Caret ---
2806
+ createRenderer({
2807
+ id: "caret",
2808
+ matches: (a) => a.type === PdfAnnotationSubtype.CARET,
2809
+ render: ({ currentObject, isSelected, scale, onClick, appearanceActive }) => /* @__PURE__ */ jsx(
2810
+ Caret,
2811
+ {
2812
+ ...currentObject,
2813
+ isSelected,
2814
+ scale,
2815
+ onClick,
2816
+ appearanceActive
2817
+ }
2818
+ ),
2819
+ interactionDefaults: { isDraggable: false, isResizable: false, isRotatable: false }
2820
+ }),
2486
2821
  // --- FreeText ---
2487
2822
  createRenderer({
2488
2823
  id: "freeText",
@@ -2797,9 +3132,10 @@ function Annotations(annotationsProps) {
2797
3132
  renderer.onDoubleClick(annotation.object.id, setEditingId);
2798
3133
  } : void 0,
2799
3134
  zIndex: renderer.zIndex,
2800
- style: ((_c = renderer.containerStyle) == null ? void 0 : _c.call(renderer, annotation.object)) ?? {
2801
- mixBlendMode: blendModeToCss(annotation.object.blendMode ?? PdfBlendMode.Normal)
2802
- },
3135
+ blendMode: blendModeToCss(
3136
+ annotation.object.blendMode ?? renderer.defaultBlendMode ?? PdfBlendMode.Normal
3137
+ ),
3138
+ style: (_c = renderer.containerStyle) == null ? void 0 : _c.call(renderer, annotation.object),
2803
3139
  appearance: useAP ? getAppearanceForAnnotation(annotation) : void 0,
2804
3140
  ...annotationsProps,
2805
3141
  children: (currentObject, { appearanceActive }) => renderer.render({
@@ -2946,6 +3282,8 @@ function TextMarkup({ documentId, pageIndex, scale }) {
2946
3282
  )
2947
3283
  }
2948
3284
  );
3285
+ case PdfAnnotationSubtype.CARET:
3286
+ return null;
2949
3287
  default:
2950
3288
  return null;
2951
3289
  }
@@ -2977,7 +3315,16 @@ function PreviewRenderer({ preview, scale }) {
2977
3315
  return /* @__PURE__ */ jsx("div", { style, children: /* @__PURE__ */ jsx(Line, { isSelected: false, scale, ...preview.data }) });
2978
3316
  }
2979
3317
  if (preview.type === PdfAnnotationSubtype.INK) {
2980
- return /* @__PURE__ */ jsx("div", { style, children: /* @__PURE__ */ jsx(Ink, { isSelected: false, scale, ...preview.data }) });
3318
+ return /* @__PURE__ */ jsx(
3319
+ "div",
3320
+ {
3321
+ style: {
3322
+ ...style,
3323
+ mixBlendMode: blendModeToCss(preview.data.blendMode ?? PdfBlendMode.Normal)
3324
+ },
3325
+ children: /* @__PURE__ */ jsx(Ink, { isSelected: false, scale, ...preview.data })
3326
+ }
3327
+ );
2981
3328
  }
2982
3329
  if (preview.type === PdfAnnotationSubtype.FREETEXT) {
2983
3330
  return /* @__PURE__ */ jsx("div", { style, children: /* @__PURE__ */ jsx(