elseware-ui 2.31.17 → 2.33.0

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/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var tailwindMerge = require('tailwind-merge');
4
- var React4 = require('react');
4
+ var React3 = require('react');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var bs = require('react-icons/bs');
7
7
  var fa = require('react-icons/fa');
@@ -12,7 +12,7 @@ var classNames16 = require('classnames');
12
12
  var fa6 = require('react-icons/fa6');
13
13
  var ReactWorldFlags = require('react-world-flags');
14
14
  var emojiFlags = require('emoji-flags');
15
- var d3 = require('d3');
15
+ var recharts = require('recharts');
16
16
  var cloudinaryReact = require('cloudinary-react');
17
17
  var formik = require('formik');
18
18
  var reactToastify = require('react-toastify');
@@ -28,29 +28,10 @@ var bi = require('react-icons/bi');
28
28
 
29
29
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
30
30
 
31
- function _interopNamespace(e) {
32
- if (e && e.__esModule) return e;
33
- var n = Object.create(null);
34
- if (e) {
35
- Object.keys(e).forEach(function (k) {
36
- if (k !== 'default') {
37
- var d = Object.getOwnPropertyDescriptor(e, k);
38
- Object.defineProperty(n, k, d.get ? d : {
39
- enumerable: true,
40
- get: function () { return e[k]; }
41
- });
42
- }
43
- });
44
- }
45
- n.default = e;
46
- return Object.freeze(n);
47
- }
48
-
49
- var React4__default = /*#__PURE__*/_interopDefault(React4);
31
+ var React3__default = /*#__PURE__*/_interopDefault(React3);
50
32
  var classNames16__default = /*#__PURE__*/_interopDefault(classNames16);
51
33
  var ReactWorldFlags__default = /*#__PURE__*/_interopDefault(ReactWorldFlags);
52
34
  var emojiFlags__default = /*#__PURE__*/_interopDefault(emojiFlags);
53
- var d3__namespace = /*#__PURE__*/_interopNamespace(d3);
54
35
 
55
36
  // node_modules/clsx/dist/clsx.mjs
56
37
  function r(e) {
@@ -207,16 +188,16 @@ function resolveAppearanceStyles({
207
188
  return solid[variant];
208
189
  }
209
190
  }
210
- var EUIContext = React4.createContext(null);
191
+ var EUIContext = React3.createContext(null);
211
192
  var EUIProvider = ({
212
193
  config,
213
194
  children
214
195
  }) => {
215
- const [state, setState] = React4.useState(config);
196
+ const [state, setState] = React3.useState(config);
216
197
  return /* @__PURE__ */ jsxRuntime.jsx(EUIContext.Provider, { value: { config: state, setConfig: setState }, children });
217
198
  };
218
199
  var useEUIConfig = () => {
219
- const ctx = React4.useContext(EUIContext);
200
+ const ctx = React3.useContext(EUIContext);
220
201
  if (!ctx) {
221
202
  throw new Error("useEUIConfig must be used inside EUIProvider");
222
203
  }
@@ -644,7 +625,7 @@ var Chip = ({
644
625
  }
645
626
  ) });
646
627
  };
647
- var DataViewContext = React4.createContext(null);
628
+ var DataViewContext = React3.createContext(null);
648
629
 
649
630
  // src/components/data-display/data-view/utils/searchData.ts
