@plait/draw 0.32.0 → 0.33.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 (41) hide show
  1. package/constants/geometry.d.ts +1 -0
  2. package/constants/index.d.ts +1 -0
  3. package/constants/theme.d.ts +26 -0
  4. package/esm2022/constants/geometry.mjs +2 -1
  5. package/esm2022/constants/index.mjs +2 -1
  6. package/esm2022/constants/theme.mjs +28 -0
  7. package/esm2022/generators/auto-complete.generator.mjs +44 -0
  8. package/esm2022/generators/geometry-shape.generator.mjs +4 -4
  9. package/esm2022/generators/line-active.generator.mjs +2 -2
  10. package/esm2022/generators/line.generator.mjs +2 -2
  11. package/esm2022/geometry.component.mjs +14 -8
  12. package/esm2022/image.component.mjs +2 -2
  13. package/esm2022/interfaces/index.mjs +3 -3
  14. package/esm2022/line.component.mjs +10 -9
  15. package/esm2022/plugins/with-auto-complete-reaction.mjs +35 -0
  16. package/esm2022/plugins/with-auto-complete.mjs +61 -0
  17. package/esm2022/plugins/with-draw.mjs +10 -6
  18. package/esm2022/plugins/with-geometry-create.mjs +3 -6
  19. package/esm2022/plugins/with-line-create.mjs +9 -24
  20. package/esm2022/plugins/with-line-resize.mjs +7 -16
  21. package/esm2022/transforms/geometry.mjs +6 -3
  22. package/esm2022/transforms/index.mjs +4 -3
  23. package/esm2022/utils/geometry.mjs +24 -9
  24. package/esm2022/utils/hit.mjs +2 -2
  25. package/esm2022/utils/line.mjs +38 -11
  26. package/esm2022/utils/style/stroke.mjs +10 -5
  27. package/fesm2022/plait-draw.mjs +312 -122
  28. package/fesm2022/plait-draw.mjs.map +1 -1
  29. package/generators/auto-complete.generator.d.ts +13 -0
  30. package/generators/geometry-shape.generator.d.ts +1 -1
  31. package/generators/line-active.generator.d.ts +1 -1
  32. package/generators/line.generator.d.ts +1 -1
  33. package/geometry.component.d.ts +2 -0
  34. package/package.json +1 -1
  35. package/plugins/with-auto-complete-reaction.d.ts +2 -0
  36. package/plugins/with-auto-complete.d.ts +7 -0
  37. package/transforms/geometry.d.ts +2 -1
  38. package/transforms/index.d.ts +1 -0
  39. package/utils/geometry.d.ts +5 -1
  40. package/utils/line.d.ts +2 -0
  41. package/utils/style/stroke.d.ts +3 -2
@@ -1,5 +1,5 @@
1
- import { PlaitElement, ACTIVE_STROKE_WIDTH, PlaitBoard, setStrokeLinecap, isPointInPolygon, getNearestPointBetweenPointAndSegments, RectangleClient, isPointInEllipse, drawRectangle, drawRoundRectangle, isPointInRoundRectangle, Transforms, clearSelectedElement, addSelectedElement, PlaitNode, Point, BOARD_TO_HOST, transformPoint, toPoint, idCreator, createG, BoardTransforms, PlaitPointerType, preventTouchMove, createForeignObject, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, distanceBetweenPointAndSegment, arrowPoints, createPath, drawLinearPath, distanceBetweenPointAndPoint, rotate, getElementById, distanceBetweenPointAndSegments, createMask, createRect, findElements, getSelectedElements, isPolylineHitRectangle, isSelectionMoving, PlaitPluginElementComponent, setClipboardData, getDataFromClipboard, depthFirstRecursion, getIsRecursionFunc, getHitElementByPoint } from '@plait/core';
2
- import { getRectangleByPoints, Generator, normalizeShapePoints, isDndMode, isDrawingMode, getExtendPoint, getFactorByPoints, getDirectionByVector, getOppositeDirection, getDirectionFactor, DEFAULT_ROUTE_MARGIN, reduceRouteMargin, getNextPoint, generateElbowLineRoute, getPoints, removeDuplicatePoints, getPointByVector, getPointOnPolyline, getDirectionByPointOfRectangle, rotateVectorAnti90, TRANSPARENT, CommonPluginElement, ActiveGenerator, WithTextPluginKey, RESIZE_HANDLE_DIAMETER, PRIMARY_COLOR, isVirtualKey, isDelete, isSpaceHotkey, acceptImageTypes, getElementOfFocusedImage, buildImage, getRectangleResizeHandleRefs, ResizeHandle, withResize, isResizingByCondition, getRatioByPoint, ImageGenerator } from '@plait/common';
1
+ import { PlaitElement, ACTIVE_STROKE_WIDTH, ThemeColorMode, PlaitBoard, setStrokeLinecap, isPointInPolygon, getNearestPointBetweenPointAndSegments, RectangleClient, isPointInEllipse, drawRectangle, drawRoundRectangle, isPointInRoundRectangle, Transforms, clearSelectedElement, addSelectedElement, PlaitNode, Point, BOARD_TO_HOST, transformPoint, toPoint, idCreator, createG, BoardTransforms, PlaitPointerType, preventTouchMove, createForeignObject, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, distanceBetweenPointAndSegment, arrowPoints, createPath, drawLinearPath, distanceBetweenPointAndPoint, rotate, depthFirstRecursion, getIsRecursionFunc, getElementById, Direction, catmullRomFitting, distanceBetweenPointAndSegments, createMask, createRect, findElements, getSelectedElements, isPolylineHitRectangle, isSelectionMoving, PlaitPluginElementComponent, setClipboardData, getDataFromClipboard, getHitElementByPoint, temporaryDisableSelection } from '@plait/core';
2
+ import { getRectangleByPoints, Generator, normalizeShapePoints, isDndMode, isDrawingMode, RESIZE_HANDLE_DIAMETER, getExtendPoint, getFactorByPoints, getRectangleResizeHandleRefs, getDirectionByVector, getOppositeDirection, getDirectionFactor, DEFAULT_ROUTE_MARGIN, reduceRouteMargin, getNextPoint, generateElbowLineRoute, getPoints, removeDuplicatePoints, getPointByVector, getPointOnPolyline, getDirectionByPointOfRectangle, rotateVectorAnti90, TRANSPARENT, CommonPluginElement, ActiveGenerator, WithTextPluginKey, PRIMARY_COLOR, isVirtualKey, isDelete, isSpaceHotkey, acceptImageTypes, getElementOfFocusedImage, buildImage, ResizeHandle, withResize, isResizingByCondition, getRatioByPoint, ImageGenerator } from '@plait/common';
3
3
  import { AlignEditor, Alignment, DEFAULT_FONT_SIZE, buildText, TextManage, getTextFromClipboard, getTextSize } from '@plait/text';
