UNPKG

tldraw

Version:

A tiny little drawing editor.

5 lines • 51.4 kB
{ "version": 3, "sources": ["../../../../src/lib/shapes/shared/PathBuilder.tsx"], "sourcesContent": ["import {\n\tapproximately,\n\tassert,\n\tassertExists,\n\tclamp,\n\tCubicBezier2d,\n\tEdge2d,\n\texhaustiveSwitchError,\n\tGeometry2d,\n\tGeometry2dFilters,\n\tGeometry2dOptions,\n\tgetPerfectDashProps,\n\tgetVerticesCountForArcLength,\n\tGroup2d,\n\tmodulate,\n\tPerfectDashTerminal,\n\trng,\n\ttoDomPrecision,\n\tVec,\n\tVecLike,\n\tVecModel,\n} from '@tldraw/editor'\nimport { ReactNode, SVGProps } from 'react'\n\n/** @public */\nexport interface BasePathBuilderOpts {\n\tstrokeWidth: number\n\tforceSolid?: boolean\n\tonlyFilled?: boolean\n\tprops?: SVGProps<SVGPathElement & SVGGElement>\n}\n\n/** @public */\nexport interface SolidPathBuilderOpts extends BasePathBuilderOpts {\n\tstyle: 'solid'\n}\n\n/** @public */\nexport interface DashedPathBuilderOpts extends BasePathBuilderOpts {\n\tstyle: 'dashed' | 'dotted'\n\tsnap?: number\n\tend?: PerfectDashTerminal\n\tstart?: PerfectDashTerminal\n\tlengthRatio?: number\n}\n\n/** @public */\nexport interface DrawPathBuilderDOpts {\n\tstrokeWidth: number\n\trandomSeed: string\n\toffset?: number\n\troundness?: number\n\tpasses?: number\n\tonlyFilled?: boolean\n}\n\n/** @public */\nexport interface DrawPathBuilderOpts extends BasePathBuilderOpts, DrawPathBuilderDOpts {\n\tstyle: 'draw'\n}\n\n/** @public */\nexport type PathBuilderOpts = SolidPathBuilderOpts | DashedPathBuilderOpts | DrawPathBuilderOpts\n\n/** @public */\nexport interface PathBuilderCommandOpts {\n\t/**\n\t * When converting to a draw-style line, how much offset from the original point should be\n\t * applied?\n\t */\n\toffset?: number\n\t/**\n\t * When converting to a draw-style line, how much roundness should be applied to the end of this\n\t * line?\n\t */\n\troundness?: number\n\t/**\n\t * When converting to a dash- or dot-style line, should the current segment be merged with the\n\t * previous segment when calculating the dash pattern? This is false by default, meaning each\n\t * command will start/end on a dash/dot boundary.\n\t */\n\tmergeWithPrevious?: boolean\n}\n\n/** @internal */\nexport interface PathBuilderCommandInfo {\n\ttangentStart: VecModel\n\ttangentEnd: VecModel\n\tlength: number\n}\n\n/** @internal */\nexport interface PathBuilderCommandBase {\n\topts?: PathBuilderCommandOpts\n\tx: number\n\ty: number\n\tisClose: boolean\n\t_info?: PathBuilderCommandInfo\n}\n\n/** @public */\nexport interface PathBuilderLineOpts extends PathBuilderCommandOpts {\n\tgeometry?: Omit<Geometry2dOptions, 'isClosed'> | false\n\tdashStart?: PerfectDashTerminal\n\tdashEnd?: PerfectDashTerminal\n}\n\n/** @internal */\nexport interface MoveToPathBuilderCommand extends PathBuilderCommandBase {\n\ttype: 'move'\n\tcloseIdx: number | null\n\topts?: PathBuilderLineOpts\n}\n\n/** @internal */\nexport interface LineToPathBuilderCommand extends PathBuilderCommandBase {\n\ttype: 'line'\n}\n\n/** @internal */\nexport interface CubicBezierToPathBuilderCommand extends PathBuilderCommandBase {\n\ttype: 'cubic'\n\tcp1: VecModel\n\tcp2: VecModel\n\tresolution?: number\n}\n\n/** @internal */\nexport type PathBuilderCommand =\n\t| MoveToPathBuilderCommand\n\t| LineToPathBuilderCommand\n\t| CubicBezierToPathBuilderCommand\n\n/** @public */\nexport interface PathBuilderToDOpts {\n\tstartIdx?: number\n\tendIdx?: number\n\tonlyFilled?: boolean\n}\n\n/** @public */\nexport class PathBuilder {\n\tstatic lineThroughPoints(\n\t\tpoints: VecLike[],\n\t\topts?: PathBuilderLineOpts & { endOffsets?: number }\n\t) {\n\t\tconst path = new PathBuilder()\n\t\tpath.moveTo(points[0].x, points[0].y, { ...opts, offset: opts?.endOffsets ?? opts?.offset })\n\t\tfor (let i = 1; i < points.length; i++) {\n\t\t\tconst isLast = i === points.length - 1\n\t\t\tpath.lineTo(points[i].x, points[i].y, isLast ? { offset: opts?.endOffsets } : undefined)\n\t\t}\n\t\treturn path\n\t}\n\n\tstatic cubicSplineThroughPoints(\n\t\tpoints: VecLike[],\n\t\topts?: PathBuilderLineOpts & { endOffsets?: number }\n\t) {\n\t\tconst path = new PathBuilder()\n\t\tconst len = points.length\n\t\tconst last = len - 2\n\t\tconst k = 1.25\n\n\t\tpath.moveTo(points[0].x, points[0].y, { ...opts, offset: opts?.endOffsets ?? opts?.offset })\n\n\t\tfor (let i = 0; i < len - 1; i++) {\n\t\t\tconst p0 = i === 0 ? points[0] : points[i - 1]\n\t\t\tconst p1 = points[i]\n\t\t\tconst p2 = points[i + 1]\n\t\t\tconst p3 = i === last ? p2 : points[i + 2]\n\n\t\t\tlet cp1x, cp1y, cp2x, cp2y\n\t\t\tif (i === 0) {\n\t\t\t\tcp1x = p0.x\n\t\t\t\tcp1y = p0.y\n\t\t\t} else {\n\t\t\t\tcp1x = p1.x + ((p2.x - p0.x) / 6) * k\n\t\t\t\tcp1y = p1.y + ((p2.y - p0.y) / 6) * k\n\t\t\t}\n\n\t\t\tlet pointOpts = undefined\n\t\t\tif (i === last) {\n\t\t\t\tcp2x = p2.x\n\t\t\t\tcp2y = p2.y\n\t\t\t\tpointOpts = { offset: opts?.endOffsets }\n\t\t\t} else {\n\t\t\t\tcp2x = p2.x - ((p3.x - p1.x) / 6) * k\n\t\t\t\tcp2y = p2.y - ((p3.y - p1.y) / 6) * k\n\t\t\t}\n\n\t\t\tpath.cubicBezierTo(p2.x, p2.y, cp1x, cp1y, cp2x, cp2y, pointOpts)\n\t\t}\n\n\t\treturn path\n\t}\n\n\tconstructor() {}\n\n\t/** @internal */\n\tcommands: PathBuilderCommand[] = []\n\n\tprivate lastMoveTo: MoveToPathBuilderCommand | null = null\n\tprivate assertHasMoveTo() {\n\t\tassert(this.lastMoveTo, 'Start an SVGPathBuilder with `.moveTo()`')\n\t\treturn this.lastMoveTo\n\t}\n\n\tmoveTo(x: number, y: number, opts?: PathBuilderLineOpts) {\n\t\tthis.lastMoveTo = { type: 'move', x, y, closeIdx: null, isClose: false, opts }\n\t\tthis.commands.push(this.lastMoveTo)\n\t\treturn this\n\t}\n\n\tlineTo(x: number, y: number, opts?: PathBuilderCommandOpts) {\n\t\tthis.assertHasMoveTo()\n\t\tthis.commands.push({ type: 'line', x, y, isClose: false, opts })\n\t\treturn this\n\t}\n\n\tcircularArcTo(\n\t\tradius: number,\n\t\tlargeArcFlag: boolean,\n\t\tsweepFlag: boolean,\n\t\tx2: number,\n\t\ty2: number,\n\t\topts?: PathBuilderCommandOpts\n\t) {\n\t\treturn this.arcTo(radius, radius, largeArcFlag, sweepFlag, 0, x2, y2, opts)\n\t}\n\n\tarcTo(\n\t\trx: number,\n\t\try: number,\n\t\tlargeArcFlag: boolean,\n\t\tsweepFlag: boolean,\n\t\txAxisRotationRadians: number,\n\t\tx2: number,\n\t\ty2: number,\n\t\topts?: PathBuilderCommandOpts\n\t) {\n\t\t// As arc flags make them very sensitive to offsets when we render them in draw mode, we\n\t\t// approximate arcs by converting them to up to 4 (1 per 90\u00B0 segment) cubic bezier curves.\n\t\t// This algorithm is a Claude special:\n\t\t// https://claude.ai/public/artifacts/5ea0bf18-4afb-4b3d-948d-31b8a77ef1e2\n\n\t\tthis.assertHasMoveTo()\n\n\t\tconst x1 = this.commands[this.commands.length - 1].x\n\t\tconst y1 = this.commands[this.commands.length - 1].y\n\n\t\t// If the endpoints are identical, don't add a command\n\t\tif (x1 === x2 && y1 === y2) {\n\t\t\treturn this\n\t\t}\n\n\t\t// If rx or ry is 0, return a straight line\n\t\tif (rx === 0 || ry === 0) {\n\t\t\treturn this.lineTo(x2, y2, opts)\n\t\t}\n\n\t\t// Convert angle from degrees to radians\n\t\tconst phi = xAxisRotationRadians\n\t\tconst sinPhi = Math.sin(phi)\n\t\tconst cosPhi = Math.cos(phi)\n\n\t\t// Ensure rx and ry are positive\n\t\tlet rx1 = Math.abs(rx)\n\t\tlet ry1 = Math.abs(ry)\n\n\t\t// Step 1: Compute (x1', y1') - transform from ellipse coordinate system to unit circle\n\t\tconst dx = (x1 - x2) / 2\n\t\tconst dy = (y1 - y2) / 2\n\t\tconst x1p = cosPhi * dx + sinPhi * dy\n\t\tconst y1p = -sinPhi * dx + cosPhi * dy\n\n\t\t// Correction of out-of-range radii\n\t\tconst lambda = (x1p * x1p) / (rx1 * rx1) + (y1p * y1p) / (ry1 * ry1)\n\t\tif (lambda > 1) {\n\t\t\tconst sqrtLambda = Math.sqrt(lambda)\n\t\t\trx1 *= sqrtLambda\n\t\t\try1 *= sqrtLambda\n\t\t}\n\n\t\t// Step 2: Compute (cx', cy') - center of ellipse in transformed system\n\t\tconst sign = largeArcFlag !== sweepFlag ? 1 : -1\n\n\t\tconst term = rx1 * rx1 * ry1 * ry1 - rx1 * rx1 * y1p * y1p - ry1 * ry1 * x1p * x1p\n\t\tconst numerator = rx1 * rx1 * y1p * y1p + ry1 * ry1 * x1p * x1p\n\n\t\tlet radicand = term / numerator\n\t\tradicand = radicand < 0 ? 0 : radicand\n\n\t\tconst coef = sign * Math.sqrt(radicand)\n\n\t\tconst cxp = coef * ((rx1 * y1p) / ry1)\n\t\tconst cyp = coef * (-(ry1 * x1p) / rx1)\n\n\t\t// Step 3: Compute (cx, cy) from (cx', cy') - transform back to original coordinate system\n\t\tconst cx = cosPhi * cxp - sinPhi * cyp + (x1 + x2) / 2\n\t\tconst cy = sinPhi * cxp + cosPhi * cyp + (y1 + y2) / 2\n\n\t\t// Step 4: Compute the start and end angles\n\t\tconst ux = (x1p - cxp) / rx1\n\t\tconst uy = (y1p - cyp) / ry1\n\t\tconst vx = (-x1p - cxp) / rx1\n\t\tconst vy = (-y1p - cyp) / ry1\n\n\t\tconst startAngle = Math.atan2(uy, ux)\n\t\tlet endAngle = Math.atan2(vy, vx)\n\n\t\t// Ensure correct sweep direction\n\t\tif (!sweepFlag && endAngle > startAngle) {\n\t\t\tendAngle -= 2 * Math.PI\n\t\t} else if (sweepFlag && endAngle < startAngle) {\n\t\t\tendAngle += 2 * Math.PI\n\t\t}\n\n\t\t// Calculate the sweep angle\n\t\tconst sweepAngle = endAngle - startAngle\n\n\t\t// Calculate the approximate arc length. General ellipse arc length is expensive - there's\n\t\t// no closed form solution, so we have to do iterative numerical approximation. As we only\n\t\t// use this to control the resolution of later approximations, let's cheat and just use the\n\t\t// circular arc length with the largest radius:\n\t\tconst approximateArcLength = Math.max(rx1, ry1) * Math.abs(sweepAngle)\n\n\t\t// Approximate the arc using cubic bezier curves\n\t\tconst numSegments = Math.min(4, Math.ceil(Math.abs(sweepAngle) / (Math.PI / 2)))\n\t\tconst resolutionPerSegment = Math.ceil(\n\t\t\tgetVerticesCountForArcLength(approximateArcLength) / numSegments\n\t\t)\n\t\tconst anglePerSegment = sweepAngle / numSegments\n\n\t\t// Helper function to compute point on ellipse\n\t\tconst ellipsePoint = (angle: number) => {\n\t\t\treturn {\n\t\t\t\tx: cx + rx1 * Math.cos(angle) * cosPhi - ry1 * Math.sin(angle) * sinPhi,\n\t\t\t\ty: cy + rx1 * Math.cos(angle) * sinPhi + ry1 * Math.sin(angle) * cosPhi,\n\t\t\t}\n\t\t}\n\n\t\t// Helper function to compute derivative (tangent vector) at a point on the ellipse\n\t\tconst ellipseDerivative = (angle: number) => {\n\t\t\treturn {\n\t\t\t\tx: -rx1 * Math.sin(angle) * cosPhi - ry1 * Math.cos(angle) * sinPhi,\n\t\t\t\ty: -rx1 * Math.sin(angle) * sinPhi + ry1 * Math.cos(angle) * cosPhi,\n\t\t\t}\n\t\t}\n\n\t\t// Generate cubic bezier approximations\n\t\tfor (let i = 0; i < numSegments; i++) {\n\t\t\tconst theta1 = startAngle + i * anglePerSegment\n\t\t\tconst theta2 = startAngle + (i + 1) * anglePerSegment\n\t\t\tconst deltaTheta = theta2 - theta1\n\n\t\t\tconst start = ellipsePoint(theta1)\n\t\t\tconst end = ellipsePoint(theta2)\n\n\t\t\t// Get the derivative at the start and end points\n\t\t\tconst d1 = ellipseDerivative(theta1)\n\t\t\tconst d2 = ellipseDerivative(theta2)\n\n\t\t\t// Calculate the length of the tangent handles\n\t\t\t// This is a key factor for the accuracy of the approximation\n\t\t\t// For a 90\u00B0 arc, the handle length should be 4/3 * tan(\u03C0/8) * r\n\t\t\t// For smaller arcs, we scale this value by the angle ratio\n\t\t\tconst handleScale = (4 / 3) * Math.tan(deltaTheta / 4)\n\n\t\t\t// Create control points that are tangent to the ellipse at the endpoints\n\t\t\tconst cp1x = start.x + handleScale * d1.x\n\t\t\tconst cp1y = start.y + handleScale * d1.y\n\n\t\t\tconst cp2x = end.x - handleScale * d2.x\n\t\t\tconst cp2y = end.y - handleScale * d2.y\n\n\t\t\tconst bezierOpts = i === 0 ? opts : { ...opts, mergeWithPrevious: true }\n\t\t\tthis.cubicBezierToWithResolution(\n\t\t\t\tend.x,\n\t\t\t\tend.y,\n\t\t\t\tcp1x,\n\t\t\t\tcp1y,\n\t\t\t\tcp2x,\n\t\t\t\tcp2y,\n\t\t\t\tbezierOpts,\n\t\t\t\tresolutionPerSegment\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\tcubicBezierTo(\n\t\tx: number,\n\t\ty: number,\n\t\tcp1X: number,\n\t\tcp1Y: number,\n\t\tcp2X: number,\n\t\tcp2Y: number,\n\t\topts?: PathBuilderCommandOpts\n\t) {\n\t\treturn this.cubicBezierToWithResolution(x, y, cp1X, cp1Y, cp2X, cp2Y, opts)\n\t}\n\tprivate cubicBezierToWithResolution(\n\t\tx: number,\n\t\ty: number,\n\t\tcp1X: number,\n\t\tcp1Y: number,\n\t\tcp2X: number,\n\t\tcp2Y: number,\n\t\topts?: PathBuilderCommandOpts,\n\t\tresolution?: number\n\t) {\n\t\tthis.assertHasMoveTo()\n\t\tthis.commands.push({\n\t\t\ttype: 'cubic',\n\t\t\tx,\n\t\t\ty,\n\t\t\tcp1: { x: cp1X, y: cp1Y },\n\t\t\tcp2: { x: cp2X, y: cp2Y },\n\t\t\tisClose: false,\n\t\t\topts,\n\t\t\tresolution,\n\t\t})\n\t\treturn this\n\t}\n\n\tclose() {\n\t\tconst lastMoveTo = this.assertHasMoveTo()\n\t\tconst lastCommand = this.commands[this.commands.length - 1]\n\n\t\tif (approximately(lastMoveTo.x, lastCommand.x) && approximately(lastMoveTo.y, lastCommand.y)) {\n\t\t\tlastCommand.isClose = true\n\t\t} else {\n\t\t\tthis.commands.push({\n\t\t\t\ttype: 'line',\n\t\t\t\tx: lastMoveTo.x,\n\t\t\t\ty: lastMoveTo.y,\n\t\t\t\tisClose: true,\n\t\t\t})\n\t\t}\n\n\t\tlastMoveTo.closeIdx = this.commands.length - 1\n\t\tthis.lastMoveTo = null\n\t\treturn this\n\t}\n\n\ttoD(opts: PathBuilderToDOpts = {}) {\n\t\tconst { startIdx = 0, endIdx = this.commands.length, onlyFilled = false } = opts\n\t\tconst parts = []\n\n\t\tlet isSkippingCurrentLine = false\n\n\t\tlet didAddMove = false\n\t\tlet didAddNaturalMove = false\n\n\t\tconst addMoveIfNeeded = (i: number) => {\n\t\t\tif (didAddMove || i === 0) return\n\t\t\tdidAddMove = true\n\t\t\tconst command = this.commands[i - 1]\n\t\t\tparts.push('M', toDomPrecision(command.x), toDomPrecision(command.y))\n\t\t}\n\n\t\tfor (let i = startIdx; i < endIdx; i++) {\n\t\t\tconst command = this.commands[i]\n\t\t\tswitch (command.type) {\n\t\t\t\tcase 'move': {\n\t\t\t\t\tconst isFilled =\n\t\t\t\t\t\tcommand.opts?.geometry === false ? false : (command.opts?.geometry?.isFilled ?? false)\n\t\t\t\t\tif (onlyFilled && !isFilled) {\n\t\t\t\t\t\tisSkippingCurrentLine = true\n\t\t\t\t\t} else {\n\t\t\t\t\t\tisSkippingCurrentLine = false\n\t\t\t\t\t\tdidAddMove = true\n\t\t\t\t\t\tdidAddNaturalMove = true\n\t\t\t\t\t\tparts.push('M', toDomPrecision(command.x), toDomPrecision(command.y))\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'line':\n\t\t\t\t\tif (isSkippingCurrentLine) break\n\t\t\t\t\taddMoveIfNeeded(i)\n\t\t\t\t\tif (command.isClose && didAddNaturalMove) {\n\t\t\t\t\t\tparts.push('Z')\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparts.push('L', toDomPrecision(command.x), toDomPrecision(command.y))\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\tcase 'cubic':\n\t\t\t\t\tif (isSkippingCurrentLine) break\n\t\t\t\t\taddMoveIfNeeded(i)\n\t\t\t\t\tparts.push(\n\t\t\t\t\t\t'C',\n\t\t\t\t\t\ttoDomPrecision(command.cp1.x),\n\t\t\t\t\t\ttoDomPrecision(command.cp1.y),\n\t\t\t\t\t\ttoDomPrecision(command.cp2.x),\n\t\t\t\t\t\ttoDomPrecision(command.cp2.y),\n\t\t\t\t\t\ttoDomPrecision(command.x),\n\t\t\t\t\t\ttoDomPrecision(command.y)\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(command, 'type')\n\t\t\t}\n\t\t}\n\t\treturn parts.join(' ')\n\t}\n\n\ttoSvg(opts: PathBuilderOpts) {\n\t\tif (opts.forceSolid) {\n\t\t\treturn this.toSolidSvg(opts)\n\t\t}\n\t\tswitch (opts.style) {\n\t\t\tcase 'solid':\n\t\t\t\treturn this.toSolidSvg(opts)\n\t\t\tcase 'dashed':\n\t\t\tcase 'dotted':\n\t\t\t\treturn this.toDashedSvg(opts)\n\t\t\tcase 'draw': {\n\t\t\t\tconst d = this.toDrawSvg(opts)\n\t\t\t\treturn d\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\texhaustiveSwitchError(opts, 'style')\n\t\t}\n\t}\n\n\ttoPath2D(opts: PathBuilderOpts): Path2D {\n\t\tif (opts.forceSolid || opts.style === 'solid') {\n\t\t\treturn new Path2D(this.toD({ onlyFilled: opts.onlyFilled }))\n\t\t}\n\t\tif (opts.style === 'draw') {\n\t\t\treturn new Path2D(this.toDrawD(opts))\n\t\t}\n\n\t\treturn new Path2D(this.toD({ onlyFilled: opts.onlyFilled }))\n\t}\n\n\ttoGeometry(): PathBuilderGeometry2d | Group2d {\n\t\tconst geometries = []\n\n\t\tlet current: null | {\n\t\t\tstartIdx: number\n\t\t\tmoveCommand: MoveToPathBuilderCommand\n\t\t\tisClosed: boolean\n\t\t\topts?: PathBuilderLineOpts\n\t\t} = null\n\t\tfor (let i = 0; i < this.commands.length; i++) {\n\t\t\tconst command = this.commands[i]\n\n\t\t\tif (command.type === 'move') {\n\t\t\t\tif (current && current.opts?.geometry !== false) {\n\t\t\t\t\tgeometries.push(\n\t\t\t\t\t\tnew PathBuilderGeometry2d(this, current.startIdx, i, {\n\t\t\t\t\t\t\t...current.opts?.geometry,\n\t\t\t\t\t\t\tisFilled: current.opts?.geometry?.isFilled ?? false,\n\t\t\t\t\t\t\tisClosed: current.moveCommand.closeIdx !== null,\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tcurrent = { startIdx: i, moveCommand: command, opts: command.opts, isClosed: false }\n\t\t\t}\n\n\t\t\tif (command.isClose) {\n\t\t\t\tassert(current, 'No current move command')\n\t\t\t\tcurrent.isClosed = true\n\t\t\t}\n\t\t}\n\n\t\tif (current && current.opts?.geometry !== false) {\n\t\t\tgeometries.push(\n\t\t\t\tnew PathBuilderGeometry2d(this, current.startIdx, this.commands.length, {\n\t\t\t\t\t...current.opts?.geometry,\n\t\t\t\t\tisFilled: current.opts?.geometry?.isFilled ?? false,\n\t\t\t\t\tisClosed: current.moveCommand.closeIdx !== null,\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\n\t\tassert(geometries.length > 0)\n\t\tif (geometries.length === 1) return geometries[0]\n\t\treturn new Group2d({ children: geometries })\n\t}\n\n\tprivate toSolidSvg(opts: PathBuilderOpts) {\n\t\tconst { strokeWidth, props } = opts\n\n\t\treturn (\n\t\t\t<path strokeWidth={strokeWidth} d={this.toD({ onlyFilled: opts.onlyFilled })} {...props} />\n\t\t)\n\t}\n\n\tprivate toDashedSvg(opts: DashedPathBuilderOpts) {\n\t\tconst {\n\t\t\tstyle,\n\t\t\tstrokeWidth,\n\t\t\tsnap,\n\t\t\tlengthRatio,\n\t\t\tprops: { markerStart, markerEnd, ...props } = {},\n\t\t} = opts\n\n\t\tconst parts: ReactNode[] = []\n\n\t\tlet isCurrentPathClosed = false\n\t\tlet isSkippingCurrentLine = false\n\t\tlet currentLineOpts: PathBuilderLineOpts | undefined = undefined\n\n\t\tlet currentRun: {\n\t\t\tstartIdx: number\n\t\t\tendIdx: number\n\t\t\tisFirst: boolean\n\t\t\tisLast: boolean\n\t\t\tlength: number\n\t\t\tlineOpts: PathBuilderLineOpts | undefined\n\t\t\tpathIsClosed: boolean\n\t\t} | null = null\n\n\t\tconst addCurrentRun = () => {\n\t\t\tif (!currentRun) return\n\t\t\tconst { startIdx, endIdx, isFirst, isLast, length, lineOpts, pathIsClosed } = currentRun\n\t\t\tcurrentRun = null\n\n\t\t\tif (startIdx === endIdx && this.commands[startIdx].type === 'move') return\n\n\t\t\tconst start = lineOpts?.dashStart ?? opts.start\n\t\t\tconst end = lineOpts?.dashEnd ?? opts.end\n\t\t\tconst { strokeDasharray, strokeDashoffset } = getPerfectDashProps(length, strokeWidth, {\n\t\t\t\tstyle,\n\t\t\t\tsnap,\n\t\t\t\tlengthRatio,\n\t\t\t\tstart: isFirst ? (start ?? (pathIsClosed ? 'outset' : 'none')) : 'outset',\n\t\t\t\tend: isLast ? (end ?? (pathIsClosed ? 'outset' : 'none')) : 'outset',\n\t\t\t})\n\n\t\t\tconst d = this.toD({ startIdx, endIdx: endIdx + 1 })\n\t\t\tparts.push(\n\t\t\t\t<path\n\t\t\t\t\tkey={parts.length}\n\t\t\t\t\td={d}\n\t\t\t\t\tstrokeDasharray={strokeDasharray}\n\t\t\t\t\tstrokeDashoffset={strokeDashoffset}\n\t\t\t\t\tmarkerStart={isFirst ? markerStart : undefined}\n\t\t\t\t\tmarkerEnd={isLast ? markerEnd : undefined}\n\t\t\t\t/>\n\t\t\t)\n\t\t}\n\n\t\tfor (let i = 0; i < this.commands.length; i++) {\n\t\t\tconst command = this.commands[i]\n\t\t\tconst lastCommand = this.commands[i - 1]\n\t\t\tif (command.type === 'move') {\n\t\t\t\tisCurrentPathClosed = command.closeIdx !== null\n\t\t\t\tconst isFilled =\n\t\t\t\t\tcommand.opts?.geometry === false ? false : (command.opts?.geometry?.isFilled ?? false)\n\t\t\t\tif (opts.onlyFilled && !isFilled) {\n\t\t\t\t\tisSkippingCurrentLine = true\n\t\t\t\t} else {\n\t\t\t\t\tisSkippingCurrentLine = false\n\t\t\t\t\tcurrentLineOpts = command.opts\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (isSkippingCurrentLine) continue\n\n\t\t\tconst segmentLength = this.calculateSegmentLength(lastCommand, command)\n\t\t\tconst isFirst = lastCommand.type === 'move'\n\t\t\tconst isLast =\n\t\t\t\tcommand.isClose || i === this.commands.length - 1 || this.commands[i + 1]?.type === 'move'\n\n\t\t\tif (currentRun && command.opts?.mergeWithPrevious) {\n\t\t\t\tcurrentRun.length += segmentLength\n\t\t\t\tcurrentRun.endIdx = i\n\t\t\t\tcurrentRun.isLast = isLast\n\t\t\t} else {\n\t\t\t\taddCurrentRun()\n\t\t\t\tcurrentRun = {\n\t\t\t\t\tstartIdx: i,\n\t\t\t\t\tendIdx: i,\n\t\t\t\t\tisFirst,\n\t\t\t\t\tisLast,\n\t\t\t\t\tlength: segmentLength,\n\t\t\t\t\tlineOpts: currentLineOpts,\n\t\t\t\t\tpathIsClosed: isCurrentPathClosed,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\taddCurrentRun()\n\n\t\treturn (\n\t\t\t<g strokeWidth={strokeWidth} {...props}>\n\t\t\t\t{parts}\n\t\t\t</g>\n\t\t)\n\t}\n\n\tprivate toDrawSvg(opts: DrawPathBuilderOpts) {\n\t\treturn <path strokeWidth={opts.strokeWidth} d={this.toDrawD(opts)} {...opts.props} />\n\t}\n\n\ttoDrawD(opts: DrawPathBuilderDOpts) {\n\t\tconst {\n\t\t\tstrokeWidth,\n\t\t\trandomSeed,\n\t\t\toffset: defaultOffset = strokeWidth / 3,\n\t\t\troundness: defaultRoundness = strokeWidth * 2,\n\t\t\tpasses = 2,\n\t\t\tonlyFilled = false,\n\t\t} = opts\n\n\t\tconst parts = []\n\n\t\tconst commandInfo = this.getCommandInfo()\n\n\t\t// for each command, we draw the line for the command, plus the corner to the next command.\n\t\tconst drawCommands = []\n\t\tlet lastMoveCommandIdx = null\n\t\tfor (let i = 0; i < this.commands.length; i++) {\n\t\t\tconst command = this.commands[i]\n\t\t\tconst offset = command.opts?.offset ?? defaultOffset\n\t\t\tconst roundness = command.opts?.roundness ?? defaultRoundness\n\n\t\t\tif (command.type === 'move') {\n\t\t\t\tlastMoveCommandIdx = i\n\t\t\t}\n\n\t\t\tconst nextIdx = command.isClose\n\t\t\t\t? assertExists(lastMoveCommandIdx) + 1\n\t\t\t\t: !this.commands[i + 1] || this.commands[i + 1].type === 'move'\n\t\t\t\t\t? undefined\n\t\t\t\t\t: i + 1\n\n\t\t\tconst nextInfo =\n\t\t\t\tnextIdx !== undefined && this.commands[nextIdx] && this.commands[nextIdx]?.type !== 'move'\n\t\t\t\t\t? commandInfo[nextIdx]\n\t\t\t\t\t: undefined\n\n\t\t\tconst currentSupportsRoundness = commandsSupportingRoundness[command.type]\n\t\t\tconst nextSupportsRoundness =\n\t\t\t\tnextIdx !== undefined ? commandsSupportingRoundness[this.commands[nextIdx].type] : false\n\n\t\t\tconst currentInfo = commandInfo[i]\n\n\t\t\tconst tangentToPrev = currentInfo?.tangentEnd\n\t\t\tconst tangentToNext = nextInfo?.tangentStart\n\n\t\t\tconst roundnessClampedForAngle =\n\t\t\t\tcurrentSupportsRoundness &&\n\t\t\t\tnextSupportsRoundness &&\n\t\t\t\ttangentToPrev &&\n\t\t\t\ttangentToNext &&\n\t\t\t\tVec.Len2(tangentToPrev) > 0.01 &&\n\t\t\t\tVec.Len2(tangentToNext) > 0.01\n\t\t\t\t\t? modulate(\n\t\t\t\t\t\t\tMath.abs(Vec.AngleBetween(tangentToPrev, tangentToNext)),\n\t\t\t\t\t\t\t[Math.PI / 2, Math.PI],\n\t\t\t\t\t\t\t[roundness, 0],\n\t\t\t\t\t\t\ttrue\n\t\t\t\t\t\t)\n\t\t\t\t\t: 0\n\n\t\t\tconst shortestDistance = Math.min(\n\t\t\t\tcurrentInfo?.length ?? Infinity,\n\t\t\t\tnextInfo?.length ?? Infinity\n\t\t\t)\n\t\t\tconst offsetLimit = shortestDistance - roundnessClampedForAngle * 2\n\n\t\t\tconst offsetAmount = clamp(offset, 0, offsetLimit / 4)\n\n\t\t\tconst roundnessBeforeClampedForLength = Math.min(\n\t\t\t\troundnessClampedForAngle,\n\t\t\t\t(currentInfo?.length ?? Infinity) / 4\n\t\t\t)\n\t\t\tconst roundnessAfterClampedForLength = Math.min(\n\t\t\t\troundnessClampedForAngle,\n\t\t\t\t(nextInfo?.length ?? Infinity) / 4\n\t\t\t)\n\n\t\t\tconst drawCommand = {\n\t\t\t\tcommand,\n\t\t\t\toffsetAmount,\n\t\t\t\troundnessBefore: roundnessBeforeClampedForLength,\n\t\t\t\troundnessAfter: roundnessAfterClampedForLength,\n\t\t\t\ttangentToPrev: commandInfo[i]?.tangentEnd,\n\t\t\t\ttangentToNext: nextInfo?.tangentStart,\n\t\t\t\tmoveDidClose: false,\n\t\t\t}\n\n\t\t\tdrawCommands.push(drawCommand)\n\n\t\t\tif (command.isClose && lastMoveCommandIdx !== null) {\n\t\t\t\tconst lastMoveCommand = drawCommands[lastMoveCommandIdx]\n\t\t\t\tlastMoveCommand.moveDidClose = true\n\t\t\t\tlastMoveCommand.roundnessAfter = roundnessAfterClampedForLength\n\t\t\t} else if (command.type === 'move') {\n\t\t\t\tlastMoveCommandIdx = i\n\t\t\t}\n\t\t}\n\n\t\tfor (let pass = 0; pass < passes; pass++) {\n\t\t\tconst random = rng(randomSeed + pass)\n\n\t\t\tlet lastMoveToOffset = { x: 0, y: 0 }\n\t\t\tlet isSkippingCurrentLine = false\n\t\t\tfor (const {\n\t\t\t\tcommand,\n\t\t\t\toffsetAmount,\n\t\t\t\troundnessBefore,\n\t\t\t\troundnessAfter,\n\t\t\t\ttangentToNext,\n\t\t\t\ttangentToPrev,\n\t\t\t} of drawCommands) {\n\t\t\t\tconst offset = command.isClose\n\t\t\t\t\t? lastMoveToOffset\n\t\t\t\t\t: { x: random() * offsetAmount, y: random() * offsetAmount }\n\n\t\t\t\tif (command.type === 'move') {\n\t\t\t\t\tlastMoveToOffset = offset\n\t\t\t\t\tconst isFilled =\n\t\t\t\t\t\tcommand.opts?.geometry === false ? false : (command.opts?.geometry?.isFilled ?? false)\n\t\t\t\t\tif (onlyFilled && !isFilled) {\n\t\t\t\t\t\tisSkippingCurrentLine = true\n\t\t\t\t\t} else {\n\t\t\t\t\t\tisSkippingCurrentLine = false\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (isSkippingCurrentLine) continue\n\n\t\t\t\tconst offsetPoint = Vec.Add(command, offset)\n\n\t\t\t\tconst endPoint =\n\t\t\t\t\ttangentToNext && roundnessAfter > 0\n\t\t\t\t\t\t? Vec.Mul(tangentToNext, -roundnessAfter).add(offsetPoint)\n\t\t\t\t\t\t: offsetPoint\n\n\t\t\t\tconst startPoint =\n\t\t\t\t\ttangentToPrev && roundnessBefore > 0\n\t\t\t\t\t\t? Vec.Mul(tangentToPrev, roundnessBefore).add(offsetPoint)\n\t\t\t\t\t\t: offsetPoint\n\n\t\t\t\tif (endPoint === offsetPoint || startPoint === offsetPoint) {\n\t\t\t\t\tswitch (command.type) {\n\t\t\t\t\t\tcase 'move':\n\t\t\t\t\t\t\tparts.push('M', toDomPrecision(endPoint.x), toDomPrecision(endPoint.y))\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'line':\n\t\t\t\t\t\t\tparts.push('L', toDomPrecision(endPoint.x), toDomPrecision(endPoint.y))\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'cubic': {\n\t\t\t\t\t\t\tconst offsetCp1 = Vec.Add(command.cp1, offset)\n\t\t\t\t\t\t\tconst offsetCp2 = Vec.Add(command.cp2, offset)\n\t\t\t\t\t\t\tparts.push(\n\t\t\t\t\t\t\t\t'C',\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp1.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp1.y),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp2.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp2.y),\n\t\t\t\t\t\t\t\ttoDomPrecision(endPoint.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(endPoint.y)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\texhaustiveSwitchError(command, 'type')\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tswitch (command.type) {\n\t\t\t\t\t\tcase 'move':\n\t\t\t\t\t\t\tparts.push('M', toDomPrecision(endPoint.x), toDomPrecision(endPoint.y))\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'line':\n\t\t\t\t\t\t\tparts.push(\n\t\t\t\t\t\t\t\t'L',\n\t\t\t\t\t\t\t\ttoDomPrecision(startPoint.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(startPoint.y),\n\n\t\t\t\t\t\t\t\t'Q',\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetPoint.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetPoint.y),\n\t\t\t\t\t\t\t\ttoDomPrecision(endPoint.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(endPoint.y)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'cubic': {\n\t\t\t\t\t\t\tconst offsetCp1 = Vec.Add(command.cp1, offset)\n\t\t\t\t\t\t\tconst offsetCp2 = Vec.Add(command.cp2, offset)\n\t\t\t\t\t\t\tparts.push(\n\t\t\t\t\t\t\t\t'C',\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp1.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp1.y),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp2.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp2.y),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetPoint.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetPoint.y)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\texhaustiveSwitchError(command, 'type')\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn parts.join(' ')\n\t}\n\n\tprivate calculateSegmentLength(lastPoint: VecLike, command: PathBuilderCommand) {\n\t\tswitch (command.type) {\n\t\t\tcase 'move':\n\t\t\t\treturn 0\n\t\t\tcase 'line':\n\t\t\t\treturn Vec.Dist(lastPoint, command)\n\t\t\tcase 'cubic':\n\t\t\t\treturn CubicBezier.length(\n\t\t\t\t\tlastPoint.x,\n\t\t\t\t\tlastPoint.y,\n\t\t\t\t\tcommand.cp1.x,\n\t\t\t\t\tcommand.cp1.y,\n\t\t\t\t\tcommand.cp2.x,\n\t\t\t\t\tcommand.cp2.y,\n\t\t\t\t\tcommand.x,\n\t\t\t\t\tcommand.y\n\t\t\t\t)\n\t\t\tdefault:\n\t\t\t\texhaustiveSwitchError(command, 'type')\n\t\t}\n\t}\n\n\t/** @internal */\n\tgetCommands(): readonly PathBuilderCommand[] {\n\t\treturn this.commands\n\t}\n\n\t/** @internal */\n\tgetCommandInfo() {\n\t\tconst commandInfo: Array<undefined | PathBuilderCommandInfo> = []\n\t\tfor (let i = 1; i < this.commands.length; i++) {\n\t\t\tconst previous = this.commands[i - 1]\n\t\t\tconst current = this.commands[i]\n\n\t\t\tif (current._info) {\n\t\t\t\tcommandInfo[i] = current._info\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (current.type === 'move') {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlet tangentStart, tangentEnd\n\t\t\tswitch (current.type) {\n\t\t\t\tcase 'line':\n\t\t\t\t\ttangentStart = tangentEnd = Vec.Sub(previous, current).uni()\n\t\t\t\t\tbreak\n\t\t\t\tcase 'cubic': {\n\t\t\t\t\ttangentStart = Vec.Sub(current.cp1, previous).uni()\n\t\t\t\t\ttangentEnd = Vec.Sub(current.cp2, current).uni()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(current, 'type')\n\t\t\t}\n\n\t\t\tcurrent._info = {\n\t\t\t\ttangentStart,\n\t\t\t\ttangentEnd,\n\t\t\t\tlength: this.calculateSegmentLength(previous, current),\n\t\t\t}\n\t\t\tcommandInfo[i] = current._info\n\t\t}\n\n\t\treturn commandInfo\n\t}\n}\n\nconst commandsSupportingRoundness = {\n\tline: true,\n\tmove: true,\n\tcubic: false,\n} as const satisfies Record<PathBuilderCommand['type'], boolean>\n\n/** @public */\nexport class PathBuilderGeometry2d extends Geometry2d {\n\tconstructor(\n\t\tprivate readonly path: PathBuilder,\n\t\tprivate readonly startIdx: number,\n\t\tprivate readonly endIdx: number,\n\t\toptions: Geometry2dOptions\n\t) {\n\t\tsuper(options)\n\t}\n\n\tprivate _segments: Geometry2d[] | null = null\n\tgetSegments() {\n\t\tif (this._segments) return this._segments\n\n\t\tthis._segments = []\n\t\tlet last = this.path.commands[this.startIdx]\n\t\tassert(last.type === 'move')\n\n\t\tfor (let i = this.startIdx + 1; i < this.endIdx; i++) {\n\t\t\tconst command = this.path.commands[i]\n\t\t\tassert(command.type !== 'move')\n\n\t\t\tswitch (command.type) {\n\t\t\t\tcase 'line':\n\t\t\t\t\tthis._segments.push(new Edge2d({ start: Vec.From(last), end: Vec.From(command) }))\n\t\t\t\t\tbreak\n\t\t\t\tcase 'cubic': {\n\t\t\t\t\tthis._segments.push(\n\t\t\t\t\t\tnew CubicBezier2d({\n\t\t\t\t\t\t\tstart: Vec.From(last),\n\t\t\t\t\t\t\tcp1: Vec.From(command.cp1),\n\t\t\t\t\t\t\tcp2: Vec.From(command.cp2),\n\t\t\t\t\t\t\tend: Vec.From(command),\n\t\t\t\t\t\t\tresolution: command.resolution,\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(command, 'type')\n\t\t\t}\n\n\t\t\tlast = command\n\t\t}\n\n\t\treturn this._segments\n\t}\n\n\toverride getVertices(filters: Geometry2dFilters): Vec[] {\n\t\tconst vs = this.getSegments()\n\t\t\t.flatMap((s) => s.getVertices(filters))\n\t\t\t.filter((vertex, i, vertices) => {\n\t\t\t\tconst prev = vertices[i - 1]\n\t\t\t\tif (!prev) return true\n\t\t\t\treturn !Vec.Equals(prev, vertex)\n\t\t\t})\n\n\t\tif (this.isClosed) {\n\t\t\tconst last = vs[vs.length - 1]\n\t\t\tconst first = vs[0]\n\t\t\tif (!Vec.Equals(last, first)) {\n\t\t\t\tvs.push(first)\n\t\t\t}\n\t\t}\n\n\t\treturn vs\n\t}\n\n\toverride nearestPoint(point: VecLike, _filters?: Geometry2dFilters): Vec {\n\t\tlet nearest: Vec | null = null\n\t\tlet nearestDistance = Infinity\n\n\t\tfor (const segment of this.getSegments()) {\n\t\t\tconst candidate = segment.nearestPoint(point)\n\t\t\tconst distance = Vec.Dist2(point, candidate)\n\t\t\tif (distance < nearestDistance) {\n\t\t\t\tnearestDistance = distance\n\t\t\t\tnearest = candidate\n\t\t\t}\n\t\t}\n\n\t\tassert(nearest, 'No nearest point found')\n\t\treturn nearest\n\t}\n\n\toverride hitTestLineSegment(\n\t\tA: VecLike,\n\t\tB: VecLike,\n\t\tdistance = 0,\n\t\tfilters?: Geometry2dFilters\n\t): boolean {\n\t\treturn super.hitTestLineSegment(A, B, distance, filters)\n\t}\n\toverride getSvgPathData(): string {\n\t\treturn this.path.toD({ startIdx: this.startIdx, endIdx: this.endIdx })\n\t}\n}\n\n/*!\n * Adapted from https://github.com/adobe-webplatform/Snap.svg/tree/master\n * Apache License: https://github.com/adobe-webplatform/Snap.svg/blob/master/LICENSE\n * https://github.com/adobe-webplatform/Snap.svg/blob/c8e483c9694517e24b282f8f59f985629f4994ce/dist/snap.svg.js#L5786\n */\nconst CubicBezier = {\n\tbase3(t: number, p1: number, p2: number, p3: number, p4: number) {\n\t\tconst t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4\n\t\tconst t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3\n\t\treturn t * t2 - 3 * p1 + 3 * p2\n\t},\n\t/**\n\t * Calculate the approximate length of a cubic bezier curve from (x1, y1) to (x4, y4) with\n\t * control points (x2, y2) and (x3, y3).\n\t */\n\tlength(\n\t\tx1: number,\n\t\ty1: number,\n\t\tx2: number,\n\t\ty2: number,\n\t\tx3: number,\n\t\ty3: number,\n\t\tx4: number,\n\t\ty4: number,\n\t\tz = 1\n\t) {\n\t\tz = z > 1 ? 1 : z < 0 ? 0 : z\n\t\tconst z2 = z / 2\n\t\tconst n = 12\n\n\t\tlet sum = 0\n\t\tsum = 0\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tconst ct = z2 * CubicBezier.Tvalues[i] + z2\n\t\t\tconst xbase = CubicBezier.base3(ct, x1, x2, x3, x4)\n\t\t\tconst ybase = CubicBezier.base3(ct, y1, y2, y3, y4)\n\t\t\tconst comb = xbase * xbase + ybase * ybase\n\t\t\tsum += CubicBezier.Cvalues[i] * Math.sqrt(comb)\n\t\t}\n\t\treturn z2 * sum\n\t},\n\tTvalues: [\n\t\t-0.1252, 0.1252, -0.3678, 0.3678, -0.5873, 0.5873, -0.7699, 0.7699, -0.9041, 0.9041, -0.9816,\n\t\t0.9816,\n\t],\n\tCvalues: [\n\t\t0.2491, 0.2491, 0.2335, 0.2335, 0.2032, 0.2032, 0.1601, 0.1601, 0.1069, 0.1069, 0.0472, 0.0472,\n\t],\n}\n"], "mappings": "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