650
631
  function searchData(data, search) {
@@ -688,19 +669,19 @@ function DataViewProvider({
688
669
  defaultPageSize = 9,
689
670
  sortConfig = {}
690
671
  }) {
691
- const [search, setSearch] = React4.useState("");
692
- const [filters, setFilters] = React4.useState({});
693
- const [sort, setSort] = React4.useState("suggested");
694
- const [page, setPage] = React4.useState(1);
695
- const [pageSize, setPageSize] = React4.useState(defaultPageSize);
696
- const processedData = React4.useMemo(() => {
672
+ const [search, setSearch] = React3.useState("");
673
+ const [filters, setFilters] = React3.useState({});
674
+ const [sort, setSort] = React3.useState("suggested");
675
+ const [page, setPage] = React3.useState(1);
676
+ const [pageSize, setPageSize] = React3.useState(defaultPageSize);
677
+ const processedData = React3.useMemo(() => {
697
678
  let result = searchData(data, search);
698
679
  result = filterData(result, filters);
699
680
  result = sortData(result, sort, sortConfig);
700
681
  return result;
701
682
  }, [data, search, filters, sort, sortConfig]);
702
683
  const totalPages = pageSize === "All" ? 1 : Math.ceil(processedData.length / pageSize);
703
- const paginatedData = React4.useMemo(() => {
684
+ const paginatedData = React3.useMemo(() => {
704
685
  if (pageSize === "All") return processedData;
705
686
  const size = pageSize;
706
687
  const start = (page - 1) * size;
@@ -738,7 +719,7 @@ function DataViewSidebar({ children }) {
738
719
  }
739
720
  var DataViewSidebar_default = DataViewSidebar;
740
721
  function useDataView() {
741
- const ctx = React4.useContext(DataViewContext);
722
+ const ctx = React3.useContext(DataViewContext);
742
723
  if (!ctx) {
743
724
  throw new Error("useDataView must be used within DataViewProvider");
744
725
  }
@@ -804,7 +785,7 @@ function Accordion({
804
785
  toggleOnSummaryClick = false,
805
786
  enableChildrenPadding = true
806
787
  }) {
807
- const [collapse, setCollapse] = React4.useState(defaultCollapse);
788
+ const [collapse, setCollapse] = React3.useState(defaultCollapse);
808
789
  const handleToggle = () => {
809
790
  setCollapse((prev) => !prev);
810
791
  };
@@ -852,7 +833,7 @@ function Accordion({
852
833
  leave: "transition duration-75 ease-out",
853
834
  leaveFrom: "transform scale-100 opacity-100",
854
835
  leaveTo: "transform scale-95 opacity-0",
855
- as: React4.Fragment,
836
+ as: React3.Fragment,
856
837
  children: /* @__PURE__ */ jsxRuntime.jsx(
857
838
  "div",
858
839
  {
@@ -1284,329 +1265,2516 @@ function DataViewPagination({ shape }) {
1284
1265
  )
1285
1266
  ] });
1286
1267
  }
1287
- var DataViewPagination_default = DataViewPagination;
1288
-
1289
- // src/components/data-display/data-view/index.ts
1290
- var DataView = Object.assign(DataViewProvider_default, {
1291
- Header: DataViewHeader_default,
1292
- Sidebar: DataViewSidebar_default,
1293
- Content: DataViewContent_default,
1294
- Footer: DataViewFooter_default,
1295
- Pagination: DataViewPagination_default,
1296
- Search: DataViewSearch_default,
1297
- Sort: DataViewSort_default,
1298
- FilterGroup: DataViewFilterGroup_default,
1299
- PageSize: DataViewPageSize_default
1300
- });
1301
- var Flag = ({
1302
- code = "US",
1303
- width = 24,
1304
- height = 16,
1305
- className,
1306
- ...rest
1307
- }) => {
1308
- const [pos, setPos] = React4.useState({ x: 0, y: 0 });
1309
- const [showTooltip, setShowTooltip] = React4.useState(false);
1310
- const upperCode = code.toUpperCase();
1311
- const country = emojiFlags__default.default.countryCode(upperCode);
1268
+ var DataViewPagination_default = DataViewPagination;
1269
+
1270
+ // src/components/data-display/data-view/index.ts
1271
+ var DataView = Object.assign(DataViewProvider_default, {
1272
+ Header: DataViewHeader_default,
1273
+ Sidebar: DataViewSidebar_default,
1274
+ Content: DataViewContent_default,
1275
+ Footer: DataViewFooter_default,
1276
+ Pagination: DataViewPagination_default,
1277
+ Search: DataViewSearch_default,
1278
+ Sort: DataViewSort_default,
1279
+ FilterGroup: DataViewFilterGroup_default,
1280
+ PageSize: DataViewPageSize_default
1281
+ });
1282
+ var Flag = ({
1283
+ code = "US",
1284
+ width = 24,
1285
+ height = 16,
1286
+ className,
1287
+ ...rest
1288
+ }) => {
1289
+ const [pos, setPos] = React3.useState({ x: 0, y: 0 });
1290
+ const [showTooltip, setShowTooltip] = React3.useState(false);
1291
+ const upperCode = code.toUpperCase();
1292
+ const country = emojiFlags__default.default.countryCode(upperCode);
1293
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1294
+ "div",
1295
+ {
1296
+ ...rest,
1297
+ className: cn("relative inline-block", className),
1298
+ onMouseMove: (e) => {
1299
+ setPos({ x: e.clientX, y: e.clientY });
1300
+ setShowTooltip(true);
1301
+ },
1302
+ onMouseLeave: () => setShowTooltip(false),
1303
+ children: [
1304
+ /* @__PURE__ */ jsxRuntime.jsx(
1305
+ ReactWorldFlags__default.default,
1306
+ {
1307
+ code: upperCode,
1308
+ style: { width, height },
1309
+ className
1310
+ }
1311
+ ),
1312
+ showTooltip && /* @__PURE__ */ jsxRuntime.jsxs(
1313
+ "div",
1314
+ {
1315
+ className: "fixed z-50 bg-black text-white text-xs px-2 py-1 rounded shadow pointer-events-none",
1316
+ style: {
1317
+ top: pos.y + 12,
1318
+ left: pos.x + 12
1319
+ },
1320
+ children: [
1321
+ upperCode,
1322
+ " \u2014 ",
1323
+ country?.name || "Unknown"
1324
+ ]
1325
+ }
1326
+ )
1327
+ ]
1328
+ }
1329
+ );
1330
+ };
1331
+
1332
+ // src/components/data-display/graphs-v2/constants/graph.constants.ts
1333
+ var GRAPH_DEFAULT_HEIGHT = 320;
1334
+ var GRAPH_DEFAULT_MAX_REALTIME_POINTS = 100;
1335
+ var GRAPH_DEFAULT_POLLING_INTERVAL = 5e3;
1336
+ var GRAPH_DEFAULT_ANIMATION_DURATION = 350;
1337
+ var GRAPH_DEFAULT_MARGIN = {
1338
+ top: 16,
1339
+ right: 24,
1340
+ bottom: 16,
1341
+ left: 8
1342
+ };
1343
+ var GRAPH_DEFAULT_STROKE_WIDTH = 2;
1344
+ var GRAPH_DEFAULT_DOT_RADIUS = 3;
1345
+ var GRAPH_DEFAULT_ACTIVE_DOT_RADIUS = 5;
1346
+ var GRAPH_DEFAULT_BAR_RADIUS = [
1347
+ 6,
1348
+ 6,
1349
+ 0,
1350
+ 0
1351
+ ];
1352
+ var GRAPH_STATUSES = {
1353
+ IDLE: "idle",
1354
+ LOADING: "loading",
1355
+ SUCCESS: "success",
1356
+ ERROR: "error",
1357
+ STREAMING: "streaming"
1358
+ };
1359
+ var GRAPH_DATA_MODES = {
1360
+ STATIC: "static",
1361
+ POLLING: "polling",
1362
+ REALTIME: "realtime"
1363
+ };
1364
+ var GRAPH_VALUE_FORMATS = {
1365
+ RAW: "raw",
1366
+ NUMBER: "number",
1367
+ INTEGER: "integer",
1368
+ COMPACT: "compact",
1369
+ PERCENT: "percent",
1370
+ CURRENCY: "currency",
1371
+ BYTES: "bytes",
1372
+ DURATION: "duration"
1373
+ };
1374
+ var GRAPH_EMPTY_MESSAGE = "No graph data available";
1375
+ var GRAPH_ERROR_MESSAGE = "Unable to load graph data";
1376
+ var GRAPH_LOADING_MESSAGE = "Loading graph data...";
1377
+
1378
+ // src/components/data-display/graphs-v2/constants/graph-theme.constants.ts
1379
+ var GRAPH_COLOR_PALETTE = [
1380
+ "#7dd3fc",
1381
+ "#a78bfa",
1382
+ "#34d399",
1383
+ "#fbbf24",
1384
+ "#fb7185",
1385
+ "#60a5fa",
1386
+ "#f472b6",
1387
+ "#22d3ee",
1388
+ "#c084fc",
1389
+ "#a3e635"
1390
+ ];
1391
+ var GRAPH_STATUS_COLORS = {
1392
+ primary: "#7dd3fc",
1393
+ secondary: "#a78bfa",
1394
+ success: "#34d399",
1395
+ warning: "#fbbf24",
1396
+ danger: "#fb7185",
1397
+ info: "#60a5fa",
1398
+ muted: "#6b7280"
1399
+ };
1400
+ var GRAPH_DARK_THEME = {
1401
+ panel: {
1402
+ background: "bg-[#111217]",
1403
+ border: "border border-[#2a2d35]",
1404
+ radius: "rounded-xl",
1405
+ shadow: "shadow-sm"
1406
+ },
1407
+ text: {
1408
+ title: "text-gray-100",
1409
+ description: "text-gray-400",
1410
+ muted: "text-gray-500"
1411
+ },
1412
+ chart: {
1413
+ grid: "#2a2d35",
1414
+ axis: "#8b949e",
1415
+ cursor: "rgba(255, 255, 255, 0.06)"
1416
+ },
1417
+ tooltip: {
1418
+ background: "#181b21",
1419
+ border: "#2a2d35",
1420
+ text: "#f3f4f6",
1421
+ muted: "#9ca3af"
1422
+ },
1423
+ colors: GRAPH_COLOR_PALETTE
1424
+ };
1425
+ var GRAPH_LIGHT_THEME = {
1426
+ panel: {
1427
+ background: "bg-white",
1428
+ border: "border border-gray-200",
1429
+ radius: "rounded-xl",
1430
+ shadow: "shadow-sm"
1431
+ },
1432
+ text: {
1433
+ title: "text-gray-900",
1434
+ description: "text-gray-500",
1435
+ muted: "text-gray-400"
1436
+ },
1437
+ chart: {
1438
+ grid: "#e5e7eb",
1439
+ axis: "#6b7280",
1440
+ cursor: "rgba(0, 0, 0, 0.04)"
1441
+ },
1442
+ tooltip: {
1443
+ background: "#ffffff",
1444
+ border: "#e5e7eb",
1445
+ text: "#111827",
1446
+ muted: "#6b7280"
1447
+ },
1448
+ colors: GRAPH_COLOR_PALETTE
1449
+ };
1450
+ var DEFAULT_GRAPH_THEME = GRAPH_DARK_THEME;
1451
+
1452
+ // src/components/data-display/graphs-v2/utils/normalizeGraphData.ts
1453
+ var DEFAULT_NORMALIZE_OPTIONS = {
1454
+ serializeDates: true,
1455
+ parseNumericStrings: true,
1456
+ sanitizeInvalidNumbers: true,
1457
+ removeUndefined: true
1458
+ };
1459
+ function isNumericString(value) {
1460
+ if (!value.trim()) {
1461
+ return false;
1462
+ }
1463
+ return !Number.isNaN(Number(value));
1464
+ }
1465
+ function normalizeValue(value, options) {
1466
+ if (value instanceof Date) {
1467
+ return options.serializeDates ? value.toISOString() : value;
1468
+ }
1469
+ if (typeof value === "number") {
1470
+ if (options.sanitizeInvalidNumbers && (Number.isNaN(value) || !Number.isFinite(value))) {
1471
+ return null;
1472
+ }
1473
+ return value;
1474
+ }
1475
+ if (typeof value === "string") {
1476
+ if (options.parseNumericStrings && isNumericString(value)) {
1477
+ return Number(value);
1478
+ }
1479
+ return value;
1480
+ }
1481
+ if (typeof value === "boolean" || value === null || value === void 0) {
1482
+ return value;
1483
+ }
1484
+ return String(value);
1485
+ }
1486
+ function normalizeGraphData(data, options = {}) {
1487
+ if (!Array.isArray(data)) {
1488
+ return [];
1489
+ }
1490
+ const resolvedOptions = {
1491
+ ...DEFAULT_NORMALIZE_OPTIONS,
1492
+ ...options
1493
+ };
1494
+ return data.map((item) => {
1495
+ const normalizedPoint = {};
1496
+ const keys = options.keys ?? Object.keys(item);
1497
+ keys.forEach((key) => {
1498
+ const value = normalizeValue(item[key], resolvedOptions);
1499
+ if (resolvedOptions.removeUndefined && value === void 0) {
1500
+ return;
1501
+ }
1502
+ normalizedPoint[key] = value;
1503
+ });
1504
+ return normalizedPoint;
1505
+ });
1506
+ }
1507
+ function normalizeGraphDataPoint(dataPoint, options = {}) {
1508
+ return normalizeGraphData([dataPoint], options)[0] ?? {};
1509
+ }
1510
+
1511
+ // src/components/data-display/graphs-v2/utils/formatGraphValue.ts
1512
+ var DEFAULT_FORMAT_OPTIONS = {
1513
+ format: "number",
1514
+ locale: "en-US",
1515
+ fallback: "-"
1516
+ };
1517
+ function isValidNumber(value) {
1518
+ return typeof value === "number" && Number.isFinite(value) && !Number.isNaN(value);
1519
+ }
1520
+ function formatBytes(value, locale) {
1521
+ if (value === 0) {
1522
+ return "0 B";
1523
+ }
1524
+ const units = ["B", "KB", "MB", "GB", "TB", "PB"];
1525
+ const unitIndex = Math.min(
1526
+ Math.floor(Math.log(Math.abs(value)) / Math.log(1024)),
1527
+ units.length - 1
1528
+ );
1529
+ const formattedValue = value / 1024 ** unitIndex;
1530
+ return `${new Intl.NumberFormat(locale, {
1531
+ maximumFractionDigits: formattedValue >= 10 ? 1 : 2
1532
+ }).format(formattedValue)} ${units[unitIndex]}`;
1533
+ }
1534
+ function formatDuration(value, locale) {
1535
+ if (value < 1e3) {
1536
+ return `${Math.round(value)} ms`;
1537
+ }
1538
+ const seconds = value / 1e3;
1539
+ if (seconds < 60) {
1540
+ return `${new Intl.NumberFormat(locale, {
1541
+ maximumFractionDigits: 2
1542
+ }).format(seconds)} s`;
1543
+ }
1544
+ const minutes = seconds / 60;
1545
+ if (minutes < 60) {
1546
+ return `${new Intl.NumberFormat(locale, {
1547
+ maximumFractionDigits: 2
1548
+ }).format(minutes)} min`;
1549
+ }
1550
+ const hours = minutes / 60;
1551
+ return `${new Intl.NumberFormat(locale, {
1552
+ maximumFractionDigits: 2
1553
+ }).format(hours)} h`;
1554
+ }
1555
+ function formatGraphValue(value, options = {}) {
1556
+ const {
1557
+ format,
1558
+ locale,
1559
+ fallback,
1560
+ prefix = "",
1561
+ suffix = "",
1562
+ currency = "USD",
1563
+ minimumFractionDigits,
1564
+ maximumFractionDigits
1565
+ } = {
1566
+ ...DEFAULT_FORMAT_OPTIONS,
1567
+ ...options
1568
+ };
1569
+ if (value === null || value === void 0 || value === "") {
1570
+ return fallback;
1571
+ }
1572
+ if (format === "raw") {
1573
+ return `${prefix}${String(value)}${suffix}`;
1574
+ }
1575
+ const numericValue = typeof value === "string" && value.trim() !== "" ? Number(value) : value;
1576
+ if (!isValidNumber(numericValue)) {
1577
+ return `${prefix}${String(value)}${suffix}`;
1578
+ }
1579
+ let formattedValue;
1580
+ switch (format) {
1581
+ case "integer":
1582
+ formattedValue = new Intl.NumberFormat(locale, {
1583
+ maximumFractionDigits: 0
1584
+ }).format(numericValue);
1585
+ break;
1586
+ case "compact":
1587
+ formattedValue = new Intl.NumberFormat(locale, {
1588
+ notation: "compact",
1589
+ maximumFractionDigits: maximumFractionDigits ?? 2
1590
+ }).format(numericValue);
1591
+ break;
1592
+ case "percent":
1593
+ formattedValue = new Intl.NumberFormat(locale, {
1594
+ style: "percent",
1595
+ minimumFractionDigits: minimumFractionDigits ?? 0,
1596
+ maximumFractionDigits: maximumFractionDigits ?? 2
1597
+ }).format(numericValue / 100);
1598
+ break;
1599
+ case "currency":
1600
+ formattedValue = new Intl.NumberFormat(locale, {
1601
+ style: "currency",
1602
+ currency,
1603
+ minimumFractionDigits,
1604
+ maximumFractionDigits
1605
+ }).format(numericValue);
1606
+ break;
1607
+ case "bytes":
1608
+ formattedValue = formatBytes(numericValue, locale);
1609
+ break;
1610
+ case "duration":
1611
+ formattedValue = formatDuration(numericValue, locale);
1612
+ break;
1613
+ case "number":
1614
+ default:
1615
+ formattedValue = new Intl.NumberFormat(locale, {
1616
+ minimumFractionDigits,
1617
+ maximumFractionDigits: maximumFractionDigits ?? 2
1618
+ }).format(numericValue);
1619
+ break;
1620
+ }
1621
+ return `${prefix}${formattedValue}${suffix}`;
1622
+ }
1623
+
1624
+ // src/components/data-display/graphs-v2/utils/resolveGraphColor.ts
1625
+ var NAMED_COLORS = {
1626
+ primary: GRAPH_STATUS_COLORS.primary,
1627
+ secondary: GRAPH_STATUS_COLORS.secondary,
1628
+ success: GRAPH_STATUS_COLORS.success,
1629
+ warning: GRAPH_STATUS_COLORS.warning,
1630
+ danger: GRAPH_STATUS_COLORS.danger,
1631
+ info: GRAPH_STATUS_COLORS.info,
1632
+ muted: GRAPH_STATUS_COLORS.muted
1633
+ };
1634
+ function isCssColor(value) {
1635
+ return value.startsWith("#") || value.startsWith("rgb(") || value.startsWith("rgba(") || value.startsWith("hsl(") || value.startsWith("hsla(") || value.startsWith("var(");
1636
+ }
1637
+ function resolveGraphColor(color, options = {}) {
1638
+ const {
1639
+ index = 0,
1640
+ fallback = GRAPH_COLOR_PALETTE[0],
1641
+ palette = GRAPH_COLOR_PALETTE
1642
+ } = options;
1643
+ if (color) {
1644
+ if (isCssColor(color)) {
1645
+ return color;
1646
+ }
1647
+ if (color in NAMED_COLORS) {
1648
+ return NAMED_COLORS[color];
1649
+ }
1650
+ }
1651
+ if (palette.length > 0) {
1652
+ return palette[index % palette.length];
1653
+ }
1654
+ return fallback;
1655
+ }
1656
+ function resolveGraphColors(count, options = {}) {
1657
+ return Array.from(
1658
+ { length: count },
1659
+ (_, index) => resolveGraphColor(void 0, {
1660
+ ...options,
1661
+ index
1662
+ })
1663
+ );
1664
+ }
1665
+
1666
+ // src/components/data-display/graphs-v2/utils/limitRealtimePoints.ts
1667
+ var DEFAULT_MAX_POINTS = 100;
1668
+ function limitRealtimePoints(currentData = [], nextData, options = {}) {
1669
+ const { maxPoints = DEFAULT_MAX_POINTS, appendDirection = "end" } = options;
1670
+ const incomingData = Array.isArray(nextData) ? nextData : [nextData];
1671
+ const mergedData = appendDirection === "start" ? [...incomingData, ...currentData] : [...currentData, ...incomingData];
1672
+ if (maxPoints <= 0) {
1673
+ return mergedData;
1674
+ }
1675
+ if (mergedData.length <= maxPoints) {
1676
+ return mergedData;
1677
+ }
1678
+ return appendDirection === "start" ? mergedData.slice(0, maxPoints) : mergedData.slice(-maxPoints);
1679
+ }
1680
+ function replaceRealtimePoints(nextData = [], options = {}) {
1681
+ const { maxPoints = DEFAULT_MAX_POINTS } = options;
1682
+ if (maxPoints <= 0) {
1683
+ return nextData;
1684
+ }
1685
+ return nextData.slice(-maxPoints);
1686
+ }
1687
+
1688
+ // src/components/data-display/graphs-v2/hooks/useGraphData.ts
1689
+ function useGraphData({
1690
+ data,
1691
+ dataSource,
1692
+ autoLoad = true,
1693
+ maxDataPoints = GRAPH_DEFAULT_MAX_REALTIME_POINTS,
1694
+ normalize: normalize2 = true,
1695
+ onDataChange,
1696
+ onError
1697
+ } = {}) {
1698
+ const [state, setState] = React3.useState({
1699
+ data: data ?? [],
1700
+ loading: false,
1701
+ error: null,
1702
+ status: data?.length ? "success" : "idle",
1703
+ lastUpdatedAt: data?.length ? /* @__PURE__ */ new Date() : void 0
1704
+ });
1705
+ const prepareData = React3.useCallback(
1706
+ (nextData) => {
1707
+ if (!normalize2) {
1708
+ return nextData;
1709
+ }
1710
+ return normalizeGraphData(nextData);
1711
+ },
1712
+ [normalize2]
1713
+ );
1714
+ const replaceData = React3.useCallback(
1715
+ (nextData) => {
1716
+ const normalizedData = prepareData(nextData);
1717
+ setState({
1718
+ data: normalizedData,
1719
+ loading: false,
1720
+ error: null,
1721
+ status: "success",
1722
+ lastUpdatedAt: /* @__PURE__ */ new Date()
1723
+ });
1724
+ onDataChange?.(normalizedData);
1725
+ },
1726
+ [onDataChange, prepareData]
1727
+ );
1728
+ const appendData = React3.useCallback(
1729
+ (nextData) => {
1730
+ setState((currentState) => {
1731
+ const incomingData = Array.isArray(nextData) ? nextData : [nextData];
1732
+ const normalizedIncomingData = prepareData(incomingData);
1733
+ const limitedData = limitRealtimePoints(
1734
+ currentState.data,
1735
+ normalizedIncomingData,
1736
+ {
1737
+ maxPoints: maxDataPoints
1738
+ }
1739
+ );
1740
+ onDataChange?.(limitedData);
1741
+ return {
1742
+ data: limitedData,
1743
+ loading: false,
1744
+ error: null,
1745
+ status: "streaming",
1746
+ lastUpdatedAt: /* @__PURE__ */ new Date()
1747
+ };
1748
+ });
1749
+ },
1750
+ [maxDataPoints, onDataChange, prepareData]
1751
+ );
1752
+ const clearData = React3.useCallback(() => {
1753
+ setState({
1754
+ data: [],
1755
+ loading: false,
1756
+ error: null,
1757
+ status: "idle",
1758
+ lastUpdatedAt: void 0
1759
+ });
1760
+ onDataChange?.([]);
1761
+ }, [onDataChange]);
1762
+ const handleError = React3.useCallback(
1763
+ (error) => {
1764
+ setState((currentState) => ({
1765
+ ...currentState,
1766
+ loading: false,
1767
+ error,
1768
+ status: "error"
1769
+ }));
1770
+ onError?.(error);
1771
+ },
1772
+ [onError]
1773
+ );
1774
+ const refresh = React3.useCallback(async () => {
1775
+ const resolvedDataSource = dataSource;
1776
+ if (!resolvedDataSource?.refresh && !resolvedDataSource?.getInitialData) {
1777
+ return;
1778
+ }
1779
+ try {
1780
+ setState((currentState) => ({
1781
+ ...currentState,
1782
+ loading: true,
1783
+ error: null,
1784
+ status: "loading"
1785
+ }));
1786
+ const loader = resolvedDataSource.refresh ?? resolvedDataSource.getInitialData;
1787
+ const result = await loader?.();
1788
+ replaceData(result ?? []);
1789
+ } catch (error) {
1790
+ handleError(error instanceof Error ? error : new Error(String(error)));
1791
+ }
1792
+ }, [dataSource, handleError, replaceData]);
1793
+ React3.useEffect(() => {
1794
+ if (!data) {
1795
+ return;
1796
+ }
1797
+ replaceData(data);
1798
+ }, [data, replaceData]);
1799
+ React3.useEffect(() => {
1800
+ if (!dataSource || !autoLoad) {
1801
+ return;
1802
+ }
1803
+ const resolvedDataSource = dataSource;
1804
+ let unsubscribe;
1805
+ let isMounted = true;
1806
+ async function loadInitialData() {
1807
+ if (!resolvedDataSource.getInitialData) {
1808
+ return;
1809
+ }
1810
+ try {
1811
+ setState((currentState) => ({
1812
+ ...currentState,
1813
+ loading: true,
1814
+ error: null,
1815
+ status: "loading"
1816
+ }));
1817
+ const result = await resolvedDataSource.getInitialData();
1818
+ if (isMounted) {
1819
+ replaceData(result ?? []);
1820
+ }
1821
+ } catch (error) {
1822
+ if (isMounted) {
1823
+ handleError(
1824
+ error instanceof Error ? error : new Error(String(error))
1825
+ );
1826
+ }
1827
+ }
1828
+ }
1829
+ void loadInitialData();
1830
+ if (resolvedDataSource.subscribe) {
1831
+ unsubscribe = resolvedDataSource.subscribe(appendData, handleError);
1832
+ }
1833
+ return () => {
1834
+ isMounted = false;
1835
+ unsubscribe?.();
1836
+ };
1837
+ }, [appendData, autoLoad, dataSource, handleError, replaceData]);
1838
+ return React3.useMemo(
1839
+ () => ({
1840
+ ...state,
1841
+ refresh,
1842
+ replaceData,
1843
+ appendData,
1844
+ clearData
1845
+ }),
1846
+ [appendData, clearData, refresh, replaceData, state]
1847
+ );
1848
+ }
1849
+ function useGraphRealtime({
1850
+ enabled = true,
1851
+ maxDataPoints = GRAPH_DEFAULT_MAX_REALTIME_POINTS,
1852
+ normalize: normalize2 = true,
1853
+ connect,
1854
+ onData,
1855
+ onError
1856
+ }) {
1857
+ const [data, setData] = React3.useState([]);
1858
+ const [error, setError] = React3.useState(null);
1859
+ const [connected, setConnected] = React3.useState(false);
1860
+ const [lastUpdatedAt, setLastUpdatedAt] = React3.useState();
1861
+ React3.useEffect(() => {
1862
+ if (!enabled) {
1863
+ setConnected(false);
1864
+ return;
1865
+ }
1866
+ const handleData = (incomingData) => {
1867
+ const incomingArray = Array.isArray(incomingData) ? incomingData : [incomingData];
1868
+ const normalizedIncomingData = normalize2 ? normalizeGraphData(incomingArray) : incomingArray;
1869
+ setData((currentData) => {
1870
+ const nextData = limitRealtimePoints(
1871
+ currentData,
1872
+ normalizedIncomingData,
1873
+ {
1874
+ maxPoints: maxDataPoints
1875
+ }
1876
+ );
1877
+ onData?.(nextData);
1878
+ return nextData;
1879
+ });
1880
+ setError(null);
1881
+ setConnected(true);
1882
+ setLastUpdatedAt(/* @__PURE__ */ new Date());
1883
+ };
1884
+ const handleError = (nextError) => {
1885
+ setError(nextError);
1886
+ onError?.(nextError);
1887
+ };
1888
+ const unsubscribe = connect(handleData, handleError);
1889
+ setConnected(true);
1890
+ return () => {
1891
+ unsubscribe?.();
1892
+ setConnected(false);
1893
+ };
1894
+ }, [connect, enabled, maxDataPoints, normalize2, onData, onError]);
1895
+ return React3.useMemo(
1896
+ () => ({
1897
+ data,
1898
+ error,
1899
+ connected,
1900
+ loading: enabled && !connected && !error,
1901
+ status: error ? "error" : connected ? "streaming" : "idle",
1902
+ lastUpdatedAt,
1903
+ clearData: () => setData([])
1904
+ }),
1905
+ [connected, data, enabled, error, lastUpdatedAt]
1906
+ );
1907
+ }
1908
+ function useGraphPolling({
1909
+ enabled = true,
1910
+ interval = GRAPH_DEFAULT_POLLING_INTERVAL,
1911
+ immediate = true,
1912
+ normalize: normalize2 = true,
1913
+ fetcher,
1914
+ onData,
1915
+ onError
1916
+ }) {
1917
+ const isMountedRef = React3.useRef(false);
1918
+ const isFetchingRef = React3.useRef(false);
1919
+ const [data, setData] = React3.useState([]);
1920
+ const [error, setError] = React3.useState(null);
1921
+ const [loading, setLoading] = React3.useState(immediate);
1922
+ const [lastUpdatedAt, setLastUpdatedAt] = React3.useState();
1923
+ const refresh = React3.useCallback(async () => {
1924
+ if (isFetchingRef.current) {
1925
+ return;
1926
+ }
1927
+ try {
1928
+ isFetchingRef.current = true;
1929
+ setLoading(true);
1930
+ setError(null);
1931
+ const result = await fetcher();
1932
+ const nextData = normalize2 ? normalizeGraphData(result ?? []) : result ?? [];
1933
+ if (!isMountedRef.current) {
1934
+ return;
1935
+ }
1936
+ setData(nextData);
1937
+ setLastUpdatedAt(/* @__PURE__ */ new Date());
1938
+ onData?.(nextData);
1939
+ } catch (error2) {
1940
+ const nextError = error2 instanceof Error ? error2 : new Error(String(error2));
1941
+ if (isMountedRef.current) {
1942
+ setError(nextError);
1943
+ onError?.(nextError);
1944
+ }
1945
+ } finally {
1946
+ if (isMountedRef.current) {
1947
+ setLoading(false);
1948
+ }
1949
+ isFetchingRef.current = false;
1950
+ }
1951
+ }, [fetcher, normalize2, onData, onError]);
1952
+ React3.useEffect(() => {
1953
+ isMountedRef.current = true;
1954
+ return () => {
1955
+ isMountedRef.current = false;
1956
+ };
1957
+ }, []);
1958
+ React3.useEffect(() => {
1959
+ if (!enabled) {
1960
+ setLoading(false);
1961
+ return;
1962
+ }
1963
+ if (immediate) {
1964
+ void refresh();
1965
+ }
1966
+ const timer = window.setInterval(() => {
1967
+ void refresh();
1968
+ }, interval);
1969
+ return () => {
1970
+ window.clearInterval(timer);
1971
+ };
1972
+ }, [enabled, immediate, interval, refresh]);
1973
+ return React3.useMemo(
1974
+ () => ({
1975
+ data,
1976
+ error,
1977
+ loading,
1978
+ status: error ? "error" : loading ? "loading" : "success",
1979
+ lastUpdatedAt,
1980
+ refresh
1981
+ }),
1982
+ [data, error, lastUpdatedAt, loading, refresh]
1983
+ );
1984
+ }
1985
+ function createLabelFromKey(key) {
1986
+ return key.replace(/[_-]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (character) => character.toUpperCase());
1987
+ }
1988
+ function inferSeriesKeys(data, xKey, excludeKeys = []) {
1989
+ const firstPoint = data[0];
1990
+ if (!firstPoint) {
1991
+ return [];
1992
+ }
1993
+ return Object.keys(firstPoint).filter((key) => {
1994
+ if (key === xKey) {
1995
+ return false;
1996
+ }
1997
+ if (excludeKeys.includes(key)) {
1998
+ return false;
1999
+ }
2000
+ const value = firstPoint[key];
2001
+ return typeof value === "number";
2002
+ });
2003
+ }
2004
+ function useGraphSeries({
2005
+ data = [],
2006
+ series,
2007
+ xKey,
2008
+ excludeKeys = []
2009
+ }) {
2010
+ return React3.useMemo(() => {
2011
+ const normalizedSeries = series && series.length > 0 ? series : inferSeriesKeys(data, xKey, excludeKeys).map((key) => ({
2012
+ key
2013
+ }));
2014
+ return normalizedSeries.map((item, index) => ({
2015
+ key: item.key,
2016
+ label: item.label ?? createLabelFromKey(item.key),
2017
+ type: item.type ?? "line",
2018
+ color: resolveGraphColor(item.color, { index }),
2019
+ unit: item.unit,
2020
+ visible: item.visible ?? true,
2021
+ strokeWidth: item.strokeWidth ?? GRAPH_DEFAULT_STROKE_WIDTH,
2022
+ radius: item.radius ?? GRAPH_DEFAULT_ACTIVE_DOT_RADIUS,
2023
+ format: item.format,
2024
+ prefix: item.prefix,
2025
+ suffix: item.suffix,
2026
+ yAxisId: item.yAxisId
2027
+ }));
2028
+ }, [data, excludeKeys, series, xKey]);
2029
+ }
2030
+ function mergeGraphTheme(baseTheme, customTheme) {
2031
+ if (!customTheme) {
2032
+ return baseTheme;
2033
+ }
2034
+ return {
2035
+ panel: {
2036
+ ...baseTheme.panel,
2037
+ ...customTheme.panel
2038
+ },
2039
+ text: {
2040
+ ...baseTheme.text,
2041
+ ...customTheme.text
2042
+ },
2043
+ chart: {
2044
+ ...baseTheme.chart,
2045
+ ...customTheme.chart
2046
+ },
2047
+ tooltip: {
2048
+ ...baseTheme.tooltip,
2049
+ ...customTheme.tooltip
2050
+ },
2051
+ colors: customTheme.colors ?? baseTheme.colors
2052
+ };
2053
+ }
2054
+ function useGraphTheme({
2055
+ mode = "dark",
2056
+ theme
2057
+ } = {}) {
2058
+ return React3.useMemo(() => {
2059
+ const baseTheme = mode === "light" ? GRAPH_LIGHT_THEME : mode === "dark" ? GRAPH_DARK_THEME : DEFAULT_GRAPH_THEME;
2060
+ return mergeGraphTheme(baseTheme, theme);
2061
+ }, [mode, theme]);
2062
+ }
2063
+ var GraphContext = React3.createContext({
2064
+ data: [],
2065
+ loading: false,
2066
+ error: null,
2067
+ status: "idle",
2068
+ maxDataPoints: GRAPH_DEFAULT_MAX_REALTIME_POINTS,
2069
+ refresh: async () => {
2070
+ },
2071
+ replaceData: () => {
2072
+ },
2073
+ appendData: () => {
2074
+ },
2075
+ clearData: () => {
2076
+ }
2077
+ });
2078
+ function GraphProvider({
2079
+ children,
2080
+ data,
2081
+ dataSource,
2082
+ maxDataPoints = GRAPH_DEFAULT_MAX_REALTIME_POINTS,
2083
+ autoLoad = true,
2084
+ onDataChange,
2085
+ onError
2086
+ }) {
2087
+ const graphData = useGraphData({
2088
+ data,
2089
+ dataSource,
2090
+ autoLoad,
2091
+ maxDataPoints,
2092
+ onDataChange,
2093
+ onError
2094
+ });
2095
+ const value = React3.useMemo(
2096
+ () => ({
2097
+ ...graphData,
2098
+ mode: dataSource?.mode,
2099
+ maxDataPoints
2100
+ }),
2101
+ [dataSource?.mode, graphData, maxDataPoints]
2102
+ );
2103
+ return /* @__PURE__ */ jsxRuntime.jsx(
2104
+ GraphContext.Provider,
2105
+ {
2106
+ value,
2107
+ children
2108
+ }
2109
+ );
2110
+ }
2111
+ function useGraphContext() {
2112
+ return React3.useContext(GraphContext);
2113
+ }
2114
+
2115
+ // src/components/data-display/graphs-v2/context/graphReducer.ts
2116
+ function createInitialGraphState(data = []) {
2117
+ return {
2118
+ data,
2119
+ loading: false,
2120
+ error: null,
2121
+ status: data.length > 0 ? "success" : "idle",
2122
+ lastUpdatedAt: data.length > 0 ? /* @__PURE__ */ new Date() : void 0
2123
+ };
2124
+ }
2125
+ function graphReducer(state, action) {
2126
+ switch (action.type) {
2127
+ case "SET_LOADING": {
2128
+ const loading = action.payload ?? true;
2129
+ return {
2130
+ ...state,
2131
+ loading,
2132
+ error: loading ? null : state.error,
2133
+ status: loading ? "loading" : state.status
2134
+ };
2135
+ }
2136
+ case "SET_ERROR": {
2137
+ return {
2138
+ ...state,
2139
+ loading: false,
2140
+ error: action.payload,
2141
+ status: action.payload ? "error" : state.data.length > 0 ? "success" : "idle"
2142
+ };
2143
+ }
2144
+ case "SET_DATA": {
2145
+ return {
2146
+ data: action.payload,
2147
+ loading: false,
2148
+ error: null,
2149
+ status: "success",
2150
+ lastUpdatedAt: /* @__PURE__ */ new Date()
2151
+ };
2152
+ }
2153
+ case "APPEND_DATA": {
2154
+ const nextData = limitRealtimePoints(state.data, action.payload.data, {
2155
+ maxPoints: action.payload.maxDataPoints ?? GRAPH_DEFAULT_MAX_REALTIME_POINTS
2156
+ });
2157
+ return {
2158
+ data: nextData,
2159
+ loading: false,
2160
+ error: null,
2161
+ status: "streaming",
2162
+ lastUpdatedAt: /* @__PURE__ */ new Date()
2163
+ };
2164
+ }
2165
+ case "CLEAR_DATA": {
2166
+ return {
2167
+ data: [],
2168
+ loading: false,
2169
+ error: null,
2170
+ status: "idle",
2171
+ lastUpdatedAt: void 0
2172
+ };
2173
+ }
2174
+ case "SET_STREAMING": {
2175
+ const streaming = action.payload ?? true;
2176
+ return {
2177
+ ...state,
2178
+ loading: false,
2179
+ error: null,
2180
+ status: streaming ? "streaming" : state.data.length > 0 ? "success" : "idle",
2181
+ lastUpdatedAt: streaming ? /* @__PURE__ */ new Date() : state.lastUpdatedAt
2182
+ };
2183
+ }
2184
+ default:
2185
+ return state;
2186
+ }
2187
+ }
2188
+ function GraphEmptyState({
2189
+ height = GRAPH_DEFAULT_HEIGHT,
2190
+ message = GRAPH_EMPTY_MESSAGE,
2191
+ description,
2192
+ className = ""
2193
+ }) {
2194
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2195
+ "div",
2196
+ {
2197
+ className: `eui-graph flex flex-col items-center justify-center rounded-xl border border-dashed border-gray-700/80 bg-[#111217]/40 px-6 text-center ${className}`,
2198
+ style: { height },
2199
+ children: [
2200
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full border border-gray-700 bg-white/5 text-gray-500", children: "\u2205" }),
2201
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 text-sm font-medium text-gray-300", children: message }),
2202
+ description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 max-w-sm text-xs text-gray-500", children: description })
2203
+ ]
2204
+ }
2205
+ );
2206
+ }
2207
+ function GraphErrorState({
2208
+ error,
2209
+ height = GRAPH_DEFAULT_HEIGHT,
2210
+ title = GRAPH_ERROR_MESSAGE,
2211
+ message,
2212
+ className = "",
2213
+ onRetry,
2214
+ retryLabel = "Retry"
2215
+ }) {
2216
+ const resolvedMessage = message ?? error?.message;
2217
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2218
+ "div",
2219
+ {
2220
+ className: `eui-graph flex flex-col items-center justify-center rounded-xl border border-red-500/30 bg-red-500/5 px-6 text-center ${className}`,
2221
+ style: { height },
2222
+ role: "alert",
2223
+ children: [
2224
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full border border-red-500/30 bg-red-500/10 text-red-400", children: "!" }),
2225
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 text-sm font-medium text-red-300", children: title }),
2226
+ resolvedMessage && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 max-w-md text-xs text-red-200/70", children: resolvedMessage }),
2227
+ onRetry && /* @__PURE__ */ jsxRuntime.jsx(
2228
+ "button",
2229
+ {
2230
+ type: "button",
2231
+ onClick: () => void onRetry(),
2232
+ className: "mt-4 rounded-md border border-red-500/30 px-3 py-1.5 text-xs font-medium text-red-200 transition-colors hover:bg-red-500/10",
2233
+ children: retryLabel
2234
+ }
2235
+ )
2236
+ ]
2237
+ }
2238
+ );
2239
+ }
2240
+ function GraphHeader({
2241
+ title,
2242
+ description,
2243
+ actions,
2244
+ className = ""
2245
+ }) {
2246
+ if (!title && !description && !actions) {
2247
+ return null;
2248
+ }
2249
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2250
+ "div",
2251
+ {
2252
+ className: `flex items-start justify-between gap-4 border-b border-[#2a2d35] px-4 py-3 ${className}`,
2253
+ children: [
2254
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
2255
+ title && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "eui-graph-title truncate text-sm font-semibold text-gray-100", children: title }),
2256
+ description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "eui-graph-description mt-1 text-xs text-gray-400", children: description })
2257
+ ] }),
2258
+ actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: actions })
2259
+ ]
2260
+ }
2261
+ );
2262
+ }
2263
+ function GraphLoadingState({
2264
+ height = GRAPH_DEFAULT_HEIGHT,
2265
+ message = GRAPH_LOADING_MESSAGE,
2266
+ className = "",
2267
+ showMessage = true
2268
+ }) {
2269
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2270
+ "div",
2271
+ {
2272
+ className: `eui-graph eui-graph-loading flex flex-col items-center justify-center rounded-xl border border-[#2a2d35] bg-[#111217]/60 px-6 text-center ${className}`,
2273
+ style: { height },
2274
+ role: "status",
2275
+ "aria-live": "polite",
2276
+ "aria-busy": "true",
2277
+ children: [
2278
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-7 w-7 animate-spin rounded-full border-2 border-gray-700 border-t-gray-200" }),
2279
+ showMessage && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-3 text-sm font-medium text-gray-300", children: message })
2280
+ ]
2281
+ }
2282
+ );
2283
+ }
2284
+ function formatLastUpdatedAt(value) {
2285
+ if (!value) {
2286
+ return "Never updated";
2287
+ }
2288
+ return `Updated ${value.toLocaleTimeString([], {
2289
+ hour: "2-digit",
2290
+ minute: "2-digit",
2291
+ second: "2-digit"
2292
+ })}`;
2293
+ }
2294
+ function GraphToolbar({
2295
+ children,
2296
+ className = "",
2297
+ showRefresh = true,
2298
+ showLastUpdated = true,
2299
+ refreshLabel = "Refresh",
2300
+ onRefresh
2301
+ }) {
2302
+ const graph = useGraphContext();
2303
+ async function handleRefresh() {
2304
+ if (onRefresh) {
2305
+ await onRefresh();
2306
+ return;
2307
+ }
2308
+ await graph.refresh();
2309
+ }
2310
+ if (!children && !showRefresh && !showLastUpdated) {
2311
+ return null;
2312
+ }
2313
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2314
+ "div",
2315
+ {
2316
+ className: `flex flex-wrap items-center justify-between gap-3 border-b border-[#2a2d35] px-4 py-2 ${className}`,
2317
+ children: [
2318
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-0 items-center gap-2", children }),
2319
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-auto flex items-center gap-3", children: [
2320
+ showLastUpdated && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-500", children: formatLastUpdatedAt(graph.lastUpdatedAt) }),
2321
+ showRefresh && /* @__PURE__ */ jsxRuntime.jsx(
2322
+ "button",
2323
+ {
2324
+ type: "button",
2325
+ onClick: () => void handleRefresh(),
2326
+ disabled: graph.loading,
2327
+ className: "rounded-md border border-[#2a2d35] px-2.5 py-1.5 text-xs font-medium text-gray-300 transition-colors hover:bg-white/5 disabled:cursor-not-allowed disabled:opacity-60",
2328
+ children: graph.loading ? "Refreshing..." : refreshLabel
2329
+ }
2330
+ )
2331
+ ] })
2332
+ ]
2333
+ }
2334
+ );
2335
+ }
2336
+ function GraphPanel({
2337
+ title,
2338
+ description,
2339
+ actions,
2340
+ toolbar,
2341
+ children,
2342
+ className = "",
2343
+ contentClassName = "",
2344
+ height = GRAPH_DEFAULT_HEIGHT,
2345
+ loading,
2346
+ error,
2347
+ empty,
2348
+ emptyMessage,
2349
+ emptyDescription,
2350
+ showToolbar = false,
2351
+ showRefresh = true,
2352
+ showLastUpdated = true,
2353
+ onRetry
2354
+ }) {
2355
+ const graph = useGraphContext();
2356
+ const resolvedLoading = loading ?? graph.loading;
2357
+ const resolvedError = error ?? graph.error;
2358
+ const resolvedEmpty = empty ?? graph.data.length === 0;
2359
+ function renderContent() {
2360
+ if (resolvedLoading) {
2361
+ return /* @__PURE__ */ jsxRuntime.jsx(GraphLoadingState, { height });
2362
+ }
2363
+ if (resolvedError) {
2364
+ return /* @__PURE__ */ jsxRuntime.jsx(
2365
+ GraphErrorState,
2366
+ {
2367
+ height,
2368
+ error: resolvedError,
2369
+ onRetry: onRetry ?? graph.refresh
2370
+ }
2371
+ );
2372
+ }
2373
+ if (resolvedEmpty) {
2374
+ return /* @__PURE__ */ jsxRuntime.jsx(
2375
+ GraphEmptyState,
2376
+ {
2377
+ height,
2378
+ message: emptyMessage,
2379
+ description: emptyDescription
2380
+ }
2381
+ );
2382
+ }
2383
+ return children;
2384
+ }
2385
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2386
+ "section",
2387
+ {
2388
+ className: `eui-graph eui-graph-panel overflow-hidden rounded-xl border border-[#2a2d35] bg-[#111217] ${className}`,
2389
+ children: [
2390
+ /* @__PURE__ */ jsxRuntime.jsx(GraphHeader, { title, description, actions }),
2391
+ showToolbar && /* @__PURE__ */ jsxRuntime.jsx(
2392
+ GraphToolbar,
2393
+ {
2394
+ showRefresh,
2395
+ showLastUpdated,
2396
+ children: toolbar
2397
+ }
2398
+ ),
2399
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: `p-4 ${contentClassName}`, children: renderContent() })
2400
+ ]
2401
+ }
2402
+ );
2403
+ }
2404
+ function createLabelFromKey2(key) {
2405
+ return key.replace(/[_-]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (character) => character.toUpperCase());
2406
+ }
2407
+ function GraphLegend({
2408
+ items,
2409
+ series,
2410
+ data = [],
2411
+ className = "",
2412
+ showValues = true,
2413
+ valueSource = "latest",
2414
+ onItemClick
2415
+ }) {
2416
+ const legendItems = React3.useMemo(() => {
2417
+ if (items?.length) {
2418
+ return items;
2419
+ }
2420
+ if (!series?.length) {
2421
+ return [];
2422
+ }
2423
+ const latestPoint = data[data.length - 1];
2424
+ return series.map((item, index) => ({
2425
+ key: item.key,
2426
+ label: item.label ?? createLabelFromKey2(item.key),
2427
+ color: resolveGraphColor(item.color, { index }),
2428
+ value: valueSource === "latest" ? latestPoint?.[item.key] : void 0,
2429
+ unit: item.unit,
2430
+ format: item.format,
2431
+ prefix: item.prefix,
2432
+ suffix: item.suffix,
2433
+ active: item.visible ?? true
2434
+ }));
2435
+ }, [data, items, series, valueSource]);
2436
+ if (!legendItems.length) {
2437
+ return null;
2438
+ }
2439
+ return /* @__PURE__ */ jsxRuntime.jsx(
2440
+ "div",
2441
+ {
2442
+ className: `eui-graph flex flex-wrap items-center gap-x-4 gap-y-2 text-xs ${className}`,
2443
+ children: legendItems.map((item, index) => {
2444
+ const color = resolveGraphColor(item.color, { index });
2445
+ const active = item.active ?? true;
2446
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2447
+ "button",
2448
+ {
2449
+ type: "button",
2450
+ onClick: () => onItemClick?.(item),
2451
+ disabled: !onItemClick,
2452
+ className: `inline-flex items-center gap-2 rounded-md transition-opacity ${active ? "opacity-100" : "opacity-40"} ${onItemClick ? "cursor-pointer hover:opacity-80" : "cursor-default"}`,
2453
+ children: [
2454
+ /* @__PURE__ */ jsxRuntime.jsx(
2455
+ "span",
2456
+ {
2457
+ className: "h-2.5 w-2.5 rounded-full",
2458
+ style: { backgroundColor: color }
2459
+ }
2460
+ ),
2461
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-400", children: item.label ?? createLabelFromKey2(item.key) }),
2462
+ showValues && item.value !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-gray-200", children: formatGraphValue(item.value, {
2463
+ format: item.format ?? "number",
2464
+ prefix: item.prefix,
2465
+ suffix: item.suffix ?? item.unit
2466
+ }) })
2467
+ ]
2468
+ },
2469
+ item.key
2470
+ );
2471
+ })
2472
+ }
2473
+ );
2474
+ }
2475
+ function GraphTooltip({
2476
+ active,
2477
+ label,
2478
+ payload,
2479
+ className = "",
2480
+ labelFormatter,
2481
+ valueFormatter,
2482
+ seriesFormatters = {}
2483
+ }) {
2484
+ if (!active || !payload?.length) {
2485
+ return null;
2486
+ }
2487
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2488
+ "div",
2489
+ {
2490
+ className: `eui-graph rounded-xl border border-[#2a2d35] bg-[#181b21] px-3 py-2 shadow-xl ${className}`,
2491
+ children: [
2492
+ label !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2 text-xs font-semibold text-gray-100", children: labelFormatter ? labelFormatter(label) : label }),
2493
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-1.5", children: payload.map((item, index) => {
2494
+ const dataKey = item.dataKey ?? item.name ?? String(index);
2495
+ const formatterOptions = seriesFormatters[dataKey];
2496
+ const formattedValue = valueFormatter ? valueFormatter(item.value, item.name, item) : formatGraphValue(item.value, {
2497
+ format: formatterOptions?.format ?? "number",
2498
+ prefix: formatterOptions?.prefix,
2499
+ suffix: formatterOptions?.suffix ?? formatterOptions?.unit
2500
+ });
2501
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2502
+ "div",
2503
+ {
2504
+ className: "flex min-w-[140px] items-center justify-between gap-4 text-xs",
2505
+ children: [
2506
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
2507
+ /* @__PURE__ */ jsxRuntime.jsx(
2508
+ "span",
2509
+ {
2510
+ className: "h-2 w-2 rounded-full",
2511
+ style: { backgroundColor: item.color }
2512
+ }
2513
+ ),
2514
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-gray-400", children: item.name ?? dataKey })
2515
+ ] }),
2516
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-gray-100", children: formattedValue })
2517
+ ]
2518
+ },
2519
+ `${dataKey}-${index}`
2520
+ );
2521
+ }) })
2522
+ ]
2523
+ }
2524
+ );
2525
+ }
2526
+ function GraphContainer({
2527
+ children,
2528
+ height = GRAPH_DEFAULT_HEIGHT,
2529
+ className = "",
2530
+ contentClassName = ""
2531
+ }) {
2532
+ return /* @__PURE__ */ jsxRuntime.jsx(
2533
+ "div",
2534
+ {
2535
+ className: `eui-graph relative w-full min-w-0 overflow-hidden ${className}`,
2536
+ style: { height },
2537
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-full w-full ${contentClassName}`, children })
2538
+ }
2539
+ );
2540
+ }
2541
+ function LineGraph({
2542
+ data,
2543
+ xKey = "time",
2544
+ series,
2545
+ height = GRAPH_DEFAULT_HEIGHT,
2546
+ loading,
2547
+ error,
2548
+ className = "",
2549
+ showGrid = true,
2550
+ showTooltip = true,
2551
+ showLegend = true,
2552
+ animated = true
2553
+ }) {
2554
+ const context = useGraphContext();
2555
+ const theme = useGraphTheme();
2556
+ const graphData = data ?? context.data;
2557
+ const graphLoading = loading ?? context.loading;
2558
+ const graphError = error ?? context.error;
2559
+ const resolvedSeries = useGraphSeries({
2560
+ data: graphData,
2561
+ series,
2562
+ xKey: String(xKey)
2563
+ }).filter((item) => item.visible);
2564
+ if (graphLoading) {
2565
+ return /* @__PURE__ */ jsxRuntime.jsx(GraphLoadingState, { height, className });
2566
+ }
2567
+ if (graphError) {
2568
+ return /* @__PURE__ */ jsxRuntime.jsx(
2569
+ GraphErrorState,
2570
+ {
2571
+ error: graphError,
2572
+ height,
2573
+ className
2574
+ }
2575
+ );
2576
+ }
2577
+ if (!graphData.length || !resolvedSeries.length) {
2578
+ return /* @__PURE__ */ jsxRuntime.jsx(GraphEmptyState, { height, className });
2579
+ }
2580
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `eui-graph flex w-full flex-col gap-3 ${className}`, children: [
2581
+ /* @__PURE__ */ jsxRuntime.jsx(GraphContainer, { height, children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.LineChart, { data: graphData, margin: GRAPH_DEFAULT_MARGIN, children: [
2582
+ showGrid && /* @__PURE__ */ jsxRuntime.jsx(
2583
+ recharts.CartesianGrid,
2584
+ {
2585
+ stroke: theme.chart.grid,
2586
+ strokeDasharray: "3 3",
2587
+ vertical: false
2588
+ }
2589
+ ),
2590
+ /* @__PURE__ */ jsxRuntime.jsx(
2591
+ recharts.XAxis,
2592
+ {
2593
+ dataKey: String(xKey),
2594
+ stroke: theme.chart.axis,
2595
+ tick: { fill: theme.chart.axis, fontSize: 12 },
2596
+ tickLine: false,
2597
+ axisLine: false
2598
+ }
2599
+ ),
2600
+ /* @__PURE__ */ jsxRuntime.jsx(
2601
+ recharts.YAxis,
2602
+ {
2603
+ stroke: theme.chart.axis,
2604
+ tick: { fill: theme.chart.axis, fontSize: 12 },
2605
+ tickLine: false,
2606
+ axisLine: false,
2607
+ tickFormatter: (value) => formatGraphValue(value, {
2608
+ format: "compact"
2609
+ })
2610
+ }
2611
+ ),
2612
+ showTooltip && /* @__PURE__ */ jsxRuntime.jsx(
2613
+ recharts.Tooltip,
2614
+ {
2615
+ content: /* @__PURE__ */ jsxRuntime.jsx(
2616
+ GraphTooltip,
2617
+ {
2618
+ seriesFormatters: Object.fromEntries(
2619
+ resolvedSeries.map((item) => [
2620
+ item.key,
2621
+ {
2622
+ format: item.format,
2623
+ prefix: item.prefix,
2624
+ suffix: item.suffix,
2625
+ unit: item.unit
2626
+ }
2627
+ ])
2628
+ )
2629
+ }
2630
+ ),
2631
+ cursor: { stroke: theme.chart.cursor }
2632
+ }
2633
+ ),
2634
+ resolvedSeries.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
2635
+ recharts.Line,
2636
+ {
2637
+ type: "monotone",
2638
+ dataKey: item.key,
2639
+ name: item.label,
2640
+ stroke: item.color,
2641
+ strokeWidth: item.strokeWidth,
2642
+ dot: false,
2643
+ activeDot: { r: item.radius },
2644
+ isAnimationActive: animated,
2645
+ animationDuration: GRAPH_DEFAULT_ANIMATION_DURATION,
2646
+ yAxisId: item.yAxisId
2647
+ },
2648
+ item.key
2649
+ ))
2650
+ ] }) }) }),
2651
+ showLegend && /* @__PURE__ */ jsxRuntime.jsx(
2652
+ GraphLegend,
2653
+ {
2654
+ series: resolvedSeries,
2655
+ data: graphData,
2656
+ showValues: true,
2657
+ valueSource: "latest"
2658
+ }
2659
+ )
2660
+ ] });
2661
+ }
2662
+ function AreaGraph({
2663
+ data,
2664
+ xKey = "time",
2665
+ series,
2666
+ height = GRAPH_DEFAULT_HEIGHT,
2667
+ loading,
2668
+ error,
2669
+ className = "",
2670
+ showGrid = true,
2671
+ showTooltip = true,
2672
+ showLegend = true,
2673
+ animated = true
2674
+ }) {
2675
+ const context = useGraphContext();
2676
+ const theme = useGraphTheme();
2677
+ const graphData = data ?? context.data;
2678
+ const graphLoading = loading ?? context.loading;
2679
+ const graphError = error ?? context.error;
2680
+ const resolvedSeries = useGraphSeries({
2681
+ data: graphData,
2682
+ series,
2683
+ xKey: String(xKey)
2684
+ }).filter((item) => item.visible);
2685
+ if (graphLoading) {
2686
+ return /* @__PURE__ */ jsxRuntime.jsx(GraphLoadingState, { height, className });
2687
+ }
2688
+ if (graphError) {
2689
+ return /* @__PURE__ */ jsxRuntime.jsx(
2690
+ GraphErrorState,
2691
+ {
2692
+ error: graphError,
2693
+ height,
2694
+ className
2695
+ }
2696
+ );
2697
+ }
2698
+ if (!graphData.length || !resolvedSeries.length) {
2699
+ return /* @__PURE__ */ jsxRuntime.jsx(GraphEmptyState, { height, className });
2700
+ }
2701
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `eui-graph flex w-full flex-col gap-3 ${className}`, children: [
2702
+ /* @__PURE__ */ jsxRuntime.jsx(GraphContainer, { height, children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.AreaChart, { data: graphData, margin: GRAPH_DEFAULT_MARGIN, children: [
2703
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: resolvedSeries.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
2704
+ "linearGradient",
2705
+ {
2706
+ id: `eui-area-gradient-${item.key}`,
2707
+ x1: "0",
2708
+ y1: "0",
2709
+ x2: "0",
2710
+ y2: "1",
2711
+ children: [
2712
+ /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "5%", stopColor: item.color, stopOpacity: 0.35 }),
2713
+ /* @__PURE__ */ jsxRuntime.jsx(
2714
+ "stop",
2715
+ {
2716
+ offset: "95%",
2717
+ stopColor: item.color,
2718
+ stopOpacity: 0.02
2719
+ }
2720
+ )
2721
+ ]
2722
+ },
2723
+ item.key
2724
+ )) }),
2725
+ showGrid && /* @__PURE__ */ jsxRuntime.jsx(
2726
+ recharts.CartesianGrid,
2727
+ {
2728
+ stroke: theme.chart.grid,
2729
+ strokeDasharray: "3 3",
2730
+ vertical: false
2731
+ }
2732
+ ),
2733
+ /* @__PURE__ */ jsxRuntime.jsx(
2734
+ recharts.XAxis,
2735
+ {
2736
+ dataKey: String(xKey),
2737
+ stroke: theme.chart.axis,
2738
+ tick: { fill: theme.chart.axis, fontSize: 12 },
2739
+ tickLine: false,
2740
+ axisLine: false
2741
+ }
2742
+ ),
2743
+ /* @__PURE__ */ jsxRuntime.jsx(
2744
+ recharts.YAxis,
2745
+ {
2746
+ stroke: theme.chart.axis,
2747
+ tick: { fill: theme.chart.axis, fontSize: 12 },
2748
+ tickLine: false,
2749
+ axisLine: false,
2750
+ tickFormatter: (value) => formatGraphValue(value, {
2751
+ format: "compact"
2752
+ })
2753
+ }
2754
+ ),
2755
+ showTooltip && /* @__PURE__ */ jsxRuntime.jsx(
2756
+ recharts.Tooltip,
2757
+ {
2758
+ content: /* @__PURE__ */ jsxRuntime.jsx(
2759
+ GraphTooltip,
2760
+ {
2761
+ seriesFormatters: Object.fromEntries(
2762
+ resolvedSeries.map((item) => [
2763
+ item.key,
2764
+ {
2765
+ format: item.format,
2766
+ prefix: item.prefix,
2767
+ suffix: item.suffix,
2768
+ unit: item.unit
2769
+ }
2770
+ ])
2771
+ )
2772
+ }
2773
+ ),
2774
+ cursor: { stroke: theme.chart.cursor }
2775
+ }
2776
+ ),
2777
+ resolvedSeries.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
2778
+ recharts.Area,
2779
+ {
2780
+ type: "monotone",
2781
+ dataKey: item.key,
2782
+ name: item.label,
2783
+ stroke: item.color,
2784
+ strokeWidth: item.strokeWidth,
2785
+ fill: `url(#eui-area-gradient-${item.key})`,
2786
+ isAnimationActive: animated,
2787
+ animationDuration: GRAPH_DEFAULT_ANIMATION_DURATION,
2788
+ yAxisId: item.yAxisId
2789
+ },
2790
+ item.key
2791
+ ))
2792
+ ] }) }) }),
2793
+ showLegend && /* @__PURE__ */ jsxRuntime.jsx(
2794
+ GraphLegend,
2795
+ {
2796
+ series: resolvedSeries,
2797
+ data: graphData,
2798
+ showValues: true,
2799
+ valueSource: "latest"
2800
+ }
2801
+ )
2802
+ ] });
2803
+ }
2804
+ function BarGraph({
2805
+ data,
2806
+ xKey = "name",
2807
+ series,
2808
+ height = GRAPH_DEFAULT_HEIGHT,
2809
+ loading,
2810
+ error,
2811
+ className = "",
2812
+ showGrid = true,
2813
+ showTooltip = true,
2814
+ showLegend = true,
2815
+ animated = true,
2816
+ layout = "horizontal"
2817
+ }) {
2818
+ const context = useGraphContext();
2819
+ const theme = useGraphTheme();
2820
+ const graphData = data ?? context.data;
2821
+ const graphLoading = loading ?? context.loading;
2822
+ const graphError = error ?? context.error;
2823
+ const resolvedSeries = useGraphSeries({
2824
+ data: graphData,
2825
+ series,
2826
+ xKey: String(xKey)
2827
+ }).filter((item) => item.visible);
2828
+ if (graphLoading) {
2829
+ return /* @__PURE__ */ jsxRuntime.jsx(GraphLoadingState, { height, className });
2830
+ }
2831
+ if (graphError) {
2832
+ return /* @__PURE__ */ jsxRuntime.jsx(
2833
+ GraphErrorState,
2834
+ {
2835
+ error: graphError,
2836
+ height,
2837
+ className
2838
+ }
2839
+ );
2840
+ }
2841
+ if (!graphData.length || !resolvedSeries.length) {
2842
+ return /* @__PURE__ */ jsxRuntime.jsx(GraphEmptyState, { height, className });
2843
+ }
2844
+ const isVertical = layout === "vertical";
2845
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `eui-graph flex w-full flex-col gap-3 ${className}`, children: [
2846
+ /* @__PURE__ */ jsxRuntime.jsx(GraphContainer, { height, children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(
2847
+ recharts.BarChart,
2848
+ {
2849
+ data: graphData,
2850
+ margin: GRAPH_DEFAULT_MARGIN,
2851
+ layout: isVertical ? "vertical" : "horizontal",
2852
+ children: [
2853
+ showGrid && /* @__PURE__ */ jsxRuntime.jsx(
2854
+ recharts.CartesianGrid,
2855
+ {
2856
+ stroke: theme.chart.grid,
2857
+ strokeDasharray: "3 3",
2858
+ horizontal: !isVertical,
2859
+ vertical: isVertical
2860
+ }
2861
+ ),
2862
+ isVertical ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2863
+ /* @__PURE__ */ jsxRuntime.jsx(
2864
+ recharts.XAxis,
2865
+ {
2866
+ type: "number",
2867
+ stroke: theme.chart.axis,
2868
+ tick: { fill: theme.chart.axis, fontSize: 12 },
2869
+ tickLine: false,
2870
+ axisLine: false,
2871
+ tickFormatter: (value) => formatGraphValue(value, {
2872
+ format: "compact"
2873
+ })
2874
+ }
2875
+ ),
2876
+ /* @__PURE__ */ jsxRuntime.jsx(
2877
+ recharts.YAxis,
2878
+ {
2879
+ type: "category",
2880
+ dataKey: String(xKey),
2881
+ stroke: theme.chart.axis,
2882
+ tick: { fill: theme.chart.axis, fontSize: 12 },
2883
+ tickLine: false,
2884
+ axisLine: false,
2885
+ width: 110
2886
+ }
2887
+ )
2888
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2889
+ /* @__PURE__ */ jsxRuntime.jsx(
2890
+ recharts.XAxis,
2891
+ {
2892
+ dataKey: String(xKey),
2893
+ stroke: theme.chart.axis,
2894
+ tick: { fill: theme.chart.axis, fontSize: 12 },
2895
+ tickLine: false,
2896
+ axisLine: false
2897
+ }
2898
+ ),
2899
+ /* @__PURE__ */ jsxRuntime.jsx(
2900
+ recharts.YAxis,
2901
+ {
2902
+ stroke: theme.chart.axis,
2903
+ tick: { fill: theme.chart.axis, fontSize: 12 },
2904
+ tickLine: false,
2905
+ axisLine: false,
2906
+ tickFormatter: (value) => formatGraphValue(value, {
2907
+ format: "compact"
2908
+ })
2909
+ }
2910
+ )
2911
+ ] }),
2912
+ showTooltip && /* @__PURE__ */ jsxRuntime.jsx(
2913
+ recharts.Tooltip,
2914
+ {
2915
+ content: /* @__PURE__ */ jsxRuntime.jsx(
2916
+ GraphTooltip,
2917
+ {
2918
+ seriesFormatters: Object.fromEntries(
2919
+ resolvedSeries.map((item) => [
2920
+ item.key,
2921
+ {
2922
+ format: item.format,
2923
+ prefix: item.prefix,
2924
+ suffix: item.suffix,
2925
+ unit: item.unit
2926
+ }
2927
+ ])
2928
+ )
2929
+ }
2930
+ ),
2931
+ cursor: { fill: theme.chart.cursor }
2932
+ }
2933
+ ),
2934
+ resolvedSeries.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
2935
+ recharts.Bar,
2936
+ {
2937
+ dataKey: item.key,
2938
+ name: item.label,
2939
+ fill: item.color,
2940
+ radius: GRAPH_DEFAULT_BAR_RADIUS,
2941
+ isAnimationActive: animated,
2942
+ animationDuration: GRAPH_DEFAULT_ANIMATION_DURATION,
2943
+ yAxisId: isVertical ? void 0 : item.yAxisId
2944
+ },
2945
+ item.key
2946
+ ))
2947
+ ]
2948
+ }
2949
+ ) }) }),
2950
+ showLegend && /* @__PURE__ */ jsxRuntime.jsx(
2951
+ GraphLegend,
2952
+ {
2953
+ series: resolvedSeries,
2954
+ data: graphData,
2955
+ showValues: true,
2956
+ valueSource: "latest"
2957
+ }
2958
+ )
2959
+ ] });
2960
+ }
2961
+ function PieGraph({
2962
+ data,
2963
+ nameKey = "name",
2964
+ valueKey = "value",
2965
+ height = GRAPH_DEFAULT_HEIGHT,
2966
+ loading,
2967
+ error,
2968
+ className = "",
2969
+ showTooltip = true,
2970
+ showLegend = true,
2971
+ animated = true,
2972
+ innerRadius = "45%",
2973
+ outerRadius = "75%",
2974
+ valueFormat = "number",
2975
+ unit
2976
+ }) {
2977
+ const context = useGraphContext();
2978
+ const theme = useGraphTheme();
2979
+ const graphData = data ?? context.data;
2980
+ const graphLoading = loading ?? context.loading;
2981
+ const graphError = error ?? context.error;
2982
+ if (graphLoading) {
2983
+ return /* @__PURE__ */ jsxRuntime.jsx(GraphLoadingState, { height, className });
2984
+ }
2985
+ if (graphError) {
2986
+ return /* @__PURE__ */ jsxRuntime.jsx(
2987
+ GraphErrorState,
2988
+ {
2989
+ error: graphError,
2990
+ height,
2991
+ className
2992
+ }
2993
+ );
2994
+ }
2995
+ if (!graphData.length) {
2996
+ return /* @__PURE__ */ jsxRuntime.jsx(GraphEmptyState, { height, className });
2997
+ }
2998
+ const legendItems = graphData.map((item, index) => {
2999
+ const key = String(item[String(nameKey)] ?? index);
3000
+ return {
3001
+ key,
3002
+ label: key,
3003
+ value: item[String(valueKey)],
3004
+ color: resolveGraphColor(void 0, {
3005
+ index,
3006
+ palette: theme.colors
3007
+ }),
3008
+ format: valueFormat,
3009
+ unit,
3010
+ active: true
3011
+ };
3012
+ });
3013
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `eui-graph flex w-full flex-col gap-3 ${className}`, children: [
3014
+ /* @__PURE__ */ jsxRuntime.jsx(GraphContainer, { height, children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.PieChart, { children: [
3015
+ /* @__PURE__ */ jsxRuntime.jsx(
3016
+ recharts.Pie,
3017
+ {
3018
+ data: graphData,
3019
+ dataKey: String(valueKey),
3020
+ nameKey: String(nameKey),
3021
+ innerRadius,
3022
+ outerRadius,
3023
+ paddingAngle: 2,
3024
+ isAnimationActive: animated,
3025
+ animationDuration: GRAPH_DEFAULT_ANIMATION_DURATION,
3026
+ children: graphData.map((_item, index) => /* @__PURE__ */ jsxRuntime.jsx(
3027
+ recharts.Cell,
3028
+ {
3029
+ fill: resolveGraphColor(void 0, {
3030
+ index,
3031
+ palette: theme.colors
3032
+ })
3033
+ },
3034
+ `cell-${index}`
3035
+ ))
3036
+ }
3037
+ ),
3038
+ showTooltip && /* @__PURE__ */ jsxRuntime.jsx(
3039
+ recharts.Tooltip,
3040
+ {
3041
+ content: /* @__PURE__ */ jsxRuntime.jsx(
3042
+ GraphTooltip,
3043
+ {
3044
+ seriesFormatters: {
3045
+ [String(valueKey)]: {
3046
+ format: valueFormat,
3047
+ suffix: unit
3048
+ }
3049
+ }
3050
+ }
3051
+ )
3052
+ }
3053
+ )
3054
+ ] }) }) }),
3055
+ showLegend && /* @__PURE__ */ jsxRuntime.jsx(GraphLegend, { items: legendItems, showValues: true, valueSource: "latest" })
3056
+ ] });
3057
+ }
3058
+ function ScatterGraph({
3059
+ data,
3060
+ xKey = "x",
3061
+ series,
3062
+ height = GRAPH_DEFAULT_HEIGHT,
3063
+ loading,
3064
+ error,
3065
+ className = "",
3066
+ showGrid = true,
3067
+ showTooltip = true,
3068
+ showLegend = true,
3069
+ animated = true
3070
+ }) {
3071
+ const context = useGraphContext();
3072
+ const theme = useGraphTheme();
3073
+ const graphData = data ?? context.data;
3074
+ const graphLoading = loading ?? context.loading;
3075
+ const graphError = error ?? context.error;
3076
+ const resolvedSeries = useGraphSeries({
3077
+ data: graphData,
3078
+ series,
3079
+ xKey: String(xKey)
3080
+ }).filter((item) => item.visible);
3081
+ if (graphLoading) {
3082
+ return /* @__PURE__ */ jsxRuntime.jsx(GraphLoadingState, { height, className });
3083
+ }
3084
+ if (graphError) {
3085
+ return /* @__PURE__ */ jsxRuntime.jsx(
3086
+ GraphErrorState,
3087
+ {
3088
+ error: graphError,
3089
+ height,
3090
+ className
3091
+ }
3092
+ );
3093
+ }
3094
+ if (!graphData.length || !resolvedSeries.length) {
3095
+ return /* @__PURE__ */ jsxRuntime.jsx(GraphEmptyState, { height, className });
3096
+ }
3097
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `eui-graph flex w-full flex-col gap-3 ${className}`, children: [
3098
+ /* @__PURE__ */ jsxRuntime.jsx(GraphContainer, { height, children: /* @__PURE__ */ jsxRuntime.jsx(recharts.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(recharts.ScatterChart, { margin: GRAPH_DEFAULT_MARGIN, children: [
3099
+ showGrid && /* @__PURE__ */ jsxRuntime.jsx(recharts.CartesianGrid, { stroke: theme.chart.grid, strokeDasharray: "3 3" }),
3100
+ /* @__PURE__ */ jsxRuntime.jsx(
3101
+ recharts.XAxis,
3102
+ {
3103
+ type: "number",
3104
+ dataKey: String(xKey),
3105
+ name: String(xKey),
3106
+ stroke: theme.chart.axis,
3107
+ tick: { fill: theme.chart.axis, fontSize: 12 },
3108
+ tickLine: false,
3109
+ axisLine: false,
3110
+ tickFormatter: (value) => formatGraphValue(value, {
3111
+ format: "compact"
3112
+ })
3113
+ }
3114
+ ),
3115
+ /* @__PURE__ */ jsxRuntime.jsx(
3116
+ recharts.YAxis,
3117
+ {
3118
+ type: "number",
3119
+ stroke: theme.chart.axis,
3120
+ tick: { fill: theme.chart.axis, fontSize: 12 },
3121
+ tickLine: false,
3122
+ axisLine: false,
3123
+ tickFormatter: (value) => formatGraphValue(value, {
3124
+ format: "compact"
3125
+ })
3126
+ }
3127
+ ),
3128
+ showTooltip && /* @__PURE__ */ jsxRuntime.jsx(
3129
+ recharts.Tooltip,
3130
+ {
3131
+ content: /* @__PURE__ */ jsxRuntime.jsx(
3132
+ GraphTooltip,
3133
+ {
3134
+ seriesFormatters: Object.fromEntries(
3135
+ resolvedSeries.map((item) => [
3136
+ item.key,
3137
+ {
3138
+ format: item.format,
3139
+ prefix: item.prefix,
3140
+ suffix: item.suffix,
3141
+ unit: item.unit
3142
+ }
3143
+ ])
3144
+ )
3145
+ }
3146
+ ),
3147
+ cursor: { stroke: theme.chart.cursor, strokeDasharray: "3 3" }
3148
+ }
3149
+ ),
3150
+ resolvedSeries.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
3151
+ recharts.Scatter,
3152
+ {
3153
+ data: graphData,
3154
+ dataKey: item.key,
3155
+ name: item.label,
3156
+ fill: item.color,
3157
+ isAnimationActive: animated,
3158
+ animationDuration: GRAPH_DEFAULT_ANIMATION_DURATION
3159
+ },
3160
+ item.key
3161
+ ))
3162
+ ] }) }) }),
3163
+ showLegend && /* @__PURE__ */ jsxRuntime.jsx(
3164
+ GraphLegend,
3165
+ {
3166
+ series: resolvedSeries,
3167
+ data: graphData,
3168
+ showValues: true,
3169
+ valueSource: "latest"
3170
+ }
3171
+ )
3172
+ ] });
3173
+ }
3174
+ function GaugeGraph({
3175
+ data,
3176
+ valueKey = "value",
3177
+ label,
3178
+ value,
3179
+ min = 0,
3180
+ max = 100,
3181
+ height = GRAPH_DEFAULT_HEIGHT,
3182
+ color,
3183
+ unit,
3184
+ format = "number",
3185
+ loading,
3186
+ error,
3187
+ className = ""
3188
+ }) {
3189
+ const context = useGraphContext();
3190
+ const theme = useGraphTheme();
3191
+ const graphData = data ?? context.data;
3192
+ const graphLoading = loading ?? context.loading;
3193
+ const graphError = error ?? context.error;
3194
+ const resolvedValue = React3.useMemo(() => {
3195
+ if (typeof value === "number") {
3196
+ return value;
3197
+ }
3198
+ const latestPoint = graphData[graphData.length - 1];
3199
+ const latestValue = latestPoint?.[String(valueKey)];
3200
+ return typeof latestValue === "number" ? latestValue : void 0;
3201
+ }, [graphData, value, valueKey]);
3202
+ if (graphLoading) {
3203
+ return /* @__PURE__ */ jsxRuntime.jsx(GraphLoadingState, { height, className });
3204
+ }
3205
+ if (graphError) {
3206
+ return /* @__PURE__ */ jsxRuntime.jsx(
3207
+ GraphErrorState,
3208
+ {
3209
+ error: graphError,
3210
+ height,
3211
+ className
3212
+ }
3213
+ );
3214
+ }
3215
+ if (resolvedValue === void 0) {
3216
+ return /* @__PURE__ */ jsxRuntime.jsx(GraphEmptyState, { height, className });
3217
+ }
3218
+ const range = max - min;
3219
+ const percentage = range === 0 ? 0 : Math.min(100, Math.max(0, (resolvedValue - min) / range * 100));
3220
+ const radius = 72;
3221
+ const strokeWidth = 14;
3222
+ const circumference = Math.PI * radius;
3223
+ const offset = circumference - percentage / 100 * circumference;
3224
+ const resolvedColor = resolveGraphColor(color, {
3225
+ index: 0,
3226
+ palette: theme.colors
3227
+ });
3228
+ return /* @__PURE__ */ jsxRuntime.jsx(
3229
+ "div",
3230
+ {
3231
+ className: `eui-graph flex items-center justify-center ${className}`,
3232
+ style: { height },
3233
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-3", children: [
3234
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "220", height: "130", viewBox: "0 0 220 130", children: [
3235
+ /* @__PURE__ */ jsxRuntime.jsx(
3236
+ "path",
3237
+ {
3238
+ d: "M 38 104 A 72 72 0 0 1 182 104",
3239
+ fill: "none",
3240
+ stroke: theme.chart.grid,
3241
+ strokeWidth,
3242
+ strokeLinecap: "round"
3243
+ }
3244
+ ),
3245
+ /* @__PURE__ */ jsxRuntime.jsx(
3246
+ "path",
3247
+ {
3248
+ d: "M 38 104 A 72 72 0 0 1 182 104",
3249
+ fill: "none",
3250
+ stroke: resolvedColor,
3251
+ strokeWidth,
3252
+ strokeLinecap: "round",
3253
+ strokeDasharray: circumference,
3254
+ strokeDashoffset: offset
3255
+ }
3256
+ ),
3257
+ /* @__PURE__ */ jsxRuntime.jsx(
3258
+ "text",
3259
+ {
3260
+ x: "110",
3261
+ y: "92",
3262
+ textAnchor: "middle",
3263
+ fill: theme.tooltip.text,
3264
+ fontSize: "28",
3265
+ fontWeight: "700",
3266
+ children: formatGraphValue(resolvedValue, {
3267
+ format,
3268
+ suffix: unit,
3269
+ maximumFractionDigits: 2
3270
+ })
3271
+ }
3272
+ ),
3273
+ label && /* @__PURE__ */ jsxRuntime.jsx(
3274
+ "text",
3275
+ {
3276
+ x: "110",
3277
+ y: "118",
3278
+ textAnchor: "middle",
3279
+ fill: theme.tooltip.muted,
3280
+ fontSize: "12",
3281
+ children: label
3282
+ }
3283
+ )
3284
+ ] }),
3285
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full max-w-[180px] justify-between text-xs text-gray-500", children: [
3286
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatGraphValue(min, {
3287
+ format,
3288
+ suffix: unit
3289
+ }) }),
3290
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatGraphValue(max, {
3291
+ format,
3292
+ suffix: unit
3293
+ }) })
3294
+ ] })
3295
+ ] })
3296
+ }
3297
+ );
3298
+ }
3299
+ function StatGraph({
3300
+ data,
3301
+ valueKey = "value",
3302
+ label,
3303
+ value,
3304
+ previousValue,
3305
+ format = "number",
3306
+ prefix,
3307
+ suffix,
3308
+ unit,
3309
+ loading,
3310
+ error,
3311
+ className = "",
3312
+ showTrend = true
3313
+ }) {
3314
+ const context = useGraphContext();
3315
+ const graphData = data ?? context.data;
3316
+ const graphLoading = loading ?? context.loading;
3317
+ const graphError = error ?? context.error;
3318
+ const resolvedValue = React3.useMemo(() => {
3319
+ if (value !== void 0) {
3320
+ return value;
3321
+ }
3322
+ const latestPoint = graphData[graphData.length - 1];
3323
+ return latestPoint?.[String(valueKey)] ?? null;
3324
+ }, [graphData, value, valueKey]);
3325
+ const resolvedPreviousValue = React3.useMemo(() => {
3326
+ if (previousValue !== void 0) {
3327
+ return previousValue;
3328
+ }
3329
+ const previousPoint = graphData[graphData.length - 2];
3330
+ const previous = previousPoint?.[String(valueKey)];
3331
+ return typeof previous === "number" ? previous : void 0;
3332
+ }, [graphData, previousValue, valueKey]);
3333
+ const trend = React3.useMemo(() => {
3334
+ if (typeof resolvedValue !== "number" || typeof resolvedPreviousValue !== "number") {
3335
+ return null;
3336
+ }
3337
+ const difference = resolvedValue - resolvedPreviousValue;
3338
+ const percentage = resolvedPreviousValue === 0 ? 0 : difference / Math.abs(resolvedPreviousValue) * 100;
3339
+ return {
3340
+ difference,
3341
+ percentage,
3342
+ direction: difference > 0 ? "up" : difference < 0 ? "down" : "neutral"
3343
+ };
3344
+ }, [resolvedPreviousValue, resolvedValue]);
3345
+ if (graphLoading) {
3346
+ return /* @__PURE__ */ jsxRuntime.jsx(GraphLoadingState, { height: 120, className });
3347
+ }
3348
+ if (graphError) {
3349
+ return /* @__PURE__ */ jsxRuntime.jsx(GraphErrorState, { error: graphError, height: 120, className });
3350
+ }
3351
+ if (resolvedValue === null || resolvedValue === void 0) {
3352
+ return /* @__PURE__ */ jsxRuntime.jsx(GraphEmptyState, { height: 120, className });
3353
+ }
1312
3354
  return /* @__PURE__ */ jsxRuntime.jsxs(
1313
3355
  "div",
1314
3356
  {
1315
- ...rest,
1316
- className: cn("relative inline-block", className),
1317
- onMouseMove: (e) => {
1318
- setPos({ x: e.clientX, y: e.clientY });
1319
- setShowTooltip(true);
1320
- },
1321
- onMouseLeave: () => setShowTooltip(false),
3357
+ className: `eui-graph rounded-xl border border-[#2a2d35] bg-[#111217] p-5 ${className}`,
1322
3358
  children: [
1323
- /* @__PURE__ */ jsxRuntime.jsx(
1324
- ReactWorldFlags__default.default,
1325
- {
1326
- code: upperCode,
1327
- style: { width, height },
1328
- className
1329
- }
1330
- ),
1331
- showTooltip && /* @__PURE__ */ jsxRuntime.jsxs(
3359
+ label && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-gray-400", children: label }),
3360
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 text-3xl font-semibold tracking-tight text-gray-100", children: formatGraphValue(resolvedValue, {
3361
+ format,
3362
+ prefix,
3363
+ suffix: suffix ?? unit
3364
+ }) }),
3365
+ showTrend && trend && /* @__PURE__ */ jsxRuntime.jsxs(
1332
3366
  "div",
1333
3367
  {
1334
- className: "fixed z-50 bg-black text-white text-xs px-2 py-1 rounded shadow pointer-events-none",
1335
- style: {
1336
- top: pos.y + 12,
1337
- left: pos.x + 12
1338
- },
3368
+ className: `mt-3 text-sm ${trend.direction === "up" ? "text-emerald-400" : trend.direction === "down" ? "text-red-400" : "text-gray-500"}`,
1339
3369
  children: [
1340
- upperCode,
1341
- " \u2014 ",
1342
- country?.name || "Unknown"
3370
+ trend.direction === "up" ? "\u2191" : trend.direction === "down" ? "\u2193" : "\u2192",
3371
+ " ",
3372
+ formatGraphValue(Math.abs(trend.percentage), {
3373
+ format: "number",
3374
+ suffix: "%",
3375
+ maximumFractionDigits: 2
3376
+ })
1343
3377
  ]
1344
3378
  }
1345
3379
  )
1346
3380
  ]
