UNPKG

ixfx

Version:

A framework for programming interactivity

1,782 lines (1,707 loc) 118 kB
import { fromNumbers as fromNumbers2, fromPoints } from "./chunk-425CNZZO.js"; import { linearSpace } from "./chunk-ARAXT7VF.js"; import { mutable } from "./chunk-BMX5N5CN.js"; import { Empty, angleRadian, bbox, bezier_exports, center, circleCircle, circleRect, clampMagnitude, clampMagnitude2, degreeArc, degreeToRadian, degreesSum, distance, distanceCenter, distanceFromCenter, distanceFromExterior, distanceFromExterior2, divide, dotProduct, dotProduct2, fromCartesian, fromNumbers, fromTopLeft, getPointParameter, getPointParameter2, getRectPositioned, guard, guard2, guard3, guard4, guardDim, guardPositioned, guardPositioned2, interpolate, intersectionLine, intersections, intersectsPoint, isCircle, isCirclePositioned, isEmpty, isEmpty2, isEqual, isEqual2, isIntersecting, isLine, isNaN, isPlaceholder, isPlaceholder2, isPoint, isPoint3d, isPolarCoord, isPolyLine, isPositioned, isPositioned2, isQuadraticBezier, isRect, isRectPositioned, length, maxFromCorners, multiply, multiplyScalar, normalise, normalise2, normaliseByRect, pointAtDistance, point_exports, polar_exports, project, radianArc, radianInvert, radianToDegree, radiansFromAxisX, radiansSum, reduce2 as reduce, reverse, rotate, subtract, sum2 as sum, toCartesian, toPoint, toString, toString2 } from "./chunk-R4JIRHLR.js"; import { minFast, minIndex } from "./chunk-YG33FJI6.js"; import { sortByNumericProperty } from "./chunk-45M4HUXQ.js"; import { zipKeyValue } from "./chunk-KVLT2D4E.js"; import { randomElement } from "./chunk-LVLPUJZY.js"; import { scale, toRgb8bit } from "./chunk-DLFRRV7R.js"; import { clampIndex } from "./chunk-QAEJS6HO.js"; import { defaultRandom } from "./chunk-5VWJ6TUI.js"; import { throwIntegerTest, throwNumberTest } from "./chunk-UC4AQMTL.js"; import { __export } from "./chunk-L5EJU35C.js"; // src/geometry/index.ts var geometry_exports = {}; __export(geometry_exports, { Arcs: () => arc_exports, Beziers: () => bezier_exports, Circles: () => circle_exports, Compound: () => CompoundPath_exports, Convolve2d: () => Convolve2d_exports, CurveSimplification: () => CurveSimplification_exports, Ellipses: () => Ellipse_exports, Grids: () => grid_exports, Layouts: () => Layout_exports, Lines: () => line_exports, Paths: () => path_exports, Points: () => point_exports, Polar: () => polar_exports, QuadTree: () => QuadTree_exports, Rects: () => rect_exports, Scaler: () => Scaler_exports, Shapes: () => shape_exports, SurfacePoints: () => SurfacePoints_exports, Triangles: () => triangle_exports, Vectors: () => Vector_exports, Waypoints: () => Waypoint_exports, degreeArc: () => degreeArc, degreeToRadian: () => degreeToRadian, degreesSum: () => degreesSum, radianArc: () => radianArc, radianInvert: () => radianInvert, radianToDegree: () => radianToDegree, radiansFromAxisX: () => radiansFromAxisX, radiansSum: () => radiansSum }); // src/geometry/Waypoint.ts var Waypoint_exports = {}; __export(Waypoint_exports, { fromPoints: () => fromPoints2, init: () => init }); // src/geometry/line/JoinPointsToLines.ts var joinPointsToLines = (...points) => { const lines = []; let start = points[0]; for (let index = 1; index < points.length; index++) { lines.push(fromPoints(start, points[index])); start = points[index]; } return lines; }; // src/geometry/line/Angles.ts var directionVector = (line) => ({ x: line.b.x - line.a.x, y: line.b.y - line.a.y }); var directionVectorNormalised = (line) => { const l = length(line); const v = directionVector(line); return { x: v.x / l, y: v.y / l }; }; var parallel = (line, distance3) => { const dv = directionVector(line); const dvn = directionVectorNormalised(line); const a = { x: line.a.x - dvn.y * distance3, y: line.a.y + dvn.x * distance3 }; return { a, b: { x: a.x + dv.x, y: a.y + dv.y } }; }; var perpendicularPoint = (line, distance3, amount = 0) => { const origin = interpolate(amount, line); const dvn = directionVectorNormalised(line); return { x: origin.x - dvn.y * distance3, y: origin.y + dvn.x * distance3 }; }; // src/geometry/line/Midpoint.ts var midpoint = (aOrLine, pointB) => { const [a, b] = getPointParameter2(aOrLine, pointB); return interpolate(0.5, a, b); }; // src/geometry/line/index.ts var line_exports = {}; __export(line_exports, { Empty: () => Empty2, Placeholder: () => Placeholder, angleRadian: () => angleRadian2, apply: () => apply, asPoints: () => asPoints, bbox: () => bbox2, distance: () => distance2, distanceSingleLine: () => distanceSingleLine, divide: () => divide2, extendFromA: () => extendFromA, fromFlatArray: () => fromFlatArray, fromNumbers: () => fromNumbers2, fromPivot: () => fromPivot, fromPoints: () => fromPoints, fromPointsToPath: () => fromPointsToPath, getPointParameter: () => getPointParameter2, guard: () => guard4, interpolate: () => interpolate, isEmpty: () => isEmpty3, isEqual: () => isEqual3, isLine: () => isLine, isPlaceholder: () => isPlaceholder3, isPolyLine: () => isPolyLine, joinPointsToLines: () => joinPointsToLines, length: () => length, midpoint: () => midpoint, multiply: () => multiply2, nearest: () => nearest, normaliseByRect: () => normaliseByRect2, parallel: () => parallel, perpendicularPoint: () => perpendicularPoint, pointAtDistance: () => pointAtDistance, pointAtX: () => pointAtX, pointsOf: () => pointsOf, relativePosition: () => relativePosition, reverse: () => reverse, rotate: () => rotate2, scaleFromMidpoint: () => scaleFromMidpoint, slope: () => slope, subtract: () => subtract2, sum: () => sum2, toFlatArray: () => toFlatArray, toPath: () => toPath, toString: () => toString3, toSvgString: () => toSvgString, withinRange: () => withinRange }); // src/geometry/line/Nearest.ts var nearest = (line, point2) => { const n = (line2) => { const { a, b } = line2; const atob = { x: b.x - a.x, y: b.y - a.y }; const atop = { x: point2.x - a.x, y: point2.y - a.y }; const length4 = atob.x * atob.x + atob.y * atob.y; let dot = atop.x * atob.x + atop.y * atob.y; const t = Math.min(1, Math.max(0, dot / length4)); dot = (b.x - a.x) * (point2.y - a.y) - (b.y - a.y) * (point2.x - a.x); return { x: a.x + atob.x * t, y: a.y + atob.y * t }; }; if (Array.isArray(line)) { const pts = line.map((l) => n(l)); const dists = pts.map((p) => distance(p, point2)); return Object.freeze(pts[minIndex(...dists)]); } else { return Object.freeze(n(line)); } }; // src/geometry/line/DistanceSingleLine.ts var distanceSingleLine = (line, point2) => { guard4(line, `line`); guard(point2, `point`); if (length(line) === 0) { return length(line.a, point2); } const near = nearest(line, point2); return length(near, point2); }; // src/geometry/line/Bbox.ts var bbox2 = (line) => bbox(line.a, line.b); // src/geometry/line/Divide.ts var divide2 = (line, point2) => Object.freeze({ ...line, a: divide(line.a, point2), b: divide(line.b, point2) }); // src/geometry/line/FromFlatArray.ts var fromFlatArray = (array) => { if (!Array.isArray(array)) throw new Error(`arr parameter is not an array`); if (array.length !== 4) throw new Error(`array is expected to have length four`); return fromNumbers2(array[0], array[1], array[2], array[3]); }; // src/geometry/line/FromPivot.ts var fromPivot = (origin = { x: 0.5, y: 0.5 }, length4 = 1, angleRadian3 = 0, balance = 0.5) => { const left = length4 * balance; const right = length4 * (1 - balance); const a = toCartesian(left, radianInvert(angleRadian3), origin); const b = toCartesian(right, angleRadian3, origin); return Object.freeze({ a, b }); }; // src/geometry/line/FromPointsToPath.ts var fromPointsToPath = (a, b) => toPath(fromPoints(a, b)); // src/geometry/line/IsEqual.ts var isEqual3 = (a, b) => isEqual(a.a, b.a) && isEqual(a.b, b.b); // src/geometry/line/Multiply.ts var multiply2 = (line, point2) => Object.freeze({ ...line, a: multiply(line.a, point2), b: multiply(line.b, point2) }); // src/geometry/line/RelativePosition.ts var relativePosition = (line, pt) => { const fromStart = distance(line.a, pt); const total = length(line); return fromStart / total; }; // src/geometry/line/Rotate.ts var rotate2 = (line, amountRadian, origin) => { if (amountRadian === void 0 || amountRadian === 0) return line; if (origin === void 0) origin = 0.5; if (typeof origin === `number`) { origin = interpolate(origin, line.a, line.b); } return Object.freeze({ ...line, a: rotate(line.a, amountRadian, origin), b: rotate(line.b, amountRadian, origin) }); }; // src/geometry/line/Subtract.ts var subtract2 = (line, point2) => Object.freeze({ ...line, a: subtract(line.a, point2), b: subtract(line.b, point2) }); // src/geometry/line/Sum.ts var sum2 = (line, point2) => Object.freeze({ ...line, a: sum(line.a, point2), b: sum(line.b, point2) }); // src/geometry/line/ToString.ts function toString3(a, b) { if (isLine(a)) { guard4(a, `a`); b = a.b; a = a.a; } else if (b === void 0) throw new Error(`Expect second point if first is a point`); return toString2(a) + `-` + toString2(b); } // src/geometry/line/index.ts var Empty2 = Object.freeze({ a: Object.freeze({ x: 0, y: 0 }), b: Object.freeze({ x: 0, y: 0 }) }); var Placeholder = Object.freeze({ a: Object.freeze({ x: Number.NaN, y: Number.NaN }), b: Object.freeze({ x: Number.NaN, y: Number.NaN }) }); var isEmpty3 = (l) => isEmpty(l.a) && isEmpty(l.b); var isPlaceholder3 = (l) => isPlaceholder(l.a) && isPlaceholder(l.b); var apply = (line, fn) => Object.freeze( { ...line, a: fn(line.a), b: fn(line.b) } ); var angleRadian2 = (lineOrPoint, b) => { let a; if (isLine(lineOrPoint)) { a = lineOrPoint.a; b = lineOrPoint.b; } else { a = lineOrPoint; if (b === void 0) throw new Error(`b point must be provided`); } return Math.atan2(b.y - a.y, b.x - a.x); }; var normaliseByRect2 = (line, width, height4) => Object.freeze({ ...line, a: normaliseByRect(line.a, width, height4), b: normaliseByRect(line.b, width, height4) }); var withinRange = (line, point2, maxRange) => { const calculatedDistance = distance2(line, point2); return calculatedDistance <= maxRange; }; var slope = (lineOrPoint, b) => { let a; if (isLine(lineOrPoint)) { a = lineOrPoint.a; b = lineOrPoint.b; } else { a = lineOrPoint; if (b === void 0) throw new Error(`b parameter required`); } if (b === void 0) { throw new TypeError(`Second point missing`); } else { return (b.y - a.y) / (b.x - a.x); } }; var scaleFromMidpoint = (line, factor) => { const a = interpolate(factor / 2, line); const b = interpolate(0.5 + factor / 2, line); return { a, b }; }; var pointAtX = (line, x) => { const y = line.a.y + (x - line.a.x) * slope(line); return Object.freeze({ x, y }); }; var extendFromA = (line, distance3) => { const calculatedLength = length(line); return Object.freeze({ ...line, a: line.a, b: Object.freeze({ x: line.b.x + (line.b.x - line.a.x) / calculatedLength * distance3, y: line.b.y + (line.b.y - line.a.y) / calculatedLength * distance3 }) }); }; function* pointsOf(line) { const { a, b } = line; let x0 = Math.floor(a.x); let y0 = Math.floor(a.y); const x1 = Math.floor(b.x); const y1 = Math.floor(b.y); const dx = Math.abs(x1 - x0); const dy = -Math.abs(y1 - y0); const sx = x0 < x1 ? 1 : -1; const sy = y0 < y1 ? 1 : -1; let err = dx + dy; while (true) { yield { x: x0, y: y0 }; if (x0 === x1 && y0 === y1) break; const e2 = 2 * err; if (e2 >= dy) { err += dy; x0 += sx; } if (e2 <= dx) { err += dx; y0 += sy; } } } var distance2 = (line, point2) => { if (Array.isArray(line)) { const distances = line.map((l) => distanceSingleLine(l, point2)); return minFast(distances); } else { return distanceSingleLine(line, point2); } }; var toFlatArray = (a, b) => { if (isLine(a)) { return [a.a.x, a.a.y, a.b.x, a.b.y]; } else if (isPoint(a) && isPoint(b)) { return [a.x, a.y, b.x, b.y]; } else { throw new Error(`Expected single line parameter, or a and b points`); } }; function* asPoints(lines) { for (const l of lines) { yield l.a; yield l.b; } } var toSvgString = (a, b) => [`M${a.x} ${a.y} L ${b.x} ${b.y}`]; // src/geometry/line/ToPath.ts var toPath = (line) => { const { a, b } = line; return Object.freeze({ ...line, length: () => length(a, b), interpolate: (amount) => interpolate(amount, a, b), relativePosition: (point2) => relativePosition(line, point2), bbox: () => bbox2(line), toString: () => toString3(a, b), toFlatArray: () => toFlatArray(a, b), toSvgString: () => toSvgString(a, b), toPoints: () => [a, b], rotate: (amountRadian, origin) => toPath(rotate2(line, amountRadian, origin)), nearest: (point2) => nearest(line, point2), sum: (point2) => toPath(sum2(line, point2)), divide: (point2) => toPath(divide2(line, point2)), multiply: (point2) => toPath(multiply2(line, point2)), subtract: (point2) => toPath(subtract2(line, point2)), midpoint: () => midpoint(a, b), distanceToPoint: (point2) => distanceSingleLine(line, point2), parallel: (distance3) => parallel(line, distance3), perpendicularPoint: (distance3, amount) => perpendicularPoint(line, distance3, amount), slope: () => slope(line), withinRange: (point2, maxRange) => withinRange(line, point2, maxRange), isEqual: (otherLine) => isEqual3(line, otherLine), apply: (fn) => toPath(apply(line, fn)), kind: `line` }); }; // src/geometry/Waypoint.ts var fromPoints2 = (waypoints, opts = {}) => { const lines = joinPointsToLines(...waypoints); return init( lines.map((l) => toPath(l)), opts ); }; var init = (paths, opts = {}) => { const maxDistanceFromLine = opts.maxDistanceFromLine ?? 0.1; const checkUnordered = (pt) => { const results = paths.map((p, index) => { const nearest3 = p.nearest(pt); const distance3 = distance(pt, nearest3); const positionRelative = p.relativePosition(nearest3, maxDistanceFromLine); ; return { positionRelative, path: p, index, nearest: nearest3, distance: distance3, rank: Number.MAX_SAFE_INTEGER }; }); const filtered = results.filter((v) => v.distance <= maxDistanceFromLine); const sorted = sortByNumericProperty(filtered, `distance`); for (let rank = 0; rank < sorted.length; rank++) { sorted[rank].rank = rank; } return sorted; }; return checkUnordered; }; // src/geometry/Layout.ts var Layout_exports = {}; __export(Layout_exports, { CirclePacking: () => CirclePacking_exports }); // src/geometry/CirclePacking.ts var CirclePacking_exports = {}; __export(CirclePacking_exports, { random: () => random2 }); // src/geometry/shape/index.ts var shape_exports = {}; __export(shape_exports, { arrow: () => arrow, center: () => center3, isIntersecting: () => isIntersecting3, randomPoint: () => randomPoint3, starburst: () => starburst }); // src/geometry/rect/Corners.ts var corners = (rect, origin) => { const r = getRectPositioned(rect, origin); return [ { x: r.x, y: r.y }, { x: r.x + r.width, y: r.y }, { x: r.x + r.width, y: r.y + r.height }, { x: r.x, y: r.y + r.height } ]; }; // src/geometry/circle/IsContainedBy.ts var isContainedBy = (a, b, c) => { const d = distanceCenter(a, b); if (isCircle(b)) { return d < Math.abs(a.radius - b.radius); } else if (isPoint(b)) { if (c === void 0) { return d <= a.radius; } else { return d < Math.abs(a.radius - c); } } else throw new Error(`b parameter is expected to be CirclePositioned or Point`); }; // src/geometry/circle/Intersecting.ts var isIntersecting2 = (a, b, c) => { if (isEqual(a, b)) return true; if (isContainedBy(a, b, c)) return true; if (isCircle(b)) { return circleCircle(a, b); } else if (isRectPositioned(b)) { return circleRect(a, b); } else if (isPoint(b) && c !== void 0) { return circleCircle(a, { ...b, radius: c }); } return false; }; // src/geometry/circle/Random.ts var piPi = Math.PI * 2; var randomPoint = (within, opts = {}) => { const offset2 = isCirclePositioned(within) ? within : { x: 0, y: 0 }; const strategy = opts.strategy ?? `uniform`; const margin = opts.margin ?? 0; const radius = within.radius - margin; const rand = opts.randomSource ?? Math.random; switch (strategy) { case `naive`: { return sum(offset2, toCartesian(rand() * radius, rand() * piPi)); } case `uniform`: { return sum(offset2, toCartesian(Math.sqrt(rand()) * radius, rand() * piPi)); } default: { throw new Error(`Unknown strategy '${strategy}'. Expects 'uniform' or 'naive'`); } } }; // src/geometry/circle/Center.ts var center2 = (circle) => { return isCirclePositioned(circle) ? Object.freeze({ x: circle.x, y: circle.y }) : Object.freeze({ x: circle.radius, y: circle.radius }); }; // src/geometry/rect/Random.ts var random = (rando) => { if (rando === void 0) rando = defaultRandom; return Object.freeze({ x: rando(), y: rando(), width: rando(), height: rando() }); }; var randomPoint2 = (within, options = {}) => { const rand = options.randomSource ?? defaultRandom; const margin = options.margin ?? { x: 0, y: 0 }; const x = rand() * (within.width - margin.x - margin.x); const y = rand() * (within.height - margin.y - margin.y); const pos = { x: x + margin.x, y: y + margin.y }; return isPositioned2(within) ? sum(pos, within) : Object.freeze(pos); }; // src/geometry/shape/index.ts var isIntersecting3 = (a, b) => { if (isCirclePositioned(a)) { return isIntersecting2(a, b); } else if (isRectPositioned(a)) { return isIntersecting(a, b); } throw new Error( `a or b are unknown shapes. a: ${JSON.stringify(a)} b: ${JSON.stringify(b)}` ); }; var randomPoint3 = (shape, opts = {}) => { if (isCirclePositioned(shape)) { return randomPoint(shape, opts); } else if (isRectPositioned(shape)) { return randomPoint2(shape, opts); } throw new Error(`Unknown shape. Only CirclePositioned and RectPositioned are supported.`); }; var center3 = (shape) => { if (shape === void 0) { return Object.freeze({ x: 0.5, y: 0.5 }); } else if (isRect(shape)) { return center(shape); } else if (triangle_exports.isTriangle(shape)) { return triangle_exports.centroid(shape); } else if (isCircle(shape)) { return center2(shape); } else { throw new Error(`Unknown shape: ${JSON.stringify(shape)}`); } }; var starburst = (outerRadius, points = 5, innerRadius, origin = point_exports.Empty, opts) => { throwIntegerTest(points, `positive`, `points`); const angle = Math.PI * 2 / points; const angleHalf = angle / 2; const initialAngle = opts?.initialAngleRadian ?? -Math.PI / 2; if (innerRadius === void 0) innerRadius = outerRadius / 2; let a = initialAngle; const pts = []; for (let index = 0; index < points; index++) { const peak = toCartesian(outerRadius, a, origin); const left = toCartesian(innerRadius, a - angleHalf, origin); const right = toCartesian(innerRadius, a + angleHalf, origin); pts.push(left, peak); if (index + 1 < points) pts.push(right); a += angle; } return pts; }; var arrow = (origin, from, opts = {}) => { const tailLength = opts.tailLength ?? 10; const tailThickness = opts.tailThickness ?? Math.max(tailLength / 5, 5); const angleRadian3 = opts.angleRadian ?? 0; const arrowSize = opts.arrowSize ?? Math.max(tailLength / 5, 15); const triAngle = Math.PI / 2; let tri; let tailPoints; if (from === `tip`) { tri = triangle_exports.equilateralFromVertex(origin, arrowSize, triAngle); tailPoints = corners( fromTopLeft( { x: tri.a.x - tailLength, y: origin.y - tailThickness / 2 }, tailLength, tailThickness ) ); } else if (from === `middle`) { const midX = tailLength + arrowSize / 2; const midY = tailThickness / 2; tri = triangle_exports.equilateralFromVertex( { x: origin.x + arrowSize * 1.2, y: origin.y }, arrowSize, triAngle ); tailPoints = corners( fromTopLeft( { x: origin.x - midX, y: origin.y - midY }, tailLength + arrowSize, tailThickness ) ); } else { tailPoints = corners( fromTopLeft( { x: origin.x, y: origin.y - tailThickness / 2 }, tailLength, tailThickness ) ); tri = triangle_exports.equilateralFromVertex( { x: origin.x + tailLength + arrowSize * 0.7, y: origin.y }, arrowSize, triAngle ); } const arrow2 = point_exports.rotate( [ tailPoints[0], tailPoints[1], tri.a, tri.b, tri.c, tailPoints[2], tailPoints[3] ], angleRadian3, origin ); return arrow2; }; // src/geometry/CirclePacking.ts var random2 = (circles, container, opts = {}) => { if (!Array.isArray(circles)) throw new Error(`Parameter 'circles' is not an array`); const attempts = opts.attempts ?? 2e3; const sorted = sortByNumericProperty(circles, `radius`); const positionedCircles = []; const willHit = (b, radius) => positionedCircles.some((v) => isIntersecting2(v, b, radius)); while (sorted.length > 0) { const circle = sorted.pop(); if (!circle) break; const randomPointOpts = { ...opts, margin: { x: circle.radius, y: circle.radius } }; for (let index = 0; index < attempts; index++) { const position = randomPoint3(container, randomPointOpts); if (!willHit(position, circle.radius)) { positionedCircles.push(Object.freeze({ ...circle, ...position })); break; } } } return positionedCircles; }; // src/geometry/circle/index.ts var circle_exports = {}; __export(circle_exports, { area: () => area, bbox: () => bbox3, center: () => center2, circumference: () => circumference, distanceCenter: () => distanceCenter, distanceFromExterior: () => distanceFromExterior, exteriorIntegerPoints: () => exteriorIntegerPoints, guard: () => guard2, guardPositioned: () => guardPositioned, interiorIntegerPoints: () => interiorIntegerPoints, interpolate: () => interpolate2, intersectionLine: () => intersectionLine, intersections: () => intersections, isCircle: () => isCircle, isCirclePositioned: () => isCirclePositioned, isContainedBy: () => isContainedBy, isEqual: () => isEqual2, isIntersecting: () => isIntersecting2, isNaN: () => isNaN, isPositioned: () => isPositioned, length: () => length2, multiplyScalar: () => multiplyScalar2, nearest: () => nearest2, pointOnPerimeter: () => pointOnPerimeter, randomPoint: () => randomPoint, toPath: () => toPath2, toPositioned: () => toPositioned, toSvg: () => toSvg }); // src/geometry/circle/Area.ts var area = (circle) => { guard2(circle); return Math.PI * circle.radius * circle.radius; }; // src/geometry/rect/FromCenter.ts var fromCenter = (origin, width, height4) => { guard(origin, `origin`); guardDim(width, `width`); guardDim(height4, `height`); const halfW = width / 2; const halfH = height4 / 2; return { x: origin.x - halfW, y: origin.y - halfH, width, height: height4 }; }; // src/geometry/circle/Bbox.ts var bbox3 = (circle) => { return isCirclePositioned(circle) ? fromCenter(circle, circle.radius * 2, circle.radius * 2) : { width: circle.radius * 2, height: circle.radius * 2, x: 0, y: 0 }; }; // src/geometry/circle/ExteriorPoints.ts function* exteriorIntegerPoints(circle) { const { x, y, radius } = circle; let xx = radius; let yy = 0; let radiusError = 1 - x; while (xx >= yy) { yield { x: xx + x, y: yy + y }; yield { x: yy + x, y: xx + y }; yield { x: -xx + x, y: yy + y }; yield { x: -yy + x, y: xx + y }; yield { x: -xx + x, y: -yy + y }; yield { x: -yy + x, y: -xx + y }; yield { x: xx + x, y: -yy + y }; yield { x: yy + x, y: -xx + y }; yy++; if (radiusError < 0) { radiusError += 2 * yy + 1; } else { xx--; radiusError += 2 * (yy - xx + 1); } } } // src/geometry/circle/InteriorPoints.ts function* interiorIntegerPoints(circle) { const xMin = circle.x - circle.radius; const xMax = circle.x + circle.radius; const yMin = circle.y - circle.radius; const yMax = circle.y + circle.radius; for (let x = xMin; x < xMax; x++) { for (let y = yMin; y < yMax; y++) { const r = Math.abs(distance(circle, x, y)); if (r <= circle.radius) yield { x, y }; } } } // src/geometry/circle/Perimeter.ts var piPi2 = Math.PI * 2; var nearest2 = (circle, point2) => { const n = (a) => { const l = Math.sqrt(Math.pow(point2.x - a.x, 2) + Math.pow(point2.y - a.y, 2)); const x = a.x + a.radius * ((point2.x - a.x) / l); const y = a.y + a.radius * ((point2.y - a.y) / l); return { x, y }; }; if (Array.isArray(circle)) { const pts = circle.map((l) => n(l)); const dists = pts.map((p) => distance(p, point2)); return Object.freeze(pts[minIndex(...dists)]); } else { return Object.freeze(n(circle)); } }; var pointOnPerimeter = (circle, angleRadian3, origin) => { if (origin === void 0) { origin = isCirclePositioned(circle) ? circle : { x: 0, y: 0 }; } return { x: Math.cos(-angleRadian3) * circle.radius + origin.x, y: Math.sin(-angleRadian3) * circle.radius + origin.y }; }; var circumference = (circle) => { guard2(circle); return piPi2 * circle.radius; }; var length2 = (circle) => circumference(circle); // src/geometry/circle/Interpolate.ts var piPi3 = Math.PI * 2; var interpolate2 = (circle, t) => pointOnPerimeter(circle, t * piPi3); // src/geometry/circle/Multiply.ts function multiplyScalar2(a, value) { if (isCirclePositioned(a)) { const pt = multiplyScalar(a, value); return Object.freeze({ ...a, ...pt, radius: a.radius * value }); } else { return Object.freeze({ ...a, radius: a.radius * value }); } } // src/geometry/circle/Svg.ts var toSvg = (a, sweep, origin) => { if (isCircle(a)) { if (origin !== void 0) { return toSvgFull(a.radius, origin, sweep); } if (isCirclePositioned(a)) { return toSvgFull(a.radius, a, sweep); } else throw new Error(`origin parameter needed for non-positioned circle`); } else { if (origin === void 0) { throw new Error(`origin parameter needed`); } else { return toSvgFull(a, origin, sweep); } } }; var toSvgFull = (radius, origin, sweep) => { const { x, y } = origin; const s = sweep ? `1` : `0`; return ` M ${x}, ${y} m -${radius}, 0 a ${radius},${radius} 0 1,${s} ${radius * 2},0 a ${radius},${radius} 0 1,${s} -${radius * 2},0 `.split(` `); }; // src/geometry/circle/ToPath.ts var toPath2 = (circle) => { guard2(circle); return { ...circle, nearest: (point2) => nearest2(circle, point2), /** * Returns a relative (0.0-1.0) point on a circle. 0=3 o'clock, 0.25=6 o'clock, 0.5=9 o'clock, 0.75=12 o'clock etc. * @param {t} Relative (0.0-1.0) point * @returns {Point} X,y */ interpolate: (t) => interpolate2(circle, t), bbox: () => bbox3(circle), length: () => circumference(circle), toSvgString: (sweep = true) => toSvg(circle, sweep), relativePosition: (_point, _intersectionThreshold) => { throw new Error(`Not implemented`); }, distanceToPoint: (_point) => { throw new Error(`Not implemented`); }, kind: `circular` }; }; // src/geometry/circle/ToPositioned.ts var toPositioned = (circle, defaultPositionOrX, y) => { if (isCirclePositioned(circle)) return circle; const pt = getPointParameter(defaultPositionOrX, y); return Object.freeze({ ...circle, ...pt }); }; // src/geometry/rect/index.ts var rect_exports = {}; __export(rect_exports, { Empty: () => Empty3, EmptyPositioned: () => EmptyPositioned, Placeholder: () => Placeholder2, PlaceholderPositioned: () => PlaceholderPositioned, applyDim: () => applyDim, applyFields: () => applyFields, applyMerge: () => applyMerge, applyScalar: () => applyScalar, area: () => area2, cardinal: () => cardinal, center: () => center, corners: () => corners, distanceFromCenter: () => distanceFromCenter, distanceFromExterior: () => distanceFromExterior2, divide: () => divide3, divideDim: () => divideDim, divideScalar: () => divideScalar, dividerByLargestDimension: () => dividerByLargestDimension, edges: () => edges, encompass: () => encompass, fromCenter: () => fromCenter, fromElement: () => fromElement, fromNumbers: () => fromNumbers3, fromTopLeft: () => fromTopLeft, getEdgeX: () => getEdgeX, getEdgeY: () => getEdgeY, getRectPositioned: () => getRectPositioned, getRectPositionedParameter: () => getRectPositionedParameter, guard: () => guard3, guardDim: () => guardDim, guardPositioned: () => guardPositioned2, intersectsPoint: () => intersectsPoint, isEmpty: () => isEmpty2, isEqual: () => isEqual4, isEqualSize: () => isEqualSize, isIntersecting: () => isIntersecting, isPlaceholder: () => isPlaceholder2, isPositioned: () => isPositioned2, isRect: () => isRect, isRectPositioned: () => isRectPositioned, lengths: () => lengths, maxFromCorners: () => maxFromCorners, multiply: () => multiply3, multiplyDim: () => multiplyDim, multiplyScalar: () => multiplyScalar3, nearestInternal: () => nearestInternal, perimeter: () => perimeter, random: () => random, randomPoint: () => randomPoint2, subtract: () => subtract3, subtractOffset: () => subtractOffset, subtractSize: () => subtractSize, sum: () => sum3, sumOffset: () => sumOffset, toArray: () => toArray }); // src/geometry/rect/Area.ts var area2 = (rect) => { guard3(rect); return rect.height * rect.width; }; // src/geometry/rect/Apply.ts function applyFields(op, rectOrWidth, heightValue) { let width = typeof rectOrWidth === `number` ? rectOrWidth : rectOrWidth.width; let height4 = typeof rectOrWidth === `number` ? heightValue : rectOrWidth.height; if (width === void 0) throw new Error(`Param 'width' undefined`); if (height4 === void 0) throw new Error(`Param 'height' undefined`); width = op(width, `width`); height4 = op(height4, `height`); if (typeof rectOrWidth === `object`) { if (isPositioned2(rectOrWidth)) { const x = op(rectOrWidth.x, `x`); const y = op(rectOrWidth.y, `y`); return { ...rectOrWidth, width, height: height4, x, y }; } else { return { ...rectOrWidth, width, height: height4 }; } } return { width, height: height4 }; } function applyMerge(op, a, b, c) { guard3(a, `a`); if (isRect(b)) { return isRectPositioned(a) ? Object.freeze({ ...a, x: op(a.x, b.width), y: op(a.y, b.height), width: op(a.width, b.width), height: op(a.height, b.height) }) : Object.freeze({ ...a, width: op(a.width, b.width), height: op(a.height, b.height) }); } else { if (typeof b !== `number`) { throw new TypeError( `Expected second parameter of type Rect or number. Got ${JSON.stringify( b )}` ); } if (typeof c !== `number`) throw new Error(`Expected third param as height. Got ${JSON.stringify(c)}`); return isRectPositioned(a) ? Object.freeze({ ...a, x: op(a.x, b), y: op(a.y, c), width: op(a.width, b), height: op(a.height, c) }) : Object.freeze({ ...a, width: op(a.width, b), height: op(a.height, c) }); } } function applyScalar(op, rect, parameter) { return isPositioned2(rect) ? Object.freeze({ ...rect, x: op(rect.x, parameter), y: op(rect.y, parameter), width: op(rect.width, parameter), height: op(rect.height, parameter) }) : Object.freeze({ ...rect, width: op(rect.width, parameter), height: op(rect.height, parameter) }); } function applyDim(op, rect, parameter) { return Object.freeze({ ...rect, width: op(rect.width, parameter), height: op(rect.height, parameter) }); } // src/geometry/rect/Cardinal.ts var cardinal = (rect, card) => { const { x, y, width, height: height4 } = rect; switch (card) { case `nw`: { return Object.freeze({ x, y }); } case `n`: { return Object.freeze({ x: x + width / 2, y }); } case `ne`: { return Object.freeze({ x: x + width, y }); } case `sw`: { return Object.freeze({ x, y: y + height4 }); } case `s`: { return Object.freeze({ x: x + width / 2, y: y + height4 }); } case `se`: { return Object.freeze({ x: x + width, y: y + height4 }); } case `w`: { return Object.freeze({ x, y: y + height4 / 2 }); } case `e`: { return Object.freeze({ x: x + width, y: y + height4 / 2 }); } case `center`: { return Object.freeze({ x: x + width / 2, y: y + height4 / 2 }); } default: { throw new Error(`Unknown direction: ${card}`); } } }; // src/geometry/rect/Divide.ts var divideOp = (a, b) => a / b; function divide3(a, b, c) { return applyMerge(divideOp, a, b, c); } function divideScalar(rect, amount) { return applyScalar(divideOp, rect, amount); } function divideDim(rect, amount) { return applyDim(divideOp, rect, amount); } // src/geometry/rect/Edges.ts var edges = (rect, origin) => { const c = corners(rect, origin); return joinPointsToLines(...c, c[0]); }; var getEdgeX = (rect, edge) => { guard3(rect); switch (edge) { case `top`: { return isPoint(rect) ? rect.x : 0; } case `bottom`: { return isPoint(rect) ? rect.x : 0; } case `left`: { return isPoint(rect) ? rect.y : 0; } case `right`: { return isPoint(rect) ? rect.x + rect.width : rect.width; } } }; var getEdgeY = (rect, edge) => { guard3(rect); switch (edge) { case `top`: { return isPoint(rect) ? rect.y : 0; } case `bottom`: { return isPoint(rect) ? rect.y + rect.height : rect.height; } case `left`: { return isPoint(rect) ? rect.y : 0; } case `right`: { return isPoint(rect) ? rect.y : 0; } } }; // src/geometry/rect/Empty.ts var Empty3 = Object.freeze({ width: 0, height: 0 }); var EmptyPositioned = Object.freeze({ x: 0, y: 0, width: 0, height: 0 }); // src/geometry/rect/Encompass.ts var encompass = (rect, ...points) => { const x = points.map((p) => p.x); const y = points.map((p) => p.y); let minX = Math.min(...x, rect.x); let minY = Math.min(...y, rect.y); let maxX = Math.max(...x, rect.x + rect.width); let maxY = Math.max(...y, rect.y + rect.height); let rectW = Math.max(rect.width, maxX - minX); let rectH = Math.max(rect.height, maxY - minY); return Object.freeze({ ...rect, x: minX, y: minY, width: rectW, height: rectH }); }; // src/geometry/rect/FromElement.ts var fromElement = (el) => ({ width: el.clientWidth, height: el.clientHeight }); // src/geometry/rect/FromNumbers.ts function fromNumbers3(xOrWidth, yOrHeight, width, height4) { if (width === void 0 || height4 === void 0) { if (typeof xOrWidth !== `number`) throw new Error(`width is not an number`); if (typeof yOrHeight !== `number`) { throw new TypeError(`height is not an number`); } return Object.freeze({ width: xOrWidth, height: yOrHeight }); } if (typeof xOrWidth !== `number`) throw new Error(`x is not an number`); if (typeof yOrHeight !== `number`) throw new Error(`y is not an number`); if (typeof width !== `number`) throw new Error(`width is not an number`); if (typeof height4 !== `number`) throw new Error(`height is not an number`); return Object.freeze({ x: xOrWidth, y: yOrHeight, width, height: height4 }); } // src/geometry/rect/GetRectPositionedParameter.ts function getRectPositionedParameter(a, b, c, d) { if (typeof a === `number`) { if (typeof b === `number`) { if (typeof c === `number` && typeof d === `number`) { return { x: a, y: b, width: c, height: d }; } else if (isRect(c)) { return { x: a, y: b, width: c.width, height: c.height }; } else { throw new TypeError(`If params 'a' & 'b' are numbers, expect following parameters to be x,y or Rect`); } } else { throw new TypeError(`If parameter 'a' is a number, expect following parameters to be: y,w,h`); } } else if (isRectPositioned(a)) { return a; } else if (isRect(a)) { if (typeof b === `number` && typeof c === `number`) { return { width: a.width, height: a.height, x: b, y: c }; } else if (isPoint(b)) { return { width: a.width, height: a.height, x: b.x, y: b.y }; } else { throw new TypeError(`If param 'a' is a Rect, expects following parameters to be x,y`); } } else if (isPoint(a)) { if (typeof b === `number` && typeof c === `number`) { return { x: a.x, y: a.y, width: b, height: c }; } else if (isRect(b)) { return { x: a.x, y: a.y, width: b.width, height: b.height }; } else { throw new TypeError(`If parameter 'a' is a Point, expect following params to be: Rect or width,height`); } } throw new TypeError(`Expect a first parameter to be x,RectPositioned,Rect or Point`); } // src/geometry/rect/IsEqual.ts var isEqualSize = (a, b) => { if (a === void 0) throw new Error(`a undefined`); if (b === void 0) throw new Error(`b undefined`); return a.width === b.width && a.height === b.height; }; var isEqual4 = (a, b) => { if (isPositioned2(a) && isPositioned2(b)) { if (!isEqual(a, b)) return false; return a.width === b.width && a.height === b.height; } else if (!isPositioned2(a) && !isPositioned2(b)) { return a.width === b.width && a.height === b.height; } else { return false; } }; // src/geometry/rect/Lengths.ts var lengths = (rect) => { guardPositioned2(rect, `rect`); return edges(rect).map((l) => length(l)); }; // src/geometry/rect/Multiply.ts var multiplyOp = (a, b) => a * b; function multiply3(a, b, c) { return applyMerge(multiplyOp, a, b, c); } function multiplyScalar3(rect, amount) { return applyScalar(multiplyOp, rect, amount); } function multiplyDim(rect, amount) { return applyDim(multiplyOp, rect, amount); } // src/geometry/rect/Nearest.ts var nearestInternal = (rect, p) => { let { x, y } = p; if (x < rect.x) x = rect.x; else if (x > rect.x + rect.width) x = rect.x + rect.width; if (y < rect.y) y = rect.y; else if (y > rect.y + rect.height) y = rect.y + rect.height; return Object.freeze({ ...p, x, y }); }; // src/geometry/rect/Placeholder.ts var Placeholder2 = Object.freeze({ width: Number.NaN, height: Number.NaN }); var PlaceholderPositioned = Object.freeze({ x: Number.NaN, y: Number.NaN, width: Number.NaN, height: Number.NaN }); // src/geometry/rect/Perimeter.ts var perimeter = (rect) => { guard3(rect); return rect.height + rect.height + rect.width + rect.width; }; // src/geometry/rect/NormaliseByRect.ts var dividerByLargestDimension = (rect) => { const largest = Math.max(rect.width, rect.height); return (value) => { if (typeof value === `number`) { return value / largest; } else if (isPoint3d(value)) { return Object.freeze({ ...value, x: value.x / largest, y: value.y / largest, z: value.x / largest }); } else if (isPoint(value)) { return Object.freeze({ ...value, x: value.x / largest, y: value.y / largest }); } else throw new Error(`Param 'value' is neither number nor Point`); }; }; // src/geometry/rect/Subtract.ts var subtractOp = (a, b) => a - b; function subtract3(a, b, c) { return applyMerge(subtractOp, a, b, c); } function subtractSize(a, b, c) { const w = typeof b === `number` ? b : b.width; const h = typeof b === `number` ? c : b.height; if (h === void 0) throw new Error(`Expected height as third parameter`); const r = { ...a, width: a.width - w, height: a.height - h }; return r; } function subtractOffset(a, b) { let x = 0; let y = 0; if (isPositioned2(a)) { x = a.x; y = a.y; } let xB = 0; let yB = 0; if (isPositioned2(b)) { xB = b.x; yB = b.y; } return Object.freeze({ ...a, x: x - xB, y: y - yB, width: a.width - b.width, height: a.height - b.height }); } // src/geometry/rect/Sum.ts var sumOp = (a, b) => a + b; function sum3(a, b, c) { return applyMerge(sumOp, a, b, c); } function sumOffset(a, b) { let x = 0; let y = 0; if (isPositioned2(a)) { x = a.x; y = a.y; } let xB = 0; let yB = 0; if (isPositioned2(b)) { xB = b.x; yB = b.y; } return Object.freeze({ ...a, x: x + xB, y: y + yB, width: a.width + b.width, height: a.height + b.height }); } // src/geometry/rect/ToArray.ts function toArray(rect) { if (isPositioned2(rect)) { return [rect.x, rect.y, rect.width, rect.height]; } else if (isRect(rect)) { return [rect.width, rect.height]; } else { throw new Error( `Param 'rect' is not a rectangle. Got: ${JSON.stringify(rect)}` ); } } // src/geometry/path/index.ts var path_exports = {}; __export(path_exports, { getEnd: () => getEnd, getStart: () => getStart }); var getStart = function(path) { if (isQuadraticBezier(path)) return path.a; else if (isLine(path)) return path.a; else throw new Error(`Unknown path type ${JSON.stringify(path)}`); }; var getEnd = function(path) { if (isQuadraticBezier(path)) return path.b; else if (isLine(path)) return path.b; else throw new Error(`Unknown path type ${JSON.stringify(path)}`); }; // src/geometry/grid/index.ts var grid_exports = {}; __export(grid_exports, { Array1d: () => Array1d_exports, Array2d: () => Array2d_exports, As: () => As_exports, By: () => enumerators_exports, Visit: () => visitors_exports, allDirections: () => allDirections, applyBounds: () => applyBounds, asRectangles: () => asRectangles, cellAtPoint: () => cellAtPoint, cellEquals: () => cellEquals, cellFromIndex: () => cellFromIndex, cellKeyString: () => cellKeyString, cellMiddle: () => cellMiddle, crossDirections: () => crossDirections, getLine: () => getLine, getVectorFromCardinal: () => getVectorFromCardinal, guardCell: () => guardCell, guardGrid: () => guardGrid, indexFromCell: () => indexFromCell, inside: () => inside, isCell: () => isCell, isEqual: () => isEqual5, neighbourList: () => neighbourList, neighbours: () => neighbours, offset: () => offset, offsetCardinals: () => offsetCardinals, randomNeighbour: () => randomNeighbour, rectangleForCell: () => rectangleForCell, simpleLine: () => simpleLine, toArray2d: () => toArray2d, values: () => values }); // src/geometry/grid/Inside.ts var inside = (grid2, cell) => { if (cell.x < 0 || cell.y < 0) return false; if (cell.x >= grid2.cols || cell.y >= grid2.rows) return false; return true; }; // src/geometry/grid/Guards.ts var isCell = (cell) => { if (cell === void 0) return false; return `x` in cell && `y` in cell; }; var guardCell = (cell, parameterName = `Param`, grid2) => { if (cell === void 0) { throw new Error(parameterName + ` is undefined. Expecting {x,y}`); } if (cell.x === void 0) throw new Error(parameterName + `.x is undefined`); if (cell.y === void 0) throw new Error(parameterName + `.y is undefined`); if (Number.isNaN(cell.x)) throw new Error(parameterName + `.x is NaN`); if (Number.isNaN(cell.y)) throw new Error(parameterName + `.y is NaN`); if (!Number.isInteger(cell.x)) { throw new TypeError(parameterName + `.x is non-integer`); } if (!Number.isInteger(cell.y)) { throw new TypeError(parameterName + `.y is non-integer`); } if (grid2 !== void 0 && !inside(grid2, cell)) { throw new Error( `${parameterName} is outside of grid. Cell: ${cell.x},${cell.y} Grid: ${grid2.cols}, ${grid2.rows}` ); } }; var guardGrid = (grid2, parameterName = `Param`) => { if (grid2 === void 0) { throw new Error(`${parameterName} is undefined. Expecting grid.`); } if (!(`rows` in grid2)) throw new Error(`${parameterName}.rows is undefined`); if (!(`cols` in grid2)) throw new Error(`${parameterName}.cols is undefined`); if (!Number.isInteger(grid2.rows)) { throw new TypeError(`${parameterName}.rows is not an integer`); } if (!Number.isInteger(grid2.cols)) { throw new TypeError(`${parameterName}.cols is not an integer`); } }; // src/geometry/grid/ApplyBounds.ts var applyBounds = function(grid2, cell, wrap4 = `undefined`) { guardGrid(grid2, `grid`); guardCell(cell, `cell`); let x = cell.x; let y = cell.y; switch (wrap4) { case `wrap`: { x = x % grid2.cols; y = y % grid2.rows; if (x < 0) x = grid2.cols + x; else if (x >= grid2.cols) { x -= grid2.cols; } if (y < 0) y = grid2.rows + y; else if (y >= grid2.rows) { y -= grid2.rows; } x = Math.abs(x); y = Math.abs(y); break; } case `stop`: { x = clampIndex(x, grid2.cols); y = clampIndex(y, grid2.rows); break; } case `undefined`: { if (x < 0 || y < 0) return; if (x >= grid2.cols || y >= grid2.rows) return; break; } case `unbounded`: { break; } default: { throw new Error(`Unknown BoundsLogic '${wrap4}'. Expected: wrap, stop, undefined or unbounded`); } } return Object.freeze({ x, y }); }; // src/geometry/grid/Array1d.ts var Array1d_exports = {}; __export(Array1d_exports, { access: () => access, createArray: () => createArray, createMutable: () => createMutable, set: () => set, setMutate: () => setMutate, wrap: () => wrap, wrapMutable: () => wrapMutable }); var access = (array, cols) => { const grid2 = gridFromArrayDimensions(array, cols); const fn = (cell, wrap4 = `undefined`) => accessWithGrid(grid2, array, cell, wrap4); return fn; }; var accessWithGrid = (grid2, array, cell, wrap4) => { const index = indexFromCell(grid2, cell, wrap4); if (index === void 0) return void 0; return array[index]; }; var setMutate = (array, cols) => { const grid2 = gridFromArrayDimensions(array, cols); return (value, cell, wrap4 = `undefined`) => setMutateWithGrid(grid2, array, value, cell, wrap4); }; var setMutateWithGrid = (grid2, array, value, cell, wrap4) => { const index = indexFromCell(grid2, cell, wrap4); if (index === void 0) throw new RangeError(`Cell (${cell.x},${cell.y}) is out of range of grid cols: ${grid2.cols} rows: ${grid2.rows}`); array[index] = value; return array; }; var set = (array, cols) => { const grid2 = gridFromArrayDimensions(array, cols); return (value, cell, wrap4) => setWithGrid(grid2, array, value, cell, wrap4); }; var setWithGrid = (grid2, array, value, cell, wrap4) => { const index = indexFromCell(grid2, cell, wrap4); if (index === void 0) throw new RangeError(`Cell (${cell.x},${cell.y}) is out of range of grid cols: ${grid2.cols} rows: ${grid2.rows}`); let copy = [...array]; copy[index] = value; array = copy; return copy; }; var gridFromArrayDimensions = (array, cols) => { const grid2 = { cols, rows: Math.ceil(array.length / cols) }; return grid2; }; var wrapMutable = (array, cols) => { const grid2 = gridFromArrayDimensions(array, cols); return { ...grid2, get: access(array, cols), set: setMutate(array, cols), get array() { return array; } }; }; var wrap = (array, cols) => { const grid2 = gridFromArrayDimensions(array, cols); return { ...grid2, get: (cell, boundsLogic = `undefined`) => accessWithGrid(grid2, array, cell, boundsLogic), set: (value, cell, boundsLogic = `undefined`) => { array = setWithGrid(grid2, array, value, cell, boundsLogic); return wrap(array, cols); }, get array() { return array; } }; }; var createArray = (initialValue, rowsOrGrid, columns2) => { const rows2 = typeof rowsOrGrid === `number` ? rowsOrGrid : rowsOrGrid.rows; const cols = typeof rowsOrGrid === `object` ? rowsOrGrid.cols : columns2; if (!cols) throw new Error(`Parameter 'columns' missing`); throwIntegerTest(rows2, `aboveZero`, `rows`); throwIntegerTest(cols, `aboveZero`, `cols`); let t = []; let total = rows2 * cols; for (let i = 0; i < total; i++) { t[i] = initialValue; } return t; }; var createMutable = (initialValue, rowsOrGrid, columns2) => { const rows2 = typeof rowsOrGrid === `number` ? rowsOrGrid : rowsOrGrid.rows; const cols = typeof rowsOrGrid === `object` ? rowsOrGrid.cols : columns2; if (!cols) throw new Error(`Parameter 'columns' missing`); const arr = createArray(initialValue, rows2, cols); return wrapMutable(arr, cols); }; // src/geometry/grid/Array2d.ts var Array2d_exports = {}; __export(Array2d_exports, { access: () => access2, create: () => create, set: () => set2, setMutate: () => setMutate2, wrap: () => wrap2, wrapMutable: () => wrapMutable2 }); var create = (array) => { let colLen = NaN; for (const row of array) { if (Number.isNaN(colLen)) { colLen = row.length; } else { if (colLen !== row.length) throw new Error(`Array does not have uniform column length`);