@plait/common 0.28.0 → 0.30.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.
@@ -1,4 +1,4 @@
1
- import { createG, RectangleClient, drawRectangle, drawCircle, PlaitBoard, createForeignObject, updateForeignObject, getSelectedElements, PlaitElement, Transforms, PlaitPointerType, isMainPointer, transformPoint, toPoint, preventTouchMove, distanceBetweenPointAndPoint, PRESS_AND_MOVE_BUFFER, throttleRAF, handleTouchTarget, MERGING, Direction, hotkeys, PlaitContextService, PlaitPluginElementComponent, isSelectionMoving, ACTIVE_STROKE_WIDTH } from '@plait/core';
1
+ import { createG, RectangleClient, drawRectangle, drawCircle, PlaitBoard, createForeignObject, updateForeignObject, getSelectedElements, PlaitElement, Transforms, PlaitPointerType, isMainPointer, transformPoint, toPoint, preventTouchMove, distanceBetweenPointAndPoint, PRESS_AND_MOVE_BUFFER, throttleRAF, handleTouchTarget, MERGING, Direction, Point, hotkeys, PlaitContextService, PlaitPluginElementComponent, isSelectionMoving, ACTIVE_STROKE_WIDTH } from '@plait/core';
2
2
  import { isKeyHotkey } from 'is-hotkey';
3
3
  import * as i0 from '@angular/core';
4
4
  import { Directive, Input } from '@angular/core';
@@ -7,6 +7,7 @@ const BASE = 4;
7
7
  const PRIMARY_COLOR = '#6698FF';
8
8
  const RESIZE_HANDLE_DIAMETER = 8;
9
9
  const WithTextPluginKey = 'plait-text-plugin-key';
10
+ const DEFAULT_ROUTE_MARGIN = 30;
10
11
 
11
12
  var MediaKeys;
12
13
  (function (MediaKeys) {
@@ -614,6 +615,17 @@ function isPointOnLineSegment(point, startPoint, endPoint) {
614
615
  const segmentLength = distanceBetweenPointAndPoint(startPoint[0], startPoint[1], endPoint[0], endPoint[1]);
615
616
  return Math.abs(distanceToStart + distanceToEnd - segmentLength) < 0.1;
616
617
  }
618
+ const removeDuplicatePoints = (points) => {
619
+ const newArray = [];
620
+ points.forEach(point => {
621
+ const index = newArray.findIndex(otherPoint => {
622
+ return Point.isEquals(point, otherPoint);
623
+ });
624
+ if (index === -1)
625
+ newArray.push(point);
626
+ });
627
+ return newArray;
628
+ };
617
629
 
618
630
  function isVirtualKey(e) {
619
631
  const isMod = e.ctrlKey || e.metaKey;
@@ -725,6 +737,376 @@ function getImageSize(file, defaultImageWidth) {
725
737
  };
726
738
  });
727
739
  }
