@juv/codego-react-ui 1.1.7 → 3.0.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.
@@ -1459,7 +1459,7 @@ var CodegoUI = (() => {
1459
1459
  var require_react_dom_production = __commonJS({
1460
1460
  "node_modules/react-dom/cjs/react-dom.production.js"(exports) {
1461
1461
  "use strict";
1462
- var React49 = require_react();
1462
+ var React50 = require_react();
1463
1463
  function formatProdErrorMessage(code) {
1464
1464
  var url = "https://react.dev/errors/" + code;
1465
1465
  if (1 < arguments.length) {
@@ -1499,7 +1499,7 @@ var CodegoUI = (() => {
1499
1499
  implementation
1500
1500
  };
1501
1501
  }
1502
- var ReactSharedInternals = React49.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
1502
+ var ReactSharedInternals = React50.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
1503
1503
  function getCrossOriginStringAs(as, input) {
1504
1504
  if ("font" === as) return "";
1505
1505
  if ("string" === typeof input)
@@ -1653,7 +1653,7 @@ var CodegoUI = (() => {
1653
1653
  return dispatcher;
1654
1654
  }
1655
1655
  "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
1656
- var React49 = require_react(), Internals = {
1656
+ var React50 = require_react(), Internals = {
1657
1657
  d: {
1658
1658
  f: noop,
1659
1659
  r: function() {
@@ -1671,7 +1671,7 @@ var CodegoUI = (() => {
1671
1671
  },
1672
1672
  p: 0,
1673
1673
  findDOMNode: null
1674
- }, REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for("react.portal"), ReactSharedInternals = React49.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
1674
+ }, REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for("react.portal"), ReactSharedInternals = React50.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
1675
1675
  "function" === typeof Map && null != Map.prototype && "function" === typeof Map.prototype.forEach && "function" === typeof Set && null != Set.prototype && "function" === typeof Set.prototype.clear && "function" === typeof Set.prototype.forEach || console.error(
1676
1676
  "React depends on Map and Set built-in types. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills"
1677
1677
  );
@@ -2118,18 +2118,18 @@ var CodegoUI = (() => {
2118
2118
  function isValidElement(object) {
2119
2119
  return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE;
2120
2120
  }
2121
- var React49 = require_react(), REACT_ELEMENT_TYPE = /* @__PURE__ */ Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = /* @__PURE__ */ Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = /* @__PURE__ */ Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = /* @__PURE__ */ Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = /* @__PURE__ */ Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = /* @__PURE__ */ Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = /* @__PURE__ */ Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = /* @__PURE__ */ Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for("react.memo"), REACT_LAZY_TYPE = /* @__PURE__ */ Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = /* @__PURE__ */ Symbol.for("react.activity"), REACT_CLIENT_REFERENCE = /* @__PURE__ */ Symbol.for("react.client.reference"), ReactSharedInternals = React49.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function() {
2121
+ var React50 = require_react(), REACT_ELEMENT_TYPE = /* @__PURE__ */ Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = /* @__PURE__ */ Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = /* @__PURE__ */ Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = /* @__PURE__ */ Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = /* @__PURE__ */ Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = /* @__PURE__ */ Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = /* @__PURE__ */ Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = /* @__PURE__ */ Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for("react.memo"), REACT_LAZY_TYPE = /* @__PURE__ */ Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = /* @__PURE__ */ Symbol.for("react.activity"), REACT_CLIENT_REFERENCE = /* @__PURE__ */ Symbol.for("react.client.reference"), ReactSharedInternals = React50.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function() {
2122
2122
  return null;
2123
2123
  };
2124
- React49 = {
2124
+ React50 = {
2125
2125
  react_stack_bottom_frame: function(callStackForError) {
2126
2126
  return callStackForError();
2127
2127
  }
2128
2128
  };
2129
2129
  var specialPropKeyWarningShown;
2130
2130
  var didWarnAboutElementRef = {};
2131
- var unknownOwnerDebugStack = React49.react_stack_bottom_frame.bind(
2132
- React49,
2131
+ var unknownOwnerDebugStack = React50.react_stack_bottom_frame.bind(
2132
+ React50,
2133
2133
  UnknownOwner
2134
2134
  )();
2135
2135
  var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
@@ -36231,24 +36231,38 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
36231
36231
  ];
36232
36232
  var Satellite = createLucideIcon("satellite", __iconNode53);
36233
36233
 
36234
- // node_modules/lucide-react/dist/esm/icons/search.js
36234
+ // node_modules/lucide-react/dist/esm/icons/save.js
36235
36235
  var __iconNode54 = [
36236
+ [
36237
+ "path",
36238
+ {
36239
+ d: "M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",
36240
+ key: "1c8476"
36241
+ }
36242
+ ],
36243
+ ["path", { d: "M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7", key: "1ydtos" }],
36244
+ ["path", { d: "M7 3v4a1 1 0 0 0 1 1h7", key: "t51u73" }]
36245
+ ];
36246
+ var Save = createLucideIcon("save", __iconNode54);
36247
+
36248
+ // node_modules/lucide-react/dist/esm/icons/search.js
36249
+ var __iconNode55 = [
36236
36250
  ["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
36237
36251
  ["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
36238
36252
  ];
36239
- var Search = createLucideIcon("search", __iconNode54);
36253
+ var Search = createLucideIcon("search", __iconNode55);
36240
36254
 
36241
36255
  // node_modules/lucide-react/dist/esm/icons/settings-2.js
36242
- var __iconNode55 = [
36256
+ var __iconNode56 = [
36243
36257
  ["path", { d: "M14 17H5", key: "gfn3mx" }],
36244
36258
  ["path", { d: "M19 7h-9", key: "6i9tg" }],
36245
36259
  ["circle", { cx: "17", cy: "17", r: "3", key: "18b49y" }],
36246
36260
  ["circle", { cx: "7", cy: "7", r: "3", key: "dfmy0x" }]
36247
36261
  ];
36248
- var Settings2 = createLucideIcon("settings-2", __iconNode55);
36262
+ var Settings2 = createLucideIcon("settings-2", __iconNode56);
36249
36263
 
36250
36264
  // node_modules/lucide-react/dist/esm/icons/sliders-vertical.js
36251
- var __iconNode56 = [
36265
+ var __iconNode57 = [
36252
36266
  ["path", { d: "M10 8h4", key: "1sr2af" }],
36253
36267
  ["path", { d: "M12 21v-9", key: "17s77i" }],
36254
36268
  ["path", { d: "M12 8V3", key: "13r4qs" }],
@@ -36259,10 +36273,10 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
36259
36273
  ["path", { d: "M5 10V3", key: "cb8scm" }],
36260
36274
  ["path", { d: "M5 21v-7", key: "1w1uti" }]
36261
36275
  ];
36262
- var SlidersVertical = createLucideIcon("sliders-vertical", __iconNode56);
36276
+ var SlidersVertical = createLucideIcon("sliders-vertical", __iconNode57);
36263
36277
 
36264
36278
  // node_modules/lucide-react/dist/esm/icons/sun.js
36265
- var __iconNode57 = [
36279
+ var __iconNode58 = [
36266
36280
  ["circle", { cx: "12", cy: "12", r: "4", key: "4exip2" }],
36267
36281
  ["path", { d: "M12 2v2", key: "tus03m" }],
36268
36282
  ["path", { d: "M12 20v2", key: "1lh1kg" }],
@@ -36273,34 +36287,34 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
36273
36287
  ["path", { d: "m6.34 17.66-1.41 1.41", key: "1m8zz5" }],
36274
36288
  ["path", { d: "m19.07 4.93-1.41 1.41", key: "1shlcs" }]
36275
36289
  ];
36276
- var Sun = createLucideIcon("sun", __iconNode57);
36290
+ var Sun = createLucideIcon("sun", __iconNode58);
36277
36291
 
36278
36292
  // node_modules/lucide-react/dist/esm/icons/trash-2.js
36279
- var __iconNode58 = [
36293
+ var __iconNode59 = [
36280
36294
  ["path", { d: "M10 11v6", key: "nco0om" }],
36281
36295
  ["path", { d: "M14 11v6", key: "outv1u" }],
36282
36296
  ["path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6", key: "miytrc" }],
36283
36297
  ["path", { d: "M3 6h18", key: "d0wm0j" }],
36284
36298
  ["path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2", key: "e791ji" }]
36285
36299
  ];
36286
- var Trash2 = createLucideIcon("trash-2", __iconNode58);
36300
+ var Trash2 = createLucideIcon("trash-2", __iconNode59);
36287
36301
 
36288
36302
  // node_modules/lucide-react/dist/esm/icons/trending-down.js
36289
- var __iconNode59 = [
36303
+ var __iconNode60 = [
36290
36304
  ["path", { d: "M16 17h6v-6", key: "t6n2it" }],
36291
36305
  ["path", { d: "m22 17-8.5-8.5-5 5L2 7", key: "x473p" }]
36292
36306
  ];
36293
- var TrendingDown = createLucideIcon("trending-down", __iconNode59);
36307
+ var TrendingDown = createLucideIcon("trending-down", __iconNode60);
36294
36308
 
36295
36309
  // node_modules/lucide-react/dist/esm/icons/trending-up.js
36296
- var __iconNode60 = [
36310
+ var __iconNode61 = [
36297
36311
  ["path", { d: "M16 7h6v6", key: "box55l" }],
36298
36312
  ["path", { d: "m22 7-8.5 8.5-5-5L2 17", key: "1t1m79" }]
36299
36313
  ];
36300
- var TrendingUp = createLucideIcon("trending-up", __iconNode60);
36314
+ var TrendingUp = createLucideIcon("trending-up", __iconNode61);
36301
36315
 
36302
36316
  // node_modules/lucide-react/dist/esm/icons/triangle-alert.js
36303
- var __iconNode61 = [
36317
+ var __iconNode62 = [
36304
36318
  [
36305
36319
  "path",
36306
36320
  {
@@ -36311,28 +36325,28 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
36311
36325
  ["path", { d: "M12 9v4", key: "juzpu7" }],
36312
36326
  ["path", { d: "M12 17h.01", key: "p32p05" }]
36313
36327
  ];
36314
- var TriangleAlert = createLucideIcon("triangle-alert", __iconNode61);
36328
+ var TriangleAlert = createLucideIcon("triangle-alert", __iconNode62);
36315
36329
 
36316
36330
  // node_modules/lucide-react/dist/esm/icons/underline.js
36317
- var __iconNode62 = [
36331
+ var __iconNode63 = [
36318
36332
  ["path", { d: "M6 4v6a6 6 0 0 0 12 0V4", key: "9kb039" }],
36319
36333
  ["line", { x1: "4", x2: "20", y1: "20", y2: "20", key: "nun2al" }]
36320
36334
  ];
36321
- var Underline = createLucideIcon("underline", __iconNode62);
36335
+ var Underline = createLucideIcon("underline", __iconNode63);
36322
36336
 
36323
36337
  // node_modules/lucide-react/dist/esm/icons/undo.js
36324
- var __iconNode63 = [
36338
+ var __iconNode64 = [
36325
36339
  ["path", { d: "M3 7v6h6", key: "1v2h90" }],
36326
36340
  ["path", { d: "M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13", key: "1r6uu6" }]
36327
36341
  ];
36328
- var Undo = createLucideIcon("undo", __iconNode63);
36342
+ var Undo = createLucideIcon("undo", __iconNode64);
36329
36343
 
36330
36344
  // node_modules/lucide-react/dist/esm/icons/x.js
36331
- var __iconNode64 = [
36345
+ var __iconNode65 = [
36332
36346
  ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
36333
36347
  ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
36334
36348
  ];
36335
- var X = createLucideIcon("x", __iconNode64);
36349
+ var X = createLucideIcon("x", __iconNode65);
36336
36350
 
36337
36351
  // node_modules/clsx/dist/clsx.mjs
36338
36352
  function r(e) {
@@ -46713,6 +46727,45 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
46713
46727
  });
46714
46728
  }
46715
46729
  }
46730
+ var OSRM_PROFILE2 = { drive: "driving", walk: "foot" };
46731
+ async function fetchOsrmRoute2(points, routeType) {
46732
+ const profile = OSRM_PROFILE2[routeType];
46733
+ const coords = points.map((p) => `${p.lng},${p.lat}`).join(";");
46734
+ const res = await fetch(`https://router.project-osrm.org/route/v1/${profile}/${coords}?overview=full&geometries=geojson`);
46735
+ if (!res.ok) throw new Error("OSRM failed");
46736
+ const data = await res.json();
46737
+ if (data.code !== "Ok" || !data.routes?.length) throw new Error("No route");
46738
+ const route = data.routes[0];
46739
+ return {
46740
+ coords: route.geometry.coordinates,
46741
+ // already [lng, lat] for MapLibre
46742
+ distance: route.distance,
46743
+ duration: route.duration
46744
+ };
46745
+ }
46746
+ function fmtDistance2(m) {
46747
+ return m >= 1e3 ? `${(m / 1e3).toFixed(1)} km` : `${Math.round(m)} m`;
46748
+ }
46749
+ function fmtDuration2(s) {
46750
+ const h = Math.floor(s / 3600), m = Math.floor(s % 3600 / 60);
46751
+ return h > 0 ? `${h}h ${m}min` : `${m} min`;
46752
+ }
46753
+ function makeClusterHTML(variant, count, color) {
46754
+ if (variant === "bubble") {
46755
+ const size = count > 99 ? 52 : count > 9 ? 44 : 36;
46756
+ return `<div style="width:${size}px;height:${size}px;border-radius:50%;background:${color};color:#fff;font-weight:700;font-size:${count > 99 ? 11 : 13}px;font-family:sans-serif;display:flex;align-items:center;justify-content:center;border:3px solid white;box-shadow:0 2px 8px rgba(0,0,0,.3);">${count}</div>`;
46757
+ }
46758
+ if (variant === "donut") {
46759
+ const r2 = 20, stroke = 5, circ = 2 * Math.PI * r2;
46760
+ const dash = Math.min(count / 50, 1) * circ;
46761
+ return `<svg width="54" height="54" viewBox="0 0 54 54"><circle cx="27" cy="27" r="${r2}" fill="none" stroke="${color}33" stroke-width="${stroke}"/><circle cx="27" cy="27" r="${r2}" fill="none" stroke="${color}" stroke-width="${stroke}" stroke-dasharray="${dash} ${circ}" stroke-dashoffset="${circ / 4}" stroke-linecap="round"/><circle cx="27" cy="27" r="${r2 - stroke - 2}" fill="${color}22"/><text x="27" y="27" text-anchor="middle" dominant-baseline="middle" font-size="12" font-weight="700" fill="${color}" font-family="sans-serif">${count}</text></svg>`;
46762
+ }
46763
+ const w = count > 99 ? 52 : 40;
46764
+ return `<div style="min-width:${w}px;height:28px;border-radius:14px;background:${color};color:#fff;font-weight:700;font-size:12px;font-family:sans-serif;display:flex;align-items:center;justify-content:center;padding:0 8px;border:2px solid white;box-shadow:0 2px 8px rgba(0,0,0,.25);">${count}</div>`;
46765
+ }
46766
+ function makeEndpointHTML(color, label) {
46767
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 28 28"><circle cx="14" cy="14" r="12" fill="${color}" stroke="white" stroke-width="2.5"/><text x="14" y="14" text-anchor="middle" dominant-baseline="middle" font-size="12" font-weight="700" fill="white" font-family="sans-serif">${label}</text></svg>`;
46768
+ }
46716
46769
  function MapLibreMap({
46717
46770
  style: styleProp = "street",
46718
46771
  center = [0, 20],
@@ -46727,6 +46780,9 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
46727
46780
  maxBearing = 180,
46728
46781
  flyTo,
46729
46782
  markers = [],
46783
+ routes = [],
46784
+ cluster = false,
46785
+ clusterVariant = "default",
46730
46786
  height = 480,
46731
46787
  showControls = true,
46732
46788
  showStyleSwitcher = true,
@@ -46737,7 +46793,9 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
46737
46793
  const containerRef = React24.useRef(null);
46738
46794
  const mapRef = React24.useRef(null);
46739
46795
  const markersRef = React24.useRef([]);
46796
+ const routeMarkersRef = React24.useRef([]);
46740
46797
  const flyingRef = React24.useRef(false);
46798
+ const [routeLoading, setRouteLoading] = React24.useState(false);
46741
46799
  const [activeStyle, setActiveStyle] = React24.useState(styleProp);
46742
46800
  const [ready, setReady] = React24.useState(false);
46743
46801
  const [showCamera, setShowCamera] = React24.useState(false);
@@ -46825,6 +46883,109 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
46825
46883
  if (ftBearing !== void 0) setBearing(clampBearing(ftBearing));
46826
46884
  });
46827
46885
  }, [flyTo]);
46886
+ React24.useEffect(() => {
46887
+ const map = mapRef.current;
46888
+ if (!map || !ready || routes.length === 0) return;
46889
+ function cleanRoutes() {
46890
+ routeMarkersRef.current.forEach((m) => m.remove());
46891
+ routeMarkersRef.current = [];
46892
+ const style = map.getStyle();
46893
+ (style.layers ?? []).forEach((l) => {
46894
+ if (l.id.startsWith("route-")) try {
46895
+ map.removeLayer(l.id);
46896
+ } catch {
46897
+ }
46898
+ });
46899
+ Object.keys(style.sources ?? {}).forEach((s) => {
46900
+ if (s.startsWith("route-")) try {
46901
+ map.removeSource(s);
46902
+ } catch {
46903
+ }
46904
+ });
46905
+ }
46906
+ cleanRoutes();
46907
+ setRouteLoading(true);
46908
+ Promise.all(
46909
+ routes.map(async (r2, i) => {
46910
+ const points = [r2.start, ...r2.waypoints ?? [], r2.end];
46911
+ try {
46912
+ const result = await fetchOsrmRoute2(points, r2.routeType ?? "drive");
46913
+ return { route: r2, idx: i, ...result, error: false };
46914
+ } catch {
46915
+ return { route: r2, idx: i, coords: points.map((p) => [p.lng, p.lat]), distance: 0, duration: 0, error: true };
46916
+ }
46917
+ })
46918
+ ).then((results) => {
46919
+ setRouteLoading(false);
46920
+ if (!mapRef.current) return;
46921
+ const m = mapRef.current;
46922
+ const allCoords = [];
46923
+ results.forEach(({ route, idx, coords, distance, duration }) => {
46924
+ const color = route.color ?? (route.routeType === "walk" ? "#22c55e" : "#6366f1");
46925
+ const srcId = `route-${idx}`;
46926
+ const geojson = {
46927
+ type: "Feature",
46928
+ properties: {},
46929
+ geometry: { type: "LineString", coordinates: coords }
46930
+ };
46931
+ m.addSource(srcId, { type: "geojson", data: geojson });
46932
+ m.addLayer({
46933
+ id: `${srcId}-outline`,
46934
+ type: "line",
46935
+ source: srcId,
46936
+ layout: { "line-cap": "round", "line-join": "round" },
46937
+ paint: { "line-color": "#ffffff", "line-width": (route.weight ?? 5) + 4, "line-opacity": 0.3 }
46938
+ });
46939
+ m.addLayer({
46940
+ id: `${srcId}-line`,
46941
+ type: "line",
46942
+ source: srcId,
46943
+ layout: { "line-cap": "round", "line-join": "round" },
46944
+ paint: { "line-color": color, "line-width": route.weight ?? 5, "line-opacity": 0.9 }
46945
+ });
46946
+ allCoords.push(...coords);
46947
+ const makeEndpointMarker = (lngLat, label, markerColor, popupHtml) => {
46948
+ const el = document.createElement("div");
46949
+ el.innerHTML = makeEndpointHTML(markerColor, label);
46950
+ el.style.cssText = "width:28px;height:28px";
46951
+ const popup = new import_maplibre_gl.default.Popup({ offset: [0, -16], closeButton: false }).setHTML(popupHtml);
46952
+ const marker = new import_maplibre_gl.default.Marker({ element: el, anchor: "center" }).setLngLat(lngLat).setPopup(popup).addTo(m);
46953
+ routeMarkersRef.current.push(marker);
46954
+ };
46955
+ const infoHtml = distance > 0 ? `<p style="font-size:11px;color:#888;margin:2px 0 0">${fmtDistance2(distance)} \xB7 ${fmtDuration2(duration)} \xB7 ${route.routeType === "walk" ? "\u{1F6B6} Walk" : "\u{1F697} Drive"}</p>` : "";
46956
+ makeEndpointMarker(
46957
+ [route.start.lng, route.start.lat],
46958
+ "A",
46959
+ color,
46960
+ `<div style="padding:2px;min-width:120px"><p style="font-weight:700;font-size:13px;margin:0">${route.label ? `${route.label} \u2014 Start` : "Start"}</p>${infoHtml}</div>`
46961
+ );
46962
+ makeEndpointMarker(
46963
+ [route.end.lng, route.end.lat],
46964
+ "B",
46965
+ "#ef4444",
46966
+ `<div style="padding:2px;min-width:120px"><p style="font-weight:700;font-size:13px;margin:0">${route.label ? `${route.label} \u2014 End` : "End"}</p>${infoHtml}</div>`
46967
+ );
46968
+ if (distance > 0 && coords.length > 1) {
46969
+ const mid = coords[Math.floor(coords.length / 2)];
46970
+ const text = `${fmtDistance2(distance)} \xB7 ${fmtDuration2(duration)}`;
46971
+ const estW = text.length * 7 + 16;
46972
+ const el = document.createElement("div");
46973
+ el.innerHTML = `<div style="display:inline-flex;align-items:center;justify-content:center;background:${color};color:white;font-size:11px;font-weight:600;font-family:sans-serif;padding:3px 8px;border-radius:12px;border:2px solid white;box-shadow:0 2px 6px rgba(0,0,0,.25);white-space:nowrap;">${text}</div>`;
46974
+ el.style.cssText = `width:${estW}px;height:22px;pointer-events:none`;
46975
+ const badge = new import_maplibre_gl.default.Marker({ element: el, anchor: "center" }).setLngLat(mid).addTo(m);
46976
+ routeMarkersRef.current.push(badge);
46977
+ }
46978
+ });
46979
+ if (allCoords.length > 1) {
46980
+ const lngs = allCoords.map((c) => c[0]), lats = allCoords.map((c) => c[1]);
46981
+ m.fitBounds(
46982
+ [[Math.min(...lngs), Math.min(...lats)], [Math.max(...lngs), Math.max(...lats)]],
46983
+ { padding: 60, duration: 800 }
46984
+ );
46985
+ }
46986
+ });
46987
+ return cleanRoutes;
46988
+ }, [routes, ready]);
46828
46989
  function switchStyle(s) {
46829
46990
  const map = mapRef.current;
46830
46991
  if (!map) return;
@@ -46832,6 +46993,8 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
46832
46993
  setReady(false);
46833
46994
  markersRef.current.forEach((m) => m.remove());
46834
46995
  markersRef.current = [];
46996
+ routeMarkersRef.current.forEach((m) => m.remove());
46997
+ routeMarkersRef.current = [];
46835
46998
  map.setStyle(s === "satellite" ? SATELLITE_STYLE : STYLE_URLS[s]);
46836
46999
  map.once("style.load", () => {
46837
47000
  if (s === "globe") {
@@ -46863,32 +47026,107 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
46863
47026
  setReady(true);
46864
47027
  });
46865
47028
  }
47029
+ const [mapZoom, setMapZoom] = React24.useState(zoom);
47030
+ React24.useEffect(() => {
47031
+ const map = mapRef.current;
47032
+ if (!map) return;
47033
+ const h2 = () => setMapZoom(map.getZoom());
47034
+ map.on("zoomend", h2);
47035
+ return () => {
47036
+ map.off("zoomend", h2);
47037
+ };
47038
+ }, [ready]);
46866
47039
  React24.useEffect(() => {
46867
47040
  const map = mapRef.current;
46868
47041
  if (!map || !ready) return;
46869
47042
  markersRef.current.forEach((m) => m.remove());
46870
47043
  markersRef.current = [];
46871
- markers.forEach((m) => {
46872
- const color = resolveColor2(m.color);
46873
- const el = document.createElement("div");
46874
- el.innerHTML = makePinHTML(color, m.icon, m.image);
46875
- el.style.cssText = m.image ? "width:40px;height:50px" : "width:32px;height:42px";
46876
- const popup = new import_maplibre_gl.default.Popup({ offset: m.image ? [0, -52] : [0, -44], closeButton: false });
46877
- if (m.popup) {
46878
- if (typeof m.popup === "string") popup.setHTML(m.popup);
46879
- else popup.setDOMContent(m.popup);
46880
- } else if (m.label) {
46881
- popup.setHTML(`<span style="font-size:13px;font-weight:600">${m.label}</span>`);
46882
- }
46883
- const marker = new import_maplibre_gl.default.Marker({ element: el, anchor: "bottom" }).setLngLat([m.lng, m.lat]);
46884
- if (m.popup || m.label) marker.setPopup(popup);
46885
- el.addEventListener("click", () => onMarkerClick?.(m));
46886
- marker.addTo(map);
46887
- markersRef.current.push(marker);
46888
- });
46889
- }, [markers, ready, onMarkerClick]);
47044
+ if (cluster && markers.length > 0) {
47045
+ const GRID = 80;
47046
+ const used = /* @__PURE__ */ new Set();
47047
+ const groups = [];
47048
+ markers.forEach((m, i) => {
47049
+ if (used.has(i)) return;
47050
+ const pt = map.project([m.lng, m.lat]);
47051
+ const group = [m];
47052
+ used.add(i);
47053
+ markers.forEach((m2, j) => {
47054
+ if (used.has(j)) return;
47055
+ const pt2 = map.project([m2.lng, m2.lat]);
47056
+ if (Math.abs(pt.x - pt2.x) < GRID && Math.abs(pt.y - pt2.y) < GRID) {
47057
+ group.push(m2);
47058
+ used.add(j);
47059
+ }
47060
+ });
47061
+ const lat = group.reduce((s, x) => s + x.lat, 0) / group.length;
47062
+ const lng = group.reduce((s, x) => s + x.lng, 0) / group.length;
47063
+ groups.push({ center: { lng, lat }, items: group });
47064
+ });
47065
+ groups.forEach((g, gi) => {
47066
+ if (g.items.length === 1) {
47067
+ const m = g.items[0];
47068
+ const color = resolveColor2(m.color);
47069
+ const el = document.createElement("div");
47070
+ el.innerHTML = makePinHTML(color, m.icon, m.image);
47071
+ el.style.cssText = m.image ? "width:40px;height:50px" : "width:32px;height:42px";
47072
+ const popup = new import_maplibre_gl.default.Popup({ offset: m.image ? [0, -52] : [0, -44], closeButton: false });
47073
+ if (m.popup) {
47074
+ typeof m.popup === "string" ? popup.setHTML(m.popup) : popup.setDOMContent(m.popup);
47075
+ } else if (m.label) popup.setHTML(`<span style="font-size:13px;font-weight:600">${m.label}</span>`);
47076
+ const marker = new import_maplibre_gl.default.Marker({ element: el, anchor: "bottom" }).setLngLat([m.lng, m.lat]);
47077
+ if (m.popup || m.label) marker.setPopup(popup);
47078
+ el.addEventListener("click", () => onMarkerClick?.(m));
47079
+ marker.addTo(map);
47080
+ markersRef.current.push(marker);
47081
+ } else {
47082
+ const color = resolveColor2(g.items[0].color);
47083
+ const el = document.createElement("div");
47084
+ el.innerHTML = makeClusterHTML(clusterVariant, g.items.length, color);
47085
+ el.style.cssText = "cursor:pointer";
47086
+ const listItems = g.items.map(
47087
+ (m) => `<div data-id="${m.id}" style="font-size:12px;padding:2px 0;cursor:pointer;">${m.label ?? `Marker ${m.id}`}</div>`
47088
+ ).join("");
47089
+ const popup = new import_maplibre_gl.default.Popup({ offset: [0, -8], closeButton: false }).setHTML(`<div style="max-height:160px;overflow-y:auto;padding:2px">${listItems}</div>`);
47090
+ el.addEventListener("click", () => {
47091
+ map.flyTo({ center: [g.center.lng, g.center.lat], zoom: map.getZoom() + 2, duration: 400 });
47092
+ });
47093
+ const marker = new import_maplibre_gl.default.Marker({ element: el, anchor: "center" }).setLngLat([g.center.lng, g.center.lat]).setPopup(popup).addTo(map);
47094
+ markersRef.current.push(marker);
47095
+ marker.getPopup().on("open", () => {
47096
+ g.items.forEach((m) => {
47097
+ const node = document.querySelector(`[data-id="${m.id}"]`);
47098
+ node?.addEventListener("click", () => onMarkerClick?.(m));
47099
+ });
47100
+ });
47101
+ }
47102
+ });
47103
+ } else {
47104
+ markers.forEach((m) => {
47105
+ const color = resolveColor2(m.color);
47106
+ const el = document.createElement("div");
47107
+ el.innerHTML = makePinHTML(color, m.icon, m.image);
47108
+ el.style.cssText = m.image ? "width:40px;height:50px" : "width:32px;height:42px";
47109
+ const popup = new import_maplibre_gl.default.Popup({ offset: m.image ? [0, -52] : [0, -44], closeButton: false });
47110
+ if (m.popup) {
47111
+ if (typeof m.popup === "string") popup.setHTML(m.popup);
47112
+ else popup.setDOMContent(m.popup);
47113
+ } else if (m.label) {
47114
+ popup.setHTML(`<span style="font-size:13px;font-weight:600">${m.label}</span>`);
47115
+ }
47116
+ const marker = new import_maplibre_gl.default.Marker({ element: el, anchor: "bottom" }).setLngLat([m.lng, m.lat]);
47117
+ if (m.popup || m.label) marker.setPopup(popup);
47118
+ el.addEventListener("click", () => onMarkerClick?.(m));
47119
+ marker.addTo(map);
47120
+ markersRef.current.push(marker);
47121
+ });
47122
+ }
47123
+ }, [markers, ready, onMarkerClick, cluster, clusterVariant, mapZoom]);
46890
47124
  const cameraOpen = showCameraControls || showCamera;
46891
47125
  return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: cn("relative w-full overflow-hidden rounded-2xl border border-border", className), style: { height: h }, children: [
47126
+ routeLoading && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "absolute inset-0 z-[1000] flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center gap-2 bg-card/90 backdrop-blur-sm border border-border rounded-xl px-4 py-2 shadow-lg text-sm font-medium", children: [
47127
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "h-4 w-4 rounded-full border-2 border-primary border-t-transparent animate-spin" }),
47128
+ "Calculating route\u2026"
47129
+ ] }) }),
46892
47130
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { ref: containerRef, style: { width: "100%", height: "100%" } }),
46893
47131
  cameraOpen && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "absolute top-4 left-4 z-10 bg-card/90 backdrop-blur-sm border border-border rounded-2xl p-3 shadow-xl space-y-3 w-52", children: [
46894
47132
  /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center justify-between", children: [
@@ -47220,6 +47458,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
47220
47458
  const [isSearching, setIsSearching] = React27.useState(false);
47221
47459
  const containerRef = React27.useRef(null);
47222
47460
  const triggerRef = React27.useRef(null);
47461
+ const portalRef = React27.useRef(null);
47223
47462
  const [dropStyle, setDropStyle] = React27.useState({});
47224
47463
  const getKey = React27.useCallback((opt) => String(Object.keys(opt)[0]), []);
47225
47464
  const getLabel = React27.useCallback((opt) => Object.values(opt)[0], []);
@@ -47250,9 +47489,9 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
47250
47489
  };
47251
47490
  React27.useEffect(() => {
47252
47491
  const handler = (e) => {
47253
- if (containerRef.current && !containerRef.current.contains(e.target)) {
47254
- setIsOpen(false);
47255
- }
47492
+ const target = e.target;
47493
+ if (containerRef.current?.contains(target) || portalRef.current?.contains(target)) return;
47494
+ setIsOpen(false);
47256
47495
  };
47257
47496
  document.addEventListener("mousedown", handler);
47258
47497
  return () => document.removeEventListener("mousedown", handler);
@@ -47395,6 +47634,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
47395
47634
  isOpen && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(FloatingPortal, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
47396
47635
  "div",
47397
47636
  {
47637
+ ref: portalRef,
47398
47638
  className: "max-h-60 overflow-auto rounded-md border border-white/10 bg-background/80 backdrop-blur-xl text-popover-foreground shadow-lg animate-in fade-in-80",
47399
47639
  style: dropStyle,
47400
47640
  children: [
@@ -48356,67 +48596,386 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
48356
48596
 
48357
48597
  // src/components/conf/settingConfig.json
48358
48598
  var settingConfig_default = {
48359
- theme: "dark",
48360
- fontSize: "16px",
48361
- fontFamily: '"Space Grotesk", "Inter", sans-serif',
48362
- colors: {
48363
- primary: "#8b5cf6",
48364
- primaryHover: "#7c3aed",
48365
- secondary: "#171717",
48366
- secondaryHover: "#262626",
48367
- info: "#3b82f6",
48368
- infoHover: "#2563eb",
48369
- warning: "#f59e0b",
48370
- warningHover: "#d97706",
48371
- danger: "#ef4444",
48372
- dangerHover: "#dc2626"
48373
- }
48599
+ defaults: {
48600
+ theme: "light",
48601
+ fontSize: "16px",
48602
+ fontFamily: '"Space Grotesk", "Inter", sans-serif',
48603
+ colors: {
48604
+ primary: "#5CF6E2",
48605
+ primaryHover: "#73F3E2",
48606
+ secondary: "#171717",
48607
+ secondaryHover: "#262626",
48608
+ info: "#3b82f6",
48609
+ infoHover: "#2563eb",
48610
+ warning: "#f59e0b",
48611
+ warningHover: "#d97706",
48612
+ danger: "#ef4444",
48613
+ dangerHover: "#dc2626"
48614
+ }
48615
+ },
48616
+ themeOptions: [
48617
+ { light: "Light" },
48618
+ { dark: "Dark" },
48619
+ { system: "System" }
48620
+ ],
48621
+ fontSizes: [
48622
+ { "14px": "Small (14px)" },
48623
+ { "16px": "Medium (16px)" },
48624
+ { "18px": "Large (18px)" },
48625
+ { "20px": "Extra Large (20px)" }
48626
+ ],
48627
+ fontFamilies: [
48628
+ { '"Space Grotesk", "Inter", sans-serif': "Space Grotesk" },
48629
+ { '"Inter", sans-serif': "Inter" },
48630
+ { '"JetBrains Mono", monospace': "JetBrains Mono" },
48631
+ { "system-ui, sans-serif": "System UI" }
48632
+ ],
48633
+ colorPairs: [
48634
+ { base: "primary", hover: "primaryHover", label: "Primary" },
48635
+ { base: "secondary", hover: "secondaryHover", label: "Secondary" },
48636
+ { base: "info", hover: "infoHover", label: "Info" },
48637
+ { base: "warning", hover: "warningHover", label: "Warning" },
48638
+ { base: "danger", hover: "dangerHover", label: "Danger" }
48639
+ ],
48640
+ colorPalette: [
48641
+ {
48642
+ base: "#6366F1",
48643
+ hover: "#4F46E5",
48644
+ info: "#F59E0B",
48645
+ infoHover: "#D97706"
48646
+ },
48647
+ {
48648
+ base: "#818CF8",
48649
+ hover: "#6366F1",
48650
+ info: "#FBBF24",
48651
+ infoHover: "#F59E0B"
48652
+ },
48653
+ {
48654
+ base: "#4F46E5",
48655
+ hover: "#4338CA",
48656
+ info: "#F59E0B",
48657
+ infoHover: "#D97706"
48658
+ },
48659
+ {
48660
+ base: "#3730A3",
48661
+ hover: "#312E81",
48662
+ info: "#D97706",
48663
+ infoHover: "#B45309"
48664
+ },
48665
+ {
48666
+ base: "#7C3AED",
48667
+ hover: "#6D28D9",
48668
+ info: "#F97316",
48669
+ infoHover: "#EA580C"
48670
+ },
48671
+ {
48672
+ base: "#A78BFA",
48673
+ hover: "#8B5CF6",
48674
+ info: "#FB923C",
48675
+ infoHover: "#F97316"
48676
+ },
48677
+ {
48678
+ base: "#8B5CF6",
48679
+ hover: "#7C3AED",
48680
+ info: "#F97316",
48681
+ infoHover: "#EA580C"
48682
+ },
48683
+ {
48684
+ base: "#6D28D9",
48685
+ hover: "#5B21B6",
48686
+ info: "#EA580C",
48687
+ infoHover: "#C2410C"
48688
+ },
48689
+ {
48690
+ base: "#0EA5E9",
48691
+ hover: "#0284C7",
48692
+ info: "#F97316",
48693
+ infoHover: "#EA580C"
48694
+ },
48695
+ {
48696
+ base: "#38BDF8",
48697
+ hover: "#0EA5E9",
48698
+ info: "#FB923C",
48699
+ infoHover: "#F97316"
48700
+ },
48701
+ {
48702
+ base: "#3B82F6",
48703
+ hover: "#2563EB",
48704
+ info: "#F59E0B",
48705
+ infoHover: "#D97706"
48706
+ },
48707
+ {
48708
+ base: "#1D4ED8",
48709
+ hover: "#1E40AF",
48710
+ info: "#D97706",
48711
+ infoHover: "#B45309"
48712
+ },
48713
+ {
48714
+ base: "#06B6D4",
48715
+ hover: "#0891B2",
48716
+ info: "#A855F7",
48717
+ infoHover: "#9333EA"
48718
+ },
48719
+ {
48720
+ base: "#22D3EE",
48721
+ hover: "#06B6D4",
48722
+ info: "#C084FC",
48723
+ infoHover: "#A855F7"
48724
+ },
48725
+ {
48726
+ base: "#14B8A6",
48727
+ hover: "#0F766E",
48728
+ info: "#8B5CF6",
48729
+ infoHover: "#7C3AED"
48730
+ },
48731
+ {
48732
+ base: "#0D9488",
48733
+ hover: "#0F766E",
48734
+ info: "#7C3AED",
48735
+ infoHover: "#6D28D9"
48736
+ },
48737
+ {
48738
+ base: "#10B981",
48739
+ hover: "#059669",
48740
+ info: "#8B5CF6",
48741
+ infoHover: "#7C3AED"
48742
+ },
48743
+ {
48744
+ base: "#34D399",
48745
+ hover: "#10B981",
48746
+ info: "#A855F7",
48747
+ infoHover: "#9333EA"
48748
+ },
48749
+ {
48750
+ base: "#22C55E",
48751
+ hover: "#16A34A",
48752
+ info: "#7C3AED",
48753
+ infoHover: "#6D28D9"
48754
+ },
48755
+ {
48756
+ base: "#16A34A",
48757
+ hover: "#15803D",
48758
+ info: "#6D28D9",
48759
+ infoHover: "#5B21B6"
48760
+ },
48761
+ {
48762
+ base: "#84CC16",
48763
+ hover: "#65A30D",
48764
+ info: "#6366F1",
48765
+ infoHover: "#4F46E5"
48766
+ },
48767
+ {
48768
+ base: "#A3E635",
48769
+ hover: "#84CC16",
48770
+ info: "#818CF8",
48771
+ infoHover: "#6366F1"
48772
+ },
48773
+ {
48774
+ base: "#65A30D",
48775
+ hover: "#4D7C0F",
48776
+ info: "#4F46E5",
48777
+ infoHover: "#4338CA"
48778
+ },
48779
+ {
48780
+ base: "#4D7C0F",
48781
+ hover: "#3F6212",
48782
+ info: "#3730A3",
48783
+ infoHover: "#312E81"
48784
+ },
48785
+ {
48786
+ base: "#EAB308",
48787
+ hover: "#CA8A04",
48788
+ info: "#3B82F6",
48789
+ infoHover: "#2563EB"
48790
+ },
48791
+ {
48792
+ base: "#FACC15",
48793
+ hover: "#EAB308",
48794
+ info: "#60A5FA",
48795
+ infoHover: "#3B82F6"
48796
+ },
48797
+ {
48798
+ base: "#F59E0B",
48799
+ hover: "#D97706",
48800
+ info: "#2563EB",
48801
+ infoHover: "#1D4ED8"
48802
+ },
48803
+ {
48804
+ base: "#D97706",
48805
+ hover: "#B45309",
48806
+ info: "#1D4ED8",
48807
+ infoHover: "#1E40AF"
48808
+ },
48809
+ {
48810
+ base: "#F97316",
48811
+ hover: "#EA580C",
48812
+ info: "#0EA5E9",
48813
+ infoHover: "#0284C7"
48814
+ },
48815
+ {
48816
+ base: "#FB923C",
48817
+ hover: "#F97316",
48818
+ info: "#38BDF8",
48819
+ infoHover: "#0EA5E9"
48820
+ },
48821
+ {
48822
+ base: "#EA580C",
48823
+ hover: "#C2410C",
48824
+ info: "#0284C7",
48825
+ infoHover: "#0369A1"
48826
+ },
48827
+ {
48828
+ base: "#C2410C",
48829
+ hover: "#9A3412",
48830
+ info: "#0369A1",
48831
+ infoHover: "#075985"
48832
+ },
48833
+ {
48834
+ base: "#EF4444",
48835
+ hover: "#DC2626",
48836
+ info: "#0EA5E9",
48837
+ infoHover: "#0284C7"
48838
+ },
48839
+ {
48840
+ base: "#F87171",
48841
+ hover: "#EF4444",
48842
+ info: "#38BDF8",
48843
+ infoHover: "#0EA5E9"
48844
+ },
48845
+ {
48846
+ base: "#DC2626",
48847
+ hover: "#B91C1C",
48848
+ info: "#0284C7",
48849
+ infoHover: "#0369A1"
48850
+ },
48851
+ {
48852
+ base: "#B91C1C",
48853
+ hover: "#991B1B",
48854
+ info: "#0369A1",
48855
+ infoHover: "#075985"
48856
+ },
48857
+ {
48858
+ base: "#F43F5E",
48859
+ hover: "#E11D48",
48860
+ info: "#0EA5E9",
48861
+ infoHover: "#0284C7"
48862
+ },
48863
+ {
48864
+ base: "#FB7185",
48865
+ hover: "#F43F5E",
48866
+ info: "#38BDF8",
48867
+ infoHover: "#0EA5E9"
48868
+ },
48869
+ {
48870
+ base: "#E11D48",
48871
+ hover: "#BE123C",
48872
+ info: "#0284C7",
48873
+ infoHover: "#0369A1"
48874
+ },
48875
+ {
48876
+ base: "#BE123C",
48877
+ hover: "#9F1239",
48878
+ info: "#0369A1",
48879
+ infoHover: "#075985"
48880
+ },
48881
+ {
48882
+ base: "#EC4899",
48883
+ hover: "#DB2777",
48884
+ info: "#06B6D4",
48885
+ infoHover: "#0891B2"
48886
+ },
48887
+ {
48888
+ base: "#F472B6",
48889
+ hover: "#EC4899",
48890
+ info: "#22D3EE",
48891
+ infoHover: "#06B6D4"
48892
+ },
48893
+ {
48894
+ base: "#DB2777",
48895
+ hover: "#BE185D",
48896
+ info: "#0891B2",
48897
+ infoHover: "#0E7490"
48898
+ },
48899
+ {
48900
+ base: "#BE185D",
48901
+ hover: "#9D174D",
48902
+ info: "#0E7490",
48903
+ infoHover: "#155E75"
48904
+ },
48905
+ {
48906
+ base: "#D946EF",
48907
+ hover: "#C026D3",
48908
+ info: "#F59E0B",
48909
+ infoHover: "#D97706"
48910
+ },
48911
+ {
48912
+ base: "#E879F9",
48913
+ hover: "#D946EF",
48914
+ info: "#FBBF24",
48915
+ infoHover: "#F59E0B"
48916
+ },
48917
+ {
48918
+ base: "#C026D3",
48919
+ hover: "#A21CAF",
48920
+ info: "#D97706",
48921
+ infoHover: "#B45309"
48922
+ },
48923
+ {
48924
+ base: "#A21CAF",
48925
+ hover: "#86198F",
48926
+ info: "#B45309",
48927
+ infoHover: "#92400E"
48928
+ }
48929
+ ]
48374
48930
  };
48375
48931
 
48376
48932
  // src/components/theme-provider.tsx
48377
48933
  var import_jsx_runtime36 = __toESM(require_jsx_runtime(), 1);
48378
- var configDefaults = {
48379
- theme: settingConfig_default.theme,
48380
- fontSize: settingConfig_default.fontSize,
48381
- fontFamily: settingConfig_default.fontFamily,
48382
- colors: settingConfig_default.colors
48934
+ var FACTORY_DEFAULTS = {
48935
+ theme: settingConfig_default.defaults.theme,
48936
+ fontSize: settingConfig_default.defaults.fontSize,
48937
+ fontFamily: settingConfig_default.defaults.fontFamily,
48938
+ colors: settingConfig_default.defaults.colors
48383
48939
  };
48940
+ function loadJSON(key, fallback) {
48941
+ try {
48942
+ const raw = localStorage.getItem(key);
48943
+ if (raw) return { ...fallback, ...JSON.parse(raw) };
48944
+ } catch {
48945
+ }
48946
+ return fallback;
48947
+ }
48948
+ function saveJSON(key, value) {
48949
+ try {
48950
+ localStorage.setItem(key, JSON.stringify(value));
48951
+ } catch {
48952
+ }
48953
+ }
48384
48954
  var initialState = {
48385
- ...configDefaults,
48955
+ ...FACTORY_DEFAULTS,
48386
48956
  setTheme: () => null,
48387
48957
  setColors: () => null,
48388
48958
  setFontSize: () => null,
48389
48959
  setFontFamily: () => null,
48960
+ saveConfig: () => null,
48390
48961
  resetSettings: () => null
48391
48962
  };
48392
48963
  var ThemeProviderContext = (0, import_react13.createContext)(initialState);
48393
- var COLOR_PALETTE = [
48394
- { base: "#6366f1", hover: "#4f46e5" },
48395
- { base: "#8b5cf6", hover: "#7c3aed" },
48396
- { base: "#3b82f6", hover: "#2563eb" },
48397
- { base: "#10b981", hover: "#059669" },
48398
- { base: "#22c55e", hover: "#16a34a" },
48399
- { base: "#eab308", hover: "#ca8a04" },
48400
- { base: "#f59e0b", hover: "#d97706" },
48401
- { base: "#f97316", hover: "#ea580c" },
48402
- { base: "#ef4444", hover: "#dc2626" },
48403
- { base: "#ec4899", hover: "#db2777" }
48404
- ];
48964
+ var COLOR_PALETTE = settingConfig_default.colorPalette;
48405
48965
  function ThemeProvider({
48406
48966
  children,
48407
48967
  storageKey = "codego-ui-theme-settings",
48968
+ savedConfigKey = "codego-ui-saved-config",
48408
48969
  ...props
48409
48970
  }) {
48410
- const [settings, setSettings] = (0, import_react13.useState)(() => {
48411
- try {
48412
- const stored = localStorage.getItem(storageKey);
48413
- if (stored) return { ...configDefaults, ...JSON.parse(stored) };
48414
- } catch {
48415
- }
48416
- return configDefaults;
48417
- });
48971
+ const [savedConfig, setSavedConfig] = (0, import_react13.useState)(
48972
+ () => loadJSON(savedConfigKey, FACTORY_DEFAULTS)
48973
+ );
48974
+ const [settings, setSettings] = (0, import_react13.useState)(
48975
+ () => loadJSON(storageKey, savedConfig)
48976
+ );
48418
48977
  (0, import_react13.useEffect)(() => {
48419
- localStorage.setItem(storageKey, JSON.stringify(settings));
48978
+ saveJSON(storageKey, settings);
48420
48979
  }, [settings, storageKey]);
48421
48980
  (0, import_react13.useEffect)(() => {
48422
48981
  const root = window.document.documentElement;
@@ -48442,7 +49001,13 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
48442
49001
  setColors: (colors) => setSettings((s) => ({ ...s, colors: { ...s.colors, ...colors } })),
48443
49002
  setFontSize: (fontSize) => setSettings((s) => ({ ...s, fontSize })),
48444
49003
  setFontFamily: (fontFamily) => setSettings((s) => ({ ...s, fontFamily })),
48445
- resetSettings: () => setSettings(configDefaults)
49004
+ // Save current live settings as the new persisted defaults
49005
+ saveConfig: () => {
49006
+ setSavedConfig(settings);
49007
+ saveJSON(savedConfigKey, settings);
49008
+ },
49009
+ // Reset live settings back to saved defaults
49010
+ resetSettings: () => setSettings(savedConfig)
48446
49011
  };
48447
49012
  return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ThemeProviderContext.Provider, { ...props, value, children });
48448
49013
  }
@@ -49329,6 +49894,9 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
49329
49894
  ] });
49330
49895
  }
49331
49896
 
49897
+ // src/components/ui/PanelSettings.tsx
49898
+ var React41 = __toESM(require_react(), 1);
49899
+
49332
49900
  // src/components/ui/tabs.tsx
49333
49901
  var React40 = __toESM(require_react(), 1);
49334
49902
  var import_jsx_runtime47 = __toESM(require_jsx_runtime(), 1);
@@ -49413,30 +49981,10 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
49413
49981
 
49414
49982
  // src/components/ui/PanelSettings.tsx
49415
49983
  var import_jsx_runtime48 = __toESM(require_jsx_runtime(), 1);
49416
- var FONT_SIZES = [
49417
- { value: "14px", label: "Small (14px)" },
49418
- { value: "16px", label: "Medium (16px)" },
49419
- { value: "18px", label: "Large (18px)" },
49420
- { value: "20px", label: "Extra Large (20px)" }
49421
- ];
49422
- var FONT_FAMILIES = [
49423
- { value: '"Space Grotesk", "Inter", sans-serif', label: "Space Grotesk" },
49424
- { value: '"Inter", sans-serif', label: "Inter" },
49425
- { value: '"JetBrains Mono", monospace', label: "JetBrains Mono" },
49426
- { value: "system-ui, sans-serif", label: "System UI" }
49427
- ];
49428
- var THEME_OPTIONS = [
49429
- { value: "light", label: "Light" },
49430
- { value: "dark", label: "Dark" },
49431
- { value: "system", label: "System" }
49432
- ];
49433
- var COLOR_PAIRS = [
49434
- { base: "primary", hover: "primaryHover", label: "Primary" },
49435
- { base: "secondary", hover: "secondaryHover", label: "Secondary" },
49436
- { base: "info", hover: "infoHover", label: "Info" },
49437
- { base: "warning", hover: "warningHover", label: "Warning" },
49438
- { base: "danger", hover: "dangerHover", label: "Danger" }
49439
- ];
49984
+ var THEME_OPTIONS = settingConfig_default.themeOptions;
49985
+ var FONT_SIZES = settingConfig_default.fontSizes;
49986
+ var FONT_FAMILIES = settingConfig_default.fontFamilies;
49987
+ var COLOR_PAIRS = settingConfig_default.colorPairs;
49440
49988
  function SettingRow({ label, description, children }) {
49441
49989
  return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-start justify-between gap-4 py-3 border-b border-border/60 last:border-0", children: [
49442
49990
  /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "min-w-0", children: [
@@ -49484,8 +50032,8 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
49484
50032
  type: "button",
49485
50033
  title: c.base,
49486
50034
  onClick: () => {
49487
- setColors({ primary: c.base, primaryHover: c.hover });
49488
- onColorsChange?.({ primary: c.base, primaryHover: c.hover });
50035
+ setColors({ primary: c.base, primaryHover: c.hover, info: c.info, infoHover: c.infoHover });
50036
+ onColorsChange?.({ primary: c.base, primaryHover: c.hover, info: c.info, infoHover: c.infoHover });
49489
50037
  },
49490
50038
  className: cn(
49491
50039
  "h-7 w-full rounded-md border border-white/10 transition-transform hover:scale-110 focus:outline-none focus:ring-2 focus:ring-ring",
@@ -49561,10 +50109,18 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
49561
50109
  onColorsChange,
49562
50110
  onFontSizeChange,
49563
50111
  onFontFamilyChange,
50112
+ onSave,
49564
50113
  onReset,
49565
50114
  className
49566
50115
  }) {
49567
- const { resetSettings } = useTheme();
50116
+ const { saveConfig, resetSettings } = useTheme();
50117
+ const [saved, setSaved] = React41.useState(false);
50118
+ const handleSave = () => {
50119
+ saveConfig();
50120
+ onSave?.();
50121
+ setSaved(true);
50122
+ setTimeout(() => setSaved(false), 2e3);
50123
+ };
49568
50124
  const handleReset = () => {
49569
50125
  resetSettings();
49570
50126
  onReset?.();
@@ -49588,10 +50144,16 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
49588
50144
  ];
49589
50145
  return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: cn("flex flex-col gap-4", className), children: [
49590
50146
  /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Tabs, { items: tabs, defaultValue: defaultTab, variant: "pill" }),
49591
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "flex justify-end pt-1", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(Button, { variant: "outline", size: "sm", onClick: handleReset, children: [
49592
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(RotateCcw, { className: "h-3.5 w-3.5 mr-1.5" }),
49593
- "Reset to Defaults"
49594
- ] }) })
50147
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex justify-end gap-2 pt-1", children: [
50148
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(Button, { variant: "outline", size: "sm", onClick: handleReset, children: [
50149
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(RotateCcw, { className: "h-3.5 w-3.5 mr-1.5" }),
50150
+ "Reset"
50151
+ ] }),
50152
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(Button, { size: "sm", onClick: handleSave, children: [
50153
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Save, { className: "h-3.5 w-3.5 mr-1.5" }),
50154
+ saved ? "Saved!" : "Save"
50155
+ ] })
50156
+ ] })
49595
50157
  ] });
49596
50158
  }
49597
50159
 
@@ -49611,7 +50173,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
49611
50173
  }
49612
50174
 
49613
50175
  // src/components/ui/slider.tsx
49614
- var React41 = __toESM(require_react(), 1);
50176
+ var React42 = __toESM(require_react(), 1);
49615
50177
  var import_jsx_runtime50 = __toESM(require_jsx_runtime(), 1);
49616
50178
  function pct(val, min, max) {
49617
50179
  return (val - min) / (max - min) * 100;
@@ -49631,8 +50193,8 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
49631
50193
  showValue = false,
49632
50194
  className
49633
50195
  }) {
49634
- const [internal, setInternal] = React41.useState(defaultValue);
49635
- const [hovering, setHovering] = React41.useState(false);
50196
+ const [internal, setInternal] = React42.useState(defaultValue);
50197
+ const [hovering, setHovering] = React42.useState(false);
49636
50198
  const val = controlled ?? internal;
49637
50199
  function handleChange(e) {
49638
50200
  const v = Number(e.target.value);
@@ -49709,8 +50271,8 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
49709
50271
  showValue = false,
49710
50272
  className
49711
50273
  }) {
49712
- const [internal, setInternal] = React41.useState(defaultValue);
49713
- const [active, setActive] = React41.useState(null);
50274
+ const [internal, setInternal] = React42.useState(defaultValue);
50275
+ const [active, setActive] = React42.useState(null);
49714
50276
  const val = controlled ?? internal;
49715
50277
  function handleChange(idx, e) {
49716
50278
  const v = Number(e.target.value);
@@ -49733,7 +50295,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
49733
50295
  /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "absolute w-full h-1.5 rounded-full bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "absolute h-full rounded-full bg-primary", style: { left: `${p0}%`, width: `${p1 - p0}%` } }) }),
49734
50296
  [0, 1].map((idx) => {
49735
50297
  const p = idx === 0 ? p0 : p1;
49736
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(React41.Fragment, { children: [
50298
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(React42.Fragment, { children: [
49737
50299
  showTooltip && active === idx && !disabled && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
49738
50300
  "div",
49739
50301
  {
@@ -49843,7 +50405,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
49843
50405
  }
49844
50406
 
49845
50407
  // src/components/ui/stepper.tsx
49846
- var React42 = __toESM(require_react(), 1);
50408
+ var React43 = __toESM(require_react(), 1);
49847
50409
  var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1);
49848
50410
  function getStatus(idx, current) {
49849
50411
  if (idx < current) return "complete";
@@ -49865,7 +50427,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
49865
50427
  clickable = false,
49866
50428
  className
49867
50429
  }) {
49868
- const [internal, setInternal] = React42.useState(defaultCurrent);
50430
+ const [internal, setInternal] = React43.useState(defaultCurrent);
49869
50431
  const current = controlled ?? internal;
49870
50432
  function go(idx) {
49871
50433
  if (!clickable) return;
@@ -49880,7 +50442,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
49880
50442
  ), children: steps.map((step, i) => {
49881
50443
  const status = getStatus(i, current);
49882
50444
  const isLast = i === steps.length - 1;
49883
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(React42.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: cn(
50445
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(React43.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: cn(
49884
50446
  "flex",
49885
50447
  isHorizontal ? "flex-col items-center flex-1" : "flex-row gap-4"
49886
50448
  ), children: [
@@ -49924,7 +50486,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
49924
50486
  }
49925
50487
 
49926
50488
  // src/components/ui/table.tsx
49927
- var React43 = __toESM(require_react(), 1);
50489
+ var React44 = __toESM(require_react(), 1);
49928
50490
  var import_jsx_runtime53 = __toESM(require_jsx_runtime(), 1);
49929
50491
  var BADGE_COLORS = {
49930
50492
  active: "bg-success/10 text-success border-success/20",
@@ -49948,11 +50510,11 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
49948
50510
  idKey = "id",
49949
50511
  className
49950
50512
  }) {
49951
- const [search, setSearch] = React43.useState("");
49952
- const [currentPage, setCurrentPage] = React43.useState(1);
49953
- const [selectedIds, setSelectedIds] = React43.useState([]);
49954
- const [sortKey, setSortKey] = React43.useState(null);
49955
- const [sortDir, setSortDir] = React43.useState(null);
50513
+ const [search, setSearch] = React44.useState("");
50514
+ const [currentPage, setCurrentPage] = React44.useState(1);
50515
+ const [selectedIds, setSelectedIds] = React44.useState([]);
50516
+ const [sortKey, setSortKey] = React44.useState(null);
50517
+ const [sortDir, setSortDir] = React44.useState(null);
49956
50518
  const handleSort = (key) => {
49957
50519
  if (sortKey !== key) {
49958
50520
  setSortKey(key);
@@ -49966,7 +50528,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
49966
50528
  setSortKey(null);
49967
50529
  setSortDir(null);
49968
50530
  };
49969
- const filteredData = React43.useMemo(() => {
50531
+ const filteredData = React44.useMemo(() => {
49970
50532
  let d = search ? data.filter(
49971
50533
  (item) => Object.values(item).some(
49972
50534
  (val) => val && typeof val === "string" && val.toLowerCase().includes(search.toLowerCase())
@@ -49984,18 +50546,18 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
49984
50546
  }, [data, search, sortKey, sortDir]);
49985
50547
  const totalPages = Math.max(1, Math.ceil(filteredData.length / itemsPerPage));
49986
50548
  const safePage = Math.min(currentPage, totalPages);
49987
- const paginatedData = React43.useMemo(() => {
50549
+ const paginatedData = React44.useMemo(() => {
49988
50550
  if (!pagination) return filteredData;
49989
50551
  const start = (safePage - 1) * itemsPerPage;
49990
50552
  return filteredData.slice(start, start + itemsPerPage);
49991
50553
  }, [filteredData, pagination, safePage, itemsPerPage]);
49992
- React43.useEffect(() => {
50554
+ React44.useEffect(() => {
49993
50555
  setCurrentPage(1);
49994
50556
  }, [search]);
49995
50557
  const handleSelectAll = (checked) => setSelectedIds(checked ? paginatedData.map((item) => String(item[idKey])) : []);
49996
50558
  const handleSelect = (id, checked) => setSelectedIds((prev) => checked ? [...prev, id] : prev.filter((i) => i !== id));
49997
50559
  const allSelected = paginatedData.length > 0 && selectedIds.length === paginatedData.length;
49998
- const pagePills = React43.useMemo(() => {
50560
+ const pagePills = React44.useMemo(() => {
49999
50561
  if (totalPages <= 5) return Array.from({ length: totalPages }, (_, i) => i + 1);
50000
50562
  if (safePage <= 3) return [1, 2, 3, 4, 5];
50001
50563
  if (safePage >= totalPages - 2) return [totalPages - 4, totalPages - 3, totalPages - 2, totalPages - 1, totalPages];
@@ -50224,7 +50786,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
50224
50786
  }
50225
50787
 
50226
50788
  // src/components/ui/tag-input.tsx
50227
- var React44 = __toESM(require_react(), 1);
50789
+ var React45 = __toESM(require_react(), 1);
50228
50790
  var import_jsx_runtime54 = __toESM(require_jsx_runtime(), 1);
50229
50791
  function TagInput({
50230
50792
  value: controlled,
@@ -50236,9 +50798,9 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
50236
50798
  disabled = false,
50237
50799
  className
50238
50800
  }) {
50239
- const [internal, setInternal] = React44.useState(defaultValue);
50240
- const [input, setInput] = React44.useState("");
50241
- const inputRef = React44.useRef(null);
50801
+ const [internal, setInternal] = React45.useState(defaultValue);
50802
+ const [input, setInput] = React45.useState("");
50803
+ const inputRef = React45.useRef(null);
50242
50804
  const tags = controlled ?? internal;
50243
50805
  function addTag(raw) {
50244
50806
  const tag = raw.trim();
@@ -50342,9 +50904,9 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
50342
50904
  }
50343
50905
 
50344
50906
  // src/components/ui/toggle-switch.tsx
50345
- var React45 = __toESM(require_react(), 1);
50907
+ var React46 = __toESM(require_react(), 1);
50346
50908
  var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);
50347
- var ToggleSwitch = React45.forwardRef(
50909
+ var ToggleSwitch = React46.forwardRef(
50348
50910
  ({
50349
50911
  className,
50350
50912
  inline = false,
@@ -50362,10 +50924,10 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
50362
50924
  disabled,
50363
50925
  ...props
50364
50926
  }, ref) => {
50365
- const toggleId = id ?? React45.useId();
50927
+ const toggleId = id ?? React46.useId();
50366
50928
  const trackW = width ? typeof width === "number" ? `${width}px` : width : "2.75rem";
50367
50929
  const trackH = height ? typeof height === "number" ? `${height}px` : height : "1.5rem";
50368
- const [internalChecked, setInternalChecked] = React45.useState(defaultChecked ?? false);
50930
+ const [internalChecked, setInternalChecked] = React46.useState(defaultChecked ?? false);
50369
50931
  const isControlled = checked !== void 0;
50370
50932
  const isOn = accepted ? true : declined ? false : isControlled ? checked : internalChecked;
50371
50933
  const stateColor = accepted ? acceptedColor ?? "#22c55e" : declined ? declinedColor ?? "#ef4444" : isOn ? void 0 : void 0;
@@ -50435,7 +50997,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
50435
50997
  ToggleSwitch.displayName = "ToggleSwitch";
50436
50998
 
50437
50999
  // src/components/ui/tree-view.tsx
50438
- var React46 = __toESM(require_react(), 1);
51000
+ var React47 = __toESM(require_react(), 1);
50439
51001
  var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
50440
51002
  function TreeNodeItem({ node, depth, selected, expanded, onToggleExpand, onSelect, multiple }) {
50441
51003
  const hasChildren = !!node.children?.length;
@@ -50488,8 +51050,8 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
50488
51050
  className
50489
51051
  }) {
50490
51052
  const init = defaultSelected ? Array.isArray(defaultSelected) ? defaultSelected : [defaultSelected] : [];
50491
- const [internal, setInternal] = React46.useState(init);
50492
- const [expanded, setExpanded] = React46.useState(defaultExpanded);
51053
+ const [internal, setInternal] = React47.useState(init);
51054
+ const [expanded, setExpanded] = React47.useState(defaultExpanded);
50493
51055
  const selected = controlled ? Array.isArray(controlled) ? controlled : [controlled] : internal;
50494
51056
  function handleSelect(id) {
50495
51057
  let next;
@@ -50520,7 +51082,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
50520
51082
  }
50521
51083
 
50522
51084
  // src/components/ui/widget.tsx
50523
- var React47 = __toESM(require_react(), 1);
51085
+ var React48 = __toESM(require_react(), 1);
50524
51086
  var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
50525
51087
  var iconColorMap = {
50526
51088
  primary: "bg-primary/10 text-primary",
@@ -50549,8 +51111,8 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
50549
51111
  outline: "bg-transparent border-2"
50550
51112
  };
50551
51113
  function useCountUp(target, enabled, duration = 1e3) {
50552
- const [display, setDisplay] = React47.useState(enabled ? 0 : target);
50553
- React47.useEffect(() => {
51114
+ const [display, setDisplay] = React48.useState(enabled ? 0 : target);
51115
+ React48.useEffect(() => {
50554
51116
  if (!enabled) {
50555
51117
  setDisplay(target);
50556
51118
  return;
@@ -50663,7 +51225,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
50663
51225
  }
50664
51226
 
50665
51227
  // src/components/ui/wizard.tsx
50666
- var React48 = __toESM(require_react(), 1);
51228
+ var React49 = __toESM(require_react(), 1);
50667
51229
  var import_jsx_runtime59 = __toESM(require_jsx_runtime(), 1);
50668
51230
  var SIZE_MAP = {
50669
51231
  sm: "max-w-sm",
@@ -50686,7 +51248,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
50686
51248
  return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "flex items-start w-full", children: steps.map((step, i) => {
50687
51249
  const status = stepStatus(i, current);
50688
51250
  const isLast = i === steps.length - 1;
50689
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(React48.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex flex-col items-center flex-1 min-w-0", children: [
51251
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(React49.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex flex-col items-center flex-1 min-w-0", children: [
50690
51252
  /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "flex items-center w-full", children: [
50691
51253
  i > 0 && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: cn("flex-1 h-0.5 transition-colors", i <= current ? "bg-primary" : "bg-border") }),
50692
51254
  /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
@@ -50914,7 +51476,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
50914
51476
  const isFirst = current === 0;
50915
51477
  const isLast = current === steps.length - 1;
50916
51478
  const isSidebar = variant === "sidebar";
50917
- const [validationError, setValidationError] = React48.useState(null);
51479
+ const [validationError, setValidationError] = React49.useState(null);
50918
51480
  const handleNext = () => {
50919
51481
  const validate = steps[current]?.validate;
50920
51482
  if (validate) {
@@ -51018,7 +51580,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
51018
51580
  className,
51019
51581
  contentClassName
51020
51582
  }) {
51021
- const [internalStep, setInternalStep] = React48.useState(defaultStep);
51583
+ const [internalStep, setInternalStep] = React49.useState(defaultStep);
51022
51584
  const current = controlledStep ?? internalStep;
51023
51585
  const go = (idx) => {
51024
51586
  const clamped = Math.max(0, Math.min(steps.length - 1, idx));
@@ -51033,7 +51595,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
51033
51595
  }
51034
51596
  go(current + 1);
51035
51597
  };
51036
- React48.useEffect(() => {
51598
+ React49.useEffect(() => {
51037
51599
  if (layout !== "modal" || !isOpen || unchange) return;
51038
51600
  const handler = (e) => {
51039
51601
  if (e.key === "Escape") onClose?.();
@@ -51250,6 +51812,7 @@ lucide-react/dist/esm/icons/redo.js:
51250
51812
  lucide-react/dist/esm/icons/rotate-ccw.js:
51251
51813
  lucide-react/dist/esm/icons/rotate-cw.js:
51252
51814
  lucide-react/dist/esm/icons/satellite.js:
51815
+ lucide-react/dist/esm/icons/save.js:
51253
51816
  lucide-react/dist/esm/icons/search.js:
51254
51817
  lucide-react/dist/esm/icons/settings-2.js:
51255
51818
  lucide-react/dist/esm/icons/sliders-vertical.js: