import { r as a, e as X, f as q, s as P, h as G, j as O, G as K, S as Q, i as Y, m as Z, n as ee, o as te, t as ne, l as J, E as B, _ as W, p as j, q as re, v as M, w as se, x as A, y as F, D as ae, z as ie, A as I, B as L, C as oe } from "./index-6wLGsgHc.js";
import { v as ce, d as le } from "./withFullScreenWrapper-WW0e_nhm-C14gxK5f.js";
import { X as k, R as H, y as ue } from "./Toolbar-Ba82LOXi-BP4R8EQ5.js";
import { s as fe } from "./index-GLEJ4uEg-C8vY6-j7.js";
import { m as de } from "./FormClearHelper-Dgu5Halt-DyRdP6JG.js";
var _ = /* @__PURE__ */ a.forwardRef(function(n, t) {
  var s = {
    fill: "currentColor",
    xmlns: "http://www.w3.org/2000/svg"
  };
  return /* @__PURE__ */ a.createElement(B, W({
    iconAttrs: s,
    iconVerticalAlign: "middle",
    iconViewBox: "0 0 24 24"
  }, n, {
    ref: t
  }), /* @__PURE__ */ a.createElement("path", {
    fill: "none",
    d: "M0 0h24v24H0V0z"
  }), /* @__PURE__ */ a.createElement("path", {
    d: "M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14zM7 10h2v7H7zm4-3h2v10h-2zm4 6h2v4h-2z"
  }));
});
_.displayName = "InsertChart";
var U = /* @__PURE__ */ a.forwardRef(function(n, t) {
  var s = {
    fill: "currentColor",
    xmlns: "http://www.w3.org/2000/svg"
  };
  return /* @__PURE__ */ a.createElement(B, W({
    iconAttrs: s,
    iconVerticalAlign: "middle",
    iconViewBox: "0 0 24 24"
  }, n, {
    ref: t
  }), /* @__PURE__ */ a.createElement("path", {
    fill: "none",
    d: "M0 0h24v24H0V0z"
  }), /* @__PURE__ */ a.createElement("path", {
    d: "M20 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h15c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 2v3H5V5h15zm-5 14h-5v-9h5v9zM5 10h3v9H5v-9zm12 9v-9h3v9h-3z"
  }));
});
U.displayName = "TableChart";
const me = 20;
function he(n) {
  "params" in n && "encoding" in n && n.params.forEach((t) => {
    "select" in t && (["interval", "point"].includes(t.select) && (t.select = {
      type: t.select
    }), "type" in t.select && t.select.type === "point" && !("encodings" in t.select) && M(t.select.encodings) && (t.select.encodings = Object.keys(n.encoding)));
  });
}
const ge = (n, t, s, r, u, c, l, g) => {
  const e = JSON.parse(n);
  if (r === "streamlit" ? e.config = j(e.config, c) : e.usermeta?.embedOptions?.theme === "streamlit" ? (e.config = j(e.config, c), e.usermeta.embedOptions.theme = void 0) : e.config = re(e.config, c), e.title && (typeof e.title == "string" && (e.title = {
    text: e.title
  }), e.title.limit = // Preserve existing limit if it exists,
  e.title.limit ?? // Otherwise, calculate the width - 40px to give some padding, especially
  // for the ... menu button. If the width is less than 40px, we set it to
  // 0 to avoid negative values.
  Math.max(l - 40, 0)), s && (e.height = g), t && (e.width = l, "vconcat" in e && e.vconcat.forEach((d) => {
    d.width = l;
  })), e.padding || (e.padding = {}), M(e.padding.bottom) && (e.padding.bottom = me), e.datasets) throw new Error("Datasets should not be passed as part of the spec");
  return u.length > 0 && he(e), e;
}, pe = (n, t, s, r, u) => {
  const c = Z(), {
    id: l,
    formId: g,
    spec: e,
    data: d,
    datasets: i,
    vegaLiteTheme: f,
    selectionMode: o
  } = n, p = a.useMemo(() => o, [JSON.stringify(o)]), v = a.useMemo(() => ge(e, r, u, f, p, c, t, s), [e, r, u, f, p, c, t, s]);
  return {
    id: l,
    formId: g,
    vegaLiteTheme: f,
    spec: v,
    selectionMode: p,
    data: d,
    datasets: i,
    useContainerWidth: r
  };
}, we = {
  DATAFRAME_INDEX: "(index)"
};
function ye(n) {
  return !n || n.dimensions.numDataRows === 0 ? null : D(n);
}
function ve(n) {
  const t = T(n);
  if (M(t)) return null;
  const s = {};
  for (const [r, u] of Object.entries(t)) s[r] = D(u);
  return s;
}
function T(n) {
  if (n?.length === 0) return null;
  const t = {};
  return n.forEach((s) => {
    if (!s) return;
    const r = s.hasName ? s.name : null;
    t[r] = s.data;
  }), t;
}
function D(n, t = 0) {
  if (n.dimensions.numDataRows === 0) return [];
  const s = [], {
    numDataRows: r,
    numDataColumns: u,
    numIndexColumns: c
  } = n.dimensions, l = n.columnTypes[0] ?? void 0, g = l && l.type === ae.INDEX && (ie(l) || I(l) || L(l));
  for (let e = t; e < r; e++) {
    const d = {};
    if (g) {
      const {
        content: i
      } = n.getCell(e, 0);
      d[we.DATAFRAME_INDEX] = typeof i == "bigint" ? Number(i) : i;
    }
    for (let i = 0; i < u; i++) {
      const f = i + c, {
        content: o,
        contentType: p
      } = n.getCell(e, f);
      if ((o instanceof Date || typeof o == "number" && Number.isFinite(o)) && (I(p) || L(p)) && // Only convert dates without timezone information
      // to utc timezone
      !oe(p)) {
        const v = new Date(o).getTimezoneOffset() * 60 * 1e3;
        d[n.columnNames[0][f]] = o.valueOf() + v;
      } else d[n.columnNames[0][f]] = typeof o == "bigint" ? Number(o) : o;
    }
    s.push(d);
  }
  return s;
}
const be = 150, Ce = J.getLogger("useVegaLiteSelections"), Ee = (n, t, s) => {
  const {
    id: r,
    formId: u,
    selectionMode: c
  } = n, l = a.useCallback((e) => {
    c.forEach((i) => {
      e.addSignalListener(i, se(be, (f, o) => {
        const p = e.getState({
          // There are also `signals` data, but I believe its
          // not relevant for restoring the selection state.
          data: (w, y) => c.some((E) => `${E}_store` === w),
          // Don't include subcontext data since it will lead to exceptions
          // when loading the state.
          recurse: !1
        });
        A(p) && t.setElementState(r, "viewState", p);
        let v = o;
        "vlPoint" in o && "or" in o.vlPoint && (v = o.vlPoint.or);
        const z = {
          id: r,
          formId: u
        }, h = JSON.parse(t.getStringValue(z) || "{}"), m = {
          selection: {
            ...h?.selection || {},
            [f]: v || {}
          }
        };
        F(h, m) || t.setStringValue(z, JSON.stringify(m), {
          fromUi: !0
        }, s);
      }));
    });
    const d = t.getElementState(r, "viewState");
    if (A(d)) try {
      return e.setState(d);
    } catch (i) {
      Ce.warn("Failed to restore view state", i);
    }
    return e;
  }, [r, c, t, u, s]), g = a.useCallback(() => {
    const e = {
      selection: {}
    };
    c.forEach((o) => {
      e.selection[o] = {};
    });
    const d = {
      id: r,
      formId: u
    }, i = t.getStringValue(d), f = i ? JSON.parse(i) : (
      // If there wasn't any selection yet, the selection state
      // is assumed to be empty.
      e
    );
    F(f, e) || t.setStringValue(d, JSON.stringify(e), {
      fromUi: !0
    }, s);
  }, [r, u, s, c, t]);
  return {
    maybeConfigureSelections: l,
    onFormCleared: g
  };
}, $ = "source", Se = J.getLogger("useVegaEmbed");
function Ve(n, t, s) {
  const r = a.useRef(null), u = a.useRef(null), c = a.useRef($), l = a.useRef(null), g = a.useRef([]), {
    maybeConfigureSelections: e,
    onFormCleared: d
  } = Ee(n, t, s);
  de({
    widgetMgr: t,
    element: n,
    onFormCleared: d
  });
  const {
    data: i,
    datasets: f
  } = n;
  a.useEffect(() => {
    r.current === null && (l.current = i, g.current = f);
  }, [i, f]);
  const o = a.useCallback(() => {
    u.current && u.current(), u.current = null, r.current = null;
  }, []), p = a.useCallback(async (h, m) => {
    if (h.current === null) throw new Error("Element missing.");
    o();
    const w = {
      // Adds interpreter support for Vega expressions that is compliant with CSP
      ast: !0,
      expr: te,
      // Disable default styles so that vega doesn't inject <style> tags in the
      // DOM. We set these styles manually for finer control over them and to
      // avoid inlining styles.
      tooltip: {
        disableDefaultStyle: !0
      },
      defaultStyle: !1,
      forceActionsMenu: !0
    }, {
      vgSpec: y,
      view: E,
      finalize: x
    } = await ee(h.current, m, w);
    r.current = e(E), u.current = x;
    const b = ve(g.current), S = b ? Object.keys(b) : [];
    if (S.length === 1) {
      const [C] = S;
      c.current = C;
    } else S.length === 0 && y.data && (c.current = $);
    const V = ye(l.current);
    if (V && r.current.insert(c.current, V), b) for (const [C, N] of Object.entries(b)) r.current.insert(C, N);
    return await r.current.runAsync(), await r.current.resize().runAsync(), r.current;
  }, [o, e]), v = a.useCallback((h, m, w, y) => {
    if (!y || y.dimensions.numDataRows === 0) {
      try {
        h.remove(m, ne);
      } finally {
      }
      return;
    }
    if (!w || w.dimensions.numDataRows === 0) {
      h.insert(m, D(y));
      return;
    }
    y.hash !== w.hash && (h.data(m, D(y)), Se.info(`Had to clear the ${m} dataset before inserting data through Vega view.`));
  }, []), z = a.useCallback(async (h, m) => {
    if (r.current === null) return null;
    const w = l.current, y = g.current;
    (w || h) && v(r.current, c.current, w, h);
    const E = T(y) ?? {}, x = T(m) ?? {};
    for (const [b, S] of Object.entries(x)) {
      const V = b || c.current, C = E[V];
      v(r.current, V, C, S);
    }
    for (const b of Object.keys(E)) !Object.hasOwn(x, b) && b !== c.current && v(r.current, b, null, null);
    return await r.current?.resize().runAsync(), l.current = h, g.current = m, r.current;
  }, [v]);
  return {
    createView: p,
    updateView: z,
    finalizeView: o
  };
}
function xe(n) {
  try {
    const t = typeof n == "string" ? JSON.parse(n) : n;
    return !!(t.facet || // TODO (lawilby): do some tests for row/column
    // shorthand facet charts to confirm they work with
    // sizing in the same way.
    t.encoding?.row || t.encoding?.column || t.encoding?.facet);
  } catch {
    return !1;
  }
}
const Ne = ({
  disableFullscreenMode: n,
  element: t,
  fragmentId: s,
  widgetMgr: r,
  widthConfig: u,
  heightConfig: c
}) => {
  const [l, g] = a.useState(!1), [e, d] = a.useState(!1), {
    expanded: i,
    height: f,
    width: o,
    expand: p,
    collapse: v
  } = X(le), {
    width: z,
    height: h,
    elementRef: m
  } = q(
    // We need to update whenever the showData state changes because
    // the underlying element ref that needs to be observed is updated.
    [l],
    // Use 0 as fallback instead of -1 because Vega-Lite cannot handle negative dimensions
    0
  ), w = P(u) || t.useContainerWidth, y = G(c), E = xe(t.spec), x = pe(
    t,
    // Facet charts enter a loop when using the width/height from the StyledVegaLiteChartContainer.
    E ? o ?? 0 : z,
    (i ? f : h) ?? 0,
    i ? !0 : w,
    i ? !0 : y
  ), {
    createView: b,
    updateView: S,
    finalizeView: V
  } = Ve(x, r, s), {
    data: C,
    datasets: N,
    spec: R
  } = x;
  return a.useLayoutEffect(() => (m.current !== null && b(m, R), V), [b, V, R, o, f, l, m]), a.useEffect(() => {
    S(C, N);
  }, [C, N, S]), a.useEffect(() => {
    C || N?.[0]?.data ? d(!0) : d(!1);
  }, [C, N]), l ? /* @__PURE__ */ O.jsx(fe, {
    data: C ?? N[0]?.data,
    height: f ?? h ?? void 0,
    customToolbarActions: [/* @__PURE__ */ O.jsx(k, {
      label: "Show chart",
      icon: _,
      onClick: () => {
        g(!1);
      }
    }, "show-chart")]
  }) : /* @__PURE__ */ O.jsxs(H, {
    height: y ? i ? f : "100%" : f,
    useContainerWidth: i ? !0 : w,
    children: [/* @__PURE__ */ O.jsx(ue, {
      target: H,
      isFullScreen: i,
      onExpand: p,
      onCollapse: v,
      disableFullscreenMode: n,
      children: e && /* @__PURE__ */ O.jsx(k, {
        label: "Show data",
        icon: U,
        onClick: () => {
          g(!0);
        }
      })
    }), /* @__PURE__ */ O.jsx(K, {
      styles: Q
    }), /* @__PURE__ */ O.jsx(Y, {
      "data-testid": "stVegaLiteChart",
      className: "stVegaLiteChart",
      useContainerWidth: w,
      useContainerHeight: y,
      ref: m
    })]
  });
}, Oe = ce(Ne), je = a.memo(Oe);
export {
  Q as StyledVegaLiteChartTooltips,
  j as applyStreamlitTheme,
  je as default
};
//# sourceMappingURL=index-DhLLbarZ-kDRg26CV.js.map