4
4
  import { isKeyHotkey } from 'is-hotkey';
5
5
  import { pointsOnBezierCurves } from 'points-on-curve';
@@ -122,6 +122,7 @@ const DefaultFlowchartPropertyMap = {
122
122
  [FlowchartSymbols.delay]: DefaultFlowchartProperty,
123
123
  [FlowchartSymbols.storedData]: DefaultFlowchartProperty
124
124
  };
125
+ const REACTION_MARGIN = -4;
125
126
 
126
127
  const getGeometryPointers = () => {
127
128
  return [...Object.keys(BasicShapes), ...Object.keys(FlowchartSymbols)];
@@ -138,6 +139,33 @@ const getLinePointers = () => {
138
139
 
139
140
  const DEFAULT_IMAGE_WIDTH = 1000;
140
141
 
142
+ const DrawThemeColors = {
143
+ [ThemeColorMode.default]: {
144
+ strokeColor: '#333333',
145
+ fill: '#FFFFFF'
146
+ },
147
+ [ThemeColorMode.colorful]: {
148
+ strokeColor: '#06ADBF',
149
+ fill: '#CDEFF2'
150
+ },
151
+ [ThemeColorMode.soft]: {
152
+ strokeColor: '#6D89C1',
153
+ fill: '#DADFEB'
154
+ },
155
+ [ThemeColorMode.retro]: {
156
+ strokeColor: '#E9C358',
157
+ fill: '#F6EDCF'
158
+ },
159
+ [ThemeColorMode.dark]: {
160
+ strokeColor: '#FFFFFF',
161
+ fill: '#434343'
162
+ },
163
+ [ThemeColorMode.starry]: {
164
+ strokeColor: '#42ABE5',
165
+ fill: '#163F5A'
166
+ }
167
+ };
168
+
141
169
  const getStrokeWidthByElement = (element) => {
142
170
  if (PlaitDrawElement.isText(element)) {
143
171
  return 0;
@@ -145,12 +173,16 @@ const getStrokeWidthByElement = (element) => {
145
173
  const strokeWidth = element.strokeWidth || DefaultGeometryStyle.strokeWidth;
146
174
  return strokeWidth;
147
175
  };
148
- const getStrokeColorByElement = (element) => {
149
- const strokeColor = element.strokeColor || DefaultGeometryStyle.strokeColor;
176
+ const getStrokeColorByElement = (board, element) => {
177
+ const defaultColor = getDrawDefaultStrokeColor(board.theme.themeColorMode);
178
+ const strokeColor = element.strokeColor || defaultColor;
150
179
  return strokeColor;
151
180
  };
152
- const getFillByElement = (element) => {
153
- const fill = element.fill || DefaultGeometryStyle.fill;
181
+ const getFillByElement = (board, element) => {
182
+ const defaultFill = PlaitDrawElement.isFlowchart(element)
183
+ ? getFlowchartDefaultFill(board.theme.themeColorMode)
184
+ : DefaultGeometryStyle.fill;
185
+ const fill = element.fill || defaultFill;
154
186
  return fill;
155
187
  };
156
188
  const getLineDashByElement = (element) => {
@@ -1172,15 +1204,15 @@ class GeometryShapeGenerator extends Generator {
1172
1204
  canDraw(element, data) {
1173
1205
  return true;
1174
1206
  }
1175
- baseDraw(element, data) {
1207
+ draw(element, data) {
1176
1208
  const rectangle = getRectangleByPoints(element.points);
1177
1209
  const shape = element.shape;
1178
1210
  if (shape === BasicShapes.text) {
1179
1211
  return;
1180
1212
  }
1181
1213
  const strokeWidth = getStrokeWidthByElement(element);
1182
- const strokeColor = getStrokeColorByElement(element);
1183
- const fill = getFillByElement(element);
1214
+ const strokeColor = getStrokeColorByElement(this.board, element);
1215
+ const fill = getFillByElement(this.board, element);
1184
1216
  const strokeLineDash = getLineDashByElement(element);
1185
1217
  return drawGeometry(this.board, RectangleClient.inflate(rectangle, -strokeWidth), shape, {
1186
1218
  stroke: strokeColor,
@@ -1193,7 +1225,6 @@ class GeometryShapeGenerator extends Generator {
1193
1225
 
1194
1226
  const insertGeometry = (board, points, shape) => {
1195
1227
  let newElement = createGeometryElement(shape, points, '', {
1196
- strokeColor: DefaultBasicShapeProperty.strokeColor,
1197
1228
  strokeWidth: DefaultBasicShapeProperty.strokeWidth
1198
1229
  });
1199
1230
  Transforms.insertNode(board, newElement, [board.children.length]);
@@ -1216,6 +1247,10 @@ const resizeGeometry = (board, points, textHeight, path) => {
1216
1247
  }
1217
1248
  Transforms.setNode(board, newProperties, path);
1218
1249
  };
1250
+ const transformShape = (board, element, shape) => {
1251
+ const path = PlaitBoard.findPath(board, element);
1252
+ Transforms.setNode(board, { shape }, path);
1253
+ };
1219
1254
 
1220
1255
  const normalizePoints = (board, element, width, textHeight) => {
1221
1256
  let points = element.points;
@@ -1320,7 +1355,8 @@ const DrawTransforms = {
1320
1355
  setLineTexts,
1321
1356
  removeLineText,
1322
1357
  setLineMark,
1323
- insertImage
1358
+ insertImage,
1359
+ transformShape
1324
1360
  };
1325
1361
 
1326
1362
  const withGeometryCreateByDrag = (board) => {
@@ -1344,10 +1380,9 @@ const withGeometryCreateByDrag = (board) => {
1344
1380
  }
1345
1381
  else {
1346
1382
  const temporaryElement = createGeometryElement(pointer, points, '', {
1347
- strokeColor: DefaultBasicShapeProperty.strokeColor,
1348
1383
  strokeWidth: DefaultBasicShapeProperty.strokeWidth
1349
1384
  });
1350
- geometryGenerator.draw(temporaryElement, geometryShapeG);
1385
+ geometryGenerator.processDrawing(temporaryElement, geometryShapeG);
1351
1386
  PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
1352
1387
  }
1353
1388
  }
@@ -1420,10 +1455,9 @@ const withGeometryCreateByDrawing = (board) => {
1420
1455
  if (drawMode && pointer !== BasicShapes.text) {
1421
1456
  const points = normalizeShapePoints([start, movingPoint], isShift);
1422
1457
  temporaryElement = createGeometryElement(pointer, points, '', {
1423
- strokeColor: DefaultBasicShapeProperty.strokeColor,
1424
1458
  strokeWidth: DefaultBasicShapeProperty.strokeWidth
1425
1459
  });
1426
- geometryGenerator.draw(temporaryElement, geometryShapeG);
1460
+ geometryGenerator.processDrawing(temporaryElement, geometryShapeG);
1427
1461
  PlaitBoard.getElementActiveHost(board).append(geometryShapeG);
1428
1462
  }
1429
1463
  pointerMove(event);
@@ -1438,7 +1472,6 @@ const withGeometryCreateByDrawing = (board) => {
1438
1472
  const points = getDefaultGeometryPoints(pointer, targetPoint);
1439
1473
  if (pointer !== BasicShapes.text) {
1440
1474
  temporaryElement = createGeometryElement(pointer, points, '', {
1441
- strokeColor: DefaultBasicShapeProperty.strokeColor,
1442
1475
  strokeWidth: DefaultBasicShapeProperty.strokeWidth
1443
1476
  });
1444
1477
  }
@@ -1502,10 +1535,6 @@ const createGeometryElement = (shape, points, text, options) => {
1502
1535
  textOptions = { autoSize: true };
1503
1536
  alignment = undefined;
1504
1537
  }
1505
- let flowchartOptions = {};
1506
- if (getFlowchartPointers().includes(shape)) {
1507
- flowchartOptions = { fill: '#ffffff' };
1508
- }
1509
1538
  return {
1510
1539
  id: idCreator(),
1511
1540
  type: 'geometry',
@@ -1516,8 +1545,7 @@ const createGeometryElement = (shape, points, text, options) => {
1516
1545
  text: buildText(text, alignment),
1517
1546
  points,
1518
1547
  ...textOptions,
1519
- ...options,
1520
- ...flowchartOptions
1548
+ ...options
1521
1549
  };
1522
1550
  };
1523
1551
  const getPointsByCenterPoint = (point, width, height) => {
@@ -1649,6 +1677,26 @@ const createDefaultFlowchart = (point) => {
1649
1677
  ], { marker: LineMarkerType.none, connection: [0.5, 1], boundId: processElement2.id }, { marker: LineMarkerType.arrow, connection: [1, 0.5], boundId: endElement.id }, [], lineOptions);
1650
1678
  return [startElement, processElement1, decisionElement, processElement2, endElement, line1, line2, line3, line4, line5];
1651
1679
  };
1680
+ const getAutoCompletePoints = (element) => {
1681
+ const AutoCompleteMargin = (12 + RESIZE_HANDLE_DIAMETER / 2) * 2;
1682
+ let rectangle = getRectangleByPoints(element.points);
1683
+ rectangle = RectangleClient.inflate(rectangle, AutoCompleteMargin);
1684
+ return RectangleClient.getEdgeCenterPoints(rectangle);
1685
+ };
1686
+ const getHitIndexOfAutoCompletePoint = (movingPoint, points) => {
1687
+ return points.findIndex(point => {
1688
+ const movingRectangle = RectangleClient.toRectangleClient([movingPoint]);
1689
+ let rectangle = RectangleClient.toRectangleClient([point]);
1690
+ rectangle = RectangleClient.inflate(rectangle, RESIZE_HANDLE_DIAMETER);
1691
+ return RectangleClient.isHit(movingRectangle, rectangle);
1692
+ });
1693
+ };
1694
+ const getDrawDefaultStrokeColor = (theme) => {
1695
+ return DrawThemeColors[theme].strokeColor;
1696
+ };
1697
+ const getFlowchartDefaultFill = (theme) => {
1698
+ return DrawThemeColors[theme].fill;
1699
+ };
1652
1700
 
1653
1701
  const MAX_LENGTH = 100;
1654
1702
  const drawLineArrow = (element, points, options) => {
@@ -1765,6 +1813,41 @@ const drawHollowTriangleArrow = (source, target, options) => {
1765
1813
  return drawLinearPath([pointLeft, pointRight, target], { ...options, fill: 'white' }, true);
1766
1814
  };
1767
1815
 
1816
+ class LineShapeGenerator extends Generator {
1817
+ canDraw(element, data) {
1818
+ return true;
1819
+ }
1820
+ draw(element, data) {
1821
+ let lineG;
1822
+ lineG = drawLine(this.board, element);
1823
+ return lineG;
1824
+ }
1825
+ }
1826
+
1827
+ const getHitGeometryResizeHandleRef = (board, element, point) => {
1828
+ const rectangle = getRectangleByPoints(element.points);
1829
+ const resizeHandleRefs = getRectangleResizeHandleRefs(rectangle, RESIZE_HANDLE_DIAMETER);
1830
+ const result = resizeHandleRefs.find(resizeHandleRef => {
1831
+ return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), resizeHandleRef.rectangle);
1832
+ });
1833
+ return result;
1834
+ };
1835
+ const getHitOutlineGeometry = (board, point, offset = 0) => {
1836
+ let geometry = null;
1837
+ depthFirstRecursion(board, node => {
1838
+ if (PlaitDrawElement.isGeometry(node) || PlaitDrawElement.isImage(node)) {
1839
+ let client = getRectangleByPoints(node.points);
1840
+ client = RectangleClient.getOutlineRectangle(client, offset);
1841
+ const shape = getShape(node);
1842
+ const isHit = getEngine(shape).isHit(client, point);
1843
+ if (isHit) {
1844
+ geometry = node;
1845
+ }
1846
+ }
1847
+ }, getIsRecursionFunc(board), true);
1848
+ return geometry;
1849
+ };
1850
+
1768
1851
  const createLineElement = (shape, points, source, target, texts, options) => {
1769
1852
  return {
1770
1853
  id: idCreator(),
@@ -1799,7 +1882,7 @@ const getLineHandleRefPair = (board, element) => {
1799
1882
  let targetPoint = targetBoundElement
1800
1883
  ? getConnectionPoint(targetBoundElement, element.target.connection)
1801
1884
  : element.points[element.points.length - 1];
1802
- let sourceDirection = getDirectionByVector([targetPoint[0] - sourcePoint[0], targetPoint[1] - sourcePoint[1]]);
1885
+ let sourceDirection = getDirectionByVector([targetPoint[0] - sourcePoint[0], targetPoint[1] - sourcePoint[1]]) || Direction.right;
1803
1886
  let targetDirection = getOppositeDirection(sourceDirection);
1804
1887
  const sourceFactor = getDirectionFactor(sourceDirection);
1805
1888
  const targetFactor = getDirectionFactor(targetDirection);
@@ -1911,12 +1994,9 @@ const getCurvePoints = (board, element) => {
1911
1994
  return pointsOnBezierCurves(curvePoints);
1912
1995
  }
1913
1996
  else {
1914
- //TODO 直接获取贝塞尔曲线上高密度点
1915
- const points = PlaitLine.getPoints(board, element);
1916
- const draw = PlaitBoard.getRoughSVG(board).generator.curve(points);
1917
- let bezierPoints = transformOpsToPoints(draw.sets[0].ops);
1918
- bezierPoints = removeDuplicatePoints(bezierPoints);
1919
- return pointsOnBezierCurves(bezierPoints);
1997
+ const allPoints = PlaitLine.getPoints(board, element);
1998
+ const points = catmullRomFitting(allPoints);
1999
+ return pointsOnBezierCurves(points);
1920
2000
  }
1921
2001
  };
1922
2002
  const transformOpsToPoints = (ops) => {
@@ -1958,7 +2038,7 @@ const isHitLineText = (board, element, point) => {
1958
2038
  };
1959
2039
  const drawLine = (board, element) => {
1960
2040
  const strokeWidth = getStrokeWidthByElement(element);
1961
- const strokeColor = getStrokeColorByElement(element);
2041
+ const strokeColor = getStrokeColorByElement(board, element);
1962
2042
  const strokeLineDash = getLineDashByElement(element);
1963
2043
  const options = { stroke: strokeColor, strokeWidth, strokeLineDash };
1964
2044
  const lineG = createG();
@@ -2092,6 +2172,33 @@ const getVectorByConnection = (boundElement, connection) => {
2092
2172
  }
2093
2173
  return vector;
2094
2174
  };
2175
+ const alignPoints = (basePoint, movingPoint) => {
2176
+ const offset = 3;
2177
+ const newPoint = [...movingPoint];
2178
+ if (Point.isVerticalAlign(newPoint, basePoint, offset)) {
2179
+ newPoint[0] = basePoint[0];
2180
+ }
2181
+ if (Point.isHorizontalAlign(newPoint, basePoint, offset)) {
2182
+ newPoint[1] = basePoint[1];
2183
+ }
2184
+ return newPoint;
2185
+ };
2186
+ const handleLineCreating = (board, lineShape, startPoint, movingPoint, sourceElement, lineShapeG) => {
2187
+ const hitElement = getHitOutlineGeometry(board, movingPoint, REACTION_MARGIN);
2188
+ const targetConnection = hitElement ? transformPointToConnection(board, movingPoint, hitElement) : undefined;
2189
+ const connection = sourceElement ? transformPointToConnection(board, startPoint, sourceElement) : undefined;
2190
+ const targetBoundId = hitElement ? hitElement.id : undefined;
2191
+ const lineGenerator = new LineShapeGenerator(board);
2192
+ const temporaryLineElement = createLineElement(lineShape, [startPoint, movingPoint], { marker: LineMarkerType.none, connection: connection, boundId: sourceElement?.id }, { marker: LineMarkerType.arrow, connection: targetConnection, boundId: targetBoundId }, [], {
2193
+ strokeWidth: DefaultLineStyle.strokeWidth
2194
+ });
2195
+ const linePoints = getLinePoints(board, temporaryLineElement);
2196
+ const otherPoint = linePoints[0];
2197
+ temporaryLineElement.points[1] = alignPoints(otherPoint, movingPoint);
2198
+ lineGenerator.processDrawing(temporaryLineElement, lineShapeG);
2199
+ PlaitBoard.getElementActiveHost(board).append(lineShapeG);
2200
+ return temporaryLineElement;
2201
+ };
2095
2202
 
2096
2203
  const getSelectedDrawElements = (board) => {
2097
2204
  const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isDrawElement(value));
@@ -2146,7 +2253,7 @@ const isRectangleHitDrawElement = (board, element, selection) => {
2146
2253
  };
2147
2254
  const isHitDrawElement = (board, element, point) => {
2148
2255
  if (PlaitDrawElement.isGeometry(element)) {
2149
- const fill = getFillByElement(element);
2256
+ const fill = getFillByElement(board, element);
2150
2257
  // when shape equals text, fill is not allowed
2151
2258
  if (fill !== DefaultGeometryStyle.fill && fill !== TRANSPARENT && !PlaitDrawElement.isText(element)) {
2152
2259
  return isRectangleHitDrawElement(board, element, { anchor: point, focus: point });
@@ -2273,13 +2380,54 @@ const PlaitDrawElement = {
2273
2380
  return PlaitDrawElement.isImage(value) || PlaitDrawElement.isGeometry(value);
2274
2381
  },
2275
2382
  isBaseShape: (value) => {
2276
- return Object.keys(BasicShapes).includes(value.type);
2383
+ return Object.keys(BasicShapes).includes(value.shape);
2277
2384
  },
2278
2385
  isFlowchart: (value) => {
2279
- return Object.keys(FlowchartSymbols).includes(value.type);
2386
+ return Object.keys(FlowchartSymbols).includes(value.shape);
2280
2387
  }
2281
2388
  };
2282
2389
 
2390
+ class AutoCompleteGenerator extends Generator {
2391
+ constructor(board) {
2392
+ super(board);
2393
+ this.board = board;
2394
+ this.hoverElement = null;
2395
+ }
2396
+ canDraw(element, data) {
2397
+ const selectedElements = getSelectedElements(this.board);
2398
+ if (data.selected && selectedElements.length === 1 && !isSelectionMoving(this.board)) {
2399
+ return true;
2400
+ }
2401
+ else {
2402
+ return false;
2403
+ }
2404
+ }
2405
+ draw(element, data) {
2406
+ this.autoCompleteG = createG();
2407
+ const middlePoints = getAutoCompletePoints(element);
2408
+ middlePoints.forEach((point, index) => {
2409
+ const circle = drawCircle(PlaitBoard.getRoughSVG(this.board), point, RESIZE_HANDLE_DIAMETER, {
2410
+ stroke: 'none',
2411
+ fill: '#6698FF4d',
2412
+ fillStyle: 'solid'
2413
+ });
2414
+ circle.classList.add(`geometry-auto-complete-${index}`);
2415
+ this.autoCompleteG.appendChild(circle);
2416
+ });
2417
+ return this.autoCompleteG;
2418
+ }
2419
+ removeAutoCompleteG(index) {
2420
+ this.hoverElement = this.autoCompleteG.querySelector(`.geometry-auto-complete-${index}`);
2421
+ this.hoverElement.style.visibility = 'hidden';
2422
+ }
2423
+ recoverAutoCompleteG() {
2424
+ if (this.hoverElement) {
2425
+ this.hoverElement.style.visibility = 'visible';
2426
+ this.hoverElement = null;
2427
+ }
2428
+ }
2429
+ }
2430
+
2283
2431
  class GeometryComponent extends CommonPluginElement {
2284
2432
  get textManage() {
2285
2433
  return this.getTextManages()[0];
@@ -2321,33 +2469,38 @@ class GeometryComponent extends CommonPluginElement {
2321
2469
  return selectedElements.length === 1 && !isSelectionMoving(this.board);
2322
2470
  }
2323
2471
  });
2472
+ this.autoCompleteGenerator = new AutoCompleteGenerator(this.board);
2324
2473
  this.shapeGenerator = new GeometryShapeGenerator(this.board);
2325
2474
  this.initializeTextManage();
2326
2475
  }
2327
2476
  ngOnInit() {
2328
2477
  super.ngOnInit();
2329
2478
  this.initializeGenerator();
2330
- this.shapeGenerator.draw(this.element, this.g);
2331
- this.activeGenerator.draw(this.element, this.g, { selected: this.selected });
2479
+ this.shapeGenerator.processDrawing(this.element, this.g);
2480
+ this.activeGenerator.processDrawing(this.element, this.g, { selected: this.selected });
2481
+ this.autoCompleteGenerator.processDrawing(this.element, this.g, { selected: this.selected });
2332
2482
  this.drawText();
2333
2483
  }
2334
2484
  onContextChanged(value, previous) {
2335
- if (value.element !== previous.element) {
2336
- this.shapeGenerator.draw(this.element, this.g);
2337
- this.activeGenerator.draw(this.element, this.g, { selected: this.selected });
2485
+ const isChangeTheme = this.board.operations.find(op => op.type === 'set_theme');
2486
+ if (value.element !== previous.element || isChangeTheme) {
2487
+ this.shapeGenerator.processDrawing(this.element, this.g);
2488
+ this.activeGenerator.processDrawing(this.element, this.g, { selected: this.selected });
2489
+ this.autoCompleteGenerator.processDrawing(this.element, this.g, { selected: this.selected });
2338
2490
  this.updateText();
2339
2491
  }
2340
2492
  else {
2341
2493
  const hasSameSelected = value.selected === previous.selected;
2342
2494
  const hasSameHandleState = this.activeGenerator.options.hasResizeHandle() === this.activeGenerator.hasResizeHandle;
2343
2495
  if (!hasSameSelected || !hasSameHandleState) {
2344
- this.activeGenerator.draw(this.element, this.g, { selected: this.selected });
2496
+ this.activeGenerator.processDrawing(this.element, this.g, { selected: this.selected });
2497
+ this.autoCompleteGenerator.processDrawing(this.element, this.g, { selected: this.selected });
2345
2498
  }
2346
2499
  }
2347
2500
  }
2348
2501
  editText() {
2349
2502
  this.textManage.edit();
2350
- this.activeGenerator.draw(this.element, this.g, { selected: this.selected });
2503
+ this.activeGenerator.processDrawing(this.element, this.g, { selected: this.selected });
2351
2504
  }
2352
2505
  drawText() {
2353
2506
  this.textManage.draw(this.element.text);
@@ -2408,17 +2561,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
2408
2561
  }]
2409
2562
  }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
2410
2563
 
2411
- class LineShapeGenerator extends Generator {
2412
- canDraw(element, data) {
2413
- return true;
2414
- }
2415
- baseDraw(element, data) {
2416
- let lineG;
2417
- lineG = drawLine(this.board, element);
2418
- return lineG;
2419
- }
2420
- }
2421
-
2422
2564
  class LineActiveGenerator extends Generator {
2423
2565
  constructor() {
2424
2566
  super(...arguments);
@@ -2432,7 +2574,7 @@ class LineActiveGenerator extends Generator {
2432
2574
  return false;
2433
2575
  }
2434
2576
  }
2435
- baseDraw(element, data) {
2577
+ draw(element, data) {
2436
2578
  const activeG = createG();
2437
2579
  if (this.hasResizeHandle) {
2438
2580
  activeG.classList.add('active');
@@ -2515,8 +2657,8 @@ class LineComponent extends PlaitPluginElementComponent {
2515
2657
  }
2516
2658
  ngOnInit() {
2517
2659
  this.initializeGenerator();
2518
- this.shapeGenerator.draw(this.element, this.g);
2519
- this.activeGenerator.draw(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2660
+ this.shapeGenerator.processDrawing(this.element, this.g);
2661
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2520
2662
  super.ngOnInit();
2521
2663
  this.boundedElements = this.getBoundedElements();
2522
2664
  this.drawText();
@@ -2541,21 +2683,22 @@ class LineComponent extends PlaitPluginElementComponent {
2541
2683
  const boundedElements = this.getBoundedElements();
2542
2684
  const isBoundedElementsChanged = boundedElements.source !== this.boundedElements.source || boundedElements.target !== this.boundedElements.target;
2543
2685
  this.boundedElements = boundedElements;
2544
- if (value.element !== previous.element) {
2545
- this.shapeGenerator.draw(this.element, this.g);
2546
- this.activeGenerator.draw(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2686
+ const isChangeTheme = this.board.operations.find(op => op.type === 'set_theme');
2687
+ if (value.element !== previous.element || isChangeTheme) {
2688
+ this.shapeGenerator.processDrawing(this.element, this.g);
2689
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2547
2690
  this.updateText(previous.element.texts, value.element.texts);
2548
2691
  this.updateTextRectangle();
2549
2692
  }
2550
2693
  if (isBoundedElementsChanged) {
2551
- this.shapeGenerator.draw(this.element, this.g);
2552
- this.activeGenerator.draw(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2694
+ this.shapeGenerator.processDrawing(this.element, this.g);
2695
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2553
2696
  this.updateTextRectangle();
2554
2697
  return;
2555
2698
  }
2556
2699
  if (!isSelectionMoving(this.board)) {
2557
2700
  this.activeGenerator.hasResizeHandle = this.hasResizeHandle();
2558
- this.activeGenerator.draw(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2701
+ this.activeGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
2559
2702
  }
2560
2703
  }
2561
2704
  hasResizeHandle() {
@@ -2804,35 +2947,10 @@ const getBoundedLineElements = (board, plaitShapes) => {
2804
2947
  return lines.filter(line => plaitShapes.find(shape => PlaitLine.isBoundElementOfSource(line, shape) || PlaitLine.isBoundElementOfTarget(line, shape)));
2805
2948
  };
2806
2949
 
2807
- const getHitGeometryResizeHandleRef = (board, element, point) => {
2808
- const rectangle = getRectangleByPoints(element.points);
2809
- const resizeHandleRefs = getRectangleResizeHandleRefs(rectangle, RESIZE_HANDLE_DIAMETER);
2810
- const result = resizeHandleRefs.find(resizeHandleRef => {
2811
- return RectangleClient.isHit(RectangleClient.toRectangleClient([point, point]), resizeHandleRef.rectangle);
2812
- });
2813
- return result;
2814
- };
2815
- const getHitOutlineGeometry = (board, point, offset = 0) => {
2816
- let geometry = null;
2817
- depthFirstRecursion(board, node => {
2818
- if (PlaitDrawElement.isGeometry(node) || PlaitDrawElement.isImage(node)) {
2819
- let client = getRectangleByPoints(node.points);
2820
- client = RectangleClient.getOutlineRectangle(client, offset);
2821
- const shape = getShape(node);
2822
- const isHit = getEngine(shape).isHit(client, point);
2823
- if (isHit) {
2824
- geometry = node;
2825
- }
2826
- }
2827
- }, getIsRecursionFunc(board), true);
2828
- return geometry;
2829
- };
2830
-
2831
2950
  const withLineCreateByDraw = (board) => {
2832
2951
  const { pointerDown, pointerMove, pointerUp } = board;
2833
2952
  let start = null;
2834
- let sourceRef = {};
2835
- let targetRef = {};
2953
+ let sourceElement;
2836
2954
  let lineShapeG = null;
2837
2955
  let temporaryElement = null;
2838
2956
  board.pointerDown = (event) => {
@@ -2841,10 +2959,9 @@ const withLineCreateByDraw = (board) => {
2841
2959
  if (isLinePointer && isDrawingMode(board)) {
2842
2960
  const point = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
2843
2961
  start = point;
2844
- const hitElement = getHitOutlineGeometry(board, point, -4);
2962
+ const hitElement = getHitOutlineGeometry(board, point, REACTION_MARGIN);
2845
2963
  if (hitElement) {
2846
- sourceRef.connection = transformPointToConnection(board, point, hitElement);
2847
- sourceRef.boundId = hitElement.id;
2964
+ sourceElement = hitElement;
2848
2965
  }
2849
2966
  preventTouchMove(board, event, true);
2850
2967
  }
@@ -2853,19 +2970,10 @@ const withLineCreateByDraw = (board) => {
2853
2970
  board.pointerMove = (event) => {
2854
2971
  lineShapeG?.remove();
2855
2972
  lineShapeG = createG();
2856
- const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
2973
+ let movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
2857
2974
  if (start) {
2858
- const hitElement = getHitOutlineGeometry(board, movingPoint, -4);
2859
- targetRef.connection = hitElement ? transformPointToConnection(board, movingPoint, hitElement) : undefined;
2860
- targetRef.boundId = hitElement ? hitElement.id : undefined;
2861
- const lineGenerator = new LineShapeGenerator(board);
2862
2975
  const lineShape = PlaitBoard.getPointer(board);
2863
- temporaryElement = createLineElement(lineShape, [start, movingPoint], { marker: LineMarkerType.none, connection: sourceRef.connection, boundId: sourceRef?.boundId }, { marker: LineMarkerType.arrow, connection: targetRef.connection, boundId: targetRef?.boundId }, [], {
2864
- strokeColor: DefaultLineStyle.strokeColor,
2865
- strokeWidth: DefaultLineStyle.strokeWidth
2866
- });
2867
- lineGenerator.draw(temporaryElement, lineShapeG);
2868
- PlaitBoard.getElementActiveHost(board).append(lineShapeG);
2976
+ temporaryElement = handleLineCreating(board, lineShape, start, movingPoint, sourceElement, lineShapeG);
2869
2977
  }
2870
2978
  pointerMove(event);
2871
2979
  };
@@ -2878,9 +2986,8 @@ const withLineCreateByDraw = (board) => {
2878
2986
  }
2879
2987
  lineShapeG?.remove();
2880
2988
  lineShapeG = null;
2989
+ sourceElement = null;
2881
2990
  start = null;
2882
- sourceRef = {};
2883
- targetRef = {};
2884
2991
  temporaryElement = null;
2885
2992
  preventTouchMove(board, event, false);
2886
2993
  pointerUp(event);
@@ -3066,7 +3173,7 @@ const withLineResize = (board) => {
3066
3173
  if (resizeRef.handle === LineResizeHandle.source || resizeRef.handle === LineResizeHandle.target) {
3067
3174
  const object = resizeRef.handle === LineResizeHandle.source ? source : target;
3068
3175
  points[pointIndex] = resizeState.endTransformPoint;
3069
- const hitElement = getHitOutlineGeometry(board, resizeState.endTransformPoint, -4);
3176
+ const hitElement = getHitOutlineGeometry(board, resizeState.endTransformPoint, REACTION_MARGIN);
3070
3177
  if (hitElement) {
3071
3178
  object.connection = transformPointToConnection(board, resizeState.endTransformPoint, hitElement);
3072
3179
  object.boundId = hitElement.id;
@@ -3076,7 +3183,9 @@ const withLineResize = (board) => {
3076
3183
  object.boundId = undefined;
3077
3184
  if (points.length === 2) {
3078
3185
  let movingPoint = points[pointIndex];
3079
- const otherPoint = points[Number(!pointIndex)];
3186
+ const drawPoints = getLinePoints(board, resizeRef.element);
3187
+ const index = pointIndex === 0 ? drawPoints.length - 1 : pointIndex;
3188
+ const otherPoint = drawPoints[index];
3080
3189
  points[pointIndex] = alignPoints(otherPoint, movingPoint);
3081
3190
  }
3082
3191
  }
@@ -3093,17 +3202,6 @@ const withLineResize = (board) => {
3093
3202
  withResize(board, options);
3094
3203
  return board;
3095
3204
  };
3096
- const alignPoints = (basePoint, movingPoint) => {
3097
- const offset = 3;
3098
- const newPoint = [...movingPoint];
3099
- if (Point.isVerticalAlign(newPoint, basePoint, offset)) {
3100
- newPoint[0] = basePoint[0];
3101
- }
3102
- if (Point.isHorizontalAlign(newPoint, basePoint, offset)) {
3103
- newPoint[1] = basePoint[1];
3104
- }
3105
- return newPoint;
3106
- };
3107
3205
 
3108
3206
  const withLineBoundReaction = (board) => {
3109
3207
  const { pointerMove, pointerUp } = board;
@@ -3227,7 +3325,7 @@ class ImageComponent extends CommonPluginElement {
3227
3325
  ngOnInit() {
3228
3326
  super.ngOnInit();
3229
3327
  this.initializeGenerator();
3230
- this.imageGenerator.draw(this.element, this.g, this.viewContainerRef);
3328
+ this.imageGenerator.processDrawing(this.element, this.g, this.viewContainerRef);
3231
3329
  }
3232
3330
  onContextChanged(value, previous) {
3233
3331
  if (value.element !== previous.element) {
@@ -3261,6 +3359,96 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
3261
3359
  }]
3262
3360
  }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ChangeDetectorRef }]; } });
3263
3361
 
3362
+ const withAutoCompleteReaction = (board) => {
3363
+ const { pointerMove } = board;
3364
+ let reactionG = null;
3365
+ board.pointerMove = (event) => {
3366
+ reactionG?.remove();
3367
+ if (isSelectionMoving(board)) {
3368
+ pointerMove(event);
3369
+ return;
3370
+ }
3371
+ const selectedElements = getSelectedDrawElements(board);
3372
+ const movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3373
+ if (selectedElements.length === 1 && PlaitDrawElement.isGeometry(selectedElements[0])) {
3374
+ const points = getAutoCompletePoints(selectedElements[0]);
3375
+ const hitIndex = getHitIndexOfAutoCompletePoint(movingPoint, points);
3376
+ const hitPoint = points[hitIndex];
3377
+ const component = PlaitElement.getComponent(selectedElements[0]);
3378
+ component.autoCompleteGenerator.recoverAutoCompleteG();
3379
+ if (hitPoint) {
3380
+ component.autoCompleteGenerator.removeAutoCompleteG(hitIndex);
3381
+ reactionG = drawCircle(PlaitBoard.getRoughSVG(board), hitPoint, 10, {
3382
+ stroke: 'none',
3383
+ fill: '#6698FF80',
3384
+ fillStyle: 'solid'
3385
+ });
3386
+ PlaitBoard.getElementActiveHost(board).append(reactionG);
3387
+ }
3388
+ }
3389
+ pointerMove(event);
3390
+ };
3391
+ return board;
3392
+ };
3393
+
3394
+ const withAutoCompletePluginKey = 'plait-auto-complete-plugin-key';
3395
+ const withAutoComplete = (board) => {
3396
+ const { pointerDown, pointerMove, pointerUp } = board;
3397
+ const tolerance = 3;
3398
+ let startPoint = null;
3399
+ let lineShapeG = null;
3400
+ let sourceElement;
3401
+ let temporaryElement;
3402
+ board.pointerDown = (event) => {
3403
+ const selectedElements = getSelectedDrawElements(board);
3404
+ const clickPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3405
+ if (selectedElements.length === 1 && PlaitDrawElement.isGeometry(selectedElements[0])) {
3406
+ const points = getAutoCompletePoints(selectedElements[0]);
3407
+ const index = getHitIndexOfAutoCompletePoint(clickPoint, points);
3408
+ const hitPoint = points[index];
3409
+ if (hitPoint) {
3410
+ temporaryDisableSelection(board);
3411
+ startPoint = clickPoint;
3412
+ sourceElement = selectedElements[0];
3413
+ BoardTransforms.updatePointerType(board, LineShape.elbow);
3414
+ }
3415
+ }
3416
+ pointerDown(event);
3417
+ };
3418
+ board.pointerMove = (event) => {
3419
+ lineShapeG?.remove();
3420
+ lineShapeG = createG();
3421
+ let movingPoint = transformPoint(board, toPoint(event.x, event.y, PlaitBoard.getHost(board)));
3422
+ if (startPoint && sourceElement) {
3423
+ const distance = distanceBetweenPointAndPoint(...movingPoint, ...startPoint);
3424
+ if (distance > tolerance) {
3425
+ temporaryElement = handleLineCreating(board, LineShape.elbow, startPoint, movingPoint, sourceElement, lineShapeG);
3426
+ }
3427
+ }
3428
+ pointerMove(event);
3429
+ };
3430
+ board.pointerUp = event => {
3431
+ if (temporaryElement) {
3432
+ Transforms.insertNode(board, temporaryElement, [board.children.length]);
3433
+ clearSelectedElement(board);
3434
+ addSelectedElement(board, temporaryElement);
3435
+ const afterComplete = board.getPluginOptions(withAutoCompletePluginKey)
3436
+ ?.afterComplete;
3437
+ afterComplete && afterComplete(temporaryElement);
3438
+ }
3439
+ if (startPoint) {
3440
+ BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
3441
+ startPoint = null;
3442
+ }
3443
+ lineShapeG?.remove();
3444
+ lineShapeG = null;
3445
+ sourceElement = null;
3446
+ temporaryElement = null;
3447
+ pointerUp(event);
3448
+ };
3449
+ return board;
3450
+ };
3451
+
3264
3452
  const withDraw = (board) => {
3265
3453
  const { drawElement, getRectangle, isRectangleHit, isHit, isMovable, isAlign } = board;
3266
3454
  board.drawElement = (context) => {
@@ -3314,11 +3502,13 @@ const withDraw = (board) => {
3314
3502
  const isSelected = (boundId) => {
3315
3503
  return !!selectedElements.find(value => value.id === boundId);
3316
3504
  };
3317
- if ((element.source.boundId && !isSelected(element.source.boundId)) ||
3318
- (element.target.boundId && !isSelected(element.target.boundId))) {
3319
- return false;
3505
+ if ((!element.source.boundId ||
3506
+ (element.source.boundId && isSelected(element.source.boundId) && selectedElements.includes(element))) &&
3507
+ (!element.target.boundId ||
3508
+ (element.source.boundId && isSelected(element.source.boundId) && selectedElements.includes(element)))) {
3509
+ return true;
3320
3510
  }
3321
- return true;
3511
+ return false;
3322
3512
  }
3323
3513
  return isMovable(element);
3324
3514
  };
@@ -3328,12 +3518,12 @@ const withDraw = (board) => {
3328
3518
  }
3329
3519
  return isAlign(element);
3330
3520
  };
3331
- return withLineText(withLineBoundReaction(withLineResize(withGeometryResize(withLineCreateByDraw(withGeometryCreateByDrag(withGeometryCreateByDrawing(withDrawFragment(withDrawHotkey(board)))))))));
3521
+ return withAutoCompleteReaction(withLineText(withLineBoundReaction(withLineResize(withGeometryResize(withLineCreateByDraw(withAutoComplete(withGeometryCreateByDrag(withGeometryCreateByDrawing(withDrawFragment(withDrawHotkey(board)))))))))));
3332
3522
  };
3333
3523
 
3334
3524
  /**
3335
3525
  * Generated bundle index. Do not edit.
3336
3526
  */
3337
3527
 
3338
- export { BasicShapes, DEFAULT_IMAGE_WIDTH, DefaultBasicShapeProperty, DefaultConnectorProperty, DefaultDataProperty, DefaultDecisionProperty, DefaultFlowchartProperty, DefaultFlowchartPropertyMap, DefaultGeometryActiveStyle, DefaultGeometryStyle, DefaultManualInputProperty, DefaultMergeProperty, DefaultTextProperty, DrawTransforms, FlowchartSymbols, GeometryComponent, GeometryThreshold, LineComponent, LineHandleKey, LineMarkerType, LineShape, PlaitDrawElement, PlaitGeometry, PlaitLine, Q2C, ShapeDefaultSpace, StrokeStyle, createDefaultFlowchart, createGeometryElement, createLineElement, drawBoundMask, drawGeometry, drawLine, getBasicPointers, getBoardLines, getCenterPointsOnPolygon, getConnectionPoint, getCurvePoints, getDefaultFlowchartProperty, getEdgeOnPolygonByPoint, getElbowPoints, getFillByElement, getFlowchartPointers, getGeometryPointers, getHitConnectorPoint, getHitLineTextIndex, getLineDashByElement, getLineHandleRefPair, getLinePointers, getLinePoints, getLineTextRectangle, getNearestPoint, getPointsByCenterPoint, getSelectedDrawElements, getSelectedGeometryElements, getSelectedImageElements, getSelectedLineElements, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getTextRectangle, getVectorByConnection, isHitDrawElement, isHitLineText, isHitPolyLine, isRectangleHitDrawElement, isTextExceedingBounds, transformOpsToPoints, transformPointToConnection, withDraw };
3528
+ export { BasicShapes, DEFAULT_IMAGE_WIDTH, DefaultBasicShapeProperty, DefaultConnectorProperty, DefaultDataProperty, DefaultDecisionProperty, DefaultFlowchartProperty, DefaultFlowchartPropertyMap, DefaultGeometryActiveStyle, DefaultGeometryStyle, DefaultManualInputProperty, DefaultMergeProperty, DefaultTextProperty, DrawThemeColors, DrawTransforms, FlowchartSymbols, GeometryComponent, GeometryThreshold, LineComponent, LineHandleKey, LineMarkerType, LineShape, PlaitDrawElement, PlaitGeometry, PlaitLine, Q2C, REACTION_MARGIN, ShapeDefaultSpace, StrokeStyle, alignPoints, createDefaultFlowchart, createGeometryElement, createLineElement, drawBoundMask, drawGeometry, drawLine, getAutoCompletePoints, getBasicPointers, getBoardLines, getCenterPointsOnPolygon, getConnectionPoint, getCurvePoints, getDefaultFlowchartProperty, getDrawDefaultStrokeColor, getEdgeOnPolygonByPoint, getElbowPoints, getFillByElement, getFlowchartDefaultFill, getFlowchartPointers, getGeometryPointers, getHitConnectorPoint, getHitIndexOfAutoCompletePoint, getHitLineTextIndex, getLineDashByElement, getLineHandleRefPair, getLinePointers, getLinePoints, getLineTextRectangle, getNearestPoint, getPointsByCenterPoint, getSelectedDrawElements, getSelectedGeometryElements, getSelectedImageElements, getSelectedLineElements, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getTextRectangle, getVectorByConnection, handleLineCreating, isHitDrawElement, isHitLineText, isHitPolyLine, isRectangleHitDrawElement, isTextExceedingBounds, transformOpsToPoints, transformPointToConnection, withDraw };
3339
3529
  //# sourceMappingURL=plait-draw.mjs.map