printbench 0.8.3 → 0.8.6

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.
@@ -0,0 +1,312 @@
1
+ import { Vector3 as z, Matrix3 as j, LoadingManager as S, Color as I } from "three";
2
+ import { DRACOLoader as X } from "three/examples/jsm/loaders/DRACOLoader.js";
3
+ import { GLTFLoader as R } from "three/examples/jsm/loaders/GLTFLoader.js";
4
+ import { MeshoptDecoder as Z } from "three/examples/jsm/libs/meshopt_decoder.module.js";
5
+ import { STLLoader as G } from "three/examples/jsm/loaders/STLLoader.js";
6
+ import { OBJLoader as J } from "three/examples/jsm/loaders/OBJLoader.js";
7
+ import { ThreeMFLoader as P } from "three/examples/jsm/loaders/3MFLoader.js";
8
+ import Y from "jszip";
9
+ import { w as O, u as _ } from "./index-DV7N04zK.js";
10
+ import { A as be } from "./index-DV7N04zK.js";
11
+ import { parse3mfMeshObjects as k } from "./3mf-BrPsk9Z0.js";
12
+ const q = new URL("../assets/draco_wasm_wrapper.js", import.meta.url).href, V = new URL("../assets/draco_decoder.wasm", import.meta.url).href;
13
+ let D = null;
14
+ function H(e) {
15
+ return e.split("?")[0]?.split("/").pop() ?? e;
16
+ }
17
+ function K() {
18
+ const e = new S();
19
+ e.setURLModifier((a) => {
20
+ const m = H(a);
21
+ return m === "draco_wasm_wrapper.js" ? q : m === "draco_decoder.wasm" ? V : a;
22
+ });
23
+ const r = new X(e);
24
+ return r.setDecoderConfig({ type: "wasm" }), r.setDecoderPath(""), r;
25
+ }
26
+ function Q() {
27
+ const e = new R();
28
+ return D || (D = K()), e.setDRACOLoader(D), e.setMeshoptDecoder(Z), e;
29
+ }
30
+ function ee(e) {
31
+ return e ? Array.isArray(e) ? e : [e] : [];
32
+ }
33
+ function U(e) {
34
+ const r = "color" in e ? e.color : void 0;
35
+ return r && r instanceof I ? [r.r, r.g, r.b] : [1, 1, 1];
36
+ }
37
+ function te(e) {
38
+ return ("map" in e ? e.map : void 0) ?? void 0;
39
+ }
40
+ function E(e) {
41
+ if (!("metalness" in e)) return;
42
+ const r = e.metalness;
43
+ return typeof r == "number" ? r : void 0;
44
+ }
45
+ function N(e) {
46
+ if (!("roughness" in e)) return;
47
+ const r = e.roughness;
48
+ return typeof r == "number" ? r : void 0;
49
+ }
50
+ function T(e) {
51
+ return e[0] > 0.97 && e[1] > 0.97 && e[2] > 0.97;
52
+ }
53
+ function ne(e) {
54
+ if (!e?.image) return;
55
+ const r = e.image, a = Number(r.width), m = Number(r.height);
56
+ if (!(!a || !m))
57
+ try {
58
+ const n = document.createElement("canvas");
59
+ n.width = a, n.height = m;
60
+ const o = n.getContext("2d");
61
+ return o ? (o.drawImage(e.image, 0, 0, a, m), { canvas: n, flipY: e.flipY }) : void 0;
62
+ } catch {
63
+ return;
64
+ }
65
+ }
66
+ function re(e, r, a, m) {
67
+ const n = (r % 1 + 1) % 1, o = (a % 1 + 1) % 1, f = m ? 1 - o : o, h = Math.min(e.width - 1, Math.max(0, Math.floor(n * e.width))), c = (Math.min(e.height - 1, Math.max(0, Math.floor(f * e.height))) * e.width + h) * 4;
68
+ return [e.data[c] / 255, e.data[c + 1] / 255, e.data[c + 2] / 255];
69
+ }
70
+ function oe(e, r, a, m, n, o) {
71
+ const f = new Float32Array(e * 3);
72
+ f.fill(1);
73
+ const h = o.map((c) => {
74
+ if (!c) return;
75
+ const l = c.canvas.getContext("2d");
76
+ if (l)
77
+ return { data: l.getImageData(0, 0, c.canvas.width, c.canvas.height), flipY: c.flipY };
78
+ }), s = (c) => {
79
+ for (const l of m)
80
+ if (c >= l.start && c < l.start + l.count) return l.materialIndex ?? 0;
81
+ return 0;
82
+ };
83
+ for (let c = 0; c < r.length; c += 3) {
84
+ const l = n.length ? Math.max(0, Math.min(n.length - 1, s(c))) : 0, i = h[l], p = n[l] ? U(n[l]) : [1, 1, 1];
85
+ for (let u = 0; u < 3; u++) {
86
+ const d = r[c + u];
87
+ let g = p[0], M = p[1], y = p[2];
88
+ if (i && a && d * 2 + 1 < a.length) {
89
+ const b = re(i.data, a[d * 2], a[d * 2 + 1], i.flipY);
90
+ g *= b[0], M *= b[1], y *= b[2];
91
+ }
92
+ f[d * 3] = g, f[d * 3 + 1] = M, f[d * 3 + 2] = y;
93
+ }
94
+ }
95
+ return f;
96
+ }
97
+ function B(e, r, a, m) {
98
+ const n = e.getAttribute("position");
99
+ if (!n) throw new Error("网格缺少 position 属性");
100
+ const o = e.getIndex(), f = new Float32Array(n.count * 3), h = new z();
101
+ for (let t = 0; t < n.count; t++)
102
+ h.set(n.getX(t), n.getY(t), n.getZ(t)), a && h.applyMatrix4(a), f[t * 3] = h.x, f[t * 3 + 1] = h.y, f[t * 3 + 2] = h.z;
103
+ let s;
104
+ if (o) {
105
+ s = new Uint32Array(o.count);
106
+ for (let t = 0; t < o.count; t++) s[t] = o.getX(t);
107
+ } else {
108
+ s = new Uint32Array(n.count);
109
+ for (let t = 0; t < n.count; t++) s[t] = t;
110
+ }
111
+ const c = e.getAttribute("color");
112
+ let l;
113
+ if (c) {
114
+ l = new Float32Array(n.count * 3);
115
+ for (let t = 0; t < n.count; t++)
116
+ l[t * 3] = c.getX(t), l[t * 3 + 1] = c.getY(t), l[t * 3 + 2] = c.getZ(t);
117
+ }
118
+ const i = e.getAttribute("uv");
119
+ let p;
120
+ if (i) {
121
+ p = new Float32Array(n.count * 2);
122
+ for (let t = 0; t < n.count; t++)
123
+ p[t * 2] = i.getX(t), p[t * 2 + 1] = i.getY(t);
124
+ }
125
+ const u = e.getAttribute("normal");
126
+ let d;
127
+ if (u) {
128
+ d = new Float32Array(n.count * 3);
129
+ const t = a ? new j().getNormalMatrix(a) : null, A = new z();
130
+ for (let w = 0; w < n.count; w++)
131
+ A.set(u.getX(w), u.getY(w), u.getZ(w)), t ? A.applyMatrix3(t).normalize() : A.normalize(), d[w * 3] = A.x, d[w * 3 + 1] = A.y, d[w * 3 + 2] = A.z;
132
+ }
133
+ const g = ee(m), M = g.map((t) => ne(te(t)));
134
+ let y, b, C, x, L;
135
+ if (g.length <= 1) {
136
+ if (y = M[0]?.canvas, b = M[0]?.flipY, g[0]) {
137
+ const t = U(g[0]);
138
+ (!T(t) || y) && (C = t), x = E(g[0]), L = N(g[0]);
139
+ }
140
+ } else {
141
+ const t = M.map((w) => w?.canvas).filter((w) => !!w);
142
+ if (new Set(t).size === 1 && t.length === g.length) {
143
+ y = t[0], b = M.find(($) => $)?.flipY;
144
+ const w = U(g[0]);
145
+ (!T(w) || y) && (C = w), x = E(g[0]), L = N(g[0]);
146
+ } else
147
+ l = oe(n.count, s, p, e.groups, g, M);
148
+ }
149
+ const v = O(f, s, 1e-5, l, p, d), W = (() => {
150
+ const t = {};
151
+ if (v.uvs && (t.uvs = v.uvs), v.colors && (t.colors = v.colors), v.normals && (t.normals = v.normals), C && (t.baseColor = C), y && (t.texture = y, t.flipY = b), x != null && (t.metalness = x), L != null && (t.roughness = L), !(!t.texture && !t.colors && !t.baseColor && !t.normals))
152
+ return t;
153
+ })();
154
+ return {
155
+ id: _("mesh"),
156
+ name: r,
157
+ visible: !0,
158
+ buffers: { positions: v.positions, indices: v.indices, colors: v.colors },
159
+ appearance: W
160
+ };
161
+ }
162
+ function se(e, r, a, m) {
163
+ const n = O(r, a, 1e-5);
164
+ return {
165
+ id: _("mesh"),
166
+ name: e,
167
+ visible: !0,
168
+ printColor: m ? [m[0], m[1], m[2]] : void 0,
169
+ buffers: { positions: n.positions, indices: n.indices, colors: n.colors }
170
+ };
171
+ }
172
+ function F(e, r) {
173
+ const a = [];
174
+ let m = 0, n = !1;
175
+ return e.updateMatrixWorld(!0), e.traverse((o) => {
176
+ let f = 0, h = o;
177
+ for (; h; )
178
+ f++, h = h.parent;
179
+ if (m = Math.max(m, f), o.isMesh) {
180
+ const s = o;
181
+ (Array.isArray(s.geometry) ? s.geometry : [s.geometry]).forEach((l, i) => {
182
+ if (!l) return;
183
+ const u = (typeof s.name == "string" ? s.name.trim() : "") || `${r}_${a.length || i}`;
184
+ a.push(B(l, u, s.matrixWorld, s.material));
185
+ }), s.material && (n = !0);
186
+ }
187
+ }), { meshes: a, depth: m, hasMat: n };
188
+ }
189
+ async function ae(e) {
190
+ const r = e.name.split(".").pop()?.toLowerCase() ?? "", a = await e.arrayBuffer();
191
+ if (r === "zip") return ie(e, a);
192
+ if (r === "glb" || r === "gltf") {
193
+ const n = await Q().parseAsync(a, ""), { meshes: o, depth: f, hasMat: h } = F(n.scene, e.name.replace(/\.[^.]+$/, ""));
194
+ if (!o.length) throw new Error("该文件不包含网格,可能是纯灯光/相机场景");
195
+ const s = o.reduce((l, i) => l + i.buffers.indices.length / 3, 0), c = o.reduce((l, i) => l + i.buffers.positions.length / 3, 0);
196
+ return {
197
+ meshes: o,
198
+ summary: {
199
+ fileName: e.name,
200
+ format: r,
201
+ triangleCount: s,
202
+ vertexCount: c,
203
+ nodeDepth: f,
204
+ hasMaterials: h,
205
+ hasAnimations: (n.animations?.length ?? 0) > 0
206
+ }
207
+ };
208
+ }
209
+ if (r === "stl") {
210
+ const n = new G().parse(a), o = B(n, e.name.replace(/\.[^.]+$/, ""));
211
+ return {
212
+ meshes: [o],
213
+ summary: {
214
+ fileName: e.name,
215
+ format: "stl",
216
+ triangleCount: o.buffers.indices.length / 3,
217
+ vertexCount: o.buffers.positions.length / 3,
218
+ nodeDepth: 1,
219
+ hasMaterials: !1,
220
+ hasAnimations: !1
221
+ }
222
+ };
223
+ }
224
+ if (r === "obj") {
225
+ const m = new TextDecoder().decode(a), o = new J().parse(m), { meshes: f, depth: h, hasMat: s } = F(o, e.name.replace(/\.[^.]+$/, ""));
226
+ if (!f.length) throw new Error("OBJ 中没有可用网格");
227
+ const c = f.reduce((i, p) => i + p.buffers.indices.length / 3, 0), l = f.reduce((i, p) => i + p.buffers.positions.length / 3, 0);
228
+ return {
229
+ meshes: f,
230
+ summary: {
231
+ fileName: e.name,
232
+ format: "obj",
233
+ triangleCount: c,
234
+ vertexCount: l,
235
+ nodeDepth: h,
236
+ hasMaterials: s,
237
+ hasAnimations: !1
238
+ }
239
+ };
240
+ }
241
+ if (r === "3mf") {
242
+ const m = await ce(a), o = (await Y.loadAsync(a)).file(/3dmodel\.model$/i)[0], f = o ? await o.async("string") : "", h = f ? k(f) : [];
243
+ let s = [], c = 1, l = !1;
244
+ try {
245
+ const d = new P().parse(a), g = F(d, e.name.replace(/\.[^.]+$/, ""));
246
+ s = g.meshes, c = g.depth, l = g.hasMat;
247
+ } catch {
248
+ s = [];
249
+ }
250
+ if (h.length > s.length ? (s = h.map((u) => se(u.name, u.positions, u.indices, u.printColor)), l = !1, c = 1) : h.length && h.forEach((u, d) => {
251
+ s[d] && (u.name?.trim() && (s[d].name = u.name.trim()), u.printColor && (s[d].printColor = [u.printColor[0], u.printColor[1], u.printColor[2]]));
252
+ }), !s.length) throw new Error("3MF 中没有可用网格");
253
+ const i = s.reduce((u, d) => u + d.buffers.indices.length / 3, 0), p = s.reduce((u, d) => u + d.buffers.positions.length / 3, 0);
254
+ return {
255
+ meshes: s,
256
+ declaredUnit: m,
257
+ summary: {
258
+ fileName: e.name,
259
+ format: "3mf",
260
+ triangleCount: i,
261
+ vertexCount: p,
262
+ nodeDepth: c,
263
+ hasMaterials: l,
264
+ hasAnimations: !1,
265
+ declaredUnit: m
266
+ }
267
+ };
268
+ }
269
+ throw new Error("仅支持 GLB / GLTF / STL / OBJ / 3MF / ZIP");
270
+ }
271
+ async function ie(e, r) {
272
+ const a = await Y.loadAsync(r), m = Object.values(a.files).filter(
273
+ (i) => !i.dir && !i.name.startsWith("__MACOSX") && !/(^|\/)\./.test(i.name) && /\.(glb|gltf|stl|obj|3mf)$/i.test(i.name)
274
+ ).sort((i, p) => i.name.localeCompare(p.name, "en"));
275
+ if (!m.length) throw new Error("压缩包中没有 STL / 3MF / OBJ / GLB 模型");
276
+ const n = [];
277
+ let o = !1, f = !1, h = 1, s;
278
+ for (const i of m) {
279
+ const p = await i.async("arraybuffer"), u = i.name.split(/[/\\]/).pop() || i.name, d = await ae(new File([p], u));
280
+ n.push(...d.meshes), o = o || d.summary.hasMaterials, f = f || d.summary.hasAnimations, h = Math.max(h, d.summary.nodeDepth), d.declaredUnit && !s && (s = d.declaredUnit);
281
+ }
282
+ if (!n.length) throw new Error("压缩包中没有可用网格");
283
+ const c = n.reduce((i, p) => i + p.buffers.indices.length / 3, 0), l = n.reduce((i, p) => i + p.buffers.positions.length / 3, 0);
284
+ return {
285
+ meshes: n,
286
+ declaredUnit: s,
287
+ summary: {
288
+ fileName: e.name,
289
+ format: "zip",
290
+ triangleCount: c,
291
+ vertexCount: l,
292
+ nodeDepth: h,
293
+ hasMaterials: o,
294
+ hasAnimations: f,
295
+ declaredUnit: s
296
+ }
297
+ };
298
+ }
299
+ async function ce(e) {
300
+ try {
301
+ const a = (await Y.loadAsync(e)).file(/3dmodel\.model$/i)[0];
302
+ if (!a) return "mm";
303
+ const o = ((await a.async("string")).match(/unit\s*=\s*"([^"]+)"/i)?.[1] ?? "millimeter").toLowerCase();
304
+ return o.startsWith("micro") ? "mm" : o.startsWith("centi") ? "cm" : o.startsWith("meter") && !o.includes("milli") ? "m" : "mm";
305
+ } catch {
306
+ return "mm";
307
+ }
308
+ }
309
+ export {
310
+ be as ACCEPT_EXT,
311
+ ae as loadModelFile
312
+ };
@@ -1,5 +1,5 @@
1
1
  import { GLTFLoader as w } from "three/examples/jsm/loaders/GLTFLoader.js";
