drizzle-cube 0.2.12 → 0.2.14
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.
- package/dist/client/charts.js +15 -15
- package/dist/client/chunks/{chart-activitygridchart-CUGN9Xq9.js → chart-activitygridchart-BSA93MaS.js} +895 -887
- package/dist/client/chunks/chart-activitygridchart-BSA93MaS.js.map +1 -0
- package/dist/client/chunks/chart-areachart-Cz-Bv8ZB.js +238 -0
- package/dist/client/chunks/chart-areachart-Cz-Bv8ZB.js.map +1 -0
- package/dist/client/chunks/{chart-axisformatcontrols-Ch_IYF94.js → chart-axisformatcontrols-BNfQgqND.js} +2 -2
- package/dist/client/chunks/{chart-axisformatcontrols-Ch_IYF94.js.map → chart-axisformatcontrols-BNfQgqND.js.map} +1 -1
- package/dist/client/chunks/{chart-barchart-D_op06r-.js → chart-barchart-CI8LhTwO.js} +73 -70
- package/dist/client/chunks/chart-barchart-CI8LhTwO.js.map +1 -0
- package/dist/client/chunks/chart-bubblechart-DaFSD3dc.js +247 -0
- package/dist/client/chunks/chart-bubblechart-DaFSD3dc.js.map +1 -0
- package/dist/client/chunks/{chart-charttooltip-Bx3I8jQv.js → chart-charttooltip-hLOOlEDZ.js} +4 -4
- package/dist/client/chunks/{chart-charttooltip-Bx3I8jQv.js.map → chart-charttooltip-hLOOlEDZ.js.map} +1 -1
- package/dist/client/chunks/chart-datatable-Dj_3LWKH.js +350 -0
- package/dist/client/chunks/chart-datatable-Dj_3LWKH.js.map +1 -0
- package/dist/client/chunks/chart-kpidelta-D45MO-i1.js +435 -0
- package/dist/client/chunks/chart-kpidelta-D45MO-i1.js.map +1 -0
- package/dist/client/chunks/chart-kpinumber-J3jJ1lz7.js +400 -0
- package/dist/client/chunks/chart-kpinumber-J3jJ1lz7.js.map +1 -0
- package/dist/client/chunks/{chart-kpitext-BZkC9u3A.js → chart-kpitext-Bo86g7Jn.js} +24 -24
- package/dist/client/chunks/chart-kpitext-Bo86g7Jn.js.map +1 -0
- package/dist/client/chunks/{chart-linechart-DqFmLbRe.js → chart-linechart-B7HFYqC7.js} +77 -73
- package/dist/client/chunks/chart-linechart-B7HFYqC7.js.map +1 -0
- package/dist/client/chunks/{chart-markdownchart-9n_TemoB.js → chart-markdownchart-C-lDJMtY.js} +20 -19
- package/dist/client/chunks/chart-markdownchart-C-lDJMtY.js.map +1 -0
- package/dist/client/chunks/{chart-piechart-CrXFd9pE.js → chart-piechart-CJCJZXmm.js} +17 -17
- package/dist/client/chunks/chart-piechart-CJCJZXmm.js.map +1 -0
- package/dist/client/chunks/{chart-radarchart-tar2GBkO.js → chart-radarchart-CJ-8qPmX.js} +19 -19
- package/dist/client/chunks/chart-radarchart-CJ-8qPmX.js.map +1 -0
- package/dist/client/chunks/{chart-radialbarchart-ab8Swtal.js → chart-radialbarchart-C8PlVtXx.js} +16 -16
- package/dist/client/chunks/chart-radialbarchart-C8PlVtXx.js.map +1 -0
- package/dist/client/chunks/{chart-scatterchart-BP06BeU5.js → chart-scatterchart-CXujAIug.js} +29 -29
- package/dist/client/chunks/chart-scatterchart-CXujAIug.js.map +1 -0
- package/dist/client/chunks/{chart-treemapchart-DAiixITm.js → chart-treemapchart-D9lYs_Y9.js} +20 -20
- package/dist/client/chunks/chart-treemapchart-D9lYs_Y9.js.map +1 -0
- package/dist/client/chunks/{charts-CHzWeaY1.js → charts-PgJ3XcwQ.js} +70 -70
- package/dist/client/chunks/{charts-CHzWeaY1.js.map → charts-PgJ3XcwQ.js.map} +1 -1
- package/dist/client/chunks/{components-DnM9CCUS.js → components-Cd068oGo.js} +4249 -4146
- package/dist/client/chunks/components-Cd068oGo.js.map +1 -0
- package/dist/client/chunks/{index-DlsvcKXf.js → index-Baq5aJv1.js} +2 -2
- package/dist/client/chunks/{index-DlsvcKXf.js.map → index-Baq5aJv1.js.map} +1 -1
- package/dist/client/components/AnalyticsPortlet.d.ts +2 -1
- package/dist/client/components/DashboardPortletCard.d.ts +3 -3
- package/dist/client/components/charts/ActivityGridChart.d.ts +3 -1
- package/dist/client/components/charts/AreaChart.d.ts +3 -1
- package/dist/client/components/charts/BarChart.d.ts +3 -1
- package/dist/client/components/charts/BubbleChart.d.ts +3 -1
- package/dist/client/components/charts/DataTable.d.ts +3 -1
- package/dist/client/components/charts/KpiDelta.d.ts +3 -1
- package/dist/client/components/charts/KpiNumber.d.ts +3 -1
- package/dist/client/components/charts/KpiText.d.ts +3 -1
- package/dist/client/components/charts/LineChart.d.ts +3 -1
- package/dist/client/components/charts/MarkdownChart.d.ts +3 -1
- package/dist/client/components/charts/PieChart.d.ts +3 -1
- package/dist/client/components/charts/RadarChart.d.ts +3 -1
- package/dist/client/components/charts/RadialBarChart.d.ts +3 -1
- package/dist/client/components/charts/ScatterChart.d.ts +3 -1
- package/dist/client/components/charts/TreeMapChart.d.ts +3 -1
- package/dist/client/components.js +2 -2
- package/dist/client/hooks/useCubeFieldLabel.d.ts +16 -0
- package/dist/client/hooks/useScrollDetection.d.ts +27 -0
- package/dist/client/hooks/useTheme.d.ts +11 -0
- package/dist/client/hooks.js +9 -9
- package/dist/client/index.d.ts +6 -1
- package/dist/client/index.js +53 -45
- package/dist/client/index.js.map +1 -1
- package/dist/client/providers/CubeApiProvider.d.ts +22 -0
- package/dist/client/providers/CubeFeaturesProvider.d.ts +15 -0
- package/dist/client/providers/CubeMetaProvider.d.ts +17 -0
- package/dist/client/providers/CubeProvider.d.ts +28 -8
- package/dist/client/providers.js +4 -3
- package/dist/client/providers.js.map +1 -1
- package/dist/client/styles.css +1 -1
- package/dist/client/utils/chartUtils.d.ts +2 -2
- package/dist/client/utils/filterUtils.d.ts +15 -0
- package/dist/client-bundle-stats.html +1 -1
- package/package.json +1 -1
- package/dist/client/chunks/chart-activitygridchart-CUGN9Xq9.js.map +0 -1
- package/dist/client/chunks/chart-areachart-B4tknnsY.js +0 -239
- package/dist/client/chunks/chart-areachart-B4tknnsY.js.map +0 -1
- package/dist/client/chunks/chart-barchart-D_op06r-.js.map +0 -1
- package/dist/client/chunks/chart-bubblechart-BsaIXUbS.js +0 -214
- package/dist/client/chunks/chart-bubblechart-BsaIXUbS.js.map +0 -1
- package/dist/client/chunks/chart-datatable-C7MS9q4Y.js +0 -283
- package/dist/client/chunks/chart-datatable-C7MS9q4Y.js.map +0 -1
- package/dist/client/chunks/chart-kpidelta-7-KOmb3w.js +0 -436
- package/dist/client/chunks/chart-kpidelta-7-KOmb3w.js.map +0 -1
- package/dist/client/chunks/chart-kpinumber-HOPfcK2N.js +0 -398
- package/dist/client/chunks/chart-kpinumber-HOPfcK2N.js.map +0 -1
- package/dist/client/chunks/chart-kpitext-BZkC9u3A.js.map +0 -1
- package/dist/client/chunks/chart-linechart-DqFmLbRe.js.map +0 -1
- package/dist/client/chunks/chart-markdownchart-9n_TemoB.js.map +0 -1
- package/dist/client/chunks/chart-piechart-CrXFd9pE.js.map +0 -1
- package/dist/client/chunks/chart-radarchart-tar2GBkO.js.map +0 -1
- package/dist/client/chunks/chart-radialbarchart-ab8Swtal.js.map +0 -1
- package/dist/client/chunks/chart-scatterchart-BP06BeU5.js.map +0 -1
- package/dist/client/chunks/chart-treemapchart-DAiixITm.js.map +0 -1
- package/dist/client/chunks/components-DnM9CCUS.js.map +0 -1
|
@@ -1,436 +0,0 @@
|
|
|
1
|
-
import { jsx as i, jsxs as c } from "react/jsx-runtime";
|
|
2
|
-
import { useState as K, useRef as _, useEffect as te } from "react";
|
|
3
|
-
import { ac as ne, k as se } from "./icons-B2XSxpVK.js";
|
|
4
|
-
import { u as re } from "./chart-activitygridchart-CUGN9Xq9.js";
|
|
5
|
-
function ie(s, r) {
|
|
6
|
-
const e = new Date(s);
|
|
7
|
-
switch (r.toLowerCase()) {
|
|
8
|
-
case "day":
|
|
9
|
-
e.setHours(23, 59, 59, 999);
|
|
10
|
-
break;
|
|
11
|
-
case "week": {
|
|
12
|
-
const n = 6 - e.getDay();
|
|
13
|
-
e.setDate(e.getDate() + n), e.setHours(23, 59, 59, 999);
|
|
14
|
-
break;
|
|
15
|
-
}
|
|
16
|
-
case "month":
|
|
17
|
-
e.setMonth(e.getMonth() + 1, 0), e.setHours(23, 59, 59, 999);
|
|
18
|
-
break;
|
|
19
|
-
case "quarter": {
|
|
20
|
-
const l = e.getMonth(), n = Math.floor(l / 3) * 3 + 2;
|
|
21
|
-
e.setMonth(n + 1, 0), e.setHours(23, 59, 59, 999);
|
|
22
|
-
break;
|
|
23
|
-
}
|
|
24
|
-
case "year":
|
|
25
|
-
e.setMonth(11, 31), e.setHours(23, 59, 59, 999);
|
|
26
|
-
break;
|
|
27
|
-
default:
|
|
28
|
-
e.setHours(23, 59, 59, 999);
|
|
29
|
-
}
|
|
30
|
-
return e;
|
|
31
|
-
}
|
|
32
|
-
function oe(s, r, e) {
|
|
33
|
-
if (!s || !r || !e)
|
|
34
|
-
return !0;
|
|
35
|
-
const l = s[r];
|
|
36
|
-
if (!l)
|
|
37
|
-
return !0;
|
|
38
|
-
const n = new Date(l);
|
|
39
|
-
return isNaN(n.getTime()) ? !0 : ie(n, e) <= /* @__PURE__ */ new Date();
|
|
40
|
-
}
|
|
41
|
-
function ae(s, r) {
|
|
42
|
-
if (!s?.timeDimensions || s.timeDimensions.length === 0)
|
|
43
|
-
return null;
|
|
44
|
-
if (r) {
|
|
45
|
-
const l = s.timeDimensions.find(
|
|
46
|
-
(n) => n.dimension === r || n.dimension?.includes(r) || r?.includes(n.dimension)
|
|
47
|
-
);
|
|
48
|
-
if (l?.granularity)
|
|
49
|
-
return l.granularity;
|
|
50
|
-
}
|
|
51
|
-
return s.timeDimensions[0]?.granularity || null;
|
|
52
|
-
}
|
|
53
|
-
function ce(s, r, e, l, n = !1) {
|
|
54
|
-
const o = {
|
|
55
|
-
filteredData: s,
|
|
56
|
-
excludedIncompletePeriod: !1,
|
|
57
|
-
skippedLastPeriod: !1,
|
|
58
|
-
granularity: null
|
|
59
|
-
};
|
|
60
|
-
if (s.length < 2)
|
|
61
|
-
return o;
|
|
62
|
-
const a = ae(e, r);
|
|
63
|
-
if (n)
|
|
64
|
-
return {
|
|
65
|
-
filteredData: s.slice(0, -1),
|
|
66
|
-
excludedIncompletePeriod: !1,
|
|
67
|
-
skippedLastPeriod: !0,
|
|
68
|
-
granularity: a
|
|
69
|
-
};
|
|
70
|
-
if (!l)
|
|
71
|
-
return { ...o, granularity: a };
|
|
72
|
-
if (!r)
|
|
73
|
-
return { ...o, granularity: a };
|
|
74
|
-
if (!e?.timeDimensions || e.timeDimensions.length === 0)
|
|
75
|
-
return { ...o, granularity: a };
|
|
76
|
-
if (!a)
|
|
77
|
-
return o;
|
|
78
|
-
const N = s[s.length - 1];
|
|
79
|
-
return oe(N, r, a) ? { ...o, granularity: a } : {
|
|
80
|
-
filteredData: s.slice(0, -1),
|
|
81
|
-
excludedIncompletePeriod: !0,
|
|
82
|
-
skippedLastPeriod: !1,
|
|
83
|
-
granularity: a
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
function le({
|
|
87
|
-
values: s,
|
|
88
|
-
lastValue: r,
|
|
89
|
-
positiveColor: e,
|
|
90
|
-
negativeColor: l,
|
|
91
|
-
formatValue: n,
|
|
92
|
-
width: o,
|
|
93
|
-
height: a
|
|
94
|
-
}) {
|
|
95
|
-
const N = Math.max(10, Math.floor(o / 10)), g = s.length > N ? s.slice(-N) : s, y = g.map((h) => h - r), d = Math.min(...y, 0), f = Math.max(...y, 0);
|
|
96
|
-
if (Math.max(Math.abs(d), Math.abs(f)) === 0 || y.length === 0)
|
|
97
|
-
return /* @__PURE__ */ i(
|
|
98
|
-
"div",
|
|
99
|
-
{
|
|
100
|
-
className: "flex items-center justify-center bg-dc-bg-secondary rounded-sm border border-dc-border",
|
|
101
|
-
style: { width: `${o}px`, height: `${a}px` },
|
|
102
|
-
children: /* @__PURE__ */ i("span", { className: "text-xs text-dc-text-muted", children: "No variance data" })
|
|
103
|
-
}
|
|
104
|
-
);
|
|
105
|
-
const M = 2, k = o - (g.length - 1) * M, w = Math.max(4, k / g.length), x = f - d, b = x > 0 ? f / x * 100 : 50;
|
|
106
|
-
return /* @__PURE__ */ c("div", { className: "flex items-center space-x-2", children: [
|
|
107
|
-
/* @__PURE__ */ c(
|
|
108
|
-
"div",
|
|
109
|
-
{
|
|
110
|
-
className: "relative",
|
|
111
|
-
style: {
|
|
112
|
-
width: `${o}px`,
|
|
113
|
-
height: `${a}px`
|
|
114
|
-
},
|
|
115
|
-
children: [
|
|
116
|
-
/* @__PURE__ */ i(
|
|
117
|
-
"div",
|
|
118
|
-
{
|
|
119
|
-
className: "absolute left-0 right-0",
|
|
120
|
-
style: {
|
|
121
|
-
height: "1px",
|
|
122
|
-
top: `${b}%`,
|
|
123
|
-
backgroundColor: "var(--dc-border)",
|
|
124
|
-
zIndex: 1
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
),
|
|
128
|
-
y.map((h, D) => {
|
|
129
|
-
const I = Math.abs(h) / x, P = Math.max(2, I * (a - 4)), z = h >= 0, H = D === g.length - 1, j = z ? e : l, u = D * (w + M);
|
|
130
|
-
return /* @__PURE__ */ i(
|
|
131
|
-
"div",
|
|
132
|
-
{
|
|
133
|
-
className: "absolute rounded-xs",
|
|
134
|
-
style: {
|
|
135
|
-
left: `${u}px`,
|
|
136
|
-
width: `${w}px`,
|
|
137
|
-
height: `${P}px`,
|
|
138
|
-
backgroundColor: j,
|
|
139
|
-
opacity: H ? 1 : 0.6,
|
|
140
|
-
// Position bar relative to zero line
|
|
141
|
-
...z ? { bottom: `${100 - b}%` } : { top: `${b}%` },
|
|
142
|
-
zIndex: 2
|
|
143
|
-
},
|
|
144
|
-
title: `${n(g[D])}: ${h >= 0 ? "+" : ""}${n(h)} vs current`
|
|
145
|
-
},
|
|
146
|
-
D
|
|
147
|
-
);
|
|
148
|
-
})
|
|
149
|
-
]
|
|
150
|
-
}
|
|
151
|
-
),
|
|
152
|
-
/* @__PURE__ */ c(
|
|
153
|
-
"div",
|
|
154
|
-
{
|
|
155
|
-
className: "flex flex-col justify-between text-xs text-dc-text-muted",
|
|
156
|
-
style: { height: `${a}px` },
|
|
157
|
-
children: [
|
|
158
|
-
/* @__PURE__ */ c("span", { children: [
|
|
159
|
-
"+",
|
|
160
|
-
n(f)
|
|
161
|
-
] }),
|
|
162
|
-
/* @__PURE__ */ c("span", { children: [
|
|
163
|
-
(d < 0, ""),
|
|
164
|
-
n(d)
|
|
165
|
-
] })
|
|
166
|
-
]
|
|
167
|
-
}
|
|
168
|
-
)
|
|
169
|
-
] });
|
|
170
|
-
}
|
|
171
|
-
function de({
|
|
172
|
-
data: s,
|
|
173
|
-
chartConfig: r,
|
|
174
|
-
displayConfig: e = {},
|
|
175
|
-
queryObject: l,
|
|
176
|
-
height: n = "100%",
|
|
177
|
-
colorPalette: o
|
|
178
|
-
}) {
|
|
179
|
-
const [a, N] = K(32), [g, y] = K(250), d = _(null), f = _(null), { getFieldLabel: W } = re();
|
|
180
|
-
if (te(() => {
|
|
181
|
-
const t = () => {
|
|
182
|
-
if (d.current) {
|
|
183
|
-
const C = d.current.getBoundingClientRect(), S = C.width, B = C.height;
|
|
184
|
-
if (S > 0 && B > 0) {
|
|
185
|
-
const Q = S / 4, J = B / 4, X = Math.min(Q, J), Y = Math.max(28, Math.min(X, 140));
|
|
186
|
-
N(Y), setTimeout(() => {
|
|
187
|
-
if (f.current) {
|
|
188
|
-
const Z = f.current.getBoundingClientRect().width, q = S - 100, ee = Math.max(
|
|
189
|
-
Z,
|
|
190
|
-
Math.min(q, S * 0.7)
|
|
191
|
-
);
|
|
192
|
-
y(Math.max(100, ee));
|
|
193
|
-
}
|
|
194
|
-
}, 10);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}, p = setTimeout(t, 50), v = new ResizeObserver(() => {
|
|
198
|
-
setTimeout(t, 10);
|
|
199
|
-
});
|
|
200
|
-
return d.current && v.observe(d.current), () => {
|
|
201
|
-
clearTimeout(p), v.disconnect();
|
|
202
|
-
};
|
|
203
|
-
}, [s, r]), !s || s.length === 0)
|
|
204
|
-
return /* @__PURE__ */ i(
|
|
205
|
-
"div",
|
|
206
|
-
{
|
|
207
|
-
className: "flex items-center justify-center w-full h-full",
|
|
208
|
-
style: {
|
|
209
|
-
height: n === "100%" ? "100%" : n,
|
|
210
|
-
minHeight: n === "100%" ? "200px" : void 0
|
|
211
|
-
},
|
|
212
|
-
children: /* @__PURE__ */ c("div", { className: "text-center text-dc-text-muted", children: [
|
|
213
|
-
/* @__PURE__ */ i("div", { className: "text-sm font-semibold mb-1", children: "No data available" }),
|
|
214
|
-
/* @__PURE__ */ i("div", { className: "text-xs text-dc-text-secondary", children: "No data points to display" })
|
|
215
|
-
] })
|
|
216
|
-
}
|
|
217
|
-
);
|
|
218
|
-
let M = [], k = [];
|
|
219
|
-
if (r?.yAxis && (M = Array.isArray(r.yAxis) ? r.yAxis : [r.yAxis]), r?.xAxis && (k = Array.isArray(r.xAxis) ? r.xAxis : [r.xAxis]), M.length === 0)
|
|
220
|
-
return /* @__PURE__ */ i(
|
|
221
|
-
"div",
|
|
222
|
-
{
|
|
223
|
-
className: "flex items-center justify-center w-full h-full",
|
|
224
|
-
style: {
|
|
225
|
-
height: n === "100%" ? "100%" : n,
|
|
226
|
-
minHeight: n === "100%" ? "200px" : void 0,
|
|
227
|
-
backgroundColor: "var(--dc-danger-bg)",
|
|
228
|
-
color: "var(--dc-danger)",
|
|
229
|
-
borderColor: "var(--dc-danger-border)"
|
|
230
|
-
},
|
|
231
|
-
children: /* @__PURE__ */ c("div", { className: "text-center", children: [
|
|
232
|
-
/* @__PURE__ */ i("div", { className: "text-sm font-semibold mb-1", children: "Configuration Error" }),
|
|
233
|
-
/* @__PURE__ */ i("div", { className: "text-xs", children: "No measure field configured" })
|
|
234
|
-
] })
|
|
235
|
-
}
|
|
236
|
-
);
|
|
237
|
-
const w = M[0], x = k[0];
|
|
238
|
-
let b = [...s];
|
|
239
|
-
x && (b = b.sort((t, p) => {
|
|
240
|
-
const v = t[x], m = p[x];
|
|
241
|
-
return v < m ? -1 : v > m ? 1 : 0;
|
|
242
|
-
}));
|
|
243
|
-
const { useLastCompletePeriod: h = !0, skipLastPeriod: D = !1 } = e, {
|
|
244
|
-
filteredData: I,
|
|
245
|
-
excludedIncompletePeriod: P,
|
|
246
|
-
skippedLastPeriod: z,
|
|
247
|
-
granularity: H
|
|
248
|
-
} = ce(
|
|
249
|
-
b,
|
|
250
|
-
x,
|
|
251
|
-
l,
|
|
252
|
-
h,
|
|
253
|
-
D
|
|
254
|
-
), u = I.map((t) => t[w]).filter((t) => t != null && !isNaN(Number(t))).map((t) => Number(t));
|
|
255
|
-
if (u.length < 2)
|
|
256
|
-
return /* @__PURE__ */ i(
|
|
257
|
-
"div",
|
|
258
|
-
{
|
|
259
|
-
className: "flex items-center justify-center w-full h-full",
|
|
260
|
-
style: {
|
|
261
|
-
height: n === "100%" ? "100%" : n,
|
|
262
|
-
minHeight: n === "100%" ? "200px" : void 0,
|
|
263
|
-
backgroundColor: "var(--dc-warning-bg)",
|
|
264
|
-
color: "var(--dc-warning)",
|
|
265
|
-
borderColor: "var(--dc-warning-border)"
|
|
266
|
-
},
|
|
267
|
-
children: /* @__PURE__ */ c("div", { className: "text-center", children: [
|
|
268
|
-
/* @__PURE__ */ i("div", { className: "text-sm font-semibold mb-1", children: "Insufficient Data" }),
|
|
269
|
-
/* @__PURE__ */ i("div", { className: "text-xs", children: "Delta calculation requires at least 2 data points" }),
|
|
270
|
-
/* @__PURE__ */ c("div", { className: "text-xs", children: [
|
|
271
|
-
"Current data points: ",
|
|
272
|
-
u.length
|
|
273
|
-
] })
|
|
274
|
-
] })
|
|
275
|
-
}
|
|
276
|
-
);
|
|
277
|
-
const A = u[u.length - 1], L = u[u.length - 2], V = A - L, U = L !== 0 ? V / Math.abs(L) * 100 : 0, $ = V >= 0, T = (t) => {
|
|
278
|
-
if (e.formatValue)
|
|
279
|
-
return e.formatValue(t);
|
|
280
|
-
if (t == null)
|
|
281
|
-
return "—";
|
|
282
|
-
const p = e.decimals ?? 0, v = e.prefix ?? "";
|
|
283
|
-
let m;
|
|
284
|
-
return Math.abs(t) >= 1e9 ? m = (t / 1e9).toFixed(p) + "B" : Math.abs(t) >= 1e6 ? m = (t / 1e6).toFixed(p) + "M" : Math.abs(t) >= 1e3 ? m = (t / 1e3).toFixed(p) + "K" : m = t.toFixed(p), v + m;
|
|
285
|
-
}, G = () => {
|
|
286
|
-
if (e.positiveColorIndex !== void 0 && o?.colors) {
|
|
287
|
-
const t = e.positiveColorIndex;
|
|
288
|
-
if (t >= 0 && t < o.colors.length)
|
|
289
|
-
return o.colors[t];
|
|
290
|
-
}
|
|
291
|
-
return "#10b981";
|
|
292
|
-
}, O = () => {
|
|
293
|
-
if (e.negativeColorIndex !== void 0 && o?.colors) {
|
|
294
|
-
const t = e.negativeColorIndex;
|
|
295
|
-
if (t >= 0 && t < o.colors.length)
|
|
296
|
-
return o.colors[t];
|
|
297
|
-
}
|
|
298
|
-
return "#ef4444";
|
|
299
|
-
}, E = G(), F = O(), R = $ ? E : F;
|
|
300
|
-
return /* @__PURE__ */ c(
|
|
301
|
-
"div",
|
|
302
|
-
{
|
|
303
|
-
ref: d,
|
|
304
|
-
className: "flex flex-col items-center justify-center w-full h-full p-4",
|
|
305
|
-
style: {
|
|
306
|
-
height: n === "100%" ? "100%" : n,
|
|
307
|
-
minHeight: n === "100%" ? "200px" : void 0
|
|
308
|
-
},
|
|
309
|
-
children: [
|
|
310
|
-
/* @__PURE__ */ c(
|
|
311
|
-
"div",
|
|
312
|
-
{
|
|
313
|
-
className: "text-dc-text-secondary font-bold text-center mb-2 flex items-center justify-center gap-1",
|
|
314
|
-
style: {
|
|
315
|
-
fontSize: "14px",
|
|
316
|
-
lineHeight: "1.2"
|
|
317
|
-
},
|
|
318
|
-
children: [
|
|
319
|
-
/* @__PURE__ */ i("span", { children: (() => {
|
|
320
|
-
const t = W(w);
|
|
321
|
-
return t && t.length > 1 ? t : w;
|
|
322
|
-
})() }),
|
|
323
|
-
(P || z) && /* @__PURE__ */ i(
|
|
324
|
-
"span",
|
|
325
|
-
{
|
|
326
|
-
title: z ? `Excludes last ${H || "period"}` : `Excludes current incomplete ${H}`,
|
|
327
|
-
className: "cursor-help",
|
|
328
|
-
children: /* @__PURE__ */ i(
|
|
329
|
-
ne,
|
|
330
|
-
{
|
|
331
|
-
icon: se,
|
|
332
|
-
className: "w-4 h-4 text-dc-text-muted opacity-70"
|
|
333
|
-
}
|
|
334
|
-
)
|
|
335
|
-
}
|
|
336
|
-
)
|
|
337
|
-
]
|
|
338
|
-
}
|
|
339
|
-
),
|
|
340
|
-
/* @__PURE__ */ c("div", { className: "flex items-center justify-center space-x-4 mb-2", children: [
|
|
341
|
-
/* @__PURE__ */ i(
|
|
342
|
-
"div",
|
|
343
|
-
{
|
|
344
|
-
ref: f,
|
|
345
|
-
className: "font-bold leading-none",
|
|
346
|
-
style: {
|
|
347
|
-
fontSize: `${a}px`,
|
|
348
|
-
color: "var(--dc-text)"
|
|
349
|
-
// Keep main value neutral
|
|
350
|
-
},
|
|
351
|
-
children: T(A)
|
|
352
|
-
}
|
|
353
|
-
),
|
|
354
|
-
/* @__PURE__ */ c("div", { className: "flex items-center space-x-1", children: [
|
|
355
|
-
/* @__PURE__ */ i(
|
|
356
|
-
"div",
|
|
357
|
-
{
|
|
358
|
-
className: "font-bold",
|
|
359
|
-
style: {
|
|
360
|
-
color: R,
|
|
361
|
-
fontSize: `${a * 0.35}px`
|
|
362
|
-
},
|
|
363
|
-
children: $ ? "▲" : "▼"
|
|
364
|
-
}
|
|
365
|
-
),
|
|
366
|
-
/* @__PURE__ */ c("div", { className: "text-left", children: [
|
|
367
|
-
/* @__PURE__ */ c(
|
|
368
|
-
"div",
|
|
369
|
-
{
|
|
370
|
-
className: "font-bold leading-tight",
|
|
371
|
-
style: {
|
|
372
|
-
fontSize: `${a * 0.35}px`,
|
|
373
|
-
color: R
|
|
374
|
-
},
|
|
375
|
-
children: [
|
|
376
|
-
$ ? "+" : "",
|
|
377
|
-
T(V)
|
|
378
|
-
]
|
|
379
|
-
}
|
|
380
|
-
),
|
|
381
|
-
/* @__PURE__ */ c(
|
|
382
|
-
"div",
|
|
383
|
-
{
|
|
384
|
-
className: "font-semibold leading-tight",
|
|
385
|
-
style: {
|
|
386
|
-
fontSize: `${a * 0.28}px`,
|
|
387
|
-
color: R,
|
|
388
|
-
opacity: 0.8
|
|
389
|
-
},
|
|
390
|
-
children: [
|
|
391
|
-
$ ? "+" : "",
|
|
392
|
-
U.toFixed(1),
|
|
393
|
-
"%"
|
|
394
|
-
]
|
|
395
|
-
}
|
|
396
|
-
)
|
|
397
|
-
] })
|
|
398
|
-
] })
|
|
399
|
-
] }),
|
|
400
|
-
e.suffix && !e.formatValue && /* @__PURE__ */ i(
|
|
401
|
-
"div",
|
|
402
|
-
{
|
|
403
|
-
className: "text-dc-text-muted text-center mb-3",
|
|
404
|
-
style: {
|
|
405
|
-
fontSize: "14px",
|
|
406
|
-
lineHeight: "1.2",
|
|
407
|
-
opacity: 0.8
|
|
408
|
-
},
|
|
409
|
-
children: e.suffix
|
|
410
|
-
}
|
|
411
|
-
),
|
|
412
|
-
e.showHistogram !== !1 && u.length > 2 && /* @__PURE__ */ i("div", { className: "mt-2 w-full flex justify-center overflow-hidden", children: /* @__PURE__ */ i(
|
|
413
|
-
le,
|
|
414
|
-
{
|
|
415
|
-
values: u,
|
|
416
|
-
lastValue: A,
|
|
417
|
-
positiveColor: E,
|
|
418
|
-
negativeColor: F,
|
|
419
|
-
formatValue: T,
|
|
420
|
-
width: g,
|
|
421
|
-
height: 64
|
|
422
|
-
}
|
|
423
|
-
) })
|
|
424
|
-
]
|
|
425
|
-
}
|
|
426
|
-
);
|
|
427
|
-
}
|
|
428
|
-
const pe = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
429
|
-
__proto__: null,
|
|
430
|
-
default: de
|
|
431
|
-
}, Symbol.toStringTag, { value: "Module" }));
|
|
432
|
-
export {
|
|
433
|
-
pe as K,
|
|
434
|
-
ce as f
|
|
435
|
-
};
|
|
436
|
-
//# sourceMappingURL=chart-kpidelta-7-KOmb3w.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"chart-kpidelta-7-KOmb3w.js","sources":["../../../src/client/utils/periodUtils.ts","../../../src/client/components/charts/KpiDelta.tsx"],"sourcesContent":["/**\n * Utility functions for detecting incomplete time periods in KPI charts\n */\n\n/**\n * Get the end date of a period based on granularity\n * @param date - The date within the period\n * @param granularity - The time granularity (day, week, month, quarter, year)\n * @returns The end date of the period (end of day)\n */\nexport function getPeriodEndDate(date: Date, granularity: string): Date {\n const endDate = new Date(date)\n\n switch (granularity.toLowerCase()) {\n case 'day':\n // End of the same day\n endDate.setHours(23, 59, 59, 999)\n break\n\n case 'week': {\n // End of the week (Saturday, assuming week starts Sunday)\n const dayOfWeek = endDate.getDay()\n const daysUntilSaturday = 6 - dayOfWeek\n endDate.setDate(endDate.getDate() + daysUntilSaturday)\n endDate.setHours(23, 59, 59, 999)\n break\n }\n\n case 'month':\n // Last day of the month\n endDate.setMonth(endDate.getMonth() + 1, 0) // Set to day 0 of next month = last day of current month\n endDate.setHours(23, 59, 59, 999)\n break\n\n case 'quarter': {\n // Last day of the quarter\n const currentMonth = endDate.getMonth()\n const quarterEndMonth = Math.floor(currentMonth / 3) * 3 + 2 // 0->2, 3->5, 6->8, 9->11\n endDate.setMonth(quarterEndMonth + 1, 0) // Last day of quarter end month\n endDate.setHours(23, 59, 59, 999)\n break\n }\n\n case 'year':\n // December 31st\n endDate.setMonth(11, 31) // December 31\n endDate.setHours(23, 59, 59, 999)\n break\n\n default:\n // Unknown granularity - treat as complete\n endDate.setHours(23, 59, 59, 999)\n }\n\n return endDate\n}\n\n/**\n * Check if the last period in the data is complete based on granularity\n * @param lastDataPoint - The last data point in the sorted dataset\n * @param timeDimensionField - The field name containing the time value\n * @param granularity - The time granularity\n * @returns true if the period is complete, false if it's incomplete\n */\nexport function isLastPeriodComplete(\n lastDataPoint: any,\n timeDimensionField: string,\n granularity: string\n): boolean {\n if (!lastDataPoint || !timeDimensionField || !granularity) {\n return true // Assume complete if we can't determine\n }\n\n const timeValue = lastDataPoint[timeDimensionField]\n if (!timeValue) {\n return true // Assume complete if no time value\n }\n\n // Parse the time value\n const date = new Date(timeValue)\n if (isNaN(date.getTime())) {\n return true // Assume complete if invalid date\n }\n\n // Get the end of this period\n const periodEnd = getPeriodEndDate(date, granularity)\n\n // Compare with current time\n const now = new Date()\n\n // If the period end is in the future, the period is incomplete\n return periodEnd <= now\n}\n\n/**\n * Extract granularity from a query object\n * @param queryObject - The CubeQuery object\n * @param dimensionField - Optional specific dimension field to match\n * @returns The granularity string or null if not found\n */\nexport function getQueryGranularity(\n queryObject: any,\n dimensionField?: string\n): string | null {\n if (!queryObject?.timeDimensions || queryObject.timeDimensions.length === 0) {\n return null\n }\n\n // If a specific dimension field is provided, try to find its granularity\n if (dimensionField) {\n const matchingDim = queryObject.timeDimensions.find((td: any) =>\n td.dimension === dimensionField ||\n td.dimension?.includes(dimensionField) ||\n dimensionField?.includes(td.dimension)\n )\n if (matchingDim?.granularity) {\n return matchingDim.granularity\n }\n }\n\n // Fallback to first time dimension's granularity\n const firstTimeDim = queryObject.timeDimensions[0]\n return firstTimeDim?.granularity || null\n}\n\n/**\n * Filter data to exclude incomplete or last period\n * @param data - The data array sorted by time\n * @param timeDimensionField - The field containing time values\n * @param queryObject - The query object containing timeDimensions\n * @param useLastCompletePeriod - Whether to check for incomplete periods\n * @param skipLastPeriod - Whether to always skip the last period (overrides useLastCompletePeriod)\n * @returns Object with filtered data and whether filtering was applied\n */\nexport function filterIncompletePeriod(\n data: any[],\n timeDimensionField: string | undefined,\n queryObject: any,\n useLastCompletePeriod: boolean,\n skipLastPeriod: boolean = false\n): { filteredData: any[]; excludedIncompletePeriod: boolean; skippedLastPeriod: boolean; granularity: string | null } {\n // Default return - no filtering\n const noFilter = {\n filteredData: data,\n excludedIncompletePeriod: false,\n skippedLastPeriod: false,\n granularity: null\n }\n\n // Need at least 2 data points to filter\n if (data.length < 2) {\n return noFilter\n }\n\n const granularity = getQueryGranularity(queryObject, timeDimensionField)\n\n // If skipLastPeriod is enabled, always skip the last period\n if (skipLastPeriod) {\n return {\n filteredData: data.slice(0, -1),\n excludedIncompletePeriod: false,\n skippedLastPeriod: true,\n granularity\n }\n }\n\n // Skip incomplete period check if feature is disabled\n if (!useLastCompletePeriod) {\n return { ...noFilter, granularity }\n }\n\n // Skip if no time dimension field\n if (!timeDimensionField) {\n return { ...noFilter, granularity }\n }\n\n // Skip if no time dimensions in query\n if (!queryObject?.timeDimensions || queryObject.timeDimensions.length === 0) {\n return { ...noFilter, granularity }\n }\n\n if (!granularity) {\n return noFilter\n }\n\n // Check if last period is incomplete\n const lastRow = data[data.length - 1]\n if (!isLastPeriodComplete(lastRow, timeDimensionField, granularity)) {\n return {\n filteredData: data.slice(0, -1),\n excludedIncompletePeriod: true,\n skippedLastPeriod: false,\n granularity\n }\n }\n\n return { ...noFilter, granularity }\n}\n","import { useState, useRef, useEffect } from \"react\";\nimport { Icon } from \"@iconify/react\";\nimport infoCircleIcon from \"@iconify-icons/tabler/info-circle\";\nimport { useCubeContext } from \"../../providers/CubeProvider\";\nimport { filterIncompletePeriod } from \"../../utils/periodUtils\";\nimport type { ChartProps } from \"../../types\";\n\ninterface VarianceHistogramProps {\n values: number[];\n lastValue: number;\n positiveColor: string;\n negativeColor: string;\n formatValue: (value: number) => string;\n width: number;\n height: number;\n}\n\nfunction VarianceHistogram({\n values,\n lastValue,\n positiveColor,\n negativeColor,\n formatValue,\n width,\n height,\n}: VarianceHistogramProps) {\n // Limit to most recent N values to fit in the histogram\n // Calculate max bars based on width (minimum 8px per bar including gap)\n const maxBars = Math.max(10, Math.floor(width / 10));\n const limitedValues =\n values.length > maxBars\n ? values.slice(-maxBars) // Take the most recent values\n : values;\n\n // Calculate variance (difference) from current/last value for each point\n const variances = limitedValues.map((value) => value - lastValue);\n\n // Find min/max variance for scaling (include 0 as baseline)\n const minVariance = Math.min(...variances, 0);\n const maxVariance = Math.max(...variances, 0);\n const range = Math.max(Math.abs(minVariance), Math.abs(maxVariance));\n\n if (range === 0 || variances.length === 0) {\n return (\n <div\n className=\"flex items-center justify-center bg-dc-bg-secondary rounded-sm border border-dc-border\"\n style={{ width: `${width}px`, height: `${height}px` }}\n >\n <span className=\"text-xs text-dc-text-muted\">No variance data</span>\n </div>\n );\n }\n\n // Calculate bar dimensions\n const barGap = 2;\n const availableWidth = width - (limitedValues.length - 1) * barGap;\n const barWidth = Math.max(4, availableWidth / limitedValues.length);\n\n // Calculate where zero line should be positioned (as percentage from top)\n // If maxVariance = 67 and minVariance = -24, total range = 91\n // Zero should be at 67/91 = 73.6% from top\n const totalRange = maxVariance - minVariance;\n const zeroLinePercent =\n totalRange > 0 ? (maxVariance / totalRange) * 100 : 50;\n\n return (\n <div className=\"flex items-center space-x-2\">\n {/* Histogram bars */}\n <div\n className=\"relative\"\n style={{\n width: `${width}px`,\n height: `${height}px`,\n }}\n >\n {/* Zero line (represents current value) */}\n <div\n className=\"absolute left-0 right-0\"\n style={{\n height: \"1px\",\n top: `${zeroLinePercent}%`,\n backgroundColor: \"var(--dc-border)\",\n zIndex: 1,\n }}\n />\n\n {/* Variance bars - oldest to newest (left to right) */}\n {variances.map((variance, index) => {\n // Calculate bar height as proportion of total range\n const normalizedHeight = Math.abs(variance) / totalRange;\n const barHeight = Math.max(2, normalizedHeight * (height - 4));\n const isPositive = variance >= 0;\n const isLastValue = index === limitedValues.length - 1;\n const color = isPositive ? positiveColor : negativeColor;\n const xPosition = index * (barWidth + barGap);\n\n return (\n <div\n key={index}\n className=\"absolute rounded-xs\"\n style={{\n left: `${xPosition}px`,\n width: `${barWidth}px`,\n height: `${barHeight}px`,\n backgroundColor: color,\n opacity: isLastValue ? 1 : 0.6,\n // Position bar relative to zero line\n ...(isPositive\n ? { bottom: `${100 - zeroLinePercent}%` }\n : { top: `${zeroLinePercent}%` }),\n zIndex: 2,\n }}\n title={`${formatValue(limitedValues[index])}: ${variance >= 0 ? \"+\" : \"\"}${formatValue(variance)} vs current`}\n />\n );\n })}\n </div>\n\n {/* Variance labels on the right - show actual value difference */}\n <div\n className=\"flex flex-col justify-between text-xs text-dc-text-muted\"\n style={{ height: `${height}px` }}\n >\n <span>+{formatValue(maxVariance)}</span>\n <span>\n {minVariance < 0 ? \"\" : \"\"}\n {formatValue(minVariance)}\n </span>\n </div>\n </div>\n );\n}\n\nexport default function KpiDelta({\n data,\n chartConfig,\n displayConfig = {},\n queryObject,\n height = \"100%\",\n colorPalette,\n}: ChartProps) {\n const [fontSize, setFontSize] = useState(32);\n const [textWidth, setTextWidth] = useState(250);\n const containerRef = useRef<HTMLDivElement>(null);\n const valueRef = useRef<HTMLDivElement>(null);\n const { getFieldLabel } = useCubeContext();\n\n // Calculate font size and text width based on container dimensions\n useEffect(() => {\n const updateDimensions = () => {\n if (containerRef.current) {\n const container = containerRef.current;\n const rect = container.getBoundingClientRect();\n const containerWidth = rect.width;\n const containerHeight = rect.height;\n\n if (containerWidth > 0 && containerHeight > 0) {\n const widthBasedSize = containerWidth / 4;\n const heightBasedSize = containerHeight / 4;\n const baseFontSize = Math.min(widthBasedSize, heightBasedSize);\n const clampedFontSize = Math.max(28, Math.min(baseFontSize, 140));\n setFontSize(clampedFontSize);\n\n setTimeout(() => {\n if (valueRef.current) {\n const textRect = valueRef.current.getBoundingClientRect();\n const measuredWidth = textRect.width;\n // Scale histogram width with container, accounting for labels on the right (~60px)\n const maxHistogramWidth = containerWidth - 100; // Leave room for padding and labels\n const effectiveWidth = Math.max(\n measuredWidth,\n Math.min(maxHistogramWidth, containerWidth * 0.7),\n );\n setTextWidth(Math.max(100, effectiveWidth)); // Minimum 100px\n }\n }, 10);\n }\n }\n };\n\n const timer = setTimeout(updateDimensions, 50);\n\n const resizeObserver = new ResizeObserver(() => {\n setTimeout(updateDimensions, 10);\n });\n\n if (containerRef.current) {\n resizeObserver.observe(containerRef.current);\n }\n\n return () => {\n clearTimeout(timer);\n resizeObserver.disconnect();\n };\n }, [data, chartConfig]);\n\n if (!data || data.length === 0) {\n return (\n <div\n className=\"flex items-center justify-center w-full h-full\"\n style={{\n height: height === \"100%\" ? \"100%\" : height,\n minHeight: height === \"100%\" ? \"200px\" : undefined,\n }}\n >\n <div className=\"text-center text-dc-text-muted\">\n <div className=\"text-sm font-semibold mb-1\">No data available</div>\n <div className=\"text-xs text-dc-text-secondary\">\n No data points to display\n </div>\n </div>\n </div>\n );\n }\n\n // Extract value and dimension fields from chart config\n let valueFields: string[] = [];\n let dimensionFields: string[] = [];\n\n if (chartConfig?.yAxis) {\n valueFields = Array.isArray(chartConfig.yAxis)\n ? chartConfig.yAxis\n : [chartConfig.yAxis];\n }\n\n if (chartConfig?.xAxis) {\n dimensionFields = Array.isArray(chartConfig.xAxis)\n ? chartConfig.xAxis\n : [chartConfig.xAxis];\n }\n\n if (valueFields.length === 0) {\n return (\n <div\n className=\"flex items-center justify-center w-full h-full\"\n style={{\n height: height === \"100%\" ? \"100%\" : height,\n minHeight: height === \"100%\" ? \"200px\" : undefined,\n backgroundColor: \"var(--dc-danger-bg)\",\n color: \"var(--dc-danger)\",\n borderColor: \"var(--dc-danger-border)\",\n }}\n >\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Configuration Error</div>\n <div className=\"text-xs\">No measure field configured</div>\n </div>\n </div>\n );\n }\n\n const valueField = valueFields[0];\n const dimensionField = dimensionFields[0]; // Optional\n\n // Sort data by dimension if available (for time series)\n let sortedData = [...data];\n if (dimensionField) {\n sortedData = sortedData.sort((a, b) => {\n const aVal = a[dimensionField];\n const bVal = b[dimensionField];\n if (aVal < bVal) return -1;\n if (aVal > bVal) return 1;\n return 0;\n });\n }\n\n // Filter out incomplete or last period if enabled\n const { useLastCompletePeriod = true, skipLastPeriod = false } =\n displayConfig;\n const {\n filteredData,\n excludedIncompletePeriod,\n skippedLastPeriod,\n granularity,\n } = filterIncompletePeriod(\n sortedData,\n dimensionField,\n queryObject,\n useLastCompletePeriod,\n skipLastPeriod,\n );\n\n // Use filtered data for calculations\n const dataToUse = filteredData;\n\n // Extract values from filtered data\n const values = dataToUse\n .map((row) => row[valueField])\n .filter((val) => val !== null && val !== undefined && !isNaN(Number(val)))\n .map((val) => Number(val));\n\n if (values.length < 2) {\n return (\n <div\n className=\"flex items-center justify-center w-full h-full\"\n style={{\n height: height === \"100%\" ? \"100%\" : height,\n minHeight: height === \"100%\" ? \"200px\" : undefined,\n backgroundColor: \"var(--dc-warning-bg)\",\n color: \"var(--dc-warning)\",\n borderColor: \"var(--dc-warning-border)\",\n }}\n >\n <div className=\"text-center\">\n <div className=\"text-sm font-semibold mb-1\">Insufficient Data</div>\n <div className=\"text-xs\">\n Delta calculation requires at least 2 data points\n </div>\n <div className=\"text-xs\">Current data points: {values.length}</div>\n </div>\n </div>\n );\n }\n\n // Calculate delta between last and second-last values\n const lastValue = values[values.length - 1];\n const secondLastValue = values[values.length - 2];\n const absoluteChange = lastValue - secondLastValue;\n const percentageChange =\n secondLastValue !== 0\n ? (absoluteChange / Math.abs(secondLastValue)) * 100\n : 0;\n\n const isPositiveChange = absoluteChange >= 0;\n\n // Format number with appropriate units and decimals\n const formatNumber = (value: number | null | undefined): string => {\n // If custom formatValue is provided, use it exclusively\n if (displayConfig.formatValue) {\n return displayConfig.formatValue(value);\n }\n\n // Null handling: Show placeholder for missing data\n if (value === null || value === undefined) {\n return \"—\";\n }\n\n const decimals = displayConfig.decimals ?? 0;\n const prefix = displayConfig.prefix ?? \"\";\n\n let formattedValue: string;\n\n if (Math.abs(value) >= 1e9) {\n formattedValue = (value / 1e9).toFixed(decimals) + \"B\";\n } else if (Math.abs(value) >= 1e6) {\n formattedValue = (value / 1e6).toFixed(decimals) + \"M\";\n } else if (Math.abs(value) >= 1e3) {\n formattedValue = (value / 1e3).toFixed(decimals) + \"K\";\n } else {\n formattedValue = value.toFixed(decimals);\n }\n\n return prefix + formattedValue;\n };\n\n // Get colors from palette\n const getPositiveColor = (): string => {\n if (\n displayConfig.positiveColorIndex !== undefined &&\n colorPalette?.colors\n ) {\n const colorIndex = displayConfig.positiveColorIndex;\n if (colorIndex >= 0 && colorIndex < colorPalette.colors.length) {\n return colorPalette.colors[colorIndex];\n }\n }\n return \"#10b981\"; // Default green\n };\n\n const getNegativeColor = (): string => {\n if (\n displayConfig.negativeColorIndex !== undefined &&\n colorPalette?.colors\n ) {\n const colorIndex = displayConfig.negativeColorIndex;\n if (colorIndex >= 0 && colorIndex < colorPalette.colors.length) {\n return colorPalette.colors[colorIndex];\n }\n }\n return \"#ef4444\"; // Default red\n };\n\n const positiveColor = getPositiveColor();\n const negativeColor = getNegativeColor();\n const currentColor = isPositiveChange ? positiveColor : negativeColor;\n\n return (\n <div\n ref={containerRef}\n className=\"flex flex-col items-center justify-center w-full h-full p-4\"\n style={{\n height: height === \"100%\" ? \"100%\" : height,\n minHeight: height === \"100%\" ? \"200px\" : undefined,\n }}\n >\n {/* Field Label */}\n <div\n className=\"text-dc-text-secondary font-bold text-center mb-2 flex items-center justify-center gap-1\"\n style={{\n fontSize: \"14px\",\n lineHeight: \"1.2\",\n }}\n >\n <span>\n {(() => {\n const label = getFieldLabel(valueField);\n return label && label.length > 1 ? label : valueField;\n })()}\n </span>\n {(excludedIncompletePeriod || skippedLastPeriod) && (\n <span\n title={\n skippedLastPeriod\n ? `Excludes last ${granularity || \"period\"}`\n : `Excludes current incomplete ${granularity}`\n }\n className=\"cursor-help\"\n >\n <Icon\n icon={infoCircleIcon}\n className=\"w-4 h-4 text-dc-text-muted opacity-70\"\n />\n </span>\n )}\n </div>\n\n {/* Main KPI Value and Delta */}\n <div className=\"flex items-center justify-center space-x-4 mb-2\">\n {/* Main KPI Value */}\n <div\n ref={valueRef}\n className=\"font-bold leading-none\"\n style={{\n fontSize: `${fontSize}px`,\n color: \"var(--dc-text)\", // Keep main value neutral\n }}\n >\n {formatNumber(lastValue)}\n </div>\n\n {/* Delta Information */}\n <div className=\"flex items-center space-x-1\">\n {/* Arrow */}\n <div\n className=\"font-bold\"\n style={{\n color: currentColor,\n fontSize: `${fontSize * 0.35}px`,\n }}\n >\n {isPositiveChange ? \"▲\" : \"▼\"}\n </div>\n\n {/* Delta Values */}\n <div className=\"text-left\">\n <div\n className=\"font-bold leading-tight\"\n style={{\n fontSize: `${fontSize * 0.35}px`,\n color: currentColor,\n }}\n >\n {isPositiveChange ? \"+\" : \"\"}\n {formatNumber(absoluteChange)}\n </div>\n <div\n className=\"font-semibold leading-tight\"\n style={{\n fontSize: `${fontSize * 0.28}px`,\n color: currentColor,\n opacity: 0.8,\n }}\n >\n {isPositiveChange ? \"+\" : \"\"}\n {percentageChange.toFixed(1)}%\n </div>\n </div>\n </div>\n </div>\n\n {/* Unit/Suffix (hidden when formatValue is provided) */}\n {displayConfig.suffix && !displayConfig.formatValue && (\n <div\n className=\"text-dc-text-muted text-center mb-3\"\n style={{\n fontSize: \"14px\",\n lineHeight: \"1.2\",\n opacity: 0.8,\n }}\n >\n {displayConfig.suffix}\n </div>\n )}\n\n {/* Variance Histogram */}\n {displayConfig.showHistogram !== false && values.length > 2 && (\n <div className=\"mt-2 w-full flex justify-center overflow-hidden\">\n <VarianceHistogram\n values={values}\n lastValue={lastValue}\n positiveColor={positiveColor}\n negativeColor={negativeColor}\n formatValue={formatNumber}\n width={textWidth}\n height={64}\n />\n </div>\n )}\n </div>\n );\n}\n"],"names":["getPeriodEndDate","date","granularity","endDate","daysUntilSaturday","currentMonth","quarterEndMonth","isLastPeriodComplete","lastDataPoint","timeDimensionField","timeValue","getQueryGranularity","queryObject","dimensionField","matchingDim","td","filterIncompletePeriod","data","useLastCompletePeriod","skipLastPeriod","noFilter","lastRow","VarianceHistogram","values","lastValue","positiveColor","negativeColor","formatValue","width","height","maxBars","limitedValues","variances","value","minVariance","maxVariance","jsx","barGap","availableWidth","barWidth","totalRange","zeroLinePercent","jsxs","variance","index","normalizedHeight","barHeight","isPositive","isLastValue","color","xPosition","KpiDelta","chartConfig","displayConfig","colorPalette","fontSize","setFontSize","useState","textWidth","setTextWidth","containerRef","useRef","valueRef","getFieldLabel","useCubeContext","useEffect","updateDimensions","rect","containerWidth","containerHeight","widthBasedSize","heightBasedSize","baseFontSize","clampedFontSize","measuredWidth","maxHistogramWidth","effectiveWidth","timer","resizeObserver","valueFields","dimensionFields","valueField","sortedData","a","b","aVal","bVal","filteredData","excludedIncompletePeriod","skippedLastPeriod","row","val","secondLastValue","absoluteChange","percentageChange","isPositiveChange","formatNumber","decimals","prefix","formattedValue","getPositiveColor","colorIndex","getNegativeColor","currentColor","label","Icon","infoCircleIcon"],"mappings":";;;;AAUO,SAASA,GAAiBC,GAAYC,GAA2B;AACtE,QAAMC,IAAU,IAAI,KAAKF,CAAI;AAE7B,UAAQC,EAAY,eAAY;AAAA,IAC9B,KAAK;AAEH,MAAAC,EAAQ,SAAS,IAAI,IAAI,IAAI,GAAG;AAChC;AAAA,IAEF,KAAK,QAAQ;AAGX,YAAMC,IAAoB,IADRD,EAAQ,OAAA;AAE1B,MAAAA,EAAQ,QAAQA,EAAQ,QAAA,IAAYC,CAAiB,GACrDD,EAAQ,SAAS,IAAI,IAAI,IAAI,GAAG;AAChC;AAAA,IACF;AAAA,IAEA,KAAK;AAEH,MAAAA,EAAQ,SAASA,EAAQ,SAAA,IAAa,GAAG,CAAC,GAC1CA,EAAQ,SAAS,IAAI,IAAI,IAAI,GAAG;AAChC;AAAA,IAEF,KAAK,WAAW;AAEd,YAAME,IAAeF,EAAQ,SAAA,GACvBG,IAAkB,KAAK,MAAMD,IAAe,CAAC,IAAI,IAAI;AAC3D,MAAAF,EAAQ,SAASG,IAAkB,GAAG,CAAC,GACvCH,EAAQ,SAAS,IAAI,IAAI,IAAI,GAAG;AAChC;AAAA,IACF;AAAA,IAEA,KAAK;AAEH,MAAAA,EAAQ,SAAS,IAAI,EAAE,GACvBA,EAAQ,SAAS,IAAI,IAAI,IAAI,GAAG;AAChC;AAAA,IAEF;AAEE,MAAAA,EAAQ,SAAS,IAAI,IAAI,IAAI,GAAG;AAAA,EAAA;AAGpC,SAAOA;AACT;AASO,SAASI,GACdC,GACAC,GACAP,GACS;AACT,MAAI,CAACM,KAAiB,CAACC,KAAsB,CAACP;AAC5C,WAAO;AAGT,QAAMQ,IAAYF,EAAcC,CAAkB;AAClD,MAAI,CAACC;AACH,WAAO;AAIT,QAAMT,IAAO,IAAI,KAAKS,CAAS;AAC/B,SAAI,MAAMT,EAAK,QAAA,CAAS,IACf,KAISD,GAAiBC,GAAMC,CAAW,yBAGpC,KAAA;AAIlB;AAQO,SAASS,GACdC,GACAC,GACe;AACf,MAAI,CAACD,GAAa,kBAAkBA,EAAY,eAAe,WAAW;AACxE,WAAO;AAIT,MAAIC,GAAgB;AAClB,UAAMC,IAAcF,EAAY,eAAe;AAAA,MAAK,CAACG,MACnDA,EAAG,cAAcF,KACjBE,EAAG,WAAW,SAASF,CAAc,KACrCA,GAAgB,SAASE,EAAG,SAAS;AAAA,IAAA;AAEvC,QAAID,GAAa;AACf,aAAOA,EAAY;AAAA,EAEvB;AAIA,SADqBF,EAAY,eAAe,CAAC,GAC5B,eAAe;AACtC;AAWO,SAASI,GACdC,GACAR,GACAG,GACAM,GACAC,IAA0B,IAC0F;AAEpH,QAAMC,IAAW;AAAA,IACf,cAAcH;AAAA,IACd,0BAA0B;AAAA,IAC1B,mBAAmB;AAAA,IACnB,aAAa;AAAA,EAAA;AAIf,MAAIA,EAAK,SAAS;AAChB,WAAOG;AAGT,QAAMlB,IAAcS,GAAoBC,GAAaH,CAAkB;AAGvE,MAAIU;AACF,WAAO;AAAA,MACL,cAAcF,EAAK,MAAM,GAAG,EAAE;AAAA,MAC9B,0BAA0B;AAAA,MAC1B,mBAAmB;AAAA,MACnB,aAAAf;AAAA,IAAA;AAKJ,MAAI,CAACgB;AACH,WAAO,EAAE,GAAGE,GAAU,aAAAlB,EAAA;AAIxB,MAAI,CAACO;AACH,WAAO,EAAE,GAAGW,GAAU,aAAAlB,EAAA;AAIxB,MAAI,CAACU,GAAa,kBAAkBA,EAAY,eAAe,WAAW;AACxE,WAAO,EAAE,GAAGQ,GAAU,aAAAlB,EAAA;AAGxB,MAAI,CAACA;AACH,WAAOkB;AAIT,QAAMC,IAAUJ,EAAKA,EAAK,SAAS,CAAC;AACpC,SAAKV,GAAqBc,GAASZ,GAAoBP,CAAW,IAS3D,EAAE,GAAGkB,GAAU,aAAAlB,EAAA,IARb;AAAA,IACL,cAAce,EAAK,MAAM,GAAG,EAAE;AAAA,IAC9B,0BAA0B;AAAA,IAC1B,mBAAmB;AAAA,IACnB,aAAAf;AAAA,EAAA;AAKN;ACpLA,SAASoB,GAAkB;AAAA,EACzB,QAAAC;AAAA,EACA,WAAAC;AAAA,EACA,eAAAC;AAAA,EACA,eAAAC;AAAA,EACA,aAAAC;AAAA,EACA,OAAAC;AAAA,EACA,QAAAC;AACF,GAA2B;AAGzB,QAAMC,IAAU,KAAK,IAAI,IAAI,KAAK,MAAMF,IAAQ,EAAE,CAAC,GAC7CG,IACJR,EAAO,SAASO,IACZP,EAAO,MAAM,CAACO,CAAO,IACrBP,GAGAS,IAAYD,EAAc,IAAI,CAACE,MAAUA,IAAQT,CAAS,GAG1DU,IAAc,KAAK,IAAI,GAAGF,GAAW,CAAC,GACtCG,IAAc,KAAK,IAAI,GAAGH,GAAW,CAAC;AAG5C,MAFc,KAAK,IAAI,KAAK,IAAIE,CAAW,GAAG,KAAK,IAAIC,CAAW,CAAC,MAErD,KAAKH,EAAU,WAAW;AACtC,WACE,gBAAAI;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO,EAAE,OAAO,GAAGR,CAAK,MAAM,QAAQ,GAAGC,CAAM,KAAA;AAAA,QAE/C,UAAA,gBAAAO,EAAC,QAAA,EAAK,WAAU,8BAA6B,UAAA,mBAAA,CAAgB;AAAA,MAAA;AAAA,IAAA;AAMnE,QAAMC,IAAS,GACTC,IAAiBV,KAASG,EAAc,SAAS,KAAKM,GACtDE,IAAW,KAAK,IAAI,GAAGD,IAAiBP,EAAc,MAAM,GAK5DS,IAAaL,IAAcD,GAC3BO,IACJD,IAAa,IAAKL,IAAcK,IAAc,MAAM;AAEtD,SACE,gBAAAE,EAAC,OAAA,EAAI,WAAU,+BAEb,UAAA;AAAA,IAAA,gBAAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO;AAAA,UACL,OAAO,GAAGd,CAAK;AAAA,UACf,QAAQ,GAAGC,CAAM;AAAA,QAAA;AAAA,QAInB,UAAA;AAAA,UAAA,gBAAAO;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO;AAAA,gBACL,QAAQ;AAAA,gBACR,KAAK,GAAGK,CAAe;AAAA,gBACvB,iBAAiB;AAAA,gBACjB,QAAQ;AAAA,cAAA;AAAA,YACV;AAAA,UAAA;AAAA,UAIDT,EAAU,IAAI,CAACW,GAAUC,MAAU;AAElC,kBAAMC,IAAmB,KAAK,IAAIF,CAAQ,IAAIH,GACxCM,IAAY,KAAK,IAAI,GAAGD,KAAoBhB,IAAS,EAAE,GACvDkB,IAAaJ,KAAY,GACzBK,IAAcJ,MAAUb,EAAc,SAAS,GAC/CkB,IAAQF,IAAatB,IAAgBC,GACrCwB,IAAYN,KAASL,IAAWF;AAEtC,mBACE,gBAAAD;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,WAAU;AAAA,gBACV,OAAO;AAAA,kBACL,MAAM,GAAGc,CAAS;AAAA,kBAClB,OAAO,GAAGX,CAAQ;AAAA,kBAClB,QAAQ,GAAGO,CAAS;AAAA,kBACpB,iBAAiBG;AAAA,kBACjB,SAASD,IAAc,IAAI;AAAA;AAAA,kBAE3B,GAAID,IACA,EAAE,QAAQ,GAAG,MAAMN,CAAe,IAAA,IAClC,EAAE,KAAK,GAAGA,CAAe,IAAA;AAAA,kBAC7B,QAAQ;AAAA,gBAAA;AAAA,gBAEV,OAAO,GAAGd,EAAYI,EAAca,CAAK,CAAC,CAAC,KAAKD,KAAY,IAAI,MAAM,EAAE,GAAGhB,EAAYgB,CAAQ,CAAC;AAAA,cAAA;AAAA,cAd3FC;AAAA,YAAA;AAAA,UAiBX,CAAC;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAIH,gBAAAF;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO,EAAE,QAAQ,GAAGb,CAAM,KAAA;AAAA,QAE1B,UAAA;AAAA,UAAA,gBAAAa,EAAC,QAAA,EAAK,UAAA;AAAA,YAAA;AAAA,YAAEf,EAAYQ,CAAW;AAAA,UAAA,GAAE;AAAA,4BAChC,QAAA,EACE,UAAA;AAAA,aAAAD,IAAc,GAAI;AAAA,YAClBP,EAAYO,CAAW;AAAA,UAAA,EAAA,CAC1B;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EACF,GACF;AAEJ;AAEA,SAAwBiB,GAAS;AAAA,EAAA,MAC/BlC;AAAAA,EACA,aAAAmC;AAAA,EACA,eAAAC,IAAgB,CAAA;AAAA,EAChB,aAAAzC;AAAA,EACA,QAAAiB,IAAS;AAAA,EACT,cAAAyB;AACF,GAAe;AACb,QAAM,CAACC,GAAUC,CAAW,IAAIC,EAAS,EAAE,GACrC,CAACC,GAAWC,CAAY,IAAIF,EAAS,GAAG,GACxCG,IAAeC,EAAuB,IAAI,GAC1CC,IAAWD,EAAuB,IAAI,GACtC,EAAE,eAAAE,EAAA,IAAkBC,GAAA;AAmD1B,MAhDAC,GAAU,MAAM;AACd,UAAMC,IAAmB,MAAM;AAC7B,UAAIN,EAAa,SAAS;AAExB,cAAMO,IADYP,EAAa,QACR,sBAAA,GACjBQ,IAAiBD,EAAK,OACtBE,IAAkBF,EAAK;AAE7B,YAAIC,IAAiB,KAAKC,IAAkB,GAAG;AAC7C,gBAAMC,IAAiBF,IAAiB,GAClCG,IAAkBF,IAAkB,GACpCG,IAAe,KAAK,IAAIF,GAAgBC,CAAe,GACvDE,IAAkB,KAAK,IAAI,IAAI,KAAK,IAAID,GAAc,GAAG,CAAC;AAChE,UAAAhB,EAAYiB,CAAe,GAE3B,WAAW,MAAM;AACf,gBAAIX,EAAS,SAAS;AAEpB,oBAAMY,IADWZ,EAAS,QAAQ,sBAAA,EACH,OAEzBa,IAAoBP,IAAiB,KACrCQ,KAAiB,KAAK;AAAA,gBAC1BF;AAAA,gBACA,KAAK,IAAIC,GAAmBP,IAAiB,GAAG;AAAA,cAAA;AAElD,cAAAT,EAAa,KAAK,IAAI,KAAKiB,EAAc,CAAC;AAAA,YAC5C;AAAA,UACF,GAAG,EAAE;AAAA,QACP;AAAA,MACF;AAAA,IACF,GAEMC,IAAQ,WAAWX,GAAkB,EAAE,GAEvCY,IAAiB,IAAI,eAAe,MAAM;AAC9C,iBAAWZ,GAAkB,EAAE;AAAA,IACjC,CAAC;AAED,WAAIN,EAAa,WACfkB,EAAe,QAAQlB,EAAa,OAAO,GAGtC,MAAM;AACX,mBAAaiB,CAAK,GAClBC,EAAe,WAAA;AAAA,IACjB;AAAA,EACF,GAAG,CAAC7D,GAAMmC,CAAW,CAAC,GAElB,CAACnC,KAAQA,EAAK,WAAW;AAC3B,WACE,gBAAAmB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO;AAAA,UACL,QAAQP,MAAW,SAAS,SAASA;AAAA,UACrC,WAAWA,MAAW,SAAS,UAAU;AAAA,QAAA;AAAA,QAG3C,UAAA,gBAAAa,EAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,UAAA,gBAAAN,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,qBAAiB;AAAA,UAC7D,gBAAAA,EAAC,OAAA,EAAI,WAAU,kCAAiC,UAAA,4BAAA,CAEhD;AAAA,QAAA,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAMN,MAAI2C,IAAwB,CAAA,GACxBC,IAA4B,CAAA;AAchC,MAZI5B,GAAa,UACf2B,IAAc,MAAM,QAAQ3B,EAAY,KAAK,IACzCA,EAAY,QACZ,CAACA,EAAY,KAAK,IAGpBA,GAAa,UACf4B,IAAkB,MAAM,QAAQ5B,EAAY,KAAK,IAC7CA,EAAY,QACZ,CAACA,EAAY,KAAK,IAGpB2B,EAAY,WAAW;AACzB,WACE,gBAAA3C;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO;AAAA,UACL,QAAQP,MAAW,SAAS,SAASA;AAAA,UACrC,WAAWA,MAAW,SAAS,UAAU;AAAA,UACzC,iBAAiB;AAAA,UACjB,OAAO;AAAA,UACP,aAAa;AAAA,QAAA;AAAA,QAGf,UAAA,gBAAAa,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,UAAA,gBAAAN,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,uBAAmB;AAAA,UAC/D,gBAAAA,EAAC,OAAA,EAAI,WAAU,WAAU,UAAA,8BAAA,CAA2B;AAAA,QAAA,EAAA,CACtD;AAAA,MAAA;AAAA,IAAA;AAKN,QAAM6C,IAAaF,EAAY,CAAC,GAC1BlE,IAAiBmE,EAAgB,CAAC;AAGxC,MAAIE,IAAa,CAAC,GAAGjE,CAAI;AACzB,EAAIJ,MACFqE,IAAaA,EAAW,KAAK,CAACC,GAAGC,MAAM;AACrC,UAAMC,IAAOF,EAAEtE,CAAc,GACvByE,IAAOF,EAAEvE,CAAc;AAC7B,WAAIwE,IAAOC,IAAa,KACpBD,IAAOC,IAAa,IACjB;AAAA,EACT,CAAC;AAIH,QAAM,EAAE,uBAAApE,IAAwB,IAAM,gBAAAC,IAAiB,OACrDkC,GACI;AAAA,IACJ,cAAAkC;AAAA,IACA,0BAAAC;AAAA,IACA,mBAAAC;AAAA,IACA,aAAAvF;AAAA,EAAA,IACEc;AAAA,IACFkE;AAAA,IACArE;AAAA,IACAD;AAAA,IACAM;AAAA,IACAC;AAAA,EAAA,GAOII,IAHYgE,EAIf,IAAI,CAACG,MAAQA,EAAIT,CAAU,CAAC,EAC5B,OAAO,CAACU,MAAQA,KAAQ,QAA6B,CAAC,MAAM,OAAOA,CAAG,CAAC,CAAC,EACxE,IAAI,CAACA,MAAQ,OAAOA,CAAG,CAAC;AAE3B,MAAIpE,EAAO,SAAS;AAClB,WACE,gBAAAa;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO;AAAA,UACL,QAAQP,MAAW,SAAS,SAASA;AAAA,UACrC,WAAWA,MAAW,SAAS,UAAU;AAAA,UACzC,iBAAiB;AAAA,UACjB,OAAO;AAAA,UACP,aAAa;AAAA,QAAA;AAAA,QAGf,UAAA,gBAAAa,EAAC,OAAA,EAAI,WAAU,eACb,UAAA;AAAA,UAAA,gBAAAN,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,qBAAiB;AAAA,UAC7D,gBAAAA,EAAC,OAAA,EAAI,WAAU,WAAU,UAAA,qDAEzB;AAAA,UACA,gBAAAM,EAAC,OAAA,EAAI,WAAU,WAAU,UAAA;AAAA,YAAA;AAAA,YAAsBnB,EAAO;AAAA,UAAA,EAAA,CAAO;AAAA,QAAA,EAAA,CAC/D;AAAA,MAAA;AAAA,IAAA;AAMN,QAAMC,IAAYD,EAAOA,EAAO,SAAS,CAAC,GACpCqE,IAAkBrE,EAAOA,EAAO,SAAS,CAAC,GAC1CsE,IAAiBrE,IAAYoE,GAC7BE,IACJF,MAAoB,IACfC,IAAiB,KAAK,IAAID,CAAe,IAAK,MAC/C,GAEAG,IAAmBF,KAAkB,GAGrCG,IAAe,CAAC/D,MAA6C;AAEjE,QAAIoB,EAAc;AAChB,aAAOA,EAAc,YAAYpB,CAAK;AAIxC,QAAIA,KAAU;AACZ,aAAO;AAGT,UAAMgE,IAAW5C,EAAc,YAAY,GACrC6C,IAAS7C,EAAc,UAAU;AAEvC,QAAI8C;AAEJ,WAAI,KAAK,IAAIlE,CAAK,KAAK,MACrBkE,KAAkBlE,IAAQ,KAAK,QAAQgE,CAAQ,IAAI,MAC1C,KAAK,IAAIhE,CAAK,KAAK,MAC5BkE,KAAkBlE,IAAQ,KAAK,QAAQgE,CAAQ,IAAI,MAC1C,KAAK,IAAIhE,CAAK,KAAK,MAC5BkE,KAAkBlE,IAAQ,KAAK,QAAQgE,CAAQ,IAAI,MAEnDE,IAAiBlE,EAAM,QAAQgE,CAAQ,GAGlCC,IAASC;AAAA,EAClB,GAGMC,IAAmB,MAAc;AACrC,QACE/C,EAAc,uBAAuB,UACrCC,GAAc,QACd;AACA,YAAM+C,IAAahD,EAAc;AACjC,UAAIgD,KAAc,KAAKA,IAAa/C,EAAa,OAAO;AACtD,eAAOA,EAAa,OAAO+C,CAAU;AAAA,IAEzC;AACA,WAAO;AAAA,EACT,GAEMC,IAAmB,MAAc;AACrC,QACEjD,EAAc,uBAAuB,UACrCC,GAAc,QACd;AACA,YAAM+C,IAAahD,EAAc;AACjC,UAAIgD,KAAc,KAAKA,IAAa/C,EAAa,OAAO;AACtD,eAAOA,EAAa,OAAO+C,CAAU;AAAA,IAEzC;AACA,WAAO;AAAA,EACT,GAEM5E,IAAgB2E,EAAA,GAChB1E,IAAgB4E,EAAA,GAChBC,IAAeR,IAAmBtE,IAAgBC;AAExD,SACE,gBAAAgB;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAKkB;AAAA,MACL,WAAU;AAAA,MACV,OAAO;AAAA,QACL,QAAQ/B,MAAW,SAAS,SAASA;AAAA,QACrC,WAAWA,MAAW,SAAS,UAAU;AAAA,MAAA;AAAA,MAI3C,UAAA;AAAA,QAAA,gBAAAa;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,UAAU;AAAA,cACV,YAAY;AAAA,YAAA;AAAA,YAGd,UAAA;AAAA,cAAA,gBAAAN,EAAC,UACG,WAAA,MAAM;AACN,sBAAMoE,IAAQzC,EAAckB,CAAU;AACtC,uBAAOuB,KAASA,EAAM,SAAS,IAAIA,IAAQvB;AAAA,cAC7C,KAAG,CACL;AAAA,eACEO,KAA4BC,MAC5B,gBAAArD;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,OACEqD,IACI,iBAAiBvF,KAAe,QAAQ,KACxC,+BAA+BA,CAAW;AAAA,kBAEhD,WAAU;AAAA,kBAEV,UAAA,gBAAAkC;AAAA,oBAACqE;AAAA,oBAAA;AAAA,sBACC,MAAMC;AAAAA,sBACN,WAAU;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBACZ;AAAA,cAAA;AAAA,YACF;AAAA,UAAA;AAAA,QAAA;AAAA,QAKJ,gBAAAhE,EAAC,OAAA,EAAI,WAAU,mDAEb,UAAA;AAAA,UAAA,gBAAAN;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAK0B;AAAA,cACL,WAAU;AAAA,cACV,OAAO;AAAA,gBACL,UAAU,GAAGP,CAAQ;AAAA,gBACrB,OAAO;AAAA;AAAA,cAAA;AAAA,cAGR,YAAa/B,CAAS;AAAA,YAAA;AAAA,UAAA;AAAA,UAIzB,gBAAAkB,EAAC,OAAA,EAAI,WAAU,+BAEb,UAAA;AAAA,YAAA,gBAAAN;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAU;AAAA,gBACV,OAAO;AAAA,kBACL,OAAOmE;AAAA,kBACP,UAAU,GAAGhD,IAAW,IAAI;AAAA,gBAAA;AAAA,gBAG7B,cAAmB,MAAM;AAAA,cAAA;AAAA,YAAA;AAAA,YAI5B,gBAAAb,EAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,cAAA,gBAAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,UAAU,GAAGa,IAAW,IAAI;AAAA,oBAC5B,OAAOgD;AAAA,kBAAA;AAAA,kBAGR,UAAA;AAAA,oBAAAR,IAAmB,MAAM;AAAA,oBACzBC,EAAaH,CAAc;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,cAE9B,gBAAAnD;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,UAAU,GAAGa,IAAW,IAAI;AAAA,oBAC5B,OAAOgD;AAAA,oBACP,SAAS;AAAA,kBAAA;AAAA,kBAGV,UAAA;AAAA,oBAAAR,IAAmB,MAAM;AAAA,oBACzBD,EAAiB,QAAQ,CAAC;AAAA,oBAAE;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YAC/B,EAAA,CACF;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,GACF;AAAA,QAGCzC,EAAc,UAAU,CAACA,EAAc,eACtC,gBAAAjB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,UAAU;AAAA,cACV,YAAY;AAAA,cACZ,SAAS;AAAA,YAAA;AAAA,YAGV,UAAAiB,EAAc;AAAA,UAAA;AAAA,QAAA;AAAA,QAKlBA,EAAc,kBAAkB,MAAS9B,EAAO,SAAS,KACxD,gBAAAa,EAAC,OAAA,EAAI,WAAU,mDACb,UAAA,gBAAAA;AAAA,UAACd;AAAA,UAAA;AAAA,YACC,QAAAC;AAAA,YACA,WAAAC;AAAA,YACA,eAAAC;AAAA,YACA,eAAAC;AAAA,YACA,aAAasE;AAAA,YACb,OAAOtC;AAAA,YACP,QAAQ;AAAA,UAAA;AAAA,QAAA,EACV,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAIR;;;;;"}
|