three-slicer 0.1.6 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +310 -22
  3. package/THIRD-PARTY-NOTICES.md +37 -0
  4. package/components/README.md +2 -0
  5. package/components/dist/SettingsPanel.js +92 -92
  6. package/data/config-schema.json +698 -0
  7. package/data/filaments.js +1 -1
  8. package/data/preset-keys.json +1 -0
  9. package/data/printers.json +1 -1
  10. package/data/processes.js +1 -1
  11. package/data/ui-tree.json +342 -0
  12. package/engine/README.md +279 -3
  13. package/engine/examples/sla_headless.mjs +51 -0
  14. package/engine/index.d.ts +77 -5
  15. package/engine/index.js +15 -4
  16. package/engine/src/client.js +165 -0
  17. package/engine/src/data.js +3 -0
  18. package/engine/src/preset_file.js +99 -0
  19. package/engine/src/settings.js +232 -0
  20. package/engine/src/sla_core.js +188 -0
  21. package/engine/src/sla_request.js +185 -0
  22. package/engine/src/slicer.worker.js +76 -4
  23. package/engine/src/slicer_core.js +0 -0
  24. package/engine/src/slicer_core.mt.js +0 -0
  25. package/package.json +26 -11
  26. package/types/client.d.ts +88 -0
  27. package/types/components.d.ts +10 -0
  28. package/types/data/preset-keys.json.d.ts +20 -0
  29. package/types/data/printers.json.d.ts +2 -2
  30. package/types/data.d.ts +4 -0
  31. package/types/settings-keys.d.ts +107 -1
  32. package/types/settings.d.ts +116 -1
  33. package/types/sla.d.ts +167 -0
  34. package/types/viewer.d.ts +59 -1
  35. package/types/worker.d.ts +95 -0
  36. package/viewer/README.md +163 -3
  37. package/viewer/dist/Viewport.js +3633 -3137
  38. package/viewer/dist/model_loaders.js +1 -1
  39. package/viewer/dist/parse_3mf-C2X_W442.js +300 -0
  40. package/viewer/dist/parse_3mf.worker.js +1 -1
  41. package/viewer/styles.css +5 -0
  42. package/types/gen_settings_types.mjs +0 -70
  43. package/viewer/dist/parse_3mf-8oCnCJNK.js +0 -216
