three-slicer-viewer 0.3.2 → 0.3.4

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.
@@ -8,39 +8,39 @@ import { S as X } from "./shadow_host-CQ3LirzD.js";
8
8
  const Y = ':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 var(--_light-divider)}.row .lbl{color:var(--_light-text);text-decoration:none}.row .lbl:hover{color:var(--_accent-ink);text-decoration:underline}.row .key{font-size:11px;color:var(--_light-text-faint);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:var(--_light-text-faint);font-size:12px;white-space:nowrap}.pts{font-size:11px;color:var(--_light-text-muted)}.badge{font-size:10px;padding:1px 6px;border-radius:8px;color:var(--_on-accent);text-align:center}.mode-simple{background:var(--_accent-ink)}.mode-advanced{background:var(--_info-ink)}.mode-expert{background:var(--_warn)}.mode-develop{background:var(--_danger)}.mode-none,.mode-undefined{background:var(--_light-text-faint)}.muted{color:var(--_light-text-faint);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:var(--_light-subtle)}.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:var(--_warn);box-shadow:0 0 0 2px var(--_warn-soft)}.override-dot{flex:0 0 auto;width:9px;height:9px;border-radius:50%;background:var(--_warn);border:0;padding:0;cursor:pointer;box-shadow:0 0 0 2px var(--_warn-soft)}.override-dot:hover{background:var(--_warn-ink)}.widget-cell{display:inline-flex;align-items:center;gap:6px;min-width:0}.reset-btn{flex:0 0 auto;border:1px solid var(--_warn-border);background:var(--_warn-soft);color:var(--_warn-ink);border-radius:5px;cursor:pointer;font-size:13px;line-height:1;padding:1px 5px}.reset-btn:hover{background:var(--_warn-soft-hover)}.settings-panel{flex:0 0 400px;width:400px;border-left:1px solid var(--_light-divider);display:flex;flex-direction:column;min-height:0;background:var(--_light-surface);color:var(--_light-text);font:14px/1.5 -apple-system,Segoe UI,sans-serif}.settings-panel .sp-top{padding:10px 12px 8px;border-bottom:1px solid var(--_light-divider)}.sp-builder{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--_light-text-muted)}.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 var(--_light-border);background:var(--_light-subtle);border-radius:6px;padding:4px 8px;font-size:12px;cursor:pointer}.sp-pages button.on{background:var(--_accent-soft);color:var(--_accent-ink);border-color:var(--_accent-soft-border);font-weight:700}.sp-modes{display:flex;gap:4px;margin-top:8px}.sp-modes button{border:0;background:none;font-size:11px;color:var(--_light-text-faint);padding:2px 6px;border-radius:6px;cursor:pointer}.sp-modes button.on{background:var(--_accent-soft);color:var(--_accent-ink);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 var(--_light-border);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 var(--_light-border);background:var(--_light-subtle);border-radius:6px;padding:2px 8px;font-size:11px;cursor:pointer}.bse-modes button.on{background:var(--_accent-soft);color:var(--_accent-ink);border-color:var(--_accent-soft-border);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:var(--_light-text-muted);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 var(--_light-border);border-radius:6px;box-sizing:border-box}.bse-json.err{border-color:var(--_danger);background:var(--_danger-soft)}', q = (t, a, r, o) => [[r, o], [t + r, o], [t + r, a + o], [r, a + o]], L = R.printable_area.default, V = (t) => {
9
9
  const a = t / 2, r = 32;
10
10
  return Array.from({ length: r }, (o, i) => {
11
- const u = 2 * Math.PI * i / r;
12
- return [+(a + a * Math.cos(u)).toFixed(2), +(a + a * Math.sin(u)).toFixed(2)];
11
+ const m = 2 * Math.PI * i / r;
12
+ return [+(a + a * Math.cos(m)).toFixed(2), +(a + a * Math.sin(m)).toFixed(2)];
13
13
  });
14
14
  }, T = (t) => {
15
15
  const a = t.map((o) => o[0]), r = t.map((o) => o[1]);
16
16
  return { x0: Math.min(...a), y0: Math.min(...r), w: Math.max(...a) - Math.min(...a), d: Math.max(...r) - Math.min(...r) };
17
17
  };
