import { VIBE_PRESETS, DEFAULT_VIBE, resolveVibe, vibeToRoughOptions } from './chunk-3TD64277.js';
import { createContext, useMemo, useContext, useId } from 'react';
import { jsx, jsxs } from 'react/jsx-runtime';
import { scaleLinear, scaleBand, scalePoint, scaleSqrt } from 'd3-scale';
import rough from 'roughjs';

var VibeContext = createContext(VIBE_PRESETS[DEFAULT_VIBE]);
function VibeProvider({ vibe, brandOverrides, children }) {
  const resolved = useMemo(() => resolveVibe(vibe, brandOverrides), [vibe, brandOverrides]);
  return /* @__PURE__ */ jsx(VibeContext.Provider, { value: resolved, children });
}
function useVibeContext() {
  return useContext(VibeContext);
}
function useResolvedVibe(localVibe, seed) {
  const contextVibe = useVibeContext();
  return useMemo(() => {
    const base = localVibe === void 0 ? contextVibe : resolveVibe(localVibe);
    return seed === void 0 ? base : { ...base, seed };
  }, [localVibe, contextVibe, seed]);
}
function linearScale(domain, range) {
  return scaleLinear().domain(domain).range(range);
}
function bandScale(domain, range, padding = 0.2) {
  return scaleBand().domain(domain).range(range).padding(padding);
}
function pointScale(domain, range, padding = 0.5) {
  return scalePoint().domain(domain).range(range).padding(padding);
}
function sqrtScale(domain, range) {
  return scaleSqrt().domain(domain).range(range);
}
function extentOf(values, includeZero = true) {
  const finite = values.filter((v) => Number.isFinite(v));
  if (finite.length === 0) return [0, 1];
  let min = Math.min(...finite);
  let max = Math.max(...finite);
  if (includeZero) {
    min = Math.min(min, 0);
    max = Math.max(max, 0);
  }
  if (min === max) max = min + 1;
  return [min, max];
}

