@anuma/sdk 11.2.0 → 11.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -34529,6 +34529,159 @@ import {
34529
34529
  XAxis,
34530
34530
  YAxis
34531
34531
  } from "recharts";
34532
+
34533
+ // src/tools/chartModel.ts
34534
+ var DOT_LIMIT = 12;
34535
+ var MAX_TICKS = 8;
34536
+ var MINUS = "\u2212";
34537
+ function chartCellText(value) {
34538
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : "";
34539
+ }
34540
+ function tickDigits(ticks) {
34541
+ if (!ticks || ticks.length < 2) return 3;
34542
+ const step = ticks[1] - ticks[0];
34543
+ const magnitude = Math.max(...ticks.map(Math.abs));
34544
+ if (step <= 0 || magnitude === 0) return 3;
34545
+ const needed = Math.floor(Math.log10(magnitude)) - Math.floor(Math.log10(step)) + 1;
34546
+ return Math.min(21, Math.max(3, needed));
34547
+ }
34548
+ function keepSmall(options) {
34549
+ const small = new Intl.NumberFormat(void 0, { ...options, maximumSignificantDigits: 3 });
34550
+ const regular = new Intl.NumberFormat(void 0, { ...options, maximumFractionDigits: 2 });
34551
+ return (n, format) => format(n !== 0 && Math.abs(n) < 1 ? small : regular, n);
34552
+ }
34553
+ function buildFormatters(format, currency, ticks) {
34554
+ const digits = tickDigits(ticks);
34555
+ if (format === "currency") {
34556
+ const money = (options) => new Intl.NumberFormat(void 0, {
34557
+ style: "currency",
34558
+ currency: currency ?? "USD",
34559
+ ...options
34560
+ });
34561
+ const compact2 = money({ notation: "compact", maximumSignificantDigits: 3 });
34562
+ const tick2 = money({ notation: "compact", maximumSignificantDigits: digits });
34563
+ const small2 = money({ maximumSignificantDigits: 4 });
34564
+ const cents = money({ minimumFractionDigits: 2, maximumFractionDigits: 2 });
34565
+ const value2 = (n) => Math.abs(n) >= 1e6 ? compact2.format(n) : n !== 0 && Math.abs(n) < 1 ? small2.format(n) : cents.format(n);
34566
+ return { tick: (n) => tick2.format(n), value: value2, change: (d) => value2(Math.abs(d)) };
34567
+ }
34568
+ if (format === "percent") {
34569
+ const percent = keepSmall({ style: "percent" });
34570
+ const points = keepSmall({});
34571
+ const tick2 = new Intl.NumberFormat(void 0, {
34572
+ style: "percent",
34573
+ maximumSignificantDigits: digits
34574
+ });
34575
+ return {
34576
+ tick: (n) => tick2.format(n / 100),
34577
+ value: (n) => percent(n, (formatter) => formatter.format(n / 100)),
34578
+ change: (d) => `${points(Math.abs(d), (formatter, n) => formatter.format(n))} pts`
34579
+ };
34580
+ }
34581
+ const tick = new Intl.NumberFormat(void 0, {
34582
+ notation: "compact",
34583
+ maximumSignificantDigits: digits
34584
+ });
34585
+ const compact = new Intl.NumberFormat(void 0, {
34586
+ notation: "compact",
34587
+ maximumSignificantDigits: 3
34588
+ });
34589
+ const small = new Intl.NumberFormat(void 0, { maximumSignificantDigits: 4 });
34590
+ const plain2 = new Intl.NumberFormat(void 0, { maximumFractionDigits: 2 });
34591
+ const value = (n) => Math.abs(n) >= 1e6 ? compact.format(n) : n !== 0 && Math.abs(n) < 1 ? small.format(n) : plain2.format(n);
34592
+ return { tick: (n) => tick.format(n), value, change: (d) => value(Math.abs(d)) };
34593
+ }
34594
+ function seriesValues(points, keys) {
34595
+ return points.flatMap(
34596
+ (point) => keys.map((key3) => point[key3]).filter((v) => typeof v === "number")
34597
+ );
34598
+ }
34599
+ function niceStep(rough) {
34600
+ const exponent = Math.floor(Math.log10(rough));
34601
+ const base = 10 ** exponent;
34602
+ const fraction = rough / base;
34603
+ const nice = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 2.5 ? 2.5 : fraction <= 5 ? 5 : 10;
34604
+ return nice * base;
34605
+ }
34606
+ function niceTicks(values) {
34607
+ if (values.length === 0) return void 0;
34608
+ const min = Math.min(...values);
34609
+ const max = Math.max(...values);
34610
+ const span = max - min || Math.abs(max) * 0.02 || 1;
34611
+ const low = min - span * 0.1;
34612
+ const high = max + span * 0.1;
34613
+ const step = niceStep((high - low) / 3);
34614
+ const start = min >= 0 ? Math.max(0, Math.floor(low / step) * step) : Math.floor(low / step) * step;
34615
+ const ticks = [];
34616
+ for (let index = 0; index <= MAX_TICKS; index++) {
34617
+ const tick = Number((start + index * step).toPrecision(15));
34618
+ if (ticks.length > 0 && tick <= ticks[ticks.length - 1]) break;
34619
+ ticks.push(tick);
34620
+ if (tick >= high) break;
34621
+ }
34622
+ return ticks.length >= 2 ? ticks : void 0;
34623
+ }
34624
+ function buildTrend(values, format, formatters) {
34625
+ if (values.length < 2) return void 0;
34626
+ const first = values[0];
34627
+ const last = values[values.length - 1];
34628
+ const difference = last - first;
34629
+ const direction = difference > 0 ? "up" : difference < 0 ? "down" : "flat";
34630
+ const sign = direction === "up" ? "+" : direction === "down" ? MINUS : "";
34631
+ const percent = format !== "percent" && first !== 0 ? ` (${sign}${new Intl.NumberFormat(void 0, { maximumFractionDigits: 2 }).format(
34632
+ Math.abs(difference / Math.abs(first) * 100)
34633
+ )}%)` : "";
34634
+ return {
34635
+ value: formatters.value(last),
34636
+ change: `${sign}${formatters.change(difference)}${percent}`,
34637
+ direction
34638
+ };
34639
+ }
34640
+ function lastValueIndex(points, key3) {
34641
+ for (let index = points.length - 1; index >= 0; index--) {
34642
+ if (typeof points[index][key3] === "number") return index;
34643
+ }
34644
+ return -1;
34645
+ }
34646
+ function chartSeriesLabel(key3) {
34647
+ return key3.charAt(0).toUpperCase() + key3.slice(1);
34648
+ }
34649
+ function buildChartModel(spec) {
34650
+ const { chartType, title, data, dataKeys, xAxisKey, valueFormat, currency } = spec;
34651
+ const isTrendChart = chartType === "line" || chartType === "area";
34652
+ const plottedKeys = chartType === "pie" ? dataKeys.slice(0, 1) : dataKeys;
34653
+ const values = seriesValues(data, plottedKeys);
34654
+ const yTicks = isTrendChart ? niceTicks(values) : void 0;
34655
+ const yDomain = yTicks ? [yTicks[0], yTicks[yTicks.length - 1]] : void 0;
34656
+ const formatters = buildFormatters(valueFormat, currency, yTicks);
34657
+ const seriesLabels = Object.fromEntries(dataKeys.map((key3) => [key3, chartSeriesLabel(key3)]));
34658
+ const trendBase = isTrendChart && dataKeys.length === 1 ? buildTrend(values, valueFormat, formatters) : void 0;
34659
+ const trendRows = trendBase ? data.filter((point) => typeof point[dataKeys[0]] === "number") : [];
34660
+ const range = trendBase && xAxisKey ? [trendRows[0], trendRows[trendRows.length - 1]].map((point) => chartCellText(point[xAxisKey])).filter(Boolean).join(" \u2013 ") || void 0 : void 0;
34661
+ const trend = trendBase ? { ...trendBase, range } : void 0;
34662
+ const tickSamples = [...yDomain ?? [], ...values].map((value) => formatters.tick(value));
34663
+ const showDots = data.length <= DOT_LIMIT;
34664
+ return {
34665
+ isTrendChart,
34666
+ plottedKeys,
34667
+ seriesLabels,
34668
+ labelKey: chartType === "pie" ? xAxisKey || "name" : xAxisKey,
34669
+ values,
34670
+ yTicks,
34671
+ yDomain,
34672
+ formatters,
34673
+ trend,
34674
+ title: title ?? (trend ? seriesLabels[dataKeys[0]] : void 0),
34675
+ showDots,
34676
+ endIndexes: Object.fromEntries(plottedKeys.map((key3) => [key3, lastValueIndex(data, key3)])),
34677
+ curve: showDots ? "linear" : "monotone",
34678
+ hasNegative: values.some((value) => value < 0),
34679
+ longestTickLength: tickSamples.reduce((max, label) => Math.max(max, label.length), 0),
34680
+ total: values.reduce((sum, value) => sum + value, 0)
34681
+ };
34682
+ }
34683
+
34684
+ // src/react/chart.tsx
34532
34685
  import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
