@codefrydev/svg-engine 0.1.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.
package/dist/editor.js ADDED
@@ -0,0 +1,3060 @@
1
+ import {
2
+ Renderer,
3
+ getMouseCoords,
4
+ snap
5
+ } from "./chunk-KRCGD3CL.js";
6
+
7
+ // src/editor/Editor.tsx
8
+ import { forwardRef, useEffect as useEffect2, useImperativeHandle, useMemo as useMemo2, useState as useState2 } from "react";
9
+
10
+ // src/editor/hooks/useDrawing.ts
11
+ import { useEffect, useMemo, useRef, useState } from "react";
12
+ var waveOscillationDefaults = (tool) => {
13
+ let defaultColor = "#0f172a";
14
+ if (["spring", "sine_wave", "wavefronts", "shm_graph"].includes(tool)) defaultColor = "#3b82f6";
15
+ if (["standing_wave", "wave_pulse", "torsion_pendulum"].includes(tool)) defaultColor = "#ec4899";
16
+ if (["pendulum", "phasor"].includes(tool)) defaultColor = "#8b5cf6";
17
+ if (["wall", "vane_liquid"].includes(tool)) defaultColor = "#64748b";
18
+ if (tool === "mass_box") defaultColor = "#ef4444";
19
+ const base = { color: defaultColor, strokeWidth: 2, fontSize: 18 };
20
+ switch (tool) {
21
+ case "standing_wave":
22
+ case "sine_wave":
23
+ return { ...base, amplitude: 40, loops: 2 };
24
+ case "damped_wave":
25
+ return { ...base, amplitude: 50, damping: 0.015, frequency: 10 };
26
+ case "shm_graph":
27
+ return { ...base, amplitude: 40, loops: 1, graphType: "all" };
28
+ case "energy_graph":
29
+ return { ...base, amplitude: 50, loops: 1, domain: "time" };
30
+ case "strobe_shm":
31
+ return { ...base, amplitude: 40, loops: 1 };
32
+ case "beats_graph":
33
+ return { ...base, amplitude: 30, frequency: 15, beatFreq: 2 };
34
+ case "wavefronts":
35
+ return { ...base, velocityRatio: 0.5, rings: 5 };
36
+ case "mach_cone":
37
+ return { ...base, machNumber: 2 };
38
+ case "mass_box":
39
+ return { ...base, size: 30 };
40
+ case "pendulum":
41
+ return { ...base, size: 15, showForces: false };
42
+ case "phasor":
43
+ return { ...base, showProjection: false };
44
+ case "spring":
45
+ return { ...base, coils: 8 };
46
+ case "text":
47
+ return { ...base, label: "Equation/Label" };
48
+ default:
49
+ return base;
50
+ }
51
+ };
52
+ var toolCreateDefaults = (tool, presetKey) => {
53
+ if (presetKey === "waveOscillation") return waveOscillationDefaults(tool);
54
+ switch (tool) {
55
+ case "charge_pos":
56
+ return { color: "#ef4444", strokeWidth: 2, fontSize: 18 };
57
+ case "charge_neg":
58
+ return { color: "#3b82f6", strokeWidth: 2, fontSize: 18 };
59
+ case "charge_plus":
60
+ return { color: "#ef4444", strokeWidth: 2, fontSize: 16 };
61
+ case "charge_minus":
62
+ return { color: "#3b82f6", strokeWidth: 2, fontSize: 16 };
63
+ case "dipole":
64
+ return { color: "#64748b", strokeWidth: 2 };
65
+ case "charged_plate_pos":
66
+ return { color: "#ef4444", strokeWidth: 2 };
67
+ case "charged_plate_neg":
68
+ return { color: "#3b82f6", strokeWidth: 2 };
69
+ case "gaussian_sphere":
70
+ return { color: "#10b981", strokeWidth: 2 };
71
+ case "gaussian_cylinder":
72
+ return { color: "#10b981", strokeWidth: 2, curveHeight: 40 };
73
+ case "vector":
74
+ case "ray":
75
+ case "photon":
76
+ if (presetKey === "graph") return { color: "#0f172a", strokeWidth: 2 };
77
+ if (presetKey === "mechanics" || presetKey === "mechanical") return { color: "#0f172a", strokeWidth: 2 };
78
+ if (presetKey === "rotation") return { color: "#ef4444", strokeWidth: 2 };
79
+ if (presetKey === "optical" && (tool === "ray" || tool === "photon")) return { color: "#ef4444", strokeWidth: 2 };
80
+ if (presetKey === "optical") return { color: "#0f172a", strokeWidth: 2 };
81
+ return { color: "#ef4444", strokeWidth: 2 };
82
+ case "lens_convex":
83
+ case "lens_concave":
84
+ case "prism":
85
+ case "glass_slab":
86
+ return { color: "#38bdf8", strokeWidth: 2 };
87
+ case "mirror_plane":
88
+ case "mirror_concave":
89
+ case "mirror_convex":
90
+ return { color: "#0f172a", strokeWidth: 2 };
91
+ case "slit_double":
92
+ case "slit_single":
93
+ return { color: "#0f172a", strokeWidth: 4 };
94
+ case "nucleus":
95
+ if (presetKey === "optical") return { color: "#3b82f6", strokeWidth: 2, fontSize: 18 };
96
+ return { color: "#0f172a", strokeWidth: 2, fontSize: 18 };
97
+ case "energy_level":
98
+ return { color: "#0f172a", strokeWidth: 2, label: "n=1", energy: "-13.6 eV" };
99
+ case "dashed_line":
100
+ return { color: "#0f172a", strokeWidth: 2, lineStyle: "dashed" };
101
+ case "point":
102
+ if (presetKey === "graph") return { color: "#0f172a", strokeWidth: 2, fontSize: 16, label: "P" };
103
+ if (presetKey === "light" || presetKey === "optical") return { color: "#0f172a", strokeWidth: 2, fontSize: 18, label: "P" };
104
+ if (presetKey === "thermo") return { color: "#0f172a", strokeWidth: 2, fontSize: 18, label: "P" };
105
+ return {};
106
+ case "text":
107
+ if (presetKey === "graph") return { color: "#0f172a", strokeWidth: 2, fontSize: 18, label: "Label" };
108
+ if (presetKey === "light" || presetKey === "optical") return { color: "#0f172a", strokeWidth: 2, fontSize: 18, label: "Text" };
109
+ if (presetKey === "mechanics" || presetKey === "mechanical") return { color: "#0f172a", strokeWidth: 2, fontSize: 20, label: "Label" };
110
+ if (presetKey === "rotation") return { color: "#1e293b", strokeWidth: 2, fontSize: 20, label: "Label" };
111
+ if (presetKey === "thermo") return { color: "#1e293b", strokeWidth: 2, fontSize: 18, label: "Equation/Label" };
112
+ return {};
113
+ case "b_field_line":
114
+ case "b_field_curve":
115
+ if (presetKey === "magnetism") return { color: "#10b981", strokeWidth: 2 };
116
+ return {};
117
+ case "pole_piece":
118
+ if (presetKey === "magnetism") return { color: "#0f172a", strokeWidth: 2, label: "N" };
119
+ return {};
120
+ case "b_region_in":
121
+ case "b_region_out":
122
+ if (presetKey === "magnetism") return { color: "#94a3b8", strokeWidth: 2 };
123
+ return {};
124
+ case "current_wire":
125
+ if (presetKey === "magnetism") return { color: "#ef4444", strokeWidth: 2, label: "I" };
126
+ return {};
127
+ case "bar_magnet":
128
+ if (presetKey === "magnetism") return { color: "#0f172a", strokeWidth: 2, label: "" };
129
+ return {};
130
+ case "coil":
131
+ if (presetKey === "magnetism") return { color: "#0f172a", strokeWidth: 2 };
132
+ return {};
133
+ case "bezier":
134
+ if (presetKey === "magnetism") return { color: "#0f172a", strokeWidth: 2 };
135
+ return {};
136
+ case "meter":
137
+ if (presetKey === "magnetism") return { color: "#0f172a", strokeWidth: 2, fontSize: 24, label: "G" };
138
+ return {};
139
+ case "ac_source":
140
+ if (presetKey === "magnetism") return { color: "#0f172a", strokeWidth: 2, fontSize: 18, label: "V_rms" };
141
+ return {};
142
+ case "spring":
143
+ if (presetKey === "rotation") return { color: "#0f172a", strokeWidth: 2, coils: 6, lineStyle: "solid" };
144
+ if (presetKey === "mechanics" || presetKey === "mechanical") return { color: "#0f172a", strokeWidth: 2 };
145
+ return {};
146
+ case "pivot":
147
+ if (presetKey === "rotation") return { color: "#64748b", strokeWidth: 2, size: 20, fontSize: 18 };
148
+ if (presetKey === "mechanics" || presetKey === "mechanical") return { color: "#0f172a", strokeWidth: 2 };
149
+ return {};
150
+ case "pulley":
151
+ if (presetKey === "rotation") return { color: "#64748b", strokeWidth: 2, fontSize: 18 };
152
+ if (presetKey === "mechanics" || presetKey === "mechanical") return { color: "#0f172a", strokeWidth: 2 };
153
+ return {};
154
+ case "point_mass":
155
+ return { color: "#ef4444", strokeWidth: 2, size: 15, fontSize: 18 };
156
+ case "block_mass":
157
+ return { color: "#3b82f6", strokeWidth: 2, fontSize: 18 };
158
+ case "com_indicator":
159
+ return { color: "#10b981", strokeWidth: 2, size: 15, fontSize: 18 };
160
+ case "system_boundary":
161
+ case "dashed_path":
162
+ return { color: "#94a3b8", strokeWidth: presetKey === "rotation" ? 1.5 : 2, fontSize: 18 };
163
+ case "rocket":
164
+ return { color: "#ef4444", strokeWidth: 2, fontSize: 18 };
165
+ case "uniform_rod":
166
+ return { color: "#f59e0b", strokeWidth: 10, fontSize: 18 };
167
+ case "solid_disk":
168
+ case "hoop_ring":
169
+ return { color: "#3b82f6", strokeWidth: 2, fontSize: 18 };
170
+ case "rolling_body":
171
+ return { color: "#3b82f6", strokeWidth: 2, fontSize: 18, showVelocity: true, showOmega: true };
172
+ case "inclined_wedge":
173
+ return { color: "#64748b", strokeWidth: 2, fontSize: 18 };
174
+ case "curve_arrow":
175
+ return { color: "#10b981", strokeWidth: 2, fontSize: 18 };
176
+ case "line":
177
+ if (presetKey === "rotation") return { color: "#1e293b", strokeWidth: 1.5 };
178
+ if (presetKey === "thermo") return { color: "#1e293b", strokeWidth: 2, lineStyle: "solid" };
179
+ return {};
180
+ case "piston_cylinder":
181
+ if (presetKey !== "thermo") return {};
182
+ return {
183
+ color: "#1e293b",
184
+ strokeWidth: 2,
185
+ fontSize: 18,
186
+ compression: 0.5,
187
+ showHeat: false,
188
+ lineStyle: "solid"
189
+ };
190
+ case "heat_engine":
191
+ if (presetKey !== "thermo") return {};
192
+ return {
193
+ color: "#10b981",
194
+ strokeWidth: 2,
195
+ fontSize: 18,
196
+ engineType: "engine",
197
+ efficiency: 0.4,
198
+ lineStyle: "solid"
199
+ };
200
+ case "conduction_rod":
201
+ if (presetKey !== "thermo") return {};
202
+ return { color: "#3b82f6", strokeWidth: 2, fontSize: 18, lineStyle: "solid" };
203
+ case "pv_axes":
204
+ if (presetKey !== "thermo") return {};
205
+ return {
206
+ color: "#1e293b",
207
+ strokeWidth: 2,
208
+ fontSize: 18,
209
+ xLabel: "V",
210
+ yLabel: "P",
211
+ lineStyle: "solid"
212
+ };
213
+ case "thermo_process":
214
+ if (presetKey !== "thermo") return {};
215
+ return {
216
+ color: "#ec4899",
217
+ strokeWidth: 2,
218
+ fontSize: 18,
219
+ processType: "isotherm",
220
+ lineStyle: "solid"
221
+ };
222
+ case "carnot_cycle":
223
+ if (presetKey !== "thermo") return {};
224
+ return { color: "#ec4899", strokeWidth: 2, fontSize: 18, lineStyle: "solid" };
225
+ case "maxwell_boltzmann":
226
+ if (presetKey !== "thermo") return {};
227
+ return {
228
+ color: "#1e293b",
229
+ strokeWidth: 2,
230
+ fontSize: 18,
231
+ t1: 300,
232
+ t2: 600,
233
+ lineStyle: "solid"
234
+ };
235
+ case "diatomic_gas":
236
+ return { color: "#f59e0b", strokeWidth: 2, fontSize: 18, showRotations: true };
237
+ case "random_walk":
238
+ if (presetKey !== "thermo") return {};
239
+ return { color: "#8b5cf6", strokeWidth: 2, fontSize: 18, steps: 5, lineStyle: "solid" };
240
+ case "string":
241
+ case "surface":
242
+ case "dashed":
243
+ case "dimension":
244
+ case "rod":
245
+ case "arc":
246
+ case "wedge":
247
+ case "axes":
248
+ case "disk":
249
+ case "particle":
250
+ case "com":
251
+ if (presetKey === "mechanics" || presetKey === "mechanical") return { color: "#0f172a", strokeWidth: 2 };
252
+ return {};
253
+ case "block":
254
+ case "cart":
255
+ if (presetKey === "mechanics" || presetKey === "mechanical") return { color: "#0f172a", strokeWidth: 2, rotation: 0 };
256
+ return {};
257
+ default:
258
+ return {};
259
+ }
260
+ };
261
+ var useDrawing = (initialElements2, presetKey) => {
262
+ const [elements, setElements] = useState(initialElements2);
263
+ const [tool, setTool] = useState("select");
264
+ const [drawing, setDrawing] = useState(null);
265
+ const [selectedId, setSelectedId] = useState(null);
266
+ const [isViewMode, setIsViewMode] = useState(false);
267
+ const [showJsonModal, setShowJsonModal] = useState(false);
268
+ const [jsonText, setJsonText] = useState("");
269
+ const [showProperties, setShowProperties] = useState(false);
270
+ const [draggingId, setDraggingId] = useState(null);
271
+ const svgRef = useRef(null);
272
+ const dragStart = useRef({ x: 0, y: 0 });
273
+ const originalPos = useRef(null);
274
+ useEffect(() => {
275
+ setElements(initialElements2);
276
+ }, [initialElements2]);
277
+ useEffect(() => {
278
+ const handleKeyDown = (e) => {
279
+ if ((e.key === "Delete" || e.key === "Backspace") && selectedId) {
280
+ setElements((prev) => prev.filter((el) => el.id !== selectedId));
281
+ setSelectedId(null);
282
+ setShowProperties(false);
283
+ }
284
+ if (e.key === "Escape") {
285
+ setDrawing(null);
286
+ setTool("select");
287
+ }
288
+ };
289
+ window.addEventListener("keydown", handleKeyDown);
290
+ return () => window.removeEventListener("keydown", handleKeyDown);
291
+ }, [selectedId]);
292
+ const selectedElement = useMemo(
293
+ () => elements.find((e) => e.id === selectedId) || null,
294
+ [elements, selectedId]
295
+ );
296
+ const onElementMouseDown = (e, element) => {
297
+ if (tool !== "select") return;
298
+ e.stopPropagation();
299
+ if (!svgRef.current) return;
300
+ const m = getMouseCoords(svgRef.current, e);
301
+ setSelectedId(element.id);
302
+ setDraggingId(element.id);
303
+ dragStart.current = m;
304
+ originalPos.current = { x1: element.x1, y1: element.y1, x2: element.x2, y2: element.y2 };
305
+ };
306
+ const handleMouseDown = (e) => {
307
+ if (!svgRef.current) return;
308
+ if (tool === "select") {
309
+ setSelectedId(null);
310
+ return;
311
+ }
312
+ const p = getMouseCoords(svgRef.current, e);
313
+ const x = snap(p.x);
314
+ const y = snap(p.y);
315
+ const mechanicsSingle = (presetKey === "mechanics" || presetKey === "mechanical") && ["pivot", "com", "axes"].includes(tool);
316
+ const rotationSingle = presetKey === "rotation" && ["point_mass", "com_indicator", "pivot"].includes(tool);
317
+ const waveOscSingle = presetKey === "waveOscillation" && ["tuning_fork", "speaker", "wavefronts", "mass_box"].includes(tool);
318
+ const single = mechanicsSingle || rotationSingle || waveOscSingle || [
319
+ "point",
320
+ "text",
321
+ "diatomic_gas",
322
+ "benzene",
323
+ "cyclohexane",
324
+ "cyclopentane",
325
+ "cyclobutane",
326
+ "cyclopropane",
327
+ "atom",
328
+ "charge_plus",
329
+ "charge_minus",
330
+ "charge_pos",
331
+ "charge_neg",
332
+ "radical",
333
+ "lone_pair",
334
+ "nucleus",
335
+ "meter",
336
+ "ac_source"
337
+ ].includes(tool);
338
+ if (single) {
339
+ const defaults2 = toolCreateDefaults(tool, presetKey);
340
+ const defaultLabel = tool === "text" ? "Text" : tool === "atom" ? "C" : tool === "charge_pos" ? "+q" : tool === "charge_neg" ? "-q" : tool === "charge_plus" ? "+q" : tool === "charge_minus" ? "-q" : tool === "meter" ? "G" : tool === "ac_source" ? "V_rms" : "";
341
+ const el = {
342
+ id: Date.now(),
343
+ type: tool,
344
+ x1: x,
345
+ y1: y,
346
+ x2: x,
347
+ y2: y,
348
+ ...defaults2,
349
+ label: typeof defaults2.label === "string" ? defaults2.label : defaultLabel
350
+ };
351
+ setElements((prev) => [...prev, el]);
352
+ setSelectedId(el.id);
353
+ setTool("select");
354
+ return;
355
+ }
356
+ const defaults = toolCreateDefaults(tool, presetKey);
357
+ const rotationExtra = (presetKey === "mechanics" || presetKey === "mechanical") && (tool === "block" || tool === "cart") ? { rotation: defaults.rotation ?? 0 } : {};
358
+ setDrawing({
359
+ ...defaults,
360
+ ...rotationExtra,
361
+ id: Date.now(),
362
+ type: tool,
363
+ x1: x,
364
+ y1: y,
365
+ x2: x,
366
+ y2: y,
367
+ label: typeof defaults.label === "string" ? defaults.label : ""
368
+ });
369
+ };
370
+ const handleMouseMove = (e) => {
371
+ if (!svgRef.current) return;
372
+ const p = getMouseCoords(svgRef.current, e);
373
+ if (draggingId && originalPos.current) {
374
+ const dx = snap(p.x - dragStart.current.x);
375
+ const dy = snap(p.y - dragStart.current.y);
376
+ setElements(
377
+ (prev) => prev.map(
378
+ (el) => el.id === draggingId ? {
379
+ ...el,
380
+ x1: originalPos.current.x1 + dx,
381
+ y1: originalPos.current.y1 + dy,
382
+ x2: originalPos.current.x2 + dx,
383
+ y2: originalPos.current.y2 + dy
384
+ } : el
385
+ )
386
+ );
387
+ return;
388
+ }
389
+ if (!drawing) return;
390
+ setDrawing({ ...drawing, x2: snap(p.x), y2: snap(p.y) });
391
+ };
392
+ const handleMouseUp = () => {
393
+ if (draggingId) {
394
+ setDraggingId(null);
395
+ return;
396
+ }
397
+ if (!drawing) return;
398
+ if (drawing.x1 === drawing.x2 && drawing.y1 === drawing.y2) {
399
+ setDrawing(null);
400
+ setTool("select");
401
+ return;
402
+ }
403
+ const finalized = drawing.type === "bezier" ? {
404
+ ...drawing,
405
+ cps: [{ x: (drawing.x1 + drawing.x2) / 2, y: Math.min(drawing.y1, drawing.y2) - 60 }]
406
+ } : drawing;
407
+ setElements((prev) => [...prev, finalized]);
408
+ setSelectedId(drawing.id);
409
+ setDrawing(null);
410
+ setTool("select");
411
+ };
412
+ return {
413
+ elements,
414
+ setElements,
415
+ tool,
416
+ setTool,
417
+ drawing,
418
+ selectedId,
419
+ setSelectedId,
420
+ isViewMode,
421
+ setIsViewMode,
422
+ showJsonModal,
423
+ setShowJsonModal,
424
+ jsonText,
425
+ setJsonText,
426
+ showProperties,
427
+ setShowProperties,
428
+ selectedElement,
429
+ svgRef,
430
+ onElementMouseDown,
431
+ handleMouseDown,
432
+ handleMouseMove,
433
+ handleMouseUp
434
+ };
435
+ };
436
+
437
+ // src/editor/icons.tsx
438
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
439
+ var Icons = {
440
+ select: /* @__PURE__ */ jsx("path", { d: "M 8 4 L 16 12 L 11 13 L 9 18 L 6 17 L 8 12 L 4 11 Z", fill: "currentColor", stroke: "currentColor", strokeWidth: "1.5" }),
441
+ point: /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "3", fill: "currentColor" }),
442
+ line: /* @__PURE__ */ jsx("line", { x1: "4", y1: "20", x2: "20", y2: "4", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" }),
443
+ string: /* @__PURE__ */ jsx("line", { x1: "4", y1: "12", x2: "20", y2: "12", stroke: "currentColor", strokeWidth: "2" }),
444
+ vector: /* @__PURE__ */ jsxs(Fragment, { children: [
445
+ /* @__PURE__ */ jsx("line", { x1: "4", y1: "20", x2: "18", y2: "6", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" }),
446
+ /* @__PURE__ */ jsx("polygon", { points: "14,4 20,4 20,10", fill: "none", stroke: "currentColor", strokeWidth: "2.5" })
447
+ ] }),
448
+ ray: /* @__PURE__ */ jsxs(Fragment, { children: [
449
+ /* @__PURE__ */ jsx("line", { x1: "2", y1: "12", x2: "22", y2: "12", stroke: "currentColor", strokeWidth: "2" }),
450
+ /* @__PURE__ */ jsx("polygon", { points: "10,8 16,12 10,16", fill: "currentColor" })
451
+ ] }),
452
+ wire: /* @__PURE__ */ jsx("line", { x1: "3", y1: "12", x2: "21", y2: "12", stroke: "currentColor", strokeWidth: "2.8", strokeLinecap: "round" }),
453
+ text: /* @__PURE__ */ jsx("text", { x: "12", y: "18", fontSize: "18", textAnchor: "middle", fill: "currentColor", fontWeight: "bold", fontFamily: "serif", children: "T" }),
454
+ block: /* @__PURE__ */ jsx("rect", { x: "5", y: "6", width: "14", height: "12", fill: "none", stroke: "currentColor", strokeWidth: "2", rx: "1" }),
455
+ wedge: /* @__PURE__ */ jsx("polygon", { points: "2,20 22,20 22,6", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinejoin: "round" }),
456
+ pulley: /* @__PURE__ */ jsxs(Fragment, { children: [
457
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "10", r: "6", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
458
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "2", x2: "12", y2: "10", stroke: "currentColor", strokeWidth: "2" }),
459
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "10", x2: "6", y2: "20", stroke: "currentColor", strokeWidth: "1.5" }),
460
+ /* @__PURE__ */ jsx("line", { x1: "18", y1: "10", x2: "18", y2: "18", stroke: "currentColor", strokeWidth: "1.5" })
461
+ ] }),
462
+ point_mass: /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "8", fill: "currentColor", stroke: "currentColor", strokeWidth: "2" }),
463
+ block_mass: /* @__PURE__ */ jsx("rect", { x: "6", y: "6", width: "12", height: "12", fill: "none", stroke: "currentColor", strokeWidth: "2", rx: "1" }),
464
+ com_indicator: /* @__PURE__ */ jsxs(Fragment, { children: [
465
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "8", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
466
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "2", x2: "12", y2: "22", stroke: "currentColor", strokeWidth: "2" }),
467
+ /* @__PURE__ */ jsx("line", { x1: "2", y1: "12", x2: "22", y2: "12", stroke: "currentColor", strokeWidth: "2" }),
468
+ /* @__PURE__ */ jsx("path", { d: "M 12 12 L 17 7 A 7 7 0 0 1 17 17 Z M 12 12 L 7 17 A 7 7 0 0 1 7 7 Z", fill: "currentColor", opacity: "0.3" })
469
+ ] }),
470
+ system_boundary: /* @__PURE__ */ jsx("rect", { x: "4", y: "4", width: "16", height: "16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeDasharray: "3 2", rx: "4" }),
471
+ rocket: /* @__PURE__ */ jsxs(Fragment, { children: [
472
+ /* @__PURE__ */ jsx("path", { d: "M12 2 L16 8 L16 16 L20 20 L4 20 L8 16 L8 8 Z", fill: "none", stroke: "currentColor", strokeWidth: "1.5" }),
473
+ /* @__PURE__ */ jsx("path", { d: "M8 20 Q12 24 16 20", fill: "currentColor" })
474
+ ] }),
475
+ dashed_path: /* @__PURE__ */ jsx("path", { d: "M 4 20 Q 8 8 20 4", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeDasharray: "4 3" }),
476
+ uniform_rod: /* @__PURE__ */ jsx("rect", { x: "3", y: "10", width: "18", height: "4", fill: "currentColor", rx: "2", opacity: "0.8" }),
477
+ solid_disk: /* @__PURE__ */ jsxs(Fragment, { children: [
478
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9", fill: "currentColor", opacity: "0.5", stroke: "currentColor", strokeWidth: "2" }),
479
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "1.5", fill: "currentColor" })
480
+ ] }),
481
+ hoop_ring: /* @__PURE__ */ jsxs(Fragment, { children: [
482
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9", fill: "none", stroke: "currentColor", strokeWidth: "2.5" }),
483
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "1.5", fill: "currentColor" })
484
+ ] }),
485
+ rolling_body: /* @__PURE__ */ jsxs(Fragment, { children: [
486
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "8", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
487
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "12", x2: "20", y2: "12", stroke: "currentColor", strokeWidth: "1.5" }),
488
+ /* @__PURE__ */ jsx("polygon", { points: "18,10 22,12 18,14", fill: "currentColor" }),
489
+ /* @__PURE__ */ jsx("path", { d: "M 16 6 A 8 8 0 0 1 20 10", fill: "none", stroke: "currentColor", strokeWidth: "1.5" }),
490
+ /* @__PURE__ */ jsx("polygon", { points: "19,11 22,9 18,8", fill: "currentColor" })
491
+ ] }),
492
+ inclined_wedge: /* @__PURE__ */ jsx("polygon", { points: "4,20 20,20 4,8", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinejoin: "round" }),
493
+ curve_arrow: /* @__PURE__ */ jsxs(Fragment, { children: [
494
+ /* @__PURE__ */ jsx("path", { d: "M 6 18 A 9 9 0 0 1 18 6", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
495
+ /* @__PURE__ */ jsx("polygon", { points: "16,5 20,4 19,8", fill: "currentColor" })
496
+ ] }),
497
+ ladder: /* @__PURE__ */ jsxs(Fragment, { children: [
498
+ /* @__PURE__ */ jsx("line", { x1: "7", y1: "4", x2: "4", y2: "20", stroke: "currentColor", strokeWidth: "2" }),
499
+ /* @__PURE__ */ jsx("line", { x1: "17", y1: "4", x2: "14", y2: "20", stroke: "currentColor", strokeWidth: "2" }),
500
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "8", x2: "16", y2: "8", stroke: "currentColor", strokeWidth: "1.6" }),
501
+ /* @__PURE__ */ jsx("line", { x1: "5", y1: "12", x2: "15", y2: "12", stroke: "currentColor", strokeWidth: "1.6" }),
502
+ /* @__PURE__ */ jsx("line", { x1: "4.5", y1: "16", x2: "14.5", y2: "16", stroke: "currentColor", strokeWidth: "1.6" })
503
+ ] }),
504
+ spring: /* @__PURE__ */ jsx(
505
+ "path",
506
+ {
507
+ d: "M 2 12 L 5 12 L 7 6 L 11 18 L 15 6 L 19 18 L 21 12 L 22 12",
508
+ fill: "none",
509
+ stroke: "currentColor",
510
+ strokeWidth: "2",
511
+ strokeLinejoin: "bevel"
512
+ }
513
+ ),
514
+ arc: /* @__PURE__ */ jsx(
515
+ "path",
516
+ {
517
+ d: "M 22 12 A 10 10 0 0 0 12 2 L 12 12 Z",
518
+ fill: "none",
519
+ stroke: "currentColor",
520
+ strokeWidth: "2",
521
+ strokeLinejoin: "round"
522
+ }
523
+ ),
524
+ arc_arrow: /* @__PURE__ */ jsxs(Fragment, { children: [
525
+ /* @__PURE__ */ jsx("path", { d: "M 4 16 A 8 8 0 0 1 18 8", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round" }),
526
+ /* @__PURE__ */ jsx("polygon", { points: "17,5 21,9 15,10", fill: "currentColor" })
527
+ ] }),
528
+ dashed: /* @__PURE__ */ jsx("line", { x1: "2", y1: "12", x2: "22", y2: "12", stroke: "currentColor", strokeWidth: "2", strokeDasharray: "4,4" }),
529
+ surface: /* @__PURE__ */ jsx(
530
+ "path",
531
+ {
532
+ d: "M 4 10 L 20 10 M 6 10 L 2 16 M 12 10 L 8 16 M 18 10 L 14 16 M 24 10 L 20 16",
533
+ fill: "none",
534
+ stroke: "currentColor",
535
+ strokeWidth: "2"
536
+ }
537
+ ),
538
+ dimension: /* @__PURE__ */ jsxs(Fragment, { children: [
539
+ /* @__PURE__ */ jsx("line", { x1: "4", y1: "12", x2: "20", y2: "12", stroke: "currentColor", strokeWidth: "1.5", strokeDasharray: "2 2" }),
540
+ /* @__PURE__ */ jsx("polygon", { points: "4,12 8,9 8,15", fill: "currentColor" }),
541
+ /* @__PURE__ */ jsx("polygon", { points: "20,12 16,9 16,15", fill: "currentColor" })
542
+ ] }),
543
+ axes: /* @__PURE__ */ jsxs(Fragment, { children: [
544
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "18", x2: "6", y2: "6", stroke: "currentColor", strokeWidth: "2" }),
545
+ /* @__PURE__ */ jsx("polygon", { points: "6,4 3,9 9,9", fill: "currentColor" }),
546
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "18", x2: "18", y2: "18", stroke: "currentColor", strokeWidth: "2" }),
547
+ /* @__PURE__ */ jsx("polygon", { points: "20,18 15,15 15,21", fill: "currentColor" })
548
+ ] }),
549
+ cart: /* @__PURE__ */ jsx(
550
+ "path",
551
+ {
552
+ d: "M 4 8 L 20 8 L 20 14 L 4 14 Z M 8 18 A 2 2 0 1 0 8 14 A 2 2 0 1 0 8 18 M 16 18 A 2 2 0 1 0 16 14 A 2 2 0 1 0 16 18",
553
+ fill: "none",
554
+ stroke: "currentColor",
555
+ strokeWidth: "2"
556
+ }
557
+ ),
558
+ disk: /* @__PURE__ */ jsxs(Fragment, { children: [
559
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "8", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
560
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "12", x2: "18", y2: "18", stroke: "currentColor", strokeWidth: "2" }),
561
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "2", fill: "currentColor" })
562
+ ] }),
563
+ com: /* @__PURE__ */ jsxs(Fragment, { children: [
564
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "8", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
565
+ /* @__PURE__ */ jsx("path", { d: "M 12 4 A 8 8 0 0 1 20 12 L 12 12 Z M 12 20 A 8 8 0 0 1 4 12 L 12 12 Z", fill: "currentColor" })
566
+ ] }),
567
+ particle: /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "5", fill: "currentColor" }),
568
+ pivot: /* @__PURE__ */ jsxs(Fragment, { children: [
569
+ /* @__PURE__ */ jsx("polygon", { points: "12,6 6,18 18,18", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
570
+ /* @__PURE__ */ jsx("line", { x1: "4", y1: "20", x2: "20", y2: "20", stroke: "currentColor", strokeWidth: "2" }),
571
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "6", r: "2", fill: "currentColor" })
572
+ ] }),
573
+ dashed_line: /* @__PURE__ */ jsx("line", { x1: "4", y1: "20", x2: "20", y2: "4", stroke: "currentColor", strokeWidth: "2.5", strokeDasharray: "4 4", strokeLinecap: "round" }),
574
+ angle: /* @__PURE__ */ jsxs(Fragment, { children: [
575
+ /* @__PURE__ */ jsx("line", { x1: "4", y1: "20", x2: "20", y2: "20", stroke: "currentColor", strokeWidth: "2" }),
576
+ /* @__PURE__ */ jsx("line", { x1: "4", y1: "20", x2: "16", y2: "4", stroke: "currentColor", strokeWidth: "2" }),
577
+ /* @__PURE__ */ jsx("path", { d: "M 14 20 A 10 10 0 0 0 10 12", fill: "none", stroke: "currentColor", strokeWidth: "2" })
578
+ ] }),
579
+ rectangle: /* @__PURE__ */ jsx("rect", { x: "4", y: "6", width: "16", height: "12", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinejoin: "round" }),
580
+ circle: /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "8", fill: "none", stroke: "currentColor", strokeWidth: "2.5" }),
581
+ ellipse: /* @__PURE__ */ jsx("ellipse", { cx: "12", cy: "12", rx: "10", ry: "5", fill: "none", stroke: "currentColor", strokeWidth: "2.5" }),
582
+ parabola_v: /* @__PURE__ */ jsx("path", { d: "M 4 4 Q 12 24 20 4", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" }),
583
+ parabola_h: /* @__PURE__ */ jsx("path", { d: "M 20 4 Q 0 12 20 20", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" }),
584
+ hyperbola: /* @__PURE__ */ jsxs(Fragment, { children: [
585
+ /* @__PURE__ */ jsx("path", { d: "M 6 2 Q 12 12 6 22", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
586
+ /* @__PURE__ */ jsx("path", { d: "M 18 2 Q 12 12 18 22", fill: "none", stroke: "currentColor", strokeWidth: "2" })
587
+ ] }),
588
+ sine_wave: /* @__PURE__ */ jsx("path", { d: "M 2 12 Q 7 2 12 12 T 22 12", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" }),
589
+ mass_box: /* @__PURE__ */ jsx("rect", { x: "6", y: "6", width: "12", height: "12", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
590
+ pendulum: /* @__PURE__ */ jsxs(Fragment, { children: [
591
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "2", x2: "18", y2: "16", stroke: "currentColor", strokeWidth: "2" }),
592
+ /* @__PURE__ */ jsx("circle", { cx: "18", cy: "18", r: "4", fill: "currentColor" }),
593
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "2", x2: "18", y2: "2", stroke: "currentColor", strokeWidth: "2" })
594
+ ] }),
595
+ phasor: /* @__PURE__ */ jsxs(Fragment, { children: [
596
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
597
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "12", x2: "18", y2: "6", stroke: "currentColor", strokeWidth: "2" }),
598
+ /* @__PURE__ */ jsx("polygon", { points: "15,5 19,5 19,9", fill: "currentColor" })
599
+ ] }),
600
+ damped_wave: /* @__PURE__ */ jsx("path", { d: "M 2 12 Q 5 2 8 12 T 14 12 T 18 12 T 22 12", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
601
+ vane_liquid: /* @__PURE__ */ jsxs(Fragment, { children: [
602
+ /* @__PURE__ */ jsx("path", { d: "M 4 4 L 4 20 L 20 20 L 20 4", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
603
+ /* @__PURE__ */ jsx("rect", { x: "4", y: "10", width: "16", height: "10", fill: "currentColor", opacity: "0.35" }),
604
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "2", x2: "12", y2: "16", stroke: "currentColor", strokeWidth: "2" }),
605
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "16", x2: "16", y2: "16", stroke: "currentColor", strokeWidth: "2" })
606
+ ] }),
607
+ torsion_pendulum: /* @__PURE__ */ jsxs(Fragment, { children: [
608
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "2", x2: "12", y2: "16", stroke: "currentColor", strokeWidth: "2" }),
609
+ /* @__PURE__ */ jsx("ellipse", { cx: "12", cy: "16", rx: "8", ry: "3", fill: "currentColor" }),
610
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "16", x2: "18", y2: "18", stroke: "currentColor", strokeWidth: "1" })
611
+ ] }),
612
+ standing_wave: /* @__PURE__ */ jsxs(Fragment, { children: [
613
+ /* @__PURE__ */ jsx("path", { d: "M 2 12 Q 7 2 12 12 T 22 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5" }),
614
+ /* @__PURE__ */ jsx(
615
+ "path",
616
+ {
617
+ d: "M 2 12 Q 7 22 12 12 T 22 12",
618
+ fill: "none",
619
+ stroke: "currentColor",
620
+ strokeWidth: "1.5",
621
+ strokeDasharray: "2 2"
622
+ }
623
+ )
624
+ ] }),
625
+ wave_pulse: /* @__PURE__ */ jsx("path", { d: "M 2 16 L 8 16 Q 12 4 16 16 L 22 16", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
626
+ shm_graph: /* @__PURE__ */ jsxs(Fragment, { children: [
627
+ /* @__PURE__ */ jsx("line", { x1: "2", y1: "12", x2: "22", y2: "12", stroke: "currentColor", strokeWidth: "1", opacity: "0.5" }),
628
+ /* @__PURE__ */ jsx("path", { d: "M 2 12 Q 7 2 12 12 T 22 12", fill: "none", stroke: "#3b82f6", strokeWidth: "2" }),
629
+ /* @__PURE__ */ jsx(
630
+ "path",
631
+ {
632
+ d: "M 2 12 Q 7 22 12 12 T 22 12",
633
+ fill: "none",
634
+ stroke: "#ef4444",
635
+ strokeWidth: "2",
636
+ strokeDasharray: "2 2"
637
+ }
638
+ )
639
+ ] }),
640
+ energy_graph: /* @__PURE__ */ jsxs(Fragment, { children: [
641
+ /* @__PURE__ */ jsx("line", { x1: "2", y1: "20", x2: "22", y2: "20", stroke: "currentColor", strokeWidth: "2" }),
642
+ /* @__PURE__ */ jsx("path", { d: "M 4 6 Q 12 24 20 6", fill: "none", stroke: "#ef4444", strokeWidth: "2" }),
643
+ /* @__PURE__ */ jsx("path", { d: "M 4 20 Q 12 2 20 20", fill: "none", stroke: "#10b981", strokeWidth: "2" })
644
+ ] }),
645
+ strobe_shm: /* @__PURE__ */ jsxs(Fragment, { children: [
646
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "4", r: "2", fill: "currentColor" }),
647
+ /* @__PURE__ */ jsx("circle", { cx: "18", cy: "12", r: "2", fill: "currentColor" }),
648
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "20", r: "2", fill: "currentColor" }),
649
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "4", x2: "18", y2: "4", stroke: "currentColor", strokeWidth: "0.5" }),
650
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "12", x2: "18", y2: "12", stroke: "currentColor", strokeWidth: "0.5" }),
651
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "20", x2: "18", y2: "20", stroke: "currentColor", strokeWidth: "0.5" })
652
+ ] }),
653
+ wall: /* @__PURE__ */ jsxs(Fragment, { children: [
654
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "2", x2: "12", y2: "22", stroke: "currentColor", strokeWidth: "2" }),
655
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "4", x2: "16", y2: "0", stroke: "currentColor", strokeWidth: "1.5" }),
656
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "10", x2: "16", y2: "6", stroke: "currentColor", strokeWidth: "1.5" }),
657
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "16", x2: "16", y2: "12", stroke: "currentColor", strokeWidth: "1.5" }),
658
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "22", x2: "16", y2: "18", stroke: "currentColor", strokeWidth: "1.5" })
659
+ ] }),
660
+ tuning_fork: /* @__PURE__ */ jsxs(Fragment, { children: [
661
+ /* @__PURE__ */ jsx("path", { d: "M 8 4 L 8 14 Q 12 20 16 14 L 16 4", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
662
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "17", x2: "12", y2: "24", stroke: "currentColor", strokeWidth: "2" })
663
+ ] }),
664
+ speaker: /* @__PURE__ */ jsxs(Fragment, { children: [
665
+ /* @__PURE__ */ jsx("polygon", { points: "8,8 14,4 14,20 8,16", fill: "currentColor" }),
666
+ /* @__PURE__ */ jsx("rect", { x: "4", y: "8", width: "4", height: "8", fill: "currentColor" }),
667
+ /* @__PURE__ */ jsx("path", { d: "M 18 8 Q 20 12 18 16 M 21 5 Q 24 12 21 19", fill: "none", stroke: "currentColor", strokeWidth: "2" })
668
+ ] }),
669
+ wavefronts: /* @__PURE__ */ jsxs(Fragment, { children: [
670
+ /* @__PURE__ */ jsx("circle", { cx: "10", cy: "12", r: "4", fill: "none", stroke: "currentColor" }),
671
+ /* @__PURE__ */ jsx("circle", { cx: "11", cy: "12", r: "8", fill: "none", stroke: "currentColor" }),
672
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "12", fill: "none", stroke: "currentColor" })
673
+ ] }),
674
+ mach_cone: /* @__PURE__ */ jsxs(Fragment, { children: [
675
+ /* @__PURE__ */ jsx("circle", { cx: "18", cy: "12", r: "2", fill: "currentColor" }),
676
+ /* @__PURE__ */ jsx("line", { x1: "2", y1: "4", x2: "18", y2: "12", stroke: "currentColor", strokeWidth: "1.5" }),
677
+ /* @__PURE__ */ jsx("line", { x1: "2", y1: "20", x2: "18", y2: "12", stroke: "currentColor", strokeWidth: "1.5" })
678
+ ] }),
679
+ beats_graph: /* @__PURE__ */ jsx(
680
+ "path",
681
+ {
682
+ d: "M 2 12 Q 4 6 6 12 Q 8 18 10 12 Q 12 8 14 12 Q 16 16 18 12 Q 20 10 22 12",
683
+ fill: "none",
684
+ stroke: "currentColor",
685
+ strokeWidth: "1.5"
686
+ }
687
+ ),
688
+ step_function: /* @__PURE__ */ jsxs(Fragment, { children: [
689
+ /* @__PURE__ */ jsx("path", { d: "M2 18 L8 18 M8 12 L14 12 M14 6 L20 6", stroke: "currentColor", strokeWidth: "2" }),
690
+ /* @__PURE__ */ jsx("circle", { cx: "2", cy: "18", r: "2", fill: "currentColor" }),
691
+ /* @__PURE__ */ jsx("circle", { cx: "8", cy: "18", r: "2", fill: "none", stroke: "currentColor" }),
692
+ /* @__PURE__ */ jsx("circle", { cx: "8", cy: "12", r: "2", fill: "currentColor" }),
693
+ /* @__PURE__ */ jsx("circle", { cx: "14", cy: "12", r: "2", fill: "none", stroke: "currentColor" }),
694
+ /* @__PURE__ */ jsx("circle", { cx: "14", cy: "6", r: "2", fill: "currentColor" }),
695
+ /* @__PURE__ */ jsx("circle", { cx: "20", cy: "6", r: "2", fill: "none", stroke: "currentColor" })
696
+ ] }),
697
+ shaded_area: /* @__PURE__ */ jsxs(Fragment, { children: [
698
+ /* @__PURE__ */ jsx("path", { d: "M4 20 L4 10 Q12 2 20 10 L20 20 Z", fill: "currentColor", opacity: "0.3" }),
699
+ /* @__PURE__ */ jsx("path", { d: "M4 10 Q12 2 20 10", fill: "none", stroke: "currentColor", strokeWidth: "2" })
700
+ ] }),
701
+ modulus: /* @__PURE__ */ jsx("polyline", { points: "4,4 12,20 20,4", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }),
702
+ exponential: /* @__PURE__ */ jsx("path", { d: "M4 20 Q14 20 20 4", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" }),
703
+ logarithmic: /* @__PURE__ */ jsx("path", { d: "M4 20 Q4 10 20 4", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" }),
704
+ axes_3d: /* @__PURE__ */ jsxs(Fragment, { children: [
705
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "16", x2: "8", y2: "2", stroke: "currentColor", strokeWidth: "2" }),
706
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "16", x2: "22", y2: "16", stroke: "currentColor", strokeWidth: "2" }),
707
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "16", x2: "2", y2: "22", stroke: "currentColor", strokeWidth: "2" })
708
+ ] }),
709
+ rod: /* @__PURE__ */ jsx("line", { x1: "2", y1: "12", x2: "22", y2: "12", stroke: "currentColor", strokeWidth: "6", strokeLinecap: "round" }),
710
+ hinge: /* @__PURE__ */ jsxs(Fragment, { children: [
711
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "3.5", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
712
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "1.5", fill: "currentColor" })
713
+ ] }),
714
+ slit_double: /* @__PURE__ */ jsxs(Fragment, { children: [
715
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "2", x2: "12", y2: "8", stroke: "currentColor", strokeWidth: "3" }),
716
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "11", x2: "12", y2: "13", stroke: "currentColor", strokeWidth: "3" }),
717
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "16", x2: "12", y2: "22", stroke: "currentColor", strokeWidth: "3" })
718
+ ] }),
719
+ slit_single: /* @__PURE__ */ jsxs(Fragment, { children: [
720
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "2", x2: "12", y2: "9", stroke: "currentColor", strokeWidth: "3" }),
721
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "15", x2: "12", y2: "22", stroke: "currentColor", strokeWidth: "3" })
722
+ ] }),
723
+ photon: /* @__PURE__ */ jsxs(Fragment, { children: [
724
+ /* @__PURE__ */ jsx("path", { d: "M 2 12 Q 5 6 8 12 T 14 12 T 20 12", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
725
+ /* @__PURE__ */ jsx("polygon", { points: "18,8 22,12 18,16", fill: "currentColor" })
726
+ ] }),
727
+ nucleus: /* @__PURE__ */ jsxs(Fragment, { children: [
728
+ /* @__PURE__ */ jsx("ellipse", { cx: "12", cy: "12", rx: "10", ry: "4", fill: "none", stroke: "currentColor", transform: "rotate(45 12 12)" }),
729
+ /* @__PURE__ */ jsx("ellipse", { cx: "12", cy: "12", rx: "10", ry: "4", fill: "none", stroke: "currentColor", transform: "rotate(-45 12 12)" }),
730
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "3", fill: "#ef4444" })
731
+ ] }),
732
+ orbit: /* @__PURE__ */ jsx("ellipse", { cx: "12", cy: "12", rx: "8", ry: "4.5", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
733
+ resistor: /* @__PURE__ */ jsx("path", { d: "M 2 12 L 6 12 L 8 6 L 12 18 L 16 6 L 18 12 L 22 12", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
734
+ capacitor: /* @__PURE__ */ jsxs(Fragment, { children: [
735
+ /* @__PURE__ */ jsx("line", { x1: "3", y1: "12", x2: "9", y2: "12", stroke: "currentColor", strokeWidth: "2" }),
736
+ /* @__PURE__ */ jsx("line", { x1: "9", y1: "6", x2: "9", y2: "18", stroke: "currentColor", strokeWidth: "2.2" }),
737
+ /* @__PURE__ */ jsx("line", { x1: "15", y1: "6", x2: "15", y2: "18", stroke: "currentColor", strokeWidth: "2.2" }),
738
+ /* @__PURE__ */ jsx("line", { x1: "15", y1: "12", x2: "21", y2: "12", stroke: "currentColor", strokeWidth: "2" })
739
+ ] }),
740
+ inductor: /* @__PURE__ */ jsx("path", { d: "M 3 12 C 5 8, 7 8, 9 12 C 11 8, 13 8, 15 12 C 17 8, 19 8, 21 12", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
741
+ diode: /* @__PURE__ */ jsxs(Fragment, { children: [
742
+ /* @__PURE__ */ jsx("line", { x1: "3", y1: "12", x2: "8", y2: "12", stroke: "currentColor", strokeWidth: "2" }),
743
+ /* @__PURE__ */ jsx("polygon", { points: "8,7 8,17 14,12", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
744
+ /* @__PURE__ */ jsx("line", { x1: "15.5", y1: "7", x2: "15.5", y2: "17", stroke: "currentColor", strokeWidth: "2" }),
745
+ /* @__PURE__ */ jsx("line", { x1: "15.5", y1: "12", x2: "21", y2: "12", stroke: "currentColor", strokeWidth: "2" })
746
+ ] }),
747
+ battery: /* @__PURE__ */ jsxs(Fragment, { children: [
748
+ /* @__PURE__ */ jsx("path", { d: "M 2 12 L 10 12 M 10 4 L 10 20 M 14 8 L 14 16 M 14 12 L 22 12", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
749
+ /* @__PURE__ */ jsx("line", { x1: "14", y1: "8", x2: "14", y2: "16", stroke: "currentColor", strokeWidth: "4" })
750
+ ] }),
751
+ ground: /* @__PURE__ */ jsx("path", { d: "M 12 4 L 12 12 M 6 12 L 18 12 M 8 16 L 16 16 M 10 20 L 14 20", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
752
+ meter_v: /* @__PURE__ */ jsxs(Fragment, { children: [
753
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "7", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
754
+ /* @__PURE__ */ jsx("text", { x: "12", y: "15", fontSize: "8", textAnchor: "middle", fill: "currentColor", children: "V" })
755
+ ] }),
756
+ meter_a: /* @__PURE__ */ jsxs(Fragment, { children: [
757
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "7", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
758
+ /* @__PURE__ */ jsx("text", { x: "12", y: "15", fontSize: "8", textAnchor: "middle", fill: "currentColor", children: "A" })
759
+ ] }),
760
+ piston_cylinder: /* @__PURE__ */ jsxs(Fragment, { children: [
761
+ /* @__PURE__ */ jsx("path", { d: "M 4 4 L 4 20 L 20 20 L 20 4", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
762
+ /* @__PURE__ */ jsx("rect", { x: "5", y: "10", width: "14", height: "4", fill: "currentColor" }),
763
+ /* @__PURE__ */ jsx("circle", { cx: "9", cy: "16", r: "1", fill: "currentColor" }),
764
+ /* @__PURE__ */ jsx("circle", { cx: "15", cy: "17", r: "1", fill: "currentColor" }),
765
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "14", r: "1", fill: "currentColor" })
766
+ ] }),
767
+ heat_engine: /* @__PURE__ */ jsxs(Fragment, { children: [
768
+ /* @__PURE__ */ jsx("rect", { x: "6", y: "2", width: "12", height: "4", fill: "#ef4444" }),
769
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "4", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
770
+ /* @__PURE__ */ jsx("rect", { x: "6", y: "18", width: "12", height: "4", fill: "#3b82f6" }),
771
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "6", x2: "12", y2: "8", stroke: "currentColor", strokeWidth: "2" }),
772
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "16", x2: "12", y2: "18", stroke: "currentColor", strokeWidth: "2" }),
773
+ /* @__PURE__ */ jsx("line", { x1: "16", y1: "12", x2: "20", y2: "12", stroke: "currentColor", strokeWidth: "2" })
774
+ ] }),
775
+ conduction_rod: /* @__PURE__ */ jsxs(Fragment, { children: [
776
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: "thermo-conduction-icon-grad", x1: "0%", y1: "0%", x2: "100%", y2: "0%", children: [
777
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: "#ef4444" }),
778
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: "#3b82f6" })
779
+ ] }) }),
780
+ /* @__PURE__ */ jsx(
781
+ "rect",
782
+ {
783
+ x: "2",
784
+ y: "8",
785
+ width: "20",
786
+ height: "8",
787
+ fill: "url(#thermo-conduction-icon-grad)",
788
+ stroke: "currentColor",
789
+ strokeWidth: "1"
790
+ }
791
+ )
792
+ ] }),
793
+ pv_axes: /* @__PURE__ */ jsxs(Fragment, { children: [
794
+ /* @__PURE__ */ jsx("line", { x1: "4", y1: "4", x2: "4", y2: "20", stroke: "currentColor", strokeWidth: "2" }),
795
+ /* @__PURE__ */ jsx("line", { x1: "4", y1: "20", x2: "20", y2: "20", stroke: "currentColor", strokeWidth: "2" }),
796
+ /* @__PURE__ */ jsx("polygon", { points: "4,2 2,6 6,6", fill: "currentColor" }),
797
+ /* @__PURE__ */ jsx("polygon", { points: "22,20 18,18 18,22", fill: "currentColor" })
798
+ ] }),
799
+ thermo_process: /* @__PURE__ */ jsxs(Fragment, { children: [
800
+ /* @__PURE__ */ jsx("path", { d: "M 4 4 Q 8 16 20 20", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
801
+ /* @__PURE__ */ jsx("polygon", { points: "12,12 8,10 10,14", fill: "currentColor" })
802
+ ] }),
803
+ carnot_cycle: /* @__PURE__ */ jsx(
804
+ "path",
805
+ {
806
+ d: "M 6 6 Q 12 8 16 12 Q 14 16 10 18 Q 6 14 6 6",
807
+ fill: "none",
808
+ stroke: "currentColor",
809
+ strokeWidth: "2"
810
+ }
811
+ ),
812
+ maxwell_boltzmann: /* @__PURE__ */ jsxs(Fragment, { children: [
813
+ /* @__PURE__ */ jsx("line", { x1: "2", y1: "20", x2: "22", y2: "20", stroke: "currentColor", strokeWidth: "2" }),
814
+ /* @__PURE__ */ jsx("path", { d: "M 2 20 Q 8 4 12 12 T 22 20", fill: "none", stroke: "#ef4444", strokeWidth: "2" }),
815
+ /* @__PURE__ */ jsx(
816
+ "path",
817
+ {
818
+ d: "M 2 20 Q 6 10 10 16 T 22 20",
819
+ fill: "none",
820
+ stroke: "#3b82f6",
821
+ strokeWidth: "2",
822
+ strokeDasharray: "2 2"
823
+ }
824
+ )
825
+ ] }),
826
+ diatomic_gas: /* @__PURE__ */ jsxs(Fragment, { children: [
827
+ /* @__PURE__ */ jsx("circle", { cx: "6", cy: "12", r: "4", fill: "currentColor" }),
828
+ /* @__PURE__ */ jsx("circle", { cx: "18", cy: "12", r: "4", fill: "currentColor" }),
829
+ /* @__PURE__ */ jsx("line", { x1: "10", y1: "12", x2: "14", y2: "12", stroke: "currentColor", strokeWidth: "2" }),
830
+ /* @__PURE__ */ jsx("path", { d: "M 8 6 A 6 6 0 0 1 16 6", fill: "none", stroke: "currentColor", strokeWidth: "1" })
831
+ ] }),
832
+ random_walk: /* @__PURE__ */ jsxs(Fragment, { children: [
833
+ /* @__PURE__ */ jsx("polyline", { points: "2,18 8,12 14,16 20,6", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
834
+ /* @__PURE__ */ jsx("circle", { cx: "2", cy: "18", r: "1.5", fill: "currentColor" }),
835
+ /* @__PURE__ */ jsx("circle", { cx: "20", cy: "6", r: "1.5", fill: "currentColor" })
836
+ ] }),
837
+ lens_convex: /* @__PURE__ */ jsx(
838
+ "path",
839
+ {
840
+ d: "M 12 2 Q 18 12 12 22 Q 6 12 12 2 Z",
841
+ fill: "#38bdf8",
842
+ fillOpacity: "0.4",
843
+ stroke: "currentColor",
844
+ strokeWidth: "2"
845
+ }
846
+ ),
847
+ lens_concave: /* @__PURE__ */ jsx(
848
+ "path",
849
+ {
850
+ d: "M 8 2 L 16 2 Q 12 12 16 22 L 8 22 Q 12 12 8 2 Z",
851
+ fill: "#38bdf8",
852
+ fillOpacity: "0.4",
853
+ stroke: "currentColor",
854
+ strokeWidth: "2"
855
+ }
856
+ ),
857
+ mirror_concave: /* @__PURE__ */ jsxs(Fragment, { children: [
858
+ /* @__PURE__ */ jsx("path", { d: "M 16 2 Q 8 12 16 22", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
859
+ /* @__PURE__ */ jsx("line", { x1: "11", y1: "6", x2: "6", y2: "8", stroke: "currentColor" }),
860
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "12", x2: "3", y2: "12", stroke: "currentColor" }),
861
+ /* @__PURE__ */ jsx("line", { x1: "11", y1: "18", x2: "6", y2: "16", stroke: "currentColor" })
862
+ ] }),
863
+ mirror_convex: /* @__PURE__ */ jsxs(Fragment, { children: [
864
+ /* @__PURE__ */ jsx("path", { d: "M 8 4 Q 16 12 8 20", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
865
+ /* @__PURE__ */ jsx("line", { x1: "13", y1: "6", x2: "18", y2: "8", stroke: "currentColor" }),
866
+ /* @__PURE__ */ jsx("line", { x1: "16", y1: "12", x2: "21", y2: "12", stroke: "currentColor" }),
867
+ /* @__PURE__ */ jsx("line", { x1: "13", y1: "18", x2: "18", y2: "16", stroke: "currentColor" })
868
+ ] }),
869
+ prism: /* @__PURE__ */ jsx("polygon", { points: "12,4 2,20 22,20", fill: "#38bdf8", fillOpacity: "0.4", stroke: "currentColor", strokeWidth: "2" }),
870
+ glass_slab: /* @__PURE__ */ jsx("rect", { x: "4", y: "6", width: "16", height: "12", fill: "#38bdf8", fillOpacity: "0.4", stroke: "currentColor", strokeWidth: "2" }),
871
+ pole_piece: /* @__PURE__ */ jsxs(Fragment, { children: [
872
+ /* @__PURE__ */ jsx("rect", { x: "4", y: "2", width: "16", height: "20", fill: "#93c5fd", fillOpacity: "0.4", stroke: "currentColor", strokeWidth: "2" }),
873
+ /* @__PURE__ */ jsx("text", { x: "12", y: "16", fontSize: "12", textAnchor: "middle", fill: "currentColor", fontWeight: "bold", children: "N" })
874
+ ] }),
875
+ b_field_line: /* @__PURE__ */ jsxs(Fragment, { children: [
876
+ /* @__PURE__ */ jsx("line", { x1: "2", y1: "12", x2: "22", y2: "12", stroke: "currentColor", strokeWidth: "2" }),
877
+ /* @__PURE__ */ jsx("polygon", { points: "10,8 16,12 10,16", fill: "currentColor" })
878
+ ] }),
879
+ b_field_curve: /* @__PURE__ */ jsxs(Fragment, { children: [
880
+ /* @__PURE__ */ jsx("path", { d: "M 4 20 Q 12 2 20 20", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
881
+ /* @__PURE__ */ jsx("polygon", { points: "10,8 14,11 10,14", fill: "currentColor", transform: "rotate(30 12 11)" })
882
+ ] }),
883
+ bezier: /* @__PURE__ */ jsxs(Fragment, { children: [
884
+ /* @__PURE__ */ jsx("path", { d: "M 4 20 Q 4 4 20 4", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
885
+ /* @__PURE__ */ jsx("circle", { cx: "4", cy: "4", r: "2", fill: "currentColor" }),
886
+ /* @__PURE__ */ jsx("line", { x1: "4", y1: "20", x2: "4", y2: "4", stroke: "currentColor", strokeWidth: "1", strokeDasharray: "2 2" }),
887
+ /* @__PURE__ */ jsx("line", { x1: "20", y1: "4", x2: "4", y2: "4", stroke: "currentColor", strokeWidth: "1", strokeDasharray: "2 2" })
888
+ ] }),
889
+ current_wire: /* @__PURE__ */ jsxs(Fragment, { children: [
890
+ /* @__PURE__ */ jsx("line", { x1: "2", y1: "12", x2: "22", y2: "12", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" }),
891
+ /* @__PURE__ */ jsx("polygon", { points: "15,8 20,12 15,16", fill: "currentColor" })
892
+ ] }),
893
+ b_region_in: /* @__PURE__ */ jsxs(Fragment, { children: [
894
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "3", width: "18", height: "18", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeDasharray: "2 2" }),
895
+ /* @__PURE__ */ jsx("path", { d: "M 8 8 L 16 16 M 16 8 L 8 16", stroke: "currentColor", strokeWidth: "2" })
896
+ ] }),
897
+ b_region_out: /* @__PURE__ */ jsxs(Fragment, { children: [
898
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "3", width: "18", height: "18", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeDasharray: "2 2" }),
899
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "2", fill: "currentColor" })
900
+ ] }),
901
+ bar_magnet: /* @__PURE__ */ jsxs(Fragment, { children: [
902
+ /* @__PURE__ */ jsx("rect", { x: "2", y: "8", width: "20", height: "8", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
903
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "8", x2: "12", y2: "16", stroke: "currentColor", strokeWidth: "2" }),
904
+ /* @__PURE__ */ jsx("text", { x: "7", y: "15", fontSize: "7", fill: "currentColor", fontWeight: "bold", children: "N" }),
905
+ /* @__PURE__ */ jsx("text", { x: "17", y: "15", fontSize: "7", fill: "currentColor", fontWeight: "bold", children: "S" })
906
+ ] }),
907
+ coil: /* @__PURE__ */ jsx("path", { d: "M2 12 C 5 -2, 10 26, 12 12 C 14 -2, 19 26, 22 12", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinejoin: "round" }),
908
+ meter: /* @__PURE__ */ jsxs(Fragment, { children: [
909
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "8", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
910
+ /* @__PURE__ */ jsx("text", { x: "12", y: "16", fontSize: "10", fontWeight: "bold", textAnchor: "middle", fill: "currentColor", children: "G" })
911
+ ] }),
912
+ ac_source: /* @__PURE__ */ jsxs(Fragment, { children: [
913
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "8", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
914
+ /* @__PURE__ */ jsx("path", { d: "M 7 12 Q 9.5 8 12 12 T 17 12", fill: "none", stroke: "currentColor", strokeWidth: "2" })
915
+ ] }),
916
+ single_bond: /* @__PURE__ */ jsx("line", { x1: "4", y1: "18", x2: "20", y2: "6", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" }),
917
+ double_bond: /* @__PURE__ */ jsxs(Fragment, { children: [
918
+ /* @__PURE__ */ jsx("line", { x1: "3", y1: "15", x2: "17", y2: "3", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" }),
919
+ /* @__PURE__ */ jsx("line", { x1: "7", y1: "21", x2: "21", y2: "9", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round" })
920
+ ] }),
921
+ triple_bond: /* @__PURE__ */ jsxs(Fragment, { children: [
922
+ /* @__PURE__ */ jsx("line", { x1: "2", y1: "12", x2: "16", y2: "0", stroke: "currentColor", strokeWidth: "2" }),
923
+ /* @__PURE__ */ jsx("line", { x1: "5", y1: "16", x2: "19", y2: "4", stroke: "currentColor", strokeWidth: "2" }),
924
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "20", x2: "22", y2: "8", stroke: "currentColor", strokeWidth: "2" })
925
+ ] }),
926
+ wedge_bond: /* @__PURE__ */ jsx("polygon", { points: "4,18 20,4 22,8", fill: "currentColor" }),
927
+ dash_bond: /* @__PURE__ */ jsx("line", { x1: "4", y1: "18", x2: "20", y2: "6", stroke: "currentColor", strokeWidth: "2.5", strokeDasharray: "3 3" }),
928
+ benzene: /* @__PURE__ */ jsxs(Fragment, { children: [
929
+ /* @__PURE__ */ jsx("polygon", { points: "12,2 20.6,7 20.6,17 12,22 3.4,17 3.4,7", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
930
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "5", fill: "none", stroke: "currentColor", strokeWidth: "1.5" })
931
+ ] }),
932
+ cyclohexane: /* @__PURE__ */ jsx("polygon", { points: "12,2 20.6,7 20.6,17 12,22 3.4,17 3.4,7", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
933
+ cyclopentane: /* @__PURE__ */ jsx("polygon", { points: "12,2 22,9.5 18,21 6,21 2,9.5", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
934
+ cyclobutane: /* @__PURE__ */ jsx("rect", { x: "5", y: "5", width: "14", height: "14", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
935
+ cyclopropane: /* @__PURE__ */ jsx("polygon", { points: "12,4 22,18 2,18", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
936
+ reaction_arrow: /* @__PURE__ */ jsxs(Fragment, { children: [
937
+ /* @__PURE__ */ jsx("line", { x1: "2", y1: "12", x2: "20", y2: "12", stroke: "currentColor", strokeWidth: "2" }),
938
+ /* @__PURE__ */ jsx("polyline", { points: "14,6 22,12 14,18", fill: "none", stroke: "currentColor", strokeWidth: "2" })
939
+ ] }),
940
+ equilibrium_arrow: /* @__PURE__ */ jsxs(Fragment, { children: [
941
+ /* @__PURE__ */ jsx("line", { x1: "2", y1: "9", x2: "20", y2: "9", stroke: "currentColor", strokeWidth: "1.5" }),
942
+ /* @__PURE__ */ jsx("polyline", { points: "14,4 20,9", fill: "none", stroke: "currentColor", strokeWidth: "1.5" }),
943
+ /* @__PURE__ */ jsx("line", { x1: "4", y1: "15", x2: "22", y2: "15", stroke: "currentColor", strokeWidth: "1.5" }),
944
+ /* @__PURE__ */ jsx("polyline", { points: "10,20 4,15", fill: "none", stroke: "currentColor", strokeWidth: "1.5" })
945
+ ] }),
946
+ curved_arrow: /* @__PURE__ */ jsx("path", { d: "M 4 18 Q 12 4 20 18 L 16 16 M 20 18 L 22 14", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }),
947
+ resonance_arrow: /* @__PURE__ */ jsxs(Fragment, { children: [
948
+ /* @__PURE__ */ jsx("line", { x1: "4", y1: "12", x2: "20", y2: "12", stroke: "currentColor", strokeWidth: "2" }),
949
+ /* @__PURE__ */ jsx("polyline", { points: "8,6 2,12 8,18", fill: "none", stroke: "currentColor", strokeWidth: "2" }),
950
+ /* @__PURE__ */ jsx("polyline", { points: "16,6 22,12 16,18", fill: "none", stroke: "currentColor", strokeWidth: "2" })
951
+ ] }),
952
+ atom: /* @__PURE__ */ jsx("text", { x: "12", y: "18", fontSize: "18", textAnchor: "middle", fill: "currentColor", fontWeight: "bold", fontFamily: "sans-serif", children: "C" }),
953
+ charge_plus: /* @__PURE__ */ jsxs(Fragment, { children: [
954
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "8", fill: "none", stroke: "currentColor", strokeWidth: "1.5" }),
955
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "8", x2: "12", y2: "16", stroke: "currentColor", strokeWidth: "1.5" }),
956
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "12", x2: "16", y2: "12", stroke: "currentColor", strokeWidth: "1.5" })
957
+ ] }),
958
+ charge_minus: /* @__PURE__ */ jsxs(Fragment, { children: [
959
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "8", fill: "none", stroke: "currentColor", strokeWidth: "1.5" }),
960
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "12", x2: "16", y2: "12", stroke: "currentColor", strokeWidth: "1.5" })
961
+ ] }),
962
+ radical: /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "2.5", fill: "currentColor" }),
963
+ lone_pair: /* @__PURE__ */ jsxs(Fragment, { children: [
964
+ /* @__PURE__ */ jsx("circle", { cx: "8", cy: "12", r: "2", fill: "currentColor" }),
965
+ /* @__PURE__ */ jsx("circle", { cx: "16", cy: "12", r: "2", fill: "currentColor" })
966
+ ] }),
967
+ charge_pos: /* @__PURE__ */ jsxs(Fragment, { children: [
968
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "8", fill: "#fecaca", stroke: "#ef4444", strokeWidth: "2" }),
969
+ /* @__PURE__ */ jsx("path", { d: "M12 8v8M8 12h8", stroke: "#ef4444", strokeWidth: "2", strokeLinecap: "round" })
970
+ ] }),
971
+ charge_neg: /* @__PURE__ */ jsxs(Fragment, { children: [
972
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "8", fill: "#bfdbfe", stroke: "#3b82f6", strokeWidth: "2" }),
973
+ /* @__PURE__ */ jsx("path", { d: "M8 12h8", stroke: "#3b82f6", strokeWidth: "2", strokeLinecap: "round" })
974
+ ] }),
975
+ dipole: /* @__PURE__ */ jsxs(Fragment, { children: [
976
+ /* @__PURE__ */ jsx("circle", { cx: "5", cy: "12", r: "4", fill: "#fecaca", stroke: "#ef4444" }),
977
+ /* @__PURE__ */ jsx("circle", { cx: "19", cy: "12", r: "4", fill: "#bfdbfe", stroke: "#3b82f6" }),
978
+ /* @__PURE__ */ jsx("line", { x1: "9", y1: "12", x2: "15", y2: "12", stroke: "currentColor", strokeDasharray: "2 2" })
979
+ ] }),
980
+ charged_plate_pos: /* @__PURE__ */ jsxs(Fragment, { children: [
981
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "2", x2: "12", y2: "22", stroke: "#ef4444", strokeWidth: "6" }),
982
+ /* @__PURE__ */ jsx("path", { d: "M9 6h6M12 3v6 M9 12h6M12 9v6 M9 18h6M12 15v6", stroke: "#fff", strokeWidth: "1" })
983
+ ] }),
984
+ charged_plate_neg: /* @__PURE__ */ jsxs(Fragment, { children: [
985
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "2", x2: "12", y2: "22", stroke: "#3b82f6", strokeWidth: "6" }),
986
+ /* @__PURE__ */ jsx("path", { d: "M9 6h6 M9 12h6 M9 18h6", stroke: "#fff", strokeWidth: "1" })
987
+ ] }),
988
+ gaussian_sphere: /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9", fill: "#d1fae5", fillOpacity: "0.4", stroke: "#10b981", strokeWidth: "2", strokeDasharray: "3 3" }),
989
+ gaussian_cylinder: /* @__PURE__ */ jsxs(Fragment, { children: [
990
+ /* @__PURE__ */ jsx("ellipse", { cx: "12", cy: "4", rx: "7", ry: "2", fill: "none", stroke: "#10b981", strokeWidth: "1.5", strokeDasharray: "2 2" }),
991
+ /* @__PURE__ */ jsx("ellipse", { cx: "12", cy: "20", rx: "7", ry: "2", fill: "none", stroke: "#10b981", strokeWidth: "1.5", strokeDasharray: "2 2" }),
992
+ /* @__PURE__ */ jsx("path", { d: "M5 4v16M19 4v16", stroke: "#10b981", strokeWidth: "1.5", strokeDasharray: "2 2" })
993
+ ] }),
994
+ mirror_plane: /* @__PURE__ */ jsxs(Fragment, { children: [
995
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "2", x2: "12", y2: "22", stroke: "currentColor", strokeWidth: "2" }),
996
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "6", x2: "6", y2: "10", stroke: "currentColor" }),
997
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "12", x2: "6", y2: "16", stroke: "currentColor" }),
998
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "18", x2: "6", y2: "22", stroke: "currentColor" })
999
+ ] }),
1000
+ energy_level: /* @__PURE__ */ jsxs(Fragment, { children: [
1001
+ /* @__PURE__ */ jsx("line", { x1: "4", y1: "8", x2: "20", y2: "8", stroke: "currentColor", strokeWidth: "2" }),
1002
+ /* @__PURE__ */ jsx("line", { x1: "4", y1: "16", x2: "20", y2: "16", stroke: "currentColor", strokeWidth: "2" }),
1003
+ /* @__PURE__ */ jsx("text", { x: "12", y: "13", fontSize: "6", fill: "currentColor", textAnchor: "middle", children: "n" })
1004
+ ] })
1005
+ };
1006
+
1007
+ // src/editor/Toolbar.tsx
1008
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
1009
+ var Toolbar = ({ categories, tool, onSelect }) => {
1010
+ const isChemistryCategory = (name) => ["chemistry", "arrows", "rings", "symbols"].includes(name.toLowerCase());
1011
+ return /* @__PURE__ */ jsx2("aside", { className: "w-[108px] border-r border-slate-200 bg-gradient-to-b from-slate-50 to-white flex flex-col items-center py-3 gap-4 overflow-y-auto shrink-0", children: categories.map((category) => /* @__PURE__ */ jsxs2("section", { className: "flex flex-col items-center w-full px-2", children: [
1012
+ /* @__PURE__ */ jsx2("div", { className: "text-[10px] font-semibold uppercase tracking-[0.20em] text-slate-400 mb-2 w-full text-center border-b border-slate-200 pb-1.5", children: category.name }),
1013
+ /* @__PURE__ */ jsx2("div", { className: "flex flex-col gap-1.5 w-full items-center", children: category.tools.map((t) => {
1014
+ const chemistryTone = isChemistryCategory(category.name);
1015
+ const activeClass = chemistryTone ? "bg-teal-50 text-teal-700 border-teal-200 shadow-sm ring-1 ring-teal-100" : "bg-blue-50 text-blue-700 border-blue-200 shadow-sm ring-1 ring-blue-100";
1016
+ return /* @__PURE__ */ jsxs2(
1017
+ "button",
1018
+ {
1019
+ type: "button",
1020
+ onClick: () => onSelect(t.id),
1021
+ title: t.name,
1022
+ className: `p-2 rounded-xl border flex flex-col items-center gap-1 transition-all w-full ${tool === t.id ? activeClass : "text-slate-600 border-transparent hover:bg-slate-100 hover:border-slate-200"}`,
1023
+ children: [
1024
+ /* @__PURE__ */ jsx2("svg", { className: "w-5 h-5", viewBox: "0 0 24 24", children: Icons[t.id] ?? Icons.line }),
1025
+ /* @__PURE__ */ jsx2("span", { className: "text-[11px] font-medium tracking-tight leading-tight text-center", children: t.name })
1026
+ ]
1027
+ },
1028
+ t.id
1029
+ );
1030
+ }) })
1031
+ ] }, category.name)) });
1032
+ };
1033
+
1034
+ // src/editor/PropertiesPanel.tsx
1035
+ import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1036
+ var needsCurveHeight = (t) => ["gaussian_cylinder", "lens_convex", "lens_concave", "mirror_concave", "mirror_convex", "b_field_curve"].includes(t);
1037
+ var needsFontSize = (t) => ["text", "point", "charge_pos", "charge_neg", "point_mass", "com_indicator", "diatomic_gas", "mass_box"].includes(t);
1038
+ var needsRotationSize = (t) => ["point_mass", "com_indicator", "pivot"].includes(t);
1039
+ var needsWaveOscSize = (t) => ["pendulum", "mass_box"].includes(t);
1040
+ var needsWaveAmplitude = (t) => [
1041
+ "sine_wave",
1042
+ "standing_wave",
1043
+ "wave_pulse",
1044
+ "damped_wave",
1045
+ "beats_graph",
1046
+ "shm_graph",
1047
+ "energy_graph",
1048
+ "strobe_shm"
1049
+ ].includes(t);
1050
+ var needsWaveLoops = (t) => ["sine_wave", "standing_wave", "shm_graph", "energy_graph", "strobe_shm"].includes(t);
1051
+ var needsRollingFlags = (t) => t === "rolling_body";
1052
+ var needsCoils = (t) => t === "spring";
1053
+ var needsRotation = (t) => ["block", "cart"].includes(t);
1054
+ var PropertiesPanel = ({ element, onChange, onDelete, onClose }) => {
1055
+ if (!element) return null;
1056
+ return /* @__PURE__ */ jsxs3(
1057
+ "div",
1058
+ {
1059
+ id: "svg-engine-properties-panel",
1060
+ role: "region",
1061
+ "aria-label": "Element properties",
1062
+ className: "absolute right-6 top-6 w-80 bg-white/95 backdrop-blur rounded-xl shadow-2xl border border-slate-200 flex flex-col p-5 z-30 max-h-[80vh] overflow-y-auto",
1063
+ children: [
1064
+ /* @__PURE__ */ jsxs3("div", { className: "flex justify-between items-center border-b border-slate-100 pb-3 mb-4 sticky top-0 bg-white z-10", children: [
1065
+ /* @__PURE__ */ jsx3("h3", { className: "text-[11px] font-semibold text-blue-700 uppercase tracking-[0.18em]", children: "Properties" }),
1066
+ /* @__PURE__ */ jsx3("button", { type: "button", onClick: onClose, className: "text-slate-400 hover:text-slate-800", children: "\u2715" })
1067
+ ] }),
1068
+ /* @__PURE__ */ jsxs3("div", { className: "space-y-4", children: [
1069
+ /* @__PURE__ */ jsx3(
1070
+ "input",
1071
+ {
1072
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1073
+ value: String(element.label || ""),
1074
+ onChange: (e) => onChange("label", e.target.value),
1075
+ placeholder: "Label"
1076
+ }
1077
+ ),
1078
+ /* @__PURE__ */ jsx3(
1079
+ "input",
1080
+ {
1081
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1082
+ value: String(element.value || ""),
1083
+ onChange: (e) => onChange("value", e.target.value),
1084
+ placeholder: "Value"
1085
+ }
1086
+ ),
1087
+ /* @__PURE__ */ jsxs3("div", { className: "grid grid-cols-2 gap-3", children: [
1088
+ /* @__PURE__ */ jsx3(
1089
+ "input",
1090
+ {
1091
+ type: "color",
1092
+ value: String(element.color || "#0f172a"),
1093
+ onChange: (e) => onChange("color", e.target.value),
1094
+ className: "h-10 w-full rounded-lg border border-slate-200"
1095
+ }
1096
+ ),
1097
+ /* @__PURE__ */ jsx3(
1098
+ "input",
1099
+ {
1100
+ type: "number",
1101
+ className: "px-3 py-2 border border-slate-300 rounded-lg text-sm",
1102
+ value: Number(element.strokeWidth || 2),
1103
+ onChange: (e) => onChange("strokeWidth", Number(e.target.value))
1104
+ }
1105
+ )
1106
+ ] }),
1107
+ needsRotation(String(element.type)) && /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1108
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Rotation (degrees)" }),
1109
+ /* @__PURE__ */ jsx3(
1110
+ "input",
1111
+ {
1112
+ type: "number",
1113
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1114
+ value: Number(element.rotation ?? 0),
1115
+ onChange: (e) => onChange("rotation", Number(e.target.value))
1116
+ }
1117
+ )
1118
+ ] }),
1119
+ needsCurveHeight(String(element.type)) && /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1120
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: element.type === "gaussian_cylinder" ? "Cylinder half-height (curveHeight)" : "Curve height" }),
1121
+ /* @__PURE__ */ jsx3(
1122
+ "input",
1123
+ {
1124
+ type: "number",
1125
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1126
+ value: Number(
1127
+ element.curveHeight ?? (element.type === "b_field_curve" ? 50 : element.type === "gaussian_cylinder" || element.type === "mirror_concave" || element.type === "mirror_convex" ? 40 : 20)
1128
+ ),
1129
+ onChange: (e) => onChange("curveHeight", Number(e.target.value))
1130
+ }
1131
+ )
1132
+ ] }),
1133
+ String(element.type) === "bezier" && /* @__PURE__ */ jsxs3("label", { className: "flex items-center gap-2 text-sm text-slate-700", children: [
1134
+ /* @__PURE__ */ jsx3(
1135
+ "input",
1136
+ {
1137
+ type: "checkbox",
1138
+ checked: Boolean(element.showArrow),
1139
+ onChange: (e) => onChange("showArrow", e.target.checked)
1140
+ }
1141
+ ),
1142
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Show arrow on curve" })
1143
+ ] }),
1144
+ String(element.type) === "energy_level" && /* @__PURE__ */ jsx3(
1145
+ "input",
1146
+ {
1147
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1148
+ value: String(element.energy ?? ""),
1149
+ onChange: (e) => onChange("energy", e.target.value),
1150
+ placeholder: "Energy (e.g. -13.6 eV)"
1151
+ }
1152
+ ),
1153
+ needsFontSize(String(element.type)) && /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1154
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Font size" }),
1155
+ /* @__PURE__ */ jsx3(
1156
+ "input",
1157
+ {
1158
+ type: "number",
1159
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1160
+ value: Number(element.fontSize ?? 16),
1161
+ onChange: (e) => onChange("fontSize", Number(e.target.value))
1162
+ }
1163
+ )
1164
+ ] }),
1165
+ needsRotationSize(String(element.type)) && /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1166
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Size (radius / pivot scale)" }),
1167
+ /* @__PURE__ */ jsx3(
1168
+ "input",
1169
+ {
1170
+ type: "number",
1171
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1172
+ value: Number(element.size ?? 15),
1173
+ onChange: (e) => onChange("size", Number(e.target.value))
1174
+ }
1175
+ )
1176
+ ] }),
1177
+ needsWaveOscSize(String(element.type)) && /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1178
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: element.type === "mass_box" ? "Block size" : "Bob radius" }),
1179
+ /* @__PURE__ */ jsx3(
1180
+ "input",
1181
+ {
1182
+ type: "number",
1183
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1184
+ value: Number(element.size ?? (element.type === "mass_box" ? 30 : 15)),
1185
+ onChange: (e) => onChange("size", Number(e.target.value))
1186
+ }
1187
+ )
1188
+ ] }),
1189
+ needsRollingFlags(String(element.type)) && /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-2 text-sm text-slate-700", children: [
1190
+ /* @__PURE__ */ jsxs3("label", { className: "flex items-center gap-2", children: [
1191
+ /* @__PURE__ */ jsx3(
1192
+ "input",
1193
+ {
1194
+ type: "checkbox",
1195
+ checked: Boolean(element.showVelocity),
1196
+ onChange: (e) => onChange("showVelocity", e.target.checked)
1197
+ }
1198
+ ),
1199
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Show velocity (v)" })
1200
+ ] }),
1201
+ /* @__PURE__ */ jsxs3("label", { className: "flex items-center gap-2", children: [
1202
+ /* @__PURE__ */ jsx3(
1203
+ "input",
1204
+ {
1205
+ type: "checkbox",
1206
+ checked: Boolean(element.showOmega),
1207
+ onChange: (e) => onChange("showOmega", e.target.checked)
1208
+ }
1209
+ ),
1210
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Show angular velocity (\u03C9)" })
1211
+ ] })
1212
+ ] }),
1213
+ needsCoils(String(element.type)) && /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1214
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Coils" }),
1215
+ /* @__PURE__ */ jsx3(
1216
+ "input",
1217
+ {
1218
+ type: "number",
1219
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1220
+ value: Number(element.coils ?? 6),
1221
+ onChange: (e) => onChange("coils", Number(e.target.value))
1222
+ }
1223
+ )
1224
+ ] }),
1225
+ String(element.type) === "piston_cylinder" && /* @__PURE__ */ jsxs3(Fragment2, { children: [
1226
+ /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1227
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Compression (0.1\u20130.9)" }),
1228
+ /* @__PURE__ */ jsx3(
1229
+ "input",
1230
+ {
1231
+ type: "range",
1232
+ min: 0.1,
1233
+ max: 0.9,
1234
+ step: 0.05,
1235
+ className: "w-full",
1236
+ value: Number(element.compression ?? 0.5),
1237
+ onChange: (e) => onChange("compression", Number(e.target.value))
1238
+ }
1239
+ )
1240
+ ] }),
1241
+ /* @__PURE__ */ jsxs3("label", { className: "flex items-center gap-2 text-sm text-slate-700", children: [
1242
+ /* @__PURE__ */ jsx3(
1243
+ "input",
1244
+ {
1245
+ type: "checkbox",
1246
+ checked: Boolean(element.showHeat),
1247
+ onChange: (e) => onChange("showHeat", e.target.checked)
1248
+ }
1249
+ ),
1250
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Show heat source (Q)" })
1251
+ ] })
1252
+ ] }),
1253
+ String(element.type) === "heat_engine" && /* @__PURE__ */ jsxs3(Fragment2, { children: [
1254
+ /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1255
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Machine type" }),
1256
+ /* @__PURE__ */ jsxs3(
1257
+ "select",
1258
+ {
1259
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm bg-white",
1260
+ value: String(element.engineType ?? "engine"),
1261
+ onChange: (e) => onChange("engineType", e.target.value),
1262
+ children: [
1263
+ /* @__PURE__ */ jsx3("option", { value: "engine", children: "Heat engine" }),
1264
+ /* @__PURE__ */ jsx3("option", { value: "refrigerator", children: "Refrigerator / pump" })
1265
+ ]
1266
+ }
1267
+ )
1268
+ ] }),
1269
+ /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1270
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Efficiency (display)" }),
1271
+ /* @__PURE__ */ jsx3(
1272
+ "input",
1273
+ {
1274
+ type: "number",
1275
+ min: 0,
1276
+ max: 1,
1277
+ step: 0.05,
1278
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1279
+ value: Number(element.efficiency ?? 0.4),
1280
+ onChange: (e) => onChange("efficiency", Number(e.target.value))
1281
+ }
1282
+ )
1283
+ ] })
1284
+ ] }),
1285
+ String(element.type) === "thermo_process" && /* @__PURE__ */ jsxs3(Fragment2, { children: [
1286
+ /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1287
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Process type" }),
1288
+ /* @__PURE__ */ jsxs3(
1289
+ "select",
1290
+ {
1291
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm bg-white",
1292
+ value: String(element.processType ?? "isotherm"),
1293
+ onChange: (e) => onChange("processType", e.target.value),
1294
+ children: [
1295
+ /* @__PURE__ */ jsx3("option", { value: "isotherm", children: "Isothermal" }),
1296
+ /* @__PURE__ */ jsx3("option", { value: "adiabatic", children: "Adiabatic" }),
1297
+ /* @__PURE__ */ jsx3("option", { value: "isobaric", children: "Isobaric" }),
1298
+ /* @__PURE__ */ jsx3("option", { value: "isochoric", children: "Isochoric" })
1299
+ ]
1300
+ }
1301
+ )
1302
+ ] }),
1303
+ /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1304
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Line style" }),
1305
+ /* @__PURE__ */ jsxs3(
1306
+ "select",
1307
+ {
1308
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm bg-white",
1309
+ value: String(element.lineStyle ?? "solid"),
1310
+ onChange: (e) => onChange("lineStyle", e.target.value),
1311
+ children: [
1312
+ /* @__PURE__ */ jsx3("option", { value: "solid", children: "Solid" }),
1313
+ /* @__PURE__ */ jsx3("option", { value: "dashed", children: "Dashed" }),
1314
+ /* @__PURE__ */ jsx3("option", { value: "dotted", children: "Dotted" })
1315
+ ]
1316
+ }
1317
+ )
1318
+ ] })
1319
+ ] }),
1320
+ String(element.type) === "pv_axes" && /* @__PURE__ */ jsxs3("div", { className: "grid grid-cols-2 gap-3", children: [
1321
+ /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1322
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "X label (V)" }),
1323
+ /* @__PURE__ */ jsx3(
1324
+ "input",
1325
+ {
1326
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1327
+ value: String(element.xLabel ?? "V"),
1328
+ onChange: (e) => onChange("xLabel", e.target.value)
1329
+ }
1330
+ )
1331
+ ] }),
1332
+ /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1333
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Y label (P)" }),
1334
+ /* @__PURE__ */ jsx3(
1335
+ "input",
1336
+ {
1337
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1338
+ value: String(element.yLabel ?? "P"),
1339
+ onChange: (e) => onChange("yLabel", e.target.value)
1340
+ }
1341
+ )
1342
+ ] })
1343
+ ] }),
1344
+ String(element.type) === "maxwell_boltzmann" && /* @__PURE__ */ jsxs3("div", { className: "grid grid-cols-2 gap-3", children: [
1345
+ /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1346
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "T\u2081 (K)" }),
1347
+ /* @__PURE__ */ jsx3(
1348
+ "input",
1349
+ {
1350
+ type: "number",
1351
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1352
+ value: Number(element.t1 ?? 300),
1353
+ onChange: (e) => onChange("t1", Number(e.target.value))
1354
+ }
1355
+ )
1356
+ ] }),
1357
+ /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1358
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "T\u2082 (K)" }),
1359
+ /* @__PURE__ */ jsx3(
1360
+ "input",
1361
+ {
1362
+ type: "number",
1363
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1364
+ value: Number(element.t2 ?? 600),
1365
+ onChange: (e) => onChange("t2", Number(e.target.value))
1366
+ }
1367
+ )
1368
+ ] })
1369
+ ] }),
1370
+ String(element.type) === "diatomic_gas" && /* @__PURE__ */ jsxs3("label", { className: "flex items-center gap-2 text-sm text-slate-700", children: [
1371
+ /* @__PURE__ */ jsx3(
1372
+ "input",
1373
+ {
1374
+ type: "checkbox",
1375
+ checked: element.showRotations !== false,
1376
+ onChange: (e) => onChange("showRotations", e.target.checked)
1377
+ }
1378
+ ),
1379
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Show rotation DOF" })
1380
+ ] }),
1381
+ String(element.type) === "random_walk" && /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1382
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Steps" }),
1383
+ /* @__PURE__ */ jsx3(
1384
+ "input",
1385
+ {
1386
+ type: "number",
1387
+ min: 2,
1388
+ max: 30,
1389
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1390
+ value: Number(element.steps ?? 5),
1391
+ onChange: (e) => onChange("steps", Number(e.target.value))
1392
+ }
1393
+ )
1394
+ ] }),
1395
+ needsWaveAmplitude(String(element.type)) && /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1396
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Amplitude" }),
1397
+ /* @__PURE__ */ jsx3(
1398
+ "input",
1399
+ {
1400
+ type: "number",
1401
+ min: 1,
1402
+ max: 200,
1403
+ step: 1,
1404
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1405
+ value: Number(element.amplitude ?? 40),
1406
+ onChange: (e) => onChange("amplitude", Number(e.target.value))
1407
+ }
1408
+ )
1409
+ ] }),
1410
+ needsWaveLoops(String(element.type)) && /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1411
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Loops / waves (n)" }),
1412
+ /* @__PURE__ */ jsx3(
1413
+ "input",
1414
+ {
1415
+ type: "number",
1416
+ min: 0.5,
1417
+ max: 20,
1418
+ step: 0.5,
1419
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1420
+ value: Number(element.loops ?? 2),
1421
+ onChange: (e) => onChange("loops", Number(e.target.value))
1422
+ }
1423
+ )
1424
+ ] }),
1425
+ String(element.type) === "shm_graph" && /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1426
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Graph function" }),
1427
+ /* @__PURE__ */ jsxs3(
1428
+ "select",
1429
+ {
1430
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm bg-white",
1431
+ value: String(element.graphType ?? "x"),
1432
+ onChange: (e) => onChange("graphType", e.target.value),
1433
+ children: [
1434
+ /* @__PURE__ */ jsx3("option", { value: "x", children: "Position x(t)" }),
1435
+ /* @__PURE__ */ jsx3("option", { value: "v", children: "Velocity v(t)" }),
1436
+ /* @__PURE__ */ jsx3("option", { value: "a", children: "Acceleration a(t)" }),
1437
+ /* @__PURE__ */ jsx3("option", { value: "all", children: "Compare all three" })
1438
+ ]
1439
+ }
1440
+ )
1441
+ ] }),
1442
+ String(element.type) === "energy_graph" && /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1443
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Domain" }),
1444
+ /* @__PURE__ */ jsxs3(
1445
+ "select",
1446
+ {
1447
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm bg-white",
1448
+ value: String(element.domain ?? "time"),
1449
+ onChange: (e) => onChange("domain", e.target.value),
1450
+ children: [
1451
+ /* @__PURE__ */ jsx3("option", { value: "time", children: "Versus time (t)" }),
1452
+ /* @__PURE__ */ jsx3("option", { value: "position", children: "Versus position (x)" })
1453
+ ]
1454
+ }
1455
+ )
1456
+ ] }),
1457
+ String(element.type) === "pendulum" && /* @__PURE__ */ jsxs3("label", { className: "flex items-center gap-2 text-sm text-slate-700", children: [
1458
+ /* @__PURE__ */ jsx3(
1459
+ "input",
1460
+ {
1461
+ type: "checkbox",
1462
+ checked: Boolean(element.showForces),
1463
+ onChange: (e) => onChange("showForces", e.target.checked)
1464
+ }
1465
+ ),
1466
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Show force vectors" })
1467
+ ] }),
1468
+ String(element.type) === "phasor" && /* @__PURE__ */ jsxs3("label", { className: "flex items-center gap-2 text-sm text-slate-700", children: [
1469
+ /* @__PURE__ */ jsx3(
1470
+ "input",
1471
+ {
1472
+ type: "checkbox",
1473
+ checked: Boolean(element.showProjection),
1474
+ onChange: (e) => onChange("showProjection", e.target.checked)
1475
+ }
1476
+ ),
1477
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Show axis projections" })
1478
+ ] }),
1479
+ String(element.type) === "damped_wave" && /* @__PURE__ */ jsxs3(Fragment2, { children: [
1480
+ /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1481
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Damping (b/2m)" }),
1482
+ /* @__PURE__ */ jsx3(
1483
+ "input",
1484
+ {
1485
+ type: "number",
1486
+ min: 0,
1487
+ max: 0.1,
1488
+ step: 5e-3,
1489
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1490
+ value: Number(element.damping ?? 0.015),
1491
+ onChange: (e) => onChange("damping", Number(e.target.value))
1492
+ }
1493
+ )
1494
+ ] }),
1495
+ /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1496
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Angular frequency (\u03C9)" }),
1497
+ /* @__PURE__ */ jsx3(
1498
+ "input",
1499
+ {
1500
+ type: "number",
1501
+ min: 1,
1502
+ max: 50,
1503
+ step: 1,
1504
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1505
+ value: Number(element.frequency ?? 10),
1506
+ onChange: (e) => onChange("frequency", Number(e.target.value))
1507
+ }
1508
+ )
1509
+ ] })
1510
+ ] }),
1511
+ String(element.type) === "beats_graph" && /* @__PURE__ */ jsxs3(Fragment2, { children: [
1512
+ /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1513
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Carrier frequency (avg f)" }),
1514
+ /* @__PURE__ */ jsx3(
1515
+ "input",
1516
+ {
1517
+ type: "number",
1518
+ min: 5,
1519
+ max: 50,
1520
+ step: 1,
1521
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1522
+ value: Number(element.frequency ?? 15),
1523
+ onChange: (e) => onChange("frequency", Number(e.target.value))
1524
+ }
1525
+ )
1526
+ ] }),
1527
+ /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1528
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Beat frequency (\u0394f)" }),
1529
+ /* @__PURE__ */ jsx3(
1530
+ "input",
1531
+ {
1532
+ type: "number",
1533
+ min: 0.1,
1534
+ max: 10,
1535
+ step: 0.1,
1536
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1537
+ value: Number(element.beatFreq ?? 2),
1538
+ onChange: (e) => onChange("beatFreq", Number(e.target.value))
1539
+ }
1540
+ )
1541
+ ] })
1542
+ ] }),
1543
+ String(element.type) === "wavefronts" && /* @__PURE__ */ jsxs3(Fragment2, { children: [
1544
+ /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1545
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Velocity ratio (v_s / v)" }),
1546
+ /* @__PURE__ */ jsx3(
1547
+ "input",
1548
+ {
1549
+ type: "number",
1550
+ min: 0,
1551
+ max: 0.9,
1552
+ step: 0.1,
1553
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1554
+ value: Number(element.velocityRatio ?? 0.5),
1555
+ onChange: (e) => onChange("velocityRatio", Number(e.target.value))
1556
+ }
1557
+ )
1558
+ ] }),
1559
+ /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1560
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Rings" }),
1561
+ /* @__PURE__ */ jsx3(
1562
+ "input",
1563
+ {
1564
+ type: "number",
1565
+ min: 1,
1566
+ max: 20,
1567
+ step: 1,
1568
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1569
+ value: Number(element.rings ?? 5),
1570
+ onChange: (e) => onChange("rings", Number(e.target.value))
1571
+ }
1572
+ )
1573
+ ] })
1574
+ ] }),
1575
+ String(element.type) === "mach_cone" && /* @__PURE__ */ jsxs3("label", { className: "block space-y-1", children: [
1576
+ /* @__PURE__ */ jsx3("span", { className: "text-xs font-medium text-slate-600", children: "Mach number (M)" }),
1577
+ /* @__PURE__ */ jsx3(
1578
+ "input",
1579
+ {
1580
+ type: "number",
1581
+ min: 1.05,
1582
+ max: 5,
1583
+ step: 0.1,
1584
+ className: "w-full px-3 py-2 border border-slate-300 rounded-lg text-sm",
1585
+ value: Number(element.machNumber ?? 2),
1586
+ onChange: (e) => onChange("machNumber", Number(e.target.value))
1587
+ }
1588
+ )
1589
+ ] }),
1590
+ /* @__PURE__ */ jsx3(
1591
+ "button",
1592
+ {
1593
+ type: "button",
1594
+ onClick: onDelete,
1595
+ className: "w-full py-2 bg-red-50 text-red-600 hover:bg-red-100 rounded-lg text-sm font-semibold transition",
1596
+ children: "Delete Element"
1597
+ }
1598
+ )
1599
+ ] })
1600
+ ]
1601
+ }
1602
+ );
1603
+ };
1604
+
1605
+ // src/editor/JsonModal.tsx
1606
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1607
+ var JsonModal = ({ open, jsonText, setJsonText, onClose, onLoad }) => {
1608
+ if (!open) return null;
1609
+ return /* @__PURE__ */ jsx4("div", { className: "fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4", children: /* @__PURE__ */ jsxs4("div", { className: "bg-white rounded-lg shadow-xl w-full max-w-2xl flex flex-col max-h-full", children: [
1610
+ /* @__PURE__ */ jsxs4("div", { className: "px-6 py-4 border-b flex justify-between items-center", children: [
1611
+ /* @__PURE__ */ jsx4("h2", { className: "text-lg font-bold text-gray-800", children: "Diagram Data (JSON)" }),
1612
+ /* @__PURE__ */ jsx4("button", { onClick: onClose, className: "text-gray-500 hover:text-gray-800 font-bold", children: "\u2715" })
1613
+ ] }),
1614
+ /* @__PURE__ */ jsx4("div", { className: "p-6 flex-1 overflow-hidden flex flex-col gap-4", children: /* @__PURE__ */ jsx4("textarea", { value: jsonText, onChange: (e) => setJsonText(e.target.value), className: "w-full flex-1 min-h-[300px] p-4 font-mono text-sm border border-gray-300 rounded-md", spellCheck: "false" }) }),
1615
+ /* @__PURE__ */ jsxs4("div", { className: "px-6 py-4 border-t bg-gray-50 flex justify-end gap-3", children: [
1616
+ /* @__PURE__ */ jsx4("button", { onClick: onClose, className: "px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-200 rounded-md transition", children: "Cancel" }),
1617
+ /* @__PURE__ */ jsx4("button", { onClick: onLoad, className: "px-4 py-2 text-sm font-medium bg-blue-600 text-white hover:bg-blue-700 rounded-md transition shadow-sm", children: "Load Diagram" })
1618
+ ] })
1619
+ ] }) });
1620
+ };
1621
+
1622
+ // src/editor/presets/mechanics.ts
1623
+ var mechanics = {
1624
+ name: "Mechanics",
1625
+ elements: [
1626
+ { id: 1, type: "wedge", x1: 100, y1: 400, x2: 500, y2: 100, label: "M", value: "", color: "#0f172a", strokeWidth: 2 },
1627
+ { id: 2, type: "block", x1: 220, y1: 260, x2: 300, y2: 300, label: "m", value: "", color: "#0f172a", strokeWidth: 2, rotation: -37 },
1628
+ { id: 3, type: "vector", x1: 260, y1: 280, x2: 260, y2: 400, label: "mg", value: "", color: "#0f172a", strokeWidth: 2 },
1629
+ { id: 4, type: "vector", x1: 260, y1: 280, x2: 212, y2: 216, label: "N", value: "", color: "#0f172a", strokeWidth: 2 },
1630
+ { id: 5, type: "vector", x1: 260, y1: 280, x2: 180, y2: 340, label: "f", value: "", color: "#0f172a", strokeWidth: 2 },
1631
+ { id: 6, type: "arc", x1: 100, y1: 400, x2: 260, y2: 280, label: "\u03B8", value: "", color: "#0f172a", strokeWidth: 2 },
1632
+ { id: 7, type: "dashed", x1: 260, y1: 280, x2: 308, y2: 344, label: "", value: "", color: "#0f172a", strokeWidth: 2 },
1633
+ { id: 8, type: "dashed", x1: 260, y1: 280, x2: 340, y2: 220, label: "", value: "", color: "#0f172a", strokeWidth: 2 },
1634
+ { id: 9, type: "dimension", x1: 100, y1: 440, x2: 500, y2: 440, label: "L", value: "", color: "#0f172a", strokeWidth: 2 },
1635
+ { id: 10, type: "axes", x1: 60, y1: 100, x2: 60, y2: 100, label: "", value: "", color: "#0f172a", strokeWidth: 2 }
1636
+ ],
1637
+ toolCategories: [
1638
+ {
1639
+ name: "Sketch and forces",
1640
+ tools: [
1641
+ { id: "select", name: "Select" },
1642
+ { id: "string", name: "String / Line" },
1643
+ { id: "spring", name: "Spring" },
1644
+ { id: "vector", name: "Force Vector" },
1645
+ { id: "dashed", name: "Dashed Line" },
1646
+ { id: "dimension", name: "Dimension" },
1647
+ { id: "surface", name: "Rigid Surface" }
1648
+ ]
1649
+ },
1650
+ {
1651
+ name: "Rigid bodies",
1652
+ tools: [
1653
+ { id: "wedge", name: "Wedge / Incline" },
1654
+ { id: "axes", name: "Axes / Frame" },
1655
+ { id: "block", name: "Mass / Block" },
1656
+ { id: "cart", name: "Cart / Vehicle" },
1657
+ { id: "particle", name: "Point Mass" },
1658
+ { id: "disk", name: "Disk / Sphere" },
1659
+ { id: "rod", name: "Rod / Beam" },
1660
+ { id: "pulley", name: "Pulley" }
1661
+ ]
1662
+ },
1663
+ {
1664
+ name: "Points and labels",
1665
+ tools: [
1666
+ { id: "pivot", name: "Pivot / Hinge" },
1667
+ { id: "com", name: "Center of Mass" },
1668
+ { id: "arc", name: "Angle / Arc" },
1669
+ { id: "text", name: "Label" }
1670
+ ]
1671
+ }
1672
+ ]
1673
+ };
1674
+
1675
+ // src/editor/presets/circuit.ts
1676
+ var circuit = {
1677
+ name: "Circuit",
1678
+ elements: [
1679
+ { id: 1, type: "resistor", x1: 200, y1: 300, x2: 400, y2: 200, label: "R1", value: "60\u03A9" },
1680
+ { id: 2, type: "resistor", x1: 200, y1: 300, x2: 400, y2: 400, label: "R3", value: "300\u03A9" },
1681
+ { id: 3, type: "resistor", x1: 400, y1: 200, x2: 600, y2: 300, label: "R2", value: "100\u03A9" },
1682
+ { id: 4, type: "resistor", x1: 400, y1: 400, x2: 600, y2: 300, label: "R4", value: "500\u03A9" },
1683
+ { id: 5, type: "battery", x1: 400, y1: 400, x2: 400, y2: 200, label: "50V", value: "" },
1684
+ { id: 6, type: "wire", x1: 200, y1: 300, x2: 200, y2: 100, label: "", value: "" },
1685
+ { id: 7, type: "wire", x1: 200, y1: 100, x2: 340, y2: 100, label: "", value: "" },
1686
+ { id: 8, type: "meter_v", x1: 340, y1: 100, x2: 460, y2: 100, label: "", value: "" },
1687
+ { id: 9, type: "wire", x1: 460, y1: 100, x2: 600, y2: 100, label: "", value: "" },
1688
+ { id: 10, type: "wire", x1: 600, y1: 100, x2: 600, y2: 300, label: "", value: "" },
1689
+ { id: 11, type: "text", x1: 180, y1: 300, x2: 180, y2: 300, label: "S", value: "", fontFamily: "sans-serif", fontWeight: "bold", fontSize: 18 },
1690
+ { id: 12, type: "text", x1: 400, y1: 180, x2: 400, y2: 180, label: "P", value: "", fontFamily: "sans-serif", fontWeight: "bold", fontSize: 18 },
1691
+ { id: 13, type: "text", x1: 400, y1: 420, x2: 400, y2: 420, label: "Q", value: "", fontFamily: "sans-serif", fontWeight: "bold", fontSize: 18 },
1692
+ { id: 14, type: "text", x1: 620, y1: 300, x2: 620, y2: 300, label: "T", value: "", fontFamily: "sans-serif", fontWeight: "bold", fontSize: 18 }
1693
+ ],
1694
+ toolCategories: [
1695
+ {
1696
+ name: "Circuit",
1697
+ tools: [
1698
+ { id: "select", name: "Select / Move" },
1699
+ { id: "wire", name: "Wire" },
1700
+ { id: "resistor", name: "Resistor" },
1701
+ { id: "capacitor", name: "Capacitor" },
1702
+ { id: "inductor", name: "Inductor" },
1703
+ { id: "diode", name: "Diode" },
1704
+ { id: "battery", name: "Battery" },
1705
+ { id: "meter_v", name: "Voltmeter" },
1706
+ { id: "meter_a", name: "Ammeter" },
1707
+ { id: "ground", name: "Ground" },
1708
+ { id: "text", name: "Text Label" }
1709
+ ]
1710
+ }
1711
+ ]
1712
+ };
1713
+
1714
+ // src/editor/presets/thermo.ts
1715
+ var thermo = {
1716
+ name: "Thermodynamics",
1717
+ elements: [
1718
+ { id: 101, type: "text", x1: 50, y1: 40, x2: 50, y2: 40, label: "1. First Law (Piston/Cylinder)", fontSize: 20, color: "#1e293b" },
1719
+ {
1720
+ id: 1,
1721
+ type: "piston_cylinder",
1722
+ x1: 80,
1723
+ y1: 100,
1724
+ x2: 240,
1725
+ y2: 260,
1726
+ compression: 0.6,
1727
+ showHeat: true,
1728
+ color: "#0ea5e9",
1729
+ strokeWidth: 2,
1730
+ label: "Gas Expansion"
1731
+ },
1732
+ { id: 102, type: "text", x1: 380, y1: 40, x2: 380, y2: 40, label: "2. Heat Engine & 2nd Law", fontSize: 20, color: "#1e293b" },
1733
+ {
1734
+ id: 2,
1735
+ type: "heat_engine",
1736
+ x1: 440,
1737
+ y1: 80,
1738
+ x2: 540,
1739
+ y2: 260,
1740
+ engineType: "engine",
1741
+ efficiency: 0.4,
1742
+ color: "#10b981",
1743
+ strokeWidth: 2,
1744
+ label: "Carnot Engine"
1745
+ },
1746
+ { id: 103, type: "text", x1: 700, y1: 40, x2: 700, y2: 40, label: "3. P-V Diagrams", fontSize: 20, color: "#1e293b" },
1747
+ {
1748
+ id: 3,
1749
+ type: "pv_axes",
1750
+ x1: 720,
1751
+ y1: 260,
1752
+ x2: 920,
1753
+ y2: 80,
1754
+ color: "#1e293b",
1755
+ strokeWidth: 2,
1756
+ label: "P vs V",
1757
+ xLabel: "V",
1758
+ yLabel: "P"
1759
+ },
1760
+ { id: 4, type: "carnot_cycle", x1: 760, y1: 120, x2: 880, y2: 220, color: "#ec4899", strokeWidth: 2 },
1761
+ { id: 104, type: "text", x1: 50, y1: 340, x2: 50, y2: 340, label: "4. Kinetic Theory & Speeds", fontSize: 20, color: "#1e293b" },
1762
+ {
1763
+ id: 5,
1764
+ type: "maxwell_boltzmann",
1765
+ x1: 80,
1766
+ y1: 520,
1767
+ x2: 320,
1768
+ y2: 380,
1769
+ t1: 300,
1770
+ t2: 600,
1771
+ color: "#8b5cf6",
1772
+ strokeWidth: 2,
1773
+ label: "f(v) vs v"
1774
+ },
1775
+ {
1776
+ id: 6,
1777
+ type: "diatomic_gas",
1778
+ x1: 400,
1779
+ y1: 440,
1780
+ x2: 500,
1781
+ y2: 440,
1782
+ color: "#f59e0b",
1783
+ strokeWidth: 2,
1784
+ label: "Diatomic (5 DOF)",
1785
+ showRotations: true
1786
+ },
1787
+ { id: 105, type: "text", x1: 700, y1: 340, x2: 700, y2: 340, label: "5. Thermal Conduction", fontSize: 20, color: "#1e293b" },
1788
+ {
1789
+ id: 7,
1790
+ type: "conduction_rod",
1791
+ x1: 700,
1792
+ y1: 420,
1793
+ x2: 900,
1794
+ y2: 460,
1795
+ color: "#3b82f6",
1796
+ strokeWidth: 2,
1797
+ label: "L, k, A"
1798
+ }
1799
+ ],
1800
+ toolCategories: [
1801
+ {
1802
+ name: "Basics",
1803
+ tools: [
1804
+ { id: "select", name: "Select" },
1805
+ { id: "point", name: "Node / Label" },
1806
+ { id: "line", name: "Line / Axis" },
1807
+ { id: "text", name: "Text Box" }
1808
+ ]
1809
+ },
1810
+ {
1811
+ name: "Systems",
1812
+ tools: [
1813
+ { id: "piston_cylinder", name: "Piston & Gas" },
1814
+ { id: "heat_engine", name: "Heat Engine" },
1815
+ { id: "conduction_rod", name: "Thermal Rod" }
1816
+ ]
1817
+ },
1818
+ {
1819
+ name: "PV Diagrams",
1820
+ tools: [
1821
+ { id: "pv_axes", name: "P-V Axes" },
1822
+ { id: "thermo_process", name: "Thermodynamic Path" },
1823
+ { id: "carnot_cycle", name: "Carnot Cycle" }
1824
+ ]
1825
+ },
1826
+ {
1827
+ name: "KTG",
1828
+ tools: [
1829
+ { id: "maxwell_boltzmann", name: "Maxwell Dist." },
1830
+ { id: "diatomic_gas", name: "Diatomic DOF" },
1831
+ { id: "random_walk", name: "Random Walk" }
1832
+ ]
1833
+ }
1834
+ ]
1835
+ };
1836
+
1837
+ // src/editor/presets/optical.ts
1838
+ var optical = {
1839
+ name: "Optical",
1840
+ elements: [
1841
+ { id: 1, type: "line", x1: 50, y1: 300, x2: 750, y2: 300, lineStyle: "dashed", color: "#94a3b8", strokeWidth: 2 },
1842
+ { id: 2, type: "lens_convex", x1: 400, y1: 150, x2: 400, y2: 450, color: "#38bdf8", strokeWidth: 2 },
1843
+ { id: 3, type: "point", x1: 250, y1: 300, x2: 250, y2: 300, label: "2F\u2081", color: "#64748b" },
1844
+ { id: 4, type: "point", x1: 325, y1: 300, x2: 325, y2: 300, label: "F\u2081", color: "#64748b" },
1845
+ { id: 5, type: "point", x1: 475, y1: 300, x2: 475, y2: 300, label: "F\u2082", color: "#64748b" },
1846
+ { id: 6, type: "point", x1: 550, y1: 300, x2: 550, y2: 300, label: "2F\u2082", color: "#64748b" },
1847
+ { id: 7, type: "vector", x1: 250, y1: 300, x2: 250, y2: 200, label: "O", color: "#10b981", strokeWidth: 3 },
1848
+ { id: 8, type: "ray", x1: 250, y1: 200, x2: 400, y2: 200, color: "#ef4444", strokeWidth: 2 },
1849
+ { id: 9, type: "ray", x1: 400, y1: 200, x2: 625, y2: 500, color: "#ef4444", strokeWidth: 2 },
1850
+ { id: 10, type: "ray", x1: 250, y1: 200, x2: 625, y2: 450, color: "#ef4444", strokeWidth: 2 },
1851
+ { id: 11, type: "vector", x1: 550, y1: 300, x2: 550, y2: 400, label: "I", color: "#f59e0b", strokeWidth: 3, lineStyle: "dashed" },
1852
+ { id: 12, type: "nucleus", x1: 120, y1: 500, x2: 120, y2: 500, label: "Atom", color: "#3b82f6", strokeWidth: 2 },
1853
+ { id: 13, type: "photon", x1: 160, y1: 500, x2: 280, y2: 460, label: "\u03B3", color: "#8b5cf6", strokeWidth: 2 },
1854
+ { id: 14, type: "slit_double", x1: 600, y1: 460, x2: 600, y2: 580, color: "#0f172a", strokeWidth: 4 },
1855
+ { id: 15, type: "photon", x1: 510, y1: 520, x2: 590, y2: 520, label: "\u03BB", color: "#eab308", strokeWidth: 2 }
1856
+ ],
1857
+ toolCategories: [
1858
+ {
1859
+ name: "Basics",
1860
+ tools: [
1861
+ { id: "select", name: "Select/Move" },
1862
+ { id: "point", name: "Point/Node" },
1863
+ { id: "line", name: "Solid Line" },
1864
+ { id: "vector", name: "Vector/Object" },
1865
+ { id: "text", name: "Text Label" }
1866
+ ]
1867
+ },
1868
+ {
1869
+ name: "Optics",
1870
+ tools: [
1871
+ { id: "ray", name: "Light Ray" },
1872
+ { id: "lens_convex", name: "Convex Lens" },
1873
+ { id: "lens_concave", name: "Concave Lens" },
1874
+ { id: "mirror_plane", name: "Plane Mirror" },
1875
+ { id: "mirror_concave", name: "Concave Mirror" },
1876
+ { id: "mirror_convex", name: "Convex Mirror" },
1877
+ { id: "prism", name: "Glass Prism" },
1878
+ { id: "glass_slab", name: "Glass Slab" }
1879
+ ]
1880
+ },
1881
+ {
1882
+ name: "Modern Physics",
1883
+ tools: [
1884
+ { id: "photon", name: "Photon (Wavy)" },
1885
+ { id: "slit_double", name: "Double Slit" },
1886
+ { id: "slit_single", name: "Single Slit" },
1887
+ { id: "energy_level", name: "Energy Level" },
1888
+ { id: "nucleus", name: "Atom/Nucleus" }
1889
+ ]
1890
+ }
1891
+ ]
1892
+ };
1893
+
1894
+ // src/editor/presets/magnetism.ts
1895
+ var magnetism = {
1896
+ name: "Magnetism",
1897
+ elements: [
1898
+ { id: 1, type: "pole_piece", x1: 100, y1: 80, x2: 200, y2: 300, label: "N", color: "#0f172a", strokeWidth: 2 },
1899
+ { id: 2, type: "pole_piece", x1: 500, y1: 80, x2: 600, y2: 300, label: "S", color: "#0f172a", strokeWidth: 2 },
1900
+ { id: 3, type: "b_field_line", x1: 200, y1: 120, x2: 500, y2: 120, label: "", color: "#10b981", strokeWidth: 2 },
1901
+ { id: 4, type: "b_field_line", x1: 200, y1: 190, x2: 500, y2: 190, label: "B", color: "#10b981", strokeWidth: 2, fontSize: 18 },
1902
+ { id: 5, type: "b_field_line", x1: 200, y1: 260, x2: 500, y2: 260, label: "", color: "#10b981", strokeWidth: 2 },
1903
+ { id: 6, type: "b_field_curve", x1: 280, y1: 80, x2: 420, y2: 80, curveHeight: 50, label: "", color: "#10b981", strokeWidth: 2 },
1904
+ { id: 7, type: "b_field_curve", x1: 250, y1: 80, x2: 450, y2: 80, curveHeight: 110, label: "", color: "#10b981", strokeWidth: 2 },
1905
+ { id: 8, type: "axes_3d", x1: 200, y1: 540, x2: 300, y2: 540, label: "", color: "#64748b", strokeWidth: 2, fontSize: 16 },
1906
+ { id: 9, type: "line", x1: 200, y1: 540, x2: 200, y2: 400, label: "", color: "#0ea5e9", strokeWidth: 3 },
1907
+ { id: 10, type: "line", x1: 200, y1: 400, x2: 320, y2: 400, label: "i", color: "#0ea5e9", strokeWidth: 3, fontSize: 16 },
1908
+ { id: 11, type: "line", x1: 320, y1: 400, x2: 320, y2: 540, label: "", color: "#0ea5e9", strokeWidth: 3 },
1909
+ { id: 12, type: "line", x1: 320, y1: 540, x2: 200, y2: 540, label: "", color: "#0ea5e9", strokeWidth: 3 },
1910
+ { id: 13, type: "vector", x1: 200, y1: 540, x2: 320, y2: 620, label: "B", color: "#10b981", strokeWidth: 2.5, fontSize: 18 }
1911
+ ],
1912
+ toolCategories: [
1913
+ {
1914
+ name: "Basics",
1915
+ tools: [
1916
+ { id: "select", name: "Select/Move" },
1917
+ { id: "point", name: "Point/Node" },
1918
+ { id: "line", name: "Solid Line" },
1919
+ { id: "vector", name: "Vector/Force" },
1920
+ { id: "text", name: "Text Label" }
1921
+ ]
1922
+ },
1923
+ {
1924
+ name: "Magnetism",
1925
+ tools: [
1926
+ { id: "axes_3d", name: "3D Axes (x,y,z)" },
1927
+ { id: "angle", name: "Angle/Arc" },
1928
+ { id: "b_field_line", name: "B-Line (Straight)" },
1929
+ { id: "b_field_curve", name: "B-Line (Curved)" },
1930
+ { id: "bezier", name: "Bezier Curve" },
1931
+ { id: "pole_piece", name: "Pole Piece (N/S)" },
1932
+ { id: "b_region_in", name: "B-Field (IN)" },
1933
+ { id: "b_region_out", name: "B-Field (OUT)" },
1934
+ { id: "current_wire", name: "Wire (with I)" }
1935
+ ]
1936
+ },
1937
+ {
1938
+ name: "Magnets & circuits",
1939
+ tools: [
1940
+ { id: "bar_magnet", name: "Bar Magnet" },
1941
+ { id: "coil", name: "Coil/Inductor" },
1942
+ { id: "charge_plus", name: "+ Charge" },
1943
+ { id: "charge_minus", name: "- Charge" },
1944
+ { id: "resistor", name: "Resistor" },
1945
+ { id: "capacitor", name: "Capacitor" },
1946
+ { id: "ac_source", name: "AC Source" },
1947
+ { id: "meter", name: "Galvano/Meter" },
1948
+ { id: "ground", name: "Ground" }
1949
+ ]
1950
+ },
1951
+ {
1952
+ name: "Drawing",
1953
+ tools: [
1954
+ { id: "circle", name: "Circle/Loop" },
1955
+ { id: "axes", name: "2D Axes" }
1956
+ ]
1957
+ }
1958
+ ]
1959
+ };
1960
+
1961
+ // src/editor/presets/lightTopics.ts
1962
+ var LIGHT_TOPICS = [
1963
+ {
1964
+ name: "Ch 34: Lens Combination (JEE Classic)",
1965
+ elements: [
1966
+ { id: 1, type: "line", x1: 50, y1: 300, x2: 850, y2: 300, lineStyle: "dashed", color: "#94a3b8", strokeWidth: 2 },
1967
+ { id: 2, type: "lens_convex", x1: 300, y1: 150, x2: 300, y2: 450, color: "#38bdf8", strokeWidth: 2, label: "f\u2081 = +30cm" },
1968
+ { id: 3, type: "lens_concave", x1: 500, y1: 150, x2: 500, y2: 450, color: "#38bdf8", strokeWidth: 2, label: "f\u2082 = -10cm" },
1969
+ { id: 4, type: "ray", x1: 50, y1: 200, x2: 300, y2: 200, color: "#ef4444", strokeWidth: 2 },
1970
+ { id: 5, type: "ray", x1: 50, y1: 400, x2: 300, y2: 400, color: "#ef4444", strokeWidth: 2 },
1971
+ { id: 6, type: "ray", x1: 300, y1: 200, x2: 500, y2: 266, color: "#ef4444", strokeWidth: 2 },
1972
+ { id: 7, type: "ray", x1: 300, y1: 400, x2: 500, y2: 334, color: "#ef4444", strokeWidth: 2 },
1973
+ { id: 8, type: "ray", x1: 500, y1: 266, x2: 800, y2: 266, color: "#ef4444", strokeWidth: 2 },
1974
+ { id: 9, type: "ray", x1: 500, y1: 334, x2: 800, y2: 334, color: "#ef4444", strokeWidth: 2 },
1975
+ { id: 10, type: "line", x1: 500, y1: 266, x2: 600, y2: 300, lineStyle: "dashed", color: "#ef4444", strokeWidth: 2 },
1976
+ { id: 11, type: "line", x1: 500, y1: 334, x2: 600, y2: 300, lineStyle: "dashed", color: "#ef4444", strokeWidth: 2 },
1977
+ { id: 12, type: "point", x1: 600, y1: 300, x2: 600, y2: 300, label: "Virtual Object", color: "#64748b" }
1978
+ ]
1979
+ },
1980
+ {
1981
+ name: "Ch 34: Concave Mirror (Real Image)",
1982
+ elements: [
1983
+ { id: 1, type: "line", x1: 50, y1: 300, x2: 700, y2: 300, lineStyle: "dashed", color: "#94a3b8", strokeWidth: 2 },
1984
+ { id: 2, type: "mirror_concave", x1: 600, y1: 150, x2: 600, y2: 450, curveHeight: 40, color: "#0f172a", strokeWidth: 2 },
1985
+ { id: 3, type: "point", x1: 400, y1: 300, x2: 400, y2: 300, label: "C", color: "#64748b" },
1986
+ { id: 4, type: "point", x1: 500, y1: 300, x2: 500, y2: 300, label: "F", color: "#64748b" },
1987
+ { id: 5, type: "vector", x1: 300, y1: 300, x2: 300, y2: 200, label: "O", color: "#10b981", strokeWidth: 3 },
1988
+ { id: 6, type: "ray", x1: 300, y1: 200, x2: 600, y2: 200, color: "#ef4444", strokeWidth: 2 },
1989
+ { id: 7, type: "ray", x1: 600, y1: 200, x2: 400, y2: 400, color: "#ef4444", strokeWidth: 2 },
1990
+ { id: 8, type: "ray", x1: 300, y1: 200, x2: 400, y2: 300, color: "#3b82f6", strokeWidth: 2 },
1991
+ { id: 9, type: "ray", x1: 400, y1: 300, x2: 600, y2: 500, color: "#3b82f6", strokeWidth: 2 },
1992
+ { id: 10, type: "ray", x1: 600, y1: 500, x2: 450, y2: 350, color: "#3b82f6", strokeWidth: 2 },
1993
+ { id: 11, type: "vector", x1: 450, y1: 300, x2: 450, y2: 350, label: "I", color: "#f59e0b", strokeWidth: 3 }
1994
+ ]
1995
+ },
1996
+ {
1997
+ name: "Ch 34: Apparent Depth (Refraction)",
1998
+ elements: [
1999
+ { id: 1, type: "glass_slab", x1: 50, y1: 300, x2: 850, y2: 600, color: "#38bdf8", label: "Water (\u03BC = 4/3)", strokeWidth: 2 },
2000
+ { id: 2, type: "point", x1: 450, y1: 500, x2: 450, y2: 500, label: "Real Object", color: "#0f172a" },
2001
+ { id: 3, type: "ray", x1: 450, y1: 500, x2: 450, y2: 300, color: "#ef4444", strokeWidth: 2 },
2002
+ { id: 4, type: "ray", x1: 450, y1: 300, x2: 450, y2: 100, color: "#ef4444", strokeWidth: 2 },
2003
+ { id: 5, type: "ray", x1: 450, y1: 500, x2: 550, y2: 300, color: "#ef4444", strokeWidth: 2 },
2004
+ { id: 6, type: "ray", x1: 550, y1: 300, x2: 700, y2: 150, color: "#ef4444", strokeWidth: 2 },
2005
+ { id: 7, type: "line", x1: 550, y1: 300, x2: 450, y2: 400, lineStyle: "dashed", color: "#ef4444", strokeWidth: 2 },
2006
+ { id: 8, type: "point", x1: 450, y1: 400, x2: 450, y2: 400, label: "Virtual Image", color: "#f59e0b" },
2007
+ { id: 9, type: "line", x1: 550, y1: 200, x2: 550, y2: 400, lineStyle: "dashed", color: "#94a3b8", strokeWidth: 1 }
2008
+ ]
2009
+ },
2010
+ {
2011
+ name: "Ch 35: Young's Double Slit (YDSE)",
2012
+ elements: [
2013
+ { id: 1, type: "slit_double", x1: 200, y1: 200, x2: 200, y2: 400, color: "#0f172a", strokeWidth: 4 },
2014
+ { id: 2, type: "line", x1: 700, y1: 100, x2: 700, y2: 500, color: "#0f172a", strokeWidth: 4, label: "Screen" },
2015
+ { id: 3, type: "line", x1: 200, y1: 300, x2: 700, y2: 300, lineStyle: "dashed", color: "#94a3b8", strokeWidth: 2 },
2016
+ { id: 4, type: "point", x1: 200, y1: 250, x2: 200, y2: 250, label: "S\u2081", color: "#0f172a" },
2017
+ { id: 5, type: "point", x1: 200, y1: 350, x2: 200, y2: 350, label: "S\u2082", color: "#0f172a" },
2018
+ { id: 6, type: "point", x1: 700, y1: 150, x2: 700, y2: 150, label: "P (Maxima/Minima)", color: "#0f172a" },
2019
+ { id: 7, type: "photon", x1: 200, y1: 250, x2: 700, y2: 150, color: "#eab308", strokeWidth: 2 },
2020
+ { id: 8, type: "photon", x1: 200, y1: 350, x2: 700, y2: 150, color: "#eab308", strokeWidth: 2 },
2021
+ { id: 9, type: "line", x1: 200, y1: 250, x2: 240, y2: 340, lineStyle: "dashed", color: "#ef4444", strokeWidth: 2 },
2022
+ { id: 10, type: "text", x1: 250, y1: 370, x2: 250, y2: 370, label: "\u0394x = d sin \u03B8", color: "#ef4444", fontSize: 18 },
2023
+ { id: 11, type: "text", x1: 450, y1: 280, x2: 450, y2: 280, label: "D", color: "#64748b", fontSize: 20 },
2024
+ { id: 12, type: "line", x1: 720, y1: 300, x2: 720, y2: 150, lineStyle: "solid", color: "#64748b", strokeWidth: 2 },
2025
+ { id: 13, type: "text", x1: 740, y1: 225, x2: 740, y2: 225, label: "y", color: "#64748b", fontSize: 18 }
2026
+ ]
2027
+ },
2028
+ {
2029
+ name: "Ch 36: Single Slit Diffraction",
2030
+ elements: [
2031
+ { id: 1, type: "slit_single", x1: 300, y1: 200, x2: 300, y2: 400, color: "#0f172a", strokeWidth: 5, label: "Width a" },
2032
+ { id: 2, type: "line", x1: 700, y1: 100, x2: 700, y2: 500, color: "#0f172a", strokeWidth: 4 },
2033
+ { id: 3, type: "line", x1: 100, y1: 300, x2: 700, y2: 300, lineStyle: "dashed", color: "#94a3b8", strokeWidth: 2 },
2034
+ { id: 4, type: "photon", x1: 100, y1: 220, x2: 300, y2: 220, color: "#8b5cf6", strokeWidth: 2 },
2035
+ { id: 5, type: "photon", x1: 100, y1: 380, x2: 300, y2: 380, color: "#8b5cf6", strokeWidth: 2 },
2036
+ { id: 6, type: "ray", x1: 300, y1: 220, x2: 700, y2: 300, color: "#ef4444", strokeWidth: 2 },
2037
+ { id: 7, type: "ray", x1: 300, y1: 380, x2: 700, y2: 300, color: "#ef4444", strokeWidth: 2 },
2038
+ { id: 8, type: "ray", x1: 300, y1: 220, x2: 700, y2: 150, color: "#3b82f6", strokeWidth: 2 },
2039
+ { id: 9, type: "ray", x1: 300, y1: 380, x2: 700, y2: 150, color: "#3b82f6", strokeWidth: 2 },
2040
+ { id: 10, type: "point", x1: 700, y1: 300, x2: 700, y2: 300, label: "Central Max", color: "#ef4444" },
2041
+ { id: 11, type: "point", x1: 700, y1: 150, x2: 700, y2: 150, label: "1st Min (a sin \u03B8 = \u03BB)", color: "#3b82f6" }
2042
+ ]
2043
+ }
2044
+ ];
2045
+
2046
+ // src/editor/presets/light.ts
2047
+ var light = {
2048
+ name: "Light",
2049
+ elements: LIGHT_TOPICS[0].elements,
2050
+ toolCategories: [
2051
+ {
2052
+ name: "Basics",
2053
+ tools: [
2054
+ { id: "select", name: "Select/Move" },
2055
+ { id: "point", name: "Point/Node" },
2056
+ { id: "line", name: "Solid Line" },
2057
+ { id: "vector", name: "Vector/Object" },
2058
+ { id: "text", name: "Text Label" }
2059
+ ]
2060
+ },
2061
+ {
2062
+ name: "Optics",
2063
+ tools: [
2064
+ { id: "ray", name: "Light Ray" },
2065
+ { id: "lens_convex", name: "Convex Lens" },
2066
+ { id: "lens_concave", name: "Concave Lens" },
2067
+ { id: "mirror_plane", name: "Plane Mirror" },
2068
+ { id: "mirror_concave", name: "Concave Mirror" },
2069
+ { id: "mirror_convex", name: "Convex Mirror" },
2070
+ { id: "prism", name: "Glass Prism" },
2071
+ { id: "glass_slab", name: "Glass Slab" }
2072
+ ]
2073
+ },
2074
+ {
2075
+ name: "Modern Physics",
2076
+ tools: [
2077
+ { id: "photon", name: "Photon (Wavy)" },
2078
+ { id: "slit_double", name: "Double Slit" },
2079
+ { id: "slit_single", name: "Single Slit" },
2080
+ { id: "energy_level", name: "Energy Level" },
2081
+ { id: "nucleus", name: "Atom/Nucleus" }
2082
+ ]
2083
+ }
2084
+ ]
2085
+ };
2086
+
2087
+ // src/editor/presets/waves.ts
2088
+ var waves = {
2089
+ name: "Waves",
2090
+ elements: [
2091
+ { id: 1, type: "line", x1: 100, y1: 300, x2: 800, y2: 300, color: "#64748b", strokeWidth: 2 },
2092
+ { id: 2, type: "slit_double", x1: 200, y1: 200, x2: 200, y2: 400, color: "#0f172a", strokeWidth: 4 },
2093
+ { id: 3, type: "photon", x1: 200, y1: 250, x2: 700, y2: 150, color: "#eab308", strokeWidth: 2 }
2094
+ ],
2095
+ toolCategories: [{ name: "Waves", tools: [{ id: "select", name: "Select" }, { id: "line", name: "Axis" }, { id: "slit_double", name: "Double Slit" }, { id: "photon", name: "Wave Ray" }, { id: "text", name: "Text" }] }]
2096
+ };
2097
+
2098
+ // src/editor/presets/waveOscillation.ts
2099
+ var waveOscillation = {
2100
+ name: "Oscillations & Waves",
2101
+ elements: [
2102
+ { id: 101, type: "text", x1: 50, y1: 40, x2: 50, y2: 40, label: "1. SHM Kinematics & Freeze-Frames", fontSize: 20, color: "#1e293b" },
2103
+ {
2104
+ id: 1,
2105
+ type: "strobe_shm",
2106
+ x1: 120,
2107
+ y1: 80,
2108
+ x2: 120,
2109
+ y2: 280,
2110
+ amplitude: 60,
2111
+ loops: 1,
2112
+ color: "#f59e0b",
2113
+ strokeWidth: 2,
2114
+ label: "Motion"
2115
+ },
2116
+ {
2117
+ id: 2,
2118
+ type: "shm_graph",
2119
+ x1: 260,
2120
+ y1: 180,
2121
+ x2: 460,
2122
+ y2: 180,
2123
+ amplitude: 60,
2124
+ loops: 1,
2125
+ graphType: "all",
2126
+ color: "#1e293b",
2127
+ strokeWidth: 2,
2128
+ label: "x(t), v(t), a(t)"
2129
+ },
2130
+ { id: 102, type: "text", x1: 540, y1: 40, x2: 540, y2: 40, label: "2. Oscillators & Projections", fontSize: 20, color: "#1e293b" },
2131
+ {
2132
+ id: 3,
2133
+ type: "pendulum",
2134
+ x1: 600,
2135
+ y1: 80,
2136
+ x2: 660,
2137
+ y2: 220,
2138
+ label: "m",
2139
+ color: "#0ea5e9",
2140
+ strokeWidth: 2,
2141
+ size: 15,
2142
+ showForces: true
2143
+ },
2144
+ {
2145
+ id: 4,
2146
+ type: "phasor",
2147
+ x1: 800,
2148
+ y1: 150,
2149
+ x2: 860,
2150
+ y2: 90,
2151
+ label: "\u03C9t",
2152
+ color: "#8b5cf6",
2153
+ strokeWidth: 2,
2154
+ showProjection: true
2155
+ },
2156
+ { id: 103, type: "text", x1: 50, y1: 340, x2: 50, y2: 340, label: "3. Energy & Damped Systems", fontSize: 20, color: "#1e293b" },
2157
+ {
2158
+ id: 5,
2159
+ type: "energy_graph",
2160
+ x1: 80,
2161
+ y1: 460,
2162
+ x2: 280,
2163
+ y2: 460,
2164
+ amplitude: 80,
2165
+ domain: "time",
2166
+ color: "#1e293b",
2167
+ strokeWidth: 2,
2168
+ label: "U(t) & K(t)"
2169
+ },
2170
+ {
2171
+ id: 6,
2172
+ type: "vane_liquid",
2173
+ x1: 400,
2174
+ y1: 380,
2175
+ x2: 480,
2176
+ y2: 380,
2177
+ color: "#64748b",
2178
+ strokeWidth: 2,
2179
+ label: "Damping (b)"
2180
+ },
2181
+ { id: 7, type: "spring", x1: 440, y1: 260, x2: 440, y2: 380, color: "#3b82f6", strokeWidth: 2, coils: 6 },
2182
+ { id: 104, type: "text", x1: 440, y1: 240, x2: 440, y2: 240, label: "Rigid Support", fontSize: 14, color: "#64748b" },
2183
+ {
2184
+ id: 8,
2185
+ type: "torsion_pendulum",
2186
+ x1: 640,
2187
+ y1: 320,
2188
+ x2: 640,
2189
+ y2: 480,
2190
+ color: "#ec4899",
2191
+ strokeWidth: 2,
2192
+ label: "Torsion Pendulum"
2193
+ }
2194
+ ],
2195
+ toolCategories: [
2196
+ {
2197
+ name: "Basics",
2198
+ tools: [
2199
+ { id: "select", name: "Select" },
2200
+ { id: "point", name: "Point/Node" },
2201
+ { id: "line", name: "Line / Axis" },
2202
+ { id: "vector", name: "Vector" },
2203
+ { id: "text", name: "Text Label" }
2204
+ ]
2205
+ },
2206
+ {
2207
+ name: "Oscillations",
2208
+ tools: [
2209
+ { id: "spring", name: "Spring" },
2210
+ { id: "mass_box", name: "Mass Block" },
2211
+ { id: "pendulum", name: "Pendulum" },
2212
+ { id: "torsion_pendulum", name: "Torsion Pendulum" },
2213
+ { id: "vane_liquid", name: "Damping Vane" },
2214
+ { id: "phasor", name: "Phasor" },
2215
+ { id: "damped_wave", name: "Damped SHM" }
2216
+ ]
2217
+ },
2218
+ {
2219
+ name: "Graphs & Waves",
2220
+ tools: [
2221
+ { id: "sine_wave", name: "Sine Wave" },
2222
+ { id: "standing_wave", name: "Standing Wave" },
2223
+ { id: "wave_pulse", name: "Wave Pulse" },
2224
+ { id: "shm_graph", name: "SHM Kinematics" },
2225
+ { id: "energy_graph", name: "Energy (U/K)" },
2226
+ { id: "strobe_shm", name: "Strobe Motion" },
2227
+ { id: "wall", name: "Rigid Boundary" }
2228
+ ]
2229
+ },
2230
+ {
2231
+ name: "Sound & Gases",
2232
+ tools: [
2233
+ { id: "speaker", name: "Speaker" },
2234
+ { id: "tuning_fork", name: "Tuning Fork" },
2235
+ { id: "wavefronts", name: "Wavefronts" },
2236
+ { id: "mach_cone", name: "Mach Cone" },
2237
+ { id: "beats_graph", name: "Beats Envelope" }
2238
+ ]
2239
+ }
2240
+ ]
2241
+ };
2242
+
2243
+ // src/editor/presets/rotation.ts
2244
+ var rotation = {
2245
+ name: "Rotation",
2246
+ elements: [
2247
+ { id: 101, type: "text", x1: 60, y1: 40, x2: 60, y2: 40, label: "1. Center of Mass & 2D Collision", fontSize: 20, color: "#1e293b" },
2248
+ { id: 1, type: "point_mass", x1: 80, y1: 140, x2: 80, y2: 140, size: 25, color: "#ef4444", label: "m\u2081" },
2249
+ { id: 2, type: "vector", x1: 80, y1: 140, x2: 180, y2: 140, color: "#ef4444", label: "u\u2081", strokeWidth: 2 },
2250
+ { id: 3, type: "point_mass", x1: 240, y1: 100, x2: 240, y2: 100, size: 15, color: "#3b82f6", label: "m\u2082" },
2251
+ { id: 4, type: "dashed_path", x1: 180, y1: 140, x2: 320, y2: 80, color: "#ef4444", strokeWidth: 1.5 },
2252
+ { id: 5, type: "dashed_path", x1: 240, y1: 100, x2: 340, y2: 180, color: "#3b82f6", strokeWidth: 1.5 },
2253
+ { id: 6, type: "com_indicator", x1: 160, y1: 120, x2: 160, y2: 120, color: "#10b981", size: 15, label: "COM" },
2254
+ { id: 7, type: "system_boundary", x1: 40, y1: 60, x2: 360, y2: 220, color: "#94a3b8", strokeWidth: 1.5 },
2255
+ { id: 102, type: "text", x1: 560, y1: 40, x2: 560, y2: 40, label: "2. Rigid Body Rotation & Torque", fontSize: 20, color: "#1e293b" },
2256
+ { id: 8, type: "pivot", x1: 480, y1: 140, x2: 480, y2: 140, color: "#64748b", size: 25 },
2257
+ { id: 9, type: "uniform_rod", x1: 480, y1: 140, x2: 740, y2: 180, color: "#f59e0b", strokeWidth: 12, label: "L, M" },
2258
+ { id: 10, type: "vector", x1: 740, y1: 180, x2: 740, y2: 260, color: "#ef4444", label: "mg", strokeWidth: 2 },
2259
+ { id: 11, type: "curve_arrow", x1: 480, y1: 140, x2: 540, y2: 200, color: "#8b5cf6", strokeWidth: 2, label: "\u03B1" },
2260
+ { id: 103, type: "text", x1: 60, y1: 300, x2: 60, y2: 300, label: "3. Rolling on Inclined Plane", fontSize: 20, color: "#1e293b" },
2261
+ { id: 12, type: "inclined_wedge", x1: 60, y1: 360, x2: 360, y2: 520, color: "#64748b", strokeWidth: 2, label: "\u03B8" },
2262
+ {
2263
+ id: 13,
2264
+ type: "rolling_body",
2265
+ x1: 160,
2266
+ y1: 390,
2267
+ x2: 200,
2268
+ y2: 390,
2269
+ color: "#3b82f6",
2270
+ strokeWidth: 2,
2271
+ label: "M, R",
2272
+ showVelocity: true,
2273
+ showOmega: true
2274
+ },
2275
+ { id: 14, type: "vector", x1: 160, y1: 410, x2: 110, y2: 385, color: "#ef4444", label: "f_s", strokeWidth: 2 },
2276
+ { id: 104, type: "text", x1: 560, y1: 300, x2: 560, y2: 300, label: "4. Systems & Angular Momentum", fontSize: 20, color: "#1e293b" },
2277
+ { id: 15, type: "rocket", x1: 500, y1: 500, x2: 500, y2: 380, color: "#3b82f6", strokeWidth: 2, label: "v(t)" },
2278
+ { id: 16, type: "vector", x1: 500, y1: 500, x2: 500, y2: 560, color: "#f97316", strokeWidth: 2, label: "u_rel dm/dt" },
2279
+ { id: 17, type: "pulley", x1: 720, y1: 360, x2: 760, y2: 360, color: "#64748b", strokeWidth: 2 },
2280
+ { id: 18, type: "block_mass", x1: 660, y1: 460, x2: 700, y2: 500, color: "#0ea5e9", label: "m\u2081" },
2281
+ { id: 19, type: "block_mass", x1: 740, y1: 400, x2: 780, y2: 440, color: "#0ea5e9", label: "m\u2082" },
2282
+ { id: 20, type: "line", x1: 680, y1: 460, x2: 680, y2: 360, color: "#1e293b", strokeWidth: 1.5 },
2283
+ { id: 21, type: "line", x1: 760, y1: 400, x2: 760, y2: 360, color: "#1e293b", strokeWidth: 1.5 }
2284
+ ],
2285
+ toolCategories: [
2286
+ {
2287
+ name: "Basics",
2288
+ tools: [
2289
+ { id: "select", name: "Select" },
2290
+ { id: "line", name: "Line / Axis" },
2291
+ { id: "vector", name: "Vector" },
2292
+ { id: "text", name: "Text Label" }
2293
+ ]
2294
+ },
2295
+ {
2296
+ name: "Mass & Momentum",
2297
+ tools: [
2298
+ { id: "point_mass", name: "Point Mass" },
2299
+ { id: "block_mass", name: "Block/Mass" },
2300
+ { id: "com_indicator", name: "Center of Mass" },
2301
+ { id: "system_boundary", name: "System Bound" },
2302
+ { id: "dashed_path", name: "Trajectory" },
2303
+ { id: "rocket", name: "Rocket (Varying)" }
2304
+ ]
2305
+ },
2306
+ {
2307
+ name: "Rigid Bodies",
2308
+ tools: [
2309
+ { id: "uniform_rod", name: "Uniform Rod" },
2310
+ { id: "solid_disk", name: "Solid Disk/Sphere" },
2311
+ { id: "hoop_ring", name: "Hoop/Ring" },
2312
+ { id: "rolling_body", name: "Rolling Object" }
2313
+ ]
2314
+ },
2315
+ {
2316
+ name: "Mechanics",
2317
+ tools: [
2318
+ { id: "pivot", name: "Pivot / Hinge" },
2319
+ { id: "inclined_wedge", name: "Inclined Plane" },
2320
+ { id: "pulley", name: "Pulley System" },
2321
+ { id: "spring", name: "Spring" },
2322
+ { id: "curve_arrow", name: "Angular Vector (\u03C9/\u03C4)" }
2323
+ ]
2324
+ }
2325
+ ]
2326
+ };
2327
+
2328
+ // src/editor/presets/graph.ts
2329
+ var initialElements = [
2330
+ { id: 1, type: "capacitor", x1: 260, y1: 200, x2: 460, y2: 200, label: "C = 10\u03BCF", color: "#0f172a", strokeWidth: 3, fontSize: 18 },
2331
+ { id: 2, type: "line", x1: 260, y1: 200, x2: 260, y2: 400, color: "#0f172a", strokeWidth: 2 },
2332
+ { id: 3, type: "line", x1: 460, y1: 200, x2: 460, y2: 400, color: "#0f172a", strokeWidth: 2 },
2333
+ { id: 4, type: "capacitor", x1: 260, y1: 400, x2: 460, y2: 400, label: "V = 12V", color: "#0f172a", strokeWidth: 3, fontSize: 18 },
2334
+ { id: 5, type: "ground", x1: 460, y1: 400, x2: 460, y2: 460, label: "", color: "#0f172a", strokeWidth: 2 },
2335
+ { id: 6, type: "charge_plus", x1: 340, y1: 180, x2: 340, y2: 180, label: "+Q", color: "#ef4444", strokeWidth: 2, fontSize: 16 },
2336
+ { id: 7, type: "charge_minus", x1: 380, y1: 180, x2: 380, y2: 180, label: "-Q", color: "#3b82f6", strokeWidth: 2, fontSize: 16 },
2337
+ {
2338
+ id: 8,
2339
+ type: "vector",
2340
+ x1: 345,
2341
+ y1: 190,
2342
+ x2: 375,
2343
+ y2: 190,
2344
+ label: "",
2345
+ color: "#ef4444",
2346
+ strokeWidth: 1.5,
2347
+ lineStyle: "dashed"
2348
+ },
2349
+ {
2350
+ id: 9,
2351
+ type: "vector",
2352
+ x1: 345,
2353
+ y1: 210,
2354
+ x2: 375,
2355
+ y2: 210,
2356
+ label: "",
2357
+ color: "#ef4444",
2358
+ strokeWidth: 1.5,
2359
+ lineStyle: "dashed"
2360
+ },
2361
+ { id: 10, type: "charge_plus", x1: 600, y1: 300, x2: 600, y2: 300, label: "+q", color: "#ef4444", strokeWidth: 2, fontSize: 18 },
2362
+ { id: 11, type: "charge_minus", x1: 800, y1: 300, x2: 800, y2: 300, label: "-q", color: "#3b82f6", strokeWidth: 2, fontSize: 18 },
2363
+ { id: 12, type: "vector", x1: 620, y1: 300, x2: 780, y2: 300, label: "E", color: "#94a3b8", strokeWidth: 2, fontSize: 18 },
2364
+ {
2365
+ id: 13,
2366
+ type: "circle",
2367
+ x1: 600,
2368
+ y1: 300,
2369
+ x2: 660,
2370
+ y2: 300,
2371
+ label: "",
2372
+ color: "#ef4444",
2373
+ strokeWidth: 1.5,
2374
+ lineStyle: "dashed"
2375
+ }
2376
+ ];
2377
+ var graph = {
2378
+ name: "Graph",
2379
+ elements: initialElements,
2380
+ toolCategories: [
2381
+ {
2382
+ name: "Basic",
2383
+ tools: [
2384
+ { id: "select", name: "Select/Move" },
2385
+ { id: "point", name: "Point/Node" },
2386
+ { id: "line", name: "Solid Line" },
2387
+ { id: "dashed_line", name: "Dashed Line" },
2388
+ { id: "vector", name: "Vector/Arrow" },
2389
+ { id: "angle", name: "Angle/Vector" },
2390
+ { id: "axes", name: "X-Y Axes" },
2391
+ { id: "text", name: "Text Label" }
2392
+ ]
2393
+ },
2394
+ {
2395
+ name: "Physics",
2396
+ tools: [
2397
+ { id: "charge_plus", name: "+ Charge" },
2398
+ { id: "charge_minus", name: "- Charge" },
2399
+ { id: "capacitor", name: "Capacitor" },
2400
+ { id: "ground", name: "Ground" }
2401
+ ]
2402
+ },
2403
+ {
2404
+ name: "Shapes",
2405
+ tools: [
2406
+ { id: "rectangle", name: "Rectangle" },
2407
+ { id: "circle", name: "Circle" },
2408
+ { id: "ellipse", name: "Ellipse" }
2409
+ ]
2410
+ },
2411
+ {
2412
+ name: "Curves",
2413
+ tools: [
2414
+ { id: "parabola_v", name: "Parabola (V)" },
2415
+ { id: "parabola_h", name: "Parabola (H)" },
2416
+ { id: "hyperbola", name: "Hyperbola" },
2417
+ { id: "modulus", name: "Modulus |x|" },
2418
+ { id: "step_function", name: "Step [x]" },
2419
+ { id: "shaded_area", name: "Area Graph" },
2420
+ { id: "exponential", name: "Exponential" },
2421
+ { id: "logarithmic", name: "Logarithmic" },
2422
+ { id: "sine_wave", name: "Sine Wave" }
2423
+ ]
2424
+ },
2425
+ {
2426
+ name: "Mechanical",
2427
+ tools: [{ id: "spring", name: "Spring" }]
2428
+ }
2429
+ ]
2430
+ };
2431
+
2432
+ // src/editor/presets/electrostatics.ts
2433
+ var electrostatics = {
2434
+ name: "Electrostatics",
2435
+ elements: [
2436
+ { id: 1, type: "charge_pos", x1: 160, y1: 160, x2: 160, y2: 160, label: "+q", color: "#ef4444", strokeWidth: 2, fontSize: 18 },
2437
+ { id: 2, type: "gaussian_sphere", x1: 160, y1: 160, x2: 260, y2: 160, color: "#10b981", strokeWidth: 2, label: "Gaussian Sphere" },
2438
+ { id: 3, type: "vector", x1: 160, y1: 160, x2: 280, y2: 160, color: "#ef4444", strokeWidth: 2, label: "E" },
2439
+ { id: 4, type: "vector", x1: 160, y1: 160, x2: 160, y2: 40, color: "#ef4444", strokeWidth: 2 },
2440
+ { id: 5, type: "vector", x1: 160, y1: 160, x2: 40, y2: 160, color: "#ef4444", strokeWidth: 2 },
2441
+ { id: 6, type: "vector", x1: 160, y1: 160, x2: 160, y2: 280, color: "#ef4444", strokeWidth: 2 },
2442
+ { id: 7, type: "text", x1: 160, y1: 320, x2: 160, y2: 320, label: "Point Charge Field", color: "#334155", fontSize: 18 },
2443
+ { id: 8, type: "charged_plate_pos", x1: 500, y1: 60, x2: 500, y2: 360, color: "#ef4444", strokeWidth: 2, label: "+\u03BB (Line Charge)" },
2444
+ { id: 9, type: "gaussian_cylinder", x1: 500, y1: 120, x2: 500, y2: 300, color: "#10b981", strokeWidth: 2, curveHeight: 60, label: "Gaussian Cylinder" },
2445
+ { id: 10, type: "vector", x1: 500, y1: 210, x2: 620, y2: 210, color: "#ef4444", strokeWidth: 2, label: "E" },
2446
+ { id: 11, type: "vector", x1: 500, y1: 210, x2: 380, y2: 210, color: "#ef4444", strokeWidth: 2 },
2447
+ { id: 12, type: "text", x1: 500, y1: 400, x2: 500, y2: 400, label: "Cylindrical Symmetry", color: "#334155", fontSize: 18 },
2448
+ { id: 13, type: "charged_plate_pos", x1: 760, y1: 100, x2: 960, y2: 100, color: "#ef4444", strokeWidth: 2 },
2449
+ { id: 14, type: "charged_plate_neg", x1: 760, y1: 300, x2: 960, y2: 300, color: "#3b82f6", strokeWidth: 2 },
2450
+ { id: 15, type: "vector", x1: 800, y1: 100, x2: 800, y2: 300, color: "#ef4444", strokeWidth: 2 },
2451
+ { id: 16, type: "vector", x1: 860, y1: 100, x2: 860, y2: 300, color: "#ef4444", strokeWidth: 2, label: "Uniform E-Field" },
2452
+ { id: 17, type: "vector", x1: 920, y1: 100, x2: 920, y2: 300, color: "#ef4444", strokeWidth: 2 },
2453
+ { id: 18, type: "text", x1: 860, y1: 340, x2: 860, y2: 340, label: "Parallel Plates", color: "#334155", fontSize: 18 },
2454
+ { id: 19, type: "dipole", x1: 100, y1: 500, x2: 260, y2: 500, color: "#64748b", strokeWidth: 2, label: "Electric Dipole (p)" },
2455
+ { id: 20, type: "vector", x1: 100, y1: 500, x2: 260, y2: 500, color: "#f59e0b", strokeWidth: 2, label: "p" }
2456
+ ],
2457
+ toolCategories: [
2458
+ {
2459
+ name: "Basics",
2460
+ tools: [
2461
+ { id: "select", name: "Select/Move" },
2462
+ { id: "point", name: "Point" },
2463
+ { id: "line", name: "Line" },
2464
+ { id: "vector", name: "Vector" },
2465
+ { id: "text", name: "Text Label" }
2466
+ ]
2467
+ },
2468
+ {
2469
+ name: "Electrostatics",
2470
+ tools: [
2471
+ { id: "charge_pos", name: "+ Charge" },
2472
+ { id: "charge_neg", name: "- Charge" },
2473
+ { id: "dipole", name: "Dipole" },
2474
+ { id: "charged_plate_pos", name: "+ Plate" },
2475
+ { id: "charged_plate_neg", name: "- Plate" },
2476
+ { id: "gaussian_sphere", name: "Gauss Sphere" },
2477
+ { id: "gaussian_cylinder", name: "Gauss Cyl" }
2478
+ ]
2479
+ },
2480
+ {
2481
+ name: "Optics",
2482
+ tools: [
2483
+ { id: "ray", name: "Light Ray" },
2484
+ { id: "lens_convex", name: "Convex Lens" },
2485
+ { id: "lens_concave", name: "Concave Lens" },
2486
+ { id: "mirror_plane", name: "Plane Mirror" }
2487
+ ]
2488
+ },
2489
+ {
2490
+ name: "Modern Phys",
2491
+ tools: [
2492
+ { id: "photon", name: "Photon" },
2493
+ { id: "slit_double", name: "Double Slit" },
2494
+ { id: "energy_level", name: "Energy Lvl" }
2495
+ ]
2496
+ }
2497
+ ]
2498
+ };
2499
+
2500
+ // src/editor/presets/chemistry.ts
2501
+ var chemistry = {
2502
+ name: "Chemistry",
2503
+ elements: [
2504
+ { id: 1, type: "benzene", x1: 150, y1: 210, x2: 150, y2: 210, label: "", value: "" },
2505
+ { id: 2, type: "text", x1: 240, y1: 210, x2: 240, y2: 210, label: "+", value: "" },
2506
+ { id: 3, type: "atom", x1: 285, y1: 210, x2: 285, y2: 210, label: "Cl", value: "" },
2507
+ { id: 4, type: "single_bond", x1: 300, y1: 210, x2: 330, y2: 210, label: "", value: "" },
2508
+ { id: 5, type: "atom", x1: 345, y1: 210, x2: 345, y2: 210, label: "Cl", value: "" },
2509
+ { id: 6, type: "reaction_arrow", x1: 400, y1: 210, x2: 520, y2: 210, label: "FeCl3", value: "Dark" },
2510
+ { id: 7, type: "benzene", x1: 600, y1: 210, x2: 600, y2: 210, label: "", value: "" },
2511
+ { id: 8, type: "single_bond", x1: 600, y1: 180, x2: 600, y2: 120, label: "", value: "" },
2512
+ { id: 9, type: "atom", x1: 600, y1: 105, x2: 600, y2: 105, label: "Cl", value: "" },
2513
+ { id: 10, type: "text", x1: 690, y1: 210, x2: 690, y2: 210, label: "+", value: "" },
2514
+ { id: 11, type: "atom", x1: 750, y1: 210, x2: 750, y2: 210, label: "HCl", value: "" }
2515
+ ],
2516
+ toolCategories: [
2517
+ {
2518
+ name: "Chemistry",
2519
+ tools: [
2520
+ { id: "select", name: "Select/Move" },
2521
+ { id: "single_bond", name: "Single Bond" },
2522
+ { id: "double_bond", name: "Double Bond" },
2523
+ { id: "triple_bond", name: "Triple Bond" },
2524
+ { id: "wedge_bond", name: "Wedge (Up)" },
2525
+ { id: "dash_bond", name: "Dash (Down)" }
2526
+ ]
2527
+ },
2528
+ {
2529
+ name: "Arrows",
2530
+ tools: [
2531
+ { id: "curved_arrow", name: "Mechanism" },
2532
+ { id: "reaction_arrow", name: "Reaction" },
2533
+ { id: "equilibrium_arrow", name: "Equilibrium" },
2534
+ { id: "resonance_arrow", name: "Resonance" }
2535
+ ]
2536
+ },
2537
+ {
2538
+ name: "Rings",
2539
+ tools: [
2540
+ { id: "benzene", name: "Benzene" },
2541
+ { id: "cyclohexane", name: "Cyclohexane" },
2542
+ { id: "cyclopentane", name: "Cyclopentane" },
2543
+ { id: "cyclobutane", name: "Cyclobutane" },
2544
+ { id: "cyclopropane", name: "Cyclopropane" }
2545
+ ]
2546
+ },
2547
+ {
2548
+ name: "Symbols",
2549
+ tools: [
2550
+ { id: "atom", name: "Atom/Group" },
2551
+ { id: "charge_plus", name: "Pos. Charge" },
2552
+ { id: "charge_minus", name: "Neg. Charge" },
2553
+ { id: "radical", name: "Radical" },
2554
+ { id: "lone_pair", name: "Lone Pair" },
2555
+ { id: "text", name: "Plain Text" }
2556
+ ]
2557
+ }
2558
+ ]
2559
+ };
2560
+
2561
+ // src/editor/presets/mechanical.ts
2562
+ var mechanical = {
2563
+ name: "Mechanical",
2564
+ elements: [
2565
+ { id: 1, type: "wedge", x1: 100, y1: 400, x2: 500, y2: 100, label: "M" },
2566
+ { id: 2, type: "block", x1: 220, y1: 260, x2: 300, y2: 300, label: "m" },
2567
+ { id: 3, type: "arc", x1: 100, y1: 400, x2: 260, y2: 280, label: "\u03B8" }
2568
+ ],
2569
+ toolCategories: [{ name: "Mechanical", tools: [{ id: "select", name: "Select" }, { id: "wedge", name: "Wedge" }, { id: "block", name: "Block" }, { id: "vector", name: "Vector" }, { id: "arc", name: "Arc" }, { id: "dashed", name: "Dashed" }, { id: "dimension", name: "Dimension" }, { id: "axes", name: "Axes" }] }]
2570
+ };
2571
+
2572
+ // src/editor/presets/index.ts
2573
+ var presets = {
2574
+ mechanics,
2575
+ circuit,
2576
+ thermo,
2577
+ optical,
2578
+ magnetism,
2579
+ light,
2580
+ waves,
2581
+ waveOscillation,
2582
+ rotation,
2583
+ graph,
2584
+ electrostatics,
2585
+ chemistry,
2586
+ mechanical
2587
+ };
2588
+
2589
+ // src/editor/Editor.tsx
2590
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
2591
+ var defaultPreset = presets.mechanics;
2592
+ var Editor = forwardRef(function Editor2({
2593
+ initialElements: initialElements2,
2594
+ toolCategories,
2595
+ preset,
2596
+ enablePresetSwitch = true,
2597
+ onPresetChange,
2598
+ onChange,
2599
+ viewMode,
2600
+ embedded = false,
2601
+ documentTitle,
2602
+ hideDocumentTitle = false,
2603
+ onExport
2604
+ }, ref) {
2605
+ const [selectedPreset, setSelectedPreset] = useState2(preset ?? "mechanics");
2606
+ const isPresetExternallyControlled = preset !== void 0 && typeof onPresetChange === "function";
2607
+ useEffect2(() => {
2608
+ if (isPresetExternallyControlled && preset) {
2609
+ setSelectedPreset(preset);
2610
+ }
2611
+ }, [preset, isPresetExternallyControlled]);
2612
+ const activePresetKey = isPresetExternallyControlled ? preset ?? selectedPreset : selectedPreset;
2613
+ const activePreset = presets[activePresetKey] ?? defaultPreset;
2614
+ const [lightTopicIndex, setLightTopicIndex] = useState2(0);
2615
+ useEffect2(() => {
2616
+ setLightTopicIndex(0);
2617
+ }, [activePresetKey]);
2618
+ const resolvedInitialElements = useMemo2(() => {
2619
+ if (initialElements2 != null) return initialElements2;
2620
+ if (activePresetKey === "light") return LIGHT_TOPICS[lightTopicIndex].elements;
2621
+ return activePreset.elements;
2622
+ }, [initialElements2, activePresetKey, lightTopicIndex, activePreset.elements]);
2623
+ const state = useDrawing(resolvedInitialElements, activePresetKey);
2624
+ const showLightTopicPicker = activePresetKey === "light" && initialElements2 == null;
2625
+ useEffect2(() => {
2626
+ onChange?.(state.elements);
2627
+ }, [state.elements, onChange]);
2628
+ useEffect2(() => {
2629
+ if (typeof viewMode === "boolean") state.setIsViewMode(viewMode);
2630
+ }, [viewMode, state]);
2631
+ useEffect2(() => {
2632
+ if (!state.selectedId) {
2633
+ state.setShowProperties(false);
2634
+ }
2635
+ }, [state.selectedId, state.setShowProperties]);
2636
+ const categories = toolCategories ?? activePreset.toolCategories;
2637
+ useImperativeHandle(
2638
+ ref,
2639
+ () => ({
2640
+ getData: () => state.elements,
2641
+ setData: (els) => state.setElements(els),
2642
+ clear: () => state.setElements([])
2643
+ }),
2644
+ [state.elements, state.setElements]
2645
+ );
2646
+ const displayTitle = documentTitle ?? `${activePreset.name} Editor`;
2647
+ const handleCopyJson = () => {
2648
+ const json = JSON.stringify(state.elements, null, 2);
2649
+ onExport?.({ elements: state.elements, json });
2650
+ if (typeof navigator !== "undefined" && navigator.clipboard?.writeText) {
2651
+ void navigator.clipboard.writeText(json);
2652
+ }
2653
+ };
2654
+ const updateSelected = (key, value) => {
2655
+ state.setElements((els) => els.map((el) => el.id === state.selectedId ? { ...el, [key]: value } : el));
2656
+ };
2657
+ const deleteSelected = () => {
2658
+ if (!state.selectedId) return;
2659
+ state.setElements((els) => els.filter((el) => el.id !== state.selectedId));
2660
+ state.setSelectedId(null);
2661
+ state.setShowProperties(false);
2662
+ };
2663
+ const rootClass = embedded ? "flex flex-col h-full min-h-0 w-full bg-white text-gray-900 font-sans" : "flex flex-col h-screen w-full bg-white text-gray-900 font-sans";
2664
+ const headerButtonBase = "text-xs md:text-sm px-2.5 md:px-3.5 py-2 rounded-lg font-medium transition border border-transparent";
2665
+ return /* @__PURE__ */ jsxs5("div", { className: rootClass, children: [
2666
+ /* @__PURE__ */ jsxs5("header", { className: "border-b border-slate-200 bg-white/95 backdrop-blur flex items-center justify-between px-3 md:px-6 py-2 shadow-sm z-20 shrink-0 gap-2 min-w-0", children: [
2667
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2 md:gap-3 min-w-0", children: [
2668
+ enablePresetSwitch && /* @__PURE__ */ jsxs5("div", { className: "relative shrink-0", children: [
2669
+ /* @__PURE__ */ jsx5(
2670
+ "select",
2671
+ {
2672
+ value: activePresetKey,
2673
+ onChange: (e) => {
2674
+ const next = e.target.value;
2675
+ if (!isPresetExternallyControlled) {
2676
+ setSelectedPreset(next);
2677
+ }
2678
+ onPresetChange?.(next);
2679
+ },
2680
+ className: "appearance-none text-xs md:text-sm pl-3 pr-8 py-2 rounded-full border border-slate-200 bg-slate-50 text-slate-700 shadow-sm hover:bg-slate-100 focus:outline-none focus:ring-2 focus:ring-blue-200",
2681
+ title: "Switch preset",
2682
+ children: Object.keys(presets).map((key) => /* @__PURE__ */ jsx5("option", { value: key, children: presets[key].name }, key))
2683
+ }
2684
+ ),
2685
+ /* @__PURE__ */ jsx5("span", { className: "pointer-events-none absolute inset-y-0 right-2 flex items-center text-slate-500 text-xs", children: "\u25BC" })
2686
+ ] }),
2687
+ showLightTopicPicker && /* @__PURE__ */ jsxs5("div", { className: "relative shrink-0 max-w-[min(100%,280px)]", children: [
2688
+ /* @__PURE__ */ jsx5(
2689
+ "select",
2690
+ {
2691
+ value: lightTopicIndex,
2692
+ onChange: (e) => {
2693
+ const idx = Number(e.target.value);
2694
+ setLightTopicIndex(idx);
2695
+ state.setSelectedId(null);
2696
+ state.setShowProperties(false);
2697
+ },
2698
+ className: "w-full appearance-none text-xs md:text-sm pl-3 pr-8 py-2 rounded-full border border-slate-200 bg-sky-50 text-slate-800 shadow-sm hover:bg-sky-100 focus:outline-none focus:ring-2 focus:ring-sky-200 truncate",
2699
+ title: "Load JEE/NEET topic scene",
2700
+ "aria-label": "Light syllabus topic",
2701
+ children: LIGHT_TOPICS.map((t, i) => /* @__PURE__ */ jsx5("option", { value: i, children: t.name }, t.name))
2702
+ }
2703
+ ),
2704
+ /* @__PURE__ */ jsx5("span", { className: "pointer-events-none absolute inset-y-0 right-2 flex items-center text-slate-500 text-xs", children: "\u25BC" })
2705
+ ] }),
2706
+ !hideDocumentTitle && /* @__PURE__ */ jsx5("h1", { className: "text-lg md:text-2xl font-semibold tracking-tight text-slate-800 truncate min-w-0", children: displayTitle })
2707
+ ] }),
2708
+ /* @__PURE__ */ jsxs5(
2709
+ "div",
2710
+ {
2711
+ className: `flex gap-1.5 md:gap-3 items-center flex-wrap justify-end ${hideDocumentTitle ? "ml-auto w-full" : "ml-auto"}`,
2712
+ children: [
2713
+ /* @__PURE__ */ jsx5(
2714
+ "button",
2715
+ {
2716
+ type: "button",
2717
+ onClick: handleCopyJson,
2718
+ className: `${headerButtonBase} text-slate-700 hover:bg-emerald-50 hover:text-emerald-700`,
2719
+ children: "Copy JSON"
2720
+ }
2721
+ ),
2722
+ /* @__PURE__ */ jsx5(
2723
+ "button",
2724
+ {
2725
+ type: "button",
2726
+ onClick: () => {
2727
+ state.setJsonText(JSON.stringify(state.elements, null, 2));
2728
+ state.setShowJsonModal(true);
2729
+ },
2730
+ className: `${headerButtonBase} text-slate-700 hover:bg-blue-50 hover:text-blue-700`,
2731
+ children: "Export/Import"
2732
+ }
2733
+ ),
2734
+ state.selectedId != null && !state.isViewMode && /* @__PURE__ */ jsxs5(
2735
+ "button",
2736
+ {
2737
+ type: "button",
2738
+ onClick: () => state.setShowProperties((open) => !open),
2739
+ className: `${headerButtonBase} inline-flex items-center gap-1.5 ${state.showProperties ? "bg-violet-100 text-violet-800 border-violet-200" : "text-slate-700 hover:bg-violet-50 hover:text-violet-800"}`,
2740
+ title: state.showProperties ? "Hide properties" : "Edit properties",
2741
+ "aria-expanded": state.showProperties,
2742
+ "aria-controls": "svg-engine-properties-panel",
2743
+ children: [
2744
+ /* @__PURE__ */ jsx5("svg", { className: "w-4 h-4 shrink-0", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": true, children: /* @__PURE__ */ jsx5(
2745
+ "path",
2746
+ {
2747
+ strokeLinecap: "round",
2748
+ strokeLinejoin: "round",
2749
+ d: "M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"
2750
+ }
2751
+ ) }),
2752
+ /* @__PURE__ */ jsx5("span", { className: "hidden sm:inline", children: "Properties" })
2753
+ ]
2754
+ }
2755
+ ),
2756
+ /* @__PURE__ */ jsx5(
2757
+ "button",
2758
+ {
2759
+ type: "button",
2760
+ onClick: () => {
2761
+ state.setIsViewMode(!state.isViewMode);
2762
+ state.setSelectedId(null);
2763
+ state.setTool("select");
2764
+ },
2765
+ className: `${headerButtonBase} ${state.isViewMode ? "bg-blue-100 text-blue-800 border-blue-200" : "text-slate-700 hover:bg-blue-50 hover:text-blue-700"}`,
2766
+ children: state.isViewMode ? "Exit Preview" : "Preview Mode"
2767
+ }
2768
+ )
2769
+ ]
2770
+ }
2771
+ )
2772
+ ] }),
2773
+ /* @__PURE__ */ jsxs5("div", { className: "flex flex-1 overflow-hidden min-h-0", children: [
2774
+ !state.isViewMode && /* @__PURE__ */ jsx5(Toolbar, { categories, tool: state.tool, onSelect: (id) => {
2775
+ state.setTool(id);
2776
+ state.setSelectedId(null);
2777
+ } }),
2778
+ /* @__PURE__ */ jsxs5("div", { className: "flex-1 relative overflow-hidden bg-slate-50 min-h-0", children: [
2779
+ /* @__PURE__ */ jsx5(
2780
+ Renderer,
2781
+ {
2782
+ svgRef: state.svgRef,
2783
+ className: "w-full h-full",
2784
+ elements: state.elements,
2785
+ drawing: state.drawing,
2786
+ selectedId: state.selectedId,
2787
+ viewMode: state.isViewMode,
2788
+ onBackgroundMouseDown: state.isViewMode ? void 0 : state.handleMouseDown,
2789
+ onBackgroundMouseMove: state.isViewMode ? void 0 : state.handleMouseMove,
2790
+ onBackgroundMouseUp: state.isViewMode ? void 0 : state.handleMouseUp,
2791
+ onBackgroundMouseLeave: state.isViewMode ? void 0 : state.handleMouseUp,
2792
+ onElementMouseDown: state.onElementMouseDown
2793
+ }
2794
+ ),
2795
+ state.showProperties && state.selectedId && !state.isViewMode && /* @__PURE__ */ jsx5(
2796
+ PropertiesPanel,
2797
+ {
2798
+ element: state.selectedElement,
2799
+ onChange: updateSelected,
2800
+ onDelete: deleteSelected,
2801
+ onClose: () => state.setShowProperties(false)
2802
+ }
2803
+ )
2804
+ ] })
2805
+ ] }),
2806
+ /* @__PURE__ */ jsx5(
2807
+ JsonModal,
2808
+ {
2809
+ open: state.showJsonModal,
2810
+ jsonText: state.jsonText,
2811
+ setJsonText: state.setJsonText,
2812
+ onClose: () => state.setShowJsonModal(false),
2813
+ onLoad: () => {
2814
+ try {
2815
+ state.setElements(JSON.parse(state.jsonText));
2816
+ state.setShowJsonModal(false);
2817
+ } catch {
2818
+ alert("Invalid JSON format");
2819
+ }
2820
+ }
2821
+ }
2822
+ )
2823
+ ] });
2824
+ });
2825
+
2826
+ // src/editor/EditorWindow.tsx
2827
+ import { forwardRef as forwardRef2, useCallback, useImperativeHandle as useImperativeHandle2, useMemo as useMemo3, useRef as useRef2, useState as useState3 } from "react";
2828
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
2829
+ var positionStyle = (p) => {
2830
+ const pad = 16;
2831
+ switch (p) {
2832
+ case "top-left":
2833
+ return { top: pad, left: pad };
2834
+ case "top-right":
2835
+ return { top: pad, right: pad };
2836
+ case "bottom-left":
2837
+ return { bottom: pad, left: pad };
2838
+ case "bottom-right":
2839
+ return { bottom: pad, right: pad };
2840
+ case "center":
2841
+ return { top: "50%", left: "50%", transform: "translate(-50%, -50%)" };
2842
+ default:
2843
+ return { top: pad, right: pad };
2844
+ }
2845
+ };
2846
+ var EditorWindow = forwardRef2(function EditorWindow2({
2847
+ mode = "floating",
2848
+ title = "Diagram editor",
2849
+ startMinimized = false,
2850
+ position = "top-right",
2851
+ width = "min(960px, 92vw)",
2852
+ height = "min(640px, 78vh)",
2853
+ onChange,
2854
+ onExport,
2855
+ onShellMinimize,
2856
+ onShellMaximize,
2857
+ onShellClose,
2858
+ documentTitle,
2859
+ ...editorProps
2860
+ }, ref) {
2861
+ const editorRef = useRef2(null);
2862
+ const [minimized, setMinimized] = useState3(startMinimized);
2863
+ const [maximized, setMaximized] = useState3(false);
2864
+ const [closed, setClosed] = useState3(false);
2865
+ const [dragOffset, setDragOffset] = useState3({ x: 0, y: 0 });
2866
+ const dragRef = useRef2(null);
2867
+ const shellRef = useRef2(null);
2868
+ useImperativeHandle2(
2869
+ ref,
2870
+ () => ({
2871
+ getData: () => editorRef.current?.getData() ?? [],
2872
+ setData: (els) => editorRef.current?.setData(els),
2873
+ clear: () => editorRef.current?.clear(),
2874
+ minimize: () => {
2875
+ setMinimized(true);
2876
+ setMaximized(false);
2877
+ },
2878
+ maximize: () => {
2879
+ setMinimized(false);
2880
+ setMaximized(true);
2881
+ },
2882
+ restore: () => {
2883
+ setMinimized(false);
2884
+ setMaximized(false);
2885
+ },
2886
+ close: () => setClosed(true),
2887
+ open: () => setClosed(false)
2888
+ }),
2889
+ []
2890
+ );
2891
+ const handleExport = useCallback(
2892
+ (payload) => {
2893
+ onExport?.(payload);
2894
+ },
2895
+ [onExport]
2896
+ );
2897
+ const onHeaderPointerDown = (e) => {
2898
+ if (mode !== "floating" || maximized) return;
2899
+ e.preventDefault();
2900
+ dragRef.current = {
2901
+ startX: e.clientX,
2902
+ startY: e.clientY,
2903
+ ox: dragOffset.x,
2904
+ oy: dragOffset.y
2905
+ };
2906
+ e.currentTarget.setPointerCapture(e.pointerId);
2907
+ };
2908
+ const onHeaderPointerMove = (e) => {
2909
+ if (!dragRef.current || mode !== "floating" || maximized) return;
2910
+ const dx = e.clientX - dragRef.current.startX;
2911
+ const dy = e.clientY - dragRef.current.startY;
2912
+ setDragOffset({
2913
+ x: dragRef.current.ox + dx,
2914
+ y: dragRef.current.oy + dy
2915
+ });
2916
+ };
2917
+ const onHeaderPointerUp = (e) => {
2918
+ dragRef.current = null;
2919
+ try {
2920
+ e.currentTarget.releasePointerCapture(e.pointerId);
2921
+ } catch {
2922
+ }
2923
+ };
2924
+ const floatingShellStyle = useMemo3(() => {
2925
+ if (mode !== "floating") return {};
2926
+ const transform = position === "center" ? `translate(calc(-50% + ${dragOffset.x}px), calc(-50% + ${dragOffset.y}px))` : `translate(${dragOffset.x}px, ${dragOffset.y}px)`;
2927
+ const base = {
2928
+ position: "fixed",
2929
+ zIndex: 9999,
2930
+ display: closed ? "none" : "flex",
2931
+ flexDirection: "column",
2932
+ background: "#fff",
2933
+ borderRadius: "12px",
2934
+ boxShadow: "0 25px 50px -12px rgb(0 0 0 / 0.25)",
2935
+ border: "1px solid #e2e8f0",
2936
+ overflow: "hidden",
2937
+ transform
2938
+ };
2939
+ if (maximized) {
2940
+ return {
2941
+ ...base,
2942
+ inset: 16,
2943
+ width: "auto",
2944
+ height: "auto",
2945
+ maxWidth: "none",
2946
+ maxHeight: "none",
2947
+ transform: `translate(${dragOffset.x}px, ${dragOffset.y}px)`
2948
+ };
2949
+ }
2950
+ const minimizedH = minimized ? "auto" : void 0;
2951
+ return {
2952
+ ...base,
2953
+ ...positionStyle(position),
2954
+ width,
2955
+ height: minimized ? minimizedH : height,
2956
+ maxHeight: minimized ? "none" : "90vh",
2957
+ maxWidth: "96vw"
2958
+ };
2959
+ }, [mode, closed, maximized, minimized, position, width, height, dragOffset]);
2960
+ if (mode === "inline") {
2961
+ return /* @__PURE__ */ jsx6("div", { className: "flex flex-col bg-white rounded-lg border border-gray-200 overflow-hidden", style: { width, height }, children: /* @__PURE__ */ jsx6(
2962
+ Editor,
2963
+ {
2964
+ ref: editorRef,
2965
+ ...editorProps,
2966
+ embedded: true,
2967
+ documentTitle: documentTitle ?? title,
2968
+ onChange,
2969
+ onExport: handleExport
2970
+ }
2971
+ ) });
2972
+ }
2973
+ return /* @__PURE__ */ jsxs6("div", { ref: shellRef, style: floatingShellStyle, className: "font-sans text-gray-900", children: [
2974
+ /* @__PURE__ */ jsxs6(
2975
+ "div",
2976
+ {
2977
+ className: "h-11 shrink-0 flex items-center justify-between px-3 border-b border-gray-100 bg-slate-50 cursor-grab active:cursor-grabbing select-none",
2978
+ onPointerDown: onHeaderPointerDown,
2979
+ onPointerMove: onHeaderPointerMove,
2980
+ onPointerUp: onHeaderPointerUp,
2981
+ onPointerCancel: onHeaderPointerUp,
2982
+ children: [
2983
+ /* @__PURE__ */ jsx6("span", { className: "text-sm font-semibold text-slate-800 truncate pr-2", children: title }),
2984
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1 shrink-0", children: [
2985
+ /* @__PURE__ */ jsx6(
2986
+ "button",
2987
+ {
2988
+ type: "button",
2989
+ className: "p-1.5 rounded hover:bg-slate-200 text-slate-600",
2990
+ title: minimized ? "Expand" : "Minimize",
2991
+ onClick: (e) => {
2992
+ e.stopPropagation();
2993
+ setMinimized((m) => !m);
2994
+ if (!minimized) setMaximized(false);
2995
+ onShellMinimize?.();
2996
+ },
2997
+ children: minimized ? "\u25A2" : "\u2212"
2998
+ }
2999
+ ),
3000
+ /* @__PURE__ */ jsx6(
3001
+ "button",
3002
+ {
3003
+ type: "button",
3004
+ className: "p-1.5 rounded hover:bg-slate-200 text-slate-600",
3005
+ title: maximized ? "Restore" : "Maximize",
3006
+ onClick: (e) => {
3007
+ e.stopPropagation();
3008
+ setMaximized((m) => !m);
3009
+ if (!maximized) setMinimized(false);
3010
+ onShellMaximize?.();
3011
+ },
3012
+ children: "\u25A1"
3013
+ }
3014
+ ),
3015
+ /* @__PURE__ */ jsx6(
3016
+ "button",
3017
+ {
3018
+ type: "button",
3019
+ className: "p-1.5 rounded hover:bg-red-100 text-red-600",
3020
+ title: "Close",
3021
+ onClick: (e) => {
3022
+ e.stopPropagation();
3023
+ setClosed(true);
3024
+ onShellClose?.();
3025
+ },
3026
+ children: "\xD7"
3027
+ }
3028
+ )
3029
+ ] })
3030
+ ]
3031
+ }
3032
+ ),
3033
+ /* @__PURE__ */ jsx6(
3034
+ "div",
3035
+ {
3036
+ className: "flex-1 min-h-0 overflow-hidden flex flex-col",
3037
+ style: minimized ? { maxHeight: 0, opacity: 0, overflow: "hidden", pointerEvents: "none" } : void 0,
3038
+ "aria-hidden": minimized,
3039
+ children: /* @__PURE__ */ jsx6(
3040
+ Editor,
3041
+ {
3042
+ ref: editorRef,
3043
+ ...editorProps,
3044
+ embedded: true,
3045
+ hideDocumentTitle: true,
3046
+ documentTitle,
3047
+ onChange,
3048
+ onExport: handleExport
3049
+ }
3050
+ )
3051
+ }
3052
+ ),
3053
+ minimized && /* @__PURE__ */ jsx6("div", { className: "px-3 py-2 text-xs text-slate-500 border-t border-gray-100 bg-white", children: "Editor minimized \u2014 click \u25A2 on the bar to expand." })
3054
+ ] });
3055
+ });
3056
+ export {
3057
+ Editor,
3058
+ EditorWindow,
3059
+ presets
3060
+ };