1347
3381
  }
1348
3382
  );
1349
- };
3383
+ }
3384
+ function renderGraphChart(props) {
3385
+ const {
3386
+ type = "line",
3387
+ data,
3388
+ xKey,
3389
+ series,
3390
+ height,
3391
+ loading,
3392
+ error,
3393
+ chartClassName = "",
3394
+ showGrid = true,
3395
+ showTooltip = true,
3396
+ showLegend = true,
3397
+ animated = true,
3398
+ layout,
3399
+ nameKey,
3400
+ valueKey,
3401
+ innerRadius,
3402
+ outerRadius,
3403
+ valueFormat,
3404
+ value,
3405
+ previousValue,
3406
+ label,
3407
+ min,
3408
+ max,
3409
+ color,
3410
+ unit,
3411
+ format,
3412
+ prefix,
3413
+ suffix,
3414
+ showTrend
3415
+ } = props;
3416
+ switch (type) {
3417
+ case "area":
3418
+ return /* @__PURE__ */ jsxRuntime.jsx(
3419
+ AreaGraph,
3420
+ {
3421
+ data,
3422
+ xKey,
3423
+ series,
3424
+ height,
3425
+ loading,
3426
+ error,
3427
+ className: chartClassName,
3428
+ showGrid,
3429
+ showTooltip,
3430
+ showLegend,
3431
+ animated
3432
+ }
3433
+ );
3434
+ case "bar":
3435
+ return /* @__PURE__ */ jsxRuntime.jsx(
3436
+ BarGraph,
3437
+ {
3438
+ data,
3439
+ xKey,
3440
+ series,
3441
+ height,
3442
+ loading,
3443
+ error,
3444
+ className: chartClassName,
3445
+ showGrid,
3446
+ showTooltip,
3447
+ showLegend,
3448
+ animated,
3449
+ layout
3450
+ }
3451
+ );
3452
+ case "pie":
3453
+ return /* @__PURE__ */ jsxRuntime.jsx(
3454
+ PieGraph,
3455
+ {
3456
+ data,
3457
+ nameKey,
3458
+ valueKey,
3459
+ height,
3460
+ loading,
3461
+ error,
3462
+ className: chartClassName,
3463
+ showTooltip,
3464
+ showLegend,
3465
+ animated,
3466
+ innerRadius,
3467
+ outerRadius,
3468
+ valueFormat,
3469
+ unit
3470
+ }
3471
+ );
3472
+ case "scatter":
3473
+ return /* @__PURE__ */ jsxRuntime.jsx(
3474
+ ScatterGraph,
3475
+ {
3476
+ data,
3477
+ xKey,
3478
+ series,
3479
+ height,
3480
+ loading,
3481
+ error,
3482
+ className: chartClassName,
3483
+ showGrid,
3484
+ showTooltip,
3485
+ showLegend,
3486
+ animated
3487
+ }
3488
+ );
3489
+ case "gauge":
3490
+ return /* @__PURE__ */ jsxRuntime.jsx(
3491
+ GaugeGraph,
3492
+ {
3493
+ data,
3494
+ valueKey,
3495
+ value: typeof value === "number" ? value : void 0,
3496
+ label,
3497
+ min,
3498
+ max,
3499
+ height,
3500
+ color,
3501
+ unit,
3502
+ format,
3503
+ loading,
3504
+ error,
3505
+ className: chartClassName
3506
+ }
3507
+ );
3508
+ case "stat":
3509
+ return /* @__PURE__ */ jsxRuntime.jsx(
3510
+ StatGraph,
3511
+ {
3512
+ data,
3513
+ valueKey,
3514
+ value,
3515
+ previousValue,
3516
+ label,
3517
+ format,
3518
+ prefix,
3519
+ suffix,
3520
+ unit,
3521
+ loading,
3522
+ error,
3523
+ className: chartClassName,
3524
+ showTrend
3525
+ }
3526
+ );
3527
+ case "line":
3528
+ default:
3529
+ return /* @__PURE__ */ jsxRuntime.jsx(
3530
+ LineGraph,
3531
+ {
3532
+ data,
3533
+ xKey,
3534
+ series,
3535
+ height,
3536
+ loading,
3537
+ error,
3538
+ className: chartClassName,
3539
+ showGrid,
3540
+ showTooltip,
3541
+ showLegend,
3542
+ animated
3543
+ }
3544
+ );
3545
+ }
3546
+ }
3547
+ function GraphContent(props) {
3548
+ const {
3549
+ children,
3550
+ withPanel = true,
3551
+ title,
3552
+ description,
3553
+ actions,
3554
+ toolbar,
3555
+ className = "",
3556
+ contentClassName = "",
3557
+ height,
3558
+ loading,
3559
+ error,
3560
+ showToolbar = false,
3561
+ showRefresh = true,
3562
+ showLastUpdated = true,
3563
+ emptyMessage,
3564
+ emptyDescription,
3565
+ onRetry
3566
+ } = props;
3567
+ const chart = children ?? renderGraphChart(props);
3568
+ if (!withPanel) {
3569
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: chart });
3570
+ }
3571
+ return /* @__PURE__ */ jsxRuntime.jsx(
3572
+ GraphPanel,
3573
+ {
3574
+ title,
3575
+ description,
3576
+ actions,
3577
+ toolbar,
3578
+ className,
3579
+ contentClassName,
3580
+ height,
3581
+ loading,
3582
+ error,
3583
+ empty: children ? false : void 0,
3584
+ showToolbar,
3585
+ showRefresh,
3586
+ showLastUpdated,
3587
+ emptyMessage,
3588
+ emptyDescription,
3589
+ onRetry,
3590
+ children: chart
3591
+ }
3592
+ );
3593
+ }
3594
+ function Graph(props) {
3595
+ const {
3596
+ data,
3597
+ dataSource,
3598
+ autoLoad = true,
3599
+ maxDataPoints,
3600
+ theme,
3601
+ onDataChange,
3602
+ onError
3603
+ } = props;
3604
+ const shouldUseProvider = Boolean(data || dataSource);
3605
+ const content = /* @__PURE__ */ jsxRuntime.jsx(GraphContent, { ...props });
3606
+ if (!shouldUseProvider) {
3607
+ return content;
3608
+ }
3609
+ return /* @__PURE__ */ jsxRuntime.jsx(
3610
+ GraphProvider,
3611
+ {
3612
+ data,
3613
+ dataSource,
3614
+ autoLoad,
3615
+ maxDataPoints,
3616
+ theme,
3617
+ onDataChange,
3618
+ onError,
3619
+ children: content
3620
+ }
3621
+ );
3622
+ }
1350
3623
 