34533
34686
  function cx(...classes) {
34534
34687
  return classes.filter(Boolean).join(" ");
@@ -34725,7 +34878,7 @@ function ChartLegendContent({
34725
34878
  style: { backgroundColor: item.color }
34726
34879
  }
34727
34880
  ),
34728
- itemConfig?.label ?? cellText(item.value)
34881
+ itemConfig?.label ?? chartCellText(item.value)
34729
34882
  ]
34730
34883
  },
34731
34884
  String(item.value)
@@ -34753,15 +34906,9 @@ var DEFAULT_COLORS = [
34753
34906
  "var(--chart-5)"
34754
34907
  ];
34755
34908
  var SURFACE = "var(--chart-surface)";
34756
- var DOT_LIMIT = 12;
34757
- var MAX_TICKS = 8;
34758
- var MINUS = "\u2212";
34759
34909
  function paletteColor(index) {
34760
34910
  return index < DEFAULT_COLORS.length ? DEFAULT_COLORS[index] : `hsl(${Math.round(index * 137.508 % 360)} 65% 55%)`;
34761
34911
  }
34762
- function cellText(value) {
34763
- return typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? String(value) : "";
34764
- }
34765
34912
  var VISUALLY_HIDDEN = {
34766
34913
  position: "absolute",
34767
34914
  width: 1,
@@ -34773,107 +34920,17 @@ var VISUALLY_HIDDEN = {
34773
34920
  whiteSpace: "nowrap",
34774
34921
  border: 0
34775
34922
  };
34776
- function tickDigits(ticks) {
34777
- if (!ticks || ticks.length < 2) return 3;
34778
- const step = ticks[1] - ticks[0];
34779
- const magnitude = Math.max(...ticks.map(Math.abs));
34780
- if (step <= 0 || magnitude === 0) return 3;
34781
- const needed = Math.floor(Math.log10(magnitude)) - Math.floor(Math.log10(step)) + 1;
34782
- return Math.min(21, Math.max(3, needed));
34783
- }
34784
- function keepSmall(options) {
34785
- const small = new Intl.NumberFormat(void 0, { ...options, maximumSignificantDigits: 3 });
34786
- const regular = new Intl.NumberFormat(void 0, { ...options, maximumFractionDigits: 2 });
34787
- return (n, format) => format(n !== 0 && Math.abs(n) < 1 ? small : regular, n);
34788
- }
34789
- function buildFormatters(format, currency, ticks) {
34790
- const digits = tickDigits(ticks);
34791
- if (format === "currency") {
34792
- const money = (options) => new Intl.NumberFormat(void 0, {
34793
- style: "currency",
34794
- currency: currency ?? "USD",
34795
- ...options
34796
- });
34797
- const compact2 = money({ notation: "compact", maximumSignificantDigits: 3 });
34798
- const tick2 = money({ notation: "compact", maximumSignificantDigits: digits });
34799
- const small2 = money({ maximumSignificantDigits: 4 });
34800
- const cents = money({ minimumFractionDigits: 2, maximumFractionDigits: 2 });
34801
- const value2 = (n) => Math.abs(n) >= 1e6 ? compact2.format(n) : n !== 0 && Math.abs(n) < 1 ? small2.format(n) : cents.format(n);
34802
- return { tick: (n) => tick2.format(n), value: value2, change: (d) => value2(Math.abs(d)) };
34803
- }
34804
- if (format === "percent") {
34805
- const percent = keepSmall({ style: "percent" });
34806
- const points = keepSmall({});
34807
- const tick2 = new Intl.NumberFormat(void 0, {
34808
- style: "percent",
34809
- maximumSignificantDigits: digits
34810
- });
34811
- return {
34812
- tick: (n) => tick2.format(n / 100),
34813
- value: (n) => percent(n, (formatter) => formatter.format(n / 100)),
34814
- change: (d) => `${points(Math.abs(d), (formatter, n) => formatter.format(n))} pts`
34815
- };
34816
- }
34817
- const tick = new Intl.NumberFormat(void 0, {
34818
- notation: "compact",
34819
- maximumSignificantDigits: digits
34820
- });
34821
- const compact = new Intl.NumberFormat(void 0, {
34822
- notation: "compact",
34823
- maximumSignificantDigits: 3
34824
- });
34825
- const small = new Intl.NumberFormat(void 0, { maximumSignificantDigits: 4 });
34826
- const plain2 = new Intl.NumberFormat(void 0, { maximumFractionDigits: 2 });
34827
- const value = (n) => Math.abs(n) >= 1e6 ? compact.format(n) : n !== 0 && Math.abs(n) < 1 ? small.format(n) : plain2.format(n);
34828
- return { tick: (n) => tick.format(n), value, change: (d) => value(Math.abs(d)) };
34829
- }
34830
- function seriesValues(points, keys) {
34831
- return points.flatMap(
34832
- (point) => keys.map((key3) => point[key3]).filter((v) => typeof v === "number")
34833
- );
34834
- }
34835
- function niceStep(rough) {
34836
- const exponent = Math.floor(Math.log10(rough));
34837
- const base = 10 ** exponent;
34838
- const fraction = rough / base;
34839
- const nice = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 2.5 ? 2.5 : fraction <= 5 ? 5 : 10;
34840
- return nice * base;
34841
- }
34842
- function niceTicks(values) {
34843
- if (values.length === 0) return void 0;
34844
- const min = Math.min(...values);
34845
- const max = Math.max(...values);
34846
- const span = max - min || Math.abs(max) * 0.02 || 1;
34847
- const low = min - span * 0.1;
34848
- const high = max + span * 0.1;
34849
- const step = niceStep((high - low) / 3);
34850
- const start = min >= 0 ? Math.max(0, Math.floor(low / step) * step) : Math.floor(low / step) * step;
34851
- const ticks = [];
34852
- for (let index = 0; index <= MAX_TICKS; index++) {
34853
- const tick = Number((start + index * step).toPrecision(15));
34854
- if (ticks.length > 0 && tick <= ticks[ticks.length - 1]) break;
34855
- ticks.push(tick);
34856
- if (tick >= high) break;
34857
- }
34858
- return ticks.length >= 2 ? ticks : void 0;
34859
- }
34860
- function buildChartConfig(dataKeys, colors) {
34923
+ function buildChartConfig(dataKeys, labels, colors) {
34861
34924
  const config = {};
34862
34925
  dataKeys.forEach((key3, i) => {
34863
34926
  const custom = colors?.[key3];
34864
34927
  config[key3] = {
34865
- label: key3.charAt(0).toUpperCase() + key3.slice(1),
34928
+ label: labels[key3],
34866
34929
  color: isSafeCssColor(custom) ? custom : paletteColor(i)
34867
34930
  };
34868
34931
  });
34869
34932
  return config;
34870
34933
  }
34871
- function lastValueIndex(points, key3) {
34872
- for (let index = points.length - 1; index >= 0; index--) {
34873
- if (typeof points[index][key3] === "number") return index;
34874
- }
34875
- return -1;
34876
- }
34877
34934
  function usePrefersReducedMotion() {
34878
34935
  const [reduced, setReduced] = React2.useState(false);
34879
34936
  React2.useEffect(() => {
@@ -34886,33 +34943,13 @@ function usePrefersReducedMotion() {
34886
34943
  }, []);
34887
34944
  return reduced;
34888
34945
  }
34889
- function buildTrend(values, format, formatters) {
34890
- if (values.length < 2) return void 0;
34891
- const first = values[0];
34892
- const last = values[values.length - 1];
34893
- const difference = last - first;
34894
- const direction = difference > 0 ? "up" : difference < 0 ? "down" : "flat";
34895
- const sign = direction === "up" ? "+" : direction === "down" ? MINUS : "";
34896
- const percent = format !== "percent" && first !== 0 ? ` (${sign}${new Intl.NumberFormat(void 0, { maximumFractionDigits: 2 }).format(
34897
- Math.abs(difference / Math.abs(first) * 100)
34898
- )}%)` : "";
34899
- return {
34900
- value: formatters.value(last),
34901
- change: `${sign}${formatters.change(difference)}${percent}`,
34902
- direction
34903
- };
34904
- }
34905
34946
  var TREND_CLASS = {
34906
34947
  up: "text-emerald-600 dark:text-emerald-400",
34907
34948
  down: "text-red-600 dark:text-red-400",
34908
34949
  flat: "text-muted-foreground"
34909
34950
  };
34910
34951
  var TREND_ARROW = { up: "\u25B2", down: "\u25BC", flat: "" };
34911
- function ChartHeader({
34912
- title,
34913
- trend,
34914
- range
34915
- }) {
34952
+ function ChartHeader({ title, trend }) {
34916
34953
  if (!trend) {
34917
34954
  return title ? /* @__PURE__ */ jsx2("p", { className: "mb-3 text-sm font-medium", children: title }) : null;
34918
34955
  }
@@ -34924,7 +34961,7 @@ function ChartHeader({
34924
34961
  TREND_ARROW[trend.direction] && /* @__PURE__ */ jsx2("span", { "aria-hidden": "true", className: "mr-1 text-[0.6rem]", children: TREND_ARROW[trend.direction] }),
34925
34962
  trend.change
34926
34963
  ] }),
34927
- range && /* @__PURE__ */ jsx2("span", { className: "text-muted-foreground", children: range })
34964
+ trend.range && /* @__PURE__ */ jsx2("span", { className: "text-muted-foreground", children: trend.range })
34928
34965
  ] })
34929
34966
  ] });
