{"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":""}