@plait/core 0.75.0-next.9 → 0.76.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.
@@ -892,7 +892,7 @@ function getNearestPointBetweenPointAndSegment(point, linePoints) {
892
892
  }
893
893
  return [xx, yy];
894
894
  }
895
- function distanceBetweenPointAndSegments(points, point) {
895
+ function distanceBetweenPointAndSegments(point, points) {
896
896
  const len = points.length;
897
897
  let distance = Infinity;
898
898
  if (points.length === 1) {
@@ -925,6 +925,19 @@ function getNearestPointBetweenPointAndSegments(point, points, isClose = true) {
925
925
  }
926
926
  return result;
927
927
  }
928
+ function getNearestPointBetweenPointAndDiscreteSegments(point, segments) {
929
+ let minDistance = Infinity;
930
+ let nearestPoint = point;
931
+ for (const segment of segments) {
932
+ const currentNearestPoint = getNearestPointBetweenPointAndSegment(point, segment);
933
+ const currentDistance = distanceBetweenPointAndPoint(point[0], point[1], currentNearestPoint[0], currentNearestPoint[1]);
934
+ if (currentDistance < minDistance) {
935
+ minDistance = currentDistance;
936
+ nearestPoint = currentNearestPoint;
937
+ }
938
+ }
939
+ return nearestPoint;
940
+ }
928
941
  function getNearestPointBetweenPointAndEllipse(point, center, rx, ry) {
929
942
  const rectangleClient = {
930
943
  x: center[0] - rx,
@@ -997,10 +1010,10 @@ const isLineHitRectangle = (points, rectangle) => {
997
1010
  const rectanglePoints = RectangleClient.getCornerPoints(rectangle);
998
1011
  const len = points.length;
999
1012
  for (let i = 0; i < len; i++) {
1000
- if (i === len - 1)
1001
- continue;
1002
1013
  const p1 = points[i];
1003
1014
  const p2 = points[(i + 1) % len];
1015
+ if (i === len - 1 && Point.isEquals(p1, p2))
1016
+ continue;
1004
1017
  const isHit = isSingleLineHitRectangleEdge(p1, p2, rectangle);
1005
1018
  if (isHit || isPointInPolygon(p1, rectanglePoints) || isPointInPolygon(p2, rectanglePoints)) {
1006
1019
  return true;
@@ -1229,64 +1242,61 @@ function getPointBetween(x0, y0, x1, y1, d = 0.5) {
1229
1242
  * 获取点到半椭圆弧段的最近点
1230
1243
  * @param point 目标点
1231
1244
  * @param startPoint 弧段起点
1232
- * @param arcPoint 弧段数据
1245
+ * @param arcCommand SVG 弧形命令参数
1233
1246
  */
1234
1247
  /**
1235
1248
  * 计算椭圆弧的中心点和实际半径
1236
1249
  */
1237
- function getEllipseArcCenter(startPoint, arcPoint) {
1250
+ function getEllipseArcCenter(startPoint, arcCommand) {
1238
1251
  // 1. 将坐标转换到标准位置
1239
- const dx = (arcPoint.endX - startPoint[0]) / 2;
1240
- const dy = (arcPoint.endY - startPoint[1]) / 2;
1241
- const cosAngle = Math.cos(arcPoint.xAxisRotation);
1242
- const sinAngle = Math.sin(arcPoint.xAxisRotation);
1252
+ const dx = (arcCommand.endX - startPoint[0]) / 2;
1253
+ const dy = (arcCommand.endY - startPoint[1]) / 2;
1254
+ const cosAngle = Math.cos(arcCommand.xAxisRotation);
1255
+ const sinAngle = Math.sin(arcCommand.xAxisRotation);
1243
1256
  // 旋转到椭圆坐标系
1244
1257
  const x1 = cosAngle * dx + sinAngle * dy;
1245
1258
  const y1 = -sinAngle * dx + cosAngle * dy;
1246
1259
  // 2. 计算中心点
1247
- const rx = Math.abs(arcPoint.rx);
1248
- const ry = Math.abs(arcPoint.ry);
1260
+ const rx = Math.abs(arcCommand.rx);
1261
+ const ry = Math.abs(arcCommand.ry);
1249
1262
  // 确保半径足够大
1250
1263
  const lambda = (x1 * x1) / (rx * rx) + (y1 * y1) / (ry * ry);
1251
1264
  const factor = lambda > 1 ? Math.sqrt(lambda) : 1;
1252
1265
  const adjustedRx = rx * factor;
1253
1266
  const adjustedRy = ry * factor;
1254
1267
  // 计算中心点坐标
1255
- const sign = arcPoint.largeArcFlag === arcPoint.sweepFlag ? -1 : 1;
1256
- const sq = ((adjustedRx * adjustedRx * adjustedRy * adjustedRy) -
1257
- (adjustedRx * adjustedRx * y1 * y1) -
1258
- (adjustedRy * adjustedRy * x1 * x1)) /
1259
- ((adjustedRx * adjustedRx * y1 * y1) +
1260
- (adjustedRy * adjustedRy * x1 * x1));
1268
+ const sign = arcCommand.largeArcFlag === arcCommand.sweepFlag ? -1 : 1;
1269
+ const sq = (adjustedRx * adjustedRx * adjustedRy * adjustedRy - adjustedRx * adjustedRx * y1 * y1 - adjustedRy * adjustedRy * x1 * x1) /
1270
+ (adjustedRx * adjustedRx * y1 * y1 + adjustedRy * adjustedRy * x1 * x1);
1261
1271
  const coef = sign * Math.sqrt(Math.max(0, sq));
1262
1272
  const centerX = coef * ((adjustedRx * y1) / adjustedRy);
1263
1273
  const centerY = coef * (-(adjustedRy * x1) / adjustedRx);
1264
1274
  // 3. 转换回原始坐标系
1265
- const cx = cosAngle * centerX - sinAngle * centerY + (startPoint[0] + arcPoint.endX) / 2;
1266
- const cy = sinAngle * centerX + cosAngle * centerY + (startPoint[1] + arcPoint.endY) / 2;
1275
+ const cx = cosAngle * centerX - sinAngle * centerY + (startPoint[0] + arcCommand.endX) / 2;
1276
+ const cy = sinAngle * centerX + cosAngle * centerY + (startPoint[1] + arcCommand.endY) / 2;
1267
1277
  return {
1268
1278
  center: [cx, cy],
1269
1279
  rx: adjustedRx,
1270
1280
  ry: adjustedRy
1271
1281
  };
1272
1282
  }
1273
- function getNearestPointBetweenPointAndArc(point, startPoint, arcPoint) {
1274
- const { center, rx, ry } = getEllipseArcCenter(startPoint, arcPoint);
1283
+ function getNearestPointBetweenPointAndArc(point, startPoint, arcCommand) {
1284
+ const { center, rx, ry } = getEllipseArcCenter(startPoint, arcCommand);
1275
1285
  // 获取椭圆上的最近点
1276
1286
  const nearestPoint = getNearestPointBetweenPointAndEllipse(point, center, rx, ry);
1277
1287
  // 判断最近点是否在弧段上
1278
1288
  const startAngle = Math.atan2(startPoint[1] - center[1], startPoint[0] - center[0]);
1279
- const endAngle = Math.atan2(arcPoint.endY - center[1], arcPoint.endX - center[0]);
1289
+ const endAngle = Math.atan2(arcCommand.endY - center[1], arcCommand.endX - center[0]);
1280
1290
  const pointAngle = Math.atan2(nearestPoint[1] - center[1], nearestPoint[0] - center[0]);
1281
1291
  // 检查点是否在弧段范围内
1282
- const isInArc = isAngleBetween(pointAngle, startAngle, endAngle, arcPoint.sweepFlag === 1);
1292
+ const isInArc = isAngleBetween(pointAngle, startAngle, endAngle, arcCommand.sweepFlag === 1);
1283
1293
  if (isInArc) {
1284
1294
  return nearestPoint;
1285
1295
  }
1286
1296
  // 如果不在弧段上,返回最近的端点
1287
1297
  const distanceToStart = distanceBetweenPointAndPoint(point[0], point[1], startPoint[0], startPoint[1]);
1288
- const distanceToEnd = distanceBetweenPointAndPoint(point[0], point[1], arcPoint.endX, arcPoint.endY);
1289
- return distanceToStart < distanceToEnd ? startPoint : [arcPoint.endX, arcPoint.endY];
1298
+ const distanceToEnd = distanceBetweenPointAndPoint(point[0], point[1], arcCommand.endX, arcCommand.endY);
1299
+ return distanceToStart < distanceToEnd ? startPoint : [arcCommand.endX, arcCommand.endY];
1290
1300
  }
1291
1301
  function isAngleBetween(angle, start, end, clockwise) {
1292
1302
  // 标准化角度到 [0, 2π]
@@ -1295,10 +1305,10 @@ function isAngleBetween(angle, start, end, clockwise) {
1295
1305
  const s = normalize(start);
1296
1306
  const e = normalize(end);
1297
1307
  if (clockwise) {
1298
- return s <= e ? (a >= s && a <= e) : (a >= s || a <= e);
1308
+ return s <= e ? a >= s && a <= e : a >= s || a <= e;
1299
1309
  }
1300
1310
  else {
1301
- return s >= e ? (a <= s && a >= e) : (a <= s || a >= e);
1311
+ return s >= e ? a <= s && a >= e : a <= s || a >= e;
1302
1312
  }
1303
1313
  }
1304
1314
 
@@ -1388,6 +1398,9 @@ const isSecondaryPointer = (event) => {
1388
1398
  const isMainPointer = (event) => {
1389
1399
  return event.button === POINTER_BUTTON.MAIN;
1390
1400
  };
1401
+ const isWheelPointer = (event) => {
1402
+ return event.button === POINTER_BUTTON.WHEEL;
1403
+ };
1391
1404
 
1392
1405
  function createForeignObject(x, y, width, height) {
1393
1406
  var newForeignObject = document.createElementNS(NS, 'foreignObject');
@@ -1427,6 +1440,7 @@ const IS_EDGE_LEGACY = typeof navigator !== 'undefined' && /Edge?\/(?:[0-6][0-9]
1427
1440
  const IS_CHROME = typeof navigator !== 'undefined' && /Chrome/i.test(navigator.userAgent);
1428
1441
  // Native beforeInput events don't work well with react on Chrome 75 and older, Chrome 76+ can use beforeInput
1429
1442
  const IS_CHROME_LEGACY = typeof navigator !== 'undefined' && /Chrome?\/(?:[0-7][0-5]|[0-6][0-9])/i.test(navigator.userAgent);
1443
+ const IS_WINDOWS = typeof navigator !== 'undefined' && /Windows/.test(navigator.userAgent);
1430
1444
 
1431
1445
  // Credits to slate - https://github.com/ianstormtaylor/slate
1432
1446
  /**
@@ -1742,7 +1756,7 @@ class DebugGenerator {
1742
1756
  }
1743
1757
  const gArray = getTemporaryGArray(this.debugKey);
1744
1758
  setTemporaryGArray(this.debugKey, []);
1745
- gArray.forEach(g => g.remove());
1759
+ gArray.forEach((g) => g.remove());
1746
1760
  }
1747
1761
  drawPolygon(board, points, options) {
1748
1762
  if (!isDebug(this.debugKey)) {
@@ -1750,7 +1764,7 @@ class DebugGenerator {
1750
1764
  }
1751
1765
  const polygonG = PlaitBoard.getRoughSVG(board).polygon(points, options || { stroke: 'red' });
1752
1766
  polygonG.classList.add(this.debugKey);
1753
- PlaitBoard.getElementActiveHost(board).append(polygonG);
1767
+ PlaitBoard.getElementTopHost(board).append(polygonG);
1754
1768
  const gArray = getTemporaryGArray(this.debugKey);
1755
1769
  gArray.push(polygonG);
1756
1770
  setTemporaryGArray(this.debugKey, gArray);
@@ -1762,7 +1776,7 @@ class DebugGenerator {
1762
1776
  }
1763
1777
  const lineG = PlaitBoard.getRoughSVG(board).linearPath(points, options || { stroke: 'red' });
1764
1778
  lineG.classList.add(this.debugKey);
1765
- PlaitBoard.getElementActiveHost(board).append(lineG);
1779
+ PlaitBoard.getElementTopHost(board).append(lineG);
1766
1780
  const gArray = getTemporaryGArray(this.debugKey);
1767
1781
  gArray.push(lineG);
1768
1782
  setTemporaryGArray(this.debugKey, gArray);
@@ -1781,7 +1795,7 @@ class DebugGenerator {
1781
1795
  }
1782
1796
  const rectangleG = PlaitBoard.getRoughSVG(board).rectangle(rectangle.x, rectangle.y, rectangle.width, rectangle.height, options || { stroke: 'red' });
1783
1797
  rectangleG.classList.add(this.debugKey);
1784
- PlaitBoard.getElementActiveHost(board).append(rectangleG);
1798
+ PlaitBoard.getElementTopHost(board).append(rectangleG);
1785
1799
  const gArray = getTemporaryGArray(this.debugKey);
1786
1800
  gArray.push(rectangleG);
1787
1801
  setTemporaryGArray(this.debugKey, gArray);
@@ -1795,7 +1809,7 @@ class DebugGenerator {
1795
1809
  points.forEach((p, i) => {
1796
1810
  const circle = PlaitBoard.getRoughSVG(board).circle(p[0], p[1], isCumulativeDiameter ? diameter * (i + 1) : diameter, Object.assign({}, { stroke: 'red', fill: 'red', fillStyle: 'solid' }, options || {}));
1797
1811
  circle.classList.add(this.debugKey);
1798
- PlaitBoard.getElementActiveHost(board).append(circle);
1812
+ PlaitBoard.getElementTopHost(board).append(circle);
1799
1813
  const gArray = getTemporaryGArray(this.debugKey);
1800
1814
  gArray.push(circle);
1801
1815
  result.push(circle);
@@ -2215,6 +2229,30 @@ function toHostPoint(board, x, y) {
2215
2229
  const rect = host.getBoundingClientRect();
2216
2230
  return [x - rect.x, y - rect.y];
2217
2231
  }
2232
+ function toActiveRectangleFromViewBoxRectangle(board, rectangle) {
2233
+ const leftTop = [rectangle.x, rectangle.y];
2234
+ const rightBottom = [rectangle.x + rectangle.width, rectangle.y + rectangle.height];
2235
+ const leftTopOfActive = toActivePointFromViewBoxPoint(board, leftTop);
2236
+ const rightBottomOfActive = toActivePointFromViewBoxPoint(board, rightBottom);
2237
+ return RectangleClient.getRectangleByPoints([leftTopOfActive, rightBottomOfActive]);
2238
+ }
2239
+ function toActivePointFromViewBoxPoint(board, point) {
2240
+ const screenPoint = toScreenPointFromHostPoint(board, toHostPointFromViewBoxPoint(board, point));
2241
+ return toActivePoint(board, screenPoint[0], screenPoint[1]);
2242
+ }
2243
+ /**
2244
+ * Get the screen point starting from the upper left corner of the svg element (based on the svg screen coordinate system)
2245
+ */
2246
+ function toActivePoint(board, x, y) {
2247
+ const boardContainer = PlaitBoard.getBoardContainer(board);
2248
+ const rect = boardContainer.getBoundingClientRect();
2249
+ return [x - rect.x, y - rect.y];
2250
+ }
2251
+ function toScreenPointFromActivePoint(board, activePoint) {
2252
+ const boardContainer = PlaitBoard.getBoardContainer(board);
2253
+ const rect = boardContainer.getBoundingClientRect();
2254
+ return [rect.x + activePoint[0], rect.y + activePoint[1]];
2255
+ }
2218
2256
  /**
2219
2257
  * Get the point in the coordinate system of the svg viewBox
2220
2258
  */
@@ -2227,7 +2265,7 @@ function toViewBoxPoint(board, hostPoint) {
2227
2265
  return newPoint;
2228
2266
  }
2229
2267
  function toViewBoxPoints(board, hostPoints) {
2230
- const newPoints = hostPoints.map(point => {
2268
+ const newPoints = hostPoints.map((point) => {
2231
2269
  return toViewBoxPoint(board, point);
2232
2270
  });
2233
2271
  return newPoints;
@@ -3016,7 +3054,7 @@ function isHandleSelection(board) {
3016
3054
  return board.pointer !== PlaitPointerType.hand && !options.isDisabledSelection && !PlaitBoard.isReadonly(board);
3017
3055
  }
3018
3056
  function hasSetSelectionOperation(board) {
3019
- return !!board.operations.find(op => PlaitOperation.isSetSelectionOperation(op));
3057
+ return !!board.operations.find((op) => PlaitOperation.isSetSelectionOperation(op));
3020
3058
  }
3021
3059
  function getTemporaryElements(board) {
3022
3060
  const ref = BOARD_TO_TEMPORARY_ELEMENTS.get(board);
@@ -3036,8 +3074,9 @@ function deleteTemporaryElements(board) {
3036
3074
  function drawSelectionRectangleG(board) {
3037
3075
  const elements = getSelectedElements(board);
3038
3076
  const rectangle = getRectangleByElements(board, elements, false);
3039
- if (rectangle.width > 0 && rectangle.height > 0 && elements.length > 1) {
3040
- const selectionRectangleG = drawRectangle(board, RectangleClient.inflate(rectangle, ACTIVE_STROKE_WIDTH), {
3077
+ const activeRectangle = toActiveRectangleFromViewBoxRectangle(board, rectangle);
3078
+ if (activeRectangle.width > 0 && activeRectangle.height > 0 && elements.length > 1) {
3079
+ const selectionRectangleG = drawRectangle(board, RectangleClient.inflate(activeRectangle, ACTIVE_STROKE_WIDTH), {
3041
3080
  stroke: SELECTION_BORDER_COLOR,
3042
3081
  strokeWidth: ACTIVE_STROKE_WIDTH,
3043
3082
  fillStyle: 'solid'
@@ -3045,7 +3084,7 @@ function drawSelectionRectangleG(board) {
3045
3084
  selectionRectangleG.classList.add(SELECTION_RECTANGLE_CLASS_NAME, SELECTION_RECTANGLE_BOUNDING_CLASS_NAME);
3046
3085
  const angle = getSelectionAngle(elements);
3047
3086
  if (angle) {
3048
- setAngleForG(selectionRectangleG, RectangleClient.getCenterPoint(rectangle), angle);
3087
+ setAngleForG(selectionRectangleG, RectangleClient.getCenterPoint(activeRectangle), angle);
3049
3088
  }
3050
3089
  return selectionRectangleG;
3051
3090
  }
@@ -3058,7 +3097,7 @@ function setSelectedElementsWithGroup(board, elements, isShift) {
3058
3097
  const selectedElements = getSelectedElements(board);
3059
3098
  if (!Selection.isCollapsed(board.selection)) {
3060
3099
  let newElements = [...selectedElements];
3061
- elements.forEach(item => {
3100
+ elements.forEach((item) => {
3062
3101
  if (!item.groupId) {
3063
3102
  newElements.push(item);
3064
3103
  }
@@ -3074,7 +3113,7 @@ function setSelectedElementsWithGroup(board, elements, isShift) {
3074
3113
  const hitElementGroups = getGroupByElement(board, hitElement, true);
3075
3114
  if (hitElementGroups.length) {
3076
3115
  const elementsInHighestGroup = getElementsInGroup(board, hitElementGroups[hitElementGroups.length - 1], true) || [];
3077
- const isSelectGroupElement = selectedElements.some(element => elementsInHighestGroup.map(item => item.id).includes(element.id));
3116
+ const isSelectGroupElement = selectedElements.some((element) => elementsInHighestGroup.map((item) => item.id).includes(element.id));
3078
3117
  if (isShift) {
3079
3118
  cacheSelectedElementsWithGroupOnShift(board, elements, isSelectGroupElement, elementsInHighestGroup);
3080
3119
  }
@@ -3093,16 +3132,16 @@ function cacheSelectedElementsWithGroupOnShift(board, elements, isSelectGroupEle
3093
3132
  pendingElements = elementsInHighestGroup;
3094
3133
  }
3095
3134
  else {
3096
- const isHitSelectedElement = selectedElements.some(item => item.id === hitElement.id);
3097
- const selectedElementsInGroup = elementsInHighestGroup.filter(item => selectedElements.includes(item));
3135
+ const isHitSelectedElement = selectedElements.some((item) => item.id === hitElement.id);
3136
+ const selectedElementsInGroup = elementsInHighestGroup.filter((item) => selectedElements.includes(item));
3098
3137
  if (isHitSelectedElement) {
3099
- pendingElements = selectedElementsInGroup.filter(item => item.id !== hitElement.id);
3138
+ pendingElements = selectedElementsInGroup.filter((item) => item.id !== hitElement.id);
3100
3139
  }
3101
3140
  else {
3102
3141
  pendingElements.push(...selectedElementsInGroup, ...elements);
3103
3142
  }
3104
3143
  }
3105
- elementsInHighestGroup.forEach(element => {
3144
+ elementsInHighestGroup.forEach((element) => {
3106
3145
  if (newElements.includes(element)) {
3107
3146
  newElements.splice(newElements.indexOf(element), 1);
3108
3147
  }
@@ -3905,14 +3944,14 @@ const rotatePoints = (points, centerPoint, angle) => {
3905
3944
  return rotate(points[0], points[1], centerPoint[0], centerPoint[1], angle);
3906
3945
  }
3907
3946
  else {
3908
- return points.map(point => {
3947
+ return points.map((point) => {
3909
3948
  return rotate(point[0], point[1], centerPoint[0], centerPoint[1], angle || 0);
3910
3949
  });
3911
3950
  }
3912
3951
  };
3913
3952
  const getSelectionAngle = (elements) => {
3914
3953
  let angle = elements[0]?.angle || 0;
3915
- elements.forEach(item => {
3954
+ elements.forEach((item) => {
3916
3955
  if (item.angle !== angle && !approximately(((item.angle || 0) % (Math.PI / 2)) - (angle % (Math.PI / 2)), 0)) {
3917
3956
  angle = 0;
3918
3957
  }
@@ -3927,7 +3966,7 @@ const hasSameAngle = (elements) => {
3927
3966
  if (angle === undefined) {
3928
3967
  return false;
3929
3968
  }
3930
- return !elements.some(item => item.angle !== angle);
3969
+ return !elements.some((item) => item.angle !== angle);
3931
3970
  };
3932
3971
  const getRotatedBoundingRectangle = (rectanglesCornerPoints, angle) => {
3933
3972
  let rectanglesFromOrigin = [];
@@ -3951,7 +3990,7 @@ const getOffsetAfterRotate = (rectangle, rotateCenterPoint, angle) => {
3951
3990
  };
3952
3991
  const rotatedDataPoints = (points, rotateCenterPoint, angle) => {
3953
3992
  const { offsetX, offsetY } = getOffsetAfterRotate(RectangleClient.getRectangleByPoints(points), rotateCenterPoint, angle);
3954
- return points.map(p => [p[0] + offsetX, p[1] + offsetY]);
3993
+ return points.map((p) => [p[0] + offsetX, p[1] + offsetY]);
3955
3994
  };
3956
3995
  const hasValidAngle = (node) => {
3957
3996
  return isValidAngle(node.angle);
@@ -3979,10 +4018,11 @@ const rotatePointsByAngle = (points, angle) => {
3979
4018
  return null;
3980
4019
  }
3981
4020
  };
3982
- const rotateAntiPointsByElement = (points, element) => {
4021
+ const rotateAntiPointsByElement = (board, points, element, isToActive = false) => {
3983
4022
  if (hasValidAngle(element)) {
3984
4023
  let rectangle = RectangleClient.getRectangleByPoints(element.points);
3985
- const centerPoint = RectangleClient.getCenterPoint(rectangle);
4024
+ const activeRectangle = isToActive ? toActiveRectangleFromViewBoxRectangle(board, rectangle) : rectangle;
4025
+ const centerPoint = RectangleClient.getCenterPoint(activeRectangle);
3986
4026
  return rotatePoints(points, centerPoint, element.angle ? -element.angle : 0);
3987
4027
  }
3988
4028
  else {
@@ -4010,7 +4050,7 @@ function radiansToDegrees(r) {
4010
4050
  function rotateElements(board, elements, angle) {
4011
4051
  const selectionRectangle = getRectangleByElements(board, elements, false);
4012
4052
  const selectionCenterPoint = RectangleClient.getCenterPoint(selectionRectangle);
4013
- elements.forEach(item => {
4053
+ elements.forEach((item) => {
4014
4054
  const originAngle = item.angle;
4015
4055
  const points = rotatedDataPoints(item.points, selectionCenterPoint, normalizeAngle(angle));
4016
4056
  const path = PlaitBoard.findPath(board, item);
@@ -4238,7 +4278,10 @@ const PlaitBoard = {
4238
4278
  getElementUpperHost(board) {
4239
4279
  return BOARD_TO_ELEMENT_HOST.get(board)?.upperHost;
4240
4280
  },
4241
- getElementActiveHost(board) {
4281
+ getElementTopHost(board) {
4282
+ return BOARD_TO_ELEMENT_HOST.get(board)?.topHost;
4283
+ },
4284
+ getActiveHost(board) {
4242
4285
  return BOARD_TO_ELEMENT_HOST.get(board)?.activeHost;
4243
4286
  },
4244
4287
  getRoughSVG(board) {
@@ -5603,24 +5646,44 @@ function withBoard(board) {
5603
5646
  }
5604
5647
 
5605
5648
  const isSmartHand = (board, event) => {
5606
- return (PlaitBoard.isPointer(board, PlaitPointerType.hand) ||
5607
- (PlaitBoard.isPointer(board, PlaitPointerType.selection) && isMobileDeviceEvent(event)));
5649
+ return PlaitBoard.isPointer(board, PlaitPointerType.selection) && isMobileDeviceEvent(event);
5608
5650
  };
5609
5651
 
5652
+ const ShortcutKey = 'Space';
5610
5653
  function withHandPointer(board) {
5611
5654
  const { pointerDown, pointerMove, globalPointerUp, keyDown, keyUp, pointerUp } = board;
5612
- let isMoving = false;
5655
+ let isHandMoving = false;
5613
5656
  let movingPoint = null;
5614
5657
  let pointerDownEvent = null;
5658
+ let hasWheelPressed = false;
5659
+ let beingPressedShortcutKey = false;
5615
5660
  board.pointerDown = (event) => {
5616
5661
  const options = board.getPluginOptions(PlaitPluginKey.withHand);
5617
5662
  const point = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
5618
5663
  const isHitTarget = isHitElement(board, point);
5619
- if ((options?.isHandMode(board, event) || (isSmartHand(board, event) && !isHitTarget)) && isMainPointer(event)) {
5664
+ const canEnterHandMode = options?.isHandMode(board, event) ||
5665
+ PlaitBoard.isPointer(board, PlaitPointerType.hand) ||
5666
+ (isSmartHand(board, event) && !isHitTarget) ||
5667
+ beingPressedShortcutKey;
5668
+ if (canEnterHandMode && isMainPointer(event)) {
5620
5669
  movingPoint = {
5621
5670
  x: event.x,
5622
5671
  y: event.y
5623
5672
  };
5673
+ if (!PlaitBoard.isPointer(board, PlaitPointerType.hand)) {
5674
+ PlaitBoard.getBoardContainer(board).classList.add('viewport-moving');
5675
+ }
5676
+ }
5677
+ else if (isWheelPointer(event)) {
5678
+ hasWheelPressed = true;
5679
+ // Prevent the browser's default behavior of scrolling the page when the mouse wheel is pressed.
5680
+ event.preventDefault();
5681
+ movingPoint = {
5682
+ x: event.x,
5683
+ y: event.y
5684
+ };
5685
+ isHandMoving = true;
5686
+ PlaitBoard.getBoardContainer(board).classList.add('viewport-moving');
5624
5687
  }
5625
5688
  pointerDownEvent = event;
5626
5689
  pointerDown(event);
@@ -5635,19 +5698,20 @@ function withHandPointer(board) {
5635
5698
  // withHand behavior is only triggered if drag selection state is not initiated.
5636
5699
  const triggerDistance = DRAG_SELECTION_PRESS_AND_MOVE_BUFFER + 4;
5637
5700
  if (movingPoint &&
5638
- !isMoving &&
5701
+ !isHandMoving &&
5639
5702
  !isSelectionMoving(board) &&
5640
5703
  pointerDownEvent &&
5641
5704
  distanceBetweenPointAndPoint(pointerDownEvent.x, pointerDownEvent.y, event.x, event.y) > triggerDistance &&
5642
5705
  !isMovingElements(board)) {
5643
- isMoving = true;
5706
+ isHandMoving = true;
5644
5707
  PlaitBoard.getBoardContainer(board).classList.add('viewport-moving');
5645
5708
  }
5646
- if ((options?.isHandMode(board, event) || isSmartHand(board, event)) &&
5647
- isMoving &&
5648
- movingPoint &&
5649
- !isSelectionMoving(board) &&
5650
- !isMovingElements(board)) {
5709
+ const canEnterHandMode = options?.isHandMode(board, event) ||
5710
+ PlaitBoard.isPointer(board, PlaitPointerType.hand) ||
5711
+ isSmartHand(board, event) ||
5712
+ hasWheelPressed ||
5713
+ beingPressedShortcutKey;
5714
+ if (canEnterHandMode && isHandMoving && movingPoint && !isSelectionMoving(board) && !isMovingElements(board)) {
5651
5715
  const viewportContainer = PlaitBoard.getViewportContainer(board);
5652
5716
  const left = viewportContainer.scrollLeft - (event.x - movingPoint.x);
5653
5717
  const top = viewportContainer.scrollTop - (event.y - movingPoint.y);
@@ -5658,7 +5722,7 @@ function withHandPointer(board) {
5658
5722
  pointerMove(event);
5659
5723
  };
5660
5724
  board.pointerUp = (event) => {
5661
- if (isMoving) {
5725
+ if (isHandMoving) {
5662
5726
  return;
5663
5727
  }
5664
5728
  pointerUp(event);
@@ -5667,24 +5731,25 @@ function withHandPointer(board) {
5667
5731
  if (movingPoint) {
5668
5732
  movingPoint = null;
5669
5733
  }
5670
- if (isMoving) {
5671
- isMoving = false;
5672
- PlaitBoard.getBoardContainer(board).classList.remove('viewport-moving');
5673
- }
5734
+ isHandMoving = false;
5735
+ PlaitBoard.getBoardContainer(board).classList.remove('viewport-moving');
5736
+ hasWheelPressed = false;
5674
5737
  globalPointerUp(event);
5675
5738
  };
5676
5739
  board.keyDown = (event) => {
5677
- if (event.code === 'Space') {
5740
+ if (event.code === ShortcutKey) {
5678
5741
  if (!PlaitBoard.isPointer(board, PlaitPointerType.hand)) {
5679
- BoardTransforms.updatePointerType(board, PlaitPointerType.hand);
5742
+ beingPressedShortcutKey = true;
5743
+ PlaitBoard.getBoardContainer(board).classList.add('viewport-moving');
5680
5744
  }
5681
5745
  event.preventDefault();
5682
5746
  }
5683
5747
  keyDown(event);
5684
5748
  };
5685
5749
  board.keyUp = (event) => {
5686
- if (!board.options.readonly && event.code === 'Space') {
5687
- BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
5750
+ if (!board.options.readonly && event.code === ShortcutKey) {
5751
+ beingPressedShortcutKey = true;
5752
+ PlaitBoard.getBoardContainer(board).classList.remove('viewport-moving');
5688
5753
  }
5689
5754
  keyUp(event);
5690
5755
  };
@@ -6086,7 +6151,7 @@ function withMoving(board) {
6086
6151
  event.preventDefault();
6087
6152
  if (startPoint && activeElements.length && !PlaitBoard.hasBeenTextEditing(board)) {
6088
6153
  pendingNodesG = drawPendingNodesG(board, activeElements, offsetX, offsetY);
6089
- pendingNodesG && PlaitBoard.getElementActiveHost(board).append(pendingNodesG);
6154
+ pendingNodesG && PlaitBoard.getElementTopHost(board).append(pendingNodesG);
6090
6155
  }
6091
6156
  }
6092
6157
  }
@@ -6170,10 +6235,10 @@ function withMoving(board) {
6170
6235
  offsetY += ref.deltaY;
6171
6236
  snapG = ref.snapG;
6172
6237
  snapG.classList.add(ACTIVE_MOVING_CLASS_NAME);
6173
- PlaitBoard.getElementActiveHost(board).append(snapG);
6238
+ PlaitBoard.getElementTopHost(board).append(snapG);
6174
6239
  if (event.altKey) {
6175
6240
  pendingNodesG = drawPendingNodesG(board, activeElements, offsetX, offsetY);
6176
- pendingNodesG && PlaitBoard.getElementActiveHost(board).append(pendingNodesG);
6241
+ pendingNodesG && PlaitBoard.getElementTopHost(board).append(pendingNodesG);
6177
6242
  }
6178
6243
  else {
6179
6244
  const currentElements = updatePoints(board, activeElements, offsetX, offsetY);
@@ -6370,11 +6435,10 @@ function withRelatedFragment(board) {
6370
6435
 
6371
6436
  function withSelection(board) {
6372
6437
  const { pointerDown, pointerUp, pointerMove, globalPointerUp, onChange, afterChange, drawSelectionRectangle } = board;
6373
- let start = null;
6374
- let end = null;
6438
+ let screenStart = null;
6439
+ let screenEnd = null;
6375
6440
  let selectionMovingG;
6376
6441
  let selectionRectangleG;
6377
- let previousSelectedElements;
6378
6442
  let isShift = false;
6379
6443
  let timerId = null;
6380
6444
  let pointerDownEvent = null;
@@ -6389,18 +6453,18 @@ function withSelection(board) {
6389
6453
  const isHitTarget = isHitElement(board, point);
6390
6454
  const options = getSelectionOptions(board);
6391
6455
  if (PlaitBoard.isPointer(board, PlaitPointerType.selection) &&
6456
+ isMainPointer(event) &&
6392
6457
  !isHitTarget &&
6393
6458
  options.isMultipleSelection &&
6394
6459
  !options.isDisabledSelection) {
6395
- // start drag selection
6396
6460
  if (isMobileDeviceEvent(event)) {
6397
6461
  timerId = setTimeout(() => {
6398
- start = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
6462
+ screenStart = [event.x, event.y];
6399
6463
  timerId = null;
6400
6464
  }, 120);
6401
6465
  }
6402
6466
  else {
6403
- start = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
6467
+ screenStart = [event.x, event.y];
6404
6468
  }
6405
6469
  }
6406
6470
  pointerDownEvent = event;
@@ -6413,14 +6477,20 @@ function withSelection(board) {
6413
6477
  clearTimeout(timerId);
6414
6478
  timerId = null;
6415
6479
  }
6416
- if (PlaitBoard.isPointer(board, PlaitPointerType.selection) && start) {
6417
- const movedTarget = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
6418
- const rectangle = RectangleClient.getRectangleByPoints([start, movedTarget]);
6480
+ if (PlaitBoard.isPointer(board, PlaitPointerType.selection) && screenStart) {
6481
+ event.preventDefault();
6482
+ screenEnd = [event.x, event.y];
6483
+ const rectangle = RectangleClient.getRectangleByPoints([
6484
+ toActivePoint(board, ...screenStart),
6485
+ toActivePoint(board, ...screenEnd)
6486
+ ]);
6419
6487
  selectionMovingG?.remove();
6420
- end = movedTarget;
6421
6488
  throttleRAF(board, 'with-selection', () => {
6422
- if (start && end) {
6423
- Transforms.setSelection(board, { anchor: start, focus: end });
6489
+ if (screenStart && screenEnd) {
6490
+ Transforms.setSelection(board, {
6491
+ anchor: toViewBoxPoint(board, toHostPoint(board, screenStart[0], screenStart[1])),
6492
+ focus: toViewBoxPoint(board, toHostPoint(board, screenEnd[0], screenEnd[1]))
6493
+ });
6424
6494
  }
6425
6495
  });
6426
6496
  setSelectionMoving(board);
@@ -6430,7 +6500,7 @@ function withSelection(board) {
6430
6500
  fill: SELECTION_FILL_COLOR,
6431
6501
  fillStyle: 'solid'
6432
6502
  });
6433
- PlaitBoard.getElementActiveHost(board).append(selectionMovingG);
6503
+ PlaitBoard.getActiveHost(board).append(selectionMovingG);
6434
6504
  }
6435
6505
  pointerMove(event);
6436
6506
  };
@@ -6448,10 +6518,13 @@ function withSelection(board) {
6448
6518
  pointerUp(event);
6449
6519
  };
6450
6520
  board.globalPointerUp = (event) => {
6451
- if (start && end) {
6521
+ if (screenStart && screenEnd) {
6452
6522
  selectionMovingG?.remove();
6453
6523
  clearSelectionMoving(board);
6454
- Transforms.setSelection(board, { anchor: start, focus: end });
6524
+ Transforms.setSelection(board, {
6525
+ anchor: toViewBoxPoint(board, toHostPoint(board, screenStart[0], screenStart[1])),
6526
+ focus: toViewBoxPoint(board, toHostPoint(board, screenEnd[0], screenEnd[1]))
6527
+ });
6455
6528
  }
6456
6529
  const options = getSelectionOptions(board);
6457
6530
  if (PlaitBoard.isFocus(board) && !options.isPreventClearSelection) {
@@ -6460,12 +6533,12 @@ function withSelection(board) {
6460
6533
  const isAttachedElement = event.target instanceof Element && event.target.closest(`.${ATTACHED_ELEMENT_CLASS_NAME}`);
6461
6534
  // Clear selection when mouse board outside area
6462
6535
  // The framework needs to determine whether the board is focused through selection
6463
- if (!isInBoard && !start && !isAttachedElement && isInDocument) {
6536
+ if (!isInBoard && !screenStart && !isAttachedElement && isInDocument) {
6464
6537
  Transforms.setSelection(board, null);
6465
6538
  }
6466
6539
  }
6467
- start = null;
6468
- end = null;
6540
+ screenStart = null;
6541
+ screenEnd = null;
6469
6542
  if (timerId) {
6470
6543
  clearTimeout(timerId);
6471
6544
  timerId = null;
@@ -6538,13 +6611,12 @@ function withSelection(board) {
6538
6611
  }
6539
6612
  }
6540
6613
  const newElements = getSelectedElements(board);
6541
- previousSelectedElements = [...newElements];
6542
6614
  deleteTemporaryElements(board);
6543
6615
  if (!isSelectionMoving(board)) {
6544
6616
  selectionRectangleG?.remove();
6545
6617
  if (newElements.length > 1) {
6546
6618
  selectionRectangleG = board.drawSelectionRectangle();
6547
- PlaitBoard.getElementActiveHost(board).append(selectionRectangleG);
6619
+ PlaitBoard.getActiveHost(board).append(selectionRectangleG);
6548
6620
  }
6549
6621
  }
6550
6622
  }
@@ -6559,14 +6631,9 @@ function withSelection(board) {
6559
6631
  try {
6560
6632
  const currentSelectedElements = getSelectedElements(board);
6561
6633
  if (currentSelectedElements.length && currentSelectedElements.length > 1) {
6562
- if (previousSelectedElements &&
6563
- (currentSelectedElements.length !== previousSelectedElements.length ||
6564
- currentSelectedElements.some((c, index) => c !== previousSelectedElements[index]))) {
6565
- selectionRectangleG?.remove();
6566
- selectionRectangleG = board.drawSelectionRectangle();
6567
- PlaitBoard.getElementActiveHost(board).append(selectionRectangleG);
6568
- previousSelectedElements = [...currentSelectedElements];
6569
- }
6634
+ selectionRectangleG?.remove();
6635
+ selectionRectangleG = board.drawSelectionRectangle();
6636
+ PlaitBoard.getActiveHost(board).append(selectionRectangleG);
6570
6637
  }
6571
6638
  else {
6572
6639
  selectionRectangleG?.remove();
@@ -6586,34 +6653,6 @@ function withSelection(board) {
6586
6653
  return board;
6587
6654
  }
6588
6655
 
6589
- function withViewport(board) {
6590
- const { onChange } = board;
6591
- const throttleUpdate = debounce(() => {
6592
- initializeViewBox(board);
6593
- updateViewportOffset(board);
6594
- }, 500, { leading: true });
6595
- board.onChange = () => {
6596
- const isSetViewport = board.operations.length && board.operations.some(op => op.type === 'set_viewport');
6597
- const isOnlySetSelection = board.operations.length && board.operations.every(op => op.type === 'set_selection');
6598
- if (isOnlySetSelection) {
6599
- return onChange();
6600
- }
6601
- if (isSetViewport && isFromScrolling(board)) {
6602
- setIsFromScrolling(board, false);
6603
- return onChange();
6604
- }
6605
- if (isSetViewport) {
6606
- initializeViewBox(board);
6607
- updateViewportOffset(board);
6608
- }
6609
- else {
6610
- throttleUpdate();
6611
- }
6612
- onChange();
6613
- };
6614
- return board;
6615
- }
6616
-
6617
6656
  /**
6618
6657
  * 1.create board instance
6619
6658
  * 2.build fake node weak map
@@ -6782,5 +6821,5 @@ function createModModifierKeys() {
6782
6821
  * Generated bundle index. Do not edit.
6783
6822
  */
6784
6823
 
6785
- export { A, ACTIVE_MOVING_CLASS_NAME, ACTIVE_STROKE_WIDTH, ALT, APOSTROPHE, ATTACHED_ELEMENT_CLASS_NAME, AT_SIGN, B, BACKSLASH, BACKSPACE, BOARD_TO_AFTER_CHANGE, BOARD_TO_CONTEXT, BOARD_TO_ELEMENT_HOST, BOARD_TO_HOST, BOARD_TO_IS_SELECTION_MOVING, BOARD_TO_MOVING_ELEMENT, BOARD_TO_MOVING_POINT, BOARD_TO_MOVING_POINT_IN_BOARD, BOARD_TO_ON_CHANGE, BOARD_TO_ROUGH_SVG, BOARD_TO_SELECTED_ELEMENT, BOARD_TO_TEMPORARY_ELEMENTS, BOARD_TO_VIEWPORT_ORIGINATION, BoardTransforms, C, CAPS_LOCK, CLOSE_SQUARE_BRACKET, COMMA, CONTEXT_MENU, CONTROL, ColorfulThemeColor, CoreTransforms, CursorClass, D, DASH, DEFAULT_COLOR, DELETE, DOWN_ARROW, DRAG_SELECTION_PRESS_AND_MOVE_BUFFER, DarkThemeColor, DebugGenerator, DefaultThemeColor, Direction, E, EIGHT, ELEMENT_TO_REF, END, ENTER, EQUALS, ESCAPE, ElementFlavour, F, F1, F10, F11, F12, F2, F3, F4, F5, F6, F7, F8, F9, FF_EQUALS, FF_MINUS, FF_MUTE, FF_SEMICOLON, FF_VOLUME_DOWN, FF_VOLUME_UP, FIRST_MEDIA, FIVE, FLUSHING, FOUR, G, H, HISTORY, HIT_DISTANCE_BUFFER, HOME, HOST_CLASS_NAME, I, INSERT, IS_APPLE, IS_BOARD_ALIVE, IS_BOARD_CACHE, IS_CHROME, IS_CHROME_LEGACY, IS_DRAGGING, IS_EDGE_LEGACY, IS_FIREFOX, IS_IOS, IS_MAC, IS_SAFARI, IS_TEXT_EDITABLE, J, K, KEY_TO_ELEMENT_MAP, L, LAST_MEDIA, LEFT_ARROW, ListRender, M, MAC_ENTER, MAC_META, MAC_WK_CMD_LEFT, MAC_WK_CMD_RIGHT, MAX_RADIUS, MAX_ZOOM, MERGING, META, MIN_ZOOM, MUTE, N, NINE, NODE_TO_CONTAINER_G, NODE_TO_G, NODE_TO_INDEX, NODE_TO_PARENT, NS, NUMPAD_DIVIDE, NUMPAD_EIGHT, NUMPAD_FIVE, NUMPAD_FOUR, NUMPAD_MINUS, NUMPAD_MULTIPLY, NUMPAD_NINE, NUMPAD_ONE, NUMPAD_PERIOD, NUMPAD_PLUS, NUMPAD_SEVEN, NUMPAD_SIX, NUMPAD_THREE, NUMPAD_TWO, NUMPAD_ZERO, NUM_CENTER, NUM_LOCK, O, ONE, OPEN_SQUARE_BRACKET, P, PAGE_DOWN, PAGE_UP, PATH_REFS, PAUSE, PERIOD, PLUS_SIGN, POINTER_BUTTON, PRESS_AND_MOVE_BUFFER, PRINT_SCREEN, Path, PlaitBoard, PlaitBoardContext, PlaitElement, PlaitGroupElement, PlaitHistoryBoard, PlaitNode, PlaitOperation, PlaitPluginKey, PlaitPointerType, Point, Q, QUESTION_MARK, R, RESIZE_CURSORS, RESIZE_HANDLE_CLASS_NAME, RIGHT_ARROW, ROTATE_HANDLE_CLASS_NAME, RectangleClient, ResizeCursorClass, RetroThemeColor, RgbaToHEX, S, SAVING, SCROLL_BAR_WIDTH, SCROLL_LOCK, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, SELECTION_RECTANGLE_BOUNDING_CLASS_NAME, SELECTION_RECTANGLE_CLASS_NAME, SEMICOLON, SEVEN, SHIFT, SINGLE_QUOTE, SIX, SLASH, SNAPPING_STROKE_WIDTH, SNAP_TOLERANCE, SPACE, SPLITTING_ONCE, Selection, SoftThemeColor, StarryThemeColor, T, TAB, THREE, TILDE, TWO, ThemeColorMode, ThemeColors, Transforms, U, UP_ARROW, V, VOLUME_DOWN, VOLUME_UP, Viewport, W, WritableClipboardOperationType, WritableClipboardType, X, Y, Z, ZERO, ZOOM_STEP, addClipboardContext, addOrCreateClipboardContext, addSelectedElement, approximately, arrowPoints, buildPlaitHtml, cacheMovingElements, cacheSelectedElements, cacheSelectedElementsWithGroup, cacheSelectedElementsWithGroupOnShift, calcNewViewBox, canAddGroup, canRemoveGroup, canSetZIndex, catmullRomFitting, ceilToDecimal, clampZoomLevel, clearNodeWeakMap, clearSelectedElement, clearSelectionMoving, clearViewportOrigination, createBoard, createClipboardContext, createDebugGenerator, createFakeEvent, createForeignObject, createG, createGroup, createGroupRectangleG, createKeyboardEvent, createMask, createModModifierKeys, createMouseEvent, createPath, createPointerEvent, createRect, createSVG, createTestingBoard, createText, createTouchEvent, debounce, degreesToRadians, deleteFragment, deleteTemporaryElements, depthFirstRecursion, distanceBetweenPointAndPoint, distanceBetweenPointAndRectangle, distanceBetweenPointAndSegment, distanceBetweenPointAndSegments, downloadImage, drawArrow, drawBezierPath, drawCircle, drawDashedLines, drawLine, drawLinearPath, drawPendingNodesG, drawPointSnapLines, drawRectangle, drawRoundRectangle, drawSelectionRectangleG, drawSolidLines, duplicateElements, fakeNodeWeakMap, filterSelectedGroups, findElements, findIndex, findLastIndex, getAllElementsInGroup, getAllMoveOptions, getAngleBetweenPoints, getAngleByElement, getBarPoint, getBoardRectangle, getBoundingRectangleByElements, getClipboardData, getClipboardFromHtml, getCrossingPointsBetweenEllipseAndSegment, getDataTransferClipboard, getDataTransferClipboardText, getEditingGroup, getElementById, getElementHostBBox, getElementMap, getElementsInGroup, getElementsInGroupByElement, getElementsIndices, getEllipseArcCenter, getEllipseTangentSlope, getGroupByElement, getHighestGroup, getHighestIndexOfElement, getHighestSelectedElements, getHighestSelectedGroup, getHighestSelectedGroups, getHitElementByPoint, getHitElementsByPoint, getHitElementsBySelection, getHitSelectedElements, getIsRecursionFunc, getMinPointDelta, getMovingElements, getNearestDelta, getNearestPointBetweenPointAndArc, getNearestPointBetweenPointAndEllipse, getNearestPointBetweenPointAndSegment, getNearestPointBetweenPointAndSegments, getNearestPointRectangle, getOffsetAfterRotate, getOneMoveOptions, getPointBetween, getProbablySupportsClipboardRead, getProbablySupportsClipboardWrite, getProbablySupportsClipboardWriteText, getRealScrollBarWidth, getRectangleByAngle, getRectangleByElements, getRectangleByGroup, getRotatedBoundingRectangle, getSelectedElements, getSelectedGroups, getSelectedIsolatedElements, getSelectedIsolatedElementsCanAddToGroup, getSelectedTargetElements, getSelectionAngle, getSelectionOptions, getSnapRectangles, getTemporaryElements, getTemporaryRef, getTripleAxis, getValidElements, getVectorFromPointAndSlope, getViewBox, getViewBoxCenterPoint, getViewportContainerRect, getViewportOrigination, hasBeforeContextChange, hasInputOrTextareaTarget, hasOnContextChanged, hasSameAngle, hasSelectedElementsInSameGroup, hasSetSelectionOperation, hasValidAngle, hotkeys, idCreator, initializeViewBox, initializeViewportContainer, initializeViewportOffset, inverse, isAxisChangedByAngle, isContextmenu, isDOMElement, isDOMNode, isDebug, isDragging, isFromScrolling, isFromViewportChange, isHandleSelection, isHitElement, isHitSelectedRectangle, isInPlaitBoard, isIndicesContinuous, isLineHitLine, isLineHitRectangle, isLineHitRectangleEdge, isMainPointer, isMobileDeviceEvent, isMouseEvent, isMovingElements, isNullOrUndefined, isPencilEvent, isPointInEllipse, isPointInPolygon, isPointInRoundRectangle, isSecondaryPointer, isSelectedAllElementsInGroup, isSelectedElement, isSelectedElementOrGroup, isSelectionMoving, isSetSelectionOperation, isSetThemeOperation, isSetViewportOperation, isSingleLineHitRectangleEdge, isSnapPoint, isTouchEvent, isValidAngle, mountElementG, moveElementsToNewPath, moveElementsToNewPathAfterAddGroup, nonGroupInHighestSelectedElements, normalizeAngle, normalizePoint, radiansToDegrees, removeMovingElements, removeSelectedElement, replaceAngleBrackets, replaceSelectedElement, reverseReplaceAngleBrackets, rotate, rotateAntiPointsByElement, rotateElements, rotatePoints, rotatePointsByAngle, rotatePointsByElement, rotatedDataPoints, scrollToRectangle, setAngleForG, setClipboardData, setDataTransferClipboard, setDataTransferClipboardText, setDragging, setFragment, setIsFromScrolling, setIsFromViewportChange, setPathStrokeLinecap, setSVGViewBox, setSelectedElementsWithGroup, setSelectionMoving, setSelectionOptions, setStrokeLinecap, shouldClear, shouldMerge, shouldSave, sortElements, stripHtml, temporaryDisableSelection, throttleRAF, toDomPrecision, toFixed, toHostPoint, toHostPointFromViewBoxPoint, toImage, toScreenPointFromHostPoint, toViewBoxPoint, toViewBoxPoints, uniqueById, updateForeignObject, updateForeignObjectWidth, updatePoints, updateViewportByScrolling, updateViewportContainerScroll, updateViewportOffset, updateViewportOrigination, withArrowMoving, withBoard, withHandPointer, withHistory, withHotkey, withMoving, withOptions, withRelatedFragment, withSelection, withViewport };
6824
+ export { A, ACTIVE_MOVING_CLASS_NAME, ACTIVE_STROKE_WIDTH, ALT, APOSTROPHE, ATTACHED_ELEMENT_CLASS_NAME, AT_SIGN, B, BACKSLASH, BACKSPACE, BOARD_TO_AFTER_CHANGE, BOARD_TO_CONTEXT, BOARD_TO_ELEMENT_HOST, BOARD_TO_HOST, BOARD_TO_IS_SELECTION_MOVING, BOARD_TO_MOVING_ELEMENT, BOARD_TO_MOVING_POINT, BOARD_TO_MOVING_POINT_IN_BOARD, BOARD_TO_ON_CHANGE, BOARD_TO_ROUGH_SVG, BOARD_TO_SELECTED_ELEMENT, BOARD_TO_TEMPORARY_ELEMENTS, BOARD_TO_VIEWPORT_ORIGINATION, BoardTransforms, C, CAPS_LOCK, CLOSE_SQUARE_BRACKET, COMMA, CONTEXT_MENU, CONTROL, ColorfulThemeColor, CoreTransforms, CursorClass, D, DASH, DEFAULT_COLOR, DELETE, DOWN_ARROW, DRAG_SELECTION_PRESS_AND_MOVE_BUFFER, DarkThemeColor, DebugGenerator, DefaultThemeColor, Direction, E, EIGHT, ELEMENT_TO_REF, END, ENTER, EQUALS, ESCAPE, ElementFlavour, F, F1, F10, F11, F12, F2, F3, F4, F5, F6, F7, F8, F9, FF_EQUALS, FF_MINUS, FF_MUTE, FF_SEMICOLON, FF_VOLUME_DOWN, FF_VOLUME_UP, FIRST_MEDIA, FIVE, FLUSHING, FOUR, G, H, HISTORY, HIT_DISTANCE_BUFFER, HOME, HOST_CLASS_NAME, I, INSERT, IS_APPLE, IS_BOARD_ALIVE, IS_BOARD_CACHE, IS_CHROME, IS_CHROME_LEGACY, IS_DRAGGING, IS_EDGE_LEGACY, IS_FIREFOX, IS_IOS, IS_MAC, IS_SAFARI, IS_TEXT_EDITABLE, IS_WINDOWS, J, K, KEY_TO_ELEMENT_MAP, L, LAST_MEDIA, LEFT_ARROW, ListRender, M, MAC_ENTER, MAC_META, MAC_WK_CMD_LEFT, MAC_WK_CMD_RIGHT, MAX_RADIUS, MAX_ZOOM, MERGING, META, MIN_ZOOM, MUTE, N, NINE, NODE_TO_CONTAINER_G, NODE_TO_G, NODE_TO_INDEX, NODE_TO_PARENT, NS, NUMPAD_DIVIDE, NUMPAD_EIGHT, NUMPAD_FIVE, NUMPAD_FOUR, NUMPAD_MINUS, NUMPAD_MULTIPLY, NUMPAD_NINE, NUMPAD_ONE, NUMPAD_PERIOD, NUMPAD_PLUS, NUMPAD_SEVEN, NUMPAD_SIX, NUMPAD_THREE, NUMPAD_TWO, NUMPAD_ZERO, NUM_CENTER, NUM_LOCK, O, ONE, OPEN_SQUARE_BRACKET, P, PAGE_DOWN, PAGE_UP, PATH_REFS, PAUSE, PERIOD, PLUS_SIGN, POINTER_BUTTON, PRESS_AND_MOVE_BUFFER, PRINT_SCREEN, Path, PlaitBoard, PlaitBoardContext, PlaitElement, PlaitGroupElement, PlaitHistoryBoard, PlaitNode, PlaitOperation, PlaitPluginKey, PlaitPointerType, Point, Q, QUESTION_MARK, R, RESIZE_CURSORS, RESIZE_HANDLE_CLASS_NAME, RIGHT_ARROW, ROTATE_HANDLE_CLASS_NAME, RectangleClient, ResizeCursorClass, RetroThemeColor, RgbaToHEX, S, SAVING, SCROLL_BAR_WIDTH, SCROLL_LOCK, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, SELECTION_RECTANGLE_BOUNDING_CLASS_NAME, SELECTION_RECTANGLE_CLASS_NAME, SEMICOLON, SEVEN, SHIFT, SINGLE_QUOTE, SIX, SLASH, SNAPPING_STROKE_WIDTH, SNAP_TOLERANCE, SPACE, SPLITTING_ONCE, Selection, SoftThemeColor, StarryThemeColor, T, TAB, THREE, TILDE, TWO, ThemeColorMode, ThemeColors, Transforms, U, UP_ARROW, V, VOLUME_DOWN, VOLUME_UP, Viewport, W, WritableClipboardOperationType, WritableClipboardType, X, Y, Z, ZERO, ZOOM_STEP, addClipboardContext, addOrCreateClipboardContext, addSelectedElement, approximately, arrowPoints, buildPlaitHtml, cacheMovingElements, cacheSelectedElements, cacheSelectedElementsWithGroup, cacheSelectedElementsWithGroupOnShift, calcNewViewBox, canAddGroup, canRemoveGroup, canSetZIndex, catmullRomFitting, ceilToDecimal, clampZoomLevel, clearNodeWeakMap, clearSelectedElement, clearSelectionMoving, clearViewportOrigination, createBoard, createClipboardContext, createDebugGenerator, createFakeEvent, createForeignObject, createG, createGroup, createGroupRectangleG, createKeyboardEvent, createMask, createModModifierKeys, createMouseEvent, createPath, createPointerEvent, createRect, createSVG, createTestingBoard, createText, createTouchEvent, debounce, degreesToRadians, deleteFragment, deleteTemporaryElements, depthFirstRecursion, distanceBetweenPointAndPoint, distanceBetweenPointAndRectangle, distanceBetweenPointAndSegment, distanceBetweenPointAndSegments, downloadImage, drawArrow, drawBezierPath, drawCircle, drawDashedLines, drawLine, drawLinearPath, drawPendingNodesG, drawPointSnapLines, drawRectangle, drawRoundRectangle, drawSelectionRectangleG, drawSolidLines, duplicateElements, fakeNodeWeakMap, filterSelectedGroups, findElements, findIndex, findLastIndex, getAllElementsInGroup, getAllMoveOptions, getAngleBetweenPoints, getAngleByElement, getBarPoint, getBoardRectangle, getBoundingRectangleByElements, getClipboardData, getClipboardFromHtml, getCrossingPointsBetweenEllipseAndSegment, getDataTransferClipboard, getDataTransferClipboardText, getEditingGroup, getElementById, getElementHostBBox, getElementMap, getElementsInGroup, getElementsInGroupByElement, getElementsIndices, getEllipseArcCenter, getEllipseTangentSlope, getGroupByElement, getHighestGroup, getHighestIndexOfElement, getHighestSelectedElements, getHighestSelectedGroup, getHighestSelectedGroups, getHitElementByPoint, getHitElementsByPoint, getHitElementsBySelection, getHitSelectedElements, getIsRecursionFunc, getMinPointDelta, getMovingElements, getNearestDelta, getNearestPointBetweenPointAndArc, getNearestPointBetweenPointAndDiscreteSegments, getNearestPointBetweenPointAndEllipse, getNearestPointBetweenPointAndSegment, getNearestPointBetweenPointAndSegments, getNearestPointRectangle, getOffsetAfterRotate, getOneMoveOptions, getPointBetween, getProbablySupportsClipboardRead, getProbablySupportsClipboardWrite, getProbablySupportsClipboardWriteText, getRealScrollBarWidth, getRectangleByAngle, getRectangleByElements, getRectangleByGroup, getRotatedBoundingRectangle, getSelectedElements, getSelectedGroups, getSelectedIsolatedElements, getSelectedIsolatedElementsCanAddToGroup, getSelectedTargetElements, getSelectionAngle, getSelectionOptions, getSnapRectangles, getTemporaryElements, getTemporaryRef, getTripleAxis, getValidElements, getVectorFromPointAndSlope, getViewBox, getViewBoxCenterPoint, getViewportContainerRect, getViewportOrigination, hasBeforeContextChange, hasInputOrTextareaTarget, hasOnContextChanged, hasSameAngle, hasSelectedElementsInSameGroup, hasSetSelectionOperation, hasValidAngle, hotkeys, idCreator, initializeViewBox, initializeViewportContainer, initializeViewportOffset, inverse, isAxisChangedByAngle, isContextmenu, isDOMElement, isDOMNode, isDebug, isDragging, isFromScrolling, isFromViewportChange, isHandleSelection, isHitElement, isHitSelectedRectangle, isInPlaitBoard, isIndicesContinuous, isLineHitLine, isLineHitRectangle, isLineHitRectangleEdge, isMainPointer, isMobileDeviceEvent, isMouseEvent, isMovingElements, isNullOrUndefined, isPencilEvent, isPointInEllipse, isPointInPolygon, isPointInRoundRectangle, isSecondaryPointer, isSelectedAllElementsInGroup, isSelectedElement, isSelectedElementOrGroup, isSelectionMoving, isSetSelectionOperation, isSetThemeOperation, isSetViewportOperation, isSingleLineHitRectangleEdge, isSnapPoint, isTouchEvent, isValidAngle, isWheelPointer, mountElementG, moveElementsToNewPath, moveElementsToNewPathAfterAddGroup, nonGroupInHighestSelectedElements, normalizeAngle, normalizePoint, radiansToDegrees, removeMovingElements, removeSelectedElement, replaceAngleBrackets, replaceSelectedElement, reverseReplaceAngleBrackets, rotate, rotateAntiPointsByElement, rotateElements, rotatePoints, rotatePointsByAngle, rotatePointsByElement, rotatedDataPoints, scrollToRectangle, setAngleForG, setClipboardData, setDataTransferClipboard, setDataTransferClipboardText, setDragging, setFragment, setIsFromScrolling, setIsFromViewportChange, setPathStrokeLinecap, setSVGViewBox, setSelectedElementsWithGroup, setSelectionMoving, setSelectionOptions, setStrokeLinecap, shouldClear, shouldMerge, shouldSave, sortElements, stripHtml, temporaryDisableSelection, throttleRAF, toActivePoint, toActivePointFromViewBoxPoint, toActiveRectangleFromViewBoxRectangle, toDomPrecision, toFixed, toHostPoint, toHostPointFromViewBoxPoint, toImage, toScreenPointFromActivePoint, toScreenPointFromHostPoint, toViewBoxPoint, toViewBoxPoints, uniqueById, updateForeignObject, updateForeignObjectWidth, updatePoints, updateViewportByScrolling, updateViewportContainerScroll, updateViewportOffset, updateViewportOrigination, withArrowMoving, withBoard, withHandPointer, withHistory, withHotkey, withMoving, withOptions, withRelatedFragment, withSelection };
6786
6825
  //# sourceMappingURL=plait-core.mjs.map