2
- import { w as y } from "./index-taUrTXAq.js";
2
+ import { w as y } from "./index-DV7N04zK.js";
3
3
  const A = new URL("../assets/qiu_ao.glb", import.meta.url).href, x = new URL("../assets/qiu_tu_di.glb", import.meta.url).href;
4
4
  let l = null, i = null;
5
5
  function L(n) {
@@ -1,7 +1,7 @@
1
1
  import p from "jszip";
2
2
  import { Group as u, Mesh as l } from "three";
3
3
  import { STLExporter as w } from "three/examples/jsm/exporters/STLExporter.js";
4
- import { b as m } from "./index-taUrTXAq.js";
4
+ import { b as m } from "./index-DV7N04zK.js";
5
5
  function y(t, o) {
6
6
  const e = /* @__PURE__ */ new Set();
7
7
  return t.map((n, a) => {
@@ -1 +1 @@
1
- .pb-select{position:relative;display:block;min-width:0;width:100%}.pb-select-trigger{display:flex;align-items:center;gap:6px;width:100%;min-width:0;margin:0;padding:5px 8px;background:var(--panel-2);color:var(--text);border:1px solid var(--border);border-radius:6px;font:inherit;font-size:12px;line-height:1.3;text-align:left;cursor:pointer;color-scheme:dark}.pb-select-trigger:hover:not(:disabled){border-color:var(--accent)}.pb-select-trigger:disabled{opacity:.45;cursor:not-allowed}.pb-select-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pb-select-chevron{flex:none;width:12px;height:12px;opacity:.75}.pb-select.open .pb-select-chevron{transform:rotate(180deg)}.pb-select-menu{position:fixed;z-index:9999;margin:0;padding:4px;list-style:none;overflow:auto;background:var(--panel-2);color:var(--text);border:1px solid var(--border);border-radius:8px;box-shadow:var(--shadow);color-scheme:dark;font-family:Segoe UI,PingFang SC,Microsoft YaHei,sans-serif;font-size:12px}.pb-select-option{padding:6px 8px;border-radius:5px;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pb-select-option:hover,.pb-select-option.active{background:#5b8def2e}.pb-select-option.selected{color:var(--accent)}.unit-row>span[data-v-a695849a]{flex:none;white-space:nowrap}.unit-row[data-v-a695849a] .pb-select{flex:1;min-width:0}.settings-host[data-v-41705d65] .dialog{width:min(420px,calc(100% - 24px),92vw)}.row[data-v-41705d65]{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:8px 0;font-size:13px}.row .label[data-v-41705d65]{flex:1;min-width:0;color:var(--text)}.row[data-v-41705d65] .pb-select,.row>input[type=number][data-v-41705d65]{flex:0 0 auto;width:140px;max-width:46%}.row>input[type=number][data-v-41705d65]{background:var(--panel-2);border:1px solid var(--border);border-radius:6px;padding:5px 8px;color:var(--text);color-scheme:dark}.section[data-v-41705d65]{margin:12px 0;padding-top:10px;border-top:1px solid var(--border)}.section-title[data-v-41705d65]{font-size:12px;font-weight:600;color:var(--muted, #9aa3b2);margin-bottom:8px}.section-title .unit[data-v-41705d65]{font-weight:400;opacity:.85}.checks[data-v-41705d65]{display:grid;grid-template-columns:1fr 1fr;gap:8px 12px;margin-bottom:8px;font-size:13px}.checks label[data-v-41705d65]{display:flex;align-items:center;gap:6px;min-width:0}.bed-xyz[data-v-41705d65]{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}.axis[data-v-41705d65]{display:flex;flex-direction:column;gap:4px;min-width:0;font-size:11px;color:var(--muted, #9aa3b2)}.axis input[data-v-41705d65]{width:100%;box-sizing:border-box;background:var(--panel-2);border:1px solid var(--border);border-radius:6px;padding:5px 6px;color:var(--text);color-scheme:dark}.bed-presets[data-v-41705d65]{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}.preset[data-v-41705d65]{font-size:12px;padding:4px 8px;white-space:nowrap}.anno{display:flex;flex-direction:column;gap:8px}.anno-toolbar{display:flex;align-items:center;gap:8px}.anno-count{font-size:12px;color:var(--muted)}.anno-hint{margin:0;font-size:12px;color:var(--muted);line-height:1.5}.anno-item{border-left:3px solid var(--border);padding:8px 10px;background:var(--panel-2);border-radius:0 6px 6px 0;cursor:pointer}.anno-item.red{border-color:var(--danger)}.anno-item.yellow{border-color:var(--warn)}.anno-item.green{border-color:var(--ok)}.anno-item.info{border-color:var(--accent)}.anno-item.active{outline:1px solid var(--accent)}.anno-item-hd{display:flex;align-items:center;gap:6px;font-size:13px}.anno-item-hd b{font-weight:600;color:var(--muted)}.anno-dot{width:8px;height:8px;flex:none;border-radius:50%;background:var(--accent)}.anno-item.red .anno-dot{background:var(--danger)}.anno-item.yellow .anno-dot{background:var(--warn)}.anno-item.green .anno-dot{background:var(--ok)}.anno-title{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.anno-badge{flex:none;font-size:10px;padding:1px 5px;border-radius:4px;border:1px solid var(--border);color:var(--muted)}.anno-badge.ok{color:var(--ok);border-color:var(--ok)}.anno-badge.warn{color:var(--warn);border-color:var(--warn)}.anno-body{margin:4px 0 0;font-size:12px;color:var(--text);line-height:1.45;white-space:pre-wrap;word-break:break-word}.anno-meta{margin:4px 0 0;font-size:11px;color:var(--muted)}.anno-editor{display:flex;flex-direction:column;gap:6px;padding:8px;border:1px solid var(--border);border-radius:6px;background:var(--panel-2)}.anno-editor label{display:flex;flex-direction:column;gap:3px;font-size:11px;color:var(--muted)}.anno-editor input,.anno-editor textarea,.anno-editor select{width:100%;box-sizing:border-box;padding:5px 7px;font:inherit;font-size:12px;color:var(--text);background:var(--panel);border:1px solid var(--border);border-radius:5px;color-scheme:dark;resize:vertical}.anno-editor-actions{display:flex;gap:6px;flex-wrap:wrap}.diag-tabs{display:flex;gap:4px;margin-bottom:8px}.diag-tab{flex:1;padding:5px 8px;font:inherit;font-size:12px;color:var(--muted);background:var(--panel-2);border:1px solid var(--border);border-radius:6px;cursor:pointer}.diag-tab:hover{border-color:var(--accent)}.diag-tab.active{color:var(--text);border-color:var(--accent);background:color-mix(in srgb,var(--accent) 18%,var(--panel-2))}.diag-tab-count{margin-left:4px;font-size:10px;padding:0 4px;border-radius:8px;background:var(--accent);color:#0d1117}.warn[data-v-2a2da3f5]{color:#e07040;font-weight:600}.selection[data-v-2a2da3f5]{color:var(--text, #e8e8e8);font-weight:500}:root{--bg: #0e1116;--panel: #171b22;--panel-2: #1e242e;--border: #2c3440;--text: #e8edf4;--muted: #8b95a5;--accent: #5b8def;--danger: #ff5c5c;--warn: #f0b429;--ok: #3dcc7a;--shadow: 0 8px 32px rgba(0, 0, 0, .35);font-family:Segoe UI,PingFang SC,Microsoft YaHei,sans-serif}.printbench-root,.printbench-root *{box-sizing:border-box}.printbench-root{height:100%;min-height:0;background:var(--bg);color:var(--text);color-scheme:dark;font-family:Segoe UI,PingFang SC,Microsoft YaHei,sans-serif}.printbench-root button,.printbench-root input,.printbench-root textarea{font:inherit;color:inherit;color-scheme:dark}.workbench{position:relative;display:grid;grid-template-rows:1fr 28px;grid-template-columns:292px 1fr;height:100%}.workbench.no-left{grid-template-columns:36px 1fr}.workbench.left-float{grid-template-columns:1fr}.workbench.left-float>.panel.parts{position:absolute;left:12px;top:12px;width:280px;max-height:calc(100% - 52px);z-index:12;grid-column:1;grid-row:1;border:1px solid var(--border);border-radius:10px;box-shadow:var(--shadow);background:color-mix(in srgb,var(--panel) 94%,transparent);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.workbench.left-float>.panel.parts.collapsed{width:36px;max-height:none;bottom:40px}.workbench.left-float>.canvas-wrap{grid-column:1;grid-row:1;min-width:0}.workbench.preview-shell{grid-template-rows:1fr;grid-template-columns:1fr}.item input.swatch{flex:none;width:22px;height:18px;padding:0;border:1px solid var(--border);border-radius:4px;background:transparent;cursor:pointer}.statusbar{grid-column:1 / -1}.panel{background:var(--panel);border-right:1px solid var(--border);display:flex;flex-direction:column;min-height:0}.workbench>.panel.right{position:absolute;right:12px;top:12px;width:280px;max-height:calc(100% - 52px);z-index:var(--printbench-diagnosis-z, 100);border:1px solid var(--border);border-radius:10px;box-shadow:var(--shadow);background:color-mix(in srgb,var(--panel) 94%,transparent);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border-right:1px solid var(--border);border-left:1px solid var(--border)}.workbench>.panel.right.collapsed{width:36px;max-height:none}.panel-hd{display:flex;align-items:center;gap:6px;padding:10px 12px;font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);border-bottom:1px solid var(--border)}.panel-hd .ttl{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.panel-toggle{flex:none;width:24px;height:24px;padding:0;background:var(--panel-2);border:1px solid var(--border);border-radius:4px;color:var(--text);cursor:pointer;line-height:1;font-size:16px;display:inline-flex;align-items:center;justify-content:center}.panel-toggle:hover{border-color:var(--accent);color:var(--accent)}.panel-toggle .ico{width:14px;height:14px;display:block}.panel.collapsed .panel-hd{flex-direction:column;height:100%;padding:8px 4px;border-bottom:none;justify-content:flex-start}.panel.collapsed .panel-toggle{order:-1}.panel.collapsed .ttl{writing-mode:vertical-rl;flex:none;letter-spacing:.2em}.panel-bd{padding:10px;overflow:auto;flex:1;display:flex;flex-direction:column;gap:8px}.btn{background:var(--panel-2);border:1px solid var(--border);border-radius:6px;padding:5px 10px;cursor:pointer}.btn:hover{border-color:var(--accent)}.btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}.btn.danger{border-color:var(--danger);color:var(--danger)}.btn:disabled{opacity:.45;cursor:not-allowed}.canvas-wrap{position:relative;min-width:0;min-height:0;background:#12151c}.canvas-wrap canvas{width:100%;height:100%;display:block}.empty{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;pointer-events:none;color:var(--muted);text-align:center}.empty h2{color:var(--text);margin:0 0 8px;font-weight:600}.steps{display:flex;gap:18px;margin-top:16px;font-size:13px}.steps b{color:var(--accent)}.tree{display:flex;flex-direction:column;gap:2px;background:var(--panel-2);border:1px solid var(--border);border-radius:8px;padding:4px;min-height:120px;overflow-y:auto}.tree-empty{margin:0;padding:14px 8px;text-align:center;font-size:12px;color:var(--muted)}.item{position:relative;display:flex;align-items:center;gap:8px;padding:7px 8px;border-radius:6px;cursor:pointer}.item:hover{background:#5b8def14}.item.active{background:#263044}.item .idx{flex:none;width:18px;font-size:11px;color:var(--muted);text-align:right}.item .grow{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px}.item .rename-btn{position:absolute;right:6px;top:50%;transform:translateY(-50%);width:auto;padding:2px 6px;font-size:11px;line-height:1.3;color:var(--text);opacity:0;pointer-events:none}.item:hover .rename-btn,.item:focus-within .rename-btn{opacity:1;pointer-events:auto}.item:hover .grow,.item:focus-within .grow{padding-right:40px}.item input[type=checkbox]{accent-color:var(--accent);margin:0}.hint{margin:0;font-size:11px;line-height:1.45;color:var(--muted)}.sec{margin:4px 0 0;padding:10px 0 2px;border-top:1px solid var(--border);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}.btn-grid{display:grid;grid-template-columns:1fr 1fr;gap:6px}.btn-grid .btn,.btn-row .btn{width:100%;font-size:12px;padding:6px 8px}.btn-grid.core-actions.compact,.btn-grid.tool-mode.compact{gap:4px}.btn-grid.core-actions.icon-text{grid-template-columns:1fr 1fr}.btn-grid.core-actions.icons-only{grid-template-columns:repeat(5,1fr)}.btn-grid.tool-mode{grid-template-columns:repeat(3,1fr)}.btn-grid.core-actions .btn.icon-btn,.btn-grid.tool-mode .btn.icon-btn{display:inline-flex;align-items:center;justify-content:center;gap:4px;padding:4px 6px;font-size:11px;min-height:28px}.btn-grid.core-actions.icons-only .btn.icon-btn,.btn-grid.tool-mode.icons-only .btn.icon-btn{padding:4px}.btn-grid.core-actions .btn.icon-btn .ico,.btn-grid.tool-mode .btn.icon-btn .ico{width:14px;height:14px;flex:none;display:block}.btn-grid.core-actions .btn.icon-btn span,.btn-grid.tool-mode .btn.icon-btn span{line-height:1.2;white-space:nowrap}.btn-grid .pb-select{width:100%;min-width:0}.btn-row{display:flex;gap:6px}.split-list{display:flex;flex-direction:column;gap:6px}.split-list .btn-row .btn:first-child{flex:1;width:auto}.split-list .btn-row .btn.danger{flex:none;width:auto}.xyz{display:grid;grid-template-columns:48px 1fr 1fr 1fr;gap:4px;align-items:center;font-size:12px}.xyz>span{color:var(--muted)}.xyz input,.xyz .pb-select .pb-select-trigger{width:100%;min-width:0;background:var(--panel-2);border:1px solid var(--border);border-radius:4px;padding:4px 5px;color:var(--text);color-scheme:dark}.xyz input{text-align:center}.xyz .pb-select{grid-column:2 / -1;width:100%;min-width:0}.scale-row{display:flex;align-items:center;gap:6px;font-size:12px}.scale-row>span{color:var(--muted);flex:none}.scale-row input,.scale-row .pb-select .pb-select-trigger{min-width:0;background:var(--panel-2);border:1px solid var(--border);border-radius:4px;padding:4px 5px;color:var(--text);color-scheme:dark}.scale-row input{width:4.5rem;flex:none;text-align:center}.scale-row .pb-select{flex:1;min-width:0}.xyz-hd{display:grid;grid-template-columns:48px 1fr 1fr 1fr;gap:4px;font-size:10px;color:var(--muted);text-align:center;margin-bottom:-2px}.stack{display:flex;flex-direction:column;gap:6px}.stack .pb-select,.stack input[type=number]{width:100%;min-width:0}.stack input[type=number]{background:var(--panel-2);border:1px solid var(--border);border-radius:6px;padding:5px 8px}.check{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--muted)}.diag{border-left:3px solid var(--border);padding:8px 10px;margin-bottom:8px;background:var(--panel-2);border-radius:0 6px 6px 0;cursor:pointer}.diag.red{border-color:var(--danger)}.diag.yellow{border-color:var(--warn)}.diag.green{border-color:var(--ok)}.diag h4{margin:0 0 4px;font-size:13px}.diag p{margin:0;font-size:12px;color:var(--muted)}.statusbar{display:flex;align-items:center;gap:16px;padding:0 12px;font-size:12px;color:var(--muted);background:var(--panel);border-top:1px solid var(--border)}.overlay{position:absolute;inset:0;background:#0000008c;display:flex;align-items:center;justify-content:center;z-index:40}.workbench>.overlay{grid-column:1 / -1;grid-row:1 / -1}.dialog{width:min(480px,calc(100% - 24px),92vw);max-width:100%;background:var(--panel);border:1px solid var(--border);border-radius:10px;box-shadow:var(--shadow);padding:18px}.dialog h3{margin:0 0 10px}.dialog .row{margin:10px 0;display:flex;gap:8px;align-items:center}.dialog .pb-select{min-width:0}.dialog .actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px;margin-top:16px}.dialog .actions>.btn{flex:0 0 auto;white-space:nowrap}.dialog.help{width:min(640px,94vw);max-height:min(82vh,720px);overflow:auto}.dialog.help p{font-size:13px;line-height:1.55}.dialog .url-input{width:100%;background:var(--panel-2);border:1px solid var(--border);border-radius:6px;padding:8px 10px}.dialog .snapshot-preview{display:block;width:100%;max-height:min(52vh,420px);object-fit:contain;background:#12151c;border:1px solid var(--border);border-radius:8px}.toasts{position:fixed;top:16px;left:50%;transform:translate(-50%);display:flex;flex-direction:column;align-items:center;gap:8px;z-index:50;pointer-events:none}.toast{pointer-events:auto;padding:10px 14px;border-radius:8px;background:#1e242e;border:1px solid var(--border);color:var(--text);box-shadow:var(--shadow)}.toast.ok{background:#15261c;border-color:var(--ok)}.toast.fail{background:#2a1518;border-color:var(--danger)}.toast.info{background:#1e242e}.busy{position:absolute;inset:0;background:#0e11168c;display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:30;cursor:wait;-webkit-user-select:none;user-select:none}.bar{width:180px;height:4px;background:#2a303c;border-radius:4px;overflow:hidden}.bar i{display:block;height:100%;width:40%;background:var(--accent);animation:slide 1s infinite}@keyframes slide{0%{transform:translate(-100%)}to{transform:translate(280%)}}.field{display:flex;align-items:center;gap:8px;margin:6px 0;font-size:13px}.field input,.field .pb-select{background:var(--panel-2);border:1px solid var(--border);border-radius:4px;padding:4px 6px;width:90px}.field .pb-select{padding:0;background:transparent;border:none}.field .pb-select .pb-select-trigger{padding:4px 6px;border-radius:4px}.tour{position:absolute;left:50%;top:72px;transform:translate(-50%);background:var(--panel);border:1px solid var(--accent);border-radius:10px;padding:14px 16px;z-index:8;width:360px}.preview-lighting{position:absolute;top:10px;left:10px;z-index:6;display:flex;align-items:center;gap:6px;padding:6px 8px;border-radius:8px;background:color-mix(in srgb,var(--panel) 92%,transparent);border:1px solid var(--border);box-shadow:var(--shadow);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);font-size:12px;color:var(--text);pointer-events:auto}.preview-lighting label{display:flex;align-items:center;gap:6px;margin:0;white-space:nowrap}.preview-lighting .pb-select{max-width:9.5em}.preview-lighting .pb-select .pb-select-trigger{padding:4px 8px}.preview-tag{position:absolute;top:10px;left:10px;background:#1d3a24;color:#9dffb0;padding:4px 8px;border-radius:4px;font-size:12px}.preview-tag.below-lighting{top:52px}.marquee{position:absolute;border:1px dashed var(--accent);background:#5b8def1f;pointer-events:none}.ctx{position:fixed;z-index:60;background:var(--panel);border:1px solid var(--border);border-radius:6px;min-width:140px;padding:4px}.ctx button{display:block;width:100%;text-align:left;background:none;border:none;padding:6px 8px;cursor:pointer}.ctx button:hover{background:var(--panel-2)}.clip-slider{position:absolute;top:12px;left:50%;transform:translate(-50%);background:#141820e0;padding:8px 12px;border-radius:8px;font-size:12px;display:flex;align-items:center;gap:8px;z-index:4}.clip-slider input{width:180px}.diag.active{outline:1px solid var(--accent)}.live-read{position:absolute;left:12px;bottom:12px;background:#141820d9;padding:6px 10px;border-radius:6px;font-size:13px;color:#ffe08a}
1
+ .pb-select{position:relative;display:block;min-width:0;width:100%}.pb-select-trigger{display:flex;align-items:center;gap:6px;width:100%;min-width:0;margin:0;padding:5px 8px;background:var(--panel-2);color:var(--text);border:1px solid var(--border);border-radius:6px;font:inherit;font-size:12px;line-height:1.3;text-align:left;cursor:pointer;color-scheme:dark}.pb-select-trigger:hover:not(:disabled){border-color:var(--accent)}.pb-select-trigger:disabled{opacity:.45;cursor:not-allowed}.pb-select-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pb-select-chevron{flex:none;width:12px;height:12px;opacity:.75}.pb-select.open .pb-select-chevron{transform:rotate(180deg)}.pb-select-menu{position:fixed;z-index:9999;margin:0;padding:4px;list-style:none;overflow:auto;background:var(--panel-2);color:var(--text);border:1px solid var(--border);border-radius:8px;box-shadow:var(--shadow);color-scheme:dark;font-family:Segoe UI,PingFang SC,Microsoft YaHei,sans-serif;font-size:12px}.pb-select-option{padding:6px 8px;border-radius:5px;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pb-select-option:hover,.pb-select-option.active{background:#5b8def2e}.pb-select-option.selected{color:var(--accent)}.unit-row>span[data-v-3db9027c]{flex:none;white-space:nowrap}.unit-row[data-v-3db9027c] .pb-select{flex:1;min-width:0}.settings-host[data-v-c0ccb8a7] .dialog{width:min(420px,calc(100% - 24px),92vw)}.row[data-v-c0ccb8a7]{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:8px 0;font-size:13px}.row .label[data-v-c0ccb8a7]{flex:1;min-width:0;color:var(--text)}.row[data-v-c0ccb8a7] .pb-select,.row>input[type=number][data-v-c0ccb8a7]{flex:0 0 auto;width:140px;max-width:46%}.row>input[type=number][data-v-c0ccb8a7]{background:var(--panel-2);border:1px solid var(--border);border-radius:6px;padding:5px 8px;color:var(--text);color-scheme:dark}.section[data-v-c0ccb8a7]{margin:12px 0;padding-top:10px;border-top:1px solid var(--border)}.section-title[data-v-c0ccb8a7]{font-size:12px;font-weight:600;color:var(--muted, #9aa3b2);margin-bottom:8px}.section-title .unit[data-v-c0ccb8a7]{font-weight:400;opacity:.85}.checks[data-v-c0ccb8a7]{display:grid;grid-template-columns:1fr 1fr;gap:8px 12px;margin-bottom:8px;font-size:13px}.checks label[data-v-c0ccb8a7]{display:flex;align-items:center;gap:6px;min-width:0}.bed-xyz[data-v-c0ccb8a7]{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}.axis[data-v-c0ccb8a7]{display:flex;flex-direction:column;gap:4px;font-size:12px;color:var(--muted)}.axis input[data-v-c0ccb8a7]{width:100%;box-sizing:border-box;padding:6px 8px;border-radius:6px;border:1px solid var(--border);background:var(--panel-2);color:var(--text);color-scheme:dark}.bed-presets[data-v-c0ccb8a7]{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}.preset[data-v-c0ccb8a7]{font-size:12px}.actions[data-v-c0ccb8a7]{display:flex;justify-content:flex-end;margin-top:12px}.anno{display:flex;flex-direction:column;gap:8px}.anno-toolbar{display:flex;align-items:center;gap:8px}.anno-count{font-size:12px;color:var(--muted)}.anno-hint{margin:0;font-size:12px;color:var(--muted);line-height:1.5}.anno-item{border-left:3px solid var(--border);padding:8px 10px;background:var(--panel-2);border-radius:0 6px 6px 0;cursor:pointer}.anno-item.red{border-color:var(--danger)}.anno-item.yellow{border-color:var(--warn)}.anno-item.green{border-color:var(--ok)}.anno-item.info{border-color:var(--accent)}.anno-item.active{outline:1px solid var(--accent)}.anno-item-hd{display:flex;align-items:center;gap:6px;font-size:13px}.anno-item-hd b{font-weight:600;color:var(--muted)}.anno-dot{width:8px;height:8px;flex:none;border-radius:50%;background:var(--accent)}.anno-item.red .anno-dot{background:var(--danger)}.anno-item.yellow .anno-dot{background:var(--warn)}.anno-item.green .anno-dot{background:var(--ok)}.anno-title{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.anno-badge{flex:none;font-size:10px;padding:1px 5px;border-radius:4px;border:1px solid var(--border);color:var(--muted)}.anno-badge.ok{color:var(--ok);border-color:var(--ok)}.anno-badge.warn{color:var(--warn);border-color:var(--warn)}.anno-body{margin:4px 0 0;font-size:12px;color:var(--text);line-height:1.45;white-space:pre-wrap;word-break:break-word}.anno-meta{margin:4px 0 0;font-size:11px;color:var(--muted)}.anno-editor{display:flex;flex-direction:column;gap:6px;padding:8px;border:1px solid var(--border);border-radius:6px;background:var(--panel-2)}.anno-editor label{display:flex;flex-direction:column;gap:3px;font-size:11px;color:var(--muted)}.anno-editor input,.anno-editor textarea,.anno-editor select{width:100%;box-sizing:border-box;padding:5px 7px;font:inherit;font-size:12px;color:var(--text);background:var(--panel);border:1px solid var(--border);border-radius:5px;color-scheme:dark;resize:vertical}.anno-editor-actions{display:flex;gap:6px;flex-wrap:wrap}.diag-tabs{display:flex;gap:4px;margin-bottom:8px}.diag-tab{flex:1;padding:5px 8px;font:inherit;font-size:12px;color:var(--muted);background:var(--panel-2);border:1px solid var(--border);border-radius:6px;cursor:pointer}.diag-tab:hover{border-color:var(--accent)}.diag-tab.active{color:var(--text);border-color:var(--accent);background:color-mix(in srgb,var(--accent) 18%,var(--panel-2))}.diag-tab-count{margin-left:4px;font-size:10px;padding:0 4px;border-radius:8px;background:var(--accent);color:#0d1117}.warn[data-v-2a2da3f5]{color:#e07040;font-weight:600}.selection[data-v-2a2da3f5]{color:var(--text, #e8e8e8);font-weight:500}:root{--bg: #0e1116;--panel: #171b22;--panel-2: #1e242e;--border: #2c3440;--text: #e8edf4;--muted: #8b95a5;--accent: #5b8def;--danger: #ff5c5c;--warn: #f0b429;--ok: #3dcc7a;--shadow: 0 8px 32px rgba(0, 0, 0, .35);font-family:Segoe UI,PingFang SC,Microsoft YaHei,sans-serif}.printbench-root,.printbench-root *{box-sizing:border-box}.printbench-root{height:100%;min-height:0;background:var(--bg);color:var(--text);color-scheme:dark;font-family:Segoe UI,PingFang SC,Microsoft YaHei,sans-serif}.printbench-root button,.printbench-root input,.printbench-root textarea{font:inherit;color:inherit;color-scheme:dark}.workbench{position:relative;display:grid;grid-template-rows:1fr 28px;grid-template-columns:292px 1fr;height:100%}.workbench.no-left{grid-template-columns:36px 1fr}.workbench.left-float{grid-template-columns:1fr}.workbench.left-float>.panel.parts{position:absolute;left:12px;top:12px;width:280px;max-height:calc(100% - 52px);z-index:12;grid-column:1;grid-row:1;border:1px solid var(--border);border-radius:10px;box-shadow:var(--shadow);background:color-mix(in srgb,var(--panel) 94%,transparent);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.workbench.left-float>.panel.parts.collapsed{width:36px;max-height:none;bottom:40px}.workbench.left-float>.canvas-wrap{grid-column:1;grid-row:1;min-width:0}.workbench.preview-shell{grid-template-rows:1fr;grid-template-columns:1fr}.item input.swatch{flex:none;width:22px;height:18px;padding:0;border:1px solid var(--border);border-radius:4px;background:transparent;cursor:pointer}.statusbar{grid-column:1 / -1}.panel{background:var(--panel);border-right:1px solid var(--border);display:flex;flex-direction:column;min-height:0}.workbench>.panel.right{position:absolute;right:12px;top:12px;width:280px;max-height:calc(100% - 52px);z-index:var(--printbench-diagnosis-z, 100);border:1px solid var(--border);border-radius:10px;box-shadow:var(--shadow);background:color-mix(in srgb,var(--panel) 94%,transparent);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border-right:1px solid var(--border);border-left:1px solid var(--border)}.workbench>.panel.right.collapsed{width:36px;max-height:none}.panel-hd{display:flex;align-items:center;gap:6px;padding:10px 12px;font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);border-bottom:1px solid var(--border)}.panel-hd .ttl{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.panel-toggle{flex:none;width:24px;height:24px;padding:0;background:var(--panel-2);border:1px solid var(--border);border-radius:4px;color:var(--text);cursor:pointer;line-height:1;font-size:16px;display:inline-flex;align-items:center;justify-content:center}.panel-toggle:hover{border-color:var(--accent);color:var(--accent)}.panel-toggle .ico{width:14px;height:14px;display:block}.panel.collapsed .panel-hd{flex-direction:column;height:100%;padding:8px 4px;border-bottom:none;justify-content:flex-start}.panel.collapsed .panel-toggle{order:-1}.panel.collapsed .ttl{writing-mode:vertical-rl;flex:none;letter-spacing:.2em}.panel-bd{padding:10px;overflow:auto;flex:1;display:flex;flex-direction:column;gap:8px}.btn{background:var(--panel-2);border:1px solid var(--border);border-radius:6px;padding:5px 10px;cursor:pointer}.btn:hover{border-color:var(--accent)}.btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}.btn.danger{border-color:var(--danger);color:var(--danger)}.btn:disabled{opacity:.45;cursor:not-allowed}.canvas-wrap{position:relative;min-width:0;min-height:0;background:#12151c}.canvas-wrap canvas{width:100%;height:100%;display:block}.empty{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;pointer-events:none;color:var(--muted);text-align:center}.empty h2{color:var(--text);margin:0 0 8px;font-weight:600}.steps{display:flex;gap:18px;margin-top:16px;font-size:13px}.steps b{color:var(--accent)}.tree{display:flex;flex-direction:column;gap:2px;background:var(--panel-2);border:1px solid var(--border);border-radius:8px;padding:4px;min-height:120px;overflow-y:auto}.tree-empty{margin:0;padding:14px 8px;text-align:center;font-size:12px;color:var(--muted)}.item{position:relative;display:flex;align-items:center;gap:8px;padding:7px 8px;border-radius:6px;cursor:pointer}.item:hover{background:#5b8def14}.item.active{background:#263044}.item .idx{flex:none;width:18px;font-size:11px;color:var(--muted);text-align:right}.item .grow{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px}.item .rename-btn{position:absolute;right:6px;top:50%;transform:translateY(-50%);width:auto;padding:2px 6px;font-size:11px;line-height:1.3;color:var(--text);opacity:0;pointer-events:none}.item:hover .rename-btn,.item:focus-within .rename-btn{opacity:1;pointer-events:auto}.item:hover .grow,.item:focus-within .grow{padding-right:40px}.item input[type=checkbox]{accent-color:var(--accent);margin:0}.hint{margin:0;font-size:11px;line-height:1.45;color:var(--muted)}.sec{margin:4px 0 0;padding:10px 0 2px;border-top:1px solid var(--border);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}.btn-grid{display:grid;grid-template-columns:1fr 1fr;gap:6px}.btn-grid .btn,.btn-row .btn{width:100%;font-size:12px;padding:6px 8px}.btn-grid.core-actions.compact,.btn-grid.tool-mode.compact{gap:4px}.btn-grid.core-actions.icon-text{grid-template-columns:1fr 1fr}.btn-grid.core-actions.icons-only{grid-template-columns:repeat(5,1fr)}.btn-grid.tool-mode{grid-template-columns:repeat(3,1fr)}.btn-grid.core-actions .btn.icon-btn,.btn-grid.tool-mode .btn.icon-btn{display:inline-flex;align-items:center;justify-content:center;gap:4px;padding:4px 6px;font-size:11px;min-height:28px}.btn-grid.core-actions.icons-only .btn.icon-btn,.btn-grid.tool-mode.icons-only .btn.icon-btn{padding:4px}.btn-grid.core-actions .btn.icon-btn .ico,.btn-grid.tool-mode .btn.icon-btn .ico{width:14px;height:14px;flex:none;display:block}.btn-grid.core-actions .btn.icon-btn span,.btn-grid.tool-mode .btn.icon-btn span{line-height:1.2;white-space:nowrap}.btn-grid .pb-select{width:100%;min-width:0}.btn-row{display:flex;gap:6px}.split-list{display:flex;flex-direction:column;gap:6px}.split-list .btn-row .btn:first-child{flex:1;width:auto}.split-list .btn-row .btn.danger{flex:none;width:auto}.xyz{display:grid;grid-template-columns:48px 1fr 1fr 1fr;gap:4px;align-items:center;font-size:12px}.xyz>span{color:var(--muted)}.xyz input,.xyz .pb-select .pb-select-trigger{width:100%;min-width:0;background:var(--panel-2);border:1px solid var(--border);border-radius:4px;padding:4px 5px;color:var(--text);color-scheme:dark}.xyz input{text-align:center}.xyz .pb-select{grid-column:2 / -1;width:100%;min-width:0}.scale-row{display:flex;align-items:center;gap:6px;font-size:12px}.scale-row>span{color:var(--muted);flex:none}.scale-row input,.scale-row .pb-select .pb-select-trigger{min-width:0;background:var(--panel-2);border:1px solid var(--border);border-radius:4px;padding:4px 5px;color:var(--text);color-scheme:dark}.scale-row input{width:4.5rem;flex:none;text-align:center}.scale-row .pb-select{flex:1;min-width:0}.xyz-hd{display:grid;grid-template-columns:48px 1fr 1fr 1fr;gap:4px;font-size:10px;color:var(--muted);text-align:center;margin-bottom:-2px}.stack{display:flex;flex-direction:column;gap:6px}.stack .pb-select,.stack input[type=number]{width:100%;min-width:0}.stack input[type=number]{background:var(--panel-2);border:1px solid var(--border);border-radius:6px;padding:5px 8px}.check{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--muted)}.diag{border-left:3px solid var(--border);padding:8px 10px;margin-bottom:8px;background:var(--panel-2);border-radius:0 6px 6px 0;cursor:pointer}.diag.red{border-color:var(--danger)}.diag.yellow{border-color:var(--warn)}.diag.green{border-color:var(--ok)}.diag h4{margin:0 0 4px;font-size:13px}.diag p{margin:0;font-size:12px;color:var(--muted)}.statusbar{display:flex;align-items:center;gap:16px;padding:0 12px;font-size:12px;color:var(--muted);background:var(--panel);border-top:1px solid var(--border)}.overlay{position:absolute;inset:0;background:#0000008c;display:flex;align-items:center;justify-content:center;z-index:40}.workbench>.overlay{grid-column:1 / -1;grid-row:1 / -1}.dialog{width:min(480px,calc(100% - 24px),92vw);max-width:100%;background:var(--panel);border:1px solid var(--border);border-radius:10px;box-shadow:var(--shadow);padding:18px}.dialog h3{margin:0 0 10px}.dialog .row{margin:10px 0;display:flex;gap:8px;align-items:center}.dialog .pb-select{min-width:0}.dialog .actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px;margin-top:16px}.dialog .actions>.btn{flex:0 0 auto;white-space:nowrap}.dialog.help{width:min(640px,94vw);max-height:min(82vh,720px);overflow:auto}.dialog.help p{font-size:13px;line-height:1.55}.dialog .url-input{width:100%;background:var(--panel-2);border:1px solid var(--border);border-radius:6px;padding:8px 10px}.dialog .snapshot-preview{display:block;width:100%;max-height:min(52vh,420px);object-fit:contain;background:#12151c;border:1px solid var(--border);border-radius:8px}.toasts{position:fixed;top:16px;left:50%;transform:translate(-50%);display:flex;flex-direction:column;align-items:center;gap:8px;z-index:50;pointer-events:none}.toast{pointer-events:auto;padding:10px 14px;border-radius:8px;background:#1e242e;border:1px solid var(--border);color:var(--text);box-shadow:var(--shadow)}.toast.ok{background:#15261c;border-color:var(--ok)}.toast.fail{background:#2a1518;border-color:var(--danger)}.toast.info{background:#1e242e}.busy{position:absolute;inset:0;background:#0e11168c;display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:30;cursor:wait;-webkit-user-select:none;user-select:none}.bar{width:180px;height:4px;background:#2a303c;border-radius:4px;overflow:hidden}.bar i{display:block;height:100%;width:40%;background:var(--accent);animation:slide 1s infinite}@keyframes slide{0%{transform:translate(-100%)}to{transform:translate(280%)}}.field{display:flex;align-items:center;gap:8px;margin:6px 0;font-size:13px}.field input,.field .pb-select{background:var(--panel-2);border:1px solid var(--border);border-radius:4px;padding:4px 6px;width:90px}.field .pb-select{padding:0;background:transparent;border:none}.field .pb-select .pb-select-trigger{padding:4px 6px;border-radius:4px}.tour{position:absolute;left:50%;top:72px;transform:translate(-50%);background:var(--panel);border:1px solid var(--accent);border-radius:10px;padding:14px 16px;z-index:8;width:360px}.preview-lighting{position:absolute;top:10px;left:10px;z-index:6;display:flex;align-items:center;gap:6px;padding:6px 8px;border-radius:8px;background:color-mix(in srgb,var(--panel) 92%,transparent);border:1px solid var(--border);box-shadow:var(--shadow);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);font-size:12px;color:var(--text);pointer-events:auto}.preview-lighting label{display:flex;align-items:center;gap:6px;margin:0;white-space:nowrap}.preview-lighting .pb-select{max-width:9.5em}.preview-lighting .pb-select .pb-select-trigger{padding:4px 8px}.preview-tag{position:absolute;top:10px;left:10px;background:#1d3a24;color:#9dffb0;padding:4px 8px;border-radius:4px;font-size:12px}.preview-tag.below-lighting{top:52px}.marquee{position:absolute;border:1px dashed var(--accent);background:#5b8def1f;pointer-events:none}.ctx{position:fixed;z-index:60;background:var(--panel);border:1px solid var(--border);border-radius:6px;min-width:140px;padding:4px}.ctx button{display:block;width:100%;text-align:left;background:none;border:none;padding:6px 8px;cursor:pointer}.ctx button:hover{background:var(--panel-2)}.clip-slider{position:absolute;top:12px;left:50%;transform:translate(-50%);background:#141820e0;padding:8px 12px;border-radius:8px;font-size:12px;display:flex;align-items:center;gap:8px;z-index:4}.clip-slider input{width:180px}.diag.active{outline:1px solid var(--accent)}.live-read{position:absolute;left:12px;bottom:12px;background:#141820d9;padding:6px 10px;border-radius:6px;font-size:13px;color:#ffe08a}
@@ -1,4 +1,4 @@
1
- import { P as o, _ as s, a as t, c as e, _ as r, n as i, d as u } from "./chunks/index-taUrTXAq.js";
1
+ import { P as o, _ as s, a as t, c as e, _ as r, n as i, d as u } from "./chunks/index-DV7N04zK.js";
2
2
  export {
3
3
  o as PRINTBENCH_FULL_FEATURES,
4
4
  s as PrintBench,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "printbench",
3
- "version": "0.8.3",
3
+ "version": "0.8.6",
4
4
  "description": "Browser-based 3D print model workbench (Vue 3 + three.js + Manifold)",
5
5
  "type": "module",
6
6
  "main": "./dist/printbench.js",