34930
34967
  }
@@ -34940,34 +34977,13 @@ function ChartCard({ data }) {
34940
34977
  if ("error" in data) {
34941
34978
  return /* @__PURE__ */ jsx2("div", { className: "my-4 max-w-lg", children: /* @__PURE__ */ jsx2("div", { className: "rounded-xl bg-sidebar dark:bg-card px-4 py-3", children: /* @__PURE__ */ jsx2("p", { className: "text-sm text-muted-foreground", children: "Couldn't display this chart." }) }) });
34942
34979
  }
34943
- const {
34944
- chartType,
34945
- title,
34946
- data: chartData,
34947
- dataKeys,
34948
- xAxisKey,
34949
- colors,
34950
- valueFormat,
34951
- currency
34952
- } = data;
34953
- const chartConfig = buildChartConfig(dataKeys, colors);
34980
+ const { chartType, title, data: chartData, dataKeys, xAxisKey, colors } = data;
34981
+ const model = buildChartModel(data);
34982
+ const { plottedKeys, yTicks, yDomain, formatters, trend, isTrendChart } = model;
34983
+ const chartConfig = buildChartConfig(dataKeys, model.seriesLabels, colors);
34954
34984
  const seriesColor = (key3) => chartConfig[key3]?.color;
34955
- const isTrendChart = chartType === "line" || chartType === "area";
34956
- const plottedKeys = chartType === "pie" ? dataKeys.slice(0, 1) : dataKeys;
34957
- const values = seriesValues(chartData, plottedKeys);
34958
- const yTicks = isTrendChart ? niceTicks(values) : void 0;
34959
- const yDomain = yTicks ? [yTicks[0], yTicks[yTicks.length - 1]] : void 0;
34960
- const formatters = buildFormatters(valueFormat, currency, yTicks);
34961
- const trend = isTrendChart && dataKeys.length === 1 ? buildTrend(values, valueFormat, formatters) : void 0;
34962
- const trendRows = trend ? chartData.filter((point) => typeof point[dataKeys[0]] === "number") : [];
34963
- const range = trend && xAxisKey ? [trendRows[0], trendRows[trendRows.length - 1]].map((point) => cellText(point[xAxisKey])).filter(Boolean).join(" \u2013 ") : void 0;
34964
- const headerTitle = title ?? (trend ? chartConfig[dataKeys[0]]?.label : void 0);
34965
- const tickSamples = [...yDomain ?? [], ...values].map((value) => formatters.tick(value));
34966
- const longestTick = tickSamples.reduce((max, label) => Math.max(max, label.length), 0);
34967
34985
  const animate = !reducedMotion;
34968
- const showDots = chartData.length <= DOT_LIMIT;
34969
- const curve = showDots ? "linear" : "monotone";
34970
- const hasNegative = values.some((value) => value < 0);
34986
+ const { showDots, curve, hasNegative, endIndexes } = model;
34971
34987
  const margin = { top: 8, right: 8, bottom: 0, left: 0 };
34972
34988
  const xAxis = xAxisKey && /* @__PURE__ */ jsx2(
34973
34989
  XAxis,
@@ -34992,7 +35008,7 @@ function ChartCard({ data }) {
34992
35008
  tickFormatter: formatters.tick,
34993
35009
  domain: yDomain,
34994
35010
  allowDataOverflow: false,
34995
- width: Math.min(120, Math.max(36, longestTick * 7 + 12))
35011
+ width: Math.min(120, Math.max(36, model.longestTickLength * 7 + 12))
34996
35012
  }
34997
35013
  );
34998
35014
  const tooltip = /* @__PURE__ */ jsx2(
@@ -35015,9 +35031,8 @@ function ChartCard({ data }) {
35015
35031
  stroke: SURFACE,
35016
35032
  strokeWidth: 2
35017
35033
  });
35018
- const lineDot = (key3) => showDots ? marker(key3, 4) : (props) => props.index === lastValueIndex(chartData, key3) && typeof props.cx === "number" && typeof props.cy === "number" ? /* @__PURE__ */ jsx2("circle", { cx: props.cx, cy: props.cy, ...marker(key3, 4) }, `end-${key3}`) : /* @__PURE__ */ jsx2("g", {}, `dot-${key3}-${props.index}`);
35019
- const labelKey = chartType === "pie" ? xAxisKey || "name" : xAxisKey;
35020
- const tableColumns = labelKey ? [labelKey, ...plottedKeys] : plottedKeys;
35034
+ const lineDot = (key3) => showDots ? marker(key3, 4) : (props) => props.index === endIndexes[key3] && typeof props.cx === "number" && typeof props.cy === "number" ? /* @__PURE__ */ jsx2("circle", { cx: props.cx, cy: props.cy, ...marker(key3, 4) }, `end-${key3}`) : /* @__PURE__ */ jsx2("g", {}, `dot-${key3}-${props.index}`);
35035
+ const tableColumns = model.labelKey ? [model.labelKey, ...plottedKeys] : plottedKeys;
35021
35036
  return /* @__PURE__ */ jsx2(
35022
35037
  "div",
35023
35038
  {
@@ -35026,10 +35041,10 @@ function ChartCard({ data }) {
35026
35041
  role: "figure",
35027
35042
  "aria-label": [title, `${chartType} chart`].filter(Boolean).join(", "),
35028
35043
  children: /* @__PURE__ */ jsxs("div", { className: "rounded-xl bg-sidebar dark:bg-card px-5 py-4 [--chart-surface:var(--sidebar)] dark:[--chart-surface:var(--card)]", children: [
35029
- /* @__PURE__ */ jsx2(ChartHeader, { title: headerTitle, trend, range }),
35044
+ /* @__PURE__ */ jsx2(ChartHeader, { title: model.title, trend }),
35030
35045
  /* @__PURE__ */ jsxs("table", { style: VISUALLY_HIDDEN, children: [
35031
35046
  /* @__PURE__ */ jsx2("thead", { children: /* @__PURE__ */ jsx2("tr", { children: tableColumns.map((column) => /* @__PURE__ */ jsx2("th", { scope: "col", children: column }, column)) }) }),
35032
- /* @__PURE__ */ jsx2("tbody", { children: chartData.map((point, row) => /* @__PURE__ */ jsx2("tr", { children: tableColumns.map((column) => /* @__PURE__ */ jsx2("td", { children: cellText(point[column]) }, column)) }, row)) })
35047
+ /* @__PURE__ */ jsx2("tbody", { children: chartData.map((point, row) => /* @__PURE__ */ jsx2("tr", { children: tableColumns.map((column) => /* @__PURE__ */ jsx2("td", { children: chartCellText(point[column]) }, column)) }, row)) })
35033
35048
  ] }),
35034
35049
  ready ? /* @__PURE__ */ jsx2(
35035
35050
  ChartContainer,
@@ -35145,7 +35160,7 @@ function ChartCard({ data }) {
35145
35160
  x: box.cx,
35146
35161
  y: box.cy - 6,
35147
35162
  className: "fill-foreground text-lg font-semibold",
35148
- children: formatters.value(values.reduce((sum, value) => sum + value, 0))
35163
+ children: formatters.value(model.total)
35149
35164
  }
35150
35165
  ),
35151
35166
  /* @__PURE__ */ jsx2("tspan", { x: box.cx, y: box.cy + 14, className: "fill-muted-foreground", children: "Total" })
@@ -35276,30 +35291,60 @@ async function authenticateICloud() {
35276
35291
  ensureAuthElements();
35277
35292
  return container.setUpAuth();
35278
35293
  }
35279
- async function requestICloudSignIn() {
35280
- const container = await getContainer();
35281
- const { signIn } = ensureAuthElements();
35282
- const existingUser = await container.setUpAuth();
35283
- if (existingUser) {
35284
- return existingUser;
35285
- }
35286
- getLogger().debug("[CloudKit] Sign-in container innerHTML:", signIn.innerHTML);
35287
- getLogger().debug("[CloudKit] Sign-in container children:", signIn.children.length);
35288
- const appleButton = signIn.querySelector(
35289
- "a, button, [role='button'], div[id*='apple']"
35290
- );
35291
- getLogger().debug("[CloudKit] Found button element:", appleButton);
35292
- if (appleButton) {
35293
- getLogger().debug("[CloudKit] Clicking button...");
35294
- appleButton.click();
35295
- } else {
35296
- const anyClickable = signIn.firstElementChild;
35297
- if (anyClickable) {
35298
- getLogger().debug("[CloudKit] Clicking first child element:", anyClickable);
35299
- anyClickable.click();
35294
+ async function requestICloudSignIn({
35295
+ signal
35296
+ } = {}) {
35297
+ if (signal?.aborted) {
35298
+ throw new Error("Sign-in was cancelled");
35299
+ }
35300
+ let cancellationError;
35301
+ let timer;
35302
+ let onAbort;
35303
+ const cancellation = new Promise((_resolve, reject) => {
35304
+ const cancel = (error) => {
35305
+ cancellationError = error;
35306
+ reject(error);
35307
+ };
35308
+ onAbort = () => cancel(new Error("Sign-in was cancelled"));
35309
+ signal?.addEventListener("abort", onAbort, { once: true });
35310
+ timer = setTimeout(() => cancel(new Error("iCloud sign-in timed out")), 6e4);
35311
+ });
35312
+ const throwIfCancelled = () => {
35313
+ if (cancellationError) throw cancellationError;
35314
+ };
35315
+ const signInRequest = async () => {
35316
+ const container = await getContainer();
35317
+ throwIfCancelled();
35318
+ const { signIn } = ensureAuthElements();
35319
+ const existingUser = await container.setUpAuth();
35320
+ throwIfCancelled();
35321
+ if (existingUser) {
35322
+ return existingUser;
35323
+ }
35324
+ getLogger().debug("[CloudKit] Sign-in container innerHTML:", signIn.innerHTML);
35325
+ getLogger().debug("[CloudKit] Sign-in container children:", signIn.children.length);
35326
+ const appleButton = signIn.querySelector(
35327
+ "a, button, [role='button'], div[id*='apple']"
35328
+ );
35329
+ getLogger().debug("[CloudKit] Found button element:", appleButton);
35330
+ if (appleButton) {
35331
+ getLogger().debug("[CloudKit] Clicking button...");
35332
+ appleButton.click();
35333
+ } else {
35334
+ const anyClickable = signIn.firstElementChild;
35335
+ if (anyClickable) {
35336
+ getLogger().debug("[CloudKit] Clicking first child element:", anyClickable);
35337
+ anyClickable.click();
35338
+ }
35300
35339
  }
35340
+ return container.whenUserSignsIn();
35341
+ };
35342
+ try {
35343
+ return await Promise.race([signInRequest(), cancellation]);
35344
+ } finally {
35345
+ clearTimeout(timer);
35346
+ if (onAbort) signal?.removeEventListener("abort", onAbort);
35301
35347
  }
35302
- return container.whenUserSignsIn();
35303
35348
  }
35304
35349
  async function uploadFileToICloud(filename, content, backupRevision) {
35305
35350
  const container = await getContainer();