simple-circuit-engine 0.0.9 → 0.0.11

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.
@@ -1,4 +1,4 @@
1
- class w {
1
+ class m {
2
2
  /**
3
3
  * Create a new 3D position.
4
4
  *
@@ -6,8 +6,8 @@ class w {
6
6
  * @param y - Y coordinate
7
7
  * @param z - Z coordinate
8
8
  */
9
- constructor(t, e, r) {
10
- this.x = t, this.y = e, this.z = r;
9
+ constructor(t, e, i) {
10
+ this.x = t, this.y = e, this.z = i;
11
11
  }
12
12
  /**
13
13
  * Check if this position equals another position.
@@ -57,7 +57,7 @@ class w {
57
57
  * ```
58
58
  */
59
59
  static fromJSON(t) {
60
- return new w(t.x, t.y, t.z);
60
+ return new m(t.x, t.y, t.z);
61
61
  }
62
62
  /**
63
63
  * String representation for debugging.
@@ -68,7 +68,7 @@ class w {
68
68
  return `Position(${this.x}, ${this.y}, ${this.z})`;
69
69
  }
70
70
  }
71
- class k {
71
+ class M {
72
72
  /**
73
73
  * Create new camera options.
74
74
  *
@@ -78,8 +78,8 @@ class k {
78
78
  * @param near - Near clipping plane distance (default: 0.1)
79
79
  * @param far - Far clipping plane distance (default: 1000)
80
80
  */
81
- constructor(t = new w(0, 15, 15), e = new w(0, 0, 0), r = 75, i = 0.1, o = 1e3) {
82
- this.position = t, this.lookAtPosition = e, this.fov = r, this.near = i, this.far = o;
81
+ constructor(t = new m(0, 15, 15), e = new m(0, 0, 0), i = 75, n = 0.1, r = 1e3) {
82
+ this.position = t, this.lookAtPosition = e, this.fov = i, this.near = n, this.far = r;
83
83
  }
84
84
  /**
85
85
  * Serialize camera options to JSON.
@@ -129,9 +129,9 @@ class k {
129
129
  * ```
130
130
  */
131
131
  static fromJSON(t) {
132
- return new k(
133
- w.fromJSON(t.position),
134
- w.fromJSON(t.lookAtPosition),
132
+ return new M(
133
+ m.fromJSON(t.position),
134
+ m.fromJSON(t.lookAtPosition),
135
135
  t.fov,
136
136
  t.near,
137
137
  t.far
@@ -146,137 +146,7 @@ class k {
146
146
  return `CameraOptions(position: ${this.position.toString()}, lookAt: ${this.lookAtPosition.toString()}, fov: ${this.fov}, near: ${this.near}, far: ${this.far})`;
147
147
  }
148
148
  }
149
- var S = /* @__PURE__ */ ((n) => (n.Voltage = "Voltage", n.Current = "Current", n))(S || {}), T = /* @__PURE__ */ ((n) => (n.Battery = "battery", n.Switch = "switch", n.Lightbulb = "lightbulb", n.Relay = "relay", n.Transistor = "transistor", n.SmallLED = "smallLED", n.RectangleLED = "rectangleLED", n.Cube = "cube", n.Label = "label", n))(T || {});
150
- const E = {
151
- switch: {
152
- id: "switch",
153
- name: "Switch",
154
- pins: /* @__PURE__ */ new Map([
155
- ["input", void 0],
156
- ["output", void 0]
157
- ]),
158
- config: /* @__PURE__ */ new Map([
159
- ["initialState", "open"],
160
- ["size", "1"]
161
- ])
162
- },
163
- battery: {
164
- id: "battery",
165
- name: "Battery",
166
- pins: /* @__PURE__ */ new Map([
167
- ["cathode", S.Voltage],
168
- ["anode", S.Current]
169
- ]),
170
- config: /* @__PURE__ */ new Map([])
171
- },
172
- lightbulb: {
173
- id: "lightbulb",
174
- name: "Lightbulb",
175
- pins: /* @__PURE__ */ new Map([
176
- ["pin1", void 0],
177
- ["pin2", void 0]
178
- ]),
179
- config: /* @__PURE__ */ new Map([["size", "1"]])
180
- },
181
- relay: {
182
- id: "relay",
183
- name: "Relay",
184
- pins: /* @__PURE__ */ new Map([
185
- ["cmd_in", void 0],
186
- ["cmd_out", void 0],
187
- ["power_in", void 0],
188
- ["power_out", void 0]
189
- ]),
190
- config: /* @__PURE__ */ new Map([
191
- ["activationLogic", "positive"],
192
- ["initializationOrder", ""]
193
- ])
194
- },
195
- transistor: {
196
- id: "transistor",
197
- name: "Transistor",
198
- pins: /* @__PURE__ */ new Map([
199
- ["collector", void 0],
200
- ["base", void 0],
201
- ["emitter", void 0]
202
- ]),
203
- config: /* @__PURE__ */ new Map([
204
- ["activationLogic", "positive"],
205
- ["initializationOrder", ""]
206
- ])
207
- },
208
- smallLED: {
209
- id: "smallLED",
210
- name: "SmallLED",
211
- pins: /* @__PURE__ */ new Map([
212
- ["cathode", void 0],
213
- ["anode", void 0]
214
- ]),
215
- config: /* @__PURE__ */ new Map([
216
- ["mode", "symmetric"],
217
- ["idleColor", "white"],
218
- ["activeColor", "#ffff00"],
219
- ["size", "1"],
220
- ["ywRatio", "1"]
221
- ])
222
- },
223
- rectangleLED: {
224
- id: "rectangleLED",
225
- name: "RectangleLED",
226
- pins: /* @__PURE__ */ new Map([
227
- ["cathode", void 0],
228
- ["anode", void 0]
229
- ]),
230
- config: /* @__PURE__ */ new Map([
231
- ["mode", "symmetric"],
232
- ["idleColor", "white"],
233
- ["activeColor", "#ffff00"],
234
- ["size", "1"],
235
- ["hwRatio", "1"],
236
- ["ywRatio", "1"]
237
- ])
238
- },
239
- cube: {
240
- id: "cube",
241
- name: "Cube",
242
- pins: /* @__PURE__ */ new Map([]),
243
- config: /* @__PURE__ */ new Map([["color", "red"]])
244
- },
245
- label: {
246
- id: "label",
247
- name: "Label",
248
- pins: /* @__PURE__ */ new Map([]),
249
- config: /* @__PURE__ */ new Map([
250
- ["text", "Label"],
251
- ["size", "1"]
252
- ])
253
- }
254
- };
255
- function z() {
256
- return Object.values(T);
257
- }
258
- function N(n) {
259
- return E[n];
260
- }
261
- var M = /* @__PURE__ */ ((n) => (n.Pin = "Pin", n.BranchingPoint = "BranchingPoint", n))(M || {});
262
- function I() {
263
- if (typeof crypto < "u" && crypto.randomUUID)
264
- return crypto.randomUUID();
265
- const n = "0123456789abcdef", t = [8, 4, 4, 4, 12], e = [];
266
- for (const c of t) {
267
- let l = "";
268
- for (let s = 0; s < c; s++) {
269
- const h = Math.floor(Math.random() * 16);
270
- l += n[h];
271
- }
272
- e.push(l);
273
- }
274
- const i = e.join("-").split("");
275
- i[14] = "4";
276
- const a = parseInt(i[19] ?? "0", 16) & 3 | 8;
277
- return i[19] = n[a] ?? "0", i.join("");
278
- }
279
- class v {
149
+ class T {
280
150
  /**
281
151
  * Create a new position on the discrete grid.
282
152
  *
@@ -337,7 +207,7 @@ class v {
337
207
  * ```
338
208
  */
339
209
  static fromJSON(t) {
340
- return new v(t.x, t.y);
210
+ return new T(t.x, t.y);
341
211
  }
342
212
  /**
343
213
  * String representation for debugging.
@@ -348,44 +218,44 @@ class v {
348
218
  return `Position(${this.x}, ${this.y})`;
349
219
  }
350
220
  }
351
- function W(n, t, e = 1 / 0) {
352
- if (n.length === 0)
221
+ function R(o, t, e = 1 / 0) {
222
+ if (o.length === 0)
353
223
  return 0;
354
- if (n.length === 1)
224
+ if (o.length === 1)
355
225
  return 1;
356
- let r = 1;
357
- for (let i = 0; i < n.length - 1; i++) {
358
- const o = n[i], a = n[i + 1], c = O(t, o, a);
359
- c < e && (e = c, r = i + 1);
226
+ let i = 1;
227
+ for (let n = 0; n < o.length - 1; n++) {
228
+ const r = o[n], a = o[n + 1], c = N(t, r, a);
229
+ c < e && (e = c, i = n + 1);
360
230
  }
361
- return r;
231
+ return i;
362
232
  }
363
- function O(n, t, e) {
364
- const r = e.x - t.x, i = e.y - t.y, o = r * r + i * i;
365
- if (o === 0)
366
- return Math.sqrt((n.x - t.x) ** 2 + (n.y - t.y) ** 2);
233
+ function N(o, t, e) {
234
+ const i = e.x - t.x, n = e.y - t.y, r = i * i + n * n;
235
+ if (r === 0)
236
+ return Math.sqrt((o.x - t.x) ** 2 + (o.y - t.y) ** 2);
367
237
  const a = Math.max(
368
238
  0,
369
239
  Math.min(
370
240
  1,
371
- ((n.x - t.x) * r + (n.y - t.y) * i) / o
241
+ ((o.x - t.x) * i + (o.y - t.y) * n) / r
372
242
  )
373
- ), c = t.x + a * r, l = t.y + a * i;
374
- return Math.sqrt((n.x - c) ** 2 + (n.y - l) ** 2);
243
+ ), c = t.x + a * i, h = t.y + a * n;
244
+ return Math.sqrt((o.x - c) ** 2 + (o.y - h) ** 2);
375
245
  }
376
- function L(n, t = 5) {
377
- if (n.length <= 2)
378
- return [...n];
379
- const e = [n[0]];
380
- for (let r = 1; r < n.length - 1; r++) {
381
- const i = e[e.length - 1], o = n[r], a = n[r + 1];
382
- D(i, o, a, t) || e.push(o);
383
- }
384
- return e.push(n[n.length - 1]), e;
246
+ function z(o, t = 5) {
247
+ if (o.length <= 2)
248
+ return [...o];
249
+ const e = [o[0]];
250
+ for (let i = 1; i < o.length - 1; i++) {
251
+ const n = e[e.length - 1], r = o[i], a = o[i + 1];
252
+ A(n, r, a, t) || e.push(r);
253
+ }
254
+ return e.push(o[o.length - 1]), e;
385
255
  }
386
- function D(n, t, e, r = 5) {
387
- const i = (t.x - n.x) * (e.y - n.y) - (t.y - n.y) * (e.x - n.x);
388
- return Math.abs(i) <= r;
256
+ function A(o, t, e, i = 5) {
257
+ const n = (t.x - o.x) * (e.y - o.y) - (t.y - o.y) * (e.x - o.x);
258
+ return Math.abs(n) <= i;
389
259
  }
390
260
  class C {
391
261
  /**
@@ -457,7 +327,629 @@ class C {
457
327
  return `Rotation(${this.angle}°)`;
458
328
  }
459
329
  }
460
- class A {
330
+ function O() {
331
+ if (typeof crypto < "u" && crypto.randomUUID)
332
+ return crypto.randomUUID();
333
+ const o = "0123456789abcdef", t = [8, 4, 4, 4, 12], e = [];
334
+ for (const c of t) {
335
+ let h = "";
336
+ for (let s = 0; s < c; s++) {
337
+ const u = Math.floor(Math.random() * 16);
338
+ h += o[u];
339
+ }
340
+ e.push(h);
341
+ }
342
+ const n = e.join("-").split("");
343
+ n[14] = "4";
344
+ const a = parseInt(n[19] ?? "0", 16) & 3 | 8;
345
+ return n[19] = o[a] ?? "0", n.join("");
346
+ }
347
+ const G = "0.0.11";
348
+ var v = /* @__PURE__ */ ((o) => (o.Voltage = "Voltage", o.Current = "Current", o))(v || {}), S = /* @__PURE__ */ ((o) => (o.Pin = "Pin", o.BranchingPoint = "BranchingPoint", o))(S || {});
349
+ const W = ["CMOS1", "TTL1", "Sandbox"], U = "CMOS1";
350
+ var L = /* @__PURE__ */ ((o) => (o.Cube = "cube", o.Label = "label", o.Battery = "battery", o.Switch = "switch", o.DoubleThrowSwitch = "doubleThrowSwitch", o.Lightbulb = "lightbulb", o.Relay = "relay", o.SmallLED = "smallLED", o.RectangleLED = "rectangleLED", o.Inverter = "inverter", o.NandGate = "nandGate", o.Nand4Gate = "nand4Gate", o.Nand8Gate = "nand8Gate", o.NorGate = "norGate", o.Nor4Gate = "nor4Gate", o.Nor8Gate = "nor8Gate", o.XorGate = "xorGate", o.Xor4Gate = "xor4Gate", o.Xor8Gate = "xor8Gate", o))(L || {});
351
+ const I = {
352
+ switch: {
353
+ id: "switch",
354
+ name: "Switch",
355
+ pins: /* @__PURE__ */ new Map([
356
+ ["input", { subtype: "free", sourceType: void 0 }],
357
+ ["output", { subtype: "free", sourceType: void 0 }]
358
+ ]),
359
+ config: /* @__PURE__ */ new Map([
360
+ ["initialState", "open"],
361
+ ["size", "1"]
362
+ ])
363
+ },
364
+ doubleThrowSwitch: {
365
+ id: "doubleThrowSwitch",
366
+ // SPDT (Single-Pole Double-Throw) Switch
367
+ name: "DoubleThrowSwitch",
368
+ pins: /* @__PURE__ */ new Map([
369
+ ["input1", { subtype: "free", sourceType: void 0 }],
370
+ ["input2", { subtype: "free", sourceType: void 0 }],
371
+ ["output", { subtype: "free", sourceType: void 0 }]
372
+ ]),
373
+ config: /* @__PURE__ */ new Map([
374
+ ["initialState", "input1"],
375
+ ["size", "1"]
376
+ ])
377
+ },
378
+ battery: {
379
+ id: "battery",
380
+ name: "Battery",
381
+ pins: /* @__PURE__ */ new Map([
382
+ ["cathode", {
383
+ subtype: "mainVcc",
384
+ sourceType: "Voltage"
385
+ /* Voltage */
386
+ }],
387
+ ["anode", {
388
+ subtype: "mainGnd",
389
+ sourceType: "Current"
390
+ /* Current */
391
+ }]
392
+ ]),
393
+ config: /* @__PURE__ */ new Map([])
394
+ },
395
+ lightbulb: {
396
+ id: "lightbulb",
397
+ name: "Lightbulb",
398
+ pins: /* @__PURE__ */ new Map([
399
+ ["pin1", { subtype: "free", sourceType: void 0 }],
400
+ ["pin2", { subtype: "free", sourceType: void 0 }]
401
+ ]),
402
+ config: /* @__PURE__ */ new Map([["size", "1"]])
403
+ },
404
+ relay: {
405
+ id: "relay",
406
+ name: "Relay",
407
+ pins: /* @__PURE__ */ new Map([
408
+ ["cmd_in", { subtype: "free", sourceType: void 0 }],
409
+ ["cmd_out", { subtype: "free", sourceType: void 0 }],
410
+ ["power_in", { subtype: "free", sourceType: void 0 }],
411
+ ["power_out", { subtype: "free", sourceType: void 0 }]
412
+ ]),
413
+ config: /* @__PURE__ */ new Map([
414
+ ["activationLogic", "positive"],
415
+ ["initializationOrder", ""]
416
+ ])
417
+ },
418
+ smallLED: {
419
+ id: "smallLED",
420
+ name: "SmallLED",
421
+ pins: /* @__PURE__ */ new Map([
422
+ ["pin1", { subtype: "free", sourceType: void 0 }],
423
+ ["pin2", { subtype: "free", sourceType: void 0 }]
424
+ ]),
425
+ config: /* @__PURE__ */ new Map([
426
+ ["idleColor", "white"],
427
+ ["activeColor", "#ffff00"],
428
+ ["size", "1"],
429
+ ["ywRatio", "1"]
430
+ ])
431
+ },
432
+ rectangleLED: {
433
+ id: "rectangleLED",
434
+ name: "RectangleLED",
435
+ pins: /* @__PURE__ */ new Map([
436
+ ["pin1", { subtype: "free", sourceType: void 0 }],
437
+ ["pin2", { subtype: "free", sourceType: void 0 }]
438
+ ]),
439
+ config: /* @__PURE__ */ new Map([
440
+ ["idleColor", "white"],
441
+ ["activeColor", "#ffff00"],
442
+ ["size", "1"],
443
+ ["hwRatio", "1"],
444
+ ["ywRatio", "1"]
445
+ ])
446
+ },
447
+ cube: {
448
+ id: "cube",
449
+ name: "Cube",
450
+ pins: /* @__PURE__ */ new Map([]),
451
+ config: /* @__PURE__ */ new Map([["color", "red"]])
452
+ },
453
+ label: {
454
+ id: "label",
455
+ name: "Label",
456
+ pins: /* @__PURE__ */ new Map([]),
457
+ config: /* @__PURE__ */ new Map([
458
+ ["text", "Label"],
459
+ ["size", "1"]
460
+ ])
461
+ },
462
+ inverter: {
463
+ id: "inverter",
464
+ name: "Inverter",
465
+ pins: /* @__PURE__ */ new Map([
466
+ ["vcc", {
467
+ subtype: "vcc",
468
+ sourceType: "Voltage"
469
+ /* Voltage */
470
+ }],
471
+ ["input", { subtype: "logicInput", sourceType: void 0 }],
472
+ ["output", { subtype: "logicOutput", sourceType: void 0 }],
473
+ ["gnd", {
474
+ subtype: "gnd",
475
+ sourceType: "Current"
476
+ /* Current */
477
+ }]
478
+ ]),
479
+ config: /* @__PURE__ */ new Map([
480
+ ["defaultLogicFamily", "CMOS1"],
481
+ ["activationLogic", "negative"],
482
+ ["transitionSpan", "1"],
483
+ ["initializationOrder", ""]
484
+ ])
485
+ },
486
+ nandGate: {
487
+ id: "nandGate",
488
+ name: "NAND Gate",
489
+ pins: /* @__PURE__ */ new Map([
490
+ ["vcc", {
491
+ subtype: "vcc",
492
+ sourceType: "Voltage"
493
+ /* Voltage */
494
+ }],
495
+ ["input1", { subtype: "logicInput", sourceType: void 0 }],
496
+ ["input2", { subtype: "logicInput", sourceType: void 0 }],
497
+ ["output", { subtype: "logicOutput", sourceType: void 0 }],
498
+ ["gnd", {
499
+ subtype: "gnd",
500
+ sourceType: "Current"
501
+ /* Current */
502
+ }]
503
+ ]),
504
+ config: /* @__PURE__ */ new Map([
505
+ ["defaultLogicFamily", "CMOS1"],
506
+ ["activationLogic", "negative"],
507
+ ["transitionSpan", "1"],
508
+ ["initializationOrder", ""]
509
+ ])
510
+ },
511
+ nand4Gate: {
512
+ id: "nand4Gate",
513
+ name: "NAND4 Gate",
514
+ pins: /* @__PURE__ */ new Map([
515
+ ["vcc", {
516
+ subtype: "vcc",
517
+ sourceType: "Voltage"
518
+ /* Voltage */
519
+ }],
520
+ ["input1", { subtype: "logicInput", sourceType: void 0 }],
521
+ ["input2", { subtype: "logicInput", sourceType: void 0 }],
522
+ ["input3", { subtype: "logicInput", sourceType: void 0 }],
523
+ ["input4", { subtype: "logicInput", sourceType: void 0 }],
524
+ ["output", { subtype: "logicOutput", sourceType: void 0 }],
525
+ ["gnd", {
526
+ subtype: "gnd",
527
+ sourceType: "Current"
528
+ /* Current */
529
+ }]
530
+ ]),
531
+ config: /* @__PURE__ */ new Map([
532
+ ["defaultLogicFamily", "CMOS1"],
533
+ ["activationLogic", "negative"],
534
+ ["transitionSpan", "2"],
535
+ ["initializationOrder", ""]
536
+ ])
537
+ },
538
+ nand8Gate: {
539
+ id: "nand8Gate",
540
+ name: "NAND8 Gate",
541
+ pins: /* @__PURE__ */ new Map([
542
+ ["vcc", {
543
+ subtype: "vcc",
544
+ sourceType: "Voltage"
545
+ /* Voltage */
546
+ }],
547
+ ["input1", { subtype: "logicInput", sourceType: void 0 }],
548
+ ["input2", { subtype: "logicInput", sourceType: void 0 }],
549
+ ["input3", { subtype: "logicInput", sourceType: void 0 }],
550
+ ["input4", { subtype: "logicInput", sourceType: void 0 }],
551
+ ["input5", { subtype: "logicInput", sourceType: void 0 }],
552
+ ["input6", { subtype: "logicInput", sourceType: void 0 }],
553
+ ["input7", { subtype: "logicInput", sourceType: void 0 }],
554
+ ["input8", { subtype: "logicInput", sourceType: void 0 }],
555
+ ["output", { subtype: "logicOutput", sourceType: void 0 }],
556
+ ["gnd", {
557
+ subtype: "gnd",
558
+ sourceType: "Current"
559
+ /* Current */
560
+ }]
561
+ ]),
562
+ config: /* @__PURE__ */ new Map([
563
+ ["defaultLogicFamily", "CMOS1"],
564
+ ["activationLogic", "negative"],
565
+ ["transitionSpan", "3"],
566
+ ["initializationOrder", ""]
567
+ ])
568
+ },
569
+ norGate: {
570
+ id: "norGate",
571
+ name: "NOR Gate",
572
+ pins: /* @__PURE__ */ new Map([
573
+ ["vcc", {
574
+ subtype: "vcc",
575
+ sourceType: "Voltage"
576
+ /* Voltage */
577
+ }],
578
+ ["input1", { subtype: "logicInput", sourceType: void 0 }],
579
+ ["input2", { subtype: "logicInput", sourceType: void 0 }],
580
+ ["output", { subtype: "logicOutput", sourceType: void 0 }],
581
+ ["gnd", {
582
+ subtype: "gnd",
583
+ sourceType: "Current"
584
+ /* Current */
585
+ }]
586
+ ]),
587
+ config: /* @__PURE__ */ new Map([
588
+ ["defaultLogicFamily", "CMOS1"],
589
+ ["activationLogic", "negative"],
590
+ ["transitionSpan", "1"],
591
+ ["initializationOrder", ""]
592
+ ])
593
+ },
594
+ nor4Gate: {
595
+ id: "nor4Gate",
596
+ name: "NOR4 Gate",
597
+ pins: /* @__PURE__ */ new Map([
598
+ ["vcc", {
599
+ subtype: "vcc",
600
+ sourceType: "Voltage"
601
+ /* Voltage */
602
+ }],
603
+ ["input1", { subtype: "logicInput", sourceType: void 0 }],
604
+ ["input2", { subtype: "logicInput", sourceType: void 0 }],
605
+ ["input3", { subtype: "logicInput", sourceType: void 0 }],
606
+ ["input4", { subtype: "logicInput", sourceType: void 0 }],
607
+ ["output", { subtype: "logicOutput", sourceType: void 0 }],
608
+ ["gnd", {
609
+ subtype: "gnd",
610
+ sourceType: "Current"
611
+ /* Current */
612
+ }]
613
+ ]),
614
+ config: /* @__PURE__ */ new Map([
615
+ ["defaultLogicFamily", "CMOS1"],
616
+ ["activationLogic", "negative"],
617
+ ["transitionSpan", "2"],
618
+ ["initializationOrder", ""]
619
+ ])
620
+ },
621
+ nor8Gate: {
622
+ id: "nor8Gate",
623
+ name: "NOR8 Gate",
624
+ pins: /* @__PURE__ */ new Map([
625
+ ["vcc", {
626
+ subtype: "vcc",
627
+ sourceType: "Voltage"
628
+ /* Voltage */
629
+ }],
630
+ ["input1", { subtype: "logicInput", sourceType: void 0 }],
631
+ ["input2", { subtype: "logicInput", sourceType: void 0 }],
632
+ ["input3", { subtype: "logicInput", sourceType: void 0 }],
633
+ ["input4", { subtype: "logicInput", sourceType: void 0 }],
634
+ ["input5", { subtype: "logicInput", sourceType: void 0 }],
635
+ ["input6", { subtype: "logicInput", sourceType: void 0 }],
636
+ ["input7", { subtype: "logicInput", sourceType: void 0 }],
637
+ ["input8", { subtype: "logicInput", sourceType: void 0 }],
638
+ ["output", { subtype: "logicOutput", sourceType: void 0 }],
639
+ ["gnd", {
640
+ subtype: "gnd",
641
+ sourceType: "Current"
642
+ /* Current */
643
+ }]
644
+ ]),
645
+ config: /* @__PURE__ */ new Map([
646
+ ["defaultLogicFamily", "CMOS1"],
647
+ ["activationLogic", "negative"],
648
+ ["transitionSpan", "3"],
649
+ ["initializationOrder", ""]
650
+ ])
651
+ },
652
+ xorGate: {
653
+ id: "xorGate",
654
+ name: "XOR Gate",
655
+ pins: /* @__PURE__ */ new Map([
656
+ ["vcc", {
657
+ subtype: "vcc",
658
+ sourceType: "Voltage"
659
+ /* Voltage */
660
+ }],
661
+ ["input1", { subtype: "logicInput", sourceType: void 0 }],
662
+ ["input2", { subtype: "logicInput", sourceType: void 0 }],
663
+ ["output", { subtype: "logicOutput", sourceType: void 0 }],
664
+ ["gnd", {
665
+ subtype: "gnd",
666
+ sourceType: "Current"
667
+ /* Current */
668
+ }]
669
+ ]),
670
+ config: /* @__PURE__ */ new Map([
671
+ ["defaultLogicFamily", "CMOS1"],
672
+ ["activationLogic", "positive"],
673
+ ["transitionSpan", "2"],
674
+ ["initializationOrder", ""]
675
+ ])
676
+ },
677
+ xor4Gate: {
678
+ id: "xor4Gate",
679
+ name: "XOR4 Gate",
680
+ pins: /* @__PURE__ */ new Map([
681
+ ["vcc", {
682
+ subtype: "vcc",
683
+ sourceType: "Voltage"
684
+ /* Voltage */
685
+ }],
686
+ ["input1", { subtype: "logicInput", sourceType: void 0 }],
687
+ ["input2", { subtype: "logicInput", sourceType: void 0 }],
688
+ ["input3", { subtype: "logicInput", sourceType: void 0 }],
689
+ ["input4", { subtype: "logicInput", sourceType: void 0 }],
690
+ ["output", { subtype: "logicOutput", sourceType: void 0 }],
691
+ ["gnd", {
692
+ subtype: "gnd",
693
+ sourceType: "Current"
694
+ /* Current */
695
+ }]
696
+ ]),
697
+ config: /* @__PURE__ */ new Map([
698
+ ["defaultLogicFamily", "CMOS1"],
699
+ ["activationLogic", "positive"],
700
+ ["transitionSpan", "4"],
701
+ ["initializationOrder", ""]
702
+ ])
703
+ },
704
+ xor8Gate: {
705
+ id: "xor8Gate",
706
+ name: "XOR8 Gate",
707
+ pins: /* @__PURE__ */ new Map([
708
+ ["vcc", {
709
+ subtype: "vcc",
710
+ sourceType: "Voltage"
711
+ /* Voltage */
712
+ }],
713
+ ["input1", { subtype: "logicInput", sourceType: void 0 }],
714
+ ["input2", { subtype: "logicInput", sourceType: void 0 }],
715
+ ["input3", { subtype: "logicInput", sourceType: void 0 }],
716
+ ["input4", { subtype: "logicInput", sourceType: void 0 }],
717
+ ["input5", { subtype: "logicInput", sourceType: void 0 }],
718
+ ["input6", { subtype: "logicInput", sourceType: void 0 }],
719
+ ["input7", { subtype: "logicInput", sourceType: void 0 }],
720
+ ["input8", { subtype: "logicInput", sourceType: void 0 }],
721
+ ["output", { subtype: "logicOutput", sourceType: void 0 }],
722
+ ["gnd", {
723
+ subtype: "gnd",
724
+ sourceType: "Current"
725
+ /* Current */
726
+ }]
727
+ ]),
728
+ config: /* @__PURE__ */ new Map([
729
+ ["defaultLogicFamily", "CMOS1"],
730
+ ["activationLogic", "positive"],
731
+ ["transitionSpan", "6"],
732
+ ["initializationOrder", ""]
733
+ ])
734
+ }
735
+ };
736
+ class k {
737
+ /**
738
+ * Unique identifier for this ENode.
739
+ * @readonly
740
+ */
741
+ id;
742
+ /**
743
+ * Type of electrical node (Pin or BranchingPoint).
744
+ * @readonly
745
+ */
746
+ type;
747
+ /**
748
+ * Parent component UUID (only for pin nodes).
749
+ * Undefined for branching point nodes.
750
+ * @readonly
751
+ */
752
+ component;
753
+ /**
754
+ * Pin label within component (only for pin nodes).
755
+ * Undefined for branching point nodes.
756
+ * @readonly
757
+ */
758
+ pinLabel;
759
+ /**
760
+ * Grid position (only for branching point nodes).
761
+ * Undefined for pin nodes (position derived from component).
762
+ * @readonly
763
+ */
764
+ position;
765
+ /**
766
+ * Set of wire UUIDs connected to this node.
767
+ * Mutable to allow wire connections/disconnections.
768
+ */
769
+ wires;
770
+ /**
771
+ * Is the ENode a source of voltage or current?
772
+ */
773
+ source;
774
+ /**
775
+ * Pin role classification: free, mainVcc, vcc, mainGnd, gnd, logicInput, logicOutput.
776
+ * @readonly
777
+ */
778
+ subtype;
779
+ /**
780
+ * Create a new electrical node.
781
+ *
782
+ * **Note**: Typically ENodes are created automatically by Circuit.
783
+ * This constructor is used internally.
784
+ *
785
+ * @param type - Node type (Pin or BranchingPoint)
786
+ * @param component - Parent component UUID (pin nodes only)
787
+ * @param pinLabel - Pin label (pin nodes only)
788
+ * @param position - Grid position (branching points only)
789
+ * @param source - Source type (Voltage/Current) or undefined
790
+ *
791
+ * @param subtype
792
+ * @example
793
+ * ```typescript
794
+ * // Pin node (internal to Circuit)
795
+ * const pinNode = new ENode(
796
+ * ENodeType.Pin,
797
+ * componentId,
798
+ * '0', // first pin
799
+ * undefined,
800
+ * undefined
801
+ * );
802
+ *
803
+ * // Branching point node
804
+ * const branchNode = new ENode(
805
+ * ENodeType.BranchingPoint,
806
+ * undefined,
807
+ * undefined,
808
+ * new Position(15, 25),
809
+ * undefined
810
+ * );
811
+ * ```
812
+ */
813
+ constructor(t, e, i, n, r = void 0, a = "free") {
814
+ this.id = O(), this.type = t, this.component = e, this.pinLabel = i, this.position = n, this.wires = /* @__PURE__ */ new Set(), this.source = r, this.subtype = a;
815
+ }
816
+ /**
817
+ * Get the position of this electrical node.
818
+ *
819
+ * **Pin nodes**: Derives position from parent component.
820
+ * **Branching nodes**: Returns stored position directly.
821
+ *
822
+ * @param circuit - Circuit instance (needed to look up component for pin nodes)
823
+ * @returns Position on the grid
824
+ *
825
+ * @example
826
+ * ```typescript
827
+ * const circuit = new Circuit();
828
+ * const component = circuit.addComponent(
829
+ * new Position(10, 20),
830
+ * new Rotation(0),
831
+ * 1
832
+ * );
833
+ *
834
+ * const pinNode = circuit.getENode(component.pins[0]);
835
+ * const position = pinNode.getPosition(circuit);
836
+ * console.log(position.x); // 10 (derived from component)
837
+ * ```
838
+ */
839
+ getPosition(t) {
840
+ if (this.type === S.Pin) {
841
+ if (!this.component)
842
+ throw new Error("Pin node missing component reference");
843
+ const e = t.getComponent(this.component);
844
+ if (!e)
845
+ throw new Error(`Component ${this.component} not found for pin node ${this.id}`);
846
+ return e.position;
847
+ }
848
+ if (!this.position)
849
+ throw new Error("Branching point node missing position");
850
+ return this.position;
851
+ }
852
+ /**
853
+ * Update the enode (branching point only)'s position.
854
+ *
855
+ * @param newPosition - The new position for the enode
856
+ *
857
+ * @example
858
+ * ```typescript
859
+ * const component = circuit.getComponent(componentId);
860
+ * component.setPosition(new Position(15, 25));
861
+ * ```
862
+ */
863
+ setPosition(t) {
864
+ Object.defineProperty(this, "position", {
865
+ value: t,
866
+ writable: !1,
867
+ enumerable: !0,
868
+ configurable: !0
869
+ });
870
+ }
871
+ /**
872
+ * Update the enode's source type.
873
+ * @param sourceType
874
+ */
875
+ setSourceType(t) {
876
+ Object.defineProperty(this, "source", {
877
+ value: t,
878
+ writable: !0,
879
+ enumerable: !0,
880
+ configurable: !0
881
+ });
882
+ }
883
+ /**
884
+ * Serialize ENode to JSON.
885
+ *
886
+ * @returns Plain object representation
887
+ *
888
+ * @example
889
+ * ```typescript
890
+ * const json = enode.toJSON();
891
+ * console.log(json);
892
+ * // Pin node:
893
+ * // {
894
+ * // id: "uuid",
895
+ * // type: "Pin",
896
+ * // component: "component-uuid",
897
+ * // pinLabel: "0"
898
+ * // }
899
+ *
900
+ * // Branching node:
901
+ * // {
902
+ * // id: "uuid",
903
+ * // type: "BranchingPoint",
904
+ * // position: { x: 15, y: 25 }
905
+ * // }
906
+ * ```
907
+ */
908
+ toJSON() {
909
+ const t = {
910
+ id: this.id,
911
+ type: this.type,
912
+ source: this.source || null,
913
+ subtype: this.subtype
914
+ };
915
+ return this.type === S.Pin ? (t.component = this.component || null, t.pinLabel = this.pinLabel || null) : t.position = this.position?.toJSON() || null, t;
916
+ }
917
+ /**
918
+ * Deserialize ENode from JSON.
919
+ *
920
+ * @param json - ENode data
921
+ * @returns ENode instance
922
+ *
923
+ * @example
924
+ * ```typescript
925
+ * const json = {
926
+ * id: "uuid",
927
+ * type: "Pin",
928
+ * component: "component-uuid",
929
+ * pinLabel: "0"
930
+ * };
931
+ *
932
+ * const enode = ENode.fromJSON(json);
933
+ * ```
934
+ */
935
+ static fromJSON(t) {
936
+ const e = t.position ? T.fromJSON(t.position) : void 0, i = new k(
937
+ t.type,
938
+ t.component || void 0,
939
+ t.pinLabel || void 0,
940
+ e,
941
+ t.source || void 0,
942
+ t.subtype ?? "free"
943
+ );
944
+ return Object.defineProperty(i, "id", {
945
+ value: t.id,
946
+ writable: !1,
947
+ enumerable: !0,
948
+ configurable: !1
949
+ }), i;
950
+ }
951
+ }
952
+ class E {
461
953
  /**
462
954
  * Unique identifier for this component.
463
955
  * @readonly
@@ -488,10 +980,14 @@ class A {
488
980
  * Configuration parameters for this component instance.
489
981
  *
490
982
  * This map holds key-value pairs representing configurable settings
491
- * The available configuration keys depend on the component type see ComponentTypeMetadata for details.
983
+ * The available configuration keys depend on the component type see IComponentTypeMetadata for details.
492
984
  *
493
985
  */
494
986
  config;
987
+ /**
988
+ * allow to flag a component as non editable (feature to implement)
989
+ */
990
+ editable;
495
991
  /**
496
992
  * Create a new component.
497
993
  *
@@ -504,6 +1000,7 @@ class A {
504
1000
  * @param rotation - Orientation angle (integer degrees)
505
1001
  * @param pins - Array of pin ENode UUIDs
506
1002
  *
1003
+ * @param editable
507
1004
  * @example
508
1005
  * ```typescript
509
1006
  * // Usually created via Circuit:
@@ -522,21 +1019,21 @@ class A {
522
1019
  * );
523
1020
  * ```
524
1021
  */
525
- constructor(t, e, r, i) {
526
- if (this.id = I(), this.type = t, this.position = e, this.rotation = r, new Set(i).size !== i.length) {
527
- const o = i.filter((a, c) => i.indexOf(a) !== c);
1022
+ constructor(t, e, i, n, r = !0) {
1023
+ if (this.id = O(), this.type = t, this.position = e, this.rotation = i, new Set(n).size !== n.length) {
1024
+ const a = n.filter((c, h) => n.indexOf(c) !== h);
528
1025
  throw new Error(
529
- `Duplicate pin names are not allowed: ${[...new Set(o)].join(", ")}`
1026
+ `Duplicate pin names are not allowed: ${[...new Set(a)].join(", ")}`
530
1027
  );
531
1028
  }
532
- this.pins = i, this.config = new Map(E[t].config);
1029
+ this.pins = n, this.config = new Map(I[t].config), this.editable = r;
533
1030
  }
534
1031
  getPinLabel(t) {
535
1032
  const e = this.pins.indexOf(t);
536
1033
  if (e === -1)
537
1034
  return;
538
- const r = N(this.type).pins.keys();
539
- return Array.from(r)[e] || void 0;
1035
+ const i = I[this.type].pins.keys();
1036
+ return Array.from(i)[e] || void 0;
540
1037
  }
541
1038
  setAllParameters(t) {
542
1039
  this.config = new Map(t);
@@ -607,7 +1104,8 @@ class A {
607
1104
  position: this.position.toJSON(),
608
1105
  rotation: this.rotation.toJSON(),
609
1106
  pins: [...this.pins],
610
- config: Object.fromEntries(this.config)
1107
+ config: Object.fromEntries(this.config),
1108
+ editable: this.editable
611
1109
  };
612
1110
  }
613
1111
  /**
@@ -616,27 +1114,14 @@ class A {
616
1114
  * @param json - Component data
617
1115
  * @returns Component instance
618
1116
  *
619
- * @example
620
- * ```typescript
621
- * const json = {
622
- * id: "550e8400-...",
623
- * type: "battery",
624
- * position: { x: 10, y: 20 },
625
- * rotation: 90,
626
- * pins: ['1b4f6f3c-ce ....', '2c5e7g4d-df ...'],
627
- * config: { "voltage": "5V" }
628
- * };
629
- *
630
- * const component = Component.fromJSON(json);
631
- * console.log(component.position.x); // 10
632
- * ```
633
1117
  */
634
1118
  static fromJSON(t) {
635
- const e = new A(
1119
+ const e = new E(
636
1120
  t.type,
637
- v.fromJSON(t.position),
1121
+ T.fromJSON(t.position),
638
1122
  C.fromJSON(t.rotation),
639
- t.pins
1123
+ t.pins,
1124
+ t.editable
640
1125
  );
641
1126
  return e.config = new Map(Object.entries(t.config)), Object.defineProperty(e, "id", {
642
1127
  value: t.id,
@@ -646,207 +1131,107 @@ class A {
646
1131
  }), e;
647
1132
  }
648
1133
  }
649
- class b {
650
- /**
651
- * Current simulation step number (starts at 0).
652
- * @readonly
653
- */
654
- tick;
655
- /**
656
- * Electrical state for each ENode (component pins and branching points).
657
- * Key: ENode UUID, Value: NodeElectricalState
658
- * @readonly
659
- */
660
- nodeStates;
661
- /**
662
- * Electrical state for each Wire connecting ENodes.
663
- * Key: Wire UUID, Value: NodeElectricalState
664
- * @readonly
665
- */
666
- wireStates;
1134
+ const F = {
667
1135
  /**
668
- * Component-specific state for each component.
669
- * Key: Component UUID, Value: ComponentState subclass
670
- * @readonly
671
- */
672
- componentStates;
673
- /**
674
- * Create a new simulation state snapshot.
675
- *
676
- * @param tick - Current simulation step number
677
- */
678
- constructor(t) {
679
- if (t < 0 || !Number.isInteger(t))
680
- throw new RangeError(`Tick must be a non-negative integer (got ${t})`);
681
- this.tick = t, this.nodeStates = /* @__PURE__ */ new Map(), this.wireStates = /* @__PURE__ */ new Map(), this.componentStates = /* @__PURE__ */ new Map();
682
- }
683
- setTick(t) {
684
- this.tick = t;
685
- }
686
- /**
687
- * Create a deep copy of this state for historical storage.
688
- *
689
- * @returns Cloned SimulationState
690
- */
691
- clone() {
692
- const t = new b(this.tick), e = /* @__PURE__ */ new Map();
693
- for (const [o, a] of this.nodeStates.entries())
694
- e.set(o, { ...a });
695
- const r = /* @__PURE__ */ new Map();
696
- for (const [o, a] of this.wireStates.entries())
697
- r.set(o, { ...a });
698
- const i = /* @__PURE__ */ new Map();
699
- for (const [o, a] of this.componentStates.entries())
700
- i.set(
701
- o,
702
- Object.assign(Object.create(Object.getPrototypeOf(a)), a)
703
- );
704
- return Object.defineProperty(t, "nodeStates", {
705
- value: e,
706
- writable: !1,
707
- configurable: !1,
708
- enumerable: !0
709
- }), Object.defineProperty(t, "wireStates", {
710
- value: r,
711
- writable: !1,
712
- configurable: !1,
713
- enumerable: !0
714
- }), Object.defineProperty(t, "componentStates", {
715
- value: i,
716
- writable: !1,
717
- configurable: !1,
718
- enumerable: !0
719
- }), t;
720
- }
721
- }
722
- class R {
723
- currentState;
724
- history;
725
- historyEnabled;
726
- historyLimit;
727
- historyWriteIndex;
728
- /**
729
- * Create a new state controllerType.
730
- *
731
- * @param enableHistory - Whether to store state history (default: false)
732
- * @param historyLimit - Maximum number of historical states to keep (default: 1000)
733
- */
734
- constructor(t = !1, e = 1e3) {
735
- if (e < 1)
736
- throw new RangeError(`historyLimit must be at least 1 (got ${e})`);
737
- this.historyEnabled = t, this.historyLimit = e, this.currentState = new b(0), this.history = [], this.historyWriteIndex = 0;
738
- }
739
- /**
740
- * Get the current simulation state.
741
- *
742
- * @returns Current state (mutable for simulation controller use)
743
- */
744
- getCurrentState() {
745
- return this.currentState;
746
- }
747
- /**
748
- * Get current tick number.
749
- *
750
- * @returns Current simulation tick
1136
+ * Minimum simulation speed in ticks per second
751
1137
  */
752
- getCurrentTick() {
753
- return this.currentState.tick;
754
- }
755
- /**
756
- * Advance to next tick, optionally saving current state to history.
757
- * Creates a new SimulationState for the next tick.
758
- *
759
- * @returns New current state for the next tick
1138
+ MIN_TPS: 1,
1139
+ /**
1140
+ * Maximum simulation speed in ticks per second
760
1141
  */
761
- advanceToNextTick() {
762
- const t = this.currentState.tick + 1;
763
- return this.historyEnabled && this.saveToHistory(this.currentState.clone()), this.currentState.tick = t, this.currentState;
764
- }
1142
+ MAX_TPS: 50,
765
1143
  /**
766
- * Get a historical state by tick number.
767
- * Only works if history is enabled.
768
- *
769
- * @param tick - Tick number to retrieve
770
- * @returns State at that tick, or undefined if not available
1144
+ * Default simulation speed in ticks per second
771
1145
  */
772
- getStateAtTick(t) {
773
- if (this.historyEnabled)
774
- return this.history.find((e) => e.tick === t);
775
- }
1146
+ DEFAULT_TPS: 3,
776
1147
  /**
777
- * Get all available historical states.
778
- * Returns empty array if history is disabled.
779
- *
780
- * @returns Array of historical states, sorted by tick (oldest first)
1148
+ * Default tick interval in milliseconds (1000 / DEFAULT_TPS)
781
1149
  */
782
- getHistory() {
783
- return this.historyEnabled ? [...this.history].sort((t, e) => t.tick - e.tick) : [];
784
- }
1150
+ DEFAULT_INTERVAL_MS: 500
1151
+ }, $ = {
785
1152
  /**
786
- * Get the oldest tick number available in history.
787
- *
788
- * @returns Oldest tick number, or undefined if no history
1153
+ * Default transitionSpan for relays and transistors in ticks (instant transition)
789
1154
  */
790
- getOldestTick() {
791
- if (!(!this.historyEnabled || this.history.length === 0))
792
- return Math.min(...this.history.map((t) => t.tick));
793
- }
1155
+ TRANSITION_SPAN_TICKS: 1,
794
1156
  /**
795
- * Get the newest tick number in history (not including current tick).
796
- *
797
- * @returns Newest historical tick, or undefined if no history
1157
+ * Default transitionUserSpan for switches in milliseconds
798
1158
  */
799
- getNewestHistoricalTick() {
800
- if (!(!this.historyEnabled || this.history.length === 0))
801
- return Math.max(...this.history.map((t) => t.tick));
802
- }
1159
+ TRANSITION_USER_SPAN_MS: 200
1160
+ };
1161
+ class w {
803
1162
  /**
804
- * Clear all history.
1163
+ * Current simulation step number (starts at 0).
1164
+ * @readonly
805
1165
  */
806
- clearHistory() {
807
- this.history = [], this.historyWriteIndex = 0;
808
- }
1166
+ tick;
809
1167
  /**
810
- * Reset to tick 0, clearing current state and all history.
1168
+ * Electrical state for each ENode (component pins and branching points).
1169
+ * Key: ENode UUID, Value: INodeElectricalState
1170
+ * @readonly
811
1171
  */
812
- reset() {
813
- this.currentState = new b(0), this.clearHistory();
814
- }
1172
+ nodeStates;
815
1173
  /**
816
- * Check if history tracking is enabled.
817
- *
818
- * @returns True if history is enabled
1174
+ * Electrical state for each Wire connecting ENodes.
1175
+ * Key: Wire UUID, Value: INodeElectricalState
1176
+ * @readonly
819
1177
  */
820
- isHistoryEnabled() {
821
- return this.historyEnabled;
822
- }
1178
+ wireStates;
823
1179
  /**
824
- * Get the configured history limit.
825
- *
826
- * @returns Maximum number of historical states
1180
+ * Component-specific state for each component.
1181
+ * Key: Component UUID, Value: ComponentState subclass
1182
+ * @readonly
827
1183
  */
828
- getHistoryLimit() {
829
- return this.historyLimit;
830
- }
1184
+ componentStates;
831
1185
  /**
832
- * Get current history size.
1186
+ * Create a new simulation state snapshot.
833
1187
  *
834
- * @returns Number of states in history
1188
+ * @param tick - Current simulation step number
835
1189
  */
836
- getHistorySize() {
837
- return this.history.length;
1190
+ constructor(t) {
1191
+ if (t < 0 || !Number.isInteger(t))
1192
+ throw new RangeError(`Tick must be a non-negative integer (got ${t})`);
1193
+ this.tick = t, this.nodeStates = /* @__PURE__ */ new Map(), this.wireStates = /* @__PURE__ */ new Map(), this.componentStates = /* @__PURE__ */ new Map();
1194
+ }
1195
+ setTick(t) {
1196
+ this.tick = t;
838
1197
  }
839
1198
  /**
840
- * Save a state to history using circular buffer.
841
- * Private helper for advanceToNextTick.
1199
+ * Create a deep copy of this state for historical storage.
842
1200
  *
843
- * @param state - State to save
1201
+ * @returns Cloned SimulationState
844
1202
  */
845
- saveToHistory(t) {
846
- this.history.length < this.historyLimit ? this.history.push(t) : (this.history[this.historyWriteIndex] = t, this.historyWriteIndex = (this.historyWriteIndex + 1) % this.historyLimit);
1203
+ clone() {
1204
+ const t = new w(this.tick), e = /* @__PURE__ */ new Map();
1205
+ for (const [r, a] of this.nodeStates.entries())
1206
+ e.set(r, { ...a });
1207
+ const i = /* @__PURE__ */ new Map();
1208
+ for (const [r, a] of this.wireStates.entries())
1209
+ i.set(r, { ...a });
1210
+ const n = /* @__PURE__ */ new Map();
1211
+ for (const [r, a] of this.componentStates.entries())
1212
+ n.set(
1213
+ r,
1214
+ Object.assign(Object.create(Object.getPrototypeOf(a)), a)
1215
+ );
1216
+ return Object.defineProperty(t, "nodeStates", {
1217
+ value: e,
1218
+ writable: !1,
1219
+ configurable: !1,
1220
+ enumerable: !0
1221
+ }), Object.defineProperty(t, "wireStates", {
1222
+ value: i,
1223
+ writable: !1,
1224
+ configurable: !1,
1225
+ enumerable: !0
1226
+ }), Object.defineProperty(t, "componentStates", {
1227
+ value: n,
1228
+ writable: !1,
1229
+ configurable: !1,
1230
+ enumerable: !0
1231
+ }), t;
847
1232
  }
848
1233
  }
849
- class x {
1234
+ class D {
850
1235
  heap;
851
1236
  /**
852
1237
  * Create a new empty event queue.
@@ -878,10 +1263,10 @@ class x {
878
1263
  getReadyEvents(t) {
879
1264
  const e = [];
880
1265
  for (; this.heap.length > 0 && this.heap[0].readyAtTick <= t; ) {
881
- const r = this.extractMin();
882
- r && e.push(r);
1266
+ const i = this.extractMin();
1267
+ i && e.push(i);
883
1268
  }
884
- return e.sort((r, i) => r.readyAtTick === i.readyAtTick ? r.scheduledAtTick - i.scheduledAtTick : r.readyAtTick - i.readyAtTick), e;
1269
+ return e.sort((i, n) => i.readyAtTick === n.readyAtTick ? i.scheduledAtTick - n.scheduledAtTick : i.readyAtTick - n.readyAtTick), e;
885
1270
  }
886
1271
  /**
887
1272
  * Check if any events are pending.
@@ -897,6 +1282,17 @@ class x {
897
1282
  clear() {
898
1283
  this.heap = [];
899
1284
  }
1285
+ /**
1286
+ * Remove all pending events targeting a specific component.
1287
+ * Used when a behavior signals shouldCancelPending (e.g., Vcc loss, input change during transition).
1288
+ *
1289
+ * @param targetId - UUID of the component whose events should be removed
1290
+ * @returns Number of events removed
1291
+ */
1292
+ removeEventsForTarget(t) {
1293
+ const e = this.heap.length;
1294
+ return this.heap = this.heap.filter((i) => i.targetId !== t), this.heap.length !== e && this.rebuildHeap(), e - this.heap.length;
1295
+ }
900
1296
  /**
901
1297
  * Get number of pending events.
902
1298
  *
@@ -905,6 +1301,10 @@ class x {
905
1301
  size() {
906
1302
  return this.heap.length;
907
1303
  }
1304
+ rebuildHeap() {
1305
+ for (let t = Math.floor(this.heap.length / 2) - 1; t >= 0; t--)
1306
+ this.bubbleDown(t);
1307
+ }
908
1308
  bubbleUp(t) {
909
1309
  for (; t > 0; ) {
910
1310
  const e = Math.floor((t - 1) / 2);
@@ -917,10 +1317,10 @@ class x {
917
1317
  bubbleDown(t) {
918
1318
  const e = this.heap.length;
919
1319
  for (; ; ) {
920
- const r = 2 * t + 1, i = 2 * t + 2;
921
- let o = t;
922
- if (r < e && this.heap[r].readyAtTick < this.heap[o].readyAtTick && (o = r), i < e && this.heap[i].readyAtTick < this.heap[o].readyAtTick && (o = i), o !== t)
923
- [this.heap[t], this.heap[o]] = [this.heap[o], this.heap[t]], t = o;
1320
+ const i = 2 * t + 1, n = 2 * t + 2;
1321
+ let r = t;
1322
+ if (i < e && this.heap[i].readyAtTick < this.heap[r].readyAtTick && (r = i), n < e && this.heap[n].readyAtTick < this.heap[r].readyAtTick && (r = n), r !== t)
1323
+ [this.heap[t], this.heap[r]] = [this.heap[r], this.heap[t]], t = r;
924
1324
  else
925
1325
  break;
926
1326
  }
@@ -1040,33 +1440,133 @@ class P {
1040
1440
  return this.dirtyEnodes.size;
1041
1441
  }
1042
1442
  }
1043
- const U = {
1443
+ class x {
1444
+ currentState;
1445
+ history;
1446
+ historyEnabled;
1447
+ historyLimit;
1448
+ historyWriteIndex;
1044
1449
  /**
1045
- * Minimum simulation speed in ticks per second
1450
+ * Create a new state controllerType.
1451
+ *
1452
+ * @param enableHistory - Whether to store state history (default: false)
1453
+ * @param historyLimit - Maximum number of historical states to keep (default: 1000)
1046
1454
  */
1047
- MIN_TPS: 1,
1455
+ constructor(t = !1, e = 1e3) {
1456
+ if (e < 1)
1457
+ throw new RangeError(`historyLimit must be at least 1 (got ${e})`);
1458
+ this.historyEnabled = t, this.historyLimit = e, this.currentState = new w(0), this.history = [], this.historyWriteIndex = 0;
1459
+ }
1048
1460
  /**
1049
- * Maximum simulation speed in ticks per second
1461
+ * Get the current simulation state.
1462
+ *
1463
+ * @returns Current state (mutable for simulation controller use)
1050
1464
  */
1051
- MAX_TPS: 50,
1465
+ getCurrentState() {
1466
+ return this.currentState;
1467
+ }
1052
1468
  /**
1053
- * Default simulation speed in ticks per second
1469
+ * Get current tick number.
1470
+ *
1471
+ * @returns Current simulation tick
1054
1472
  */
1055
- DEFAULT_TPS: 3,
1473
+ getCurrentTick() {
1474
+ return this.currentState.tick;
1475
+ }
1056
1476
  /**
1057
- * Default tick interval in milliseconds (1000 / DEFAULT_TPS)
1477
+ * Advance to next tick, optionally saving current state to history.
1478
+ * Creates a new SimulationState for the next tick.
1479
+ *
1480
+ * @returns New current state for the next tick
1058
1481
  */
1059
- DEFAULT_INTERVAL_MS: 500
1060
- }, $ = {
1482
+ advanceToNextTick() {
1483
+ const t = this.currentState.tick + 1;
1484
+ return this.historyEnabled && this.saveToHistory(this.currentState.clone()), this.currentState.tick = t, this.currentState;
1485
+ }
1061
1486
  /**
1062
- * Default transitionSpan for relays and transistors in ticks (instant transition)
1487
+ * Get a historical state by tick number.
1488
+ * Only works if history is enabled.
1489
+ *
1490
+ * @param tick - Tick number to retrieve
1491
+ * @returns State at that tick, or undefined if not available
1063
1492
  */
1064
- TRANSITION_SPAN_TICKS: 1,
1493
+ getStateAtTick(t) {
1494
+ if (this.historyEnabled)
1495
+ return this.history.find((e) => e.tick === t);
1496
+ }
1065
1497
  /**
1066
- * Default transitionUserSpan for switches in milliseconds
1498
+ * Get all available historical states.
1499
+ * Returns empty array if history is disabled.
1500
+ *
1501
+ * @returns Array of historical states, sorted by tick (oldest first)
1067
1502
  */
1068
- TRANSITION_USER_SPAN_MS: 200
1069
- };
1503
+ getHistory() {
1504
+ return this.historyEnabled ? [...this.history].sort((t, e) => t.tick - e.tick) : [];
1505
+ }
1506
+ /**
1507
+ * Get the oldest tick number available in history.
1508
+ *
1509
+ * @returns Oldest tick number, or undefined if no history
1510
+ */
1511
+ getOldestTick() {
1512
+ if (!(!this.historyEnabled || this.history.length === 0))
1513
+ return Math.min(...this.history.map((t) => t.tick));
1514
+ }
1515
+ /**
1516
+ * Get the newest tick number in history (not including current tick).
1517
+ *
1518
+ * @returns Newest historical tick, or undefined if no history
1519
+ */
1520
+ getNewestHistoricalTick() {
1521
+ if (!(!this.historyEnabled || this.history.length === 0))
1522
+ return Math.max(...this.history.map((t) => t.tick));
1523
+ }
1524
+ /**
1525
+ * Clear all history.
1526
+ */
1527
+ clearHistory() {
1528
+ this.history = [], this.historyWriteIndex = 0;
1529
+ }
1530
+ /**
1531
+ * Reset to tick 0, clearing current state and all history.
1532
+ */
1533
+ reset() {
1534
+ this.currentState = new w(0), this.clearHistory();
1535
+ }
1536
+ /**
1537
+ * Check if history tracking is enabled.
1538
+ *
1539
+ * @returns True if history is enabled
1540
+ */
1541
+ isHistoryEnabled() {
1542
+ return this.historyEnabled;
1543
+ }
1544
+ /**
1545
+ * Get the configured history limit.
1546
+ *
1547
+ * @returns Maximum number of historical states
1548
+ */
1549
+ getHistoryLimit() {
1550
+ return this.historyLimit;
1551
+ }
1552
+ /**
1553
+ * Get current history size.
1554
+ *
1555
+ * @returns Number of states in history
1556
+ */
1557
+ getHistorySize() {
1558
+ return this.history.length;
1559
+ }
1560
+ /**
1561
+ * Save a state to history using circular buffer.
1562
+ * Private helper for advanceToNextTick.
1563
+ *
1564
+ * @param state - State to save
1565
+ */
1566
+ saveToHistory(t) {
1567
+ this.history.length < this.historyLimit ? this.history.push(t) : (this.history[this.historyWriteIndex] = t, this.historyWriteIndex = (this.historyWriteIndex + 1) % this.historyLimit);
1568
+ }
1569
+ }
1070
1570
  class J {
1071
1571
  circuit;
1072
1572
  stateManager;
@@ -1081,10 +1581,10 @@ class J {
1081
1581
  * @param behaviorRegistry - Registry of component behaviors
1082
1582
  * @param options - Simulation options (history settings)
1083
1583
  */
1084
- constructor(t, e, r = {}) {
1584
+ constructor(t, e, i = {}) {
1085
1585
  this.circuit = t, this.behaviorRegistry = e;
1086
- const i = r.enableHistory ?? !1, o = r.historyLimit ?? 1e3;
1087
- this.stateManager = new R(i, o), this.eventQueue = new x(), this.commands = /* @__PURE__ */ new Map(), this.dirtyTracker = new P();
1586
+ const n = i.enableHistory ?? !1, r = i.historyLimit ?? 1e3;
1587
+ this.stateManager = new x(n, r), this.eventQueue = new D(), this.commands = /* @__PURE__ */ new Map(), this.dirtyTracker = new P();
1088
1588
  try {
1089
1589
  this.initializeState();
1090
1590
  } catch (a) {
@@ -1098,25 +1598,25 @@ class J {
1098
1598
  * @returns the result of the tick execution
1099
1599
  */
1100
1600
  tick() {
1101
- const t = this.eventQueue.size(), e = this.stateManager.getCurrentTick(), r = this.applyReadyEvents(e + 1), i = this.updateState(e + 1);
1102
- i.firedEventCount = r.length;
1103
- const o = this.processCommands();
1104
- i.processedCommandCount = o.length, i.scheduledEventCount = this.eventQueue.size() + i.firedEventCount - t;
1105
- for (const a of r)
1601
+ const t = this.eventQueue.size(), e = this.stateManager.getCurrentTick(), i = this.applyReadyEvents(e + 1), n = this.updateState(e + 1);
1602
+ n.firedEventCount = i.length;
1603
+ const r = this.processCommands();
1604
+ n.processedCommandCount = r.length, n.scheduledEventCount = this.eventQueue.size() + n.firedEventCount - t;
1605
+ for (const a of i)
1106
1606
  a.hasChanged && this.dirtyTracker.markComponentDirty(a.componentState.componentId);
1107
- return i.componentUpdateCount = this.dirtyTracker.getDirtyComponentCount(), this.stateManager.advanceToNextTick(), i.endTick = this.stateManager.getCurrentTick(), i;
1607
+ return n.componentUpdateCount = this.dirtyTracker.getDirtyComponentCount(), this.stateManager.advanceToNextTick(), n.endTick = this.stateManager.getCurrentTick(), n;
1108
1608
  }
1109
1609
  /**
1110
1610
  * Execute multiple simulation ticks.
1111
1611
  *
1112
1612
  * @param count - Number of ticks to execute
1113
- * @returns an array of RunnerResult for each tick executed
1613
+ * @returns an array of IRunnerResult for each tick executed
1114
1614
  */
1115
1615
  tickN(t) {
1116
1616
  if (t < 1)
1117
1617
  throw new RangeError(`Tick count must be at least 1 (got ${t})`);
1118
1618
  const e = [];
1119
- for (let r = 0; r < t; r++)
1619
+ for (let i = 0; i < t; i++)
1120
1620
  e.push(this.tick());
1121
1621
  return e;
1122
1622
  }
@@ -1206,19 +1706,20 @@ class J {
1206
1706
  * Mark changed components as Dirty and enqueue consequent scheduled events
1207
1707
  * Finally clears command queue after processing.
1208
1708
  *
1209
- * @returns Array of BehaviorResult for each processed command
1709
+ * @returns Array of IBehaviorResult for each processed command
1210
1710
  */
1211
1711
  processCommands() {
1212
1712
  const t = this.stateManager.getCurrentState(), e = [];
1213
- for (const r of this.commands.values()) {
1214
- const i = this.circuit.getComponent(r.targetId), a = this.behaviorRegistry.get(i.type).onUserCommand(
1215
- i,
1216
- t.componentStates.get(i.id),
1217
- r
1713
+ for (const i of this.commands.values()) {
1714
+ const n = this.circuit.getComponent(i.targetId), a = this.behaviorRegistry.get(n.type).onUserCommand(
1715
+ n,
1716
+ t.componentStates.get(n.id),
1717
+ i
1218
1718
  );
1719
+ a.shouldCancelPending && this.eventQueue.removeEventsForTarget(n.id);
1219
1720
  for (const c of a.scheduledEvents)
1220
1721
  this.eventQueue.schedule(c);
1221
- e.push(a), a.hasChanged && this.dirtyTracker.markComponentDirty(i.id);
1722
+ e.push(a), a.hasChanged && this.dirtyTracker.markComponentDirty(n.id);
1222
1723
  }
1223
1724
  return this.commands.clear(), e;
1224
1725
  }
@@ -1232,8 +1733,8 @@ class J {
1232
1733
  getInitializationOrder(t) {
1233
1734
  const e = t.get("initializationOrder");
1234
1735
  if (!e || e === "") return 0;
1235
- const r = parseInt(e, 10);
1236
- return isNaN(r) ? 0 : r;
1736
+ const i = parseInt(e, 10);
1737
+ return isNaN(i) ? 0 : i;
1237
1738
  }
1238
1739
  /**
1239
1740
  * Initialize simulation state for all components.
@@ -1252,16 +1753,16 @@ class J {
1252
1753
  const t = this.stateManager.getCurrentState();
1253
1754
  for (const s of this.circuit.getAllComponents()) {
1254
1755
  if (s.pins.length < 1) continue;
1255
- const h = this.behaviorRegistry.get(s.type);
1256
- if (!h)
1756
+ const u = this.behaviorRegistry.get(s.type);
1757
+ if (!u)
1257
1758
  continue;
1258
- const u = h.createInitialState(s);
1259
- t.componentStates.set(s.id, u), this.dirtyTracker.markComponentDirty(s.id);
1759
+ const d = u.createInitialState(s);
1760
+ t.componentStates.set(s.id, d), this.dirtyTracker.markComponentDirty(s.id);
1260
1761
  }
1261
1762
  for (const s of this.circuit.getAllENodes())
1262
1763
  t.nodeStates.set(s.id, {
1263
- hasVoltage: s.source === S.Voltage,
1264
- hasCurrent: s.source === S.Current,
1764
+ hasVoltage: s.source === v.Voltage,
1765
+ hasCurrent: s.source === v.Current,
1265
1766
  locked: !!s.source
1266
1767
  });
1267
1768
  for (const s of this.circuit.getAllWires())
@@ -1270,50 +1771,50 @@ class J {
1270
1771
  hasCurrent: !1,
1271
1772
  locked: !1
1272
1773
  });
1273
- const e = this.circuit.getAllComponents(), r = /* @__PURE__ */ new Map();
1774
+ const e = this.circuit.getAllComponents(), i = /* @__PURE__ */ new Map();
1274
1775
  for (const s of e) {
1275
- const h = this.getInitializationOrder(s.config), u = r.get(h) ?? [];
1276
- u.push(s), r.set(h, u);
1776
+ const u = this.getInitializationOrder(s.config), d = i.get(u) ?? [];
1777
+ d.push(s), i.set(u, d);
1277
1778
  }
1278
- const i = Array.from(r.keys()).sort((s, h) => s - h);
1279
- for (const s of i)
1280
- r.get(s).sort((u, g) => u.id.localeCompare(g.id));
1281
- let o = !0, a = 0;
1779
+ const n = Array.from(i.keys()).sort((s, u) => s - u);
1780
+ for (const s of n)
1781
+ i.get(s).sort((d, l) => d.id.localeCompare(l.id));
1782
+ let r = !0, a = 0;
1282
1783
  const c = 100;
1283
- for (; o && a < c; ) {
1284
- o = !1, a++;
1285
- for (const s of i) {
1286
- const h = r.get(s);
1287
- for (const u of h) {
1288
- const g = this.behaviorRegistry.get(u.type);
1784
+ for (; r && a < c; ) {
1785
+ r = !1, a++;
1786
+ for (const s of n) {
1787
+ const u = i.get(s);
1788
+ for (const d of u) {
1789
+ const l = this.behaviorRegistry.get(d.type);
1790
+ if (!l) continue;
1791
+ const g = t.componentStates.get(d.id);
1289
1792
  if (!g) continue;
1290
- const f = t.componentStates.get(u.id);
1291
- if (!f) continue;
1292
1793
  this.propagateConductivity();
1293
- const m = g.onPinsChange(
1294
- u,
1295
- f,
1794
+ const b = l.onPinsChange(
1795
+ d,
1796
+ g,
1296
1797
  t.nodeStates,
1297
1798
  0
1298
1799
  );
1299
- m.hasChanged && (o = !0, t.componentStates.set(
1300
- u.id,
1301
- m.componentState
1800
+ b.hasChanged && (r = !0, t.componentStates.set(
1801
+ d.id,
1802
+ b.componentState
1302
1803
  ));
1303
- for (const y of m.scheduledEvents) {
1304
- const d = g.onEventFiring(u, f, y);
1305
- d.hasChanged && (o = !0, t.componentStates.set(
1306
- u.id,
1307
- d.componentState
1804
+ for (const f of b.scheduledEvents) {
1805
+ const p = l.onEventFiring(d, g, f);
1806
+ p.hasChanged && (r = !0, t.componentStates.set(
1807
+ d.id,
1808
+ p.componentState
1308
1809
  ));
1309
1810
  }
1310
1811
  }
1311
1812
  }
1312
1813
  }
1313
- const l = this.updateState(0);
1814
+ const h = this.updateState(0);
1314
1815
  return this.dirtyTracker.setDirtyComponents(
1315
1816
  /* @__PURE__ */ new Set([...this.circuit.getAllComponents().map((s) => s.id)])
1316
- ), this.dirtyTracker.setDirtyEnodes(/* @__PURE__ */ new Set([...this.circuit.getAllENodes().map((s) => s.id)])), this.dirtyTracker.setDirtyWires(/* @__PURE__ */ new Set([...this.circuit.getAllWires().map((s) => s.id)])), l;
1817
+ ), this.dirtyTracker.setDirtyEnodes(/* @__PURE__ */ new Set([...this.circuit.getAllENodes().map((s) => s.id)])), this.dirtyTracker.setDirtyWires(/* @__PURE__ */ new Set([...this.circuit.getAllWires().map((s) => s.id)])), h;
1317
1818
  }
1318
1819
  /**
1319
1820
  * Core method that orchestrates nodes, wires and components state updates
@@ -1321,32 +1822,32 @@ class J {
1321
1822
  * @param targetTick - Tick at which to perform the update
1322
1823
  */
1323
1824
  updateState(t) {
1324
- const e = this.stateManager.getCurrentState(), { updatedNodes: r, updatedWires: i } = this.propagateConductivity(), o = this.circuit.getComponentsOfPins(r), a = /* @__PURE__ */ new Set();
1325
- let c = 0, l = Array.from(o);
1326
- t === 0 && (l = l.sort((s, h) => {
1327
- const u = this.circuit.getComponent(s), g = this.circuit.getComponent(h), f = this.getInitializationOrder(u.config), m = this.getInitializationOrder(g.config);
1328
- return f !== m ? f - m : s.localeCompare(h);
1825
+ const e = this.stateManager.getCurrentState(), { updatedNodes: i, updatedWires: n } = this.propagateConductivity(), r = this.circuit.getComponentsOfPins(i), a = /* @__PURE__ */ new Set();
1826
+ let c = 0, h = Array.from(r);
1827
+ t === 0 && (h = h.sort((s, u) => {
1828
+ const d = this.circuit.getComponent(s), l = this.circuit.getComponent(u), g = this.getInitializationOrder(d.config), b = this.getInitializationOrder(l.config);
1829
+ return g !== b ? g - b : s.localeCompare(u);
1329
1830
  }));
1330
- for (const s of l) {
1331
- const h = this.circuit.getComponent(s), u = this.behaviorRegistry.get(h.type);
1332
- if (!u)
1831
+ for (const s of h) {
1832
+ const u = this.circuit.getComponent(s), d = this.behaviorRegistry.get(u.type);
1833
+ if (!d)
1333
1834
  continue;
1334
- const g = u.onPinsChange(
1335
- h,
1835
+ const l = d.onPinsChange(
1836
+ u,
1336
1837
  e.componentStates.get(s),
1337
1838
  e.nodeStates,
1338
1839
  t
1339
1840
  );
1340
- g.hasChanged && a.add(s);
1341
- for (const f of g.scheduledEvents)
1342
- this.eventQueue.schedule(f), c++;
1841
+ l.shouldCancelPending && this.eventQueue.removeEventsForTarget(s), l.hasChanged && a.add(s);
1842
+ for (const g of l.scheduledEvents)
1843
+ this.eventQueue.schedule(g), c++;
1343
1844
  }
1344
- return this.dirtyTracker.setDirtyComponents(a), this.dirtyTracker.setDirtyEnodes(r), this.dirtyTracker.setDirtyWires(i), {
1845
+ return this.dirtyTracker.setDirtyComponents(a), this.dirtyTracker.setDirtyEnodes(i), this.dirtyTracker.setDirtyWires(n), {
1345
1846
  startTick: this.getCurrentTick(),
1346
1847
  endTick: this.getCurrentTick(),
1347
1848
  componentUpdateCount: a.size,
1348
- nodeUpdateCount: r.size,
1349
- wireUpdateCount: i.size,
1849
+ nodeUpdateCount: i.size,
1850
+ wireUpdateCount: n.size,
1350
1851
  processedCommandCount: 0,
1351
1852
  scheduledEventCount: c,
1352
1853
  firedEventCount: 0
@@ -1360,34 +1861,34 @@ class J {
1360
1861
  */
1361
1862
  propagateConductivity() {
1362
1863
  const t = this.stateManager.getCurrentState(), e = (c) => {
1363
- const l = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set(), h = this.circuit.getAllENodes().filter((d) => d.source == c).map((d) => d.id), u = /* @__PURE__ */ new Set([
1364
- ...this.circuit.getAllENodes().filter((d) => !d.source).map((d) => d.id)
1365
- ]), g = /* @__PURE__ */ new Set([...this.circuit.getAllWires().map((d) => d.id)]), { nodes: f, wires: m } = this.computeReachability(
1864
+ const h = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Set(), u = this.circuit.getAllENodes().filter((p) => p.source == c).map((p) => p.id), d = /* @__PURE__ */ new Set([
1865
+ ...this.circuit.getAllENodes().filter((p) => !p.source).map((p) => p.id)
1866
+ ]), l = /* @__PURE__ */ new Set([...this.circuit.getAllWires().map((p) => p.id)]), { nodes: g, wires: b } = this.computeReachability(
1366
1867
  c,
1367
- h,
1868
+ u,
1368
1869
  t.componentStates
1369
- ), y = c == S.Voltage ? "hasVoltage" : "hasCurrent";
1370
- for (const d of f) {
1371
- const p = t.nodeStates.get(d);
1372
- p && !p.locked && (p[y] || (p[y] = !0, l.add(d)), u.delete(d));
1870
+ ), f = c == v.Voltage ? "hasVoltage" : "hasCurrent";
1871
+ for (const p of g) {
1872
+ const y = t.nodeStates.get(p);
1873
+ y && !y.locked && (y[f] || (y[f] = !0, h.add(p)), d.delete(p));
1373
1874
  }
1374
- for (const d of u) {
1375
- const p = t.nodeStates.get(d);
1376
- p && !p.locked && p[y] && (p[y] = !1, l.add(d));
1875
+ for (const p of d) {
1876
+ const y = t.nodeStates.get(p);
1877
+ y && !y.locked && y[f] && (y[f] = !1, h.add(p));
1377
1878
  }
1378
- for (const d of m) {
1379
- const p = t.wireStates.get(d);
1380
- p && (p[y] || (p[y] = !0, s.add(d)), g.delete(d));
1879
+ for (const p of b) {
1880
+ const y = t.wireStates.get(p);
1881
+ y && (y[f] || (y[f] = !0, s.add(p)), l.delete(p));
1381
1882
  }
1382
- for (const d of g) {
1383
- const p = t.wireStates.get(d);
1384
- p && p[y] && (p[y] = !1, s.add(d));
1883
+ for (const p of l) {
1884
+ const y = t.wireStates.get(p);
1885
+ y && y[f] && (y[f] = !1, s.add(p));
1385
1886
  }
1386
- return { updatedNodes: l, updatedWires: s };
1387
- }, { updatedNodes: r, updatedWires: i } = e(S.Voltage), { updatedNodes: o, updatedWires: a } = e(S.Current);
1887
+ return { updatedNodes: h, updatedWires: s };
1888
+ }, { updatedNodes: i, updatedWires: n } = e(v.Voltage), { updatedNodes: r, updatedWires: a } = e(v.Current);
1388
1889
  return {
1389
- updatedNodes: /* @__PURE__ */ new Set([...r, ...o]),
1390
- updatedWires: /* @__PURE__ */ new Set([...i, ...a])
1890
+ updatedNodes: /* @__PURE__ */ new Set([...i, ...r]),
1891
+ updatedWires: /* @__PURE__ */ new Set([...n, ...a])
1391
1892
  };
1392
1893
  }
1393
1894
  /**
@@ -1398,35 +1899,35 @@ class J {
1398
1899
  * @param seeds
1399
1900
  * @param componentStates
1400
1901
  */
1401
- computeReachability(t, e, r) {
1402
- const i = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Set(), a = [];
1902
+ computeReachability(t, e, i) {
1903
+ const n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), a = [];
1403
1904
  for (const c of e)
1404
- a.push(c), i.add(c);
1905
+ a.push(c), n.add(c);
1405
1906
  for (; a.length > 0; ) {
1406
1907
  const c = a.shift();
1407
1908
  for (const s of this.circuit.getWiresByNode(c)) {
1408
- const h = s.node1 === c ? s.node2 : s.node1;
1409
- i.has(h) || (i.add(h), a.push(h)), o.has(s.id) || o.add(s.id);
1909
+ const u = s.node1 === c ? s.node2 : s.node1;
1910
+ n.has(u) || (n.add(u), a.push(u)), r.has(s.id) || r.add(s.id);
1410
1911
  }
1411
- const l = this.circuit.getENode(c);
1412
- if (l.type === M.Pin) {
1413
- const s = this.circuit.getComponent(l.component), h = this.behaviorRegistry.get(s.type);
1414
- if (!h)
1912
+ const h = this.circuit.getENode(c);
1913
+ if (h.type === S.Pin) {
1914
+ const s = this.circuit.getComponent(h.component), u = this.behaviorRegistry.get(s.type);
1915
+ if (!u)
1415
1916
  continue;
1416
- const u = r.get(s.id);
1417
- for (const g of s.pins) {
1418
- if (g === c || i.has(g)) continue;
1419
- h.allowConductivity(
1917
+ const d = i.get(s.id);
1918
+ for (const l of s.pins) {
1919
+ if (l === c || n.has(l)) continue;
1920
+ u.allowConductivity(
1420
1921
  s,
1421
- u,
1922
+ d,
1422
1923
  t,
1423
1924
  c,
1424
- g
1425
- ) && (i.add(g), a.push(g));
1925
+ l
1926
+ ) && (n.add(l), a.push(l));
1426
1927
  }
1427
1928
  }
1428
1929
  }
1429
- return { nodes: i, wires: o };
1930
+ return { nodes: n, wires: r };
1430
1931
  }
1431
1932
  /**
1432
1933
  * Fire ready events and update current state accordingly
@@ -1438,40 +1939,43 @@ class J {
1438
1939
  * @param targetTick - Target tick for event processing
1439
1940
  */
1440
1941
  applyReadyEvents(t) {
1441
- const e = this.stateManager.getCurrentState(), r = this.eventQueue.getReadyEvents(t), i = [];
1442
- for (const o of r) {
1443
- const a = this.circuit.getComponent(o.targetId), c = this.behaviorRegistry.get(a.type);
1942
+ const e = this.stateManager.getCurrentState(), i = this.eventQueue.getReadyEvents(t), n = [];
1943
+ for (const r of i) {
1944
+ const a = this.circuit.getComponent(r.targetId), c = this.behaviorRegistry.get(a.type);
1444
1945
  if (!c)
1445
1946
  continue;
1446
- const l = e.componentStates.get(a.id), s = c.onEventFiring(a, l, o);
1447
- for (const h of s.scheduledEvents)
1448
- this.eventQueue.schedule(h);
1449
- i.push(s);
1947
+ const h = e.componentStates.get(a.id), s = c.onEventFiring(a, h, r);
1948
+ s.shouldCancelPending && this.eventQueue.removeEventsForTarget(a.id);
1949
+ for (const u of s.scheduledEvents)
1950
+ this.eventQueue.schedule(u);
1951
+ n.push(s);
1450
1952
  }
1451
- return i;
1953
+ return n;
1452
1954
  }
1453
1955
  }
1454
1956
  export {
1455
- k as C,
1456
- P as D,
1457
- S as E,
1458
- v as P,
1957
+ W as A,
1958
+ M as C,
1959
+ U as D,
1960
+ v as E,
1961
+ T as P,
1459
1962
  C as R,
1460
- b as S,
1963
+ F as S,
1461
1964
  $ as T,
1462
- T as a,
1463
- E as b,
1464
- N as c,
1465
- M as d,
1466
- I as e,
1467
- W as f,
1468
- z as g,
1469
- w as h,
1470
- A as i,
1471
- J as j,
1472
- R as k,
1473
- U as l,
1474
- x as m,
1475
- L as s
1965
+ m as a,
1966
+ G as b,
1967
+ L as c,
1968
+ I as d,
1969
+ S as e,
1970
+ R as f,
1971
+ O as g,
1972
+ k as h,
1973
+ E as i,
1974
+ D as j,
1975
+ P as k,
1976
+ x as l,
1977
+ J as m,
1978
+ w as n,
1979
+ z as s
1476
1980
  };
1477
- //# sourceMappingURL=CircuitRunner-FXM_s5ll.js.map
1981
+ //# sourceMappingURL=CircuitRunner-BQQlhwjD.js.map