{"version":3,"file":"svg-utils.cjs","names":[],"sources":["../../src/br/svg-utils.ts"],"sourcesContent":["import type { FittedProjection } from \"@/geo/projection\";\nimport type { GeoBounds } from \"@/geo/types\";\nimport type { BrUfGeometry, Ring } from \"./br-geo\";\n\n/** Iterate every ring of a geometry (Polygon or MultiPolygon). */\nexport function ringsOf(geometry: BrUfGeometry): Ring[] {\n    return geometry.type === \"MultiPolygon\"\n        ? (geometry.coordinates as Ring[][]).flat()\n        : (geometry.coordinates as Ring[]);\n}\n\n/** Bounding box across every coordinate of the given geometries. */\nexport function geometriesBounds(geometries: readonly BrUfGeometry[]): GeoBounds {\n    let minLat = 90;\n    let maxLat = -90;\n    let minLon = 180;\n    let maxLon = -180;\n    for (const geometry of geometries) {\n        for (const ring of ringsOf(geometry)) {\n            for (const [lon, lat] of ring) {\n                if (lat < minLat) minLat = lat;\n                if (lat > maxLat) maxLat = lat;\n                if (lon < minLon) minLon = lon;\n                if (lon > maxLon) maxLon = lon;\n            }\n        }\n    }\n    return { minLatitude: minLat, maxLatitude: maxLat, minLongitude: minLon, maxLongitude: maxLon };\n}\n\n/** Build the SVG `d` path for a geometry (all rings, `evenodd` handles holes). */\nexport function geometryPath(geometry: BrUfGeometry, projection: FittedProjection): string {\n    return ringsOf(geometry)\n        .map((ring) => {\n            const pts = ring.map(([lon, lat]) => {\n                const p = projection.project({ latitude: lat, longitude: lon });\n                return `${p.x.toFixed(1)},${p.y.toFixed(1)}`;\n            });\n            return `M${pts.join(\"L\")}Z`;\n        })\n        .join(\"\");\n}\n\n/** Rough visual centroid of a geometry (mean of its largest ring's points). */\nexport function geometryCentroid(\n    geometry: BrUfGeometry,\n    projection: FittedProjection,\n): { x: number; y: number } {\n    const rings = ringsOf(geometry);\n    const outer = rings.reduce((a, b) => (b.length > a.length ? b : a), rings[0] ?? []);\n    let sx = 0;\n    let sy = 0;\n    for (const [lon, lat] of outer) {\n        const p = projection.project({ latitude: lat, longitude: lon });\n        sx += p.x;\n        sy += p.y;\n    }\n    const n = outer.length || 1;\n    return { x: sx / n, y: sy / n };\n}\n\n/** Linearly interpolate between two hex colors, returning an `rgb(...)` string. */\nexport function lerpColor(from: string, to: string, t: number): string {\n    const parse = (c: string): [number, number, number] => {\n        const hex = c.replace(\"#\", \"\");\n        const full =\n            hex.length === 3\n                ? hex\n                      .split(\"\")\n                      .map((ch) => ch + ch)\n                      .join(\"\")\n                : hex;\n        return [\n            parseInt(full.slice(0, 2), 16),\n            parseInt(full.slice(2, 4), 16),\n            parseInt(full.slice(4, 6), 16),\n        ];\n    };\n    const [r1, g1, b1] = parse(from);\n    const [r2, g2, b2] = parse(to);\n    const mix = (a: number, b: number): number => Math.round(a + (b - a) * t);\n    return `rgb(${mix(r1, r2)}, ${mix(g1, g2)}, ${mix(b1, b2)})`;\n}\n"],"mappings":"AAKA,SAAgB,EAAQ,EAAgC,CACpD,OAAO,EAAS,OAAS,eAClB,EAAS,YAAyB,KAAK,EACvC,EAAS,WACpB,CAGA,SAAgB,EAAiB,EAAgD,CAC7E,IAAI,EAAS,GACT,EAAS,IACT,EAAS,IACT,EAAS,KACb,IAAK,IAAM,KAAY,EACnB,IAAK,IAAM,KAAQ,EAAQ,CAAQ,EAC/B,IAAK,GAAM,CAAC,EAAK,KAAQ,EACjB,EAAM,IAAQ,EAAS,GACvB,EAAM,IAAQ,EAAS,GACvB,EAAM,IAAQ,EAAS,GACvB,EAAM,IAAQ,EAAS,GAIvC,MAAO,CAAE,YAAa,EAAQ,YAAa,EAAQ,aAAc,EAAQ,aAAc,CAAO,CAClG,CAGA,SAAgB,EAAa,EAAwB,EAAsC,CACvF,OAAO,EAAQ,CAAQ,CAAC,CACnB,IAAK,GAKK,IAJK,EAAK,KAAK,CAAC,EAAK,KAAS,CACjC,IAAM,EAAI,EAAW,QAAQ,CAAE,SAAU,EAAK,UAAW,CAAI,CAAC,EAC9D,MAAO,GAAG,EAAE,EAAE,QAAQ,CAAC,EAAE,GAAG,EAAE,EAAE,QAAQ,CAAC,GAC7C,CACW,CAAA,CAAI,KAAK,GAAG,EAAE,EAC5B,CAAC,CACD,KAAK,EAAE,CAChB,CAGA,SAAgB,EACZ,EACA,EACwB,CACxB,IAAM,EAAQ,EAAQ,CAAQ,EACxB,EAAQ,EAAM,QAAQ,EAAG,IAAO,EAAE,OAAS,EAAE,OAAS,EAAI,EAAI,EAAM,IAAM,CAAC,CAAC,EAC9E,EAAK,EACL,EAAK,EACT,IAAK,GAAM,CAAC,EAAK,KAAQ,EAAO,CAC5B,IAAM,EAAI,EAAW,QAAQ,CAAE,SAAU,EAAK,UAAW,CAAI,CAAC,EAC9D,GAAM,EAAE,EACR,GAAM,EAAE,CACZ,CACA,IAAM,EAAI,EAAM,QAAU,EAC1B,MAAO,CAAE,EAAG,EAAK,EAAG,EAAG,EAAK,CAAE,CAClC,CAGA,SAAgB,EAAU,EAAc,EAAY,EAAmB,CACnE,IAAM,EAAS,GAAwC,CACnD,IAAM,EAAM,EAAE,QAAQ,IAAK,EAAE,EACvB,EACF,EAAI,SAAW,EACT,EACK,MAAM,EAAE,CAAC,CACT,IAAK,GAAO,EAAK,CAAE,CAAC,CACpB,KAAK,EAAE,EACZ,EACV,MAAO,CACH,SAAS,EAAK,MAAM,EAAG,CAAC,EAAG,EAAE,EAC7B,SAAS,EAAK,MAAM,EAAG,CAAC,EAAG,EAAE,EAC7B,SAAS,EAAK,MAAM,EAAG,CAAC,EAAG,EAAE,CACjC,CACJ,EACM,CAAC,EAAI,EAAI,GAAM,EAAM,CAAI,EACzB,CAAC,EAAI,EAAI,GAAM,EAAM,CAAE,EACvB,GAAO,EAAW,IAAsB,KAAK,MAAM,GAAK,EAAI,GAAK,CAAC,EACxE,MAAO,OAAO,EAAI,EAAI,CAAE,EAAE,IAAI,EAAI,EAAI,CAAE,EAAE,IAAI,EAAI,EAAI,CAAE,EAAE,EAC9D"}