@prozilla-os/logic-sim 1.1.19 → 1.1.21

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/main.js CHANGED
@@ -1,60 +1,65 @@
1
1
  (function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode("._CircuitView_dfvf4_1{display:flex;width:100%;height:calc(100% - var(--header-height));flex-grow:1}._Canvas_dfvf4_8{flex:1;width:100%;height:100%}._LogicSim_k1eu4_1{display:flex;flex-direction:column;width:100%;height:100%}._LogicSim_k1eu4_1{--black-0: hsl(210, 15%, 55%);--black-1: hsl(210, 15%, 40%);--black-2: hsl(210, 15%, 30%);--black-3: hsl(210, 15%, 20%);--black-4: hsl(210, 15%, 12.5%)}")),document.head.appendChild(e)}}catch(i){console.error("vite-plugin-css-injected-by-js",i)}})();
2
- var F = Object.defineProperty;
3
- var Z = (P, i, t) => i in P ? F(P, i, { enumerable: !0, configurable: !0, writable: !0, value: t }) : P[i] = t;
4
- var o = (P, i, t) => Z(P, typeof i != "symbol" ? i + "" : i, t);
5
- import { Vector2 as h, useAppFolder as q, HeaderMenu as K, DropdownAction as j, ClickAction as k, openUrl as X, App as Y } from "@prozilla-os/core";
6
- import { jsxs as D, Fragment as G, jsx as w } from "react/jsx-runtime";
7
- import { useState as _, useRef as Q, useEffect as ii } from "react";
8
- import { clamp as ti } from "@prozilla-os/shared";
9
- const si = "_CircuitView_dfvf4_1", ei = "_Canvas_dfvf4_8", J = {
10
- CircuitView: si,
11
- Canvas: ei
12
- }, O = class O {
2
+ import { Actions as $, ClickAction as w, useAppFolder as F, useSingleton as V, useManualContextMenu as X, HeaderMenu as Y, DropdownAction as k, Divider as L, openUrl as Z, App as G } from "@prozilla-os/core";
3
+ import { jsxs as v, jsx as u, Fragment as _ } from "react/jsx-runtime";
4
+ import { useRef as q, useEffect as K } from "react";
5
+ import { Vector2 as l, removeFromArray as Q, clamp as ii } from "@prozilla-os/shared";
6
+ const ti = "_CircuitView_dfvf4_1", si = "_Canvas_dfvf4_8", S = {
7
+ CircuitView: ti,
8
+ Canvas: si
9
+ };
10
+ class d {
11
+ value;
12
+ static LOW = new d(0);
13
+ static HIGH = new d(1);
13
14
  constructor(i) {
14
- o(this, "value");
15
15
  this.value = i;
16
16
  }
17
17
  static invert(i) {
18
- return new O(1 - i.value);
18
+ return new d(1 - i.value);
19
19
  }
20
20
  isEqual(i) {
21
21
  return this.value === i.value;
22
22
  }
23
- };
24
- o(O, "LOW", new O(0)), o(O, "HIGH", new O(1));
25
- let C = O;
26
- const S = {
23
+ isLow() {
24
+ return this.value === 0;
25
+ }
26
+ isHigh() {
27
+ return this.value === 1;
28
+ }
29
+ }
30
+ const y = {
27
31
  default: "default",
28
32
  pointer: "pointer"
29
- }, A = "outfit", $ = {
33
+ }, T = "outfit", B = {
30
34
  padding: 30,
31
35
  borderWidth: 7.5
32
- }, a = {
36
+ }, c = {
33
37
  radius: 25,
34
38
  borderWidth: 5,
35
39
  pinOffset: 42.5,
36
40
  connectorWidth: 7.5,
37
41
  handleWidth: 15,
42
+ handleHeight: 50,
38
43
  handleTrackWidth: 22.5,
39
44
  placingOpacity: 0.5
40
- }, H = {
45
+ }, W = {
41
46
  width: 5,
42
47
  snappingSensitivity: 10,
43
48
  cornerRadius: 25,
44
49
  resolution: 8
45
- }, d = {
50
+ }, h = {
46
51
  radius: 10,
47
52
  label: {
48
53
  offset: 10,
49
54
  fontSize: 15,
50
55
  padding: 5
51
56
  }
52
- }, m = {
57
+ }, g = {
53
58
  BorderWidth: 5,
54
59
  padding: 10,
55
60
  fontSize: 35,
56
61
  placingOutline: 10
57
- }, g = {
62
+ }, p = {
58
63
  pin: {
59
64
  fill: "black-4",
60
65
  fillHover: "black-3",
@@ -76,26 +81,26 @@ const S = {
76
81
  inner: "black-2",
77
82
  margin: "black-2"
78
83
  },
79
- wire: {
80
- placing: "black-1"
81
- },
82
84
  chip: {
83
85
  text: "black-4",
84
86
  outline: "white-0"
85
87
  }
86
88
  };
87
- class L {
88
- constructor(i, t, s, e, n) {
89
- o(this, "id");
90
- o(this, "name");
91
- o(this, "position", h.ZERO);
92
- o(this, "attachedChip");
93
- o(this, "circuit");
94
- o(this, "state", C.LOW);
95
- o(this, "isInput");
96
- o(this, "isControlled", !1);
97
- o(this, "outputWires", []);
98
- Object.assign(this, { circuit: i, name: t, isInput: s, attachedChip: e }), this.id = n ?? this.circuit.getUniqueId();
89
+ class b {
90
+ id;
91
+ name;
92
+ position = l.ZERO;
93
+ attachedChip;
94
+ circuit;
95
+ state = d.LOW;
96
+ isInput;
97
+ isControlled = !1;
98
+ outputWires = [];
99
+ constructor(i, t, s, e, o) {
100
+ Object.assign(this, { circuit: i, name: t, isInput: s, attachedChip: e }), this.id = o ?? this.circuit.getUniqueId();
101
+ }
102
+ getRawPosition() {
103
+ return l.product(this.position, this.circuit.size);
99
104
  }
100
105
  addOutputWire(i) {
101
106
  this.outputWires.push(i), i.setState(this.state);
@@ -104,45 +109,45 @@ class L {
104
109
  this.state.isEqual(i) || (this.state = i, this.update());
105
110
  }
106
111
  update() {
107
- var i;
108
- this.outputWires.forEach((t) => {
109
- t.setState(this.state);
110
- }), (i = this.attachedChip) == null || i.update();
112
+ this.outputWires.forEach((i) => {
113
+ i.setState(this.state);
114
+ }), this.attachedChip.update();
111
115
  }
112
116
  get isPointingRight() {
113
117
  return this.isInput === this.isControlled;
114
118
  }
115
119
  draw(i) {
116
- let t = g.pin.fill;
117
- if (this.circuit.inputHandler.mousePosition.getDistance(this.position.x, this.position.y) <= d.radius) {
118
- this.circuit.cursor = S.pointer, t = g.pin.fillHover;
119
- let s = this.position.x;
120
- const e = this.isPointingRight, n = this.circuit.getTextRect(d.label.fontSize, this.name);
121
- e ? s += d.radius + d.label.offset : s -= d.radius + d.label.offset;
122
- const r = {
123
- x: n.x + d.label.padding * 2,
124
- y: n.y + d.label.padding * 2
120
+ let t = p.pin.fill;
121
+ const { x: s, y: e } = this.getRawPosition();
122
+ if (this.circuit.inputHandler.rawMousePosition.getDistance(this.position.x * this.circuit.size.x, e) <= h.radius) {
123
+ this.circuit.cursor = y.pointer, t = p.pin.fillHover;
124
+ let o = s;
125
+ const r = this.isPointingRight, n = this.circuit.getTextRect(h.label.fontSize, this.name);
126
+ r ? o += h.radius + h.label.offset : o -= h.radius + h.label.offset;
127
+ const a = {
128
+ x: n.x + h.label.padding * 2,
129
+ y: n.y + h.label.padding * 2
125
130
  };
126
131
  this.circuit.drawRect(
127
- this.circuit.getColor(g.pin.labelBackground),
128
- e ? s : s - r.x,
129
- this.position.y - n.y / 2 - d.label.padding,
130
- r.x,
131
- r.y
132
- ), e ? s += d.label.padding : s -= d.label.padding, this.circuit.drawText(
133
- this.circuit.getColor(g.pin.labelText),
134
- e ? "left" : "right",
135
- s,
136
- this.position.y,
137
- d.label.fontSize,
132
+ this.circuit.getColor(p.pin.labelBackground),
133
+ r ? o : o - a.x,
134
+ e - n.y / 2 - h.label.padding,
135
+ a.x,
136
+ a.y
137
+ ), r ? o += h.label.padding : o -= h.label.padding, this.circuit.drawText(
138
+ this.circuit.getColor(p.pin.labelText),
139
+ r ? "left" : "right",
140
+ o,
141
+ e,
142
+ h.label.fontSize,
138
143
  this.name
139
144
  );
140
145
  }
141
- i && this.circuit.setDrawingOpacity(a.placingOpacity), this.circuit.drawCircle(
146
+ i && this.circuit.setDrawingOpacity(c.placingOpacity), this.circuit.drawCircle(
142
147
  this.circuit.getColor(t),
143
- this.position.x,
144
- this.position.y,
145
- d.radius
148
+ s,
149
+ e,
150
+ h.radius
146
151
  ), i && this.circuit.resetDrawingOpacity();
147
152
  }
148
153
  toJson() {
@@ -153,34 +158,34 @@ class L {
153
158
  };
154
159
  }
155
160
  }
156
- class I {
157
- constructor(i, t, s, e, n, r) {
158
- o(this, "color");
159
- o(this, "name");
160
- o(this, "position", h.ZERO);
161
- o(this, "size");
162
- o(this, "circuit");
163
- o(this, "isCircuit", !1);
164
- o(this, "isBlueprint", !1);
165
- o(this, "inputCount", 0);
166
- o(this, "outputCount", 0);
167
- o(this, "inputPins");
168
- o(this, "outputPins");
169
- o(this, "logic");
170
- if (Object.assign(this, { circuit: i, name: t, color: s, isBlueprint: e, inputCount: n, outputCount: r }), this.circuit == null && !e && (this.circuit = this, this.isCircuit = !0), !(this.isCircuit || this.isBlueprint)) {
171
- if (this.circuit != null) {
172
- const c = this.circuit.getTextRect(m.fontSize, this.name), l = c.x + (m.padding + m.BorderWidth) * 2, f = c.y + (m.padding + m.BorderWidth) * 2;
173
- this.size = new h(l, f);
161
+ class C {
162
+ color;
163
+ name;
164
+ position = l.ZERO;
165
+ size;
166
+ circuit;
167
+ isCircuit = !1;
168
+ isBlueprint = !1;
169
+ inputCount = 0;
170
+ outputCount = 0;
171
+ inputPins;
172
+ outputPins;
173
+ logic;
174
+ constructor(i, t, s, e, o, r) {
175
+ if (Object.assign(this, { circuit: i, name: t, color: s, isBlueprint: e, inputCount: o, outputCount: r }), i == null && !e && this instanceof N && (this.circuit = this, this.isCircuit = !0), !(this.isCircuit || this.isBlueprint)) {
176
+ if (i != null) {
177
+ const n = this.circuit.getTextRect(g.fontSize, this.name), a = n.x + (g.padding + g.BorderWidth) * 2, P = n.y + (g.padding + g.BorderWidth) * 2;
178
+ this.size = new l(a, P);
174
179
  }
175
180
  this.inputPins = [];
176
- for (let c = 0; c < n; c++) {
177
- const l = new L(this.circuit, "IN " + c, !0, this);
178
- this.inputPins.push(l), this.isCircuit && (l.isControlled = !0);
181
+ for (let n = 0; n < o; n++) {
182
+ const a = new b(this.circuit, "IN " + n, !0, this);
183
+ this.inputPins.push(a), this.isCircuit && (a.isControlled = !0);
179
184
  }
180
185
  this.outputPins = [];
181
- for (let c = 0; c < r; c++) {
182
- const l = new L(this.circuit, "OUT " + c, !1, this);
183
- this.outputPins.push(l), this.isCircuit && (l.isControlled = !0);
186
+ for (let n = 0; n < r; n++) {
187
+ const a = new b(this.circuit, "OUT " + n, !1, this);
188
+ this.outputPins.push(a), this.isCircuit && (a.isControlled = !0);
184
189
  }
185
190
  }
186
191
  }
@@ -197,7 +202,7 @@ class I {
197
202
  return;
198
203
  const i = [];
199
204
  for (let s = 0; s < this.inputCount; s++) {
200
- const e = this.inputPins[s].state ?? C.LOW;
205
+ const e = this.inputPins[s].state ?? d.LOW;
201
206
  i.push(e);
202
207
  }
203
208
  const t = this.logic(i);
@@ -207,48 +212,58 @@ class I {
207
212
  drawPins(i = !0) {
208
213
  this.inputPins.forEach((t, s) => {
209
214
  if (i) {
210
- const n = (this.size.y - this.inputCount * d.radius * 2) / (this.inputCount + 1);
211
- t.position.x = this.position.x, t.position.y = this.position.y + n * (s + 1) + d.radius * (2 * s + 1);
215
+ const o = (this.size.y - this.inputCount * h.radius * 2) / (this.inputCount + 1);
216
+ t.position.x = this.position.x, t.position.y = this.position.y + (o * (s + 1) + h.radius * (2 * s + 1)) / this.circuit.size.y;
212
217
  }
213
218
  const e = this.circuit.inputHandler.isPlacingPin(t, s);
214
219
  t.draw(e);
215
220
  }), this.outputPins.forEach((t, s) => {
216
221
  if (i) {
217
- const n = (this.size.y - this.outputCount * d.radius * 2) / (this.outputCount + 1);
218
- t.position.x = this.position.x + this.size.x, t.position.y = this.position.y + n * (s + 1) + d.radius * (2 * s + 1);
222
+ const o = (this.size.y - this.outputCount * h.radius * 2) / (this.outputCount + 1);
223
+ t.position.x = this.position.x + this.size.x / this.circuit.size.x, t.position.y = this.position.y + (o * (s + 1) + h.radius * (2 * s + 1)) / this.circuit.size.y;
219
224
  }
220
225
  const e = this.circuit.inputHandler.isPlacingPin(t, s);
221
226
  t.draw(e);
222
227
  });
223
228
  }
229
+ getBounds() {
230
+ return {
231
+ position: l.product(this.position, this.circuit.size),
232
+ size: this.size
233
+ };
234
+ }
224
235
  draw(i) {
236
+ const { position: t, size: s } = this.getBounds();
225
237
  this.circuit.drawRect(
226
238
  this.circuit.getColor(this.color + "-1"),
227
- this.position.x,
228
- this.position.y,
229
- this.size.x,
230
- this.size.y
239
+ t.x,
240
+ t.y,
241
+ s.x,
242
+ s.y
231
243
  ), this.circuit.drawRect(
232
244
  this.circuit.getColor(this.color + "-0"),
233
- this.position.x + m.BorderWidth,
234
- this.position.y + m.BorderWidth,
235
- this.size.x - m.BorderWidth * 2,
236
- this.size.y - m.BorderWidth * 2
245
+ t.x + g.BorderWidth,
246
+ t.y + g.BorderWidth,
247
+ s.x - g.BorderWidth * 2,
248
+ s.y - g.BorderWidth * 2
237
249
  ), this.circuit.drawText(
238
- this.circuit.getColor(g.chip.text),
250
+ this.circuit.getColor(p.chip.text),
239
251
  "center",
240
- this.position.x + this.size.x / 2,
241
- this.position.y + this.size.y / 2,
242
- m.fontSize,
252
+ t.x + s.x / 2,
253
+ t.y + s.y / 2,
254
+ g.fontSize,
243
255
  this.name
244
256
  ), i && (this.circuit.setDrawingOpacity(0.25), this.circuit.drawRect(
245
- this.circuit.getColor(g.chip.outline),
246
- this.position.x - m.placingOutline,
247
- this.position.y - m.placingOutline,
248
- this.size.x + m.placingOutline * 2,
249
- this.size.y + m.placingOutline * 2
257
+ this.circuit.getColor(p.chip.outline),
258
+ t.x - g.placingOutline,
259
+ t.y - g.placingOutline,
260
+ s.x + g.placingOutline * 2,
261
+ s.y + g.placingOutline * 2
250
262
  ), this.circuit.resetDrawingOpacity()), this.drawPins();
251
263
  }
264
+ delete() {
265
+ Q(this, this.circuit.chips);
266
+ }
252
267
  toJson() {
253
268
  const i = {
254
269
  color: this.color,
@@ -261,74 +276,74 @@ class I {
261
276
  return this.inputPins.length > 0 && (i.inputPins = this.inputPins.map((t) => t.toJson())), this.outputPins.length > 0 && (i.outputPins = this.outputPins.map((t) => t.toJson())), i;
262
277
  }
263
278
  }
264
- class U extends L {
279
+ class R extends b {
265
280
  constructor(i, t, s, e) {
266
281
  super(i, t, s, i, e), this.isControlled = !0;
267
282
  }
268
283
  drawControllerHandle(i) {
269
- const t = { x: a.handleWidth, y: a.radius * 2 };
270
- let s = this.position.x;
271
- const e = this.position.y - t.y / 2;
272
- this.isInput ? s -= a.pinOffset + a.handleTrackWidth + a.radius : s += a.pinOffset + (a.handleTrackWidth - a.handleWidth) + a.radius;
273
- const n = {
274
- position: { x: s, y: e },
275
- size: { x: t.x, y: t.y }
284
+ const t = { x: c.handleWidth, y: c.handleHeight }, s = this.getRawPosition();
285
+ let e = s.x;
286
+ const o = s.y - t.y / 2;
287
+ this.isInput ? e -= c.pinOffset + c.handleTrackWidth + c.handleHeight / 2 : e += c.pinOffset + (c.handleTrackWidth - c.handleWidth) + c.handleHeight / 2;
288
+ const r = {
289
+ position: new l(e, o),
290
+ size: new l(t.x, t.y)
276
291
  };
277
- let r;
278
- this.circuit.isPointInsideRect(n, this.circuit.inputHandler.mousePosition) ? (r = g.controller.handleHover, this.circuit.cursor = S.pointer) : r = g.controller.handle, i && this.circuit.setDrawingOpacity(a.placingOpacity), this.circuit.drawRect(
279
- this.circuit.getColor(r),
280
- n.position.x,
281
- n.position.y,
282
- n.size.x,
283
- n.size.y
292
+ let n;
293
+ this.circuit.isPointInsideRect(r, this.circuit.inputHandler.rawMousePosition) ? (n = p.controller.handleHover, this.circuit.cursor = y.pointer) : n = p.controller.handle, i && this.circuit.setDrawingOpacity(c.placingOpacity), this.circuit.drawRect(
294
+ this.circuit.getColor(n),
295
+ r.position.x,
296
+ r.position.y,
297
+ r.size.x,
298
+ r.size.y
284
299
  ), i && this.circuit.resetDrawingOpacity();
285
300
  }
286
301
  drawController(i) {
287
- const t = this.isInput ? this.position.x - a.pinOffset : this.position.x + a.pinOffset, s = this.position.y;
288
- let e;
289
- this.state.value === 1 ? e = g.controller.on : e = g.controller.off, i && this.circuit.setDrawingOpacity(a.placingOpacity), this.circuit.drawCircle(
290
- this.circuit.getColor(g.controller.stroke),
291
- t,
302
+ const t = this.getRawPosition(), s = this.isInput ? t.x - c.pinOffset : t.x + c.pinOffset, e = t.y;
303
+ let o;
304
+ this.state.value === 1 ? o = p.controller.on : o = p.controller.off, i && this.circuit.setDrawingOpacity(c.placingOpacity), this.circuit.drawCircle(
305
+ this.circuit.getColor(p.controller.stroke),
292
306
  s,
293
- a.radius
307
+ e,
308
+ c.radius
294
309
  ), this.circuit.drawCircle(
295
- this.circuit.getColor(e),
296
- t,
310
+ this.circuit.getColor(o),
297
311
  s,
298
- a.radius - a.borderWidth
299
- ), this.isInput && this.isControlled && !i && this.circuit.inputHandler.mousePosition.getDistance(t, s) <= a.radius && (this.circuit.setDrawingOpacity(0.125), this.circuit.drawCircle(
300
- this.circuit.getColor(g.controller.hover),
301
- t,
312
+ e,
313
+ c.radius - c.borderWidth
314
+ ), this.isInput && this.isControlled && !i && this.circuit.inputHandler.rawMousePosition.getDistance(s, e) <= c.radius && (this.circuit.setDrawingOpacity(0.125), this.circuit.drawCircle(
315
+ this.circuit.getColor(p.controller.hover),
302
316
  s,
303
- a.radius - a.borderWidth
304
- ), this.circuit.resetDrawingOpacity(), this.circuit.cursor = S.pointer), i && this.circuit.resetDrawingOpacity();
317
+ e,
318
+ c.radius - c.borderWidth
319
+ ), this.circuit.resetDrawingOpacity(), this.circuit.cursor = y.pointer), i && this.circuit.resetDrawingOpacity();
305
320
  }
306
321
  drawConnector(i) {
307
322
  if (i)
308
323
  return;
309
- const t = this.isInput ? this.position.x - a.pinOffset : this.position.x, s = this.position.y;
310
- i && this.circuit.setDrawingOpacity(a.placingOpacity), this.circuit.drawRect(
311
- this.circuit.getColor(g.controller.connector),
312
- t,
313
- s - a.connectorWidth / 2,
314
- a.pinOffset,
315
- a.connectorWidth
324
+ const t = this.getRawPosition(), s = this.isInput ? t.x - c.pinOffset : t.x, e = t.y;
325
+ i && this.circuit.setDrawingOpacity(c.placingOpacity), this.circuit.drawRect(
326
+ this.circuit.getColor(p.controller.connector),
327
+ s,
328
+ e - c.connectorWidth / 2,
329
+ c.pinOffset,
330
+ c.connectorWidth
316
331
  ), i && this.circuit.resetDrawingOpacity();
317
332
  }
318
333
  draw(i) {
319
- this.drawConnector(i), this.drawController(i), this.drawControllerHandle(i), super.draw(i);
334
+ this.isInput ? this.position.x = (c.handleTrackWidth + c.pinOffset + c.radius) / this.circuit.size.x : this.position.x = (this.circuit.size.x - (c.handleTrackWidth + c.pinOffset + c.radius)) / this.circuit.size.x, this.drawConnector(i), this.drawController(i), this.drawControllerHandle(i), super.draw(i);
320
335
  }
321
336
  }
322
- class V {
323
- constructor(i, t, s, e, n) {
324
- o(this, "color");
325
- o(this, "state", C.LOW);
326
- o(this, "inputPin");
327
- o(this, "outputPin");
328
- o(this, "anchorPoints");
329
- o(this, "circuit");
330
- o(this, "placedBackwards", !1);
331
- Object.assign(this, { circuit: i, color: t, inputPin: s, outputPin: e, anchorPoints: n });
337
+ class D {
338
+ color;
339
+ state = d.LOW;
340
+ inputPin;
341
+ outputPin;
342
+ anchorPoints = [];
343
+ circuit;
344
+ placedBackwards = !1;
345
+ constructor(i, t, s, e, o = []) {
346
+ Object.assign(this, { circuit: i, color: t, inputPin: s, outputPin: e, anchorPoints: o });
332
347
  }
333
348
  setState(i) {
334
349
  this.state.isEqual(i) || (this.state = i, this.update());
@@ -340,177 +355,205 @@ class V {
340
355
  const t = [...this.anchorPoints];
341
356
  this.inputPin != null && (this.placedBackwards ? t.push(this.inputPin.position) : t.unshift(this.inputPin.position)), this.outputPin != null && (this.placedBackwards ? t.unshift(this.outputPin.position) : t.push(this.outputPin.position));
342
357
  let s;
343
- i ? s = `${this.color}-2` : this.state.value === 1 ? s = `${this.color}-0` : s = `${this.color}-2`, this.circuit.drawCurvedLine(this.circuit.getColor(s), t, H.width, H.cornerRadius, H.resolution);
358
+ i ? s = `${this.color}-2` : this.state.value === 1 ? s = `${this.color}-0` : s = `${this.color}-2`;
359
+ const e = t.map((o) => l.product(o, this.circuit.size));
360
+ this.circuit.drawCurvedLine(this.circuit.getColor(s), e, W.width, W.cornerRadius, W.resolution);
344
361
  }
345
362
  toJson() {
346
363
  const i = {
347
364
  color: this.color
348
365
  };
349
- return this.inputPin != null && (i.inputId = this.inputPin.id), this.outputPin != null && (i.outputId = this.outputPin.id), this.anchorPoints != null && (i.anchorPoints = this.anchorPoints), i;
366
+ return this.inputPin != null && (i.inputId = this.inputPin.id), this.outputPin != null && (i.outputId = this.outputPin.id), this.anchorPoints.length && (i.anchorPoints = this.anchorPoints), i;
350
367
  }
351
368
  }
369
+ function ei({ chip: f, ...i }) {
370
+ return /* @__PURE__ */ v($, { ...i, children: [
371
+ /* @__PURE__ */ u(w, { label: "Delete", onTrigger: () => {
372
+ f.delete();
373
+ } }),
374
+ /* @__PURE__ */ u(w, { label: "Duplicate", onTrigger: () => {
375
+ f.circuit.inputHandler.startChipPlacement(f);
376
+ } })
377
+ ] });
378
+ }
352
379
  class ni {
380
+ circuit;
381
+ canvas;
382
+ mousePosition = l.ZERO;
383
+ rawMousePosition = l.ZERO;
384
+ isPlacing = !1;
385
+ snapping = !1;
386
+ placingOffset = l.ZERO;
387
+ previousPlacement;
388
+ placingWire;
389
+ placingChip;
390
+ placingPin;
353
391
  constructor(i) {
354
- o(this, "circuit");
355
- o(this, "canvas");
356
- o(this, "mousePosition", h.ZERO);
357
- o(this, "isPlacing", !1);
358
- o(this, "snapping", !1);
359
- o(this, "placingOffset", h.ZERO);
360
- o(this, "previousPlacement");
361
- o(this, "placingWire");
362
- o(this, "placingChip");
363
- o(this, "placingPin");
364
- o(this, "onMouseMove", (i) => {
365
- if (i != null && this.setMousePosition(i), this.placingWire != null) {
366
- this.updateWirePlacement();
367
- return;
368
- }
369
- if (this.placingChip != null) {
370
- this.updateChipPlacement();
371
- return;
372
- }
373
- const t = (s) => {
374
- const e = s.position.y - a.radius, n = s.position.y + a.radius;
375
- return this.mousePosition.y > e && this.mousePosition.y < n;
376
- };
377
- if (this.placingPin != null) {
378
- let s = this.mousePosition.x > a.handleTrackWidth && this.mousePosition.x < this.circuit.size.x - a.handleTrackWidth;
379
- if (s) {
380
- this.cancelPinPlacement();
381
- return;
382
- }
383
- this.placingPin.isInput ? this.circuit.inputPins.forEach((e, n) => {
384
- s || n == this.circuit.inputPins.length - 1 || t(e) && (s = !0);
385
- }) : this.circuit.outputPins.forEach((e, n) => {
386
- s || n == this.circuit.outputPins.length - 1 || t(e) && (s = !0);
387
- }), s ? this.cancelPinPlacement() : this.updatePinPlacement();
388
- } else if (this.mousePosition.x < a.handleTrackWidth) {
389
- let s = !1;
390
- this.circuit.inputPins.forEach((e) => {
391
- s || t(e) && (s = !0);
392
- }), s || this.startPinPlacement(!0);
393
- } else if (this.mousePosition.x > this.circuit.size.x - a.handleTrackWidth) {
394
- let s = !1;
395
- this.circuit.outputPins.forEach((e) => {
396
- s || t(e) && (s = !0);
397
- }), s || this.startPinPlacement(!1);
398
- }
399
- });
400
- o(this, "onMouseUp", (i) => {
401
- if (i.preventDefault(), this.setMousePosition(i), i.button === 2)
402
- this.placingWire != null && this.cancelWirePlacement(), this.placingChip != null && this.cancelChipPlacement();
403
- else if (i.button === 0) {
404
- let t = !1;
405
- if (this.circuit.inputPins.forEach((s) => {
406
- this.mousePosition.getDistance(s.position.x - a.pinOffset, s.position.y) <= a.radius ? (s.setState(C.invert(s.state)), t = !0) : this.mousePosition.getDistance(s.position.x, s.position.y) <= d.radius && (this.onClickPin(s), t = !0);
407
- }), t || (this.circuit.outputPins.forEach((s) => {
408
- this.mousePosition.getDistance(s.position.x, s.position.y) <= d.radius && (this.onClickPin(s), t = !0);
409
- }), t) || (this.circuit.chips.forEach((s) => {
410
- s.inputPins.concat(s.outputPins).forEach((e) => {
411
- this.mousePosition.getDistance(e.position.x, e.position.y) <= d.radius && (this.onClickPin(e), t = !0);
412
- });
413
- }), t))
414
- return;
415
- this.placingWire != null && this.anchorWirePlacement(), this.placingChip != null && this.endChipPlacement(), this.placingPin != null && this.endPinPlacement();
416
- }
417
- });
418
- o(this, "onMouseDown", (i) => {
419
- i.preventDefault(), this.setMousePosition(i), !(i.button !== 0 || this.isPlacing) && this.circuit.chips.forEach((t, s) => {
420
- if (!this.isPlacing && this.circuit.isPointInsideRect(t, this.mousePosition)) {
421
- let e = !1;
422
- t.inputPins.concat(t.outputPins).forEach((n) => {
423
- n.position.getDistance(this.mousePosition.x, this.mousePosition.y) <= d.radius && (e = !0);
424
- }), e || this.editChipPlacement(t, s);
425
- }
426
- });
427
- });
428
- o(this, "onKeyDown", (i) => {
429
- switch (i.key) {
430
- case "Shift":
431
- i.preventDefault(), this.snapping = !0, this.onMouseMove();
432
- break;
433
- case "Backspace":
434
- case "Delete":
435
- case "Escape":
436
- i.preventDefault(), this.placingWire != null && this.cancelWirePlacement(), this.placingChip != null && this.cancelChipPlacement();
437
- break;
438
- }
439
- });
440
- o(this, "onKeyUp", (i) => {
441
- switch (i.key) {
442
- case "Shift":
443
- i.preventDefault(), this.snapping = !1, this.onMouseMove();
444
- break;
445
- }
446
- });
447
- Object.assign(this, { circuit: i });
392
+ this.circuit = i;
448
393
  }
449
394
  setMousePosition(i) {
450
395
  const t = this.canvas.getBoundingClientRect();
451
- this.mousePosition.x = i.clientX - t.left, this.mousePosition.y = i.clientY - t.top;
396
+ this.rawMousePosition.x = i.clientX - t.left, this.rawMousePosition.y = i.clientY - t.top, this.mousePosition.x = this.rawMousePosition.x / this.circuit.size.x, this.mousePosition.y = this.rawMousePosition.y / this.circuit.size.y;
452
397
  }
453
398
  init() {
454
- this.canvas = this.circuit.canvas, this.mousePosition = h.ZERO, this.canvas.addEventListener("mousemove", this.onMouseMove), this.canvas.addEventListener("mouseup", this.onMouseUp), this.canvas.addEventListener("contextmenu", this.onMouseUp), this.canvas.addEventListener("mousedown", this.onMouseDown), window.addEventListener("keydown", this.onKeyDown), window.addEventListener("keyup", this.onKeyUp);
399
+ this.canvas = this.circuit.canvas, this.mousePosition = l.ZERO, this.canvas.addEventListener("mousemove", this.onMouseMove), this.canvas.addEventListener("mouseup", this.onMouseUp), this.canvas.addEventListener("contextmenu", this.onMouseUp), this.canvas.addEventListener("mousedown", this.onMouseDown), this.canvas.addEventListener("mouseleave", this.onMouseLeave), window.addEventListener("keydown", this.onKeyDown), window.addEventListener("keyup", this.onKeyUp);
455
400
  }
456
401
  cleanup() {
457
- this.canvas.removeEventListener("mousemove", this.onMouseMove), this.canvas.removeEventListener("mouseup", this.onMouseUp), this.canvas.removeEventListener("contextmenu", this.onMouseUp), this.canvas.removeEventListener("mousedown", this.onMouseDown), window.removeEventListener("keydown", this.onKeyDown), window.removeEventListener("keyup", this.onKeyUp);
402
+ this.canvas.removeEventListener("mousemove", this.onMouseMove), this.canvas.removeEventListener("mouseup", this.onMouseUp), this.canvas.removeEventListener("contextmenu", this.onMouseUp), this.canvas.removeEventListener("mousedown", this.onMouseDown), this.canvas.removeEventListener("mouseleave", this.onMouseLeave), window.removeEventListener("keydown", this.onKeyDown), window.removeEventListener("keyup", this.onKeyUp);
458
403
  }
459
404
  reset() {
460
- this.placingWire = null, this.placingChip = null, this.placingPin = null, this.previousPlacement = null, this.placingOffset = h.ZERO, this.isPlacing = !1;
405
+ this.placingWire = null, this.placingChip = null, this.placingPin = null, this.previousPlacement = null, this.placingOffset = l.ZERO, this.isPlacing = !1;
461
406
  }
407
+ onMouseMove = (i) => {
408
+ if (i != null && this.setMousePosition(i), this.placingWire != null) {
409
+ this.updateWirePlacement();
410
+ return;
411
+ }
412
+ if (this.placingChip != null) {
413
+ this.updateChipPlacement();
414
+ return;
415
+ }
416
+ const t = (s) => {
417
+ const e = s.position.y * this.circuit.size.y, o = e - c.handleHeight / 2, r = e + c.handleHeight / 2;
418
+ return this.rawMousePosition.y > o && this.rawMousePosition.y < r;
419
+ };
420
+ if (this.placingPin != null) {
421
+ let s = this.rawMousePosition.x > c.handleTrackWidth && this.rawMousePosition.x < this.circuit.size.x - c.handleTrackWidth;
422
+ if (s) {
423
+ this.cancelPinPlacement();
424
+ return;
425
+ }
426
+ this.placingPin.isInput ? this.circuit.inputPins.forEach((e, o) => {
427
+ s || o == this.circuit.inputPins.length - 1 || t(e) && (s = !0);
428
+ }) : this.circuit.outputPins.forEach((e, o) => {
429
+ s || o == this.circuit.outputPins.length - 1 || t(e) && (s = !0);
430
+ }), s ? this.cancelPinPlacement() : this.updatePinPlacement();
431
+ } else if (this.rawMousePosition.x < c.handleTrackWidth) {
432
+ let s = !1;
433
+ this.circuit.inputPins.forEach((e) => {
434
+ s || t(e) && (s = !0);
435
+ }), s || this.startPinPlacement(!0);
436
+ } else if (this.rawMousePosition.x > this.circuit.size.x - c.handleTrackWidth) {
437
+ let s = !1;
438
+ this.circuit.outputPins.forEach((e) => {
439
+ s || t(e) && (s = !0);
440
+ }), s || this.startPinPlacement(!1);
441
+ }
442
+ };
462
443
  onClickPin(i) {
463
444
  this.placingWire != null ? this.endWirePlacement(i) : this.startWirePlacement(i);
464
445
  }
446
+ openContextMenu(i, t) {
447
+ i.stopPropagation();
448
+ const s = new l(i.clientX, i.clientY);
449
+ this.circuit.openContextMenu?.(s, t);
450
+ }
451
+ openChipContextMenu(i, t) {
452
+ this.openContextMenu(i, (s) => ei({ chip: t, ...s }));
453
+ }
454
+ onMouseUp = (i) => {
455
+ if (i.preventDefault(), this.setMousePosition(i), i.button === 2)
456
+ if (this.placingWire != null)
457
+ this.cancelWirePlacement();
458
+ else if (this.placingChip != null)
459
+ this.cancelChipPlacement();
460
+ else {
461
+ let t = !1;
462
+ if (this.circuit.chips.forEach((s) => {
463
+ this.circuit.isPointInsideRect(s.getBounds(), this.rawMousePosition) && (this.openChipContextMenu(i, s), t = !0);
464
+ }), t)
465
+ return;
466
+ }
467
+ else if (i.button === 0) {
468
+ let t = !1;
469
+ if (this.circuit.inputPins.forEach((s) => {
470
+ const e = s.getRawPosition();
471
+ this.rawMousePosition.getDistance(e.x - c.pinOffset, e.y) <= c.radius ? (s.setState(d.invert(s.state)), t = !0) : this.rawMousePosition.getDistance(e) <= h.radius && (this.onClickPin(s), t = !0);
472
+ }), t || (this.circuit.outputPins.forEach((s) => {
473
+ this.rawMousePosition.getDistance(s.getRawPosition()) <= h.radius && (this.onClickPin(s), t = !0);
474
+ }), t) || (this.circuit.chips.forEach((s) => {
475
+ s.inputPins.concat(s.outputPins).forEach((e) => {
476
+ this.rawMousePosition.getDistance(e.getRawPosition()) <= h.radius && (this.onClickPin(e), t = !0);
477
+ });
478
+ }), t))
479
+ return;
480
+ this.placingWire != null && this.anchorWirePlacement(), this.placingChip != null && this.endChipPlacement(), this.placingPin != null && this.endPinPlacement();
481
+ }
482
+ };
483
+ onMouseDown = (i) => {
484
+ i.preventDefault(), this.setMousePosition(i), !(i.button !== 0 || this.isPlacing) && this.circuit.chips.forEach((t, s) => {
485
+ if (!this.isPlacing && this.circuit.isPointInsideRect(t, this.mousePosition)) {
486
+ let e = !1;
487
+ t.inputPins.concat(t.outputPins).forEach((o) => {
488
+ o.position.getDistance(this.mousePosition.x, this.mousePosition.y) <= h.radius && (e = !0);
489
+ }), e || this.editChipPlacement(t, s);
490
+ }
491
+ });
492
+ };
493
+ onKeyDown = (i) => {
494
+ switch (i.key) {
495
+ case "Shift":
496
+ i.preventDefault(), this.snapping = !0, this.onMouseMove();
497
+ break;
498
+ case "Backspace":
499
+ case "Delete":
500
+ case "Escape":
501
+ i.preventDefault(), this.placingWire != null && this.cancelWirePlacement(), this.placingChip != null && this.cancelChipPlacement();
502
+ break;
503
+ }
504
+ };
505
+ onKeyUp = (i) => {
506
+ i.key === "Shift" && (i.preventDefault(), this.snapping = !1, this.onMouseMove());
507
+ };
508
+ onMouseLeave = (i) => {
509
+ this.cancelPinPlacement();
510
+ };
465
511
  startWirePlacement(i) {
466
- const t = i.isPointingRight, s = t ? i : void 0, e = t ? void 0 : i, n = this.mousePosition.clone;
467
- this.placingWire = new V(this.circuit, "red", s, e, [n]), t || (this.placingWire.placedBackwards = !0), this.circuit.wires.push(this.placingWire);
512
+ const t = i.isPointingRight, s = t ? i : void 0, e = t ? void 0 : i, o = this.mousePosition.clone;
513
+ this.placingWire = new D(this.circuit, "red", s, e, [o]), t || (this.placingWire.placedBackwards = !0), this.circuit.wires.push(this.placingWire);
468
514
  }
469
515
  snapWireHorizontally(i, t) {
470
516
  i.x = this.mousePosition.x, i.y = t.y;
471
517
  let s = [];
472
- this.circuit.wires.forEach((r, c) => {
473
- c < this.circuit.wires.length - 1 && (s = s.concat(r.anchorPoints));
518
+ this.circuit.wires.forEach((r, n) => {
519
+ n < this.circuit.wires.length - 1 && (s = s.concat(r.anchorPoints));
474
520
  });
475
- let e, n;
521
+ let e, o;
476
522
  s.forEach((r) => {
477
- const c = Math.abs(this.mousePosition.x - r.x);
478
- (n == null || n > c) && (e = r.x, n = c);
479
- }), n != null && e != null && n < H.snappingSensitivity && (i.x = e);
523
+ const n = Math.abs(this.mousePosition.x - r.x) * this.circuit.size.x;
524
+ (o == null || o > n) && (e = r.x, o = n);
525
+ }), o != null && e != null && o < W.snappingSensitivity && (i.x = e);
480
526
  }
481
527
  snapWireVertically(i, t) {
482
- var r;
483
528
  i.x = t.x, i.y = this.mousePosition.y;
484
529
  let s;
485
- (r = this.placingWire) != null && r.placedBackwards ? (s = this.circuit.inputPins, this.circuit.chips.forEach((c) => {
486
- s = s.concat(c.outputPins);
487
- })) : (s = this.circuit.outputPins, this.circuit.chips.forEach((c) => {
488
- s = s.concat(c.inputPins);
530
+ this.placingWire?.placedBackwards ? (s = this.circuit.inputPins, this.circuit.chips.forEach((r) => {
531
+ s = s.concat(r.outputPins);
532
+ })) : (s = this.circuit.outputPins, this.circuit.chips.forEach((r) => {
533
+ s = s.concat(r.inputPins);
489
534
  }));
490
- let e, n;
491
- s.forEach((c) => {
492
- const l = Math.abs(this.mousePosition.y - c.position.y);
493
- (n == null || n > l) && (e = c.position.y, n = l);
494
- }), n != null && e != null && n < H.snappingSensitivity && (i.y = e);
535
+ let e, o;
536
+ s.forEach((r) => {
537
+ const n = Math.abs(this.mousePosition.y - r.position.y) * this.circuit.size.y;
538
+ (o == null || o > n) && (e = r.position.y, o = n);
539
+ }), o !== void 0 && e !== void 0 && o < W.snappingSensitivity && (i.y = e);
495
540
  }
496
541
  updateWirePlacement() {
497
- var s, e, n, r, c, l;
498
- const i = (s = this.placingWire) == null ? void 0 : s.anchorPoints.length;
542
+ const i = this.placingWire?.anchorPoints.length;
499
543
  if (i == null) return;
500
- const t = (e = this.placingWire) == null ? void 0 : e.anchorPoints[i - 1];
544
+ const t = this.placingWire?.anchorPoints[i - 1];
501
545
  if (t != null)
502
546
  if (!this.snapping)
503
547
  t.x = this.mousePosition.x, t.y = this.mousePosition.y;
504
548
  else {
505
- let f;
506
- if (i >= 2 ? f = (n = this.placingWire) == null ? void 0 : n.anchorPoints[i - 2] : (r = this.placingWire) != null && r.placedBackwards ? f = (l = this.placingWire) == null ? void 0 : l.outputPin.position : f = (c = this.placingWire) == null ? void 0 : c.inputPin.position, f == null) return;
507
- const z = Math.abs(this.mousePosition.x - f.x), b = Math.abs(this.mousePosition.y - f.y);
508
- z > b ? this.snapWireHorizontally(t, f) : this.snapWireVertically(t, f);
549
+ let s;
550
+ if (i >= 2 ? s = this.placingWire?.anchorPoints[i - 2] : this.placingWire?.placedBackwards ? s = this.placingWire?.outputPin?.position : s = this.placingWire?.inputPin?.position, s == null) return;
551
+ const e = Math.abs(this.mousePosition.x - s.x) * this.circuit.size.x, o = Math.abs(this.mousePosition.y - s.y) * this.circuit.size.y;
552
+ e > o ? this.snapWireHorizontally(t, s) : this.snapWireVertically(t, s);
509
553
  }
510
554
  }
511
555
  anchorWirePlacement() {
512
- var i;
513
- (i = this.placingWire) == null || i.anchorPoints.push(this.mousePosition.clone);
556
+ this.placingWire?.anchorPoints.push(this.mousePosition.clone);
514
557
  }
515
558
  cancelWirePlacement() {
516
559
  this.placingWire = null, this.isPlacing = !1, this.circuit.wires.pop();
@@ -519,40 +562,39 @@ class ni {
519
562
  const t = i.isPointingRight;
520
563
  if (this.placingWire == null) return;
521
564
  let s = !1;
522
- !t && !this.placingWire.placedBackwards ? (this.placingWire.outputPin = i, s = !0) : t && this.placingWire.placedBackwards && (this.placingWire.inputPin = i, s = !0), s && (this.placingWire.anchorPoints.pop(), this.placingWire.inputPin.addOutputWire(this.placingWire), this.placingWire.inputPin.update(), this.placingWire = null, this.isPlacing = !1);
565
+ !t && !this.placingWire.placedBackwards ? (this.placingWire.outputPin = i, s = !0) : t && this.placingWire.placedBackwards && (this.placingWire.inputPin = i, s = !0), s && (this.placingWire.anchorPoints.pop(), this.placingWire.inputPin?.addOutputWire(this.placingWire), this.placingWire.inputPin?.update(), this.placingWire = null, this.isPlacing = !1);
523
566
  }
524
567
  startChipPlacement(i) {
525
- const t = new I(this.circuit, i.name, i.color, !1, i.inputCount, i.outputCount);
526
- t.setLogic(i.logic), t.position = new h(
527
- this.mousePosition.x - t.size.x / 2,
528
- this.mousePosition.y - t.size.y / 2
568
+ const t = new C(this.circuit, i.name, i.color, !1, i.inputCount, i.outputCount);
569
+ t.setLogic(i.logic), t.position = new l(
570
+ this.mousePosition.x - t.size.x / 2 / this.circuit.size.x,
571
+ this.mousePosition.y - t.size.y / 2 / this.circuit.size.y
529
572
  ), this.placingChip = t, this.isPlacing = !0, this.circuit.chips.push(t);
530
573
  }
531
574
  editChipPlacement(i, t) {
532
- this.placingOffset = new h(
533
- i.position.x + i.size.x / 2 - this.mousePosition.x,
534
- i.position.y + i.size.y / 2 - this.mousePosition.y
575
+ this.placingOffset = new l(
576
+ i.position.x + i.size.x / 2 / this.circuit.size.x - this.mousePosition.x,
577
+ i.position.y + i.size.y / 2 / this.circuit.size.y - this.mousePosition.y
535
578
  ), this.previousPlacement = i.position.clone, this.circuit.chips.push(this.circuit.chips.splice(t, 1)[0]), this.placingChip = i, this.isPlacing = !0;
536
579
  }
537
580
  updateChipPlacement() {
538
- this.placingChip != null && (this.placingChip.position.x = this.mousePosition.x - this.placingChip.size.x / 2 + this.placingOffset.x, this.placingChip.position.y = this.mousePosition.y - this.placingChip.size.y / 2 + this.placingOffset.y);
581
+ this.placingChip != null && (this.placingChip.position.x = this.mousePosition.x - this.placingChip.size.x / 2 / this.circuit.size.x + this.placingOffset.x, this.placingChip.position.y = this.mousePosition.y - this.placingChip.size.y / 2 / this.circuit.size.y + this.placingOffset.y);
539
582
  }
540
583
  cancelChipPlacement() {
541
584
  this.placingChip != null && (this.previousPlacement != null ? (this.placingChip.position = this.previousPlacement, this.previousPlacement = null) : this.circuit.chips.pop(), this.placingChip = null, this.isPlacing = !1);
542
585
  }
543
586
  endChipPlacement() {
544
- this.placingChip = null, this.isPlacing = !1, this.placingOffset = h.ZERO;
587
+ this.placingChip = null, this.isPlacing = !1, this.placingOffset = l.ZERO;
545
588
  }
546
589
  startPinPlacement(i) {
547
- const t = new U(this.circuit, "PIN", i);
548
- t.position.x = a.handleTrackWidth + a.pinOffset + a.radius, t.position.y = this.mousePosition.y, i ? this.circuit.inputPins.push(t) : (t.position.x = this.circuit.size.x - t.position.x, this.circuit.outputPins.push(t)), this.placingPin = t;
590
+ const t = new R(this.circuit, "PIN", i);
591
+ t.position.x = (c.handleTrackWidth + c.pinOffset + c.radius) / this.circuit.size.x, t.position.y = this.mousePosition.y, i ? this.circuit.inputPins.push(t) : (t.position.x = 1 - t.position.x, this.circuit.outputPins.push(t)), this.placingPin = t;
549
592
  }
550
593
  updatePinPlacement() {
551
594
  this.placingPin != null && (this.placingPin.position.y = this.mousePosition.y);
552
595
  }
553
596
  cancelPinPlacement() {
554
- var i;
555
- (i = this.placingPin) != null && i.isInput ? this.circuit.inputPins.pop() : this.circuit.outputPins.pop(), this.placingPin = null;
597
+ this.placingPin != null && (this.placingPin?.isInput ? this.circuit.inputPins.pop() : this.circuit.outputPins.pop(), this.placingPin = null);
556
598
  }
557
599
  endPinPlacement() {
558
600
  this.placingPin = null;
@@ -561,29 +603,29 @@ class ni {
561
603
  return !i.isControlled || this.placingPin == null || this.placingPin.isInput != i.isInput ? !1 : i.isInput ? t == this.circuit.inputPins.length - 1 : t == this.circuit.outputPins.length - 1;
562
604
  }
563
605
  }
564
- class oi extends I {
565
- constructor(t, s, e, n) {
566
- super(null, t, s, !1, e, n);
567
- o(this, "canvas");
568
- o(this, "size", h.ZERO);
569
- o(this, "context");
570
- o(this, "colors", {});
571
- o(this, "inputHandler");
572
- o(this, "inputPins", []);
573
- o(this, "outputPins", []);
574
- o(this, "wires", []);
575
- o(this, "chips", []);
576
- o(this, "cursor", S.default);
577
- o(this, "lastId", 0);
578
- this.inputHandler = new ni(this);
606
+ class N extends C {
607
+ canvas;
608
+ size = l.ZERO;
609
+ context;
610
+ colors = {};
611
+ inputHandler;
612
+ openContextMenu;
613
+ inputPins = [];
614
+ outputPins = [];
615
+ wires = [];
616
+ chips = [];
617
+ cursor = y.default;
618
+ lastId = 0;
619
+ constructor(i, t, s, e) {
620
+ super(null, i, t, !1, s, e), this.inputHandler = new ni(this);
579
621
  }
580
622
  resize() {
581
623
  this.size.x = this.canvas.clientWidth, this.size.y = this.canvas.clientHeight;
582
624
  }
583
- init(t) {
584
- this.canvas = t, this.context = this.canvas.getContext("2d"), this.resize(), new ResizeObserver((e) => {
585
- e.forEach(({ target: n }) => {
586
- n === this.canvas && (n.clientWidth != this.size.x || n.clientHeight != this.size.y) && this.resize();
625
+ init(i) {
626
+ this.canvas = i, this.context = this.canvas.getContext("2d"), this.resize(), new ResizeObserver((s) => {
627
+ s.forEach(({ target: e }) => {
628
+ e === this.canvas && (e.clientWidth != this.size.x || e.clientHeight != this.size.y) && this.resize();
587
629
  });
588
630
  }).observe(this.canvas), this.inputHandler.init(), this.render();
589
631
  }
@@ -593,198 +635,210 @@ class oi extends I {
593
635
  reset() {
594
636
  this.inputPins = [], this.outputPins = [], this.wires = [], this.chips = [], this.inputHandler.reset();
595
637
  }
596
- getColor(t) {
597
- if (this.colors[t] != null)
598
- return this.colors[t];
599
- const s = getComputedStyle(this.canvas).getPropertyValue("--" + t);
600
- return this.colors[t] = s, s;
638
+ getColor(i) {
639
+ if (this.colors[i] != null)
640
+ return this.colors[i];
641
+ const t = getComputedStyle(this.canvas).getPropertyValue("--" + i);
642
+ return this.colors[i] = t, t;
601
643
  }
602
- isPointInsideRect(t, s) {
603
- return s.x > t.position.x && s.y > t.position.y && s.x < t.position.x + t.size.x && s.y < t.position.y + t.size.y;
644
+ isPointInsideRect(i, t) {
645
+ return t.x > i.position.x && t.y > i.position.y && t.x < i.position.x + i.size.x && t.y < i.position.y + i.size.y;
604
646
  }
605
647
  getUniqueId() {
606
648
  return this.lastId++;
607
649
  }
608
- getTextRect(t, s) {
609
- this.context.textBaseline = "middle", this.context.font = `bold ${t}px ${A}`;
610
- const e = this.context.measureText(s), n = e.actualBoundingBoxRight + e.actualBoundingBoxLeft, r = e.actualBoundingBoxAscent + e.actualBoundingBoxDescent;
611
- return { x: n, y: r };
650
+ getTextRect(i, t) {
651
+ this.context.textBaseline = "middle", this.context.font = `bold ${i}px ${T}`;
652
+ const s = this.context.measureText(t), e = s.actualBoundingBoxRight + s.actualBoundingBoxLeft, o = s.actualBoundingBoxAscent + s.actualBoundingBoxDescent;
653
+ return { x: e, y: o };
612
654
  }
613
- drawRect(t, s, e, n, r) {
614
- this.context.fillStyle = t, this.context.fillRect(s, e, n, r);
655
+ drawRect(i, t, s, e, o) {
656
+ this.context.fillStyle = i, this.context.fillRect(t, s, e, o);
615
657
  }
616
- drawCircle(t, s, e, n) {
617
- this.context.beginPath(), this.context.arc(s, e, n, 0, 2 * Math.PI), this.context.fillStyle = t, this.context.fill();
658
+ drawCircle(i, t, s, e) {
659
+ this.context.beginPath(), this.context.arc(t, s, e, 0, 2 * Math.PI), this.context.fillStyle = i, this.context.fill();
618
660
  }
619
- drawCurvedLine(t, s, e, n, r) {
620
- if (s.length < 2)
661
+ drawCurvedLine(i, t, s, e, o) {
662
+ if (t.length < 2)
621
663
  return;
622
- this.context.lineWidth = e, this.context.lineJoin = "round", this.context.lineCap = "round";
623
- const c = [];
624
- c.push(s[0]);
625
- for (let l = 1; l < s.length - 1; l++) {
626
- const f = s[l], z = h.normalize(h.subtract(s[l], s[l - 1])), b = h.magnitude(h.subtract(s[l], s[l - 1])), T = Math.max(b - n, b / 2), B = h.normalize(h.subtract(s[l + 1], s[l])), u = h.magnitude(h.subtract(s[l + 1], s[l])), p = h.add(s[l - 1], h.scale(z, T)), E = h.add(f, h.scale(B, Math.min(n, u / 2)));
627
- for (let v = 0; v < r; v++) {
628
- const x = v / (r - 1), M = h.lerp(p, f, x), y = h.lerp(f, E, x), W = h.lerp(M, y, x);
629
- h.sqrDistance(W, c[c.length - 1]) > 1e-3 && c.push(W);
664
+ this.context.lineWidth = s, this.context.lineJoin = "round", this.context.lineCap = "round";
665
+ const r = [];
666
+ r.push(t[0]);
667
+ for (let n = 1; n < t.length - 1; n++) {
668
+ const a = t[n], P = l.normalize(l.difference(t[n], t[n - 1])), m = l.difference(t[n], t[n - 1]).magnitude, O = Math.max(m - e, m / 2), z = l.normalize(l.difference(t[n + 1], t[n])), H = l.difference(t[n + 1], t[n]).magnitude, U = l.sum(t[n - 1], l.scale(P, O)), j = l.sum(a, l.scale(z, Math.min(e, H / 2)));
669
+ for (let M = 0; M < o; M++) {
670
+ const E = M / (o - 1), A = l.lerp(U, a, E), J = l.lerp(a, j, E), I = l.lerp(A, J, E);
671
+ I.getDistanceSquared(r[r.length - 1]) > 1e-3 && r.push(I);
630
672
  }
631
673
  }
632
- c.push(s[s.length - 1]), this.context.beginPath(), this.context.moveTo(c[0].x, c[0].y);
633
- for (let l = 1; l < c.length; l++)
634
- this.context.lineTo(c[l].x, c[l].y);
635
- this.context.strokeStyle = t, this.context.stroke();
674
+ r.push(t[t.length - 1]), this.context.beginPath(), this.context.moveTo(r[0].x, r[0].y);
675
+ for (let n = 1; n < r.length; n++)
676
+ this.context.lineTo(r[n].x, r[n].y);
677
+ this.context.strokeStyle = i, this.context.stroke();
636
678
  }
637
- drawText(t, s, e, n, r, c) {
638
- this.context.fillStyle = t, this.context.textAlign = s, this.context.textBaseline = "middle", this.context.font = `bold ${r}px ${A}`, this.context.fillText(c, e, n);
679
+ drawText(i, t, s, e, o, r) {
680
+ this.context.fillStyle = i, this.context.textAlign = t, this.context.textBaseline = "middle", this.context.font = `bold ${o}px ${T}`, this.context.fillText(r, s, e);
639
681
  }
640
- setDrawingOpacity(t) {
641
- this.context.globalAlpha = ti(t, 0, 1);
682
+ setDrawingOpacity(i) {
683
+ this.context.globalAlpha = ii(i, 0, 1);
642
684
  }
643
685
  resetDrawingOpacity() {
644
686
  this.setDrawingOpacity(1);
645
687
  }
646
688
  drawBackground() {
647
- const t = a.handleTrackWidth, s = $.padding;
648
- this.drawRect(this.getColor(g.background.margin), 0, 0, this.size.x, this.size.y);
649
- let e = 0;
689
+ const i = c.handleTrackWidth, t = B.padding;
690
+ this.drawRect(this.getColor(p.background.margin), 0, 0, this.size.x, this.size.y);
691
+ let s = 0;
650
692
  this.drawRect(
651
- this.getColor(g.background.outer),
652
- e + t,
653
- e,
654
- this.size.x - t * 2,
693
+ this.getColor(p.background.outer),
694
+ s + i,
695
+ s,
696
+ this.size.x - i * 2,
655
697
  this.size.y
656
- ), e = s - $.borderWidth, this.drawRect(
657
- this.getColor(g.background.border),
658
- e + t,
659
- e,
660
- this.size.x - e * 2 - t * 2,
661
- this.size.y - e * 2
662
- ), e = s, this.drawRect(
663
- this.getColor(g.background.inner),
664
- e + t,
665
- e,
666
- this.size.x - e * 2 - t * 2,
667
- this.size.y - e * 2
698
+ ), s = t - B.borderWidth, this.drawRect(
699
+ this.getColor(p.background.border),
700
+ s + i,
701
+ s,
702
+ this.size.x - s * 2 - i * 2,
703
+ this.size.y - s * 2
704
+ ), s = t, this.drawRect(
705
+ this.getColor(p.background.inner),
706
+ s + i,
707
+ s,
708
+ this.size.x - s * 2 - i * 2,
709
+ this.size.y - s * 2
668
710
  );
669
711
  }
670
712
  drawWires() {
671
- this.wires.forEach((t, s) => {
672
- const e = this.inputHandler.placingWire != null && s == this.wires.length - 1;
673
- t.draw(e);
713
+ this.wires.forEach((i, t) => {
714
+ const s = this.inputHandler.placingWire != null && t == this.wires.length - 1;
715
+ i.draw(s);
674
716
  });
675
717
  }
676
718
  drawChips() {
677
- this.chips.forEach((t, s) => {
678
- const e = this.inputHandler.placingChip != null && s == this.chips.length - 1;
679
- t.draw(e);
719
+ this.chips.forEach((i, t) => {
720
+ const s = this.inputHandler.placingChip != null && t == this.chips.length - 1;
721
+ i.draw(s);
680
722
  });
681
723
  }
682
724
  draw() {
683
725
  this.drawBackground(), this.drawWires(), this.drawChips(), super.drawPins(!1);
684
726
  }
685
727
  render() {
686
- this.canvas.width != this.size.x && (this.canvas.width = this.size.x), this.canvas.height != this.size.y && (this.canvas.height = this.size.y), this.cursor = S.default, this.draw(), this.inputHandler.isPlacing ? this.canvas.style.cursor = S.default : this.canvas.style.cursor = this.cursor, window.requestAnimationFrame(() => {
728
+ this.canvas.width != this.size.x && (this.canvas.width = this.size.x), this.canvas.height != this.size.y && (this.canvas.height = this.size.y), this.cursor = y.default, this.draw(), this.inputHandler.isPlacing ? this.canvas.style.cursor = y.default : this.canvas.style.cursor = this.cursor, window.requestAnimationFrame(() => {
687
729
  this.render();
688
730
  });
689
731
  }
690
732
  toJson() {
691
- const t = super.toJson();
692
- return this.wires.length > 0 && (t.wires = this.wires.map((s) => s.toJson())), this.chips.length > 0 && (t.chips = this.chips.map((s) => s.toJson())), t;
733
+ const i = super.toJson();
734
+ return this.wires.length > 0 && (i.wires = this.wires.map((t) => t.toJson())), this.chips.length > 0 && (i.chips = this.chips.map((t) => t.toJson())), i;
693
735
  }
694
736
  toString() {
695
- const t = this.toJson();
696
- return JSON.stringify(t);
737
+ const i = this.toJson();
738
+ return JSON.stringify(i);
697
739
  }
698
740
  }
699
- const N = class N {
741
+ class x {
742
+ static CHIPS = {
743
+ and: new C(null, "AND", "blue", !0, 2, 1).setLogic((i) => i[0].isHigh() && i[1].isHigh() ? [d.HIGH] : [d.LOW]),
744
+ not: new C(null, "NOT", "red", !0, 1, 1).setLogic((i) => [d.invert(i[0])]),
745
+ or: new C(null, "OR", "yellow", !0, 2, 1).setLogic((i) => i[0].isHigh() || i[1].isHigh() ? [d.HIGH] : [d.LOW]),
746
+ high: new C(null, "HIGH", "green", !0, 0, 1).setLogic((i) => [d.HIGH]),
747
+ low: new C(null, "LOW", "purple", !0, 0, 1).setLogic((i) => [d.LOW])
748
+ };
700
749
  static saveCircuit(i, t) {
701
750
  t.createFile(i.name, "json", (s) => {
702
751
  s.setContent(i.toString());
703
752
  });
704
753
  }
705
754
  static loadCircuit(i, t) {
706
- var e;
707
755
  i.reset();
708
756
  const s = t.findFile(i.name, "json");
709
- s != null && ((e = s.read()) == null || e.then((n) => {
710
- var l, f, z, b, T, B;
711
- const r = JSON.parse(n);
712
- i.color = r.color, i.name = r.name;
713
- const c = {};
714
- i.inputCount = ((l = r.inputPins) == null ? void 0 : l.length) ?? 0, (f = r.inputPins) == null || f.forEach((u) => {
715
- const p = new U(i, u.name, !0, u.id);
716
- p.position = u.position, i.inputPins.push(p), c[u.id] = p;
717
- }), i.outputCount = ((z = r.outputPins) == null ? void 0 : z.length) ?? 0, (b = r.outputPins) == null || b.forEach((u) => {
718
- const p = new U(i, u.name, !1, u.id);
719
- p.position = u.position, i.outputPins.push(p), c[u.id] = p;
720
- }), (T = r.chips) == null || T.forEach((u) => {
721
- var E, v, x, M;
722
- const p = new I(i, u.name, u.color, !1, 0, 0);
723
- p.position = u.position, p.inputCount = ((E = u.inputPins) == null ? void 0 : E.length) ?? 0, (v = u.inputPins) == null || v.forEach((y) => {
724
- const W = new L(i, y.name, !0, p, y.id);
725
- p.inputPins.push(W), c[y.id] = W;
726
- }), p.outputCount = ((x = u.outputPins) == null ? void 0 : x.length) ?? 0, (M = u.outputPins) == null || M.forEach((y) => {
727
- const W = new L(i, y.name, !1, p, y.id);
728
- p.outputPins.push(W), c[y.id] = W;
729
- }), p.setLogic(N.CHIPS[u.name].logic), p.update(), i.chips.push(p);
730
- }), (B = r.wires) == null || B.forEach((u) => {
731
- const p = c[u.inputId], E = c[u.outputId], v = u.anchorPoints ?? [], x = new V(i, u.color, p, E, v);
732
- p == null || p.addOutputWire(x), i.wires.push(x);
757
+ s?.read().then((e) => {
758
+ if (!e)
759
+ return;
760
+ const o = JSON.parse(e);
761
+ i.color = o.color, i.name = o.name;
762
+ const r = {};
763
+ i.inputCount = o.inputPins?.length ?? 0, o.inputPins?.forEach((n) => {
764
+ const a = new R(i, n.name, !0, n.id);
765
+ a.position = new l(n.position.x, n.position.y), i.inputPins.push(a), r[n.id] = a;
766
+ }), i.outputCount = o.outputPins?.length ?? 0, o.outputPins?.forEach((n) => {
767
+ const a = new R(i, n.name, !1, n.id);
768
+ a.position = new l(n.position.x, n.position.y), i.outputPins.push(a), r[n.id] = a;
769
+ }), o.chips?.forEach((n) => {
770
+ const a = new C(i, n.name, n.color, !1, 0, 0);
771
+ a.position = new l(n.position.x, n.position.y), a.inputCount = n.inputPins?.length ?? 0, n.inputPins?.forEach((P) => {
772
+ const m = new b(i, P.name, !0, a, P.id);
773
+ a.inputPins.push(m), r[P.id] = m;
774
+ }), a.outputCount = n.outputPins?.length ?? 0, n.outputPins?.forEach((P) => {
775
+ const m = new b(i, P.name, !1, a, P.id);
776
+ a.outputPins.push(m), r[P.id] = m;
777
+ }), a.setLogic(x.CHIPS[n.name].logic), a.update(), i.chips.push(a);
778
+ }), o.wires?.forEach((n) => {
779
+ const a = n.inputId ? r[n.inputId] : void 0, P = n.outputId ? r[n.outputId] : void 0, m = n.anchorPoints?.map(({ x: z, y: H }) => new l(z, H)), O = new D(i, n.color, a, P, m);
780
+ a?.addOutputWire(O), i.wires.push(O);
733
781
  });
734
- }).catch((n) => {
735
- console.error(n);
736
- }));
782
+ }).catch((e) => {
783
+ console.error(e);
784
+ });
737
785
  }
738
- };
739
- o(N, "CHIPS", {
740
- and: new I(null, "AND", "blue", !0, 2, 1).setLogic((i) => i[0].value === 1 && i[1].value === 1 ? [C.HIGH] : [C.LOW]),
741
- not: new I(null, "NOT", "red", !0, 1, 1).setLogic((i) => [C.invert(i[0])])
742
- });
743
- let R = N;
744
- function ci({ app: P }) {
745
- const i = q(P), [t] = _(new oi("Chip", "#000", 2, 1)), s = Q(null);
746
- return ii(() => {
747
- if (!(s.current == null && t.canvas != null))
786
+ }
787
+ function oi({ app: f }) {
788
+ const i = F(f), t = V(() => new N("Chip", "#000", 2, 1)), s = q(null), { openContextMenu: e } = X();
789
+ return t.openContextMenu = e, K(() => {
790
+ if (s.current != null)
748
791
  return t.init(s.current), () => {
749
792
  t.cleanup();
750
793
  };
751
- }, [s, t]), /* @__PURE__ */ D(G, { children: [
752
- /* @__PURE__ */ D(K, { children: [
753
- /* @__PURE__ */ D(j, { label: "Circuit", showOnHover: !1, children: [
754
- /* @__PURE__ */ w(k, { label: "New", onTrigger: () => {
794
+ }, [s, t]), /* @__PURE__ */ v(_, { children: [
795
+ /* @__PURE__ */ v(Y, { children: [
796
+ /* @__PURE__ */ v(k, { label: "Circuit", showOnHover: !1, children: [
797
+ /* @__PURE__ */ u(w, { label: "New", onTrigger: () => {
755
798
  t.reset();
756
799
  } }),
757
- /* @__PURE__ */ w(k, { label: "Save", onTrigger: () => {
758
- i != null && R.saveCircuit(t, i);
800
+ /* @__PURE__ */ u(w, { label: "Save", onTrigger: () => {
801
+ i != null && x.saveCircuit(t, i);
759
802
  } }),
760
- /* @__PURE__ */ w(k, { label: "Load", onTrigger: () => {
761
- i != null && R.loadCircuit(t, i);
803
+ /* @__PURE__ */ u(w, { label: "Load", onTrigger: () => {
804
+ i != null && x.loadCircuit(t, i);
762
805
  } })
763
806
  ] }),
764
- /* @__PURE__ */ D(j, { label: "Add", showOnHover: !1, children: [
765
- /* @__PURE__ */ w(k, { label: "AND gate", onTrigger: () => {
766
- t.inputHandler.startChipPlacement(R.CHIPS.and);
807
+ /* @__PURE__ */ v(k, { label: "Add", showOnHover: !1, children: [
808
+ /* @__PURE__ */ u(w, { label: "AND gate", onTrigger: () => {
809
+ t.inputHandler.startChipPlacement(x.CHIPS.and);
810
+ } }),
811
+ /* @__PURE__ */ u(w, { label: "NOT gate", onTrigger: () => {
812
+ t.inputHandler.startChipPlacement(x.CHIPS.not);
813
+ } }),
814
+ /* @__PURE__ */ u(L, {}),
815
+ /* @__PURE__ */ u(w, { label: "OR gate", onTrigger: () => {
816
+ t.inputHandler.startChipPlacement(x.CHIPS.or);
817
+ } }),
818
+ /* @__PURE__ */ u(L, {}),
819
+ /* @__PURE__ */ u(w, { label: "HIGH", onTrigger: () => {
820
+ t.inputHandler.startChipPlacement(x.CHIPS.high);
767
821
  } }),
768
- /* @__PURE__ */ w(k, { label: "NOT gate", onTrigger: () => {
769
- t.inputHandler.startChipPlacement(R.CHIPS.not);
822
+ /* @__PURE__ */ u(w, { label: "LOW", onTrigger: () => {
823
+ t.inputHandler.startChipPlacement(x.CHIPS.low);
770
824
  } })
771
825
  ] }),
772
- /* @__PURE__ */ w(j, { label: "Help", showOnHover: !1, children: /* @__PURE__ */ w(k, { label: "Digital Electronics Glossary", onTrigger: () => {
773
- X("http://www.pmcgibbon.net/teachcte/electron/degloss1.htm");
826
+ /* @__PURE__ */ u(k, { label: "Help", showOnHover: !1, children: /* @__PURE__ */ u(w, { label: "Digital Electronics Glossary", onTrigger: () => {
827
+ Z("http://www.pmcgibbon.net/teachcte/electron/degloss1.htm");
774
828
  } }) })
775
829
  ] }),
776
- /* @__PURE__ */ w("div", { className: J.CircuitView, children: /* @__PURE__ */ w("canvas", { ref: s, className: J.Canvas }) })
830
+ /* @__PURE__ */ u("div", { className: S.CircuitView, children: /* @__PURE__ */ u("canvas", { ref: s, className: S.Canvas }) })
777
831
  ] });
778
832
  }
779
- const ri = "_LogicSim_k1eu4_1", ai = {
833
+ const ri = "_LogicSim_k1eu4_1", ci = {
780
834
  LogicSim: ri
781
835
  };
782
- function li({ app: P }) {
783
- return /* @__PURE__ */ w("div", { className: ai.LogicSim, children: /* @__PURE__ */ w(ci, { app: P }) });
836
+ function ai({ app: f }) {
837
+ return /* @__PURE__ */ u("div", { className: ci.LogicSim, children: /* @__PURE__ */ u(oi, { app: f }) });
784
838
  }
785
- const hi = new Y("Logic Sim", "logic-sim", li).setIconUrl("https://os.prozilla.dev/assets/apps/icons/logic-sim.svg").setPinnedByDefault(!1).setCategory("Education");
786
- hi.setMetadata({ name: "@prozilla-os/logic-sim", version: "1.1.17", author: "Prozilla" });
839
+ const li = new G("Logic Sim", "logic-sim", ai).setIconUrl("https://os.prozilla.dev/assets/apps/icons/logic-sim.svg").setPinnedByDefault(!1).setCategory("Education");
840
+ li.setMetadata({ name: "@prozilla-os/logic-sim", version: "1.1.19", author: "Prozilla" });
787
841
  export {
788
- hi as logicSim
842
+ li as logicSim
789
843
  };
790
844
  //# sourceMappingURL=main.js.map