{"version":3,"file":"index.min.mjs","sources":["../../../../src/util/path/index.ts"],"sourcesContent":["import { cache } from '../../cache';\nimport { config } from '../../config';\nimport { halfPI, PiBy180 } from '../../constants';\nimport type { TMat2D, TRadian, TRectBounds } from '../../typedefs';\nimport { cos } from '../misc/cos';\nimport { multiplyTransformMatrices, transformPoint } from '../misc/matrix';\nimport { sin } from '../misc/sin';\nimport { toFixed } from '../misc/toFixed';\nimport type {\n  TCurveInfo,\n  TComplexPathData,\n  TParsedAbsoluteCubicCurveCommand,\n  TParsedCubicCurveCommand,\n  TPathSegmentInfo,\n  TPointAngle,\n  TSimpleParsedCommand,\n  TSimplePathData,\n  TPathSegmentCommandInfo,\n  TComplexParsedCommand,\n  TPathSegmentInfoCommon,\n  TEndPathInfo,\n  TParsedArcCommand,\n} from './typedefs';\nimport type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport { rePathCommand } from './regex';\nimport { cleanupSvgAttribute } from '../internals/cleanupSvgAttribute';\n\n/**\n * Commands that may be repeated\n */\nconst repeatedCommands: Record<string, string | undefined> = {\n  m: 'l',\n  M: 'L',\n};\n\n/**\n * Convert an arc of a rotated ellipse to a Bezier Curve\n * @param {TRadian} theta1 start of the arc\n * @param {TRadian} theta2 end of the arc\n * @param cosTh cosine of the angle of rotation\n * @param sinTh sine of the angle of rotation\n * @param rx x-axis radius (before rotation)\n * @param ry y-axis radius (before rotation)\n * @param cx1 center x of the ellipse\n * @param cy1 center y of the ellipse\n * @param mT\n * @param fromX starting point of arc x\n * @param fromY starting point of arc y\n */\nconst segmentToBezier = (\n  theta1: TRadian,\n  theta2: TRadian,\n  cosTh: number,\n  sinTh: number,\n  rx: number,\n  ry: number,\n  cx1: number,\n  cy1: number,\n  mT: number,\n  fromX: number,\n  fromY: number\n): TParsedCubicCurveCommand => {\n  const costh1 = cos(theta1),\n    sinth1 = sin(theta1),\n    costh2 = cos(theta2),\n    sinth2 = sin(theta2),\n    toX = cosTh * rx * costh2 - sinTh * ry * sinth2 + cx1,\n    toY = sinTh * rx * costh2 + cosTh * ry * sinth2 + cy1,\n    cp1X = fromX + mT * (-cosTh * rx * sinth1 - sinTh * ry * costh1),\n    cp1Y = fromY + mT * (-sinTh * rx * sinth1 + cosTh * ry * costh1),\n    cp2X = toX + mT * (cosTh * rx * sinth2 + sinTh * ry * costh2),\n    cp2Y = toY + mT * (sinTh * rx * sinth2 - cosTh * ry * costh2);\n\n  return ['C', cp1X, cp1Y, cp2X, cp2Y, toX, toY];\n};\n\n/**\n * Adapted from {@link http://dxr.mozilla.org/mozilla-central/source/dom/svg/SVGPathDataParser.cpp}\n * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here\n * http://mozilla.org/MPL/2.0/\n * @param toX\n * @param toY\n * @param rx\n * @param ry\n * @param {number} large 0 or 1 flag\n * @param {number} sweep 0 or 1 flag\n * @param rotateX\n */\nconst arcToSegments = (\n  toX: number,\n  toY: number,\n  rx: number,\n  ry: number,\n  large: number,\n  sweep: number,\n  rotateX: TRadian\n): TParsedAbsoluteCubicCurveCommand[] => {\n  if (rx === 0 || ry === 0) {\n    return [];\n  }\n  let fromX = 0,\n    fromY = 0,\n    root = 0;\n  const PI = Math.PI,\n    theta = rotateX * PiBy180,\n    sinTheta = sin(theta),\n    cosTh = cos(theta),\n    px = 0.5 * (-cosTh * toX - sinTheta * toY),\n    py = 0.5 * (-cosTh * toY + sinTheta * toX),\n    rx2 = rx ** 2,\n    ry2 = ry ** 2,\n    py2 = py ** 2,\n    px2 = px ** 2,\n    pl = rx2 * ry2 - rx2 * py2 - ry2 * px2;\n  let _rx = Math.abs(rx);\n  let _ry = Math.abs(ry);\n\n  if (pl < 0) {\n    const s = Math.sqrt(1 - pl / (rx2 * ry2));\n    _rx *= s;\n    _ry *= s;\n  } else {\n    root =\n      (large === sweep ? -1.0 : 1.0) * Math.sqrt(pl / (rx2 * py2 + ry2 * px2));\n  }\n\n  const cx = (root * _rx * py) / _ry,\n    cy = (-root * _ry * px) / _rx,\n    cx1 = cosTh * cx - sinTheta * cy + toX * 0.5,\n    cy1 = sinTheta * cx + cosTh * cy + toY * 0.5;\n  let mTheta = calcVectorAngle(1, 0, (px - cx) / _rx, (py - cy) / _ry);\n  let dtheta = calcVectorAngle(\n    (px - cx) / _rx,\n    (py - cy) / _ry,\n    (-px - cx) / _rx,\n    (-py - cy) / _ry\n  );\n\n  if (sweep === 0 && dtheta > 0) {\n    dtheta -= 2 * PI;\n  } else if (sweep === 1 && dtheta < 0) {\n    dtheta += 2 * PI;\n  }\n\n  // Convert into cubic bezier segments <= 90deg\n  const segments = Math.ceil(Math.abs((dtheta / PI) * 2)),\n    result = new Array(segments),\n    mDelta = dtheta / segments,\n    mT =\n      ((8 / 3) * Math.sin(mDelta / 4) * Math.sin(mDelta / 4)) /\n      Math.sin(mDelta / 2);\n  let th3 = mTheta + mDelta;\n\n  for (let i = 0; i < segments; i++) {\n    result[i] = segmentToBezier(\n      mTheta,\n      th3,\n      cosTh,\n      sinTheta,\n      _rx,\n      _ry,\n      cx1,\n      cy1,\n      mT,\n      fromX,\n      fromY\n    );\n    fromX = result[i][5];\n    fromY = result[i][6];\n    mTheta = th3;\n    th3 += mDelta;\n  }\n  return result;\n};\n\n/**\n * @private\n * Calculate the angle between two vectors\n * @param ux u endpoint x\n * @param uy u endpoint y\n * @param vx v endpoint x\n * @param vy v endpoint y\n */\nconst calcVectorAngle = (\n  ux: number,\n  uy: number,\n  vx: number,\n  vy: number\n): TRadian => {\n  const ta = Math.atan2(uy, ux),\n    tb = Math.atan2(vy, vx);\n  if (tb >= ta) {\n    return tb - ta;\n  } else {\n    return 2 * Math.PI - (ta - tb);\n  }\n};\n\n// functions for the Cubic beizer\n// taken from: https://github.com/konvajs/konva/blob/7.0.5/src/shapes/Path.ts#L350\nconst CB1 = (t: number) => t ** 3;\nconst CB2 = (t: number) => 3 * t ** 2 * (1 - t);\nconst CB3 = (t: number) => 3 * t * (1 - t) ** 2;\nconst CB4 = (t: number) => (1 - t) ** 3;\n\n/**\n * Calculate bounding box of a cubic Bezier curve\n * Taken from http://jsbin.com/ivomiq/56/edit (no credits available)\n * TODO: can we normalize this with the starting points set at 0 and then translated the bbox?\n * @param {number} begx starting point\n * @param {number} begy\n * @param {number} cp1x first control point\n * @param {number} cp1y\n * @param {number} cp2x second control point\n * @param {number} cp2y\n * @param {number} endx end of bezier\n * @param {number} endy\n * @return {TRectBounds} the rectangular bounds\n */\nexport function getBoundsOfCurve(\n  begx: number,\n  begy: number,\n  cp1x: number,\n  cp1y: number,\n  cp2x: number,\n  cp2y: number,\n  endx: number,\n  endy: number\n): TRectBounds {\n  let argsString: string;\n  if (config.cachesBoundsOfCurve) {\n    // eslint-disable-next-line\n    argsString = [...arguments].join();\n    if (cache.boundsOfCurveCache[argsString]) {\n      return cache.boundsOfCurveCache[argsString];\n    }\n  }\n\n  const sqrt = Math.sqrt,\n    abs = Math.abs,\n    tvalues = [],\n    bounds: [[x: number, y: number], [x: number, y: number]] = [\n      [0, 0],\n      [0, 0],\n    ];\n\n  let b = 6 * begx - 12 * cp1x + 6 * cp2x;\n  let a = -3 * begx + 9 * cp1x - 9 * cp2x + 3 * endx;\n  let c = 3 * cp1x - 3 * begx;\n\n  for (let i = 0; i < 2; ++i) {\n    if (i > 0) {\n      b = 6 * begy - 12 * cp1y + 6 * cp2y;\n      a = -3 * begy + 9 * cp1y - 9 * cp2y + 3 * endy;\n      c = 3 * cp1y - 3 * begy;\n    }\n\n    if (abs(a) < 1e-12) {\n      if (abs(b) < 1e-12) {\n        continue;\n      }\n      const t = -c / b;\n      if (0 < t && t < 1) {\n        tvalues.push(t);\n      }\n      continue;\n    }\n    const b2ac = b * b - 4 * c * a;\n    if (b2ac < 0) {\n      continue;\n    }\n    const sqrtb2ac = sqrt(b2ac);\n    const t1 = (-b + sqrtb2ac) / (2 * a);\n    if (0 < t1 && t1 < 1) {\n      tvalues.push(t1);\n    }\n    const t2 = (-b - sqrtb2ac) / (2 * a);\n    if (0 < t2 && t2 < 1) {\n      tvalues.push(t2);\n    }\n  }\n\n  let j = tvalues.length;\n  const jlen = j;\n  const iterator = getPointOnCubicBezierIterator(\n    begx,\n    begy,\n    cp1x,\n    cp1y,\n    cp2x,\n    cp2y,\n    endx,\n    endy\n  );\n  while (j--) {\n    const { x, y } = iterator(tvalues[j]);\n    bounds[0][j] = x;\n    bounds[1][j] = y;\n  }\n\n  bounds[0][jlen] = begx;\n  bounds[1][jlen] = begy;\n  bounds[0][jlen + 1] = endx;\n  bounds[1][jlen + 1] = endy;\n  const result: TRectBounds = [\n    new Point(Math.min(...bounds[0]), Math.min(...bounds[1])),\n    new Point(Math.max(...bounds[0]), Math.max(...bounds[1])),\n  ];\n  if (config.cachesBoundsOfCurve) {\n    cache.boundsOfCurveCache[argsString!] = result;\n  }\n  return result;\n}\n\n/**\n * Converts arc to a bunch of cubic Bezier curves\n * @param {number} fx starting point x\n * @param {number} fy starting point y\n * @param {TParsedArcCommand} coords Arc command\n */\nexport const fromArcToBeziers = (\n  fx: number,\n  fy: number,\n  [_, rx, ry, rot, large, sweep, tx, ty]: TParsedArcCommand\n): TParsedAbsoluteCubicCurveCommand[] => {\n  const segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n  for (let i = 0, len = segsNorm.length; i < len; i++) {\n    segsNorm[i][1] += fx;\n    segsNorm[i][2] += fy;\n    segsNorm[i][3] += fx;\n    segsNorm[i][4] += fy;\n    segsNorm[i][5] += fx;\n    segsNorm[i][6] += fy;\n  }\n  return segsNorm;\n};\n\n/**\n * This function takes a parsed SVG path and makes it simpler for fabricJS logic.\n * Simplification consist of:\n * - All commands converted to absolute (lowercase to uppercase)\n * - S converted to C\n * - T converted to Q\n * - A converted to C\n * @param {TComplexPathData} path the array of commands of a parsed SVG path for `Path`\n * @return {TSimplePathData} the simplified array of commands of a parsed SVG path for `Path`\n * TODO: figure out how to remove the type assertions in a nice way\n */\nexport const makePathSimpler = (path: TComplexPathData): TSimplePathData => {\n  // x and y represent the last point of the path, AKA the previous command point.\n  // we add them to each relative command to make it an absolute comment.\n  // we also swap the v V h H with L, because are easier to transform.\n  let x = 0,\n    y = 0;\n  // x1 and y1 represent the last point of the subpath. the subpath is started with\n  // m or M command. When a z or Z command is drawn, x and y need to be resetted to\n  // the last x1 and y1.\n  let x1 = 0,\n    y1 = 0;\n  // previous will host the letter of the previous command, to handle S and T.\n  // controlX and controlY will host the previous reflected control point\n  const destinationPath: TSimplePathData = [];\n  let previous,\n    // placeholders\n    controlX = 0,\n    controlY = 0;\n  for (const parsedCommand of path) {\n    const current: TComplexParsedCommand = [...parsedCommand];\n    let converted: TSimpleParsedCommand | undefined;\n    switch (\n      current[0] // first letter\n    ) {\n      case 'l': // lineto, relative\n        current[1] += x;\n        current[2] += y;\n      // falls through\n      case 'L':\n        x = current[1];\n        y = current[2];\n        converted = ['L', x, y];\n        break;\n      case 'h': // horizontal lineto, relative\n        current[1] += x;\n      // falls through\n      case 'H':\n        x = current[1];\n        converted = ['L', x, y];\n        break;\n      case 'v': // vertical lineto, relative\n        current[1] += y;\n      // falls through\n      case 'V':\n        y = current[1];\n        converted = ['L', x, y];\n        break;\n      case 'm': // moveTo, relative\n        current[1] += x;\n        current[2] += y;\n      // falls through\n      case 'M':\n        x = current[1];\n        y = current[2];\n        x1 = current[1];\n        y1 = current[2];\n        converted = ['M', x, y];\n        break;\n      case 'c': // bezierCurveTo, relative\n        current[1] += x;\n        current[2] += y;\n        current[3] += x;\n        current[4] += y;\n        current[5] += x;\n        current[6] += y;\n      // falls through\n      case 'C':\n        controlX = current[3];\n        controlY = current[4];\n        x = current[5];\n        y = current[6];\n        converted = ['C', current[1], current[2], controlX, controlY, x, y];\n        break;\n      case 's': // shorthand cubic bezierCurveTo, relative\n        current[1] += x;\n        current[2] += y;\n        current[3] += x;\n        current[4] += y;\n      // falls through\n      case 'S':\n        // would be sScC but since we are swapping sSc for C, we check just that.\n        if (previous === 'C') {\n          // calculate reflection of previous control points\n          controlX = 2 * x - controlX;\n          controlY = 2 * y - controlY;\n        } else {\n          // If there is no previous command or if the previous command was not a C, c, S, or s,\n          // the control point is coincident with the current point\n          controlX = x;\n          controlY = y;\n        }\n        x = current[3];\n        y = current[4];\n        converted = ['C', controlX, controlY, current[1], current[2], x, y];\n        // converted[3] and converted[4] are NOW the second control point.\n        // we keep it for the next reflection.\n        controlX = converted[3];\n        controlY = converted[4];\n        break;\n      case 'q': // quadraticCurveTo, relative\n        current[1] += x;\n        current[2] += y;\n        current[3] += x;\n        current[4] += y;\n      // falls through\n      case 'Q':\n        controlX = current[1];\n        controlY = current[2];\n        x = current[3];\n        y = current[4];\n        converted = ['Q', controlX, controlY, x, y];\n        break;\n      case 't': // shorthand quadraticCurveTo, relative\n        current[1] += x;\n        current[2] += y;\n      // falls through\n      case 'T':\n        if (previous === 'Q') {\n          // calculate reflection of previous control point\n          controlX = 2 * x - controlX;\n          controlY = 2 * y - controlY;\n        } else {\n          // If there is no previous command or if the previous command was not a Q, q, T or t,\n          // assume the control point is coincident with the current point\n          controlX = x;\n          controlY = y;\n        }\n        x = current[1];\n        y = current[2];\n        converted = ['Q', controlX, controlY, x, y];\n        break;\n      case 'a':\n        current[6] += x;\n        current[7] += y;\n      // falls through\n      case 'A':\n        fromArcToBeziers(x, y, current).forEach((b) => destinationPath.push(b));\n        x = current[6];\n        y = current[7];\n        break;\n      case 'z':\n      case 'Z':\n        x = x1;\n        y = y1;\n        converted = ['Z'];\n        break;\n      default:\n    }\n    if (converted) {\n      destinationPath.push(converted);\n      previous = converted[0];\n    } else {\n      previous = '';\n    }\n  }\n  return destinationPath;\n};\n\n// todo verify if we can just use the point class here\n/**\n * Calc length from point x1,y1 to x2,y2\n * @param {number} x1 starting point x\n * @param {number} y1 starting point y\n * @param {number} x2 starting point x\n * @param {number} y2 starting point y\n * @return {number} length of segment\n */\nconst calcLineLength = (\n  x1: number,\n  y1: number,\n  x2: number,\n  y2: number\n): number => Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);\n\n/**\n * Get an iterator that takes a percentage and returns a point\n * @param {number} begx\n * @param {number} begy\n * @param {number} cp1x\n * @param {number} cp1y\n * @param {number} cp2x\n * @param {number} cp2y\n * @param {number} endx\n * @param {number} endy\n */\nconst getPointOnCubicBezierIterator =\n  (\n    begx: number,\n    begy: number,\n    cp1x: number,\n    cp1y: number,\n    cp2x: number,\n    cp2y: number,\n    endx: number,\n    endy: number\n  ) =>\n  (pct: number) => {\n    const c1 = CB1(pct),\n      c2 = CB2(pct),\n      c3 = CB3(pct),\n      c4 = CB4(pct);\n    return new Point(\n      endx * c1 + cp2x * c2 + cp1x * c3 + begx * c4,\n      endy * c1 + cp2y * c2 + cp1y * c3 + begy * c4\n    );\n  };\n\nconst QB1 = (t: number) => t ** 2;\nconst QB2 = (t: number) => 2 * t * (1 - t);\nconst QB3 = (t: number) => (1 - t) ** 2;\n\nconst getTangentCubicIterator =\n  (\n    p1x: number,\n    p1y: number,\n    p2x: number,\n    p2y: number,\n    p3x: number,\n    p3y: number,\n    p4x: number,\n    p4y: number\n  ) =>\n  (pct: number) => {\n    const qb1 = QB1(pct),\n      qb2 = QB2(pct),\n      qb3 = QB3(pct),\n      tangentX =\n        3 * (qb3 * (p2x - p1x) + qb2 * (p3x - p2x) + qb1 * (p4x - p3x)),\n      tangentY =\n        3 * (qb3 * (p2y - p1y) + qb2 * (p3y - p2y) + qb1 * (p4y - p3y));\n    return Math.atan2(tangentY, tangentX);\n  };\n\nconst getPointOnQuadraticBezierIterator =\n  (\n    p1x: number,\n    p1y: number,\n    p2x: number,\n    p2y: number,\n    p3x: number,\n    p3y: number\n  ) =>\n  (pct: number) => {\n    const c1 = QB1(pct),\n      c2 = QB2(pct),\n      c3 = QB3(pct);\n    return new Point(\n      p3x * c1 + p2x * c2 + p1x * c3,\n      p3y * c1 + p2y * c2 + p1y * c3\n    );\n  };\n\nconst getTangentQuadraticIterator =\n  (\n    p1x: number,\n    p1y: number,\n    p2x: number,\n    p2y: number,\n    p3x: number,\n    p3y: number\n  ) =>\n  (pct: number) => {\n    const invT = 1 - pct,\n      tangentX = 2 * (invT * (p2x - p1x) + pct * (p3x - p2x)),\n      tangentY = 2 * (invT * (p2y - p1y) + pct * (p3y - p2y));\n    return Math.atan2(tangentY, tangentX);\n  };\n\n// this will run over a path segment (a cubic or quadratic segment) and approximate it\n// with 100 segments. This will good enough to calculate the length of the curve\nconst pathIterator = (\n  iterator: (pct: number) => Point,\n  x1: number,\n  y1: number\n) => {\n  let tempP = new Point(x1, y1),\n    tmpLen = 0;\n  for (let perc = 1; perc <= 100; perc += 1) {\n    const p = iterator(perc / 100);\n    tmpLen += calcLineLength(tempP.x, tempP.y, p.x, p.y);\n    tempP = p;\n  }\n  return tmpLen;\n};\n\n/**\n * Given a pathInfo, and a distance in pixels, find the percentage from 0 to 1\n * that correspond to that pixels run over the path.\n * The percentage will be then used to find the correct point on the canvas for the path.\n * @param {Array} segInfo fabricJS collection of information on a parsed path\n * @param {number} distance from starting point, in pixels.\n * @return {TPointAngle} info object with x and y ( the point on canvas ) and angle, the tangent on that point;\n */\nconst findPercentageForDistance = (\n  segInfo: TCurveInfo<'Q' | 'C'>,\n  distance: number\n): TPointAngle => {\n  let perc = 0,\n    tmpLen = 0,\n    tempP: XY = { x: segInfo.x, y: segInfo.y },\n    p: XY = { ...tempP },\n    nextLen: number,\n    nextStep = 0.01,\n    lastPerc = 0;\n  // nextStep > 0.0001 covers 0.00015625 that 1/64th of 1/100\n  // the path\n  const iterator = segInfo.iterator,\n    angleFinder = segInfo.angleFinder;\n  while (tmpLen < distance && nextStep > 0.0001) {\n    p = iterator(perc);\n    lastPerc = perc;\n    nextLen = calcLineLength(tempP.x, tempP.y, p.x, p.y);\n    // compare tmpLen each cycle with distance, decide next perc to test.\n    if (nextLen + tmpLen > distance) {\n      // we discard this step and we make smaller steps.\n      perc -= nextStep;\n      nextStep /= 2;\n    } else {\n      tempP = p;\n      perc += nextStep;\n      tmpLen += nextLen;\n    }\n  }\n  return { ...p, angle: angleFinder(lastPerc) };\n};\n\n/**\n * Run over a parsed and simplified path and extract some information (length of each command and starting point)\n * @param {TSimplePathData} path parsed path commands\n * @return {TPathSegmentInfo[]} path commands information\n */\nexport const getPathSegmentsInfo = (\n  path: TSimplePathData\n): TPathSegmentInfo[] => {\n  let totalLength = 0,\n    //x2 and y2 are the coords of segment start\n    //x1 and y1 are the coords of the current point\n    x1 = 0,\n    y1 = 0,\n    x2 = 0,\n    y2 = 0,\n    iterator,\n    tempInfo: TPathSegmentInfo;\n  const info: TPathSegmentInfo[] = [];\n  for (const current of path) {\n    const basicInfo: TPathSegmentInfoCommon<keyof TPathSegmentCommandInfo> = {\n      x: x1,\n      y: y1,\n      command: current[0],\n      length: 0,\n    };\n    switch (\n      current[0] //first letter\n    ) {\n      case 'M':\n        tempInfo = <TPathSegmentInfoCommon<'M'>>basicInfo;\n        tempInfo.x = x2 = x1 = current[1];\n        tempInfo.y = y2 = y1 = current[2];\n        break;\n      case 'L':\n        tempInfo = <TPathSegmentInfoCommon<'L'>>basicInfo;\n        tempInfo.length = calcLineLength(x1, y1, current[1], current[2]);\n        x1 = current[1];\n        y1 = current[2];\n        break;\n      case 'C':\n        iterator = getPointOnCubicBezierIterator(\n          x1,\n          y1,\n          current[1],\n          current[2],\n          current[3],\n          current[4],\n          current[5],\n          current[6]\n        );\n        tempInfo = <TCurveInfo<'C'>>basicInfo;\n        tempInfo.iterator = iterator;\n        tempInfo.angleFinder = getTangentCubicIterator(\n          x1,\n          y1,\n          current[1],\n          current[2],\n          current[3],\n          current[4],\n          current[5],\n          current[6]\n        );\n        tempInfo.length = pathIterator(iterator, x1, y1);\n\n        x1 = current[5];\n        y1 = current[6];\n        break;\n      case 'Q':\n        iterator = getPointOnQuadraticBezierIterator(\n          x1,\n          y1,\n          current[1],\n          current[2],\n          current[3],\n          current[4]\n        );\n        tempInfo = <TCurveInfo<'Q'>>basicInfo;\n        tempInfo.iterator = iterator;\n        tempInfo.angleFinder = getTangentQuadraticIterator(\n          x1,\n          y1,\n          current[1],\n          current[2],\n          current[3],\n          current[4]\n        );\n        tempInfo.length = pathIterator(iterator, x1, y1);\n        x1 = current[3];\n        y1 = current[4];\n        break;\n      case 'Z':\n        // we add those in order to ease calculations later\n        tempInfo = <TEndPathInfo>basicInfo;\n        tempInfo.destX = x2;\n        tempInfo.destY = y2;\n        tempInfo.length = calcLineLength(x1, y1, x2, y2);\n        x1 = x2;\n        y1 = y2;\n        break;\n    }\n    totalLength += tempInfo.length;\n    info.push(tempInfo);\n  }\n  info.push({ length: totalLength, x: x1, y: y1 });\n  return info;\n};\n\n/**\n * Get the point on the path that is distance along the path\n * @param path\n * @param distance\n * @param infos\n */\nexport const getPointOnPath = (\n  path: TSimplePathData,\n  distance: number,\n  infos: TPathSegmentInfo[] = getPathSegmentsInfo(path)\n): TPointAngle | undefined => {\n  let i = 0;\n  while (distance - infos[i].length > 0 && i < infos.length - 2) {\n    distance -= infos[i].length;\n    i++;\n  }\n  const segInfo = infos[i],\n    segPercent = distance / segInfo.length,\n    segment = path[i];\n\n  switch (segInfo.command) {\n    case 'M':\n      return { x: segInfo.x, y: segInfo.y, angle: 0 };\n    case 'Z':\n      return {\n        ...new Point(segInfo.x, segInfo.y).lerp(\n          new Point(segInfo.destX, segInfo.destY),\n          segPercent\n        ),\n        angle: Math.atan2(segInfo.destY - segInfo.y, segInfo.destX - segInfo.x),\n      };\n    case 'L':\n      return {\n        ...new Point(segInfo.x, segInfo.y).lerp(\n          new Point(segment[1]!, segment[2]!),\n          segPercent\n        ),\n        angle: Math.atan2(segment[2]! - segInfo.y, segment[1]! - segInfo.x),\n      };\n    case 'C':\n      return findPercentageForDistance(segInfo, distance);\n    case 'Q':\n      return findPercentageForDistance(segInfo, distance);\n    default:\n    // throw Error('Invalid command');\n  }\n};\n\nconst rePathCmdAll = new RegExp(rePathCommand, 'gi');\nconst rePathCmd = new RegExp(rePathCommand, 'i');\n\n/**\n *\n * @param {string} pathString\n * @return {TComplexPathData} An array of SVG path commands\n * @example <caption>Usage</caption>\n * parsePath('M 3 4 Q 3 5 2 1 4 0 Q 9 12 2 1 4 0') === [\n *   ['M', 3, 4],\n *   ['Q', 3, 5, 2, 1, 4, 0],\n *   ['Q', 9, 12, 2, 1, 4, 0],\n * ];\n *\n */\nexport const parsePath = (pathString: string): TComplexPathData => {\n  // clean the string\n  // add spaces around the numbers\n  pathString = cleanupSvgAttribute(pathString);\n\n  const res: TComplexPathData = [];\n  for (let [matchStr] of pathString.matchAll(rePathCmdAll)) {\n    const chain: TComplexPathData = [];\n    let paramArr: RegExpExecArray | null;\n    do {\n      paramArr = rePathCmd.exec(matchStr);\n      if (!paramArr) {\n        break;\n      }\n      // ignore undefined match groups\n      const filteredGroups = paramArr.filter((g) => g);\n      // remove the first element from the match array since it's just the whole command\n      filteredGroups.shift();\n      // if we can't parse the number, just interpret it as a string\n      // (since it's probably the path command)\n      const command = filteredGroups.map((g) => {\n        const numParse = Number.parseFloat(g);\n        if (Number.isNaN(numParse)) {\n          return g;\n        } else {\n          return numParse;\n        }\n      });\n      chain.push(command as any);\n      // stop now if it's a z command\n      if (filteredGroups.length <= 1) {\n        break;\n      }\n      // remove the last part of the chained command\n      filteredGroups.shift();\n      // ` ?` is to support commands with optional spaces between flags\n      matchStr = matchStr.replace(\n        new RegExp(`${filteredGroups.join(' ?')} ?$`),\n        ''\n      );\n    } while (paramArr);\n    // add the chain, convert multiple m's to l's in the process\n    chain.reverse().forEach((c, idx) => {\n      const transformed = repeatedCommands[c[0]];\n      if (idx > 0 && (transformed == 'l' || transformed == 'L')) {\n        c[0] = transformed;\n      }\n      res.push(c);\n    });\n  }\n  return res;\n};\n\n/**\n *\n * Converts points to a smooth SVG path\n * @param {XY[]} points Array of points\n * @param {number} [correction] Apply a correction to the path (usually we use `width / 1000`). If value is undefined 0 is used as the correction value.\n * @return {(string|number)[][]} An array of SVG path commands\n */\nexport const getSmoothPathFromPoints = (\n  points: Point[],\n  correction = 0\n): TSimplePathData => {\n  let p1 = new Point(points[0]),\n    p2 = new Point(points[1]),\n    multSignX = 1,\n    multSignY = 0;\n  const path: TSimplePathData = [],\n    len = points.length,\n    manyPoints = len > 2;\n\n  if (manyPoints) {\n    multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1;\n    multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1;\n  }\n  path.push([\n    'M',\n    p1.x - multSignX * correction,\n    p1.y - multSignY * correction,\n  ]);\n  let i;\n  for (i = 1; i < len; i++) {\n    if (!p1.eq(p2)) {\n      const midPoint = p1.midPointFrom(p2);\n      // p1 is our bezier control point\n      // midpoint is our endpoint\n      // start point is p(i-1) value.\n      path.push(['Q', p1.x, p1.y, midPoint.x, midPoint.y]);\n    }\n    p1 = points[i];\n    if (i + 1 < points.length) {\n      p2 = points[i + 1];\n    }\n  }\n  if (manyPoints) {\n    multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1;\n    multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1;\n  }\n  path.push([\n    'L',\n    p1.x + multSignX * correction,\n    p1.y + multSignY * correction,\n  ]);\n  return path;\n};\n\n/**\n * Transform a path by transforming each segment.\n * it has to be a simplified path or it won't work.\n * WARNING: this depends from pathOffset for correct operation\n * @param {TSimplePathData} path fabricJS parsed and simplified path commands\n * @param {TMat2D} transform matrix that represent the transformation\n * @param {Point} [pathOffset] `Path.pathOffset`\n * @returns {TSimplePathData} the transformed path\n */\nexport const transformPath = (\n  path: TSimplePathData,\n  transform: TMat2D,\n  pathOffset: Point\n): TSimplePathData => {\n  if (pathOffset) {\n    transform = multiplyTransformMatrices(transform, [\n      1,\n      0,\n      0,\n      1,\n      -pathOffset.x,\n      -pathOffset.y,\n    ]);\n  }\n  return path.map((pathSegment) => {\n    const newSegment: TSimpleParsedCommand = [...pathSegment];\n    for (let i = 1; i < pathSegment.length - 1; i += 2) {\n      // TODO: is there a way to get around casting to any?\n      const { x, y } = transformPoint(\n        {\n          x: pathSegment[i] as number,\n          y: pathSegment[i + 1] as number,\n        },\n        transform\n      );\n      newSegment[i] = x;\n      newSegment[i + 1] = y;\n    }\n    return newSegment;\n  });\n};\n\n/**\n * Returns an array of path commands to create a regular polygon\n * @param {number} numVertexes\n * @param {number} radius\n * @returns {TSimplePathData} An array of SVG path commands\n */\nexport const getRegularPolygonPath = (\n  numVertexes: number,\n  radius: number\n): TSimplePathData => {\n  const interiorAngle = (Math.PI * 2) / numVertexes;\n  // rotationAdjustment rotates the path by 1/2 the interior angle so that the polygon always has a flat side on the bottom\n  // This isn't strictly necessary, but it's how we tend to think of and expect polygons to be drawn\n  let rotationAdjustment = -halfPI;\n  if (numVertexes % 2 === 0) {\n    rotationAdjustment += interiorAngle / 2;\n  }\n  const d = new Array(numVertexes + 1);\n  for (let i = 0; i < numVertexes; i++) {\n    const rad = i * interiorAngle + rotationAdjustment;\n    const { x, y } = new Point(cos(rad), sin(rad)).scalarMultiply(radius);\n    d[i] = [i === 0 ? 'M' : 'L', x, y];\n  }\n  d[numVertexes] = ['Z'];\n  return d;\n};\n\n/**\n * Join path commands to go back to svg format\n * @param {TSimplePathData} pathData fabricJS parsed path commands\n * @param {number} fractionDigits number of fraction digits to \"leave\"\n * @return {String} joined path 'M 0 0 L 20 30'\n */\nexport const joinPath = (pathData: TSimplePathData, fractionDigits?: number) =>\n  pathData\n    .map((segment) => {\n      return segment\n        .map((arg, i) => {\n          if (i === 0) return arg;\n          return fractionDigits === undefined\n            ? arg\n            : toFixed(arg, fractionDigits);\n        })\n        .join(' ');\n    })\n    .join(' ');\n"],"names":["repeatedCommands","m","M","segmentToBezier","theta1","theta2","cosTh","sinTh","rx","ry","cx1","cy1","mT","fromX","fromY","costh1","cos","sinth1","sin","costh2","sinth2","toX","toY","calcVectorAngle","ux","uy","vx","vy","ta","Math","atan2","tb","PI","getBoundsOfCurve","begx","begy","cp1x","cp1y","cp2x","cp2y","endx","endy","argsString","config","cachesBoundsOfCurve","arguments","join","cache","boundsOfCurveCache","sqrt","abs","tvalues","bounds","b","a","c","i","t","push","b2ac","sqrtb2ac","t1","t2","j","length","jlen","iterator","getPointOnCubicBezierIterator","x","y","result","Point","min","max","fromArcToBeziers","fx","fy","_ref","_","rot","large","sweep","tx","ty","segsNorm","arcToSegments","rotateX","root","theta","PiBy180","sinTheta","px","py","rx2","ry2","py2","px2","pl","_rx","_ry","s","cx","cy","mTheta","dtheta","segments","ceil","Array","mDelta","th3","len","makePathSimpler","path","x1","y1","destinationPath","previous","controlX","controlY","parsedCommand","current","converted","forEach","calcLineLength","x2","y2","pct","c1","c2","CB2","c3","CB3","c4","CB4","QB1","QB2","QB3","getTangentCubicIterator","p1x","p1y","p2x","p2y","p3x","p3y","p4x","p4y","qb1","qb2","qb3","tangentX","tangentY","getPointOnQuadraticBezierIterator","getTangentQuadraticIterator","invT","pathIterator","tempP","tmpLen","perc","p","findPercentageForDistance","segInfo","distance","nextLen","_objectSpread","nextStep","lastPerc","angleFinder","angle","getPathSegmentsInfo","tempInfo","totalLength","info","basicInfo","command","destX","destY","getPointOnPath","infos","undefined","segPercent","segment","lerp","rePathCmdAll","RegExp","rePathCommand","rePathCmd","parsePath","pathString","cleanupSvgAttribute","res","matchStr","matchAll","chain","paramArr","exec","filteredGroups","filter","g","shift","map","numParse","Number","parseFloat","isNaN","replace","concat","reverse","idx","transformed","getSmoothPathFromPoints","points","correction","p1","p2","multSignX","multSignY","manyPoints","eq","midPoint","midPointFrom","transformPath","transform","pathOffset","multiplyTransformMatrices","pathSegment","newSegment","transformPoint","getRegularPolygonPath","numVertexes","radius","interiorAngle","rotationAdjustment","halfPI","d","rad","scalarMultiply","joinPath","pathData","fractionDigits","arg","toFixed"],"mappings":"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"}