hazo_ui 3.5.0 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -42,7 +42,7 @@ var Link = require('@tiptap/extension-link');
42
42
  var TextAlign = require('@tiptap/extension-text-align');
43
43
  var Highlight = require('@tiptap/extension-highlight');
44
44
  var Color = require('@tiptap/extension-color');
45
- var Image = require('@tiptap/extension-image');
45
+ var Image2 = require('@tiptap/extension-image');
46
46
  var Placeholder = require('@tiptap/extension-placeholder');
47
47
  var HorizontalRule = require('@tiptap/extension-horizontal-rule');
48
48
  var extensionTable = require('@tiptap/extension-table');
@@ -61,6 +61,8 @@ require('@uiw/react-markdown-preview/markdown.css');
61
61
  var Suggestion = require('@tiptap/suggestion');
62
62
  var state = require('@tiptap/pm/state');
63
63
  var reactDom = require('react-dom');
64
+ var Cropper = require('react-easy-crop');
65
+ var SliderPrimitive = require('@radix-ui/react-slider');
64
66
  var vaul = require('vaul');
65
67
  var AccordionPrimitive = require('@radix-ui/react-accordion');
66
68
  var CheckboxPrimitive = require('@radix-ui/react-checkbox');
@@ -122,7 +124,7 @@ var Link__default = /*#__PURE__*/_interopDefault(Link);
122
124
  var TextAlign__default = /*#__PURE__*/_interopDefault(TextAlign);
123
125
  var Highlight__default = /*#__PURE__*/_interopDefault(Highlight);
124
126
  var Color__default = /*#__PURE__*/_interopDefault(Color);
125
- var Image__default = /*#__PURE__*/_interopDefault(Image);
127
+ var Image2__default = /*#__PURE__*/_interopDefault(Image2);
126
128
  var Placeholder__default = /*#__PURE__*/_interopDefault(Placeholder);
127
129
  var HorizontalRule__default = /*#__PURE__*/_interopDefault(HorizontalRule);
128
130
  var TableRow__default = /*#__PURE__*/_interopDefault(TableRow);
@@ -132,6 +134,8 @@ var TaskList__default = /*#__PURE__*/_interopDefault(TaskList);
132
134
  var TaskItem__default = /*#__PURE__*/_interopDefault(TaskItem);
133
135
  var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
134
136
  var Suggestion__default = /*#__PURE__*/_interopDefault(Suggestion);
137
+ var Cropper__default = /*#__PURE__*/_interopDefault(Cropper);
138
+ var SliderPrimitive__namespace = /*#__PURE__*/_interopNamespace(SliderPrimitive);
135
139
  var AccordionPrimitive__namespace = /*#__PURE__*/_interopNamespace(AccordionPrimitive);
136
140
  var CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespace(CheckboxPrimitive);
137
141
  var DropdownMenuPrimitive__namespace = /*#__PURE__*/_interopNamespace(DropdownMenuPrimitive);
@@ -4364,7 +4368,7 @@ var HazoUiRte = ({
4364
4368
  multicolor: true
4365
4369
  }),
4366
4370
  Color__default.default,
4367
- Image__default.default.configure({
4371
+ Image2__default.default.configure({
4368
4372
  inline: true,
4369
4373
  allowBase64: true,
4370
4374
  HTMLAttributes: {
@@ -6912,6 +6916,210 @@ function HazoUiConfirmDialog({
6912
6916
  )
6913
6917
  ] }) });
6914
6918
  }
