plotboilerplate 1.29.0 → 1.31.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 (80) hide show
  1. package/README.md +26 -13
  2. package/dist/index.esm.js +310 -57
  3. package/dist/index.esm.js.map +1 -1
  4. package/dist/index.esm.min.js +1 -1
  5. package/dist/index.esm.min.js.map +1 -1
  6. package/dist/plotboilerplate.browser.min.js +1 -1
  7. package/dist/plotboilerplate.browser.min.js.map +1 -1
  8. package/dist/plotboilerplate.js +266 -36
  9. package/dist/plotboilerplate.min.js +1 -1
  10. package/package.json +1 -1
  11. package/src/cjs/Circle.d.ts +17 -1
  12. package/src/cjs/Circle.js +21 -1
  13. package/src/cjs/Circle.js.map +1 -1
  14. package/src/cjs/CubicBezierCurve.d.ts +34 -3
  15. package/src/cjs/CubicBezierCurve.js +79 -12
  16. package/src/cjs/CubicBezierCurve.js.map +1 -1
  17. package/src/cjs/Line.d.ts +46 -1
  18. package/src/cjs/Line.js +80 -1
  19. package/src/cjs/Line.js.map +1 -1
  20. package/src/cjs/Polygon.d.ts +18 -4
  21. package/src/cjs/Polygon.js +56 -18
  22. package/src/cjs/Polygon.js.map +1 -1
  23. package/src/cjs/VertTuple.d.ts +24 -2
  24. package/src/cjs/VertTuple.js +28 -2
  25. package/src/cjs/VertTuple.js.map +1 -1
  26. package/src/cjs/Vertex.d.ts +2 -2
  27. package/src/cjs/Vertex.js +2 -2
  28. package/src/cjs/utils/algorithms/delaunay2voronoi.d.ts +2 -1
  29. package/src/cjs/utils/algorithms/delaunay2voronoi.js +8 -10
  30. package/src/cjs/utils/algorithms/delaunay2voronoi.js.map +1 -1
  31. package/src/cjs/utils/datastructures/PointSet.d.ts +63 -0
  32. package/src/cjs/utils/datastructures/PointSet.js +126 -0
  33. package/src/cjs/utils/datastructures/PointSet.js.map +1 -0
  34. package/src/cjs/utils/datastructures/VoronoiCell.d.ts +19 -2
  35. package/src/cjs/utils/datastructures/VoronoiCell.js +39 -12
  36. package/src/cjs/utils/datastructures/VoronoiCell.js.map +1 -1
  37. package/src/cjs/utils/renderers/VoronoiRenderer.d.ts +99 -0
  38. package/src/cjs/utils/renderers/VoronoiRenderer.js +147 -0
  39. package/src/cjs/utils/renderers/VoronoiRenderer.js.map +1 -0
  40. package/src/esm/Circle.d.ts +17 -1
  41. package/src/esm/Circle.js +21 -1
  42. package/src/esm/Circle.js.map +1 -1
  43. package/src/esm/CubicBezierCurve.d.ts +34 -3
  44. package/src/esm/CubicBezierCurve.js +79 -12
  45. package/src/esm/CubicBezierCurve.js.map +1 -1
  46. package/src/esm/Line.d.ts +46 -1
  47. package/src/esm/Line.js +80 -1
  48. package/src/esm/Line.js.map +1 -1
  49. package/src/esm/Polygon.d.ts +18 -4
  50. package/src/esm/Polygon.js +56 -18
  51. package/src/esm/Polygon.js.map +1 -1
  52. package/src/esm/VertTuple.d.ts +24 -2
  53. package/src/esm/VertTuple.js +28 -2
  54. package/src/esm/VertTuple.js.map +1 -1
  55. package/src/esm/Vertex.d.ts +2 -2
  56. package/src/esm/Vertex.js +2 -2
  57. package/src/esm/utils/algorithms/delaunay2voronoi.d.ts +2 -1
  58. package/src/esm/utils/algorithms/delaunay2voronoi.js +8 -10
  59. package/src/esm/utils/algorithms/delaunay2voronoi.js.map +1 -1
  60. package/src/esm/utils/datastructures/PointSet.d.ts +63 -0
  61. package/src/esm/utils/datastructures/PointSet.js +115 -0
  62. package/src/esm/utils/datastructures/PointSet.js.map +1 -0
  63. package/src/esm/utils/datastructures/VoronoiCell.d.ts +19 -2
  64. package/src/esm/utils/datastructures/VoronoiCell.js +39 -12
  65. package/src/esm/utils/datastructures/VoronoiCell.js.map +1 -1
  66. package/src/esm/utils/renderers/VoronoiRenderer.d.ts +99 -0
  67. package/src/esm/utils/renderers/VoronoiRenderer.js +142 -0
  68. package/src/esm/utils/renderers/VoronoiRenderer.js.map +1 -0
  69. package/src/index-gl.js +1 -2
  70. package/src/ts/Circle.ts +23 -1
  71. package/src/ts/CubicBezierCurve.ts +133 -48
  72. package/src/ts/Line.ts +84 -1
  73. package/src/ts/Polygon.ts +58 -18
  74. package/src/ts/VertTuple.ts +30 -2
  75. package/src/ts/Vertex.ts +2 -2
  76. package/src/ts/utils/_AppContext.ts_ +22 -0
  77. package/src/ts/utils/algorithms/delaunay2voronoi.ts +81 -88
  78. package/src/ts/utils/datastructures/PointSet.ts +135 -0
  79. package/src/ts/utils/datastructures/VoronoiCell.ts +198 -169
  80. package/src/ts/utils/renderers/VoronoiRenderer.ts +200 -0
@@ -1 +1 @@
1
- {"version":3,"file":"plotboilerplate.browser.min.js","mappings":"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","sources":["webpack://plotboilerplate/./src/cjs/Vector.js","webpack://plotboilerplate/./src/cjs/draw.js","webpack://plotboilerplate/./src/cjs/Bounds.js","webpack://plotboilerplate/./src/cjs/Circle.js","webpack://plotboilerplate/./src/cjs/CircleSector.js","webpack://plotboilerplate/./src/cjs/drawgl.js","webpack://plotboilerplate/./src/cjs/Grid.js","webpack://plotboilerplate/./src/cjs/geomutils.js","webpack://plotboilerplate/./src/cjs/drawutilssvg.js","webpack://plotboilerplate/./src/cjs/VertexAttr.js","webpack://plotboilerplate/./src/cjs/KeyHandler.js","webpack://plotboilerplate/./src/cjs/PlotBoilerplate.js","webpack://plotboilerplate/./src/cjs/VertTuple.js","webpack://plotboilerplate/./node_modules/alloyfinger-typescript/src/esm/alloy_finger.js","webpack://plotboilerplate/./node_modules/alloyfinger-typescript/src/esm/index.js","webpack://plotboilerplate/./src/cjs/PBText.js","webpack://plotboilerplate/./src/cjs/Polygon.js","webpack://plotboilerplate/./src/cjs/VEllipseSector.js","webpack://plotboilerplate/./src/cjs/BezierPath.js","webpack://plotboilerplate/./src/cjs/Triangle.js","webpack://plotboilerplate/./src/cjs/Vertex.js","webpack://plotboilerplate/./src/cjs/PBImage.js","webpack://plotboilerplate/./src/cjs/VEllipse.js","webpack://plotboilerplate/./src/cjs/MouseHandler.js","webpack://plotboilerplate/./src/cjs/VertexListeners.js","webpack://plotboilerplate/./src/cjs/UIDGenerator.js","webpack://plotboilerplate/./src/cjs/Line.js","webpack://plotboilerplate/./src/cjs/CubicBezierCurve.js","webpack://plotboilerplate/webpack/bootstrap","webpack://plotboilerplate/webpack/runtime/define property getters","webpack://plotboilerplate/webpack/runtime/hasOwnProperty shorthand","webpack://plotboilerplate/webpack/runtime/make namespace object","webpack://plotboilerplate/./src/cjs/entry.js"],"sourcesContent":["\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2019-01-30\n * @modified 2019-02-23 Added the toSVGString function, overriding Line.toSVGString.\n * @modified 2019-03-20 Added JSDoc tags.\n * @modified 2019-04-19 Added the clone function (overriding Line.clone()).\n * @modified 2019-09-02 Added the Vector.perp() function.\n * @modified 2019-09-02 Added the Vector.inverse() function.\n * @modified 2019-12-04 Added the Vector.inv() function.\n * @modified 2020-03-23 Ported to Typescript from JS.\n * @modified 2021-01-20 Added UID.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-02-02 Cleared the `Vector.toSVGString` function (deprecated). Use `drawutilssvg` instead.\n * @modified 2022-10-25 Added the `getOrthogonal` method.\n * @modified 2025-04-14 Added the `Vector.rotate(number)` method.\n * @version 1.6.0\n *\n * @file Vector\n * @public\n **/\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Vector = void 0;\nvar VertTuple_1 = require(\"./VertTuple\");\nvar Vertex_1 = require(\"./Vertex\");\n/**\n * @classdesc A vector (Vertex,Vertex) is a line with a visible direction.<br>\n * <br>\n * Vectors are drawn with an arrow at their end point.<br>\n * <b>The Vector class extends the Line class.</b>\n *\n * @requires VertTuple\n * @requires Vertex\n **/\nvar Vector = /** @class */ (function (_super) {\n __extends(Vector, _super);\n /**\n * The constructor.\n *\n * @constructor\n * @name Vector\n * @extends Line\n * @param {Vertex} vertA - The start vertex of the vector.\n * @param {Vertex} vertB - The end vertex of the vector.\n **/\n function Vector(vertA, vertB) {\n var _this = _super.call(this, vertA, vertB, function (a, b) { return new Vector(a, b); }) || this;\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n _this.className = \"Vector\";\n return _this;\n }\n /**\n * Get the perpendicular of this vector which is located at a.\n *\n * @return {Vector} A new vector being the perpendicular of this vector sitting on a.\n **/\n Vector.prototype.perp = function () {\n var v = this.clone();\n v.sub(this.a);\n v = new Vector(new Vertex_1.Vertex(), new Vertex_1.Vertex(-v.b.y, v.b.x));\n v.a.add(this.a);\n v.b.add(this.a);\n return v;\n };\n /**\n * The inverse of a vector is a vector with the same magnitude but oppose direction.\n *\n * Please not that the origin of this vector changes here: a->b becomes b->a.\n *\n * @return {Vector}\n **/\n Vector.prototype.inverse = function () {\n var tmp = this.a;\n this.a = this.b;\n this.b = tmp;\n return this;\n };\n /**\n * This function computes the inverse of the vector, which means 'a' stays untouched.\n *\n * @return {Vector} this for chaining.\n **/\n Vector.prototype.inv = function () {\n this.b.x = this.a.x - (this.b.x - this.a.x);\n this.b.y = this.a.y - (this.b.y - this.a.y);\n return this;\n };\n /**\n * Get the intersection if this vector and the specified vector.\n *\n * @method intersection\n * @param {Vector} line The second vector.\n * @return {Vertex} The intersection (may lie outside the end-points).\n * @instance\n * @memberof Line\n **/\n Vector.prototype.intersection = function (line) {\n var denominator = this.denominator(line);\n if (denominator == 0)\n return null;\n var a = this.a.y - line.a.y;\n var b = this.a.x - line.a.x;\n var numerator1 = (line.b.x - line.a.x) * a - (line.b.y - line.a.y) * b;\n var numerator2 = (this.b.x - this.a.x) * a - (this.b.y - this.a.y) * b;\n a = numerator1 / denominator; // NaN if parallel lines\n b = numerator2 / denominator;\n // TODO:\n // FOR A VECTOR THE LINE-INTERSECTION MUST BE ON BOTH VECTORS\n // if we cast these lines infinitely in both directions, they intersect here:\n return new Vertex_1.Vertex(this.a.x + a * (this.b.x - this.a.x), this.a.y + a * (this.b.y - this.a.y));\n };\n /**\n * Get the orthogonal \"vector\" of this vector (rotated by 90° clockwise).\n *\n * @name getOrthogonal\n * @method getOrthogonal\n * @return {Vector} A new vector with the same length that stands on this vector's point a.\n * @instance\n * @memberof Vector\n **/\n Vector.prototype.getOrthogonal = function () {\n // Orthogonal of vector (0,0)->(x,y) is (0,0)->(-y,x)\n var linePoint = this.a.clone();\n var startPoint = this.b.clone().sub(this.a);\n var tmp = startPoint.x;\n startPoint.x = -startPoint.y;\n startPoint.y = tmp;\n return new Vector(linePoint, startPoint.add(this.a));\n };\n /**\n * Rotate this vector by the given angle around the first point `a`.\n *\n * @name rotate\n * @method rotate\n * @return {Vector} this - for chaining.\n * @instance\n * @memberof Vector\n */\n Vector.prototype.rotate = function (angle) {\n this.b.rotate(angle, this.a);\n return this;\n };\n Vector.utils = {\n /**\n * Generate a four-point arrow head, starting at the vector end minus the\n * arrow head length.\n *\n * The first vertex in the returned array is guaranteed to be the located\n * at the vector line end minus the arrow head length.\n *\n *\n * Due to performance all params are required.\n *\n * The params scaleX and scaleY are required for the case that the scaling is not uniform (x and y\n * scaling different). Arrow heads should not look distored on non-uniform scaling.\n *\n * If unsure use 1.0 for scaleX and scaleY (=no distortion).\n * For headlen use 8, it's a good arrow head size.\n *\n * Example:\n * buildArrowHead( new Vertex(0,0), new Vertex(50,100), 8, 1.0, 1.0 )\n *\n * @param {XYCoords} zA - The start vertex of the vector to calculate the arrow head for.\n * @param {XYCoords} zB - The end vertex of the vector.\n * @param {number} headlen - The length of the arrow head (along the vector direction. A good value is 12).\n * @param {number} scaleX - The horizontal scaling during draw.\n * @param {number} scaleY - the vertical scaling during draw.\n **/\n buildArrowHead: function (zA, zB, headlen, scaleX, scaleY) {\n var angle = Math.atan2((zB.y - zA.y) * scaleY, (zB.x - zA.x) * scaleX);\n var vertices = [];\n vertices.push(new Vertex_1.Vertex(zB.x * scaleX - headlen * Math.cos(angle), zB.y * scaleY - headlen * Math.sin(angle)));\n vertices.push(new Vertex_1.Vertex(zB.x * scaleX - headlen * 1.35 * Math.cos(angle - Math.PI / 8), zB.y * scaleY - headlen * 1.35 * Math.sin(angle - Math.PI / 8)));\n vertices.push(new Vertex_1.Vertex(zB.x * scaleX, zB.y * scaleY));\n vertices.push(new Vertex_1.Vertex(zB.x * scaleX - headlen * 1.35 * Math.cos(angle + Math.PI / 8), zB.y * scaleY - headlen * 1.35 * Math.sin(angle + Math.PI / 8)));\n return vertices;\n }\n };\n return Vector;\n}(VertTuple_1.VertTuple));\nexports.Vector = Vector;\n//# sourceMappingURL=Vector.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2018-04-22\n * @modified 2018-08-16 Added the curve() function to draw cubic bézier curves.\n * @modified 2018-10-23 Recognizing the offset param in the circle() function.\n * @modified 2018-11-27 Added the diamondHandle() function.\n * @modified 2018-11-28 Added the grid() function and the ellipse() function.\n * @modified 2018-11-30 Renamed the text() function to label() as it is not scaling.\n * @modified 2018-12-06 Added a test function for drawing arc in SVG style.\n * @modified 2018-12-09 Added the dot(Vertex,color) function (copied from Feigenbaum-plot-script).\n * @modified 2019-01-30 Added the arrow(Vertex,Vertex,color) function for drawing arrow heads.\n * @modified 2019-01-30 Added the image(Image,Vertex,Vertex) function for drawing images.\n * @modified 2019-04-27 Fixed a severe drawing bug in the arrow(...) function. Scaling arrows did not work properly.\n * @modified 2019-04-28 Added Math.round to the dot() drawing parameters to really draw a singlt dot.\n * @modified 2019-06-07 Fixed an issue in the cubicBezier() function. Paths were always closed.\n * @modified 2019-10-03 Added the beginDrawCycle hook.\n * @modified 2019-10-25 Polygons are no longer drawn with dashed lines (solid lines instead).\n * @modified 2019-11-18 Added the polyline function.\n * @modified 2019-11-22 Added a second workaround for th drawImage bug in Safari.\n * @modified 2019-12-07 Added the 'lineWidth' param to the line(...) function.\n * @modified 2019-12-07 Added the 'lineWidth' param to the cubicBezier(...) function.\n * @modified 2019-12-11 Added the 'color' param to the label(...) function.\n * @modified 2019-12-18 Added the quadraticBezier(...) function (for the sake of approximating Lissajous curves).\n * @modified 2019-12-20 Added the 'lineWidth' param to the polyline(...) function.\n * @modified 2020-01-09 Added the 'lineWidth' param to the ellipse(...) function.\n * @modified 2020-03-25 Ported this class from vanilla-JS to Typescript.\n * @modified 2020-05-05 Added the 'lineWidth' param to the circle(...) function.\n * @modified 2020-05-12 Drawing any handles (square, circle, diamond) with lineWidth 1 now; this was not reset before.\n * @modified 2020-06-22 Added a context.clearRect() call to the clear() function; clearing with alpha channel did not work as expected.\n * @modified 2020-09-07 Added the circleArc(...) function to draw sections of circles.\n * @modified 2020-10-06 Removed the .closePath() instruction from the circleArc function.\n * @modified 2020-10-15 Re-added the text() function.\n * @modified 2020-10-28 Added the path(Path2D) function.\n * @modified 2020-12-28 Added the `singleSegment` mode (test).\n * @modified 2021-01-05 Added the image-loaded/broken check.\n * @modified 2021-01-24 Added the `setCurrentId` function from the `DrawLib` interface.\n * @modified 2021-02-22 Added the `path` drawing function to draw SVG path data.\n * @modified 2021-03-31 Added the `endDrawCycle` function from `DrawLib`.\n * @modified 2021-05-31 Added the `setConfiguration` function from `DrawLib`.\n * @modified 2021-11-12 Adding more parameters tot the `text()` function: fontSize, textAlign, fontFamily, lineHeight.\n * @modified 2021-11-19 Added the `color` param to the `label(...)` function.\n * @modified 2022-02-03 Added the `lineWidth` param to the `crosshair` function.\n * @modified 2022-02-03 Added the `cross(...)` function.\n * @modified 2022-03-27 Added the `texturedPoly` function.\n * @modified 2022-06-01 Tweaked the `polyline` function; lineWidth now scales with scale.x.\n * @modified 2022-07-26 Adding `alpha` to the `image(...)` function.\n * @modified 2022-08-23 Fixed a type issue in the `polyline` function.\n * @modified 2022-08-23 Fixed a type issue in the `setConfiguration` function.\n * @modified 2022-08-23 Fixed a type issue in the `path` function.\n * @modified 2023-02-10 The methods `setCurrentClassName` and `setCurrentId` also accept `null` now.\n * @modified 2023-09-29 Removed unused method stub for texturedPoly helper function (cleanup).\n * @modified 2023-09-29 Downgrading all `Vertex` param type to the more generic `XYCoords` type in these render functions: line, arrow, texturedPoly, cubicBezier, cubicBezierPath, handle, handleLine, dot, point, circle, circleArc, ellipse, grid, raster.\n * @modified 2023-09-29 Added the `headLength` parameter to the 'DrawLib.arrow()` function.\n * @modified 2023-09-29 Added the `arrowHead(...)` function to the 'DrawLib.arrow()` interface.\n * @modified 2023-09-29 Added the `cubicBezierArrow(...)` function to the 'DrawLib.arrow()` interface.\n * @modified 2023-09-29 Added the `lineDashes` attribute.\n * @modified 2023-09-30 Adding `strokeOptions` param to these draw function: line, arrow, cubicBezierArrow, cubicBezier, cubicBezierPath, circle, circleArc, ellipse, square, rect, polygon, polyline.\n * @modified 2023-10-07 Adding the optional `arrowHeadBasePositionBuffer` param to the arrowHead(...) method.\n * @modified 2024-09-13 Remoed the scaling of `lineWidth` in the `polygon` and `polyline` methods. This makes no sense here and doesn't match up with the behavior of other line functions.\n * @modified 2026-01-04 Adding `lineJoin` attribute to the `StrokeOptions`.\n * @modified 2026-03-18 Adding `isOpen` parameter to `cubicBezierPath` draw method.\n * @modified 2026-04-04 Added the method `bounds`.\n * @modified 2026-04-04 Handling the `lineCap` attribute in the `StrokeOptions`.\n * @version 1.15.0\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.drawutils = void 0;\nvar CubicBezierCurve_1 = require(\"./CubicBezierCurve\");\nvar Vertex_1 = require(\"./Vertex\");\nvar drawutilssvg_1 = require(\"./drawutilssvg\");\nvar Vector_1 = require(\"./Vector\");\n// Todo: rename this class to Drawutils?\n/**\n * @classdesc A wrapper class for basic drawing operations.\n *\n * @requires CubicBzierCurvce\n * @requires Polygon\n * @requires Vertex\n * @requires XYCoords\n */\nvar drawutils = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name drawutils\n * @param {anvasRenderingContext2D} context - The drawing context.\n * @param {boolean} fillShaped - Indicates if the constructed drawutils should fill all drawn shapes (if possible).\n **/\n function drawutils(context, fillShapes) {\n this.ctx = context;\n // this.lineDash = [];\n this.offset = new Vertex_1.Vertex(0, 0);\n this.scale = new Vertex_1.Vertex(1, 1);\n this.fillShapes = fillShapes;\n }\n /**\n * A private helper method to apply stroke options to the current\n * context.\n * @param {StrokeOptions=} strokeOptions -\n */\n drawutils.prototype.applyStrokeOpts = function (strokeOptions) {\n var _this = this;\n var _a, _b, _c, _d;\n this.ctx.setLineDash(((_a = strokeOptions === null || strokeOptions === void 0 ? void 0 : strokeOptions.dashArray) !== null && _a !== void 0 ? _a : []).map(function (dashArrayElem) {\n // Note assume scale.x === scale.y\n // Invariant scale makes funny stuff anyway.\n return dashArrayElem * _this.scale.x;\n }));\n this.ctx.lineDashOffset = ((_b = strokeOptions === null || strokeOptions === void 0 ? void 0 : strokeOptions.dashOffset) !== null && _b !== void 0 ? _b : 0) * this.scale.x;\n this.ctx.lineJoin = (_c = strokeOptions === null || strokeOptions === void 0 ? void 0 : strokeOptions.lineJoin) !== null && _c !== void 0 ? _c : null;\n this.ctx.lineCap = (_d = strokeOptions === null || strokeOptions === void 0 ? void 0 : strokeOptions.lineCap) !== null && _d !== void 0 ? _d : null;\n };\n // +---------------------------------------------------------------------------------\n // | This is the final helper function for drawing and filling stuff. It is not\n // | intended to be used from the outside.\n // |\n // | When in draw mode it draws the current shape.\n // | When in fill mode it fills the current shape.\n // |\n // | This function is usually only called internally.\n // |\n // | @param color A stroke/fill color to use.\n // +-------------------------------\n // TODO: convert this to a STATIC function.\n drawutils.prototype._fillOrDraw = function (color) {\n if (this.fillShapes) {\n this.ctx.fillStyle = color;\n this.ctx.fill();\n }\n else {\n this.ctx.strokeStyle = color;\n this.ctx.stroke();\n }\n };\n /**\n * Called before each draw cycle.\n * @param {UID=} uid - (optional) A UID identifying the currently drawn element(s).\n **/\n drawutils.prototype.beginDrawCycle = function (renderTime) {\n // NOOP\n };\n /**\n * Called after each draw cycle.\n *\n * This is required for compatibility with other draw classes in the library (like drawgl).\n *\n * @name endDrawCycle\n * @method\n * @param {number} renderTime\n * @instance\n **/\n drawutils.prototype.endDrawCycle = function (renderTime) {\n // NOOP\n };\n /**\n * Set the current drawlib configuration.\n *\n * @name setConfiguration\n * @method\n * @param {DrawLibConfiguration} configuration - The new configuration settings to use for the next render methods.\n */\n drawutils.prototype.setConfiguration = function (configuration) {\n this.ctx.globalCompositeOperation = configuration.blendMode || \"source-over\";\n };\n // /**\n // * Set or clear the line-dash configuration. Pass `null` for un-dashed lines.\n // *\n // * See https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray\n // * and https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash\n // * for how line dashes work.\n // *\n // * @method\n // * @param {Array<number> lineDashes - The line-dash array configuration.\n // * @returns {void}\n // */\n // setLineDash(lineDash: Array<number>) {\n // this.lineDash = lineDash;\n // }\n /**\n * This method shouled be called each time the currently drawn `Drawable` changes.\n * It is used by some libraries for identifying elemente on re-renders.\n *\n * @name setCurrentId\n * @method\n * @param {UID|null} uid - A UID identifying the currently drawn element(s).\n **/\n drawutils.prototype.setCurrentId = function (uid) {\n // NOOP\n };\n /**\n * This method shouled be called each time the currently drawn `Drawable` changes.\n * Determine the class name for further usage here.\n *\n * @name setCurrentClassName\n * @method\n * @param {string|null} className - A class name for further custom use cases.\n **/\n drawutils.prototype.setCurrentClassName = function (className) {\n // NOOP\n };\n /**\n * Draw the line between the given two points with the specified (CSS-) color.\n *\n * @method line\n * @param {XYCoords} zA - The start point of the line.\n * @param {XYCoords} zB - The end point of the line.\n * @param {string} color - Any valid CSS color string.\n * @param {number} lineWidth? - [optional] The line's width.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n **/\n drawutils.prototype.line = function (zA, zB, color, lineWidth, strokeOptions) {\n this.ctx.save();\n this.ctx.beginPath();\n this.applyStrokeOpts(strokeOptions);\n this.ctx.moveTo(this.offset.x + zA.x * this.scale.x, this.offset.y + zA.y * this.scale.y);\n this.ctx.lineTo(this.offset.x + zB.x * this.scale.x, this.offset.y + zB.y * this.scale.y);\n this.ctx.strokeStyle = color;\n this.ctx.lineWidth = lineWidth || 1;\n this.ctx.stroke();\n this.ctx.restore();\n };\n /**\n * Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.\n *\n * @method arrow\n * @param {XYCoords} zA - The start point of the arrow-line.\n * @param {XYCoords} zB - The end point of the arrow-line.\n * @param {string} color - Any valid CSS color string.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {headLength=8} headLength - (optional) The length of the arrow head (default is 8 units).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n **/\n drawutils.prototype.arrow = function (zA, zB, color, lineWidth, headLength, strokeOptions) {\n if (headLength === void 0) { headLength = 8; }\n var arrowHeadBasePosition = new Vertex_1.Vertex(0, 0);\n this.arrowHead(zA, zB, color, lineWidth, headLength, undefined, arrowHeadBasePosition); // Will NOT use dash configuration\n this.line(zA, arrowHeadBasePosition, color, lineWidth, strokeOptions); // Will use dash configuration\n };\n /**\n * Draw a cubic Bézier curve and and an arrow at the end (endControlPoint) of the given line width the specified (CSS-) color and arrow size.\n *\n * @method cubicBezierArrow\n * @param {XYCoords} startPoint - The start point of the cubic Bézier curve\n * @param {XYCoords} endPoint - The end point the cubic Bézier curve.\n * @param {XYCoords} startControlPoint - The start control point the cubic Bézier curve.\n * @param {XYCoords} endControlPoint - The end control point the cubic Bézier curve.\n * @param {string} color - The CSS color to draw the curve with.\n * @param {number} lineWidth - (optional) The line width to use.\n * @param {headLength=8} headLength - (optional) The length of the arrow head (default is 8 units).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof DrawLib\n */\n drawutils.prototype.cubicBezierArrow = function (startPoint, endPoint, startControlPoint, endControlPoint, color, lineWidth, headLength, strokeOptions) {\n var arrowHeadBasePosition = new Vertex_1.Vertex(0, 0);\n // Will NOT use dash configuration\n this.arrowHead(endControlPoint, endPoint, color, lineWidth, headLength, undefined, arrowHeadBasePosition);\n var diff = arrowHeadBasePosition.difference(endPoint);\n // Will use dash configuration\n this.cubicBezier(startPoint, { x: endPoint.x - diff.x, y: endPoint.y - diff.y }, startControlPoint, { x: endControlPoint.x - diff.x, y: endControlPoint.y - diff.y }, color, lineWidth, strokeOptions);\n };\n /**\n * Draw just an arrow head a the end of an imaginary line (zB) of the given line width the specified (CSS-) color and size.\n *\n * @method arrow\n * @param {XYCoords} zA - The start point of the arrow-line.\n * @param {XYCoords} zB - The end point of the arrow-line.\n * @param {string} color - Any valid CSS color string.\n * @param {number=1} lineWidth - (optional) The line width to use; default is 1.\n * @param {number=8} headLength - (optional) The length of the arrow head (default is 8 pixels).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n * @param {XYCoords=} arrowHeadBasePositionBuffer - (optional) If not null, then this position will contain the arrow head's start point (after execution). Some sort of OUT variable.\n *\n * @return {void}\n * @instance\n * @memberof DrawLib\n **/\n drawutils.prototype.arrowHead = function (zA, zB, color, lineWidth, headLength, strokeOptions, arrowHeadBasePositionBuffer) {\n // var headLength: number = 8; // length of head in pixels\n if (headLength === void 0) { headLength = 8; }\n this.ctx.save();\n this.ctx.beginPath();\n this.applyStrokeOpts(strokeOptions);\n var vertices = Vector_1.Vector.utils.buildArrowHead(zA, zB, headLength, this.scale.x, this.scale.y);\n if (arrowHeadBasePositionBuffer) {\n arrowHeadBasePositionBuffer.x = vertices[0].x / this.scale.x;\n arrowHeadBasePositionBuffer.y = vertices[0].y / this.scale.y;\n }\n this.ctx.moveTo(this.offset.x + vertices[0].x, this.offset.y + vertices[0].y);\n for (var i = 0; i < vertices.length; i++) {\n this.ctx.lineTo(this.offset.x + vertices[i].x, this.offset.y + vertices[i].y);\n }\n this.ctx.lineTo(this.offset.x + vertices[0].x, this.offset.y + vertices[0].y);\n this.ctx.lineWidth = lineWidth || 1;\n this._fillOrDraw(color);\n this.ctx.restore();\n };\n /**\n * Draw an image at the given position with the given size.<br>\n * <br>\n * Note: SVG images may have resizing issues at the moment.Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.\n *\n * @method image\n * @param {Image} image - The image object to draw.\n * @param {XYCoords} position - The position to draw the the upper left corner at.\n * @param {XYCoords} size - The x/y-size to draw the image with.\n * @param {number=0.0} alpha - (optional, default=0.0) The transparency (1.0=opaque, 0.0=transparent).\n * @return {void}\n * @instance\n * @memberof drawutils\n **/\n drawutils.prototype.image = function (image, position, size, alpha) {\n if (alpha === void 0) { alpha = 1.0; }\n if (!image.complete || !image.naturalWidth) {\n // Avoid drawing un-unloaded or broken images\n return;\n }\n this.ctx.save();\n this.ctx.globalAlpha = alpha;\n // Note that there is a Safari bug with the 3 or 5 params variant.\n // Only the 9-param varaint works.\n this.ctx.drawImage(image, 0, 0, image.naturalWidth - 1, // There is this horrible Safari bug (fixed in newer versions)\n image.naturalHeight - 1, // To avoid errors substract 1 here.\n this.offset.x + position.x * this.scale.x, this.offset.y + position.y * this.scale.y, size.x * this.scale.x, size.y * this.scale.y);\n this.ctx.restore();\n };\n /**\n * Draw an image at the given position with the given size.<br>\n * <br>\n * Note: SVG images may have resizing issues at the moment.Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.\n *\n * @method texturedPoly\n * @param {Image} textureImage - The image object to draw.\n * @param {Bounds} textureSize - The texture size to use; these are the original bounds to map the polygon vertices to.\n * @param {Polygon} polygon - The polygon to use as clip path.\n * @param {XYCoords} polygonPosition - The polygon's position (relative), measured at the bounding box's center.\n * @param {number} rotation - The rotation to use for the polygon (and for the texture).\n * @param {XYCoords={x:0,y:0}} rotationCenter - (optional) The rotational center; default is center of bounding box.\n * @return {void}\n * @instance\n * @memberof drawutils\n **/\n drawutils.prototype.texturedPoly = function (textureImage, textureSize, polygon, polygonPosition, rotation) {\n var basePolygonBounds = polygon.getBounds();\n // var targetCenterDifference = polygonPosition.clone().difference(basePolygonBounds.getCenter());\n var targetCenterDifference = new Vertex_1.Vertex(polygonPosition.x, polygonPosition.y).difference(basePolygonBounds.getCenter());\n // var tileCenter = basePolygonBounds.getCenter().sub(targetCenterDifference);\n // Get the position offset of the polygon\n var targetTextureSize = new Vertex_1.Vertex(textureSize.width, textureSize.height);\n // var targetTextureOffset = new Vertex(-textureSize.width / 2, -textureSize.height / 2).sub(targetCenterDifference);\n var targetTextureOffset = new Vertex_1.Vertex(textureSize.min.x, textureSize.min.y).sub(polygonPosition);\n this.ctx.save();\n // this.ctx.translate(this.offset.x + rotationCenter.x * this.scale.x, this.offset.y + rotationCenter.y * this.scale.y);\n this.ctx.translate(this.offset.x + polygonPosition.x * this.scale.x, this.offset.y + polygonPosition.y * this.scale.y);\n drawutils.helpers.clipPoly(this.ctx, {\n x: -polygonPosition.x * this.scale.x,\n y: -polygonPosition.y * this.scale.y\n }, this.scale, polygon.vertices);\n this.ctx.scale(this.scale.x, this.scale.y);\n this.ctx.rotate(rotation);\n this.ctx.drawImage(textureImage, 0, 0, textureImage.naturalWidth - 1, // There is this horrible Safari bug (fixed in newer versions)\n textureImage.naturalHeight - 1, // To avoid errors substract 1 here.\n targetTextureOffset.x, // * this.scale.x,\n targetTextureOffset.y, // * this.scale.y,\n targetTextureSize.x, // * this.scale.x,\n targetTextureSize.y // * this.scale.y\n );\n this.ctx.restore();\n };\n /*\n _texturedPoly(\n textureImage: HTMLImageElement,\n textureSize: Bounds,\n polygon: Polygon,\n polygonPosition: XYCoords,\n rotation: number,\n rotationCenter: XYCoords = { x: 0, y: 0 }\n ): void {\n var basePolygonBounds = polygon.getBounds();\n var targetCenterDifference = polygonPosition.clone().difference(basePolygonBounds.getCenter());\n var rotationalOffset = rotationCenter ? polygonPosition.difference(rotationCenter) : { x: 0, y: 0 };\n // var rotationalOffset = { x: 0, y: 0 };\n var tileCenter = basePolygonBounds.getCenter().sub(targetCenterDifference);\n \n // Get the position offset of the polygon\n var targetTextureSize = new Vertex(textureSize.width, textureSize.height);\n var targetTextureOffset = new Vertex(-textureSize.width / 2, -textureSize.height / 2).sub(targetCenterDifference);\n \n this.ctx.save();\n \n // this.ctx.translate(\n // this.offset.x + (tileCenter.x - rotationalOffset.x * 0 + targetTextureOffset.x * 0.0) * this.scale.x,\n // this.offset.y + (tileCenter.y - rotationalOffset.y * 0 + targetTextureOffset.y * 0.0) * this.scale.y\n // );\n this.ctx.translate(\n this.offset.x + (tileCenter.x - rotationalOffset.x * 0 + targetTextureOffset.x * 0.0) * this.scale.x,\n this.offset.y + (tileCenter.y - rotationalOffset.y * 0 + targetTextureOffset.y * 0.0) * this.scale.y\n );\n this.ctx.rotate(rotation);\n \n drawutils.helpers.clipPoly(\n this.ctx,\n {\n x: (-targetCenterDifference.x * 1 - tileCenter.x - rotationalOffset.x) * this.scale.x,\n y: (-targetCenterDifference.y * 1 - tileCenter.y - rotationalOffset.y) * this.scale.y\n },\n this.scale,\n polygon.vertices\n );\n this.ctx.drawImage(\n textureImage,\n 0,\n 0,\n textureImage.naturalWidth - 1, // There is this horrible Safari bug (fixed in newer versions)\n textureImage.naturalHeight - 1, // To avoid errors substract 1 here.\n (-polygonPosition.x + targetTextureOffset.x * 1 - rotationalOffset.x * 1) * this.scale.x,\n (-polygonPosition.y + targetTextureOffset.y * 1 - rotationalOffset.y * 1) * this.scale.y,\n targetTextureSize.x * this.scale.x,\n targetTextureSize.y * this.scale.y\n );\n \n // const scaledTextureSize = new Bounds(\n // new Vertex(\n // -polygonPosition.x + targetTextureOffset.x - rotationalOffset.x,\n // -polygonPosition.y + targetTextureOffset.y - rotationalOffset.y\n // ).scaleXY(this.scale, rotationCenter),\n // new Vertex(\n // -polygonPosition.x + targetTextureOffset.x - rotationalOffset.x + targetTextureSize.x,\n // -polygonPosition.y + targetTextureOffset.y - rotationalOffset.y + targetTextureSize.y\n // ).scaleXY(this.scale, rotationCenter)\n // );\n // this.ctx.drawImage(\n // textureImage,\n // 0,\n // 0,\n // textureImage.naturalWidth - 1, // There is this horrible Safari bug (fixed in newer versions)\n // textureImage.naturalHeight - 1, // To avoid errors substract 1 here.\n // scaledTextureSize.min.x,\n // scaledTextureSize.min.y,\n // scaledTextureSize.width,\n // scaledTextureSize.height\n // );\n \n this.ctx.restore();\n }\n */\n /**\n * Draw a rectangle.\n *\n * @param {XYCoords} position - The upper left corner of the rectangle.\n * @param {number} width - The width of the rectangle.\n * @param {number} height - The height of the rectangle.\n * @param {string} color - The color to use.\n * @param {number=1} lineWidth - (optional) The line with to use (default is 1).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n **/\n drawutils.prototype.rect = function (position, width, height, color, lineWidth, strokeOptions) {\n this.ctx.save();\n this.ctx.beginPath();\n this.applyStrokeOpts(strokeOptions);\n this.ctx.moveTo(this.offset.x + position.x * this.scale.x, this.offset.y + position.y * this.scale.y);\n this.ctx.lineTo(this.offset.x + (position.x + width) * this.scale.x, this.offset.y + position.y * this.scale.y);\n this.ctx.lineTo(this.offset.x + (position.x + width) * this.scale.x, this.offset.y + (position.y + height) * this.scale.y);\n this.ctx.lineTo(this.offset.x + position.x * this.scale.x, this.offset.y + (position.y + height) * this.scale.y);\n // this.ctx.lineTo( this.offset.x+position.x*this.scale.x, this.offset.y+position.y*this.scale.y );\n this.ctx.closePath();\n this.ctx.lineWidth = lineWidth || 1;\n this._fillOrDraw(color);\n this.ctx.restore();\n };\n /**\n * Draw a rectangle at the given bounds; and with the specified line width and (CSS-) color.<br>\n *\n * @method bounds\n * @param {IBounds} bounds - The bounds rectangle to be drawn.\n * @param {string} color - The CSS color to draw the rectangle with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {R}\n * @instance\n * @memberof DrawLib\n */\n drawutils.prototype.bounds = function (bounds, color, lineWidth, strokeOptions) {\n this.rect(bounds.min, bounds.max.x - bounds.min.x, bounds.max.y - bounds.min.y, color, lineWidth, strokeOptions);\n };\n /**\n * Draw the given (cubic) bézier curve.\n *\n * @method cubicBezier\n * @param {XYCoords} startPoint - The start point of the cubic Bézier curve\n * @param {XYCoords} endPoint - The end point the cubic Bézier curve.\n * @param {XYCoords} startControlPoint - The start control point the cubic Bézier curve.\n * @param {XYCoords} endControlPoint - The end control point the cubic Bézier curve.\n * @param {string} color - The CSS color to draw the curve with.\n * @param {number} lineWidth - (optional) The line width to use.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.cubicBezier = function (startPoint, endPoint, startControlPoint, endControlPoint, color, lineWidth, strokeOptions) {\n if (startPoint instanceof CubicBezierCurve_1.CubicBezierCurve) {\n this.cubicBezier(startPoint.startPoint, startPoint.endPoint, startPoint.startControlPoint, startPoint.endControlPoint, color, lineWidth);\n return;\n }\n // Draw curve\n this.ctx.save();\n this.ctx.beginPath();\n this.applyStrokeOpts(strokeOptions);\n this.ctx.moveTo(this.offset.x + startPoint.x * this.scale.x, this.offset.y + startPoint.y * this.scale.y);\n this.ctx.bezierCurveTo(this.offset.x + startControlPoint.x * this.scale.x, this.offset.y + startControlPoint.y * this.scale.y, this.offset.x + endControlPoint.x * this.scale.x, this.offset.y + endControlPoint.y * this.scale.y, this.offset.x + endPoint.x * this.scale.x, this.offset.y + endPoint.y * this.scale.y);\n //this.ctx.closePath();\n this.ctx.lineWidth = lineWidth || 2;\n this._fillOrDraw(color);\n this.ctx.restore();\n };\n /**\n * Draw the given (quadratic) bézier curve.\n *\n * @method quadraticBezier\n * @param {XYCoords} startPoint - The start point of the cubic Bézier curve\n * @param {XYCoords} controlPoint - The control point the cubic Bézier curve.\n * @param {XYCoords} endPoint - The end control point the cubic Bézier curve.\n * @param {string} color - The CSS color to draw the curve with.\n * @param {number|string} lineWidth - (optional) The line width to use.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.quadraticBezier = function (startPoint, controlPoint, endPoint, color, lineWidth, strokeOptions) {\n // Draw curve\n this.ctx.save();\n this.ctx.beginPath();\n this.applyStrokeOpts(strokeOptions);\n this.ctx.moveTo(this.offset.x + startPoint.x * this.scale.x, this.offset.y + startPoint.y * this.scale.y);\n this.ctx.quadraticCurveTo(this.offset.x + controlPoint.x * this.scale.x, this.offset.y + controlPoint.y * this.scale.y, this.offset.x + endPoint.x * this.scale.x, this.offset.y + endPoint.y * this.scale.y);\n this.ctx.lineWidth = lineWidth || 2;\n this._fillOrDraw(color);\n this.ctx.restore();\n };\n /**\n * Draw the given (cubic) Bézier path.\n *\n * The given path must be an array with n*3+1 vertices, where n is the number of\n * curves in the path:\n * <pre> [ point1, point1_startControl, point2_endControl, point2, point2_startControl, point3_endControl, point3, ... pointN_endControl, pointN ]</pre>\n *\n * @method cubicBezierPath\n * @param {XYCoords[]} path - The cubic bezier path as described above.\n * @param {string} color - The CSS colot to draw the path with.\n * @param {number=1} lineWidth - (optional) The line width to use.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.cubicBezierPath = function (path, color, lineWidth, strokeOptions, isOpen) {\n if (!path || path.length == 0) {\n return;\n }\n // Draw curve\n this.ctx.save();\n this.ctx.beginPath();\n var endPoint;\n var startControlPoint;\n var endControlPoint;\n this.applyStrokeOpts(strokeOptions);\n this.ctx.moveTo(this.offset.x + path[0].x * this.scale.x, this.offset.y + path[0].y * this.scale.y);\n for (var i = 1; i < path.length; i += 3) {\n startControlPoint = path[i];\n endControlPoint = path[i + 1];\n endPoint = path[i + 2];\n this.ctx.bezierCurveTo(this.offset.x + startControlPoint.x * this.scale.x, this.offset.y + startControlPoint.y * this.scale.y, this.offset.x + endControlPoint.x * this.scale.x, this.offset.y + endControlPoint.y * this.scale.y, this.offset.x + endPoint.x * this.scale.x, this.offset.y + endPoint.y * this.scale.y);\n }\n if (!isOpen) {\n this.ctx.closePath();\n }\n this.ctx.lineWidth = lineWidth || 1;\n this._fillOrDraw(color);\n this.ctx.restore();\n };\n /**\n * Draw the given handle and handle point (used to draw interactive Bézier curves).\n *\n * The colors for this are fixed and cannot be specified.\n *\n * @method handle\n * @param {XYCoords} startPoint - The start of the handle.\n * @param {XYCoords} endPoint - The end point of the handle.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.handle = function (startPoint, endPoint) {\n // Draw handles\n // (No need to save and restore here)\n this.point(startPoint, \"rgb(0,32,192)\");\n this.square(endPoint, 5, \"rgba(0,128,192,0.5)\");\n };\n /**\n * Draw a handle line (with a light grey).\n *\n * @method handleLine\n * @param {XYCoords} startPoint - The start point to draw the handle at.\n * @param {XYCoords} endPoint - The end point to draw the handle at.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.handleLine = function (startPoint, endPoint) {\n // Draw handle lines\n this.line(startPoint, endPoint, \"rgba(128,128,128, 0.5)\", undefined);\n };\n /**\n * Draw a 1x1 dot with the specified (CSS-) color.\n *\n * @method dot\n * @param {XYCoords} p - The position to draw the dot at.\n * @param {string} color - The CSS color to draw the dot with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.dot = function (p, color) {\n this.ctx.save();\n this.ctx.beginPath();\n this.ctx.setLineDash([]); // Clear line-dash settings\n this.ctx.moveTo(Math.round(this.offset.x + this.scale.x * p.x), Math.round(this.offset.y + this.scale.y * p.y));\n this.ctx.lineTo(Math.round(this.offset.x + this.scale.x * p.x + 1), Math.round(this.offset.y + this.scale.y * p.y + 1));\n this.ctx.closePath();\n this.ctx.lineWidth = 1;\n this._fillOrDraw(color);\n this.ctx.restore();\n };\n /**\n * Draw the given point with the specified (CSS-) color and radius 3.\n *\n * @method point\n * @param {XYCoords} p - The position to draw the point at.\n * @param {string} color - The CSS color to draw the point with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.point = function (p, color) {\n var radius = 3;\n this.ctx.setLineDash([]); // Clear line-dash settings\n this.ctx.beginPath();\n this.ctx.arc(this.offset.x + p.x * this.scale.x, this.offset.y + p.y * this.scale.y, radius, 0, 2 * Math.PI, false);\n this.ctx.closePath();\n this.ctx.lineWidth = 1;\n this._fillOrDraw(color);\n };\n /**\n * Draw a circle with the specified (CSS-) color and radius.<br>\n * <br>\n * Note that if the x- and y- scales are different the result will be an ellipse rather than a circle.\n *\n * @method circle\n * @param {XYCoords} center - The center of the circle.\n * @param {number} radius - The radius of the circle.\n * @param {string} color - The CSS color to draw the circle with.\n * @param {number} lineWidth - The line width (optional, default=1).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.circle = function (center, radius, color, lineWidth, strokeOptions) {\n this.applyStrokeOpts(strokeOptions);\n this.ctx.beginPath();\n this.ctx.ellipse(this.offset.x + center.x * this.scale.x, this.offset.y + center.y * this.scale.y, radius * this.scale.x, radius * this.scale.y, 0.0, 0.0, Math.PI * 2);\n this.ctx.closePath();\n this.ctx.lineWidth = lineWidth || 1;\n this._fillOrDraw(color);\n };\n /**\n * Draw a circular arc (section of a circle) with the given CSS color.\n *\n * @method circleArc\n * @param {XYCoords} center - The center of the circle.\n * @param {number} radius - The radius of the circle.\n * @param {number} startAngle - The angle to start at.\n * @param {number} endAngle - The angle to end at.\n * @param {string=#000000} color - The CSS color to draw the circle with.\n * @param {number=1} lineWidth - The line width to use\n * @param {boolean=false} options.asSegment - If `true` then no beginPath and no draw will be applied (as part of larger path).\n * @param {number=} options.dashOffset - (optional) `See StrokeOptions`.\n * @param {number=[]} options.dashArray - (optional) `See StrokeOptions`.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.circleArc = function (center, radius, startAngle, endAngle, color, lineWidth, options) {\n if (!options || !options.asSegment) {\n this.ctx.beginPath();\n }\n this.applyStrokeOpts(options);\n this.ctx.ellipse(this.offset.x + center.x * this.scale.x, this.offset.y + center.y * this.scale.y, radius * this.scale.x, radius * this.scale.y, 0.0, startAngle, endAngle, false);\n if (!options || !options.asSegment) {\n // this.ctx.closePath();\n this.ctx.lineWidth = lineWidth || 1;\n this._fillOrDraw(color || \"#000000\");\n }\n };\n /**\n * Draw an ellipse with the specified (CSS-) color and thw two radii.\n *\n * @method ellipse\n * @param {XYCoords} center - The center of the ellipse.\n * @param {number} radiusX - The radius of the ellipse.\n * @param {number} radiusY - The radius of the ellipse.\n * @param {string} color - The CSS color to draw the ellipse with.\n * @param {number} lineWidth=1 - An optional line width param (default is 1).\n * @param {number=} rotation - (optional, default=0) The rotation of the ellipse.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.ellipse = function (center, radiusX, radiusY, color, lineWidth, rotation, strokeOptions) {\n if (typeof rotation === \"undefined\") {\n rotation = 0.0;\n }\n this.applyStrokeOpts(strokeOptions);\n this.ctx.beginPath();\n this.ctx.ellipse(this.offset.x + center.x * this.scale.x, this.offset.y + center.y * this.scale.y, radiusX * this.scale.x, radiusY * this.scale.y, rotation, 0.0, Math.PI * 2);\n this.ctx.closePath();\n this.ctx.lineWidth = lineWidth || 1;\n this._fillOrDraw(color);\n };\n /**\n * Draw square at the given center, size and with the specified (CSS-) color.<br>\n * <br>\n * Note that if the x-scale and the y-scale are different the result will be a rectangle rather than a square.\n *\n * @method square\n * @param {XYCoords} center - The center of the square.\n * @param {number} size - The size of the square.\n * @param {string} color - The CSS color to draw the square with.\n * @param {number} lineWidth - The line with to use (optional, default is 1).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.square = function (center, size, color, lineWidth, strokeOptions) {\n this.applyStrokeOpts(strokeOptions);\n this.ctx.beginPath();\n this.ctx.rect(this.offset.x + (center.x - size / 2.0) * this.scale.x, this.offset.y + (center.y - size / 2.0) * this.scale.y, size * this.scale.x, size * this.scale.y);\n this.ctx.closePath();\n this.ctx.lineWidth = lineWidth || 1;\n this._fillOrDraw(color);\n };\n /**\n * Draw a grid of horizontal and vertical lines with the given (CSS-) color.\n *\n * @method grid\n * @param {XYCoords} center - The center of the grid.\n * @param {number} width - The total width of the grid (width/2 each to the left and to the right).\n * @param {number} height - The total height of the grid (height/2 each to the top and to the bottom).\n * @param {number} sizeX - The horizontal grid size.\n * @param {number} sizeY - The vertical grid size.\n * @param {string} color - The CSS color to draw the grid with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.grid = function (center, width, height, sizeX, sizeY, color) {\n this.ctx.setLineDash([]); // Clear line-dash settings\n this.ctx.beginPath();\n var yMin = -Math.ceil((height * 0.5) / sizeY) * sizeY;\n var yMax = height / 2;\n for (var x = -Math.ceil((width * 0.5) / sizeX) * sizeX; x < width / 2; x += sizeX) {\n this.ctx.moveTo(this.offset.x + (center.x + x) * this.scale.x, this.offset.y + (center.y + yMin) * this.scale.y);\n this.ctx.lineTo(this.offset.x + (center.x + x) * this.scale.x, this.offset.y + (center.y + yMax) * this.scale.y);\n }\n var xMin = -Math.ceil((width * 0.5) / sizeX) * sizeX; // -Math.ceil((height*0.5)/sizeY)*sizeY;\n var xMax = width / 2; // height/2;\n for (var y = -Math.ceil((height * 0.5) / sizeY) * sizeY; y < height / 2; y += sizeY) {\n this.ctx.moveTo(this.offset.x + (center.x + xMin) * this.scale.x - 4, this.offset.y + (center.y + y) * this.scale.y);\n this.ctx.lineTo(this.offset.x + (center.x + xMax) * this.scale.x + 4, this.offset.y + (center.y + y) * this.scale.y);\n }\n this.ctx.strokeStyle = color;\n this.ctx.lineWidth = 1.0;\n this.ctx.stroke();\n this.ctx.closePath();\n };\n /**\n * Draw a raster of crosshairs in the given grid.<br>\n *\n * This works analogue to the grid() function\n *\n * @method raster\n * @param {XYCoords} center - The center of the raster.\n * @param {number} width - The total width of the raster (width/2 each to the left and to the right).\n * @param {number} height - The total height of the raster (height/2 each to the top and to the bottom).\n * @param {number} sizeX - The horizontal raster size.\n * @param {number} sizeY - The vertical raster size.\n * @param {string} color - The CSS color to draw the raster with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.raster = function (center, width, height, sizeX, sizeY, color) {\n this.ctx.save();\n this.ctx.setLineDash([]); // Clear line-dash settings\n this.ctx.beginPath();\n for (var x = -Math.ceil((width * 0.5) / sizeX) * sizeX; x < width / 2; x += sizeX) {\n for (var y = -Math.ceil((height * 0.5) / sizeY) * sizeY; y < height / 2; y += sizeY) {\n // Draw a crosshair\n this.ctx.moveTo(this.offset.x + (center.x + x) * this.scale.x - 4, this.offset.y + (center.y + y) * this.scale.y);\n this.ctx.lineTo(this.offset.x + (center.x + x) * this.scale.x + 4, this.offset.y + (center.y + y) * this.scale.y);\n this.ctx.moveTo(this.offset.x + (center.x + x) * this.scale.x, this.offset.y + (center.y + y) * this.scale.y - 4);\n this.ctx.lineTo(this.offset.x + (center.x + x) * this.scale.x, this.offset.y + (center.y + y) * this.scale.y + 4);\n }\n }\n this.ctx.strokeStyle = color;\n this.ctx.lineWidth = 1.0;\n this.ctx.stroke();\n this.ctx.closePath();\n this.ctx.restore();\n };\n /**\n * Draw a diamond handle (square rotated by 45°) with the given CSS color.\n *\n * It is an inherent feature of the handle functions that the drawn elements are not scaled and not\n * distorted. So even if the user zooms in or changes the aspect ratio, the handles will be drawn\n * as even shaped diamonds.\n *\n * @method diamondHandle\n * @param {XYCoords} center - The center of the diamond.\n * @param {number} size - The x/y-size of the diamond.\n * @param {string} color - The CSS color to draw the diamond with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.diamondHandle = function (center, size, color) {\n this.ctx.setLineDash([]); // Clear line-dash settings\n this.ctx.beginPath();\n this.ctx.moveTo(this.offset.x + center.x * this.scale.x - size / 2.0, this.offset.y + center.y * this.scale.y);\n this.ctx.lineTo(this.offset.x + center.x * this.scale.x, this.offset.y + center.y * this.scale.y - size / 2.0);\n this.ctx.lineTo(this.offset.x + center.x * this.scale.x + size / 2.0, this.offset.y + center.y * this.scale.y);\n this.ctx.lineTo(this.offset.x + center.x * this.scale.x, this.offset.y + center.y * this.scale.y + size / 2.0);\n this.ctx.closePath();\n this.ctx.lineWidth = 1;\n this._fillOrDraw(color);\n };\n /**\n * Draw a square handle with the given CSS color.<br>\n * <br>\n * It is an inherent feature of the handle functions that the drawn elements are not scaled and not\n * distorted. So even if the user zooms in or changes the aspect ratio, the handles will be drawn\n * as even shaped squares.\n *\n * @method squareHandle\n * @param {XYCoords} center - The center of the square.\n * @param {number} size - The x/y-size of the square.\n * @param {string} color - The CSS color to draw the square with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.squareHandle = function (center, size, color) {\n this.ctx.setLineDash([]); // Clear line-dash settings\n this.ctx.beginPath();\n this.ctx.rect(this.offset.x + center.x * this.scale.x - size / 2.0, this.offset.y + center.y * this.scale.y - size / 2.0, size, size);\n this.ctx.closePath();\n this.ctx.lineWidth = 1;\n this._fillOrDraw(color);\n };\n /**\n * Draw a circle handle with the given CSS color.<br>\n * <br>\n * It is an inherent feature of the handle functions that the drawn elements are not scaled and not\n * distorted. So even if the user zooms in or changes the aspect ratio, the handles will be drawn\n * as even shaped circles.\n *\n * @method circleHandle\n * @param {XYCoords} center - The center of the circle.\n * @param {number} radius - The radius of the circle.\n * @param {string} color - The CSS color to draw the circle with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.circleHandle = function (center, radius, color) {\n radius = radius || 3;\n this.ctx.setLineDash([]); // Clear line-dash settings\n this.ctx.beginPath();\n this.ctx.arc(this.offset.x + center.x * this.scale.x, this.offset.y + center.y * this.scale.y, radius, 0, 2 * Math.PI, false);\n this.ctx.closePath();\n this.ctx.lineWidth = 1;\n this._fillOrDraw(color);\n };\n /**\n * Draw a crosshair with given radius and color at the given position.<br>\n * <br>\n * Note that the crosshair radius will not be affected by scaling.\n *\n * @method crosshair\n * @param {XYCoords} center - The center of the crosshair.\n * @param {number} radius - The radius of the crosshair.\n * @param {string} color - The CSS color to draw the crosshair with.\n * @param {number=0.5} lineWidth - (optional, default=0.5) The line width to use.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.crosshair = function (center, radius, color, lineWidth) {\n this.ctx.save();\n this.ctx.setLineDash([]); // Clear line-dash settings\n this.ctx.beginPath();\n this.ctx.moveTo(this.offset.x + center.x * this.scale.x - radius, this.offset.y + center.y * this.scale.y);\n this.ctx.lineTo(this.offset.x + center.x * this.scale.x + radius, this.offset.y + center.y * this.scale.y);\n this.ctx.moveTo(this.offset.x + center.x * this.scale.x, this.offset.y + center.y * this.scale.y - radius);\n this.ctx.lineTo(this.offset.x + center.x * this.scale.x, this.offset.y + center.y * this.scale.y + radius);\n this.ctx.strokeStyle = color;\n this.ctx.lineWidth = lineWidth || 0.5;\n this.ctx.stroke();\n this.ctx.closePath();\n this.ctx.restore();\n };\n /**\n * Draw a cross with diagonal axes with given radius, color and lineWidth at the given position.<br>\n * <br>\n * Note that the x's radius will not be affected by scaling.\n *\n * @method crosshair\n * @param {XYCoords} center - The center of the crosshair.\n * @param {number} radius - The radius of the crosshair.\n * @param {string} color - The CSS color to draw the crosshair with.\n * @param {number=1} lineWidth - (optional, default=1.0) The line width to use.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.cross = function (center, radius, color, lineWidth) {\n this.ctx.save();\n this.ctx.setLineDash([]); // Clear line-dash settings\n this.ctx.beginPath();\n this.ctx.moveTo(this.offset.x + center.x * this.scale.x - radius, this.offset.y + center.y * this.scale.y - radius);\n this.ctx.lineTo(this.offset.x + center.x * this.scale.x + radius, this.offset.y + center.y * this.scale.y + radius);\n this.ctx.moveTo(this.offset.x + center.x * this.scale.x - radius, this.offset.y + center.y * this.scale.y + radius);\n this.ctx.lineTo(this.offset.x + center.x * this.scale.x + radius, this.offset.y + center.y * this.scale.y - radius);\n this.ctx.strokeStyle = color;\n this.ctx.lineWidth = lineWidth || 1.0;\n this.ctx.stroke();\n this.ctx.closePath();\n this.ctx.restore();\n };\n /**\n * Draw a polygon.\n *\n * @method polygon\n * @param {Polygon} polygon - The polygon to draw.\n * @param {string} color - The CSS color to draw the polygon with.\n * @param {string} lineWidth - The line width to use.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.polygon = function (polygon, color, lineWidth, strokeOptions) {\n this.polyline(polygon.vertices, polygon.isOpen, color, lineWidth, strokeOptions);\n };\n /**\n * Draw a polygon line (alternative function to the polygon).\n *\n * @method polyline\n * @param {XYCoords[]} vertices - The polygon vertices to draw.\n * @param {boolan} isOpen - If true the polyline will not be closed at its end.\n * @param {string} color - The CSS color to draw the polygon with.\n * @param {number} lineWidth - The line width (default is 1.0);\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.polyline = function (vertices, isOpen, color, lineWidth, strokeOptions) {\n if (vertices.length <= 1) {\n return;\n }\n this.ctx.save();\n this.applyStrokeOpts(strokeOptions);\n this.ctx.beginPath();\n this.ctx.lineWidth = lineWidth || 1.0;\n this.ctx.moveTo(this.offset.x + vertices[0].x * this.scale.x, this.offset.y + vertices[0].y * this.scale.y);\n for (var i = 0; i < vertices.length; i++) {\n this.ctx.lineTo(this.offset.x + vertices[i].x * this.scale.x, this.offset.y + vertices[i].y * this.scale.y);\n }\n if (!isOpen)\n // && vertices.length > 2 )\n this.ctx.closePath();\n this._fillOrDraw(color);\n this.ctx.closePath();\n this.ctx.setLineDash([]);\n this.ctx.restore();\n };\n /**\n * Draw a text at the given relative position.\n *\n * @method text\n * @param {string} text - The text to draw.\n * @param {number} x - The x-position to draw the text at.\n * @param {number} y - The y-position to draw the text at.\n * @param {string=} options.color - The Color to use.\n * @param {string=} options.fontFamily - The font family to use.\n * @param {number=} options.fontSize - The font size (in pixels) to use.\n * @param {FontStyle=} options.fontStyle - The font style to use.\n * @param {FontWeight=} options.fontWeight - The font weight to use.\n * @param {number=} options.lineHeight - The line height (in pixels) to use.\n * @param {number=} options.rotation - The (optional) rotation in radians.\n * @param {string=} options.textAlign - The text align to use. According to the specifiactions (https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign) valid values are `\"left\" || \"right\" || \"center\" || \"start\" || \"end\"`.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.text = function (text, x, y, options) {\n // See https://stackoverflow.com/a/23523697\n var _a, _b, _c;\n options = options || {};\n this.ctx.save();\n var relX = this.offset.x + x * this.scale.x;\n var relY = this.offset.y + y * this.scale.y;\n var color = options.color || \"black\";\n if (options.fontSize || options.fontFamily) {\n // Scaling of text only works in uniform mode\n this.ctx.font =\n (options.fontWeight ? options.fontWeight + \" \" : \"\") +\n (options.fontStyle ? options.fontStyle + \" \" : \"\") +\n (options.fontSize ? options.fontSize * this.scale.x + \"px \" : \" \") +\n (options.fontFamily\n ? options.fontFamily.indexOf(\" \") === -1\n ? options.fontFamily\n : \"\\\"\".concat(options.fontFamily, \"\\\"\")\n : \"Arial\");\n }\n if (options.textAlign) {\n this.ctx.textAlign = options.textAlign;\n }\n var rotation = (_a = options.rotation) !== null && _a !== void 0 ? _a : 0.0;\n var lineHeight = ((_c = (_b = options.lineHeight) !== null && _b !== void 0 ? _b : options.fontSize) !== null && _c !== void 0 ? _c : 0) * this.scale.x;\n this.ctx.translate(relX, relY);\n this.ctx.rotate(rotation);\n if (this.fillShapes) {\n this.ctx.fillStyle = color;\n this.ctx.fillText(text, 0, lineHeight / 2);\n }\n else {\n this.ctx.strokeStyle = color;\n this.ctx.strokeText(text, 0, lineHeight / 2);\n }\n // this.ctx.translate(-relX, -relY);\n // this.ctx.rotate(-rotation); // is this necessary before 'restore()'?\n this.ctx.restore();\n };\n /**\n * Draw a non-scaling text label at the given position.\n *\n * Note that these are absolute label positions, they are not affected by offset or scale.\n *\n * @method label\n * @param {string} text - The text to draw.\n * @param {number} x - The x-position to draw the text at.\n * @param {number} y - The y-position to draw the text at.\n * @param {number=} rotation - The (optional) rotation in radians (default=0).\n * @param {string=} color - The color to render the text with (default=black).\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.label = function (text, x, y, rotation, color) {\n this.ctx.save();\n this.ctx.font = \"lighter 9pt Arial\";\n this.ctx.translate(x, y);\n if (typeof rotation !== \"undefined\")\n this.ctx.rotate(rotation);\n this.ctx.fillStyle = color || \"black\";\n if (this.fillShapes) {\n this.ctx.fillText(text, 0, 0);\n }\n else {\n this.ctx.strokeText(text, 0, 0);\n }\n this.ctx.restore();\n };\n /**\n * Draw an SVG-like path given by the specified path data.\n *\n *\n * @method path\n * @param {SVGPathData} pathData - An array of path commands and params.\n * @param {string=null} color - (optional) The color to draw this path with (default is null).\n * @param {number=1} lineWidth - (optional) the line width to use (default is 1).\n * @param {boolean=false} options.inplace - (optional) If set to true then path transforamtions (scale and translate) will be done in-place in the array. This can boost the performance.\n * @param {number=} options.dashOffset - (optional) `See StrokeOptions`.\n * @param {number=[]} options.dashArray - (optional) `See StrokeOptions`.\n * @instance\n * @memberof drawutils\n * @return {R} An instance representing the drawn path.\n */\n drawutils.prototype.path = function (pathData, color, lineWidth, options) {\n var d = options && options.inplace ? pathData : drawutilssvg_1.drawutilssvg.copyPathData(pathData);\n drawutilssvg_1.drawutilssvg.transformPathData(d, this.offset, this.scale);\n if (color) {\n this.ctx.strokeStyle = color;\n }\n this.ctx.lineWidth = lineWidth || 1;\n this.applyStrokeOpts(options);\n if (this.fillShapes) {\n if (color) {\n this.ctx.fillStyle = color;\n }\n this.ctx.fill(new Path2D(d.join(\" \")));\n }\n else {\n if (color) {\n this.ctx.strokeStyle = color;\n }\n this.ctx.stroke(new Path2D(d.join(\" \")));\n }\n };\n /**\n * Due to gl compatibility there is a generic 'clear' function required\n * to avoid accessing the context object itself directly.\n *\n * This function just fills the whole canvas with a single color.\n *\n * @param {string} color - The color to clear with.\n **/\n drawutils.prototype.clear = function (color) {\n this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);\n this.ctx.fillStyle = color;\n this.ctx.fillRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);\n };\n drawutils.helpers = {\n // A helper function to define the clipping path.\n // This could be a candidate for the draw library.\n clipPoly: function (ctx, offset, scale, vertices) {\n ctx.beginPath();\n // Set clip mask\n ctx.moveTo(offset.x + vertices[0].x * scale.x, offset.y + vertices[0].y * scale.y);\n for (var i = 1; i < vertices.length; i++) {\n var vert = vertices[i];\n ctx.lineTo(offset.x + vert.x * scale.x, offset.y + vert.y * scale.y);\n }\n ctx.closePath();\n ctx.clip();\n }\n };\n return drawutils;\n}());\nexports.drawutils = drawutils;\n//# sourceMappingURL=draw.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2020-05-11\n * @modified 2020-10-30 Added the static computeFromVertices function.\n * @modified 2020-11-19 Set min, max, width and height to private.\n * @modified 2021-02-02 Added the `toPolygon` method.\n * @modified 2021-06-21 (mid-summer) Added `getCenter` method.\n * @modified 2022-02-01 Added the `toString` function.\n * @modified 2022-10-09 Added the `fromDimension` function.\n * @modified 2022-11-28 Added the `clone` method.\n * @modified 2023-09-29 Added the `randomPoint` method.\n * @modified 2025-03-23 Added the `getMinDimension` and `getMaxDimension` methods.\n * @modified 2025-04-18 Change parameter type in `Bounds.computeFromVertices` from `Vertex` to more general `XYCoords`.\n * @modified 2025-04-19 Added methods to `Bounds` class: `getNorthPoint`, `getSouthPoint`, `getEastPoint` and `getWestPoint`.\n * @modified 2025-04-26 Added static method `Bounds.computeFromBoundsSet` to calculate containing bounds for a set of bounding boxes.\n * @modified 2025-10-17 Added the methods `Bounds.getSouthWestPoint`, `getNorthWestPoint`, `getNorthEastPoint` and `getSouthEastPoint`.\n * @modified 2025-10-18 Added method `Bounds.containsVert(XYCoords)`.\n * @modified 2025-10-28 Added the `Bounds.getWidth()` and `Bounds.getHeight()`.\n * @modified 2025-11-12 Added the `Bounds.getMoved()` method.\n * @version 1.11.0\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Bounds = void 0;\nvar Polygon_1 = require(\"./Polygon\");\nvar Vertex_1 = require(\"./Vertex\");\n/**\n * @classdesc A bounds class with min and max values. Implementing IBounds.\n *\n * @requires XYCoords\n * @requires Vertex\n * @requires IBounds\n **/\nvar Bounds = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name Bounds\n * @param {XYCoords} min - The min values (x,y) as a XYCoords tuple.\n * @param {XYCoords} max - The max values (x,y) as a XYCoords tuple.\n **/\n function Bounds(min, max) {\n this.min = min;\n this.max = max;\n this.width = max.x - min.x;\n this.height = max.y - min.y;\n }\n /**\n * Check if the given vertex is inside this bounds.\n *\n * @method containsVert\n * @param {XYCoords} vert - The vertex to check.\n * @return {boolean} True if the passed vertex is inside this bounds.\n * @instance\n * @memberof Bounds\n **/\n Bounds.prototype.containsVert = function (vert) {\n return this.min.x <= vert.x && vert.x < this.max.x && this.min.y <= vert.y && vert.y < this.max.y;\n };\n Bounds.prototype.getWidth = function () {\n return this.max.x - this.min.x;\n };\n Bounds.prototype.getHeight = function () {\n return this.max.y - this.min.y;\n };\n Bounds.prototype.getScaled = function (scaleFactor) {\n var center = this.getCenter();\n var newMin = new Vertex_1.Vertex(this.min).scale(scaleFactor, center);\n var newMax = new Vertex_1.Vertex(this.max).scale(scaleFactor, center);\n return new Bounds(newMin, newMax);\n };\n Bounds.prototype.getMoved = function (moveAmount) {\n var newMin = new Vertex_1.Vertex(this.min).move(moveAmount);\n var newMax = new Vertex_1.Vertex(this.max).move(moveAmount);\n return new Bounds(newMin, newMax);\n };\n /**\n * Get the center point of the north bound.\n *\n * @method getNorthPoint\n * @instance\n * @memberof Bounds\n * @return {Vertex} The \"northmost\" centered point of this bounding box.\n */\n Bounds.prototype.getNorthPoint = function () {\n return new Vertex_1.Vertex(this.min.x + this.width / 2.0, this.min.y);\n };\n /**\n * Get the center point of the south bound.\n *\n * @method getNorthPoint\n * @instance\n * @memberof Bounds\n * @return {Vertex} The \"southhmost\" centered point of this bounding box.\n */\n Bounds.prototype.getSouthPoint = function () {\n return new Vertex_1.Vertex(this.min.x + this.width / 2.0, this.max.y);\n };\n /**\n * Get the center point of the west bound.\n *\n * @method getWestPoint\n * @instance\n * @memberof Bounds\n * @return {Vertex} The \"westhmost\" centered point of this bounding box.\n */\n Bounds.prototype.getWestPoint = function () {\n return new Vertex_1.Vertex(this.min.x, this.min.y + this.height / 2.0);\n };\n /**\n * Get the center point of the east bound.\n *\n * @method getEastPoint\n * @instance\n * @memberof Bounds\n * @return {Vertex} The \"easthmost\" centered point of this bounding box.\n */\n Bounds.prototype.getEastPoint = function () {\n return new Vertex_1.Vertex(this.max.x, this.min.y + this.height / 2.0);\n };\n /**\n * Get the upper left corner point these bounds box.\n *\n * @method getNorthWestPoint\n * @instance\n * @memberof Bounds\n * @return {Vertex} The \"northwestmost\" point of this bounding box.\n */\n Bounds.prototype.getNorthWestPoint = function () {\n return new Vertex_1.Vertex(this.min.x, this.min.y);\n };\n /**\n * Get the upper right corner point these bounds box.\n *\n * @method getNorthEastPoint\n * @instance\n * @memberof Bounds\n * @return {Vertex} The \"northeastmost\" point of this bounding box.\n */\n Bounds.prototype.getNorthEastPoint = function () {\n return new Vertex_1.Vertex(this.max.x, this.min.y);\n };\n /**\n * Get the lower right corner point these bounds box.\n *\n * @method getSouthEastPoint\n * @instance\n * @memberof Bounds\n * @return {Vertex} The \"southeastmost\" point of this bounding box.\n */\n Bounds.prototype.getSouthEastPoint = function () {\n return new Vertex_1.Vertex(this.max.x, this.max.y);\n };\n /**\n * Get the lower left corner point these bounds box.\n *\n * @method getSouthWestPoint\n * @instance\n * @memberof Bounds\n * @return {Vertex} The \"southwestmost\" point of this bounding box.\n */\n Bounds.prototype.getSouthWestPoint = function () {\n return new Vertex_1.Vertex(this.min.x, this.max.y);\n };\n /**\n * Convert this rectangular bounding box to a polygon with four vertices.\n *\n * @method toPolygon\n * @instance\n * @memberof Bounds\n * @return {Polygon} This bound rectangle as a polygon.\n */\n Bounds.prototype.toPolygon = function () {\n return new Polygon_1.Polygon([new Vertex_1.Vertex(this.min), new Vertex_1.Vertex(this.max.x, this.min.y), new Vertex_1.Vertex(this.max), new Vertex_1.Vertex(this.min.x, this.max.y)], false);\n };\n /**\n * Get the center of this boinding box.\n *\n * @method getCenter\n * @instance\n * @memberof Bounds\n * @returns {Vertex} The center of these bounds.\n */\n Bounds.prototype.getCenter = function () {\n return new Vertex_1.Vertex(this.min.x + (this.max.x - this.min.x) / 2.0, this.min.y + (this.max.y - this.min.y) / 2);\n };\n /**\n * Get the minimum of `width` and `height`.\n *\n * @returns {number} The value of Math.min( this.width, this.height )\n */\n Bounds.prototype.getMinDimension = function () {\n return Math.min(this.width, this.height);\n };\n /**\n * Get the minimum of `width` and `height`.\n *\n * @returns {number} The value of Math.min( this.width, this.height )\n */\n Bounds.prototype.getMaxDimension = function () {\n return Math.max(this.width, this.height);\n };\n /**\n * Generate a random point inside this bounds object. Safe areas at the border to avoid\n * included.\n *\n * @method randomPoint\n * @instance\n * @memberof Bounds\n * @param {horizontalSafeArea} - (optional) The horizonal (left and right) safe area. No vertex will be created here. Can be used as percent in (0.0 ... 0.1) interval.\n * @param {verticalSafeArea} - (optional) The vertical (top and bottom) safe area. No vertex will be created here. Can be used as percent in (0.0 ... 0.1) interval\n * @returns {Vertex} A pseudo random point inside these bounds.\n */\n Bounds.prototype.randomPoint = function (horizontalSafeArea, verticalSafeArea) {\n if (horizontalSafeArea === void 0) { horizontalSafeArea = 0; }\n if (verticalSafeArea === void 0) { verticalSafeArea = 0; }\n // Check if the safe areas are meant as percent\n var absHorizontalSafeArea = horizontalSafeArea > 0 && horizontalSafeArea < 1 ? this.width * horizontalSafeArea : horizontalSafeArea;\n var absVerticalSafeArea = verticalSafeArea > 0 && verticalSafeArea < 1 ? this.height * verticalSafeArea : verticalSafeArea;\n return new Vertex_1.Vertex(this.min.x + absHorizontalSafeArea + Math.random() * (this.width - 2 * absHorizontalSafeArea), this.min.y + absVerticalSafeArea + Math.random() * (this.height - 2 * absVerticalSafeArea));\n };\n /**\n * Convert these bounds to a human readable form.\n *\n * Note: the returned format might change in the future, so please do not\n * rely on the returned string format.\n *\n * @method toString\n * @instance\n * @memberof Bounds\n * @returns {string} Get these bounds in a human readable form.\n */\n Bounds.prototype.toString = function () {\n return \"{ min: \".concat(this.min.toString(), \", max : \").concat(this.max.toString(), \", width: \").concat(this.width, \", height : \").concat(this.height, \" }\");\n };\n /**\n * Clone this bounds object (create a deep clone).\n *\n * @method clone\n * @instance\n * @memberof Bounds\n * @returns {Bounds} Creates a deep clone of this bounds object.\n */\n Bounds.prototype.clone = function () {\n return new Bounds({ x: this.min.x, y: this.min.y }, { x: this.max.x, y: this.max.y });\n };\n /**\n * Compute the minimal bounding box for a given set of vertices.\n *\n * An empty vertex array will return an empty bounding box located at (0,0).\n *\n * @static\n * @method computeFromVertices\n * @memberof Bounds\n * @param {Array<XYCoords>} vertices - The set of vertices you want to get the bounding box for.\n * @return The minimal Bounds for the given vertices.\n **/\n Bounds.computeFromVertices = function (vertices) {\n if (vertices.length == 0) {\n return new Bounds(new Vertex_1.Vertex(0, 0), new Vertex_1.Vertex(0, 0));\n }\n var xMin = vertices[0].x;\n var xMax = vertices[0].x;\n var yMin = vertices[0].y;\n var yMax = vertices[0].y;\n var vert;\n for (var i in vertices) {\n vert = vertices[i];\n xMin = Math.min(xMin, vert.x);\n xMax = Math.max(xMax, vert.x);\n yMin = Math.min(yMin, vert.y);\n yMax = Math.max(yMax, vert.y);\n }\n return new Bounds(new Vertex_1.Vertex(xMin, yMin), new Vertex_1.Vertex(xMax, yMax));\n };\n /**\n * Compute the minimal bounding box for a given set of existing bounding boxes.\n *\n * An empty vertex array will return an empty bounding box located at (0,0).\n *\n * @static\n * @method computeFromBoundsSet\n * @memberof Bounds\n * @param {Array<IBounds>} boundingBoxes - The set of existing bounding boxes to get the containing bounding box for.\n * @return The minimal Bounds for the given bounds instances.\n **/\n Bounds.computeFromBoundsSet = function (boundingBoxes) {\n if (boundingBoxes.length == 0) {\n return new Bounds(new Vertex_1.Vertex(0, 0), new Vertex_1.Vertex(0, 0));\n }\n var xMin = boundingBoxes[0].min.x;\n var xMax = boundingBoxes[0].max.x;\n var yMin = boundingBoxes[0].min.y;\n var yMax = boundingBoxes[0].min.y;\n var bounds;\n for (var i in boundingBoxes) {\n bounds = boundingBoxes[i];\n xMin = Math.min(xMin, bounds.min.x);\n xMax = Math.max(xMax, bounds.max.x);\n yMin = Math.min(yMin, bounds.min.y);\n yMax = Math.max(yMax, bounds.min.y);\n }\n return new Bounds(new Vertex_1.Vertex(xMin, yMin), new Vertex_1.Vertex(xMax, yMax));\n };\n /**\n * Create a new `Bounds` instance just from `width` and `height`, located at (0,0) or the optionally given origin.\n *\n * @param {number} width - The width of the bounds\n * @param {number} height - The height of the bounds\n * @param {XYCoords={x:0,y:0}} origin - [optional] A origin to locate the new Bounds object at.\n * @returns {Bounds} A new `Bounds` instance width given width and height, located at (0,0) or the given origin..\n */\n Bounds.fromDimension = function (width, height, origin) {\n return new Bounds(origin !== null && origin !== void 0 ? origin : { x: 0, y: 0 }, { x: (origin ? origin.x : 0) + width, y: (origin ? origin.y : 0) + height });\n };\n return Bounds;\n}()); // END class bounds\nexports.Bounds = Bounds;\n//# sourceMappingURL=Bounds.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2020-05-04\n * @modified 2020-05-09 Ported to typescript.\n * @modified 2020-05-25 Added the vertAt and tangentAt functions.\n * @mofidied 2020-09-07 Added the circleIntersection(Circle) function.\n * @modified 2020-09-07 Changed the vertAt function by switching sin and cos! The old version did not return the correct vertex (by angle) accoring to the assumed circle math.\n * @modified 2020-10-16 Added the containsCircle(...) function.\n * @modified 2021-01-20 Added UID.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-02-02 Cleared the `toSVGString` function (deprecated). Use `drawutilssvg` instead.\n * @modified 2022-08-15 Added the `containsPoint` function.\n * @modified 2022-08-23 Added the `lineIntersection` function.\n * @modified 2022-08-23 Added the `closestPoint` function.\n * @modified 2025-04-09 Added the `Circle.move(amount: XYCoords)` method.\n * @modified 2025-04-16 Class `Circle` now implements interface `Intersectable`.\n * @modified 2026-06-10 Adding the utility function `Circle.circleUtils.containsPoint`.\n * @modified 2026-06-10 Adding the `Circle.clone` method.\n * @modified 2026-01-13 Adding helper function `Circle.circleUtils.containsPoint` and refactored the member method `containsPoint`.\n * @modified 2026-07-03 Adding the optional `epsilon` parameter to the `Circle.containsCircle` method.\n * @modified 2026-07-03 Fixing the `Circle.clone` method; the center had not been cloned at all, this was fixed.\n * @modified 2026-07-08 Adding the `Circle.setRadius` method (for chaining).\n * @mofified 2026-07-31 Adding the `radicalAxis(Circle)` method. Added the `Circle.circleUtils.createRadicalAxisHelperCircle` and `.circleDistance` helper methods.\n * @modified 2026-08-03 Adding `Circle.tangentsFromPoint`.\n * @version 1.7.0\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Circle = void 0;\nvar Bounds_1 = require(\"./Bounds\");\nvar Line_1 = require(\"./Line\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar Vector_1 = require(\"./Vector\");\nvar Vertex_1 = require(\"./Vertex\");\nvar geomutils_1 = require(\"./geomutils\");\n/**\n * @classdesc A simple circle: center point and radius.\n *\n * @requires Line\n * @requires Vector\n * @requires VertTuple\n * @requires Vertex\n * @requires SVGSerializale\n * @requires UID\n * @requires UIDGenerator\n **/\nvar Circle = /** @class */ (function () {\n /**\n * Create a new circle with given center point and radius.\n *\n * @constructor\n * @name Circle\n * @param {Vertex} center - The center point of the circle.\n * @param {number} radius - The radius of the circle.\n */\n function Circle(center, radius) {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"Circle\";\n this.uid = UIDGenerator_1.UIDGenerator.next();\n this.center = center;\n this.radius = radius;\n }\n /**\n * Set the radius of this circle.\n * The method is meant for chaining, you may also alter the `radius` attribute directly.\n *\n * @method setRadius\n * @param {number} radius - The amount to move.\n * @instance\n * @memberof Circle\n * @return {Circle} this for chaining\n **/\n Circle.prototype.setRadius = function (radius) {\n this.radius = radius;\n return this;\n };\n /**\n * Move the circle by the given amount.\n *\n * @method move\n * @param {XYCoords} amount - The amount to move.\n * @instance\n * @memberof Circle\n * @return {Circle} this for chaining\n **/\n Circle.prototype.move = function (amount) {\n this.center.add(amount);\n return this;\n };\n /**\n * Check if the given circle is fully contained inside this circle.\n *\n * @method containsPoint\n * @param {XYCoords} point - The point to check if it is contained in this circle.\n * @instance\n * @memberof Circle\n * @return {boolean} `true` if the given point is inside this circle.\n */\n Circle.prototype.containsPoint = function (point) {\n // return this.center.distance(point) < this.radius;//\n return Circle.circleUtils.containsPoint(this.center, this.radius, point);\n };\n /**\n * Check if the given circle is fully contained inside this circle.\n *\n * @method containsCircle\n * @param {Circle} circle - The circle to check if it is contained in this circle.\n * @instance\n * @memberof Circle\n * @return {boolean} `true` if any only if the given circle is completely inside this circle.\n */\n Circle.prototype.containsCircle = function (circle, epsilon) {\n if (typeof epsilon === \"undefined\" || Number.isNaN(epsilon)) {\n return this.center.distance(circle.center) + circle.radius < this.radius;\n }\n else {\n return this.center.distance(circle.center) + circle.radius < this.radius + Math.abs(epsilon);\n }\n };\n /**\n * Calculate the distance from this circle to the given line.\n *\n * * If the line does not intersect this ciecle then the returned\n * value will be the minimal distance.\n * * If the line goes through this circle then the returned value\n * will be max inner distance and it will be negative.\n *\n * @method lineDistance\n * @param {Line} line - The line to measure the distance to.\n * @return {number} The minimal distance from the outline of this circle to the given line.\n * @instance\n * @memberof Circle\n */\n Circle.prototype.lineDistance = function (line) {\n var closestPointOnLine = line.getClosestPoint(this.center);\n return closestPointOnLine.distance(this.center) - this.radius;\n };\n /**\n * Get the vertex on the this circle for the given angle.\n *\n * @method vertAt\n * @param {number} angle - The angle (in radians) to use.\n * @return {Vertex} The vertex (point) at the given angle.\n * @instance\n * @memberof Circle\n **/\n Circle.prototype.vertAt = function (angle) {\n // Find the point on the circle respective the angle. Then move relative to center.\n return Circle.circleUtils.vertAt(angle, this.radius).add(this.center);\n };\n /**\n * Get a tangent line of this circle for a given angle.\n *\n * Point a of the returned line is located on the circle, the length equals the radius.\n *\n * @method tangentAt\n * @instance\n * @param {number} angle - The angle (in radians) to use.\n * @return {Line} The tangent line.\n * @memberof Circle\n **/\n Circle.prototype.tangentAt = function (angle) {\n var pointA = Circle.circleUtils.vertAt(angle, this.radius);\n // Construct the perpendicular of the line in point a. Then move relative to center.\n return new Vector_1.Vector(pointA, new Vertex_1.Vertex(0, 0)).add(this.center).perp();\n // return (new Vector(this.center.clone(), pointA).add(pointA) as Vector).perp() as Vector;\n };\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get the bounding box (bounds) of this Circle.\n *\n * @method getBounds\n * @instance\n * @memberof Circle\n * @return {Bounds} The rectangular bounds of this Circle.\n **/\n Circle.prototype.getBounds = function () {\n return new Bounds_1.Bounds(this.center.clone().subXY(Math.abs(this.radius), Math.abs(this.radius)), this.center.clone().addXY(Math.abs(this.radius), Math.abs(this.radius)));\n };\n //--- END --- Implement interface `Intersectable`\n /**\n * Calculate the intersection points (if exists) with the given circle.\n *\n * @method circleIntersection\n * @instance\n * @memberof Circle\n * @param {Circle} circle\n * @return {Line|null} The intersection points (as a line) or null if the two circles do not intersect.\n **/\n Circle.prototype.circleIntersection = function (circle) {\n // Circles do not intersect at all?\n if (this.center.distance(circle.center) > this.radius + circle.radius) {\n return null;\n }\n // One circle is fully inside the other?\n if (this.center.distance(circle.center) < Math.abs(this.radius - circle.radius)) {\n return null;\n }\n // Based on the C++ implementation by Robert King\n // https://stackoverflow.com/questions/3349125/circle-circle-intersection-points\n // and the 'Circles and spheres' article by Paul Bourke.\n // http://paulbourke.net/geometry/circlesphere/\n //\n // This is the original C++ implementation:\n //\n // pair<Point, Point> intersections(Circle c) {\n // Point P0(x, y);\n // Point P1(c.x, c.y);\n // float d, a, h;\n // d = P0.distance(P1);\n // a = (r*r - c.r*c.r + d*d)/(2*d);\n // h = sqrt(r*r - a*a);\n // Point P2 = P1.sub(P0).scale(a/d).add(P0);\n // float x3, y3, x4, y4;\n // x3 = P2.x + h*(P1.y - P0.y)/d;\n // y3 = P2.y - h*(P1.x - P0.x)/d;\n // x4 = P2.x - h*(P1.y - P0.y)/d;\n // y4 = P2.y + h*(P1.x - P0.x)/d;\n // return pair<Point, Point>(Point(x3, y3), Point(x4, y4));\n // }\n var p0 = this.center;\n var p1 = circle.center;\n var d = p0.distance(p1);\n var a = (this.radius * this.radius - circle.radius * circle.radius + d * d) / (2 * d);\n var h = Math.sqrt(this.radius * this.radius - a * a);\n var p2 = p1.clone().scale(a / d, p0);\n var x3 = p2.x + (h * (p1.y - p0.y)) / d;\n var y3 = p2.y - (h * (p1.x - p0.x)) / d;\n var x4 = p2.x - (h * (p1.y - p0.y)) / d;\n var y4 = p2.y + (h * (p1.x - p0.x)) / d;\n return new Line_1.Line(new Vertex_1.Vertex(x3, y3), new Vertex_1.Vertex(x4, y4));\n };\n /**\n * Calculate the intersection points (if exists) with the given infinite line (defined by two points).\n *\n * @method lineIntersection\n * @instance\n * @memberof Circle\n * @param {Vertex} a- The first of the two points defining the line.\n * @param {XYCoords} b - The second of the two points defining the line.\n * @return {Line|null} The intersection points (as a line) or null if this circle does not intersect the line given.\n **/\n Circle.prototype.lineIntersection = function (a, b) {\n // Based on the math from\n // https://mathworld.wolfram.com/Circle-LineIntersection.html\n var interA = new Vertex_1.Vertex();\n var interB = new Vertex_1.Vertex();\n // First do a transformation, because the calculation is based on a cicle at (0,0)\n var transA = new Vertex_1.Vertex(a).sub(this.center);\n var transB = new Vertex_1.Vertex(b).sub(this.center);\n var diff = transA.difference(transB);\n // There is a special case if diff.y=0, where the intersection is not calcuatable.\n // Use an non-zero epsilon here to approximate this case.\n // TODO for the future: find a better solution\n if (Math.abs(diff.y) === 0) {\n diff.y = 0.000001;\n }\n var dist = transA.distance(transB);\n var det = transA.x * transB.y - transA.y * transB.x;\n var distSquared = dist * dist;\n var radiusSquared = this.radius * this.radius;\n // Check if circle and line have an intersection at all\n if (radiusSquared * distSquared - det * det < 0) {\n return null;\n }\n var belowSqrt = this.radius * this.radius * dist * dist - det * det;\n var sqrt = Math.sqrt(belowSqrt);\n interA.x = (det * diff.y + Math.sign(diff.y) * diff.x * sqrt) / distSquared;\n interB.x = (det * diff.y - Math.sign(diff.y) * diff.x * sqrt) / distSquared;\n interA.y = (-det * diff.x + Math.abs(diff.y) * sqrt) / distSquared;\n interB.y = (-det * diff.x - Math.abs(diff.y) * sqrt) / distSquared;\n return new Line_1.Line(interA.add(this.center), interB.add(this.center));\n };\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get all line intersections with this circle.\n *\n * This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.\n *\n * @param {VertTuple} line - The line to find intersections with.\n * @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).\n * @returns {Array<Vertex>} - An array of all intersections with the circle outline.\n */\n Circle.prototype.lineIntersections = function (line, inVectorBoundsOnly) {\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersections of all lines inside the edge bounds\n var intersectioLine = this.lineIntersection(line.a, line.b);\n if (!intersectioLine) {\n return [];\n }\n if (inVectorBoundsOnly) {\n // const maxDist = line.length();\n return [intersectioLine.a, intersectioLine.b].filter(function (vert) { return line.hasPoint(vert, true); });\n }\n else {\n return [intersectioLine.a, intersectioLine.b];\n }\n };\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @param line\n * @param lineIntersectionTangents\n * @returns\n */\n Circle.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersections of all lines plus their tangents inside the circle bounds\n var interSectionPoints = this.lineIntersections(line, inVectorBoundsOnly);\n return interSectionPoints.map(function (vert) {\n // Calculate angle\n var lineFromCenter = new Line_1.Line(_this.center, vert);\n var angle = lineFromCenter.angle();\n // console.log(\"angle\", (angle / Math.PI) * 180.0);\n // const angle = Math.random() * Math.PI * 2; // TODO\n // Calculate tangent at angle\n return _this.tangentAt(angle);\n });\n };\n //--- END --- Implement interface `Intersectable`\n /**\n * Calculate the radical axis of this and a different circle.\n * The two circles must not be co-centric.\n *\n * See this article for details:\n * https://www.cut-the-knot.org/Curriculum/Geometry/GeoGebra/RadicalAxes.shtml\n *\n * @method radicalAxis\n * @instance\n * @memberof Circle\n * @param {Circle} circleB - The second circle to calculated the radical axis for.\n * @return {Line} A line defining the radical axis of the two circles.\n **/\n Circle.prototype.radicalAxis = function (circleB) {\n var helperCircle = Circle.circleUtils.createRadicalAxisHelperCircle(this, circleB);\n var intersectionLineA = this.circleIntersection(helperCircle);\n var intersectionLineB = circleB.circleIntersection(helperCircle);\n var intersection = this.circleIntersection(circleB);\n if (!intersectionLineA || !intersectionLineB) {\n console.error(\"Critical error: none of the two intersections must be null.\");\n return intersection; // Fallback\n }\n var lineA = new Line_1.Line(intersectionLineA.a, intersectionLineA.b);\n var lineB = new Line_1.Line(intersectionLineB.a, intersectionLineB.b);\n var firstRadicalAxisPoint = lineA.intersection(lineB);\n var centerConnectLine = new Line_1.Line(this.center, circleB.center);\n var secondRadicalAxisPoint = centerConnectLine.getClosestPoint(firstRadicalAxisPoint);\n // Create a mirrored version of the second radical axis point so both are located\n // symmetrical from the circle connect point.\n // (currently the second point is located ON the connect line)\n var secondRadicalAxisPoint_mirrored = secondRadicalAxisPoint.clone().scale(2.0, firstRadicalAxisPoint);\n var radicalAxis = new Line_1.Line(firstRadicalAxisPoint, secondRadicalAxisPoint_mirrored);\n return intersection && intersection.length() > radicalAxis.length() ? intersection : radicalAxis;\n };\n /**\n * Calculate the closest point on the outline of this circle to the given point.\n *\n * @method closestPoint\n * @instance\n * @memberof Circle\n * @param {XYCoords} vert - The point to find the closest circle point for.\n * @return {Vertex} The closest point on this circle.\n **/\n Circle.prototype.closestPoint = function (vert) {\n var lineIntersection = this.lineIntersection(this.center, vert);\n if (!lineIntersection) {\n // Note: this case should not happen as a radial from the center always intersect this circle.\n return new Vertex_1.Vertex();\n }\n // Return closed of both\n if (lineIntersection.a.distance(vert) < lineIntersection.b.distance(vert)) {\n return lineIntersection.a;\n }\n else {\n return lineIntersection.b;\n }\n };\n /**\n * Get the two tangent vectors for the given point.\n * If the point is on or in the circle then null is returned.\n *\n * @method tangentsFromPoint\n * @instance\n * @memberof Circle\n * @param {Vertex} vert - The point to find the two tangents for.\n * @return {[Vector,Vector]} The two tangent vector\n **/\n Circle.prototype.tangentsFromPoint = function (vert) {\n // Inspired by\n // https://www.omnicalculator.com/math/tangent-circle\n var centerDistance = this.center.distance(vert);\n var tangentLength = Math.sqrt(centerDistance * centerDistance - this.radius * this.radius);\n // console.log(\"this.radius \", this.radius, \"centerDistance\", centerDistance, \"tangentLength\", tangentLength);\n if (Number.isNaN(tangentLength)) {\n // vertex is inside circle\n console.log(\"tangentLength is NaN\", tangentLength);\n return null;\n }\n var helperCircle = new Circle(vert, tangentLength);\n var intersection = this.circleIntersection(helperCircle);\n if (!intersection) {\n // No intersection (vertex is inside circle)\n return null;\n }\n return [new Vector_1.Vector(intersection.a, vert), new Vector_1.Vector(intersection.b, vert)];\n };\n /**\n * Create a deep copy of this circle.\n *\n * @method clone\n * @return {Circle} A new circle, an exact copy of this one.\n * @instance\n * @memberof Circle\n **/\n Circle.prototype.clone = function () {\n return new Circle(this.center.clone(), this.radius);\n };\n Circle.fromICircle = function (obj) {\n return new Circle(new Vertex_1.Vertex(obj.center), obj.radius);\n };\n // static fromObject(obj: object): Circle {\n // if (!obj) {\n // return null;\n // }\n // if (typeof obj !== \"object\") {\n // return null;\n // }\n // if (!obj.hasOwnProperty(\"center\") || typeof (obj as any).center != \"object\") {\n // return null;\n // }\n // if (!obj.hasOwnProperty(\"radius\") || typeof !(obj as any).radius != \"number\") {\n // return null;\n // }\n // var center = (obj as any).center;\n // if (!center.hasOwnProperty(\"x\") || typeof (center as any).x != \"number\") {\n // return null;\n // }\n // if (!center.hasOwnProperty(\"y\") || typeof (center as any).y != \"number\") {\n // return null;\n // }\n // return new Circle(new Vertex(center), (obj as any).radius);\n // }\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n Circle.prototype.destroy = function () {\n this.center.destroy();\n this.isDestroyed = true;\n };\n Circle.circleUtils = {\n vertAt: function (angle, radius) {\n /* return new Vertex( Math.sin(angle) * radius,\n Math.cos(angle) * radius ); */\n return new Vertex_1.Vertex(Math.cos(angle) * radius, Math.sin(angle) * radius);\n },\n containsPoint: function (circleCenter, circleRadius, point) {\n // TODO: cleanup\n // return (\n // (circle.center.x - point.x) * (circle.center.x - point.x) + (circle.center.y - point.y) * (circle.center.y - point.y) <=\n // circle.radius * circle.radius\n // );\n return geomutils_1.geomutils.dist4(point.x, point.y, circleCenter.x, circleCenter.y) < circleRadius;\n },\n createRadicalAxisHelperCircle: function (circleA, circleB) {\n // We need to create a helper circle that intersects BOTH other circles,\n // each in TWO points.\n var circleConnectLine = new Vector_1.Vector(circleA.center.clone(), circleB.center);\n circleConnectLine.a.set(circleConnectLine.vertAt(0.5));\n // Get the perpendicular by half the circle distance.\n var bisector = circleConnectLine.perp();\n var bisectorLength = Math.max(circleA.radius, circleB.radius, bisector.length());\n bisector.setLength(bisectorLength);\n return new Circle(bisector.b, bisector.b.distance(circleA.center));\n },\n /**\n * Calculate the outer distance between two circles. If the circles touch then the\n * distance is 0.0.\n * If the circles intersect then the distance in negative.\n */\n circleDistance: function (circleA, circleB) {\n return circleA.center.distance(circleB.center) - circleA.radius - circleB.radius;\n }\n };\n return Circle;\n}()); // END class\nexports.Circle = Circle;\n//# sourceMappingURL=Circle.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2020-12-17\n * @modified 2021-01-20 Added UID.\n * @modified 2021-02-26 Fixed an error in the svg-arc-calculation (case angle<90deg and anti-clockwise).\n * @modified 2024-01-30 Added a missing type in the `describeSVGArc` function.\n * @modified 2024-03-01 Added the `getStartPoint` and `getEndPoint` methods.\n * @modified 2024-03-08 Added the `containsAngle` method.\n * @modified 2024-03-09 Added the `circleSectorIntersection` method to find coherent sector intersections..\n * @modified 2024-03-09 Added the `angleAt` method to determine any angle at some ratio.\n * @modified 2025-04-02 Adding the `CircleSector.lineIntersections` and `CircleSector.lineIntersectionTangents` and implementing `Intersectable`.\n * @modified 2025-04-09 Adding the `CircleSector.move()` method.\n * @modified 2025-04-19 Tweaking the `CircleSector.containsAngle` method: all values (input angle, start- and end- angle) are wrapped into [0,2*PI) now.\n * @modified 2025-04-19 Class `CircleSector` implements interface `Bounded` now (method `getBounds` added).\n * @version 1.2.0\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.CircleSector = void 0;\nvar Bounds_1 = require(\"./Bounds\");\nvar Circle_1 = require(\"./Circle\");\nvar Line_1 = require(\"./Line\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar Vertex_1 = require(\"./Vertex\");\nvar geomutils_1 = require(\"./geomutils\");\n/**\n * @classdesc A simple circle sector: circle, start- and end-angle.\n *\n * @requires Line\n * @requires SVGSerializale\n * @requires UID\n * @requires UIDGenerator\n * @requires XYCoords\n **/\nvar CircleSector = /** @class */ (function () {\n /**\n * Create a new circle sector with given circle, start- and end-angle.\n *\n * @constructor\n * @name CircleSector\n * @param {Circle} circle - The circle.\n * @param {number} startAngle - The start angle of the sector.\n * @param {number} endAngle - The end angle of the sector.\n */\n function CircleSector(circle, startAngle, endAngle) {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"CircleSector\";\n this.uid = UIDGenerator_1.UIDGenerator.next();\n this.circle = circle;\n this.startAngle = startAngle;\n this.endAngle = endAngle;\n }\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Get the bounds of this ellipse.\n *\n * The bounds are approximated by the underlying segment buffer; the more segment there are,\n * the more accurate will be the returned bounds.\n *\n * @method getBounds\n * @instance\n * @memberof VEllipse\n * @return {Bounds} The bounds of this curve.\n **/\n CircleSector.prototype.getBounds = function () {\n var _self = this;\n var circleBounds = this.circle.getBounds();\n // Calculage angles from east, west, north and south box points and check if they are inside\n var candidates = [\n circleBounds.getNorthPoint(),\n circleBounds.getSouthPoint(),\n circleBounds.getWestPoint(),\n circleBounds.getEastPoint()\n ].filter(function (point) {\n // Check for each candidate points if they are contained in this sector. Drop if not.\n var angle = new Line_1.Line(_self.circle.center, point).angle();\n return _self.containsAngle(angle);\n });\n // Compute bounds and inlcude start end end point (they are definitely part of the bounds)\n return Bounds_1.Bounds.computeFromVertices(candidates.concat([this.getStartPoint(), this.getEndPoint()]));\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Move the circle sector by the given amount.\n *\n * @method move\n * @param {XYCoords} amount - The amount to move.\n * @instance\n * @memberof CircleSector\n * @return {CircleSector} this for chaining\n **/\n CircleSector.prototype.move = function (amount) {\n this.circle.move(amount);\n return this;\n };\n /**\n * Checks wether the given angle (must be inside 0 and PI*2) is contained inside this sector.\n *\n * @param {number} angle - The numeric angle to check.\n * @method containsAngle\n * @instance\n * @memberof CircleSector\n * @return {boolean} True if (and only if) this sector contains the given angle.\n */\n CircleSector.prototype.containsAngle = function (angle) {\n var wrappedAngle = geomutils_1.geomutils.mapAngleTo2PI(angle);\n var wrappedStart = geomutils_1.geomutils.mapAngleTo2PI(this.startAngle);\n var wrappedEnd = geomutils_1.geomutils.mapAngleTo2PI(this.endAngle);\n // TODO: cleanup\n // if (this.startAngle <= this.endAngle) {\n // return angle >= this.startAngle && angle < this.endAngle;\n // } else {\n // // startAngle > endAngle\n // return angle >= this.startAngle || angle < this.endAngle;\n // }\n if (wrappedStart <= wrappedEnd) {\n return wrappedAngle >= wrappedStart && wrappedAngle < wrappedEnd;\n }\n else {\n // startAngle > endAngle\n return wrappedAngle >= wrappedStart || wrappedAngle < wrappedEnd;\n }\n };\n /**\n * Get the angle inside this sector for a given ratio. 0.0 means startAngle, and 1.0 means endAngle.\n *\n * @param {number} t - The ratio inside [0..1].\n * @method angleAt\n * @instance\n * @memberof CircleSector\n * @return {number} The angle inside this sector at a given ratio.\n */\n CircleSector.prototype.angleAt = function (t) {\n if (this.startAngle <= this.endAngle) {\n var angleAtRatio = this.startAngle + (this.endAngle - this.startAngle) * t;\n return angleAtRatio % (Math.PI * 2.0);\n }\n else {\n // startAngle > endAngle\n var angleAtRatio = this.startAngle + (Math.PI * 2 - this.startAngle + this.endAngle) * t;\n return angleAtRatio % (Math.PI * 2.0);\n }\n };\n /**\n * Get the sectors starting point (on the underlying circle, located at the start angle).\n *\n * @method getStartPoint\n * @instance\n * @memberof CircleSector\n * @return {Vertex} The sector's stating point.\n */\n CircleSector.prototype.getStartPoint = function () {\n return this.circle.vertAt(this.startAngle);\n };\n /**\n * Get the sectors ending point (on the underlying circle, located at the end angle).\n *\n * @method getEndPoint\n * @instance\n * @memberof CircleSector\n * @return {Vertex} The sector's ending point.\n */\n CircleSector.prototype.getEndPoint = function () {\n return this.circle.vertAt(this.endAngle);\n };\n /**\n * Calculate the intersection of this circle sector and some other sector.\n *\n * If the two sectors do not corerently intersect (when not both points of the\n * radical line are containted in both source sectors) then null is returned.\n *\n * See demo/53-circle-sector-intersections for a geometric visualisation.\n *\n * @method circleSectorIntersection\n * @instance\n * @memberof CircleSector\n * @return {CircleSector | null} The intersecion of both sectors or null if they don't intersect.\n */\n CircleSector.prototype.circleSectorIntersection = function (sector) {\n var radicalLine = this.circle.circleIntersection(sector.circle);\n if (!radicalLine) {\n // The circles to not intersect at all.\n return null;\n }\n // Circles intersect. Check if this sector interval intersects, too.\n var thisIntersectionAngleA = this.circle.center.angle(radicalLine.a);\n var thisIntersectionAngleB = this.circle.center.angle(radicalLine.b);\n // Is intersection inside this sector?\n if (!this.containsAngle(thisIntersectionAngleA) || !this.containsAngle(thisIntersectionAngleB)) {\n // At least one circle intersection point is not located in this sector.\n // -> no valid intersection at all\n return null;\n }\n // Circles intersect. Check if the passed sector interval intersects, too.\n var thatIntersectionAngleA = sector.circle.center.angle(radicalLine.a);\n var thatIntersectionAngleB = sector.circle.center.angle(radicalLine.b);\n // Is intersection inside this sector?\n if (!sector.containsAngle(thatIntersectionAngleA) || !sector.containsAngle(thatIntersectionAngleB)) {\n // At least one circle intersection point is not located in this sector.\n // -> no valid intersection at all\n return null;\n }\n // The radical line has no direction. Thus the resulting sector _might_ be in reverse order.\n // Make a quick logical check: the center of the gap must still be located inside the result sector.\n // If not: reverse result.\n var gapSector = new CircleSector(this.circle, this.endAngle, this.startAngle);\n var centerOfOriginalGap = gapSector.angleAt(0.5);\n var resultSector = new CircleSector(new Circle_1.Circle(this.circle.center.clone(), this.circle.radius), thisIntersectionAngleA, thisIntersectionAngleB);\n if (resultSector.containsAngle(centerOfOriginalGap)) {\n resultSector.startAngle = thisIntersectionAngleB;\n resultSector.endAngle = thisIntersectionAngleA;\n }\n return resultSector;\n };\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get the line intersections as vectors with this ellipse.\n *\n * @method lineIntersections\n * @instance\n * @param {VertTuple<Vector> ray - The line/ray to intersect this ellipse with.\n * @param {boolean} inVectorBoundsOnly - (default=false) Set to true if only intersections within the vector bounds are of interest.\n * @returns\n */\n CircleSector.prototype.lineIntersections = function (ray, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // First get all line intersections from underlying ellipse.\n var ellipseIntersections = this.circle.lineIntersections(ray, inVectorBoundsOnly);\n // Drop all intersection points that are not contained in the circle sectors bounds.\n var tmpLine = new Line_1.Line(this.circle.center, new Vertex_1.Vertex());\n return ellipseIntersections.filter(function (intersectionPoint) {\n tmpLine.b.set(intersectionPoint);\n var lineAngle = tmpLine.angle();\n return _this.containsAngle(geomutils_1.geomutils.wrapMinMax(lineAngle, 0, Math.PI * 2));\n });\n };\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @param line\n * @param lineIntersectionTangents\n * @returns\n */\n CircleSector.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersections of all lines plus their tangents inside the circle bounds\n var interSectionPoints = this.lineIntersections(line, inVectorBoundsOnly);\n return interSectionPoints.map(function (vert) {\n // Calculate angle\n var lineFromCenter = new Line_1.Line(_this.circle.center, vert);\n var angle = lineFromCenter.angle();\n // console.log(\"angle\", (angle / Math.PI) * 180.0);\n // const angle = Math.random() * Math.PI * 2; // TODO\n // Calculate tangent at angle\n return _this.circle.tangentAt(angle);\n });\n };\n //--- END --- Implement interface `Intersectable`\n CircleSector.prototype.describeSVGPath = function (options) {\n // const buffer: SVGPathParams = [];\n // const start = this.getStartPoint();\n // const end = this.getEndPoint();\n // // describeSVGArc\n // // x: number,\n // // y: number,\n // // radius: number,\n // // startAngle: number,\n // // endAngle: number,\n // // options?: { moveToStart: boolean }\n // // ): SVGPathParams => {\n // var arcRotation = 0.0;\n // var largeArcFlag = 1;\n // var sweepFlag = 0;\n // if (options && options.moveToStart) {\n // buffer.push(\"M\", start.x, start.y);\n // }\n // buffer.push(\"A\", cSector.circle.radius, cSector.circle.radius, arcRotation, largeArcFlag, sweepFlag, end.x, end.y);\n // return buffer;\n var arc = CircleSector.circleSectorUtils.describeSVGArc(this.circle.center.x, // end.x,\n this.circle.center.y, // end.y,\n this.circle.radius, this.startAngle, this.endAngle, options // options?: { moveToStart: boolean }\n );\n return arc;\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n *\n * @method destroy\n * @instance\n * @memberof CircleSector\n * @return {void}\n */\n CircleSector.prototype.destroy = function () {\n this.circle.destroy();\n this.isDestroyed = true;\n };\n CircleSector.circleSectorUtils = {\n /**\n * Helper function to convert polar circle coordinates to cartesian coordinates.\n *\n * TODO: generalize for ellipses (two radii).\n *\n * @param {number} angle - The angle in radians.\n */\n polarToCartesian: function (centerX, centerY, radius, angle) {\n return {\n x: centerX + radius * Math.cos(angle),\n y: centerY + radius * Math.sin(angle)\n };\n },\n /**\n * Helper function to convert a circle section as SVG arc params (for the `d` attribute).\n * Found at: https://stackoverflow.com/questions/5736398/how-to-calculate-the-svg-path-for-an-arc-of-a-circle\n *\n * TODO: generalize for ellipses (two radii).\n *\n * @param {boolean} options.moveToStart - If false (default=true) the initial 'Move' command will not be used.\n * @return [ 'A', radiusx, radiusy, rotation=0, largeArcFlag=1|0, sweepFlag=0, endx, endy ]\n */\n describeSVGArc: function (x, y, radius, startAngle, endAngle, options) {\n if (typeof options === \"undefined\") {\n options = { moveToStart: true };\n }\n var end = CircleSector.circleSectorUtils.polarToCartesian(x, y, radius, endAngle);\n var start = CircleSector.circleSectorUtils.polarToCartesian(x, y, radius, startAngle);\n // Split full circles into two halves.\n // Some browsers have problems to render full circles (described by start==end).\n if (Math.PI * 2 - Math.abs(startAngle - endAngle) < 0.001) {\n var firstHalf = CircleSector.circleSectorUtils.describeSVGArc(x, y, radius, startAngle, startAngle + (endAngle - startAngle) / 2, options);\n var secondHalf = CircleSector.circleSectorUtils.describeSVGArc(x, y, radius, startAngle + (endAngle - startAngle) / 2, endAngle, options);\n return firstHalf.concat(secondHalf);\n }\n // Boolean stored as integers (0|1).\n var diff = endAngle - startAngle;\n var largeArcFlag;\n var sweepFlag;\n if (diff < 0) {\n largeArcFlag = Math.abs(diff) < Math.PI ? 1 : 0;\n sweepFlag = 1;\n }\n else {\n largeArcFlag = Math.abs(diff) > Math.PI ? 1 : 0;\n sweepFlag = 1;\n }\n var pathData = [];\n if (options.moveToStart) {\n pathData.push(\"M\", start.x, start.y);\n }\n pathData.push(\"A\", radius, radius, 0, largeArcFlag, sweepFlag, end.x, end.y);\n return pathData;\n }\n };\n return CircleSector;\n}()); // END class\nexports.CircleSector = CircleSector;\n//# sourceMappingURL=CircleSector.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2019-09-18\n * @modified 2019-10-03 Added the beginDrawCycle hook.\n * @modified 2020-03-25 Ported stub to Typescript.\n * @modified 2020-10-15 Re-added the text() function.\n * @modified 2021-01-24 Added the `setCurrentId` function.\n * @modified 2021-05-31 Added the `setConfiguration` function from `DrawLib`.\n * @modified 2022-02-03 Added the `lineWidth` param to the `crosshair` function.\n * @modified 2022-02-03 Added the `cross(...)` function.\n * @modified 2022-03-27 Added the `texturedPoly` function.\n * @modified 2022-07-26 Adding `alpha` to the `image(...)` function.\n * @modified 2023-02-10 The methods `setCurrentClassName` and `setCurrentId` also accept `null` now.\n * @modified 2023-09-29 Downgrading all `Vertex` param type to the more generic `XYCoords` type in these render functions: line, arrow, texturedPoly, cubicBezier, cubicBezierPath, handle, handleLine, dot, point, circle, circleArc, ellipse, grid, raster.\n * @modified 2023-09-29 Added the `headLength` parameter to the 'DrawLib.arrow()` function.\n * @modified 2023-09-29 Added the `arrowHead(...)` function to the 'DrawLib.arrow()` interface.\n * @modified 2023-09-29 Added the `cubicBezierArrow(...)` function to the 'DrawLib.arrow()` interface.\n * @modified 2023-09-29 Added the `lineDashes` attribute.\n * @modified 2026-03-18 Adding `isOpen` parameter to `cubicBezierPath` draw method.\n * @modified 2026-04-04 Added the method `bounds`.\n * @version 0.0.11\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.drawutilsgl = void 0;\nvar Vertex_1 = require(\"./Vertex\");\n/**\n * @classdesc A wrapper class for basic drawing operations. This is the WebGL\n * implementation whih sould work with shaders.\n *\n * @requires CubicBzierCurvce\n * @requires Polygon\n * @requires SVGSerializable\n * @requires Vertex\n * @requires XYCoords\n */\nvar drawutilsgl = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name drawutils\n * @param {WebGLRenderingContext|null} context - The drawing context.\n * @param {boolean} fillShaped - Indicates if the constructed drawutils should fill all drawn shapes (if possible).\n **/\n function drawutilsgl(context, fillShapes) {\n this.gl = context;\n this.offset = new Vertex_1.Vertex(0, 0);\n this.scale = new Vertex_1.Vertex(1, 1);\n this.fillShapes = fillShapes;\n this._zindex = 0.0;\n if (context == null || typeof context === \"undefined\")\n return;\n this.glutils = new GLU(context);\n // PROBLEM: CANNOT USE MULTIPLE SHADER PROGRAM INSTANCES ON THE SAME CONTEXT!\n // SOLUTION: USE SHARED SHADER PROGRAM!!! ... somehow ...\n // This needs to be considered in the overlying component; both draw-instances need to\n // share their gl context.\n // That's what the copyInstace(boolean) method is good for.\n this._vertShader = this.glutils.compileShader(drawutilsgl.vertCode, this.gl.VERTEX_SHADER);\n this._fragShader = this.glutils.compileShader(drawutilsgl.fragCode, this.gl.FRAGMENT_SHADER);\n this._program = this.glutils.makeProgram(this._vertShader, this._fragShader);\n // Create an empty buffer object\n this.vertex_buffer = this.gl.createBuffer();\n // Bind appropriate array buffer to it\n // this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertex_buffer);\n console.log(\"gl initialized\");\n }\n drawutilsgl.prototype._x2rel = function (x) {\n return ((this.scale.x * x + this.offset.x) / this.gl.canvas.width) * 2.0 - 1.0;\n };\n drawutilsgl.prototype._y2rel = function (y) {\n return ((this.offset.y - this.scale.y * y) / this.gl.canvas.height) * 2.0 - 1.0;\n };\n /**\n * Creates a 'shallow' (non deep) copy of this instance. This implies\n * that under the hood the same gl context and gl program will be used.\n */\n drawutilsgl.prototype.copyInstance = function (fillShapes) {\n var copy = new drawutilsgl(null, fillShapes);\n copy.gl = this.gl;\n copy.glutils = this.glutils;\n copy._vertShader = this._vertShader;\n copy._fragShader = this._fragShader;\n copy._program = this._program;\n return copy;\n };\n /**\n * Called before each draw cycle.\n * @param {number} renderTime\n **/\n drawutilsgl.prototype.beginDrawCycle = function (renderTime) {\n this._zindex = 0.0;\n this.renderTime = renderTime;\n };\n /**\n * Called after each draw cycle.\n *\n * This is required for compatibility with other draw classes in the library (like drawgl).\n *\n * @name endDrawCycle\n * @method\n * @param {number} renderTime\n * @instance\n **/\n drawutilsgl.prototype.endDrawCycle = function (renderTime) {\n // NOOP\n };\n /**\n * Set the current drawlib configuration.\n *\n * @name setConfiguration\n * @method\n * @param {DrawLibConfiguration} configuration - The new configuration settings to use for the next render methods.\n */\n drawutilsgl.prototype.setConfiguration = function (configuration) {\n // TODO\n };\n // /**\n // * Set or clear the line-dash configuration. Pass `null` for un-dashed lines.\n // *\n // * See https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray\n // * and https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash\n // * for how line dashes work.\n // *\n // * @method\n // * @param {Array<number> lineDashes - The line-dash array configuration.\n // * @returns {void}\n // */\n // setLineDash(lineDashes: Array<number>) {\n // // TODO\n // }\n /**\n * This method shouled be called each time the currently drawn `Drawable` changes.\n * It is used by some libraries for identifying elemente on re-renders.\n *\n * @name setCurrentId\n * @method\n * @param {UID|null} uid - A UID identifying the currently drawn element(s).es.\n **/\n drawutilsgl.prototype.setCurrentId = function (uid) {\n // NOOP\n this.curId = uid;\n };\n /**\n * This method shouled be called each time the currently drawn `Drawable` changes.\n * Determine the class name for further usage here.\n *\n * @name setCurrentClassName\n * @method\n * @param {string|null} className - A class name for further custom use cases.\n **/\n drawutilsgl.prototype.setCurrentClassName = function (className) {\n // NOOP\n };\n /**\n * Draw the line between the given two points with the specified (CSS-) color.\n *\n * @method line\n * @param {XYCoords} zA - The start point of the line.\n * @param {XYCoords} zB - The end point of the line.\n * @param {string} color - Any valid CSS color string.\n * @return {void}\n * @instance\n * @memberof drawutils\n **/\n drawutilsgl.prototype.line = function (zA, zB, color) {\n var vertices = new Float32Array(6);\n vertices[0] = this._x2rel(zA.x);\n vertices[1] = this._y2rel(zA.y);\n vertices[2] = this._zindex;\n vertices[3] = this._x2rel(zB.x);\n vertices[4] = this._y2rel(zB.y);\n vertices[5] = this._zindex;\n this._zindex += 0.001;\n // Create an empty buffer object\n // const vertex_buffer = this.gl.createBuffer();\n // Bind appropriate array buffer to it\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertex_buffer);\n // Pass the vertex data to the buffer\n this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW);\n // Bind vertex buffer object\n // this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertex_buffer);\n // Get the attribute location\n var coord = this.gl.getAttribLocation(this._program, \"position\");\n // Point an attribute to the currently bound VBO\n this.gl.vertexAttribPointer(coord, 3, this.gl.FLOAT, false, 0, 0);\n // Enable the attribute\n this.gl.enableVertexAttribArray(coord);\n // Unbind the buffer?\n //this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);\n // Set the view port\n this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height);\n var uRotationVector = this.gl.getUniformLocation(this._program, \"uRotationVector\");\n // let radians = currentAngle * Math.PI / 180.0;\n var currentRotation = [0.0, 1.0];\n //currentRotation[0] = Math.sin(radians);\n //currentRotation[1] = Math.cos(radians);\n this.gl.uniform2fv(uRotationVector, currentRotation);\n this.gl.lineWidth(5);\n // Draw the line\n this.gl.drawArrays(this.gl.LINES, 0, vertices.length / 3);\n // POINTS, LINE_STRIP, LINE_LOOP, LINES,\n // TRIANGLE_STRIP,TRIANGLE_FAN, TRIANGLES\n };\n /**\n * Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.\n *\n * @method arrow\n * @param {XYCoords} zA - The start point of the arrow-line.\n * @param {XYCoords} zB - The end point of the arrow-line.\n * @param {string} color - Any valid CSS color string.\n * @param {headLength=8} headLength - (optional) The length of the arrow head (default is 8 units).\n * @return {void}\n * @instance\n * @memberof drawutils\n **/\n drawutilsgl.prototype.arrow = function (zA, zB, color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a cubic Bézier curve and and an arrow at the end (endControlPoint) of the given line width the specified (CSS-) color and arrow size.\n *\n * @method cubicBezierArrow\n * @param {XYCoords} startPoint - The start point of the cubic Bézier curve\n * @param {XYCoords} endPoint - The end point the cubic Bézier curve.\n * @param {XYCoords} startControlPoint - The start control point the cubic Bézier curve.\n * @param {XYCoords} endControlPoint - The end control point the cubic Bézier curve.\n * @param {string} color - The CSS color to draw the curve with.\n * @param {number} lineWidth - (optional) The line width to use.\n * @param {headLength=8} headLength - (optional) The length of the arrow head (default is 8 units).\n *\n * @return {void}\n * @instance\n * @memberof DrawLib\n */\n drawutilsgl.prototype.cubicBezierArrow = function (startPoint, endPoint, startControlPoint, endControlPoint, color, lineWidth, headLength) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw just an arrow head a the end of an imaginary line (zB) of the given line width the specified (CSS-) color and size.\n *\n * @method arrow\n * @param {XYCoords} zA - The start point of the arrow-line.\n * @param {XYCoords} zB - The end point of the arrow-line.\n * @param {string} color - Any valid CSS color string.\n * @param {number=1} lineWidth - (optional) The line width to use; default is 1.\n * @param {number=8} headLength - (optional) The length of the arrow head (default is 8 pixels).\n * @return {void}\n * @instance\n * @memberof DrawLib\n **/\n drawutilsgl.prototype.arrowHead = function (zA, zB, color, lineWidth, headLength) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw an image at the given position with the given size.<br>\n * <br>\n * Note: SVG images may have resizing issues at the moment.Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.\n *\n * @method image\n * @param {Image} image - The image object to draw.\n * @param {XYCoords} position - The position to draw the the upper left corner at.\n * @param {XYCoords} size - The x/y-size to draw the image with.\n * @param {number=0.0} alpha - (optional, default=0.0) The transparency (0.0=opaque, 1.0=transparent).\n * @return {void}\n * @instance\n * @memberof drawutils\n **/\n drawutilsgl.prototype.image = function (image, position, size, alpha) {\n if (alpha === void 0) { alpha = 0.0; }\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw an image at the given position with the given size.<br>\n * <br>\n * Note: SVG images may have resizing issues at the moment.Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.\n *\n * @method texturedPoly\n * @param {Image} textureImage - The image object to draw.\n * @param {Bounds} textureSize - The texture size to use; these are the original bounds to map the polygon vertices to.\n * @param {Polygon} polygon - The polygon to use as clip path.\n * @param {XYCoords} polygonPosition - The polygon's position (relative), measured at the bounding box's center.\n * @param {number} rotation - The rotation to use for the polygon (and for the texture).\n * @return {void}\n * @instance\n * @memberof drawutilsgl\n **/\n drawutilsgl.prototype.texturedPoly = function (textureImage, textureSize, polygon, polygonPosition, rotation) {\n // NOT YET IMPLEMENTED\n };\n // +---------------------------------------------------------------------------------\n // | This is the final helper function for drawing and filling stuff. It is not\n // | intended to be used from the outside.\n // |\n // | When in draw mode it draws the current shape.\n // | When in fill mode it fills the current shape.\n // |\n // | This function is usually only called internally.\n // |\n // | @param color A stroke/fill color to use.\n // +-------------------------------\n drawutilsgl.prototype._fillOrDraw = function (color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw the given (cubic) bézier curve.\n *\n * @method cubicBezier\n * @param {XYCoords} startPoint - The start point of the cubic Bézier curve\n * @param {XYCoords} endPoint - The end point the cubic Bézier curve.\n * @param {XYCoords} startControlPoint - The start control point the cubic Bézier curve.\n * @param {VertXYCoordsex} endControlPoint - The end control point the cubic Bézier curve.\n * @param {string} color - The CSS color to draw the curve with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.cubicBezier = function (startPoint, endPoint, startControlPoint, endControlPoint, color, lineWidth) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw the given (cubic) Bézier path.\n *\n * The given path must be an array with n*3+1 vertices, where n is the number of\n * curves in the path:\n * <pre> [ point1, point1_startControl, point2_endControl, point2, point2_startControl, point3_endControl, point3, ... pointN_endControl, pointN ]</pre>\n *\n * @method cubicBezierPath\n * @param {XYCoords[]} path - The cubic bezier path as described above.\n * @param {string} color - The CSS colot to draw the path with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.cubicBezierPath = function (path, color, lineWidth, strokeOptions, isOpen) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw the given handle and handle point (used to draw interactive Bézier curves).\n *\n * The colors for this are fixed and cannot be specified.\n *\n * @method handle\n * @param {XYCoords} startPoint - The start of the handle.\n * @param {XYCoords} endPoint - The end point of the handle.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.handle = function (startPoint, endPoint) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a handle line (with a light grey).\n *\n * @method handleLine\n * @param {XYCoords} startPoint - The start point to draw the handle at.\n * @param {XYCoords} endPoint - The end point to draw the handle at.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.handleLine = function (startPoint, endPoint) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a 1x1 dot with the specified (CSS-) color.\n *\n * @method dot\n * @param {XYCoords} p - The position to draw the dot at.\n * @param {string} color - The CSS color to draw the dot with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.dot = function (p, color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw the given point with the specified (CSS-) color and radius 3.\n *\n * @method point\n * @param {XYCoords} p - The position to draw the point at.\n * @param {string} color - The CSS color to draw the point with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.point = function (p, color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a circle with the specified (CSS-) color and radius.<br>\n * <br>\n * Note that if the x- and y- scales are different the result will be an ellipse rather than a circle.\n *\n * @method circle\n * @param {XYCoords} center - The center of the circle.\n * @param {number} radius - The radius of the circle.\n * @param {string} color - The CSS color to draw the circle with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.circle = function (center, radius, color, lineWidth) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a circular arc (section of a circle) with the given CSS color.\n *\n * @method circleArc\n * @param {XYCoords} center - The center of the circle.\n * @param {number} radius - The radius of the circle.\n * @param {number} startAngle - The angle to start at.\n * @param {number} endAngle - The angle to end at.\n * @param {string} color - The CSS color to draw the circle with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.circleArc = function (center, radius, startAngle, endAngle, color, lineWidth) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw an ellipse with the specified (CSS-) color and thw two radii.\n *\n * @method ellipse\n * @param {XYCoords} center - The center of the ellipse.\n * @param {number} radiusX - The radius of the ellipse.\n * @param {number} radiusY - The radius of the ellipse.\n * @param {string} color - The CSS color to draw the ellipse with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {number=} rotation - (optional, default=0) The rotation of the ellipse.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.ellipse = function (center, radiusX, radiusY, color, lineWidth, rotation) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw square at the given center, size and with the specified (CSS-) color.<br>\n * <br>\n * Note that if the x-scale and the y-scale are different the result will be a rectangle rather than a square.\n *\n * @method square\n * @param {XYCords} center - The center of the square.\n * @param {number} size - The size of the square.\n * @param {string} color - The CSS color to draw the square with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.square = function (center, size, color, lineWidth) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a rectangle.\n *\n * @param {XYCoords} position - The upper left corner of the rectangle.\n * @param {number} width - The width of the rectangle.\n * @param {number} height - The height of the rectangle.\n * @param {string} color - The color to use.\n * @param {number=1} lineWidth - (optional) The line with to use (default is 1).\n **/\n drawutilsgl.prototype.rect = function (position, width, height, color, lineWidth, strokeOptions) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a rectangle at the given bounds; and with the specified line width and (CSS-) color.<br>\n *\n * @method bounds\n * @param {IBounds} bounds - The bounds rectangle to be drawn.\n * @param {string} color - The CSS color to draw the rectangle with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {R}\n * @instance\n * @memberof DrawLib\n */\n drawutilsgl.prototype.bounds = function (bounds, color, lineWidth, strokeOptions) {\n this.rect(bounds.min, bounds.max.x - bounds.min.x, bounds.max.y - bounds.min.y, color, lineWidth, strokeOptions);\n };\n /**\n * Draw a grid of horizontal and vertical lines with the given (CSS-) color.\n *\n * @method grid\n * @param {XYCoords} center - The center of the grid.\n * @param {number} width - The total width of the grid (width/2 each to the left and to the right).\n * @param {number} height - The total height of the grid (height/2 each to the top and to the bottom).\n * @param {number} sizeX - The horizontal grid size.\n * @param {number} sizeY - The vertical grid size.\n * @param {string} color - The CSS color to draw the grid with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.grid = function (center, width, height, sizeX, sizeY, color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a raster of crosshairs in the given grid.<br>\n *\n * This works analogue to the grid() function\n *\n * @method raster\n * @param {XYCoords} center - The center of the raster.\n * @param {number} width - The total width of the raster (width/2 each to the left and to the right).\n * @param {number} height - The total height of the raster (height/2 each to the top and to the bottom).\n * @param {number} sizeX - The horizontal raster size.\n * @param {number} sizeY - The vertical raster size.\n * @param {string} color - The CSS color to draw the raster with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.raster = function (center, width, height, sizeX, sizeY, color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a diamond handle (square rotated by 45°) with the given CSS color.\n *\n * It is an inherent featur of the handle functions that the drawn elements are not scaled and not\n * distorted. So even if the user zooms in or changes the aspect ratio, the handles will be drawn\n * as even shaped diamonds.\n *\n * @method diamondHandle\n * @param {XYCoords} center - The center of the diamond.\n * @param {number} size - The x/y-size of the diamond.\n * @param {string} color - The CSS color to draw the diamond with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.diamondHandle = function (center, size, color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a square handle with the given CSS color.<br>\n * <br>\n * It is an inherent featur of the handle functions that the drawn elements are not scaled and not\n * distorted. So even if the user zooms in or changes the aspect ratio, the handles will be drawn\n * as even shaped squares.\n *\n * @method squareHandle\n * @param {XYCoords} center - The center of the square.\n * @param {number} size - The x/y-size of the square.\n * @param {string} color - The CSS color to draw the square with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.squareHandle = function (center, size, color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a circle handle with the given CSS color.<br>\n * <br>\n * It is an inherent featur of the handle functions that the drawn elements are not scaled and not\n * distorted. So even if the user zooms in or changes the aspect ratio, the handles will be drawn\n * as even shaped circles.\n *\n * @method circleHandle\n * @param {XYCoords} center - The center of the circle.\n * @param {number} radius - The radius of the circle.\n * @param {string} color - The CSS color to draw the circle with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.circleHandle = function (center, size, color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a crosshair with given radius and color at the given position.<br>\n * <br>\n * Note that the crosshair radius will not be affected by scaling.\n *\n * @method crosshair\n * @param {XYCoords} center - The center of the crosshair.\n * @param {number} radius - The radius of the crosshair.\n * @param {string} color - The CSS color to draw the crosshair with.\n * @param {number=0.5} lineWidth - (optional, default=0.5) The line width to use.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.crosshair = function (center, radius, color, lineWidth) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a cross with diagonal axes with given radius, color and lineWidth at the given position.<br>\n * <br>\n * Note that the x's radius will not be affected by scaling.\n *\n * @method crosshair\n * @param {XYCoords} center - The center of the crosshair.\n * @param {number} radius - The radius of the crosshair.\n * @param {string} color - The CSS color to draw the crosshair with.\n * @param {number=1} lineWidth - (optional, default=1.0) The line width to use.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.cross = function (center, radius, color, lineWidth) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a polygon.\n *\n * @method polygon\n * @param {Polygon} polygon - The polygon to draw.\n * @param {string} color - The CSS color to draw the polygon with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.polygon = function (polygon, color, lineWidth) {\n var vertices = new Float32Array(polygon.vertices.length * 3);\n for (var i = 0; i < polygon.vertices.length; i++) {\n vertices[i * 3 + 0] = this._x2rel(polygon.vertices[i].x);\n vertices[i * 3 + 1] = this._y2rel(polygon.vertices[i].y);\n vertices[i * 3 + 2] = this._zindex;\n }\n this._zindex += 0.001;\n //console.log( vertices );\n // Create an empty buffer object\n // const vertex_buffer = this.gl.createBuffer();\n // Bind appropriate array buffer to it\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertex_buffer);\n // Pass the vertex data to the buffer\n this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW);\n // Bind vertex buffer object\n // this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertex_buffer);\n // Get the attribute location\n var coord = this.gl.getAttribLocation(this._program, \"position\");\n // Point an attribute to the currently bound VBO\n this.gl.vertexAttribPointer(coord, 3, this.gl.FLOAT, false, 0, 0);\n // Enable the attribute\n this.gl.enableVertexAttribArray(coord);\n // Unbind the buffer?\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);\n // Set the view port\n this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height);\n var uRotationVector = this.gl.getUniformLocation(this._program, \"uRotationVector\");\n // let radians = currentAngle * Math.PI / 180.0;\n var currentRotation = [0.0, 1.0];\n //currentRotation[0] = Math.sin(radians);\n //currentRotation[1] = Math.cos(radians);\n this.gl.uniform2fv(uRotationVector, currentRotation);\n // Draw the polygon\n this.gl.drawArrays(this.gl.TRIANGLE_FAN, 0, vertices.length / 3);\n // POINTS, LINE_STRIP, LINE_LOOP, LINES,\n // TRIANGLE_STRIP,TRIANGLE_FAN, TRIANGLES\n };\n /**\n * Draw a polygon line (alternative function to the polygon).\n *\n * @method polyline\n * @param {XYCoords[]} vertices - The polygon vertices to draw.\n * @param {boolan} isOpen - If true the polyline will not be closed at its end.\n * @param {string} color - The CSS color to draw the polygon with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.polyline = function (vertices, isOpen, color, lineWidth) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a text at the given relative position.\n *\n * @method text\n * @param {string} text - The text to draw.\n * @param {number} x - The x-position to draw the text at.\n * @param {number} y - The y-position to draw the text at.\n * @param {string=} options.color - The Color to use.\n * @param {string=} options.fontFamily - The font family to use.\n * @param {number=} options.fontSize - The font size (in pixels) to use.\n * @param {FontStyle=} options.fontStyle - The font style to use.\n * @param {FontWeight=} options.fontWeight - The font weight to use.\n * @param {number=} options.lineHeight - The line height (in pixels) to use.\n * @param {number=} options.rotation - The (optional) rotation in radians.\n * @param {string=} options.textAlign - The text align to use. According to the specifiactions (https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign) valid values are `\"left\" || \"right\" || \"center\" || \"start\" || \"end\"`.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.text = function (text, x, y, options) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a non-scaling text label at the given position.\n *\n * @method label\n * @param {string} text - The text to draw.\n * @param {number} x - The x-position to draw the text at.\n * @param {number} y - The y-position to draw the text at.\n * @param {number=} rotation - The (aoptional) rotation in radians.\n * @param {string=\"black\"} color - The color to use (default is black).\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.label = function (text, x, y, rotation, color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw an SVG-like path given by the specified path data.\n *\n * @method path\n * @param {SVGPathData} pathData - An array of path commands and params.\n * @param {string=null} color - (optional) The color to draw this path with (default is null).\n * @param {number=1} lineWidth - (optional) the line width to use (default is 1).\n * @param {boolean=false} options.inplace - (optional) If set to true then path transforamtions (scale and translate) will be done in-place in the array. This can boost the performance.\n * @instance\n * @memberof drawutils\n * @return {R} An instance representing the drawn path.\n */\n drawutilsgl.prototype.path = function (pathData, color, lineWidth, options) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Due to gl compatibility there is a generic 'clear' function required\n * to avoid accessing the context object itself directly.\n *\n * This function just fills the whole canvas with a single color.\n *\n * @param {string} color - The color to clear with.\n **/\n drawutilsgl.prototype.clear = function (color) {\n // NOT YET IMPLEMENTED\n // if( typeof color == 'string' )\n // color = Color.parse(color); // Color class does not yet exist in TS\n // Clear the canvas\n this.gl.clearColor(1.0, 1.0, 1.0, 1.0);\n // Enable the depth test\n this.gl.enable(this.gl.DEPTH_TEST);\n // Clear the color and depth buffer\n this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);\n };\n // Vertex shader source code\n drawutilsgl.vertCode = \"\\n precision mediump float;\\n\\n attribute vec3 position;\\n\\n uniform vec2 uRotationVector;\\n\\n void main(void) {\\n\\tvec2 rotatedPosition = vec2(\\n\\t position.x * uRotationVector.y +\\n\\t\\tposition.y * uRotationVector.x,\\n\\t position.y * uRotationVector.y -\\n\\t\\tposition.x * uRotationVector.x\\n\\t);\\n\\n\\tgl_Position = vec4(rotatedPosition, position.z, 1.0);\\n }\";\n // Fragment shader source code\n drawutilsgl.fragCode = \"\\n precision highp float;\\n\\n void main(void) {\\n\\tgl_FragColor = vec4(0.0,0.75,1.0,1.0);\\n }\";\n return drawutilsgl;\n}());\nexports.drawutilsgl = drawutilsgl;\n/**\n * Some GL helper utils.\n **/\nvar GLU = /** @class */ (function () {\n function GLU(gl) {\n this.gl = gl;\n }\n GLU.prototype.bufferData = function (verts) {\n // Create an empty buffer object\n var vbuffer = this.gl.createBuffer();\n // Bind appropriate array buffer to it\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vbuffer);\n // Pass the vertex data to the buffer\n this.gl.bufferData(this.gl.ARRAY_BUFFER, verts, this.gl.STATIC_DRAW);\n // Unbind the buffer\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);\n return vbuffer;\n };\n /*=================== Shaders ====================*/\n GLU.prototype.compileShader = function (shaderCode, shaderType) {\n // Create a vertex shader object\n var shader = this.gl.createShader(shaderType);\n // Attach vertex shader source code\n this.gl.shaderSource(shader, shaderCode);\n // Compile the vertex shader\n this.gl.compileShader(shader);\n var vertStatus = this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS);\n if (!vertStatus) {\n console.warn(\"Error in shader:\" + this.gl.getShaderInfoLog(shader));\n this.gl.deleteShader(shader);\n return null;\n }\n return shader;\n };\n GLU.prototype.makeProgram = function (vertShader, fragShader) {\n // Create a shader program object to store\n // the combined shader program\n var program = this.gl.createProgram();\n // Attach a vertex shader\n this.gl.attachShader(program, vertShader);\n // Attach a fragment shader\n this.gl.attachShader(program, fragShader);\n // Link both the programs\n this.gl.linkProgram(program);\n // Use the combined shader program object\n this.gl.useProgram(program);\n /*======= Do some cleanup ======*/\n this.gl.detachShader(program, vertShader);\n this.gl.detachShader(program, fragShader);\n this.gl.deleteShader(vertShader);\n this.gl.deleteShader(fragShader);\n return program;\n };\n return GLU;\n}());\n//# sourceMappingURL=drawgl.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2018-11-28\n * @modified 2018-12-09 Added the utils: baseLog(Number,Number) and mapRasterScale(Number,Number).\n * @version 1.0.1\n *\n * @file Grid\n * @fileoverview Note that the PlotBoilerplate already has a Grid instance member. The Grid is not meant\n * to be added to the canvas as a drawable as it encapsulates more an abstract concept of the canvas\n * rather than a drawable object.\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Grid = void 0;\n/**\n * @classdesc A grid class with vertical and horizontal lines (or a raster).\n *\n * Note that the PlotBoilerplate already has a Grid instance member. The Grid is not meant\n * to be added to the canvas as a drawable as it encapsulates more an abstract concept of the canvas\n * rather than a drawable object.\n *\n * @requires Vertex\n */\nvar Grid = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name Grid\n * @param {Vertex} center - The offset of the grid (default is [0,0]).\n * @param {Vertex} size - The x- and y-size of the grid.\n **/\n function Grid(center, size) {\n this.center = center;\n this.size = size;\n }\n ;\n /**\n * @memberof Grid\n **/\n Grid.utils = {\n /**\n * Calculate the logarithm of the given number (num) to a given base.<br>\n * <br>\n * This function returns the number l with<br>\n * <pre>num == Math.pow(base,l)</pre>\n *\n * @member baseLog\n * @function\n * @memberof Grid\n * @inner\n * @param {number} base - The base to calculate the logarithm to.\n * @param {number} num - The number to calculate the logarithm for.\n * @return {number} <pre>log(base)/log(num)</pre>\n **/\n baseLog: function (base, num) { return Math.log(base) / Math.log(num); },\n /**\n * Calculate the raster scale for a given logarithmic mapping.<br>\n * <br>\n * Example (with adjustFactor=2):<br>\n * <pre>\n * If scale is 4.33, then the mapping is 1/2 (because 2^2 <= 4.33 <= 2^3)<br>\n * If scale is 0.33, then the mapping is 2 because (2^(1/2) >= 0.33 >= 2^(1/4)\n * </pre>\n *\n * @member mapRasterScale\n * @function\n * @memberof Grid\n * @inner\n * @param {number} adjustFactor The base for the logarithmic raster scaling when zoomed.\n * @param {number} scale The currently used scale factor.\n * @return {number}\n **/\n mapRasterScale: function (adjustFactor, scale) {\n var gf = 1.0;\n if (scale >= 1) {\n gf = Math.abs(Math.floor(1 / Grid.utils.baseLog(adjustFactor, scale)));\n gf = 1 / Math.pow(adjustFactor, gf);\n }\n else {\n gf = Math.abs(Math.floor(Grid.utils.baseLog(1 / adjustFactor, 1 / (scale + 1))));\n }\n return gf;\n }\n };\n return Grid;\n}());\nexports.Grid = Grid;\n//# sourceMappingURL=Grid.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2019-02-03\n * @modified 2021-03-01 Added `wrapMax` function.\n * @modified 2024-11-15 Adding helper function `geomutils.mapAngleTo2PI(number)` for mapping any value into the interval [0,2*PI).\n * @modified 2024-11-22 Adding helper function `geomutils.dotProduct(number)` for calculating the dot product of two vertices (as vectors).\n *\n * @version 1.2.0\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.geomutils = void 0;\nvar Line_1 = require(\"./Line\");\nvar Triangle_1 = require(\"./Triangle\");\n/**\n * A collection of usefull geometry utilities.\n *\n * @global\n **/\nexports.geomutils = {\n /**\n * Map any angle (any numeric value) to [0, Math.PI).\n *\n * @param {number} angle - The numeric value to map.\n * @return {number} The mapped angle inside [0,PI*2].\n **/\n mapAngleTo2PI: function (angle) {\n // Source: https://forums.codeguru.com/showthread.php?384172-get-angle-into-range-0-2*pi\n var new_angle = Math.asin(Math.sin(angle));\n if (Math.cos(angle) < 0) {\n return Math.PI - new_angle;\n }\n else if (new_angle < 0) {\n return new_angle + 2 * Math.PI;\n }\n else {\n return new_angle;\n }\n },\n /**\n * Calculate the euclidean distance between two points given by four coordinates (two coordinates each).\n *\n * @param {number} x1\n * @param {number} y1\n * @param {number} x2\n * @param {number} y2\n * @returns {number}\n */\n dist4: function (x1, y1, x2, y2) {\n return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y1 - y2, 2));\n },\n /**\n * Map any angle (any numeric value) to [0, Math.PI).\n *\n * A × B := (A.x * B.x) + (A.y * B.y)\n *\n * @param {XYCoords} vertA - The first vertex.\n * @param {XYCoords} vertB - The second vertex.\n * @return {number} The dot product of the two vertices.\n **/\n dotProduct: function (vertA, vertB) {\n return vertA.x * vertB.x + vertA.y * vertB.y;\n },\n /**\n * Compute the n-section of the angle – described as a triangle (A,B,C) – in point A.\n *\n * @param {Vertex} pA - The first triangle point.\n * @param {Vertex} pB - The second triangle point.\n * @param {Vertex} pC - The third triangle point.\n * @param {number} n - The number of desired angle sections (example: 2 means the angle will be divided into two sections,\n * means an returned array with length 1, the middle line).\n *\n * @return {Line[]} An array of n-1 lines secting the given angle in point A into n equal sized angle sections. The lines' first vertex is A.\n */\n nsectAngle: function (pA, pB, pC, n) {\n var triangle = new Triangle_1.Triangle(pA, pB, pC);\n var lineAB = new Line_1.Line(pA, pB);\n var lineAC = new Line_1.Line(pA, pC);\n // Compute the difference; this is the angle between AB and AC\n var insideAngle = lineAB.angle(lineAC);\n // We want the inner angles of the triangle, not the outer angle;\n // which one is which depends on the triangle 'direction'\n var clockwise = triangle.determinant() > 0;\n // For convenience convert the angle [-PI,PI] to [0,2*PI]\n if (insideAngle < 0)\n insideAngle = 2 * Math.PI + insideAngle;\n if (!clockwise)\n insideAngle = (2 * Math.PI - insideAngle) * -1;\n // Scale the rotated lines to the max leg length (looks better)\n var lineLength = Math.max(lineAB.length(), lineAC.length());\n var scaleFactor = lineLength / lineAB.length();\n var result = [];\n for (var i = 1; i < n; i++) {\n // Compute the i-th inner sector line\n result.push(new Line_1.Line(pA, pB.clone().rotate(-i * (insideAngle / n), pA)).scale(scaleFactor));\n }\n return result;\n },\n /**\n * Wrap the value (e.g. an angle) into the given range of [0,max).\n *\n * @name wrapMax\n * @param {number} x - The value to wrap.\n * @param {number} max - The max bound to use for the range.\n * @return {number} The wrapped value inside the range [0,max).\n */\n wrapMax: function (x, max) {\n // Found at\n // https://stackoverflow.com/questions/4633177/c-how-to-wrap-a-float-to-the-interval-pi-pi\n return (max + (x % max)) % max;\n },\n /**\n * Wrap the value (e.g. an angle) into the given range of [min,max).\n *\n * @name wrapMinMax\n * @param {number} x - The value to wrap.\n * @param {number} min - The min bound to use for the range.\n * @param {number} max - The max bound to use for the range.\n * @return {number} The wrapped value inside the range [min,max).\n */\n // Currently un-used\n wrapMinMax: function (x, min, max) {\n return min + exports.geomutils.wrapMax(x - min, max - min);\n }\n};\n//# sourceMappingURL=geomutils.js.map","\"use strict\";\n/**\n * Draws elements into an SVG node.\n *\n * Note that this library uses buffers and draw cycles. To draw onto an SVG canvas, do this:\n * const drawLib = new drawutilssvg( svgNode, ... );\n * const fillLib = drawLib.copyInstance(true);\n * // Begin draw cycle\n * drawLib.beginDrawCycle(time);\n * // ... draw or fill your stuff ...\n * drawLib.endDrawCycle(time); // Here the elements become visible\n *\n * @author Ikaros Kappler\n * @date 2021-01-03\n * @modified 2021-01-24 Fixed the `fillShapes` attribute in the copyInstance function.\n * @modified 2021-01-26 Changed the `isPrimary` (default true) attribute to `isSecondary` (default false).\n * @modified 2021-02-03 Added the static `createSvg` function.\n * @modified 2021-02-03 Fixed the currentId='background' bug on the clear() function.\n * @modified 2021-02-03 Fixed CSSProperty `stroke-width` (was line-width before, which is wrong).\n * @modified 2021-02-03 Added the static `HEAD_XML` attribute.\n * @modified 2021-02-19 Added the static helper function `transformPathData(...)` for svg path transformations (scale and translate).\n * @modified 2021-02-22 Added the static helper function `copyPathData(...)`.\n * @modified 2021-02-22 Added the `path` drawing function to draw SVG path data.\n * @modified 2021-03-01 Fixed a bug in the `clear` function (curClassName was not cleared).\n * @modified 2021-03-29 Fixed a bug in the `text` function (second y param was wrong, used x here).\n * @modified 2021-03-29 Moved this file from `src/ts/utils/helpers/` to `src/ts/`.\n * @modified 2021-03-31 Added 'ellipseSector' the the class names.\n * @modified 2021-03-31 Implemented buffering using a buffer <g> node and the beginDrawCycle and endDrawCycle methods.\n * @modified 2021-05-31 Added the `setConfiguration` function from `DrawLib`.\n * @modified 2021-11-15 Adding more parameters tot the `text()` function: fontSize, textAlign, fontFamily, lineHeight.\n * @modified 2021-11-19 Fixing the `label(text,x,y)` position.\n * @modified 2021-11-19 Added the `color` param to the `label(...)` function.\n * @modified 2022-02-03 Added the `lineWidth` param to the `crosshair` function.\n * @modified 2022-02-03 Added the `cross(...)` function.\n * @modified 2022-03-26 Added the private `nodeDefs` and `bufferedNodeDefs` attributes.\n * @modified 2022-03-26 Added the `texturedPoly` function to draw textures polygons.\n * @modified 2022-07-26 Adding `alpha` to the `image(...)` function.\n * @modified 2022-11-10 Tweaking some type issues.\n * @modified 2023-02-04 Fixed a typo in the CSS classname for cubic Bézier paths: cubicBezier (was cubierBezier).\n * @modified 2023-02-10 The methods `setCurrentClassName` and `setCurrentId` also accept `null` now.\n * @modified 2023-09-29 Added initialization checks for null parameters.\n * @modified 2023-09-29 Added a missing implementation to the `drawurilssvg.do(XYCoords,string)` function. Didn't draw anything.\n * @modified 2023-09-29 Downgrading all `Vertex` param type to the more generic `XYCoords` type in these render functions: line, arrow, texturedPoly, cubicBezier, cubicBezierPath, handle, handleLine, dot, point, circle, circleArc, ellipse, grid, raster.\n * @modified 2023-09-29 Added the `headLength` parameter to the 'DrawLib.arrow()` function.\n * @modified 2023-09-29 Added the `arrowHead(...)` function to the 'DrawLib.arrow()` interface.\n * @modified 2023-09-29 Added the `cubicBezierArrow(...)` function to the 'DrawLib.arrow()` interface.\n * @modified 2023-10-04 Adding `strokeOptions` param to these draw function: line, arrow, cubicBezierArrow, cubicBezier, cubicBezierPath, circle, circleArc, ellipse, square, rect, polygon, polyline.\n * @modified 2024-01-30 Fixing an issue with immutable style sets; changes to the global draw config did not reflect here (do now).\n * @modified 2024-03-10 Fixing some types for Typescript 5 compatibility.\n * @modified 2024-07-24 Caching custom style defs in a private buffer variable.\n * @modified 2025-11-14 Fixing a bug in the CSS `mix-blend-mode` property handling (caused a runtime error).\n * @modified 2026-01-04 Adding `lineJoin` attribute to the methods' `StrokeOptions` param.\n * @modified 2026-01-04 Fixing missing `strokeOptions` param in the `drawutilssvg.polygon` method.\n * @modified 2026-03-18 Adding `isOpen` parameter to `cubicBezierPath` draw method.\n * @modified 2026-04-04 Added the method `bounds`.\n * @modified 2026-04-04 Handling the `stroke-linecap` option now from the `StrokeOptions` interface.\n * @modified 2026-04-04 Chaning the `copyPathData` method by usind `Array.slice()`.\n * @version 1.7.0\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.drawutilssvg = void 0;\nvar CircleSector_1 = require(\"./CircleSector\");\nvar CubicBezierCurve_1 = require(\"./CubicBezierCurve\");\nvar Vertex_1 = require(\"./Vertex\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar Vector_1 = require(\"./Vector\");\nvar RAD_TO_DEG = 180 / Math.PI;\n/**\n * @classdesc A helper class for basic SVG drawing operations. This class should\n * be compatible to the default 'draw' class.\n *\n * @requires CubicBzierCurvce\n * @requires Polygon\n * @requires Vertex\n * @requires XYCoords\n */\nvar drawutilssvg = /** @class */ (function () {\n /**\n * Passed from primary to secondary instance.\n */\n //private nodeStyle: SVGStyleElement;\n /**\n * The constructor.\n *\n * @constructor\n * @name drawutilssvg\n * @param {SVGElement} svgNode - The SVG node to use.\n * @param {XYCoords} offset - The draw offset to use.\n * @param {XYCoords} scale - The scale factors to use.\n * @param {XYDimension} canvasSize - The initial canvas size (use setSize to change).\n * @param {boolean} fillShapes - Indicates if the constructed drawutils should fill all drawn shapes (if possible).\n * @param {DrawConfig} drawConfig - The default draw config to use for CSS fallback styles.\n * @param {boolean=} isSecondary - (optional) Indicates if this is the primary or secondary instance. Only primary instances manage child nodes.\n * @param {SVGGElement=} gNode - (optional) Primary and seconday instances share the same &lt;g> node.\n **/\n function drawutilssvg(svgNode, offset, scale, canvasSize, fillShapes, drawConfig, isSecondary, gNode, bufferGNode, nodeDefs, bufferNodeDefs, nodeStyle) {\n this.svgNode = svgNode;\n this.offset = new Vertex_1.Vertex(0, 0).set(offset);\n this.scale = new Vertex_1.Vertex(1, 1).set(scale);\n this.fillShapes = fillShapes;\n this.isSecondary = Boolean(isSecondary);\n this.drawConfig = drawConfig;\n this.drawlibConfiguration = {};\n this.cache = new Map();\n this.setSize(canvasSize);\n if (isSecondary) {\n if (!gNode || !bufferGNode || !nodeDefs || !bufferNodeDefs) {\n throw \"Cannot create secondary svg draw lib with undefinde gNode|bufferGNode|nodeDefs|bufferNodeDefs.\";\n }\n this.gNode = gNode;\n this.bufferGNode = bufferGNode;\n this.nodeDefs = nodeDefs;\n this.bufferedNodeDefs = bufferNodeDefs;\n if (nodeStyle) {\n this.nodeStyle = nodeStyle;\n }\n }\n else {\n this.addStyleDefs(drawConfig);\n this.addDefsNode();\n this.gNode = this.createSVGNode(\"g\");\n this.bufferGNode = this.createSVGNode(\"g\");\n this.svgNode.appendChild(this.gNode);\n }\n }\n /**\n * Adds a default style defintion based on the passed DrawConfig.\n * Twaek the draw config to change default colors or line thicknesses.\n *\n * @param {DrawConfig} drawConfig\n */\n drawutilssvg.prototype.addStyleDefs = function (drawConfig) {\n this.nodeStyle = this.createSVGNode(\"style\");\n this.svgNode.appendChild(this.nodeStyle);\n this.rebuildStyleDefs(drawConfig);\n };\n /**\n * This method is required to re-define the global style defs. It is needed\n * if any value in the DrawConfig changed in the meantime.\n * @param drawConfig\n */\n drawutilssvg.prototype.rebuildStyleDefs = function (drawConfig) {\n // Which default styles to add? -> All from the DrawConfig.\n // Compare with DrawConfig interface\n var keys = {\n \"bezier\": \"CubicBezierCurve\",\n //\"bezierPath\": \"BezierPath\", // TODO: is this correct?\n \"polygon\": \"Polygon\",\n \"triangle\": \"Triangle\",\n \"ellipse\": \"Ellipse\",\n \"ellipseSector\": \"EllipseSector\",\n \"circle\": \"Circle\",\n \"circleSector\": \"CircleSector\",\n \"vertex\": \"Vertex\",\n \"line\": \"Line\",\n \"vector\": \"Vector\",\n \"image\": \"Image\",\n \"text\": \"Text\"\n };\n // Question: why isn't this working if the svgNode is created dynamically? (nodeStyle.sheet is null)\n var rules = [];\n // console.log(\"drawConfig\", drawConfig);\n for (var k in keys) {\n var className = keys[k];\n var drawSettings = drawConfig[k];\n if (drawSettings) {\n rules.push(\".\".concat(className, \" { fill : none; stroke: \").concat(drawSettings.color, \"; stroke-width: \").concat(drawSettings.lineWidth, \"px }\"));\n }\n else {\n console.warn(\"Warning: your draw config is missing the key '\".concat(k, \"' which is required.\"));\n }\n }\n if (this.customStyleDefs) {\n rules.push(\"\\n/* Custom styles */\\n\");\n this.customStyleDefs.forEach(function (value, key) {\n rules.push(key + \" { \" + value + \" }\");\n });\n // this.nodeStyle.innerHTML += \"\\n/* Custom styles */\\n\" + rules.join(\"\\n\");\n }\n this.nodeStyle.innerHTML = rules.join(\"\\n\");\n };\n /**\n * Adds the internal <defs> node.\n */\n drawutilssvg.prototype.addDefsNode = function () {\n this.nodeDefs = this.createSVGNode(\"defs\");\n // this.svgNode.appendChild(this.nodeDefs);\n this.bufferedNodeDefs = this.createSVGNode(\"defs\");\n this.svgNode.appendChild(this.nodeDefs);\n };\n /**\n * This is a simple way to include custom CSS class mappings to the style defs of the generated SVG.\n *\n * The mapping should be of the form\n * [style-class] -> [style-def-string]\n *\n * Example:\n * \"rect.red\" -> \"fill: #ff0000; border: 1px solid red\"\n *\n * @param {Map<string,string>} defs\n */\n drawutilssvg.prototype.addCustomStyleDefs = function (defs) {\n this.customStyleDefs = defs;\n };\n /**\n * Retieve an old (cached) element.\n * Only if both – key and nodeName – match, the element will be returned (null otherwise).\n *\n * @method findElement\n * @private\n * @memberof drawutilssvg\n * @instance\n * @param {UID} key - The key of the desired element (used when re-drawing).\n * @param {string} nodeName - The expected node name.\n */\n drawutilssvg.prototype.findElement = function (key, nodeName) {\n if (!key) {\n return null;\n }\n var node = this.cache.get(key);\n if (node && node.nodeName.toUpperCase() === nodeName.toUpperCase()) {\n this.cache.delete(key);\n return node;\n }\n return null;\n };\n /**\n * Create a new DOM node &lt;svg&gt; in the SVG namespace.\n *\n * @method createSVGNode\n * @private\n * @memberof drawutilssvg\n * @instance\n * @param {string} nodeName - The node name (tag-name).\n * @return {SVGElement} A new element in the SVG namespace with the given node name.\n */\n drawutilssvg.prototype.createSVGNode = function (nodeName) {\n return document.createElementNS(\"http://www.w3.org/2000/svg\", nodeName);\n };\n /**\n * Make a new SVG node (or recycle an old one) with the given node name (circle, path, line, rect, ...).\n *\n * This function is used in draw cycles to re-use old DOM nodes (in hope to boost performance).\n *\n * @method makeNode\n * @private\n * @instance\n * @memberof drawutilssvg\n * @param {string} nodeName - The node name.\n * @return {SVGElement} The new node, which is not yet added to any document.\n */\n drawutilssvg.prototype.makeNode = function (nodeName) {\n // Try to find node in current DOM cache.\n // Unique node keys are strictly necessary.\n // Try to recycle an old element from cache.\n var node = this.findElement(this.curId, nodeName);\n if (!node) {\n // If no such old elements exists (key not found, tag name not matching),\n // then create a new one.\n node = this.createSVGNode(nodeName);\n }\n if (this.drawlibConfiguration.blendMode) {\n var blendMode = node.style[\"mix-blend-mode\"];\n if (typeof blendMode === \"function\") {\n blendMode(this.drawlibConfiguration.blendMode);\n }\n else {\n node.style[\"mix-blend-mode\"] = this.drawlibConfiguration.blendMode;\n }\n }\n // if (this.lineDashEnabled && this.lineDash && this.lineDash.length > 0 && drawutilssvg.nodeSupportsLineDash(nodeName)) {\n // node.setAttribute(\"stroke-dasharray\", this.lineDash.join(\" \"));\n // }\n return node;\n };\n /**\n * This is the final helper function for drawing and filling stuff and binding new\n * nodes to the SVG document.\n * It is not intended to be used from the outside.\n *\n * When in draw mode it draws the current shape.\n * When in fill mode it fills the current shape.\n *\n * This function is usually only called internally.\n *\n * @method _bindFillDraw\n * @private\n * @instance\n * @memberof drawutilssvg\n * @param {SVGElement} node - The node to draw/fill and bind.\n * @param {string} className - The class name(s) to use.\n * @param {string} color - A stroke/fill color to use.\n * @param {number=1} lineWidth - (optional) A line width to use for drawing (default is 1).\n * @return {SVGElement} The node itself (for chaining).\n */\n drawutilssvg.prototype._bindFillDraw = function (node, className, color, lineWidth, strokeOptions) {\n this._configureNode(node, className, this.fillShapes, color, lineWidth, strokeOptions);\n return this._bindNode(node, undefined);\n };\n /**\n * Bind this given node to a parent. If no parent is passed then the global\n * node buffer will be used.\n *\n * @method _bindNode\n * @private\n * @instance\n * @memberof drawutilssvg\n * @param {SVGElement} node - The SVG node to bind.\n * @param {SVGElement=} bindingParent - (optional) You may pass node other than the glober buffer node.\n * @returns {SVGElement} The passed node itself.\n */\n drawutilssvg.prototype._bindNode = function (node, bindingParent) {\n if (!node.parentNode) {\n // Attach to DOM only if not already attached\n (bindingParent !== null && bindingParent !== void 0 ? bindingParent : this.bufferGNode).appendChild(node);\n }\n return node;\n };\n /**\n * Add custom CSS class names and the globally defined CSS classname to the\n * given node.\n *\n * @method addCSSClasses\n * @private\n * @instance\n * @memberof drawutilssvg\n * @param {SVGElement} node - The SVG node to bind.\n * @param {string} className - The additional custom classname to add.\n * @returns {void}\n */\n drawutilssvg.prototype._addCSSClasses = function (node, className) {\n if (this.curClassName) {\n node.setAttribute(\"class\", \"\".concat(className, \" \").concat(this.curClassName));\n }\n else {\n node.setAttribute(\"class\", className);\n }\n };\n drawutilssvg.prototype._configureNode = function (node, className, fillMode, color, lineWidth, strokeOptions) {\n this._addCSSClasses(node, className);\n node.setAttribute(\"fill\", fillMode && color ? color : \"none\");\n node.setAttribute(\"stroke\", fillMode ? \"none\" : color || \"none\");\n node.setAttribute(\"stroke-width\", \"\".concat(lineWidth || 1));\n if (this.curId) {\n node.setAttribute(\"id\", \"\".concat(this.curId)); // Maybe React-style 'key' would be better?\n }\n this.applyStrokeOpts(node, strokeOptions);\n return node;\n };\n /**\n * Sets the size and view box of the document. Call this if canvas size changes.\n *\n * @method setSize\n * @instance\n * @memberof drawutilssvg\n * @param {XYDimension} canvasSize - The new canvas size.\n */\n drawutilssvg.prototype.setSize = function (canvasSize) {\n this.canvasSize = canvasSize;\n this.svgNode.setAttribute(\"viewBox\", \"0 0 \".concat(this.canvasSize.width, \" \").concat(this.canvasSize.height));\n this.svgNode.setAttribute(\"width\", \"\".concat(this.canvasSize.width));\n this.svgNode.setAttribute(\"height\", \"\".concat(this.canvasSize.height));\n };\n /**\n * Creates a 'shallow' (non deep) copy of this instance. This implies\n * that under the hood the same gl context and gl program will be used.\n */\n drawutilssvg.prototype.copyInstance = function (fillShapes) {\n var copy = new drawutilssvg(this.svgNode, this.offset, this.scale, this.canvasSize, fillShapes, this.drawConfig, // null as any as DrawConfig, // no DrawConfig – this will work as long as `isSecondary===true`\n true, // isSecondary\n this.gNode, this.bufferGNode, this.nodeDefs, this.bufferedNodeDefs, this.nodeStyle);\n return copy;\n };\n /**\n * Set the current drawlib configuration.\n *\n * @name setConfiguration\n * @method\n * @param {DrawLibConfiguration} configuration - The new configuration settings to use for the next render methods.\n */\n drawutilssvg.prototype.setConfiguration = function (configuration) {\n this.drawlibConfiguration = configuration;\n };\n /**\n * This method shouled be called each time the currently drawn `Drawable` changes.\n * It is used by some libraries for identifying elemente on re-renders.\n *\n * @name setCurrentId\n * @method\n * @param {UID|null} uid - A UID identifying the currently drawn element(s).\n * @instance\n * @memberof drawutilssvg\n **/\n drawutilssvg.prototype.setCurrentId = function (uid) {\n this.curId = uid;\n };\n /**\n * This method shouled be called each time the currently drawn `Drawable` changes.\n * Determine the class name for further usage here.\n *\n * @name setCurrentClassName\n * @method\n * @param {string|null} className - A class name for further custom use cases.\n * @instance\n * @memberof drawutilssvg\n **/\n drawutilssvg.prototype.setCurrentClassName = function (className) {\n this.curClassName = className;\n };\n /**\n * Called before each draw cycle.\n * This is required for compatibility with other draw classes in the library.\n *\n * @name beginDrawCycle\n * @method\n * @param {UID=} uid - (optional) A UID identifying the currently drawn element(s).\n * @instance\n * @memberof drawutilssvg\n **/\n drawutilssvg.prototype.beginDrawCycle = function (renderTime) {\n // Clear non-recycable elements from last draw cycle.\n this.cache.clear();\n // Clearing an SVG is equivalent to removing all its child elements.\n for (var i = 0; i < this.bufferGNode.childNodes.length; i++) {\n // Hide all nodes here. Don't throw them away.\n // We can probably re-use them in the next draw cycle.\n var child = this.bufferGNode.childNodes[i];\n this.cache.set(child.getAttribute(\"id\"), child);\n }\n this.removeAllChildNodes();\n };\n /**\n * Called after each draw cycle.\n *\n * This is required for compatibility with other draw classes in the library (like drawgl).\n *\n * @name endDrawCycle\n * @method\n * @param {number} renderTime\n * @instance\n **/\n drawutilssvg.prototype.endDrawCycle = function (renderTime) {\n this.rebuildStyleDefs(this.drawConfig);\n if (!this.isSecondary) {\n // All elements are drawn into the buffer; they are NOT yet visible, not did the browser perform any\n // layout updates.\n // Replace the old <g>-node with the buffer node.\n // https://stackoverflow.com/questions/27442464/how-to-update-a-svg-image-without-seeing-a-blinking\n this.svgNode.replaceChild(this.bufferedNodeDefs, this.nodeDefs);\n this.svgNode.replaceChild(this.bufferGNode, this.gNode);\n }\n var tmpGNode = this.gNode;\n this.gNode = this.bufferGNode;\n this.bufferGNode = tmpGNode;\n var tmpDefsNode = this.nodeDefs;\n this.nodeDefs = this.bufferedNodeDefs;\n this.bufferedNodeDefs = tmpDefsNode;\n };\n /**\n * A private helper method to apply stroke options to the current\n * context.\n * @param {StrokeOptions=} strokeOptions -\n */\n drawutilssvg.prototype.applyStrokeOpts = function (node, strokeOptions) {\n var _this = this;\n // Set line dash options?\n if (strokeOptions &&\n strokeOptions.dashArray &&\n strokeOptions.dashArray.length > 0 &&\n drawutilssvg.nodeSupportsLineDash(node.tagName)) {\n node.setAttribute(\"stroke-dasharray\", strokeOptions.dashArray\n .map(function (dashArayElem) {\n return dashArayElem * _this.scale.x;\n })\n .join(\" \"));\n if (strokeOptions.dashOffset) {\n node.setAttribute(\"stroke-dashoffset\", \"\".concat(strokeOptions.dashOffset * this.scale.x));\n }\n }\n // Set line join option?\n if (strokeOptions && strokeOptions.lineJoin && drawutilssvg.nodeSupportsLineJoin(node.tagName)) {\n node.setAttribute(\"stroke-linejoin\", strokeOptions.lineJoin);\n }\n // Set lineCap option?\n if (strokeOptions && strokeOptions.lineCap && drawutilssvg.nodeSupportsLineCap(node.tagName)) {\n node.setAttribute(\"stroke-linecap\", strokeOptions.lineCap);\n }\n };\n drawutilssvg.prototype._x = function (x) {\n return this.offset.x + this.scale.x * x;\n };\n drawutilssvg.prototype._y = function (y) {\n return this.offset.y + this.scale.y * y;\n };\n /**\n * Draw the line between the given two points with the specified (CSS-) color.\n *\n * @method line\n * @param {XYCoords} zA - The start point of the line.\n * @param {XYCoords} zB - The end point of the line.\n * @param {string} color - Any valid CSS color string.\n * @param {number=1} lineWidth? - [optional] The line's width.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n **/\n drawutilssvg.prototype.line = function (zA, zB, color, lineWidth, strokeOptions) {\n // const line: SVGElement = this.makeNode(\"line\");\n // this.applyStrokeOpts(line, strokeOptions);\n // line.setAttribute(\"x1\", `${this._x(zA.x)}`);\n // line.setAttribute(\"y1\", `${this._y(zA.y)}`);\n // line.setAttribute(\"x2\", `${this._x(zB.x)}`);\n // line.setAttribute(\"y2\", `${this._y(zB.y)}`);\n var line = this.makeLineNode(zA, zB, color, lineWidth, strokeOptions);\n return this._bindFillDraw(line, \"line\", color, lineWidth || 1, strokeOptions);\n };\n /**\n * Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.\n *\n * @method arrow\n * @param {XYCoords} zA - The start point of the arrow-line.\n * @param {XYCoords} zB - The end point of the arrow-line.\n * @param {string} color - Any valid CSS color string.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {headLength=8} headLength - (optional) The length of the arrow head (default is 8 units).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n **/\n drawutilssvg.prototype.arrow = function (zA, zB, color, lineWidth, headLength, strokeOptions) {\n if (headLength === void 0) { headLength = 8; }\n var group = this.makeNode(\"g\");\n var arrowHeadBasePosition = { x: 0, y: 0 };\n // Just create the child nodes, don't bind them to the root node.\n var arrowHead = this.makeArrowHeadNode(zA, zB, color, lineWidth, headLength, undefined, arrowHeadBasePosition);\n var line = this.makeLineNode(zA, arrowHeadBasePosition, color, lineWidth, strokeOptions);\n group.appendChild(line);\n group.appendChild(arrowHead);\n this._addCSSClasses(group, \"linear-arrow\");\n this._bindNode(group, undefined);\n return group;\n };\n /**\n * Draw a cubic Bézier curve and and an arrow at the end (endControlPoint) of the given line width the specified (CSS-) color and arrow size.\n *\n * @method cubicBezierArrow\n * @param {XYCoords} startPoint - The start point of the cubic Bézier curve\n * @param {XYCoords} endPoint - The end point the cubic Bézier curve.\n * @param {XYCoords} startControlPoint - The start control point the cubic Bézier curve.\n * @param {XYCoords} endControlPoint - The end control point the cubic Bézier curve.\n * @param {string} color - The CSS color to draw the curve with.\n * @param {number} lineWidth - (optional) The line width to use.\n * @param {headLength=8} headLength - (optional) The length of the arrow head (default is 8 units).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof DrawLib\n */\n drawutilssvg.prototype.cubicBezierArrow = function (startPoint, endPoint, startControlPoint, endControlPoint, color, lineWidth, headLength, strokeOptions) {\n if (headLength === void 0) { headLength = 8; }\n var group = this.makeNode(\"g\");\n // Just create the child nodes, don't bind them to the root node.\n var arrowHeadBasePosition = new Vertex_1.Vertex(0, 0);\n var arrowHead = this.makeArrowHeadNode(endControlPoint, endPoint, color, lineWidth, headLength, undefined, arrowHeadBasePosition);\n var diff = arrowHeadBasePosition.difference(endPoint);\n var bezier = this.makeCubicBezierNode(startPoint, { x: endPoint.x - diff.x, y: endPoint.y - diff.y }, startControlPoint, { x: endControlPoint.x - diff.x, y: endControlPoint.y - diff.y }, color, lineWidth, strokeOptions);\n group.appendChild(bezier);\n group.appendChild(arrowHead);\n this._addCSSClasses(group, \"cubicbezier-arrow\");\n this._bindNode(group, undefined);\n return group;\n };\n /**\n * Draw just an arrow head a the end of an imaginary line (zB) of the given line width the specified (CSS-) color and size.\n *\n * @method arrow\n * @param {XYCoords} zA - The start point of the arrow-line.\n * @param {XYCoords} zB - The end point of the arrow-line.\n * @param {string} color - Any valid CSS color string.\n * @param {number=1} lineWidth - (optional) The line width to use; default is 1.\n * @param {number=8} headLength - (optional) The length of the arrow head (default is 8 pixels).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof DrawLib\n **/\n drawutilssvg.prototype.arrowHead = function (zA, zB, color, lineWidth, headLength, strokeOptions) {\n if (headLength === void 0) { headLength = 8; }\n var node = this.makeArrowHeadNode(zA, zB, color, lineWidth, headLength, strokeOptions);\n return this._bindFillDraw(node, \"arrowhead\", color, lineWidth || 1, strokeOptions);\n };\n /**\n * Draw an image at the given position with the given size.<br>\n * <br>\n * Note: SVG images may have resizing issues at the moment.Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.\n *\n * @method image\n * @param {Image} image - The image object to draw.\n * @param {XYCoords} position - The position to draw the the upper left corner at.\n * @param {XYCoords} size - The x/y-size to draw the image with.\n * @param {number=0.0} alpha - (optional, default=0.0) The transparency (1.0=opaque, 0.0=transparent).\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n **/\n drawutilssvg.prototype.image = function (image, position, size, alpha) {\n var _this = this;\n if (alpha === void 0) { alpha = 1.0; }\n var node = this.makeNode(\"image\");\n // We need to re-adjust the image if it was not yet fully loaded before.\n var setImageSize = function (image) {\n if (image.naturalWidth) {\n var ratioX = size.x / image.naturalWidth;\n var ratioY = size.y / image.naturalHeight;\n node.setAttribute(\"width\", \"\".concat(image.naturalWidth * _this.scale.x));\n node.setAttribute(\"height\", \"\".concat(image.naturalHeight * _this.scale.y));\n node.setAttribute(\"display\", null); // Dislay when loaded\n // if (alpha) {\n node.setAttribute(\"opacity\", \"\".concat(alpha));\n // }\n node.setAttribute(\"transform\", \"translate(\".concat(_this._x(position.x), \" \").concat(_this._y(position.y), \") scale(\").concat(ratioX, \" \").concat(ratioY, \")\"));\n }\n };\n image.addEventListener(\"load\", function (event) {\n setImageSize(image);\n });\n // Safari has a transform-origin bug.\n // Use x=0, y=0 and translate/scale instead (see above)\n node.setAttribute(\"x\", \"\".concat(0));\n node.setAttribute(\"y\", \"\".concat(0));\n node.setAttribute(\"display\", \"none\"); // Hide before loaded\n setImageSize(image);\n node.setAttribute(\"href\", image.src);\n return this._bindFillDraw(node, \"image\", null, null);\n };\n /**\n * Draw an image at the given position with the given size.<br>\n * <br>\n * Note: SVG images may have resizing issues at the moment.Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.\n *\n * @method texturedPoly\n * @param {Image} textureImage - The image object to draw.\n * @param {Bounds} textureSize - The texture size to use; these are the original bounds to map the polygon vertices to.\n * @param {Polygon} polygon - The polygon to use as clip path.\n * @param {XYCoords} polygonPosition - The polygon's position (relative), measured at the bounding box's center.\n * @param {number} rotation - The rotation to use for the polygon (and for the texture).\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n **/\n drawutilssvg.prototype.texturedPoly = function (textureImage, textureSize, polygon, polygonPosition, rotation) {\n // const basePolygonBounds: Bounds = polygon.getBounds();\n var rotatedScalingOrigin = new Vertex_1.Vertex(textureSize.min).clone().rotate(rotation, polygonPosition);\n // const rotationCenter = polygonPosition.clone().add(rotatedScalingOrigin.difference(textureSize.min).inv());\n // Create something like this\n // ...\n // <defs>\n // <clipPath id=\"shape\">\n // <path fill=\"none\" d=\"...\"/>\n // </clipPath>\n // </defs>\n // ...\n // <g clip-path=\"url(#shape)\">\n // <g transform=\"scale(...)\">\n // <image width=\"643\" height=\"643\" transform=\"rotate(...)\" xlink:href=\"https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/beagle400.jpg\" >\n // </g>\n // </g>\n // </image>\n // ...\n var clipPathNode = this.makeNode(\"clipPath\");\n var clipPathId = \"clippath_\".concat(UIDGenerator_1.UIDGenerator.next()); // TODO: use a better UUID generator here?\n clipPathNode.setAttribute(\"id\", clipPathId);\n var gNode = this.makeNode(\"g\");\n var imageNode = this.makeNode(\"image\");\n imageNode.setAttribute(\"x\", \"\".concat(this._x(rotatedScalingOrigin.x)));\n imageNode.setAttribute(\"y\", \"\".concat(this._y(rotatedScalingOrigin.y)));\n imageNode.setAttribute(\"width\", \"\".concat(textureSize.width));\n imageNode.setAttribute(\"height\", \"\".concat(textureSize.height));\n imageNode.setAttribute(\"href\", textureImage.src);\n // imageNode.setAttribute(\"opacity\", \"0.5\");\n // SVG rotations in degrees\n imageNode.setAttribute(\"transform\", \"rotate(\".concat(rotation * RAD_TO_DEG, \", \").concat(this._x(rotatedScalingOrigin.x), \", \").concat(this._y(rotatedScalingOrigin.y), \")\"));\n var pathNode = this.makeNode(\"path\");\n var pathData = [];\n if (polygon.vertices.length > 0) {\n var self_1 = this;\n pathData.push(\"M\", \"\".concat(this._x(polygon.vertices[0].x)), \"\".concat(this._y(polygon.vertices[0].y)));\n for (var i = 1; i < polygon.vertices.length; i++) {\n pathData.push(\"L\", \"\".concat(this._x(polygon.vertices[i].x)), \"\".concat(this._y(polygon.vertices[i].y)));\n }\n }\n pathNode.setAttribute(\"d\", pathData.join(\" \"));\n clipPathNode.appendChild(pathNode);\n this.bufferedNodeDefs.appendChild(clipPathNode);\n gNode.appendChild(imageNode);\n gNode.setAttribute(\"transform-origin\", \"\".concat(this._x(rotatedScalingOrigin.x), \" \").concat(this._y(rotatedScalingOrigin.y)));\n gNode.setAttribute(\"transform\", \"scale(\".concat(this.scale.x, \", \").concat(this.scale.y, \")\"));\n var clipNode = this.makeNode(\"g\");\n clipNode.appendChild(gNode);\n clipNode.setAttribute(\"clip-path\", \"url(#\".concat(clipPathId, \")\"));\n // TODO: check if the image class is correct here or if we should use a 'clippedImage' class here\n this._bindFillDraw(clipNode, \"image\", null, null); // No color, no lineWidth\n return clipNode;\n };\n /**\n * Draw the given (cubic) bézier curve.\n *\n * @method cubicBezier\n * @param {XYCoords} startPoint - The start point of the cubic Bézier curve\n * @param {XYCoords} endPoint - The end point the cubic Bézier curve.\n * @param {XYCoords} startControlPoint - The start control point the cubic Bézier curve.\n * @param {XYCoords} endControlPoint - The end control point the cubic Bézier curve.\n * @param {string} color - The CSS color to draw the curve with.\n * @param {number} lineWidth - (optional) The line width to use.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.cubicBezier = function (startPoint, endPoint, startControlPoint, endControlPoint, color, lineWidth, strokeOptions) {\n var node = this.makeCubicBezierNode(startPoint, endPoint, startControlPoint, endControlPoint, color, lineWidth, strokeOptions);\n return this._bindNode(node, undefined);\n };\n /**\n * Draw the given (cubic) Bézier path.\n *\n * The given path must be an array with n*3+1 vertices, where n is the number of\n * curves in the path:\n * <pre> [ point1, point1_startControl, point2_endControl, point2, point2_startControl, point3_endControl, point3, ... pointN_endControl, pointN ]</pre>\n *\n * @method cubicBezierPath\n * @param {XYCoords[]} path - The cubic bezier path as described above.\n * @param {string} color - The CSS colot to draw the path with.\n * @param {number=1} lineWidth - (optional) The line width to use.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n * @param {boolean} isOpen - (optional) Set to tur if the path should not be closed.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.cubicBezierPath = function (path, color, lineWidth, strokeOptions, isOpen) {\n var node = this.makeNode(\"path\");\n this.applyStrokeOpts(node, strokeOptions);\n if (!path || path.length == 0) {\n return node;\n }\n // Draw curve\n var d = [\"M\", this._x(path[0].x), this._y(path[0].y)];\n // Draw curve path\n var endPoint;\n var startControlPoint;\n var endControlPoint;\n for (var i = 1; i < path.length; i += 3) {\n startControlPoint = path[i];\n endControlPoint = path[i + 1];\n endPoint = path[i + 2];\n d.push(\"C\", this._x(startControlPoint.x), this._y(startControlPoint.y), this._x(endControlPoint.x), this._y(endControlPoint.y), this._x(endPoint.x), this._y(endPoint.y));\n }\n if (!isOpen) {\n d.push(\"Z\");\n }\n node.setAttribute(\"d\", d.join(\" \"));\n return this._bindFillDraw(node, \"cubicBezierPath\", color, lineWidth || 1);\n };\n /**\n * Draw the given handle and handle point (used to draw interactive Bézier curves).\n *\n * The colors for this are fixed and cannot be specified.\n *\n * @method handle\n * @param {Vertex} startPoint - The start of the handle.\n * @param {Vertex} endPoint - The end point of the handle.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.handle = function (startPoint, endPoint) {\n // TODO: redefine methods like these into an abstract class?\n this.point(startPoint, \"rgb(0,32,192)\");\n this.square(endPoint, 5, \"rgba(0,128,192,0.5)\");\n };\n /**\n * Draw a handle line (with a light grey).\n *\n * @method handleLine\n * @param {XYCoords} startPoint - The start point to draw the handle at.\n * @param {XYCoords} endPoint - The end point to draw the handle at.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.handleLine = function (startPoint, endPoint) {\n this.line(startPoint, endPoint, \"rgb(128,128,128,0.5)\");\n };\n /**\n * Draw a 1x1 dot with the specified (CSS-) color.\n *\n * @method dot\n * @param {XYCoords} p - The position to draw the dot at.\n * @param {string} color - The CSS color to draw the dot with.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.dot = function (p, color) {\n var node = this.makeNode(\"line\");\n node.setAttribute(\"x1\", \"\".concat(this._x(p.x)));\n node.setAttribute(\"y1\", \"\".concat(this._y(p.y)));\n node.setAttribute(\"x2\", \"\".concat(this._x(p.x)));\n node.setAttribute(\"y2\", \"\".concat(this._y(p.y)));\n return this._bindFillDraw(node, \"dot\", color, 1);\n };\n /**\n * Draw the given point with the specified (CSS-) color and radius 3.\n *\n * @method point\n * @param {XYCoords} p - The position to draw the point at.\n * @param {string} color - The CSS color to draw the point with.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.point = function (p, color) {\n var radius = 3;\n var node = this.makeNode(\"circle\");\n node.setAttribute(\"cx\", \"\".concat(this._x(p.x)));\n node.setAttribute(\"cy\", \"\".concat(this._y(p.y)));\n node.setAttribute(\"r\", \"\".concat(radius));\n return this._bindFillDraw(node, \"point\", color, 1);\n };\n /**\n * Draw a circle with the specified (CSS-) color and radius.<br>\n * <br>\n * Note that if the x- and y- scales are different the result will be an ellipse rather than a circle.\n *\n * @method circle\n * @param {XYCoords} center - The center of the circle.\n * @param {number} radius - The radius of the circle.\n * @param {string} color - The CSS color to draw the circle with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.circle = function (center, radius, color, lineWidth, strokeOptions) {\n // Todo: draw ellipse when scalex!=scaley\n var node = this.makeNode(\"circle\");\n this.applyStrokeOpts(node, strokeOptions);\n node.setAttribute(\"cx\", \"\".concat(this._x(center.x)));\n node.setAttribute(\"cy\", \"\".concat(this._y(center.y)));\n node.setAttribute(\"r\", \"\".concat(radius * this.scale.x)); // y?\n return this._bindFillDraw(node, \"circle\", color, lineWidth || 1);\n };\n /**\n * Draw a circular arc (section of a circle) with the given CSS color.\n *\n * @method circleArc\n * @param {XYCoords} center - The center of the circle.\n * @param {number} radius - The radius of the circle.\n * @param {number} startAngle - The angle to start at.\n * @param {number} endAngle - The angle to end at.\n * @param {string} color - The CSS color to draw the circle with.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.circleArc = function (center, radius, startAngle, endAngle, color, lineWidth, strokeOptions) {\n var node = this.makeNode(\"path\");\n this.applyStrokeOpts(node, strokeOptions);\n var arcData = CircleSector_1.CircleSector.circleSectorUtils.describeSVGArc(this._x(center.x), this._y(center.y), radius * this.scale.x, // y?\n startAngle, endAngle);\n node.setAttribute(\"d\", arcData.join(\" \"));\n return this._bindFillDraw(node, \"circleArc\", color, lineWidth || 1);\n };\n /**\n * Draw an ellipse with the specified (CSS-) color and thw two radii.\n *\n * @method ellipse\n * @param {XYCoords} center - The center of the ellipse.\n * @param {number} radiusX - The radius of the ellipse.\n * @param {number} radiusY - The radius of the ellipse.\n * @param {string} color - The CSS color to draw the ellipse with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {number=} rotation - (optional, default=0) The rotation of the ellipse.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.ellipse = function (center, radiusX, radiusY, color, lineWidth, rotation, strokeOptions) {\n if (typeof rotation === \"undefined\") {\n rotation = 0.0;\n }\n var node = this.makeNode(\"ellipse\");\n this.applyStrokeOpts(node, strokeOptions);\n node.setAttribute(\"cx\", \"\".concat(this._x(center.x)));\n node.setAttribute(\"cy\", \"\".concat(this._y(center.y)));\n node.setAttribute(\"rx\", \"\".concat(radiusX * this.scale.x));\n node.setAttribute(\"ry\", \"\".concat(radiusY * this.scale.y));\n // node.setAttribute( 'style', `transform: rotate(${rotation} ${center.x} ${center.y})` );\n node.setAttribute(\"transform\", \"rotate(\".concat((rotation * 180) / Math.PI, \" \").concat(this._x(center.x), \" \").concat(this._y(center.y), \")\"));\n return this._bindFillDraw(node, \"ellipse\", color, lineWidth || 1);\n };\n /**\n * Draw square at the given center, size and with the specified (CSS-) color.<br>\n * <br>\n * Note that if the x-scale and the y-scale are different the result will be a rectangle rather than a square.\n *\n * @method square\n * @param {XYCoords} center - The center of the square.\n * @param {number} size - The size of the square.\n * @param {string} color - The CSS color to draw the square with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {SVGElement}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.square = function (center, size, color, lineWidth, strokeOptions) {\n var node = this.makeNode(\"rectangle\");\n this.applyStrokeOpts(node, strokeOptions);\n node.setAttribute(\"x\", \"\".concat(this._x(center.x - size / 2.0)));\n node.setAttribute(\"y\", \"\".concat(this._y(center.y - size / 2.0)));\n node.setAttribute(\"width\", \"\".concat(size * this.scale.x));\n node.setAttribute(\"height\", \"\".concat(size * this.scale.y));\n return this._bindFillDraw(node, \"square\", color, lineWidth || 1);\n };\n /**\n * Draw a rectangle.\n *\n * @param {XYCoords} position - The upper left corner of the rectangle.\n * @param {number} width - The width of the rectangle.\n * @param {number} height - The height of the rectangle.\n * @param {string} color - The color to use.\n * @param {number=1} lineWidth - (optional) The line with to use (default is 1).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {SVGElement}\n * @instance\n * @memberof drawutilssvg\n **/\n drawutilssvg.prototype.rect = function (position, width, height, color, lineWidth, strokeOptions) {\n var node = this.makeNode(\"rect\");\n this.applyStrokeOpts(node, strokeOptions);\n node.setAttribute(\"x\", \"\".concat(this._x(position.x)));\n node.setAttribute(\"y\", \"\".concat(this._y(position.y)));\n node.setAttribute(\"width\", \"\".concat(width * this.scale.x));\n node.setAttribute(\"height\", \"\".concat(height * this.scale.y));\n return this._bindFillDraw(node, \"rect\", color, lineWidth || 1);\n };\n /**\n * Draw a rectangle at the given bounds; and with the specified line width and (CSS-) color.<br>\n *\n * @method bounds\n * @param {IBounds} bounds - The bounds rectangle to be drawn.\n * @param {string} color - The CSS color to draw the rectangle with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {R}\n * @instance\n * @memberof DrawLib\n */\n drawutilssvg.prototype.bounds = function (bounds, color, lineWidth, strokeOptions) {\n this.rect(bounds.min, bounds.max.x - bounds.min.x, bounds.max.y - bounds.min.y, color, lineWidth, strokeOptions);\n };\n /**\n * Draw a grid of horizontal and vertical lines with the given (CSS-) color.\n *\n * @method grid\n * @param {XYCoords} center - The center of the grid.\n * @param {number} width - The total width of the grid (width/2 each to the left and to the right).\n * @param {number} height - The total height of the grid (height/2 each to the top and to the bottom).\n * @param {number} sizeX - The horizontal grid size.\n * @param {number} sizeY - The vertical grid size.\n * @param {string} color - The CSS color to draw the grid with.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.grid = function (center, width, height, sizeX, sizeY, color) {\n // console.log(\"grid\");\n // const node: SVGElement = this.makeNode(\"pattern\");\n // var patternId = \"pattern_id_\" + Math.floor(Math.random() * 65365);\n // node.setAttribute(\"id\", patternId);\n // node.setAttribute(\"viewBox\", `0,0,${sizeX},${sizeY}`);\n // node.setAttribute(\"width\", `${sizeX}`);\n // node.setAttribute(\"height\", `${sizeX}`);\n // var pattern: SVGElement = this.makeNode(\"path\");\n // const d: SVGPathParams = [];\n // d.push(\"M\", sizeX / 2.0, 0);\n // d.push(\"L\", sizeX / 2.0, sizeY);\n // d.push(\"M\", 0, sizeY / 2.0);\n // d.push(\"L\", sizeX, sizeY / 2.0);\n // node.setAttribute(\"d\", d.join(\" \"));\n // this.bufferedNodeDefs.append(pattern);\n // const fillNode: SVGElement = this.makeNode(\"rect\");\n // // For some strange reason SVG rotation transforms use degrees instead of radians\n // // Note that the background does not scale with the zoom level (always covers full element)\n // fillNode.setAttribute(\"x\", \"0\");\n // fillNode.setAttribute(\"y\", \"0\");\n // fillNode.setAttribute(\"width\", `${this.canvasSize.width}`);\n // fillNode.setAttribute(\"height\", `${this.canvasSize.height}`);\n // fillNode.setAttribute(\"fill\", `url(#${patternId})`);\n // return this._bindFillDraw(fillNode, \"grid\", \"red\", 1);\n var node = this.makeNode(\"path\");\n var d = [];\n var yMin = -Math.ceil((height * 0.5) / sizeY) * sizeY;\n var yMax = height / 2;\n for (var x = -Math.ceil((width * 0.5) / sizeX) * sizeX; x < width / 2; x += sizeX) {\n d.push(\"M\", this._x(center.x + x), this._y(center.y + yMin));\n d.push(\"L\", this._x(center.x + x), this._y(center.y + yMax));\n }\n var xMin = -Math.ceil((width * 0.5) / sizeX) * sizeX;\n var xMax = width / 2;\n for (var y = -Math.ceil((height * 0.5) / sizeY) * sizeY; y < height / 2; y += sizeY) {\n d.push(\"M\", this._x(center.x + xMin), this._y(center.y + y));\n d.push(\"L\", this._x(center.x + xMax), this._y(center.y + y));\n }\n node.setAttribute(\"d\", d.join(\" \"));\n return this._bindFillDraw(node, \"grid\", color, 1);\n };\n /**\n * Draw a raster of crosshairs in the given grid.<br>\n *\n * This works analogue to the grid() function\n *\n * @method raster\n * @param {XYCoords} center - The center of the raster.\n * @param {number} width - The total width of the raster (width/2 each to the left and to the right).\n * @param {number} height - The total height of the raster (height/2 each to the top and to the bottom).\n * @param {number} sizeX - The horizontal raster size.\n * @param {number} sizeY - The vertical raster size.\n * @param {string} color - The CSS color to draw the raster with.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.raster = function (center, width, height, sizeX, sizeY, color) {\n var node = this.makeNode(\"path\");\n var d = [];\n for (var x = -Math.ceil((width * 0.5) / sizeX) * sizeX; x < width / 2; x += sizeX) {\n for (var y = -Math.ceil((height * 0.5) / sizeY) * sizeY; y < height / 2; y += sizeY) {\n // Draw a crosshair\n d.push(\"M\", this._x(center.x + x) - 4, this._y(center.y + y));\n d.push(\"L\", this._x(center.x + x) + 4, this._y(center.y + y));\n d.push(\"M\", this._x(center.x + x), this._y(center.y + y) - 4);\n d.push(\"L\", this._x(center.x + x), this._y(center.y + y) + 4);\n }\n }\n node.setAttribute(\"d\", d.join(\" \"));\n return this._bindFillDraw(node, \"raster\", color, 1);\n };\n /**\n * Draw a diamond handle (square rotated by 45°) with the given CSS color.\n *\n * It is an inherent featur of the handle functions that the drawn elements are not scaled and not\n * distorted. So even if the user zooms in or changes the aspect ratio, the handles will be drawn\n * as even shaped diamonds.\n *\n * @method diamondHandle\n * @param {XYCoords} center - The center of the diamond.\n * @param {number} size - The x/y-size of the diamond.\n * @param {string} color - The CSS color to draw the diamond with.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.diamondHandle = function (center, size, color) {\n var node = this.makeNode(\"path\");\n var d = [\n \"M\",\n this._x(center.x) - size / 2.0,\n this._y(center.y),\n \"L\",\n this._x(center.x),\n this._y(center.y) - size / 2.0,\n \"L\",\n this._x(center.x) + size / 2.0,\n this._y(center.y),\n \"L\",\n this._x(center.x),\n this._y(center.y) + size / 2.0,\n \"Z\"\n ];\n node.setAttribute(\"d\", d.join(\" \"));\n return this._bindFillDraw(node, \"diamondHandle\", color, 1);\n };\n /**\n * Draw a square handle with the given CSS color.<br>\n * <br>\n * It is an inherent featur of the handle functions that the drawn elements are not scaled and not\n * distorted. So even if the user zooms in or changes the aspect ratio, the handles will be drawn\n * as even shaped squares.\n *\n * @method squareHandle\n * @param {XYCoords} center - The center of the square.\n * @param {XYCoords} size - The x/y-size of the square.\n * @param {string} color - The CSS color to draw the square with.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.squareHandle = function (center, size, color) {\n var node = this.makeNode(\"rect\");\n node.setAttribute(\"x\", \"\".concat(this._x(center.x) - size / 2.0));\n node.setAttribute(\"y\", \"\".concat(this._y(center.y) - size / 2.0));\n node.setAttribute(\"width\", \"\".concat(size));\n node.setAttribute(\"height\", \"\".concat(size));\n return this._bindFillDraw(node, \"squareHandle\", color, 1);\n };\n /**\n * Draw a circle handle with the given CSS color.<br>\n * <br>\n * It is an inherent featur of the handle functions that the drawn elements are not scaled and not\n * distorted. So even if the user zooms in or changes the aspect ratio, the handles will be drawn\n * as even shaped circles.\n *\n * @method circleHandle\n * @param {XYCoords} center - The center of the circle.\n * @param {number} radius - The radius of the circle.\n * @param {string} color - The CSS color to draw the circle with.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.circleHandle = function (center, radius, color) {\n radius = radius || 3;\n var node = this.makeNode(\"circle\");\n node.setAttribute(\"cx\", \"\".concat(this._x(center.x)));\n node.setAttribute(\"cy\", \"\".concat(this._y(center.y)));\n node.setAttribute(\"r\", \"\".concat(radius));\n return this._bindFillDraw(node, \"circleHandle\", color, 1);\n };\n /**\n * Draw a crosshair with given radius and color at the given position.<br>\n * <br>\n * Note that the crosshair radius will not be affected by scaling.\n *\n * @method crosshair\n * @param {XYCoords} center - The center of the crosshair.\n * @param {number} radius - The radius of the crosshair.\n * @param {string} color - The CSS color to draw the crosshair with.\n * @param {number=0.5} lineWidth - (optional, default=0.5) The line width to use.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.crosshair = function (center, radius, color, lineWidth) {\n var node = this.makeNode(\"path\");\n var d = [\n \"M\",\n this._x(center.x) - radius,\n this._y(center.y),\n \"L\",\n this._x(center.x) + radius,\n this._y(center.y),\n \"M\",\n this._x(center.x),\n this._y(center.y) - radius,\n \"L\",\n this._x(center.x),\n this._y(center.y) + radius\n ];\n node.setAttribute(\"d\", d.join(\" \"));\n return this._bindFillDraw(node, \"crosshair\", color, lineWidth || 0.5);\n };\n /**\n * Draw a cross with diagonal axes with given radius, color and lineWidth at the given position.<br>\n * <br>\n * Note that the x's radius will not be affected by scaling.\n *\n * @method crosshair\n * @param {XYCoords} center - The center of the crosshair.\n * @param {number} radius - The radius of the crosshair.\n * @param {string} color - The CSS color to draw the crosshair with.\n * @param {number=1} lineWidth - (optional, default=1.0) The line width to use.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilssvg.prototype.cross = function (center, radius, color, lineWidth) {\n var node = this.makeNode(\"path\");\n var d = [\n \"M\",\n this._x(center.x) - radius,\n this._y(center.y) - radius,\n \"L\",\n this._x(center.x) + radius,\n this._y(center.y) + radius,\n \"M\",\n this._x(center.x) - radius,\n this._y(center.y) + radius,\n \"L\",\n this._x(center.x) + radius,\n this._y(center.y) - radius\n ];\n node.setAttribute(\"d\", d.join(\" \"));\n return this._bindFillDraw(node, \"cross\", color, lineWidth || 1.0);\n };\n /**\n * Draw a polygon.\n *\n * @method polygon\n * @param {Polygon} polygon - The polygon to draw.\n * @param {string} color - The CSS color to draw the polygon with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.polygon = function (polygon, color, lineWidth, strokeOptions) {\n return this.polyline(polygon.vertices, polygon.isOpen, color, lineWidth, strokeOptions);\n };\n /**\n * Draw a polygon line (alternative function to the polygon).\n *\n * @method polyline\n * @param {XYCoords[]} vertices - The polygon vertices to draw.\n * @param {boolan} isOpen - If true the polyline will not be closed at its end.\n * @param {string} color - The CSS color to draw the polygon with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.polyline = function (vertices, isOpen, color, lineWidth, strokeOptions) {\n var node = this.makeNode(\"path\");\n this.applyStrokeOpts(node, strokeOptions);\n if (vertices.length == 0) {\n return node;\n }\n // Draw curve\n var d = [\"M\", this._x(vertices[0].x), this._y(vertices[0].y)];\n var n = vertices.length;\n for (var i = 1; i < n; i++) {\n d.push(\"L\", this._x(vertices[i].x), this._y(vertices[i].y));\n }\n if (!isOpen)\n d.push(\"Z\");\n node.setAttribute(\"d\", d.join(\" \"));\n return this._bindFillDraw(node, \"polygon\", color, lineWidth || 1);\n };\n /**\n * Draw a text at the given relative position.\n *\n * @method text\n * @param {string} text - The text to draw.\n * @param {number} x - The x-position to draw the text at.\n * @param {number} y - The y-position to draw the text at.\n * @param {string=} options.color - The Color to use.\n * @param {string=} options.fontFamily - The font family to use.\n * @param {number=} options.fontSize - The font size (in pixels) to use.\n * @param {FontStyle=} options.fontStyle - The font style to use.\n * @param {FontWeight=} options.fontWeight - The font weight to use.\n * @param {number=} options.lineHeight - The line height (in pixels) to use.\n * @param {number=} options.rotation - The (optional) rotation in radians.\n * @param {string=} options.textAlign - The text align to use. According to the specifiactions (https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign) valid values are `\"left\" || \"right\" || \"center\" || \"start\" || \"end\"`.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilssvg.prototype.text = function (text, x, y, options) {\n var _a, _b, _c;\n options = options || {};\n var color = options.color || \"black\";\n var lineHeight = ((_b = (_a = options.lineHeight) !== null && _a !== void 0 ? _a : options.fontSize) !== null && _b !== void 0 ? _b : 0) * this.scale.x;\n // https://www.w3.org/TR/SVG/text.html#TextAnchorProperty\n // start | middle | end\n var textAlign = options.textAlign === \"left\" || options.textAlign === \"start\"\n ? \"start\"\n : options.textAlign === \"center\"\n ? \"middle\"\n : options.textAlign === \"right\" || options.textAlign === \"end\"\n ? \"end\"\n : \"start\";\n var transformOrigin = \"\".concat(this._x(x), \"px \").concat(this._y(y), \"px\");\n var translate = \"translate(\".concat(this._x(x), \" \").concat(this._y(y) + lineHeight / 2, \")\");\n // Safari has a transform-origin/rotation bug.\n // It's essential to use rotate(r,x,y) here. \"rotate(r)\"\" with transform-origin(x,y) won't do the job.\n // And rotate and translate cannot be used is combination on a text object.\n // So wrap the text inside a <g>, translate the <g>, and rotate the text inside.\n var rotate = options.rotation ? \"rotate(\".concat(options.rotation * RAD_TO_DEG, \" 0 0)\") : \"\";\n var node = this.makeNode(\"g\");\n var curId = this.curId;\n this.curId = curId + \"_text\";\n var textNode = this.makeNode(\"text\");\n node.appendChild(textNode);\n textNode.setAttribute(\"font-family\", (_c = options.fontFamily) !== null && _c !== void 0 ? _c : \"\"); // May be undefined\n textNode.setAttribute(\"font-size\", options.fontSize ? \"\".concat(options.fontSize * this.scale.x) : \"\");\n textNode.setAttribute(\"font-style\", options.fontStyle ? \"\".concat(options.fontStyle) : \"\");\n textNode.setAttribute(\"font-weight\", options.fontWeight ? \"\".concat(options.fontWeight) : \"\");\n textNode.setAttribute(\"text-anchor\", textAlign);\n textNode.setAttribute(\"transform-origin\", \"0 0\");\n textNode.setAttribute(\"transform\", rotate);\n node.setAttribute(\"transform-origin\", transformOrigin);\n node.setAttribute(\"transform\", translate);\n textNode.innerHTML = text;\n // Restore old ID\n this.curId = curId;\n return this._bindFillDraw(node, \"text\", color, 1);\n };\n /**\n * Draw a non-scaling text label at the given position.\n *\n * @method label\n * @param {string} text - The text to draw.\n * @param {number} x - The x-position to draw the text at.\n * @param {number} y - The y-position to draw the text at.\n * @param {number=} rotation - The (optional) rotation in radians.\n * @param {string=\"black\"} color - The color to use (default is black).\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.label = function (text, x, y, rotation, color) {\n var node = this.makeNode(\"text\");\n // For some strange reason SVG rotation transforms use degrees instead of radians\n node.setAttribute(\"transform\", \"translate(\".concat(x, \",\").concat(y, \"), rotate(\").concat(((rotation || 0) / Math.PI) * 180, \")\"));\n node.setAttribute(\"font-family\", \"Arial\");\n node.setAttribute(\"font-size\", \"9pt\");\n node.setAttribute(\"font-style\", \"normal\");\n node.setAttribute(\"font-weight\", \"lighter\");\n node.innerHTML = text;\n return this._bindFillDraw(node, \"label\", color || \"black\", null);\n };\n /**\n * Draw an SVG-like path given by the specified path data.\n *\n * @method path\n * @param {SVGPathData} pathData - An array of path commands and params.\n * @param {string=null} color - (optional) The color to draw this path with (default is null).\n * @param {number=1} lineWidth - (optional) the line width to use (default is 1).\n * @param {boolean=false} options.inplace - (optional) If set to true then path transforamtions (scale and translate) will be done in-place in the array. This can boost the performance.\n * @param {number=} options.dashOffset - (optional) `See StrokeOptions`.\n * @param {number=[]} options.dashArray - (optional) `See StrokeOptions`.\n *\n * @instance\n * @memberof drawutils\n * @return {R} An instance representing the drawn path.\n */\n drawutilssvg.prototype.path = function (pathData, color, lineWidth, options) {\n var node = this.makeNode(\"path\");\n this.applyStrokeOpts(node, options);\n // Transform the path: in-place (fast) or copy (slower)\n var d = options && options.inplace ? pathData : drawutilssvg.copyPathData(pathData);\n drawutilssvg.transformPathData(d, this.offset, this.scale);\n node.setAttribute(\"d\", d.join(\" \"));\n return this._bindFillDraw(node, \"path\", color, lineWidth);\n };\n /**\n * Due to gl compatibility there is a generic 'clear' function required\n * to avoid accessing the context object itself directly.\n *\n * This function just fills the whole canvas with a single color.\n *\n * @param {string} color - The color to clear with.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n **/\n drawutilssvg.prototype.clear = function (color) {\n // If this isn't the primary handler then do not remove anything here.\n // The primary handler will do that (no double work).\n if (this.isSecondary) {\n return;\n }\n // Add a covering rect with the given background color\n this.curId = \"background\";\n this.curClassName = null; // undefined;\n var node = this.makeNode(\"rect\");\n // For some strange reason SVG rotation transforms use degrees instead of radians\n // Note that the background does not scale with the zoom level (always covers full element)\n node.setAttribute(\"x\", \"0\");\n node.setAttribute(\"y\", \"0\");\n node.setAttribute(\"width\", \"\".concat(this.canvasSize.width));\n node.setAttribute(\"height\", \"\".concat(this.canvasSize.height));\n // Bind this special element into the document\n this._bindFillDraw(node, this.curId, null, null);\n node.setAttribute(\"fill\", typeof color === \"undefined\" ? \"none\" : color);\n // Clear the current ID again\n this.curId = null; // undefined;\n };\n /**\n * A private helper function to clear all SVG nodes from the &gt;g> node.\n *\n * @private\n */\n drawutilssvg.prototype.removeAllChildNodes = function () {\n while (this.bufferGNode.lastChild) {\n this.bufferGNode.removeChild(this.bufferGNode.lastChild);\n }\n while (this.bufferedNodeDefs.lastChild) {\n this.bufferedNodeDefs.removeChild(this.bufferedNodeDefs.lastChild);\n }\n };\n /**\n * Create a new and empty `SVGElement` &lt;svg&gt; in the svg-namespace.\n *\n * @name createSvg\n * @static\n * @memberof drawutilssvg\n * @return SVGElement\n */\n drawutilssvg.createSvg = function () {\n return document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n };\n /**\n * Create a copy of the given path data. As path data only consists of strings and numbers,\n * the copy will be shallow by definition.\n *\n * @name copyPathData\n * @static\n * @memberof drawutilssvg\n */\n drawutilssvg.copyPathData = function (data) {\n // To create a shallow copy we can just use the `slice` method.\n return data.slice();\n };\n /**\n * Transform the given path data (translate and scale. rotating is not intended here).\n *\n * @name transformPathData\n * @static\n * @memberof drawutilssvg\n * @param {SVGPathParams} data - The data to transform.\n * @param {XYCoords} offset - The translation offset (neutral is x=0, y=0).\n * @param {XYCoords} scale - The scale factors (neutral is x=1, y=1).\n */\n drawutilssvg.transformPathData = function (data, offset, scale) {\n // Scale and translate {x,y}\n var _stx = function (index) {\n data[index] = offset.x + scale.x * Number(data[index]);\n };\n var _sty = function (index) {\n data[index] = offset.y + scale.y * Number(data[index]);\n };\n // scale only {x,y}\n var _sx = function (index) {\n data[index] = scale.x * Number(data[index]);\n };\n var _sy = function (index) {\n data[index] = scale.y * Number(data[index]);\n };\n var i = 0;\n var lastPoint = { x: NaN, y: NaN };\n // \"save last point\"\n var _slp = function (index) {\n lastPoint.x = Number(data[index]);\n lastPoint.y = Number(data[index + 1]);\n };\n while (i < data.length) {\n var cmd = data[i];\n switch (cmd) {\n case \"M\":\n // MoveTo: M|m x y\n case \"L\":\n // LineTo L|l x y\n case \"T\":\n // Shorthand/smooth quadratic Bézier curveto: T|t x y\n _stx(i + 1);\n _sty(i + 2);\n _slp(i + 1);\n i += 3;\n break;\n case \"m\":\n // MoveTo: M|m x y\n case \"l\":\n // LineTo L|l x y\n case \"t\":\n // Shorthand/smooth quadratic Bézier curveto: T|t x y\n _sx(i + 1);\n _sy(i + 2);\n _slp(i + 1);\n i += 3;\n break;\n case \"H\":\n // HorizontalLineTo: H|h x\n _stx(i + 1);\n lastPoint.x = Number(data[i + 1]);\n i += 2;\n break;\n case \"h\":\n // HorizontalLineTo: H|h x\n _sx(i + 1);\n lastPoint.x = Number(data[i + 1]);\n i += 2;\n break;\n case \"V\":\n // VerticalLineTo: V|v y\n _sty(i + 1);\n lastPoint.y = Number(data[i + 1]);\n i += 2;\n break;\n case \"v\":\n // VerticalLineTo: V|v y\n _sy(i + 1);\n lastPoint.y = Number(data[i + 1]);\n i += 2;\n break;\n case \"C\":\n // CurveTo: C|c x1 y1 x2 y2 x y\n _stx(i + 1);\n _sty(i + 2);\n _stx(i + 3);\n _sty(i + 4);\n _stx(i + 5);\n _sty(i + 6);\n _slp(i + 5);\n i += 7;\n break;\n case \"c\":\n // CurveTo: C|c x1 y1 x2 y2 x y\n _sx(i + 1);\n _sy(i + 2);\n _sx(i + 3);\n _sy(i + 4);\n _sx(i + 5);\n _sy(i + 6);\n _slp(i + 5);\n i += 7;\n break;\n case \"S\":\n case \"Q\":\n // Shorthand-/SmoothCurveTo: S|s x2 y2 x y\n // QuadraticCurveTo: Q|q x1 y1 x y\n _stx(i + 1);\n _sty(i + 2);\n _stx(i + 3);\n _sty(i + 4);\n _slp(i + 3);\n i += 5;\n break;\n case \"s\":\n case \"q\":\n // Shorthand-/SmoothCurveTo: S|s x2 y2 x y\n // QuadraticCurveTo: Q|q x1 y1 x y\n _sx(i + 1);\n _sy(i + 2);\n _sx(i + 3);\n _sy(i + 4);\n _slp(i + 3);\n i += 5;\n break;\n case \"A\":\n // EllipticalArcTo: A|a rx ry x-axis-rotation large-arc-flag sweep-flag x y\n // Uniform scale: just scale\n // NOTE: here is something TODO\n // * if scalex!=scaleY this won't work\n // * Arcs have to be converted to Bézier curves here in that case\n _sx(i + 1);\n _sy(i + 2);\n _stx(i + 6);\n _sty(i + 7);\n _slp(i + 6);\n // Update the arc flag when x _or_ y scale is negative\n if ((scale.x < 0 && scale.y >= 0) || (scale.x >= 0 && scale.y < 0)) {\n data[i + 5] = data[i + 5] ? 0 : 1;\n }\n i += 8;\n break;\n case \"a\":\n // EllipticalArcTo: A|a rx ry x-axis-rotation large-arc-flag sweep-flag x y\n _sx(i + 1);\n _sy(i + 2);\n _sx(i + 6);\n _sy(i + 7);\n _slp(i + 6);\n i += 8;\n break;\n case \"z\":\n case \"Z\":\n // ClosePath: Z|z (no arguments)\n // lastPoint.x = firstPoint.x;\n // lastPoint.y = firstPoint.y;\n i++;\n break;\n // Safepoint: continue reading token by token until something is recognized again\n default:\n i++;\n }\n } // END while\n }; // END transformPathData\n drawutilssvg.nodeSupportsLineDash = function (nodeName) {\n return [\"line\", \"path\", \"circle\", \"ellipse\", \"rectangle\", \"rect\"].includes(nodeName);\n };\n drawutilssvg.nodeSupportsLineJoin = function (nodeName) {\n return [\"line\", \"path\", \"circle\", \"ellipse\", \"rectangle\", \"rect\"].includes(nodeName);\n };\n drawutilssvg.nodeSupportsLineCap = function (nodeName) {\n return [\"line\", \"path\", \"circle\", \"ellipse\", \"rectangle\", \"rect\"].includes(nodeName);\n };\n /**\n * Creates a basic <line> node with start and end coordinates. The created node will not\n * be bound to any root node.\n *\n * @private\n * @method makeLineNode\n * @param {XYCoords} zA - The line's start position.\n * @param {XYCoords} zB - The line's start position.\n * @param {string} color - The CSS color to draw the point with.\n * @param {number=1} lineWidth - (optional) The line width to use.\n * @param {StrokeOptions=} strokeOptions - (optional) Additional stroke options to use.\n * @param {string=} classNameOverride - (optional) If nothing is passed the default classname 'path' will be used.\n * @return {SVGLineElement}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.makeLineNode = function (zA, zB, color, lineWidth, strokeOptions, classNameOverride) {\n var line = this.makeNode(\"line\");\n line.setAttribute(\"x1\", \"\".concat(this._x(zA.x)));\n line.setAttribute(\"y1\", \"\".concat(this._y(zA.y)));\n line.setAttribute(\"x2\", \"\".concat(this._x(zB.x)));\n line.setAttribute(\"y2\", \"\".concat(this._y(zB.y)));\n this._configureNode(line, classNameOverride !== null && classNameOverride !== void 0 ? classNameOverride : \"line\", this.fillShapes, color, lineWidth || 1, strokeOptions);\n return line;\n };\n /**\n * Creates a basic <path> node with given path string data. The created node will not\n * be bound to any root node.\n *\n * @private\n * @method makePathNode\n * @param {string} pathString - The path data (must be a valid path data string).\n * @param {string} color - The CSS color to draw the point with.\n * @param {number=1} lineWidth - (optional) The line width to use.\n * @param {StrokeOptions=} strokeOptions - (optional) Additional stroke options to use.\n * @param {string=} classNameOverride - (optional) If nothing is passed the default classname 'path' will be used.\n * @return {SVGPathElement}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.makePathNode = function (pathString, color, lineWidth, strokeOptions, classNameOverride) {\n var path = this.makeNode(\"path\");\n path.setAttribute(\"d\", pathString);\n this._configureNode(path, classNameOverride !== null && classNameOverride !== void 0 ? classNameOverride : \"path\", this.fillShapes, color, lineWidth || 1, strokeOptions);\n return path;\n };\n /**\n * Creates a basic arrow head node (<path> node) at the end of the given line coordinates. The created node will not\n * be bound to any root node.\n *\n * @private\n * @method makeArrowHeadNode\n * @param {string} pathString - The path data (must be a valid path data string).\n * @param {string} color - The CSS color to draw the point with.\n * @param {number=1} lineWidth - (optional) The line width to use.\n * @param {number=8} headLength - (optional) The length of the arrow head; if none is specified then the head will be 8 absolute units long.\n * @param {StrokeOptions=} strokeOptions - (optional) Additional stroke options to use.\n * @param {XYCoords=} arrowHeadBasePositionBuffer - (optional) If not null, then this position will contain the arrow head's start point (after execution). Some sort of OUT variable.\n * @return {SVGPathElement}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.makeArrowHeadNode = function (zA, zB, color, lineWidth, headLength, strokeOptions, arrowHeadBasePositionBuffer) {\n if (headLength === void 0) { headLength = 8; }\n var vertices = Vector_1.Vector.utils.buildArrowHead(zA, zB, headLength, this.scale.x, this.scale.y);\n var d = [\"M\", this.offset.x + vertices[0].x, this.offset.y + vertices[0].y];\n if (arrowHeadBasePositionBuffer) {\n arrowHeadBasePositionBuffer.x = vertices[0].x / this.scale.x;\n arrowHeadBasePositionBuffer.y = vertices[0].y / this.scale.y;\n }\n for (var i = 1; i <= vertices.length; i++) {\n d.push(\"L\");\n // Note: only use offset here (the vertices are already scaled)\n d.push(this.offset.x + vertices[i % vertices.length].x);\n d.push(this.offset.y + vertices[i % vertices.length].y);\n }\n var node = this.makePathNode(d.join(\" \"), color, lineWidth, strokeOptions, \"arrowhead\");\n return node;\n };\n /**\n * Creates a basic cubic Bézier path node (<path> node) with the given cubic Bézier data. The created node will not\n * be bound to any root node.\n *\n * @private\n * @method makeCubicBezierNode\n * @param {XYCoords} startPoint - The start point of the cubic Bézier curve\n * @param {XYCoords} endPoint - The end point the cubic Bézier curve.\n * @param {XYCoords} startControlPoint - The start control point the cubic Bézier curve.\n * @param {XYCoords} endControlPoint - The end control point the cubic Bézier curve.\n * @param {string} color - The CSS color to draw the point with.\n * @param {number=1} lineWidth - (optional) The line width to use.\n * @param {StrokeOptions=} strokeOptions - (optional) Additional stroke options to use.\n * @param {string=} classNameOverride - (optional) If nothing is passed the default classname 'path' will be used.\n * @param {XYCoords=} arrowHeadBasePositionBuffer - (optional) If not null, then this position will contain the arrow head's start point (after execution). Some sort of OUT variable.\n * @return {SVGPathElement}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.makeCubicBezierNode = function (startPoint, endPoint, startControlPoint, endControlPoint, color, lineWidth, strokeOptions) {\n if (startPoint instanceof CubicBezierCurve_1.CubicBezierCurve) {\n return this.cubicBezier(startPoint.startPoint, startPoint.endPoint, startPoint.startControlPoint, startPoint.endControlPoint, color, lineWidth);\n }\n // Draw curve\n var d = [\n \"M\",\n this._x(startPoint.x),\n this._y(startPoint.y),\n \"C\",\n this._x(startControlPoint.x),\n this._y(startControlPoint.y),\n this._x(endControlPoint.x),\n this._y(endControlPoint.y),\n this._x(endPoint.x),\n this._y(endPoint.y)\n ];\n var node = this.makePathNode(d.join(\" \"), color, lineWidth, strokeOptions, \"cubicBezier\");\n return node;\n };\n drawutilssvg.HEAD_XML = [\n '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>',\n '<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" ',\n ' \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">',\n \"\"\n ].join(\"\\n\");\n return drawutilssvg;\n}());\nexports.drawutilssvg = drawutilssvg;\n//# sourceMappingURL=drawutilssvg.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2018-08-26\n * @modified 2018-11-17 Added the 'isSelected' attribute.\n * @modified 2018-11-27 Added the global model for instantiating with custom attributes.\n * @modified 2019-03-20 Added JSDoc tags.\n * @modified 2020-02-29 Added the 'selectable' attribute.\n * @modified 2020-03-23 Ported to Typescript from JS.\n * @modified 2024-03-10 Fixed some types for Typescript 5 compatibility.\n * @version 1.1.2\n *\n * @file VertexAttr\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.VertexAttr = void 0;\n/**\n * @classdesc The VertexAttr is a helper class to wrap together additional attributes\n * to vertices that do not belong to the 'standard canonical' vertex implementation.<br>\n * <br>\n * This is some sort of 'userData' object, but the constructor uses a global model\n * to obtain a (configurable) default attribute set to all instances.<br>\n */\nvar VertexAttr = /** @class */ (function () {\n /**\n * The constructor.\n *\n * Attributes will be initialized as defined in the model object\n * which serves as a singleton.\n *\n * @constructor\n * @name VertexAttr\n **/\n function VertexAttr() {\n this.draggable = true;\n this.selectable = true;\n this.isSelected = false;\n this.visible = true;\n for (var key in VertexAttr.model)\n this[key] = VertexAttr.model[key];\n }\n ;\n /**\n * This is the global attribute model. Set these object on the initialization\n * of your app to gain all VertexAttr instances have these attributes.\n *\n * @type {object}\n **/\n VertexAttr.model = {\n draggable: true,\n selectable: true,\n isSelected: false,\n visible: true\n };\n return VertexAttr;\n}());\nexports.VertexAttr = VertexAttr;\n//# sourceMappingURL=VertexAttr.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2018-11-11 (Alaaf)\n * @modified 2020-03-28 Ported this class from vanilla-JS to Typescript.\n * @modified 2020-07-28 Changed the `delete` key code from 8 to 46.\n * @modified 2020-10-04 Changed `window` to `globalThis`.\n * @modified 2020-10-04 Added extended JSDoc.\n * @modified 2022-02-02 Added the `destroy` method.\n * @version 1.1.0\n *\n * @file KeyHandler\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.KeyHandler = void 0;\n/**\n * @classdesc A generic key handler.\n *\n * Example\n * =======\n * @example\n * // Javascript\n *\tnew KeyHandler( { trackAll : true } )\n *\t .down('enter',function() { console.log('ENTER was hit.'); } )\n *\t .press('enter',function() { console.log('ENTER was pressed.'); } )\n *\t .up('enter',function() { console.log('ENTER was released.'); } )\n *\n * .down('e',function() { console.log('e was hit. shift is pressed?',keyHandler.isDown('shift')); } )\n *\n *\t .up('windows',function() { console.log('windows was released.'); } )\n *\t;\n */\nvar KeyHandler = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @instance\n * @memberof KeyHandler\n * @param {HTMLElement} options.element (optional) The HTML element to listen on; if null then 'window' will be used.\n * @param {boolean} options.trackAll (optional) Set to true if you want to keep track of _all_ keys (keyStatus).\n **/\n function KeyHandler(options) {\n this.downListeners = [];\n this.pressListeners = [];\n this.upListeners = [];\n this.keyStates = {};\n options = options || {};\n this.element = options.element ? options.element : globalThis;\n this.downListeners = [];\n this.pressListeners = [];\n this.upListeners = [];\n this.keyStates = [];\n // This could be made configurable in a later version. It allows to\n // keep track of the key status no matter if there are any listeners\n // on the key or not.\n this.trackAllKeys = options.trackAll || false;\n // Install the listeners\n this.installListeners();\n }\n /**\n * A helper function to fire key events from this KeyHandler.\n *\n * @param {KeyboardEvent} event - The key event to fire.\n * @param {Array<XKeyListener>} listener - The listeners to fire to.\n */\n KeyHandler.prototype.fireEvent = function (event, listeners) {\n var hasListener = false;\n for (var i in listeners) {\n var lis = listeners[i];\n if (lis.keyCode != event.keyCode)\n continue;\n lis.listener(event);\n hasListener = true;\n }\n return hasListener;\n };\n /**\n * Internal function to fire a new keydown event to all listeners.\n * You should not call this function on your own unless you know what you do.\n *\n * @name fireDownEvent\n * @memberof KeyHandler\n * @instance\n * @private\n * @param {KeyboardEvent} e\n * @param {KeyHandler} handler\n * @return {void}\n */\n KeyHandler.prototype.fireDownEvent = function (e, handler) {\n if (handler.fireEvent(e, handler.downListeners) || handler.trackAllKeys) {\n // Down event has listeners. Update key state.\n handler.keyStates[e.keyCode] = \"down\";\n }\n };\n /**\n * Internal function to fire a new keypress event to all listeners.\n * You should not call this function on your own unless you know what you do.\n *\n * @name firePressEvent\n * @memberof KeyHandler\n * @instance\n * @private\n * @param {KeyboardEvent} e\n * @param {KeyHandler} handler\n * @return void\n */\n KeyHandler.prototype.firePressEvent = function (e, handler) {\n handler.fireEvent(e, handler.pressListeners);\n };\n /**\n * Internal function to fire a new keyup event to all listeners.\n * You should not call this function on your own unless you know what you do.\n *\n * @name fireUpEvent\n * @memberof KeyHandler\n * @instance\n * @private\n * @param {KeyboardEvent} e\n * @param {KeyHandler} handler\n * @return {void}\n */\n KeyHandler.prototype.fireUpEvent = function (e, handler) {\n if (handler.fireEvent(e, handler.upListeners) || handler.trackAllKeys) {\n // Up event has listeners. Clear key state.\n delete handler.keyStates[e.keyCode];\n }\n };\n /**\n * Resolve the key/name code.\n */\n KeyHandler.key2code = function (key) {\n if (typeof key == \"number\")\n return key;\n if (typeof key != \"string\")\n throw \"Unknown key name or key type (should be a string or integer): \" + key;\n if (KeyHandler.KEY_CODES[key])\n return KeyHandler.KEY_CODES[key];\n throw \"Unknown key (cannot resolve key code): \" + key;\n };\n /**\n * Install the required listeners into the initially passed element.\n *\n * By default the listeners are installed into the root element specified on\n * construction (or 'window').\n */\n KeyHandler.prototype.installListeners = function () {\n var _self = this;\n this.element.addEventListener(\"keydown\", (this._keyDownListener = function (e) {\n _self.fireDownEvent(e, _self);\n }));\n this.element.addEventListener(\"keypress\", (this._keyPressListener = function (e) {\n _self.firePressEvent(e, _self);\n }));\n this.element.addEventListener(\"keyup\", (this._keyUpListener = function (e) {\n _self.fireUpEvent(e, _self);\n }));\n };\n /**\n * Remove all installed event listeners from the underlying element.\n */\n KeyHandler.prototype.releaseListeners = function () {\n this.element.removeEventListener(\"keydown\", this._keyDownListener);\n this.element.removeEventListener(\"keypress\", this._keyPressListener);\n this.element.removeEventListener(\"keyup\", this._keyUpListener);\n };\n /**\n * Listen for key down. This function allows chaining.\n *\n * Example: new KeyHandler().down('enter',function() {console.log('Enter hit.')});\n *\n * @name down\n * @memberof KeyHandler\n * @instance\n * @param {string|number} key - Any key identifier, key code or one from the KEY_CODES list.\n * @param {(e:KeyboardEvent)=>void} e - The callback to be triggered.\n * @return {KeyHandler} this\n */\n KeyHandler.prototype.down = function (key, listener) {\n this.downListeners.push({ key: key, keyCode: KeyHandler.key2code(key), listener: listener });\n return this;\n };\n /**\n * Listen for key press.\n *\n * Example: new KeyHandler().press('enter',function() {console.log('Enter pressed.')});\n *\n * @name press\n * @memberof KeyHandler\n * @instance\n * @param {string|number} key - Any key identifier, key code or one from the KEY_CODES list.\n * @param {(e:KeyboardEvent)=>void} listener - The callback to be triggered.\n * @return {KeyHandler} this\n */\n KeyHandler.prototype.press = function (key, listener) {\n this.pressListeners.push({ key: key, keyCode: KeyHandler.key2code(key), listener: listener });\n return this;\n };\n /**\n * Listen for key up.\n *\n * Example: new KeyHandler().up('enter',function() {console.log('Enter released.')});\n *\n * @name up\n * @memberof KeyHandler\n * @instance\n * @param {string} key - Any key identifier, key code or one from the KEY_CODES list.\n * @param {(e:KeyboardEvent)=>void)} e - The callback to be triggered.\n * @return {KeyHandler} this\n */\n KeyHandler.prototype.up = function (key, listener) {\n this.upListeners.push({ key: key, keyCode: KeyHandler.key2code(key), listener: listener });\n return this;\n };\n /**\n * Check if a specific key is currently held pressed.\n *\n * @param {string|number} key - Any key identifier, key code or one from the KEY_CODES list.\n */\n KeyHandler.prototype.isDown = function (key) {\n if (typeof key == \"number\")\n return this.keyStates[key] ? true : false;\n else\n return this.keyStates[KeyHandler.key2code(key)] ? true : false;\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used any more.\n */\n KeyHandler.prototype.destroy = function () {\n this.releaseListeners();\n };\n /**\n * Source:\n * https://keycode.info/\n */\n // prettier-ignore\n KeyHandler.KEY_CODES = {\n 'break': 3, // alternate: 19\n 'backspace': 8,\n // 'delete'\t : 8, // alternate: 46\n 'tab': 9,\n 'clear': 12,\n 'enter': 13,\n 'shift': 16,\n 'ctrl': 17,\n 'alt': 18,\n 'pause': 19,\n // 'break'\t : 19,\n 'capslock': 20,\n 'hangul': 21,\n 'hanja': 25,\n 'escape': 27,\n 'conversion': 28,\n 'non-conversion': 29, // alternate: 235?\n 'spacebar': 32,\n 'pageup': 33,\n 'pagedown': 34,\n 'end': 35,\n 'home': 36, // alternate: 172?\n 'leftarrow': 37,\n 'uparrow': 38,\n 'rightarrow': 39,\n 'downarrow': 40,\n 'select': 41,\n 'print': 42,\n 'execute': 43,\n 'printscreen': 44,\n 'insert': 45,\n 'delete': 46, // alternate: 8\n 'help': 47,\n '0': 48,\n '1': 49,\n '2': 50,\n '3': 51,\n '4': 52,\n '5': 53,\n '6': 54,\n '7': 55,\n '8': 56,\n '9': 57,\n ':': 58,\n 'semicolon (firefox)': 59,\n 'equals': 59,\n '<': 60,\n 'equals (firefox)': 61,\n 'ß': 63,\n '@ (firefox)': 64,\n 'a': 65,\n 'b': 66,\n 'c': 67,\n 'd': 68,\n 'e': 69,\n 'f': 70,\n 'g': 71,\n 'h': 72,\n 'i': 73,\n 'j': 74,\n 'k': 75,\n 'l': 76,\n 'm': 77,\n 'n': 78,\n 'o': 79,\n 'p': 80,\n 'q': 81,\n 'r': 82,\n 's': 83,\n 't': 84,\n 'u': 85,\n 'v': 86,\n 'w': 87,\n 'x': 88,\n 'y': 89,\n 'z': 90,\n 'windows': 91,\n 'leftcommand': 91, // left ⌘\n 'chromebooksearch': 91,\n 'rightwindowkey': 92,\n 'windowsmenu': 93,\n 'rightcommant': 93, // right ⌘\n 'sleep': 95,\n 'numpad0': 96,\n 'numpad1': 97,\n 'numpad2': 98,\n 'numpad3': 99,\n 'numpad4': 100,\n 'numpad5': 101,\n 'numpad6': 102,\n 'numpad7': 103,\n 'numpad8': 104,\n 'numpad9': 105,\n 'multiply': 106,\n 'add': 107,\n 'numpadperiod': 108, // firefox, 194 on chrome\n 'subtract': 109,\n 'decimalpoint': 110,\n 'divide': 111,\n 'f1': 112,\n 'f2': 113,\n 'f3': 114,\n 'f4': 115,\n 'f5': 116,\n 'f6': 117,\n 'f7': 118,\n 'f8': 119,\n 'f9': 120,\n 'f10': 121,\n 'f11': 122,\n 'f12': 123,\n 'f13': 124,\n 'f14': 125,\n 'f15': 126,\n 'f16': 127,\n 'f17': 128,\n 'f18': 129,\n 'f19': 130,\n 'f20': 131,\n 'f21': 132,\n 'f22': 133,\n 'f23': 134,\n 'f24': 135,\n 'numlock': 144,\n 'scrolllock': 145,\n '^': 160,\n '!': 161,\n // '؛' \t : 162 // (arabic semicolon)\n '#': 163,\n '$': 164,\n 'ù': 165,\n 'pagebackward': 166,\n 'pageforward': 167,\n 'refresh': 168,\n 'closingparen': 169, // (AZERTY)\n '*': 170,\n '~+*': 171,\n // 'home'\t : 172,\n 'minus': 173, // firefox\n // 'mute' : 173,\n // 'unmute'\t : 173,\n 'decreasevolumelevel': 174,\n 'increasevolumelevel': 175,\n 'next': 176,\n 'previous': 177,\n 'stop': 178,\n 'play/pause': 179,\n 'email': 180,\n 'mute': 181, // firefox, alternate: 173\n 'unmute': 181, // alternate: 173?\n //'decreasevolumelevel'\t182 // firefox\n //'increasevolumelevel'\t183 // firefox\n 'semicolon': 186,\n 'ñ': 186,\n 'equal': 187,\n 'comma': 188,\n 'dash': 189,\n 'period': 190,\n 'forwardslash': 191,\n 'ç': 191, // 231 alternate?\n 'grave accent': 192,\n //'ñ' 192,\n 'æ': 192,\n 'ö': 192,\n '?': 193,\n '/': 193,\n '°': 193,\n // 'numpadperiod'\t : 194, // chrome\n 'openbracket': 219,\n 'backslash': 220,\n 'closebracket': 221,\n 'å': 221,\n 'singlequote': 222,\n 'ø': 222,\n 'ä': 222,\n '`': 223,\n // 'left or right ⌘ key (firefox)'\t224\n 'altgr': 225,\n // '< /git >, left back slash'\t226\n 'GNOME Compose Key': 230,\n 'XF86Forward': 233,\n 'XF86Back': 234,\n 'alphanumeric': 240,\n 'hiragana': 242,\n 'katakana': 242,\n 'half-width': 243,\n 'full-width': 243,\n 'kanji': 244,\n 'unlocktrackpad': 251, // Chrome/Edge\n 'toggletouchpad': 255\n };\n return KeyHandler;\n}());\nexports.KeyHandler = KeyHandler;\n//# sourceMappingURL=KeyHandler.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2018-10-23\n * @modified 2018-11-19 Added multi-select and multi-drag.\n * @modified 2018-12-04 Added basic SVG export.\n * @modified 2018-12-09 Extended the constructor (canvas).\n * @modified 2018-12-18 Added the config.redrawOnResize param.\n * @modified 2018-12-18 Added the config.defaultCanvas{Width,Height} params.\n * @modified 2018-12-19 Added CSS scaling.\n * @modified 2018-12-28 Removed the unused 'drawLabel' param. Added the 'enableMouse' and 'enableKeys' params.\n * @modified 2018-12-29 Added the 'drawOrigin' param.\n * @modified 2018-12-29 Renamed the 'autoCenterOffset' param to 'autoAdjustOffset'. Added the params 'offsetAdjustXPercent' and 'offsetAdjustYPercent'.\n * @modified 2019-01-14 Added params 'drawBezierHandleLines' and 'drawBezierHandlePoints'. Added the 'redraw' praam to the add() function.\n * @modified 2019-01-16 Added params 'drawHandleLines' and 'drawHandlePoints'. Added the new params to the dat.gui interface.\n * @modified 2019-01-30 Added the 'Vector' type (extending the Line class).\n * @modified 2019-01-30 Added the 'PBImage' type (a wrapper for images).\n * @modified 2019-02-02 Added the 'canvasWidthFactor' and 'canvasHeightFactor' params.\n * @modified 2019-02-03 Removed the drawBackgroundImage() function, with had no purpose at all. Just add an image to the drawables-list.\n * @modified 2019-02-06 Vertices (instace of Vertex) can now be added. Added the 'draggable' attribute to the vertex attributes.\n * @modified 2019-02-10 Fixed a draggable-bug in PBImage handling (scaling was not possible).\n * @modified 2019-02-10 Added the 'enableTouch' option (default is true).\n * @modified 2019-02-14 Added the console for debugging (setConsole(object)).\n * @modified 2019-02-19 Added two new constants: DEFAULT_CLICK_TOLERANCE and DEFAULT_TOUCH_TOLERANCE.\n * @modified 2019-02-19 Added the second param to the locatePointNear(Vertex,Number) function.\n * @modified 2019-02-20 Removed the 'loadFile' entry from the GUI as it was experimental and never in use.\n * @modified 2019-02-23 Removed the 'rebuild' function as it had no purpose.\n * @modified 2019-02-23 Added scaling of the click-/touch-tolerance with the CSS scale.\n * @modified 2019-03-23 Added JSDoc tags. Changed the default value of config.drawOrigin to false.\n * @modified 2019-04-03 Fixed the touch-drag position detection for canvas elements that are not located at document position (0,0).\n * @modified 2019-04-03 Tweaked the fit-to-parent function to work with paddings and borders.\n * @modified 2019-04-28 Added the preClear callback param (called before the canvas was cleared on redraw and before any elements are drawn).\n * @modified 2019-09-18 Added basics for WebGL support (strictly experimental).\n * @modified 2019-10-03 Added the .beginDrawCycle call in the redraw function.\n * @modified 2019-11-06 Added fetch.num, fetch.val, fetch.bool, fetch.func functions.\n * @modified 2019-11-13 Fixed an issue with the mouse-sensitive area around vertices (were affected by zoom).\n * @modified 2019-11-13 Added the 'enableMouseWheel' param.\n * @modified 2019-11-18 Added the Triangle class as a regular drawable element.\n * @modified 2019-11-18 The add function now works with arrays, too.\n * @modified 2019-11-18 Added the _handleColor helper function to determine the render color of non-draggable vertices.\n * @modified 2019-11-19 Fixed a bug in the resizeCanvas function; retina resolution was not possible.\n * @modified 2019-12-04 Added relative positioned zooming.\n * @modified 2019-12-04 Added offsetX and offsetY params.\n * @modified 2019-12-04 Added an 'Set to fullsize retina' button to the GUI config.\n * @modified 2019-12-07 Added the drawConfig for lines, polygons, ellipse, triangles, bezier curves and image control lines.\n * @modified 2019-12-08 Fixed a css scale bug in the viewport() function.\n * @modified 2019-12-08 Added the drawconfig UI panel (line colors and line widths).\n * @modified 2020-02-06 Added handling for the end- and end-control-points of non-cirular Bézier paths (was still missing).\n * @modified 2020-02-06 Fixed a drag-amount bug in the move handling of end points of Bezier paths (control points was not properly moved when non circular).\n * @modified 2020-03-28 Ported this class from vanilla-JS to Typescript.\n * @modified 2020-03-29 Fixed the enableSVGExport flag (read enableEport before).\n * @modified 2020-05-09 Included the Cirlcle class.\n * @modified 2020-06-22 Added the rasterScaleX and rasterScaleY config params.\n * @modified 2020-06-03 Fixed the selectedVerticesOnPolyon(Polygon) function: non-selectable vertices were selected too, before.\n * @modified 2020-07-06 Replacing Touchy.js by AlloyFinger.js\n * @modified 2020-07-27 Added the getVertexNear(XYCoords,number) function\n * @modified 2020-07-27 Extended the remove(Drawable) function: vertices are now removed, too.\n * @modified 2020-07-28 Added PlotBoilerplate.revertMousePosition(number,number) – the inverse function of transformMousePosition(...).\n * @modified 2020-07-31 Added PlotBoilerplate.getDraggedElementCount() to check wether any elements are currently being dragged.\n * @modified 2020-08-19 Added the VertexAttributes.visible attribute to make vertices invisible.\n * @modified 2020-11-17 Added pure click handling (no dragEnd and !wasMoved jiggliny any more) to the PlotBoilerplate.\n * @modified 2020-12-11 Added the `removeAll(boolean)` function.\n * @modified 2020-12-17 Added the `CircleSector` drawable.\n * @modified 2021-01-04 Avoiding multiple redraw call on adding multiple Drawables (array).\n * @modified 2021-01-08 Added param `draw:DraLib<void>` to the methods `drawVertices`, `drawGrid` and `drawSelectPolygon`.\n * @modified 2021-01-08 Added the customizable `drawAll(...)` function.\n * @modified 2021-01-09 Added the `drawDrawable(...)` function.\n * @modified 2021-01-10 Added the `eventCatcher` element (used to track mouse events on SVGs).\n * @modified 2021-01-26 Fixed SVG resizing.\n * @modified 2021-01-26 Replaced the old SVGBuilder by the new `drawutilssvg` library.\n * @modified 2021-02-08 Fixed a lot of es2015 compatibility issues.\n * @modified 2021-02-18 Adding `adjustOffset(boolean)` function.\n * @modified 2021-03-01 Updated the `PlotBoilerplate.draw(...)` function: ellipses are now rotate-able.\n * @modified 2021-03-03 Added the `VEllipseSector` drawable.\n * @modified 2021-03-29 Clearing `currentClassName` and `currentId` after drawing each drawable.\n * @modified 2021-04-25 Extending `remove` to accept arrays of drawables.\n * @modified 2021-11-16 Adding the `PBText` drawable.\n * @modified 2022-08-01 Added `title` to the params.\n * @modified 2022-10-25 Added the `origin` to the default draw config.\n * @modified 2022-11-06 Adding an XML declaration to the SVG export routine.\n * @modified 2022-11-23 Added the `drawRaster` (default=true) option to the config/drawconfig.\n * @modified 2023-02-04 Fixed a bug in the `drawDrawable` function; fill's current classname was not set.\n * @modified 2023-02-10 Fixing an issue of the `style.position` setting when `fitToParent=true` from `absolute` to `static` (default).\n * @modified 2023-02-10 Cleaning up most type errors in the main class (mostly null checks).\n * @modified 2023-02-10 Adding `enableZoom` and `enablePan` (both default true) to have the option to disable these functions.\n * @modified 2023-09-29 Adding proper dicionary key and value types to the params of `PlotBoilerplate.utils.safeMergeByKeys` (was `object` before).\n * @modified 2024-07-08 Adding `PlotBoilerplate.getGUI()` to retrieve the GUI instance.\n * @modified 2024-08-25 Extending main class `PlotBoilerplate` optional param `isBackdropFiltersEnabled`.\n * @modified 2024-12-02 Adding the `triggerRedraw` to the `removeAll` method.\n * @modified 2025-05-07 Changing the return type of `removeVertex` from `void` to `boolean`.\n * @modified 2025-05-07 Handling content changes now with `contentChangeListeners`.\n * @modified 2025-05-07 Added `PlogBoilerplate.addContentChangeListener` and `.removeContentChangeListener`.\n * @modified 2025-05-07 Moving full vectors now by default when vector point a is moved.\n * @modified 2025-05-20 Applying `lineWith` parameter in the draw routine for vectors (had been missing).\n * @modified 2026-03-13 Changed visibility of `setZoom` and `setOffset` to public. There was no good reason to have the private.\n * @modified 2026-04-04 Added `isInPanningMode` attribute and `isPanning` method.\n *\n * @version 1.22.0\n *\n * @file PlotBoilerplate\n * @fileoverview The main class.\n * @public\n **/\nvar __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.PlotBoilerplate = void 0;\nvar alloyfinger_typescript_1 = require(\"alloyfinger-typescript\");\nvar draw_1 = require(\"./draw\");\nvar drawgl_1 = require(\"./drawgl\");\nvar drawutilssvg_1 = require(\"./drawutilssvg\");\nvar BezierPath_1 = require(\"./BezierPath\");\nvar Bounds_1 = require(\"./Bounds\");\nvar Circle_1 = require(\"./Circle\");\nvar CircleSector_1 = require(\"./CircleSector\");\nvar Grid_1 = require(\"./Grid\");\nvar KeyHandler_1 = require(\"./KeyHandler\");\nvar Line_1 = require(\"./Line\");\nvar MouseHandler_1 = require(\"./MouseHandler\");\nvar PBImage_1 = require(\"./PBImage\");\nvar Polygon_1 = require(\"./Polygon\");\nvar Triangle_1 = require(\"./Triangle\");\nvar VEllipse_1 = require(\"./VEllipse\");\nvar VEllipseSector_1 = require(\"./VEllipseSector\");\nvar Vector_1 = require(\"./Vector\");\nvar Vertex_1 = require(\"./Vertex\");\nvar VertexAttr_1 = require(\"./VertexAttr\");\nvar PBText_1 = require(\"./PBText\");\n/**\n * @classdesc The main class of the PlotBoilerplate.\n *\n * @requires Vertex\n * @requires Line\n * @requires Vector\n * @requires Polygon\n * @requires PBImage\n * @requires VEllipse\n * @requires Circle\n * @requires MouseHandler\n * @requires KeyHandler\n * @requires VertexAttr\n * @requires CubicBezierCurve\n * @requires BezierPath\n * @requires Drawable\n * @requires DrawConfig\n * @requires IHooks\n * @requires PBParams\n * @requires Triangle\n * @requires drawutils\n * @requires drawutilsgl\n * @requires SVGSerializable\n * @requires XYCoords\n * @requires XYDimension\n */\nvar PlotBoilerplate = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name PlotBoilerplate\n * @public\n * @param {object} config={} - The configuration.\n * @param {HTMLCanvasElement} config.canvas - Your canvas element in the DOM (required).\n * @param {boolean=} [config.fullSize=true] - If set to true the canvas will gain full window size.\n * @param {boolean=} [config.fitToParent=true] - If set to true the canvas will gain the size of its parent container (overrides fullSize).\n * @param {number=} [config.scaleX=1.0] - The initial x-zoom. Default is 1.0.\n * @param {number=} [config.scaleY=1.0] - The initial y-zoom. Default is 1.0.\n * @param {number=} [config.offsetX=1.0] - The initial x-offset. Default is 0.0. Note that autoAdjustOffset=true overrides these values.\n * @param {number=} [config.offsetY=1.0] - The initial y-offset. Default is 0.0. Note that autoAdjustOffset=true overrides these values.\n * @param {boolean=} [config.rasterGrid=true] - If set to true the background grid will be drawn rastered.\n * @param {boolean=} [config.rasterScaleX=1.0] - Define the default horizontal raster scale (default=1.0).\n * @param {boolean=} [config.rasterScaleY=1.0] - Define the default vertical raster scale (default=1.0).\n * @param {number=} [config.rasterAdjustFactor=1.0] - The exponential limit for wrapping down the grid. (2.0 means: halve the grid each 2.0*n zoom step).\n * @param {boolean=} [config.drawOrigin=false] - Draw a crosshair at (0,0).\n * @param {boolean=} [config.autoAdjustOffset=true] - When set to true then the origin of the XY plane will\n * be re-adjusted automatically (see the params\n * offsetAdjust{X,Y}Percent for more).\n * @param {number=} [config.offsetAdjustXPercent=50] - The x-fallback position for the origin after\n * resizing the canvas.\n * @param {number=} [config.offsetAdjustYPercent=50] - The y-fallback position for the origin after\n * resizing the canvas.\n * @param {number=} [config.defaultCanvasWidth=1024] - The canvas size fallback (width) if no automatic resizing\n * is switched on.\n * @param {number=} [config.defaultCanvasHeight=768] - The canvas size fallback (height) if no automatic resizing\n * is switched on.\n * @param {number=} [config.canvasWidthFactor=1.0] - Scaling factor (width) upon the canvas size.\n * In combination with cssScale{X,Y} this can be used to obtain\n * sub pixel resolutions for retina displays.\n * @param {number=} [config.canvasHeightFactor=1.0] - Scaling factor (height) upon the canvas size.\n * In combination with cssScale{X,Y} this can be used to obtain\n * sub pixel resolutions for retina displays.\n * @param {number=} [config.cssScaleX=1.0] - Visually resize the canvas (horizontally) using CSS transforms (scale).\n * @param {number=} [config.cssScaleY=1.0] - Visually resize the canvas (vertically) using CSS transforms (scale).\n * @param {boolan=} [config.cssUniformScale=true] - CSS scale x and y obtaining aspect ratio.\n * @param {boolean=} [config.autoDetectRetina=true] - When set to true (default) the canvas will try to use the display's pixel ratio.\n * @param {string=} [config.backgroundColor=#ffffff] - The backround color.\n * @param {boolean=} [config.redrawOnResize=true] - Switch auto-redrawing on resize on/off (some applications\n * might want to prevent automatic redrawing to avoid data loss from the draw buffer).\n * @param {boolean=} [config.drawBezierHandleLines=true] - Indicates if Bézier curve handles should be drawn (used for\n * editors, no required in pure visualizations).\n * @param {boolean=} [config.drawBezierHandlePoints=true] - Indicates if Bézier curve handle points should be drawn.\n * @param {function=} [config.preClear=null] - A callback function that will be triggered just before the\n * draw function clears the canvas (before anything else was drawn).\n * @param {function=} [config.preDraw=null] - A callback function that will be triggered just before the draw\n * function starts.\n * @param {function=} [config.postDraw=null] - A callback function that will be triggered right after the drawing\n * process finished.\n * @param {boolean=} [config.enableMouse=true] - Indicates if the application should handle mouse events for you.\n * @param {boolean=} [config.enableTouch=true] - Indicates if the application should handle touch events for you.\n * @param {boolean=} [config.enableKeys=true] - Indicates if the application should handle key events for you.\n * @param {boolean=} [config.enableMouseWheel=true] - Indicates if the application should handle mouse wheel events for you.\n * @param {boolean=} [config.enablePan=true] - (default true) Set to false if you want to disable panning completely.\n * @param {boolean=} [config.enableZoom=true] - (default true) Set to false if you want to disable zooming completely.\n * @param {boolean=} [config.enableGL=false] - Indicates if the application should use the experimental WebGL features (not recommended).\n * @param {boolean=} [config.enableSVGExport=true] - Indicates if the SVG export should be enabled (default is true).\n * Note that changes from the postDraw hook might not be visible in the export.\n * @param {string=} [config.title=null] - Specify any hover tile here. It will be attached as a `title` attribute to the most elevated element.\n */\n function PlotBoilerplate(config, drawConfig) {\n var _b, _c;\n /**\n * A list of content change listeners.\n */\n this.contentChangeListeners = [];\n /**\n * A discrete timestamp to identify single render cycles.\n * Note that using system time milliseconds is not a safe way to identify render frames, as on modern powerful machines\n * multiple frames might be rendered within each millisecond.\n * @member {number}\n * @memberof plotboilerplate\n * @instance\n * @private\n */\n this.renderTime = 0;\n /**\n * A storage variable for retrieving the GUI instance once it was created.\n */\n this._gui = null;\n // This should be in some static block ...\n VertexAttr_1.VertexAttr.model = {\n bezierAutoAdjust: false,\n renderTime: 0,\n selectable: true,\n isSelected: false,\n draggable: true,\n visible: true\n };\n if (typeof config.canvas === \"undefined\") {\n throw \"No canvas specified.\";\n }\n /**\n * A global config that's attached to the dat.gui control interface.\n *\n * @member {Object}\n * @memberof PlotBoilerplate\n * @instance\n */\n var f = PlotBoilerplate.utils.fetch;\n this.config = {\n canvas: config.canvas,\n fullSize: f.val(config, \"fullSize\", true),\n fitToParent: f.bool(config, \"fitToParent\", true),\n scaleX: f.num(config, \"scaleX\", 1.0),\n scaleY: f.num(config, \"scaleY\", 1.0),\n offsetX: f.num(config, \"offsetX\", 0.0),\n offsetY: f.num(config, \"offsetY\", 0.0),\n rasterGrid: f.bool(config, \"rasterGrid\", true),\n drawRaster: f.bool(config, \"drawRaster\", true),\n rasterScaleX: f.num(config, \"rasterScaleX\", 1.0),\n rasterScaleY: f.num(config, \"rasterScaleY\", 1.0),\n rasterAdjustFactor: f.num(config, \"rasterAdjustdFactror\", 2.0),\n drawOrigin: f.bool(config, \"drawOrigin\", false),\n autoAdjustOffset: f.val(config, \"autoAdjustOffset\", true),\n offsetAdjustXPercent: f.num(config, \"offsetAdjustXPercent\", 50),\n offsetAdjustYPercent: f.num(config, \"offsetAdjustYPercent\", 50),\n backgroundColor: config.backgroundColor || \"#ffffff\",\n redrawOnResize: f.bool(config, \"redrawOnResize\", true),\n defaultCanvasWidth: f.num(config, \"defaultCanvasWidth\", PlotBoilerplate.DEFAULT_CANVAS_WIDTH),\n defaultCanvasHeight: f.num(config, \"defaultCanvasHeight\", PlotBoilerplate.DEFAULT_CANVAS_HEIGHT),\n canvasWidthFactor: f.num(config, \"canvasWidthFactor\", 1.0),\n canvasHeightFactor: f.num(config, \"canvasHeightFactor\", 1.0),\n cssScaleX: f.num(config, \"cssScaleX\", 1.0),\n cssScaleY: f.num(config, \"cssScaleY\", 1.0),\n cssUniformScale: f.bool(config, \"cssUniformScale\", true),\n saveFile: function () {\n _self.hooks.saveFile(_self);\n },\n setToRetina: function () {\n _self._setToRetina();\n },\n autoDetectRetina: f.bool(config, \"autoDetectRetina\", true),\n enableSVGExport: f.bool(config, \"enableSVGExport\", true),\n // Listeners/observers\n preClear: f.func(config, \"preClear\", null),\n preDraw: f.func(config, \"preDraw\", null),\n postDraw: f.func(config, \"postDraw\", null),\n // Interaction\n enableMouse: f.bool(config, \"enableMouse\", true),\n enableTouch: f.bool(config, \"enableTouch\", true),\n enableKeys: f.bool(config, \"enableKeys\", true),\n enableMouseWheel: f.bool(config, \"enableMouseWheel\", true),\n enableZoom: f.bool(config, \"enableZoom\", true), // default=true\n enablePan: f.bool(config, \"enablePan\", true), // default=true\n // Experimental (and unfinished)\n enableGL: f.bool(config, \"enableGL\", false),\n isBackdropFiltersEnabled: f.bool(config, \"isBackdropFiltersEnabled\", true)\n }; // END confog\n /**\n * Configuration for drawing things.\n *\n * @member {Object}\n * @memberof PlotBoilerplate\n * @instance\n */\n this.drawConfig = {\n drawVertices: true,\n drawBezierHandleLines: f.bool(config, \"drawBezierHandleLines\", true),\n drawBezierHandlePoints: f.bool(config, \"drawBezierHandlePoints\", true),\n drawHandleLines: f.bool(config, \"drawHandleLines\", true),\n drawHandlePoints: f.bool(config, \"drawHandlePoints\", true),\n drawGrid: f.bool(config, \"drawGrid\", true),\n drawRaster: f.bool(config, \"drawRaster\", true),\n bezier: {\n color: \"#00a822\",\n lineWidth: 2,\n handleLine: {\n color: \"rgba(180,180,180,0.5)\",\n lineWidth: 1\n },\n pathVertex: {\n color: \"#B400FF\",\n lineWidth: 1,\n fill: true\n },\n controlVertex: {\n color: \"#B8D438\",\n lineWidth: 1,\n fill: true\n }\n },\n // bezierPath: {\n // color: \"#0022a8\",\n // lineWidth: 1\n // },\n polygon: {\n color: \"#0022a8\",\n lineWidth: 1\n },\n triangle: {\n color: \"#6600ff\",\n lineWidth: 1\n },\n ellipse: {\n color: \"#2222a8\",\n lineWidth: 1\n },\n ellipseSector: {\n color: \"#a822a8\",\n lineWidth: 2\n },\n circle: {\n color: \"#22a8a8\",\n lineWidth: 2\n },\n circleSector: {\n color: \"#2280a8\",\n lineWidth: 1\n },\n vertex: {\n color: \"#a8a8a8\",\n lineWidth: 1\n },\n selectedVertex: {\n color: \"#c08000\",\n lineWidth: 2\n },\n line: {\n color: \"#a844a8\",\n lineWidth: 1\n },\n vector: {\n color: \"#ff44a8\",\n lineWidth: 1\n },\n image: {\n color: \"#a8a8a8\",\n lineWidth: 1\n },\n text: {\n color: \"rgba(192,0,128,0.5)\",\n lineWidth: 1,\n fill: true,\n anchor: true\n },\n origin: {\n color: \"#000000\"\n }\n }; // END drawConfig\n // +---------------------------------------------------------------------------------\n // | Object members.\n // +-------------------------------\n this.grid = new Grid_1.Grid(new Vertex_1.Vertex(0, 0), new Vertex_1.Vertex(50, 50));\n this.canvasSize = { width: PlotBoilerplate.DEFAULT_CANVAS_WIDTH, height: PlotBoilerplate.DEFAULT_CANVAS_HEIGHT };\n var canvasElement = typeof config.canvas === \"string\" ? document.querySelector(config.canvas) : config.canvas;\n if (typeof canvasElement === \"undefined\") {\n throw \"Cannot initialize PlotBoilerplate with a null canvas (element \\\"\".concat(config.canvas, \" not found).\");\n }\n // Which renderer to use: Canvas2D, WebGL (experimental) or SVG?\n if (canvasElement.tagName.toLowerCase() === \"canvas\") {\n this.canvas = canvasElement;\n this.eventCatcher = this.canvas;\n if (this.config.enableGL && typeof drawgl_1.drawutilsgl === \"undefined\") {\n console.warn(\"Cannot use webgl. Package was compiled without experimental gl support. Please use plotboilerplate-glsupport.min.js instead.\");\n console.warn(\"Disabling GL and falling back to Canvas2D.\");\n this.config.enableGL = false;\n }\n if (this.config.enableGL) {\n // Override the case 'null' here. If GL is not supported, well then nothing works.\n var ctx = this.canvas.getContext(\"webgl\"); // webgl-experimental?\n this.draw = new drawgl_1.drawutilsgl(ctx, false);\n // PROBLEM: same instance of fill and draw when using WebGL.\n // Shader program cannot be duplicated on the same context.\n this.fill = this.draw.copyInstance(true);\n console.warn(\"Initialized with experimental mode enableGL=true. Note that this is not yet fully implemented.\");\n }\n else {\n // Override the case 'null' here. If context creation is not supported, well then nothing works.\n var ctx = this.canvas.getContext(\"2d\");\n this.draw = new draw_1.drawutils(ctx, false);\n this.fill = new draw_1.drawutils(ctx, true);\n }\n }\n else if (canvasElement.tagName.toLowerCase() === \"svg\") {\n if (typeof drawutilssvg_1.drawutilssvg === \"undefined\")\n throw \"The svg draw library is not yet integrated part of PlotBoilerplate. Please include ./src/js/utils/helpers/drawutils.svg into your document.\";\n this.canvas = canvasElement;\n this.draw = new drawutilssvg_1.drawutilssvg(this.canvas, new Vertex_1.Vertex(), // offset\n new Vertex_1.Vertex(), // scale\n this.canvasSize, false, // fillShapes=false\n this.drawConfig, false // isSecondary=false\n );\n this.fill = this.draw.copyInstance(true); // fillShapes=true\n if (this.canvas.parentElement) {\n this.eventCatcher = document.createElement(\"div\");\n this.eventCatcher.style.position = \"absolute\";\n this.eventCatcher.style.left = \"0\";\n this.eventCatcher.style.top = \"0\";\n this.eventCatcher.style.cursor = \"pointer\";\n this.canvas.parentElement.style.position = \"relative\";\n this.canvas.parentElement.appendChild(this.eventCatcher);\n }\n else {\n this.eventCatcher = document.body;\n }\n }\n else {\n throw \"Element is neither a canvas nor an svg element.\";\n }\n // At this point the event cacher element is deinfed and located at highest elevation.\n // Set `title` attribut?\n if (config.title) {\n this.eventCatcher.setAttribute(\"title\", config.title);\n }\n this.draw.scale.set((_b = this.config.scaleX) !== null && _b !== void 0 ? _b : 1.0, this.config.scaleY);\n this.fill.scale.set((_c = this.config.scaleX) !== null && _c !== void 0 ? _c : 1.0, this.config.scaleY);\n this.vertices = [];\n this.selectPolygon = null;\n this.draggedElements = [];\n this.drawables = [];\n this.console = console;\n this.hooks = {\n // This is changable from the outside\n saveFile: PlotBoilerplate._saveFile\n };\n var _self = this;\n globalThis.addEventListener(\"resize\", function () { return _self.resizeCanvas(); });\n this.resizeCanvas();\n if (config.autoDetectRetina) {\n this._setToRetina();\n }\n this.installInputListeners();\n // Apply the configured CSS scale.\n this.updateCSSscale();\n // Init\n this.redraw();\n // Gain focus\n this.canvas.focus();\n } // END constructor\n /**\n * This function opens a save-as file dialog and – once an output file is\n * selected – stores the current canvas contents as an SVG image.\n *\n * It is the default hook for saving files and can be overwritten.\n *\n * @method _saveFile\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n * @private\n **/\n PlotBoilerplate._saveFile = function (pb) {\n // Create fake SVG node\n var svgNode = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n // Draw everything to fake node.\n var tosvgDraw = new drawutilssvg_1.drawutilssvg(svgNode, pb.draw.offset, pb.draw.scale, pb.canvasSize, false, // fillShapes=false\n pb.drawConfig);\n var tosvgFill = tosvgDraw.copyInstance(true); // fillShapes=true\n tosvgDraw.beginDrawCycle(0);\n tosvgFill.beginDrawCycle(0);\n if (pb.config.preClear) {\n pb.config.preClear();\n }\n tosvgDraw.clear(pb.config.backgroundColor || \"white\");\n if (pb.config.preDraw) {\n pb.config.preDraw(tosvgDraw, tosvgFill);\n }\n pb.drawAll(0, tosvgDraw, tosvgFill);\n pb.drawVertices(0, tosvgDraw);\n if (pb.config.postDraw)\n pb.config.postDraw(tosvgDraw, tosvgFill);\n tosvgDraw.endDrawCycle(0);\n tosvgFill.endDrawCycle(0);\n // Full support in all browsers \\o/\n // https://caniuse.com/xml-serializer\n var serializer = new XMLSerializer();\n var svgCode = serializer.serializeToString(svgNode);\n // Add: '<?xml version=\"1.0\" encoding=\"utf-8\"?>\\n' ?\n var blob = new Blob(['<?xml version=\"1.0\" encoding=\"utf-8\"?>\\n' + svgCode], { type: \"image/svg;charset=utf-8\" });\n // See documentation for FileSaver.js for usage.\n // https://github.com/eligrey/FileSaver.js\n if (typeof globalThis[\"saveAs\"] !== \"function\") {\n throw \"Cannot save file; did you load the ./utils/savefile helper function and the eligrey/SaveFile library?\";\n }\n var _saveAs = globalThis[\"saveAs\"];\n _saveAs(blob, \"plotboilerplate.svg\");\n };\n /**\n * This function sets the canvas resolution to factor 2.0 (or the preferred pixel ratio of your device) for retina displays.\n * Please not that in non-GL mode this might result in very slow rendering as the canvas buffer size may increase.\n *\n * @method _setToRetina\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n * @private\n **/\n PlotBoilerplate.prototype._setToRetina = function () {\n this.config.autoDetectRetina = true;\n var pixelRatio = globalThis.devicePixelRatio || 1;\n this.config.cssScaleX = this.config.cssScaleY = 1.0 / pixelRatio;\n this.config.canvasWidthFactor = this.config.canvasHeightFactor = pixelRatio;\n this.resizeCanvas();\n this.updateCSSscale();\n };\n PlotBoilerplate.prototype.isPanning = function () {\n return this.isInPanningMode;\n };\n /**\n * Set the current zoom and draw offset to fit the given bounds.\n *\n * This method currently restores the aspect zoom ratio.\n *\n **/\n PlotBoilerplate.prototype.fitToView = function (bounds) {\n var canvasCenter = new Vertex_1.Vertex(this.canvasSize.width / 2.0, this.canvasSize.height / 2.0);\n var canvasRatio = this.canvasSize.width / this.canvasSize.height;\n var ratio = bounds.width / bounds.height;\n // Find the new draw offset\n var center = new Vertex_1.Vertex(bounds.max.x - bounds.width / 2.0, bounds.max.y - bounds.height / 2.0)\n .inv()\n .addXY(this.canvasSize.width / 2.0, this.canvasSize.height / 2.0);\n this.setOffset(center);\n if (canvasRatio < ratio) {\n var newUniformZoom = this.canvasSize.width / bounds.width;\n this.setZoom(newUniformZoom, newUniformZoom, canvasCenter);\n }\n else {\n var newUniformZoom = this.canvasSize.height / bounds.height;\n this.setZoom(newUniformZoom, newUniformZoom, canvasCenter);\n }\n this.redraw();\n };\n /**\n * Set the console for this instance.\n *\n * @method setConsole\n * @param {Console} con - The new console object (default is globalThis.console).\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.setConsole = function (con) {\n this.console = con;\n };\n /**\n * Update the CSS scale for the canvas depending onf the cssScale{X,Y} settings.<br>\n * <br>\n * This function is usually only used inernally.\n *\n * @method updateCSSscale\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n * @private\n **/\n PlotBoilerplate.prototype.updateCSSscale = function () {\n var _b, _c, _d, _e;\n if (this.config.cssUniformScale) {\n PlotBoilerplate.utils.setCSSscale(this.canvas, (_b = this.config.cssScaleX) !== null && _b !== void 0 ? _b : 1.0, (_c = this.config.cssScaleX) !== null && _c !== void 0 ? _c : 1.0);\n }\n else {\n PlotBoilerplate.utils.setCSSscale(this.canvas, (_d = this.config.cssScaleX) !== null && _d !== void 0 ? _d : 1.0, (_e = this.config.cssScaleY) !== null && _e !== void 0 ? _e : 1.0);\n }\n };\n /**\n * Adds a new content change listener to this instance. Adding duplicates is not possible.\n *\n * @param {PBContentChangeListener} listener - The listenre to add.\n * @method addContentChangeListener\n * @instance\n * @memberof PlotBoilerplate\n * @returns {void}\n */\n PlotBoilerplate.prototype.addContentChangeListener = function (listener) {\n for (var i in this.contentChangeListeners) {\n if (this.contentChangeListeners[i] === listener) {\n return;\n }\n }\n this.contentChangeListeners.push(listener);\n };\n /**\n * Removes an existing content change listener from this instance.\n *\n * @param {PBContentChangeListener} listener - The listenre to add.\n * @method removeContentChangeListener\n * @instance\n * @memberof PlotBoilerplate\n * @returns {void}\n */\n PlotBoilerplate.prototype.removeContentChangeListener = function (listener) {\n for (var i = 0; i < this.contentChangeListeners.length; i++) {\n if (this.contentChangeListeners[i] === listener) {\n this.contentChangeListeners.splice(i, 1);\n return;\n }\n }\n };\n PlotBoilerplate.prototype._fireContentChanged = function (addedDrawables, removedDrawables) {\n for (var i in this.contentChangeListeners) {\n var listener = this.contentChangeListeners[i];\n if (listener && typeof listener === \"function\") {\n listener({\n type: addedDrawables.length > 0 ? \"DRAWABLES_ADDED\" : \"DRAWABLES_REMOVED\",\n addedDrawables: addedDrawables,\n removedDrawables: removedDrawables\n });\n }\n }\n };\n /**\n * Add a drawable object.<br>\n * <br>\n * This must be either:<br>\n * <pre>\n * * a Vertex\n * * a Line\n * * a Vector\n * * a VEllipse\n * * a VEllipseSector\n * * a Circle\n * * a Polygon\n * * a Triangle\n * * a BezierPath\n * * a BPImage\n * </pre>\n *\n * @param {Drawable|Drawable[]} drawable - The drawable (of one of the allowed class instance) to add.\n * @param {boolean} [redraw=true] - If true the function will trigger redraw after the drawable(s) was/were added.\n * @method add\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.add = function (drawable, redraw, doNotFireEvent) {\n if (Array.isArray(drawable)) {\n var arr = drawable;\n for (var i = 0; i < arr.length; i++) {\n this.add(arr[i], false, doNotFireEvent);\n }\n // !doNotFireEvent && this._fireContentChanged(arr, []);\n }\n else {\n var addedDrawables = [drawable];\n if (drawable instanceof Vertex_1.Vertex) {\n this.drawables.push(drawable);\n this.vertices.push(drawable);\n }\n else if (drawable instanceof Line_1.Line) {\n // Add some lines\n this.drawables.push(drawable);\n this.vertices.push(drawable.a);\n this.vertices.push(drawable.b);\n addedDrawables.push(drawable.a, drawable.b);\n }\n else if (drawable instanceof Vector_1.Vector) {\n this.drawables.push(drawable);\n this.vertices.push(drawable.a);\n this.vertices.push(drawable.b);\n addedDrawables.push(drawable.a, drawable.b);\n drawable.a.listeners.addDragListener(function (event) {\n drawable.b.add(event.params.dragAmount);\n });\n }\n else if (drawable instanceof VEllipse_1.VEllipse) {\n this.vertices.push(drawable.center);\n this.vertices.push(drawable.axis);\n addedDrawables.push(drawable.center, drawable.axis);\n this.drawables.push(drawable);\n drawable.center.listeners.addDragListener(function (event) {\n drawable.axis.add(event.params.dragAmount);\n });\n }\n else if (drawable instanceof VEllipseSector_1.VEllipseSector) {\n this.vertices.push(drawable.ellipse.center);\n this.vertices.push(drawable.ellipse.axis);\n addedDrawables.push(drawable.ellipse.center, drawable.ellipse.axis);\n this.drawables.push(drawable);\n drawable.ellipse.center.listeners.addDragListener(function (event) {\n drawable.ellipse.axis.add(event.params.dragAmount);\n });\n }\n else if (drawable instanceof Circle_1.Circle) {\n this.vertices.push(drawable.center);\n addedDrawables.push(drawable.center);\n this.drawables.push(drawable);\n }\n else if (drawable instanceof CircleSector_1.CircleSector) {\n this.vertices.push(drawable.circle.center);\n addedDrawables.push(drawable.circle.center);\n this.drawables.push(drawable);\n }\n else if (drawable instanceof Polygon_1.Polygon) {\n this.drawables.push(drawable);\n for (var i = 0; i < drawable.vertices.length; i++) {\n this.vertices.push(drawable.vertices[i]);\n addedDrawables.push(drawable.vertices[i]);\n }\n }\n else if (drawable instanceof Triangle_1.Triangle) {\n this.drawables.push(drawable);\n this.vertices.push(drawable.a);\n this.vertices.push(drawable.b);\n this.vertices.push(drawable.c);\n addedDrawables.push(drawable.a, drawable.b, drawable.c);\n }\n else if (drawable instanceof BezierPath_1.BezierPath) {\n this.drawables.push(drawable);\n var bezierPath = drawable;\n for (var i = 0; i < bezierPath.bezierCurves.length; i++) {\n if (!drawable.adjustCircular && i == 0) {\n this.vertices.push(bezierPath.bezierCurves[i].startPoint);\n addedDrawables.push(bezierPath.bezierCurves[i].startPoint);\n }\n this.vertices.push(bezierPath.bezierCurves[i].endPoint);\n this.vertices.push(bezierPath.bezierCurves[i].startControlPoint);\n this.vertices.push(bezierPath.bezierCurves[i].endControlPoint);\n addedDrawables.push(bezierPath.bezierCurves[i].endPoint, bezierPath.bezierCurves[i].startControlPoint, bezierPath.bezierCurves[i].endControlPoint);\n bezierPath.bezierCurves[i].startControlPoint.attr.selectable = false;\n bezierPath.bezierCurves[i].endControlPoint.attr.selectable = false;\n }\n PlotBoilerplate.utils.enableBezierPathAutoAdjust(drawable);\n }\n else if (drawable instanceof PBImage_1.PBImage) {\n this.vertices.push(drawable.upperLeft);\n this.vertices.push(drawable.lowerRight);\n addedDrawables.push(drawable.upperLeft, drawable.lowerRight);\n this.drawables.push(drawable);\n // Todo: think about a IDragEvent interface\n drawable.upperLeft.listeners.addDragListener(function (e) {\n drawable.lowerRight.add(e.params.dragAmount);\n });\n drawable.lowerRight.attr.selectable = false;\n }\n else if (drawable instanceof PBText_1.PBText) {\n this.vertices.push(drawable.anchor);\n addedDrawables.push(drawable.anchor);\n this.drawables.push(drawable);\n drawable.anchor.attr.selectable = false;\n }\n else {\n throw \"Cannot add drawable of unrecognized type: \" + typeof drawable + \".\";\n }\n !doNotFireEvent && this._fireContentChanged(addedDrawables, []);\n }\n // This is a workaround for backwards compatibility when the 'redraw' param was not yet present.\n if (redraw || typeof redraw == \"undefined\") {\n this.redraw();\n }\n };\n /**\n * Remove a drawable object.<br>\n * <br>\n * This must be either:<br>\n * <pre>\n * * a Vertex\n * * a Line\n * * a Vector\n * * a VEllipse\n * * a Circle\n * * a Polygon\n * * a BezierPath\n * * a BPImage\n * * a Triangle\n * </pre>\n *\n * @param {Drawable|Array<Drawable>} drawable - The drawable (of one of the allowed class instance) to remove.\n * @param {boolean} [redraw=false]\n * @param {removeWidth}\n * @method remove\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.remove = function (drawable, redraw, removeWithVertices, doNotFireEvent) {\n if (Array.isArray(drawable)) {\n var removedDrawables_1 = [];\n for (var i = 0; i < drawable.length; i++) {\n if (this.remove(drawable[i], false, removeWithVertices, true)) {\n removedDrawables_1.push(drawable[i]);\n }\n }\n if (redraw) {\n this.redraw();\n }\n !doNotFireEvent && this._fireContentChanged([], removedDrawables_1);\n return removedDrawables_1.length > 0;\n }\n if (drawable instanceof Vertex_1.Vertex) {\n var wasRemoved_1 = this.removeVertex(drawable, false, false);\n if (redraw) {\n this.redraw();\n }\n !doNotFireEvent && this._fireContentChanged([], [drawable]);\n return wasRemoved_1;\n }\n var wasRemoved = false;\n var removedDrawables = [];\n for (var i = 0; i < this.drawables.length; i++) {\n if (this.drawables[i] === drawable || this.drawables[i].uid === drawable.uid) {\n this.drawables.splice(i, 1);\n removedDrawables.push(drawable);\n if (removeWithVertices) {\n // Check if some listeners need to be removed\n if (drawable instanceof Line_1.Line) {\n // Add some lines\n this.removeVertex(drawable.a, false, true);\n this.removeVertex(drawable.b, false, true);\n removedDrawables.push(drawable.a, drawable.b);\n }\n else if (drawable instanceof Vector_1.Vector) {\n this.removeVertex(drawable.a, false, true);\n this.removeVertex(drawable.b, false, true);\n removedDrawables.push(drawable.a, drawable.b);\n }\n else if (drawable instanceof VEllipse_1.VEllipse) {\n this.removeVertex(drawable.center, false, true);\n this.removeVertex(drawable.axis, false, true);\n removedDrawables.push(drawable.center, drawable.axis);\n }\n else if (drawable instanceof VEllipseSector_1.VEllipseSector) {\n this.removeVertex(drawable.ellipse.center, false, true);\n this.removeVertex(drawable.ellipse.axis, false, true);\n removedDrawables.push(drawable.ellipse.center, drawable.ellipse.axis);\n }\n else if (drawable instanceof Circle_1.Circle) {\n this.removeVertex(drawable.center, false, true);\n }\n else if (drawable instanceof CircleSector_1.CircleSector) {\n this.removeVertex(drawable.circle.center, false, true);\n removedDrawables.push(drawable.circle.center);\n }\n else if (drawable instanceof Polygon_1.Polygon) {\n // for( var i in drawable.vertices )\n for (var i = 0; i < drawable.vertices.length; i++) {\n this.removeVertex(drawable.vertices[i], false, true);\n removedDrawables.push(drawable.vertices[i]);\n }\n }\n else if (drawable instanceof Triangle_1.Triangle) {\n this.removeVertex(drawable.a, false, true);\n this.removeVertex(drawable.b, false, true);\n this.removeVertex(drawable.c, false, true);\n removedDrawables.push(drawable.a, drawable.b, drawable.c);\n }\n else if (drawable instanceof BezierPath_1.BezierPath) {\n for (var i = 0; i < drawable.bezierCurves.length; i++) {\n this.removeVertex(drawable.bezierCurves[i].startPoint, false, true);\n this.removeVertex(drawable.bezierCurves[i].startControlPoint, false, true);\n this.removeVertex(drawable.bezierCurves[i].endControlPoint, false, true);\n removedDrawables.push(drawable.bezierCurves[i].startPoint, drawable.bezierCurves[i].startControlPoint, drawable.bezierCurves[i].endControlPoint);\n if (i + 1 == drawable.bezierCurves.length) {\n this.removeVertex(drawable.bezierCurves[i].endPoint, false, true);\n removedDrawables.push(drawable.bezierCurves[i].endPoint);\n }\n }\n }\n else if (drawable instanceof PBImage_1.PBImage) {\n this.removeVertex(drawable.upperLeft, false, true);\n this.removeVertex(drawable.lowerRight, false, true);\n removedDrawables.push(drawable.upperLeft, drawable.lowerRight);\n }\n else if (drawable instanceof PBText_1.PBText) {\n this.removeVertex(drawable.anchor, false, true);\n removedDrawables.push(drawable.anchor);\n }\n } // END removeWithVertices\n if (redraw) {\n this.redraw();\n }\n !doNotFireEvent && this._fireContentChanged([], removedDrawables);\n wasRemoved = true;\n } // END if\n } // END for\n return wasRemoved;\n };\n /**\n * Remove a vertex from the vertex list.<br>\n *\n * @param {Vertex} vert - The vertex to remove.\n * @param {boolean} [redraw=false]\n * @method removeVertex\n * @instance\n * @memberof PlotBoilerplate\n * @return {boolean}\n **/\n PlotBoilerplate.prototype.removeVertex = function (vert, redraw, doNotFireEvent) {\n for (var i = 0; i < this.vertices.length; i++) {\n if (this.vertices[i] === vert) {\n this.vertices.splice(i, 1);\n if (redraw) {\n this.redraw();\n }\n !doNotFireEvent && this._fireContentChanged([], [vert]);\n return true;\n }\n }\n return false;\n };\n /**\n * Remove all elements.\n *\n * If you want to keep the vertices, pass `true`.\n *\n * @method removeAll\n * @param {boolean=false} keepVertices\n * @param {boolean=true} triggerRedraw - By default this method triggers the redraw routine; passing `false` will suppress redrawing.\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n */\n PlotBoilerplate.prototype.removeAll = function (keepVertices, triggerRedraw) {\n var removedDrawables = this.drawables;\n this.drawables = [];\n if (!Boolean(keepVertices)) {\n removedDrawables = removedDrawables.concat(this.vertices);\n this.vertices = [];\n }\n if (triggerRedraw || typeof triggerRedraw === \"undefined\") {\n this.redraw();\n }\n removedDrawables.length > 0 && this._fireContentChanged([], removedDrawables);\n };\n /**\n * Find the vertex near the given position.\n *\n * The position is the absolute vertex position, not the x-y-coordinates on the canvas.\n *\n * @param {XYCoords} position - The position of the vertex to search for.\n * @param {number} pixelTolerance - A radius around the position to include into the search.\n * Note that the tolerance will be scaled up/down when zoomed.\n * @return The vertex near the given position or undefined if none was found there.\n **/\n PlotBoilerplate.prototype.getVertexNear = function (pixelPosition, pixelTolerance) {\n var _b, _c;\n var p = this.locatePointNear(this.transformMousePosition(pixelPosition.x, pixelPosition.y), pixelTolerance / Math.min((_b = this.config.cssScaleX) !== null && _b !== void 0 ? _b : 1.0, (_c = this.config.cssScaleY) !== null && _c !== void 0 ? _c : 1.0));\n if (p && p.typeName == \"vertex\") {\n return this.vertices[p.vindex];\n }\n return undefined;\n };\n /**\n * Draw the grid with the current config settings.<br>\n *\n * This function is usually only used internally.\n *\n * @method drawGrid\n * @param {DrawLib} draw - The drawing library to use to draw lines.\n * @private\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.drawGrid = function (draw) {\n if (typeof draw === \"undefined\") {\n draw = this.draw;\n }\n var gScale = {\n x: (Grid_1.Grid.utils.mapRasterScale(this.config.rasterAdjustFactor, this.draw.scale.x) * this.config.rasterScaleX) /\n this.config.cssScaleX,\n y: (Grid_1.Grid.utils.mapRasterScale(this.config.rasterAdjustFactor, this.draw.scale.y) * this.config.rasterScaleY) /\n this.config.cssScaleY\n };\n var gSize = { width: this.grid.size.x * gScale.x, height: this.grid.size.y * gScale.y };\n var cs = { width: this.canvasSize.width / 2, height: this.canvasSize.height / 2 };\n var offset = this.draw.offset.clone().inv();\n // console.log( \"drawGrid\", gScale, gSize, cs, offset );\n offset.x =\n ((Math.round(offset.x + cs.width) / Math.round(gSize.width)) * gSize.width) / this.draw.scale.x +\n (((this.draw.offset.x - cs.width) / this.draw.scale.x) % gSize.width);\n offset.y =\n ((Math.round(offset.y + cs.height) / Math.round(gSize.height)) * gSize.height) / this.draw.scale.y +\n (((this.draw.offset.y - cs.height) / this.draw.scale.x) % gSize.height);\n if (this.drawConfig.drawGrid) {\n draw.setCurrentClassName(null);\n if (this.config.rasterGrid) {\n // TODO: move config member to drawConfig\n draw.setCurrentId(\"raster\");\n draw.raster(offset, this.canvasSize.width / this.draw.scale.x, this.canvasSize.height / this.draw.scale.y, gSize.width, gSize.height, \"rgba(0,128,255,0.125)\");\n }\n else {\n draw.setCurrentId(\"grid\");\n draw.grid(offset, this.canvasSize.width / this.draw.scale.x, this.canvasSize.height / this.draw.scale.y, gSize.width, gSize.height, \"rgba(0,128,255,0.095)\");\n }\n }\n };\n /**\n * Draw the origin with the current config settings.<br>\n *\n * This function is usually only used internally.\n *\n * @method drawOrigin\n * @param {DrawLib} draw - The drawing library to use to draw lines.\n * @private\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.drawOrigin = function (draw) {\n // Add a crosshair to mark the origin\n draw.setCurrentId(\"origin\");\n draw.crosshair({ x: 0, y: 0 }, 10, this.drawConfig.origin.color);\n };\n /**\n * This is just a tiny helper function to determine the render color of vertices.\n **/\n PlotBoilerplate.prototype._handleColor = function (h, color) {\n return h.attr.isSelected ? this.drawConfig.selectedVertex.color : h.attr.draggable ? color : \"rgba(128,128,128,0.5)\";\n };\n /**\n * Draw all drawables.\n *\n * This function is usually only used internally.\n *\n * @method drawDrawables\n * @param {number} renderTime - The current render time. It will be used to distinct\n * already draw vertices from non-draw-yet vertices.\n * @param {DrawLib} draw - The drawing library to use to draw lines.\n * @param {DrawLib} fill - The drawing library to use to fill areas.\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.drawDrawables = function (renderTime, draw, fill) {\n for (var i in this.drawables) {\n var d = this.drawables[i];\n this.draw.setCurrentId(d.uid);\n this.fill.setCurrentId(d.uid);\n this.draw.setCurrentClassName(d.className);\n this.fill.setCurrentClassName(d.className);\n this.drawDrawable(d, renderTime, draw, fill);\n }\n };\n /**\n * Draw the given drawable.\n *\n * This function is usually only used internally.\n *\n * @method drawDrawable\n * @param {Drawable} d - The drawable to draw.\n * @param {number} renderTime - The current render time. It will be used to distinct\n * already draw vertices from non-draw-yet vertices.\n * @param {DrawLib} draw - The drawing library to use to draw lines.\n * @param {DrawLib} fill - The drawing library to use to fill areas.\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.drawDrawable = function (d, renderTime, draw, fill) {\n if (d instanceof BezierPath_1.BezierPath) {\n var curveIndex = 0;\n for (var c in d.bezierCurves) {\n // Restore these settings again in each loop (will be overwritten)\n this.draw.setCurrentId(\"\".concat(d.uid, \"-\").concat(curveIndex));\n this.fill.setCurrentId(\"\".concat(d.uid, \"-\").concat(curveIndex));\n this.draw.setCurrentClassName(d.className);\n this.fill.setCurrentClassName(d.className);\n draw.cubicBezier(d.bezierCurves[c].startPoint, d.bezierCurves[c].endPoint, d.bezierCurves[c].startControlPoint, d.bezierCurves[c].endControlPoint, this.drawConfig.bezier.color, this.drawConfig.bezier.lineWidth);\n if (this.drawConfig.drawBezierHandlePoints && this.drawConfig.drawHandlePoints) {\n if (d.bezierCurves[c].startPoint.attr.visible) {\n var df = this.drawConfig.bezier.pathVertex.fill ? fill : draw;\n df.setCurrentId(\"\".concat(d.uid, \"_h0\"));\n df.setCurrentClassName(\"\".concat(d.className, \"-start-handle\"));\n if (d.bezierCurves[c].startPoint.attr.bezierAutoAdjust) {\n df.squareHandle(d.bezierCurves[c].startPoint, 5, this._handleColor(d.bezierCurves[c].startPoint, this.drawConfig.bezier.pathVertex.color));\n }\n else {\n df.diamondHandle(d.bezierCurves[c].startPoint, 7, this._handleColor(d.bezierCurves[c].startPoint, this.drawConfig.bezier.pathVertex.color));\n }\n }\n d.bezierCurves[c].startPoint.attr.renderTime = renderTime;\n if (d.bezierCurves[c].endPoint.attr.visible) {\n var df = this.drawConfig.bezier.pathVertex.fill ? fill : draw;\n df.setCurrentId(\"\".concat(d.uid, \"_h0\"));\n df.setCurrentClassName(\"\".concat(d.className, \"-start-handle\"));\n if (d.bezierCurves[c].endPoint.attr.bezierAutoAdjust) {\n df.squareHandle(d.bezierCurves[c].endPoint, 5, this._handleColor(d.bezierCurves[c].endPoint, this.drawConfig.bezier.pathVertex.color));\n }\n else {\n df.diamondHandle(d.bezierCurves[c].endPoint, 7, this._handleColor(d.bezierCurves[c].endPoint, this.drawConfig.bezier.pathVertex.color));\n }\n }\n if (d.bezierCurves[c].startControlPoint.attr.visible) {\n var df = this.drawConfig.bezier.controlVertex.fill ? fill : draw;\n df.setCurrentId(\"\".concat(d.uid, \"_h2\"));\n df.setCurrentClassName(\"\".concat(d.className, \"-start-control-handle\"));\n df.circleHandle(d.bezierCurves[c].startControlPoint, 3, this._handleColor(d.bezierCurves[c].startControlPoint, this.drawConfig.bezier.controlVertex.color));\n }\n if (d.bezierCurves[c].endControlPoint.attr.visible) {\n var df = this.drawConfig.bezier.controlVertex.fill ? fill : draw;\n df.setCurrentId(\"\".concat(d.uid, \"_h3\"));\n df.setCurrentClassName(\"\".concat(d.className, \"-end-control-handle\"));\n df.circleHandle(d.bezierCurves[c].endControlPoint, 3, this._handleColor(d.bezierCurves[c].endControlPoint, this.drawConfig.bezier.controlVertex.color));\n }\n d.bezierCurves[c].startPoint.attr.renderTime = renderTime;\n d.bezierCurves[c].endPoint.attr.renderTime = renderTime;\n d.bezierCurves[c].startControlPoint.attr.renderTime = renderTime;\n d.bezierCurves[c].endControlPoint.attr.renderTime = renderTime;\n }\n else {\n d.bezierCurves[c].startPoint.attr.renderTime = renderTime;\n d.bezierCurves[c].endPoint.attr.renderTime = renderTime;\n d.bezierCurves[c].startControlPoint.attr.renderTime = renderTime;\n d.bezierCurves[c].endControlPoint.attr.renderTime = renderTime;\n }\n if (this.drawConfig.drawBezierHandleLines && this.drawConfig.drawHandleLines) {\n draw.setCurrentId(\"\".concat(d.uid, \"_l0\"));\n draw.setCurrentClassName(\"\".concat(d.className, \"-start-line\"));\n draw.handleLine(d.bezierCurves[c].startPoint, d.bezierCurves[c].startControlPoint);\n draw.setCurrentId(\"\".concat(d.uid, \"_l1\"));\n draw.setCurrentClassName(\"\".concat(d.className, \"-end-line\"));\n draw.handleLine(d.bezierCurves[c].endPoint, d.bezierCurves[c].endControlPoint);\n }\n curveIndex++;\n } // END for\n }\n else if (d instanceof Polygon_1.Polygon) {\n draw.polygon(d, this.drawConfig.polygon.color, this.drawConfig.polygon.lineWidth);\n if (!this.drawConfig.drawHandlePoints) {\n for (var i in d.vertices) {\n d.vertices[i].attr.renderTime = renderTime;\n }\n }\n }\n else if (d instanceof Triangle_1.Triangle) {\n draw.polyline([d.a, d.b, d.c], false, this.drawConfig.triangle.color, this.drawConfig.triangle.lineWidth);\n if (!this.drawConfig.drawHandlePoints) {\n d.a.attr.renderTime = d.b.attr.renderTime = d.c.attr.renderTime = renderTime;\n }\n }\n else if (d instanceof VEllipse_1.VEllipse) {\n if (this.drawConfig.drawHandleLines) {\n draw.setCurrentId(\"\".concat(d.uid, \"_e0\"));\n draw.setCurrentClassName(\"\".concat(d.className, \"-v-line\"));\n draw.handleLine(d.center.clone().add(0, d.signedRadiusV()).rotate(d.rotation, d.center), d.axis); // , \"#c8c8c8\");\n draw.setCurrentId(\"\".concat(d.uid, \"_e1\"));\n draw.setCurrentClassName(\"\".concat(d.className, \"-h-line\"));\n draw.handleLine(d.center.clone().add(d.signedRadiusH(), 0).rotate(d.rotation, d.center), d.axis); // , \"#c8c8c8\");\n }\n draw.setCurrentId(d.uid);\n draw.setCurrentClassName(\"\".concat(d.className));\n draw.ellipse(d.center, \n // Math.abs(d.axis.x-d.center.x), Math.abs(d.axis.y-d.center.y),\n d.radiusH(), d.radiusV(), this.drawConfig.ellipse.color, this.drawConfig.ellipse.lineWidth, d.rotation);\n if (!this.drawConfig.drawHandlePoints) {\n d.center.attr.renderTime = renderTime;\n d.axis.attr.renderTime = renderTime;\n }\n }\n else if (d instanceof VEllipseSector_1.VEllipseSector) {\n draw.setCurrentId(d.uid);\n draw.setCurrentClassName(\"\".concat(d.className));\n var data = VEllipseSector_1.VEllipseSector.ellipseSectorUtils.describeSVGArc(d.ellipse.center.x, d.ellipse.center.y, d.ellipse.radiusH(), d.ellipse.radiusV(), d.startAngle, d.endAngle, d.ellipse.rotation, { moveToStart: true });\n draw.path(data, this.drawConfig.ellipseSector.color, this.drawConfig.ellipseSector.lineWidth);\n }\n else if (d instanceof Circle_1.Circle) {\n draw.circle(d.center, d.radius, this.drawConfig.circle.color, this.drawConfig.circle.lineWidth);\n }\n else if (d instanceof CircleSector_1.CircleSector) {\n draw.circleArc(d.circle.center, d.circle.radius, d.startAngle, d.endAngle, this.drawConfig.circleSector.color, this.drawConfig.circleSector.lineWidth);\n }\n else if (d instanceof Vertex_1.Vertex) {\n if (this.drawConfig.drawVertices && (!d.attr.selectable || !d.attr.draggable) && d.attr.visible) {\n // Draw as special point (grey)\n draw.circleHandle(d, 7, this.drawConfig.vertex.color);\n d.attr.renderTime = renderTime;\n }\n }\n else if (d instanceof Line_1.Line) {\n draw.line(d.a, d.b, this.drawConfig.line.color, this.drawConfig.line.lineWidth);\n if (!this.drawConfig.drawHandlePoints || !d.a.attr.selectable)\n d.a.attr.renderTime = renderTime;\n if (!this.drawConfig.drawHandlePoints || !d.b.attr.selectable)\n d.b.attr.renderTime = renderTime;\n }\n else if (d instanceof Vector_1.Vector) {\n draw.arrow(d.a, d.b, this.drawConfig.vector.color, this.drawConfig.vector.lineWidth);\n if (this.drawConfig.drawHandlePoints && d.b.attr.selectable && d.b.attr.visible) {\n draw.setCurrentId(\"\".concat(d.uid, \"_h0\"));\n draw.setCurrentClassName(\"\".concat(d.className, \"-handle\"));\n draw.circleHandle(d.b, 3, \"#a8a8a8\");\n }\n else {\n d.b.attr.renderTime = renderTime;\n }\n if (!this.drawConfig.drawHandlePoints || !d.a.attr.selectable)\n d.a.attr.renderTime = renderTime;\n if (!this.drawConfig.drawHandlePoints || !d.b.attr.selectable)\n d.b.attr.renderTime = renderTime;\n }\n else if (d instanceof PBImage_1.PBImage) {\n if (this.drawConfig.drawHandleLines) {\n draw.setCurrentId(\"\".concat(d.uid, \"_l0\"));\n draw.setCurrentClassName(\"\".concat(d.className, \"-line\"));\n draw.line(d.upperLeft, d.lowerRight, this.drawConfig.image.color, this.drawConfig.image.lineWidth);\n }\n fill.setCurrentId(d.uid);\n fill.image(d.image, d.upperLeft, d.lowerRight.clone().sub(d.upperLeft));\n if (this.drawConfig.drawHandlePoints) {\n draw.setCurrentId(\"\".concat(d.uid, \"_h0\"));\n draw.setCurrentClassName(\"\".concat(d.className, \"-lower-right\"));\n draw.circleHandle(d.lowerRight, 3, this.drawConfig.image.color);\n d.lowerRight.attr.renderTime = renderTime;\n }\n }\n else if (d instanceof PBText_1.PBText) {\n fill.setCurrentId(d.uid);\n fill.text(d.text, d.anchor.x, d.anchor.y, d);\n if (this.drawConfig.text.anchor) {\n draw.setCurrentId(\"\".concat(d.uid, \"_a0\"));\n draw.setCurrentClassName(\"\".concat(d.className, \"-anchor\"));\n (this.drawConfig.text.fill ? fill : draw).point(d.anchor, this.drawConfig.text.color);\n }\n d.anchor.attr.renderTime = renderTime;\n }\n else {\n console.error(\"Cannot draw object. Unknown class.\");\n }\n draw.setCurrentClassName(null);\n draw.setCurrentId(null);\n fill.setCurrentClassName(null);\n fill.setCurrentId(null);\n };\n /**\n * Draw the select-polygon (if there is one).\n *\n * This function is usually only used internally.\n *\n * @method drawSelectPolygon\n * @private\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.drawSelectPolygon = function (draw) {\n // Draw select polygon?\n if (this.selectPolygon != null && this.selectPolygon.vertices.length > 0) {\n draw.setCurrentId(this.selectPolygon.uid);\n draw.polygon(this.selectPolygon, \"#888888\");\n draw.crosshair(this.selectPolygon.vertices[0], 3, \"#008888\");\n }\n };\n /**\n * Draw all vertices that were not yet drawn with the given render time.<br>\n * <br>\n * This function is usually only used internally.\n *\n * @method drawVertices\n * @private\n * @param {number} renderTime - The current render time. It is used to distinct\n * already draw vertices from non-draw-yet vertices.\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.drawVertices = function (renderTime, draw) {\n // Draw all vertices as small squares if they were not already drawn by other objects\n for (var i in this.vertices) {\n if (this.drawConfig.drawVertices && this.vertices[i].attr.renderTime != renderTime && this.vertices[i].attr.visible) {\n draw.setCurrentId(this.vertices[i].uid);\n draw.squareHandle(this.vertices[i], 5, this._handleColor(this.vertices[i], \"rgb(0,128,192)\"));\n this.vertices[i].attr.renderTime = renderTime;\n }\n }\n };\n /**\n * Trigger redrawing of all objects.<br>\n * <br>\n * Usually this function is automatically called when objects change.\n *\n * @method redraw\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.redraw = function () {\n var renderTime = this.renderTime++;\n // Tell the drawing library that a new drawing cycle begins (required for the GL lib).\n this.draw.beginDrawCycle(renderTime);\n this.fill.beginDrawCycle(renderTime);\n if (this.config.preClear)\n this.config.preClear();\n this.clear();\n if (this.config.preDraw)\n this.config.preDraw(this.draw, this.fill);\n this.drawAll(renderTime, this.draw, this.fill);\n if (this.config.postDraw)\n this.config.postDraw(this.draw, this.fill);\n this.draw.endDrawCycle(renderTime);\n this.fill.endDrawCycle(renderTime);\n };\n /**\n * Draw all: drawables, grid, select-polygon and vertices.\n *\n * @method drawAll\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.drawAll = function (renderTime, draw, fill) {\n if (this.config.drawRaster) {\n this.drawGrid(draw);\n }\n if (this.config.drawOrigin) {\n this.drawOrigin(draw);\n }\n this.drawDrawables(renderTime, draw, fill);\n this.drawVertices(renderTime, draw);\n this.drawSelectPolygon(draw);\n // Clear IDs and classnames (postDraw hook might draw somthing and the do not want\n // to interfered with that).\n draw.setCurrentId(null);\n draw.setCurrentClassName(null);\n }; // END redraw\n /**\n * This function clears the canvas with the configured background color.<br>\n * <br>\n * This function is usually only used internally.\n *\n * @method clear\n * @private\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.clear = function () {\n // Note that elements might have an alpha channel. Clear the scene first.\n this.draw.clear(this.config.backgroundColor || \"white\");\n };\n /**\n * Clear the selection.<br>\n * <br>\n * This function is usually only used internally.\n *\n * @method clearSelection\n * @private\n * @param {boolean=} [redraw=false] - Indicates if the redraw function should be triggered.\n * @instance\n * @memberof PlotBoilerplate\n * @return {PlotBoilerplate} this\n **/\n PlotBoilerplate.prototype.clearSelection = function (redraw) {\n for (var i in this.vertices)\n this.vertices[i].attr.isSelected = false;\n if (redraw)\n this.redraw();\n return this;\n };\n /**\n * Get the current view port.\n *\n * @method viewport\n * @instance\n * @memberof PlotBoilerplate\n * @return {Bounds} The current viewport.\n **/\n PlotBoilerplate.prototype.viewport = function () {\n var _b, _c;\n return new Bounds_1.Bounds(this.transformMousePosition(0, 0), this.transformMousePosition(this.canvasSize.width * ((_b = this.config.cssScaleX) !== null && _b !== void 0 ? _b : 1.0), this.canvasSize.height * ((_c = this.config.cssScaleY) !== null && _c !== void 0 ? _c : 1.0)));\n };\n /**\n * Trigger the saveFile.hook.\n *\n * @method saveFile\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.saveFile = function () {\n this.hooks.saveFile(this);\n };\n /**\n * Internal helper function used to get 'float' properties from elements.\n * Used to determine border withs and paddings that were defined using CSS.\n */\n // TODO: this was moved to the DOM utils\n PlotBoilerplate.prototype.getFProp = function (elem, propName) {\n return parseFloat(globalThis.getComputedStyle(elem, null).getPropertyValue(propName));\n };\n /**\n * Get the available inner space of the given container.\n *\n * Size minus padding minus border.\n **/\n // TODO: this was moved to the DOM utils\n PlotBoilerplate.prototype.getAvailableContainerSpace = function () {\n var container = this.canvas.parentNode; // Element | Document | DocumentFragment;\n this.canvas.style.display = \"none\";\n var padding = this.getFProp(container, \"padding\") || 0, border = this.getFProp(this.canvas, \"border-width\") || 0, pl = this.getFProp(container, \"padding-left\") || padding, pr = this.getFProp(container, \"padding-right\") || padding, pt = this.getFProp(container, \"padding-top\") || padding, pb = this.getFProp(container, \"padding-bottom\") || padding, bl = this.getFProp(this.canvas, \"border-left-width\") || border, br = this.getFProp(this.canvas, \"border-right-width\") || border, bt = this.getFProp(this.canvas, \"border-top-width\") || border, bb = this.getFProp(this.canvas, \"border-bottom-width\") || border;\n var w = container.clientWidth;\n var h = container.clientHeight;\n this.canvas.style.display = \"block\";\n return { width: w - pl - pr - bl - br, height: h - pt - pb - bt - bb };\n };\n /**\n * This function resizes the canvas to the required settings (toggles fullscreen).<br>\n * <br>\n * This function is usually only used internally but feel free to call it if resizing required.\n *\n * @method resizeCanvas\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.resizeCanvas = function () {\n var _this = this;\n var _b, _c, _d, _e, _f, _g;\n var _self = this;\n var _setSize = function (w, h) {\n var _b, _c;\n w *= (_b = _self.config.canvasWidthFactor) !== null && _b !== void 0 ? _b : 1.0;\n h *= (_c = _self.config.canvasHeightFactor) !== null && _c !== void 0 ? _c : 1.0;\n _self.canvasSize.width = w;\n _self.canvasSize.height = h;\n if (_self.canvas instanceof HTMLCanvasElement) {\n _self.canvas.width = w;\n _self.canvas.height = h;\n }\n else if (_self.canvas instanceof SVGElement) {\n _this.canvas.setAttribute(\"viewBox\", \"0 0 \".concat(w, \" \").concat(h));\n _this.canvas.setAttribute(\"width\", \"\".concat(w));\n _this.canvas.setAttribute(\"height\", \"\".concat(h));\n _this.draw.setSize(_self.canvasSize); // No need to set size to this.fill (instance copy)\n _this.eventCatcher.style.width = \"\".concat(w, \"px\");\n _this.eventCatcher.style.height = \"\".concat(h, \"px\");\n }\n else {\n console.error(\"Error: cannot resize canvas element because it seems neither be a HTMLCanvasElement nor an SVGElement.\");\n }\n if (_self.config.autoAdjustOffset) {\n // _self.draw.offset.x = _self.fill.offset.x = _self.config.offsetX = w*(_self.config.offsetAdjustXPercent/100);\n // _self.draw.offset.y = _self.fill.offset.y = _self.config.offsetY = h*(_self.config.offsetAdjustYPercent/100);\n _self.adjustOffset(false);\n }\n };\n if (_self.config.fullSize && !_self.config.fitToParent) {\n // Set editor size\n var width = globalThis.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n var height = globalThis.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;\n _self.canvas.style.position = \"absolute\";\n _self.canvas.style.width = ((_b = _self.config.canvasWidthFactor) !== null && _b !== void 0 ? _b : 1.0) * width + \"px\";\n _self.canvas.style.height = ((_c = _self.config.canvasWidthFactor) !== null && _c !== void 0 ? _c : 1.0) * height + \"px\";\n _self.canvas.style.top = \"0px\";\n _self.canvas.style.left = \"0px\";\n _setSize(width, height);\n }\n else if (_self.config.fitToParent) {\n // Set editor size\n _self.canvas.style.position = \"static\";\n var space = this.getAvailableContainerSpace();\n _self.canvas.style.width = ((_d = _self.config.canvasWidthFactor) !== null && _d !== void 0 ? _d : 1.0) * space.width + \"px\";\n _self.canvas.style.height = ((_e = _self.config.canvasHeightFactor) !== null && _e !== void 0 ? _e : 1.0) * space.height + \"px\";\n _self.canvas.style.top = \"\";\n _self.canvas.style.left = \"\";\n _setSize(space.width, space.height);\n }\n else {\n _self.canvas.style.width = \"\";\n _self.canvas.style.height = \"\";\n _setSize((_f = _self.config.defaultCanvasWidth) !== null && _f !== void 0 ? _f : 1024, (_g = _self.config.defaultCanvasHeight) !== null && _g !== void 0 ? _g : 768);\n }\n if (_self.config.redrawOnResize)\n _self.redraw();\n };\n /**\n * Add all vertices inside the polygon to the current selection.<br>\n *\n * @method selectVerticesInPolygon\n * @param {Polygon} polygon - The polygonal selection area.\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.selectVerticesInPolygon = function (polygon) {\n for (var i in this.vertices) {\n if (this.vertices[i].attr.selectable && polygon.containsVert(this.vertices[i]))\n this.vertices[i].attr.isSelected = true;\n }\n };\n /**\n * (Helper) Locates the point (index) at the passed position. Using an internal tolerance of 7 pixels.\n *\n * The result is an object { type : 'bpath', pindex, cindex, pid }\n *\n * Returns false if no point is near the passed position.\n *\n * @method locatePointNear\n * @param {Vertex} point - The polygonal selection area.\n * @param {number=} [tolerance=7] - The tolerance to use identtifying vertices.\n * @private\n * @return {IDraggable} Or false if none found.\n **/\n PlotBoilerplate.prototype.locatePointNear = function (point, tolerance) {\n var _self = this;\n if (typeof tolerance == \"undefined\")\n tolerance = 7;\n // Apply the zoom (the tolerant area should not shrink or grow when zooming)\n tolerance /= _self.draw.scale.x;\n // Search in vertices\n for (var vindex = 0; vindex < _self.vertices.length; vindex++) {\n var vert = _self.vertices[vindex];\n if ((vert.attr.draggable || vert.attr.selectable) && vert.distance(point) < tolerance) {\n // { type : 'vertex', vindex : vindex };\n return new PlotBoilerplate.Draggable(vert, PlotBoilerplate.Draggable.VERTEX).setVIndex(vindex);\n }\n }\n return null;\n };\n /**\n * Handle left-click event.<br>\n *\n * @method handleClick\n * @param {number} x - The click X position on the canvas.\n * @param {number} y - The click Y position on the canvas.\n * @private\n * @return {void}\n **/\n PlotBoilerplate.prototype.handleClick = function (e) {\n var _self = this;\n var point = this.locatePointNear(_self.transformMousePosition(e.params.pos.x, e.params.pos.y), PlotBoilerplate.DEFAULT_CLICK_TOLERANCE / Math.min(_self.config.cssScaleX || 1.0, _self.config.cssScaleY || 1.0));\n if (point) {\n _self.vertices[point.vindex].listeners.fireClickEvent(e);\n if (this.keyHandler && this.keyHandler.isDown(\"shift\")) {\n if (point.typeName == \"bpath\") {\n var vert = _self.paths[point.pindex].bezierCurves[point.cindex].getPointByID(point.pid);\n if (vert.attr.selectable)\n vert.attr.isSelected = !vert.attr.isSelected;\n }\n else if (point.typeName == \"vertex\") {\n var vert = _self.vertices[point.vindex];\n if (vert.attr.selectable)\n vert.attr.isSelected = !vert.attr.isSelected;\n }\n _self.redraw();\n }\n else if (this.keyHandler && this.keyHandler.isDown(\"y\")) {\n _self.vertices[point.vindex].attr.bezierAutoAdjust = !_self.vertices[point.vindex].attr.bezierAutoAdjust;\n _self.redraw();\n }\n }\n else if (_self.selectPolygon != null) {\n var vert = _self.transformMousePosition(e.params.pos.x, e.params.pos.y);\n _self.selectPolygon.vertices.push(new Vertex_1.Vertex(vert.x, vert.y));\n _self.redraw();\n }\n };\n /**\n * Transforms the given x-y-(mouse-)point to coordinates respecting the view offset\n * and the zoom settings.\n *\n * @method transformMousePosition\n * @param {number} x - The x position relative to the canvas.\n * @param {number} y - The y position relative to the canvas.\n * @instance\n * @memberof PlotBoilerplate\n * @return {XYCoords} A simple object <pre>{ x : Number, y : Number }</pre> with the transformed coordinates.\n **/\n PlotBoilerplate.prototype.transformMousePosition = function (x, y) {\n return {\n x: (x / this.config.cssScaleX - this.config.offsetX) / this.config.scaleX,\n y: (y / this.config.cssScaleY - this.config.offsetY) / this.config.scaleY\n };\n };\n /**\n * Revert a transformed mouse position back to canvas coordinates.\n *\n * This is the inverse function of `transformMousePosition`.\n *\n * @method revertMousePosition\n * @param {number} x - The x component of the position to revert.\n * @param {number} y - The y component of the position to revert.\n * @instance\n * @memberof PlotBoilerplate\n * @return {XYCoords} The canvas coordinates for the given position.\n **/\n PlotBoilerplate.prototype.revertMousePosition = function (x, y) {\n return { x: x / this.config.cssScaleX + this.config.offsetX, y: y / this.config.cssScaleY + this.config.offsetY };\n };\n /**\n * Determine if any elements are currently being dragged (on mouse move or touch move).\n *\n * @method getDraggedElementCount\n * @instance\n * @memberof PlotBoilerplate\n * @return {number} The number of elements that are currently being dragged.\n **/\n PlotBoilerplate.prototype.getDraggedElementCount = function () {\n return this.draggedElements.length;\n };\n /**\n * (Helper) The mouse-down handler.\n *\n * It selects vertices for dragging.\n *\n * @method mouseDownHandler.\n * @param {XMouseEvent} e - The event to handle\n * @private\n * @return {void}\n **/\n PlotBoilerplate.prototype.mouseDownHandler = function (e) {\n var _self = this;\n if (e.button != 0)\n return; // Only react on left mouse or touch events\n var draggablePoint = _self.locatePointNear(_self.transformMousePosition(e.params.pos.x, e.params.pos.y), PlotBoilerplate.DEFAULT_CLICK_TOLERANCE / Math.min(_self.config.cssScaleX, _self.config.cssScaleY));\n if (!draggablePoint)\n return;\n // Drag all selected elements?\n if (draggablePoint.typeName == \"vertex\" && _self.vertices[draggablePoint.vindex].attr.isSelected) {\n // Multi drag\n // for( var i in _self.vertices ) {\n for (var i = 0; i < _self.vertices.length; i++) {\n if (_self.vertices[i].attr.isSelected) {\n _self.draggedElements.push(new PlotBoilerplate.Draggable(_self.vertices[i], PlotBoilerplate.Draggable.VERTEX).setVIndex(i));\n _self.vertices[i].listeners.fireDragStartEvent(e);\n }\n }\n }\n else {\n // Single drag\n if (!_self.vertices[draggablePoint.vindex].attr.draggable)\n return;\n _self.draggedElements.push(draggablePoint);\n if (draggablePoint.typeName == \"bpath\")\n _self.paths[draggablePoint.pindex].bezierCurves[draggablePoint.cindex]\n .getPointByID(draggablePoint.pid)\n .listeners.fireDragStartEvent(e);\n else if (draggablePoint.typeName == \"vertex\")\n _self.vertices[draggablePoint.vindex].listeners.fireDragStartEvent(e);\n }\n _self.redraw();\n };\n /**\n * The mouse-drag handler.\n *\n * It moves selected elements around or performs the panning if the ctrl-key if\n * hold down.\n *\n * @method mouseDragHandler.\n * @param {XMouseEvent} e - The event to handle\n * @private\n * @return {void}\n **/\n PlotBoilerplate.prototype.mouseDragHandler = function (e) {\n var _self = this;\n var oldDragAmount = { x: e.params.dragAmount.x, y: e.params.dragAmount.y };\n e.params.dragAmount.x /= _self.config.cssScaleX;\n e.params.dragAmount.y /= _self.config.cssScaleY;\n // Important note to: this.keyHandler.isDown('ctrl')\n // We should not use this for any input.\n // Reason: most browsers use [Ctrl]+[t] to create new browser tabs.\n // If so, the key-up event for [Ctrl] will be fired in the _new tab_,\n // not this one. So this tab will never receive any [Ctrl-down] events\n // until next keypress; the implication is, that [Ctrl] would still\n // considered to be pressed which is not true.\n // if (this.keyHandler && (this.keyHandler.isDown(\"alt\") || this.keyHandler.isDown(\"spacebar\"))) {\n if (this.isInPanningMode) {\n if (!this.config.enablePan) {\n return;\n }\n _self.setOffset(_self.draw.offset.clone().add(e.params.dragAmount));\n _self.redraw();\n }\n else {\n // Convert drag amount by scaling\n // Warning: this possibly invalidates the dragEvent for other listeners!\n // Rethink the solution when other features are added.\n e.params.dragAmount.x /= _self.draw.scale.x;\n e.params.dragAmount.y /= _self.draw.scale.y;\n for (var i in _self.draggedElements) {\n var p = _self.draggedElements[i];\n if (p.typeName == \"bpath\") {\n _self.paths[p.pindex].moveCurvePoint(p.cindex, p.pid, new Vertex_1.Vertex(e.params.dragAmount.x, e.params.dragAmount.y));\n _self.paths[p.pindex].bezierCurves[p.cindex].getPointByID(p.pid).listeners.fireDragEvent(e);\n }\n else if (p.typeName == \"vertex\") {\n if (!_self.vertices[p.vindex].attr.draggable)\n continue;\n _self.vertices[p.vindex].add(e.params.dragAmount);\n _self.vertices[p.vindex].listeners.fireDragEvent(e);\n }\n }\n }\n // Restore old event values!\n e.params.dragAmount.x = oldDragAmount.x;\n e.params.dragAmount.y = oldDragAmount.y;\n _self.redraw();\n };\n /**\n * The mouse-up handler.\n *\n * It clears the dragging-selection.\n *\n * @method mouseUpHandler.\n * @param {XMouseEvent} e - The event to handle\n * @private\n * @return {void}\n **/\n PlotBoilerplate.prototype.mouseUpHandler = function (e) {\n var _self = this;\n if (e.button != 0)\n return; // Only react on left mouse;\n if (!e.params.wasDragged) {\n _self.handleClick(e); // e.params.pos.x, e.params.pos.y );\n }\n for (var i in _self.draggedElements) {\n var p = _self.draggedElements[i];\n if (p.typeName == \"bpath\") {\n _self.paths[p.pindex].bezierCurves[p.cindex].getPointByID(p.pid).listeners.fireDragEndEvent(e);\n }\n else if (p.typeName == \"vertex\") {\n _self.vertices[p.vindex].listeners.fireDragEndEvent(e);\n }\n }\n _self.draggedElements = [];\n _self.redraw();\n };\n /**\n * The mouse-wheel handler.\n *\n * It performs the zooming.\n *\n * @method mouseWheelHandler.\n * @param {XMouseEvent} e - The event to handle\n * @private\n * @return {void}\n **/\n PlotBoilerplate.prototype.mouseWheelHandler = function (e) {\n if (!this.config.enableZoom) {\n return;\n }\n var zoomStep = 1.25; // Make configurable?\n // CHANGED replaced _self by this\n var _self = this;\n var we = e;\n if (we.deltaY < 0) {\n _self.setZoom(_self.config.scaleX * zoomStep, _self.config.scaleY * zoomStep, new Vertex_1.Vertex(e.params.pos.x, e.params.pos.y));\n }\n else if (we.deltaY > 0) {\n _self.setZoom(_self.config.scaleX / zoomStep, _self.config.scaleY / zoomStep, new Vertex_1.Vertex(e.params.pos.x, e.params.pos.y));\n }\n e.preventDefault();\n _self.redraw();\n };\n /**\n * Re-adjust the configured offset depending on the current canvas size and zoom (scaleX and scaleY).\n *\n * @method adjustOffset\n * @param {boolean=false} redraw - [optional] If set the canvas will redraw with the new offset (default=false).\n * @return {void}\n **/\n PlotBoilerplate.prototype.adjustOffset = function (redraw) {\n this.draw.offset.x =\n this.fill.offset.x =\n this.config.offsetX =\n this.canvasSize.width * (this.config.offsetAdjustXPercent / 100);\n this.draw.offset.y =\n this.fill.offset.y =\n this.config.offsetY =\n this.canvasSize.height * (this.config.offsetAdjustYPercent / 100);\n if (redraw) {\n this.redraw();\n }\n };\n /**\n * Set the new draw offset.\n *\n * Note: the function will not trigger any redraws.\n *\n * @param {Vertex} newOffset - The new draw offset to use.\n **/\n PlotBoilerplate.prototype.setOffset = function (newOffset) {\n this.draw.offset.set(newOffset);\n this.fill.offset.set(newOffset);\n this.config.offsetX = newOffset.x;\n this.config.offsetY = newOffset.y;\n };\n /**\n * Set a new zoom value (and re-adjust the draw offset).\n *\n * Note: the function will not trigger any redraws.\n *\n * @param {number} zoomFactorX - The new horizontal zoom value.\n * @param {number} zoomFactorY - The new vertical zoom value.\n * @param {Vertex} interactionPos - The position of mouse/touch interaction.\n **/\n PlotBoilerplate.prototype.setZoom = function (zoomFactorX, zoomFactorY, interactionPos) {\n var oldPos = this.transformMousePosition(interactionPos.x, interactionPos.y);\n this.draw.scale.x = this.fill.scale.x = this.config.scaleX = Math.max(zoomFactorX, 0.01);\n this.draw.scale.y = this.fill.scale.y = this.config.scaleY = Math.max(zoomFactorY, 0.01);\n var newPos = this.transformMousePosition(interactionPos.x, interactionPos.y);\n var newOffsetX = this.draw.offset.x + (newPos.x - oldPos.x) * this.draw.scale.x;\n var newOffsetY = this.draw.offset.y + (newPos.y - oldPos.y) * this.draw.scale.y;\n this.setOffset({ x: newOffsetX, y: newOffsetY });\n };\n PlotBoilerplate.prototype.installInputListeners = function () {\n var _this = this;\n var _self = this;\n if (this.config.enableMouse) {\n // Install a mouse handler on the canvas.\n new MouseHandler_1.MouseHandler(this.eventCatcher ? this.eventCatcher : this.canvas)\n .down(function (e) {\n _self.mouseDownHandler(e);\n })\n .drag(function (e) {\n _self.mouseDragHandler(e);\n })\n .up(function (e) {\n _self.mouseUpHandler(e);\n });\n }\n else {\n _self.console.log(\"Mouse interaction disabled.\");\n }\n if (this.config.enableMouseWheel) {\n // Install a mouse handler on the canvas.\n new MouseHandler_1.MouseHandler(this.eventCatcher ? this.eventCatcher : this.canvas).wheel(function (e) {\n _self.mouseWheelHandler(e);\n });\n }\n else {\n _self.console.log(\"Mouse wheel interaction disabled.\");\n }\n if (this.config.enableTouch) {\n // Install a touch handler on the canvas.\n var relPos_1 = function (pos) {\n var bounds = _self.canvas.getBoundingClientRect();\n return { x: pos.x - bounds.left, y: pos.y - bounds.top };\n };\n // Make PB work together with both, AlloyFinger as a esm module or a commonjs function.\n if (typeof globalThis[\"AlloyFinger\"] === \"function\" ||\n typeof globalThis[\"createAlloyFinger\"] === \"function\") {\n try {\n var touchMovePos = null;\n var touchDownPos = null;\n var draggedElement = null;\n var multiTouchStartScale = null;\n var clearTouch_1 = function () {\n touchMovePos = null;\n touchDownPos = null;\n draggedElement = null;\n multiTouchStartScale = null;\n _self.draggedElements = [];\n };\n var afProps = {\n // touchStart: (evt: TouchEvent) => {\n touchStart: function (evt) {\n if (evt.touches.length == 1) {\n touchMovePos = new Vertex_1.Vertex(relPos_1({ x: evt.touches[0].clientX, y: evt.touches[0].clientY }));\n touchDownPos = new Vertex_1.Vertex(relPos_1({ x: evt.touches[0].clientX, y: evt.touches[0].clientY }));\n draggedElement = _self.locatePointNear(_self.transformMousePosition(touchMovePos.x, touchMovePos.y), PlotBoilerplate.DEFAULT_TOUCH_TOLERANCE / Math.min(_self.config.cssScaleX, _self.config.cssScaleY));\n if (draggedElement && draggedElement.typeName == \"vertex\") {\n var draggingVertex = _self.vertices[draggedElement.vindex];\n var fakeEvent = {\n params: {\n isTouchEvent: true,\n dragAmount: { x: 0, y: 0 },\n wasDragged: false,\n mouseDownPos: touchDownPos.clone(),\n mouseDragPos: touchDownPos.clone(),\n vertex: draggingVertex\n }\n };\n _self.draggedElements = [draggedElement];\n draggingVertex.listeners.fireDragStartEvent(fakeEvent);\n }\n }\n },\n touchMove: function (evt) {\n if (evt.touches.length == 1 && draggedElement) {\n evt.preventDefault();\n evt.stopPropagation();\n if (!touchDownPos || !touchMovePos) {\n return;\n }\n var rel = relPos_1({ x: evt.touches[0].clientX, y: evt.touches[0].clientY });\n var trans = _self.transformMousePosition(rel.x, rel.y);\n var diff = new Vertex_1.Vertex(_self.transformMousePosition(touchMovePos.x, touchMovePos.y)).difference(trans);\n if (draggedElement.typeName == \"vertex\") {\n if (!_self.vertices[draggedElement.vindex].attr.draggable)\n return;\n _self.vertices[draggedElement.vindex].add(diff);\n var draggingVertex = _self.vertices[draggedElement.vindex];\n var fakeEvent = {\n isTouchEvent: true,\n params: {\n dragAmount: diff.clone(),\n wasDragged: true,\n mouseDownPos: touchDownPos.clone(),\n mouseDragPos: touchDownPos.clone().add(diff),\n vertex: draggingVertex\n }\n };\n draggingVertex.listeners.fireDragEvent(fakeEvent);\n _self.redraw();\n }\n touchMovePos = new Vertex_1.Vertex(rel);\n }\n else if (evt.touches.length == 2) {\n if (!_this.config.enablePan) {\n return;\n }\n // If at least two fingers touch and move, then change the draw offset (panning).\n evt.preventDefault();\n evt.stopPropagation();\n _self.setOffset(_self.draw.offset\n .clone()\n .addXY(evt.deltaX, evt.deltaY)); // Apply zoom?\n _self.redraw();\n }\n },\n touchEnd: function (evt) {\n // Note: e.touches.length is 0 here\n if (draggedElement && draggedElement.typeName == \"vertex\") {\n if (!touchDownPos) {\n return;\n }\n var draggingVertex = _self.vertices[draggedElement.vindex];\n var fakeEvent = {\n isTouchEvent: true,\n params: {\n dragAmount: { x: 0, y: 0 },\n wasDragged: false,\n mouseDownPos: touchDownPos.clone(),\n mouseDragPos: touchDownPos.clone(),\n vertex: draggingVertex\n }\n };\n // Check if vertex was moved\n if (touchMovePos && touchDownPos && touchDownPos.distance(touchMovePos) < 0.001) {\n // if( e.touches.length == 1 && diff.x == 0 && diff.y == 0 ) {\n draggingVertex.listeners.fireClickEvent(fakeEvent);\n }\n else {\n draggingVertex.listeners.fireDragEndEvent(fakeEvent);\n }\n }\n clearTouch_1();\n },\n touchCancel: function (evt) {\n clearTouch_1();\n },\n multipointStart: function (evt) {\n multiTouchStartScale = _self.draw.scale.clone();\n },\n multipointEnd: function (evt) {\n multiTouchStartScale = null;\n },\n pinch: function (evt) {\n if (!_this.config.enableZoom) {\n return;\n }\n var touchItem0 = evt.touches.item(0);\n var touchItem1 = evt.touches.item(1);\n if (!evt.touches || !multiTouchStartScale || !touchItem0 || !touchItem1) {\n return;\n }\n // For pinching there must be at least two touch items\n var fingerA = new Vertex_1.Vertex(touchItem0.clientX, touchItem0.clientY);\n var fingerB = new Vertex_1.Vertex(touchItem1.clientX, touchItem1.clientY);\n var center = new Line_1.Line(fingerA, fingerB).vertAt(0.5);\n _self.setZoom(multiTouchStartScale.x * evt.zoom, multiTouchStartScale.y * evt.zoom, center);\n _self.redraw();\n }\n }; // END afProps\n if (window[\"createAlloyFinger\"]) {\n // window[\"createAlloyFinger\"](this.eventCatcher ? this.eventCatcher : this.canvas, afProps);\n var createAlloyFinger = window[\"createAlloyFinger\"];\n createAlloyFinger(this.eventCatcher ? this.eventCatcher : this.canvas, afProps);\n }\n else {\n /* tslint:disable-next-line */\n new alloyfinger_typescript_1.default(this.eventCatcher ? this.eventCatcher : this.canvas, afProps);\n }\n }\n catch (e) {\n console.error(\"Failed to initialize AlloyFinger!\");\n console.error(e);\n }\n }\n else if (globalThis[\"Touchy\"] && typeof globalThis[\"Touchy\"] == \"function\") {\n console.error(\"[Deprecation] Found Touchy which is not supported any more. Please use AlloyFinger instead.\");\n // Convert absolute touch positions to relative DOM element position (relative to canvas)\n }\n else {\n console.warn(\"Cannot initialize the touch handler. AlloyFinger is missig. Did you include it?\");\n }\n }\n else {\n _self.console.log(\"Touch interaction disabled.\");\n }\n if (this.config.enableKeys) {\n // Install key handler\n this.keyHandler = new KeyHandler_1.KeyHandler({ trackAll: true })\n .down(\"escape\", function () {\n _self.clearSelection(true);\n })\n .down(\"shift\", function () {\n _self.selectPolygon = new Polygon_1.Polygon();\n _self.redraw();\n })\n .up(\"shift\", function () {\n // Find and select vertices in the drawn area\n if (_self.selectPolygon == null)\n return;\n _self.selectVerticesInPolygon(_self.selectPolygon);\n _self.selectPolygon = null;\n _self.redraw();\n })\n .down(\"alt\", function () {\n _self.isInPanningMode = true;\n })\n .up(\"alt\", function () {\n _self.isInPanningMode = false;\n })\n .down(\"spacebar\", function () {\n _self.isInPanningMode = true;\n })\n .up(\"spacebar\", function () {\n _self.isInPanningMode = false;\n });\n } // END IF enableKeys?\n else {\n _self.console.log(\"Keyboard interaction disabled.\");\n }\n };\n /**\n * Creates a control GUI (a dat.gui instance) for this\n * plot boilerplate instance.\n *\n * @method createGUI\n * @instance\n * @memberof PlotBoilerplate\n * @return {dat.gui.GUI}\n **/\n PlotBoilerplate.prototype.createGUI = function (props) {\n // This function moved to the helper utils.\n // We do not want to include the whole dat.GUI package.\n var utils = globalThis[\"utils\"];\n // if (globalThis[\"utils\"] && typeof globalThis[\"utils\"].createGUI == \"function\") {\n // return (globalThis[\"utils\" as keyof Object] as any as ({createGUI : (pb:PlotBoilerplate,props:DatGuiProps|undefined)=>GUI })).createGUI(this, props);\n if (utils && typeof utils.createGUI === \"function\") {\n return (this._gui = utils.createGUI(this, props));\n }\n else {\n throw \"Cannot create dat.GUI or lil-gui instance; did you load the ./utils/creategui helper function an the dat.GUI/lil-gui library?\";\n }\n };\n /**\n * Retriebe the GUI once it was created. If the `createGUI` method was not called or failed to create any\n * GUI then null is returned.\n * @returns {GUI | null}\n */\n PlotBoilerplate.prototype.getGUI = function () {\n return this._gui;\n };\n var _a;\n /** @constant {number} */\n PlotBoilerplate.DEFAULT_CANVAS_WIDTH = 1024;\n /** @constant {number} */\n PlotBoilerplate.DEFAULT_CANVAS_HEIGHT = 768;\n /** @constant {number} */\n PlotBoilerplate.DEFAULT_CLICK_TOLERANCE = 8;\n /** @constant {number} */\n PlotBoilerplate.DEFAULT_TOUCH_TOLERANCE = 32;\n /**\n * A wrapper class for draggable items (mostly vertices).\n * @private\n **/\n PlotBoilerplate.Draggable = (_a = /** @class */ (function () {\n function class_1(item, typeName) {\n this.item = item;\n this.typeName = typeName;\n }\n class_1.prototype.isVertex = function () {\n return this.typeName == PlotBoilerplate.Draggable.VERTEX;\n };\n class_1.prototype.setVIndex = function (vindex) {\n this.vindex = vindex;\n return this;\n };\n return class_1;\n }()),\n __setFunctionName(_a, \"Draggable\"),\n _a.VERTEX = \"vertex\",\n _a);\n /**\n * A set of helper functions.\n **/\n PlotBoilerplate.utils = {\n /**\n * Merge the elements in the 'extension' object into the 'base' object based on\n * the keys of 'base'.\n *\n * @param {Object} base\n * @param {Object} extension\n * @return {Object} base extended by the new attributes.\n **/\n safeMergeByKeys: function (base, extension) {\n for (var k in extension) {\n if (!extension.hasOwnProperty(k)) {\n continue;\n }\n if (base.hasOwnProperty(k)) {\n var typ = typeof base[k];\n var extVal = extension[k];\n try {\n if (typ == \"boolean\") {\n if (typeof extVal === \"string\")\n base[k] = Boolean(!!JSON.parse(extVal));\n else\n base[k] = extVal;\n }\n else if (typ == \"number\") {\n if (typeof extVal === \"string\")\n base[k] = Number(JSON.parse(extVal) * 1);\n else\n base[k] = extension[k];\n }\n else if (typ == \"function\" && typeof extVal == \"function\") {\n base[k] = extension[k];\n }\n else {\n // Probably a sting\n base[k] = extension[k];\n }\n }\n catch (e) {\n console.error(\"error in key \", k, extVal, e);\n }\n }\n else {\n base[k] = extension[k];\n }\n }\n return base;\n },\n /*\n __safeMergeByKeys: <KeyType extends string | number | symbol, ValueType extends boolean | number | string | Function>(\n base: Record<KeyType, ValueType>,\n extension: Record<KeyType, string>\n ): Record<KeyType, ValueType> => {\n for (var k in extension) {\n if (!extension.hasOwnProperty(k)) continue;\n if (base.hasOwnProperty(k)) {\n var typ = typeof base[k];\n try {\n if (typ == \"boolean\") base[k] = !!JSON.parse(extension[k]);\n else if (typ == \"number\") base[k] = JSON.parse(extension[k]) * 1;\n else if (typ == \"function\" && typeof extension[k] == \"function\") base[k] = extension[k];\n else base[k] = extension[k];\n } catch (e) {\n console.error(\"error in key \", k, extension[k], e);\n }\n } else {\n base[k] = extension[k];\n }\n }\n return base;\n },\n *()\n \n /**\n * A helper function to scale elements (usually the canvas) using CSS.\n *\n * transform-origin is at (0,0).\n *\n * @param {HTMLElement} element - The DOM element to scale.\n * @param {number} scaleX The - X scale factor.\n * @param {number} scaleY The - Y scale factor.\n * @return {void}\n **/\n setCSSscale: function (element, scaleX, scaleY) {\n // element.style[\"transform-origin\"] = \"0 0\";\n element.style.transformOrigin = \"0 0\";\n if (scaleX == 1.0 && scaleY == 1.0) {\n // element.style.transform = null;\n element.style.removeProperty(\"transform\");\n }\n else\n element.style.transform = \"scale(\" + scaleX + \",\" + scaleY + \")\";\n },\n // A helper for fetching data from objects.\n fetch: {\n /**\n * A helper function to the the object property value specified by the given key.\n *\n * @param {any} object - The object to get the property's value from. Must not be null.\n * @param {string} key - The key of the object property (the name).\n * @param {any} fallback - A default value if the key does not exist.\n **/\n val: function (obj, key, fallback) {\n if (!obj.hasOwnProperty(key))\n return fallback;\n if (typeof obj[key] == \"undefined\")\n return fallback;\n return obj[key];\n },\n /**\n * A helper function to the the object property numeric value specified by the given key.\n *\n * @param {any} object - The object to get the property's value from. Must not be null.\n * @param {string} key - The key of the object property (the name).\n * @param {number} fallback - A default value if the key does not exist.\n * @return {number}\n **/\n num: function (obj, key, fallback) {\n if (!obj.hasOwnProperty(key))\n return fallback;\n if (typeof obj[key] === \"number\")\n return obj[key];\n else {\n try {\n return JSON.parse(obj[key]) * 1;\n }\n catch (e) {\n return fallback;\n }\n }\n },\n /**\n * A helper function to the the object property boolean value specified by the given key.\n *\n * @param {any} object - The object to get the property's value from. Must not be null.\n * @param {string} key - The key of the object property (the name).\n * @param {boolean} fallback - A default value if the key does not exist.\n * @return {boolean}\n **/\n bool: function (obj, key, fallback) {\n if (!obj.hasOwnProperty(key))\n return fallback;\n if (typeof obj[key] == \"boolean\")\n return obj[key];\n else {\n try {\n return !!JSON.parse(obj[key]);\n }\n catch (e) {\n return fallback;\n }\n }\n },\n /**\n * A helper function to the the object property function-value specified by the given key.\n *\n * @param {any} object - The object to get the property's value from. Must not be null.\n * @param {string} key - The key of the object property (the name).\n * @param {function} fallback - A default value if the key does not exist.\n * @return {function}\n **/\n func: function (obj, key, fallback) {\n if (!obj.hasOwnProperty(key))\n return fallback;\n if (typeof obj[key] !== \"function\")\n return fallback;\n return obj[key];\n }\n }, // END fetch\n /**\n * Installs vertex listeners to the path's vertices so that controlpoints\n * move with their path points when dragged.\n *\n * Bézier path points with attr.bezierAutoAdjust==true will have their\n * two control points audo-updated if moved, too (keep path connections smooth).\n *\n * @param {BezierPath} bezierPath - The path to use auto-adjustment for.\n **/\n enableBezierPathAutoAdjust: function (bezierPath) {\n for (var i = 0; i < bezierPath.bezierCurves.length; i++) {\n // This should be wrapped into the BezierPath implementation.\n bezierPath.bezierCurves[i].startPoint.listeners.addDragListener(function (e) {\n var cindex = bezierPath.locateCurveByStartPoint(e.params.vertex);\n bezierPath.bezierCurves[cindex].startPoint.addXY(-e.params.dragAmount.x, -e.params.dragAmount.y);\n bezierPath.moveCurvePoint(cindex * 1, bezierPath.START_POINT, e.params.dragAmount);\n bezierPath.updateArcLengths();\n });\n bezierPath.bezierCurves[i].startControlPoint.listeners.addDragListener(function (e) {\n var cindex = bezierPath.locateCurveByStartControlPoint(e.params.vertex);\n if (!bezierPath.bezierCurves[cindex].startPoint.attr.bezierAutoAdjust)\n return;\n bezierPath.adjustPredecessorControlPoint(cindex * 1, true, // obtain handle length?\n false // update arc lengths\n );\n bezierPath.updateArcLengths();\n });\n bezierPath.bezierCurves[i].endControlPoint.listeners.addDragListener(function (e) {\n var cindex = bezierPath.locateCurveByEndControlPoint(e.params.vertex);\n if (!bezierPath.bezierCurves[cindex % bezierPath.bezierCurves.length].endPoint.attr.bezierAutoAdjust)\n return;\n bezierPath.adjustSuccessorControlPoint(cindex * 1, true, // obtain handle length?\n false // update arc lengths\n );\n bezierPath.updateArcLengths();\n });\n if (i + 1 == bezierPath.bezierCurves.length) {\n // && !bezierPath.adjustCircular ) {\n // Move last control point with the end point (if not circular)\n bezierPath.bezierCurves[bezierPath.bezierCurves.length - 1].endPoint.listeners.addDragListener(function (e) {\n if (!bezierPath.adjustCircular) {\n var cindex = bezierPath.locateCurveByEndPoint(e.params.vertex);\n bezierPath.moveCurvePoint(cindex * 1, bezierPath.END_CONTROL_POINT, new Vertex_1.Vertex({ x: e.params.dragAmount.x, y: e.params.dragAmount.y }));\n }\n bezierPath.updateArcLengths();\n });\n }\n } // END for\n }\n }; // END utils\n return PlotBoilerplate;\n}()); // END class PlotBoilerplate\nexports.PlotBoilerplate = PlotBoilerplate;\nexports.default = PlotBoilerplate;\n//# sourceMappingURL=PlotBoilerplate.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2020-03-24\n * @modified 2020-05-04 Fixed a serious bug in the pointDistance function.\n * @modified 2020-05-12 The angle(line) param was still not optional. Changed that.\n * @modified 2020-11-11 Generalized the `add` and `sub` param from `Vertex` to `XYCoords`.\n * @modified 2020-12-04 Changed`vtutils.dist2` params from `Vertex` to `XYCoords` (generalized).\n * @modified 2020-12-04 Changed `getClosestT` param from `Vertex` to `XYCoords` (generalized).\n * @modified 2020-12-04 Added the `hasPoint(XYCoords)` function.\n * @modified 2021-01-20 Added UID.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2023-09-29 Fixed a calculation error in the VertTuple.hasPoint() function; distance measure was broken!\n * @modified 2024-09-10 Chaging the first param of `pointDistance` from `Vertex` to less strict type `XYCoords`. This should not break anything.\n * @modified 2024-09-10 Adding the optional `epsilon` param to the `hasPoint` method.\n * @modified 2024-12-02 Added the `epsilon` param to the `colinear` method. Default is 1.0e-6.\n * @modified 2025-03-31 Added the `VertTuple.revert` method.\n * @modified 2025-04-15 Changed param of `VertTuple.moveTo` method from `Vertex` to `XYCoords`.\n * @modified 2025-04-15 Added method `VertTuple.move` method.\n * @modified 2026-06-10 Adding helper function `VertTuple.utils.calcCircumcircle`.\n * @version 1.5.0\n */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.VertTuple = void 0;\nvar Vertex_1 = require(\"./Vertex\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\n/**\n * @classdesc An abstract base classes for vertex tuple constructs, like Lines or Vectors.\n * @abstract\n * @requires UID\n * @requires Vertex\n * @requires XYCoords\n */\nvar VertTuple = /** @class */ (function () {\n /**\n * Creates an instance.\n *\n * @constructor\n * @name VertTuple\n * @param {Vertex} a The tuple's first point.\n * @param {Vertex} b The tuple's second point.\n **/\n function VertTuple(a, b, factory) {\n this.uid = UIDGenerator_1.UIDGenerator.next();\n this.a = a;\n this.b = b;\n this.factory = factory;\n }\n /**\n * Get the length of this line.\n *\n * @method length\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.length = function () {\n return Math.sqrt(Math.pow(this.b.x - this.a.x, 2) + Math.pow(this.b.y - this.a.y, 2));\n };\n /**\n * Set the length of this vector to the given amount. This only works if this\n * vector is not a null vector.\n *\n * @method setLength\n * @param {number} length - The desired length.\n * @memberof VertTuple\n * @return {T} this (for chaining)\n **/\n VertTuple.prototype.setLength = function (length) {\n return this.scale(length / this.length());\n };\n /**\n * Substract the given vertex from this line's end points.\n *\n * @method sub\n * @param {XYCoords} amount The amount (x,y) to substract.\n * @return {VertTuple} this\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.sub = function (amount) {\n this.a.sub(amount);\n this.b.sub(amount);\n return this;\n };\n /**\n * Add the given vertex to this line's end points.\n *\n * @method add\n * @param {XYCoords} amount The amount (x,y) to add.\n * @instance\n * @memberof VertTuple\n * @return {VertTuple<T>} this\n **/\n VertTuple.prototype.add = function (amount) {\n this.a.add(amount);\n this.b.add(amount);\n return this;\n };\n /**\n * Reverse this vertex tuple: a becomes b, and b becomes a.\n * This operation is in-place.\n *\n * @method add\n * @param {XYCoords} amount The amount (x,y) to add.\n * @instance\n * @memberof VertTuple\n * @return {VertTuple<T>} this\n */\n VertTuple.prototype.revert = function () {\n var tmp = this.a;\n this.a = this.b;\n this.b = tmp;\n return this;\n };\n /**\n * Normalize this line (set to length 1).\n *\n * @method normalize\n * @return {VertTuple} this\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.normalize = function () {\n this.b.set(this.a.x + (this.b.x - this.a.x) / this.length(), this.a.y + (this.b.y - this.a.y) / this.length());\n return this;\n };\n /**\n * Scale this line by the given factor.\n *\n * @method scale\n * @param {number} factor The factor for scaling (1.0 means no scale).\n * @return {VertTuple} this\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.scale = function (factor) {\n this.b.set(this.a.x + (this.b.x - this.a.x) * factor, this.a.y + (this.b.y - this.a.y) * factor);\n return this;\n };\n /**\n * Move this line to a new location.\n *\n * @method moveTo\n * @param {XYCoords} newA - The new desired location of 'a'. Vertex 'b' will be moved, too.\n * @return {VertTuple} this\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.moveTo = function (newA) {\n var diff = this.a.difference(newA);\n this.a.add(diff);\n this.b.add(diff);\n return this;\n };\n /**\n * Move this line by the given amount\n *\n * @method move\n * @param {XYCoords} amount - The amount to move both point of this tuple.\n * @return {VertTuple} this\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.move = function (amount) {\n this.a.add(amount);\n this.b.add(amount);\n return this;\n };\n /**\n * Get the angle between this and the passed line (in radians).\n *\n * @method angle\n * @param {VertTuple} line - (optional) The line to calculate the angle to. If null the baseline (x-axis) will be used.\n * @return {number} this\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.angle = function (line) {\n if (line == null || typeof line == \"undefined\") {\n line = this.factory(new Vertex_1.Vertex(0, 0), new Vertex_1.Vertex(100, 0));\n }\n // Compute the angle from x axis and the return the difference :)\n var v0 = this.b.clone().sub(this.a);\n var v1 = line.b.clone().sub(line.a);\n // Thank you, Javascript, for this second atan function. No additional math is needed here!\n // The result might be negative, but isn't it usually nicer to determine angles in positive values only?\n return Math.atan2(v1.x, v1.y) - Math.atan2(v0.x, v0.y);\n };\n /**\n * Get line point at position t in [0 ... 1]:<br>\n * <pre>[P(0)]=[A]--------------------[P(t)]------[B]=[P(1)]</pre><br>\n * <br>\n * The counterpart of this function is Line.getClosestT(Vertex).\n *\n * @method vertAt\n * @param {number} t The position scalar.\n * @return {Vertex} The vertex a position t.\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.vertAt = function (t) {\n return new Vertex_1.Vertex(this.a.x + (this.b.x - this.a.x) * t, this.a.y + (this.b.y - this.a.y) * t);\n };\n /**\n * Get the denominator of this and the given line.\n *\n * If the denominator is zero (or close to zero) both line are co-linear.\n *\n * @method denominator\n * @param {VertTuple} line\n * @instance\n * @memberof VertTuple\n * @return {Number}\n **/\n VertTuple.prototype.denominator = function (line) {\n // http://jsfiddle.net/justin_c_rounds/Gd2S2/\n return (line.b.y - line.a.y) * (this.b.x - this.a.x) - (line.b.x - line.a.x) * (this.b.y - this.a.y);\n };\n /**\n * Checks if this and the given line are co-linear.\n *\n * The constant Vertex.EPSILON is used for tolerance.\n *\n * @method colinear\n * @param {VertTuple} line\n * @param {epsilon?=1.0e-6} epsilon - The epsilon to use (default is 1.0e-6).\n * @instance\n * @memberof VertTuple\n * @return true if both lines are co-linear.\n */\n VertTuple.prototype.colinear = function (line, epsilon) {\n return Math.abs(this.denominator(line)) < (typeof epsilon === \"undefined\" ? Vertex_1.Vertex.EPSILON : epsilon);\n };\n /**\n * Get the closest position T from this line to the specified point.\n *\n * The counterpart for this function is Line.vertAt(Number).\n *\n * @name getClosetT\n * @method getClosestT\n * @param {XYCoords} p The point (vertex) to measure the distance to.\n * @return {number} The line position t of minimal distance to p.\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.getClosestT = function (p) {\n var l2 = VertTuple.vtutils.dist2(this.a, this.b);\n if (l2 === 0)\n return 0;\n var t = ((p.x - this.a.x) * (this.b.x - this.a.x) + (p.y - this.a.y) * (this.b.y - this.a.y)) / l2;\n // Do not wrap to [0,1] here.\n // Other results are of interest, too.\n // t = Math.max(0, Math.min(1, t));\n return t;\n };\n /**\n * Check if the given point is located on this line. Optionally also check if\n * that point is located between point `a` and `b`.\n *\n * @method hasPoint\n * @param {Vertex} point - The point to check.\n * @param {boolean=} insideBoundsOnly - [optional] If set to to true (default=false) the point must be between start and end point of the line.\n * @param {number=Vertex.EPSILON} epsilon - [optional] A tolerance.\n * @return {boolean} True if the given point is on this line.\n * @instance\n * @memberof VertTuple\n */\n VertTuple.prototype.hasPoint = function (point, insideBoundsOnly, epsilon) {\n var t = this.getClosestT(point);\n // Compare to pointDistance?\n var distance = Math.sqrt(VertTuple.vtutils.dist2(point, this.vertAt(t)));\n if (typeof insideBoundsOnly !== \"undefined\" && insideBoundsOnly) {\n return distance < (epsilon !== null && epsilon !== void 0 ? epsilon : Vertex_1.Vertex.EPSILON) && t >= 0 && t <= 1;\n }\n else {\n return distance < (epsilon !== null && epsilon !== void 0 ? epsilon : Vertex_1.Vertex.EPSILON); // t >= 0 && t <= 1;\n }\n };\n /**\n * Get the closest point on this line to the specified point.\n *\n * @method getClosestPoint\n * @param {Vertex} p The point (vertex) to measre the distance to.\n * @return {Vertex} The point on the line that is closest to p.\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.getClosestPoint = function (p) {\n var t = this.getClosestT(p);\n return this.vertAt(t);\n };\n /**\n * The the minimal distance between this line and the specified point.\n *\n * @method pointDistance\n * @param {XYCoords} p The point (vertex) to measre the distance to.\n * @return {number} The absolute minimal distance.\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.pointDistance = function (p) {\n // Taken From:\n // https://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment\n return Math.sqrt(VertTuple.vtutils.dist2(p, this.vertAt(this.getClosestT(p))));\n };\n /**\n * Create a deep clone of this instance.\n *\n * @method cloneLine\n * @return {T} A type safe clone if this instance.\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.clone = function () {\n return this.factory(this.a.clone(), this.b.clone());\n };\n /**\n * Create a string representation of this line.\n *\n * @method totring\n * @return {string} The string representing this line.\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.toString = function () {\n return \"{ a : \" + this.a.toString() + \", b : \" + this.b.toString() + \" }\";\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n VertTuple.prototype.destroy = function () {\n this.a.destroy();\n this.b.destroy();\n this.isDestroyed = true;\n };\n /**\n * @private\n **/\n VertTuple.vtutils = {\n dist2: function (v, w) {\n return (v.x - w.x) * (v.x - w.x) + (v.y - w.y) * (v.y - w.y);\n },\n calcCircumcircle: function (p1, p2) {\n var p1x = p1.x, p1y = p1.y, p2x = p2.x, p2y = p2.y, cx = 0.5 * (p1x + p2x), cy = 0.5 * (p1y + p2y);\n return { center: { x: cx, y: cy }, radius: Math.sqrt((p1x - cx) * (p1x - cx) + (p1y - cy) * (p1y - cy)) };\n }\n };\n return VertTuple;\n}());\nexports.VertTuple = VertTuple;\n//# sourceMappingURL=VertTuple.js.map","/* Port from AlloyFinger v0.1.15\n * Original by dntzhang\n * Typescript port by Ikaros Kappler\n * Github: https://github.com/IkarosKappler/AlloyFinger-Typescript\n *\n * @date 2021-02-10 (Typescript port)\n * @version 0.1.18\n */\n;\n/**\n * Tiny math function to calculate the length of a vector in euclidean space.\n *\n * @param {XYCoords} v - The vector in {x,y} notation.\n * @return {number} The length of the vector.\n */\nconst getLen = (v) => {\n return Math.sqrt(v.x * v.x + v.y * v.y);\n};\n/**\n * Tiny math function to calculate the dot product of two vectors.\n *\n * @param {XYCoords} v1 - The first vector in {x,y} notation.\n * @param {XYCoords} v2 - The second vector in {x,y} notation.\n * @return {number} The dot product of both vectors.\n */\nconst dot = (v1, v2) => {\n return v1.x * v2.x + v1.y * v2.y;\n};\n/**\n * Tiny math function to calculate the angle between two vectors.\n *\n * @param {XYCoords} v1 - The first vector in {x,y} notation.\n * @param {XYCoords} v2 - The second vector in {x,y} notation.\n * @return {number} The angle (in radians) between the two vectors.\n */\nconst getAngle = (v1, v2) => {\n const mr = getLen(v1) * getLen(v2);\n if (mr === 0)\n return 0;\n var r = dot(v1, v2) / mr;\n if (r > 1)\n r = 1;\n return Math.acos(r);\n};\n/**\n * Tiny math function to calculate the cross product of two vectors.\n *\n * @param {XYCoords} v1 - The first vector in {x,y} notation.\n * @param {XYCoords} v2 - The second vector in {x,y} notation.\n * @return {number} The cross product of both vectors.\n */\nconst cross = (v1, v2) => {\n return v1.x * v2.y - v2.x * v1.y;\n};\n/**\n * Tiny math function to calculate the rotate-angle (in degrees) for two vectors.\n *\n * @param {XYCoords} v1 - The first vector in {x,y} notation.\n * @param {XYCoords} v2 - The second vector in {x,y} notation.\n * @return {number} The rotate-angle in degrees for the two vectors.\n */\nconst getRotateAngle = (v1, v2) => {\n var angle = getAngle(v1, v2);\n if (cross(v1, v2) > 0) {\n angle *= -1;\n }\n return angle * 180 / Math.PI;\n};\n/**\n * A HandlerAdmin holds all the added event handlers for one kind of event type.\n */\nclass HandlerAdmin {\n constructor(el) {\n this.handlers = [];\n this.el = el;\n }\n ;\n add(handler) {\n this.handlers.push(handler);\n }\n ;\n del(handler) {\n if (!handler)\n this.handlers = [];\n for (var i = this.handlers.length; i >= 0; i--) {\n if (this.handlers[i] === handler) {\n this.handlers.splice(i, 1);\n }\n }\n }\n ;\n dispatch(..._args) {\n for (var i = 0, len = this.handlers.length; i < len; i++) {\n const handler = this.handlers[i];\n if (typeof handler === 'function') {\n handler.apply(this.el, arguments);\n }\n }\n }\n ;\n} // END class HandlerAdmin\n/**\n * A wrapper for handler functions; converts the passed handler function into a HadlerAdmin instance..\n */\nconst wrapFunc = (el, handler) => {\n const handlerAdmin = new HandlerAdmin(el);\n handlerAdmin.add(handler);\n return handlerAdmin;\n};\n/**\n * @classdesc The AlloyFinger main class. Use this to add handler functions for\n * touch events to any HTML- or SVG-Element.\n **/\nexport class AlloyFinger {\n constructor(el, option) {\n this.element = typeof el == 'string' ? document.querySelector(el) : el;\n // Fancy stuff: change `this` from the start-, move-, end- and cancel-function.\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind\n this.start = this.start.bind(this);\n this.move = this.move.bind(this);\n this.end = this.end.bind(this);\n this.cancel = this.cancel.bind(this);\n this.element.addEventListener(\"touchstart\", this.start, false);\n this.element.addEventListener(\"touchmove\", this.move, false);\n this.element.addEventListener(\"touchend\", this.end, false);\n this.element.addEventListener(\"touchcancel\", this.cancel, false);\n this.preV = { x: null, y: null };\n this.pinchStartLen = null;\n this.zoom = 1;\n this.isDoubleTap = false;\n const noop = () => { };\n this.rotate = wrapFunc(this.element, option.rotate || noop);\n this.touchStart = wrapFunc(this.element, option.touchStart || noop);\n this.multipointStart = wrapFunc(this.element, option.multipointStart || noop);\n this.multipointEnd = wrapFunc(this.element, option.multipointEnd || noop);\n this.pinch = wrapFunc(this.element, option.pinch || noop);\n this.swipe = wrapFunc(this.element, option.swipe || noop);\n this.tap = wrapFunc(this.element, option.tap || noop);\n this.doubleTap = wrapFunc(this.element, option.doubleTap || noop);\n this.longTap = wrapFunc(this.element, option.longTap || noop);\n this.singleTap = wrapFunc(this.element, option.singleTap || noop);\n this.pressMove = wrapFunc(this.element, option.pressMove || noop);\n this.twoFingerPressMove = wrapFunc(this.element, option.twoFingerPressMove || noop);\n this.touchMove = wrapFunc(this.element, option.touchMove || noop);\n this.touchEnd = wrapFunc(this.element, option.touchEnd || noop);\n this.touchCancel = wrapFunc(this.element, option.touchCancel || noop);\n this._cancelAllHandler = this.cancelAll.bind(this);\n if (globalThis && typeof globalThis.addEventListener === \"function\") {\n globalThis.addEventListener('scroll', this._cancelAllHandler);\n }\n this.delta = null;\n this.last = null;\n this.now = null;\n this.tapTimeout = null;\n this.singleTapTimeout = null;\n this.longTapTimeout = null;\n this.swipeTimeout = null;\n this.x1 = this.x2 = this.y1 = this.y2 = null;\n this.preTapPosition = { x: null, y: null };\n }\n ;\n start(evt) {\n if (!evt.touches)\n return;\n const _self = this;\n this.now = Date.now();\n this.x1 = evt.touches[0].pageX;\n this.y1 = evt.touches[0].pageY;\n this.delta = this.now - (this.last || this.now);\n this.touchStart.dispatch(evt, this.element);\n if (this.preTapPosition.x !== null) {\n this.isDoubleTap = (this.delta > 0 && this.delta <= 250 && Math.abs(this.preTapPosition.x - this.x1) < 30 && Math.abs(this.preTapPosition.y - this.y1) < 30);\n if (this.isDoubleTap)\n clearTimeout(this.singleTapTimeout);\n }\n this.preTapPosition.x = this.x1;\n this.preTapPosition.y = this.y1;\n this.last = this.now;\n const preV = this.preV;\n const len = evt.touches.length;\n if (len > 1) {\n this._cancelLongTap();\n this._cancelSingleTap();\n const v = { x: evt.touches[1].pageX - this.x1, y: evt.touches[1].pageY - this.y1 };\n preV.x = v.x;\n preV.y = v.y;\n this.pinchStartLen = getLen(preV);\n this.multipointStart.dispatch(evt, this.element);\n }\n this._preventTap = false;\n this.longTapTimeout = setTimeout((() => {\n _self.longTap.dispatch(evt, _self.element);\n _self._preventTap = true;\n }).bind(_self), 750);\n }\n ;\n move(event) {\n if (!event.touches)\n return;\n const afEvent = event;\n const preV = this.preV;\n const len = event.touches.length;\n const currentX = event.touches[0].pageX;\n const currentY = event.touches[0].pageY;\n this.isDoubleTap = false;\n if (len > 1) {\n const sCurrentX = afEvent.touches[1].pageX;\n const sCurrentY = afEvent.touches[1].pageY;\n const v = { x: afEvent.touches[1].pageX - currentX, y: afEvent.touches[1].pageY - currentY };\n if (preV.x !== null) {\n if (this.pinchStartLen > 0) {\n afEvent.zoom = getLen(v) / this.pinchStartLen;\n this.pinch.dispatch(afEvent, this.element);\n }\n afEvent.angle = getRotateAngle(v, preV);\n this.rotate.dispatch(afEvent, this.element);\n }\n preV.x = v.x;\n preV.y = v.y;\n if (this.x2 !== null && this.sx2 !== null) {\n afEvent.deltaX = (currentX - this.x2 + sCurrentX - this.sx2) / 2;\n afEvent.deltaY = (currentY - this.y2 + sCurrentY - this.sy2) / 2;\n }\n else {\n afEvent.deltaX = 0;\n afEvent.deltaY = 0;\n }\n this.twoFingerPressMove.dispatch(afEvent, this.element);\n this.sx2 = sCurrentX;\n this.sy2 = sCurrentY;\n }\n else {\n if (this.x2 !== null) {\n afEvent.deltaX = currentX - this.x2;\n afEvent.deltaY = currentY - this.y2;\n //move事件中添加对当前触摸点到初始触摸点的判断,\n //如果曾经大于过某个距离(比如10),就认为是移动到某个地方又移回来,应该不再触发tap事件才对。\n //\n // translation:\n // Add the judgment of the current touch point to the initial touch point in the event,\n // If it has been greater than a certain distance (such as 10), it is considered to be\n // moved to a certain place and then moved back, and the tap event should no longer be triggered.\n const movedX = Math.abs(this.x1 - this.x2);\n const movedY = Math.abs(this.y1 - this.y2);\n if (movedX > 10 || movedY > 10) {\n this._preventTap = true;\n }\n }\n else {\n afEvent.deltaX = 0;\n afEvent.deltaY = 0;\n }\n this.pressMove.dispatch(afEvent, this.element);\n }\n this.touchMove.dispatch(afEvent, this.element);\n this._cancelLongTap();\n this.x2 = currentX;\n this.y2 = currentY;\n if (len > 1) {\n event.preventDefault();\n }\n }\n ; // END move\n end(event) {\n if (!event.changedTouches)\n return;\n const afEvent = event;\n this._cancelLongTap();\n const self = this;\n if (afEvent.touches.length < 2) {\n this.multipointEnd.dispatch(afEvent, this.element);\n this.sx2 = this.sy2 = null;\n }\n //swipe\n if ((this.x2 && Math.abs(this.x1 - this.x2) > 30) ||\n (this.y2 && Math.abs(this.y1 - this.y2) > 30)) {\n afEvent.direction = this._swipeDirection(this.x1, this.x2, this.y1, this.y2);\n this.swipeTimeout = setTimeout(function () {\n self.swipe.dispatch(afEvent, self.element);\n }, 0);\n }\n else {\n this.tapTimeout = setTimeout(function () {\n if (!self._preventTap) {\n self.tap.dispatch(afEvent, self.element);\n }\n // trigger double tap immediately\n if (self.isDoubleTap) {\n self.doubleTap.dispatch(afEvent, self.element);\n self.isDoubleTap = false;\n }\n }, 0);\n if (!self.isDoubleTap) {\n self.singleTapTimeout = setTimeout(function () {\n self.singleTap.dispatch(afEvent, self.element);\n }, 250);\n }\n }\n this.touchEnd.dispatch(afEvent, this.element);\n this.preV.x = 0;\n this.preV.y = 0;\n this.zoom = 1;\n this.pinchStartLen = null;\n this.x1 = this.x2 = this.y1 = this.y2 = null;\n }\n ; // END end\n cancelAll() {\n this._preventTap = true;\n clearTimeout(this.singleTapTimeout);\n clearTimeout(this.tapTimeout);\n clearTimeout(this.longTapTimeout);\n clearTimeout(this.swipeTimeout);\n }\n ;\n cancel(evt) {\n this.cancelAll();\n this.touchCancel.dispatch(evt, this.element);\n }\n ;\n _cancelLongTap() {\n clearTimeout(this.longTapTimeout);\n }\n ;\n _cancelSingleTap() {\n clearTimeout(this.singleTapTimeout);\n }\n ;\n _swipeDirection(x1, x2, y1, y2) {\n return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down');\n }\n ;\n on(evt, handler) {\n if (this[evt]) {\n // Force the generic parameter into it's expected candidate here ;)\n const admin = this[evt];\n admin.add(handler);\n }\n }\n ;\n off(evt, handler) {\n if (this[evt]) {\n // Force the generic parameter into it's expected candidate here ;)\n const admin = this[evt];\n admin.del(handler);\n }\n }\n ;\n destroy() {\n if (this.singleTapTimeout) {\n clearTimeout(this.singleTapTimeout);\n }\n if (this.tapTimeout) {\n clearTimeout(this.tapTimeout);\n }\n if (this.longTapTimeout) {\n clearTimeout(this.longTapTimeout);\n }\n if (this.swipeTimeout) {\n clearTimeout(this.swipeTimeout);\n }\n this.element.removeEventListener(\"touchstart\", this.start);\n this.element.removeEventListener(\"touchmove\", this.move);\n this.element.removeEventListener(\"touchend\", this.end);\n this.element.removeEventListener(\"touchcancel\", this.cancel);\n this.rotate.del();\n this.touchStart.del();\n this.multipointStart.del();\n this.multipointEnd.del();\n this.pinch.del();\n this.swipe.del();\n this.tap.del();\n this.doubleTap.del();\n this.longTap.del();\n this.singleTap.del();\n this.pressMove.del();\n this.twoFingerPressMove.del();\n this.touchMove.del();\n this.touchEnd.del();\n this.touchCancel.del();\n this.preV = this.pinchStartLen = this.zoom = this.isDoubleTap = this.delta = this.last = this.now = this.tapTimeout = this.singleTapTimeout = this.longTapTimeout = this.swipeTimeout = this.x1 = this.x2 = this.y1 = this.y2 = this.preTapPosition = this.rotate = this.touchStart = this.multipointStart = this.multipointEnd = this.pinch = this.swipe = this.tap = this.doubleTap = this.longTap = this.singleTap = this.pressMove = this.touchMove = this.touchEnd = this.touchCancel = this.twoFingerPressMove = null;\n if (globalThis && typeof globalThis.removeEventListener === \"function\") {\n globalThis.removeEventListener('scroll', this._cancelAllHandler);\n }\n }\n ; // END destroy\n}\n;\nexport default AlloyFinger;\n//# sourceMappingURL=alloy_finger.js.map","/**\n * TypeScript port by Ikaros Kappler.\n *\n * Original file from https://github.com/AlloyTeam/AlloyFinger\n *\n * @date 2021-02-10\n */\nimport { AlloyFinger } from './alloy_finger';\nexport { AlloyFinger };\nexport default AlloyFinger;\n//# sourceMappingURL=index.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2021-11-16\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2023-09-25 Fixed a type error in the constructor. Nothing vital.\n * @version 1.1.1\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.PBText = void 0;\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar Vertex_1 = require(\"./Vertex\");\n/**\n * @classdesc A simple text element: position, fontSize, fontFamily, color, textAlign, lineHeight and rotation.\n *\n * @requires FontOptions\n * @requires FontSize\n * @requires FontStyle\n * @requires FontWeight\n * @requires Vertex\n * @requires SVGSerializale\n * @requires UID\n * @requires UIDGenerator\n **/\nvar PBText = /** @class */ (function () {\n /**\n * Create a new circle with given center point and radius.\n *\n * @constructor\n * @name Circle\n * @param {Vertex} center - The center point of the circle.\n * @param {number} radius - The radius of the circle.\n */\n function PBText(text, anchor, options) {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"PBText\";\n this.uid = UIDGenerator_1.UIDGenerator.next();\n this.text = text;\n this.anchor = anchor !== null && anchor !== void 0 ? anchor : new Vertex_1.Vertex();\n this.color = options === null || options === void 0 ? void 0 : options.color;\n this.fontFamily = options === null || options === void 0 ? void 0 : options.fontFamily;\n this.fontSize = options === null || options === void 0 ? void 0 : options.fontSize;\n this.fontStyle = options === null || options === void 0 ? void 0 : options.fontStyle;\n this.fontWeight = options === null || options === void 0 ? void 0 : options.fontWeight;\n this.lineHeight = options === null || options === void 0 ? void 0 : options.lineHeight;\n this.textAlign = options === null || options === void 0 ? void 0 : options.textAlign;\n this.rotation = options === null || options === void 0 ? void 0 : options.rotation;\n }\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n PBText.prototype.destroy = function () {\n this.anchor.destroy();\n this.isDestroyed = true;\n };\n return PBText;\n}()); // END class\nexports.PBText = PBText;\n//# sourceMappingURL=PBText.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2018-04-14\n * @modified 2018-11-17 Added the containsVert function.\n * @modified 2018-12-04 Added the toSVGString function.\n * @modified 2019-03-20 Added JSDoc tags.\n * @modified 2019-10-25 Added the scale function.\n * @modified 2019-11-06 JSDoc update.\n * @modified 2019-11-07 Added toCubicBezierPath(number) function.\n * @modified 2019-11-22 Added the rotate(number,Vertex) function.\n * @modified 2020-03-24 Ported this class from vanilla-JS to Typescript.\n * @modified 2020-10-30 Added the `addVertex` function.\n * @modified 2020-10-31 Added the `getVertexAt` function.\n * @modified 2020-11-06 Added the `move` function.\n * @modified 2020-11-10 Added the `getBounds` function.\n * @modified 2020-11-11 Generalized `move(Vertex)` to `move(XYCoords)`.\n * @modified 2021-01-20 Added UID.\n * @modified 2021-01-29 Added the `signedArea` function (was global function in the demos before).\n * @modified 2021-01-29 Added the `isClockwise` function.\n * @modified 2021-01-29 Added the `area` function.\n * @modified 2021-01-29 Changed the param type for `containsVert` from Vertex to XYCoords.\n * @modified 2021-12-14 Added the `perimeter()` function.\n * @modified 2021-12-16 Added the `getEvenDistributionPolygon()` function.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-02-02 Cleared the `Polygon.toSVGString` function (deprecated). Use `drawutilssvg` instead.\n * @modified 2022-03-08 Added the `Polygon.clone()` function.\n * @modified 2023-09-25 Added the `Polygon.getInterpolationPolygon(number)` function.\n * @modified 2023-09-25 Added the `Polygon.lineIntersections(Line,boolean)` function.\n * @modified 2023-09-29 Added the `Polygon.closestLineIntersection(Line,boolean)` function.\n * @modified 2023-11-24 Added the `Polygon.containsPolygon(Polygon)' function.\n * @modified 2024-10-12 Added the `getEdgeAt` method.\n * @modified 2024-10-30 Added the `getEdges` method.\n * @modified 2024-12-02 Added the `elimitateColinearEdges` method.\n * @modified 2025-02-12 Added the `containsVerts` method to test multiple vertices for containment.\n * @modified 2025-03-28 Added the `Polygon.utils.locateLineIntersecion` static helper method.\n * @modified 2025-03-28 Added the `Polygon.lineIntersectionTangents` method.\n * @modified 2025-04-09 Added the `Polygon.getCentroid` method.\n * @modified 2025-05-16 Class `Polygon` now implements `IBounded`.\n * @modified 2025-05-20 Tweaking `Polygon.getInnerAngleAt` and `Polygo.isAngleAcute` to handle indices out of array bounds as well.\n * @modified 2025-06-07 Adding `Polygon.closestLineIntersectionIndex` to determine line intersections plus detected edge index.\n * @version 1.16.0\n *\n * @file Polygon\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Polygon = void 0;\nvar BezierPath_1 = require(\"./BezierPath\");\nvar Bounds_1 = require(\"./Bounds\");\nvar Line_1 = require(\"./Line\");\nvar Triangle_1 = require(\"./Triangle\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar Vector_1 = require(\"./Vector\");\nvar Vertex_1 = require(\"./Vertex\");\nvar geomutils_1 = require(\"./geomutils\");\n/**\n * @classdesc A polygon class. Any polygon consists of an array of vertices; polygons can be open or closed.\n *\n * @requires BezierPath\n * @requires Bounds\n * @requires SVGSerializabe\n * @requires UID\n * @requires UIDGenerator\n * @requires Vertex\n * @requires XYCoords\n */\nvar Polygon = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name Polygon\n * @param {Vertex[]} vertices - An array of 2d vertices that shape the polygon.\n * @param {boolean} isOpen - Indicates if the polygon should be rendered as an open or closed shape.\n **/\n function Polygon(vertices, isOpen) {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"Polygon\";\n this.uid = UIDGenerator_1.UIDGenerator.next();\n if (typeof vertices == \"undefined\") {\n vertices = [];\n }\n this.vertices = vertices;\n this.isOpen = isOpen || false;\n }\n /**\n * Add a vertex to the end of the `vertices` array.\n *\n * @method addVertex\n * @param {Vertex} vert - The vertex to add.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.addVertex = function (vert) {\n this.vertices.push(vert);\n };\n /**\n * Add a vertex at a particular position of the `vertices` array.\n *\n * @method addVertexAt\n * @param {Vertex} vert - The vertex to add.\n * @param {number} index - The position to add the vertex at. Will be handled modulo.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.addVertexAt = function (vert, index) {\n // var moduloIndex = index % (this.vertices.length + 1);\n this.vertices.splice(index, 0, vert);\n };\n /**\n * Get a new instance of the line at the given start index. The returned line will consist\n * of the vertex at `vertIndex` and `vertIndex+1` (will be handled modulo).\n *\n * @method getEdgeAt\n * @param {number} vertIndex - The vertex index of the line to start.\n * @instance\n * @memberof Polygon\n * @return {Line}\n **/\n Polygon.prototype.getEdgeAt = function (vertIndex) {\n return new Line_1.Line(this.getVertexAt(vertIndex), this.getVertexAt(vertIndex + 1));\n };\n /**\n * Converts this polygon into a sequence of lines. Please note that each time\n * this method is called new lines are created. The underlying line vertices are no clones\n * (instances).\n *\n * @method getEdges\n * @instance\n * @memberof Polygon\n * @return {Array<Line>}\n */\n Polygon.prototype.getEdges = function () {\n var lines = [];\n for (var i = 0; i + 1 < this.vertices.length; i++) {\n // var line = this.getLineAt(i).clone();\n lines.push(this.getEdgeAt(i));\n }\n if (!this.isOpen && this.vertices.length > 0) {\n lines.push(this.getEdgeAt(this.vertices.length - 1));\n }\n return lines;\n };\n /**\n * Checks if the angle at the given polygon vertex (index) is acute. Please not that this is\n * only working for clockwise polygons. If this polygon is not clockwise please use the\n * `isClockwise` method and reverse polygon vertices if needed.\n *\n * @method isAngleAcute\n * @instance\n * @memberof Polygon\n * @param {number} vertIndex - The index of the polygon vertex to check.\n * @returns {boolean} `true` is angle is acute, `false` is obtuse.\n */\n Polygon.prototype.getInnerAngleAt = function (vertIndex) {\n var p2 = this.vertices[vertIndex % this.vertices.length];\n var p1 = this.vertices[(vertIndex + this.vertices.length - 1) % this.vertices.length].clone();\n var p3 = this.vertices[(vertIndex + 1) % this.vertices.length].clone();\n // See\n // https://math.stackexchange.com/questions/149959/how-to-find-the-interior-angle-of-an-irregular-pentagon-or-polygon\n // π−arccos((P2−P1)⋅(P3−P2)|P2−P1||P3−P2|)\n // Check if triangle is acute (will be used later)\n // Acute angles and obtuse angles need to be handled differently.\n var isAcute = this.isAngleAcute(vertIndex);\n // Differences\n var zero = new Vertex_1.Vertex(0, 0);\n var p2mp1 = new Vertex_1.Vertex(p2.x - p1.x, p2.y - p1.y);\n var p3mp2 = new Vertex_1.Vertex(p3.x - p2.x, p3.y - p2.y);\n var p2mp1_len = zero.distance(p2mp1);\n var p3mp2_len = zero.distance(p3mp2);\n // Dot products\n var dotProduct = geomutils_1.geomutils.dotProduct(p2mp1, p3mp2);\n var lengthProduct = p2mp1_len * p3mp2_len;\n if (isAcute) {\n return Math.PI - Math.acos(dotProduct / lengthProduct);\n }\n else {\n return Math.PI + Math.acos(dotProduct / lengthProduct);\n }\n };\n /**\n * Checks if the angle at the given polygon vertex (index) is acute.\n *\n * @method isAngleAcute\n * @instance\n * @memberof Polygon\n * @param {number} vertIndex - The index of the polygon vertex to check.\n * @returns {boolean} `true` is angle is acute, `false` is obtuse.\n */\n Polygon.prototype.isAngleAcute = function (vertIndex) {\n var A = this.vertices[(vertIndex + this.vertices.length - 1) % this.vertices.length].clone();\n var B = this.vertices[vertIndex % this.vertices.length];\n var C = this.vertices[(vertIndex + 1) % this.vertices.length].clone();\n // Find local winding number for triangle A B C\n var windingNumber = Triangle_1.Triangle.utils.determinant(A, B, C);\n // console.log(\"vertIndex\", vertIndex, \"windingNumber\", windingNumber);\n return windingNumber < 0;\n };\n /**\n * Get the polygon vertex at the given position (index).\n *\n * The index may exceed the total vertex count, and will be wrapped around then (modulo).\n *\n * For k >= 0:\n * - getVertexAt( vertices.length ) == getVertexAt( 0 )\n * - getVertexAt( vertices.length + k ) == getVertexAt( k )\n * - getVertexAt( -k ) == getVertexAt( vertices.length -k )\n *\n * @method getVertexAt\n * @param {number} index - The index of the desired vertex.\n * @instance\n * @memberof Polygon\n * @return {Vertex} At the given index.\n **/\n Polygon.prototype.getVertexAt = function (index) {\n if (index < 0) {\n return this.vertices[this.vertices.length - (Math.abs(index) % this.vertices.length)];\n }\n else {\n return this.vertices[index % this.vertices.length];\n }\n };\n /**\n * Move the polygon's vertices by the given amount.\n *\n * @method move\n * @param {XYCoords} amount - The amount to move.\n * @instance\n * @memberof Polygon\n * @return {Polygon} this for chaining\n **/\n Polygon.prototype.move = function (amount) {\n for (var i in this.vertices) {\n this.vertices[i].add(amount);\n }\n return this;\n };\n /**\n * Check if the given vertex is inside this polygon.<br>\n * <br>\n * Ray-casting algorithm found at<br>\n * https://stackoverflow.com/questions/22521982/check-if-point-inside-a-polygon\n *\n * @method containsVert\n * @param {XYCoords} vert - The vertex to check.\n * @return {boolean} True if the passed vertex is inside this polygon. The polygon is considered closed.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.containsVert = function (vert) {\n // ray-casting algorithm based on\n // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html\n var inside = false;\n for (var i = 0, j = this.vertices.length - 1; i < this.vertices.length; j = i++) {\n var xi = this.vertices[i].x, yi = this.vertices[i].y;\n var xj = this.vertices[j].x, yj = this.vertices[j].y;\n var intersect = yi > vert.y != yj > vert.y && vert.x < ((xj - xi) * (vert.y - yi)) / (yj - yi) + xi;\n if (intersect) {\n inside = !inside;\n }\n }\n return inside;\n };\n /**\n * Check if all given vertices are inside this polygon.<br>\n * <br>\n * This method just uses the `Polygon.containsVert` method.\n *\n * @method containsVerts\n * @param {XYCoords[]} verts - The vertices to check.\n * @return {boolean} True if all passed vertices are inside this polygon. The polygon is considered closed.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.containsVerts = function (verts) {\n var _this = this;\n return verts.every(function (vert) { return _this.containsVert(vert); });\n };\n /**\n * Check if the passed polygon is completly contained inside this polygon.\n *\n * This means:\n * - all polygon's vertices must be inside this polygon.\n * - the polygon has no edge intersections with this polygon.\n *\n * @param {Polygon} polygon - The polygon to check if contained.\n * @return {boolean}\n */\n Polygon.prototype.containsPolygon = function (polygon) {\n for (var i = 0; i < polygon.vertices.length; i++) {\n if (!this.containsVert(polygon.vertices[i])) {\n return false;\n }\n }\n // All vertices are inside; check for intersections\n var lineSegment = new Line_1.Line(new Vertex_1.Vertex(), new Vertex_1.Vertex());\n for (var i = 0; i < polygon.vertices.length; i++) {\n lineSegment.a.set(polygon.vertices[i]);\n lineSegment.b.set(polygon.vertices[(i + 1) % polygon.vertices.length]);\n if (this.lineIntersections(lineSegment, true).length > 0) {\n // Current segment has intersection(s) with this polygon.\n return false;\n }\n }\n return true;\n };\n /**\n * Calculate the area of the given polygon (unsigned).\n *\n * Note that this does not work for self-intersecting polygons.\n *\n * @method area\n * @instance\n * @memberof Polygon\n * @return {number}\n */\n Polygon.prototype.area = function () {\n return Polygon.utils.area(this.vertices);\n };\n /**\n * Calulate the signed polyon area by interpreting the polygon as a matrix\n * and calculating its determinant.\n *\n * @method signedArea\n * @instance\n * @memberof Polygon\n * @return {number}\n */\n Polygon.prototype.signedArea = function () {\n return Polygon.utils.signedArea(this.vertices);\n };\n /**\n * Get the winding order of this polgon: clockwise or counterclockwise.\n *\n * @method isClockwise\n * @instance\n * @memberof Polygon\n * @return {boolean}\n */\n Polygon.prototype.isClockwise = function () {\n // return Polygon.utils.signedArea(this.vertices) < 0;\n return Polygon.utils.isClockwise(this.vertices);\n };\n /**\n * Get the perimeter of this polygon.\n * The perimeter is the absolute length of the outline.\n *\n * If this polygon is open then the last segment (connecting the first and the\n * last vertex) will be skipped.\n *\n * @method perimeter\n * @instance\n * @memberof Polygon\n * @return {number}\n */\n Polygon.prototype.perimeter = function () {\n var length = 0;\n for (var i = 1; i < this.vertices.length; i++) {\n length += this.vertices[i - 1].distance(this.vertices[i]);\n }\n if (!this.isOpen && this.vertices.length > 1) {\n length += this.vertices[0].distance(this.vertices[this.vertices.length - 1]);\n }\n return length;\n };\n /**\n * Scale the polygon relative to the given center.\n *\n * @method scale\n * @param {number} factor - The scale factor.\n * @param {Vertex} center - The center of scaling.\n * @return {Polygon} this, for chaining.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.scale = function (factor, center) {\n for (var i in this.vertices) {\n if (typeof this.vertices[i].scale == \"function\")\n this.vertices[i].scale(factor, center);\n else\n console.log(\"There seems to be a null vertex!\", this.vertices[i]);\n }\n return this;\n };\n /**\n * Rotate the polygon around the given center.\n *\n * @method rotate\n * @param {number} angle - The rotation angle.\n * @param {Vertex} center - The center of rotation.\n * @instance\n * @memberof Polygon\n * @return {Polygon} this, for chaining.\n **/\n Polygon.prototype.rotate = function (angle, center) {\n for (var i in this.vertices) {\n this.vertices[i].rotate(angle, center);\n }\n return this;\n };\n /**\n * Get the mean `center` of this polygon by calculating the mean value of all vertices.\n *\n * Mean: (v[0] + v[1] + ... v[n-1]) / n\n *\n * @method getMeanCenter\n * @instance\n * @memberof Polygon\n * @return {Vertex|null} `null` is no vertices are available.\n */\n Polygon.prototype.getMeanCenter = function () {\n if (this.vertices.length === 0) {\n return null;\n }\n var center = this.vertices[0].clone();\n for (var i = 1; i < this.vertices.length; i++) {\n center.add(this.vertices[i]);\n }\n center.x /= this.vertices.length;\n center.y /= this.vertices.length;\n return center;\n };\n /**\n * Get centroid.\n * Centroids define the barycenter of any non self-intersecting convex polygon.\n *\n * If the polygon is self intersecting or non konvex then the barycenter is not well defined.\n *\n * https://mathworld.wolfram.com/PolygonCentroid.html\n *\n * @method getCentroid\n * @instance\n * @memberof Polygon\n * @returns {Vertex|null}\n */\n Polygon.prototype.getCentroid = function () {\n if (this.vertices.length === 0) {\n return null;\n }\n var center = new Vertex_1.Vertex(0.0, 0.0);\n var n = this.vertices.length;\n for (var i = 0; i < n; i++) {\n // center.add(this.vertices[i]);\n var cur = this.vertices[i];\n var next = this.vertices[(i + 1) % n];\n var factor = cur.x * next.y - next.x * cur.y;\n center.x += (cur.x + next.x) * factor;\n center.y += (cur.y + next.y) * factor;\n }\n var area = this.area();\n center.x *= 1 / (6 * area);\n center.y *= 1 / (6 * area);\n return center;\n };\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get all line intersections with this polygon.\n *\n * This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.\n *\n * See demo `47-closest-vector-projection-on-polygon` for how it works.\n *\n * @param {VertTuple} line - The line to find intersections with.\n * @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).\n * @returns {Array<Vertex>} - An array of all intersections within the polygon bounds.\n */\n Polygon.prototype.lineIntersections = function (line, inVectorBoundsOnly) {\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersections of all lines inside the edge bounds\n return Polygon.utils\n .locateLineIntersecion(line, this.vertices, this.isOpen, inVectorBoundsOnly)\n .map(function (intersectionTuple) { return intersectionTuple.intersection; });\n };\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @param line\n * @param inVectorBoundsOnly\n * @returns\n */\n Polygon.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersection tangents of all lines inside the edge bounds\n return Polygon.utils.locateLineIntersecion(line, this.vertices, this.isOpen, inVectorBoundsOnly).map(function (intersectionTuple) {\n var polyLine = _this.getEdgeAt(intersectionTuple.edgeIndex);\n return new Vector_1.Vector(polyLine.a.clone(), polyLine.b.clone()).moveTo(intersectionTuple.intersection);\n });\n };\n //--- END --- Implement interface `Intersectable`\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @param line\n * @param inVectorBoundsOnly\n * @returns\n */\n Polygon.prototype.lineIntersectionTangentsIndices = function (line, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersection tangents of all lines inside the edge bounds\n return Polygon.utils.locateLineIntersecion(line, this.vertices, this.isOpen, inVectorBoundsOnly).map(function (intersectionTuple) {\n var polyLine = _this.getEdgeAt(intersectionTuple.edgeIndex);\n return {\n intersection: new Vector_1.Vector(polyLine.a.clone(), polyLine.b.clone()).moveTo(intersectionTuple.intersection),\n edgeIndex: intersectionTuple.edgeIndex\n };\n });\n };\n /**\n * Get the closest line-polygon-intersection point (closest the line point A).\n *\n * See demo `47-closest-vector-projection-on-polygon` for how it works.\n *\n * @param {VertTuple} line - The line to find intersections with.\n * @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are considered (located strictly between start and end vertex).\n * @returns {Vertex | null} - The intersection point within the polygon bounds.\n */\n Polygon.prototype.closestLineIntersection = function (line, inVectorBoundsOnly) {\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n var closestInterSectionIndex = this.closestLineIntersectionIndex(line, inVectorBoundsOnly);\n if (closestInterSectionIndex) {\n return closestInterSectionIndex.intersection;\n }\n else {\n return null;\n }\n };\n /**\n * Get the closest line-polygon-intersection point (closest the line point A) plus the edge index..\n *\n * See demo `63-measure-angles-on-polygon` for how it works.\n *\n * @param {VertTuple} line - The line to find intersections with.\n * @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are considered (located strictly between start and end vertex).\n * @returns {PolygonIntersectionTuple| null} - A pair containing the intersection point and the affected polygon edge index.\n */\n Polygon.prototype.closestLineIntersectionIndex = function (line, inVectorBoundsOnly) {\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n var allIntersections = this.lineIntersections(line, inVectorBoundsOnly);\n if (allIntersections.length <= 0) {\n // Empty polygon -> no intersections\n return null;\n }\n // Find the closest intersection\n var closestIntersection = new Vertex_1.Vertex(Number.MAX_VALUE, Number.MAX_VALUE);\n var closestInterSectionIndex = -1;\n var curDist = Number.MAX_VALUE;\n for (var i = 0; i < allIntersections.length; i++) {\n var curVert = allIntersections[i];\n var dist = curVert.distance(line.a);\n if (dist < curDist) {\n // && line.hasPoint(curVert)) {\n curDist = dist;\n closestIntersection = curVert;\n closestInterSectionIndex = i;\n }\n }\n // return [closestIntersection, closestInterSectionIndex];\n return { edgeIndex: closestInterSectionIndex, intersection: closestIntersection };\n };\n /**\n * Construct a new polygon from this polygon with more vertices on each edge. The\n * interpolation count determines the number of additional vertices on each edge.\n * An interpolation count of `0` will return a polygon that equals the source\n * polygon.\n *\n * @param {number} interpolationCount\n * @returns {Polygon} A polygon with `interpolationCount` more vertices (as as factor).\n */\n Polygon.prototype.getInterpolationPolygon = function (interpolationCount) {\n var verts = [];\n for (var i = 0; i < this.vertices.length; i++) {\n var curVert = this.vertices[i];\n var nextVert = this.vertices[(i + 1) % this.vertices.length];\n verts.push(curVert.clone());\n // Add interpolation points\n if (!this.isOpen || i + 1 !== this.vertices.length) {\n var lerpAmount = 1.0 / (interpolationCount + 1);\n for (var j = 1; j <= interpolationCount; j++) {\n verts.push(curVert.clone().lerp(nextVert, lerpAmount * j));\n }\n }\n }\n return new Polygon(verts, this.isOpen);\n };\n /**\n * Convert this polygon into a new polygon with n evenly distributed vertices.\n *\n * @param {number} pointCount - Must not be negative.\n */\n Polygon.prototype.getEvenDistributionPolygon = function (pointCount) {\n if (pointCount <= 0) {\n throw new Error(\"pointCount must be larger than zero; is \" + pointCount + \".\");\n }\n var result = new Polygon([], this.isOpen);\n if (this.vertices.length === 0) {\n return result;\n }\n // Fetch and add the start point from the source polygon\n var polygonPoint = new Vertex_1.Vertex(this.vertices[0]);\n result.vertices.push(polygonPoint);\n if (this.vertices.length === 1) {\n return result;\n }\n var perimeter = this.perimeter();\n var stepSize = perimeter / pointCount;\n var n = this.vertices.length;\n var polygonIndex = 1;\n var nextPolygonPoint = new Vertex_1.Vertex(this.vertices[1]);\n var segmentLength = polygonPoint.distance(nextPolygonPoint);\n var loopMax = this.isOpen ? n : n + 1;\n var curSegmentU = stepSize;\n var i = 1;\n while (i < pointCount && polygonIndex < loopMax) {\n // Check if next eq point is inside this segment\n if (curSegmentU < segmentLength) {\n var newPoint = polygonPoint.clone().lerpAbs(nextPolygonPoint, curSegmentU);\n result.vertices.push(newPoint);\n curSegmentU += stepSize;\n i++;\n }\n else {\n polygonIndex++;\n polygonPoint = nextPolygonPoint;\n nextPolygonPoint = new Vertex_1.Vertex(this.vertices[polygonIndex % n]);\n curSegmentU = curSegmentU - segmentLength;\n segmentLength = polygonPoint.distance(nextPolygonPoint);\n }\n }\n return result;\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Get the bounding box (bounds) of this polygon.\n *\n * @method getBounds\n * @instance\n * @memberof Polygon\n * @return {Bounds} The rectangular bounds of this polygon.\n **/\n Polygon.prototype.getBounds = function () {\n return Bounds_1.Bounds.computeFromVertices(this.vertices);\n };\n //--- END --- Implement interface `IBounded`\n /**\n * Create a deep copy of this polygon.\n *\n * @method clone\n * @instance\n * @memberof Polygon\n * @return {Polygon} The cloned polygon.\n */\n Polygon.prototype.clone = function () {\n return new Polygon(this.vertices.map(function (vert) { return vert.clone(); }), this.isOpen);\n };\n /**\n * Create a new polygon without colinear adjacent edges. This method does not midify the current polygon\n * but creates a new one.\n *\n * Please note that this method does NOT create deep clones of the vertices. Use Polygon.clone() if you need to.\n *\n * Please also note that the `tolerance` may become really large here, as the denominator of two closely\n * parallel lines is usually pretty large. See the demo `57-eliminate-colinear-polygon-edges` to get\n * an impression of how denominators work.\n *\n * @method elimitateColinearEdges\n * @instance\n * @memberof Polygon\n * @param {number?} tolerance - (default is 1.0) The epsilon to detect co-linear edges.\n * @return {Polygon} A new polygon without co-linear adjacent edges – respective the given epsilon.\n */\n Polygon.prototype.elimitateColinearEdges = function (tolerance) {\n var eps = typeof tolerance === \"undefined\" ? 1.0 : tolerance;\n var verts = this.vertices.slice(); // Creates a shallow copy\n var i = 0;\n var lineA = new Line_1.Line(new Vertex_1.Vertex(), new Vertex_1.Vertex());\n var lineB = new Line_1.Line(new Vertex_1.Vertex(), new Vertex_1.Vertex());\n while (i + 1 < verts.length && verts.length > 2) {\n var vertA = verts[i];\n var vertB = verts[(i + 1) % verts.length];\n lineA.a = vertA;\n lineA.b = vertB;\n lineB.a = vertB;\n var areColinear = false;\n var j = i + 2;\n do {\n var vertC = verts[j % verts.length];\n lineB.b = vertC;\n areColinear = lineA.colinear(lineB, eps);\n // console.log(\"are colinear?\", i, i + 1, j, areColinear);\n if (areColinear) {\n j++;\n }\n } while (areColinear);\n // Now j points to the first vertex that's NOT colinear to the current lineA\n // -> delete all vertices in between\n if (j - i > 2) {\n // Means: there have been 'colinear vertices' in between\n verts.splice(i + 1, j - i - 2);\n }\n i++;\n }\n return new Polygon(verts, this.isOpen);\n };\n /**\n * Convert this polygon to a sequence of quadratic Bézier curves.<br>\n * <br>\n * The first vertex in the returned array is the start point.<br>\n * The following sequence are pairs of control-point-and-end-point:\n * <pre>startPoint, controlPoint0, pathPoint1, controlPoint1, pathPoint2, controlPoint2, ..., endPoint</pre>\n *\n * @method toQuadraticBezierData\n * @return {Vertex[]} An array of 2d vertices that shape the quadratic Bézier curve.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.toQuadraticBezierData = function () {\n if (this.vertices.length < 3)\n return [];\n var qbezier = [];\n var cc0 = this.vertices[0];\n var cc1 = this.vertices[1];\n var edgeCenter = new Vertex_1.Vertex(cc0.x + (cc1.x - cc0.x) / 2, cc0.y + (cc1.y - cc0.y) / 2);\n qbezier.push(edgeCenter);\n var limit = this.isOpen ? this.vertices.length : this.vertices.length + 1;\n for (var t = 1; t < limit; t++) {\n cc0 = this.vertices[t % this.vertices.length];\n cc1 = this.vertices[(t + 1) % this.vertices.length];\n var edgeCenter = new Vertex_1.Vertex(cc0.x + (cc1.x - cc0.x) / 2, cc0.y + (cc1.y - cc0.y) / 2);\n qbezier.push(cc0);\n qbezier.push(edgeCenter);\n cc0 = cc1;\n }\n return qbezier;\n };\n /**\n * Convert this polygon to a quadratic bezier curve, represented as an SVG data string.\n *\n * @method toQuadraticBezierSVGString\n * @return {string} The 'd' part for an SVG 'path' element.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.toQuadraticBezierSVGString = function () {\n var qdata = this.toQuadraticBezierData();\n if (qdata.length == 0)\n return \"\";\n var buffer = [\"M \" + qdata[0].x + \" \" + qdata[0].y];\n for (var i = 1; i < qdata.length; i += 2) {\n buffer.push(\"Q \" + qdata[i].x + \" \" + qdata[i].y + \", \" + qdata[i + 1].x + \" \" + qdata[i + 1].y);\n }\n return buffer.join(\" \");\n };\n /**\n * Convert this polygon to a sequence of cubic Bézier curves.<br>\n * <br>\n * The first vertex in the returned array is the start point.<br>\n * The following sequence are triplets of (first-control-point, secnond-control-point, end-point):<br>\n * <pre>startPoint, controlPoint0_0, controlPoint1_1, pathPoint1, controlPoint1_0, controlPoint1_1, ..., endPoint</pre>\n *\n * @method toCubicBezierData\n * @param {number=} threshold - An optional threshold (default=1.0) how strong the curve segments\n * should over-/under-drive. Should be between 0.0 and 1.0 for best\n * results but other values are allowed.\n * @return {Vertex[]} An array of 2d vertices that shape the cubic Bézier curve.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.toCubicBezierData = function (threshold) {\n if (typeof threshold == \"undefined\")\n threshold = 1.0;\n if (this.vertices.length < 3)\n return [];\n var cbezier = [];\n var a = this.vertices[0];\n var b = this.vertices[1];\n var edgeCenter = new Vertex_1.Vertex(a.x + (b.x - a.x) / 2, a.y + (b.y - a.y) / 2);\n cbezier.push(edgeCenter);\n var limit = this.isOpen ? this.vertices.length - 1 : this.vertices.length;\n for (var t = 0; t < limit; t++) {\n var a = this.vertices[t % this.vertices.length];\n var b = this.vertices[(t + 1) % this.vertices.length];\n var c = this.vertices[(t + 2) % this.vertices.length];\n var aCenter = new Vertex_1.Vertex(a.x + (b.x - a.x) / 2, a.y + (b.y - a.y) / 2);\n var bCenter = new Vertex_1.Vertex(b.x + (c.x - b.x) / 2, b.y + (c.y - b.y) / 2);\n var a2 = new Vertex_1.Vertex(aCenter.x + (b.x - aCenter.x) * threshold, aCenter.y + (b.y - aCenter.y) * threshold);\n var b0 = new Vertex_1.Vertex(bCenter.x + (b.x - bCenter.x) * threshold, bCenter.y + (b.y - bCenter.y) * threshold);\n cbezier.push(a2);\n cbezier.push(b0);\n cbezier.push(bCenter);\n }\n return cbezier;\n };\n /**\n * Convert this polygon to a cubic bezier curve, represented as an SVG data string.\n *\n * @method toCubicBezierSVGString\n * @return {string} The 'd' part for an SVG 'path' element.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.toCubicBezierSVGString = function (threshold) {\n var qdata = this.toCubicBezierData(threshold);\n if (qdata.length == 0) {\n return \"\";\n }\n var buffer = [\"M \" + qdata[0].x + \" \" + qdata[0].y];\n for (var i = 1; i < qdata.length; i += 3) {\n buffer.push(\"C \" +\n qdata[i].x +\n \" \" +\n qdata[i].y +\n \", \" +\n qdata[i + 1].x +\n \" \" +\n qdata[i + 1].y +\n \", \" +\n qdata[i + 2].x +\n \" \" +\n qdata[i + 2].y);\n }\n return buffer.join(\" \");\n };\n /**\n * Convert this polygon to a cubic bezier path instance.\n *\n * @method toCubicBezierPath\n * @param {number} threshold - The threshold, usually from 0.0 to 1.0.\n * @return {BezierPath} - A bezier path instance.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.toCubicBezierPath = function (threshold) {\n var qdata = this.toCubicBezierData(threshold);\n // Conver the linear path vertices to a two-dimensional path array\n var pathdata = [];\n for (var i = 0; i + 3 < qdata.length; i += 3) {\n pathdata.push([qdata[i], qdata[i + 3], qdata[i + 1], qdata[i + 2]]);\n }\n return BezierPath_1.BezierPath.fromArray(pathdata);\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n Polygon.prototype.destroy = function () {\n for (var i = 0; i < this.vertices.length; i++) {\n this.vertices[i].destroy();\n }\n this.isDestroyed = true;\n };\n Polygon.utils = {\n /**\n * Calculate the area of the given polygon (unsigned).\n *\n * Note that this does not work for self-intersecting polygons.\n *\n * @name area\n * @return {number}\n */\n area: function (vertices) {\n // Found at:\n // https://stackoverflow.com/questions/16285134/calculating-polygon-area\n var total = 0.0;\n for (var i = 0, l = vertices.length; i < l; i++) {\n var addX = vertices[i].x;\n var addY = vertices[(i + 1) % l].y;\n var subX = vertices[(i + 1) % l].x;\n var subY = vertices[i].y;\n total += addX * addY * 0.5;\n total -= subX * subY * 0.5;\n }\n return Math.abs(total);\n },\n isClockwise: function (vertices) {\n return Polygon.utils.signedArea(vertices) < 0;\n },\n /**\n * Calulate the signed polyon area by interpreting the polygon as a matrix\n * and calculating its determinant.\n *\n * @name signedArea\n * @return {number}\n */\n signedArea: function (vertices) {\n var sum = 0;\n var n = vertices.length;\n for (var i = 0; i < n; i++) {\n var j = (i + 1) % n;\n sum += (vertices[j].x - vertices[i].x) * (vertices[i].y + vertices[j].y);\n }\n return sum;\n },\n /**\n * Find intersections of a line with a polygon (vertices).\n *\n * @param {VertTuple<any>} line - The line to find intersections with.\n * @param {Array<Vertex>} vertices - The polygon's vertices.\n * @param {boolean} isOpen - True if the polygon is open, false otherwise.\n * @param {boolean} inVectorBoundsOnly - If only intersections in strict vector bounds should be returned.\n * @returns\n */\n locateLineIntersecion: function (line, vertices, isOpen, inVectorBoundsOnly) {\n // Find the intersections of all lines inside the edge bounds\n var intersectionPoints = [];\n var n = isOpen ? vertices.length - 1 : vertices.length;\n for (var i = 0; i < n; i++) {\n var polyLine = new Line_1.Line(vertices[i % n], vertices[(i + 1) % n]);\n var intersection = polyLine.intersection(line);\n // true => only inside bounds\n // ignore last edge if open\n if (intersection !== null &&\n polyLine.hasPoint(intersection, true) &&\n (!inVectorBoundsOnly || line.hasPoint(intersection, inVectorBoundsOnly))) {\n intersectionPoints.push({ edgeIndex: i, intersection: intersection });\n }\n }\n return intersectionPoints;\n }\n };\n return Polygon;\n}());\nexports.Polygon = Polygon;\n//# sourceMappingURL=Polygon.js.map","\"use strict\";\n/**\n * Implementation of elliptic sectors.\n * Note that sectors are constructed in clockwise direction.\n *\n * @author Ikaros Kappler\n * @date 2021-02-26\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-11-01 Tweaked the `endpointToCenterParameters` function to handle negative values, too, without errors.\n * @modified 2025-04-01 Adapting a the `toCubicBezier` calculation to match an underlying change in the vertAt and tangentAt calculation of ellipses (was required to hamonize both methods with circles).\n * @modified 2025-04-02 Adding `VEllipseSector.containsAngle` method.\n * @modified 2025-04-02 Adding `VEllipseSector.lineIntersections` and `VEllipseSector.lineIntersectionTangents` and implementing `Intersectable`.\n * @modified 2025-04-07 Adding value wrapping (0 to TWO_PI) to the `VEllipseSector.containsAngle` method.\n * @modified 2025-04-09 Adding the `VEllipseSector.move` method.\n * @modified 2025-04-19 Added the `VEllipseSector.getStartPoint` and `getEndPoint` methods.\n * @modified 2025-04-23 Added the `VEllipseSector.getBounds` method.\n * @version 1.2.0\n */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.VEllipseSector = void 0;\nvar Bounds_1 = require(\"./Bounds\");\nvar CubicBezierCurve_1 = require(\"./CubicBezierCurve\");\nvar geomutils_1 = require(\"./geomutils\");\nvar Line_1 = require(\"./Line\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar VEllipse_1 = require(\"./VEllipse\");\nvar Vertex_1 = require(\"./Vertex\");\n/**\n * @classdesc A class for elliptic sectors.\n *\n * @requires Line\n * @requires Vector\n * @requires VertTuple\n * @requires Vertex\n * @requires SVGSerializale\n * @requires UID\n * @requires UIDGenerator\n **/\nvar VEllipseSector = /** @class */ (function () {\n /**\n * Create a new elliptic sector from the given ellipse and two angles.\n *\n * Note that the direction from start to end goes clockwise, and that start and end angle\n * will be wrapped to [0,PI*2).\n *\n * @constructor\n * @name VEllipseSector\n * @param {VEllipse} - The underlying ellipse to use.\n * @param {number} startAngle - The start angle of the sector.\n * @param {numner} endAngle - The end angle of the sector.\n */\n function VEllipseSector(ellipse, startAngle, endAngle) {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"VEllipseSector\";\n this.uid = UIDGenerator_1.UIDGenerator.next();\n this.ellipse = ellipse;\n this.startAngle = geomutils_1.geomutils.wrapMinMax(startAngle, 0, Math.PI * 2);\n this.endAngle = geomutils_1.geomutils.wrapMinMax(endAngle, 0, Math.PI * 2);\n }\n /**\n * Move the ellipse sector by the given amount.\n *\n * @method move\n * @param {XYCoords} amount - The amount to move.\n * @instance\n * @memberof VEllipseSector\n * @return {VEllipseSector} this for chaining\n **/\n VEllipseSector.prototype.move = function (amount) {\n this.ellipse.move(amount);\n return this;\n };\n /**\n * Checks wether the given angle (must be inside 0 and PI*2) is contained inside this sector.\n *\n * @param {number} angle - The numeric angle to check.\n * @method containsAngle\n * @instance\n * @memberof VEllipseSectpr\n * @return {boolean} True if (and only if) this sector contains the given angle.\n */\n VEllipseSector.prototype.containsAngle = function (angle) {\n angle = geomutils_1.geomutils.mapAngleTo2PI(angle); // wrapMinMax(angle, 0, Math.PI * 2);\n var sAngle = geomutils_1.geomutils.mapAngleTo2PI(this.startAngle);\n var eAngle = geomutils_1.geomutils.mapAngleTo2PI(this.endAngle);\n // TODO: cleanup\n // if (this.startAngle <= this.endAngle) {\n // return angle >= this.startAngle && angle < this.endAngle;\n // } else {\n // // startAngle > endAngle\n // return angle >= this.startAngle || angle < this.endAngle;\n // }\n if (sAngle <= eAngle) {\n return angle >= sAngle && angle < eAngle;\n }\n else {\n // startAngle > endAngle\n return angle >= sAngle || angle < eAngle;\n }\n };\n /**\n * Get the sectors starting point (on the underlying ellipse, located at the start angle).\n *\n * @method getStartPoint\n * @instance\n * @memberof VEllipseSector\n * @return {Vertex} The sector's stating point.\n */\n VEllipseSector.prototype.getStartPoint = function () {\n return this.ellipse.vertAt(this.startAngle);\n };\n /**\n * Get the sectors ending point (on the underlying ellipse, located at the end angle).\n *\n * @method getEndPoint\n * @instance\n * @memberof VEllipseSector\n * @return {Vertex} The sector's ending point.\n */\n VEllipseSector.prototype.getEndPoint = function () {\n return this.ellipse.vertAt(this.endAngle);\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Get the bounds of this elliptic sector.\n *\n * The bounds are approximated by the underlying segment buffer; the more segment there are,\n * the more accurate will be the returned bounds.\n *\n * @method getBounds\n * @instance\n * @memberof VEllipse\n * @return {Bounds} The bounds of this elliptic sector.\n **/\n VEllipseSector.prototype.getBounds = function () {\n var _this = this;\n // Calculage angles from east, west, north and south box points and check if they are inside\n var extremes = this.ellipse.getExtremePoints();\n var candidates = extremes.filter(function (point) {\n var angle = new Line_1.Line(_this.ellipse.center, point).angle() - _this.ellipse.rotation;\n return _this.containsAngle(angle);\n });\n return Bounds_1.Bounds.computeFromVertices([this.getStartPoint(), this.getEndPoint()].concat(candidates));\n };\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get the line intersections as vectors with this ellipse.\n *\n * @method lineIntersections\n * @instance\n * @memberof VEllipseSectpr\n * @param {VertTuple<Vector>} ray - The line/ray to intersect this ellipse with.\n * @param {boolean} inVectorBoundsOnly - (default=false) Set to true if only intersections within the vector bounds are of interest.\n * @returns\n */\n VEllipseSector.prototype.lineIntersections = function (ray, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // First get all line intersections from underlying ellipse.\n var ellipseIntersections = this.ellipse.lineIntersections(ray, inVectorBoundsOnly);\n // Drop all intersection points that are not contained in the circle sectors bounds.\n var tmpLine = new Line_1.Line(this.ellipse.center, new Vertex_1.Vertex());\n return ellipseIntersections.filter(function (intersectionPoint) {\n tmpLine.b.set(intersectionPoint);\n var lineAngle = tmpLine.angle();\n return _this.containsAngle(lineAngle - _this.ellipse.rotation);\n });\n };\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @method lineIntersections\n * @memberof VEllipseSectpr\n * @param line\n * @param lineIntersectionTangents\n * @returns\n */\n VEllipseSector.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersections of all lines plus their tangents inside the circle bounds\n var interSectionPoints = this.lineIntersections(line, inVectorBoundsOnly);\n return interSectionPoints.map(function (vert) {\n // Calculate angle\n var lineFromCenter = new Line_1.Line(_this.ellipse.center, vert);\n var angle = lineFromCenter.angle();\n // console.log(\"angle\", (angle / Math.PI) * 180.0);\n // const angle = Math.random() * Math.PI * 2; // TODO\n // Calculate tangent at angle\n return _this.ellipse.tangentAt(angle);\n });\n };\n //--- END --- Implement interface `Intersectable`\n /**\n * Convert this elliptic sector into cubic Bézier curves.\n *\n * @param {number=3} quarterSegmentCount - The number of segments per base elliptic quarter (default is 3, min is 1).\n * @param {number=0.666666} threshold - The Bézier threshold (default value 0.666666 approximates the ellipse with best results\n * but you might wish to use other values)\n * @return {Array<CubicBezierCurve>} An array of cubic Bézier curves representing the elliptic sector.\n */\n VEllipseSector.prototype.toCubicBezier = function (quarterSegmentCount, threshold) {\n // There are at least 4 segments required (dour quarters) to approximate a whole\n // ellipse with Bézier curves.\n // A visually 'good' approximation should have 12; this seems to be a good value (anything multiple of 4).\n var segmentCount = Math.max(1, quarterSegmentCount || 3) * 4;\n threshold = typeof threshold === \"undefined\" ? 0.666666 : threshold;\n var radiusH = this.ellipse.radiusH();\n var radiusV = this.ellipse.radiusV();\n var startAngle = VEllipseSector.ellipseSectorUtils.normalizeAngle(this.startAngle);\n var endAngle = VEllipseSector.ellipseSectorUtils.normalizeAngle(this.endAngle);\n // Find all angles inside start and end\n var angles = VEllipseSector.ellipseSectorUtils.equidistantVertAngles(radiusH, radiusV, startAngle, endAngle, segmentCount);\n angles = [startAngle].concat(angles).concat([endAngle]);\n var curves = [];\n var curAngle = angles[0];\n var startPoint = this.ellipse.vertAt(curAngle);\n for (var i = 0; i + 1 < angles.length; i++) {\n var nextAngle = angles[(i + 1) % angles.length];\n var endPoint = this.ellipse.vertAt(nextAngle);\n var startTangent = this.ellipse.tangentAt(curAngle + this.ellipse.rotation);\n var endTangent = this.ellipse.tangentAt(nextAngle + this.ellipse.rotation);\n // Distorted ellipses can only be approximated by linear Bézier segments\n if (Math.abs(radiusV) < 0.0001 || Math.abs(radiusH) < 0.0001) {\n var diff = startPoint.difference(endPoint);\n var curve = new CubicBezierCurve_1.CubicBezierCurve(startPoint.clone(), endPoint.clone(), startPoint.clone().addXY(diff.x * 0.333, diff.y * 0.333), endPoint.clone().addXY(-diff.x * 0.333, -diff.y * 0.333));\n curves.push(curve);\n }\n else {\n // Find intersection\n var intersection = startTangent.intersection(endTangent);\n // What if intersection is undefined?\n // --> This *can* not happen if segmentCount > 2 and height and width of the ellipse are not zero.\n if (intersection) {\n // It's VERY LIKELY hat this ALWAYS happens; it's just a typesave variant.\n // Intersection cannot be null.\n var startDiff = startPoint.difference(intersection);\n var endDiff = endPoint.difference(intersection);\n var curve = new CubicBezierCurve_1.CubicBezierCurve(startPoint.clone(), endPoint.clone(), startPoint.clone().add(startDiff.scale(threshold)), endPoint.clone().add(endDiff.scale(threshold)));\n curves.push(curve);\n }\n }\n startPoint = endPoint;\n curAngle = nextAngle;\n }\n return curves;\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n VEllipseSector.prototype.destroy = function () {\n this.ellipse.destroy();\n this.isDestroyed = true;\n };\n VEllipseSector.ellipseSectorUtils = {\n /**\n * Helper function to convert an elliptic section to SVG arc params (for the `d` attribute).\n * Inspiration found at:\n * https://stackoverflow.com/questions/5736398/how-to-calculate-the-svg-path-for-an-arc-of-a-circle\n *\n * @param {boolean} options.moveToStart - If false (default=true) the initial 'Move' command will not be used.\n * @return [ 'A', radiusH, radiusV, rotation, largeArcFlag=1|0, sweepFlag=0, endx, endy ]\n */\n describeSVGArc: function (x, y, radiusH, radiusV, startAngle, endAngle, rotation, options) {\n if (typeof options === \"undefined\")\n options = { moveToStart: true };\n if (typeof rotation === \"undefined\")\n rotation = 0.0;\n // Important note: this function only works if start- and end-angle are within\n // one whole circle [x,x+2*PI].\n // Revelations of more than 2*PI might result in unexpected arcs.\n // -> Use the geomutils.wrapMax( angle, 2*PI )\n startAngle = geomutils_1.geomutils.wrapMax(startAngle, Math.PI * 2);\n endAngle = geomutils_1.geomutils.wrapMax(endAngle, Math.PI * 2);\n // Find the start- and end-point on the rotated ellipse\n // XYCoords to Vertex (for rotation)\n var end = new Vertex_1.Vertex(VEllipse_1.VEllipse.utils.polarToCartesian(x, y, radiusH, radiusV, endAngle));\n var start = new Vertex_1.Vertex(VEllipse_1.VEllipse.utils.polarToCartesian(x, y, radiusH, radiusV, startAngle));\n end.rotate(rotation, { x: x, y: y });\n start.rotate(rotation, { x: x, y: y });\n // Boolean stored as integers (0|1).\n var diff = endAngle - startAngle;\n var largeArcFlag;\n if (diff < 0) {\n largeArcFlag = Math.abs(diff) < Math.PI ? 1 : 0;\n }\n else {\n largeArcFlag = Math.abs(diff) > Math.PI ? 1 : 0;\n }\n var sweepFlag = 1;\n var pathData = [];\n if (options.moveToStart) {\n pathData.push(\"M\", start.x, start.y);\n }\n // Arc rotation in degrees, not radians.\n var r2d = 180 / Math.PI;\n pathData.push(\"A\", radiusH, radiusV, rotation * r2d, largeArcFlag, sweepFlag, end.x, end.y);\n return pathData;\n }, // END function describeSVGArc\n /**\n * Helper function to find second-kind elliptic angles, so that the euclidean distance along the the\n * elliptic sector is the same for all.\n *\n * Note that this is based on the full ellipse calculuation and start and end will be cropped; so the\n * distance from the start angle to the first angle and/or the distance from the last angle to\n * the end angle may be different to the others.\n *\n * Furthermore the computation is only possible on un-rotated ellipses; if your source ellipse has\n * a rotation on the plane please 'rotate' the result angles afterwards to find matching angles.\n *\n * Returned angles are normalized to the interval `[ 0, PI*2 ]`.\n *\n * @param {number} radiusH - The first (horizonal) radius of the ellipse.\n * @param {number} radiusV - The second (vertical) radius of the ellipse.\n * @param {number} startAngle - The opening angle of your elliptic sector (please use normalized angles).\n * @param {number} endAngle - The closing angle of your elliptic sector (please use normalized angles).\n * @param {number} fullEllipsePointCount - The number of base segments to use from the source ellipse (12 or 16 are good numbers).\n * @return {Array<number>} An array of n angles inside startAngle and endAngle (where n <= fullEllipsePointCount).\n */\n equidistantVertAngles: function (radiusH, radiusV, startAngle, endAngle, fullEllipsePointCount) {\n var ellipseAngles = VEllipse_1.VEllipse.utils.equidistantVertAngles(radiusH, radiusV, fullEllipsePointCount);\n ellipseAngles = ellipseAngles.map(function (angle) { return VEllipseSector.ellipseSectorUtils.normalizeAngle(angle); });\n var angleIsInRange = function (angle) {\n if (startAngle < endAngle)\n return angle >= startAngle && angle <= endAngle;\n else\n return angle >= startAngle || (angle <= endAngle && angle >= 0);\n };\n // Drop all angles outside the sector\n ellipseAngles = ellipseAngles.filter(angleIsInRange);\n // Now we need to sort the angles to the first one in the array is the closest to startAngle.\n // --> find the angle that is closest to the start angle\n var startIndex = VEllipseSector.ellipseSectorUtils.findClosestToStartAngle(startAngle, endAngle, ellipseAngles);\n // Bring all angles into the correct order\n // Idea: use splice or slice here?\n var angles = [];\n for (var i = 0; i < ellipseAngles.length; i++) {\n angles.push(ellipseAngles[(startIndex + i) % ellipseAngles.length]);\n }\n return angles;\n },\n findClosestToStartAngle: function (startAngle, endAngle, ellipseAngles) {\n // Note: endAngle > 0 && startAngle > 0\n if (startAngle > endAngle) {\n var n = ellipseAngles.length;\n for (var i = 0; i < n; i++) {\n var ea = geomutils_1.geomutils.wrapMinMax(ellipseAngles[i], 0, Math.PI * 2);\n if (ea >= startAngle && ea >= endAngle) {\n return i;\n }\n }\n }\n return 0;\n },\n normalizeAngle: function (angle) { return (angle < 0 ? Math.PI * 2 + angle : angle); },\n /**\n * Convert the elliptic arc from endpoint parameters to center parameters as described\n * in the w3c svg arc implementation note.\n *\n * https://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter\n *\n * @param {number} x1 - The x component of the start point (end of last SVG command).\n * @param {number} y1 - The y component of the start point (end of last SVG command).\n * @param {number} rx - The first (horizontal) radius of the ellipse.\n * @param {number} ry - The second (vertical) radius of the ellipse.\n * @param {number} phi - The ellipse's rotational angle (angle of axis rotation) in radians (not in degrees as the SVG command uses!)\n * @param {boolean} fa - The large-arc-flag (boolean, not 0 or 1).\n * @param {boolean} fs - The sweep-flag (boolean, not 0 or 1).\n * @param {number} x2 - The x component of the end point (end of last SVG command).\n * @param {number} y2 - The y component of the end point (end of last SVG command).\n * @returns\n */\n endpointToCenterParameters: function (x1, y1, rx, ry, phi, fa, fs, x2, y2) {\n // console.log(\"endpointToCenterParameters\", x1, y1, phi, rx, ry, fa, fs, x2, y2);\n // Thanks to\n // https://observablehq.com/@toja/ellipse-and-elliptical-arc-conversion\n var abs = Math.abs;\n var sin = Math.sin;\n var cos = Math.cos;\n var sqrt = Math.sqrt;\n var pow = function (n) {\n return n * n;\n };\n var sinphi = sin(phi);\n var cosphi = cos(phi);\n // Step 1: simplify through translation/rotation\n var x = (cosphi * (x1 - x2)) / 2 + (sinphi * (y1 - y2)) / 2;\n var y = (-sinphi * (x1 - x2)) / 2 + (cosphi * (y1 - y2)) / 2;\n var px = pow(x), py = pow(y), prx = pow(rx), pry = pow(ry);\n // correct of out-of-range radii\n var L = px / prx + py / pry;\n if (L > 1) {\n rx = sqrt(L) * abs(rx);\n ry = sqrt(L) * abs(ry);\n }\n else {\n rx = abs(rx);\n ry = abs(ry);\n }\n // Step 2 + 3: compute center\n var sign = fa === fs ? -1 : 1;\n // const M: number = sqrt((prx * pry - prx * py - pry * px) / (prx * py + pry * px)) * sign;\n var M = sqrt(Math.abs((prx * pry - prx * py - pry * px) / (prx * py + pry * px))) * sign;\n var _cx = (M * (rx * y)) / ry;\n var _cy = (M * (-ry * x)) / rx;\n var cx = cosphi * _cx - sinphi * _cy + (x1 + x2) / 2;\n var cy = sinphi * _cx + cosphi * _cy + (y1 + y2) / 2;\n // Step 4: Compute start and end angle\n var center = new Vertex_1.Vertex(cx, cy);\n var axis = center.clone().addXY(rx, ry);\n var ellipse = new VEllipse_1.VEllipse(center, axis, 0);\n // console.log(\"VELLIPSE::::::\", ellipse);\n ellipse.rotate(phi);\n var startAngle = new Line_1.Line(ellipse.center, new Vertex_1.Vertex(x1, y1)).angle();\n var endAngle = new Line_1.Line(ellipse.center, new Vertex_1.Vertex(x2, y2)).angle();\n return new VEllipseSector(ellipse, startAngle - phi, endAngle - phi);\n }\n }; // END ellipseSectorUtils\n return VEllipseSector;\n}());\nexports.VEllipseSector = VEllipseSector;\n//# sourceMappingURL=VEllipseSector.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2013-08-19\n * @modified 2018-08-16 Added closure. Removed the 'IKRS' wrapper.\n * @modified 2018-11-20 Added circular auto-adjustment.\n * @modified 2018-11-25 Added the point constants to the BezierPath class itself.\n * @modified 2018-11-28 Added the locateCurveByStartPoint() function.\n * @modified 2018-12-04 Added the toSVGString() function.\n * @modified 2019-03-23 Added JSDoc tags.\n * @modified 2019-03-23 Changed the fuctions getPoint and getPointAt to match semantics in the Line class.\n * @modified 2019-11-18 Fixed the clone function: adjustCircular attribute was not cloned.\n * @modified 2019-12-02 Removed some excessive comments.\n * @modified 2019-12-04 Fixed the missing obtainHandleLengths behavior in the adjustNeightbourControlPoint function.\n * @modified 2020-02-06 Added function locateCurveByEndPoint( Vertex ).\n * @modified 2020-02-11 Added 'return this' to the scale(Vertex,number) and to the translate(Vertex) function.\n * @modified 2020-03-24 Ported this class from vanilla-JS to Typescript.\n * @modified 2020-06-03 Made the private helper function _locateUIndex to a private function.\n * @modified 2020-06-03 Added the getBounds() function.\n * @modified 2020-07-14 Changed the moveCurvePoint(...,Vertex) to moveCurvePoint(...,XYCoords).\n * @modified 2020-07-24 Added the getClosestT(Vertex) function.\n * @modified 2020-12-29 Constructor is now private (no explicit use intended).\n * @modified 2021-05-25 Added BezierPath.fromReducedList( Array<number> ).\n * @modified 2022-01-31 Added `BezierPath.getEvenDistributionVertices(number)`.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-02-02 Cleared the `toSVGString` function (deprecated). Use `drawutilssvg` instead.\n * @modified 2023-10-06 Adding the `BezierPath.toPathPoints()` method.\n * @modified 2023-10-07 Adding the `BezierPath.fromCurve(CubicBezierCurve)` static function.\n * @modified 2025-04-09 Added the `BezierPath.move` method to match the convention – which just calls `translate`.\n * @modified 2025-04-09 Modified the `BezierPath.translate` method: chaning parameter `Vertex` to more generalized `XYCoords`.\n * @modified 2025-04-14 Class `BezierPath` is now implementing interface `Intersectable`.\n * @version 2.7.0\n *\n * @file BezierPath\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.BezierPath = void 0;\nvar Bounds_1 = require(\"./Bounds\");\nvar CubicBezierCurve_1 = require(\"./CubicBezierCurve\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar Vertex_1 = require(\"./Vertex\");\n/**\n * @classdesc A BezierPath class.\n *\n * This was refactored from an older project.\n *\n * @requires Bounds\n * @requires Vertex\n * @requires CubicBezierCurve\n * @requires XYCoords\n * @requires SVGSerializable\n * @requires UID\n * @requires UIDGenerator\n **/\nvar BezierPath = /** @class */ (function () {\n /**\n * The constructor.<br>\n * <br>\n * This constructor expects a sequence of path points and will approximate\n * the location of control points by picking some between the points.<br>\n * You should consider just constructing empty paths and then add more curves later using\n * the addCurve() function.\n *\n * @constructor\n * @name BezierPath\n * @param {Vertex[]} pathPoints - An array of path vertices (no control points).\n **/\n function BezierPath() {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"BezierPath\";\n /** @constant {number} */\n this.START_POINT = 0;\n /** @constant {number} */\n this.START_CONTROL_POINT = 1;\n /** @constant {number} */\n this.END_CONTROL_POINT = 2;\n /** @constant {number} */\n this.END_POINT = 3;\n // pathPoints: Array<Vertex> | undefined | null) {\n this.uid = UIDGenerator_1.UIDGenerator.next();\n // if (!pathPoints) {\n // pathPoints = [];\n // }\n this.totalArcLength = 0.0;\n // Set this flag to true if you want the first point and\n // last point of the path to be auto adjusted, too.\n this.adjustCircular = false;\n this.bezierCurves = [];\n }\n /**\n * Add a cubic bezier curve to the end of this path.\n *\n * @method addCurve\n * @param {CubicBezierCurve} curve - The curve to be added to the end of the path.\n * @instance\n * @memberof BezierPath\n * @return {void}\n **/\n BezierPath.prototype.addCurve = function (curve) {\n if (curve == null || typeof curve == \"undefined\")\n throw \"Cannot add null curve to bézier path.\";\n this.bezierCurves.push(curve);\n if (this.bezierCurves.length > 1) {\n curve.startPoint = this.bezierCurves[this.bezierCurves.length - 2].endPoint;\n this.adjustSuccessorControlPoint(this.bezierCurves.length - 2, // curveIndex,\n true, // obtainHandleLength,\n true // updateArcLengths\n );\n }\n else {\n this.totalArcLength += curve.getLength();\n }\n };\n /**\n * Locate the curve with the given start point (function returns the index).\n *\n * @method locateCurveByStartPoint\n * @param {Vertex} point - The (curve start-) point to look for.\n * @instance\n * @memberof BezierPath\n * @return {number} The curve index or -1 if curve (start-) point not found\n **/\n BezierPath.prototype.locateCurveByStartPoint = function (point) {\n // for( var i in this.bezierCurves ) {\n for (var i = 0; i < this.bezierCurves.length; i++) {\n if (this.bezierCurves[i].startPoint.equals(point))\n return i;\n }\n return -1;\n };\n /**\n * Locate the curve with the given end point (function returns the index).\n *\n * @method locateCurveByEndPoint\n * @param {Vertex} point - The (curve end-) point to look for.\n * @instance\n * @memberof BezierPath\n * @return {number} The curve index or -1 if curve (end-) point not found\n **/\n BezierPath.prototype.locateCurveByEndPoint = function (point) {\n // for( var i in this.bezierCurves ) {\n for (var i = 0; i < this.bezierCurves.length; i++) {\n if (this.bezierCurves[i].endPoint.equals(point))\n return i;\n }\n return -1;\n };\n /**\n * Locate the curve with the given start point (function returns the index).\n *\n * @method locateCurveByStartControlPoint\n * @param {Vertex} point - The (curve endt-) point to look for.\n * @instance\n * @memberof BezierPath\n * @return {number} The curve index or -1 if curve (end-) point not found\n **/\n BezierPath.prototype.locateCurveByStartControlPoint = function (point) {\n // for( var i in this.bezierCurves ) {\n for (var i = 0; i < this.bezierCurves.length; i++) {\n if (this.bezierCurves[i].startControlPoint.equals(point))\n return i;\n }\n return -1;\n };\n // +---------------------------------------------------------------------------------\n // | Locate the curve with the given end control point.\n // |\n // | @param point:Vertex The point to look for.\n // | @return Number The index or -1 if not found.\n // +-------------------------------\n BezierPath.prototype.locateCurveByEndControlPoint = function (point) {\n // for( var i in this.bezierCurves ) {\n for (var i = 0; i < this.bezierCurves.length; i++) {\n if (this.bezierCurves[i].endControlPoint.equals(point))\n return i;\n }\n return -1;\n };\n /**\n * Get the total length of this path.<br>\n * <br>\n * Note that the returned value comes from the curve buffer. Unregistered changes\n * to the curve points will result in invalid path length values.\n *\n * @method getLength\n * @instance\n * @memberof BezierPath\n * @return {number} The (buffered) length of the path.\n **/\n BezierPath.prototype.getLength = function () {\n return this.totalArcLength;\n };\n /**\n * This function is internally called whenever the curve or path configuration\n * changed. It updates the attribute that stores the path length information.<br>\n * <br>\n * If you perform any unregistered changes to the curve points you should call\n * this function afterwards to update the curve buffer. Not updating may\n * result in unexpected behavior.\n *\n * @method updateArcLengths\n * @instance\n * @memberof BezierPath\n * @return {void}\n **/\n BezierPath.prototype.updateArcLengths = function () {\n this.totalArcLength = 0.0;\n for (var i = 0; i < this.bezierCurves.length; i++) {\n this.bezierCurves[i].updateArcLengths();\n this.totalArcLength += this.bezierCurves[i].getLength();\n }\n };\n /**\n * Get the number of curves in this path.\n *\n * @method getCurveCount\n * @instance\n * @memberof BezierPath\n * @return {number} The number of curves in this path.\n **/\n BezierPath.prototype.getCurveCount = function () {\n return this.bezierCurves.length;\n };\n /**\n * Get the cubic bezier curve at the given index.\n *\n * @method getCurveAt\n * @param {number} index - The curve index from 0 to getCurveCount()-1.\n * @instance\n * @memberof BezierPath\n * @return {CubicBezierCurve} The curve at the specified index.\n **/\n BezierPath.prototype.getCurveAt = function (curveIndex) {\n return this.bezierCurves[curveIndex];\n };\n /**\n * Move the whole bezier path by the given (x,y)-amount.\n *\n * @method translate\n * @param {XYCoords} amount - The amount to be added (amount.x and amount.y)\n * to each vertex of the curve.\n * @instance\n * @memberof BezierPath\n * @return {BezierPath} this for chaining\n **/\n BezierPath.prototype.translate = function (amount) {\n for (var i = 0; i < this.bezierCurves.length; i++) {\n var curve = this.bezierCurves[i];\n curve.getStartPoint().add(amount);\n curve.getStartControlPoint().add(amount);\n curve.getEndControlPoint().add(amount);\n }\n // Don't forget to translate the last curve's last point\n var curve = this.bezierCurves[this.bezierCurves.length - 1];\n curve.getEndPoint().add(amount);\n this.updateArcLengths();\n return this;\n };\n /**\n * Move the whole bezier path by the given (x,y)-amount.\n *\n * @method move\n * @param {XYCoords} amount - The amount to be added (amount.x and amount.y)\n * to each vertex of the curve.\n * @instance\n * @memberof BezierPath\n * @return {BezierPath} this for chaining\n **/\n BezierPath.prototype.move = function (amount) {\n return this.translate(amount);\n };\n /**\n * Scale the whole bezier path by the given uniform factor.\n *\n * @method scale\n * @param {Vertex} anchor - The scale origin to scale from.\n * @param {number} scaleFactor - The scalar to be multiplied with.\n * @instance\n * @memberof BezierPath\n * @return {BezierPath} this for chaining.\n **/\n BezierPath.prototype.scale = function (anchor, scaleFactor) {\n return this.scaleXY({ x: scaleFactor, y: scaleFactor }, anchor);\n };\n /**\n * Scale the whole bezier path by the given (x,y)-factors.\n *\n * @method scale\n * @param {Vertex} anchor - The scale origin to scale from.\n * @param {number} amount - The scalar to be multiplied with.\n * @instance\n * @memberof BezierPath\n * @return {BezierPath} this for chaining.\n **/\n BezierPath.prototype.scaleXY = function (scaleFactors, anchor) {\n for (var i = 0; i < this.bezierCurves.length; i++) {\n var curve = this.bezierCurves[i];\n curve.getStartPoint().scaleXY(scaleFactors, anchor);\n curve.getStartControlPoint().scaleXY(scaleFactors, anchor);\n curve.getEndControlPoint().scaleXY(scaleFactors, anchor);\n // Do NOT scale the end point here!\n // Don't forget that the curves are connected and on curve's end point\n // the the successor's start point (same instance)!\n }\n // Finally move the last end point (was not scaled yet)\n if (this.bezierCurves.length > 0 && !this.adjustCircular) {\n this.bezierCurves[this.bezierCurves.length - 1].getEndPoint().scaleXY(scaleFactors, anchor);\n }\n this.updateArcLengths();\n return this;\n };\n /**\n * Rotate the whole bezier path around a point..\n *\n * @method rotate\n * @param {Vertex} angle - The angle to rotate this path by.\n * @param {Vertex} center - The rotation center.\n * @instance\n * @memberof BezierPath\n * @return {void}\n **/\n BezierPath.prototype.rotate = function (angle, center) {\n for (var i = 0; i < this.bezierCurves.length; i++) {\n var curve = this.bezierCurves[i];\n curve.getStartPoint().rotate(angle, center);\n curve.getStartControlPoint().rotate(angle, center);\n curve.getEndControlPoint().rotate(angle, center);\n // Do NOT rotate the end point here!\n // Don't forget that the curves are connected and on curve's end point\n // the the successor's start point (same instance)!\n }\n // Finally move the last end point (was not scaled yet)\n if (this.bezierCurves.length > 0 && !this.adjustCircular) {\n this.bezierCurves[this.bezierCurves.length - 1].getEndPoint().rotate(angle, center);\n }\n };\n /**\n * Get the 't' position on this curve with the minimal distance to point p.\n *\n * @param {Vertex} p - The point to find the closest curve point for.\n * @return {number} A value t with 0.0 <= t <= 1.0.\n **/\n BezierPath.prototype.getClosestT = function (p) {\n // Find the spline to extract the value from\n var minIndex = -1;\n var minDist = 0.0;\n var dist = 0.0;\n var curveT = 0.0;\n var uMin = 0.0;\n var u = 0.0;\n for (var i = 0; i < this.bezierCurves.length; i++) {\n curveT = this.bezierCurves[i].getClosestT(p);\n dist = this.bezierCurves[i].getPointAt(curveT).distance(p);\n if (minIndex == -1 || dist < minDist) {\n minIndex = i;\n minDist = dist;\n uMin = u + curveT * this.bezierCurves[i].getLength();\n }\n u += this.bezierCurves[i].getLength();\n }\n return Math.max(0.0, Math.min(1.0, uMin / this.totalArcLength));\n };\n /**\n * Get the point on the bézier path at the given relative path location.\n *\n * @method getPoint\n * @param {number} u - The relative path position: <pre>0 <= u <= this.getLength()</pre>\n * @instance\n * @memberof BezierPath\n * @return {Vertex} The point at the relative path position.\n **/\n BezierPath.prototype.getPoint = function (u) {\n if (u < 0 || u > this.totalArcLength) {\n console.warn(\"[BezierPath.getPoint(u)] u is out of bounds: \" + u + \".\");\n u = Math.min(this.totalArcLength, Math.max(u, 0));\n }\n // Find the spline to extract the value from\n var i = 0;\n var uTemp = 0.0;\n while (i < this.bezierCurves.length && uTemp + this.bezierCurves[i].getLength() < u) {\n uTemp += this.bezierCurves[i].getLength();\n i++;\n }\n // if u == arcLength\n // -> i is max\n if (i >= this.bezierCurves.length)\n return this.bezierCurves[this.bezierCurves.length - 1].getEndPoint().clone();\n var bCurve = this.bezierCurves[i];\n var relativeU = u - uTemp;\n return bCurve.getPoint(relativeU);\n };\n /**\n * Get the point on the bézier path at the given path fraction.\n *\n * @method getPointAt\n * @param {number} t - The absolute path position: <pre>0.0 <= t <= 1.0</pre>\n * @instance\n * @memberof BezierPath\n * @return {Vertex} The point at the absolute path position.\n **/\n BezierPath.prototype.getPointAt = function (t) {\n return this.getPoint(t * this.totalArcLength);\n };\n /**\n * Get the tangent of the bézier path at the given path fraction.<br>\n * <br>\n * Note that the returned vector is not normalized.\n *\n * @method getTangentAt\n * @param {number} t - The absolute path position: <pre>0.0 <= t <= 1.0</pre>\n * @instance\n * @memberof BezierPath\n * @return {Vertex} The tangent vector at the absolute path position.\n **/\n BezierPath.prototype.getTangentAt = function (t) {\n return this.getTangent(t * this.totalArcLength);\n };\n /**\n * Get the tangent of the bézier path at the given path location.<br>\n * <br>\n * Note that the returned vector is not normalized.\n *\n * @method getTangent\n * @param {number} u - The relative path position: <pre>0 <= u <= getLength()</pre>\n * @instance\n * @memberof BezierPath\n * @return {Vertex} The tangent vector at the relative path position.\n **/\n BezierPath.prototype.getTangent = function (u) {\n if (u < 0 || u > this.totalArcLength) {\n console.warn(\"[BezierPath.getTangent(u)] u is out of bounds: \" + u + \".\");\n // return undefined;\n u = Math.min(this.totalArcLength, Math.max(0, u));\n }\n // Find the spline to extract the value from\n var i = 0;\n var uTemp = 0.0;\n while (i < this.bezierCurves.length && uTemp + this.bezierCurves[i].getLength() < u) {\n uTemp += this.bezierCurves[i].getLength();\n i++;\n }\n var bCurve = this.bezierCurves[i];\n var relativeU = u - uTemp;\n return bCurve.getTangent(relativeU);\n };\n /**\n * Get the perpendicular of the bézier path at the given absolute path location (fraction).<br>\n * <br>\n * Note that the returned vector is not normalized.\n *\n * @method getPerpendicularAt\n * @param {number} t - The absolute path position: <pre>0.0 <= t <= 1.0</pre>\n * @instance\n * @memberof BezierPath\n * @return {Vertex} The perpendicluar vector at the absolute path position.\n **/\n BezierPath.prototype.getPerpendicularAt = function (t) {\n return this.getPerpendicular(t * this.totalArcLength);\n };\n /**\n * Get the perpendicular of the bézier path at the given relative path location.<br>\n * <br>\n * Note that the returned vector is not normalized.\n *\n * @method getPerpendicular\n * @param {number} u - The relative path position: <pre>0 <= u <= getLength()</pre>\n * @instance\n * @memberof BezierPath\n * @return {Vertex} The perpendicluar vector at the relative path position.\n **/\n BezierPath.prototype.getPerpendicular = function (u) {\n if (u < 0 || u > this.totalArcLength) {\n console.log(\"[BezierPath.getPerpendicular(u)] u is out of bounds: \" + u + \".\");\n u = Math.min(this.totalArcLength, Math.max(0, u));\n }\n // Find the spline to extract the value from\n var uResult = BezierPath._locateUIndex(this, u);\n var bCurve = this.bezierCurves[uResult.i];\n var relativeU = u - uResult.uPart;\n return bCurve.getPerpendicular(relativeU);\n };\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get all line intersections with this shape.\n *\n * This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.\n *\n * @param {VertTuple} line - The line to find intersections with.\n * @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).\n * @returns {Array<Vertex>} - An array of all intersections with the shape's outline.\n */\n BezierPath.prototype.lineIntersections = function (line, inVectorBoundsOnly) {\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n return this.bezierCurves.reduce(function (accu, curCurve) {\n return accu.concat(curCurve.lineIntersections(line, inVectorBoundsOnly));\n }, []);\n };\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @param line\n * @param lineIntersectionTangents\n * @returns\n */\n BezierPath.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n return this.bezierCurves.reduce(function (accu, curCurve) {\n return accu.concat(curCurve.lineIntersectionTangents(line, inVectorBoundsOnly));\n }, []);\n };\n //--- END --- Implement interface `Intersectable`\n /**\n * This is a helper function to locate the curve index for a given\n * absolute path position u.\n *\n * I decided to put this into privat scope as it is really specific. Maybe\n * put this into a utils wrapper.\n *\n * Returns:\n * - {number} i - the index of the containing curve.\n * - {number} uPart - the absolute curve length sum (length from the beginning to u, should equal u itself).\n * - {number} uBefore - the absolute curve length for all segments _before_ the matched curve (usually uBefore <= uPart).\n **/\n BezierPath._locateUIndex = function (path, u) {\n var i = 0;\n var uTemp = 0.0;\n var uBefore = 0.0;\n while (i < path.bezierCurves.length && uTemp + path.bezierCurves[i].getLength() < u) {\n uTemp += path.bezierCurves[i].getLength();\n if (i + 1 < path.bezierCurves.length)\n uBefore += path.bezierCurves[i].getLength();\n i++;\n }\n return { i: i, uPart: uTemp, uBefore: uBefore };\n };\n /**\n * Get a specific sub path from this path. The start and end position are specified by\n * ratio number in [0..1].\n *\n * 0.0 is at the beginning of the path.\n * 1.0 is at the end of the path.\n *\n * Values below 0 or beyond 1 are cropped down to the [0..1] interval.\n *\n * startT > endT is allowed, the returned sub path will have inverse direction then.\n *\n * @method getSubPathAt\n * @param {number} startT - The start position of the sub path.\n * @param {number} endT - The end position of the sub path.\n * @instance\n * @memberof BezierPath\n * @return {BezierPath} The desired sub path in the bounds [startT..endT].\n **/\n BezierPath.prototype.getSubPathAt = function (startT, endT) {\n startT = Math.max(0, startT);\n endT = Math.min(1.0, endT);\n var startU = startT * this.totalArcLength;\n var endU = endT * this.totalArcLength;\n var uStartResult = BezierPath._locateUIndex(this, startU); // { i:int, uPart:float, uBefore:float }\n var uEndResult = BezierPath._locateUIndex(this, endU); // { i:int, uPart:float, uBefore:float }\n var firstT = (startU - uStartResult.uBefore) / this.bezierCurves[uStartResult.i].getLength();\n if (uStartResult.i == uEndResult.i) {\n // Subpath begins and ends in the same path segment (just get a simple sub curve from that path element).\n var lastT = (endU - uEndResult.uBefore) / this.bezierCurves[uEndResult.i].getLength();\n var firstCurve = this.bezierCurves[uStartResult.i].getSubCurveAt(firstT, lastT);\n return BezierPath.fromArray([firstCurve]);\n }\n else {\n var curves = [];\n if (uStartResult.i > uEndResult.i) {\n // Back to front direction\n var firstCurve = this.bezierCurves[uStartResult.i].getSubCurveAt(firstT, 0.0);\n curves.push(firstCurve);\n for (var i = uStartResult.i - 1; i > uEndResult.i; i--) {\n curves.push(this.bezierCurves[i].clone().reverse());\n }\n var lastT = (endU - uEndResult.uBefore) / this.bezierCurves[uEndResult.i].getLength();\n curves.push(this.bezierCurves[uEndResult.i].getSubCurveAt(1.0, lastT));\n }\n else {\n // Front to back direction\n var firstCurve = this.bezierCurves[uStartResult.i].getSubCurveAt(firstT, 1.0);\n curves.push(firstCurve);\n for (var i = uStartResult.i + 1; i < uEndResult.i && i < this.bezierCurves.length; i++) {\n curves.push(this.bezierCurves[i].clone());\n }\n var lastT = (endU - uEndResult.uBefore) / this.bezierCurves[uEndResult.i].getLength();\n curves.push(this.bezierCurves[uEndResult.i].getSubCurveAt(0, lastT));\n }\n return BezierPath.fromArray(curves);\n }\n };\n /**\n * This function moves the addressed curve point (or control point) with\n * keeping up the path's curve integrity.<br>\n * <br>\n * Thus is done by moving neighbour- and control- points as needed.\n *\n * @method moveCurvePoint\n * @param {number} curveIndex - The curve index to move a point from.\n * @param {number} pointID - One of the curve's four point IDs (START_POINT,\n * START_CONTROL_POINT, END_CONTRO_POINT or END_POINT).\n * @param {XYCoords} moveAmount - The amount to move the addressed vertex by.\n * @instance\n * @memberof BezierPath\n * @return {void}\n **/\n BezierPath.prototype.moveCurvePoint = function (curveIndex, pointID, moveAmount) {\n var bCurve = this.getCurveAt(curveIndex);\n bCurve.moveCurvePoint(pointID, moveAmount, true, // move control point, too\n true // updateArcLengths\n );\n // If inner point and NOT control point\n // --> move neightbour\n if (pointID == this.START_POINT && (curveIndex > 0 || this.adjustCircular)) {\n // Set predecessor's control point!\n var predecessor = this.getCurveAt(curveIndex - 1 < 0 ? this.bezierCurves.length + (curveIndex - 1) : curveIndex - 1);\n predecessor.moveCurvePoint(this.END_CONTROL_POINT, moveAmount, true, // move control point, too\n false // updateArcLengths\n );\n }\n else if (pointID == this.END_POINT && (curveIndex + 1 < this.bezierCurves.length || this.adjustCircular)) {\n // Set successcor\n var successor = this.getCurveAt((curveIndex + 1) % this.bezierCurves.length);\n successor.moveCurvePoint(this.START_CONTROL_POINT, moveAmount, true, // move control point, too\n false // updateArcLengths\n );\n }\n else if (pointID == this.START_CONTROL_POINT && curveIndex > 0) {\n this.adjustPredecessorControlPoint(curveIndex, true, // obtain handle length?\n false // update arc lengths\n );\n }\n else if (pointID == this.END_CONTROL_POINT && curveIndex + 1 < this.getCurveCount()) {\n this.adjustSuccessorControlPoint(curveIndex, true, // obtain handle length?\n false // update arc lengths\n );\n }\n // Don't forget to update the arc lengths!\n // Note: this can be optimized as only two curves have changed their lengths!\n this.updateArcLengths();\n };\n /**\n * This helper function adjusts the given point's predecessor's control point.\n *\n * @method adjustPredecessorControlPoint\n * @param {number} curveIndex - The curve index to move a point from.\n * @param {boolean} obtainHandleLength - Moves the point with keeping the original handle length.\n * @param {boolean} updateArcLength - The amount to move the addressed vertex by.\n * @instance\n * @private\n * @memberof BezierPath\n * @return {void}\n **/\n BezierPath.prototype.adjustPredecessorControlPoint = function (curveIndex, obtainHandleLength, updateArcLengths) {\n if (!this.adjustCircular && curveIndex <= 0)\n return; // false;\n var mainCurve = this.getCurveAt(curveIndex);\n var neighbourCurve = this.getCurveAt(curveIndex - 1 < 0 ? this.getCurveCount() + (curveIndex - 1) : curveIndex - 1);\n BezierPath.adjustNeighbourControlPoint(mainCurve, neighbourCurve, mainCurve.getStartPoint(), // the reference point\n mainCurve.getStartControlPoint(), // the dragged control point\n neighbourCurve.getEndPoint(), // the neighbour's point\n neighbourCurve.getEndControlPoint(), // the neighbour's control point to adjust\n obtainHandleLength, updateArcLengths);\n };\n /**\n * This helper function adjusts the given point's successor's control point.\n *\n * @method adjustSuccessorControlPoint\n * @param {number} curveIndex - The curve index to move a point from.\n * @param {boolean} obtainHandleLength - Moves the point with keeping the original handle length.\n * @param {boolean} updateArcLength - The amount to move the addressed vertex by.\n * @instance\n * @private\n * @memberof BezierPath\n * @return {void}\n **/\n BezierPath.prototype.adjustSuccessorControlPoint = function (curveIndex, obtainHandleLength, updateArcLengths) {\n if (!this.adjustCircular && curveIndex + 1 > this.getCurveCount())\n return; // false;\n var mainCurve = this.getCurveAt(curveIndex);\n var neighbourCurve = this.getCurveAt((curveIndex + 1) % this.getCurveCount());\n /* return */ BezierPath.adjustNeighbourControlPoint(mainCurve, neighbourCurve, mainCurve.getEndPoint(), // the reference point\n mainCurve.getEndControlPoint(), // the dragged control point\n neighbourCurve.getStartPoint(), // the neighbour's point\n neighbourCurve.getStartControlPoint(), // the neighbour's control point to adjust\n obtainHandleLength, updateArcLengths);\n };\n /**\n * This helper function adjusts the given point's successor's control point.\n *\n * @method adjustNeighbourControlPoint\n * @param {CubicBezierCurve} mainCurve\n * @param {CubicBezierCurve} neighbourCurve\n * @param {Vertex} mainPoint\n * @param {Vertex} mainControlPoint\n * @param {Vertex} neighbourPoint\n * @param {Vertex} neighbourControlPoint\n * @param {boolean} obtainHandleLengths\n * @param {boolean} updateArcLengths\n * @instance\n * @private\n * @memberof BezierPath\n * @return {void}\n **/\n BezierPath.adjustNeighbourControlPoint = function (_mainCurve, // TODO: remove param\n neighbourCurve, mainPoint, mainControlPoint, neighbourPoint, neighbourControlPoint, obtainHandleLengths, _updateArcLengths // TODO: remove param\n ) {\n // Calculate start handle length\n var mainHandleBounds = new Vertex_1.Vertex(mainControlPoint.x - mainPoint.x, mainControlPoint.y - mainPoint.y);\n var neighbourHandleBounds = new Vertex_1.Vertex(neighbourControlPoint.x - neighbourPoint.x, neighbourControlPoint.y - neighbourPoint.y);\n var mainHandleLength = Math.sqrt(Math.pow(mainHandleBounds.x, 2) + Math.pow(mainHandleBounds.y, 2));\n var neighbourHandleLength = Math.sqrt(Math.pow(neighbourHandleBounds.x, 2) + Math.pow(neighbourHandleBounds.y, 2));\n if (mainHandleLength <= 0.1)\n return; // no secure length available for division? What about zoom? Use EPSILON?\n // Just invert the main handle (keep length or not?\n if (obtainHandleLengths) {\n neighbourControlPoint.set(neighbourPoint.x - mainHandleBounds.x * (neighbourHandleLength / mainHandleLength), neighbourPoint.y - mainHandleBounds.y * (neighbourHandleLength / mainHandleLength));\n }\n else {\n neighbourControlPoint.set(neighbourPoint.x - mainHandleBounds.x, neighbourPoint.y - mainHandleBounds.y);\n }\n neighbourCurve.updateArcLengths();\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Get the bounds of this Bézier path.\n *\n * Note the the curves' underlyung segment buffers are used to determine the bounds. The more\n * elements the segment buffers have, the more precise the returned bounds will be.\n *\n * @return {Bounds} The bounds of this Bézier path.\n **/\n BezierPath.prototype.getBounds = function () {\n var min = new Vertex_1.Vertex(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY);\n var max = new Vertex_1.Vertex(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY);\n var b;\n for (var i = 0; i < this.bezierCurves.length; i++) {\n b = this.bezierCurves[i].getBounds();\n min.x = Math.min(min.x, b.min.x);\n min.y = Math.min(min.y, b.min.y);\n max.x = Math.max(max.x, b.max.x);\n max.y = Math.max(max.y, b.max.y);\n }\n return new Bounds_1.Bounds(min, max);\n };\n //--- END --- Implement interface `IBounded`\n /**\n * Get n 'equally' distributed vertices along this Bézier path.\n *\n * As the changing curvature of the B slines makes prediction of distances difficult, the\n * returned vertices' distances are only relatively equal:\n * - the distance grows where curvature is large.\n * - the distance shrinks where curvature is small.\n *\n * Only the distance mean of all consecutive is 1/n-th of the total arc length.\n *\n * Usually this approximation is good enough for most use cases.\n *\n * @param {number} pointCount - (must be at least 2) The number of desired points (start and end point included).\n * @return {Array<Vertex>}\n */\n BezierPath.prototype.getEvenDistributionVertices = function (pointCount) {\n if (pointCount < 2) {\n throw new Error(\"pointCount must be larger than one; is \" + pointCount + \".\");\n }\n var result = [];\n if (this.bezierCurves.length === 0) {\n return result;\n }\n // Fetch and add the start point from the source polygon\n var polygonPoint = new Vertex_1.Vertex(this.bezierCurves[0].startPoint);\n result.push(polygonPoint);\n // if (this.bezierCurves.length === 1) {\n // return result;\n // }\n var perimeter = this.totalArcLength;\n var stepSize = perimeter / (pointCount - 1);\n var n = this.bezierCurves.length;\n var curveIndex = 0;\n var segmentLength = this.bezierCurves[0].arcLength;\n var curSegmentU = stepSize;\n var i = 1;\n while (i < pointCount && curveIndex < n) {\n // Check if next eq point is inside this segment\n if (curSegmentU < segmentLength) {\n var newPoint = this.bezierCurves[curveIndex].getPoint(curSegmentU);\n result.push(newPoint);\n curSegmentU += stepSize;\n i++;\n }\n else {\n curveIndex++;\n curSegmentU = curSegmentU - segmentLength;\n segmentLength = curveIndex < n ? this.bezierCurves[curveIndex].arcLength : 0;\n }\n }\n result.push(new Vertex_1.Vertex(this.bezierCurves[n - 1].endPoint));\n return result;\n };\n /**\n * Clone this BezierPath (deep clone).\n *\n * @method clone\n * @instance\n * @memberof BezierPath\n * @return {BezierPath}\n **/\n BezierPath.prototype.clone = function () {\n var path = new BezierPath(); // undefined);\n for (var i = 0; i < this.bezierCurves.length; i++) {\n path.bezierCurves.push(this.bezierCurves[i].clone());\n // Connect splines\n if (i > 0)\n path.bezierCurves[i - 1].endPoint = path.bezierCurves[i].startPoint;\n }\n path.updateArcLengths();\n path.adjustCircular = this.adjustCircular;\n return path;\n };\n /**\n * Compare this and the passed Bézier path.\n *\n * @method equals\n * @param {BezierPath} path - The pass to compare with.\n * @instance\n * @memberof BezierPath\n * @return {boolean}\n **/\n BezierPath.prototype.equals = function (path) {\n if (!path)\n return false;\n // Check if path contains the credentials\n if (!path.bezierCurves)\n return false;\n if (typeof path.bezierCurves.length == \"undefined\")\n return false;\n if (path.bezierCurves.length != this.bezierCurves.length)\n return false;\n for (var i = 0; i < this.bezierCurves.length; i++) {\n if (!this.bezierCurves[i].equals(path.bezierCurves[i]))\n return false;\n }\n return true;\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n *\n * @method destroy\n * @instance\n * @memberof BezierPath\n */\n BezierPath.prototype.destroy = function () {\n for (var i = 0; i < this.bezierCurves.length; i++) {\n this.bezierCurves[i].destroy();\n }\n this.isDestroyed = true;\n };\n /**\n * Convert this path to an array of path points that can be drawn by the default DrawLib\n * implementations.\n *\n * @method toPathPoints\n * @instance\n * @memberof BezierPath\n * @return {Array<XYCoords>}\n */\n BezierPath.prototype.toPathPoints = function () {\n if (this.bezierCurves.length === 0) {\n return [];\n }\n if (this.bezierCurves.length === 1) {\n return [\n this.bezierCurves[0].startPoint,\n this.bezierCurves[0].startControlPoint,\n this.bezierCurves[0].endControlPoint,\n this.bezierCurves[0].endPoint\n ];\n }\n var arr = [];\n arr.push(this.bezierCurves[0].startPoint);\n arr.push(this.bezierCurves[0].startControlPoint);\n for (var i = 1; i < this.bezierCurves.length; i++) {\n arr.push(this.bezierCurves[i - 1].endControlPoint);\n arr.push(this.bezierCurves[i - 1].endPoint);\n arr.push(this.bezierCurves[i].startPoint);\n arr.push(this.bezierCurves[i].startControlPoint);\n }\n arr.push(this.bezierCurves[0].endControlPoint);\n arr.push(this.bezierCurves[0].endPoint);\n return arr;\n };\n /**\n * Create a JSON string representation of this bézier curve.\n *\n * @method toJSON\n * @param {boolean} prettyFormat - If true then the function will add line breaks.\n * @instance\n * @memberof BezierPath\n * @return {string} The JSON string.\n **/\n BezierPath.prototype.toJSON = function (prettyFormat) {\n var buffer = [];\n buffer.push(\"[\"); // array begin\n for (var i = 0; i < this.bezierCurves.length; i++) {\n if (i > 0)\n buffer.push(\",\");\n if (prettyFormat)\n buffer.push(\"\\n\\t\");\n else\n buffer.push(\" \");\n buffer.push(this.bezierCurves[i].toJSON(prettyFormat));\n }\n if (this.bezierCurves.length != 0)\n buffer.push(\" \");\n buffer.push(\"]\"); // array end\n return buffer.join(\"\"); // Convert to string, with empty separator.\n };\n /**\n * Parse a BezierPath from the given JSON string.\n *\n * @method fromJSON\n * @param {string} jsonString - The string with the JSON data.\n * @throw An error if the string is not JSON or does not contain a bezier path object.\n * @static\n * @memberof BezierPath\n * @return {BezierPath} The parsed bezier path instance.\n **/\n BezierPath.fromJSON = function (jsonString) {\n var obj = JSON.parse(jsonString);\n return BezierPath.fromArray(obj);\n };\n /**\n * Construct a new path with a single curve. Adding more curves is always possible.\n *\n * @method fromCurve\n * @param {CubicBezierCurve} curve - The curve to construct a new path from.\n * @static\n * @memberof BezierPath\n * @return {BezierPath} The constructed bezier path instance.\n */\n BezierPath.fromCurve = function (curve) {\n var path = new BezierPath(); // []);\n path.addCurve(curve);\n return path;\n };\n /**\n * Create a BezierPath instance from the given array.\n *\n * @method fromArray\n * @param {Vertex[][]} arr - A two-dimensional array containing the bezier path vertices.\n * @throw An error if the array does not contain proper bezier path data.\n * @static\n * @memberof BezierPath\n * @return {BezierPath} The bezier path instance retrieved from the array data.\n **/\n BezierPath.fromArray = function (obj) {\n if (!Array.isArray(obj)) {\n throw \"[BezierPath.fromArray] Passed object must be an array.\";\n }\n var arr = obj; // FORCE?\n if (arr.length < 1) {\n throw \"[BezierPath.fromArray] Passed array must contain at least one bezier curve (has \" + arr.length + \").\";\n }\n // Create an empty bezier path\n var bPath = new BezierPath(); // undefined);\n var lastCurve = null;\n for (var i = 0; i < arr.length; i++) {\n // Convert object (or array?) to bezier curve\n var bCurve;\n if (CubicBezierCurve_1.CubicBezierCurve.isInstance(arr[i])) {\n bCurve = arr[i].clone();\n }\n else if (0 in arr[i] && 1 in arr[i] && 2 in arr[i] && 3 in arr[i]) {\n if (!arr[i][0] || !arr[i][1] || !arr[i][2] || !arr[i][3])\n throw \"Cannot convert path data to BezierPath instance. At least one element is undefined (index=\" + i + \"): \" + arr[i];\n bCurve = CubicBezierCurve_1.CubicBezierCurve.fromArray(arr[i]);\n }\n else {\n bCurve = CubicBezierCurve_1.CubicBezierCurve.fromObject(arr[i]);\n }\n // Set curve start point?\n // (avoid duplicate point instances!)\n if (lastCurve)\n bCurve.startPoint = lastCurve.endPoint;\n // Add to path's internal list\n bPath.bezierCurves.push(bCurve);\n // bPath.totalArcLength += bCurve.getLength();\n lastCurve = bCurve;\n }\n bPath.updateArcLengths();\n // Bezier segments added. Done\n return bPath;\n };\n /**\n * This function converts the bezier path into a string containing\n * integer values only.\n * The points' float values are rounded to 1 digit after the comma.\n *\n * The returned string represents a JSON array (with leading '[' and\n * trailing ']', the separator is ',').\n *\n * @method toReducedListRepresentation\n * @param {number} digits - The number of digits to be used after the comma '.'.\n * @instance\n * @memberof BezierPath\n * @return {string} The reduced list representation of this path.\n **/\n BezierPath.prototype.toReducedListRepresentation = function (digits) {\n if (typeof digits == \"undefined\")\n digits = 1;\n var buffer = [];\n buffer.push(\"[\"); // array begin\n for (var i = 0; i < this.bezierCurves.length; i++) {\n var curve = this.bezierCurves[i];\n buffer.push(curve.getStartPoint().x.toFixed(digits));\n buffer.push(\",\");\n buffer.push(curve.getStartPoint().y.toFixed(digits));\n buffer.push(\",\");\n buffer.push(curve.getStartControlPoint().x.toFixed(digits));\n buffer.push(\",\");\n buffer.push(curve.getStartControlPoint().y.toFixed(digits));\n buffer.push(\",\");\n buffer.push(curve.getEndControlPoint().x.toFixed(digits));\n buffer.push(\",\");\n buffer.push(curve.getEndControlPoint().y.toFixed(digits));\n buffer.push(\",\");\n }\n if (this.bezierCurves.length != 0) {\n var curve = this.bezierCurves[this.bezierCurves.length - 1];\n buffer.push(curve.getEndPoint().x.toFixed(digits));\n buffer.push(\",\");\n buffer.push(curve.getEndPoint().y.toFixed(digits));\n }\n buffer.push(\"]\"); // array end\n return buffer.join(\"\"); // Convert to string, with empty separator.\n };\n /**\n * Parse a BezierPath instance from the reduced list representation.<br>\n * <br>\n * The passed string must represent a JSON array containing numbers only.\n *\n * @method fromReducedListRepresentation\n * @param {string} listJSON - The number of digits to be used after the floating point.\n * @throw An error if the string is malformed.\n * @instance\n * @memberof BezierPath\n * @return {BezierPath} The bezier path instance retrieved from the string.\n **/\n BezierPath.fromReducedListRepresentation = function (listJSON, adjustCircular) {\n // Parse the array\n var pointArray = JSON.parse(listJSON);\n if (!pointArray.length) {\n console.log(\"Cannot parse bezier path from non-array object nor from empty point list.\");\n throw \"Cannot parse bezier path from non-array object nor from empty point list.\";\n }\n if (pointArray.length < 8) {\n console.log(\"Cannot build bezier path. The passed array must contain at least 8 elements (numbers).\");\n throw \"Cannot build bezier path. The passed array must contain at least 8 elements (numbers).\";\n }\n return BezierPath.fromReducedList(pointArray, adjustCircular);\n };\n /**\n * Convert a reduced list representation (array of numeric coordinates) to a BezierPath instance.\n *\n * The array's length must be 6*n + 2:\n * - [sx, sy, scx, scy, ecx, ecy, ... , ex, ey ]\n * | | | |\n * +--- sequence of curves --------+ +-end-+\n *\n * @param {number[]} pointArray\n * @returns BezierPath\n */\n BezierPath.fromReducedList = function (pointArray, adjustCircular) {\n // Convert to object\n var bezierPath = new BezierPath(); // null); // No points yet\n var startPoint = new Vertex_1.Vertex();\n var startControlPoint;\n var endControlPoint;\n var endPoint;\n var i = 0;\n do {\n if (i == 0) {\n // firstStartPoint =\n startPoint = new Vertex_1.Vertex(pointArray[i], pointArray[i + 1]);\n }\n startControlPoint = new Vertex_1.Vertex(pointArray[i + 2], pointArray[i + 3]);\n endControlPoint = new Vertex_1.Vertex(pointArray[i + 4], pointArray[i + 5]);\n // if (i + 8 >= pointArray.length) {\n // endPoint = firstStartPoint;\n // } else {\n endPoint = new Vertex_1.Vertex(pointArray[i + 6], pointArray[i + 7]);\n // }\n var bCurve = new CubicBezierCurve_1.CubicBezierCurve(startPoint, endPoint, startControlPoint, endControlPoint);\n bezierPath.bezierCurves.push(bCurve);\n startPoint = endPoint;\n i += 6;\n } while (i + 2 < pointArray.length);\n bezierPath.adjustCircular = adjustCircular !== null && adjustCircular !== void 0 ? adjustCircular : false;\n if (adjustCircular) {\n bezierPath.bezierCurves[bezierPath.bezierCurves.length - 1].endPoint = bezierPath.bezierCurves[0].startPoint;\n }\n bezierPath.updateArcLengths();\n return bezierPath;\n };\n // +---------------------------------------------------------------------------------\n // | These constants equal the values from CubicBezierCurve.\n // +-------------------------------\n /** @constant {number} */\n BezierPath.START_POINT = 0;\n /** @constant {number} */\n BezierPath.START_CONTROL_POINT = 1;\n /** @constant {number} */\n BezierPath.END_CONTROL_POINT = 2;\n /** @constant {number} */\n BezierPath.END_POINT = 3;\n return BezierPath;\n}());\nexports.BezierPath = BezierPath;\n//# sourceMappingURL=BezierPath.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date_init 2012-10-17 (Wrote a first version of this in that year).\n * @date 2018-04-03 (Refactored the code into a new class).\n * @modified 2018-04-28 Added some documentation.\n * @modified 2019-09-11 Added the scaleToCentroid(Number) function (used by the walking triangle demo).\n * @modified 2019-09-12 Added beautiful JSDoc compliable comments.\n * @modified 2019-11-07 Added to toSVG(options) function to make Triangles renderable as SVG.\n * @modified 2019-12-09 Fixed the determinant() function. The calculation was just wrong.\n * @modified 2020-03-16 (Corona times) Added the 'fromArray' function.\n * @modified 2020-03-17 Added the Triangle.toPolygon() function.\n * @modified 2020-03-17 Added proper JSDoc comments.\n * @modified 2020-03-25 Ported this class from vanilla-JS to Typescript.\n * @modified 2020-05-09 Added the new Circle class (ported to Typescript from the demos).\n * @modified 2020-05-12 Added getIncircularTriangle() function.\n * @modified 2020-05-12 Added getIncircle() function.\n * @modified 2020-05-12 Fixed the signature of getCircumcirle(). Was still a generic object.\n * @modified 2020-06-18 Added the `getIncenter` function.\n * @modified 2020-12-28 Added the `getArea` function.\n * @modified 2021-01-20 Added UID.\n * @modified 2021-01-22 Always updating circumcircle when retieving it.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-02-02 Cleared the `Triangle.toSVGString` function (deprecated). Use `drawutilssvg` instead.\n * @modified 2024-11-22 Added static utility function Triangle.utils.determinant; adapted method `determinant`.\n * @modified 2024-11-22 Changing visibility of `Triangle.utils` from `private` to `public`.\n * @modified 2025-14-16 Class `Triangle` now implements interface `Intersectable`.\n * @modified 2025-14-16 Class `Triangle` now implements interface `IBounded`.\n * @modified 2025-14-16 Class `Triangle` now implements interface `Intersectable`.\n * @modified 2025-14-16 Added method `Triangle.move`.\n * @modified 2026-06-10 Refactoring the `Trianble.bounds` method and added a plain `Triangle.utils.bounds` method.\n * @modified 2026-06-10 Refactoring the `Trianble.calcCircumCircle` method and added a plain `Triangle.utils.calcCircumCircle` method.\n * @modified 2026-06-13 Adding `Triangle.getVertices()`.\n * @version 2.11.0\n *\n * @file Triangle\n * @fileoverview A simple triangle class: three vertices.\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Triangle = void 0;\nvar Bounds_1 = require(\"./Bounds\");\nvar Circle_1 = require(\"./Circle\");\nvar Line_1 = require(\"./Line\");\nvar Polygon_1 = require(\"./Polygon\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar Vector_1 = require(\"./Vector\");\nvar VertTuple_1 = require(\"./VertTuple\");\nvar Vertex_1 = require(\"./Vertex\");\nvar geomutils_1 = require(\"./geomutils\");\n/**\n * @classdesc A triangle class for triangulations.\n *\n * The class was written for a Delaunay trinagulation demo so it might\n * contain some strange and unexpected functions.\n *\n * @requires Bounds\n * @requires Circle\n * @requires Line\n * @requires Vertex\n * @requires Polygon\n * @requires SVGSerializale\n * @requires UID\n * @requires UIDGenerator\n * @requires geomutils\n *\n */\nvar Triangle = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name Triangle\n * @param {Vertex} a - The first vertex of the triangle.\n * @param {Vertex} b - The second vertex of the triangle.\n * @param {Vertex} c - The third vertex of the triangle.\n **/\n function Triangle(a, b, c) {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"Triangle\";\n this.uid = UIDGenerator_1.UIDGenerator.next();\n this.a = a;\n this.b = b;\n this.c = c;\n this.calcCircumcircle();\n }\n /**\n * Create a new triangle from the given array of vertices.\n *\n * The array must have at least three vertices, otherwise an error will be raised.\n * This function will not create copies of the vertices.\n *\n * @method fromArray\n * @static\n * @param {Array<Vertex>} arr - The required array with at least three vertices.\n * @memberof Vertex\n * @return {Triangle}\n **/\n Triangle.fromArray = function (arr) {\n if (arr.length < 3)\n throw \"Cannot create triangle from array with less than three vertices (\".concat(arr.length, \")\");\n return new Triangle(arr[0], arr[1], arr[2]);\n };\n /**\n * Get the area of this triangle. The returned area is never negative.\n *\n * If you are interested in the signed area, please consider using the\n * `Triangle.utils.signedArea` helper function. This method just returns\n * the absolute value of the signed area.\n *\n * @method getArea\n * @instance\n * @memberof Triangle\n * @return {number} The non-negative area of this triangle.\n */\n Triangle.prototype.getArea = function () {\n return Math.abs(Triangle.utils.signedArea(this.a.x, this.a.y, this.b.x, this.b.y, this.c.x, this.c.y));\n };\n /**\n * Get the centroid of this triangle.\n *\n * The centroid is the average midpoint for each side.\n *\n * @method getCentroid\n * @return {Vertex} The centroid\n * @instance\n * @memberof Triangle\n **/\n Triangle.prototype.getCentroid = function () {\n return new Vertex_1.Vertex((this.a.x + this.b.x + this.c.x) / 3, (this.a.y + this.b.y + this.c.y) / 3);\n };\n /**\n * Scale the triangle towards its centroid.\n *\n * @method scaleToCentroid\n * @param {number} - The scale factor to use. That can be any scalar.\n * @return {Triangle} this (for chaining)\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.scaleToCentroid = function (factor) {\n var centroid = this.getCentroid();\n this.a.scale(factor, centroid);\n this.b.scale(factor, centroid);\n this.c.scale(factor, centroid);\n return this;\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Get the bounding box (bounds) of this Triangle.\n *\n * @method getBounds\n * @instance\n * @memberof Triangle\n * @return {Bounds} The rectangular bounds of this Triangle.\n **/\n Triangle.prototype.getBounds = function () {\n // return Bounds.computeFromVertices([this.a, this.b, this.c]);\n return this.bounds();\n };\n //--- END --- Implement interface `IBounded`\n /**\n * Move the Triangle's vertices by the given amount.\n *\n * @method move\n * @param {XYCoords} amount - The amount to move.\n * @instance\n * @memberof Triangle\n * @return {Triangle} this for chaining\n **/\n Triangle.prototype.move = function (amount) {\n this.a.add(amount);\n this.b.add(amount);\n this.c.add(amount);\n return this;\n };\n /**\n * Get the circumcircle of this triangle.\n *\n * The circumcircle is that unique circle on which all three\n * vertices of this triangle are located on.\n *\n * Please note that for performance reasons any changes to vertices will not reflect in changes\n * of the circumcircle (center or radius). Please call the calcCirumcircle() function\n * after triangle vertex changes.\n *\n * @method getCircumcircle\n * @return {Circle} - The circle touching exactly all three triangle vertices.\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.getCircumcircle = function () {\n // if( !this.center || !this.radius )\n this.calcCircumcircle();\n return new Circle_1.Circle(this.center.clone(), this.radius);\n };\n /**\n * Calculates the minimun enclosing circle.\n *\n * @method getMinimumEnclosingCircle\n * @return {Object} - { center:Vertex, radius:float }\n * @instance\n * @memberof Triangle\n * @returns\n */\n Triangle.prototype.getMinimumEnclosingCircle = function () {\n // First option: two points construct a circle and the third point is contained.\n var circleAB = VertTuple_1.VertTuple.vtutils.calcCircumcircle(this.a, this.b);\n if (Circle_1.Circle.circleUtils.containsPoint(circleAB.center, circleAB.radius, this.c)) {\n return Circle_1.Circle.fromICircle(circleAB);\n }\n var circleBC = VertTuple_1.VertTuple.vtutils.calcCircumcircle(this.b, this.c);\n if (Circle_1.Circle.circleUtils.containsPoint(circleBC.center, circleBC.radius, this.c)) {\n return Circle_1.Circle.fromICircle(circleBC);\n }\n var circleCA = VertTuple_1.VertTuple.vtutils.calcCircumcircle(this.c, this.a);\n if (Circle_1.Circle.circleUtils.containsPoint(circleCA.center, circleCA.radius, this.c)) {\n return Circle_1.Circle.fromICircle(circleCA);\n }\n // If none of the three upper cases applies: return the circumcircle.\n var circumCircle = Triangle.utils.calcCircumcircle(this.a, this.b, this.c);\n return Circle_1.Circle.fromICircle(circumCircle);\n };\n /**\n * Check if this triangle and the passed triangle share an\n * adjacent edge.\n *\n * For edge-checking Vertex.equals is used which uses an\n * an epsilon for comparison.\n *\n * @method isAdjacent\n * @param {Triangle} tri - The second triangle to check adjacency with.\n * @return {boolean} - True if this and the passed triangle have at least one common edge.\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.isAdjacent = function (tri) {\n var a = this.a.equals(tri.a) || this.a.equals(tri.b) || this.a.equals(tri.c);\n var b = this.b.equals(tri.a) || this.b.equals(tri.b) || this.b.equals(tri.c);\n var c = this.c.equals(tri.a) || this.c.equals(tri.b) || this.c.equals(tri.c);\n return (a && b) || (a && c) || (b && c);\n };\n /**\n * Get that vertex of this triangle (a,b,c) that is not vert1 nor vert2 of\n * the passed two.\n *\n * @method getThirdVertex\n * @param {Vertex} vert1 - The first vertex.\n * @param {Vertex} vert2 - The second vertex.\n * @return {Vertex} - The third vertex of this triangle that makes up the whole triangle with vert1 and vert2.\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.getThirdVertex = function (vert1, vert2) {\n if ((this.a.equals(vert1) && this.b.equals(vert2)) || (this.a.equals(vert2) && this.b.equals(vert1)))\n return this.c;\n if ((this.b.equals(vert1) && this.c.equals(vert2)) || (this.b.equals(vert2) && this.c.equals(vert1)))\n return this.a;\n //if( this.c.equals(vert1) && this.a.equals(vert2) || this.c.equals(vert2) && this.a.equals(vert1) )\n return this.b;\n };\n /**\n * Get the three triangele vertices in a 3-element array.\n *\n * @method getVertices\n * @returns {[Vertex, Vertex, Vertex]} - The three vertices – real instances, not copies.\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.getVertices = function () {\n return [this.a, this.b, this.c];\n };\n /**\n * Re-compute the circumcircle of this triangle (if the vertices\n * have changed).\n *\n * The circumcenter and radius are stored in this.center and\n * this.radius. There is a third result: radius_squared (for internal computations).\n *\n * @method calcCircumcircle\n * @return void\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.calcCircumcircle = function () {\n // // From\n // // http://www.exaflop.org/docs/cgafaq/cga1.html\n // const A: number = this.b.x - this.a.x;\n // const B: number = this.b.y - this.a.y;\n // const C: number = this.c.x - this.a.x;\n // const D: number = this.c.y - this.a.y;\n // const E: number = A * (this.a.x + this.b.x) + B * (this.a.y + this.b.y);\n // const F: number = C * (this.a.x + this.c.x) + D * (this.a.y + this.c.y);\n // const G: number = 2.0 * (A * (this.c.y - this.b.y) - B * (this.c.x - this.b.x));\n // let dx: number, dy: number;\n // if (Math.abs(G) < Triangle.EPSILON) {\n // // Collinear - find extremes and use the midpoint\n // const bounds: Bounds = this.bounds();\n // this.center = new Vertex((bounds.min.x + bounds.max.x) / 2, (bounds.min.y + bounds.max.y) / 2);\n // dx = this.center.x - bounds.min.x;\n // dy = this.center.y - bounds.min.y;\n // } else {\n // const cx: number = (D * E - B * F) / G;\n // const cy: number = (A * F - C * E) / G;\n // this.center = new Vertex(cx, cy);\n // dx = this.center.x - this.a.x;\n // dy = this.center.y - this.a.y;\n // }\n // this.radius_squared = dx * dx + dy * dy;\n // this.radius = Math.sqrt(this.radius_squared);\n var tmpCircle = Triangle.utils.calcCircumcircle(this.a, this.b, this.c);\n this.center = new Vertex_1.Vertex(tmpCircle.center.x, tmpCircle.center.y);\n this.radius = tmpCircle.radius;\n this.radius_squared = tmpCircle.radius_squared;\n }; // END calcCircumcircle\n /**\n * Check if the passed vertex is inside this triangle's\n * circumcircle.\n *\n * @method inCircumcircle\n * @param {Vertex} v - The vertex to check.\n * @return {boolean}\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.inCircumcircle = function (v) {\n var dx = this.center.x - v.x;\n var dy = this.center.y - v.y;\n var dist_squared = dx * dx + dy * dy;\n return dist_squared <= this.radius_squared;\n };\n /**\n * Get the rectangular bounds for this triangle.\n *\n * @method bounds\n * @return {Bounds} - The min/max bounds of this triangle.\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.bounds = function () {\n // return new Bounds(\n // new Vertex(Triangle.utils.min3(this.a.x, this.b.x, this.c.x), Triangle.utils.min3(this.a.y, this.b.y, this.c.y)),\n // new Vertex(Triangle.utils.max3(this.a.x, this.b.x, this.c.x), Triangle.utils.max3(this.a.y, this.b.y, this.c.y))\n // );\n return Triangle.utils.bounds(this.a, this.b, this.c);\n };\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get all line intersections with this polygon.\n *\n * This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.\n *\n * See demo `47-closest-vector-projection-on-polygon` for how it works.\n *\n * @param {VertTuple} line - The line to find intersections with.\n * @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).\n * @returns {Array<Vertex>} - An array of all intersections within the polygon bounds.\n */\n Triangle.prototype.lineIntersections = function (line, inVectorBoundsOnly) {\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersections of all lines inside the edge bounds\n return Polygon_1.Polygon.utils\n .locateLineIntersecion(line, [this.a, this.b, this.c], false, inVectorBoundsOnly)\n .map(function (intersectionTuple) { return intersectionTuple.intersection; });\n };\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @param line\n * @param inVectorBoundsOnly\n * @returns\n */\n Triangle.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersection tangents of all lines inside the edge bounds\n return Polygon_1.Polygon.utils\n .locateLineIntersecion(line, [this.a, this.b, this.c], false, inVectorBoundsOnly)\n .map(function (intersectionTuple) {\n // const polyLine = this.getEdgeAt(intersectionTuple.edgeIndex);\n var polyLine = _this.getEdgeAt(intersectionTuple.edgeIndex);\n return new Vector_1.Vector(polyLine.a.clone(), polyLine.b.clone()).moveTo(intersectionTuple.intersection);\n });\n };\n //--- END --- Implement interface `Intersectable`\n Triangle.prototype.getEdgeAt = function (edgeIndex) {\n var modIndex = edgeIndex % 3;\n return modIndex === 0 ? new Line_1.Line(this.a, this.b) : modIndex === 1 ? new Line_1.Line(this.b, this.c) : new Line_1.Line(this.c, this.a);\n };\n /**\n * Convert this triangle to a polygon instance.\n *\n * Plase note that this conversion does not perform a deep clone.\n *\n * @method toPolygon\n * @return {Polygon} A new polygon representing this triangle.\n * @instance\n * @memberof Triangle\n **/\n Triangle.prototype.toPolygon = function () {\n return new Polygon_1.Polygon([this.a, this.b, this.c]);\n };\n /**\n * Get the determinant of this triangle.\n *\n * @method determinant\n * @return {number} - The determinant (float).\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.determinant = function () {\n // (b.y - a.y)*(c.x - b.x) - (c.y - b.y)*(b.x - a.x);\n // return (this.b.y - this.a.y) * (this.c.x - this.b.x) - (this.c.y - this.b.y) * (this.b.x - this.a.x);\n return Triangle.utils.determinant(this.a, this.b, this.c);\n };\n /**\n * Checks if the passed vertex (p) is inside this triangle.\n *\n * Note: matrix determinants rock.\n *\n * @method containsPoint\n * @param {Vertex} p - The vertex to check.\n * @return {boolean}\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.containsPoint = function (p) {\n return Triangle.utils.pointIsInTriangle(p.x, p.y, this.a.x, this.a.y, this.b.x, this.b.y, this.c.x, this.c.y);\n };\n /**\n * Get that inner triangle which defines the maximal incircle.\n *\n * @return {Triangle} The triangle of those points in this triangle that define the incircle.\n */\n Triangle.prototype.getIncircularTriangle = function () {\n var lineA = new Line_1.Line(this.a, this.b);\n var lineB = new Line_1.Line(this.b, this.c);\n var lineC = new Line_1.Line(this.c, this.a);\n var bisector1 = geomutils_1.geomutils.nsectAngle(this.b, this.a, this.c, 2)[0]; // bisector of first angle (in b)\n var bisector2 = geomutils_1.geomutils.nsectAngle(this.c, this.b, this.a, 2)[0]; // bisector of second angle (in c)\n // Cast to non-null here because we know there _is_ an intersection\n var intersection = bisector1.intersection(bisector2);\n // Find the closest points on one of the polygon lines (all have same distance by construction)\n var circleIntersA = lineA.getClosestPoint(intersection);\n var circleIntersB = lineB.getClosestPoint(intersection);\n var circleIntersC = lineC.getClosestPoint(intersection);\n return new Triangle(circleIntersA, circleIntersB, circleIntersC);\n };\n /**\n * Get the incircle of this triangle. That is the circle that touches each side\n * of this triangle in exactly one point.\n *\n * Note this just calls getIncircularTriangle().getCircumcircle()\n *\n * @return {Circle} The incircle of this triangle.\n */\n Triangle.prototype.getIncircle = function () {\n return this.getIncircularTriangle().getCircumcircle();\n };\n /**\n * Get the incenter of this triangle (which is the center of the circumcircle).\n *\n * Note: due to performance reasonst the incenter is buffered inside the triangle because\n * computing it is relatively expensive. If a, b or c have changed you should call the\n * calcCircumcircle() function first, otherwise you might get wrong results.\n * @return Vertex The incenter of this triangle.\n **/\n Triangle.prototype.getIncenter = function () {\n if (!this.center || !this.radius) {\n this.calcCircumcircle();\n }\n return this.center.clone();\n };\n /**\n * Converts this triangle into a human-readable string.\n *\n * @method toString\n * @return {string}\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.toString = function () {\n return \"{ a : \" + this.a.toString() + \", b : \" + this.b.toString() + \", c : \" + this.c.toString() + \"}\";\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n Triangle.prototype.destroy = function () {\n this.a.destroy();\n this.b.destroy();\n this.c.destroy();\n this.isDestroyed = true;\n };\n /**\n * An epsilon for comparison.\n * This should be the same epsilon as in Vertex.\n *\n * @private\n **/\n Triangle.EPSILON = 1.0e-6;\n Triangle.utils = {\n // Used in the bounds() function.\n max3: function (a, b, c) {\n return a >= b && a >= c ? a : b >= a && b >= c ? b : c;\n },\n min3: function (a, b, c) {\n return a <= b && a <= c ? a : b <= a && b <= c ? b : c;\n },\n signedArea: function (p0x, p0y, p1x, p1y, p2x, p2y) {\n return 0.5 * (-p1y * p2x + p0y * (-p1x + p2x) + p0x * (p1y - p2y) + p1x * p2y);\n },\n /**\n * Used by the containsPoint() function.\n *\n * @private\n **/\n pointIsInTriangle: function (px, py, p0x, p0y, p1x, p1y, p2x, p2y) {\n //\n // Point-in-Triangle test found at\n // http://stackoverflow.com/questions/2049582/how-to-determine-a-point-in-a-2d-triangle\n // var area : number = 1/2*(-p1y*p2x + p0y*(-p1x + p2x) + p0x*(p1y - p2y) + p1x*p2y);\n var area = Triangle.utils.signedArea(p0x, p0y, p1x, p1y, p2x, p2y);\n var s = (1 / (2 * area)) * (p0y * p2x - p0x * p2y + (p2y - p0y) * px + (p0x - p2x) * py);\n var t = (1 / (2 * area)) * (p0x * p1y - p0y * p1x + (p0y - p1y) * px + (p1x - p0x) * py);\n return s > 0 && t > 0 && 1 - s - t > 0;\n },\n /**\n * Calculate the determinant of the three vertices a, b and c (in this order).\n * @param {XYCords} a - The first vertex.\n * @param {XYCords} b - The first vertex.\n * @param {XYCords} c - The first vertex.\n * @returns {nmber}\n */\n determinant: function (a, b, c) {\n return (b.y - a.y) * (c.x - b.x) - (c.y - b.y) * (b.x - a.x);\n },\n bounds: function (a, b, c) {\n return new Bounds_1.Bounds(new Vertex_1.Vertex(Triangle.utils.min3(a.x, b.x, c.x), Triangle.utils.min3(a.y, b.y, c.y)), new Vertex_1.Vertex(Triangle.utils.max3(a.x, b.x, c.x), Triangle.utils.max3(a.y, b.y, c.y)));\n },\n /**\n * Re-compute the circumcircle of this triangle (if the vertices\n * have changed).\n *\n * The circumcenter and radius are stored in this.center and\n * this.radius. There is a third result: radius_squared (for internal computations).\n *\n * @method calcCircumcircle\n * @return void\n * @instance\n * @memberof Triangle\n */\n calcCircumcircle: function (a, b, c) {\n // From\n // http://www.exaflop.org/docs/cgafaq/cga1.html\n var A = b.x - a.x;\n var B = b.y - a.y;\n var C = c.x - a.x;\n var D = c.y - a.y;\n var E = A * (a.x + b.x) + B * (a.y + b.y);\n var F = C * (a.x + c.x) + D * (a.y + c.y);\n var G = 2.0 * (A * (c.y - b.y) - B * (c.x - b.x));\n var dx, dy;\n var center;\n if (Math.abs(G) < Triangle.EPSILON) {\n // Collinear - find extremes and use the midpoint\n // const bounds: Bounds = this.bounds();\n var bounds = Triangle.utils.bounds(a, b, c);\n center = new Vertex_1.Vertex((bounds.min.x + bounds.max.x) / 2, (bounds.min.y + bounds.max.y) / 2);\n dx = center.x - bounds.min.x;\n dy = center.y - bounds.min.y;\n }\n else {\n var cx = (D * E - B * F) / G;\n var cy = (A * F - C * E) / G;\n center = new Vertex_1.Vertex(cx, cy);\n dx = center.x - a.x;\n dy = center.y - a.y;\n }\n var radius_squared = dx * dx + dy * dy;\n var radius = Math.sqrt(radius_squared);\n return { center: center, radius: radius, radius_squared: radius_squared };\n } // END calcCircumcircle\n };\n return Triangle;\n}());\nexports.Triangle = Triangle;\n//# sourceMappingURL=Triangle.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2012-10-17\n * @modified 2018-04-03 Refactored the code of october 2012 into a new class.\n * @modified 2018-04-28 Added some documentation.\n * @modified 2018-08-16 Added the set() function.\n * @modified 2018-08-26 Added VertexAttr.\n * @modified 2018-10-31 Extended the constructor by object{x,y}.\n * @modified 2018-11-19 Extended the set(number,number) function to set(Vertex).\n * @modified 2018-11-28 Added 'this' to the VertexAttr constructor.\n * @modified 2018-12-05 Added the sub(...) function. Changed the signature of the add() function! add(Vertex) and add(number,number) are now possible.\n * @modified 2018-12-21 (It's winter solstice) Added the inv()-function.\n * @modified 2019-01-30 Added the setX(Number) and setY(Number) functions.\n * @modified 2019-02-19 Added the difference(Vertex) function.\n * @modified 2019-03-20 Added JSDoc tags.\n * @modified 2019-04-24 Added the randomVertex(ViewPort) function.\n * @modified 2019-11-07 Added toSVGString(object) function.\n * @modified 2019-11-18 Added the rotate(number,Vertex) function.\n * @modified 2019-11-21 Fixed a bug in the rotate(...) function (elements were moved).\n * @modified 2020-03-06 Added functions invX() and invY().\n * @modified 2020-03-23 Ported to Typescript from JS.\n * @modified 2020-05-26 Added functions addX(number) and addY(number).\n * @modified 2020-10-30 Changed the warnings in `sub(...)` and `add(...)` into real errors.\n * @modified 2021-03-01 Changed the second param `center` in the `rotate` function from Vertex to XYCoords.\n * @modified 2021-12-01 Changed the type of param of `scale` to XYCoords.\n * @modified 2021-12-01 Added function `scaleXY` for non uniform scaling.\n * @modified 2021-12-17 Added the functions `lerp` and `lerpAbs` for linear interpolations.\n * @modified 2022-01-31 Added `Vertex.utils.arrayToJSON`.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-02-02 Cleared the `Vertex.toSVGString` function (deprecated). Use `drawutilssvg` instead.\n * @modified 2022-11-28 Added the `subXY`, `subX` and `subY` methods to the `Vertex` class.\n * @modified 2023-09-29 Downgraded types for the `Vertex.utils.buildArrowHead` function (replacing Vertex params by more generic XYCoords type).\n * @modified 2023-09-29 Added the `Vertex.abs()` method as it seems useful.\n * @modified 2024-03-08 Added the optional `precision` param to the `toString` method.\n * @modified 2024-12-17 Outsourced the euclidean distance calculation of `Vertex.distance` to `geomutils.dist4`.\n * @modified 2025-03-24 Making the second parameter `center` of the `Vertex.rotate` method optional.\n * @modified 2025-04-13 Adding the `Vertex.move(amount: XYCoords)` method (does the same as `add`, added by naming convention).\n * @modified 2025-05-07 Class `Vertex` is now implementing interface `IBounded` (to meet convention).\n * @modified 2026-06-10 Adding methods `Vertex.findClosestPoint` and `Vertex.findFarestPoint`.\n * @version 2.12.0\n *\n * @file Vertex\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Vertex = void 0;\nvar VertexAttr_1 = require(\"./VertexAttr\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar VertexListeners_1 = require(\"./VertexListeners\");\nvar geomutils_1 = require(\"./geomutils\");\nvar Bounds_1 = require(\"./Bounds\");\n/**\n * @classdesc A vertex is a pair of two numbers.<br>\n * <br>\n * It is used to identify a 2-dimensional point on the x-y-plane.\n *\n * @requires IVertexAttr\n * @requires SVGSerializable\n * @requires UID\n * @requires UIDGenerator\n * @requires VertexAttr\n * @requires VertexListeners\n * @requires XYCoords\n *\n */\nvar Vertex = /** @class */ (function () {\n /**\n * The constructor for the vertex class.\n *\n * @constructor\n * @name Vertex\n * @param {number} x - The x-coordinate of the new vertex.\n * @param {number} y - The y-coordinate of the new vertex.\n **/\n function Vertex(x, y) {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"Vertex\";\n this.uid = UIDGenerator_1.UIDGenerator.next();\n if (typeof x == \"undefined\") {\n this.x = 0;\n this.y = 0;\n }\n else if (typeof x == \"number\" && typeof y == \"number\") {\n this.x = x;\n this.y = y;\n }\n else {\n var tuple = x;\n if (typeof tuple.x == \"number\" && typeof tuple.y == \"number\") {\n this.x = tuple.x;\n this.y = tuple.y;\n }\n else {\n if (typeof x == \"number\")\n this.x = x;\n else if (typeof x == \"undefined\")\n this.x = 0;\n else\n this.x = NaN;\n if (typeof y == \"number\")\n this.y = y;\n else if (typeof y == \"undefined\")\n this.y = 0;\n else\n this.y = NaN;\n }\n }\n this.attr = new VertexAttr_1.VertexAttr();\n this.listeners = new VertexListeners_1.VertexListeners(this);\n }\n /**\n * Set the x- and y- component of this vertex.\n *\n * @method set\n * @param {number} x - The new x-component.\n * @param {number} y - The new y-component.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.set = function (x, y) {\n if (typeof x == \"number\" && typeof y == \"number\") {\n this.x = x;\n this.y = y;\n }\n else {\n var tuple = x;\n if (typeof tuple.x == \"number\" && typeof tuple.y == \"number\") {\n this.x = tuple.x;\n this.y = tuple.y;\n }\n else {\n if (typeof x == \"number\")\n this.x = x;\n else if (typeof x == \"undefined\")\n this.x = 0;\n else\n this.x = NaN;\n if (typeof y == \"number\")\n this.y = y;\n else if (typeof y == \"undefined\")\n this.y = 0;\n else\n this.y = NaN;\n }\n }\n return this;\n };\n /**\n * Set the x-component of this vertex.\n *\n * @method setX\n * @param {number} x - The new x-component.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.setX = function (x) {\n this.x = x;\n return this;\n };\n /**\n * Set the y-component of this vertex.\n *\n * @method setY\n * @param {number} y - The new y-component.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.setY = function (y) {\n this.y = y;\n return this;\n };\n /**\n * Set the x-component if this vertex to the inverse of its value.\n *\n * @method invX\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.invX = function () {\n this.x = -this.x;\n return this;\n };\n /**\n * Set the y-component if this vertex to the inverse of its value.\n *\n * @method invY\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.invY = function () {\n this.y = -this.y;\n return this;\n };\n /**\n * Add the passed amount to x- and y- component of this vertex.<br>\n * <br>\n * This function works with add( {number}, {number} ) and\n * add( {Vertex} ), as well.\n *\n * @method add\n * @param {(number|Vertex)} x - The amount to add to x (or a vertex itself).\n * @param {number=} y - The amount to add to y.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.add = function (x, y) {\n if (typeof x == \"number\" && typeof y == \"number\") {\n this.x += x;\n this.y += y;\n }\n else {\n var tuple = x;\n if (typeof tuple.x == \"number\" && typeof tuple.y == \"number\") {\n this.x += tuple.x;\n this.y += tuple.y;\n }\n else {\n if (typeof x == \"number\")\n this.x += x;\n else\n throw \"Cannot add \".concat(typeof x, \" to numeric x component!\");\n if (typeof y == \"number\")\n this.y += y;\n else\n throw \"Cannot add \".concat(typeof y, \" to numeric y component!\");\n }\n }\n return this;\n };\n /**\n * Move this point by the given amount.\n *\n * This method just calls `add(amount).\n *\n *\n * @method move\n * @param {Vertex} amount - The amount to move this vertex.\n * @return {Vertex} this - For chaining.\n * @instance\n * @memberof Vertex\n */\n Vertex.prototype.move = function (amount) {\n return this.add(amount);\n };\n /**\n * Add the passed amounts to the x- and y- components of this vertex.\n *\n * @method addXY\n * @param {number} x - The amount to add to x.\n * @param {number} y - The amount to add to y.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.addXY = function (amountX, amountY) {\n this.x += amountX;\n this.y += amountY;\n return this;\n };\n /**\n * Add the passed amounts to the x-component of this vertex.\n *\n * @method addX\n * @param {number} x - The amount to add to x.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.addX = function (amountX) {\n this.x += amountX;\n return this;\n };\n /**\n * Add the passed amounts to the y-component of this vertex.\n *\n * @method addY\n * @param {number} y - The amount to add to y.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.addY = function (amountY) {\n this.y += amountY;\n return this;\n };\n /**\n * Substract the passed amount from x- and y- component of this vertex.<br>\n * <br>\n * This function works with sub( {number}, {number} ) and\n * sub( {Vertex} ), as well.\n *\n * @method sub\n * @param {(number|Vertex)} x - The amount to substract from x (or a vertex itself).\n * @param {number=} y - The amount to substract from y.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.sub = function (x, y) {\n if (typeof x == \"number\" && typeof y == \"number\") {\n this.x -= x;\n this.y -= y;\n }\n else {\n var tuple = x;\n if (typeof tuple.x == \"number\" && typeof tuple.y == \"number\") {\n this.x -= tuple.x;\n this.y -= tuple.y;\n }\n else {\n if (typeof x == \"number\")\n this.x -= x;\n else\n throw \"Cannot add \".concat(typeof x, \" to numeric x component!\");\n if (typeof y == \"number\")\n this.y -= y;\n else\n throw \"Cannot add \".concat(typeof y, \" to numeric y component!\");\n }\n }\n return this;\n };\n /**\n * Substract the passed amounts from the x- and y- components of this vertex.\n *\n * @method subXY\n * @param {number} x - The amount to substract from x.\n * @param {number} y - The amount to substract from y.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.subXY = function (amountX, amountY) {\n this.x -= amountX;\n this.y -= amountY;\n return this;\n };\n /**\n * Substract the passed amounts from the x-component of this vertex.\n *\n * @method addX\n * @param {number} x - The amount to substract from x.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.subX = function (amountX) {\n this.x -= amountX;\n return this;\n };\n /**\n * Substract the passed amounts from the y-component of this vertex.\n *\n * @method subY\n * @param {number} y - The amount to substract from y.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.subY = function (amountY) {\n this.y -= amountY;\n return this;\n };\n /**\n * Check if this vertex equals the passed one.\n * <br>\n * This function uses an internal epsilon as tolerance.\n *\n * @method equals\n * @param {Vertex} vertex - The vertex to compare this with.\n * @return {boolean}\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.equals = function (vertex) {\n var eqX = Math.abs(this.x - vertex.x) < Vertex.EPSILON;\n var eqY = Math.abs(this.y - vertex.y) < Vertex.EPSILON;\n var result = eqX && eqY;\n return result;\n };\n /**\n * Create a copy of this vertex.\n *\n * @method clone\n * @return {Vertex} A new vertex, an exact copy of this.\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.clone = function () {\n return new Vertex(this.x, this.y);\n };\n /**\n * Get the distance to the passed point (in euclidean metric)\n *\n * @method distance\n * @param {XYCoords} vert - The vertex to measure the distance to.\n * @return {number}\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.distance = function (vert) {\n // return Math.sqrt(Math.pow(vert.x - this.x, 2) + Math.pow(vert.y - this.y, 2));\n return geomutils_1.geomutils.dist4(this.x, this.y, vert.x, vert.y);\n };\n /**\n * Get the angle of this point (relative to (0,0) or to the given other origin point).\n *\n * @method angle\n * @param {XYCoords} origin - The vertex to measure the angle from.\n * @return {number}\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.angle = function (origin) {\n var a = typeof origin === \"undefined\"\n ? Math.PI / 2 - Math.atan2(this.x, this.y)\n : Math.PI / 2 - Math.atan2(origin.x - this.x, origin.y - this.y);\n // Map to positive value\n return a < 0 ? Math.PI * 2 + a : a;\n };\n /**\n * Get the difference to the passed point.<br>\n * <br>\n * The difference is (vert.x-this.x, vert.y-this.y).\n *\n * @method difference\n * @param {Vertex} vert - The vertex to measure the x-y-difference to.\n * @return {Vertex} A new vertex.\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.difference = function (vert) {\n return new Vertex(vert.x - this.x, vert.y - this.y);\n };\n /**\n * This is a vector-like behavior and 'scales' this vertex\n * towards/from a given center by one uniform scale factor.\n *\n * @method scale\n * @param {number} factor - The factor to 'scale' this vertex; 1.0 means no change.\n * @param {XYCoords=} center - The origin of scaling; default is (0,0).\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.scale = function (factor, center) {\n return this.scaleXY({ x: factor, y: factor }, center);\n };\n /**\n * Perform a linear interpolation towards the given target vertex.\n * The amount value `t` is relative, `t=0.0` means no change, `t=1.0`\n * means this point will be moved to the exact target position.\n *\n * `t=0.5` will move this point to the middle of the connecting\n * linear segment.\n *\n * @param {XYCoords} target - The target position to lerp this vertex to.\n * @param {number} t - The relative amount, usually in [0..1], but other values will work, too.\n * @returns\n */\n Vertex.prototype.lerp = function (target, t) {\n var diff = this.difference(target);\n // return new Vertex(this.x + diff.x * t, this.y + diff.y * t);\n this.x += diff.x * t;\n this.y += diff.y * t;\n return this;\n };\n /**\n * Perform a linear interpolation towards the given target vertex (absolute variant).\n * The amount value `t` is absolute, which means the lerp amount is a direct distance\n * value. This point will have move the amount of the passed distance `u`.\n *\n * @param {XYCoords} target - The target position to lerp this vertex to.\n * @param {number} t - The absolute move amount to use to lerping.\n * @returns\n */\n Vertex.prototype.lerpAbs = function (target, u) {\n var dist = this.distance(target);\n var diff = this.difference(target);\n var step = { x: diff.x / dist, y: diff.y / dist };\n // return new Vertex(this.x + step.x * u, this.y + step.y * u);\n this.x += step.x * u;\n this.y += step.y * u;\n return this;\n };\n /**\n * This is a vector-like behavior and 'scales' this vertex\n * towards/from a given center by two independent x- and y- scale factors.\n *\n * @method scale\n * @param {number} factor - The factor to 'scale' this vertex; 1.0 means no change.\n * @param {XYCoords=} center - The origin of scaling; default is (0,0).\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.scaleXY = function (factors, center) {\n if (!center || typeof center === \"undefined\") {\n center = { x: 0, y: 0 };\n }\n this.x = center.x + (this.x - center.x) * factors.x;\n this.y = center.y + (this.y - center.y) * factors.y;\n return this;\n };\n /**\n * This is a vector-like behavior and 'rotates' this vertex\n * around given center.\n *\n * @method rotate\n * @param {number} angle - The angle to 'rotate' this vertex; 0.0 means no change.\n * @param {XYCoords=} center - The center of rotation; default is (0,0).\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.rotate = function (angle, center) {\n if (!center || typeof center === \"undefined\") {\n center = { x: 0, y: 0 };\n }\n this.sub(center);\n angle += Math.atan2(this.y, this.x);\n var len = this.distance(Vertex.ZERO); // {x:0,y:0});\n this.x = len * Math.cos(angle);\n this.y = len * Math.sin(angle);\n this.add(center);\n return this;\n };\n /**\n * Multiply both components of this vertex with the given scalar.<br>\n * <br>\n * Note: as in<br>\n * https://threejs.org/docs/#api/math/Vector2.multiplyScalar\n *\n * @method multiplyScalar\n * @param {number} scalar - The scale factor; 1.0 means no change.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.multiplyScalar = function (scalar) {\n this.x *= scalar;\n this.y *= scalar;\n return this;\n };\n /**\n * Round the two components x and y of this vertex.\n *\n * @method round\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.round = function () {\n this.x = Math.round(this.x);\n this.y = Math.round(this.y);\n return this;\n };\n /**\n * Change this vertex (x,y) to its inverse (-x,-y).\n *\n * @method inv\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.inv = function () {\n this.x = -this.x;\n this.y = -this.y;\n return this;\n };\n /**\n * Set both coordinates of this vertex to their absolute value (abs(x), abs(y)).\n *\n * @method abs\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n */\n Vertex.prototype.abs = function () {\n this.x = Math.abs(this.x);\n this.y = Math.abs(this.y);\n return this;\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Get the bounding box (bounds) of this Vertex.\n * This is just by convention – any vertex is just a position without any useful with or height (0).\n *\n * @method getBounds\n * @instance\n * @memberof Vertex\n * @return {Bounds} The rectangular bounds of this Vertex (width and height are zero).\n **/\n Vertex.prototype.getBounds = function () {\n // return Bounds.computeFromVertices([this.a, this.b, this.c]);\n return Bounds_1.Bounds.computeFromVertices([this]);\n };\n //--- END --- Implement interface `IBounded`\n /**\n * Find the one of two given points that's closest to this point.\n *\n * @method findClosestPoint\n * @instance\n * @memberof Vertex\n * @param {XYCoords | Vertex} pointA\n * @param {XYCoords | Vertex} pointB\n * @returns {XYCoords | Vertex}\n */\n Vertex.prototype.findClosestPoint = function (pointA, pointB) {\n // TODO: put this implementation to geomutils?\n var distA = this.distance(pointA);\n var distB = this.distance(pointB);\n if (distA < distB) {\n return pointA;\n }\n else {\n return pointB;\n }\n };\n /**\n * Find the one of two given points that's farest from this point.\n *\n * @method findFarestPoint\n * @instance\n * @memberof Vertex\n * @param {XYCoords | Vertex} pointA\n * @param {XYCoords | Vertex} pointB\n * @returns {XYCoords | Vertex}\n */\n Vertex.prototype.findFarestPoint = function (pointA, pointB) {\n var distA = this.distance(pointA);\n var distB = this.distance(pointB);\n if (distA > distB) {\n return pointA;\n }\n else {\n return pointB;\n }\n };\n /**\n * Get a string representation of this vertex.\n *\n * @method toString\n * @return {string} The string representation of this vertex.\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.toString = function (precision) {\n if (typeof precision === \"undefined\") {\n return \"(\" + this.x + \",\" + this.y + \")\";\n }\n else {\n return \"(\" + this.x.toFixed(precision) + \",\" + this.y.toFixed(precision) + \")\";\n }\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n Vertex.prototype.destroy = function () {\n this.listeners.removeAllListeners();\n this.isDestroyed = true;\n };\n /**\n * Create a new random vertex inside the given viewport.\n *\n * @param {ViewPort} viewPort - A {min:Vertex, max:Vertex} viewport specifying the bounds.\n * @return A new vertex with a random position.\n **/\n Vertex.randomVertex = function (viewPort) {\n return new Vertex(viewPort.min.x + Math.random() * (viewPort.max.x - viewPort.min.x), viewPort.min.y + Math.random() * (viewPort.max.y - viewPort.min.y));\n };\n Vertex.ZERO = new Vertex(0, 0);\n /**\n * An epsilon for comparison\n *\n * @private\n * @readonly\n **/\n Vertex.EPSILON = 1.0e-6;\n Vertex.utils = {\n /**\n * Generate a four-point arrow head, starting at the vector end minus the\n * arrow head length.\n *\n * The first vertex in the returned array is guaranteed to be the located\n * at the vector line end minus the arrow head length.\n *\n *\n * Due to performance all params are required.\n *\n * The params scaleX and scaleY are required for the case that the scaling is not uniform (x and y\n * scaling different). Arrow heads should not look distored on non-uniform scaling.\n *\n * If unsure use 1.0 for scaleX and scaleY (=no distortion).\n * For headlen use 8, it's a good arrow head size.\n *\n * Example:\n * buildArrowHead( new Vertex(0,0), new Vertex(50,100), 8, 1.0, 1.0 )\n *\n * @param {XYCoords} zA - The start vertex of the vector to calculate the arrow head for.\n * @param {XYCoords} zB - The end vertex of the vector.\n * @param {number} headlen - The length of the arrow head (along the vector direction. A good value is 12).\n * @param {number} scaleX - The horizontal scaling during draw.\n * @param {number} scaleY - the vertical scaling during draw.\n **/\n // @DEPRECATED: use Vector.utils.buildArrowHead instead!!!\n buildArrowHead: function (zA, zB, headlen, scaleX, scaleY) {\n console.warn(\"[DEPRECATION] Vertex.utils.buildArrowHead is deprecated. Please use Vector.utils.buildArrowHead instead.\");\n var angle = Math.atan2((zB.y - zA.y) * scaleY, (zB.x - zA.x) * scaleX);\n var vertices = [];\n vertices.push(new Vertex(zB.x * scaleX - headlen * Math.cos(angle), zB.y * scaleY - headlen * Math.sin(angle)));\n vertices.push(new Vertex(zB.x * scaleX - headlen * 1.35 * Math.cos(angle - Math.PI / 8), zB.y * scaleY - headlen * 1.35 * Math.sin(angle - Math.PI / 8)));\n vertices.push(new Vertex(zB.x * scaleX, zB.y * scaleY));\n vertices.push(new Vertex(zB.x * scaleX - headlen * 1.35 * Math.cos(angle + Math.PI / 8), zB.y * scaleY - headlen * 1.35 * Math.sin(angle + Math.PI / 8)));\n return vertices;\n },\n /**\n * Convert the given vertices (array) to a JSON string.\n *\n * @param {number?} precision - (optional) The numeric precision to be used (number of precision digits).\n * @returns {string}\n */\n arrayToJSON: function (vertices, precision) {\n return JSON.stringify(vertices.map(function (vert) {\n return typeof precision === undefined\n ? { x: vert.x, y: vert.y }\n : { x: Number(vert.x.toFixed(precision)), y: Number(vert.y.toFixed(precision)) };\n }));\n }\n };\n return Vertex;\n}());\nexports.Vertex = Vertex;\n//# sourceMappingURL=Vertex.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2019-01-30\n * @modified 2019-03-23 Added JSDoc tags.\n * @modified 2020-03-25 Ported this class from vanilla-JS to Typescript.\n * @modified 2021-01-20 Added UID.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-02-02 Cleared the `PBImage.toSVGString` function (deprecated). Use `drawutilssvg` instead.\n * @version 1.2.0\n *\n * @file PBImage\n * @fileoverview As native Image objects have only a position and with\n * and height thei are not suitable for UI dragging interfaces.\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.PBImage = void 0;\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\n/**\n * @classdesc A wrapper for image objects. Has an upper left and a lower right corner point.\n *\n * @requires Vertex\n * @requires SVGSerializable\n * @requires UID\n * @requires UIDGenerator\n */\nvar PBImage = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name PBImage\n * @param {Image} image - The actual image.\n * @param {Vertex} upperLeft - The upper left corner.\n * @param {Vertex} lowerRight - The lower right corner.\n **/\n function PBImage(image, upperLeft, lowerRight) {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"PBImage\";\n this.uid = UIDGenerator_1.UIDGenerator.next();\n this.image = image;\n this.upperLeft = upperLeft;\n this.lowerRight = lowerRight;\n }\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n PBImage.prototype.destroy = function () {\n this.upperLeft.destroy();\n this.lowerRight.destroy();\n this.isDestroyed = true;\n };\n return PBImage;\n}());\nexports.PBImage = PBImage;\n//# sourceMappingURL=PBImage.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2018-11-28\n * @modified 2018-12-04 Added the toSVGString function.\n * @modified 2020-03-25 Ported this class from vanilla-JS to Typescript.\n * @modified 2021-01-20 Added UID.\n * @modified 2021-02-14 Added functions `radiusH` and `radiusV`.\n * @modified 2021-02-26 Added helper function `decribeSVGArc(...)`.\n * @modified 2021-03-01 Added attribute `rotation` to allow rotation of ellipses.\n * @modified 2021-03-03 Added the `vertAt` and `perimeter` methods.\n * @modified 2021-03-05 Added the `getFoci`, `normalAt` and `tangentAt` methods.\n * @modified 2021-03-09 Added the `clone` and `rotate` methods.\n * @modified 2021-03-10 Added the `toCubicBezier` method.\n * @modified 2021-03-15 Added `VEllipse.quarterSegmentCount` and `VEllipse.scale` functions.\n * @modified 2021-03-19 Added the `VEllipse.rotate` function.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-02-02 Cleared the `VEllipse.toSVGString` function (deprecated). Use `drawutilssvg` instead.\n * @modified 2025-03-31 ATTENTION: modified the winding direction of the `tangentAt` method to match with the Circle method. This is a breaking change!\n * @modified 2025-03-31 Adding the `VEllipse.move(amount: XYCoords)` method.\n * @modified 2025-04-19 Adding the `VEllipse.getBounds()` method.\n * @modified 2025-04-24 Adding the `VEllipse.getExtremePoints()` method for calculating minima and maxima.\n * @version 1.4.0\n *\n * @file VEllipse\n * @fileoverview Ellipses with a center and an x- and a y-axis (stored as a vertex).\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.VEllipse = void 0;\nvar Line_1 = require(\"./Line\");\nvar Vector_1 = require(\"./Vector\");\nvar Vertex_1 = require(\"./Vertex\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar CubicBezierCurve_1 = require(\"./CubicBezierCurve\");\nvar Circle_1 = require(\"./Circle\");\nvar Bounds_1 = require(\"./Bounds\");\n/**\n * @classdesc An ellipse class based on two vertices [centerX,centerY] and [radiusX,radiusY].\n *\n * @requires SVGSerializable\n * @requires UID\n * @requires UIDGenerator\n * @requires Vertex\n */\nvar VEllipse = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @param {Vertex} center - The ellipses center.\n * @param {Vertex} axis - The x- and y-axis (the two radii encoded in a control point).\n * @param {Vertex} rotation - [optional, default=0] The rotation of this ellipse.\n * @name VEllipse\n **/\n function VEllipse(center, axis, rotation) {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"VEllipse\";\n this.uid = UIDGenerator_1.UIDGenerator.next();\n this.center = center;\n this.axis = axis;\n this.rotation = rotation || 0.0;\n }\n /**\n * Clone this ellipse (deep clone).\n *\n * @return {VEllipse} A copy of this ellipse.s\n */\n VEllipse.prototype.clone = function () {\n return new VEllipse(this.center.clone(), this.axis.clone(), this.rotation);\n };\n /**\n * Get the non-negative horizonal radius of this ellipse.\n *\n * @method radiusH\n * @instance\n * @memberof VEllipse\n * @return {number} The unsigned horizontal radius of this ellipse.\n */\n VEllipse.prototype.radiusH = function () {\n return Math.abs(this.signedRadiusH());\n };\n /**\n * Get the signed horizonal radius of this ellipse.\n *\n * @method signedRadiusH\n * @instance\n * @memberof VEllipse\n * @return {number} The signed horizontal radius of this ellipse.\n */\n VEllipse.prototype.signedRadiusH = function () {\n // return Math.abs(this.axis.x - this.center.x);\n // Rotate axis back to origin before calculating radius\n // return Math.abs(new Vertex(this.axis).rotate(-this.rotation,this.center).x - this.center.x);\n return new Vertex_1.Vertex(this.axis).rotate(-this.rotation, this.center).x - this.center.x;\n };\n /**\n * Get the non-negative vertical radius of this ellipse.\n *\n * @method radiusV\n * @instance\n * @memberof VEllipse\n * @return {number} The unsigned vertical radius of this ellipse.\n */\n VEllipse.prototype.radiusV = function () {\n return Math.abs(this.signedRadiusV());\n };\n /**\n * Get the signed vertical radius of this ellipse.\n *\n * @method radiusV\n * @instance\n * @memberof VEllipse\n * @return {number} The signed vertical radius of this ellipse.\n */\n VEllipse.prototype.signedRadiusV = function () {\n // Rotate axis back to origin before calculating radius\n return new Vertex_1.Vertex(this.axis).rotate(-this.rotation, this.center).y - this.center.y;\n };\n /**\n * Get the the minima and maxima (points) of this (rotated) ellipse.\n *\n * @method getExtremePoints\n * @instance\n * @memberof VEllipse\n * @return {[Vertex, Vertex, Vertex, Vertex]} Get the the minima and maxima (points) of this (rotated) ellipse.\n */\n VEllipse.prototype.getExtremePoints = function () {\n var a = this.radiusH();\n var b = this.radiusV();\n // Calculate t_x values\n var t_x1 = Math.atan2(-b * Math.sin(this.rotation), a * Math.cos(this.rotation));\n var t_x2 = t_x1 + Math.PI;\n // Calculate x values at t_x\n var x_x1 = this.center.x + a * Math.cos(t_x1) * Math.cos(this.rotation) - b * Math.sin(t_x1) * Math.sin(this.rotation);\n var y_x1 = this.center.y + a * Math.cos(t_x1) * Math.sin(this.rotation) + b * Math.sin(t_x1) * Math.cos(this.rotation);\n var x_x2 = this.center.x + a * Math.cos(t_x2) * Math.cos(this.rotation) - b * Math.sin(t_x2) * Math.sin(this.rotation);\n var y_x2 = this.center.y + a * Math.cos(t_x2) * Math.sin(this.rotation) + b * Math.sin(t_x2) * Math.cos(this.rotation);\n var x_max, x_min;\n if (x_x1 > x_x2) {\n x_max = new Vertex_1.Vertex(x_x1, y_x1);\n x_min = new Vertex_1.Vertex(x_x2, y_x2);\n }\n else {\n x_max = new Vertex_1.Vertex(x_x2, y_x2);\n x_min = new Vertex_1.Vertex(x_x1, y_x1);\n }\n // Calculate t_y values\n var t_y1 = Math.atan2(b * Math.cos(this.rotation), a * Math.sin(this.rotation));\n var t_y2 = t_y1 + Math.PI;\n // Calculate y values at t_y\n var x_y1 = this.center.x + a * Math.cos(t_y1) * Math.cos(this.rotation) - b * Math.sin(t_y1) * Math.sin(this.rotation);\n var y_y1 = this.center.y + a * Math.cos(t_y1) * Math.sin(this.rotation) + b * Math.sin(t_y1) * Math.cos(this.rotation);\n var x_y2 = this.center.x + a * Math.cos(t_y2) * Math.cos(this.rotation) - b * Math.sin(t_y2) * Math.sin(this.rotation);\n var y_y2 = this.center.y + a * Math.cos(t_y2) * Math.sin(this.rotation) + b * Math.sin(t_y2) * Math.cos(this.rotation);\n var y_max, y_min;\n if (y_y1 > y_y2) {\n y_max = new Vertex_1.Vertex(x_y1, y_y1);\n y_min = new Vertex_1.Vertex(x_y2, y_y2);\n }\n else {\n y_max = new Vertex_1.Vertex(x_y2, y_y2);\n y_min = new Vertex_1.Vertex(x_y1, y_y1);\n }\n return [x_max, x_min, y_max, y_min];\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Get the bounds of this ellipse.\n *\n * The bounds are approximated by the underlying segment buffer; the more segment there are,\n * the more accurate will be the returned bounds.\n *\n * @method getBounds\n * @instance\n * @memberof VEllipse\n * @return {Bounds} The bounds of this ellipse.\n **/\n VEllipse.prototype.getBounds = function () {\n // Thanks to Cuixiping\n // https://stackoverflow.com/questions/87734/how-do-you-calculate-the-axis-aligned-bounding-box-of-an-ellipse\n var r1 = this.radiusH();\n var r2 = this.radiusV();\n var ux = r1 * Math.cos(this.rotation);\n var uy = r1 * Math.sin(this.rotation);\n var vx = r2 * Math.cos(this.rotation + Math.PI / 2);\n var vy = r2 * Math.sin(this.rotation + Math.PI / 2);\n var bbox_halfwidth = Math.sqrt(ux * ux + vx * vx);\n var bbox_halfheight = Math.sqrt(uy * uy + vy * vy);\n return new Bounds_1.Bounds({ x: this.center.x - bbox_halfwidth, y: this.center.y - bbox_halfheight }, { x: this.center.x + bbox_halfwidth, y: this.center.y + bbox_halfheight });\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Move the ellipse by the given amount. This is equivalent by moving the `center` and `axis` points.\n *\n * @method move\n * @param {XYCoords} amount - The amount to move.\n * @instance\n * @memberof VEllipse\n * @return {VEllipse} this for chaining\n **/\n VEllipse.prototype.move = function (amount) {\n this.center.add(amount);\n this.axis.add(amount);\n return this;\n };\n /**\n * Scale this ellipse by the given factor from the center point. The factor will be applied to both radii.\n *\n * @method scale\n * @instance\n * @memberof VEllipse\n * @param {number} factor - The factor to scale by.\n * @return {VEllipse} this for chaining.\n */\n VEllipse.prototype.scale = function (factor) {\n this.axis.scale(factor, this.center);\n return this;\n };\n /**\n * Rotate this ellipse around its center.\n *\n * @method rotate\n * @instance\n * @memberof VEllipse\n * @param {number} angle - The angle to rotate by.\n * @returns {VEllipse} this for chaining.\n */\n VEllipse.prototype.rotate = function (angle) {\n this.axis.rotate(angle, this.center);\n this.rotation += angle;\n return this;\n };\n /**\n * Get the vertex on the ellipse's outline at the given angle.\n *\n * @method vertAt\n * @instance\n * @memberof VEllipse\n * @param {number} angle - The angle to determine the vertex at.\n * @return {Vertex} The vertex on the outline at the given angle.\n */\n VEllipse.prototype.vertAt = function (angle) {\n // Tanks to Narasinham for the vertex-on-ellipse equations\n // https://math.stackexchange.com/questions/22064/calculating-a-point-that-lies-on-an-ellipse-given-an-angle\n var a = this.radiusH();\n var b = this.radiusV();\n return new Vertex_1.Vertex(VEllipse.utils.polarToCartesian(this.center.x, this.center.y, a, b, angle)).rotate(this.rotation, this.center);\n };\n /**\n * Get the normal vector at the given angle.\n * The normal vector is the vector that intersects the ellipse in a 90 degree angle\n * at the given point (speicified by the given angle).\n *\n * Length of desired normal vector can be specified, default is 1.0.\n *\n * @method normalAt\n * @instance\n * @memberof VEllipse\n * @param {number} angle - The angle to get the normal vector at.\n * @param {number=1.0} length - [optional, default=1] The length of the returned vector.\n */\n VEllipse.prototype.normalAt = function (angle, length) {\n var point = this.vertAt(angle - this.rotation); // HERE IS THE CORRECT BEHAVIOR!\n var foci = this.getFoci();\n // Calculate the angle between [point,focusA] and [point,focusB]\n var angleA = new Line_1.Line(point, foci[0]).angle();\n var angleB = new Line_1.Line(point, foci[1]).angle();\n var centerAngle = angleA + (angleB - angleA) / 2.0;\n var endPointA = point.clone().addX(50).clone().rotate(centerAngle, point);\n var endPointB = point\n .clone()\n .addX(50)\n .clone()\n .rotate(Math.PI + centerAngle, point);\n var resultVector = this.center.distance(endPointA) < this.center.distance(endPointB)\n ? new Vector_1.Vector(point, endPointB)\n : new Vector_1.Vector(point, endPointA);\n if (typeof length === \"number\") {\n resultVector.setLength(length);\n }\n return resultVector;\n };\n /**\n * Get the tangent vector at the given angle.\n * The tangent vector is the vector that touches the ellipse exactly at the given given\n * point (speicified by the given angle).\n *\n * Note that the tangent is just 90 degree rotated normal vector.\n *\n * Length of desired tangent vector can be specified, default is 1.0.\n *\n * @method tangentAt\n * @instance\n * @memberof VEllipse\n * @param {number} angle - The angle to get the tangent vector at.\n * @param {number=1.0} length - [optional, default=1] The length of the returned vector.\n */\n VEllipse.prototype.tangentAt = function (angle, length) {\n var normal = this.normalAt(angle, length);\n return normal.inv().perp();\n };\n /**\n * Get the perimeter of this ellipse.\n *\n * @method perimeter\n * @instance\n * @memberof VEllipse\n * @return {number}\n */\n VEllipse.prototype.perimeter = function () {\n // This method does not use an iterative approximation to determine the perimeter, but it uses\n // a wonderful closed approximation found by Srinivasa Ramanujan.\n // Matt Parker made a neat video about it:\n // https://www.youtube.com/watch?v=5nW3nJhBHL0\n var a = this.radiusH();\n var b = this.radiusV();\n return Math.PI * (3 * (a + b) - Math.sqrt((3 * a + b) * (a + 3 * b)));\n };\n /**\n * Get the two foci of this ellipse.\n *\n * @method getFoci\n * @instance\n * @memberof VEllipse\n * @return {Array<Vertex>} An array with two elements, the two focal points of the ellipse (foci).\n */\n VEllipse.prototype.getFoci = function () {\n // https://www.mathopenref.com/ellipsefoci.html\n var rh = this.radiusH();\n var rv = this.radiusV();\n var sdiff = rh * rh - rv * rv;\n // f is the distance of each focs to the center.\n var f = Math.sqrt(Math.abs(sdiff));\n // Foci on x- or y-axis?\n if (sdiff < 0) {\n return [\n this.center.clone().addY(f).rotate(this.rotation, this.center),\n this.center.clone().addY(-f).rotate(this.rotation, this.center)\n ];\n }\n else {\n return [\n this.center.clone().addX(f).rotate(this.rotation, this.center),\n this.center.clone().addX(-f).rotate(this.rotation, this.center)\n ];\n }\n };\n /**\n * Get equally distributed points on the outline of this ellipse.\n *\n * @method getEquidistantVertices\n * @instance\n * @param {number} pointCount - The number of points.\n * @returns {Array<Vertex>}\n */\n VEllipse.prototype.getEquidistantVertices = function (pointCount) {\n var angles = VEllipse.utils.equidistantVertAngles(this.radiusH(), this.radiusV(), pointCount);\n var result = [];\n for (var i = 0; i < angles.length; i++) {\n result.push(this.vertAt(angles[i]));\n }\n return result;\n };\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get the line intersections as vectors with this ellipse.\n *\n * @method lineIntersections\n * @instance\n * @param {VertTuple<Vector> ray - The line/ray to intersect this ellipse with.\n * @param {boolean} inVectorBoundsOnly - (default=false) Set to true if only intersections within the vector bounds are of interest.\n * @returns\n */\n VEllipse.prototype.lineIntersections = function (ray, inVectorBoundsOnly) {\n // Question: what happens to extreme versions when ellipse is a line (width or height is zero)?\n // This would result in a Division_by_Zero exception!\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Step A: create clones for operations (keep originals unchanged)\n var ellipseCopy = this.clone(); // VEllipse\n var rayCopy = ray.clone(); // Vector\n // Step B: move both so ellipse's center is located at (0,0)\n var moveAmount = ellipseCopy.center.clone().inv();\n ellipseCopy.move(moveAmount);\n rayCopy.add(moveAmount);\n // Step C: rotate eclipse backwards it's rotation, so that rotation is zero (0.0).\n // Rotate together with ray!\n var rotationAmount = -ellipseCopy.rotation;\n ellipseCopy.rotate(rotationAmount); // Rotation around (0,0) = center of translated ellipse\n rayCopy.a.rotate(rotationAmount, ellipseCopy.center);\n rayCopy.b.rotate(rotationAmount, ellipseCopy.center);\n // Step D: find x/y factors to use for scaling to transform the ellipse to a circle.\n // Scale together with vector ray.\n var radiusH = ellipseCopy.radiusH();\n var radiusV = ellipseCopy.radiusV();\n var scalingFactors = radiusH > radiusV ? { x: radiusV / radiusH, y: 1.0 } : { x: 1.0, y: radiusH / radiusV };\n // Step E: scale ellipse AND ray by calculated factors.\n ellipseCopy.axis.scaleXY(scalingFactors);\n rayCopy.a.scaleXY(scalingFactors);\n rayCopy.b.scaleXY(scalingFactors);\n // Intermediate result: now the ellipse is transformed to a circle and we can calculate intersections :)\n // Step F: calculate circle+line intersecions\n var tmpCircle = new Circle_1.Circle(new Vertex_1.Vertex(), ellipseCopy.radiusH()); // radiusH() === radiusV()\n var intersections = tmpCircle.lineIntersections(rayCopy, inVectorBoundsOnly);\n // Step G: transform intersecions back to original configuration\n intersections.forEach(function (intersectionPoint) {\n // Reverse transformation from above.\n intersectionPoint.scaleXY({ x: 1 / scalingFactors.x, y: 1 / scalingFactors.y }, ellipseCopy.center);\n intersectionPoint.rotate(-rotationAmount, ellipseCopy.center);\n intersectionPoint.sub(moveAmount);\n });\n return intersections;\n };\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @param line\n * @param lineIntersectionTangents\n * @returns\n */\n VEllipse.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersections of all lines plus their tangents inside the circle bounds\n var interSectionPoints = this.lineIntersections(line, inVectorBoundsOnly);\n return interSectionPoints.map(function (vert) {\n // Calculate angle\n var lineFromCenter = new Line_1.Line(_this.center, vert);\n var angle = lineFromCenter.angle();\n // Calculate tangent at angle\n return _this.tangentAt(angle);\n });\n };\n //--- END --- Implement interface `Intersectable`\n /**\n * Convert this ellipse into cubic Bézier curves.\n *\n * @param {number=3} quarterSegmentCount - The number of segments per base elliptic quarter (default is 3, min is 1).\n * @param {number=0.666666} threshold - The Bézier threshold (default value 0.666666 approximates the ellipse with best results\n * but you might wish to use other values)\n * @return {Array<CubicBezierCurve>} An array of cubic Bézier curves representing this ellipse.\n */\n VEllipse.prototype.toCubicBezier = function (quarterSegmentCount, threshold) {\n // Math by Luc Maisonobe\n // http://www.spaceroots.org/documents/ellipse/node22.html\n // Note that ellipses with radiusH=0 or radiusV=0 cannot be represented as Bézier curves.\n // Return a single line here (as a Bézier curve)?\n // if (Math.abs(this.radiusV()) < 0.00001) {\n // const radiusH = this.radiusH();\n // return [\n // new CubicBezierCurve(\n // this.center.clone().addX(radiusH),\n // this.center.clone().addX(-radiusH),\n // this.center.clone(),\n // this.center.clone()\n // )\n // ]; // TODO: test horizontal line ellipse\n // }\n // if (Math.abs(this.radiusH()) < 0.00001) {\n // const radiusV = this.radiusV();\n // return [\n // new CubicBezierCurve(\n // this.center.clone().addY(radiusV),\n // this.center.clone().addY(-radiusV),\n // this.center.clone(),\n // this.center.clone()\n // )\n // ]; // TODO: test vertical line ellipse\n // }\n // At least 4, but 16 seems to be a good value.\n var segmentCount = Math.max(1, quarterSegmentCount || 3) * 4;\n threshold = typeof threshold === \"undefined\" ? 0.666666 : threshold;\n var radiusH = this.radiusH();\n var radiusV = this.radiusV();\n var curves = [];\n var angles = VEllipse.utils.equidistantVertAngles(radiusH, radiusV, segmentCount);\n var curAngle = angles[0] + this.rotation;\n var startPoint = this.vertAt(curAngle);\n for (var i = 0; i < angles.length; i++) {\n var nextAngle = angles[(i + 1) % angles.length] + this.rotation;\n var endPoint = this.vertAt(nextAngle);\n if (Math.abs(radiusV) < 0.0001 || Math.abs(radiusH) < 0.0001) {\n // Distorted ellipses can only be approximated by linear Bézier segments\n var diff = startPoint.difference(endPoint);\n var curve = new CubicBezierCurve_1.CubicBezierCurve(startPoint.clone(), endPoint.clone(), startPoint.clone().addXY(diff.x * 0.333, diff.y * 0.333), endPoint.clone().addXY(-diff.x * 0.333, -diff.y * 0.333));\n curves.push(curve);\n }\n else {\n var startTangent = this.tangentAt(curAngle + this.rotation);\n var endTangent = this.tangentAt(nextAngle + this.rotation);\n // Find intersection (ignore that the result might be null in some extreme cases)\n var intersection = startTangent.intersection(endTangent);\n // What if intersection is undefined?\n // --> This *can* not happen if segmentCount > 2 and height and width of the ellipse are not zero.\n var startDiff = startPoint.difference(intersection);\n var endDiff = endPoint.difference(intersection);\n var curve = new CubicBezierCurve_1.CubicBezierCurve(startPoint.clone(), endPoint.clone(), startPoint.clone().add(startDiff.scale(threshold)), endPoint.clone().add(endDiff.scale(threshold)));\n curves.push(curve);\n }\n startPoint = endPoint;\n curAngle = nextAngle;\n }\n return curves;\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n VEllipse.prototype.destroy = function () {\n this.center.destroy();\n this.axis.destroy();\n this.isDestroyed = true;\n };\n /**\n * A static collection of ellipse-related helper functions.\n * @static\n */\n VEllipse.utils = {\n /**\n * Calculate a particular point on the outline of the given ellipse (center plus two radii plus angle).\n *\n * @name polarToCartesian\n * @param {number} centerX - The x coordinate of the elliptic center.\n * @param {number} centerY - The y coordinate of the elliptic center.\n * @param {number} radiusH - The horizontal radius of the ellipse.\n * @param {number} radiusV - The vertical radius of the ellipse.\n * @param {number} angle - The angle (in radians) to get the desired outline point for.\n * @reutn {XYCoords} The outlont point in absolute x-y-coordinates.\n */\n polarToCartesian: function (centerX, centerY, radiusH, radiusV, angle) {\n // Tanks to Narasinham for the vertex-on-ellipse equations\n // https://math.stackexchange.com/questions/22064/calculating-a-point-that-lies-on-an-ellipse-given-an-angle\n var s = Math.sin(Math.PI / 2 - angle);\n var c = Math.cos(Math.PI / 2 - angle);\n return {\n x: centerX + (radiusH * radiusV * s) / Math.sqrt(Math.pow(radiusH * c, 2) + Math.pow(radiusV * s, 2)),\n y: centerY + (radiusH * radiusV * c) / Math.sqrt(Math.pow(radiusH * c, 2) + Math.pow(radiusV * s, 2))\n };\n },\n /**\n * Get the `theta` for a given `phi` (used to determine equidistant points on ellipse).\n *\n * @param radiusH\n * @param radiusV\n * @param phi\n * @returns {number} theta\n */\n phiToTheta: function (radiusH, radiusV, phi) {\n // See https://math.stackexchange.com/questions/172766/calculating-equidistant-points-around-an-ellipse-arc\n var tanPhi = Math.tan(phi);\n var tanPhi2 = tanPhi * tanPhi;\n var theta = -Math.PI / 2 + phi + Math.atan(((radiusH - radiusV) * tanPhi) / (radiusV + radiusH * tanPhi2));\n return theta;\n },\n /**\n * Get n equidistant points on the elliptic arc.\n *\n * @param pointCount\n * @returns\n */\n equidistantVertAngles: function (radiusH, radiusV, pointCount) {\n var angles = [];\n for (var i = 0; i < pointCount; i++) {\n var phi = Math.PI / 2.0 + ((Math.PI * 2) / pointCount) * i;\n var theta = VEllipse.utils.phiToTheta(radiusH, radiusV, phi);\n angles[i] = theta;\n }\n return angles;\n }\n }; // END utils\n return VEllipse;\n}());\nexports.VEllipse = VEllipse;\n//# sourceMappingURL=VEllipse.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2018-03-19\n * @modified 2018-04-28 Added the param 'wasDragged'.\n * @modified 2018-08-16 Added the param 'dragAmount'.\n * @modified 2018-08-27 Added the param 'element'.\n * @modified 2018-11-11 Changed the scope from a simple global var to a member of window/_context.\n * @modified 2018-11-19 Renamed the 'mousedown' function to 'down' and the 'mouseup' function to 'up'.\n * @modified 2018-11-28 Added the 'wheel' listener.\n * @modified 2018-12-09 Cleaned up some code.\n * @modified 2019-02-10 Cleaned up some more code.\n * @modified 2020-03-25 Ported this class from vanilla-JS to Typescript.\n * @modified 2020-04-08 Fixed the click event (internally fired a 'mouseup' event) (1.0.10)\n * @modified 2020-04-08 Added the optional 'name' property. (1.0.11)\n * @modified 2020-04-08 The new version always installs internal listenrs to track drag events even\n * if there is no external drag listener installed (1.1.0).\n * @modified 2020-10-04 Added extended JSDoc comments.\n * @modified 2020-11-25 Added the `isTouchEvent` param.\n * @modified 2021-01-10 The mouse handler is now also working with SVGElements.\n * @modified 2022-08-16 Fixed a bug in the mouse button detection.\n * @version 1.2.1\n *\n * @file MouseHandler\n * @public\n **/\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.MouseHandler = exports.XWheelEvent = exports.XMouseEvent = void 0;\nvar XMouseEvent = /** @class */ (function (_super) {\n __extends(XMouseEvent, _super);\n function XMouseEvent() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n return XMouseEvent;\n}(MouseEvent));\nexports.XMouseEvent = XMouseEvent;\nvar XWheelEvent = /** @class */ (function (_super) {\n __extends(XWheelEvent, _super);\n function XWheelEvent() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n return XWheelEvent;\n}(WheelEvent));\nexports.XWheelEvent = XWheelEvent;\n/**\n * @classdesc A simple mouse handler for demos.\n * Use to avoid load massive libraries like jQuery.\n *\n * @requires XYCoords\n */\nvar MouseHandler = /** @class */ (function () {\n /**\n * The constructor.\n *\n * Pass the DOM element you want to receive mouse events from.\n *\n * Usage\n * =====\n * @example\n * // Javascript\n * new MouseHandler( document.getElementById('mycanvas') )\n *\t .drag( function(e) {\n *\t\tconsole.log( 'Mouse dragged: ' + JSON.stringify(e) );\n *\t\tif( e.params.leftMouse ) ;\n *\t\telse if( e.params.rightMouse ) ;\n *\t } )\n *\t .move( function(e) {\n *\t\tconsole.log( 'Mouse moved: ' + JSON.stringify(e.params) );\n *\t } )\n * .up( function(e) {\n * console.log( 'Mouse up. Was dragged?', e.params.wasDragged );\n * } )\n * .down( function(e) {\n * console.log( 'Mouse down.' );\n * } )\n * .click( function(e) {\n * console.log( 'Click.' );\n * } )\n * .wheel( function(e) {\n * console.log( 'Wheel. delta='+e.deltaY );\n * } )\n *\n * @example\n * // Typescript\n * new MouseHandler( document.getElementById('mycanvas') )\n *\t .drag( (e:XMouseEvent) => {\n *\t\tconsole.log( 'Mouse dragged: ' + JSON.stringify(e) );\n *\t\tif( e.params.leftMouse ) ;\n *\t\telse if( e.params.rightMouse ) ;\n *\t } )\n *\t .move( (e:XMouseEvent) => {\n *\t\tconsole.log( 'Mouse moved: ' + JSON.stringify(e.params) );\n *\t } )\n * .up( (e:XMouseEvent) => {\n * console.log( 'Mouse up. Was dragged?', e.params.wasDragged );\n * } )\n * .down( (e:XMouseEvent) => {\n * console.log( 'Mouse down.' );\n * } )\n * .click( (e:XMouseEvent) => {\n * console.log( 'Click.' );\n * } )\n * .wheel( (e:XWheelEvent) => {\n * console.log( 'Wheel. delta='+e.deltaY );\n * } )\n *\n * @constructor\n * @instance\n * @memberof MouseHandler\n * @param {HTMLElement} element\n **/\n function MouseHandler(element, name) {\n this.mouseDownPos = undefined;\n this.mouseDragPos = undefined;\n // TODO: cc\n // private mousePos : { x:number, y:number }|undefined = undefined;\n this.mouseButton = -1;\n this.listeners = {};\n this.installed = {};\n this.handlers = {};\n // +----------------------------------------------------------------------\n // | Some private vars to store the current mouse/position/button state.\n // +-------------------------------------------------\n this.name = name;\n this.element = element;\n this.mouseDownPos = undefined;\n this.mouseDragPos = undefined;\n // this.mousePos = null;\n this.mouseButton = -1;\n this.listeners = {};\n this.installed = {};\n this.handlers = {};\n // +----------------------------------------------------------------------\n // | Define the internal event handlers.\n // |\n // | They will dispatch the modified event (relative mouse position,\n // | drag offset, ...) to the callbacks.\n // +-------------------------------------------------\n var _self = this;\n this.handlers[\"mousemove\"] = function (e) {\n if (_self.listeners.mousemove)\n _self.listeners.mousemove(_self.mkParams(e, \"mousemove\"));\n if (_self.mouseDragPos && _self.listeners.drag)\n _self.listeners.drag(_self.mkParams(e, \"drag\"));\n if (_self.mouseDownPos)\n _self.mouseDragPos = _self.relPos(e);\n };\n this.handlers[\"mouseup\"] = function (e) {\n if (_self.listeners.mouseup)\n _self.listeners.mouseup(_self.mkParams(e, \"mouseup\"));\n _self.mouseDragPos = undefined;\n _self.mouseDownPos = undefined;\n _self.mouseButton = -1;\n };\n this.handlers[\"mousedown\"] = function (e) {\n _self.mouseDragPos = _self.relPos(e);\n _self.mouseDownPos = _self.relPos(e);\n _self.mouseButton = e.button;\n if (_self.listeners.mousedown)\n _self.listeners.mousedown(_self.mkParams(e, \"mousedown\"));\n };\n this.handlers[\"click\"] = function (e) {\n if (_self.listeners.click)\n _self.listeners.click(_self.mkParams(e, \"click\"));\n };\n this.handlers[\"wheel\"] = function (e) {\n if (_self.listeners.wheel)\n _self.listeners.wheel(_self.mkParams(e, \"wheel\"));\n };\n this.element.addEventListener(\"mousemove\", this.handlers[\"mousemove\"]);\n this.element.addEventListener(\"mouseup\", this.handlers[\"mouseup\"]);\n this.element.addEventListener(\"mousedown\", this.handlers[\"mousedown\"]);\n this.element.addEventListener(\"click\", this.handlers[\"click\"]);\n this.element.addEventListener(\"wheel\", this.handlers[\"wheel\"]);\n }\n /**\n * Get relative position from the given MouseEvent.\n *\n * @name relPos\n * @memberof MouseHandler\n * @instance\n * @private\n * @param {MouseEvent} e - The mouse event to get the relative position for.\n * @return {XYCoords} The relative mouse coordinates.\n */\n MouseHandler.prototype.relPos = function (e) {\n return { x: e.offsetX, y: e.offsetY };\n };\n /**\n * Build the extended event params.\n *\n * @name mkParams\n * @memberof MouseHandler\n * @instance\n * @private\n * @param {MouseEvent} event - The mouse event to get the relative position for.\n * @param {string} eventName - The name of the firing event.\n * @return {XMouseEvent}\n */\n MouseHandler.prototype.mkParams = function (event, eventName) {\n var _a, _b;\n var rel = this.relPos(event);\n var xEvent = event;\n xEvent.params = {\n element: this.element,\n name: eventName,\n isTouchEvent: false,\n pos: rel,\n button: event.button, // this.mouseButton,\n leftButton: event.button === 0, // this.mouseButton === 0,\n middleButton: event.button === 1, // this.mouseButton === 1,\n rightButton: event.button === 2, // this.mouseButton === 2,\n mouseDownPos: (_a = this.mouseDownPos) !== null && _a !== void 0 ? _a : { x: NaN, y: NaN },\n draggedFrom: (_b = this.mouseDragPos) !== null && _b !== void 0 ? _b : { x: NaN, y: NaN },\n wasDragged: this.mouseDownPos != null && (this.mouseDownPos.x != rel.x || this.mouseDownPos.y != rel.y),\n dragAmount: this.mouseDragPos != null ? { x: rel.x - this.mouseDragPos.x, y: rel.y - this.mouseDragPos.y } : { x: 0, y: 0 }\n };\n return xEvent;\n };\n /**\n * Install a new listener.\n * Please note that this mouse handler can only handle one listener per event type.\n *\n * @name listenFor\n * @memberof MouseHandler\n * @instance\n * @private\n * @param {string} eventName - The name of the firing event to listen for.\n * @return {void}\n */\n MouseHandler.prototype.listenFor = function (eventName) {\n if (this.installed[eventName])\n return;\n // In the new version 1.1.0 has all internal listeners installed by default.\n this.installed[eventName] = true;\n };\n /**\n * Un-install a new listener.\n *\n * @name listenFor\n * @memberof MouseHandler\n * @instance\n * @private\n * @param {string} eventName - The name of the firing event to unlisten for.\n * @return {void}\n */\n MouseHandler.prototype.unlistenFor = function (eventName) {\n if (!this.installed[eventName])\n return;\n // In the new version 1.1.0 has all internal listeners installed by default.\n delete this.installed[eventName];\n };\n /**\n * Installer function to listen for a specific event: mouse-drag.\n * Pass your callbacks here.\n *\n * Note: this support chaining.\n *\n * @name drag\n * @memberof MouseHandler\n * @instance\n * @param {XMouseCallback} callback - The drag-callback to listen for.\n * @return {MouseHandler} this\n */\n MouseHandler.prototype.drag = function (callback) {\n if (this.listeners.drag)\n this.throwAlreadyInstalled(\"drag\");\n this.listeners.drag = callback;\n this.listenFor(\"mousedown\");\n this.listenFor(\"mousemove\");\n this.listenFor(\"mouseup\");\n return this;\n };\n /**\n * Installer function to listen for a specific event: mouse-move.\n * Pass your callbacks here.\n *\n * Note: this support chaining.\n *\n * @name move\n * @memberof MouseHandler\n * @instance\n * @param {XMouseCallback} callback - The move-callback to listen for.\n * @return {MouseHandler} this\n */\n MouseHandler.prototype.move = function (callback) {\n if (this.listeners.mousemove)\n this.throwAlreadyInstalled(\"mousemove\");\n this.listenFor(\"mousemove\");\n this.listeners.mousemove = callback;\n return this;\n };\n /**\n * Installer function to listen for a specific event: mouse-up.\n * Pass your callbacks here.\n *\n * Note: this support chaining.\n *\n * @name up\n * @memberof MouseHandler\n * @instance\n * @param {XMouseCallback} callback - The up-callback to listen for.\n * @return {MouseHandler} this\n */\n MouseHandler.prototype.up = function (callback) {\n if (this.listeners.mouseup)\n this.throwAlreadyInstalled(\"mouseup\");\n this.listenFor(\"mouseup\");\n this.listeners.mouseup = callback;\n return this;\n };\n /**\n * Installer function to listen for a specific event: mouse-down.\n * Pass your callbacks here.\n *\n * Note: this support chaining.\n *\n * @name down\n * @memberof MouseHandler\n * @instance\n * @param {XMouseCallback} callback - The down-callback to listen for.\n * @return {MouseHandler} this\n */\n MouseHandler.prototype.down = function (callback) {\n if (this.listeners.mousedown)\n this.throwAlreadyInstalled(\"mousedown\");\n this.listenFor(\"mousedown\");\n this.listeners.mousedown = callback;\n return this;\n };\n /**\n * Installer function to listen for a specific event: mouse-click.\n * Pass your callbacks here.\n *\n * Note: this support chaining.\n *\n * @name click\n * @memberof MouseHandler\n * @instance\n * @param {XMouseCallback} callback - The click-callback to listen for.\n * @return {MouseHandler} this\n */\n MouseHandler.prototype.click = function (callback) {\n if (this.listeners.click)\n this.throwAlreadyInstalled(\"click\");\n this.listenFor(\"click\");\n this.listeners.click = callback;\n return this;\n };\n /**\n * Installer function to listen for a specific event: mouse-wheel.\n * Pass your callbacks here.\n *\n * Note: this support chaining.\n *\n * @name wheel\n * @memberof MouseHandler\n * @instance\n * @param {XWheelCallback} callback - The wheel-callback to listen for.\n * @return {MouseHandler} this\n */\n MouseHandler.prototype.wheel = function (callback) {\n if (this.listeners.wheel)\n this.throwAlreadyInstalled(\"wheel\");\n this.listenFor(\"wheel\");\n this.listeners.wheel = callback;\n return this;\n };\n /**\n * An internal function to throw events.\n *\n * @name throwAlreadyInstalled\n * @memberof MouseHandler\n * @instance\n * @private\n * @param {string} name - The name of the event.\n * @return {void}\n */\n MouseHandler.prototype.throwAlreadyInstalled = function (name) {\n throw \"This MouseHandler already has a '\".concat(name, \"' callback. To keep the code simple there is only room for one.\");\n };\n /**\n * Call this when your work is done.\n *\n * The function will un-install all event listeners.\n *\n * @name destroy\n * @memberof MouseHandler\n * @instance\n * @private\n * @return {void}\n */\n MouseHandler.prototype.destroy = function () {\n this.unlistenFor(\"mousedown\");\n this.unlistenFor(\"mousemove\");\n this.unlistenFor(\"moseup\");\n this.unlistenFor(\"click\");\n this.unlistenFor(\"wheel\");\n this.element.removeEventListener(\"mousemove\", this.handlers[\"mousemove\"]);\n this.element.removeEventListener(\"mouseup\", this.handlers[\"mousedown\"]);\n this.element.removeEventListener(\"mousedown\", this.handlers[\"mousedown\"]);\n this.element.removeEventListener(\"click\", this.handlers[\"click\"]);\n this.element.removeEventListener(\"wheel\", this.handlers[\"wheel\"]);\n };\n return MouseHandler;\n}());\nexports.MouseHandler = MouseHandler;\n//# sourceMappingURL=MouseHandler.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2018-08-27\n * @modified 2018-11-28 Added the vertex-param to the constructor and extended the event. Vertex events now have a 'params' attribute object.\n * @modified 2019-03-20 Added JSDoc tags.\n * @modified 2020-02-22 Added 'return this' to the add* functions (for chanining).\n * @modified 2020-03-23 Ported to Typescript from JS.\n * @modified 2020-11-17 Added the `click` handler.\n * @modified 2026-04-04 Adding null-listeners will now throw an error.\n * @version 1.2.0\n *\n * @file VertexListeners\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.VertexListeners = void 0;\n/**\n * @classdesc An event listeners wrapper. This is just a set of three listener\n * queues (drag, dragStart, dragEnd) and their respective firing\n * functions.\n *\n */\nvar VertexListeners = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name VertexListeners\n * @param {Vertex} vertex - The vertex to use these listeners on (just a backward reference).\n **/\n function VertexListeners(vertex) {\n this.click = [];\n this.drag = [];\n this.dragStart = [];\n this.dragEnd = [];\n this.vertex = vertex;\n }\n /**\n * Add a click listener.\n *\n * @method addClickListener\n * @param {VertexListeners~dragListener} listener - The click listener to add (a callback).\n * @return {VertexListeners} this (for chaining)\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.addClickListener = function (listener) {\n VertexListeners._addListener(this.click, listener);\n return this;\n };\n /**\n * The click listener is a function with a single drag event param.\n * @callback VertexListeners~clickListener\n * @param {Event} e - The (extended) click event.\n */\n /**\n * Remove a drag listener.\n *\n * @method removeDragListener\n * @param {VertexListeners~dragListener} listener - The drag listener to remove (a callback).\n * @return {VertexListeners} this (for chaining)\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.removeClickListener = function (listener) {\n this.click = VertexListeners._removeListener(this.click, listener);\n return this;\n };\n /**\n * The click listener is a function with a single drag event param.\n * @callback VertexListeners~clickListener\n * @param {Event} e - The (extended) click event.\n */\n /**\n * Add a drag listener.\n *\n * @method addDragListener\n * @param {VertexListeners~dragListener} listener - The drag listener to add (a callback).\n * @return {VertexListeners} this (for chaining)\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.addDragListener = function (listener) {\n VertexListeners._addListener(this.drag, listener);\n return this;\n };\n /**\n * The drag listener is a function with a single drag event param.\n * @callback VertexListeners~dragListener\n * @param {Event} e - The (extended) drag event.\n */\n /**\n * Remove a drag listener.\n *\n * @method removeDragListener\n * @param {VertexListeners~dragListener} listener - The drag listener to remove (a callback).\n * @return {VertexListeners} this (for chaining)\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.removeDragListener = function (listener) {\n this.drag = VertexListeners._removeListener(this.drag, listener);\n return this;\n };\n /**\n * Add a dragStart listener.\n *\n * @method addDragListener\n * @param {VertexListeners~dragStartListener} listener - The drag-start listener to add (a callback).\n * @return {VertexListeners} this (for chaining)\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.addDragStartListener = function (listener) {\n VertexListeners._addListener(this.dragStart, listener);\n return this;\n };\n /**\n * The drag-start listener is a function with a single drag event param.\n * @callback VertexListeners~dragStartListener\n * @param {Event} e - The (extended) drag event.\n */\n /**\n * Remove a dragStart listener.\n *\n * @method addDragStartListener\n * @param {VertexListeners~dragListener} listener - The drag listener to remove (a callback).\n * @return {VertexListeners} this (for chaining)\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.removeDragStartListener = function (listener) {\n this.dragStart = VertexListeners._removeListener(this.dragStart, listener);\n return this;\n };\n /**\n * Add a dragEnd listener.\n *\n * @method addDragListener\n * @param {VertexListeners~dragEndListener} listener - The drag-end listener to add (a callback).\n * @return {VertexListeners} this (for chaining)\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.addDragEndListener = function (listener) {\n // this.dragEnd.push( listener );\n VertexListeners._addListener(this.dragEnd, listener);\n return this;\n };\n /**\n * The drag-end listener is a function with a single drag event param.\n * @callback VertexListeners~dragEndListener\n * @param {Event} e - The (extended) drag event.\n */\n /**\n * Remove a drag listener.\n *\n * @method removeDragEndListener\n * @param {VertexListeners~clickListener} listener - The drag listener to remove (a callback).\n * @return {VertexListeners} this (for chaining)\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.removeDragEndListener = function (listener) {\n // this.drag.push( listener );\n this.dragEnd = VertexListeners._removeListener(this.dragEnd, listener);\n return this;\n };\n /**\n * Fire a click event with the given event instance to all\n * installed click listeners.\n *\n * @method fireClickEvent\n * @param {VertEvent|XMouseEvent} e - The click event itself to be fired to all installed drag listeners.\n * @return {void}\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.fireClickEvent = function (e) {\n VertexListeners._fireEvent(this, this.click, e);\n };\n /**\n * Fire a drag event with the given event instance to all\n * installed drag listeners.\n *\n * @method fireDragEvent\n * @param {VertEvent|XMouseEvent} e - The drag event itself to be fired to all installed drag listeners.\n * @return {void}\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.fireDragEvent = function (e) {\n VertexListeners._fireEvent(this, this.drag, e);\n };\n /**\n * Fire a dragStart event with the given event instance to all\n * installed drag-start listeners.\n *\n * @method fireDragStartEvent\n * @param {VertEvent|XMouseEvent} e - The drag-start event itself to be fired to all installed dragStart listeners.\n * @return {void}\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.fireDragStartEvent = function (e) {\n VertexListeners._fireEvent(this, this.dragStart, e);\n };\n /**\n * Fire a dragEnd event with the given event instance to all\n * installed drag-end listeners.\n *\n * @method fireDragEndEvent\n * @param {VertEvent|XMouseEvent} e - The drag-end event itself to be fired to all installed dragEnd listeners.\n * @return {void}\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.fireDragEndEvent = function (e) {\n VertexListeners._fireEvent(this, this.dragEnd, e);\n };\n /**\n * Removes all listeners from this listeners object.\n */\n VertexListeners.prototype.removeAllListeners = function () {\n this.click = [];\n this.drag = [];\n this.dragStart = [];\n this.dragEnd = [];\n };\n /**\n * @private\n **/\n VertexListeners._fireEvent = function (_self, listeners, e) {\n var ve = e;\n if (typeof ve.params == \"undefined\")\n ve.params = { vertex: _self.vertex };\n else\n ve.params.vertex = _self.vertex;\n for (var i in listeners) {\n listeners[i](ve);\n }\n };\n /**\n * @private\n */\n VertexListeners._addListener = function (listeners, newListener) {\n if (!newListener) {\n throw new Error(\"Cannot add null listener. This would lead to unpredictable errors during event handling.\");\n }\n for (var i in listeners) {\n if (listeners[i] == newListener)\n return false;\n }\n listeners.push(newListener);\n return true;\n };\n /**\n * @private\n */\n VertexListeners._removeListener = function (listeners, oldListener) {\n for (var i = 0; i < listeners.length; i++) {\n if (listeners[i] == oldListener)\n return listeners.splice(i, 1);\n }\n return listeners;\n };\n return VertexListeners;\n}());\nexports.VertexListeners = VertexListeners;\n//# sourceMappingURL=VertexListeners.js.map","\"use strict\";\n/**\n * @classdesc A static UIDGenerator.\n *\n * @author Ikaros Kappler\n * @date 2021-01-20\n * @version 1.0.0\n */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.UIDGenerator = void 0;\nvar UIDGenerator = /** @class */ (function () {\n function UIDGenerator() {\n }\n UIDGenerator.next = function () {\n return \"\".concat(UIDGenerator.current++);\n };\n UIDGenerator.current = 0;\n return UIDGenerator;\n}());\nexports.UIDGenerator = UIDGenerator;\n//# sourceMappingURL=UIDGenerator.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2016-03-12\n * @modified 2018-12-05 Refactored the code from the morley-triangle script.\n * @modified 2019-03-20 Added JSDoc tags.\n * @modified 2019-04-28 Fixed a bug in the Line.sub( Vertex ) function (was not working).\n * @modified 2019-09-02 Added the Line.add( Vertex ) function.\n * @modified 2019-09-02 Added the Line.denominator( Line ) function.\n * @modified 2019-09-02 Added the Line.colinear( Line ) function.\n * @modified 2019-09-02 Fixed an error in the Line.intersection( Line ) function (class Point was renamed to Vertex).\n * @modified 2019-12-15 Added the Line.moveTo(Vertex) function.\n * @modified 2020-03-16 The Line.angle(Line) parameter is now optional. The baseline (x-axis) will be used if not defined.\n * @modified 2020-03-23 Ported to Typescript from JS.\n * @modified 2020-12-04 The `intersection` function returns undefined if both lines are parallel.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-10-09 Changed the actual return value of the `intersection` function to null (was undefined before).\n * @modified 2022-10-17 Adding these methods from the `PathSegment` interface: getStartPoint, getEndPoint, revert.\n * @modified 2023-09-25 Changed param type of `intersection()` from Line to VertTuple.\n * @modified 2025-04-15 Class `Line` now implements interface `Intersectable`.\n * @modified 2025-04-16 Class `Line` now implements interface `IBounded`.\n * @version 2.4.0\n *\n * @file Line\n * @public\n **/\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Line = void 0;\nvar Bounds_1 = require(\"./Bounds\");\nvar Vector_1 = require(\"./Vector\");\nvar VertTuple_1 = require(\"./VertTuple\");\nvar Vertex_1 = require(\"./Vertex\");\n/**\n * @classdesc A line consists of two vertices a and b.<br>\n * <br>\n * This is some refactored code from my 'Morley Triangle' test<br>\n * https://github.com/IkarosKappler/morleys-trisector-theorem\n *\n * @requires Vertex\n */\nvar Line = /** @class */ (function (_super) {\n __extends(Line, _super);\n /**\n * Creates an instance of Line.\n *\n * @constructor\n * @name Line\n * @param {Vertex} a The line's first point.\n * @param {Vertex} b The line's second point.\n **/\n function Line(a, b) {\n var _this = _super.call(this, a, b, function (a, b) { return new Line(a, b); }) || this;\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n _this.className = \"Line\";\n return _this;\n }\n /**\n * Get the intersection if this line and the specified line.\n *\n * @method intersection\n * @param {Line} line The second line.\n * @return {Vertex|undefined} The intersection (may lie outside the end-points) or `undefined` if both lines are parallel.\n * @instance\n * @memberof Line\n **/\n // !!! DO NOT MOVE TO VertTuple\n Line.prototype.intersection = function (line) {\n var denominator = this.denominator(line);\n if (denominator == 0) {\n return null;\n }\n var a = this.a.y - line.a.y;\n var b = this.a.x - line.a.x;\n var numerator1 = (line.b.x - line.a.x) * a - (line.b.y - line.a.y) * b;\n var numerator2 = (this.b.x - this.a.x) * a - (this.b.y - this.a.y) * b;\n a = numerator1 / denominator; // NaN if parallel lines\n b = numerator2 / denominator;\n // Catch NaN?\n var x = this.a.x + a * (this.b.x - this.a.x);\n var y = this.a.y + a * (this.b.y - this.a.y);\n if (isNaN(a) || isNaN(x) || isNaN(y)) {\n return null;\n }\n // if we cast these lines infinitely in both directions, they intersect here:\n return new Vertex_1.Vertex(x, y);\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Get the bounding box (bounds) of this Line.\n *\n * @method getBounds\n * @instance\n * @memberof Line\n * @return {Bounds} The rectangular bounds of this Line.\n **/\n Line.prototype.getBounds = function () {\n return Bounds_1.Bounds.computeFromVertices([this.a, this.b]);\n };\n //--- END --- Implement interface `IBounded`\n //--- Implement PathSegment ---\n /**\n * Get the start point of this path segment.\n *\n * @method getStartPoint\n * @memberof PathSegment\n * @return {Vertex} The start point of this path segment.\n */\n Line.prototype.getStartPoint = function () {\n return this.a;\n };\n /**\n * Get the end point of this path segment.\n *\n * @method getEndPoint\n * @memberof PathSegment\n * @return {Vertex} The end point of this path segment.\n */\n Line.prototype.getEndPoint = function () {\n return this.b;\n };\n /**\n * Get the tangent's end point at the start point of this segment.\n *\n * @method getStartTangent\n * @memberof PathSegment\n * @return {Vertex} The end point of the starting point's tangent.\n */\n Line.prototype.getStartTangent = function () {\n return this.b;\n };\n /**\n * Get the tangent's end point at the end point of this segment.\n *\n * @method getEndTangent\n * @memberof PathSegment\n * @return {Vertex} The end point of the ending point's tangent.\n */\n Line.prototype.getEndTangent = function () {\n return this.a;\n };\n /**\n * Inverse this path segment (in-place) and return this same instance (useful for chaining).\n *\n * @method reverse\n * @memberof PathSegment\n * @return {PathSegment} This path segment instance (for chaining).\n */\n Line.prototype.reverse = function () {\n var tmp = this.a;\n this.a = this.b;\n this.b = tmp;\n return this;\n };\n //--- END Implement PathSegment ---\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get all line intersections with this polygon.\n *\n * This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.\n *\n * See demo `47-closest-vector-projection-on-polygon` for how it works.\n *\n * @param {VertTuple} line - The line to find intersections with.\n * @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).\n * @returns {Array<Vertex>} - An array of all intersections within the polygon bounds.\n */\n Line.prototype.lineIntersections = function (line, inVectorBoundsOnly) {\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersections of all lines inside the edge bounds\n var intersection = this.intersection(line);\n if (!intersection) {\n return []; // Both lines parallel\n }\n if (this.hasPoint(intersection, true) && (!inVectorBoundsOnly || line.hasPoint(intersection, inVectorBoundsOnly))) {\n return [intersection];\n }\n else {\n return [];\n }\n };\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @param line\n * @param inVectorBoundsOnly\n * @returns\n */\n Line.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersection tangents of all lines inside the edge bounds\n var intersections = this.lineIntersections(line, inVectorBoundsOnly);\n if (intersections.length === 0) {\n return [];\n }\n var intrsctn = intersections[0];\n return [new Vector_1.Vector(this.a.clone(), this.b.clone()).moveTo(intrsctn)];\n };\n return Line;\n}(VertTuple_1.VertTuple));\nexports.Line = Line;\n//# sourceMappingURL=Line.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2013-08-15\n * @modified 2018-08-16 Added a closure. Removed the wrapper class 'IKRS'. Replaced class THREE.Vector2 by Vertex class.\n * @modified 2018-11-19 Added the fromArray(Array) function.\n * @modified 2018-11-28 Added the locateCurveByPoint(Vertex) function.\n * @modified 2018-12-04 Added the toSVGPathData() function.\n * @modified 2019-03-20 Added JSDoc tags.\n * @modified 2019-03-23 Changed the signatures of getPoint, getPointAt and getTangent (!version 2.0).\n * @modified 2019-12-02 Fixed the updateArcLength function. It used the wrong pointAt function (was renamed before).\n * @modified 2020-02-06 Added the getSubCurveAt(number,number) function.\n * @modified 2020-02-06 Fixed a serious bug in the arc lenght calculation (length was never reset, urgh).\n * @modified 2020-02-07 Added the isInstance(any) function.\n * @modified 2020-02-10 Added the reverse() function.\n * @modified 2020-02-10 Fixed the translate(...) function (returning 'this' was missing).\n * @modified 2020-03-24 Ported this class from vanilla JS to Typescript.\n * @modified 2020-06-03 Added the getBounds() function.\n * @modified 2020-07-14 Changed the moveCurvePoint(...,Vertex) to moveCurvePoint(...,XYCoords), which is more generic.\n * @modified 2020-07-24 Added the getClosestT function and the helper function locateIntervalByDistance(...).\n * @modified 2021-01-20 Added UID.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-02-02 Cleared the `toSVGPathData` function (deprecated). Use `drawutilssvg` instead.\n * @modified 2022-10-17 The `CubicBezierCurve` class now implements the new `PathSegment` interface.\n * @modified 2023-09-30 Added the function `CubicbezierCurve.getSubCurve(number,number)` – similar to `getSubCurveAt(...)` but with absolute position parameters.\n * @modified 2023-10-07 Added the `trimEnd`, `trimEndAt`, `trimStart`, `trimStartAt` methods.\n * @modified 2025-04-09 Added the `CubicBezierCurve.move` method to match the convention – which just calls `translate`.\n * @modified 2025-04-09 Modified the `CubicBezierCurve.translate` method: chaning parameter `Vertex` to more generalized `XYCoords`.\n * @modified 2025-04-13 Changed visibility of `CubicBezierCurve.utils` from 'private' to 'public'.\n * @modified 2025-04-13 Added helper function `CubicBezierCurve.utils.bezierCoeffs`.\n * @modified 2025-04-13 Added helper functopn `CubicBezierCurve.utils.sgn(number)` for division safe sign calculation.\n * @modified 2025-03-13 Class `CubicBezierCurve` is now implementing interface `Intersectable`.\n * @modified 2025-04-18 Added evaluation method for cubic Bézier curves `CubicBezierCurve.utils.evaluateT`.\n * @modified 2025-04-18 Refactored method `CubicBezierCurve.getPointAt` to use `evaluateT`.\n * @modified 2025-04-18 Fixed the `CubicBezierCurve.getBounds` method: now returning the real bounding box. Before it was an approximated one.\n * @modified 2025-ß4-18 Added helper methods for bounding box calculation `CubucBezierCurve.util.cubicPolyMinMax` and `cubicPoly`.\n * @version 2.9.0\n *\n * @file CubicBezierCurve\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.CubicBezierCurve = void 0;\nvar Bounds_1 = require(\"./Bounds\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar Vertex_1 = require(\"./Vertex\");\nvar Vector_1 = require(\"./Vector\");\n/**\n * @classdesc A refactored cubic bezier curve class.\n *\n * @requires Bounds\n * @requires Vertex\n * @requires Vector\n * @requires XYCoords\n * @requires UID\n * @requires UIDGenerator\n */\nvar CubicBezierCurve = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name CubicBezierCurve\n * @param {Vertex} startPoint - The Bézier curve's start point.\n * @param {Vertex} endPoint - The Bézier curve's end point.\n * @param {Vertex} startControlPoint - The Bézier curve's start control point.\n * @param {Vertex} endControlPoint - The Bézier curve's end control point.\n **/\n function CubicBezierCurve(startPoint, endPoint, startControlPoint, endControlPoint) {\n /** @constant {number} */\n this.START_POINT = CubicBezierCurve.START_POINT;\n /** @constant {number} */\n this.START_CONTROL_POINT = CubicBezierCurve.START_CONTROL_POINT;\n /** @constant {number} */\n this.END_CONTROL_POINT = CubicBezierCurve.END_CONTROL_POINT;\n /** @constant {number} */\n this.END_POINT = CubicBezierCurve.END_POINT;\n this.uid = UIDGenerator_1.UIDGenerator.next();\n this.startPoint = startPoint;\n this.startControlPoint = startControlPoint;\n this.endPoint = endPoint;\n this.endControlPoint = endControlPoint;\n this.curveIntervals = 30;\n // An array of vertices\n this.segmentCache = [];\n // An array of floats\n this.segmentLengths = [];\n // float\n // this.arcLength = null;\n this.updateArcLengths();\n }\n /**\n * Move the given curve point (the start point, end point or one of the two\n * control points).\n *\n * @method moveCurvePoint\n * @param {number} pointID - The numeric identicator of the point to move. Use one of the four eBezierPoint constants.\n * @param {XYCoords} moveAmount - The amount to move the specified point by.\n * @param {boolean} moveControlPoint - Move the control points along with their path point (if specified point is a path point).\n * @param {boolean} updateArcLengths - Specifiy if the internal arc segment buffer should be updated.\n * @instance\n * @memberof CubicBezierCurve\n * @return {void}\n **/\n CubicBezierCurve.prototype.moveCurvePoint = function (pointID, moveAmount, moveControlPoint, updateArcLengths) {\n if (pointID == this.START_POINT) {\n this.getStartPoint().add(moveAmount);\n if (moveControlPoint)\n this.getStartControlPoint().add(moveAmount);\n }\n else if (pointID == this.START_CONTROL_POINT) {\n this.getStartControlPoint().add(moveAmount);\n }\n else if (pointID == this.END_CONTROL_POINT) {\n this.getEndControlPoint().add(moveAmount);\n }\n else if (pointID == this.END_POINT) {\n this.getEndPoint().add(moveAmount);\n if (moveControlPoint)\n this.getEndControlPoint().add(moveAmount);\n }\n else {\n console.log(\"[CubicBezierCurve.moveCurvePoint] pointID '\".concat(pointID, \"' invalid.\"));\n }\n if (updateArcLengths)\n this.updateArcLengths();\n };\n /**\n * Translate the whole curve by the given {x,y} amount: moves all four points.\n *\n * @method translate\n * @param {XYCoords} amount - The amount to translate this curve by.\n * @instance\n * @memberof CubicBezierCurve\n * @return {CubicBezierCurve} this (for chaining).\n **/\n CubicBezierCurve.prototype.translate = function (amount) {\n this.startPoint.add(amount);\n this.startControlPoint.add(amount);\n this.endControlPoint.add(amount);\n this.endPoint.add(amount);\n return this;\n };\n /**\n * Translate the whole curve by the given {x,y} amount: moves all four points.\n *\n * @method translate\n * @param {XYCoords} amount - The amount to translate this curve by.\n * @instance\n * @memberof CubicBezierCurve\n * @return {CubicBezierCurve} this (for chaining).\n **/\n CubicBezierCurve.prototype.move = function (amount) {\n return this.translate(amount);\n };\n /**\n * Reverse this curve, means swapping start- and end-point and swapping\n * start-control- and end-control-point.\n *\n * @method reverse\n * @instance\n * @memberof CubicBezierCurve\n * @return {CubicBezierCurve} this (for chaining).\n **/\n CubicBezierCurve.prototype.reverse = function () {\n var tmp = this.startPoint;\n this.startPoint = this.endPoint;\n this.endPoint = tmp;\n tmp = this.startControlPoint;\n this.startControlPoint = this.endControlPoint;\n this.endControlPoint = tmp;\n return this;\n };\n /**\n * Get the total curve length.<br>\n * <br>\n * As not all Bézier curved have a closed formula to calculate their lengths, this\n * implementation uses a segment buffer (with a length of 30 segments). So the\n * returned length is taken from the arc segment buffer.<br>\n * <br>\n * Note that if the curve points were changed and the segment buffer was not\n * updated this function might return wrong (old) values.\n *\n * @method getLength\n * @instance\n * @memberof CubicBezierCurve\n * @return {number} >= 0\n **/\n CubicBezierCurve.prototype.getLength = function () {\n return this.arcLength;\n };\n /**\n * Uptate the internal arc segment buffer and their lengths.<br>\n * <br>\n * All class functions update the buffer automatically; if any\n * curve point is changed by other reasons you should call this\n * function to keep actual values in the buffer.\n *\n * @method updateArcLengths\n * @instance\n * @memberof CubicBezierCurve\n * @return {void}\n **/\n CubicBezierCurve.prototype.updateArcLengths = function () {\n var pointA = this.startPoint.clone();\n var pointB = new Vertex_1.Vertex(0, 0);\n var curveStep = 1.0 / this.curveIntervals;\n // Clear segment cache\n this.segmentCache = [];\n // Push start point into buffer\n this.segmentCache.push(this.startPoint);\n this.segmentLengths = [];\n var newLength = 0.0;\n var t = 0.0;\n var tmpLength;\n while (t <= 1.0) {\n pointB = this.getPointAt(t);\n // Store point into cache\n this.segmentCache.push(pointB);\n // Calculate segment length\n tmpLength = pointA.distance(pointB);\n this.segmentLengths.push(tmpLength);\n newLength += tmpLength;\n pointA = pointB;\n t += curveStep;\n }\n this.arcLength = newLength;\n };\n /**\n * Get a 't' (relative position on curve) with the closest distance to point 'p'.\n *\n * The returned number is 0.0 <= t <= 1.0. Use the getPointAt(t) function to retrieve the actual curve point.\n *\n * This function uses a recursive approach by cutting the curve into several linear segments.\n *\n * @method getClosestT\n * @instance\n * @memberof CubicBezierCurve\n * @param {Vertex} p - The point to find the closest position ('t' on the curve).\n * @return {number}\n **/\n CubicBezierCurve.prototype.getClosestT = function (p) {\n // We would like to have an error that's not larger than 1.0.\n var desiredEpsilon = 1.0;\n var result = { t: 0, tPrev: 0.0, tNext: 1.0 };\n var iteration = 0;\n do {\n result = this.locateIntervalByDistance(p, result.tPrev, result.tNext, this.curveIntervals);\n iteration++;\n // Be sure: stop after 4 iterations\n } while (iteration < 4 && this.getPointAt(result.tPrev).distance(this.getPointAt(result.tNext)) > desiredEpsilon);\n return result.t;\n };\n /**\n * This helper function locates the 't' on a fixed step interval with the minimal distance\n * between the curve (at 't') and the given point.\n *\n * Furthermore you must specify a sub curve (start 't' and end 't') you want to search on.\n * Using tStart=0.0 and tEnd=1.0 will search on the full curve.\n *\n * @param {Vertex} p - The point to find the closest curve point for.\n * @param {number} tStart - The start position (start 't' of the sub curve). Should be >= 0.0.\n * @param {number} tEnd - The end position (end 't' of the sub curve). Should be <= 1.0.\n * @param {number} stepCount - The number of steps to check within the interval.\n *\n * @return {object} - An object with t, tPrev and tNext (numbers).\n **/\n CubicBezierCurve.prototype.locateIntervalByDistance = function (p, tStart, tEnd, stepCount) {\n var minIndex = -1;\n var minDist = 0;\n var t = 0.0;\n var tDiff = tEnd - tStart;\n for (var i = 0; i <= stepCount; i++) {\n t = tStart + tDiff * (i / stepCount);\n var vert = this.getPointAt(t);\n var dist = vert.distance(p);\n if (minIndex == -1 || dist < minDist) {\n minIndex = i;\n minDist = dist;\n }\n }\n return {\n t: tStart + tDiff * (minIndex / stepCount),\n tPrev: tStart + tDiff * (Math.max(0, minIndex - 1) / stepCount),\n tNext: tStart + tDiff * (Math.min(stepCount, minIndex + 1) / stepCount)\n };\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Get the bounds of this bezier curve.\n *\n * The bounds are approximated by the underlying segment buffer; the more segment there are,\n * the more accurate will be the returned bounds.\n *\n * @method getClosestT\n * @instance\n * @memberof CubicBezierCurve\n * @return {Bounds} The bounds of this ellipse.\n **/\n CubicBezierCurve.prototype.getBounds = function () {\n // Thanks to Richard \"RM\" for the Bézier bounds calculatin\n // https://jsfiddle.net/SalixAlba/QQnvm/4/\n var xMinMax = CubicBezierCurve.utils.cubicPolyMinMax(this.startPoint.x, this.startControlPoint.x, this.endControlPoint.x, this.endPoint.x);\n var xl = xMinMax.min;\n var xh = xMinMax.max;\n var yMinMax = CubicBezierCurve.utils.cubicPolyMinMax(this.startPoint.y, this.startControlPoint.y, this.endControlPoint.y, this.endPoint.y);\n var yl = yMinMax.min;\n var yh = yMinMax.max;\n return Bounds_1.Bounds.computeFromVertices([\n { x: xl, y: yl },\n { x: xl, y: yh },\n { x: xh, y: yh },\n { x: xh, y: yl }\n ]);\n };\n //--- END --- Implement interface `IBounded`\n /**\n * Get the start point of the curve.<br>\n * <br>\n * This function just returns this.startPoint.\n *\n * @method getStartPoint\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex} this.startPoint\n **/\n CubicBezierCurve.prototype.getStartPoint = function () {\n return this.startPoint;\n };\n /**\n * Get the end point of the curve.<br>\n * <br>\n * This function just returns this.endPoint.\n *\n * @method getEndPoint\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex} this.endPoint\n **/\n CubicBezierCurve.prototype.getEndPoint = function () {\n return this.endPoint;\n };\n /**\n * Get the start control point of the curve.<br>\n * <br>\n * This function just returns this.startControlPoint.\n *\n * @method getStartControlPoint\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex} this.startControlPoint\n **/\n CubicBezierCurve.prototype.getStartControlPoint = function () {\n return this.startControlPoint;\n };\n /**\n * Get the end control point of the curve.<br>\n * <br>\n * This function just returns this.endControlPoint.\n *\n * @method getEndControlPoint\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex} this.endControlPoint\n **/\n CubicBezierCurve.prototype.getEndControlPoint = function () {\n return this.endControlPoint;\n };\n /**\n * Get one of the four curve points specified by the passt point ID.\n *\n * @method getEndControlPoint\n * @param {number} id - One of START_POINT, START_CONTROL_POINT, END_CONTROL_POINT or END_POINT.\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex}\n **/\n CubicBezierCurve.prototype.getPointByID = function (id) {\n if (id == this.START_POINT)\n return this.startPoint;\n if (id == this.END_POINT)\n return this.endPoint;\n if (id == this.START_CONTROL_POINT)\n return this.startControlPoint;\n if (id == this.END_CONTROL_POINT)\n return this.endControlPoint;\n throw new Error(\"Invalid point ID '\".concat(id, \"'.\"));\n };\n /**\n * Get the curve point at a given position t, where t is in [0,1].<br>\n * <br>\n * @see Line.pointAt\n *\n * @method getPointAt\n * @param {number} t - The position on the curve in [0,1] (0 means at\n * start point, 1 means at end point, other values address points in bertween).\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex}\n **/\n CubicBezierCurve.prototype.getPointAt = function (t) {\n // Perform some powerful math magic\n // TODO: cleanup\n // const x: number =\n // this.startPoint.x * Math.pow(1.0 - t, 3) +\n // this.startControlPoint.x * 3 * t * Math.pow(1.0 - t, 2) +\n // this.endControlPoint.x * 3 * Math.pow(t, 2) * (1.0 - t) +\n // this.endPoint.x * Math.pow(t, 3);\n // const y: number =\n // this.startPoint.y * Math.pow(1.0 - t, 3) +\n // this.startControlPoint.y * 3 * t * Math.pow(1.0 - t, 2) +\n // this.endControlPoint.y * 3 * Math.pow(t, 2) * (1.0 - t) +\n // this.endPoint.y * Math.pow(t, 3);\n var x = CubicBezierCurve.utils.evaluateT(this.startPoint.x, this.startControlPoint.x, this.endControlPoint.x, this.endPoint.x, t);\n var y = CubicBezierCurve.utils.evaluateT(this.startPoint.y, this.startControlPoint.y, this.endControlPoint.y, this.endPoint.y, t);\n return new Vertex_1.Vertex(x, y);\n };\n /**\n * Get the curve point at a given position u, where u is in [0,arcLength].<br>\n * <br>\n * @see CubicBezierCurve.getPointAt\n *\n * @method getPoint\n * @param {number} u - The position on the curve in [0,arcLength] (0 means at\n * start point, arcLength means at end point, other values address points in bertween).\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex}\n **/\n CubicBezierCurve.prototype.getPoint = function (u) {\n return this.getPointAt(u / this.arcLength);\n };\n /**\n * Get the curve tangent vector at a given absolute curve position t in [0,1].<br>\n * <br>\n * Note that the returned tangent vector (end point) is not normalized and relative to (0,0).\n *\n * @method getTangent\n * @param {number} t - The position on the curve in [0,1].\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex}\n **/\n CubicBezierCurve.prototype.getTangentAt = function (t) {\n var a = this.getStartPoint();\n var b = this.getStartControlPoint();\n var c = this.getEndControlPoint();\n var d = this.getEndPoint();\n // This is the shortened one\n var t2 = t * t;\n // (1 - t)^2 = (1-t)*(1-t) = 1 - t - t + t^2 = 1 - 2*t + t^2\n var nt2 = 1 - 2 * t + t2;\n var tX = -3 * a.x * nt2 + b.x * (3 * nt2 - 6 * (t - t2)) + c.x * (6 * (t - t2) - 3 * t2) + 3 * d.x * t2;\n var tY = -3 * a.y * nt2 + b.y * (3 * nt2 - 6 * (t - t2)) + c.y * (6 * (t - t2) - 3 * t2) + 3 * d.y * t2;\n // Note: my implementation does NOT normalize tangent vectors!\n return new Vertex_1.Vertex(tX, tY);\n };\n /**\n * Trim off a start section of this curve. The position parameter `uValue` is the absolute position on the\n * curve in `[0...arcLength]`.\n * The remaining curve will be the one in the bounds `[uValue,1]` (so `[0.0,uValue]` is cut off).\n *\n * Note this function just converts the absolute parameter to a relative one and call `trimStartAt`.\n *\n * @method trimStart\n * @instance\n * @memberof CubicBezierCurve\n * @param {number} uValue - The absolute position parameter where to cut off the head curve.\n * @returns {CubicBezierCurve} `this` for chanining.\n */\n CubicBezierCurve.prototype.trimStart = function (uValue) {\n return this.trimStartAt(this.convertU2T(uValue));\n };\n /**\n * Trim off a start section of this curve. The position parameter `t` is the relative position in [0..1].\n * The remaining curve will be the one in the bounds `[uValue,1]` (so `[0.0,uValue]` is cut off).\n *\n * @method trimStartAt\n * @instance\n * @memberof CubicBezierCurve\n * @param {number} t - The relative position parameter where to cut off the head curve.\n * @returns {CubicBezierCurve} `this` for chanining.\n */\n CubicBezierCurve.prototype.trimStartAt = function (t) {\n var subCurbePoints = CubicBezierCurve.utils.getSubCurvePointsAt(this, t, 1.0);\n this.startPoint.set(subCurbePoints[0]);\n this.startControlPoint.set(subCurbePoints[2]);\n this.endPoint.set(subCurbePoints[1]);\n this.endControlPoint.set(subCurbePoints[3]);\n this.updateArcLengths();\n return this;\n };\n /**\n * Trim off the end of this curve. The position parameter `uValue` is the absolute position on the\n * curve in `[0...arcLength]`.\n * The remaining curve will be the one in the bounds `[0,uValue]` (so `[1.0-uValue,1.0]` is cut off).\n *\n * Note this function just converts the absolute parameter to a relative one and call `trimEndAt`.\n *\n * @method trimEnd\n * @instance\n * @memberof CubicBezierCurve\n * @param {number} uValue - The absolute position parameter where to cut off the tail curve.\n * @returns {CubicBezierCurve} `this` for chanining.\n */\n CubicBezierCurve.prototype.trimEnd = function (uValue) {\n return this.trimEndAt(this.convertU2T(uValue));\n };\n /**\n * Trim off the end of this curve. The position parameter `t` is the relative position in [0..1].\n * The remaining curve will be the one in the bounds `[0,t]` (so `[1.0-t,1.0]` is cut off).\n *\n * @method trimEndAt\n * @instance\n * @memberof CubicBezierCurve\n * @param {number} t - The relative position parameter where to cut off the tail curve.\n * @returns {CubicBezierCurve} `this` for chanining.\n */\n CubicBezierCurve.prototype.trimEndAt = function (t) {\n var subCurbePoints = CubicBezierCurve.utils.getSubCurvePointsAt(this, 0.0, t);\n this.startPoint.set(subCurbePoints[0]);\n this.startControlPoint.set(subCurbePoints[2]);\n this.endPoint.set(subCurbePoints[1]);\n this.endControlPoint.set(subCurbePoints[3]);\n this.updateArcLengths();\n return this;\n };\n /**\n * Get a sub curve at the given start end end positions (values on the curve's length, between 0 and curve.arcLength).\n *\n * tStart >= tEnd is allowed, you will get a reversed sub curve then.\n *\n * @method getSubCurve\n * @param {number} tStart – The start position of the desired sub curve (must be in [0..arcLength]).\n * @param {number} tEnd – The end position if the desired cub curve (must be in [0..arcLength]).\n * @instance\n * @memberof CubicBezierCurve\n * @return {CubicBezierCurve} The sub curve as a new curve.\n **/\n CubicBezierCurve.prototype.getSubCurve = function (uStart, uEnd) {\n return this.getSubCurveAt(this.convertU2T(uStart), this.convertU2T(uEnd));\n };\n /**\n * Get a sub curve at the given start end end offsets (values between 0.0 and 1.0).\n *\n * tStart >= tEnd is allowed, you will get a reversed sub curve then.\n *\n * @method getSubCurveAt\n * @param {number} tStart – The start offset of the desired sub curve (must be in [0..1]).\n * @param {number} tEnd – The end offset if the desired cub curve (must be in [0..1]).\n * @instance\n * @memberof CubicBezierCurve\n * @return {CubicBezierCurve} The sub curve as a new curve.\n **/\n CubicBezierCurve.prototype.getSubCurveAt = function (tStart, tEnd) {\n // This 'splits' the curve at the given point at t.\n var subCurbePoints = CubicBezierCurve.utils.getSubCurvePointsAt(this, tStart, tEnd);\n return new CubicBezierCurve(subCurbePoints[0], subCurbePoints[1], subCurbePoints[2], subCurbePoints[3]);\n };\n /**\n * Convert a relative curve position u to the absolute curve position t.\n *\n * @method convertU2t\n * @param {number} u - The relative position on the curve in [0,arcLength].\n * @instance\n * @memberof CubicBezierCurve\n * @return {number}\n **/\n CubicBezierCurve.prototype.convertU2T = function (u) {\n return Math.max(0.0, Math.min(1.0, u / this.arcLength));\n };\n /**\n * Get the curve tangent vector at a given relative position u in [0,arcLength].<br>\n * <br>\n * Note that the returned tangent vector (end point) is not normalized.\n *\n * @method getTangent\n * @param {number} u - The position on the curve in [0,arcLength].\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex}\n **/\n CubicBezierCurve.prototype.getTangent = function (u) {\n return this.getTangentAt(this.convertU2T(u));\n };\n /**\n * Get the curve perpendicular at a given relative position u in [0,arcLength] as a vector.<br>\n * <br>\n * Note that the returned vector (end point) is not normalized.\n *\n * @method getPerpendicular\n * @param {number} u - The relative position on the curve in [0,arcLength].\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex}\n **/\n CubicBezierCurve.prototype.getPerpendicular = function (u) {\n return this.getPerpendicularAt(this.convertU2T(u));\n };\n /**\n * Get the curve perpendicular at a given absolute position t in [0,1] as a vector.<br>\n * <br>\n * Note that the returned vector (end point) is not normalized.\n *\n * @method getPerpendicularAt\n * @param {number} u - The absolute position on the curve in [0,1].\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex}\n **/\n CubicBezierCurve.prototype.getPerpendicularAt = function (t) {\n var tangentVector = this.getTangentAt(t);\n return new Vertex_1.Vertex(tangentVector.y, -tangentVector.x);\n };\n /**\n * Clone this Bézier curve (deep clone).\n *\n * @method clone\n * @instance\n * @memberof CubicBezierCurve\n * @return {CubicBezierCurve}\n **/\n CubicBezierCurve.prototype.clone = function () {\n return new CubicBezierCurve(this.getStartPoint().clone(), this.getEndPoint().clone(), this.getStartControlPoint().clone(), this.getEndControlPoint().clone());\n };\n //---BEGIN PathSegment-------------------------\n /**\n * Get the tangent's end point at the start point of this segment.\n *\n * @method getStartTangent\n * @memberof PathSegment\n * @return {Vertex} The end point of the starting point's tangent.\n */\n CubicBezierCurve.prototype.getStartTangent = function () {\n return this.startControlPoint;\n };\n /**\n * Get the tangent's end point at the end point of this segment.\n *\n * @method getEndTangent\n * @memberof PathSegment\n * @return {Vertex} The end point of the ending point's tangent.\n */\n CubicBezierCurve.prototype.getEndTangent = function () {\n return this.endControlPoint;\n };\n //---END PathSegment-------------------------\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get all line intersections with this shape.\n *\n * This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.\n *\n * @param {VertTuple} line - The line to find intersections with.\n * @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).\n * @returns {Array<Vertex>} - An array of all intersections with the shape outline.\n */\n CubicBezierCurve.prototype.lineIntersections = function (line, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n var intersectionTs = this.lineIntersectionTs(line);\n var intersectionPoints = intersectionTs.map(function (t) {\n return _this.getPointAt(t);\n });\n if (inVectorBoundsOnly) {\n // const maxDist = line.length();\n return intersectionPoints.filter(function (vert) { return line.hasPoint(vert, true); });\n }\n else {\n return intersectionPoints;\n }\n };\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @param line\n * @param lineIntersectionTangents\n * @returns\n */\n CubicBezierCurve.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n var intersectionTs = this.lineIntersectionTs(line);\n var intersectionTangents = intersectionTs.map(function (t) {\n var startPoint = _this.getPointAt(t);\n var endPoint = _this.getTangentAt(t);\n return new Vector_1.Vector(startPoint, endPoint.add(startPoint));\n });\n if (inVectorBoundsOnly) {\n return intersectionTangents.filter(function (vec) { return line.hasPoint(vec.a, true); });\n }\n else {\n return intersectionTangents;\n }\n };\n //--- END --- Implement interface `Intersectable`\n CubicBezierCurve.prototype.lineIntersectionTs = function (line) {\n var A = line.b.y - line.a.y; // A=y2-y1\n var B = line.a.x - line.b.x; // B=x1-x2\n var C = line.a.x * (line.a.y - line.b.y) + line.a.y * (line.b.x - line.a.x); //C=x1*(y1-y2)+y1*(x2-x1)\n // var bx = bezierCoeffs(px[0], px[1], px[2], px[3]);\n // var by = bezierCoeffs(py[0], py[1], py[2], py[3]);\n var bx = CubicBezierCurve.utils.bezierCoeffs(this.startPoint.x, this.startControlPoint.x, this.endControlPoint.x, this.endPoint.x);\n var by = CubicBezierCurve.utils.bezierCoeffs(this.startPoint.y, this.startControlPoint.y, this.endControlPoint.y, this.endPoint.y);\n var poly = Array(4);\n poly[0] = A * bx[0] + B * by[0]; /*t^3*/\n poly[1] = A * bx[1] + B * by[1]; /*t^2*/\n poly[2] = A * bx[2] + B * by[2]; /*t*/\n poly[3] = A * bx[3] + B * by[3] + C; /*1*/\n var roots = CubicBezierCurve.utils.cubicRoots(poly);\n return roots.filter(function (root) { return root != -1; });\n };\n /**\n * Check if this and the specified curve are equal.<br>\n * <br>\n * All four points need to be equal for this, the Vertex.equals function is used.<br>\n * <br>\n * Please note that this function is not type safe (comparison with any object will fail).\n *\n * @method clone\n * @param {CubicBezierCurve} curve - The curve to compare with.\n * @instance\n * @memberof CubicBezierCurve\n * @return {boolean}\n **/\n CubicBezierCurve.prototype.equals = function (curve) {\n // Note: in the earlier vanilla-JS version this was callable with plain objects.\n // Let's see if this restricted version works out.\n if (!curve)\n return false;\n if (!curve.startPoint || !curve.endPoint || !curve.startControlPoint || !curve.endControlPoint)\n return false;\n return (this.startPoint.equals(curve.startPoint) &&\n this.endPoint.equals(curve.endPoint) &&\n this.startControlPoint.equals(curve.startControlPoint) &&\n this.endControlPoint.equals(curve.endControlPoint));\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n CubicBezierCurve.prototype.destroy = function () {\n this.startPoint.destroy();\n this.endPoint.destroy();\n this.startControlPoint.destroy();\n this.endControlPoint.destroy();\n this.isDestroyed = true;\n };\n /**\n * Quick check for class instance.\n * Is there a better way?\n *\n * @method isInstance\n * @param {any} obj - Check if the passed object/value is an instance of CubicBezierCurve.\n * @instance\n * @memberof CubicBezierCurve\n * @return {boolean}\n **/\n CubicBezierCurve.isInstance = function (obj) {\n // Note: check this again\n /* OLD VANILLA JS IMPLEMENTATION */\n /* if( typeof obj != \"object\" )\n return false;\n function hasXY(v) {\n return typeof v != \"undefined\" && typeof v.x == \"number\" && typeof v.y == \"number\";\n }\n return typeof obj.startPoint == \"object\" && hasXY(obj.startPoint)\n && typeof obj.endPoint == \"object\" && hasXY(obj.endPoint)\n && typeof obj.startControlPoint == \"object\" && hasXY(obj.startControlPoint)\n && typeof obj.endControlPoint == \"object\" && hasXY(obj.endControlPoint);\n */\n return obj instanceof CubicBezierCurve;\n };\n /**\n * Convert this curve to a JSON string.\n *\n * @method toJSON\n * @param {boolean=} [prettyFormat=false] - If set to true the function will add line breaks.\n * @instance\n * @memberof CubicBezierCurve\n * @return {string} The JSON data.\n **/\n CubicBezierCurve.prototype.toJSON = function (prettyFormat) {\n var jsonString = \"{ \" + // begin object\n (prettyFormat ? \"\\n\\t\" : \"\") +\n '\"startPoint\" : [' +\n this.getStartPoint().x +\n \",\" +\n this.getStartPoint().y +\n \"], \" +\n (prettyFormat ? \"\\n\\t\" : \"\") +\n '\"endPoint\" : [' +\n this.getEndPoint().x +\n \",\" +\n this.getEndPoint().y +\n \"], \" +\n (prettyFormat ? \"\\n\\t\" : \"\") +\n '\"startControlPoint\": [' +\n this.getStartControlPoint().x +\n \",\" +\n this.getStartControlPoint().y +\n \"], \" +\n (prettyFormat ? \"\\n\\t\" : \"\") +\n '\"endControlPoint\" : [' +\n this.getEndControlPoint().x +\n \",\" +\n this.getEndControlPoint().y +\n \"]\" +\n (prettyFormat ? \"\\n\\t\" : \"\") +\n \" }\"; // end object\n return jsonString;\n };\n /**\n * Parse a Bézier curve from the given JSON string.\n *\n * @method fromJSON\n * @param {string} jsonString - The JSON data to parse.\n * @memberof CubicBezierCurve\n * @static\n * @throws An exception if the JSON string is malformed.\n * @return {CubicBezierCurve}\n **/\n CubicBezierCurve.fromJSON = function (jsonString) {\n var obj = JSON.parse(jsonString);\n return CubicBezierCurve.fromObject(obj);\n };\n /**\n * Try to convert the passed object to a CubicBezierCurve.\n *\n * @method fromObject\n * @param {object} obj - The object to convert.\n * @memberof CubicBezierCurve\n * @static\n * @throws An exception if the passed object is malformed.\n * @return {CubicBezierCurve}\n **/\n CubicBezierCurve.fromObject = function (obj) {\n if (typeof obj !== \"object\")\n throw \"Can only build from object.\";\n if (!obj.startPoint)\n throw 'Object member \"startPoint\" missing.';\n if (!obj.endPoint)\n throw 'Object member \"endPoint\" missing.';\n if (!obj.startControlPoint)\n throw 'Object member \"startControlPoint\" missing.';\n if (!obj.endControlPoint)\n throw 'Object member \"endControlPoint\" missing.';\n return new CubicBezierCurve(new Vertex_1.Vertex(obj.startPoint[0], obj.startPoint[1]), new Vertex_1.Vertex(obj.endPoint[0], obj.endPoint[1]), new Vertex_1.Vertex(obj.startControlPoint[0], obj.startControlPoint[1]), new Vertex_1.Vertex(obj.endControlPoint[0], obj.endControlPoint[1]));\n };\n /**\n * Convert a 4-element array of vertices to a cubic bézier curve.\n *\n * @method fromArray\n * @param {Vertex[]} arr - [ startVertex, endVertex, startControlVertex, endControlVertex ]\n * @memberof CubicBezierCurve\n * @throws An exception if the passed array is malformed.\n * @return {CubicBezierCurve}\n **/\n CubicBezierCurve.fromArray = function (arr) {\n if (!Array.isArray(arr))\n throw \"Can only build from object.\";\n if (arr.length != 4)\n throw \"Can only build from array with four elements.\";\n return new CubicBezierCurve(arr[0], arr[1], arr[2], arr[3]);\n };\n /** @constant {number} */\n CubicBezierCurve.START_POINT = 0;\n /** @constant {number} */\n CubicBezierCurve.START_CONTROL_POINT = 1;\n /** @constant {number} */\n CubicBezierCurve.END_CONTROL_POINT = 2;\n /** @constant {number} */\n CubicBezierCurve.END_POINT = 3;\n /**\n * Helper utils.\n */\n CubicBezierCurve.utils = {\n evaluateT: function (p0, p1, p2, p3, t) {\n return p0 * Math.pow(1.0 - t, 3) +\n p1 * 3 * t * Math.pow(1.0 - t, 2) +\n p2 * 3 * Math.pow(t, 2) * (1.0 - t) +\n p3 * Math.pow(t, 3);\n },\n cubicPolyMinMax: function (p0, p1, p2, p3) {\n // var polyX = CubicBezierCurve.utils.cubicPoly2(\n // p0, // P[0].X, // bezierCurve.startPoint.x,\n // p1, // P[1].X, // bezierCurve.startControlPoint.x,\n // p2, // P[2].X, // bezierCurve.endControlPoint.x,\n // p3 // P[3].X // bezierCurve.endPoint.x\n // );\n // var a = polyX.a;\n // var b = polyX.b;\n // var c = polyX.c;\n // var disc = polyX.b * polyX.b - 4 * polyX.a * polyX.c;\n var polyX = CubicBezierCurve.utils.cubicPoly(p0, // P[0].X, // bezierCurve.startPoint.x,\n p1, // P[1].X, // bezierCurve.startControlPoint.x,\n p2, // P[2].X, // bezierCurve.endControlPoint.x,\n p3 // P[3].X // bezierCurve.endPoint.x\n );\n var a = polyX[0]; // .a;\n var b = polyX[1]; // .b;\n var c = polyX[2]; // .c;\n //alert(\"a \"+a+\" \"+b+\" \"+c);\n // var disc = b * b - 4 * a * c;\n var disc = polyX[1] * polyX[1] - 4 * polyX[0] * polyX[2];\n // var polyX = CubicBezierCurve.utils.bezierCoeffs(p3,p2,p1,p0);\n // var a = polyX[0]; //polyX.a;\n // var b = polyX[1]; // .b;\n // var c = polyX[2]; //.c;\n // var disc = polyX[1] * polyX[1] - 4 * polyX[0] * polyX[2];\n // var xl = Math.min(bCurve.endPoint.x, bCurve.startPoint.x); // P[0].X;\n // var xh = Math.max(bCurve.endPoint.x, bCurve.startPoint.x); // P[0].X;\n var xl = Math.min(p3, p0); // P[0].X;\n var xh = Math.max(p3, p0); // P[0].X;\n // if (P[3].X < xl) xl = P[3].X;\n // if (P[3].X > xh) xh = P[3].X;\n if (disc >= 0) {\n var t1 = (-b + Math.sqrt(disc)) / (2 * a);\n // alert(\"t1 \" + t1);\n if (t1 > 0 && t1 < 1) {\n // var x1 = evalBez(PX, t1);\n // var x1 = bCurve.getPointAt(t1).x;\n var x1 = CubicBezierCurve.utils.evaluateT(p0, p1, p2, p3, t1); // bCurve.getPointAt(t1).x;\n if (x1 < xl)\n xl = x1;\n if (x1 > xh)\n xh = x1;\n }\n var t2 = (-b - Math.sqrt(disc)) / (2 * a);\n // alert(\"t2 \" + t2);\n if (t2 > 0 && t2 < 1) {\n // var x2 = evalBez(PX, t2);\n // var x2 = bCurve.getPointAt(t2).x;\n var x2 = CubicBezierCurve.utils.evaluateT(p0, p1, p2, p3, t2); //\n if (x2 < xl)\n xl = x2;\n if (x2 > xh)\n xh = x2;\n }\n }\n return { min: xl, max: xh };\n },\n /**\n * Get the points of a sub curve at the given start end end offsets (values between 0.0 and 1.0).\n *\n * tStart >= tEnd is allowed, you will get a reversed sub curve then.\n *\n * @method getSubCurvePointsAt\n * @param {CubicBezierCurve} curve – The curve to get the sub curve points from.\n * @param {number} tStart – The start offset of the desired sub curve (must be in [0..1]).\n * @param {number} tEnd – The end offset if the desired cub curve (must be in [0..1]).\n * @instance\n * @memberof CubicBezierCurve\n * @return {CubicBezierCurve} The sub curve as a new curve.\n **/\n getSubCurvePointsAt: function (curve, tStart, tEnd) {\n var startVec = new Vector_1.Vector(curve.getPointAt(tStart), curve.getTangentAt(tStart));\n var endVec = new Vector_1.Vector(curve.getPointAt(tEnd), curve.getTangentAt(tEnd).inv());\n // Tangents are relative. Make absolute.\n startVec.b.add(startVec.a);\n endVec.b.add(endVec.a);\n // This 'splits' the curve at the given point at t.\n startVec.scale(0.33333333 * (tEnd - tStart));\n endVec.scale(0.33333333 * (tEnd - tStart));\n return [startVec.a, endVec.a, startVec.b, endVec.b];\n },\n /**\n * Compute the cubic roots for the given cubic polynomial coefficients.\n *\n * Based on\n * http://mysite.verizon.net/res148h4j/javascript/script_exact_cubic.html#the%20source%20code\n * Inspired by\n * https://www.particleincell.com/2013/cubic-line-intersection/\n * Thanks to Stephan Schmitt and Particle-In-Cell!\n *\n * @param poly\n * @returns\n */\n cubicRoots: function (poly) {\n var a = poly[0];\n var b = poly[1];\n var c = poly[2];\n var d = poly[3];\n var A = b / a;\n var B = c / a;\n var C = d / a;\n var S, T, Im;\n var Q = (3 * B - Math.pow(A, 2)) / 9;\n var R = (9 * A * B - 27 * C - 2 * Math.pow(A, 3)) / 54;\n var D = Math.pow(Q, 3) + Math.pow(R, 2); // polynomial discriminant\n var ts = []; // Array();\n if (D >= 0) {\n // complex or duplicate roots\n S = CubicBezierCurve.utils.sgn(R + Math.sqrt(D)) * Math.pow(Math.abs(R + Math.sqrt(D)), 1 / 3);\n T = CubicBezierCurve.utils.sgn(R - Math.sqrt(D)) * Math.pow(Math.abs(R - Math.sqrt(D)), 1 / 3);\n ts[0] = -A / 3 + (S + T); // real root\n ts[1] = -A / 3 - (S + T) / 2; // real part of complex root\n ts[2] = -A / 3 - (S + T) / 2; // real part of complex root\n Im = Math.abs((Math.sqrt(3) * (S - T)) / 2); // complex part of root pair\n // Mark complex roots to be discarded\n if (Im != 0) {\n ts[1] = -1;\n ts[2] = -1;\n }\n } // distinct real roots\n else {\n var th = Math.acos(R / Math.sqrt(-Math.pow(Q, 3)));\n ts[0] = 2 * Math.sqrt(-Q) * Math.cos(th / 3) - A / 3;\n ts[1] = 2 * Math.sqrt(-Q) * Math.cos((th + 2 * Math.PI) / 3) - A / 3;\n ts[2] = 2 * Math.sqrt(-Q) * Math.cos((th + 4 * Math.PI) / 3) - A / 3;\n Im = 0.0;\n }\n // Discard all t's out of spec and sort the rest\n return ts.filter(function (t) { return t >= 0 && t <= 1.0; }).sort();\n },\n /**\n * Compute the Bézier coefficients from the given Bézier point coordinates.\n *\n * @param {number} p0 - The start point coordinate.\n * @param {number} p1 - The start control point coordinate.\n * @param {number} p2 - The end control point coordinate.\n * @param {number} p3 - The end point coordinate.\n * @returns {[number,number,number,number]}\n */\n bezierCoeffs: function (p0, p1, p2, p3) {\n var coeffs = [NaN, NaN, NaN, NaN]; //Array(4);\n coeffs[0] = -p0 + 3 * p1 + -3 * p2 + p3;\n coeffs[1] = 3 * p0 - 6 * p1 + 3 * p2;\n coeffs[2] = -3 * p0 + 3 * p1;\n coeffs[3] = p0;\n return coeffs;\n },\n /**\n * Calculate the cubic polynomial coefficients used to find the bounding box.\n *\n * @param {number} p0 - The start point coordinate.\n * @param {number} p1 - The start control point coordinate.\n * @param {number} p2 - The end control point coordinate.\n * @param {number} p3 - The end point coordinate.\n * @returns {[number,number,number]}\n */\n cubicPoly: function (p0, p1, p2, p3) {\n return [\n 3 * p3 - 9 * p2 + 9 * p1 - 3 * p0,\n 6 * p0 - 12 * p1 + 6 * p2,\n 3 * p1 - 3 * p0\n ];\n },\n /**\n * sign of number, but is division safe: no zero returned :)\n */\n sgn: function (x) {\n return x < 0.0 ? -1 : 1;\n }\n };\n return CubicBezierCurve;\n}());\nexports.CubicBezierCurve = CubicBezierCurve;\n//# sourceMappingURL=CubicBezierCurve.js.map","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","\"use strict\";\n/* Imports for webpack */\n\nglobalThis.UIDGenerator = require(\"./UIDGenerator.js\").UIDGenerator;\nglobalThis.VertexAttr = require(\"./VertexAttr.js\").VertexAttr;\nglobalThis.VertexListeners = require(\"./VertexListeners.js\").VertexListeners;\nglobalThis.Vertex = require(\"./Vertex.js\").Vertex;\n\nglobalThis.Bounds = require(\"./Bounds.js\").Bounds;\nglobalThis.Grid = require(\"./Grid.js\").Grid;\nglobalThis.Line = require(\"./Line.js\").Line;\nglobalThis.Vector = require(\"./Vector.js\").Vector;\nglobalThis.CubicBezierCurve = require(\"./CubicBezierCurve.js\").CubicBezierCurve;\nglobalThis.BezierPath = require(\"./BezierPath.js\").BezierPath;\nglobalThis.Polygon = require(\"./Polygon.js\").Polygon;\nglobalThis.Triangle = require(\"./Triangle.js\").Triangle;\nglobalThis.VEllipse = require(\"./VEllipse.js\").VEllipse;\nglobalThis.VEllipseSector = require(\"./VEllipseSector.js\").VEllipseSector;\nglobalThis.Circle = require(\"./Circle.js\").Circle;\nglobalThis.CircleSector = require(\"./CircleSector.js\").CircleSector;\nglobalThis.PBImage = require(\"./PBImage.js\").PBImage;\nglobalThis.PBText = require(\"./PBText.js\").PBText;\nglobalThis.MouseHandler = require(\"./MouseHandler.js\").MouseHandler;\nglobalThis.KeyHandler = require(\"./KeyHandler.js\").KeyHandler;\nglobalThis.drawutils = require(\"./draw.js\").drawutils;\n// globalThis.drawutilsgl = require(\"./drawgl.js\").drawutilsgl; // Unfinished\nglobalThis.drawutilssvg = require(\"./drawutilssvg.js\").drawutilssvg;\nglobalThis.geomutils = require(\"./geomutils.js\").geomutils;\nglobalThis.PlotBoilerplate = require(\"./PlotBoilerplate.js\").PlotBoilerplate;\n"],"names":["extendStatics","__extends","this","d","b","Object","setPrototypeOf","__proto__","Array","p","prototype","hasOwnProperty","call","TypeError","String","__","constructor","create","defineProperty","exports","value","Vector","VertTuple_1","Vertex_1","_super","vertA","vertB","_this","a","className","perp","v","clone","sub","Vertex","y","x","add","inverse","tmp","inv","intersection","line","denominator","numerator1","numerator2","getOrthogonal","linePoint","startPoint","rotate","angle","utils","buildArrowHead","zA","zB","headlen","scaleX","scaleY","Math","atan2","vertices","push","cos","sin","PI","VertTuple","drawutils","CubicBezierCurve_1","drawutilssvg_1","Vector_1","context","fillShapes","ctx","offset","scale","applyStrokeOpts","strokeOptions","_a","_b","_c","_d","setLineDash","dashArray","map","dashArrayElem","lineDashOffset","dashOffset","lineJoin","lineCap","_fillOrDraw","color","fillStyle","fill","strokeStyle","stroke","beginDrawCycle","renderTime","endDrawCycle","setConfiguration","configuration","globalCompositeOperation","blendMode","setCurrentId","uid","setCurrentClassName","lineWidth","save","beginPath","moveTo","lineTo","restore","arrow","headLength","arrowHeadBasePosition","arrowHead","undefined","cubicBezierArrow","endPoint","startControlPoint","endControlPoint","diff","difference","cubicBezier","arrowHeadBasePositionBuffer","i","length","image","position","size","alpha","complete","naturalWidth","globalAlpha","drawImage","naturalHeight","texturedPoly","textureImage","textureSize","polygon","polygonPosition","rotation","basePolygonBounds","getBounds","targetTextureSize","getCenter","width","height","targetTextureOffset","min","translate","helpers","clipPoly","rect","closePath","bounds","max","CubicBezierCurve","bezierCurveTo","quadraticBezier","controlPoint","quadraticCurveTo","cubicBezierPath","path","isOpen","handle","point","square","handleLine","dot","round","arc","circle","center","radius","ellipse","circleArc","startAngle","endAngle","options","asSegment","radiusX","radiusY","grid","sizeX","sizeY","yMin","ceil","yMax","xMin","xMax","raster","diamondHandle","squareHandle","circleHandle","crosshair","cross","polyline","text","relX","relY","fontSize","fontFamily","font","fontWeight","fontStyle","indexOf","concat","textAlign","lineHeight","fillText","strokeText","label","pathData","inplace","drawutilssvg","copyPathData","transformPathData","Path2D","join","clear","clearRect","canvas","fillRect","vert","clip","Bounds","Polygon_1","containsVert","getWidth","getHeight","getScaled","scaleFactor","getMoved","moveAmount","move","getNorthPoint","getSouthPoint","getWestPoint","getEastPoint","getNorthWestPoint","getNorthEastPoint","getSouthEastPoint","getSouthWestPoint","toPolygon","Polygon","getMinDimension","getMaxDimension","randomPoint","horizontalSafeArea","verticalSafeArea","absHorizontalSafeArea","absVerticalSafeArea","random","toString","computeFromVertices","computeFromBoundsSet","boundingBoxes","fromDimension","origin","Circle","Bounds_1","Line_1","UIDGenerator_1","geomutils_1","UIDGenerator","next","setRadius","amount","containsPoint","circleUtils","containsCircle","epsilon","Number","isNaN","distance","abs","lineDistance","getClosestPoint","vertAt","tangentAt","pointA","subXY","addXY","circleIntersection","p0","p1","h","sqrt","p2","x3","y3","x4","y4","Line","lineIntersection","interA","interB","transA","transB","dist","det","distSquared","belowSqrt","sign","lineIntersections","inVectorBoundsOnly","intersectioLine","filter","hasPoint","lineIntersectionTangents","radicalAxis","circleB","helperCircle","createRadicalAxisHelperCircle","intersectionLineA","intersectionLineB","console","error","lineA","lineB","firstRadicalAxisPoint","secondRadicalAxisPoint_mirrored","closestPoint","tangentsFromPoint","centerDistance","tangentLength","log","fromICircle","obj","destroy","isDestroyed","circleCenter","circleRadius","geomutils","dist4","circleA","circleConnectLine","set","bisector","bisectorLength","setLength","circleDistance","CircleSector","Circle_1","_self","circleBounds","candidates","containsAngle","getStartPoint","getEndPoint","wrappedAngle","mapAngleTo2PI","wrappedStart","wrappedEnd","angleAt","t","circleSectorIntersection","sector","radicalLine","thisIntersectionAngleA","thisIntersectionAngleB","thatIntersectionAngleA","thatIntersectionAngleB","centerOfOriginalGap","resultSector","ray","ellipseIntersections","tmpLine","intersectionPoint","lineAngle","wrapMinMax","describeSVGPath","circleSectorUtils","describeSVGArc","polarToCartesian","centerX","centerY","moveToStart","end","start","firstHalf","secondHalf","largeArcFlag","sweepFlag","drawutilsgl","gl","_zindex","glutils","GLU","_vertShader","compileShader","vertCode","VERTEX_SHADER","_fragShader","fragCode","FRAGMENT_SHADER","_program","makeProgram","vertex_buffer","createBuffer","_x2rel","_y2rel","copyInstance","copy","curId","Float32Array","bindBuffer","ARRAY_BUFFER","bufferData","STATIC_DRAW","coord","getAttribLocation","vertexAttribPointer","FLOAT","enableVertexAttribArray","viewport","uRotationVector","getUniformLocation","uniform2fv","drawArrays","LINES","TRIANGLE_FAN","clearColor","enable","DEPTH_TEST","COLOR_BUFFER_BIT","DEPTH_BUFFER_BIT","verts","vbuffer","shaderCode","shaderType","shader","createShader","shaderSource","getShaderParameter","COMPILE_STATUS","warn","getShaderInfoLog","deleteShader","vertShader","fragShader","program","createProgram","attachShader","linkProgram","useProgram","detachShader","Grid","baseLog","base","num","mapRasterScale","adjustFactor","gf","floor","pow","Triangle_1","new_angle","asin","x1","y1","x2","y2","dotProduct","nsectAngle","pA","pB","pC","n","triangle","Triangle","lineAB","lineAC","insideAngle","clockwise","determinant","result","wrapMax","CircleSector_1","RAD_TO_DEG","svgNode","canvasSize","drawConfig","isSecondary","gNode","bufferGNode","nodeDefs","bufferNodeDefs","nodeStyle","Boolean","drawlibConfiguration","cache","Map","setSize","bufferedNodeDefs","addStyleDefs","addDefsNode","createSVGNode","appendChild","rebuildStyleDefs","keys","rules","k","drawSettings","customStyleDefs","forEach","key","innerHTML","addCustomStyleDefs","defs","findElement","nodeName","node","get","toUpperCase","delete","document","createElementNS","makeNode","style","_bindFillDraw","_configureNode","_bindNode","bindingParent","parentNode","_addCSSClasses","curClassName","setAttribute","fillMode","childNodes","child","getAttribute","removeAllChildNodes","replaceChild","tmpGNode","tmpDefsNode","nodeSupportsLineDash","tagName","dashArayElem","nodeSupportsLineJoin","nodeSupportsLineCap","_x","_y","makeLineNode","group","makeArrowHeadNode","bezier","makeCubicBezierNode","setImageSize","ratioX","ratioY","addEventListener","event","src","rotatedScalingOrigin","clipPathNode","clipPathId","imageNode","pathNode","clipNode","arcData","transformOrigin","textNode","lastChild","removeChild","createSvg","data","slice","_stx","index","_sty","_sx","_sy","lastPoint","NaN","_slp","includes","classNameOverride","makePathNode","pathString","HEAD_XML","VertexAttr","draggable","selectable","isSelected","visible","model","KeyHandler","downListeners","pressListeners","upListeners","keyStates","element","globalThis","trackAllKeys","trackAll","installListeners","fireEvent","listeners","hasListener","lis","keyCode","listener","fireDownEvent","e","handler","firePressEvent","fireUpEvent","key2code","KEY_CODES","_keyDownListener","_keyPressListener","_keyUpListener","releaseListeners","removeEventListener","down","press","up","isDown","__setFunctionName","f","name","prefix","description","configurable","PlotBoilerplate","alloyfinger_typescript_1","draw_1","drawgl_1","BezierPath_1","Grid_1","KeyHandler_1","MouseHandler_1","PBImage_1","VEllipse_1","VEllipseSector_1","VertexAttr_1","PBText_1","config","contentChangeListeners","_gui","bezierAutoAdjust","fetch","fullSize","val","fitToParent","bool","offsetX","offsetY","rasterGrid","drawRaster","rasterScaleX","rasterScaleY","rasterAdjustFactor","drawOrigin","autoAdjustOffset","offsetAdjustXPercent","offsetAdjustYPercent","backgroundColor","redrawOnResize","defaultCanvasWidth","DEFAULT_CANVAS_WIDTH","defaultCanvasHeight","DEFAULT_CANVAS_HEIGHT","canvasWidthFactor","canvasHeightFactor","cssScaleX","cssScaleY","cssUniformScale","saveFile","hooks","setToRetina","_setToRetina","autoDetectRetina","enableSVGExport","preClear","func","preDraw","postDraw","enableMouse","enableTouch","enableKeys","enableMouseWheel","enableZoom","enablePan","enableGL","isBackdropFiltersEnabled","drawVertices","drawBezierHandleLines","drawBezierHandlePoints","drawHandleLines","drawHandlePoints","drawGrid","pathVertex","controlVertex","ellipseSector","circleSector","vertex","selectedVertex","vector","anchor","canvasElement","querySelector","toLowerCase","eventCatcher","getContext","draw","parentElement","createElement","left","top","cursor","body","title","selectPolygon","draggedElements","drawables","_saveFile","resizeCanvas","installInputListeners","updateCSSscale","redraw","focus","pb","tosvgDraw","tosvgFill","drawAll","svgCode","XMLSerializer","serializeToString","blob","Blob","type","_saveAs","pixelRatio","devicePixelRatio","isPanning","isInPanningMode","fitToView","canvasCenter","canvasRatio","ratio","setOffset","newUniformZoom","setZoom","setConsole","con","_e","setCSSscale","addContentChangeListener","removeContentChangeListener","splice","_fireContentChanged","addedDrawables","removedDrawables","drawable","doNotFireEvent","isArray","arr","addDragListener","params","dragAmount","VEllipse","axis","VEllipseSector","c","BezierPath","bezierPath","bezierCurves","adjustCircular","attr","enableBezierPathAutoAdjust","PBImage","upperLeft","lowerRight","PBText","remove","removeWithVertices","removedDrawables_1","wasRemoved_1","removeVertex","wasRemoved","removeAll","keepVertices","triggerRedraw","getVertexNear","pixelPosition","pixelTolerance","locatePointNear","transformMousePosition","typeName","vindex","gScale","gSize","cs","_handleColor","drawDrawables","drawDrawable","curveIndex","df","signedRadiusV","signedRadiusH","radiusH","radiusV","ellipseSectorUtils","drawSelectPolygon","clearSelection","getFProp","elem","propName","parseFloat","getComputedStyle","getPropertyValue","getAvailableContainerSpace","container","display","padding","border","pl","pr","pt","bl","br","bt","bb","w","clientWidth","clientHeight","_f","_g","_setSize","HTMLCanvasElement","SVGElement","adjustOffset","innerWidth","documentElement","innerHeight","space","selectVerticesInPolygon","tolerance","Draggable","VERTEX","setVIndex","handleClick","pos","DEFAULT_CLICK_TOLERANCE","fireClickEvent","keyHandler","paths","pindex","cindex","getPointByID","pid","revertMousePosition","getDraggedElementCount","mouseDownHandler","button","draggablePoint","fireDragStartEvent","mouseDragHandler","oldDragAmount","moveCurvePoint","fireDragEvent","mouseUpHandler","wasDragged","fireDragEndEvent","mouseWheelHandler","zoomStep","we","deltaY","preventDefault","newOffset","zoomFactorX","zoomFactorY","interactionPos","oldPos","newPos","newOffsetX","newOffsetY","MouseHandler","drag","wheel","relPos_1","getBoundingClientRect","touchMovePos","touchDownPos","draggedElement","multiTouchStartScale","clearTouch_1","afProps","touchStart","evt","touches","clientX","clientY","DEFAULT_TOUCH_TOLERANCE","draggingVertex","fakeEvent","isTouchEvent","mouseDownPos","mouseDragPos","touchMove","stopPropagation","rel","trans","deltaX","touchEnd","touchCancel","multipointStart","multipointEnd","pinch","touchItem0","item","touchItem1","fingerA","fingerB","zoom","window","createAlloyFinger","default","createGUI","props","getGUI","class_1","isVertex","safeMergeByKeys","extension","typ","extVal","JSON","parse","removeProperty","transform","fallback","locateCurveByStartPoint","START_POINT","updateArcLengths","locateCurveByStartControlPoint","adjustPredecessorControlPoint","locateCurveByEndControlPoint","adjustSuccessorControlPoint","locateCurveByEndPoint","END_CONTROL_POINT","factory","revert","normalize","factor","newA","v0","v1","colinear","EPSILON","getClosestT","l2","vtutils","dist2","insideBoundsOnly","pointDistance","calcCircumcircle","p1x","p1y","cx","cy","getLen","HandlerAdmin","el","handlers","del","dispatch","_args","len","apply","arguments","wrapFunc","handlerAdmin","AlloyFinger","option","bind","cancel","preV","pinchStartLen","isDoubleTap","noop","swipe","tap","doubleTap","longTap","singleTap","pressMove","twoFingerPressMove","_cancelAllHandler","cancelAll","delta","last","now","tapTimeout","singleTapTimeout","longTapTimeout","swipeTimeout","preTapPosition","Date","pageX","pageY","clearTimeout","_cancelLongTap","_cancelSingleTap","_preventTap","setTimeout","afEvent","currentX","currentY","sCurrentX","sCurrentY","v2","mr","r","acos","getAngle","sx2","sy2","movedX","movedY","changedTouches","self","direction","_swipeDirection","on","off","addVertex","addVertexAt","getEdgeAt","vertIndex","getVertexAt","getEdges","lines","getInnerAngleAt","p3","isAcute","isAngleAcute","zero","p2mp1","p3mp2","p2mp1_len","p3mp2_len","lengthProduct","A","B","C","inside","j","xi","yi","xj","yj","containsVerts","every","containsPolygon","lineSegment","area","signedArea","isClockwise","perimeter","getMeanCenter","getCentroid","cur","locateLineIntersecion","intersectionTuple","polyLine","edgeIndex","lineIntersectionTangentsIndices","closestLineIntersection","closestInterSectionIndex","closestLineIntersectionIndex","allIntersections","closestIntersection","MAX_VALUE","curDist","curVert","getInterpolationPolygon","interpolationCount","nextVert","lerpAmount","lerp","getEvenDistributionPolygon","pointCount","Error","polygonPoint","stepSize","polygonIndex","nextPolygonPoint","segmentLength","loopMax","curSegmentU","newPoint","lerpAbs","elimitateColinearEdges","eps","areColinear","vertC","toQuadraticBezierData","qbezier","cc0","cc1","edgeCenter","limit","toQuadraticBezierSVGString","qdata","buffer","toCubicBezierData","threshold","cbezier","aCenter","bCenter","a2","b0","toCubicBezierSVGString","toCubicBezierPath","pathdata","fromArray","total","l","sum","intersectionPoints","sAngle","eAngle","getExtremePoints","toCubicBezier","quarterSegmentCount","segmentCount","normalizeAngle","angles","equidistantVertAngles","curves","curAngle","nextAngle","startTangent","endTangent","curve","startDiff","endDiff","r2d","fullEllipsePointCount","ellipseAngles","startIndex","findClosestToStartAngle","ea","endpointToCenterParameters","rx","ry","phi","fa","fs","sinphi","cosphi","px","py","prx","pry","L","M","_cx","_cy","START_CONTROL_POINT","END_POINT","totalArcLength","addCurve","getLength","equals","getCurveCount","getCurveAt","getStartControlPoint","getEndControlPoint","scaleXY","scaleFactors","minIndex","minDist","curveT","uMin","u","getPointAt","getPoint","uTemp","relativeU","getTangentAt","getTangent","getPerpendicularAt","getPerpendicular","uResult","_locateUIndex","bCurve","uPart","reduce","accu","curCurve","uBefore","getSubPathAt","startT","endT","startU","endU","uStartResult","uEndResult","firstT","lastT","firstCurve","getSubCurveAt","reverse","pointID","obtainHandleLength","mainCurve","neighbourCurve","adjustNeighbourControlPoint","_mainCurve","mainPoint","mainControlPoint","neighbourPoint","neighbourControlPoint","obtainHandleLengths","_updateArcLengths","mainHandleBounds","neighbourHandleBounds","mainHandleLength","neighbourHandleLength","POSITIVE_INFINITY","NEGATIVE_INFINITY","getEvenDistributionVertices","arcLength","toPathPoints","toJSON","prettyFormat","fromJSON","jsonString","fromCurve","bPath","lastCurve","isInstance","fromObject","toReducedListRepresentation","digits","toFixed","fromReducedListRepresentation","listJSON","pointArray","fromReducedList","getArea","scaleToCentroid","centroid","getCircumcircle","getMinimumEnclosingCircle","circleAB","circleBC","circleCA","circumCircle","isAdjacent","tri","getThirdVertex","vert1","vert2","getVertices","tmpCircle","radius_squared","inCircumcircle","dx","dy","modIndex","pointIsInTriangle","getIncircularTriangle","lineC","bisector1","bisector2","getIncircle","getIncenter","max3","min3","p0x","p0y","p2x","p2y","s","D","E","F","G","VertexListeners_1","tuple","VertexListeners","setX","setY","invX","invY","amountX","amountY","addX","addY","subX","subY","eqX","eqY","target","step","factors","ZERO","multiplyScalar","scalar","findClosestPoint","pointB","findFarestPoint","precision","removeAllListeners","randomVertex","viewPort","arrayToJSON","stringify","x_max","x_min","t_x1","t_x2","x_x1","y_x1","x_x2","y_x2","y_max","y_min","t_y1","t_y2","x_y1","y_y1","x_y2","y_y2","r1","r2","ux","uy","vx","vy","bbox_halfwidth","bbox_halfheight","normalAt","foci","getFoci","angleA","centerAngle","endPointA","endPointB","resultVector","rh","rv","sdiff","getEquidistantVertices","ellipseCopy","rayCopy","rotationAmount","scalingFactors","intersections","phiToTheta","tanPhi","tan","tanPhi2","atan","theta","XWheelEvent","XMouseEvent","MouseEvent","WheelEvent","mouseButton","installed","mousemove","mkParams","relPos","mouseup","mousedown","click","eventName","xEvent","leftButton","middleButton","rightButton","draggedFrom","listenFor","unlistenFor","callback","throwAlreadyInstalled","dragStart","dragEnd","addClickListener","_addListener","removeClickListener","_removeListener","removeDragListener","addDragStartListener","removeDragStartListener","addDragEndListener","removeDragEndListener","_fireEvent","ve","newListener","oldListener","current","getStartTangent","getEndTangent","intrsctn","curveIntervals","segmentCache","segmentLengths","moveControlPoint","curveStep","tmpLength","newLength","tPrev","tNext","iteration","locateIntervalByDistance","tStart","tEnd","stepCount","tDiff","xMinMax","cubicPolyMinMax","xl","xh","yMinMax","yl","yh","id","evaluateT","t2","nt2","tX","tY","trimStart","uValue","trimStartAt","convertU2T","subCurbePoints","getSubCurvePointsAt","trimEnd","trimEndAt","getSubCurve","uStart","uEnd","tangentVector","lineIntersectionTs","intersectionTangents","vec","bx","bezierCoeffs","by","poly","cubicRoots","root","polyX","cubicPoly","disc","t1","startVec","endVec","S","T","Q","R","ts","sgn","th","sort","coeffs","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","module","__webpack_modules__","definition","o","enumerable","prop","Symbol","toStringTag"],"sourceRoot":""}
1
+ {"version":3,"file":"plotboilerplate.browser.min.js","mappings":"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","sources":["webpack://plotboilerplate/./src/cjs/Vector.js","webpack://plotboilerplate/./src/cjs/draw.js","webpack://plotboilerplate/./src/cjs/Bounds.js","webpack://plotboilerplate/./src/cjs/Circle.js","webpack://plotboilerplate/./src/cjs/CircleSector.js","webpack://plotboilerplate/./src/cjs/drawgl.js","webpack://plotboilerplate/./src/cjs/Grid.js","webpack://plotboilerplate/./src/cjs/geomutils.js","webpack://plotboilerplate/./src/cjs/drawutilssvg.js","webpack://plotboilerplate/./src/cjs/VertexAttr.js","webpack://plotboilerplate/./src/cjs/KeyHandler.js","webpack://plotboilerplate/./src/cjs/PlotBoilerplate.js","webpack://plotboilerplate/./src/cjs/VertTuple.js","webpack://plotboilerplate/./node_modules/alloyfinger-typescript/src/esm/alloy_finger.js","webpack://plotboilerplate/./node_modules/alloyfinger-typescript/src/esm/index.js","webpack://plotboilerplate/./src/cjs/PBText.js","webpack://plotboilerplate/./src/cjs/Polygon.js","webpack://plotboilerplate/./src/cjs/VEllipseSector.js","webpack://plotboilerplate/./src/cjs/BezierPath.js","webpack://plotboilerplate/./src/cjs/Triangle.js","webpack://plotboilerplate/./src/cjs/Vertex.js","webpack://plotboilerplate/./src/cjs/PBImage.js","webpack://plotboilerplate/./src/cjs/VEllipse.js","webpack://plotboilerplate/./src/cjs/MouseHandler.js","webpack://plotboilerplate/./src/cjs/VertexListeners.js","webpack://plotboilerplate/./src/cjs/UIDGenerator.js","webpack://plotboilerplate/./src/cjs/Line.js","webpack://plotboilerplate/./src/cjs/CubicBezierCurve.js","webpack://plotboilerplate/webpack/bootstrap","webpack://plotboilerplate/webpack/runtime/define property getters","webpack://plotboilerplate/webpack/runtime/hasOwnProperty shorthand","webpack://plotboilerplate/webpack/runtime/make namespace object","webpack://plotboilerplate/./src/cjs/entry.js"],"sourcesContent":["\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2019-01-30\n * @modified 2019-02-23 Added the toSVGString function, overriding Line.toSVGString.\n * @modified 2019-03-20 Added JSDoc tags.\n * @modified 2019-04-19 Added the clone function (overriding Line.clone()).\n * @modified 2019-09-02 Added the Vector.perp() function.\n * @modified 2019-09-02 Added the Vector.inverse() function.\n * @modified 2019-12-04 Added the Vector.inv() function.\n * @modified 2020-03-23 Ported to Typescript from JS.\n * @modified 2021-01-20 Added UID.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-02-02 Cleared the `Vector.toSVGString` function (deprecated). Use `drawutilssvg` instead.\n * @modified 2022-10-25 Added the `getOrthogonal` method.\n * @modified 2025-04-14 Added the `Vector.rotate(number)` method.\n * @version 1.6.0\n *\n * @file Vector\n * @public\n **/\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Vector = void 0;\nvar VertTuple_1 = require(\"./VertTuple\");\nvar Vertex_1 = require(\"./Vertex\");\n/**\n * @classdesc A vector (Vertex,Vertex) is a line with a visible direction.<br>\n * <br>\n * Vectors are drawn with an arrow at their end point.<br>\n * <b>The Vector class extends the Line class.</b>\n *\n * @requires VertTuple\n * @requires Vertex\n **/\nvar Vector = /** @class */ (function (_super) {\n __extends(Vector, _super);\n /**\n * The constructor.\n *\n * @constructor\n * @name Vector\n * @extends Line\n * @param {Vertex} vertA - The start vertex of the vector.\n * @param {Vertex} vertB - The end vertex of the vector.\n **/\n function Vector(vertA, vertB) {\n var _this = _super.call(this, vertA, vertB, function (a, b) { return new Vector(a, b); }) || this;\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n _this.className = \"Vector\";\n return _this;\n }\n /**\n * Get the perpendicular of this vector which is located at a.\n *\n * @return {Vector} A new vector being the perpendicular of this vector sitting on a.\n **/\n Vector.prototype.perp = function () {\n var v = this.clone();\n v.sub(this.a);\n v = new Vector(new Vertex_1.Vertex(), new Vertex_1.Vertex(-v.b.y, v.b.x));\n v.a.add(this.a);\n v.b.add(this.a);\n return v;\n };\n /**\n * The inverse of a vector is a vector with the same magnitude but oppose direction.\n *\n * Please not that the origin of this vector changes here: a->b becomes b->a.\n *\n * @return {Vector}\n **/\n Vector.prototype.inverse = function () {\n var tmp = this.a;\n this.a = this.b;\n this.b = tmp;\n return this;\n };\n /**\n * This function computes the inverse of the vector, which means 'a' stays untouched.\n *\n * @return {Vector} this for chaining.\n **/\n Vector.prototype.inv = function () {\n this.b.x = this.a.x - (this.b.x - this.a.x);\n this.b.y = this.a.y - (this.b.y - this.a.y);\n return this;\n };\n /**\n * Get the intersection if this vector and the specified vector.\n *\n * @method intersection\n * @param {Vector} line The second vector.\n * @return {Vertex} The intersection (may lie outside the end-points).\n * @instance\n * @memberof Line\n **/\n Vector.prototype.intersection = function (line) {\n var denominator = this.denominator(line);\n if (denominator == 0)\n return null;\n var a = this.a.y - line.a.y;\n var b = this.a.x - line.a.x;\n var numerator1 = (line.b.x - line.a.x) * a - (line.b.y - line.a.y) * b;\n var numerator2 = (this.b.x - this.a.x) * a - (this.b.y - this.a.y) * b;\n a = numerator1 / denominator; // NaN if parallel lines\n b = numerator2 / denominator;\n // TODO:\n // FOR A VECTOR THE LINE-INTERSECTION MUST BE ON BOTH VECTORS\n // if we cast these lines infinitely in both directions, they intersect here:\n return new Vertex_1.Vertex(this.a.x + a * (this.b.x - this.a.x), this.a.y + a * (this.b.y - this.a.y));\n };\n /**\n * Get the orthogonal \"vector\" of this vector (rotated by 90° clockwise).\n *\n * @name getOrthogonal\n * @method getOrthogonal\n * @return {Vector} A new vector with the same length that stands on this vector's point a.\n * @instance\n * @memberof Vector\n **/\n Vector.prototype.getOrthogonal = function () {\n // Orthogonal of vector (0,0)->(x,y) is (0,0)->(-y,x)\n var linePoint = this.a.clone();\n var startPoint = this.b.clone().sub(this.a);\n var tmp = startPoint.x;\n startPoint.x = -startPoint.y;\n startPoint.y = tmp;\n return new Vector(linePoint, startPoint.add(this.a));\n };\n /**\n * Rotate this vector by the given angle around the first point `a`.\n *\n * @name rotate\n * @method rotate\n * @return {Vector} this - for chaining.\n * @instance\n * @memberof Vector\n */\n Vector.prototype.rotate = function (angle) {\n this.b.rotate(angle, this.a);\n return this;\n };\n Vector.utils = {\n /**\n * Generate a four-point arrow head, starting at the vector end minus the\n * arrow head length.\n *\n * The first vertex in the returned array is guaranteed to be the located\n * at the vector line end minus the arrow head length.\n *\n *\n * Due to performance all params are required.\n *\n * The params scaleX and scaleY are required for the case that the scaling is not uniform (x and y\n * scaling different). Arrow heads should not look distored on non-uniform scaling.\n *\n * If unsure use 1.0 for scaleX and scaleY (=no distortion).\n * For headlen use 8, it's a good arrow head size.\n *\n * Example:\n * buildArrowHead( new Vertex(0,0), new Vertex(50,100), 8, 1.0, 1.0 )\n *\n * @param {XYCoords} zA - The start vertex of the vector to calculate the arrow head for.\n * @param {XYCoords} zB - The end vertex of the vector.\n * @param {number} headlen - The length of the arrow head (along the vector direction. A good value is 12).\n * @param {number} scaleX - The horizontal scaling during draw.\n * @param {number} scaleY - the vertical scaling during draw.\n **/\n buildArrowHead: function (zA, zB, headlen, scaleX, scaleY) {\n var angle = Math.atan2((zB.y - zA.y) * scaleY, (zB.x - zA.x) * scaleX);\n var vertices = [];\n vertices.push(new Vertex_1.Vertex(zB.x * scaleX - headlen * Math.cos(angle), zB.y * scaleY - headlen * Math.sin(angle)));\n vertices.push(new Vertex_1.Vertex(zB.x * scaleX - headlen * 1.35 * Math.cos(angle - Math.PI / 8), zB.y * scaleY - headlen * 1.35 * Math.sin(angle - Math.PI / 8)));\n vertices.push(new Vertex_1.Vertex(zB.x * scaleX, zB.y * scaleY));\n vertices.push(new Vertex_1.Vertex(zB.x * scaleX - headlen * 1.35 * Math.cos(angle + Math.PI / 8), zB.y * scaleY - headlen * 1.35 * Math.sin(angle + Math.PI / 8)));\n return vertices;\n }\n };\n return Vector;\n}(VertTuple_1.VertTuple));\nexports.Vector = Vector;\n//# sourceMappingURL=Vector.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2018-04-22\n * @modified 2018-08-16 Added the curve() function to draw cubic bézier curves.\n * @modified 2018-10-23 Recognizing the offset param in the circle() function.\n * @modified 2018-11-27 Added the diamondHandle() function.\n * @modified 2018-11-28 Added the grid() function and the ellipse() function.\n * @modified 2018-11-30 Renamed the text() function to label() as it is not scaling.\n * @modified 2018-12-06 Added a test function for drawing arc in SVG style.\n * @modified 2018-12-09 Added the dot(Vertex,color) function (copied from Feigenbaum-plot-script).\n * @modified 2019-01-30 Added the arrow(Vertex,Vertex,color) function for drawing arrow heads.\n * @modified 2019-01-30 Added the image(Image,Vertex,Vertex) function for drawing images.\n * @modified 2019-04-27 Fixed a severe drawing bug in the arrow(...) function. Scaling arrows did not work properly.\n * @modified 2019-04-28 Added Math.round to the dot() drawing parameters to really draw a singlt dot.\n * @modified 2019-06-07 Fixed an issue in the cubicBezier() function. Paths were always closed.\n * @modified 2019-10-03 Added the beginDrawCycle hook.\n * @modified 2019-10-25 Polygons are no longer drawn with dashed lines (solid lines instead).\n * @modified 2019-11-18 Added the polyline function.\n * @modified 2019-11-22 Added a second workaround for th drawImage bug in Safari.\n * @modified 2019-12-07 Added the 'lineWidth' param to the line(...) function.\n * @modified 2019-12-07 Added the 'lineWidth' param to the cubicBezier(...) function.\n * @modified 2019-12-11 Added the 'color' param to the label(...) function.\n * @modified 2019-12-18 Added the quadraticBezier(...) function (for the sake of approximating Lissajous curves).\n * @modified 2019-12-20 Added the 'lineWidth' param to the polyline(...) function.\n * @modified 2020-01-09 Added the 'lineWidth' param to the ellipse(...) function.\n * @modified 2020-03-25 Ported this class from vanilla-JS to Typescript.\n * @modified 2020-05-05 Added the 'lineWidth' param to the circle(...) function.\n * @modified 2020-05-12 Drawing any handles (square, circle, diamond) with lineWidth 1 now; this was not reset before.\n * @modified 2020-06-22 Added a context.clearRect() call to the clear() function; clearing with alpha channel did not work as expected.\n * @modified 2020-09-07 Added the circleArc(...) function to draw sections of circles.\n * @modified 2020-10-06 Removed the .closePath() instruction from the circleArc function.\n * @modified 2020-10-15 Re-added the text() function.\n * @modified 2020-10-28 Added the path(Path2D) function.\n * @modified 2020-12-28 Added the `singleSegment` mode (test).\n * @modified 2021-01-05 Added the image-loaded/broken check.\n * @modified 2021-01-24 Added the `setCurrentId` function from the `DrawLib` interface.\n * @modified 2021-02-22 Added the `path` drawing function to draw SVG path data.\n * @modified 2021-03-31 Added the `endDrawCycle` function from `DrawLib`.\n * @modified 2021-05-31 Added the `setConfiguration` function from `DrawLib`.\n * @modified 2021-11-12 Adding more parameters tot the `text()` function: fontSize, textAlign, fontFamily, lineHeight.\n * @modified 2021-11-19 Added the `color` param to the `label(...)` function.\n * @modified 2022-02-03 Added the `lineWidth` param to the `crosshair` function.\n * @modified 2022-02-03 Added the `cross(...)` function.\n * @modified 2022-03-27 Added the `texturedPoly` function.\n * @modified 2022-06-01 Tweaked the `polyline` function; lineWidth now scales with scale.x.\n * @modified 2022-07-26 Adding `alpha` to the `image(...)` function.\n * @modified 2022-08-23 Fixed a type issue in the `polyline` function.\n * @modified 2022-08-23 Fixed a type issue in the `setConfiguration` function.\n * @modified 2022-08-23 Fixed a type issue in the `path` function.\n * @modified 2023-02-10 The methods `setCurrentClassName` and `setCurrentId` also accept `null` now.\n * @modified 2023-09-29 Removed unused method stub for texturedPoly helper function (cleanup).\n * @modified 2023-09-29 Downgrading all `Vertex` param type to the more generic `XYCoords` type in these render functions: line, arrow, texturedPoly, cubicBezier, cubicBezierPath, handle, handleLine, dot, point, circle, circleArc, ellipse, grid, raster.\n * @modified 2023-09-29 Added the `headLength` parameter to the 'DrawLib.arrow()` function.\n * @modified 2023-09-29 Added the `arrowHead(...)` function to the 'DrawLib.arrow()` interface.\n * @modified 2023-09-29 Added the `cubicBezierArrow(...)` function to the 'DrawLib.arrow()` interface.\n * @modified 2023-09-29 Added the `lineDashes` attribute.\n * @modified 2023-09-30 Adding `strokeOptions` param to these draw function: line, arrow, cubicBezierArrow, cubicBezier, cubicBezierPath, circle, circleArc, ellipse, square, rect, polygon, polyline.\n * @modified 2023-10-07 Adding the optional `arrowHeadBasePositionBuffer` param to the arrowHead(...) method.\n * @modified 2024-09-13 Remoed the scaling of `lineWidth` in the `polygon` and `polyline` methods. This makes no sense here and doesn't match up with the behavior of other line functions.\n * @modified 2026-01-04 Adding `lineJoin` attribute to the `StrokeOptions`.\n * @modified 2026-03-18 Adding `isOpen` parameter to `cubicBezierPath` draw method.\n * @modified 2026-04-04 Added the method `bounds`.\n * @modified 2026-04-04 Handling the `lineCap` attribute in the `StrokeOptions`.\n * @version 1.15.0\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.drawutils = void 0;\nvar CubicBezierCurve_1 = require(\"./CubicBezierCurve\");\nvar Vertex_1 = require(\"./Vertex\");\nvar drawutilssvg_1 = require(\"./drawutilssvg\");\nvar Vector_1 = require(\"./Vector\");\n// Todo: rename this class to Drawutils?\n/**\n * @classdesc A wrapper class for basic drawing operations.\n *\n * @requires CubicBzierCurvce\n * @requires Polygon\n * @requires Vertex\n * @requires XYCoords\n */\nvar drawutils = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name drawutils\n * @param {anvasRenderingContext2D} context - The drawing context.\n * @param {boolean} fillShaped - Indicates if the constructed drawutils should fill all drawn shapes (if possible).\n **/\n function drawutils(context, fillShapes) {\n this.ctx = context;\n // this.lineDash = [];\n this.offset = new Vertex_1.Vertex(0, 0);\n this.scale = new Vertex_1.Vertex(1, 1);\n this.fillShapes = fillShapes;\n }\n /**\n * A private helper method to apply stroke options to the current\n * context.\n * @param {StrokeOptions=} strokeOptions -\n */\n drawutils.prototype.applyStrokeOpts = function (strokeOptions) {\n var _this = this;\n var _a, _b, _c, _d;\n this.ctx.setLineDash(((_a = strokeOptions === null || strokeOptions === void 0 ? void 0 : strokeOptions.dashArray) !== null && _a !== void 0 ? _a : []).map(function (dashArrayElem) {\n // Note assume scale.x === scale.y\n // Invariant scale makes funny stuff anyway.\n return dashArrayElem * _this.scale.x;\n }));\n this.ctx.lineDashOffset = ((_b = strokeOptions === null || strokeOptions === void 0 ? void 0 : strokeOptions.dashOffset) !== null && _b !== void 0 ? _b : 0) * this.scale.x;\n this.ctx.lineJoin = (_c = strokeOptions === null || strokeOptions === void 0 ? void 0 : strokeOptions.lineJoin) !== null && _c !== void 0 ? _c : null;\n this.ctx.lineCap = (_d = strokeOptions === null || strokeOptions === void 0 ? void 0 : strokeOptions.lineCap) !== null && _d !== void 0 ? _d : null;\n };\n // +---------------------------------------------------------------------------------\n // | This is the final helper function for drawing and filling stuff. It is not\n // | intended to be used from the outside.\n // |\n // | When in draw mode it draws the current shape.\n // | When in fill mode it fills the current shape.\n // |\n // | This function is usually only called internally.\n // |\n // | @param color A stroke/fill color to use.\n // +-------------------------------\n // TODO: convert this to a STATIC function.\n drawutils.prototype._fillOrDraw = function (color) {\n if (this.fillShapes) {\n this.ctx.fillStyle = color;\n this.ctx.fill();\n }\n else {\n this.ctx.strokeStyle = color;\n this.ctx.stroke();\n }\n };\n /**\n * Called before each draw cycle.\n * @param {UID=} uid - (optional) A UID identifying the currently drawn element(s).\n **/\n drawutils.prototype.beginDrawCycle = function (renderTime) {\n // NOOP\n };\n /**\n * Called after each draw cycle.\n *\n * This is required for compatibility with other draw classes in the library (like drawgl).\n *\n * @name endDrawCycle\n * @method\n * @param {number} renderTime\n * @instance\n **/\n drawutils.prototype.endDrawCycle = function (renderTime) {\n // NOOP\n };\n /**\n * Set the current drawlib configuration.\n *\n * @name setConfiguration\n * @method\n * @param {DrawLibConfiguration} configuration - The new configuration settings to use for the next render methods.\n */\n drawutils.prototype.setConfiguration = function (configuration) {\n this.ctx.globalCompositeOperation = configuration.blendMode || \"source-over\";\n };\n // /**\n // * Set or clear the line-dash configuration. Pass `null` for un-dashed lines.\n // *\n // * See https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray\n // * and https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash\n // * for how line dashes work.\n // *\n // * @method\n // * @param {Array<number> lineDashes - The line-dash array configuration.\n // * @returns {void}\n // */\n // setLineDash(lineDash: Array<number>) {\n // this.lineDash = lineDash;\n // }\n /**\n * This method shouled be called each time the currently drawn `Drawable` changes.\n * It is used by some libraries for identifying elemente on re-renders.\n *\n * @name setCurrentId\n * @method\n * @param {UID|null} uid - A UID identifying the currently drawn element(s).\n **/\n drawutils.prototype.setCurrentId = function (uid) {\n // NOOP\n };\n /**\n * This method shouled be called each time the currently drawn `Drawable` changes.\n * Determine the class name for further usage here.\n *\n * @name setCurrentClassName\n * @method\n * @param {string|null} className - A class name for further custom use cases.\n **/\n drawutils.prototype.setCurrentClassName = function (className) {\n // NOOP\n };\n /**\n * Draw the line between the given two points with the specified (CSS-) color.\n *\n * @method line\n * @param {XYCoords} zA - The start point of the line.\n * @param {XYCoords} zB - The end point of the line.\n * @param {string} color - Any valid CSS color string.\n * @param {number} lineWidth? - [optional] The line's width.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n **/\n drawutils.prototype.line = function (zA, zB, color, lineWidth, strokeOptions) {\n this.ctx.save();\n this.ctx.beginPath();\n this.applyStrokeOpts(strokeOptions);\n this.ctx.moveTo(this.offset.x + zA.x * this.scale.x, this.offset.y + zA.y * this.scale.y);\n this.ctx.lineTo(this.offset.x + zB.x * this.scale.x, this.offset.y + zB.y * this.scale.y);\n this.ctx.strokeStyle = color;\n this.ctx.lineWidth = lineWidth || 1;\n this.ctx.stroke();\n this.ctx.restore();\n };\n /**\n * Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.\n *\n * @method arrow\n * @param {XYCoords} zA - The start point of the arrow-line.\n * @param {XYCoords} zB - The end point of the arrow-line.\n * @param {string} color - Any valid CSS color string.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {headLength=8} headLength - (optional) The length of the arrow head (default is 8 units).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n **/\n drawutils.prototype.arrow = function (zA, zB, color, lineWidth, headLength, strokeOptions) {\n if (headLength === void 0) { headLength = 8; }\n var arrowHeadBasePosition = new Vertex_1.Vertex(0, 0);\n this.arrowHead(zA, zB, color, lineWidth, headLength, undefined, arrowHeadBasePosition); // Will NOT use dash configuration\n this.line(zA, arrowHeadBasePosition, color, lineWidth, strokeOptions); // Will use dash configuration\n };\n /**\n * Draw a cubic Bézier curve and and an arrow at the end (endControlPoint) of the given line width the specified (CSS-) color and arrow size.\n *\n * @method cubicBezierArrow\n * @param {XYCoords} startPoint - The start point of the cubic Bézier curve\n * @param {XYCoords} endPoint - The end point the cubic Bézier curve.\n * @param {XYCoords} startControlPoint - The start control point the cubic Bézier curve.\n * @param {XYCoords} endControlPoint - The end control point the cubic Bézier curve.\n * @param {string} color - The CSS color to draw the curve with.\n * @param {number} lineWidth - (optional) The line width to use.\n * @param {headLength=8} headLength - (optional) The length of the arrow head (default is 8 units).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof DrawLib\n */\n drawutils.prototype.cubicBezierArrow = function (startPoint, endPoint, startControlPoint, endControlPoint, color, lineWidth, headLength, strokeOptions) {\n var arrowHeadBasePosition = new Vertex_1.Vertex(0, 0);\n // Will NOT use dash configuration\n this.arrowHead(endControlPoint, endPoint, color, lineWidth, headLength, undefined, arrowHeadBasePosition);\n var diff = arrowHeadBasePosition.difference(endPoint);\n // Will use dash configuration\n this.cubicBezier(startPoint, { x: endPoint.x - diff.x, y: endPoint.y - diff.y }, startControlPoint, { x: endControlPoint.x - diff.x, y: endControlPoint.y - diff.y }, color, lineWidth, strokeOptions);\n };\n /**\n * Draw just an arrow head a the end of an imaginary line (zB) of the given line width the specified (CSS-) color and size.\n *\n * @method arrow\n * @param {XYCoords} zA - The start point of the arrow-line.\n * @param {XYCoords} zB - The end point of the arrow-line.\n * @param {string} color - Any valid CSS color string.\n * @param {number=1} lineWidth - (optional) The line width to use; default is 1.\n * @param {number=8} headLength - (optional) The length of the arrow head (default is 8 pixels).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n * @param {XYCoords=} arrowHeadBasePositionBuffer - (optional) If not null, then this position will contain the arrow head's start point (after execution). Some sort of OUT variable.\n *\n * @return {void}\n * @instance\n * @memberof DrawLib\n **/\n drawutils.prototype.arrowHead = function (zA, zB, color, lineWidth, headLength, strokeOptions, arrowHeadBasePositionBuffer) {\n // var headLength: number = 8; // length of head in pixels\n if (headLength === void 0) { headLength = 8; }\n this.ctx.save();\n this.ctx.beginPath();\n this.applyStrokeOpts(strokeOptions);\n var vertices = Vector_1.Vector.utils.buildArrowHead(zA, zB, headLength, this.scale.x, this.scale.y);\n if (arrowHeadBasePositionBuffer) {\n arrowHeadBasePositionBuffer.x = vertices[0].x / this.scale.x;\n arrowHeadBasePositionBuffer.y = vertices[0].y / this.scale.y;\n }\n this.ctx.moveTo(this.offset.x + vertices[0].x, this.offset.y + vertices[0].y);\n for (var i = 0; i < vertices.length; i++) {\n this.ctx.lineTo(this.offset.x + vertices[i].x, this.offset.y + vertices[i].y);\n }\n this.ctx.lineTo(this.offset.x + vertices[0].x, this.offset.y + vertices[0].y);\n this.ctx.lineWidth = lineWidth || 1;\n this._fillOrDraw(color);\n this.ctx.restore();\n };\n /**\n * Draw an image at the given position with the given size.<br>\n * <br>\n * Note: SVG images may have resizing issues at the moment.Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.\n *\n * @method image\n * @param {Image} image - The image object to draw.\n * @param {XYCoords} position - The position to draw the the upper left corner at.\n * @param {XYCoords} size - The x/y-size to draw the image with.\n * @param {number=0.0} alpha - (optional, default=0.0) The transparency (1.0=opaque, 0.0=transparent).\n * @return {void}\n * @instance\n * @memberof drawutils\n **/\n drawutils.prototype.image = function (image, position, size, alpha) {\n if (alpha === void 0) { alpha = 1.0; }\n if (!image.complete || !image.naturalWidth) {\n // Avoid drawing un-unloaded or broken images\n return;\n }\n this.ctx.save();\n this.ctx.globalAlpha = alpha;\n // Note that there is a Safari bug with the 3 or 5 params variant.\n // Only the 9-param varaint works.\n this.ctx.drawImage(image, 0, 0, image.naturalWidth - 1, // There is this horrible Safari bug (fixed in newer versions)\n image.naturalHeight - 1, // To avoid errors substract 1 here.\n this.offset.x + position.x * this.scale.x, this.offset.y + position.y * this.scale.y, size.x * this.scale.x, size.y * this.scale.y);\n this.ctx.restore();\n };\n /**\n * Draw an image at the given position with the given size.<br>\n * <br>\n * Note: SVG images may have resizing issues at the moment.Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.\n *\n * @method texturedPoly\n * @param {Image} textureImage - The image object to draw.\n * @param {Bounds} textureSize - The texture size to use; these are the original bounds to map the polygon vertices to.\n * @param {Polygon} polygon - The polygon to use as clip path.\n * @param {XYCoords} polygonPosition - The polygon's position (relative), measured at the bounding box's center.\n * @param {number} rotation - The rotation to use for the polygon (and for the texture).\n * @param {XYCoords={x:0,y:0}} rotationCenter - (optional) The rotational center; default is center of bounding box.\n * @return {void}\n * @instance\n * @memberof drawutils\n **/\n drawutils.prototype.texturedPoly = function (textureImage, textureSize, polygon, polygonPosition, rotation) {\n var basePolygonBounds = polygon.getBounds();\n // var targetCenterDifference = polygonPosition.clone().difference(basePolygonBounds.getCenter());\n var targetCenterDifference = new Vertex_1.Vertex(polygonPosition.x, polygonPosition.y).difference(basePolygonBounds.getCenter());\n // var tileCenter = basePolygonBounds.getCenter().sub(targetCenterDifference);\n // Get the position offset of the polygon\n var targetTextureSize = new Vertex_1.Vertex(textureSize.width, textureSize.height);\n // var targetTextureOffset = new Vertex(-textureSize.width / 2, -textureSize.height / 2).sub(targetCenterDifference);\n var targetTextureOffset = new Vertex_1.Vertex(textureSize.min.x, textureSize.min.y).sub(polygonPosition);\n this.ctx.save();\n // this.ctx.translate(this.offset.x + rotationCenter.x * this.scale.x, this.offset.y + rotationCenter.y * this.scale.y);\n this.ctx.translate(this.offset.x + polygonPosition.x * this.scale.x, this.offset.y + polygonPosition.y * this.scale.y);\n drawutils.helpers.clipPoly(this.ctx, {\n x: -polygonPosition.x * this.scale.x,\n y: -polygonPosition.y * this.scale.y\n }, this.scale, polygon.vertices);\n this.ctx.scale(this.scale.x, this.scale.y);\n this.ctx.rotate(rotation);\n this.ctx.drawImage(textureImage, 0, 0, textureImage.naturalWidth - 1, // There is this horrible Safari bug (fixed in newer versions)\n textureImage.naturalHeight - 1, // To avoid errors substract 1 here.\n targetTextureOffset.x, // * this.scale.x,\n targetTextureOffset.y, // * this.scale.y,\n targetTextureSize.x, // * this.scale.x,\n targetTextureSize.y // * this.scale.y\n );\n this.ctx.restore();\n };\n /*\n _texturedPoly(\n textureImage: HTMLImageElement,\n textureSize: Bounds,\n polygon: Polygon,\n polygonPosition: XYCoords,\n rotation: number,\n rotationCenter: XYCoords = { x: 0, y: 0 }\n ): void {\n var basePolygonBounds = polygon.getBounds();\n var targetCenterDifference = polygonPosition.clone().difference(basePolygonBounds.getCenter());\n var rotationalOffset = rotationCenter ? polygonPosition.difference(rotationCenter) : { x: 0, y: 0 };\n // var rotationalOffset = { x: 0, y: 0 };\n var tileCenter = basePolygonBounds.getCenter().sub(targetCenterDifference);\n \n // Get the position offset of the polygon\n var targetTextureSize = new Vertex(textureSize.width, textureSize.height);\n var targetTextureOffset = new Vertex(-textureSize.width / 2, -textureSize.height / 2).sub(targetCenterDifference);\n \n this.ctx.save();\n \n // this.ctx.translate(\n // this.offset.x + (tileCenter.x - rotationalOffset.x * 0 + targetTextureOffset.x * 0.0) * this.scale.x,\n // this.offset.y + (tileCenter.y - rotationalOffset.y * 0 + targetTextureOffset.y * 0.0) * this.scale.y\n // );\n this.ctx.translate(\n this.offset.x + (tileCenter.x - rotationalOffset.x * 0 + targetTextureOffset.x * 0.0) * this.scale.x,\n this.offset.y + (tileCenter.y - rotationalOffset.y * 0 + targetTextureOffset.y * 0.0) * this.scale.y\n );\n this.ctx.rotate(rotation);\n \n drawutils.helpers.clipPoly(\n this.ctx,\n {\n x: (-targetCenterDifference.x * 1 - tileCenter.x - rotationalOffset.x) * this.scale.x,\n y: (-targetCenterDifference.y * 1 - tileCenter.y - rotationalOffset.y) * this.scale.y\n },\n this.scale,\n polygon.vertices\n );\n this.ctx.drawImage(\n textureImage,\n 0,\n 0,\n textureImage.naturalWidth - 1, // There is this horrible Safari bug (fixed in newer versions)\n textureImage.naturalHeight - 1, // To avoid errors substract 1 here.\n (-polygonPosition.x + targetTextureOffset.x * 1 - rotationalOffset.x * 1) * this.scale.x,\n (-polygonPosition.y + targetTextureOffset.y * 1 - rotationalOffset.y * 1) * this.scale.y,\n targetTextureSize.x * this.scale.x,\n targetTextureSize.y * this.scale.y\n );\n \n // const scaledTextureSize = new Bounds(\n // new Vertex(\n // -polygonPosition.x + targetTextureOffset.x - rotationalOffset.x,\n // -polygonPosition.y + targetTextureOffset.y - rotationalOffset.y\n // ).scaleXY(this.scale, rotationCenter),\n // new Vertex(\n // -polygonPosition.x + targetTextureOffset.x - rotationalOffset.x + targetTextureSize.x,\n // -polygonPosition.y + targetTextureOffset.y - rotationalOffset.y + targetTextureSize.y\n // ).scaleXY(this.scale, rotationCenter)\n // );\n // this.ctx.drawImage(\n // textureImage,\n // 0,\n // 0,\n // textureImage.naturalWidth - 1, // There is this horrible Safari bug (fixed in newer versions)\n // textureImage.naturalHeight - 1, // To avoid errors substract 1 here.\n // scaledTextureSize.min.x,\n // scaledTextureSize.min.y,\n // scaledTextureSize.width,\n // scaledTextureSize.height\n // );\n \n this.ctx.restore();\n }\n */\n /**\n * Draw a rectangle.\n *\n * @param {XYCoords} position - The upper left corner of the rectangle.\n * @param {number} width - The width of the rectangle.\n * @param {number} height - The height of the rectangle.\n * @param {string} color - The color to use.\n * @param {number=1} lineWidth - (optional) The line with to use (default is 1).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n **/\n drawutils.prototype.rect = function (position, width, height, color, lineWidth, strokeOptions) {\n this.ctx.save();\n this.ctx.beginPath();\n this.applyStrokeOpts(strokeOptions);\n this.ctx.moveTo(this.offset.x + position.x * this.scale.x, this.offset.y + position.y * this.scale.y);\n this.ctx.lineTo(this.offset.x + (position.x + width) * this.scale.x, this.offset.y + position.y * this.scale.y);\n this.ctx.lineTo(this.offset.x + (position.x + width) * this.scale.x, this.offset.y + (position.y + height) * this.scale.y);\n this.ctx.lineTo(this.offset.x + position.x * this.scale.x, this.offset.y + (position.y + height) * this.scale.y);\n // this.ctx.lineTo( this.offset.x+position.x*this.scale.x, this.offset.y+position.y*this.scale.y );\n this.ctx.closePath();\n this.ctx.lineWidth = lineWidth || 1;\n this._fillOrDraw(color);\n this.ctx.restore();\n };\n /**\n * Draw a rectangle at the given bounds; and with the specified line width and (CSS-) color.<br>\n *\n * @method bounds\n * @param {IBounds} bounds - The bounds rectangle to be drawn.\n * @param {string} color - The CSS color to draw the rectangle with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {R}\n * @instance\n * @memberof DrawLib\n */\n drawutils.prototype.bounds = function (bounds, color, lineWidth, strokeOptions) {\n this.rect(bounds.min, bounds.max.x - bounds.min.x, bounds.max.y - bounds.min.y, color, lineWidth, strokeOptions);\n };\n /**\n * Draw the given (cubic) bézier curve.\n *\n * @method cubicBezier\n * @param {XYCoords} startPoint - The start point of the cubic Bézier curve\n * @param {XYCoords} endPoint - The end point the cubic Bézier curve.\n * @param {XYCoords} startControlPoint - The start control point the cubic Bézier curve.\n * @param {XYCoords} endControlPoint - The end control point the cubic Bézier curve.\n * @param {string} color - The CSS color to draw the curve with.\n * @param {number} lineWidth - (optional) The line width to use.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.cubicBezier = function (startPoint, endPoint, startControlPoint, endControlPoint, color, lineWidth, strokeOptions) {\n if (startPoint instanceof CubicBezierCurve_1.CubicBezierCurve) {\n this.cubicBezier(startPoint.startPoint, startPoint.endPoint, startPoint.startControlPoint, startPoint.endControlPoint, color, lineWidth);\n return;\n }\n // Draw curve\n this.ctx.save();\n this.ctx.beginPath();\n this.applyStrokeOpts(strokeOptions);\n this.ctx.moveTo(this.offset.x + startPoint.x * this.scale.x, this.offset.y + startPoint.y * this.scale.y);\n this.ctx.bezierCurveTo(this.offset.x + startControlPoint.x * this.scale.x, this.offset.y + startControlPoint.y * this.scale.y, this.offset.x + endControlPoint.x * this.scale.x, this.offset.y + endControlPoint.y * this.scale.y, this.offset.x + endPoint.x * this.scale.x, this.offset.y + endPoint.y * this.scale.y);\n //this.ctx.closePath();\n this.ctx.lineWidth = lineWidth || 2;\n this._fillOrDraw(color);\n this.ctx.restore();\n };\n /**\n * Draw the given (quadratic) bézier curve.\n *\n * @method quadraticBezier\n * @param {XYCoords} startPoint - The start point of the cubic Bézier curve\n * @param {XYCoords} controlPoint - The control point the cubic Bézier curve.\n * @param {XYCoords} endPoint - The end control point the cubic Bézier curve.\n * @param {string} color - The CSS color to draw the curve with.\n * @param {number|string} lineWidth - (optional) The line width to use.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.quadraticBezier = function (startPoint, controlPoint, endPoint, color, lineWidth, strokeOptions) {\n // Draw curve\n this.ctx.save();\n this.ctx.beginPath();\n this.applyStrokeOpts(strokeOptions);\n this.ctx.moveTo(this.offset.x + startPoint.x * this.scale.x, this.offset.y + startPoint.y * this.scale.y);\n this.ctx.quadraticCurveTo(this.offset.x + controlPoint.x * this.scale.x, this.offset.y + controlPoint.y * this.scale.y, this.offset.x + endPoint.x * this.scale.x, this.offset.y + endPoint.y * this.scale.y);\n this.ctx.lineWidth = lineWidth || 2;\n this._fillOrDraw(color);\n this.ctx.restore();\n };\n /**\n * Draw the given (cubic) Bézier path.\n *\n * The given path must be an array with n*3+1 vertices, where n is the number of\n * curves in the path:\n * <pre> [ point1, point1_startControl, point2_endControl, point2, point2_startControl, point3_endControl, point3, ... pointN_endControl, pointN ]</pre>\n *\n * @method cubicBezierPath\n * @param {XYCoords[]} path - The cubic bezier path as described above.\n * @param {string} color - The CSS colot to draw the path with.\n * @param {number=1} lineWidth - (optional) The line width to use.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.cubicBezierPath = function (path, color, lineWidth, strokeOptions, isOpen) {\n if (!path || path.length == 0) {\n return;\n }\n // Draw curve\n this.ctx.save();\n this.ctx.beginPath();\n var endPoint;\n var startControlPoint;\n var endControlPoint;\n this.applyStrokeOpts(strokeOptions);\n this.ctx.moveTo(this.offset.x + path[0].x * this.scale.x, this.offset.y + path[0].y * this.scale.y);\n for (var i = 1; i < path.length; i += 3) {\n startControlPoint = path[i];\n endControlPoint = path[i + 1];\n endPoint = path[i + 2];\n this.ctx.bezierCurveTo(this.offset.x + startControlPoint.x * this.scale.x, this.offset.y + startControlPoint.y * this.scale.y, this.offset.x + endControlPoint.x * this.scale.x, this.offset.y + endControlPoint.y * this.scale.y, this.offset.x + endPoint.x * this.scale.x, this.offset.y + endPoint.y * this.scale.y);\n }\n if (!isOpen) {\n this.ctx.closePath();\n }\n this.ctx.lineWidth = lineWidth || 1;\n this._fillOrDraw(color);\n this.ctx.restore();\n };\n /**\n * Draw the given handle and handle point (used to draw interactive Bézier curves).\n *\n * The colors for this are fixed and cannot be specified.\n *\n * @method handle\n * @param {XYCoords} startPoint - The start of the handle.\n * @param {XYCoords} endPoint - The end point of the handle.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.handle = function (startPoint, endPoint) {\n // Draw handles\n // (No need to save and restore here)\n this.point(startPoint, \"rgb(0,32,192)\");\n this.square(endPoint, 5, \"rgba(0,128,192,0.5)\");\n };\n /**\n * Draw a handle line (with a light grey).\n *\n * @method handleLine\n * @param {XYCoords} startPoint - The start point to draw the handle at.\n * @param {XYCoords} endPoint - The end point to draw the handle at.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.handleLine = function (startPoint, endPoint) {\n // Draw handle lines\n this.line(startPoint, endPoint, \"rgba(128,128,128, 0.5)\", undefined);\n };\n /**\n * Draw a 1x1 dot with the specified (CSS-) color.\n *\n * @method dot\n * @param {XYCoords} p - The position to draw the dot at.\n * @param {string} color - The CSS color to draw the dot with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.dot = function (p, color) {\n this.ctx.save();\n this.ctx.beginPath();\n this.ctx.setLineDash([]); // Clear line-dash settings\n this.ctx.moveTo(Math.round(this.offset.x + this.scale.x * p.x), Math.round(this.offset.y + this.scale.y * p.y));\n this.ctx.lineTo(Math.round(this.offset.x + this.scale.x * p.x + 1), Math.round(this.offset.y + this.scale.y * p.y + 1));\n this.ctx.closePath();\n this.ctx.lineWidth = 1;\n this._fillOrDraw(color);\n this.ctx.restore();\n };\n /**\n * Draw the given point with the specified (CSS-) color and radius 3.\n *\n * @method point\n * @param {XYCoords} p - The position to draw the point at.\n * @param {string} color - The CSS color to draw the point with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.point = function (p, color) {\n var radius = 3;\n this.ctx.setLineDash([]); // Clear line-dash settings\n this.ctx.beginPath();\n this.ctx.arc(this.offset.x + p.x * this.scale.x, this.offset.y + p.y * this.scale.y, radius, 0, 2 * Math.PI, false);\n this.ctx.closePath();\n this.ctx.lineWidth = 1;\n this._fillOrDraw(color);\n };\n /**\n * Draw a circle with the specified (CSS-) color and radius.<br>\n * <br>\n * Note that if the x- and y- scales are different the result will be an ellipse rather than a circle.\n *\n * @method circle\n * @param {XYCoords} center - The center of the circle.\n * @param {number} radius - The radius of the circle.\n * @param {string} color - The CSS color to draw the circle with.\n * @param {number} lineWidth - The line width (optional, default=1).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.circle = function (center, radius, color, lineWidth, strokeOptions) {\n this.applyStrokeOpts(strokeOptions);\n this.ctx.beginPath();\n this.ctx.ellipse(this.offset.x + center.x * this.scale.x, this.offset.y + center.y * this.scale.y, radius * this.scale.x, radius * this.scale.y, 0.0, 0.0, Math.PI * 2);\n this.ctx.closePath();\n this.ctx.lineWidth = lineWidth || 1;\n this._fillOrDraw(color);\n };\n /**\n * Draw a circular arc (section of a circle) with the given CSS color.\n *\n * @method circleArc\n * @param {XYCoords} center - The center of the circle.\n * @param {number} radius - The radius of the circle.\n * @param {number} startAngle - The angle to start at.\n * @param {number} endAngle - The angle to end at.\n * @param {string=#000000} color - The CSS color to draw the circle with.\n * @param {number=1} lineWidth - The line width to use\n * @param {boolean=false} options.asSegment - If `true` then no beginPath and no draw will be applied (as part of larger path).\n * @param {number=} options.dashOffset - (optional) `See StrokeOptions`.\n * @param {number=[]} options.dashArray - (optional) `See StrokeOptions`.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.circleArc = function (center, radius, startAngle, endAngle, color, lineWidth, options) {\n if (!options || !options.asSegment) {\n this.ctx.beginPath();\n }\n this.applyStrokeOpts(options);\n this.ctx.ellipse(this.offset.x + center.x * this.scale.x, this.offset.y + center.y * this.scale.y, radius * this.scale.x, radius * this.scale.y, 0.0, startAngle, endAngle, false);\n if (!options || !options.asSegment) {\n // this.ctx.closePath();\n this.ctx.lineWidth = lineWidth || 1;\n this._fillOrDraw(color || \"#000000\");\n }\n };\n /**\n * Draw an ellipse with the specified (CSS-) color and thw two radii.\n *\n * @method ellipse\n * @param {XYCoords} center - The center of the ellipse.\n * @param {number} radiusX - The radius of the ellipse.\n * @param {number} radiusY - The radius of the ellipse.\n * @param {string} color - The CSS color to draw the ellipse with.\n * @param {number} lineWidth=1 - An optional line width param (default is 1).\n * @param {number=} rotation - (optional, default=0) The rotation of the ellipse.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.ellipse = function (center, radiusX, radiusY, color, lineWidth, rotation, strokeOptions) {\n if (typeof rotation === \"undefined\") {\n rotation = 0.0;\n }\n this.applyStrokeOpts(strokeOptions);\n this.ctx.beginPath();\n this.ctx.ellipse(this.offset.x + center.x * this.scale.x, this.offset.y + center.y * this.scale.y, radiusX * this.scale.x, radiusY * this.scale.y, rotation, 0.0, Math.PI * 2);\n this.ctx.closePath();\n this.ctx.lineWidth = lineWidth || 1;\n this._fillOrDraw(color);\n };\n /**\n * Draw square at the given center, size and with the specified (CSS-) color.<br>\n * <br>\n * Note that if the x-scale and the y-scale are different the result will be a rectangle rather than a square.\n *\n * @method square\n * @param {XYCoords} center - The center of the square.\n * @param {number} size - The size of the square.\n * @param {string} color - The CSS color to draw the square with.\n * @param {number} lineWidth - The line with to use (optional, default is 1).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.square = function (center, size, color, lineWidth, strokeOptions) {\n this.applyStrokeOpts(strokeOptions);\n this.ctx.beginPath();\n this.ctx.rect(this.offset.x + (center.x - size / 2.0) * this.scale.x, this.offset.y + (center.y - size / 2.0) * this.scale.y, size * this.scale.x, size * this.scale.y);\n this.ctx.closePath();\n this.ctx.lineWidth = lineWidth || 1;\n this._fillOrDraw(color);\n };\n /**\n * Draw a grid of horizontal and vertical lines with the given (CSS-) color.\n *\n * @method grid\n * @param {XYCoords} center - The center of the grid.\n * @param {number} width - The total width of the grid (width/2 each to the left and to the right).\n * @param {number} height - The total height of the grid (height/2 each to the top and to the bottom).\n * @param {number} sizeX - The horizontal grid size.\n * @param {number} sizeY - The vertical grid size.\n * @param {string} color - The CSS color to draw the grid with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.grid = function (center, width, height, sizeX, sizeY, color) {\n this.ctx.setLineDash([]); // Clear line-dash settings\n this.ctx.beginPath();\n var yMin = -Math.ceil((height * 0.5) / sizeY) * sizeY;\n var yMax = height / 2;\n for (var x = -Math.ceil((width * 0.5) / sizeX) * sizeX; x < width / 2; x += sizeX) {\n this.ctx.moveTo(this.offset.x + (center.x + x) * this.scale.x, this.offset.y + (center.y + yMin) * this.scale.y);\n this.ctx.lineTo(this.offset.x + (center.x + x) * this.scale.x, this.offset.y + (center.y + yMax) * this.scale.y);\n }\n var xMin = -Math.ceil((width * 0.5) / sizeX) * sizeX; // -Math.ceil((height*0.5)/sizeY)*sizeY;\n var xMax = width / 2; // height/2;\n for (var y = -Math.ceil((height * 0.5) / sizeY) * sizeY; y < height / 2; y += sizeY) {\n this.ctx.moveTo(this.offset.x + (center.x + xMin) * this.scale.x - 4, this.offset.y + (center.y + y) * this.scale.y);\n this.ctx.lineTo(this.offset.x + (center.x + xMax) * this.scale.x + 4, this.offset.y + (center.y + y) * this.scale.y);\n }\n this.ctx.strokeStyle = color;\n this.ctx.lineWidth = 1.0;\n this.ctx.stroke();\n this.ctx.closePath();\n };\n /**\n * Draw a raster of crosshairs in the given grid.<br>\n *\n * This works analogue to the grid() function\n *\n * @method raster\n * @param {XYCoords} center - The center of the raster.\n * @param {number} width - The total width of the raster (width/2 each to the left and to the right).\n * @param {number} height - The total height of the raster (height/2 each to the top and to the bottom).\n * @param {number} sizeX - The horizontal raster size.\n * @param {number} sizeY - The vertical raster size.\n * @param {string} color - The CSS color to draw the raster with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.raster = function (center, width, height, sizeX, sizeY, color) {\n this.ctx.save();\n this.ctx.setLineDash([]); // Clear line-dash settings\n this.ctx.beginPath();\n for (var x = -Math.ceil((width * 0.5) / sizeX) * sizeX; x < width / 2; x += sizeX) {\n for (var y = -Math.ceil((height * 0.5) / sizeY) * sizeY; y < height / 2; y += sizeY) {\n // Draw a crosshair\n this.ctx.moveTo(this.offset.x + (center.x + x) * this.scale.x - 4, this.offset.y + (center.y + y) * this.scale.y);\n this.ctx.lineTo(this.offset.x + (center.x + x) * this.scale.x + 4, this.offset.y + (center.y + y) * this.scale.y);\n this.ctx.moveTo(this.offset.x + (center.x + x) * this.scale.x, this.offset.y + (center.y + y) * this.scale.y - 4);\n this.ctx.lineTo(this.offset.x + (center.x + x) * this.scale.x, this.offset.y + (center.y + y) * this.scale.y + 4);\n }\n }\n this.ctx.strokeStyle = color;\n this.ctx.lineWidth = 1.0;\n this.ctx.stroke();\n this.ctx.closePath();\n this.ctx.restore();\n };\n /**\n * Draw a diamond handle (square rotated by 45°) with the given CSS color.\n *\n * It is an inherent feature of the handle functions that the drawn elements are not scaled and not\n * distorted. So even if the user zooms in or changes the aspect ratio, the handles will be drawn\n * as even shaped diamonds.\n *\n * @method diamondHandle\n * @param {XYCoords} center - The center of the diamond.\n * @param {number} size - The x/y-size of the diamond.\n * @param {string} color - The CSS color to draw the diamond with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.diamondHandle = function (center, size, color) {\n this.ctx.setLineDash([]); // Clear line-dash settings\n this.ctx.beginPath();\n this.ctx.moveTo(this.offset.x + center.x * this.scale.x - size / 2.0, this.offset.y + center.y * this.scale.y);\n this.ctx.lineTo(this.offset.x + center.x * this.scale.x, this.offset.y + center.y * this.scale.y - size / 2.0);\n this.ctx.lineTo(this.offset.x + center.x * this.scale.x + size / 2.0, this.offset.y + center.y * this.scale.y);\n this.ctx.lineTo(this.offset.x + center.x * this.scale.x, this.offset.y + center.y * this.scale.y + size / 2.0);\n this.ctx.closePath();\n this.ctx.lineWidth = 1;\n this._fillOrDraw(color);\n };\n /**\n * Draw a square handle with the given CSS color.<br>\n * <br>\n * It is an inherent feature of the handle functions that the drawn elements are not scaled and not\n * distorted. So even if the user zooms in or changes the aspect ratio, the handles will be drawn\n * as even shaped squares.\n *\n * @method squareHandle\n * @param {XYCoords} center - The center of the square.\n * @param {number} size - The x/y-size of the square.\n * @param {string} color - The CSS color to draw the square with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.squareHandle = function (center, size, color) {\n this.ctx.setLineDash([]); // Clear line-dash settings\n this.ctx.beginPath();\n this.ctx.rect(this.offset.x + center.x * this.scale.x - size / 2.0, this.offset.y + center.y * this.scale.y - size / 2.0, size, size);\n this.ctx.closePath();\n this.ctx.lineWidth = 1;\n this._fillOrDraw(color);\n };\n /**\n * Draw a circle handle with the given CSS color.<br>\n * <br>\n * It is an inherent feature of the handle functions that the drawn elements are not scaled and not\n * distorted. So even if the user zooms in or changes the aspect ratio, the handles will be drawn\n * as even shaped circles.\n *\n * @method circleHandle\n * @param {XYCoords} center - The center of the circle.\n * @param {number} radius - The radius of the circle.\n * @param {string} color - The CSS color to draw the circle with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.circleHandle = function (center, radius, color) {\n radius = radius || 3;\n this.ctx.setLineDash([]); // Clear line-dash settings\n this.ctx.beginPath();\n this.ctx.arc(this.offset.x + center.x * this.scale.x, this.offset.y + center.y * this.scale.y, radius, 0, 2 * Math.PI, false);\n this.ctx.closePath();\n this.ctx.lineWidth = 1;\n this._fillOrDraw(color);\n };\n /**\n * Draw a crosshair with given radius and color at the given position.<br>\n * <br>\n * Note that the crosshair radius will not be affected by scaling.\n *\n * @method crosshair\n * @param {XYCoords} center - The center of the crosshair.\n * @param {number} radius - The radius of the crosshair.\n * @param {string} color - The CSS color to draw the crosshair with.\n * @param {number=0.5} lineWidth - (optional, default=0.5) The line width to use.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.crosshair = function (center, radius, color, lineWidth) {\n this.ctx.save();\n this.ctx.setLineDash([]); // Clear line-dash settings\n this.ctx.beginPath();\n this.ctx.moveTo(this.offset.x + center.x * this.scale.x - radius, this.offset.y + center.y * this.scale.y);\n this.ctx.lineTo(this.offset.x + center.x * this.scale.x + radius, this.offset.y + center.y * this.scale.y);\n this.ctx.moveTo(this.offset.x + center.x * this.scale.x, this.offset.y + center.y * this.scale.y - radius);\n this.ctx.lineTo(this.offset.x + center.x * this.scale.x, this.offset.y + center.y * this.scale.y + radius);\n this.ctx.strokeStyle = color;\n this.ctx.lineWidth = lineWidth || 0.5;\n this.ctx.stroke();\n this.ctx.closePath();\n this.ctx.restore();\n };\n /**\n * Draw a cross with diagonal axes with given radius, color and lineWidth at the given position.<br>\n * <br>\n * Note that the x's radius will not be affected by scaling.\n *\n * @method crosshair\n * @param {XYCoords} center - The center of the crosshair.\n * @param {number} radius - The radius of the crosshair.\n * @param {string} color - The CSS color to draw the crosshair with.\n * @param {number=1} lineWidth - (optional, default=1.0) The line width to use.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.cross = function (center, radius, color, lineWidth) {\n this.ctx.save();\n this.ctx.setLineDash([]); // Clear line-dash settings\n this.ctx.beginPath();\n this.ctx.moveTo(this.offset.x + center.x * this.scale.x - radius, this.offset.y + center.y * this.scale.y - radius);\n this.ctx.lineTo(this.offset.x + center.x * this.scale.x + radius, this.offset.y + center.y * this.scale.y + radius);\n this.ctx.moveTo(this.offset.x + center.x * this.scale.x - radius, this.offset.y + center.y * this.scale.y + radius);\n this.ctx.lineTo(this.offset.x + center.x * this.scale.x + radius, this.offset.y + center.y * this.scale.y - radius);\n this.ctx.strokeStyle = color;\n this.ctx.lineWidth = lineWidth || 1.0;\n this.ctx.stroke();\n this.ctx.closePath();\n this.ctx.restore();\n };\n /**\n * Draw a polygon.\n *\n * @method polygon\n * @param {Polygon} polygon - The polygon to draw.\n * @param {string} color - The CSS color to draw the polygon with.\n * @param {string} lineWidth - The line width to use.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.polygon = function (polygon, color, lineWidth, strokeOptions) {\n this.polyline(polygon.vertices, polygon.isOpen, color, lineWidth, strokeOptions);\n };\n /**\n * Draw a polygon line (alternative function to the polygon).\n *\n * @method polyline\n * @param {XYCoords[]} vertices - The polygon vertices to draw.\n * @param {boolan} isOpen - If true the polyline will not be closed at its end.\n * @param {string} color - The CSS color to draw the polygon with.\n * @param {number} lineWidth - The line width (default is 1.0);\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.polyline = function (vertices, isOpen, color, lineWidth, strokeOptions) {\n if (vertices.length <= 1) {\n return;\n }\n this.ctx.save();\n this.applyStrokeOpts(strokeOptions);\n this.ctx.beginPath();\n this.ctx.lineWidth = lineWidth || 1.0;\n this.ctx.moveTo(this.offset.x + vertices[0].x * this.scale.x, this.offset.y + vertices[0].y * this.scale.y);\n for (var i = 0; i < vertices.length; i++) {\n this.ctx.lineTo(this.offset.x + vertices[i].x * this.scale.x, this.offset.y + vertices[i].y * this.scale.y);\n }\n if (!isOpen)\n // && vertices.length > 2 )\n this.ctx.closePath();\n this._fillOrDraw(color);\n this.ctx.closePath();\n this.ctx.setLineDash([]);\n this.ctx.restore();\n };\n /**\n * Draw a text at the given relative position.\n *\n * @method text\n * @param {string} text - The text to draw.\n * @param {number} x - The x-position to draw the text at.\n * @param {number} y - The y-position to draw the text at.\n * @param {string=} options.color - The Color to use.\n * @param {string=} options.fontFamily - The font family to use.\n * @param {number=} options.fontSize - The font size (in pixels) to use.\n * @param {FontStyle=} options.fontStyle - The font style to use.\n * @param {FontWeight=} options.fontWeight - The font weight to use.\n * @param {number=} options.lineHeight - The line height (in pixels) to use.\n * @param {number=} options.rotation - The (optional) rotation in radians.\n * @param {string=} options.textAlign - The text align to use. According to the specifiactions (https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign) valid values are `\"left\" || \"right\" || \"center\" || \"start\" || \"end\"`.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.text = function (text, x, y, options) {\n // See https://stackoverflow.com/a/23523697\n var _a, _b, _c;\n options = options || {};\n this.ctx.save();\n var relX = this.offset.x + x * this.scale.x;\n var relY = this.offset.y + y * this.scale.y;\n var color = options.color || \"black\";\n if (options.fontSize || options.fontFamily) {\n // Scaling of text only works in uniform mode\n this.ctx.font =\n (options.fontWeight ? options.fontWeight + \" \" : \"\") +\n (options.fontStyle ? options.fontStyle + \" \" : \"\") +\n (options.fontSize ? options.fontSize * this.scale.x + \"px \" : \" \") +\n (options.fontFamily\n ? options.fontFamily.indexOf(\" \") === -1\n ? options.fontFamily\n : \"\\\"\".concat(options.fontFamily, \"\\\"\")\n : \"Arial\");\n }\n if (options.textAlign) {\n this.ctx.textAlign = options.textAlign;\n }\n var rotation = (_a = options.rotation) !== null && _a !== void 0 ? _a : 0.0;\n var lineHeight = ((_c = (_b = options.lineHeight) !== null && _b !== void 0 ? _b : options.fontSize) !== null && _c !== void 0 ? _c : 0) * this.scale.x;\n this.ctx.translate(relX, relY);\n this.ctx.rotate(rotation);\n if (this.fillShapes) {\n this.ctx.fillStyle = color;\n this.ctx.fillText(text, 0, lineHeight / 2);\n }\n else {\n this.ctx.strokeStyle = color;\n this.ctx.strokeText(text, 0, lineHeight / 2);\n }\n // this.ctx.translate(-relX, -relY);\n // this.ctx.rotate(-rotation); // is this necessary before 'restore()'?\n this.ctx.restore();\n };\n /**\n * Draw a non-scaling text label at the given position.\n *\n * Note that these are absolute label positions, they are not affected by offset or scale.\n *\n * @method label\n * @param {string} text - The text to draw.\n * @param {number} x - The x-position to draw the text at.\n * @param {number} y - The y-position to draw the text at.\n * @param {number=} rotation - The (optional) rotation in radians (default=0).\n * @param {string=} color - The color to render the text with (default=black).\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutils.prototype.label = function (text, x, y, rotation, color) {\n this.ctx.save();\n this.ctx.font = \"lighter 9pt Arial\";\n this.ctx.translate(x, y);\n if (typeof rotation !== \"undefined\")\n this.ctx.rotate(rotation);\n this.ctx.fillStyle = color || \"black\";\n if (this.fillShapes) {\n this.ctx.fillText(text, 0, 0);\n }\n else {\n this.ctx.strokeText(text, 0, 0);\n }\n this.ctx.restore();\n };\n /**\n * Draw an SVG-like path given by the specified path data.\n *\n *\n * @method path\n * @param {SVGPathData} pathData - An array of path commands and params.\n * @param {string=null} color - (optional) The color to draw this path with (default is null).\n * @param {number=1} lineWidth - (optional) the line width to use (default is 1).\n * @param {boolean=false} options.inplace - (optional) If set to true then path transforamtions (scale and translate) will be done in-place in the array. This can boost the performance.\n * @param {number=} options.dashOffset - (optional) `See StrokeOptions`.\n * @param {number=[]} options.dashArray - (optional) `See StrokeOptions`.\n * @instance\n * @memberof drawutils\n * @return {R} An instance representing the drawn path.\n */\n drawutils.prototype.path = function (pathData, color, lineWidth, options) {\n var d = options && options.inplace ? pathData : drawutilssvg_1.drawutilssvg.copyPathData(pathData);\n drawutilssvg_1.drawutilssvg.transformPathData(d, this.offset, this.scale);\n if (color) {\n this.ctx.strokeStyle = color;\n }\n this.ctx.lineWidth = lineWidth || 1;\n this.applyStrokeOpts(options);\n if (this.fillShapes) {\n if (color) {\n this.ctx.fillStyle = color;\n }\n this.ctx.fill(new Path2D(d.join(\" \")));\n }\n else {\n if (color) {\n this.ctx.strokeStyle = color;\n }\n this.ctx.stroke(new Path2D(d.join(\" \")));\n }\n };\n /**\n * Due to gl compatibility there is a generic 'clear' function required\n * to avoid accessing the context object itself directly.\n *\n * This function just fills the whole canvas with a single color.\n *\n * @param {string} color - The color to clear with.\n **/\n drawutils.prototype.clear = function (color) {\n this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);\n this.ctx.fillStyle = color;\n this.ctx.fillRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);\n };\n drawutils.helpers = {\n // A helper function to define the clipping path.\n // This could be a candidate for the draw library.\n clipPoly: function (ctx, offset, scale, vertices) {\n ctx.beginPath();\n // Set clip mask\n ctx.moveTo(offset.x + vertices[0].x * scale.x, offset.y + vertices[0].y * scale.y);\n for (var i = 1; i < vertices.length; i++) {\n var vert = vertices[i];\n ctx.lineTo(offset.x + vert.x * scale.x, offset.y + vert.y * scale.y);\n }\n ctx.closePath();\n ctx.clip();\n }\n };\n return drawutils;\n}());\nexports.drawutils = drawutils;\n//# sourceMappingURL=draw.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2020-05-11\n * @modified 2020-10-30 Added the static computeFromVertices function.\n * @modified 2020-11-19 Set min, max, width and height to private.\n * @modified 2021-02-02 Added the `toPolygon` method.\n * @modified 2021-06-21 (mid-summer) Added `getCenter` method.\n * @modified 2022-02-01 Added the `toString` function.\n * @modified 2022-10-09 Added the `fromDimension` function.\n * @modified 2022-11-28 Added the `clone` method.\n * @modified 2023-09-29 Added the `randomPoint` method.\n * @modified 2025-03-23 Added the `getMinDimension` and `getMaxDimension` methods.\n * @modified 2025-04-18 Change parameter type in `Bounds.computeFromVertices` from `Vertex` to more general `XYCoords`.\n * @modified 2025-04-19 Added methods to `Bounds` class: `getNorthPoint`, `getSouthPoint`, `getEastPoint` and `getWestPoint`.\n * @modified 2025-04-26 Added static method `Bounds.computeFromBoundsSet` to calculate containing bounds for a set of bounding boxes.\n * @modified 2025-10-17 Added the methods `Bounds.getSouthWestPoint`, `getNorthWestPoint`, `getNorthEastPoint` and `getSouthEastPoint`.\n * @modified 2025-10-18 Added method `Bounds.containsVert(XYCoords)`.\n * @modified 2025-10-28 Added the `Bounds.getWidth()` and `Bounds.getHeight()`.\n * @modified 2025-11-12 Added the `Bounds.getMoved()` method.\n * @version 1.11.0\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Bounds = void 0;\nvar Polygon_1 = require(\"./Polygon\");\nvar Vertex_1 = require(\"./Vertex\");\n/**\n * @classdesc A bounds class with min and max values. Implementing IBounds.\n *\n * @requires XYCoords\n * @requires Vertex\n * @requires IBounds\n **/\nvar Bounds = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name Bounds\n * @param {XYCoords} min - The min values (x,y) as a XYCoords tuple.\n * @param {XYCoords} max - The max values (x,y) as a XYCoords tuple.\n **/\n function Bounds(min, max) {\n this.min = min;\n this.max = max;\n this.width = max.x - min.x;\n this.height = max.y - min.y;\n }\n /**\n * Check if the given vertex is inside this bounds.\n *\n * @method containsVert\n * @param {XYCoords} vert - The vertex to check.\n * @return {boolean} True if the passed vertex is inside this bounds.\n * @instance\n * @memberof Bounds\n **/\n Bounds.prototype.containsVert = function (vert) {\n return this.min.x <= vert.x && vert.x < this.max.x && this.min.y <= vert.y && vert.y < this.max.y;\n };\n Bounds.prototype.getWidth = function () {\n return this.max.x - this.min.x;\n };\n Bounds.prototype.getHeight = function () {\n return this.max.y - this.min.y;\n };\n Bounds.prototype.getScaled = function (scaleFactor) {\n var center = this.getCenter();\n var newMin = new Vertex_1.Vertex(this.min).scale(scaleFactor, center);\n var newMax = new Vertex_1.Vertex(this.max).scale(scaleFactor, center);\n return new Bounds(newMin, newMax);\n };\n Bounds.prototype.getMoved = function (moveAmount) {\n var newMin = new Vertex_1.Vertex(this.min).move(moveAmount);\n var newMax = new Vertex_1.Vertex(this.max).move(moveAmount);\n return new Bounds(newMin, newMax);\n };\n /**\n * Get the center point of the north bound.\n *\n * @method getNorthPoint\n * @instance\n * @memberof Bounds\n * @return {Vertex} The \"northmost\" centered point of this bounding box.\n */\n Bounds.prototype.getNorthPoint = function () {\n return new Vertex_1.Vertex(this.min.x + this.width / 2.0, this.min.y);\n };\n /**\n * Get the center point of the south bound.\n *\n * @method getNorthPoint\n * @instance\n * @memberof Bounds\n * @return {Vertex} The \"southhmost\" centered point of this bounding box.\n */\n Bounds.prototype.getSouthPoint = function () {\n return new Vertex_1.Vertex(this.min.x + this.width / 2.0, this.max.y);\n };\n /**\n * Get the center point of the west bound.\n *\n * @method getWestPoint\n * @instance\n * @memberof Bounds\n * @return {Vertex} The \"westhmost\" centered point of this bounding box.\n */\n Bounds.prototype.getWestPoint = function () {\n return new Vertex_1.Vertex(this.min.x, this.min.y + this.height / 2.0);\n };\n /**\n * Get the center point of the east bound.\n *\n * @method getEastPoint\n * @instance\n * @memberof Bounds\n * @return {Vertex} The \"easthmost\" centered point of this bounding box.\n */\n Bounds.prototype.getEastPoint = function () {\n return new Vertex_1.Vertex(this.max.x, this.min.y + this.height / 2.0);\n };\n /**\n * Get the upper left corner point these bounds box.\n *\n * @method getNorthWestPoint\n * @instance\n * @memberof Bounds\n * @return {Vertex} The \"northwestmost\" point of this bounding box.\n */\n Bounds.prototype.getNorthWestPoint = function () {\n return new Vertex_1.Vertex(this.min.x, this.min.y);\n };\n /**\n * Get the upper right corner point these bounds box.\n *\n * @method getNorthEastPoint\n * @instance\n * @memberof Bounds\n * @return {Vertex} The \"northeastmost\" point of this bounding box.\n */\n Bounds.prototype.getNorthEastPoint = function () {\n return new Vertex_1.Vertex(this.max.x, this.min.y);\n };\n /**\n * Get the lower right corner point these bounds box.\n *\n * @method getSouthEastPoint\n * @instance\n * @memberof Bounds\n * @return {Vertex} The \"southeastmost\" point of this bounding box.\n */\n Bounds.prototype.getSouthEastPoint = function () {\n return new Vertex_1.Vertex(this.max.x, this.max.y);\n };\n /**\n * Get the lower left corner point these bounds box.\n *\n * @method getSouthWestPoint\n * @instance\n * @memberof Bounds\n * @return {Vertex} The \"southwestmost\" point of this bounding box.\n */\n Bounds.prototype.getSouthWestPoint = function () {\n return new Vertex_1.Vertex(this.min.x, this.max.y);\n };\n /**\n * Convert this rectangular bounding box to a polygon with four vertices.\n *\n * @method toPolygon\n * @instance\n * @memberof Bounds\n * @return {Polygon} This bound rectangle as a polygon.\n */\n Bounds.prototype.toPolygon = function () {\n return new Polygon_1.Polygon([new Vertex_1.Vertex(this.min), new Vertex_1.Vertex(this.max.x, this.min.y), new Vertex_1.Vertex(this.max), new Vertex_1.Vertex(this.min.x, this.max.y)], false);\n };\n /**\n * Get the center of this boinding box.\n *\n * @method getCenter\n * @instance\n * @memberof Bounds\n * @returns {Vertex} The center of these bounds.\n */\n Bounds.prototype.getCenter = function () {\n return new Vertex_1.Vertex(this.min.x + (this.max.x - this.min.x) / 2.0, this.min.y + (this.max.y - this.min.y) / 2);\n };\n /**\n * Get the minimum of `width` and `height`.\n *\n * @returns {number} The value of Math.min( this.width, this.height )\n */\n Bounds.prototype.getMinDimension = function () {\n return Math.min(this.width, this.height);\n };\n /**\n * Get the minimum of `width` and `height`.\n *\n * @returns {number} The value of Math.min( this.width, this.height )\n */\n Bounds.prototype.getMaxDimension = function () {\n return Math.max(this.width, this.height);\n };\n /**\n * Generate a random point inside this bounds object. Safe areas at the border to avoid\n * included.\n *\n * @method randomPoint\n * @instance\n * @memberof Bounds\n * @param {horizontalSafeArea} - (optional) The horizonal (left and right) safe area. No vertex will be created here. Can be used as percent in (0.0 ... 0.1) interval.\n * @param {verticalSafeArea} - (optional) The vertical (top and bottom) safe area. No vertex will be created here. Can be used as percent in (0.0 ... 0.1) interval\n * @returns {Vertex} A pseudo random point inside these bounds.\n */\n Bounds.prototype.randomPoint = function (horizontalSafeArea, verticalSafeArea) {\n if (horizontalSafeArea === void 0) { horizontalSafeArea = 0; }\n if (verticalSafeArea === void 0) { verticalSafeArea = 0; }\n // Check if the safe areas are meant as percent\n var absHorizontalSafeArea = horizontalSafeArea > 0 && horizontalSafeArea < 1 ? this.width * horizontalSafeArea : horizontalSafeArea;\n var absVerticalSafeArea = verticalSafeArea > 0 && verticalSafeArea < 1 ? this.height * verticalSafeArea : verticalSafeArea;\n return new Vertex_1.Vertex(this.min.x + absHorizontalSafeArea + Math.random() * (this.width - 2 * absHorizontalSafeArea), this.min.y + absVerticalSafeArea + Math.random() * (this.height - 2 * absVerticalSafeArea));\n };\n /**\n * Convert these bounds to a human readable form.\n *\n * Note: the returned format might change in the future, so please do not\n * rely on the returned string format.\n *\n * @method toString\n * @instance\n * @memberof Bounds\n * @returns {string} Get these bounds in a human readable form.\n */\n Bounds.prototype.toString = function () {\n return \"{ min: \".concat(this.min.toString(), \", max : \").concat(this.max.toString(), \", width: \").concat(this.width, \", height : \").concat(this.height, \" }\");\n };\n /**\n * Clone this bounds object (create a deep clone).\n *\n * @method clone\n * @instance\n * @memberof Bounds\n * @returns {Bounds} Creates a deep clone of this bounds object.\n */\n Bounds.prototype.clone = function () {\n return new Bounds({ x: this.min.x, y: this.min.y }, { x: this.max.x, y: this.max.y });\n };\n /**\n * Compute the minimal bounding box for a given set of vertices.\n *\n * An empty vertex array will return an empty bounding box located at (0,0).\n *\n * @static\n * @method computeFromVertices\n * @memberof Bounds\n * @param {Array<XYCoords>} vertices - The set of vertices you want to get the bounding box for.\n * @return The minimal Bounds for the given vertices.\n **/\n Bounds.computeFromVertices = function (vertices) {\n if (vertices.length == 0) {\n return new Bounds(new Vertex_1.Vertex(0, 0), new Vertex_1.Vertex(0, 0));\n }\n var xMin = vertices[0].x;\n var xMax = vertices[0].x;\n var yMin = vertices[0].y;\n var yMax = vertices[0].y;\n var vert;\n for (var i in vertices) {\n vert = vertices[i];\n xMin = Math.min(xMin, vert.x);\n xMax = Math.max(xMax, vert.x);\n yMin = Math.min(yMin, vert.y);\n yMax = Math.max(yMax, vert.y);\n }\n return new Bounds(new Vertex_1.Vertex(xMin, yMin), new Vertex_1.Vertex(xMax, yMax));\n };\n /**\n * Compute the minimal bounding box for a given set of existing bounding boxes.\n *\n * An empty vertex array will return an empty bounding box located at (0,0).\n *\n * @static\n * @method computeFromBoundsSet\n * @memberof Bounds\n * @param {Array<IBounds>} boundingBoxes - The set of existing bounding boxes to get the containing bounding box for.\n * @return The minimal Bounds for the given bounds instances.\n **/\n Bounds.computeFromBoundsSet = function (boundingBoxes) {\n if (boundingBoxes.length == 0) {\n return new Bounds(new Vertex_1.Vertex(0, 0), new Vertex_1.Vertex(0, 0));\n }\n var xMin = boundingBoxes[0].min.x;\n var xMax = boundingBoxes[0].max.x;\n var yMin = boundingBoxes[0].min.y;\n var yMax = boundingBoxes[0].min.y;\n var bounds;\n for (var i in boundingBoxes) {\n bounds = boundingBoxes[i];\n xMin = Math.min(xMin, bounds.min.x);\n xMax = Math.max(xMax, bounds.max.x);\n yMin = Math.min(yMin, bounds.min.y);\n yMax = Math.max(yMax, bounds.min.y);\n }\n return new Bounds(new Vertex_1.Vertex(xMin, yMin), new Vertex_1.Vertex(xMax, yMax));\n };\n /**\n * Create a new `Bounds` instance just from `width` and `height`, located at (0,0) or the optionally given origin.\n *\n * @param {number} width - The width of the bounds\n * @param {number} height - The height of the bounds\n * @param {XYCoords={x:0,y:0}} origin - [optional] A origin to locate the new Bounds object at.\n * @returns {Bounds} A new `Bounds` instance width given width and height, located at (0,0) or the given origin..\n */\n Bounds.fromDimension = function (width, height, origin) {\n return new Bounds(origin !== null && origin !== void 0 ? origin : { x: 0, y: 0 }, { x: (origin ? origin.x : 0) + width, y: (origin ? origin.y : 0) + height });\n };\n return Bounds;\n}()); // END class bounds\nexports.Bounds = Bounds;\n//# sourceMappingURL=Bounds.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2020-05-04\n * @modified 2020-05-09 Ported to typescript.\n * @modified 2020-05-25 Added the vertAt and tangentAt functions.\n * @mofidied 2020-09-07 Added the circleIntersection(Circle) function.\n * @modified 2020-09-07 Changed the vertAt function by switching sin and cos! The old version did not return the correct vertex (by angle) accoring to the assumed circle math.\n * @modified 2020-10-16 Added the containsCircle(...) function.\n * @modified 2021-01-20 Added UID.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-02-02 Cleared the `toSVGString` function (deprecated). Use `drawutilssvg` instead.\n * @modified 2022-08-15 Added the `containsPoint` function.\n * @modified 2022-08-23 Added the `lineIntersection` function.\n * @modified 2022-08-23 Added the `closestPoint` function.\n * @modified 2025-04-09 Added the `Circle.move(amount: XYCoords)` method.\n * @modified 2025-04-16 Class `Circle` now implements interface `Intersectable`.\n * @modified 2026-06-10 Adding the utility function `Circle.circleUtils.containsPoint`.\n * @modified 2026-06-10 Adding the `Circle.clone` method.\n * @modified 2026-01-13 Adding helper function `Circle.circleUtils.containsPoint` and refactored the member method `containsPoint`.\n * @modified 2026-07-03 Adding the optional `epsilon` parameter to the `Circle.containsCircle` method.\n * @modified 2026-07-03 Fixing the `Circle.clone` method; the center had not been cloned at all, this was fixed.\n * @modified 2026-07-08 Adding the `Circle.setRadius` method (for chaining).\n * @mofified 2026-07-31 Adding the `radicalAxis(Circle)` method. Added the `Circle.circleUtils.createRadicalAxisHelperCircle` and `.circleDistance` helper methods.\n * @modified 2026-08-03 Adding `Circle.tangentsFromPoint`.\n * @modified 2026-08-16 Adding the `Circle.sectorAngleByArcLength` method and the `Circle.circleUtils.sectorAngleByArcLength` helper method.\n * @version 1.8.0\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Circle = void 0;\nvar Bounds_1 = require(\"./Bounds\");\nvar Line_1 = require(\"./Line\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar Vector_1 = require(\"./Vector\");\nvar Vertex_1 = require(\"./Vertex\");\nvar geomutils_1 = require(\"./geomutils\");\n/**\n * @classdesc A simple circle: center point and radius.\n *\n * @requires Line\n * @requires Vector\n * @requires VertTuple\n * @requires Vertex\n * @requires SVGSerializale\n * @requires UID\n * @requires UIDGenerator\n **/\nvar Circle = /** @class */ (function () {\n /**\n * Create a new circle with given center point and radius.\n *\n * @constructor\n * @name Circle\n * @param {Vertex} center - The center point of the circle.\n * @param {number} radius - The radius of the circle.\n */\n function Circle(center, radius) {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"Circle\";\n this.uid = UIDGenerator_1.UIDGenerator.next();\n this.center = center;\n this.radius = radius;\n }\n /**\n * Set the radius of this circle.\n * The method is meant for chaining, you may also alter the `radius` attribute directly.\n *\n * @method setRadius\n * @param {number} radius - The amount to move.\n * @instance\n * @memberof Circle\n * @return {Circle} this for chaining\n **/\n Circle.prototype.setRadius = function (radius) {\n this.radius = radius;\n return this;\n };\n /**\n * Move the circle by the given amount.\n *\n * @method move\n * @param {XYCoords} amount - The amount to move.\n * @instance\n * @memberof Circle\n * @return {Circle} this for chaining\n **/\n Circle.prototype.move = function (amount) {\n this.center.add(amount);\n return this;\n };\n /**\n * Check if the given circle is fully contained inside this circle.\n *\n * @method containsPoint\n * @param {XYCoords} point - The point to check if it is contained in this circle.\n * @instance\n * @memberof Circle\n * @return {boolean} `true` if the given point is inside this circle.\n */\n Circle.prototype.containsPoint = function (point) {\n // return this.center.distance(point) < this.radius;//\n return Circle.circleUtils.containsPoint(this.center, this.radius, point);\n };\n /**\n * Check if the given circle is fully contained inside this circle.\n *\n * @method containsCircle\n * @param {Circle} circle - The circle to check if it is contained in this circle.\n * @instance\n * @memberof Circle\n * @return {boolean} `true` if any only if the given circle is completely inside this circle.\n */\n Circle.prototype.containsCircle = function (circle, epsilon) {\n if (typeof epsilon === \"undefined\" || Number.isNaN(epsilon)) {\n return this.center.distance(circle.center) + circle.radius < this.radius;\n }\n else {\n return this.center.distance(circle.center) + circle.radius < this.radius + Math.abs(epsilon);\n }\n };\n /**\n * Calculate the distance from this circle to the given line.\n *\n * * If the line does not intersect this ciecle then the returned\n * value will be the minimal distance.\n * * If the line goes through this circle then the returned value\n * will be max inner distance and it will be negative.\n *\n * @method lineDistance\n * @param {Line} line - The line to measure the distance to.\n * @return {number} The minimal distance from the outline of this circle to the given line.\n * @instance\n * @memberof Circle\n */\n Circle.prototype.lineDistance = function (line) {\n var closestPointOnLine = line.getClosestPoint(this.center);\n return closestPointOnLine.distance(this.center) - this.radius;\n };\n /**\n * Get the vertex on the this circle for the given angle.\n *\n * @method vertAt\n * @param {number} angle - The angle (in radians) to use.\n * @return {Vertex} The vertex (point) at the given angle.\n * @instance\n * @memberof Circle\n **/\n Circle.prototype.vertAt = function (angle) {\n // Find the point on the circle respective the angle. Then move relative to center.\n return Circle.circleUtils.vertAt(angle, this.radius).add(this.center);\n };\n /**\n * Get a tangent line of this circle for a given angle.\n *\n * Point a of the returned line is located on the circle, the length equals the radius.\n *\n * @method tangentAt\n * @instance\n * @param {number} angle - The angle (in radians) to use.\n * @return {Line} The tangent line.\n * @memberof Circle\n **/\n Circle.prototype.tangentAt = function (angle) {\n var pointA = Circle.circleUtils.vertAt(angle, this.radius);\n // Construct the perpendicular of the line in point a. Then move relative to center.\n return new Vector_1.Vector(pointA, new Vertex_1.Vertex(0, 0)).add(this.center).perp();\n // return (new Vector(this.center.clone(), pointA).add(pointA) as Vector).perp() as Vector;\n };\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get the bounding box (bounds) of this Circle.\n *\n * @method getBounds\n * @instance\n * @memberof Circle\n * @return {Bounds} The rectangular bounds of this Circle.\n **/\n Circle.prototype.getBounds = function () {\n return new Bounds_1.Bounds(this.center.clone().subXY(Math.abs(this.radius), Math.abs(this.radius)), this.center.clone().addXY(Math.abs(this.radius), Math.abs(this.radius)));\n };\n //--- END --- Implement interface `Intersectable`\n /**\n * Calculate the intersection points (if exists) with the given circle.\n *\n * @method circleIntersection\n * @instance\n * @memberof Circle\n * @param {Circle} circle\n * @return {Line|null} The intersection points (as a line) or null if the two circles do not intersect.\n **/\n Circle.prototype.circleIntersection = function (circle) {\n // Circles do not intersect at all?\n if (this.center.distance(circle.center) > this.radius + circle.radius) {\n return null;\n }\n // One circle is fully inside the other?\n if (this.center.distance(circle.center) < Math.abs(this.radius - circle.radius)) {\n return null;\n }\n // Based on the C++ implementation by Robert King\n // https://stackoverflow.com/questions/3349125/circle-circle-intersection-points\n // and the 'Circles and spheres' article by Paul Bourke.\n // http://paulbourke.net/geometry/circlesphere/\n //\n // This is the original C++ implementation:\n //\n // pair<Point, Point> intersections(Circle c) {\n // Point P0(x, y);\n // Point P1(c.x, c.y);\n // float d, a, h;\n // d = P0.distance(P1);\n // a = (r*r - c.r*c.r + d*d)/(2*d);\n // h = sqrt(r*r - a*a);\n // Point P2 = P1.sub(P0).scale(a/d).add(P0);\n // float x3, y3, x4, y4;\n // x3 = P2.x + h*(P1.y - P0.y)/d;\n // y3 = P2.y - h*(P1.x - P0.x)/d;\n // x4 = P2.x - h*(P1.y - P0.y)/d;\n // y4 = P2.y + h*(P1.x - P0.x)/d;\n // return pair<Point, Point>(Point(x3, y3), Point(x4, y4));\n // }\n var p0 = this.center;\n var p1 = circle.center;\n var d = p0.distance(p1);\n var a = (this.radius * this.radius - circle.radius * circle.radius + d * d) / (2 * d);\n var h = Math.sqrt(this.radius * this.radius - a * a);\n var p2 = p1.clone().scale(a / d, p0);\n var x3 = p2.x + (h * (p1.y - p0.y)) / d;\n var y3 = p2.y - (h * (p1.x - p0.x)) / d;\n var x4 = p2.x - (h * (p1.y - p0.y)) / d;\n var y4 = p2.y + (h * (p1.x - p0.x)) / d;\n return new Line_1.Line(new Vertex_1.Vertex(x3, y3), new Vertex_1.Vertex(x4, y4));\n };\n /**\n * Calculate the intersection points (if exists) with the given infinite line (defined by two points).\n *\n * @method lineIntersection\n * @instance\n * @memberof Circle\n * @param {Vertex} a- The first of the two points defining the line.\n * @param {XYCoords} b - The second of the two points defining the line.\n * @return {Line|null} The intersection points (as a line) or null if this circle does not intersect the line given.\n **/\n Circle.prototype.lineIntersection = function (a, b) {\n // Based on the math from\n // https://mathworld.wolfram.com/Circle-LineIntersection.html\n var interA = new Vertex_1.Vertex();\n var interB = new Vertex_1.Vertex();\n // First do a transformation, because the calculation is based on a cicle at (0,0)\n var transA = new Vertex_1.Vertex(a).sub(this.center);\n var transB = new Vertex_1.Vertex(b).sub(this.center);\n var diff = transA.difference(transB);\n // There is a special case if diff.y=0, where the intersection is not calcuatable.\n // Use an non-zero epsilon here to approximate this case.\n // TODO for the future: find a better solution\n if (Math.abs(diff.y) === 0) {\n diff.y = 0.000001;\n }\n var dist = transA.distance(transB);\n var det = transA.x * transB.y - transA.y * transB.x;\n var distSquared = dist * dist;\n var radiusSquared = this.radius * this.radius;\n // Check if circle and line have an intersection at all\n if (radiusSquared * distSquared - det * det < 0) {\n return null;\n }\n var belowSqrt = this.radius * this.radius * dist * dist - det * det;\n var sqrt = Math.sqrt(belowSqrt);\n interA.x = (det * diff.y + Math.sign(diff.y) * diff.x * sqrt) / distSquared;\n interB.x = (det * diff.y - Math.sign(diff.y) * diff.x * sqrt) / distSquared;\n interA.y = (-det * diff.x + Math.abs(diff.y) * sqrt) / distSquared;\n interB.y = (-det * diff.x - Math.abs(diff.y) * sqrt) / distSquared;\n return new Line_1.Line(interA.add(this.center), interB.add(this.center));\n };\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get all line intersections with this circle.\n *\n * This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.\n *\n * @param {VertTuple} line - The line to find intersections with.\n * @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).\n * @returns {Array<Vertex>} - An array of all intersections with the circle outline.\n */\n Circle.prototype.lineIntersections = function (line, inVectorBoundsOnly) {\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersections of all lines inside the edge bounds\n var intersectioLine = this.lineIntersection(line.a, line.b);\n if (!intersectioLine) {\n return [];\n }\n if (inVectorBoundsOnly) {\n // const maxDist = line.length();\n return [intersectioLine.a, intersectioLine.b].filter(function (vert) { return line.hasPoint(vert, true); });\n }\n else {\n return [intersectioLine.a, intersectioLine.b];\n }\n };\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @param line\n * @param lineIntersectionTangents\n * @returns\n */\n Circle.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersections of all lines plus their tangents inside the circle bounds\n var interSectionPoints = this.lineIntersections(line, inVectorBoundsOnly);\n return interSectionPoints.map(function (vert) {\n // Calculate angle\n var lineFromCenter = new Line_1.Line(_this.center, vert);\n var angle = lineFromCenter.angle();\n // console.log(\"angle\", (angle / Math.PI) * 180.0);\n // const angle = Math.random() * Math.PI * 2; // TODO\n // Calculate tangent at angle\n return _this.tangentAt(angle);\n });\n };\n //--- END --- Implement interface `Intersectable`\n /**\n * Calculate the radical axis of this and a different circle.\n * The two circles must not be co-centric.\n *\n * See this article for details:\n * https://www.cut-the-knot.org/Curriculum/Geometry/GeoGebra/RadicalAxes.shtml\n *\n * @method radicalAxis\n * @instance\n * @memberof Circle\n * @param {Circle} circleB - The second circle to calculated the radical axis for.\n * @return {Line} A line defining the radical axis of the two circles.\n **/\n Circle.prototype.radicalAxis = function (circleB) {\n var helperCircle = Circle.circleUtils.createRadicalAxisHelperCircle(this, circleB);\n var intersectionLineA = this.circleIntersection(helperCircle);\n var intersectionLineB = circleB.circleIntersection(helperCircle);\n var intersection = this.circleIntersection(circleB);\n if (!intersectionLineA || !intersectionLineB) {\n console.error(\"Critical error: none of the two intersections must be null.\");\n return intersection; // Fallback\n }\n var lineA = new Line_1.Line(intersectionLineA.a, intersectionLineA.b);\n var lineB = new Line_1.Line(intersectionLineB.a, intersectionLineB.b);\n var firstRadicalAxisPoint = lineA.intersection(lineB);\n var centerConnectLine = new Line_1.Line(this.center, circleB.center);\n var secondRadicalAxisPoint = centerConnectLine.getClosestPoint(firstRadicalAxisPoint);\n // Create a mirrored version of the second radical axis point so both are located\n // symmetrical from the circle connect point.\n // (currently the second point is located ON the connect line)\n var secondRadicalAxisPoint_mirrored = secondRadicalAxisPoint.clone().scale(2.0, firstRadicalAxisPoint);\n var radicalAxis = new Line_1.Line(firstRadicalAxisPoint, secondRadicalAxisPoint_mirrored);\n return intersection && intersection.length() > radicalAxis.length() ? intersection : radicalAxis;\n };\n /**\n * Calculate the closest point on the outline of this circle to the given point.\n *\n * @method closestPoint\n * @instance\n * @memberof Circle\n * @param {XYCoords} vert - The point to find the closest circle point for.\n * @return {Vertex} The closest point on this circle.\n **/\n Circle.prototype.closestPoint = function (vert) {\n var lineIntersection = this.lineIntersection(this.center, vert);\n if (!lineIntersection) {\n // Note: this case should not happen as a radial from the center always intersect this circle.\n return new Vertex_1.Vertex();\n }\n // Return closed of both\n if (lineIntersection.a.distance(vert) < lineIntersection.b.distance(vert)) {\n return lineIntersection.a;\n }\n else {\n return lineIntersection.b;\n }\n };\n /**\n * Get the two tangent vectors for the given point.\n * If the point is on or in the circle then null is returned.\n *\n * @method tangentsFromPoint\n * @instance\n * @memberof Circle\n * @param {Vertex} vert - The point to find the two tangents for.\n * @return {[Vector,Vector]} The two tangent vector\n **/\n Circle.prototype.tangentsFromPoint = function (vert) {\n // Inspired by\n // https://www.omnicalculator.com/math/tangent-circle\n var centerDistance = this.center.distance(vert);\n var tangentLength = Math.sqrt(centerDistance * centerDistance - this.radius * this.radius);\n // console.log(\"this.radius \", this.radius, \"centerDistance\", centerDistance, \"tangentLength\", tangentLength);\n if (Number.isNaN(tangentLength)) {\n // vertex is inside circle\n console.log(\"tangentLength is NaN\", tangentLength);\n return null;\n }\n var helperCircle = new Circle(vert, tangentLength);\n var intersection = this.circleIntersection(helperCircle);\n if (!intersection) {\n // No intersection (vertex is inside circle)\n return null;\n }\n return [new Vector_1.Vector(intersection.a, vert), new Vector_1.Vector(intersection.b, vert)];\n };\n /**\n * Calculate inner sector angle for this circle and a given circle arc length.\n *\n * @param {number} sectorArcLength - The desired arc length (in units).\n * @returns The sector's inner angle (in radians).\n */\n Circle.prototype.sectorAngleByArcLength = function (sectorArcLength) {\n return Circle.circleUtils.sectorAngleByArcLength(sectorArcLength, this.radius);\n };\n /**\n * Create a deep copy of this circle.\n *\n * @method clone\n * @return {Circle} A new circle, an exact copy of this one.\n * @instance\n * @memberof Circle\n **/\n Circle.prototype.clone = function () {\n return new Circle(this.center.clone(), this.radius);\n };\n Circle.fromICircle = function (obj) {\n return new Circle(new Vertex_1.Vertex(obj.center), obj.radius);\n };\n // static fromObject(obj: object): Circle {\n // if (!obj) {\n // return null;\n // }\n // if (typeof obj !== \"object\") {\n // return null;\n // }\n // if (!obj.hasOwnProperty(\"center\") || typeof (obj as any).center != \"object\") {\n // return null;\n // }\n // if (!obj.hasOwnProperty(\"radius\") || typeof !(obj as any).radius != \"number\") {\n // return null;\n // }\n // var center = (obj as any).center;\n // if (!center.hasOwnProperty(\"x\") || typeof (center as any).x != \"number\") {\n // return null;\n // }\n // if (!center.hasOwnProperty(\"y\") || typeof (center as any).y != \"number\") {\n // return null;\n // }\n // return new Circle(new Vertex(center), (obj as any).radius);\n // }\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n Circle.prototype.destroy = function () {\n this.center.destroy();\n this.isDestroyed = true;\n };\n Circle.circleUtils = {\n vertAt: function (angle, radius) {\n /* return new Vertex( Math.sin(angle) * radius,\n Math.cos(angle) * radius ); */\n return new Vertex_1.Vertex(Math.cos(angle) * radius, Math.sin(angle) * radius);\n },\n containsPoint: function (circleCenter, circleRadius, point) {\n // TODO: cleanup\n // return (\n // (circle.center.x - point.x) * (circle.center.x - point.x) + (circle.center.y - point.y) * (circle.center.y - point.y) <=\n // circle.radius * circle.radius\n // );\n return geomutils_1.geomutils.dist4(point.x, point.y, circleCenter.x, circleCenter.y) < circleRadius;\n },\n createRadicalAxisHelperCircle: function (circleA, circleB) {\n // We need to create a helper circle that intersects BOTH other circles,\n // each in TWO points.\n var circleConnectLine = new Vector_1.Vector(circleA.center.clone(), circleB.center);\n circleConnectLine.a.set(circleConnectLine.vertAt(0.5));\n // Get the perpendicular by half the circle distance.\n var bisector = circleConnectLine.perp();\n var bisectorLength = Math.max(circleA.radius, circleB.radius, bisector.length());\n bisector.setLength(bisectorLength);\n return new Circle(bisector.b, bisector.b.distance(circleA.center));\n },\n /**\n * Calculate the outer distance between two circles. If the circles touch then the\n * distance is 0.0.\n * If the circles intersect then the distance in negative.\n */\n circleDistance: function (circleA, circleB) {\n return circleA.center.distance(circleB.center) - circleA.radius - circleB.radius;\n },\n /**\n * Calculate the inner sector angle for a given circle arc length and radius.\n *\n * @param {number} sectorArcLength - The desired arc length.\n * @param {number} circleRadius - The circle's radius.\n * @returns The sector angle in radians.\n */\n sectorAngleByArcLength: function (sectorArcLength, circleRadius) {\n return sectorArcLength / circleRadius;\n }\n };\n return Circle;\n}()); // END class\nexports.Circle = Circle;\n//# sourceMappingURL=Circle.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2020-12-17\n * @modified 2021-01-20 Added UID.\n * @modified 2021-02-26 Fixed an error in the svg-arc-calculation (case angle<90deg and anti-clockwise).\n * @modified 2024-01-30 Added a missing type in the `describeSVGArc` function.\n * @modified 2024-03-01 Added the `getStartPoint` and `getEndPoint` methods.\n * @modified 2024-03-08 Added the `containsAngle` method.\n * @modified 2024-03-09 Added the `circleSectorIntersection` method to find coherent sector intersections..\n * @modified 2024-03-09 Added the `angleAt` method to determine any angle at some ratio.\n * @modified 2025-04-02 Adding the `CircleSector.lineIntersections` and `CircleSector.lineIntersectionTangents` and implementing `Intersectable`.\n * @modified 2025-04-09 Adding the `CircleSector.move()` method.\n * @modified 2025-04-19 Tweaking the `CircleSector.containsAngle` method: all values (input angle, start- and end- angle) are wrapped into [0,2*PI) now.\n * @modified 2025-04-19 Class `CircleSector` implements interface `Bounded` now (method `getBounds` added).\n * @version 1.2.0\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.CircleSector = void 0;\nvar Bounds_1 = require(\"./Bounds\");\nvar Circle_1 = require(\"./Circle\");\nvar Line_1 = require(\"./Line\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar Vertex_1 = require(\"./Vertex\");\nvar geomutils_1 = require(\"./geomutils\");\n/**\n * @classdesc A simple circle sector: circle, start- and end-angle.\n *\n * @requires Line\n * @requires SVGSerializale\n * @requires UID\n * @requires UIDGenerator\n * @requires XYCoords\n **/\nvar CircleSector = /** @class */ (function () {\n /**\n * Create a new circle sector with given circle, start- and end-angle.\n *\n * @constructor\n * @name CircleSector\n * @param {Circle} circle - The circle.\n * @param {number} startAngle - The start angle of the sector.\n * @param {number} endAngle - The end angle of the sector.\n */\n function CircleSector(circle, startAngle, endAngle) {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"CircleSector\";\n this.uid = UIDGenerator_1.UIDGenerator.next();\n this.circle = circle;\n this.startAngle = startAngle;\n this.endAngle = endAngle;\n }\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Get the bounds of this ellipse.\n *\n * The bounds are approximated by the underlying segment buffer; the more segment there are,\n * the more accurate will be the returned bounds.\n *\n * @method getBounds\n * @instance\n * @memberof VEllipse\n * @return {Bounds} The bounds of this curve.\n **/\n CircleSector.prototype.getBounds = function () {\n var _self = this;\n var circleBounds = this.circle.getBounds();\n // Calculage angles from east, west, north and south box points and check if they are inside\n var candidates = [\n circleBounds.getNorthPoint(),\n circleBounds.getSouthPoint(),\n circleBounds.getWestPoint(),\n circleBounds.getEastPoint()\n ].filter(function (point) {\n // Check for each candidate points if they are contained in this sector. Drop if not.\n var angle = new Line_1.Line(_self.circle.center, point).angle();\n return _self.containsAngle(angle);\n });\n // Compute bounds and inlcude start end end point (they are definitely part of the bounds)\n return Bounds_1.Bounds.computeFromVertices(candidates.concat([this.getStartPoint(), this.getEndPoint()]));\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Move the circle sector by the given amount.\n *\n * @method move\n * @param {XYCoords} amount - The amount to move.\n * @instance\n * @memberof CircleSector\n * @return {CircleSector} this for chaining\n **/\n CircleSector.prototype.move = function (amount) {\n this.circle.move(amount);\n return this;\n };\n /**\n * Checks wether the given angle (must be inside 0 and PI*2) is contained inside this sector.\n *\n * @param {number} angle - The numeric angle to check.\n * @method containsAngle\n * @instance\n * @memberof CircleSector\n * @return {boolean} True if (and only if) this sector contains the given angle.\n */\n CircleSector.prototype.containsAngle = function (angle) {\n var wrappedAngle = geomutils_1.geomutils.mapAngleTo2PI(angle);\n var wrappedStart = geomutils_1.geomutils.mapAngleTo2PI(this.startAngle);\n var wrappedEnd = geomutils_1.geomutils.mapAngleTo2PI(this.endAngle);\n // TODO: cleanup\n // if (this.startAngle <= this.endAngle) {\n // return angle >= this.startAngle && angle < this.endAngle;\n // } else {\n // // startAngle > endAngle\n // return angle >= this.startAngle || angle < this.endAngle;\n // }\n if (wrappedStart <= wrappedEnd) {\n return wrappedAngle >= wrappedStart && wrappedAngle < wrappedEnd;\n }\n else {\n // startAngle > endAngle\n return wrappedAngle >= wrappedStart || wrappedAngle < wrappedEnd;\n }\n };\n /**\n * Get the angle inside this sector for a given ratio. 0.0 means startAngle, and 1.0 means endAngle.\n *\n * @param {number} t - The ratio inside [0..1].\n * @method angleAt\n * @instance\n * @memberof CircleSector\n * @return {number} The angle inside this sector at a given ratio.\n */\n CircleSector.prototype.angleAt = function (t) {\n if (this.startAngle <= this.endAngle) {\n var angleAtRatio = this.startAngle + (this.endAngle - this.startAngle) * t;\n return angleAtRatio % (Math.PI * 2.0);\n }\n else {\n // startAngle > endAngle\n var angleAtRatio = this.startAngle + (Math.PI * 2 - this.startAngle + this.endAngle) * t;\n return angleAtRatio % (Math.PI * 2.0);\n }\n };\n /**\n * Get the sectors starting point (on the underlying circle, located at the start angle).\n *\n * @method getStartPoint\n * @instance\n * @memberof CircleSector\n * @return {Vertex} The sector's stating point.\n */\n CircleSector.prototype.getStartPoint = function () {\n return this.circle.vertAt(this.startAngle);\n };\n /**\n * Get the sectors ending point (on the underlying circle, located at the end angle).\n *\n * @method getEndPoint\n * @instance\n * @memberof CircleSector\n * @return {Vertex} The sector's ending point.\n */\n CircleSector.prototype.getEndPoint = function () {\n return this.circle.vertAt(this.endAngle);\n };\n /**\n * Calculate the intersection of this circle sector and some other sector.\n *\n * If the two sectors do not corerently intersect (when not both points of the\n * radical line are containted in both source sectors) then null is returned.\n *\n * See demo/53-circle-sector-intersections for a geometric visualisation.\n *\n * @method circleSectorIntersection\n * @instance\n * @memberof CircleSector\n * @return {CircleSector | null} The intersecion of both sectors or null if they don't intersect.\n */\n CircleSector.prototype.circleSectorIntersection = function (sector) {\n var radicalLine = this.circle.circleIntersection(sector.circle);\n if (!radicalLine) {\n // The circles to not intersect at all.\n return null;\n }\n // Circles intersect. Check if this sector interval intersects, too.\n var thisIntersectionAngleA = this.circle.center.angle(radicalLine.a);\n var thisIntersectionAngleB = this.circle.center.angle(radicalLine.b);\n // Is intersection inside this sector?\n if (!this.containsAngle(thisIntersectionAngleA) || !this.containsAngle(thisIntersectionAngleB)) {\n // At least one circle intersection point is not located in this sector.\n // -> no valid intersection at all\n return null;\n }\n // Circles intersect. Check if the passed sector interval intersects, too.\n var thatIntersectionAngleA = sector.circle.center.angle(radicalLine.a);\n var thatIntersectionAngleB = sector.circle.center.angle(radicalLine.b);\n // Is intersection inside this sector?\n if (!sector.containsAngle(thatIntersectionAngleA) || !sector.containsAngle(thatIntersectionAngleB)) {\n // At least one circle intersection point is not located in this sector.\n // -> no valid intersection at all\n return null;\n }\n // The radical line has no direction. Thus the resulting sector _might_ be in reverse order.\n // Make a quick logical check: the center of the gap must still be located inside the result sector.\n // If not: reverse result.\n var gapSector = new CircleSector(this.circle, this.endAngle, this.startAngle);\n var centerOfOriginalGap = gapSector.angleAt(0.5);\n var resultSector = new CircleSector(new Circle_1.Circle(this.circle.center.clone(), this.circle.radius), thisIntersectionAngleA, thisIntersectionAngleB);\n if (resultSector.containsAngle(centerOfOriginalGap)) {\n resultSector.startAngle = thisIntersectionAngleB;\n resultSector.endAngle = thisIntersectionAngleA;\n }\n return resultSector;\n };\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get the line intersections as vectors with this ellipse.\n *\n * @method lineIntersections\n * @instance\n * @param {VertTuple<Vector> ray - The line/ray to intersect this ellipse with.\n * @param {boolean} inVectorBoundsOnly - (default=false) Set to true if only intersections within the vector bounds are of interest.\n * @returns\n */\n CircleSector.prototype.lineIntersections = function (ray, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // First get all line intersections from underlying ellipse.\n var ellipseIntersections = this.circle.lineIntersections(ray, inVectorBoundsOnly);\n // Drop all intersection points that are not contained in the circle sectors bounds.\n var tmpLine = new Line_1.Line(this.circle.center, new Vertex_1.Vertex());\n return ellipseIntersections.filter(function (intersectionPoint) {\n tmpLine.b.set(intersectionPoint);\n var lineAngle = tmpLine.angle();\n return _this.containsAngle(geomutils_1.geomutils.wrapMinMax(lineAngle, 0, Math.PI * 2));\n });\n };\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @param line\n * @param lineIntersectionTangents\n * @returns\n */\n CircleSector.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersections of all lines plus their tangents inside the circle bounds\n var interSectionPoints = this.lineIntersections(line, inVectorBoundsOnly);\n return interSectionPoints.map(function (vert) {\n // Calculate angle\n var lineFromCenter = new Line_1.Line(_this.circle.center, vert);\n var angle = lineFromCenter.angle();\n // console.log(\"angle\", (angle / Math.PI) * 180.0);\n // const angle = Math.random() * Math.PI * 2; // TODO\n // Calculate tangent at angle\n return _this.circle.tangentAt(angle);\n });\n };\n //--- END --- Implement interface `Intersectable`\n CircleSector.prototype.describeSVGPath = function (options) {\n // const buffer: SVGPathParams = [];\n // const start = this.getStartPoint();\n // const end = this.getEndPoint();\n // // describeSVGArc\n // // x: number,\n // // y: number,\n // // radius: number,\n // // startAngle: number,\n // // endAngle: number,\n // // options?: { moveToStart: boolean }\n // // ): SVGPathParams => {\n // var arcRotation = 0.0;\n // var largeArcFlag = 1;\n // var sweepFlag = 0;\n // if (options && options.moveToStart) {\n // buffer.push(\"M\", start.x, start.y);\n // }\n // buffer.push(\"A\", cSector.circle.radius, cSector.circle.radius, arcRotation, largeArcFlag, sweepFlag, end.x, end.y);\n // return buffer;\n var arc = CircleSector.circleSectorUtils.describeSVGArc(this.circle.center.x, // end.x,\n this.circle.center.y, // end.y,\n this.circle.radius, this.startAngle, this.endAngle, options // options?: { moveToStart: boolean }\n );\n return arc;\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n *\n * @method destroy\n * @instance\n * @memberof CircleSector\n * @return {void}\n */\n CircleSector.prototype.destroy = function () {\n this.circle.destroy();\n this.isDestroyed = true;\n };\n CircleSector.circleSectorUtils = {\n /**\n * Helper function to convert polar circle coordinates to cartesian coordinates.\n *\n * TODO: generalize for ellipses (two radii).\n *\n * @param {number} angle - The angle in radians.\n */\n polarToCartesian: function (centerX, centerY, radius, angle) {\n return {\n x: centerX + radius * Math.cos(angle),\n y: centerY + radius * Math.sin(angle)\n };\n },\n /**\n * Helper function to convert a circle section as SVG arc params (for the `d` attribute).\n * Found at: https://stackoverflow.com/questions/5736398/how-to-calculate-the-svg-path-for-an-arc-of-a-circle\n *\n * TODO: generalize for ellipses (two radii).\n *\n * @param {boolean} options.moveToStart - If false (default=true) the initial 'Move' command will not be used.\n * @return [ 'A', radiusx, radiusy, rotation=0, largeArcFlag=1|0, sweepFlag=0, endx, endy ]\n */\n describeSVGArc: function (x, y, radius, startAngle, endAngle, options) {\n if (typeof options === \"undefined\") {\n options = { moveToStart: true };\n }\n var end = CircleSector.circleSectorUtils.polarToCartesian(x, y, radius, endAngle);\n var start = CircleSector.circleSectorUtils.polarToCartesian(x, y, radius, startAngle);\n // Split full circles into two halves.\n // Some browsers have problems to render full circles (described by start==end).\n if (Math.PI * 2 - Math.abs(startAngle - endAngle) < 0.001) {\n var firstHalf = CircleSector.circleSectorUtils.describeSVGArc(x, y, radius, startAngle, startAngle + (endAngle - startAngle) / 2, options);\n var secondHalf = CircleSector.circleSectorUtils.describeSVGArc(x, y, radius, startAngle + (endAngle - startAngle) / 2, endAngle, options);\n return firstHalf.concat(secondHalf);\n }\n // Boolean stored as integers (0|1).\n var diff = endAngle - startAngle;\n var largeArcFlag;\n var sweepFlag;\n if (diff < 0) {\n largeArcFlag = Math.abs(diff) < Math.PI ? 1 : 0;\n sweepFlag = 1;\n }\n else {\n largeArcFlag = Math.abs(diff) > Math.PI ? 1 : 0;\n sweepFlag = 1;\n }\n var pathData = [];\n if (options.moveToStart) {\n pathData.push(\"M\", start.x, start.y);\n }\n pathData.push(\"A\", radius, radius, 0, largeArcFlag, sweepFlag, end.x, end.y);\n return pathData;\n }\n };\n return CircleSector;\n}()); // END class\nexports.CircleSector = CircleSector;\n//# sourceMappingURL=CircleSector.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2019-09-18\n * @modified 2019-10-03 Added the beginDrawCycle hook.\n * @modified 2020-03-25 Ported stub to Typescript.\n * @modified 2020-10-15 Re-added the text() function.\n * @modified 2021-01-24 Added the `setCurrentId` function.\n * @modified 2021-05-31 Added the `setConfiguration` function from `DrawLib`.\n * @modified 2022-02-03 Added the `lineWidth` param to the `crosshair` function.\n * @modified 2022-02-03 Added the `cross(...)` function.\n * @modified 2022-03-27 Added the `texturedPoly` function.\n * @modified 2022-07-26 Adding `alpha` to the `image(...)` function.\n * @modified 2023-02-10 The methods `setCurrentClassName` and `setCurrentId` also accept `null` now.\n * @modified 2023-09-29 Downgrading all `Vertex` param type to the more generic `XYCoords` type in these render functions: line, arrow, texturedPoly, cubicBezier, cubicBezierPath, handle, handleLine, dot, point, circle, circleArc, ellipse, grid, raster.\n * @modified 2023-09-29 Added the `headLength` parameter to the 'DrawLib.arrow()` function.\n * @modified 2023-09-29 Added the `arrowHead(...)` function to the 'DrawLib.arrow()` interface.\n * @modified 2023-09-29 Added the `cubicBezierArrow(...)` function to the 'DrawLib.arrow()` interface.\n * @modified 2023-09-29 Added the `lineDashes` attribute.\n * @modified 2026-03-18 Adding `isOpen` parameter to `cubicBezierPath` draw method.\n * @modified 2026-04-04 Added the method `bounds`.\n * @version 0.0.11\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.drawutilsgl = void 0;\nvar Vertex_1 = require(\"./Vertex\");\n/**\n * @classdesc A wrapper class for basic drawing operations. This is the WebGL\n * implementation whih sould work with shaders.\n *\n * @requires CubicBzierCurvce\n * @requires Polygon\n * @requires SVGSerializable\n * @requires Vertex\n * @requires XYCoords\n */\nvar drawutilsgl = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name drawutils\n * @param {WebGLRenderingContext|null} context - The drawing context.\n * @param {boolean} fillShaped - Indicates if the constructed drawutils should fill all drawn shapes (if possible).\n **/\n function drawutilsgl(context, fillShapes) {\n this.gl = context;\n this.offset = new Vertex_1.Vertex(0, 0);\n this.scale = new Vertex_1.Vertex(1, 1);\n this.fillShapes = fillShapes;\n this._zindex = 0.0;\n if (context == null || typeof context === \"undefined\")\n return;\n this.glutils = new GLU(context);\n // PROBLEM: CANNOT USE MULTIPLE SHADER PROGRAM INSTANCES ON THE SAME CONTEXT!\n // SOLUTION: USE SHARED SHADER PROGRAM!!! ... somehow ...\n // This needs to be considered in the overlying component; both draw-instances need to\n // share their gl context.\n // That's what the copyInstace(boolean) method is good for.\n this._vertShader = this.glutils.compileShader(drawutilsgl.vertCode, this.gl.VERTEX_SHADER);\n this._fragShader = this.glutils.compileShader(drawutilsgl.fragCode, this.gl.FRAGMENT_SHADER);\n this._program = this.glutils.makeProgram(this._vertShader, this._fragShader);\n // Create an empty buffer object\n this.vertex_buffer = this.gl.createBuffer();\n // Bind appropriate array buffer to it\n // this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertex_buffer);\n console.log(\"gl initialized\");\n }\n drawutilsgl.prototype._x2rel = function (x) {\n return ((this.scale.x * x + this.offset.x) / this.gl.canvas.width) * 2.0 - 1.0;\n };\n drawutilsgl.prototype._y2rel = function (y) {\n return ((this.offset.y - this.scale.y * y) / this.gl.canvas.height) * 2.0 - 1.0;\n };\n /**\n * Creates a 'shallow' (non deep) copy of this instance. This implies\n * that under the hood the same gl context and gl program will be used.\n */\n drawutilsgl.prototype.copyInstance = function (fillShapes) {\n var copy = new drawutilsgl(null, fillShapes);\n copy.gl = this.gl;\n copy.glutils = this.glutils;\n copy._vertShader = this._vertShader;\n copy._fragShader = this._fragShader;\n copy._program = this._program;\n return copy;\n };\n /**\n * Called before each draw cycle.\n * @param {number} renderTime\n **/\n drawutilsgl.prototype.beginDrawCycle = function (renderTime) {\n this._zindex = 0.0;\n this.renderTime = renderTime;\n };\n /**\n * Called after each draw cycle.\n *\n * This is required for compatibility with other draw classes in the library (like drawgl).\n *\n * @name endDrawCycle\n * @method\n * @param {number} renderTime\n * @instance\n **/\n drawutilsgl.prototype.endDrawCycle = function (renderTime) {\n // NOOP\n };\n /**\n * Set the current drawlib configuration.\n *\n * @name setConfiguration\n * @method\n * @param {DrawLibConfiguration} configuration - The new configuration settings to use for the next render methods.\n */\n drawutilsgl.prototype.setConfiguration = function (configuration) {\n // TODO\n };\n // /**\n // * Set or clear the line-dash configuration. Pass `null` for un-dashed lines.\n // *\n // * See https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray\n // * and https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash\n // * for how line dashes work.\n // *\n // * @method\n // * @param {Array<number> lineDashes - The line-dash array configuration.\n // * @returns {void}\n // */\n // setLineDash(lineDashes: Array<number>) {\n // // TODO\n // }\n /**\n * This method shouled be called each time the currently drawn `Drawable` changes.\n * It is used by some libraries for identifying elemente on re-renders.\n *\n * @name setCurrentId\n * @method\n * @param {UID|null} uid - A UID identifying the currently drawn element(s).es.\n **/\n drawutilsgl.prototype.setCurrentId = function (uid) {\n // NOOP\n this.curId = uid;\n };\n /**\n * This method shouled be called each time the currently drawn `Drawable` changes.\n * Determine the class name for further usage here.\n *\n * @name setCurrentClassName\n * @method\n * @param {string|null} className - A class name for further custom use cases.\n **/\n drawutilsgl.prototype.setCurrentClassName = function (className) {\n // NOOP\n };\n /**\n * Draw the line between the given two points with the specified (CSS-) color.\n *\n * @method line\n * @param {XYCoords} zA - The start point of the line.\n * @param {XYCoords} zB - The end point of the line.\n * @param {string} color - Any valid CSS color string.\n * @return {void}\n * @instance\n * @memberof drawutils\n **/\n drawutilsgl.prototype.line = function (zA, zB, color) {\n var vertices = new Float32Array(6);\n vertices[0] = this._x2rel(zA.x);\n vertices[1] = this._y2rel(zA.y);\n vertices[2] = this._zindex;\n vertices[3] = this._x2rel(zB.x);\n vertices[4] = this._y2rel(zB.y);\n vertices[5] = this._zindex;\n this._zindex += 0.001;\n // Create an empty buffer object\n // const vertex_buffer = this.gl.createBuffer();\n // Bind appropriate array buffer to it\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertex_buffer);\n // Pass the vertex data to the buffer\n this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW);\n // Bind vertex buffer object\n // this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertex_buffer);\n // Get the attribute location\n var coord = this.gl.getAttribLocation(this._program, \"position\");\n // Point an attribute to the currently bound VBO\n this.gl.vertexAttribPointer(coord, 3, this.gl.FLOAT, false, 0, 0);\n // Enable the attribute\n this.gl.enableVertexAttribArray(coord);\n // Unbind the buffer?\n //this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);\n // Set the view port\n this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height);\n var uRotationVector = this.gl.getUniformLocation(this._program, \"uRotationVector\");\n // let radians = currentAngle * Math.PI / 180.0;\n var currentRotation = [0.0, 1.0];\n //currentRotation[0] = Math.sin(radians);\n //currentRotation[1] = Math.cos(radians);\n this.gl.uniform2fv(uRotationVector, currentRotation);\n this.gl.lineWidth(5);\n // Draw the line\n this.gl.drawArrays(this.gl.LINES, 0, vertices.length / 3);\n // POINTS, LINE_STRIP, LINE_LOOP, LINES,\n // TRIANGLE_STRIP,TRIANGLE_FAN, TRIANGLES\n };\n /**\n * Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.\n *\n * @method arrow\n * @param {XYCoords} zA - The start point of the arrow-line.\n * @param {XYCoords} zB - The end point of the arrow-line.\n * @param {string} color - Any valid CSS color string.\n * @param {headLength=8} headLength - (optional) The length of the arrow head (default is 8 units).\n * @return {void}\n * @instance\n * @memberof drawutils\n **/\n drawutilsgl.prototype.arrow = function (zA, zB, color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a cubic Bézier curve and and an arrow at the end (endControlPoint) of the given line width the specified (CSS-) color and arrow size.\n *\n * @method cubicBezierArrow\n * @param {XYCoords} startPoint - The start point of the cubic Bézier curve\n * @param {XYCoords} endPoint - The end point the cubic Bézier curve.\n * @param {XYCoords} startControlPoint - The start control point the cubic Bézier curve.\n * @param {XYCoords} endControlPoint - The end control point the cubic Bézier curve.\n * @param {string} color - The CSS color to draw the curve with.\n * @param {number} lineWidth - (optional) The line width to use.\n * @param {headLength=8} headLength - (optional) The length of the arrow head (default is 8 units).\n *\n * @return {void}\n * @instance\n * @memberof DrawLib\n */\n drawutilsgl.prototype.cubicBezierArrow = function (startPoint, endPoint, startControlPoint, endControlPoint, color, lineWidth, headLength) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw just an arrow head a the end of an imaginary line (zB) of the given line width the specified (CSS-) color and size.\n *\n * @method arrow\n * @param {XYCoords} zA - The start point of the arrow-line.\n * @param {XYCoords} zB - The end point of the arrow-line.\n * @param {string} color - Any valid CSS color string.\n * @param {number=1} lineWidth - (optional) The line width to use; default is 1.\n * @param {number=8} headLength - (optional) The length of the arrow head (default is 8 pixels).\n * @return {void}\n * @instance\n * @memberof DrawLib\n **/\n drawutilsgl.prototype.arrowHead = function (zA, zB, color, lineWidth, headLength) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw an image at the given position with the given size.<br>\n * <br>\n * Note: SVG images may have resizing issues at the moment.Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.\n *\n * @method image\n * @param {Image} image - The image object to draw.\n * @param {XYCoords} position - The position to draw the the upper left corner at.\n * @param {XYCoords} size - The x/y-size to draw the image with.\n * @param {number=0.0} alpha - (optional, default=0.0) The transparency (0.0=opaque, 1.0=transparent).\n * @return {void}\n * @instance\n * @memberof drawutils\n **/\n drawutilsgl.prototype.image = function (image, position, size, alpha) {\n if (alpha === void 0) { alpha = 0.0; }\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw an image at the given position with the given size.<br>\n * <br>\n * Note: SVG images may have resizing issues at the moment.Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.\n *\n * @method texturedPoly\n * @param {Image} textureImage - The image object to draw.\n * @param {Bounds} textureSize - The texture size to use; these are the original bounds to map the polygon vertices to.\n * @param {Polygon} polygon - The polygon to use as clip path.\n * @param {XYCoords} polygonPosition - The polygon's position (relative), measured at the bounding box's center.\n * @param {number} rotation - The rotation to use for the polygon (and for the texture).\n * @return {void}\n * @instance\n * @memberof drawutilsgl\n **/\n drawutilsgl.prototype.texturedPoly = function (textureImage, textureSize, polygon, polygonPosition, rotation) {\n // NOT YET IMPLEMENTED\n };\n // +---------------------------------------------------------------------------------\n // | This is the final helper function for drawing and filling stuff. It is not\n // | intended to be used from the outside.\n // |\n // | When in draw mode it draws the current shape.\n // | When in fill mode it fills the current shape.\n // |\n // | This function is usually only called internally.\n // |\n // | @param color A stroke/fill color to use.\n // +-------------------------------\n drawutilsgl.prototype._fillOrDraw = function (color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw the given (cubic) bézier curve.\n *\n * @method cubicBezier\n * @param {XYCoords} startPoint - The start point of the cubic Bézier curve\n * @param {XYCoords} endPoint - The end point the cubic Bézier curve.\n * @param {XYCoords} startControlPoint - The start control point the cubic Bézier curve.\n * @param {VertXYCoordsex} endControlPoint - The end control point the cubic Bézier curve.\n * @param {string} color - The CSS color to draw the curve with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.cubicBezier = function (startPoint, endPoint, startControlPoint, endControlPoint, color, lineWidth) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw the given (cubic) Bézier path.\n *\n * The given path must be an array with n*3+1 vertices, where n is the number of\n * curves in the path:\n * <pre> [ point1, point1_startControl, point2_endControl, point2, point2_startControl, point3_endControl, point3, ... pointN_endControl, pointN ]</pre>\n *\n * @method cubicBezierPath\n * @param {XYCoords[]} path - The cubic bezier path as described above.\n * @param {string} color - The CSS colot to draw the path with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.cubicBezierPath = function (path, color, lineWidth, strokeOptions, isOpen) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw the given handle and handle point (used to draw interactive Bézier curves).\n *\n * The colors for this are fixed and cannot be specified.\n *\n * @method handle\n * @param {XYCoords} startPoint - The start of the handle.\n * @param {XYCoords} endPoint - The end point of the handle.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.handle = function (startPoint, endPoint) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a handle line (with a light grey).\n *\n * @method handleLine\n * @param {XYCoords} startPoint - The start point to draw the handle at.\n * @param {XYCoords} endPoint - The end point to draw the handle at.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.handleLine = function (startPoint, endPoint) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a 1x1 dot with the specified (CSS-) color.\n *\n * @method dot\n * @param {XYCoords} p - The position to draw the dot at.\n * @param {string} color - The CSS color to draw the dot with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.dot = function (p, color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw the given point with the specified (CSS-) color and radius 3.\n *\n * @method point\n * @param {XYCoords} p - The position to draw the point at.\n * @param {string} color - The CSS color to draw the point with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.point = function (p, color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a circle with the specified (CSS-) color and radius.<br>\n * <br>\n * Note that if the x- and y- scales are different the result will be an ellipse rather than a circle.\n *\n * @method circle\n * @param {XYCoords} center - The center of the circle.\n * @param {number} radius - The radius of the circle.\n * @param {string} color - The CSS color to draw the circle with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.circle = function (center, radius, color, lineWidth) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a circular arc (section of a circle) with the given CSS color.\n *\n * @method circleArc\n * @param {XYCoords} center - The center of the circle.\n * @param {number} radius - The radius of the circle.\n * @param {number} startAngle - The angle to start at.\n * @param {number} endAngle - The angle to end at.\n * @param {string} color - The CSS color to draw the circle with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.circleArc = function (center, radius, startAngle, endAngle, color, lineWidth) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw an ellipse with the specified (CSS-) color and thw two radii.\n *\n * @method ellipse\n * @param {XYCoords} center - The center of the ellipse.\n * @param {number} radiusX - The radius of the ellipse.\n * @param {number} radiusY - The radius of the ellipse.\n * @param {string} color - The CSS color to draw the ellipse with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {number=} rotation - (optional, default=0) The rotation of the ellipse.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.ellipse = function (center, radiusX, radiusY, color, lineWidth, rotation) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw square at the given center, size and with the specified (CSS-) color.<br>\n * <br>\n * Note that if the x-scale and the y-scale are different the result will be a rectangle rather than a square.\n *\n * @method square\n * @param {XYCords} center - The center of the square.\n * @param {number} size - The size of the square.\n * @param {string} color - The CSS color to draw the square with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.square = function (center, size, color, lineWidth) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a rectangle.\n *\n * @param {XYCoords} position - The upper left corner of the rectangle.\n * @param {number} width - The width of the rectangle.\n * @param {number} height - The height of the rectangle.\n * @param {string} color - The color to use.\n * @param {number=1} lineWidth - (optional) The line with to use (default is 1).\n **/\n drawutilsgl.prototype.rect = function (position, width, height, color, lineWidth, strokeOptions) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a rectangle at the given bounds; and with the specified line width and (CSS-) color.<br>\n *\n * @method bounds\n * @param {IBounds} bounds - The bounds rectangle to be drawn.\n * @param {string} color - The CSS color to draw the rectangle with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {R}\n * @instance\n * @memberof DrawLib\n */\n drawutilsgl.prototype.bounds = function (bounds, color, lineWidth, strokeOptions) {\n this.rect(bounds.min, bounds.max.x - bounds.min.x, bounds.max.y - bounds.min.y, color, lineWidth, strokeOptions);\n };\n /**\n * Draw a grid of horizontal and vertical lines with the given (CSS-) color.\n *\n * @method grid\n * @param {XYCoords} center - The center of the grid.\n * @param {number} width - The total width of the grid (width/2 each to the left and to the right).\n * @param {number} height - The total height of the grid (height/2 each to the top and to the bottom).\n * @param {number} sizeX - The horizontal grid size.\n * @param {number} sizeY - The vertical grid size.\n * @param {string} color - The CSS color to draw the grid with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.grid = function (center, width, height, sizeX, sizeY, color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a raster of crosshairs in the given grid.<br>\n *\n * This works analogue to the grid() function\n *\n * @method raster\n * @param {XYCoords} center - The center of the raster.\n * @param {number} width - The total width of the raster (width/2 each to the left and to the right).\n * @param {number} height - The total height of the raster (height/2 each to the top and to the bottom).\n * @param {number} sizeX - The horizontal raster size.\n * @param {number} sizeY - The vertical raster size.\n * @param {string} color - The CSS color to draw the raster with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.raster = function (center, width, height, sizeX, sizeY, color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a diamond handle (square rotated by 45°) with the given CSS color.\n *\n * It is an inherent featur of the handle functions that the drawn elements are not scaled and not\n * distorted. So even if the user zooms in or changes the aspect ratio, the handles will be drawn\n * as even shaped diamonds.\n *\n * @method diamondHandle\n * @param {XYCoords} center - The center of the diamond.\n * @param {number} size - The x/y-size of the diamond.\n * @param {string} color - The CSS color to draw the diamond with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.diamondHandle = function (center, size, color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a square handle with the given CSS color.<br>\n * <br>\n * It is an inherent featur of the handle functions that the drawn elements are not scaled and not\n * distorted. So even if the user zooms in or changes the aspect ratio, the handles will be drawn\n * as even shaped squares.\n *\n * @method squareHandle\n * @param {XYCoords} center - The center of the square.\n * @param {number} size - The x/y-size of the square.\n * @param {string} color - The CSS color to draw the square with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.squareHandle = function (center, size, color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a circle handle with the given CSS color.<br>\n * <br>\n * It is an inherent featur of the handle functions that the drawn elements are not scaled and not\n * distorted. So even if the user zooms in or changes the aspect ratio, the handles will be drawn\n * as even shaped circles.\n *\n * @method circleHandle\n * @param {XYCoords} center - The center of the circle.\n * @param {number} radius - The radius of the circle.\n * @param {string} color - The CSS color to draw the circle with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.circleHandle = function (center, size, color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a crosshair with given radius and color at the given position.<br>\n * <br>\n * Note that the crosshair radius will not be affected by scaling.\n *\n * @method crosshair\n * @param {XYCoords} center - The center of the crosshair.\n * @param {number} radius - The radius of the crosshair.\n * @param {string} color - The CSS color to draw the crosshair with.\n * @param {number=0.5} lineWidth - (optional, default=0.5) The line width to use.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.crosshair = function (center, radius, color, lineWidth) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a cross with diagonal axes with given radius, color and lineWidth at the given position.<br>\n * <br>\n * Note that the x's radius will not be affected by scaling.\n *\n * @method crosshair\n * @param {XYCoords} center - The center of the crosshair.\n * @param {number} radius - The radius of the crosshair.\n * @param {string} color - The CSS color to draw the crosshair with.\n * @param {number=1} lineWidth - (optional, default=1.0) The line width to use.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.cross = function (center, radius, color, lineWidth) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a polygon.\n *\n * @method polygon\n * @param {Polygon} polygon - The polygon to draw.\n * @param {string} color - The CSS color to draw the polygon with.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.polygon = function (polygon, color, lineWidth) {\n var vertices = new Float32Array(polygon.vertices.length * 3);\n for (var i = 0; i < polygon.vertices.length; i++) {\n vertices[i * 3 + 0] = this._x2rel(polygon.vertices[i].x);\n vertices[i * 3 + 1] = this._y2rel(polygon.vertices[i].y);\n vertices[i * 3 + 2] = this._zindex;\n }\n this._zindex += 0.001;\n //console.log( vertices );\n // Create an empty buffer object\n // const vertex_buffer = this.gl.createBuffer();\n // Bind appropriate array buffer to it\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertex_buffer);\n // Pass the vertex data to the buffer\n this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW);\n // Bind vertex buffer object\n // this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertex_buffer);\n // Get the attribute location\n var coord = this.gl.getAttribLocation(this._program, \"position\");\n // Point an attribute to the currently bound VBO\n this.gl.vertexAttribPointer(coord, 3, this.gl.FLOAT, false, 0, 0);\n // Enable the attribute\n this.gl.enableVertexAttribArray(coord);\n // Unbind the buffer?\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);\n // Set the view port\n this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height);\n var uRotationVector = this.gl.getUniformLocation(this._program, \"uRotationVector\");\n // let radians = currentAngle * Math.PI / 180.0;\n var currentRotation = [0.0, 1.0];\n //currentRotation[0] = Math.sin(radians);\n //currentRotation[1] = Math.cos(radians);\n this.gl.uniform2fv(uRotationVector, currentRotation);\n // Draw the polygon\n this.gl.drawArrays(this.gl.TRIANGLE_FAN, 0, vertices.length / 3);\n // POINTS, LINE_STRIP, LINE_LOOP, LINES,\n // TRIANGLE_STRIP,TRIANGLE_FAN, TRIANGLES\n };\n /**\n * Draw a polygon line (alternative function to the polygon).\n *\n * @method polyline\n * @param {XYCoords[]} vertices - The polygon vertices to draw.\n * @param {boolan} isOpen - If true the polyline will not be closed at its end.\n * @param {string} color - The CSS color to draw the polygon with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.polyline = function (vertices, isOpen, color, lineWidth) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a text at the given relative position.\n *\n * @method text\n * @param {string} text - The text to draw.\n * @param {number} x - The x-position to draw the text at.\n * @param {number} y - The y-position to draw the text at.\n * @param {string=} options.color - The Color to use.\n * @param {string=} options.fontFamily - The font family to use.\n * @param {number=} options.fontSize - The font size (in pixels) to use.\n * @param {FontStyle=} options.fontStyle - The font style to use.\n * @param {FontWeight=} options.fontWeight - The font weight to use.\n * @param {number=} options.lineHeight - The line height (in pixels) to use.\n * @param {number=} options.rotation - The (optional) rotation in radians.\n * @param {string=} options.textAlign - The text align to use. According to the specifiactions (https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign) valid values are `\"left\" || \"right\" || \"center\" || \"start\" || \"end\"`.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.text = function (text, x, y, options) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw a non-scaling text label at the given position.\n *\n * @method label\n * @param {string} text - The text to draw.\n * @param {number} x - The x-position to draw the text at.\n * @param {number} y - The y-position to draw the text at.\n * @param {number=} rotation - The (aoptional) rotation in radians.\n * @param {string=\"black\"} color - The color to use (default is black).\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilsgl.prototype.label = function (text, x, y, rotation, color) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Draw an SVG-like path given by the specified path data.\n *\n * @method path\n * @param {SVGPathData} pathData - An array of path commands and params.\n * @param {string=null} color - (optional) The color to draw this path with (default is null).\n * @param {number=1} lineWidth - (optional) the line width to use (default is 1).\n * @param {boolean=false} options.inplace - (optional) If set to true then path transforamtions (scale and translate) will be done in-place in the array. This can boost the performance.\n * @instance\n * @memberof drawutils\n * @return {R} An instance representing the drawn path.\n */\n drawutilsgl.prototype.path = function (pathData, color, lineWidth, options) {\n // NOT YET IMPLEMENTED\n };\n /**\n * Due to gl compatibility there is a generic 'clear' function required\n * to avoid accessing the context object itself directly.\n *\n * This function just fills the whole canvas with a single color.\n *\n * @param {string} color - The color to clear with.\n **/\n drawutilsgl.prototype.clear = function (color) {\n // NOT YET IMPLEMENTED\n // if( typeof color == 'string' )\n // color = Color.parse(color); // Color class does not yet exist in TS\n // Clear the canvas\n this.gl.clearColor(1.0, 1.0, 1.0, 1.0);\n // Enable the depth test\n this.gl.enable(this.gl.DEPTH_TEST);\n // Clear the color and depth buffer\n this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);\n };\n // Vertex shader source code\n drawutilsgl.vertCode = \"\\n precision mediump float;\\n\\n attribute vec3 position;\\n\\n uniform vec2 uRotationVector;\\n\\n void main(void) {\\n\\tvec2 rotatedPosition = vec2(\\n\\t position.x * uRotationVector.y +\\n\\t\\tposition.y * uRotationVector.x,\\n\\t position.y * uRotationVector.y -\\n\\t\\tposition.x * uRotationVector.x\\n\\t);\\n\\n\\tgl_Position = vec4(rotatedPosition, position.z, 1.0);\\n }\";\n // Fragment shader source code\n drawutilsgl.fragCode = \"\\n precision highp float;\\n\\n void main(void) {\\n\\tgl_FragColor = vec4(0.0,0.75,1.0,1.0);\\n }\";\n return drawutilsgl;\n}());\nexports.drawutilsgl = drawutilsgl;\n/**\n * Some GL helper utils.\n **/\nvar GLU = /** @class */ (function () {\n function GLU(gl) {\n this.gl = gl;\n }\n GLU.prototype.bufferData = function (verts) {\n // Create an empty buffer object\n var vbuffer = this.gl.createBuffer();\n // Bind appropriate array buffer to it\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vbuffer);\n // Pass the vertex data to the buffer\n this.gl.bufferData(this.gl.ARRAY_BUFFER, verts, this.gl.STATIC_DRAW);\n // Unbind the buffer\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);\n return vbuffer;\n };\n /*=================== Shaders ====================*/\n GLU.prototype.compileShader = function (shaderCode, shaderType) {\n // Create a vertex shader object\n var shader = this.gl.createShader(shaderType);\n // Attach vertex shader source code\n this.gl.shaderSource(shader, shaderCode);\n // Compile the vertex shader\n this.gl.compileShader(shader);\n var vertStatus = this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS);\n if (!vertStatus) {\n console.warn(\"Error in shader:\" + this.gl.getShaderInfoLog(shader));\n this.gl.deleteShader(shader);\n return null;\n }\n return shader;\n };\n GLU.prototype.makeProgram = function (vertShader, fragShader) {\n // Create a shader program object to store\n // the combined shader program\n var program = this.gl.createProgram();\n // Attach a vertex shader\n this.gl.attachShader(program, vertShader);\n // Attach a fragment shader\n this.gl.attachShader(program, fragShader);\n // Link both the programs\n this.gl.linkProgram(program);\n // Use the combined shader program object\n this.gl.useProgram(program);\n /*======= Do some cleanup ======*/\n this.gl.detachShader(program, vertShader);\n this.gl.detachShader(program, fragShader);\n this.gl.deleteShader(vertShader);\n this.gl.deleteShader(fragShader);\n return program;\n };\n return GLU;\n}());\n//# sourceMappingURL=drawgl.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2018-11-28\n * @modified 2018-12-09 Added the utils: baseLog(Number,Number) and mapRasterScale(Number,Number).\n * @version 1.0.1\n *\n * @file Grid\n * @fileoverview Note that the PlotBoilerplate already has a Grid instance member. The Grid is not meant\n * to be added to the canvas as a drawable as it encapsulates more an abstract concept of the canvas\n * rather than a drawable object.\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Grid = void 0;\n/**\n * @classdesc A grid class with vertical and horizontal lines (or a raster).\n *\n * Note that the PlotBoilerplate already has a Grid instance member. The Grid is not meant\n * to be added to the canvas as a drawable as it encapsulates more an abstract concept of the canvas\n * rather than a drawable object.\n *\n * @requires Vertex\n */\nvar Grid = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name Grid\n * @param {Vertex} center - The offset of the grid (default is [0,0]).\n * @param {Vertex} size - The x- and y-size of the grid.\n **/\n function Grid(center, size) {\n this.center = center;\n this.size = size;\n }\n ;\n /**\n * @memberof Grid\n **/\n Grid.utils = {\n /**\n * Calculate the logarithm of the given number (num) to a given base.<br>\n * <br>\n * This function returns the number l with<br>\n * <pre>num == Math.pow(base,l)</pre>\n *\n * @member baseLog\n * @function\n * @memberof Grid\n * @inner\n * @param {number} base - The base to calculate the logarithm to.\n * @param {number} num - The number to calculate the logarithm for.\n * @return {number} <pre>log(base)/log(num)</pre>\n **/\n baseLog: function (base, num) { return Math.log(base) / Math.log(num); },\n /**\n * Calculate the raster scale for a given logarithmic mapping.<br>\n * <br>\n * Example (with adjustFactor=2):<br>\n * <pre>\n * If scale is 4.33, then the mapping is 1/2 (because 2^2 <= 4.33 <= 2^3)<br>\n * If scale is 0.33, then the mapping is 2 because (2^(1/2) >= 0.33 >= 2^(1/4)\n * </pre>\n *\n * @member mapRasterScale\n * @function\n * @memberof Grid\n * @inner\n * @param {number} adjustFactor The base for the logarithmic raster scaling when zoomed.\n * @param {number} scale The currently used scale factor.\n * @return {number}\n **/\n mapRasterScale: function (adjustFactor, scale) {\n var gf = 1.0;\n if (scale >= 1) {\n gf = Math.abs(Math.floor(1 / Grid.utils.baseLog(adjustFactor, scale)));\n gf = 1 / Math.pow(adjustFactor, gf);\n }\n else {\n gf = Math.abs(Math.floor(Grid.utils.baseLog(1 / adjustFactor, 1 / (scale + 1))));\n }\n return gf;\n }\n };\n return Grid;\n}());\nexports.Grid = Grid;\n//# sourceMappingURL=Grid.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2019-02-03\n * @modified 2021-03-01 Added `wrapMax` function.\n * @modified 2024-11-15 Adding helper function `geomutils.mapAngleTo2PI(number)` for mapping any value into the interval [0,2*PI).\n * @modified 2024-11-22 Adding helper function `geomutils.dotProduct(number)` for calculating the dot product of two vertices (as vectors).\n *\n * @version 1.2.0\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.geomutils = void 0;\nvar Line_1 = require(\"./Line\");\nvar Triangle_1 = require(\"./Triangle\");\n/**\n * A collection of usefull geometry utilities.\n *\n * @global\n **/\nexports.geomutils = {\n /**\n * Map any angle (any numeric value) to [0, Math.PI).\n *\n * @param {number} angle - The numeric value to map.\n * @return {number} The mapped angle inside [0,PI*2].\n **/\n mapAngleTo2PI: function (angle) {\n // Source: https://forums.codeguru.com/showthread.php?384172-get-angle-into-range-0-2*pi\n var new_angle = Math.asin(Math.sin(angle));\n if (Math.cos(angle) < 0) {\n return Math.PI - new_angle;\n }\n else if (new_angle < 0) {\n return new_angle + 2 * Math.PI;\n }\n else {\n return new_angle;\n }\n },\n /**\n * Calculate the euclidean distance between two points given by four coordinates (two coordinates each).\n *\n * @param {number} x1\n * @param {number} y1\n * @param {number} x2\n * @param {number} y2\n * @returns {number}\n */\n dist4: function (x1, y1, x2, y2) {\n return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y1 - y2, 2));\n },\n /**\n * Map any angle (any numeric value) to [0, Math.PI).\n *\n * A × B := (A.x * B.x) + (A.y * B.y)\n *\n * @param {XYCoords} vertA - The first vertex.\n * @param {XYCoords} vertB - The second vertex.\n * @return {number} The dot product of the two vertices.\n **/\n dotProduct: function (vertA, vertB) {\n return vertA.x * vertB.x + vertA.y * vertB.y;\n },\n /**\n * Compute the n-section of the angle – described as a triangle (A,B,C) – in point A.\n *\n * @param {Vertex} pA - The first triangle point.\n * @param {Vertex} pB - The second triangle point.\n * @param {Vertex} pC - The third triangle point.\n * @param {number} n - The number of desired angle sections (example: 2 means the angle will be divided into two sections,\n * means an returned array with length 1, the middle line).\n *\n * @return {Line[]} An array of n-1 lines secting the given angle in point A into n equal sized angle sections. The lines' first vertex is A.\n */\n nsectAngle: function (pA, pB, pC, n) {\n var triangle = new Triangle_1.Triangle(pA, pB, pC);\n var lineAB = new Line_1.Line(pA, pB);\n var lineAC = new Line_1.Line(pA, pC);\n // Compute the difference; this is the angle between AB and AC\n var insideAngle = lineAB.angle(lineAC);\n // We want the inner angles of the triangle, not the outer angle;\n // which one is which depends on the triangle 'direction'\n var clockwise = triangle.determinant() > 0;\n // For convenience convert the angle [-PI,PI] to [0,2*PI]\n if (insideAngle < 0)\n insideAngle = 2 * Math.PI + insideAngle;\n if (!clockwise)\n insideAngle = (2 * Math.PI - insideAngle) * -1;\n // Scale the rotated lines to the max leg length (looks better)\n var lineLength = Math.max(lineAB.length(), lineAC.length());\n var scaleFactor = lineLength / lineAB.length();\n var result = [];\n for (var i = 1; i < n; i++) {\n // Compute the i-th inner sector line\n result.push(new Line_1.Line(pA, pB.clone().rotate(-i * (insideAngle / n), pA)).scale(scaleFactor));\n }\n return result;\n },\n /**\n * Wrap the value (e.g. an angle) into the given range of [0,max).\n *\n * @name wrapMax\n * @param {number} x - The value to wrap.\n * @param {number} max - The max bound to use for the range.\n * @return {number} The wrapped value inside the range [0,max).\n */\n wrapMax: function (x, max) {\n // Found at\n // https://stackoverflow.com/questions/4633177/c-how-to-wrap-a-float-to-the-interval-pi-pi\n return (max + (x % max)) % max;\n },\n /**\n * Wrap the value (e.g. an angle) into the given range of [min,max).\n *\n * @name wrapMinMax\n * @param {number} x - The value to wrap.\n * @param {number} min - The min bound to use for the range.\n * @param {number} max - The max bound to use for the range.\n * @return {number} The wrapped value inside the range [min,max).\n */\n // Currently un-used\n wrapMinMax: function (x, min, max) {\n return min + exports.geomutils.wrapMax(x - min, max - min);\n }\n};\n//# sourceMappingURL=geomutils.js.map","\"use strict\";\n/**\n * Draws elements into an SVG node.\n *\n * Note that this library uses buffers and draw cycles. To draw onto an SVG canvas, do this:\n * const drawLib = new drawutilssvg( svgNode, ... );\n * const fillLib = drawLib.copyInstance(true);\n * // Begin draw cycle\n * drawLib.beginDrawCycle(time);\n * // ... draw or fill your stuff ...\n * drawLib.endDrawCycle(time); // Here the elements become visible\n *\n * @author Ikaros Kappler\n * @date 2021-01-03\n * @modified 2021-01-24 Fixed the `fillShapes` attribute in the copyInstance function.\n * @modified 2021-01-26 Changed the `isPrimary` (default true) attribute to `isSecondary` (default false).\n * @modified 2021-02-03 Added the static `createSvg` function.\n * @modified 2021-02-03 Fixed the currentId='background' bug on the clear() function.\n * @modified 2021-02-03 Fixed CSSProperty `stroke-width` (was line-width before, which is wrong).\n * @modified 2021-02-03 Added the static `HEAD_XML` attribute.\n * @modified 2021-02-19 Added the static helper function `transformPathData(...)` for svg path transformations (scale and translate).\n * @modified 2021-02-22 Added the static helper function `copyPathData(...)`.\n * @modified 2021-02-22 Added the `path` drawing function to draw SVG path data.\n * @modified 2021-03-01 Fixed a bug in the `clear` function (curClassName was not cleared).\n * @modified 2021-03-29 Fixed a bug in the `text` function (second y param was wrong, used x here).\n * @modified 2021-03-29 Moved this file from `src/ts/utils/helpers/` to `src/ts/`.\n * @modified 2021-03-31 Added 'ellipseSector' the the class names.\n * @modified 2021-03-31 Implemented buffering using a buffer <g> node and the beginDrawCycle and endDrawCycle methods.\n * @modified 2021-05-31 Added the `setConfiguration` function from `DrawLib`.\n * @modified 2021-11-15 Adding more parameters tot the `text()` function: fontSize, textAlign, fontFamily, lineHeight.\n * @modified 2021-11-19 Fixing the `label(text,x,y)` position.\n * @modified 2021-11-19 Added the `color` param to the `label(...)` function.\n * @modified 2022-02-03 Added the `lineWidth` param to the `crosshair` function.\n * @modified 2022-02-03 Added the `cross(...)` function.\n * @modified 2022-03-26 Added the private `nodeDefs` and `bufferedNodeDefs` attributes.\n * @modified 2022-03-26 Added the `texturedPoly` function to draw textures polygons.\n * @modified 2022-07-26 Adding `alpha` to the `image(...)` function.\n * @modified 2022-11-10 Tweaking some type issues.\n * @modified 2023-02-04 Fixed a typo in the CSS classname for cubic Bézier paths: cubicBezier (was cubierBezier).\n * @modified 2023-02-10 The methods `setCurrentClassName` and `setCurrentId` also accept `null` now.\n * @modified 2023-09-29 Added initialization checks for null parameters.\n * @modified 2023-09-29 Added a missing implementation to the `drawurilssvg.do(XYCoords,string)` function. Didn't draw anything.\n * @modified 2023-09-29 Downgrading all `Vertex` param type to the more generic `XYCoords` type in these render functions: line, arrow, texturedPoly, cubicBezier, cubicBezierPath, handle, handleLine, dot, point, circle, circleArc, ellipse, grid, raster.\n * @modified 2023-09-29 Added the `headLength` parameter to the 'DrawLib.arrow()` function.\n * @modified 2023-09-29 Added the `arrowHead(...)` function to the 'DrawLib.arrow()` interface.\n * @modified 2023-09-29 Added the `cubicBezierArrow(...)` function to the 'DrawLib.arrow()` interface.\n * @modified 2023-10-04 Adding `strokeOptions` param to these draw function: line, arrow, cubicBezierArrow, cubicBezier, cubicBezierPath, circle, circleArc, ellipse, square, rect, polygon, polyline.\n * @modified 2024-01-30 Fixing an issue with immutable style sets; changes to the global draw config did not reflect here (do now).\n * @modified 2024-03-10 Fixing some types for Typescript 5 compatibility.\n * @modified 2024-07-24 Caching custom style defs in a private buffer variable.\n * @modified 2025-11-14 Fixing a bug in the CSS `mix-blend-mode` property handling (caused a runtime error).\n * @modified 2026-01-04 Adding `lineJoin` attribute to the methods' `StrokeOptions` param.\n * @modified 2026-01-04 Fixing missing `strokeOptions` param in the `drawutilssvg.polygon` method.\n * @modified 2026-03-18 Adding `isOpen` parameter to `cubicBezierPath` draw method.\n * @modified 2026-04-04 Added the method `bounds`.\n * @modified 2026-04-04 Handling the `stroke-linecap` option now from the `StrokeOptions` interface.\n * @modified 2026-04-04 Chaning the `copyPathData` method by usind `Array.slice()`.\n * @version 1.7.0\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.drawutilssvg = void 0;\nvar CircleSector_1 = require(\"./CircleSector\");\nvar CubicBezierCurve_1 = require(\"./CubicBezierCurve\");\nvar Vertex_1 = require(\"./Vertex\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar Vector_1 = require(\"./Vector\");\nvar RAD_TO_DEG = 180 / Math.PI;\n/**\n * @classdesc A helper class for basic SVG drawing operations. This class should\n * be compatible to the default 'draw' class.\n *\n * @requires CubicBzierCurvce\n * @requires Polygon\n * @requires Vertex\n * @requires XYCoords\n */\nvar drawutilssvg = /** @class */ (function () {\n /**\n * Passed from primary to secondary instance.\n */\n //private nodeStyle: SVGStyleElement;\n /**\n * The constructor.\n *\n * @constructor\n * @name drawutilssvg\n * @param {SVGElement} svgNode - The SVG node to use.\n * @param {XYCoords} offset - The draw offset to use.\n * @param {XYCoords} scale - The scale factors to use.\n * @param {XYDimension} canvasSize - The initial canvas size (use setSize to change).\n * @param {boolean} fillShapes - Indicates if the constructed drawutils should fill all drawn shapes (if possible).\n * @param {DrawConfig} drawConfig - The default draw config to use for CSS fallback styles.\n * @param {boolean=} isSecondary - (optional) Indicates if this is the primary or secondary instance. Only primary instances manage child nodes.\n * @param {SVGGElement=} gNode - (optional) Primary and seconday instances share the same &lt;g> node.\n **/\n function drawutilssvg(svgNode, offset, scale, canvasSize, fillShapes, drawConfig, isSecondary, gNode, bufferGNode, nodeDefs, bufferNodeDefs, nodeStyle) {\n this.svgNode = svgNode;\n this.offset = new Vertex_1.Vertex(0, 0).set(offset);\n this.scale = new Vertex_1.Vertex(1, 1).set(scale);\n this.fillShapes = fillShapes;\n this.isSecondary = Boolean(isSecondary);\n this.drawConfig = drawConfig;\n this.drawlibConfiguration = {};\n this.cache = new Map();\n this.setSize(canvasSize);\n if (isSecondary) {\n if (!gNode || !bufferGNode || !nodeDefs || !bufferNodeDefs) {\n throw \"Cannot create secondary svg draw lib with undefinde gNode|bufferGNode|nodeDefs|bufferNodeDefs.\";\n }\n this.gNode = gNode;\n this.bufferGNode = bufferGNode;\n this.nodeDefs = nodeDefs;\n this.bufferedNodeDefs = bufferNodeDefs;\n if (nodeStyle) {\n this.nodeStyle = nodeStyle;\n }\n }\n else {\n this.addStyleDefs(drawConfig);\n this.addDefsNode();\n this.gNode = this.createSVGNode(\"g\");\n this.bufferGNode = this.createSVGNode(\"g\");\n this.svgNode.appendChild(this.gNode);\n }\n }\n /**\n * Adds a default style defintion based on the passed DrawConfig.\n * Twaek the draw config to change default colors or line thicknesses.\n *\n * @param {DrawConfig} drawConfig\n */\n drawutilssvg.prototype.addStyleDefs = function (drawConfig) {\n this.nodeStyle = this.createSVGNode(\"style\");\n this.svgNode.appendChild(this.nodeStyle);\n this.rebuildStyleDefs(drawConfig);\n };\n /**\n * This method is required to re-define the global style defs. It is needed\n * if any value in the DrawConfig changed in the meantime.\n * @param drawConfig\n */\n drawutilssvg.prototype.rebuildStyleDefs = function (drawConfig) {\n // Which default styles to add? -> All from the DrawConfig.\n // Compare with DrawConfig interface\n var keys = {\n \"bezier\": \"CubicBezierCurve\",\n //\"bezierPath\": \"BezierPath\", // TODO: is this correct?\n \"polygon\": \"Polygon\",\n \"triangle\": \"Triangle\",\n \"ellipse\": \"Ellipse\",\n \"ellipseSector\": \"EllipseSector\",\n \"circle\": \"Circle\",\n \"circleSector\": \"CircleSector\",\n \"vertex\": \"Vertex\",\n \"line\": \"Line\",\n \"vector\": \"Vector\",\n \"image\": \"Image\",\n \"text\": \"Text\"\n };\n // Question: why isn't this working if the svgNode is created dynamically? (nodeStyle.sheet is null)\n var rules = [];\n // console.log(\"drawConfig\", drawConfig);\n for (var k in keys) {\n var className = keys[k];\n var drawSettings = drawConfig[k];\n if (drawSettings) {\n rules.push(\".\".concat(className, \" { fill : none; stroke: \").concat(drawSettings.color, \"; stroke-width: \").concat(drawSettings.lineWidth, \"px }\"));\n }\n else {\n console.warn(\"Warning: your draw config is missing the key '\".concat(k, \"' which is required.\"));\n }\n }\n if (this.customStyleDefs) {\n rules.push(\"\\n/* Custom styles */\\n\");\n this.customStyleDefs.forEach(function (value, key) {\n rules.push(key + \" { \" + value + \" }\");\n });\n // this.nodeStyle.innerHTML += \"\\n/* Custom styles */\\n\" + rules.join(\"\\n\");\n }\n this.nodeStyle.innerHTML = rules.join(\"\\n\");\n };\n /**\n * Adds the internal <defs> node.\n */\n drawutilssvg.prototype.addDefsNode = function () {\n this.nodeDefs = this.createSVGNode(\"defs\");\n // this.svgNode.appendChild(this.nodeDefs);\n this.bufferedNodeDefs = this.createSVGNode(\"defs\");\n this.svgNode.appendChild(this.nodeDefs);\n };\n /**\n * This is a simple way to include custom CSS class mappings to the style defs of the generated SVG.\n *\n * The mapping should be of the form\n * [style-class] -> [style-def-string]\n *\n * Example:\n * \"rect.red\" -> \"fill: #ff0000; border: 1px solid red\"\n *\n * @param {Map<string,string>} defs\n */\n drawutilssvg.prototype.addCustomStyleDefs = function (defs) {\n this.customStyleDefs = defs;\n };\n /**\n * Retieve an old (cached) element.\n * Only if both – key and nodeName – match, the element will be returned (null otherwise).\n *\n * @method findElement\n * @private\n * @memberof drawutilssvg\n * @instance\n * @param {UID} key - The key of the desired element (used when re-drawing).\n * @param {string} nodeName - The expected node name.\n */\n drawutilssvg.prototype.findElement = function (key, nodeName) {\n if (!key) {\n return null;\n }\n var node = this.cache.get(key);\n if (node && node.nodeName.toUpperCase() === nodeName.toUpperCase()) {\n this.cache.delete(key);\n return node;\n }\n return null;\n };\n /**\n * Create a new DOM node &lt;svg&gt; in the SVG namespace.\n *\n * @method createSVGNode\n * @private\n * @memberof drawutilssvg\n * @instance\n * @param {string} nodeName - The node name (tag-name).\n * @return {SVGElement} A new element in the SVG namespace with the given node name.\n */\n drawutilssvg.prototype.createSVGNode = function (nodeName) {\n return document.createElementNS(\"http://www.w3.org/2000/svg\", nodeName);\n };\n /**\n * Make a new SVG node (or recycle an old one) with the given node name (circle, path, line, rect, ...).\n *\n * This function is used in draw cycles to re-use old DOM nodes (in hope to boost performance).\n *\n * @method makeNode\n * @private\n * @instance\n * @memberof drawutilssvg\n * @param {string} nodeName - The node name.\n * @return {SVGElement} The new node, which is not yet added to any document.\n */\n drawutilssvg.prototype.makeNode = function (nodeName) {\n // Try to find node in current DOM cache.\n // Unique node keys are strictly necessary.\n // Try to recycle an old element from cache.\n var node = this.findElement(this.curId, nodeName);\n if (!node) {\n // If no such old elements exists (key not found, tag name not matching),\n // then create a new one.\n node = this.createSVGNode(nodeName);\n }\n if (this.drawlibConfiguration.blendMode) {\n var blendMode = node.style[\"mix-blend-mode\"];\n if (typeof blendMode === \"function\") {\n blendMode(this.drawlibConfiguration.blendMode);\n }\n else {\n node.style[\"mix-blend-mode\"] = this.drawlibConfiguration.blendMode;\n }\n }\n // if (this.lineDashEnabled && this.lineDash && this.lineDash.length > 0 && drawutilssvg.nodeSupportsLineDash(nodeName)) {\n // node.setAttribute(\"stroke-dasharray\", this.lineDash.join(\" \"));\n // }\n return node;\n };\n /**\n * This is the final helper function for drawing and filling stuff and binding new\n * nodes to the SVG document.\n * It is not intended to be used from the outside.\n *\n * When in draw mode it draws the current shape.\n * When in fill mode it fills the current shape.\n *\n * This function is usually only called internally.\n *\n * @method _bindFillDraw\n * @private\n * @instance\n * @memberof drawutilssvg\n * @param {SVGElement} node - The node to draw/fill and bind.\n * @param {string} className - The class name(s) to use.\n * @param {string} color - A stroke/fill color to use.\n * @param {number=1} lineWidth - (optional) A line width to use for drawing (default is 1).\n * @return {SVGElement} The node itself (for chaining).\n */\n drawutilssvg.prototype._bindFillDraw = function (node, className, color, lineWidth, strokeOptions) {\n this._configureNode(node, className, this.fillShapes, color, lineWidth, strokeOptions);\n return this._bindNode(node, undefined);\n };\n /**\n * Bind this given node to a parent. If no parent is passed then the global\n * node buffer will be used.\n *\n * @method _bindNode\n * @private\n * @instance\n * @memberof drawutilssvg\n * @param {SVGElement} node - The SVG node to bind.\n * @param {SVGElement=} bindingParent - (optional) You may pass node other than the glober buffer node.\n * @returns {SVGElement} The passed node itself.\n */\n drawutilssvg.prototype._bindNode = function (node, bindingParent) {\n if (!node.parentNode) {\n // Attach to DOM only if not already attached\n (bindingParent !== null && bindingParent !== void 0 ? bindingParent : this.bufferGNode).appendChild(node);\n }\n return node;\n };\n /**\n * Add custom CSS class names and the globally defined CSS classname to the\n * given node.\n *\n * @method addCSSClasses\n * @private\n * @instance\n * @memberof drawutilssvg\n * @param {SVGElement} node - The SVG node to bind.\n * @param {string} className - The additional custom classname to add.\n * @returns {void}\n */\n drawutilssvg.prototype._addCSSClasses = function (node, className) {\n if (this.curClassName) {\n node.setAttribute(\"class\", \"\".concat(className, \" \").concat(this.curClassName));\n }\n else {\n node.setAttribute(\"class\", className);\n }\n };\n drawutilssvg.prototype._configureNode = function (node, className, fillMode, color, lineWidth, strokeOptions) {\n this._addCSSClasses(node, className);\n node.setAttribute(\"fill\", fillMode && color ? color : \"none\");\n node.setAttribute(\"stroke\", fillMode ? \"none\" : color || \"none\");\n node.setAttribute(\"stroke-width\", \"\".concat(lineWidth || 1));\n if (this.curId) {\n node.setAttribute(\"id\", \"\".concat(this.curId)); // Maybe React-style 'key' would be better?\n }\n this.applyStrokeOpts(node, strokeOptions);\n return node;\n };\n /**\n * Sets the size and view box of the document. Call this if canvas size changes.\n *\n * @method setSize\n * @instance\n * @memberof drawutilssvg\n * @param {XYDimension} canvasSize - The new canvas size.\n */\n drawutilssvg.prototype.setSize = function (canvasSize) {\n this.canvasSize = canvasSize;\n this.svgNode.setAttribute(\"viewBox\", \"0 0 \".concat(this.canvasSize.width, \" \").concat(this.canvasSize.height));\n this.svgNode.setAttribute(\"width\", \"\".concat(this.canvasSize.width));\n this.svgNode.setAttribute(\"height\", \"\".concat(this.canvasSize.height));\n };\n /**\n * Creates a 'shallow' (non deep) copy of this instance. This implies\n * that under the hood the same gl context and gl program will be used.\n */\n drawutilssvg.prototype.copyInstance = function (fillShapes) {\n var copy = new drawutilssvg(this.svgNode, this.offset, this.scale, this.canvasSize, fillShapes, this.drawConfig, // null as any as DrawConfig, // no DrawConfig – this will work as long as `isSecondary===true`\n true, // isSecondary\n this.gNode, this.bufferGNode, this.nodeDefs, this.bufferedNodeDefs, this.nodeStyle);\n return copy;\n };\n /**\n * Set the current drawlib configuration.\n *\n * @name setConfiguration\n * @method\n * @param {DrawLibConfiguration} configuration - The new configuration settings to use for the next render methods.\n */\n drawutilssvg.prototype.setConfiguration = function (configuration) {\n this.drawlibConfiguration = configuration;\n };\n /**\n * This method shouled be called each time the currently drawn `Drawable` changes.\n * It is used by some libraries for identifying elemente on re-renders.\n *\n * @name setCurrentId\n * @method\n * @param {UID|null} uid - A UID identifying the currently drawn element(s).\n * @instance\n * @memberof drawutilssvg\n **/\n drawutilssvg.prototype.setCurrentId = function (uid) {\n this.curId = uid;\n };\n /**\n * This method shouled be called each time the currently drawn `Drawable` changes.\n * Determine the class name for further usage here.\n *\n * @name setCurrentClassName\n * @method\n * @param {string|null} className - A class name for further custom use cases.\n * @instance\n * @memberof drawutilssvg\n **/\n drawutilssvg.prototype.setCurrentClassName = function (className) {\n this.curClassName = className;\n };\n /**\n * Called before each draw cycle.\n * This is required for compatibility with other draw classes in the library.\n *\n * @name beginDrawCycle\n * @method\n * @param {UID=} uid - (optional) A UID identifying the currently drawn element(s).\n * @instance\n * @memberof drawutilssvg\n **/\n drawutilssvg.prototype.beginDrawCycle = function (renderTime) {\n // Clear non-recycable elements from last draw cycle.\n this.cache.clear();\n // Clearing an SVG is equivalent to removing all its child elements.\n for (var i = 0; i < this.bufferGNode.childNodes.length; i++) {\n // Hide all nodes here. Don't throw them away.\n // We can probably re-use them in the next draw cycle.\n var child = this.bufferGNode.childNodes[i];\n this.cache.set(child.getAttribute(\"id\"), child);\n }\n this.removeAllChildNodes();\n };\n /**\n * Called after each draw cycle.\n *\n * This is required for compatibility with other draw classes in the library (like drawgl).\n *\n * @name endDrawCycle\n * @method\n * @param {number} renderTime\n * @instance\n **/\n drawutilssvg.prototype.endDrawCycle = function (renderTime) {\n this.rebuildStyleDefs(this.drawConfig);\n if (!this.isSecondary) {\n // All elements are drawn into the buffer; they are NOT yet visible, not did the browser perform any\n // layout updates.\n // Replace the old <g>-node with the buffer node.\n // https://stackoverflow.com/questions/27442464/how-to-update-a-svg-image-without-seeing-a-blinking\n this.svgNode.replaceChild(this.bufferedNodeDefs, this.nodeDefs);\n this.svgNode.replaceChild(this.bufferGNode, this.gNode);\n }\n var tmpGNode = this.gNode;\n this.gNode = this.bufferGNode;\n this.bufferGNode = tmpGNode;\n var tmpDefsNode = this.nodeDefs;\n this.nodeDefs = this.bufferedNodeDefs;\n this.bufferedNodeDefs = tmpDefsNode;\n };\n /**\n * A private helper method to apply stroke options to the current\n * context.\n * @param {StrokeOptions=} strokeOptions -\n */\n drawutilssvg.prototype.applyStrokeOpts = function (node, strokeOptions) {\n var _this = this;\n // Set line dash options?\n if (strokeOptions &&\n strokeOptions.dashArray &&\n strokeOptions.dashArray.length > 0 &&\n drawutilssvg.nodeSupportsLineDash(node.tagName)) {\n node.setAttribute(\"stroke-dasharray\", strokeOptions.dashArray\n .map(function (dashArayElem) {\n return dashArayElem * _this.scale.x;\n })\n .join(\" \"));\n if (strokeOptions.dashOffset) {\n node.setAttribute(\"stroke-dashoffset\", \"\".concat(strokeOptions.dashOffset * this.scale.x));\n }\n }\n // Set line join option?\n if (strokeOptions && strokeOptions.lineJoin && drawutilssvg.nodeSupportsLineJoin(node.tagName)) {\n node.setAttribute(\"stroke-linejoin\", strokeOptions.lineJoin);\n }\n // Set lineCap option?\n if (strokeOptions && strokeOptions.lineCap && drawutilssvg.nodeSupportsLineCap(node.tagName)) {\n node.setAttribute(\"stroke-linecap\", strokeOptions.lineCap);\n }\n };\n drawutilssvg.prototype._x = function (x) {\n return this.offset.x + this.scale.x * x;\n };\n drawutilssvg.prototype._y = function (y) {\n return this.offset.y + this.scale.y * y;\n };\n /**\n * Draw the line between the given two points with the specified (CSS-) color.\n *\n * @method line\n * @param {XYCoords} zA - The start point of the line.\n * @param {XYCoords} zB - The end point of the line.\n * @param {string} color - Any valid CSS color string.\n * @param {number=1} lineWidth? - [optional] The line's width.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n **/\n drawutilssvg.prototype.line = function (zA, zB, color, lineWidth, strokeOptions) {\n // const line: SVGElement = this.makeNode(\"line\");\n // this.applyStrokeOpts(line, strokeOptions);\n // line.setAttribute(\"x1\", `${this._x(zA.x)}`);\n // line.setAttribute(\"y1\", `${this._y(zA.y)}`);\n // line.setAttribute(\"x2\", `${this._x(zB.x)}`);\n // line.setAttribute(\"y2\", `${this._y(zB.y)}`);\n var line = this.makeLineNode(zA, zB, color, lineWidth, strokeOptions);\n return this._bindFillDraw(line, \"line\", color, lineWidth || 1, strokeOptions);\n };\n /**\n * Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.\n *\n * @method arrow\n * @param {XYCoords} zA - The start point of the arrow-line.\n * @param {XYCoords} zB - The end point of the arrow-line.\n * @param {string} color - Any valid CSS color string.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {headLength=8} headLength - (optional) The length of the arrow head (default is 8 units).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n **/\n drawutilssvg.prototype.arrow = function (zA, zB, color, lineWidth, headLength, strokeOptions) {\n if (headLength === void 0) { headLength = 8; }\n var group = this.makeNode(\"g\");\n var arrowHeadBasePosition = { x: 0, y: 0 };\n // Just create the child nodes, don't bind them to the root node.\n var arrowHead = this.makeArrowHeadNode(zA, zB, color, lineWidth, headLength, undefined, arrowHeadBasePosition);\n var line = this.makeLineNode(zA, arrowHeadBasePosition, color, lineWidth, strokeOptions);\n group.appendChild(line);\n group.appendChild(arrowHead);\n this._addCSSClasses(group, \"linear-arrow\");\n this._bindNode(group, undefined);\n return group;\n };\n /**\n * Draw a cubic Bézier curve and and an arrow at the end (endControlPoint) of the given line width the specified (CSS-) color and arrow size.\n *\n * @method cubicBezierArrow\n * @param {XYCoords} startPoint - The start point of the cubic Bézier curve\n * @param {XYCoords} endPoint - The end point the cubic Bézier curve.\n * @param {XYCoords} startControlPoint - The start control point the cubic Bézier curve.\n * @param {XYCoords} endControlPoint - The end control point the cubic Bézier curve.\n * @param {string} color - The CSS color to draw the curve with.\n * @param {number} lineWidth - (optional) The line width to use.\n * @param {headLength=8} headLength - (optional) The length of the arrow head (default is 8 units).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof DrawLib\n */\n drawutilssvg.prototype.cubicBezierArrow = function (startPoint, endPoint, startControlPoint, endControlPoint, color, lineWidth, headLength, strokeOptions) {\n if (headLength === void 0) { headLength = 8; }\n var group = this.makeNode(\"g\");\n // Just create the child nodes, don't bind them to the root node.\n var arrowHeadBasePosition = new Vertex_1.Vertex(0, 0);\n var arrowHead = this.makeArrowHeadNode(endControlPoint, endPoint, color, lineWidth, headLength, undefined, arrowHeadBasePosition);\n var diff = arrowHeadBasePosition.difference(endPoint);\n var bezier = this.makeCubicBezierNode(startPoint, { x: endPoint.x - diff.x, y: endPoint.y - diff.y }, startControlPoint, { x: endControlPoint.x - diff.x, y: endControlPoint.y - diff.y }, color, lineWidth, strokeOptions);\n group.appendChild(bezier);\n group.appendChild(arrowHead);\n this._addCSSClasses(group, \"cubicbezier-arrow\");\n this._bindNode(group, undefined);\n return group;\n };\n /**\n * Draw just an arrow head a the end of an imaginary line (zB) of the given line width the specified (CSS-) color and size.\n *\n * @method arrow\n * @param {XYCoords} zA - The start point of the arrow-line.\n * @param {XYCoords} zB - The end point of the arrow-line.\n * @param {string} color - Any valid CSS color string.\n * @param {number=1} lineWidth - (optional) The line width to use; default is 1.\n * @param {number=8} headLength - (optional) The length of the arrow head (default is 8 pixels).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof DrawLib\n **/\n drawutilssvg.prototype.arrowHead = function (zA, zB, color, lineWidth, headLength, strokeOptions) {\n if (headLength === void 0) { headLength = 8; }\n var node = this.makeArrowHeadNode(zA, zB, color, lineWidth, headLength, strokeOptions);\n return this._bindFillDraw(node, \"arrowhead\", color, lineWidth || 1, strokeOptions);\n };\n /**\n * Draw an image at the given position with the given size.<br>\n * <br>\n * Note: SVG images may have resizing issues at the moment.Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.\n *\n * @method image\n * @param {Image} image - The image object to draw.\n * @param {XYCoords} position - The position to draw the the upper left corner at.\n * @param {XYCoords} size - The x/y-size to draw the image with.\n * @param {number=0.0} alpha - (optional, default=0.0) The transparency (1.0=opaque, 0.0=transparent).\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n **/\n drawutilssvg.prototype.image = function (image, position, size, alpha) {\n var _this = this;\n if (alpha === void 0) { alpha = 1.0; }\n var node = this.makeNode(\"image\");\n // We need to re-adjust the image if it was not yet fully loaded before.\n var setImageSize = function (image) {\n if (image.naturalWidth) {\n var ratioX = size.x / image.naturalWidth;\n var ratioY = size.y / image.naturalHeight;\n node.setAttribute(\"width\", \"\".concat(image.naturalWidth * _this.scale.x));\n node.setAttribute(\"height\", \"\".concat(image.naturalHeight * _this.scale.y));\n node.setAttribute(\"display\", null); // Dislay when loaded\n // if (alpha) {\n node.setAttribute(\"opacity\", \"\".concat(alpha));\n // }\n node.setAttribute(\"transform\", \"translate(\".concat(_this._x(position.x), \" \").concat(_this._y(position.y), \") scale(\").concat(ratioX, \" \").concat(ratioY, \")\"));\n }\n };\n image.addEventListener(\"load\", function (event) {\n setImageSize(image);\n });\n // Safari has a transform-origin bug.\n // Use x=0, y=0 and translate/scale instead (see above)\n node.setAttribute(\"x\", \"\".concat(0));\n node.setAttribute(\"y\", \"\".concat(0));\n node.setAttribute(\"display\", \"none\"); // Hide before loaded\n setImageSize(image);\n node.setAttribute(\"href\", image.src);\n return this._bindFillDraw(node, \"image\", null, null);\n };\n /**\n * Draw an image at the given position with the given size.<br>\n * <br>\n * Note: SVG images may have resizing issues at the moment.Draw a line and an arrow at the end (zB) of the given line with the specified (CSS-) color.\n *\n * @method texturedPoly\n * @param {Image} textureImage - The image object to draw.\n * @param {Bounds} textureSize - The texture size to use; these are the original bounds to map the polygon vertices to.\n * @param {Polygon} polygon - The polygon to use as clip path.\n * @param {XYCoords} polygonPosition - The polygon's position (relative), measured at the bounding box's center.\n * @param {number} rotation - The rotation to use for the polygon (and for the texture).\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n **/\n drawutilssvg.prototype.texturedPoly = function (textureImage, textureSize, polygon, polygonPosition, rotation) {\n // const basePolygonBounds: Bounds = polygon.getBounds();\n var rotatedScalingOrigin = new Vertex_1.Vertex(textureSize.min).clone().rotate(rotation, polygonPosition);\n // const rotationCenter = polygonPosition.clone().add(rotatedScalingOrigin.difference(textureSize.min).inv());\n // Create something like this\n // ...\n // <defs>\n // <clipPath id=\"shape\">\n // <path fill=\"none\" d=\"...\"/>\n // </clipPath>\n // </defs>\n // ...\n // <g clip-path=\"url(#shape)\">\n // <g transform=\"scale(...)\">\n // <image width=\"643\" height=\"643\" transform=\"rotate(...)\" xlink:href=\"https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/beagle400.jpg\" >\n // </g>\n // </g>\n // </image>\n // ...\n var clipPathNode = this.makeNode(\"clipPath\");\n var clipPathId = \"clippath_\".concat(UIDGenerator_1.UIDGenerator.next()); // TODO: use a better UUID generator here?\n clipPathNode.setAttribute(\"id\", clipPathId);\n var gNode = this.makeNode(\"g\");\n var imageNode = this.makeNode(\"image\");\n imageNode.setAttribute(\"x\", \"\".concat(this._x(rotatedScalingOrigin.x)));\n imageNode.setAttribute(\"y\", \"\".concat(this._y(rotatedScalingOrigin.y)));\n imageNode.setAttribute(\"width\", \"\".concat(textureSize.width));\n imageNode.setAttribute(\"height\", \"\".concat(textureSize.height));\n imageNode.setAttribute(\"href\", textureImage.src);\n // imageNode.setAttribute(\"opacity\", \"0.5\");\n // SVG rotations in degrees\n imageNode.setAttribute(\"transform\", \"rotate(\".concat(rotation * RAD_TO_DEG, \", \").concat(this._x(rotatedScalingOrigin.x), \", \").concat(this._y(rotatedScalingOrigin.y), \")\"));\n var pathNode = this.makeNode(\"path\");\n var pathData = [];\n if (polygon.vertices.length > 0) {\n var self_1 = this;\n pathData.push(\"M\", \"\".concat(this._x(polygon.vertices[0].x)), \"\".concat(this._y(polygon.vertices[0].y)));\n for (var i = 1; i < polygon.vertices.length; i++) {\n pathData.push(\"L\", \"\".concat(this._x(polygon.vertices[i].x)), \"\".concat(this._y(polygon.vertices[i].y)));\n }\n }\n pathNode.setAttribute(\"d\", pathData.join(\" \"));\n clipPathNode.appendChild(pathNode);\n this.bufferedNodeDefs.appendChild(clipPathNode);\n gNode.appendChild(imageNode);\n gNode.setAttribute(\"transform-origin\", \"\".concat(this._x(rotatedScalingOrigin.x), \" \").concat(this._y(rotatedScalingOrigin.y)));\n gNode.setAttribute(\"transform\", \"scale(\".concat(this.scale.x, \", \").concat(this.scale.y, \")\"));\n var clipNode = this.makeNode(\"g\");\n clipNode.appendChild(gNode);\n clipNode.setAttribute(\"clip-path\", \"url(#\".concat(clipPathId, \")\"));\n // TODO: check if the image class is correct here or if we should use a 'clippedImage' class here\n this._bindFillDraw(clipNode, \"image\", null, null); // No color, no lineWidth\n return clipNode;\n };\n /**\n * Draw the given (cubic) bézier curve.\n *\n * @method cubicBezier\n * @param {XYCoords} startPoint - The start point of the cubic Bézier curve\n * @param {XYCoords} endPoint - The end point the cubic Bézier curve.\n * @param {XYCoords} startControlPoint - The start control point the cubic Bézier curve.\n * @param {XYCoords} endControlPoint - The end control point the cubic Bézier curve.\n * @param {string} color - The CSS color to draw the curve with.\n * @param {number} lineWidth - (optional) The line width to use.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.cubicBezier = function (startPoint, endPoint, startControlPoint, endControlPoint, color, lineWidth, strokeOptions) {\n var node = this.makeCubicBezierNode(startPoint, endPoint, startControlPoint, endControlPoint, color, lineWidth, strokeOptions);\n return this._bindNode(node, undefined);\n };\n /**\n * Draw the given (cubic) Bézier path.\n *\n * The given path must be an array with n*3+1 vertices, where n is the number of\n * curves in the path:\n * <pre> [ point1, point1_startControl, point2_endControl, point2, point2_startControl, point3_endControl, point3, ... pointN_endControl, pointN ]</pre>\n *\n * @method cubicBezierPath\n * @param {XYCoords[]} path - The cubic bezier path as described above.\n * @param {string} color - The CSS colot to draw the path with.\n * @param {number=1} lineWidth - (optional) The line width to use.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n * @param {boolean} isOpen - (optional) Set to tur if the path should not be closed.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.cubicBezierPath = function (path, color, lineWidth, strokeOptions, isOpen) {\n var node = this.makeNode(\"path\");\n this.applyStrokeOpts(node, strokeOptions);\n if (!path || path.length == 0) {\n return node;\n }\n // Draw curve\n var d = [\"M\", this._x(path[0].x), this._y(path[0].y)];\n // Draw curve path\n var endPoint;\n var startControlPoint;\n var endControlPoint;\n for (var i = 1; i < path.length; i += 3) {\n startControlPoint = path[i];\n endControlPoint = path[i + 1];\n endPoint = path[i + 2];\n d.push(\"C\", this._x(startControlPoint.x), this._y(startControlPoint.y), this._x(endControlPoint.x), this._y(endControlPoint.y), this._x(endPoint.x), this._y(endPoint.y));\n }\n if (!isOpen) {\n d.push(\"Z\");\n }\n node.setAttribute(\"d\", d.join(\" \"));\n return this._bindFillDraw(node, \"cubicBezierPath\", color, lineWidth || 1);\n };\n /**\n * Draw the given handle and handle point (used to draw interactive Bézier curves).\n *\n * The colors for this are fixed and cannot be specified.\n *\n * @method handle\n * @param {Vertex} startPoint - The start of the handle.\n * @param {Vertex} endPoint - The end point of the handle.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.handle = function (startPoint, endPoint) {\n // TODO: redefine methods like these into an abstract class?\n this.point(startPoint, \"rgb(0,32,192)\");\n this.square(endPoint, 5, \"rgba(0,128,192,0.5)\");\n };\n /**\n * Draw a handle line (with a light grey).\n *\n * @method handleLine\n * @param {XYCoords} startPoint - The start point to draw the handle at.\n * @param {XYCoords} endPoint - The end point to draw the handle at.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.handleLine = function (startPoint, endPoint) {\n this.line(startPoint, endPoint, \"rgb(128,128,128,0.5)\");\n };\n /**\n * Draw a 1x1 dot with the specified (CSS-) color.\n *\n * @method dot\n * @param {XYCoords} p - The position to draw the dot at.\n * @param {string} color - The CSS color to draw the dot with.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.dot = function (p, color) {\n var node = this.makeNode(\"line\");\n node.setAttribute(\"x1\", \"\".concat(this._x(p.x)));\n node.setAttribute(\"y1\", \"\".concat(this._y(p.y)));\n node.setAttribute(\"x2\", \"\".concat(this._x(p.x)));\n node.setAttribute(\"y2\", \"\".concat(this._y(p.y)));\n return this._bindFillDraw(node, \"dot\", color, 1);\n };\n /**\n * Draw the given point with the specified (CSS-) color and radius 3.\n *\n * @method point\n * @param {XYCoords} p - The position to draw the point at.\n * @param {string} color - The CSS color to draw the point with.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.point = function (p, color) {\n var radius = 3;\n var node = this.makeNode(\"circle\");\n node.setAttribute(\"cx\", \"\".concat(this._x(p.x)));\n node.setAttribute(\"cy\", \"\".concat(this._y(p.y)));\n node.setAttribute(\"r\", \"\".concat(radius));\n return this._bindFillDraw(node, \"point\", color, 1);\n };\n /**\n * Draw a circle with the specified (CSS-) color and radius.<br>\n * <br>\n * Note that if the x- and y- scales are different the result will be an ellipse rather than a circle.\n *\n * @method circle\n * @param {XYCoords} center - The center of the circle.\n * @param {number} radius - The radius of the circle.\n * @param {string} color - The CSS color to draw the circle with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.circle = function (center, radius, color, lineWidth, strokeOptions) {\n // Todo: draw ellipse when scalex!=scaley\n var node = this.makeNode(\"circle\");\n this.applyStrokeOpts(node, strokeOptions);\n node.setAttribute(\"cx\", \"\".concat(this._x(center.x)));\n node.setAttribute(\"cy\", \"\".concat(this._y(center.y)));\n node.setAttribute(\"r\", \"\".concat(radius * this.scale.x)); // y?\n return this._bindFillDraw(node, \"circle\", color, lineWidth || 1);\n };\n /**\n * Draw a circular arc (section of a circle) with the given CSS color.\n *\n * @method circleArc\n * @param {XYCoords} center - The center of the circle.\n * @param {number} radius - The radius of the circle.\n * @param {number} startAngle - The angle to start at.\n * @param {number} endAngle - The angle to end at.\n * @param {string} color - The CSS color to draw the circle with.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.circleArc = function (center, radius, startAngle, endAngle, color, lineWidth, strokeOptions) {\n var node = this.makeNode(\"path\");\n this.applyStrokeOpts(node, strokeOptions);\n var arcData = CircleSector_1.CircleSector.circleSectorUtils.describeSVGArc(this._x(center.x), this._y(center.y), radius * this.scale.x, // y?\n startAngle, endAngle);\n node.setAttribute(\"d\", arcData.join(\" \"));\n return this._bindFillDraw(node, \"circleArc\", color, lineWidth || 1);\n };\n /**\n * Draw an ellipse with the specified (CSS-) color and thw two radii.\n *\n * @method ellipse\n * @param {XYCoords} center - The center of the ellipse.\n * @param {number} radiusX - The radius of the ellipse.\n * @param {number} radiusY - The radius of the ellipse.\n * @param {string} color - The CSS color to draw the ellipse with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {number=} rotation - (optional, default=0) The rotation of the ellipse.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.ellipse = function (center, radiusX, radiusY, color, lineWidth, rotation, strokeOptions) {\n if (typeof rotation === \"undefined\") {\n rotation = 0.0;\n }\n var node = this.makeNode(\"ellipse\");\n this.applyStrokeOpts(node, strokeOptions);\n node.setAttribute(\"cx\", \"\".concat(this._x(center.x)));\n node.setAttribute(\"cy\", \"\".concat(this._y(center.y)));\n node.setAttribute(\"rx\", \"\".concat(radiusX * this.scale.x));\n node.setAttribute(\"ry\", \"\".concat(radiusY * this.scale.y));\n // node.setAttribute( 'style', `transform: rotate(${rotation} ${center.x} ${center.y})` );\n node.setAttribute(\"transform\", \"rotate(\".concat((rotation * 180) / Math.PI, \" \").concat(this._x(center.x), \" \").concat(this._y(center.y), \")\"));\n return this._bindFillDraw(node, \"ellipse\", color, lineWidth || 1);\n };\n /**\n * Draw square at the given center, size and with the specified (CSS-) color.<br>\n * <br>\n * Note that if the x-scale and the y-scale are different the result will be a rectangle rather than a square.\n *\n * @method square\n * @param {XYCoords} center - The center of the square.\n * @param {number} size - The size of the square.\n * @param {string} color - The CSS color to draw the square with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {SVGElement}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.square = function (center, size, color, lineWidth, strokeOptions) {\n var node = this.makeNode(\"rectangle\");\n this.applyStrokeOpts(node, strokeOptions);\n node.setAttribute(\"x\", \"\".concat(this._x(center.x - size / 2.0)));\n node.setAttribute(\"y\", \"\".concat(this._y(center.y - size / 2.0)));\n node.setAttribute(\"width\", \"\".concat(size * this.scale.x));\n node.setAttribute(\"height\", \"\".concat(size * this.scale.y));\n return this._bindFillDraw(node, \"square\", color, lineWidth || 1);\n };\n /**\n * Draw a rectangle.\n *\n * @param {XYCoords} position - The upper left corner of the rectangle.\n * @param {number} width - The width of the rectangle.\n * @param {number} height - The height of the rectangle.\n * @param {string} color - The color to use.\n * @param {number=1} lineWidth - (optional) The line with to use (default is 1).\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {SVGElement}\n * @instance\n * @memberof drawutilssvg\n **/\n drawutilssvg.prototype.rect = function (position, width, height, color, lineWidth, strokeOptions) {\n var node = this.makeNode(\"rect\");\n this.applyStrokeOpts(node, strokeOptions);\n node.setAttribute(\"x\", \"\".concat(this._x(position.x)));\n node.setAttribute(\"y\", \"\".concat(this._y(position.y)));\n node.setAttribute(\"width\", \"\".concat(width * this.scale.x));\n node.setAttribute(\"height\", \"\".concat(height * this.scale.y));\n return this._bindFillDraw(node, \"rect\", color, lineWidth || 1);\n };\n /**\n * Draw a rectangle at the given bounds; and with the specified line width and (CSS-) color.<br>\n *\n * @method bounds\n * @param {IBounds} bounds - The bounds rectangle to be drawn.\n * @param {string} color - The CSS color to draw the rectangle with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {R}\n * @instance\n * @memberof DrawLib\n */\n drawutilssvg.prototype.bounds = function (bounds, color, lineWidth, strokeOptions) {\n this.rect(bounds.min, bounds.max.x - bounds.min.x, bounds.max.y - bounds.min.y, color, lineWidth, strokeOptions);\n };\n /**\n * Draw a grid of horizontal and vertical lines with the given (CSS-) color.\n *\n * @method grid\n * @param {XYCoords} center - The center of the grid.\n * @param {number} width - The total width of the grid (width/2 each to the left and to the right).\n * @param {number} height - The total height of the grid (height/2 each to the top and to the bottom).\n * @param {number} sizeX - The horizontal grid size.\n * @param {number} sizeY - The vertical grid size.\n * @param {string} color - The CSS color to draw the grid with.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.grid = function (center, width, height, sizeX, sizeY, color) {\n // console.log(\"grid\");\n // const node: SVGElement = this.makeNode(\"pattern\");\n // var patternId = \"pattern_id_\" + Math.floor(Math.random() * 65365);\n // node.setAttribute(\"id\", patternId);\n // node.setAttribute(\"viewBox\", `0,0,${sizeX},${sizeY}`);\n // node.setAttribute(\"width\", `${sizeX}`);\n // node.setAttribute(\"height\", `${sizeX}`);\n // var pattern: SVGElement = this.makeNode(\"path\");\n // const d: SVGPathParams = [];\n // d.push(\"M\", sizeX / 2.0, 0);\n // d.push(\"L\", sizeX / 2.0, sizeY);\n // d.push(\"M\", 0, sizeY / 2.0);\n // d.push(\"L\", sizeX, sizeY / 2.0);\n // node.setAttribute(\"d\", d.join(\" \"));\n // this.bufferedNodeDefs.append(pattern);\n // const fillNode: SVGElement = this.makeNode(\"rect\");\n // // For some strange reason SVG rotation transforms use degrees instead of radians\n // // Note that the background does not scale with the zoom level (always covers full element)\n // fillNode.setAttribute(\"x\", \"0\");\n // fillNode.setAttribute(\"y\", \"0\");\n // fillNode.setAttribute(\"width\", `${this.canvasSize.width}`);\n // fillNode.setAttribute(\"height\", `${this.canvasSize.height}`);\n // fillNode.setAttribute(\"fill\", `url(#${patternId})`);\n // return this._bindFillDraw(fillNode, \"grid\", \"red\", 1);\n var node = this.makeNode(\"path\");\n var d = [];\n var yMin = -Math.ceil((height * 0.5) / sizeY) * sizeY;\n var yMax = height / 2;\n for (var x = -Math.ceil((width * 0.5) / sizeX) * sizeX; x < width / 2; x += sizeX) {\n d.push(\"M\", this._x(center.x + x), this._y(center.y + yMin));\n d.push(\"L\", this._x(center.x + x), this._y(center.y + yMax));\n }\n var xMin = -Math.ceil((width * 0.5) / sizeX) * sizeX;\n var xMax = width / 2;\n for (var y = -Math.ceil((height * 0.5) / sizeY) * sizeY; y < height / 2; y += sizeY) {\n d.push(\"M\", this._x(center.x + xMin), this._y(center.y + y));\n d.push(\"L\", this._x(center.x + xMax), this._y(center.y + y));\n }\n node.setAttribute(\"d\", d.join(\" \"));\n return this._bindFillDraw(node, \"grid\", color, 1);\n };\n /**\n * Draw a raster of crosshairs in the given grid.<br>\n *\n * This works analogue to the grid() function\n *\n * @method raster\n * @param {XYCoords} center - The center of the raster.\n * @param {number} width - The total width of the raster (width/2 each to the left and to the right).\n * @param {number} height - The total height of the raster (height/2 each to the top and to the bottom).\n * @param {number} sizeX - The horizontal raster size.\n * @param {number} sizeY - The vertical raster size.\n * @param {string} color - The CSS color to draw the raster with.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.raster = function (center, width, height, sizeX, sizeY, color) {\n var node = this.makeNode(\"path\");\n var d = [];\n for (var x = -Math.ceil((width * 0.5) / sizeX) * sizeX; x < width / 2; x += sizeX) {\n for (var y = -Math.ceil((height * 0.5) / sizeY) * sizeY; y < height / 2; y += sizeY) {\n // Draw a crosshair\n d.push(\"M\", this._x(center.x + x) - 4, this._y(center.y + y));\n d.push(\"L\", this._x(center.x + x) + 4, this._y(center.y + y));\n d.push(\"M\", this._x(center.x + x), this._y(center.y + y) - 4);\n d.push(\"L\", this._x(center.x + x), this._y(center.y + y) + 4);\n }\n }\n node.setAttribute(\"d\", d.join(\" \"));\n return this._bindFillDraw(node, \"raster\", color, 1);\n };\n /**\n * Draw a diamond handle (square rotated by 45°) with the given CSS color.\n *\n * It is an inherent featur of the handle functions that the drawn elements are not scaled and not\n * distorted. So even if the user zooms in or changes the aspect ratio, the handles will be drawn\n * as even shaped diamonds.\n *\n * @method diamondHandle\n * @param {XYCoords} center - The center of the diamond.\n * @param {number} size - The x/y-size of the diamond.\n * @param {string} color - The CSS color to draw the diamond with.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.diamondHandle = function (center, size, color) {\n var node = this.makeNode(\"path\");\n var d = [\n \"M\",\n this._x(center.x) - size / 2.0,\n this._y(center.y),\n \"L\",\n this._x(center.x),\n this._y(center.y) - size / 2.0,\n \"L\",\n this._x(center.x) + size / 2.0,\n this._y(center.y),\n \"L\",\n this._x(center.x),\n this._y(center.y) + size / 2.0,\n \"Z\"\n ];\n node.setAttribute(\"d\", d.join(\" \"));\n return this._bindFillDraw(node, \"diamondHandle\", color, 1);\n };\n /**\n * Draw a square handle with the given CSS color.<br>\n * <br>\n * It is an inherent featur of the handle functions that the drawn elements are not scaled and not\n * distorted. So even if the user zooms in or changes the aspect ratio, the handles will be drawn\n * as even shaped squares.\n *\n * @method squareHandle\n * @param {XYCoords} center - The center of the square.\n * @param {XYCoords} size - The x/y-size of the square.\n * @param {string} color - The CSS color to draw the square with.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.squareHandle = function (center, size, color) {\n var node = this.makeNode(\"rect\");\n node.setAttribute(\"x\", \"\".concat(this._x(center.x) - size / 2.0));\n node.setAttribute(\"y\", \"\".concat(this._y(center.y) - size / 2.0));\n node.setAttribute(\"width\", \"\".concat(size));\n node.setAttribute(\"height\", \"\".concat(size));\n return this._bindFillDraw(node, \"squareHandle\", color, 1);\n };\n /**\n * Draw a circle handle with the given CSS color.<br>\n * <br>\n * It is an inherent featur of the handle functions that the drawn elements are not scaled and not\n * distorted. So even if the user zooms in or changes the aspect ratio, the handles will be drawn\n * as even shaped circles.\n *\n * @method circleHandle\n * @param {XYCoords} center - The center of the circle.\n * @param {number} radius - The radius of the circle.\n * @param {string} color - The CSS color to draw the circle with.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.circleHandle = function (center, radius, color) {\n radius = radius || 3;\n var node = this.makeNode(\"circle\");\n node.setAttribute(\"cx\", \"\".concat(this._x(center.x)));\n node.setAttribute(\"cy\", \"\".concat(this._y(center.y)));\n node.setAttribute(\"r\", \"\".concat(radius));\n return this._bindFillDraw(node, \"circleHandle\", color, 1);\n };\n /**\n * Draw a crosshair with given radius and color at the given position.<br>\n * <br>\n * Note that the crosshair radius will not be affected by scaling.\n *\n * @method crosshair\n * @param {XYCoords} center - The center of the crosshair.\n * @param {number} radius - The radius of the crosshair.\n * @param {string} color - The CSS color to draw the crosshair with.\n * @param {number=0.5} lineWidth - (optional, default=0.5) The line width to use.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.crosshair = function (center, radius, color, lineWidth) {\n var node = this.makeNode(\"path\");\n var d = [\n \"M\",\n this._x(center.x) - radius,\n this._y(center.y),\n \"L\",\n this._x(center.x) + radius,\n this._y(center.y),\n \"M\",\n this._x(center.x),\n this._y(center.y) - radius,\n \"L\",\n this._x(center.x),\n this._y(center.y) + radius\n ];\n node.setAttribute(\"d\", d.join(\" \"));\n return this._bindFillDraw(node, \"crosshair\", color, lineWidth || 0.5);\n };\n /**\n * Draw a cross with diagonal axes with given radius, color and lineWidth at the given position.<br>\n * <br>\n * Note that the x's radius will not be affected by scaling.\n *\n * @method crosshair\n * @param {XYCoords} center - The center of the crosshair.\n * @param {number} radius - The radius of the crosshair.\n * @param {string} color - The CSS color to draw the crosshair with.\n * @param {number=1} lineWidth - (optional, default=1.0) The line width to use.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilssvg.prototype.cross = function (center, radius, color, lineWidth) {\n var node = this.makeNode(\"path\");\n var d = [\n \"M\",\n this._x(center.x) - radius,\n this._y(center.y) - radius,\n \"L\",\n this._x(center.x) + radius,\n this._y(center.y) + radius,\n \"M\",\n this._x(center.x) - radius,\n this._y(center.y) + radius,\n \"L\",\n this._x(center.x) + radius,\n this._y(center.y) - radius\n ];\n node.setAttribute(\"d\", d.join(\" \"));\n return this._bindFillDraw(node, \"cross\", color, lineWidth || 1.0);\n };\n /**\n * Draw a polygon.\n *\n * @method polygon\n * @param {Polygon} polygon - The polygon to draw.\n * @param {string} color - The CSS color to draw the polygon with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.polygon = function (polygon, color, lineWidth, strokeOptions) {\n return this.polyline(polygon.vertices, polygon.isOpen, color, lineWidth, strokeOptions);\n };\n /**\n * Draw a polygon line (alternative function to the polygon).\n *\n * @method polyline\n * @param {XYCoords[]} vertices - The polygon vertices to draw.\n * @param {boolan} isOpen - If true the polyline will not be closed at its end.\n * @param {string} color - The CSS color to draw the polygon with.\n * @param {number=} lineWidth - (optional) The line width to use; default is 1.\n * @param {StrokeOptions=} strokeOptions - (optional) Stroke settings to use.\n *\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.polyline = function (vertices, isOpen, color, lineWidth, strokeOptions) {\n var node = this.makeNode(\"path\");\n this.applyStrokeOpts(node, strokeOptions);\n if (vertices.length == 0) {\n return node;\n }\n // Draw curve\n var d = [\"M\", this._x(vertices[0].x), this._y(vertices[0].y)];\n var n = vertices.length;\n for (var i = 1; i < n; i++) {\n d.push(\"L\", this._x(vertices[i].x), this._y(vertices[i].y));\n }\n if (!isOpen)\n d.push(\"Z\");\n node.setAttribute(\"d\", d.join(\" \"));\n return this._bindFillDraw(node, \"polygon\", color, lineWidth || 1);\n };\n /**\n * Draw a text at the given relative position.\n *\n * @method text\n * @param {string} text - The text to draw.\n * @param {number} x - The x-position to draw the text at.\n * @param {number} y - The y-position to draw the text at.\n * @param {string=} options.color - The Color to use.\n * @param {string=} options.fontFamily - The font family to use.\n * @param {number=} options.fontSize - The font size (in pixels) to use.\n * @param {FontStyle=} options.fontStyle - The font style to use.\n * @param {FontWeight=} options.fontWeight - The font weight to use.\n * @param {number=} options.lineHeight - The line height (in pixels) to use.\n * @param {number=} options.rotation - The (optional) rotation in radians.\n * @param {string=} options.textAlign - The text align to use. According to the specifiactions (https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign) valid values are `\"left\" || \"right\" || \"center\" || \"start\" || \"end\"`.\n * @return {void}\n * @instance\n * @memberof drawutils\n */\n drawutilssvg.prototype.text = function (text, x, y, options) {\n var _a, _b, _c;\n options = options || {};\n var color = options.color || \"black\";\n var lineHeight = ((_b = (_a = options.lineHeight) !== null && _a !== void 0 ? _a : options.fontSize) !== null && _b !== void 0 ? _b : 0) * this.scale.x;\n // https://www.w3.org/TR/SVG/text.html#TextAnchorProperty\n // start | middle | end\n var textAlign = options.textAlign === \"left\" || options.textAlign === \"start\"\n ? \"start\"\n : options.textAlign === \"center\"\n ? \"middle\"\n : options.textAlign === \"right\" || options.textAlign === \"end\"\n ? \"end\"\n : \"start\";\n var transformOrigin = \"\".concat(this._x(x), \"px \").concat(this._y(y), \"px\");\n var translate = \"translate(\".concat(this._x(x), \" \").concat(this._y(y) + lineHeight / 2, \")\");\n // Safari has a transform-origin/rotation bug.\n // It's essential to use rotate(r,x,y) here. \"rotate(r)\"\" with transform-origin(x,y) won't do the job.\n // And rotate and translate cannot be used is combination on a text object.\n // So wrap the text inside a <g>, translate the <g>, and rotate the text inside.\n var rotate = options.rotation ? \"rotate(\".concat(options.rotation * RAD_TO_DEG, \" 0 0)\") : \"\";\n var node = this.makeNode(\"g\");\n var curId = this.curId;\n this.curId = curId + \"_text\";\n var textNode = this.makeNode(\"text\");\n node.appendChild(textNode);\n textNode.setAttribute(\"font-family\", (_c = options.fontFamily) !== null && _c !== void 0 ? _c : \"\"); // May be undefined\n textNode.setAttribute(\"font-size\", options.fontSize ? \"\".concat(options.fontSize * this.scale.x) : \"\");\n textNode.setAttribute(\"font-style\", options.fontStyle ? \"\".concat(options.fontStyle) : \"\");\n textNode.setAttribute(\"font-weight\", options.fontWeight ? \"\".concat(options.fontWeight) : \"\");\n textNode.setAttribute(\"text-anchor\", textAlign);\n textNode.setAttribute(\"transform-origin\", \"0 0\");\n textNode.setAttribute(\"transform\", rotate);\n node.setAttribute(\"transform-origin\", transformOrigin);\n node.setAttribute(\"transform\", translate);\n textNode.innerHTML = text;\n // Restore old ID\n this.curId = curId;\n return this._bindFillDraw(node, \"text\", color, 1);\n };\n /**\n * Draw a non-scaling text label at the given position.\n *\n * @method label\n * @param {string} text - The text to draw.\n * @param {number} x - The x-position to draw the text at.\n * @param {number} y - The y-position to draw the text at.\n * @param {number=} rotation - The (optional) rotation in radians.\n * @param {string=\"black\"} color - The color to use (default is black).\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.label = function (text, x, y, rotation, color) {\n var node = this.makeNode(\"text\");\n // For some strange reason SVG rotation transforms use degrees instead of radians\n node.setAttribute(\"transform\", \"translate(\".concat(x, \",\").concat(y, \"), rotate(\").concat(((rotation || 0) / Math.PI) * 180, \")\"));\n node.setAttribute(\"font-family\", \"Arial\");\n node.setAttribute(\"font-size\", \"9pt\");\n node.setAttribute(\"font-style\", \"normal\");\n node.setAttribute(\"font-weight\", \"lighter\");\n node.innerHTML = text;\n return this._bindFillDraw(node, \"label\", color || \"black\", null);\n };\n /**\n * Draw an SVG-like path given by the specified path data.\n *\n * @method path\n * @param {SVGPathData} pathData - An array of path commands and params.\n * @param {string=null} color - (optional) The color to draw this path with (default is null).\n * @param {number=1} lineWidth - (optional) the line width to use (default is 1).\n * @param {boolean=false} options.inplace - (optional) If set to true then path transforamtions (scale and translate) will be done in-place in the array. This can boost the performance.\n * @param {number=} options.dashOffset - (optional) `See StrokeOptions`.\n * @param {number=[]} options.dashArray - (optional) `See StrokeOptions`.\n *\n * @instance\n * @memberof drawutils\n * @return {R} An instance representing the drawn path.\n */\n drawutilssvg.prototype.path = function (pathData, color, lineWidth, options) {\n var node = this.makeNode(\"path\");\n this.applyStrokeOpts(node, options);\n // Transform the path: in-place (fast) or copy (slower)\n var d = options && options.inplace ? pathData : drawutilssvg.copyPathData(pathData);\n drawutilssvg.transformPathData(d, this.offset, this.scale);\n node.setAttribute(\"d\", d.join(\" \"));\n return this._bindFillDraw(node, \"path\", color, lineWidth);\n };\n /**\n * Due to gl compatibility there is a generic 'clear' function required\n * to avoid accessing the context object itself directly.\n *\n * This function just fills the whole canvas with a single color.\n *\n * @param {string} color - The color to clear with.\n * @return {void}\n * @instance\n * @memberof drawutilssvg\n **/\n drawutilssvg.prototype.clear = function (color) {\n // If this isn't the primary handler then do not remove anything here.\n // The primary handler will do that (no double work).\n if (this.isSecondary) {\n return;\n }\n // Add a covering rect with the given background color\n this.curId = \"background\";\n this.curClassName = null; // undefined;\n var node = this.makeNode(\"rect\");\n // For some strange reason SVG rotation transforms use degrees instead of radians\n // Note that the background does not scale with the zoom level (always covers full element)\n node.setAttribute(\"x\", \"0\");\n node.setAttribute(\"y\", \"0\");\n node.setAttribute(\"width\", \"\".concat(this.canvasSize.width));\n node.setAttribute(\"height\", \"\".concat(this.canvasSize.height));\n // Bind this special element into the document\n this._bindFillDraw(node, this.curId, null, null);\n node.setAttribute(\"fill\", typeof color === \"undefined\" ? \"none\" : color);\n // Clear the current ID again\n this.curId = null; // undefined;\n };\n /**\n * A private helper function to clear all SVG nodes from the &gt;g> node.\n *\n * @private\n */\n drawutilssvg.prototype.removeAllChildNodes = function () {\n while (this.bufferGNode.lastChild) {\n this.bufferGNode.removeChild(this.bufferGNode.lastChild);\n }\n while (this.bufferedNodeDefs.lastChild) {\n this.bufferedNodeDefs.removeChild(this.bufferedNodeDefs.lastChild);\n }\n };\n /**\n * Create a new and empty `SVGElement` &lt;svg&gt; in the svg-namespace.\n *\n * @name createSvg\n * @static\n * @memberof drawutilssvg\n * @return SVGElement\n */\n drawutilssvg.createSvg = function () {\n return document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n };\n /**\n * Create a copy of the given path data. As path data only consists of strings and numbers,\n * the copy will be shallow by definition.\n *\n * @name copyPathData\n * @static\n * @memberof drawutilssvg\n */\n drawutilssvg.copyPathData = function (data) {\n // To create a shallow copy we can just use the `slice` method.\n return data.slice();\n };\n /**\n * Transform the given path data (translate and scale. rotating is not intended here).\n *\n * @name transformPathData\n * @static\n * @memberof drawutilssvg\n * @param {SVGPathParams} data - The data to transform.\n * @param {XYCoords} offset - The translation offset (neutral is x=0, y=0).\n * @param {XYCoords} scale - The scale factors (neutral is x=1, y=1).\n */\n drawutilssvg.transformPathData = function (data, offset, scale) {\n // Scale and translate {x,y}\n var _stx = function (index) {\n data[index] = offset.x + scale.x * Number(data[index]);\n };\n var _sty = function (index) {\n data[index] = offset.y + scale.y * Number(data[index]);\n };\n // scale only {x,y}\n var _sx = function (index) {\n data[index] = scale.x * Number(data[index]);\n };\n var _sy = function (index) {\n data[index] = scale.y * Number(data[index]);\n };\n var i = 0;\n var lastPoint = { x: NaN, y: NaN };\n // \"save last point\"\n var _slp = function (index) {\n lastPoint.x = Number(data[index]);\n lastPoint.y = Number(data[index + 1]);\n };\n while (i < data.length) {\n var cmd = data[i];\n switch (cmd) {\n case \"M\":\n // MoveTo: M|m x y\n case \"L\":\n // LineTo L|l x y\n case \"T\":\n // Shorthand/smooth quadratic Bézier curveto: T|t x y\n _stx(i + 1);\n _sty(i + 2);\n _slp(i + 1);\n i += 3;\n break;\n case \"m\":\n // MoveTo: M|m x y\n case \"l\":\n // LineTo L|l x y\n case \"t\":\n // Shorthand/smooth quadratic Bézier curveto: T|t x y\n _sx(i + 1);\n _sy(i + 2);\n _slp(i + 1);\n i += 3;\n break;\n case \"H\":\n // HorizontalLineTo: H|h x\n _stx(i + 1);\n lastPoint.x = Number(data[i + 1]);\n i += 2;\n break;\n case \"h\":\n // HorizontalLineTo: H|h x\n _sx(i + 1);\n lastPoint.x = Number(data[i + 1]);\n i += 2;\n break;\n case \"V\":\n // VerticalLineTo: V|v y\n _sty(i + 1);\n lastPoint.y = Number(data[i + 1]);\n i += 2;\n break;\n case \"v\":\n // VerticalLineTo: V|v y\n _sy(i + 1);\n lastPoint.y = Number(data[i + 1]);\n i += 2;\n break;\n case \"C\":\n // CurveTo: C|c x1 y1 x2 y2 x y\n _stx(i + 1);\n _sty(i + 2);\n _stx(i + 3);\n _sty(i + 4);\n _stx(i + 5);\n _sty(i + 6);\n _slp(i + 5);\n i += 7;\n break;\n case \"c\":\n // CurveTo: C|c x1 y1 x2 y2 x y\n _sx(i + 1);\n _sy(i + 2);\n _sx(i + 3);\n _sy(i + 4);\n _sx(i + 5);\n _sy(i + 6);\n _slp(i + 5);\n i += 7;\n break;\n case \"S\":\n case \"Q\":\n // Shorthand-/SmoothCurveTo: S|s x2 y2 x y\n // QuadraticCurveTo: Q|q x1 y1 x y\n _stx(i + 1);\n _sty(i + 2);\n _stx(i + 3);\n _sty(i + 4);\n _slp(i + 3);\n i += 5;\n break;\n case \"s\":\n case \"q\":\n // Shorthand-/SmoothCurveTo: S|s x2 y2 x y\n // QuadraticCurveTo: Q|q x1 y1 x y\n _sx(i + 1);\n _sy(i + 2);\n _sx(i + 3);\n _sy(i + 4);\n _slp(i + 3);\n i += 5;\n break;\n case \"A\":\n // EllipticalArcTo: A|a rx ry x-axis-rotation large-arc-flag sweep-flag x y\n // Uniform scale: just scale\n // NOTE: here is something TODO\n // * if scalex!=scaleY this won't work\n // * Arcs have to be converted to Bézier curves here in that case\n _sx(i + 1);\n _sy(i + 2);\n _stx(i + 6);\n _sty(i + 7);\n _slp(i + 6);\n // Update the arc flag when x _or_ y scale is negative\n if ((scale.x < 0 && scale.y >= 0) || (scale.x >= 0 && scale.y < 0)) {\n data[i + 5] = data[i + 5] ? 0 : 1;\n }\n i += 8;\n break;\n case \"a\":\n // EllipticalArcTo: A|a rx ry x-axis-rotation large-arc-flag sweep-flag x y\n _sx(i + 1);\n _sy(i + 2);\n _sx(i + 6);\n _sy(i + 7);\n _slp(i + 6);\n i += 8;\n break;\n case \"z\":\n case \"Z\":\n // ClosePath: Z|z (no arguments)\n // lastPoint.x = firstPoint.x;\n // lastPoint.y = firstPoint.y;\n i++;\n break;\n // Safepoint: continue reading token by token until something is recognized again\n default:\n i++;\n }\n } // END while\n }; // END transformPathData\n drawutilssvg.nodeSupportsLineDash = function (nodeName) {\n return [\"line\", \"path\", \"circle\", \"ellipse\", \"rectangle\", \"rect\"].includes(nodeName);\n };\n drawutilssvg.nodeSupportsLineJoin = function (nodeName) {\n return [\"line\", \"path\", \"circle\", \"ellipse\", \"rectangle\", \"rect\"].includes(nodeName);\n };\n drawutilssvg.nodeSupportsLineCap = function (nodeName) {\n return [\"line\", \"path\", \"circle\", \"ellipse\", \"rectangle\", \"rect\"].includes(nodeName);\n };\n /**\n * Creates a basic <line> node with start and end coordinates. The created node will not\n * be bound to any root node.\n *\n * @private\n * @method makeLineNode\n * @param {XYCoords} zA - The line's start position.\n * @param {XYCoords} zB - The line's start position.\n * @param {string} color - The CSS color to draw the point with.\n * @param {number=1} lineWidth - (optional) The line width to use.\n * @param {StrokeOptions=} strokeOptions - (optional) Additional stroke options to use.\n * @param {string=} classNameOverride - (optional) If nothing is passed the default classname 'path' will be used.\n * @return {SVGLineElement}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.makeLineNode = function (zA, zB, color, lineWidth, strokeOptions, classNameOverride) {\n var line = this.makeNode(\"line\");\n line.setAttribute(\"x1\", \"\".concat(this._x(zA.x)));\n line.setAttribute(\"y1\", \"\".concat(this._y(zA.y)));\n line.setAttribute(\"x2\", \"\".concat(this._x(zB.x)));\n line.setAttribute(\"y2\", \"\".concat(this._y(zB.y)));\n this._configureNode(line, classNameOverride !== null && classNameOverride !== void 0 ? classNameOverride : \"line\", this.fillShapes, color, lineWidth || 1, strokeOptions);\n return line;\n };\n /**\n * Creates a basic <path> node with given path string data. The created node will not\n * be bound to any root node.\n *\n * @private\n * @method makePathNode\n * @param {string} pathString - The path data (must be a valid path data string).\n * @param {string} color - The CSS color to draw the point with.\n * @param {number=1} lineWidth - (optional) The line width to use.\n * @param {StrokeOptions=} strokeOptions - (optional) Additional stroke options to use.\n * @param {string=} classNameOverride - (optional) If nothing is passed the default classname 'path' will be used.\n * @return {SVGPathElement}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.makePathNode = function (pathString, color, lineWidth, strokeOptions, classNameOverride) {\n var path = this.makeNode(\"path\");\n path.setAttribute(\"d\", pathString);\n this._configureNode(path, classNameOverride !== null && classNameOverride !== void 0 ? classNameOverride : \"path\", this.fillShapes, color, lineWidth || 1, strokeOptions);\n return path;\n };\n /**\n * Creates a basic arrow head node (<path> node) at the end of the given line coordinates. The created node will not\n * be bound to any root node.\n *\n * @private\n * @method makeArrowHeadNode\n * @param {string} pathString - The path data (must be a valid path data string).\n * @param {string} color - The CSS color to draw the point with.\n * @param {number=1} lineWidth - (optional) The line width to use.\n * @param {number=8} headLength - (optional) The length of the arrow head; if none is specified then the head will be 8 absolute units long.\n * @param {StrokeOptions=} strokeOptions - (optional) Additional stroke options to use.\n * @param {XYCoords=} arrowHeadBasePositionBuffer - (optional) If not null, then this position will contain the arrow head's start point (after execution). Some sort of OUT variable.\n * @return {SVGPathElement}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.makeArrowHeadNode = function (zA, zB, color, lineWidth, headLength, strokeOptions, arrowHeadBasePositionBuffer) {\n if (headLength === void 0) { headLength = 8; }\n var vertices = Vector_1.Vector.utils.buildArrowHead(zA, zB, headLength, this.scale.x, this.scale.y);\n var d = [\"M\", this.offset.x + vertices[0].x, this.offset.y + vertices[0].y];\n if (arrowHeadBasePositionBuffer) {\n arrowHeadBasePositionBuffer.x = vertices[0].x / this.scale.x;\n arrowHeadBasePositionBuffer.y = vertices[0].y / this.scale.y;\n }\n for (var i = 1; i <= vertices.length; i++) {\n d.push(\"L\");\n // Note: only use offset here (the vertices are already scaled)\n d.push(this.offset.x + vertices[i % vertices.length].x);\n d.push(this.offset.y + vertices[i % vertices.length].y);\n }\n var node = this.makePathNode(d.join(\" \"), color, lineWidth, strokeOptions, \"arrowhead\");\n return node;\n };\n /**\n * Creates a basic cubic Bézier path node (<path> node) with the given cubic Bézier data. The created node will not\n * be bound to any root node.\n *\n * @private\n * @method makeCubicBezierNode\n * @param {XYCoords} startPoint - The start point of the cubic Bézier curve\n * @param {XYCoords} endPoint - The end point the cubic Bézier curve.\n * @param {XYCoords} startControlPoint - The start control point the cubic Bézier curve.\n * @param {XYCoords} endControlPoint - The end control point the cubic Bézier curve.\n * @param {string} color - The CSS color to draw the point with.\n * @param {number=1} lineWidth - (optional) The line width to use.\n * @param {StrokeOptions=} strokeOptions - (optional) Additional stroke options to use.\n * @param {string=} classNameOverride - (optional) If nothing is passed the default classname 'path' will be used.\n * @param {XYCoords=} arrowHeadBasePositionBuffer - (optional) If not null, then this position will contain the arrow head's start point (after execution). Some sort of OUT variable.\n * @return {SVGPathElement}\n * @instance\n * @memberof drawutilssvg\n */\n drawutilssvg.prototype.makeCubicBezierNode = function (startPoint, endPoint, startControlPoint, endControlPoint, color, lineWidth, strokeOptions) {\n if (startPoint instanceof CubicBezierCurve_1.CubicBezierCurve) {\n return this.cubicBezier(startPoint.startPoint, startPoint.endPoint, startPoint.startControlPoint, startPoint.endControlPoint, color, lineWidth);\n }\n // Draw curve\n var d = [\n \"M\",\n this._x(startPoint.x),\n this._y(startPoint.y),\n \"C\",\n this._x(startControlPoint.x),\n this._y(startControlPoint.y),\n this._x(endControlPoint.x),\n this._y(endControlPoint.y),\n this._x(endPoint.x),\n this._y(endPoint.y)\n ];\n var node = this.makePathNode(d.join(\" \"), color, lineWidth, strokeOptions, \"cubicBezier\");\n return node;\n };\n drawutilssvg.HEAD_XML = [\n '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>',\n '<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" ',\n ' \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">',\n \"\"\n ].join(\"\\n\");\n return drawutilssvg;\n}());\nexports.drawutilssvg = drawutilssvg;\n//# sourceMappingURL=drawutilssvg.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2018-08-26\n * @modified 2018-11-17 Added the 'isSelected' attribute.\n * @modified 2018-11-27 Added the global model for instantiating with custom attributes.\n * @modified 2019-03-20 Added JSDoc tags.\n * @modified 2020-02-29 Added the 'selectable' attribute.\n * @modified 2020-03-23 Ported to Typescript from JS.\n * @modified 2024-03-10 Fixed some types for Typescript 5 compatibility.\n * @version 1.1.2\n *\n * @file VertexAttr\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.VertexAttr = void 0;\n/**\n * @classdesc The VertexAttr is a helper class to wrap together additional attributes\n * to vertices that do not belong to the 'standard canonical' vertex implementation.<br>\n * <br>\n * This is some sort of 'userData' object, but the constructor uses a global model\n * to obtain a (configurable) default attribute set to all instances.<br>\n */\nvar VertexAttr = /** @class */ (function () {\n /**\n * The constructor.\n *\n * Attributes will be initialized as defined in the model object\n * which serves as a singleton.\n *\n * @constructor\n * @name VertexAttr\n **/\n function VertexAttr() {\n this.draggable = true;\n this.selectable = true;\n this.isSelected = false;\n this.visible = true;\n for (var key in VertexAttr.model)\n this[key] = VertexAttr.model[key];\n }\n ;\n /**\n * This is the global attribute model. Set these object on the initialization\n * of your app to gain all VertexAttr instances have these attributes.\n *\n * @type {object}\n **/\n VertexAttr.model = {\n draggable: true,\n selectable: true,\n isSelected: false,\n visible: true\n };\n return VertexAttr;\n}());\nexports.VertexAttr = VertexAttr;\n//# sourceMappingURL=VertexAttr.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2018-11-11 (Alaaf)\n * @modified 2020-03-28 Ported this class from vanilla-JS to Typescript.\n * @modified 2020-07-28 Changed the `delete` key code from 8 to 46.\n * @modified 2020-10-04 Changed `window` to `globalThis`.\n * @modified 2020-10-04 Added extended JSDoc.\n * @modified 2022-02-02 Added the `destroy` method.\n * @version 1.1.0\n *\n * @file KeyHandler\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.KeyHandler = void 0;\n/**\n * @classdesc A generic key handler.\n *\n * Example\n * =======\n * @example\n * // Javascript\n *\tnew KeyHandler( { trackAll : true } )\n *\t .down('enter',function() { console.log('ENTER was hit.'); } )\n *\t .press('enter',function() { console.log('ENTER was pressed.'); } )\n *\t .up('enter',function() { console.log('ENTER was released.'); } )\n *\n * .down('e',function() { console.log('e was hit. shift is pressed?',keyHandler.isDown('shift')); } )\n *\n *\t .up('windows',function() { console.log('windows was released.'); } )\n *\t;\n */\nvar KeyHandler = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @instance\n * @memberof KeyHandler\n * @param {HTMLElement} options.element (optional) The HTML element to listen on; if null then 'window' will be used.\n * @param {boolean} options.trackAll (optional) Set to true if you want to keep track of _all_ keys (keyStatus).\n **/\n function KeyHandler(options) {\n this.downListeners = [];\n this.pressListeners = [];\n this.upListeners = [];\n this.keyStates = {};\n options = options || {};\n this.element = options.element ? options.element : globalThis;\n this.downListeners = [];\n this.pressListeners = [];\n this.upListeners = [];\n this.keyStates = [];\n // This could be made configurable in a later version. It allows to\n // keep track of the key status no matter if there are any listeners\n // on the key or not.\n this.trackAllKeys = options.trackAll || false;\n // Install the listeners\n this.installListeners();\n }\n /**\n * A helper function to fire key events from this KeyHandler.\n *\n * @param {KeyboardEvent} event - The key event to fire.\n * @param {Array<XKeyListener>} listener - The listeners to fire to.\n */\n KeyHandler.prototype.fireEvent = function (event, listeners) {\n var hasListener = false;\n for (var i in listeners) {\n var lis = listeners[i];\n if (lis.keyCode != event.keyCode)\n continue;\n lis.listener(event);\n hasListener = true;\n }\n return hasListener;\n };\n /**\n * Internal function to fire a new keydown event to all listeners.\n * You should not call this function on your own unless you know what you do.\n *\n * @name fireDownEvent\n * @memberof KeyHandler\n * @instance\n * @private\n * @param {KeyboardEvent} e\n * @param {KeyHandler} handler\n * @return {void}\n */\n KeyHandler.prototype.fireDownEvent = function (e, handler) {\n if (handler.fireEvent(e, handler.downListeners) || handler.trackAllKeys) {\n // Down event has listeners. Update key state.\n handler.keyStates[e.keyCode] = \"down\";\n }\n };\n /**\n * Internal function to fire a new keypress event to all listeners.\n * You should not call this function on your own unless you know what you do.\n *\n * @name firePressEvent\n * @memberof KeyHandler\n * @instance\n * @private\n * @param {KeyboardEvent} e\n * @param {KeyHandler} handler\n * @return void\n */\n KeyHandler.prototype.firePressEvent = function (e, handler) {\n handler.fireEvent(e, handler.pressListeners);\n };\n /**\n * Internal function to fire a new keyup event to all listeners.\n * You should not call this function on your own unless you know what you do.\n *\n * @name fireUpEvent\n * @memberof KeyHandler\n * @instance\n * @private\n * @param {KeyboardEvent} e\n * @param {KeyHandler} handler\n * @return {void}\n */\n KeyHandler.prototype.fireUpEvent = function (e, handler) {\n if (handler.fireEvent(e, handler.upListeners) || handler.trackAllKeys) {\n // Up event has listeners. Clear key state.\n delete handler.keyStates[e.keyCode];\n }\n };\n /**\n * Resolve the key/name code.\n */\n KeyHandler.key2code = function (key) {\n if (typeof key == \"number\")\n return key;\n if (typeof key != \"string\")\n throw \"Unknown key name or key type (should be a string or integer): \" + key;\n if (KeyHandler.KEY_CODES[key])\n return KeyHandler.KEY_CODES[key];\n throw \"Unknown key (cannot resolve key code): \" + key;\n };\n /**\n * Install the required listeners into the initially passed element.\n *\n * By default the listeners are installed into the root element specified on\n * construction (or 'window').\n */\n KeyHandler.prototype.installListeners = function () {\n var _self = this;\n this.element.addEventListener(\"keydown\", (this._keyDownListener = function (e) {\n _self.fireDownEvent(e, _self);\n }));\n this.element.addEventListener(\"keypress\", (this._keyPressListener = function (e) {\n _self.firePressEvent(e, _self);\n }));\n this.element.addEventListener(\"keyup\", (this._keyUpListener = function (e) {\n _self.fireUpEvent(e, _self);\n }));\n };\n /**\n * Remove all installed event listeners from the underlying element.\n */\n KeyHandler.prototype.releaseListeners = function () {\n this.element.removeEventListener(\"keydown\", this._keyDownListener);\n this.element.removeEventListener(\"keypress\", this._keyPressListener);\n this.element.removeEventListener(\"keyup\", this._keyUpListener);\n };\n /**\n * Listen for key down. This function allows chaining.\n *\n * Example: new KeyHandler().down('enter',function() {console.log('Enter hit.')});\n *\n * @name down\n * @memberof KeyHandler\n * @instance\n * @param {string|number} key - Any key identifier, key code or one from the KEY_CODES list.\n * @param {(e:KeyboardEvent)=>void} e - The callback to be triggered.\n * @return {KeyHandler} this\n */\n KeyHandler.prototype.down = function (key, listener) {\n this.downListeners.push({ key: key, keyCode: KeyHandler.key2code(key), listener: listener });\n return this;\n };\n /**\n * Listen for key press.\n *\n * Example: new KeyHandler().press('enter',function() {console.log('Enter pressed.')});\n *\n * @name press\n * @memberof KeyHandler\n * @instance\n * @param {string|number} key - Any key identifier, key code or one from the KEY_CODES list.\n * @param {(e:KeyboardEvent)=>void} listener - The callback to be triggered.\n * @return {KeyHandler} this\n */\n KeyHandler.prototype.press = function (key, listener) {\n this.pressListeners.push({ key: key, keyCode: KeyHandler.key2code(key), listener: listener });\n return this;\n };\n /**\n * Listen for key up.\n *\n * Example: new KeyHandler().up('enter',function() {console.log('Enter released.')});\n *\n * @name up\n * @memberof KeyHandler\n * @instance\n * @param {string} key - Any key identifier, key code or one from the KEY_CODES list.\n * @param {(e:KeyboardEvent)=>void)} e - The callback to be triggered.\n * @return {KeyHandler} this\n */\n KeyHandler.prototype.up = function (key, listener) {\n this.upListeners.push({ key: key, keyCode: KeyHandler.key2code(key), listener: listener });\n return this;\n };\n /**\n * Check if a specific key is currently held pressed.\n *\n * @param {string|number} key - Any key identifier, key code or one from the KEY_CODES list.\n */\n KeyHandler.prototype.isDown = function (key) {\n if (typeof key == \"number\")\n return this.keyStates[key] ? true : false;\n else\n return this.keyStates[KeyHandler.key2code(key)] ? true : false;\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used any more.\n */\n KeyHandler.prototype.destroy = function () {\n this.releaseListeners();\n };\n /**\n * Source:\n * https://keycode.info/\n */\n // prettier-ignore\n KeyHandler.KEY_CODES = {\n 'break': 3, // alternate: 19\n 'backspace': 8,\n // 'delete'\t : 8, // alternate: 46\n 'tab': 9,\n 'clear': 12,\n 'enter': 13,\n 'shift': 16,\n 'ctrl': 17,\n 'alt': 18,\n 'pause': 19,\n // 'break'\t : 19,\n 'capslock': 20,\n 'hangul': 21,\n 'hanja': 25,\n 'escape': 27,\n 'conversion': 28,\n 'non-conversion': 29, // alternate: 235?\n 'spacebar': 32,\n 'pageup': 33,\n 'pagedown': 34,\n 'end': 35,\n 'home': 36, // alternate: 172?\n 'leftarrow': 37,\n 'uparrow': 38,\n 'rightarrow': 39,\n 'downarrow': 40,\n 'select': 41,\n 'print': 42,\n 'execute': 43,\n 'printscreen': 44,\n 'insert': 45,\n 'delete': 46, // alternate: 8\n 'help': 47,\n '0': 48,\n '1': 49,\n '2': 50,\n '3': 51,\n '4': 52,\n '5': 53,\n '6': 54,\n '7': 55,\n '8': 56,\n '9': 57,\n ':': 58,\n 'semicolon (firefox)': 59,\n 'equals': 59,\n '<': 60,\n 'equals (firefox)': 61,\n 'ß': 63,\n '@ (firefox)': 64,\n 'a': 65,\n 'b': 66,\n 'c': 67,\n 'd': 68,\n 'e': 69,\n 'f': 70,\n 'g': 71,\n 'h': 72,\n 'i': 73,\n 'j': 74,\n 'k': 75,\n 'l': 76,\n 'm': 77,\n 'n': 78,\n 'o': 79,\n 'p': 80,\n 'q': 81,\n 'r': 82,\n 's': 83,\n 't': 84,\n 'u': 85,\n 'v': 86,\n 'w': 87,\n 'x': 88,\n 'y': 89,\n 'z': 90,\n 'windows': 91,\n 'leftcommand': 91, // left ⌘\n 'chromebooksearch': 91,\n 'rightwindowkey': 92,\n 'windowsmenu': 93,\n 'rightcommant': 93, // right ⌘\n 'sleep': 95,\n 'numpad0': 96,\n 'numpad1': 97,\n 'numpad2': 98,\n 'numpad3': 99,\n 'numpad4': 100,\n 'numpad5': 101,\n 'numpad6': 102,\n 'numpad7': 103,\n 'numpad8': 104,\n 'numpad9': 105,\n 'multiply': 106,\n 'add': 107,\n 'numpadperiod': 108, // firefox, 194 on chrome\n 'subtract': 109,\n 'decimalpoint': 110,\n 'divide': 111,\n 'f1': 112,\n 'f2': 113,\n 'f3': 114,\n 'f4': 115,\n 'f5': 116,\n 'f6': 117,\n 'f7': 118,\n 'f8': 119,\n 'f9': 120,\n 'f10': 121,\n 'f11': 122,\n 'f12': 123,\n 'f13': 124,\n 'f14': 125,\n 'f15': 126,\n 'f16': 127,\n 'f17': 128,\n 'f18': 129,\n 'f19': 130,\n 'f20': 131,\n 'f21': 132,\n 'f22': 133,\n 'f23': 134,\n 'f24': 135,\n 'numlock': 144,\n 'scrolllock': 145,\n '^': 160,\n '!': 161,\n // '؛' \t : 162 // (arabic semicolon)\n '#': 163,\n '$': 164,\n 'ù': 165,\n 'pagebackward': 166,\n 'pageforward': 167,\n 'refresh': 168,\n 'closingparen': 169, // (AZERTY)\n '*': 170,\n '~+*': 171,\n // 'home'\t : 172,\n 'minus': 173, // firefox\n // 'mute' : 173,\n // 'unmute'\t : 173,\n 'decreasevolumelevel': 174,\n 'increasevolumelevel': 175,\n 'next': 176,\n 'previous': 177,\n 'stop': 178,\n 'play/pause': 179,\n 'email': 180,\n 'mute': 181, // firefox, alternate: 173\n 'unmute': 181, // alternate: 173?\n //'decreasevolumelevel'\t182 // firefox\n //'increasevolumelevel'\t183 // firefox\n 'semicolon': 186,\n 'ñ': 186,\n 'equal': 187,\n 'comma': 188,\n 'dash': 189,\n 'period': 190,\n 'forwardslash': 191,\n 'ç': 191, // 231 alternate?\n 'grave accent': 192,\n //'ñ' 192,\n 'æ': 192,\n 'ö': 192,\n '?': 193,\n '/': 193,\n '°': 193,\n // 'numpadperiod'\t : 194, // chrome\n 'openbracket': 219,\n 'backslash': 220,\n 'closebracket': 221,\n 'å': 221,\n 'singlequote': 222,\n 'ø': 222,\n 'ä': 222,\n '`': 223,\n // 'left or right ⌘ key (firefox)'\t224\n 'altgr': 225,\n // '< /git >, left back slash'\t226\n 'GNOME Compose Key': 230,\n 'XF86Forward': 233,\n 'XF86Back': 234,\n 'alphanumeric': 240,\n 'hiragana': 242,\n 'katakana': 242,\n 'half-width': 243,\n 'full-width': 243,\n 'kanji': 244,\n 'unlocktrackpad': 251, // Chrome/Edge\n 'toggletouchpad': 255\n };\n return KeyHandler;\n}());\nexports.KeyHandler = KeyHandler;\n//# sourceMappingURL=KeyHandler.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2018-10-23\n * @modified 2018-11-19 Added multi-select and multi-drag.\n * @modified 2018-12-04 Added basic SVG export.\n * @modified 2018-12-09 Extended the constructor (canvas).\n * @modified 2018-12-18 Added the config.redrawOnResize param.\n * @modified 2018-12-18 Added the config.defaultCanvas{Width,Height} params.\n * @modified 2018-12-19 Added CSS scaling.\n * @modified 2018-12-28 Removed the unused 'drawLabel' param. Added the 'enableMouse' and 'enableKeys' params.\n * @modified 2018-12-29 Added the 'drawOrigin' param.\n * @modified 2018-12-29 Renamed the 'autoCenterOffset' param to 'autoAdjustOffset'. Added the params 'offsetAdjustXPercent' and 'offsetAdjustYPercent'.\n * @modified 2019-01-14 Added params 'drawBezierHandleLines' and 'drawBezierHandlePoints'. Added the 'redraw' praam to the add() function.\n * @modified 2019-01-16 Added params 'drawHandleLines' and 'drawHandlePoints'. Added the new params to the dat.gui interface.\n * @modified 2019-01-30 Added the 'Vector' type (extending the Line class).\n * @modified 2019-01-30 Added the 'PBImage' type (a wrapper for images).\n * @modified 2019-02-02 Added the 'canvasWidthFactor' and 'canvasHeightFactor' params.\n * @modified 2019-02-03 Removed the drawBackgroundImage() function, with had no purpose at all. Just add an image to the drawables-list.\n * @modified 2019-02-06 Vertices (instace of Vertex) can now be added. Added the 'draggable' attribute to the vertex attributes.\n * @modified 2019-02-10 Fixed a draggable-bug in PBImage handling (scaling was not possible).\n * @modified 2019-02-10 Added the 'enableTouch' option (default is true).\n * @modified 2019-02-14 Added the console for debugging (setConsole(object)).\n * @modified 2019-02-19 Added two new constants: DEFAULT_CLICK_TOLERANCE and DEFAULT_TOUCH_TOLERANCE.\n * @modified 2019-02-19 Added the second param to the locatePointNear(Vertex,Number) function.\n * @modified 2019-02-20 Removed the 'loadFile' entry from the GUI as it was experimental and never in use.\n * @modified 2019-02-23 Removed the 'rebuild' function as it had no purpose.\n * @modified 2019-02-23 Added scaling of the click-/touch-tolerance with the CSS scale.\n * @modified 2019-03-23 Added JSDoc tags. Changed the default value of config.drawOrigin to false.\n * @modified 2019-04-03 Fixed the touch-drag position detection for canvas elements that are not located at document position (0,0).\n * @modified 2019-04-03 Tweaked the fit-to-parent function to work with paddings and borders.\n * @modified 2019-04-28 Added the preClear callback param (called before the canvas was cleared on redraw and before any elements are drawn).\n * @modified 2019-09-18 Added basics for WebGL support (strictly experimental).\n * @modified 2019-10-03 Added the .beginDrawCycle call in the redraw function.\n * @modified 2019-11-06 Added fetch.num, fetch.val, fetch.bool, fetch.func functions.\n * @modified 2019-11-13 Fixed an issue with the mouse-sensitive area around vertices (were affected by zoom).\n * @modified 2019-11-13 Added the 'enableMouseWheel' param.\n * @modified 2019-11-18 Added the Triangle class as a regular drawable element.\n * @modified 2019-11-18 The add function now works with arrays, too.\n * @modified 2019-11-18 Added the _handleColor helper function to determine the render color of non-draggable vertices.\n * @modified 2019-11-19 Fixed a bug in the resizeCanvas function; retina resolution was not possible.\n * @modified 2019-12-04 Added relative positioned zooming.\n * @modified 2019-12-04 Added offsetX and offsetY params.\n * @modified 2019-12-04 Added an 'Set to fullsize retina' button to the GUI config.\n * @modified 2019-12-07 Added the drawConfig for lines, polygons, ellipse, triangles, bezier curves and image control lines.\n * @modified 2019-12-08 Fixed a css scale bug in the viewport() function.\n * @modified 2019-12-08 Added the drawconfig UI panel (line colors and line widths).\n * @modified 2020-02-06 Added handling for the end- and end-control-points of non-cirular Bézier paths (was still missing).\n * @modified 2020-02-06 Fixed a drag-amount bug in the move handling of end points of Bezier paths (control points was not properly moved when non circular).\n * @modified 2020-03-28 Ported this class from vanilla-JS to Typescript.\n * @modified 2020-03-29 Fixed the enableSVGExport flag (read enableEport before).\n * @modified 2020-05-09 Included the Cirlcle class.\n * @modified 2020-06-22 Added the rasterScaleX and rasterScaleY config params.\n * @modified 2020-06-03 Fixed the selectedVerticesOnPolyon(Polygon) function: non-selectable vertices were selected too, before.\n * @modified 2020-07-06 Replacing Touchy.js by AlloyFinger.js\n * @modified 2020-07-27 Added the getVertexNear(XYCoords,number) function\n * @modified 2020-07-27 Extended the remove(Drawable) function: vertices are now removed, too.\n * @modified 2020-07-28 Added PlotBoilerplate.revertMousePosition(number,number) – the inverse function of transformMousePosition(...).\n * @modified 2020-07-31 Added PlotBoilerplate.getDraggedElementCount() to check wether any elements are currently being dragged.\n * @modified 2020-08-19 Added the VertexAttributes.visible attribute to make vertices invisible.\n * @modified 2020-11-17 Added pure click handling (no dragEnd and !wasMoved jiggliny any more) to the PlotBoilerplate.\n * @modified 2020-12-11 Added the `removeAll(boolean)` function.\n * @modified 2020-12-17 Added the `CircleSector` drawable.\n * @modified 2021-01-04 Avoiding multiple redraw call on adding multiple Drawables (array).\n * @modified 2021-01-08 Added param `draw:DraLib<void>` to the methods `drawVertices`, `drawGrid` and `drawSelectPolygon`.\n * @modified 2021-01-08 Added the customizable `drawAll(...)` function.\n * @modified 2021-01-09 Added the `drawDrawable(...)` function.\n * @modified 2021-01-10 Added the `eventCatcher` element (used to track mouse events on SVGs).\n * @modified 2021-01-26 Fixed SVG resizing.\n * @modified 2021-01-26 Replaced the old SVGBuilder by the new `drawutilssvg` library.\n * @modified 2021-02-08 Fixed a lot of es2015 compatibility issues.\n * @modified 2021-02-18 Adding `adjustOffset(boolean)` function.\n * @modified 2021-03-01 Updated the `PlotBoilerplate.draw(...)` function: ellipses are now rotate-able.\n * @modified 2021-03-03 Added the `VEllipseSector` drawable.\n * @modified 2021-03-29 Clearing `currentClassName` and `currentId` after drawing each drawable.\n * @modified 2021-04-25 Extending `remove` to accept arrays of drawables.\n * @modified 2021-11-16 Adding the `PBText` drawable.\n * @modified 2022-08-01 Added `title` to the params.\n * @modified 2022-10-25 Added the `origin` to the default draw config.\n * @modified 2022-11-06 Adding an XML declaration to the SVG export routine.\n * @modified 2022-11-23 Added the `drawRaster` (default=true) option to the config/drawconfig.\n * @modified 2023-02-04 Fixed a bug in the `drawDrawable` function; fill's current classname was not set.\n * @modified 2023-02-10 Fixing an issue of the `style.position` setting when `fitToParent=true` from `absolute` to `static` (default).\n * @modified 2023-02-10 Cleaning up most type errors in the main class (mostly null checks).\n * @modified 2023-02-10 Adding `enableZoom` and `enablePan` (both default true) to have the option to disable these functions.\n * @modified 2023-09-29 Adding proper dicionary key and value types to the params of `PlotBoilerplate.utils.safeMergeByKeys` (was `object` before).\n * @modified 2024-07-08 Adding `PlotBoilerplate.getGUI()` to retrieve the GUI instance.\n * @modified 2024-08-25 Extending main class `PlotBoilerplate` optional param `isBackdropFiltersEnabled`.\n * @modified 2024-12-02 Adding the `triggerRedraw` to the `removeAll` method.\n * @modified 2025-05-07 Changing the return type of `removeVertex` from `void` to `boolean`.\n * @modified 2025-05-07 Handling content changes now with `contentChangeListeners`.\n * @modified 2025-05-07 Added `PlogBoilerplate.addContentChangeListener` and `.removeContentChangeListener`.\n * @modified 2025-05-07 Moving full vectors now by default when vector point a is moved.\n * @modified 2025-05-20 Applying `lineWith` parameter in the draw routine for vectors (had been missing).\n * @modified 2026-03-13 Changed visibility of `setZoom` and `setOffset` to public. There was no good reason to have the private.\n * @modified 2026-04-04 Added `isInPanningMode` attribute and `isPanning` method.\n *\n * @version 1.22.0\n *\n * @file PlotBoilerplate\n * @fileoverview The main class.\n * @public\n **/\nvar __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.PlotBoilerplate = void 0;\nvar alloyfinger_typescript_1 = require(\"alloyfinger-typescript\");\nvar draw_1 = require(\"./draw\");\nvar drawgl_1 = require(\"./drawgl\");\nvar drawutilssvg_1 = require(\"./drawutilssvg\");\nvar BezierPath_1 = require(\"./BezierPath\");\nvar Bounds_1 = require(\"./Bounds\");\nvar Circle_1 = require(\"./Circle\");\nvar CircleSector_1 = require(\"./CircleSector\");\nvar Grid_1 = require(\"./Grid\");\nvar KeyHandler_1 = require(\"./KeyHandler\");\nvar Line_1 = require(\"./Line\");\nvar MouseHandler_1 = require(\"./MouseHandler\");\nvar PBImage_1 = require(\"./PBImage\");\nvar Polygon_1 = require(\"./Polygon\");\nvar Triangle_1 = require(\"./Triangle\");\nvar VEllipse_1 = require(\"./VEllipse\");\nvar VEllipseSector_1 = require(\"./VEllipseSector\");\nvar Vector_1 = require(\"./Vector\");\nvar Vertex_1 = require(\"./Vertex\");\nvar VertexAttr_1 = require(\"./VertexAttr\");\nvar PBText_1 = require(\"./PBText\");\n/**\n * @classdesc The main class of the PlotBoilerplate.\n *\n * @requires Vertex\n * @requires Line\n * @requires Vector\n * @requires Polygon\n * @requires PBImage\n * @requires VEllipse\n * @requires Circle\n * @requires MouseHandler\n * @requires KeyHandler\n * @requires VertexAttr\n * @requires CubicBezierCurve\n * @requires BezierPath\n * @requires Drawable\n * @requires DrawConfig\n * @requires IHooks\n * @requires PBParams\n * @requires Triangle\n * @requires drawutils\n * @requires drawutilsgl\n * @requires SVGSerializable\n * @requires XYCoords\n * @requires XYDimension\n */\nvar PlotBoilerplate = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name PlotBoilerplate\n * @public\n * @param {object} config={} - The configuration.\n * @param {HTMLCanvasElement} config.canvas - Your canvas element in the DOM (required).\n * @param {boolean=} [config.fullSize=true] - If set to true the canvas will gain full window size.\n * @param {boolean=} [config.fitToParent=true] - If set to true the canvas will gain the size of its parent container (overrides fullSize).\n * @param {number=} [config.scaleX=1.0] - The initial x-zoom. Default is 1.0.\n * @param {number=} [config.scaleY=1.0] - The initial y-zoom. Default is 1.0.\n * @param {number=} [config.offsetX=1.0] - The initial x-offset. Default is 0.0. Note that autoAdjustOffset=true overrides these values.\n * @param {number=} [config.offsetY=1.0] - The initial y-offset. Default is 0.0. Note that autoAdjustOffset=true overrides these values.\n * @param {boolean=} [config.rasterGrid=true] - If set to true the background grid will be drawn rastered.\n * @param {boolean=} [config.rasterScaleX=1.0] - Define the default horizontal raster scale (default=1.0).\n * @param {boolean=} [config.rasterScaleY=1.0] - Define the default vertical raster scale (default=1.0).\n * @param {number=} [config.rasterAdjustFactor=1.0] - The exponential limit for wrapping down the grid. (2.0 means: halve the grid each 2.0*n zoom step).\n * @param {boolean=} [config.drawOrigin=false] - Draw a crosshair at (0,0).\n * @param {boolean=} [config.autoAdjustOffset=true] - When set to true then the origin of the XY plane will\n * be re-adjusted automatically (see the params\n * offsetAdjust{X,Y}Percent for more).\n * @param {number=} [config.offsetAdjustXPercent=50] - The x-fallback position for the origin after\n * resizing the canvas.\n * @param {number=} [config.offsetAdjustYPercent=50] - The y-fallback position for the origin after\n * resizing the canvas.\n * @param {number=} [config.defaultCanvasWidth=1024] - The canvas size fallback (width) if no automatic resizing\n * is switched on.\n * @param {number=} [config.defaultCanvasHeight=768] - The canvas size fallback (height) if no automatic resizing\n * is switched on.\n * @param {number=} [config.canvasWidthFactor=1.0] - Scaling factor (width) upon the canvas size.\n * In combination with cssScale{X,Y} this can be used to obtain\n * sub pixel resolutions for retina displays.\n * @param {number=} [config.canvasHeightFactor=1.0] - Scaling factor (height) upon the canvas size.\n * In combination with cssScale{X,Y} this can be used to obtain\n * sub pixel resolutions for retina displays.\n * @param {number=} [config.cssScaleX=1.0] - Visually resize the canvas (horizontally) using CSS transforms (scale).\n * @param {number=} [config.cssScaleY=1.0] - Visually resize the canvas (vertically) using CSS transforms (scale).\n * @param {boolan=} [config.cssUniformScale=true] - CSS scale x and y obtaining aspect ratio.\n * @param {boolean=} [config.autoDetectRetina=true] - When set to true (default) the canvas will try to use the display's pixel ratio.\n * @param {string=} [config.backgroundColor=#ffffff] - The backround color.\n * @param {boolean=} [config.redrawOnResize=true] - Switch auto-redrawing on resize on/off (some applications\n * might want to prevent automatic redrawing to avoid data loss from the draw buffer).\n * @param {boolean=} [config.drawBezierHandleLines=true] - Indicates if Bézier curve handles should be drawn (used for\n * editors, no required in pure visualizations).\n * @param {boolean=} [config.drawBezierHandlePoints=true] - Indicates if Bézier curve handle points should be drawn.\n * @param {function=} [config.preClear=null] - A callback function that will be triggered just before the\n * draw function clears the canvas (before anything else was drawn).\n * @param {function=} [config.preDraw=null] - A callback function that will be triggered just before the draw\n * function starts.\n * @param {function=} [config.postDraw=null] - A callback function that will be triggered right after the drawing\n * process finished.\n * @param {boolean=} [config.enableMouse=true] - Indicates if the application should handle mouse events for you.\n * @param {boolean=} [config.enableTouch=true] - Indicates if the application should handle touch events for you.\n * @param {boolean=} [config.enableKeys=true] - Indicates if the application should handle key events for you.\n * @param {boolean=} [config.enableMouseWheel=true] - Indicates if the application should handle mouse wheel events for you.\n * @param {boolean=} [config.enablePan=true] - (default true) Set to false if you want to disable panning completely.\n * @param {boolean=} [config.enableZoom=true] - (default true) Set to false if you want to disable zooming completely.\n * @param {boolean=} [config.enableGL=false] - Indicates if the application should use the experimental WebGL features (not recommended).\n * @param {boolean=} [config.enableSVGExport=true] - Indicates if the SVG export should be enabled (default is true).\n * Note that changes from the postDraw hook might not be visible in the export.\n * @param {string=} [config.title=null] - Specify any hover tile here. It will be attached as a `title` attribute to the most elevated element.\n */\n function PlotBoilerplate(config, drawConfig) {\n var _b, _c;\n /**\n * A list of content change listeners.\n */\n this.contentChangeListeners = [];\n /**\n * A discrete timestamp to identify single render cycles.\n * Note that using system time milliseconds is not a safe way to identify render frames, as on modern powerful machines\n * multiple frames might be rendered within each millisecond.\n * @member {number}\n * @memberof plotboilerplate\n * @instance\n * @private\n */\n this.renderTime = 0;\n /**\n * A storage variable for retrieving the GUI instance once it was created.\n */\n this._gui = null;\n // This should be in some static block ...\n VertexAttr_1.VertexAttr.model = {\n bezierAutoAdjust: false,\n renderTime: 0,\n selectable: true,\n isSelected: false,\n draggable: true,\n visible: true\n };\n if (typeof config.canvas === \"undefined\") {\n throw \"No canvas specified.\";\n }\n /**\n * A global config that's attached to the dat.gui control interface.\n *\n * @member {Object}\n * @memberof PlotBoilerplate\n * @instance\n */\n var f = PlotBoilerplate.utils.fetch;\n this.config = {\n canvas: config.canvas,\n fullSize: f.val(config, \"fullSize\", true),\n fitToParent: f.bool(config, \"fitToParent\", true),\n scaleX: f.num(config, \"scaleX\", 1.0),\n scaleY: f.num(config, \"scaleY\", 1.0),\n offsetX: f.num(config, \"offsetX\", 0.0),\n offsetY: f.num(config, \"offsetY\", 0.0),\n rasterGrid: f.bool(config, \"rasterGrid\", true),\n drawRaster: f.bool(config, \"drawRaster\", true),\n rasterScaleX: f.num(config, \"rasterScaleX\", 1.0),\n rasterScaleY: f.num(config, \"rasterScaleY\", 1.0),\n rasterAdjustFactor: f.num(config, \"rasterAdjustdFactror\", 2.0),\n drawOrigin: f.bool(config, \"drawOrigin\", false),\n autoAdjustOffset: f.val(config, \"autoAdjustOffset\", true),\n offsetAdjustXPercent: f.num(config, \"offsetAdjustXPercent\", 50),\n offsetAdjustYPercent: f.num(config, \"offsetAdjustYPercent\", 50),\n backgroundColor: config.backgroundColor || \"#ffffff\",\n redrawOnResize: f.bool(config, \"redrawOnResize\", true),\n defaultCanvasWidth: f.num(config, \"defaultCanvasWidth\", PlotBoilerplate.DEFAULT_CANVAS_WIDTH),\n defaultCanvasHeight: f.num(config, \"defaultCanvasHeight\", PlotBoilerplate.DEFAULT_CANVAS_HEIGHT),\n canvasWidthFactor: f.num(config, \"canvasWidthFactor\", 1.0),\n canvasHeightFactor: f.num(config, \"canvasHeightFactor\", 1.0),\n cssScaleX: f.num(config, \"cssScaleX\", 1.0),\n cssScaleY: f.num(config, \"cssScaleY\", 1.0),\n cssUniformScale: f.bool(config, \"cssUniformScale\", true),\n saveFile: function () {\n _self.hooks.saveFile(_self);\n },\n setToRetina: function () {\n _self._setToRetina();\n },\n autoDetectRetina: f.bool(config, \"autoDetectRetina\", true),\n enableSVGExport: f.bool(config, \"enableSVGExport\", true),\n // Listeners/observers\n preClear: f.func(config, \"preClear\", null),\n preDraw: f.func(config, \"preDraw\", null),\n postDraw: f.func(config, \"postDraw\", null),\n // Interaction\n enableMouse: f.bool(config, \"enableMouse\", true),\n enableTouch: f.bool(config, \"enableTouch\", true),\n enableKeys: f.bool(config, \"enableKeys\", true),\n enableMouseWheel: f.bool(config, \"enableMouseWheel\", true),\n enableZoom: f.bool(config, \"enableZoom\", true), // default=true\n enablePan: f.bool(config, \"enablePan\", true), // default=true\n // Experimental (and unfinished)\n enableGL: f.bool(config, \"enableGL\", false),\n isBackdropFiltersEnabled: f.bool(config, \"isBackdropFiltersEnabled\", true)\n }; // END confog\n /**\n * Configuration for drawing things.\n *\n * @member {Object}\n * @memberof PlotBoilerplate\n * @instance\n */\n this.drawConfig = {\n drawVertices: true,\n drawBezierHandleLines: f.bool(config, \"drawBezierHandleLines\", true),\n drawBezierHandlePoints: f.bool(config, \"drawBezierHandlePoints\", true),\n drawHandleLines: f.bool(config, \"drawHandleLines\", true),\n drawHandlePoints: f.bool(config, \"drawHandlePoints\", true),\n drawGrid: f.bool(config, \"drawGrid\", true),\n drawRaster: f.bool(config, \"drawRaster\", true),\n bezier: {\n color: \"#00a822\",\n lineWidth: 2,\n handleLine: {\n color: \"rgba(180,180,180,0.5)\",\n lineWidth: 1\n },\n pathVertex: {\n color: \"#B400FF\",\n lineWidth: 1,\n fill: true\n },\n controlVertex: {\n color: \"#B8D438\",\n lineWidth: 1,\n fill: true\n }\n },\n // bezierPath: {\n // color: \"#0022a8\",\n // lineWidth: 1\n // },\n polygon: {\n color: \"#0022a8\",\n lineWidth: 1\n },\n triangle: {\n color: \"#6600ff\",\n lineWidth: 1\n },\n ellipse: {\n color: \"#2222a8\",\n lineWidth: 1\n },\n ellipseSector: {\n color: \"#a822a8\",\n lineWidth: 2\n },\n circle: {\n color: \"#22a8a8\",\n lineWidth: 2\n },\n circleSector: {\n color: \"#2280a8\",\n lineWidth: 1\n },\n vertex: {\n color: \"#a8a8a8\",\n lineWidth: 1\n },\n selectedVertex: {\n color: \"#c08000\",\n lineWidth: 2\n },\n line: {\n color: \"#a844a8\",\n lineWidth: 1\n },\n vector: {\n color: \"#ff44a8\",\n lineWidth: 1\n },\n image: {\n color: \"#a8a8a8\",\n lineWidth: 1\n },\n text: {\n color: \"rgba(192,0,128,0.5)\",\n lineWidth: 1,\n fill: true,\n anchor: true\n },\n origin: {\n color: \"#000000\"\n }\n }; // END drawConfig\n // +---------------------------------------------------------------------------------\n // | Object members.\n // +-------------------------------\n this.grid = new Grid_1.Grid(new Vertex_1.Vertex(0, 0), new Vertex_1.Vertex(50, 50));\n this.canvasSize = { width: PlotBoilerplate.DEFAULT_CANVAS_WIDTH, height: PlotBoilerplate.DEFAULT_CANVAS_HEIGHT };\n var canvasElement = typeof config.canvas === \"string\" ? document.querySelector(config.canvas) : config.canvas;\n if (typeof canvasElement === \"undefined\") {\n throw \"Cannot initialize PlotBoilerplate with a null canvas (element \\\"\".concat(config.canvas, \" not found).\");\n }\n // Which renderer to use: Canvas2D, WebGL (experimental) or SVG?\n if (canvasElement.tagName.toLowerCase() === \"canvas\") {\n this.canvas = canvasElement;\n this.eventCatcher = this.canvas;\n if (this.config.enableGL && typeof drawgl_1.drawutilsgl === \"undefined\") {\n console.warn(\"Cannot use webgl. Package was compiled without experimental gl support. Please use plotboilerplate-glsupport.min.js instead.\");\n console.warn(\"Disabling GL and falling back to Canvas2D.\");\n this.config.enableGL = false;\n }\n if (this.config.enableGL) {\n // Override the case 'null' here. If GL is not supported, well then nothing works.\n var ctx = this.canvas.getContext(\"webgl\"); // webgl-experimental?\n this.draw = new drawgl_1.drawutilsgl(ctx, false);\n // PROBLEM: same instance of fill and draw when using WebGL.\n // Shader program cannot be duplicated on the same context.\n this.fill = this.draw.copyInstance(true);\n console.warn(\"Initialized with experimental mode enableGL=true. Note that this is not yet fully implemented.\");\n }\n else {\n // Override the case 'null' here. If context creation is not supported, well then nothing works.\n var ctx = this.canvas.getContext(\"2d\");\n this.draw = new draw_1.drawutils(ctx, false);\n this.fill = new draw_1.drawutils(ctx, true);\n }\n }\n else if (canvasElement.tagName.toLowerCase() === \"svg\") {\n if (typeof drawutilssvg_1.drawutilssvg === \"undefined\")\n throw \"The svg draw library is not yet integrated part of PlotBoilerplate. Please include ./src/js/utils/helpers/drawutils.svg into your document.\";\n this.canvas = canvasElement;\n this.draw = new drawutilssvg_1.drawutilssvg(this.canvas, new Vertex_1.Vertex(), // offset\n new Vertex_1.Vertex(), // scale\n this.canvasSize, false, // fillShapes=false\n this.drawConfig, false // isSecondary=false\n );\n this.fill = this.draw.copyInstance(true); // fillShapes=true\n if (this.canvas.parentElement) {\n this.eventCatcher = document.createElement(\"div\");\n this.eventCatcher.style.position = \"absolute\";\n this.eventCatcher.style.left = \"0\";\n this.eventCatcher.style.top = \"0\";\n this.eventCatcher.style.cursor = \"pointer\";\n this.canvas.parentElement.style.position = \"relative\";\n this.canvas.parentElement.appendChild(this.eventCatcher);\n }\n else {\n this.eventCatcher = document.body;\n }\n }\n else {\n throw \"Element is neither a canvas nor an svg element.\";\n }\n // At this point the event cacher element is deinfed and located at highest elevation.\n // Set `title` attribut?\n if (config.title) {\n this.eventCatcher.setAttribute(\"title\", config.title);\n }\n this.draw.scale.set((_b = this.config.scaleX) !== null && _b !== void 0 ? _b : 1.0, this.config.scaleY);\n this.fill.scale.set((_c = this.config.scaleX) !== null && _c !== void 0 ? _c : 1.0, this.config.scaleY);\n this.vertices = [];\n this.selectPolygon = null;\n this.draggedElements = [];\n this.drawables = [];\n this.console = console;\n this.hooks = {\n // This is changable from the outside\n saveFile: PlotBoilerplate._saveFile\n };\n var _self = this;\n globalThis.addEventListener(\"resize\", function () { return _self.resizeCanvas(); });\n this.resizeCanvas();\n if (config.autoDetectRetina) {\n this._setToRetina();\n }\n this.installInputListeners();\n // Apply the configured CSS scale.\n this.updateCSSscale();\n // Init\n this.redraw();\n // Gain focus\n this.canvas.focus();\n } // END constructor\n /**\n * This function opens a save-as file dialog and – once an output file is\n * selected – stores the current canvas contents as an SVG image.\n *\n * It is the default hook for saving files and can be overwritten.\n *\n * @method _saveFile\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n * @private\n **/\n PlotBoilerplate._saveFile = function (pb) {\n // Create fake SVG node\n var svgNode = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n // Draw everything to fake node.\n var tosvgDraw = new drawutilssvg_1.drawutilssvg(svgNode, pb.draw.offset, pb.draw.scale, pb.canvasSize, false, // fillShapes=false\n pb.drawConfig);\n var tosvgFill = tosvgDraw.copyInstance(true); // fillShapes=true\n tosvgDraw.beginDrawCycle(0);\n tosvgFill.beginDrawCycle(0);\n if (pb.config.preClear) {\n pb.config.preClear();\n }\n tosvgDraw.clear(pb.config.backgroundColor || \"white\");\n if (pb.config.preDraw) {\n pb.config.preDraw(tosvgDraw, tosvgFill);\n }\n pb.drawAll(0, tosvgDraw, tosvgFill);\n pb.drawVertices(0, tosvgDraw);\n if (pb.config.postDraw)\n pb.config.postDraw(tosvgDraw, tosvgFill);\n tosvgDraw.endDrawCycle(0);\n tosvgFill.endDrawCycle(0);\n // Full support in all browsers \\o/\n // https://caniuse.com/xml-serializer\n var serializer = new XMLSerializer();\n var svgCode = serializer.serializeToString(svgNode);\n // Add: '<?xml version=\"1.0\" encoding=\"utf-8\"?>\\n' ?\n var blob = new Blob(['<?xml version=\"1.0\" encoding=\"utf-8\"?>\\n' + svgCode], { type: \"image/svg;charset=utf-8\" });\n // See documentation for FileSaver.js for usage.\n // https://github.com/eligrey/FileSaver.js\n if (typeof globalThis[\"saveAs\"] !== \"function\") {\n throw \"Cannot save file; did you load the ./utils/savefile helper function and the eligrey/SaveFile library?\";\n }\n var _saveAs = globalThis[\"saveAs\"];\n _saveAs(blob, \"plotboilerplate.svg\");\n };\n /**\n * This function sets the canvas resolution to factor 2.0 (or the preferred pixel ratio of your device) for retina displays.\n * Please not that in non-GL mode this might result in very slow rendering as the canvas buffer size may increase.\n *\n * @method _setToRetina\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n * @private\n **/\n PlotBoilerplate.prototype._setToRetina = function () {\n this.config.autoDetectRetina = true;\n var pixelRatio = globalThis.devicePixelRatio || 1;\n this.config.cssScaleX = this.config.cssScaleY = 1.0 / pixelRatio;\n this.config.canvasWidthFactor = this.config.canvasHeightFactor = pixelRatio;\n this.resizeCanvas();\n this.updateCSSscale();\n };\n PlotBoilerplate.prototype.isPanning = function () {\n return this.isInPanningMode;\n };\n /**\n * Set the current zoom and draw offset to fit the given bounds.\n *\n * This method currently restores the aspect zoom ratio.\n *\n **/\n PlotBoilerplate.prototype.fitToView = function (bounds) {\n var canvasCenter = new Vertex_1.Vertex(this.canvasSize.width / 2.0, this.canvasSize.height / 2.0);\n var canvasRatio = this.canvasSize.width / this.canvasSize.height;\n var ratio = bounds.width / bounds.height;\n // Find the new draw offset\n var center = new Vertex_1.Vertex(bounds.max.x - bounds.width / 2.0, bounds.max.y - bounds.height / 2.0)\n .inv()\n .addXY(this.canvasSize.width / 2.0, this.canvasSize.height / 2.0);\n this.setOffset(center);\n if (canvasRatio < ratio) {\n var newUniformZoom = this.canvasSize.width / bounds.width;\n this.setZoom(newUniformZoom, newUniformZoom, canvasCenter);\n }\n else {\n var newUniformZoom = this.canvasSize.height / bounds.height;\n this.setZoom(newUniformZoom, newUniformZoom, canvasCenter);\n }\n this.redraw();\n };\n /**\n * Set the console for this instance.\n *\n * @method setConsole\n * @param {Console} con - The new console object (default is globalThis.console).\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.setConsole = function (con) {\n this.console = con;\n };\n /**\n * Update the CSS scale for the canvas depending onf the cssScale{X,Y} settings.<br>\n * <br>\n * This function is usually only used inernally.\n *\n * @method updateCSSscale\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n * @private\n **/\n PlotBoilerplate.prototype.updateCSSscale = function () {\n var _b, _c, _d, _e;\n if (this.config.cssUniformScale) {\n PlotBoilerplate.utils.setCSSscale(this.canvas, (_b = this.config.cssScaleX) !== null && _b !== void 0 ? _b : 1.0, (_c = this.config.cssScaleX) !== null && _c !== void 0 ? _c : 1.0);\n }\n else {\n PlotBoilerplate.utils.setCSSscale(this.canvas, (_d = this.config.cssScaleX) !== null && _d !== void 0 ? _d : 1.0, (_e = this.config.cssScaleY) !== null && _e !== void 0 ? _e : 1.0);\n }\n };\n /**\n * Adds a new content change listener to this instance. Adding duplicates is not possible.\n *\n * @param {PBContentChangeListener} listener - The listenre to add.\n * @method addContentChangeListener\n * @instance\n * @memberof PlotBoilerplate\n * @returns {void}\n */\n PlotBoilerplate.prototype.addContentChangeListener = function (listener) {\n for (var i in this.contentChangeListeners) {\n if (this.contentChangeListeners[i] === listener) {\n return;\n }\n }\n this.contentChangeListeners.push(listener);\n };\n /**\n * Removes an existing content change listener from this instance.\n *\n * @param {PBContentChangeListener} listener - The listenre to add.\n * @method removeContentChangeListener\n * @instance\n * @memberof PlotBoilerplate\n * @returns {void}\n */\n PlotBoilerplate.prototype.removeContentChangeListener = function (listener) {\n for (var i = 0; i < this.contentChangeListeners.length; i++) {\n if (this.contentChangeListeners[i] === listener) {\n this.contentChangeListeners.splice(i, 1);\n return;\n }\n }\n };\n PlotBoilerplate.prototype._fireContentChanged = function (addedDrawables, removedDrawables) {\n for (var i in this.contentChangeListeners) {\n var listener = this.contentChangeListeners[i];\n if (listener && typeof listener === \"function\") {\n listener({\n type: addedDrawables.length > 0 ? \"DRAWABLES_ADDED\" : \"DRAWABLES_REMOVED\",\n addedDrawables: addedDrawables,\n removedDrawables: removedDrawables\n });\n }\n }\n };\n /**\n * Add a drawable object.<br>\n * <br>\n * This must be either:<br>\n * <pre>\n * * a Vertex\n * * a Line\n * * a Vector\n * * a VEllipse\n * * a VEllipseSector\n * * a Circle\n * * a Polygon\n * * a Triangle\n * * a BezierPath\n * * a BPImage\n * </pre>\n *\n * @param {Drawable|Drawable[]} drawable - The drawable (of one of the allowed class instance) to add.\n * @param {boolean} [redraw=true] - If true the function will trigger redraw after the drawable(s) was/were added.\n * @method add\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.add = function (drawable, redraw, doNotFireEvent) {\n if (Array.isArray(drawable)) {\n var arr = drawable;\n for (var i = 0; i < arr.length; i++) {\n this.add(arr[i], false, doNotFireEvent);\n }\n // !doNotFireEvent && this._fireContentChanged(arr, []);\n }\n else {\n var addedDrawables = [drawable];\n if (drawable instanceof Vertex_1.Vertex) {\n this.drawables.push(drawable);\n this.vertices.push(drawable);\n }\n else if (drawable instanceof Line_1.Line) {\n // Add some lines\n this.drawables.push(drawable);\n this.vertices.push(drawable.a);\n this.vertices.push(drawable.b);\n addedDrawables.push(drawable.a, drawable.b);\n }\n else if (drawable instanceof Vector_1.Vector) {\n this.drawables.push(drawable);\n this.vertices.push(drawable.a);\n this.vertices.push(drawable.b);\n addedDrawables.push(drawable.a, drawable.b);\n drawable.a.listeners.addDragListener(function (event) {\n drawable.b.add(event.params.dragAmount);\n });\n }\n else if (drawable instanceof VEllipse_1.VEllipse) {\n this.vertices.push(drawable.center);\n this.vertices.push(drawable.axis);\n addedDrawables.push(drawable.center, drawable.axis);\n this.drawables.push(drawable);\n drawable.center.listeners.addDragListener(function (event) {\n drawable.axis.add(event.params.dragAmount);\n });\n }\n else if (drawable instanceof VEllipseSector_1.VEllipseSector) {\n this.vertices.push(drawable.ellipse.center);\n this.vertices.push(drawable.ellipse.axis);\n addedDrawables.push(drawable.ellipse.center, drawable.ellipse.axis);\n this.drawables.push(drawable);\n drawable.ellipse.center.listeners.addDragListener(function (event) {\n drawable.ellipse.axis.add(event.params.dragAmount);\n });\n }\n else if (drawable instanceof Circle_1.Circle) {\n this.vertices.push(drawable.center);\n addedDrawables.push(drawable.center);\n this.drawables.push(drawable);\n }\n else if (drawable instanceof CircleSector_1.CircleSector) {\n this.vertices.push(drawable.circle.center);\n addedDrawables.push(drawable.circle.center);\n this.drawables.push(drawable);\n }\n else if (drawable instanceof Polygon_1.Polygon) {\n this.drawables.push(drawable);\n for (var i = 0; i < drawable.vertices.length; i++) {\n this.vertices.push(drawable.vertices[i]);\n addedDrawables.push(drawable.vertices[i]);\n }\n }\n else if (drawable instanceof Triangle_1.Triangle) {\n this.drawables.push(drawable);\n this.vertices.push(drawable.a);\n this.vertices.push(drawable.b);\n this.vertices.push(drawable.c);\n addedDrawables.push(drawable.a, drawable.b, drawable.c);\n }\n else if (drawable instanceof BezierPath_1.BezierPath) {\n this.drawables.push(drawable);\n var bezierPath = drawable;\n for (var i = 0; i < bezierPath.bezierCurves.length; i++) {\n if (!drawable.adjustCircular && i == 0) {\n this.vertices.push(bezierPath.bezierCurves[i].startPoint);\n addedDrawables.push(bezierPath.bezierCurves[i].startPoint);\n }\n this.vertices.push(bezierPath.bezierCurves[i].endPoint);\n this.vertices.push(bezierPath.bezierCurves[i].startControlPoint);\n this.vertices.push(bezierPath.bezierCurves[i].endControlPoint);\n addedDrawables.push(bezierPath.bezierCurves[i].endPoint, bezierPath.bezierCurves[i].startControlPoint, bezierPath.bezierCurves[i].endControlPoint);\n bezierPath.bezierCurves[i].startControlPoint.attr.selectable = false;\n bezierPath.bezierCurves[i].endControlPoint.attr.selectable = false;\n }\n PlotBoilerplate.utils.enableBezierPathAutoAdjust(drawable);\n }\n else if (drawable instanceof PBImage_1.PBImage) {\n this.vertices.push(drawable.upperLeft);\n this.vertices.push(drawable.lowerRight);\n addedDrawables.push(drawable.upperLeft, drawable.lowerRight);\n this.drawables.push(drawable);\n // Todo: think about a IDragEvent interface\n drawable.upperLeft.listeners.addDragListener(function (e) {\n drawable.lowerRight.add(e.params.dragAmount);\n });\n drawable.lowerRight.attr.selectable = false;\n }\n else if (drawable instanceof PBText_1.PBText) {\n this.vertices.push(drawable.anchor);\n addedDrawables.push(drawable.anchor);\n this.drawables.push(drawable);\n drawable.anchor.attr.selectable = false;\n }\n else {\n throw \"Cannot add drawable of unrecognized type: \" + typeof drawable + \".\";\n }\n !doNotFireEvent && this._fireContentChanged(addedDrawables, []);\n }\n // This is a workaround for backwards compatibility when the 'redraw' param was not yet present.\n if (redraw || typeof redraw == \"undefined\") {\n this.redraw();\n }\n };\n /**\n * Remove a drawable object.<br>\n * <br>\n * This must be either:<br>\n * <pre>\n * * a Vertex\n * * a Line\n * * a Vector\n * * a VEllipse\n * * a Circle\n * * a Polygon\n * * a BezierPath\n * * a BPImage\n * * a Triangle\n * </pre>\n *\n * @param {Drawable|Array<Drawable>} drawable - The drawable (of one of the allowed class instance) to remove.\n * @param {boolean} [redraw=false]\n * @param {removeWidth}\n * @method remove\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.remove = function (drawable, redraw, removeWithVertices, doNotFireEvent) {\n if (Array.isArray(drawable)) {\n var removedDrawables_1 = [];\n for (var i = 0; i < drawable.length; i++) {\n if (this.remove(drawable[i], false, removeWithVertices, true)) {\n removedDrawables_1.push(drawable[i]);\n }\n }\n if (redraw) {\n this.redraw();\n }\n !doNotFireEvent && this._fireContentChanged([], removedDrawables_1);\n return removedDrawables_1.length > 0;\n }\n if (drawable instanceof Vertex_1.Vertex) {\n var wasRemoved_1 = this.removeVertex(drawable, false, false);\n if (redraw) {\n this.redraw();\n }\n !doNotFireEvent && this._fireContentChanged([], [drawable]);\n return wasRemoved_1;\n }\n var wasRemoved = false;\n var removedDrawables = [];\n for (var i = 0; i < this.drawables.length; i++) {\n if (this.drawables[i] === drawable || this.drawables[i].uid === drawable.uid) {\n this.drawables.splice(i, 1);\n removedDrawables.push(drawable);\n if (removeWithVertices) {\n // Check if some listeners need to be removed\n if (drawable instanceof Line_1.Line) {\n // Add some lines\n this.removeVertex(drawable.a, false, true);\n this.removeVertex(drawable.b, false, true);\n removedDrawables.push(drawable.a, drawable.b);\n }\n else if (drawable instanceof Vector_1.Vector) {\n this.removeVertex(drawable.a, false, true);\n this.removeVertex(drawable.b, false, true);\n removedDrawables.push(drawable.a, drawable.b);\n }\n else if (drawable instanceof VEllipse_1.VEllipse) {\n this.removeVertex(drawable.center, false, true);\n this.removeVertex(drawable.axis, false, true);\n removedDrawables.push(drawable.center, drawable.axis);\n }\n else if (drawable instanceof VEllipseSector_1.VEllipseSector) {\n this.removeVertex(drawable.ellipse.center, false, true);\n this.removeVertex(drawable.ellipse.axis, false, true);\n removedDrawables.push(drawable.ellipse.center, drawable.ellipse.axis);\n }\n else if (drawable instanceof Circle_1.Circle) {\n this.removeVertex(drawable.center, false, true);\n }\n else if (drawable instanceof CircleSector_1.CircleSector) {\n this.removeVertex(drawable.circle.center, false, true);\n removedDrawables.push(drawable.circle.center);\n }\n else if (drawable instanceof Polygon_1.Polygon) {\n // for( var i in drawable.vertices )\n for (var i = 0; i < drawable.vertices.length; i++) {\n this.removeVertex(drawable.vertices[i], false, true);\n removedDrawables.push(drawable.vertices[i]);\n }\n }\n else if (drawable instanceof Triangle_1.Triangle) {\n this.removeVertex(drawable.a, false, true);\n this.removeVertex(drawable.b, false, true);\n this.removeVertex(drawable.c, false, true);\n removedDrawables.push(drawable.a, drawable.b, drawable.c);\n }\n else if (drawable instanceof BezierPath_1.BezierPath) {\n for (var i = 0; i < drawable.bezierCurves.length; i++) {\n this.removeVertex(drawable.bezierCurves[i].startPoint, false, true);\n this.removeVertex(drawable.bezierCurves[i].startControlPoint, false, true);\n this.removeVertex(drawable.bezierCurves[i].endControlPoint, false, true);\n removedDrawables.push(drawable.bezierCurves[i].startPoint, drawable.bezierCurves[i].startControlPoint, drawable.bezierCurves[i].endControlPoint);\n if (i + 1 == drawable.bezierCurves.length) {\n this.removeVertex(drawable.bezierCurves[i].endPoint, false, true);\n removedDrawables.push(drawable.bezierCurves[i].endPoint);\n }\n }\n }\n else if (drawable instanceof PBImage_1.PBImage) {\n this.removeVertex(drawable.upperLeft, false, true);\n this.removeVertex(drawable.lowerRight, false, true);\n removedDrawables.push(drawable.upperLeft, drawable.lowerRight);\n }\n else if (drawable instanceof PBText_1.PBText) {\n this.removeVertex(drawable.anchor, false, true);\n removedDrawables.push(drawable.anchor);\n }\n } // END removeWithVertices\n if (redraw) {\n this.redraw();\n }\n !doNotFireEvent && this._fireContentChanged([], removedDrawables);\n wasRemoved = true;\n } // END if\n } // END for\n return wasRemoved;\n };\n /**\n * Remove a vertex from the vertex list.<br>\n *\n * @param {Vertex} vert - The vertex to remove.\n * @param {boolean} [redraw=false]\n * @method removeVertex\n * @instance\n * @memberof PlotBoilerplate\n * @return {boolean}\n **/\n PlotBoilerplate.prototype.removeVertex = function (vert, redraw, doNotFireEvent) {\n for (var i = 0; i < this.vertices.length; i++) {\n if (this.vertices[i] === vert) {\n this.vertices.splice(i, 1);\n if (redraw) {\n this.redraw();\n }\n !doNotFireEvent && this._fireContentChanged([], [vert]);\n return true;\n }\n }\n return false;\n };\n /**\n * Remove all elements.\n *\n * If you want to keep the vertices, pass `true`.\n *\n * @method removeAll\n * @param {boolean=false} keepVertices\n * @param {boolean=true} triggerRedraw - By default this method triggers the redraw routine; passing `false` will suppress redrawing.\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n */\n PlotBoilerplate.prototype.removeAll = function (keepVertices, triggerRedraw) {\n var removedDrawables = this.drawables;\n this.drawables = [];\n if (!Boolean(keepVertices)) {\n removedDrawables = removedDrawables.concat(this.vertices);\n this.vertices = [];\n }\n if (triggerRedraw || typeof triggerRedraw === \"undefined\") {\n this.redraw();\n }\n removedDrawables.length > 0 && this._fireContentChanged([], removedDrawables);\n };\n /**\n * Find the vertex near the given position.\n *\n * The position is the absolute vertex position, not the x-y-coordinates on the canvas.\n *\n * @param {XYCoords} position - The position of the vertex to search for.\n * @param {number} pixelTolerance - A radius around the position to include into the search.\n * Note that the tolerance will be scaled up/down when zoomed.\n * @return The vertex near the given position or undefined if none was found there.\n **/\n PlotBoilerplate.prototype.getVertexNear = function (pixelPosition, pixelTolerance) {\n var _b, _c;\n var p = this.locatePointNear(this.transformMousePosition(pixelPosition.x, pixelPosition.y), pixelTolerance / Math.min((_b = this.config.cssScaleX) !== null && _b !== void 0 ? _b : 1.0, (_c = this.config.cssScaleY) !== null && _c !== void 0 ? _c : 1.0));\n if (p && p.typeName == \"vertex\") {\n return this.vertices[p.vindex];\n }\n return undefined;\n };\n /**\n * Draw the grid with the current config settings.<br>\n *\n * This function is usually only used internally.\n *\n * @method drawGrid\n * @param {DrawLib} draw - The drawing library to use to draw lines.\n * @private\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.drawGrid = function (draw) {\n if (typeof draw === \"undefined\") {\n draw = this.draw;\n }\n var gScale = {\n x: (Grid_1.Grid.utils.mapRasterScale(this.config.rasterAdjustFactor, this.draw.scale.x) * this.config.rasterScaleX) /\n this.config.cssScaleX,\n y: (Grid_1.Grid.utils.mapRasterScale(this.config.rasterAdjustFactor, this.draw.scale.y) * this.config.rasterScaleY) /\n this.config.cssScaleY\n };\n var gSize = { width: this.grid.size.x * gScale.x, height: this.grid.size.y * gScale.y };\n var cs = { width: this.canvasSize.width / 2, height: this.canvasSize.height / 2 };\n var offset = this.draw.offset.clone().inv();\n // console.log( \"drawGrid\", gScale, gSize, cs, offset );\n offset.x =\n ((Math.round(offset.x + cs.width) / Math.round(gSize.width)) * gSize.width) / this.draw.scale.x +\n (((this.draw.offset.x - cs.width) / this.draw.scale.x) % gSize.width);\n offset.y =\n ((Math.round(offset.y + cs.height) / Math.round(gSize.height)) * gSize.height) / this.draw.scale.y +\n (((this.draw.offset.y - cs.height) / this.draw.scale.x) % gSize.height);\n if (this.drawConfig.drawGrid) {\n draw.setCurrentClassName(null);\n if (this.config.rasterGrid) {\n // TODO: move config member to drawConfig\n draw.setCurrentId(\"raster\");\n draw.raster(offset, this.canvasSize.width / this.draw.scale.x, this.canvasSize.height / this.draw.scale.y, gSize.width, gSize.height, \"rgba(0,128,255,0.125)\");\n }\n else {\n draw.setCurrentId(\"grid\");\n draw.grid(offset, this.canvasSize.width / this.draw.scale.x, this.canvasSize.height / this.draw.scale.y, gSize.width, gSize.height, \"rgba(0,128,255,0.095)\");\n }\n }\n };\n /**\n * Draw the origin with the current config settings.<br>\n *\n * This function is usually only used internally.\n *\n * @method drawOrigin\n * @param {DrawLib} draw - The drawing library to use to draw lines.\n * @private\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.drawOrigin = function (draw) {\n // Add a crosshair to mark the origin\n draw.setCurrentId(\"origin\");\n draw.crosshair({ x: 0, y: 0 }, 10, this.drawConfig.origin.color);\n };\n /**\n * This is just a tiny helper function to determine the render color of vertices.\n **/\n PlotBoilerplate.prototype._handleColor = function (h, color) {\n return h.attr.isSelected ? this.drawConfig.selectedVertex.color : h.attr.draggable ? color : \"rgba(128,128,128,0.5)\";\n };\n /**\n * Draw all drawables.\n *\n * This function is usually only used internally.\n *\n * @method drawDrawables\n * @param {number} renderTime - The current render time. It will be used to distinct\n * already draw vertices from non-draw-yet vertices.\n * @param {DrawLib} draw - The drawing library to use to draw lines.\n * @param {DrawLib} fill - The drawing library to use to fill areas.\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.drawDrawables = function (renderTime, draw, fill) {\n for (var i in this.drawables) {\n var d = this.drawables[i];\n this.draw.setCurrentId(d.uid);\n this.fill.setCurrentId(d.uid);\n this.draw.setCurrentClassName(d.className);\n this.fill.setCurrentClassName(d.className);\n this.drawDrawable(d, renderTime, draw, fill);\n }\n };\n /**\n * Draw the given drawable.\n *\n * This function is usually only used internally.\n *\n * @method drawDrawable\n * @param {Drawable} d - The drawable to draw.\n * @param {number} renderTime - The current render time. It will be used to distinct\n * already draw vertices from non-draw-yet vertices.\n * @param {DrawLib} draw - The drawing library to use to draw lines.\n * @param {DrawLib} fill - The drawing library to use to fill areas.\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.drawDrawable = function (d, renderTime, draw, fill) {\n if (d instanceof BezierPath_1.BezierPath) {\n var curveIndex = 0;\n for (var c in d.bezierCurves) {\n // Restore these settings again in each loop (will be overwritten)\n this.draw.setCurrentId(\"\".concat(d.uid, \"-\").concat(curveIndex));\n this.fill.setCurrentId(\"\".concat(d.uid, \"-\").concat(curveIndex));\n this.draw.setCurrentClassName(d.className);\n this.fill.setCurrentClassName(d.className);\n draw.cubicBezier(d.bezierCurves[c].startPoint, d.bezierCurves[c].endPoint, d.bezierCurves[c].startControlPoint, d.bezierCurves[c].endControlPoint, this.drawConfig.bezier.color, this.drawConfig.bezier.lineWidth);\n if (this.drawConfig.drawBezierHandlePoints && this.drawConfig.drawHandlePoints) {\n if (d.bezierCurves[c].startPoint.attr.visible) {\n var df = this.drawConfig.bezier.pathVertex.fill ? fill : draw;\n df.setCurrentId(\"\".concat(d.uid, \"_h0\"));\n df.setCurrentClassName(\"\".concat(d.className, \"-start-handle\"));\n if (d.bezierCurves[c].startPoint.attr.bezierAutoAdjust) {\n df.squareHandle(d.bezierCurves[c].startPoint, 5, this._handleColor(d.bezierCurves[c].startPoint, this.drawConfig.bezier.pathVertex.color));\n }\n else {\n df.diamondHandle(d.bezierCurves[c].startPoint, 7, this._handleColor(d.bezierCurves[c].startPoint, this.drawConfig.bezier.pathVertex.color));\n }\n }\n d.bezierCurves[c].startPoint.attr.renderTime = renderTime;\n if (d.bezierCurves[c].endPoint.attr.visible) {\n var df = this.drawConfig.bezier.pathVertex.fill ? fill : draw;\n df.setCurrentId(\"\".concat(d.uid, \"_h0\"));\n df.setCurrentClassName(\"\".concat(d.className, \"-start-handle\"));\n if (d.bezierCurves[c].endPoint.attr.bezierAutoAdjust) {\n df.squareHandle(d.bezierCurves[c].endPoint, 5, this._handleColor(d.bezierCurves[c].endPoint, this.drawConfig.bezier.pathVertex.color));\n }\n else {\n df.diamondHandle(d.bezierCurves[c].endPoint, 7, this._handleColor(d.bezierCurves[c].endPoint, this.drawConfig.bezier.pathVertex.color));\n }\n }\n if (d.bezierCurves[c].startControlPoint.attr.visible) {\n var df = this.drawConfig.bezier.controlVertex.fill ? fill : draw;\n df.setCurrentId(\"\".concat(d.uid, \"_h2\"));\n df.setCurrentClassName(\"\".concat(d.className, \"-start-control-handle\"));\n df.circleHandle(d.bezierCurves[c].startControlPoint, 3, this._handleColor(d.bezierCurves[c].startControlPoint, this.drawConfig.bezier.controlVertex.color));\n }\n if (d.bezierCurves[c].endControlPoint.attr.visible) {\n var df = this.drawConfig.bezier.controlVertex.fill ? fill : draw;\n df.setCurrentId(\"\".concat(d.uid, \"_h3\"));\n df.setCurrentClassName(\"\".concat(d.className, \"-end-control-handle\"));\n df.circleHandle(d.bezierCurves[c].endControlPoint, 3, this._handleColor(d.bezierCurves[c].endControlPoint, this.drawConfig.bezier.controlVertex.color));\n }\n d.bezierCurves[c].startPoint.attr.renderTime = renderTime;\n d.bezierCurves[c].endPoint.attr.renderTime = renderTime;\n d.bezierCurves[c].startControlPoint.attr.renderTime = renderTime;\n d.bezierCurves[c].endControlPoint.attr.renderTime = renderTime;\n }\n else {\n d.bezierCurves[c].startPoint.attr.renderTime = renderTime;\n d.bezierCurves[c].endPoint.attr.renderTime = renderTime;\n d.bezierCurves[c].startControlPoint.attr.renderTime = renderTime;\n d.bezierCurves[c].endControlPoint.attr.renderTime = renderTime;\n }\n if (this.drawConfig.drawBezierHandleLines && this.drawConfig.drawHandleLines) {\n draw.setCurrentId(\"\".concat(d.uid, \"_l0\"));\n draw.setCurrentClassName(\"\".concat(d.className, \"-start-line\"));\n draw.handleLine(d.bezierCurves[c].startPoint, d.bezierCurves[c].startControlPoint);\n draw.setCurrentId(\"\".concat(d.uid, \"_l1\"));\n draw.setCurrentClassName(\"\".concat(d.className, \"-end-line\"));\n draw.handleLine(d.bezierCurves[c].endPoint, d.bezierCurves[c].endControlPoint);\n }\n curveIndex++;\n } // END for\n }\n else if (d instanceof Polygon_1.Polygon) {\n draw.polygon(d, this.drawConfig.polygon.color, this.drawConfig.polygon.lineWidth);\n if (!this.drawConfig.drawHandlePoints) {\n for (var i in d.vertices) {\n d.vertices[i].attr.renderTime = renderTime;\n }\n }\n }\n else if (d instanceof Triangle_1.Triangle) {\n draw.polyline([d.a, d.b, d.c], false, this.drawConfig.triangle.color, this.drawConfig.triangle.lineWidth);\n if (!this.drawConfig.drawHandlePoints) {\n d.a.attr.renderTime = d.b.attr.renderTime = d.c.attr.renderTime = renderTime;\n }\n }\n else if (d instanceof VEllipse_1.VEllipse) {\n if (this.drawConfig.drawHandleLines) {\n draw.setCurrentId(\"\".concat(d.uid, \"_e0\"));\n draw.setCurrentClassName(\"\".concat(d.className, \"-v-line\"));\n draw.handleLine(d.center.clone().add(0, d.signedRadiusV()).rotate(d.rotation, d.center), d.axis); // , \"#c8c8c8\");\n draw.setCurrentId(\"\".concat(d.uid, \"_e1\"));\n draw.setCurrentClassName(\"\".concat(d.className, \"-h-line\"));\n draw.handleLine(d.center.clone().add(d.signedRadiusH(), 0).rotate(d.rotation, d.center), d.axis); // , \"#c8c8c8\");\n }\n draw.setCurrentId(d.uid);\n draw.setCurrentClassName(\"\".concat(d.className));\n draw.ellipse(d.center, \n // Math.abs(d.axis.x-d.center.x), Math.abs(d.axis.y-d.center.y),\n d.radiusH(), d.radiusV(), this.drawConfig.ellipse.color, this.drawConfig.ellipse.lineWidth, d.rotation);\n if (!this.drawConfig.drawHandlePoints) {\n d.center.attr.renderTime = renderTime;\n d.axis.attr.renderTime = renderTime;\n }\n }\n else if (d instanceof VEllipseSector_1.VEllipseSector) {\n draw.setCurrentId(d.uid);\n draw.setCurrentClassName(\"\".concat(d.className));\n var data = VEllipseSector_1.VEllipseSector.ellipseSectorUtils.describeSVGArc(d.ellipse.center.x, d.ellipse.center.y, d.ellipse.radiusH(), d.ellipse.radiusV(), d.startAngle, d.endAngle, d.ellipse.rotation, { moveToStart: true });\n draw.path(data, this.drawConfig.ellipseSector.color, this.drawConfig.ellipseSector.lineWidth);\n }\n else if (d instanceof Circle_1.Circle) {\n draw.circle(d.center, d.radius, this.drawConfig.circle.color, this.drawConfig.circle.lineWidth);\n }\n else if (d instanceof CircleSector_1.CircleSector) {\n draw.circleArc(d.circle.center, d.circle.radius, d.startAngle, d.endAngle, this.drawConfig.circleSector.color, this.drawConfig.circleSector.lineWidth);\n }\n else if (d instanceof Vertex_1.Vertex) {\n if (this.drawConfig.drawVertices && (!d.attr.selectable || !d.attr.draggable) && d.attr.visible) {\n // Draw as special point (grey)\n draw.circleHandle(d, 7, this.drawConfig.vertex.color);\n d.attr.renderTime = renderTime;\n }\n }\n else if (d instanceof Line_1.Line) {\n draw.line(d.a, d.b, this.drawConfig.line.color, this.drawConfig.line.lineWidth);\n if (!this.drawConfig.drawHandlePoints || !d.a.attr.selectable)\n d.a.attr.renderTime = renderTime;\n if (!this.drawConfig.drawHandlePoints || !d.b.attr.selectable)\n d.b.attr.renderTime = renderTime;\n }\n else if (d instanceof Vector_1.Vector) {\n draw.arrow(d.a, d.b, this.drawConfig.vector.color, this.drawConfig.vector.lineWidth);\n if (this.drawConfig.drawHandlePoints && d.b.attr.selectable && d.b.attr.visible) {\n draw.setCurrentId(\"\".concat(d.uid, \"_h0\"));\n draw.setCurrentClassName(\"\".concat(d.className, \"-handle\"));\n draw.circleHandle(d.b, 3, \"#a8a8a8\");\n }\n else {\n d.b.attr.renderTime = renderTime;\n }\n if (!this.drawConfig.drawHandlePoints || !d.a.attr.selectable)\n d.a.attr.renderTime = renderTime;\n if (!this.drawConfig.drawHandlePoints || !d.b.attr.selectable)\n d.b.attr.renderTime = renderTime;\n }\n else if (d instanceof PBImage_1.PBImage) {\n if (this.drawConfig.drawHandleLines) {\n draw.setCurrentId(\"\".concat(d.uid, \"_l0\"));\n draw.setCurrentClassName(\"\".concat(d.className, \"-line\"));\n draw.line(d.upperLeft, d.lowerRight, this.drawConfig.image.color, this.drawConfig.image.lineWidth);\n }\n fill.setCurrentId(d.uid);\n fill.image(d.image, d.upperLeft, d.lowerRight.clone().sub(d.upperLeft));\n if (this.drawConfig.drawHandlePoints) {\n draw.setCurrentId(\"\".concat(d.uid, \"_h0\"));\n draw.setCurrentClassName(\"\".concat(d.className, \"-lower-right\"));\n draw.circleHandle(d.lowerRight, 3, this.drawConfig.image.color);\n d.lowerRight.attr.renderTime = renderTime;\n }\n }\n else if (d instanceof PBText_1.PBText) {\n fill.setCurrentId(d.uid);\n fill.text(d.text, d.anchor.x, d.anchor.y, d);\n if (this.drawConfig.text.anchor) {\n draw.setCurrentId(\"\".concat(d.uid, \"_a0\"));\n draw.setCurrentClassName(\"\".concat(d.className, \"-anchor\"));\n (this.drawConfig.text.fill ? fill : draw).point(d.anchor, this.drawConfig.text.color);\n }\n d.anchor.attr.renderTime = renderTime;\n }\n else {\n console.error(\"Cannot draw object. Unknown class.\");\n }\n draw.setCurrentClassName(null);\n draw.setCurrentId(null);\n fill.setCurrentClassName(null);\n fill.setCurrentId(null);\n };\n /**\n * Draw the select-polygon (if there is one).\n *\n * This function is usually only used internally.\n *\n * @method drawSelectPolygon\n * @private\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.drawSelectPolygon = function (draw) {\n // Draw select polygon?\n if (this.selectPolygon != null && this.selectPolygon.vertices.length > 0) {\n draw.setCurrentId(this.selectPolygon.uid);\n draw.polygon(this.selectPolygon, \"#888888\");\n draw.crosshair(this.selectPolygon.vertices[0], 3, \"#008888\");\n }\n };\n /**\n * Draw all vertices that were not yet drawn with the given render time.<br>\n * <br>\n * This function is usually only used internally.\n *\n * @method drawVertices\n * @private\n * @param {number} renderTime - The current render time. It is used to distinct\n * already draw vertices from non-draw-yet vertices.\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.drawVertices = function (renderTime, draw) {\n // Draw all vertices as small squares if they were not already drawn by other objects\n for (var i in this.vertices) {\n if (this.drawConfig.drawVertices && this.vertices[i].attr.renderTime != renderTime && this.vertices[i].attr.visible) {\n draw.setCurrentId(this.vertices[i].uid);\n draw.squareHandle(this.vertices[i], 5, this._handleColor(this.vertices[i], \"rgb(0,128,192)\"));\n this.vertices[i].attr.renderTime = renderTime;\n }\n }\n };\n /**\n * Trigger redrawing of all objects.<br>\n * <br>\n * Usually this function is automatically called when objects change.\n *\n * @method redraw\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.redraw = function () {\n var renderTime = this.renderTime++;\n // Tell the drawing library that a new drawing cycle begins (required for the GL lib).\n this.draw.beginDrawCycle(renderTime);\n this.fill.beginDrawCycle(renderTime);\n if (this.config.preClear)\n this.config.preClear();\n this.clear();\n if (this.config.preDraw)\n this.config.preDraw(this.draw, this.fill);\n this.drawAll(renderTime, this.draw, this.fill);\n if (this.config.postDraw)\n this.config.postDraw(this.draw, this.fill);\n this.draw.endDrawCycle(renderTime);\n this.fill.endDrawCycle(renderTime);\n };\n /**\n * Draw all: drawables, grid, select-polygon and vertices.\n *\n * @method drawAll\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.drawAll = function (renderTime, draw, fill) {\n if (this.config.drawRaster) {\n this.drawGrid(draw);\n }\n if (this.config.drawOrigin) {\n this.drawOrigin(draw);\n }\n this.drawDrawables(renderTime, draw, fill);\n this.drawVertices(renderTime, draw);\n this.drawSelectPolygon(draw);\n // Clear IDs and classnames (postDraw hook might draw somthing and the do not want\n // to interfered with that).\n draw.setCurrentId(null);\n draw.setCurrentClassName(null);\n }; // END redraw\n /**\n * This function clears the canvas with the configured background color.<br>\n * <br>\n * This function is usually only used internally.\n *\n * @method clear\n * @private\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.clear = function () {\n // Note that elements might have an alpha channel. Clear the scene first.\n this.draw.clear(this.config.backgroundColor || \"white\");\n };\n /**\n * Clear the selection.<br>\n * <br>\n * This function is usually only used internally.\n *\n * @method clearSelection\n * @private\n * @param {boolean=} [redraw=false] - Indicates if the redraw function should be triggered.\n * @instance\n * @memberof PlotBoilerplate\n * @return {PlotBoilerplate} this\n **/\n PlotBoilerplate.prototype.clearSelection = function (redraw) {\n for (var i in this.vertices)\n this.vertices[i].attr.isSelected = false;\n if (redraw)\n this.redraw();\n return this;\n };\n /**\n * Get the current view port.\n *\n * @method viewport\n * @instance\n * @memberof PlotBoilerplate\n * @return {Bounds} The current viewport.\n **/\n PlotBoilerplate.prototype.viewport = function () {\n var _b, _c;\n return new Bounds_1.Bounds(this.transformMousePosition(0, 0), this.transformMousePosition(this.canvasSize.width * ((_b = this.config.cssScaleX) !== null && _b !== void 0 ? _b : 1.0), this.canvasSize.height * ((_c = this.config.cssScaleY) !== null && _c !== void 0 ? _c : 1.0)));\n };\n /**\n * Trigger the saveFile.hook.\n *\n * @method saveFile\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.saveFile = function () {\n this.hooks.saveFile(this);\n };\n /**\n * Internal helper function used to get 'float' properties from elements.\n * Used to determine border withs and paddings that were defined using CSS.\n */\n // TODO: this was moved to the DOM utils\n PlotBoilerplate.prototype.getFProp = function (elem, propName) {\n return parseFloat(globalThis.getComputedStyle(elem, null).getPropertyValue(propName));\n };\n /**\n * Get the available inner space of the given container.\n *\n * Size minus padding minus border.\n **/\n // TODO: this was moved to the DOM utils\n PlotBoilerplate.prototype.getAvailableContainerSpace = function () {\n var container = this.canvas.parentNode; // Element | Document | DocumentFragment;\n this.canvas.style.display = \"none\";\n var padding = this.getFProp(container, \"padding\") || 0, border = this.getFProp(this.canvas, \"border-width\") || 0, pl = this.getFProp(container, \"padding-left\") || padding, pr = this.getFProp(container, \"padding-right\") || padding, pt = this.getFProp(container, \"padding-top\") || padding, pb = this.getFProp(container, \"padding-bottom\") || padding, bl = this.getFProp(this.canvas, \"border-left-width\") || border, br = this.getFProp(this.canvas, \"border-right-width\") || border, bt = this.getFProp(this.canvas, \"border-top-width\") || border, bb = this.getFProp(this.canvas, \"border-bottom-width\") || border;\n var w = container.clientWidth;\n var h = container.clientHeight;\n this.canvas.style.display = \"block\";\n return { width: w - pl - pr - bl - br, height: h - pt - pb - bt - bb };\n };\n /**\n * This function resizes the canvas to the required settings (toggles fullscreen).<br>\n * <br>\n * This function is usually only used internally but feel free to call it if resizing required.\n *\n * @method resizeCanvas\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.resizeCanvas = function () {\n var _this = this;\n var _b, _c, _d, _e, _f, _g;\n var _self = this;\n var _setSize = function (w, h) {\n var _b, _c;\n w *= (_b = _self.config.canvasWidthFactor) !== null && _b !== void 0 ? _b : 1.0;\n h *= (_c = _self.config.canvasHeightFactor) !== null && _c !== void 0 ? _c : 1.0;\n _self.canvasSize.width = w;\n _self.canvasSize.height = h;\n if (_self.canvas instanceof HTMLCanvasElement) {\n _self.canvas.width = w;\n _self.canvas.height = h;\n }\n else if (_self.canvas instanceof SVGElement) {\n _this.canvas.setAttribute(\"viewBox\", \"0 0 \".concat(w, \" \").concat(h));\n _this.canvas.setAttribute(\"width\", \"\".concat(w));\n _this.canvas.setAttribute(\"height\", \"\".concat(h));\n _this.draw.setSize(_self.canvasSize); // No need to set size to this.fill (instance copy)\n _this.eventCatcher.style.width = \"\".concat(w, \"px\");\n _this.eventCatcher.style.height = \"\".concat(h, \"px\");\n }\n else {\n console.error(\"Error: cannot resize canvas element because it seems neither be a HTMLCanvasElement nor an SVGElement.\");\n }\n if (_self.config.autoAdjustOffset) {\n // _self.draw.offset.x = _self.fill.offset.x = _self.config.offsetX = w*(_self.config.offsetAdjustXPercent/100);\n // _self.draw.offset.y = _self.fill.offset.y = _self.config.offsetY = h*(_self.config.offsetAdjustYPercent/100);\n _self.adjustOffset(false);\n }\n };\n if (_self.config.fullSize && !_self.config.fitToParent) {\n // Set editor size\n var width = globalThis.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;\n var height = globalThis.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;\n _self.canvas.style.position = \"absolute\";\n _self.canvas.style.width = ((_b = _self.config.canvasWidthFactor) !== null && _b !== void 0 ? _b : 1.0) * width + \"px\";\n _self.canvas.style.height = ((_c = _self.config.canvasWidthFactor) !== null && _c !== void 0 ? _c : 1.0) * height + \"px\";\n _self.canvas.style.top = \"0px\";\n _self.canvas.style.left = \"0px\";\n _setSize(width, height);\n }\n else if (_self.config.fitToParent) {\n // Set editor size\n _self.canvas.style.position = \"static\";\n var space = this.getAvailableContainerSpace();\n _self.canvas.style.width = ((_d = _self.config.canvasWidthFactor) !== null && _d !== void 0 ? _d : 1.0) * space.width + \"px\";\n _self.canvas.style.height = ((_e = _self.config.canvasHeightFactor) !== null && _e !== void 0 ? _e : 1.0) * space.height + \"px\";\n _self.canvas.style.top = \"\";\n _self.canvas.style.left = \"\";\n _setSize(space.width, space.height);\n }\n else {\n _self.canvas.style.width = \"\";\n _self.canvas.style.height = \"\";\n _setSize((_f = _self.config.defaultCanvasWidth) !== null && _f !== void 0 ? _f : 1024, (_g = _self.config.defaultCanvasHeight) !== null && _g !== void 0 ? _g : 768);\n }\n if (_self.config.redrawOnResize)\n _self.redraw();\n };\n /**\n * Add all vertices inside the polygon to the current selection.<br>\n *\n * @method selectVerticesInPolygon\n * @param {Polygon} polygon - The polygonal selection area.\n * @instance\n * @memberof PlotBoilerplate\n * @return {void}\n **/\n PlotBoilerplate.prototype.selectVerticesInPolygon = function (polygon) {\n for (var i in this.vertices) {\n if (this.vertices[i].attr.selectable && polygon.containsVert(this.vertices[i]))\n this.vertices[i].attr.isSelected = true;\n }\n };\n /**\n * (Helper) Locates the point (index) at the passed position. Using an internal tolerance of 7 pixels.\n *\n * The result is an object { type : 'bpath', pindex, cindex, pid }\n *\n * Returns false if no point is near the passed position.\n *\n * @method locatePointNear\n * @param {Vertex} point - The polygonal selection area.\n * @param {number=} [tolerance=7] - The tolerance to use identtifying vertices.\n * @private\n * @return {IDraggable} Or false if none found.\n **/\n PlotBoilerplate.prototype.locatePointNear = function (point, tolerance) {\n var _self = this;\n if (typeof tolerance == \"undefined\")\n tolerance = 7;\n // Apply the zoom (the tolerant area should not shrink or grow when zooming)\n tolerance /= _self.draw.scale.x;\n // Search in vertices\n for (var vindex = 0; vindex < _self.vertices.length; vindex++) {\n var vert = _self.vertices[vindex];\n if ((vert.attr.draggable || vert.attr.selectable) && vert.distance(point) < tolerance) {\n // { type : 'vertex', vindex : vindex };\n return new PlotBoilerplate.Draggable(vert, PlotBoilerplate.Draggable.VERTEX).setVIndex(vindex);\n }\n }\n return null;\n };\n /**\n * Handle left-click event.<br>\n *\n * @method handleClick\n * @param {number} x - The click X position on the canvas.\n * @param {number} y - The click Y position on the canvas.\n * @private\n * @return {void}\n **/\n PlotBoilerplate.prototype.handleClick = function (e) {\n var _self = this;\n var point = this.locatePointNear(_self.transformMousePosition(e.params.pos.x, e.params.pos.y), PlotBoilerplate.DEFAULT_CLICK_TOLERANCE / Math.min(_self.config.cssScaleX || 1.0, _self.config.cssScaleY || 1.0));\n if (point) {\n _self.vertices[point.vindex].listeners.fireClickEvent(e);\n if (this.keyHandler && this.keyHandler.isDown(\"shift\")) {\n if (point.typeName == \"bpath\") {\n var vert = _self.paths[point.pindex].bezierCurves[point.cindex].getPointByID(point.pid);\n if (vert.attr.selectable)\n vert.attr.isSelected = !vert.attr.isSelected;\n }\n else if (point.typeName == \"vertex\") {\n var vert = _self.vertices[point.vindex];\n if (vert.attr.selectable)\n vert.attr.isSelected = !vert.attr.isSelected;\n }\n _self.redraw();\n }\n else if (this.keyHandler && this.keyHandler.isDown(\"y\")) {\n _self.vertices[point.vindex].attr.bezierAutoAdjust = !_self.vertices[point.vindex].attr.bezierAutoAdjust;\n _self.redraw();\n }\n }\n else if (_self.selectPolygon != null) {\n var vert = _self.transformMousePosition(e.params.pos.x, e.params.pos.y);\n _self.selectPolygon.vertices.push(new Vertex_1.Vertex(vert.x, vert.y));\n _self.redraw();\n }\n };\n /**\n * Transforms the given x-y-(mouse-)point to coordinates respecting the view offset\n * and the zoom settings.\n *\n * @method transformMousePosition\n * @param {number} x - The x position relative to the canvas.\n * @param {number} y - The y position relative to the canvas.\n * @instance\n * @memberof PlotBoilerplate\n * @return {XYCoords} A simple object <pre>{ x : Number, y : Number }</pre> with the transformed coordinates.\n **/\n PlotBoilerplate.prototype.transformMousePosition = function (x, y) {\n return {\n x: (x / this.config.cssScaleX - this.config.offsetX) / this.config.scaleX,\n y: (y / this.config.cssScaleY - this.config.offsetY) / this.config.scaleY\n };\n };\n /**\n * Revert a transformed mouse position back to canvas coordinates.\n *\n * This is the inverse function of `transformMousePosition`.\n *\n * @method revertMousePosition\n * @param {number} x - The x component of the position to revert.\n * @param {number} y - The y component of the position to revert.\n * @instance\n * @memberof PlotBoilerplate\n * @return {XYCoords} The canvas coordinates for the given position.\n **/\n PlotBoilerplate.prototype.revertMousePosition = function (x, y) {\n return { x: x / this.config.cssScaleX + this.config.offsetX, y: y / this.config.cssScaleY + this.config.offsetY };\n };\n /**\n * Determine if any elements are currently being dragged (on mouse move or touch move).\n *\n * @method getDraggedElementCount\n * @instance\n * @memberof PlotBoilerplate\n * @return {number} The number of elements that are currently being dragged.\n **/\n PlotBoilerplate.prototype.getDraggedElementCount = function () {\n return this.draggedElements.length;\n };\n /**\n * (Helper) The mouse-down handler.\n *\n * It selects vertices for dragging.\n *\n * @method mouseDownHandler.\n * @param {XMouseEvent} e - The event to handle\n * @private\n * @return {void}\n **/\n PlotBoilerplate.prototype.mouseDownHandler = function (e) {\n var _self = this;\n if (e.button != 0)\n return; // Only react on left mouse or touch events\n var draggablePoint = _self.locatePointNear(_self.transformMousePosition(e.params.pos.x, e.params.pos.y), PlotBoilerplate.DEFAULT_CLICK_TOLERANCE / Math.min(_self.config.cssScaleX, _self.config.cssScaleY));\n if (!draggablePoint)\n return;\n // Drag all selected elements?\n if (draggablePoint.typeName == \"vertex\" && _self.vertices[draggablePoint.vindex].attr.isSelected) {\n // Multi drag\n // for( var i in _self.vertices ) {\n for (var i = 0; i < _self.vertices.length; i++) {\n if (_self.vertices[i].attr.isSelected) {\n _self.draggedElements.push(new PlotBoilerplate.Draggable(_self.vertices[i], PlotBoilerplate.Draggable.VERTEX).setVIndex(i));\n _self.vertices[i].listeners.fireDragStartEvent(e);\n }\n }\n }\n else {\n // Single drag\n if (!_self.vertices[draggablePoint.vindex].attr.draggable)\n return;\n _self.draggedElements.push(draggablePoint);\n if (draggablePoint.typeName == \"bpath\")\n _self.paths[draggablePoint.pindex].bezierCurves[draggablePoint.cindex]\n .getPointByID(draggablePoint.pid)\n .listeners.fireDragStartEvent(e);\n else if (draggablePoint.typeName == \"vertex\")\n _self.vertices[draggablePoint.vindex].listeners.fireDragStartEvent(e);\n }\n _self.redraw();\n };\n /**\n * The mouse-drag handler.\n *\n * It moves selected elements around or performs the panning if the ctrl-key if\n * hold down.\n *\n * @method mouseDragHandler.\n * @param {XMouseEvent} e - The event to handle\n * @private\n * @return {void}\n **/\n PlotBoilerplate.prototype.mouseDragHandler = function (e) {\n var _self = this;\n var oldDragAmount = { x: e.params.dragAmount.x, y: e.params.dragAmount.y };\n e.params.dragAmount.x /= _self.config.cssScaleX;\n e.params.dragAmount.y /= _self.config.cssScaleY;\n // Important note to: this.keyHandler.isDown('ctrl')\n // We should not use this for any input.\n // Reason: most browsers use [Ctrl]+[t] to create new browser tabs.\n // If so, the key-up event for [Ctrl] will be fired in the _new tab_,\n // not this one. So this tab will never receive any [Ctrl-down] events\n // until next keypress; the implication is, that [Ctrl] would still\n // considered to be pressed which is not true.\n // if (this.keyHandler && (this.keyHandler.isDown(\"alt\") || this.keyHandler.isDown(\"spacebar\"))) {\n if (this.isInPanningMode) {\n if (!this.config.enablePan) {\n return;\n }\n _self.setOffset(_self.draw.offset.clone().add(e.params.dragAmount));\n _self.redraw();\n }\n else {\n // Convert drag amount by scaling\n // Warning: this possibly invalidates the dragEvent for other listeners!\n // Rethink the solution when other features are added.\n e.params.dragAmount.x /= _self.draw.scale.x;\n e.params.dragAmount.y /= _self.draw.scale.y;\n for (var i in _self.draggedElements) {\n var p = _self.draggedElements[i];\n if (p.typeName == \"bpath\") {\n _self.paths[p.pindex].moveCurvePoint(p.cindex, p.pid, new Vertex_1.Vertex(e.params.dragAmount.x, e.params.dragAmount.y));\n _self.paths[p.pindex].bezierCurves[p.cindex].getPointByID(p.pid).listeners.fireDragEvent(e);\n }\n else if (p.typeName == \"vertex\") {\n if (!_self.vertices[p.vindex].attr.draggable)\n continue;\n _self.vertices[p.vindex].add(e.params.dragAmount);\n _self.vertices[p.vindex].listeners.fireDragEvent(e);\n }\n }\n }\n // Restore old event values!\n e.params.dragAmount.x = oldDragAmount.x;\n e.params.dragAmount.y = oldDragAmount.y;\n _self.redraw();\n };\n /**\n * The mouse-up handler.\n *\n * It clears the dragging-selection.\n *\n * @method mouseUpHandler.\n * @param {XMouseEvent} e - The event to handle\n * @private\n * @return {void}\n **/\n PlotBoilerplate.prototype.mouseUpHandler = function (e) {\n var _self = this;\n if (e.button != 0)\n return; // Only react on left mouse;\n if (!e.params.wasDragged) {\n _self.handleClick(e); // e.params.pos.x, e.params.pos.y );\n }\n for (var i in _self.draggedElements) {\n var p = _self.draggedElements[i];\n if (p.typeName == \"bpath\") {\n _self.paths[p.pindex].bezierCurves[p.cindex].getPointByID(p.pid).listeners.fireDragEndEvent(e);\n }\n else if (p.typeName == \"vertex\") {\n _self.vertices[p.vindex].listeners.fireDragEndEvent(e);\n }\n }\n _self.draggedElements = [];\n _self.redraw();\n };\n /**\n * The mouse-wheel handler.\n *\n * It performs the zooming.\n *\n * @method mouseWheelHandler.\n * @param {XMouseEvent} e - The event to handle\n * @private\n * @return {void}\n **/\n PlotBoilerplate.prototype.mouseWheelHandler = function (e) {\n if (!this.config.enableZoom) {\n return;\n }\n var zoomStep = 1.25; // Make configurable?\n // CHANGED replaced _self by this\n var _self = this;\n var we = e;\n if (we.deltaY < 0) {\n _self.setZoom(_self.config.scaleX * zoomStep, _self.config.scaleY * zoomStep, new Vertex_1.Vertex(e.params.pos.x, e.params.pos.y));\n }\n else if (we.deltaY > 0) {\n _self.setZoom(_self.config.scaleX / zoomStep, _self.config.scaleY / zoomStep, new Vertex_1.Vertex(e.params.pos.x, e.params.pos.y));\n }\n e.preventDefault();\n _self.redraw();\n };\n /**\n * Re-adjust the configured offset depending on the current canvas size and zoom (scaleX and scaleY).\n *\n * @method adjustOffset\n * @param {boolean=false} redraw - [optional] If set the canvas will redraw with the new offset (default=false).\n * @return {void}\n **/\n PlotBoilerplate.prototype.adjustOffset = function (redraw) {\n this.draw.offset.x =\n this.fill.offset.x =\n this.config.offsetX =\n this.canvasSize.width * (this.config.offsetAdjustXPercent / 100);\n this.draw.offset.y =\n this.fill.offset.y =\n this.config.offsetY =\n this.canvasSize.height * (this.config.offsetAdjustYPercent / 100);\n if (redraw) {\n this.redraw();\n }\n };\n /**\n * Set the new draw offset.\n *\n * Note: the function will not trigger any redraws.\n *\n * @param {Vertex} newOffset - The new draw offset to use.\n **/\n PlotBoilerplate.prototype.setOffset = function (newOffset) {\n this.draw.offset.set(newOffset);\n this.fill.offset.set(newOffset);\n this.config.offsetX = newOffset.x;\n this.config.offsetY = newOffset.y;\n };\n /**\n * Set a new zoom value (and re-adjust the draw offset).\n *\n * Note: the function will not trigger any redraws.\n *\n * @param {number} zoomFactorX - The new horizontal zoom value.\n * @param {number} zoomFactorY - The new vertical zoom value.\n * @param {Vertex} interactionPos - The position of mouse/touch interaction.\n **/\n PlotBoilerplate.prototype.setZoom = function (zoomFactorX, zoomFactorY, interactionPos) {\n var oldPos = this.transformMousePosition(interactionPos.x, interactionPos.y);\n this.draw.scale.x = this.fill.scale.x = this.config.scaleX = Math.max(zoomFactorX, 0.01);\n this.draw.scale.y = this.fill.scale.y = this.config.scaleY = Math.max(zoomFactorY, 0.01);\n var newPos = this.transformMousePosition(interactionPos.x, interactionPos.y);\n var newOffsetX = this.draw.offset.x + (newPos.x - oldPos.x) * this.draw.scale.x;\n var newOffsetY = this.draw.offset.y + (newPos.y - oldPos.y) * this.draw.scale.y;\n this.setOffset({ x: newOffsetX, y: newOffsetY });\n };\n PlotBoilerplate.prototype.installInputListeners = function () {\n var _this = this;\n var _self = this;\n if (this.config.enableMouse) {\n // Install a mouse handler on the canvas.\n new MouseHandler_1.MouseHandler(this.eventCatcher ? this.eventCatcher : this.canvas)\n .down(function (e) {\n _self.mouseDownHandler(e);\n })\n .drag(function (e) {\n _self.mouseDragHandler(e);\n })\n .up(function (e) {\n _self.mouseUpHandler(e);\n });\n }\n else {\n _self.console.log(\"Mouse interaction disabled.\");\n }\n if (this.config.enableMouseWheel) {\n // Install a mouse handler on the canvas.\n new MouseHandler_1.MouseHandler(this.eventCatcher ? this.eventCatcher : this.canvas).wheel(function (e) {\n _self.mouseWheelHandler(e);\n });\n }\n else {\n _self.console.log(\"Mouse wheel interaction disabled.\");\n }\n if (this.config.enableTouch) {\n // Install a touch handler on the canvas.\n var relPos_1 = function (pos) {\n var bounds = _self.canvas.getBoundingClientRect();\n return { x: pos.x - bounds.left, y: pos.y - bounds.top };\n };\n // Make PB work together with both, AlloyFinger as a esm module or a commonjs function.\n if (typeof globalThis[\"AlloyFinger\"] === \"function\" ||\n typeof globalThis[\"createAlloyFinger\"] === \"function\") {\n try {\n var touchMovePos = null;\n var touchDownPos = null;\n var draggedElement = null;\n var multiTouchStartScale = null;\n var clearTouch_1 = function () {\n touchMovePos = null;\n touchDownPos = null;\n draggedElement = null;\n multiTouchStartScale = null;\n _self.draggedElements = [];\n };\n var afProps = {\n // touchStart: (evt: TouchEvent) => {\n touchStart: function (evt) {\n if (evt.touches.length == 1) {\n touchMovePos = new Vertex_1.Vertex(relPos_1({ x: evt.touches[0].clientX, y: evt.touches[0].clientY }));\n touchDownPos = new Vertex_1.Vertex(relPos_1({ x: evt.touches[0].clientX, y: evt.touches[0].clientY }));\n draggedElement = _self.locatePointNear(_self.transformMousePosition(touchMovePos.x, touchMovePos.y), PlotBoilerplate.DEFAULT_TOUCH_TOLERANCE / Math.min(_self.config.cssScaleX, _self.config.cssScaleY));\n if (draggedElement && draggedElement.typeName == \"vertex\") {\n var draggingVertex = _self.vertices[draggedElement.vindex];\n var fakeEvent = {\n params: {\n isTouchEvent: true,\n dragAmount: { x: 0, y: 0 },\n wasDragged: false,\n mouseDownPos: touchDownPos.clone(),\n mouseDragPos: touchDownPos.clone(),\n vertex: draggingVertex\n }\n };\n _self.draggedElements = [draggedElement];\n draggingVertex.listeners.fireDragStartEvent(fakeEvent);\n }\n }\n },\n touchMove: function (evt) {\n if (evt.touches.length == 1 && draggedElement) {\n evt.preventDefault();\n evt.stopPropagation();\n if (!touchDownPos || !touchMovePos) {\n return;\n }\n var rel = relPos_1({ x: evt.touches[0].clientX, y: evt.touches[0].clientY });\n var trans = _self.transformMousePosition(rel.x, rel.y);\n var diff = new Vertex_1.Vertex(_self.transformMousePosition(touchMovePos.x, touchMovePos.y)).difference(trans);\n if (draggedElement.typeName == \"vertex\") {\n if (!_self.vertices[draggedElement.vindex].attr.draggable)\n return;\n _self.vertices[draggedElement.vindex].add(diff);\n var draggingVertex = _self.vertices[draggedElement.vindex];\n var fakeEvent = {\n isTouchEvent: true,\n params: {\n dragAmount: diff.clone(),\n wasDragged: true,\n mouseDownPos: touchDownPos.clone(),\n mouseDragPos: touchDownPos.clone().add(diff),\n vertex: draggingVertex\n }\n };\n draggingVertex.listeners.fireDragEvent(fakeEvent);\n _self.redraw();\n }\n touchMovePos = new Vertex_1.Vertex(rel);\n }\n else if (evt.touches.length == 2) {\n if (!_this.config.enablePan) {\n return;\n }\n // If at least two fingers touch and move, then change the draw offset (panning).\n evt.preventDefault();\n evt.stopPropagation();\n _self.setOffset(_self.draw.offset\n .clone()\n .addXY(evt.deltaX, evt.deltaY)); // Apply zoom?\n _self.redraw();\n }\n },\n touchEnd: function (evt) {\n // Note: e.touches.length is 0 here\n if (draggedElement && draggedElement.typeName == \"vertex\") {\n if (!touchDownPos) {\n return;\n }\n var draggingVertex = _self.vertices[draggedElement.vindex];\n var fakeEvent = {\n isTouchEvent: true,\n params: {\n dragAmount: { x: 0, y: 0 },\n wasDragged: false,\n mouseDownPos: touchDownPos.clone(),\n mouseDragPos: touchDownPos.clone(),\n vertex: draggingVertex\n }\n };\n // Check if vertex was moved\n if (touchMovePos && touchDownPos && touchDownPos.distance(touchMovePos) < 0.001) {\n // if( e.touches.length == 1 && diff.x == 0 && diff.y == 0 ) {\n draggingVertex.listeners.fireClickEvent(fakeEvent);\n }\n else {\n draggingVertex.listeners.fireDragEndEvent(fakeEvent);\n }\n }\n clearTouch_1();\n },\n touchCancel: function (evt) {\n clearTouch_1();\n },\n multipointStart: function (evt) {\n multiTouchStartScale = _self.draw.scale.clone();\n },\n multipointEnd: function (evt) {\n multiTouchStartScale = null;\n },\n pinch: function (evt) {\n if (!_this.config.enableZoom) {\n return;\n }\n var touchItem0 = evt.touches.item(0);\n var touchItem1 = evt.touches.item(1);\n if (!evt.touches || !multiTouchStartScale || !touchItem0 || !touchItem1) {\n return;\n }\n // For pinching there must be at least two touch items\n var fingerA = new Vertex_1.Vertex(touchItem0.clientX, touchItem0.clientY);\n var fingerB = new Vertex_1.Vertex(touchItem1.clientX, touchItem1.clientY);\n var center = new Line_1.Line(fingerA, fingerB).vertAt(0.5);\n _self.setZoom(multiTouchStartScale.x * evt.zoom, multiTouchStartScale.y * evt.zoom, center);\n _self.redraw();\n }\n }; // END afProps\n if (window[\"createAlloyFinger\"]) {\n // window[\"createAlloyFinger\"](this.eventCatcher ? this.eventCatcher : this.canvas, afProps);\n var createAlloyFinger = window[\"createAlloyFinger\"];\n createAlloyFinger(this.eventCatcher ? this.eventCatcher : this.canvas, afProps);\n }\n else {\n /* tslint:disable-next-line */\n new alloyfinger_typescript_1.default(this.eventCatcher ? this.eventCatcher : this.canvas, afProps);\n }\n }\n catch (e) {\n console.error(\"Failed to initialize AlloyFinger!\");\n console.error(e);\n }\n }\n else if (globalThis[\"Touchy\"] && typeof globalThis[\"Touchy\"] == \"function\") {\n console.error(\"[Deprecation] Found Touchy which is not supported any more. Please use AlloyFinger instead.\");\n // Convert absolute touch positions to relative DOM element position (relative to canvas)\n }\n else {\n console.warn(\"Cannot initialize the touch handler. AlloyFinger is missig. Did you include it?\");\n }\n }\n else {\n _self.console.log(\"Touch interaction disabled.\");\n }\n if (this.config.enableKeys) {\n // Install key handler\n this.keyHandler = new KeyHandler_1.KeyHandler({ trackAll: true })\n .down(\"escape\", function () {\n _self.clearSelection(true);\n })\n .down(\"shift\", function () {\n _self.selectPolygon = new Polygon_1.Polygon();\n _self.redraw();\n })\n .up(\"shift\", function () {\n // Find and select vertices in the drawn area\n if (_self.selectPolygon == null)\n return;\n _self.selectVerticesInPolygon(_self.selectPolygon);\n _self.selectPolygon = null;\n _self.redraw();\n })\n .down(\"alt\", function () {\n _self.isInPanningMode = true;\n })\n .up(\"alt\", function () {\n _self.isInPanningMode = false;\n })\n .down(\"spacebar\", function () {\n _self.isInPanningMode = true;\n })\n .up(\"spacebar\", function () {\n _self.isInPanningMode = false;\n });\n } // END IF enableKeys?\n else {\n _self.console.log(\"Keyboard interaction disabled.\");\n }\n };\n /**\n * Creates a control GUI (a dat.gui instance) for this\n * plot boilerplate instance.\n *\n * @method createGUI\n * @instance\n * @memberof PlotBoilerplate\n * @return {dat.gui.GUI}\n **/\n PlotBoilerplate.prototype.createGUI = function (props) {\n // This function moved to the helper utils.\n // We do not want to include the whole dat.GUI package.\n var utils = globalThis[\"utils\"];\n // if (globalThis[\"utils\"] && typeof globalThis[\"utils\"].createGUI == \"function\") {\n // return (globalThis[\"utils\" as keyof Object] as any as ({createGUI : (pb:PlotBoilerplate,props:DatGuiProps|undefined)=>GUI })).createGUI(this, props);\n if (utils && typeof utils.createGUI === \"function\") {\n return (this._gui = utils.createGUI(this, props));\n }\n else {\n throw \"Cannot create dat.GUI or lil-gui instance; did you load the ./utils/creategui helper function an the dat.GUI/lil-gui library?\";\n }\n };\n /**\n * Retriebe the GUI once it was created. If the `createGUI` method was not called or failed to create any\n * GUI then null is returned.\n * @returns {GUI | null}\n */\n PlotBoilerplate.prototype.getGUI = function () {\n return this._gui;\n };\n var _a;\n /** @constant {number} */\n PlotBoilerplate.DEFAULT_CANVAS_WIDTH = 1024;\n /** @constant {number} */\n PlotBoilerplate.DEFAULT_CANVAS_HEIGHT = 768;\n /** @constant {number} */\n PlotBoilerplate.DEFAULT_CLICK_TOLERANCE = 8;\n /** @constant {number} */\n PlotBoilerplate.DEFAULT_TOUCH_TOLERANCE = 32;\n /**\n * A wrapper class for draggable items (mostly vertices).\n * @private\n **/\n PlotBoilerplate.Draggable = (_a = /** @class */ (function () {\n function class_1(item, typeName) {\n this.item = item;\n this.typeName = typeName;\n }\n class_1.prototype.isVertex = function () {\n return this.typeName == PlotBoilerplate.Draggable.VERTEX;\n };\n class_1.prototype.setVIndex = function (vindex) {\n this.vindex = vindex;\n return this;\n };\n return class_1;\n }()),\n __setFunctionName(_a, \"Draggable\"),\n _a.VERTEX = \"vertex\",\n _a);\n /**\n * A set of helper functions.\n **/\n PlotBoilerplate.utils = {\n /**\n * Merge the elements in the 'extension' object into the 'base' object based on\n * the keys of 'base'.\n *\n * @param {Object} base\n * @param {Object} extension\n * @return {Object} base extended by the new attributes.\n **/\n safeMergeByKeys: function (base, extension) {\n for (var k in extension) {\n if (!extension.hasOwnProperty(k)) {\n continue;\n }\n if (base.hasOwnProperty(k)) {\n var typ = typeof base[k];\n var extVal = extension[k];\n try {\n if (typ == \"boolean\") {\n if (typeof extVal === \"string\")\n base[k] = Boolean(!!JSON.parse(extVal));\n else\n base[k] = extVal;\n }\n else if (typ == \"number\") {\n if (typeof extVal === \"string\")\n base[k] = Number(JSON.parse(extVal) * 1);\n else\n base[k] = extension[k];\n }\n else if (typ == \"function\" && typeof extVal == \"function\") {\n base[k] = extension[k];\n }\n else {\n // Probably a sting\n base[k] = extension[k];\n }\n }\n catch (e) {\n console.error(\"error in key \", k, extVal, e);\n }\n }\n else {\n base[k] = extension[k];\n }\n }\n return base;\n },\n /*\n __safeMergeByKeys: <KeyType extends string | number | symbol, ValueType extends boolean | number | string | Function>(\n base: Record<KeyType, ValueType>,\n extension: Record<KeyType, string>\n ): Record<KeyType, ValueType> => {\n for (var k in extension) {\n if (!extension.hasOwnProperty(k)) continue;\n if (base.hasOwnProperty(k)) {\n var typ = typeof base[k];\n try {\n if (typ == \"boolean\") base[k] = !!JSON.parse(extension[k]);\n else if (typ == \"number\") base[k] = JSON.parse(extension[k]) * 1;\n else if (typ == \"function\" && typeof extension[k] == \"function\") base[k] = extension[k];\n else base[k] = extension[k];\n } catch (e) {\n console.error(\"error in key \", k, extension[k], e);\n }\n } else {\n base[k] = extension[k];\n }\n }\n return base;\n },\n *()\n \n /**\n * A helper function to scale elements (usually the canvas) using CSS.\n *\n * transform-origin is at (0,0).\n *\n * @param {HTMLElement} element - The DOM element to scale.\n * @param {number} scaleX The - X scale factor.\n * @param {number} scaleY The - Y scale factor.\n * @return {void}\n **/\n setCSSscale: function (element, scaleX, scaleY) {\n // element.style[\"transform-origin\"] = \"0 0\";\n element.style.transformOrigin = \"0 0\";\n if (scaleX == 1.0 && scaleY == 1.0) {\n // element.style.transform = null;\n element.style.removeProperty(\"transform\");\n }\n else\n element.style.transform = \"scale(\" + scaleX + \",\" + scaleY + \")\";\n },\n // A helper for fetching data from objects.\n fetch: {\n /**\n * A helper function to the the object property value specified by the given key.\n *\n * @param {any} object - The object to get the property's value from. Must not be null.\n * @param {string} key - The key of the object property (the name).\n * @param {any} fallback - A default value if the key does not exist.\n **/\n val: function (obj, key, fallback) {\n if (!obj.hasOwnProperty(key))\n return fallback;\n if (typeof obj[key] == \"undefined\")\n return fallback;\n return obj[key];\n },\n /**\n * A helper function to the the object property numeric value specified by the given key.\n *\n * @param {any} object - The object to get the property's value from. Must not be null.\n * @param {string} key - The key of the object property (the name).\n * @param {number} fallback - A default value if the key does not exist.\n * @return {number}\n **/\n num: function (obj, key, fallback) {\n if (!obj.hasOwnProperty(key))\n return fallback;\n if (typeof obj[key] === \"number\")\n return obj[key];\n else {\n try {\n return JSON.parse(obj[key]) * 1;\n }\n catch (e) {\n return fallback;\n }\n }\n },\n /**\n * A helper function to the the object property boolean value specified by the given key.\n *\n * @param {any} object - The object to get the property's value from. Must not be null.\n * @param {string} key - The key of the object property (the name).\n * @param {boolean} fallback - A default value if the key does not exist.\n * @return {boolean}\n **/\n bool: function (obj, key, fallback) {\n if (!obj.hasOwnProperty(key))\n return fallback;\n if (typeof obj[key] == \"boolean\")\n return obj[key];\n else {\n try {\n return !!JSON.parse(obj[key]);\n }\n catch (e) {\n return fallback;\n }\n }\n },\n /**\n * A helper function to the the object property function-value specified by the given key.\n *\n * @param {any} object - The object to get the property's value from. Must not be null.\n * @param {string} key - The key of the object property (the name).\n * @param {function} fallback - A default value if the key does not exist.\n * @return {function}\n **/\n func: function (obj, key, fallback) {\n if (!obj.hasOwnProperty(key))\n return fallback;\n if (typeof obj[key] !== \"function\")\n return fallback;\n return obj[key];\n }\n }, // END fetch\n /**\n * Installs vertex listeners to the path's vertices so that controlpoints\n * move with their path points when dragged.\n *\n * Bézier path points with attr.bezierAutoAdjust==true will have their\n * two control points audo-updated if moved, too (keep path connections smooth).\n *\n * @param {BezierPath} bezierPath - The path to use auto-adjustment for.\n **/\n enableBezierPathAutoAdjust: function (bezierPath) {\n for (var i = 0; i < bezierPath.bezierCurves.length; i++) {\n // This should be wrapped into the BezierPath implementation.\n bezierPath.bezierCurves[i].startPoint.listeners.addDragListener(function (e) {\n var cindex = bezierPath.locateCurveByStartPoint(e.params.vertex);\n bezierPath.bezierCurves[cindex].startPoint.addXY(-e.params.dragAmount.x, -e.params.dragAmount.y);\n bezierPath.moveCurvePoint(cindex * 1, bezierPath.START_POINT, e.params.dragAmount);\n bezierPath.updateArcLengths();\n });\n bezierPath.bezierCurves[i].startControlPoint.listeners.addDragListener(function (e) {\n var cindex = bezierPath.locateCurveByStartControlPoint(e.params.vertex);\n if (!bezierPath.bezierCurves[cindex].startPoint.attr.bezierAutoAdjust)\n return;\n bezierPath.adjustPredecessorControlPoint(cindex * 1, true, // obtain handle length?\n false // update arc lengths\n );\n bezierPath.updateArcLengths();\n });\n bezierPath.bezierCurves[i].endControlPoint.listeners.addDragListener(function (e) {\n var cindex = bezierPath.locateCurveByEndControlPoint(e.params.vertex);\n if (!bezierPath.bezierCurves[cindex % bezierPath.bezierCurves.length].endPoint.attr.bezierAutoAdjust)\n return;\n bezierPath.adjustSuccessorControlPoint(cindex * 1, true, // obtain handle length?\n false // update arc lengths\n );\n bezierPath.updateArcLengths();\n });\n if (i + 1 == bezierPath.bezierCurves.length) {\n // && !bezierPath.adjustCircular ) {\n // Move last control point with the end point (if not circular)\n bezierPath.bezierCurves[bezierPath.bezierCurves.length - 1].endPoint.listeners.addDragListener(function (e) {\n if (!bezierPath.adjustCircular) {\n var cindex = bezierPath.locateCurveByEndPoint(e.params.vertex);\n bezierPath.moveCurvePoint(cindex * 1, bezierPath.END_CONTROL_POINT, new Vertex_1.Vertex({ x: e.params.dragAmount.x, y: e.params.dragAmount.y }));\n }\n bezierPath.updateArcLengths();\n });\n }\n } // END for\n }\n }; // END utils\n return PlotBoilerplate;\n}()); // END class PlotBoilerplate\nexports.PlotBoilerplate = PlotBoilerplate;\nexports.default = PlotBoilerplate;\n//# sourceMappingURL=PlotBoilerplate.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2020-03-24\n * @modified 2020-05-04 Fixed a serious bug in the pointDistance function.\n * @modified 2020-05-12 The angle(line) param was still not optional. Changed that.\n * @modified 2020-11-11 Generalized the `add` and `sub` param from `Vertex` to `XYCoords`.\n * @modified 2020-12-04 Changed`vtutils.dist2` params from `Vertex` to `XYCoords` (generalized).\n * @modified 2020-12-04 Changed `getClosestT` param from `Vertex` to `XYCoords` (generalized).\n * @modified 2020-12-04 Added the `hasPoint(XYCoords)` function.\n * @modified 2021-01-20 Added UID.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2023-09-29 Fixed a calculation error in the VertTuple.hasPoint() function; distance measure was broken!\n * @modified 2024-09-10 Chaging the first param of `pointDistance` from `Vertex` to less strict type `XYCoords`. This should not break anything.\n * @modified 2024-09-10 Adding the optional `epsilon` param to the `hasPoint` method.\n * @modified 2024-12-02 Added the `epsilon` param to the `colinear` method. Default is 1.0e-6.\n * @modified 2025-03-31 Added the `VertTuple.revert` method.\n * @modified 2025-04-15 Changed param of `VertTuple.moveTo` method from `Vertex` to `XYCoords`.\n * @modified 2025-04-15 Added method `VertTuple.move` method.\n * @modified 2026-06-10 Adding helper function `VertTuple.utils.calcCircumcircle`.\n * @modified 2026-06-17 Adding method `VertTuple.asLine` for converting TertTuples to Line instances.\n * @modified 2026-09-21 Adding method `VertTuple.asVector` for converting TertTuples to Vector instances.\n * @version 1.7.0\n */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.VertTuple = void 0;\nvar Vertex_1 = require(\"./Vertex\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar Line_1 = require(\"./Line\");\nvar Vector_1 = require(\"./Vector\");\n/**\n * @classdesc An abstract base classes for vertex tuple constructs, like Lines or Vectors.\n * @abstract\n * @requires UID\n * @requires Vertex\n * @requires XYCoords\n */\nvar VertTuple = /** @class */ (function () {\n /**\n * Creates an instance.\n *\n * @constructor\n * @name VertTuple\n * @param {Vertex} a The tuple's first point.\n * @param {Vertex} b The tuple's second point.\n **/\n function VertTuple(a, b, factory) {\n this.uid = UIDGenerator_1.UIDGenerator.next();\n this.a = a;\n this.b = b;\n this.factory = factory;\n }\n /**\n * Get the length of this line.\n *\n * @method length\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.length = function () {\n return Math.sqrt(Math.pow(this.b.x - this.a.x, 2) + Math.pow(this.b.y - this.a.y, 2));\n };\n /**\n * Set the length of this vector to the given amount. This only works if this\n * vector is not a null vector.\n *\n * @method setLength\n * @param {number} length - The desired length.\n * @memberof VertTuple\n * @return {T} this (for chaining)\n **/\n VertTuple.prototype.setLength = function (length) {\n return this.scale(length / this.length());\n };\n /**\n * Substract the given vertex from this line's end points.\n *\n * @method sub\n * @param {XYCoords} amount The amount (x,y) to substract.\n * @return {VertTuple} this\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.sub = function (amount) {\n this.a.sub(amount);\n this.b.sub(amount);\n return this;\n };\n /**\n * Add the given vertex to this line's end points.\n *\n * @method add\n * @param {XYCoords} amount The amount (x,y) to add.\n * @instance\n * @memberof VertTuple\n * @return {VertTuple<T>} this\n **/\n VertTuple.prototype.add = function (amount) {\n this.a.add(amount);\n this.b.add(amount);\n return this;\n };\n /**\n * Reverse this vertex tuple: a becomes b, and b becomes a.\n * This operation is in-place.\n *\n * @method add\n * @param {XYCoords} amount The amount (x,y) to add.\n * @instance\n * @memberof VertTuple\n * @return {VertTuple<T>} this\n */\n VertTuple.prototype.revert = function () {\n var tmp = this.a;\n this.a = this.b;\n this.b = tmp;\n return this;\n };\n /**\n * Normalize this line (set to length 1).\n *\n * @method normalize\n * @return {VertTuple} this\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.normalize = function () {\n this.b.set(this.a.x + (this.b.x - this.a.x) / this.length(), this.a.y + (this.b.y - this.a.y) / this.length());\n return this;\n };\n /**\n * Scale this line by the given factor.\n *\n * @method scale\n * @param {number} factor The factor for scaling (1.0 means no scale).\n * @return {VertTuple} this\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.scale = function (factor) {\n this.b.set(this.a.x + (this.b.x - this.a.x) * factor, this.a.y + (this.b.y - this.a.y) * factor);\n return this;\n };\n /**\n * Move this line to a new location.\n *\n * @method moveTo\n * @param {XYCoords} newA - The new desired location of 'a'. Vertex 'b' will be moved, too.\n * @return {VertTuple} this\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.moveTo = function (newA) {\n var diff = this.a.difference(newA);\n this.a.add(diff);\n this.b.add(diff);\n return this;\n };\n /**\n * Move this line by the given amount\n *\n * @method move\n * @param {XYCoords} amount - The amount to move both point of this tuple.\n * @return {VertTuple} this\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.move = function (amount) {\n this.a.add(amount);\n this.b.add(amount);\n return this;\n };\n /**\n * Get the angle between this and the passed line (in radians).\n *\n * @method angle\n * @param {VertTuple} line - (optional) The line to calculate the angle to. If null the baseline (x-axis) will be used.\n * @return {number} this\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.angle = function (line) {\n if (line == null || typeof line == \"undefined\") {\n line = this.factory(new Vertex_1.Vertex(0, 0), new Vertex_1.Vertex(100, 0));\n }\n // Compute the angle from x axis and the return the difference :)\n var v0 = this.b.clone().sub(this.a);\n var v1 = line.b.clone().sub(line.a);\n // Thank you, Javascript, for this second atan function. No additional math is needed here!\n // The result might be negative, but isn't it usually nicer to determine angles in positive values only?\n return Math.atan2(v1.x, v1.y) - Math.atan2(v0.x, v0.y);\n };\n /**\n * Get line point at position t in [0 ... 1]:<br>\n * <pre>[P(0)]=[A]--------------------[P(t)]------[B]=[P(1)]</pre><br>\n * <br>\n * The counterpart of this function is Line.getClosestT(Vertex).\n *\n * @method vertAt\n * @param {number} t The position scalar.\n * @return {Vertex} The vertex a position t.\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.vertAt = function (t) {\n return new Vertex_1.Vertex(this.a.x + (this.b.x - this.a.x) * t, this.a.y + (this.b.y - this.a.y) * t);\n };\n /**\n * Get the denominator of this and the given line.\n *\n * If the denominator is zero (or close to zero) both line are co-linear.\n *\n * @method denominator\n * @param {VertTuple} line\n * @instance\n * @memberof VertTuple\n * @return {Number}\n **/\n VertTuple.prototype.denominator = function (line) {\n // http://jsfiddle.net/justin_c_rounds/Gd2S2/\n return (line.b.y - line.a.y) * (this.b.x - this.a.x) - (line.b.x - line.a.x) * (this.b.y - this.a.y);\n };\n /**\n * Checks if this and the given line are co-linear.\n *\n * The constant Vertex.EPSILON is used for tolerance.\n *\n * @method colinear\n * @param {VertTuple} line\n * @param {epsilon?=1.0e-6} epsilon - The epsilon to use (default is 1.0e-6).\n * @instance\n * @memberof VertTuple\n * @return true if both lines are co-linear.\n */\n VertTuple.prototype.colinear = function (line, epsilon) {\n return Math.abs(this.denominator(line)) < (typeof epsilon === \"undefined\" ? Vertex_1.Vertex.EPSILON : epsilon);\n };\n /**\n * Get the closest position T from this line to the specified point.\n *\n * The counterpart for this function is Line.vertAt(Number).\n *\n * @name getClosetT\n * @method getClosestT\n * @param {XYCoords} p The point (vertex) to measure the distance to.\n * @return {number} The line position t of minimal distance to p.\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.getClosestT = function (p) {\n var l2 = VertTuple.vtutils.dist2(this.a, this.b);\n if (l2 === 0)\n return 0;\n var t = ((p.x - this.a.x) * (this.b.x - this.a.x) + (p.y - this.a.y) * (this.b.y - this.a.y)) / l2;\n // Do not wrap to [0,1] here.\n // Other results are of interest, too.\n // t = Math.max(0, Math.min(1, t));\n return t;\n };\n /**\n * Check if the given point is located on this line. Optionally also check if\n * that point is located between point `a` and `b`.\n *\n * @method hasPoint\n * @param {Vertex} point - The point to check.\n * @param {boolean=} insideBoundsOnly - [optional] If set to to true (default=false) the point must be between start and end point of the line.\n * @param {number=Vertex.EPSILON} epsilon - [optional] A tolerance.\n * @return {boolean} True if the given point is on this line.\n * @instance\n * @memberof VertTuple\n */\n VertTuple.prototype.hasPoint = function (point, insideBoundsOnly, epsilon) {\n var t = this.getClosestT(point);\n // Compare to pointDistance?\n var distance = Math.sqrt(VertTuple.vtutils.dist2(point, this.vertAt(t)));\n if (typeof insideBoundsOnly !== \"undefined\" && insideBoundsOnly) {\n return distance < (epsilon !== null && epsilon !== void 0 ? epsilon : Vertex_1.Vertex.EPSILON) && t >= 0 && t <= 1;\n }\n else {\n return distance < (epsilon !== null && epsilon !== void 0 ? epsilon : Vertex_1.Vertex.EPSILON); // t >= 0 && t <= 1;\n }\n };\n /**\n * Get the closest point on this line to the specified point.\n *\n * @method getClosestPoint\n * @param {Vertex} p The point (vertex) to measre the distance to.\n * @return {Vertex} The point on the line that is closest to p.\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.getClosestPoint = function (p) {\n var t = this.getClosestT(p);\n return this.vertAt(t);\n };\n /**\n * The the minimal distance between this line and the specified point.\n *\n * @method pointDistance\n * @param {XYCoords} p The point (vertex) to measre the distance to.\n * @return {number} The absolute minimal distance.\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.pointDistance = function (p) {\n // Taken From:\n // https://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment\n return Math.sqrt(VertTuple.vtutils.dist2(p, this.vertAt(this.getClosestT(p))));\n };\n /**\n * Create a deep clone of this instance.\n *\n * @method clone\n * @return {T} A type safe clone if this instance.\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.clone = function () {\n return this.factory(this.a.clone(), this.b.clone());\n };\n /**\n * Converts this `VertTuple` to a `Line` (segment).\n *\n * @method asLine\n * @return {Line} This tuple as `Line` instance.\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.asLine = function () {\n return new Line_1.Line(this.a, this.b);\n };\n /**\n * Converts this `VertTuple` to a `Vector` (arrow).\n *\n * @method asVector\n * @return {Line} This tuple as `Vector` instance.\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.asVector = function () {\n return new Vector_1.Vector(this.a, this.b);\n };\n /**\n * Create a string representation of this line.\n *\n * @method totring\n * @return {string} The string representing this line.\n * @instance\n * @memberof VertTuple\n **/\n VertTuple.prototype.toString = function () {\n return \"{ a : \" + this.a.toString() + \", b : \" + this.b.toString() + \" }\";\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n VertTuple.prototype.destroy = function () {\n this.a.destroy();\n this.b.destroy();\n this.isDestroyed = true;\n };\n /**\n * @private\n **/\n VertTuple.vtutils = {\n dist2: function (v, w) {\n return (v.x - w.x) * (v.x - w.x) + (v.y - w.y) * (v.y - w.y);\n },\n calcCircumcircle: function (p1, p2) {\n var p1x = p1.x, p1y = p1.y, p2x = p2.x, p2y = p2.y, cx = 0.5 * (p1x + p2x), cy = 0.5 * (p1y + p2y);\n return { center: { x: cx, y: cy }, radius: Math.sqrt((p1x - cx) * (p1x - cx) + (p1y - cy) * (p1y - cy)) };\n }\n };\n return VertTuple;\n}());\nexports.VertTuple = VertTuple;\n//# sourceMappingURL=VertTuple.js.map","/* Port from AlloyFinger v0.1.15\n * Original by dntzhang\n * Typescript port by Ikaros Kappler\n * Github: https://github.com/IkarosKappler/AlloyFinger-Typescript\n *\n * @date 2021-02-10 (Typescript port)\n * @version 0.1.18\n */\n;\n/**\n * Tiny math function to calculate the length of a vector in euclidean space.\n *\n * @param {XYCoords} v - The vector in {x,y} notation.\n * @return {number} The length of the vector.\n */\nconst getLen = (v) => {\n return Math.sqrt(v.x * v.x + v.y * v.y);\n};\n/**\n * Tiny math function to calculate the dot product of two vectors.\n *\n * @param {XYCoords} v1 - The first vector in {x,y} notation.\n * @param {XYCoords} v2 - The second vector in {x,y} notation.\n * @return {number} The dot product of both vectors.\n */\nconst dot = (v1, v2) => {\n return v1.x * v2.x + v1.y * v2.y;\n};\n/**\n * Tiny math function to calculate the angle between two vectors.\n *\n * @param {XYCoords} v1 - The first vector in {x,y} notation.\n * @param {XYCoords} v2 - The second vector in {x,y} notation.\n * @return {number} The angle (in radians) between the two vectors.\n */\nconst getAngle = (v1, v2) => {\n const mr = getLen(v1) * getLen(v2);\n if (mr === 0)\n return 0;\n var r = dot(v1, v2) / mr;\n if (r > 1)\n r = 1;\n return Math.acos(r);\n};\n/**\n * Tiny math function to calculate the cross product of two vectors.\n *\n * @param {XYCoords} v1 - The first vector in {x,y} notation.\n * @param {XYCoords} v2 - The second vector in {x,y} notation.\n * @return {number} The cross product of both vectors.\n */\nconst cross = (v1, v2) => {\n return v1.x * v2.y - v2.x * v1.y;\n};\n/**\n * Tiny math function to calculate the rotate-angle (in degrees) for two vectors.\n *\n * @param {XYCoords} v1 - The first vector in {x,y} notation.\n * @param {XYCoords} v2 - The second vector in {x,y} notation.\n * @return {number} The rotate-angle in degrees for the two vectors.\n */\nconst getRotateAngle = (v1, v2) => {\n var angle = getAngle(v1, v2);\n if (cross(v1, v2) > 0) {\n angle *= -1;\n }\n return angle * 180 / Math.PI;\n};\n/**\n * A HandlerAdmin holds all the added event handlers for one kind of event type.\n */\nclass HandlerAdmin {\n constructor(el) {\n this.handlers = [];\n this.el = el;\n }\n ;\n add(handler) {\n this.handlers.push(handler);\n }\n ;\n del(handler) {\n if (!handler)\n this.handlers = [];\n for (var i = this.handlers.length; i >= 0; i--) {\n if (this.handlers[i] === handler) {\n this.handlers.splice(i, 1);\n }\n }\n }\n ;\n dispatch(..._args) {\n for (var i = 0, len = this.handlers.length; i < len; i++) {\n const handler = this.handlers[i];\n if (typeof handler === 'function') {\n handler.apply(this.el, arguments);\n }\n }\n }\n ;\n} // END class HandlerAdmin\n/**\n * A wrapper for handler functions; converts the passed handler function into a HadlerAdmin instance..\n */\nconst wrapFunc = (el, handler) => {\n const handlerAdmin = new HandlerAdmin(el);\n handlerAdmin.add(handler);\n return handlerAdmin;\n};\n/**\n * @classdesc The AlloyFinger main class. Use this to add handler functions for\n * touch events to any HTML- or SVG-Element.\n **/\nexport class AlloyFinger {\n constructor(el, option) {\n this.element = typeof el == 'string' ? document.querySelector(el) : el;\n // Fancy stuff: change `this` from the start-, move-, end- and cancel-function.\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind\n this.start = this.start.bind(this);\n this.move = this.move.bind(this);\n this.end = this.end.bind(this);\n this.cancel = this.cancel.bind(this);\n this.element.addEventListener(\"touchstart\", this.start, false);\n this.element.addEventListener(\"touchmove\", this.move, false);\n this.element.addEventListener(\"touchend\", this.end, false);\n this.element.addEventListener(\"touchcancel\", this.cancel, false);\n this.preV = { x: null, y: null };\n this.pinchStartLen = null;\n this.zoom = 1;\n this.isDoubleTap = false;\n const noop = () => { };\n this.rotate = wrapFunc(this.element, option.rotate || noop);\n this.touchStart = wrapFunc(this.element, option.touchStart || noop);\n this.multipointStart = wrapFunc(this.element, option.multipointStart || noop);\n this.multipointEnd = wrapFunc(this.element, option.multipointEnd || noop);\n this.pinch = wrapFunc(this.element, option.pinch || noop);\n this.swipe = wrapFunc(this.element, option.swipe || noop);\n this.tap = wrapFunc(this.element, option.tap || noop);\n this.doubleTap = wrapFunc(this.element, option.doubleTap || noop);\n this.longTap = wrapFunc(this.element, option.longTap || noop);\n this.singleTap = wrapFunc(this.element, option.singleTap || noop);\n this.pressMove = wrapFunc(this.element, option.pressMove || noop);\n this.twoFingerPressMove = wrapFunc(this.element, option.twoFingerPressMove || noop);\n this.touchMove = wrapFunc(this.element, option.touchMove || noop);\n this.touchEnd = wrapFunc(this.element, option.touchEnd || noop);\n this.touchCancel = wrapFunc(this.element, option.touchCancel || noop);\n this._cancelAllHandler = this.cancelAll.bind(this);\n if (globalThis && typeof globalThis.addEventListener === \"function\") {\n globalThis.addEventListener('scroll', this._cancelAllHandler);\n }\n this.delta = null;\n this.last = null;\n this.now = null;\n this.tapTimeout = null;\n this.singleTapTimeout = null;\n this.longTapTimeout = null;\n this.swipeTimeout = null;\n this.x1 = this.x2 = this.y1 = this.y2 = null;\n this.preTapPosition = { x: null, y: null };\n }\n ;\n start(evt) {\n if (!evt.touches)\n return;\n const _self = this;\n this.now = Date.now();\n this.x1 = evt.touches[0].pageX;\n this.y1 = evt.touches[0].pageY;\n this.delta = this.now - (this.last || this.now);\n this.touchStart.dispatch(evt, this.element);\n if (this.preTapPosition.x !== null) {\n this.isDoubleTap = (this.delta > 0 && this.delta <= 250 && Math.abs(this.preTapPosition.x - this.x1) < 30 && Math.abs(this.preTapPosition.y - this.y1) < 30);\n if (this.isDoubleTap)\n clearTimeout(this.singleTapTimeout);\n }\n this.preTapPosition.x = this.x1;\n this.preTapPosition.y = this.y1;\n this.last = this.now;\n const preV = this.preV;\n const len = evt.touches.length;\n if (len > 1) {\n this._cancelLongTap();\n this._cancelSingleTap();\n const v = { x: evt.touches[1].pageX - this.x1, y: evt.touches[1].pageY - this.y1 };\n preV.x = v.x;\n preV.y = v.y;\n this.pinchStartLen = getLen(preV);\n this.multipointStart.dispatch(evt, this.element);\n }\n this._preventTap = false;\n this.longTapTimeout = setTimeout((() => {\n _self.longTap.dispatch(evt, _self.element);\n _self._preventTap = true;\n }).bind(_self), 750);\n }\n ;\n move(event) {\n if (!event.touches)\n return;\n const afEvent = event;\n const preV = this.preV;\n const len = event.touches.length;\n const currentX = event.touches[0].pageX;\n const currentY = event.touches[0].pageY;\n this.isDoubleTap = false;\n if (len > 1) {\n const sCurrentX = afEvent.touches[1].pageX;\n const sCurrentY = afEvent.touches[1].pageY;\n const v = { x: afEvent.touches[1].pageX - currentX, y: afEvent.touches[1].pageY - currentY };\n if (preV.x !== null) {\n if (this.pinchStartLen > 0) {\n afEvent.zoom = getLen(v) / this.pinchStartLen;\n this.pinch.dispatch(afEvent, this.element);\n }\n afEvent.angle = getRotateAngle(v, preV);\n this.rotate.dispatch(afEvent, this.element);\n }\n preV.x = v.x;\n preV.y = v.y;\n if (this.x2 !== null && this.sx2 !== null) {\n afEvent.deltaX = (currentX - this.x2 + sCurrentX - this.sx2) / 2;\n afEvent.deltaY = (currentY - this.y2 + sCurrentY - this.sy2) / 2;\n }\n else {\n afEvent.deltaX = 0;\n afEvent.deltaY = 0;\n }\n this.twoFingerPressMove.dispatch(afEvent, this.element);\n this.sx2 = sCurrentX;\n this.sy2 = sCurrentY;\n }\n else {\n if (this.x2 !== null) {\n afEvent.deltaX = currentX - this.x2;\n afEvent.deltaY = currentY - this.y2;\n //move事件中添加对当前触摸点到初始触摸点的判断,\n //如果曾经大于过某个距离(比如10),就认为是移动到某个地方又移回来,应该不再触发tap事件才对。\n //\n // translation:\n // Add the judgment of the current touch point to the initial touch point in the event,\n // If it has been greater than a certain distance (such as 10), it is considered to be\n // moved to a certain place and then moved back, and the tap event should no longer be triggered.\n const movedX = Math.abs(this.x1 - this.x2);\n const movedY = Math.abs(this.y1 - this.y2);\n if (movedX > 10 || movedY > 10) {\n this._preventTap = true;\n }\n }\n else {\n afEvent.deltaX = 0;\n afEvent.deltaY = 0;\n }\n this.pressMove.dispatch(afEvent, this.element);\n }\n this.touchMove.dispatch(afEvent, this.element);\n this._cancelLongTap();\n this.x2 = currentX;\n this.y2 = currentY;\n if (len > 1) {\n event.preventDefault();\n }\n }\n ; // END move\n end(event) {\n if (!event.changedTouches)\n return;\n const afEvent = event;\n this._cancelLongTap();\n const self = this;\n if (afEvent.touches.length < 2) {\n this.multipointEnd.dispatch(afEvent, this.element);\n this.sx2 = this.sy2 = null;\n }\n //swipe\n if ((this.x2 && Math.abs(this.x1 - this.x2) > 30) ||\n (this.y2 && Math.abs(this.y1 - this.y2) > 30)) {\n afEvent.direction = this._swipeDirection(this.x1, this.x2, this.y1, this.y2);\n this.swipeTimeout = setTimeout(function () {\n self.swipe.dispatch(afEvent, self.element);\n }, 0);\n }\n else {\n this.tapTimeout = setTimeout(function () {\n if (!self._preventTap) {\n self.tap.dispatch(afEvent, self.element);\n }\n // trigger double tap immediately\n if (self.isDoubleTap) {\n self.doubleTap.dispatch(afEvent, self.element);\n self.isDoubleTap = false;\n }\n }, 0);\n if (!self.isDoubleTap) {\n self.singleTapTimeout = setTimeout(function () {\n self.singleTap.dispatch(afEvent, self.element);\n }, 250);\n }\n }\n this.touchEnd.dispatch(afEvent, this.element);\n this.preV.x = 0;\n this.preV.y = 0;\n this.zoom = 1;\n this.pinchStartLen = null;\n this.x1 = this.x2 = this.y1 = this.y2 = null;\n }\n ; // END end\n cancelAll() {\n this._preventTap = true;\n clearTimeout(this.singleTapTimeout);\n clearTimeout(this.tapTimeout);\n clearTimeout(this.longTapTimeout);\n clearTimeout(this.swipeTimeout);\n }\n ;\n cancel(evt) {\n this.cancelAll();\n this.touchCancel.dispatch(evt, this.element);\n }\n ;\n _cancelLongTap() {\n clearTimeout(this.longTapTimeout);\n }\n ;\n _cancelSingleTap() {\n clearTimeout(this.singleTapTimeout);\n }\n ;\n _swipeDirection(x1, x2, y1, y2) {\n return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down');\n }\n ;\n on(evt, handler) {\n if (this[evt]) {\n // Force the generic parameter into it's expected candidate here ;)\n const admin = this[evt];\n admin.add(handler);\n }\n }\n ;\n off(evt, handler) {\n if (this[evt]) {\n // Force the generic parameter into it's expected candidate here ;)\n const admin = this[evt];\n admin.del(handler);\n }\n }\n ;\n destroy() {\n if (this.singleTapTimeout) {\n clearTimeout(this.singleTapTimeout);\n }\n if (this.tapTimeout) {\n clearTimeout(this.tapTimeout);\n }\n if (this.longTapTimeout) {\n clearTimeout(this.longTapTimeout);\n }\n if (this.swipeTimeout) {\n clearTimeout(this.swipeTimeout);\n }\n this.element.removeEventListener(\"touchstart\", this.start);\n this.element.removeEventListener(\"touchmove\", this.move);\n this.element.removeEventListener(\"touchend\", this.end);\n this.element.removeEventListener(\"touchcancel\", this.cancel);\n this.rotate.del();\n this.touchStart.del();\n this.multipointStart.del();\n this.multipointEnd.del();\n this.pinch.del();\n this.swipe.del();\n this.tap.del();\n this.doubleTap.del();\n this.longTap.del();\n this.singleTap.del();\n this.pressMove.del();\n this.twoFingerPressMove.del();\n this.touchMove.del();\n this.touchEnd.del();\n this.touchCancel.del();\n this.preV = this.pinchStartLen = this.zoom = this.isDoubleTap = this.delta = this.last = this.now = this.tapTimeout = this.singleTapTimeout = this.longTapTimeout = this.swipeTimeout = this.x1 = this.x2 = this.y1 = this.y2 = this.preTapPosition = this.rotate = this.touchStart = this.multipointStart = this.multipointEnd = this.pinch = this.swipe = this.tap = this.doubleTap = this.longTap = this.singleTap = this.pressMove = this.touchMove = this.touchEnd = this.touchCancel = this.twoFingerPressMove = null;\n if (globalThis && typeof globalThis.removeEventListener === \"function\") {\n globalThis.removeEventListener('scroll', this._cancelAllHandler);\n }\n }\n ; // END destroy\n}\n;\nexport default AlloyFinger;\n//# sourceMappingURL=alloy_finger.js.map","/**\n * TypeScript port by Ikaros Kappler.\n *\n * Original file from https://github.com/AlloyTeam/AlloyFinger\n *\n * @date 2021-02-10\n */\nimport { AlloyFinger } from './alloy_finger';\nexport { AlloyFinger };\nexport default AlloyFinger;\n//# sourceMappingURL=index.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2021-11-16\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2023-09-25 Fixed a type error in the constructor. Nothing vital.\n * @version 1.1.1\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.PBText = void 0;\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar Vertex_1 = require(\"./Vertex\");\n/**\n * @classdesc A simple text element: position, fontSize, fontFamily, color, textAlign, lineHeight and rotation.\n *\n * @requires FontOptions\n * @requires FontSize\n * @requires FontStyle\n * @requires FontWeight\n * @requires Vertex\n * @requires SVGSerializale\n * @requires UID\n * @requires UIDGenerator\n **/\nvar PBText = /** @class */ (function () {\n /**\n * Create a new circle with given center point and radius.\n *\n * @constructor\n * @name Circle\n * @param {Vertex} center - The center point of the circle.\n * @param {number} radius - The radius of the circle.\n */\n function PBText(text, anchor, options) {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"PBText\";\n this.uid = UIDGenerator_1.UIDGenerator.next();\n this.text = text;\n this.anchor = anchor !== null && anchor !== void 0 ? anchor : new Vertex_1.Vertex();\n this.color = options === null || options === void 0 ? void 0 : options.color;\n this.fontFamily = options === null || options === void 0 ? void 0 : options.fontFamily;\n this.fontSize = options === null || options === void 0 ? void 0 : options.fontSize;\n this.fontStyle = options === null || options === void 0 ? void 0 : options.fontStyle;\n this.fontWeight = options === null || options === void 0 ? void 0 : options.fontWeight;\n this.lineHeight = options === null || options === void 0 ? void 0 : options.lineHeight;\n this.textAlign = options === null || options === void 0 ? void 0 : options.textAlign;\n this.rotation = options === null || options === void 0 ? void 0 : options.rotation;\n }\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n PBText.prototype.destroy = function () {\n this.anchor.destroy();\n this.isDestroyed = true;\n };\n return PBText;\n}()); // END class\nexports.PBText = PBText;\n//# sourceMappingURL=PBText.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2018-04-14\n * @modified 2018-11-17 Added the containsVert function.\n * @modified 2018-12-04 Added the toSVGString function.\n * @modified 2019-03-20 Added JSDoc tags.\n * @modified 2019-10-25 Added the scale function.\n * @modified 2019-11-06 JSDoc update.\n * @modified 2019-11-07 Added toCubicBezierPath(number) function.\n * @modified 2019-11-22 Added the rotate(number,Vertex) function.\n * @modified 2020-03-24 Ported this class from vanilla-JS to Typescript.\n * @modified 2020-10-30 Added the `addVertex` function.\n * @modified 2020-10-31 Added the `getVertexAt` function.\n * @modified 2020-11-06 Added the `move` function.\n * @modified 2020-11-10 Added the `getBounds` function.\n * @modified 2020-11-11 Generalized `move(Vertex)` to `move(XYCoords)`.\n * @modified 2021-01-20 Added UID.\n * @modified 2021-01-29 Added the `signedArea` function (was global function in the demos before).\n * @modified 2021-01-29 Added the `isClockwise` function.\n * @modified 2021-01-29 Added the `area` function.\n * @modified 2021-01-29 Changed the param type for `containsVert` from Vertex to XYCoords.\n * @modified 2021-12-14 Added the `perimeter()` function.\n * @modified 2021-12-16 Added the `getEvenDistributionPolygon()` function.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-02-02 Cleared the `Polygon.toSVGString` function (deprecated). Use `drawutilssvg` instead.\n * @modified 2022-03-08 Added the `Polygon.clone()` function.\n * @modified 2023-09-25 Added the `Polygon.getInterpolationPolygon(number)` function.\n * @modified 2023-09-25 Added the `Polygon.lineIntersections(Line,boolean)` function.\n * @modified 2023-09-29 Added the `Polygon.closestLineIntersection(Line,boolean)` function.\n * @modified 2023-11-24 Added the `Polygon.containsPolygon(Polygon)' function.\n * @modified 2024-10-12 Added the `getEdgeAt` method.\n * @modified 2024-10-30 Added the `getEdges` method.\n * @modified 2024-12-02 Added the `elimitateColinearEdges` method.\n * @modified 2025-02-12 Added the `containsVerts` method to test multiple vertices for containment.\n * @modified 2025-03-28 Added the `Polygon.utils.locateLineIntersecion` static helper method.\n * @modified 2025-03-28 Added the `Polygon.lineIntersectionTangents` method.\n * @modified 2025-04-09 Added the `Polygon.getCentroid` method.\n * @modified 2025-05-16 Class `Polygon` now implements `IBounded`.\n * @modified 2025-05-20 Tweaking `Polygon.getInnerAngleAt` and `Polygo.isAngleAcute` to handle indices out of array bounds as well.\n * @modified 2025-06-07 Adding `Polygon.closestLineIntersectionIndex` to determine line intersections plus detected edge index.\n * @modified 2026-09-16 Adding a `forceClockwise` parameter to the `Polygon.getCentroid()` method.\n * @modified 2026-09-21 Adding `Polygon.revert` method to change the winding order.\n * @version 1.17.0\n *\n * @file Polygon\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Polygon = void 0;\nvar BezierPath_1 = require(\"./BezierPath\");\nvar Bounds_1 = require(\"./Bounds\");\nvar Line_1 = require(\"./Line\");\nvar Triangle_1 = require(\"./Triangle\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar Vector_1 = require(\"./Vector\");\nvar Vertex_1 = require(\"./Vertex\");\nvar geomutils_1 = require(\"./geomutils\");\n/**\n * @classdesc A polygon class. Any polygon consists of an array of vertices; polygons can be open or closed.\n *\n * @requires BezierPath\n * @requires Bounds\n * @requires SVGSerializabe\n * @requires UID\n * @requires UIDGenerator\n * @requires Vertex\n * @requires XYCoords\n */\nvar Polygon = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name Polygon\n * @param {Vertex[]} vertices - An array of 2d vertices that shape the polygon.\n * @param {boolean} isOpen - Indicates if the polygon should be rendered as an open or closed shape.\n **/\n function Polygon(vertices, isOpen) {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"Polygon\";\n this.uid = UIDGenerator_1.UIDGenerator.next();\n if (typeof vertices == \"undefined\") {\n vertices = [];\n }\n this.vertices = vertices;\n this.isOpen = isOpen || false;\n }\n /**\n * Add a vertex to the end of the `vertices` array.\n *\n * @method addVertex\n * @param {Vertex} vert - The vertex to add.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.addVertex = function (vert) {\n this.vertices.push(vert);\n };\n /**\n * Add a vertex at a particular position of the `vertices` array.\n *\n * @method addVertexAt\n * @param {Vertex} vert - The vertex to add.\n * @param {number} index - The position to add the vertex at. Will be handled modulo.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.addVertexAt = function (vert, index) {\n // var moduloIndex = index % (this.vertices.length + 1);\n this.vertices.splice(index, 0, vert);\n };\n /**\n * Get a new instance of the line at the given start index. The returned line will consist\n * of the vertex at `vertIndex` and `vertIndex+1` (will be handled modulo).\n *\n * @method getEdgeAt\n * @param {number} vertIndex - The vertex index of the line to start.\n * @instance\n * @memberof Polygon\n * @return {Line}\n **/\n Polygon.prototype.getEdgeAt = function (vertIndex) {\n return new Line_1.Line(this.getVertexAt(vertIndex), this.getVertexAt(vertIndex + 1));\n };\n /**\n * Converts this polygon into a sequence of lines. Please note that each time\n * this method is called new lines are created. The underlying line vertices are no clones\n * (instances).\n *\n * @method getEdges\n * @instance\n * @memberof Polygon\n * @return {Array<Line>}\n */\n Polygon.prototype.getEdges = function () {\n var lines = [];\n for (var i = 0; i + 1 < this.vertices.length; i++) {\n // var line = this.getLineAt(i).clone();\n lines.push(this.getEdgeAt(i));\n }\n if (!this.isOpen && this.vertices.length > 0) {\n lines.push(this.getEdgeAt(this.vertices.length - 1));\n }\n return lines;\n };\n /**\n * Checks if the angle at the given polygon vertex (index) is acute. Please not that this is\n * only working for clockwise polygons. If this polygon is not clockwise please use the\n * `isClockwise` method and reverse polygon vertices if needed.\n *\n * @method isAngleAcute\n * @instance\n * @memberof Polygon\n * @param {number} vertIndex - The index of the polygon vertex to check.\n * @returns {boolean} `true` is angle is acute, `false` is obtuse.\n */\n Polygon.prototype.getInnerAngleAt = function (vertIndex) {\n var p2 = this.vertices[vertIndex % this.vertices.length];\n var p1 = this.vertices[(vertIndex + this.vertices.length - 1) % this.vertices.length].clone();\n var p3 = this.vertices[(vertIndex + 1) % this.vertices.length].clone();\n // See\n // https://math.stackexchange.com/questions/149959/how-to-find-the-interior-angle-of-an-irregular-pentagon-or-polygon\n // π−arccos((P2−P1)⋅(P3−P2)|P2−P1||P3−P2|)\n // Check if triangle is acute (will be used later)\n // Acute angles and obtuse angles need to be handled differently.\n var isAcute = this.isAngleAcute(vertIndex);\n // Differences\n var zero = new Vertex_1.Vertex(0, 0);\n var p2mp1 = new Vertex_1.Vertex(p2.x - p1.x, p2.y - p1.y);\n var p3mp2 = new Vertex_1.Vertex(p3.x - p2.x, p3.y - p2.y);\n var p2mp1_len = zero.distance(p2mp1);\n var p3mp2_len = zero.distance(p3mp2);\n // Dot products\n var dotProduct = geomutils_1.geomutils.dotProduct(p2mp1, p3mp2);\n var lengthProduct = p2mp1_len * p3mp2_len;\n if (isAcute) {\n return Math.PI - Math.acos(dotProduct / lengthProduct);\n }\n else {\n return Math.PI + Math.acos(dotProduct / lengthProduct);\n }\n };\n /**\n * Checks if the angle at the given polygon vertex (index) is acute.\n *\n * @method isAngleAcute\n * @instance\n * @memberof Polygon\n * @param {number} vertIndex - The index of the polygon vertex to check.\n * @returns {boolean} `true` is angle is acute, `false` is obtuse.\n */\n Polygon.prototype.isAngleAcute = function (vertIndex) {\n var A = this.vertices[(vertIndex + this.vertices.length - 1) % this.vertices.length].clone();\n var B = this.vertices[vertIndex % this.vertices.length];\n var C = this.vertices[(vertIndex + 1) % this.vertices.length].clone();\n // Find local winding number for triangle A B C\n var windingNumber = Triangle_1.Triangle.utils.determinant(A, B, C);\n // console.log(\"vertIndex\", vertIndex, \"windingNumber\", windingNumber);\n return windingNumber < 0;\n };\n /**\n * Get the polygon vertex at the given position (index).\n *\n * The index may exceed the total vertex count, and will be wrapped around then (modulo).\n *\n * For k >= 0:\n * - getVertexAt( vertices.length ) == getVertexAt( 0 )\n * - getVertexAt( vertices.length + k ) == getVertexAt( k )\n * - getVertexAt( -k ) == getVertexAt( vertices.length -k )\n *\n * @method getVertexAt\n * @param {number} index - The index of the desired vertex.\n * @instance\n * @memberof Polygon\n * @return {Vertex} At the given index.\n **/\n Polygon.prototype.getVertexAt = function (index) {\n if (index < 0) {\n return this.vertices[this.vertices.length - (Math.abs(index) % this.vertices.length)];\n }\n else {\n return this.vertices[index % this.vertices.length];\n }\n };\n /**\n * Move the polygon's vertices by the given amount.\n *\n * @method move\n * @param {XYCoords} amount - The amount to move.\n * @instance\n * @memberof Polygon\n * @return {Polygon} this for chaining\n **/\n Polygon.prototype.move = function (amount) {\n for (var i in this.vertices) {\n this.vertices[i].add(amount);\n }\n return this;\n };\n /**\n * Check if the given vertex is inside this polygon.<br>\n * <br>\n * Ray-casting algorithm found at<br>\n * https://stackoverflow.com/questions/22521982/check-if-point-inside-a-polygon\n *\n * @method containsVert\n * @param {XYCoords} vert - The vertex to check.\n * @return {boolean} True if the passed vertex is inside this polygon. The polygon is considered closed.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.containsVert = function (vert) {\n // ray-casting algorithm based on\n // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html\n var inside = false;\n for (var i = 0, j = this.vertices.length - 1; i < this.vertices.length; j = i++) {\n var xi = this.vertices[i].x, yi = this.vertices[i].y;\n var xj = this.vertices[j].x, yj = this.vertices[j].y;\n var intersect = yi > vert.y != yj > vert.y && vert.x < ((xj - xi) * (vert.y - yi)) / (yj - yi) + xi;\n if (intersect) {\n inside = !inside;\n }\n }\n return inside;\n };\n /**\n * Check if all given vertices are inside this polygon.<br>\n * <br>\n * This method just uses the `Polygon.containsVert` method.\n *\n * @method containsVerts\n * @param {XYCoords[]} verts - The vertices to check.\n * @return {boolean} True if all passed vertices are inside this polygon. The polygon is considered closed.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.containsVerts = function (verts) {\n var _this = this;\n return verts.every(function (vert) { return _this.containsVert(vert); });\n };\n /**\n * Check if the passed polygon is completly contained inside this polygon.\n *\n * This means:\n * - all polygon's vertices must be inside this polygon.\n * - the polygon has no edge intersections with this polygon.\n *\n * @param {Polygon} polygon - The polygon to check if contained.\n * @return {boolean}\n */\n Polygon.prototype.containsPolygon = function (polygon) {\n for (var i = 0; i < polygon.vertices.length; i++) {\n if (!this.containsVert(polygon.vertices[i])) {\n return false;\n }\n }\n // All vertices are inside; check for intersections\n var lineSegment = new Line_1.Line(new Vertex_1.Vertex(), new Vertex_1.Vertex());\n for (var i = 0; i < polygon.vertices.length; i++) {\n lineSegment.a.set(polygon.vertices[i]);\n lineSegment.b.set(polygon.vertices[(i + 1) % polygon.vertices.length]);\n if (this.lineIntersections(lineSegment, true).length > 0) {\n // Current segment has intersection(s) with this polygon.\n return false;\n }\n }\n return true;\n };\n /**\n * Calculate the area of the given polygon (unsigned).\n *\n * Note that this does not work for self-intersecting polygons.\n *\n * @method area\n * @instance\n * @memberof Polygon\n * @return {number}\n */\n Polygon.prototype.area = function () {\n return Polygon.utils.area(this.vertices);\n };\n /**\n * Calulate the signed polyon area by interpreting the polygon as a matrix\n * and calculating its determinant.\n *\n * @method signedArea\n * @instance\n * @memberof Polygon\n * @return {number}\n */\n Polygon.prototype.signedArea = function () {\n return Polygon.utils.signedArea(this.vertices);\n };\n /**\n * Get the winding order of this polgon: clockwise or counterclockwise.\n *\n * @method isClockwise\n * @instance\n * @memberof Polygon\n * @return {boolean}\n */\n Polygon.prototype.isClockwise = function () {\n // return Polygon.utils.signedArea(this.vertices) < 0;\n return Polygon.utils.isClockwise(this.vertices);\n };\n /**\n * Revert the order of this polygon's vertices to change the winding order.\n * This operation is in-place.\n *\n * @method revert\n * @instance\n * @memberof Polygon\n * @return {Polygon} This for chaining.\n */\n Polygon.prototype.revert = function () {\n // this.vertices.slice().reverse(); // Copy?\n this.vertices.reverse();\n return this;\n };\n /**\n * Get the perimeter of this polygon.\n * The perimeter is the absolute length of the outline.\n *\n * If this polygon is open then the last segment (connecting the first and the\n * last vertex) will be skipped.\n *\n * @method perimeter\n * @instance\n * @memberof Polygon\n * @return {number}\n */\n Polygon.prototype.perimeter = function () {\n var length = 0;\n for (var i = 1; i < this.vertices.length; i++) {\n length += this.vertices[i - 1].distance(this.vertices[i]);\n }\n if (!this.isOpen && this.vertices.length > 1) {\n length += this.vertices[0].distance(this.vertices[this.vertices.length - 1]);\n }\n return length;\n };\n /**\n * Scale the polygon relative to the given center.\n *\n * @method scale\n * @param {number} factor - The scale factor.\n * @param {Vertex} center - The center of scaling.\n * @return {Polygon} this, for chaining.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.scale = function (factor, center) {\n for (var i in this.vertices) {\n if (typeof this.vertices[i].scale == \"function\")\n this.vertices[i].scale(factor, center);\n else\n console.log(\"There seems to be a null vertex!\", this.vertices[i]);\n }\n return this;\n };\n /**\n * Rotate the polygon around the given center.\n *\n * @method rotate\n * @param {number} angle - The rotation angle.\n * @param {Vertex} center - The center of rotation.\n * @instance\n * @memberof Polygon\n * @return {Polygon} this, for chaining.\n **/\n Polygon.prototype.rotate = function (angle, center) {\n for (var i in this.vertices) {\n this.vertices[i].rotate(angle, center);\n }\n return this;\n };\n /**\n * Get the mean `center` of this polygon by calculating the mean value of all vertices.\n *\n * Mean: (v[0] + v[1] + ... v[n-1]) / n\n *\n * @method getMeanCenter\n * @instance\n * @memberof Polygon\n * @return {Vertex|null} `null` is no vertices are available.\n */\n Polygon.prototype.getMeanCenter = function () {\n if (this.vertices.length === 0) {\n return null;\n }\n var center = this.vertices[0].clone();\n for (var i = 1; i < this.vertices.length; i++) {\n center.add(this.vertices[i]);\n }\n center.x /= this.vertices.length;\n center.y /= this.vertices.length;\n return center;\n };\n /**\n * Get centroid.\n * Centroids define the barycenter of any non self-intersecting convex clockwise polygon.\n *\n * If the polygon is self intersecting or non convex or not clockwise then the barycenter is not well defined.\n *\n * https://mathworld.wolfram.com/PolygonCentroid.html\n *\n * @method getCentroid\n * @instance\n * @param {boolean} forceClockwise - [optiona] If set to true then the centroid will be calculated for the clockwise polygon.\n * @memberof Polygon\n * @returns {Vertex|null}\n */\n Polygon.prototype.getCentroid = function (forceClockwise) {\n if (this.vertices.length === 0) {\n return null;\n }\n // const centroid: Vertex = new Vertex(0.0, 0.0);\n // const n = this.vertices.length;\n // for (var i = 0; i < n; i++) {\n // // center.add(this.vertices[i]);\n // const cur: Vertex = this.vertices[i];\n // const next: Vertex = this.vertices[(i + 1) % n];\n // var factor: number = cur.x * next.y - next.x * cur.y;\n // centroid.x += (cur.x + next.x) * factor;\n // centroid.y += (cur.y + next.y) * factor;\n // }\n // const area = this.area();\n // centroid.x *= 1 / (6 * area);\n // centroid.y *= 1 / (6 * area);\n // return centroid;\n return Polygon.utils.calculateCentroid(this.vertices, forceClockwise);\n };\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get all line intersections with this polygon.\n *\n * This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.\n *\n * See demo `47-closest-vector-projection-on-polygon` for how it works.\n *\n * @param {VertTuple} line - The line to find intersections with.\n * @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).\n * @returns {Array<Vertex>} - An array of all intersections within the polygon bounds.\n */\n Polygon.prototype.lineIntersections = function (line, inVectorBoundsOnly) {\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersections of all lines inside the edge bounds\n return Polygon.utils\n .locateLineIntersecion(line, this.vertices, this.isOpen, inVectorBoundsOnly)\n .map(function (intersectionTuple) { return intersectionTuple.intersection; });\n };\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @param line\n * @param inVectorBoundsOnly\n * @returns\n */\n Polygon.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersection tangents of all lines inside the edge bounds\n return Polygon.utils.locateLineIntersecion(line, this.vertices, this.isOpen, inVectorBoundsOnly).map(function (intersectionTuple) {\n var polyLine = _this.getEdgeAt(intersectionTuple.edgeIndex);\n return new Vector_1.Vector(polyLine.a.clone(), polyLine.b.clone()).moveTo(intersectionTuple.intersection);\n });\n };\n //--- END --- Implement interface `Intersectable`\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @param line\n * @param inVectorBoundsOnly\n * @returns\n */\n Polygon.prototype.lineIntersectionTangentsIndices = function (line, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersection tangents of all lines inside the edge bounds\n return Polygon.utils.locateLineIntersecion(line, this.vertices, this.isOpen, inVectorBoundsOnly).map(function (intersectionTuple) {\n var polyLine = _this.getEdgeAt(intersectionTuple.edgeIndex);\n return {\n intersection: new Vector_1.Vector(polyLine.a.clone(), polyLine.b.clone()).moveTo(intersectionTuple.intersection),\n edgeIndex: intersectionTuple.edgeIndex\n };\n });\n };\n /**\n * Get the closest line-polygon-intersection point (closest the line point A).\n *\n * See demo `47-closest-vector-projection-on-polygon` for how it works.\n *\n * @param {VertTuple} line - The line to find intersections with.\n * @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are considered (located strictly between start and end vertex).\n * @returns {Vertex | null} - The intersection point within the polygon bounds.\n */\n Polygon.prototype.closestLineIntersection = function (line, inVectorBoundsOnly) {\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n var closestInterSectionIndex = this.closestLineIntersectionIndex(line, inVectorBoundsOnly);\n if (closestInterSectionIndex) {\n return closestInterSectionIndex.intersection;\n }\n else {\n return null;\n }\n };\n /**\n * Get the closest line-polygon-intersection point (closest the line point A) plus the edge index..\n *\n * See demo `63-measure-angles-on-polygon` for how it works.\n *\n * @param {VertTuple} line - The line to find intersections with.\n * @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are considered (located strictly between start and end vertex).\n * @returns {PolygonIntersectionTuple| null} - A pair containing the intersection point and the affected polygon edge index.\n */\n Polygon.prototype.closestLineIntersectionIndex = function (line, inVectorBoundsOnly) {\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n var allIntersections = this.lineIntersections(line, inVectorBoundsOnly);\n if (allIntersections.length <= 0) {\n // Empty polygon -> no intersections\n return null;\n }\n // Find the closest intersection\n var closestIntersection = new Vertex_1.Vertex(Number.MAX_VALUE, Number.MAX_VALUE);\n var closestInterSectionIndex = -1;\n var curDist = Number.MAX_VALUE;\n for (var i = 0; i < allIntersections.length; i++) {\n var curVert = allIntersections[i];\n var dist = curVert.distance(line.a);\n if (dist < curDist) {\n // && line.hasPoint(curVert)) {\n curDist = dist;\n closestIntersection = curVert;\n closestInterSectionIndex = i;\n }\n }\n // return [closestIntersection, closestInterSectionIndex];\n return { edgeIndex: closestInterSectionIndex, intersection: closestIntersection };\n };\n /**\n * Construct a new polygon from this polygon with more vertices on each edge. The\n * interpolation count determines the number of additional vertices on each edge.\n * An interpolation count of `0` will return a polygon that equals the source\n * polygon.\n *\n * @param {number} interpolationCount\n * @returns {Polygon} A polygon with `interpolationCount` more vertices (as as factor).\n */\n Polygon.prototype.getInterpolationPolygon = function (interpolationCount) {\n var verts = [];\n for (var i = 0; i < this.vertices.length; i++) {\n var curVert = this.vertices[i];\n var nextVert = this.vertices[(i + 1) % this.vertices.length];\n verts.push(curVert.clone());\n // Add interpolation points\n if (!this.isOpen || i + 1 !== this.vertices.length) {\n var lerpAmount = 1.0 / (interpolationCount + 1);\n for (var j = 1; j <= interpolationCount; j++) {\n verts.push(curVert.clone().lerp(nextVert, lerpAmount * j));\n }\n }\n }\n return new Polygon(verts, this.isOpen);\n };\n /**\n * Convert this polygon into a new polygon with n evenly distributed vertices.\n *\n * @param {number} pointCount - Must not be negative.\n */\n Polygon.prototype.getEvenDistributionPolygon = function (pointCount) {\n if (pointCount <= 0) {\n throw new Error(\"pointCount must be larger than zero; is \" + pointCount + \".\");\n }\n var result = new Polygon([], this.isOpen);\n if (this.vertices.length === 0) {\n return result;\n }\n // Fetch and add the start point from the source polygon\n var polygonPoint = new Vertex_1.Vertex(this.vertices[0]);\n result.vertices.push(polygonPoint);\n if (this.vertices.length === 1) {\n return result;\n }\n var perimeter = this.perimeter();\n var stepSize = perimeter / pointCount;\n var n = this.vertices.length;\n var polygonIndex = 1;\n var nextPolygonPoint = new Vertex_1.Vertex(this.vertices[1]);\n var segmentLength = polygonPoint.distance(nextPolygonPoint);\n var loopMax = this.isOpen ? n : n + 1;\n var curSegmentU = stepSize;\n var i = 1;\n while (i < pointCount && polygonIndex < loopMax) {\n // Check if next eq point is inside this segment\n if (curSegmentU < segmentLength) {\n var newPoint = polygonPoint.clone().lerpAbs(nextPolygonPoint, curSegmentU);\n result.vertices.push(newPoint);\n curSegmentU += stepSize;\n i++;\n }\n else {\n polygonIndex++;\n polygonPoint = nextPolygonPoint;\n nextPolygonPoint = new Vertex_1.Vertex(this.vertices[polygonIndex % n]);\n curSegmentU = curSegmentU - segmentLength;\n segmentLength = polygonPoint.distance(nextPolygonPoint);\n }\n }\n return result;\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Get the bounding box (bounds) of this polygon.\n *\n * @method getBounds\n * @instance\n * @memberof Polygon\n * @return {Bounds} The rectangular bounds of this polygon.\n **/\n Polygon.prototype.getBounds = function () {\n return Bounds_1.Bounds.computeFromVertices(this.vertices);\n };\n //--- END --- Implement interface `IBounded`\n /**\n * Create a deep copy of this polygon.\n *\n * @method clone\n * @instance\n * @memberof Polygon\n * @return {Polygon} The cloned polygon.\n */\n Polygon.prototype.clone = function () {\n return new Polygon(this.vertices.map(function (vert) { return vert.clone(); }), this.isOpen);\n };\n /**\n * Create a new polygon without colinear adjacent edges. This method does not midify the current polygon\n * but creates a new one.\n *\n * Please note that this method does NOT create deep clones of the vertices. Use Polygon.clone() if you need to.\n *\n * Please also note that the `tolerance` may become really large here, as the denominator of two closely\n * parallel lines is usually pretty large. See the demo `57-eliminate-colinear-polygon-edges` to get\n * an impression of how denominators work.\n *\n * @method elimitateColinearEdges\n * @instance\n * @memberof Polygon\n * @param {number?} tolerance - (default is 1.0) The epsilon to detect co-linear edges.\n * @return {Polygon} A new polygon without co-linear adjacent edges – respective the given epsilon.\n */\n Polygon.prototype.elimitateColinearEdges = function (tolerance) {\n var eps = typeof tolerance === \"undefined\" ? 1.0 : tolerance;\n var verts = this.vertices.slice(); // Creates a shallow copy\n var i = 0;\n var lineA = new Line_1.Line(new Vertex_1.Vertex(), new Vertex_1.Vertex());\n var lineB = new Line_1.Line(new Vertex_1.Vertex(), new Vertex_1.Vertex());\n while (i + 1 < verts.length && verts.length > 2) {\n var vertA = verts[i];\n var vertB = verts[(i + 1) % verts.length];\n lineA.a = vertA;\n lineA.b = vertB;\n lineB.a = vertB;\n var areColinear = false;\n var j = i + 2;\n do {\n var vertC = verts[j % verts.length];\n lineB.b = vertC;\n areColinear = lineA.colinear(lineB, eps);\n // console.log(\"are colinear?\", i, i + 1, j, areColinear);\n if (areColinear) {\n j++;\n }\n } while (areColinear);\n // Now j points to the first vertex that's NOT colinear to the current lineA\n // -> delete all vertices in between\n if (j - i > 2) {\n // Means: there have been 'colinear vertices' in between\n verts.splice(i + 1, j - i - 2);\n }\n i++;\n }\n return new Polygon(verts, this.isOpen);\n };\n /**\n * Convert this polygon to a sequence of quadratic Bézier curves.<br>\n * <br>\n * The first vertex in the returned array is the start point.<br>\n * The following sequence are pairs of control-point-and-end-point:\n * <pre>startPoint, controlPoint0, pathPoint1, controlPoint1, pathPoint2, controlPoint2, ..., endPoint</pre>\n *\n * @method toQuadraticBezierData\n * @return {Vertex[]} An array of 2d vertices that shape the quadratic Bézier curve.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.toQuadraticBezierData = function () {\n if (this.vertices.length < 3)\n return [];\n var qbezier = [];\n var cc0 = this.vertices[0];\n var cc1 = this.vertices[1];\n var edgeCenter = new Vertex_1.Vertex(cc0.x + (cc1.x - cc0.x) / 2, cc0.y + (cc1.y - cc0.y) / 2);\n qbezier.push(edgeCenter);\n var limit = this.isOpen ? this.vertices.length : this.vertices.length + 1;\n for (var t = 1; t < limit; t++) {\n cc0 = this.vertices[t % this.vertices.length];\n cc1 = this.vertices[(t + 1) % this.vertices.length];\n var edgeCenter = new Vertex_1.Vertex(cc0.x + (cc1.x - cc0.x) / 2, cc0.y + (cc1.y - cc0.y) / 2);\n qbezier.push(cc0);\n qbezier.push(edgeCenter);\n cc0 = cc1;\n }\n return qbezier;\n };\n /**\n * Convert this polygon to a quadratic bezier curve, represented as an SVG data string.\n *\n * @method toQuadraticBezierSVGString\n * @return {string} The 'd' part for an SVG 'path' element.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.toQuadraticBezierSVGString = function () {\n var qdata = this.toQuadraticBezierData();\n if (qdata.length == 0)\n return \"\";\n var buffer = [\"M \" + qdata[0].x + \" \" + qdata[0].y];\n for (var i = 1; i < qdata.length; i += 2) {\n buffer.push(\"Q \" + qdata[i].x + \" \" + qdata[i].y + \", \" + qdata[i + 1].x + \" \" + qdata[i + 1].y);\n }\n return buffer.join(\" \");\n };\n /**\n * Convert this polygon to a sequence of cubic Bézier curves.<br>\n * <br>\n * The first vertex in the returned array is the start point.<br>\n * The following sequence are triplets of (first-control-point, secnond-control-point, end-point):<br>\n * <pre>startPoint, controlPoint0_0, controlPoint1_1, pathPoint1, controlPoint1_0, controlPoint1_1, ..., endPoint</pre>\n *\n * @method toCubicBezierData\n * @param {number=} threshold - An optional threshold (default=1.0) how strong the curve segments\n * should over-/under-drive. Should be between 0.0 and 1.0 for best\n * results but other values are allowed.\n * @return {Vertex[]} An array of 2d vertices that shape the cubic Bézier curve.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.toCubicBezierData = function (threshold) {\n if (typeof threshold == \"undefined\")\n threshold = 1.0;\n if (this.vertices.length < 3)\n return [];\n var cbezier = [];\n var a = this.vertices[0];\n var b = this.vertices[1];\n var edgeCenter = new Vertex_1.Vertex(a.x + (b.x - a.x) / 2, a.y + (b.y - a.y) / 2);\n cbezier.push(edgeCenter);\n var limit = this.isOpen ? this.vertices.length - 1 : this.vertices.length;\n for (var t = 0; t < limit; t++) {\n var a = this.vertices[t % this.vertices.length];\n var b = this.vertices[(t + 1) % this.vertices.length];\n var c = this.vertices[(t + 2) % this.vertices.length];\n var aCenter = new Vertex_1.Vertex(a.x + (b.x - a.x) / 2, a.y + (b.y - a.y) / 2);\n var bCenter = new Vertex_1.Vertex(b.x + (c.x - b.x) / 2, b.y + (c.y - b.y) / 2);\n var a2 = new Vertex_1.Vertex(aCenter.x + (b.x - aCenter.x) * threshold, aCenter.y + (b.y - aCenter.y) * threshold);\n var b0 = new Vertex_1.Vertex(bCenter.x + (b.x - bCenter.x) * threshold, bCenter.y + (b.y - bCenter.y) * threshold);\n cbezier.push(a2);\n cbezier.push(b0);\n cbezier.push(bCenter);\n }\n return cbezier;\n };\n /**\n * Convert this polygon to a cubic bezier curve, represented as an SVG data string.\n *\n * @method toCubicBezierSVGString\n * @return {string} The 'd' part for an SVG 'path' element.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.toCubicBezierSVGString = function (threshold) {\n var qdata = this.toCubicBezierData(threshold);\n if (qdata.length == 0) {\n return \"\";\n }\n var buffer = [\"M \" + qdata[0].x + \" \" + qdata[0].y];\n for (var i = 1; i < qdata.length; i += 3) {\n buffer.push(\"C \" +\n qdata[i].x +\n \" \" +\n qdata[i].y +\n \", \" +\n qdata[i + 1].x +\n \" \" +\n qdata[i + 1].y +\n \", \" +\n qdata[i + 2].x +\n \" \" +\n qdata[i + 2].y);\n }\n return buffer.join(\" \");\n };\n /**\n * Convert this polygon to a cubic bezier path instance.\n *\n * @method toCubicBezierPath\n * @param {number} threshold - The threshold, usually from 0.0 to 1.0.\n * @return {BezierPath} - A bezier path instance.\n * @instance\n * @memberof Polygon\n **/\n Polygon.prototype.toCubicBezierPath = function (threshold) {\n var qdata = this.toCubicBezierData(threshold);\n // Conver the linear path vertices to a two-dimensional path array\n var pathdata = [];\n for (var i = 0; i + 3 < qdata.length; i += 3) {\n pathdata.push([qdata[i], qdata[i + 3], qdata[i + 1], qdata[i + 2]]);\n }\n return BezierPath_1.BezierPath.fromArray(pathdata);\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n Polygon.prototype.destroy = function () {\n for (var i = 0; i < this.vertices.length; i++) {\n this.vertices[i].destroy();\n }\n this.isDestroyed = true;\n };\n Polygon.utils = {\n /**\n * Calculate the area of the given polygon (unsigned).\n *\n * Note that this does not work for self-intersecting polygons.\n *\n * @name area\n * @return {number}\n */\n area: function (vertices) {\n // Found at:\n // https://stackoverflow.com/questions/16285134/calculating-polygon-area\n var total = 0.0;\n for (var i = 0, l = vertices.length; i < l; i++) {\n var addX = vertices[i].x;\n var addY = vertices[(i + 1) % l].y;\n var subX = vertices[(i + 1) % l].x;\n var subY = vertices[i].y;\n total += addX * addY * 0.5;\n total -= subX * subY * 0.5;\n }\n return Math.abs(total);\n },\n isClockwise: function (vertices) {\n return Polygon.utils.signedArea(vertices) < 0;\n },\n calculateCentroid: function (vertices, forceClockwise) {\n var centroid = new Vertex_1.Vertex(0.0, 0.0);\n var n = vertices.length;\n if (forceClockwise && !Polygon.utils.isClockwise(vertices)) {\n return Polygon.utils.calculateCentroid(vertices.slice().reverse());\n }\n for (var i = 0; i < n; i++) {\n // center.add(this.vertices[i]);\n var cur = vertices[i];\n var next = vertices[(i + 1) % n];\n var factor = cur.x * next.y - next.x * cur.y;\n centroid.x += (cur.x + next.x) * factor;\n centroid.y += (cur.y + next.y) * factor;\n }\n // const area = this.area();\n var area = Polygon.utils.area(vertices);\n centroid.x *= 1 / (6 * area);\n centroid.y *= 1 / (6 * area);\n return centroid;\n },\n /**\n * Calulate the signed polyon area by interpreting the polygon as a matrix\n * and calculating its determinant.\n *\n * @name signedArea\n * @return {number}\n */\n signedArea: function (vertices) {\n var sum = 0;\n var n = vertices.length;\n for (var i = 0; i < n; i++) {\n var j = (i + 1) % n;\n sum += (vertices[j].x - vertices[i].x) * (vertices[i].y + vertices[j].y);\n }\n return sum;\n },\n /**\n * Find intersections of a line with a polygon (vertices).\n *\n * @param {VertTuple<any>} line - The line to find intersections with.\n * @param {Array<Vertex>} vertices - The polygon's vertices.\n * @param {boolean} isOpen - True if the polygon is open, false otherwise.\n * @param {boolean} inVectorBoundsOnly - If only intersections in strict vector bounds should be returned.\n * @returns\n */\n locateLineIntersecion: function (line, vertices, isOpen, inVectorBoundsOnly) {\n // Find the intersections of all lines inside the edge bounds\n var intersectionPoints = [];\n var n = isOpen ? vertices.length - 1 : vertices.length;\n for (var i = 0; i < n; i++) {\n var polyLine = new Line_1.Line(vertices[i % n], vertices[(i + 1) % n]);\n var intersection = polyLine.intersection(line);\n // true => only inside bounds\n // ignore last edge if open\n if (intersection !== null &&\n polyLine.hasPoint(intersection, true) &&\n (!inVectorBoundsOnly || line.hasPoint(intersection, inVectorBoundsOnly))) {\n intersectionPoints.push({ edgeIndex: i, intersection: intersection });\n }\n }\n return intersectionPoints;\n }\n };\n return Polygon;\n}());\nexports.Polygon = Polygon;\n//# sourceMappingURL=Polygon.js.map","\"use strict\";\n/**\n * Implementation of elliptic sectors.\n * Note that sectors are constructed in clockwise direction.\n *\n * @author Ikaros Kappler\n * @date 2021-02-26\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-11-01 Tweaked the `endpointToCenterParameters` function to handle negative values, too, without errors.\n * @modified 2025-04-01 Adapting a the `toCubicBezier` calculation to match an underlying change in the vertAt and tangentAt calculation of ellipses (was required to hamonize both methods with circles).\n * @modified 2025-04-02 Adding `VEllipseSector.containsAngle` method.\n * @modified 2025-04-02 Adding `VEllipseSector.lineIntersections` and `VEllipseSector.lineIntersectionTangents` and implementing `Intersectable`.\n * @modified 2025-04-07 Adding value wrapping (0 to TWO_PI) to the `VEllipseSector.containsAngle` method.\n * @modified 2025-04-09 Adding the `VEllipseSector.move` method.\n * @modified 2025-04-19 Added the `VEllipseSector.getStartPoint` and `getEndPoint` methods.\n * @modified 2025-04-23 Added the `VEllipseSector.getBounds` method.\n * @version 1.2.0\n */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.VEllipseSector = void 0;\nvar Bounds_1 = require(\"./Bounds\");\nvar CubicBezierCurve_1 = require(\"./CubicBezierCurve\");\nvar geomutils_1 = require(\"./geomutils\");\nvar Line_1 = require(\"./Line\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar VEllipse_1 = require(\"./VEllipse\");\nvar Vertex_1 = require(\"./Vertex\");\n/**\n * @classdesc A class for elliptic sectors.\n *\n * @requires Line\n * @requires Vector\n * @requires VertTuple\n * @requires Vertex\n * @requires SVGSerializale\n * @requires UID\n * @requires UIDGenerator\n **/\nvar VEllipseSector = /** @class */ (function () {\n /**\n * Create a new elliptic sector from the given ellipse and two angles.\n *\n * Note that the direction from start to end goes clockwise, and that start and end angle\n * will be wrapped to [0,PI*2).\n *\n * @constructor\n * @name VEllipseSector\n * @param {VEllipse} - The underlying ellipse to use.\n * @param {number} startAngle - The start angle of the sector.\n * @param {numner} endAngle - The end angle of the sector.\n */\n function VEllipseSector(ellipse, startAngle, endAngle) {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"VEllipseSector\";\n this.uid = UIDGenerator_1.UIDGenerator.next();\n this.ellipse = ellipse;\n this.startAngle = geomutils_1.geomutils.wrapMinMax(startAngle, 0, Math.PI * 2);\n this.endAngle = geomutils_1.geomutils.wrapMinMax(endAngle, 0, Math.PI * 2);\n }\n /**\n * Move the ellipse sector by the given amount.\n *\n * @method move\n * @param {XYCoords} amount - The amount to move.\n * @instance\n * @memberof VEllipseSector\n * @return {VEllipseSector} this for chaining\n **/\n VEllipseSector.prototype.move = function (amount) {\n this.ellipse.move(amount);\n return this;\n };\n /**\n * Checks wether the given angle (must be inside 0 and PI*2) is contained inside this sector.\n *\n * @param {number} angle - The numeric angle to check.\n * @method containsAngle\n * @instance\n * @memberof VEllipseSectpr\n * @return {boolean} True if (and only if) this sector contains the given angle.\n */\n VEllipseSector.prototype.containsAngle = function (angle) {\n angle = geomutils_1.geomutils.mapAngleTo2PI(angle); // wrapMinMax(angle, 0, Math.PI * 2);\n var sAngle = geomutils_1.geomutils.mapAngleTo2PI(this.startAngle);\n var eAngle = geomutils_1.geomutils.mapAngleTo2PI(this.endAngle);\n // TODO: cleanup\n // if (this.startAngle <= this.endAngle) {\n // return angle >= this.startAngle && angle < this.endAngle;\n // } else {\n // // startAngle > endAngle\n // return angle >= this.startAngle || angle < this.endAngle;\n // }\n if (sAngle <= eAngle) {\n return angle >= sAngle && angle < eAngle;\n }\n else {\n // startAngle > endAngle\n return angle >= sAngle || angle < eAngle;\n }\n };\n /**\n * Get the sectors starting point (on the underlying ellipse, located at the start angle).\n *\n * @method getStartPoint\n * @instance\n * @memberof VEllipseSector\n * @return {Vertex} The sector's stating point.\n */\n VEllipseSector.prototype.getStartPoint = function () {\n return this.ellipse.vertAt(this.startAngle);\n };\n /**\n * Get the sectors ending point (on the underlying ellipse, located at the end angle).\n *\n * @method getEndPoint\n * @instance\n * @memberof VEllipseSector\n * @return {Vertex} The sector's ending point.\n */\n VEllipseSector.prototype.getEndPoint = function () {\n return this.ellipse.vertAt(this.endAngle);\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Get the bounds of this elliptic sector.\n *\n * The bounds are approximated by the underlying segment buffer; the more segment there are,\n * the more accurate will be the returned bounds.\n *\n * @method getBounds\n * @instance\n * @memberof VEllipse\n * @return {Bounds} The bounds of this elliptic sector.\n **/\n VEllipseSector.prototype.getBounds = function () {\n var _this = this;\n // Calculage angles from east, west, north and south box points and check if they are inside\n var extremes = this.ellipse.getExtremePoints();\n var candidates = extremes.filter(function (point) {\n var angle = new Line_1.Line(_this.ellipse.center, point).angle() - _this.ellipse.rotation;\n return _this.containsAngle(angle);\n });\n return Bounds_1.Bounds.computeFromVertices([this.getStartPoint(), this.getEndPoint()].concat(candidates));\n };\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get the line intersections as vectors with this ellipse.\n *\n * @method lineIntersections\n * @instance\n * @memberof VEllipseSectpr\n * @param {VertTuple<Vector>} ray - The line/ray to intersect this ellipse with.\n * @param {boolean} inVectorBoundsOnly - (default=false) Set to true if only intersections within the vector bounds are of interest.\n * @returns\n */\n VEllipseSector.prototype.lineIntersections = function (ray, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // First get all line intersections from underlying ellipse.\n var ellipseIntersections = this.ellipse.lineIntersections(ray, inVectorBoundsOnly);\n // Drop all intersection points that are not contained in the circle sectors bounds.\n var tmpLine = new Line_1.Line(this.ellipse.center, new Vertex_1.Vertex());\n return ellipseIntersections.filter(function (intersectionPoint) {\n tmpLine.b.set(intersectionPoint);\n var lineAngle = tmpLine.angle();\n return _this.containsAngle(lineAngle - _this.ellipse.rotation);\n });\n };\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @method lineIntersections\n * @memberof VEllipseSectpr\n * @param line\n * @param lineIntersectionTangents\n * @returns\n */\n VEllipseSector.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersections of all lines plus their tangents inside the circle bounds\n var interSectionPoints = this.lineIntersections(line, inVectorBoundsOnly);\n return interSectionPoints.map(function (vert) {\n // Calculate angle\n var lineFromCenter = new Line_1.Line(_this.ellipse.center, vert);\n var angle = lineFromCenter.angle();\n // console.log(\"angle\", (angle / Math.PI) * 180.0);\n // const angle = Math.random() * Math.PI * 2; // TODO\n // Calculate tangent at angle\n return _this.ellipse.tangentAt(angle);\n });\n };\n //--- END --- Implement interface `Intersectable`\n /**\n * Convert this elliptic sector into cubic Bézier curves.\n *\n * @param {number=3} quarterSegmentCount - The number of segments per base elliptic quarter (default is 3, min is 1).\n * @param {number=0.666666} threshold - The Bézier threshold (default value 0.666666 approximates the ellipse with best results\n * but you might wish to use other values)\n * @return {Array<CubicBezierCurve>} An array of cubic Bézier curves representing the elliptic sector.\n */\n VEllipseSector.prototype.toCubicBezier = function (quarterSegmentCount, threshold) {\n // There are at least 4 segments required (dour quarters) to approximate a whole\n // ellipse with Bézier curves.\n // A visually 'good' approximation should have 12; this seems to be a good value (anything multiple of 4).\n var segmentCount = Math.max(1, quarterSegmentCount || 3) * 4;\n threshold = typeof threshold === \"undefined\" ? 0.666666 : threshold;\n var radiusH = this.ellipse.radiusH();\n var radiusV = this.ellipse.radiusV();\n var startAngle = VEllipseSector.ellipseSectorUtils.normalizeAngle(this.startAngle);\n var endAngle = VEllipseSector.ellipseSectorUtils.normalizeAngle(this.endAngle);\n // Find all angles inside start and end\n var angles = VEllipseSector.ellipseSectorUtils.equidistantVertAngles(radiusH, radiusV, startAngle, endAngle, segmentCount);\n angles = [startAngle].concat(angles).concat([endAngle]);\n var curves = [];\n var curAngle = angles[0];\n var startPoint = this.ellipse.vertAt(curAngle);\n for (var i = 0; i + 1 < angles.length; i++) {\n var nextAngle = angles[(i + 1) % angles.length];\n var endPoint = this.ellipse.vertAt(nextAngle);\n var startTangent = this.ellipse.tangentAt(curAngle + this.ellipse.rotation);\n var endTangent = this.ellipse.tangentAt(nextAngle + this.ellipse.rotation);\n // Distorted ellipses can only be approximated by linear Bézier segments\n if (Math.abs(radiusV) < 0.0001 || Math.abs(radiusH) < 0.0001) {\n var diff = startPoint.difference(endPoint);\n var curve = new CubicBezierCurve_1.CubicBezierCurve(startPoint.clone(), endPoint.clone(), startPoint.clone().addXY(diff.x * 0.333, diff.y * 0.333), endPoint.clone().addXY(-diff.x * 0.333, -diff.y * 0.333));\n curves.push(curve);\n }\n else {\n // Find intersection\n var intersection = startTangent.intersection(endTangent);\n // What if intersection is undefined?\n // --> This *can* not happen if segmentCount > 2 and height and width of the ellipse are not zero.\n if (intersection) {\n // It's VERY LIKELY hat this ALWAYS happens; it's just a typesave variant.\n // Intersection cannot be null.\n var startDiff = startPoint.difference(intersection);\n var endDiff = endPoint.difference(intersection);\n var curve = new CubicBezierCurve_1.CubicBezierCurve(startPoint.clone(), endPoint.clone(), startPoint.clone().add(startDiff.scale(threshold)), endPoint.clone().add(endDiff.scale(threshold)));\n curves.push(curve);\n }\n }\n startPoint = endPoint;\n curAngle = nextAngle;\n }\n return curves;\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n VEllipseSector.prototype.destroy = function () {\n this.ellipse.destroy();\n this.isDestroyed = true;\n };\n VEllipseSector.ellipseSectorUtils = {\n /**\n * Helper function to convert an elliptic section to SVG arc params (for the `d` attribute).\n * Inspiration found at:\n * https://stackoverflow.com/questions/5736398/how-to-calculate-the-svg-path-for-an-arc-of-a-circle\n *\n * @param {boolean} options.moveToStart - If false (default=true) the initial 'Move' command will not be used.\n * @return [ 'A', radiusH, radiusV, rotation, largeArcFlag=1|0, sweepFlag=0, endx, endy ]\n */\n describeSVGArc: function (x, y, radiusH, radiusV, startAngle, endAngle, rotation, options) {\n if (typeof options === \"undefined\")\n options = { moveToStart: true };\n if (typeof rotation === \"undefined\")\n rotation = 0.0;\n // Important note: this function only works if start- and end-angle are within\n // one whole circle [x,x+2*PI].\n // Revelations of more than 2*PI might result in unexpected arcs.\n // -> Use the geomutils.wrapMax( angle, 2*PI )\n startAngle = geomutils_1.geomutils.wrapMax(startAngle, Math.PI * 2);\n endAngle = geomutils_1.geomutils.wrapMax(endAngle, Math.PI * 2);\n // Find the start- and end-point on the rotated ellipse\n // XYCoords to Vertex (for rotation)\n var end = new Vertex_1.Vertex(VEllipse_1.VEllipse.utils.polarToCartesian(x, y, radiusH, radiusV, endAngle));\n var start = new Vertex_1.Vertex(VEllipse_1.VEllipse.utils.polarToCartesian(x, y, radiusH, radiusV, startAngle));\n end.rotate(rotation, { x: x, y: y });\n start.rotate(rotation, { x: x, y: y });\n // Boolean stored as integers (0|1).\n var diff = endAngle - startAngle;\n var largeArcFlag;\n if (diff < 0) {\n largeArcFlag = Math.abs(diff) < Math.PI ? 1 : 0;\n }\n else {\n largeArcFlag = Math.abs(diff) > Math.PI ? 1 : 0;\n }\n var sweepFlag = 1;\n var pathData = [];\n if (options.moveToStart) {\n pathData.push(\"M\", start.x, start.y);\n }\n // Arc rotation in degrees, not radians.\n var r2d = 180 / Math.PI;\n pathData.push(\"A\", radiusH, radiusV, rotation * r2d, largeArcFlag, sweepFlag, end.x, end.y);\n return pathData;\n }, // END function describeSVGArc\n /**\n * Helper function to find second-kind elliptic angles, so that the euclidean distance along the the\n * elliptic sector is the same for all.\n *\n * Note that this is based on the full ellipse calculuation and start and end will be cropped; so the\n * distance from the start angle to the first angle and/or the distance from the last angle to\n * the end angle may be different to the others.\n *\n * Furthermore the computation is only possible on un-rotated ellipses; if your source ellipse has\n * a rotation on the plane please 'rotate' the result angles afterwards to find matching angles.\n *\n * Returned angles are normalized to the interval `[ 0, PI*2 ]`.\n *\n * @param {number} radiusH - The first (horizonal) radius of the ellipse.\n * @param {number} radiusV - The second (vertical) radius of the ellipse.\n * @param {number} startAngle - The opening angle of your elliptic sector (please use normalized angles).\n * @param {number} endAngle - The closing angle of your elliptic sector (please use normalized angles).\n * @param {number} fullEllipsePointCount - The number of base segments to use from the source ellipse (12 or 16 are good numbers).\n * @return {Array<number>} An array of n angles inside startAngle and endAngle (where n <= fullEllipsePointCount).\n */\n equidistantVertAngles: function (radiusH, radiusV, startAngle, endAngle, fullEllipsePointCount) {\n var ellipseAngles = VEllipse_1.VEllipse.utils.equidistantVertAngles(radiusH, radiusV, fullEllipsePointCount);\n ellipseAngles = ellipseAngles.map(function (angle) { return VEllipseSector.ellipseSectorUtils.normalizeAngle(angle); });\n var angleIsInRange = function (angle) {\n if (startAngle < endAngle)\n return angle >= startAngle && angle <= endAngle;\n else\n return angle >= startAngle || (angle <= endAngle && angle >= 0);\n };\n // Drop all angles outside the sector\n ellipseAngles = ellipseAngles.filter(angleIsInRange);\n // Now we need to sort the angles to the first one in the array is the closest to startAngle.\n // --> find the angle that is closest to the start angle\n var startIndex = VEllipseSector.ellipseSectorUtils.findClosestToStartAngle(startAngle, endAngle, ellipseAngles);\n // Bring all angles into the correct order\n // Idea: use splice or slice here?\n var angles = [];\n for (var i = 0; i < ellipseAngles.length; i++) {\n angles.push(ellipseAngles[(startIndex + i) % ellipseAngles.length]);\n }\n return angles;\n },\n findClosestToStartAngle: function (startAngle, endAngle, ellipseAngles) {\n // Note: endAngle > 0 && startAngle > 0\n if (startAngle > endAngle) {\n var n = ellipseAngles.length;\n for (var i = 0; i < n; i++) {\n var ea = geomutils_1.geomutils.wrapMinMax(ellipseAngles[i], 0, Math.PI * 2);\n if (ea >= startAngle && ea >= endAngle) {\n return i;\n }\n }\n }\n return 0;\n },\n normalizeAngle: function (angle) { return (angle < 0 ? Math.PI * 2 + angle : angle); },\n /**\n * Convert the elliptic arc from endpoint parameters to center parameters as described\n * in the w3c svg arc implementation note.\n *\n * https://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter\n *\n * @param {number} x1 - The x component of the start point (end of last SVG command).\n * @param {number} y1 - The y component of the start point (end of last SVG command).\n * @param {number} rx - The first (horizontal) radius of the ellipse.\n * @param {number} ry - The second (vertical) radius of the ellipse.\n * @param {number} phi - The ellipse's rotational angle (angle of axis rotation) in radians (not in degrees as the SVG command uses!)\n * @param {boolean} fa - The large-arc-flag (boolean, not 0 or 1).\n * @param {boolean} fs - The sweep-flag (boolean, not 0 or 1).\n * @param {number} x2 - The x component of the end point (end of last SVG command).\n * @param {number} y2 - The y component of the end point (end of last SVG command).\n * @returns\n */\n endpointToCenterParameters: function (x1, y1, rx, ry, phi, fa, fs, x2, y2) {\n // console.log(\"endpointToCenterParameters\", x1, y1, phi, rx, ry, fa, fs, x2, y2);\n // Thanks to\n // https://observablehq.com/@toja/ellipse-and-elliptical-arc-conversion\n var abs = Math.abs;\n var sin = Math.sin;\n var cos = Math.cos;\n var sqrt = Math.sqrt;\n var pow = function (n) {\n return n * n;\n };\n var sinphi = sin(phi);\n var cosphi = cos(phi);\n // Step 1: simplify through translation/rotation\n var x = (cosphi * (x1 - x2)) / 2 + (sinphi * (y1 - y2)) / 2;\n var y = (-sinphi * (x1 - x2)) / 2 + (cosphi * (y1 - y2)) / 2;\n var px = pow(x), py = pow(y), prx = pow(rx), pry = pow(ry);\n // correct of out-of-range radii\n var L = px / prx + py / pry;\n if (L > 1) {\n rx = sqrt(L) * abs(rx);\n ry = sqrt(L) * abs(ry);\n }\n else {\n rx = abs(rx);\n ry = abs(ry);\n }\n // Step 2 + 3: compute center\n var sign = fa === fs ? -1 : 1;\n // const M: number = sqrt((prx * pry - prx * py - pry * px) / (prx * py + pry * px)) * sign;\n var M = sqrt(Math.abs((prx * pry - prx * py - pry * px) / (prx * py + pry * px))) * sign;\n var _cx = (M * (rx * y)) / ry;\n var _cy = (M * (-ry * x)) / rx;\n var cx = cosphi * _cx - sinphi * _cy + (x1 + x2) / 2;\n var cy = sinphi * _cx + cosphi * _cy + (y1 + y2) / 2;\n // Step 4: Compute start and end angle\n var center = new Vertex_1.Vertex(cx, cy);\n var axis = center.clone().addXY(rx, ry);\n var ellipse = new VEllipse_1.VEllipse(center, axis, 0);\n // console.log(\"VELLIPSE::::::\", ellipse);\n ellipse.rotate(phi);\n var startAngle = new Line_1.Line(ellipse.center, new Vertex_1.Vertex(x1, y1)).angle();\n var endAngle = new Line_1.Line(ellipse.center, new Vertex_1.Vertex(x2, y2)).angle();\n return new VEllipseSector(ellipse, startAngle - phi, endAngle - phi);\n }\n }; // END ellipseSectorUtils\n return VEllipseSector;\n}());\nexports.VEllipseSector = VEllipseSector;\n//# sourceMappingURL=VEllipseSector.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2013-08-19\n * @modified 2018-08-16 Added closure. Removed the 'IKRS' wrapper.\n * @modified 2018-11-20 Added circular auto-adjustment.\n * @modified 2018-11-25 Added the point constants to the BezierPath class itself.\n * @modified 2018-11-28 Added the locateCurveByStartPoint() function.\n * @modified 2018-12-04 Added the toSVGString() function.\n * @modified 2019-03-23 Added JSDoc tags.\n * @modified 2019-03-23 Changed the fuctions getPoint and getPointAt to match semantics in the Line class.\n * @modified 2019-11-18 Fixed the clone function: adjustCircular attribute was not cloned.\n * @modified 2019-12-02 Removed some excessive comments.\n * @modified 2019-12-04 Fixed the missing obtainHandleLengths behavior in the adjustNeightbourControlPoint function.\n * @modified 2020-02-06 Added function locateCurveByEndPoint( Vertex ).\n * @modified 2020-02-11 Added 'return this' to the scale(Vertex,number) and to the translate(Vertex) function.\n * @modified 2020-03-24 Ported this class from vanilla-JS to Typescript.\n * @modified 2020-06-03 Made the private helper function _locateUIndex to a private function.\n * @modified 2020-06-03 Added the getBounds() function.\n * @modified 2020-07-14 Changed the moveCurvePoint(...,Vertex) to moveCurvePoint(...,XYCoords).\n * @modified 2020-07-24 Added the getClosestT(Vertex) function.\n * @modified 2020-12-29 Constructor is now private (no explicit use intended).\n * @modified 2021-05-25 Added BezierPath.fromReducedList( Array<number> ).\n * @modified 2022-01-31 Added `BezierPath.getEvenDistributionVertices(number)`.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-02-02 Cleared the `toSVGString` function (deprecated). Use `drawutilssvg` instead.\n * @modified 2023-10-06 Adding the `BezierPath.toPathPoints()` method.\n * @modified 2023-10-07 Adding the `BezierPath.fromCurve(CubicBezierCurve)` static function.\n * @modified 2025-04-09 Added the `BezierPath.move` method to match the convention – which just calls `translate`.\n * @modified 2025-04-09 Modified the `BezierPath.translate` method: chaning parameter `Vertex` to more generalized `XYCoords`.\n * @modified 2025-04-14 Class `BezierPath` is now implementing interface `Intersectable`.\n * @version 2.7.0\n *\n * @file BezierPath\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.BezierPath = void 0;\nvar Bounds_1 = require(\"./Bounds\");\nvar CubicBezierCurve_1 = require(\"./CubicBezierCurve\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar Vertex_1 = require(\"./Vertex\");\n/**\n * @classdesc A BezierPath class.\n *\n * This was refactored from an older project.\n *\n * @requires Bounds\n * @requires Vertex\n * @requires CubicBezierCurve\n * @requires XYCoords\n * @requires SVGSerializable\n * @requires UID\n * @requires UIDGenerator\n **/\nvar BezierPath = /** @class */ (function () {\n /**\n * The constructor.<br>\n * <br>\n * This constructor expects a sequence of path points and will approximate\n * the location of control points by picking some between the points.<br>\n * You should consider just constructing empty paths and then add more curves later using\n * the addCurve() function.\n *\n * @constructor\n * @name BezierPath\n * @param {Vertex[]} pathPoints - An array of path vertices (no control points).\n **/\n function BezierPath() {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"BezierPath\";\n /** @constant {number} */\n this.START_POINT = 0;\n /** @constant {number} */\n this.START_CONTROL_POINT = 1;\n /** @constant {number} */\n this.END_CONTROL_POINT = 2;\n /** @constant {number} */\n this.END_POINT = 3;\n // pathPoints: Array<Vertex> | undefined | null) {\n this.uid = UIDGenerator_1.UIDGenerator.next();\n // if (!pathPoints) {\n // pathPoints = [];\n // }\n this.totalArcLength = 0.0;\n // Set this flag to true if you want the first point and\n // last point of the path to be auto adjusted, too.\n this.adjustCircular = false;\n this.bezierCurves = [];\n }\n /**\n * Add a cubic bezier curve to the end of this path.\n *\n * @method addCurve\n * @param {CubicBezierCurve} curve - The curve to be added to the end of the path.\n * @instance\n * @memberof BezierPath\n * @return {void}\n **/\n BezierPath.prototype.addCurve = function (curve) {\n if (curve == null || typeof curve == \"undefined\")\n throw \"Cannot add null curve to bézier path.\";\n this.bezierCurves.push(curve);\n if (this.bezierCurves.length > 1) {\n curve.startPoint = this.bezierCurves[this.bezierCurves.length - 2].endPoint;\n this.adjustSuccessorControlPoint(this.bezierCurves.length - 2, // curveIndex,\n true, // obtainHandleLength,\n true // updateArcLengths\n );\n }\n else {\n this.totalArcLength += curve.getLength();\n }\n };\n /**\n * Locate the curve with the given start point (function returns the index).\n *\n * @method locateCurveByStartPoint\n * @param {Vertex} point - The (curve start-) point to look for.\n * @instance\n * @memberof BezierPath\n * @return {number} The curve index or -1 if curve (start-) point not found\n **/\n BezierPath.prototype.locateCurveByStartPoint = function (point) {\n // for( var i in this.bezierCurves ) {\n for (var i = 0; i < this.bezierCurves.length; i++) {\n if (this.bezierCurves[i].startPoint.equals(point))\n return i;\n }\n return -1;\n };\n /**\n * Locate the curve with the given end point (function returns the index).\n *\n * @method locateCurveByEndPoint\n * @param {Vertex} point - The (curve end-) point to look for.\n * @instance\n * @memberof BezierPath\n * @return {number} The curve index or -1 if curve (end-) point not found\n **/\n BezierPath.prototype.locateCurveByEndPoint = function (point) {\n // for( var i in this.bezierCurves ) {\n for (var i = 0; i < this.bezierCurves.length; i++) {\n if (this.bezierCurves[i].endPoint.equals(point))\n return i;\n }\n return -1;\n };\n /**\n * Locate the curve with the given start point (function returns the index).\n *\n * @method locateCurveByStartControlPoint\n * @param {Vertex} point - The (curve endt-) point to look for.\n * @instance\n * @memberof BezierPath\n * @return {number} The curve index or -1 if curve (end-) point not found\n **/\n BezierPath.prototype.locateCurveByStartControlPoint = function (point) {\n // for( var i in this.bezierCurves ) {\n for (var i = 0; i < this.bezierCurves.length; i++) {\n if (this.bezierCurves[i].startControlPoint.equals(point))\n return i;\n }\n return -1;\n };\n // +---------------------------------------------------------------------------------\n // | Locate the curve with the given end control point.\n // |\n // | @param point:Vertex The point to look for.\n // | @return Number The index or -1 if not found.\n // +-------------------------------\n BezierPath.prototype.locateCurveByEndControlPoint = function (point) {\n // for( var i in this.bezierCurves ) {\n for (var i = 0; i < this.bezierCurves.length; i++) {\n if (this.bezierCurves[i].endControlPoint.equals(point))\n return i;\n }\n return -1;\n };\n /**\n * Get the total length of this path.<br>\n * <br>\n * Note that the returned value comes from the curve buffer. Unregistered changes\n * to the curve points will result in invalid path length values.\n *\n * @method getLength\n * @instance\n * @memberof BezierPath\n * @return {number} The (buffered) length of the path.\n **/\n BezierPath.prototype.getLength = function () {\n return this.totalArcLength;\n };\n /**\n * This function is internally called whenever the curve or path configuration\n * changed. It updates the attribute that stores the path length information.<br>\n * <br>\n * If you perform any unregistered changes to the curve points you should call\n * this function afterwards to update the curve buffer. Not updating may\n * result in unexpected behavior.\n *\n * @method updateArcLengths\n * @instance\n * @memberof BezierPath\n * @return {void}\n **/\n BezierPath.prototype.updateArcLengths = function () {\n this.totalArcLength = 0.0;\n for (var i = 0; i < this.bezierCurves.length; i++) {\n this.bezierCurves[i].updateArcLengths();\n this.totalArcLength += this.bezierCurves[i].getLength();\n }\n };\n /**\n * Get the number of curves in this path.\n *\n * @method getCurveCount\n * @instance\n * @memberof BezierPath\n * @return {number} The number of curves in this path.\n **/\n BezierPath.prototype.getCurveCount = function () {\n return this.bezierCurves.length;\n };\n /**\n * Get the cubic bezier curve at the given index.\n *\n * @method getCurveAt\n * @param {number} index - The curve index from 0 to getCurveCount()-1.\n * @instance\n * @memberof BezierPath\n * @return {CubicBezierCurve} The curve at the specified index.\n **/\n BezierPath.prototype.getCurveAt = function (curveIndex) {\n return this.bezierCurves[curveIndex];\n };\n /**\n * Move the whole bezier path by the given (x,y)-amount.\n *\n * @method translate\n * @param {XYCoords} amount - The amount to be added (amount.x and amount.y)\n * to each vertex of the curve.\n * @instance\n * @memberof BezierPath\n * @return {BezierPath} this for chaining\n **/\n BezierPath.prototype.translate = function (amount) {\n for (var i = 0; i < this.bezierCurves.length; i++) {\n var curve = this.bezierCurves[i];\n curve.getStartPoint().add(amount);\n curve.getStartControlPoint().add(amount);\n curve.getEndControlPoint().add(amount);\n }\n // Don't forget to translate the last curve's last point\n var curve = this.bezierCurves[this.bezierCurves.length - 1];\n curve.getEndPoint().add(amount);\n this.updateArcLengths();\n return this;\n };\n /**\n * Move the whole bezier path by the given (x,y)-amount.\n *\n * @method move\n * @param {XYCoords} amount - The amount to be added (amount.x and amount.y)\n * to each vertex of the curve.\n * @instance\n * @memberof BezierPath\n * @return {BezierPath} this for chaining\n **/\n BezierPath.prototype.move = function (amount) {\n return this.translate(amount);\n };\n /**\n * Scale the whole bezier path by the given uniform factor.\n *\n * @method scale\n * @param {Vertex} anchor - The scale origin to scale from.\n * @param {number} scaleFactor - The scalar to be multiplied with.\n * @instance\n * @memberof BezierPath\n * @return {BezierPath} this for chaining.\n **/\n BezierPath.prototype.scale = function (anchor, scaleFactor) {\n return this.scaleXY({ x: scaleFactor, y: scaleFactor }, anchor);\n };\n /**\n * Scale the whole bezier path by the given (x,y)-factors.\n *\n * @method scale\n * @param {Vertex} anchor - The scale origin to scale from.\n * @param {number} amount - The scalar to be multiplied with.\n * @instance\n * @memberof BezierPath\n * @return {BezierPath} this for chaining.\n **/\n BezierPath.prototype.scaleXY = function (scaleFactors, anchor) {\n for (var i = 0; i < this.bezierCurves.length; i++) {\n var curve = this.bezierCurves[i];\n curve.getStartPoint().scaleXY(scaleFactors, anchor);\n curve.getStartControlPoint().scaleXY(scaleFactors, anchor);\n curve.getEndControlPoint().scaleXY(scaleFactors, anchor);\n // Do NOT scale the end point here!\n // Don't forget that the curves are connected and on curve's end point\n // the the successor's start point (same instance)!\n }\n // Finally move the last end point (was not scaled yet)\n if (this.bezierCurves.length > 0 && !this.adjustCircular) {\n this.bezierCurves[this.bezierCurves.length - 1].getEndPoint().scaleXY(scaleFactors, anchor);\n }\n this.updateArcLengths();\n return this;\n };\n /**\n * Rotate the whole bezier path around a point..\n *\n * @method rotate\n * @param {Vertex} angle - The angle to rotate this path by.\n * @param {Vertex} center - The rotation center.\n * @instance\n * @memberof BezierPath\n * @return {void}\n **/\n BezierPath.prototype.rotate = function (angle, center) {\n for (var i = 0; i < this.bezierCurves.length; i++) {\n var curve = this.bezierCurves[i];\n curve.getStartPoint().rotate(angle, center);\n curve.getStartControlPoint().rotate(angle, center);\n curve.getEndControlPoint().rotate(angle, center);\n // Do NOT rotate the end point here!\n // Don't forget that the curves are connected and on curve's end point\n // the the successor's start point (same instance)!\n }\n // Finally move the last end point (was not scaled yet)\n if (this.bezierCurves.length > 0 && !this.adjustCircular) {\n this.bezierCurves[this.bezierCurves.length - 1].getEndPoint().rotate(angle, center);\n }\n };\n /**\n * Get the 't' position on this curve with the minimal distance to point p.\n *\n * @param {Vertex} p - The point to find the closest curve point for.\n * @return {number} A value t with 0.0 <= t <= 1.0.\n **/\n BezierPath.prototype.getClosestT = function (p) {\n // Find the spline to extract the value from\n var minIndex = -1;\n var minDist = 0.0;\n var dist = 0.0;\n var curveT = 0.0;\n var uMin = 0.0;\n var u = 0.0;\n for (var i = 0; i < this.bezierCurves.length; i++) {\n curveT = this.bezierCurves[i].getClosestT(p);\n dist = this.bezierCurves[i].getPointAt(curveT).distance(p);\n if (minIndex == -1 || dist < minDist) {\n minIndex = i;\n minDist = dist;\n uMin = u + curveT * this.bezierCurves[i].getLength();\n }\n u += this.bezierCurves[i].getLength();\n }\n return Math.max(0.0, Math.min(1.0, uMin / this.totalArcLength));\n };\n /**\n * Get the point on the bézier path at the given relative path location.\n *\n * @method getPoint\n * @param {number} u - The relative path position: <pre>0 <= u <= this.getLength()</pre>\n * @instance\n * @memberof BezierPath\n * @return {Vertex} The point at the relative path position.\n **/\n BezierPath.prototype.getPoint = function (u) {\n if (u < 0 || u > this.totalArcLength) {\n console.warn(\"[BezierPath.getPoint(u)] u is out of bounds: \" + u + \".\");\n u = Math.min(this.totalArcLength, Math.max(u, 0));\n }\n // Find the spline to extract the value from\n var i = 0;\n var uTemp = 0.0;\n while (i < this.bezierCurves.length && uTemp + this.bezierCurves[i].getLength() < u) {\n uTemp += this.bezierCurves[i].getLength();\n i++;\n }\n // if u == arcLength\n // -> i is max\n if (i >= this.bezierCurves.length)\n return this.bezierCurves[this.bezierCurves.length - 1].getEndPoint().clone();\n var bCurve = this.bezierCurves[i];\n var relativeU = u - uTemp;\n return bCurve.getPoint(relativeU);\n };\n /**\n * Get the point on the bézier path at the given path fraction.\n *\n * @method getPointAt\n * @param {number} t - The absolute path position: <pre>0.0 <= t <= 1.0</pre>\n * @instance\n * @memberof BezierPath\n * @return {Vertex} The point at the absolute path position.\n **/\n BezierPath.prototype.getPointAt = function (t) {\n return this.getPoint(t * this.totalArcLength);\n };\n /**\n * Get the tangent of the bézier path at the given path fraction.<br>\n * <br>\n * Note that the returned vector is not normalized.\n *\n * @method getTangentAt\n * @param {number} t - The absolute path position: <pre>0.0 <= t <= 1.0</pre>\n * @instance\n * @memberof BezierPath\n * @return {Vertex} The tangent vector at the absolute path position.\n **/\n BezierPath.prototype.getTangentAt = function (t) {\n return this.getTangent(t * this.totalArcLength);\n };\n /**\n * Get the tangent of the bézier path at the given path location.<br>\n * <br>\n * Note that the returned vector is not normalized.\n *\n * @method getTangent\n * @param {number} u - The relative path position: <pre>0 <= u <= getLength()</pre>\n * @instance\n * @memberof BezierPath\n * @return {Vertex} The tangent vector at the relative path position.\n **/\n BezierPath.prototype.getTangent = function (u) {\n if (u < 0 || u > this.totalArcLength) {\n console.warn(\"[BezierPath.getTangent(u)] u is out of bounds: \" + u + \".\");\n // return undefined;\n u = Math.min(this.totalArcLength, Math.max(0, u));\n }\n // Find the spline to extract the value from\n var i = 0;\n var uTemp = 0.0;\n while (i < this.bezierCurves.length && uTemp + this.bezierCurves[i].getLength() < u) {\n uTemp += this.bezierCurves[i].getLength();\n i++;\n }\n var bCurve = this.bezierCurves[i];\n var relativeU = u - uTemp;\n return bCurve.getTangent(relativeU);\n };\n /**\n * Get the perpendicular of the bézier path at the given absolute path location (fraction).<br>\n * <br>\n * Note that the returned vector is not normalized.\n *\n * @method getPerpendicularAt\n * @param {number} t - The absolute path position: <pre>0.0 <= t <= 1.0</pre>\n * @instance\n * @memberof BezierPath\n * @return {Vertex} The perpendicluar vector at the absolute path position.\n **/\n BezierPath.prototype.getPerpendicularAt = function (t) {\n return this.getPerpendicular(t * this.totalArcLength);\n };\n /**\n * Get the perpendicular of the bézier path at the given relative path location.<br>\n * <br>\n * Note that the returned vector is not normalized.\n *\n * @method getPerpendicular\n * @param {number} u - The relative path position: <pre>0 <= u <= getLength()</pre>\n * @instance\n * @memberof BezierPath\n * @return {Vertex} The perpendicluar vector at the relative path position.\n **/\n BezierPath.prototype.getPerpendicular = function (u) {\n if (u < 0 || u > this.totalArcLength) {\n console.log(\"[BezierPath.getPerpendicular(u)] u is out of bounds: \" + u + \".\");\n u = Math.min(this.totalArcLength, Math.max(0, u));\n }\n // Find the spline to extract the value from\n var uResult = BezierPath._locateUIndex(this, u);\n var bCurve = this.bezierCurves[uResult.i];\n var relativeU = u - uResult.uPart;\n return bCurve.getPerpendicular(relativeU);\n };\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get all line intersections with this shape.\n *\n * This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.\n *\n * @param {VertTuple} line - The line to find intersections with.\n * @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).\n * @returns {Array<Vertex>} - An array of all intersections with the shape's outline.\n */\n BezierPath.prototype.lineIntersections = function (line, inVectorBoundsOnly) {\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n return this.bezierCurves.reduce(function (accu, curCurve) {\n return accu.concat(curCurve.lineIntersections(line, inVectorBoundsOnly));\n }, []);\n };\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @param line\n * @param lineIntersectionTangents\n * @returns\n */\n BezierPath.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n return this.bezierCurves.reduce(function (accu, curCurve) {\n return accu.concat(curCurve.lineIntersectionTangents(line, inVectorBoundsOnly));\n }, []);\n };\n //--- END --- Implement interface `Intersectable`\n /**\n * This is a helper function to locate the curve index for a given\n * absolute path position u.\n *\n * I decided to put this into privat scope as it is really specific. Maybe\n * put this into a utils wrapper.\n *\n * Returns:\n * - {number} i - the index of the containing curve.\n * - {number} uPart - the absolute curve length sum (length from the beginning to u, should equal u itself).\n * - {number} uBefore - the absolute curve length for all segments _before_ the matched curve (usually uBefore <= uPart).\n **/\n BezierPath._locateUIndex = function (path, u) {\n var i = 0;\n var uTemp = 0.0;\n var uBefore = 0.0;\n while (i < path.bezierCurves.length && uTemp + path.bezierCurves[i].getLength() < u) {\n uTemp += path.bezierCurves[i].getLength();\n if (i + 1 < path.bezierCurves.length)\n uBefore += path.bezierCurves[i].getLength();\n i++;\n }\n return { i: i, uPart: uTemp, uBefore: uBefore };\n };\n /**\n * Get a specific sub path from this path. The start and end position are specified by\n * ratio number in [0..1].\n *\n * 0.0 is at the beginning of the path.\n * 1.0 is at the end of the path.\n *\n * Values below 0 or beyond 1 are cropped down to the [0..1] interval.\n *\n * startT > endT is allowed, the returned sub path will have inverse direction then.\n *\n * @method getSubPathAt\n * @param {number} startT - The start position of the sub path.\n * @param {number} endT - The end position of the sub path.\n * @instance\n * @memberof BezierPath\n * @return {BezierPath} The desired sub path in the bounds [startT..endT].\n **/\n BezierPath.prototype.getSubPathAt = function (startT, endT) {\n startT = Math.max(0, startT);\n endT = Math.min(1.0, endT);\n var startU = startT * this.totalArcLength;\n var endU = endT * this.totalArcLength;\n var uStartResult = BezierPath._locateUIndex(this, startU); // { i:int, uPart:float, uBefore:float }\n var uEndResult = BezierPath._locateUIndex(this, endU); // { i:int, uPart:float, uBefore:float }\n var firstT = (startU - uStartResult.uBefore) / this.bezierCurves[uStartResult.i].getLength();\n if (uStartResult.i == uEndResult.i) {\n // Subpath begins and ends in the same path segment (just get a simple sub curve from that path element).\n var lastT = (endU - uEndResult.uBefore) / this.bezierCurves[uEndResult.i].getLength();\n var firstCurve = this.bezierCurves[uStartResult.i].getSubCurveAt(firstT, lastT);\n return BezierPath.fromArray([firstCurve]);\n }\n else {\n var curves = [];\n if (uStartResult.i > uEndResult.i) {\n // Back to front direction\n var firstCurve = this.bezierCurves[uStartResult.i].getSubCurveAt(firstT, 0.0);\n curves.push(firstCurve);\n for (var i = uStartResult.i - 1; i > uEndResult.i; i--) {\n curves.push(this.bezierCurves[i].clone().reverse());\n }\n var lastT = (endU - uEndResult.uBefore) / this.bezierCurves[uEndResult.i].getLength();\n curves.push(this.bezierCurves[uEndResult.i].getSubCurveAt(1.0, lastT));\n }\n else {\n // Front to back direction\n var firstCurve = this.bezierCurves[uStartResult.i].getSubCurveAt(firstT, 1.0);\n curves.push(firstCurve);\n for (var i = uStartResult.i + 1; i < uEndResult.i && i < this.bezierCurves.length; i++) {\n curves.push(this.bezierCurves[i].clone());\n }\n var lastT = (endU - uEndResult.uBefore) / this.bezierCurves[uEndResult.i].getLength();\n curves.push(this.bezierCurves[uEndResult.i].getSubCurveAt(0, lastT));\n }\n return BezierPath.fromArray(curves);\n }\n };\n /**\n * This function moves the addressed curve point (or control point) with\n * keeping up the path's curve integrity.<br>\n * <br>\n * Thus is done by moving neighbour- and control- points as needed.\n *\n * @method moveCurvePoint\n * @param {number} curveIndex - The curve index to move a point from.\n * @param {number} pointID - One of the curve's four point IDs (START_POINT,\n * START_CONTROL_POINT, END_CONTRO_POINT or END_POINT).\n * @param {XYCoords} moveAmount - The amount to move the addressed vertex by.\n * @instance\n * @memberof BezierPath\n * @return {void}\n **/\n BezierPath.prototype.moveCurvePoint = function (curveIndex, pointID, moveAmount) {\n var bCurve = this.getCurveAt(curveIndex);\n bCurve.moveCurvePoint(pointID, moveAmount, true, // move control point, too\n true // updateArcLengths\n );\n // If inner point and NOT control point\n // --> move neightbour\n if (pointID == this.START_POINT && (curveIndex > 0 || this.adjustCircular)) {\n // Set predecessor's control point!\n var predecessor = this.getCurveAt(curveIndex - 1 < 0 ? this.bezierCurves.length + (curveIndex - 1) : curveIndex - 1);\n predecessor.moveCurvePoint(this.END_CONTROL_POINT, moveAmount, true, // move control point, too\n false // updateArcLengths\n );\n }\n else if (pointID == this.END_POINT && (curveIndex + 1 < this.bezierCurves.length || this.adjustCircular)) {\n // Set successcor\n var successor = this.getCurveAt((curveIndex + 1) % this.bezierCurves.length);\n successor.moveCurvePoint(this.START_CONTROL_POINT, moveAmount, true, // move control point, too\n false // updateArcLengths\n );\n }\n else if (pointID == this.START_CONTROL_POINT && curveIndex > 0) {\n this.adjustPredecessorControlPoint(curveIndex, true, // obtain handle length?\n false // update arc lengths\n );\n }\n else if (pointID == this.END_CONTROL_POINT && curveIndex + 1 < this.getCurveCount()) {\n this.adjustSuccessorControlPoint(curveIndex, true, // obtain handle length?\n false // update arc lengths\n );\n }\n // Don't forget to update the arc lengths!\n // Note: this can be optimized as only two curves have changed their lengths!\n this.updateArcLengths();\n };\n /**\n * This helper function adjusts the given point's predecessor's control point.\n *\n * @method adjustPredecessorControlPoint\n * @param {number} curveIndex - The curve index to move a point from.\n * @param {boolean} obtainHandleLength - Moves the point with keeping the original handle length.\n * @param {boolean} updateArcLength - The amount to move the addressed vertex by.\n * @instance\n * @private\n * @memberof BezierPath\n * @return {void}\n **/\n BezierPath.prototype.adjustPredecessorControlPoint = function (curveIndex, obtainHandleLength, updateArcLengths) {\n if (!this.adjustCircular && curveIndex <= 0)\n return; // false;\n var mainCurve = this.getCurveAt(curveIndex);\n var neighbourCurve = this.getCurveAt(curveIndex - 1 < 0 ? this.getCurveCount() + (curveIndex - 1) : curveIndex - 1);\n BezierPath.adjustNeighbourControlPoint(mainCurve, neighbourCurve, mainCurve.getStartPoint(), // the reference point\n mainCurve.getStartControlPoint(), // the dragged control point\n neighbourCurve.getEndPoint(), // the neighbour's point\n neighbourCurve.getEndControlPoint(), // the neighbour's control point to adjust\n obtainHandleLength, updateArcLengths);\n };\n /**\n * This helper function adjusts the given point's successor's control point.\n *\n * @method adjustSuccessorControlPoint\n * @param {number} curveIndex - The curve index to move a point from.\n * @param {boolean} obtainHandleLength - Moves the point with keeping the original handle length.\n * @param {boolean} updateArcLength - The amount to move the addressed vertex by.\n * @instance\n * @private\n * @memberof BezierPath\n * @return {void}\n **/\n BezierPath.prototype.adjustSuccessorControlPoint = function (curveIndex, obtainHandleLength, updateArcLengths) {\n if (!this.adjustCircular && curveIndex + 1 > this.getCurveCount())\n return; // false;\n var mainCurve = this.getCurveAt(curveIndex);\n var neighbourCurve = this.getCurveAt((curveIndex + 1) % this.getCurveCount());\n /* return */ BezierPath.adjustNeighbourControlPoint(mainCurve, neighbourCurve, mainCurve.getEndPoint(), // the reference point\n mainCurve.getEndControlPoint(), // the dragged control point\n neighbourCurve.getStartPoint(), // the neighbour's point\n neighbourCurve.getStartControlPoint(), // the neighbour's control point to adjust\n obtainHandleLength, updateArcLengths);\n };\n /**\n * This helper function adjusts the given point's successor's control point.\n *\n * @method adjustNeighbourControlPoint\n * @param {CubicBezierCurve} mainCurve\n * @param {CubicBezierCurve} neighbourCurve\n * @param {Vertex} mainPoint\n * @param {Vertex} mainControlPoint\n * @param {Vertex} neighbourPoint\n * @param {Vertex} neighbourControlPoint\n * @param {boolean} obtainHandleLengths\n * @param {boolean} updateArcLengths\n * @instance\n * @private\n * @memberof BezierPath\n * @return {void}\n **/\n BezierPath.adjustNeighbourControlPoint = function (_mainCurve, // TODO: remove param\n neighbourCurve, mainPoint, mainControlPoint, neighbourPoint, neighbourControlPoint, obtainHandleLengths, _updateArcLengths // TODO: remove param\n ) {\n // Calculate start handle length\n var mainHandleBounds = new Vertex_1.Vertex(mainControlPoint.x - mainPoint.x, mainControlPoint.y - mainPoint.y);\n var neighbourHandleBounds = new Vertex_1.Vertex(neighbourControlPoint.x - neighbourPoint.x, neighbourControlPoint.y - neighbourPoint.y);\n var mainHandleLength = Math.sqrt(Math.pow(mainHandleBounds.x, 2) + Math.pow(mainHandleBounds.y, 2));\n var neighbourHandleLength = Math.sqrt(Math.pow(neighbourHandleBounds.x, 2) + Math.pow(neighbourHandleBounds.y, 2));\n if (mainHandleLength <= 0.1)\n return; // no secure length available for division? What about zoom? Use EPSILON?\n // Just invert the main handle (keep length or not?\n if (obtainHandleLengths) {\n neighbourControlPoint.set(neighbourPoint.x - mainHandleBounds.x * (neighbourHandleLength / mainHandleLength), neighbourPoint.y - mainHandleBounds.y * (neighbourHandleLength / mainHandleLength));\n }\n else {\n neighbourControlPoint.set(neighbourPoint.x - mainHandleBounds.x, neighbourPoint.y - mainHandleBounds.y);\n }\n neighbourCurve.updateArcLengths();\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Get the bounds of this Bézier path.\n *\n * Note the the curves' underlyung segment buffers are used to determine the bounds. The more\n * elements the segment buffers have, the more precise the returned bounds will be.\n *\n * @return {Bounds} The bounds of this Bézier path.\n **/\n BezierPath.prototype.getBounds = function () {\n var min = new Vertex_1.Vertex(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY);\n var max = new Vertex_1.Vertex(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY);\n var b;\n for (var i = 0; i < this.bezierCurves.length; i++) {\n b = this.bezierCurves[i].getBounds();\n min.x = Math.min(min.x, b.min.x);\n min.y = Math.min(min.y, b.min.y);\n max.x = Math.max(max.x, b.max.x);\n max.y = Math.max(max.y, b.max.y);\n }\n return new Bounds_1.Bounds(min, max);\n };\n //--- END --- Implement interface `IBounded`\n /**\n * Get n 'equally' distributed vertices along this Bézier path.\n *\n * As the changing curvature of the B slines makes prediction of distances difficult, the\n * returned vertices' distances are only relatively equal:\n * - the distance grows where curvature is large.\n * - the distance shrinks where curvature is small.\n *\n * Only the distance mean of all consecutive is 1/n-th of the total arc length.\n *\n * Usually this approximation is good enough for most use cases.\n *\n * @param {number} pointCount - (must be at least 2) The number of desired points (start and end point included).\n * @return {Array<Vertex>}\n */\n BezierPath.prototype.getEvenDistributionVertices = function (pointCount) {\n if (pointCount < 2) {\n throw new Error(\"pointCount must be larger than one; is \" + pointCount + \".\");\n }\n var result = [];\n if (this.bezierCurves.length === 0) {\n return result;\n }\n // Fetch and add the start point from the source polygon\n var polygonPoint = new Vertex_1.Vertex(this.bezierCurves[0].startPoint);\n result.push(polygonPoint);\n // if (this.bezierCurves.length === 1) {\n // return result;\n // }\n var perimeter = this.totalArcLength;\n var stepSize = perimeter / (pointCount - 1);\n var n = this.bezierCurves.length;\n var curveIndex = 0;\n var segmentLength = this.bezierCurves[0].arcLength;\n var curSegmentU = stepSize;\n var i = 1;\n while (i < pointCount && curveIndex < n) {\n // Check if next eq point is inside this segment\n if (curSegmentU < segmentLength) {\n var newPoint = this.bezierCurves[curveIndex].getPoint(curSegmentU);\n result.push(newPoint);\n curSegmentU += stepSize;\n i++;\n }\n else {\n curveIndex++;\n curSegmentU = curSegmentU - segmentLength;\n segmentLength = curveIndex < n ? this.bezierCurves[curveIndex].arcLength : 0;\n }\n }\n result.push(new Vertex_1.Vertex(this.bezierCurves[n - 1].endPoint));\n return result;\n };\n /**\n * Clone this BezierPath (deep clone).\n *\n * @method clone\n * @instance\n * @memberof BezierPath\n * @return {BezierPath}\n **/\n BezierPath.prototype.clone = function () {\n var path = new BezierPath(); // undefined);\n for (var i = 0; i < this.bezierCurves.length; i++) {\n path.bezierCurves.push(this.bezierCurves[i].clone());\n // Connect splines\n if (i > 0)\n path.bezierCurves[i - 1].endPoint = path.bezierCurves[i].startPoint;\n }\n path.updateArcLengths();\n path.adjustCircular = this.adjustCircular;\n return path;\n };\n /**\n * Compare this and the passed Bézier path.\n *\n * @method equals\n * @param {BezierPath} path - The pass to compare with.\n * @instance\n * @memberof BezierPath\n * @return {boolean}\n **/\n BezierPath.prototype.equals = function (path) {\n if (!path)\n return false;\n // Check if path contains the credentials\n if (!path.bezierCurves)\n return false;\n if (typeof path.bezierCurves.length == \"undefined\")\n return false;\n if (path.bezierCurves.length != this.bezierCurves.length)\n return false;\n for (var i = 0; i < this.bezierCurves.length; i++) {\n if (!this.bezierCurves[i].equals(path.bezierCurves[i]))\n return false;\n }\n return true;\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n *\n * @method destroy\n * @instance\n * @memberof BezierPath\n */\n BezierPath.prototype.destroy = function () {\n for (var i = 0; i < this.bezierCurves.length; i++) {\n this.bezierCurves[i].destroy();\n }\n this.isDestroyed = true;\n };\n /**\n * Convert this path to an array of path points that can be drawn by the default DrawLib\n * implementations.\n *\n * @method toPathPoints\n * @instance\n * @memberof BezierPath\n * @return {Array<XYCoords>}\n */\n BezierPath.prototype.toPathPoints = function () {\n if (this.bezierCurves.length === 0) {\n return [];\n }\n if (this.bezierCurves.length === 1) {\n return [\n this.bezierCurves[0].startPoint,\n this.bezierCurves[0].startControlPoint,\n this.bezierCurves[0].endControlPoint,\n this.bezierCurves[0].endPoint\n ];\n }\n var arr = [];\n arr.push(this.bezierCurves[0].startPoint);\n arr.push(this.bezierCurves[0].startControlPoint);\n for (var i = 1; i < this.bezierCurves.length; i++) {\n arr.push(this.bezierCurves[i - 1].endControlPoint);\n arr.push(this.bezierCurves[i - 1].endPoint);\n arr.push(this.bezierCurves[i].startPoint);\n arr.push(this.bezierCurves[i].startControlPoint);\n }\n arr.push(this.bezierCurves[0].endControlPoint);\n arr.push(this.bezierCurves[0].endPoint);\n return arr;\n };\n /**\n * Create a JSON string representation of this bézier curve.\n *\n * @method toJSON\n * @param {boolean} prettyFormat - If true then the function will add line breaks.\n * @instance\n * @memberof BezierPath\n * @return {string} The JSON string.\n **/\n BezierPath.prototype.toJSON = function (prettyFormat) {\n var buffer = [];\n buffer.push(\"[\"); // array begin\n for (var i = 0; i < this.bezierCurves.length; i++) {\n if (i > 0)\n buffer.push(\",\");\n if (prettyFormat)\n buffer.push(\"\\n\\t\");\n else\n buffer.push(\" \");\n buffer.push(this.bezierCurves[i].toJSON(prettyFormat));\n }\n if (this.bezierCurves.length != 0)\n buffer.push(\" \");\n buffer.push(\"]\"); // array end\n return buffer.join(\"\"); // Convert to string, with empty separator.\n };\n /**\n * Parse a BezierPath from the given JSON string.\n *\n * @method fromJSON\n * @param {string} jsonString - The string with the JSON data.\n * @throw An error if the string is not JSON or does not contain a bezier path object.\n * @static\n * @memberof BezierPath\n * @return {BezierPath} The parsed bezier path instance.\n **/\n BezierPath.fromJSON = function (jsonString) {\n var obj = JSON.parse(jsonString);\n return BezierPath.fromArray(obj);\n };\n /**\n * Construct a new path with a single curve. Adding more curves is always possible.\n *\n * @method fromCurve\n * @param {CubicBezierCurve} curve - The curve to construct a new path from.\n * @static\n * @memberof BezierPath\n * @return {BezierPath} The constructed bezier path instance.\n */\n BezierPath.fromCurve = function (curve) {\n var path = new BezierPath(); // []);\n path.addCurve(curve);\n return path;\n };\n /**\n * Create a BezierPath instance from the given array.\n *\n * @method fromArray\n * @param {Vertex[][]} arr - A two-dimensional array containing the bezier path vertices.\n * @throw An error if the array does not contain proper bezier path data.\n * @static\n * @memberof BezierPath\n * @return {BezierPath} The bezier path instance retrieved from the array data.\n **/\n BezierPath.fromArray = function (obj) {\n if (!Array.isArray(obj)) {\n throw \"[BezierPath.fromArray] Passed object must be an array.\";\n }\n var arr = obj; // FORCE?\n if (arr.length < 1) {\n throw \"[BezierPath.fromArray] Passed array must contain at least one bezier curve (has \" + arr.length + \").\";\n }\n // Create an empty bezier path\n var bPath = new BezierPath(); // undefined);\n var lastCurve = null;\n for (var i = 0; i < arr.length; i++) {\n // Convert object (or array?) to bezier curve\n var bCurve;\n if (CubicBezierCurve_1.CubicBezierCurve.isInstance(arr[i])) {\n bCurve = arr[i].clone();\n }\n else if (0 in arr[i] && 1 in arr[i] && 2 in arr[i] && 3 in arr[i]) {\n if (!arr[i][0] || !arr[i][1] || !arr[i][2] || !arr[i][3])\n throw \"Cannot convert path data to BezierPath instance. At least one element is undefined (index=\" + i + \"): \" + arr[i];\n bCurve = CubicBezierCurve_1.CubicBezierCurve.fromArray(arr[i]);\n }\n else {\n bCurve = CubicBezierCurve_1.CubicBezierCurve.fromObject(arr[i]);\n }\n // Set curve start point?\n // (avoid duplicate point instances!)\n if (lastCurve)\n bCurve.startPoint = lastCurve.endPoint;\n // Add to path's internal list\n bPath.bezierCurves.push(bCurve);\n // bPath.totalArcLength += bCurve.getLength();\n lastCurve = bCurve;\n }\n bPath.updateArcLengths();\n // Bezier segments added. Done\n return bPath;\n };\n /**\n * This function converts the bezier path into a string containing\n * integer values only.\n * The points' float values are rounded to 1 digit after the comma.\n *\n * The returned string represents a JSON array (with leading '[' and\n * trailing ']', the separator is ',').\n *\n * @method toReducedListRepresentation\n * @param {number} digits - The number of digits to be used after the comma '.'.\n * @instance\n * @memberof BezierPath\n * @return {string} The reduced list representation of this path.\n **/\n BezierPath.prototype.toReducedListRepresentation = function (digits) {\n if (typeof digits == \"undefined\")\n digits = 1;\n var buffer = [];\n buffer.push(\"[\"); // array begin\n for (var i = 0; i < this.bezierCurves.length; i++) {\n var curve = this.bezierCurves[i];\n buffer.push(curve.getStartPoint().x.toFixed(digits));\n buffer.push(\",\");\n buffer.push(curve.getStartPoint().y.toFixed(digits));\n buffer.push(\",\");\n buffer.push(curve.getStartControlPoint().x.toFixed(digits));\n buffer.push(\",\");\n buffer.push(curve.getStartControlPoint().y.toFixed(digits));\n buffer.push(\",\");\n buffer.push(curve.getEndControlPoint().x.toFixed(digits));\n buffer.push(\",\");\n buffer.push(curve.getEndControlPoint().y.toFixed(digits));\n buffer.push(\",\");\n }\n if (this.bezierCurves.length != 0) {\n var curve = this.bezierCurves[this.bezierCurves.length - 1];\n buffer.push(curve.getEndPoint().x.toFixed(digits));\n buffer.push(\",\");\n buffer.push(curve.getEndPoint().y.toFixed(digits));\n }\n buffer.push(\"]\"); // array end\n return buffer.join(\"\"); // Convert to string, with empty separator.\n };\n /**\n * Parse a BezierPath instance from the reduced list representation.<br>\n * <br>\n * The passed string must represent a JSON array containing numbers only.\n *\n * @method fromReducedListRepresentation\n * @param {string} listJSON - The number of digits to be used after the floating point.\n * @throw An error if the string is malformed.\n * @instance\n * @memberof BezierPath\n * @return {BezierPath} The bezier path instance retrieved from the string.\n **/\n BezierPath.fromReducedListRepresentation = function (listJSON, adjustCircular) {\n // Parse the array\n var pointArray = JSON.parse(listJSON);\n if (!pointArray.length) {\n console.log(\"Cannot parse bezier path from non-array object nor from empty point list.\");\n throw \"Cannot parse bezier path from non-array object nor from empty point list.\";\n }\n if (pointArray.length < 8) {\n console.log(\"Cannot build bezier path. The passed array must contain at least 8 elements (numbers).\");\n throw \"Cannot build bezier path. The passed array must contain at least 8 elements (numbers).\";\n }\n return BezierPath.fromReducedList(pointArray, adjustCircular);\n };\n /**\n * Convert a reduced list representation (array of numeric coordinates) to a BezierPath instance.\n *\n * The array's length must be 6*n + 2:\n * - [sx, sy, scx, scy, ecx, ecy, ... , ex, ey ]\n * | | | |\n * +--- sequence of curves --------+ +-end-+\n *\n * @param {number[]} pointArray\n * @returns BezierPath\n */\n BezierPath.fromReducedList = function (pointArray, adjustCircular) {\n // Convert to object\n var bezierPath = new BezierPath(); // null); // No points yet\n var startPoint = new Vertex_1.Vertex();\n var startControlPoint;\n var endControlPoint;\n var endPoint;\n var i = 0;\n do {\n if (i == 0) {\n // firstStartPoint =\n startPoint = new Vertex_1.Vertex(pointArray[i], pointArray[i + 1]);\n }\n startControlPoint = new Vertex_1.Vertex(pointArray[i + 2], pointArray[i + 3]);\n endControlPoint = new Vertex_1.Vertex(pointArray[i + 4], pointArray[i + 5]);\n // if (i + 8 >= pointArray.length) {\n // endPoint = firstStartPoint;\n // } else {\n endPoint = new Vertex_1.Vertex(pointArray[i + 6], pointArray[i + 7]);\n // }\n var bCurve = new CubicBezierCurve_1.CubicBezierCurve(startPoint, endPoint, startControlPoint, endControlPoint);\n bezierPath.bezierCurves.push(bCurve);\n startPoint = endPoint;\n i += 6;\n } while (i + 2 < pointArray.length);\n bezierPath.adjustCircular = adjustCircular !== null && adjustCircular !== void 0 ? adjustCircular : false;\n if (adjustCircular) {\n bezierPath.bezierCurves[bezierPath.bezierCurves.length - 1].endPoint = bezierPath.bezierCurves[0].startPoint;\n }\n bezierPath.updateArcLengths();\n return bezierPath;\n };\n // +---------------------------------------------------------------------------------\n // | These constants equal the values from CubicBezierCurve.\n // +-------------------------------\n /** @constant {number} */\n BezierPath.START_POINT = 0;\n /** @constant {number} */\n BezierPath.START_CONTROL_POINT = 1;\n /** @constant {number} */\n BezierPath.END_CONTROL_POINT = 2;\n /** @constant {number} */\n BezierPath.END_POINT = 3;\n return BezierPath;\n}());\nexports.BezierPath = BezierPath;\n//# sourceMappingURL=BezierPath.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date_init 2012-10-17 (Wrote a first version of this in that year).\n * @date 2018-04-03 (Refactored the code into a new class).\n * @modified 2018-04-28 Added some documentation.\n * @modified 2019-09-11 Added the scaleToCentroid(Number) function (used by the walking triangle demo).\n * @modified 2019-09-12 Added beautiful JSDoc compliable comments.\n * @modified 2019-11-07 Added to toSVG(options) function to make Triangles renderable as SVG.\n * @modified 2019-12-09 Fixed the determinant() function. The calculation was just wrong.\n * @modified 2020-03-16 (Corona times) Added the 'fromArray' function.\n * @modified 2020-03-17 Added the Triangle.toPolygon() function.\n * @modified 2020-03-17 Added proper JSDoc comments.\n * @modified 2020-03-25 Ported this class from vanilla-JS to Typescript.\n * @modified 2020-05-09 Added the new Circle class (ported to Typescript from the demos).\n * @modified 2020-05-12 Added getIncircularTriangle() function.\n * @modified 2020-05-12 Added getIncircle() function.\n * @modified 2020-05-12 Fixed the signature of getCircumcirle(). Was still a generic object.\n * @modified 2020-06-18 Added the `getIncenter` function.\n * @modified 2020-12-28 Added the `getArea` function.\n * @modified 2021-01-20 Added UID.\n * @modified 2021-01-22 Always updating circumcircle when retieving it.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-02-02 Cleared the `Triangle.toSVGString` function (deprecated). Use `drawutilssvg` instead.\n * @modified 2024-11-22 Added static utility function Triangle.utils.determinant; adapted method `determinant`.\n * @modified 2024-11-22 Changing visibility of `Triangle.utils` from `private` to `public`.\n * @modified 2025-14-16 Class `Triangle` now implements interface `Intersectable`.\n * @modified 2025-14-16 Class `Triangle` now implements interface `IBounded`.\n * @modified 2025-14-16 Class `Triangle` now implements interface `Intersectable`.\n * @modified 2025-14-16 Added method `Triangle.move`.\n * @modified 2026-06-10 Refactoring the `Trianble.bounds` method and added a plain `Triangle.utils.bounds` method.\n * @modified 2026-06-10 Refactoring the `Trianble.calcCircumCircle` method and added a plain `Triangle.utils.calcCircumCircle` method.\n * @modified 2026-06-13 Adding `Triangle.getVertices()`.\n * @version 2.11.0\n *\n * @file Triangle\n * @fileoverview A simple triangle class: three vertices.\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Triangle = void 0;\nvar Bounds_1 = require(\"./Bounds\");\nvar Circle_1 = require(\"./Circle\");\nvar Line_1 = require(\"./Line\");\nvar Polygon_1 = require(\"./Polygon\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar Vector_1 = require(\"./Vector\");\nvar VertTuple_1 = require(\"./VertTuple\");\nvar Vertex_1 = require(\"./Vertex\");\nvar geomutils_1 = require(\"./geomutils\");\n/**\n * @classdesc A triangle class for triangulations.\n *\n * The class was written for a Delaunay trinagulation demo so it might\n * contain some strange and unexpected functions.\n *\n * @requires Bounds\n * @requires Circle\n * @requires Line\n * @requires Vertex\n * @requires Polygon\n * @requires SVGSerializale\n * @requires UID\n * @requires UIDGenerator\n * @requires geomutils\n *\n */\nvar Triangle = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name Triangle\n * @param {Vertex} a - The first vertex of the triangle.\n * @param {Vertex} b - The second vertex of the triangle.\n * @param {Vertex} c - The third vertex of the triangle.\n **/\n function Triangle(a, b, c) {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"Triangle\";\n this.uid = UIDGenerator_1.UIDGenerator.next();\n this.a = a;\n this.b = b;\n this.c = c;\n this.calcCircumcircle();\n }\n /**\n * Create a new triangle from the given array of vertices.\n *\n * The array must have at least three vertices, otherwise an error will be raised.\n * This function will not create copies of the vertices.\n *\n * @method fromArray\n * @static\n * @param {Array<Vertex>} arr - The required array with at least three vertices.\n * @memberof Vertex\n * @return {Triangle}\n **/\n Triangle.fromArray = function (arr) {\n if (arr.length < 3)\n throw \"Cannot create triangle from array with less than three vertices (\".concat(arr.length, \")\");\n return new Triangle(arr[0], arr[1], arr[2]);\n };\n /**\n * Get the area of this triangle. The returned area is never negative.\n *\n * If you are interested in the signed area, please consider using the\n * `Triangle.utils.signedArea` helper function. This method just returns\n * the absolute value of the signed area.\n *\n * @method getArea\n * @instance\n * @memberof Triangle\n * @return {number} The non-negative area of this triangle.\n */\n Triangle.prototype.getArea = function () {\n return Math.abs(Triangle.utils.signedArea(this.a.x, this.a.y, this.b.x, this.b.y, this.c.x, this.c.y));\n };\n /**\n * Get the centroid of this triangle.\n *\n * The centroid is the average midpoint for each side.\n *\n * @method getCentroid\n * @return {Vertex} The centroid\n * @instance\n * @memberof Triangle\n **/\n Triangle.prototype.getCentroid = function () {\n return new Vertex_1.Vertex((this.a.x + this.b.x + this.c.x) / 3, (this.a.y + this.b.y + this.c.y) / 3);\n };\n /**\n * Scale the triangle towards its centroid.\n *\n * @method scaleToCentroid\n * @param {number} - The scale factor to use. That can be any scalar.\n * @return {Triangle} this (for chaining)\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.scaleToCentroid = function (factor) {\n var centroid = this.getCentroid();\n this.a.scale(factor, centroid);\n this.b.scale(factor, centroid);\n this.c.scale(factor, centroid);\n return this;\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Get the bounding box (bounds) of this Triangle.\n *\n * @method getBounds\n * @instance\n * @memberof Triangle\n * @return {Bounds} The rectangular bounds of this Triangle.\n **/\n Triangle.prototype.getBounds = function () {\n // return Bounds.computeFromVertices([this.a, this.b, this.c]);\n return this.bounds();\n };\n //--- END --- Implement interface `IBounded`\n /**\n * Move the Triangle's vertices by the given amount.\n *\n * @method move\n * @param {XYCoords} amount - The amount to move.\n * @instance\n * @memberof Triangle\n * @return {Triangle} this for chaining\n **/\n Triangle.prototype.move = function (amount) {\n this.a.add(amount);\n this.b.add(amount);\n this.c.add(amount);\n return this;\n };\n /**\n * Get the circumcircle of this triangle.\n *\n * The circumcircle is that unique circle on which all three\n * vertices of this triangle are located on.\n *\n * Please note that for performance reasons any changes to vertices will not reflect in changes\n * of the circumcircle (center or radius). Please call the calcCirumcircle() function\n * after triangle vertex changes.\n *\n * @method getCircumcircle\n * @return {Circle} - The circle touching exactly all three triangle vertices.\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.getCircumcircle = function () {\n // if( !this.center || !this.radius )\n this.calcCircumcircle();\n return new Circle_1.Circle(this.center.clone(), this.radius);\n };\n /**\n * Calculates the minimun enclosing circle.\n *\n * @method getMinimumEnclosingCircle\n * @return {Object} - { center:Vertex, radius:float }\n * @instance\n * @memberof Triangle\n * @returns\n */\n Triangle.prototype.getMinimumEnclosingCircle = function () {\n // First option: two points construct a circle and the third point is contained.\n var circleAB = VertTuple_1.VertTuple.vtutils.calcCircumcircle(this.a, this.b);\n if (Circle_1.Circle.circleUtils.containsPoint(circleAB.center, circleAB.radius, this.c)) {\n return Circle_1.Circle.fromICircle(circleAB);\n }\n var circleBC = VertTuple_1.VertTuple.vtutils.calcCircumcircle(this.b, this.c);\n if (Circle_1.Circle.circleUtils.containsPoint(circleBC.center, circleBC.radius, this.c)) {\n return Circle_1.Circle.fromICircle(circleBC);\n }\n var circleCA = VertTuple_1.VertTuple.vtutils.calcCircumcircle(this.c, this.a);\n if (Circle_1.Circle.circleUtils.containsPoint(circleCA.center, circleCA.radius, this.c)) {\n return Circle_1.Circle.fromICircle(circleCA);\n }\n // If none of the three upper cases applies: return the circumcircle.\n var circumCircle = Triangle.utils.calcCircumcircle(this.a, this.b, this.c);\n return Circle_1.Circle.fromICircle(circumCircle);\n };\n /**\n * Check if this triangle and the passed triangle share an\n * adjacent edge.\n *\n * For edge-checking Vertex.equals is used which uses an\n * an epsilon for comparison.\n *\n * @method isAdjacent\n * @param {Triangle} tri - The second triangle to check adjacency with.\n * @return {boolean} - True if this and the passed triangle have at least one common edge.\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.isAdjacent = function (tri) {\n var a = this.a.equals(tri.a) || this.a.equals(tri.b) || this.a.equals(tri.c);\n var b = this.b.equals(tri.a) || this.b.equals(tri.b) || this.b.equals(tri.c);\n var c = this.c.equals(tri.a) || this.c.equals(tri.b) || this.c.equals(tri.c);\n return (a && b) || (a && c) || (b && c);\n };\n /**\n * Get that vertex of this triangle (a,b,c) that is not vert1 nor vert2 of\n * the passed two.\n *\n * @method getThirdVertex\n * @param {Vertex} vert1 - The first vertex.\n * @param {Vertex} vert2 - The second vertex.\n * @return {Vertex} - The third vertex of this triangle that makes up the whole triangle with vert1 and vert2.\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.getThirdVertex = function (vert1, vert2) {\n if ((this.a.equals(vert1) && this.b.equals(vert2)) || (this.a.equals(vert2) && this.b.equals(vert1)))\n return this.c;\n if ((this.b.equals(vert1) && this.c.equals(vert2)) || (this.b.equals(vert2) && this.c.equals(vert1)))\n return this.a;\n //if( this.c.equals(vert1) && this.a.equals(vert2) || this.c.equals(vert2) && this.a.equals(vert1) )\n return this.b;\n };\n /**\n * Get the three triangele vertices in a 3-element array.\n *\n * @method getVertices\n * @returns {[Vertex, Vertex, Vertex]} - The three vertices – real instances, not copies.\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.getVertices = function () {\n return [this.a, this.b, this.c];\n };\n /**\n * Re-compute the circumcircle of this triangle (if the vertices\n * have changed).\n *\n * The circumcenter and radius are stored in this.center and\n * this.radius. There is a third result: radius_squared (for internal computations).\n *\n * @method calcCircumcircle\n * @return void\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.calcCircumcircle = function () {\n // // From\n // // http://www.exaflop.org/docs/cgafaq/cga1.html\n // const A: number = this.b.x - this.a.x;\n // const B: number = this.b.y - this.a.y;\n // const C: number = this.c.x - this.a.x;\n // const D: number = this.c.y - this.a.y;\n // const E: number = A * (this.a.x + this.b.x) + B * (this.a.y + this.b.y);\n // const F: number = C * (this.a.x + this.c.x) + D * (this.a.y + this.c.y);\n // const G: number = 2.0 * (A * (this.c.y - this.b.y) - B * (this.c.x - this.b.x));\n // let dx: number, dy: number;\n // if (Math.abs(G) < Triangle.EPSILON) {\n // // Collinear - find extremes and use the midpoint\n // const bounds: Bounds = this.bounds();\n // this.center = new Vertex((bounds.min.x + bounds.max.x) / 2, (bounds.min.y + bounds.max.y) / 2);\n // dx = this.center.x - bounds.min.x;\n // dy = this.center.y - bounds.min.y;\n // } else {\n // const cx: number = (D * E - B * F) / G;\n // const cy: number = (A * F - C * E) / G;\n // this.center = new Vertex(cx, cy);\n // dx = this.center.x - this.a.x;\n // dy = this.center.y - this.a.y;\n // }\n // this.radius_squared = dx * dx + dy * dy;\n // this.radius = Math.sqrt(this.radius_squared);\n var tmpCircle = Triangle.utils.calcCircumcircle(this.a, this.b, this.c);\n this.center = new Vertex_1.Vertex(tmpCircle.center.x, tmpCircle.center.y);\n this.radius = tmpCircle.radius;\n this.radius_squared = tmpCircle.radius_squared;\n }; // END calcCircumcircle\n /**\n * Check if the passed vertex is inside this triangle's\n * circumcircle.\n *\n * @method inCircumcircle\n * @param {Vertex} v - The vertex to check.\n * @return {boolean}\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.inCircumcircle = function (v) {\n var dx = this.center.x - v.x;\n var dy = this.center.y - v.y;\n var dist_squared = dx * dx + dy * dy;\n return dist_squared <= this.radius_squared;\n };\n /**\n * Get the rectangular bounds for this triangle.\n *\n * @method bounds\n * @return {Bounds} - The min/max bounds of this triangle.\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.bounds = function () {\n // return new Bounds(\n // new Vertex(Triangle.utils.min3(this.a.x, this.b.x, this.c.x), Triangle.utils.min3(this.a.y, this.b.y, this.c.y)),\n // new Vertex(Triangle.utils.max3(this.a.x, this.b.x, this.c.x), Triangle.utils.max3(this.a.y, this.b.y, this.c.y))\n // );\n return Triangle.utils.bounds(this.a, this.b, this.c);\n };\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get all line intersections with this polygon.\n *\n * This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.\n *\n * See demo `47-closest-vector-projection-on-polygon` for how it works.\n *\n * @param {VertTuple} line - The line to find intersections with.\n * @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).\n * @returns {Array<Vertex>} - An array of all intersections within the polygon bounds.\n */\n Triangle.prototype.lineIntersections = function (line, inVectorBoundsOnly) {\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersections of all lines inside the edge bounds\n return Polygon_1.Polygon.utils\n .locateLineIntersecion(line, [this.a, this.b, this.c], false, inVectorBoundsOnly)\n .map(function (intersectionTuple) { return intersectionTuple.intersection; });\n };\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @param line\n * @param inVectorBoundsOnly\n * @returns\n */\n Triangle.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersection tangents of all lines inside the edge bounds\n return Polygon_1.Polygon.utils\n .locateLineIntersecion(line, [this.a, this.b, this.c], false, inVectorBoundsOnly)\n .map(function (intersectionTuple) {\n // const polyLine = this.getEdgeAt(intersectionTuple.edgeIndex);\n var polyLine = _this.getEdgeAt(intersectionTuple.edgeIndex);\n return new Vector_1.Vector(polyLine.a.clone(), polyLine.b.clone()).moveTo(intersectionTuple.intersection);\n });\n };\n //--- END --- Implement interface `Intersectable`\n Triangle.prototype.getEdgeAt = function (edgeIndex) {\n var modIndex = edgeIndex % 3;\n return modIndex === 0 ? new Line_1.Line(this.a, this.b) : modIndex === 1 ? new Line_1.Line(this.b, this.c) : new Line_1.Line(this.c, this.a);\n };\n /**\n * Convert this triangle to a polygon instance.\n *\n * Plase note that this conversion does not perform a deep clone.\n *\n * @method toPolygon\n * @return {Polygon} A new polygon representing this triangle.\n * @instance\n * @memberof Triangle\n **/\n Triangle.prototype.toPolygon = function () {\n return new Polygon_1.Polygon([this.a, this.b, this.c]);\n };\n /**\n * Get the determinant of this triangle.\n *\n * @method determinant\n * @return {number} - The determinant (float).\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.determinant = function () {\n // (b.y - a.y)*(c.x - b.x) - (c.y - b.y)*(b.x - a.x);\n // return (this.b.y - this.a.y) * (this.c.x - this.b.x) - (this.c.y - this.b.y) * (this.b.x - this.a.x);\n return Triangle.utils.determinant(this.a, this.b, this.c);\n };\n /**\n * Checks if the passed vertex (p) is inside this triangle.\n *\n * Note: matrix determinants rock.\n *\n * @method containsPoint\n * @param {Vertex} p - The vertex to check.\n * @return {boolean}\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.containsPoint = function (p) {\n return Triangle.utils.pointIsInTriangle(p.x, p.y, this.a.x, this.a.y, this.b.x, this.b.y, this.c.x, this.c.y);\n };\n /**\n * Get that inner triangle which defines the maximal incircle.\n *\n * @return {Triangle} The triangle of those points in this triangle that define the incircle.\n */\n Triangle.prototype.getIncircularTriangle = function () {\n var lineA = new Line_1.Line(this.a, this.b);\n var lineB = new Line_1.Line(this.b, this.c);\n var lineC = new Line_1.Line(this.c, this.a);\n var bisector1 = geomutils_1.geomutils.nsectAngle(this.b, this.a, this.c, 2)[0]; // bisector of first angle (in b)\n var bisector2 = geomutils_1.geomutils.nsectAngle(this.c, this.b, this.a, 2)[0]; // bisector of second angle (in c)\n // Cast to non-null here because we know there _is_ an intersection\n var intersection = bisector1.intersection(bisector2);\n // Find the closest points on one of the polygon lines (all have same distance by construction)\n var circleIntersA = lineA.getClosestPoint(intersection);\n var circleIntersB = lineB.getClosestPoint(intersection);\n var circleIntersC = lineC.getClosestPoint(intersection);\n return new Triangle(circleIntersA, circleIntersB, circleIntersC);\n };\n /**\n * Get the incircle of this triangle. That is the circle that touches each side\n * of this triangle in exactly one point.\n *\n * Note this just calls getIncircularTriangle().getCircumcircle()\n *\n * @return {Circle} The incircle of this triangle.\n */\n Triangle.prototype.getIncircle = function () {\n return this.getIncircularTriangle().getCircumcircle();\n };\n /**\n * Get the incenter of this triangle (which is the center of the circumcircle).\n *\n * Note: due to performance reasonst the incenter is buffered inside the triangle because\n * computing it is relatively expensive. If a, b or c have changed you should call the\n * calcCircumcircle() function first, otherwise you might get wrong results.\n * @return Vertex The incenter of this triangle.\n **/\n Triangle.prototype.getIncenter = function () {\n if (!this.center || !this.radius) {\n this.calcCircumcircle();\n }\n return this.center.clone();\n };\n /**\n * Converts this triangle into a human-readable string.\n *\n * @method toString\n * @return {string}\n * @instance\n * @memberof Triangle\n */\n Triangle.prototype.toString = function () {\n return \"{ a : \" + this.a.toString() + \", b : \" + this.b.toString() + \", c : \" + this.c.toString() + \"}\";\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n Triangle.prototype.destroy = function () {\n this.a.destroy();\n this.b.destroy();\n this.c.destroy();\n this.isDestroyed = true;\n };\n /**\n * An epsilon for comparison.\n * This should be the same epsilon as in Vertex.\n *\n * @private\n **/\n Triangle.EPSILON = 1.0e-6;\n Triangle.utils = {\n // Used in the bounds() function.\n max3: function (a, b, c) {\n return a >= b && a >= c ? a : b >= a && b >= c ? b : c;\n },\n min3: function (a, b, c) {\n return a <= b && a <= c ? a : b <= a && b <= c ? b : c;\n },\n signedArea: function (p0x, p0y, p1x, p1y, p2x, p2y) {\n return 0.5 * (-p1y * p2x + p0y * (-p1x + p2x) + p0x * (p1y - p2y) + p1x * p2y);\n },\n /**\n * Used by the containsPoint() function.\n *\n * @private\n **/\n pointIsInTriangle: function (px, py, p0x, p0y, p1x, p1y, p2x, p2y) {\n //\n // Point-in-Triangle test found at\n // http://stackoverflow.com/questions/2049582/how-to-determine-a-point-in-a-2d-triangle\n // var area : number = 1/2*(-p1y*p2x + p0y*(-p1x + p2x) + p0x*(p1y - p2y) + p1x*p2y);\n var area = Triangle.utils.signedArea(p0x, p0y, p1x, p1y, p2x, p2y);\n var s = (1 / (2 * area)) * (p0y * p2x - p0x * p2y + (p2y - p0y) * px + (p0x - p2x) * py);\n var t = (1 / (2 * area)) * (p0x * p1y - p0y * p1x + (p0y - p1y) * px + (p1x - p0x) * py);\n return s > 0 && t > 0 && 1 - s - t > 0;\n },\n /**\n * Calculate the determinant of the three vertices a, b and c (in this order).\n * @param {XYCords} a - The first vertex.\n * @param {XYCords} b - The first vertex.\n * @param {XYCords} c - The first vertex.\n * @returns {nmber}\n */\n determinant: function (a, b, c) {\n return (b.y - a.y) * (c.x - b.x) - (c.y - b.y) * (b.x - a.x);\n },\n bounds: function (a, b, c) {\n return new Bounds_1.Bounds(new Vertex_1.Vertex(Triangle.utils.min3(a.x, b.x, c.x), Triangle.utils.min3(a.y, b.y, c.y)), new Vertex_1.Vertex(Triangle.utils.max3(a.x, b.x, c.x), Triangle.utils.max3(a.y, b.y, c.y)));\n },\n /**\n * Re-compute the circumcircle of this triangle (if the vertices\n * have changed).\n *\n * The circumcenter and radius are stored in this.center and\n * this.radius. There is a third result: radius_squared (for internal computations).\n *\n * @method calcCircumcircle\n * @return void\n * @instance\n * @memberof Triangle\n */\n calcCircumcircle: function (a, b, c) {\n // From\n // http://www.exaflop.org/docs/cgafaq/cga1.html\n var A = b.x - a.x;\n var B = b.y - a.y;\n var C = c.x - a.x;\n var D = c.y - a.y;\n var E = A * (a.x + b.x) + B * (a.y + b.y);\n var F = C * (a.x + c.x) + D * (a.y + c.y);\n var G = 2.0 * (A * (c.y - b.y) - B * (c.x - b.x));\n var dx, dy;\n var center;\n if (Math.abs(G) < Triangle.EPSILON) {\n // Collinear - find extremes and use the midpoint\n // const bounds: Bounds = this.bounds();\n var bounds = Triangle.utils.bounds(a, b, c);\n center = new Vertex_1.Vertex((bounds.min.x + bounds.max.x) / 2, (bounds.min.y + bounds.max.y) / 2);\n dx = center.x - bounds.min.x;\n dy = center.y - bounds.min.y;\n }\n else {\n var cx = (D * E - B * F) / G;\n var cy = (A * F - C * E) / G;\n center = new Vertex_1.Vertex(cx, cy);\n dx = center.x - a.x;\n dy = center.y - a.y;\n }\n var radius_squared = dx * dx + dy * dy;\n var radius = Math.sqrt(radius_squared);\n return { center: center, radius: radius, radius_squared: radius_squared };\n } // END calcCircumcircle\n };\n return Triangle;\n}());\nexports.Triangle = Triangle;\n//# sourceMappingURL=Triangle.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2012-10-17\n * @modified 2018-04-03 Refactored the code of october 2012 into a new class.\n * @modified 2018-04-28 Added some documentation.\n * @modified 2018-08-16 Added the set() function.\n * @modified 2018-08-26 Added VertexAttr.\n * @modified 2018-10-31 Extended the constructor by object{x,y}.\n * @modified 2018-11-19 Extended the set(number,number) function to set(Vertex).\n * @modified 2018-11-28 Added 'this' to the VertexAttr constructor.\n * @modified 2018-12-05 Added the sub(...) function. Changed the signature of the add() function! add(Vertex) and add(number,number) are now possible.\n * @modified 2018-12-21 (It's winter solstice) Added the inv()-function.\n * @modified 2019-01-30 Added the setX(Number) and setY(Number) functions.\n * @modified 2019-02-19 Added the difference(Vertex) function.\n * @modified 2019-03-20 Added JSDoc tags.\n * @modified 2019-04-24 Added the randomVertex(ViewPort) function.\n * @modified 2019-11-07 Added toSVGString(object) function.\n * @modified 2019-11-18 Added the rotate(number,Vertex) function.\n * @modified 2019-11-21 Fixed a bug in the rotate(...) function (elements were moved).\n * @modified 2020-03-06 Added functions invX() and invY().\n * @modified 2020-03-23 Ported to Typescript from JS.\n * @modified 2020-05-26 Added functions addX(number) and addY(number).\n * @modified 2020-10-30 Changed the warnings in `sub(...)` and `add(...)` into real errors.\n * @modified 2021-03-01 Changed the second param `center` in the `rotate` function from Vertex to XYCoords.\n * @modified 2021-12-01 Changed the type of param of `scale` to XYCoords.\n * @modified 2021-12-01 Added function `scaleXY` for non uniform scaling.\n * @modified 2021-12-17 Added the functions `lerp` and `lerpAbs` for linear interpolations.\n * @modified 2022-01-31 Added `Vertex.utils.arrayToJSON`.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-02-02 Cleared the `Vertex.toSVGString` function (deprecated). Use `drawutilssvg` instead.\n * @modified 2022-11-28 Added the `subXY`, `subX` and `subY` methods to the `Vertex` class.\n * @modified 2023-09-29 Downgraded types for the `Vertex.utils.buildArrowHead` function (replacing Vertex params by more generic XYCoords type).\n * @modified 2023-09-29 Added the `Vertex.abs()` method as it seems useful.\n * @modified 2024-03-08 Added the optional `precision` param to the `toString` method.\n * @modified 2024-12-17 Outsourced the euclidean distance calculation of `Vertex.distance` to `geomutils.dist4`.\n * @modified 2025-03-24 Making the second parameter `center` of the `Vertex.rotate` method optional.\n * @modified 2025-04-13 Adding the `Vertex.move(amount: XYCoords)` method (does the same as `add`, added by naming convention).\n * @modified 2025-05-07 Class `Vertex` is now implementing interface `IBounded` (to meet convention).\n * @modified 2026-06-10 Adding methods `Vertex.findClosestPoint` and `Vertex.findFarestPoint`.\n * @version 2.12.1\n *\n * @file Vertex\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Vertex = void 0;\nvar VertexAttr_1 = require(\"./VertexAttr\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar VertexListeners_1 = require(\"./VertexListeners\");\nvar geomutils_1 = require(\"./geomutils\");\nvar Bounds_1 = require(\"./Bounds\");\n/**\n * @classdesc A vertex is a pair of two numbers.<br>\n * <br>\n * It is used to identify a 2-dimensional point on the x-y-plane.\n *\n * @requires IVertexAttr\n * @requires SVGSerializable\n * @requires UID\n * @requires UIDGenerator\n * @requires VertexAttr\n * @requires VertexListeners\n * @requires XYCoords\n *\n */\nvar Vertex = /** @class */ (function () {\n /**\n * The constructor for the vertex class.\n *\n * @constructor\n * @name Vertex\n * @param {number} x - The x-coordinate of the new vertex.\n * @param {number} y - The y-coordinate of the new vertex.\n **/\n function Vertex(x, y) {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"Vertex\";\n this.uid = UIDGenerator_1.UIDGenerator.next();\n if (typeof x == \"undefined\") {\n this.x = 0;\n this.y = 0;\n }\n else if (typeof x == \"number\" && typeof y == \"number\") {\n this.x = x;\n this.y = y;\n }\n else {\n var tuple = x;\n if (typeof tuple.x == \"number\" && typeof tuple.y == \"number\") {\n this.x = tuple.x;\n this.y = tuple.y;\n }\n else {\n if (typeof x == \"number\")\n this.x = x;\n else if (typeof x == \"undefined\")\n this.x = 0;\n else\n this.x = NaN;\n if (typeof y == \"number\")\n this.y = y;\n else if (typeof y == \"undefined\")\n this.y = 0;\n else\n this.y = NaN;\n }\n }\n this.attr = new VertexAttr_1.VertexAttr();\n this.listeners = new VertexListeners_1.VertexListeners(this);\n }\n /**\n * Set the x- and y- component of this vertex.\n *\n * @method set\n * @param {number} x - The new x-component.\n * @param {number} y - The new y-component.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.set = function (x, y) {\n if (typeof x == \"number\" && typeof y == \"number\") {\n this.x = x;\n this.y = y;\n }\n else {\n var tuple = x;\n if (typeof tuple.x == \"number\" && typeof tuple.y == \"number\") {\n this.x = tuple.x;\n this.y = tuple.y;\n }\n else {\n if (typeof x == \"number\")\n this.x = x;\n else if (typeof x == \"undefined\")\n this.x = 0;\n else\n this.x = NaN;\n if (typeof y == \"number\")\n this.y = y;\n else if (typeof y == \"undefined\")\n this.y = 0;\n else\n this.y = NaN;\n }\n }\n return this;\n };\n /**\n * Set the x-component of this vertex.\n *\n * @method setX\n * @param {number} x - The new x-component.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.setX = function (x) {\n this.x = x;\n return this;\n };\n /**\n * Set the y-component of this vertex.\n *\n * @method setY\n * @param {number} y - The new y-component.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.setY = function (y) {\n this.y = y;\n return this;\n };\n /**\n * Set the x-component if this vertex to the inverse of its value.\n *\n * @method invX\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.invX = function () {\n this.x = -this.x;\n return this;\n };\n /**\n * Set the y-component if this vertex to the inverse of its value.\n *\n * @method invY\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.invY = function () {\n this.y = -this.y;\n return this;\n };\n /**\n * Add the passed amount to x- and y- component of this vertex.<br>\n * <br>\n * This function works with add( {number}, {number} ) and\n * add( {Vertex} ), as well.\n *\n * @method add\n * @param {(number|Vertex)} x - The amount to add to x (or a vertex itself).\n * @param {number=} y - The amount to add to y.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.add = function (x, y) {\n if (typeof x == \"number\" && typeof y == \"number\") {\n this.x += x;\n this.y += y;\n }\n else {\n var tuple = x;\n if (typeof tuple.x == \"number\" && typeof tuple.y == \"number\") {\n this.x += tuple.x;\n this.y += tuple.y;\n }\n else {\n if (typeof x == \"number\")\n this.x += x;\n else\n throw \"Cannot add \".concat(typeof x, \" to numeric x component!\");\n if (typeof y == \"number\")\n this.y += y;\n else\n throw \"Cannot add \".concat(typeof y, \" to numeric y component!\");\n }\n }\n return this;\n };\n /**\n * Move this point by the given amount.\n *\n * This method just calls `add(amount).\n *\n *\n * @method move\n * @param {Vertex} amount - The amount to move this vertex.\n * @return {Vertex} this - For chaining.\n * @instance\n * @memberof Vertex\n */\n Vertex.prototype.move = function (amount) {\n return this.add(amount);\n };\n /**\n * Add the passed amounts to the x- and y- components of this vertex.\n *\n * @method addXY\n * @param {number} x - The amount to add to x.\n * @param {number} y - The amount to add to y.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.addXY = function (amountX, amountY) {\n this.x += amountX;\n this.y += amountY;\n return this;\n };\n /**\n * Add the passed amounts to the x-component of this vertex.\n *\n * @method addX\n * @param {number} x - The amount to add to x.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.addX = function (amountX) {\n this.x += amountX;\n return this;\n };\n /**\n * Add the passed amounts to the y-component of this vertex.\n *\n * @method addY\n * @param {number} y - The amount to add to y.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.addY = function (amountY) {\n this.y += amountY;\n return this;\n };\n /**\n * Substract the passed amount from x- and y- component of this vertex.<br>\n * <br>\n * This function works with sub( {number}, {number} ) and\n * sub( {Vertex} ), as well.\n *\n * @method sub\n * @param {(number|Vertex)} x - The amount to substract from x (or a vertex itself).\n * @param {number=} y - The amount to substract from y.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.sub = function (x, y) {\n if (typeof x == \"number\" && typeof y == \"number\") {\n this.x -= x;\n this.y -= y;\n }\n else {\n var tuple = x;\n if (typeof tuple.x == \"number\" && typeof tuple.y == \"number\") {\n this.x -= tuple.x;\n this.y -= tuple.y;\n }\n else {\n if (typeof x == \"number\")\n this.x -= x;\n else\n throw \"Cannot add \".concat(typeof x, \" to numeric x component!\");\n if (typeof y == \"number\")\n this.y -= y;\n else\n throw \"Cannot add \".concat(typeof y, \" to numeric y component!\");\n }\n }\n return this;\n };\n /**\n * Substract the passed amounts from the x- and y- components of this vertex.\n *\n * @method subXY\n * @param {number} x - The amount to substract from x.\n * @param {number} y - The amount to substract from y.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.subXY = function (amountX, amountY) {\n this.x -= amountX;\n this.y -= amountY;\n return this;\n };\n /**\n * Substract the passed amounts from the x-component of this vertex.\n *\n * @method addX\n * @param {number} x - The amount to substract from x.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.subX = function (amountX) {\n this.x -= amountX;\n return this;\n };\n /**\n * Substract the passed amounts from the y-component of this vertex.\n *\n * @method subY\n * @param {number} y - The amount to substract from y.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.subY = function (amountY) {\n this.y -= amountY;\n return this;\n };\n /**\n * Check if this vertex equals the passed one.\n * <br>\n * This function uses an internal epsilon as tolerance.\n *\n * @method equals\n * @param {Vertex} vertex - The vertex to compare this with.\n * @return {boolean}\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.equals = function (vertex) {\n var eqX = Math.abs(this.x - vertex.x) < Vertex.EPSILON;\n var eqY = Math.abs(this.y - vertex.y) < Vertex.EPSILON;\n var result = eqX && eqY;\n return result;\n };\n /**\n * Create a copy of this vertex.\n *\n * @method clone\n * @return {Vertex} A new vertex, an exact copy of this.\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.clone = function () {\n return new Vertex(this.x, this.y);\n };\n /**\n * Get the distance to the passed point (in euclidean metric)\n *\n * @method distance\n * @param {XYCoords} vert - The vertex to measure the distance to.\n * @return {number}\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.distance = function (vert) {\n // return Math.sqrt(Math.pow(vert.x - this.x, 2) + Math.pow(vert.y - this.y, 2));\n return geomutils_1.geomutils.dist4(this.x, this.y, vert.x, vert.y);\n };\n /**\n * Get the angle of this point (relative to (0,0) or to the given other origin point).\n *\n * @method angle\n * @param {XYCoords} origin - The vertex to measure the angle from.\n * @return {number}\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.angle = function (origin) {\n var a = typeof origin === \"undefined\"\n ? Math.PI / 2 - Math.atan2(this.x, this.y)\n : Math.PI / 2 - Math.atan2(origin.x - this.x, origin.y - this.y);\n // Map to positive value\n return a < 0 ? Math.PI * 2 + a : a;\n };\n /**\n * Get the difference to the passed point.<br>\n * <br>\n * The difference is (vert.x-this.x, vert.y-this.y).\n *\n * @method difference\n * @param {Vertex} vert - The vertex to measure the x-y-difference to.\n * @return {Vertex} A new vertex.\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.difference = function (vert) {\n return new Vertex(vert.x - this.x, vert.y - this.y);\n };\n /**\n * This is a vector-like behavior and 'scales' this vertex\n * towards/from a given center by one uniform scale factor.\n *\n * @method scale\n * @param {number} factor - The factor to 'scale' this vertex; 1.0 means no change.\n * @param {XYCoords=} center - The origin of scaling; default is (0,0).\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.scale = function (factor, center) {\n return this.scaleXY({ x: factor, y: factor }, center);\n };\n /**\n * Perform a linear interpolation towards the given target vertex.\n * The amount value `t` is relative, `t=0.0` means no change, `t=1.0`\n * means this point will be moved to the exact target position.\n *\n * `t=0.5` will move this point to the middle of the connecting\n * linear segment.\n *\n * @param {XYCoords} target - The target position to lerp this vertex to.\n * @param {number} t - The relative amount, usually in [0..1], but other values will work, too.\n * @returns\n */\n Vertex.prototype.lerp = function (target, t) {\n var diff = this.difference(target);\n // return new Vertex(this.x + diff.x * t, this.y + diff.y * t);\n this.x += diff.x * t;\n this.y += diff.y * t;\n return this;\n };\n /**\n * Perform a linear interpolation towards the given target vertex (absolute variant).\n * The amount value `t` is absolute, which means the lerp amount is a direct distance\n * value. This point will have move the amount of the passed distance `u`.\n *\n * @param {XYCoords} target - The target position to lerp this vertex to.\n * @param {number} t - The absolute move amount to use to lerping.\n * @returns\n */\n Vertex.prototype.lerpAbs = function (target, u) {\n var dist = this.distance(target);\n var diff = this.difference(target);\n var step = { x: diff.x / dist, y: diff.y / dist };\n // return new Vertex(this.x + step.x * u, this.y + step.y * u);\n this.x += step.x * u;\n this.y += step.y * u;\n return this;\n };\n /**\n * This is a vector-like behavior and 'scales' this vertex\n * towards/from a given center by two independent x- and y- scale factors.\n *\n * @method scale\n * @param {number} factor - The factor to 'scale' this vertex; 1.0 means no change.\n * @param {XYCoords=} center - The origin of scaling; default is (0,0).\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.scaleXY = function (factors, center) {\n if (!center || typeof center === \"undefined\") {\n center = { x: 0, y: 0 };\n }\n this.x = center.x + (this.x - center.x) * factors.x;\n this.y = center.y + (this.y - center.y) * factors.y;\n return this;\n };\n /**\n * This is a vector-like behavior and 'rotates' this vertex\n * around given center.\n *\n * @method rotate\n * @param {number} angle - The angle in radians to 'rotate' this vertex; 0.0 means no change.\n * @param {XYCoords=} center - The center of rotation; default is (0,0).\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.rotate = function (angle, center) {\n if (!center || typeof center === \"undefined\") {\n center = { x: 0, y: 0 };\n }\n this.sub(center);\n angle += Math.atan2(this.y, this.x);\n var len = this.distance(Vertex.ZERO); // {x:0,y:0});\n this.x = len * Math.cos(angle);\n this.y = len * Math.sin(angle);\n this.add(center);\n return this;\n };\n /**\n * Multiply both components of this vertex with the given scalar.<br>\n * <br>\n * Note: as in<br>\n * https://threejs.org/docs/#api/math/Vector2.multiplyScalar\n *\n * @method multiplyScalar\n * @param {number} scalar - The scale factor; 1.0 means no change.\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.multiplyScalar = function (scalar) {\n this.x *= scalar;\n this.y *= scalar;\n return this;\n };\n /**\n * Round the two components x and y of this vertex.\n *\n * @method round\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.round = function () {\n this.x = Math.round(this.x);\n this.y = Math.round(this.y);\n return this;\n };\n /**\n * Change this vertex (x,y) to its inverse (-x,-y).\n *\n * @method inv\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.inv = function () {\n this.x = -this.x;\n this.y = -this.y;\n return this;\n };\n /**\n * Set both coordinates of this vertex to their absolute value (abs(x), abs(y)).\n *\n * @method abs\n * @return {Vertex} this\n * @instance\n * @memberof Vertex\n */\n Vertex.prototype.abs = function () {\n this.x = Math.abs(this.x);\n this.y = Math.abs(this.y);\n return this;\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Get the bounding box (bounds) of this Vertex.\n * This is just by convention – any vertex is just a position without any useful with or height (0).\n *\n * @method getBounds\n * @instance\n * @memberof Vertex\n * @return {Bounds} The rectangular bounds of this Vertex (width and height are zero).\n **/\n Vertex.prototype.getBounds = function () {\n // return Bounds.computeFromVertices([this.a, this.b, this.c]);\n return Bounds_1.Bounds.computeFromVertices([this]);\n };\n //--- END --- Implement interface `IBounded`\n /**\n * Find the one of two given points that's closest to this point.\n *\n * @method findClosestPoint\n * @instance\n * @memberof Vertex\n * @param {XYCoords | Vertex} pointA\n * @param {XYCoords | Vertex} pointB\n * @returns {XYCoords | Vertex}\n */\n Vertex.prototype.findClosestPoint = function (pointA, pointB) {\n // TODO: put this implementation to geomutils?\n var distA = this.distance(pointA);\n var distB = this.distance(pointB);\n if (distA < distB) {\n return pointA;\n }\n else {\n return pointB;\n }\n };\n /**\n * Find the one of two given points that's farest from this point.\n *\n * @method findFarestPoint\n * @instance\n * @memberof Vertex\n * @param {XYCoords | Vertex} pointA\n * @param {XYCoords | Vertex} pointB\n * @returns {XYCoords | Vertex}\n */\n Vertex.prototype.findFarestPoint = function (pointA, pointB) {\n var distA = this.distance(pointA);\n var distB = this.distance(pointB);\n if (distA > distB) {\n return pointA;\n }\n else {\n return pointB;\n }\n };\n /**\n * Get a string representation of this vertex.\n *\n * @method toString\n * @return {string} The string representation of this vertex.\n * @instance\n * @memberof Vertex\n **/\n Vertex.prototype.toString = function (precision) {\n if (typeof precision === \"undefined\") {\n return \"(\" + this.x + \",\" + this.y + \")\";\n }\n else {\n return \"(\" + this.x.toFixed(precision) + \",\" + this.y.toFixed(precision) + \")\";\n }\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n Vertex.prototype.destroy = function () {\n this.listeners.removeAllListeners();\n this.isDestroyed = true;\n };\n /**\n * Create a new random vertex inside the given viewport.\n *\n * @param {ViewPort} viewPort - A {min:Vertex, max:Vertex} viewport specifying the bounds.\n * @return A new vertex with a random position.\n **/\n Vertex.randomVertex = function (viewPort) {\n return new Vertex(viewPort.min.x + Math.random() * (viewPort.max.x - viewPort.min.x), viewPort.min.y + Math.random() * (viewPort.max.y - viewPort.min.y));\n };\n Vertex.ZERO = new Vertex(0, 0);\n /**\n * An epsilon for comparison\n *\n * @private\n * @readonly\n **/\n Vertex.EPSILON = 1.0e-6;\n Vertex.utils = {\n /**\n * Generate a four-point arrow head, starting at the vector end minus the\n * arrow head length.\n *\n * The first vertex in the returned array is guaranteed to be the located\n * at the vector line end minus the arrow head length.\n *\n *\n * Due to performance all params are required.\n *\n * The params scaleX and scaleY are required for the case that the scaling is not uniform (x and y\n * scaling different). Arrow heads should not look distored on non-uniform scaling.\n *\n * If unsure use 1.0 for scaleX and scaleY (=no distortion).\n * For headlen use 8, it's a good arrow head size.\n *\n * Example:\n * buildArrowHead( new Vertex(0,0), new Vertex(50,100), 8, 1.0, 1.0 )\n *\n * @param {XYCoords} zA - The start vertex of the vector to calculate the arrow head for.\n * @param {XYCoords} zB - The end vertex of the vector.\n * @param {number} headlen - The length of the arrow head (along the vector direction. A good value is 12).\n * @param {number} scaleX - The horizontal scaling during draw.\n * @param {number} scaleY - the vertical scaling during draw.\n **/\n // @DEPRECATED: use Vector.utils.buildArrowHead instead!!!\n buildArrowHead: function (zA, zB, headlen, scaleX, scaleY) {\n console.warn(\"[DEPRECATION] Vertex.utils.buildArrowHead is deprecated. Please use Vector.utils.buildArrowHead instead.\");\n var angle = Math.atan2((zB.y - zA.y) * scaleY, (zB.x - zA.x) * scaleX);\n var vertices = [];\n vertices.push(new Vertex(zB.x * scaleX - headlen * Math.cos(angle), zB.y * scaleY - headlen * Math.sin(angle)));\n vertices.push(new Vertex(zB.x * scaleX - headlen * 1.35 * Math.cos(angle - Math.PI / 8), zB.y * scaleY - headlen * 1.35 * Math.sin(angle - Math.PI / 8)));\n vertices.push(new Vertex(zB.x * scaleX, zB.y * scaleY));\n vertices.push(new Vertex(zB.x * scaleX - headlen * 1.35 * Math.cos(angle + Math.PI / 8), zB.y * scaleY - headlen * 1.35 * Math.sin(angle + Math.PI / 8)));\n return vertices;\n },\n /**\n * Convert the given vertices (array) to a JSON string.\n *\n * @param {number?} precision - (optional) The numeric precision to be used (number of precision digits).\n * @returns {string}\n */\n arrayToJSON: function (vertices, precision) {\n return JSON.stringify(vertices.map(function (vert) {\n return typeof precision === undefined\n ? { x: vert.x, y: vert.y }\n : { x: Number(vert.x.toFixed(precision)), y: Number(vert.y.toFixed(precision)) };\n }));\n }\n };\n return Vertex;\n}());\nexports.Vertex = Vertex;\n//# sourceMappingURL=Vertex.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2019-01-30\n * @modified 2019-03-23 Added JSDoc tags.\n * @modified 2020-03-25 Ported this class from vanilla-JS to Typescript.\n * @modified 2021-01-20 Added UID.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-02-02 Cleared the `PBImage.toSVGString` function (deprecated). Use `drawutilssvg` instead.\n * @version 1.2.0\n *\n * @file PBImage\n * @fileoverview As native Image objects have only a position and with\n * and height thei are not suitable for UI dragging interfaces.\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.PBImage = void 0;\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\n/**\n * @classdesc A wrapper for image objects. Has an upper left and a lower right corner point.\n *\n * @requires Vertex\n * @requires SVGSerializable\n * @requires UID\n * @requires UIDGenerator\n */\nvar PBImage = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name PBImage\n * @param {Image} image - The actual image.\n * @param {Vertex} upperLeft - The upper left corner.\n * @param {Vertex} lowerRight - The lower right corner.\n **/\n function PBImage(image, upperLeft, lowerRight) {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"PBImage\";\n this.uid = UIDGenerator_1.UIDGenerator.next();\n this.image = image;\n this.upperLeft = upperLeft;\n this.lowerRight = lowerRight;\n }\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n PBImage.prototype.destroy = function () {\n this.upperLeft.destroy();\n this.lowerRight.destroy();\n this.isDestroyed = true;\n };\n return PBImage;\n}());\nexports.PBImage = PBImage;\n//# sourceMappingURL=PBImage.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2018-11-28\n * @modified 2018-12-04 Added the toSVGString function.\n * @modified 2020-03-25 Ported this class from vanilla-JS to Typescript.\n * @modified 2021-01-20 Added UID.\n * @modified 2021-02-14 Added functions `radiusH` and `radiusV`.\n * @modified 2021-02-26 Added helper function `decribeSVGArc(...)`.\n * @modified 2021-03-01 Added attribute `rotation` to allow rotation of ellipses.\n * @modified 2021-03-03 Added the `vertAt` and `perimeter` methods.\n * @modified 2021-03-05 Added the `getFoci`, `normalAt` and `tangentAt` methods.\n * @modified 2021-03-09 Added the `clone` and `rotate` methods.\n * @modified 2021-03-10 Added the `toCubicBezier` method.\n * @modified 2021-03-15 Added `VEllipse.quarterSegmentCount` and `VEllipse.scale` functions.\n * @modified 2021-03-19 Added the `VEllipse.rotate` function.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-02-02 Cleared the `VEllipse.toSVGString` function (deprecated). Use `drawutilssvg` instead.\n * @modified 2025-03-31 ATTENTION: modified the winding direction of the `tangentAt` method to match with the Circle method. This is a breaking change!\n * @modified 2025-03-31 Adding the `VEllipse.move(amount: XYCoords)` method.\n * @modified 2025-04-19 Adding the `VEllipse.getBounds()` method.\n * @modified 2025-04-24 Adding the `VEllipse.getExtremePoints()` method for calculating minima and maxima.\n * @version 1.4.0\n *\n * @file VEllipse\n * @fileoverview Ellipses with a center and an x- and a y-axis (stored as a vertex).\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.VEllipse = void 0;\nvar Line_1 = require(\"./Line\");\nvar Vector_1 = require(\"./Vector\");\nvar Vertex_1 = require(\"./Vertex\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar CubicBezierCurve_1 = require(\"./CubicBezierCurve\");\nvar Circle_1 = require(\"./Circle\");\nvar Bounds_1 = require(\"./Bounds\");\n/**\n * @classdesc An ellipse class based on two vertices [centerX,centerY] and [radiusX,radiusY].\n *\n * @requires SVGSerializable\n * @requires UID\n * @requires UIDGenerator\n * @requires Vertex\n */\nvar VEllipse = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @param {Vertex} center - The ellipses center.\n * @param {Vertex} axis - The x- and y-axis (the two radii encoded in a control point).\n * @param {Vertex} rotation - [optional, default=0] The rotation of this ellipse.\n * @name VEllipse\n **/\n function VEllipse(center, axis, rotation) {\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n this.className = \"VEllipse\";\n this.uid = UIDGenerator_1.UIDGenerator.next();\n this.center = center;\n this.axis = axis;\n this.rotation = rotation || 0.0;\n }\n /**\n * Clone this ellipse (deep clone).\n *\n * @return {VEllipse} A copy of this ellipse.s\n */\n VEllipse.prototype.clone = function () {\n return new VEllipse(this.center.clone(), this.axis.clone(), this.rotation);\n };\n /**\n * Get the non-negative horizonal radius of this ellipse.\n *\n * @method radiusH\n * @instance\n * @memberof VEllipse\n * @return {number} The unsigned horizontal radius of this ellipse.\n */\n VEllipse.prototype.radiusH = function () {\n return Math.abs(this.signedRadiusH());\n };\n /**\n * Get the signed horizonal radius of this ellipse.\n *\n * @method signedRadiusH\n * @instance\n * @memberof VEllipse\n * @return {number} The signed horizontal radius of this ellipse.\n */\n VEllipse.prototype.signedRadiusH = function () {\n // return Math.abs(this.axis.x - this.center.x);\n // Rotate axis back to origin before calculating radius\n // return Math.abs(new Vertex(this.axis).rotate(-this.rotation,this.center).x - this.center.x);\n return new Vertex_1.Vertex(this.axis).rotate(-this.rotation, this.center).x - this.center.x;\n };\n /**\n * Get the non-negative vertical radius of this ellipse.\n *\n * @method radiusV\n * @instance\n * @memberof VEllipse\n * @return {number} The unsigned vertical radius of this ellipse.\n */\n VEllipse.prototype.radiusV = function () {\n return Math.abs(this.signedRadiusV());\n };\n /**\n * Get the signed vertical radius of this ellipse.\n *\n * @method radiusV\n * @instance\n * @memberof VEllipse\n * @return {number} The signed vertical radius of this ellipse.\n */\n VEllipse.prototype.signedRadiusV = function () {\n // Rotate axis back to origin before calculating radius\n return new Vertex_1.Vertex(this.axis).rotate(-this.rotation, this.center).y - this.center.y;\n };\n /**\n * Get the the minima and maxima (points) of this (rotated) ellipse.\n *\n * @method getExtremePoints\n * @instance\n * @memberof VEllipse\n * @return {[Vertex, Vertex, Vertex, Vertex]} Get the the minima and maxima (points) of this (rotated) ellipse.\n */\n VEllipse.prototype.getExtremePoints = function () {\n var a = this.radiusH();\n var b = this.radiusV();\n // Calculate t_x values\n var t_x1 = Math.atan2(-b * Math.sin(this.rotation), a * Math.cos(this.rotation));\n var t_x2 = t_x1 + Math.PI;\n // Calculate x values at t_x\n var x_x1 = this.center.x + a * Math.cos(t_x1) * Math.cos(this.rotation) - b * Math.sin(t_x1) * Math.sin(this.rotation);\n var y_x1 = this.center.y + a * Math.cos(t_x1) * Math.sin(this.rotation) + b * Math.sin(t_x1) * Math.cos(this.rotation);\n var x_x2 = this.center.x + a * Math.cos(t_x2) * Math.cos(this.rotation) - b * Math.sin(t_x2) * Math.sin(this.rotation);\n var y_x2 = this.center.y + a * Math.cos(t_x2) * Math.sin(this.rotation) + b * Math.sin(t_x2) * Math.cos(this.rotation);\n var x_max, x_min;\n if (x_x1 > x_x2) {\n x_max = new Vertex_1.Vertex(x_x1, y_x1);\n x_min = new Vertex_1.Vertex(x_x2, y_x2);\n }\n else {\n x_max = new Vertex_1.Vertex(x_x2, y_x2);\n x_min = new Vertex_1.Vertex(x_x1, y_x1);\n }\n // Calculate t_y values\n var t_y1 = Math.atan2(b * Math.cos(this.rotation), a * Math.sin(this.rotation));\n var t_y2 = t_y1 + Math.PI;\n // Calculate y values at t_y\n var x_y1 = this.center.x + a * Math.cos(t_y1) * Math.cos(this.rotation) - b * Math.sin(t_y1) * Math.sin(this.rotation);\n var y_y1 = this.center.y + a * Math.cos(t_y1) * Math.sin(this.rotation) + b * Math.sin(t_y1) * Math.cos(this.rotation);\n var x_y2 = this.center.x + a * Math.cos(t_y2) * Math.cos(this.rotation) - b * Math.sin(t_y2) * Math.sin(this.rotation);\n var y_y2 = this.center.y + a * Math.cos(t_y2) * Math.sin(this.rotation) + b * Math.sin(t_y2) * Math.cos(this.rotation);\n var y_max, y_min;\n if (y_y1 > y_y2) {\n y_max = new Vertex_1.Vertex(x_y1, y_y1);\n y_min = new Vertex_1.Vertex(x_y2, y_y2);\n }\n else {\n y_max = new Vertex_1.Vertex(x_y2, y_y2);\n y_min = new Vertex_1.Vertex(x_y1, y_y1);\n }\n return [x_max, x_min, y_max, y_min];\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Get the bounds of this ellipse.\n *\n * The bounds are approximated by the underlying segment buffer; the more segment there are,\n * the more accurate will be the returned bounds.\n *\n * @method getBounds\n * @instance\n * @memberof VEllipse\n * @return {Bounds} The bounds of this ellipse.\n **/\n VEllipse.prototype.getBounds = function () {\n // Thanks to Cuixiping\n // https://stackoverflow.com/questions/87734/how-do-you-calculate-the-axis-aligned-bounding-box-of-an-ellipse\n var r1 = this.radiusH();\n var r2 = this.radiusV();\n var ux = r1 * Math.cos(this.rotation);\n var uy = r1 * Math.sin(this.rotation);\n var vx = r2 * Math.cos(this.rotation + Math.PI / 2);\n var vy = r2 * Math.sin(this.rotation + Math.PI / 2);\n var bbox_halfwidth = Math.sqrt(ux * ux + vx * vx);\n var bbox_halfheight = Math.sqrt(uy * uy + vy * vy);\n return new Bounds_1.Bounds({ x: this.center.x - bbox_halfwidth, y: this.center.y - bbox_halfheight }, { x: this.center.x + bbox_halfwidth, y: this.center.y + bbox_halfheight });\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Move the ellipse by the given amount. This is equivalent by moving the `center` and `axis` points.\n *\n * @method move\n * @param {XYCoords} amount - The amount to move.\n * @instance\n * @memberof VEllipse\n * @return {VEllipse} this for chaining\n **/\n VEllipse.prototype.move = function (amount) {\n this.center.add(amount);\n this.axis.add(amount);\n return this;\n };\n /**\n * Scale this ellipse by the given factor from the center point. The factor will be applied to both radii.\n *\n * @method scale\n * @instance\n * @memberof VEllipse\n * @param {number} factor - The factor to scale by.\n * @return {VEllipse} this for chaining.\n */\n VEllipse.prototype.scale = function (factor) {\n this.axis.scale(factor, this.center);\n return this;\n };\n /**\n * Rotate this ellipse around its center.\n *\n * @method rotate\n * @instance\n * @memberof VEllipse\n * @param {number} angle - The angle to rotate by.\n * @returns {VEllipse} this for chaining.\n */\n VEllipse.prototype.rotate = function (angle) {\n this.axis.rotate(angle, this.center);\n this.rotation += angle;\n return this;\n };\n /**\n * Get the vertex on the ellipse's outline at the given angle.\n *\n * @method vertAt\n * @instance\n * @memberof VEllipse\n * @param {number} angle - The angle to determine the vertex at.\n * @return {Vertex} The vertex on the outline at the given angle.\n */\n VEllipse.prototype.vertAt = function (angle) {\n // Tanks to Narasinham for the vertex-on-ellipse equations\n // https://math.stackexchange.com/questions/22064/calculating-a-point-that-lies-on-an-ellipse-given-an-angle\n var a = this.radiusH();\n var b = this.radiusV();\n return new Vertex_1.Vertex(VEllipse.utils.polarToCartesian(this.center.x, this.center.y, a, b, angle)).rotate(this.rotation, this.center);\n };\n /**\n * Get the normal vector at the given angle.\n * The normal vector is the vector that intersects the ellipse in a 90 degree angle\n * at the given point (speicified by the given angle).\n *\n * Length of desired normal vector can be specified, default is 1.0.\n *\n * @method normalAt\n * @instance\n * @memberof VEllipse\n * @param {number} angle - The angle to get the normal vector at.\n * @param {number=1.0} length - [optional, default=1] The length of the returned vector.\n */\n VEllipse.prototype.normalAt = function (angle, length) {\n var point = this.vertAt(angle - this.rotation); // HERE IS THE CORRECT BEHAVIOR!\n var foci = this.getFoci();\n // Calculate the angle between [point,focusA] and [point,focusB]\n var angleA = new Line_1.Line(point, foci[0]).angle();\n var angleB = new Line_1.Line(point, foci[1]).angle();\n var centerAngle = angleA + (angleB - angleA) / 2.0;\n var endPointA = point.clone().addX(50).clone().rotate(centerAngle, point);\n var endPointB = point\n .clone()\n .addX(50)\n .clone()\n .rotate(Math.PI + centerAngle, point);\n var resultVector = this.center.distance(endPointA) < this.center.distance(endPointB)\n ? new Vector_1.Vector(point, endPointB)\n : new Vector_1.Vector(point, endPointA);\n if (typeof length === \"number\") {\n resultVector.setLength(length);\n }\n return resultVector;\n };\n /**\n * Get the tangent vector at the given angle.\n * The tangent vector is the vector that touches the ellipse exactly at the given given\n * point (speicified by the given angle).\n *\n * Note that the tangent is just 90 degree rotated normal vector.\n *\n * Length of desired tangent vector can be specified, default is 1.0.\n *\n * @method tangentAt\n * @instance\n * @memberof VEllipse\n * @param {number} angle - The angle to get the tangent vector at.\n * @param {number=1.0} length - [optional, default=1] The length of the returned vector.\n */\n VEllipse.prototype.tangentAt = function (angle, length) {\n var normal = this.normalAt(angle, length);\n return normal.inv().perp();\n };\n /**\n * Get the perimeter of this ellipse.\n *\n * @method perimeter\n * @instance\n * @memberof VEllipse\n * @return {number}\n */\n VEllipse.prototype.perimeter = function () {\n // This method does not use an iterative approximation to determine the perimeter, but it uses\n // a wonderful closed approximation found by Srinivasa Ramanujan.\n // Matt Parker made a neat video about it:\n // https://www.youtube.com/watch?v=5nW3nJhBHL0\n var a = this.radiusH();\n var b = this.radiusV();\n return Math.PI * (3 * (a + b) - Math.sqrt((3 * a + b) * (a + 3 * b)));\n };\n /**\n * Get the two foci of this ellipse.\n *\n * @method getFoci\n * @instance\n * @memberof VEllipse\n * @return {Array<Vertex>} An array with two elements, the two focal points of the ellipse (foci).\n */\n VEllipse.prototype.getFoci = function () {\n // https://www.mathopenref.com/ellipsefoci.html\n var rh = this.radiusH();\n var rv = this.radiusV();\n var sdiff = rh * rh - rv * rv;\n // f is the distance of each focs to the center.\n var f = Math.sqrt(Math.abs(sdiff));\n // Foci on x- or y-axis?\n if (sdiff < 0) {\n return [\n this.center.clone().addY(f).rotate(this.rotation, this.center),\n this.center.clone().addY(-f).rotate(this.rotation, this.center)\n ];\n }\n else {\n return [\n this.center.clone().addX(f).rotate(this.rotation, this.center),\n this.center.clone().addX(-f).rotate(this.rotation, this.center)\n ];\n }\n };\n /**\n * Get equally distributed points on the outline of this ellipse.\n *\n * @method getEquidistantVertices\n * @instance\n * @param {number} pointCount - The number of points.\n * @returns {Array<Vertex>}\n */\n VEllipse.prototype.getEquidistantVertices = function (pointCount) {\n var angles = VEllipse.utils.equidistantVertAngles(this.radiusH(), this.radiusV(), pointCount);\n var result = [];\n for (var i = 0; i < angles.length; i++) {\n result.push(this.vertAt(angles[i]));\n }\n return result;\n };\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get the line intersections as vectors with this ellipse.\n *\n * @method lineIntersections\n * @instance\n * @param {VertTuple<Vector> ray - The line/ray to intersect this ellipse with.\n * @param {boolean} inVectorBoundsOnly - (default=false) Set to true if only intersections within the vector bounds are of interest.\n * @returns\n */\n VEllipse.prototype.lineIntersections = function (ray, inVectorBoundsOnly) {\n // Question: what happens to extreme versions when ellipse is a line (width or height is zero)?\n // This would result in a Division_by_Zero exception!\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Step A: create clones for operations (keep originals unchanged)\n var ellipseCopy = this.clone(); // VEllipse\n var rayCopy = ray.clone(); // Vector\n // Step B: move both so ellipse's center is located at (0,0)\n var moveAmount = ellipseCopy.center.clone().inv();\n ellipseCopy.move(moveAmount);\n rayCopy.add(moveAmount);\n // Step C: rotate eclipse backwards it's rotation, so that rotation is zero (0.0).\n // Rotate together with ray!\n var rotationAmount = -ellipseCopy.rotation;\n ellipseCopy.rotate(rotationAmount); // Rotation around (0,0) = center of translated ellipse\n rayCopy.a.rotate(rotationAmount, ellipseCopy.center);\n rayCopy.b.rotate(rotationAmount, ellipseCopy.center);\n // Step D: find x/y factors to use for scaling to transform the ellipse to a circle.\n // Scale together with vector ray.\n var radiusH = ellipseCopy.radiusH();\n var radiusV = ellipseCopy.radiusV();\n var scalingFactors = radiusH > radiusV ? { x: radiusV / radiusH, y: 1.0 } : { x: 1.0, y: radiusH / radiusV };\n // Step E: scale ellipse AND ray by calculated factors.\n ellipseCopy.axis.scaleXY(scalingFactors);\n rayCopy.a.scaleXY(scalingFactors);\n rayCopy.b.scaleXY(scalingFactors);\n // Intermediate result: now the ellipse is transformed to a circle and we can calculate intersections :)\n // Step F: calculate circle+line intersecions\n var tmpCircle = new Circle_1.Circle(new Vertex_1.Vertex(), ellipseCopy.radiusH()); // radiusH() === radiusV()\n var intersections = tmpCircle.lineIntersections(rayCopy, inVectorBoundsOnly);\n // Step G: transform intersecions back to original configuration\n intersections.forEach(function (intersectionPoint) {\n // Reverse transformation from above.\n intersectionPoint.scaleXY({ x: 1 / scalingFactors.x, y: 1 / scalingFactors.y }, ellipseCopy.center);\n intersectionPoint.rotate(-rotationAmount, ellipseCopy.center);\n intersectionPoint.sub(moveAmount);\n });\n return intersections;\n };\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @param line\n * @param lineIntersectionTangents\n * @returns\n */\n VEllipse.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersections of all lines plus their tangents inside the circle bounds\n var interSectionPoints = this.lineIntersections(line, inVectorBoundsOnly);\n return interSectionPoints.map(function (vert) {\n // Calculate angle\n var lineFromCenter = new Line_1.Line(_this.center, vert);\n var angle = lineFromCenter.angle();\n // Calculate tangent at angle\n return _this.tangentAt(angle);\n });\n };\n //--- END --- Implement interface `Intersectable`\n /**\n * Convert this ellipse into cubic Bézier curves.\n *\n * @param {number=3} quarterSegmentCount - The number of segments per base elliptic quarter (default is 3, min is 1).\n * @param {number=0.666666} threshold - The Bézier threshold (default value 0.666666 approximates the ellipse with best results\n * but you might wish to use other values)\n * @return {Array<CubicBezierCurve>} An array of cubic Bézier curves representing this ellipse.\n */\n VEllipse.prototype.toCubicBezier = function (quarterSegmentCount, threshold) {\n // Math by Luc Maisonobe\n // http://www.spaceroots.org/documents/ellipse/node22.html\n // Note that ellipses with radiusH=0 or radiusV=0 cannot be represented as Bézier curves.\n // Return a single line here (as a Bézier curve)?\n // if (Math.abs(this.radiusV()) < 0.00001) {\n // const radiusH = this.radiusH();\n // return [\n // new CubicBezierCurve(\n // this.center.clone().addX(radiusH),\n // this.center.clone().addX(-radiusH),\n // this.center.clone(),\n // this.center.clone()\n // )\n // ]; // TODO: test horizontal line ellipse\n // }\n // if (Math.abs(this.radiusH()) < 0.00001) {\n // const radiusV = this.radiusV();\n // return [\n // new CubicBezierCurve(\n // this.center.clone().addY(radiusV),\n // this.center.clone().addY(-radiusV),\n // this.center.clone(),\n // this.center.clone()\n // )\n // ]; // TODO: test vertical line ellipse\n // }\n // At least 4, but 16 seems to be a good value.\n var segmentCount = Math.max(1, quarterSegmentCount || 3) * 4;\n threshold = typeof threshold === \"undefined\" ? 0.666666 : threshold;\n var radiusH = this.radiusH();\n var radiusV = this.radiusV();\n var curves = [];\n var angles = VEllipse.utils.equidistantVertAngles(radiusH, radiusV, segmentCount);\n var curAngle = angles[0] + this.rotation;\n var startPoint = this.vertAt(curAngle);\n for (var i = 0; i < angles.length; i++) {\n var nextAngle = angles[(i + 1) % angles.length] + this.rotation;\n var endPoint = this.vertAt(nextAngle);\n if (Math.abs(radiusV) < 0.0001 || Math.abs(radiusH) < 0.0001) {\n // Distorted ellipses can only be approximated by linear Bézier segments\n var diff = startPoint.difference(endPoint);\n var curve = new CubicBezierCurve_1.CubicBezierCurve(startPoint.clone(), endPoint.clone(), startPoint.clone().addXY(diff.x * 0.333, diff.y * 0.333), endPoint.clone().addXY(-diff.x * 0.333, -diff.y * 0.333));\n curves.push(curve);\n }\n else {\n var startTangent = this.tangentAt(curAngle + this.rotation);\n var endTangent = this.tangentAt(nextAngle + this.rotation);\n // Find intersection (ignore that the result might be null in some extreme cases)\n var intersection = startTangent.intersection(endTangent);\n // What if intersection is undefined?\n // --> This *can* not happen if segmentCount > 2 and height and width of the ellipse are not zero.\n var startDiff = startPoint.difference(intersection);\n var endDiff = endPoint.difference(intersection);\n var curve = new CubicBezierCurve_1.CubicBezierCurve(startPoint.clone(), endPoint.clone(), startPoint.clone().add(startDiff.scale(threshold)), endPoint.clone().add(endDiff.scale(threshold)));\n curves.push(curve);\n }\n startPoint = endPoint;\n curAngle = nextAngle;\n }\n return curves;\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n VEllipse.prototype.destroy = function () {\n this.center.destroy();\n this.axis.destroy();\n this.isDestroyed = true;\n };\n /**\n * A static collection of ellipse-related helper functions.\n * @static\n */\n VEllipse.utils = {\n /**\n * Calculate a particular point on the outline of the given ellipse (center plus two radii plus angle).\n *\n * @name polarToCartesian\n * @param {number} centerX - The x coordinate of the elliptic center.\n * @param {number} centerY - The y coordinate of the elliptic center.\n * @param {number} radiusH - The horizontal radius of the ellipse.\n * @param {number} radiusV - The vertical radius of the ellipse.\n * @param {number} angle - The angle (in radians) to get the desired outline point for.\n * @reutn {XYCoords} The outlont point in absolute x-y-coordinates.\n */\n polarToCartesian: function (centerX, centerY, radiusH, radiusV, angle) {\n // Tanks to Narasinham for the vertex-on-ellipse equations\n // https://math.stackexchange.com/questions/22064/calculating-a-point-that-lies-on-an-ellipse-given-an-angle\n var s = Math.sin(Math.PI / 2 - angle);\n var c = Math.cos(Math.PI / 2 - angle);\n return {\n x: centerX + (radiusH * radiusV * s) / Math.sqrt(Math.pow(radiusH * c, 2) + Math.pow(radiusV * s, 2)),\n y: centerY + (radiusH * radiusV * c) / Math.sqrt(Math.pow(radiusH * c, 2) + Math.pow(radiusV * s, 2))\n };\n },\n /**\n * Get the `theta` for a given `phi` (used to determine equidistant points on ellipse).\n *\n * @param radiusH\n * @param radiusV\n * @param phi\n * @returns {number} theta\n */\n phiToTheta: function (radiusH, radiusV, phi) {\n // See https://math.stackexchange.com/questions/172766/calculating-equidistant-points-around-an-ellipse-arc\n var tanPhi = Math.tan(phi);\n var tanPhi2 = tanPhi * tanPhi;\n var theta = -Math.PI / 2 + phi + Math.atan(((radiusH - radiusV) * tanPhi) / (radiusV + radiusH * tanPhi2));\n return theta;\n },\n /**\n * Get n equidistant points on the elliptic arc.\n *\n * @param pointCount\n * @returns\n */\n equidistantVertAngles: function (radiusH, radiusV, pointCount) {\n var angles = [];\n for (var i = 0; i < pointCount; i++) {\n var phi = Math.PI / 2.0 + ((Math.PI * 2) / pointCount) * i;\n var theta = VEllipse.utils.phiToTheta(radiusH, radiusV, phi);\n angles[i] = theta;\n }\n return angles;\n }\n }; // END utils\n return VEllipse;\n}());\nexports.VEllipse = VEllipse;\n//# sourceMappingURL=VEllipse.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2018-03-19\n * @modified 2018-04-28 Added the param 'wasDragged'.\n * @modified 2018-08-16 Added the param 'dragAmount'.\n * @modified 2018-08-27 Added the param 'element'.\n * @modified 2018-11-11 Changed the scope from a simple global var to a member of window/_context.\n * @modified 2018-11-19 Renamed the 'mousedown' function to 'down' and the 'mouseup' function to 'up'.\n * @modified 2018-11-28 Added the 'wheel' listener.\n * @modified 2018-12-09 Cleaned up some code.\n * @modified 2019-02-10 Cleaned up some more code.\n * @modified 2020-03-25 Ported this class from vanilla-JS to Typescript.\n * @modified 2020-04-08 Fixed the click event (internally fired a 'mouseup' event) (1.0.10)\n * @modified 2020-04-08 Added the optional 'name' property. (1.0.11)\n * @modified 2020-04-08 The new version always installs internal listenrs to track drag events even\n * if there is no external drag listener installed (1.1.0).\n * @modified 2020-10-04 Added extended JSDoc comments.\n * @modified 2020-11-25 Added the `isTouchEvent` param.\n * @modified 2021-01-10 The mouse handler is now also working with SVGElements.\n * @modified 2022-08-16 Fixed a bug in the mouse button detection.\n * @version 1.2.1\n *\n * @file MouseHandler\n * @public\n **/\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.MouseHandler = exports.XWheelEvent = exports.XMouseEvent = void 0;\nvar XMouseEvent = /** @class */ (function (_super) {\n __extends(XMouseEvent, _super);\n function XMouseEvent() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n return XMouseEvent;\n}(MouseEvent));\nexports.XMouseEvent = XMouseEvent;\nvar XWheelEvent = /** @class */ (function (_super) {\n __extends(XWheelEvent, _super);\n function XWheelEvent() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n return XWheelEvent;\n}(WheelEvent));\nexports.XWheelEvent = XWheelEvent;\n/**\n * @classdesc A simple mouse handler for demos.\n * Use to avoid load massive libraries like jQuery.\n *\n * @requires XYCoords\n */\nvar MouseHandler = /** @class */ (function () {\n /**\n * The constructor.\n *\n * Pass the DOM element you want to receive mouse events from.\n *\n * Usage\n * =====\n * @example\n * // Javascript\n * new MouseHandler( document.getElementById('mycanvas') )\n *\t .drag( function(e) {\n *\t\tconsole.log( 'Mouse dragged: ' + JSON.stringify(e) );\n *\t\tif( e.params.leftMouse ) ;\n *\t\telse if( e.params.rightMouse ) ;\n *\t } )\n *\t .move( function(e) {\n *\t\tconsole.log( 'Mouse moved: ' + JSON.stringify(e.params) );\n *\t } )\n * .up( function(e) {\n * console.log( 'Mouse up. Was dragged?', e.params.wasDragged );\n * } )\n * .down( function(e) {\n * console.log( 'Mouse down.' );\n * } )\n * .click( function(e) {\n * console.log( 'Click.' );\n * } )\n * .wheel( function(e) {\n * console.log( 'Wheel. delta='+e.deltaY );\n * } )\n *\n * @example\n * // Typescript\n * new MouseHandler( document.getElementById('mycanvas') )\n *\t .drag( (e:XMouseEvent) => {\n *\t\tconsole.log( 'Mouse dragged: ' + JSON.stringify(e) );\n *\t\tif( e.params.leftMouse ) ;\n *\t\telse if( e.params.rightMouse ) ;\n *\t } )\n *\t .move( (e:XMouseEvent) => {\n *\t\tconsole.log( 'Mouse moved: ' + JSON.stringify(e.params) );\n *\t } )\n * .up( (e:XMouseEvent) => {\n * console.log( 'Mouse up. Was dragged?', e.params.wasDragged );\n * } )\n * .down( (e:XMouseEvent) => {\n * console.log( 'Mouse down.' );\n * } )\n * .click( (e:XMouseEvent) => {\n * console.log( 'Click.' );\n * } )\n * .wheel( (e:XWheelEvent) => {\n * console.log( 'Wheel. delta='+e.deltaY );\n * } )\n *\n * @constructor\n * @instance\n * @memberof MouseHandler\n * @param {HTMLElement} element\n **/\n function MouseHandler(element, name) {\n this.mouseDownPos = undefined;\n this.mouseDragPos = undefined;\n // TODO: cc\n // private mousePos : { x:number, y:number }|undefined = undefined;\n this.mouseButton = -1;\n this.listeners = {};\n this.installed = {};\n this.handlers = {};\n // +----------------------------------------------------------------------\n // | Some private vars to store the current mouse/position/button state.\n // +-------------------------------------------------\n this.name = name;\n this.element = element;\n this.mouseDownPos = undefined;\n this.mouseDragPos = undefined;\n // this.mousePos = null;\n this.mouseButton = -1;\n this.listeners = {};\n this.installed = {};\n this.handlers = {};\n // +----------------------------------------------------------------------\n // | Define the internal event handlers.\n // |\n // | They will dispatch the modified event (relative mouse position,\n // | drag offset, ...) to the callbacks.\n // +-------------------------------------------------\n var _self = this;\n this.handlers[\"mousemove\"] = function (e) {\n if (_self.listeners.mousemove)\n _self.listeners.mousemove(_self.mkParams(e, \"mousemove\"));\n if (_self.mouseDragPos && _self.listeners.drag)\n _self.listeners.drag(_self.mkParams(e, \"drag\"));\n if (_self.mouseDownPos)\n _self.mouseDragPos = _self.relPos(e);\n };\n this.handlers[\"mouseup\"] = function (e) {\n if (_self.listeners.mouseup)\n _self.listeners.mouseup(_self.mkParams(e, \"mouseup\"));\n _self.mouseDragPos = undefined;\n _self.mouseDownPos = undefined;\n _self.mouseButton = -1;\n };\n this.handlers[\"mousedown\"] = function (e) {\n _self.mouseDragPos = _self.relPos(e);\n _self.mouseDownPos = _self.relPos(e);\n _self.mouseButton = e.button;\n if (_self.listeners.mousedown)\n _self.listeners.mousedown(_self.mkParams(e, \"mousedown\"));\n };\n this.handlers[\"click\"] = function (e) {\n if (_self.listeners.click)\n _self.listeners.click(_self.mkParams(e, \"click\"));\n };\n this.handlers[\"wheel\"] = function (e) {\n if (_self.listeners.wheel)\n _self.listeners.wheel(_self.mkParams(e, \"wheel\"));\n };\n this.element.addEventListener(\"mousemove\", this.handlers[\"mousemove\"]);\n this.element.addEventListener(\"mouseup\", this.handlers[\"mouseup\"]);\n this.element.addEventListener(\"mousedown\", this.handlers[\"mousedown\"]);\n this.element.addEventListener(\"click\", this.handlers[\"click\"]);\n this.element.addEventListener(\"wheel\", this.handlers[\"wheel\"]);\n }\n /**\n * Get relative position from the given MouseEvent.\n *\n * @name relPos\n * @memberof MouseHandler\n * @instance\n * @private\n * @param {MouseEvent} e - The mouse event to get the relative position for.\n * @return {XYCoords} The relative mouse coordinates.\n */\n MouseHandler.prototype.relPos = function (e) {\n return { x: e.offsetX, y: e.offsetY };\n };\n /**\n * Build the extended event params.\n *\n * @name mkParams\n * @memberof MouseHandler\n * @instance\n * @private\n * @param {MouseEvent} event - The mouse event to get the relative position for.\n * @param {string} eventName - The name of the firing event.\n * @return {XMouseEvent}\n */\n MouseHandler.prototype.mkParams = function (event, eventName) {\n var _a, _b;\n var rel = this.relPos(event);\n var xEvent = event;\n xEvent.params = {\n element: this.element,\n name: eventName,\n isTouchEvent: false,\n pos: rel,\n button: event.button, // this.mouseButton,\n leftButton: event.button === 0, // this.mouseButton === 0,\n middleButton: event.button === 1, // this.mouseButton === 1,\n rightButton: event.button === 2, // this.mouseButton === 2,\n mouseDownPos: (_a = this.mouseDownPos) !== null && _a !== void 0 ? _a : { x: NaN, y: NaN },\n draggedFrom: (_b = this.mouseDragPos) !== null && _b !== void 0 ? _b : { x: NaN, y: NaN },\n wasDragged: this.mouseDownPos != null && (this.mouseDownPos.x != rel.x || this.mouseDownPos.y != rel.y),\n dragAmount: this.mouseDragPos != null ? { x: rel.x - this.mouseDragPos.x, y: rel.y - this.mouseDragPos.y } : { x: 0, y: 0 }\n };\n return xEvent;\n };\n /**\n * Install a new listener.\n * Please note that this mouse handler can only handle one listener per event type.\n *\n * @name listenFor\n * @memberof MouseHandler\n * @instance\n * @private\n * @param {string} eventName - The name of the firing event to listen for.\n * @return {void}\n */\n MouseHandler.prototype.listenFor = function (eventName) {\n if (this.installed[eventName])\n return;\n // In the new version 1.1.0 has all internal listeners installed by default.\n this.installed[eventName] = true;\n };\n /**\n * Un-install a new listener.\n *\n * @name listenFor\n * @memberof MouseHandler\n * @instance\n * @private\n * @param {string} eventName - The name of the firing event to unlisten for.\n * @return {void}\n */\n MouseHandler.prototype.unlistenFor = function (eventName) {\n if (!this.installed[eventName])\n return;\n // In the new version 1.1.0 has all internal listeners installed by default.\n delete this.installed[eventName];\n };\n /**\n * Installer function to listen for a specific event: mouse-drag.\n * Pass your callbacks here.\n *\n * Note: this support chaining.\n *\n * @name drag\n * @memberof MouseHandler\n * @instance\n * @param {XMouseCallback} callback - The drag-callback to listen for.\n * @return {MouseHandler} this\n */\n MouseHandler.prototype.drag = function (callback) {\n if (this.listeners.drag)\n this.throwAlreadyInstalled(\"drag\");\n this.listeners.drag = callback;\n this.listenFor(\"mousedown\");\n this.listenFor(\"mousemove\");\n this.listenFor(\"mouseup\");\n return this;\n };\n /**\n * Installer function to listen for a specific event: mouse-move.\n * Pass your callbacks here.\n *\n * Note: this support chaining.\n *\n * @name move\n * @memberof MouseHandler\n * @instance\n * @param {XMouseCallback} callback - The move-callback to listen for.\n * @return {MouseHandler} this\n */\n MouseHandler.prototype.move = function (callback) {\n if (this.listeners.mousemove)\n this.throwAlreadyInstalled(\"mousemove\");\n this.listenFor(\"mousemove\");\n this.listeners.mousemove = callback;\n return this;\n };\n /**\n * Installer function to listen for a specific event: mouse-up.\n * Pass your callbacks here.\n *\n * Note: this support chaining.\n *\n * @name up\n * @memberof MouseHandler\n * @instance\n * @param {XMouseCallback} callback - The up-callback to listen for.\n * @return {MouseHandler} this\n */\n MouseHandler.prototype.up = function (callback) {\n if (this.listeners.mouseup)\n this.throwAlreadyInstalled(\"mouseup\");\n this.listenFor(\"mouseup\");\n this.listeners.mouseup = callback;\n return this;\n };\n /**\n * Installer function to listen for a specific event: mouse-down.\n * Pass your callbacks here.\n *\n * Note: this support chaining.\n *\n * @name down\n * @memberof MouseHandler\n * @instance\n * @param {XMouseCallback} callback - The down-callback to listen for.\n * @return {MouseHandler} this\n */\n MouseHandler.prototype.down = function (callback) {\n if (this.listeners.mousedown)\n this.throwAlreadyInstalled(\"mousedown\");\n this.listenFor(\"mousedown\");\n this.listeners.mousedown = callback;\n return this;\n };\n /**\n * Installer function to listen for a specific event: mouse-click.\n * Pass your callbacks here.\n *\n * Note: this support chaining.\n *\n * @name click\n * @memberof MouseHandler\n * @instance\n * @param {XMouseCallback} callback - The click-callback to listen for.\n * @return {MouseHandler} this\n */\n MouseHandler.prototype.click = function (callback) {\n if (this.listeners.click)\n this.throwAlreadyInstalled(\"click\");\n this.listenFor(\"click\");\n this.listeners.click = callback;\n return this;\n };\n /**\n * Installer function to listen for a specific event: mouse-wheel.\n * Pass your callbacks here.\n *\n * Note: this support chaining.\n *\n * @name wheel\n * @memberof MouseHandler\n * @instance\n * @param {XWheelCallback} callback - The wheel-callback to listen for.\n * @return {MouseHandler} this\n */\n MouseHandler.prototype.wheel = function (callback) {\n if (this.listeners.wheel)\n this.throwAlreadyInstalled(\"wheel\");\n this.listenFor(\"wheel\");\n this.listeners.wheel = callback;\n return this;\n };\n /**\n * An internal function to throw events.\n *\n * @name throwAlreadyInstalled\n * @memberof MouseHandler\n * @instance\n * @private\n * @param {string} name - The name of the event.\n * @return {void}\n */\n MouseHandler.prototype.throwAlreadyInstalled = function (name) {\n throw \"This MouseHandler already has a '\".concat(name, \"' callback. To keep the code simple there is only room for one.\");\n };\n /**\n * Call this when your work is done.\n *\n * The function will un-install all event listeners.\n *\n * @name destroy\n * @memberof MouseHandler\n * @instance\n * @private\n * @return {void}\n */\n MouseHandler.prototype.destroy = function () {\n this.unlistenFor(\"mousedown\");\n this.unlistenFor(\"mousemove\");\n this.unlistenFor(\"moseup\");\n this.unlistenFor(\"click\");\n this.unlistenFor(\"wheel\");\n this.element.removeEventListener(\"mousemove\", this.handlers[\"mousemove\"]);\n this.element.removeEventListener(\"mouseup\", this.handlers[\"mousedown\"]);\n this.element.removeEventListener(\"mousedown\", this.handlers[\"mousedown\"]);\n this.element.removeEventListener(\"click\", this.handlers[\"click\"]);\n this.element.removeEventListener(\"wheel\", this.handlers[\"wheel\"]);\n };\n return MouseHandler;\n}());\nexports.MouseHandler = MouseHandler;\n//# sourceMappingURL=MouseHandler.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2018-08-27\n * @modified 2018-11-28 Added the vertex-param to the constructor and extended the event. Vertex events now have a 'params' attribute object.\n * @modified 2019-03-20 Added JSDoc tags.\n * @modified 2020-02-22 Added 'return this' to the add* functions (for chanining).\n * @modified 2020-03-23 Ported to Typescript from JS.\n * @modified 2020-11-17 Added the `click` handler.\n * @modified 2026-04-04 Adding null-listeners will now throw an error.\n * @version 1.2.0\n *\n * @file VertexListeners\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.VertexListeners = void 0;\n/**\n * @classdesc An event listeners wrapper. This is just a set of three listener\n * queues (drag, dragStart, dragEnd) and their respective firing\n * functions.\n *\n */\nvar VertexListeners = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name VertexListeners\n * @param {Vertex} vertex - The vertex to use these listeners on (just a backward reference).\n **/\n function VertexListeners(vertex) {\n this.click = [];\n this.drag = [];\n this.dragStart = [];\n this.dragEnd = [];\n this.vertex = vertex;\n }\n /**\n * Add a click listener.\n *\n * @method addClickListener\n * @param {VertexListeners~dragListener} listener - The click listener to add (a callback).\n * @return {VertexListeners} this (for chaining)\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.addClickListener = function (listener) {\n VertexListeners._addListener(this.click, listener);\n return this;\n };\n /**\n * The click listener is a function with a single drag event param.\n * @callback VertexListeners~clickListener\n * @param {Event} e - The (extended) click event.\n */\n /**\n * Remove a drag listener.\n *\n * @method removeDragListener\n * @param {VertexListeners~dragListener} listener - The drag listener to remove (a callback).\n * @return {VertexListeners} this (for chaining)\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.removeClickListener = function (listener) {\n this.click = VertexListeners._removeListener(this.click, listener);\n return this;\n };\n /**\n * The click listener is a function with a single drag event param.\n * @callback VertexListeners~clickListener\n * @param {Event} e - The (extended) click event.\n */\n /**\n * Add a drag listener.\n *\n * @method addDragListener\n * @param {VertexListeners~dragListener} listener - The drag listener to add (a callback).\n * @return {VertexListeners} this (for chaining)\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.addDragListener = function (listener) {\n VertexListeners._addListener(this.drag, listener);\n return this;\n };\n /**\n * The drag listener is a function with a single drag event param.\n * @callback VertexListeners~dragListener\n * @param {Event} e - The (extended) drag event.\n */\n /**\n * Remove a drag listener.\n *\n * @method removeDragListener\n * @param {VertexListeners~dragListener} listener - The drag listener to remove (a callback).\n * @return {VertexListeners} this (for chaining)\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.removeDragListener = function (listener) {\n this.drag = VertexListeners._removeListener(this.drag, listener);\n return this;\n };\n /**\n * Add a dragStart listener.\n *\n * @method addDragListener\n * @param {VertexListeners~dragStartListener} listener - The drag-start listener to add (a callback).\n * @return {VertexListeners} this (for chaining)\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.addDragStartListener = function (listener) {\n VertexListeners._addListener(this.dragStart, listener);\n return this;\n };\n /**\n * The drag-start listener is a function with a single drag event param.\n * @callback VertexListeners~dragStartListener\n * @param {Event} e - The (extended) drag event.\n */\n /**\n * Remove a dragStart listener.\n *\n * @method addDragStartListener\n * @param {VertexListeners~dragListener} listener - The drag listener to remove (a callback).\n * @return {VertexListeners} this (for chaining)\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.removeDragStartListener = function (listener) {\n this.dragStart = VertexListeners._removeListener(this.dragStart, listener);\n return this;\n };\n /**\n * Add a dragEnd listener.\n *\n * @method addDragListener\n * @param {VertexListeners~dragEndListener} listener - The drag-end listener to add (a callback).\n * @return {VertexListeners} this (for chaining)\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.addDragEndListener = function (listener) {\n // this.dragEnd.push( listener );\n VertexListeners._addListener(this.dragEnd, listener);\n return this;\n };\n /**\n * The drag-end listener is a function with a single drag event param.\n * @callback VertexListeners~dragEndListener\n * @param {Event} e - The (extended) drag event.\n */\n /**\n * Remove a drag listener.\n *\n * @method removeDragEndListener\n * @param {VertexListeners~clickListener} listener - The drag listener to remove (a callback).\n * @return {VertexListeners} this (for chaining)\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.removeDragEndListener = function (listener) {\n // this.drag.push( listener );\n this.dragEnd = VertexListeners._removeListener(this.dragEnd, listener);\n return this;\n };\n /**\n * Fire a click event with the given event instance to all\n * installed click listeners.\n *\n * @method fireClickEvent\n * @param {VertEvent|XMouseEvent} e - The click event itself to be fired to all installed drag listeners.\n * @return {void}\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.fireClickEvent = function (e) {\n VertexListeners._fireEvent(this, this.click, e);\n };\n /**\n * Fire a drag event with the given event instance to all\n * installed drag listeners.\n *\n * @method fireDragEvent\n * @param {VertEvent|XMouseEvent} e - The drag event itself to be fired to all installed drag listeners.\n * @return {void}\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.fireDragEvent = function (e) {\n VertexListeners._fireEvent(this, this.drag, e);\n };\n /**\n * Fire a dragStart event with the given event instance to all\n * installed drag-start listeners.\n *\n * @method fireDragStartEvent\n * @param {VertEvent|XMouseEvent} e - The drag-start event itself to be fired to all installed dragStart listeners.\n * @return {void}\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.fireDragStartEvent = function (e) {\n VertexListeners._fireEvent(this, this.dragStart, e);\n };\n /**\n * Fire a dragEnd event with the given event instance to all\n * installed drag-end listeners.\n *\n * @method fireDragEndEvent\n * @param {VertEvent|XMouseEvent} e - The drag-end event itself to be fired to all installed dragEnd listeners.\n * @return {void}\n * @instance\n * @memberof VertexListeners\n **/\n VertexListeners.prototype.fireDragEndEvent = function (e) {\n VertexListeners._fireEvent(this, this.dragEnd, e);\n };\n /**\n * Removes all listeners from this listeners object.\n */\n VertexListeners.prototype.removeAllListeners = function () {\n this.click = [];\n this.drag = [];\n this.dragStart = [];\n this.dragEnd = [];\n };\n /**\n * @private\n **/\n VertexListeners._fireEvent = function (_self, listeners, e) {\n var ve = e;\n if (typeof ve.params == \"undefined\")\n ve.params = { vertex: _self.vertex };\n else\n ve.params.vertex = _self.vertex;\n for (var i in listeners) {\n listeners[i](ve);\n }\n };\n /**\n * @private\n */\n VertexListeners._addListener = function (listeners, newListener) {\n if (!newListener) {\n throw new Error(\"Cannot add null listener. This would lead to unpredictable errors during event handling.\");\n }\n for (var i in listeners) {\n if (listeners[i] == newListener)\n return false;\n }\n listeners.push(newListener);\n return true;\n };\n /**\n * @private\n */\n VertexListeners._removeListener = function (listeners, oldListener) {\n for (var i = 0; i < listeners.length; i++) {\n if (listeners[i] == oldListener)\n return listeners.splice(i, 1);\n }\n return listeners;\n };\n return VertexListeners;\n}());\nexports.VertexListeners = VertexListeners;\n//# sourceMappingURL=VertexListeners.js.map","\"use strict\";\n/**\n * @classdesc A static UIDGenerator.\n *\n * @author Ikaros Kappler\n * @date 2021-01-20\n * @version 1.0.0\n */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.UIDGenerator = void 0;\nvar UIDGenerator = /** @class */ (function () {\n function UIDGenerator() {\n }\n UIDGenerator.next = function () {\n return \"\".concat(UIDGenerator.current++);\n };\n UIDGenerator.current = 0;\n return UIDGenerator;\n}());\nexports.UIDGenerator = UIDGenerator;\n//# sourceMappingURL=UIDGenerator.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2016-03-12\n * @modified 2018-12-05 Refactored the code from the morley-triangle script.\n * @modified 2019-03-20 Added JSDoc tags.\n * @modified 2019-04-28 Fixed a bug in the Line.sub( Vertex ) function (was not working).\n * @modified 2019-09-02 Added the Line.add( Vertex ) function.\n * @modified 2019-09-02 Added the Line.denominator( Line ) function.\n * @modified 2019-09-02 Added the Line.colinear( Line ) function.\n * @modified 2019-09-02 Fixed an error in the Line.intersection( Line ) function (class Point was renamed to Vertex).\n * @modified 2019-12-15 Added the Line.moveTo(Vertex) function.\n * @modified 2020-03-16 The Line.angle(Line) parameter is now optional. The baseline (x-axis) will be used if not defined.\n * @modified 2020-03-23 Ported to Typescript from JS.\n * @modified 2020-12-04 The `intersection` function returns undefined if both lines are parallel.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-10-09 Changed the actual return value of the `intersection` function to null (was undefined before).\n * @modified 2022-10-17 Adding these methods from the `PathSegment` interface: getStartPoint, getEndPoint, revert.\n * @modified 2023-09-25 Changed param type of `intersection()` from Line to VertTuple.\n * @modified 2025-04-15 Class `Line` now implements interface `Intersectable`.\n * @modified 2025-04-16 Class `Line` now implements interface `IBounded`.\n * @modified 2026-08-16 Adding methods `Line.trimStart` and `Line.trimEnd`. Adding methods `Line.trimStartAt` and `Line.trimEndAt`.\n * @version 2.5.0\n *\n * @file Line\n * @public\n **/\nvar __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Line = void 0;\nvar Bounds_1 = require(\"./Bounds\");\nvar Vector_1 = require(\"./Vector\");\nvar VertTuple_1 = require(\"./VertTuple\");\nvar Vertex_1 = require(\"./Vertex\");\n/**\n * @classdesc A line consists of two vertices a and b.<br>\n * <br>\n * This is some refactored code from my 'Morley Triangle' test<br>\n * https://github.com/IkarosKappler/morleys-trisector-theorem\n *\n * @requires Vertex\n */\nvar Line = /** @class */ (function (_super) {\n __extends(Line, _super);\n /**\n * Creates an instance of Line.\n *\n * @constructor\n * @name Line\n * @param {Vertex} a The line's first point.\n * @param {Vertex} b The line's second point.\n **/\n function Line(a, b) {\n var _this = _super.call(this, a, b, function (a, b) { return new Line(a, b); }) || this;\n /**\n * Required to generate proper CSS classes and other class related IDs.\n **/\n _this.className = \"Line\";\n return _this;\n }\n /**\n * Get the intersection if this line and the specified line.\n *\n * @method intersection\n * @param {Line} line The second line.\n * @return {Vertex|undefined} The intersection (may lie outside the end-points) or `undefined` if both lines are parallel.\n * @instance\n * @memberof Line\n **/\n // !!! DO NOT MOVE TO VertTuple\n Line.prototype.intersection = function (line) {\n var denominator = this.denominator(line);\n if (denominator == 0) {\n return null;\n }\n var a = this.a.y - line.a.y;\n var b = this.a.x - line.a.x;\n var numerator1 = (line.b.x - line.a.x) * a - (line.b.y - line.a.y) * b;\n var numerator2 = (this.b.x - this.a.x) * a - (this.b.y - this.a.y) * b;\n a = numerator1 / denominator; // NaN if parallel lines\n b = numerator2 / denominator;\n // Catch NaN?\n var x = this.a.x + a * (this.b.x - this.a.x);\n var y = this.a.y + a * (this.b.y - this.a.y);\n if (isNaN(a) || isNaN(x) || isNaN(y)) {\n return null;\n }\n // if we cast these lines infinitely in both directions, they intersect here:\n return new Vertex_1.Vertex(x, y);\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Get the bounding box (bounds) of this Line.\n *\n * @method getBounds\n * @instance\n * @memberof Line\n * @return {Bounds} The rectangular bounds of this Line.\n **/\n Line.prototype.getBounds = function () {\n return Bounds_1.Bounds.computeFromVertices([this.a, this.b]);\n };\n //--- END --- Implement interface `IBounded`\n //--- Implement PathSegment ---\n /**\n * Get the start point of this path segment.\n *\n * @method getStartPoint\n * @memberof PathSegment\n * @return {Vertex} The start point of this path segment.\n */\n Line.prototype.getStartPoint = function () {\n return this.a;\n };\n /**\n * Get the end point of this path segment.\n *\n * @method getEndPoint\n * @memberof PathSegment\n * @return {Vertex} The end point of this path segment.\n */\n Line.prototype.getEndPoint = function () {\n return this.b;\n };\n /**\n * Get the tangent's end point at the start point of this segment.\n *\n * @method getStartTangent\n * @memberof PathSegment\n * @return {Vertex} The end point of the starting point's tangent.\n */\n Line.prototype.getStartTangent = function () {\n return this.b;\n };\n /**\n * Get the tangent's end point at the end point of this segment.\n *\n * @method getEndTangent\n * @memberof PathSegment\n * @return {Vertex} The end point of the ending point's tangent.\n */\n Line.prototype.getEndTangent = function () {\n return this.a;\n };\n /**\n * Inverse this path segment (in-place) and return this same instance (useful for chaining).\n *\n * @method reverse\n * @memberof PathSegment\n * @return {PathSegment} This path segment instance (for chaining).\n */\n Line.prototype.reverse = function () {\n var tmp = this.a;\n this.a = this.b;\n this.b = tmp;\n return this;\n };\n //--- END Implement PathSegment ---\n /**\n * Trim this line segment from the start point by the given amount.\n * The amount must be positive and should be withing the segment's length. If the amount exceeds the segment's length\n * then the length of the resulting line will be zero (0.0).\n *\n * @method trimStart\n * @memberof Line\n * @param {number} amount - The positive amount to trim the line from the start point `a`.\n * @returns {Line} This for chaining, with updated point `a`.\n */\n Line.prototype.trimStart = function (amount) {\n // Calculate the relative position `t` on this line.\n var t = amount / this.length();\n // `t` should be inside 0..1 – otherwise the amount was too large or negative.\n if (t < 0.0) {\n return this;\n }\n if (t > 1.0) {\n // Set the line to length zero (endpoint only)\n this.a = this.b.clone();\n return this;\n }\n this.a = this.vertAt(t);\n return this;\n };\n /**\n * Trim this line segment from the start point by the given relative amount.\n * The amount must be positive and should be within 0.0 and 1.0. If the amount exceeds the segment's length\n * then the length of the resulting line will be zero (0.0).\n *\n * @method trimStartAt\n * @memberof Line\n * @param {number} amount - The positive amount to trim the line from the start point `a`.\n * @returns {Line} This for chaining, with updated point `a`.\n */\n Line.prototype.trimStartAt = function (relativeAmount) {\n // Calculate the relative position `t` on this line.\n return this.trimStart(relativeAmount * this.length());\n };\n /**\n * Trim this line segment from the end point by the given amount.\n * The amount must be positive and should be withing the segment's length. If the amount exceeds the segment's length\n * then the length of the resulting line will be zero (0.0).\n *\n * @method trimEnd\n * @memberof Line\n * @param {number} amount - The positive amount to trim the line from the end point `b`.\n * @returns {Line} This for chaining, with updated point `b`.\n */\n Line.prototype.trimEnd = function (amount) {\n // Calculate the relative position `t` on this line.\n var t = 1.0 - amount / this.length();\n // `t` should be inside 0..1 – otherwise the amount was too large or negative.\n if (t < 0.0) {\n return this;\n }\n if (t > 1.0) {\n // Set the line to length zero (endpoint only)\n this.b = this.a.clone();\n return this;\n }\n this.b = this.vertAt(t);\n return this;\n };\n /**\n * Trim this line segment from the end point by the given relative amount.\n * The amount must be positive and should be within 0.0 and 1.0. If the amount exceeds the segment's length\n * then the length of the resulting line will be zero (0.0).\n *\n * @method trimEndAt\n * @memberof Line\n * @param {number} amount - The positive amount to trim the line from the start point `a`.\n * @returns {Line} This for chaining, with updated point `a`.\n */\n Line.prototype.trimEndAt = function (relativeAmount) {\n // Calculate the relative position `t` on this line.\n return this.trimEnd(relativeAmount * this.length());\n };\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get all line intersections with this polygon.\n *\n * This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.\n *\n * See demo `47-closest-vector-projection-on-polygon` for how it works.\n *\n * @param {VertTuple} line - The line to find intersections with.\n * @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).\n * @returns {Array<Vertex>} - An array of all intersections within the polygon bounds.\n */\n Line.prototype.lineIntersections = function (line, inVectorBoundsOnly) {\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersections of all lines inside the edge bounds\n var intersection = this.intersection(line);\n if (!intersection) {\n return []; // Both lines parallel\n }\n if (this.hasPoint(intersection, true) && (!inVectorBoundsOnly || line.hasPoint(intersection, inVectorBoundsOnly))) {\n return [intersection];\n }\n else {\n return [];\n }\n };\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @param line\n * @param inVectorBoundsOnly\n * @returns\n */\n Line.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n // Find the intersection tangents of all lines inside the edge bounds\n var intersections = this.lineIntersections(line, inVectorBoundsOnly);\n if (intersections.length === 0) {\n return [];\n }\n var intrsctn = intersections[0];\n return [new Vector_1.Vector(this.a.clone(), this.b.clone()).moveTo(intrsctn)];\n };\n return Line;\n}(VertTuple_1.VertTuple));\nexports.Line = Line;\n//# sourceMappingURL=Line.js.map","\"use strict\";\n/**\n * @author Ikaros Kappler\n * @date 2013-08-15\n * @modified 2018-08-16 Added a closure. Removed the wrapper class 'IKRS'. Replaced class THREE.Vector2 by Vertex class.\n * @modified 2018-11-19 Added the fromArray(Array) function.\n * @modified 2018-11-28 Added the locateCurveByPoint(Vertex) function.\n * @modified 2018-12-04 Added the toSVGPathData() function.\n * @modified 2019-03-20 Added JSDoc tags.\n * @modified 2019-03-23 Changed the signatures of getPoint, getPointAt and getTangent (!version 2.0).\n * @modified 2019-12-02 Fixed the updateArcLength function. It used the wrong pointAt function (was renamed before).\n * @modified 2020-02-06 Added the getSubCurveAt(number,number) function.\n * @modified 2020-02-06 Fixed a serious bug in the arc lenght calculation (length was never reset, urgh).\n * @modified 2020-02-07 Added the isInstance(any) function.\n * @modified 2020-02-10 Added the reverse() function.\n * @modified 2020-02-10 Fixed the translate(...) function (returning 'this' was missing).\n * @modified 2020-03-24 Ported this class from vanilla JS to Typescript.\n * @modified 2020-06-03 Added the getBounds() function.\n * @modified 2020-07-14 Changed the moveCurvePoint(...,Vertex) to moveCurvePoint(...,XYCoords), which is more generic.\n * @modified 2020-07-24 Added the getClosestT function and the helper function locateIntervalByDistance(...).\n * @modified 2021-01-20 Added UID.\n * @modified 2022-02-02 Added the `destroy` method.\n * @modified 2022-02-02 Cleared the `toSVGPathData` function (deprecated). Use `drawutilssvg` instead.\n * @modified 2022-10-17 The `CubicBezierCurve` class now implements the new `PathSegment` interface.\n * @modified 2023-09-30 Added the function `CubicbezierCurve.getSubCurve(number,number)` – similar to `getSubCurveAt(...)` but with absolute position parameters.\n * @modified 2023-10-07 Added the `trimEnd`, `trimEndAt`, `trimStart`, `trimStartAt` methods.\n * @modified 2025-04-09 Added the `CubicBezierCurve.move` method to match the convention – which just calls `translate`.\n * @modified 2025-04-09 Modified the `CubicBezierCurve.translate` method: chaning parameter `Vertex` to more generalized `XYCoords`.\n * @modified 2025-04-13 Changed visibility of `CubicBezierCurve.utils` from 'private' to 'public'.\n * @modified 2025-04-13 Added helper function `CubicBezierCurve.utils.bezierCoeffs`.\n * @modified 2025-04-13 Added helper functopn `CubicBezierCurve.utils.sgn(number)` for division safe sign calculation.\n * @modified 2025-03-13 Class `CubicBezierCurve` is now implementing interface `Intersectable`.\n * @modified 2025-04-18 Added evaluation method for cubic Bézier curves `CubicBezierCurve.utils.evaluateT`.\n * @modified 2025-04-18 Refactored method `CubicBezierCurve.getPointAt` to use `evaluateT`.\n * @modified 2025-04-18 Fixed the `CubicBezierCurve.getBounds` method: now returning the real bounding box. Before it was an approximated one.\n * @modified 2025-04-18 Added helper methods for bounding box calculation `CubucBezierCurve.util.cubicPolyMinMax` and `cubicPoly`.\n * @modified 2026-09-09 Adding methods `CubicBezierCurve.trimStartEnd` and `CubicBezierCurve.trimStartEndAt`.\n * @version 2.10.0\n *\n * @file CubicBezierCurve\n * @public\n **/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.CubicBezierCurve = void 0;\nvar Bounds_1 = require(\"./Bounds\");\nvar UIDGenerator_1 = require(\"./UIDGenerator\");\nvar Vertex_1 = require(\"./Vertex\");\nvar Vector_1 = require(\"./Vector\");\n/**\n * @classdesc A refactored cubic bezier curve class.\n *\n * @requires Bounds\n * @requires Vertex\n * @requires Vector\n * @requires XYCoords\n * @requires UID\n * @requires UIDGenerator\n */\nvar CubicBezierCurve = /** @class */ (function () {\n /**\n * The constructor.\n *\n * @constructor\n * @name CubicBezierCurve\n * @param {Vertex} startPoint - The Bézier curve's start point.\n * @param {Vertex} endPoint - The Bézier curve's end point.\n * @param {Vertex} startControlPoint - The Bézier curve's start control point.\n * @param {Vertex} endControlPoint - The Bézier curve's end control point.\n **/\n function CubicBezierCurve(startPoint, endPoint, startControlPoint, endControlPoint) {\n /** @constant {number} */\n this.START_POINT = CubicBezierCurve.START_POINT;\n /** @constant {number} */\n this.START_CONTROL_POINT = CubicBezierCurve.START_CONTROL_POINT;\n /** @constant {number} */\n this.END_CONTROL_POINT = CubicBezierCurve.END_CONTROL_POINT;\n /** @constant {number} */\n this.END_POINT = CubicBezierCurve.END_POINT;\n this.uid = UIDGenerator_1.UIDGenerator.next();\n this.startPoint = startPoint;\n this.startControlPoint = startControlPoint;\n this.endPoint = endPoint;\n this.endControlPoint = endControlPoint;\n this.curveIntervals = 30;\n // An array of vertices\n this.segmentCache = [];\n // An array of floats\n this.segmentLengths = [];\n // float\n // this.arcLength = null;\n this.updateArcLengths();\n }\n /**\n * Move the given curve point (the start point, end point or one of the two\n * control points).\n *\n * @method moveCurvePoint\n * @param {number} pointID - The numeric identicator of the point to move. Use one of the four eBezierPoint constants.\n * @param {XYCoords} moveAmount - The amount to move the specified point by.\n * @param {boolean} moveControlPoint - Move the control points along with their path point (if specified point is a path point).\n * @param {boolean} updateArcLengths - Specifiy if the internal arc segment buffer should be updated.\n * @instance\n * @memberof CubicBezierCurve\n * @return {void}\n **/\n CubicBezierCurve.prototype.moveCurvePoint = function (pointID, moveAmount, moveControlPoint, updateArcLengths) {\n if (pointID == this.START_POINT) {\n this.getStartPoint().add(moveAmount);\n if (moveControlPoint)\n this.getStartControlPoint().add(moveAmount);\n }\n else if (pointID == this.START_CONTROL_POINT) {\n this.getStartControlPoint().add(moveAmount);\n }\n else if (pointID == this.END_CONTROL_POINT) {\n this.getEndControlPoint().add(moveAmount);\n }\n else if (pointID == this.END_POINT) {\n this.getEndPoint().add(moveAmount);\n if (moveControlPoint)\n this.getEndControlPoint().add(moveAmount);\n }\n else {\n console.log(\"[CubicBezierCurve.moveCurvePoint] pointID '\".concat(pointID, \"' invalid.\"));\n }\n if (updateArcLengths)\n this.updateArcLengths();\n };\n /**\n * Translate the whole curve by the given {x,y} amount: moves all four points.\n *\n * @method translate\n * @param {XYCoords} amount - The amount to translate this curve by.\n * @instance\n * @memberof CubicBezierCurve\n * @return {CubicBezierCurve} this (for chaining).\n **/\n CubicBezierCurve.prototype.translate = function (amount) {\n this.startPoint.add(amount);\n this.startControlPoint.add(amount);\n this.endControlPoint.add(amount);\n this.endPoint.add(amount);\n return this;\n };\n /**\n * Translate the whole curve by the given {x,y} amount: moves all four points.\n *\n * @method translate\n * @param {XYCoords} amount - The amount to translate this curve by.\n * @instance\n * @memberof CubicBezierCurve\n * @return {CubicBezierCurve} this (for chaining).\n **/\n CubicBezierCurve.prototype.move = function (amount) {\n return this.translate(amount);\n };\n /**\n * Reverse this curve, means swapping start- and end-point and swapping\n * start-control- and end-control-point.\n *\n * @method reverse\n * @instance\n * @memberof CubicBezierCurve\n * @return {CubicBezierCurve} this (for chaining).\n **/\n CubicBezierCurve.prototype.reverse = function () {\n var tmp = this.startPoint;\n this.startPoint = this.endPoint;\n this.endPoint = tmp;\n tmp = this.startControlPoint;\n this.startControlPoint = this.endControlPoint;\n this.endControlPoint = tmp;\n return this;\n };\n /**\n * Get the total curve length.<br>\n * <br>\n * As not all Bézier curved have a closed formula to calculate their lengths, this\n * implementation uses a segment buffer (with a length of 30 segments). So the\n * returned length is taken from the arc segment buffer.<br>\n * <br>\n * Note that if the curve points were changed and the segment buffer was not\n * updated this function might return wrong (old) values.\n *\n * @method getLength\n * @instance\n * @memberof CubicBezierCurve\n * @return {number} >= 0\n **/\n CubicBezierCurve.prototype.getLength = function () {\n return this.arcLength;\n };\n /**\n * Uptate the internal arc segment buffer and their lengths.<br>\n * <br>\n * All class functions update the buffer automatically; if any\n * curve point is changed by other reasons you should call this\n * function to keep actual values in the buffer.\n *\n * @method updateArcLengths\n * @instance\n * @memberof CubicBezierCurve\n * @return {void}\n **/\n CubicBezierCurve.prototype.updateArcLengths = function () {\n var pointA = this.startPoint.clone();\n var pointB = new Vertex_1.Vertex(0, 0);\n var curveStep = 1.0 / this.curveIntervals;\n // Clear segment cache\n this.segmentCache = [];\n // Push start point into buffer\n this.segmentCache.push(this.startPoint);\n this.segmentLengths = [];\n var newLength = 0.0;\n var t = 0.0;\n var tmpLength;\n while (t <= 1.0) {\n pointB = this.getPointAt(t);\n // Store point into cache\n this.segmentCache.push(pointB);\n // Calculate segment length\n tmpLength = pointA.distance(pointB);\n this.segmentLengths.push(tmpLength);\n newLength += tmpLength;\n pointA = pointB;\n t += curveStep;\n }\n this.arcLength = newLength;\n };\n /**\n * Get a 't' (relative position on curve) with the closest distance to point 'p'.\n *\n * The returned number is 0.0 <= t <= 1.0. Use the getPointAt(t) function to retrieve the actual curve point.\n *\n * This function uses a recursive approach by cutting the curve into several linear segments.\n *\n * @method getClosestT\n * @instance\n * @memberof CubicBezierCurve\n * @param {Vertex} p - The point to find the closest position ('t' on the curve).\n * @return {number}\n **/\n CubicBezierCurve.prototype.getClosestT = function (p) {\n // We would like to have an error that's not larger than 1.0.\n var desiredEpsilon = 1.0;\n var result = { t: 0, tPrev: 0.0, tNext: 1.0 };\n var iteration = 0;\n do {\n result = this.locateIntervalByDistance(p, result.tPrev, result.tNext, this.curveIntervals);\n iteration++;\n // Be sure: stop after 4 iterations\n } while (iteration < 4 && this.getPointAt(result.tPrev).distance(this.getPointAt(result.tNext)) > desiredEpsilon);\n return result.t;\n };\n /**\n * This helper function locates the 't' on a fixed step interval with the minimal distance\n * between the curve (at 't') and the given point.\n *\n * Furthermore you must specify a sub curve (start 't' and end 't') you want to search on.\n * Using tStart=0.0 and tEnd=1.0 will search on the full curve.\n *\n * @param {Vertex} p - The point to find the closest curve point for.\n * @param {number} tStart - The start position (start 't' of the sub curve). Should be >= 0.0.\n * @param {number} tEnd - The end position (end 't' of the sub curve). Should be <= 1.0.\n * @param {number} stepCount - The number of steps to check within the interval.\n *\n * @return {object} - An object with t, tPrev and tNext (numbers).\n **/\n CubicBezierCurve.prototype.locateIntervalByDistance = function (p, tStart, tEnd, stepCount) {\n var minIndex = -1;\n var minDist = 0;\n var t = 0.0;\n var tDiff = tEnd - tStart;\n for (var i = 0; i <= stepCount; i++) {\n t = tStart + tDiff * (i / stepCount);\n var vert = this.getPointAt(t);\n var dist = vert.distance(p);\n if (minIndex == -1 || dist < minDist) {\n minIndex = i;\n minDist = dist;\n }\n }\n return {\n t: tStart + tDiff * (minIndex / stepCount),\n tPrev: tStart + tDiff * (Math.max(0, minIndex - 1) / stepCount),\n tNext: tStart + tDiff * (Math.min(stepCount, minIndex + 1) / stepCount)\n };\n };\n //--- BEGIN --- Implement interface `IBounded`\n /**\n * Get the bounds of this bezier curve.\n *\n * The bounds are approximated by the underlying segment buffer; the more segment there are,\n * the more accurate will be the returned bounds.\n *\n * @method getClosestT\n * @instance\n * @memberof CubicBezierCurve\n * @return {Bounds} The bounds of this ellipse.\n **/\n CubicBezierCurve.prototype.getBounds = function () {\n // Thanks to Richard \"RM\" for the Bézier bounds calculatin\n // https://jsfiddle.net/SalixAlba/QQnvm/4/\n var xMinMax = CubicBezierCurve.utils.cubicPolyMinMax(this.startPoint.x, this.startControlPoint.x, this.endControlPoint.x, this.endPoint.x);\n var xl = xMinMax.min;\n var xh = xMinMax.max;\n var yMinMax = CubicBezierCurve.utils.cubicPolyMinMax(this.startPoint.y, this.startControlPoint.y, this.endControlPoint.y, this.endPoint.y);\n var yl = yMinMax.min;\n var yh = yMinMax.max;\n return Bounds_1.Bounds.computeFromVertices([\n { x: xl, y: yl },\n { x: xl, y: yh },\n { x: xh, y: yh },\n { x: xh, y: yl }\n ]);\n };\n //--- END --- Implement interface `IBounded`\n /**\n * Get the start point of the curve.<br>\n * <br>\n * This function just returns this.startPoint.\n *\n * @method getStartPoint\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex} this.startPoint\n **/\n CubicBezierCurve.prototype.getStartPoint = function () {\n return this.startPoint;\n };\n /**\n * Get the end point of the curve.<br>\n * <br>\n * This function just returns this.endPoint.\n *\n * @method getEndPoint\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex} this.endPoint\n **/\n CubicBezierCurve.prototype.getEndPoint = function () {\n return this.endPoint;\n };\n /**\n * Get the start control point of the curve.<br>\n * <br>\n * This function just returns this.startControlPoint.\n *\n * @method getStartControlPoint\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex} this.startControlPoint\n **/\n CubicBezierCurve.prototype.getStartControlPoint = function () {\n return this.startControlPoint;\n };\n /**\n * Get the end control point of the curve.<br>\n * <br>\n * This function just returns this.endControlPoint.\n *\n * @method getEndControlPoint\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex} this.endControlPoint\n **/\n CubicBezierCurve.prototype.getEndControlPoint = function () {\n return this.endControlPoint;\n };\n /**\n * Get one of the four curve points specified by the passt point ID.\n *\n * @method getEndControlPoint\n * @param {number} id - One of START_POINT, START_CONTROL_POINT, END_CONTROL_POINT or END_POINT.\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex}\n **/\n CubicBezierCurve.prototype.getPointByID = function (id) {\n if (id == this.START_POINT)\n return this.startPoint;\n if (id == this.END_POINT)\n return this.endPoint;\n if (id == this.START_CONTROL_POINT)\n return this.startControlPoint;\n if (id == this.END_CONTROL_POINT)\n return this.endControlPoint;\n throw new Error(\"Invalid point ID '\".concat(id, \"'.\"));\n };\n /**\n * Get the curve point at a given position t, where t is in [0,1].<br>\n * <br>\n * @see Line.pointAt\n *\n * @method getPointAt\n * @param {number} t - The position on the curve in [0,1] (0 means at\n * start point, 1 means at end point, other values address points in bertween).\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex}\n **/\n CubicBezierCurve.prototype.getPointAt = function (t) {\n // Perform some powerful math magic\n // TODO: cleanup\n // const x: number =\n // this.startPoint.x * Math.pow(1.0 - t, 3) +\n // this.startControlPoint.x * 3 * t * Math.pow(1.0 - t, 2) +\n // this.endControlPoint.x * 3 * Math.pow(t, 2) * (1.0 - t) +\n // this.endPoint.x * Math.pow(t, 3);\n // const y: number =\n // this.startPoint.y * Math.pow(1.0 - t, 3) +\n // this.startControlPoint.y * 3 * t * Math.pow(1.0 - t, 2) +\n // this.endControlPoint.y * 3 * Math.pow(t, 2) * (1.0 - t) +\n // this.endPoint.y * Math.pow(t, 3);\n var x = CubicBezierCurve.utils.evaluateT(this.startPoint.x, this.startControlPoint.x, this.endControlPoint.x, this.endPoint.x, t);\n var y = CubicBezierCurve.utils.evaluateT(this.startPoint.y, this.startControlPoint.y, this.endControlPoint.y, this.endPoint.y, t);\n return new Vertex_1.Vertex(x, y);\n };\n /**\n * Get the curve point at a given position u, where u is in [0,arcLength].<br>\n * <br>\n * @see CubicBezierCurve.getPointAt\n *\n * @method getPoint\n * @param {number} u - The position on the curve in [0,arcLength] (0 means at\n * start point, arcLength means at end point, other values address points in bertween).\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex}\n **/\n CubicBezierCurve.prototype.getPoint = function (u) {\n return this.getPointAt(u / this.arcLength);\n };\n /**\n * Get the curve tangent vector at a given absolute curve position t in [0,1].<br>\n * <br>\n * Note that the returned tangent vector (end point) is not normalized and relative to (0,0).\n *\n * @method getTangent\n * @param {number} t - The position on the curve in [0,1].\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex}\n **/\n CubicBezierCurve.prototype.getTangentAt = function (t) {\n var a = this.getStartPoint();\n var b = this.getStartControlPoint();\n var c = this.getEndControlPoint();\n var d = this.getEndPoint();\n // This is the shortened one\n var t2 = t * t;\n // (1 - t)^2 = (1-t)*(1-t) = 1 - t - t + t^2 = 1 - 2*t + t^2\n var nt2 = 1 - 2 * t + t2;\n var tX = -3 * a.x * nt2 + b.x * (3 * nt2 - 6 * (t - t2)) + c.x * (6 * (t - t2) - 3 * t2) + 3 * d.x * t2;\n var tY = -3 * a.y * nt2 + b.y * (3 * nt2 - 6 * (t - t2)) + c.y * (6 * (t - t2) - 3 * t2) + 3 * d.y * t2;\n // Note: my implementation does NOT normalize tangent vectors!\n return new Vertex_1.Vertex(tX, tY);\n };\n /**\n * Trim off a start section of this curve. The position parameter `uValue` is the absolute position on the\n * curve in `[0...arcLength]`.\n * The remaining curve will be the one in the bounds `[uValue,1]` (so `[0.0,uValue]` is cut off).\n *\n * Note this function just converts the absolute parameter to a relative one and call `trimStartAt`.\n *\n * @method trimStart\n * @instance\n * @memberof CubicBezierCurve\n * @param {number} uValue - The absolute position parameter where to cut off the head curve.\n * @returns {CubicBezierCurve} `this` for chanining.\n */\n CubicBezierCurve.prototype.trimStart = function (uValue) {\n return this.trimStartAt(this.convertU2T(uValue));\n };\n /**\n * Trim off a start section of this curve. The position parameter `t` is the relative position in [0..1].\n * The remaining curve will be the one in the bounds `[uValue,1]` (so `[0.0,uValue]` is cut off).\n *\n * @method trimStartAt\n * @instance\n * @memberof CubicBezierCurve\n * @param {number} t - The relative position parameter where to cut off the head curve.\n * @returns {CubicBezierCurve} `this` for chanining.\n */\n CubicBezierCurve.prototype.trimStartAt = function (t) {\n var subCurbePoints = CubicBezierCurve.utils.getSubCurvePointsAt(this, t, 1.0);\n this.startPoint.set(subCurbePoints[0]);\n this.startControlPoint.set(subCurbePoints[2]);\n this.endPoint.set(subCurbePoints[1]);\n this.endControlPoint.set(subCurbePoints[3]);\n this.updateArcLengths();\n return this;\n // return this.trimStartEndAt(t, null);\n };\n /**\n * Trim off the end of this curve. The position parameter `uValue` is the absolute position on the\n * curve in `[0...arcLength]`.\n * The remaining curve will be the one in the bounds `[0,uValue]` (so `[1.0-uValue,1.0]` is cut off).\n *\n * Note this function just converts the absolute parameter to a relative one and call `trimEndAt`.\n *\n * @method trimEnd\n * @instance\n * @memberof CubicBezierCurve\n * @param {number} uValue - The absolute position parameter where to cut off the tail curve.\n * @returns {CubicBezierCurve} `this` for chanining.\n */\n CubicBezierCurve.prototype.trimEnd = function (uValue) {\n return this.trimEndAt(this.convertU2T(uValue));\n };\n /**\n * Trim off the end of this curve. The position parameter `t` is the relative position in [0..1].\n * The remaining curve will be the one in the bounds `[0,t]` (so `[1.0-t,1.0]` is cut off).\n *\n * @method trimEndAt\n * @instance\n * @memberof CubicBezierCurve\n * @param {number} t - The relative position parameter where to cut off the tail curve.\n * @returns {CubicBezierCurve} `this` for chanining.\n */\n CubicBezierCurve.prototype.trimEndAt = function (t) {\n var subCurbePoints = CubicBezierCurve.utils.getSubCurvePointsAt(this, 0.0, t);\n this.startPoint.set(subCurbePoints[0]);\n this.startControlPoint.set(subCurbePoints[2]);\n this.endPoint.set(subCurbePoints[1]);\n this.endControlPoint.set(subCurbePoints[3]);\n this.updateArcLengths();\n return this;\n // return this.trimStartEndAt(null, t);\n };\n /**\n * Trim off a start and end section of this curve. The position parameters `uStart` and `uEnd` are the absolute positions in [0..arcLength].\n * The remaining curve will be the one in the bounds `[uStart,uEnd]` (so `[0.0,uStart]` and `[uEnd,1.0]` are cut off).\n *\n * Parameters out of bounds (< 0.0 or > arcLength) are ignored.\n * If `uEnd` is smaller than `uStart` then a curve with length zero (0) at `uStart` is returned.\n *\n * @method trimStartEndAt\n * @instance\n * @memberof CubicBezierCurve\n * @param {number} tStart - The relative position parameter where to cut off the head curve.\n * @param {number} tEnd - The relative position parameter where to cut off the tail curve.\n * @returns {CubicBezierCurve} `this` for chanining.\n */\n CubicBezierCurve.prototype.trimStartEnd = function (uStart, uEnd) {\n return this.trimStartEndAt(this.convertU2T(uStart), this.convertU2T(uEnd));\n };\n /**\n * Trim off a start and end section of this curve. The position parameters `tStart` and `tEnd` are the relative positions in [0..1].\n * The remaining curve will be the one in the bounds `[tStart,tEnd]` (so `[0.0,tStart]` and `[tEnd,1.0]` are cut off).\n *\n * Parameters out of bounds (< 0.0 or > 1.0) are ignored.\n * If `tEnd` is smaller than `tStart` then a curve with length zero (0) at `tStart` is returned.\n *\n * @method trimStartEndAt\n * @instance\n * @memberof CubicBezierCurve\n * @param {number} tStart - The relative position parameter where to cut off the head curve.\n * @param {number} tEnd - The relative position parameter where to cut off the tail curve.\n * @returns {CubicBezierCurve} `this` for chanining.\n */\n CubicBezierCurve.prototype.trimStartEndAt = function (tStart, tEnd) {\n var cleanTrimStart = Math.min(Math.max(0.0, tStart), 1.0);\n var cleanTrimEnd = Math.min(Math.max(cleanTrimStart, tEnd), 1.0);\n this.trimStartAt(cleanTrimStart);\n var relativeTrimEnd = (cleanTrimEnd - cleanTrimStart) / (1.0 - cleanTrimStart);\n this.trimEndAt(relativeTrimEnd);\n return this;\n };\n // __trimStartEndAt(tStart: number, tEnd: number): CubicBezierCurve {\n // var finalCurvePoints = [\n // this.startPoint.clone(),\n // this.endPoint.clone(),\n // this.startControlPoint.clone(),\n // this.endControlPoint.clone()\n // ];\n // if (typeof tStart === \"number\" && !Number.isNaN(tStart)) {\n // const subCurvePointsStart = CubicBezierCurve.utils.getSubCurvePointsAt(this, tStart, 1.0);\n // finalCurvePoints[0].set(subCurvePointsStart[0]);\n // finalCurvePoints[2].set(subCurvePointsStart[2]);\n // // this.startPoint.set(subCurvePointsStart[0]);\n // // this.startControlPoint.set(subCurvePointsStart[2]);\n // // this.endPoint.set(subCurvePointsStart[1]);\n // // this.endControlPoint.set(subCurvePointsStart[3]);\n // }\n // if (typeof tEnd === \"number\" && !Number.isNaN(tEnd)) {\n // const subCurvePointsEnd = CubicBezierCurve.utils.getSubCurvePointsAt(this, 0.0, tEnd);\n // // this.startPoint.set(subCurvePointsEnd[0]);\n // // this.startControlPoint.set(subCurvePointsEnd[2]);\n // // this.endPoint.set(subCurvePointsEnd[1]);\n // // this.endControlPoint.set(subCurvePointsEnd[3]);\n // finalCurvePoints[1].set(subCurvePointsEnd[1]);\n // finalCurvePoints[3].set(subCurvePointsEnd[3]);\n // }\n // this.startPoint.set(finalCurvePoints[0]);\n // this.endPoint.set(finalCurvePoints[1]);\n // this.startControlPoint.set(finalCurvePoints[2]);\n // this.endControlPoint.set(finalCurvePoints[3]);\n // this.updateArcLengths();\n // return this;\n // }\n /**\n * Get a sub curve at the given start end end positions (values on the curve's length, between 0 and curve.arcLength).\n *\n * tStart >= tEnd is allowed, you will get a reversed sub curve then.\n *\n * @method getSubCurve\n * @param {number} tStart – The start position of the desired sub curve (must be in [0..arcLength]).\n * @param {number} tEnd – The end position if the desired cub curve (must be in [0..arcLength]).\n * @instance\n * @memberof CubicBezierCurve\n * @return {CubicBezierCurve} The sub curve as a new curve.\n **/\n CubicBezierCurve.prototype.getSubCurve = function (uStart, uEnd) {\n return this.getSubCurveAt(this.convertU2T(uStart), this.convertU2T(uEnd));\n };\n /**\n * Get a sub curve at the given start end end offsets (values between 0.0 and 1.0).\n *\n * tStart >= tEnd is allowed, you will get a reversed sub curve then.\n *\n * @method getSubCurveAt\n * @param {number} tStart – The start offset of the desired sub curve (must be in [0..1]).\n * @param {number} tEnd – The end offset if the desired cub curve (must be in [0..1]).\n * @instance\n * @memberof CubicBezierCurve\n * @return {CubicBezierCurve} The sub curve as a new curve.\n **/\n CubicBezierCurve.prototype.getSubCurveAt = function (tStart, tEnd) {\n // This 'splits' the curve at the given point at t.\n var subCurbePoints = CubicBezierCurve.utils.getSubCurvePointsAt(this, tStart, tEnd);\n return new CubicBezierCurve(subCurbePoints[0], subCurbePoints[1], subCurbePoints[2], subCurbePoints[3]);\n };\n /**\n * Convert a relative curve position u to the absolute curve position t.\n *\n * @method convertU2t\n * @param {number} u - The relative position on the curve in [0,arcLength].\n * @instance\n * @memberof CubicBezierCurve\n * @return {number}\n **/\n CubicBezierCurve.prototype.convertU2T = function (u) {\n return Math.max(0.0, Math.min(1.0, u / this.arcLength));\n };\n /**\n * Get the curve tangent vector at a given relative position u in [0,arcLength].<br>\n * <br>\n * Note that the returned tangent vector (end point) is not normalized.\n *\n * @method getTangent\n * @param {number} u - The position on the curve in [0,arcLength].\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex}\n **/\n CubicBezierCurve.prototype.getTangent = function (u) {\n return this.getTangentAt(this.convertU2T(u));\n };\n /**\n * Get the curve perpendicular at a given relative position u in [0,arcLength] as a vector.<br>\n * <br>\n * Note that the returned vector (end point) is not normalized.\n *\n * @method getPerpendicular\n * @param {number} u - The relative position on the curve in [0,arcLength].\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex}\n **/\n CubicBezierCurve.prototype.getPerpendicular = function (u) {\n return this.getPerpendicularAt(this.convertU2T(u));\n };\n /**\n * Get the curve perpendicular at a given absolute position t in [0,1] as a vector.<br>\n * <br>\n * Note that the returned vector (end point) is not normalized.\n *\n * @method getPerpendicularAt\n * @param {number} u - The absolute position on the curve in [0,1].\n * @instance\n * @memberof CubicBezierCurve\n * @return {Vertex}\n **/\n CubicBezierCurve.prototype.getPerpendicularAt = function (t) {\n var tangentVector = this.getTangentAt(t);\n return new Vertex_1.Vertex(tangentVector.y, -tangentVector.x);\n };\n /**\n * Clone this Bézier curve (deep clone).\n *\n * @method clone\n * @instance\n * @memberof CubicBezierCurve\n * @return {CubicBezierCurve}\n **/\n CubicBezierCurve.prototype.clone = function () {\n return new CubicBezierCurve(this.getStartPoint().clone(), this.getEndPoint().clone(), this.getStartControlPoint().clone(), this.getEndControlPoint().clone());\n };\n //---BEGIN PathSegment-------------------------\n /**\n * Get the tangent's end point at the start point of this segment.\n *\n * @method getStartTangent\n * @memberof PathSegment\n * @return {Vertex} The end point of the starting point's tangent.\n */\n CubicBezierCurve.prototype.getStartTangent = function () {\n return this.startControlPoint;\n };\n /**\n * Get the tangent's end point at the end point of this segment.\n *\n * @method getEndTangent\n * @memberof PathSegment\n * @return {Vertex} The end point of the ending point's tangent.\n */\n CubicBezierCurve.prototype.getEndTangent = function () {\n return this.endControlPoint;\n };\n //---END PathSegment-------------------------\n //--- BEGIN --- Implement interface `Intersectable`\n /**\n * Get all line intersections with this shape.\n *\n * This method returns all intersections (as vertices) with this shape. The returned array of vertices is in no specific order.\n *\n * @param {VertTuple} line - The line to find intersections with.\n * @param {boolean} inVectorBoundsOnly - If set to true only intersecion points on the passed vector are returned (located strictly between start and end vertex).\n * @returns {Array<Vertex>} - An array of all intersections with the shape outline.\n */\n CubicBezierCurve.prototype.lineIntersections = function (line, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n var intersectionTs = this.lineIntersectionTs(line);\n var intersectionPoints = intersectionTs.map(function (t) {\n return _this.getPointAt(t);\n });\n if (inVectorBoundsOnly) {\n // const maxDist = line.length();\n return intersectionPoints.filter(function (vert) { return line.hasPoint(vert, true); });\n }\n else {\n return intersectionPoints;\n }\n };\n /**\n * Get all line intersections of this polygon and their tangents along the shape.\n *\n * This method returns all intersection tangents (as vectors) with this shape. The returned array of vectors is in no specific order.\n *\n * @param line\n * @param lineIntersectionTangents\n * @returns\n */\n CubicBezierCurve.prototype.lineIntersectionTangents = function (line, inVectorBoundsOnly) {\n var _this = this;\n if (inVectorBoundsOnly === void 0) { inVectorBoundsOnly = false; }\n var intersectionTs = this.lineIntersectionTs(line);\n var intersectionTangents = intersectionTs.map(function (t) {\n var startPoint = _this.getPointAt(t);\n var endPoint = _this.getTangentAt(t);\n return new Vector_1.Vector(startPoint, endPoint.add(startPoint));\n });\n if (inVectorBoundsOnly) {\n return intersectionTangents.filter(function (vec) { return line.hasPoint(vec.a, true); });\n }\n else {\n return intersectionTangents;\n }\n };\n //--- END --- Implement interface `Intersectable`\n CubicBezierCurve.prototype.lineIntersectionTs = function (line) {\n var A = line.b.y - line.a.y; // A=y2-y1\n var B = line.a.x - line.b.x; // B=x1-x2\n var C = line.a.x * (line.a.y - line.b.y) + line.a.y * (line.b.x - line.a.x); //C=x1*(y1-y2)+y1*(x2-x1)\n // var bx = bezierCoeffs(px[0], px[1], px[2], px[3]);\n // var by = bezierCoeffs(py[0], py[1], py[2], py[3]);\n var bx = CubicBezierCurve.utils.bezierCoeffs(this.startPoint.x, this.startControlPoint.x, this.endControlPoint.x, this.endPoint.x);\n var by = CubicBezierCurve.utils.bezierCoeffs(this.startPoint.y, this.startControlPoint.y, this.endControlPoint.y, this.endPoint.y);\n var poly = Array(4);\n poly[0] = A * bx[0] + B * by[0]; /*t^3*/\n poly[1] = A * bx[1] + B * by[1]; /*t^2*/\n poly[2] = A * bx[2] + B * by[2]; /*t*/\n poly[3] = A * bx[3] + B * by[3] + C; /*1*/\n var roots = CubicBezierCurve.utils.cubicRoots(poly);\n return roots.filter(function (root) { return root != -1; });\n };\n /**\n * Check if this and the specified curve are equal.<br>\n * <br>\n * All four points need to be equal for this, the Vertex.equals function is used.<br>\n * <br>\n * Please note that this function is not type safe (comparison with any object will fail).\n *\n * @method clone\n * @param {CubicBezierCurve} curve - The curve to compare with.\n * @instance\n * @memberof CubicBezierCurve\n * @return {boolean}\n **/\n CubicBezierCurve.prototype.equals = function (curve) {\n // Note: in the earlier vanilla-JS version this was callable with plain objects.\n // Let's see if this restricted version works out.\n if (!curve)\n return false;\n if (!curve.startPoint || !curve.endPoint || !curve.startControlPoint || !curve.endControlPoint)\n return false;\n return (this.startPoint.equals(curve.startPoint) &&\n this.endPoint.equals(curve.endPoint) &&\n this.startControlPoint.equals(curve.startControlPoint) &&\n this.endControlPoint.equals(curve.endControlPoint));\n };\n /**\n * This function should invalidate any installed listeners and invalidate this object.\n * After calling this function the object might not hold valid data any more and\n * should not be used.\n */\n CubicBezierCurve.prototype.destroy = function () {\n this.startPoint.destroy();\n this.endPoint.destroy();\n this.startControlPoint.destroy();\n this.endControlPoint.destroy();\n this.isDestroyed = true;\n };\n /**\n * Quick check for class instance.\n * Is there a better way?\n *\n * @method isInstance\n * @param {any} obj - Check if the passed object/value is an instance of CubicBezierCurve.\n * @instance\n * @memberof CubicBezierCurve\n * @return {boolean}\n **/\n CubicBezierCurve.isInstance = function (obj) {\n // Note: check this again\n /* OLD VANILLA JS IMPLEMENTATION */\n /* if( typeof obj != \"object\" )\n return false;\n function hasXY(v) {\n return typeof v != \"undefined\" && typeof v.x == \"number\" && typeof v.y == \"number\";\n }\n return typeof obj.startPoint == \"object\" && hasXY(obj.startPoint)\n && typeof obj.endPoint == \"object\" && hasXY(obj.endPoint)\n && typeof obj.startControlPoint == \"object\" && hasXY(obj.startControlPoint)\n && typeof obj.endControlPoint == \"object\" && hasXY(obj.endControlPoint);\n */\n return obj instanceof CubicBezierCurve;\n };\n /**\n * Convert this curve to a JSON string.\n *\n * @method toJSON\n * @param {boolean=} [prettyFormat=false] - If set to true the function will add line breaks.\n * @instance\n * @memberof CubicBezierCurve\n * @return {string} The JSON data.\n **/\n CubicBezierCurve.prototype.toJSON = function (prettyFormat) {\n var jsonString = \"{ \" + // begin object\n (prettyFormat ? \"\\n\\t\" : \"\") +\n '\"startPoint\" : [' +\n this.getStartPoint().x +\n \",\" +\n this.getStartPoint().y +\n \"], \" +\n (prettyFormat ? \"\\n\\t\" : \"\") +\n '\"endPoint\" : [' +\n this.getEndPoint().x +\n \",\" +\n this.getEndPoint().y +\n \"], \" +\n (prettyFormat ? \"\\n\\t\" : \"\") +\n '\"startControlPoint\": [' +\n this.getStartControlPoint().x +\n \",\" +\n this.getStartControlPoint().y +\n \"], \" +\n (prettyFormat ? \"\\n\\t\" : \"\") +\n '\"endControlPoint\" : [' +\n this.getEndControlPoint().x +\n \",\" +\n this.getEndControlPoint().y +\n \"]\" +\n (prettyFormat ? \"\\n\\t\" : \"\") +\n \" }\"; // end object\n return jsonString;\n };\n /**\n * Parse a Bézier curve from the given JSON string.\n *\n * @method fromJSON\n * @param {string} jsonString - The JSON data to parse.\n * @memberof CubicBezierCurve\n * @static\n * @throws An exception if the JSON string is malformed.\n * @return {CubicBezierCurve}\n **/\n CubicBezierCurve.fromJSON = function (jsonString) {\n var obj = JSON.parse(jsonString);\n return CubicBezierCurve.fromObject(obj);\n };\n /**\n * Try to convert the passed object to a CubicBezierCurve.\n *\n * @method fromObject\n * @param {object} obj - The object to convert.\n * @memberof CubicBezierCurve\n * @static\n * @throws An exception if the passed object is malformed.\n * @return {CubicBezierCurve}\n **/\n CubicBezierCurve.fromObject = function (obj) {\n if (typeof obj !== \"object\")\n throw \"Can only build from object.\";\n if (!obj.startPoint)\n throw 'Object member \"startPoint\" missing.';\n if (!obj.endPoint)\n throw 'Object member \"endPoint\" missing.';\n if (!obj.startControlPoint)\n throw 'Object member \"startControlPoint\" missing.';\n if (!obj.endControlPoint)\n throw 'Object member \"endControlPoint\" missing.';\n return new CubicBezierCurve(new Vertex_1.Vertex(obj.startPoint[0], obj.startPoint[1]), new Vertex_1.Vertex(obj.endPoint[0], obj.endPoint[1]), new Vertex_1.Vertex(obj.startControlPoint[0], obj.startControlPoint[1]), new Vertex_1.Vertex(obj.endControlPoint[0], obj.endControlPoint[1]));\n };\n /**\n * Convert a 4-element array of vertices to a cubic bézier curve.\n *\n * @method fromArray\n * @param {Vertex[]} arr - [ startVertex, endVertex, startControlVertex, endControlVertex ]\n * @memberof CubicBezierCurve\n * @throws An exception if the passed array is malformed.\n * @return {CubicBezierCurve}\n **/\n CubicBezierCurve.fromArray = function (arr) {\n if (!Array.isArray(arr))\n throw \"Can only build from object.\";\n if (arr.length != 4)\n throw \"Can only build from array with four elements.\";\n return new CubicBezierCurve(arr[0], arr[1], arr[2], arr[3]);\n };\n /** @constant {number} */\n CubicBezierCurve.START_POINT = 0;\n /** @constant {number} */\n CubicBezierCurve.START_CONTROL_POINT = 1;\n /** @constant {number} */\n CubicBezierCurve.END_CONTROL_POINT = 2;\n /** @constant {number} */\n CubicBezierCurve.END_POINT = 3;\n /**\n * Helper utils.\n */\n CubicBezierCurve.utils = {\n evaluateT: function (p0, p1, p2, p3, t) {\n return (p0 * Math.pow(1.0 - t, 3) + p1 * 3 * t * Math.pow(1.0 - t, 2) + p2 * 3 * Math.pow(t, 2) * (1.0 - t) + p3 * Math.pow(t, 3));\n },\n cubicPolyMinMax: function (p0, p1, p2, p3) {\n // var polyX = CubicBezierCurve.utils.cubicPoly2(\n // p0, // P[0].X, // bezierCurve.startPoint.x,\n // p1, // P[1].X, // bezierCurve.startControlPoint.x,\n // p2, // P[2].X, // bezierCurve.endControlPoint.x,\n // p3 // P[3].X // bezierCurve.endPoint.x\n // );\n // var a = polyX.a;\n // var b = polyX.b;\n // var c = polyX.c;\n // var disc = polyX.b * polyX.b - 4 * polyX.a * polyX.c;\n var polyX = CubicBezierCurve.utils.cubicPoly(p0, // P[0].X, // bezierCurve.startPoint.x,\n p1, // P[1].X, // bezierCurve.startControlPoint.x,\n p2, // P[2].X, // bezierCurve.endControlPoint.x,\n p3 // P[3].X // bezierCurve.endPoint.x\n );\n var a = polyX[0]; // .a;\n var b = polyX[1]; // .b;\n var c = polyX[2]; // .c;\n //alert(\"a \"+a+\" \"+b+\" \"+c);\n // var disc = b * b - 4 * a * c;\n var disc = polyX[1] * polyX[1] - 4 * polyX[0] * polyX[2];\n // var polyX = CubicBezierCurve.utils.bezierCoeffs(p3,p2,p1,p0);\n // var a = polyX[0]; //polyX.a;\n // var b = polyX[1]; // .b;\n // var c = polyX[2]; //.c;\n // var disc = polyX[1] * polyX[1] - 4 * polyX[0] * polyX[2];\n // var xl = Math.min(bCurve.endPoint.x, bCurve.startPoint.x); // P[0].X;\n // var xh = Math.max(bCurve.endPoint.x, bCurve.startPoint.x); // P[0].X;\n var xl = Math.min(p3, p0); // P[0].X;\n var xh = Math.max(p3, p0); // P[0].X;\n // if (P[3].X < xl) xl = P[3].X;\n // if (P[3].X > xh) xh = P[3].X;\n if (disc >= 0) {\n var t1 = (-b + Math.sqrt(disc)) / (2 * a);\n // alert(\"t1 \" + t1);\n if (t1 > 0 && t1 < 1) {\n // var x1 = evalBez(PX, t1);\n // var x1 = bCurve.getPointAt(t1).x;\n var x1 = CubicBezierCurve.utils.evaluateT(p0, p1, p2, p3, t1); // bCurve.getPointAt(t1).x;\n if (x1 < xl)\n xl = x1;\n if (x1 > xh)\n xh = x1;\n }\n var t2 = (-b - Math.sqrt(disc)) / (2 * a);\n // alert(\"t2 \" + t2);\n if (t2 > 0 && t2 < 1) {\n // var x2 = evalBez(PX, t2);\n // var x2 = bCurve.getPointAt(t2).x;\n var x2 = CubicBezierCurve.utils.evaluateT(p0, p1, p2, p3, t2); //\n if (x2 < xl)\n xl = x2;\n if (x2 > xh)\n xh = x2;\n }\n }\n return { min: xl, max: xh };\n },\n /**\n * Get the points of a sub curve at the given start end end offsets (values between 0.0 and 1.0).\n *\n * tStart >= tEnd is allowed, you will get a reversed sub curve then.\n *\n * @method getSubCurvePointsAt\n * @param {CubicBezierCurve} curve – The curve to get the sub curve points from.\n * @param {number} tStart – The start offset of the desired sub curve (must be in [0..1]).\n * @param {number} tEnd – The end offset if the desired cub curve (must be in [0..1]).\n * @instance\n * @memberof CubicBezierCurve\n * @return {[Vertex, Vertex, Vertex, Vertex]} The sub curve as curve vertices.\n **/\n getSubCurvePointsAt: function (curve, tStart, tEnd) {\n var startVec = new Vector_1.Vector(curve.getPointAt(tStart), curve.getTangentAt(tStart));\n var endVec = new Vector_1.Vector(curve.getPointAt(tEnd), curve.getTangentAt(tEnd).inv());\n // Tangents are relative. Make absolute.\n startVec.b.add(startVec.a);\n endVec.b.add(endVec.a);\n // This 'splits' the curve at the given point at t.\n startVec.scale(0.33333333 * (tEnd - tStart));\n endVec.scale(0.33333333 * (tEnd - tStart));\n return [startVec.a, endVec.a, startVec.b, endVec.b];\n },\n /**\n * Compute the cubic roots for the given cubic polynomial coefficients.\n *\n * Based on\n * http://mysite.verizon.net/res148h4j/javascript/script_exact_cubic.html#the%20source%20code\n * Inspired by\n * https://www.particleincell.com/2013/cubic-line-intersection/\n * Thanks to Stephan Schmitt and Particle-In-Cell!\n *\n * @param poly\n * @returns\n */\n cubicRoots: function (poly) {\n var a = poly[0];\n var b = poly[1];\n var c = poly[2];\n var d = poly[3];\n var A = b / a;\n var B = c / a;\n var C = d / a;\n var S, T, Im;\n var Q = (3 * B - Math.pow(A, 2)) / 9;\n var R = (9 * A * B - 27 * C - 2 * Math.pow(A, 3)) / 54;\n var D = Math.pow(Q, 3) + Math.pow(R, 2); // polynomial discriminant\n var ts = []; // Array();\n if (D >= 0) {\n // complex or duplicate roots\n S = CubicBezierCurve.utils.sgn(R + Math.sqrt(D)) * Math.pow(Math.abs(R + Math.sqrt(D)), 1 / 3);\n T = CubicBezierCurve.utils.sgn(R - Math.sqrt(D)) * Math.pow(Math.abs(R - Math.sqrt(D)), 1 / 3);\n ts[0] = -A / 3 + (S + T); // real root\n ts[1] = -A / 3 - (S + T) / 2; // real part of complex root\n ts[2] = -A / 3 - (S + T) / 2; // real part of complex root\n Im = Math.abs((Math.sqrt(3) * (S - T)) / 2); // complex part of root pair\n // Mark complex roots to be discarded\n if (Im != 0) {\n ts[1] = -1;\n ts[2] = -1;\n }\n } // distinct real roots\n else {\n var th = Math.acos(R / Math.sqrt(-Math.pow(Q, 3)));\n ts[0] = 2 * Math.sqrt(-Q) * Math.cos(th / 3) - A / 3;\n ts[1] = 2 * Math.sqrt(-Q) * Math.cos((th + 2 * Math.PI) / 3) - A / 3;\n ts[2] = 2 * Math.sqrt(-Q) * Math.cos((th + 4 * Math.PI) / 3) - A / 3;\n Im = 0.0;\n }\n // Discard all t's out of spec and sort the rest\n return ts.filter(function (t) { return t >= 0 && t <= 1.0; }).sort();\n },\n /**\n * Compute the Bézier coefficients from the given Bézier point coordinates.\n *\n * @param {number} p0 - The start point coordinate.\n * @param {number} p1 - The start control point coordinate.\n * @param {number} p2 - The end control point coordinate.\n * @param {number} p3 - The end point coordinate.\n * @returns {[number,number,number,number]}\n */\n bezierCoeffs: function (p0, p1, p2, p3) {\n var coeffs = [NaN, NaN, NaN, NaN]; //Array(4);\n coeffs[0] = -p0 + 3 * p1 + -3 * p2 + p3;\n coeffs[1] = 3 * p0 - 6 * p1 + 3 * p2;\n coeffs[2] = -3 * p0 + 3 * p1;\n coeffs[3] = p0;\n return coeffs;\n },\n /**\n * Calculate the cubic polynomial coefficients used to find the bounding box.\n *\n * @param {number} p0 - The start point coordinate.\n * @param {number} p1 - The start control point coordinate.\n * @param {number} p2 - The end control point coordinate.\n * @param {number} p3 - The end point coordinate.\n * @returns {[number,number,number]}\n */\n cubicPoly: function (p0, p1, p2, p3) {\n return [3 * p3 - 9 * p2 + 9 * p1 - 3 * p0, 6 * p0 - 12 * p1 + 6 * p2, 3 * p1 - 3 * p0];\n },\n /**\n * sign of number, but is division safe: no zero returned :)\n */\n sgn: function (x) {\n return x < 0.0 ? -1 : 1;\n }\n };\n return CubicBezierCurve;\n}());\nexports.CubicBezierCurve = CubicBezierCurve;\n//# sourceMappingURL=CubicBezierCurve.js.map","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","\"use strict\";\n/* Imports for webpack */\n\nglobalThis.UIDGenerator = require(\"./UIDGenerator.js\").UIDGenerator;\nglobalThis.VertexAttr = require(\"./VertexAttr.js\").VertexAttr;\nglobalThis.VertexListeners = require(\"./VertexListeners.js\").VertexListeners;\nglobalThis.Vertex = require(\"./Vertex.js\").Vertex;\n\nglobalThis.Bounds = require(\"./Bounds.js\").Bounds;\nglobalThis.Grid = require(\"./Grid.js\").Grid;\nglobalThis.Line = require(\"./Line.js\").Line;\nglobalThis.Vector = require(\"./Vector.js\").Vector;\nglobalThis.CubicBezierCurve = require(\"./CubicBezierCurve.js\").CubicBezierCurve;\nglobalThis.BezierPath = require(\"./BezierPath.js\").BezierPath;\nglobalThis.Polygon = require(\"./Polygon.js\").Polygon;\nglobalThis.Triangle = require(\"./Triangle.js\").Triangle;\nglobalThis.VEllipse = require(\"./VEllipse.js\").VEllipse;\nglobalThis.VEllipseSector = require(\"./VEllipseSector.js\").VEllipseSector;\nglobalThis.Circle = require(\"./Circle.js\").Circle;\nglobalThis.CircleSector = require(\"./CircleSector.js\").CircleSector;\nglobalThis.PBImage = require(\"./PBImage.js\").PBImage;\nglobalThis.PBText = require(\"./PBText.js\").PBText;\nglobalThis.MouseHandler = require(\"./MouseHandler.js\").MouseHandler;\nglobalThis.KeyHandler = require(\"./KeyHandler.js\").KeyHandler;\nglobalThis.drawutils = require(\"./draw.js\").drawutils;\n// globalThis.drawutilsgl = require(\"./drawgl.js\").drawutilsgl; // Unfinished\nglobalThis.drawutilssvg = require(\"./drawutilssvg.js\").drawutilssvg;\nglobalThis.geomutils = require(\"./geomutils.js\").geomutils;\nglobalThis.PlotBoilerplate = require(\"./PlotBoilerplate.js\").PlotBoilerplate;\n"],"names":["extendStatics","__extends","this","d","b","Object","setPrototypeOf","__proto__","Array","p","prototype","hasOwnProperty","call","TypeError","String","__","constructor","create","defineProperty","exports","value","Vector","VertTuple_1","Vertex_1","_super","vertA","vertB","_this","a","className","perp","v","clone","sub","Vertex","y","x","add","inverse","tmp","inv","intersection","line","denominator","numerator1","numerator2","getOrthogonal","linePoint","startPoint","rotate","angle","utils","buildArrowHead","zA","zB","headlen","scaleX","scaleY","Math","atan2","vertices","push","cos","sin","PI","VertTuple","drawutils","CubicBezierCurve_1","drawutilssvg_1","Vector_1","context","fillShapes","ctx","offset","scale","applyStrokeOpts","strokeOptions","_a","_b","_c","_d","setLineDash","dashArray","map","dashArrayElem","lineDashOffset","dashOffset","lineJoin","lineCap","_fillOrDraw","color","fillStyle","fill","strokeStyle","stroke","beginDrawCycle","renderTime","endDrawCycle","setConfiguration","configuration","globalCompositeOperation","blendMode","setCurrentId","uid","setCurrentClassName","lineWidth","save","beginPath","moveTo","lineTo","restore","arrow","headLength","arrowHeadBasePosition","arrowHead","undefined","cubicBezierArrow","endPoint","startControlPoint","endControlPoint","diff","difference","cubicBezier","arrowHeadBasePositionBuffer","i","length","image","position","size","alpha","complete","naturalWidth","globalAlpha","drawImage","naturalHeight","texturedPoly","textureImage","textureSize","polygon","polygonPosition","rotation","basePolygonBounds","getBounds","targetTextureSize","getCenter","width","height","targetTextureOffset","min","translate","helpers","clipPoly","rect","closePath","bounds","max","CubicBezierCurve","bezierCurveTo","quadraticBezier","controlPoint","quadraticCurveTo","cubicBezierPath","path","isOpen","handle","point","square","handleLine","dot","round","arc","circle","center","radius","ellipse","circleArc","startAngle","endAngle","options","asSegment","radiusX","radiusY","grid","sizeX","sizeY","yMin","ceil","yMax","xMin","xMax","raster","diamondHandle","squareHandle","circleHandle","crosshair","cross","polyline","text","relX","relY","fontSize","fontFamily","font","fontWeight","fontStyle","indexOf","concat","textAlign","lineHeight","fillText","strokeText","label","pathData","inplace","drawutilssvg","copyPathData","transformPathData","Path2D","join","clear","clearRect","canvas","fillRect","vert","clip","Bounds","Polygon_1","containsVert","getWidth","getHeight","getScaled","scaleFactor","getMoved","moveAmount","move","getNorthPoint","getSouthPoint","getWestPoint","getEastPoint","getNorthWestPoint","getNorthEastPoint","getSouthEastPoint","getSouthWestPoint","toPolygon","Polygon","getMinDimension","getMaxDimension","randomPoint","horizontalSafeArea","verticalSafeArea","absHorizontalSafeArea","absVerticalSafeArea","random","toString","computeFromVertices","computeFromBoundsSet","boundingBoxes","fromDimension","origin","Circle","Bounds_1","Line_1","UIDGenerator_1","geomutils_1","UIDGenerator","next","setRadius","amount","containsPoint","circleUtils","containsCircle","epsilon","Number","isNaN","distance","abs","lineDistance","getClosestPoint","vertAt","tangentAt","pointA","subXY","addXY","circleIntersection","p0","p1","h","sqrt","p2","x3","y3","x4","y4","Line","lineIntersection","interA","interB","transA","transB","dist","det","distSquared","belowSqrt","sign","lineIntersections","inVectorBoundsOnly","intersectioLine","filter","hasPoint","lineIntersectionTangents","radicalAxis","circleB","helperCircle","createRadicalAxisHelperCircle","intersectionLineA","intersectionLineB","console","error","lineA","lineB","firstRadicalAxisPoint","secondRadicalAxisPoint_mirrored","closestPoint","tangentsFromPoint","centerDistance","tangentLength","log","sectorAngleByArcLength","sectorArcLength","fromICircle","obj","destroy","isDestroyed","circleCenter","circleRadius","geomutils","dist4","circleA","circleConnectLine","set","bisector","bisectorLength","setLength","circleDistance","CircleSector","Circle_1","_self","circleBounds","candidates","containsAngle","getStartPoint","getEndPoint","wrappedAngle","mapAngleTo2PI","wrappedStart","wrappedEnd","angleAt","t","circleSectorIntersection","sector","radicalLine","thisIntersectionAngleA","thisIntersectionAngleB","thatIntersectionAngleA","thatIntersectionAngleB","centerOfOriginalGap","resultSector","ray","ellipseIntersections","tmpLine","intersectionPoint","lineAngle","wrapMinMax","describeSVGPath","circleSectorUtils","describeSVGArc","polarToCartesian","centerX","centerY","moveToStart","end","start","firstHalf","secondHalf","largeArcFlag","sweepFlag","drawutilsgl","gl","_zindex","glutils","GLU","_vertShader","compileShader","vertCode","VERTEX_SHADER","_fragShader","fragCode","FRAGMENT_SHADER","_program","makeProgram","vertex_buffer","createBuffer","_x2rel","_y2rel","copyInstance","copy","curId","Float32Array","bindBuffer","ARRAY_BUFFER","bufferData","STATIC_DRAW","coord","getAttribLocation","vertexAttribPointer","FLOAT","enableVertexAttribArray","viewport","uRotationVector","getUniformLocation","uniform2fv","drawArrays","LINES","TRIANGLE_FAN","clearColor","enable","DEPTH_TEST","COLOR_BUFFER_BIT","DEPTH_BUFFER_BIT","verts","vbuffer","shaderCode","shaderType","shader","createShader","shaderSource","getShaderParameter","COMPILE_STATUS","warn","getShaderInfoLog","deleteShader","vertShader","fragShader","program","createProgram","attachShader","linkProgram","useProgram","detachShader","Grid","baseLog","base","num","mapRasterScale","adjustFactor","gf","floor","pow","Triangle_1","new_angle","asin","x1","y1","x2","y2","dotProduct","nsectAngle","pA","pB","pC","n","triangle","Triangle","lineAB","lineAC","insideAngle","clockwise","determinant","result","wrapMax","CircleSector_1","RAD_TO_DEG","svgNode","canvasSize","drawConfig","isSecondary","gNode","bufferGNode","nodeDefs","bufferNodeDefs","nodeStyle","Boolean","drawlibConfiguration","cache","Map","setSize","bufferedNodeDefs","addStyleDefs","addDefsNode","createSVGNode","appendChild","rebuildStyleDefs","keys","rules","k","drawSettings","customStyleDefs","forEach","key","innerHTML","addCustomStyleDefs","defs","findElement","nodeName","node","get","toUpperCase","delete","document","createElementNS","makeNode","style","_bindFillDraw","_configureNode","_bindNode","bindingParent","parentNode","_addCSSClasses","curClassName","setAttribute","fillMode","childNodes","child","getAttribute","removeAllChildNodes","replaceChild","tmpGNode","tmpDefsNode","nodeSupportsLineDash","tagName","dashArayElem","nodeSupportsLineJoin","nodeSupportsLineCap","_x","_y","makeLineNode","group","makeArrowHeadNode","bezier","makeCubicBezierNode","setImageSize","ratioX","ratioY","addEventListener","event","src","rotatedScalingOrigin","clipPathNode","clipPathId","imageNode","pathNode","clipNode","arcData","transformOrigin","textNode","lastChild","removeChild","createSvg","data","slice","_stx","index","_sty","_sx","_sy","lastPoint","NaN","_slp","includes","classNameOverride","makePathNode","pathString","HEAD_XML","VertexAttr","draggable","selectable","isSelected","visible","model","KeyHandler","downListeners","pressListeners","upListeners","keyStates","element","globalThis","trackAllKeys","trackAll","installListeners","fireEvent","listeners","hasListener","lis","keyCode","listener","fireDownEvent","e","handler","firePressEvent","fireUpEvent","key2code","KEY_CODES","_keyDownListener","_keyPressListener","_keyUpListener","releaseListeners","removeEventListener","down","press","up","isDown","__setFunctionName","f","name","prefix","description","configurable","PlotBoilerplate","alloyfinger_typescript_1","draw_1","drawgl_1","BezierPath_1","Grid_1","KeyHandler_1","MouseHandler_1","PBImage_1","VEllipse_1","VEllipseSector_1","VertexAttr_1","PBText_1","config","contentChangeListeners","_gui","bezierAutoAdjust","fetch","fullSize","val","fitToParent","bool","offsetX","offsetY","rasterGrid","drawRaster","rasterScaleX","rasterScaleY","rasterAdjustFactor","drawOrigin","autoAdjustOffset","offsetAdjustXPercent","offsetAdjustYPercent","backgroundColor","redrawOnResize","defaultCanvasWidth","DEFAULT_CANVAS_WIDTH","defaultCanvasHeight","DEFAULT_CANVAS_HEIGHT","canvasWidthFactor","canvasHeightFactor","cssScaleX","cssScaleY","cssUniformScale","saveFile","hooks","setToRetina","_setToRetina","autoDetectRetina","enableSVGExport","preClear","func","preDraw","postDraw","enableMouse","enableTouch","enableKeys","enableMouseWheel","enableZoom","enablePan","enableGL","isBackdropFiltersEnabled","drawVertices","drawBezierHandleLines","drawBezierHandlePoints","drawHandleLines","drawHandlePoints","drawGrid","pathVertex","controlVertex","ellipseSector","circleSector","vertex","selectedVertex","vector","anchor","canvasElement","querySelector","toLowerCase","eventCatcher","getContext","draw","parentElement","createElement","left","top","cursor","body","title","selectPolygon","draggedElements","drawables","_saveFile","resizeCanvas","installInputListeners","updateCSSscale","redraw","focus","pb","tosvgDraw","tosvgFill","drawAll","svgCode","XMLSerializer","serializeToString","blob","Blob","type","_saveAs","pixelRatio","devicePixelRatio","isPanning","isInPanningMode","fitToView","canvasCenter","canvasRatio","ratio","setOffset","newUniformZoom","setZoom","setConsole","con","_e","setCSSscale","addContentChangeListener","removeContentChangeListener","splice","_fireContentChanged","addedDrawables","removedDrawables","drawable","doNotFireEvent","isArray","arr","addDragListener","params","dragAmount","VEllipse","axis","VEllipseSector","c","BezierPath","bezierPath","bezierCurves","adjustCircular","attr","enableBezierPathAutoAdjust","PBImage","upperLeft","lowerRight","PBText","remove","removeWithVertices","removedDrawables_1","wasRemoved_1","removeVertex","wasRemoved","removeAll","keepVertices","triggerRedraw","getVertexNear","pixelPosition","pixelTolerance","locatePointNear","transformMousePosition","typeName","vindex","gScale","gSize","cs","_handleColor","drawDrawables","drawDrawable","curveIndex","df","signedRadiusV","signedRadiusH","radiusH","radiusV","ellipseSectorUtils","drawSelectPolygon","clearSelection","getFProp","elem","propName","parseFloat","getComputedStyle","getPropertyValue","getAvailableContainerSpace","container","display","padding","border","pl","pr","pt","bl","br","bt","bb","w","clientWidth","clientHeight","_f","_g","_setSize","HTMLCanvasElement","SVGElement","adjustOffset","innerWidth","documentElement","innerHeight","space","selectVerticesInPolygon","tolerance","Draggable","VERTEX","setVIndex","handleClick","pos","DEFAULT_CLICK_TOLERANCE","fireClickEvent","keyHandler","paths","pindex","cindex","getPointByID","pid","revertMousePosition","getDraggedElementCount","mouseDownHandler","button","draggablePoint","fireDragStartEvent","mouseDragHandler","oldDragAmount","moveCurvePoint","fireDragEvent","mouseUpHandler","wasDragged","fireDragEndEvent","mouseWheelHandler","zoomStep","we","deltaY","preventDefault","newOffset","zoomFactorX","zoomFactorY","interactionPos","oldPos","newPos","newOffsetX","newOffsetY","MouseHandler","drag","wheel","relPos_1","getBoundingClientRect","touchMovePos","touchDownPos","draggedElement","multiTouchStartScale","clearTouch_1","afProps","touchStart","evt","touches","clientX","clientY","DEFAULT_TOUCH_TOLERANCE","draggingVertex","fakeEvent","isTouchEvent","mouseDownPos","mouseDragPos","touchMove","stopPropagation","rel","trans","deltaX","touchEnd","touchCancel","multipointStart","multipointEnd","pinch","touchItem0","item","touchItem1","fingerA","fingerB","zoom","window","createAlloyFinger","default","createGUI","props","getGUI","class_1","isVertex","safeMergeByKeys","extension","typ","extVal","JSON","parse","removeProperty","transform","fallback","locateCurveByStartPoint","START_POINT","updateArcLengths","locateCurveByStartControlPoint","adjustPredecessorControlPoint","locateCurveByEndControlPoint","adjustSuccessorControlPoint","locateCurveByEndPoint","END_CONTROL_POINT","factory","revert","normalize","factor","newA","v0","v1","colinear","EPSILON","getClosestT","l2","vtutils","dist2","insideBoundsOnly","pointDistance","asLine","asVector","calcCircumcircle","p1x","p1y","cx","cy","getLen","HandlerAdmin","el","handlers","del","dispatch","_args","len","apply","arguments","wrapFunc","handlerAdmin","AlloyFinger","option","bind","cancel","preV","pinchStartLen","isDoubleTap","noop","swipe","tap","doubleTap","longTap","singleTap","pressMove","twoFingerPressMove","_cancelAllHandler","cancelAll","delta","last","now","tapTimeout","singleTapTimeout","longTapTimeout","swipeTimeout","preTapPosition","Date","pageX","pageY","clearTimeout","_cancelLongTap","_cancelSingleTap","_preventTap","setTimeout","afEvent","currentX","currentY","sCurrentX","sCurrentY","v2","mr","r","acos","getAngle","sx2","sy2","movedX","movedY","changedTouches","self","direction","_swipeDirection","on","off","addVertex","addVertexAt","getEdgeAt","vertIndex","getVertexAt","getEdges","lines","getInnerAngleAt","p3","isAcute","isAngleAcute","zero","p2mp1","p3mp2","p2mp1_len","p3mp2_len","lengthProduct","A","B","C","inside","j","xi","yi","xj","yj","containsVerts","every","containsPolygon","lineSegment","area","signedArea","isClockwise","reverse","perimeter","getMeanCenter","getCentroid","forceClockwise","calculateCentroid","locateLineIntersecion","intersectionTuple","polyLine","edgeIndex","lineIntersectionTangentsIndices","closestLineIntersection","closestInterSectionIndex","closestLineIntersectionIndex","allIntersections","closestIntersection","MAX_VALUE","curDist","curVert","getInterpolationPolygon","interpolationCount","nextVert","lerpAmount","lerp","getEvenDistributionPolygon","pointCount","Error","polygonPoint","stepSize","polygonIndex","nextPolygonPoint","segmentLength","loopMax","curSegmentU","newPoint","lerpAbs","elimitateColinearEdges","eps","areColinear","vertC","toQuadraticBezierData","qbezier","cc0","cc1","edgeCenter","limit","toQuadraticBezierSVGString","qdata","buffer","toCubicBezierData","threshold","cbezier","aCenter","bCenter","a2","b0","toCubicBezierSVGString","toCubicBezierPath","pathdata","fromArray","total","l","centroid","cur","sum","intersectionPoints","sAngle","eAngle","getExtremePoints","toCubicBezier","quarterSegmentCount","segmentCount","normalizeAngle","angles","equidistantVertAngles","curves","curAngle","nextAngle","startTangent","endTangent","curve","startDiff","endDiff","r2d","fullEllipsePointCount","ellipseAngles","startIndex","findClosestToStartAngle","ea","endpointToCenterParameters","rx","ry","phi","fa","fs","sinphi","cosphi","px","py","prx","pry","L","M","_cx","_cy","START_CONTROL_POINT","END_POINT","totalArcLength","addCurve","getLength","equals","getCurveCount","getCurveAt","getStartControlPoint","getEndControlPoint","scaleXY","scaleFactors","minIndex","minDist","curveT","uMin","u","getPointAt","getPoint","uTemp","relativeU","getTangentAt","getTangent","getPerpendicularAt","getPerpendicular","uResult","_locateUIndex","bCurve","uPart","reduce","accu","curCurve","uBefore","getSubPathAt","startT","endT","startU","endU","uStartResult","uEndResult","firstT","lastT","firstCurve","getSubCurveAt","pointID","obtainHandleLength","mainCurve","neighbourCurve","adjustNeighbourControlPoint","_mainCurve","mainPoint","mainControlPoint","neighbourPoint","neighbourControlPoint","obtainHandleLengths","_updateArcLengths","mainHandleBounds","neighbourHandleBounds","mainHandleLength","neighbourHandleLength","POSITIVE_INFINITY","NEGATIVE_INFINITY","getEvenDistributionVertices","arcLength","toPathPoints","toJSON","prettyFormat","fromJSON","jsonString","fromCurve","bPath","lastCurve","isInstance","fromObject","toReducedListRepresentation","digits","toFixed","fromReducedListRepresentation","listJSON","pointArray","fromReducedList","getArea","scaleToCentroid","getCircumcircle","getMinimumEnclosingCircle","circleAB","circleBC","circleCA","circumCircle","isAdjacent","tri","getThirdVertex","vert1","vert2","getVertices","tmpCircle","radius_squared","inCircumcircle","dx","dy","modIndex","pointIsInTriangle","getIncircularTriangle","lineC","bisector1","bisector2","getIncircle","getIncenter","max3","min3","p0x","p0y","p2x","p2y","s","D","E","F","G","VertexListeners_1","tuple","VertexListeners","setX","setY","invX","invY","amountX","amountY","addX","addY","subX","subY","eqX","eqY","target","step","factors","ZERO","multiplyScalar","scalar","findClosestPoint","pointB","findFarestPoint","precision","removeAllListeners","randomVertex","viewPort","arrayToJSON","stringify","x_max","x_min","t_x1","t_x2","x_x1","y_x1","x_x2","y_x2","y_max","y_min","t_y1","t_y2","x_y1","y_y1","x_y2","y_y2","r1","r2","ux","uy","vx","vy","bbox_halfwidth","bbox_halfheight","normalAt","foci","getFoci","angleA","centerAngle","endPointA","endPointB","resultVector","rh","rv","sdiff","getEquidistantVertices","ellipseCopy","rayCopy","rotationAmount","scalingFactors","intersections","phiToTheta","tanPhi","tan","tanPhi2","atan","theta","XWheelEvent","XMouseEvent","MouseEvent","WheelEvent","mouseButton","installed","mousemove","mkParams","relPos","mouseup","mousedown","click","eventName","xEvent","leftButton","middleButton","rightButton","draggedFrom","listenFor","unlistenFor","callback","throwAlreadyInstalled","dragStart","dragEnd","addClickListener","_addListener","removeClickListener","_removeListener","removeDragListener","addDragStartListener","removeDragStartListener","addDragEndListener","removeDragEndListener","_fireEvent","ve","newListener","oldListener","current","getStartTangent","getEndTangent","trimStart","trimStartAt","relativeAmount","trimEnd","trimEndAt","intrsctn","curveIntervals","segmentCache","segmentLengths","moveControlPoint","curveStep","tmpLength","newLength","tPrev","tNext","iteration","locateIntervalByDistance","tStart","tEnd","stepCount","tDiff","xMinMax","cubicPolyMinMax","xl","xh","yMinMax","yl","yh","id","evaluateT","t2","nt2","tX","tY","uValue","convertU2T","subCurbePoints","getSubCurvePointsAt","trimStartEnd","uStart","uEnd","trimStartEndAt","cleanTrimStart","cleanTrimEnd","relativeTrimEnd","getSubCurve","tangentVector","lineIntersectionTs","intersectionTangents","vec","bx","bezierCoeffs","by","poly","cubicRoots","root","polyX","cubicPoly","disc","t1","startVec","endVec","S","T","Q","R","ts","sgn","th","sort","coeffs","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","module","__webpack_modules__","definition","o","enumerable","prop","Symbol","toStringTag"],"sourceRoot":""}