18
18
  function Z({ value: t, onChange: a, disabled: r }) {
19
- const o = Array.isArray(t) && t.length >= 3 ? t : L, i = T(o), [u, d] = y(o.length === 4 ? "rect" : o.length >= 12 ? "circle" : "custom"), [c, p] = y({ w: i.w, d: i.d, ox: i.x0, oy: i.y0 }), [x, g] = y(Math.round(i.w)), [l, b] = y(JSON.stringify(o)), [k, w] = y(!1);
19
+ const o = Array.isArray(t) && t.length >= 3 ? t : L, i = T(o), [m, d] = y(o.length === 4 ? "rect" : o.length >= 12 ? "circle" : "custom"), [c, p] = y({ w: i.w, d: i.d, ox: i.x0, oy: i.y0 }), [x, b] = y(Math.round(i.w)), [l, u] = y(JSON.stringify(o)), [_, w] = y(!1);
20
20
  P(() => {
21
21
  const n = T(o);
22
- p({ w: n.w, d: n.d, ox: n.x0, oy: n.y0 }), g(Math.round(n.w)), b(JSON.stringify(o)), w(!1);
22
+ p({ w: n.w, d: n.d, ox: n.x0, oy: n.y0 }), b(Math.round(n.w)), u(JSON.stringify(o)), w(!1);
23
23
  }, [JSON.stringify(t)]);
24
24
  const v = (n) => {
25
25
  p(n);
26
- const { w: m, d: f, ox: S, oy: M } = n;
27
- m > 0 && f > 0 && a(q(m, f, S, M));
28
- }, _ = (n) => {
29
- g(n), n > 0 && a(V(n));
26
+ const { w: g, d: f, ox: S, oy: M } = n;
27
+ g > 0 && f > 0 && a(q(g, f, S, M));
28
+ }, N = (n) => {
29
+ b(n), n > 0 && a(V(n));
30
30
  }, z = (n) => {
31
- b(n);
31
+ u(n);
32
32
  try {
33
- const m = JSON.parse(n);
34
- if (!Array.isArray(m) || m.length < 3 || !m.every((f) => Array.isArray(f) && f.length === 2 && f.every(Number.isFinite))) throw 0;
35
- w(!1), a(m);
33
+ const g = JSON.parse(n);
34
+ if (!Array.isArray(g) || g.length < 3 || !g.every((f) => Array.isArray(f) && f.length === 2 && f.every(Number.isFinite))) throw 0;
35
+ w(!1), a(g);
36
36
  } catch {
37
37
  w(!0);
38
38
  }
39
39
  }, E = (n) => {
40
- const m = parseFloat(n);
41
- return Number.isFinite(m) ? m : 0;
40
+ const g = parseFloat(n);
41
+ return Number.isFinite(g) ? g : 0;
42
42
  };
43
- 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(([n, m]) => /* @__PURE__ */ e.createElement("button", { key: n, type: "button", className: u === n ? "on" : "", disabled: r, onClick: () => d(n) }, m))), u === "rect" && /* @__PURE__ */ e.createElement("div", { className: "bse-grid" }, /* @__PURE__ */ e.createElement("label", null, "Width ", /* @__PURE__ */ e.createElement(
43
+ 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(([n, g]) => /* @__PURE__ */ e.createElement("button", { key: n, type: "button", className: m === n ? "on" : "", disabled: r, onClick: () => d(n) }, g))), m === "rect" && /* @__PURE__ */ e.createElement("div", { className: "bse-grid" }, /* @__PURE__ */ e.createElement("label", null, "Width ", /* @__PURE__ */ e.createElement(
44
44
  "input",
45
45
  {
46
46
  type: "number",
@@ -76,7 +76,7 @@ function Z({ value: t, onChange: a, disabled: r }) {
76
76
  disabled: r,
77
77
  onChange: (n) => v({ ...c, oy: E(n.target.value) })
78
78
  }
79
- ))), u === "circle" && /* @__PURE__ */ e.createElement("div", { className: "bse-grid" }, /* @__PURE__ */ e.createElement("label", null, "Diameter ", /* @__PURE__ */ e.createElement(
79
+ ))), m === "circle" && /* @__PURE__ */ e.createElement("div", { className: "bse-grid" }, /* @__PURE__ */ e.createElement("label", null, "Diameter ", /* @__PURE__ */ e.createElement(
80
80
  "input",
81
81
  {
82
82
  type: "number",
@@ -84,12 +84,12 @@ function Z({ value: t, onChange: a, disabled: r }) {
84
84
  value: x,
85
85
  disabled: r,
86
86
  "data-testid": "bed-dia",
87
- onChange: (n) => _(E(n.target.value))
87
+ onChange: (n) => N(E(n.target.value))
88
88
  }
89
- ), " mm")), u === "custom" && /* @__PURE__ */ e.createElement(
89
+ ), " mm")), m === "custom" && /* @__PURE__ */ e.createElement(
90
90
  "textarea",
91
91
  {
92
- className: "bse-json" + (k ? " err" : ""),
92
+ className: "bse-json" + (_ ? " err" : ""),
93
93
  rows: 3,
94
94
  value: l,
95
95
  disabled: r,
@@ -118,35 +118,39 @@ function le(t) {
118
118
  function ie({ mode: t }) {
119
119
  return /* @__PURE__ */ e.createElement("span", { className: `badge mode-${t ?? "none"}` }, t ?? "—");
120
120
  }
121
- function ce({ def: t, optKey: a, settings: r, setSettings: o, disabled: i, customWidgets: u }) {
122
- const d = I(r, a), c = (l) => o((b) => ({ ...b, [a]: l })), p = u?.[a] ?? K[a];
121
+ function ce({ def: t, optKey: a, settings: r, setSettings: o, disabled: i, customWidgets: m }) {
122
+ const d = I(r, a), c = (l) => o((u) => ({ ...u, [a]: l })), p = m?.[a] ?? K[a];
123
123
  if (p) return /* @__PURE__ */ e.createElement(p, { def: t, value: d, onChange: c, disabled: i });
124
- const x = le(t), g = Array.isArray(d) ? d[0] : d;
124
+ const x = le(t), b = Array.isArray(d) ? d[0] : d;
125
125
  switch (x) {
126
126
  case "select":
127
- return /* @__PURE__ */ e.createElement("select", { value: g ?? "", onChange: (l) => c(l.target.value), disabled: i }, t.enum_values.map((l, b) => /* @__PURE__ */ e.createElement("option", { key: l, value: l }, t.enum_labels?.[b] ?? l)));
127
+ return /* @__PURE__ */ e.createElement("select", { value: b ?? "", onChange: (l) => c(l.target.value), disabled: i }, t.enum_values.map((l, u) => /* @__PURE__ */ e.createElement("option", { key: l, value: l }, t.enum_labels?.[u] ?? l)));
128
128
  case "checkbox":
129
129
  return /* @__PURE__ */ e.createElement("input", { type: "checkbox", checked: Array.isArray(d) ? !!d[0] : !!d, onChange: (l) => c(l.target.checked), disabled: i });
130
130
  case "color":
131
- return /* @__PURE__ */ e.createElement("input", { type: "color", value: typeof g == "string" && g.startsWith("#") ? g : H, onChange: (l) => c(l.target.value), disabled: i });
132
- case "textarea":
133
- return /* @__PURE__ */ e.createElement("textarea", { rows: 2, value: Array.isArray(d) ? d.join(`
134
- `) : d ?? "", onChange: (l) => c(l.target.value), disabled: i });
131
+ return /* @__PURE__ */ e.createElement("input", { type: "color", value: typeof b == "string" && b.startsWith("#") ? b : H, onChange: (l) => c(l.target.value), disabled: i });
132
+ case "textarea": {
133
+ let l = 2;
134
+ t.full_width && (l = 12);
135
+ let u = d ?? "";
136
+ return Array.isArray(d) && (u = d.join(`
137
+ `)), /* @__PURE__ */ e.createElement("textarea", { rows: l, value: u, onChange: (_) => c(_.target.value), disabled: i });
138
+ }
135
139
  case "points":
136
140
  return /* @__PURE__ */ e.createElement("code", { className: "pts" }, JSON.stringify(d ?? []));
137
141
  case "unknown":
138
142
  return /* @__PURE__ */ e.createElement("span", { className: "muted" }, "No schema");
139
143
  default:
140
- return /* @__PURE__ */ e.createElement("span", { className: "inputwrap" }, /* @__PURE__ */ e.createElement("input", { value: g ?? "", onChange: (l) => c(l.target.value), disabled: i }), t.sidetext && /* @__PURE__ */ e.createElement("span", { className: "unit" }, t.sidetext));
144
+ return /* @__PURE__ */ e.createElement("span", { className: "inputwrap" }, /* @__PURE__ */ e.createElement("input", { value: b ?? "", onChange: (l) => c(l.target.value), disabled: i }), t.sidetext && /* @__PURE__ */ e.createElement("span", { className: "unit" }, t.sidetext));
141
145
  }
142
146
  }
143
- function de({ schema: t, optKey: a, settings: r, setSettings: o, disabled: i, onOptionOpen: u, customWidgets: d, overridden: c, onRevertKey: p }) {
147
+ function de({ schema: t, optKey: a, settings: r, setSettings: o, disabled: i, onOptionOpen: m, customWidgets: d, overridden: c, onRevertKey: p }) {
144
148
  if (a.startsWith("<")) return /* @__PURE__ */ e.createElement("div", { className: "row custom" }, /* @__PURE__ */ e.createElement("span", { className: "muted" }, "⚙ Custom widget ", a));
145
- const x = t[a], g = i ? i[a] : void 0, l = g != null, b = oe(t, r, a), k = () => o((v) => {
146
- const _ = { ...v };
147
- return delete _[a], _;
149
+ const x = t[a], b = i ? i[a] : void 0, l = b != null, u = oe(t, r, a), _ = () => o((v) => {
150
+ const N = { ...v };
151
+ return delete N[a], N;
148
152
  }), w = x?.label || x?.full_label || a;
149
- return /* @__PURE__ */ e.createElement("div", { className: "row" + (l ? " disabled" : ""), title: l ? `Disabled when: ${g}` : x?.tooltip ?? "", "data-testid": `row-${a}` }, /* @__PURE__ */ e.createElement("span", { className: "lbl-cell" }, c && /* @__PURE__ */ e.createElement(
153
+ return /* @__PURE__ */ e.createElement("div", { className: "row" + (l ? " disabled" : ""), title: l ? `Disabled when: ${b}` : x?.tooltip ?? "", "data-testid": `row-${a}` }, /* @__PURE__ */ e.createElement("span", { className: "lbl-cell" }, c && /* @__PURE__ */ e.createElement(
150
154
  "button",
151
155
  {
152
156
  type: "button",
@@ -155,7 +159,7 @@ function de({ schema: t, optKey: a, settings: r, setSettings: o, disabled: i, on
155
159
  title: "This plate's override — click to follow the global value again",
156
160
  "data-testid": `override-${a}`
157
161
  }
158
- ), b && /* @__PURE__ */ e.createElement("span", { className: "dirty-dot", title: "Changed from default", "data-testid": `dirty-${a}` }), u ? /* @__PURE__ */ e.createElement("button", { type: "button", className: "lbl lbl-link", onClick: () => u(a), title: "Details" }, w) : /* @__PURE__ */ e.createElement("span", { className: "lbl" }, w)), /* @__PURE__ */ e.createElement("code", { className: "key" }, a), /* @__PURE__ */ e.createElement(ie, { mode: x?.mode }), /* @__PURE__ */ e.createElement("span", { className: "widget-cell" }, /* @__PURE__ */ e.createElement(ce, { def: x, optKey: a, settings: r, setSettings: o, disabled: l, customWidgets: d }), b && /* @__PURE__ */ e.createElement("button", { className: "reset-btn", onClick: k, title: "Reset to default", "data-testid": `reset-${a}` }, "↺")));
162
+ ), u && /* @__PURE__ */ e.createElement("span", { className: "dirty-dot", title: "Changed from default", "data-testid": `dirty-${a}` }), m ? /* @__PURE__ */ e.createElement("button", { type: "button", className: "lbl lbl-link", onClick: () => m(a), title: "Details" }, w) : /* @__PURE__ */ e.createElement("span", { className: "lbl" }, w)), /* @__PURE__ */ e.createElement("code", { className: "key" }, a), /* @__PURE__ */ e.createElement(ie, { mode: x?.mode }), /* @__PURE__ */ e.createElement("span", { className: "widget-cell" }, /* @__PURE__ */ e.createElement(ce, { def: x, optKey: a, settings: r, setSettings: o, disabled: l, customWidgets: d }), u && /* @__PURE__ */ e.createElement("button", { className: "reset-btn", onClick: _, title: "Reset to default", "data-testid": `reset-${a}` }, "↺")));
159
163
  }
160
164
  function fe({
161
165
  schema: t = R,
@@ -163,14 +167,14 @@ function fe({
163
167
  toggle: r = re,
164
168
  settings: o,
165
169
  setSettings: i,
166
- onOptionOpen: u,
170
+ onOptionOpen: m,
167
171
  embedded: d = !1,
168
172
  customWidgets: c,
169
173
  only: p,
170
174
  overriddenKeys: x,
171
- onRevertKey: g
175
+ onRevertKey: b
172
176
  }) {
173
- const l = j(() => ne(a), [a]), [b, k] = y(p?.builder ?? l[0] ?? ""), [w, v] = y(0), [_, z] = y("all"), [E, n] = y(""), m = W(o), f = l.filter((s) => te(s) === m), S = p?.builder ?? (f.includes(b) ? b : f[0] ?? ""), M = a[p?.builder ?? S] ?? [], A = p?.page ? M.filter((s) => s.page === p.page) : M, O = A[Math.min(w, A.length - 1)], J = j(() => r.disabledKeys(r.makeCfg(o)), [o, r]), N = E.trim().toLowerCase(), C = j(() => N ? Object.entries(t).filter(([s, h]) => s.includes(N) || h.label?.toLowerCase().includes(N) || h.full_label?.toLowerCase().includes(N)).slice(0, 60).map(([s]) => s) : [], [N]), D = (s, h) => /* @__PURE__ */ e.createElement(
177
+ const l = j(() => ne(a), [a]), [u, _] = y(p?.builder ?? l[0] ?? ""), [w, v] = y(0), [N, z] = y("all"), [E, n] = y(""), g = W(o), f = l.filter((s) => te(s) === g), S = p?.builder ?? (f.includes(u) ? u : f[0] ?? ""), M = a[p?.builder ?? S] ?? [], A = p?.page ? M.filter((s) => s.page === p.page) : M, O = A[Math.min(w, A.length - 1)], J = j(() => r.disabledKeys(r.makeCfg(o)), [o, r]), k = E.trim().toLowerCase(), C = j(() => k ? Object.entries(t).filter(([s, h]) => s.includes(k) || h.label?.toLowerCase().includes(k) || h.full_label?.toLowerCase().includes(k)).slice(0, 60).map(([s]) => s) : [], [k]), D = (s, h) => /* @__PURE__ */ e.createElement(
174
178
  de,
175
179
  {
176
180
  schema: t,
@@ -179,16 +183,16 @@ function fe({
179
183
  settings: o,
180
184
  setSettings: i,
181
185
  disabled: J,
182
- onOptionOpen: u,
186
+ onOptionOpen: m,
183
187
  customWidgets: c,
184
188
  overridden: x?.includes(s),
185
- onRevertKey: g
189
+ onRevertKey: b
186
190
  }
187
191
  );
188
- return /* @__PURE__ */ e.createElement(X, { css: Q + Y, className: d ? "sp-embedded" : void 0 }, /* @__PURE__ */ e.createElement("div", { className: "settings-panel" }, !p && /* @__PURE__ */ e.createElement("div", { className: "sp-top" }, /* @__PURE__ */ e.createElement("input", { className: "sp-search", placeholder: `Search options (${Object.keys(t).length})…`, value: E, onChange: (s) => n(s.target.value), "data-testid": "opt-search" }), !N && /* @__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: S, onChange: (s) => {
189
- k(s.target.value), v(0);
190
- } }, f.map((s) => /* @__PURE__ */ e.createElement("option", { key: s, value: s }, B(s))))), /* @__PURE__ */ e.createElement("div", { className: "sp-pages" }, A.map((s, h) => /* @__PURE__ */ e.createElement("button", { key: s.page + h, className: h === Math.min(w, A.length - 1) ? "on" : "", onClick: () => v(h) }, s.page))), /* @__PURE__ */ e.createElement("div", { className: "sp-modes" }, ee.map((s) => /* @__PURE__ */ e.createElement("button", { key: s, className: _ === s ? "on" : "", onClick: () => z(s) }, s))))), /* @__PURE__ */ e.createElement("div", { className: "sp-body" }, N ? /* @__PURE__ */ e.createElement("section", { "data-testid": "search-results" }, /* @__PURE__ */ e.createElement("h3", null, "Search: “", E, "” — ", C.length, " hit", C.length === 1 ? "" : "s", C.length === 60 ? "+" : ""), C.map(D), !C.length && /* @__PURE__ */ e.createElement("p", { className: "muted" }, "No matches")) : O ? /* @__PURE__ */ e.createElement(e.Fragment, null, !p && /* @__PURE__ */ e.createElement("h2", null, O.page, " ", /* @__PURE__ */ e.createElement("span", { className: "muted" }, "Tab.cpp:", O.line)), O.groups.map((s) => {
191
- const h = s.options.filter((F) => se(t, F, _) && !(p && F.startsWith("<")));
192
+ return /* @__PURE__ */ e.createElement(X, { css: Q + Y, className: d ? "sp-embedded" : void 0 }, /* @__PURE__ */ e.createElement("div", { className: "settings-panel" }, !p && /* @__PURE__ */ e.createElement("div", { className: "sp-top" }, /* @__PURE__ */ e.createElement("input", { className: "sp-search", placeholder: `Search options (${Object.keys(t).length})…`, value: E, onChange: (s) => n(s.target.value), "data-testid": "opt-search" }), !k && /* @__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: S, onChange: (s) => {
193
+ _(s.target.value), v(0);
194
+ } }, f.map((s) => /* @__PURE__ */ e.createElement("option", { key: s, value: s }, B(s))))), /* @__PURE__ */ e.createElement("div", { className: "sp-pages" }, A.map((s, h) => /* @__PURE__ */ e.createElement("button", { key: s.page + h, className: h === Math.min(w, A.length - 1) ? "on" : "", onClick: () => v(h) }, s.page))), /* @__PURE__ */ e.createElement("div", { className: "sp-modes" }, ee.map((s) => /* @__PURE__ */ e.createElement("button", { key: s, className: N === s ? "on" : "", onClick: () => z(s) }, s))))), /* @__PURE__ */ e.createElement("div", { className: "sp-body" }, k ? /* @__PURE__ */ e.createElement("section", { "data-testid": "search-results" }, /* @__PURE__ */ e.createElement("h3", null, "Search: “", E, "” — ", C.length, " hit", C.length === 1 ? "" : "s", C.length === 60 ? "+" : ""), C.map(D), !C.length && /* @__PURE__ */ e.createElement("p", { className: "muted" }, "No matches")) : O ? /* @__PURE__ */ e.createElement(e.Fragment, null, !p && /* @__PURE__ */ e.createElement("h2", null, O.page, " ", /* @__PURE__ */ e.createElement("span", { className: "muted" }, "Tab.cpp:", O.line)), O.groups.map((s) => {
195
+ const h = s.options.filter((F) => se(t, F, N) && !(p && F.startsWith("<")));
192
196
  return h.length ? /* @__PURE__ */ e.createElement("section", { key: s.group + s.line }, /* @__PURE__ */ e.createElement("h3", null, s.group || "(untitled group)", " ", /* @__PURE__ */ e.createElement("span", { className: "muted" }, ":", s.line)), h.map(D)) : null;
193
197
  })) : /* @__PURE__ */ e.createElement("p", { className: "muted" }, "No builder"))));
194
198
  }
@@ -1,32 +1,60 @@
1
- import { D as Lt, a as Nt } from "./viewer_defaults-B7UUZ582.js";
2
- import { R as t, e as Z } from "./toolpath_encoding-BuYs95qZ.js";
3
- import { T as ft } from "./toolpath_palette-B8xEl-qa.js";
4
- const F = 1e-6, Rt = 254, It = /^(filament|extruder)_colour\s*=\s*(.*)$/i, ut = (i) => i.split(/[;,]/).map((r) => {
5
- const s = /^"?#?([0-9a-f]{6})(?:[0-9a-f]{2})?"?$/i.exec(r.trim());
6
- return s ? "#" + s[1].toUpperCase() : null;
7
- }), At = (i) => "#" + ft[i % ft.length].map((r) => Math.round(r * 255).toString(16).padStart(2, "0")).join("");
8
- function gt(i, r) {
9
- let s = [];
10
- Array.isArray(i?.colors) && (s = i.colors);
11
- const g = r ?? [], u = Math.max(s.length, g.length, i?.filament_mm_by_tool?.length ?? 0);
12
- return Array.from({ length: u }, (m, c) => s[c] || g[c] || At(c));
1
+ import { D as At, a as St } from "./viewer_defaults-B7UUZ582.js";
2
+ import { R as t, S as ut, e as $ } from "./toolpath_encoding-BuYs95qZ.js";
3
+ import { T as mt } from "./toolpath_palette-B8xEl-qa.js";
4
+ const ht = ";_GP_FIRST_LINE_M73_PLACEHOLDER", gt = ";_GP_LAST_LINE_M73_PLACEHOLDER", Lt = "@PRINT_TIME_SEC@", pt = "@USED_FILAMENT_LENGTH@", Nt = (s) => Math.floor((Math.max(0, s) + 0.5) / 60), Z = (s, i) => `M73 P${s} R${i}`;
5
+ function Ct(s, i) {
6
+ let n = String(s ?? "");
7
+ const m = Number(i?.time_estimate) || 0;
8
+ if (n.includes(Lt) && (n = n.split(Lt).join(m.toFixed(2))), n.includes(pt) && (n = n.split(pt).join(((Number(i?.filament_mm) || 0) / 1e3).toFixed(2))), !n.includes(ht)) return n;
9
+ let a = [];
10
+ Array.isArray(i?.layer_times) && (a = i.layer_times);
11
+ const l = n.split(`
12
+ `), o = [];
13
+ let L = 0, E = 0, d = "";
14
+ for (const N of l) {
15
+ if (N === ht) {
16
+ d = Z(0, Nt(m)), o.push(d);
17
+ continue;
18
+ }
19
+ if (N === gt) {
20
+ o.push(Z(100, 0));
21
+ continue;
22
+ }
23
+ if (o.push(N), !N.startsWith("; LAYER ")) continue;
24
+ let A = 0;
25
+ m > 0 && (A = Math.min(100, Math.floor(100 * E / m)));
26
+ const S = Z(A, Nt(m - E));
27
+ S !== d && (o.push(S), d = S), E += Number(a[L]) || 0, L += 1;
28
+ }
29
+ return o.join(`
30
+ `);
13
31
  }
14
- function wt(i, r) {
15
- return dt(i.gcode, gt(i.stats, r));
32
+ const B = 1e-6, Mt = 254, Tt = /^(filament|extruder)_colour\s*=\s*(.*)$/i, It = (s) => s.split(/[;,]/).map((i) => {
33
+ const n = /^"?#?([0-9a-f]{6})(?:[0-9a-f]{2})?"?$/i.exec(i.trim());
34
+ return n ? "#" + n[1].toUpperCase() : null;
35
+ }), Pt = (s) => "#" + mt[s % mt.length].map((i) => Math.round(i * 255).toString(16).padStart(2, "0")).join("");
36
+ function Ot(s, i) {
37
+ let n = [];
38
+ Array.isArray(s?.colors) && (n = s.colors);
39
+ const m = i ?? [], a = Math.max(n.length, m.length, s?.filament_mm_by_tool?.length ?? 0);
40
+ return Array.from({ length: a }, (l, o) => n[o] || m[o] || Pt(o));
16
41
  }
17
- function dt(i, r) {
18
- const s = String(i ?? ""), g = [r].flat().filter(Boolean);
19
- if (!g.length || /^;\s*filament_colour\s*=/mi.test(s)) return s;
20
- const u = "; filament_colour = " + g.join(";") + `
21
- `, m = s.lastIndexOf(`
42
+ function Ut(s, i) {
43
+ return yt(s.gcode, Ot(s.stats, i));
44
+ }
45
+ function yt(s, i) {
46
+ const n = String(s ?? ""), m = [i].flat().filter(Boolean);
47
+ if (!m.length || /^;\s*filament_colour\s*=/mi.test(n)) return n;
48
+ const a = "; filament_colour = " + m.join(";") + `
49
+ `, l = n.lastIndexOf(`
22
50
  ; CONFIG_BLOCK_END`);
23
- if (m >= 0) return s.slice(0, m + 1) + u + s.slice(m + 1);
24
- let c = `
51
+ if (l >= 0) return n.slice(0, l + 1) + a + n.slice(l + 1);
52
+ let o = `
25
53
  `;
26
- return (!s || s.endsWith(`
27
- `)) && (c = ""), s + c + u;
54
+ return (!n || n.endsWith(`
55
+ `)) && (o = ""), n + o + a;
28
56
  }
29
- const St = {
57
+ const _t = {
30
58
  // OrcaSlicer / PrusaSlicer ;TYPE: names
31
59
  "outer wall": t.WALL,
32
60
  "external perimeter": t.WALL,
@@ -69,7 +97,7 @@ const St = {
69
97
  skin: t.SOLID,
70
98
  "support-interface": t.SUPPORT,
71
99
  "prime-tower": t.PRIME
72
- }, Pt = [
100
+ }, Gt = [
73
101
  ["skirt/brim", t.SKIRT],
74
102
  ["skirt", t.SKIRT],
75
103
  ["walls", t.WALL],
@@ -80,7 +108,7 @@ const St = {
80
108
  ["support", t.SUPPORT],
81
109
  ["prime tower", t.PRIME],
82
110
  ["wipe_tower_real", t.PRIME]
83
- ], Et = (i, r) => i === r || r.length < i.length && " (:/".includes(i[r.length]) && i.startsWith(r), Ot = {
111
+ ], wt = (s, i) => s === i || i.length < s.length && " (:/".includes(s[i.length]) && s.startsWith(i), Wt = {
84
112
  1: t.WALL,
85
113
  2: t.WALL,
86
114
  3: t.WALL,
@@ -99,136 +127,151 @@ const St = {
99
127
  16: t.SUPPORT,
100
128
  17: t.PRIME
101
129
  };
102
- function Gt(i, r = {}) {
103
- const s = Math.PI / 4 * (r.filamentDiameter > 0 ? r.filamentDiameter : Lt) ** 2, g = r.defaultLayerHeight > 0 ? r.defaultLayerHeight : Nt;
104
- let u = 0, m = 0, c = 0, b = 0, _ = !0, W = !0, d = 0, w = t.WALL, y = 0, R = null;
105
- const E = [];
106
- let D = !1, x = !0, K = NaN, q = 0, X = 0, $ = 0;
107
- const v = /* @__PURE__ */ new Set([0]), H = [];
108
- let z = [], k = [], j = !1;
109
- const V = () => {
110
- w = t.WALL, y = 0;
111
- }, U = (o, a = !1) => {
112
- R = { z: o, p: [], w: [] }, E.push(R), x = !1, K = NaN, (a || !j) && V();
113
- }, mt = () => E.length > 1 ? E[E.length - 2].z : 0, J = (o, a, S, P, A, n, e) => {
114
- const p = Math.hypot(P - o, A - a, n - S);
115
- if (!(p < F))
116
- if (e > F) {
117
- $ += e, H[d] = (H[d] ?? 0) + e, x ? U(Number.isNaN(K) ? n : K) : !D && n > R.z + 1e-3 && U(n);
118
- const h = Z(w, d);
119
- R.p.push(o, a, S, h, P, A, n, h);
120
- const f = Math.max(0.02, R.z - mt() || g), L = y > 0 ? y : e * s / (p * f) + f * (1 - Math.PI / 4);
121
- R.w.push(Math.min(3, Math.max(0.05, L))), q++;
122
- } else R && (R.p.push(o, a, S, Z(t.TRAVEL, d), P, A, n, Z(t.TRAVEL, d)), R.w.push(0), X++);
130
+ function Ht(s, { center: i = { x: 0, y: 0 }, filamentDiameter: n, layerHeight: m } = {}) {
131
+ const a = bt(s, { filamentDiameter: n, defaultLayerHeight: m });
132
+ for (const l of a.layers) {
133
+ const o = l.paths;
134
+ for (let L = 0; L + ut <= o.length; L += ut)
135
+ o[L] -= i.x, o[L + 1] -= i.y, o[L + 4] -= i.x, o[L + 5] -= i.y;
136
+ }
137
+ return a;
138
+ }
139
+ function bt(s, i = {}) {
140
+ const n = Math.PI / 4 * (i.filamentDiameter > 0 ? i.filamentDiameter : At) ** 2, m = i.defaultLayerHeight > 0 ? i.defaultLayerHeight : St;
141
+ let a = 0, l = 0, o = 0, L = 0, E = !0, d = !0, N = 0, A = t.WALL, S = 0, g = null;
142
+ const y = [];
143
+ let x = !1, D = !0, v = NaN, q = 0, X = 0, V = 0;
144
+ const K = /* @__PURE__ */ new Set([0]), z = [];
145
+ let j = [], k = [], F = !1;
146
+ const J = () => {
147
+ A = t.WALL, S = 0;
148
+ }, C = (c, f = !1) => {
149
+ g = { z: c, p: [], w: [] }, y.push(g), D = !1, v = NaN, (f || !F) && J();
150
+ }, Rt = () => y.length > 1 ? y[y.length - 2].z : 0, Q = (c, f, P, O, T, r, e) => {
151
+ const p = Math.hypot(O - c, T - f, r - P);
152
+ if (!(p < B))
153
+ if (e > B) {
154
+ V += e, z[N] = (z[N] ?? 0) + e, D ? C(Number.isNaN(v) ? r : v) : !x && r > g.z + 1e-3 && C(r);
155
+ const I = $(A, N);
156
+ g.p.push(c, f, P, I, O, T, r, I);
157
+ const h = Math.max(0.02, g.z - Rt() || m), _ = S > 0 ? S : e * n / (p * h) + h * (1 - Math.PI / 4);
158
+ g.w.push(Math.min(3, Math.max(0.05, _))), q++;
159
+ } else g && (g.p.push(c, f, P, $(t.TRAVEL, N), O, T, r, $(t.TRAVEL, N)), g.w.push(0), X++);
123
160
  };
124
- for (const o of i.split(`
161
+ for (const c of s.split(`
125
162
  `)) {
126
- const a = o.indexOf(";"), S = (a < 0 ? o : o.slice(0, a)).trim(), P = a < 0 ? "" : o.slice(a + 1).trim();
127
- if (P && !S) {
128
- const e = P.toLowerCase(), p = It.exec(P);
163
+ const f = c.indexOf(";"), P = (f < 0 ? c : c.slice(0, f)).trim(), O = f < 0 ? "" : c.slice(f + 1).trim();
164
+ if (O && !P) {
165
+ const e = O.toLowerCase(), p = Tt.exec(O);
129
166
  if (p) {
130
- p[1].toLowerCase() === "filament" ? z = ut(p[2]) : k = ut(p[2]);
167
+ p[1].toLowerCase() === "filament" ? j = It(p[2]) : k = It(p[2]);
131
168
  continue;
132
169
  }
133
170
  if (e.startsWith("type:")) {
134
- w = St[e.slice(5).trim()] ?? t.WALL, j = !0;
171
+ A = _t[e.slice(5).trim()] ?? t.WALL, F = !0;
172
+ continue;
173
+ }
174
+ if (e.startsWith("feature:")) {
175
+ A = _t[e.slice(8).trim()] ?? t.WALL, F = !0;
135
176
  continue;
136
177
  }
137
178
  if (e.startsWith("_extrusion_role:")) {
138
- w = Ot[parseInt(e.slice(16), 10)] ?? t.WALL, j = !0;
179
+ A = Wt[parseInt(e.slice(16), 10)] ?? t.WALL, F = !0;
139
180
  continue;
140
181
  }
141
- if (e.startsWith("width:")) {
142
- const L = parseFloat(e.slice(6));
143
- y = L > 0 ? L : 0;
182
+ if (e.startsWith("width:") || e.startsWith("line_width:")) {
183
+ const _ = parseFloat(e.slice(e.indexOf(":") + 1));
184
+ S = 0, _ > 0 && (S = _);
144
185
  continue;
145
186
  }
146
- if (e.startsWith("layer_change") || e.startsWith("layer:")) {
147
- D = !0, x = !0, V();
187
+ if (e.startsWith("layer_change") || e.startsWith("change_layer") || e.startsWith("layer:")) {
188
+ x = !0, D = !0, J();
148
189
  continue;
149
190
  }
150
- if (e.startsWith("z:")) {
151
- const L = parseFloat(e.slice(2));
152
- x && L > 0 && (D = !0, U(L));
191
+ if (e.startsWith("z:") || e.startsWith("z_height:")) {
192
+ const _ = parseFloat(e.slice(e.indexOf(":") + 1));
193
+ D && _ > 0 && (x = !0, C(_));
153
194
  continue;
154
195
  }
155
- const h = /^layer \d+ z([-\d.]+)/.exec(e);
156
- if (h) {
157
- D = !0, U(parseFloat(h[1]), !0);
196
+ const I = /^layer \d+ z([-\d.]+)/.exec(e);
197
+ if (I) {
198
+ x = !0, C(parseFloat(I[1]), !0);
158
199
  continue;
159
200
  }
160
- const f = Pt.find(([L]) => Et(e, L));
161
- f && (w = f[1]);
201
+ const h = Gt.find(([_]) => wt(e, _));
202
+ h && (A = h[1]);
162
203
  continue;
163
204
  }
164
- if (!S) continue;
165
- const A = S.split(/\s+/), n = A[0].toUpperCase();
166
- if (n === "G90") {
167
- _ = !0;
205
+ if (!P) continue;
206
+ const T = P.split(/\s+/), r = T[0].toUpperCase();
207
+ if (r === "G90") {
208
+ E = !0;
168
209
  continue;
169
210
  }
170
- if (n === "G91") {
171
- _ = !1;
211
+ if (r === "G91") {
212
+ E = !1;
172
213
  continue;
173
214
  }
174
- if (n === "M82") {
175
- W = !0;
215
+ if (r === "M82") {
216
+ d = !0;
176
217
  continue;
177
218
  }
178
- if (n === "M83") {
179
- W = !1;
219
+ if (r === "M83") {
220
+ d = !1;
180
221
  continue;
181
222
  }
182
- if (/^T\d+$/.test(n)) {
183
- const e = parseInt(n.slice(1), 10);
184
- e <= Rt && (d = e, v.add(d));
223
+ if (/^T\d+$/.test(r)) {
224
+ const e = parseInt(r.slice(1), 10);
225
+ e <= Mt && (N = e, K.add(N));
185
226
  continue;
186
227
  }
187
- if (n === "G92" || n === "G0" || n === "G1" || n === "G2" || n === "G3") {
188
- let e = NaN, p = NaN, h = NaN, f = NaN, L = 0, tt = 0;
189
- for (let I = 1; I < A.length; I++) {
190
- const l = A[I][0], N = parseFloat(A[I].slice(1));
191
- Number.isNaN(N) || (l === "X" || l === "x" ? e = N : l === "Y" || l === "y" ? p = N : l === "Z" || l === "z" ? h = N : l === "E" || l === "e" ? f = N : l === "I" || l === "i" ? L = N : (l === "J" || l === "j") && (tt = N));
228
+ if (r === "G92" || r === "G0" || r === "G1" || r === "G2" || r === "G3") {
229
+ let e = NaN, p = NaN, I = NaN, h = NaN, _ = 0, et = 0;
230
+ for (let M = 1; M < T.length; M++) {
231
+ const u = T[M][0], R = parseFloat(T[M].slice(1));
232
+ Number.isNaN(R) || (u === "X" || u === "x" ? e = R : u === "Y" || u === "y" ? p = R : u === "Z" || u === "z" ? I = R : u === "E" || u === "e" ? h = R : u === "I" || u === "i" ? _ = R : (u === "J" || u === "j") && (et = R));
192
233
  }
193
- if (n === "G92") {
194
- Number.isNaN(e) || (u = e), Number.isNaN(p) || (m = p), Number.isNaN(h) || (c = h), Number.isNaN(f) || (b = f);
234
+ if (r === "G92") {
235
+ Number.isNaN(e) || (a = e), Number.isNaN(p) || (l = p), Number.isNaN(I) || (o = I), Number.isNaN(h) || (L = h);
195
236
  continue;
196
237
  }
197
- const C = Number.isNaN(e) ? u : _ ? e : u + e, B = Number.isNaN(p) ? m : _ ? p : m + p, Y = Number.isNaN(h) ? c : _ ? h : c + h, et = Number.isNaN(f) ? 0 : W ? f - b : f;
198
- if (n === "G2" || n === "G3") {
199
- const I = u + L, l = m + tt, N = Math.hypot(u - I, m - l), G = Math.atan2(m - l, u - I);
200
- let O = Math.atan2(B - l, C - I);
201
- const nt = n === "G3";
202
- nt && O <= G + F && (O += 2 * Math.PI), !nt && O >= G - F && (O -= 2 * Math.PI);
203
- const M = Math.max(1, Math.min(360, Math.ceil(Math.abs(O - G) * N / 0.3)));
204
- let it = u, rt = m, ot = c;
205
- for (let T = 1; T <= M; T++) {
206
- const st = G + (O - G) * T / M, at = T === M ? C : I + N * Math.cos(st), lt = T === M ? B : l + N * Math.sin(st), ct = c + (Y - c) * T / M;
207
- J(it, rt, ot, at, lt, ct, et / M), it = at, rt = lt, ot = ct;
238
+ const U = Number.isNaN(e) ? a : E ? e : a + e, H = Number.isNaN(p) ? l : E ? p : l + p, Y = Number.isNaN(I) ? o : E ? I : o + I, it = Number.isNaN(h) ? 0 : d ? h - L : h;
239
+ if (r === "G2" || r === "G3") {
240
+ const M = a + _, u = l + et, R = Math.hypot(a - M, l - u), b = Math.atan2(l - u, a - M);
241
+ let G = Math.atan2(H - u, U - M);
242
+ const nt = r === "G3";
243
+ nt && G <= b + B && (G += 2 * Math.PI), !nt && G >= b - B && (G -= 2 * Math.PI);
244
+ const w = Math.max(1, Math.min(360, Math.ceil(Math.abs(G - b) * R / 0.3)));
245
+ let st = a, ot = l, rt = o;
246
+ for (let W = 1; W <= w; W++) {
247
+ const at = b + (G - b) * W / w, lt = W === w ? U : M + R * Math.cos(at), ct = W === w ? H : u + R * Math.sin(at), ft = o + (Y - o) * W / w;
248
+ Q(st, ot, rt, lt, ct, ft, it / w), st = lt, ot = ct, rt = ft;
208
249
  }
209
250
  } else
210
- J(u, m, c, C, B, Y, et);
211
- u = C, m = B, c = Y, Number.isNaN(f) || (b = W ? f : b + f);
251
+ Q(a, l, o, U, H, Y, it);
252
+ a = U, l = H, o = Y, Number.isNaN(h) || (L = d ? h : L + h);
212
253
  }
213
254
  }
214
- const pt = Math.max(z.length, k.length), Q = Array.from({ length: pt }, (o, a) => k[a] || z[a] || null), ht = Array.from({ length: Math.max(...v) + 1 }, (o, a) => H[a] || 0);
255
+ const Et = Math.max(j.length, k.length), tt = Array.from({ length: Et }, (c, f) => k[f] || j[f] || null), dt = Array.from({ length: Math.max(...K) + 1 }, (c, f) => z[f] || 0);
215
256
  return {
216
- layers: E.map((o) => ({ z: o.z, paths: Float32Array.from(o.p), widths: Float32Array.from(o.w) })),
257
+ layers: y.map((c) => ({ z: c.z, paths: Float32Array.from(c.p), widths: Float32Array.from(c.w) })),
217
258
  stats: {
218
- layers: E.length,
259
+ layers: y.length,
219
260
  path_segments: q,
220
261
  travel_segments: X,
221
- filament_mm: $,
222
- tools: [...v].sort((o, a) => o - a),
262
+ filament_mm: V,
263
+ tools: [...K].sort((c, f) => c - f),
223
264
  // The kernel's own stat name, so the Filament-view switch and the stats card's per-tool split work unchanged.
224
- filament_mm_by_tool: ht,
225
- ...Q.some(Boolean) && { colors: Q }
265
+ filament_mm_by_tool: dt,
266
+ ...tt.some(Boolean) && { colors: tt }
226
267
  }
227
268
  };
228
269
  }
229
270
  export {
230
- wt as exportedGcode,
231
- Gt as parseGcode,
232
- gt as resultToolColors,
233
- dt as withFilamentColours
271
+ Ut as exportedGcode,
272
+ Ct as finalizeGcode,
273
+ bt as parseGcode,
274
+ Ht as previewFromGcode,
275
+ Ot as resultToolColors,
276
+ yt as withFilamentColours
234
277
  };