6919
+ var Slider = React26__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
6920
+ SliderPrimitive__namespace.Root,
6921
+ {
6922
+ ref,
6923
+ className: cn("relative flex w-full touch-none select-none items-center", className),
6924
+ ...props,
6925
+ children: [
6926
+ /* @__PURE__ */ jsxRuntime.jsx(SliderPrimitive__namespace.Track, { className: "relative h-2 w-full grow overflow-hidden rounded-full bg-secondary", children: /* @__PURE__ */ jsxRuntime.jsx(SliderPrimitive__namespace.Range, { className: "absolute h-full bg-primary" }) }),
6927
+ /* @__PURE__ */ jsxRuntime.jsx(SliderPrimitive__namespace.Thumb, { className: "block h-5 w-5 rounded-full border-2 border-primary bg-background ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50" })
6928
+ ]
6929
+ }
6930
+ ));
6931
+ Slider.displayName = SliderPrimitive__namespace.Root.displayName;
6932
+ async function getCroppedImg(imageSrc, areaPixels, outputSize, quality) {
6933
+ const img = await new Promise((resolve, reject) => {
6934
+ const image = new Image();
6935
+ image.crossOrigin = "anonymous";
6936
+ image.onload = () => resolve(image);
6937
+ image.onerror = (e) => reject(e);
6938
+ image.src = imageSrc;
6939
+ });
6940
+ const canvas = document.createElement("canvas");
6941
+ canvas.width = outputSize;
6942
+ canvas.height = outputSize;
6943
+ const ctx = canvas.getContext("2d");
6944
+ if (!ctx) {
6945
+ throw new Error("HazoUiImageCropper: canvas 2d context unavailable");
6946
+ }
6947
+ ctx.drawImage(
6948
+ img,
6949
+ areaPixels.x,
6950
+ areaPixels.y,
6951
+ areaPixels.width,
6952
+ areaPixels.height,
6953
+ 0,
6954
+ 0,
6955
+ outputSize,
6956
+ outputSize
6957
+ );
6958
+ return new Promise((resolve, reject) => {
6959
+ canvas.toBlob(
6960
+ (blob) => {
6961
+ if (blob) {
6962
+ resolve(blob);
6963
+ } else {
6964
+ reject(new Error("HazoUiImageCropper: canvas.toBlob returned null"));
6965
+ }
6966
+ },
6967
+ "image/webp",
6968
+ quality
6969
+ );
6970
+ });
6971
+ }
6972
+ var HazoUiImageCropper = React26__namespace.forwardRef(function HazoUiImageCropper2({
6973
+ imageSrc,
6974
+ onCropped,
6975
+ outputSize = 512,
6976
+ quality = 0.9,
6977
+ zoomLabel = "Zoom",
6978
+ className
6979
+ }, ref) {
6980
+ const [crop, set_crop] = React26__namespace.useState({
6981
+ x: 0,
6982
+ y: 0
6983
+ });
6984
+ const [zoom, set_zoom] = React26__namespace.useState(1);
6985
+ const cropped_area_pixels_ref = React26__namespace.useRef(null);
6986
+ const handle_crop_complete = React26__namespace.useCallback(
6987
+ (_croppedArea, croppedAreaPixels) => {
6988
+ cropped_area_pixels_ref.current = croppedAreaPixels;
6989
+ },
6990
+ []
6991
+ );
6992
+ React26__namespace.useImperativeHandle(
6993
+ ref,
6994
+ () => ({
6995
+ getCroppedBlob: async () => {
6996
+ if (!cropped_area_pixels_ref.current) {
6997
+ throw new Error(
6998
+ "HazoUiImageCropper: crop area not yet initialised \u2014 wait for the cropper to mount before calling getCroppedBlob."
6999
+ );
7000
+ }
7001
+ const blob = await getCroppedImg(
7002
+ imageSrc,
7003
+ cropped_area_pixels_ref.current,
7004
+ outputSize,
7005
+ quality
7006
+ );
7007
+ await onCropped?.(blob);
7008
+ return blob;
7009
+ }
7010
+ }),
7011
+ [imageSrc, onCropped, outputSize, quality]
7012
+ );
7013
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("cls_image_cropper_root flex flex-col gap-4", className), children: [
7014
+ /* @__PURE__ */ jsxRuntime.jsx(
7015
+ "div",
7016
+ {
7017
+ className: "cls_cropper_stage relative w-full overflow-hidden rounded-lg bg-muted",
7018
+ style: { height: "320px" },
7019
+ children: /* @__PURE__ */ jsxRuntime.jsx(
7020
+ Cropper__default.default,
7021
+ {
7022
+ image: imageSrc,
7023
+ crop,
7024
+ zoom,
7025
+ aspect: 1,
7026
+ cropShape: "round",
7027
+ showGrid: false,
7028
+ onCropChange: set_crop,
7029
+ onZoomChange: set_zoom,
7030
+ onCropComplete: handle_crop_complete
7031
+ }
7032
+ )
7033
+ }
7034
+ ),
7035
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cls_zoom_control flex flex-col gap-1.5", children: [
7036
+ /* @__PURE__ */ jsxRuntime.jsx(
7037
+ "label",
7038
+ {
7039
+ className: "cls_zoom_label text-sm font-medium text-foreground",
7040
+ id: "hazo-cropper-zoom-label",
7041
+ children: zoomLabel
7042
+ }
7043
+ ),
7044
+ /* @__PURE__ */ jsxRuntime.jsx(
7045
+ Slider,
7046
+ {
7047
+ "aria-labelledby": "hazo-cropper-zoom-label",
7048
+ min: 1,
7049
+ max: 3,
7050
+ step: 0.1,
7051
+ value: [zoom],
7052
+ onValueChange: (values) => set_zoom(values[0])
7053
+ }
7054
+ )
7055
+ ] })
7056
+ ] });
7057
+ });
7058
+ HazoUiImageCropper.displayName = "HazoUiImageCropper";
7059
+ function HazoUiImageCropperDialog({
7060
+ open,
7061
+ onOpenChange,
7062
+ file,
7063
+ onConfirm,
7064
+ onCancel,
7065
+ title = "Crop photo",
7066
+ confirmLabel = "Save",
7067
+ cancelLabel = "Cancel",
7068
+ zoomLabel = "Zoom",
7069
+ outputSize = 512,
7070
+ quality = 0.9
7071
+ }) {
7072
+ const cropper_ref = React26__namespace.useRef(null);
7073
+ const [image_src, set_image_src] = React26__namespace.useState(null);
7074
+ const [is_confirming, set_is_confirming] = React26__namespace.useState(false);
7075
+ React26__namespace.useEffect(() => {
7076
+ if (!file) {
7077
+ set_image_src(null);
7078
+ return;
7079
+ }
7080
+ const url = URL.createObjectURL(file);
7081
+ set_image_src(url);
7082
+ return () => {
7083
+ URL.revokeObjectURL(url);
7084
+ };
7085
+ }, [file]);
7086
+ const handle_confirm = async () => {
7087
+ if (!cropper_ref.current) return;
7088
+ set_is_confirming(true);
7089
+ try {
7090
+ const blob = await cropper_ref.current.getCroppedBlob();
7091
+ await onConfirm(blob);
7092
+ onOpenChange(false);
7093
+ } finally {
7094
+ set_is_confirming(false);
7095
+ }
7096
+ };
7097
+ return /* @__PURE__ */ jsxRuntime.jsx(
7098
+ HazoUiDialog,
7099
+ {
7100
+ open,
7101
+ onOpenChange,
7102
+ title,
7103
+ actionButtonText: confirmLabel,
7104
+ cancelButtonText: cancelLabel,
7105
+ onConfirm: handle_confirm,
7106
+ onCancel,
7107
+ actionButtonLoading: is_confirming,
7108
+ sizeWidth: "min(90vw, 520px)",
7109
+ contentClassName: "cls_image_cropper_dialog_body",
7110
+ children: image_src && /* @__PURE__ */ jsxRuntime.jsx(
7111
+ HazoUiImageCropper,
7112
+ {
7113
+ ref: cropper_ref,
7114
+ imageSrc: image_src,
7115
+ outputSize,
7116
+ quality,
7117
+ zoomLabel
7118
+ }
7119
+ )
7120
+ }
7121
+ );
7122
+ }
6915
7123
  var Drawer = ({
6916
7124
  shouldScaleBackground = true,
6917
7125
  ...props
@@ -7458,6 +7666,38 @@ function ButtonGroupText({ className, asChild = false, ...props }) {
7458
7666
  function ButtonGroupSeparator({ className, orientation = "vertical", ...props }) {
7459
7667
  return /* @__PURE__ */ jsxRuntime.jsx(Separator3, { orientation, className: cn("bg-input relative !m-0 self-stretch data-[orientation=vertical]:h-auto", className), ...props });
7460
7668
  }
7669
+ var InputAffix = React26__namespace.forwardRef(
7670
+ ({ className, containerClassName, prefix, suffix, type = "text", ...props }, ref) => {
7671
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7672
+ "div",
7673
+ {
7674
+ className: cn(
7675
+ "flex h-10 w-full items-center rounded-md border border-input bg-background text-sm ring-offset-background focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2",
7676
+ containerClassName
7677
+ ),
7678
+ children: [
7679
+ prefix != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex select-none items-center pl-3 text-muted-foreground", children: prefix }),
7680
+ /* @__PURE__ */ jsxRuntime.jsx(
7681
+ "input",
7682
+ {
7683
+ type,
7684
+ ref,
7685
+ className: cn(
7686
+ "h-full w-full bg-transparent px-3 py-2 outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
7687
+ prefix != null && "pl-2",
7688
+ suffix != null && "pr-2",
7689
+ className
7690
+ ),
7691
+ ...props
7692
+ }
7693
+ ),
7694
+ suffix != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex select-none items-center pr-3 text-muted-foreground", children: suffix })
7695
+ ]
7696
+ }
7697
+ );
7698
+ }
7699
+ );
7700
+ InputAffix.displayName = "InputAffix";
7461
7701
  var SkeletonBase = React26__namespace.forwardRef(
7462
7702
  ({ className, ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
7463
7703
  "div",
@@ -9736,573 +9976,12 @@ function pick_x_label_indices(length) {
9736
9976
  if (length === 2) return [0, 0, 1];
9737
9977
  return [0, Math.floor(length / 2), length - 1];
9738
9978
  }
9739
- var PAD_LEFT = 38;
9740
- var PAD_RIGHT = 14;
9741
- var PAD_TOP = 12;
9979
+ var PAD_LEFT = 32;
9980
+ var PAD_RIGHT = 8;
9981
+ var PAD_TOP = 10;
9742
9982
  var PAD_BOTTOM = 22;
9743
- var AXIS_LABEL_COLOR = "#8b949e";
9744
- var GRIDLINE_COLOR = "#2a3441";
9745
- function compute_geometry(data, width, height) {
9746
- const vals = data.filter((v) => v !== null && !Number.isNaN(v));
9747
- if (vals.length === 0) return null;
9748
- const mn = Math.min(...vals);
9749
- const mx = Math.max(...vals);
9750
- const rng = mx - mn || mx * 0.1 + 1;
9751
- const y_min = Math.max(0, mn - rng * 0.1);
9752
- const y_max = mx + rng * 0.1;
9753
- const y_rng = y_max - y_min || 1;
9754
- const plot_w = width - PAD_LEFT - PAD_RIGHT;
9755
- const plot_h = height - PAD_TOP - PAD_BOTTOM;
9756
- return {
9757
- vbox_w: width,
9758
- vbox_h: height,
9759
- y_min,
9760
- y_max,
9761
- cx: (i) => data.length <= 1 ? PAD_LEFT + plot_w / 2 : PAD_LEFT + i * plot_w / (data.length - 1),
9762
- cy: (v) => PAD_TOP + (1 - (v - y_min) / y_rng) * plot_h
9763
- };
9764
- }
9765
- function build_paths(data, g) {
9766
- let line_d = "";
9767
- let first_idx = -1;
9768
- data.forEach((v, i) => {
9769
- if (v === null || Number.isNaN(v)) return;
9770
- if (first_idx === -1) first_idx = i;
9771
- line_d += `${line_d ? " L" : "M"}${g.cx(i).toFixed(1)},${g.cy(v).toFixed(1)}`;
9772
- });
9773
- const last_idx = data.length - 1;
9774
- const last_v = data[last_idx];
9775
- const area_d = line_d && last_v !== null && last_v !== void 0 && !Number.isNaN(last_v) ? `${line_d} L${g.cx(last_idx).toFixed(1)},${g.vbox_h - PAD_BOTTOM} L${g.cx(first_idx).toFixed(1)},${g.vbox_h - PAD_BOTTOM} Z` : "";
9776
- return { line_d, area_d };
9777
- }
9778
- function LineChart({
9779
- data,
9780
- dates,
9781
- color: color2,
9782
- width = 360,
9783
- height = 130,
9784
- unit = "",
9785
- showTooltip = true,
9786
- className
9787
- }) {
9788
- const geo = compute_geometry(data, width, height);
9789
- const svg_ref = React26__namespace.useRef(null);
9790
- const [hover_idx, set_hover_idx] = React26__namespace.useState(null);
9791
- const handle_mouse_move = React26__namespace.useCallback(
9792
- (e) => {
9793
- if (!geo) return;
9794
- const rect = e.currentTarget.getBoundingClientRect();
9795
- if (rect.width === 0) return;
9796
- const vbox_x = (e.clientX - rect.left) / rect.width * geo.vbox_w;
9797
- const plot_w = geo.vbox_w - PAD_LEFT - PAD_RIGHT;
9798
- if (vbox_x < PAD_LEFT || vbox_x > geo.vbox_w - PAD_RIGHT) {
9799
- set_hover_idx(null);
9800
- return;
9801
- }
9802
- const ratio = (vbox_x - PAD_LEFT) / plot_w;
9803
- const idx = Math.round(ratio * (data.length - 1));
9804
- const clamped = Math.max(0, Math.min(data.length - 1, idx));
9805
- let resolved = clamped;
9806
- if (data[resolved] === null || Number.isNaN(data[resolved])) {
9807
- for (let step = 1; step < data.length; step += 1) {
9808
- const left_i = clamped - step;
9809
- const right_i = clamped + step;
9810
- if (left_i >= 0 && data[left_i] !== null && !Number.isNaN(data[left_i])) {
9811
- resolved = left_i;
9812
- break;
9813
- }
9814
- if (right_i < data.length && data[right_i] !== null && !Number.isNaN(data[right_i])) {
9815
- resolved = right_i;
9816
- break;
9817
- }
9818
- }
9819
- }
9820
- set_hover_idx(resolved);
9821
- },
9822
- [geo, data]
9823
- );
9824
- const handle_mouse_leave = React26__namespace.useCallback(() => set_hover_idx(null), []);
9825
- if (!geo) {
9826
- return /* @__PURE__ */ jsxRuntime.jsx(
9827
- "svg",
9828
- {
9829
- viewBox: `0 0 ${width} ${height}`,
9830
- className: cn("cls_hazo_chart cls_hazo_chart_empty", className),
9831
- style: { width: "100%", height: "auto", display: "block", maxHeight: `${height + 10}px` }
9832
- }
9833
- );
9834
- }
9835
- const { line_d, area_d } = build_paths(data, geo);
9836
- const x_label_idx = pick_x_label_indices(data.length);
9837
- const last_idx = data.length - 1;
9838
- const last_v = data[last_idx];
9839
- const has_last = last_v !== null && last_v !== void 0 && !Number.isNaN(last_v);
9840
- const hover_v = hover_idx !== null ? data[hover_idx] : null;
9841
- const hover_has_v = hover_v !== null && hover_v !== void 0 && !Number.isNaN(hover_v);
9842
- return /* @__PURE__ */ jsxRuntime.jsxs(
9843
- "svg",
9844
- {
9845
- ref: svg_ref,
9846
- viewBox: `0 0 ${width} ${height}`,
9847
- onMouseMove: showTooltip ? handle_mouse_move : void 0,
9848
- onMouseLeave: showTooltip ? handle_mouse_leave : void 0,
9849
- className: cn("cls_hazo_chart", className),
9850
- style: {
9851
- width: "100%",
9852
- height: "auto",
9853
- display: "block",
9854
- maxHeight: `${height + 10}px`,
9855
- cursor: showTooltip ? "crosshair" : "default"
9856
- },
9857
- children: [
9858
- [0, 1, 2].map((i) => {
9859
- const y = PAD_TOP + i / 2 * (geo.vbox_h - PAD_TOP - PAD_BOTTOM);
9860
- return /* @__PURE__ */ jsxRuntime.jsx(
9861
- "line",
9862
- {
9863
- x1: PAD_LEFT,
9864
- x2: geo.vbox_w - PAD_RIGHT,
9865
- y1: y,
9866
- y2: y,
9867
- stroke: GRIDLINE_COLOR,
9868
- strokeWidth: 0.5,
9869
- strokeDasharray: "2,3"
9870
- },
9871
- i
9872
- );
9873
- }),
9874
- area_d && /* @__PURE__ */ jsxRuntime.jsx("path", { d: area_d, fill: color2, fillOpacity: 0.12, stroke: "none" }),
9875
- line_d && /* @__PURE__ */ jsxRuntime.jsx("path", { d: line_d, stroke: color2, strokeWidth: 1.8, fill: "none" }),
9876
- /* @__PURE__ */ jsxRuntime.jsx("text", { x: PAD_LEFT - 4, y: PAD_TOP + 3, textAnchor: "end", fill: AXIS_LABEL_COLOR, fontSize: 9, children: format_num(geo.y_max) }),
9877
- /* @__PURE__ */ jsxRuntime.jsx(
9878
- "text",
9879
- {
9880
- x: PAD_LEFT - 4,
9881
- y: PAD_TOP + (geo.vbox_h - PAD_TOP - PAD_BOTTOM) / 2 + 3,
9882
- textAnchor: "end",
9883
- fill: AXIS_LABEL_COLOR,
9884
- fontSize: 9,
9885
- children: format_num((geo.y_max + geo.y_min) / 2)
9886
- }
9887
- ),
9888
- /* @__PURE__ */ jsxRuntime.jsx(
9889
- "text",
9890
- {
9891
- x: PAD_LEFT - 4,
9892
- y: geo.vbox_h - PAD_BOTTOM + 3,
9893
- textAnchor: "end",
9894
- fill: AXIS_LABEL_COLOR,
9895
- fontSize: 9,
9896
- children: format_num(geo.y_min)
9897
- }
9898
- ),
9899
- x_label_idx.map((idx, k) => {
9900
- const anchor = k === 0 ? "start" : k === 1 ? "middle" : "end";
9901
- const x_pos = geo.cx(idx);
9902
- return /* @__PURE__ */ jsxRuntime.jsx(
9903
- "text",
9904
- {
9905
- x: x_pos,
9906
- y: geo.vbox_h - 6,
9907
- textAnchor: anchor,
9908
- fill: AXIS_LABEL_COLOR,
9909
- fontSize: 9,
9910
- children: dates[idx] ?? ""
9911
- },
9912
- `x_${k}`
9913
- );
9914
- }),
9915
- has_last && hover_idx === null && (() => {
9916
- const x = geo.cx(last_idx);
9917
- const y = geo.cy(last_v);
9918
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9919
- /* @__PURE__ */ jsxRuntime.jsx(
9920
- "line",
9921
- {
9922
- x1: x,
9923
- x2: PAD_LEFT,
9924
- y1: y,
9925
- y2: y,
9926
- stroke: color2,
9927
- strokeWidth: 0.5,
9928
- strokeDasharray: "2,2",
9929
- opacity: 0.4
9930
- }
9931
- ),
9932
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x, cy: y, r: 3.5, fill: color2, stroke: color2, strokeWidth: 2, fillOpacity: 0.3 }),
9933
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x, cy: y, r: 2, fill: color2 }),
9934
- /* @__PURE__ */ jsxRuntime.jsxs("text", { x: x - 6, y: y - 6, textAnchor: "end", fill: color2, fontSize: 10, fontWeight: 700, children: [
9935
- format_num(last_v),
9936
- unit
9937
- ] })
9938
- ] });
9939
- })(),
9940
- showTooltip && hover_idx !== null && hover_has_v && (() => {
9941
- const x = geo.cx(hover_idx);
9942
- const y = geo.cy(hover_v);
9943
- const label = `${format_num(hover_v)}${unit}`;
9944
- const date = dates[hover_idx] ?? "";
9945
- const bubble_text_w = Math.max(label.length, date.length) * 5.5 + 12;
9946
- const bubble_w = Math.max(bubble_text_w, 40);
9947
- const bubble_h = 26;
9948
- const flip = x + bubble_w + 6 > geo.vbox_w - PAD_RIGHT;
9949
- const bubble_x = flip ? x - bubble_w - 6 : x + 6;
9950
- const bubble_y = Math.max(PAD_TOP, Math.min(y - bubble_h / 2, geo.vbox_h - PAD_BOTTOM - bubble_h));
9951
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9952
- /* @__PURE__ */ jsxRuntime.jsx(
9953
- "line",
9954
- {
9955
- x1: x,
9956
- x2: x,
9957
- y1: PAD_TOP,
9958
- y2: geo.vbox_h - PAD_BOTTOM,
9959
- stroke: color2,
9960
- strokeWidth: 0.5,
9961
- strokeDasharray: "2,2",
9962
- opacity: 0.6
9963
- }
9964
- ),
9965
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: x, cy: y, r: 3, fill: color2 }),
9966
- /* @__PURE__ */ jsxRuntime.jsx(
9967
- "rect",
9968
- {
9969
- x: bubble_x,
9970
- y: bubble_y,
9971
- width: bubble_w,
9972
- height: bubble_h,
9973
- rx: 3,
9974
- fill: "#0d1117",
9975
- stroke: color2,
9976
- strokeWidth: 0.5,
9977
- fillOpacity: 0.92
9978
- }
9979
- ),
9980
- /* @__PURE__ */ jsxRuntime.jsx(
9981
- "text",
9982
- {
9983
- x: bubble_x + bubble_w / 2,
9984
- y: bubble_y + 11,
9985
- textAnchor: "middle",
9986
- fill: color2,
9987
- fontSize: 10,
9988
- fontWeight: 700,
9989
- children: label
9990
- }
9991
- ),
9992
- /* @__PURE__ */ jsxRuntime.jsx(
9993
- "text",
9994
- {
9995
- x: bubble_x + bubble_w / 2,
9996
- y: bubble_y + 22,
9997
- textAnchor: "middle",
9998
- fill: AXIS_LABEL_COLOR,
9999
- fontSize: 8,
10000
- children: date
10001
- }
10002
- )
10003
- ] });
10004
- })()
10005
- ]
10006
- }
10007
- );
10008
- }
10009
- var PAD_LEFT2 = 38;
10010
- var PAD_RIGHT2 = 14;
10011
- var PAD_TOP2 = 12;
10012
- var PAD_BOTTOM2 = 22;
10013
- var AXIS_LABEL_COLOR2 = "#8b949e";
10014
- var GRIDLINE_COLOR2 = "#2a3441";
10015
- function compute_geometry2(series, width, height) {
10016
- const all_vals = [];
10017
- let n = 0;
10018
- for (const s of series) {
10019
- n = Math.max(n, s.data.length);
10020
- for (const v of s.data) if (v !== null && !Number.isNaN(v)) all_vals.push(v);
10021
- }
10022
- if (all_vals.length === 0 || n === 0) return null;
10023
- const mn = Math.min(...all_vals);
10024
- const mx = Math.max(...all_vals);
10025
- const rng = mx - mn || mx * 0.1 + 1;
10026
- const y_min = Math.max(0, mn - rng * 0.05);
10027
- const y_max = mx + rng * 0.05;
10028
- const y_rng = y_max - y_min || 1;
10029
- const plot_w = width - PAD_LEFT2 - PAD_RIGHT2;
10030
- const plot_h = height - PAD_TOP2 - PAD_BOTTOM2;
10031
- return {
10032
- vbox_w: width,
10033
- vbox_h: height,
10034
- y_min,
10035
- y_max,
10036
- point_count: n,
10037
- cx: (i) => n <= 1 ? PAD_LEFT2 + plot_w / 2 : PAD_LEFT2 + i * plot_w / (n - 1),
10038
- cy: (v) => PAD_TOP2 + (1 - (v - y_min) / y_rng) * plot_h
10039
- };
10040
- }
10041
- function MultiLineChart({
10042
- series,
10043
- dates,
10044
- width = 360,
10045
- height = 140,
10046
- showTooltip = true,
10047
- showLegend = true,
10048
- className
10049
- }) {
10050
- const geo = compute_geometry2(series, width, height);
10051
- const [hover_idx, set_hover_idx] = React26__namespace.useState(null);
10052
- const handle_mouse_move = React26__namespace.useCallback(
10053
- (e) => {
10054
- if (!geo) return;
10055
- const rect = e.currentTarget.getBoundingClientRect();
10056
- if (rect.width === 0) return;
10057
- const vbox_x = (e.clientX - rect.left) / rect.width * geo.vbox_w;
10058
- const plot_w = geo.vbox_w - PAD_LEFT2 - PAD_RIGHT2;
10059
- if (vbox_x < PAD_LEFT2 || vbox_x > geo.vbox_w - PAD_RIGHT2) {
10060
- set_hover_idx(null);
10061
- return;
10062
- }
10063
- const ratio = (vbox_x - PAD_LEFT2) / plot_w;
10064
- const idx = Math.round(ratio * (geo.point_count - 1));
10065
- set_hover_idx(Math.max(0, Math.min(geo.point_count - 1, idx)));
10066
- },
10067
- [geo]
10068
- );
10069
- const handle_mouse_leave = React26__namespace.useCallback(() => set_hover_idx(null), []);
10070
- if (!geo) {
10071
- return /* @__PURE__ */ jsxRuntime.jsx(
10072
- "svg",
10073
- {
10074
- viewBox: `0 0 ${width} ${height}`,
10075
- className: cn("cls_hazo_chart cls_hazo_chart_empty", className),
10076
- style: { width: "100%", height: "auto", display: "block", maxHeight: `${height + 10}px` }
10077
- }
10078
- );
10079
- }
10080
- const x_label_idx = pick_x_label_indices(geo.point_count);
10081
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("cls_hazo_chart_wrapper", className), children: [
10082
- /* @__PURE__ */ jsxRuntime.jsxs(
10083
- "svg",
10084
- {
10085
- viewBox: `0 0 ${width} ${height}`,
10086
- onMouseMove: showTooltip ? handle_mouse_move : void 0,
10087
- onMouseLeave: showTooltip ? handle_mouse_leave : void 0,
10088
- className: "cls_hazo_chart cls_hazo_chart_multi",
10089
- style: {
10090
- width: "100%",
10091
- height: "auto",
10092
- display: "block",
10093
- maxHeight: `${height + 10}px`,
10094
- cursor: showTooltip ? "crosshair" : "default"
10095
- },
10096
- children: [
10097
- [0, 1, 2].map((i) => {
10098
- const y = PAD_TOP2 + i / 2 * (geo.vbox_h - PAD_TOP2 - PAD_BOTTOM2);
10099
- return /* @__PURE__ */ jsxRuntime.jsx(
10100
- "line",
10101
- {
10102
- x1: PAD_LEFT2,
10103
- x2: geo.vbox_w - PAD_RIGHT2,
10104
- y1: y,
10105
- y2: y,
10106
- stroke: GRIDLINE_COLOR2,
10107
- strokeWidth: 0.5,
10108
- strokeDasharray: "2,3"
10109
- },
10110
- i
10111
- );
10112
- }),
10113
- /* @__PURE__ */ jsxRuntime.jsx("text", { x: PAD_LEFT2 - 4, y: PAD_TOP2 + 3, textAnchor: "end", fill: AXIS_LABEL_COLOR2, fontSize: 9, children: format_num(geo.y_max) }),
10114
- /* @__PURE__ */ jsxRuntime.jsx(
10115
- "text",
10116
- {
10117
- x: PAD_LEFT2 - 4,
10118
- y: PAD_TOP2 + (geo.vbox_h - PAD_TOP2 - PAD_BOTTOM2) / 2 + 3,
10119
- textAnchor: "end",
10120
- fill: AXIS_LABEL_COLOR2,
10121
- fontSize: 9,
10122
- children: format_num((geo.y_max + geo.y_min) / 2)
10123
- }
10124
- ),
10125
- /* @__PURE__ */ jsxRuntime.jsx("text", { x: PAD_LEFT2 - 4, y: geo.vbox_h - PAD_BOTTOM2 + 3, textAnchor: "end", fill: AXIS_LABEL_COLOR2, fontSize: 9, children: format_num(geo.y_min) }),
10126
- x_label_idx.map((idx, k) => {
10127
- const anchor = k === 0 ? "start" : k === 1 ? "middle" : "end";
10128
- return /* @__PURE__ */ jsxRuntime.jsx(
10129
- "text",
10130
- {
10131
- x: geo.cx(idx),
10132
- y: geo.vbox_h - 6,
10133
- textAnchor: anchor,
10134
- fill: AXIS_LABEL_COLOR2,
10135
- fontSize: 9,
10136
- children: dates[idx] ?? ""
10137
- },
10138
- `x_${k}`
10139
- );
10140
- }),
10141
- series.map((s, s_idx) => {
10142
- let d = "";
10143
- s.data.forEach((v, i) => {
10144
- if (v === null || Number.isNaN(v)) return;
10145
- d += `${d ? " L" : "M"}${geo.cx(i).toFixed(1)},${geo.cy(v).toFixed(1)}`;
10146
- });
10147
- const last_idx = s.data.length - 1;
10148
- const last_v = s.data[last_idx];
10149
- const has_last = last_v !== null && last_v !== void 0 && !Number.isNaN(last_v);
10150
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
10151
- d && /* @__PURE__ */ jsxRuntime.jsx("path", { d, stroke: s.color, strokeWidth: 1.7, fill: "none" }),
10152
- has_last && hover_idx === null && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10153
- /* @__PURE__ */ jsxRuntime.jsx(
10154
- "circle",
10155
- {
10156
- cx: geo.cx(last_idx),
10157
- cy: geo.cy(last_v),
10158
- r: 3,
10159
- fill: s.color,
10160
- fillOpacity: 0.3,
10161
- stroke: s.color,
10162
- strokeWidth: 1.5
10163
- }
10164
- ),
10165
- /* @__PURE__ */ jsxRuntime.jsx(
10166
- "text",
10167
- {
10168
- x: geo.cx(last_idx) - 5,
10169
- y: geo.cy(last_v) - 5,
10170
- textAnchor: "end",
10171
- fill: s.color,
10172
- fontSize: 9,
10173
- fontWeight: 700,
10174
- children: format_num(last_v)
10175
- }
10176
- )
10177
- ] })
10178
- ] }, `series_${s_idx}`);
10179
- }),
10180
- showTooltip && hover_idx !== null && (() => {
10181
- const x = geo.cx(hover_idx);
10182
- const items = series.map((s) => ({
10183
- label: s.label,
10184
- color: s.color,
10185
- value: s.data[hover_idx] ?? null
10186
- })).filter((it) => it.value !== null && !Number.isNaN(it.value));
10187
- if (items.length === 0) return null;
10188
- const bubble_w = 70;
10189
- const row_h = 12;
10190
- const bubble_h = items.length * row_h + 18;
10191
- const flip = x + bubble_w + 6 > geo.vbox_w - PAD_RIGHT2;
10192
- const bubble_x = flip ? x - bubble_w - 6 : x + 6;
10193
- const bubble_y = Math.max(PAD_TOP2, Math.min(PAD_TOP2 + 5, geo.vbox_h - PAD_BOTTOM2 - bubble_h));
10194
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10195
- /* @__PURE__ */ jsxRuntime.jsx(
10196
- "line",
10197
- {
10198
- x1: x,
10199
- x2: x,
10200
- y1: PAD_TOP2,
10201
- y2: geo.vbox_h - PAD_BOTTOM2,
10202
- stroke: AXIS_LABEL_COLOR2,
10203
- strokeWidth: 0.5,
10204
- strokeDasharray: "2,2",
10205
- opacity: 0.6
10206
- }
10207
- ),
10208
- items.map((it) => /* @__PURE__ */ jsxRuntime.jsx(
10209
- "circle",
10210
- {
10211
- cx: x,
10212
- cy: geo.cy(it.value),
10213
- r: 3,
10214
- fill: it.color
10215
- },
10216
- `hd_${it.label}`
10217
- )),
10218
- /* @__PURE__ */ jsxRuntime.jsx(
10219
- "rect",
10220
- {
10221
- x: bubble_x,
10222
- y: bubble_y,
10223
- width: bubble_w,
10224
- height: bubble_h,
10225
- rx: 3,
10226
- fill: "#0d1117",
10227
- stroke: AXIS_LABEL_COLOR2,
10228
- strokeWidth: 0.5,
10229
- fillOpacity: 0.92
10230
- }
10231
- ),
10232
- /* @__PURE__ */ jsxRuntime.jsx("text", { x: bubble_x + 6, y: bubble_y + 10, fill: AXIS_LABEL_COLOR2, fontSize: 8, children: dates[hover_idx] ?? "" }),
10233
- items.map((it, i) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
10234
- /* @__PURE__ */ jsxRuntime.jsx(
10235
- "rect",
10236
- {
10237
- x: bubble_x + 6,
10238
- y: bubble_y + 14 + i * row_h,
10239
- width: 6,
10240
- height: 6,
10241
- fill: it.color
10242
- }
10243
- ),
10244
- /* @__PURE__ */ jsxRuntime.jsx(
10245
- "text",
10246
- {
10247
- x: bubble_x + 16,
10248
- y: bubble_y + 20 + i * row_h,
10249
- fill: it.color,
10250
- fontSize: 9,
10251
- fontWeight: 600,
10252
- children: format_num(it.value)
10253
- }
10254
- )
10255
- ] }, `row_${i}`))
10256
- ] });
10257
- })()
10258
- ]
10259
- }
10260
- ),
10261
- showLegend && /* @__PURE__ */ jsxRuntime.jsx(
10262
- "div",
10263
- {
10264
- className: "cls_hazo_chart_legend",
10265
- style: {
10266
- display: "flex",
10267
- gap: "12px",
10268
- justifyContent: "center",
10269
- marginTop: "4px",
10270
- fontSize: "10px",
10271
- color: AXIS_LABEL_COLOR2,
10272
- flexWrap: "wrap"
10273
- },
10274
- children: series.map((s) => /* @__PURE__ */ jsxRuntime.jsxs(
10275
- "span",
10276
- {
10277
- style: { display: "inline-flex", alignItems: "center", gap: "4px" },
10278
- children: [
10279
- /* @__PURE__ */ jsxRuntime.jsx(
10280
- "i",
10281
- {
10282
- style: {
10283
- display: "inline-block",
10284
- width: "8px",
10285
- height: "8px",
10286
- background: s.color,
10287
- borderRadius: "1px"
10288
- }
10289
- }
10290
- ),
10291
- s.label
10292
- ]
10293
- },
10294
- s.label
10295
- ))
10296
- }
10297
- )
10298
- ] });
10299
- }
10300
- var PAD_LEFT3 = 32;
10301
- var PAD_RIGHT3 = 8;
10302
- var PAD_TOP3 = 10;
10303
- var PAD_BOTTOM3 = 22;
10304
9983
  var BAR_GAP_RATIO = 0.25;
