@cwellt_software/cwellt-reactjs-lib 1.6.3 → 1.7.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.
Files changed (102) hide show
  1. package/dist/index.cjs.js +2479 -146
  2. package/dist/index.css +1 -1
  3. package/dist/index.d.ts +679 -2
  4. package/dist/index.es.js +2465 -147
  5. package/dist/src/components/custom/report-viewer/CwReportGauge.d.ts +19 -0
  6. package/dist/src/components/custom/report-viewer/CwReportGauge.d.ts.map +1 -0
  7. package/dist/src/components/custom/report-viewer/CwReportLineChart.d.ts +21 -0
  8. package/dist/src/components/custom/report-viewer/CwReportLineChart.d.ts.map +1 -0
  9. package/dist/src/components/custom/report-viewer/CwReportPage.d.ts +36 -0
  10. package/dist/src/components/custom/report-viewer/CwReportPage.d.ts.map +1 -0
  11. package/dist/src/components/custom/report-viewer/CwReportParameterForm.d.ts +26 -0
  12. package/dist/src/components/custom/report-viewer/CwReportParameterForm.d.ts.map +1 -0
  13. package/dist/src/components/custom/report-viewer/CwReportPieChart.d.ts +13 -0
  14. package/dist/src/components/custom/report-viewer/CwReportPieChart.d.ts.map +1 -0
  15. package/dist/src/components/custom/report-viewer/CwReportToolbar.d.ts +40 -0
  16. package/dist/src/components/custom/report-viewer/CwReportToolbar.d.ts.map +1 -0
  17. package/dist/src/components/custom/report-viewer/CwReportViewer.d.ts +50 -0
  18. package/dist/src/components/custom/report-viewer/CwReportViewer.d.ts.map +1 -0
  19. package/dist/src/components/custom/report-viewer/ReportItem.d.ts +21 -0
  20. package/dist/src/components/custom/report-viewer/ReportItem.d.ts.map +1 -0
  21. package/dist/src/components/custom/report-viewer/ReportTextbox.d.ts +10 -0
  22. package/dist/src/components/custom/report-viewer/ReportTextbox.d.ts.map +1 -0
  23. package/dist/src/components/custom/report-viewer/logic/rdlChartMarkers.d.ts +26 -0
  24. package/dist/src/components/custom/report-viewer/logic/rdlChartMarkers.d.ts.map +1 -0
  25. package/dist/src/components/custom/report-viewer/logic/rdlChartScale.d.ts +75 -0
  26. package/dist/src/components/custom/report-viewer/logic/rdlChartScale.d.ts.map +1 -0
  27. package/dist/src/components/custom/report-viewer/logic/rdlFind.d.ts +38 -0
  28. package/dist/src/components/custom/report-viewer/logic/rdlFind.d.ts.map +1 -0
  29. package/dist/src/components/custom/report-viewer/logic/rdlGauge.d.ts +40 -0
  30. package/dist/src/components/custom/report-viewer/logic/rdlGauge.d.ts.map +1 -0
  31. package/dist/src/components/custom/report-viewer/logic/rdlListMarkers.d.ts +12 -0
  32. package/dist/src/components/custom/report-viewer/logic/rdlListMarkers.d.ts.map +1 -0
  33. package/dist/src/components/custom/report-viewer/logic/rdlNumberFormat.d.ts +8 -0
  34. package/dist/src/components/custom/report-viewer/logic/rdlNumberFormat.d.ts.map +1 -0
  35. package/dist/src/components/custom/report-viewer/logic/rdlPageGeometry.d.ts +38 -0
  36. package/dist/src/components/custom/report-viewer/logic/rdlPageGeometry.d.ts.map +1 -0
  37. package/dist/src/components/custom/report-viewer/logic/rdlParameterValues.d.ts +42 -0
  38. package/dist/src/components/custom/report-viewer/logic/rdlParameterValues.d.ts.map +1 -0
  39. package/dist/src/components/custom/report-viewer/logic/rdlStyle.d.ts +62 -0
  40. package/dist/src/components/custom/report-viewer/logic/rdlStyle.d.ts.map +1 -0
  41. package/dist/src/components/custom/report-viewer/logic/rdlTableLayout.d.ts +33 -0
  42. package/dist/src/components/custom/report-viewer/logic/rdlTableLayout.d.ts.map +1 -0
  43. package/dist/src/components/custom/report-viewer/logic/rdlToggles.d.ts +20 -0
  44. package/dist/src/components/custom/report-viewer/logic/rdlToggles.d.ts.map +1 -0
  45. package/dist/src/components/custom/report-viewer/logic/rdlUnits.d.ts +9 -0
  46. package/dist/src/components/custom/report-viewer/logic/rdlUnits.d.ts.map +1 -0
  47. package/dist/src/components/custom/report-viewer/logic/reportOutputGuard.d.ts +20 -0
  48. package/dist/src/components/custom/report-viewer/logic/reportOutputGuard.d.ts.map +1 -0
  49. package/dist/src/components/custom/report-viewer/logic/reportViewerLayout.d.ts +17 -0
  50. package/dist/src/components/custom/report-viewer/logic/reportViewerLayout.d.ts.map +1 -0
  51. package/dist/src/components/custom/report-viewer/rdlTypes.d.ts +333 -0
  52. package/dist/src/components/custom/report-viewer/rdlTypes.d.ts.map +1 -0
  53. package/dist/src/components/custom/report-viewer/reportChartShared.d.ts +53 -0
  54. package/dist/src/components/custom/report-viewer/reportChartShared.d.ts.map +1 -0
  55. package/dist/src/components/custom/report-viewer/reportRenderContext.d.ts +25 -0
  56. package/dist/src/components/custom/report-viewer/reportRenderContext.d.ts.map +1 -0
  57. package/dist/src/components/custom/report-viewer/useReportParameterForm.d.ts +30 -0
  58. package/dist/src/components/custom/report-viewer/useReportParameterForm.d.ts.map +1 -0
  59. package/dist/src/components/custom/report-viewer/useReportViewerState.d.ts +74 -0
  60. package/dist/src/components/custom/report-viewer/useReportViewerState.d.ts.map +1 -0
  61. package/dist/src/components/custom/report-viewer/useSidebarResize.d.ts +22 -0
  62. package/dist/src/components/custom/report-viewer/useSidebarResize.d.ts.map +1 -0
  63. package/dist/src/components/display/data/tooltip_manager/CwTooltipManager.d.ts +1 -1
  64. package/dist/src/components/display/data/tooltip_manager/CwTooltipManager.d.ts.map +1 -1
  65. package/dist/src/index.d.ts +15 -0
  66. package/dist/src/index.d.ts.map +1 -1
  67. package/dist/src/playground/PlaygroundApp.d.ts.map +1 -1
  68. package/dist/src/playground/pages/ReportViewerPage.d.ts +8 -0
  69. package/dist/src/playground/pages/ReportViewerPage.d.ts.map +1 -0
  70. package/dist/src/playground/pages/reportViewerFakeData.d.ts +13 -0
  71. package/dist/src/playground/pages/reportViewerFakeData.d.ts.map +1 -0
  72. package/dist/test/components/custom/report-viewer/rdlChartMarkers.test.d.ts +2 -0
  73. package/dist/test/components/custom/report-viewer/rdlChartMarkers.test.d.ts.map +1 -0
  74. package/dist/test/components/custom/report-viewer/rdlChartScale.test.d.ts +2 -0
  75. package/dist/test/components/custom/report-viewer/rdlChartScale.test.d.ts.map +1 -0
  76. package/dist/test/components/custom/report-viewer/rdlFind.test.d.ts +2 -0
  77. package/dist/test/components/custom/report-viewer/rdlFind.test.d.ts.map +1 -0
  78. package/dist/test/components/custom/report-viewer/rdlGauge.test.d.ts +2 -0
  79. package/dist/test/components/custom/report-viewer/rdlGauge.test.d.ts.map +1 -0
  80. package/dist/test/components/custom/report-viewer/rdlNumberFormat.test.d.ts +2 -0
  81. package/dist/test/components/custom/report-viewer/rdlNumberFormat.test.d.ts.map +1 -0
  82. package/dist/test/components/custom/report-viewer/rdlParameterValues.test.d.ts +2 -0
  83. package/dist/test/components/custom/report-viewer/rdlParameterValues.test.d.ts.map +1 -0
  84. package/dist/test/components/custom/report-viewer/rdlTableLayout.test.d.ts +2 -0
  85. package/dist/test/components/custom/report-viewer/rdlTableLayout.test.d.ts.map +1 -0
  86. package/dist/test/components/custom/report-viewer/rdlText.test.d.ts +2 -0
  87. package/dist/test/components/custom/report-viewer/rdlText.test.d.ts.map +1 -0
  88. package/dist/test/components/custom/report-viewer/rdlToggles.test.d.ts +2 -0
  89. package/dist/test/components/custom/report-viewer/rdlToggles.test.d.ts.map +1 -0
  90. package/dist/test/components/custom/report-viewer/rdlUnits.test.d.ts +2 -0
  91. package/dist/test/components/custom/report-viewer/rdlUnits.test.d.ts.map +1 -0
  92. package/dist/test/components/custom/report-viewer/reportOutputGuard.test.d.ts +2 -0
  93. package/dist/test/components/custom/report-viewer/reportOutputGuard.test.d.ts.map +1 -0
  94. package/dist/test/components/custom/report-viewer/reportViewerLayout.test.d.ts +2 -0
  95. package/dist/test/components/custom/report-viewer/reportViewerLayout.test.d.ts.map +1 -0
  96. package/dist/test/components/custom/report-viewer/useReportParameterForm.test.d.ts +2 -0
  97. package/dist/test/components/custom/report-viewer/useReportParameterForm.test.d.ts.map +1 -0
  98. package/dist/test/components/custom/report-viewer/useReportViewerState.test.d.ts +2 -0
  99. package/dist/test/components/custom/report-viewer/useReportViewerState.test.d.ts.map +1 -0
  100. package/dist/test/helpers/renderHookHeadless.d.ts +8 -0
  101. package/dist/test/helpers/renderHookHeadless.d.ts.map +1 -0
  102. package/package.json +89 -89
package/dist/index.cjs.js CHANGED
@@ -194,7 +194,7 @@ function getContrastColor(color) {
194
194
  return `hsl(${hsl.h}, ${contrastS}%, ${targetL}%)`;
195
195
  }
196
196
 
197
- var styles$A = {"cw-tooltip-content":"cw-tooltip-module__cw-tooltip-content__RZczd","cw-tooltip":"cw-tooltip-module__cw-tooltip__1KYig"};
197
+ var styles$D = {"cw-tooltip-content":"cw-tooltip-module__cw-tooltip-content__RZczd","cw-tooltip":"cw-tooltip-module__cw-tooltip__1KYig"};
198
198
 
199
199
  // Constants
200
200
  const margin$1 = 16;
@@ -484,7 +484,7 @@ const CwTooltipManager = () => {
484
484
  if (!state.isVisible || !state.content) {
485
485
  return null;
486
486
  }
487
- return reactDom.createPortal(jsxRuntime.jsx("div", { ref: tooltipRef, className: styles$A["cw-tooltip-content"], "data-position": actualPosition, "data-visible": state.isVisible, "data-inline": state.displayInline, style: {
487
+ return reactDom.createPortal(jsxRuntime.jsx("div", { ref: tooltipRef, className: styles$D["cw-tooltip-content"], "data-position": actualPosition, "data-visible": state.isVisible, "data-inline": state.displayInline, style: {
488
488
  top: `${tooltipPosition.top}px`,
489
489
  left: `${tooltipPosition.left}px`,
490
490
  opacity: (isPositioned && !isMeasuring) ? 1 : 0,
@@ -565,7 +565,7 @@ const CwTooltipNew = ({ children, content = null, position = "right", dissapears
565
565
  React.useEffect(() => {
566
566
  ensureTooltipManager();
567
567
  }, []);
568
- return (jsxRuntime.jsx("div", { ref: containerRef, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, className: styles$A["cw-tooltip"], children: children }));
568
+ return (jsxRuntime.jsx("div", { ref: containerRef, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, className: styles$D["cw-tooltip"], children: children }));
569
569
  };
570
570
 
571
571
  const SVG_ICONS = {
@@ -685,7 +685,7 @@ function resolveBadgeAria(label, loading, hasText) {
685
685
  return hasText ? {} : { 'aria-hidden': 'true' };
686
686
  }
687
687
 
688
- var styles$z = {"badge":"cw-badge-module__badge__PKlak"};
688
+ var styles$C = {"badge":"cw-badge-module__badge__PKlak"};
689
689
 
690
690
  /**
691
691
  * CwBadge - the small coloured circle with a number, used for alert and notification counts.
@@ -721,7 +721,7 @@ const CwBadge = ({ count, content, color = 'info', variant = 'solid', size = 'sm
721
721
  ? formatBadgeCount(count, max)
722
722
  : undefined;
723
723
  const isDot = !loading && !hasContent && count === undefined;
724
- const badgeClassNames = ['cw-badge', styles$z.badge, className].filter(Boolean).join(' ');
724
+ const badgeClassNames = ['cw-badge', styles$C.badge, className].filter(Boolean).join(' ');
725
725
  return (jsxRuntime.jsx("span", { ...dataAttributes, className: badgeClassNames, "data-color": color, "data-variant": variant, "data-size": size, "data-loading": loading ? 'true' : undefined, "data-dot": isDot ? 'true' : undefined, ...resolveBadgeAria(label, loading, !loading && (hasContent || countText !== undefined)), style: style, children: loading ? jsxRuntime.jsx(CwIcon, { iconId: "spinner", size: "small" }) : hasContent ? content : countText }));
726
726
  };
727
727
 
@@ -1109,7 +1109,7 @@ function CwLoading({ isLoading = false, text = '', size = 'regular', iconPositio
1109
1109
  return (jsxRuntime.jsxs("div", { "aria-busy": isLoading, className: "cw-loading-container", "data-children": !!children, children: [overlay, jsxRuntime.jsx("div", { className: "cw-loading-disabled-content", children: children })] }));
1110
1110
  }
1111
1111
 
1112
- var styles$y = {"skeleton":"cw-skeleton-module__skeleton__Jvx2x","group":"cw-skeleton-module__group__Cm8AU"};
1112
+ var styles$B = {"skeleton":"cw-skeleton-module__skeleton__Jvx2x","group":"cw-skeleton-module__group__Cm8AU"};
1113
1113
 
1114
1114
  /*
1115
1115
  * Internal helper for skeleton allocations (CwSkeleton, tables, cards).
@@ -1151,8 +1151,8 @@ function CwSkeleton({ variant = 'text', width, height, count = 1, radius, gap })
1151
1151
  };
1152
1152
  // The un-hashed cw-skeleton / cw-skeleton-group classes carry no styles in the
1153
1153
  // library - they are stable public hooks for exceptional external overrides.
1154
- const skeletonClassName = ['cw-skeleton', styles$y.skeleton].filter(Boolean).join(' ');
1155
- const groupClassName = ['cw-skeleton-group', styles$y.group].filter(Boolean).join(' ');
1154
+ const skeletonClassName = ['cw-skeleton', styles$B.skeleton].filter(Boolean).join(' ');
1155
+ const groupClassName = ['cw-skeleton-group', styles$B.group].filter(Boolean).join(' ');
1156
1156
  const lineCount = normalizeSkeletonCount(count, 1);
1157
1157
  if (lineCount <= 1) {
1158
1158
  return (jsxRuntime.jsx("span", { className: skeletonClassName, "data-variant": variant, "aria-hidden": "true", style: style }));
@@ -1164,7 +1164,7 @@ function CwSkeleton({ variant = 'text', width, height, count = 1, radius, gap })
1164
1164
  return (jsxRuntime.jsx("span", { className: groupClassName, "aria-hidden": "true", style: groupStyle, children: skeletonElements }));
1165
1165
  }
1166
1166
 
1167
- var styles$x = {"progress":"cw-progress-module__progress__d-g2-","value":"cw-progress-module__value__Q-DrH","label":"cw-progress-module__label__jwOWp","track":"cw-progress-module__track__572-3","footer":"cw-progress-module__footer__0Wo4G","header":"cw-progress-module__header__mv5ct","fill":"cw-progress-module__fill__fX1UA"};
1167
+ var styles$A = {"progress":"cw-progress-module__progress__d-g2-","value":"cw-progress-module__value__Q-DrH","label":"cw-progress-module__label__jwOWp","track":"cw-progress-module__track__572-3","footer":"cw-progress-module__footer__0Wo4G","header":"cw-progress-module__header__mv5ct","fill":"cw-progress-module__fill__fX1UA"};
1168
1168
 
1169
1169
  /**
1170
1170
  * CwProgress - a determinate or indeterminate progress bar.
@@ -1188,17 +1188,17 @@ function CwProgress({ value, indeterminate = false, label, rightLabel, footer, s
1188
1188
  const valueContent = rightLabel ?? (percent !== undefined ? `${percent}%` : '');
1189
1189
  // The un-hashed cw-progress class carries no styles in the library - a stable
1190
1190
  // public hook for exceptional external overrides only.
1191
- const rootClassName = ['cw-progress', styles$x.progress, className].filter(Boolean).join(' ');
1192
- const labelSpan = label ? jsxRuntime.jsx("span", { className: styles$x.label, id: labelId, children: label }) : null;
1193
- const valueLabel = showValue ? (jsxRuntime.jsx("span", { className: styles$x.value, "data-mono": monoValue || undefined, children: valueContent })) : null;
1194
- return (jsxRuntime.jsxs("div", { ...dataAttributes, className: rootClassName, style: style, "data-layout": layout, "data-size": size, "data-color": color, "data-prominent": prominent || undefined, "data-indeterminate": indeterminate || undefined, children: [layout === 'column' && (labelSpan || valueLabel) && (jsxRuntime.jsxs("header", { className: styles$x.header, children: [labelSpan, valueLabel] })), layout === 'row' && labelSpan, jsxRuntime.jsx("div", { className: styles$x.track, role: "progressbar", ...(label && { 'aria-labelledby': labelId }), ...(!indeterminate && percent !== undefined && {
1191
+ const rootClassName = ['cw-progress', styles$A.progress, className].filter(Boolean).join(' ');
1192
+ const labelSpan = label ? jsxRuntime.jsx("span", { className: styles$A.label, id: labelId, children: label }) : null;
1193
+ const valueLabel = showValue ? (jsxRuntime.jsx("span", { className: styles$A.value, "data-mono": monoValue || undefined, children: valueContent })) : null;
1194
+ return (jsxRuntime.jsxs("div", { ...dataAttributes, className: rootClassName, style: style, "data-layout": layout, "data-size": size, "data-color": color, "data-prominent": prominent || undefined, "data-indeterminate": indeterminate || undefined, children: [layout === 'column' && (labelSpan || valueLabel) && (jsxRuntime.jsxs("header", { className: styles$A.header, children: [labelSpan, valueLabel] })), layout === 'row' && labelSpan, jsxRuntime.jsx("div", { className: styles$A.track, role: "progressbar", ...(label && { 'aria-labelledby': labelId }), ...(!indeterminate && percent !== undefined && {
1195
1195
  'aria-valuenow': percent,
1196
1196
  'aria-valuemin': 0,
1197
1197
  'aria-valuemax': 100
1198
- }), children: jsxRuntime.jsx("div", { className: styles$x.fill, style: !indeterminate && clamped !== undefined ? { width: `${clamped}%` } : undefined }) }), layout === 'row' && valueLabel, footer != null && jsxRuntime.jsx("footer", { className: styles$x.footer, children: footer })] }));
1198
+ }), children: jsxRuntime.jsx("div", { className: styles$A.fill, style: !indeterminate && clamped !== undefined ? { width: `${clamped}%` } : undefined }) }), layout === 'row' && valueLabel, footer != null && jsxRuntime.jsx("footer", { className: styles$A.footer, children: footer })] }));
1199
1199
  }
1200
1200
 
1201
- var styles$w = {"cw-generic-tooltip-content":"cw-generic-tooltip-module__cw-generic-tooltip-content__la-Si","cw-generic-tooltip":"cw-generic-tooltip-module__cw-generic-tooltip__Ij76M"};
1201
+ var styles$z = {"cw-generic-tooltip-content":"cw-generic-tooltip-module__cw-generic-tooltip-content__la-Si","cw-generic-tooltip":"cw-generic-tooltip-module__cw-generic-tooltip__Ij76M"};
1202
1202
 
1203
1203
  // Constants moved outside to prevent recreation
1204
1204
  const margin = 16;
@@ -1325,12 +1325,12 @@ const CwGenericTooltip = ({ children, content = null, position = defaultPosition
1325
1325
  const { setTooltipTimeout, clearTooltipTimeout } = useTooltipDelay(() => {
1326
1326
  setIsVisible(true);
1327
1327
  }, showDelay);
1328
- const { position: tooltipPosition, actualPosition } = useTooltipPosition(isVisible, containerRef, position, styles$w["cw-generic-tooltip-content"]);
1328
+ const { position: tooltipPosition, actualPosition } = useTooltipPosition(isVisible, containerRef, position, styles$z["cw-generic-tooltip-content"]);
1329
1329
  // Memoize tooltip content creation
1330
1330
  const tooltipContent = React.useMemo(() => {
1331
1331
  if (hide || !isVisible || !content)
1332
1332
  return null;
1333
- return reactDom.createPortal(jsxRuntime.jsx("div", { className: styles$w["cw-generic-tooltip-content"], "data-position": actualPosition, "data-visible": isVisible, "data-inline": displayInline, style: {
1333
+ return reactDom.createPortal(jsxRuntime.jsx("div", { className: styles$z["cw-generic-tooltip-content"], "data-position": actualPosition, "data-visible": isVisible, "data-inline": displayInline, style: {
1334
1334
  position: 'fixed',
1335
1335
  top: `${tooltipPosition.top}px`,
1336
1336
  left: `${tooltipPosition.left}px`,
@@ -1345,7 +1345,7 @@ const CwGenericTooltip = ({ children, content = null, position = defaultPosition
1345
1345
  clearTooltipTimeout();
1346
1346
  setIsVisible(false);
1347
1347
  }, [clearTooltipTimeout]);
1348
- return (jsxRuntime.jsxs("div", { ref: containerRef, className: styles$w["cw-generic-tooltip"], onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, children: [tooltipContent, children] }));
1348
+ return (jsxRuntime.jsxs("div", { ref: containerRef, className: styles$z["cw-generic-tooltip"], onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: overlayStyle, "data-inline": displayInline, children: [tooltipContent, children] }));
1349
1349
  };
1350
1350
 
1351
1351
  const CwButton = React.forwardRef(function CwButton({ text, variant = 'solid', color = 'primary', size = 'medium', iconPosition = 'left', pressed, className = '', icon = "", title, tooltipPosition = "bottom", badge, children, ...buttonProps }, ref) {
@@ -1413,7 +1413,7 @@ function CwModal(custModalProps) {
1413
1413
  return (jsxRuntime.jsx("div", { children: custModalProps.modalState && (jsxRuntime.jsxs("div", { className: custModalProps.classNameModalOverlay + " cwelltModalOverlay", children: [jsxRuntime.jsx("div", { className: "cwelltModalOverlayBg", onClick: custModalProps.onCloseModal }), jsxRuntime.jsx(Draggable, { disabled: isModalDisabled, axis: "both", nodeRef: draggableRef, children: jsxRuntime.jsxs("div", { className: custModalProps.classNameModal + " cwelltContainerModal", ref: draggableRef, style: widthModalDef !== "40em" ? modalStyle.widthCustomStyle : modalStyle.widthDefStyle, children: [jsxRuntime.jsxs("div", { className: "cwelltModalHeader", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: [jsxRuntime.jsx("div", { className: "cwelltModalTitle", children: custModalProps.titleModal }), jsxRuntime.jsx("button", { className: "cwelltBtnCloseModal", onClick: custModalProps.onCloseModal, children: jsxRuntime.jsx("span", { className: "cwelltCloseIcon" }) })] }), jsxRuntime.jsx("div", { className: "cwelltModalBody", children: jsxRuntime.jsx("div", { className: "cwelltContainerModalBody", style: { position: "relative" }, children: custModalProps.children }) }), isHide === false ? (jsxRuntime.jsx("footer", { className: "legacy-modal-footer", onMouseOver: cwelltOnMouseOverModal, onMouseOut: cwelltOnMouseOutModal, children: jsxRuntime.jsx(CwButton, { variant: "icon", icon: "save", title: "Save", onClick: custModalProps.onSaveModal, form: custModalProps.formSaveModal, hidden: custModalProps.HideBtnModal, type: custModalProps.HtmlSubmitModal }) })) : (jsxRuntime.jsx("div", { style: { display: "none" } }))] }) })] })) }));
1414
1414
  }
1415
1415
 
1416
- var styles$v = {"overlayPositioned":"CwConfirmationPopup-module__overlayPositioned__11qYB","popup":"CwConfirmationPopup-module__popup__ahPjM","message":"CwConfirmationPopup-module__message__MnNL4","buttons":"CwConfirmationPopup-module__buttons__fGYYE","button":"CwConfirmationPopup-module__button__ugYQE","confirmButton":"CwConfirmationPopup-module__confirmButton__rTP4S","cancelButton":"CwConfirmationPopup-module__cancelButton__Ry694"};
1416
+ var styles$y = {"overlayPositioned":"CwConfirmationPopup-module__overlayPositioned__11qYB","popup":"CwConfirmationPopup-module__popup__ahPjM","message":"CwConfirmationPopup-module__message__MnNL4","buttons":"CwConfirmationPopup-module__buttons__fGYYE","button":"CwConfirmationPopup-module__button__ugYQE","confirmButton":"CwConfirmationPopup-module__confirmButton__rTP4S","cancelButton":"CwConfirmationPopup-module__cancelButton__Ry694"};
1417
1417
 
1418
1418
  /**
1419
1419
  * Small anchored confirmation for a destructive action.
@@ -1482,15 +1482,15 @@ function CwConfirmationPopup(props) {
1482
1482
  onCancel();
1483
1483
  }
1484
1484
  };
1485
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [renderChildren(), isOpen && (jsxRuntime.jsx("div", { className: styles$v.overlayPositioned, onClick: handleOverlayClick, children: jsxRuntime.jsxs("div", { ref: popupRef, className: styles$v.popup, style: {
1485
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [renderChildren(), isOpen && (jsxRuntime.jsx("div", { className: styles$y.overlayPositioned, onClick: handleOverlayClick, children: jsxRuntime.jsxs("div", { ref: popupRef, className: styles$y.popup, style: {
1486
1486
  position: 'absolute',
1487
1487
  top: `${position.top}px`,
1488
1488
  left: `${position.left}px`,
1489
1489
  transform: 'none'
1490
- }, children: [jsxRuntime.jsx("p", { className: styles$v.message, children: message }), jsxRuntime.jsxs("div", { className: styles$v.buttons, children: [jsxRuntime.jsx("button", { className: `${styles$v.button} ${styles$v.confirmButton}`, onClick: onConfirm, children: confirmText }), jsxRuntime.jsx("button", { className: `${styles$v.button} ${styles$v.cancelButton}`, onClick: onCancel, children: cancelText })] })] }) }))] }));
1490
+ }, children: [jsxRuntime.jsx("p", { className: styles$y.message, children: message }), jsxRuntime.jsxs("div", { className: styles$y.buttons, children: [jsxRuntime.jsx("button", { className: `${styles$y.button} ${styles$y.confirmButton}`, onClick: onConfirm, children: confirmText }), jsxRuntime.jsx("button", { className: `${styles$y.button} ${styles$y.cancelButton}`, onClick: onCancel, children: cancelText })] })] }) }))] }));
1491
1491
  }
1492
1492
 
1493
- var styles$u = {"cw-dialog-main":"cw-dialog-module__cw-dialog-main__cHxHt","cw-dialog-button-close":"cw-dialog-module__cw-dialog-button-close__9GRd8"};
1493
+ var styles$x = {"cw-dialog-main":"cw-dialog-module__cw-dialog-main__cHxHt","cw-dialog-button-close":"cw-dialog-module__cw-dialog-button-close__9GRd8"};
1494
1494
 
1495
1495
  // Helper function to parse size values
1496
1496
  const parseSize = (size) => {
@@ -1763,7 +1763,7 @@ const CwDialog = props => {
1763
1763
  }
1764
1764
  }
1765
1765
  }, [open]);
1766
- const header = React.useMemo(() => (jsxRuntime.jsxs("header", { onMouseDown: handleMouseDown, children: [jsxRuntime.jsx("span", { children: headline }), customHeader || (jsxRuntime.jsx("button", { className: styles$u["cw-dialog-button-close"], onClick: onClose }))] })), [handleMouseDown, headline, customHeader, onClose]);
1766
+ const header = React.useMemo(() => (jsxRuntime.jsxs("header", { onMouseDown: handleMouseDown, children: [jsxRuntime.jsx("span", { children: headline }), customHeader || (jsxRuntime.jsx("button", { className: styles$x["cw-dialog-button-close"], onClick: onClose }))] })), [handleMouseDown, headline, customHeader, onClose]);
1767
1767
  const content = React.useMemo(() => (jsxRuntime.jsx("section", { children: children })), [children]);
1768
1768
  const footer = React.useMemo(() => (jsxRuntime.jsx("footer", { children: customFooter || (jsxRuntime.jsx(CwButton, { variant: "icon", icon: "save", title: "Save", onClick: onSave, tooltipPosition: "top", disabled: disableSave, "data-testid": "cw-dialog-save" })) })), [customFooter, onSave, disableSave]);
1769
1769
  const resizeHandles = React.useMemo(() => size.autoHeight
@@ -1790,7 +1790,7 @@ const CwDialog = props => {
1790
1790
  : `${convertFromPx(size.height, size.heightUnit)}${size.heightUnit}`;
1791
1791
  return { displayWidth, displayHeight };
1792
1792
  }, [size.width, size.height, size.widthUnit, size.heightUnit, size.autoHeight]);
1793
- const dialogContent = (jsxRuntime.jsx("div", { "data-has-scrim": hasScrim, className: styles$u["cw-dialog-main"], onMouseDown: handleScrimMouseDown, onMouseUp: handleScrimMouseUpOrLeave, onMouseLeave: handleScrimMouseUpOrLeave, "data-pressing": isPressingScrim, children: jsxRuntime.jsxs("dialog", { ...domProps, ref: dialogRef, style: {
1793
+ const dialogContent = (jsxRuntime.jsx("div", { "data-has-scrim": hasScrim, className: styles$x["cw-dialog-main"], onMouseDown: handleScrimMouseDown, onMouseUp: handleScrimMouseUpOrLeave, onMouseLeave: handleScrimMouseUpOrLeave, "data-pressing": isPressingScrim, children: jsxRuntime.jsxs("dialog", { ...domProps, ref: dialogRef, style: {
1794
1794
  left: `${position.x}px`,
1795
1795
  top: `${position.y}px`,
1796
1796
  width: displayDimensions.displayWidth,
@@ -1952,7 +1952,7 @@ function CwAlign(props) {
1952
1952
  }, children: props.children }));
1953
1953
  }
1954
1954
 
1955
- var styles$t = {"card":"cw-card-module__card__HJUT0","content":"cw-card-module__content__ma9qy","clickable":"cw-card-module__clickable__Y-V3X","disabled":"cw-card-module__disabled__0wHh1","headerContent":"cw-card-module__headerContent__x4Jfl","footerTags":"cw-card-module__footerTags__80sSW"};
1955
+ var styles$w = {"card":"cw-card-module__card__HJUT0","content":"cw-card-module__content__ma9qy","clickable":"cw-card-module__clickable__Y-V3X","disabled":"cw-card-module__disabled__0wHh1","headerContent":"cw-card-module__headerContent__x4Jfl","footerTags":"cw-card-module__footerTags__80sSW"};
1956
1956
 
1957
1957
  /**
1958
1958
  * CwCard - A simple card component for displaying content in a contained format
@@ -1978,10 +1978,10 @@ const CwCard = ({ id, title, subtitle, alignment = 'center', children, footer, o
1978
1978
  // Construct class names using CSS modules
1979
1979
  const cardClassNames = [
1980
1980
  'cw-card',
1981
- styles$t.card,
1981
+ styles$w.card,
1982
1982
  className,
1983
- clickable ? styles$t.clickable : '',
1984
- disabled ? styles$t.disabled : '',
1983
+ clickable ? styles$w.clickable : '',
1984
+ disabled ? styles$w.disabled : '',
1985
1985
  ].filter(Boolean).join(' ');
1986
1986
  // Handle click event when card is clickable
1987
1987
  const handleClick = () => {
@@ -1999,15 +1999,15 @@ const CwCard = ({ id, title, subtitle, alignment = 'center', children, footer, o
1999
1999
  const hasFooter = hasChips || footer || (hasActions && resolvedDirection === "row");
2000
2000
  // Actions component to reuse. While loading, each provided action renders a circular
2001
2001
  // ghost sized to the CwButton icon footprint (2rem) - no interactive buttons.
2002
- const ActionsComponent = hasActions && !disabled ? (jsxRuntime.jsx("div", { className: styles$t.actions, children: isLoading ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [extraActions && jsxRuntime.jsx(CwSkeleton, { variant: "circle", height: "2rem" }), onEdit && jsxRuntime.jsx(CwSkeleton, { variant: "circle", height: "2rem" }), onDelete && jsxRuntime.jsx(CwSkeleton, { variant: "circle", height: "2rem" })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [extraActions ?? null, onEdit && jsxRuntime.jsx(CwButton, { variant: "icon", icon: "edit", onClick: onEdit }), onDelete && jsxRuntime.jsx(CwButton, { variant: "icon", icon: "delete", color: "danger", onClick: onDelete })] })) })) : null;
2002
+ const ActionsComponent = hasActions && !disabled ? (jsxRuntime.jsx("div", { className: styles$w.actions, children: isLoading ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [extraActions && jsxRuntime.jsx(CwSkeleton, { variant: "circle", height: "2rem" }), onEdit && jsxRuntime.jsx(CwSkeleton, { variant: "circle", height: "2rem" }), onDelete && jsxRuntime.jsx(CwSkeleton, { variant: "circle", height: "2rem" })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [extraActions ?? null, onEdit && jsxRuntime.jsx(CwButton, { variant: "icon", icon: "edit", onClick: onEdit }), onDelete && jsxRuntime.jsx(CwButton, { variant: "icon", icon: "delete", color: "danger", onClick: onDelete })] })) })) : null;
2003
2003
  return (jsxRuntime.jsxs("div", { ...(id && { id }), className: cardClassNames, ...(style && { style }), ...(clickable && !isLoading && {
2004
2004
  role: 'button',
2005
2005
  tabIndex: 0,
2006
2006
  onClick: handleClick,
2007
- }), "data-variant": variant, "data-direction": resolvedDirection, "aria-busy": isLoading || undefined, children: [isLoading ? (jsxRuntime.jsxs("header", { children: [jsxRuntime.jsx("div", { className: styles$t.headerContent, "data-align": resolvedAlign, children: jsxRuntime.jsx(CwSkeleton, { width: "8rem", height: "1.5em" }) }), resolvedDirection === "column" && ActionsComponent] })) : (hasHeader && (jsxRuntime.jsxs("header", { children: [(title || subtitle) && (jsxRuntime.jsxs("div", { className: styles$t.headerContent, "data-align": resolvedAlign, children: [title && jsxRuntime.jsx("h5", { children: title }), subtitle && jsxRuntime.jsx("strong", { children: subtitle })] })), resolvedDirection === "column" && ActionsComponent] }))), jsxRuntime.jsx("div", { className: styles$t.content, children: isLoading ? jsxRuntime.jsx(CwSkeleton, { count: normalizeSkeletonCount(skeletonLines, 3) }) : children }), hasFooter && (isLoading ? (jsxRuntime.jsx("footer", { children: jsxRuntime.jsx("div", { className: styles$t.footerTags, children: jsxRuntime.jsx(CwSkeleton, { variant: "rect", width: "4rem", height: "1.5em", radius: "1rem" }) }) })) : (jsxRuntime.jsxs("footer", { children: [hasChips && (jsxRuntime.jsx("div", { className: styles$t.footerTags, children: chips.map((chip, index) => (jsxRuntime.jsx(CwChip, { label: chip.label, color: chip.color, colorScheme: chip.colorScheme, className: styles$t.chip, ...(chip.customColor && { customColor: chip.customColor }), ...(chip.variant && { variant: chip.variant }), ...(chip.icon && { icon: chip.icon }) }, index))) })), footer && (jsxRuntime.jsx("div", { className: styles$t.footerContent, children: footer }))] }))), resolvedDirection === "row" && ActionsComponent] }));
2007
+ }), "data-variant": variant, "data-direction": resolvedDirection, "aria-busy": isLoading || undefined, children: [isLoading ? (jsxRuntime.jsxs("header", { children: [jsxRuntime.jsx("div", { className: styles$w.headerContent, "data-align": resolvedAlign, children: jsxRuntime.jsx(CwSkeleton, { width: "8rem", height: "1.5em" }) }), resolvedDirection === "column" && ActionsComponent] })) : (hasHeader && (jsxRuntime.jsxs("header", { children: [(title || subtitle) && (jsxRuntime.jsxs("div", { className: styles$w.headerContent, "data-align": resolvedAlign, children: [title && jsxRuntime.jsx("h5", { children: title }), subtitle && jsxRuntime.jsx("strong", { children: subtitle })] })), resolvedDirection === "column" && ActionsComponent] }))), jsxRuntime.jsx("div", { className: styles$w.content, children: isLoading ? jsxRuntime.jsx(CwSkeleton, { count: normalizeSkeletonCount(skeletonLines, 3) }) : children }), hasFooter && (isLoading ? (jsxRuntime.jsx("footer", { children: jsxRuntime.jsx("div", { className: styles$w.footerTags, children: jsxRuntime.jsx(CwSkeleton, { variant: "rect", width: "4rem", height: "1.5em", radius: "1rem" }) }) })) : (jsxRuntime.jsxs("footer", { children: [hasChips && (jsxRuntime.jsx("div", { className: styles$w.footerTags, children: chips.map((chip, index) => (jsxRuntime.jsx(CwChip, { label: chip.label, color: chip.color, colorScheme: chip.colorScheme, className: styles$w.chip, ...(chip.customColor && { customColor: chip.customColor }), ...(chip.variant && { variant: chip.variant }), ...(chip.icon && { icon: chip.icon }) }, index))) })), footer && (jsxRuntime.jsx("div", { className: styles$w.footerContent, children: footer }))] }))), resolvedDirection === "row" && ActionsComponent] }));
2008
2008
  };
2009
2009
 
2010
- var styles$s = {"cardContainer":"cw-card-list-module__cardContainer__l3YEh","pagination":"cw-card-list-module__pagination__5Ay78","pageInfo":"cw-card-list-module__pageInfo__uiMel","emptyState":"cw-card-list-module__emptyState__RlqiS"};
2010
+ var styles$v = {"cardContainer":"cw-card-list-module__cardContainer__l3YEh","pagination":"cw-card-list-module__pagination__5Ay78","pageInfo":"cw-card-list-module__pageInfo__uiMel","emptyState":"cw-card-list-module__emptyState__RlqiS"};
2011
2011
 
2012
2012
  /**
2013
2013
  * Option to display in the CwSelect
@@ -2102,10 +2102,10 @@ function CwCardList({ items, renderCard, pageSize = 10, layout = 'grid', default
2102
2102
  icon: sortDirection === 'asc' ? 'arrow-up' : 'arrow-down',
2103
2103
  onClick: () => setSortDirection(prev => prev === 'asc' ? 'desc' : 'asc'),
2104
2104
  title: `Sort ${sortDirection === 'asc' ? 'descending' : 'ascending'}`,
2105
- }, value: sortKey, onChange: (e) => handleSortChange(e.target.value), children: sortOptions.map(option => (jsxRuntime.jsx(CwOption, { value: option.key, children: option.label }, option.key))) }) })), isLoading ? (jsxRuntime.jsx("div", { className: `${styles$s.cardContainer}`, "data-layout": layout, style: gridStyle, "aria-busy": true, children: Array.from({ length: normalizeSkeletonCount(skeletonCards, 6) }, (_, index) => (jsxRuntime.jsx(CwCard, { isLoading: true, children: null }, `skeleton_${index}`))) })) : sortedItems.length === 0 ? (jsxRuntime.jsx("div", { className: styles$s.emptyState, children: emptyState || jsxRuntime.jsx("p", { children: "No items to display" }) })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: `${styles$s.cardContainer}`, "data-layout": layout, style: gridStyle, children: visibleItems.map((item, index) => (jsxRuntime.jsx(React.Fragment, { children: renderCard(item, index) }, keyExtractor ? keyExtractor(item, index) : index))) }), totalPages > 1 && (jsxRuntime.jsxs("div", { className: styles$s.pagination, children: [jsxRuntime.jsx(CwButton, { variant: "icon", icon: "chevron-left", disabled: currentPage === 1, onClick: () => setCurrentPage(p => Math.max(1, p - 1)) }), jsxRuntime.jsxs("span", { className: styles$s.pageInfo, children: [currentPage, " / ", totalPages] }), jsxRuntime.jsx(CwButton, { variant: "icon", icon: "chevron-right", disabled: currentPage === totalPages, onClick: () => setCurrentPage(p => Math.min(totalPages, p + 1)) })] }))] }))] }));
2105
+ }, value: sortKey, onChange: (e) => handleSortChange(e.target.value), children: sortOptions.map(option => (jsxRuntime.jsx(CwOption, { value: option.key, children: option.label }, option.key))) }) })), isLoading ? (jsxRuntime.jsx("div", { className: `${styles$v.cardContainer}`, "data-layout": layout, style: gridStyle, "aria-busy": true, children: Array.from({ length: normalizeSkeletonCount(skeletonCards, 6) }, (_, index) => (jsxRuntime.jsx(CwCard, { isLoading: true, children: null }, `skeleton_${index}`))) })) : sortedItems.length === 0 ? (jsxRuntime.jsx("div", { className: styles$v.emptyState, children: emptyState || jsxRuntime.jsx("p", { children: "No items to display" }) })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: `${styles$v.cardContainer}`, "data-layout": layout, style: gridStyle, children: visibleItems.map((item, index) => (jsxRuntime.jsx(React.Fragment, { children: renderCard(item, index) }, keyExtractor ? keyExtractor(item, index) : index))) }), totalPages > 1 && (jsxRuntime.jsxs("div", { className: styles$v.pagination, children: [jsxRuntime.jsx(CwButton, { variant: "icon", icon: "chevron-left", disabled: currentPage === 1, onClick: () => setCurrentPage(p => Math.max(1, p - 1)) }), jsxRuntime.jsxs("span", { className: styles$v.pageInfo, children: [currentPage, " / ", totalPages] }), jsxRuntime.jsx(CwButton, { variant: "icon", icon: "chevron-right", disabled: currentPage === totalPages, onClick: () => setCurrentPage(p => Math.min(totalPages, p + 1)) })] }))] }))] }));
2106
2106
  }
2107
2107
 
2108
- var styles$r = {"cw-accordion":"cw-accordion-module__cw-accordion__ErvlW","cw-accordion-body":"cw-accordion-module__cw-accordion-body__xlI8b"};
2108
+ var styles$u = {"cw-accordion":"cw-accordion-module__cw-accordion__ErvlW","cw-accordion-body":"cw-accordion-module__cw-accordion-body__xlI8b"};
2109
2109
 
2110
2110
  /**
2111
2111
  * Legacy collapsible section with its own header markup.
@@ -2120,7 +2120,7 @@ function CwAccordionContainer(CwelltAccordionContainerProps) {
2120
2120
  setVisible_accordionBody(!isVisible_accordionBody);
2121
2121
  };
2122
2122
  // #endregion
2123
- return (jsxRuntime.jsxs("div", { className: styles$r["cw-accordion"], style: CwelltAccordionContainerProps.style, "data-open": isVisible_accordionBody, children: [jsxRuntime.jsxs("header", { onClick: () => showAccordionBody(), children: [jsxRuntime.jsx("div", { children: CwelltAccordionContainerProps.desc_text }), jsxRuntime.jsx("button", { className: "cw-button-icon" })] }), jsxRuntime.jsx("div", { className: styles$r["cw-accordion-body"], children: CwelltAccordionContainerProps.children })] }));
2123
+ return (jsxRuntime.jsxs("div", { className: styles$u["cw-accordion"], style: CwelltAccordionContainerProps.style, "data-open": isVisible_accordionBody, children: [jsxRuntime.jsxs("header", { onClick: () => showAccordionBody(), children: [jsxRuntime.jsx("div", { children: CwelltAccordionContainerProps.desc_text }), jsxRuntime.jsx("button", { className: "cw-button-icon" })] }), jsxRuntime.jsx("div", { className: styles$u["cw-accordion-body"], children: CwelltAccordionContainerProps.children })] }));
2124
2124
  }
2125
2125
 
2126
2126
  /*
@@ -2399,7 +2399,7 @@ function CwTable({ columns, data, pagination = false, pageSizeOptions = [5, 10,
2399
2399
  }, min: 1, max: totalPages }), jsxRuntime.jsx("span", { children: "/" }), jsxRuntime.jsx("span", { children: totalPages }), jsxRuntime.jsx(CwButton, { onClick: () => handlePageChange(page + 1), disabled: page === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right" }), jsxRuntime.jsx(CwButton, { onClick: () => handlePageChange(totalPages), disabled: page === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right-double" })] })] }))] }));
2400
2400
  }
2401
2401
 
2402
- var styles$q = {"dropIndicator":"cw-sortable-table-module__dropIndicator__ov-Jz","dragging":"cw-sortable-table-module__dragging__MrLrz","saveBar":"cw-sortable-table-module__saveBar__3OdoZ cw-flex-row cw-align-center-center cw-gap-small"};
2402
+ var styles$t = {"dropIndicator":"cw-sortable-table-module__dropIndicator__ov-Jz","dragging":"cw-sortable-table-module__dragging__MrLrz","saveBar":"cw-sortable-table-module__saveBar__3OdoZ cw-flex-row cw-align-center-center cw-gap-small"};
2403
2403
 
2404
2404
  /**
2405
2405
  * Hook that provides state management for CwSortableTable.
@@ -2462,7 +2462,7 @@ function useSortableTable(initialItems) {
2462
2462
  }
2463
2463
 
2464
2464
  // ─── Drop indicator row ───────────────────────────────────────────────────────
2465
- const DropIndicatorRow = ({ colSpan }) => (jsxRuntime.jsx("tr", { className: styles$q.dropIndicator, "aria-hidden": true, children: jsxRuntime.jsx("td", { colSpan: colSpan, children: jsxRuntime.jsx("div", {}) }) }));
2465
+ const DropIndicatorRow = ({ colSpan }) => (jsxRuntime.jsx("tr", { className: styles$t.dropIndicator, "aria-hidden": true, children: jsxRuntime.jsx("td", { colSpan: colSpan, children: jsxRuntime.jsx("div", {}) }) }));
2466
2466
  // ─── Loading skeleton ─────────────────────────────────────────────────────────
2467
2467
  // Plain td cells (no local class): the ghost cells get the same global cw-table
2468
2468
  // padding as real body cells, so row heights match the loaded rows exactly.
@@ -2565,11 +2565,11 @@ function CwSortableTable({ columns, data, rowKey = "key", onReorder, loading = f
2565
2565
  return items.map((item, index) => {
2566
2566
  const key = item[rowKey];
2567
2567
  const isDragging = draggedItem?.[rowKey] === key;
2568
- return (jsxRuntime.jsxs(React.Fragment, { children: [dropIndicatorIndex === index && (jsxRuntime.jsx(DropIndicatorRow, { colSpan: totalCols })), jsxRuntime.jsxs("tr", { draggable: true, onDragStart: (e) => handleDragStart(e, item), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, className: isDragging ? styles$q.dragging : "", children: [showHandle && (jsxRuntime.jsx("td", { className: "cw-table-col-action", children: jsxRuntime.jsx(CwIcon, { iconId: "grip-dots", color: "neutral", style: { opacity: 0.75 } }) })), columns.map(col => (jsxRuntime.jsx("td", { className: col.className ?? "", style: col.width ? { width: col.width } : undefined, children: renderCell(item, col) }, `${String(key)}_${col.key}`)))] }), index === items.length - 1 && dropIndicatorIndex === items.length && (jsxRuntime.jsx(DropIndicatorRow, { colSpan: totalCols }))] }, String(key)));
2568
+ return (jsxRuntime.jsxs(React.Fragment, { children: [dropIndicatorIndex === index && (jsxRuntime.jsx(DropIndicatorRow, { colSpan: totalCols })), jsxRuntime.jsxs("tr", { draggable: true, onDragStart: (e) => handleDragStart(e, item), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, className: isDragging ? styles$t.dragging : "", children: [showHandle && (jsxRuntime.jsx("td", { className: "cw-table-col-action", children: jsxRuntime.jsx(CwIcon, { iconId: "grip-dots", color: "neutral", style: { opacity: 0.75 } }) })), columns.map(col => (jsxRuntime.jsx("td", { className: col.className ?? "", style: col.width ? { width: col.width } : undefined, children: renderCell(item, col) }, `${String(key)}_${col.key}`)))] }), index === items.length - 1 && dropIndicatorIndex === items.length && (jsxRuntime.jsx(DropIndicatorRow, { colSpan: totalCols }))] }, String(key)));
2569
2569
  });
2570
2570
  };
2571
2571
  // ── Render ──────────────────────────────────────────────────────────────
2572
- return (jsxRuntime.jsxs("div", { className: `cw-table-container ${className ?? ""}`, style: containerStyle, "aria-busy": loading || undefined, children: [jsxRuntime.jsxs("table", { className: `cw-table cw-sortable-table ${tableClassName ?? ""}`, style: { width: "100%" }, children: [jsxRuntime.jsx("thead", { children: jsxRuntime.jsxs("tr", { children: [showHandle && jsxRuntime.jsx("th", { className: "cw-table-col-action" }), columns.map(col => (jsxRuntime.jsx("th", { className: col.className ?? "", style: col.width ? { width: col.width, minWidth: 50 } : undefined, children: col.title }, col.key)))] }) }), jsxRuntime.jsx("tbody", { children: renderBody() })] }), !loading && hasChanges && (jsxRuntime.jsxs("footer", { className: styles$q.saveBar, children: [jsxRuntime.jsx(CwButton, { variant: "outline", color: "neutral", icon: "undo", text: discardLabel, onClick: handleDiscard }), jsxRuntime.jsx(CwButton, { variant: "solid", color: "primary", icon: "save", text: saveLabel, onClick: () => handleSave(onReorder) })] }))] }));
2572
+ return (jsxRuntime.jsxs("div", { className: `cw-table-container ${className ?? ""}`, style: containerStyle, "aria-busy": loading || undefined, children: [jsxRuntime.jsxs("table", { className: `cw-table cw-sortable-table ${tableClassName ?? ""}`, style: { width: "100%" }, children: [jsxRuntime.jsx("thead", { children: jsxRuntime.jsxs("tr", { children: [showHandle && jsxRuntime.jsx("th", { className: "cw-table-col-action" }), columns.map(col => (jsxRuntime.jsx("th", { className: col.className ?? "", style: col.width ? { width: col.width, minWidth: 50 } : undefined, children: col.title }, col.key)))] }) }), jsxRuntime.jsx("tbody", { children: renderBody() })] }), !loading && hasChanges && (jsxRuntime.jsxs("footer", { className: styles$t.saveBar, children: [jsxRuntime.jsx(CwButton, { variant: "outline", color: "neutral", icon: "undo", text: discardLabel, onClick: handleDiscard }), jsxRuntime.jsx(CwButton, { variant: "solid", color: "primary", icon: "save", text: saveLabel, onClick: () => handleSave(onReorder) })] }))] }));
2573
2573
  }
2574
2574
 
2575
2575
  /**
@@ -2770,7 +2770,7 @@ function CwTableServerSide({ columns, data, totalItems, pagination = false, page
2770
2770
  }, min: 1, max: totalPages }), jsxRuntime.jsx("span", { children: "/" }), jsxRuntime.jsx("span", { children: totalPages }), jsxRuntime.jsx(CwButton, { onClick: () => handlePageChange(state.page + 1), disabled: state.page === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right" }), jsxRuntime.jsx(CwButton, { onClick: () => handlePageChange(totalPages), disabled: state.page === totalPages || totalPages <= 1, variant: "icon", icon: "chevron-right-double" })] })] }))] }));
2771
2771
  }
2772
2772
 
2773
- var styles$p = {"cw-tabs":"cw-tabs-module__cw-tabs__1pmji","cw-tabs-content":"cw-tabs-module__cw-tabs-content__HTp8d"};
2773
+ var styles$s = {"cw-tabs":"cw-tabs-module__cw-tabs__1pmji","cw-tabs-content":"cw-tabs-module__cw-tabs-content__HTp8d"};
2774
2774
 
2775
2775
  const BADGE_COLOR_SCHEMES = ['primary', 'danger', 'warning', 'success', 'info', 'neutral'];
2776
2776
  function isBadgeColorScheme(value) {
@@ -2824,11 +2824,11 @@ function CwTabs(CwTabsProps) {
2824
2824
  const tabsListStyle = position === 'left' && CwTabsProps.tabsListWidth
2825
2825
  ? { minWidth: CwTabsProps.tabsListWidth }
2826
2826
  : undefined;
2827
- return (jsxRuntime.jsxs("div", { id: CwTabsProps.id, "data-testid": CwTabsProps.testId, className: styles$p['cw-tabs'] + (CwTabsProps.className ? ` ${CwTabsProps.className}` : "") + "", style: CwTabsProps.style, "data-tabs-position": position, children: [jsxRuntime.jsx("ul", { style: tabsListStyle, children: CwTabsProps.tabs.map(tab => {
2827
+ return (jsxRuntime.jsxs("div", { id: CwTabsProps.id, "data-testid": CwTabsProps.testId, className: styles$s['cw-tabs'] + (CwTabsProps.className ? ` ${CwTabsProps.className}` : "") + "", style: CwTabsProps.style, "data-tabs-position": position, children: [jsxRuntime.jsx("ul", { style: tabsListStyle, children: CwTabsProps.tabs.map(tab => {
2828
2828
  const badgeScheme = tab.badgeColor && isBadgeColorScheme(tab.badgeColor) ? tab.badgeColor : undefined;
2829
2829
  const rawBadgeColor = tab.badgeColor && !badgeScheme ? tab.badgeColor : undefined;
2830
2830
  return (jsxRuntime.jsxs("li", { className: `${tab.key === activeTab ? "cw-tab-active" : ""}`, onClick: () => handleTabClick(tab), "data-active": tab.key === activeTab, "data-tab-key": tab.key, "data-badge-themed": tab.badgeColor ? "true" : undefined, children: [jsxRuntime.jsx(TabIcon, { icon: tab.icon }), tab.title, (tab.badge !== undefined || tab.badgeColor) && (jsxRuntime.jsx(CwBadge, { count: typeof tab.badge === 'number' ? tab.badge : undefined, content: typeof tab.badge === 'string' ? tab.badge : undefined, size: "medium", color: badgeScheme ?? 'primary', variant: badgeScheme ? 'solid' : 'soft', style: rawBadgeColor ? { backgroundColor: rawBadgeColor, color: getContrastColor(rawBadgeColor) } : undefined }))] }, tab.key));
2831
- }) }), jsxRuntime.jsx("div", { className: styles$p['cw-tabs-content'], "data-active-tab-key": activeTab ?? undefined, style: CwTabsProps.contentHeight ? { '--tabs-height': CwTabsProps.contentHeight } : undefined, children: activeTab !== null && CwTabsProps.tabs.find(tab => tab.key === activeTab)?.content })] }));
2831
+ }) }), jsxRuntime.jsx("div", { className: styles$s['cw-tabs-content'], "data-active-tab-key": activeTab ?? undefined, style: CwTabsProps.contentHeight ? { '--tabs-height': CwTabsProps.contentHeight } : undefined, children: activeTab !== null && CwTabsProps.tabs.find(tab => tab.key === activeTab)?.content })] }));
2832
2832
  }
2833
2833
 
2834
2834
  /**
@@ -2856,7 +2856,7 @@ const CwExpandable = ({ briefing, onToggle, onOpen, onClose, children, ...detail
2856
2856
  return (jsxRuntime.jsxs("details", { ref: myRef, ...detailsProps, className: "cw-expandable", children: [jsxRuntime.jsx("summary", { children: briefing }), children && jsxRuntime.jsx("section", { children: children })] }));
2857
2857
  };
2858
2858
 
2859
- var styles$o = {"cw-master-detail":"cw-master-detail-module__cw-master-detail__O8-FA","resizer":"cw-master-detail-module__resizer__hvGhL","detail":"cw-master-detail-module__detail__BG4Dm","skeletonRow":"cw-master-detail-module__skeletonRow__6BUgt","detailSkeleton":"cw-master-detail-module__detailSkeleton__GcDS4","detail-empty":"cw-master-detail-module__detail-empty__KFScK"};
2859
+ var styles$r = {"cw-master-detail":"cw-master-detail-module__cw-master-detail__O8-FA","resizer":"cw-master-detail-module__resizer__hvGhL","detail":"cw-master-detail-module__detail__BG4Dm","skeletonRow":"cw-master-detail-module__skeletonRow__6BUgt","detailSkeleton":"cw-master-detail-module__detailSkeleton__GcDS4","detail-empty":"cw-master-detail-module__detail-empty__KFScK"};
2860
2860
 
2861
2861
  /*
2862
2862
  * Fixed rem widths for the ghosts: the master rows and detail panel size their
@@ -2900,12 +2900,12 @@ const CwMasterDetail = ({ id, className, style, items, selectedKey, onSelect, de
2900
2900
  document.body.style.userSelect = '';
2901
2901
  };
2902
2902
  }, [isResizing, minMasterWidth, maxMasterWidth]);
2903
- const rootClassName = [styles$o['cw-master-detail'], className].filter(Boolean).join(' ');
2903
+ const rootClassName = [styles$r['cw-master-detail'], className].filter(Boolean).join(' ');
2904
2904
  return (jsxRuntime.jsxs("div", { id: id, ref: containerRef, className: rootClassName, style: style, "aria-busy": loading || undefined, children: [jsxRuntime.jsxs("aside", { style: { width: masterWidth, minWidth: masterWidth }, children: [showSearch && (jsxRuntime.jsx("search", { children: jsxRuntime.jsx("input", { type: "text", placeholder: searchPlaceholder, onChange: (e) => onSearch?.(e.target.value) }) })), masterHeader && (jsxRuntime.jsx("header", { children: masterHeader })), jsxRuntime.jsx("ul", { children: loading
2905
- ? Array.from({ length: skeletonRows }, (_unused, rowIndex) => (jsxRuntime.jsxs("li", { "aria-hidden": "true", children: [jsxRuntime.jsx(CwSkeleton, { variant: "circle", height: "2rem" }), jsxRuntime.jsxs("div", { className: styles$o.skeletonRow, children: [jsxRuntime.jsx(CwSkeleton, { variant: "text", width: MASTER_TITLE_WIDTHS[rowIndex % MASTER_TITLE_WIDTHS.length] }), jsxRuntime.jsx(CwSkeleton, { variant: "text", width: MASTER_SUBTITLE_WIDTH })] })] }, `skeleton_${rowIndex}`)))
2906
- : items.map((item) => (jsxRuntime.jsx("li", { "data-master-key": item.key, "data-selected": item.key === selectedKey, "data-disabled": item.disabled, onClick: () => onSelect?.(item.key), children: item.content }, item.key))) }), masterFooter && (jsxRuntime.jsx("footer", { children: masterFooter }))] }), resizable && (jsxRuntime.jsx("div", { className: styles$o.resizer, "data-resizing": isResizing, onMouseDown: handleMouseDown })), jsxRuntime.jsx("section", { className: styles$o.detail, children: loading ? (jsxRuntime.jsxs("div", { className: styles$o.detailSkeleton, "aria-hidden": "true", children: [jsxRuntime.jsx(CwSkeleton, { variant: "text", width: "14rem", height: "1.5em" }), jsxRuntime.jsx(CwSkeleton, { variant: "text", width: "22rem" }), jsxRuntime.jsx(CwSkeleton, { variant: "text", width: "18rem" }), jsxRuntime.jsx(CwSkeleton, { variant: "text", width: "20rem" })] })) : selectedKey && detailContent
2905
+ ? Array.from({ length: skeletonRows }, (_unused, rowIndex) => (jsxRuntime.jsxs("li", { "aria-hidden": "true", children: [jsxRuntime.jsx(CwSkeleton, { variant: "circle", height: "2rem" }), jsxRuntime.jsxs("div", { className: styles$r.skeletonRow, children: [jsxRuntime.jsx(CwSkeleton, { variant: "text", width: MASTER_TITLE_WIDTHS[rowIndex % MASTER_TITLE_WIDTHS.length] }), jsxRuntime.jsx(CwSkeleton, { variant: "text", width: MASTER_SUBTITLE_WIDTH })] })] }, `skeleton_${rowIndex}`)))
2906
+ : items.map((item) => (jsxRuntime.jsx("li", { "data-master-key": item.key, "data-selected": item.key === selectedKey, "data-disabled": item.disabled, onClick: () => onSelect?.(item.key), children: item.content }, item.key))) }), masterFooter && (jsxRuntime.jsx("footer", { children: masterFooter }))] }), resizable && (jsxRuntime.jsx("div", { className: styles$r.resizer, "data-resizing": isResizing, onMouseDown: handleMouseDown })), jsxRuntime.jsx("section", { className: styles$r.detail, children: loading ? (jsxRuntime.jsxs("div", { className: styles$r.detailSkeleton, "aria-hidden": "true", children: [jsxRuntime.jsx(CwSkeleton, { variant: "text", width: "14rem", height: "1.5em" }), jsxRuntime.jsx(CwSkeleton, { variant: "text", width: "22rem" }), jsxRuntime.jsx(CwSkeleton, { variant: "text", width: "18rem" }), jsxRuntime.jsx(CwSkeleton, { variant: "text", width: "20rem" })] })) : selectedKey && detailContent
2907
2907
  ? detailContent
2908
- : (jsxRuntime.jsx("div", { className: styles$o['detail-empty'], children: emptyDetail ?? 'Select an item to view details' })) })] }));
2908
+ : (jsxRuntime.jsx("div", { className: styles$r['detail-empty'], children: emptyDetail ?? 'Select an item to view details' })) })] }));
2909
2909
  };
2910
2910
 
2911
2911
  /*
@@ -2945,7 +2945,7 @@ const CwKeyValueList = ({ items, className = "", emptyValue = "-", direction = "
2945
2945
  return (jsxRuntime.jsx("dl", { className: `cw-keyvalue-list ${className}`, "data-direction": groupLayout?.direction, "data-align": groupLayout?.align, "data-justify": groupLayout?.justify, "data-gap": groupLayout?.gap, "aria-busy": loading || undefined, ...htmlProps, children: renderItems() }));
2946
2946
  };
2947
2947
 
2948
- var styles$n = {"sortableList":"cw-sortable-list-module__sortableList__PyLO-","sortableItem":"cw-sortable-list-module__sortableItem__FAnn2","readOnly":"cw-sortable-list-module__readOnly__r7GcH","dragging":"cw-sortable-list-module__dragging__MD715","moved":"cw-sortable-list-module__moved__sE6-N","expandedContent":"cw-sortable-list-module__expandedContent__Kocna","sortableHandle":"cw-sortable-list-module__sortableHandle__HvYBK","sortableContent":"cw-sortable-list-module__sortableContent__C6JhR","sortableTitle":"cw-sortable-list-module__sortableTitle__EgWXr","sortableExtraContent":"cw-sortable-list-module__sortableExtraContent__s4LSv","sortableActions":"cw-sortable-list-module__sortableActions__gwQOU","dropIndicator":"cw-sortable-list-module__dropIndicator__MNSF-","emptyMessage":"cw-sortable-list-module__emptyMessage__gMpaL"};
2948
+ var styles$q = {"sortableList":"cw-sortable-list-module__sortableList__PyLO-","sortableItem":"cw-sortable-list-module__sortableItem__FAnn2","readOnly":"cw-sortable-list-module__readOnly__r7GcH","dragging":"cw-sortable-list-module__dragging__MD715","moved":"cw-sortable-list-module__moved__sE6-N","expandedContent":"cw-sortable-list-module__expandedContent__Kocna","sortableHandle":"cw-sortable-list-module__sortableHandle__HvYBK","sortableContent":"cw-sortable-list-module__sortableContent__C6JhR","sortableTitle":"cw-sortable-list-module__sortableTitle__EgWXr","sortableExtraContent":"cw-sortable-list-module__sortableExtraContent__s4LSv","sortableActions":"cw-sortable-list-module__sortableActions__gwQOU","dropIndicator":"cw-sortable-list-module__dropIndicator__MNSF-","emptyMessage":"cw-sortable-list-module__emptyMessage__gMpaL"};
2949
2949
 
2950
2950
  function CwSortableList({ items, onReorder, renderItem, className = '', movedItems = new Set(), emptyMessage = "No elements to show", readOnly = false, maxHeight = "300px", }) {
2951
2951
  const [draggedItem, setDraggedItem] = React.useState(null);
@@ -3008,15 +3008,15 @@ function CwSortableList({ items, onReorder, renderItem, className = '', movedIte
3008
3008
  }
3009
3009
  };
3010
3010
  if (items.length === 0) {
3011
- return (jsxRuntime.jsx("div", { className: `${styles$n.sortableList} ${styles$n.emptyState} ${className}`, children: jsxRuntime.jsx("div", { className: styles$n.emptyMessage, children: emptyMessage }) }));
3011
+ return (jsxRuntime.jsx("div", { className: `${styles$q.sortableList} ${styles$q.emptyState} ${className}`, children: jsxRuntime.jsx("div", { className: styles$q.emptyMessage, children: emptyMessage }) }));
3012
3012
  }
3013
- return (jsxRuntime.jsx("div", { className: `${styles$n.sortableList} ${className}`, style: { maxHeight }, children: items.map((item, index) => {
3013
+ return (jsxRuntime.jsx("div", { className: `${styles$q.sortableList} ${className}`, style: { maxHeight }, children: items.map((item, index) => {
3014
3014
  const { title, extraContent, actions, showHandle = true, expandedContent } = renderItem(item);
3015
3015
  const isDragging = draggedItem?.id === item.id;
3016
3016
  const isMoved = movedItems.has(item.id);
3017
3017
  const canExpand = Boolean(expandedContent);
3018
3018
  const isExpanded = expandedItems.has(item.id);
3019
- return (jsxRuntime.jsxs(React.Fragment, { children: [dropIndicatorIndex === index && jsxRuntime.jsx("div", { className: styles$n.dropIndicator }), jsxRuntime.jsxs("div", { className: `${styles$n.sortableItem} ${isDragging ? styles$n.dragging : ''} ${isMoved ? styles$n.moved : ''} ${readOnly ? styles$n.readOnly : ''}`, draggable: !readOnly, onDragStart: (e) => handleDragStart(e, item), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, children: [jsxRuntime.jsxs("header", { children: [canExpand ? (jsxRuntime.jsx(CwButton, { variant: "icon", onClick: () => toggleExpanded(item.id), type: "button", title: isExpanded ? "Collapse" : "Expand", icon: isExpanded ? "chevron-up" : "chevron-down" })) : showHandle ? (jsxRuntime.jsx("div", { className: styles$n.sortableHandle, children: jsxRuntime.jsx(CwIcon, { iconId: "grip-dots" }) })) : null, jsxRuntime.jsxs("div", { className: styles$n.sortableContent, children: [jsxRuntime.jsx("div", { className: styles$n.sortableTitle, children: title }), extraContent && jsxRuntime.jsx("div", { className: styles$n.sortableExtraContent, children: extraContent })] }), jsxRuntime.jsx("div", { className: styles$n.sortableActions, children: actions })] }), isExpanded && expandedContent && (jsxRuntime.jsx("div", { className: styles$n.expandedContent, children: expandedContent }))] }), !readOnly && dropIndicatorIndex === items.length && index === items.length - 1 && (jsxRuntime.jsx("div", { className: styles$n.dropIndicator }))] }, item.id));
3019
+ return (jsxRuntime.jsxs(React.Fragment, { children: [dropIndicatorIndex === index && jsxRuntime.jsx("div", { className: styles$q.dropIndicator }), jsxRuntime.jsxs("div", { className: `${styles$q.sortableItem} ${isDragging ? styles$q.dragging : ''} ${isMoved ? styles$q.moved : ''} ${readOnly ? styles$q.readOnly : ''}`, draggable: !readOnly, onDragStart: (e) => handleDragStart(e, item), onDragOver: (e) => handleDragOver(e, index), onDragEnd: handleDragEnd, children: [jsxRuntime.jsxs("header", { children: [canExpand ? (jsxRuntime.jsx(CwButton, { variant: "icon", onClick: () => toggleExpanded(item.id), type: "button", title: isExpanded ? "Collapse" : "Expand", icon: isExpanded ? "chevron-up" : "chevron-down" })) : showHandle ? (jsxRuntime.jsx("div", { className: styles$q.sortableHandle, children: jsxRuntime.jsx(CwIcon, { iconId: "grip-dots" }) })) : null, jsxRuntime.jsxs("div", { className: styles$q.sortableContent, children: [jsxRuntime.jsx("div", { className: styles$q.sortableTitle, children: title }), extraContent && jsxRuntime.jsx("div", { className: styles$q.sortableExtraContent, children: extraContent })] }), jsxRuntime.jsx("div", { className: styles$q.sortableActions, children: actions })] }), isExpanded && expandedContent && (jsxRuntime.jsx("div", { className: styles$q.expandedContent, children: expandedContent }))] }), !readOnly && dropIndicatorIndex === items.length && index === items.length - 1 && (jsxRuntime.jsx("div", { className: styles$q.dropIndicator }))] }, item.id));
3020
3020
  }) }));
3021
3021
  }
3022
3022
 
@@ -3143,7 +3143,7 @@ const CwTableGrouped = props => {
3143
3143
  group.rows.map((child, j) => (jsxRuntime.jsx("tr", { "data-row": true, "data-row-last-of-group": j == group.rows.length - 1, children: child.cells.map((cell, k) => (jsxRuntime.jsx("td", { children: cell.content }, k))) }, j)))] }, i))) }), jsxRuntime.jsx("tfoot", {})] }) }));
3144
3144
  };
3145
3145
 
3146
- var styles$m = {"fileUploadContainer":"cw-file-upload-multiple-module__fileUploadContainer__liEc1","hiddenInput":"cw-file-upload-multiple-module__hiddenInput__TZBBI","uploadArea":"cw-file-upload-multiple-module__uploadArea__DdOhs","uploadAreaDisabled":"cw-file-upload-multiple-module__uploadAreaDisabled__VWeFX","uploadTitle":"cw-file-upload-multiple-module__uploadTitle__gjRk8","uploadSubtitle":"cw-file-upload-multiple-module__uploadSubtitle__Z0S5t","filesContainer":"cw-file-upload-multiple-module__filesContainer__g44PY","fileItem":"cw-file-upload-multiple-module__fileItem__w27Dg","fileIcon":"cw-file-upload-multiple-module__fileIcon__iJJUX","fileExtension":"cw-file-upload-multiple-module__fileExtension__vOuHv","fileInfo":"cw-file-upload-multiple-module__fileInfo__R5ZTv","fileName":"cw-file-upload-multiple-module__fileName__DjepK","fileSize":"cw-file-upload-multiple-module__fileSize__b8GSm","smallButton":"cw-file-upload-multiple-module__smallButton__siUAh"};
3146
+ var styles$p = {"fileUploadContainer":"cw-file-upload-multiple-module__fileUploadContainer__liEc1","hiddenInput":"cw-file-upload-multiple-module__hiddenInput__TZBBI","uploadArea":"cw-file-upload-multiple-module__uploadArea__DdOhs","uploadAreaDisabled":"cw-file-upload-multiple-module__uploadAreaDisabled__VWeFX","uploadTitle":"cw-file-upload-multiple-module__uploadTitle__gjRk8","uploadSubtitle":"cw-file-upload-multiple-module__uploadSubtitle__Z0S5t","filesContainer":"cw-file-upload-multiple-module__filesContainer__g44PY","fileItem":"cw-file-upload-multiple-module__fileItem__w27Dg","fileIcon":"cw-file-upload-multiple-module__fileIcon__iJJUX","fileExtension":"cw-file-upload-multiple-module__fileExtension__vOuHv","fileInfo":"cw-file-upload-multiple-module__fileInfo__R5ZTv","fileName":"cw-file-upload-multiple-module__fileName__DjepK","fileSize":"cw-file-upload-multiple-module__fileSize__b8GSm","smallButton":"cw-file-upload-multiple-module__smallButton__siUAh"};
3147
3147
 
3148
3148
  const DEFAULT_LABELS$1 = {
3149
3149
  uploadDisabled: 'Upload disabled',
@@ -3329,12 +3329,12 @@ function CwFileUploadMultiple(fileUploadProps) {
3329
3329
  }
3330
3330
  }
3331
3331
  };
3332
- return (jsxRuntime.jsxs("div", { className: `${styles$m.fileUploadContainer} ${fileUploadProps.className}`, children: [jsxRuntime.jsx("input", { ref: fileInputRef, type: "file", name: fileUploadProps.name, accept: fileUploadProps.accept, multiple: fileUploadProps.multiple, onChange: handleFileSelectInternal, disabled: fileUploadProps.disabled, "aria-label": "files", className: styles$m.hiddenInput }), selectedFiles.length === 0 && !existingFile ? (jsxRuntime.jsxs("div", { className: `${styles$m.uploadArea} ${fileUploadProps.disabled ? styles$m.uploadAreaDisabled : ''}`, onDragOver: handleDragOver, onDrop: handleDrop, onClick: !fileUploadProps.disabled ? handleButtonClick : undefined, children: [jsxRuntime.jsx(CwIcon, { iconId: "upload" }), jsxRuntime.jsx("p", { className: `${styles$m.uploadTitle}`, children: fileUploadProps.disabled ? labels.uploadDisabled : labels.clickToUpload }), jsxRuntime.jsxs("p", { className: `${styles$m.uploadSubtitle}`, children: [fileUploadProps.accept ? labels.acceptedFiles(fileUploadProps.accept) : labels.allTypesAccepted, !fileUploadProps.multiple && ` ${labels.singleFileOnly}`] })] })) : selectedFiles.length === 0 && existingFile ? (jsxRuntime.jsxs("div", { className: styles$m.filesContainer, children: [jsxRuntime.jsxs("div", { className: styles$m.fileItem, children: [jsxRuntime.jsxs("div", { className: styles$m.fileIcon, children: [jsxRuntime.jsx(CwIcon, { iconId: "page" }), jsxRuntime.jsx("span", { className: styles$m.fileExtension, children: getFileExtension(existingFile) })] }), jsxRuntime.jsx("div", { className: styles$m.fileInfo, children: jsxRuntime.jsx("p", { className: styles$m.fileName, children: existingFile }) }), jsxRuntime.jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => {
3332
+ return (jsxRuntime.jsxs("div", { className: `${styles$p.fileUploadContainer} ${fileUploadProps.className}`, children: [jsxRuntime.jsx("input", { ref: fileInputRef, type: "file", name: fileUploadProps.name, accept: fileUploadProps.accept, multiple: fileUploadProps.multiple, onChange: handleFileSelectInternal, disabled: fileUploadProps.disabled, "aria-label": "files", className: styles$p.hiddenInput }), selectedFiles.length === 0 && !existingFile ? (jsxRuntime.jsxs("div", { className: `${styles$p.uploadArea} ${fileUploadProps.disabled ? styles$p.uploadAreaDisabled : ''}`, onDragOver: handleDragOver, onDrop: handleDrop, onClick: !fileUploadProps.disabled ? handleButtonClick : undefined, children: [jsxRuntime.jsx(CwIcon, { iconId: "upload" }), jsxRuntime.jsx("p", { className: `${styles$p.uploadTitle}`, children: fileUploadProps.disabled ? labels.uploadDisabled : labels.clickToUpload }), jsxRuntime.jsxs("p", { className: `${styles$p.uploadSubtitle}`, children: [fileUploadProps.accept ? labels.acceptedFiles(fileUploadProps.accept) : labels.allTypesAccepted, !fileUploadProps.multiple && ` ${labels.singleFileOnly}`] })] })) : selectedFiles.length === 0 && existingFile ? (jsxRuntime.jsxs("div", { className: styles$p.filesContainer, children: [jsxRuntime.jsxs("div", { className: styles$p.fileItem, children: [jsxRuntime.jsxs("div", { className: styles$p.fileIcon, children: [jsxRuntime.jsx(CwIcon, { iconId: "page" }), jsxRuntime.jsx("span", { className: styles$p.fileExtension, children: getFileExtension(existingFile) })] }), jsxRuntime.jsx("div", { className: styles$p.fileInfo, children: jsxRuntime.jsx("p", { className: styles$p.fileName, children: existingFile }) }), jsxRuntime.jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => {
3333
3333
  setExistingFile(undefined);
3334
3334
  if (fileUploadProps.onSelect) {
3335
3335
  fileUploadProps.onSelect(null);
3336
3336
  }
3337
- }, disabled: fileUploadProps.disabled, className: styles$m.smallButton })] }), jsxRuntime.jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled })] })) : (jsxRuntime.jsxs("div", { className: styles$m.filesContainer, children: [jsxRuntime.jsxs("header", { className: "cw-flex-row cw-align-between-center cw-flex-wrap", children: [jsxRuntime.jsx("small", { className: styles$m.filesCount, children: fileUploadProps.statusText ?? labels.filesSelected(selectedFiles.length) }), jsxRuntime.jsxs("div", { className: "cw-flex-row", children: [fileUploadProps.onConfirm && selectedFiles.length > 0 && (jsxRuntime.jsx(CwButton, { onClick: () => {
3337
+ }, disabled: fileUploadProps.disabled, className: styles$p.smallButton })] }), jsxRuntime.jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled })] })) : (jsxRuntime.jsxs("div", { className: styles$p.filesContainer, children: [jsxRuntime.jsxs("header", { className: "cw-flex-row cw-align-between-center cw-flex-wrap", children: [jsxRuntime.jsx("small", { className: styles$p.filesCount, children: fileUploadProps.statusText ?? labels.filesSelected(selectedFiles.length) }), jsxRuntime.jsxs("div", { className: "cw-flex-row", children: [fileUploadProps.onConfirm && selectedFiles.length > 0 && (jsxRuntime.jsx(CwButton, { onClick: () => {
3338
3338
  let files = fileInputRef.current?.files ?? null;
3339
3339
  if (!files) {
3340
3340
  const dataTransfer = new DataTransfer();
@@ -3342,7 +3342,7 @@ function CwFileUploadMultiple(fileUploadProps) {
3342
3342
  files = dataTransfer.files;
3343
3343
  }
3344
3344
  fileUploadProps.onConfirm?.(files);
3345
- }, disabled: fileUploadProps.disabled || fileUploadProps.confirmDisabled, icon: "upload", text: fileUploadProps.confirmLabel ?? labels.upload })), !fileUploadProps.hideClearAll && (jsxRuntime.jsx(CwButton, { onClick: removeAllFiles, disabled: fileUploadProps.disabled, color: "danger", variant: "outline", icon: "delete", text: labels.clearAll }))] })] }), selectedFiles.map((file, index) => (jsxRuntime.jsxs("div", { className: styles$m.fileItem, children: [jsxRuntime.jsxs("div", { className: styles$m.fileIcon, children: [jsxRuntime.jsx(CwIcon, { iconId: "page" }), jsxRuntime.jsx("span", { className: styles$m.fileExtension, children: getFileExtension(file.name) })] }), jsxRuntime.jsxs("div", { className: styles$m.fileInfo, children: [jsxRuntime.jsx("p", { className: styles$m.fileName, children: file.name }), jsxRuntime.jsxs("p", { className: styles$m.fileSize, children: [(file.size / 1024).toFixed(1), " KB"] })] }), jsxRuntime.jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => removeFile(index), className: styles$m.smallButton })] }, `${file.name}-${file.size}`))), fileUploadProps.multiple && (jsxRuntime.jsx(CwButton, { text: labels.addMoreFiles, icon: "plus", variant: "outline", onClick: handleButtonClick, disabled: fileUploadProps.disabled })), !fileUploadProps.multiple && (jsxRuntime.jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled }))] }))] }));
3345
+ }, disabled: fileUploadProps.disabled || fileUploadProps.confirmDisabled, icon: "upload", text: fileUploadProps.confirmLabel ?? labels.upload })), !fileUploadProps.hideClearAll && (jsxRuntime.jsx(CwButton, { onClick: removeAllFiles, disabled: fileUploadProps.disabled, color: "danger", variant: "outline", icon: "delete", text: labels.clearAll }))] })] }), selectedFiles.map((file, index) => (jsxRuntime.jsxs("div", { className: styles$p.fileItem, children: [jsxRuntime.jsxs("div", { className: styles$p.fileIcon, children: [jsxRuntime.jsx(CwIcon, { iconId: "page" }), jsxRuntime.jsx("span", { className: styles$p.fileExtension, children: getFileExtension(file.name) })] }), jsxRuntime.jsxs("div", { className: styles$p.fileInfo, children: [jsxRuntime.jsx("p", { className: styles$p.fileName, children: file.name }), jsxRuntime.jsxs("p", { className: styles$p.fileSize, children: [(file.size / 1024).toFixed(1), " KB"] })] }), jsxRuntime.jsx(CwButton, { variant: "icon", icon: "close", color: "neutral", onClick: () => removeFile(index), className: styles$p.smallButton })] }, `${file.name}-${file.size}`))), fileUploadProps.multiple && (jsxRuntime.jsx(CwButton, { text: labels.addMoreFiles, icon: "plus", variant: "outline", onClick: handleButtonClick, disabled: fileUploadProps.disabled })), !fileUploadProps.multiple && (jsxRuntime.jsx(CwButton, { text: labels.changeFile, icon: "refresh", onClick: handleButtonClick, disabled: fileUploadProps.disabled }))] }))] }));
3346
3346
  }
3347
3347
 
3348
3348
  /**
@@ -3395,7 +3395,7 @@ function CwDigit(props) {
3395
3395
  return (jsxRuntime.jsxs("div", { className: "cw-input-text", "data-direction": labelProps ? flexDirection : "column", "data-feedback-position": feedbackPosition, children: [jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: inputProps.required === true ? "required" : "", children: [labelProps && (jsxRuntime.jsxs(CwLabel, { ...labelProps, children: [iconProps && jsxRuntime.jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxRuntime.jsxs("div", { className: "cw-input-button", children: [jsxRuntime.jsx("input", { type: "number", ...inputProps, "aria-describedby": describedBy }), buttonProps && jsxRuntime.jsx(CwButton, { ...buttonProps })] })] }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-info", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
3396
3396
  }
3397
3397
 
3398
- var styles$l = {"colorPreview":"cw-color-picker-module__colorPreview__ylJcD","hueBar":"cw-color-picker-module__hueBar__bFhyC","hueBarSlider":"cw-color-picker-module__hueBarSlider__D53IV","colorPickerInteractiveArea":"cw-color-picker-module__colorPickerInteractiveArea__KZFR1","colorArea":"cw-color-picker-module__colorArea__xgpSE","colorAreaOverlay":"cw-color-picker-module__colorAreaOverlay__pmgOc","hueBackground":"cw-color-picker-module__hueBackground__Mks78","whiteGradient":"cw-color-picker-module__whiteGradient__Bt-fU","blackGradient":"cw-color-picker-module__blackGradient__VnEKJ","colorAreaCursor":"cw-color-picker-module__colorAreaCursor__lotg3"};
3398
+ var styles$o = {"colorPreview":"cw-color-picker-module__colorPreview__ylJcD","hueBar":"cw-color-picker-module__hueBar__bFhyC","hueBarSlider":"cw-color-picker-module__hueBarSlider__D53IV","colorPickerInteractiveArea":"cw-color-picker-module__colorPickerInteractiveArea__KZFR1","colorArea":"cw-color-picker-module__colorArea__xgpSE","colorAreaOverlay":"cw-color-picker-module__colorAreaOverlay__pmgOc","hueBackground":"cw-color-picker-module__hueBackground__Mks78","whiteGradient":"cw-color-picker-module__whiteGradient__Bt-fU","blackGradient":"cw-color-picker-module__blackGradient__VnEKJ","colorAreaCursor":"cw-color-picker-module__colorAreaCursor__lotg3"};
3399
3399
 
3400
3400
  const CwColorPicker = ({ initialColor, onChange, previewText = "Color preview" }) => {
3401
3401
  const [rgb, setRgb] = React.useState({ r: 255, g: 255, b: 255 });
@@ -3598,13 +3598,13 @@ const CwColorPicker = ({ initialColor, onChange, previewText = "Color preview" }
3598
3598
  // Calculate background color for the main area based on current hue
3599
3599
  const hueColor = hsvToRgb(hsv.h, 100, 100);
3600
3600
  const hueHex = rgbToHex(hueColor.r, hueColor.g, hueColor.b);
3601
- return (jsxRuntime.jsxs("div", { className: "cw-flex-column cw-gap-small", children: [jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-between-center cw-gap-small", children: [jsxRuntime.jsx("div", { className: styles$l.colorPreview, style: { backgroundColor: hexColor, color: getContrastColor(hexColor) }, children: previewText }), jsxRuntime.jsx("button", { type: "button", className: "cw-button", onClick: toggleInputMode, style: { minWidth: "3ch" }, children: inputMode === 'hex' ? 'RGB' : 'HEX' })] }), jsxRuntime.jsx("div", { className: "color-inputs-row", children: inputMode === 'hex' ? (jsxRuntime.jsx("input", { type: "text", value: hexColor, onChange: handleHexChange })) : (jsxRuntime.jsxs("div", { className: "cw-grid-base-3 cw-gap-small", children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: "R:" }), jsxRuntime.jsx("input", { type: "number", name: "r", min: "0", max: "255", value: rgb.r, onChange: handleRgbChange })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: "G:" }), jsxRuntime.jsx("input", { type: "number", name: "g", min: "0", max: "255", value: rgb.g, onChange: handleRgbChange })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: "B:" }), jsxRuntime.jsx("input", { type: "number", name: "b", min: "0", max: "255", value: rgb.b, onChange: handleRgbChange })] })] })) }), jsxRuntime.jsxs("div", { className: styles$l.colorPickerInteractiveArea, children: [jsxRuntime.jsx("div", { className: styles$l.hueBar, ref: hueBarRef, onClick: handleHueBarClick, children: jsxRuntime.jsx("div", { className: styles$l.hueBarSlider, style: { top: `${(360 - hsv.h) / 360 * 100}%` } }) }), jsxRuntime.jsxs("div", { className: styles$l.colorArea, ref: colorAreaRef, onClick: handleColorAreaClick, children: [jsxRuntime.jsxs("div", { className: styles$l.colorAreaOverlay, children: [jsxRuntime.jsx("div", { className: styles$l.hueBackground, style: { backgroundColor: hueHex } }), jsxRuntime.jsx("div", { className: styles$l.whiteGradient }), jsxRuntime.jsx("div", { className: styles$l.blackGradient })] }), jsxRuntime.jsx("div", { className: styles$l.colorAreaCursor, style: {
3601
+ return (jsxRuntime.jsxs("div", { className: "cw-flex-column cw-gap-small", children: [jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-between-center cw-gap-small", children: [jsxRuntime.jsx("div", { className: styles$o.colorPreview, style: { backgroundColor: hexColor, color: getContrastColor(hexColor) }, children: previewText }), jsxRuntime.jsx("button", { type: "button", className: "cw-button", onClick: toggleInputMode, style: { minWidth: "3ch" }, children: inputMode === 'hex' ? 'RGB' : 'HEX' })] }), jsxRuntime.jsx("div", { className: "color-inputs-row", children: inputMode === 'hex' ? (jsxRuntime.jsx("input", { type: "text", value: hexColor, onChange: handleHexChange })) : (jsxRuntime.jsxs("div", { className: "cw-grid-base-3 cw-gap-small", children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: "R:" }), jsxRuntime.jsx("input", { type: "number", name: "r", min: "0", max: "255", value: rgb.r, onChange: handleRgbChange })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: "G:" }), jsxRuntime.jsx("input", { type: "number", name: "g", min: "0", max: "255", value: rgb.g, onChange: handleRgbChange })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { children: "B:" }), jsxRuntime.jsx("input", { type: "number", name: "b", min: "0", max: "255", value: rgb.b, onChange: handleRgbChange })] })] })) }), jsxRuntime.jsxs("div", { className: styles$o.colorPickerInteractiveArea, children: [jsxRuntime.jsx("div", { className: styles$o.hueBar, ref: hueBarRef, onClick: handleHueBarClick, children: jsxRuntime.jsx("div", { className: styles$o.hueBarSlider, style: { top: `${(360 - hsv.h) / 360 * 100}%` } }) }), jsxRuntime.jsxs("div", { className: styles$o.colorArea, ref: colorAreaRef, onClick: handleColorAreaClick, children: [jsxRuntime.jsxs("div", { className: styles$o.colorAreaOverlay, children: [jsxRuntime.jsx("div", { className: styles$o.hueBackground, style: { backgroundColor: hueHex } }), jsxRuntime.jsx("div", { className: styles$o.whiteGradient }), jsxRuntime.jsx("div", { className: styles$o.blackGradient })] }), jsxRuntime.jsx("div", { className: styles$o.colorAreaCursor, style: {
3602
3602
  left: `${hsv.s}%`,
3603
3603
  top: `${100 - hsv.v}%`
3604
3604
  } })] })] })] }));
3605
3605
  };
3606
3606
 
3607
- var styles$k = {"container":"cw-input-color-module__container__x7gpk","selectColor":"cw-input-color-module__selectColor__DTo3V","disabled":"cw-input-color-module__disabled__O1fK5","readOnly":"cw-input-color-module__readOnly__HL-Bz","colorDropdown":"cw-input-color-module__colorDropdown__pX2bc"};
3607
+ var styles$n = {"container":"cw-input-color-module__container__x7gpk","selectColor":"cw-input-color-module__selectColor__DTo3V","disabled":"cw-input-color-module__disabled__O1fK5","readOnly":"cw-input-color-module__readOnly__HL-Bz","colorDropdown":"cw-input-color-module__colorDropdown__pX2bc"};
3608
3608
 
3609
3609
  const CwInputColor = ({ value, onChange, previewText = "Color preview", disabled = false, readOnly = false, width = '4rem', height = '2rem', labelProps, layoutProps, className, style, }) => {
3610
3610
  const [isOpen, setIsOpen] = React.useState(false);
@@ -3737,11 +3737,11 @@ const CwInputColor = ({ value, onChange, previewText = "Color preview", disabled
3737
3737
  break;
3738
3738
  }
3739
3739
  };
3740
- return (jsxRuntime.jsxs("div", { className: `cw-input-color ${styles$k.container}${className ? ` ${className}` : ''}`, style: style, "data-direction": layoutProps?.direction ?? "row", "data-align": layoutProps?.align, children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps })), jsxRuntime.jsx("div", { ref: containerRef, onClick: handleToggle, className: `${styles$k.selectColor} ${disabled ? styles$k.disabled : ''} ${readOnly ? styles$k.readOnly : ''}`, style: {
3740
+ return (jsxRuntime.jsxs("div", { className: `cw-input-color ${styles$n.container}${className ? ` ${className}` : ''}`, style: style, "data-direction": layoutProps?.direction ?? "row", "data-align": layoutProps?.align, children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps })), jsxRuntime.jsx("div", { ref: containerRef, onClick: handleToggle, className: `${styles$n.selectColor} ${disabled ? styles$n.disabled : ''} ${readOnly ? styles$n.readOnly : ''}`, style: {
3741
3741
  width,
3742
3742
  height,
3743
3743
  backgroundColor: value,
3744
- }, "aria-label": "Open color picker", "aria-expanded": isOpen, "aria-haspopup": "dialog", "aria-readonly": readOnly, role: "button", tabIndex: disabled ? -1 : 0, onKeyDown: handleKeyDown }), isOpen && reactDom.createPortal(jsxRuntime.jsx("div", { ref: dropdownRef, className: styles$k.colorDropdown, style: dropdownStyle, role: "dialog", "aria-modal": "true", "aria-label": "Color picker", children: jsxRuntime.jsx(CwColorPicker, { initialColor: value, onChange: handleColorChange, previewText: previewText }) }), document.body)] }));
3744
+ }, "aria-label": "Open color picker", "aria-expanded": isOpen, "aria-haspopup": "dialog", "aria-readonly": readOnly, role: "button", tabIndex: disabled ? -1 : 0, onKeyDown: handleKeyDown }), isOpen && reactDom.createPortal(jsxRuntime.jsx("div", { ref: dropdownRef, className: styles$n.colorDropdown, style: dropdownStyle, role: "dialog", "aria-modal": "true", "aria-label": "Color picker", children: jsxRuntime.jsx(CwColorPicker, { initialColor: value, onChange: handleColorChange, previewText: previewText }) }), document.body)] }));
3745
3745
  };
3746
3746
 
3747
3747
  /**
@@ -3996,7 +3996,7 @@ function CwInputDateText(props) {
3996
3996
  return (jsxRuntime.jsx("div", { className: "cw-input-date-text", children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsxs(CwLabel, { ...labelProps, children: [iconProps && jsxRuntime.jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("input", { type: "text", disabled: disabled, maxLength: 10, onChange: onChangeInputText, pattern: "^$ --|[.0-9\\/\\-]{10}", placeholder: format.toLowerCase(), readOnly: readOnly, ref: textInputRef, required: required, size: width, tabIndex: tabIndex, value: displayedDate }), jsxRuntime.jsxs("span", { children: [jsxRuntime.jsx(CwIcon, { iconId: "calendar" }), jsxRuntime.jsx("input", { type: "date", disabled: disabled, onChange: onChangeInputDate, readOnly: readOnly, ref: dateInputRef, tabIndex: -1, value: date, ...inputProps })] })] }), buttonProps && jsxRuntime.jsx(CwButton, { ...buttonProps })] }) }));
3997
3997
  }
3998
3998
 
3999
- var styles$j = {"hiddenInput":"cw-input-image-module__hiddenInput__pS7hb","dropZone":"cw-input-image-module__dropZone__ygrGu","title":"cw-input-image-module__title__Rji5M","subtitle":"cw-input-image-module__subtitle__djYYu","container":"cw-input-image-module__container__qh7Tm"};
3999
+ var styles$m = {"hiddenInput":"cw-input-image-module__hiddenInput__pS7hb","dropZone":"cw-input-image-module__dropZone__ygrGu","title":"cw-input-image-module__title__Rji5M","subtitle":"cw-input-image-module__subtitle__djYYu","container":"cw-input-image-module__container__qh7Tm"};
4000
4000
 
4001
4001
  const DEFAULT_LABELS = {
4002
4002
  dropImageHere: "Drop image here",
@@ -4075,7 +4075,7 @@ function CwInputImage(props) {
4075
4075
  const file = e.currentTarget.files?.[0];
4076
4076
  void handleFile(file ?? null);
4077
4077
  };
4078
- return (jsxRuntime.jsxs("div", { className: `cw-input-image ${styles$j.container}`, "data-size": size, children: [jsxRuntime.jsxs("div", { onDragOver: (e) => e.preventDefault(), onDrop: handleDrop, className: styles$j.dropZone, children: [jsxRuntime.jsx(CwIcon, { iconId: "upload" }), jsxRuntime.jsxs("div", { className: "cw-flex-column cw-gap-tiny", children: [jsxRuntime.jsx("p", { className: styles$j.title, children: labels.dropImageHere }), jsxRuntime.jsx("p", { className: styles$j.subtitle, children: labels.acceptedFormats(allowedFormats.join(", ").replace(/image\//g, "")) })] })] }), jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-center-center cw-gap-small", children: [jsxRuntime.jsx(CwButton, { onClick: onPasteButtonClick, icon: "paste", text: labels.paste, size: size }), jsxRuntime.jsx(CwButton, { onClick: () => inputRef.current?.click(), icon: "folder-open", text: labels.browse, size: size })] }), jsxRuntime.jsx("input", { ref: inputRef, type: "file", accept: allowedFormats.join(","), onChange: handleFileChange, className: styles$j.hiddenInput, ...inputProps })] }));
4078
+ return (jsxRuntime.jsxs("div", { className: `cw-input-image ${styles$m.container}`, "data-size": size, children: [jsxRuntime.jsxs("div", { onDragOver: (e) => e.preventDefault(), onDrop: handleDrop, className: styles$m.dropZone, children: [jsxRuntime.jsx(CwIcon, { iconId: "upload" }), jsxRuntime.jsxs("div", { className: "cw-flex-column cw-gap-tiny", children: [jsxRuntime.jsx("p", { className: styles$m.title, children: labels.dropImageHere }), jsxRuntime.jsx("p", { className: styles$m.subtitle, children: labels.acceptedFormats(allowedFormats.join(", ").replace(/image\//g, "")) })] })] }), jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-center-center cw-gap-small", children: [jsxRuntime.jsx(CwButton, { onClick: onPasteButtonClick, icon: "paste", text: labels.paste, size: size }), jsxRuntime.jsx(CwButton, { onClick: () => inputRef.current?.click(), icon: "folder-open", text: labels.browse, size: size })] }), jsxRuntime.jsx("input", { ref: inputRef, type: "file", accept: allowedFormats.join(","), onChange: handleFileChange, className: styles$m.hiddenInput, ...inputProps })] }));
4079
4079
  }
4080
4080
 
4081
4081
  /**
@@ -4207,7 +4207,7 @@ const CwImageArea = React.forwardRef((props, ref) => {
4207
4207
  });
4208
4208
  CwImageArea.displayName = "CwImageArea";
4209
4209
 
4210
- var styles$i = {"container":"cw-weekday-selector-module__container__pwcvx","days":"cw-weekday-selector-module__days__Dd3RH"};
4210
+ var styles$l = {"container":"cw-weekday-selector-module__container__pwcvx","days":"cw-weekday-selector-module__days__Dd3RH"};
4211
4211
 
4212
4212
  /* 2024-01-01 was a Monday. Formatted in UTC so a negative browser offset cannot shift a day. */
4213
4213
  const MONDAY_UTC = Date.UTC(2024, 0, 1);
@@ -4405,16 +4405,16 @@ const CwWeekdaySelector = ({ value = "mtwrfsu", onChange, disabled = false, labe
4405
4405
  // Points at the label element rather than copying its text, which also covers a labelProps that
4406
4406
  // carries children instead of `text`.
4407
4407
  const labelId = labelProps?.id ?? `${feedbackId}-label`;
4408
- return (jsxRuntime.jsxs("div", { ...dataAttributes, className: `cw-weekday-selector ${styles$i.container}${className ? ` ${className}` : ""}`, "data-direction": labelProps ? layout?.direction ?? "row" : "column", "data-align": layout?.align, "data-gap": layout?.gap, children: [labelProps && jsxRuntime.jsx(CwLabel, { id: labelId, ...labelProps }), jsxRuntime.jsx("div", { role: "group", className: styles$i.days, "aria-labelledby": labelProps ? labelId : undefined, "aria-describedby": describedBy, children: Weekdays.getFullWeek().map(day => (jsxRuntime.jsx("input", { type: "checkbox", "data-day": day, "data-letter": dayNames[day].letter, "aria-label": dayNames[day].full, title: dayNames[day].full, checked: selectedDays.includes(day), onChange: (e) => handleChange(day, e.target.checked), disabled: disabled }, day))) }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
4408
+ return (jsxRuntime.jsxs("div", { ...dataAttributes, className: `cw-weekday-selector ${styles$l.container}${className ? ` ${className}` : ""}`, "data-direction": labelProps ? layout?.direction ?? "row" : "column", "data-align": layout?.align, "data-gap": layout?.gap, children: [labelProps && jsxRuntime.jsx(CwLabel, { id: labelId, ...labelProps }), jsxRuntime.jsx("div", { role: "group", className: styles$l.days, "aria-labelledby": labelProps ? labelId : undefined, "aria-describedby": describedBy, children: Weekdays.getFullWeek().map(day => (jsxRuntime.jsx("input", { type: "checkbox", "data-day": day, "data-letter": dayNames[day].letter, "aria-label": dayNames[day].full, title: dayNames[day].full, checked: selectedDays.includes(day), onChange: (e) => handleChange(day, e.target.checked), disabled: disabled }, day))) }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
4409
4409
  };
4410
4410
 
4411
- var styles$h = {"check-container":"cw-check-module__check-container__4nscZ","group":"cw-check-module__group__6JCQo","options":"cw-check-module__options__-g9LF"};
4411
+ var styles$k = {"check-container":"cw-check-module__check-container__4nscZ","group":"cw-check-module__group__6JCQo","options":"cw-check-module__options__-g9LF"};
4412
4412
 
4413
4413
  function CwCheck(props) {
4414
4414
  const { labelProps, labelText, direction, alignment, className, ...inputProps } = props;
4415
4415
  const resolvedDirection = direction ?? alignment ?? "row";
4416
4416
  const displayText = labelProps?.text ?? labelText;
4417
- return (jsxRuntime.jsx("div", { className: `cw-check ${styles$h["check-container"]}${className ? ` ${className}` : ''}`, children: jsxRuntime.jsxs("label", { "data-direction": resolvedDirection, children: [jsxRuntime.jsx("input", { type: "checkbox", ...inputProps }), displayText && (jsxRuntime.jsx("span", { className: "cw-icon-text", children: displayText }))] }) }));
4417
+ return (jsxRuntime.jsx("div", { className: `cw-check ${styles$k["check-container"]}${className ? ` ${className}` : ''}`, children: jsxRuntime.jsxs("label", { "data-direction": resolvedDirection, children: [jsxRuntime.jsx("input", { type: "checkbox", ...inputProps }), displayText && (jsxRuntime.jsx("span", { className: "cw-icon-text", children: displayText }))] }) }));
4418
4418
  }
4419
4419
 
4420
4420
  function CwCheckbox(CwCheckboxProps) {
@@ -4468,14 +4468,14 @@ function CwCheckboxGroup({ options, value = [], onChange, labelProps, groupLayou
4468
4468
  ?? (optionsAlignment === "column" ? "row" : "column");
4469
4469
  // Each checkbox's box-to-text layout is the opposite of the options flow, mirroring CwRadioGroup.
4470
4470
  const checkDirection = itemDirection === "row" ? "column" : "row";
4471
- return (jsxRuntime.jsxs("div", { className: `cw-checkbox-group ${styles$h.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? groupDirection : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsx("div", { className: styles$h.options, role: "group", "aria-label": labelProps?.text, "aria-describedby": describedBy, "aria-required": required || undefined, "data-direction": itemDirection, "data-gap": itemLayout?.gap, children: options.map((option) => (jsxRuntime.jsx(CwCheck, { labelProps: { text: option.label }, checked: value.includes(option.value), disabled: disabled || option.disabled, direction: checkDirection, onChange: (e) => handleChange(option.value, e.currentTarget.checked) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
4471
+ return (jsxRuntime.jsxs("div", { className: `cw-checkbox-group ${styles$k.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? groupDirection : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsx("div", { className: styles$k.options, role: "group", "aria-label": labelProps?.text, "aria-describedby": describedBy, "aria-required": required || undefined, "data-direction": itemDirection, "data-gap": itemLayout?.gap, children: options.map((option) => (jsxRuntime.jsx(CwCheck, { labelProps: { text: option.label }, checked: value.includes(option.value), disabled: disabled || option.disabled, direction: checkDirection, onChange: (e) => handleChange(option.value, e.currentTarget.checked) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
4472
4472
  }
4473
4473
 
4474
- var styles$g = {"radio":"cw-radio-module__radio__5sh7a","group":"cw-radio-module__group__br-HM","options":"cw-radio-module__options__LSw7M"};
4474
+ var styles$j = {"radio":"cw-radio-module__radio__5sh7a","group":"cw-radio-module__group__br-HM","options":"cw-radio-module__options__LSw7M"};
4475
4475
 
4476
4476
  /** Single native radio input. Building block for CwRadioGroup. */
4477
4477
  function CwRadio({ label, direction = "row", className, ...inputProps }) {
4478
- return (jsxRuntime.jsxs("label", { className: `cw-radio ${styles$g.radio}${className ? ` ${className}` : ""}`, "data-direction": direction, children: [jsxRuntime.jsx("input", { type: "radio", ...inputProps }), label && jsxRuntime.jsx("span", { children: label })] }));
4478
+ return (jsxRuntime.jsxs("label", { className: `cw-radio ${styles$j.radio}${className ? ` ${className}` : ""}`, "data-direction": direction, children: [jsxRuntime.jsx("input", { type: "radio", ...inputProps }), label && jsxRuntime.jsx("span", { children: label })] }));
4479
4479
  }
4480
4480
 
4481
4481
  /**
@@ -4502,7 +4502,7 @@ function CwRadioGroup({ options, value, onChange, labelProps, groupLayout, itemL
4502
4502
  // (itemLayout column) reads best with the circle beside the text; a side-by-side row reads
4503
4503
  // best with the circle above the text.
4504
4504
  const radioDirection = itemLayout?.direction === "row" ? "column" : "row";
4505
- return (jsxRuntime.jsxs("div", { className: `cw-radio-group ${styles$g.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? (groupLayout?.direction ?? "column") : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsx("div", { className: styles$g.options, role: "radiogroup", "aria-describedby": describedBy, "aria-labelledby": ariaLabelledby, "aria-label": ariaLabelledby ? undefined : (ariaLabel ?? labelProps?.text), "aria-required": required || undefined, "data-direction": itemLayout?.direction ?? "column", "data-gap": itemLayout?.gap, children: options.map((option) => (jsxRuntime.jsx(CwRadio, { name: groupName, label: option.label, direction: radioDirection, checked: value === option.value, required: required, disabled: disabled || option.disabled, onChange: () => onChange(option.value) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
4505
+ return (jsxRuntime.jsxs("div", { className: `cw-radio-group ${styles$j.group}${className ? ` ${className}` : ""}`, "data-testid": dataTestId, "data-direction": labelProps ? (groupLayout?.direction ?? "column") : "column", "data-align": groupLayout?.align, "data-gap": groupLayout?.gap, children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsx("div", { className: styles$j.options, role: "radiogroup", "aria-describedby": describedBy, "aria-labelledby": ariaLabelledby, "aria-label": ariaLabelledby ? undefined : (ariaLabel ?? labelProps?.text), "aria-required": required || undefined, "data-direction": itemLayout?.direction ?? "column", "data-gap": itemLayout?.gap, children: options.map((option) => (jsxRuntime.jsx(CwRadio, { name: groupName, label: option.label, direction: radioDirection, checked: value === option.value, required: required, disabled: disabled || option.disabled, onChange: () => onChange(option.value) }, option.value))) }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] }));
4506
4506
  }
4507
4507
 
4508
4508
  function CwToggle(props) {
@@ -4643,7 +4643,7 @@ function useDropdownPortal({ anchorRef, isOpen, onClose, positionStrategy = defa
4643
4643
  return { panelRef, panelStyle: style, renderPanel };
4644
4644
  }
4645
4645
 
4646
- var styles$f = {"dropdown":"cw-dropdown-module__dropdown__EFZ9M cw-choice-dropdown-module__dropdown__P0b4j","option":"cw-dropdown-module__option__TuMdI cw-choice-dropdown-module__option__uR-ro","optionFocused":"cw-dropdown-module__optionFocused__7LGaC cw-choice-dropdown-module__optionFocused__BYMxj","optionSelected":"cw-dropdown-module__optionSelected__OiXIc cw-choice-dropdown-module__optionSelected__Lt8Xg","optionDisabled":"cw-dropdown-module__optionDisabled__lYM6w cw-choice-dropdown-module__optionDisabled__n3scM","emptyState":"cw-dropdown-module__emptyState__gp8KT cw-choice-dropdown-module__emptyState__HO0Y7","searchBox":"cw-dropdown-module__searchBox__Bx0JE cw-choice-dropdown-module__searchBox__0gox7","searchInput":"cw-dropdown-module__searchInput__JrxCK cw-choice-dropdown-module__searchInput__G5oRs","value":"cw-dropdown-module__value__i-7IN","colorCircle":"cw-dropdown-module__colorCircle__5kgiT cw-choice-dropdown-module__colorCircle__x7mI9"};
4646
+ var styles$i = {"dropdown":"cw-dropdown-module__dropdown__EFZ9M cw-choice-dropdown-module__dropdown__P0b4j","option":"cw-dropdown-module__option__TuMdI cw-choice-dropdown-module__option__uR-ro","optionFocused":"cw-dropdown-module__optionFocused__7LGaC cw-choice-dropdown-module__optionFocused__BYMxj","optionSelected":"cw-dropdown-module__optionSelected__OiXIc cw-choice-dropdown-module__optionSelected__Lt8Xg","optionDisabled":"cw-dropdown-module__optionDisabled__lYM6w cw-choice-dropdown-module__optionDisabled__n3scM","emptyState":"cw-dropdown-module__emptyState__gp8KT cw-choice-dropdown-module__emptyState__HO0Y7","searchBox":"cw-dropdown-module__searchBox__Bx0JE cw-choice-dropdown-module__searchBox__0gox7","searchInput":"cw-dropdown-module__searchInput__JrxCK cw-choice-dropdown-module__searchInput__G5oRs","value":"cw-dropdown-module__value__i-7IN","colorCircle":"cw-dropdown-module__colorCircle__5kgiT cw-choice-dropdown-module__colorCircle__x7mI9"};
4647
4647
 
4648
4648
  /**
4649
4649
  * Custom dropdown component with colour-coded options, optional search filter, and full
@@ -4757,12 +4757,12 @@ function CwDropdown({ options, value, onChange, labelProps, alignProps, placehol
4757
4757
  }
4758
4758
  }, [isOpen, highlightedIndex, filteredOptions, handleOptionSelect]);
4759
4759
  const flexDirection = alignProps?.flexDirection ?? "row";
4760
- return (jsxRuntime.jsx("div", { ref: containerRef, className: `cw-dropdown${className ? ` ${className}` : ""}`, "data-direction": flexDirection, style: style, ...otherProps, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && jsxRuntime.jsx(CwLabel, { id: labelId, ...labelProps }), jsxRuntime.jsxs("div", { className: styles$f.value, children: [jsxRuntime.jsxs("div", { className: "cw-dropdown-wrapper", ref: wrapperRef, children: [jsxRuntime.jsxs("button", { type: "button", className: "cw-dropdown-trigger", onClick: handleTriggerClick, onKeyDown: handleKeyDown, disabled: disabled, "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-labelledby": labelProps ? `${labelId} ${valueId}` : undefined, "aria-label": labelProps ? undefined : (selectedOption?.label || placeholder), "aria-describedby": describedBy, children: [jsxRuntime.jsx("div", { className: "cw-dropdown-trigger-content", id: valueId, children: selectedOption ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [selectedOption.color && (jsxRuntime.jsx("span", { className: styles$f.colorCircle, style: { backgroundColor: selectedOption.color } })), jsxRuntime.jsx("span", { children: selectedOption.label })] })) : (jsxRuntime.jsx("span", { className: "cw-dropdown-placeholder", children: placeholder })) }), jsxRuntime.jsx(CwIcon, { iconId: "chevron-down", size: "small" })] }), renderPanel(jsxRuntime.jsxs("div", { ref: panelRef, className: styles$f.dropdown, style: panelStyle, role: "listbox", onKeyDown: handleKeyDown, children: [allowSearch && (jsxRuntime.jsx("div", { className: styles$f.searchBox, children: jsxRuntime.jsx("input", { ref: inputRef, type: "text", placeholder: "Search...", value: searchText, onChange: handleSearchChange, onKeyDown: handleKeyDown, className: styles$f.searchInput, autoComplete: "off" }) })), jsxRuntime.jsx("ul", { children: filteredOptions.length > 0 ? (filteredOptions.map((option, index) => (jsxRuntime.jsxs("li", { ref: highlightedIndex === index ? highlightedItemRef : null, className: [
4761
- styles$f.option,
4762
- value === option.value ? styles$f.optionSelected : "",
4763
- highlightedIndex === index ? styles$f.optionFocused : "",
4764
- option.disabled ? styles$f.optionDisabled : "",
4765
- ].filter(Boolean).join(" "), onClick: () => !option.disabled && handleOptionSelect(option.value), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": value === option.value, "aria-disabled": option.disabled, children: [option.color && (jsxRuntime.jsx("span", { className: styles$f.colorCircle, style: { backgroundColor: option.color } })), jsxRuntime.jsx("span", { children: option.label })] }, option.value)))) : (jsxRuntime.jsx("li", { className: styles$f.emptyState, children: "No options available" })) })] }))] }), feedbackMessages.map((item, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": item.type, "aria-live": "polite", children: item.message }, index)))] })] }) }));
4760
+ return (jsxRuntime.jsx("div", { ref: containerRef, className: `cw-dropdown${className ? ` ${className}` : ""}`, "data-direction": flexDirection, style: style, ...otherProps, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && jsxRuntime.jsx(CwLabel, { id: labelId, ...labelProps }), jsxRuntime.jsxs("div", { className: styles$i.value, children: [jsxRuntime.jsxs("div", { className: "cw-dropdown-wrapper", ref: wrapperRef, children: [jsxRuntime.jsxs("button", { type: "button", className: "cw-dropdown-trigger", onClick: handleTriggerClick, onKeyDown: handleKeyDown, disabled: disabled, "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-labelledby": labelProps ? `${labelId} ${valueId}` : undefined, "aria-label": labelProps ? undefined : (selectedOption?.label || placeholder), "aria-describedby": describedBy, children: [jsxRuntime.jsx("div", { className: "cw-dropdown-trigger-content", id: valueId, children: selectedOption ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [selectedOption.color && (jsxRuntime.jsx("span", { className: styles$i.colorCircle, style: { backgroundColor: selectedOption.color } })), jsxRuntime.jsx("span", { children: selectedOption.label })] })) : (jsxRuntime.jsx("span", { className: "cw-dropdown-placeholder", children: placeholder })) }), jsxRuntime.jsx(CwIcon, { iconId: "chevron-down", size: "small" })] }), renderPanel(jsxRuntime.jsxs("div", { ref: panelRef, className: styles$i.dropdown, style: panelStyle, role: "listbox", onKeyDown: handleKeyDown, children: [allowSearch && (jsxRuntime.jsx("div", { className: styles$i.searchBox, children: jsxRuntime.jsx("input", { ref: inputRef, type: "text", placeholder: "Search...", value: searchText, onChange: handleSearchChange, onKeyDown: handleKeyDown, className: styles$i.searchInput, autoComplete: "off" }) })), jsxRuntime.jsx("ul", { children: filteredOptions.length > 0 ? (filteredOptions.map((option, index) => (jsxRuntime.jsxs("li", { ref: highlightedIndex === index ? highlightedItemRef : null, className: [
4761
+ styles$i.option,
4762
+ value === option.value ? styles$i.optionSelected : "",
4763
+ highlightedIndex === index ? styles$i.optionFocused : "",
4764
+ option.disabled ? styles$i.optionDisabled : "",
4765
+ ].filter(Boolean).join(" "), onClick: () => !option.disabled && handleOptionSelect(option.value), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": value === option.value, "aria-disabled": option.disabled, children: [option.color && (jsxRuntime.jsx("span", { className: styles$i.colorCircle, style: { backgroundColor: option.color } })), jsxRuntime.jsx("span", { children: option.label })] }, option.value)))) : (jsxRuntime.jsx("li", { className: styles$i.emptyState, children: "No options available" })) })] }))] }), feedbackMessages.map((item, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": item.type, "aria-live": "polite", children: item.message }, index)))] })] }) }));
4766
4766
  }
4767
4767
 
4768
4768
  /**
@@ -4779,7 +4779,7 @@ function CwDropdownFilter(props) {
4779
4779
  return (jsxRuntime.jsxs("div", { id: props.IdContent, className: containerClassName, children: [props.children, isVisible && (jsxRuntime.jsx("nav", { className: "cw-dropdown-menu", style: inlineStyles, onMouseLeave: props.onMouseLeave, id: props.idDropDownFilter, role: "menu", children: jsxRuntime.jsx("ul", { role: "none", children: props.DataSourceDropDownItem?.map((item) => (jsxRuntime.jsx("li", { id: item.IdDropDown_filter, role: "menuitem", children: item.dropDownFilter_desc }, item.IdDropDown_filter))) }) }))] }));
4780
4780
  }
4781
4781
 
4782
- var styles$e = {"container":"cw-popover-button-module__container__YSWQU","panel":"cw-popover-button-module__panel__C-BTn"};
4782
+ var styles$h = {"container":"cw-popover-button-module__container__YSWQU","panel":"cw-popover-button-module__panel__C-BTn"};
4783
4783
 
4784
4784
  /**
4785
4785
  * Button that toggles a floating panel with arbitrary children.
@@ -4858,7 +4858,7 @@ function CwPopoverButton({ children, panelWidth = "auto", placement = "bottom-st
4858
4858
  }
4859
4859
  panel.showPopover();
4860
4860
  }, [placement]);
4861
- return (jsxRuntime.jsxs("div", { ref: containerRef, className: styles$e.container, children: [jsxRuntime.jsx(CwButton, { ...buttonProps, onClick: handleClick }), jsxRuntime.jsx("div", { ref: panelCallbackRef, className: `${styles$e.panel}${panelClassName ? ` ${panelClassName}` : ""}`, style: { width: panelWidth }, children: children })] }));
4861
+ return (jsxRuntime.jsxs("div", { ref: containerRef, className: styles$h.container, children: [jsxRuntime.jsx(CwButton, { ...buttonProps, onClick: handleClick }), jsxRuntime.jsx("div", { ref: panelCallbackRef, className: `${styles$h.panel}${panelClassName ? ` ${panelClassName}` : ""}`, style: { width: panelWidth }, children: children })] }));
4862
4862
  }
4863
4863
 
4864
4864
  function itemsToMultiFilterTags(items, nameKey, valueKey, category, primaryColor, onPrimaryColor) {
@@ -4876,13 +4876,13 @@ function itemsToMultiFilterTags(items, nameKey, valueKey, category, primaryColor
4876
4876
  return result;
4877
4877
  }
4878
4878
 
4879
- var styles$d = {"cw-multifilter-tag":"cw-multi-filter-tag-module__cw-multifilter-tag__Epda-"};
4879
+ var styles$g = {"cw-multifilter-tag":"cw-multi-filter-tag-module__cw-multifilter-tag__Epda-"};
4880
4880
 
4881
4881
  const CwMultiFilterTag = props => {
4882
4882
  const { ID, Name, Value, Category, Removable, PrimaryColor, Selectable, Selected } = props;
4883
4883
  const backgroundColor = `rgb(${PrimaryColor.r},${PrimaryColor.g},${PrimaryColor.b})`;
4884
4884
  const isOutlineMode = Selected && !Removable;
4885
- return (jsxRuntime.jsx("li", { className: styles$d["cw-multifilter-tag"], id: ID, "data-value": Value, "data-category": Category, "data-selected": !!Selected, title: props.tooltip ?? Name, onClick: () => {
4885
+ return (jsxRuntime.jsx("li", { className: styles$g["cw-multifilter-tag"], id: ID, "data-value": Value, "data-category": Category, "data-selected": !!Selected, title: props.tooltip ?? Name, onClick: () => {
4886
4886
  if (Selectable)
4887
4887
  props.OnSelect?.(props);
4888
4888
  }, children: jsxRuntime.jsx(CwChip, { label: Name, colorScheme: "custom", customColor: backgroundColor, variant: isOutlineMode ? "outline" : "soft", closable: Removable, onClose: () => props.OnRemove?.(props),
@@ -4892,7 +4892,7 @@ const CwMultiFilterTag = props => {
4892
4892
  } : undefined }) }));
4893
4893
  };
4894
4894
 
4895
- var styles$c = {"cw-multi-filter-catalog-container":"cw-multi-filter-module__cw-multi-filter-catalog-container__S3nsq","cw-multi-filter":"cw-multi-filter-module__cw-multi-filter__zipBK","category-selected":"cw-multi-filter-module__category-selected__eYbes","cw-multi-filter-search":"cw-multi-filter-module__cw-multi-filter-search__eyHr0 cw-choice-input-box-module__inputBox__gHY9d"};
4895
+ var styles$f = {"cw-multi-filter-catalog-container":"cw-multi-filter-module__cw-multi-filter-catalog-container__S3nsq","cw-multi-filter":"cw-multi-filter-module__cw-multi-filter__zipBK","category-selected":"cw-multi-filter-module__category-selected__eYbes","cw-multi-filter-search":"cw-multi-filter-module__cw-multi-filter-search__eyHr0 cw-choice-input-box-module__inputBox__gHY9d"};
4896
4896
 
4897
4897
  /**
4898
4898
  * A multiple filter selector, a MULTI-SELECT even. Allows users to select and filter items based on tags.
@@ -5133,9 +5133,9 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
5133
5133
  inputRef.current?.focus();
5134
5134
  }
5135
5135
  };
5136
- return (jsxRuntime.jsxs("form", { ref: componentRef, id: id, "data-testid": testId, className: `${styles$c["cw-multi-filter"]}${className ? ` ${className}` : ""}`, style: style, onSubmit: (e) => {
5136
+ return (jsxRuntime.jsxs("form", { ref: componentRef, id: id, "data-testid": testId, className: `${styles$f["cw-multi-filter"]}${className ? ` ${className}` : ""}`, style: style, onSubmit: (e) => {
5137
5137
  e.preventDefault();
5138
- }, children: [jsxRuntime.jsxs("div", { onClick: handleDivClick, ref: wrapperRef, className: styles$c["cw-multi-filter-search"], style: isPanelOpen ? { outline: "1px solid var(--cw-outline-variant)" } : {}, children: [jsxRuntime.jsxs("ul", { id: id + "_selected_filters", children: [Array.from(selectedTags).map(tag => (React.createElement(CwMultiFilterTag, { ...tag, key: tag.ID, Selectable: false, Removable: true, OnRemove: () => removeTag(tag.ID) }))), jsxRuntime.jsx("input", { type: "text", id: id + "_input", ref: inputRef, value: inputTextValue, spellCheck: false, onFocus: () => setIsPanelOpen(true), onChange: e => handleInputText(e.currentTarget.value), autoComplete: "off", placeholder: selectedTags.size === 0 ? placeholder : "", onKeyDown: e => {
5138
+ }, children: [jsxRuntime.jsxs("div", { onClick: handleDivClick, ref: wrapperRef, className: styles$f["cw-multi-filter-search"], style: isPanelOpen ? { outline: "1px solid var(--cw-outline-variant)" } : {}, children: [jsxRuntime.jsxs("ul", { id: id + "_selected_filters", children: [Array.from(selectedTags).map(tag => (React.createElement(CwMultiFilterTag, { ...tag, key: tag.ID, Selectable: false, Removable: true, OnRemove: () => removeTag(tag.ID) }))), jsxRuntime.jsx("input", { type: "text", id: id + "_input", ref: inputRef, value: inputTextValue, spellCheck: false, onFocus: () => setIsPanelOpen(true), onChange: e => handleInputText(e.currentTarget.value), autoComplete: "off", placeholder: selectedTags.size === 0 ? placeholder : "", onKeyDown: e => {
5139
5139
  switch (e.key) {
5140
5140
  case "Enter":
5141
5141
  case "Tab": {
@@ -5162,7 +5162,7 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
5162
5162
  break;
5163
5163
  }
5164
5164
  }
5165
- } })] }), selectedTags.size > 0 && (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onMouseDown: e => e.preventDefault(), onClick: (e) => { e.stopPropagation(); onChangeSelectedTags(new Set()); setIsPanelOpen(false); }, tabIndex: -1, "aria-label": "Clear all" }))] }), renderPanel(jsxRuntime.jsxs("section", { ref: panelRef, className: styles$c["cw-multi-filter-catalog-container"], style: panelStyle, children: [jsxRuntime.jsxs("nav", { children: [jsxRuntime.jsx("button", { className: selectedCategory === "All" ? styles$c["category-selected"] : undefined, onClick: () => handleClickCategory("All"), children: allCategoriesLabel }), Array.from(categoriesMappedToTags().keys()).map(category => (jsxRuntime.jsx("button", { className: selectedCategory === category ? styles$c["category-selected"] : undefined, style: {
5165
+ } })] }), selectedTags.size > 0 && (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onMouseDown: e => e.preventDefault(), onClick: (e) => { e.stopPropagation(); onChangeSelectedTags(new Set()); setIsPanelOpen(false); }, tabIndex: -1, "aria-label": "Clear all" }))] }), renderPanel(jsxRuntime.jsxs("section", { ref: panelRef, className: styles$f["cw-multi-filter-catalog-container"], style: panelStyle, children: [jsxRuntime.jsxs("nav", { children: [jsxRuntime.jsx("button", { className: selectedCategory === "All" ? styles$f["category-selected"] : undefined, onClick: () => handleClickCategory("All"), children: allCategoriesLabel }), Array.from(categoriesMappedToTags().keys()).map(category => (jsxRuntime.jsx("button", { className: selectedCategory === category ? styles$f["category-selected"] : undefined, style: {
5166
5166
  backgroundColor: getColor(category).primary,
5167
5167
  color: getColor(category).onPrimary,
5168
5168
  }, onClick: () => handleClickCategory(category), children: category }, category)))] }), jsxRuntime.jsx("ul", { children: displayTags
@@ -5188,7 +5188,7 @@ const CwMultiFilter = ({ allTags, id, onChangeSelectedTags, selectedTags, placeh
5188
5188
  } }, props.ID))) })] }))] }));
5189
5189
  };
5190
5190
 
5191
- var styles$b = {"container":"cw-tag-selector-module__container__-do8i","value":"cw-tag-selector-module__value__TDAy3","inputBox":"cw-tag-selector-module__inputBox__3NGz9 cw-choice-input-box-module__inputBox__gHY9d","disabled":"cw-tag-selector-module__disabled__vbud9 cw-choice-input-box-module__disabled__TFAnC","dropdown":"cw-tag-selector-module__dropdown__X6Dob cw-choice-dropdown-module__dropdown__P0b4j","option":"cw-tag-selector-module__option__2UQ7g cw-choice-dropdown-module__option__uR-ro","optionFocused":"cw-tag-selector-module__optionFocused__8-lv8 cw-choice-dropdown-module__optionFocused__BYMxj","optionDot":"cw-tag-selector-module__optionDot__CdFlG cw-choice-dropdown-module__colorCircle__x7mI9","selectAll":"cw-tag-selector-module__selectAll__HyvMA"};
5191
+ var styles$e = {"container":"cw-tag-selector-module__container__-do8i","value":"cw-tag-selector-module__value__TDAy3","inputBox":"cw-tag-selector-module__inputBox__3NGz9 cw-choice-input-box-module__inputBox__gHY9d","disabled":"cw-tag-selector-module__disabled__vbud9 cw-choice-input-box-module__disabled__TFAnC","dropdown":"cw-tag-selector-module__dropdown__X6Dob cw-choice-dropdown-module__dropdown__P0b4j","option":"cw-tag-selector-module__option__2UQ7g cw-choice-dropdown-module__option__uR-ro","optionFocused":"cw-tag-selector-module__optionFocused__8-lv8 cw-choice-dropdown-module__optionFocused__BYMxj","optionDot":"cw-tag-selector-module__optionDot__CdFlG cw-choice-dropdown-module__colorCircle__x7mI9","selectAll":"cw-tag-selector-module__selectAll__HyvMA"};
5192
5192
 
5193
5193
  /**
5194
5194
  * Multi-select input with chip tags and searchable dropdown.
@@ -5339,11 +5339,11 @@ function CwTagSelector({ id, options, value, onChange, labelProps, iconProps, al
5339
5339
  const feedbackId = React.useId();
5340
5340
  const feedbackIds = feedbackMessages.map((_, index) => `${feedbackId}-${index}`);
5341
5341
  const describedBy = feedbackIds.join(" ") || undefined;
5342
- return (jsxRuntime.jsxs("div", { ref: containerRef, className: `${styles$b.container}${className ? ` ${className}` : ""}`, style: style, id: id, "data-direction": direction, children: [jsxRuntime.jsxs(CwAlign, { ...alignProps, children: [labelProps && (jsxRuntime.jsxs(CwLabel, { ...labelProps, children: [iconProps && jsxRuntime.jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxRuntime.jsxs("div", { className: styles$b.value, children: [jsxRuntime.jsxs("div", { className: `${styles$b.inputBox}${disabled ? ` ${styles$b.disabled}` : ""}`, ref: inputBoxRef, onClick: () => { if (!disabled)
5343
- inputRef.current?.focus(); }, children: [selectedOptions.map(opt => (jsxRuntime.jsx(CwChip, { label: opt.label, colorScheme: opt.color ? "custom" : "info", customColor: opt.color, closable: !disabled, onClose: () => handleRemove(opt.value) }, opt.value))), jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: search, onChange: handleInputChange, onFocus: handleInputFocus, onKeyDown: handleKeyDown, placeholder: selectedOptions.length === 0 ? placeholder : "", disabled: disabled, autoComplete: "off", "aria-describedby": describedBy }), value.length > 0 && !disabled && (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onMouseDown: (e) => e.preventDefault(), onClick: (e) => { e.stopPropagation(); onChange([]); setSearch(""); setOpen(false); }, tabIndex: -1, "aria-label": "Clear all" }))] }), feedbackMessages.map((fb, i) => (jsxRuntime.jsx("p", { id: feedbackIds[i], className: "cw-input-feedback", "data-color": fb.type, "aria-live": "polite", children: fb.message }, i)))] })] }), renderPanel((showSelectAll || filtered.length > 0) ? (jsxRuntime.jsxs("div", { ref: panelRef, className: styles$b.dropdown, style: panelStyle, children: [showSelectAll && !search && (jsxRuntime.jsxs("div", { className: styles$b.selectAll, onMouseDown: (e) => e.preventDefault(), onClick: handleToggleAll, children: [jsxRuntime.jsx("input", { type: "checkbox", checked: allSelected, readOnly: true, tabIndex: -1 }), allSelected ? "Deselect all" : "Select all"] })), jsxRuntime.jsx("ul", { ref: listRef, children: filtered.map((opt, idx) => (jsxRuntime.jsxs("li", { className: `${styles$b.option}${idx === focusedIndex ? ` ${styles$b.optionFocused}` : ""}`, onMouseDown: (e) => e.preventDefault(), onClick: () => handleSelect(opt.value), onMouseEnter: () => setFocusedIndex(idx), title: opt.tooltip, children: [opt.color && jsxRuntime.jsx("span", { className: styles$b.optionDot, style: { backgroundColor: opt.color } }), opt.label] }, opt.value))) })] })) : null)] }));
5342
+ return (jsxRuntime.jsxs("div", { ref: containerRef, className: `${styles$e.container}${className ? ` ${className}` : ""}`, style: style, id: id, "data-direction": direction, children: [jsxRuntime.jsxs(CwAlign, { ...alignProps, children: [labelProps && (jsxRuntime.jsxs(CwLabel, { ...labelProps, children: [iconProps && jsxRuntime.jsx(CwIcon, { ...iconProps }), labelProps.text] })), jsxRuntime.jsxs("div", { className: styles$e.value, children: [jsxRuntime.jsxs("div", { className: `${styles$e.inputBox}${disabled ? ` ${styles$e.disabled}` : ""}`, ref: inputBoxRef, onClick: () => { if (!disabled)
5343
+ inputRef.current?.focus(); }, children: [selectedOptions.map(opt => (jsxRuntime.jsx(CwChip, { label: opt.label, colorScheme: opt.color ? "custom" : "info", customColor: opt.color, closable: !disabled, onClose: () => handleRemove(opt.value) }, opt.value))), jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: search, onChange: handleInputChange, onFocus: handleInputFocus, onKeyDown: handleKeyDown, placeholder: selectedOptions.length === 0 ? placeholder : "", disabled: disabled, autoComplete: "off", "aria-describedby": describedBy }), value.length > 0 && !disabled && (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onMouseDown: (e) => e.preventDefault(), onClick: (e) => { e.stopPropagation(); onChange([]); setSearch(""); setOpen(false); }, tabIndex: -1, "aria-label": "Clear all" }))] }), feedbackMessages.map((fb, i) => (jsxRuntime.jsx("p", { id: feedbackIds[i], className: "cw-input-feedback", "data-color": fb.type, "aria-live": "polite", children: fb.message }, i)))] })] }), renderPanel((showSelectAll || filtered.length > 0) ? (jsxRuntime.jsxs("div", { ref: panelRef, className: styles$e.dropdown, style: panelStyle, children: [showSelectAll && !search && (jsxRuntime.jsxs("div", { className: styles$e.selectAll, onMouseDown: (e) => e.preventDefault(), onClick: handleToggleAll, children: [jsxRuntime.jsx("input", { type: "checkbox", checked: allSelected, readOnly: true, tabIndex: -1 }), allSelected ? "Deselect all" : "Select all"] })), jsxRuntime.jsx("ul", { ref: listRef, children: filtered.map((opt, idx) => (jsxRuntime.jsxs("li", { className: `${styles$e.option}${idx === focusedIndex ? ` ${styles$e.optionFocused}` : ""}`, onMouseDown: (e) => e.preventDefault(), onClick: () => handleSelect(opt.value), onMouseEnter: () => setFocusedIndex(idx), title: opt.tooltip, children: [opt.color && jsxRuntime.jsx("span", { className: styles$e.optionDot, style: { backgroundColor: opt.color } }), opt.label] }, opt.value))) })] })) : null)] }));
5344
5344
  }
5345
5345
 
5346
- var styles$a = {"tree-container":"cw-tree-view-module__tree-container__NN-HJ","tree-wrapper":"cw-tree-view-module__tree-wrapper__keBZI","tree-item":"cw-tree-view-module__tree-item__prE9N","tree-node":"cw-tree-view-module__tree-node__wfro9","selected":"cw-tree-view-module__selected__XJQ0w","non-selectable":"cw-tree-view-module__non-selectable__YuPSx","tree-children":"cw-tree-view-module__tree-children__ji8CZ","empty-state":"cw-tree-view-module__empty-state__yvRjo","tree-label":"cw-tree-view-module__tree-label__ss3Nf","tree-spacer":"cw-tree-view-module__tree-spacer__E9Ud2"};
5346
+ var styles$d = {"tree-container":"cw-tree-view-module__tree-container__NN-HJ","tree-wrapper":"cw-tree-view-module__tree-wrapper__keBZI","tree-item":"cw-tree-view-module__tree-item__prE9N","tree-node":"cw-tree-view-module__tree-node__wfro9","selected":"cw-tree-view-module__selected__XJQ0w","non-selectable":"cw-tree-view-module__non-selectable__YuPSx","tree-children":"cw-tree-view-module__tree-children__ji8CZ","empty-state":"cw-tree-view-module__empty-state__yvRjo","tree-label":"cw-tree-view-module__tree-label__ss3Nf","tree-spacer":"cw-tree-view-module__tree-spacer__E9Ud2"};
5347
5347
 
5348
5348
  function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId: initialSelectedId = null, ...dataAttributes }) {
5349
5349
  const [expanded, setExpanded] = React.useState(new Set());
@@ -5410,10 +5410,10 @@ function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId:
5410
5410
  const isLeaf = !hasChildren;
5411
5411
  const isSelected = selectedId?.toString().toLowerCase() === node.id.toString().toLowerCase();
5412
5412
  const selectable = allowParentSelection || isLeaf;
5413
- return (jsxRuntime.jsxs("div", { className: styles$a["tree-item"], children: [jsxRuntime.jsxs("div", { className: [
5414
- styles$a["tree-node"],
5415
- isSelected && styles$a["selected"],
5416
- !selectable && styles$a["non-selectable"]
5413
+ return (jsxRuntime.jsxs("div", { className: styles$d["tree-item"], children: [jsxRuntime.jsxs("div", { className: [
5414
+ styles$d["tree-node"],
5415
+ isSelected && styles$d["selected"],
5416
+ !selectable && styles$d["non-selectable"]
5417
5417
  ].filter(Boolean).join(' '), style: { paddingLeft: `${depth * 24 + 8}px` }, onClick: () => {
5418
5418
  if (selectable) {
5419
5419
  setSelectedId(node.id);
@@ -5425,7 +5425,7 @@ function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId:
5425
5425
  }, children: [hasChildren && (jsxRuntime.jsx(CwButton, { variant: "icon", color: "neutral", icon: isExpanded ? "chevron-down" : "chevron-right", "aria-expanded": isExpanded, "aria-label": `${isExpanded ? "Collapse" : "Expand"} ${node.label}`, onClick: (event) => {
5426
5426
  event.stopPropagation();
5427
5427
  toggleExpand(node.id);
5428
- } })), jsxRuntime.jsx("div", { className: `${styles$a["tree-label"]} ${!hasChildren ? styles$a["tree-spacer"] : ''}`, children: node.label })] }), hasChildren && isExpanded && (jsxRuntime.jsx("div", { className: styles$a["tree-children"], children: node.children.map((child) => renderNode(child, depth + 1)) }))] }, node.id));
5428
+ } })), jsxRuntime.jsx("div", { className: `${styles$d["tree-label"]} ${!hasChildren ? styles$d["tree-spacer"] : ''}`, children: node.label })] }), hasChildren && isExpanded && (jsxRuntime.jsx("div", { className: styles$d["tree-children"], children: node.children.map((child) => renderNode(child, depth + 1)) }))] }, node.id));
5429
5429
  };
5430
5430
  // Function to search for nodes that match the search term
5431
5431
  const searchInTree = (nodes, searchTerm) => {
@@ -5449,7 +5449,7 @@ function CwTreeView({ data, onSelect, allowParentSelection = false, selectedId:
5449
5449
  return results;
5450
5450
  };
5451
5451
  const filteredData = searchInTree(data, search);
5452
- return (jsxRuntime.jsxs("div", { ...dataAttributes, className: `cw-tree-view ${styles$a["tree-container"]}`, children: [jsxRuntime.jsxs("header", { children: [jsxRuntime.jsx("input", { type: "text", placeholder: "Search in tree...", value: search, onChange: (e) => setSearch(e.target.value) }), search && (jsxRuntime.jsx(CwButton, { onClick: () => setSearch(""), type: "button", icon: "close", variant: "icon", color: "neutral" }))] }), jsxRuntime.jsx("div", { className: styles$a["tree-wrapper"], children: filteredData.length > 0 ? (filteredData.map((node) => renderNode(node))) : (jsxRuntime.jsxs("div", { className: styles$a["empty-state"], children: [jsxRuntime.jsx(CwIcon, { iconId: "comment" }), search ? "No results found" : "There are no items"] })) })] }));
5452
+ return (jsxRuntime.jsxs("div", { ...dataAttributes, className: `cw-tree-view ${styles$d["tree-container"]}`, children: [jsxRuntime.jsxs("header", { children: [jsxRuntime.jsx("input", { type: "text", placeholder: "Search in tree...", value: search, onChange: (e) => setSearch(e.target.value) }), search && (jsxRuntime.jsx(CwButton, { onClick: () => setSearch(""), type: "button", icon: "close", variant: "icon", color: "neutral" }))] }), jsxRuntime.jsx("div", { className: styles$d["tree-wrapper"], children: filteredData.length > 0 ? (filteredData.map((node) => renderNode(node))) : (jsxRuntime.jsxs("div", { className: styles$d["empty-state"], children: [jsxRuntime.jsx(CwIcon, { iconId: "comment" }), search ? "No results found" : "There are no items"] })) })] }));
5453
5453
  }
5454
5454
 
5455
5455
  const EXACT_PHRASE = /"([^"]+)"/g;
@@ -5517,7 +5517,7 @@ function sortNavItems(items, alphabetically) {
5517
5517
  return [...items].sort((first, second) => first.label.localeCompare(second.label));
5518
5518
  }
5519
5519
 
5520
- var styles$9 = {"menu":"cw-nav-menu-module__menu__LmeQg","expandIndicator":"cw-nav-menu-module__expandIndicator__TBSdQ","favorites":"cw-nav-menu-module__favorites__Esaqd","favoritesContent":"cw-nav-menu-module__favoritesContent__l5DGG","favoriteStar":"cw-nav-menu-module__favoriteStar__J-jzg","emptyMessage":"cw-nav-menu-module__emptyMessage__-CQNd","skeleton":"cw-nav-menu-module__skeleton__INQqF"};
5520
+ var styles$c = {"menu":"cw-nav-menu-module__menu__LmeQg","expandIndicator":"cw-nav-menu-module__expandIndicator__TBSdQ","favorites":"cw-nav-menu-module__favorites__Esaqd","favoritesContent":"cw-nav-menu-module__favoritesContent__l5DGG","favoriteStar":"cw-nav-menu-module__favoriteStar__J-jzg","emptyMessage":"cw-nav-menu-module__emptyMessage__-CQNd","skeleton":"cw-nav-menu-module__skeleton__INQqF"};
5521
5521
 
5522
5522
  const SKELETON_ROW_COUNT = 5;
5523
5523
  const defaultRenderLink = (item, children) => (jsxRuntime.jsx("a", { href: item.href, children: children }));
@@ -5529,13 +5529,13 @@ function CwNavMenu({ items, loading = false, isActive, renderLink = defaultRende
5529
5529
  const renderItem = (item, level) => {
5530
5530
  const children = item.children;
5531
5531
  if (children && children.length > 0) {
5532
- return (jsxRuntime.jsx("li", { children: jsxRuntime.jsxs("details", { "data-level": level, open: hasActiveDescendant(item) || undefined, children: [jsxRuntime.jsxs("summary", { children: [item.icon && jsxRuntime.jsx(CwIcon, { iconId: item.icon, size: level >= 2 ? "small" : "medium" }), item.label, (showExpandIndicator || level >= 2) && (jsxRuntime.jsx(CwIcon, { iconId: "chevron-down", size: "small", className: styles$9.expandIndicator }))] }), jsxRuntime.jsx("ul", { children: children.map(child => renderItem(child, level + 1)) })] }) }, item.id));
5532
+ return (jsxRuntime.jsx("li", { children: jsxRuntime.jsxs("details", { "data-level": level, open: hasActiveDescendant(item) || undefined, children: [jsxRuntime.jsxs("summary", { children: [item.icon && jsxRuntime.jsx(CwIcon, { iconId: item.icon, size: level >= 2 ? "small" : "medium" }), item.label, (showExpandIndicator || level >= 2) && (jsxRuntime.jsx(CwIcon, { iconId: "chevron-down", size: "small", className: styles$c.expandIndicator }))] }), jsxRuntime.jsx("ul", { children: children.map(child => renderItem(child, level + 1)) })] }) }, item.id));
5533
5533
  }
5534
- return (jsxRuntime.jsx("li", { "data-active": isActive?.(item) ? "true" : undefined, children: renderLink(item, jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [item.icon && jsxRuntime.jsx(CwIcon, { iconId: item.icon, size: "medium" }), item.label, isFavorite?.(item) && jsxRuntime.jsx(CwIcon, { iconId: "star", size: "small", className: styles$9.favoriteStar })] })) }, item.id));
5534
+ return (jsxRuntime.jsx("li", { "data-active": isActive?.(item) ? "true" : undefined, children: renderLink(item, jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [item.icon && jsxRuntime.jsx(CwIcon, { iconId: item.icon, size: "medium" }), item.label, isFavorite?.(item) && jsxRuntime.jsx(CwIcon, { iconId: "star", size: "small", className: styles$c.favoriteStar })] })) }, item.id));
5535
5535
  };
5536
- return (jsxRuntime.jsxs("nav", { ...navProps, className: [styles$9.menu, className].filter(Boolean).join(" "), "aria-busy": loading || undefined, children: [favoritesSlot && (jsxRuntime.jsxs("details", { open: true, ...favoritesProps, className: [styles$9.favorites, favoritesProps?.className].filter(Boolean).join(" "), children: [jsxRuntime.jsxs("summary", { children: [jsxRuntime.jsx(CwIcon, { iconId: "star", size: "medium" }), favoritesLabel] }), jsxRuntime.jsx("div", { className: styles$9.favoritesContent, children: favoritesSlot })] })), beforeTreeSlot, jsxRuntime.jsx("ul", { children: loading
5537
- ? Array.from({ length: SKELETON_ROW_COUNT }, (_unused, index) => (jsxRuntime.jsx("li", { className: styles$9.skeleton, children: jsxRuntime.jsx(CwSkeleton, { height: "var(--cw-size-small)", radius: "var(--cw-border-radius-small)" }) }, index)))
5538
- : visibleItems.map(item => renderItem(item, 1)) }), showEmptyMessage && jsxRuntime.jsx("p", { className: styles$9.emptyMessage, children: emptyMessage })] }));
5536
+ return (jsxRuntime.jsxs("nav", { ...navProps, className: [styles$c.menu, className].filter(Boolean).join(" "), "aria-busy": loading || undefined, children: [favoritesSlot && (jsxRuntime.jsxs("details", { open: true, ...favoritesProps, className: [styles$c.favorites, favoritesProps?.className].filter(Boolean).join(" "), children: [jsxRuntime.jsxs("summary", { children: [jsxRuntime.jsx(CwIcon, { iconId: "star", size: "medium" }), favoritesLabel] }), jsxRuntime.jsx("div", { className: styles$c.favoritesContent, children: favoritesSlot })] })), beforeTreeSlot, jsxRuntime.jsx("ul", { children: loading
5537
+ ? Array.from({ length: SKELETON_ROW_COUNT }, (_unused, index) => (jsxRuntime.jsx("li", { className: styles$c.skeleton, children: jsxRuntime.jsx(CwSkeleton, { height: "var(--cw-size-small)", radius: "var(--cw-border-radius-small)" }) }, index)))
5538
+ : visibleItems.map(item => renderItem(item, 1)) }), showEmptyMessage && jsxRuntime.jsx("p", { className: styles$c.emptyMessage, children: emptyMessage })] }));
5539
5539
  }
5540
5540
 
5541
5541
  var dropdownStyles = {"dropdown":"cw-choice-dropdown-module__dropdown__P0b4j","option":"cw-choice-dropdown-module__option__uR-ro","optionFocused":"cw-choice-dropdown-module__optionFocused__BYMxj"};
@@ -5701,7 +5701,7 @@ function CwSearchInput(optionsProps) {
5701
5701
  return (jsxRuntime.jsxs("div", { className: `cw-search-input ${className || ""}`, style: style, ...otherProps, "data-direction": direction, children: [jsxRuntime.jsxs(CwAlign, { ...alignProps, children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: "cw-search-input-wrapper", ref: wrapperRef, children: [jsxRuntime.jsx("input", { ref: inputRef, id: id, type: "text", value: searchText, onChange: handleInputChange, onKeyDown: handleKeyDown, onFocus: handleInputFocus, onBlur: handleInputBlur, placeholder: placeholder, className: "cw-input-search", disabled: disabled, autoFocus: autoFocus, autoComplete: "off", role: "combobox", "aria-haspopup": "listbox", "aria-expanded": showDropdown && filteredOptions.length > 0, "aria-controls": listboxId, "aria-activedescendant": highlightedIndex >= 0 ? optionId(highlightedIndex) : undefined }), isLoading && (jsxRuntime.jsx("div", { className: "cw-search-input-loading", children: jsxRuntime.jsx(CwIcon, { iconId: "spinner" }) })), jsxRuntime.jsx("div", { className: "cw-search-input-icons", children: searchText && !disabled && !isLoading ? (jsxRuntime.jsx(CwButton, { type: "button", onClick: handleClearClick, "aria-label": "Clear search", variant: "icon", icon: "close", color: "neutral" })) : (iconProps ? jsxRuntime.jsx(CwIcon, { ...iconProps }) : jsxRuntime.jsx(CwIcon, { iconId: "search" })) })] })] }), renderPanel(jsxRuntime.jsx("div", { ref: panelRef, id: listboxId, className: dropdownStyles.dropdown, style: panelStyle, role: "listbox", children: jsxRuntime.jsx("ul", { children: filteredOptions.map((option, index) => (jsxRuntime.jsx("li", { id: optionId(index), className: `${dropdownStyles.option}${index === highlightedIndex ? ` ${dropdownStyles.optionFocused}` : ""}`, onClick: () => handleOptionSelect(option), onMouseDown: (e) => e.preventDefault(), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": index === highlightedIndex, children: renderOption ? renderOption(option) : option.description }, option.id))) }) }))] }));
5702
5702
  }
5703
5703
 
5704
- var styles$8 = {"value":"cw-search-async-module__value__z53xT"};
5704
+ var styles$b = {"value":"cw-search-async-module__value__z53xT"};
5705
5705
 
5706
5706
  /**
5707
5707
  * Generic API-backed search input. Fetches matching options from a caller-supplied `onSearch`
@@ -5965,10 +5965,10 @@ const CwSearchAsync = ({ onSearch, onChange, value, onResolveInitial, onResolveS
5965
5965
  return (jsxRuntime.jsxs("div", { ...dataAttributes, className: `cw-search-input ${className}`, style: {
5966
5966
  ...(width ? { width } : {}),
5967
5967
  ...(labelProps?.labelWidth ? { "--label-width": labelProps.labelWidth } : {}),
5968
- }, "data-direction": direction, children: [jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$8.value, children: [jsxRuntime.jsxs("div", { className: "cw-search-input-wrapper", ref: wrapperRef, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, onChange: handleInputChange, onKeyDown: handleKeyDown, onFocus: handleInputFocus, placeholder: isInitialLoading ? "Loading…" : placeholder, disabled: disabled, required: required, autoComplete: "off", role: "combobox", "aria-haspopup": "listbox", "aria-expanded": showDropdown, "aria-controls": listboxId, "aria-activedescendant": highlightedIndex >= 0 ? optionId(highlightedIndex) : undefined, "aria-describedby": describedBy, title: tooltipText }), (isLoading || isInitialLoading) && (jsxRuntime.jsx("div", { className: "cw-search-input-loading", children: jsxRuntime.jsx(CwIcon, { iconId: "spinner" }) })), jsxRuntime.jsx("div", { className: "cw-search-input-icons", children: inputValue && !disabled && !isInitialLoading ? (jsxRuntime.jsx(CwButton, { type: "button", onClick: handleClear, "aria-label": "Clear selection", variant: "icon", icon: "close", color: "neutral" })) : (icon ? jsxRuntime.jsx(CwIcon, { ...icon }) : jsxRuntime.jsx(CwIcon, { iconId: "search" })) })] }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] })] }), renderPanel(jsxRuntime.jsx("div", { ref: panelRef, id: listboxId, className: dropdownStyles.dropdown, style: panelStyle, role: "listbox", children: jsxRuntime.jsx("ul", { children: options.map((option, index) => (jsxRuntime.jsx("li", { id: optionId(index), className: `${dropdownStyles.option}${index === highlightedIndex ? ` ${dropdownStyles.optionFocused}` : ""}`, onClick: () => handleOptionSelect(option.id), onMouseDown: (e) => e.preventDefault(), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": index === highlightedIndex, children: option.subLabel ? (jsxRuntime.jsxs("span", { className: "cw-search-async-option-lines", children: [jsxRuntime.jsx("span", { children: option.label }), jsxRuntime.jsx("span", { className: "cw-search-async-option-sub", children: option.subLabel })] })) : (option.label) }, option.id))) }) }))] }));
5968
+ }, "data-direction": direction, children: [jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$b.value, children: [jsxRuntime.jsxs("div", { className: "cw-search-input-wrapper", ref: wrapperRef, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, onChange: handleInputChange, onKeyDown: handleKeyDown, onFocus: handleInputFocus, placeholder: isInitialLoading ? "Loading…" : placeholder, disabled: disabled, required: required, autoComplete: "off", role: "combobox", "aria-haspopup": "listbox", "aria-expanded": showDropdown, "aria-controls": listboxId, "aria-activedescendant": highlightedIndex >= 0 ? optionId(highlightedIndex) : undefined, "aria-describedby": describedBy, title: tooltipText }), (isLoading || isInitialLoading) && (jsxRuntime.jsx("div", { className: "cw-search-input-loading", children: jsxRuntime.jsx(CwIcon, { iconId: "spinner" }) })), jsxRuntime.jsx("div", { className: "cw-search-input-icons", children: inputValue && !disabled && !isInitialLoading ? (jsxRuntime.jsx(CwButton, { type: "button", onClick: handleClear, "aria-label": "Clear selection", variant: "icon", icon: "close", color: "neutral" })) : (icon ? jsxRuntime.jsx(CwIcon, { ...icon }) : jsxRuntime.jsx(CwIcon, { iconId: "search" })) })] }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] })] }), renderPanel(jsxRuntime.jsx("div", { ref: panelRef, id: listboxId, className: dropdownStyles.dropdown, style: panelStyle, role: "listbox", children: jsxRuntime.jsx("ul", { children: options.map((option, index) => (jsxRuntime.jsx("li", { id: optionId(index), className: `${dropdownStyles.option}${index === highlightedIndex ? ` ${dropdownStyles.optionFocused}` : ""}`, onClick: () => handleOptionSelect(option.id), onMouseDown: (e) => e.preventDefault(), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": index === highlightedIndex, children: option.subLabel ? (jsxRuntime.jsxs("span", { className: "cw-search-async-option-lines", children: [jsxRuntime.jsx("span", { children: option.label }), jsxRuntime.jsx("span", { className: "cw-search-async-option-sub", children: option.subLabel })] })) : (option.label) }, option.id))) }) }))] }));
5969
5969
  };
5970
5970
 
5971
- var styles$7 = {"menu":"cw-context-menu-module__menu__tXmun","item":"cw-context-menu-module__item__-ko8L","arrow":"cw-context-menu-module__arrow__LHZmQ"};
5971
+ var styles$a = {"menu":"cw-context-menu-module__menu__tXmun","item":"cw-context-menu-module__item__-ko8L","arrow":"cw-context-menu-module__arrow__LHZmQ"};
5972
5972
 
5973
5973
  const ARROW_SIZE = 8;
5974
5974
  const SAFETY_MARGIN = 8;
@@ -6109,14 +6109,14 @@ const CwAnchoredMenu = ({ children, options, onSelect, placement = 'bottom', ope
6109
6109
  document.removeEventListener("keydown", handleEscape);
6110
6110
  };
6111
6111
  }, [isOpen]);
6112
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { ref: triggerRef, onContextMenu: handleContextMenu, style: { display: "contents" }, children: children }), isOpen && normalizedOptions.length > 0 && reactDom.createPortal(jsxRuntime.jsxs("div", { ref: menuRef, className: styles$7["menu"], style: {
6112
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { ref: triggerRef, onContextMenu: handleContextMenu, style: { display: "contents" }, children: children }), isOpen && normalizedOptions.length > 0 && reactDom.createPortal(jsxRuntime.jsxs("div", { ref: menuRef, className: styles$a["menu"], style: {
6113
6113
  top: `${position.y}px`,
6114
6114
  left: `${position.x}px`,
6115
- }, "data-has-arrow": "true", children: [jsxRuntime.jsx("div", { ref: arrowRef, className: styles$7["arrow"], "data-placement": placement }), normalizedOptions.map(option => (jsxRuntime.jsxs("div", { onClick: (e) => {
6115
+ }, "data-has-arrow": "true", children: [jsxRuntime.jsx("div", { ref: arrowRef, className: styles$a["arrow"], "data-placement": placement }), normalizedOptions.map(option => (jsxRuntime.jsxs("div", { onClick: (e) => {
6116
6116
  e.stopPropagation();
6117
6117
  e.preventDefault();
6118
6118
  handleOptionClick(option);
6119
- }, className: `${styles$7["item"]} ${option.disabled ? styles$7["disabled"] : ""}`, "data-disabled": option.disabled, children: [option.icon && jsxRuntime.jsx("span", { className: styles$7["icon"], children: option.icon }), option.label] }, option.key)))] }), document.body)] }));
6119
+ }, className: `${styles$a["item"]} ${option.disabled ? styles$a["disabled"] : ""}`, "data-disabled": option.disabled, children: [option.icon && jsxRuntime.jsx("span", { className: styles$a["icon"], children: option.icon }), option.label] }, option.key)))] }), document.body)] }));
6120
6120
  };
6121
6121
 
6122
6122
  /**
@@ -6189,13 +6189,13 @@ const CwContextMenu = ({ children, options, offset = DEFAULT_OFFSET, onSelect })
6189
6189
  document.removeEventListener("keydown", handleEscape);
6190
6190
  };
6191
6191
  }, [isOpen]);
6192
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { onContextMenu: handleContextMenu, children: children }), isOpen && reactDom.createPortal(jsxRuntime.jsx("div", { ref: menuRef, className: styles$7["menu"], style: {
6192
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { onContextMenu: handleContextMenu, children: children }), isOpen && reactDom.createPortal(jsxRuntime.jsx("div", { ref: menuRef, className: styles$a["menu"], style: {
6193
6193
  top: `${position.y}px`,
6194
6194
  left: `${position.x}px`,
6195
- }, children: options.map(option => (jsxRuntime.jsx("div", { onClick: () => handleOptionClick(option), className: styles$7["item"], children: option }, option))) }), document.body)] }));
6195
+ }, children: options.map(option => (jsxRuntime.jsx("div", { onClick: () => handleOptionClick(option), className: styles$a["item"], children: option }, option))) }), document.body)] }));
6196
6196
  };
6197
6197
 
6198
- var styles$6 = {"split":"cw-button-split-module__split__B2KbU","menu":"cw-button-split-module__menu__mKDlt","item":"cw-button-split-module__item__Aqw6f"};
6198
+ var styles$9 = {"split":"cw-button-split-module__split__B2KbU","menu":"cw-button-split-module__menu__mKDlt","item":"cw-button-split-module__item__Aqw6f"};
6199
6199
 
6200
6200
  /**
6201
6201
  * CwButtonSplit - A primary action joined to a dropdown of alternative actions.
@@ -6221,7 +6221,7 @@ function CwButtonSplit({ text, icon, onClick, actions, onSelect, variant = "soli
6221
6221
  onSelect(action.key);
6222
6222
  event.currentTarget.closest("[popover]")?.hidePopover();
6223
6223
  };
6224
- return (jsxRuntime.jsxs("div", { className: styles$6.split, "data-variant": variant, "data-testid": dataTestId, children: [jsxRuntime.jsx(CwButton, { text: text, icon: icon, variant: variant, color: color, size: size, onClick: onClick, disabled: disabled }), jsxRuntime.jsx(CwPopoverButton, { icon: "chevron-down", title: "More actions", variant: variant, color: color, size: size, disabled: disabled, placement: placement, children: jsxRuntime.jsx("div", { className: styles$6.menu, children: actions.map((action) => (jsxRuntime.jsx(CwButton, { variant: "ghost", color: "neutral", text: action.label, icon: action.icon, disabled: action.disabled, className: styles$6.item, onClick: handleSelect(action) }, action.key))) }) })] }));
6224
+ return (jsxRuntime.jsxs("div", { className: styles$9.split, "data-variant": variant, "data-testid": dataTestId, children: [jsxRuntime.jsx(CwButton, { text: text, icon: icon, variant: variant, color: color, size: size, onClick: onClick, disabled: disabled }), jsxRuntime.jsx(CwPopoverButton, { icon: "chevron-down", title: "More actions", variant: variant, color: color, size: size, disabled: disabled, placement: placement, children: jsxRuntime.jsx("div", { className: styles$9.menu, children: actions.map((action) => (jsxRuntime.jsx(CwButton, { variant: "ghost", color: "neutral", text: action.label, icon: action.icon, disabled: action.disabled, className: styles$9.item, onClick: handleSelect(action) }, action.key))) }) })] }));
6225
6225
  }
6226
6226
 
6227
6227
  /**
@@ -6289,7 +6289,7 @@ function useRovingSingleSelect(options, value, onChange) {
6289
6289
  return { activeIndex, getSegmentProps };
6290
6290
  }
6291
6291
 
6292
- var styles$5 = {"switch":"cw-button-switch-module__switch__vdWV-","segment":"cw-button-switch-module__segment__JmVla","iconOnly":"cw-button-switch-module__iconOnly__-kCwj"};
6292
+ var styles$8 = {"switch":"cw-button-switch-module__switch__vdWV-","segment":"cw-button-switch-module__segment__JmVla","iconOnly":"cw-button-switch-module__iconOnly__-kCwj"};
6293
6293
 
6294
6294
  /**
6295
6295
  * CwButtonSwitch - Segmented single-select control: a strip of joined CwButtons.
@@ -6319,10 +6319,10 @@ var styles$5 = {"switch":"cw-button-switch-module__switch__vdWV-","segment":"cw-
6319
6319
  */
6320
6320
  function CwButtonSwitch({ options, value, onChange, size = "medium", color = "primary", iconOnly = false, direction = "row", disabled = false, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, ...dataAttributes }) {
6321
6321
  const { getSegmentProps } = useRovingSingleSelect(options, value, onChange);
6322
- return (jsxRuntime.jsx("div", { ...dataAttributes, className: `cw-button-switch ${styles$5.switch}`, role: "radiogroup", "aria-labelledby": ariaLabelledby, "aria-label": ariaLabelledby ? undefined : ariaLabel, "data-direction": direction, children: options.map((option, index) => {
6322
+ return (jsxRuntime.jsx("div", { ...dataAttributes, className: `cw-button-switch ${styles$8.switch}`, role: "radiogroup", "aria-labelledby": ariaLabelledby, "aria-label": ariaLabelledby ? undefined : ariaLabel, "data-direction": direction, children: options.map((option, index) => {
6323
6323
  const selected = option.value === value;
6324
6324
  const segmentProps = getSegmentProps(index);
6325
- return (jsxRuntime.jsx(CwButton, { text: iconOnly ? undefined : option.label, title: iconOnly ? option.label : undefined, icon: option.icon, size: size, color: color, variant: selected ? "solid" : "outline", role: "radio", "aria-checked": selected, disabled: disabled || option.disabled, onClick: () => onChange(option.value), className: `${styles$5.segment}${iconOnly ? ` ${styles$5.iconOnly}` : ""}`, tabIndex: segmentProps.tabIndex, ref: segmentProps.ref, onKeyDown: segmentProps.onKeyDown }, option.value));
6325
+ return (jsxRuntime.jsx(CwButton, { text: iconOnly ? undefined : option.label, title: iconOnly ? option.label : undefined, icon: option.icon, size: size, color: color, variant: selected ? "solid" : "outline", role: "radio", "aria-checked": selected, disabled: disabled || option.disabled, onClick: () => onChange(option.value), className: `${styles$8.segment}${iconOnly ? ` ${styles$8.iconOnly}` : ""}`, tabIndex: segmentProps.tabIndex, ref: segmentProps.ref, onKeyDown: segmentProps.onKeyDown }, option.value));
6326
6326
  }) }));
6327
6327
  }
6328
6328
 
@@ -6364,7 +6364,7 @@ function CwBtnCancel({ cw_btnOnclick, cw_btn_disabled, onClick, disabled, ...res
6364
6364
  return (jsxRuntime.jsx(CwButton, { ...rest, variant: "icon", icon: "cancel", color: "danger", onClick: onClick ?? cw_btnOnclick, disabled: disabled ?? cw_btn_disabled, title: "Cancel" }));
6365
6365
  }
6366
6366
 
6367
- var styles$4 = {"value":"cw-pickers-base-module__value__BR67P","pickerWrapper":"cw-pickers-base-module__pickerWrapper__Fb9Zo","pickerIcons":"cw-pickers-base-module__pickerIcons__dyd2-","pickerPopup":"cw-pickers-base-module__pickerPopup__dkxJo"};
6367
+ var styles$7 = {"value":"cw-pickers-base-module__value__BR67P","pickerWrapper":"cw-pickers-base-module__pickerWrapper__Fb9Zo","pickerIcons":"cw-pickers-base-module__pickerIcons__dyd2-","pickerPopup":"cw-pickers-base-module__pickerPopup__dkxJo"};
6368
6368
 
6369
6369
  /**
6370
6370
  * Renders a picker popup in a portal so it escapes overflow containers.
@@ -6604,7 +6604,7 @@ function CwDatePicker({ value, onChange, minDate, maxDate, disabledDates, disabl
6604
6604
  ...(maxDate ? [{ after: maxDate }] : []),
6605
6605
  ...(disabledMatcher ? [disabledMatcher] : []),
6606
6606
  ], [disabledDates, minDate, maxDate, disabledMatcher]);
6607
- return (jsxRuntime.jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-datepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$4.value, children: [jsxRuntime.jsxs("div", { ref: wrapperRef, className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) }), renderPopup(jsxRuntime.jsxs("div", { ref: popupRef, className: styles$4.pickerPopup, style: popupStyle, children: [jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "single", selected: value || undefined, defaultMonth: defaultMonth || value || undefined, onSelect: handleDaySelect, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale$1, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
6607
+ return (jsxRuntime.jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-datepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$7.value, children: [jsxRuntime.jsxs("div", { ref: wrapperRef, className: styles$7.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length }), jsxRuntime.jsx("div", { className: styles$7.pickerIcons, children: showClear && value && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) }), renderPopup(jsxRuntime.jsxs("div", { ref: popupRef, className: styles$7.pickerPopup, style: popupStyle, children: [jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "single", selected: value || undefined, defaultMonth: defaultMonth || value || undefined, onSelect: handleDaySelect, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale$1, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
6608
6608
  today: new Date(),
6609
6609
  }, modifiersClassNames: {
6610
6610
  today: "rdp-day-today",
@@ -7253,7 +7253,7 @@ function CwDateRangePicker({ value, onChange, minDate, maxDate, disabledDates, d
7253
7253
  }
7254
7254
  return undefined;
7255
7255
  }, [value]);
7256
- return (jsxRuntime.jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-rangepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$4.value, children: [jsxRuntime.jsxs("div", { ref: wrapperRef, className: rangeStyles.rangeWrapper, children: [jsxRuntime.jsxs("div", { className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputFromRef, type: "text", value: inputFromValue, placeholder: placeholderFrom, onChange: handleInputFromChange, onBlur: () => handleInputBlur('from'), onClick: handleInputFromClick, onKeyDown: (e) => handleInputKeyDown(e, 'from'), disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length, "data-focused": focusedInput === 'from' }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.from && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearFrom, tabIndex: -1, "aria-label": "Clear from date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), jsxRuntime.jsx(CwIcon, { iconId: "arrow-right", size: "medium" }), jsxRuntime.jsxs("div", { className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputToRef, type: "text", value: inputToValue, placeholder: placeholderTo, onChange: handleInputToChange, onBlur: () => handleInputBlur('to'), onClick: handleInputToClick, onKeyDown: (e) => handleInputKeyDown(e, 'to'), disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length, "data-focused": focusedInput === 'to' }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.to && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearTo, tabIndex: -1, "aria-label": "Clear to date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), renderPopup(jsxRuntime.jsxs("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${rangeStyles.rangePopup}`, style: popupStyle, children: [jsxRuntime.jsxs("div", { className: rangeStyles.rangeCalendarRow, children: [showPresets && presetsToRender.length > 0 && (jsxRuntime.jsx("div", { className: rangeStyles.presetList, children: presetsToRender.map((preset) => (jsxRuntime.jsx("button", { type: "button", onClick: (e) => handlePresetClick(preset, e), children: preset.label }, preset.key))) })), jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, numberOfMonths: numberOfMonths, defaultMonth: defaultMonth || value?.from || undefined, modifiers: {
7256
+ return (jsxRuntime.jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-rangepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$7.value, children: [jsxRuntime.jsxs("div", { ref: wrapperRef, className: rangeStyles.rangeWrapper, children: [jsxRuntime.jsxs("div", { className: styles$7.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputFromRef, type: "text", value: inputFromValue, placeholder: placeholderFrom, onChange: handleInputFromChange, onBlur: () => handleInputBlur('from'), onClick: handleInputFromClick, onKeyDown: (e) => handleInputKeyDown(e, 'from'), disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length, "data-focused": focusedInput === 'from' }), jsxRuntime.jsx("div", { className: styles$7.pickerIcons, children: showClear && value?.from && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearFrom, tabIndex: -1, "aria-label": "Clear from date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), jsxRuntime.jsx(CwIcon, { iconId: "arrow-right", size: "medium" }), jsxRuntime.jsxs("div", { className: styles$7.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputToRef, type: "text", value: inputToValue, placeholder: placeholderTo, onChange: handleInputToChange, onBlur: () => handleInputBlur('to'), onClick: handleInputToClick, onKeyDown: (e) => handleInputKeyDown(e, 'to'), disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length, "data-focused": focusedInput === 'to' }), jsxRuntime.jsx("div", { className: styles$7.pickerIcons, children: showClear && value?.to && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearTo, tabIndex: -1, "aria-label": "Clear to date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), renderPopup(jsxRuntime.jsxs("div", { ref: popupRef, className: `${styles$7.pickerPopup} ${rangeStyles.rangePopup}`, style: popupStyle, children: [jsxRuntime.jsxs("div", { className: rangeStyles.rangeCalendarRow, children: [showPresets && presetsToRender.length > 0 && (jsxRuntime.jsx("div", { className: rangeStyles.presetList, children: presetsToRender.map((preset) => (jsxRuntime.jsx("button", { type: "button", onClick: (e) => handlePresetClick(preset, e), children: preset.label }, preset.key))) })), jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, numberOfMonths: numberOfMonths, defaultMonth: defaultMonth || value?.from || undefined, modifiers: {
7257
7257
  today: new Date(),
7258
7258
  }, modifiersClassNames: {
7259
7259
  today: "rdp-day-today",
@@ -7426,10 +7426,10 @@ function CwTimePicker({ value, onChange, interval = 15, minTime, maxTime, labelP
7426
7426
  const displayValue = inputValue;
7427
7427
  // If using native time input
7428
7428
  if (useNative) {
7429
- return (jsxRuntime.jsx("div", { ...dataAttributes, className: `cw-timepicker cw-timepicker-native ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$4.value, children: [jsxRuntime.jsx("div", { className: styles$4.pickerWrapper, children: jsxRuntime.jsx("input", { type: "time", value: displayValue, onChange: handleNativeChange, min: minTime, max: maxTime, step: interval * 60, disabled: disabled, required: required, placeholder: placeholder, "aria-describedby": describedBy, className: "cw-timepicker-native" }) }), feedbackElements] })] }) }));
7429
+ return (jsxRuntime.jsx("div", { ...dataAttributes, className: `cw-timepicker cw-timepicker-native ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$7.value, children: [jsxRuntime.jsx("div", { className: styles$7.pickerWrapper, children: jsxRuntime.jsx("input", { type: "time", value: displayValue, onChange: handleNativeChange, min: minTime, max: maxTime, step: interval * 60, disabled: disabled, required: required, placeholder: placeholder, "aria-describedby": describedBy, className: "cw-timepicker-native" }) }), feedbackElements] })] }) }));
7430
7430
  }
7431
7431
  // Custom time picker
7432
- return (jsxRuntime.jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-timepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$4.value, children: [jsxRuntime.jsxs("div", { ref: wrapperRef, className: `${styles$4.pickerWrapper} ${timeStyles.field}${showClear ? "" : ` ${timeStyles.narrow}`}`, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, "aria-describedby": describedBy, required: required, maxLength: 5 }), showClear && (jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: value && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", icon: "close", color: "neutral", onClick: handleClear, tabIndex: -1, "aria-label": "Clear time" })) : (jsxRuntime.jsx(CwIcon, { iconId: "clock" })) })), renderPopup(jsxRuntime.jsx("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${timeStyles.timePickerPopup}`, style: popupStyle, children: jsxRuntime.jsx("div", { className: timeStyles.timePickerList, children: timeOptions.map((time) => {
7432
+ return (jsxRuntime.jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-timepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$7.value, children: [jsxRuntime.jsxs("div", { ref: wrapperRef, className: `${styles$7.pickerWrapper} ${timeStyles.field}${showClear ? "" : ` ${timeStyles.narrow}`}`, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, "aria-describedby": describedBy, required: required, maxLength: 5 }), showClear && (jsxRuntime.jsx("div", { className: styles$7.pickerIcons, children: value && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", icon: "close", color: "neutral", onClick: handleClear, tabIndex: -1, "aria-label": "Clear time" })) : (jsxRuntime.jsx(CwIcon, { iconId: "clock" })) })), renderPopup(jsxRuntime.jsx("div", { ref: popupRef, className: `${styles$7.pickerPopup} ${timeStyles.timePickerPopup}`, style: popupStyle, children: jsxRuntime.jsx("div", { className: timeStyles.timePickerList, children: timeOptions.map((time) => {
7433
7433
  const isSelected = time === value;
7434
7434
  return (jsxRuntime.jsx("button", { ref: isSelected ? selectedItemRef : null, type: "button", className: isSelected ? timeStyles.selected : "", onClick: () => handleTimeSelect(time), children: time }, time));
7435
7435
  }) }) }))] }), feedbackElements] })] }) }));
@@ -7737,7 +7737,7 @@ function CwDateTimePicker({ value, onChange, minDateTime, maxDateTime, disabledD
7737
7737
  const displayMaxDate = React.useMemo(() => normalizedMaxDateTime && timezoneOffset !== undefined
7738
7738
  ? getDateInOffset(normalizedMaxDateTime, timezoneOffset)
7739
7739
  : normalizedMaxDateTime, [normalizedMaxDateTime, timezoneOffset]);
7740
- return jsxRuntime.jsx("div", { ...dataAttributes, className: `cw-datetimepicker cw-datetimepicker-separate ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$4.value, children: [jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-left-center cw-gap-small", children: [jsxRuntime.jsx(CwDatePicker, { value: selectedDate, onChange: handleDateChange, minDate: displayMinDate, maxDate: displayMaxDate, disabledDates: disabledDates, disabledMatcher: disabledMatcher, placeholder: datePlaceholder, disabled: disabled, required: required, showClear: showClear, numberOfMonths: numberOfMonths, popupPosition: popupPosition, locale: locale$1 }), jsxRuntime.jsx(CwTimePicker, { value: selectedTime, onChange: handleTimeChange, interval: timeInterval, minTime: timeRestrictions.minTime, maxTime: timeRestrictions.maxTime, placeholder: timePlaceholder, disabled: disabled, required: required, showClear: showClear, popupPosition: popupPosition }), showNowButton && (jsxRuntime.jsx(CwButton, { type: "button", variant: "outline", onClick: handleNowClick, disabled: disabled, text: nowLabel }))] }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] })] }) });
7740
+ return jsxRuntime.jsx("div", { ...dataAttributes, className: `cw-datetimepicker cw-datetimepicker-separate ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$7.value, children: [jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-left-center cw-gap-small", children: [jsxRuntime.jsx(CwDatePicker, { value: selectedDate, onChange: handleDateChange, minDate: displayMinDate, maxDate: displayMaxDate, disabledDates: disabledDates, disabledMatcher: disabledMatcher, placeholder: datePlaceholder, disabled: disabled, required: required, showClear: showClear, numberOfMonths: numberOfMonths, popupPosition: popupPosition, locale: locale$1 }), jsxRuntime.jsx(CwTimePicker, { value: selectedTime, onChange: handleTimeChange, interval: timeInterval, minTime: timeRestrictions.minTime, maxTime: timeRestrictions.maxTime, placeholder: timePlaceholder, disabled: disabled, required: required, showClear: showClear, popupPosition: popupPosition }), showNowButton && (jsxRuntime.jsx(CwButton, { type: "button", variant: "outline", onClick: handleNowClick, disabled: disabled, text: nowLabel }))] }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] })] }) });
7741
7741
  }
7742
7742
 
7743
7743
  var compactStyles = {"compactPopup":"cw-datetime-compact-module__compactPopup__GiuNY","calendarWrapper":"cw-datetime-compact-module__calendarWrapper__P4Nlq","timeWrapper":"cw-datetime-compact-module__timeWrapper__uMe-A","compactTimeList":"cw-datetime-compact-module__compactTimeList__MzSQT"};
@@ -7993,7 +7993,7 @@ function CwDateTimePickerCompact({ value, onChange, minDateTime, maxDateTime, di
7993
7993
  ...(maxDateTime ? [{ after: maxDateTime }] : []),
7994
7994
  ...(disabledMatcher ? [disabledMatcher] : []),
7995
7995
  ], [disabledDates, minDateTime, maxDateTime, disabledMatcher]);
7996
- return (jsxRuntime.jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-datetimepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$4.value, children: [jsxRuntime.jsxs("div", { ref: wrapperRef, className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, "aria-describedby": describedBy, required: required, maxLength: 16 }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear datetime" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar-time" })) }), renderPopup(jsxRuntime.jsxs("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${compactStyles.compactPopup}`, style: popupStyle, children: [jsxRuntime.jsxs("div", { className: compactStyles.calendarWrapper, children: [jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "single", selected: selectedDate, onSelect: handleDaySelect, defaultMonth: selectedDate, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale$1, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
7996
+ return (jsxRuntime.jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-datetimepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$7.value, children: [jsxRuntime.jsxs("div", { ref: wrapperRef, className: styles$7.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, "aria-describedby": describedBy, required: required, maxLength: 16 }), jsxRuntime.jsx("div", { className: styles$7.pickerIcons, children: showClear && value && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear datetime" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar-time" })) }), renderPopup(jsxRuntime.jsxs("div", { ref: popupRef, className: `${styles$7.pickerPopup} ${compactStyles.compactPopup}`, style: popupStyle, children: [jsxRuntime.jsxs("div", { className: compactStyles.calendarWrapper, children: [jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "single", selected: selectedDate, onSelect: handleDaySelect, defaultMonth: selectedDate, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale$1, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
7997
7997
  today: new Date(),
7998
7998
  }, modifiersClassNames: {
7999
7999
  today: "rdp-day-today",
@@ -8228,7 +8228,7 @@ function CwDatePickerTemporal({ value, onChange, minDate, maxDate, disabledDates
8228
8228
  const defaultMonthJsDate = defaultMonth
8229
8229
  ? new Date(defaultMonth.year, defaultMonth.month - 1, 1)
8230
8230
  : selectedJsDate;
8231
- return (jsxRuntime.jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-datepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$4.value, children: [jsxRuntime.jsxs("div", { ref: wrapperRef, className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) }), renderPopup(jsxRuntime.jsxs("div", { ref: popupRef, className: styles$4.pickerPopup, style: popupStyle, children: [jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "single", selected: selectedJsDate, defaultMonth: defaultMonthJsDate, onSelect: handleDaySelect, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale$1, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
8231
+ return (jsxRuntime.jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-datepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$7.value, children: [jsxRuntime.jsxs("div", { ref: wrapperRef, className: styles$7.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: inputValue, placeholder: placeholder, onChange: handleInputChange, onBlur: handleInputBlur, onClick: handleInputClick, onKeyDown: handleInputKeyDown, disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length }), jsxRuntime.jsx("div", { className: styles$7.pickerIcons, children: showClear && value && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClear, tabIndex: -1, "aria-label": "Clear date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) }), renderPopup(jsxRuntime.jsxs("div", { ref: popupRef, className: styles$7.pickerPopup, style: popupStyle, children: [jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "single", selected: selectedJsDate, defaultMonth: defaultMonthJsDate, onSelect: handleDaySelect, disabled: disabledDays, numberOfMonths: numberOfMonths, locale: locale$1, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
8232
8232
  today: new Date(),
8233
8233
  }, modifiersClassNames: {
8234
8234
  today: "rdp-day-today",
@@ -8529,7 +8529,7 @@ function CwDateTimePickerTemporal({ value, onChange, minDateTime, maxDateTime, d
8529
8529
  minTime,
8530
8530
  maxTime,
8531
8531
  });
8532
- return jsxRuntime.jsx("div", { ...dataAttributes, className: `cw-datetimepicker cw-datetimepicker-separate ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$4.value, children: [jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-left-center cw-gap-small", children: [jsxRuntime.jsx(CwDatePickerTemporal, { value: picker.date, onChange: picker.selectDate, minDate: picker.minDate, maxDate: picker.maxDate, disabledDates: disabledDates, disabledMatcher: disabledMatcher, placeholder: datePlaceholder, disabled: disabled, required: required, showClear: showClear, numberOfMonths: numberOfMonths, popupPosition: popupPosition, locale: locale$1 }), jsxRuntime.jsx(CwTimePicker, { value: picker.time, onChange: picker.selectTime, interval: timeInterval, minTime: picker.effectiveMinTime, maxTime: picker.effectiveMaxTime, placeholder: timePlaceholder, disabled: disabled, required: required, showClear: showClear, popupPosition: popupPosition }), showNowButton && (jsxRuntime.jsx(CwButton, { type: "button", variant: "outline", onClick: picker.selectNow, disabled: disabled, text: nowLabel }))] }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] })] }) });
8532
+ return jsxRuntime.jsx("div", { ...dataAttributes, className: `cw-datetimepicker cw-datetimepicker-separate ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$7.value, children: [jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-left-center cw-gap-small", children: [jsxRuntime.jsx(CwDatePickerTemporal, { value: picker.date, onChange: picker.selectDate, minDate: picker.minDate, maxDate: picker.maxDate, disabledDates: disabledDates, disabledMatcher: disabledMatcher, placeholder: datePlaceholder, disabled: disabled, required: required, showClear: showClear, numberOfMonths: numberOfMonths, popupPosition: popupPosition, locale: locale$1 }), jsxRuntime.jsx(CwTimePicker, { value: picker.time, onChange: picker.selectTime, interval: timeInterval, minTime: picker.effectiveMinTime, maxTime: picker.effectiveMaxTime, placeholder: timePlaceholder, disabled: disabled, required: required, showClear: showClear, popupPosition: popupPosition }), showNowButton && (jsxRuntime.jsx(CwButton, { type: "button", variant: "outline", onClick: picker.selectNow, disabled: disabled, text: nowLabel }))] }), feedbackMessages.map((feedbackItem, index) => (jsxRuntime.jsx("p", { id: feedbackIds[index], className: "cw-input-feedback", "data-color": feedbackItem.type, "aria-live": "polite", children: feedbackItem.message }, index)))] })] }) });
8533
8533
  }
8534
8534
 
8535
8535
  // dateRangePresetsTemporal.ts
@@ -8981,7 +8981,7 @@ function CwDateRangePickerTemporal({ value, onChange, minDate, maxDate, disabled
8981
8981
  const defaultMonthJsDate = defaultMonth
8982
8982
  ? new Date(defaultMonth.year, defaultMonth.month - 1, 1)
8983
8983
  : (value?.from ? plainDateToJsDate(value.from) : undefined);
8984
- return (jsxRuntime.jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-rangepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$4.value, children: [jsxRuntime.jsxs("div", { ref: wrapperRef, className: rangeStyles.rangeWrapper, children: [jsxRuntime.jsxs("div", { className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputFromRef, type: "text", value: inputFromValue, placeholder: placeholderFrom, onChange: handleInputFromChange, onBlur: () => handleInputBlur('from'), onClick: handleInputFromClick, onKeyDown: (e) => handleInputKeyDown(e, 'from'), disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length, "data-focused": focusedInput === 'from' }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.from && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearFrom, tabIndex: -1, "aria-label": "Clear from date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), jsxRuntime.jsx(CwIcon, { iconId: "arrow-right", size: "medium" }), jsxRuntime.jsxs("div", { className: styles$4.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputToRef, type: "text", value: inputToValue, placeholder: placeholderTo, onChange: handleInputToChange, onBlur: () => handleInputBlur('to'), onClick: handleInputToClick, onKeyDown: (e) => handleInputKeyDown(e, 'to'), disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length, "data-focused": focusedInput === 'to' }), jsxRuntime.jsx("div", { className: styles$4.pickerIcons, children: showClear && value?.to && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearTo, tabIndex: -1, "aria-label": "Clear to date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), renderPopup(jsxRuntime.jsxs("div", { ref: popupRef, className: `${styles$4.pickerPopup} ${rangeStyles.rangePopup}`, style: popupStyle, children: [jsxRuntime.jsxs("div", { className: rangeStyles.rangeCalendarRow, children: [showPresets && presetsToRender.length > 0 && (jsxRuntime.jsx("div", { className: rangeStyles.presetList, children: presetsToRender.map((preset) => (jsxRuntime.jsx("button", { type: "button", onClick: (e) => handlePresetClick(preset, e), children: preset.label }, preset.key))) })), jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, numberOfMonths: numberOfMonths, defaultMonth: defaultMonthJsDate, locale: locale$1, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
8984
+ return (jsxRuntime.jsx("div", { ...dataAttributes, ref: containerRef, className: `cw-rangepicker ${className || ""}`, children: jsxRuntime.jsxs(CwAlign, { ...alignProps, itemProp: required ? "required" : "", children: [labelProps && (jsxRuntime.jsx(CwLabel, { ...labelProps, children: labelProps.text })), jsxRuntime.jsxs("div", { className: styles$7.value, children: [jsxRuntime.jsxs("div", { ref: wrapperRef, className: rangeStyles.rangeWrapper, children: [jsxRuntime.jsxs("div", { className: styles$7.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputFromRef, type: "text", value: inputFromValue, placeholder: placeholderFrom, onChange: handleInputFromChange, onBlur: () => handleInputBlur('from'), onClick: handleInputFromClick, onKeyDown: (e) => handleInputKeyDown(e, 'from'), disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length, "data-focused": focusedInput === 'from' }), jsxRuntime.jsx("div", { className: styles$7.pickerIcons, children: showClear && value?.from && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearFrom, tabIndex: -1, "aria-label": "Clear from date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), jsxRuntime.jsx(CwIcon, { iconId: "arrow-right", size: "medium" }), jsxRuntime.jsxs("div", { className: styles$7.pickerWrapper, children: [jsxRuntime.jsx("input", { ref: inputToRef, type: "text", value: inputToValue, placeholder: placeholderTo, onChange: handleInputToChange, onBlur: () => handleInputBlur('to'), onClick: handleInputToClick, onKeyDown: (e) => handleInputKeyDown(e, 'to'), disabled: disabled, "aria-describedby": describedBy, required: required, size: displayFormat.length, "data-focused": focusedInput === 'to' }), jsxRuntime.jsx("div", { className: styles$7.pickerIcons, children: showClear && value?.to && !disabled ? (jsxRuntime.jsx(CwButton, { type: "button", variant: "icon", color: "neutral", icon: "close", onClick: handleClearTo, tabIndex: -1, "aria-label": "Clear to date" })) : (jsxRuntime.jsx(CwIcon, { iconId: "calendar" })) })] }), renderPopup(jsxRuntime.jsxs("div", { ref: popupRef, className: `${styles$7.pickerPopup} ${rangeStyles.rangePopup}`, style: popupStyle, children: [jsxRuntime.jsxs("div", { className: rangeStyles.rangeCalendarRow, children: [showPresets && presetsToRender.length > 0 && (jsxRuntime.jsx("div", { className: rangeStyles.presetList, children: presetsToRender.map((preset) => (jsxRuntime.jsx("button", { type: "button", onClick: (e) => handlePresetClick(preset, e), children: preset.label }, preset.key))) })), jsxRuntime.jsx(reactDayPicker.DayPicker, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, numberOfMonths: numberOfMonths, defaultMonth: defaultMonthJsDate, locale: locale$1, captionLayout: "dropdown", startMonth: dropdownStartMonth, endMonth: dropdownEndMonth, modifiers: {
8985
8985
  today: new Date(),
8986
8986
  }, modifiersClassNames: {
8987
8987
  today: "rdp-day-today",
@@ -9128,7 +9128,7 @@ class OnClickContextMenu {
9128
9128
  }
9129
9129
  }
9130
9130
 
9131
- var styles$3 = {"scheduler-header":"scheduler-header-module__scheduler-header__Y7SNV","scheduler-header-divisions":"scheduler-header-module__scheduler-header-divisions__1JrNe","scheduler-timeline-now":"scheduler-header-module__scheduler-timeline-now__naREv","scheduler-timeline-label":"scheduler-header-module__scheduler-timeline-label__mLVAp","scheduler-header-title":"scheduler-header-module__scheduler-header-title__Jzy94","title-cell":"scheduler-header-module__title-cell__mz7Ki","title":"scheduler-header-module__title__TuJVn","scheduler-dates":"scheduler-header-module__scheduler-dates__O7ePQ","current-day":"scheduler-header-module__current-day__FpHiv","scheduler-hours":"scheduler-header-module__scheduler-hours__ZDCVj"};
9131
+ var styles$6 = {"scheduler-header":"scheduler-header-module__scheduler-header__Y7SNV","scheduler-header-divisions":"scheduler-header-module__scheduler-header-divisions__1JrNe","scheduler-timeline-now":"scheduler-header-module__scheduler-timeline-now__naREv","scheduler-timeline-label":"scheduler-header-module__scheduler-timeline-label__mLVAp","scheduler-header-title":"scheduler-header-module__scheduler-header-title__Jzy94","title-cell":"scheduler-header-module__title-cell__mz7Ki","title":"scheduler-header-module__title__TuJVn","scheduler-dates":"scheduler-header-module__scheduler-dates__O7ePQ","current-day":"scheduler-header-module__current-day__FpHiv","scheduler-hours":"scheduler-header-module__scheduler-hours__ZDCVj"};
9132
9132
 
9133
9133
  const getNow$1 = (isUtc) => {
9134
9134
  let now = new Date();
@@ -9157,9 +9157,9 @@ const TimeLine = ({ left, top = "0px", height, color, width = "2px", zIndexNumbe
9157
9157
  background: color,
9158
9158
  pointerEvents: "none",
9159
9159
  zIndex: zIndexNumber,
9160
- }, className: styles$3["scheduler-timeline-now"], children: isHeader && (jsxRuntime.jsx("span", { style: {
9160
+ }, className: styles$6["scheduler-timeline-now"], children: isHeader && (jsxRuntime.jsx("span", { style: {
9161
9161
  color: color,
9162
- }, className: styles$3["scheduler-timeline-label"], children: currentTime.toLocaleTimeString([], {
9162
+ }, className: styles$6["scheduler-timeline-label"], children: currentTime.toLocaleTimeString([], {
9163
9163
  hour: '2-digit',
9164
9164
  minute: '2-digit',
9165
9165
  hour12: false
@@ -9186,17 +9186,17 @@ const SchedulerHeaderDivision = ({ topDivisions, bottomDivisions, classification
9186
9186
  return (jsxRuntime.jsxs("div", { style: {
9187
9187
  width: topWidth,
9188
9188
  cursor: "pointer"
9189
- }, children: [jsxRuntime.jsx("div", { className: `${styles$3["scheduler-dates"]} ${isToday(startDate, endDate) ? styles$3["current-day"] : ""}`, children: jsxRuntime.jsx("span", { children: topDivisions }) }), jsxRuntime.jsx("div", { style: { display: "flex", justifyContent: "space-between", flex: 1 }, children: bottomDivisions.map((element) => (jsxRuntime.jsx("div", { className: styles$3["scheduler-hours"], children: jsxRuntime.jsx("span", { children: element }) }, classification + element + topDivisions))) })] }));
9189
+ }, children: [jsxRuntime.jsx("div", { className: `${styles$6["scheduler-dates"]} ${isToday(startDate, endDate) ? styles$6["current-day"] : ""}`, children: jsxRuntime.jsx("span", { children: topDivisions }) }), jsxRuntime.jsx("div", { style: { display: "flex", justifyContent: "space-between", flex: 1 }, children: bottomDivisions.map((element) => (jsxRuntime.jsx("div", { className: styles$6["scheduler-hours"], children: jsxRuntime.jsx("span", { children: element }) }, classification + element + topDivisions))) })] }));
9190
9190
  };
9191
9191
 
9192
9192
  const HeaderTitle = ({ title, dividerText, width }) => {
9193
- return (jsxRuntime.jsxs("div", { className: styles$3["scheduler-header-title"], style: { width: width }, children: [jsxRuntime.jsx("div", { className: styles$3["title-cell"], children: jsxRuntime.jsx("span", { className: styles$3.title, children: title }) }), jsxRuntime.jsx("div", { children: jsxRuntime.jsx("span", { children: dividerText }) })] }));
9193
+ return (jsxRuntime.jsxs("div", { className: styles$6["scheduler-header-title"], style: { width: width }, children: [jsxRuntime.jsx("div", { className: styles$6["title-cell"], children: jsxRuntime.jsx("span", { className: styles$6.title, children: title }) }), jsxRuntime.jsx("div", { children: jsxRuntime.jsx("span", { children: dividerText }) })] }));
9194
9194
  };
9195
9195
 
9196
9196
  const SchedulerHeader = ({ content, divisions, visibleDays, selectedDate, width, onEvent, timeLinePercentage, isUtc }) => {
9197
9197
  const topWidth = (100 / visibleDays);
9198
9198
  const { title, classification } = content;
9199
- return (jsxRuntime.jsxs("div", { className: styles$3["scheduler-header"], children: [jsxRuntime.jsx(HeaderTitle, { title: title, dividerText: classification, width: width }), jsxRuntime.jsxs("div", { className: styles$3["scheduler-header-divisions"], style: { flex: 1, display: "flex", position: "relative" }, onMouseDown: (e) => {
9199
+ return (jsxRuntime.jsxs("div", { className: styles$6["scheduler-header"], children: [jsxRuntime.jsx(HeaderTitle, { title: title, dividerText: classification, width: width }), jsxRuntime.jsxs("div", { className: styles$6["scheduler-header-divisions"], style: { flex: 1, display: "flex", position: "relative" }, onMouseDown: (e) => {
9200
9200
  e.preventDefault();
9201
9201
  const clickPercentage = getPercentageFromMouseEvent(e);
9202
9202
  const date = dateFromPercentage(selectedDate, visibleDays, clickPercentage);
@@ -9228,7 +9228,7 @@ function getStartEnd(day) {
9228
9228
  };
9229
9229
  }
9230
9230
 
9231
- var styles$2 = {"hide-scrollbar":"new-scheduler-module__hide-scrollbar__33GG9","scheduler-event":"new-scheduler-module__scheduler-event__gphwn","scheduler-event-container":"new-scheduler-module__scheduler-event-container__-h1xm","time-marker":"new-scheduler-module__time-marker__2BejU","underlay":"new-scheduler-module__underlay__RVCnV","label-halo":"new-scheduler-module__label-halo__84c7e","corner-marker":"new-scheduler-module__corner-marker__w7o90","color-bars":"new-scheduler-module__color-bars__MhMF7","scheduler-event-text":"new-scheduler-module__scheduler-event-text__zjvd7"};
9231
+ var styles$5 = {"hide-scrollbar":"new-scheduler-module__hide-scrollbar__33GG9","scheduler-event":"new-scheduler-module__scheduler-event__gphwn","scheduler-event-container":"new-scheduler-module__scheduler-event-container__-h1xm","time-marker":"new-scheduler-module__time-marker__2BejU","underlay":"new-scheduler-module__underlay__RVCnV","label-halo":"new-scheduler-module__label-halo__84c7e","corner-marker":"new-scheduler-module__corner-marker__w7o90","color-bars":"new-scheduler-module__color-bars__MhMF7","scheduler-event-text":"new-scheduler-module__scheduler-event-text__zjvd7"};
9232
9232
 
9233
9233
  const BackgroundEvent = ({ value, heightRem }) => {
9234
9234
  const backColor = getHSLColor(value.color, value.alpha ?? 0.5);
@@ -9255,13 +9255,13 @@ const BackgroundEvent = ({ value, heightRem }) => {
9255
9255
  padding: "0.25rem",
9256
9256
  color: textColor,
9257
9257
  alignItems: value.contentAlign ?? "center"
9258
- }, className: styles$2["scheduler-event-container"], children: [value.icons ? jsxRuntime.jsx("div", { style: {
9258
+ }, className: styles$5["scheduler-event-container"], children: [value.icons ? jsxRuntime.jsx("div", { style: {
9259
9259
  display: "flex",
9260
9260
  flexDirection: "row",
9261
9261
  alignItems: "center",
9262
9262
  whiteSpace: "nowrap",
9263
9263
  color: textColor,
9264
- }, children: value.icons }) : null, jsxRuntime.jsx("span", { className: styles$2["scheduler-event-text"], children: value.name })] }) }) }) }) })) : null;
9264
+ }, children: value.icons }) : null, jsxRuntime.jsx("span", { className: styles$5["scheduler-event-text"], children: value.name })] }) }) }) }) })) : null;
9265
9265
  };
9266
9266
 
9267
9267
  const eventIsVisible = (startDate, endDate, selectedDate, visibleDays) => {
@@ -9423,7 +9423,7 @@ const WeekEndLine = ({ left, top = "0px", height, widthPercentage }) => {
9423
9423
  } }));
9424
9424
  };
9425
9425
 
9426
- var styles$1 = {"scheduler-row-header":"scheduler-row-module__scheduler-row-header__S-iv4"};
9426
+ var styles$4 = {"scheduler-row-header":"scheduler-row-module__scheduler-row-header__S-iv4"};
9427
9427
 
9428
9428
  const DefaultRowHeader = ({ value, width, onEvent }) => {
9429
9429
  return (jsxRuntime.jsxs("div", { style: {
@@ -9432,7 +9432,7 @@ const DefaultRowHeader = ({ value, width, onEvent }) => {
9432
9432
  background: value.highlightColor,
9433
9433
  }, onClick: (_) => {
9434
9434
  onEvent(new OnClickRowHeader(value.rowId));
9435
- }, className: styles$1["scheduler-row-header"], children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { children: value.title }), value.title2 && jsxRuntime.jsxs("span", { children: ["-", value.title2] }), " ", jsxRuntime.jsx("strong", { children: value.subtitle })] }), value.subtitle && jsxRuntime.jsxs("div", { style: { opacity: 0.5 }, children: [value.title3 && jsxRuntime.jsxs("span", { className: styles$1["scheduler-crewmember-functions"], children: ["(", value.title3, ")"] }), value.subtitle2 && jsxRuntime.jsxs("span", { children: ["-", value.subtitle2] })] })] }));
9435
+ }, className: styles$4["scheduler-row-header"], children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { children: value.title }), value.title2 && jsxRuntime.jsxs("span", { children: ["-", value.title2] }), " ", jsxRuntime.jsx("strong", { children: value.subtitle })] }), value.subtitle && jsxRuntime.jsxs("div", { style: { opacity: 0.5 }, children: [value.title3 && jsxRuntime.jsxs("span", { className: styles$4["scheduler-crewmember-functions"], children: ["(", value.title3, ")"] }), value.subtitle2 && jsxRuntime.jsxs("span", { children: ["-", value.subtitle2] })] })] }));
9436
9436
  };
9437
9437
 
9438
9438
  const EventSideDrag = ({ left = false, heightRem, onStartEvent }) => {
@@ -9522,7 +9522,7 @@ const SchedulerEvent = ({ value, heightRem, onEvent, maxEventHeightRem }) => {
9522
9522
  height: `calc(${effectiveHeight}rem - 4px)`,
9523
9523
  opacity: eventTransparent ? 0.5 : 1,
9524
9524
  ...value.style,
9525
- }, className: styles$2["scheduler-event"], "data-underlay": value.underlay ? true : undefined, children: [value.underlay && jsxRuntime.jsx("div", { className: styles$2["underlay"], children: value.underlay }), jsxRuntime.jsxs("div", { style: {
9525
+ }, className: styles$5["scheduler-event"], "data-underlay": value.underlay ? true : undefined, children: [value.underlay && jsxRuntime.jsx("div", { className: styles$5["underlay"], children: value.underlay }), jsxRuntime.jsxs("div", { style: {
9526
9526
  display: "flex",
9527
9527
  flexDirection: "row",
9528
9528
  alignItems: "stretch",
@@ -9533,13 +9533,13 @@ const SchedulerEvent = ({ value, heightRem, onEvent, maxEventHeightRem }) => {
9533
9533
  height: "100%",
9534
9534
  }, children: [value.isResizable && (jsxRuntime.jsx(EventSideDrag, { left: true, heightRem: effectiveHeight * 0.7, onStartEvent: () => {
9535
9535
  onEvent(new OnLeftDragStart(value.id));
9536
- } })), jsxRuntime.jsxs("div", { className: styles$2["scheduler-event-container"], children: [jsxRuntime.jsx("div", { style: {
9536
+ } })), jsxRuntime.jsxs("div", { className: styles$5["scheduler-event-container"], children: [jsxRuntime.jsx("div", { style: {
9537
9537
  display: "flex",
9538
9538
  flexDirection: "row",
9539
9539
  alignItems: "center",
9540
9540
  whiteSpace: "nowrap",
9541
9541
  color: textColor,
9542
- }, children: value.icons }), jsxRuntime.jsx("span", { className: value.underlay ? styles$2["label-halo"] : undefined, style: {
9542
+ }, children: value.icons }), jsxRuntime.jsx("span", { className: value.underlay ? styles$5["label-halo"] : undefined, style: {
9543
9543
  padding: "0.1rem",
9544
9544
  color: textColor,
9545
9545
  display: "flex",
@@ -9547,13 +9547,13 @@ const SchedulerEvent = ({ value, heightRem, onEvent, maxEventHeightRem }) => {
9547
9547
  alignItems: "center",
9548
9548
  width: "100%",
9549
9549
  ...(value.underlay && { "--label-halo-color": backColor }),
9550
- }, children: value.rectangleColors && value.rectangleColors.length > 0 ? (jsxRuntime.jsx("div", { className: styles$2["color-bars"], children: value.rectangleColors.map((item, i) => (jsxRuntime.jsx("div", { style: { backgroundColor: item } }, value.id + "_" + i))) })) : (value.label ?? value.name) })] }), value.isResizable && (jsxRuntime.jsx(EventSideDrag, { heightRem: effectiveHeight * 0.7, onStartEvent: () => {
9550
+ }, children: value.rectangleColors && value.rectangleColors.length > 0 ? (jsxRuntime.jsx("div", { className: styles$5["color-bars"], children: value.rectangleColors.map((item, i) => (jsxRuntime.jsx("div", { style: { backgroundColor: item } }, value.id + "_" + i))) })) : (value.label ?? value.name) })] }), value.isResizable && (jsxRuntime.jsx(EventSideDrag, { heightRem: effectiveHeight * 0.7, onStartEvent: () => {
9551
9551
  onEvent(new OnRightDragStart(value.id));
9552
- } }))] }), value.primaryTimeMarkerColor && (jsxRuntime.jsx("div", { className: styles$2["time-marker"], style: {
9552
+ } }))] }), value.primaryTimeMarkerColor && (jsxRuntime.jsx("div", { className: styles$5["time-marker"], style: {
9553
9553
  backgroundColor: value.primaryTimeMarkerColor,
9554
- } })), value.secondaryTimeMarkerColor && (jsxRuntime.jsx("div", { className: styles$2["time-marker"], style: {
9554
+ } })), value.secondaryTimeMarkerColor && (jsxRuntime.jsx("div", { className: styles$5["time-marker"], style: {
9555
9555
  backgroundColor: value.secondaryTimeMarkerColor,
9556
- } }))] }) }) }, value.id) }), value.cornerMarker && (jsxRuntime.jsx("div", { className: styles$2["corner-marker"], style: {
9556
+ } }))] }) }) }, value.id) }), value.cornerMarker && (jsxRuntime.jsx("div", { className: styles$5["corner-marker"], style: {
9557
9557
  top: `${topOffsetPx}px`,
9558
9558
  left: `${value.left}%`,
9559
9559
  width: `${value.width}%`,
@@ -10087,13 +10087,13 @@ const Scheduler = (props) => {
10087
10087
  position: "sticky",
10088
10088
  top: 0,
10089
10089
  zIndex: 1,
10090
- }, children: jsxRuntime.jsx(SchedulerHeader, { ...header }) })), jsxRuntime.jsx(reactWindow.VariableSizeList, { height: schedulerContentHeight * 16, itemCount: rows.length, itemSize: getItemSize, itemData: itemData, width: "100%", style: { overflowX: "hidden" }, ref: instanceRef, className: styles$2["hide-scrollbar"], children: Row })] }) }));
10090
+ }, children: jsxRuntime.jsx(SchedulerHeader, { ...header }) })), jsxRuntime.jsx(reactWindow.VariableSizeList, { height: schedulerContentHeight * 16, itemCount: rows.length, itemSize: getItemSize, itemData: itemData, width: "100%", style: { overflowX: "hidden" }, ref: instanceRef, className: styles$5["hide-scrollbar"], children: Row })] }) }));
10091
10091
  };
10092
10092
 
10093
10093
  class UiEvent {
10094
10094
  }
10095
10095
 
10096
- var styles = {"super-scheduler-row-header":"super-scheduler-module__super-scheduler-row-header__TTs4e","indicators":"super-scheduler-module__indicators__f4lIT","scheduler-crewmember-functions":"super-scheduler-module__scheduler-crewmember-functions__BS2hs"};
10096
+ var styles$3 = {"super-scheduler-row-header":"super-scheduler-module__super-scheduler-row-header__TTs4e","indicators":"super-scheduler-module__indicators__f4lIT","scheduler-crewmember-functions":"super-scheduler-module__scheduler-crewmember-functions__BS2hs"};
10097
10097
 
10098
10098
  class OnPinRow {
10099
10099
  id;
@@ -10121,15 +10121,15 @@ const PinRowHeader = ({ value, width, onEvent }) => {
10121
10121
  flexShrink: 0,
10122
10122
  height: "100%",
10123
10123
  background: highlightColor
10124
- }, className: styles["super-scheduler-row-header"], children: [jsxRuntime.jsx("button", { className: "cw-button-icon cwi-pin", "data-pinned": value.isPinned, onClick: (_) => {
10124
+ }, className: styles$3["super-scheduler-row-header"], children: [jsxRuntime.jsx("button", { className: "cw-button-icon cwi-pin", "data-pinned": value.isPinned, onClick: (_) => {
10125
10125
  onEvent(value.isPinned ? new OnUnpinRow(value.rowId) : new OnPinRow(value.rowId));
10126
- } }), jsxRuntime.jsx("div", { className: styles["indicators"], children: value.indicators ?? undefined }), jsxRuntime.jsxs("div", { style: {
10126
+ } }), jsxRuntime.jsx("div", { className: styles$3["indicators"], children: value.indicators ?? undefined }), jsxRuntime.jsxs("div", { style: {
10127
10127
  display: "flex",
10128
10128
  flexDirection: "column",
10129
10129
  justifyContent: "center",
10130
10130
  alignItems: "flex-start",
10131
10131
  }, children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("strong", { children: value.title }), value.title2 && jsxRuntime.jsxs("span", { children: ["-", value.title2] }), " ", jsxRuntime.jsx("strong", { children: value.subtitle })] }), value.subtitle && jsxRuntime.jsxs("div", { style: { opacity: 0.5 }, children: [value.title3 &&
10132
- jsxRuntime.jsxs("span", { className: styles["scheduler-crewmember-functions"], children: ["(", value.title3, ")"] }), value.subtitle2 && jsxRuntime.jsxs("span", { children: ["-", value.subtitle2] })] })] }), isLoading ? jsxRuntime.jsx("span", { className: "cwi-icons cwi-spinner" }) : undefined] }) }, value.rowId) }, value.rowId);
10132
+ jsxRuntime.jsxs("span", { className: styles$3["scheduler-crewmember-functions"], children: ["(", value.title3, ")"] }), value.subtitle2 && jsxRuntime.jsxs("span", { children: ["-", value.subtitle2] })] })] }), isLoading ? jsxRuntime.jsx("span", { className: "cwi-icons cwi-spinner" }) : undefined] }) }, value.rowId) }, value.rowId);
10133
10133
  };
10134
10134
 
10135
10135
  const SuperScheduler = ({ id, state, header, rows, events, headerColumnComp, pinnedOrderCategory, unPinnedOrderCategory, backgroundEvents, indicatorRows = [], contextMenuItems, onEvent, rowHeightRem = 1.75, rowHeaderWidth, maxEventHeightRem, EventComp = SchedulerEvent, }) => {
@@ -10141,6 +10141,2324 @@ const SuperScheduler = ({ id, state, header, rows, events, headerColumnComp, pin
10141
10141
  }, children: "Clear pinned" }) })] })), jsxRuntime.jsx(Scheduler, { id: `${id}-notPinned`, state: { ...state, isHeaderVisible: !isFirstVisible }, header: header, rows: notPinnedRows, events: events, backgroundEvents: backgroundEvents, indicatorRows: indicatorRows, contextMenuItems: contextMenuItems, orderCategories: unPinnedOrderCategory, onEvent: onEvent, EventComp: EventComp, RowTitleComp: headerColumnComp, rowHeightRem: rowHeightRem, rowHeaderWidth: rowHeaderWidth, maxEventHeightRem: maxEventHeightRem })] }));
10142
10142
  };
10143
10143
 
10144
+ /** A toggle ref hides its item while `InitiallyHidden` XOR "flipped" is true. */
10145
+ function isToggleRefHidden(ref, flipped) {
10146
+ return ref.InitiallyHidden !== flipped.has(ref.Id);
10147
+ }
10148
+ /** An item, row or cell is visible only when every toggle it depends on is in its visible state. */
10149
+ function isRdlVisible(toggles, flipped) {
10150
+ if (!toggles || toggles.length === 0)
10151
+ return true;
10152
+ return toggles.every(ref => !isToggleRefHidden(ref, flipped));
10153
+ }
10154
+ /** The +/- state of a toggle textbox: the initial state inverted when its id was flipped. */
10155
+ function isToggleExpanded(textbox, flipped) {
10156
+ const initial = textbox.ToggleExpanded ?? false;
10157
+ return textbox.ToggleId ? initial !== flipped.has(textbox.ToggleId) : initial;
10158
+ }
10159
+ /**
10160
+ * The toggle ids an export or print sends so the file shows the drilldown state of the screen: the
10161
+ * ids flipped relative to the render's initial state (a toggle clicked twice is back to its initial
10162
+ * state and not sent), sorted for a stable request.
10163
+ */
10164
+ function flippedToggleIds(flipped) {
10165
+ return [...flipped].sort();
10166
+ }
10167
+ /** The toggle ids to ask the server for after a click on toggle `id`: the flipped ids with `id` flipped once more. */
10168
+ function toggledIds(flipped, id) {
10169
+ return flippedToggleIds(flipToggle(flipped, id));
10170
+ }
10171
+ /** Returns a new set with `id` flipped (added when absent, removed when present). */
10172
+ function flipToggle(flipped, id) {
10173
+ const next = new Set(flipped);
10174
+ if (next.has(id)) {
10175
+ next.delete(id);
10176
+ }
10177
+ else {
10178
+ next.add(id);
10179
+ }
10180
+ return next;
10181
+ }
10182
+
10183
+ /** Number of visible rows among `span` rows starting at `start`, at least 1. */
10184
+ function visibleRowSpan(rowVisible, start, span) {
10185
+ const end = Math.min(rowVisible.length, start + Math.max(1, span));
10186
+ let count = 0;
10187
+ for (let i = start; i < end; i++) {
10188
+ if (rowVisible[i])
10189
+ count++;
10190
+ }
10191
+ return Math.max(1, count);
10192
+ }
10193
+ function sum(values, from, to) {
10194
+ let total = 0;
10195
+ for (let i = Math.max(0, from); i < Math.min(values.length, to); i++)
10196
+ total += values[i];
10197
+ return total;
10198
+ }
10199
+ function visibleHeight(rows, rowVisible, start, span) {
10200
+ const end = Math.min(rows.length, start + Math.max(1, span));
10201
+ let height = 0;
10202
+ for (let i = start; i < end; i++) {
10203
+ if (rowVisible[i])
10204
+ height += rows[i].Height;
10205
+ }
10206
+ return height;
10207
+ }
10208
+ /**
10209
+ * Lays a table out for the current toggle state: hidden rows take no space, cells are placed at
10210
+ * their column with ColSpan/RowSpan and a header cell's RowSpan is recounted over the visible rows.
10211
+ * Cells that start in a hidden row are not drawn.
10212
+ */
10213
+ function layoutRdlTable(table, flipped) {
10214
+ const rows = table.Rows;
10215
+ const widths = table.ColumnWidths;
10216
+ const rowVisible = rows.map(row => isRdlVisible(row.Toggles, flipped));
10217
+ const rowTops = [];
10218
+ let top = 0;
10219
+ rows.forEach((row, index) => {
10220
+ rowTops.push(top);
10221
+ if (rowVisible[index])
10222
+ top += row.Height;
10223
+ });
10224
+ const cells = [];
10225
+ rows.forEach((row, rowIndex) => {
10226
+ if (!rowVisible[rowIndex])
10227
+ return;
10228
+ row.Cells.forEach((cell, cellIndex) => {
10229
+ const colSpan = Math.max(1, cell.ColSpan);
10230
+ cells.push({
10231
+ cell,
10232
+ rowIndex,
10233
+ cellIndex,
10234
+ left: sum(widths, 0, cell.Column),
10235
+ top: rowTops[rowIndex],
10236
+ width: sum(widths, cell.Column, cell.Column + colSpan),
10237
+ height: visibleHeight(rows, rowVisible, rowIndex, cell.RowSpan),
10238
+ rowSpan: visibleRowSpan(rowVisible, rowIndex, cell.RowSpan),
10239
+ hidden: !isRdlVisible(cell.Toggles, flipped)
10240
+ });
10241
+ });
10242
+ });
10243
+ return {
10244
+ width: sum(widths, 0, widths.length),
10245
+ height: top,
10246
+ rowTops,
10247
+ rowVisible,
10248
+ cells
10249
+ };
10250
+ }
10251
+
10252
+ /*
10253
+ * Find over the text of one page. Every run gets a key from its position in the render tree; the
10254
+ * renderer builds the same keys, so a match can be highlighted where the run is drawn.
10255
+ */
10256
+ /** Key prefixes of the three page sections. */
10257
+ const RDL_SECTION_KEYS = { header: "h", body: "b", footer: "f" };
10258
+ function rdlItemKey(parentKey, index) {
10259
+ return `${parentKey}.${index}`;
10260
+ }
10261
+ function rdlCellKey(tableKey, rowIndex, cellIndex) {
10262
+ return `${tableKey}.r${rowIndex}c${cellIndex}`;
10263
+ }
10264
+ function rdlRunKey(textboxKey, paragraphIndex, runIndex) {
10265
+ return `${textboxKey}.p${paragraphIndex}r${runIndex}`;
10266
+ }
10267
+ function collectTextbox(textbox, key, out) {
10268
+ textbox.Paragraphs.forEach((paragraph, p) => {
10269
+ paragraph.Runs.forEach((run, r) => {
10270
+ if (run.Text)
10271
+ out.push({ key: rdlRunKey(key, p, r), text: run.Text });
10272
+ });
10273
+ });
10274
+ }
10275
+ function collectItem(item, key, flipped, out) {
10276
+ if (!isRdlVisible(item.Toggles, flipped))
10277
+ return;
10278
+ switch (item.Kind) {
10279
+ case "textbox":
10280
+ collectTextbox(item, key, out);
10281
+ break;
10282
+ case "rectangle":
10283
+ collectItems(item.Items, key, flipped, out);
10284
+ break;
10285
+ case "table": {
10286
+ const layout = layoutRdlTable(item, flipped);
10287
+ for (const box of layout.cells) {
10288
+ if (box.hidden || !box.cell.Content)
10289
+ continue;
10290
+ collectItem(box.cell.Content, rdlCellKey(key, box.rowIndex, box.cellIndex), flipped, out);
10291
+ }
10292
+ break;
10293
+ }
10294
+ }
10295
+ }
10296
+ function collectItems(items, parentKey, flipped, out) {
10297
+ items.forEach((item, index) => collectItem(item, rdlItemKey(parentKey, index), flipped, out));
10298
+ }
10299
+ /** Every visible text run of a page in document order: header, body, footer. */
10300
+ function collectPageText(page, flipped) {
10301
+ const out = [];
10302
+ if (page.Header)
10303
+ collectItems(page.Header.Items, RDL_SECTION_KEYS.header, flipped, out);
10304
+ collectItems(page.Items, RDL_SECTION_KEYS.body, flipped, out);
10305
+ if (page.Footer)
10306
+ collectItems(page.Footer.Items, RDL_SECTION_KEYS.footer, flipped, out);
10307
+ return out;
10308
+ }
10309
+ /**
10310
+ * The text lower-cased one character at a time, with each code unit of the result pointing back to the
10311
+ * original character it came from: lower-casing can change the length ("İ" becomes two code units outside
10312
+ * Turkish), and the highlights slice the original text.
10313
+ */
10314
+ function lowerWithOffsets(text, locale) {
10315
+ let lower = "";
10316
+ const starts = [];
10317
+ const ends = [];
10318
+ let index = 0;
10319
+ for (const character of text) {
10320
+ const lowered = character.toLocaleLowerCase(locale);
10321
+ for (let unit = 0; unit < lowered.length; unit++) {
10322
+ starts.push(index);
10323
+ ends.push(index + character.length);
10324
+ }
10325
+ lower += lowered;
10326
+ index += character.length;
10327
+ }
10328
+ return { lower, starts, ends };
10329
+ }
10330
+ /**
10331
+ * Case-insensitive, non-overlapping matches of `query` in the runs, in run order, with the casing rules of
10332
+ * `locale` (default: the browser's, so "istanbul" finds "İSTANBUL" in Turkish). A match does not span two runs.
10333
+ */
10334
+ function findInRuns(runs, query, locale) {
10335
+ const needle = query.trim().toLocaleLowerCase(locale);
10336
+ if (needle === "")
10337
+ return [];
10338
+ const matches = [];
10339
+ for (const run of runs) {
10340
+ const { lower, starts, ends } = lowerWithOffsets(run.text, locale);
10341
+ let from = 0;
10342
+ for (;;) {
10343
+ const at = lower.indexOf(needle, from);
10344
+ if (at < 0)
10345
+ break;
10346
+ const start = starts[at];
10347
+ matches.push({ key: run.key, start, length: ends[at + needle.length - 1] - start });
10348
+ from = at + needle.length;
10349
+ }
10350
+ }
10351
+ return matches;
10352
+ }
10353
+ /** Find over the visible text of one page. */
10354
+ function findInPage(page, query, flipped) {
10355
+ return findInRuns(collectPageText(page, flipped), query);
10356
+ }
10357
+ /**
10358
+ * The active match index: -1 without matches; the stored index clamped into the matches when it belongs to the
10359
+ * current page and query (a stored -1 from an empty search becomes 0 once a drilldown reveals matches); else 0.
10360
+ */
10361
+ function activeMatchIndex(storedIndex, storedForCurrentSearch, count) {
10362
+ if (count <= 0)
10363
+ return -1;
10364
+ return storedForCurrentSearch ? Math.min(Math.max(0, storedIndex), count - 1) : 0;
10365
+ }
10366
+ /** The next match index after `current`, cycling; -1 when there are no matches. */
10367
+ function nextMatchIndex(current, count) {
10368
+ if (count <= 0)
10369
+ return -1;
10370
+ return current < 0 ? 0 : (current + 1) % count;
10371
+ }
10372
+
10373
+ /** CSS pixels per point: 96 px per inch, 72 pt per inch. */
10374
+ const PX_PER_PT = 96 / 72;
10375
+ /** Converts points to CSS pixels at a zoom factor (1 = 100%). */
10376
+ function ptToPx(pt, zoom = 1) {
10377
+ return pt * PX_PER_PT * zoom;
10378
+ }
10379
+ const POINTS_PER_UNIT = {
10380
+ pt: 1,
10381
+ px: 72 / 96,
10382
+ in: 72,
10383
+ cm: 72 / 2.54,
10384
+ mm: 72 / 25.4,
10385
+ pc: 12
10386
+ };
10387
+ // Linear: one digit run either side of the point, so a long non-matching value cannot backtrack quadratically.
10388
+ const SIZE_PATTERN = /^\s*(-?(?:\d+(?:\.\d*)?|\.\d+))\s*(pt|px|in|cm|mm|pc)?\s*$/i;
10389
+ /** No real RDL size comes near this; longer report-supplied strings are rejected before matching. */
10390
+ const MAX_SIZE_LENGTH = 32;
10391
+ /** Parses an RDL size ("10pt", "2.5mm", "1in", ...) into points; a bare number is points. Null when unparsable. */
10392
+ function parseRdlSize(value) {
10393
+ if (!value || value.length > MAX_SIZE_LENGTH)
10394
+ return null;
10395
+ const match = SIZE_PATTERN.exec(value);
10396
+ if (!match)
10397
+ return null;
10398
+ const unit = (match[2] ?? "pt").toLowerCase();
10399
+ return parseFloat(match[1]) * POINTS_PER_UNIT[unit];
10400
+ }
10401
+ /** An RDL size as CSS pixels at a zoom factor, or undefined when the size is missing or unparsable. */
10402
+ function rdlSizeToPx(value, zoom) {
10403
+ const pt = parseRdlSize(value);
10404
+ return pt === null ? undefined : ptToPx(pt, zoom);
10405
+ }
10406
+
10407
+ /** The zoom steps of the toolbar, 50% to 200%. */
10408
+ const REPORT_ZOOM_STEPS = [0.5, 0.75, 1, 1.25, 1.5, 2];
10409
+ const MIN_ZOOM = 0.1;
10410
+ const MAX_ZOOM = 4;
10411
+ /** Default margins of a standalone CwReportPage: a quarter inch, so content never touches the paper edge. */
10412
+ const DEFAULT_PAGE_MARGIN_PT = 18;
10413
+ /**
10414
+ * Margins of the sheet in the viewer: none. Like the old ReportViewer, the screen shows the content
10415
+ * (header, body, footer) without the RDL page margins; PDF and print come from the server with them.
10416
+ */
10417
+ const SCREEN_PAGE_MARGINS = { top: 0, right: 0, bottom: 0, left: 0 };
10418
+ /** Width of the page content in points: the page's own `Width` (body plus items reaching past it) when the server sends it, else the body width. */
10419
+ function pageContentWidthPt(page, bodyWidth) {
10420
+ return page.Width && Number.isFinite(page.Width) && page.Width > 0 ? Math.max(page.Width, bodyWidth) : bodyWidth;
10421
+ }
10422
+ /** Size of the drawn sheet in points: margins + header + body + footer, as wide as the content so every item lies on it. */
10423
+ function pageSheetSizePt(page, bodyWidth, margins) {
10424
+ return {
10425
+ width: margins.left + pageContentWidthPt(page, bodyWidth) + margins.right,
10426
+ height: margins.top + (page.Header?.Height ?? 0) + page.Height + (page.Footer?.Height ?? 0) + margins.bottom
10427
+ };
10428
+ }
10429
+ /**
10430
+ * The zoom factor to draw with. "pageWidth" fits the sheet width into the available width,
10431
+ * "wholePage" fits the whole sheet; available sizes are CSS pixels. Clamped to 10%..400%.
10432
+ */
10433
+ function resolveZoomFactor(zoom, sheetPt, available) {
10434
+ if (typeof zoom === "number")
10435
+ return clamp(zoom);
10436
+ const widthPx = ptToPx(sheetPt.width);
10437
+ const heightPx = ptToPx(sheetPt.height);
10438
+ if (widthPx <= 0 || available.width <= 0)
10439
+ return 1;
10440
+ const byWidth = available.width / widthPx;
10441
+ if (zoom === "pageWidth" || heightPx <= 0 || available.height <= 0)
10442
+ return clamp(byWidth);
10443
+ return clamp(Math.min(byWidth, available.height / heightPx));
10444
+ }
10445
+ function clamp(value) {
10446
+ return Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, value));
10447
+ }
10448
+
10449
+ /*
10450
+ * Maps the RDL style vocabulary to CSS. Everything here is report CONTENT: colors, fonts and borders
10451
+ * come from the report definition and are applied as given, not from the design system.
10452
+ */
10453
+ const RDL_DEFAULT_FONT_FAMILY = "Arial";
10454
+ const RDL_DEFAULT_FONT_SIZE = "10pt";
10455
+ const RDL_DEFAULT_COLOR = "black";
10456
+ const FONT_WEIGHTS = {
10457
+ thin: 100,
10458
+ extralight: 200,
10459
+ light: 300,
10460
+ normal: 400,
10461
+ medium: 500,
10462
+ semibold: 600,
10463
+ bold: 700,
10464
+ extrabold: 800,
10465
+ heavy: 900
10466
+ };
10467
+ const BORDER_STYLES = {
10468
+ solid: "solid",
10469
+ dotted: "dotted",
10470
+ dashed: "dashed",
10471
+ double: "double",
10472
+ none: "none"
10473
+ };
10474
+ /** An RDL color as CSS: "Transparent" = transparent, names and #RRGGBB pass through, empty = undefined. */
10475
+ function rdlColor(value) {
10476
+ if (!value)
10477
+ return undefined;
10478
+ const trimmed = value.trim();
10479
+ if (trimmed === "")
10480
+ return undefined;
10481
+ return trimmed.toLowerCase() === "transparent" ? "transparent" : trimmed;
10482
+ }
10483
+ /** Thin..Heavy to 100..900; unknown values fall back to normal. */
10484
+ function rdlFontWeight(value) {
10485
+ if (!value)
10486
+ return 400;
10487
+ return FONT_WEIGHTS[value.toLowerCase()] ?? (/^\d{3}$/.test(value) ? parseInt(value, 10) : 400);
10488
+ }
10489
+ /** A border side as a CSS shorthand; Style None or missing = none. Width defaults to 1pt, color to black. */
10490
+ function rdlBorder(border, zoom) {
10491
+ if (!border)
10492
+ return undefined;
10493
+ const style = BORDER_STYLES[(border.Style ?? "none").toLowerCase()] ?? "solid";
10494
+ if (style === "none")
10495
+ return "none";
10496
+ const widthPt = parseRdlSize(border.Width) ?? 1;
10497
+ const widthPx = Math.max(1, ptToPx(widthPt, zoom));
10498
+ return `${widthPx}px ${style} ${rdlColor(border.Color) ?? RDL_DEFAULT_COLOR}`;
10499
+ }
10500
+ /**
10501
+ * The four borders of an item box as the custom properties its border overlay draws
10502
+ * (`--rdl-border-top` ... in cw-report-page.module.css). Like the report server, borders sit on
10503
+ * the box edge and take no space from the content, so text laid out by the server to just fit
10504
+ * still fits. Always all four sides, "none" when unset: custom properties inherit, and a nested
10505
+ * item must not draw its container's borders.
10506
+ */
10507
+ function rdlBorderVars(style, zoom) {
10508
+ return {
10509
+ "--rdl-border-top": rdlBorder(style?.BorderTop, zoom) ?? "none",
10510
+ "--rdl-border-right": rdlBorder(style?.BorderRight, zoom) ?? "none",
10511
+ "--rdl-border-bottom": rdlBorder(style?.BorderBottom, zoom) ?? "none",
10512
+ "--rdl-border-left": rdlBorder(style?.BorderLeft, zoom) ?? "none"
10513
+ };
10514
+ }
10515
+ /** Background, borders (as overlay custom properties, see `rdlBorderVars`) and padding of an item box. */
10516
+ function rdlBoxStyle(style, zoom) {
10517
+ if (!style)
10518
+ return rdlBorderVars(null, zoom);
10519
+ return {
10520
+ ...rdlBorderVars(style, zoom),
10521
+ backgroundColor: rdlColor(style.BackgroundColor),
10522
+ paddingTop: rdlSizeToPx(style.PaddingTop, zoom),
10523
+ paddingRight: rdlSizeToPx(style.PaddingRight, zoom),
10524
+ paddingBottom: rdlSizeToPx(style.PaddingBottom, zoom),
10525
+ paddingLeft: rdlSizeToPx(style.PaddingLeft, zoom)
10526
+ };
10527
+ }
10528
+ function pick(key, styles) {
10529
+ for (const style of styles) {
10530
+ const value = style?.[key];
10531
+ if (value)
10532
+ return value;
10533
+ }
10534
+ return null;
10535
+ }
10536
+ function resolveRdlTextStyle(run, paragraph, textbox) {
10537
+ const chain = [run, paragraph, textbox];
10538
+ return {
10539
+ color: pick("Color", chain) ?? RDL_DEFAULT_COLOR,
10540
+ fontFamily: pick("FontFamily", chain) ?? RDL_DEFAULT_FONT_FAMILY,
10541
+ fontSize: pick("FontSize", chain) ?? RDL_DEFAULT_FONT_SIZE,
10542
+ fontStyle: pick("FontStyle", chain),
10543
+ fontWeight: pick("FontWeight", chain),
10544
+ textDecoration: pick("TextDecoration", chain),
10545
+ lineHeight: pick("LineHeight", chain)
10546
+ };
10547
+ }
10548
+ /**
10549
+ * The text style of a paragraph element. Its font sets the strut every line box gets, so it takes
10550
+ * the font of its runs (they usually share one; when they differ, the first run's): a paragraph
10551
+ * left at the textbox default (Arial 10pt) around Segoe UI 8pt runs would make every line taller
10552
+ * than the server measured and the text would overflow its box. An RDL LineHeight on the paragraph
10553
+ * or textbox still wins; otherwise the run's LineHeight, if any, applies.
10554
+ */
10555
+ function resolveParagraphTextStyle(runStyles, paragraph, textbox) {
10556
+ const own = resolveRdlTextStyle(null, paragraph, textbox);
10557
+ if (runStyles.length === 0)
10558
+ return own;
10559
+ const run = resolveRdlTextStyle(runStyles[0], paragraph, textbox);
10560
+ return {
10561
+ ...own,
10562
+ fontFamily: run.fontFamily,
10563
+ fontSize: run.fontSize,
10564
+ fontStyle: run.fontStyle,
10565
+ fontWeight: run.fontWeight,
10566
+ lineHeight: own.lineHeight ?? run.lineHeight
10567
+ };
10568
+ }
10569
+ function textDecoration(value) {
10570
+ switch ((value ?? "").toLowerCase()) {
10571
+ case "underline": return "underline";
10572
+ case "linethrough": return "line-through";
10573
+ case "overline": return "overline";
10574
+ default: return undefined;
10575
+ }
10576
+ }
10577
+ /** An RDL LineHeight in pixels, else "normal"; an unparsable value also falls back to normal. */
10578
+ function rdlLineHeight(value, zoom) {
10579
+ const px = rdlSizeToPx(value, zoom);
10580
+ return px === undefined ? "normal" : `${px}px`;
10581
+ }
10582
+ /**
10583
+ * CSS of a resolved text style at a zoom factor. Without an RDL LineHeight the line height is the
10584
+ * font's natural one ("normal"), the spacing the server measures text with; set inline so no app
10585
+ * or base rule on p / span (125%, 1.15) can shrink the line box and clip large glyphs.
10586
+ */
10587
+ function rdlTextCss(text, zoom) {
10588
+ return {
10589
+ // Transparent text is invisible, as in Reporting Services (reports use it to hide values).
10590
+ color: rdlColor(text.color),
10591
+ fontFamily: text.fontFamily,
10592
+ fontSize: rdlSizeToPx(text.fontSize, zoom) ?? ptToPx(10, zoom),
10593
+ fontStyle: (text.fontStyle ?? "").toLowerCase() === "italic" ? "italic" : undefined,
10594
+ fontWeight: text.fontWeight ? rdlFontWeight(text.fontWeight) : undefined,
10595
+ textDecoration: textDecoration(text.textDecoration),
10596
+ lineHeight: rdlLineHeight(text.lineHeight, zoom)
10597
+ };
10598
+ }
10599
+ /** TextAlign Left/Center/Right/General (General = left). */
10600
+ function rdlTextAlign(value) {
10601
+ switch ((value ?? "").toLowerCase()) {
10602
+ case "center": return "center";
10603
+ case "right": return "right";
10604
+ case "justify": return "justify";
10605
+ default: return "left";
10606
+ }
10607
+ }
10608
+ /**
10609
+ * VerticalAlign Top/Middle/Bottom as the justify-content of a column flex box. "safe": when the
10610
+ * text is taller than its box it falls back to the top, so the first line is never cut off.
10611
+ */
10612
+ function rdlVerticalAlign(value) {
10613
+ switch ((value ?? "").toLowerCase()) {
10614
+ case "middle": return "safe center";
10615
+ case "bottom": return "safe flex-end";
10616
+ default: return "flex-start";
10617
+ }
10618
+ }
10619
+ /** The stroke of a line item: BorderTop, else BorderLeft, default 1pt solid black. */
10620
+ function rdlLineStroke(style, zoom) {
10621
+ const border = style?.BorderTop ?? style?.BorderLeft ?? null;
10622
+ const width = Math.max(1, ptToPx(parseRdlSize(border?.Width) ?? 1, zoom));
10623
+ const kind = (border?.Style ?? "solid").toLowerCase();
10624
+ const color = rdlColor(border?.Color) ?? RDL_DEFAULT_COLOR;
10625
+ if (kind === "none")
10626
+ return { color: "transparent", width };
10627
+ if (kind === "dotted")
10628
+ return { color, width, dash: `${width} ${width * 2}` };
10629
+ if (kind === "dashed")
10630
+ return { color, width, dash: `${width * 4} ${width * 2}` };
10631
+ return { color, width };
10632
+ }
10633
+
10634
+ /*
10635
+ * Pure chart math for the report charts. The hex values below are the report's chart palettes:
10636
+ * content colors (like the colors a report carries), not UI chrome, so no design tokens.
10637
+ */
10638
+ /**
10639
+ * The Microsoft chart palettes by name, with the exact colors of the old ReportViewer engine.
10640
+ * The engine's semi-transparent palettes are #AARRGGBB; here they are CSS #RRGGBBAA.
10641
+ */
10642
+ const PALETTES = {
10643
+ Default: [
10644
+ "#008000", "#0000FF", "#800080", "#00FF00", "#FF00FF", "#008080", "#FFFF00", "#808080",
10645
+ "#00FFFF", "#000080", "#800000", "#FF0000", "#808000", "#C0C0C0", "#FF6347", "#FFE4B5"
10646
+ ],
10647
+ Grayscale: [
10648
+ "#C8C8C8", "#BDBDBD", "#B2B2B2", "#A7A7A7", "#9C9C9C", "#919191", "#868686", "#7B7B7B",
10649
+ "#707070", "#656565", "#5A5A5A", "#4F4F4F", "#444444", "#393939", "#2E2E2E", "#232323"
10650
+ ],
10651
+ Excel: [
10652
+ "#9999FF", "#993366", "#FFFFCC", "#CCFFFF", "#660066", "#FF8080", "#0066CC", "#CCCCFF",
10653
+ "#000080", "#FF00FF", "#FFFF00", "#00FFFF", "#800080", "#800000", "#008080", "#0000FF"
10654
+ ],
10655
+ Light: ["#E6E6FA", "#FFF0F5", "#FFDAB9", "#FFFACD", "#FFE4E1", "#F0FFF0", "#F0F8FF", "#F5F5F5", "#FAEBD7", "#E0FFFF"],
10656
+ Pastel: [
10657
+ "#87CEEB", "#32CD32", "#BA55D3", "#F08080", "#4682B4", "#9ACD32", "#40E0D0", "#FF69B4",
10658
+ "#F0E68C", "#D2B48C", "#8FBC8B", "#6495ED", "#DDA0DD", "#5F9EA0", "#FFDAB9", "#FFA07A"
10659
+ ],
10660
+ EarthTones: [
10661
+ "#FF8000", "#B8860B", "#C04000", "#6B8E23", "#CD853F", "#C0C000", "#228B22", "#D2691E",
10662
+ "#808000", "#20B2AA", "#F4A460", "#00C000", "#8FBC8B", "#B22222", "#8B4513", "#C00000"
10663
+ ],
10664
+ SemiTransparent: [
10665
+ "#FF000096", "#00FF0096", "#0000FF96", "#FFFF0096", "#00FFFF96", "#FF00FF96", "#AA781496", "#FF000050",
10666
+ "#00FF0050", "#0000FF50", "#FFFF0050", "#00FFFF50", "#FF00FF50", "#AA781450", "#64783296", "#285A9696"
10667
+ ],
10668
+ Berry: ["#8A2BE2", "#BA55D3", "#4169E1", "#C71585", "#0000FF", "#8A2BE2", "#DA70D6", "#7B68EE", "#C000C0", "#0000CD", "#800080"],
10669
+ Chocolate: ["#A0522D", "#D2691E", "#8B0000", "#CD853F", "#A52A2A", "#F4A460", "#8B4513", "#C04000", "#B22222", "#B65C3A"],
10670
+ Fire: ["#FFD700", "#FF0000", "#FF1493", "#DC143C", "#FF8C00", "#FF00FF", "#FFFF00", "#FF4500", "#C71585", "#DDE221"],
10671
+ SeaGreen: ["#2E8B57", "#66CDAA", "#4682B4", "#008B8B", "#5F9EA0", "#3CB371", "#48D1CC", "#B0C4DE", "#8FBC8B", "#87CEEB"],
10672
+ BrightPastel: [
10673
+ "#418CF0", "#FCB441", "#E0400A", "#056492", "#BFBFBF", "#1A3B69", "#FFE382", "#129CDD",
10674
+ "#CA6B4B", "#005CDB", "#F3D288", "#506381", "#F1B9A8", "#E0830A", "#7893BE"
10675
+ ],
10676
+ Pacific: [
10677
+ "#01B8AA", "#374649", "#FD625E", "#F2C80F", "#5F6B6D", "#8AD4EB", "#FE9666", "#A66999", "#3599B8", "#DFBFBF",
10678
+ "#4AC5BB", "#5F6B6D", "#FB8281", "#F4D25A", "#7F898A", "#A4DDEE", "#FDAB89", "#B687AC", "#28738A", "#A78F8F"
10679
+ ],
10680
+ PacificLight: ["#4AC5BB", "#5F6B6D", "#FB8281", "#F4D25A", "#7F898A", "#A4DDEE", "#FDAB89", "#B687AC", "#28738A", "#A78F8F"],
10681
+ PacificSemiTransparent: [
10682
+ "#01B8AA99", "#37464999", "#FD625E99", "#F2C80F99", "#5F6B6D99", "#8AD4EB99", "#FE966699", "#A6699999", "#3599B899", "#DFBFBF99",
10683
+ "#4AC5BB99", "#5F6B6D99", "#FB828199", "#F4D25A99", "#7F898A99", "#A4DDEE99", "#FDAB8999", "#B687AC99", "#28738A99", "#A78F8F99"
10684
+ ]
10685
+ };
10686
+ const PALETTES_BY_NAME = new Map(Object.entries(PALETTES).map(([name, colors]) => [name.toLowerCase(), colors]));
10687
+ /** The palette for an RDL palette name (any case); a missing or unknown name is "Default", the RDL default. */
10688
+ function chartPalette(name) {
10689
+ return PALETTES_BY_NAME.get((name ?? "").trim().toLowerCase()) ?? PALETTES.Default;
10690
+ }
10691
+ /** The color of series `index`: its own color, else the palette entry. */
10692
+ function seriesColor(series, index, palette) {
10693
+ return series.Color && series.Color.toLowerCase() !== "automatic" ? series.Color : palette[index % palette.length];
10694
+ }
10695
+ /** Steps of a value axis: about five, rounded to 1, 2, 5 or 10 times a power of ten. */
10696
+ const VALUE_AXIS_STEPS = 5;
10697
+ /** Drops the binary noise of step multiples (0.6000000000000001 -> 0.6). */
10698
+ function tidy$1(value) {
10699
+ return Number(value.toPrecision(12));
10700
+ }
10701
+ /**
10702
+ * bound / step, snapped to the nearest integer only when it is within a few ulps of it: 0.07 / 0.01 is
10703
+ * 7.000000000000001 in binary floating point and would otherwise add an axis step. Genuine non-multiples
10704
+ * (0.37 / 0.05) keep their fraction so the bounds still round outwards.
10705
+ */
10706
+ function axisQuotient(bound, step) {
10707
+ const quotient = bound / step;
10708
+ const nearest = Math.round(quotient);
10709
+ const reconstructed = nearest * step;
10710
+ const tolerance = Number.EPSILON * 4 * Math.max(1, Math.abs(bound), Math.abs(reconstructed));
10711
+ return Math.abs(reconstructed - bound) <= tolerance ? nearest : quotient;
10712
+ }
10713
+ /** The nice step for a value range (> 0): range / 5 rounded to 1, 2, 5 or 10 times its magnitude. */
10714
+ function niceAxisStep(range) {
10715
+ const raw = range / VALUE_AXIS_STEPS;
10716
+ const magnitude = Math.pow(10, Math.floor(Math.log10(raw)));
10717
+ const residual = raw / magnitude;
10718
+ const nice = residual < 1.5 ? 1 : residual < 3.5 ? 2 : residual < 7.5 ? 5 : 10;
10719
+ return tidy$1(nice * magnitude);
10720
+ }
10721
+ /**
10722
+ * A value axis over the given values, the same rule as the server's PDF: the range always includes
10723
+ * 0, nulls are ignored, the step is `niceAxisStep(range)` and the bounds are rounded out to whole
10724
+ * steps (data max 113 gives 0..120 in steps of 20). All-null or all-zero data gives 0..1.
10725
+ */
10726
+ function computeValueScale(values) {
10727
+ let min = 0;
10728
+ let max = 0;
10729
+ for (const value of values) {
10730
+ if (value === null || value === undefined || !Number.isFinite(value))
10731
+ continue;
10732
+ if (value < min)
10733
+ min = value;
10734
+ if (value > max)
10735
+ max = value;
10736
+ }
10737
+ if (min === max)
10738
+ max = min + 1;
10739
+ const step = niceAxisStep(max - min);
10740
+ const first = Math.floor(axisQuotient(min, step));
10741
+ const last = Math.ceil(axisQuotient(max, step));
10742
+ const ticks = [];
10743
+ for (let index = first; index <= last; index++)
10744
+ ticks.push(tidy$1(index * step));
10745
+ return { min: tidy$1(first * step), max: tidy$1(last * step), ticks };
10746
+ }
10747
+ /**
10748
+ * The server's category axis labels (`RdlRenderChart.CategoryAxisLabels`) along an axis that starts
10749
+ * at `start` with `band` pixels per category: position 0 is the first category's point (the middle
10750
+ * of its band), fractions fall between two categories. Labels outside the categories are dropped.
10751
+ */
10752
+ function categoryAxisLabels(labels, categoryCount, start, band) {
10753
+ return labels
10754
+ .filter(label => Number.isFinite(label.Position) && label.Position >= -0.5 && label.Position <= categoryCount - 0.5)
10755
+ .map(label => ({ at: start + band * (label.Position + 0.5), text: label.Text }));
10756
+ }
10757
+ /**
10758
+ * Centers a label of `width` on `center`, moved inside [min, max] when it would cross an end: a
10759
+ * category label never runs past the value axis (and its origin label) or the plot's right edge.
10760
+ */
10761
+ function placeAxisLabel(center, width, min, max) {
10762
+ if (center - width / 2 < min)
10763
+ return { x: min, anchor: "start" };
10764
+ if (center + width / 2 > max)
10765
+ return { x: max, anchor: "end" };
10766
+ return { x: center, anchor: "middle" };
10767
+ }
10768
+ /** Maps a value of the scale to a pixel coordinate between `from` (scale min) and `to` (scale max). */
10769
+ function scaleValue(value, scale, from, to) {
10770
+ const span = scale.max - scale.min;
10771
+ if (span === 0)
10772
+ return from;
10773
+ return from + ((value - scale.min) / span) * (to - from);
10774
+ }
10775
+ /** Splits a series into runs of consecutive non-null points: a null value leaves a gap in the line. */
10776
+ function lineSegments(values, x, y) {
10777
+ const segments = [];
10778
+ let current = [];
10779
+ values.forEach((value, index) => {
10780
+ if (value === null || value === undefined || !Number.isFinite(value)) {
10781
+ if (current.length > 0)
10782
+ segments.push(current);
10783
+ current = [];
10784
+ return;
10785
+ }
10786
+ current.push({ index, value, x: x(index), y: y(value) });
10787
+ });
10788
+ if (current.length > 0)
10789
+ segments.push(current);
10790
+ return segments;
10791
+ }
10792
+ /** SVG path of one segment: straight, stepped (horizontal then vertical) or smooth (Catmull-Rom as cubic Beziers). */
10793
+ function segmentPath(points, subtype) {
10794
+ if (points.length === 0)
10795
+ return "";
10796
+ const kind = (subtype ?? "").toLowerCase();
10797
+ let path = `M${points[0].x},${points[0].y}`;
10798
+ for (let i = 1; i < points.length; i++) {
10799
+ const prev = points[i - 1];
10800
+ const point = points[i];
10801
+ if (kind === "stepped") {
10802
+ path += ` H${point.x} V${point.y}`;
10803
+ }
10804
+ else if (kind === "smooth") {
10805
+ const before = points[i - 2] ?? prev;
10806
+ const after = points[i + 1] ?? point;
10807
+ const c1x = prev.x + (point.x - before.x) / 6;
10808
+ const c1y = prev.y + (point.y - before.y) / 6;
10809
+ const c2x = point.x - (after.x - prev.x) / 6;
10810
+ const c2y = point.y - (after.y - prev.y) / 6;
10811
+ path += ` C${c1x},${c1y} ${c2x},${c2y} ${point.x},${point.y}`;
10812
+ }
10813
+ else {
10814
+ path += ` L${point.x},${point.y}`;
10815
+ }
10816
+ }
10817
+ return path;
10818
+ }
10819
+ /** Pie slices of positive values (null, zero and negative values get no slice); angles in radians from 12 o'clock, clockwise. */
10820
+ function pieSlices(values) {
10821
+ const total = values.reduce((acc, value) => acc + (value !== null && value > 0 ? value : 0), 0);
10822
+ if (total <= 0)
10823
+ return [];
10824
+ const slices = [];
10825
+ let angle = 0;
10826
+ values.forEach((value, index) => {
10827
+ if (value === null || value <= 0)
10828
+ return;
10829
+ const fraction = value / total;
10830
+ const end = angle + fraction * Math.PI * 2;
10831
+ slices.push({ index, value, fraction, startAngle: angle, endAngle: end });
10832
+ angle = end;
10833
+ });
10834
+ return slices;
10835
+ }
10836
+ /** A point on a circle; angle in radians from 12 o'clock, clockwise. */
10837
+ function polar(cx, cy, radius, angle) {
10838
+ return { x: cx + radius * Math.sin(angle), y: cy - radius * Math.cos(angle) };
10839
+ }
10840
+ /** SVG path of an arc band (or a pie wedge when innerRadius is 0) between two angles. */
10841
+ function arcPath(cx, cy, outerRadius, innerRadius, start, end) {
10842
+ const sweep = end - start;
10843
+ if (sweep >= Math.PI * 2 - 1e-9) {
10844
+ const mid = start + Math.PI;
10845
+ return arcPath(cx, cy, outerRadius, innerRadius, start, mid) + " " + arcPath(cx, cy, outerRadius, innerRadius, mid, end);
10846
+ }
10847
+ const large = sweep > Math.PI ? 1 : 0;
10848
+ const o1 = polar(cx, cy, outerRadius, start);
10849
+ const o2 = polar(cx, cy, outerRadius, end);
10850
+ if (innerRadius <= 0) {
10851
+ return `M${cx},${cy} L${o1.x},${o1.y} A${outerRadius},${outerRadius} 0 ${large} 1 ${o2.x},${o2.y} Z`;
10852
+ }
10853
+ const i2 = polar(cx, cy, innerRadius, end);
10854
+ const i1 = polar(cx, cy, innerRadius, start);
10855
+ return `M${o1.x},${o1.y} A${outerRadius},${outerRadius} 0 ${large} 1 ${o2.x},${o2.y} L${i2.x},${i2.y} A${innerRadius},${innerRadius} 0 ${large} 0 ${i1.x},${i1.y} Z`;
10856
+ }
10857
+ /** Clamps a gauge value into the scale; null stays at the minimum. */
10858
+ function clampGaugeValue(value, minimum, maximum) {
10859
+ if (value === null || value === undefined || !Number.isFinite(value))
10860
+ return minimum;
10861
+ const low = Math.min(minimum, maximum);
10862
+ const high = Math.max(minimum, maximum);
10863
+ return Math.min(high, Math.max(low, value));
10864
+ }
10865
+ /** Formats an axis or data value compactly: integers without decimals, else up to 2 decimals. */
10866
+ function formatChartValue(value) {
10867
+ if (Number.isInteger(value))
10868
+ return value.toString();
10869
+ return (Math.round(value * 100) / 100).toString();
10870
+ }
10871
+
10872
+ /** More ticks than this on one scale is a broken interval, not a scale anyone can read. */
10873
+ const MAX_GAUGE_TICKS = 200;
10874
+ /**
10875
+ * The ellipse a state indicator fills: its percent box of the panel, stretched to an oval in a box
10876
+ * that is not square, like the old viewer. Null when the active state has no color or the box is empty.
10877
+ */
10878
+ function stateIndicatorEllipse(indicator, panelWidth, panelHeight) {
10879
+ if (!indicator.Color)
10880
+ return null;
10881
+ const width = (Math.max(0, indicator.Width) / 100) * panelWidth;
10882
+ const height = (Math.max(0, indicator.Height) / 100) * panelHeight;
10883
+ if (width <= 0 || height <= 0)
10884
+ return null;
10885
+ const left = (indicator.Left / 100) * panelWidth;
10886
+ const top = (indicator.Top / 100) * panelHeight;
10887
+ return { cx: left + width / 2, cy: top + height / 2, rx: width / 2, ry: height / 2 };
10888
+ }
10889
+ /** The value span a Bar pointer covers: from the scale minimum to the value clamped into the scale. */
10890
+ function gaugeBarSpan(value, minimum, maximum) {
10891
+ return { from: minimum, to: clampGaugeValue(value, minimum, maximum) };
10892
+ }
10893
+ function tidy(value) {
10894
+ return Number(value.toPrecision(12));
10895
+ }
10896
+ /**
10897
+ * The major tick values of a gauge scale: every `interval` from the minimum up to the maximum (the
10898
+ * server computes it); without a usable interval the chart axis' nice step of the range is used.
10899
+ */
10900
+ function gaugeTicks(minimum, maximum, interval) {
10901
+ const low = Math.min(minimum, maximum);
10902
+ const high = Math.max(minimum, maximum);
10903
+ if (!Number.isFinite(low) || !Number.isFinite(high))
10904
+ return [];
10905
+ if (high === low)
10906
+ return [tidy(low)];
10907
+ const step = interval !== null && interval !== undefined && Number.isFinite(interval) && interval > 0
10908
+ ? interval
10909
+ : niceAxisStep(high - low);
10910
+ const count = Math.floor(tidy((high - low) / step));
10911
+ if (count > MAX_GAUGE_TICKS)
10912
+ return [tidy(low), tidy(high)];
10913
+ const ticks = [];
10914
+ for (let index = 0; index <= count; index++)
10915
+ ticks.push(tidy(low + index * step));
10916
+ return ticks;
10917
+ }
10918
+ /**
10919
+ * A thickness given in percent of the gauge's own size (for a horizontal linear gauge its height, as
10920
+ * the chart engine measures range and pointer widths), or the default fraction when it is missing.
10921
+ */
10922
+ function gaugeThickness(percent, gaugeSize, defaultFraction) {
10923
+ const fraction = percent !== null && percent !== undefined && Number.isFinite(percent) && percent > 0 ? percent / 100 : defaultFraction;
10924
+ return gaugeSize * Math.min(1, fraction);
10925
+ }
10926
+ /** Cross (or none) is centred on the scale line, Inside lies above it, Outside below it. */
10927
+ function gaugeBandExtent(placement, thickness) {
10928
+ switch ((placement ?? "").toLowerCase()) {
10929
+ case "inside": return { up: thickness, down: 0 };
10930
+ case "outside": return { up: 0, down: thickness };
10931
+ default: return { up: thickness / 2, down: thickness / 2 };
10932
+ }
10933
+ }
10934
+ /**
10935
+ * The y of the scale line of a horizontal linear gauge `height` tall: the bands (ranges and pointers)
10936
+ * and the tick labels below them (`labelSpace`) are centred as one block.
10937
+ */
10938
+ function linearGaugeScaleY(height, bands, labelSpace) {
10939
+ const up = Math.max(0, ...bands.map(band => band.up));
10940
+ const down = Math.max(0, ...bands.map(band => band.down));
10941
+ return Math.max(up, (height - (up + down + labelSpace)) / 2 + up);
10942
+ }
10943
+
10944
+ /** The order an "Auto" marker takes per series, as the chart engine cycles it. */
10945
+ const AUTO_SHAPES = ["square", "circle", "diamond", "triangle", "cross", "star4", "star5", "star6", "star10"];
10946
+ const SHAPES = {
10947
+ square: "square",
10948
+ circle: "circle",
10949
+ diamond: "diamond",
10950
+ triangle: "triangle",
10951
+ cross: "cross",
10952
+ star4: "star4",
10953
+ star5: "star5",
10954
+ star6: "star6",
10955
+ star10: "star10"
10956
+ };
10957
+ /** The marker size when the series sets none, as the server uses it. */
10958
+ const RDL_DEFAULT_MARKER_SIZE_PT = 5;
10959
+ /**
10960
+ * The marker a series draws, or null for none. The server resolves Auto to a shape, so a missing type
10961
+ * or None means no marker. Should an Auto (or an unknown name) still arrive, a scatter series cycles
10962
+ * the shapes per series, so its points stay visible; a line series then draws none.
10963
+ */
10964
+ function seriesMarker(markerType, scatter, seriesIndex) {
10965
+ if (!markerType)
10966
+ return null;
10967
+ const name = markerType.trim().toLowerCase();
10968
+ if (name === "none" || name === "")
10969
+ return null;
10970
+ const shape = SHAPES[name];
10971
+ if (shape)
10972
+ return shape;
10973
+ return scatter ? AUTO_SHAPES[seriesIndex % AUTO_SHAPES.length] : null;
10974
+ }
10975
+ /** The marker size in pixels at a zoom (RDL size, default 5pt), at least 3 px so it stays visible. */
10976
+ function markerSizePx(markerSize, zoom) {
10977
+ return Math.max(3, ptToPx(parseRdlSize(markerSize) ?? RDL_DEFAULT_MARKER_SIZE_PT, zoom));
10978
+ }
10979
+ function round(value) {
10980
+ return Math.round(value * 100) / 100;
10981
+ }
10982
+ function polygon(points) {
10983
+ return `M${points.map(([x, y]) => `${round(x)},${round(y)}`).join(" L")} Z`;
10984
+ }
10985
+ function star(cx, cy, outer, points) {
10986
+ const inner = outer * (points <= 4 ? 0.35 : 0.45);
10987
+ const corners = [];
10988
+ for (let index = 0; index < points * 2; index++) {
10989
+ const radius = index % 2 === 0 ? outer : inner;
10990
+ const angle = -Math.PI / 2 + (index * Math.PI) / points;
10991
+ corners.push([cx + radius * Math.cos(angle), cy + radius * Math.sin(angle)]);
10992
+ }
10993
+ return polygon(corners);
10994
+ }
10995
+ /** SVG path of a marker of `size` (its width; an X has arms of that length along its diagonals) centered on (cx, cy); every shape is filled. */
10996
+ function markerPath(shape, cx, cy, size) {
10997
+ const r = size / 2;
10998
+ switch (shape) {
10999
+ case "square":
11000
+ return polygon([[cx - r, cy - r], [cx + r, cy - r], [cx + r, cy + r], [cx - r, cy + r]]);
11001
+ case "circle":
11002
+ return `M${round(cx - r)},${round(cy)} A${round(r)},${round(r)} 0 1 0 ${round(cx + r)},${round(cy)} A${round(r)},${round(r)} 0 1 0 ${round(cx - r)},${round(cy)} Z`;
11003
+ case "diamond":
11004
+ return polygon([[cx, cy - r], [cx + r, cy], [cx, cy + r], [cx - r, cy]]);
11005
+ case "triangle":
11006
+ return polygon([[cx, cy - r], [cx + r, cy + r], [cx - r, cy + r]]);
11007
+ case "cross": {
11008
+ // The chart engine's Cross is an X: a filled plus sign, its arms a third of the size thick, turned by 45 degrees.
11009
+ const t = size / 6;
11010
+ const plus = [
11011
+ [-t, -r], [t, -r], [t, -t], [r, -t], [r, t], [t, t],
11012
+ [t, r], [-t, r], [-t, t], [-r, t], [-r, -t], [-t, -t]
11013
+ ];
11014
+ const turn = Math.SQRT1_2;
11015
+ return polygon(plus.map(([dx, dy]) => [cx + (dx - dy) * turn, cy + (dx + dy) * turn]));
11016
+ }
11017
+ case "star4": return star(cx, cy, r, 4);
11018
+ case "star5": return star(cx, cy, r, 5);
11019
+ case "star6": return star(cx, cy, r, 6);
11020
+ case "star10": return star(cx, cy, r, 10);
11021
+ }
11022
+ }
11023
+ const ALIGN = {
11024
+ left: "start",
11025
+ top: "start",
11026
+ center: "center",
11027
+ right: "end",
11028
+ bottom: "end"
11029
+ };
11030
+ /** The RDL default legend position: a column on the right, vertically centered (RightCenter). */
11031
+ const DEFAULT_LEGEND = { edge: "right", align: "center" };
11032
+ /**
11033
+ * The RDL ChartLegend Position as an edge and an alignment: the first word is the edge, the second
11034
+ * the alignment along it (TopLeft = top edge, left aligned; LeftTop = left edge, top aligned).
11035
+ * Missing or unknown = RightCenter, the RDL default.
11036
+ */
11037
+ function legendPlacement(position) {
11038
+ const match = /^(top|bottom|left|right)(left|right|top|bottom|center)$/i.exec((position ?? "").trim());
11039
+ if (!match)
11040
+ return DEFAULT_LEGEND;
11041
+ const edge = match[1].toLowerCase();
11042
+ const along = match[2].toLowerCase();
11043
+ const horizontalEdge = edge === "top" || edge === "bottom";
11044
+ // "TopTop" or "LeftLeft" make no sense: the alignment must run along the edge.
11045
+ const valid = horizontalEdge ? ["left", "center", "right"].includes(along) : ["top", "center", "bottom"].includes(along);
11046
+ return { edge, align: valid ? ALIGN[along] : "center" };
11047
+ }
11048
+
11049
+ var styles$2 = {"chart":"cw-report-chart-module__chart__HEwvf","title":"cw-report-chart-module__title__zvCfx","axis":"cw-report-chart-module__axis__qwHaL","grid":"cw-report-chart-module__grid__xJMG8","tick":"cw-report-chart-module__tick__uQJeQ","muted":"cw-report-chart-module__muted__Nj1-j","hit":"cw-report-chart-module__hit__-u6vf","point":"cw-report-chart-module__point__M-GuI","slice":"cw-report-chart-module__slice__DEbOB","track":"cw-report-chart-module__track__NAVBX","needle":"cw-report-chart-module__needle__m5fJK","cap":"cw-report-chart-module__cap__zL7KT"};
11050
+
11051
+ /** Chart text size in points (scaled with the zoom). */
11052
+ const CHART_FONT_PT = 8;
11053
+ /** Rough width of one character of the chart font, as a share of the font size. */
11054
+ const CHAR_WIDTH = 0.6;
11055
+ function chartFontPx(zoom) {
11056
+ return ptToPx(CHART_FONT_PT, zoom);
11057
+ }
11058
+ function estimateTextWidth(text, fontPx) {
11059
+ return text.length * fontPx * CHAR_WIDTH;
11060
+ }
11061
+ /** Hover handlers that show the shared CwTooltipManager tooltip over an SVG element. */
11062
+ function useChartTooltip() {
11063
+ React.useEffect(() => {
11064
+ ensureTooltipManager();
11065
+ }, []);
11066
+ const show = React.useCallback((content) => (event) => {
11067
+ showTooltip(content, event.currentTarget, "top");
11068
+ }, []);
11069
+ const hide = React.useCallback(() => hideTooltip(), []);
11070
+ return { show, hide };
11071
+ }
11072
+ function tooltipContent(title, label, value) {
11073
+ return (jsxRuntime.jsxs("span", { children: [jsxRuntime.jsx("strong", { children: title }), jsxRuntime.jsx("br", {}), label, ": ", value] }));
11074
+ }
11075
+ /** Lays legend entries out in rows that wrap at `width`, each row aligned within `width` (centered by default). */
11076
+ function layoutLegend(entries, width, fontPx, align = "center") {
11077
+ if (entries.length === 0)
11078
+ return { height: 0, width: 0, items: [] };
11079
+ const swatch = fontPx;
11080
+ const gap = fontPx;
11081
+ const lineHeight = fontPx * 1.6;
11082
+ const rows = [[]];
11083
+ let rowWidth = 0;
11084
+ for (const entry of entries) {
11085
+ const itemWidth = swatch + fontPx * 0.4 + estimateTextWidth(entry.label, fontPx);
11086
+ if (rowWidth > 0 && rowWidth + gap + itemWidth > width) {
11087
+ rows.push([]);
11088
+ rowWidth = 0;
11089
+ }
11090
+ rowWidth += (rowWidth > 0 ? gap : 0) + itemWidth;
11091
+ rows[rows.length - 1].push({ entry, width: itemWidth });
11092
+ }
11093
+ const items = [];
11094
+ let widest = 0;
11095
+ rows.forEach((row, rowIndex) => {
11096
+ const total = row.reduce((acc, item) => acc + item.width, 0) + gap * (row.length - 1);
11097
+ widest = Math.max(widest, total);
11098
+ const free = Math.max(0, width - total);
11099
+ let x = align === "start" ? 0 : align === "end" ? free : free / 2;
11100
+ for (const item of row) {
11101
+ items.push({ entry: item.entry, x, y: rowIndex * lineHeight + lineHeight / 2 });
11102
+ x += item.width + gap;
11103
+ }
11104
+ });
11105
+ return { height: rows.length * lineHeight, width: widest, items };
11106
+ }
11107
+ function ChartLegend({ layout, top, left = 0, fontPx }) {
11108
+ return (jsxRuntime.jsx("g", { transform: `translate(${left}, ${top})`, children: layout.items.map((item, index) => (jsxRuntime.jsxs("g", { transform: `translate(${item.x}, ${item.y})`, children: [item.entry.marker
11109
+ ? jsxRuntime.jsx("path", { d: markerPath(item.entry.marker, fontPx / 2, 0, fontPx), fill: item.entry.color })
11110
+ : jsxRuntime.jsx("rect", { x: 0, y: -fontPx / 2, width: fontPx, height: fontPx, fill: item.entry.color }), jsxRuntime.jsx("text", { x: fontPx * 1.4, dominantBaseline: "central", fontSize: fontPx, children: item.entry.label })] }, index))) }));
11111
+ }
11112
+ /** The chart titles, one line each, centered. Returns the height they take. */
11113
+ function ChartTitles({ titles, width, fontPx }) {
11114
+ return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: titles.map((title, index) => (jsxRuntime.jsx("text", { className: styles$2.title, x: width / 2, y: fontPx * 1.5 * (index + 1), textAnchor: "middle", fontSize: fontPx * 1.25, children: title }, index))) }));
11115
+ }
11116
+ function titlesHeight(titles, fontPx) {
11117
+ return titles.length === 0 ? 0 : fontPx * 1.5 * titles.length + fontPx * 0.5;
11118
+ }
11119
+ /** A centered message instead of the plot (dataset error or no rows). */
11120
+ function ChartMessage({ text, width, height, fontPx }) {
11121
+ return (jsxRuntime.jsx("text", { className: styles$2.muted, x: width / 2, y: height / 2, textAnchor: "middle", dominantBaseline: "central", fontSize: fontPx * 1.2, children: text }));
11122
+ }
11123
+
11124
+ /** 270 degree dial: from 7:30 to 4:30 on a clock face, in radians from 12 o'clock. */
11125
+ const DIAL_START = -Math.PI * 0.75;
11126
+ const DIAL_END = Math.PI * 0.75;
11127
+ /** Report content defaults, as the old viewer drew them: black pointers, the Default palette for ranges. */
11128
+ const POINTER_FALLBACK = "black";
11129
+ const RANGE_PALETTE = chartPalette(null);
11130
+ /** Thickness of a range / pointer without a Width, as a fraction of the gauge height (the chart engine defaults). */
11131
+ const RANGE_DEFAULT_WIDTH = 0.3;
11132
+ const POINTER_DEFAULT_WIDTH = 0.1;
11133
+ const EMPTY_SCALE = { Minimum: 0, Maximum: 100, Pointers: [], Ranges: [] };
11134
+ function isBarPointer(type) {
11135
+ return (type ?? "").toLowerCase() === "bar";
11136
+ }
11137
+ function rangeColor(range, index) {
11138
+ return range.Color || RANGE_PALETTE[index % RANGE_PALETTE.length];
11139
+ }
11140
+ function pointerColor(pointer) {
11141
+ return pointer.Color || POINTER_FALLBACK;
11142
+ }
11143
+ function RadialGauge({ gauge, width, height, fontPx, zoom }) {
11144
+ const scale = gauge.Scales[0] ?? EMPTY_SCALE;
11145
+ const { Minimum: min, Maximum: max } = scale;
11146
+ const radius = Math.max(0, Math.min(width / 2, height / 1.75) - fontPx * 0.5);
11147
+ const cx = width / 2;
11148
+ const cy = fontPx * 0.5 + radius;
11149
+ const band = radius * 0.15;
11150
+ const angle = (value) => scaleValue(clampGaugeValue(value, min, max), { min, max }, DIAL_START, DIAL_END);
11151
+ const minLabel = polar(cx, cy, radius - band * 2.5, DIAL_START);
11152
+ const maxLabel = polar(cx, cy, radius - band * 2.5, DIAL_END);
11153
+ const showLabels = scale.ShowLabels !== false;
11154
+ return (jsxRuntime.jsxs("g", { children: [jsxRuntime.jsx("path", { className: styles$2.track, d: arcPath(cx, cy, radius, radius - band, DIAL_START, DIAL_END) }), scale.Ranges.map((range, index) => (jsxRuntime.jsx("path", { d: arcPath(cx, cy, radius, radius - band, angle(range.Start ?? min), angle(range.End ?? max)), fill: rangeColor(range, index) }, `r${index}`))), scale.Pointers.map((pointer, index) => {
11155
+ if (isBarPointer(pointer.Type)) {
11156
+ const span = gaugeBarSpan(pointer.Value, min, max);
11157
+ return (jsxRuntime.jsx("path", { d: arcPath(cx, cy, radius - band * 1.2, radius - band * 1.9, angle(span.from), angle(span.to)), fill: pointerColor(pointer) }, `p${index}`));
11158
+ }
11159
+ const tip = polar(cx, cy, radius * 0.8, angle(pointer.Value ?? min));
11160
+ return (jsxRuntime.jsx("line", { className: styles$2.needle, x1: cx, y1: cy, x2: tip.x, y2: tip.y, style: pointer.Color ? { stroke: pointer.Color } : undefined, strokeWidth: Math.max(1.5, 2.5 * zoom) }, `p${index}`));
11161
+ }), jsxRuntime.jsx("circle", { className: styles$2.cap, cx: cx, cy: cy, r: Math.max(2, radius * 0.06) }), showLabels && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("text", { className: styles$2.tick, x: minLabel.x, y: minLabel.y, textAnchor: "middle", fontSize: fontPx, children: formatChartValue(min) }), jsxRuntime.jsx("text", { className: styles$2.tick, x: maxLabel.x, y: maxLabel.y, textAnchor: "middle", fontSize: fontPx, children: formatChartValue(max) })] }))] }));
11162
+ }
11163
+ /**
11164
+ * A horizontal linear gauge as the chart engine draws it: range bands and pointers are as thick as
11165
+ * their Width percent of the gauge height (ranges 30%, pointers 10% by default) around the scale line
11166
+ * (Cross centred, Inside above, Outside below), the ranges in their own colour at full opacity, a Bar
11167
+ * pointer on top of them from the minimum to the value, and the major ticks with labels below.
11168
+ */
11169
+ function LinearGauge({ gauge, width, height, fontPx }) {
11170
+ const scale = gauge.Scales[0] ?? EMPTY_SCALE;
11171
+ const { Minimum: min, Maximum: max } = scale;
11172
+ const showLabels = scale.ShowLabels !== false;
11173
+ const left = fontPx;
11174
+ const right = width - fontPx;
11175
+ const labelSpace = showLabels ? fontPx * 2 : 0;
11176
+ const x = (value) => scaleValue(clampGaugeValue(value, min, max), { min, max }, left, right);
11177
+ const ticks = showLabels ? gaugeTicks(min, max, scale.Interval) : [];
11178
+ const ranges = scale.Ranges.map(range => {
11179
+ const thickness = gaugeThickness(range.Width, height, RANGE_DEFAULT_WIDTH);
11180
+ return { range, thickness, extent: gaugeBandExtent(range.Placement, thickness) };
11181
+ });
11182
+ const pointers = scale.Pointers.map(pointer => {
11183
+ const thickness = gaugeThickness(pointer.Width, height, POINTER_DEFAULT_WIDTH);
11184
+ return { pointer, thickness, extent: gaugeBandExtent(pointer.Placement, thickness) };
11185
+ });
11186
+ const extents = [...ranges, ...pointers].map(band => band.extent);
11187
+ const scaleY = linearGaugeScaleY(height, extents, labelSpace);
11188
+ const bandsBottom = scaleY + Math.max(0, ...extents.map(extent => extent.down));
11189
+ return (jsxRuntime.jsxs("g", { children: [ranges.map(({ range, thickness, extent }, index) => {
11190
+ const from = x(range.Start ?? min);
11191
+ const to = x(range.End ?? max);
11192
+ return (jsxRuntime.jsx("rect", { x: Math.min(from, to), y: scaleY - extent.up, width: Math.abs(to - from), height: thickness, fill: rangeColor(range, index) }, `r${index}`));
11193
+ }), jsxRuntime.jsx("line", { className: styles$2.axis, x1: left, x2: right, y1: scaleY, y2: scaleY }), pointers.map(({ pointer, thickness, extent }, index) => {
11194
+ if (isBarPointer(pointer.Type)) {
11195
+ const span = gaugeBarSpan(pointer.Value, min, max);
11196
+ const from = x(span.from);
11197
+ const to = x(span.to);
11198
+ return (jsxRuntime.jsx("rect", { x: Math.min(from, to), y: scaleY - extent.up, width: Math.abs(to - from), height: thickness, fill: pointerColor(pointer) }, `p${index}`));
11199
+ }
11200
+ // A marker: a triangle pointing at the scale line from below.
11201
+ const at = x(pointer.Value ?? min);
11202
+ const size = Math.max(thickness, fontPx * 0.6);
11203
+ return (jsxRuntime.jsx("path", { d: `M${at},${scaleY} l${-size / 2},${size} h${size} Z`, fill: pointerColor(pointer) }, `p${index}`));
11204
+ }), ticks.map(tick => (jsxRuntime.jsxs("g", { children: [jsxRuntime.jsx("line", { className: styles$2.axis, x1: x(tick), x2: x(tick), y1: bandsBottom, y2: bandsBottom + fontPx * 0.4 }), jsxRuntime.jsx("text", { className: styles$2.tick, x: x(tick), y: bandsBottom + fontPx * 1.5, textAnchor: "middle", fontSize: fontPx, children: formatChartValue(tick) })] }, tick)))] }));
11205
+ }
11206
+ /**
11207
+ * A gauge panel: its gauges side by side (RadialGauge = 270 degree dial with colored ranges and a
11208
+ * needle or bar per pointer, LinearGauge = horizontal track with range bands, a bar or marker per
11209
+ * pointer and the major ticks), the state indicators at their percent boxes and the panel labels
11210
+ * below. The pointer value is not printed; only the report's own labels are. Only the first scale of
11211
+ * a gauge is drawn.
11212
+ */
11213
+ function CwReportGauge({ panel, width, height, zoom = 1 }) {
11214
+ const fontPx = chartFontPx(zoom);
11215
+ const lineHeight = fontPx * 1.5;
11216
+ const labelsHeight = panel.Labels.length * lineHeight;
11217
+ const gaugeHeight = Math.max(0, height - labelsHeight);
11218
+ const cellWidth = panel.Gauges.length > 0 ? width / panel.Gauges.length : width;
11219
+ return (jsxRuntime.jsxs("svg", { className: styles$2.chart, width: width, height: height, role: "img", "aria-label": panel.Name, children: [panel.Error ? (jsxRuntime.jsx(ChartMessage, { text: panel.Error, width: width, height: height, fontPx: fontPx })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [panel.Gauges.map((gauge, index) => {
11220
+ const drawProps = { gauge, width: cellWidth, height: gaugeHeight, fontPx, zoom };
11221
+ return (jsxRuntime.jsx("g", { transform: `translate(${cellWidth * index}, 0)`, children: gauge.Kind.toLowerCase() === "lineargauge" ? jsxRuntime.jsx(LinearGauge, { ...drawProps }) : jsxRuntime.jsx(RadialGauge, { ...drawProps }) }, index));
11222
+ }), (panel.StateIndicators ?? []).map((indicator, index) => {
11223
+ const ellipse = stateIndicatorEllipse(indicator, width, height);
11224
+ return ellipse && jsxRuntime.jsx("ellipse", { ...ellipse, fill: indicator.Color ?? undefined }, `s${index}`);
11225
+ })] })), panel.Labels.map((label, index) => (jsxRuntime.jsx("text", { x: width / 2, y: gaugeHeight + lineHeight * (index + 0.7), textAnchor: "middle", fontSize: fontPx, children: label }, index)))] }));
11226
+ }
11227
+
11228
+ /*
11229
+ * The .NET numeric format strings a report puts on a chart's value axis (<Format>), applied with the
11230
+ * report culture so the screen shows the same tick text as the server's PDF. Only the formats reports
11231
+ * actually use are covered; anything else returns null and the caller keeps its own formatting.
11232
+ */
11233
+ /** .NET's default decimals of the N, F and P standard formats without a precision. */
11234
+ const STANDARD_DEFAULT_DECIMALS = 2;
11235
+ const STANDARD_FORMAT = /^([NnFfPp])(\d{1,2})?$/;
11236
+ /** 0, 0.00, 0.0#, #,##0, #,0.00, 0%, 0.0% ... (integer part of 0, # and one optional grouping comma). */
11237
+ const CUSTOM_FORMAT = /^(#*,?#*0+)(?:\.(0*)(#*))?(%?)$/;
11238
+ /**
11239
+ * Formats longer than this are not matched (the custom pattern backtracks quadratically on a long
11240
+ * non-matching string), and more decimals than this are left to the caller: Intl.NumberFormat throws
11241
+ * above 100 fraction digits (above 20 on older browsers), which would break the chart render.
11242
+ */
11243
+ const MAX_FORMAT_LENGTH = 64;
11244
+ const MAX_FRACTION_DIGITS = 20;
11245
+ function parseFormat(format) {
11246
+ if (format.length > MAX_FORMAT_LENGTH)
11247
+ return null;
11248
+ const standard = STANDARD_FORMAT.exec(format);
11249
+ if (standard) {
11250
+ const kind = standard[1].toUpperCase();
11251
+ const digits = standard[2] === undefined ? STANDARD_DEFAULT_DECIMALS : parseInt(standard[2], 10);
11252
+ return {
11253
+ minimumFractionDigits: digits,
11254
+ maximumFractionDigits: digits,
11255
+ grouping: kind !== "F",
11256
+ percent: kind === "P" ? "standard" : null
11257
+ };
11258
+ }
11259
+ const custom = CUSTOM_FORMAT.exec(format);
11260
+ if (custom) {
11261
+ const required = custom[2]?.length ?? 0;
11262
+ const optional = custom[3]?.length ?? 0;
11263
+ return {
11264
+ minimumFractionDigits: required,
11265
+ maximumFractionDigits: required + optional,
11266
+ grouping: custom[1].includes(","),
11267
+ percent: custom[4] === "%" ? "custom" : null
11268
+ };
11269
+ }
11270
+ return null;
11271
+ }
11272
+ function numberFormat(locale, options) {
11273
+ try {
11274
+ return new Intl.NumberFormat(locale || "en-US", options);
11275
+ }
11276
+ catch {
11277
+ return new Intl.NumberFormat("en-US", options);
11278
+ }
11279
+ }
11280
+ /**
11281
+ * A value in a .NET numeric format ("N0", "F1", "P0", "0", "0.0", "#,##0.00", "0%", ...) and a culture
11282
+ * ("de-CH"; missing or unknown = invariant-like en-US). Null for a missing or unsupported format.
11283
+ * The standard "P" uses the culture's percent pattern (e.g. "12 %" in de-DE); a custom "%" appends the
11284
+ * sign directly, as .NET does.
11285
+ */
11286
+ function formatRdlNumber(value, format, culture) {
11287
+ if (!format || !Number.isFinite(value))
11288
+ return null;
11289
+ const spec = parseFormat(format.trim());
11290
+ if (!spec || spec.maximumFractionDigits > MAX_FRACTION_DIGITS)
11291
+ return null;
11292
+ const digits = {
11293
+ minimumFractionDigits: spec.minimumFractionDigits,
11294
+ maximumFractionDigits: spec.maximumFractionDigits,
11295
+ useGrouping: spec.grouping
11296
+ };
11297
+ const locale = culture ?? undefined;
11298
+ if (spec.percent === "standard")
11299
+ return numberFormat(locale, { ...digits, style: "percent" }).format(value);
11300
+ if (spec.percent === "custom") {
11301
+ // The percent style scales by 100 without float noise (0.145 -> 14.5, not 14.499...); its own
11302
+ // sign and spacing are dropped for the plain "%" a custom format appends.
11303
+ const parts = numberFormat(locale, { ...digits, style: "percent" }).formatToParts(value);
11304
+ return `${parts.filter(part => part.type !== "percentSign" && part.type !== "literal").map(part => part.value).join("")}%`;
11305
+ }
11306
+ return numberFormat(locale, digits).format(value);
11307
+ }
11308
+
11309
+ function seriesKind(series) {
11310
+ switch (series.Type.toLowerCase()) {
11311
+ case "column": return "column";
11312
+ case "bar": return "bar";
11313
+ case "area": return "area";
11314
+ case "scatter": return "scatter";
11315
+ default: return "line";
11316
+ }
11317
+ }
11318
+ function truncate(text, maxWidth, fontPx) {
11319
+ if (estimateTextWidth(text, fontPx) <= maxWidth)
11320
+ return text;
11321
+ const chars = Math.max(1, Math.floor(maxWidth / (fontPx * 0.6)) - 1);
11322
+ return text.slice(0, chars) + "…";
11323
+ }
11324
+ /** Categories along the x axis, values up: lines, areas, columns and scatter points. */
11325
+ function VerticalPlot({ chart, colors, scale, fontPx, left, top, right, bottom, strokeWidth, zoom, tickLabel }) {
11326
+ const tooltip = useChartTooltip();
11327
+ const count = Math.max(1, chart.Categories.length);
11328
+ const band = (right - left) / count;
11329
+ const x = (index) => left + band * (index + 0.5);
11330
+ const y = (value) => scaleValue(value, scale, bottom, top);
11331
+ const baseline = y(Math.min(scale.max, Math.max(scale.min, 0)));
11332
+ const columns = chart.Series.map((series, index) => ({ series, index })).filter(({ series }) => {
11333
+ const kind = seriesKind(series);
11334
+ return kind === "column" || kind === "bar";
11335
+ });
11336
+ const groupWidth = band * 0.75;
11337
+ const columnWidth = columns.length > 0 ? groupWidth / columns.length : 0;
11338
+ const labelWidth = Math.max(...chart.Categories.map(label => estimateTextWidth(label, fontPx)), 0) + fontPx;
11339
+ const labelStep = Math.max(1, Math.ceil(Math.min(labelWidth, fontPx * 12) / band));
11340
+ const marks = [];
11341
+ const hits = [];
11342
+ columns.forEach(({ series, index }, columnIndex) => {
11343
+ series.Values.forEach((value, category) => {
11344
+ if (value === null || !Number.isFinite(value))
11345
+ return;
11346
+ const columnX = left + band * category + (band - groupWidth) / 2 + columnWidth * columnIndex;
11347
+ const valueY = y(value);
11348
+ const content = tooltipContent(series.Name, chart.Categories[category] ?? "", formatChartValue(value));
11349
+ marks.push(jsxRuntime.jsx("rect", { x: columnX, y: Math.min(valueY, baseline), width: Math.max(1, columnWidth - 1), height: Math.max(0, Math.abs(baseline - valueY)), fill: colors[index], onMouseEnter: tooltip.show(content), onMouseLeave: tooltip.hide }, `c${index}-${category}`));
11350
+ if (series.ShowDataLabels) {
11351
+ marks.push(jsxRuntime.jsx("text", { x: columnX + columnWidth / 2, y: valueY - fontPx * 0.4, textAnchor: "middle", fontSize: fontPx, children: formatChartValue(value) }, `cl${index}-${category}`));
11352
+ }
11353
+ });
11354
+ });
11355
+ chart.Series.forEach((series, index) => {
11356
+ const kind = seriesKind(series);
11357
+ if (kind !== "line" && kind !== "area" && kind !== "scatter")
11358
+ return;
11359
+ const marker = seriesMarker(series.MarkerType, kind === "scatter", index);
11360
+ const markerSize = markerSizePx(series.MarkerSize, zoom);
11361
+ const segments = lineSegments(series.Values, x, y);
11362
+ segments.forEach((segment, segmentIndex) => {
11363
+ if (kind !== "scatter")
11364
+ drawLine(segment, segmentIndex);
11365
+ for (const point of segment) {
11366
+ if (marker) {
11367
+ marks.push(jsxRuntime.jsx("path", { d: markerPath(marker, point.x, point.y, markerSize), fill: colors[index] }, `m${index}-${point.index}`));
11368
+ }
11369
+ if (series.ShowDataLabels) {
11370
+ marks.push(jsxRuntime.jsx("text", { x: point.x, y: point.y - Math.max(fontPx * 0.6, markerSize), textAnchor: "middle", fontSize: fontPx, children: formatChartValue(point.value) }, `ll${index}-${point.index}`));
11371
+ }
11372
+ const content = tooltipContent(series.Name, chart.Categories[point.index] ?? "", formatChartValue(point.value));
11373
+ hits.push(jsxRuntime.jsx("circle", { className: styles$2.hit, cx: point.x, cy: point.y, r: Math.max(4, Math.min(8, band / 3), markerSize / 2), onMouseEnter: tooltip.show(content), onMouseLeave: tooltip.hide }, `h${index}-${point.index}`));
11374
+ }
11375
+ });
11376
+ function drawLine(segment, segmentIndex) {
11377
+ const path = segmentPath(segment, series.Subtype);
11378
+ if (kind === "area") {
11379
+ const first = segment[0];
11380
+ const last = segment[segment.length - 1];
11381
+ marks.push(jsxRuntime.jsx("path", { d: `${path} L${last.x},${baseline} L${first.x},${baseline} Z`, fill: colors[index], fillOpacity: 0.45, stroke: "none" }, `a${index}-${segmentIndex}`));
11382
+ }
11383
+ marks.push(jsxRuntime.jsx("path", { d: path, fill: "none", stroke: colors[index], strokeWidth: strokeWidth }, `l${index}-${segmentIndex}`));
11384
+ // A lone point between gaps has no line to show it: a dot, unless the series draws markers.
11385
+ if (segment.length === 1 && !marker) {
11386
+ marks.push(jsxRuntime.jsx("circle", { className: styles$2.point, cx: segment[0].x, cy: segment[0].y, r: strokeWidth * 1.5, fill: colors[index] }, `p${index}-${segmentIndex}`));
11387
+ }
11388
+ }
11389
+ });
11390
+ const serverLabels = chart.CategoryAxisLabels ? categoryAxisLabels(chart.CategoryAxisLabels, count, left, band) : null;
11391
+ // Category gridlines run through the labelled categories: the server's labels, else every labelStep-th category.
11392
+ const categoryGrid = chart.CategoryAxisGridLines === false
11393
+ ? []
11394
+ : serverLabels?.map(label => label.at) ?? chart.Categories.map((_label, index) => index).filter(index => index % labelStep === 0).map(x);
11395
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [categoryGrid.map((at, index) => jsxRuntime.jsx("line", { className: styles$2.grid, x1: at, x2: at, y1: top, y2: bottom }, `cg${index}`)), scale.ticks.map(tick => (jsxRuntime.jsxs("g", { children: [chart.ValueAxisGridLines !== false && jsxRuntime.jsx("line", { className: styles$2.grid, x1: left, x2: right, y1: y(tick), y2: y(tick) }), jsxRuntime.jsx("text", { className: styles$2.tick, x: left - fontPx * 0.4, y: y(tick), textAnchor: "end", dominantBaseline: "central", fontSize: fontPx, children: tickLabel(tick) })] }, tick))), jsxRuntime.jsx("line", { className: styles$2.axis, x1: left, x2: left, y1: top, y2: bottom }), jsxRuntime.jsx("line", { className: styles$2.axis, x1: left, x2: right, y1: baseline, y2: baseline }), serverLabels
11396
+ ? serverLabels.map((label, index) => {
11397
+ const placement = placeAxisLabel(label.at, estimateTextWidth(label.text, fontPx), left, right);
11398
+ return (jsxRuntime.jsxs("g", { children: [jsxRuntime.jsx("line", { className: styles$2.axis, x1: label.at, x2: label.at, y1: bottom, y2: bottom + fontPx * 0.3 }), jsxRuntime.jsx("text", { className: styles$2.tick, x: placement.x, y: bottom + fontPx * 1.3, textAnchor: placement.anchor, fontSize: fontPx, children: label.text })] }, `c${index}`));
11399
+ })
11400
+ : chart.Categories.map((label, index) => {
11401
+ if (index % labelStep !== 0)
11402
+ return null;
11403
+ const text = truncate(label, band * labelStep - fontPx * 0.4, fontPx);
11404
+ const placement = placeAxisLabel(x(index), estimateTextWidth(text, fontPx), left, right);
11405
+ return (jsxRuntime.jsx("text", { className: styles$2.tick, x: placement.x, y: bottom + fontPx * 1.1, textAnchor: placement.anchor, fontSize: fontPx, children: text }, index));
11406
+ }), marks, hits] }));
11407
+ }
11408
+ /** Categories down the y axis, values to the right: horizontal bars. */
11409
+ function HorizontalPlot({ chart, colors, scale, fontPx, left, top, right, bottom, tickLabel }) {
11410
+ const tooltip = useChartTooltip();
11411
+ const count = Math.max(1, chart.Categories.length);
11412
+ const band = (bottom - top) / count;
11413
+ const x = (value) => scaleValue(value, scale, left, right);
11414
+ const baseline = x(Math.min(scale.max, Math.max(scale.min, 0)));
11415
+ const groupHeight = band * 0.75;
11416
+ const barHeight = chart.Series.length > 0 ? groupHeight / chart.Series.length : 0;
11417
+ const serverLabels = chart.CategoryAxisLabels ? categoryAxisLabels(chart.CategoryAxisLabels, count, top, band) : null;
11418
+ const categoryGrid = chart.CategoryAxisGridLines === false
11419
+ ? []
11420
+ : serverLabels?.map(label => label.at) ?? chart.Categories.map((_label, index) => top + band * (index + 0.5));
11421
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [categoryGrid.map((at, index) => jsxRuntime.jsx("line", { className: styles$2.grid, x1: left, x2: right, y1: at, y2: at }, `cg${index}`)), scale.ticks.map(tick => (jsxRuntime.jsxs("g", { children: [chart.ValueAxisGridLines !== false && jsxRuntime.jsx("line", { className: styles$2.grid, x1: x(tick), x2: x(tick), y1: top, y2: bottom }), jsxRuntime.jsx("text", { className: styles$2.tick, x: x(tick), y: bottom + fontPx * 1.1, textAnchor: "middle", fontSize: fontPx, children: tickLabel(tick) })] }, tick))), jsxRuntime.jsx("line", { className: styles$2.axis, x1: baseline, x2: baseline, y1: top, y2: bottom }), jsxRuntime.jsx("line", { className: styles$2.axis, x1: left, x2: right, y1: bottom, y2: bottom }), serverLabels
11422
+ ? serverLabels.map((label, index) => (jsxRuntime.jsxs("g", { children: [jsxRuntime.jsx("line", { className: styles$2.axis, x1: left - fontPx * 0.3, x2: left, y1: label.at, y2: label.at }), jsxRuntime.jsx("text", { className: styles$2.tick, x: left - fontPx * 0.4, y: label.at, textAnchor: "end", dominantBaseline: "central", fontSize: fontPx, children: truncate(label.text, left - fontPx, fontPx) })] }, `c${index}`)))
11423
+ : chart.Categories.map((label, index) => (jsxRuntime.jsx("text", { className: styles$2.tick, x: left - fontPx * 0.4, y: top + band * (index + 0.5), textAnchor: "end", dominantBaseline: "central", fontSize: fontPx, children: truncate(label, left - fontPx, fontPx) }, index))), chart.Series.map((series, index) => series.Values.map((value, category) => {
11424
+ if (value === null || !Number.isFinite(value))
11425
+ return null;
11426
+ const barY = top + band * category + (band - groupHeight) / 2 + barHeight * index;
11427
+ const valueX = x(value);
11428
+ const content = tooltipContent(series.Name, chart.Categories[category] ?? "", formatChartValue(value));
11429
+ return (jsxRuntime.jsxs("g", { children: [jsxRuntime.jsx("rect", { x: Math.min(valueX, baseline), y: barY, width: Math.max(0, Math.abs(valueX - baseline)), height: Math.max(1, barHeight - 1), fill: colors[index], onMouseEnter: tooltip.show(content), onMouseLeave: tooltip.hide }), series.ShowDataLabels && (jsxRuntime.jsx("text", { x: Math.max(valueX, baseline) + fontPx * 0.3, y: barY + barHeight / 2, dominantBaseline: "central", fontSize: fontPx, children: formatChartValue(value) }))] }, `${index}-${category}`));
11430
+ }))] }));
11431
+ }
11432
+ /**
11433
+ * A report chart over categories: Line (Smooth / Stepped), Area, Column and Scatter series share one
11434
+ * value axis; a chart made only of Bar series is drawn horizontally. Scatter series draw only their
11435
+ * markers, line series draw markers too when the report sets a marker type. Null values leave gaps.
11436
+ * The legend sits where the RDL legend Position says. Own SVG, no chart library; hover shows
11437
+ * category, series and value.
11438
+ */
11439
+ function CwReportLineChart({ chart, width, height, zoom = 1, culture }) {
11440
+ const fontPx = chartFontPx(zoom);
11441
+ const palette = chartPalette(chart.Palette);
11442
+ const colors = chart.Series.map((series, index) => seriesColor(series, index, palette));
11443
+ const titleHeight = titlesHeight(chart.Titles, fontPx);
11444
+ // The legend on the side its RDL Position names: a side legend is a column at most 30% wide.
11445
+ const placement = legendPlacement(chart.LegendPosition);
11446
+ const sideLegend = placement.edge === "left" || placement.edge === "right";
11447
+ const legend = layoutLegend(chart.LegendHidden ? [] : chart.Series.map((series, index) => ({
11448
+ label: series.Name,
11449
+ color: colors[index],
11450
+ marker: seriesMarker(series.MarkerType, seriesKind(series) === "scatter", index)
11451
+ })), sideLegend ? width * 0.3 : width, fontPx, sideLegend ? "start" : placement.align);
11452
+ const legendHeight = legend.height > 0 ? legend.height + fontPx * 0.5 : 0;
11453
+ const legendWidth = legend.width > 0 ? legend.width + fontPx : 0;
11454
+ const legendSpace = {
11455
+ top: placement.edge === "top" ? legendHeight : 0,
11456
+ bottom: placement.edge === "bottom" ? legendHeight : 0,
11457
+ left: placement.edge === "left" ? legendWidth : 0,
11458
+ right: placement.edge === "right" ? legendWidth : 0
11459
+ };
11460
+ const message = chart.Error
11461
+ ?? (chart.Categories.length === 0 || chart.Series.length === 0 ? (chart.NoRowsMessage ?? "No data") : null);
11462
+ if (message) {
11463
+ return (jsxRuntime.jsxs("svg", { className: styles$2.chart, width: width, height: height, role: "img", "aria-label": chart.Titles.join(" ") || chart.Name, children: [jsxRuntime.jsx(ChartTitles, { titles: chart.Titles, width: width, fontPx: fontPx }), jsxRuntime.jsx(ChartMessage, { text: message, width: width, height: height, fontPx: fontPx })] }));
11464
+ }
11465
+ const horizontal = chart.Series.every(series => seriesKind(series) === "bar");
11466
+ const scale = computeValueScale(chart.Series.flatMap(series => series.Values));
11467
+ // The axis <Format> with the report culture, as the server's PDF prints it; an unsupported format keeps the compact default.
11468
+ const tickLabel = (tick) => formatRdlNumber(tick, chart.ValueAxisFormat, culture) ?? formatChartValue(tick);
11469
+ const tickWidth = Math.max(...scale.ticks.map(tick => estimateTextWidth(tickLabel(tick), fontPx)));
11470
+ const categoryWidth = Math.min(width * 0.35, Math.max(...chart.Categories.map(label => estimateTextWidth(label, fontPx)), 0));
11471
+ const lineHeight = fontPx * 1.6;
11472
+ const valueTitleSpace = chart.ValueAxisTitle ? lineHeight : 0;
11473
+ const categoryTitleSpace = chart.CategoryAxisTitle ? lineHeight : 0;
11474
+ const left = legendSpace.left + (horizontal ? categoryTitleSpace + categoryWidth : valueTitleSpace + tickWidth) + fontPx * 0.8;
11475
+ const right = width - fontPx - legendSpace.right;
11476
+ const top = titleHeight + legendSpace.top + fontPx * 0.8;
11477
+ const bottom = height - legendSpace.bottom - lineHeight - (horizontal ? valueTitleSpace : categoryTitleSpace);
11478
+ const strokeWidth = Math.max(1, 1.5 * zoom);
11479
+ const plotProps = { chart, colors, scale, fontPx, left, top, right, bottom, strokeWidth, zoom, tickLabel };
11480
+ const verticalTitle = horizontal ? chart.CategoryAxisTitle : chart.ValueAxisTitle;
11481
+ const horizontalTitle = horizontal ? chart.ValueAxisTitle : chart.CategoryAxisTitle;
11482
+ const titleX = legendSpace.left + fontPx;
11483
+ const legendLeft = placement.edge === "left" ? fontPx * 0.4 : placement.edge === "right" ? width - legendWidth + fontPx * 0.4 : 0;
11484
+ const legendTop = (() => {
11485
+ switch (placement.edge) {
11486
+ case "top": return titleHeight;
11487
+ case "bottom": return height - legend.height;
11488
+ default:
11489
+ if (placement.align === "start")
11490
+ return top;
11491
+ if (placement.align === "end")
11492
+ return Math.max(top, bottom - legend.height);
11493
+ return Math.max(top, (top + bottom - legend.height) / 2);
11494
+ }
11495
+ })();
11496
+ return (jsxRuntime.jsxs("svg", { className: styles$2.chart, width: width, height: height, role: "img", "aria-label": chart.Titles.join(" ") || chart.Name, children: [jsxRuntime.jsx(ChartTitles, { titles: chart.Titles, width: width, fontPx: fontPx }), right - left > 10 && bottom - top > 10 && (horizontal ? jsxRuntime.jsx(HorizontalPlot, { ...plotProps }) : jsxRuntime.jsx(VerticalPlot, { ...plotProps })), verticalTitle && (jsxRuntime.jsx("text", { x: titleX, y: (top + bottom) / 2, textAnchor: "middle", dominantBaseline: "central", fontSize: fontPx, transform: `rotate(-90 ${titleX} ${(top + bottom) / 2})`, children: verticalTitle })), horizontalTitle && (jsxRuntime.jsx("text", { x: (left + right) / 2, y: bottom + lineHeight * 1.6, textAnchor: "middle", fontSize: fontPx, children: horizontalTitle })), jsxRuntime.jsx(ChartLegend, { layout: legend, top: legendTop, left: legendLeft, fontPx: fontPx })] }));
11497
+ }
11498
+
11499
+ /** A pie of the chart's first series over its categories (RDL series Type "Shape"). Own SVG. */
11500
+ function CwReportPieChart({ chart, width, height, zoom = 1 }) {
11501
+ const tooltip = useChartTooltip();
11502
+ const fontPx = chartFontPx(zoom);
11503
+ const palette = chartPalette(chart.Palette);
11504
+ const series = chart.Series[0];
11505
+ const colorOf = (index) => palette[index % palette.length];
11506
+ const titleHeight = titlesHeight(chart.Titles, fontPx);
11507
+ const legend = layoutLegend(chart.LegendHidden ? [] : chart.Categories.map((label, index) => ({ label, color: colorOf(index) })), width, fontPx);
11508
+ const legendHeight = legend.height > 0 ? legend.height + fontPx * 0.5 : 0;
11509
+ const slices = series ? pieSlices(series.Values) : [];
11510
+ const message = chart.Error ?? (slices.length === 0 ? (chart.NoRowsMessage ?? "No data") : null);
11511
+ const plotTop = titleHeight + fontPx * 0.5;
11512
+ const plotHeight = height - plotTop - legendHeight;
11513
+ const radius = Math.max(0, Math.min(width, plotHeight) / 2 - fontPx * 0.5);
11514
+ const cx = width / 2;
11515
+ const cy = plotTop + plotHeight / 2;
11516
+ return (jsxRuntime.jsxs("svg", { className: styles$2.chart, width: width, height: height, role: "img", "aria-label": chart.Titles.join(" ") || chart.Name, children: [jsxRuntime.jsx(ChartTitles, { titles: chart.Titles, width: width, fontPx: fontPx }), message ? (jsxRuntime.jsx(ChartMessage, { text: message, width: width, height: height, fontPx: fontPx })) : (slices.map(slice => {
11517
+ const category = chart.Categories[slice.index] ?? "";
11518
+ const percent = `${formatChartValue(slice.fraction * 100)}%`;
11519
+ const labelAt = polar(cx, cy, radius * 0.65, (slice.startAngle + slice.endAngle) / 2);
11520
+ return (jsxRuntime.jsxs("g", { children: [jsxRuntime.jsx("path", { className: styles$2.slice, d: arcPath(cx, cy, radius, 0, slice.startAngle, slice.endAngle), fill: colorOf(slice.index), onMouseEnter: tooltip.show(tooltipContent(series.Name, category, `${formatChartValue(slice.value)} (${percent})`)), onMouseLeave: tooltip.hide }), series.ShowDataLabels && slice.fraction >= 0.03 && (jsxRuntime.jsx("text", { x: labelAt.x, y: labelAt.y, textAnchor: "middle", dominantBaseline: "central", fontSize: fontPx, pointerEvents: "none", children: formatChartValue(slice.value) }))] }, slice.index));
11521
+ })), jsxRuntime.jsx(ChartLegend, { layout: legend, top: height - legend.height, fontPx: fontPx })] }));
11522
+ }
11523
+
11524
+ /** Indent of one list level, in points. */
11525
+ const RDL_LIST_INDENT_PT = 18;
11526
+ const BULLETS = ["•", "◦", "▪"];
11527
+ function listKind(paragraph) {
11528
+ switch ((paragraph.ListStyle ?? "").toLowerCase()) {
11529
+ case "bulleted": return "bulleted";
11530
+ case "numbered": return "numbered";
11531
+ default: return null;
11532
+ }
11533
+ }
11534
+ /**
11535
+ * The list marker of every paragraph (null = no list). Numbering counts consecutive numbered
11536
+ * paragraphs of the same level: a non-list paragraph resets every level, a paragraph at a level
11537
+ * resets the levels below it, and a bulleted paragraph resets the numbering of its own level.
11538
+ */
11539
+ function computeListMarkers(paragraphs) {
11540
+ const counters = [];
11541
+ return paragraphs.map(paragraph => {
11542
+ const kind = listKind(paragraph);
11543
+ if (!kind) {
11544
+ counters.length = 0;
11545
+ return null;
11546
+ }
11547
+ const level = Math.max(1, paragraph.ListLevel);
11548
+ counters.length = Math.min(counters.length, level);
11549
+ if (kind === "bulleted") {
11550
+ counters[level - 1] = 0;
11551
+ return BULLETS[(level - 1) % BULLETS.length];
11552
+ }
11553
+ counters[level - 1] = (counters[level - 1] ?? 0) + 1;
11554
+ return `${counters[level - 1]}.`;
11555
+ });
11556
+ }
11557
+ /** Left indent of a paragraph in points: one list indent per level (a list paragraph has at least level 1). */
11558
+ function paragraphIndentPt(paragraph) {
11559
+ const level = listKind(paragraph) ? Math.max(1, paragraph.ListLevel) : Math.max(0, paragraph.ListLevel);
11560
+ return level * RDL_LIST_INDENT_PT;
11561
+ }
11562
+
11563
+ const EMPTY_FLIPPED = new Set();
11564
+ const EMPTY_HIGHLIGHTS = new Map();
11565
+ const ReportRenderContext = React.createContext({
11566
+ zoom: 1,
11567
+ flipped: EMPTY_FLIPPED,
11568
+ highlights: EMPTY_HIGHLIGHTS,
11569
+ activeMatchIndex: -1
11570
+ });
11571
+ function useReportRender() {
11572
+ return React.useContext(ReportRenderContext);
11573
+ }
11574
+ /** Groups the page's matches by run key. */
11575
+ function highlightsByRun(matches) {
11576
+ const map = new Map();
11577
+ matches.forEach((match, matchIndex) => {
11578
+ const list = map.get(match.key) ?? [];
11579
+ list.push({ start: match.start, length: match.length, matchIndex });
11580
+ map.set(match.key, list);
11581
+ });
11582
+ return map;
11583
+ }
11584
+
11585
+ var styles$1 = {"sheet":"cw-report-page-module__sheet__MAL8a","section":"cw-report-page-module__section__rN7A3","item":"cw-report-page-module__item__VZFw8","table":"cw-report-page-module__table__SAZVC","textbox":"cw-report-page-module__textbox__iwVwk cw-report-page-module__item__VZFw8","textRow":"cw-report-page-module__textRow__3WIRX","textBody":"cw-report-page-module__textBody__Jp1-1","paragraph":"cw-report-page-module__paragraph__d6dYI","marker":"cw-report-page-module__marker__geRQt","link":"cw-report-page-module__link__YFX1h","match":"cw-report-page-module__match__sWdSD","inlineButton":"cw-report-page-module__inlineButton__m05OC","rectangle":"cw-report-page-module__rectangle__2PYyK cw-report-page-module__item__VZFw8","line":"cw-report-page-module__line__Vfus-","image":"cw-report-page-module__image__VEp5H cw-report-page-module__item__VZFw8","tableMessage":"cw-report-page-module__tableMessage__kWsAj","chart":"cw-report-page-module__chart__PP9oM cw-report-page-module__item__VZFw8","placeholder":"cw-report-page-module__placeholder__FK8kO cw-report-page-module__item__VZFw8"};
11586
+
11587
+ /** Size of the drilldown / sort icons, in points: a little below the default 10pt text. */
11588
+ const INLINE_ICON_PT = 9;
11589
+ const SAFE_LINK = /^(https?:|mailto:)/i;
11590
+ function highlightedText(text, highlights, activeMatchIndex) {
11591
+ if (!highlights || highlights.length === 0)
11592
+ return text;
11593
+ const parts = [];
11594
+ let cursor = 0;
11595
+ for (const highlight of highlights) {
11596
+ if (highlight.start > cursor)
11597
+ parts.push(text.slice(cursor, highlight.start));
11598
+ const active = highlight.matchIndex === activeMatchIndex;
11599
+ parts.push(jsxRuntime.jsx("mark", { className: styles$1.match, "data-active": active ? "true" : undefined, "data-active-match": active ? "true" : undefined, children: text.slice(highlight.start, highlight.start + highlight.length) }, highlight.matchIndex));
11600
+ cursor = highlight.start + highlight.length;
11601
+ }
11602
+ if (cursor < text.length)
11603
+ parts.push(text.slice(cursor));
11604
+ return parts;
11605
+ }
11606
+ function ReportRun({ run, runKey, paragraphStyle, textboxStyle }) {
11607
+ const { zoom, highlights, activeMatchIndex } = useReportRender();
11608
+ const css = rdlTextCss(resolveRdlTextStyle(run.Style, paragraphStyle, textboxStyle), zoom);
11609
+ const content = highlightedText(run.Text, highlights.get(runKey), activeMatchIndex);
11610
+ if (run.Href && SAFE_LINK.test(run.Href)) {
11611
+ return (jsxRuntime.jsx("a", { className: styles$1.link, href: run.Href, target: "_blank", rel: "noopener noreferrer", style: css, children: content }));
11612
+ }
11613
+ return jsxRuntime.jsx("span", { style: css, children: content });
11614
+ }
11615
+ function iconSizeStyle(zoom) {
11616
+ return { "--btn-size": `${ptToPx(INLINE_ICON_PT, zoom)}px` };
11617
+ }
11618
+ function sortIcon(direction) {
11619
+ switch ((direction ?? "").toLowerCase()) {
11620
+ case "ascending": return "sort-asc";
11621
+ case "descending": return "sort-desc";
11622
+ default: return "sortable";
11623
+ }
11624
+ }
11625
+ /** A textbox: paragraphs as blocks, runs as inline spans, plain text only (never HTML). */
11626
+ function ReportTextbox({ textbox, itemKey, frameStyle }) {
11627
+ const { zoom, flipped, onToggle, onSort } = useReportRender();
11628
+ const markers = computeListMarkers(textbox.Paragraphs);
11629
+ const paragraphs = textbox.Paragraphs.map((paragraph, p) => {
11630
+ const indent = ptToPx(paragraphIndentPt(paragraph), zoom);
11631
+ const marker = markers[p];
11632
+ const firstRun = paragraph.Runs[0];
11633
+ const paragraphCss = {
11634
+ ...rdlTextCss(resolveParagraphTextStyle(paragraph.Runs.map(run => run.Style), paragraph.Style, textbox.Style), zoom),
11635
+ textAlign: rdlTextAlign(paragraph.Style?.TextAlign ?? textbox.Style?.TextAlign),
11636
+ paddingLeft: indent || undefined
11637
+ };
11638
+ return (jsxRuntime.jsxs("p", { className: styles$1.paragraph, style: paragraphCss, children: [marker !== null && (jsxRuntime.jsx("span", { className: styles$1.marker, style: {
11639
+ ...rdlTextCss(resolveRdlTextStyle(firstRun?.Style, paragraph.Style, textbox.Style), zoom),
11640
+ left: indent - ptToPx(RDL_LIST_INDENT_PT, zoom),
11641
+ width: ptToPx(RDL_LIST_INDENT_PT, zoom)
11642
+ }, children: marker })), paragraph.Runs.map((run, r) => (jsxRuntime.jsx(ReportRun, { run: run, runKey: rdlRunKey(itemKey, p, r), paragraphStyle: paragraph.Style, textboxStyle: textbox.Style }, r)))] }, p));
11643
+ });
11644
+ const boxCss = {
11645
+ ...frameStyle,
11646
+ ...rdlBoxStyle(textbox.Style, zoom),
11647
+ color: rdlColor(textbox.Style?.Color),
11648
+ justifyContent: rdlVerticalAlign(textbox.Style?.VerticalAlign)
11649
+ };
11650
+ const toggleId = textbox.ToggleId;
11651
+ const sortId = textbox.SortId;
11652
+ if (!toggleId && !sortId) {
11653
+ return jsxRuntime.jsx("div", { className: styles$1.textbox, style: boxCss, children: paragraphs });
11654
+ }
11655
+ const expanded = isToggleExpanded(textbox, flipped);
11656
+ return (jsxRuntime.jsx("div", { className: styles$1.textbox, style: boxCss, children: jsxRuntime.jsxs("div", { className: styles$1.textRow, children: [toggleId && (jsxRuntime.jsx(CwButton, { variant: "icon", size: "small", icon: expanded ? "minus" : "plus", className: styles$1.inlineButton, style: iconSizeStyle(zoom), "aria-label": expanded ? "Collapse" : "Expand", "aria-expanded": expanded, "data-toggle-id": toggleId, onClick: () => onToggle?.(toggleId) })), jsxRuntime.jsx("div", { className: styles$1.textBody, children: paragraphs }), sortId && (jsxRuntime.jsx(CwButton, { variant: "icon", size: "small", icon: sortIcon(textbox.SortDirection), className: styles$1.inlineButton, style: iconSizeStyle(zoom), "aria-label": "Sort", onClick: () => onSort?.(sortId) }))] }) }));
11657
+ }
11658
+
11659
+ function frameOf(item) {
11660
+ return { top: item.Top, left: item.Left, width: item.Width, height: item.Height };
11661
+ }
11662
+ function frameCss(frame, zoom) {
11663
+ return {
11664
+ top: ptToPx(frame.top, zoom),
11665
+ left: ptToPx(frame.left, zoom),
11666
+ width: ptToPx(frame.width, zoom),
11667
+ height: ptToPx(frame.height, zoom)
11668
+ };
11669
+ }
11670
+ const SAFE_IMAGE_URL = /^https?:/i;
11671
+ function ReportRectangle({ item, itemKey, frame }) {
11672
+ const { zoom } = useReportRender();
11673
+ return (jsxRuntime.jsx("div", { className: styles$1.rectangle, style: { ...frameCss(frame, zoom), ...rdlBoxStyle(item.Style, zoom) }, children: jsxRuntime.jsx(ReportItems, { items: item.Items, parentKey: itemKey }) }));
11674
+ }
11675
+ function ReportLine({ item, frame }) {
11676
+ const { zoom } = useReportRender();
11677
+ const stroke = rdlLineStroke(item.Style, zoom);
11678
+ const x1 = ptToPx(frame.left, zoom);
11679
+ const y1 = ptToPx(frame.top, zoom);
11680
+ const x2 = ptToPx(frame.left + frame.width, zoom);
11681
+ const y2 = ptToPx(frame.top + frame.height, zoom);
11682
+ const pad = stroke.width;
11683
+ const left = Math.min(x1, x2) - pad;
11684
+ const top = Math.min(y1, y2) - pad;
11685
+ const width = Math.abs(x2 - x1) + pad * 2;
11686
+ const height = Math.abs(y2 - y1) + pad * 2;
11687
+ return (jsxRuntime.jsx("svg", { className: styles$1.line, style: { left, top, width, height }, width: width, height: height, "aria-hidden": "true", children: jsxRuntime.jsx("line", { x1: x1 - left, y1: y1 - top, x2: x2 - left, y2: y2 - top, stroke: stroke.color, strokeWidth: stroke.width, strokeDasharray: stroke.dash }) }));
11688
+ }
11689
+ function imageSizing(sizing) {
11690
+ switch (sizing.toLowerCase()) {
11691
+ case "fit": return "fit";
11692
+ case "fitproportional": return "proportional";
11693
+ default: return "natural";
11694
+ }
11695
+ }
11696
+ function ReportImage({ item, frame }) {
11697
+ const { zoom, getImageUrl } = useReportRender();
11698
+ const src = item.Url && SAFE_IMAGE_URL.test(item.Url)
11699
+ ? item.Url
11700
+ : item.ImageId && getImageUrl ? getImageUrl(item.ImageId) : null;
11701
+ const sizing = imageSizing(item.Sizing);
11702
+ return (jsxRuntime.jsx("div", { className: styles$1.image, style: { ...frameCss(frame, zoom), ...rdlBoxStyle(item.Style, zoom) }, children: src && (jsxRuntime.jsx("img", { src: src, alt: item.Name, referrerPolicy: "no-referrer", "data-sizing": sizing, style: sizing === "natural" ? { transform: `scale(${zoom})` } : undefined })) }));
11703
+ }
11704
+ function ReportTable({ item, itemKey, frame }) {
11705
+ const { zoom, flipped } = useReportRender();
11706
+ const message = item.Error ?? (item.Rows.length === 0 ? item.NoRowsMessage : null);
11707
+ if (message) {
11708
+ const textCss = rdlTextCss(resolveRdlTextStyle(null, null, item.Style), zoom);
11709
+ return (jsxRuntime.jsx("div", { className: styles$1.table, style: { ...frameCss(frame, zoom), height: undefined, ...rdlBoxStyle(item.Style, zoom) }, children: item.Error
11710
+ ? jsxRuntime.jsx(CwNote, { color: "danger", variant: "soft", fontSize: "small", content: item.Error })
11711
+ : jsxRuntime.jsx("p", { className: `${styles$1.tableMessage} cw-margin-none`, style: textCss, children: message }) }));
11712
+ }
11713
+ const layout = layoutRdlTable(item, flipped);
11714
+ return (jsxRuntime.jsx("div", { className: styles$1.table, style: { ...frameCss({ ...frame, width: layout.width, height: layout.height }, zoom), ...rdlBoxStyle(item.Style, zoom) }, children: layout.cells.map(box => {
11715
+ const content = box.cell.Content;
11716
+ if (!content)
11717
+ return null;
11718
+ const cellFrame = { top: box.top, left: box.left, width: box.width, height: box.height };
11719
+ const key = `${box.rowIndex}-${box.cellIndex}`;
11720
+ if (box.hidden) {
11721
+ // Drawn empty: the cell keeps its borders and background so the grid stays closed.
11722
+ return jsxRuntime.jsx("div", { className: styles$1.item, style: { ...frameCss(cellFrame, zoom), ...rdlBoxStyle(content.Style, zoom) } }, key);
11723
+ }
11724
+ return jsxRuntime.jsx(ReportItem, { item: content, itemKey: rdlCellKey(itemKey, box.rowIndex, box.cellIndex), frame: cellFrame }, key);
11725
+ }) }));
11726
+ }
11727
+ function ReportChart({ item, frame }) {
11728
+ const { zoom, culture } = useReportRender();
11729
+ const width = ptToPx(frame.width, zoom);
11730
+ const height = ptToPx(frame.height, zoom);
11731
+ const pie = item.Series[0]?.Type.toLowerCase() === "shape";
11732
+ return (jsxRuntime.jsx("div", { className: styles$1.chart, style: { ...frameCss(frame, zoom), ...rdlBoxStyle(item.Style, zoom) }, children: pie
11733
+ ? jsxRuntime.jsx(CwReportPieChart, { chart: item, width: width, height: height, zoom: zoom })
11734
+ : jsxRuntime.jsx(CwReportLineChart, { chart: item, width: width, height: height, zoom: zoom, culture: culture }) }));
11735
+ }
11736
+ function ReportGauge({ item, frame }) {
11737
+ const { zoom } = useReportRender();
11738
+ return (jsxRuntime.jsx("div", { className: styles$1.chart, style: { ...frameCss(frame, zoom), ...rdlBoxStyle(item.Style, zoom) }, children: jsxRuntime.jsx(CwReportGauge, { panel: item, width: ptToPx(frame.width, zoom), height: ptToPx(frame.height, zoom), zoom: zoom }) }));
11739
+ }
11740
+ function ReportPlaceholder({ item, frame }) {
11741
+ const { zoom } = useReportRender();
11742
+ return (jsxRuntime.jsx(CwTooltipNew, { content: `${item.Element}: ${item.Reason}`, position: "top", children: jsxRuntime.jsx("div", { className: styles$1.placeholder, style: frameCss(frame, zoom), "aria-label": `${item.Element}: ${item.Reason}`, children: item.Element }) }));
11743
+ }
11744
+ /** One render-tree item, absolutely positioned in its container; nothing when its toggles hide it. */
11745
+ function ReportItem({ item, itemKey, frame }) {
11746
+ const { zoom, flipped } = useReportRender();
11747
+ if (!isRdlVisible(item.Toggles, flipped))
11748
+ return null;
11749
+ const box = frame ?? frameOf(item);
11750
+ switch (item.Kind) {
11751
+ case "textbox": return jsxRuntime.jsx(ReportTextbox, { textbox: item, itemKey: itemKey, frameStyle: frameCss(box, zoom) });
11752
+ case "rectangle": return jsxRuntime.jsx(ReportRectangle, { item: item, itemKey: itemKey, frame: box });
11753
+ case "line": return jsxRuntime.jsx(ReportLine, { item: item, frame: box });
11754
+ case "image": return jsxRuntime.jsx(ReportImage, { item: item, frame: box });
11755
+ case "table": return jsxRuntime.jsx(ReportTable, { item: item, itemKey: itemKey, frame: box });
11756
+ case "chart": return jsxRuntime.jsx(ReportChart, { item: item, frame: box });
11757
+ case "gauge": return jsxRuntime.jsx(ReportGauge, { item: item, frame: box });
11758
+ case "placeholder": return jsxRuntime.jsx(ReportPlaceholder, { item: item, frame: box });
11759
+ default: return null;
11760
+ }
11761
+ }
11762
+ function ReportItems({ items, parentKey }) {
11763
+ return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: items.map((item, index) => (jsxRuntime.jsx(ReportItem, { item: item, itemKey: rdlItemKey(parentKey, index) }, index))) }));
11764
+ }
11765
+
11766
+ const NO_FLIPS$1 = new Set();
11767
+ const NO_MATCHES = [];
11768
+ const DEFAULT_MARGINS = {
11769
+ top: DEFAULT_PAGE_MARGIN_PT,
11770
+ right: DEFAULT_PAGE_MARGIN_PT,
11771
+ bottom: DEFAULT_PAGE_MARGIN_PT,
11772
+ left: DEFAULT_PAGE_MARGIN_PT
11773
+ };
11774
+ function Band({ section, sectionKey, zoom, bodyWidth, as: Element }) {
11775
+ return (jsxRuntime.jsx(Element, { className: styles$1.section, style: { ...rdlBoxStyle(section.Style, zoom), width: ptToPx(bodyWidth, zoom), height: ptToPx(section.Height, zoom) }, children: jsxRuntime.jsx(ReportItems, { items: section.Items, parentKey: sectionKey }) }));
11776
+ }
11777
+ /**
11778
+ * One page of a rendered RDL report drawn as a sheet of paper: page header, body and page footer,
11779
+ * every item absolutely positioned in points scaled by the zoom. Presentational: toggle state,
11780
+ * sorting, images and find matches come from the host.
11781
+ */
11782
+ function CwReportPage({ page, bodyWidth, zoom = 1, culture, margins = DEFAULT_MARGINS, flippedToggles = NO_FLIPS$1, onToggle, onSort, getImageUrl, findMatches = NO_MATCHES, activeMatchIndex = -1, className }) {
11783
+ const sheetRef = React.useRef(null);
11784
+ const highlights = React.useMemo(() => highlightsByRun(findMatches), [findMatches]);
11785
+ const context = React.useMemo(() => ({
11786
+ zoom,
11787
+ culture,
11788
+ flipped: flippedToggles,
11789
+ onToggle,
11790
+ onSort,
11791
+ getImageUrl,
11792
+ highlights,
11793
+ activeMatchIndex
11794
+ }), [zoom, culture, flippedToggles, onToggle, onSort, getImageUrl, highlights, activeMatchIndex]);
11795
+ React.useEffect(() => {
11796
+ if (activeMatchIndex < 0)
11797
+ return;
11798
+ const active = sheetRef.current?.querySelector("[data-active-match='true']");
11799
+ active?.scrollIntoView?.({ block: "center", inline: "nearest" });
11800
+ }, [activeMatchIndex, findMatches]);
11801
+ const sheet = pageSheetSizePt(page, bodyWidth, margins);
11802
+ return (jsxRuntime.jsx(ReportRenderContext.Provider, { value: context, children: jsxRuntime.jsxs("div", { ref: sheetRef, className: `${styles$1.sheet}${className ? ` ${className}` : ""}`, style: {
11803
+ width: ptToPx(sheet.width, zoom),
11804
+ height: ptToPx(sheet.height, zoom),
11805
+ padding: `${ptToPx(margins.top, zoom)}px ${ptToPx(margins.right, zoom)}px ${ptToPx(margins.bottom, zoom)}px ${ptToPx(margins.left, zoom)}px`
11806
+ }, "data-page": page.Number, children: [page.Header && jsxRuntime.jsx(Band, { section: page.Header, sectionKey: RDL_SECTION_KEYS.header, zoom: zoom, bodyWidth: bodyWidth, as: "header" }), jsxRuntime.jsx("div", { className: styles$1.section, style: { width: ptToPx(bodyWidth, zoom), height: ptToPx(page.Height, zoom) }, children: jsxRuntime.jsx(ReportItems, { items: page.Items, parentKey: RDL_SECTION_KEYS.body }) }), page.Footer && jsxRuntime.jsx(Band, { section: page.Footer, sectionKey: RDL_SECTION_KEYS.footer, zoom: zoom, bodyWidth: bodyWidth, as: "footer" })] }) }));
11807
+ }
11808
+
11809
+ const DATE_PREFIX = /^(\d{4}-\d{2}-\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2}))?)?/;
11810
+ /** Reads the date and time of an ISO 8601 text (any offset is ignored, the wall clock is kept). Null when it is not a date. */
11811
+ function parseRdlDateTime(text) {
11812
+ const match = DATE_PREFIX.exec(text.trim());
11813
+ if (!match)
11814
+ return null;
11815
+ try {
11816
+ return Temporal.PlainDateTime.from(`${match[1]}T${match[2] ?? "00"}:${match[3] ?? "00"}:${match[4] ?? "00"}`);
11817
+ }
11818
+ catch {
11819
+ return null;
11820
+ }
11821
+ }
11822
+ /** A date-time as invariant text "YYYY-MM-DDTHH:mm:ss". */
11823
+ function formatRdlDateTime(value) {
11824
+ return value.toString({ smallestUnit: "second", calendarName: "never" });
11825
+ }
11826
+ /** A typed API value as the text of an option or an editor (null stays null). */
11827
+ function rdlValueToText(value) {
11828
+ if (value === null || value === undefined)
11829
+ return null;
11830
+ if (typeof value === "boolean")
11831
+ return value ? "true" : "false";
11832
+ if (typeof value === "number")
11833
+ return numberToInvariant(value);
11834
+ return value;
11835
+ }
11836
+ function numberToInvariant(value) {
11837
+ return Number.isFinite(value) ? value.toString() : "";
11838
+ }
11839
+ function isDateTime(parameter) {
11840
+ return parameter.DataType.toLowerCase() === "datetime" || parameter.InputType.toLowerCase() === "datetime";
11841
+ }
11842
+ function isBoolean(parameter) {
11843
+ return parameter.DataType.toLowerCase() === "boolean" || parameter.InputType.toLowerCase() === "boolean";
11844
+ }
11845
+ function isTextInput(parameter) {
11846
+ return parameter.InputType.toLowerCase() === "textbox";
11847
+ }
11848
+ function isNumeric(parameter) {
11849
+ const type = parameter.DataType.toLowerCase();
11850
+ return type === "integer" || type === "float";
11851
+ }
11852
+ function toEditorScalar(parameter, value) {
11853
+ if (isDateTime(parameter) && parameter.InputType.toLowerCase() !== "dropdownlist") {
11854
+ const text = String(value);
11855
+ return parseRdlDateTime(text) ?? text;
11856
+ }
11857
+ if (isBoolean(parameter) && parameter.InputType.toLowerCase() !== "dropdownlist") {
11858
+ return typeof value === "boolean" ? value : String(value).toLowerCase() === "true";
11859
+ }
11860
+ return rdlValueToText(value) ?? "";
11861
+ }
11862
+ /** The editor state of one parameter from the values the server sent; a NULL value is an empty field. */
11863
+ function initialParameterEdit(parameter) {
11864
+ const scalars = (parameter.Values ?? [])
11865
+ .filter((value) => value !== null && value !== undefined)
11866
+ .map(value => toEditorScalar(parameter, value));
11867
+ return { values: parameter.MultiValue ? scalars : scalars.slice(0, 1) };
11868
+ }
11869
+ /** The values that count: a multi-value text drops its empty lines, a single value keeps only the first. */
11870
+ function enteredValues(parameter, edit) {
11871
+ const values = edit.values.filter(value => value !== "");
11872
+ return parameter.MultiValue ? values : values.slice(0, 1);
11873
+ }
11874
+ /** The editor state of a whole form. */
11875
+ function initialParameterEdits(parameters) {
11876
+ const edits = {};
11877
+ for (const parameter of parameters)
11878
+ edits[parameter.Name] = initialParameterEdit(parameter);
11879
+ return edits;
11880
+ }
11881
+ /** One editor value as invariant text. */
11882
+ function editorScalarToInvariant(parameter, value) {
11883
+ if (typeof value === "boolean")
11884
+ return value ? "true" : "false";
11885
+ if (typeof value !== "string")
11886
+ return formatRdlDateTime(value);
11887
+ if (isNumeric(parameter))
11888
+ return value.trim().replace(",", ".");
11889
+ return value;
11890
+ }
11891
+ /**
11892
+ * The values the API takes (RdlParameterValuesRequest.Values): every parameter, each as an array of
11893
+ * invariant text. An empty field is [null] when the parameter is nullable, [""] for a single text,
11894
+ * else []. A parameter without an edit sends the values the server gave it.
11895
+ *
11896
+ * A nullable boolean whose value is NULL shows neither True nor False and keeps sending NULL until
11897
+ * the user picks one; from then on it sends "true" / "false" (a radio group cannot be emptied again).
11898
+ */
11899
+ function toRdlParameterValues(parameters, edits) {
11900
+ const result = {};
11901
+ for (const parameter of parameters) {
11902
+ const edit = edits[parameter.Name] ?? initialParameterEdit(parameter);
11903
+ const texts = enteredValues(parameter, edit).map(value => editorScalarToInvariant(parameter, value));
11904
+ if (texts.length > 0) {
11905
+ result[parameter.Name] = texts;
11906
+ }
11907
+ else if (parameter.Nullable) {
11908
+ result[parameter.Name] = [null];
11909
+ }
11910
+ else {
11911
+ result[parameter.Name] = !parameter.MultiValue && isTextInput(parameter) ? [""] : [];
11912
+ }
11913
+ }
11914
+ return result;
11915
+ }
11916
+ /** True when any other parameter lists `name` in its DependsOn: a change must re-resolve the form. */
11917
+ function hasDependentParameters(parameters, name) {
11918
+ return parameters.some(parameter => parameter.Name !== name && parameter.DependsOn.includes(name));
11919
+ }
11920
+ /** Whether the user edits the parameter (hidden and server-filled parameters are not editable). */
11921
+ function isEditableParameter(parameter) {
11922
+ return !parameter.Hidden && !parameter.ServerValue;
11923
+ }
11924
+ /** Whether the form has anything for the user to fill in (some parameter is neither hidden nor server-filled). */
11925
+ function hasEditableParameters(parameters) {
11926
+ return parameters.some(isEditableParameter);
11927
+ }
11928
+ /**
11929
+ * Client-side checks before "View report": a value is required unless the parameter is nullable
11930
+ * (empty = NULL) or allows blank text (AllowBlank), and numbers / dates must parse. Hidden and
11931
+ * server-filled parameters are the server's business. Returns parameter name to message.
11932
+ */
11933
+ function validateParameterEdits(parameters, edits) {
11934
+ const errors = {};
11935
+ for (const parameter of parameters) {
11936
+ if (!isEditableParameter(parameter))
11937
+ continue;
11938
+ const edit = edits[parameter.Name] ?? initialParameterEdit(parameter);
11939
+ const values = enteredValues(parameter, edit);
11940
+ if (values.length === 0) {
11941
+ const blankAllowed = parameter.Nullable
11942
+ || (parameter.AllowBlank && !parameter.MultiValue && isTextInput(parameter) && !isNumeric(parameter));
11943
+ if (!blankAllowed)
11944
+ errors[parameter.Name] = parameter.MultiValue ? "Select at least one value." : "A value is required.";
11945
+ continue;
11946
+ }
11947
+ if (isNumeric(parameter) && parameter.InputType.toLowerCase() !== "dropdownlist") {
11948
+ const integer = parameter.DataType.toLowerCase() === "integer";
11949
+ const invalid = values.some(value => {
11950
+ const text = editorScalarToInvariant(parameter, value);
11951
+ return integer ? !/^-?\d+$/.test(text) : !/^-?(\d+\.?\d*|\.\d+)$/.test(text);
11952
+ });
11953
+ if (invalid)
11954
+ errors[parameter.Name] = integer ? "Enter a whole number." : "Enter a number.";
11955
+ continue;
11956
+ }
11957
+ if (isDateTime(parameter) && parameter.InputType.toLowerCase() !== "dropdownlist"
11958
+ && values.some(value => typeof value === "string")) {
11959
+ errors[parameter.Name] = "Enter a valid date.";
11960
+ }
11961
+ }
11962
+ return errors;
11963
+ }
11964
+
11965
+ var styles = {"viewer":"cw-report-viewer-module__viewer__SYHSE","sidebar":"cw-report-viewer-module__sidebar__1ZSM2","resizer":"cw-report-viewer-module__resizer__JdnQI","main":"cw-report-viewer-module__main__qsPXX","parameterForm":"cw-report-viewer-module__parameterForm__H01sS","parameterFields":"cw-report-viewer-module__parameterFields__D2BuK","parameterActions":"cw-report-viewer-module__parameterActions__01RD4","viewButton":"cw-report-viewer-module__viewButton__1CMHL","parameterGrid":"cw-report-viewer-module__parameterGrid__Jyn0M","toolbar":"cw-report-viewer-module__toolbar__9gKXV","reportName":"cw-report-viewer-module__reportName__g5nsm","findStatus":"cw-report-viewer-module__findStatus__4gLGb","warningsButton":"cw-report-viewer-module__warningsButton__GIKjH","warningsPanel":"cw-report-viewer-module__warningsPanel__rFHBP","warningList":"cw-report-viewer-module__warningList__Ouk7x","menu":"cw-report-viewer-module__menu__ufxUU","menuItem":"cw-report-viewer-module__menuItem__hBmdD","canvas":"cw-report-viewer-module__canvas__9KuUT","canvasNote":"cw-report-viewer-module__canvasNote__K9XP0","sheetSkeleton":"cw-report-viewer-module__sheetSkeleton__DsSaA","emptyState":"cw-report-viewer-module__emptyState__pJyQ1"};
11966
+
11967
+ /** Above this many options a single-select dropdown gets a search box. */
11968
+ const SEARCH_THRESHOLD = 10;
11969
+ const LABEL_LAYOUT = { flexDirection: "column" };
11970
+ const BOOLEAN_OPTIONS = [
11971
+ { value: "true", label: "True" },
11972
+ { value: "false", label: "False" }
11973
+ ];
11974
+ function scalarText(value) {
11975
+ if (value === undefined)
11976
+ return "";
11977
+ if (typeof value === "boolean")
11978
+ return value ? "true" : "false";
11979
+ return typeof value === "string" ? value : value.toString();
11980
+ }
11981
+ function feedbackFor(parameter, clientError) {
11982
+ const messages = [];
11983
+ if (parameter.ValidValuesError)
11984
+ messages.push({ type: "danger", message: parameter.ValidValuesError });
11985
+ if (parameter.ValueError)
11986
+ messages.push({ type: "danger", message: parameter.ValueError });
11987
+ if (clientError)
11988
+ messages.push({ type: "danger", message: clientError });
11989
+ return messages.length > 0 ? messages : undefined;
11990
+ }
11991
+ function ParameterField({ parameter, edit, error, disabled, setEdit, commit }) {
11992
+ const label = { text: parameter.Prompt || parameter.Name };
11993
+ const feedback = feedbackFor(parameter, error);
11994
+ const testId = `report-parameter-${parameter.Name}`;
11995
+ // A NULL valid value is no option of its own: leaving the field empty is NULL.
11996
+ const options = parameter.ValidValues
11997
+ .filter(option => option.Value !== null && option.Value !== undefined)
11998
+ .map(option => ({ value: rdlValueToText(option.Value) ?? "", label: option.Label }));
11999
+ switch (parameter.InputType.toLowerCase()) {
12000
+ case "dropdownlist":
12001
+ if (parameter.MultiValue) {
12002
+ return (jsxRuntime.jsx(CwTagSelector, { id: testId, labelProps: label, alignProps: LABEL_LAYOUT, options: options, value: edit.values.map(scalarText), onChange: values => setEdit({ values }, true), showSelectAll: true, disabled: disabled, feedback: feedback }));
12003
+ }
12004
+ return (jsxRuntime.jsx(CwDropdown, { "data-testid": testId, labelProps: label, alignProps: LABEL_LAYOUT, options: options, value: scalarText(edit.values[0]), onChange: value => setEdit({ values: value === undefined ? [] : [String(value)] }, true), allowSearch: options.length > SEARCH_THRESHOLD, disabled: disabled, feedback: feedback }));
12005
+ case "datetime": {
12006
+ const value = edit.values[0];
12007
+ return (jsxRuntime.jsx(CwDateTimePickerTemporal, { "data-testid": testId, labelProps: label, alignProps: LABEL_LAYOUT, value: value instanceof Temporal.PlainDateTime ? value : undefined, onChange: dateTime => setEdit({ values: dateTime ? [dateTime] : [] }, true), disabled: disabled, feedback: feedback }));
12008
+ }
12009
+ case "boolean":
12010
+ return (jsxRuntime.jsx(CwRadioGroup, { "data-testid": testId, labelProps: label, groupLayout: { direction: "row" }, options: BOOLEAN_OPTIONS, value: edit.values.length > 0 ? scalarText(edit.values[0]) : undefined, onChange: value => setEdit({ values: [value === "true"] }, true), disabled: disabled, feedback: feedback }));
12011
+ case "integer":
12012
+ case "float":
12013
+ return (jsxRuntime.jsx(CwDigit, { "data-testid": testId, labelProps: label, alignProps: LABEL_LAYOUT, step: parameter.InputType.toLowerCase() === "integer" ? 1 : "any", value: scalarText(edit.values[0]), onChange: e => {
12014
+ const text = e.currentTarget.value;
12015
+ setEdit({ values: text === "" ? [] : [text] }, false);
12016
+ }, onBlur: commit, disabled: disabled, feedback: feedback }));
12017
+ default:
12018
+ if (parameter.MultiValue) {
12019
+ return (jsxRuntime.jsx(CwTextArea, { "data-testid": testId, labelProps: label, alignProps: LABEL_LAYOUT, value: edit.values.map(scalarText).join("\n"), onChange: e => {
12020
+ // Keep empty lines while typing (Enter must survive the re-render); they are dropped on serialization.
12021
+ setEdit({ values: e.currentTarget.value.split("\n") }, false);
12022
+ }, onBlur: commit, disabled: disabled, feedback: feedback ?? { type: "neutral", message: "One value per line." } }));
12023
+ }
12024
+ return (jsxRuntime.jsx(CwInputText, { "data-testid": testId, labelProps: label, alignProps: LABEL_LAYOUT, value: scalarText(edit.values[0]), onChange: e => {
12025
+ const text = e.currentTarget.value;
12026
+ setEdit({ values: [text] }, false);
12027
+ }, onBlur: commit, disabled: disabled, feedback: feedback }));
12028
+ }
12029
+ }
12030
+ /**
12031
+ * The report parameter form in the server's order: dropdowns (multi-value as tag selector with
12032
+ * select-all), date-time pickers, True/False, numbers and text. There is no NULL control: an empty
12033
+ * field of a nullable parameter is sent as NULL (see rdlParameterValues), as in the old WinOps
12034
+ * report page. Hidden parameters are not drawn; server-filled ones are read-only. Presentational:
12035
+ * the host owns the editor state (`useReportParameterForm`); a change to a parameter others depend
12036
+ * on calls its `onResolve`, "View report" its `onRender` with the values as invariant text
12037
+ * (`toRdlParameterValues`).
12038
+ *
12039
+ * The form fills its parent's height when the parent gives it one: the fields scroll and the
12040
+ * "View report" footer stays pinned at the bottom. In an unbounded parent it simply grows.
12041
+ */
12042
+ function CwReportParameterForm({ controller, loading = false, rendering = false }) {
12043
+ const { form } = controller;
12044
+ const visible = form?.Parameters.filter(parameter => !parameter.Hidden) ?? [];
12045
+ return (jsxRuntime.jsxs("form", { className: styles.parameterForm, "data-testid": "report-parameter-form", onSubmit: e => {
12046
+ e.preventDefault();
12047
+ controller.submit();
12048
+ }, children: [jsxRuntime.jsx("div", { className: styles.parameterFields, children: form ? (jsxRuntime.jsx(CwLoading, { isLoading: loading, size: "small", children: visible.length > 0 && (jsxRuntime.jsx("div", { className: `${styles.parameterGrid} cw-grid-base-auto`, children: visible.map(parameter => (jsxRuntime.jsx(ParameterField, { parameter: parameter, edit: controller.edits[parameter.Name] ?? { values: [] }, error: controller.errors[parameter.Name], disabled: loading || !!parameter.ServerValue, setEdit: (edit, commit) => controller.setEdit(parameter.Name, edit, commit), commit: () => controller.commit(parameter.Name) }, parameter.Name))) })) })) : (jsxRuntime.jsxs("div", { className: `${styles.parameterGrid} cw-grid-base-auto`, "aria-busy": "true", children: [jsxRuntime.jsx(CwSkeleton, { variant: "rect", height: "3.5rem" }), jsxRuntime.jsx(CwSkeleton, { variant: "rect", height: "3.5rem" }), jsxRuntime.jsx(CwSkeleton, { variant: "rect", height: "3.5rem" })] })) }), jsxRuntime.jsx("footer", { className: styles.parameterActions, children: jsxRuntime.jsx(CwButton, { type: "submit", text: "View report", icon: "file-view", className: styles.viewButton, disabled: !form || loading || rendering, "data-testid": "report-view-button" }) })] }));
12049
+ }
12050
+
12051
+ const REPORT_EXPORT_LABELS = {
12052
+ pdf: "PDF",
12053
+ xlsx: "Excel",
12054
+ docx: "Word"
12055
+ };
12056
+ /** A render with warnings asks before exporting or printing; without warnings the action runs at once. */
12057
+ function needsOutputConfirmation(warnings) {
12058
+ return (warnings?.length ?? 0) > 0;
12059
+ }
12060
+ /** Texts of the confirmation shown before an export or print of a render with warnings. */
12061
+ function outputConfirmation(action, warningCount) {
12062
+ const count = `${warningCount} warning${warningCount === 1 ? "" : "s"}`;
12063
+ if (action.kind === "print") {
12064
+ return {
12065
+ headline: "Print report",
12066
+ message: `This report has ${count}. The printout may not match the report exactly.`,
12067
+ confirmText: "Print anyway"
12068
+ };
12069
+ }
12070
+ const label = REPORT_EXPORT_LABELS[action.format];
12071
+ return {
12072
+ headline: `Export as ${label}`,
12073
+ message: `This report has ${count}. The ${label} export may not match the report exactly.`,
12074
+ confirmText: "Export anyway"
12075
+ };
12076
+ }
12077
+
12078
+ const EXPORTS = [
12079
+ { format: "pdf", label: REPORT_EXPORT_LABELS.pdf, icon: "file-pdf" },
12080
+ { format: "xlsx", label: REPORT_EXPORT_LABELS.xlsx, icon: "table" },
12081
+ { format: "docx", label: REPORT_EXPORT_LABELS.docx, icon: "document" }
12082
+ ];
12083
+ function zoomToValue(zoom) {
12084
+ return typeof zoom === "number" ? String(zoom) : zoom;
12085
+ }
12086
+ function valueToZoom(value) {
12087
+ if (value === "pageWidth" || value === "wholePage")
12088
+ return value;
12089
+ const factor = parseFloat(value);
12090
+ return Number.isFinite(factor) && factor > 0 ? factor : 1;
12091
+ }
12092
+ function closePopover(element) {
12093
+ element.closest("[popover]")?.hidePopover();
12094
+ }
12095
+ function PageInput({ pageNumber, pageCount, onPage, disabled }) {
12096
+ const [draft, setDraft] = React.useState({ page: pageNumber, text: String(pageNumber) });
12097
+ const text = draft.page === pageNumber ? draft.text : String(pageNumber);
12098
+ const commit = () => {
12099
+ const parsed = parseInt(text, 10);
12100
+ const target = Number.isFinite(parsed) ? Math.min(Math.max(1, parsed), Math.max(1, pageCount)) : pageNumber;
12101
+ setDraft({ page: pageNumber, text: String(target) });
12102
+ if (target !== pageNumber)
12103
+ onPage(target);
12104
+ };
12105
+ return (jsxRuntime.jsx(CwDigit, { "data-size": "tiny", "aria-label": "Page", min: 1, max: Math.max(1, pageCount), value: text, disabled: disabled, onChange: e => {
12106
+ const value = e.currentTarget.value;
12107
+ setDraft({ page: pageNumber, text: value });
12108
+ }, onKeyDown: (e) => {
12109
+ if (e.key === "Enter")
12110
+ commit();
12111
+ }, onBlur: commit }));
12112
+ }
12113
+ /**
12114
+ * The report viewer toolbar, like the old ReportViewer: page navigation, refresh, back, zoom,
12115
+ * find on the current page, export (PDF / Excel / Word) and print. Warnings stay invisible until
12116
+ * there are some (Dark Cockpit). Presentational: every action is a callback.
12117
+ */
12118
+ function CwReportToolbar({ pageNumber, pageCount, onPage, onRefresh, onBack, zoom, onZoomChange, findText, onFindTextChange, onFindNext, findMatchCount, findMatchIndex, onExport, onPrint, warnings = [], onToggleParameters, parametersVisible = true, disabled = false, reportName }) {
12119
+ const firstPage = disabled || pageNumber <= 1;
12120
+ const lastPage = disabled || pageNumber >= pageCount;
12121
+ const findStatus = findText.trim() === ""
12122
+ ? ""
12123
+ : findMatchCount === 0 ? "No matches" : `${Math.max(0, findMatchIndex) + 1} of ${findMatchCount}`;
12124
+ return (jsxRuntime.jsxs("header", { className: `${styles.toolbar} cw-flex-row cw-align-left-center cw-flex-wrap cw-gap-small`, "data-testid": "report-toolbar", children: [onBack && jsxRuntime.jsx(CwButton, { variant: "icon", icon: "arrow-left", title: "Back", onClick: onBack }), onToggleParameters && (jsxRuntime.jsx(CwButton, { variant: "icon", icon: "filter-list", title: parametersVisible ? "Hide parameters" : "Show parameters", pressed: parametersVisible, onClick: onToggleParameters })), jsxRuntime.jsxs("nav", { className: "cw-flex-row cw-align-left-center cw-gap-tiny", "aria-label": "Pages", children: [jsxRuntime.jsx(CwButton, { variant: "icon", icon: "chevron-left-double", title: "First page", disabled: firstPage, onClick: () => onPage(1) }), jsxRuntime.jsx(CwButton, { variant: "icon", icon: "chevron-left", title: "Previous page", disabled: firstPage, onClick: () => onPage(pageNumber - 1) }), jsxRuntime.jsx(PageInput, { pageNumber: pageNumber, pageCount: pageCount, onPage: onPage, disabled: disabled }), jsxRuntime.jsxs("span", { className: "cw-font-size-small", children: ["of ", disabled ? "-" : pageCount] }), jsxRuntime.jsx(CwButton, { variant: "icon", icon: "chevron-right", title: "Next page", disabled: lastPage, onClick: () => onPage(pageNumber + 1) }), jsxRuntime.jsx(CwButton, { variant: "icon", icon: "chevron-right-double", title: "Last page", disabled: lastPage, onClick: () => onPage(pageCount) })] }), onRefresh && jsxRuntime.jsx(CwButton, { variant: "icon", icon: "refresh", title: "Refresh", disabled: disabled, onClick: onRefresh }), jsxRuntime.jsxs(CwSelect, { "aria-label": "Zoom", value: zoomToValue(zoom), handleChange: value => onZoomChange(valueToZoom(value)), children: [REPORT_ZOOM_STEPS.map(step => (jsxRuntime.jsx(CwOption, { value: String(step), text: `${Math.round(step * 100)}%` }, step))), jsxRuntime.jsx(CwOption, { value: "pageWidth", text: "Page width" }), jsxRuntime.jsx(CwOption, { value: "wholePage", text: "Whole page" })] }), jsxRuntime.jsxs("div", { className: "cw-flex-row cw-align-left-center cw-gap-small", children: [jsxRuntime.jsx(CwInputText, { "aria-label": "Find text", placeholder: "Find", value: findText, disabled: disabled, onChange: e => onFindTextChange(e.currentTarget.value), onKeyDown: (e) => {
12125
+ if (e.key === "Enter")
12126
+ onFindNext();
12127
+ }, buttonProps: {
12128
+ text: "Next",
12129
+ variant: "outline",
12130
+ disabled: disabled || findMatchCount === 0,
12131
+ onClick: onFindNext
12132
+ } }), jsxRuntime.jsx("span", { className: `${styles.findStatus} cw-font-size-small`, "aria-live": "polite", children: findStatus })] }), jsxRuntime.jsx("div", { className: styles.reportName, children: reportName && (jsxRuntime.jsx(CwTooltipNew, { content: reportName, position: "bottom", children: jsxRuntime.jsx("strong", { className: "cw-text-ellipsis", "data-testid": "report-name", children: reportName }) })) }), warnings.length > 0 && (jsxRuntime.jsx(CwPopoverButton, { variant: "icon", icon: "warning", title: "Warnings", badge: { count: warnings.length, color: "warning" }, className: styles.warningsButton, placement: "bottom-end", panelClassName: styles.warningsPanel, children: jsxRuntime.jsx("ul", { className: styles.warningList, children: warnings.map((warning, index) => jsxRuntime.jsx("li", { children: warning }, index)) }) })), jsxRuntime.jsx(CwPopoverButton, { icon: "download", title: "Export", variant: "icon", disabled: disabled, placement: "bottom-end", children: jsxRuntime.jsx("div", { className: styles.menu, children: EXPORTS.map(item => (jsxRuntime.jsx(CwButton, { variant: "ghost", color: "neutral", text: item.label, icon: item.icon, className: styles.menuItem, onClick: e => {
12133
+ closePopover(e.currentTarget);
12134
+ onExport(item.format);
12135
+ } }, item.format))) }) }), jsxRuntime.jsx(CwButton, { variant: "icon", icon: "print", title: "Print", disabled: disabled, onClick: onPrint })] }));
12136
+ }
12137
+
12138
+ /** Width change of one arrow key press on the sidebar resize handle, in CSS pixels. */
12139
+ const SIDEBAR_KEY_STEP = 16;
12140
+ /** Keeps a sidebar width inside [min, max]; a max below min collapses to min. */
12141
+ function clampSidebarWidth(width, min, max) {
12142
+ const upper = Math.max(min, max);
12143
+ if (!Number.isFinite(width))
12144
+ return min;
12145
+ return Math.min(Math.max(width, min), upper);
12146
+ }
12147
+ /**
12148
+ * The sidebar width after a key press on the resize handle: arrows step, Home / End jump to the
12149
+ * bounds. Null for keys the handle does not use, so they keep their default behaviour.
12150
+ */
12151
+ function sidebarWidthForKey(key, current, min, max, step = SIDEBAR_KEY_STEP) {
12152
+ switch (key) {
12153
+ case "ArrowLeft":
12154
+ return clampSidebarWidth(current - step, min, max);
12155
+ case "ArrowRight":
12156
+ return clampSidebarWidth(current + step, min, max);
12157
+ case "Home":
12158
+ return clampSidebarWidth(min, min, max);
12159
+ case "End":
12160
+ return clampSidebarWidth(max, min, max);
12161
+ default:
12162
+ return null;
12163
+ }
12164
+ }
12165
+ /**
12166
+ * Whether the viewer shows the parameter sidebar. While the form loads for the first time it shows
12167
+ * the skeleton; once loaded only when the user has something to fill in. A report whose parameters
12168
+ * are all hidden or server-filled (or that has none) gets no sidebar.
12169
+ */
12170
+ function showsParameterSidebar(parameters, loadingParameters) {
12171
+ return parameters ? hasEditableParameters(parameters.Parameters) : loadingParameters;
12172
+ }
12173
+
12174
+ /**
12175
+ * Width of a left sidebar resized by dragging the handle on its right edge, like the master panel
12176
+ * of CwMasterDetail. The handle captures the pointer, so the drag keeps going outside it; the
12177
+ * keyboard steps the width for users who cannot drag.
12178
+ */
12179
+ function useSidebarResize(initialWidth, minWidth, maxWidth) {
12180
+ const [storedWidth, setStoredWidth] = React.useState(initialWidth);
12181
+ const [resizing, setResizing] = React.useState(false);
12182
+ const drag = React.useRef(null);
12183
+ const width = clampSidebarWidth(storedWidth, minWidth, maxWidth);
12184
+ const onPointerDown = React.useCallback((e) => {
12185
+ if (e.button !== 0)
12186
+ return;
12187
+ e.preventDefault();
12188
+ e.currentTarget.setPointerCapture(e.pointerId);
12189
+ drag.current = { startX: e.clientX, startWidth: width };
12190
+ setResizing(true);
12191
+ }, [width]);
12192
+ const onPointerMove = React.useCallback((e) => {
12193
+ const start = drag.current;
12194
+ if (!start)
12195
+ return;
12196
+ setStoredWidth(clampSidebarWidth(start.startWidth + e.clientX - start.startX, minWidth, maxWidth));
12197
+ }, [minWidth, maxWidth]);
12198
+ const endDrag = React.useCallback((e) => {
12199
+ if (!drag.current)
12200
+ return;
12201
+ drag.current = null;
12202
+ if (e.currentTarget.hasPointerCapture(e.pointerId))
12203
+ e.currentTarget.releasePointerCapture(e.pointerId);
12204
+ setResizing(false);
12205
+ }, []);
12206
+ const onKeyDown = React.useCallback((e) => {
12207
+ const next = sidebarWidthForKey(e.key, width, minWidth, maxWidth);
12208
+ if (next === null)
12209
+ return;
12210
+ e.preventDefault();
12211
+ setStoredWidth(next);
12212
+ }, [width, minWidth, maxWidth]);
12213
+ return {
12214
+ width,
12215
+ resizing,
12216
+ handleProps: { onPointerDown, onPointerMove, onPointerUp: endDrag, onPointerCancel: endDrag, onKeyDown }
12217
+ };
12218
+ }
12219
+
12220
+ /** Space the canvas keeps around the sheet when fitting it (its padding on both sides), in CSS pixels. */
12221
+ const CANVAS_GUTTER = 32;
12222
+ function useElementSize(ref) {
12223
+ const [size, setSize] = React.useState({ width: 0, height: 0 });
12224
+ React.useEffect(() => {
12225
+ const element = ref.current;
12226
+ if (!element || typeof ResizeObserver === "undefined")
12227
+ return;
12228
+ const observer = new ResizeObserver(() => {
12229
+ setSize({ width: element.clientWidth, height: element.clientHeight });
12230
+ });
12231
+ observer.observe(element);
12232
+ return () => observer.disconnect();
12233
+ }, [ref]);
12234
+ return size;
12235
+ }
12236
+ /**
12237
+ * The RDL report viewer: a resizable, collapsible parameter sidebar on the left, the toolbar and
12238
+ * the page on a neutral canvas on the right, like the old ReportViewer. The sidebar only exists
12239
+ * when the user has a parameter to fill in. Presentational: it fetches nothing and owns no report
12240
+ * state. The host calls `useReportViewerState` and `useReportParameterForm` and passes their results
12241
+ * as `state` and `parameterForm`; every request goes out through the callbacks given to those hooks
12242
+ * (or `onSort` / `onRefresh` / `onBack`) and comes back as their arguments.
12243
+ */
12244
+ function CwReportViewer({ definition, state, parameterForm, loadingParameters = false, loadingRender = false, error, onSort, onRefresh, onBack, getImageUrl, sidebarWidth = 320, minSidebarWidth = 240, maxSidebarWidth = 600, resizable = true, className }) {
12245
+ const { result } = state;
12246
+ const parameters = parameterForm.form;
12247
+ const sidebar = useSidebarResize(sidebarWidth, minSidebarWidth, maxSidebarWidth);
12248
+ const canvasRef = React.useRef(null);
12249
+ const canvasSize = useElementSize(canvasRef);
12250
+ const hasSidebar = showsParameterSidebar(parameters, loadingParameters);
12251
+ const sidebarOpen = hasSidebar && state.parametersVisible;
12252
+ const warnings = result?.Warnings ?? [];
12253
+ const reportName = result?.Name || definition?.Name || null;
12254
+ const confirmation = state.pendingOutput ? outputConfirmation(state.pendingOutput, warnings.length) : null;
12255
+ /** Where the clicked toggle sat in the canvas, so the re-rendered page keeps it in the same place. */
12256
+ const toggleAnchorRef = React.useRef(null);
12257
+ const handleToggle = (toggleId) => {
12258
+ if (state.serverToggles) {
12259
+ const canvas = canvasRef.current;
12260
+ const button = canvas?.querySelector(`[data-toggle-id="${CSS.escape(toggleId)}"]`);
12261
+ toggleAnchorRef.current = canvas && button
12262
+ ? { toggleId, offset: button.getBoundingClientRect().top - canvas.getBoundingClientRect().top }
12263
+ : null;
12264
+ }
12265
+ state.toggle(toggleId);
12266
+ };
12267
+ React.useLayoutEffect(() => {
12268
+ const anchor = toggleAnchorRef.current;
12269
+ const canvas = canvasRef.current;
12270
+ if (!anchor || !canvas || !result)
12271
+ return;
12272
+ toggleAnchorRef.current = null;
12273
+ const button = canvas.querySelector(`[data-toggle-id="${CSS.escape(anchor.toggleId)}"]`);
12274
+ if (button)
12275
+ canvas.scrollTop += button.getBoundingClientRect().top - canvas.getBoundingClientRect().top - anchor.offset;
12276
+ }, [result]);
12277
+ // Without a sidebar (nothing to fill in) the form's "View report" lives on the canvas instead.
12278
+ const runButton = !hasSidebar && parameters && !result ? (jsxRuntime.jsx(CwButton, { text: "View report", icon: "file-view", disabled: loadingParameters || loadingRender, onClick: parameterForm.submit, "data-testid": "report-view-button" })) : null;
12279
+ const zoomFactor = result
12280
+ ? resolveZoomFactor(state.zoom, pageSheetSizePt(result.Page, result.BodyWidth, SCREEN_PAGE_MARGINS), { width: canvasSize.width - CANVAS_GUTTER, height: canvasSize.height - CANVAS_GUTTER })
12281
+ : 1;
12282
+ const renderCanvas = () => {
12283
+ if (error) {
12284
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(CwNote, { color: "danger", variant: "soft", icon: "warning", content: error, className: styles.canvasNote }), runButton] }));
12285
+ }
12286
+ if (!result) {
12287
+ if (loadingRender) {
12288
+ return (jsxRuntime.jsx("div", { className: styles.sheetSkeleton, "aria-busy": "true", children: jsxRuntime.jsx(CwSkeleton, { variant: "text", count: 14 }) }));
12289
+ }
12290
+ return (jsxRuntime.jsxs("div", { className: `${styles.emptyState} cw-flex-column cw-align-center-center cw-gap-small`, children: [jsxRuntime.jsx(CwIcon, { iconId: "file-report", size: "huge", color: "neutral" }), jsxRuntime.jsx("p", { className: "cw-margin-none", children: hasSidebar ? "Set the parameters and select View report." : "Select View report to run the report." }), runButton] }));
12291
+ }
12292
+ return (jsxRuntime.jsx(CwLoading, { isLoading: loadingRender, children: jsxRuntime.jsx(CwReportPage, { page: result.Page, bodyWidth: result.BodyWidth, zoom: zoomFactor, culture: result.Culture, margins: SCREEN_PAGE_MARGINS, flippedToggles: state.drawnFlips, onToggle: handleToggle, onSort: onSort, getImageUrl: getImageUrl, findMatches: state.findMatches, activeMatchIndex: state.findIndex }) }));
12293
+ };
12294
+ return (jsxRuntime.jsxs("section", { className: `${styles.viewer}${className ? ` ${className}` : ""}`, "aria-label": result?.Name ?? definition?.Name ?? "Report", "data-resizing": sidebar.resizing || undefined, "data-testid": "report-viewer", children: [sidebarOpen && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("aside", { className: styles.sidebar, style: { width: sidebar.width }, "aria-label": "Report parameters", "data-testid": "report-parameter-sidebar", children: jsxRuntime.jsx(CwReportParameterForm, { controller: parameterForm, loading: loadingParameters, rendering: loadingRender }) }), resizable && (jsxRuntime.jsx("div", { className: styles.resizer, role: "separator", "aria-orientation": "vertical", "aria-label": "Resize parameters", "aria-valuenow": sidebar.width, "aria-valuemin": minSidebarWidth, "aria-valuemax": Math.max(minSidebarWidth, maxSidebarWidth), tabIndex: 0, "data-resizing": sidebar.resizing, ...sidebar.handleProps }))] })), jsxRuntime.jsxs("div", { className: styles.main, children: [jsxRuntime.jsx(CwReportToolbar, { pageNumber: result?.Page.Number ?? 1, pageCount: result?.PageCount ?? 1, onPage: state.goToPage, onRefresh: onRefresh, onBack: onBack, zoom: state.zoom, onZoomChange: state.setZoom, findText: state.findText, onFindTextChange: state.setFindText, onFindNext: state.findNext, findMatchCount: state.findMatches.length, findMatchIndex: state.findIndex, onExport: format => state.requestOutput({ kind: "export", format }), onPrint: () => state.requestOutput({ kind: "print" }), warnings: warnings, reportName: reportName, onToggleParameters: hasSidebar ? state.toggleParameters : undefined, parametersVisible: state.parametersVisible, disabled: !result || loadingRender || !!error }), jsxRuntime.jsx("div", { ref: canvasRef, className: styles.canvas, "data-testid": "report-canvas", children: renderCanvas() })] }), confirmation && (jsxRuntime.jsx(CwDialog, { open: true, headline: confirmation.headline, width: "28rem", onClose: state.cancelOutput, customFooter: [
12295
+ jsxRuntime.jsx(CwButton, { text: "Cancel", variant: "outline", onClick: state.cancelOutput }, "cancel"),
12296
+ jsxRuntime.jsx(CwButton, { text: confirmation.confirmText, onClick: state.confirmOutput, "data-testid": "report-output-confirm" }, "confirm")
12297
+ ], "data-testid": "report-output-dialog", children: jsxRuntime.jsx("p", { className: "cw-margin-none", children: confirmation.message }) })), state.permissionDialogOpen && (jsxRuntime.jsx(CwDialog, { open: true, headline: "SQL ERROR", width: "30rem", onClose: state.closePermissionDialog, customFooter: [jsxRuntime.jsx(CwButton, { text: "OK", onClick: state.closePermissionDialog }, "ok")], "data-testid": "report-permission-dialog", children: jsxRuntime.jsx("p", { className: "cw-margin-none", children: "You do not have the database permission this report needs, so some of its data could not be read. Ask an administrator to grant access to the report data." }) }))] }));
12298
+ }
12299
+
12300
+ const NO_FLIPS = new Set();
12301
+ /**
12302
+ * Client-side state of the report viewer around one render result, owned by the host and handed to
12303
+ * `CwReportViewer` as `state`. The drilldown toggles belong to a render: a new RenderId (new render,
12304
+ * sort) starts with none flipped, paging and server views of the same render keep them. With
12305
+ * `onView` the host re-renders the page for the flipped toggles, so the page and find use it as drawn
12306
+ * (`drawnFlips` = none). The find position belongs to the query and the page shown. The permission
12307
+ * dialog is dismissed per render, and a pending export / print question is dropped by a new render.
12308
+ */
12309
+ function useReportViewerState(result, options) {
12310
+ const { onPage, onView, onExport, onPrint, initialZoom = 1 } = options;
12311
+ const renderId = result?.RenderId ?? null;
12312
+ const page = result?.Page ?? null;
12313
+ const pageNumber = page?.Number ?? 1;
12314
+ const warnings = result?.Warnings;
12315
+ const serverToggles = !!onView;
12316
+ const [zoom, setZoom] = React.useState(initialZoom);
12317
+ const [toggles, setToggles] = React.useState({ renderId: null, flipped: NO_FLIPS });
12318
+ const [findText, setFindText] = React.useState("");
12319
+ const [find, setFind] = React.useState({ key: "", index: 0 });
12320
+ const [parametersVisible, setParametersVisible] = React.useState(true);
12321
+ const [dismissedRenderId, setDismissedRenderId] = React.useState(null);
12322
+ const [output, setOutput] = React.useState(null);
12323
+ const flipped = toggles.renderId === renderId ? toggles.flipped : NO_FLIPS;
12324
+ const toggle = React.useCallback((toggleId) => {
12325
+ setToggles(previous => ({
12326
+ renderId,
12327
+ flipped: flipToggle(previous.renderId === renderId ? previous.flipped : NO_FLIPS, toggleId)
12328
+ }));
12329
+ if (onView)
12330
+ onView(toggledIds(flipped, toggleId), pageNumber);
12331
+ }, [renderId, onView, flipped, pageNumber]);
12332
+ const setFlipped = React.useCallback((toggleIds) => {
12333
+ setToggles({ renderId, flipped: new Set(toggleIds) });
12334
+ }, [renderId]);
12335
+ const goToPage = React.useCallback((target) => {
12336
+ if (onView && flipped.size > 0) {
12337
+ onView(flippedToggleIds(flipped), target);
12338
+ }
12339
+ else {
12340
+ onPage(target);
12341
+ }
12342
+ }, [onView, onPage, flipped]);
12343
+ // With server toggles the page arrives already drawn for the flipped toggles, so nothing is flipped again here.
12344
+ const drawnFlips = serverToggles ? NO_FLIPS : flipped;
12345
+ const findMatches = React.useMemo(() => (page ? findInPage(page, findText, drawnFlips) : []), [page, findText, drawnFlips]);
12346
+ const findKey = `${renderId ?? ""}|${page?.Number ?? 0}|${findText}`;
12347
+ const findIndex = activeMatchIndex(find.index, find.key === findKey, findMatches.length);
12348
+ const findNext = React.useCallback(() => {
12349
+ setFind({ key: findKey, index: nextMatchIndex(findIndex, findMatches.length) });
12350
+ }, [findKey, findIndex, findMatches.length]);
12351
+ const toggleParameters = React.useCallback(() => setParametersVisible(visible => !visible), []);
12352
+ const closePermissionDialog = React.useCallback(() => setDismissedRenderId(renderId), [renderId]);
12353
+ // A new render (refresh, sort) drops a question asked about the previous one.
12354
+ const pendingOutput = output && output.renderId === renderId ? output.action : null;
12355
+ const runOutput = React.useCallback((action) => {
12356
+ const toggleIds = flippedToggleIds(flipped);
12357
+ if (action.kind === "print") {
12358
+ onPrint(toggleIds);
12359
+ }
12360
+ else {
12361
+ onExport(action.format, toggleIds);
12362
+ }
12363
+ }, [flipped, onPrint, onExport]);
12364
+ const requestOutput = React.useCallback((action) => {
12365
+ if (needsOutputConfirmation(warnings)) {
12366
+ setOutput({ renderId, action });
12367
+ }
12368
+ else {
12369
+ runOutput(action);
12370
+ }
12371
+ }, [warnings, renderId, runOutput]);
12372
+ const confirmOutput = React.useCallback(() => {
12373
+ setOutput(null);
12374
+ if (pendingOutput)
12375
+ runOutput(pendingOutput);
12376
+ }, [pendingOutput, runOutput]);
12377
+ const cancelOutput = React.useCallback(() => setOutput(null), []);
12378
+ return {
12379
+ result,
12380
+ serverToggles,
12381
+ zoom,
12382
+ setZoom,
12383
+ flipped,
12384
+ drawnFlips,
12385
+ toggle,
12386
+ setFlipped,
12387
+ goToPage,
12388
+ findText,
12389
+ setFindText,
12390
+ findMatches,
12391
+ findIndex,
12392
+ findNext,
12393
+ parametersVisible,
12394
+ toggleParameters,
12395
+ permissionDialogOpen: !!result?.PermissionDenied && dismissedRenderId !== renderId,
12396
+ closePermissionDialog,
12397
+ pendingOutput,
12398
+ requestOutput,
12399
+ confirmOutput,
12400
+ cancelOutput
12401
+ };
12402
+ }
12403
+
12404
+ function stateFor(form) {
12405
+ return { source: form, edits: initialParameterEdits(form?.Parameters ?? []), pending: new Set(), showErrors: false };
12406
+ }
12407
+ /**
12408
+ * Editor state of the report parameter form, owned by the host and handed to `CwReportParameterForm`
12409
+ * as `controller`. A new form object from the host (after a resolve) resets the editors to the values
12410
+ * it carries; the server echoes the submitted values, so nothing is lost.
12411
+ */
12412
+ function useReportParameterForm(form, options) {
12413
+ const { onResolve, onRender } = options;
12414
+ const [state, setState] = React.useState(() => stateFor(form));
12415
+ const current = state.source === form ? state : stateFor(form);
12416
+ if (current !== state)
12417
+ setState(current);
12418
+ const parameters = form?.Parameters ?? [];
12419
+ const setEdit = React.useCallback((name, edit, commit) => {
12420
+ const params = form?.Parameters ?? [];
12421
+ const edits = { ...current.edits, [name]: edit };
12422
+ const pending = new Set(current.pending);
12423
+ if (commit) {
12424
+ pending.delete(name);
12425
+ }
12426
+ else {
12427
+ pending.add(name);
12428
+ }
12429
+ setState({ ...current, edits, pending });
12430
+ if (commit && hasDependentParameters(params, name))
12431
+ onResolve(toRdlParameterValues(params, edits));
12432
+ }, [current, form, onResolve]);
12433
+ const commit = React.useCallback((name) => {
12434
+ if (!current.pending.has(name))
12435
+ return;
12436
+ const params = form?.Parameters ?? [];
12437
+ const pending = new Set(current.pending);
12438
+ pending.delete(name);
12439
+ setState({ ...current, pending });
12440
+ if (hasDependentParameters(params, name))
12441
+ onResolve(toRdlParameterValues(params, current.edits));
12442
+ }, [current, form, onResolve]);
12443
+ const submit = React.useCallback(() => {
12444
+ const params = form?.Parameters ?? [];
12445
+ const errors = validateParameterEdits(params, current.edits);
12446
+ if (Object.keys(errors).length > 0) {
12447
+ setState({ ...current, showErrors: true });
12448
+ return;
12449
+ }
12450
+ onRender(toRdlParameterValues(params, current.edits));
12451
+ }, [current, form, onRender]);
12452
+ return {
12453
+ form,
12454
+ edits: current.edits,
12455
+ errors: current.showErrors ? validateParameterEdits(parameters, current.edits) : {},
12456
+ setEdit,
12457
+ commit,
12458
+ submit
12459
+ };
12460
+ }
12461
+
10144
12462
  /**
10145
12463
  * API-backed airport search input for WinOps.
10146
12464
  *
@@ -10644,7 +12962,14 @@ exports.CwOption = CwOption;
10644
12962
  exports.CwPopoverButton = CwPopoverButton;
10645
12963
  exports.CwProgress = CwProgress;
10646
12964
  exports.CwRadioGroup = CwRadioGroup;
12965
+ exports.CwReportGauge = CwReportGauge;
12966
+ exports.CwReportLineChart = CwReportLineChart;
10647
12967
  exports.CwReportModal = CwReportModal;
12968
+ exports.CwReportPage = CwReportPage;
12969
+ exports.CwReportParameterForm = CwReportParameterForm;
12970
+ exports.CwReportPieChart = CwReportPieChart;
12971
+ exports.CwReportToolbar = CwReportToolbar;
12972
+ exports.CwReportViewer = CwReportViewer;
10648
12973
  exports.CwSearchAsync = CwSearchAsync;
10649
12974
  exports.CwSearchInput = CwSearchInput;
10650
12975
  exports.CwSelect = CwSelect;
@@ -10690,6 +13015,7 @@ exports.OnStartClickHeaderEvent = OnStartClickHeaderEvent;
10690
13015
  exports.OnUnpinRow = OnUnpinRow;
10691
13016
  exports.PRESET_LIBRARY_TEMPORAL = PRESET_LIBRARY_TEMPORAL;
10692
13017
  exports.PinRowHeader = PinRowHeader;
13018
+ exports.REPORT_ZOOM_STEPS = REPORT_ZOOM_STEPS;
10693
13019
  exports.Scheduler = Scheduler;
10694
13020
  exports.SchedulerEvent = SchedulerEvent;
10695
13021
  exports.SuperScheduler = SuperScheduler;
@@ -10700,13 +13026,20 @@ exports.configureCwLoading = configureCwLoading;
10700
13026
  exports.eventIsVisible = eventIsVisible;
10701
13027
  exports.filterNavItems = filterNavItems;
10702
13028
  exports.filterVisibleEvents = filterVisibleEvents;
13029
+ exports.findInPage = findInPage;
13030
+ exports.flipToggle = flipToggle;
10703
13031
  exports.getCwLoadingDefaults = getCwLoadingDefaults;
10704
13032
  exports.getDefaultDivisions = getDefaultDivisions;
10705
13033
  exports.getEventSizes = getEventSizes;
10706
13034
  exports.getPresetsByKeysTemporal = getPresetsByKeysTemporal;
13035
+ exports.initialParameterEdits = initialParameterEdits;
13036
+ exports.isRdlVisible = isRdlVisible;
10707
13037
  exports.itemsToMultiFilterTags = itemsToMultiFilterTags;
10708
13038
  exports.sortNavItems = sortNavItems;
13039
+ exports.toRdlParameterValues = toRdlParameterValues;
10709
13040
  exports.useCwMessage = useCwMessage;
13041
+ exports.useReportParameterForm = useReportParameterForm;
13042
+ exports.useReportViewerState = useReportViewerState;
10710
13043
  exports.useSortableList = useSortableList;
10711
13044
  exports.useSortableTable = useSortableTable;
10712
13045
  exports.useTooltipConstraint = useTooltipConstraint;