@@ -1,63 +1,63 @@
1
- import e, { useRef as _, useState as h, useLayoutEffect as D, useEffect as P, useMemo as A } from "react";
2
- import { createPortal as F } from "react-dom";
3
- import { uiTree as S, schema as C } from "three-slicer/data";
4
- import { settingRaw as J } from "three-slicer/settings";
5
- import { disabledKeys as I, makeCfg as B } from "three-slicer/toggle";
6
- function L({ css: t, className: s, children: r }) {
7
- const i = _(null), [c] = h(() => {
8
- const l = document.createElement("div");
9
- return l.style.display = "contents", l;
1
+ import e, { useRef as L, useState as w, useLayoutEffect as P, useEffect as J, useMemo as F } from "react";
2
+ import { createPortal as B } from "react-dom";
3
+ import { uiTree as _, schema as S } from "three-slicer/data";
4
+ import { printerTechnology as I, settingRaw as T } from "three-slicer/settings";
5
+ import { disabledKeys as $, makeCfg as U } from "three-slicer/toggle";
6
+ function W({ css: t, className: s, children: n }) {
7
+ const i = L(null), [c] = w(() => {
8
+ const r = document.createElement("div");
9
+ return r.style.display = "contents", r;
10
10
  });
11
- return D(() => {
12
- const l = i.current, o = l.shadowRoot || l.attachShadow({ mode: "open" });
11
+ return P(() => {
12
+ const r = i.current, o = r.shadowRoot || r.attachShadow({ mode: "open" });
13
13
  let p = o.querySelector("style[data-ts-css]");
14
14
  p || (p = document.createElement("style"), p.setAttribute("data-ts-css", ""), o.append(p)), p.textContent = t, o.contains(c) || o.append(c);
15
- }, [t, c]), /* @__PURE__ */ e.createElement("div", { ref: i, className: s }, F(r, c));
15
+ }, [t, c]), /* @__PURE__ */ e.createElement("div", { ref: i, className: s }, B(n, c));
16
16
  }
17
- const $ = ':host{display:contents}*{box-sizing:border-box}.row{display:grid;grid-template-columns:260px 220px 70px 1fr;gap:8px;align-items:center;padding:3px 0;border-bottom:1px dashed #f0f0f0}.row .lbl{color:#222;text-decoration:none}.row .lbl:hover{color:#0a7d4f;text-decoration:underline}.row .key{font-size:11px;color:#999;overflow:hidden;text-overflow:ellipsis}.row input[type=text],.row input:not([type]),.row select,.row textarea{width:100%;max-width:260px;padding:2px 6px}.inputwrap{display:inline-flex;align-items:center;gap:4px}.unit{color:#888;font-size:12px;white-space:nowrap}.pts{font-size:11px;color:#666}.badge{font-size:10px;padding:1px 6px;border-radius:8px;color:#fff;text-align:center}.mode-simple{background:#2e9e5b}.mode-advanced{background:#3673c3}.mode-expert{background:#d9822b}.mode-develop{background:#c0392b}.mode-none,.mode-undefined{background:#aaa}.muted{color:#999;font-weight:400;font-size:12px}.row.custom{grid-template-columns:1fr}.row.disabled{opacity:.42}.row.disabled input,.row.disabled select,.row.disabled textarea{cursor:not-allowed;background:#f2f2f2}.lbl-cell{display:inline-flex;align-items:center;gap:5px;min-width:0}.lbl-cell .lbl{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dirty-dot{flex:0 0 auto;width:7px;height:7px;border-radius:50%;background:#e8873a;box-shadow:0 0 0 2px #fff3e6}.widget-cell{display:inline-flex;align-items:center;gap:6px;min-width:0}.reset-btn{flex:0 0 auto;border:1px solid #d8b48a;background:#fbf1e4;color:#b5701f;border-radius:5px;cursor:pointer;font-size:13px;line-height:1;padding:1px 5px}.reset-btn:hover{background:#f3e2cb}.settings-panel{flex:0 0 400px;width:400px;border-left:1px solid #e2e2e2;display:flex;flex-direction:column;min-height:0;background:#fff;color:#222;font:14px/1.5 -apple-system,Segoe UI,sans-serif}.settings-panel .sp-top{padding:10px 12px 8px;border-bottom:1px solid #eee}.sp-builder{display:flex;align-items:center;gap:8px;font-size:12px;color:#666}.sp-builder select{flex:1;padding:4px 6px}.sp-pages{display:flex;flex-wrap:wrap;gap:4px;margin-top:8px}.sp-pages button{border:1px solid #e0e0e0;background:#fafafa;border-radius:6px;padding:4px 8px;font-size:12px;cursor:pointer}.sp-pages button.on{background:#e6f5ee;color:#0a7d4f;border-color:#b7e2cd;font-weight:700}.sp-modes{display:flex;gap:4px;margin-top:8px}.sp-modes button{border:0;background:none;font-size:11px;color:#888;padding:2px 6px;border-radius:6px;cursor:pointer}.sp-modes button.on{background:#eef2f0;color:#0a7d4f;font-weight:700}.settings-panel .sp-body{flex:1 1 auto;overflow-y:auto;padding:8px 14px 24px}.settings-panel .sp-body h2{font-size:16px}.settings-panel .row{grid-template-columns:1fr auto;grid-template-areas:"lbl badge" "key widget";row-gap:2px;padding:6px 0}.settings-panel .row .lbl{grid-area:lbl;font-weight:600}.settings-panel .row .badge{grid-area:badge;justify-self:end}.settings-panel .row .key{grid-area:key}.settings-panel .row .inputwrap,.settings-panel .row>select,.settings-panel .row>input,.settings-panel .row>textarea,.settings-panel .row>.pts,.settings-panel .row>.muted{grid-area:widget;justify-self:end}.settings-panel .row input:not([type=checkbox]):not([type=color]),.settings-panel .row select,.settings-panel .row textarea{max-width:200px}.settings-panel .row.custom{grid-template-columns:1fr;grid-template-areas:"lbl"}.sp-search{width:100%;box-sizing:border-box;padding:6px 9px;border:1px solid #d6d6d6;border-radius:6px;font-size:13px;margin-bottom:8px}:host(.sp-embedded) .settings-panel{position:static;width:auto;flex:none;border:0;height:auto}:host(.sp-embedded) .sp-body{padding:4px 2px 8px;max-height:460px}.bse{display:flex;flex-direction:column;gap:6px;min-width:0;max-width:220px}.bse-modes{display:flex;gap:4px}.bse-modes button{border:1px solid #e0e0e0;background:#fafafa;border-radius:6px;padding:2px 8px;font-size:11px;cursor:pointer}.bse-modes button.on{background:#e6f5ee;color:#0a7d4f;border-color:#b7e2cd;font-weight:700}.bse-grid{display:grid;grid-template-columns:1fr 1fr;gap:4px 8px}.bse-grid label{display:flex;align-items:center;gap:4px;font-size:11px;color:#666;white-space:nowrap}.bse-grid input{width:56px;padding:2px 4px;font-size:12px}.bse-json{width:100%;font:11px ui-monospace,monospace;padding:4px 6px;border:1px solid #d6d6d6;border-radius:6px;box-sizing:border-box}.bse-json.err{border-color:#d0435a;background:#fdf3f4}', j = (t, s, r, i) => [[r, i], [t + r, i], [t + r, s + i], [r, s + i]], T = (t) => {
18
- const s = t / 2, r = 32;
19
- return Array.from({ length: r }, (i, c) => {
20
- const l = 2 * Math.PI * c / r;
21
- return [+(s + s * Math.cos(l)).toFixed(2), +(s + s * Math.sin(l)).toFixed(2)];
17
+ const q = ':host{display:contents}*{box-sizing:border-box}.row{display:grid;grid-template-columns:260px 220px 70px 1fr;gap:8px;align-items:center;padding:3px 0;border-bottom:1px dashed #f0f0f0}.row .lbl{color:#222;text-decoration:none}.row .lbl:hover{color:#0a7d4f;text-decoration:underline}.row .key{font-size:11px;color:#999;overflow:hidden;text-overflow:ellipsis}.row input[type=text],.row input:not([type]),.row select,.row textarea{width:100%;max-width:260px;padding:2px 6px}.inputwrap{display:inline-flex;align-items:center;gap:4px}.unit{color:#888;font-size:12px;white-space:nowrap}.pts{font-size:11px;color:#666}.badge{font-size:10px;padding:1px 6px;border-radius:8px;color:#fff;text-align:center}.mode-simple{background:#2e9e5b}.mode-advanced{background:#3673c3}.mode-expert{background:#d9822b}.mode-develop{background:#c0392b}.mode-none,.mode-undefined{background:#aaa}.muted{color:#999;font-weight:400;font-size:12px}.row.custom{grid-template-columns:1fr}.row.disabled{opacity:.42}.row.disabled input,.row.disabled select,.row.disabled textarea{cursor:not-allowed;background:#f2f2f2}.lbl-cell{display:inline-flex;align-items:center;gap:5px;min-width:0}.lbl-cell .lbl{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dirty-dot{flex:0 0 auto;width:7px;height:7px;border-radius:50%;background:#e8873a;box-shadow:0 0 0 2px #fff3e6}.widget-cell{display:inline-flex;align-items:center;gap:6px;min-width:0}.reset-btn{flex:0 0 auto;border:1px solid #d8b48a;background:#fbf1e4;color:#b5701f;border-radius:5px;cursor:pointer;font-size:13px;line-height:1;padding:1px 5px}.reset-btn:hover{background:#f3e2cb}.settings-panel{flex:0 0 400px;width:400px;border-left:1px solid #e2e2e2;display:flex;flex-direction:column;min-height:0;background:#fff;color:#222;font:14px/1.5 -apple-system,Segoe UI,sans-serif}.settings-panel .sp-top{padding:10px 12px 8px;border-bottom:1px solid #eee}.sp-builder{display:flex;align-items:center;gap:8px;font-size:12px;color:#666}.sp-builder select{flex:1;padding:4px 6px}.sp-pages{display:flex;flex-wrap:wrap;gap:4px;margin-top:8px}.sp-pages button{border:1px solid #e0e0e0;background:#fafafa;border-radius:6px;padding:4px 8px;font-size:12px;cursor:pointer}.sp-pages button.on{background:#e6f5ee;color:#0a7d4f;border-color:#b7e2cd;font-weight:700}.sp-modes{display:flex;gap:4px;margin-top:8px}.sp-modes button{border:0;background:none;font-size:11px;color:#888;padding:2px 6px;border-radius:6px;cursor:pointer}.sp-modes button.on{background:#eef2f0;color:#0a7d4f;font-weight:700}.settings-panel .sp-body{flex:1 1 auto;overflow-y:auto;padding:8px 14px 24px}.settings-panel .sp-body h2{font-size:16px}.settings-panel .row{grid-template-columns:1fr auto;grid-template-areas:"lbl badge" "key widget";row-gap:2px;padding:6px 0}.settings-panel .row .lbl{grid-area:lbl;font-weight:600}.settings-panel .row .badge{grid-area:badge;justify-self:end}.settings-panel .row .key{grid-area:key}.settings-panel .row .inputwrap,.settings-panel .row>select,.settings-panel .row>input,.settings-panel .row>textarea,.settings-panel .row>.pts,.settings-panel .row>.muted{grid-area:widget;justify-self:end}.settings-panel .row input:not([type=checkbox]):not([type=color]),.settings-panel .row select,.settings-panel .row textarea{max-width:200px}.settings-panel .row.custom{grid-template-columns:1fr;grid-template-areas:"lbl"}.sp-search{width:100%;box-sizing:border-box;padding:6px 9px;border:1px solid #d6d6d6;border-radius:6px;font-size:13px;margin-bottom:8px}:host(.sp-embedded) .settings-panel{position:static;width:auto;flex:none;border:0;height:auto}:host(.sp-embedded) .sp-body{padding:4px 2px 8px;max-height:460px}.bse{display:flex;flex-direction:column;gap:6px;min-width:0;max-width:220px}.bse-modes{display:flex;gap:4px}.bse-modes button{border:1px solid #e0e0e0;background:#fafafa;border-radius:6px;padding:2px 8px;font-size:11px;cursor:pointer}.bse-modes button.on{background:#e6f5ee;color:#0a7d4f;border-color:#b7e2cd;font-weight:700}.bse-grid{display:grid;grid-template-columns:1fr 1fr;gap:4px 8px}.bse-grid label{display:flex;align-items:center;gap:4px;font-size:11px;color:#666;white-space:nowrap}.bse-grid input{width:56px;padding:2px 4px;font-size:12px}.bse-json{width:100%;font:11px ui-monospace,monospace;padding:4px 6px;border:1px solid #d6d6d6;border-radius:6px;box-sizing:border-box}.bse-json.err{border-color:#d0435a;background:#fdf3f4}', O = (t, s, n, i) => [[n, i], [t + n, i], [t + n, s + i], [n, s + i]], G = (t) => {
18
+ const s = t / 2, n = 32;
19
+ return Array.from({ length: n }, (i, c) => {
20
+ const r = 2 * Math.PI * c / n;
21
+ return [+(s + s * Math.cos(r)).toFixed(2), +(s + s * Math.sin(r)).toFixed(2)];
22
22
  });
23
- }, O = (t) => {
24
- const s = t.map((i) => i[0]), r = t.map((i) => i[1]);
25
- return { x0: Math.min(...s), y0: Math.min(...r), w: Math.max(...s) - Math.min(...s), d: Math.max(...r) - Math.min(...r) };
23
+ }, R = (t) => {
24
+ const s = t.map((i) => i[0]), n = t.map((i) => i[1]);
25
+ return { x0: Math.min(...s), y0: Math.min(...n), w: Math.max(...s) - Math.min(...s), d: Math.max(...n) - Math.min(...n) };
26
26
  };
27
- function U({ value: t, onChange: s, disabled: r }) {
28
- const i = Array.isArray(t) && t.length >= 3 ? t : j(200, 200, 0, 0), c = O(i), [l, o] = h(i.length === 4 ? "rect" : i.length >= 12 ? "circle" : "custom"), [p, x] = h({ w: c.w, d: c.d, ox: c.x0, oy: c.y0 }), [w, u] = h(Math.round(c.w)), [d, f] = h(JSON.stringify(i)), [E, N] = h(!1);
29
- P(() => {
30
- const a = O(i);
31
- x({ w: a.w, d: a.d, ox: a.x0, oy: a.y0 }), u(Math.round(a.w)), f(JSON.stringify(i)), N(!1);
27
+ function H({ value: t, onChange: s, disabled: n }) {
28
+ const i = Array.isArray(t) && t.length >= 3 ? t : O(200, 200, 0, 0), c = R(i), [r, o] = w(i.length === 4 ? "rect" : i.length >= 12 ? "circle" : "custom"), [p, b] = w({ w: c.w, d: c.d, ox: c.x0, oy: c.y0 }), [E, g] = w(Math.round(c.w)), [d, x] = w(JSON.stringify(i)), [y, k] = w(!1);
29
+ J(() => {
30
+ const a = R(i);
31
+ b({ w: a.w, d: a.d, ox: a.x0, oy: a.y0 }), g(Math.round(a.w)), x(JSON.stringify(i)), k(!1);
32
32
  }, [JSON.stringify(t)]);
33
- const y = (a) => {
34
- x(a);
35
- const { w: m, d: n, ox: b, oy: v } = a;
36
- m > 0 && n > 0 && s(j(m, n, b, v));
37
- }, k = (a) => {
38
- u(a), a > 0 && s(T(a));
33
+ const v = (a) => {
34
+ b(a);
35
+ const { w: u, d: m, ox: N, oy: z } = a;
36
+ u > 0 && m > 0 && s(O(u, m, N, z));
39
37
  }, M = (a) => {
40
- f(a);
38
+ g(a), a > 0 && s(G(a));
39
+ }, A = (a) => {
40
+ x(a);
41
41
  try {
42
- const m = JSON.parse(a);
43
- if (!Array.isArray(m) || m.length < 3 || !m.every((n) => Array.isArray(n) && n.length === 2 && n.every(Number.isFinite))) throw 0;
44
- N(!1), s(m);
42
+ const u = JSON.parse(a);
43
+ if (!Array.isArray(u) || u.length < 3 || !u.every((m) => Array.isArray(m) && m.length === 2 && m.every(Number.isFinite))) throw 0;
44
+ k(!1), s(u);
45
45
  } catch {
46
- N(!0);
46
+ k(!0);
47
47
  }
48
- }, g = (a) => {
49
- const m = parseFloat(a);
50
- return Number.isFinite(m) ? m : 0;
48
+ }, h = (a) => {
49
+ const u = parseFloat(a);
50
+ return Number.isFinite(u) ? u : 0;
51
51
  };
52
- return /* @__PURE__ */ e.createElement("div", { className: "bse", "data-testid": "bed-shape-editor" }, /* @__PURE__ */ e.createElement("div", { className: "bse-modes" }, [["rect", "Rectangular"], ["circle", "Circular"], ["custom", "Custom"]].map(([a, m]) => /* @__PURE__ */ e.createElement("button", { key: a, type: "button", className: l === a ? "on" : "", disabled: r, onClick: () => o(a) }, m))), l === "rect" && /* @__PURE__ */ e.createElement("div", { className: "bse-grid" }, /* @__PURE__ */ e.createElement("label", null, "Width ", /* @__PURE__ */ e.createElement(
52
+ return /* @__PURE__ */ e.createElement("div", { className: "bse", "data-testid": "bed-shape-editor" }, /* @__PURE__ */ e.createElement("div", { className: "bse-modes" }, [["rect", "Rectangular"], ["circle", "Circular"], ["custom", "Custom"]].map(([a, u]) => /* @__PURE__ */ e.createElement("button", { key: a, type: "button", className: r === a ? "on" : "", disabled: n, onClick: () => o(a) }, u))), r === "rect" && /* @__PURE__ */ e.createElement("div", { className: "bse-grid" }, /* @__PURE__ */ e.createElement("label", null, "Width ", /* @__PURE__ */ e.createElement(
53
53
  "input",
54
54
  {
55
55
  type: "number",
56
56
  min: "1",
57
57
  value: p.w,
58
- disabled: r,
58
+ disabled: n,
59
59
  "data-testid": "bed-w",
60
- onChange: (a) => y({ ...p, w: g(a.target.value) })
60
+ onChange: (a) => v({ ...p, w: h(a.target.value) })
61
61
  }
62
62
  ), " mm"), /* @__PURE__ */ e.createElement("label", null, "Depth ", /* @__PURE__ */ e.createElement(
63
63
  "input",
@@ -65,84 +65,84 @@ function U({ value: t, onChange: s, disabled: r }) {
65
65
  type: "number",
66
66
  min: "1",
67
67
  value: p.d,
68
- disabled: r,
68
+ disabled: n,
69
69
  "data-testid": "bed-d",
70
- onChange: (a) => y({ ...p, d: g(a.target.value) })
70
+ onChange: (a) => v({ ...p, d: h(a.target.value) })
71
71
  }
72
72
  ), " mm"), /* @__PURE__ */ e.createElement("label", null, "Origin X ", /* @__PURE__ */ e.createElement(
73
73
  "input",
74
74
  {
75
75
  type: "number",
76
76
  value: p.ox,
77
- disabled: r,
78
- onChange: (a) => y({ ...p, ox: g(a.target.value) })
77
+ disabled: n,
78
+ onChange: (a) => v({ ...p, ox: h(a.target.value) })
79
79
  }
80
80
  )), /* @__PURE__ */ e.createElement("label", null, "Origin Y ", /* @__PURE__ */ e.createElement(
81
81
  "input",
82
82
  {
83
83
  type: "number",
84
84
  value: p.oy,
85
- disabled: r,
86
- onChange: (a) => y({ ...p, oy: g(a.target.value) })
85
+ disabled: n,
86
+ onChange: (a) => v({ ...p, oy: h(a.target.value) })
87
87
  }
88
- ))), l === "circle" && /* @__PURE__ */ e.createElement("div", { className: "bse-grid" }, /* @__PURE__ */ e.createElement("label", null, "Diameter ", /* @__PURE__ */ e.createElement(
88
+ ))), r === "circle" && /* @__PURE__ */ e.createElement("div", { className: "bse-grid" }, /* @__PURE__ */ e.createElement("label", null, "Diameter ", /* @__PURE__ */ e.createElement(
89
89
  "input",
90
90
  {
91
91
  type: "number",
92
92
  min: "1",
93
- value: w,
94
- disabled: r,
93
+ value: E,
94
+ disabled: n,
95
95
  "data-testid": "bed-dia",
96
- onChange: (a) => k(g(a.target.value))
96
+ onChange: (a) => M(h(a.target.value))
97
97
  }
98
- ), " mm")), l === "custom" && /* @__PURE__ */ e.createElement(
98
+ ), " mm")), r === "custom" && /* @__PURE__ */ e.createElement(
99
99
  "textarea",
100
100
  {
101
- className: "bse-json" + (E ? " err" : ""),
101
+ className: "bse-json" + (y ? " err" : ""),
102
102
  rows: 3,
103
103
  value: d,
104
- disabled: r,
104
+ disabled: n,
105
105
  "data-testid": "bed-json",
106
- onChange: (a) => M(a.target.value),
106
+ onChange: (a) => A(a.target.value),
107
107
  placeholder: "[[0,0],[200,0],[200,200],[0,200]]"
108
108
  }
109
109
  ));
110
110
  }
111
- const W = {
112
- printable_area: U
113
- }, R = Object.keys(S).filter((t) => S[t].length > 0), q = ["all", "simple", "advanced", "expert", "develop"], G = (t) => t.replace("::build", "").replace("Tab", "");
114
- function H(t, s) {
111
+ const Q = {
112
+ printable_area: H
113
+ }, D = Object.keys(_).filter((t) => _[t].length > 0), X = ["all", "simple", "advanced", "expert", "develop"], Y = (t) => t.replace("::build", "").replace("Tab", "").replace("_sla", " (SLA)"), V = (t) => /SLA|build_sla\b/.test(t) ? "SLA" : "FFF";
114
+ function Z(t, s) {
115
115
  var c;
116
116
  if (!t || !(s in t)) return !1;
117
- const r = (c = C[s]) == null ? void 0 : c.default, i = Array.isArray(r) ? r[0] : r;
117
+ const n = (c = S[s]) == null ? void 0 : c.default, i = Array.isArray(n) ? n[0] : n;
118
118
  return String(t[s]) !== String(i ?? "");
119
119
  }
120
- function Q(t, s) {
120
+ function K(t, s) {
121
121
  var i;
122
122
  if (s === "all" || t.startsWith("<")) return !0;
123
- const r = (i = C[t]) == null ? void 0 : i.mode;
124
- return s === "simple" ? r === "simple" : s === "advanced" ? r === "simple" || r === "advanced" : !0;
123
+ const n = (i = S[t]) == null ? void 0 : i.mode;
124
+ return s === "simple" ? n === "simple" : s === "advanced" ? n === "simple" || n === "advanced" : !0;
125
125
  }
126
- function X(t) {
126
+ function ee(t) {
127
127
  return t ? t.gui_type === "color" ? "color" : t.enum_values ? "select" : t.type === "coBool" || t.type === "coBools" ? "checkbox" : t.multiline || t.is_code ? "textarea" : t.type === "coPoints" || t.type === "coPoint" ? "points" : "input" : "unknown";
128
128
  }
129
- function Y({ mode: t }) {
129
+ function te({ mode: t }) {
130
130
  return /* @__PURE__ */ e.createElement("span", { className: `badge mode-${t ?? "none"}` }, t ?? "—");
131
131
  }
132
- function V({ def: t, optKey: s, settings: r, setSettings: i, disabled: c, customWidgets: l }) {
133
- const o = J(r, s), p = (d) => i((f) => ({ ...f, [s]: d })), x = (l == null ? void 0 : l[s]) ?? W[s];
134
- if (x) return /* @__PURE__ */ e.createElement(x, { def: t, value: o, onChange: p, disabled: c });
135
- const w = X(t), u = Array.isArray(o) ? o[0] : o;
136
- switch (w) {
132
+ function ae({ def: t, optKey: s, settings: n, setSettings: i, disabled: c, customWidgets: r }) {
133
+ const o = T(n, s), p = (d) => i((x) => ({ ...x, [s]: d })), b = (r == null ? void 0 : r[s]) ?? Q[s];
134
+ if (b) return /* @__PURE__ */ e.createElement(b, { def: t, value: o, onChange: p, disabled: c });
135
+ const E = ee(t), g = Array.isArray(o) ? o[0] : o;
136
+ switch (E) {
137
137
  case "select":
138
- return /* @__PURE__ */ e.createElement("select", { value: u ?? "", onChange: (d) => p(d.target.value), disabled: c }, t.enum_values.map((d, f) => {
139
- var E;
140
- return /* @__PURE__ */ e.createElement("option", { key: d, value: d }, ((E = t.enum_labels) == null ? void 0 : E[f]) ?? d);
138
+ return /* @__PURE__ */ e.createElement("select", { value: g ?? "", onChange: (d) => p(d.target.value), disabled: c }, t.enum_values.map((d, x) => {
139
+ var y;
140
+ return /* @__PURE__ */ e.createElement("option", { key: d, value: d }, ((y = t.enum_labels) == null ? void 0 : y[x]) ?? d);
141
141
  }));
142
142
  case "checkbox":
143
143
  return /* @__PURE__ */ e.createElement("input", { type: "checkbox", checked: Array.isArray(o) ? !!o[0] : !!o, onChange: (d) => p(d.target.checked), disabled: c });
144
144
  case "color":
145
- return /* @__PURE__ */ e.createElement("input", { type: "color", value: typeof u == "string" && u.startsWith("#") ? u : "#00ae42", onChange: (d) => p(d.target.value), disabled: c });
145
+ return /* @__PURE__ */ e.createElement("input", { type: "color", value: typeof g == "string" && g.startsWith("#") ? g : "#00ae42", onChange: (d) => p(d.target.value), disabled: c });
146
146
  case "textarea":
147
147
  return /* @__PURE__ */ e.createElement("textarea", { rows: 2, value: Array.isArray(o) ? o.join(`
148
148
  `) : o ?? "", onChange: (d) => p(d.target.value), disabled: c });
@@ -151,29 +151,29 @@ function V({ def: t, optKey: s, settings: r, setSettings: i, disabled: c, custom
151
151
  case "unknown":
152
152
  return /* @__PURE__ */ e.createElement("span", { className: "muted" }, "No schema");
153
153
  default:
154
- return /* @__PURE__ */ e.createElement("span", { className: "inputwrap" }, /* @__PURE__ */ e.createElement("input", { value: u ?? "", onChange: (d) => p(d.target.value), disabled: c }), t.sidetext && /* @__PURE__ */ e.createElement("span", { className: "unit" }, t.sidetext));
154
+ return /* @__PURE__ */ e.createElement("span", { className: "inputwrap" }, /* @__PURE__ */ e.createElement("input", { value: g ?? "", onChange: (d) => p(d.target.value), disabled: c }), t.sidetext && /* @__PURE__ */ e.createElement("span", { className: "unit" }, t.sidetext));
155
155
  }
156
156
  }
157
- function Z({ optKey: t, settings: s, setSettings: r, disabled: i, onOptionOpen: c, customWidgets: l }) {
157
+ function ne({ optKey: t, settings: s, setSettings: n, disabled: i, onOptionOpen: c, customWidgets: r }) {
158
158
  if (t.startsWith("<")) return /* @__PURE__ */ e.createElement("div", { className: "row custom" }, /* @__PURE__ */ e.createElement("span", { className: "muted" }, "⚙ Custom widget ", t));
159
- const o = C[t], p = i ? i[t] : void 0, x = p != null, w = H(s, t), u = () => r((f) => {
160
- const E = { ...f };
161
- return delete E[t], E;
159
+ const o = S[t], p = i ? i[t] : void 0, b = p != null, E = Z(s, t), g = () => n((x) => {
160
+ const y = { ...x };
161
+ return delete y[t], y;
162
162
  }), d = (o == null ? void 0 : o.label) || (o == null ? void 0 : o.full_label) || t;
163
- return /* @__PURE__ */ e.createElement("div", { className: "row" + (x ? " disabled" : ""), title: x ? `Disabled when: ${p}` : (o == null ? void 0 : o.tooltip) ?? "", "data-testid": `row-${t}` }, /* @__PURE__ */ e.createElement("span", { className: "lbl-cell" }, w && /* @__PURE__ */ e.createElement("span", { className: "dirty-dot", title: "Changed from default", "data-testid": `dirty-${t}` }), c ? /* @__PURE__ */ e.createElement("button", { type: "button", className: "lbl lbl-link", onClick: () => c(t), title: "Details" }, d) : /* @__PURE__ */ e.createElement("span", { className: "lbl" }, d)), /* @__PURE__ */ e.createElement("code", { className: "key" }, t), /* @__PURE__ */ e.createElement(Y, { mode: o == null ? void 0 : o.mode }), /* @__PURE__ */ e.createElement("span", { className: "widget-cell" }, /* @__PURE__ */ e.createElement(V, { def: o, optKey: t, settings: s, setSettings: r, disabled: x, customWidgets: l }), w && /* @__PURE__ */ e.createElement("button", { className: "reset-btn", onClick: u, title: "Reset to default", "data-testid": `reset-${t}` }, "↺")));
163
+ return /* @__PURE__ */ e.createElement("div", { className: "row" + (b ? " disabled" : ""), title: b ? `Disabled when: ${p}` : (o == null ? void 0 : o.tooltip) ?? "", "data-testid": `row-${t}` }, /* @__PURE__ */ e.createElement("span", { className: "lbl-cell" }, E && /* @__PURE__ */ e.createElement("span", { className: "dirty-dot", title: "Changed from default", "data-testid": `dirty-${t}` }), c ? /* @__PURE__ */ e.createElement("button", { type: "button", className: "lbl lbl-link", onClick: () => c(t), title: "Details" }, d) : /* @__PURE__ */ e.createElement("span", { className: "lbl" }, d)), /* @__PURE__ */ e.createElement("code", { className: "key" }, t), /* @__PURE__ */ e.createElement(te, { mode: o == null ? void 0 : o.mode }), /* @__PURE__ */ e.createElement("span", { className: "widget-cell" }, /* @__PURE__ */ e.createElement(ae, { def: o, optKey: t, settings: s, setSettings: n, disabled: b, customWidgets: r }), E && /* @__PURE__ */ e.createElement("button", { className: "reset-btn", onClick: g, title: "Reset to default", "data-testid": `reset-${t}` }, "↺")));
164
164
  }
165
- function re({ settings: t, setSettings: s, onOptionOpen: r, embedded: i = !1, customWidgets: c, only: l }) {
166
- const [o, p] = h((l == null ? void 0 : l.builder) ?? R[0] ?? ""), [x, w] = h(0), [u, d] = h("all"), [f, E] = h(""), N = S[(l == null ? void 0 : l.builder) ?? o] ?? [], y = l != null && l.page ? N.filter((n) => n.page === l.page) : N, k = y[Math.min(x, y.length - 1)], M = A(() => I(B(t)), [t]), g = f.trim().toLowerCase(), a = A(() => g ? Object.entries(C).filter(([n, b]) => {
167
- var v, z;
168
- return n.includes(g) || ((v = b.label) == null ? void 0 : v.toLowerCase().includes(g)) || ((z = b.full_label) == null ? void 0 : z.toLowerCase().includes(g));
169
- }).slice(0, 60).map(([n]) => n) : [], [g]), m = (n, b) => /* @__PURE__ */ e.createElement(Z, { key: n + b, optKey: n, settings: t, setSettings: s, disabled: M, onOptionOpen: r, customWidgets: c });
170
- return /* @__PURE__ */ e.createElement(L, { css: $, className: i ? "sp-embedded" : void 0 }, /* @__PURE__ */ e.createElement("div", { className: "settings-panel" }, !l && /* @__PURE__ */ e.createElement("div", { className: "sp-top" }, /* @__PURE__ */ e.createElement("input", { className: "sp-search", placeholder: `Search options (${Object.keys(C).length})…`, value: f, onChange: (n) => E(n.target.value), "data-testid": "opt-search" }), !g && /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement("label", { className: "sp-builder" }, /* @__PURE__ */ e.createElement("span", null, "Settings group"), /* @__PURE__ */ e.createElement("select", { value: o, onChange: (n) => {
171
- p(n.target.value), w(0);
172
- } }, R.map((n) => /* @__PURE__ */ e.createElement("option", { key: n, value: n }, G(n))))), /* @__PURE__ */ e.createElement("div", { className: "sp-pages" }, y.map((n, b) => /* @__PURE__ */ e.createElement("button", { key: n.page + b, className: b === Math.min(x, y.length - 1) ? "on" : "", onClick: () => w(b) }, n.page))), /* @__PURE__ */ e.createElement("div", { className: "sp-modes" }, q.map((n) => /* @__PURE__ */ e.createElement("button", { key: n, className: u === n ? "on" : "", onClick: () => d(n) }, n))))), /* @__PURE__ */ e.createElement("div", { className: "sp-body" }, g ? /* @__PURE__ */ e.createElement("section", { "data-testid": "search-results" }, /* @__PURE__ */ e.createElement("h3", null, "Search: “", f, "” — ", a.length, " hit", a.length === 1 ? "" : "s", a.length === 60 ? "+" : ""), a.map(m), !a.length && /* @__PURE__ */ e.createElement("p", { className: "muted" }, "No matches")) : k ? /* @__PURE__ */ e.createElement(e.Fragment, null, !l && /* @__PURE__ */ e.createElement("h2", null, k.page, " ", /* @__PURE__ */ e.createElement("span", { className: "muted" }, "Tab.cpp:", k.line)), k.groups.map((n) => {
173
- const b = n.options.filter((v) => Q(v, u) && !(l && v.startsWith("<")));
174
- return b.length ? /* @__PURE__ */ e.createElement("section", { key: n.group + n.line }, /* @__PURE__ */ e.createElement("h3", null, n.group || "(untitled group)", " ", /* @__PURE__ */ e.createElement("span", { className: "muted" }, ":", n.line)), b.map(m)) : null;
165
+ function ce({ settings: t, setSettings: s, onOptionOpen: n, embedded: i = !1, customWidgets: c, only: r }) {
166
+ const [o, p] = w((r == null ? void 0 : r.builder) ?? D[0] ?? ""), [b, E] = w(0), [g, d] = w("all"), [x, y] = w(""), k = I(t), v = D.filter((l) => V(l) === k), M = (r == null ? void 0 : r.builder) ?? (v.includes(o) ? o : v[0] ?? ""), A = _[(r == null ? void 0 : r.builder) ?? M] ?? [], h = r != null && r.page ? A.filter((l) => l.page === r.page) : A, a = h[Math.min(b, h.length - 1)], u = F(() => $(U(t)), [t]), m = x.trim().toLowerCase(), N = F(() => m ? Object.entries(S).filter(([l, f]) => {
167
+ var C, j;
168
+ return l.includes(m) || ((C = f.label) == null ? void 0 : C.toLowerCase().includes(m)) || ((j = f.full_label) == null ? void 0 : j.toLowerCase().includes(m));
169
+ }).slice(0, 60).map(([l]) => l) : [], [m]), z = (l, f) => /* @__PURE__ */ e.createElement(ne, { key: l + f, optKey: l, settings: t, setSettings: s, disabled: u, onOptionOpen: n, customWidgets: c });
170
+ return /* @__PURE__ */ e.createElement(W, { css: q, className: i ? "sp-embedded" : void 0 }, /* @__PURE__ */ e.createElement("div", { className: "settings-panel" }, !r && /* @__PURE__ */ e.createElement("div", { className: "sp-top" }, /* @__PURE__ */ e.createElement("input", { className: "sp-search", placeholder: `Search options (${Object.keys(S).length})…`, value: x, onChange: (l) => y(l.target.value), "data-testid": "opt-search" }), !m && /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement("label", { className: "sp-builder" }, /* @__PURE__ */ e.createElement("span", null, "Settings group"), /* @__PURE__ */ e.createElement("select", { value: M, onChange: (l) => {
171
+ p(l.target.value), E(0);
172
+ } }, v.map((l) => /* @__PURE__ */ e.createElement("option", { key: l, value: l }, Y(l))))), /* @__PURE__ */ e.createElement("div", { className: "sp-pages" }, h.map((l, f) => /* @__PURE__ */ e.createElement("button", { key: l.page + f, className: f === Math.min(b, h.length - 1) ? "on" : "", onClick: () => E(f) }, l.page))), /* @__PURE__ */ e.createElement("div", { className: "sp-modes" }, X.map((l) => /* @__PURE__ */ e.createElement("button", { key: l, className: g === l ? "on" : "", onClick: () => d(l) }, l))))), /* @__PURE__ */ e.createElement("div", { className: "sp-body" }, m ? /* @__PURE__ */ e.createElement("section", { "data-testid": "search-results" }, /* @__PURE__ */ e.createElement("h3", null, "Search: “", x, "” — ", N.length, " hit", N.length === 1 ? "" : "s", N.length === 60 ? "+" : ""), N.map(z), !N.length && /* @__PURE__ */ e.createElement("p", { className: "muted" }, "No matches")) : a ? /* @__PURE__ */ e.createElement(e.Fragment, null, !r && /* @__PURE__ */ e.createElement("h2", null, a.page, " ", /* @__PURE__ */ e.createElement("span", { className: "muted" }, "Tab.cpp:", a.line)), a.groups.map((l) => {
173
+ const f = l.options.filter((C) => K(C, g) && !(r && C.startsWith("<")));
174
+ return f.length ? /* @__PURE__ */ e.createElement("section", { key: l.group + l.line }, /* @__PURE__ */ e.createElement("h3", null, l.group || "(untitled group)", " ", /* @__PURE__ */ e.createElement("span", { className: "muted" }, ":", l.line)), f.map(z)) : null;
175
175
  })) : /* @__PURE__ */ e.createElement("p", { className: "muted" }, "No builder"))));
176
176
  }
177
177
  export {
178
- re as default
178
+ ce as default
179
179
  };