@valbuild/ui 0.41.0 → 0.42.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.
@@ -51498,7 +51498,7 @@ function isRichTextSchema(schema) {
51498
51498
  function isImageSchema(schema) {
51499
51499
  return schema instanceof ImageSchema || _typeof(schema) === "object" && "type" in schema && schema.type === "image";
51500
51500
  }
51501
- function resolvePath$2(path, valModule, schema) {
51501
+ function resolvePath$1(path, valModule, schema) {
51502
51502
  var parts = parsePath$1(path);
51503
51503
  var origParts = _toConsumableArray$1(parts);
51504
51504
  var resolvedSchema = schema;
@@ -52034,7 +52034,7 @@ var Internal = {
52034
52034
  getValPath,
52035
52035
  getVal,
52036
52036
  getSource,
52037
- resolvePath: resolvePath$2,
52037
+ resolvePath: resolvePath$1,
52038
52038
  splitModuleIdAndModulePath,
52039
52039
  isVal,
52040
52040
  createValPathOfItem: createValPathOfItem$1,
@@ -66595,106 +66595,419 @@ function useDrag({
66595
66595
  const isInitialized = !!((_b = (_a = ref == null ? void 0 : ref.current) == null ? void 0 : _a.getBoundingClientRect()) == null ? void 0 : _b.width);
66596
66596
  return [position, isInitialized, ref, handleMouseDown];
66597
66597
  }
66598
- function resolvePath$1(sourcePath, modules) {
66599
- const [moduleId, modulePath] = Internal.splitModuleIdAndModulePath(sourcePath);
66600
- const valModule = modules[moduleId];
66601
- if (!(valModule == null ? void 0 : valModule.source)) {
66602
- return result.err({
66603
- message: `Module "${moduleId}" has no source`
66598
+ function usePatch(paths, api, valStore, onSubmit, session) {
66599
+ const [state, setState] = React$3.useState({});
66600
+ const [error, setError] = React$3.useState(null);
66601
+ const [progress, setProgress] = React$3.useState("ready");
66602
+ const initPatchCallback = React$3.useCallback(
66603
+ (paths2) => {
66604
+ return (callback) => {
66605
+ setState((prev) => {
66606
+ const nextState = paths2.reduce((acc, path) => {
66607
+ const patchPath = Internal.createPatchJSONPath(
66608
+ Internal.splitModuleIdAndModulePath(path)[1]
66609
+ );
66610
+ return {
66611
+ ...acc,
66612
+ [path]: () => callback(patchPath)
66613
+ };
66614
+ }, {});
66615
+ return {
66616
+ ...prev,
66617
+ ...nextState
66618
+ };
66619
+ });
66620
+ };
66621
+ },
66622
+ []
66623
+ );
66624
+ React$3.useEffect(() => {
66625
+ setState((prev) => {
66626
+ const newState = {};
66627
+ for (const path of paths) {
66628
+ if (prev[path]) {
66629
+ newState[path] = prev[path];
66630
+ }
66631
+ }
66632
+ if (Object.keys(newState).length === Object.keys(prev).length) {
66633
+ return prev;
66634
+ }
66635
+ return newState;
66604
66636
  });
66605
- }
66606
- if (!(valModule == null ? void 0 : valModule.schema)) {
66607
- return result.err({
66608
- message: `Module "${moduleId}" has no schema`
66637
+ }, [paths]);
66638
+ const onSubmitPatch = React$3.useCallback(async () => {
66639
+ setError(null);
66640
+ setProgress("create_patch");
66641
+ const patches = {};
66642
+ for (const path in state) {
66643
+ const [moduleId] = Internal.splitModuleIdAndModulePath(
66644
+ path
66645
+ );
66646
+ const patch = await state[path]();
66647
+ patches[moduleId] = patch;
66648
+ }
66649
+ return maybeStartViewTransition(() => {
66650
+ setProgress("patching");
66651
+ return Promise.all(
66652
+ Object.entries(patches).map(
66653
+ ([moduleId, patch]) => api.postPatches(moduleId, patch).then((res) => {
66654
+ if (result.isErr(res)) {
66655
+ throw res.error;
66656
+ } else {
66657
+ res.value;
66658
+ }
66659
+ })
66660
+ )
66661
+ ).then(() => {
66662
+ setProgress("on_submit");
66663
+ const refreshRequired = session.status === "success" && session.data.mode === "proxy";
66664
+ return onSubmit(refreshRequired);
66665
+ }).then(() => {
66666
+ setProgress("update_store");
66667
+ return valStore.update(
66668
+ paths.map(
66669
+ (path) => Internal.splitModuleIdAndModulePath(path)[0]
66670
+ )
66671
+ );
66672
+ });
66673
+ }).catch((err2) => {
66674
+ setError(err2);
66675
+ }).finally(() => {
66676
+ setProgress("ready");
66609
66677
  });
66678
+ }, [state, session]);
66679
+ return { initPatchCallback, onSubmitPatch, error, progress };
66680
+ }
66681
+ async function maybeStartViewTransition(f) {
66682
+ if ("startViewTransition" in document && typeof document.startViewTransition === "function") {
66683
+ await document.startViewTransition(f);
66610
66684
  }
66611
- return result.ok(
66612
- Internal.resolvePath(modulePath, valModule.source, valModule.schema)
66613
- );
66685
+ await f();
66614
66686
  }
66615
- const falsyToString = (value) => typeof value === "boolean" ? "".concat(value) : value === 0 ? "0" : value;
66616
- const cx = clsx;
66617
- const cva = (base, config) => {
66618
- return (props) => {
66619
- var ref;
66620
- if ((config === null || config === void 0 ? void 0 : config.variants) == null)
66621
- return cx(base, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
66622
- const { variants, defaultVariants } = config;
66623
- const getVariantClassNames = Object.keys(variants).map((variant) => {
66624
- const variantProp = props === null || props === void 0 ? void 0 : props[variant];
66625
- const defaultVariantProp = defaultVariants === null || defaultVariants === void 0 ? void 0 : defaultVariants[variant];
66626
- if (variantProp === null)
66627
- return null;
66628
- const variantKey = falsyToString(variantProp) || falsyToString(defaultVariantProp);
66629
- return variants[variant][variantKey];
66630
- });
66631
- const propsWithoutUndefined = props && Object.entries(props).reduce((acc, param) => {
66632
- let [key, value] = param;
66633
- if (value === void 0) {
66634
- return acc;
66687
+ function useTheme(defaultTheme = "dark") {
66688
+ const [theme2, setTheme] = React$3.useState(defaultTheme);
66689
+ React$3.useEffect(() => {
66690
+ if (localStorage.getItem("val-theme") === "light") {
66691
+ setTheme("light");
66692
+ } else if (localStorage.getItem("val-theme") === "dark") {
66693
+ setTheme("dark");
66694
+ } else if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
66695
+ setTheme("dark");
66696
+ } else if (window.matchMedia && window.matchMedia("(prefers-color-scheme: light)").matches) {
66697
+ setTheme("light");
66698
+ }
66699
+ const themeListener = (e) => {
66700
+ if (!localStorage.getItem("val-theme")) {
66701
+ setTheme(e.matches ? "dark" : "light");
66635
66702
  }
66636
- acc[key] = value;
66637
- return acc;
66638
- }, {});
66639
- const getCompoundVariantClassNames = config === null || config === void 0 ? void 0 : (ref = config.compoundVariants) === null || ref === void 0 ? void 0 : ref.reduce((acc, param1) => {
66640
- let { class: cvClass, className: cvClassName, ...compoundVariantOptions } = param1;
66641
- return Object.entries(compoundVariantOptions).every((param) => {
66642
- let [key, value] = param;
66643
- return Array.isArray(value) ? value.includes({
66644
- ...defaultVariants,
66645
- ...propsWithoutUndefined
66646
- }[key]) : {
66647
- ...defaultVariants,
66648
- ...propsWithoutUndefined
66649
- }[key] === value;
66650
- }) ? [
66651
- ...acc,
66652
- cvClass,
66653
- cvClassName
66654
- ] : acc;
66655
- }, []);
66656
- return cx(base, getVariantClassNames, getCompoundVariantClassNames, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
66703
+ };
66704
+ window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", themeListener);
66705
+ return () => {
66706
+ window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", themeListener);
66707
+ };
66708
+ }, []);
66709
+ return [
66710
+ theme2,
66711
+ (theme22) => {
66712
+ localStorage.setItem("val-theme", theme22);
66713
+ setTheme(theme22);
66714
+ }
66715
+ ];
66716
+ }
66717
+ function Grid({ children }) {
66718
+ const leftColRef = React$3.useRef(null);
66719
+ const rightColRef = React$3.useRef(null);
66720
+ const isResizing = React$3.useRef(false);
66721
+ const x = React$3.useRef(0);
66722
+ const dragRef = React$3.useRef(null);
66723
+ const originalWidth = React$3.useRef(0);
66724
+ const handleMouseUp = () => {
66725
+ isResizing.current = false;
66726
+ dragRef.current = null;
66727
+ x.current = 0;
66728
+ originalWidth.current = 0;
66657
66729
  };
66658
- };
66659
- const buttonVariants = cva(
66660
- "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium 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",
66661
- {
66662
- variants: {
66663
- variant: {
66664
- default: "bg-primary text-primary-foreground hover:bg-primary/90",
66665
- destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
66666
- outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
66667
- secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
66668
- ghost: "hover:bg-accent hover:text-accent-foreground",
66669
- link: "text-primary underline-offset-4 hover:underline"
66670
- },
66671
- size: {
66672
- default: "h-10 px-4 py-2",
66673
- sm: "h-9 rounded-md px-3",
66674
- lg: "h-11 rounded-md px-8",
66675
- icon: "h-10 w-10"
66730
+ const handleMouseMove = (event) => {
66731
+ event.preventDefault();
66732
+ const targetRef = dragRef.current === "left" ? leftColRef : rightColRef;
66733
+ if (targetRef.current && isResizing.current) {
66734
+ const dx = dragRef.current === "left" ? event.screenX - x.current : x.current - event.screenX;
66735
+ targetRef.current.style.width = `${Math.max(
66736
+ originalWidth.current + dx,
66737
+ 150
66738
+ )}px`;
66739
+ }
66740
+ };
66741
+ const handleMouseDown = (column) => (event) => {
66742
+ const target = event.target;
66743
+ if (target) {
66744
+ const columnRef = column === "left" ? leftColRef : column === "right" ? rightColRef : null;
66745
+ isResizing.current = true;
66746
+ if (columnRef && columnRef.current) {
66747
+ x.current = event.screenX;
66748
+ dragRef.current = column;
66749
+ if (columnRef.current) {
66750
+ originalWidth.current = columnRef.current.offsetWidth;
66751
+ }
66676
66752
  }
66677
- },
66678
- defaultVariants: {
66679
- variant: "default",
66680
- size: "default"
66681
66753
  }
66682
- }
66683
- );
66684
- const Button = React__namespace.forwardRef(
66685
- ({ className: className2, variant, size: size2, asChild = false, ...props }, ref) => {
66686
- const Comp = asChild ? $5e63c961fc1ce211$export$8c6ed5c666ac1360 : "button";
66687
- return /* @__PURE__ */ jsxRuntime.jsx(
66688
- Comp,
66754
+ };
66755
+ const [header1, body1, header2, body2, header3, body3] = React$3.Children.toArray(children);
66756
+ React$3.useEffect(() => {
66757
+ document.addEventListener("mouseup", handleMouseUp);
66758
+ document.addEventListener("mousemove", handleMouseMove);
66759
+ return () => {
66760
+ document.removeEventListener("mouseup", handleMouseUp);
66761
+ document.removeEventListener("mousemove", handleMouseMove);
66762
+ };
66763
+ }, []);
66764
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-screen", children: [
66765
+ /* @__PURE__ */ jsxRuntime.jsxs(
66766
+ "div",
66689
66767
  {
66690
- className: cn(buttonVariants({ variant, size: size2, className: className2 })),
66691
- ref,
66692
- ...props
66768
+ ref: leftColRef,
66769
+ className: "relative border-r border-border",
66770
+ style: { width: 300 },
66771
+ children: [
66772
+ /* @__PURE__ */ jsxRuntime.jsxs(Grid.Column, { children: [
66773
+ header1,
66774
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { style: { height: "calc(100vh - 50px)" }, children: body1 })
66775
+ ] }),
66776
+ /* @__PURE__ */ jsxRuntime.jsx(
66777
+ "div",
66778
+ {
66779
+ className: "absolute inset-y-0 right-0 cursor-col-resize w-[1px] hover:w-[3px] h-full hover:bg-border",
66780
+ onMouseDown: handleMouseDown("left")
66781
+ }
66782
+ )
66783
+ ]
66693
66784
  }
66694
- );
66695
- }
66696
- );
66697
- Button.displayName = "Button";
66785
+ ),
66786
+ /* @__PURE__ */ jsxRuntime.jsx(
66787
+ "div",
66788
+ {
66789
+ className: classNames("", {
66790
+ "w-full": !header3 && !body3
66791
+ }),
66792
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Grid.Column, { children: [
66793
+ header2,
66794
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { style: { height: "calc(100vh - 50px)" }, children: body2 })
66795
+ ] })
66796
+ }
66797
+ ),
66798
+ header3 || body3 && /* @__PURE__ */ jsxRuntime.jsxs(
66799
+ "div",
66800
+ {
66801
+ ref: rightColRef,
66802
+ className: "relative h-screen border-l border-border",
66803
+ style: { width: 300 },
66804
+ children: [
66805
+ /* @__PURE__ */ jsxRuntime.jsxs(Grid.Column, { children: [
66806
+ header3,
66807
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { style: { height: "calc(100vh - 50px)" }, children: body3 })
66808
+ ] }),
66809
+ /* @__PURE__ */ jsxRuntime.jsx(
66810
+ "div",
66811
+ {
66812
+ onMouseDown: handleMouseDown("right"),
66813
+ className: "absolute inset-y-0 left-0 cursor-col-resize w-[1px] bg-border hover:w-[3px] hover:bg-border"
66814
+ }
66815
+ )
66816
+ ]
66817
+ }
66818
+ )
66819
+ ] });
66820
+ }
66821
+ Grid.Column = ({ children }) => {
66822
+ const [header, body] = React$3.Children.toArray(children);
66823
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
66824
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center border-b border-border", children: header }),
66825
+ body
66826
+ ] });
66827
+ };
66828
+ const Section = ({ className: className2 }) => {
66829
+ return /* @__PURE__ */ jsxRuntime.jsxs(
66830
+ "svg",
66831
+ {
66832
+ width: "9",
66833
+ height: "10",
66834
+ viewBox: "0 0 9 10",
66835
+ className: className2,
66836
+ fill: "currentColor",
66837
+ xmlns: "http://www.w3.org/2000/svg",
66838
+ children: [
66839
+ /* @__PURE__ */ jsxRuntime.jsxs("g", { clipPath: "url(#clip0_1222_1618)", children: [
66840
+ /* @__PURE__ */ jsxRuntime.jsx(
66841
+ "path",
66842
+ {
66843
+ fillRule: "evenodd",
66844
+ clipRule: "evenodd",
66845
+ d: "M9 1.5H0V0.5H9V1.5Z",
66846
+ fill: "currentColor"
66847
+ }
66848
+ ),
66849
+ /* @__PURE__ */ jsxRuntime.jsx(
66850
+ "path",
66851
+ {
66852
+ fillRule: "evenodd",
66853
+ clipRule: "evenodd",
66854
+ d: "M9 9.5H0V8.5H9V9.5Z",
66855
+ fill: "currentColor"
66856
+ }
66857
+ )
66858
+ ] }),
66859
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip0_1222_1618", children: /* @__PURE__ */ jsxRuntime.jsx(
66860
+ "rect",
66861
+ {
66862
+ width: "9",
66863
+ height: "9",
66864
+ fill: "white",
66865
+ transform: "translate(0 0.5)"
66866
+ }
66867
+ ) }) })
66868
+ ]
66869
+ }
66870
+ );
66871
+ };
66872
+ const Section$1 = Section;
66873
+ const TextIcon = ({ className: className2 }) => {
66874
+ return /* @__PURE__ */ jsxRuntime.jsx(
66875
+ "svg",
66876
+ {
66877
+ width: "9",
66878
+ height: "10",
66879
+ viewBox: "0 0 9 10",
66880
+ fill: "currentColor",
66881
+ xmlns: "http://www.w3.org/2000/svg",
66882
+ className: className2,
66883
+ children: /* @__PURE__ */ jsxRuntime.jsx("g", { clipPath: "url(#clip0_1229_1625)", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M0.0145513 0.5H8.98545L9 3.18569H8.57074C8.43007 2.2276 8.02749 1.57948 7.36298 1.24133C6.98949 1.05491 6.43169 0.953035 5.68957 0.935694V7.94581C5.68957 8.43569 5.78416 8.76084 5.97332 8.92124C6.16734 9.08165 6.5675 9.16185 7.17381 9.16185V9.5H1.86257V9.16185C2.44462 9.16185 2.83023 9.08165 3.0194 8.92124C3.21342 8.7565 3.31043 8.43136 3.31043 7.94581V0.935694C2.58286 0.953035 2.02506 1.05491 1.63703 1.24133C0.92401 1.58815 0.521423 2.23627 0.429264 3.18569H0L0.0145513 0.5Z" }) })
66884
+ }
66885
+ );
66886
+ };
66887
+ const TextIcon$1 = TextIcon;
66888
+ function Tree({ children, rootPath }) {
66889
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col w-full py-2 text-xs", children: React$3.Children.map(children, (child) => {
66890
+ return React$3.cloneElement(child, {
66891
+ paths: [rootPath]
66892
+ });
66893
+ }) });
66894
+ }
66895
+ Tree.Node = ({
66896
+ children,
66897
+ paths = [],
66898
+ path,
66899
+ level = 1,
66900
+ type,
66901
+ setActivePath
66902
+ }) => {
66903
+ const paddingLeft = level * 30;
66904
+ const logo = type === "string" ? /* @__PURE__ */ jsxRuntime.jsx(TextIcon$1, {}) : type === "image" ? /* @__PURE__ */ jsxRuntime.jsx(ImageIcon$1, { className: "h-[9px] w-[9px]" }) : /* @__PURE__ */ jsxRuntime.jsx(Section$1, {});
66905
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
66906
+ /* @__PURE__ */ jsxRuntime.jsx(
66907
+ "button",
66908
+ {
66909
+ className: "flex justify-between w-full group py-2 text-xs font-[400] shrink-0",
66910
+ onClick: () => {
66911
+ setActivePath && setActivePath(path);
66912
+ },
66913
+ style: { paddingLeft },
66914
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2", children: [
66915
+ logo,
66916
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: path })
66917
+ ] })
66918
+ }
66919
+ ),
66920
+ children && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: React$3.Children.map(children, (child) => {
66921
+ return React$3.cloneElement(child, {
66922
+ level: level + 1,
66923
+ paths: [...paths, path]
66924
+ });
66925
+ }) })
66926
+ ] });
66927
+ };
66928
+ const falsyToString = (value) => typeof value === "boolean" ? "".concat(value) : value === 0 ? "0" : value;
66929
+ const cx = clsx;
66930
+ const cva = (base, config) => {
66931
+ return (props) => {
66932
+ var ref;
66933
+ if ((config === null || config === void 0 ? void 0 : config.variants) == null)
66934
+ return cx(base, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
66935
+ const { variants, defaultVariants } = config;
66936
+ const getVariantClassNames = Object.keys(variants).map((variant) => {
66937
+ const variantProp = props === null || props === void 0 ? void 0 : props[variant];
66938
+ const defaultVariantProp = defaultVariants === null || defaultVariants === void 0 ? void 0 : defaultVariants[variant];
66939
+ if (variantProp === null)
66940
+ return null;
66941
+ const variantKey = falsyToString(variantProp) || falsyToString(defaultVariantProp);
66942
+ return variants[variant][variantKey];
66943
+ });
66944
+ const propsWithoutUndefined = props && Object.entries(props).reduce((acc, param) => {
66945
+ let [key, value] = param;
66946
+ if (value === void 0) {
66947
+ return acc;
66948
+ }
66949
+ acc[key] = value;
66950
+ return acc;
66951
+ }, {});
66952
+ const getCompoundVariantClassNames = config === null || config === void 0 ? void 0 : (ref = config.compoundVariants) === null || ref === void 0 ? void 0 : ref.reduce((acc, param1) => {
66953
+ let { class: cvClass, className: cvClassName, ...compoundVariantOptions } = param1;
66954
+ return Object.entries(compoundVariantOptions).every((param) => {
66955
+ let [key, value] = param;
66956
+ return Array.isArray(value) ? value.includes({
66957
+ ...defaultVariants,
66958
+ ...propsWithoutUndefined
66959
+ }[key]) : {
66960
+ ...defaultVariants,
66961
+ ...propsWithoutUndefined
66962
+ }[key] === value;
66963
+ }) ? [
66964
+ ...acc,
66965
+ cvClass,
66966
+ cvClassName
66967
+ ] : acc;
66968
+ }, []);
66969
+ return cx(base, getVariantClassNames, getCompoundVariantClassNames, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);
66970
+ };
66971
+ };
66972
+ const buttonVariants = cva(
66973
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium 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",
66974
+ {
66975
+ variants: {
66976
+ variant: {
66977
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
66978
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
66979
+ outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
66980
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
66981
+ ghost: "hover:bg-accent hover:text-accent-foreground",
66982
+ link: "text-primary underline-offset-4 hover:underline"
66983
+ },
66984
+ size: {
66985
+ default: "h-10 px-4 py-2",
66986
+ sm: "h-9 rounded-md px-3",
66987
+ lg: "h-11 rounded-md px-8",
66988
+ icon: "h-10 w-10"
66989
+ }
66990
+ },
66991
+ defaultVariants: {
66992
+ variant: "default",
66993
+ size: "default"
66994
+ }
66995
+ }
66996
+ );
66997
+ const Button = React__namespace.forwardRef(
66998
+ ({ className: className2, variant, size: size2, asChild = false, ...props }, ref) => {
66999
+ const Comp = asChild ? $5e63c961fc1ce211$export$8c6ed5c666ac1360 : "button";
67000
+ return /* @__PURE__ */ jsxRuntime.jsx(
67001
+ Comp,
67002
+ {
67003
+ className: cn(buttonVariants({ variant, size: size2, className: className2 })),
67004
+ ref,
67005
+ ...props
67006
+ }
67007
+ );
67008
+ }
67009
+ );
67010
+ Button.displayName = "Button";
66698
67011
  const Input = React__namespace.forwardRef(
66699
67012
  ({ className: className2, type, ...props }, ref) => {
66700
67013
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -71101,255 +71414,544 @@ const SelectSeparator = React__namespace.forwardRef(({ className: className2, ..
71101
71414
  }
71102
71415
  ));
71103
71416
  SelectSeparator.displayName = $cc7e05a45900e73f$export$1ff3c3f08ae963c0.displayName;
71104
- function Grid({ children }) {
71105
- const leftColRef = React$3.useRef(null);
71106
- const rightColRef = React$3.useRef(null);
71107
- const isResizing = React$3.useRef(false);
71108
- const x = React$3.useRef(0);
71109
- const dragRef = React$3.useRef(null);
71110
- const originalWidth = React$3.useRef(0);
71111
- const handleMouseUp = () => {
71112
- isResizing.current = false;
71113
- dragRef.current = null;
71114
- x.current = 0;
71115
- originalWidth.current = 0;
71116
- };
71117
- const handleMouseMove = (event) => {
71118
- event.preventDefault();
71119
- const targetRef = dragRef.current === "left" ? leftColRef : rightColRef;
71120
- if (targetRef.current && isResizing.current) {
71121
- const dx = dragRef.current === "left" ? event.screenX - x.current : x.current - event.screenX;
71122
- targetRef.current.style.width = `${Math.max(
71123
- originalWidth.current + dx,
71124
- 150
71125
- )}px`;
71126
- }
71127
- };
71128
- const handleMouseDown = (column) => (event) => {
71129
- const target = event.target;
71130
- if (target) {
71131
- const columnRef = column === "left" ? leftColRef : column === "right" ? rightColRef : null;
71132
- isResizing.current = true;
71133
- if (columnRef && columnRef.current) {
71134
- x.current = event.screenX;
71135
- dragRef.current = column;
71136
- if (columnRef.current) {
71137
- originalWidth.current = columnRef.current.offsetWidth;
71138
- }
71417
+ function ValFormField({
71418
+ path,
71419
+ disabled,
71420
+ source,
71421
+ schema,
71422
+ registerPatchCallback,
71423
+ onSubmit
71424
+ }) {
71425
+ if ((typeof source === "string" || source === null) && (schema == null ? void 0 : schema.type) === "string") {
71426
+ return /* @__PURE__ */ jsxRuntime.jsx(
71427
+ StringField,
71428
+ {
71429
+ defaultValue: source,
71430
+ disabled,
71431
+ registerPatchCallback,
71432
+ onSubmit
71139
71433
  }
71140
- }
71141
- };
71142
- const [header1, body1, header2, body2, header3, body3] = React$3.Children.toArray(children);
71143
- React$3.useEffect(() => {
71144
- document.addEventListener("mouseup", handleMouseUp);
71145
- document.addEventListener("mousemove", handleMouseMove);
71146
- return () => {
71147
- document.removeEventListener("mouseup", handleMouseUp);
71148
- document.removeEventListener("mousemove", handleMouseMove);
71149
- };
71150
- }, []);
71151
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-screen", children: [
71152
- /* @__PURE__ */ jsxRuntime.jsxs(
71153
- "div",
71434
+ );
71435
+ }
71436
+ if ((typeof source === "number" || source === null) && (schema == null ? void 0 : schema.type) === "number") {
71437
+ return /* @__PURE__ */ jsxRuntime.jsx(
71438
+ NumberField,
71154
71439
  {
71155
- ref: leftColRef,
71156
- className: "relative border-r border-border",
71157
- style: { width: 300 },
71158
- children: [
71159
- /* @__PURE__ */ jsxRuntime.jsxs(Grid.Column, { children: [
71160
- header1,
71161
- /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { style: { height: "calc(100vh - 50px)" }, children: body1 })
71162
- ] }),
71163
- /* @__PURE__ */ jsxRuntime.jsx(
71164
- "div",
71165
- {
71166
- className: "absolute inset-y-0 right-0 cursor-col-resize w-[1px] hover:w-[3px] h-full hover:bg-border",
71167
- onMouseDown: handleMouseDown("left")
71168
- }
71169
- )
71170
- ]
71440
+ defaultValue: source,
71441
+ disabled,
71442
+ registerPatchCallback,
71443
+ onSubmit
71171
71444
  }
71172
- ),
71173
- /* @__PURE__ */ jsxRuntime.jsx(
71174
- "div",
71445
+ );
71446
+ }
71447
+ if ((typeof source === "number" || typeof source === "string" || source === null) && (schema == null ? void 0 : schema.type) === "keyOf") {
71448
+ return /* @__PURE__ */ jsxRuntime.jsx(
71449
+ KeyOfField,
71175
71450
  {
71176
- className: classNames("", {
71177
- "w-full": !header3 && !body3
71178
- }),
71179
- children: /* @__PURE__ */ jsxRuntime.jsxs(Grid.Column, { children: [
71180
- header2,
71181
- /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { style: { height: "calc(100vh - 50px)" }, children: body2 })
71182
- ] })
71451
+ defaultValue: source,
71452
+ disabled,
71453
+ registerPatchCallback,
71454
+ onSubmit,
71455
+ selector: schema.selector
71183
71456
  }
71184
- ),
71185
- header3 || body3 && /* @__PURE__ */ jsxRuntime.jsxs(
71186
- "div",
71457
+ );
71458
+ }
71459
+ if ((typeof source === "number" || source === null) && (schema == null ? void 0 : schema.type) === "number") {
71460
+ return /* @__PURE__ */ jsxRuntime.jsx(
71461
+ NumberField,
71187
71462
  {
71188
- ref: rightColRef,
71189
- className: "relative h-screen border-l border-border",
71190
- style: { width: 300 },
71191
- children: [
71192
- /* @__PURE__ */ jsxRuntime.jsxs(Grid.Column, { children: [
71193
- header3,
71194
- /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { style: { height: "calc(100vh - 50px)" }, children: body3 })
71195
- ] }),
71196
- /* @__PURE__ */ jsxRuntime.jsx(
71197
- "div",
71198
- {
71199
- onMouseDown: handleMouseDown("right"),
71200
- className: "absolute inset-y-0 left-0 cursor-col-resize w-[1px] bg-border hover:w-[3px] hover:bg-border"
71201
- }
71202
- )
71203
- ]
71463
+ defaultValue: source,
71464
+ disabled,
71465
+ registerPatchCallback,
71466
+ onSubmit
71204
71467
  }
71205
- )
71468
+ );
71469
+ }
71470
+ if ((typeof source === "number" || typeof source === "string" || source === null) && (schema == null ? void 0 : schema.type) === "keyOf") {
71471
+ return /* @__PURE__ */ jsxRuntime.jsx(
71472
+ KeyOfField,
71473
+ {
71474
+ defaultValue: source,
71475
+ disabled,
71476
+ registerPatchCallback,
71477
+ onSubmit,
71478
+ selector: schema.selector
71479
+ }
71480
+ );
71481
+ }
71482
+ if ((typeof source === "object" || source === null) && (schema == null ? void 0 : schema.type) === "richtext") {
71483
+ return /* @__PURE__ */ jsxRuntime.jsx(
71484
+ RichTextField,
71485
+ {
71486
+ registerPatchCallback,
71487
+ onSubmit,
71488
+ defaultValue: source
71489
+ }
71490
+ );
71491
+ }
71492
+ if ((typeof source === "object" || source === null) && (schema == null ? void 0 : schema.type) === "image") {
71493
+ return /* @__PURE__ */ jsxRuntime.jsx(
71494
+ ImageField,
71495
+ {
71496
+ path,
71497
+ registerPatchCallback,
71498
+ onSubmit,
71499
+ defaultValue: source
71500
+ }
71501
+ );
71502
+ }
71503
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
71504
+ "Unsupported schema: ",
71505
+ schema.type
71206
71506
  ] });
71207
71507
  }
71208
- Grid.Column = ({ children }) => {
71209
- const [header, body] = React$3.Children.toArray(children);
71210
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
71211
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center border-b border-border", children: header }),
71212
- body
71213
- ] });
71214
- };
71215
- const Section = ({ className: className2 }) => {
71216
- return /* @__PURE__ */ jsxRuntime.jsxs(
71217
- "svg",
71218
- {
71219
- width: "9",
71220
- height: "10",
71221
- viewBox: "0 0 9 10",
71222
- className: className2,
71223
- fill: "currentColor",
71224
- xmlns: "http://www.w3.org/2000/svg",
71225
- children: [
71226
- /* @__PURE__ */ jsxRuntime.jsxs("g", { clipPath: "url(#clip0_1222_1618)", children: [
71227
- /* @__PURE__ */ jsxRuntime.jsx(
71228
- "path",
71229
- {
71230
- fillRule: "evenodd",
71231
- clipRule: "evenodd",
71232
- d: "M9 1.5H0V0.5H9V1.5Z",
71233
- fill: "currentColor"
71234
- }
71235
- ),
71236
- /* @__PURE__ */ jsxRuntime.jsx(
71237
- "path",
71238
- {
71239
- fillRule: "evenodd",
71240
- clipRule: "evenodd",
71241
- d: "M9 9.5H0V8.5H9V9.5Z",
71242
- fill: "currentColor"
71243
- }
71244
- )
71245
- ] }),
71246
- /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx("clipPath", { id: "clip0_1222_1618", children: /* @__PURE__ */ jsxRuntime.jsx(
71247
- "rect",
71248
- {
71249
- width: "9",
71250
- height: "9",
71251
- fill: "white",
71252
- transform: "translate(0 0.5)"
71253
- }
71254
- ) }) })
71255
- ]
71508
+ function createImagePatch(path, data, filename, metadata) {
71509
+ if (!data || !metadata) {
71510
+ return [];
71511
+ }
71512
+ const shaSuffix = metadata.sha256.slice(0, 5);
71513
+ const newFilePath = function() {
71514
+ const mimeType = getMimeType(data) ?? "unknown";
71515
+ const newExt = mimeTypeToFileExt(mimeType);
71516
+ if (filename) {
71517
+ const filenameWithoutExt = filename.split(".").slice(0, -1).join(".") || filename;
71518
+ return `/public/${filenameWithoutExt}_${shaSuffix}.${newExt}`;
71256
71519
  }
71257
- );
71258
- };
71259
- const Section$1 = Section;
71260
- const TextIcon = ({ className: className2 }) => {
71261
- return /* @__PURE__ */ jsxRuntime.jsx(
71262
- "svg",
71520
+ return `/public/${metadata.sha256}.${newExt}`;
71521
+ }();
71522
+ return [
71263
71523
  {
71264
- width: "9",
71265
- height: "10",
71266
- viewBox: "0 0 9 10",
71267
- fill: "currentColor",
71268
- xmlns: "http://www.w3.org/2000/svg",
71269
- className: className2,
71270
- children: /* @__PURE__ */ jsxRuntime.jsx("g", { clipPath: "url(#clip0_1229_1625)", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M0.0145513 0.5H8.98545L9 3.18569H8.57074C8.43007 2.2276 8.02749 1.57948 7.36298 1.24133C6.98949 1.05491 6.43169 0.953035 5.68957 0.935694V7.94581C5.68957 8.43569 5.78416 8.76084 5.97332 8.92124C6.16734 9.08165 6.5675 9.16185 7.17381 9.16185V9.5H1.86257V9.16185C2.44462 9.16185 2.83023 9.08165 3.0194 8.92124C3.21342 8.7565 3.31043 8.43136 3.31043 7.94581V0.935694C2.58286 0.953035 2.02506 1.05491 1.63703 1.24133C0.92401 1.58815 0.521423 2.23627 0.429264 3.18569H0L0.0145513 0.5Z" }) })
71524
+ value: {
71525
+ [FILE_REF_PROP]: newFilePath,
71526
+ [VAL_EXTENSION]: "file",
71527
+ metadata
71528
+ },
71529
+ op: "replace",
71530
+ path
71531
+ },
71532
+ {
71533
+ value: data,
71534
+ op: "file",
71535
+ path,
71536
+ filePath: newFilePath
71271
71537
  }
71272
- );
71273
- };
71274
- const TextIcon$1 = TextIcon;
71275
- function Tree({ children, rootPath }) {
71276
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col w-full py-2 text-xs", children: React$3.Children.map(children, (child) => {
71277
- return React$3.cloneElement(child, {
71278
- paths: [rootPath]
71279
- });
71280
- }) });
71538
+ ];
71281
71539
  }
71282
- Tree.Node = ({
71283
- children,
71284
- paths = [],
71540
+ function ImageField({
71285
71541
  path,
71286
- level = 1,
71287
- type,
71288
- setActivePath
71289
- }) => {
71290
- const paddingLeft = level * 30;
71291
- const logo = type === "string" ? /* @__PURE__ */ jsxRuntime.jsx(TextIcon$1, {}) : type === "image" ? /* @__PURE__ */ jsxRuntime.jsx(ImageIcon$1, { className: "h-[9px] w-[9px]" }) : /* @__PURE__ */ jsxRuntime.jsx(Section$1, {});
71292
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
71293
- /* @__PURE__ */ jsxRuntime.jsx(
71294
- "button",
71542
+ defaultValue,
71543
+ onSubmit,
71544
+ registerPatchCallback
71545
+ }) {
71546
+ const [data, setData] = React$3.useState(
71547
+ null
71548
+ );
71549
+ const [loading, setLoading] = React$3.useState(false);
71550
+ const [metadata, setMetadata] = React$3.useState();
71551
+ const [url, setUrl] = React$3.useState();
71552
+ React$3.useEffect(() => {
71553
+ setUrl(defaultValue && Internal.convertFileSource(defaultValue).url);
71554
+ }, [defaultValue]);
71555
+ React$3.useEffect(() => {
71556
+ if (registerPatchCallback) {
71557
+ registerPatchCallback(async (path2) => {
71558
+ return createImagePatch(
71559
+ path2,
71560
+ (data == null ? void 0 : data.src) ?? null,
71561
+ (data == null ? void 0 : data.filename) ?? null,
71562
+ metadata
71563
+ );
71564
+ });
71565
+ }
71566
+ }, [data, defaultValue]);
71567
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-4xl p-4", children: [
71568
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: `img_input:${path}`, className: "", children: [
71569
+ data || url ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: (data == null ? void 0 : data.src) || url }) : /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Empty" }),
71570
+ /* @__PURE__ */ jsxRuntime.jsx(
71571
+ "input",
71572
+ {
71573
+ id: `img_input:${path}`,
71574
+ type: "file",
71575
+ hidden: true,
71576
+ onChange: (ev) => {
71577
+ readImage(ev).then((res) => {
71578
+ setData({ src: res.src, filename: res.filename });
71579
+ if (res.width && res.height) {
71580
+ setMetadata({
71581
+ sha256: res.sha256,
71582
+ width: res.width,
71583
+ height: res.height
71584
+ });
71585
+ } else {
71586
+ setMetadata(void 0);
71587
+ }
71588
+ }).catch((err2) => {
71589
+ console.error(err2.message);
71590
+ setData(null);
71591
+ setMetadata(void 0);
71592
+ });
71593
+ }
71594
+ }
71595
+ )
71596
+ ] }),
71597
+ onSubmit && /* @__PURE__ */ jsxRuntime.jsx("div", { children: data && /* @__PURE__ */ jsxRuntime.jsx(
71598
+ Button,
71295
71599
  {
71296
- className: "flex justify-between w-full group py-2 text-xs font-[400] shrink-0",
71600
+ disabled: loading,
71297
71601
  onClick: () => {
71298
- setActivePath && setActivePath(path);
71602
+ setLoading(true);
71603
+ onSubmit(
71604
+ (path2) => Promise.resolve(
71605
+ createImagePatch(
71606
+ path2,
71607
+ data.src,
71608
+ data.filename ?? null,
71609
+ metadata
71610
+ )
71611
+ )
71612
+ ).finally(() => {
71613
+ setLoading(false);
71614
+ setData(null);
71615
+ setMetadata(void 0);
71616
+ });
71299
71617
  },
71300
- style: { paddingLeft },
71301
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2", children: [
71302
- logo,
71303
- /* @__PURE__ */ jsxRuntime.jsx("p", { children: path })
71304
- ] })
71618
+ children: loading ? "Saving..." : "Save"
71305
71619
  }