10305
- var AXIS_LABEL_COLOR3 = "#8b949e";
9984
+ var AXIS_LABEL_COLOR = "#8b949e";
10306
9985
  function StackedBars({
10307
9986
  bars,
10308
9987
  width = 360,
@@ -10312,11 +9991,11 @@ function StackedBars({
10312
9991
  }) {
10313
9992
  const totals = bars.map((b) => b.segments.reduce((sum, s) => sum + s.value, 0));
10314
9993
  const y_max = Math.max(0, ...totals) || 1;
10315
- const plot_w = width - PAD_LEFT3 - PAD_RIGHT3;
10316
- const plot_h = height - PAD_TOP3 - PAD_BOTTOM3;
9994
+ const plot_w = width - PAD_LEFT - PAD_RIGHT;
9995
+ const plot_h = height - PAD_TOP - PAD_BOTTOM;
10317
9996
  const slot_w = bars.length > 0 ? plot_w / bars.length : 0;
10318
9997
  const bar_w = slot_w * (1 - BAR_GAP_RATIO);
10319
- const x_for = (i) => PAD_LEFT3 + i * slot_w + (slot_w - bar_w) / 2;
9998
+ const x_for = (i) => PAD_LEFT + i * slot_w + (slot_w - bar_w) / 2;
10320
9999
  const x_label_idx = pick_x_label_indices(bars.length);
10321
10000
  return /* @__PURE__ */ jsxRuntime.jsxs(
10322
10001
  "svg",
@@ -10326,14 +10005,14 @@ function StackedBars({
10326
10005
  style: { width: "100%", height: "auto", display: "block", maxHeight: `${height + 10}px` },
10327
10006
  children: [
10328
10007
  showYAxis && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10329
- /* @__PURE__ */ jsxRuntime.jsx("text", { x: PAD_LEFT3 - 4, y: PAD_TOP3 + 3, textAnchor: "end", fill: AXIS_LABEL_COLOR3, fontSize: 9, children: format_num(y_max) }),
10008
+ /* @__PURE__ */ jsxRuntime.jsx("text", { x: PAD_LEFT - 4, y: PAD_TOP + 3, textAnchor: "end", fill: AXIS_LABEL_COLOR, fontSize: 9, children: format_num(y_max) }),
10330
10009
  /* @__PURE__ */ jsxRuntime.jsx(
10331
10010
  "text",
10332
10011
  {
10333
- x: PAD_LEFT3 - 4,
10334
- y: PAD_TOP3 + plot_h / 2 + 3,
10012
+ x: PAD_LEFT - 4,
10013
+ y: PAD_TOP + plot_h / 2 + 3,
10335
10014
  textAnchor: "end",
10336
- fill: AXIS_LABEL_COLOR3,
10015
+ fill: AXIS_LABEL_COLOR,
10337
10016
  fontSize: 9,
10338
10017
  children: format_num(y_max / 2)
10339
10018
  }
@@ -10341,17 +10020,17 @@ function StackedBars({
10341
10020
  /* @__PURE__ */ jsxRuntime.jsx(
10342
10021
  "text",
10343
10022
  {
10344
- x: PAD_LEFT3 - 4,
10345
- y: height - PAD_BOTTOM3 + 3,
10023
+ x: PAD_LEFT - 4,
10024
+ y: height - PAD_BOTTOM + 3,
10346
10025
  textAnchor: "end",
10347
- fill: AXIS_LABEL_COLOR3,
10026
+ fill: AXIS_LABEL_COLOR,
10348
10027
  fontSize: 9,
10349
10028
  children: "0"
10350
10029
  }
10351
10030
  )
10352
10031
  ] }),
10353
10032
  bars.map((bar, i) => {
10354
- let cursor_y = height - PAD_BOTTOM3;
10033
+ let cursor_y = height - PAD_BOTTOM;
10355
10034
  return /* @__PURE__ */ jsxRuntime.jsx("g", { children: bar.segments.map((seg, s_idx) => {
10356
10035
  if (seg.value <= 0) return null;
10357
10036
  const seg_h = seg.value / y_max * plot_h;
@@ -10379,7 +10058,7 @@ function StackedBars({
10379
10058
  x: x_pos,
10380
10059
  y: height - 6,
10381
10060
  textAnchor: anchor,
10382
- fill: AXIS_LABEL_COLOR3,
10061
+ fill: AXIS_LABEL_COLOR,
10383
10062
  fontSize: 9,
10384
10063
  children: bars[idx]?.label ?? ""
10385
10064
  },
@@ -10428,15 +10107,15 @@ function DateRangeSelector({
10428
10107
  }
10429
10108
  );
10430
10109
  }
10431
- var PAD_LEFT4 = 80;
10432
- var PAD_RIGHT4 = 72;
10433
- var PAD_TOP4 = 12;
10434
- var PAD_BOTTOM4 = 12;
10110
+ var PAD_LEFT2 = 80;
10111
+ var PAD_RIGHT2 = 72;
10112
+ var PAD_TOP2 = 12;
10113
+ var PAD_BOTTOM2 = 12;
10435
10114
  var ROW_H = 44;
10436
10115
  var LABEL_H = 14;
10437
10116
  var BAR_H = 22;
10438
- var AXIS_LABEL_COLOR4 = "#8b949e";
10439
- var GRIDLINE_COLOR3 = "#2a3441";
10117
+ var AXIS_LABEL_COLOR2 = "#8b949e";
10118
+ var GRIDLINE_COLOR = "#2a3441";
10440
10119
  function step_total(step) {
10441
10120
  if (step.value !== void 0) return step.value;
10442
10121
  if (step.segments) return step.segments.reduce((s, g) => s + g.value, 0);
@@ -10456,15 +10135,15 @@ function FunnelChart({
10456
10135
  const fmt = valueFormat ?? format_num;
10457
10136
  const totals = steps.map(step_total);
10458
10137
  const value_max = Math.max(1, ...totals);
10459
- const plot_w = width - PAD_LEFT4 - PAD_RIGHT4;
10460
- const vbox_h = height ?? PAD_TOP4 + steps.length * ROW_H + PAD_BOTTOM4;
10138
+ const plot_w = width - PAD_LEFT2 - PAD_RIGHT2;
10139
+ const vbox_h = height ?? PAD_TOP2 + steps.length * ROW_H + PAD_BOTTOM2;
10461
10140
  const handle_mouse_move = React26__namespace.useCallback(
10462
10141
  (e) => {
10463
10142
  if (steps.length === 0) return;
10464
10143
  const rect = e.currentTarget.getBoundingClientRect();
10465
10144
  if (rect.height === 0) return;
10466
10145
  const vbox_y = (e.clientY - rect.top) / rect.height * vbox_h;
10467
- const row_idx = Math.floor((vbox_y - PAD_TOP4) / ROW_H);
10146
+ const row_idx = Math.floor((vbox_y - PAD_TOP2) / ROW_H);
10468
10147
  if (row_idx < 0 || row_idx >= steps.length) {
10469
10148
  set_hover_idx(null);
10470
10149
  return;
@@ -10491,11 +10170,11 @@ function FunnelChart({
10491
10170
  steps.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
10492
10171
  "line",
10493
10172
  {
10494
- x1: PAD_LEFT4 + plot_w / 2,
10495
- x2: PAD_LEFT4 + plot_w / 2,
10496
- y1: PAD_TOP4,
10497
- y2: PAD_TOP4 + steps.length * ROW_H,
10498
- stroke: GRIDLINE_COLOR3,
10173
+ x1: PAD_LEFT2 + plot_w / 2,
10174
+ x2: PAD_LEFT2 + plot_w / 2,
10175
+ y1: PAD_TOP2,
10176
+ y2: PAD_TOP2 + steps.length * ROW_H,
10177
+ stroke: GRIDLINE_COLOR,
10499
10178
  strokeWidth: 0.5,
10500
10179
  strokeDasharray: "2,3"
10501
10180
  }
@@ -10503,8 +10182,8 @@ function FunnelChart({
10503
10182
  steps.map((step, i) => {
10504
10183
  const total = totals[i];
10505
10184
  const bar_w = total / value_max * plot_w;
10506
- const bar_x = PAD_LEFT4 + (plot_w - bar_w) / 2;
10507
- const bar_y = PAD_TOP4 + i * ROW_H + LABEL_H;
10185
+ const bar_x = PAD_LEFT2 + (plot_w - bar_w) / 2;
10186
+ const bar_y = PAD_TOP2 + i * ROW_H + LABEL_H;
10508
10187
  const pct_first = i === 0 ? 100 : Math.round(total / (totals[0] || 1) * 100);
10509
10188
  const value_label = i === 0 ? `${fmt(total)} (100%)` : `${fmt(total)} (${pct_first}%)`;
10510
10189
  const dropoff = i > 0 ? totals[i - 1] - total : 0;
@@ -10513,10 +10192,10 @@ function FunnelChart({
10513
10192
  /* @__PURE__ */ jsxRuntime.jsx(
10514
10193
  "text",
10515
10194
  {
10516
- x: PAD_LEFT4 - 6,
10195
+ x: PAD_LEFT2 - 6,
10517
10196
  y: bar_y + BAR_H / 2 + 4,
10518
10197
  textAnchor: "end",
10519
- fill: AXIS_LABEL_COLOR4,
10198
+ fill: AXIS_LABEL_COLOR2,
10520
10199
  fontSize: 9,
10521
10200
  children: step.label
10522
10201
  }
@@ -10558,7 +10237,7 @@ function FunnelChart({
10558
10237
  x: label_x,
10559
10238
  y: bar_y + BAR_H / 2 + 10,
10560
10239
  textAnchor: "start",
10561
- fill: AXIS_LABEL_COLOR4,
10240
+ fill: AXIS_LABEL_COLOR2,
10562
10241
  fontSize: 8,
10563
10242
  children: `\u2212${fmt(dropoff)}`
10564
10243
  }
@@ -10573,8 +10252,8 @@ function FunnelChart({
10573
10252
  const pct_prev = i === 0 ? 100 : Math.round(total / (totals[i - 1] || 1) * 100);
10574
10253
  const dropoff = i > 0 ? totals[i - 1] - total : 0;
10575
10254
  const bar_w = total / value_max * plot_w;
10576
- const bar_x = PAD_LEFT4 + (plot_w - bar_w) / 2;
10577
- const bar_y = PAD_TOP4 + i * ROW_H + LABEL_H;
10255
+ const bar_x = PAD_LEFT2 + (plot_w - bar_w) / 2;
10256
+ const bar_y = PAD_TOP2 + i * ROW_H + LABEL_H;
10578
10257
  const bubble_anchor_y = bar_y + BAR_H / 2;
10579
10258
  const lines = [
10580
10259
  { text: step.label, accent: true },
@@ -10628,7 +10307,7 @@ function FunnelChart({
10628
10307
  {
10629
10308
  x: bubble_x + 7,
10630
10309
  y: bubble_y + pad_v + k * line_h + line_h * 0.75,
10631
- fill: line.accent ? color2 : AXIS_LABEL_COLOR4,
10310
+ fill: line.accent ? color2 : AXIS_LABEL_COLOR2,
10632
10311
  fontSize: line.accent ? 10 : 8,
10633
10312
  fontWeight: line.accent ? 700 : 400,
10634
10313
  children: line.text
@@ -11184,6 +10863,8 @@ exports.HazoUiDialogTrigger = DialogTrigger;
11184
10863
  exports.HazoUiEtaProgress = HazoUiEtaProgress;
11185
10864
  exports.HazoUiFlexInput = HazoUiFlexInput;
11186
10865
  exports.HazoUiFlexRadio = HazoUiFlexRadio;
10866
+ exports.HazoUiImageCropper = HazoUiImageCropper;
10867
+ exports.HazoUiImageCropperDialog = HazoUiImageCropperDialog;
11187
10868
  exports.HazoUiKanban = HazoUiKanban;
11188
10869
  exports.HazoUiKanbanFilter = HazoUiKanbanFilter;
11189
10870
  exports.HazoUiMultiFilterDialog = HazoUiMultiFilterDialog;
@@ -11199,12 +10880,11 @@ exports.HoverCard = HoverCard;
11199
10880
  exports.HoverCardContent = HoverCardContent;
11200
10881
  exports.HoverCardTrigger = HoverCardTrigger;
11201
10882
  exports.Input = Input;
10883
+ exports.InputAffix = InputAffix;
11202
10884
  exports.InverseSparkline = InverseSparkline;
11203
10885
  exports.Label = Label3;
11204
- exports.LineChart = LineChart;
11205
10886
  exports.LoadingTimeout = LoadingTimeout;
11206
10887
  exports.MarkdownEditor = MarkdownEditor;
11207
- exports.MultiLineChart = MultiLineChart;
11208
10888
  exports.Popover = Popover;
11209
10889
  exports.PopoverContent = PopoverContent;
11210
10890
  exports.PopoverTrigger = PopoverTrigger;
@@ -11235,6 +10915,7 @@ exports.SkeletonBar = SkeletonBar;
11235
10915
  exports.SkeletonCircle = SkeletonCircle;
11236
10916
  exports.SkeletonGroup = SkeletonGroup;
11237
10917
  exports.SkeletonRect = SkeletonRect;
10918
+ exports.Slider = Slider;
11238
10919
  exports.Sparkline = Sparkline;
11239
10920
  exports.Spinner = Spinner;
11240
10921
  exports.StackedBars = StackedBars;