740
+ const BOARD_TO_ELEMENT_OF_FOCUSED_IMAGE = new WeakMap();
741
+ const getElementOfFocusedImage = (board) => {
742
+ return BOARD_TO_ELEMENT_OF_FOCUSED_IMAGE.get(board);
743
+ };
744
+ const addElementOfFocusedImage = (board, element) => {
745
+ BOARD_TO_ELEMENT_OF_FOCUSED_IMAGE.set(board, element);
746
+ };
747
+ const removeElementOfFocusedImage = (board) => {
748
+ BOARD_TO_ELEMENT_OF_FOCUSED_IMAGE.delete(board);
749
+ };
750
+
751
+ class PriorityQueue {
752
+ constructor() {
753
+ this.list = [];
754
+ }
755
+ enqueue(item) {
756
+ this.list.push(item);
757
+ this.list = this.list.sort((item1, item2) => item1.priority - item2.priority);
758
+ }
759
+ dequeue() {
760
+ return this.list.shift();
761
+ }
762
+ }
763
+
764
+ class AStar {
765
+ constructor(graph) {
766
+ this.graph = graph;
767
+ this.cameFrom = new Map();
768
+ }
769
+ heuristic(a, b) {
770
+ return Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1]);
771
+ }
772
+ search(start, end, previousStart) {
773
+ const frontier = new PriorityQueue();
774
+ const startNode = this.graph.get(start);
775
+ this.cameFrom = new Map();
776
+ const costSoFar = new Map();
777
+ costSoFar.set(startNode, 0);
778
+ frontier.enqueue({ node: startNode, priority: 0 });
779
+ while (frontier.list.length > 0) {
780
+ var current = frontier.dequeue();
781
+ if (!current) {
782
+ throw new Error(`can't find current`);
783
+ }
784
+ const currentPoint = current.node.data;
785
+ if (currentPoint[0] === end[0] && currentPoint[1] === end[1]) {
786
+ break;
787
+ }
788
+ current.node.adjacentNodes.forEach(next => {
789
+ let newCost = costSoFar.get(current.node) + this.heuristic(next.data, current.node.data);
790
+ const previousNode = this.cameFrom.get(current.node);
791
+ // 拐点权重
792
+ const previousPoint = previousNode ? previousNode.data : previousStart;
793
+ const x = previousPoint[0] === current?.node.data[0] && previousPoint[0] === next.data[0];
794
+ const y = previousPoint[1] === current?.node.data[1] && previousPoint[1] === next.data[1];
795
+ if (!x && !y) {
796
+ newCost = newCost + 1;
797
+ }
798
+ if (!costSoFar.has(next) || (costSoFar.get(next) && newCost < costSoFar.get(next))) {
799
+ costSoFar.set(next, newCost);
800
+ const priority = newCost + this.heuristic(next.data, end);
801
+ frontier.enqueue({ node: next, priority });
802
+ this.cameFrom.set(next, current.node);
803
+ }
804
+ });
805
+ }
806
+ }
807
+ getRoute(start, end) {
808
+ const result = [];
809
+ let temp = end;
810
+ while (temp[0] !== start[0] || temp[1] !== start[1]) {
811
+ const node = this.graph.get(temp);
812
+ const preNode = this.cameFrom.get(node);
813
+ result.unshift(preNode.data);
814
+ temp = preNode.data;
815
+ }
816
+ return result;
817
+ }
818
+ }
819
+
820
+ class PointNode {
821
+ constructor(data) {
822
+ this.data = data;
823
+ this.distance = Number.MAX_SAFE_INTEGER;
824
+ this.adjacentNodes = [];
825
+ }
826
+ }
827
+ class PointGraph {
828
+ constructor() {
829
+ this.index = {};
830
+ }
831
+ add(p) {
832
+ const x = p[0];
833
+ const y = p[1];
834
+ const xs = x.toString(), ys = y.toString();
835
+ if (!(xs in this.index)) {
836
+ this.index[xs] = {};
837
+ }
838
+ if (!(ys in this.index[xs])) {
839
+ this.index[xs][ys] = new PointNode(p);
840
+ }
841
+ }
842
+ connect(a, b) {
843
+ const nodeA = this.get(a);
844
+ const nodeB = this.get(b);
845
+ if (!nodeA || !nodeB) {
846
+ throw new Error(`A point was not found`);
847
+ }
848
+ nodeA.adjacentNodes.push(nodeB);
849
+ }
850
+ has(p) {
851
+ const x = p[0];
852
+ const y = p[1];
853
+ const xs = x.toString(), ys = y.toString();
854
+ return xs in this.index && ys in this.index[xs];
855
+ }
856
+ get(p) {
857
+ const x = p[0];
858
+ const y = p[1];
859
+ const xs = x.toString(), ys = y.toString();
860
+ if (xs in this.index && ys in this.index[xs]) {
861
+ return this.index[xs][ys];
862
+ }
863
+ return null;
864
+ }
865
+ }
866
+
867
+ const generateElbowLineRoute = (options) => {
868
+ const { nextSourcePoint, nextTargetPoint } = options;
869
+ const points = getGraphPoints(options);
870
+ const graph = createGraph(points);
871
+ const aStar = new AStar(graph);
872
+ aStar.search(nextSourcePoint, nextTargetPoint, options.sourcePoint);
873
+ let route = aStar.getRoute(nextSourcePoint, nextTargetPoint);
874
+ route = [options.sourcePoint, ...route, nextTargetPoint, options.targetPoint];
875
+ const isHitX = RectangleClient.isHitX(options.sourceOuterRectangle, options.targetOuterRectangle);
876
+ const isHitY = RectangleClient.isHitY(options.sourceOuterRectangle, options.targetOuterRectangle);
877
+ const xAxis = isHitX ? undefined : RectangleClient.getGapCenter(options.sourceOuterRectangle, options.targetOuterRectangle, false);
878
+ const yAxis = isHitY ? undefined : RectangleClient.getGapCenter(options.sourceOuterRectangle, options.targetOuterRectangle, true);
879
+ route = routeAdjust(route, { xAxis, yAxis, sourceRectangle: options.sourceRectangle, targetRectangle: options.targetRectangle });
880
+ return route;
881
+ };
882
+ const routeAdjust = (path, options) => {
883
+ // 基于 middleX/middleY 中线纠正 path
884
+ // 1. 找垂直/水平的线段
885
+ // 2. 找到和middleX/middleY相交的点
886
+ // 3. 基于垂直/水平的线段分别和相交点构建矩形
887
+ // 4. 判断矩形相交
888
+ // 5. 处理 path
889
+ const { sourceRectangle, targetRectangle, xAxis, yAxis } = options;
890
+ if (xAxis !== undefined) {
891
+ const optionsX = getAdjustOptions(path, xAxis, true);
892
+ const resultX = optionsX.pointOfHit &&
893
+ adjust(path, { parallelPaths: optionsX.parallelPaths, pointOfHit: optionsX.pointOfHit, sourceRectangle, targetRectangle });
894
+ if (resultX) {
895
+ path = resultX;
896
+ }
897
+ }
898
+ if (yAxis !== undefined) {
899
+ const optionsY = getAdjustOptions(path, yAxis, false);
900
+ const resultY = optionsY.pointOfHit &&
901
+ adjust(path, { parallelPaths: optionsY.parallelPaths, pointOfHit: optionsY.pointOfHit, sourceRectangle, targetRectangle });
902
+ if (resultY) {
903
+ path = resultY;
904
+ }
905
+ }
906
+ return path;
907
+ };
908
+ const adjust = (route, options) => {
909
+ const { parallelPaths, pointOfHit, sourceRectangle, targetRectangle } = options;
910
+ let result = null;
911
+ parallelPaths.forEach(parallelPath => {
912
+ // 构建矩形
913
+ const tempRect = RectangleClient.toRectangleClient([pointOfHit, parallelPath[0], parallelPath[1]]);
914
+ if (!RectangleClient.isHit(tempRect, sourceRectangle) && !RectangleClient.isHit(tempRect, targetRectangle)) {
915
+ const getCornerCount = (path) => {
916
+ let cornerCount = 0;
917
+ for (let index = 1; index < path.length - 1; index++) {
918
+ const pre = path[index - 1];
919
+ const current = path[index];
920
+ const next = path[index + 1];
921
+ if (pre &&
922
+ current &&
923
+ next &&
924
+ !((Math.floor(current[0]) === Math.floor(pre[0]) && Math.floor(current[0]) === Math.floor(next[0])) ||
925
+ (Math.floor(current[1]) === Math.floor(pre[1]) && Math.floor(current[1]) === Math.floor(next[1])))) {
926
+ cornerCount++;
927
+ }
928
+ }
929
+ return cornerCount;
930
+ };
931
+ const tempCorners = RectangleClient.getCornerPoints(tempRect);
932
+ const indexRangeInPath = [];
933
+ const indexRangeInCorner = [];
934
+ route.forEach((point, index) => {
935
+ const cornerResult = tempCorners.findIndex(corner => Math.floor(corner[0]) === Math.floor(point[0]) && Math.floor(corner[1]) === Math.floor(point[1]));
936
+ if (cornerResult !== -1) {
937
+ indexRangeInPath.push(index);
938
+ indexRangeInCorner.push(cornerResult);
939
+ }
940
+ });
941
+ const newPath = [...route];
942
+ const missCorner = tempCorners.find((c, index) => !indexRangeInCorner.includes(index));
943
+ const removeLength = Math.abs(indexRangeInPath[0] - indexRangeInPath[indexRangeInPath.length - 1]) + 1;
944
+ newPath.splice(indexRangeInPath[0] + 1, removeLength - 2, missCorner);
945
+ const cornerCount = getCornerCount([...route]);
946
+ const newCornerCount = getCornerCount([...newPath]);
947
+ if (newCornerCount <= cornerCount) {
948
+ result = newPath;
949
+ }
950
+ }
951
+ return null;
952
+ });
953
+ return result;
954
+ };
955
+ const getAdjustOptions = (path, middle, isHorizontal) => {
956
+ const parallelPaths = [];
957
+ let start = null;
958
+ let pointOfHit = null;
959
+ const axis = isHorizontal ? 0 : 1;
960
+ for (let index = 0; index < path.length; index++) {
961
+ const previous = path[index - 1];
962
+ const current = path[index];
963
+ if (start === null && previous && previous[axis] === current[axis]) {
964
+ start = previous;
965
+ }
966
+ if (start !== null) {
967
+ if (previous[axis] !== current[axis]) {
968
+ parallelPaths.push([start, previous]);
969
+ start = null;
970
+ }
971
+ }
972
+ if (current[axis] === middle) {
973
+ pointOfHit = current;
974
+ }
975
+ }
976
+ if (start) {
977
+ parallelPaths.push([start, path[path.length - 1]]);
978
+ }
979
+ return { pointOfHit, parallelPaths };
980
+ };
981
+ const getGraphPoints = (options) => {
982
+ const { nextSourcePoint, nextTargetPoint, sourceOuterRectangle, targetOuterRectangle } = options;
983
+ const x = [];
984
+ const y = [];
985
+ let result = [];
986
+ [sourceOuterRectangle, targetOuterRectangle].forEach(rectangle => {
987
+ x.push(rectangle.x, rectangle.x + rectangle.width / 2, rectangle.x + rectangle.width);
988
+ y.push(rectangle.y, rectangle.y + rectangle.height / 2, rectangle.y + rectangle.height);
989
+ });
990
+ const rectanglesX = [
991
+ sourceOuterRectangle.x,
992
+ sourceOuterRectangle.x + sourceOuterRectangle.width,
993
+ targetOuterRectangle.x,
994
+ targetOuterRectangle.x + targetOuterRectangle.width
995
+ ].sort((a, b) => a - b);
996
+ x.push((rectanglesX[1] + rectanglesX[2]) / 2, nextSourcePoint[0], nextTargetPoint[0]);
997
+ const rectanglesY = [
998
+ sourceOuterRectangle.y,
999
+ sourceOuterRectangle.y + sourceOuterRectangle.height,
1000
+ targetOuterRectangle.y,
1001
+ targetOuterRectangle.y + targetOuterRectangle.height
1002
+ ].sort((a, b) => a - b);
1003
+ y.push((rectanglesY[1] + rectanglesY[2]) / 2, nextSourcePoint[1], nextTargetPoint[1]);
1004
+ for (let i = 0; i < x.length; i++) {
1005
+ for (let j = 0; j < y.length; j++) {
1006
+ const point = [x[i], y[j]];
1007
+ const isInSource = RectangleClient.isPointInRectangle(sourceOuterRectangle, point);
1008
+ const isInTarget = RectangleClient.isPointInRectangle(targetOuterRectangle, point);
1009
+ if (!isInSource && !isInTarget) {
1010
+ result.push(point);
1011
+ }
1012
+ }
1013
+ }
1014
+ result = removeDuplicatePoints(result).filter(point => {
1015
+ const isInSource = RectangleClient.isPointInRectangle(sourceOuterRectangle, point);
1016
+ const isInTarget = RectangleClient.isPointInRectangle(targetOuterRectangle, point);
1017
+ return !isInSource && !isInTarget;
1018
+ });
1019
+ return result;
1020
+ };
1021
+ const createGraph = (points) => {
1022
+ const graph = new PointGraph();
1023
+ const Xs = [];
1024
+ const Ys = [];
1025
+ points.forEach(p => {
1026
+ const x = p[0], y = p[1];
1027
+ if (Xs.indexOf(x) < 0)
1028
+ Xs.push(x);
1029
+ if (Ys.indexOf(y) < 0)
1030
+ Ys.push(y);
1031
+ graph.add(p);
1032
+ });
1033
+ Xs.sort((a, b) => a - b);
1034
+ Ys.sort((a, b) => a - b);
1035
+ const inHotIndex = (p) => graph.has(p);
1036
+ for (let i = 0; i < Xs.length; i++) {
1037
+ for (let j = 0; j < Ys.length; j++) {
1038
+ const point = [Xs[i], Ys[j]];
1039
+ if (!inHotIndex(point))
1040
+ continue;
1041
+ if (i > 0) {
1042
+ const otherPoint = [Xs[i - 1], Ys[j]];
1043
+ if (inHotIndex(otherPoint)) {
1044
+ graph.connect(otherPoint, point);
1045
+ graph.connect(point, otherPoint);
1046
+ }
1047
+ }
1048
+ if (j > 0) {
1049
+ const otherPoint = [Xs[i], Ys[j - 1]];
1050
+ if (inHotIndex(otherPoint)) {
1051
+ graph.connect(otherPoint, point);
1052
+ graph.connect(point, otherPoint);
1053
+ }
1054
+ }
1055
+ }
1056
+ }
1057
+ return graph;
1058
+ };
1059
+ const reduceRouteMargin = (sourceRectangle, targetRectangle) => {
1060
+ const defaultOffset = DEFAULT_ROUTE_MARGIN;
1061
+ let sourceOffset = new Array(4).fill(defaultOffset);
1062
+ let targetOffset = new Array(4).fill(defaultOffset);
1063
+ const sourceOuterRectangle = RectangleClient.inflate(sourceRectangle, defaultOffset * 2);
1064
+ const targetOuterRectangle = RectangleClient.inflate(targetRectangle, defaultOffset * 2);
1065
+ const isHit = RectangleClient.isHit(sourceOuterRectangle, targetOuterRectangle);
1066
+ if (isHit) {
1067
+ const leftToRight = sourceRectangle.x - (targetRectangle.x + targetRectangle.width);
1068
+ const rightToLeft = targetRectangle.x - (sourceRectangle.x + sourceRectangle.width);
1069
+ if (leftToRight > 0 && leftToRight < defaultOffset * 2) {
1070
+ const offset = leftToRight / 2;
1071
+ sourceOffset[3] = offset;
1072
+ targetOffset[1] = offset;
1073
+ }
1074
+ if (rightToLeft > 0 && rightToLeft < defaultOffset * 2) {
1075
+ const offset = rightToLeft / 2;
1076
+ targetOffset[3] = offset;
1077
+ sourceOffset[1] = offset;
1078
+ }
1079
+ const topToBottom = sourceRectangle.y - (targetRectangle.y + targetRectangle.height);
1080
+ const bottomToTop = targetRectangle.y - (sourceRectangle.y + sourceRectangle.height);
1081
+ if (topToBottom > 0 && topToBottom < defaultOffset * 2) {
1082
+ const offset = topToBottom / 2;
1083
+ sourceOffset[0] = offset;
1084
+ targetOffset[2] = offset;
1085
+ }
1086
+ if (bottomToTop > 0 && bottomToTop < defaultOffset * 2) {
1087
+ const offset = bottomToTop / 2;
1088
+ sourceOffset[2] = offset;
1089
+ targetOffset[0] = offset;
1090
+ }
1091
+ }
1092
+ return { sourceOffset, targetOffset };
1093
+ };
1094
+ const getNextPoint = (point, outerRectangle, direction) => {
1095
+ switch (direction) {
1096
+ case Direction.top: {
1097
+ return [point[0], outerRectangle.y];
1098
+ }
1099
+ case Direction.bottom: {
1100
+ return [point[0], outerRectangle.y + outerRectangle.height];
1101
+ }
1102
+ case Direction.right: {
1103
+ return [outerRectangle.x + outerRectangle.width, point[1]];
1104
+ }
1105
+ default: {
1106
+ return [outerRectangle.x, point[1]];
1107
+ }
1108
+ }
1109
+ };
728
1110
 