71306
- ),
71307
- children && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: React$3.Children.map(children, (child) => {
71308
- return React$3.cloneElement(child, {
71309
- level: level + 1,
71310
- paths: [...paths, path]
71311
- });
71312
- }) })
71313
- ] });
71314
- };
71315
- const Logo = ({ className: className2 }) => {
71316
- return /* @__PURE__ */ jsxRuntime.jsxs(
71317
- "svg",
71620
+ ) })
71621
+ ] }, path);
71622
+ }
71623
+ async function createRichTextPatch(path, editor) {
71624
+ const { templateStrings, exprs, files } = editor ? await lexicalToRichTextSource(
71625
+ editor.getEditorState().toJSON().root
71626
+ ) : {
71627
+ [VAL_EXTENSION]: "richtext",
71628
+ templateStrings: [""],
71629
+ exprs: [],
71630
+ files: {}
71631
+ };
71632
+ return [
71318
71633
  {
71319
- width: "58",
71320
- height: "34",
71321
- viewBox: "0 0 58 34",
71322
- fill: "none",
71323
- xmlns: "http://www.w3.org/2000/svg",
71324
- className: className2,
71325
- children: [
71326
- /* @__PURE__ */ jsxRuntime.jsx("g", { filter: "url(#filter0_d_21_1677)", children: /* @__PURE__ */ jsxRuntime.jsx(
71327
- "path",
71328
- {
71329
- d: "M5 5.36426C5 5.16309 5.16309 5 5.36426 5H17.6581C17.8593 5 18.0223 5.16309 18.0223 5.36426V28.4949C18.0223 28.696 17.8593 28.8591 17.6581 28.8591H5.36426C5.16309 28.8591 5 28.696 5 28.4949V5.36426Z",
71330
- fill: "#38CD98"
71634
+ op: "replace",
71635
+ path,
71636
+ value: {
71637
+ templateStrings,
71638
+ exprs,
71639
+ [VAL_EXTENSION]: "richtext"
71640
+ }
71641
+ },
71642
+ ...Object.entries(files).map(([filePath, value]) => {
71643
+ return {
71644
+ op: "file",
71645
+ path,
71646
+ filePath,
71647
+ value
71648
+ };
71649
+ })
71650
+ ];
71651
+ }
71652
+ function RichTextField({
71653
+ defaultValue,
71654
+ onSubmit,
71655
+ registerPatchCallback
71656
+ }) {
71657
+ const [editor, setEditor] = React$3.useState(null);
71658
+ const [didChange, setDidChange] = React$3.useState(false);
71659
+ const [loading, setLoading] = React$3.useState(false);
71660
+ React$3.useEffect(() => {
71661
+ if (editor) {
71662
+ setDidChange(false);
71663
+ editor.registerTextContentListener(() => {
71664
+ setDidChange(true);
71665
+ });
71666
+ editor.registerDecoratorListener(() => {
71667
+ setDidChange(true);
71668
+ });
71669
+ }
71670
+ }, [editor]);
71671
+ React$3.useEffect(() => {
71672
+ if (editor && registerPatchCallback) {
71673
+ registerPatchCallback((path) => createRichTextPatch(path, editor));
71674
+ }
71675
+ }, [editor]);
71676
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 border rounded border-card", children: [
71677
+ /* @__PURE__ */ jsxRuntime.jsx(
71678
+ RichTextEditor,
71679
+ {
71680
+ onEditor: (editor2) => {
71681
+ setEditor(editor2);
71682
+ },
71683
+ richtext: defaultValue || {
71684
+ children: [],
71685
+ [VAL_EXTENSION]: "root"
71686
+ }
71687
+ }
71688
+ ),
71689
+ onSubmit && /* @__PURE__ */ jsxRuntime.jsx("div", { children: didChange && /* @__PURE__ */ jsxRuntime.jsx(
71690
+ Button,
71691
+ {
71692
+ disabled: loading || !editor,
71693
+ onClick: () => {
71694
+ if (editor) {
71695
+ setLoading(true);
71696
+ onSubmit((path) => createRichTextPatch(path, editor)).finally(
71697
+ () => {
71698
+ setLoading(false);
71699
+ setDidChange(false);
71700
+ }
71701
+ );
71331
71702
  }
71332
- ) }),
71333
- /* @__PURE__ */ jsxRuntime.jsx("g", { filter: "url(#filter1_i_21_1677)", children: /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11.4656", cy: "23.7595", r: "2.18557", fill: "currentColor" }) }),
71334
- /* @__PURE__ */ jsxRuntime.jsx(
71335
- "path",
71703
+ },
71704
+ children: loading ? "Saving..." : "Save"
71705
+ }
71706
+ ) })
71707
+ ] });
71708
+ }
71709
+ function KeyOfField({
71710
+ disabled,
71711
+ defaultValue,
71712
+ registerPatchCallback,
71713
+ onSubmit,
71714
+ selector
71715
+ }) {
71716
+ const valModule = useValModuleFromPath(selector);
71717
+ const getValuesFromModule = (module2) => {
71718
+ if (Array.isArray(module2.moduleSource)) {
71719
+ return {
71720
+ type: "number",
71721
+ values: Object.keys(module2.moduleSource).map((key) => parseInt(key))
71722
+ };
71723
+ }
71724
+ return {
71725
+ type: "string",
71726
+ values: Object.keys(module2.moduleSource ?? ["ERROR fetching source"])
71727
+ };
71728
+ };
71729
+ const typeAndValues = getValuesFromModule(valModule);
71730
+ const [value, setValue] = React$3.useState(defaultValue || typeAndValues.values[0]);
71731
+ const [loading, setLoading] = React$3.useState(false);
71732
+ React$3.useEffect(() => {
71733
+ setLoading(disabled);
71734
+ }, [disabled]);
71735
+ const parse2 = (value2) => {
71736
+ if (typeAndValues.type === "number") {
71737
+ if (value2 === "") {
71738
+ throw new Error("Value cannot be empty");
71739
+ }
71740
+ if (Number.isNaN(Number(value2))) {
71741
+ throw new Error("Value was not a number: " + JSON.stringify(value2));
71742
+ }
71743
+ return Number(value2);
71744
+ }
71745
+ return value2;
71746
+ };
71747
+ React$3.useEffect(() => {
71748
+ if (registerPatchCallback) {
71749
+ registerPatchCallback(async (path) => {
71750
+ return [
71336
71751
  {
71337
- fillRule: "evenodd",
71338
- clipRule: "evenodd",
71339
- d: "M52.8588 23.839H48.7257H48.537H48.1128C47.6715 23.839 47.4508 23.5942 47.4508 23.1044V13.7293C47.4508 13.5784 47.3285 13.4561 47.1777 13.4561H45.8118C45.6609 13.4561 45.5386 13.5784 45.5386 13.7293V15.1836C45.5386 15.2844 45.4569 15.3661 45.3561 15.3661C45.2876 15.3661 45.225 15.3275 45.1924 15.2672C44.805 14.5503 44.283 14.02 43.6264 13.6765C42.9563 13.301 42.2045 13.1132 41.3709 13.1132C40.6028 13.1132 39.8755 13.252 39.189 13.5295C38.5026 13.8071 37.8979 14.2152 37.3748 14.7539C36.8682 15.2764 36.4678 15.9212 36.1736 16.6885C35.8794 17.4558 35.7323 18.3374 35.7323 19.3332V19.725C35.7323 20.7372 35.8794 21.627 36.1736 22.3942C36.4678 23.1615 36.8682 23.8146 37.3748 24.3533C37.8979 24.8757 38.5026 25.2757 39.189 25.5532C39.8755 25.8144 40.6191 25.945 41.42 25.945C42.1881 25.945 42.9154 25.7491 43.6019 25.3573C44.2751 24.982 44.8058 24.4119 45.1941 23.6471C45.2255 23.5852 45.2886 23.5452 45.358 23.5452H45.3917C45.4728 23.5452 45.5386 23.611 45.5386 23.6921C45.5386 23.7904 45.544 23.8856 45.5547 23.9777V25.1392C45.5547 25.3904 45.7584 25.5941 46.0096 25.5941H47.2261C47.2914 25.5995 47.3581 25.6022 47.4263 25.6022H48.537H48.7257H57.7268C57.8777 25.6022 58 25.4799 58 25.329V24.1122C58 23.9614 57.8777 23.839 57.7268 23.839H55.3174C55.1665 23.839 55.0442 23.7167 55.0442 23.5659V8.73368C55.0442 8.58279 54.9219 8.46048 54.771 8.46048H50.5054C50.3545 8.46048 50.2322 8.58279 50.2322 8.73368V9.95043C50.2322 10.1013 50.3545 10.2236 50.5054 10.2236H52.8588C53.0097 10.2236 53.132 10.3459 53.132 10.4968V23.5659C53.132 23.7167 53.0097 23.839 52.8588 23.839ZM41.6161 24.1329C42.1881 24.1329 42.7111 24.0268 43.1851 23.8146C43.6754 23.6023 44.0922 23.3003 44.4354 22.9085C44.7786 22.5167 45.0483 22.0514 45.2444 21.5127C45.4406 20.9576 45.5386 20.3454 45.5386 19.6761V19.3822C45.5386 18.7292 45.4406 18.1333 45.2444 17.5946C45.0483 17.0395 44.7705 16.5661 44.4109 16.1743C44.0677 15.7824 43.6509 15.4804 43.1606 15.2682C42.6866 15.0396 42.1718 14.9254 41.6161 14.9254C41.044 14.9254 40.521 15.0315 40.0471 15.2437C39.5731 15.4559 39.1563 15.758 38.7968 16.1498C38.4535 16.5252 38.1839 16.9905 37.9877 17.5456C37.7916 18.0843 37.6936 18.6802 37.6936 19.3332V19.725C37.6936 21.1127 38.0531 22.1983 38.7722 22.982C39.5077 23.7493 40.4557 24.1329 41.6161 24.1329ZM31.1115 25.4191C31.0732 25.5287 30.9698 25.6022 30.8536 25.6022H27.4661C27.35 25.6022 27.2465 25.5287 27.2082 25.4191L23.1578 13.8193C23.0958 13.6417 23.2276 13.4561 23.4157 13.4561H25.089C25.2068 13.4561 25.3114 13.5316 25.3484 13.6435L28.9666 24.581C28.9942 24.6643 29.0721 24.7206 29.1599 24.7206C29.2477 24.7206 29.3256 24.6643 29.3532 24.581L32.9714 13.6435C33.0084 13.5316 33.1129 13.4561 33.2308 13.4561H34.9041C35.0922 13.4561 35.224 13.6417 35.162 13.8193L31.1115 25.4191Z",
71340
- fill: "currentColor"
71752
+ op: "replace",
71753
+ path,
71754
+ value
71341
71755
  }
71342
- ),
71343
- /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
71344
- /* @__PURE__ */ jsxRuntime.jsxs(
71345
- "filter",
71346
- {
71347
- id: "filter0_d_21_1677",
71348
- x: "0.124722",
71349
- y: "0.124722",
71350
- width: "22.7729",
71351
- height: "33.6097",
71352
- filterUnits: "userSpaceOnUse",
71756
+ ];
71757
+ });
71758
+ }
71759
+ }, [value]);
71760
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col justify-between h-full gap-y-4", children: [
71761
+ /* @__PURE__ */ jsxRuntime.jsxs(
71762
+ Select,
71763
+ {
71764
+ defaultValue: value.toString(),
71765
+ disabled: loading,
71766
+ onValueChange: (value2) => {
71767
+ setValue(parse2(value2));
71768
+ },
71769
+ children: [
71770
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "Select a value" }) }),
71771
+ /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: typeAndValues.values.map((value2) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: value2.toString(), children: value2.toString() }, value2)) })
71772
+ ]
71773
+ }
71774
+ ),
71775
+ onSubmit && /* @__PURE__ */ jsxRuntime.jsx("div", { children: defaultValue !== value && /* @__PURE__ */ jsxRuntime.jsx(
71776
+ Button,
71777
+ {
71778
+ disabled: loading,
71779
+ onClick: () => {
71780
+ setLoading(true);
71781
+ onSubmit(async (path) => [
71782
+ {
71783
+ op: "replace",
71784
+ path,
71785
+ value
71786
+ }
71787
+ ]).finally(() => {
71788
+ setLoading(false);
71789
+ });
71790
+ },
71791
+ children: loading ? "Saving..." : "Save"
71792
+ }
71793
+ ) })
71794
+ ] });
71795
+ }
71796
+ function NumberField({
71797
+ disabled,
71798
+ defaultValue,
71799
+ registerPatchCallback,
71800
+ onSubmit
71801
+ }) {
71802
+ const [value, setValue] = React$3.useState(defaultValue || 0);
71803
+ const [loading, setLoading] = React$3.useState(false);
71804
+ React$3.useEffect(() => {
71805
+ setLoading(disabled);
71806
+ }, [disabled]);
71807
+ const ref = React$3.useRef(null);
71808
+ React$3.useEffect(() => {
71809
+ if (registerPatchCallback) {
71810
+ registerPatchCallback(async (path) => {
71811
+ var _a;
71812
+ return [
71813
+ {
71814
+ op: "replace",
71815
+ path,
71816
+ value: Number((_a = ref.current) == null ? void 0 : _a.value) || 0
71817
+ }
71818
+ ];
71819
+ });
71820
+ }
71821
+ }, []);
71822
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col justify-between h-full gap-y-4", children: [
71823
+ /* @__PURE__ */ jsxRuntime.jsx(
71824
+ Input,
71825
+ {
71826
+ ref,
71827
+ disabled: loading,
71828
+ defaultValue: value ?? 0,
71829
+ onChange: (e) => setValue(Number(e.target.value)),
71830
+ type: "number"
71831
+ }
71832
+ ),
71833
+ onSubmit && /* @__PURE__ */ jsxRuntime.jsx("div", { children: defaultValue !== value && /* @__PURE__ */ jsxRuntime.jsx(
71834
+ Button,
71835
+ {
71836
+ disabled: loading,
71837
+ onClick: () => {
71838
+ setLoading(true);
71839
+ onSubmit(async (path) => {
71840
+ var _a;
71841
+ return [
71842
+ {
71843
+ op: "replace",
71844
+ path,
71845
+ value: Number((_a = ref.current) == null ? void 0 : _a.value) || 0
71846
+ }
71847
+ ];
71848
+ }).finally(() => {
71849
+ setLoading(false);
71850
+ });
71851
+ },
71852
+ children: loading ? "Saving..." : "Save"
71853
+ }
71854
+ ) })
71855
+ ] });
71856
+ }
71857
+ function StringField({
71858
+ disabled,
71859
+ defaultValue,
71860
+ registerPatchCallback,
71861
+ onSubmit
71862
+ }) {
71863
+ const [value, setValue] = React$3.useState(defaultValue || "");
71864
+ const [loading, setLoading] = React$3.useState(false);
71865
+ React$3.useEffect(() => {
71866
+ setLoading(disabled);
71867
+ }, [disabled]);
71868
+ const ref = React$3.useRef(null);
71869
+ React$3.useEffect(() => {
71870
+ if (registerPatchCallback) {
71871
+ registerPatchCallback(async (path) => {
71872
+ var _a;
71873
+ return [
71874
+ {
71875
+ op: "replace",
71876
+ path,
71877
+ value: ((_a = ref.current) == null ? void 0 : _a.value) || ""
71878
+ }
71879
+ ];
71880
+ });
71881
+ }
71882
+ }, []);
71883
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col justify-between h-full gap-y-4", children: [
71884
+ /* @__PURE__ */ jsxRuntime.jsx(
71885
+ Input,
71886
+ {
71887
+ ref,
71888
+ disabled: loading,
71889
+ defaultValue: value ?? "",
71890
+ onChange: (e) => setValue(e.target.value)
71891
+ }
71892
+ ),
71893
+ onSubmit && /* @__PURE__ */ jsxRuntime.jsx("div", { children: defaultValue !== value && /* @__PURE__ */ jsxRuntime.jsx(
71894
+ Button,
71895
+ {
71896
+ disabled: loading,
71897
+ onClick: () => {
71898
+ setLoading(true);
71899
+ onSubmit(async (path) => {
71900
+ var _a;
71901
+ return [
71902
+ {
71903
+ op: "replace",
71904
+ path,
71905
+ value: ((_a = ref.current) == null ? void 0 : _a.value) || ""
71906
+ }
71907
+ ];
71908
+ }).finally(() => {
71909
+ setLoading(false);
71910
+ });
71911
+ },
71912
+ children: loading ? "Saving..." : "Save"
71913
+ }
71914
+ ) })
71915
+ ] });
71916
+ }
71917
+ const Logo = ({ className: className2 }) => {
71918
+ return /* @__PURE__ */ jsxRuntime.jsxs(
71919
+ "svg",
71920
+ {
71921
+ width: "58",
71922
+ height: "34",
71923
+ viewBox: "0 0 58 34",
71924
+ fill: "none",
71925
+ xmlns: "http://www.w3.org/2000/svg",
71926
+ className: className2,
71927
+ children: [
71928
+ /* @__PURE__ */ jsxRuntime.jsx("g", { filter: "url(#filter0_d_21_1677)", children: /* @__PURE__ */ jsxRuntime.jsx(
71929
+ "path",
71930
+ {
71931
+ d: "M5 5.36426C5 5.16309 5.16309 5 5.36426 5H17.6581C17.8593 5 18.0223 5.16309 18.0223 5.36426V28.4949C18.0223 28.696 17.8593 28.8591 17.6581 28.8591H5.36426C5.16309 28.8591 5 28.696 5 28.4949V5.36426Z",
71932
+ fill: "#38CD98"
71933
+ }
71934
+ ) }),
71935
+ /* @__PURE__ */ jsxRuntime.jsx("g", { filter: "url(#filter1_i_21_1677)", children: /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11.4656", cy: "23.7595", r: "2.18557", fill: "currentColor" }) }),
71936
+ /* @__PURE__ */ jsxRuntime.jsx(
71937
+ "path",
71938
+ {
71939
+ fillRule: "evenodd",
71940
+ clipRule: "evenodd",
71941
+ d: "M52.8588 23.839H48.7257H48.537H48.1128C47.6715 23.839 47.4508 23.5942 47.4508 23.1044V13.7293C47.4508 13.5784 47.3285 13.4561 47.1777 13.4561H45.8118C45.6609 13.4561 45.5386 13.5784 45.5386 13.7293V15.1836C45.5386 15.2844 45.4569 15.3661 45.3561 15.3661C45.2876 15.3661 45.225 15.3275 45.1924 15.2672C44.805 14.5503 44.283 14.02 43.6264 13.6765C42.9563 13.301 42.2045 13.1132 41.3709 13.1132C40.6028 13.1132 39.8755 13.252 39.189 13.5295C38.5026 13.8071 37.8979 14.2152 37.3748 14.7539C36.8682 15.2764 36.4678 15.9212 36.1736 16.6885C35.8794 17.4558 35.7323 18.3374 35.7323 19.3332V19.725C35.7323 20.7372 35.8794 21.627 36.1736 22.3942C36.4678 23.1615 36.8682 23.8146 37.3748 24.3533C37.8979 24.8757 38.5026 25.2757 39.189 25.5532C39.8755 25.8144 40.6191 25.945 41.42 25.945C42.1881 25.945 42.9154 25.7491 43.6019 25.3573C44.2751 24.982 44.8058 24.4119 45.1941 23.6471C45.2255 23.5852 45.2886 23.5452 45.358 23.5452H45.3917C45.4728 23.5452 45.5386 23.611 45.5386 23.6921C45.5386 23.7904 45.544 23.8856 45.5547 23.9777V25.1392C45.5547 25.3904 45.7584 25.5941 46.0096 25.5941H47.2261C47.2914 25.5995 47.3581 25.6022 47.4263 25.6022H48.537H48.7257H57.7268C57.8777 25.6022 58 25.4799 58 25.329V24.1122C58 23.9614 57.8777 23.839 57.7268 23.839H55.3174C55.1665 23.839 55.0442 23.7167 55.0442 23.5659V8.73368C55.0442 8.58279 54.9219 8.46048 54.771 8.46048H50.5054C50.3545 8.46048 50.2322 8.58279 50.2322 8.73368V9.95043C50.2322 10.1013 50.3545 10.2236 50.5054 10.2236H52.8588C53.0097 10.2236 53.132 10.3459 53.132 10.4968V23.5659C53.132 23.7167 53.0097 23.839 52.8588 23.839ZM41.6161 24.1329C42.1881 24.1329 42.7111 24.0268 43.1851 23.8146C43.6754 23.6023 44.0922 23.3003 44.4354 22.9085C44.7786 22.5167 45.0483 22.0514 45.2444 21.5127C45.4406 20.9576 45.5386 20.3454 45.5386 19.6761V19.3822C45.5386 18.7292 45.4406 18.1333 45.2444 17.5946C45.0483 17.0395 44.7705 16.5661 44.4109 16.1743C44.0677 15.7824 43.6509 15.4804 43.1606 15.2682C42.6866 15.0396 42.1718 14.9254 41.6161 14.9254C41.044 14.9254 40.521 15.0315 40.0471 15.2437C39.5731 15.4559 39.1563 15.758 38.7968 16.1498C38.4535 16.5252 38.1839 16.9905 37.9877 17.5456C37.7916 18.0843 37.6936 18.6802 37.6936 19.3332V19.725C37.6936 21.1127 38.0531 22.1983 38.7722 22.982C39.5077 23.7493 40.4557 24.1329 41.6161 24.1329ZM31.1115 25.4191C31.0732 25.5287 30.9698 25.6022 30.8536 25.6022H27.4661C27.35 25.6022 27.2465 25.5287 27.2082 25.4191L23.1578 13.8193C23.0958 13.6417 23.2276 13.4561 23.4157 13.4561H25.089C25.2068 13.4561 25.3114 13.5316 25.3484 13.6435L28.9666 24.581C28.9942 24.6643 29.0721 24.7206 29.1599 24.7206C29.2477 24.7206 29.3256 24.6643 29.3532 24.581L32.9714 13.6435C33.0084 13.5316 33.1129 13.4561 33.2308 13.4561H34.9041C35.0922 13.4561 35.224 13.6417 35.162 13.8193L31.1115 25.4191Z",
71942
+ fill: "currentColor"
71943
+ }
71944
+ ),
71945
+ /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
71946
+ /* @__PURE__ */ jsxRuntime.jsxs(
71947
+ "filter",
71948
+ {
71949
+ id: "filter0_d_21_1677",
71950
+ x: "0.124722",
71951
+ y: "0.124722",
71952
+ width: "22.7729",
71953
+ height: "33.6097",
71954
+ filterUnits: "userSpaceOnUse",
71353
71955
  colorInterpolationFilters: "sRGB",
71354
71956
  children: [
71355
71957
  /* @__PURE__ */ jsxRuntime.jsx("feFlood", { floodOpacity: "0", result: "BackgroundImageFix" }),
@@ -71993,36 +72595,6 @@ function useNavigateStable() {
71993
72595
  }
71994
72596
  new Promise(() => {
71995
72597
  });
71996
- function useTheme(defaultTheme = "dark") {
71997
- const [theme2, setTheme] = React$3.useState(defaultTheme);
71998
- React$3.useEffect(() => {
71999
- if (localStorage.getItem("val-theme") === "light") {
72000
- setTheme("light");
72001
- } else if (localStorage.getItem("val-theme") === "dark") {
72002
- setTheme("dark");
72003
- } else if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
72004
- setTheme("dark");
72005
- } else if (window.matchMedia && window.matchMedia("(prefers-color-scheme: light)").matches) {
72006
- setTheme("light");
72007
- }
72008
- const themeListener = (e) => {
72009
- if (!localStorage.getItem("val-theme")) {
72010
- setTheme(e.matches ? "dark" : "light");
72011
- }
72012
- };
72013
- window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", themeListener);
72014
- return () => {
72015
- window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", themeListener);
72016
- };
72017
- }, []);
72018
- return [
72019
- theme2,
72020
- (theme22) => {
72021
- localStorage.setItem("val-theme", theme22);
72022
- setTheme(theme22);
72023
- }
72024
- ];
72025
- }
72026
72598
  const ValModulesContext = React$3.createContext(null);
72027
72599
  const useValModuleFromPath = (sourcePath) => {
72028
72600
  var _a, _b;
@@ -72212,1356 +72784,766 @@ Showing stack trace of: 0. ${fatalErrors[0].message}`;
72212
72784
  ] }),
72213
72785
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4", children: [
72214
72786
  error && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-lg text-destructive-foreground", children: [
72215
- "ERROR: ",
72216
- error
72217
- ] }),
72218
- modules && selectedPath && selectedModuleId && moduleSource !== void 0 && moduleSchema !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(ValModulesContext.Provider, { value: modules, children: /* @__PURE__ */ jsxRuntime.jsx(
72219
- ValModule,
72220
- {
72221
- path: selectedPath,
72222
- source: moduleSource,
72223
- schema: moduleSchema,
72224
- setSelectedPath,
72225
- initOnSubmit
72226
- }
72227
- ) })
72228
- ] })
72229
- ] }) })
72230
- }
72231
- )
72232
- ]
72233
- }
72234
- )
72235
- }
72236
- );
72237
- };
72238
- const ValFullscreenHoverContext = React$3.createContext({
72239
- hoverElem: null
72240
- });
72241
- const useValFullscreenHover = () => {
72242
- return React$3.useContext(ValFullscreenHoverContext);
72243
- };
72244
- function ValModule({
72245
- path,
72246
- source: moduleSource,
72247
- schema: moduleSchema,
72248
- setSelectedPath,
72249
- initOnSubmit
72250
- }) {
72251
- const [, modulePath] = Internal.splitModuleIdAndModulePath(
72252
- path
72253
- );
72254
- const resolvedPath = Internal.resolvePath(
72255
- modulePath,
72256
- moduleSource,
72257
- moduleSchema
72258
- );
72259
- if (!resolvedPath) {
72260
- throw Error("Could not resolve module: " + path);
72261
- }
72262
- return /* @__PURE__ */ jsxRuntime.jsx(
72263
- AnyVal,
72264
- {
72265
- path,
72266
- source: resolvedPath.source,
72267
- schema: resolvedPath.schema,
72268
- setSelectedPath,
72269
- initOnSubmit,
72270
- top: true
72271
- }
72272
- );
72273
- }
72274
- function AnyVal({
72275
- path,
72276
- source,
72277
- schema,
72278
- setSelectedPath,
72279
- field,
72280
- initOnSubmit,
72281
- top
72282
- }) {
72283
- if (source === null || schema.opt) {
72284
- return /* @__PURE__ */ jsxRuntime.jsx(
72285
- ValOptional,
72286
- {
72287
- path,
72288
- source,
72289
- schema,
72290
- field,
72291
- initOnSubmit,
72292
- setSelectedPath
72293
- }
72294
- );
72295
- }
72296
- if (schema.type === "object") {
72297
- if (typeof source !== "object" || isJsonArray(source)) {
72298
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
72299
- "ERROR: expected object, but found ",
72300
- typeof source
72301
- ] });
72302
- }
72303
- return /* @__PURE__ */ jsxRuntime.jsx(
72304
- ValObject,
72305
- {
72306
- source,
72307
- path,
72308
- schema,
72309
- initOnSubmit,
72310
- setSelectedPath,
72311
- top
72312
- }
72313
- );
72314
- } else if (schema.type === "array") {
72315
- if (typeof source !== "object" || !isJsonArray(source)) {
72316
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
72317
- "ERROR: expected array, but found ",
72318
- typeof source
72319
- ] });
72320
- }
72321
- return /* @__PURE__ */ jsxRuntime.jsx(
72322
- ValList,
72323
- {
72324
- source,
72325
- path,
72326
- schema,
72327
- setSelectedPath
72328
- }
72329
- );
72330
- } else if (schema.type === "record") {
72331
- if (typeof source !== "object") {
72332
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
72333
- "ERROR: expected object for ",
72334
- schema.type,
72335
- ", but found ",
72336
- typeof source
72337
- ] });
72338
- }
72339
- if (isJsonArray(source)) {
72340
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
72341
- "ERROR: did not expect array for ",
72342
- schema.type
72343
- ] });
72344
- }
72345
- return /* @__PURE__ */ jsxRuntime.jsx(
72346
- ValRecord,
72347
- {
72348
- source,
72349
- path,
72350
- schema,
72351
- setSelectedPath
72352
- }
72353
- );
72354
- }
72355
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-2 gap-y-4", children: [
72356
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-left", children: field || path }),
72357
- /* @__PURE__ */ jsxRuntime.jsx(
72358
- ValFormField,
72359
- {
72360
- path,
72361
- disabled: false,
72362
- source,
72363
- schema,
72364
- onSubmit: initOnSubmit(path)
72365
- }
72366
- )
72367
- ] });
72368
- }
72369
- function ValObject({
72370
- path,
72371
- source,
72372
- schema,
72373
- setSelectedPath,
72374
- initOnSubmit,
72375
- top
72376
- }) {
72377
- return /* @__PURE__ */ jsxRuntime.jsx(
72378
- "div",
72379
- {
72380
- className: classNames("flex flex-col gap-y-8", {
72381
- "border-l-2 border-border pl-6": !top
72382
- }),
72383
- children: Object.entries(schema.items).map(([key, property]) => {
72384
- const subPath = createValPathOfItem(path, key);
72385
- return /* @__PURE__ */ jsxRuntime.jsx(
72386
- AnyVal,
72387
- {
72388
- path: subPath,
72389
- source: source[key],
72390
- schema: property,
72391
- setSelectedPath,
72392
- field: key,
72393
- initOnSubmit
72394
- },
72395
- subPath
72396
- );
72397
- })
72398
- },
72399
- path
72400
- );
72401
- }
72402
- function ValRecord({
72403
- path,
72404
- source,
72405
- schema,
72406
- setSelectedPath
72407
- }) {
72408
- const navigate = useNavigate();
72409
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 p-2", children: Object.entries(source).map(([key, item]) => {
72410
- const subPath = createValPathOfItem(path, key);
72411
- return /* @__PURE__ */ jsxRuntime.jsx(
72412
- "button",
72413
- {
72414
- onClick: () => {
72415
- setSelectedPath(subPath);
72416
- navigate(subPath);
72417
- },
72418
- children: /* @__PURE__ */ jsxRuntime.jsx(
72419
- ValRecordItem,
72420
- {
72421
- recordKey: key,
72422
- path: subPath,
72423
- source: item,
72424
- schema: schema.item
72425
- }
72426
- )
72427
- },
72428
- subPath
72429
- );
72430
- }) }, path);
72431
- }
72432
- const RECORD_ITEM_MAX_HEIGHT = 170;
72433
- function ValRecordItem({
72434
- recordKey,
72435
- path,
72436
- source,
72437
- schema
72438
- }) {
72439
- const ref = React$3.useRef(null);
72440
- const [isTruncated, setIsTruncated] = React$3.useState(false);
72441
- React$3.useEffect(() => {
72442
- if (ref.current) {
72443
- const height2 = ref.current.getBoundingClientRect().height;
72444
- if (height2 >= RECORD_ITEM_MAX_HEIGHT) {
72445
- setIsTruncated(true);
72446
- }
72447
- }
72448
- }, []);
72449
- return /* @__PURE__ */ jsxRuntime.jsxs(
72450
- Card,
72451
- {
72452
- ref,
72453
- className: "relative px-4 pt-2 pb-4 overflow-hidden border gap-y-2",
72454
- style: {
72455
- maxHeight: RECORD_ITEM_MAX_HEIGHT
72456
- },
72457
- children: [
72458
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pb-4 font-serif text-left text-accent", children: recordKey }),
72459
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs", children: /* @__PURE__ */ jsxRuntime.jsx(ValPreview, { path, source, schema }) }),
72460
- isTruncated && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 left-0 w-full h-[20px] bg-gradient-to-b from-transparent to-background" })
72461
- ]
72462
- },
72463
- path
72464
- );
72465
- }
72466
- function ValList({
72467
- path,
72468
- source,
72469
- schema,
72470
- setSelectedPath
72471
- }) {
72472
- const navigate = useNavigate();
72473
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 p-2", children: source.map((item, index2) => {
72474
- const subPath = createValPathOfItem(path, index2);
72475
- return /* @__PURE__ */ jsxRuntime.jsx(
72476
- "button",
72477
- {
72478
- onClick: () => {
72479
- setSelectedPath(subPath);
72480
- navigate(subPath);
72481
- },
72482
- children: /* @__PURE__ */ jsxRuntime.jsx(
72483
- ValListItem,
72484
- {
72485
- index: index2,
72486
- path: subPath,
72487
- source: item,
72488
- schema: schema.item
72489
- },
72490
- subPath
72491
- )
72492
- },
72493
- subPath
72494
- );
72495
- }) }, path);
72496
- }
72497
- const LIST_ITEM_MAX_HEIGHT = RECORD_ITEM_MAX_HEIGHT;
72498
- function ValListItem({
72499
- index: index2,
72500
- path,
72501
- source,
72502
- schema
72503
- }) {
72504
- const ref = React$3.useRef(null);
72505
- const [isTruncated, setIsTruncated] = React$3.useState(false);
72506
- React$3.useEffect(() => {
72507
- if (ref.current) {
72508
- const height2 = ref.current.getBoundingClientRect().height;
72509
- if (height2 >= LIST_ITEM_MAX_HEIGHT) {
72510
- setIsTruncated(true);
72511
- }
72512
- }
72513
- }, []);
72514
- return /* @__PURE__ */ jsxRuntime.jsxs(
72515
- Card,
72516
- {
72517
- ref,
72518
- className: "relative px-4 pt-2 pb-4 overflow-hidden border gap-y-2",
72519
- style: {
72520
- maxHeight: LIST_ITEM_MAX_HEIGHT
72521
- },
72522
- children: [
72523
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pb-4 font-serif text-left uppercase text-accent", children: index2 + 1 < 10 ? `0${index2 + 1}` : index2 + 1 }),
72524
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs", children: /* @__PURE__ */ jsxRuntime.jsx(ValPreview, { path, source, schema }) }),
72525
- isTruncated && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 left-0 w-full h-[20px] bg-gradient-to-b from-transparent to-background" })
72526
- ]
72527
- }
72528
- );
72529
- }
72530
- function createValPathOfItem(arrayPath, prop) {
72531
- const val = Internal.createValPathOfItem(arrayPath, prop);
72532
- if (!val) {
72533
- throw Error(
72534
- `Could not create val path: ${arrayPath} of ${prop == null ? void 0 : prop.toString()}`
72535
- );
72536
- }
72537
- return val;
72538
- }
72539
- function ValPreview({
72540
- path,
72541
- source,
72542
- schema
72543
- }) {
72544
- const [isMouseOver, setIsMouseOver] = React$3.useState(null);
72545
- const { hoverElem } = useValFullscreenHover();
72546
- if (schema.type === "object") {
72547
- return /* @__PURE__ */ jsxRuntime.jsx(
72548
- "div",
72549
- {
72550
- className: "grid grid-cols-[min-content_1fr] gap-2 text-left",
72551
- children: Object.entries(schema.items).map(([key]) => {
72552
- return /* @__PURE__ */ jsxRuntime.jsxs(React$3.Fragment, { children: [
72553
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted", children: [
72554
- key,
72555
- ":"
72556
- ] }),
72557
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: /* @__PURE__ */ jsxRuntime.jsx(
72558
- ValPreview,
72559
- {
72560
- source: (source == null ? void 0 : source[key]) ?? null,
72561
- schema: schema.items[key],
72562
- path: createValPathOfItem(path, key)
72563
- }
72564
- ) })
72565
- ] }, createValPathOfItem(path, key));
72566
- })
72567
- },
72568
- path
72569
- );
72570
- } else if (schema.type === "array") {
72571
- if (source === null) {
72572
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: "Empty" }, path);
72573
- }
72574
- if (Array.isArray(source)) {
72575
- return /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
72576
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: source.length }),
72577
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: source.length === 1 ? " item" : " items" })
72578
- ] }, path);
72579
- }
72580
- return /* @__PURE__ */ jsxRuntime.jsx(
72581
- "span",
72582
- {
72583
- className: "px-2 bg-destructive text-destructive-foreground",
72584
- children: "Unknown length"
72585
- },
72586
- path
72587
- );
72588
- } else if (schema.type === "richtext") {
72589
- if (source === null) {
72590
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: "Empty" }, path);
72591
- }
72592
- if (typeof source !== "object") {
72593
- return /* @__PURE__ */ jsxRuntime.jsxs(
72594
- "div",
72595
- {
72596
- className: "p-4 text-destructive-foreground bg-destructive",
72597
- children: [
72598
- "ERROR: ",
72599
- typeof source,
72600
- " not an object"
72601
- ]
72602
- },
72603
- path
72604
- );
72605
- }
72606
- if (!(VAL_EXTENSION in source) || source[VAL_EXTENSION] !== "richtext") {
72607
- return /* @__PURE__ */ jsxRuntime.jsx(
72608
- "div",
72609
- {
72610
- className: "p-4 text-destructive-foreground bg-destructive",
72611
- children: "ERROR: object is not richtext"
72612
- },
72613
- path
72614
- );
72615
- }
72616
- return /* @__PURE__ */ jsxRuntime.jsx(ValRichText, { children: parseRichTextSource(source) }, path);
72617
- } else if (schema.type === "string") {
72618
- if (source === null) {
72619
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: "Empty" }, path);
72620
- }
72621
- return /* @__PURE__ */ jsxRuntime.jsx("span", { children: source });
72622
- } else if (schema.type === "image") {
72623
- if (source === null) {
72624
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: "Empty" }, path);
72625
- }
72626
- if (typeof source !== "object") {
72627
- return /* @__PURE__ */ jsxRuntime.jsx(
72628
- "div",
72629
- {
72630
- className: "p-4 text-destructive-foreground bg-destructive",
72631
- children: "ERROR: not an object"
72632
- },
72633
- path
72634
- );
72635
- }
72636
- if (!(FILE_REF_PROP in source) || typeof source[FILE_REF_PROP] !== "string") {
72637
- return /* @__PURE__ */ jsxRuntime.jsx(
72638
- "div",
72639
- {
72640
- className: "p-4 text-destructive-foreground bg-destructive",
72641
- children: "ERROR: object is not an image"
72642
- },
72643
- path
72644
- );
72645
- }
72646
- const url = Internal.convertFileSource(
72647
- source
72648
- ).url;
72649
- return /* @__PURE__ */ jsxRuntime.jsxs(
72650
- "span",
72651
- {
72652
- onMouseOver: (ev) => {
72653
- setIsMouseOver({
72654
- x: ev.clientX,
72655
- y: ev.clientY
72656
- });
72657
- },
72658
- onMouseLeave: () => {
72659
- setIsMouseOver(null);
72660
- },
72661
- className: "relative flex items-center justify-start gap-1",
72662
- children: [
72663
- /* @__PURE__ */ jsxRuntime.jsx("a", { href: url, className: "overflow-hidden underline truncate ", children: source[FILE_REF_PROP] }),
72664
- isMouseOver && hoverElem && reactDomExports.createPortal(
72665
- /* @__PURE__ */ jsxRuntime.jsx(
72666
- "img",
72667
- {
72668
- className: "absolute z-[5] max-w-[10vw]",
72669
- style: {
72670
- left: isMouseOver.x + 10,
72671
- top: isMouseOver.y + 10
72672
- },
72673
- src: url
72674
- }
72675
- ),
72676
- hoverElem
72677
- )
72678
- ]
72679
- },
72680
- path
72681
- );
72682
- } else if (schema.type === "boolean") {
72683
- if (source === null) {
72684
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: "Empty" }, path);
72685
- }
72686
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: source ? "true" : "false" }, path);
72687
- } else if (schema.type === "number") {
72688
- if (source === null) {
72689
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: "Empty" }, path);
72690
- }
72691
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: source.toString() });
72692
- } else if (schema.type === "keyOf") {
72693
- if (source === null) {
72694
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: "Empty" }, path);
72695
- }
72696
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: source.toString() }, path);
72697
- }
72698
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
72699
- "TODO: ",
72700
- schema.type
72701
- ] }, path);
72702
- }
72703
- function ValOptional({
72704
- path,
72705
- source,
72706
- schema,
72707
- setSelectedPath,
72708
- initOnSubmit,
72709
- field
72710
- }) {
72711
- const [enable, setEnable] = React$3.useState(source !== null);
72712
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
72713
- field ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-start gap-x-4", children: [
72714
- /* @__PURE__ */ jsxRuntime.jsx(
72715
- Switch,
72716
- {
72717
- checked: enable,
72718
- onClick: () => {
72719
- setEnable((prev) => !prev);
72720
- }
72721
- }
72722
- ),
72723
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: field })
72724
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(
72725
- Switch,
72726
- {
72727
- checked: enable,
72728
- onClick: () => {
72729
- setEnable((prev) => !prev);
72730
- }
72731
- }
72732
- ),
72733
- enable && /* @__PURE__ */ jsxRuntime.jsx(
72734
- ValDefaultOf,
72735
- {
72736
- source,
72737
- schema,
72738
- path,
72739
- setSelectedPath,
72740
- initOnSubmit
72741
- }
72742
- )
72743
- ] }, path);
72744
- }
72745
- function ValDefaultOf({
72746
- source,
72747
- path,
72748
- schema,
72749
- setSelectedPath,
72750
- initOnSubmit
72751
- }) {
72752
- if (schema.type === "array") {
72753
- if (typeof source === "object" && (source === null || isJsonArray(source))) {
72754
- return /* @__PURE__ */ jsxRuntime.jsx(
72755
- ValList,
72756
- {
72757
- source: source === null ? [] : source,
72758
- path,
72759
- schema,
72760
- setSelectedPath
72761
- }
72762
- );
72763
- }
72764
- } else if (schema.type === "object") {
72765
- if (typeof source === "object" && (source === null || !isJsonArray(source))) {
72766
- return /* @__PURE__ */ jsxRuntime.jsx(
72767
- ValObject,
72768
- {
72769
- source,
72770
- path,
72771
- schema,
72772
- setSelectedPath,
72773
- initOnSubmit
72774
- }
72775
- );
72776
- }
72777
- } else if (schema.type === "richtext" || schema.type === "string" || schema.type === "image" || schema.type === "number" || schema.type === "keyOf") {
72778
- return /* @__PURE__ */ jsxRuntime.jsx(
72779
- ValFormField,
72780
- {
72781
- path,
72782
- disabled: false,
72783
- source,
72784
- schema,
72785
- onSubmit: initOnSubmit(path)
72786
- },
72787
- path
72788
- );
72789
- }
72790
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 bg-destructive text-destructive-foreground", children: [
72791
- "ERROR: unexpected source type ",
72792
- typeof source,
72793
- " for schema type",
72794
- " ",
72795
- schema.type
72796
- ] });
72797
- }
72798
- function isJsonArray(source) {
72799
- return Array.isArray(source);
72800
- }
72801
- function pathsToTree(paths) {
72802
- const tree = {};
72803
- paths.forEach((path) => {
72804
- const parts = path.split("/").filter((part) => part !== "");
72805
- let current = tree;
72806
- parts.forEach((part) => {
72807
- if (!current[part]) {
72808
- current[part] = {};
72809
- }
72810
- current = current[part];
72811
- });
72812
- });
72813
- return tree;
72814
- }
72815
- function PathTree({
72816
- paths,
72817
- setSelectedModuleId
72818
- }) {
72819
- const tree = pathsToTree(paths);
72820
- return /* @__PURE__ */ jsxRuntime.jsx(Tree, { children: Object.entries(tree).map(([name, subTree]) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(
72821
- PathNode,
72822
- {
72823
- name,
72824
- tree: subTree,
72825
- moduleId: `/${name}`,
72826
- setSelectedModuleId
72827
- }
72828
- ) }, `/${name}`)) });
72829
- }
72830
- function PathNode({
72831
- name,
72832
- tree,
72833
- moduleId,
72834
- setSelectedModuleId
72835
- }) {
72836
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
72837
- /* @__PURE__ */ jsxRuntime.jsx(
72838
- "button",
72839
- {
72840
- onClick: () => {
72841
- setSelectedModuleId(moduleId);
72842
- },
72843
- children: name
72844
- }
72845
- ),
72846
- Object.entries(tree).map(([childName, childTree]) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-1", children: /* @__PURE__ */ jsxRuntime.jsx(
72847
- PathNode,
72848
- {
72849
- name: childName,
72850
- tree: childTree,
72851
- moduleId: `${moduleId}/${childName}`,
72852
- setSelectedModuleId
72853
- }
72854
- ) }, `${moduleId}/${childName}`))
72855
- ] });
72856
- }
72857
- const theme = {
72858
- tags: {
72859
- h1: "font-bold",
72860
- h2: "font-bold",
72861
- h3: "font-bold",
72862
- h4: "font-bold",
72863
- h5: "font-bold",
72864
- h6: "font-bold",
72865
- p: ""
72866
- },
72867
- classes: {
72868
- bold: "font-bold",
72869
- italic: "italic",
72870
- lineThrough: "line-through"
72871
- }
72872
- };
72873
- function ValRichText({
72874
- children
72875
- }) {
72876
- const root = children;
72877
- function withRenderTag(clazz, current) {
72878
- const renderClass = theme.tags[clazz];
72879
- if (renderClass && current) {
72880
- return [current, renderClass].join(" ");
72881
- }
72882
- if (renderClass) {
72883
- return renderClass;
72884
- }
72885
- return current;
72886
- }
72887
- function withRenderClass(clazz, current) {
72888
- const renderClass = theme.classes[clazz];
72889
- if (renderClass && current) {
72890
- return [current, renderClass].join(" ");
72891
- }
72892
- if (renderClass) {
72893
- return renderClass;
72894
- }
72895
- return current;
72896
- }
72897
- function toReact(node, key) {
72898
- var _a, _b;
72899
- if (typeof node === "string") {
72900
- return node;
72901
- }
72902
- if (node.tag === "p") {
72903
- return /* @__PURE__ */ jsxRuntime.jsx("p", { className: withRenderTag("p"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72904
- }
72905
- if (node.tag === "img") {
72906
- return /* @__PURE__ */ jsxRuntime.jsx("img", { className: withRenderTag("img"), src: node.src }, key);
72907
- }
72908
- if (node.tag === "ul") {
72909
- return /* @__PURE__ */ jsxRuntime.jsx("ul", { className: withRenderTag("ul"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72910
- }
72911
- if (node.tag === "ol") {
72912
- return /* @__PURE__ */ jsxRuntime.jsx("ol", { className: withRenderTag("ol"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72913
- }
72914
- if (node.tag === "li") {
72915
- return /* @__PURE__ */ jsxRuntime.jsx("li", { className: withRenderTag("li"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72916
- }
72917
- if (node.tag === "span") {
72918
- return /* @__PURE__ */ jsxRuntime.jsx(
72919
- "span",
72920
- {
72921
- className: node.classes.map((nodeClass) => {
72922
- switch (nodeClass) {
72923
- case "bold":
72924
- return withRenderClass("bold");
72925
- case "line-through":
72926
- return withRenderClass("lineThrough");
72927
- case "italic":
72928
- return withRenderClass("italic");
72929
- }
72930
- }).join(" "),
72931
- children: node.children.map((child, key2) => toReact(child, key2))
72932
- },
72933
- key
72934
- );
72935
- }
72936
- if (node.tag === "h1") {
72937
- return /* @__PURE__ */ jsxRuntime.jsx("h1", { className: withRenderTag("h1"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72938
- }
72939
- if (node.tag === "h2") {
72940
- return /* @__PURE__ */ jsxRuntime.jsx("h2", { className: withRenderTag("h2"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72941
- }
72942
- if (node.tag === "h3") {
72943
- return /* @__PURE__ */ jsxRuntime.jsx("h3", { className: withRenderTag("h3"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72944
- }
72945
- if (node.tag === "h4") {
72946
- return /* @__PURE__ */ jsxRuntime.jsx("h4", { className: withRenderTag("h4"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72947
- }
72948
- if (node.tag === "h5") {
72949
- return /* @__PURE__ */ jsxRuntime.jsx("h5", { className: withRenderTag("h5"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72950
- }
72951
- if (node.tag === "h6") {
72952
- return /* @__PURE__ */ jsxRuntime.jsx("h6", { className: withRenderTag("h6"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72953
- }
72954
- if (node.tag === "br") {
72955
- return /* @__PURE__ */ jsxRuntime.jsx("br", {}, key);
72956
- }
72957
- if (node.tag === "a") {
72958
- return /* @__PURE__ */ jsxRuntime.jsx("a", { href: node.href, children: node.children.map((child, key2) => toReact(child, key2)) }, key);
72959
- }
72960
- console.error("Unknown tag", node.tag);
72961
- const _exhaustiveCheck = node.tag;
72962
- const anyNode = _exhaustiveCheck;
72963
- if (!(anyNode == null ? void 0 : anyNode.tag)) {
72964
- return null;
72787
+ "ERROR: ",
72788
+ error
72789
+ ] }),
72790
+ modules && selectedPath && selectedModuleId && moduleSource !== void 0 && moduleSchema !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(ValModulesContext.Provider, { value: modules, children: /* @__PURE__ */ jsxRuntime.jsx(
72791
+ ValModule,
72792
+ {
72793
+ path: selectedPath,
72794
+ source: moduleSource,
72795
+ schema: moduleSchema,
72796
+ setSelectedPath,
72797
+ initOnSubmit
72798
+ }
72799
+ ) })
72800
+ ] })
72801
+ ] }) })
72802
+ }
72803
+ )
72804
+ ]
72805
+ }
72806
+ )
72965
72807
  }
72966
- return React$3.createElement(anyNode.tag, {
72967
- key,
72968
- className: (_a = anyNode.class) == null ? void 0 : _a.join(" "),
72969
- children: (_b = anyNode.children) == null ? void 0 : _b.map(toReact)
72970
- });
72808
+ );
72809
+ };
72810
+ const ValFullscreenHoverContext = React$3.createContext({
72811
+ hoverElem: null
72812
+ });
72813
+ const useValFullscreenHover = () => {
72814
+ return React$3.useContext(ValFullscreenHoverContext);
72815
+ };
72816
+ function ValModule({
72817
+ path,
72818
+ source: moduleSource,
72819
+ schema: moduleSchema,
72820
+ setSelectedPath,
72821
+ initOnSubmit
72822
+ }) {
72823
+ const [, modulePath] = Internal.splitModuleIdAndModulePath(
72824
+ path
72825
+ );
72826
+ const resolvedPath = Internal.resolvePath(
72827
+ modulePath,
72828
+ moduleSource,
72829
+ moduleSchema
72830
+ );
72831
+ if (!resolvedPath) {
72832
+ throw Error("Could not resolve module: " + path);
72971
72833
  }
72972
- return /* @__PURE__ */ jsxRuntime.jsx("span", { "data-val-path": root.valPath, children: root.children.map((child, i) => {
72973
- return toReact(child, i);
72974
- }) });
72834
+ return /* @__PURE__ */ jsxRuntime.jsx(
72835
+ AnyVal,
72836
+ {
72837
+ path,
72838
+ source: resolvedPath.source,
72839
+ schema: resolvedPath.schema,
72840
+ setSelectedPath,
72841
+ initOnSubmit,
72842
+ top: true
72843
+ }
72844
+ );
72975
72845
  }
72976
- function ValFormField({
72846
+ function AnyVal({
72977
72847
  path,
72978
- disabled,
72979
72848
  source,
72980
72849
  schema,
72981
- registerPatchCallback,
72982
- onSubmit
72850
+ setSelectedPath,
72851
+ field,
72852
+ initOnSubmit,
72853
+ top
72983
72854
  }) {
72984
- if ((typeof source === "string" || source === null) && (schema == null ? void 0 : schema.type) === "string") {
72985
- return /* @__PURE__ */ jsxRuntime.jsx(
72986
- StringField,
72987
- {
72988
- defaultValue: source,
72989
- disabled,
72990
- registerPatchCallback,
72991
- onSubmit
72992
- }
72993
- );
72994
- }
72995
- if ((typeof source === "number" || source === null) && (schema == null ? void 0 : schema.type) === "number") {
72996
- return /* @__PURE__ */ jsxRuntime.jsx(
72997
- NumberField,
72998
- {
72999
- defaultValue: source,
73000
- disabled,
73001
- registerPatchCallback,
73002
- onSubmit
73003
- }
73004
- );
73005
- }
73006
- if ((typeof source === "number" || typeof source === "string" || source === null) && (schema == null ? void 0 : schema.type) === "keyOf") {
72855
+ if (source === null || schema.opt) {
73007
72856
  return /* @__PURE__ */ jsxRuntime.jsx(
73008
- KeyOfField,
72857
+ ValOptional,
73009
72858
  {
73010
- defaultValue: source,
73011
- disabled,
73012
- registerPatchCallback,
73013
- onSubmit,
73014
- selector: schema.selector
72859
+ path,
72860
+ source,
72861
+ schema,
72862
+ field,
72863
+ initOnSubmit,
72864
+ setSelectedPath
73015
72865
  }
73016
72866
  );
73017
72867
  }
73018
- if ((typeof source === "number" || source === null) && (schema == null ? void 0 : schema.type) === "number") {
72868
+ if (schema.type === "object") {
72869
+ if (typeof source !== "object" || isJsonArray(source)) {
72870
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
72871
+ "ERROR: expected object, but found ",
72872
+ typeof source
72873
+ ] });
72874
+ }
73019
72875
  return /* @__PURE__ */ jsxRuntime.jsx(
73020
- NumberField,
72876
+ ValObject,
73021
72877
  {
73022
- defaultValue: source,
73023
- disabled,
73024
- registerPatchCallback,
73025
- onSubmit
72878
+ source,
72879
+ path,
72880
+ schema,
72881
+ initOnSubmit,
72882
+ setSelectedPath,
72883
+ top
73026
72884
  }
73027
72885
  );
73028
- }
73029
- if ((typeof source === "number" || typeof source === "string" || source === null) && (schema == null ? void 0 : schema.type) === "keyOf") {
72886
+ } else if (schema.type === "array") {
72887
+ if (typeof source !== "object" || !isJsonArray(source)) {
72888
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
72889
+ "ERROR: expected array, but found ",
72890
+ typeof source
72891
+ ] });
72892
+ }
73030
72893
  return /* @__PURE__ */ jsxRuntime.jsx(
73031
- KeyOfField,
72894
+ ValList,
73032
72895
  {
73033
- defaultValue: source,
73034
- disabled,
73035
- registerPatchCallback,
73036
- onSubmit,
73037
- selector: schema.selector
72896
+ source,
72897
+ path,
72898
+ schema,
72899
+ setSelectedPath
73038
72900
  }
73039
72901
  );
73040
- }
73041
- if ((typeof source === "object" || source === null) && (schema == null ? void 0 : schema.type) === "richtext") {
72902
+ } else if (schema.type === "record") {
72903
+ if (typeof source !== "object") {
72904
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
72905
+ "ERROR: expected object for ",
72906
+ schema.type,
72907
+ ", but found ",
72908
+ typeof source
72909
+ ] });
72910
+ }
72911
+ if (isJsonArray(source)) {
72912
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
72913
+ "ERROR: did not expect array for ",
72914
+ schema.type
72915
+ ] });
72916
+ }
73042
72917
  return /* @__PURE__ */ jsxRuntime.jsx(
73043
- RichTextField,
72918
+ ValRecord,
73044
72919
  {
73045
- registerPatchCallback,
73046
- onSubmit,
73047
- defaultValue: source
72920
+ source,
72921
+ path,
72922
+ schema,
72923
+ setSelectedPath
73048
72924
  }
73049
72925
  );
73050
72926
  }
73051
- if ((typeof source === "object" || source === null) && (schema == null ? void 0 : schema.type) === "image") {
73052
- return /* @__PURE__ */ jsxRuntime.jsx(
73053
- ImageField,
72927
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-2 gap-y-4", children: [
72928
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-left", children: field || path }),
72929
+ /* @__PURE__ */ jsxRuntime.jsx(
72930
+ ValFormField,
73054
72931
  {
73055
72932
  path,
73056
- registerPatchCallback,
73057
- onSubmit,
73058
- defaultValue: source
72933
+ disabled: false,
72934
+ source,
72935
+ schema,
72936
+ onSubmit: initOnSubmit(path)
73059
72937
  }
73060
- );
73061
- }
73062
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
73063
- "Unsupported schema: ",
73064
- schema.type
72938
+ )
73065
72939
  ] });
73066
72940
  }
73067
- function createImagePatch(path, data, filename, metadata) {
73068
- if (!data || !metadata) {
73069
- return [];
73070
- }
73071
- const shaSuffix = metadata.sha256.slice(0, 5);
73072
- const newFilePath = function() {
73073
- const mimeType = getMimeType(data) ?? "unknown";
73074
- const newExt = mimeTypeToFileExt(mimeType);
73075
- if (filename) {
73076
- const filenameWithoutExt = filename.split(".").slice(0, -1).join(".") || filename;
73077
- return `/public/${filenameWithoutExt}_${shaSuffix}.${newExt}`;
72941
+ function ValObject({
72942
+ path,
72943
+ source,
72944
+ schema,
72945
+ setSelectedPath,
72946
+ initOnSubmit,
72947
+ top
72948
+ }) {
72949
+ return /* @__PURE__ */ jsxRuntime.jsx(
72950
+ "div",
72951
+ {
72952
+ className: classNames("flex flex-col gap-y-8", {
72953
+ "border-l-2 border-border pl-6": !top
72954
+ }),
72955
+ children: Object.entries(schema.items).map(([key, property]) => {
72956
+ const subPath = createValPathOfItem(path, key);
72957
+ return /* @__PURE__ */ jsxRuntime.jsx(
72958
+ AnyVal,
72959
+ {
72960
+ path: subPath,
72961
+ source: source[key],
72962
+ schema: property,
72963
+ setSelectedPath,
72964
+ field: key,
72965
+ initOnSubmit
72966
+ },
72967
+ subPath
72968
+ );
72969
+ })
72970
+ },
72971
+ path
72972
+ );
72973
+ }
72974
+ function ValRecord({
72975
+ path,
72976
+ source,
72977
+ schema,
72978
+ setSelectedPath
72979
+ }) {
72980
+ const navigate = useNavigate();
72981
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 p-2", children: Object.entries(source).map(([key, item]) => {
72982
+ const subPath = createValPathOfItem(path, key);
72983
+ return /* @__PURE__ */ jsxRuntime.jsx(
72984
+ "button",
72985
+ {
72986
+ onClick: () => {
72987
+ setSelectedPath(subPath);
72988
+ navigate(subPath);
72989
+ },
72990
+ children: /* @__PURE__ */ jsxRuntime.jsx(
72991
+ ValRecordItem,
72992
+ {
72993
+ recordKey: key,
72994
+ path: subPath,
72995
+ source: item,
72996
+ schema: schema.item
72997
+ }
72998
+ )
72999
+ },
73000
+ subPath
73001
+ );
73002
+ }) }, path);
73003
+ }
73004
+ const RECORD_ITEM_MAX_HEIGHT = 170;
73005
+ function ValRecordItem({
73006
+ recordKey,
73007
+ path,
73008
+ source,
73009
+ schema
73010
+ }) {
73011
+ const ref = React$3.useRef(null);
73012
+ const [isTruncated, setIsTruncated] = React$3.useState(false);
73013
+ React$3.useEffect(() => {
73014
+ if (ref.current) {
73015
+ const height2 = ref.current.getBoundingClientRect().height;
73016
+ if (height2 >= RECORD_ITEM_MAX_HEIGHT) {
73017
+ setIsTruncated(true);
73018
+ }
73078
73019
  }
73079
- return `/public/${metadata.sha256}.${newExt}`;
73080
- }();
73081
- return [
73020
+ }, []);
73021
+ return /* @__PURE__ */ jsxRuntime.jsxs(
73022
+ Card,
73082
73023
  {
73083
- value: {
73084
- [FILE_REF_PROP]: newFilePath,
73085
- [VAL_EXTENSION]: "file",
73086
- metadata
73024
+ ref,
73025
+ className: "relative px-4 pt-2 pb-4 overflow-hidden border gap-y-2",
73026
+ style: {
73027
+ maxHeight: RECORD_ITEM_MAX_HEIGHT
73087
73028
  },
73088
- op: "replace",
73089
- path
73029
+ children: [
73030
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pb-4 font-serif text-left text-accent", children: recordKey }),
73031
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs", children: /* @__PURE__ */ jsxRuntime.jsx(ValPreview, { path, source, schema }) }),
73032
+ isTruncated && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 left-0 w-full h-[20px] bg-gradient-to-b from-transparent to-background" })
73033
+ ]
73090
73034
  },
73091
- {
73092
- value: data,
73093
- op: "file",
73094
- path,
73095
- filePath: newFilePath
73096
- }
73097
- ];
73035
+ path
73036
+ );
73098
73037
  }
73099
- function ImageField({
73038
+ function ValList({
73100
73039
  path,
73101
- defaultValue,
73102
- onSubmit,
73103
- registerPatchCallback
73040
+ source,
73041
+ schema,
73042
+ setSelectedPath
73104
73043
  }) {
73105
- const [data, setData] = React$3.useState(
73106
- null
73107
- );
73108
- const [loading, setLoading] = React$3.useState(false);
73109
- const [metadata, setMetadata] = React$3.useState();
73110
- const [url, setUrl] = React$3.useState();
73111
- React$3.useEffect(() => {
73112
- setUrl(defaultValue && Internal.convertFileSource(defaultValue).url);
73113
- }, [defaultValue]);
73114
- React$3.useEffect(() => {
73115
- if (registerPatchCallback) {
73116
- registerPatchCallback(async (path2) => {
73117
- return createImagePatch(
73118
- path2,
73119
- (data == null ? void 0 : data.src) ?? null,
73120
- (data == null ? void 0 : data.filename) ?? null,
73121
- metadata
73122
- );
73123
- });
73124
- }
73125
- }, [data, defaultValue]);
73126
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-4xl p-4", children: [
73127
- /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: `img_input:${path}`, className: "", children: [
73128
- data || url ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: (data == null ? void 0 : data.src) || url }) : /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Empty" }),
73129
- /* @__PURE__ */ jsxRuntime.jsx(
73130
- "input",
73131
- {
73132
- id: `img_input:${path}`,
73133
- type: "file",
73134
- hidden: true,
73135
- onChange: (ev) => {
73136
- readImage(ev).then((res) => {
73137
- setData({ src: res.src, filename: res.filename });
73138
- if (res.width && res.height) {
73139
- setMetadata({
73140
- sha256: res.sha256,
73141
- width: res.width,
73142
- height: res.height
73143
- });
73144
- } else {
73145
- setMetadata(void 0);
73146
- }
73147
- }).catch((err2) => {
73148
- console.error(err2.message);
73149
- setData(null);
73150
- setMetadata(void 0);
73151
- });
73152
- }
73153
- }
73154
- )
73155
- ] }),
73156
- onSubmit && /* @__PURE__ */ jsxRuntime.jsx("div", { children: data && /* @__PURE__ */ jsxRuntime.jsx(
73157
- Button,
73044
+ const navigate = useNavigate();
73045
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 p-2", children: source.map((item, index2) => {
73046
+ const subPath = createValPathOfItem(path, index2);
73047
+ return /* @__PURE__ */ jsxRuntime.jsx(
73048
+ "button",
73158
73049
  {
73159
- disabled: loading,
73160
73050
  onClick: () => {
73161
- setLoading(true);
73162
- onSubmit(
73163
- (path2) => Promise.resolve(
73164
- createImagePatch(
73165
- path2,
73166
- data.src,
73167
- data.filename ?? null,
73168
- metadata
73169
- )
73170
- )
73171
- ).finally(() => {
73172
- setLoading(false);
73173
- setData(null);
73174
- setMetadata(void 0);
73175
- });
73051
+ setSelectedPath(subPath);
73052
+ navigate(subPath);
73176
73053
  },
73177
- children: loading ? "Saving..." : "Submit"
73178
- }
73179
- ) })
73180
- ] }, path);
73054
+ children: /* @__PURE__ */ jsxRuntime.jsx(
73055
+ ValListItem,
73056
+ {
73057
+ index: index2,
73058
+ path: subPath,
73059
+ source: item,
73060
+ schema: schema.item
73061
+ },
73062
+ subPath
73063
+ )
73064
+ },
73065
+ subPath
73066
+ );
73067
+ }) }, path);
73181
73068
  }
73182
- async function createRichTextPatch(path, editor) {
73183
- const { templateStrings, exprs, files } = editor ? await lexicalToRichTextSource(
73184
- editor.getEditorState().toJSON().root
73185
- ) : {
73186
- [VAL_EXTENSION]: "richtext",
73187
- templateStrings: [""],
73188
- exprs: [],
73189
- files: {}
73190
- };
73191
- return [
73192
- {
73193
- op: "replace",
73194
- path,
73195
- value: {
73196
- templateStrings,
73197
- exprs,
73198
- [VAL_EXTENSION]: "richtext"
73069
+ const LIST_ITEM_MAX_HEIGHT = RECORD_ITEM_MAX_HEIGHT;
73070
+ function ValListItem({
73071
+ index: index2,
73072
+ path,
73073
+ source,
73074
+ schema
73075
+ }) {
73076
+ const ref = React$3.useRef(null);
73077
+ const [isTruncated, setIsTruncated] = React$3.useState(false);
73078
+ React$3.useEffect(() => {
73079
+ if (ref.current) {
73080
+ const height2 = ref.current.getBoundingClientRect().height;
73081
+ if (height2 >= LIST_ITEM_MAX_HEIGHT) {
73082
+ setIsTruncated(true);
73199
73083
  }
73200
- },
73201
- ...Object.entries(files).map(([filePath, value]) => {
73202
- return {
73203
- op: "file",
73204
- path,
73205
- filePath,
73206
- value
73207
- };
73208
- })
73209
- ];
73084
+ }
73085
+ }, []);
73086
+ return /* @__PURE__ */ jsxRuntime.jsxs(
73087
+ Card,
73088
+ {
73089
+ ref,
73090
+ className: "relative px-4 pt-2 pb-4 overflow-hidden border gap-y-2",
73091
+ style: {
73092
+ maxHeight: LIST_ITEM_MAX_HEIGHT
73093
+ },
73094
+ children: [
73095
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pb-4 font-serif text-left uppercase text-accent", children: index2 + 1 < 10 ? `0${index2 + 1}` : index2 + 1 }),
73096
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs", children: /* @__PURE__ */ jsxRuntime.jsx(ValPreview, { path, source, schema }) }),
73097
+ isTruncated && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 left-0 w-full h-[20px] bg-gradient-to-b from-transparent to-background" })
73098
+ ]
73099
+ }
73100
+ );
73210
73101
  }
73211
- function RichTextField({
73212
- defaultValue,
73213
- onSubmit,
73214
- registerPatchCallback
73102
+ function createValPathOfItem(arrayPath, prop) {
73103
+ const val = Internal.createValPathOfItem(arrayPath, prop);
73104
+ if (!val) {
73105
+ throw Error(
73106
+ `Could not create val path: ${arrayPath} of ${prop == null ? void 0 : prop.toString()}`
73107
+ );
73108
+ }
73109
+ return val;
73110
+ }
73111
+ function ValPreview({
73112
+ path,
73113
+ source,
73114
+ schema
73215
73115
  }) {
73216
- const [editor, setEditor] = React$3.useState(null);
73217
- const [didChange, setDidChange] = React$3.useState(false);
73218
- const [loading, setLoading] = React$3.useState(false);
73219
- React$3.useEffect(() => {
73220
- if (editor) {
73221
- setDidChange(false);
73222
- editor.registerTextContentListener(() => {
73223
- setDidChange(true);
73224
- });
73225
- editor.registerDecoratorListener(() => {
73226
- setDidChange(true);
73227
- });
73116
+ const [isMouseOver, setIsMouseOver] = React$3.useState(null);
73117
+ const { hoverElem } = useValFullscreenHover();
73118
+ if (schema.type === "object") {
73119
+ return /* @__PURE__ */ jsxRuntime.jsx(
73120
+ "div",
73121
+ {
73122
+ className: "grid grid-cols-[min-content_1fr] gap-2 text-left",
73123
+ children: Object.entries(schema.items).map(([key]) => {
73124
+ return /* @__PURE__ */ jsxRuntime.jsxs(React$3.Fragment, { children: [
73125
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted", children: [
73126
+ key,
73127
+ ":"
73128
+ ] }),
73129
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: /* @__PURE__ */ jsxRuntime.jsx(
73130
+ ValPreview,
73131
+ {
73132
+ source: (source == null ? void 0 : source[key]) ?? null,
73133
+ schema: schema.items[key],
73134
+ path: createValPathOfItem(path, key)
73135
+ }
73136
+ ) })
73137
+ ] }, createValPathOfItem(path, key));
73138
+ })
73139
+ },
73140
+ path
73141
+ );
73142
+ } else if (schema.type === "array") {
73143
+ if (source === null) {
73144
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: "Empty" }, path);
73228
73145
  }
73229
- }, [editor]);
73230
- React$3.useEffect(() => {
73231
- if (editor && registerPatchCallback) {
73232
- registerPatchCallback((path) => createRichTextPatch(path, editor));
73146
+ if (Array.isArray(source)) {
73147
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
73148
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: source.length }),
73149
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: source.length === 1 ? " item" : " items" })
73150
+ ] }, path);
73233
73151
  }
73234
- }, [editor]);
73235
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 border rounded border-card", children: [
73236
- /* @__PURE__ */ jsxRuntime.jsx(
73237
- RichTextEditor,
73152
+ return /* @__PURE__ */ jsxRuntime.jsx(
73153
+ "span",
73238
73154
  {
73239
- onEditor: (editor2) => {
73240
- setEditor(editor2);
73155
+ className: "px-2 bg-destructive text-destructive-foreground",
73156
+ children: "Unknown length"
73157
+ },
73158
+ path
73159
+ );
73160
+ } else if (schema.type === "richtext") {
73161
+ if (source === null) {
73162
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: "Empty" }, path);
73163
+ }
73164
+ if (typeof source !== "object") {
73165
+ return /* @__PURE__ */ jsxRuntime.jsxs(
73166
+ "div",
73167
+ {
73168
+ className: "p-4 text-destructive-foreground bg-destructive",
73169
+ children: [
73170
+ "ERROR: ",
73171
+ typeof source,
73172
+ " not an object"
73173
+ ]
73241
73174
  },
73242
- richtext: defaultValue || {
73243
- children: [],
73244
- [VAL_EXTENSION]: "root"
73245
- }
73246
- }
73247
- ),
73248
- onSubmit && /* @__PURE__ */ jsxRuntime.jsx("div", { children: didChange && /* @__PURE__ */ jsxRuntime.jsx(
73249
- Button,
73250
- {
73251
- disabled: loading || !editor,
73252
- onClick: () => {
73253
- if (editor) {
73254
- setLoading(true);
73255
- onSubmit((path) => createRichTextPatch(path, editor)).finally(
73256
- () => {
73257
- setLoading(false);
73258
- setDidChange(false);
73259
- }
73260
- );
73261
- }
73175
+ path
73176
+ );
73177
+ }
73178
+ if (!(VAL_EXTENSION in source) || source[VAL_EXTENSION] !== "richtext") {
73179
+ return /* @__PURE__ */ jsxRuntime.jsx(
73180
+ "div",
73181
+ {
73182
+ className: "p-4 text-destructive-foreground bg-destructive",
73183
+ children: "ERROR: object is not richtext"
73262
73184
  },
73263
- children: loading ? "Saving..." : "Submit"
73264
- }
73265
- ) })
73266
- ] });
73267
- }
73268
- function KeyOfField({
73269
- disabled,
73270
- defaultValue,
73271
- registerPatchCallback,
73272
- onSubmit,
73273
- selector
73274
- }) {
73275
- const valModule = useValModuleFromPath(selector);
73276
- const getValuesFromModule = (module2) => {
73277
- if (Array.isArray(module2.moduleSource)) {
73278
- return {
73279
- type: "number",
73280
- values: Object.keys(module2.moduleSource).map((key) => parseInt(key))
73281
- };
73185
+ path
73186
+ );
73282
73187
  }
73283
- return {
73284
- type: "string",
73285
- values: Object.keys(module2.moduleSource ?? ["ERROR fetching source"])
73286
- };
73287
- };
73288
- const typeAndValues = getValuesFromModule(valModule);
73289
- const [value, setValue] = React$3.useState(defaultValue || typeAndValues.values[0]);
73290
- const [loading, setLoading] = React$3.useState(false);
73291
- React$3.useEffect(() => {
73292
- setLoading(disabled);
73293
- }, [disabled]);
73294
- const parse2 = (value2) => {
73295
- if (typeAndValues.type === "number") {
73296
- if (value2 === "") {
73297
- throw new Error("Value cannot be empty");
73298
- }
73299
- if (Number.isNaN(Number(value2))) {
73300
- throw new Error("Value was not a number: " + JSON.stringify(value2));
73301
- }
73302
- return Number(value2);
73188
+ return /* @__PURE__ */ jsxRuntime.jsx(ValRichText, { children: parseRichTextSource(source) }, path);
73189
+ } else if (schema.type === "string") {
73190
+ if (source === null) {
73191
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: "Empty" }, path);
73303
73192
  }
73304
- return value2;
73305
- };
73306
- React$3.useEffect(() => {
73307
- if (registerPatchCallback) {
73308
- registerPatchCallback(async (path) => {
73309
- return [
73310
- {
73311
- op: "replace",
73312
- path,
73313
- value
73314
- }
73315
- ];
73316
- });
73193
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { children: source });
73194
+ } else if (schema.type === "image") {
73195
+ if (source === null) {
73196
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: "Empty" }, path);
73317
73197
  }
73318
- }, [value]);
73319
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col justify-between h-full gap-y-4", children: [
73320
- /* @__PURE__ */ jsxRuntime.jsxs(
73321
- Select,
73198
+ if (typeof source !== "object") {
73199
+ return /* @__PURE__ */ jsxRuntime.jsx(
73200
+ "div",
73201
+ {
73202
+ className: "p-4 text-destructive-foreground bg-destructive",
73203
+ children: "ERROR: not an object"
73204
+ },
73205
+ path
73206
+ );
73207
+ }
73208
+ if (!(FILE_REF_PROP in source) || typeof source[FILE_REF_PROP] !== "string") {
73209
+ return /* @__PURE__ */ jsxRuntime.jsx(
73210
+ "div",
73211
+ {
73212
+ className: "p-4 text-destructive-foreground bg-destructive",
73213
+ children: "ERROR: object is not an image"
73214
+ },
73215
+ path
73216
+ );
73217
+ }
73218
+ const url = Internal.convertFileSource(
73219
+ source
73220
+ ).url;
73221
+ return /* @__PURE__ */ jsxRuntime.jsxs(
73222
+ "span",
73322
73223
  {
73323
- defaultValue: value.toString(),
73324
- disabled: loading,
73325
- onValueChange: (value2) => {
73326
- setValue(parse2(value2));
73224
+ onMouseOver: (ev) => {
73225
+ setIsMouseOver({
73226
+ x: ev.clientX,
73227
+ y: ev.clientY
73228
+ });
73327
73229
  },
73230
+ onMouseLeave: () => {
73231
+ setIsMouseOver(null);
73232
+ },
73233
+ className: "relative flex items-center justify-start gap-1",
73328
73234
  children: [
73329
- /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "Select a value" }) }),
73330
- /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: typeAndValues.values.map((value2) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: value2.toString(), children: value2.toString() }, value2)) })
73235
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: url, className: "overflow-hidden underline truncate ", children: source[FILE_REF_PROP] }),
73236
+ isMouseOver && hoverElem && reactDomExports.createPortal(
73237
+ /* @__PURE__ */ jsxRuntime.jsx(
73238
+ "img",
73239
+ {
73240
+ className: "absolute z-[5] max-w-[10vw]",
73241
+ style: {
73242
+ left: isMouseOver.x + 10,
73243
+ top: isMouseOver.y + 10
73244
+ },
73245
+ src: url
73246
+ }
73247
+ ),
73248
+ hoverElem
73249
+ )
73331
73250
  ]
73251
+ },
73252
+ path
73253
+ );
73254
+ } else if (schema.type === "boolean") {
73255
+ if (source === null) {
73256
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: "Empty" }, path);
73257
+ }
73258
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: source ? "true" : "false" }, path);
73259
+ } else if (schema.type === "number") {
73260
+ if (source === null) {
73261
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: "Empty" }, path);
73262
+ }
73263
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: source.toString() });
73264
+ } else if (schema.type === "keyOf") {
73265
+ if (source === null) {
73266
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: "Empty" }, path);
73267
+ }
73268
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-accent", children: source.toString() }, path);
73269
+ }
73270
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
73271
+ "TODO: ",
73272
+ schema.type
73273
+ ] }, path);
73274
+ }
73275
+ function ValOptional({
73276
+ path,
73277
+ source,
73278
+ schema,
73279
+ setSelectedPath,
73280
+ initOnSubmit,
73281
+ field
73282
+ }) {
73283
+ const [enable, setEnable] = React$3.useState(source !== null);
73284
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-6", children: [
73285
+ field ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-start gap-x-4", children: [
73286
+ /* @__PURE__ */ jsxRuntime.jsx(
73287
+ Switch,
73288
+ {
73289
+ checked: enable,
73290
+ onClick: () => {
73291
+ setEnable((prev) => !prev);
73292
+ }
73293
+ }
73294
+ ),
73295
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: field })
73296
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
73297
+ Switch,
73298
+ {
73299
+ checked: enable,
73300
+ onClick: () => {
73301
+ setEnable((prev) => !prev);
73302
+ }
73332
73303
  }
73333
73304
  ),
73334
- onSubmit && /* @__PURE__ */ jsxRuntime.jsx("div", { children: defaultValue !== value && /* @__PURE__ */ jsxRuntime.jsx(
73335
- Button,
73305
+ enable && /* @__PURE__ */ jsxRuntime.jsx(
73306
+ ValDefaultOf,
73336
73307
  {
73337
- disabled: loading,
73338
- onClick: () => {
73339
- setLoading(true);
73340
- onSubmit(async (path) => [
73341
- {
73342
- op: "replace",
73343
- path,
73344
- value
73345
- }
73346
- ]).finally(() => {
73347
- setLoading(false);
73348
- });
73349
- },
73350
- children: loading ? "Saving..." : "Submit"
73308
+ source,
73309
+ schema,
73310
+ path,
73311
+ setSelectedPath,
73312
+ initOnSubmit
73351
73313
  }
73352
- ) })
73314
+ )
73315
+ ] }, path);
73316
+ }
73317
+ function ValDefaultOf({
73318
+ source,
73319
+ path,
73320
+ schema,
73321
+ setSelectedPath,
73322
+ initOnSubmit
73323
+ }) {
73324
+ if (schema.type === "array") {
73325
+ if (typeof source === "object" && (source === null || isJsonArray(source))) {
73326
+ return /* @__PURE__ */ jsxRuntime.jsx(
73327
+ ValList,
73328
+ {
73329
+ source: source === null ? [] : source,
73330
+ path,
73331
+ schema,
73332
+ setSelectedPath
73333
+ }
73334
+ );
73335
+ }
73336
+ } else if (schema.type === "object") {
73337
+ if (typeof source === "object" && (source === null || !isJsonArray(source))) {
73338
+ return /* @__PURE__ */ jsxRuntime.jsx(
73339
+ ValObject,
73340
+ {
73341
+ source,
73342
+ path,
73343
+ schema,
73344
+ setSelectedPath,
73345
+ initOnSubmit
73346
+ }
73347
+ );
73348
+ }
73349
+ } else if (schema.type === "richtext" || schema.type === "string" || schema.type === "image" || schema.type === "number" || schema.type === "keyOf") {
73350
+ return /* @__PURE__ */ jsxRuntime.jsx(
73351
+ ValFormField,
73352
+ {
73353
+ path,
73354
+ disabled: false,
73355
+ source,
73356
+ schema,
73357
+ onSubmit: initOnSubmit(path)
73358
+ },
73359
+ path
73360
+ );
73361
+ }
73362
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-4 bg-destructive text-destructive-foreground", children: [
73363
+ "ERROR: unexpected source type ",
73364
+ typeof source,
73365
+ " for schema type",
73366
+ " ",
73367
+ schema.type
73353
73368
  ] });
73354
73369
  }
73355
- function NumberField({
73356
- disabled,
73357
- defaultValue,
73358
- registerPatchCallback,
73359
- onSubmit
73370
+ function isJsonArray(source) {
73371
+ return Array.isArray(source);
73372
+ }
73373
+ function pathsToTree(paths) {
73374
+ const tree = {};
73375
+ paths.forEach((path) => {
73376
+ const parts = path.split("/").filter((part) => part !== "");
73377
+ let current = tree;
73378
+ parts.forEach((part) => {
73379
+ if (!current[part]) {
73380
+ current[part] = {};
73381
+ }
73382
+ current = current[part];
73383
+ });
73384
+ });
73385
+ return tree;
73386
+ }
73387
+ function PathTree({
73388
+ paths,
73389
+ setSelectedModuleId
73360
73390
  }) {
73361
- const [value, setValue] = React$3.useState(defaultValue || 0);
73362
- const [loading, setLoading] = React$3.useState(false);
73363
- React$3.useEffect(() => {
73364
- setLoading(disabled);
73365
- }, [disabled]);
73366
- const ref = React$3.useRef(null);
73367
- React$3.useEffect(() => {
73368
- if (registerPatchCallback) {
73369
- registerPatchCallback(async (path) => {
73370
- var _a;
73371
- return [
73372
- {
73373
- op: "replace",
73374
- path,
73375
- value: Number((_a = ref.current) == null ? void 0 : _a.value) || 0
73376
- }
73377
- ];
73378
- });
73391
+ const tree = pathsToTree(paths);
73392
+ return /* @__PURE__ */ jsxRuntime.jsx(Tree, { children: Object.entries(tree).map(([name, subTree]) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(
73393
+ PathNode,
73394
+ {
73395
+ name,
73396
+ tree: subTree,
73397
+ moduleId: `/${name}`,
73398
+ setSelectedModuleId
73379
73399
  }
73380
- }, []);
73381
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col justify-between h-full gap-y-4", children: [
73400
+ ) }, `/${name}`)) });
73401
+ }
73402
+ function PathNode({
73403
+ name,
73404
+ tree,
73405
+ moduleId,
73406
+ setSelectedModuleId
73407
+ }) {
73408
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
73382
73409
  /* @__PURE__ */ jsxRuntime.jsx(
73383
- Input,
73410
+ "button",
73384
73411
  {
73385
- ref,
73386
- disabled: loading,
73387
- defaultValue: value ?? 0,
73388
- onChange: (e) => setValue(Number(e.target.value)),
73389
- type: "number"
73412
+ onClick: () => {
73413
+ setSelectedModuleId(moduleId);
73414
+ },
73415
+ children: name
73390
73416
  }
73391
73417
  ),
73392
- onSubmit && /* @__PURE__ */ jsxRuntime.jsx("div", { children: defaultValue !== value && /* @__PURE__ */ jsxRuntime.jsx(
73393
- Button,
73418
+ Object.entries(tree).map(([childName, childTree]) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-1", children: /* @__PURE__ */ jsxRuntime.jsx(
73419
+ PathNode,
73394
73420
  {
73395
- disabled: loading,
73396
- onClick: () => {
73397
- setLoading(true);
73398
- onSubmit(async (path) => {
73399
- var _a;
73400
- return [
73401
- {
73402
- op: "replace",
73403
- path,
73404
- value: Number((_a = ref.current) == null ? void 0 : _a.value) || 0
73405
- }
73406
- ];
73407
- }).finally(() => {
73408
- setLoading(false);
73409
- });
73410
- },
73411
- children: loading ? "Saving..." : "Submit"
73421
+ name: childName,
73422
+ tree: childTree,
73423
+ moduleId: `${moduleId}/${childName}`,
73424
+ setSelectedModuleId
73412
73425
  }
73413
- ) })
73426
+ ) }, `${moduleId}/${childName}`))
73414
73427
  ] });
73415
73428
  }
73416
- function StringField({
73417
- disabled,
73418
- defaultValue,
73419
- registerPatchCallback,
73420
- onSubmit
73429
+ const theme = {
73430
+ tags: {
73431
+ h1: "font-bold",
73432
+ h2: "font-bold",
73433
+ h3: "font-bold",
73434
+ h4: "font-bold",
73435
+ h5: "font-bold",
73436
+ h6: "font-bold",
73437
+ p: ""
73438
+ },
73439
+ classes: {
73440
+ bold: "font-bold",
73441
+ italic: "italic",
73442
+ lineThrough: "line-through"
73443
+ }
73444
+ };
73445
+ function ValRichText({
73446
+ children
73421
73447
  }) {
73422
- const [value, setValue] = React$3.useState(defaultValue || "");
73423
- const [loading, setLoading] = React$3.useState(false);
73424
- React$3.useEffect(() => {
73425
- setLoading(disabled);
73426
- }, [disabled]);
73427
- const ref = React$3.useRef(null);
73428
- React$3.useEffect(() => {
73429
- if (registerPatchCallback) {
73430
- registerPatchCallback(async (path) => {
73431
- var _a;
73432
- return [
73433
- {
73434
- op: "replace",
73435
- path,
73436
- value: ((_a = ref.current) == null ? void 0 : _a.value) || ""
73437
- }
73438
- ];
73439
- });
73448
+ const root = children;
73449
+ function withRenderTag(clazz, current) {
73450
+ const renderClass = theme.tags[clazz];
73451
+ if (renderClass && current) {
73452
+ return [current, renderClass].join(" ");
73453
+ }
73454
+ if (renderClass) {
73455
+ return renderClass;
73456
+ }
73457
+ return current;
73458
+ }
73459
+ function withRenderClass(clazz, current) {
73460
+ const renderClass = theme.classes[clazz];
73461
+ if (renderClass && current) {
73462
+ return [current, renderClass].join(" ");
73463
+ }
73464
+ if (renderClass) {
73465
+ return renderClass;
73466
+ }
73467
+ return current;
73468
+ }
73469
+ function toReact(node, key) {
73470
+ var _a, _b;
73471
+ if (typeof node === "string") {
73472
+ return node;
73473
+ }
73474
+ if (node.tag === "p") {
73475
+ return /* @__PURE__ */ jsxRuntime.jsx("p", { className: withRenderTag("p"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73476
+ }
73477
+ if (node.tag === "img") {
73478
+ return /* @__PURE__ */ jsxRuntime.jsx("img", { className: withRenderTag("img"), src: node.src }, key);
73479
+ }
73480
+ if (node.tag === "ul") {
73481
+ return /* @__PURE__ */ jsxRuntime.jsx("ul", { className: withRenderTag("ul"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73482
+ }
73483
+ if (node.tag === "ol") {
73484
+ return /* @__PURE__ */ jsxRuntime.jsx("ol", { className: withRenderTag("ol"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73485
+ }
73486
+ if (node.tag === "li") {
73487
+ return /* @__PURE__ */ jsxRuntime.jsx("li", { className: withRenderTag("li"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73440
73488
  }
73441
- }, []);
73442
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col justify-between h-full gap-y-4", children: [
73443
- /* @__PURE__ */ jsxRuntime.jsx(
73444
- Input,
73445
- {
73446
- ref,
73447
- disabled: loading,
73448
- defaultValue: value ?? "",
73449
- onChange: (e) => setValue(e.target.value)
73450
- }
73451
- ),
73452
- onSubmit && /* @__PURE__ */ jsxRuntime.jsx("div", { children: defaultValue !== value && /* @__PURE__ */ jsxRuntime.jsx(
73453
- Button,
73454
- {
73455
- disabled: loading,
73456
- onClick: () => {
73457
- setLoading(true);
73458
- onSubmit(async (path) => {
73459
- var _a;
73460
- return [
73461
- {
73462
- op: "replace",
73463
- path,
73464
- value: ((_a = ref.current) == null ? void 0 : _a.value) || ""
73465
- }
73466
- ];
73467
- }).finally(() => {
73468
- setLoading(false);
73469
- });
73489
+ if (node.tag === "span") {
73490
+ return /* @__PURE__ */ jsxRuntime.jsx(
73491
+ "span",
73492
+ {
73493
+ className: node.classes.map((nodeClass) => {
73494
+ switch (nodeClass) {
73495
+ case "bold":
73496
+ return withRenderClass("bold");
73497
+ case "line-through":
73498
+ return withRenderClass("lineThrough");
73499
+ case "italic":
73500
+ return withRenderClass("italic");
73501
+ }
73502
+ }).join(" "),
73503
+ children: node.children.map((child, key2) => toReact(child, key2))
73470
73504
  },
73471
- children: loading ? "Saving..." : "Submit"
73472
- }
73473
- ) })
73474
- ] });
73475
- }
73476
- function usePatch(paths, api, valStore, onSubmit, session) {
73477
- const [state, setState] = React$3.useState({});
73478
- const [error, setError] = React$3.useState(null);
73479
- const [progress, setProgress] = React$3.useState("ready");
73480
- const initPatchCallback = React$3.useCallback(
73481
- (pathsAttr) => {
73482
- return (callback) => {
73483
- setState((prev) => {
73484
- const paths2 = pathsAttr.split(",");
73485
- const nextState = paths2.reduce((acc, path) => {
73486
- const patchPath = Internal.createPatchJSONPath(
73487
- Internal.splitModuleIdAndModulePath(path)[1]
73488
- );
73489
- return {
73490
- ...acc,
73491
- [path]: () => callback(patchPath)
73492
- };
73493
- }, {});
73494
- return {
73495
- ...prev,
73496
- ...nextState
73497
- };
73498
- });
73499
- };
73500
- },
73501
- []
73502
- );
73503
- React$3.useEffect(() => {
73504
- setState((prev) => {
73505
- const newState = {};
73506
- for (const path of paths) {
73507
- if (prev[path]) {
73508
- newState[path] = prev[path];
73509
- }
73510
- }
73511
- if (Object.keys(newState).length === Object.keys(prev).length) {
73512
- return prev;
73513
- }
73514
- return newState;
73515
- });
73516
- }, [paths]);
73517
- const onSubmitPatch = React$3.useCallback(async () => {
73518
- setError(null);
73519
- setProgress("create_patch");
73520
- const patches = {};
73521
- for (const path in state) {
73522
- const [moduleId] = Internal.splitModuleIdAndModulePath(
73523
- path
73505
+ key
73524
73506
  );
73525
- const patch = await state[path]();
73526
- patches[moduleId] = patch;
73527
73507
  }
73528
- return maybeStartViewTransition(() => {
73529
- setProgress("patching");
73530
- return Promise.all(
73531
- Object.entries(patches).map(
73532
- ([moduleId, patch]) => api.postPatches(moduleId, patch).then((res) => {
73533
- if (result.isErr(res)) {
73534
- throw res.error;
73535
- } else {
73536
- res.value;
73537
- }
73538
- })
73539
- )
73540
- ).then(() => {
73541
- setProgress("on_submit");
73542
- const refreshRequired = session.status === "success" && session.data.mode === "proxy";
73543
- return onSubmit(refreshRequired);
73544
- }).then(() => {
73545
- setProgress("update_store");
73546
- return valStore.update(
73547
- paths.map(
73548
- (path) => Internal.splitModuleIdAndModulePath(path)[0]
73549
- )
73550
- );
73551
- });
73552
- }).catch((err2) => {
73553
- setError(err2);
73554
- }).finally(() => {
73555
- setProgress("ready");
73508
+ if (node.tag === "h1") {
73509
+ return /* @__PURE__ */ jsxRuntime.jsx("h1", { className: withRenderTag("h1"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73510
+ }
73511
+ if (node.tag === "h2") {
73512
+ return /* @__PURE__ */ jsxRuntime.jsx("h2", { className: withRenderTag("h2"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73513
+ }
73514
+ if (node.tag === "h3") {
73515
+ return /* @__PURE__ */ jsxRuntime.jsx("h3", { className: withRenderTag("h3"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73516
+ }
73517
+ if (node.tag === "h4") {
73518
+ return /* @__PURE__ */ jsxRuntime.jsx("h4", { className: withRenderTag("h4"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73519
+ }
73520
+ if (node.tag === "h5") {
73521
+ return /* @__PURE__ */ jsxRuntime.jsx("h5", { className: withRenderTag("h5"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73522
+ }
73523
+ if (node.tag === "h6") {
73524
+ return /* @__PURE__ */ jsxRuntime.jsx("h6", { className: withRenderTag("h6"), children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73525
+ }
73526
+ if (node.tag === "br") {
73527
+ return /* @__PURE__ */ jsxRuntime.jsx("br", {}, key);
73528
+ }
73529
+ if (node.tag === "a") {
73530
+ return /* @__PURE__ */ jsxRuntime.jsx("a", { href: node.href, children: node.children.map((child, key2) => toReact(child, key2)) }, key);
73531
+ }
73532
+ console.error("Unknown tag", node.tag);
73533
+ const _exhaustiveCheck = node.tag;
73534
+ const anyNode = _exhaustiveCheck;
73535
+ if (!(anyNode == null ? void 0 : anyNode.tag)) {
73536
+ return null;
73537
+ }
73538
+ return React$3.createElement(anyNode.tag, {
73539
+ key,
73540
+ className: (_a = anyNode.class) == null ? void 0 : _a.join(" "),
73541
+ children: (_b = anyNode.children) == null ? void 0 : _b.map(toReact)
73556
73542
  });
73557
- }, [state, session]);
73558
- return { initPatchCallback, onSubmitPatch, error, progress };
73559
- }
73560
- async function maybeStartViewTransition(f) {
73561
- if ("startViewTransition" in document && typeof document.startViewTransition === "function") {
73562
- await document.startViewTransition(f);
73563
73543
  }
73564
- await f();
73544
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { "data-val-path": root.valPath, children: root.children.map((child, i) => {
73545
+ return toReact(child, i);
73546
+ }) });
73565
73547
  }
73566
73548
  function ValOverlay({
73567
73549
  defaultTheme,
@@ -73575,32 +73557,48 @@ function ValOverlay({
73575
73557
  const [hoverTarget, setHoverTarget] = useHoverTarget(editMode);
73576
73558
  const [windowTarget, setWindowTarget] = React$3.useState(null);
73577
73559
  const [highlight, setHighlight] = React$3.useState(false);
73578
- const { selectedSchema, selectedSource, moduleId, error, loading } = useValModules(api, windowTarget == null ? void 0 : windowTarget.path);
73560
+ const paths = (windowTarget == null ? void 0 : windowTarget.path) ? windowTarget.path.split(",") : [];
73561
+ const [formData, setFormData] = React$3.useState(
73562
+ Object.fromEntries(
73563
+ paths.map((path) => {
73564
+ return [path, { status: "not-asked" }];
73565
+ })
73566
+ )
73567
+ );
73568
+ React$3.useEffect(() => {
73569
+ setFormData(
73570
+ Object.fromEntries(paths.map((path) => [path, { status: "loading" }]))
73571
+ );
73572
+ for (const path of paths) {
73573
+ updateFormData(api, path, setFormData);
73574
+ }
73575
+ }, [paths.join(";")]);
73576
+ const selectedPaths = (windowTarget == null ? void 0 : windowTarget.path) ? paths : [];
73579
73577
  const {
73580
- initPatchCallback,
73581
73578
  onSubmitPatch,
73582
- progress: patchProgress,
73579
+ // progress: patchProgress,
73583
73580
  error: patchError
73584
- } = usePatch(
73585
- (windowTarget == null ? void 0 : windowTarget.path) ? [windowTarget.path] : [],
73586
- api,
73587
- store,
73588
- onSubmit,
73589
- session
73590
- );
73581
+ } = usePatch(selectedPaths, api, store, onSubmit, session);
73591
73582
  const [windowSize, setWindowSize] = React$3.useState();
73592
73583
  React$3.useEffect(() => {
73593
- if (moduleId) {
73594
- store.update([moduleId]);
73595
- } else {
73596
- store.updateAll();
73597
- }
73598
- }, [moduleId]);
73584
+ store.updateAll();
73585
+ }, []);
73599
73586
  React$3.useEffect(() => {
73600
73587
  if (patchError) {
73601
73588
  console.error(patchError);
73602
73589
  }
73603
73590
  }, [patchError]);
73591
+ const initOnSubmit = React$3.useCallback(
73592
+ (path) => async (callback) => {
73593
+ const [moduleId, modulePath] = Internal.splitModuleIdAndModulePath(path);
73594
+ const patch = await callback(Internal.createPatchJSONPath(modulePath));
73595
+ await api.postPatches(moduleId, patch);
73596
+ return onSubmitPatch().then(() => store.update([moduleId])).then(() => {
73597
+ updateFormData(api, path, setFormData);
73598
+ });
73599
+ },
73600
+ []
73601
+ );
73604
73602
  return /* @__PURE__ */ jsxRuntime.jsx(
73605
73603
  ValOverlayContext.Provider,
73606
73604
  {
@@ -73618,7 +73616,7 @@ function ValOverlay({
73618
73616
  },
73619
73617
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-mode": theme2, className: "antialiased", children: [
73620
73618
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed -translate-x-1/2 z-overlay left-1/2 bottom-4", children: /* @__PURE__ */ jsxRuntime.jsx(ValMenu, { api }) }),
73621
- editMode === "hover" && hoverTarget.path && /* @__PURE__ */ jsxRuntime.jsx(
73619
+ session.status === "success" && session.data.enabled && editMode === "hover" && hoverTarget.path && /* @__PURE__ */ jsxRuntime.jsx(
73622
73620
  ValHover,
73623
73621
  {
73624
73622
  hoverTarget,
@@ -73627,134 +73625,109 @@ function ValOverlay({
73627
73625
  setWindowTarget
73628
73626
  }
73629
73627
  ),
73630
- editMode === "window" && windowTarget && /* @__PURE__ */ jsxRuntime.jsxs(
73628
+ editMode === "window" && windowTarget && /* @__PURE__ */ jsxRuntime.jsx(
73631
73629
  ValWindow,
73632
73630
  {
73633
73631
  onClose: () => {
73634
73632
  setWindowTarget(null);
73635
73633
  setEditMode("hover");
73636
73634
  },
73637
- children: [
73638
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-full px-4 py-2 text-sm border-b border-highlight", children: /* @__PURE__ */ jsxRuntime.jsx(
73639
- WindowHeader,
73640
- {
73641
- path: windowTarget.path,
73642
- type: selectedSchema == null ? void 0 : selectedSchema.type
73643
- }
73644
- ) }),
73645
- loading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-primary", children: "Loading..." }),
73646
- error && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-2 text-red", children: [
73647
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "font-bold", children: [
73648
- "Error: ",
73649
- error.message
73650
- ] }),
73651
- "details" in error && /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "bg-card text-card-foreground", children: error.details })
73652
- ] }),
73653
- selectedSchema !== void 0 && selectedSource !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(
73654
- ValFormField,
73655
- {
73656
- path: windowTarget.path,
73657
- disabled: loading,
73658
- source: selectedSource,
73659
- schema: selectedSchema,
73660
- registerPatchCallback: initPatchCallback(windowTarget.path)
73661
- }
73662
- ),
73663
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-end justify-end py-2", children: /* @__PURE__ */ jsxRuntime.jsx(
73664
- Button,
73665
- {
73666
- className: "px-4 py-2 border border-highlight disabled:border-border",
73667
- disabled: patchProgress !== "ready",
73668
- onClick: onSubmitPatch,
73669
- children: patchProgress === "patching" ? "Finalizing..." : patchProgress === "create_patch" ? "Patching..." : patchProgress === "on_submit" ? "Completing..." : patchProgress === "update_store" ? "Refreshing..." : "Submit"
73670
- }
73671
- ) })
73672
- ]
73635
+ children: /* @__PURE__ */ jsxRuntime.jsx(
73636
+ "div",
73637
+ {
73638
+ className: "p-4",
73639
+ style: {
73640
+ maxHeight: windowSize == null ? void 0 : windowSize.innerHeight
73641
+ },
73642
+ children: Object.entries(formData).map(([path, data]) => {
73643
+ if (data.status !== "success") {
73644
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
73645
+ path,
73646
+ ": ",
73647
+ data.status
73648
+ ] }, path);
73649
+ }
73650
+ const { source, schema } = data.data;
73651
+ if (!source || !schema) {
73652
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
73653
+ "Module: ",
73654
+ path,
73655
+ " is missing source or schema"
73656
+ ] });
73657
+ }
73658
+ return /* @__PURE__ */ jsxRuntime.jsx(
73659
+ AnyVal,
73660
+ {
73661
+ initOnSubmit,
73662
+ path,
73663
+ schema,
73664
+ source,
73665
+ setSelectedPath: () => {
73666
+ },
73667
+ field: path,
73668
+ top: true
73669
+ },
73670
+ path
73671
+ );
73672
+ })
73673
+ }
73674
+ )
73673
73675
  }
73674
73676
  )
73675
73677
  ] })
73676
73678
  }
73677
73679
  );
73678
73680
  }
73679
- function useValModules(api, path) {
73680
- const [modules, setModules] = React$3.useState();
73681
- const moduleId = path && Internal.splitModuleIdAndModulePath(path)[0];
73682
- React$3.useEffect(() => {
73683
- if (path) {
73684
- setModules({ status: "loading" });
73685
- api.getTree({
73686
- patch: true,
73687
- includeSchema: true,
73688
- includeSource: true,
73689
- treePath: moduleId
73690
- }).then((res) => {
73691
- if (result.isOk(res)) {
73692
- setModules({ status: "success", data: res.value.modules });
73693
- } else {
73694
- console.error({ status: "error", error: res.error });
73695
- setModules({ status: "error", error: res.error.message });
73681
+ function updateFormData(api, path, setData) {
73682
+ const [moduleId, modulePath] = Internal.splitModuleIdAndModulePath(
73683
+ path
73684
+ );
73685
+ api.getTree({
73686
+ patch: true,
73687
+ includeSchema: true,
73688
+ includeSource: true,
73689
+ treePath: moduleId
73690
+ }).then((res) => {
73691
+ if (result.isOk(res)) {
73692
+ const { schema, source } = res.value.modules[moduleId];
73693
+ if (!schema || !source) {
73694
+ return setData((prev) => ({
73695
+ ...prev,
73696
+ [path]: {
73697
+ status: "success",
73698
+ data: {
73699
+ source: res.value.modules[moduleId].source,
73700
+ schema: res.value.modules[moduleId].schema
73701
+ }
73702
+ }
73703
+ }));
73704
+ }
73705
+ const resolvedModulePath = Internal.resolvePath(
73706
+ modulePath,
73707
+ source,
73708
+ schema
73709
+ );
73710
+ setData((prev) => ({
73711
+ ...prev,
73712
+ [path]: {
73713
+ status: "success",
73714
+ data: {
73715
+ source: resolvedModulePath.source,
73716
+ schema: resolvedModulePath.schema
73717
+ }
73696
73718
  }
73697
- });
73719
+ }));
73720
+ } else {
73721
+ console.error({ status: "error", error: res.error });
73722
+ setData((prev) => ({
73723
+ ...prev,
73724
+ [path]: {
73725
+ status: "error",
73726
+ error: res.error.message
73727
+ }
73728
+ }));
73698
73729
  }
73699
- }, [path]);
73700
- if (!path || (modules == null ? void 0 : modules.status) === "not-asked") {
73701
- return {
73702
- moduleId,
73703
- error: null,
73704
- selectedSource: void 0,
73705
- selectedSchema: void 0,
73706
- loading: false
73707
- };
73708
- }
73709
- if ((modules == null ? void 0 : modules.status) === "loading") {
73710
- return {
73711
- moduleId,
73712
- error: null,
73713
- selectedSource: void 0,
73714
- selectedSchema: void 0,
73715
- loading: true
73716
- };
73717
- }
73718
- if ((modules == null ? void 0 : modules.status) === "error") {
73719
- return {
73720
- moduleId,
73721
- error: { message: modules.error },
73722
- selectedSource: void 0,
73723
- selectedSchema: void 0,
73724
- loading: false
73725
- };
73726
- }
73727
- if (!(modules == null ? void 0 : modules.data)) {
73728
- return {
73729
- error: {
73730
- message: "Val could not fetch data for this element.",
73731
- details: "Module data not found for: " + moduleId
73732
- },
73733
- selectedSource: void 0,
73734
- selectedSchema: void 0,
73735
- loading: false
73736
- };
73737
- }
73738
- const resolvedModulePath = resolvePath$1(path, modules.data);
73739
- const {
73740
- error,
73741
- source: selectedSource,
73742
- schema: selectedSchema
73743
- } = resolvedModulePath && result.isOk(resolvedModulePath) ? {
73744
- ...resolvedModulePath.value,
73745
- error: null
73746
- } : {
73747
- error: resolvedModulePath && result.isErr(resolvedModulePath) ? resolvedModulePath.error : null,
73748
- source: void 0,
73749
- schema: void 0
73750
- };
73751
- return {
73752
- moduleId,
73753
- error,
73754
- selectedSource,
73755
- selectedSchema,
73756
- loading: false
73757
- };
73730
+ });
73758
73731
  }
73759
73732
  function ValHover({
73760
73733
  hoverTarget,
@@ -73921,40 +73894,7 @@ function useSession(api) {
73921
73894
  }, [sessionResetId]);
73922
73895
  return session;
73923
73896
  }
73924
- function WindowHeader({
73925
- path,
73926
- type
73927
- }) {
73928
- const segments = path.split("/").slice(1);
73929
- return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "h-[20px] flex items-center justify-between", children: [
73930
- /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "whitespace-nowrap", dir: "rtl", children: segments.map((segment, i) => {
73931
- if (i === segments.length - 1) {
73932
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary", children: segment.split(".").map((s, i2) => {
73933
- let name = s;
73934
- if (i2 === 0) {
73935
- return /* @__PURE__ */ jsxRuntime.jsx("span", { children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: name }) }, i2 + ".");
73936
- } else {
73937
- name = JSON.parse(s);
73938
- }
73939
- return /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
73940
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-1 text-xs text-highlight", children: "/" }),
73941
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: name })
73942
- ] }, i2 + ".");
73943
- }) }, i);
73944
- }
73945
- return /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
73946
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: segment }),
73947
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "px-1 text-xs opacity-50", children: "/" })
73948
- ] }, i);
73949
- }) }),
73950
- type && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-4", children: [
73951
- "(",
73952
- type,
73953
- ")"
73954
- ] })
73955
- ] });
73956
- }
73957
- const styleCss = "/*\n Need to explicitly set config path, otherwise it may fail to resolve when\n built from outside packages/ui.\n*/\n\n/*\n ! tailwindcss v3.3.5 | MIT License | https://tailwindcss.com\n*/\n\n/*\n1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)\n2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)\n*/\n\n*,\n::before,\n::after {\n box-sizing: border-box; /* 1 */\n border-width: 0; /* 2 */\n border-style: solid; /* 2 */\n border-color: #e5e7eb; /* 2 */\n}\n\n::before,\n::after {\n --tw-content: '';\n}\n\n/*\n1. Use a consistent sensible line-height in all browsers.\n2. Prevent adjustments of font size after orientation changes in iOS.\n3. Use a more readable tab size.\n4. Use the user's configured `sans` font-family by default.\n5. Use the user's configured `sans` font-feature-settings by default.\n6. Use the user's configured `sans` font-variation-settings by default.\n*/\n\nhtml {\n line-height: 1.5; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n -moz-tab-size: 4; /* 3 */\n -o-tab-size: 4;\n tab-size: 4; /* 3 */\n font-family: 'Roboto', sans-serif; /* 4 */\n font-feature-settings: normal; /* 5 */\n font-variation-settings: normal; /* 6 */\n}\n\n/*\n1. Remove the margin in all browsers.\n2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.\n*/\n\nbody {\n margin: 0; /* 1 */\n line-height: inherit; /* 2 */\n}\n\n/*\n1. Add the correct height in Firefox.\n2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)\n3. Ensure horizontal rules are visible by default.\n*/\n\nhr {\n height: 0; /* 1 */\n color: inherit; /* 2 */\n border-top-width: 1px; /* 3 */\n}\n\n/*\nAdd the correct text decoration in Chrome, Edge, and Safari.\n*/\n\nabbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n}\n\n/*\nRemove the default font size and weight for headings.\n*/\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-size: inherit;\n font-weight: inherit;\n}\n\n/*\nReset links to optimize for opt-in styling instead of opt-out.\n*/\n\na {\n color: inherit;\n text-decoration: inherit;\n}\n\n/*\nAdd the correct font weight in Edge and Safari.\n*/\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/*\n1. Use the user's configured `mono` font family by default.\n2. Correct the odd `em` font sizing in all browsers.\n*/\n\ncode,\nkbd,\nsamp,\npre {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/*\nAdd the correct font size in all browsers.\n*/\n\nsmall {\n font-size: 80%;\n}\n\n/*\nPrevent `sub` and `sup` elements from affecting the line height in all browsers.\n*/\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/*\n1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)\n2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)\n3. Remove gaps between table borders by default.\n*/\n\ntable {\n text-indent: 0; /* 1 */\n border-color: inherit; /* 2 */\n border-collapse: collapse; /* 3 */\n}\n\n/*\n1. Change the font styles in all browsers.\n2. Remove the margin in Firefox and Safari.\n3. Remove default padding in all browsers.\n*/\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-feature-settings: inherit; /* 1 */\n font-variation-settings: inherit; /* 1 */\n font-size: 100%; /* 1 */\n font-weight: inherit; /* 1 */\n line-height: inherit; /* 1 */\n color: inherit; /* 1 */\n margin: 0; /* 2 */\n padding: 0; /* 3 */\n}\n\n/*\nRemove the inheritance of text transform in Edge and Firefox.\n*/\n\nbutton,\nselect {\n text-transform: none;\n}\n\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Remove default button styles.\n*/\n\nbutton,\n[type='button'],\n[type='reset'],\n[type='submit'] {\n -webkit-appearance: button; /* 1 */\n background-color: transparent; /* 2 */\n background-image: none; /* 2 */\n}\n\n/*\nUse the modern Firefox focus style for all focusable elements.\n*/\n\n:-moz-focusring {\n outline: auto;\n}\n\n/*\nRemove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)\n*/\n\n:-moz-ui-invalid {\n box-shadow: none;\n}\n\n/*\nAdd the correct vertical alignment in Chrome and Firefox.\n*/\n\nprogress {\n vertical-align: baseline;\n}\n\n/*\nCorrect the cursor style of increment and decrement buttons in Safari.\n*/\n\n::-webkit-inner-spin-button,\n::-webkit-outer-spin-button {\n height: auto;\n}\n\n/*\n1. Correct the odd appearance in Chrome and Safari.\n2. Correct the outline style in Safari.\n*/\n\n[type='search'] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/*\nRemove the inner padding in Chrome and Safari on macOS.\n*/\n\n::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Change font properties to `inherit` in Safari.\n*/\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/*\nAdd the correct display in Chrome and Safari.\n*/\n\nsummary {\n display: list-item;\n}\n\n/*\nRemoves the default spacing and border for appropriate elements.\n*/\n\nblockquote,\ndl,\ndd,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhr,\nfigure,\np,\npre {\n margin: 0;\n}\n\nfieldset {\n margin: 0;\n padding: 0;\n}\n\nlegend {\n padding: 0;\n}\n\nol,\nul,\nmenu {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n/*\nReset default styling for dialogs.\n*/\n\ndialog {\n padding: 0;\n}\n\n/*\nPrevent resizing textareas horizontally by default.\n*/\n\ntextarea {\n resize: vertical;\n}\n\n/*\n1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)\n2. Set the default placeholder color to the user's configured gray 400 color.\n*/\n\ninput::-moz-placeholder, textarea::-moz-placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\n\ninput::placeholder,\ntextarea::placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\n\n/*\nSet the default cursor for buttons.\n*/\n\nbutton,\n[role=\"button\"] {\n cursor: pointer;\n}\n\n/*\nMake sure disabled buttons don't get the pointer cursor.\n*/\n\n:disabled {\n cursor: default;\n}\n\n/*\n1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)\n2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)\n This can trigger a poorly considered lint error in some tools but is included by design.\n*/\n\nimg,\nsvg,\nvideo,\ncanvas,\naudio,\niframe,\nembed,\nobject {\n display: block; /* 1 */\n vertical-align: middle; /* 2 */\n}\n\n/*\nConstrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)\n*/\n\nimg,\nvideo {\n max-width: 100%;\n height: auto;\n}\n\n/* Make elements with the HTML hidden attribute stay hidden by default */\n\n[hidden] {\n display: none;\n}\n\n/* :host for use with Shadow DOM, copied from the TailwindCSS prelude */\n\n:host {\n --background: 0 0% 100%;\n --foreground: 222.2 84% 4.9%;\n\n --card: 0 0% 100%;\n --card-foreground: 222.2 84% 4.9%;\n\n --popover: 0 0% 100%;\n --popover-foreground: 222.2 84% 4.9%;\n\n --primary: 222.2 47.4% 11.2%;\n --primary-foreground: 210 40% 98%;\n\n --secondary: 210 40% 96.1%;\n --secondary-foreground: 222.2 47.4% 11.2%;\n\n --muted: 0 0% 57.3%;\n --muted-foreground: 215.4 16.3% 46.9%;\n\n --accent: 159, 60%, 51%, 1;\n --accent-foreground: 222.2 47.4% 11.2%;\n\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 40% 98%;\n\n --border: 214.3 31.8% 91.4%;\n --input: 214.3 31.8% 91.4%;\n --ring: 222.2 84% 4.9%;\n\n --radius: 0.5rem;\n }\n\n:root {\n --background: 0 0% 100%;\n --foreground: 222.2 84% 4.9%;\n\n --card: 0 0% 100%;\n --card-foreground: 222.2 84% 4.9%;\n\n --popover: 0 0% 100%;\n --popover-foreground: 222.2 84% 4.9%;\n\n --primary: 222.2 47.4% 11.2%;\n --primary-foreground: 210 40% 98%;\n\n --secondary: 210 40% 96.1%;\n --secondary-foreground: 222.2 47.4% 11.2%;\n\n --muted: 0 0% 57.3%;\n --muted-foreground: 215.4 16.3% 46.9%;\n\n --accent: 159, 60%, 51%, 1;\n --accent-foreground: 222.2 47.4% 11.2%;\n\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 40% 98%;\n\n --border: 214.3 31.8% 91.4%;\n --input: 214.3 31.8% 91.4%;\n --ring: 222.2 84% 4.9%;\n\n --radius: 0.5rem;\n }\n\n/* dark theme */\n\n*[data-mode=\"dark\"] {\n --background: 0 0% 4%;\n --foreground: 210 40% 98%;\n\n --card: 222.2 84% 4.9%;\n --card-foreground: 210 40% 98%;\n\n --popover: 222.2 84% 4.9%;\n --popover-foreground: 210 40% 98%;\n\n --primary: 210 40% 98%;\n --primary-foreground: 222.2 47.4% 11.2%;\n\n --secondary: 217.2 32.6% 17.5%;\n --secondary-foreground: 210 40% 98%;\n\n --muted: 178, 23%, 76%, 1;\n --muted-foreground: 215 20.2% 65.1%;\n\n --accent: 159, 60%, 51%, 1;\n --accent-foreground: 210 40% 98%;\n\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 210 40% 98%;\n\n --border: 217.2 32.6% 17.5%;\n --input: 217.2 32.6% 17.5%;\n --ring: 212.7 26.8% 83.9%;\n }\n\n* {\n border-color: hsl(var(--border));\n}\n\nbody {\n background-color: hsl(var(--background));\n color: hsl(var(--foreground));\n}\n\n*, ::before, ::after {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n}\n\n::backdrop {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n}\n.pointer-events-none {\n pointer-events: none;\n}\n.invisible {\n visibility: hidden;\n}\n.static {\n position: static;\n}\n.fixed {\n position: fixed;\n}\n.absolute {\n position: absolute;\n}\n.relative {\n position: relative;\n}\n.sticky {\n position: sticky;\n}\n.inset-0 {\n inset: 0px;\n}\n.inset-y-0 {\n top: 0px;\n bottom: 0px;\n}\n.-left-2 {\n left: -0.5rem;\n}\n.-right-\\[10px\\] {\n right: -10px;\n}\n.-top-\\[10px\\] {\n top: -10px;\n}\n.-top-\\[4px\\] {\n top: -4px;\n}\n.bottom-0 {\n bottom: 0px;\n}\n.bottom-4 {\n bottom: 1rem;\n}\n.left-0 {\n left: 0px;\n}\n.left-1 {\n left: 0.25rem;\n}\n.left-1\\/2 {\n left: 50%;\n}\n.left-2 {\n left: 0.5rem;\n}\n.left-\\[50\\%\\] {\n left: 50%;\n}\n.right-0 {\n right: 0px;\n}\n.right-1 {\n right: 0.25rem;\n}\n.right-4 {\n right: 1rem;\n}\n.right-\\[16px\\] {\n right: 16px;\n}\n.top-0 {\n top: 0px;\n}\n.top-4 {\n top: 1rem;\n}\n.top-\\[50\\%\\] {\n top: 50%;\n}\n.z-50 {\n z-index: 50;\n}\n.z-\\[5\\] {\n z-index: 5;\n}\n.z-overlay {\n z-index: 4;\n}\n.-mx-1 {\n margin-left: -0.25rem;\n margin-right: -0.25rem;\n}\n.-my-2 {\n margin-top: -0.5rem;\n margin-bottom: -0.5rem;\n}\n.-my-\\[100px\\] {\n margin-top: -100px;\n margin-bottom: -100px;\n}\n.mx-2 {\n margin-left: 0.5rem;\n margin-right: 0.5rem;\n}\n.my-1 {\n margin-top: 0.25rem;\n margin-bottom: 0.25rem;\n}\n.mb-4 {\n margin-bottom: 1rem;\n}\n.ml-2 {\n margin-left: 0.5rem;\n}\n.ml-4 {\n margin-left: 1rem;\n}\n.ml-\\[20px\\] {\n margin-left: 20px;\n}\n.ml-auto {\n margin-left: auto;\n}\n.mr-2 {\n margin-right: 0.5rem;\n}\n.mt-2 {\n margin-top: 0.5rem;\n}\n.block {\n display: block;\n}\n.inline {\n display: inline;\n}\n.flex {\n display: flex;\n}\n.inline-flex {\n display: inline-flex;\n}\n.table {\n display: table;\n}\n.grid {\n display: grid;\n}\n.hidden {\n display: none;\n}\n.aspect-square {\n aspect-ratio: 1 / 1;\n}\n.h-10 {\n height: 2.5rem;\n}\n.h-11 {\n height: 2.75rem;\n}\n.h-2 {\n height: 0.5rem;\n}\n.h-2\\.5 {\n height: 0.625rem;\n}\n.h-3 {\n height: 0.75rem;\n}\n.h-3\\.5 {\n height: 0.875rem;\n}\n.h-4 {\n height: 1rem;\n}\n.h-7 {\n height: 1.75rem;\n}\n.h-9 {\n height: 2.25rem;\n}\n.h-\\[14px\\] {\n height: 14px;\n}\n.h-\\[18px\\] {\n height: 18px;\n}\n.h-\\[1px\\] {\n height: 1px;\n}\n.h-\\[20px\\] {\n height: 20px;\n}\n.h-\\[22px\\] {\n height: 22px;\n}\n.h-\\[24px\\] {\n height: 24px;\n}\n.h-\\[32px\\] {\n height: 32px;\n}\n.h-\\[50px\\] {\n height: 50px;\n}\n.h-\\[75px\\] {\n height: 75px;\n}\n.h-\\[9px\\] {\n height: 9px;\n}\n.h-\\[var\\(--radix-select-trigger-height\\)\\] {\n height: var(--radix-select-trigger-height);\n}\n.h-full {\n height: 100%;\n}\n.h-px {\n height: 1px;\n}\n.h-screen {\n height: 100vh;\n}\n.max-h-\\[300px\\] {\n max-height: 300px;\n}\n.min-h-\\[200px\\] {\n min-height: 200px;\n}\n.min-h-\\[300px\\] {\n min-height: 300px;\n}\n.min-h-screen {\n min-height: 100vh;\n}\n.w-1\\/3 {\n width: 33.333333%;\n}\n.w-10 {\n width: 2.5rem;\n}\n.w-2 {\n width: 0.5rem;\n}\n.w-2\\.5 {\n width: 0.625rem;\n}\n.w-3 {\n width: 0.75rem;\n}\n.w-3\\.5 {\n width: 0.875rem;\n}\n.w-4 {\n width: 1rem;\n}\n.w-5 {\n width: 1.25rem;\n}\n.w-7 {\n width: 1.75rem;\n}\n.w-72 {\n width: 18rem;\n}\n.w-9 {\n width: 2.25rem;\n}\n.w-\\[14px\\] {\n width: 14px;\n}\n.w-\\[1px\\] {\n width: 1px;\n}\n.w-\\[20px\\] {\n width: 20px;\n}\n.w-\\[24px\\] {\n width: 24px;\n}\n.w-\\[32px\\] {\n width: 32px;\n}\n.w-\\[44px\\] {\n width: 44px;\n}\n.w-\\[9px\\] {\n width: 9px;\n}\n.w-fit {\n width: -moz-fit-content;\n width: fit-content;\n}\n.w-full {\n width: 100%;\n}\n.w-screen {\n width: 100vw;\n}\n.min-w-0 {\n min-width: 0px;\n}\n.min-w-\\[320px\\] {\n min-width: 320px;\n}\n.min-w-\\[500px\\] {\n min-width: 500px;\n}\n.min-w-\\[8rem\\] {\n min-width: 8rem;\n}\n.min-w-\\[var\\(--radix-select-trigger-width\\)\\] {\n min-width: var(--radix-select-trigger-width);\n}\n.max-w-4xl {\n max-width: 56rem;\n}\n.max-w-\\[1000px\\] {\n max-width: 1000px;\n}\n.max-w-\\[10vw\\] {\n max-width: 10vw;\n}\n.max-w-\\[300px\\] {\n max-width: 300px;\n}\n.max-w-\\[90vw\\] {\n max-width: 90vw;\n}\n.max-w-full {\n max-width: 100%;\n}\n.max-w-lg {\n max-width: 32rem;\n}\n.flex-1 {\n flex: 1 1 0%;\n}\n.flex-auto {\n flex: 1 1 auto;\n}\n.flex-shrink-0 {\n flex-shrink: 0;\n}\n.shrink-0 {\n flex-shrink: 0;\n}\n.flex-grow {\n flex-grow: 1;\n}\n.border-collapse {\n border-collapse: collapse;\n}\n.-translate-x-1\\/2 {\n --tw-translate-x: -50%;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.translate-x-\\[-50\\%\\] {\n --tw-translate-x: -50%;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.translate-y-\\[-50\\%\\] {\n --tw-translate-y: -50%;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.-rotate-90 {\n --tw-rotate: -90deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.rotate-90 {\n --tw-rotate: 90deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.rotate-\\[-90deg\\] {\n --tw-rotate: -90deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.rotate-\\[90deg\\] {\n --tw-rotate: 90deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.transform {\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.cursor-col-resize {\n cursor: col-resize;\n}\n.cursor-default {\n cursor: default;\n}\n.cursor-grab {\n cursor: grab;\n}\n.cursor-pointer {\n cursor: pointer;\n}\n.cursor-se-resize {\n cursor: se-resize;\n}\n.touch-none {\n touch-action: none;\n}\n.select-none {\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n}\n.resize-none {\n resize: none;\n}\n.resize {\n resize: both;\n}\n.list-decimal {\n list-style-type: decimal;\n}\n.list-disc {\n list-style-type: disc;\n}\n.grid-cols-\\[min-content_1fr\\] {\n grid-template-columns: min-content 1fr;\n}\n.grid-rows-\\[1fr\\2c _min-content\\] {\n grid-template-rows: 1fr min-content;\n}\n.flex-row {\n flex-direction: row;\n}\n.flex-col {\n flex-direction: column;\n}\n.flex-col-reverse {\n flex-direction: column-reverse;\n}\n.items-start {\n align-items: flex-start;\n}\n.items-end {\n align-items: flex-end;\n}\n.items-center {\n align-items: center;\n}\n.justify-start {\n justify-content: flex-start;\n}\n.justify-end {\n justify-content: flex-end;\n}\n.justify-center {\n justify-content: center;\n}\n.justify-between {\n justify-content: space-between;\n}\n.gap-1 {\n gap: 0.25rem;\n}\n.gap-2 {\n gap: 0.5rem;\n}\n.gap-3 {\n gap: 0.75rem;\n}\n.gap-4 {\n gap: 1rem;\n}\n.gap-5 {\n gap: 1.25rem;\n}\n.gap-\\[0\\.5em\\] {\n gap: 0.5em;\n}\n.gap-\\[36px\\] {\n gap: 36px;\n}\n.gap-x-2 {\n -moz-column-gap: 0.5rem;\n column-gap: 0.5rem;\n}\n.gap-x-3 {\n -moz-column-gap: 0.75rem;\n column-gap: 0.75rem;\n}\n.gap-x-4 {\n -moz-column-gap: 1rem;\n column-gap: 1rem;\n}\n.gap-y-2 {\n row-gap: 0.5rem;\n}\n.gap-y-4 {\n row-gap: 1rem;\n}\n.gap-y-6 {\n row-gap: 1.5rem;\n}\n.gap-y-8 {\n row-gap: 2rem;\n}\n.space-x-1 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-x-reverse: 0;\n margin-right: calc(0.25rem * var(--tw-space-x-reverse));\n margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse)));\n}\n.space-y-1 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));\n}\n.space-y-1\\.5 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(0.375rem * var(--tw-space-y-reverse));\n}\n.space-y-2 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));\n}\n.space-y-4 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(1rem * var(--tw-space-y-reverse));\n}\n.overflow-auto {\n overflow: auto;\n}\n.overflow-hidden {\n overflow: hidden;\n}\n.overflow-clip {\n overflow: clip;\n}\n.overflow-scroll {\n overflow: scroll;\n}\n.overflow-y-auto {\n overflow-y: auto;\n}\n.overflow-x-hidden {\n overflow-x: hidden;\n}\n.overflow-y-scroll {\n overflow-y: scroll;\n}\n.truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.whitespace-nowrap {\n white-space: nowrap;\n}\n.rounded {\n border-radius: 0.25rem;\n}\n.rounded-\\[inherit\\] {\n border-radius: inherit;\n}\n.rounded-full {\n border-radius: 9999px;\n}\n.rounded-lg {\n border-radius: var(--radius);\n}\n.rounded-md {\n border-radius: calc(var(--radius) - 2px);\n}\n.rounded-sm {\n border-radius: calc(var(--radius) - 4px);\n}\n.border {\n border-width: 1px;\n}\n.border-2 {\n border-width: 2px;\n}\n.border-\\[2px\\] {\n border-width: 2px;\n}\n.border-y {\n border-top-width: 1px;\n border-bottom-width: 1px;\n}\n.border-b {\n border-bottom-width: 1px;\n}\n.border-l {\n border-left-width: 1px;\n}\n.border-l-2 {\n border-left-width: 2px;\n}\n.border-r {\n border-right-width: 1px;\n}\n.border-t {\n border-top-width: 1px;\n}\n.border-accent {\n border-color: hsl(var(--accent));\n}\n.border-border {\n border-color: hsl(var(--border));\n}\n.border-card {\n border-color: hsl(var(--card));\n}\n.border-gray-400 {\n --tw-border-opacity: 1;\n border-color: rgb(156 163 175 / var(--tw-border-opacity));\n}\n.border-input {\n border-color: hsl(var(--input));\n}\n.border-primary {\n border-color: hsl(var(--primary));\n}\n.border-transparent {\n border-color: transparent;\n}\n.border-l-transparent {\n border-left-color: transparent;\n}\n.border-t-transparent {\n border-top-color: transparent;\n}\n.bg-accent {\n background-color: hsl(var(--accent));\n}\n.bg-background {\n background-color: hsl(var(--background));\n}\n.bg-background\\/80 {\n background-color: hsl(var(--background) / 0.8);\n}\n.bg-border {\n background-color: hsl(var(--border));\n}\n.bg-card {\n background-color: hsl(var(--card));\n}\n.bg-card-foreground {\n background-color: hsl(var(--card-foreground));\n}\n.bg-destructive {\n background-color: hsl(var(--destructive));\n}\n.bg-gray-300 {\n --tw-bg-opacity: 1;\n background-color: rgb(209 213 219 / var(--tw-bg-opacity));\n}\n.bg-gray-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(107 114 128 / var(--tw-bg-opacity));\n}\n.bg-muted {\n background-color: hsl(var(--muted));\n}\n.bg-popover {\n background-color: hsl(var(--popover));\n}\n.bg-primary {\n background-color: hsl(var(--primary));\n}\n.bg-red-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(239 68 68 / var(--tw-bg-opacity));\n}\n.bg-secondary {\n background-color: hsl(var(--secondary));\n}\n.bg-transparent {\n background-color: transparent;\n}\n.bg-white {\n --tw-bg-opacity: 1;\n background-color: rgb(255 255 255 / var(--tw-bg-opacity));\n}\n.bg-gradient-to-b {\n background-image: linear-gradient(to bottom, var(--tw-gradient-stops));\n}\n.from-transparent {\n --tw-gradient-from: transparent var(--tw-gradient-from-position);\n --tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position);\n --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);\n}\n.to-background {\n --tw-gradient-to: hsl(var(--background)) var(--tw-gradient-to-position);\n}\n.fill-current {\n fill: currentColor;\n}\n.fill-white {\n fill: #fff;\n}\n.stroke-\\[2px\\] {\n stroke-width: 2px;\n}\n.stroke-\\[3px\\] {\n stroke-width: 3px;\n}\n.object-contain {\n -o-object-fit: contain;\n object-fit: contain;\n}\n.p-0 {\n padding: 0px;\n}\n.p-1 {\n padding: 0.25rem;\n}\n.p-10 {\n padding: 2.5rem;\n}\n.p-2 {\n padding: 0.5rem;\n}\n.p-3 {\n padding: 0.75rem;\n}\n.p-4 {\n padding: 1rem;\n}\n.p-6 {\n padding: 1.5rem;\n}\n.p-\\[1px\\] {\n padding: 1px;\n}\n.px-1 {\n padding-left: 0.25rem;\n padding-right: 0.25rem;\n}\n.px-2 {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.px-2\\.5 {\n padding-left: 0.625rem;\n padding-right: 0.625rem;\n}\n.px-3 {\n padding-left: 0.75rem;\n padding-right: 0.75rem;\n}\n.px-4 {\n padding-left: 1rem;\n padding-right: 1rem;\n}\n.px-5 {\n padding-left: 1.25rem;\n padding-right: 1.25rem;\n}\n.px-8 {\n padding-left: 2rem;\n padding-right: 2rem;\n}\n.px-\\[24px\\] {\n padding-left: 24px;\n padding-right: 24px;\n}\n.py-1 {\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n}\n.py-1\\.5 {\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n}\n.py-2 {\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n.py-3 {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n}\n.py-4 {\n padding-top: 1rem;\n padding-bottom: 1rem;\n}\n.py-6 {\n padding-top: 1.5rem;\n padding-bottom: 1.5rem;\n}\n.py-7 {\n padding-top: 1.75rem;\n padding-bottom: 1.75rem;\n}\n.py-\\[2px\\] {\n padding-top: 2px;\n padding-bottom: 2px;\n}\n.pb-0 {\n padding-bottom: 0px;\n}\n.pb-20 {\n padding-bottom: 5rem;\n}\n.pb-4 {\n padding-bottom: 1rem;\n}\n.pl-6 {\n padding-left: 1.5rem;\n}\n.pl-8 {\n padding-left: 2rem;\n}\n.pr-2 {\n padding-right: 0.5rem;\n}\n.pt-0 {\n padding-top: 0px;\n}\n.pt-1 {\n padding-top: 0.25rem;\n}\n.pt-2 {\n padding-top: 0.5rem;\n}\n.pt-4 {\n padding-top: 1rem;\n}\n.text-left {\n text-align: left;\n}\n.text-center {\n text-align: center;\n}\n.text-start {\n text-align: start;\n}\n.font-sans {\n font-family: 'Roboto', sans-serif;\n}\n.font-serif {\n font-family: 'Space Mono', monospace;\n}\n.text-2xl {\n font-size: 1.5rem;\n line-height: 2rem;\n}\n.text-3xl {\n font-size: 1.875rem;\n line-height: 2.25rem;\n}\n.text-4xl {\n font-size: 2.25rem;\n line-height: 2.5rem;\n}\n.text-\\[0\\.8rem\\] {\n font-size: 0.8rem;\n}\n.text-\\[12px\\] {\n font-size: 12px;\n}\n.text-lg {\n font-size: 1.125rem;\n line-height: 1.75rem;\n}\n.text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n.text-xl {\n font-size: 1.25rem;\n line-height: 1.75rem;\n}\n.text-xs {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n.font-\\[12px\\] {\n font-weight: 12px;\n}\n.font-\\[400\\] {\n font-weight: 400;\n}\n.font-\\[500\\] {\n font-weight: 500;\n}\n.font-\\[550\\] {\n font-weight: 550;\n}\n.font-bold {\n font-weight: 700;\n}\n.font-extrabold {\n font-weight: 800;\n}\n.font-medium {\n font-weight: 500;\n}\n.font-normal {\n font-weight: 400;\n}\n.font-semibold {\n font-weight: 600;\n}\n.uppercase {\n text-transform: uppercase;\n}\n.italic {\n font-style: italic;\n}\n.leading-4 {\n line-height: 1rem;\n}\n.leading-none {\n line-height: 1;\n}\n.tracking-\\[0\\.04em\\] {\n letter-spacing: 0.04em;\n}\n.tracking-tight {\n letter-spacing: -0.025em;\n}\n.tracking-wider {\n letter-spacing: 0.05em;\n}\n.tracking-widest {\n letter-spacing: 0.1em;\n}\n.text-accent {\n color: hsl(var(--accent));\n}\n.text-accent-foreground {\n color: hsl(var(--accent-foreground));\n}\n.text-background {\n color: hsl(var(--background));\n}\n.text-card-foreground {\n color: hsl(var(--card-foreground));\n}\n.text-current {\n color: currentColor;\n}\n.text-destructive {\n color: hsl(var(--destructive));\n}\n.text-destructive-foreground {\n color: hsl(var(--destructive-foreground));\n}\n.text-foreground {\n color: hsl(var(--foreground));\n}\n.text-muted {\n color: hsl(var(--muted));\n}\n.text-muted-foreground {\n color: hsl(var(--muted-foreground));\n}\n.text-popover-foreground {\n color: hsl(var(--popover-foreground));\n}\n.text-primary {\n color: hsl(var(--primary));\n}\n.text-primary-foreground {\n color: hsl(var(--primary-foreground));\n}\n.text-secondary-foreground {\n color: hsl(var(--secondary-foreground));\n}\n.text-white {\n --tw-text-opacity: 1;\n color: rgb(255 255 255 / var(--tw-text-opacity));\n}\n.underline {\n text-decoration-line: underline;\n}\n.line-through {\n text-decoration-line: line-through;\n}\n.underline-offset-4 {\n text-underline-offset: 4px;\n}\n.antialiased {\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.opacity-0 {\n opacity: 0;\n}\n.opacity-100 {\n opacity: 1;\n}\n.opacity-50 {\n opacity: 0.5;\n}\n.opacity-60 {\n opacity: 0.6;\n}\n.opacity-70 {\n opacity: 0.7;\n}\n.opacity-75 {\n opacity: 0.75;\n}\n.shadow {\n --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.shadow-lg {\n --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.shadow-md {\n --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.shadow-sm {\n --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.outline-none {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n.outline {\n outline-style: solid;\n}\n.ring-0 {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);\n}\n.ring-offset-background {\n --tw-ring-offset-color: hsl(var(--background));\n}\n.drop-shadow-2xl {\n --tw-drop-shadow: drop-shadow(0 25px 25px rgb(0 0 0 / 0.15));\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.drop-shadow-\\[0px_0px_12px_rgba\\(56\\2c 205\\2c 152\\2c 0\\.60\\)\\] {\n --tw-drop-shadow: drop-shadow(0px 0px 12px rgba(56,205,152,0.60));\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.filter {\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.backdrop-blur-sm {\n --tw-backdrop-blur: blur(4px);\n -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\n backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\n}\n.transition-all {\n transition-property: all;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.transition-colors {\n transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.transition-opacity {\n transition-property: opacity;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.transition-transform {\n transition-property: transform;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.duration-150 {\n transition-duration: 150ms;\n}\n.duration-200 {\n transition-duration: 200ms;\n}\n.ease-in-out {\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n@keyframes enter {\n\n from {\n opacity: var(--tw-enter-opacity, 1);\n transform: translate3d(var(--tw-enter-translate-x, 0), var(--tw-enter-translate-y, 0), 0) scale3d(var(--tw-enter-scale, 1), var(--tw-enter-scale, 1), var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0));\n }\n}\n@keyframes exit {\n\n to {\n opacity: var(--tw-exit-opacity, 1);\n transform: translate3d(var(--tw-exit-translate-x, 0), var(--tw-exit-translate-y, 0), 0) scale3d(var(--tw-exit-scale, 1), var(--tw-exit-scale, 1), var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0));\n }\n}\n.animate-in {\n animation-name: enter;\n animation-duration: 150ms;\n --tw-enter-opacity: initial;\n --tw-enter-scale: initial;\n --tw-enter-rotate: initial;\n --tw-enter-translate-x: initial;\n --tw-enter-translate-y: initial;\n}\n.fade-in-0 {\n --tw-enter-opacity: 0;\n}\n.zoom-in-95 {\n --tw-enter-scale: .95;\n}\n.duration-150 {\n animation-duration: 150ms;\n}\n.duration-200 {\n animation-duration: 200ms;\n}\n.ease-in-out {\n animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n.file\\:border-0::file-selector-button {\n border-width: 0px;\n}\n.file\\:bg-transparent::file-selector-button {\n background-color: transparent;\n}\n.file\\:text-sm::file-selector-button {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n.file\\:font-medium::file-selector-button {\n font-weight: 500;\n}\n.placeholder\\:text-muted-foreground::-moz-placeholder {\n color: hsl(var(--muted-foreground));\n}\n.placeholder\\:text-muted-foreground::placeholder {\n color: hsl(var(--muted-foreground));\n}\n.focus-within\\:relative:focus-within {\n position: relative;\n}\n.hover\\:w-\\[2px\\]:hover {\n width: 2px;\n}\n.hover\\:w-\\[3px\\]:hover {\n width: 3px;\n}\n.hover\\:cursor-pointer:hover {\n cursor: pointer;\n}\n.hover\\:rounded-lg:hover {\n border-radius: var(--radius);\n}\n.hover\\:bg-accent:hover {\n background-color: hsl(var(--accent));\n}\n.hover\\:bg-background:hover {\n background-color: hsl(var(--background));\n}\n.hover\\:bg-border:hover {\n background-color: hsl(var(--border));\n}\n.hover\\:bg-destructive\\/90:hover {\n background-color: hsl(var(--destructive) / 0.9);\n}\n.hover\\:bg-muted:hover {\n background-color: hsl(var(--muted));\n}\n.hover\\:bg-primary:hover {\n background-color: hsl(var(--primary));\n}\n.hover\\:bg-primary\\/90:hover {\n background-color: hsl(var(--primary) / 0.9);\n}\n.hover\\:bg-red-700:hover {\n --tw-bg-opacity: 1;\n background-color: rgb(185 28 28 / var(--tw-bg-opacity));\n}\n.hover\\:bg-secondary\\/80:hover {\n background-color: hsl(var(--secondary) / 0.8);\n}\n.hover\\:text-accent-foreground:hover {\n color: hsl(var(--accent-foreground));\n}\n.hover\\:text-muted-foreground:hover {\n color: hsl(var(--muted-foreground));\n}\n.hover\\:text-primary-foreground:hover {\n color: hsl(var(--primary-foreground));\n}\n.hover\\:text-white:hover {\n --tw-text-opacity: 1;\n color: rgb(255 255 255 / var(--tw-text-opacity));\n}\n.hover\\:underline:hover {\n text-decoration-line: underline;\n}\n.hover\\:opacity-100:hover {\n opacity: 1;\n}\n.focus\\:bg-accent:focus {\n background-color: hsl(var(--accent));\n}\n.focus\\:bg-primary:focus {\n background-color: hsl(var(--primary));\n}\n.focus\\:text-accent-foreground:focus {\n color: hsl(var(--accent-foreground));\n}\n.focus\\:text-primary-foreground:focus {\n color: hsl(var(--primary-foreground));\n}\n.focus\\:outline-none:focus {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n.focus\\:ring-2:focus {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);\n}\n.focus\\:ring-ring:focus {\n --tw-ring-color: hsl(var(--ring));\n}\n.focus\\:ring-offset-2:focus {\n --tw-ring-offset-width: 2px;\n}\n.focus-visible\\:outline-none:focus-visible {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n.focus-visible\\:outline-accent:focus-visible {\n outline-color: hsl(var(--accent));\n}\n.focus-visible\\:ring-2:focus-visible {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);\n}\n.focus-visible\\:ring-ring:focus-visible {\n --tw-ring-color: hsl(var(--ring));\n}\n.focus-visible\\:ring-offset-2:focus-visible {\n --tw-ring-offset-width: 2px;\n}\n.focus-visible\\:ring-offset-background:focus-visible {\n --tw-ring-offset-color: hsl(var(--background));\n}\n.disabled\\:pointer-events-none:disabled {\n pointer-events: none;\n}\n.disabled\\:cursor-not-allowed:disabled {\n cursor: not-allowed;\n}\n.disabled\\:border-border:disabled {\n border-color: hsl(var(--border));\n}\n.disabled\\:text-background:disabled {\n color: hsl(var(--background));\n}\n.disabled\\:opacity-50:disabled {\n opacity: 0.5;\n}\n.peer:disabled ~ .peer-disabled\\:cursor-not-allowed {\n cursor: not-allowed;\n}\n.peer:disabled ~ .peer-disabled\\:opacity-70 {\n opacity: 0.7;\n}\n.aria-selected\\:bg-accent[aria-selected=\"true\"] {\n background-color: hsl(var(--accent));\n}\n.aria-selected\\:text-accent-foreground[aria-selected=\"true\"] {\n color: hsl(var(--accent-foreground));\n}\n.aria-selected\\:opacity-100[aria-selected=\"true\"] {\n opacity: 1;\n}\n.data-\\[disabled\\]\\:pointer-events-none[data-disabled] {\n pointer-events: none;\n}\n.data-\\[side\\=bottom\\]\\:translate-y-1[data-side=bottom] {\n --tw-translate-y: 0.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[side\\=left\\]\\:-translate-x-1[data-side=left] {\n --tw-translate-x: -0.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[side\\=right\\]\\:translate-x-1[data-side=right] {\n --tw-translate-x: 0.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[side\\=top\\]\\:-translate-y-1[data-side=top] {\n --tw-translate-y: -0.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[state\\=checked\\]\\:translate-x-5[data-state=checked] {\n --tw-translate-x: 1.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[state\\=unchecked\\]\\:translate-x-0[data-state=unchecked] {\n --tw-translate-x: 0px;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n@keyframes accordion-up {\n\n from {\n height: var(--radix-accordion-content-height);\n }\n\n to {\n height: 0;\n }\n}\n.data-\\[state\\=closed\\]\\:animate-accordion-up[data-state=closed] {\n animation: accordion-up 0.2s ease-out;\n}\n@keyframes accordion-down {\n\n from {\n height: 0;\n }\n\n to {\n height: var(--radix-accordion-content-height);\n }\n}\n.data-\\[state\\=open\\]\\:animate-accordion-down[data-state=open] {\n animation: accordion-down 0.2s ease-out;\n}\n.data-\\[state\\=active\\]\\:bg-background[data-state=active] {\n background-color: hsl(var(--background));\n}\n.data-\\[state\\=checked\\]\\:bg-accent[data-state=checked] {\n background-color: hsl(var(--accent));\n}\n.data-\\[state\\=checked\\]\\:bg-primary[data-state=checked] {\n background-color: hsl(var(--primary));\n}\n.data-\\[state\\=on\\]\\:bg-accent[data-state=on] {\n background-color: hsl(var(--accent));\n}\n.data-\\[state\\=open\\]\\:bg-accent[data-state=open] {\n background-color: hsl(var(--accent));\n}\n.data-\\[state\\=unchecked\\]\\:bg-primary[data-state=unchecked] {\n background-color: hsl(var(--primary));\n}\n.data-\\[state\\=active\\]\\:text-foreground[data-state=active] {\n color: hsl(var(--foreground));\n}\n.data-\\[state\\=checked\\]\\:text-primary-foreground[data-state=checked] {\n color: hsl(var(--primary-foreground));\n}\n.data-\\[state\\=on\\]\\:text-accent-foreground[data-state=on] {\n color: hsl(var(--accent-foreground));\n}\n.data-\\[state\\=open\\]\\:text-muted-foreground[data-state=open] {\n color: hsl(var(--muted-foreground));\n}\n.data-\\[disabled\\]\\:opacity-50[data-disabled] {\n opacity: 0.5;\n}\n.data-\\[state\\=active\\]\\:shadow-sm[data-state=active] {\n --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.data-\\[state\\=open\\]\\:animate-in[data-state=open] {\n animation-name: enter;\n animation-duration: 150ms;\n --tw-enter-opacity: initial;\n --tw-enter-scale: initial;\n --tw-enter-rotate: initial;\n --tw-enter-translate-x: initial;\n --tw-enter-translate-y: initial;\n}\n.data-\\[state\\=closed\\]\\:animate-out[data-state=closed] {\n animation-name: exit;\n animation-duration: 150ms;\n --tw-exit-opacity: initial;\n --tw-exit-scale: initial;\n --tw-exit-rotate: initial;\n --tw-exit-translate-x: initial;\n --tw-exit-translate-y: initial;\n}\n.data-\\[state\\=closed\\]\\:fade-out-0[data-state=closed] {\n --tw-exit-opacity: 0;\n}\n.data-\\[state\\=open\\]\\:fade-in-0[data-state=open] {\n --tw-enter-opacity: 0;\n}\n.data-\\[state\\=closed\\]\\:zoom-out-95[data-state=closed] {\n --tw-exit-scale: .95;\n}\n.data-\\[state\\=open\\]\\:zoom-in-95[data-state=open] {\n --tw-enter-scale: .95;\n}\n.data-\\[side\\=bottom\\]\\:slide-in-from-top-2[data-side=bottom] {\n --tw-enter-translate-y: -0.5rem;\n}\n.data-\\[side\\=left\\]\\:slide-in-from-right-2[data-side=left] {\n --tw-enter-translate-x: 0.5rem;\n}\n.data-\\[side\\=right\\]\\:slide-in-from-left-2[data-side=right] {\n --tw-enter-translate-x: -0.5rem;\n}\n.data-\\[side\\=top\\]\\:slide-in-from-bottom-2[data-side=top] {\n --tw-enter-translate-y: 0.5rem;\n}\n.data-\\[state\\=closed\\]\\:slide-out-to-left-1\\/2[data-state=closed] {\n --tw-exit-translate-x: -50%;\n}\n.data-\\[state\\=closed\\]\\:slide-out-to-top-\\[48\\%\\][data-state=closed] {\n --tw-exit-translate-y: -48%;\n}\n.data-\\[state\\=open\\]\\:slide-in-from-left-1\\/2[data-state=open] {\n --tw-enter-translate-x: -50%;\n}\n.data-\\[state\\=open\\]\\:slide-in-from-top-\\[48\\%\\][data-state=open] {\n --tw-enter-translate-y: -48%;\n}\n:is([data-mode=\"dark\"] .dark\\:border-white) {\n --tw-border-opacity: 1;\n border-color: rgb(255 255 255 / var(--tw-border-opacity));\n}\n@media (min-width: 640px) {\n\n .sm\\:mt-0 {\n margin-top: 0px;\n }\n\n .sm\\:block {\n display: block;\n }\n\n .sm\\:flex-row {\n flex-direction: row;\n }\n\n .sm\\:justify-end {\n justify-content: flex-end;\n }\n\n .sm\\:space-x-2 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-x-reverse: 0;\n margin-right: calc(0.5rem * var(--tw-space-x-reverse));\n margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));\n }\n\n .sm\\:space-x-4 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-x-reverse: 0;\n margin-right: calc(1rem * var(--tw-space-x-reverse));\n margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse)));\n }\n\n .sm\\:space-y-0 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(0px * var(--tw-space-y-reverse));\n }\n\n .sm\\:rounded-lg {\n border-radius: var(--radius);\n }\n\n .sm\\:p-0 {\n padding: 0px;\n }\n\n .sm\\:text-left {\n text-align: left;\n }\n}\n@media (min-width: 768px) {\n\n .md\\:w-full {\n width: 100%;\n }\n}\n.\\[\\&\\:has\\(\\[aria-selected\\]\\)\\]\\:bg-accent:has([aria-selected]) {\n background-color: hsl(var(--accent));\n}\n.first\\:\\[\\&\\:has\\(\\[aria-selected\\]\\)\\]\\:rounded-l-md:has([aria-selected]):first-child {\n border-top-left-radius: calc(var(--radius) - 2px);\n border-bottom-left-radius: calc(var(--radius) - 2px);\n}\n.last\\:\\[\\&\\:has\\(\\[aria-selected\\]\\)\\]\\:rounded-r-md:has([aria-selected]):last-child {\n border-top-right-radius: calc(var(--radius) - 2px);\n border-bottom-right-radius: calc(var(--radius) - 2px);\n}\n.\\[\\&\\[data-state\\=open\\]\\>svg\\]\\:rotate-180[data-state=open]>svg {\n --tw-rotate: 180deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:px-2 [cmdk-group-heading] {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:py-1\\.5 [cmdk-group-heading] {\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:text-xs [cmdk-group-heading] {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:font-medium [cmdk-group-heading] {\n font-weight: 500;\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:text-muted-foreground [cmdk-group-heading] {\n color: hsl(var(--muted-foreground));\n}\n.\\[\\&_\\[cmdk-group\\]\\:not\\(\\[hidden\\]\\)_\\~\\[cmdk-group\\]\\]\\:pt-0 [cmdk-group]:not([hidden]) ~[cmdk-group] {\n padding-top: 0px;\n}\n.\\[\\&_\\[cmdk-group\\]\\]\\:px-2 [cmdk-group] {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.\\[\\&_\\[cmdk-input-wrapper\\]_svg\\]\\:h-5 [cmdk-input-wrapper] svg {\n height: 1.25rem;\n}\n.\\[\\&_\\[cmdk-input-wrapper\\]_svg\\]\\:w-5 [cmdk-input-wrapper] svg {\n width: 1.25rem;\n}\n.\\[\\&_\\[cmdk-input\\]\\]\\:h-12 [cmdk-input] {\n height: 3rem;\n}\n.\\[\\&_\\[cmdk-item\\]\\]\\:px-2 [cmdk-item] {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.\\[\\&_\\[cmdk-item\\]\\]\\:py-3 [cmdk-item] {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n}\n.\\[\\&_\\[cmdk-item\\]_svg\\]\\:h-5 [cmdk-item] svg {\n height: 1.25rem;\n}\n.\\[\\&_\\[cmdk-item\\]_svg\\]\\:w-5 [cmdk-item] svg {\n width: 1.25rem;\n}\n";
73897
+ const styleCss = "/*\n Need to explicitly set config path, otherwise it may fail to resolve when\n built from outside packages/ui.\n*/\n\n/*\n ! tailwindcss v3.3.5 | MIT License | https://tailwindcss.com\n*/\n\n/*\n1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)\n2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)\n*/\n\n*,\n::before,\n::after {\n box-sizing: border-box; /* 1 */\n border-width: 0; /* 2 */\n border-style: solid; /* 2 */\n border-color: #e5e7eb; /* 2 */\n}\n\n::before,\n::after {\n --tw-content: '';\n}\n\n/*\n1. Use a consistent sensible line-height in all browsers.\n2. Prevent adjustments of font size after orientation changes in iOS.\n3. Use a more readable tab size.\n4. Use the user's configured `sans` font-family by default.\n5. Use the user's configured `sans` font-feature-settings by default.\n6. Use the user's configured `sans` font-variation-settings by default.\n*/\n\nhtml {\n line-height: 1.5; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n -moz-tab-size: 4; /* 3 */\n -o-tab-size: 4;\n tab-size: 4; /* 3 */\n font-family: 'Roboto', sans-serif; /* 4 */\n font-feature-settings: normal; /* 5 */\n font-variation-settings: normal; /* 6 */\n}\n\n/*\n1. Remove the margin in all browsers.\n2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.\n*/\n\nbody {\n margin: 0; /* 1 */\n line-height: inherit; /* 2 */\n}\n\n/*\n1. Add the correct height in Firefox.\n2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)\n3. Ensure horizontal rules are visible by default.\n*/\n\nhr {\n height: 0; /* 1 */\n color: inherit; /* 2 */\n border-top-width: 1px; /* 3 */\n}\n\n/*\nAdd the correct text decoration in Chrome, Edge, and Safari.\n*/\n\nabbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n}\n\n/*\nRemove the default font size and weight for headings.\n*/\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-size: inherit;\n font-weight: inherit;\n}\n\n/*\nReset links to optimize for opt-in styling instead of opt-out.\n*/\n\na {\n color: inherit;\n text-decoration: inherit;\n}\n\n/*\nAdd the correct font weight in Edge and Safari.\n*/\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/*\n1. Use the user's configured `mono` font family by default.\n2. Correct the odd `em` font sizing in all browsers.\n*/\n\ncode,\nkbd,\nsamp,\npre {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/*\nAdd the correct font size in all browsers.\n*/\n\nsmall {\n font-size: 80%;\n}\n\n/*\nPrevent `sub` and `sup` elements from affecting the line height in all browsers.\n*/\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/*\n1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)\n2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)\n3. Remove gaps between table borders by default.\n*/\n\ntable {\n text-indent: 0; /* 1 */\n border-color: inherit; /* 2 */\n border-collapse: collapse; /* 3 */\n}\n\n/*\n1. Change the font styles in all browsers.\n2. Remove the margin in Firefox and Safari.\n3. Remove default padding in all browsers.\n*/\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-feature-settings: inherit; /* 1 */\n font-variation-settings: inherit; /* 1 */\n font-size: 100%; /* 1 */\n font-weight: inherit; /* 1 */\n line-height: inherit; /* 1 */\n color: inherit; /* 1 */\n margin: 0; /* 2 */\n padding: 0; /* 3 */\n}\n\n/*\nRemove the inheritance of text transform in Edge and Firefox.\n*/\n\nbutton,\nselect {\n text-transform: none;\n}\n\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Remove default button styles.\n*/\n\nbutton,\n[type='button'],\n[type='reset'],\n[type='submit'] {\n -webkit-appearance: button; /* 1 */\n background-color: transparent; /* 2 */\n background-image: none; /* 2 */\n}\n\n/*\nUse the modern Firefox focus style for all focusable elements.\n*/\n\n:-moz-focusring {\n outline: auto;\n}\n\n/*\nRemove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)\n*/\n\n:-moz-ui-invalid {\n box-shadow: none;\n}\n\n/*\nAdd the correct vertical alignment in Chrome and Firefox.\n*/\n\nprogress {\n vertical-align: baseline;\n}\n\n/*\nCorrect the cursor style of increment and decrement buttons in Safari.\n*/\n\n::-webkit-inner-spin-button,\n::-webkit-outer-spin-button {\n height: auto;\n}\n\n/*\n1. Correct the odd appearance in Chrome and Safari.\n2. Correct the outline style in Safari.\n*/\n\n[type='search'] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/*\nRemove the inner padding in Chrome and Safari on macOS.\n*/\n\n::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Change font properties to `inherit` in Safari.\n*/\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/*\nAdd the correct display in Chrome and Safari.\n*/\n\nsummary {\n display: list-item;\n}\n\n/*\nRemoves the default spacing and border for appropriate elements.\n*/\n\nblockquote,\ndl,\ndd,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhr,\nfigure,\np,\npre {\n margin: 0;\n}\n\nfieldset {\n margin: 0;\n padding: 0;\n}\n\nlegend {\n padding: 0;\n}\n\nol,\nul,\nmenu {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n/*\nReset default styling for dialogs.\n*/\n\ndialog {\n padding: 0;\n}\n\n/*\nPrevent resizing textareas horizontally by default.\n*/\n\ntextarea {\n resize: vertical;\n}\n\n/*\n1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)\n2. Set the default placeholder color to the user's configured gray 400 color.\n*/\n\ninput::-moz-placeholder, textarea::-moz-placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\n\ninput::placeholder,\ntextarea::placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\n\n/*\nSet the default cursor for buttons.\n*/\n\nbutton,\n[role=\"button\"] {\n cursor: pointer;\n}\n\n/*\nMake sure disabled buttons don't get the pointer cursor.\n*/\n\n:disabled {\n cursor: default;\n}\n\n/*\n1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)\n2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)\n This can trigger a poorly considered lint error in some tools but is included by design.\n*/\n\nimg,\nsvg,\nvideo,\ncanvas,\naudio,\niframe,\nembed,\nobject {\n display: block; /* 1 */\n vertical-align: middle; /* 2 */\n}\n\n/*\nConstrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)\n*/\n\nimg,\nvideo {\n max-width: 100%;\n height: auto;\n}\n\n/* Make elements with the HTML hidden attribute stay hidden by default */\n\n[hidden] {\n display: none;\n}\n\n/* :host for use with Shadow DOM, copied from the TailwindCSS prelude */\n\n:host {\n --background: 0 0% 100%;\n --foreground: 222.2 84% 4.9%;\n\n --card: 0 0% 100%;\n --card-foreground: 222.2 84% 4.9%;\n\n --popover: 0 0% 100%;\n --popover-foreground: 222.2 84% 4.9%;\n\n --primary: 222.2 47.4% 11.2%;\n --primary-foreground: 210 40% 98%;\n\n --secondary: 210 40% 96.1%;\n --secondary-foreground: 222.2 47.4% 11.2%;\n\n --muted: 0 0% 57.3%;\n --muted-foreground: 215.4 16.3% 46.9%;\n\n --accent: 159, 60%, 51%, 1;\n --accent-foreground: 222.2 47.4% 11.2%;\n\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 40% 98%;\n\n --border: 214.3 31.8% 91.4%;\n --input: 214.3 31.8% 91.4%;\n --ring: 222.2 84% 4.9%;\n\n --radius: 0.5rem;\n }\n\n:root {\n --background: 0 0% 100%;\n --foreground: 222.2 84% 4.9%;\n\n --card: 0 0% 100%;\n --card-foreground: 222.2 84% 4.9%;\n\n --popover: 0 0% 100%;\n --popover-foreground: 222.2 84% 4.9%;\n\n --primary: 222.2 47.4% 11.2%;\n --primary-foreground: 210 40% 98%;\n\n --secondary: 210 40% 96.1%;\n --secondary-foreground: 222.2 47.4% 11.2%;\n\n --muted: 0 0% 57.3%;\n --muted-foreground: 215.4 16.3% 46.9%;\n\n --accent: 159, 60%, 51%, 1;\n --accent-foreground: 222.2 47.4% 11.2%;\n\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 40% 98%;\n\n --border: 214.3 31.8% 91.4%;\n --input: 214.3 31.8% 91.4%;\n --ring: 222.2 84% 4.9%;\n\n --radius: 0.5rem;\n }\n\n/* dark theme */\n\n*[data-mode=\"dark\"] {\n --background: 0 0% 4%;\n --foreground: 210 40% 98%;\n\n --card: 222.2 84% 4.9%;\n --card-foreground: 210 40% 98%;\n\n --popover: 222.2 84% 4.9%;\n --popover-foreground: 210 40% 98%;\n\n --primary: 210 40% 98%;\n --primary-foreground: 222.2 47.4% 11.2%;\n\n --secondary: 217.2 32.6% 17.5%;\n --secondary-foreground: 210 40% 98%;\n\n --muted: 178, 23%, 76%, 1;\n --muted-foreground: 215 20.2% 65.1%;\n\n --accent: 159, 60%, 51%, 1;\n --accent-foreground: 210 40% 98%;\n\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 210 40% 98%;\n\n --border: 217.2 32.6% 17.5%;\n --input: 217.2 32.6% 17.5%;\n --ring: 212.7 26.8% 83.9%;\n }\n\n* {\n border-color: hsl(var(--border));\n}\n\nbody {\n background-color: hsl(var(--background));\n color: hsl(var(--foreground));\n}\n\n*, ::before, ::after {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n}\n\n::backdrop {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n}\n.pointer-events-none {\n pointer-events: none;\n}\n.invisible {\n visibility: hidden;\n}\n.static {\n position: static;\n}\n.fixed {\n position: fixed;\n}\n.absolute {\n position: absolute;\n}\n.relative {\n position: relative;\n}\n.sticky {\n position: sticky;\n}\n.inset-0 {\n inset: 0px;\n}\n.inset-y-0 {\n top: 0px;\n bottom: 0px;\n}\n.-left-2 {\n left: -0.5rem;\n}\n.-right-\\[10px\\] {\n right: -10px;\n}\n.-top-\\[10px\\] {\n top: -10px;\n}\n.-top-\\[4px\\] {\n top: -4px;\n}\n.bottom-0 {\n bottom: 0px;\n}\n.bottom-4 {\n bottom: 1rem;\n}\n.left-0 {\n left: 0px;\n}\n.left-1 {\n left: 0.25rem;\n}\n.left-1\\/2 {\n left: 50%;\n}\n.left-2 {\n left: 0.5rem;\n}\n.left-\\[50\\%\\] {\n left: 50%;\n}\n.right-0 {\n right: 0px;\n}\n.right-1 {\n right: 0.25rem;\n}\n.right-4 {\n right: 1rem;\n}\n.right-\\[16px\\] {\n right: 16px;\n}\n.top-0 {\n top: 0px;\n}\n.top-4 {\n top: 1rem;\n}\n.top-\\[50\\%\\] {\n top: 50%;\n}\n.z-50 {\n z-index: 50;\n}\n.z-\\[5\\] {\n z-index: 5;\n}\n.z-overlay {\n z-index: 4;\n}\n.-mx-1 {\n margin-left: -0.25rem;\n margin-right: -0.25rem;\n}\n.-my-2 {\n margin-top: -0.5rem;\n margin-bottom: -0.5rem;\n}\n.-my-\\[100px\\] {\n margin-top: -100px;\n margin-bottom: -100px;\n}\n.mx-2 {\n margin-left: 0.5rem;\n margin-right: 0.5rem;\n}\n.my-1 {\n margin-top: 0.25rem;\n margin-bottom: 0.25rem;\n}\n.mb-4 {\n margin-bottom: 1rem;\n}\n.ml-2 {\n margin-left: 0.5rem;\n}\n.ml-4 {\n margin-left: 1rem;\n}\n.ml-\\[20px\\] {\n margin-left: 20px;\n}\n.ml-auto {\n margin-left: auto;\n}\n.mr-2 {\n margin-right: 0.5rem;\n}\n.mt-2 {\n margin-top: 0.5rem;\n}\n.block {\n display: block;\n}\n.inline {\n display: inline;\n}\n.flex {\n display: flex;\n}\n.inline-flex {\n display: inline-flex;\n}\n.table {\n display: table;\n}\n.grid {\n display: grid;\n}\n.hidden {\n display: none;\n}\n.aspect-square {\n aspect-ratio: 1 / 1;\n}\n.h-10 {\n height: 2.5rem;\n}\n.h-11 {\n height: 2.75rem;\n}\n.h-2 {\n height: 0.5rem;\n}\n.h-2\\.5 {\n height: 0.625rem;\n}\n.h-3 {\n height: 0.75rem;\n}\n.h-3\\.5 {\n height: 0.875rem;\n}\n.h-4 {\n height: 1rem;\n}\n.h-7 {\n height: 1.75rem;\n}\n.h-9 {\n height: 2.25rem;\n}\n.h-\\[14px\\] {\n height: 14px;\n}\n.h-\\[18px\\] {\n height: 18px;\n}\n.h-\\[1px\\] {\n height: 1px;\n}\n.h-\\[20px\\] {\n height: 20px;\n}\n.h-\\[22px\\] {\n height: 22px;\n}\n.h-\\[24px\\] {\n height: 24px;\n}\n.h-\\[32px\\] {\n height: 32px;\n}\n.h-\\[50px\\] {\n height: 50px;\n}\n.h-\\[75px\\] {\n height: 75px;\n}\n.h-\\[9px\\] {\n height: 9px;\n}\n.h-\\[var\\(--radix-select-trigger-height\\)\\] {\n height: var(--radix-select-trigger-height);\n}\n.h-full {\n height: 100%;\n}\n.h-px {\n height: 1px;\n}\n.h-screen {\n height: 100vh;\n}\n.max-h-\\[300px\\] {\n max-height: 300px;\n}\n.min-h-\\[200px\\] {\n min-height: 200px;\n}\n.min-h-\\[300px\\] {\n min-height: 300px;\n}\n.min-h-screen {\n min-height: 100vh;\n}\n.w-1\\/3 {\n width: 33.333333%;\n}\n.w-10 {\n width: 2.5rem;\n}\n.w-2 {\n width: 0.5rem;\n}\n.w-2\\.5 {\n width: 0.625rem;\n}\n.w-3 {\n width: 0.75rem;\n}\n.w-3\\.5 {\n width: 0.875rem;\n}\n.w-4 {\n width: 1rem;\n}\n.w-5 {\n width: 1.25rem;\n}\n.w-7 {\n width: 1.75rem;\n}\n.w-72 {\n width: 18rem;\n}\n.w-9 {\n width: 2.25rem;\n}\n.w-\\[14px\\] {\n width: 14px;\n}\n.w-\\[1px\\] {\n width: 1px;\n}\n.w-\\[20px\\] {\n width: 20px;\n}\n.w-\\[24px\\] {\n width: 24px;\n}\n.w-\\[32px\\] {\n width: 32px;\n}\n.w-\\[44px\\] {\n width: 44px;\n}\n.w-\\[9px\\] {\n width: 9px;\n}\n.w-fit {\n width: -moz-fit-content;\n width: fit-content;\n}\n.w-full {\n width: 100%;\n}\n.w-screen {\n width: 100vw;\n}\n.min-w-0 {\n min-width: 0px;\n}\n.min-w-\\[320px\\] {\n min-width: 320px;\n}\n.min-w-\\[500px\\] {\n min-width: 500px;\n}\n.min-w-\\[8rem\\] {\n min-width: 8rem;\n}\n.min-w-\\[var\\(--radix-select-trigger-width\\)\\] {\n min-width: var(--radix-select-trigger-width);\n}\n.max-w-4xl {\n max-width: 56rem;\n}\n.max-w-\\[1000px\\] {\n max-width: 1000px;\n}\n.max-w-\\[10vw\\] {\n max-width: 10vw;\n}\n.max-w-\\[300px\\] {\n max-width: 300px;\n}\n.max-w-\\[90vw\\] {\n max-width: 90vw;\n}\n.max-w-lg {\n max-width: 32rem;\n}\n.flex-1 {\n flex: 1 1 0%;\n}\n.flex-auto {\n flex: 1 1 auto;\n}\n.flex-shrink-0 {\n flex-shrink: 0;\n}\n.shrink-0 {\n flex-shrink: 0;\n}\n.flex-grow {\n flex-grow: 1;\n}\n.border-collapse {\n border-collapse: collapse;\n}\n.-translate-x-1\\/2 {\n --tw-translate-x: -50%;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.translate-x-\\[-50\\%\\] {\n --tw-translate-x: -50%;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.translate-y-\\[-50\\%\\] {\n --tw-translate-y: -50%;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.-rotate-90 {\n --tw-rotate: -90deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.rotate-90 {\n --tw-rotate: 90deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.rotate-\\[-90deg\\] {\n --tw-rotate: -90deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.rotate-\\[90deg\\] {\n --tw-rotate: 90deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.transform {\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.cursor-col-resize {\n cursor: col-resize;\n}\n.cursor-default {\n cursor: default;\n}\n.cursor-grab {\n cursor: grab;\n}\n.cursor-pointer {\n cursor: pointer;\n}\n.cursor-se-resize {\n cursor: se-resize;\n}\n.touch-none {\n touch-action: none;\n}\n.select-none {\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n}\n.resize-none {\n resize: none;\n}\n.resize {\n resize: both;\n}\n.list-decimal {\n list-style-type: decimal;\n}\n.list-disc {\n list-style-type: disc;\n}\n.grid-cols-\\[min-content_1fr\\] {\n grid-template-columns: min-content 1fr;\n}\n.grid-rows-\\[1fr\\2c _min-content\\] {\n grid-template-rows: 1fr min-content;\n}\n.flex-row {\n flex-direction: row;\n}\n.flex-col {\n flex-direction: column;\n}\n.flex-col-reverse {\n flex-direction: column-reverse;\n}\n.items-start {\n align-items: flex-start;\n}\n.items-center {\n align-items: center;\n}\n.justify-start {\n justify-content: flex-start;\n}\n.justify-end {\n justify-content: flex-end;\n}\n.justify-center {\n justify-content: center;\n}\n.justify-between {\n justify-content: space-between;\n}\n.gap-1 {\n gap: 0.25rem;\n}\n.gap-2 {\n gap: 0.5rem;\n}\n.gap-3 {\n gap: 0.75rem;\n}\n.gap-4 {\n gap: 1rem;\n}\n.gap-5 {\n gap: 1.25rem;\n}\n.gap-\\[0\\.5em\\] {\n gap: 0.5em;\n}\n.gap-\\[36px\\] {\n gap: 36px;\n}\n.gap-x-2 {\n -moz-column-gap: 0.5rem;\n column-gap: 0.5rem;\n}\n.gap-x-3 {\n -moz-column-gap: 0.75rem;\n column-gap: 0.75rem;\n}\n.gap-x-4 {\n -moz-column-gap: 1rem;\n column-gap: 1rem;\n}\n.gap-y-2 {\n row-gap: 0.5rem;\n}\n.gap-y-4 {\n row-gap: 1rem;\n}\n.gap-y-6 {\n row-gap: 1.5rem;\n}\n.gap-y-8 {\n row-gap: 2rem;\n}\n.space-x-1 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-x-reverse: 0;\n margin-right: calc(0.25rem * var(--tw-space-x-reverse));\n margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse)));\n}\n.space-y-1 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));\n}\n.space-y-1\\.5 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(0.375rem * var(--tw-space-y-reverse));\n}\n.space-y-2 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));\n}\n.space-y-4 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(1rem * var(--tw-space-y-reverse));\n}\n.overflow-auto {\n overflow: auto;\n}\n.overflow-hidden {\n overflow: hidden;\n}\n.overflow-clip {\n overflow: clip;\n}\n.overflow-scroll {\n overflow: scroll;\n}\n.overflow-y-auto {\n overflow-y: auto;\n}\n.overflow-x-hidden {\n overflow-x: hidden;\n}\n.overflow-y-scroll {\n overflow-y: scroll;\n}\n.truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.whitespace-nowrap {\n white-space: nowrap;\n}\n.rounded {\n border-radius: 0.25rem;\n}\n.rounded-\\[inherit\\] {\n border-radius: inherit;\n}\n.rounded-full {\n border-radius: 9999px;\n}\n.rounded-lg {\n border-radius: var(--radius);\n}\n.rounded-md {\n border-radius: calc(var(--radius) - 2px);\n}\n.rounded-sm {\n border-radius: calc(var(--radius) - 4px);\n}\n.border {\n border-width: 1px;\n}\n.border-2 {\n border-width: 2px;\n}\n.border-\\[2px\\] {\n border-width: 2px;\n}\n.border-y {\n border-top-width: 1px;\n border-bottom-width: 1px;\n}\n.border-b {\n border-bottom-width: 1px;\n}\n.border-l {\n border-left-width: 1px;\n}\n.border-l-2 {\n border-left-width: 2px;\n}\n.border-r {\n border-right-width: 1px;\n}\n.border-t {\n border-top-width: 1px;\n}\n.border-accent {\n border-color: hsl(var(--accent));\n}\n.border-border {\n border-color: hsl(var(--border));\n}\n.border-card {\n border-color: hsl(var(--card));\n}\n.border-gray-400 {\n --tw-border-opacity: 1;\n border-color: rgb(156 163 175 / var(--tw-border-opacity));\n}\n.border-input {\n border-color: hsl(var(--input));\n}\n.border-primary {\n border-color: hsl(var(--primary));\n}\n.border-transparent {\n border-color: transparent;\n}\n.border-l-transparent {\n border-left-color: transparent;\n}\n.border-t-transparent {\n border-top-color: transparent;\n}\n.bg-accent {\n background-color: hsl(var(--accent));\n}\n.bg-background {\n background-color: hsl(var(--background));\n}\n.bg-background\\/80 {\n background-color: hsl(var(--background) / 0.8);\n}\n.bg-border {\n background-color: hsl(var(--border));\n}\n.bg-card {\n background-color: hsl(var(--card));\n}\n.bg-card-foreground {\n background-color: hsl(var(--card-foreground));\n}\n.bg-destructive {\n background-color: hsl(var(--destructive));\n}\n.bg-gray-300 {\n --tw-bg-opacity: 1;\n background-color: rgb(209 213 219 / var(--tw-bg-opacity));\n}\n.bg-gray-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(107 114 128 / var(--tw-bg-opacity));\n}\n.bg-muted {\n background-color: hsl(var(--muted));\n}\n.bg-popover {\n background-color: hsl(var(--popover));\n}\n.bg-primary {\n background-color: hsl(var(--primary));\n}\n.bg-red-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(239 68 68 / var(--tw-bg-opacity));\n}\n.bg-secondary {\n background-color: hsl(var(--secondary));\n}\n.bg-transparent {\n background-color: transparent;\n}\n.bg-white {\n --tw-bg-opacity: 1;\n background-color: rgb(255 255 255 / var(--tw-bg-opacity));\n}\n.bg-gradient-to-b {\n background-image: linear-gradient(to bottom, var(--tw-gradient-stops));\n}\n.from-transparent {\n --tw-gradient-from: transparent var(--tw-gradient-from-position);\n --tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position);\n --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);\n}\n.to-background {\n --tw-gradient-to: hsl(var(--background)) var(--tw-gradient-to-position);\n}\n.fill-current {\n fill: currentColor;\n}\n.fill-white {\n fill: #fff;\n}\n.stroke-\\[2px\\] {\n stroke-width: 2px;\n}\n.stroke-\\[3px\\] {\n stroke-width: 3px;\n}\n.object-contain {\n -o-object-fit: contain;\n object-fit: contain;\n}\n.p-0 {\n padding: 0px;\n}\n.p-1 {\n padding: 0.25rem;\n}\n.p-10 {\n padding: 2.5rem;\n}\n.p-2 {\n padding: 0.5rem;\n}\n.p-3 {\n padding: 0.75rem;\n}\n.p-4 {\n padding: 1rem;\n}\n.p-6 {\n padding: 1.5rem;\n}\n.p-\\[1px\\] {\n padding: 1px;\n}\n.px-1 {\n padding-left: 0.25rem;\n padding-right: 0.25rem;\n}\n.px-2 {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.px-2\\.5 {\n padding-left: 0.625rem;\n padding-right: 0.625rem;\n}\n.px-3 {\n padding-left: 0.75rem;\n padding-right: 0.75rem;\n}\n.px-4 {\n padding-left: 1rem;\n padding-right: 1rem;\n}\n.px-5 {\n padding-left: 1.25rem;\n padding-right: 1.25rem;\n}\n.px-8 {\n padding-left: 2rem;\n padding-right: 2rem;\n}\n.px-\\[24px\\] {\n padding-left: 24px;\n padding-right: 24px;\n}\n.py-1 {\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n}\n.py-1\\.5 {\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n}\n.py-2 {\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n}\n.py-3 {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n}\n.py-4 {\n padding-top: 1rem;\n padding-bottom: 1rem;\n}\n.py-6 {\n padding-top: 1.5rem;\n padding-bottom: 1.5rem;\n}\n.py-7 {\n padding-top: 1.75rem;\n padding-bottom: 1.75rem;\n}\n.py-\\[2px\\] {\n padding-top: 2px;\n padding-bottom: 2px;\n}\n.pb-0 {\n padding-bottom: 0px;\n}\n.pb-20 {\n padding-bottom: 5rem;\n}\n.pb-4 {\n padding-bottom: 1rem;\n}\n.pl-6 {\n padding-left: 1.5rem;\n}\n.pl-8 {\n padding-left: 2rem;\n}\n.pr-2 {\n padding-right: 0.5rem;\n}\n.pt-0 {\n padding-top: 0px;\n}\n.pt-1 {\n padding-top: 0.25rem;\n}\n.pt-2 {\n padding-top: 0.5rem;\n}\n.pt-4 {\n padding-top: 1rem;\n}\n.text-left {\n text-align: left;\n}\n.text-center {\n text-align: center;\n}\n.text-start {\n text-align: start;\n}\n.font-sans {\n font-family: 'Roboto', sans-serif;\n}\n.font-serif {\n font-family: 'Space Mono', monospace;\n}\n.text-2xl {\n font-size: 1.5rem;\n line-height: 2rem;\n}\n.text-3xl {\n font-size: 1.875rem;\n line-height: 2.25rem;\n}\n.text-4xl {\n font-size: 2.25rem;\n line-height: 2.5rem;\n}\n.text-\\[0\\.8rem\\] {\n font-size: 0.8rem;\n}\n.text-\\[12px\\] {\n font-size: 12px;\n}\n.text-lg {\n font-size: 1.125rem;\n line-height: 1.75rem;\n}\n.text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n.text-xl {\n font-size: 1.25rem;\n line-height: 1.75rem;\n}\n.text-xs {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n.font-\\[12px\\] {\n font-weight: 12px;\n}\n.font-\\[400\\] {\n font-weight: 400;\n}\n.font-\\[500\\] {\n font-weight: 500;\n}\n.font-\\[550\\] {\n font-weight: 550;\n}\n.font-bold {\n font-weight: 700;\n}\n.font-extrabold {\n font-weight: 800;\n}\n.font-medium {\n font-weight: 500;\n}\n.font-normal {\n font-weight: 400;\n}\n.font-semibold {\n font-weight: 600;\n}\n.uppercase {\n text-transform: uppercase;\n}\n.italic {\n font-style: italic;\n}\n.leading-4 {\n line-height: 1rem;\n}\n.leading-none {\n line-height: 1;\n}\n.tracking-\\[0\\.04em\\] {\n letter-spacing: 0.04em;\n}\n.tracking-tight {\n letter-spacing: -0.025em;\n}\n.tracking-wider {\n letter-spacing: 0.05em;\n}\n.tracking-widest {\n letter-spacing: 0.1em;\n}\n.text-accent {\n color: hsl(var(--accent));\n}\n.text-accent-foreground {\n color: hsl(var(--accent-foreground));\n}\n.text-background {\n color: hsl(var(--background));\n}\n.text-card-foreground {\n color: hsl(var(--card-foreground));\n}\n.text-current {\n color: currentColor;\n}\n.text-destructive {\n color: hsl(var(--destructive));\n}\n.text-destructive-foreground {\n color: hsl(var(--destructive-foreground));\n}\n.text-foreground {\n color: hsl(var(--foreground));\n}\n.text-muted {\n color: hsl(var(--muted));\n}\n.text-muted-foreground {\n color: hsl(var(--muted-foreground));\n}\n.text-popover-foreground {\n color: hsl(var(--popover-foreground));\n}\n.text-primary {\n color: hsl(var(--primary));\n}\n.text-primary-foreground {\n color: hsl(var(--primary-foreground));\n}\n.text-secondary-foreground {\n color: hsl(var(--secondary-foreground));\n}\n.text-white {\n --tw-text-opacity: 1;\n color: rgb(255 255 255 / var(--tw-text-opacity));\n}\n.underline {\n text-decoration-line: underline;\n}\n.line-through {\n text-decoration-line: line-through;\n}\n.underline-offset-4 {\n text-underline-offset: 4px;\n}\n.antialiased {\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.opacity-0 {\n opacity: 0;\n}\n.opacity-100 {\n opacity: 1;\n}\n.opacity-50 {\n opacity: 0.5;\n}\n.opacity-60 {\n opacity: 0.6;\n}\n.opacity-70 {\n opacity: 0.7;\n}\n.opacity-75 {\n opacity: 0.75;\n}\n.shadow {\n --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.shadow-lg {\n --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.shadow-md {\n --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.shadow-sm {\n --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.outline-none {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n.outline {\n outline-style: solid;\n}\n.ring-0 {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);\n}\n.ring-offset-background {\n --tw-ring-offset-color: hsl(var(--background));\n}\n.drop-shadow-2xl {\n --tw-drop-shadow: drop-shadow(0 25px 25px rgb(0 0 0 / 0.15));\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.drop-shadow-\\[0px_0px_12px_rgba\\(56\\2c 205\\2c 152\\2c 0\\.60\\)\\] {\n --tw-drop-shadow: drop-shadow(0px 0px 12px rgba(56,205,152,0.60));\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.filter {\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.backdrop-blur-sm {\n --tw-backdrop-blur: blur(4px);\n -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\n backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);\n}\n.transition-all {\n transition-property: all;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.transition-colors {\n transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.transition-opacity {\n transition-property: opacity;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.transition-transform {\n transition-property: transform;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms;\n}\n.duration-150 {\n transition-duration: 150ms;\n}\n.duration-200 {\n transition-duration: 200ms;\n}\n.ease-in-out {\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n@keyframes enter {\n\n from {\n opacity: var(--tw-enter-opacity, 1);\n transform: translate3d(var(--tw-enter-translate-x, 0), var(--tw-enter-translate-y, 0), 0) scale3d(var(--tw-enter-scale, 1), var(--tw-enter-scale, 1), var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0));\n }\n}\n@keyframes exit {\n\n to {\n opacity: var(--tw-exit-opacity, 1);\n transform: translate3d(var(--tw-exit-translate-x, 0), var(--tw-exit-translate-y, 0), 0) scale3d(var(--tw-exit-scale, 1), var(--tw-exit-scale, 1), var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0));\n }\n}\n.animate-in {\n animation-name: enter;\n animation-duration: 150ms;\n --tw-enter-opacity: initial;\n --tw-enter-scale: initial;\n --tw-enter-rotate: initial;\n --tw-enter-translate-x: initial;\n --tw-enter-translate-y: initial;\n}\n.fade-in-0 {\n --tw-enter-opacity: 0;\n}\n.zoom-in-95 {\n --tw-enter-scale: .95;\n}\n.duration-150 {\n animation-duration: 150ms;\n}\n.duration-200 {\n animation-duration: 200ms;\n}\n.ease-in-out {\n animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n}\n.file\\:border-0::file-selector-button {\n border-width: 0px;\n}\n.file\\:bg-transparent::file-selector-button {\n background-color: transparent;\n}\n.file\\:text-sm::file-selector-button {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n.file\\:font-medium::file-selector-button {\n font-weight: 500;\n}\n.placeholder\\:text-muted-foreground::-moz-placeholder {\n color: hsl(var(--muted-foreground));\n}\n.placeholder\\:text-muted-foreground::placeholder {\n color: hsl(var(--muted-foreground));\n}\n.focus-within\\:relative:focus-within {\n position: relative;\n}\n.hover\\:w-\\[2px\\]:hover {\n width: 2px;\n}\n.hover\\:w-\\[3px\\]:hover {\n width: 3px;\n}\n.hover\\:cursor-pointer:hover {\n cursor: pointer;\n}\n.hover\\:rounded-lg:hover {\n border-radius: var(--radius);\n}\n.hover\\:bg-accent:hover {\n background-color: hsl(var(--accent));\n}\n.hover\\:bg-background:hover {\n background-color: hsl(var(--background));\n}\n.hover\\:bg-border:hover {\n background-color: hsl(var(--border));\n}\n.hover\\:bg-destructive\\/90:hover {\n background-color: hsl(var(--destructive) / 0.9);\n}\n.hover\\:bg-muted:hover {\n background-color: hsl(var(--muted));\n}\n.hover\\:bg-primary:hover {\n background-color: hsl(var(--primary));\n}\n.hover\\:bg-primary\\/90:hover {\n background-color: hsl(var(--primary) / 0.9);\n}\n.hover\\:bg-red-700:hover {\n --tw-bg-opacity: 1;\n background-color: rgb(185 28 28 / var(--tw-bg-opacity));\n}\n.hover\\:bg-secondary\\/80:hover {\n background-color: hsl(var(--secondary) / 0.8);\n}\n.hover\\:text-accent-foreground:hover {\n color: hsl(var(--accent-foreground));\n}\n.hover\\:text-muted-foreground:hover {\n color: hsl(var(--muted-foreground));\n}\n.hover\\:text-primary-foreground:hover {\n color: hsl(var(--primary-foreground));\n}\n.hover\\:text-white:hover {\n --tw-text-opacity: 1;\n color: rgb(255 255 255 / var(--tw-text-opacity));\n}\n.hover\\:underline:hover {\n text-decoration-line: underline;\n}\n.hover\\:opacity-100:hover {\n opacity: 1;\n}\n.focus\\:bg-accent:focus {\n background-color: hsl(var(--accent));\n}\n.focus\\:bg-primary:focus {\n background-color: hsl(var(--primary));\n}\n.focus\\:text-accent-foreground:focus {\n color: hsl(var(--accent-foreground));\n}\n.focus\\:text-primary-foreground:focus {\n color: hsl(var(--primary-foreground));\n}\n.focus\\:outline-none:focus {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n.focus\\:ring-2:focus {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);\n}\n.focus\\:ring-ring:focus {\n --tw-ring-color: hsl(var(--ring));\n}\n.focus\\:ring-offset-2:focus {\n --tw-ring-offset-width: 2px;\n}\n.focus-visible\\:outline-none:focus-visible {\n outline: 2px solid transparent;\n outline-offset: 2px;\n}\n.focus-visible\\:outline-accent:focus-visible {\n outline-color: hsl(var(--accent));\n}\n.focus-visible\\:ring-2:focus-visible {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);\n}\n.focus-visible\\:ring-ring:focus-visible {\n --tw-ring-color: hsl(var(--ring));\n}\n.focus-visible\\:ring-offset-2:focus-visible {\n --tw-ring-offset-width: 2px;\n}\n.focus-visible\\:ring-offset-background:focus-visible {\n --tw-ring-offset-color: hsl(var(--background));\n}\n.disabled\\:pointer-events-none:disabled {\n pointer-events: none;\n}\n.disabled\\:cursor-not-allowed:disabled {\n cursor: not-allowed;\n}\n.disabled\\:text-background:disabled {\n color: hsl(var(--background));\n}\n.disabled\\:opacity-50:disabled {\n opacity: 0.5;\n}\n.peer:disabled ~ .peer-disabled\\:cursor-not-allowed {\n cursor: not-allowed;\n}\n.peer:disabled ~ .peer-disabled\\:opacity-70 {\n opacity: 0.7;\n}\n.aria-selected\\:bg-accent[aria-selected=\"true\"] {\n background-color: hsl(var(--accent));\n}\n.aria-selected\\:text-accent-foreground[aria-selected=\"true\"] {\n color: hsl(var(--accent-foreground));\n}\n.aria-selected\\:opacity-100[aria-selected=\"true\"] {\n opacity: 1;\n}\n.data-\\[disabled\\]\\:pointer-events-none[data-disabled] {\n pointer-events: none;\n}\n.data-\\[side\\=bottom\\]\\:translate-y-1[data-side=bottom] {\n --tw-translate-y: 0.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[side\\=left\\]\\:-translate-x-1[data-side=left] {\n --tw-translate-x: -0.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[side\\=right\\]\\:translate-x-1[data-side=right] {\n --tw-translate-x: 0.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[side\\=top\\]\\:-translate-y-1[data-side=top] {\n --tw-translate-y: -0.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[state\\=checked\\]\\:translate-x-5[data-state=checked] {\n --tw-translate-x: 1.25rem;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.data-\\[state\\=unchecked\\]\\:translate-x-0[data-state=unchecked] {\n --tw-translate-x: 0px;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n@keyframes accordion-up {\n\n from {\n height: var(--radix-accordion-content-height);\n }\n\n to {\n height: 0;\n }\n}\n.data-\\[state\\=closed\\]\\:animate-accordion-up[data-state=closed] {\n animation: accordion-up 0.2s ease-out;\n}\n@keyframes accordion-down {\n\n from {\n height: 0;\n }\n\n to {\n height: var(--radix-accordion-content-height);\n }\n}\n.data-\\[state\\=open\\]\\:animate-accordion-down[data-state=open] {\n animation: accordion-down 0.2s ease-out;\n}\n.data-\\[state\\=active\\]\\:bg-background[data-state=active] {\n background-color: hsl(var(--background));\n}\n.data-\\[state\\=checked\\]\\:bg-accent[data-state=checked] {\n background-color: hsl(var(--accent));\n}\n.data-\\[state\\=checked\\]\\:bg-primary[data-state=checked] {\n background-color: hsl(var(--primary));\n}\n.data-\\[state\\=on\\]\\:bg-accent[data-state=on] {\n background-color: hsl(var(--accent));\n}\n.data-\\[state\\=open\\]\\:bg-accent[data-state=open] {\n background-color: hsl(var(--accent));\n}\n.data-\\[state\\=unchecked\\]\\:bg-primary[data-state=unchecked] {\n background-color: hsl(var(--primary));\n}\n.data-\\[state\\=active\\]\\:text-foreground[data-state=active] {\n color: hsl(var(--foreground));\n}\n.data-\\[state\\=checked\\]\\:text-primary-foreground[data-state=checked] {\n color: hsl(var(--primary-foreground));\n}\n.data-\\[state\\=on\\]\\:text-accent-foreground[data-state=on] {\n color: hsl(var(--accent-foreground));\n}\n.data-\\[state\\=open\\]\\:text-muted-foreground[data-state=open] {\n color: hsl(var(--muted-foreground));\n}\n.data-\\[disabled\\]\\:opacity-50[data-disabled] {\n opacity: 0.5;\n}\n.data-\\[state\\=active\\]\\:shadow-sm[data-state=active] {\n --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.data-\\[state\\=open\\]\\:animate-in[data-state=open] {\n animation-name: enter;\n animation-duration: 150ms;\n --tw-enter-opacity: initial;\n --tw-enter-scale: initial;\n --tw-enter-rotate: initial;\n --tw-enter-translate-x: initial;\n --tw-enter-translate-y: initial;\n}\n.data-\\[state\\=closed\\]\\:animate-out[data-state=closed] {\n animation-name: exit;\n animation-duration: 150ms;\n --tw-exit-opacity: initial;\n --tw-exit-scale: initial;\n --tw-exit-rotate: initial;\n --tw-exit-translate-x: initial;\n --tw-exit-translate-y: initial;\n}\n.data-\\[state\\=closed\\]\\:fade-out-0[data-state=closed] {\n --tw-exit-opacity: 0;\n}\n.data-\\[state\\=open\\]\\:fade-in-0[data-state=open] {\n --tw-enter-opacity: 0;\n}\n.data-\\[state\\=closed\\]\\:zoom-out-95[data-state=closed] {\n --tw-exit-scale: .95;\n}\n.data-\\[state\\=open\\]\\:zoom-in-95[data-state=open] {\n --tw-enter-scale: .95;\n}\n.data-\\[side\\=bottom\\]\\:slide-in-from-top-2[data-side=bottom] {\n --tw-enter-translate-y: -0.5rem;\n}\n.data-\\[side\\=left\\]\\:slide-in-from-right-2[data-side=left] {\n --tw-enter-translate-x: 0.5rem;\n}\n.data-\\[side\\=right\\]\\:slide-in-from-left-2[data-side=right] {\n --tw-enter-translate-x: -0.5rem;\n}\n.data-\\[side\\=top\\]\\:slide-in-from-bottom-2[data-side=top] {\n --tw-enter-translate-y: 0.5rem;\n}\n.data-\\[state\\=closed\\]\\:slide-out-to-left-1\\/2[data-state=closed] {\n --tw-exit-translate-x: -50%;\n}\n.data-\\[state\\=closed\\]\\:slide-out-to-top-\\[48\\%\\][data-state=closed] {\n --tw-exit-translate-y: -48%;\n}\n.data-\\[state\\=open\\]\\:slide-in-from-left-1\\/2[data-state=open] {\n --tw-enter-translate-x: -50%;\n}\n.data-\\[state\\=open\\]\\:slide-in-from-top-\\[48\\%\\][data-state=open] {\n --tw-enter-translate-y: -48%;\n}\n:is([data-mode=\"dark\"] .dark\\:border-white) {\n --tw-border-opacity: 1;\n border-color: rgb(255 255 255 / var(--tw-border-opacity));\n}\n@media (min-width: 640px) {\n\n .sm\\:mt-0 {\n margin-top: 0px;\n }\n\n .sm\\:block {\n display: block;\n }\n\n .sm\\:flex-row {\n flex-direction: row;\n }\n\n .sm\\:justify-end {\n justify-content: flex-end;\n }\n\n .sm\\:space-x-2 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-x-reverse: 0;\n margin-right: calc(0.5rem * var(--tw-space-x-reverse));\n margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));\n }\n\n .sm\\:space-x-4 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-x-reverse: 0;\n margin-right: calc(1rem * var(--tw-space-x-reverse));\n margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse)));\n }\n\n .sm\\:space-y-0 > :not([hidden]) ~ :not([hidden]) {\n --tw-space-y-reverse: 0;\n margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse)));\n margin-bottom: calc(0px * var(--tw-space-y-reverse));\n }\n\n .sm\\:rounded-lg {\n border-radius: var(--radius);\n }\n\n .sm\\:p-0 {\n padding: 0px;\n }\n\n .sm\\:text-left {\n text-align: left;\n }\n}\n@media (min-width: 768px) {\n\n .md\\:w-full {\n width: 100%;\n }\n}\n.\\[\\&\\:has\\(\\[aria-selected\\]\\)\\]\\:bg-accent:has([aria-selected]) {\n background-color: hsl(var(--accent));\n}\n.first\\:\\[\\&\\:has\\(\\[aria-selected\\]\\)\\]\\:rounded-l-md:has([aria-selected]):first-child {\n border-top-left-radius: calc(var(--radius) - 2px);\n border-bottom-left-radius: calc(var(--radius) - 2px);\n}\n.last\\:\\[\\&\\:has\\(\\[aria-selected\\]\\)\\]\\:rounded-r-md:has([aria-selected]):last-child {\n border-top-right-radius: calc(var(--radius) - 2px);\n border-bottom-right-radius: calc(var(--radius) - 2px);\n}\n.\\[\\&\\[data-state\\=open\\]\\>svg\\]\\:rotate-180[data-state=open]>svg {\n --tw-rotate: 180deg;\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:px-2 [cmdk-group-heading] {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:py-1\\.5 [cmdk-group-heading] {\n padding-top: 0.375rem;\n padding-bottom: 0.375rem;\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:text-xs [cmdk-group-heading] {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:font-medium [cmdk-group-heading] {\n font-weight: 500;\n}\n.\\[\\&_\\[cmdk-group-heading\\]\\]\\:text-muted-foreground [cmdk-group-heading] {\n color: hsl(var(--muted-foreground));\n}\n.\\[\\&_\\[cmdk-group\\]\\:not\\(\\[hidden\\]\\)_\\~\\[cmdk-group\\]\\]\\:pt-0 [cmdk-group]:not([hidden]) ~[cmdk-group] {\n padding-top: 0px;\n}\n.\\[\\&_\\[cmdk-group\\]\\]\\:px-2 [cmdk-group] {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.\\[\\&_\\[cmdk-input-wrapper\\]_svg\\]\\:h-5 [cmdk-input-wrapper] svg {\n height: 1.25rem;\n}\n.\\[\\&_\\[cmdk-input-wrapper\\]_svg\\]\\:w-5 [cmdk-input-wrapper] svg {\n width: 1.25rem;\n}\n.\\[\\&_\\[cmdk-input\\]\\]\\:h-12 [cmdk-input] {\n height: 3rem;\n}\n.\\[\\&_\\[cmdk-item\\]\\]\\:px-2 [cmdk-item] {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n}\n.\\[\\&_\\[cmdk-item\\]\\]\\:py-3 [cmdk-item] {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n}\n.\\[\\&_\\[cmdk-item\\]_svg\\]\\:h-5 [cmdk-item] svg {\n height: 1.25rem;\n}\n.\\[\\&_\\[cmdk-item\\]_svg\\]\\:w-5 [cmdk-item] svg {\n width: 1.25rem;\n}\n";
73958
73898
  function Style() {
73959
73899
  return /* @__PURE__ */ jsxRuntime.jsx("style", { children: styleCss });
73960
73900
  }