1351
- // src/components/data-display/graphs/layouts/registry.ts
1352
- var registry = /* @__PURE__ */ new Map();
1353
- var registerLayout = (type, executor) => {
1354
- registry.set(type, executor);
1355
- };
1356
- var getLayout = (type) => {
1357
- const layout = registry.get(type);
1358
- if (!layout) {
1359
- throw new Error(`Layout "${type}" not registered`);
3624
+ // src/components/data-display/graphs-v2/datasource/GraphDataSource.ts
3625
+ var BaseGraphDataSource = class {
3626
+ normalizeError(error) {
3627
+ if (error instanceof Error) {
3628
+ return error;
3629
+ }
3630
+ return new Error(String(error));
1360
3631
  }
1361
- return layout;
1362
- };
1363
- var createForceLayout = (nodes, edges, width, height) => {
1364
- const nodeMap = new Map(nodes.map((n) => [n.id, n]));
1365
- const d3Links = edges.filter((e) => {
1366
- const fromId = typeof e.from === "string" ? e.from : e.from.id;
1367
- const toId = typeof e.to === "string" ? e.to : e.to.id;
1368
- const valid = nodeMap.has(fromId) && nodeMap.has(toId);
1369
- if (!valid) {
1370
- console.warn("Invalid edge skipped:", e);
3632
+ ensureArray(data) {
3633
+ if (!data) {
3634
+ return [];
1371
3635
  }
1372
- return valid;
1373
- }).map((e) => ({
1374
- source: typeof e.from === "string" ? e.from : e.from.id,
1375
- target: typeof e.to === "string" ? e.to : e.to.id,
1376
- weight: e.weight
1377
- }));
1378
- return d3__namespace.forceSimulation(nodes).force(
1379
- "link",
1380
- d3__namespace.forceLink(d3Links).id((d) => d.id).distance(120).strength(0.7)
1381
- ).force("charge", d3__namespace.forceManyBody().strength(-280)).force("center", d3__namespace.forceCenter(width / 2, height / 2)).force("collision", d3__namespace.forceCollide().radius(35));
3636
+ return Array.isArray(data) ? data : [data];
3637
+ }
3638
+ safeExecute(executor) {
3639
+ try {
3640
+ return Promise.resolve(executor());
3641
+ } catch (error) {
3642
+ return Promise.reject(this.normalizeError(error));
3643
+ }
3644
+ }
1382
3645
  };
1383
3646
 
1384
- // src/components/data-display/graphs/layouts/gridLayout.ts
1385
- function createGridLayout(nodes, width, height) {
1386
- const cols = Math.ceil(Math.sqrt(nodes.length));
1387
- const spacingX = width / (cols + 1);
1388
- const spacingY = height / (cols + 1);
1389
- return nodes.map((node, i) => ({
1390
- ...node,
1391
- x: spacingX * (i % cols + 1),
1392
- y: spacingY * (Math.floor(i / cols) + 1)
1393
- }));
1394
- }
3647
+ // src/components/data-display/graphs-v2/datasource/StaticGraphDataSource.ts
3648
+ var StaticGraphDataSource = class extends BaseGraphDataSource {
3649
+ constructor(config = {}) {
3650
+ super();
3651
+ this.mode = GRAPH_DATA_MODES.STATIC;
3652
+ this.data = Array.isArray(config) ? config : config.data ?? [];
3653
+ }
3654
+ getInitialData() {
3655
+ return this.data;
3656
+ }
3657
+ refresh() {
3658
+ return this.data;
3659
+ }
3660
+ setData(data) {
3661
+ this.data = data;
3662
+ }
3663
+ appendData(data) {
3664
+ const nextData = this.ensureArray(data);
3665
+ this.data = [...this.data, ...nextData];
3666
+ }
3667
+ clearData() {
3668
+ this.data = [];
3669
+ }
3670
+ };
1395
3671
 
1396
- // src/components/data-display/graphs/layouts/treeLayout.ts
1397
- function createTreeLayout(nodes, edges, width, height) {
1398
- const levelMap = {};
1399
- const root = nodes[0];
1400
- if (!root) return nodes;
1401
- levelMap[root.id] = 0;
1402
- edges.forEach((edge) => {
1403
- const fromId = typeof edge.from === "string" ? edge.from : edge.from.id;
1404
- const toId = typeof edge.to === "string" ? edge.to : edge.to.id;
1405
- levelMap[toId] = (levelMap[fromId] ?? 0) + 1;
1406
- });
1407
- const maxLevel = Math.max(...Object.values(levelMap));
1408
- const levelGroups = {};
1409
- nodes.forEach((node) => {
1410
- const level = levelMap[node.id] ?? 0;
1411
- if (!levelGroups[level]) levelGroups[level] = [];
1412
- levelGroups[level].push(node);
1413
- });
1414
- return nodes.map((node) => {
1415
- const level = levelMap[node.id] ?? 0;
1416
- const siblings = levelGroups[level];
1417
- const index = siblings.indexOf(node);
1418
- return {
1419
- ...node,
1420
- x: (index + 1) * width / (siblings.length + 1),
1421
- y: (level + 1) * height / (maxLevel + 2)
1422
- };
1423
- });
1424
- }
1425
- var NODE_SIZE = 48;
1426
- var GraphNode = ({ node, renderCustom }) => {
1427
- if (node.x === void 0 || node.y === void 0) return null;
1428
- const x = node.x;
1429
- const y = node.y;
1430
- if (renderCustom) {
1431
- return /* @__PURE__ */ jsxRuntime.jsx(
1432
- "foreignObject",
1433
- {
1434
- x: x - NODE_SIZE / 2,
1435
- y: y - NODE_SIZE / 2,
1436
- width: NODE_SIZE,
1437
- height: NODE_SIZE,
1438
- style: { overflow: "visible" },
1439
- children: /* @__PURE__ */ jsxRuntime.jsx(
1440
- "div",
1441
- {
1442
- style: {
1443
- width: NODE_SIZE,
1444
- height: NODE_SIZE,
1445
- display: "flex",
1446
- alignItems: "center",
1447
- justifyContent: "center"
1448
- },
1449
- children: renderCustom(node)
1450
- }
1451
- )
1452
- }
1453
- );
3672
+ // src/components/data-display/graphs-v2/datasource/PollingGraphDataSource.ts
3673
+ var PollingGraphDataSource = class extends BaseGraphDataSource {
3674
+ constructor(config) {
3675
+ super();
3676
+ this.mode = GRAPH_DATA_MODES.POLLING;
3677
+ this.fetcher = config.fetcher;
3678
+ this.interval = config.interval ?? GRAPH_DEFAULT_POLLING_INTERVAL;
3679
+ this.immediate = config.immediate ?? true;
1454
3680
  }
1455
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${x}, ${y})`, children: [
1456
- /* @__PURE__ */ jsxRuntime.jsx("circle", { r: 16, fill: "#4f46e5" }),
1457
- node.label && /* @__PURE__ */ jsxRuntime.jsx(
1458
- "text",
1459
- {
1460
- y: 4,
1461
- textAnchor: "middle",
1462
- fontSize: "11",
1463
- fill: "white",
1464
- pointerEvents: "none",
1465
- children: node.label
3681
+ getInitialData() {
3682
+ return this.refresh();
3683
+ }
3684
+ refresh() {
3685
+ return this.safeExecute(async () => {
3686
+ const data = await this.fetcher();
3687
+ return this.ensureArray(data);
3688
+ });
3689
+ }
3690
+ subscribe(onData, onError) {
3691
+ let disposed = false;
3692
+ let fetching = false;
3693
+ let timer;
3694
+ const execute = async () => {
3695
+ if (disposed || fetching) {
3696
+ return;
1466
3697
  }
1467
- )
1468
- ] });
1469
- };
1470
- function resolveNode(ref, map) {
1471
- return typeof ref === "string" ? map.get(ref) : ref;
1472
- }
1473
- var GraphEdge = ({ edge, nodeMap }) => {
1474
- const source = resolveNode(edge.from, nodeMap);
1475
- const target = resolveNode(edge.to, nodeMap);
1476
- if (!source || !target) return null;
1477
- if (source.x == null || source.y == null) return null;
1478
- if (target.x == null || target.y == null) return null;
1479
- const labelX = (source.x + target.x) / 2;
1480
- const labelY = (source.y + target.y) / 2;
1481
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
1482
- /* @__PURE__ */ jsxRuntime.jsx(
1483
- "line",
1484
- {
1485
- x1: source.x,
1486
- y1: source.y,
1487
- x2: target.x,
1488
- y2: target.y,
1489
- stroke: "#64748b",
1490
- strokeWidth: 1.5
3698
+ try {
3699
+ fetching = true;
3700
+ const data = await this.refresh();
3701
+ if (!disposed) {
3702
+ onData(data);
3703
+ }
3704
+ } catch (error) {
3705
+ if (!disposed) {
3706
+ onError?.(this.normalizeError(error));
3707
+ }
3708
+ } finally {
3709
+ fetching = false;
1491
3710
  }
1492
- ),
1493
- edge.weight && /* @__PURE__ */ jsxRuntime.jsx(
1494
- "text",
1495
- {
1496
- x: labelX,
1497
- y: labelY - 4,
1498
- textAnchor: "middle",
1499
- fontSize: 10,
1500
- fill: "#e5e7eb",
1501
- children: edge.weight
3711
+ };
3712
+ if (this.immediate) {
3713
+ void execute();
3714
+ }
3715
+ timer = globalThis.setInterval(() => {
3716
+ void execute();
3717
+ }, this.interval);
3718
+ return () => {
3719
+ disposed = true;
3720
+ if (timer) {
3721
+ globalThis.clearInterval(timer);
1502
3722
  }
1503
- )
1504
- ] });
3723
+ };
3724
+ }
1505
3725
  };
1506
- var GraphRenderer = ({
1507
- data,
1508
- layout = "force",
1509
- nodeRenderer,
1510
- width = 1e3,
1511
- height = 700
1512
- }) => {
1513
- const [nodes, setNodes] = React4.useState([]);
1514
- const edges = data.edges;
1515
- const simulationRef = React4.useRef(null);
1516
- const [offset, setOffset] = React4.useState({ x: 0, y: 0 });
1517
- const isDragging = React4.useRef(false);
1518
- const lastPos = React4.useRef({ x: 0, y: 0 });
1519
- const nodeMap = React4.useMemo(() => {
1520
- return new Map(nodes.map((n) => [n.id, n]));
1521
- }, [nodes]);
1522
- React4.useEffect(() => {
1523
- simulationRef.current?.stop?.();
1524
- const positionedNodes = data.nodes.map((n) => ({
1525
- ...n,
1526
- x: width / 2,
1527
- y: height / 2
1528
- }));
1529
- const executor = getLayout(layout);
1530
- const instance = executor({
1531
- nodes: positionedNodes,
1532
- edges,
1533
- width,
1534
- height,
1535
- onTick: setNodes
3726
+
3727
+ // src/components/data-display/graphs-v2/datasource/RealtimeGraphDataSource.ts
3728
+ var RealtimeGraphDataSource = class extends BaseGraphDataSource {
3729
+ constructor(config) {
3730
+ super();
3731
+ this.mode = GRAPH_DATA_MODES.REALTIME;
3732
+ this.connect = config.connect;
3733
+ this.initialDataLoader = config.getInitialData;
3734
+ this.refreshHandler = config.refresh;
3735
+ }
3736
+ getInitialData() {
3737
+ if (!this.initialDataLoader) {
3738
+ return [];
3739
+ }
3740
+ return this.safeExecute(async () => {
3741
+ const data = await this.initialDataLoader?.();
3742
+ return this.ensureArray(data);
1536
3743
  });
1537
- simulationRef.current = instance;
1538
- return () => instance.stop?.();
1539
- }, [data, layout, width, height]);
1540
- const onMouseDown = (e) => {
1541
- isDragging.current = true;
1542
- lastPos.current = { x: e.clientX, y: e.clientY };
1543
- };
1544
- const onMouseMove = (e) => {
1545
- if (!isDragging.current) return;
1546
- const dx = e.clientX - lastPos.current.x;
1547
- const dy = e.clientY - lastPos.current.y;
1548
- setOffset((prev) => ({
1549
- x: prev.x + dx,
1550
- y: prev.y + dy
1551
- }));
1552
- lastPos.current = { x: e.clientX, y: e.clientY };
1553
- };
1554
- const stopDrag = () => isDragging.current = false;
1555
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative overflow-hidden border border-gray-800 rounded-lg", children: /* @__PURE__ */ jsxRuntime.jsx(
1556
- "svg",
1557
- {
1558
- width: "100%",
1559
- height,
1560
- viewBox: `0 0 ${width} ${height}`,
1561
- onMouseDown,
1562
- onMouseMove,
1563
- onMouseUp: stopDrag,
1564
- onMouseLeave: stopDrag,
1565
- style: {
1566
- cursor: isDragging.current ? "grabbing" : "grab"
1567
- },
1568
- children: /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(${offset.x}, ${offset.y})`, children: [
1569
- edges.map((edge, i) => /* @__PURE__ */ jsxRuntime.jsx(GraphEdge, { edge, nodeMap }, edge.id || i)),
1570
- nodes.map((node) => /* @__PURE__ */ jsxRuntime.jsx(GraphNode, { node, renderCustom: nodeRenderer }, node.id))
1571
- ] })
3744
+ }
3745
+ refresh() {
3746
+ if (!this.refreshHandler) {
3747
+ return this.getInitialData();
1572
3748
  }
1573
- ) });
1574
- };
1575
- var Graph = ({
1576
- data,
1577
- layout = "force",
1578
- nodeRenderer,
1579
- width = 800,
1580
- height = 500,
1581
- className,
1582
- ...rest
1583
- }) => {
1584
- return /* @__PURE__ */ jsxRuntime.jsx(
1585
- "div",
1586
- {
1587
- ...rest,
1588
- style: { width, height },
1589
- className: cn("relative bg-gray-900 rounded-lg", className),
1590
- children: /* @__PURE__ */ jsxRuntime.jsx(
1591
- GraphRenderer,
1592
- {
1593
- data,
1594
- layout,
1595
- nodeRenderer,
1596
- width,
1597
- height
3749
+ return this.safeExecute(async () => {
3750
+ const data = await this.refreshHandler?.();
3751
+ return this.ensureArray(data);
3752
+ });
3753
+ }
3754
+ subscribe(onData, onError) {
3755
+ try {
3756
+ return this.connect(
3757
+ (data) => {
3758
+ onData(this.ensureArray(data));
3759
+ },
3760
+ (error) => {
3761
+ onError?.(this.normalizeError(error));
1598
3762
  }
1599
- )
3763
+ );
3764
+ } catch (error) {
3765
+ onError?.(this.normalizeError(error));
3766
+ return () => {
3767
+ };
1600
3768
  }
1601
- );
3769
+ }
1602
3770
  };
1603
- var CloudinaryContext = React4.createContext(null);
3771
+ var CloudinaryContext = React3.createContext(null);
1604
3772
  var CloudinaryProvider = ({
1605
3773
  cloudName,
1606
3774
  children
1607
3775
  }) => /* @__PURE__ */ jsxRuntime.jsx(CloudinaryContext.Provider, { value: { cloudName }, children });
1608
3776
  var useCloudinaryConfig = () => {
1609
- const ctx = React4.useContext(CloudinaryContext);
3777
+ const ctx = React3.useContext(CloudinaryContext);
1610
3778
  if (!ctx) {
1611
3779
  throw new Error(
1612
3780
  "CloudinaryProvider is missing. Wrap your app with <CloudinaryProvider />"
@@ -2061,7 +4229,7 @@ var ListItem = ({
2061
4229
  children: bullet
2062
4230
  }
2063
4231
  ),
2064
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: TypographyComponent ? React4__default.default.cloneElement(
4232
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: TypographyComponent ? React3__default.default.cloneElement(
2065
4233
  TypographyComponent,
2066
4234
  {
2067
4235
  className: cn(
@@ -2095,7 +4263,7 @@ function normalizeItem(item, defaultBulletType) {
2095
4263
  bulletType: defaultBulletType
2096
4264
  };
2097
4265
  }
2098
- if (React4__default.default.isValidElement(item)) {
4266
+ if (React3__default.default.isValidElement(item)) {
2099
4267
  return {
2100
4268
  content: item,
2101
4269
  bulletType: defaultBulletType
@@ -2559,8 +4727,8 @@ function Table({
2559
4727
  }) {
2560
4728
  const eui = useEUIConfig();
2561
4729
  const resolvedShape = shape ?? eui?.config?.global?.shape ?? "square";
2562
- const [sortKey, setSortKey] = React4.useState(null);
2563
- const [sortOrder, setSortOrder] = React4.useState("asc");
4730
+ const [sortKey, setSortKey] = React3.useState(null);
4731
+ const [sortOrder, setSortOrder] = React3.useState("asc");
2564
4732
  const toggleSort = (key) => {
2565
4733
  if (sortKey === key) {
2566
4734
  setSortOrder((prev) => prev === "asc" ? "desc" : "asc");
@@ -2569,7 +4737,7 @@ function Table({
2569
4737
  setSortOrder("asc");
2570
4738
  }
2571
4739
  };
2572
- const sortedData = React4.useMemo(() => {
4740
+ const sortedData = React3.useMemo(() => {
2573
4741
  if (!sortKey) return data;
2574
4742
  return [...data].sort((a, b) => {
2575
4743
  const aVal = a[sortKey];
@@ -2652,7 +4820,7 @@ function Tag({ text, className, ...rest }) {
2652
4820
  );
2653
4821
  }
2654
4822
  var Tag_default = Tag;
2655
- function Tooltip4({
4823
+ function Tooltip9({
2656
4824
  children,
2657
4825
  show,
2658
4826
  offsetX = 20,
@@ -2660,8 +4828,8 @@ function Tooltip4({
2660
4828
  className,
2661
4829
  ...rest
2662
4830
  }) {
2663
- const [pos, setPos] = React4.useState({ x: 0, y: 0 });
2664
- React4.useEffect(() => {
4831
+ const [pos, setPos] = React3.useState({ x: 0, y: 0 });
4832
+ React3.useEffect(() => {
2665
4833
  if (!show) return;
2666
4834
  const handleMove = (e) => {
2667
4835
  setPos({ x: e.clientX + offsetX, y: e.clientY + offsetY });
@@ -2790,8 +4958,8 @@ function CloudinaryVideo({
2790
4958
  }
2791
4959
  var CloudinaryVideo_default = CloudinaryVideo;
2792
4960
  var FormObserver = ({ formik, onChange }) => {
2793
- const prevValuesRef = React4.useRef(formik.values);
2794
- React4.useEffect(() => {
4961
+ const prevValuesRef = React3.useRef(formik.values);
4962
+ React3.useEffect(() => {
2795
4963
  if (!onChange) return;
2796
4964
  const currentValues = formik.values;
2797
4965
  const prevValues = prevValuesRef.current;
@@ -2810,7 +4978,7 @@ var FormObserver = ({ formik, onChange }) => {
2810
4978
  };
2811
4979
  var FormObserver_default = FormObserver;
2812
4980
  var DirtyObserver = ({ formik, onDirtyChange }) => {
2813
- React4.useEffect(() => {
4981
+ React3.useEffect(() => {
2814
4982
  if (onDirtyChange) {
2815
4983
  onDirtyChange(formik.dirty);
2816
4984
  }
@@ -2819,7 +4987,7 @@ var DirtyObserver = ({ formik, onDirtyChange }) => {
2819
4987
  };
2820
4988
  var DirtyObserver_default = DirtyObserver;
2821
4989
  var UnsavedChangesGuard = ({ formik, enabled }) => {
2822
- React4.useEffect(() => {
4990
+ React3.useEffect(() => {
2823
4991
  if (!enabled) return;
2824
4992
  const handleBeforeUnload = (e) => {
2825
4993
  if (!formik.dirty) return;
@@ -2925,7 +5093,7 @@ function TransitionDropdown({ visibility, children }) {
2925
5093
  return /* @__PURE__ */ jsxRuntime.jsx(
2926
5094
  react.Transition,
2927
5095
  {
2928
- as: React4.Fragment,
5096
+ as: React3.Fragment,
2929
5097
  show: visibility,
2930
5098
  enter: "transition duration-100 ease-out",
2931
5099
  enterFrom: "transform scale-95 opacity-0",
@@ -2942,7 +5110,7 @@ function TransitionFadeIn({ visibility, children }) {
2942
5110
  return /* @__PURE__ */ jsxRuntime.jsx(
2943
5111
  react.Transition,
2944
5112
  {
2945
- as: React4.Fragment,
5113
+ as: React3.Fragment,
2946
5114
  show: visibility,
2947
5115
  enter: `transition-all ease-in-out duration-700 dalay-[0ms]`,
2948
5116
  enterFrom: "opacity-0 translate-y-6",
@@ -3045,17 +5213,17 @@ function YoutubeVideo({
3045
5213
  ) });
3046
5214
  }
3047
5215
  var YoutubeVideo_default = YoutubeVideo;
3048
- var ThemeContext = React4.createContext(
5216
+ var ThemeContext = React3.createContext(
3049
5217
  void 0
3050
5218
  );
3051
5219
  var ThemeProvider = ({
3052
5220
  defaultTheme = "dark",
3053
5221
  children
3054
5222
  }) => {
3055
- const [theme, setTheme] = React4.useState(() => {
5223
+ const [theme, setTheme] = React3.useState(() => {
3056
5224
  return localStorage.getItem("theme") || defaultTheme;
3057
5225
  });
3058
- React4.useEffect(() => {
5226
+ React3.useEffect(() => {
3059
5227
  if (theme === "dark") {
3060
5228
  document.documentElement.classList.add("dark");
3061
5229
  } else {
@@ -3069,7 +5237,7 @@ var ThemeProvider = ({
3069
5237
  return /* @__PURE__ */ jsxRuntime.jsx(ThemeContext.Provider, { value: { theme, setTheme, toggleTheme }, children });
3070
5238
  };
3071
5239
  var ThemeSwitch = () => {
3072
- const themeContext = React4.useContext(ThemeContext);
5240
+ const themeContext = React3.useContext(ThemeContext);
3073
5241
  if (!themeContext) return null;
3074
5242
  const { theme, toggleTheme } = themeContext;
3075
5243
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -3132,7 +5300,7 @@ var ShapeSwitch = () => {
3132
5300
  {
3133
5301
  value: currentShape,
3134
5302
  onChange: handleChange,
3135
- className: "\r\n px-3 py-2 rounded-md border border-gray-300\r\n bg-white dark:bg-gray-800\r\n text-sm shadow-sm\r\n focus:outline-none\r\n ",
5303
+ className: "\n px-3 py-2 rounded-md border border-gray-300\n bg-white dark:bg-gray-800\n text-sm shadow-sm\n focus:outline-none\n ",
3136
5304
  children: Object.keys(Shape).map((shape) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: shape, children: shape }, shape))
3137
5305
  }
3138
5306
  ) });
@@ -3140,7 +5308,7 @@ var ShapeSwitch = () => {
3140
5308
 
3141
5309
  // src/hooks/theme/useCurrentTheme.ts
3142
5310
  var useCurrentTheme = () => {
3143
- const context = React4.useContext(ThemeContext);
5311
+ const context = React3.useContext(ThemeContext);
3144
5312
  if (!context) {
3145
5313
  throw new Error("useCurrentTheme must be used within a ThemeProvider");
3146
5314
  }
@@ -14483,7 +16651,7 @@ function WorldMap({
14483
16651
  }
14484
16652
  };
14485
16653
  const mode = isDarkMode ? mapStyles.dark : mapStyles.light;
14486
- const resolvedData = React4.useMemo(() => {
16654
+ const resolvedData = React3.useMemo(() => {
14487
16655
  return data.map((item) => {
14488
16656
  const c = COUNTRIES.find((x) => x.code === item.code);
14489
16657
  if (!c) return null;
@@ -14495,8 +16663,8 @@ function WorldMap({
14495
16663
  }).filter(Boolean);
14496
16664
  }, [data]);
14497
16665
  const maxValue = resolvedData.length > 0 ? Math.max(...resolvedData.map((d) => d.value)) : 0;
14498
- const [showTooltip, setShowTooltip] = React4.useState(false);
14499
- const [tooltipContent, setTooltipContent] = React4.useState(null);
16666
+ const [showTooltip, setShowTooltip] = React3.useState(false);
16667
+ const [tooltipContent, setTooltipContent] = React3.useState(null);
14500
16668
  const handleMouseMove = (_e, point) => {
14501
16669
  setTooltipContent(
14502
16670
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
@@ -14554,7 +16722,7 @@ function WorldMap({
14554
16722
  ]
14555
16723
  }
14556
16724
  ) }),
14557
- /* @__PURE__ */ jsxRuntime.jsx(Tooltip4, { show: showTooltip, children: tooltipContent })
16725
+ /* @__PURE__ */ jsxRuntime.jsx(Tooltip9, { show: showTooltip, children: tooltipContent })
14558
16726
  ] });
14559
16727
  }
14560
16728
  var sizes4 = {
@@ -14582,7 +16750,7 @@ function Button({
14582
16750
  }) {
14583
16751
  const eui = useEUIConfig();
14584
16752
  const resolvedShape = shape ?? eui?.config?.global?.shape ?? "square";
14585
- const btnRef = React4.useRef(null);
16753
+ const btnRef = React3.useRef(null);
14586
16754
  const variantStyles = resolveAppearanceStyles({
14587
16755
  appearance,
14588
16756
  variant,
@@ -14683,7 +16851,7 @@ var toggleType = (visibility) => {
14683
16851
  var PasswordVisibilityToggler = ({
14684
16852
  onClick
14685
16853
  }) => {
14686
- const [passwordVisibility, setPasswordVisibilty] = React4.useState(false);
16854
+ const [passwordVisibility, setPasswordVisibilty] = React3.useState(false);
14687
16855
  const handleOnClick = (visibility) => {
14688
16856
  onClick(visibility);
14689
16857
  setPasswordVisibilty(visibility);
@@ -14708,7 +16876,7 @@ var Input = ({
14708
16876
  const eui = useEUIConfig();
14709
16877
  const resolvedShape = shape ?? eui?.config?.global?.shape ?? "square";
14710
16878
  const [field, meta] = formik.useField(props);
14711
- const [passwordVisibility, setPasswordVisibilty] = React4.useState(false);
16879
+ const [passwordVisibility, setPasswordVisibilty] = React3.useState(false);
14712
16880
  const inputType = type === "password" ? toggleType(passwordVisibility) : type;
14713
16881
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full", children: [
14714
16882
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -14753,7 +16921,7 @@ var InputFile = ({
14753
16921
  styles,
14754
16922
  ...props
14755
16923
  }) => {
14756
- const fileInputRef = React4.useRef(null);
16924
+ const fileInputRef = React3.useRef(null);
14757
16925
  const [field, meta, helpers] = formik.useField(props);
14758
16926
  const handleFileChange = (e) => {
14759
16927
  const file = e.target.files?.[0] || null;
@@ -15235,7 +17403,7 @@ function ImageView({ imageUrl, secure = true, alt = "image" }) {
15235
17403
  ) }) });
15236
17404
  }
15237
17405
  var ImageView_default = ImageView;
15238
- var ImageInput = React4.forwardRef(
17406
+ var ImageInput = React3.forwardRef(
15239
17407
  ({
15240
17408
  title = "Upload Image",
15241
17409
  uploadDir = "eg-frontend-admin-temp",
@@ -15247,10 +17415,10 @@ var ImageInput = React4.forwardRef(
15247
17415
  const [field, meta, helpers] = formik.useField(props);
15248
17416
  const { value: imageUrl } = field;
15249
17417
  const { setValue } = helpers;
15250
- const [image, setImage] = React4.useState(null);
15251
- const [url, setUrl] = React4.useState(imageUrl);
15252
- const [loading, setLoading] = React4.useState(false);
15253
- const [preview, setPreview] = React4.useState(null);
17418
+ const [image, setImage] = React3.useState(null);
17419
+ const [url, setUrl] = React3.useState(imageUrl);
17420
+ const [loading, setLoading] = React3.useState(false);
17421
+ const [preview, setPreview] = React3.useState(null);
15254
17422
  const uploadImage = async () => {
15255
17423
  if (!image) return;
15256
17424
  setLoading(true);
@@ -15296,10 +17464,10 @@ var ImageInput = React4.forwardRef(
15296
17464
  if (!disableSetValue) setValue("");
15297
17465
  setLoading(false);
15298
17466
  };
15299
- React4.useImperativeHandle(ref, () => ({
17467
+ React3.useImperativeHandle(ref, () => ({
15300
17468
  handleResetClick
15301
17469
  }));
15302
- React4.useEffect(() => {
17470
+ React3.useEffect(() => {
15303
17471
  if (!disableSetValue) setValue(url);
15304
17472
  }, [url, setValue, disableSetValue]);
15305
17473
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
@@ -15384,14 +17552,14 @@ function MultiImageInput({
15384
17552
  const [field, meta, helpers] = formik.useField(props);
15385
17553
  const { value: imageUrls } = field;
15386
17554
  const { setValue } = helpers;
15387
- const imageInputRef = React4.useRef(null);
17555
+ const imageInputRef = React3.useRef(null);
15388
17556
  const onValueChanged = (url) => {
15389
17557
  setValue([...imageUrls, url]);
15390
17558
  if (imageInputRef.current) {
15391
17559
  imageInputRef.current.handleResetClick();
15392
17560
  }
15393
17561
  };
15394
- React4.useEffect(() => {
17562
+ React3.useEffect(() => {
15395
17563
  }, [imageUrls]);
15396
17564
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
15397
17565
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-row flex-wrap gap-5 w-ful", children: [
@@ -15491,9 +17659,9 @@ function StarRatingInput({
15491
17659
  const { name } = props;
15492
17660
  const [field, meta] = formik.useField(props);
15493
17661
  const formikContext = formik.useFormikContext();
15494
- const [rating, setRating] = React4.useState(Number(field.value) || 0);
15495
- const [hover, setHover] = React4.useState(null);
15496
- React4.useEffect(() => {
17662
+ const [rating, setRating] = React3.useState(Number(field.value) || 0);
17663
+ const [hover, setHover] = React3.useState(null);
17664
+ React3.useEffect(() => {
15497
17665
  setRating(Number(field.value));
15498
17666
  }, [field.value]);
15499
17667
  const handleOnClick = (index) => {
@@ -15642,7 +17810,7 @@ function Tags({
15642
17810
  ...props
15643
17811
  }) {
15644
17812
  const [field, meta, helpers] = formik.useField({ ...props });
15645
- const [input, setInput] = React4.useState("");
17813
+ const [input, setInput] = React3.useState("");
15646
17814
  const handleAddTag = () => {
15647
17815
  const trimmed = input.trim();
15648
17816
  if (trimmed && !field.value.includes(trimmed) && field.value.length < limit) {
@@ -15906,8 +18074,8 @@ var Header = ({
15906
18074
  );
15907
18075
  };
15908
18076
  var useIsMobile = (breakpoint = 768) => {
15909
- const [isMobile, setIsMobile] = React4.useState(window.innerWidth < breakpoint);
15910
- React4.useEffect(() => {
18077
+ const [isMobile, setIsMobile] = React3.useState(window.innerWidth < breakpoint);
18078
+ React3.useEffect(() => {
15911
18079
  const handleResize = () => {
15912
18080
  setIsMobile(window.innerWidth < breakpoint);
15913
18081
  };
@@ -16017,7 +18185,7 @@ function BlockGroup({
16017
18185
  }
16018
18186
  var BlockGroup_default = BlockGroup;
16019
18187
  var useTheme = () => {
16020
- const context = React4.useContext(ThemeContext);
18188
+ const context = React3.useContext(ThemeContext);
16021
18189
  if (!context) {
16022
18190
  throw new Error("useTheme must be used within a ThemeProvider");
16023
18191
  }
@@ -16079,11 +18247,11 @@ function MarkdownEditor({
16079
18247
  ] });
16080
18248
  }
16081
18249
  var MarkdownEditor_default = MarkdownEditor;
16082
- var MarkdownContext = React4.createContext(null);
18250
+ var MarkdownContext = React3.createContext(null);
16083
18251
 
16084
18252
  // src/components/markdown/hooks/useMarkdown.tsx
16085
18253
  function useMarkdown() {
16086
- return React4.useContext(MarkdownContext);
18254
+ return React3.useContext(MarkdownContext);
16087
18255
  }
16088
18256
 
16089
18257
  // src/components/markdown/utils/generateHeadingNumbers.ts
@@ -16126,7 +18294,7 @@ function MarkdownTOC({ title = "Table of Contents" }) {
16126
18294
  /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
16127
18295
  "h2",
16128
18296
  {
16129
- className: "\r\n text-sm\r\n font-semibold\r\n uppercase\r\n tracking-wide\r\n text-gray-900\r\n dark:text-gray-100\r\n ",
18297
+ className: "\n text-sm\n font-semibold\n uppercase\n tracking-wide\n text-gray-900\n dark:text-gray-100\n ",
16130
18298
  children: title
16131
18299
  }
16132
18300
  ) }),
@@ -16158,7 +18326,7 @@ function MarkdownViewer({ value }) {
16158
18326
  const markdown = value ?? context?.markdown ?? "";
16159
18327
  const headings = context?.headings ?? [];
16160
18328
  const setActiveHeading = context?.setActiveHeading;
16161
- React4.useEffect(() => {
18329
+ React3.useEffect(() => {
16162
18330
  const timeout = setTimeout(() => {
16163
18331
  headings.forEach((heading) => {
16164
18332
  const headingEls = document.querySelectorAll("h1,h2,h3,h4,h5,h6");
@@ -16263,8 +18431,8 @@ function extractHeadings(markdown) {
16263
18431
  });
16264
18432
  }
16265
18433
  function MarkdownProvider({ markdown, children }) {
16266
- const [activeHeading, setActiveHeading] = React4.useState("");
16267
- const headings = React4.useMemo(() => extractHeadings(markdown), [markdown]);
18434
+ const [activeHeading, setActiveHeading] = React3.useState("");
18435
+ const headings = React3.useMemo(() => extractHeadings(markdown), [markdown]);
16268
18436
  return /* @__PURE__ */ jsxRuntime.jsx(
16269
18437
  MarkdownContext.Provider,
16270
18438
  {
@@ -16337,7 +18505,7 @@ var Breadcrumb = ({
16337
18505
  const { config } = useEUIConfig();
16338
18506
  const pathname = currentPath || (typeof window !== "undefined" ? window.location.pathname : "/");
16339
18507
  const resolvedRoutes = routes || config?.routes || [];
16340
- const resolvedData = React4.useMemo(() => {
18508
+ const resolvedData = React3.useMemo(() => {
16341
18509
  if (resolvedRoutes && resolvedRoutes.length > 0) {
16342
18510
  return buildFromRoutes(resolvedRoutes, pathname);
16343
18511
  }
@@ -16354,7 +18522,7 @@ var Breadcrumb = ({
16354
18522
  navigate(item.href);
16355
18523
  }
16356
18524
  };
16357
- return /* @__PURE__ */ jsxRuntime.jsxs(React4__default.default.Fragment, { children: [
18525
+ return /* @__PURE__ */ jsxRuntime.jsxs(React3__default.default.Fragment, { children: [
16358
18526
  /* @__PURE__ */ jsxRuntime.jsx(
16359
18527
  BreadcrumbItem_default,
16360
18528
  {
@@ -16699,7 +18867,7 @@ function HeaderNav({ data = [], styles }) {
16699
18867
  }
16700
18868
  var HeaderNav_default = HeaderNav;
16701
18869
  function useClickOutside(ref, fun) {
16702
- React4.useEffect(() => {
18870
+ React3.useEffect(() => {
16703
18871
  const listener = (e) => {
16704
18872
  if (!ref.current || ref.current.contains(e.target)) {
16705
18873
  return;
@@ -16740,8 +18908,8 @@ var HeaderNavGroup = ({
16740
18908
  styles,
16741
18909
  children
16742
18910
  }) => {
16743
- const [collapsed, setCollapsed] = React4.useState(true);
16744
- const headerNavGroupRef = React4.useRef(null);
18911
+ const [collapsed, setCollapsed] = React3.useState(true);
18912
+ const headerNavGroupRef = React3.useRef(null);
16745
18913
  useClickOutside(headerNavGroupRef, () => setCollapsed(true));
16746
18914
  const handleNavigation = () => {
16747
18915
  if (to) {
@@ -16964,8 +19132,8 @@ var MenuGroup = ({
16964
19132
  style,
16965
19133
  ...rest
16966
19134
  }) => {
16967
- const [collapsed, setCollapsed] = React4.useState(!defaultOpen);
16968
- React4.useEffect(() => {
19135
+ const [collapsed, setCollapsed] = React3.useState(!defaultOpen);
19136
+ React3.useEffect(() => {
16969
19137
  if (defaultOpen !== void 0) {
16970
19138
  setCollapsed(!defaultOpen);
16971
19139
  }
@@ -17082,12 +19250,12 @@ var Menu = ({
17082
19250
  defaultMenuElements,
17083
19251
  currentPath
17084
19252
  }) => {
17085
- const normalizedItems = React4.useMemo(() => assignKeys(items), [items]);
17086
- const selected = React4.useMemo(() => {
19253
+ const normalizedItems = React3.useMemo(() => assignKeys(items), [items]);
19254
+ const selected = React3.useMemo(() => {
17087
19255
  if (!currentPath) return void 0;
17088
19256
  return findSelectedKey(normalizedItems, currentPath);
17089
19257
  }, [currentPath, normalizedItems]);
17090
- const parentMap = React4.useMemo(
19258
+ const parentMap = React3.useMemo(
17091
19259
  () => buildParentMap(normalizedItems),
17092
19260
  [normalizedItems]
17093
19261
  );
@@ -17240,8 +19408,8 @@ function RouteTabs({
17240
19408
  const currentPath = window.location.pathname;
17241
19409
  return navData.find((tab) => tab.to === currentPath)?.to || navData[0]?.to;
17242
19410
  };
17243
- const [activeTab, setActiveTab] = React4.useState(getActiveTab);
17244
- React4.useEffect(() => {
19411
+ const [activeTab, setActiveTab] = React3.useState(getActiveTab);
19412
+ React3.useEffect(() => {
17245
19413
  if (mode !== "route") return;
17246
19414
  const handlePopState = () => {
17247
19415
  setActiveTab(getActiveTab());
@@ -17338,7 +19506,7 @@ function Modal({
17338
19506
  }) {
17339
19507
  const eui = useEUIConfig();
17340
19508
  const resolvedShape = shape ?? eui?.config?.global?.shape ?? "square";
17341
- const modalRef = React4.useRef(null);
19509
+ const modalRef = React3.useRef(null);
17342
19510
  useClickOutside(
17343
19511
  modalRef,
17344
19512
  enableCloseOnClickOutside ? handleOnClose : void 0
@@ -17353,7 +19521,7 @@ function Modal({
17353
19521
  leave: "transition duration-100 ease-out",
17354
19522
  leaveFrom: "transform scale-200 opacity-100",
17355
19523
  leaveTo: "transform scale-95 opacity-0",
17356
- as: React4.Fragment,
19524
+ as: React3.Fragment,
17357
19525
  children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-eui-dark-900/90 top-0 bottom-0 left-0 right-0 z-50 fixed inset-0 flex items-center justify-center overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
17358
19526
  "div",
17359
19527
  {
@@ -17407,8 +19575,8 @@ var GlowWrapper = ({
17407
19575
  className = "",
17408
19576
  hideOnLeave = true
17409
19577
  }) => {
17410
- const ref = React4.useRef(null);
17411
- const handleMove = React4.useCallback(
19578
+ const ref = React3.useRef(null);
19579
+ const handleMove = React3.useCallback(
17412
19580
  (e) => {
17413
19581
  const el = ref.current;
17414
19582
  if (!el) return;
@@ -17430,7 +19598,7 @@ var GlowWrapper = ({
17430
19598
  },
17431
19599
  [glowSize, glowColor]
17432
19600
  );
17433
- const handleLeave = React4.useCallback(() => {
19601
+ const handleLeave = React3.useCallback(() => {
17434
19602
  const el = ref.current;
17435
19603
  if (!el || !hideOnLeave) return;
17436
19604
  el.style.setProperty("--glow-x", `-999px`);
@@ -17456,7 +19624,7 @@ var GlowWrapper = ({
17456
19624
  /* @__PURE__ */ jsxRuntime.jsx(
17457
19625
  "span",
17458
19626
  {
17459
- className: "\r\n pointer-events-none absolute inset-0 opacity-0 \r\n group-hover:opacity-100 transition-opacity duration-300\r\n ",
19627
+ className: "\n pointer-events-none absolute inset-0 opacity-0 \n group-hover:opacity-100 transition-opacity duration-300\n ",
17460
19628
  style: { background: "var(--glow-bg)" }
17461
19629
  }
17462
19630
  ),
@@ -17466,8 +19634,43 @@ var GlowWrapper = ({
17466
19634
  );
17467
19635
  };
17468
19636
  var GlowWrapper_default = GlowWrapper;
19637
+ function InfiniteScrollTrigger({
19638
+ children,
19639
+ className,
19640
+ hasMore = false,
19641
+ isLoading = false,
19642
+ rootMargin = "600px",
19643
+ threshold = 0,
19644
+ onLoadMore
19645
+ }) {
19646
+ const triggerRef = React3.useRef(null);
19647
+ React3.useEffect(() => {
19648
+ const element = triggerRef.current;
19649
+ if (!element || !hasMore || isLoading) {
19650
+ return;
19651
+ }
19652
+ const observer = new IntersectionObserver(
19653
+ ([entry]) => {
19654
+ if (entry?.isIntersecting) {
19655
+ onLoadMore?.();
19656
+ }
19657
+ },
19658
+ {
19659
+ root: null,
19660
+ rootMargin,
19661
+ threshold
19662
+ }
19663
+ );
19664
+ observer.observe(element);
19665
+ return () => {
19666
+ observer.disconnect();
19667
+ };
19668
+ }, [hasMore, isLoading, onLoadMore, rootMargin, threshold]);
19669
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: triggerRef, className: cn("w-full", className), children });
19670
+ }
19671
+ var InfiniteScrollTrigger_default = InfiniteScrollTrigger;
17469
19672
  function ShowMore({ text, limit }) {
17470
- const [showMore, setShowMore] = React4.useState(false);
19673
+ const [showMore, setShowMore] = React3.useState(false);
17471
19674
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
17472
19675
  showMore ? text : `${text.substring(0, limit)}`,
17473
19676
  text.length > limit && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
@@ -17495,8 +19698,8 @@ function CommentComposer({
17495
19698
  loading,
17496
19699
  onSubmit
17497
19700
  }) {
17498
- const [value, setValue] = React4.useState("");
17499
- const [focused, setFocused] = React4.useState(false);
19701
+ const [value, setValue] = React3.useState("");
19702
+ const [focused, setFocused] = React3.useState(false);
17500
19703
  async function handleSubmit() {
17501
19704
  const content = value.trim();
17502
19705
  if (!content) {
@@ -17751,7 +19954,7 @@ function CommentHeader({ comment, config }) {
17751
19954
  }
17752
19955
  var CommentHeader_default = CommentHeader;
17753
19956
  var useDrawer = (defaultVisibility = true) => {
17754
- const [show, setShow] = React4.useState(defaultVisibility);
19957
+ const [show, setShow] = React3.useState(defaultVisibility);
17755
19958
  const openDrawer = () => {
17756
19959
  setShow((prev) => !prev);
17757
19960
  };
@@ -17766,7 +19969,7 @@ var useDrawer = (defaultVisibility = true) => {
17766
19969
  };
17767
19970
  var useDrawer_default = useDrawer;
17768
19971
  var useModal = () => {
17769
- const [show, setShow] = React4.useState(false);
19972
+ const [show, setShow] = React3.useState(false);
17770
19973
  const handleOpenModal = () => {
17771
19974
  setShow(true);
17772
19975
  };
@@ -17814,7 +20017,7 @@ function CommentMenu({
17814
20017
  onDelete,
17815
20018
  onReport
17816
20019
  }) {
17817
- const ref = React4.useRef(null);
20020
+ const ref = React3.useRef(null);
17818
20021
  useClickOutside(ref, () => setOpen(false));
17819
20022
  const items = [];
17820
20023
  if (canEdit) {
@@ -17942,11 +20145,11 @@ function CommentItem({
17942
20145
  onDelete,
17943
20146
  onReport
17944
20147
  }) {
17945
- const [collapsed, setCollapsed] = React4.useState(true);
17946
- const [isReplying, setIsReplying] = React4.useState(false);
17947
- const [menuOpen, setMenuOpen] = React4.useState(false);
17948
- const [loadingReplies, setLoadingReplies] = React4.useState(false);
17949
- const [repliesLoaded, setRepliesLoaded] = React4.useState(false);
20148
+ const [collapsed, setCollapsed] = React3.useState(true);
20149
+ const [isReplying, setIsReplying] = React3.useState(false);
20150
+ const [menuOpen, setMenuOpen] = React3.useState(false);
20151
+ const [loadingReplies, setLoadingReplies] = React3.useState(false);
20152
+ const [repliesLoaded, setRepliesLoaded] = React3.useState(false);
17950
20153
  const resolvedDepth = Math.min(depth, config.maxDepth);
17951
20154
  const {
17952
20155
  Header: HeaderComponent = CommentHeader_default,
@@ -18110,18 +20313,18 @@ function CommentThread({
18110
20313
  onDelete,
18111
20314
  onReport
18112
20315
  }) {
18113
- const [comments, setComments] = React4.useState([]);
18114
- const [isLoadingComments, setIsLoadingComments] = React4.useState(true);
18115
- const [replyCache, setReplyCache] = React4.useState(
20316
+ const [comments, setComments] = React3.useState([]);
20317
+ const [isLoadingComments, setIsLoadingComments] = React3.useState(true);
20318
+ const [replyCache, setReplyCache] = React3.useState(
18116
20319
  {}
18117
20320
  );
18118
- const replyCacheRef = React4.useRef(replyCache);
20321
+ const replyCacheRef = React3.useRef(replyCache);
18119
20322
  const ComposerComponent = components?.Composer ?? CommentComposer_default;
18120
20323
  const resolvedConfig = {
18121
20324
  ...DEFAULT_COMMENT_THREAD_CONFIG,
18122
20325
  ...config
18123
20326
  };
18124
- React4.useEffect(() => {
20327
+ React3.useEffect(() => {
18125
20328
  async function loadComments() {
18126
20329
  try {
18127
20330
  const result = await dataSource.getComments({
@@ -18135,10 +20338,10 @@ function CommentThread({
18135
20338
  }
18136
20339
  void loadComments();
18137
20340
  }, [dataSource, resolvedConfig.commentsPerPage]);
18138
- React4.useEffect(() => {
20341
+ React3.useEffect(() => {
18139
20342
  replyCacheRef.current = replyCache;
18140
20343
  }, [replyCache]);
18141
- React4.useEffect(() => {
20344
+ React3.useEffect(() => {
18142
20345
  let cancelled = false;
18143
20346
  async function refreshLoadedReplies() {
18144
20347
  const parentIds = Object.keys(replyCacheRef.current);
@@ -18174,13 +20377,13 @@ function CommentThread({
18174
20377
  cancelled = true;
18175
20378
  };
18176
20379
  }, [dataSource, resolvedConfig.repliesPerPage]);
18177
- React4.useEffect(() => {
20380
+ React3.useEffect(() => {
18178
20381
  if (!updatedComment) {
18179
20382
  return;
18180
20383
  }
18181
20384
  updateCommentEverywhere(updatedComment.id, () => updatedComment);
18182
20385
  }, [updatedComment]);
18183
- React4.useEffect(() => {
20386
+ React3.useEffect(() => {
18184
20387
  if (!deletedComment) {
18185
20388
  return;
18186
20389
  }
@@ -18394,13 +20597,13 @@ function SliderItem({
18394
20597
  }
18395
20598
  var SliderItem_default = SliderItem;
18396
20599
  function Slider({ isLoading, isSuccess, coverArt, screenshots }) {
18397
- const [images, setImages] = React4.useState([
20600
+ const [images, setImages] = React3.useState([
18398
20601
  {
18399
20602
  img: coverArt,
18400
20603
  selected: true
18401
20604
  }
18402
20605
  ]);
18403
- React4.useEffect(() => {
20606
+ React3.useEffect(() => {
18404
20607
  setImages([
18405
20608
  {
18406
20609
  img: coverArt,
@@ -18408,7 +20611,7 @@ function Slider({ isLoading, isSuccess, coverArt, screenshots }) {
18408
20611
  }
18409
20612
  ]);
18410
20613
  }, [isSuccess]);
18411
- React4.useEffect(() => {
20614
+ React3.useEffect(() => {
18412
20615
  if (screenshots) {
18413
20616
  const selectableScreenshots = [];
18414
20617
  screenshots.forEach((item) => {
@@ -18420,8 +20623,8 @@ function Slider({ isLoading, isSuccess, coverArt, screenshots }) {
18420
20623
  setImages((prev) => [...prev, ...selectableScreenshots]);
18421
20624
  }
18422
20625
  }, [isSuccess]);
18423
- const [displayImg, setDisplayImg] = React4.useState(coverArt);
18424
- React4.useEffect(() => {
20626
+ const [displayImg, setDisplayImg] = React3.useState(coverArt);
20627
+ React3.useEffect(() => {
18425
20628
  setDisplayImg(coverArt);
18426
20629
  }, [coverArt]);
18427
20630
  const displayImageHandler = (itemIndex, img) => {
@@ -18533,7 +20736,7 @@ function WorldMapCountryTable({
18533
20736
  title = "Country Breakdown",
18534
20737
  data
18535
20738
  }) {
18536
- const enrichedData = React4.useMemo(() => {
20739
+ const enrichedData = React3.useMemo(() => {
18537
20740
  const mapped = data.map((item) => {
18538
20741
  const countryMeta = COUNTRIES.find((c) => c.code === item.code);
18539
20742
  return {
@@ -18546,11 +20749,11 @@ function WorldMapCountryTable({
18546
20749
  });
18547
20750
  return mapped.sort((a, b) => b.value - a.value);
18548
20751
  }, [data]);
18549
- const total = React4.useMemo(
20752
+ const total = React3.useMemo(
18550
20753
  () => enrichedData.reduce((sum, i) => sum + i.value, 0),
18551
20754
  [enrichedData]
18552
20755
  );
18553
- const finalData = React4.useMemo(() => {
20756
+ const finalData = React3.useMemo(() => {
18554
20757
  return enrichedData.map((item) => ({
18555
20758
  ...item,
18556
20759
  percent: total > 0 ? item.value / total * 100 : 0
@@ -18795,7 +20998,7 @@ var TNDropdownGroup = ({
18795
20998
  navigate,
18796
20999
  className
18797
21000
  }) => {
18798
- const [open, setOpen] = React4.useState(true);
21001
+ const [open, setOpen] = React3.useState(true);
18799
21002
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
18800
21003
  /* @__PURE__ */ jsxRuntime.jsxs(
18801
21004
  "div",
@@ -18884,8 +21087,8 @@ var TNGroup = ({
18884
21087
  components,
18885
21088
  selected
18886
21089
  }) => {
18887
- const [open, setOpen] = React4.useState(false);
18888
- const timeoutRef = React4.useRef(null);
21090
+ const [open, setOpen] = React3.useState(false);
21091
+ const timeoutRef = React3.useRef(null);
18889
21092
  const handleEnter = () => {
18890
21093
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
18891
21094
  setOpen(true);
@@ -19022,7 +21225,7 @@ function SidebarLayout({
19022
21225
  header = /* @__PURE__ */ jsxRuntime.jsx(Header, {}),
19023
21226
  footer = /* @__PURE__ */ jsxRuntime.jsx(Footer, {})
19024
21227
  }) {
19025
- const [showSidebar, setShowSidebar] = React4.useState(true);
21228
+ const [showSidebar, setShowSidebar] = React3.useState(true);
19026
21229
  return /* @__PURE__ */ jsxRuntime.jsx(GenericLayout_default, { children: /* @__PURE__ */ jsxRuntime.jsx(Layout, { children: /* @__PURE__ */ jsxRuntime.jsx(Layout, { flexDirection: "horizontal", children: /* @__PURE__ */ jsxRuntime.jsxs(Content, { sidebarVisible: showSidebar, styles: "theme-bg-md pt-[60px]", children: [
19027
21230
  /* @__PURE__ */ jsxRuntime.jsx(ContentArea_default, { children }),
19028
21231
  footer
@@ -19076,7 +21279,7 @@ function ScrollToTop({
19076
21279
  behavior = "smooth",
19077
21280
  target
19078
21281
  }) {
19079
- React4.useEffect(() => {
21282
+ React3.useEffect(() => {
19080
21283
  if (target) {
19081
21284
  target.scrollTo({
19082
21285
  top: 0,
@@ -19094,11 +21297,14 @@ function ScrollToTop({
19094
21297
  var ScrollToTop_default = ScrollToTop;
19095
21298
 
19096
21299
  exports.Accordion = Accordion_default;
21300
+ exports.AreaGraph = AreaGraph;
19097
21301
  exports.AsyncComponentWrapper = AsyncComponentWrapper_default;
19098
21302
  exports.Avatar = Avatar;
19099
21303
  exports.Backdrop = Backdrop_default;
19100
21304
  exports.Badge = Badge;
19101
21305
  exports.BarChart = BarChart_default;
21306
+ exports.BarGraph = BarGraph;
21307
+ exports.BaseGraphDataSource = BaseGraphDataSource;
19102
21308
  exports.Block = Block_default;
19103
21309
  exports.BlockGroup = BlockGroup_default;
19104
21310
  exports.BoxNav = BoxNav_default;
@@ -19122,6 +21328,7 @@ exports.Code = Code;
19122
21328
  exports.CommentThread = CommentThread_default;
19123
21329
  exports.Content = Content;
19124
21330
  exports.ContentArea = ContentArea_default;
21331
+ exports.DEFAULT_GRAPH_THEME = DEFAULT_GRAPH_THEME;
19125
21332
  exports.DataView = DataView;
19126
21333
  exports.DataViewTable = DataViewTable_default;
19127
21334
  exports.DateSelector = DateSelector_default;
@@ -19144,12 +21351,40 @@ exports.FooterNavItemContext = FooterNavItemContext;
19144
21351
  exports.FooterNavItemTitle = FooterNavItemTitle;
19145
21352
  exports.Form = Form;
19146
21353
  exports.FormResponse = FormResponse_default;
21354
+ exports.GRAPH_COLOR_PALETTE = GRAPH_COLOR_PALETTE;
21355
+ exports.GRAPH_DARK_THEME = GRAPH_DARK_THEME;
21356
+ exports.GRAPH_DATA_MODES = GRAPH_DATA_MODES;
21357
+ exports.GRAPH_DEFAULT_ACTIVE_DOT_RADIUS = GRAPH_DEFAULT_ACTIVE_DOT_RADIUS;
21358
+ exports.GRAPH_DEFAULT_ANIMATION_DURATION = GRAPH_DEFAULT_ANIMATION_DURATION;
21359
+ exports.GRAPH_DEFAULT_BAR_RADIUS = GRAPH_DEFAULT_BAR_RADIUS;
21360
+ exports.GRAPH_DEFAULT_DOT_RADIUS = GRAPH_DEFAULT_DOT_RADIUS;
21361
+ exports.GRAPH_DEFAULT_HEIGHT = GRAPH_DEFAULT_HEIGHT;
21362
+ exports.GRAPH_DEFAULT_MARGIN = GRAPH_DEFAULT_MARGIN;
21363
+ exports.GRAPH_DEFAULT_MAX_REALTIME_POINTS = GRAPH_DEFAULT_MAX_REALTIME_POINTS;
21364
+ exports.GRAPH_DEFAULT_POLLING_INTERVAL = GRAPH_DEFAULT_POLLING_INTERVAL;
21365
+ exports.GRAPH_DEFAULT_STROKE_WIDTH = GRAPH_DEFAULT_STROKE_WIDTH;
21366
+ exports.GRAPH_EMPTY_MESSAGE = GRAPH_EMPTY_MESSAGE;
21367
+ exports.GRAPH_ERROR_MESSAGE = GRAPH_ERROR_MESSAGE;
21368
+ exports.GRAPH_LIGHT_THEME = GRAPH_LIGHT_THEME;
21369
+ exports.GRAPH_LOADING_MESSAGE = GRAPH_LOADING_MESSAGE;
21370
+ exports.GRAPH_STATUSES = GRAPH_STATUSES;
21371
+ exports.GRAPH_STATUS_COLORS = GRAPH_STATUS_COLORS;
21372
+ exports.GRAPH_VALUE_FORMATS = GRAPH_VALUE_FORMATS;
21373
+ exports.GaugeGraph = GaugeGraph;
19147
21374
  exports.GenericLayout = GenericLayout_default;
19148
21375
  exports.GlowWrapper = GlowWrapper_default;
19149
21376
  exports.Graph = Graph;
19150
- exports.GraphEdge = GraphEdge;
19151
- exports.GraphNode = GraphNode;
19152
- exports.GraphRenderer = GraphRenderer;
21377
+ exports.GraphContainer = GraphContainer;
21378
+ exports.GraphContext = GraphContext;
21379
+ exports.GraphEmptyState = GraphEmptyState;
21380
+ exports.GraphErrorState = GraphErrorState;
21381
+ exports.GraphHeader = GraphHeader;
21382
+ exports.GraphLegend = GraphLegend;
21383
+ exports.GraphLoadingState = GraphLoadingState;
21384
+ exports.GraphPanel = GraphPanel;
21385
+ exports.GraphProvider = GraphProvider;
21386
+ exports.GraphToolbar = GraphToolbar;
21387
+ exports.GraphTooltip = GraphTooltip;
19153
21388
  exports.Grid = Grid_default;
19154
21389
  exports.Header = Header;
19155
21390
  exports.HeaderNav = HeaderNav_default;
@@ -19160,6 +21395,7 @@ exports.HeaderNavItemTitle = HeaderNavItemTitle;
19160
21395
  exports.HomeLayout = HomeLayout_default;
19161
21396
  exports.Image = Image2;
19162
21397
  exports.ImageInput = ImageInput_default;
21398
+ exports.InfiniteScrollTrigger = InfiniteScrollTrigger_default;
19163
21399
  exports.Info = Info_default;
19164
21400
  exports.Input = Input;
19165
21401
  exports.InputFile = InputFile;
@@ -19171,6 +21407,7 @@ exports.Label = Label;
19171
21407
  exports.Layout = Layout;
19172
21408
  exports.Lead = Lead;
19173
21409
  exports.LineChart = LineChart_default;
21410
+ exports.LineGraph = LineGraph;
19174
21411
  exports.Link = Link;
19175
21412
  exports.List = List_default;
19176
21413
  exports.ListItem = ListItem_default;
@@ -19189,13 +21426,17 @@ exports.NumericRating = NumericRating_default;
19189
21426
  exports.Overline = Overline;
19190
21427
  exports.Paragraph = Paragraph;
19191
21428
  exports.PieChart = PieChart_default;
21429
+ exports.PieGraph = PieGraph;
21430
+ exports.PollingGraphDataSource = PollingGraphDataSource;
19192
21431
  exports.PriceTag = PriceTag;
19193
21432
  exports.ProgressBar = ProgressBar;
19194
21433
  exports.ProgressBarRating = ProgressBarRating_default;
19195
21434
  exports.Quote = Quote;
19196
21435
  exports.Radio = Radio_default;
21436
+ exports.RealtimeGraphDataSource = RealtimeGraphDataSource;
19197
21437
  exports.RouteTab = RouteTab_default;
19198
21438
  exports.RouteTabs = RouteTabs_default;
21439
+ exports.ScatterGraph = ScatterGraph;
19199
21440
  exports.ScrollToTop = ScrollToTop_default;
19200
21441
  exports.Section = Section;
19201
21442
  exports.Select = Select_default;
@@ -19209,6 +21450,8 @@ exports.Slider = Slider_default;
19209
21450
  exports.StarRating = StarRating_default;
19210
21451
  exports.StarRatingDistribution = StarRatingDistribution_default;
19211
21452
  exports.StarRatingInput = StarRatingInput_default;
21453
+ exports.StatGraph = StatGraph;
21454
+ exports.StaticGraphDataSource = StaticGraphDataSource;
19212
21455
  exports.Switch = Switch_default;
19213
21456
  exports.TNDropdown = TNDropdown;
19214
21457
  exports.TNDropdownItem = TNDropdownItem;
@@ -19223,7 +21466,7 @@ exports.ThemeProvider = ThemeProvider;
19223
21466
  exports.ThemeSwitch = ThemeSwitch;
19224
21467
  exports.TitleBanner = TitleBanner;
19225
21468
  exports.Toast = Toast;
19226
- exports.Tooltip = Tooltip4;
21469
+ exports.Tooltip = Tooltip9;
19227
21470
  exports.TopNav = TopNav;
19228
21471
  exports.Transition = Transition4;
19229
21472
  exports.TransitionDropdown = TransitionDropdown_default;
@@ -19237,24 +21480,28 @@ exports.YoutubeVideoPlayer = YoutubeVideo_default;
19237
21480
  exports.addReplyToCache = addReplyToCache;
19238
21481
  exports.applyReactionState = applyReactionState;
19239
21482
  exports.cn = cn;
19240
- exports.createForceLayout = createForceLayout;
19241
- exports.createGridLayout = createGridLayout;
19242
- exports.createTreeLayout = createTreeLayout;
21483
+ exports.createInitialGraphState = createInitialGraphState;
19243
21484
  exports.decrementReplyCount = decrementReplyCount;
19244
21485
  exports.enumValues = enumValues;
19245
21486
  exports.formatCommentDate = formatCommentDate;
21487
+ exports.formatGraphValue = formatGraphValue;
19246
21488
  exports.getCurrencySymbol = getCurrencySymbol;
19247
- exports.getLayout = getLayout;
19248
21489
  exports.getOptimisticDislikeState = getOptimisticDislikeState;
19249
21490
  exports.getOptimisticLikeState = getOptimisticLikeState;
21491
+ exports.graphReducer = graphReducer;
19250
21492
  exports.incrementReplyCount = incrementReplyCount;
19251
21493
  exports.isMatch = isMatch;
19252
21494
  exports.isRenderFn = isRenderFn;
21495
+ exports.limitRealtimePoints = limitRealtimePoints;
19253
21496
  exports.normalize = normalize;
19254
- exports.registerLayout = registerLayout;
21497
+ exports.normalizeGraphData = normalizeGraphData;
21498
+ exports.normalizeGraphDataPoint = normalizeGraphDataPoint;
19255
21499
  exports.removeComment = removeComment;
19256
21500
  exports.removeCommentTreeFromCache = removeCommentTreeFromCache;
21501
+ exports.replaceRealtimePoints = replaceRealtimePoints;
19257
21502
  exports.resolveAppearanceStyles = resolveAppearanceStyles;
21503
+ exports.resolveGraphColor = resolveGraphColor;
21504
+ exports.resolveGraphColors = resolveGraphColors;
19258
21505
  exports.resolveWithGlobal = resolveWithGlobal;
19259
21506
  exports.sendToast = sendToast;
19260
21507
  exports.updateComment = updateComment;
@@ -19264,6 +21511,12 @@ exports.useCloudinaryConfig = useCloudinaryConfig;
19264
21511
  exports.useCurrentTheme = useCurrentTheme_default;
19265
21512
  exports.useDrawer = useDrawer_default;
19266
21513
  exports.useEUIConfig = useEUIConfig;
21514
+ exports.useGraphContext = useGraphContext;
21515
+ exports.useGraphData = useGraphData;
21516
+ exports.useGraphPolling = useGraphPolling;
21517
+ exports.useGraphRealtime = useGraphRealtime;
21518
+ exports.useGraphSeries = useGraphSeries;
21519
+ exports.useGraphTheme = useGraphTheme;
19267
21520
  exports.useIsMobile = useIsMobile_default;
19268
21521
  exports.useModal = useModal_default;
19269
21522
  exports.useTheme = useTheme_default;