729
1111
  class CommonPluginElement extends PlaitPluginElementComponent {
730
1112
  constructor() {
@@ -804,10 +1186,10 @@ class ImageBaseComponent {
804
1186
  this.activeGenerator.destroy();
805
1187
  }
806
1188
  }
807
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: ImageBaseComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive }); }
808
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.3", type: ImageBaseComponent, inputs: { element: "element", imageItem: "imageItem", board: "board", isFocus: "isFocus", getRectangle: "getRectangle", hasResizeHandle: "hasResizeHandle" }, host: { classAttribute: "plait-image-container" }, ngImport: i0 }); }
1189
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ImageBaseComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive }); }
1190
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ImageBaseComponent, inputs: { element: "element", imageItem: "imageItem", board: "board", isFocus: "isFocus", getRectangle: "getRectangle", hasResizeHandle: "hasResizeHandle" }, host: { classAttribute: "plait-image-container" }, ngImport: i0 }); }
809
1191
  }
810
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: ImageBaseComponent, decorators: [{
1192
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ImageBaseComponent, decorators: [{
811
1193
  type: Directive,
812
1194
  args: [{
813
1195
  host: {
@@ -836,5 +1218,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImpor
836
1218
  * Generated bundle index. Do not edit.
837
1219
  */
838
1220
 
839
- export { ActiveGenerator, BASE, BoardCreationMode, CommonPluginElement, Generator, IS_RESIZING, ImageBaseComponent, ImageGenerator, MediaKeys, PICTURE_ACCEPTED_UPLOAD_SIZE, PRIMARY_COLOR, PropertyTransforms, RESIZE_HANDLE_DIAMETER, ResizeCursorClass, ResizeHandle, WithCommonPluginKey, WithTextPluginKey, acceptImageTypes, addResizing, buildImage, calculatePolylineLength, getCreationMode, getDirection, getDirectionBetweenPointAndPoint, getDirectionByPointOfRectangle, getDirectionByVector, getDirectionFactor, getEdgeCenter, getFactorByPoints, getOppositeDirection, getPointByVector, getPointOnPolyline, getPoints, getRatioByPoint, getRectangleByPoints, getRectangleResizeHandleRefs, getTextEditors, getTextManages, hasAfterDraw, isDelete, isDndMode, isDrawingMode, isEnterHotkey, isExpandHotkey, isPointOnLineSegment, isResizing, isResizingByCondition, isSpaceHotkey, isTabHotkey, isVirtualKey, normalizeShapePoints, removeResizing, rotateVectorAnti90, selectImage, setCreationMode, withResize };
1221
+ export { AStar, ActiveGenerator, BASE, BoardCreationMode, CommonPluginElement, DEFAULT_ROUTE_MARGIN, Generator, IS_RESIZING, ImageBaseComponent, ImageGenerator, MediaKeys, PICTURE_ACCEPTED_UPLOAD_SIZE, PRIMARY_COLOR, PointGraph, PointNode, PriorityQueue, PropertyTransforms, RESIZE_HANDLE_DIAMETER, ResizeCursorClass, ResizeHandle, WithCommonPluginKey, WithTextPluginKey, acceptImageTypes, addElementOfFocusedImage, addResizing, buildImage, calculatePolylineLength, createGraph, generateElbowLineRoute, getCreationMode, getDirection, getDirectionBetweenPointAndPoint, getDirectionByPointOfRectangle, getDirectionByVector, getDirectionFactor, getEdgeCenter, getElementOfFocusedImage, getFactorByPoints, getGraphPoints, getNextPoint, getOppositeDirection, getPointByVector, getPointOnPolyline, getPoints, getRatioByPoint, getRectangleByPoints, getRectangleResizeHandleRefs, getTextEditors, getTextManages, hasAfterDraw, isDelete, isDndMode, isDrawingMode, isEnterHotkey, isExpandHotkey, isPointOnLineSegment, isResizing, isResizingByCondition, isSpaceHotkey, isTabHotkey, isVirtualKey, normalizeShapePoints, reduceRouteMargin, removeDuplicatePoints, removeElementOfFocusedImage, removeResizing, rotateVectorAnti90, selectImage, setCreationMode, withResize };
840
1222
  //# sourceMappingURL=plait-common.mjs.map