// src/core/text.ts
var HELVETICA_1000 = {
  " ": 278,
  "!": 278,
  '"': 355,
  "#": 556,
  $: 556,
  "%": 889,
  "&": 667,
  "'": 191,
  "(": 333,
  ")": 333,
  "*": 389,
  "+": 584,
  ",": 278,
  "-": 333,
  ".": 278,
  "/": 278,
  "0": 556,
  "1": 556,
  "2": 556,
  "3": 556,
  "4": 556,
  "5": 556,
  "6": 556,
  "7": 556,
  "8": 556,
  "9": 556,
  ":": 278,
  ";": 278,
  "<": 584,
  "=": 584,
  ">": 584,
  "?": 556,
  "@": 1015,
  A: 667,
  B: 667,
  C: 722,
  D: 722,
  E: 667,
  F: 611,
  G: 778,
  H: 722,
  I: 278,
  J: 500,
  K: 667,
  L: 556,
  M: 833,
  N: 722,
  O: 778,
  P: 667,
  Q: 778,
  R: 722,
  S: 667,
  T: 611,
  U: 722,
  V: 667,
  W: 944,
  X: 667,
  Y: 667,
  Z: 611,
  "[": 278,
  "\\": 278,
  "]": 278,
  "^": 469,
  _: 556,
  "`": 333,
  a: 556,
  b: 556,
  c: 500,
  d: 556,
  e: 556,
  f: 278,
  g: 556,
  h: 556,
  i: 222,
  j: 222,
  k: 500,
  l: 222,
  m: 833,
  n: 556,
  o: 556,
  p: 556,
  q: 556,
  r: 333,
  s: 500,
  t: 278,
  u: 556,
  v: 500,
  w: 722,
  x: 500,
  y: 500,
  z: 500,
  "{": 334,
  "|": 260,
  "}": 334,
  "~": 584
};
function charEm(ch) {
  return (HELVETICA_1000[ch] ?? 556) / 1e3;
}
function familyFactor(fontFamily) {
  const f = fontFamily.toLowerCase();
  if (f.includes("mono") || f.includes("courier")) return { fixed: 0.6, scale: 1 };
  if (f.includes("comic") || f.includes("print") || f.includes("cursive")) return { fixed: null, scale: 1.08 };
  return { fixed: null, scale: 1 };
}
function measureText(text, fontSize, fontFamily) {
  const { fixed, scale } = familyFactor(fontFamily);
  let em = 0;
  for (const ch of text) em += fixed ?? charEm(ch);
  return { width: em * fontSize * scale, height: fontSize * 1.2 };
}
function wrapText(text, maxWidth, fontSize, fontFamily) {
  const words = text.split(/\s+/).filter(Boolean);
  if (words.length === 0) return [];
  const lines = [];
  let line = "";
  const fits = (s) => measureText(s, fontSize, fontFamily).width <= maxWidth;
  for (const word of words) {
    const candidate = line ? `${line} ${word}` : word;
    if (fits(candidate) || !line) {
      if (fits(candidate)) {
        line = candidate;
        continue;
      }
      let chunk = "";
      for (const ch of word) {
        if (chunk && !fits(chunk + ch)) {
          lines.push(chunk);
          chunk = ch;
        } else {
          chunk += ch;
        }
      }
      line = chunk;
    } else {
      lines.push(line);
      line = word;
    }
  }
  if (line) lines.push(line);
  return lines;
}
function autoMargin(labels, fontSize, fontFamily, base, pad = 8) {
  const widest = labels.reduce((max, l) => Math.max(max, measureText(l, fontSize, fontFamily).width), 0);
  const lineHeight = fontSize * 1.2;
  return {
    ...base,
    left: Math.max(base.left, Math.ceil(widest + pad)),
    bottom: Math.max(base.bottom, Math.ceil(lineHeight + pad))
  };
}
var generator = null;
function getRoughGenerator() {
  if (generator === null) {
    generator = rough.generator();
  }
  return generator;
}
function allFinite(...nums) {
  return nums.every((n) => Number.isFinite(n));
}
function pathIsRenderable(d) {
  if (d.trim() === "") return false;
  return !/NaN|Infinity/.test(d);
}
function drawableToPaths(drawable) {
  const infos = getRoughGenerator().toPaths(drawable);
  const sets = drawable.sets ?? [];
  return infos.map((info, i) => ({
    ...info,
    kind: sets[i]?.type === "path" ? "stroke" : "fill"
  }));
}
function SketchPaths({
  paths,
  className,
  style,
  onClick,
  dataAttrs,
  onPointerEnter,
  onPointerMove,
  onPointerLeave,
  onPointerDown,
  onPointerUp,
  children,
  animate,
  clip
}) {
  const rawId = useId();
  const hasFill = paths.some((p) => p.kind === "fill");
  const clipId = clip && hasFill ? `gc-clip-${rawId.replace(/:/g, "")}` : null;
  return /* @__PURE__ */ jsxs(
    "g",
    {
      className,
      style,
      onClick,
      onPointerEnter,
      onPointerMove,
      onPointerLeave,
      onPointerDown,
      onPointerUp,
      ...dataAttrs,
      children: [
        clipId ? /* @__PURE__ */ jsx("clipPath", { id: clipId, children: /* @__PURE__ */ jsx("path", { d: clip }) }) : null,
        dataAttrs && clip ? /* @__PURE__ */ jsx("path", { d: clip, fill: "transparent", stroke: "none", "data-gc-hit": "" }) : null,
        paths.map((p, i) => {
          const isStroke = p.kind === "stroke";
          return /* @__PURE__ */ jsx(
            "path",
            {
              d: p.d,
              stroke: p.stroke,
              strokeWidth: p.strokeWidth,
              fill: p.fill,
              strokeLinecap: "round",
              strokeLinejoin: "round",
              clipPath: !isStroke && clipId ? `url(#${clipId})` : void 0,
              className: animate ? isStroke ? "gc-draw-stroke" : "gc-draw-fill" : void 0,
              pathLength: animate && isStroke ? 1 : void 0
            },
            i
          );
        }),
        children
      ]
    }
  );
}
function RoughLine({
  x1,
  y1,
  x2,
  y2,
  vibe,
  seed,
  stroke,
  className,
  style,
  onClick,
  dataAttrs,
  onPointerEnter,
  onPointerMove,
  onPointerLeave,
  onPointerDown,
  onPointerUp
}) {
  const resolved = useResolvedVibe(vibe, seed);
  const paths = useMemo(() => {
    if (!allFinite(x1, y1, x2, y2)) return [];
    const options = vibeToRoughOptions({ ...resolved, stroke: stroke ?? resolved.stroke }, resolved.seed);
    const drawable = getRoughGenerator().line(x1, y1, x2, y2, options);
    return drawableToPaths(drawable);
  }, [x1, y1, x2, y2, resolved, stroke]);
  return /* @__PURE__ */ jsx(
    SketchPaths,
    {
      paths,
      className,
      style,
      onClick,
      dataAttrs,
      onPointerEnter,
      onPointerMove,
      onPointerLeave,
      onPointerDown,
      onPointerUp,
      animate: !!resolved.animate?.drawOn
    }
  );
}
function RoughRectangle({
  x,
  y,
  width,
  height,
  vibe,
  seed,
  stroke,
  fill,
  className,
  style,
  onClick,
  dataAttrs,
  onPointerEnter,
  onPointerMove,
  onPointerLeave,
  onPointerDown,
  onPointerUp,
  children
}) {
  const resolved = useResolvedVibe(vibe, seed);
  const paths = useMemo(() => {
    if (!allFinite(x, y, width, height)) return [];
    const shapeVibe = {
      ...resolved,
      stroke: stroke ?? resolved.stroke,
      fill: fill === void 0 ? resolved.fill : fill
    };
    const options = vibeToRoughOptions(shapeVibe, shapeVibe.seed);
    const drawable = getRoughGenerator().rectangle(x, y, width, height, options);
    return drawableToPaths(drawable);
  }, [x, y, width, height, resolved, stroke, fill]);
  const clip = allFinite(x, y, width, height) ? `M${x},${y}h${width}v${height}h${-width}z` : void 0;
  return /* @__PURE__ */ jsx(
    SketchPaths,
    {
      paths,
      className,
      style,
      onClick,
      dataAttrs,
      onPointerEnter,
      onPointerMove,
      onPointerLeave,
      onPointerDown,
      onPointerUp,
      animate: !!resolved.animate?.drawOn,
      clip,
      children
    }
  );
}
var BASELINE_MAP = {
  auto: "auto",
  middle: "central",
  hanging: "hanging"
};
var LINE_EM = 1.2;
function RoughText({
  x,
  y,
  children,
  anchor = "middle",
  baseline = "middle",
  rotate,
  vibe,
  seed,
  fill,
  haloColor,
  maxWidth,
  className,
  style,
  onClick,
  dataAttrs,
  onPointerEnter,
  onPointerMove,
  onPointerLeave,
  onPointerDown,
  onPointerUp
}) {
  const resolved = useResolvedVibe(vibe, seed);
  const lines = maxWidth ? wrapText(children, maxWidth, resolved.fontSize, resolved.fontFamily) : null;
  const halo = haloColor ?? resolved.background;
  const haloWidth = halo ? Math.max(2, resolved.fontSize * 0.18) : void 0;
  const content = lines && lines.length > 1 ? lines.map((line, i) => /* @__PURE__ */ jsx("tspan", { x, dy: `${i === 0 ? -((lines.length - 1) * LINE_EM) / 2 : LINE_EM}em`, children: line }, i)) : children;
  return /* @__PURE__ */ jsx(
    "text",
    {
      x,
      y,
      textAnchor: anchor,
      dominantBaseline: BASELINE_MAP[baseline],
      transform: rotate ? `rotate(${rotate} ${x} ${y})` : void 0,
      fontFamily: resolved.fontFamily,
      fontSize: resolved.fontSize,
      fill: fill ?? resolved.stroke,
      stroke: halo,
      strokeWidth: haloWidth,
      strokeLinejoin: "round",
      paintOrder: halo ? "stroke" : void 0,
      textRendering: "geometricPrecision",
      className,
      style,
      onClick,
      onPointerEnter,
      onPointerMove,
      onPointerLeave,
      onPointerDown,
      onPointerUp,
      ...dataAttrs,
      children: content
    }
  );
}
var defaultSeriesVisibility = { hidden: /* @__PURE__ */ new Set(), toggle: () => {
}, interactive: false };
var Ctx = createContext(defaultSeriesVisibility);
var SeriesVisibilityProvider = Ctx.Provider;
function useSeriesVisibility() {
  return useContext(Ctx);
}

export { RoughLine, RoughRectangle, RoughText, SeriesVisibilityProvider, SketchPaths, VibeProvider, allFinite, autoMargin, bandScale, defaultSeriesVisibility, drawableToPaths, extentOf, getRoughGenerator, linearScale, measureText, pathIsRenderable, pointScale, sqrtScale, useResolvedVibe, useSeriesVisibility, useVibeContext, wrapText };
//# sourceMappingURL=chunk-2FBXYIJM.js.map
//# sourceMappingURL=chunk-2FBXYIJM.js.map