@prozilla-os/logic-sim 1.1.18 → 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.d.ts +225 -2
- package/dist/main.js +497 -443
- package/dist/main.js.map +1 -1
- package/package.json +7 -7
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sources":["../src/core/_utils/state.ts","../src/constants/logicSim.const.ts","../src/core/pins/pin.ts","../src/core/chips/chip.ts","../src/core/pins/controlledPin.ts","../src/core/wires/wire.ts","../src/core/inputHandler.ts","../src/core/circuit.ts","../src/core/chips/chipsManager.ts","../src/components/CircuitView.tsx","../src/components/LogicSim.tsx","../src/main.ts"],"sourcesContent":["export class State {\n\tvalue: number;\n\n\tstatic LOW = new State(0);\n\tstatic HIGH = new State(1);\n\n\tconstructor(value: number) {\n\t\tthis.value = value;\n\t}\n\n\tstatic invert(state: State) {\n\t\treturn new State(1 - state.value);\n\t}\n\n\tisEqual(state: State) {\n\t\treturn this.value === state.value;\n\t}\n}","export const CURSORS = {\n\tdefault: \"default\",\n\tpointer: \"pointer\",\n};\n\nexport const FONT = \"outfit\";\nexport const ENABLE_COLOR_CACHING = true;\nexport const VIRTUAL_PATH = \"~/Apps/logic-sim/\";\n\nexport const BACKGROUND = {\n\tpadding: 30,\n\tborderWidth: 7.5,\n};\n\nexport const CONTROLLER = {\n\tradius: 25,\n\tborderWidth: 5,\n\tpinOffset: 42.5,\n\tconnectorWidth: 7.5,\n\thandleWidth: 15,\n\thandleTrackWidth: 22.5,\n\tplacingOpacity: 0.5,\n};\n\nexport const WIRE = {\n\twidth: 5,\n\tsnappingSensitivity: 10,\n\tcornerRadius: 25,\n\tresolution: 8,\n};\n\nexport const PIN = {\n\tradius: 10,\n\tlabel: {\n\t\toffset: 10,\n\t\tfontSize: 15,\n\t\tpadding: 5,\n\t},\n};\n\nexport const CHIP = {\n\tBorderWidth: 5,\n\tpadding: 10,\n\tfontSize: 35,\n\tplacingOutline: 10,\n};\n\nexport const COLORS = {\n\tpin: {\n\t\tfill: \"black-4\",\n\t\tfillHover: \"black-3\",\n\t\tlabelText: \"white-0\",\n\t\tlabelBackground: \"black-4\",\n\t},\n\tcontroller: {\n\t\tstroke: \"black-4\",\n\t\tconnector: \"black-4\",\n\t\ton: \"red-0\",\n\t\toff: \"red-2\",\n\t\thover: \"white-0\",\n\t\thandle: \"black-3\",\n\t\thandleHover: \"black-4\",\n\t},\n\tbackground: {\n\t\tborder: \"black-0\",\n\t\touter: \"black-1\",\n\t\tinner: \"black-2\",\n\t\tmargin: \"black-2\",\n\t},\n\twire: {\n\t\tplacing: \"black-1\",\n\t},\n\tchip: {\n\t\ttext: \"black-4\",\n\t\toutline: \"white-0\",\n\t},\n};","import { Vector2 } from \"@prozilla-os/core\";\nimport { Chip } from \"../chips/chip\";\nimport { Circuit } from \"../circuit\";\nimport { State } from \"../_utils/state\";\nimport { Wire } from \"../wires/wire\";\nimport { COLORS, CONTROLLER, CURSORS, PIN } from \"../../constants/logicSim.const\";\n\nexport interface PinJson {\n\tname: string;\n\tid: number;\n\tposition: {\n\t\tx: number;\n\t\ty: number;\n\t};\n}\n\nexport class Pin {\n\tid: number;\n\tname!: string;\n\tposition = Vector2.ZERO;\n\tattachedChip!: Chip;\n\tcircuit!: Circuit;\n\n\tstate = State.LOW;\n\tisInput!: boolean;\n\tisControlled: boolean = false;\n\toutputWires: Wire[] = [];\n\n\tconstructor(circuit: Circuit, name: string, isInput: boolean, attachedChip: Chip, id?: number) {\n\t\tObject.assign(this, { circuit, name, isInput, attachedChip });\n\t\tthis.id = id ?? this.circuit.getUniqueId();\n\t}\n\n\taddOutputWire(wire: Wire) {\n\t\tthis.outputWires.push(wire);\n\t\twire.setState(this.state);\n\t}\n\n\tsetState(state: State) {\n\t\tif (this.state.isEqual(state))\n\t\t\treturn;\n\n\t\tthis.state = state;\n\t\tthis.update();\n\t}\n\n\tupdate() {\n\t\t// TO DO: clean this mess\n\t\tthis.outputWires.forEach((wire) => {\n\t\t\twire.setState(this.state);\n\t\t});\n\t\tthis.attachedChip?.update();\n\t}\n\n\tget isPointingRight() {\n\t\treturn this.isInput === this.isControlled;\n\t}\n\n\tdraw(isPlacing: boolean) {\n\t\tlet color = COLORS.pin.fill;\n\n\t\tif (this.circuit.inputHandler.mousePosition.getDistance(this.position.x, this.position.y) <= PIN.radius) {\n\t\t\tthis.circuit.cursor = CURSORS.pointer;\n\t\t\tcolor = COLORS.pin.fillHover;\n\n\t\t\t// Draw label\n\t\t\tlet positionX = this.position.x;\n\t\t\tconst leftAligned = this.isPointingRight;\n\t\t\tconst textRect = this.circuit.getTextRect(PIN.label.fontSize, this.name);\n\n\t\t\tif (leftAligned) {\n\t\t\t\tpositionX += PIN.radius + PIN.label.offset;\n\t\t\t} else {\n\t\t\t\tpositionX -= PIN.radius + PIN.label.offset;\n\t\t\t}\n\n\t\t\tconst backgroundSize = {\n\t\t\t\tx: textRect.x + PIN.label.padding * 2,\n\t\t\t\ty: textRect.y + PIN.label.padding * 2,\n\t\t\t};\n\n\t\t\tthis.circuit.drawRect(\n\t\t\t\tthis.circuit.getColor(COLORS.pin.labelBackground),\n\t\t\t\tleftAligned ? positionX : positionX - backgroundSize.x, this.position.y - textRect.y / 2 - PIN.label.padding,\n\t\t\t\tbackgroundSize.x, backgroundSize.y\n\t\t\t);\n\n\t\t\tif (leftAligned) {\n\t\t\t\tpositionX += PIN.label.padding;\n\t\t\t} else {\n\t\t\t\tpositionX -= PIN.label.padding;\n\t\t\t}\n\n\t\t\tthis.circuit.drawText(\n\t\t\t\tthis.circuit.getColor(COLORS.pin.labelText),\n\t\t\t\tleftAligned ? \"left\" : \"right\",\n\t\t\t\tpositionX, this.position.y,\n\t\t\t\tPIN.label.fontSize,\n\t\t\t\tthis.name\n\t\t\t);\n\t\t}\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.setDrawingOpacity(CONTROLLER.placingOpacity);\n\n\t\tthis.circuit.drawCircle(\n\t\t\tthis.circuit.getColor(color),\n\t\t\tthis.position.x, this.position.y,\n\t\t\tPIN.radius\n\t\t);\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t}\n\n\ttoJson(): PinJson {\n\t\tconst object = {\n\t\t\tname: this.name,\n\t\t\tid: this.id,\n\t\t\tposition: this.position,\n\t\t} as PinJson;\n\n\t\treturn object;\n\t}\n}","import { Circuit } from \"../circuit\";\nimport { Pin, PinJson } from \"../pins/pin\";\nimport { State } from \"../_utils/state\";\nimport { Vector2 } from \"@prozilla-os/core\";\nimport { CHIP, COLORS, PIN } from \"../../constants/logicSim.const\";\n\nexport interface ChipJson {\n\tcolor: string;\n\tname: string;\n\tposition: {\n\t\tx: number;\n\t\ty: number;\n\t};\n\tinputPins: PinJson[];\n\toutputPins: PinJson[];\n}\n\nexport class Chip {\n\tcolor!: string;\n\tname!: string;\n\tposition = Vector2.ZERO;\n\tsize!: Vector2;\n\tcircuit!: Circuit;\n\tisCircuit = false;\n\tisBlueprint = false;\n\n\tinputCount = 0;\n\toutputCount = 0;\n\tinputPins!: Pin[];\n\toutputPins!: Pin[];\n\tlogic!: (inputStates: State[]) => State[];\n\n\tconstructor(circuit: Circuit | null, name: string, color: string, isBlueprint: boolean, inputCount: number, outputCount: number) {\n\t\tObject.assign(this, { circuit, name, color, isBlueprint, inputCount, outputCount });\n\n\t\tif (this.circuit == null && !isBlueprint) {\n\t\t\tthis.circuit = this as unknown as Circuit;\n\t\t\tthis.isCircuit = true;\n\t\t}\n\n\t\tif (this.isCircuit || this.isBlueprint)\n\t\t\treturn;\n\n\n\t\tif (this.circuit != null) {\n\t\t\tconst textRect = this.circuit.getTextRect(CHIP.fontSize, this.name);\n\n\t\t\tconst width = textRect.x + (CHIP.padding + CHIP.BorderWidth) * 2;\n\t\t\tconst minHeight = textRect.y + (CHIP.padding + CHIP.BorderWidth) * 2;\n\t\n\t\t\tthis.size = new Vector2(width, minHeight);\n\t\t}\n\n\t\tthis.inputPins = [];\n\t\tfor (let i = 0; i < inputCount; i++) {\n\t\t\tconst newPin = new Pin(this.circuit, \"IN \" + i, true, this);\n\t\t\tthis.inputPins.push(newPin);\n\n\t\t\tif (this.isCircuit)\n\t\t\t\tnewPin.isControlled = true;\n\t\t}\n\n\t\tthis.outputPins = [];\n\t\tfor (let i = 0; i < outputCount; i++) {\n\t\t\tconst newPin = new Pin(this.circuit, \"OUT \" + i, false, this);\n\t\t\tthis.outputPins.push(newPin);\n\n\t\t\tif (this.isCircuit)\n\t\t\t\tnewPin.isControlled = true;\n\t\t}\n\t}\n\n\tsetCircuit(circuit: Circuit) {\n\t\tthis.circuit = circuit;\n\n\t\tthis.inputPins.concat(this.outputPins).forEach((pin) => { pin.circuit = circuit; });\n\t}\n\n\tsetLogic(logic: (inputStates: State[]) => State[]) {\n\t\tthis.logic = logic;\n\t\treturn this;\n\t}\n\n\tupdate() {\n\t\tif (this.logic == null)\n\t\t\treturn;\n\n\t\tconst inputStates: State[] = [];\n\t\tfor (let i = 0; i < this.inputCount; i++) {\n\t\t\tconst state = this.inputPins[i].state ?? State.LOW;\n\t\t\tinputStates.push(state);\n\t\t}\n\n\t\tconst outputStates: State[] = this.logic(inputStates);\n\n\t\tfor (let i = 0; i < this.outputCount; i++) {\n\t\t\tthis.outputPins[i].setState(outputStates[i]);\n\t\t}\n\t}\n\n\tdrawPins(reposition = true) {\n\t\tthis.inputPins.forEach((pin, index) => {\n\t\t\tif (reposition) {\n\t\t\t\tconst gap = (this.size.y - this.inputCount * PIN.radius * 2) / (this.inputCount + 1);\n\t\t\t\tpin.position.x = this.position.x;\n\t\t\t\tpin.position.y = this.position.y + gap * (index + 1) + PIN.radius * (2 * index + 1);\n\t\t\t}\n\n\t\t\tconst isPlacingPin = this.circuit.inputHandler.isPlacingPin(pin, index);\n\t\t\tpin.draw(isPlacingPin);\n\t\t});\n\n\t\tthis.outputPins.forEach((pin, index) => {\n\t\t\tif (reposition) {\n\t\t\t\tconst gap = (this.size.y - this.outputCount * PIN.radius * 2) / (this.outputCount + 1);\n\t\t\t\tpin.position.x = this.position.x + this.size.x;\n\t\t\t\tpin.position.y = this.position.y + gap * (index + 1) + PIN.radius * (2 * index + 1);\n\t\t\t}\n\n\t\t\tconst isPlacingPin = this.circuit.inputHandler.isPlacingPin(pin, index);\n\t\t\tpin.draw(isPlacingPin);\n\t\t});\n\t}\n\n\tdraw(isPlacing: boolean) {\n\t\tthis.circuit.drawRect(\n\t\t\tthis.circuit.getColor(this.color + \"-1\"),\n\t\t\tthis.position.x, this.position.y,\n\t\t\tthis.size.x, this.size.y\n\t\t);\n\t\tthis.circuit.drawRect(\n\t\t\tthis.circuit.getColor(this.color + \"-0\"),\n\t\t\tthis.position.x + CHIP.BorderWidth, this.position.y + CHIP.BorderWidth,\n\t\t\tthis.size.x - CHIP.BorderWidth * 2, this.size.y - CHIP.BorderWidth * 2\n\t\t);\n\n\t\tthis.circuit.drawText(\n\t\t\tthis.circuit.getColor(COLORS.chip.text),\n\t\t\t\"center\",\n\t\t\tthis.position.x + this.size.x / 2, this.position.y + this.size.y / 2,\n\t\t\tCHIP.fontSize,\n\t\t\tthis.name\n\t\t);\n\n\t\tif (isPlacing) {\n\t\t\tthis.circuit.setDrawingOpacity(0.25);\n\t\t\tthis.circuit.drawRect(\n\t\t\t\tthis.circuit.getColor(COLORS.chip.outline),\n\t\t\t\tthis.position.x - CHIP.placingOutline, this.position.y - CHIP.placingOutline,\n\t\t\t\tthis.size.x + CHIP.placingOutline * 2, this.size.y + CHIP.placingOutline * 2\n\t\t\t);\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t\t}\n\n\t\tthis.drawPins();\n\t}\n\n\ttoJson(): ChipJson {\n\t\tconst object = {\n\t\t\tcolor: this.color,\n\t\t\tname: this.name,\n\t\t\tposition: {\n\t\t\t\tx: this.position.x,\n\t\t\t\ty: this.position.y,\n\t\t\t},\n\t\t} as ChipJson;\n\n\t\tif (this.inputPins.length > 0)\n\t\t\tobject.inputPins = this.inputPins.map((pin) => pin.toJson());\n\n\t\tif (this.outputPins.length > 0)\n\t\t\tobject.outputPins = this.outputPins.map((pin) => pin.toJson());\n\n\t\treturn object;\n\t}\n}","import { Vector2 } from \"@prozilla-os/core\";\nimport { Circuit } from \"../circuit\";\nimport { Pin } from \"./pin\";\nimport { COLORS, CONTROLLER, CURSORS } from \"../../constants/logicSim.const\";\n\nexport class ControlledPin extends Pin {\n\tconstructor(circuit: Circuit, name: string, isInput: boolean, id?: number) {\n\t\tsuper(circuit, name, isInput, circuit, id);\n\t\tthis.isControlled = true;\n\t}\n\n\tdrawControllerHandle(isPlacing: boolean) {\n\t\tconst size = { x: CONTROLLER.handleWidth, y: CONTROLLER.radius * 2 };\n\n\t\tlet positionX = this.position.x;\n\t\tconst positionY = this.position.y - size.y / 2;\n\n\n\t\tif (this.isInput) {\n\t\t\tpositionX -= CONTROLLER.pinOffset + CONTROLLER.handleTrackWidth + CONTROLLER.radius;\n\t\t} else {\n\t\t\tpositionX += CONTROLLER.pinOffset + (CONTROLLER.handleTrackWidth - CONTROLLER.handleWidth) + CONTROLLER.radius;\n\t\t}\n\n\t\tconst rect = {\n\t\t\tposition: { x: positionX, y: positionY } as Vector2,\n\t\t\tsize: { x: size.x, y: size.y } as Vector2,\n\t\t};\n\n\t\tlet color: string;\n\n\t\tif (this.circuit.isPointInsideRect(rect, this.circuit.inputHandler.mousePosition)) {\n\t\t\tcolor = COLORS.controller.handleHover;\n\t\t\tthis.circuit.cursor = CURSORS.pointer;\n\t\t} else {\n\t\t\tcolor = COLORS.controller.handle;\n\t\t}\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.setDrawingOpacity(CONTROLLER.placingOpacity);\n\n\t\tthis.circuit.drawRect(\n\t\t\tthis.circuit.getColor(color),\n\t\t\trect.position.x, rect.position.y,\n\t\t\trect.size.x, rect.size.y\n\t\t);\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t}\n\n\tdrawController(isPlacing: boolean) {\n\t\tconst positionX = this.isInput ? this.position.x - CONTROLLER.pinOffset : this.position.x + CONTROLLER.pinOffset;\n\t\tconst positionY = this.position.y;\n\n\t\tlet color: string;\n\n\t\tif (this.state.value === 1) {\n\t\t\tcolor = COLORS.controller.on;\n\t\t} else {\n\t\t\tcolor = COLORS.controller.off;\n\t\t}\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.setDrawingOpacity(CONTROLLER.placingOpacity);\n\n\t\tthis.circuit.drawCircle(\n\t\t\tthis.circuit.getColor(COLORS.controller.stroke),\n\t\t\tpositionX, positionY,\n\t\t\tCONTROLLER.radius\n\t\t);\n\t\tthis.circuit.drawCircle(\n\t\t\tthis.circuit.getColor(color),\n\t\t\tpositionX, positionY,\n\t\t\tCONTROLLER.radius - CONTROLLER.borderWidth\n\t\t);\n\n\t\tconst isInteractable = this.isInput && this.isControlled && !isPlacing;\n\t\tif (isInteractable && this.circuit.inputHandler.mousePosition.getDistance(positionX, positionY) <= CONTROLLER.radius) {\n\t\t\tthis.circuit.setDrawingOpacity(0.125);\n\t\t\tthis.circuit.drawCircle(\n\t\t\t\tthis.circuit.getColor(COLORS.controller.hover),\n\t\t\t\tpositionX, positionY,\n\t\t\t\tCONTROLLER.radius - CONTROLLER.borderWidth\n\t\t\t);\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t\t\tthis.circuit.cursor = CURSORS.pointer;\n\t\t}\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t}\n\n\tdrawConnector(isPlacing: boolean) {\n\t\tif (isPlacing)\n\t\t\treturn;\n\n\t\tconst positionX = this.isInput ? this.position.x - CONTROLLER.pinOffset : this.position.x;\n\t\tconst positionY = this.position.y;\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.setDrawingOpacity(CONTROLLER.placingOpacity);\n\n\t\tthis.circuit.drawRect(\n\t\t\tthis.circuit.getColor(COLORS.controller.connector),\n\t\t\tpositionX, positionY - CONTROLLER.connectorWidth / 2,\n\t\t\tCONTROLLER.pinOffset, CONTROLLER.connectorWidth\n\t\t);\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t}\n\n\tdraw(isPlacing: boolean) {\n\t\tthis.drawConnector(isPlacing);\n\t\tthis.drawController(isPlacing);\n\t\tthis.drawControllerHandle(isPlacing);\n\n\t\tsuper.draw(isPlacing);\n\t}\n}","import { Vector2 } from \"@prozilla-os/core\";\nimport { Circuit } from \"../circuit\";\nimport { Pin } from \"../pins/pin\";\nimport { State } from \"../_utils/state\";\nimport { WIRE } from \"../../constants/logicSim.const\";\n\nexport interface WireJson {\n\tcolor: string;\n\tinputId: number;\n\toutputId: number;\n\tanchorPoints: {\n\t\tx: number;\n\t\ty: number;\n\t}[];\n}\n\nexport class Wire {\n\tcolor!: string;\n\tstate = State.LOW;\n\tinputPin!: Pin;\n\toutputPin!: Pin;\n\tanchorPoints!: Vector2[];\n\tcircuit!: Circuit;\n\tplacedBackwards = false;\n\n\tconstructor(circuit: Circuit, color: string, inputPin?: Pin, outputPin?: Pin, anchorPoints?: Vector2[]) {\n\t\tObject.assign(this, { circuit, color, inputPin, outputPin, anchorPoints });\n\t}\n\n\tsetState(state: State) {\n\t\tif (this.state.isEqual(state))\n\t\t\treturn;\n\n\t\tthis.state = state;\n\t\tthis.update();\n\t}\n\n\tupdate() {\n\t\tif (this.outputPin == null)\n\t\t\treturn;\n\n\t\tthis.outputPin.setState(this.state);\n\t}\n\n\tdraw(isPlacing: boolean) {\n\t\tconst positions = [...this.anchorPoints];\n\n\t\tif (this.inputPin != null) {\n\t\t\tif (!this.placedBackwards) {\n\t\t\t\tpositions.unshift(this.inputPin.position);\n\t\t\t} else {\n\t\t\t\tpositions.push(this.inputPin.position);\n\t\t\t}\n\t\t}\n\t\t\n\t\tif (this.outputPin != null) {\n\t\t\tif (!this.placedBackwards) {\n\t\t\t\tpositions.push(this.outputPin.position);\n\t\t\t} else {\n\t\t\t\tpositions.unshift(this.outputPin.position);\n\t\t\t}\n\t\t}\n\n\t\tlet color: string;\n\n\t\tif (isPlacing) {\n\t\t\tcolor = `${this.color}-2`;\n\t\t} else if (this.state.value === 1) {\n\t\t\tcolor = `${this.color}-0`;\n\t\t} else {\n\t\t\tcolor = `${this.color}-2`;\n\t\t}\n\n\t\tthis.circuit.drawCurvedLine(this.circuit.getColor(color), positions, WIRE.width, WIRE.cornerRadius, WIRE.resolution);\n\t}\n\n\ttoJson() {\n\t\tconst object = {\n\t\t\tcolor: this.color,\n\t\t} as WireJson;\n\n\t\tif (this.inputPin != null)\n\t\t\tobject.inputId = this.inputPin.id;\n\n\t\tif (this.outputPin != null)\n\t\t\tobject.outputId = this.outputPin.id;\n\n\t\tif (this.anchorPoints != null)\n\t\t\tobject.anchorPoints = this.anchorPoints;\n\n\t\treturn object;\n\t}\n}","import { Chip } from \"./chips/chip\";\nimport { Circuit } from \"./circuit\";\nimport { ControlledPin } from \"./pins/controlledPin\";\nimport { Pin } from \"./pins/pin\";\nimport { State } from \"./_utils/state\";\nimport { Wire } from \"./wires/wire\";\nimport { Vector2 } from \"@prozilla-os/core\";\nimport { CONTROLLER, PIN, WIRE } from \"../constants/logicSim.const\";\n\nexport class InputHandler {\n\tcircuit!: Circuit;\n\tcanvas!: HTMLCanvasElement;\n\n\tmousePosition = Vector2.ZERO;\n\n\tisPlacing = false;\n\tsnapping = false;\n\tplacingOffset = Vector2.ZERO;\n\tpreviousPlacement!: Vector2 | null;\n\tplacingWire!: Wire | null;\n\tplacingChip!: Chip | null;\n\tplacingPin!: ControlledPin | null;\n\n\tconstructor(circuit: Circuit) {\n\t\tObject.assign(this, { circuit });\n\t}\n\n\tsetMousePosition(event: MouseEvent) {\n\t\tconst rect = this.canvas.getBoundingClientRect();\n\t\tthis.mousePosition.x = event.clientX - rect.left;\n\t\tthis.mousePosition.y = event.clientY - rect.top;\n\t}\n\n\tinit() {\n\t\tthis.canvas = this.circuit.canvas;\n\t\tthis.mousePosition = Vector2.ZERO;\n\n\t\t// TO DO: add support for touch devices\n\n\t\tthis.canvas.addEventListener(\"mousemove\", this.onMouseMove);\n\t\tthis.canvas.addEventListener(\"mouseup\", this.onMouseUp);\n\t\tthis.canvas.addEventListener(\"contextmenu\", this.onMouseUp);\n\t\tthis.canvas.addEventListener(\"mousedown\", this.onMouseDown);\n\n\t\twindow.addEventListener(\"keydown\", this.onKeyDown);\n\t\twindow.addEventListener(\"keyup\", this.onKeyUp);\n\t}\n\n\tcleanup() {\n\t\tthis.canvas.removeEventListener(\"mousemove\", this.onMouseMove);\n\t\tthis.canvas.removeEventListener(\"mouseup\", this.onMouseUp);\n\t\tthis.canvas.removeEventListener(\"contextmenu\", this.onMouseUp);\n\t\tthis.canvas.removeEventListener(\"mousedown\", this.onMouseDown);\n\n\t\twindow.removeEventListener(\"keydown\", this.onKeyDown);\n\t\twindow.removeEventListener(\"keyup\", this.onKeyUp);\n\t}\n\n\treset() {\n\t\tthis.placingWire = null;\n\t\tthis.placingChip = null;\n\t\tthis.placingPin = null;\n\t\tthis.previousPlacement = null;\n\t\tthis.placingOffset = Vector2.ZERO;\n\t\tthis.isPlacing = false;\n\t}\n\n\tonMouseMove = (event?: MouseEvent) => {\n\t\tif (event != null)\n\t\t\tthis.setMousePosition(event);\n\n\t\tif (this.placingWire != null) {\n\t\t\tthis.updateWirePlacement();\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.placingChip != null) {\n\t\t\tthis.updateChipPlacement();\n\t\t\treturn;\n\t\t}\n\n\t\tconst isHoveringPinHandle = (pin: ControlledPin) => {\n\t\t\tconst top = pin.position.y - CONTROLLER.radius;\n\t\t\tconst bottom = pin.position.y + CONTROLLER.radius;\n\n\t\t\treturn (this.mousePosition.y > top && this.mousePosition.y < bottom);\n\t\t};\n\n\t\tif (this.placingPin != null) {\n\t\t\tlet invalidPlacement = this.mousePosition.x > CONTROLLER.handleTrackWidth && this.mousePosition.x < this.circuit.size.x - CONTROLLER.handleTrackWidth;\n\n\t\t\tif (invalidPlacement) {\n\t\t\t\tthis.cancelPinPlacement();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.placingPin.isInput) {\n\t\t\t\tthis.circuit.inputPins.forEach((pin, index) => {\n\t\t\t\t\tif (invalidPlacement || index == this.circuit.inputPins.length - 1)\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\tif (isHoveringPinHandle(pin))\n\t\t\t\t\t\tinvalidPlacement = true;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.circuit.outputPins.forEach((pin, index) => {\n\t\t\t\t\tif (invalidPlacement || index == this.circuit.outputPins.length - 1)\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\tif (isHoveringPinHandle(pin))\n\t\t\t\t\t\tinvalidPlacement = true;\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (invalidPlacement) {\n\t\t\t\tthis.cancelPinPlacement();\n\t\t\t} else {\n\t\t\t\tthis.updatePinPlacement();\n\t\t\t}\n\t\t} else {\n\t\t\tif (this.mousePosition.x < CONTROLLER.handleTrackWidth) {\n\t\t\t\tlet invalidPlacement = false;\n\n\t\t\t\tthis.circuit.inputPins.forEach((pin) => {\n\t\t\t\t\tif (invalidPlacement)\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\tif (isHoveringPinHandle(pin))\n\t\t\t\t\t\tinvalidPlacement = true;\n\t\t\t\t});\n\n\t\t\t\tif (!invalidPlacement)\n\t\t\t\t\tthis.startPinPlacement(true);\n\t\t\t} else if (this.mousePosition.x > this.circuit.size.x - CONTROLLER.handleTrackWidth) {\n\t\t\t\tlet invalidPlacement = false;\n\n\t\t\t\tthis.circuit.outputPins.forEach((pin) => {\n\t\t\t\t\tif (invalidPlacement)\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\tif (isHoveringPinHandle(pin))\n\t\t\t\t\t\tinvalidPlacement = true;\n\t\t\t\t});\n\n\t\t\t\tif (!invalidPlacement)\n\t\t\t\t\tthis.startPinPlacement(false);\n\t\t\t}\n\t\t}\n\t};\n\n\tonClickPin(pin: Pin) {\n\t\tif (this.placingWire != null) {\n\t\t\tthis.endWirePlacement(pin);\n\t\t} else {\n\t\t\tthis.startWirePlacement(pin);\n\t\t}\n\t}\n\n\tonMouseUp = (event: MouseEvent) => {\n\t\tevent.preventDefault();\n\t\tthis.setMousePosition(event);\n\n\t\tif (event.button === 2) {\n\t\t\tif (this.placingWire != null)\n\t\t\t\tthis.cancelWirePlacement();\n\t\t\tif (this.placingChip != null)\n\t\t\t\tthis.cancelChipPlacement();\n\t\t} else if (event.button === 0) {\n\t\t\tlet eventComplete = false;\n\n\t\t\tthis.circuit.inputPins.forEach((pin: Pin) => {\n\t\t\t\tif (this.mousePosition.getDistance(pin.position.x - CONTROLLER.pinOffset, pin.position.y) <= CONTROLLER.radius) {\n\t\t\t\t\tpin.setState(State.invert(pin.state));\n\t\t\t\t\teventComplete = true;\n\t\t\t\t} else if (this.mousePosition.getDistance(pin.position.x, pin.position.y) <= PIN.radius) {\n\t\t\t\t\tthis.onClickPin(pin);\n\t\t\t\t\teventComplete = true;\n\t\t\t\t}\n\t\t\t});\n\t\n\t\t\tif (eventComplete)\n\t\t\t\treturn;\n\t\n\t\t\tthis.circuit.outputPins.forEach((pin: Pin) => {\n\t\t\t\tif (this.mousePosition.getDistance(pin.position.x, pin.position.y) <= PIN.radius) {\n\t\t\t\t\tthis.onClickPin(pin);\n\t\t\t\t\teventComplete = true;\n\t\t\t\t}\n\t\t\t});\n\t\n\t\t\tif (eventComplete)\n\t\t\t\treturn;\n\n\t\t\tthis.circuit.chips.forEach((chip) => {\n\t\t\t\tchip.inputPins.concat(chip.outputPins).forEach((pin) => {\n\t\t\t\t\tif (this.mousePosition.getDistance(pin.position.x, pin.position.y) <= PIN.radius) {\n\t\t\t\t\t\tthis.onClickPin(pin);\n\t\t\t\t\t\teventComplete = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tif (eventComplete)\n\t\t\t\treturn;\n\t\n\t\t\tif (this.placingWire != null)\n\t\t\t\tthis.anchorWirePlacement();\n\n\t\t\tif (this.placingChip != null)\n\t\t\t\tthis.endChipPlacement();\n\n\t\t\tif (this.placingPin != null)\n\t\t\t\tthis.endPinPlacement();\n\t\t}\n\t};\n\n\tonMouseDown = (event: MouseEvent) => {\n\t\tevent.preventDefault();\n\t\tthis.setMousePosition(event);\n\n\t\tif (event.button !== 0 || this.isPlacing)\n\t\t\treturn;\n\n\t\tthis.circuit.chips.forEach((chip, index) => {\n\t\t\tif (!this.isPlacing && this.circuit.isPointInsideRect(chip, this.mousePosition)) {\n\t\t\t\tlet hoveringPin = false;\n\n\t\t\t\tchip.inputPins.concat(chip.outputPins).forEach((pin) => {\n\t\t\t\t\tif (pin.position.getDistance(this.mousePosition.x, this.mousePosition.y) <= PIN.radius)\n\t\t\t\t\t\thoveringPin = true;\n\t\t\t\t});\n\n\t\t\t\tif (!hoveringPin)\n\t\t\t\t\tthis.editChipPlacement(chip, index);\n\t\t\t}\n\t\t});\n\t};\n\n\tonKeyDown = (event: KeyboardEvent) => {\n\t\tswitch (event.key) {\n\t\t\tcase \"Shift\":\n\t\t\t\tevent.preventDefault();\n\t\t\t\tthis.snapping = true;\n\t\t\t\tthis.onMouseMove();\n\t\t\t\tbreak;\n\t\t\tcase \"Backspace\":\n\t\t\tcase \"Delete\":\n\t\t\tcase \"Escape\":\n\t\t\t\tevent.preventDefault();\n\t\t\t\tif (this.placingWire != null)\n\t\t\t\t\tthis.cancelWirePlacement();\n\t\t\t\tif (this.placingChip != null)\n\t\t\t\t\tthis.cancelChipPlacement();\n\t\t\t\tbreak;\n\t\t}\n\t};\n\n\tonKeyUp = (event: KeyboardEvent) => {\n\t\tswitch (event.key) {\n\t\t\tcase \"Shift\":\n\t\t\t\tevent.preventDefault();\n\t\t\t\tthis.snapping = false;\n\t\t\t\tthis.onMouseMove();\n\t\t\t\tbreak;\n\t\t}\n\t};\n\n\tstartWirePlacement(pin: Pin) {\n\t\tconst isInputPin = pin.isPointingRight;\n\n\t\t// Start wire placement\n\t\tconst inputPin = isInputPin ? pin : undefined;\n\t\tconst outputPin = !isInputPin ? pin : undefined;\n\t\tconst anchorPoint = this.mousePosition.clone;\n\n\t\tthis.placingWire = new Wire(this.circuit, \"red\", inputPin, outputPin, [anchorPoint]);\n\n\t\tif (!isInputPin)\n\t\t\tthis.placingWire.placedBackwards = true;\n\n\t\tthis.circuit.wires.push(this.placingWire);\n\t}\n\n\tsnapWireHorizontally(lastAnchorPoint: Vector2, previousAnchorPoint: Vector2) {\n\t\tlastAnchorPoint.x = this.mousePosition.x;\n\t\tlastAnchorPoint.y = previousAnchorPoint.y;\n\n\t\t// Snapping horizontal wire to other wires\n\t\tlet anchorPoints: Vector2[] = [];\n\n\t\tthis.circuit.wires.forEach((wire, index) => {\n\t\t\tif (index < this.circuit.wires.length - 1)\n\t\t\t\tanchorPoints = anchorPoints.concat(wire.anchorPoints);\n\t\t});\n\n\t\tlet closestPositionX: number | undefined;\n\t\tlet closestDistance: number | undefined;\n\n\t\tanchorPoints.forEach((point) => {\n\t\t\tconst distance = Math.abs(this.mousePosition.x - point.x);\n\n\t\t\tif (closestDistance == null || closestDistance > distance) {\n\t\t\t\tclosestPositionX = point.x;\n\t\t\t\tclosestDistance = distance;\n\t\t\t}\n\t\t});\n\n\t\tif (closestDistance != null && closestPositionX != null && closestDistance < WIRE.snappingSensitivity)\n\t\t\tlastAnchorPoint.x = closestPositionX;\n\t}\n\n\tsnapWireVertically(lastAnchorPoint: Vector2, previousAnchorPoint: Vector2) {\n\t\tlastAnchorPoint.x = previousAnchorPoint.x;\n\t\tlastAnchorPoint.y = this.mousePosition.y;\n\n\t\t// Snapping vertical wire to pins\n\t\tlet pins: Pin[];\n\n\t\tif (!this.placingWire?.placedBackwards) {\n\t\t\tpins = this.circuit.outputPins;\n\n\t\t\tthis.circuit.chips.forEach((chip) => {\n\t\t\t\tpins = pins.concat(chip.inputPins);\n\t\t\t});\n\t\t} else {\n\t\t\tpins = this.circuit.inputPins;\n\n\t\t\tthis.circuit.chips.forEach((chip) => {\n\t\t\t\tpins = pins.concat(chip.outputPins);\n\t\t\t});\n\t\t}\n\n\t\tlet closestPositionY: number | undefined;\n\t\tlet closestDistance: number | undefined;\n\n\t\tpins.forEach((pin) => {\n\t\t\tconst distance = Math.abs(this.mousePosition.y - pin.position.y);\n\n\t\t\tif (closestDistance == null || closestDistance > distance) {\n\t\t\t\tclosestPositionY = pin.position.y;\n\t\t\t\tclosestDistance = distance;\n\t\t\t}\n\t\t});\n\n\t\tif (closestDistance != null && closestPositionY != null && closestDistance < WIRE.snappingSensitivity)\n\t\t\tlastAnchorPoint.y = closestPositionY;\n\t}\n\n\tupdateWirePlacement() {\n\t\tconst anchorCount = this.placingWire?.anchorPoints.length;\n\t\tif (anchorCount == null) return;\n\t\tconst lastAnchorPoint = this.placingWire?.anchorPoints[anchorCount - 1];\n\t\tif (lastAnchorPoint == null) return;\n\n\t\tif (!this.snapping) {\n\t\t\tlastAnchorPoint.x = this.mousePosition.x;\n\t\t\tlastAnchorPoint.y = this.mousePosition.y;\n\t\t} else {\n\t\t\t// Wire snapping\n\t\t\tlet previousAnchorPoint: Vector2 | undefined;\n\n\t\t\tif (anchorCount >= 2) {\n\t\t\t\tpreviousAnchorPoint = this.placingWire?.anchorPoints[anchorCount - 2];\n\t\t\t} else if (!this.placingWire?.placedBackwards) {\n\t\t\t\tpreviousAnchorPoint = this.placingWire?.inputPin.position;\n\t\t\t} else {\n\t\t\t\tpreviousAnchorPoint = this.placingWire?.outputPin.position;\n\t\t\t}\n\n\t\t\tif (previousAnchorPoint == null) return;\n\t\n\t\t\tconst deltaX = Math.abs(this.mousePosition.x - previousAnchorPoint.x);\n\t\t\tconst deltaY = Math.abs(this.mousePosition.y - previousAnchorPoint.y);\n\t\n\t\t\tif (deltaX > deltaY) {\n\t\t\t\tthis.snapWireHorizontally(lastAnchorPoint, previousAnchorPoint);\n\t\t\t} else {\n\t\t\t\tthis.snapWireVertically(lastAnchorPoint, previousAnchorPoint);\n\t\t\t}\n\t\t}\n\t}\n\n\tanchorWirePlacement() {\n\t\tthis.placingWire?.anchorPoints.push(this.mousePosition.clone);\n\t}\n\n\tcancelWirePlacement() {\n\t\tthis.placingWire = null;\n\t\tthis.isPlacing = false;\n\t\tthis.circuit.wires.pop();\n\t}\n\n\tendWirePlacement(pin: Pin) {\n\t\tconst isInputPin = pin.isPointingRight;\n\n\t\tif (this.placingWire == null) return;\n\n\t\tlet correctPlacement = false;\n\t\tif (!isInputPin && !this.placingWire.placedBackwards) {\n\t\t\tthis.placingWire.outputPin = pin;\n\t\t\tcorrectPlacement = true;\n\t\t} else if (isInputPin && this.placingWire.placedBackwards) {\n\t\t\tthis.placingWire.inputPin = pin;\n\t\t\tcorrectPlacement = true;\n\t\t}\n\n\t\tif (correctPlacement) {\n\t\t\tthis.placingWire.anchorPoints.pop();\n\t\t\tthis.placingWire.inputPin.addOutputWire(this.placingWire);\n\t\t\tthis.placingWire.inputPin.update();\n\n\t\t\tthis.placingWire = null;\n\t\t\tthis.isPlacing = false;\n\t\t}\n\t}\n\n\tstartChipPlacement(chip: Chip) {\n\t\tconst newChip = new Chip(this.circuit, chip.name, chip.color, false, chip.inputCount, chip.outputCount);\n\t\tnewChip.setLogic(chip.logic);\n\t\tnewChip.position = new Vector2(\n\t\t\tthis.mousePosition.x - newChip.size.x / 2,\n\t\t\tthis.mousePosition.y - newChip.size.y / 2\n\t\t);\n\n\t\tthis.placingChip = newChip;\n\t\tthis.isPlacing = true;\n\t\tthis.circuit.chips.push(newChip);\n\t}\n\n\teditChipPlacement(chip: Chip, index: number) {\n\t\tthis.placingOffset = new Vector2(\n\t\t\t(chip.position.x + chip.size.x / 2) - this.mousePosition.x,\n\t\t\t(chip.position.y + chip.size.y / 2) - this.mousePosition.y\n\t\t);\n\t\tthis.previousPlacement = chip.position.clone;\n\t\tthis.circuit.chips.push(this.circuit.chips.splice(index, 1)[0]);\n\n\t\tthis.placingChip = chip;\n\t\tthis.isPlacing = true;\n\t}\n\n\tupdateChipPlacement() {\n\t\tif (this.placingChip == null) return;\n\t\tthis.placingChip.position.x = this.mousePosition.x - this.placingChip.size.x / 2 + this.placingOffset.x;\n\t\tthis.placingChip.position.y = this.mousePosition.y - this.placingChip.size.y / 2 + this.placingOffset.y;\n\t}\n\n\tcancelChipPlacement() {\n\t\tif (this.placingChip == null) return;\n\n\t\tif (this.previousPlacement != null) {\n\t\t\tthis.placingChip.position = this.previousPlacement;\n\t\t\tthis.previousPlacement = null;\n\t\t} else {\n\t\t\tthis.circuit.chips.pop();\n\t\t}\n\n\t\tthis.placingChip = null;\n\t\tthis.isPlacing = false;\n\t}\n\n\tendChipPlacement() {\n\t\tthis.placingChip = null;\n\t\tthis.isPlacing = false;\n\t\tthis.placingOffset = Vector2.ZERO;\n\t}\n\n\tstartPinPlacement(isInput: boolean) {\n\t\tconst newPin = new ControlledPin(this.circuit, \"PIN\", isInput);\n\n\t\tnewPin.position.x = CONTROLLER.handleTrackWidth + CONTROLLER.pinOffset + CONTROLLER.radius;\n\t\tnewPin.position.y = this.mousePosition.y;\n\n\t\tif (isInput) {\n\t\t\tthis.circuit.inputPins.push(newPin);\n\t\t} else {\n\t\t\tnewPin.position.x = this.circuit.size.x - newPin.position.x;\n\t\t\tthis.circuit.outputPins.push(newPin);\n\t\t}\n\n\t\tthis.placingPin = newPin;\n\t}\n\n\tupdatePinPlacement() {\n\t\tif (this.placingPin != null)\n\t\t\tthis.placingPin.position.y = this.mousePosition.y;\n\t}\n\n\tcancelPinPlacement() {\n\t\tif (this.placingPin?.isInput) {\n\t\t \tthis.circuit.inputPins.pop();\n\t\t} else {\n\t\t\tthis.circuit.outputPins.pop();\n\t\t}\n\n\t\tthis.placingPin = null;\n\t}\n\n\tendPinPlacement() {\n\t\tthis.placingPin = null;\n\t}\n\n\tisPlacingPin(pin: Pin, index: number) {\n\t\tif (!pin.isControlled || this.placingPin == null || this.placingPin.isInput != pin.isInput)\n\t\t\treturn false;\n\n\t\tif (pin.isInput) {\n\t\t\treturn index == this.circuit.inputPins.length - 1;\n\t\t} else {\n\t\t\treturn index == this.circuit.outputPins.length - 1;\n\t\t}\n\t}\n}","import { Vector2 } from \"@prozilla-os/core\";\nimport { Chip, ChipJson } from \"./chips/chip\";\nimport { ControlledPin } from \"./pins/controlledPin\";\nimport { InputHandler } from \"./inputHandler\";\nimport { Wire, WireJson } from \"./wires/wire\";\nimport { BACKGROUND, COLORS, CONTROLLER, CURSORS, ENABLE_COLOR_CACHING, FONT } from \"../constants/logicSim.const\";\nimport { clamp } from \"@prozilla-os/shared\";\n\nexport interface CircuitJson extends ChipJson {\n\twires: WireJson[];\n\tchips: ChipJson[];\n}\n\nexport class Circuit extends Chip {\n\tcanvas!: HTMLCanvasElement;\n\tsize = Vector2.ZERO;\n\tcontext!: CanvasRenderingContext2D;\n\tcolors: { [key: string]: string } = {};\n\tinputHandler: InputHandler;\n\n\tinputPins: ControlledPin[] = [];\n\toutputPins: ControlledPin[] = [];\n\n\twires: Wire[] = [];\n\tchips: Chip[] = [];\n\n\tcursor = CURSORS.default;\n\n\tlastId = 0;\n\n\tconstructor(name: string, color: string, inputCount: number, outputCount: number) {\n\t\tsuper(null, name, color, false, inputCount, outputCount);\n\t\tthis.inputHandler = new InputHandler(this);\n\t}\n\n\tresize() {\n\t\tthis.size.x = this.canvas.clientWidth;\n\t\tthis.size.y = this.canvas.clientHeight;\n\t}\n\n\tinit(canvas: HTMLCanvasElement) {\n\t\tthis.canvas = canvas;\n\t\tthis.context = this.canvas.getContext(\"2d\") as CanvasRenderingContext2D;\n\t\tthis.resize();\n\n\t\t// Detect size changes of canvas\n\t\tconst observer = new ResizeObserver((entries) => {\n\t\t\tentries.forEach(({ target }) => {\n\t\t\t\tif (target === this.canvas && (target.clientWidth != this.size.x || target.clientHeight != this.size.y)) {\n\t\t\t\t\tthis.resize();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tobserver.observe(this.canvas);\n\n\t\tthis.inputHandler.init();\n\n\t\tthis.render();\n\t}\n\n\tcleanup() {\n\t\tthis.inputHandler.cleanup();\n\t}\n\n\treset() {\n\t\tthis.inputPins = [];\n\t\tthis.outputPins = [];\n\t\tthis.wires = [];\n\t\tthis.chips = [];\n\n\t\tthis.inputHandler.reset();\n\t}\n\n\tgetColor(key: string) {\n\t\tif (this.colors[key] != null)\n\t\t\treturn this.colors[key];\n\n\t\tconst color = getComputedStyle(this.canvas).getPropertyValue(\"--\" + key);\n\n\t\tif (ENABLE_COLOR_CACHING)\n\t\t\tthis.colors[key] = color;\n\n\t\treturn color;\n\t}\n\n\tisPointInsideRect(rect: { position: Vector2, size: Vector2 }, point: Vector2) {\n\t\treturn point.x > rect.position.x && point.y > rect.position.y\n\t\t\t&& point.x < rect.position.x + rect.size.x && point.y < rect.position.y + rect.size.y;\n\t}\n\n\tgetUniqueId() {\n\t\treturn this.lastId++;\n\t}\n\n\tgetTextRect(size: number, content: string) {\n\t\tthis.context.textBaseline = \"middle\";\n\t\tthis.context.font = `bold ${size}px ${FONT}`;\n\t\tconst metrics = this.context.measureText(content);\n\n\t\tconst width = metrics.actualBoundingBoxRight + metrics.actualBoundingBoxLeft;\n\t\tconst height = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;\n\n\t\treturn { x: width, y: height };\n\t}\n\n\tdrawRect(style: string, positionX: number, positionY: number, sizeX: number, sizeY: number) {\n\t\tthis.context.fillStyle = style;\n\t\tthis.context.fillRect(positionX, positionY, sizeX, sizeY);\n\t}\n\n\tdrawCircle(style: string, positionX: number, positionY: number, radius: number) {\n\t\tthis.context.beginPath();\n\t\tthis.context.arc(positionX, positionY, radius, 0, 2 * Math.PI);\n\n\t\tthis.context.fillStyle = style;\n\t\tthis.context.fill();\n\t}\n\n\tdrawCurvedLine(style: string, positions: Vector2[], width: number, radius: number, resolution: number) {\n\t\tif (positions.length < 2)\n\t\t\treturn;\n\n\t\tthis.context.lineWidth = width;\n\t\tthis.context.lineJoin = \"round\";\n\t\tthis.context.lineCap = \"round\";\n\n\t\t/**\n\t\t * Based on https://github.com/SebLague/Digital-Logic-Sim/blob/main/Assets/Modules/Chip%20Creation/Scripts/Chip/Wires/WireRenderer.cs\n\t\t * TO DO: optimize\n\t\t */\n\n\t\tconst drawPoints: Vector2[] = [];\n\t\tdrawPoints.push(positions[0]);\n\n\t\tfor (let i = 1; i < positions.length - 1; i++) {\n\t\t\tconst targetPoint = positions[i];\n\t\t\tconst targetDir = Vector2.normalize(Vector2.subtract(positions[i], positions[i - 1]));\n\t\t\tconst distanceToTarget = Vector2.magnitude(Vector2.subtract(positions[i], positions[i - 1]));\n\t\t\tconst distanceToCurveStart = Math.max(distanceToTarget - radius, distanceToTarget / 2);\n\n\t\t\tconst nextTargetDir = Vector2.normalize(Vector2.subtract(positions[i + 1], positions[i]));\n\t\t\tconst nextLineLength = Vector2.magnitude(Vector2.subtract(positions[i + 1], positions[i]));\n\n\t\t\tconst curveStartPoint = Vector2.add(positions[i - 1], Vector2.scale(targetDir, distanceToCurveStart));\n\t\t\tconst curveEndPoint = Vector2.add(targetPoint, Vector2.scale(nextTargetDir, Math.min(radius, nextLineLength / 2)));\n\n\t\t\t// Bezier\n\t\t\tfor (let j = 0; j < resolution; j++) {\n\t\t\t\tconst t = j / (resolution - 1);\n\t\t\t\tconst a = Vector2.lerp(curveStartPoint, targetPoint, t);\n\t\t\t\tconst b = Vector2.lerp(targetPoint, curveEndPoint, t);\n\t\t\t\tconst p = Vector2.lerp(a, b, t);\n\n\t\t\t\tif (Vector2.sqrDistance(p, drawPoints[drawPoints.length - 1]) > 0.001) {\n\t\t\t\t\tdrawPoints.push(p);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdrawPoints.push(positions[positions.length - 1]);\n\n\t\tthis.context.beginPath();\n\t\tthis.context.moveTo(drawPoints[0].x, drawPoints[0].y);\n\n\t\tfor (let i = 1; i < drawPoints.length; i++) {\n\t\t\tthis.context.lineTo(drawPoints[i].x, drawPoints[i].y);\n\t\t}\n\n\t\tthis.context.strokeStyle = style;\n\t\tthis.context.stroke();\n\t}\n\n\tdrawText(style: string, align: CanvasTextAlign, positionX: number, positionY: number, size: number, content: string) {\n\t\tthis.context.fillStyle = style;\n\t\tthis.context.textAlign = align;\n\t\tthis.context.textBaseline = \"middle\";\n\t\tthis.context.font = `bold ${size}px ${FONT}`;\n\t\tthis.context.fillText(content, positionX, positionY);\n\t}\n\n\tsetDrawingOpacity(alpha: number) {\n\t\tthis.context.globalAlpha = clamp(alpha, 0, 1);\n\t}\n\n\tresetDrawingOpacity() {\n\t\tthis.setDrawingOpacity(1);\n\t}\n\n\tdrawBackground() {\n\t\tconst margin = CONTROLLER.handleTrackWidth;\n\t\tconst padding = BACKGROUND.padding;\n\n\t\tthis.drawRect(this.getColor(COLORS.background.margin), 0, 0, this.size.x, this.size.y);\n\n\t\tlet offset = 0;\n\n\t\tthis.drawRect(\n\t\t\tthis.getColor(COLORS.background.outer),\n\t\t\toffset + margin, offset,\n\t\t\tthis.size.x - margin * 2, this.size.y\n\t\t);\n\n\t\toffset = padding - BACKGROUND.borderWidth;\n\t\tthis.drawRect(\n\t\t\tthis.getColor(COLORS.background.border),\n\t\t\toffset + margin, offset,\n\t\t\tthis.size.x - offset * 2 - margin * 2, this.size.y - offset * 2\n\t\t);\n\n\t\toffset = padding;\n\t\tthis.drawRect(\n\t\t\tthis.getColor(COLORS.background.inner),\n\t\t\toffset + margin, offset,\n\t\t\tthis.size.x - offset * 2 - margin * 2, this.size.y - offset * 2\n\t\t);\n\t}\n\n\tdrawWires() {\n\t\tthis.wires.forEach((wire, index) => {\n\t\t\tconst isPlacingWire = this.inputHandler.placingWire != null && index == this.wires.length - 1;\n\t\t\twire.draw(isPlacingWire);\n\t\t});\n\t}\n\n\tdrawChips() {\n\t\tthis.chips.forEach((chip, index) => {\n\t\t\tconst isPlacingChip = this.inputHandler.placingChip != null && index == this.chips.length - 1;\n\t\t\tchip.draw(isPlacingChip);\n\t\t});\n\t}\n\n\tdraw() {\n\t\tthis.drawBackground();\n\t\tthis.drawWires();\n\t\tthis.drawChips();\n\t\tsuper.drawPins(false);\n\t}\n\n\trender() {\n\t\tif (this.canvas.width != this.size.x)\n\t\t\tthis.canvas.width = this.size.x;\n\t\tif (this.canvas.height != this.size.y)\n\t\t\tthis.canvas.height = this.size.y;\n\n\t\tthis.cursor = CURSORS.default;\n\n\t\tthis.draw();\n\n\t\tif (this.inputHandler.isPlacing) {\n\t\t\tthis.canvas.style.cursor = CURSORS.default;\n\t\t} else {\n\t\t\tthis.canvas.style.cursor = this.cursor;\n\t\t}\n\n\t\twindow.requestAnimationFrame(() => {\n\t\t\tthis.render();\n\t\t});\n\t}\n\n\ttoJson() {\n\t\tconst object = super.toJson() as CircuitJson;\n\n\t\tif (this.wires.length > 0)\n\t\t\tobject.wires = this.wires.map((wire) => wire.toJson());\n\n\t\tif (this.chips.length > 0)\n\t\t\tobject.chips = this.chips.map((chip) => chip.toJson());\n\n\t\treturn object;\n\t}\n\n\ttoString(): string {\n\t\tconst json = this.toJson();\n\t\treturn JSON.stringify(json);\n\t}\n}","import { Chip } from \"./chip\";\nimport { State } from \"../_utils/state\";\nimport { Circuit, CircuitJson } from \"../circuit\";\nimport { ControlledPin } from \"../pins/controlledPin\";\nimport { Pin } from \"../pins/pin\";\nimport { Wire } from \"../wires/wire\";\nimport { Vector2, VirtualFolder } from \"@prozilla-os/core\";\n\nexport class ChipsManager {\n\tstatic CHIPS: Record<string, Chip> = {\n\t\tand: new Chip(null, \"AND\", \"blue\", true, 2, 1).setLogic((inputStates: State[]) => {\n\t\t\tif (inputStates[0].value === 1 && inputStates[1].value === 1) {\n\t\t\t\treturn [State.HIGH];\n\t\t\t} else {\n\t\t\t\treturn [State.LOW];\n\t\t\t}\n\t\t}),\n\t\tnot: new Chip(null, \"NOT\", \"red\", true, 1, 1).setLogic((inputStates: State[]) => {\n\t\t\treturn [State.invert(inputStates[0])];\n\t\t}),\n\t};\n\n\tstatic saveCircuit(circuit: Circuit, virtualFolder: VirtualFolder) {\n\t\tvirtualFolder.createFile(circuit.name, \"json\", (file) => {\n\t\t\tfile.setContent(circuit.toString());\n\t\t});\n\t}\n\n\tstatic loadCircuit(circuit: Circuit, virtualFolder: VirtualFolder) {\n\t\tcircuit.reset();\n\t\tconst virtualFile = virtualFolder.findFile(circuit.name, \"json\");\n\n\t\tif (virtualFile == null)\n\t\t\treturn;\n\n\t\tvirtualFile.read()?.then((content) => {\n\t\t\tconst data = JSON.parse(content as string) as CircuitJson;\n\n\t\t\tcircuit.color = data.color;\n\t\t\tcircuit.name = data.name;\n\n\t\t\tconst pins: { [id: number]: Pin } = {};\n\n\t\t\t// Load input pins\n\t\t\tcircuit.inputCount = data.inputPins?.length ?? 0;\n\t\t\tdata.inputPins?.forEach((pinData) => {\n\t\t\t\tconst newPin = new ControlledPin(circuit, pinData.name, true, pinData.id);\n\t\t\t\tnewPin.position = pinData.position as Vector2;\n\n\t\t\t\tcircuit.inputPins.push(newPin);\n\t\t\t\tpins[pinData.id] = newPin;\n\t\t\t});\n\n\t\t\t// Load output pins\n\t\t\tcircuit.outputCount = data.outputPins?.length ?? 0;\n\t\t\tdata.outputPins?.forEach((pinData) => {\n\t\t\t\tconst newPin = new ControlledPin(circuit, pinData.name, false, pinData.id);\n\t\t\t\tnewPin.position = pinData.position as Vector2;\n\n\t\t\t\tcircuit.outputPins.push(newPin);\n\t\t\t\tpins[pinData.id] = newPin;\n\t\t\t});\n\n\t\t\t// Load chips\n\t\t\tdata.chips?.forEach((chipData) => {\n\t\t\t\tconst newChip = new Chip(circuit, chipData.name, chipData.color, false, 0, 0);\n\t\t\t\tnewChip.position = chipData.position as Vector2;\n\n\t\t\t\t// Load input pins\n\t\t\t\tnewChip.inputCount = chipData.inputPins?.length ?? 0;\n\t\t\t\tchipData.inputPins?.forEach((pinData) => {\n\t\t\t\t\tconst newPin = new Pin(circuit, pinData.name, true, newChip, pinData.id);\n\t\t\t\t\tnewChip.inputPins.push(newPin);\n\t\t\t\t\tpins[pinData.id] = newPin;\n\t\t\t\t});\n\n\t\t\t\t// Load output pins\n\t\t\t\tnewChip.outputCount = chipData.outputPins?.length ?? 0;\n\t\t\t\tchipData.outputPins?.forEach((pinData) => {\n\t\t\t\t\tconst newPin = new Pin(circuit, pinData.name, false, newChip, pinData.id);\n\t\t\t\t\tnewChip.outputPins.push(newPin);\n\t\t\t\t\tpins[pinData.id] = newPin;\n\t\t\t\t});\n\n\t\t\t\t// Load logic\n\t\t\t\tnewChip.setLogic((ChipsManager.CHIPS[chipData.name]).logic);\n\t\t\t\tnewChip.update();\n\n\t\t\t\tcircuit.chips.push(newChip);\n\t\t\t});\n\n\t\t\t// Load wires\n\t\t\tdata.wires?.forEach((wireData) => {\n\t\t\t\tconst inputPin = pins[wireData.inputId];\n\t\t\t\tconst outputPin = pins[wireData.outputId];\n\t\t\t\tconst anchorPoints = wireData.anchorPoints as Vector2[] ?? [];\n\n\t\t\t\tconst newWire = new Wire(circuit, wireData.color, inputPin, outputPin, anchorPoints);\n\t\t\t\tinputPin?.addOutputWire(newWire);\n\t\t\t\tcircuit.wires.push(newWire);\n\t\t\t});\n\t\t}).catch((error) => {\n\t\t\tconsole.error(error);\n\t\t});\n\t}\n}","import { useEffect, useRef, useState } from \"react\";\nimport styles from \"./CircuitView.module.css\";\nimport { App, ClickAction, DropdownAction, HeaderMenu, openUrl, useAppFolder } from \"@prozilla-os/core\";\nimport { Circuit } from \"../core/circuit\";\nimport { ChipsManager } from \"../core/chips/chipsManager\";\n\ninterface CircuitViewProps {\n\tapp?: App;\n}\n\nexport function CircuitView({ app }: CircuitViewProps) {\n\tconst virtualFolder = useAppFolder(app);\n\tconst [circuit] = useState(new Circuit(\"Chip\", \"#000\", 2, 1));\n\tconst canvasRef = useRef(null);\n\n\tuseEffect(() => {\n\t\tif (canvasRef.current == null && circuit.canvas != null)\n\t\t\treturn;\n\n\t\tcircuit.init(canvasRef.current as unknown as HTMLCanvasElement);\n\n\t\treturn () => {\n\t\t\tcircuit.cleanup();\n\t\t};\n\t}, [canvasRef, circuit]);\n\n\treturn <>\n\t\t<HeaderMenu>\n\t\t\t<DropdownAction label=\"Circuit\" showOnHover={false}>\n\t\t\t\t<ClickAction label=\"New\" onTrigger={() => { circuit.reset(); }}/>\n\t\t\t\t<ClickAction label=\"Save\" onTrigger={() => {\n\t\t\t\t\tif (virtualFolder != null)\n\t\t\t\t\t\tChipsManager.saveCircuit(circuit, virtualFolder);\n\t\t\t\t}}/>\n\t\t\t\t<ClickAction label=\"Load\" onTrigger={() => {\n\t\t\t\t\tif (virtualFolder != null)\n\t\t\t\t\t\tChipsManager.loadCircuit(circuit, virtualFolder);\n\t\t\t\t}}/>\n\t\t\t</DropdownAction>\n\t\t\t<DropdownAction label=\"Add\" showOnHover={false}>\n\t\t\t\t<ClickAction label=\"AND gate\" onTrigger={() => {\n\t\t\t\t\tcircuit.inputHandler.startChipPlacement(ChipsManager.CHIPS.and);\n\t\t\t\t}}/>\n\t\t\t\t<ClickAction label=\"NOT gate\" onTrigger={() => {\n\t\t\t\t\tcircuit.inputHandler.startChipPlacement(ChipsManager.CHIPS.not);\n\t\t\t\t}}/>\n\t\t\t</DropdownAction>\n\t\t\t<DropdownAction label=\"Help\" showOnHover={false}>\n\t\t\t\t<ClickAction label=\"Digital Electronics Glossary\" onTrigger={() => {\n\t\t\t\t\topenUrl(\"http://www.pmcgibbon.net/teachcte/electron/degloss1.htm\");\n\t\t\t\t}}/>\n\t\t\t</DropdownAction>\n\t\t</HeaderMenu>\n\t\t<div className={styles.CircuitView}>\n\t\t\t<canvas ref={canvasRef} className={styles.Canvas}/>\n\t\t</div>\n\t</>;\n}","import { WindowProps } from \"@prozilla-os/core\";\nimport { CircuitView } from \"./CircuitView\";\nimport styles from \"./LogicSim.module.css\";\n\nexport function LogicSim({ app }: WindowProps) {\n\treturn <div className={styles.LogicSim}>\n\t\t<CircuitView app={app}/>\n\t</div>;\n}","import { App } from \"@prozilla-os/core\";\nimport { LogicSim } from \"./components/LogicSim\";\n\nconst logicSim = new App(\"Logic Sim\", \"logic-sim\", LogicSim)\n\t.setIconUrl(\"https://os.prozilla.dev/assets/apps/icons/logic-sim.svg\")\n\t.setPinnedByDefault(false)\n\t.setCategory(\"Education\");\nlogicSim.setMetadata({ name: \"@prozilla-os/logic-sim\", version: \"1.1.17\", author: \"Prozilla\" });\n\n\nexport { logicSim };"],"names":["_State","value","__publicField","state","State","CURSORS","FONT","BACKGROUND","CONTROLLER","WIRE","PIN","CHIP","COLORS","Pin","circuit","name","isInput","attachedChip","id","Vector2","wire","_a","isPlacing","color","positionX","leftAligned","textRect","backgroundSize","Chip","isBlueprint","inputCount","outputCount","width","minHeight","i","newPin","pin","logic","inputStates","outputStates","reposition","index","gap","isPlacingPin","object","ControlledPin","size","positionY","rect","Wire","inputPin","outputPin","anchorPoints","positions","InputHandler","event","isHoveringPinHandle","top","bottom","invalidPlacement","eventComplete","chip","hoveringPin","isInputPin","anchorPoint","lastAnchorPoint","previousAnchorPoint","closestPositionX","closestDistance","point","distance","pins","closestPositionY","anchorCount","_b","_c","_d","_f","_e","deltaX","deltaY","correctPlacement","newChip","Circuit","canvas","entries","target","key","content","metrics","height","style","sizeX","sizeY","radius","resolution","drawPoints","targetPoint","targetDir","distanceToTarget","distanceToCurveStart","nextTargetDir","nextLineLength","curveStartPoint","curveEndPoint","j","t","a","b","p","align","alpha","clamp","margin","padding","offset","isPlacingWire","isPlacingChip","json","_ChipsManager","virtualFolder","file","virtualFile","data","pinData","chipData","wireData","newWire","error","ChipsManager","CircuitView","app","useAppFolder","useState","canvasRef","useRef","useEffect","jsxs","Fragment","HeaderMenu","DropdownAction","jsx","ClickAction","openUrl","styles","LogicSim","logicSim","App"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"main.js","sources":["../src/core/_utils/state.ts","../src/constants/logicSim.const.ts","../src/core/pins/pin.ts","../src/core/chips/chip.ts","../src/core/pins/controlledPin.ts","../src/core/wires/wire.ts","../src/components/context-menu/ChipContextMenu.tsx","../src/core/inputHandler.ts","../src/core/circuit.ts","../src/core/chips/chipsManager.ts","../src/components/CircuitView.tsx","../src/components/LogicSim.tsx","../src/main.ts"],"sourcesContent":["export class State {\n\tvalue: number;\n\n\tstatic readonly LOW = new State(0);\n\tstatic readonly HIGH = new State(1);\n\n\tconstructor(value: number) {\n\t\tthis.value = value;\n\t}\n\n\tstatic invert(state: State) {\n\t\treturn new State(1 - state.value);\n\t}\n\n\tisEqual(state: State) {\n\t\treturn this.value === state.value;\n\t}\n\n\tisLow() {\n\t\treturn this.value === 0;\n\t}\n\n\tisHigh() {\n\t\treturn this.value === 1;\n\t}\n}","export const CURSORS = {\n\tdefault: \"default\",\n\tpointer: \"pointer\",\n};\n\nexport const FONT = \"outfit\";\nexport const ENABLE_COLOR_CACHING = true;\nexport const VIRTUAL_PATH = \"~/Apps/logic-sim/\";\n\nexport const BACKGROUND = {\n\tpadding: 30,\n\tborderWidth: 7.5,\n};\n\nexport const CONTROLLER = {\n\tradius: 25,\n\tborderWidth: 5,\n\tpinOffset: 42.5,\n\tconnectorWidth: 7.5,\n\thandleWidth: 15,\n\thandleHeight: 50,\n\thandleTrackWidth: 22.5,\n\tplacingOpacity: 0.5,\n};\n\nexport const WIRE = {\n\twidth: 5,\n\tsnappingSensitivity: 10,\n\tcornerRadius: 25,\n\tresolution: 8,\n};\n\nexport const PIN = {\n\tradius: 10,\n\tlabel: {\n\t\toffset: 10,\n\t\tfontSize: 15,\n\t\tpadding: 5,\n\t},\n};\n\nexport const CHIP = {\n\tBorderWidth: 5,\n\tpadding: 10,\n\tfontSize: 35,\n\tplacingOutline: 10,\n};\n\nexport const COLORS = {\n\tpin: {\n\t\tfill: \"black-4\",\n\t\tfillHover: \"black-3\",\n\t\tlabelText: \"white-0\",\n\t\tlabelBackground: \"black-4\",\n\t},\n\tcontroller: {\n\t\tstroke: \"black-4\",\n\t\tconnector: \"black-4\",\n\t\ton: \"red-0\",\n\t\toff: \"red-2\",\n\t\thover: \"white-0\",\n\t\thandle: \"black-3\",\n\t\thandleHover: \"black-4\",\n\t},\n\tbackground: {\n\t\tborder: \"black-0\",\n\t\touter: \"black-1\",\n\t\tinner: \"black-2\",\n\t\tmargin: \"black-2\",\n\t},\n\twire: {\n\t\tplacing: \"black-1\",\n\t},\n\tchip: {\n\t\ttext: \"black-4\",\n\t\toutline: \"white-0\",\n\t},\n};","import { Chip } from \"../chips/chip\";\nimport { Circuit } from \"../circuit\";\nimport { State } from \"../_utils/state\";\nimport { Wire } from \"../wires/wire\";\nimport { COLORS, CONTROLLER, CURSORS, PIN } from \"../../constants/logicSim.const\";\nimport { Vector2 } from \"@prozilla-os/shared\";\n\nexport interface PinJson {\n\tname: string;\n\tid: number;\n\tposition: {\n\t\tx: number;\n\t\ty: number;\n\t};\n}\n\nexport class Pin {\n\tid: number;\n\tname!: string;\n\tposition = Vector2.ZERO;\n\tattachedChip!: Chip;\n\tcircuit!: Circuit;\n\n\tstate = State.LOW;\n\tisInput!: boolean;\n\tisControlled: boolean = false;\n\toutputWires: Wire[] = [];\n\n\tconstructor(circuit: Circuit, name: string, isInput: boolean, attachedChip: Chip, id?: number) {\n\t\tObject.assign(this, { circuit, name, isInput, attachedChip });\n\t\tthis.id = id ?? this.circuit.getUniqueId();\n\t}\n\n\tgetRawPosition() {\n\t\treturn Vector2.product(this.position, this.circuit.size);\n\t}\n\n\taddOutputWire(wire: Wire) {\n\t\tthis.outputWires.push(wire);\n\t\twire.setState(this.state);\n\t}\n\n\tsetState(state: State) {\n\t\tif (this.state.isEqual(state))\n\t\t\treturn;\n\n\t\tthis.state = state;\n\t\tthis.update();\n\t}\n\n\tupdate() {\n\t\t// TO DO: clean this mess\n\t\tthis.outputWires.forEach((wire) => {\n\t\t\twire.setState(this.state);\n\t\t});\n\t\tthis.attachedChip.update();\n\t}\n\n\tget isPointingRight() {\n\t\treturn this.isInput === this.isControlled;\n\t}\n\n\tdraw(isPlacing: boolean) {\n\t\tlet color = COLORS.pin.fill;\n\n\t\tconst { x: positionX, y: positionY } = this.getRawPosition();\n\t\tif (this.circuit.inputHandler.rawMousePosition.getDistance(this.position.x * this.circuit.size.x, positionY) <= PIN.radius) {\n\t\t\tthis.circuit.cursor = CURSORS.pointer;\n\t\t\tcolor = COLORS.pin.fillHover;\n\n\t\t\t// Draw label\n\t\t\tlet offsetPositionX = positionX;\n\t\t\tconst leftAligned = this.isPointingRight;\n\t\t\tconst textRect = this.circuit.getTextRect(PIN.label.fontSize, this.name);\n\n\t\t\tif (leftAligned) {\n\t\t\t\toffsetPositionX += PIN.radius + PIN.label.offset;\n\t\t\t} else {\n\t\t\t\toffsetPositionX -= PIN.radius + PIN.label.offset;\n\t\t\t}\n\n\t\t\tconst backgroundSize = {\n\t\t\t\tx: textRect.x + PIN.label.padding * 2,\n\t\t\t\ty: textRect.y + PIN.label.padding * 2,\n\t\t\t};\n\n\t\t\tthis.circuit.drawRect(\n\t\t\t\tthis.circuit.getColor(COLORS.pin.labelBackground),\n\t\t\t\tleftAligned ? offsetPositionX : offsetPositionX - backgroundSize.x, positionY - textRect.y / 2 - PIN.label.padding,\n\t\t\t\tbackgroundSize.x, backgroundSize.y\n\t\t\t);\n\n\t\t\tif (leftAligned) {\n\t\t\t\toffsetPositionX += PIN.label.padding;\n\t\t\t} else {\n\t\t\t\toffsetPositionX -= PIN.label.padding;\n\t\t\t}\n\n\t\t\tthis.circuit.drawText(\n\t\t\t\tthis.circuit.getColor(COLORS.pin.labelText),\n\t\t\t\tleftAligned ? \"left\" : \"right\",\n\t\t\t\toffsetPositionX, positionY,\n\t\t\t\tPIN.label.fontSize,\n\t\t\t\tthis.name\n\t\t\t);\n\t\t}\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.setDrawingOpacity(CONTROLLER.placingOpacity);\n\n\t\tthis.circuit.drawCircle(\n\t\t\tthis.circuit.getColor(color),\n\t\t\tpositionX, positionY,\n\t\t\tPIN.radius\n\t\t);\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t}\n\n\ttoJson(): PinJson {\n\t\tconst object: PinJson = {\n\t\t\tname: this.name,\n\t\t\tid: this.id,\n\t\t\tposition: this.position,\n\t\t};\n\n\t\treturn object;\n\t}\n}","import { Circuit } from \"../circuit\";\nimport { Pin, PinJson } from \"../pins/pin\";\nimport { State } from \"../_utils/state\";\nimport { CHIP, COLORS, PIN } from \"../../constants/logicSim.const\";\nimport { removeFromArray, Vector2 } from \"@prozilla-os/shared\";\n\nexport interface ChipJson {\n\tcolor: string;\n\tname: string;\n\tposition: {\n\t\tx: number;\n\t\ty: number;\n\t};\n\tinputPins?: PinJson[];\n\toutputPins?: PinJson[];\n}\n\nexport class Chip {\n\tcolor!: string;\n\tname!: string;\n\tposition = Vector2.ZERO;\n\tsize!: Vector2;\n\tcircuit!: Circuit;\n\tisCircuit = false;\n\tisBlueprint = false;\n\n\tinputCount = 0;\n\toutputCount = 0;\n\tinputPins!: Pin[];\n\toutputPins!: Pin[];\n\tlogic?: (inputStates: State[]) => State[];\n\n\tconstructor(circuit: Circuit | null, name: string, color: string, isBlueprint: boolean, inputCount: number, outputCount: number) {\n\t\tObject.assign(this, { circuit, name, color, isBlueprint, inputCount, outputCount });\n\n\t\tif (circuit == null && !isBlueprint && this instanceof Circuit) {\n\t\t\tthis.circuit = this;\n\t\t\tthis.isCircuit = true;\n\t\t}\n\n\t\tif (this.isCircuit || this.isBlueprint)\n\t\t\treturn;\n\n\n\t\tif (circuit != null) {\n\t\t\tconst textRect = this.circuit.getTextRect(CHIP.fontSize, this.name);\n\n\t\t\tconst width = textRect.x + (CHIP.padding + CHIP.BorderWidth) * 2;\n\t\t\tconst minHeight = textRect.y + (CHIP.padding + CHIP.BorderWidth) * 2;\n\t\n\t\t\tthis.size = new Vector2(width, minHeight);\n\t\t}\n\n\t\tthis.inputPins = [];\n\t\tfor (let i = 0; i < inputCount; i++) {\n\t\t\tconst newPin = new Pin(this.circuit, \"IN \" + i, true, this);\n\t\t\tthis.inputPins.push(newPin);\n\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n\t\t\tif (this.isCircuit)\n\t\t\t\tnewPin.isControlled = true;\n\t\t}\n\n\t\tthis.outputPins = [];\n\t\tfor (let i = 0; i < outputCount; i++) {\n\t\t\tconst newPin = new Pin(this.circuit, \"OUT \" + i, false, this);\n\t\t\tthis.outputPins.push(newPin);\n\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n\t\t\tif (this.isCircuit)\n\t\t\t\tnewPin.isControlled = true;\n\t\t}\n\t}\n\n\tsetCircuit(circuit: Circuit) {\n\t\tthis.circuit = circuit;\n\n\t\tthis.inputPins.concat(this.outputPins).forEach((pin) => { pin.circuit = circuit; });\n\t}\n\n\tsetLogic(logic?: (inputStates: State[]) => State[]) {\n\t\tthis.logic = logic;\n\t\treturn this;\n\t}\n\n\tupdate() {\n\t\tif (this.logic == null)\n\t\t\treturn;\n\n\t\tconst inputStates: State[] = [];\n\t\tfor (let i = 0; i < this.inputCount; i++) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n\t\t\tconst state = this.inputPins[i].state ?? State.LOW;\n\t\t\tinputStates.push(state);\n\t\t}\n\n\t\tconst outputStates: State[] = this.logic(inputStates);\n\n\t\tfor (let i = 0; i < this.outputCount; i++) {\n\t\t\tthis.outputPins[i].setState(outputStates[i]);\n\t\t}\n\t}\n\n\tdrawPins(reposition = true) {\n\t\tthis.inputPins.forEach((pin, index) => {\n\t\t\tif (reposition) {\n\t\t\t\tconst gap = (this.size.y - this.inputCount * PIN.radius * 2) / (this.inputCount + 1);\n\t\t\t\tpin.position.x = this.position.x;\n\t\t\t\tpin.position.y = this.position.y + (gap * (index + 1) + PIN.radius * (2 * index + 1)) / this.circuit.size.y;\n\t\t\t}\n\n\t\t\tconst isPlacingPin = this.circuit.inputHandler.isPlacingPin(pin, index);\n\t\t\tpin.draw(isPlacingPin);\n\t\t});\n\n\t\tthis.outputPins.forEach((pin, index) => {\n\t\t\tif (reposition) {\n\t\t\t\tconst gap = (this.size.y - this.outputCount * PIN.radius * 2) / (this.outputCount + 1);\n\t\t\t\tpin.position.x = this.position.x + this.size.x / this.circuit.size.x;\n\t\t\t\tpin.position.y = this.position.y + (gap * (index + 1) + PIN.radius * (2 * index + 1)) / this.circuit.size.y;\n\t\t\t}\n\n\t\t\tconst isPlacingPin = this.circuit.inputHandler.isPlacingPin(pin, index);\n\t\t\tpin.draw(isPlacingPin);\n\t\t});\n\t}\n\n\tgetBounds() {\n\t\treturn {\n\t\t\tposition: Vector2.product(this.position, this.circuit.size),\n\t\t\tsize: this.size,\n\t\t};\n\t}\n\n\tdraw(isPlacing: boolean) {\n\t\tconst { position, size } = this.getBounds();\n\n\t\tthis.circuit.drawRect(\n\t\t\tthis.circuit.getColor(this.color + \"-1\"),\n\t\t\tposition.x, position.y,\n\t\t\tsize.x, size.y\n\t\t);\n\t\tthis.circuit.drawRect(\n\t\t\tthis.circuit.getColor(this.color + \"-0\"),\n\t\t\tposition.x + CHIP.BorderWidth, position.y + CHIP.BorderWidth,\n\t\t\tsize.x - CHIP.BorderWidth * 2, size.y - CHIP.BorderWidth * 2\n\t\t);\n\n\t\tthis.circuit.drawText(\n\t\t\tthis.circuit.getColor(COLORS.chip.text),\n\t\t\t\"center\",\n\t\t\tposition.x + size.x / 2, position.y + size.y / 2,\n\t\t\tCHIP.fontSize,\n\t\t\tthis.name\n\t\t);\n\n\t\tif (isPlacing) {\n\t\t\tthis.circuit.setDrawingOpacity(0.25);\n\t\t\tthis.circuit.drawRect(\n\t\t\t\tthis.circuit.getColor(COLORS.chip.outline),\n\t\t\t\tposition.x - CHIP.placingOutline, position.y - CHIP.placingOutline,\n\t\t\t\tsize.x + CHIP.placingOutline * 2, size.y + CHIP.placingOutline * 2\n\t\t\t);\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t\t}\n\n\t\tthis.drawPins();\n\t}\n\n\tdelete() {\n\t\t// TO DO: Disconnect wires\n\t\tremoveFromArray(this, this.circuit.chips);\n\t}\n\n\ttoJson(): ChipJson {\n\t\tconst object: ChipJson = {\n\t\t\tcolor: this.color,\n\t\t\tname: this.name,\n\t\t\tposition: {\n\t\t\t\tx: this.position.x,\n\t\t\t\ty: this.position.y,\n\t\t\t},\n\t\t};\n\n\t\tif (this.inputPins.length > 0)\n\t\t\tobject.inputPins = this.inputPins.map((pin) => pin.toJson());\n\n\t\tif (this.outputPins.length > 0)\n\t\t\tobject.outputPins = this.outputPins.map((pin) => pin.toJson());\n\n\t\treturn object;\n\t}\n}","import { Vector2 } from \"@prozilla-os/shared\";\nimport { Circuit } from \"../circuit\";\nimport { Pin } from \"./pin\";\nimport { COLORS, CONTROLLER, CURSORS } from \"../../constants/logicSim.const\";\n\nexport class ControlledPin extends Pin {\n\tconstructor(circuit: Circuit, name: string, isInput: boolean, id?: number) {\n\t\tsuper(circuit, name, isInput, circuit, id);\n\t\tthis.isControlled = true;\n\t}\n\n\tdrawControllerHandle(isPlacing: boolean) {\n\t\tconst size = { x: CONTROLLER.handleWidth, y: CONTROLLER.handleHeight };\n\n\t\tconst rawPosition = this.getRawPosition();\n\t\tlet positionX = rawPosition.x;\n\t\tconst positionY = rawPosition.y - size.y / 2;\n\n\t\tif (this.isInput) {\n\t\t\tpositionX -= CONTROLLER.pinOffset + CONTROLLER.handleTrackWidth + CONTROLLER.handleHeight / 2;\n\t\t} else {\n\t\t\tpositionX += CONTROLLER.pinOffset + (CONTROLLER.handleTrackWidth - CONTROLLER.handleWidth) + CONTROLLER.handleHeight / 2;\n\t\t}\n\n\t\tconst rect = {\n\t\t\tposition: new Vector2(positionX, positionY),\n\t\t\tsize: new Vector2(size.x, size.y),\n\t\t};\n\n\t\tlet color: string;\n\n\t\tif (this.circuit.isPointInsideRect(rect, this.circuit.inputHandler.rawMousePosition)) {\n\t\t\tcolor = COLORS.controller.handleHover;\n\t\t\tthis.circuit.cursor = CURSORS.pointer;\n\t\t} else {\n\t\t\tcolor = COLORS.controller.handle;\n\t\t}\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.setDrawingOpacity(CONTROLLER.placingOpacity);\n\n\t\tthis.circuit.drawRect(\n\t\t\tthis.circuit.getColor(color),\n\t\t\trect.position.x, rect.position.y,\n\t\t\trect.size.x, rect.size.y\n\t\t);\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t}\n\n\tdrawController(isPlacing: boolean) {\n\t\tconst rawPosition = this.getRawPosition();\n\t\tconst positionX = this.isInput ? rawPosition.x - CONTROLLER.pinOffset : rawPosition.x + CONTROLLER.pinOffset;\n\t\tconst positionY = rawPosition.y;\n\n\t\tlet color: string;\n\n\t\tif (this.state.value === 1) {\n\t\t\tcolor = COLORS.controller.on;\n\t\t} else {\n\t\t\tcolor = COLORS.controller.off;\n\t\t}\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.setDrawingOpacity(CONTROLLER.placingOpacity);\n\n\t\tthis.circuit.drawCircle(\n\t\t\tthis.circuit.getColor(COLORS.controller.stroke),\n\t\t\tpositionX, positionY,\n\t\t\tCONTROLLER.radius\n\t\t);\n\t\tthis.circuit.drawCircle(\n\t\t\tthis.circuit.getColor(color),\n\t\t\tpositionX, positionY,\n\t\t\tCONTROLLER.radius - CONTROLLER.borderWidth\n\t\t);\n\n\t\tconst isInteractable = this.isInput && this.isControlled && !isPlacing;\n\t\tif (isInteractable && this.circuit.inputHandler.rawMousePosition.getDistance(positionX, positionY) <= CONTROLLER.radius) {\n\t\t\tthis.circuit.setDrawingOpacity(0.125);\n\t\t\tthis.circuit.drawCircle(\n\t\t\t\tthis.circuit.getColor(COLORS.controller.hover),\n\t\t\t\tpositionX, positionY,\n\t\t\t\tCONTROLLER.radius - CONTROLLER.borderWidth\n\t\t\t);\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t\t\tthis.circuit.cursor = CURSORS.pointer;\n\t\t}\n\n\t\tif (isPlacing)\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t}\n\n\tdrawConnector(isPlacing: boolean) {\n\t\tif (isPlacing)\n\t\t\treturn; // Overlapping shapes with opacity look weird, so we hide the connector while placing\n\n\t\tconst rawPosition = this.getRawPosition();\n\t\tconst positionX = this.isInput ? rawPosition.x - CONTROLLER.pinOffset : rawPosition.x;\n\t\tconst positionY = rawPosition.y;\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n\t\tif (isPlacing)\n\t\t\tthis.circuit.setDrawingOpacity(CONTROLLER.placingOpacity);\n\n\t\tthis.circuit.drawRect(\n\t\t\tthis.circuit.getColor(COLORS.controller.connector),\n\t\t\tpositionX, positionY - CONTROLLER.connectorWidth / 2,\n\t\t\tCONTROLLER.pinOffset, CONTROLLER.connectorWidth\n\t\t);\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n\t\tif (isPlacing)\n\t\t\tthis.circuit.resetDrawingOpacity();\n\t}\n\n\tdraw(isPlacing: boolean) {\n\t\tif (!this.isInput) {\n\t\t\tthis.position.x = (this.circuit.size.x - (CONTROLLER.handleTrackWidth + CONTROLLER.pinOffset + CONTROLLER.radius)) / this.circuit.size.x;\n\t\t} else {\n\t\t\tthis.position.x = (CONTROLLER.handleTrackWidth + CONTROLLER.pinOffset + CONTROLLER.radius) / this.circuit.size.x;\n\t\t}\n\n\t\tthis.drawConnector(isPlacing);\n\t\tthis.drawController(isPlacing);\n\t\tthis.drawControllerHandle(isPlacing);\n\n\t\tsuper.draw(isPlacing);\n\t}\n}","import { Vector2 } from \"@prozilla-os/shared\";\nimport { Circuit } from \"../circuit\";\nimport { Pin } from \"../pins/pin\";\nimport { State } from \"../_utils/state\";\nimport { WIRE } from \"../../constants/logicSim.const\";\n\nexport interface WireJson {\n\tcolor: string;\n\tinputId?: number;\n\toutputId?: number;\n\tanchorPoints?: {\n\t\tx: number;\n\t\ty: number;\n\t}[];\n}\n\nexport class Wire {\n\tcolor!: string;\n\tstate = State.LOW;\n\tinputPin?: Pin;\n\toutputPin?: Pin;\n\tanchorPoints: Vector2[] = [];\n\tcircuit!: Circuit;\n\tplacedBackwards = false;\n\n\tconstructor(circuit: Circuit, color: string, inputPin?: Pin, outputPin?: Pin, anchorPoints: Vector2[] = []) {\n\t\tObject.assign(this, { circuit, color, inputPin, outputPin, anchorPoints });\n\t}\n\n\tsetState(state: State) {\n\t\tif (this.state.isEqual(state))\n\t\t\treturn;\n\n\t\tthis.state = state;\n\t\tthis.update();\n\t}\n\n\tupdate() {\n\t\tif (this.outputPin == null)\n\t\t\treturn;\n\n\t\tthis.outputPin.setState(this.state);\n\t}\n\n\tdraw(isPlacing: boolean) {\n\t\tconst positions = [...this.anchorPoints];\n\n\t\tif (this.inputPin != null) {\n\t\t\tif (!this.placedBackwards) {\n\t\t\t\tpositions.unshift(this.inputPin.position);\n\t\t\t} else {\n\t\t\t\tpositions.push(this.inputPin.position);\n\t\t\t}\n\t\t}\n\t\t\n\t\tif (this.outputPin != null) {\n\t\t\tif (!this.placedBackwards) {\n\t\t\t\tpositions.push(this.outputPin.position);\n\t\t\t} else {\n\t\t\t\tpositions.unshift(this.outputPin.position);\n\t\t\t}\n\t\t}\n\n\t\tlet color: string;\n\n\t\tif (isPlacing) {\n\t\t\tcolor = `${this.color}-2`;\n\t\t} else if (this.state.value === 1) {\n\t\t\tcolor = `${this.color}-0`;\n\t\t} else {\n\t\t\tcolor = `${this.color}-2`;\n\t\t}\n\n\t\tconst rawPositions = positions.map((position) => Vector2.product(position, this.circuit.size));\n\t\tthis.circuit.drawCurvedLine(this.circuit.getColor(color), rawPositions, WIRE.width, WIRE.cornerRadius, WIRE.resolution);\n\t}\n\n\ttoJson(): WireJson {\n\t\tconst object: WireJson = {\n\t\t\tcolor: this.color,\n\t\t};\n\n\t\tif (this.inputPin != null)\n\t\t\tobject.inputId = this.inputPin.id;\n\n\t\tif (this.outputPin != null)\n\t\t\tobject.outputId = this.outputPin.id;\n\n\t\tif (this.anchorPoints.length)\n\t\t\tobject.anchorPoints = this.anchorPoints;\n\n\t\treturn object;\n\t}\n}","import { Actions, ActionsProps, ClickAction } from \"@prozilla-os/core\";\nimport { Chip } from \"../../core/chips/chip\";\n\nexport interface ChipContextMenuProps extends ActionsProps {\n\tchip: Chip;\n}\n\nexport function ChipContextMenu({ chip, ...props }: ChipContextMenuProps) {\n\treturn <Actions {...props}>\n\t\t<ClickAction label=\"Delete\" onTrigger={() => {\n\t\t\tchip.delete();\n\t\t}}/>\n\t\t<ClickAction label=\"Duplicate\" onTrigger={() => {\n\t\t\tchip.circuit.inputHandler.startChipPlacement(chip);\n\t\t}}/>\n\t</Actions>;\n}","/* eslint-disable @typescript-eslint/no-unnecessary-condition */\nimport { Chip } from \"./chips/chip\";\nimport { Circuit } from \"./circuit\";\nimport { ControlledPin } from \"./pins/controlledPin\";\nimport { Pin } from \"./pins/pin\";\nimport { State } from \"./_utils/state\";\nimport { Wire } from \"./wires/wire\";\nimport { ActionsProps } from \"@prozilla-os/core\";\nimport { CONTROLLER, PIN, WIRE } from \"../constants/logicSim.const\";\nimport { ChipContextMenu } from \"../components/context-menu/ChipContextMenu\";\nimport { Vector2 } from \"@prozilla-os/shared\";\n\nexport class InputHandler {\n\tcircuit: Circuit;\n\tcanvas!: HTMLCanvasElement;\n\n\tmousePosition = Vector2.ZERO;\n\trawMousePosition = Vector2.ZERO;\n\n\tisPlacing = false;\n\tsnapping = false;\n\tplacingOffset = Vector2.ZERO;\n\tpreviousPlacement!: Vector2 | null;\n\tplacingWire!: Wire | null;\n\tplacingChip!: Chip | null;\n\tplacingPin!: ControlledPin | null;\n\n\tconstructor(circuit: Circuit) {\n\t\tthis.circuit = circuit;\n\t}\n\n\tsetMousePosition(event: MouseEvent) {\n\t\tconst rect = this.canvas.getBoundingClientRect();\n\t\tthis.rawMousePosition.x = event.clientX - rect.left;\n\t\tthis.rawMousePosition.y = event.clientY - rect.top;\n\t\tthis.mousePosition.x = this.rawMousePosition.x / this.circuit.size.x;\n\t\tthis.mousePosition.y = this.rawMousePosition.y / this.circuit.size.y;\n\t}\n\n\tinit() {\n\t\tthis.canvas = this.circuit.canvas;\n\t\tthis.mousePosition = Vector2.ZERO;\n\n\t\t// TO DO: add support for touch devices\n\n\t\tthis.canvas.addEventListener(\"mousemove\", this.onMouseMove);\n\t\tthis.canvas.addEventListener(\"mouseup\", this.onMouseUp);\n\t\tthis.canvas.addEventListener(\"contextmenu\", this.onMouseUp);\n\t\tthis.canvas.addEventListener(\"mousedown\", this.onMouseDown);\n\t\tthis.canvas.addEventListener(\"mouseleave\", this.onMouseLeave);\n\n\t\twindow.addEventListener(\"keydown\", this.onKeyDown);\n\t\twindow.addEventListener(\"keyup\", this.onKeyUp);\n\t}\n\n\tcleanup() {\n\t\tthis.canvas.removeEventListener(\"mousemove\", this.onMouseMove);\n\t\tthis.canvas.removeEventListener(\"mouseup\", this.onMouseUp);\n\t\tthis.canvas.removeEventListener(\"contextmenu\", this.onMouseUp);\n\t\tthis.canvas.removeEventListener(\"mousedown\", this.onMouseDown);\n\t\tthis.canvas.removeEventListener(\"mouseleave\", this.onMouseLeave);\n\n\t\twindow.removeEventListener(\"keydown\", this.onKeyDown);\n\t\twindow.removeEventListener(\"keyup\", this.onKeyUp);\n\t}\n\n\treset() {\n\t\tthis.placingWire = null;\n\t\tthis.placingChip = null;\n\t\tthis.placingPin = null;\n\t\tthis.previousPlacement = null;\n\t\tthis.placingOffset = Vector2.ZERO;\n\t\tthis.isPlacing = false;\n\t}\n\n\tonMouseMove = (event?: MouseEvent) => {\n\t\tif (event != null)\n\t\t\tthis.setMousePosition(event);\n\n\t\tif (this.placingWire != null) {\n\t\t\tthis.updateWirePlacement();\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.placingChip != null) {\n\t\t\tthis.updateChipPlacement();\n\t\t\treturn;\n\t\t}\n\n\t\tconst isHoveringPinHandle = (pin: ControlledPin) => {\n\t\t\tconst pinPositionY = pin.position.y * this.circuit.size.y;\n\t\t\tconst top = pinPositionY - CONTROLLER.handleHeight / 2;\n\t\t\tconst bottom = pinPositionY + CONTROLLER.handleHeight / 2;\n\n\t\t\treturn this.rawMousePosition.y > top && this.rawMousePosition.y < bottom;\n\t\t};\n\n\t\tif (this.placingPin != null) {\n\t\t\tlet invalidPlacement = this.rawMousePosition.x > CONTROLLER.handleTrackWidth && this.rawMousePosition.x < this.circuit.size.x - CONTROLLER.handleTrackWidth;\n\n\t\t\tif (invalidPlacement) {\n\t\t\t\tthis.cancelPinPlacement();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (this.placingPin.isInput) {\n\t\t\t\tthis.circuit.inputPins.forEach((pin, index) => {\n\t\t\t\t\tif (invalidPlacement || index == this.circuit.inputPins.length - 1)\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\tif (isHoveringPinHandle(pin))\n\t\t\t\t\t\tinvalidPlacement = true;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.circuit.outputPins.forEach((pin, index) => {\n\t\t\t\t\tif (invalidPlacement || index == this.circuit.outputPins.length - 1)\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\tif (isHoveringPinHandle(pin))\n\t\t\t\t\t\tinvalidPlacement = true;\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (invalidPlacement) {\n\t\t\t\tthis.cancelPinPlacement();\n\t\t\t} else {\n\t\t\t\tthis.updatePinPlacement();\n\t\t\t}\n\t\t} else {\n\t\t\tif (this.rawMousePosition.x < CONTROLLER.handleTrackWidth) {\n\t\t\t\tlet invalidPlacement = false;\n\n\t\t\t\tthis.circuit.inputPins.forEach((pin) => {\n\t\t\t\t\tif (invalidPlacement)\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\tif (isHoveringPinHandle(pin))\n\t\t\t\t\t\tinvalidPlacement = true;\n\t\t\t\t});\n\n\t\t\t\tif (!invalidPlacement)\n\t\t\t\t\tthis.startPinPlacement(true);\n\t\t\t} else if (this.rawMousePosition.x > this.circuit.size.x - CONTROLLER.handleTrackWidth) {\n\t\t\t\tlet invalidPlacement = false;\n\n\t\t\t\tthis.circuit.outputPins.forEach((pin) => {\n\t\t\t\t\tif (invalidPlacement)\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\tif (isHoveringPinHandle(pin))\n\t\t\t\t\t\tinvalidPlacement = true;\n\t\t\t\t});\n\n\t\t\t\tif (!invalidPlacement)\n\t\t\t\t\tthis.startPinPlacement(false);\n\t\t\t}\n\t\t}\n\t};\n\n\tonClickPin(pin: Pin) {\n\t\tif (this.placingWire != null) {\n\t\t\tthis.endWirePlacement(pin);\n\t\t} else {\n\t\t\tthis.startWirePlacement(pin);\n\t\t}\n\t}\n\n\topenContextMenu(event: MouseEvent, Actions: React.FC<ActionsProps>) {\n\t\tevent.stopPropagation();\n\t\tconst position = new Vector2(event.clientX, event.clientY);\n\t\tthis.circuit.openContextMenu?.(position, Actions);\n\t}\n\n\topenChipContextMenu(event: MouseEvent, chip: Chip) {\n\t\tthis.openContextMenu(event, (props) => ChipContextMenu({ chip, ...props }));\n\t}\n\n\tonMouseUp = (event: MouseEvent) => {\n\t\tevent.preventDefault();\n\t\tthis.setMousePosition(event);\n\n\t\tif (event.button === 2) {\n\t\t\tif (this.placingWire != null) {\n\t\t\t\tthis.cancelWirePlacement();\n\t\t\t} else if (this.placingChip != null) {\n\t\t\t\tthis.cancelChipPlacement();\n\t\t\t} else {\n\t\t\t\tlet eventComplete = false;\n\n\t\t\t\tthis.circuit.chips.forEach((chip) => {\n\t\t\t\t\tif (this.circuit.isPointInsideRect(chip.getBounds(), this.rawMousePosition)) {\n\t\t\t\t\t\tthis.openChipContextMenu(event, chip);\n\t\t\t\t\t\teventComplete = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tif (eventComplete)\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t} else if (event.button === 0) {\n\t\t\tlet eventComplete = false;\n\n\t\t\tthis.circuit.inputPins.forEach((pin: Pin) => {\n\t\t\t\tconst rawPinPosition = pin.getRawPosition();\n\t\t\t\tif (this.rawMousePosition.getDistance(rawPinPosition.x - CONTROLLER.pinOffset, rawPinPosition.y) <= CONTROLLER.radius) {\n\t\t\t\t\tpin.setState(State.invert(pin.state));\n\t\t\t\t\teventComplete = true;\n\t\t\t\t} else if (this.rawMousePosition.getDistance(rawPinPosition) <= PIN.radius) {\n\t\t\t\t\tthis.onClickPin(pin);\n\t\t\t\t\teventComplete = true;\n\t\t\t\t}\n\t\t\t});\n\t\n\t\t\tif (eventComplete)\n\t\t\t\treturn;\n\t\n\t\t\tthis.circuit.outputPins.forEach((pin: Pin) => {\n\t\t\t\tif (this.rawMousePosition.getDistance(pin.getRawPosition()) <= PIN.radius) {\n\t\t\t\t\tthis.onClickPin(pin);\n\t\t\t\t\teventComplete = true;\n\t\t\t\t}\n\t\t\t});\n\t\n\t\t\tif (eventComplete)\n\t\t\t\treturn;\n\n\t\t\tthis.circuit.chips.forEach((chip) => {\n\t\t\t\tchip.inputPins.concat(chip.outputPins).forEach((pin) => {\n\t\t\t\t\tif (this.rawMousePosition.getDistance(pin.getRawPosition()) <= PIN.radius) {\n\t\t\t\t\t\tthis.onClickPin(pin);\n\t\t\t\t\t\teventComplete = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tif (eventComplete)\n\t\t\t\treturn;\n\t\n\t\t\tif (this.placingWire != null)\n\t\t\t\tthis.anchorWirePlacement();\n\n\t\t\tif (this.placingChip != null)\n\t\t\t\tthis.endChipPlacement();\n\n\t\t\tif (this.placingPin != null)\n\t\t\t\tthis.endPinPlacement();\n\t\t}\n\t};\n\n\tonMouseDown = (event: MouseEvent) => {\n\t\tevent.preventDefault();\n\t\tthis.setMousePosition(event);\n\n\t\tif (event.button !== 0 || this.isPlacing)\n\t\t\treturn;\n\n\t\tthis.circuit.chips.forEach((chip, index) => {\n\t\t\tif (!this.isPlacing && this.circuit.isPointInsideRect(chip, this.mousePosition)) {\n\t\t\t\tlet hoveringPin = false;\n\n\t\t\t\tchip.inputPins.concat(chip.outputPins).forEach((pin) => {\n\t\t\t\t\tif (pin.position.getDistance(this.mousePosition.x, this.mousePosition.y) <= PIN.radius)\n\t\t\t\t\t\thoveringPin = true;\n\t\t\t\t});\n\n\t\t\t\tif (!hoveringPin)\n\t\t\t\t\tthis.editChipPlacement(chip, index);\n\t\t\t}\n\t\t});\n\t};\n\n\tonKeyDown = (event: KeyboardEvent) => {\n\t\tswitch (event.key) {\n\t\t\tcase \"Shift\":\n\t\t\t\tevent.preventDefault();\n\t\t\t\tthis.snapping = true;\n\t\t\t\tthis.onMouseMove();\n\t\t\t\tbreak;\n\t\t\tcase \"Backspace\":\n\t\t\tcase \"Delete\":\n\t\t\tcase \"Escape\":\n\t\t\t\tevent.preventDefault();\n\t\t\t\tif (this.placingWire != null)\n\t\t\t\t\tthis.cancelWirePlacement();\n\t\t\t\tif (this.placingChip != null)\n\t\t\t\t\tthis.cancelChipPlacement();\n\t\t\t\tbreak;\n\t\t}\n\t};\n\n\tonKeyUp = (event: KeyboardEvent) => {\n\t\tswitch (event.key) {\n\t\t\tcase \"Shift\":\n\t\t\t\tevent.preventDefault();\n\t\t\t\tthis.snapping = false;\n\t\t\t\tthis.onMouseMove();\n\t\t\t\tbreak;\n\t\t}\n\t};\n\n\tonMouseLeave = (_event: MouseEvent) => {\n\t\tthis.cancelPinPlacement();\n\t};\n\n\tstartWirePlacement(pin: Pin) {\n\t\tconst isInputPin = pin.isPointingRight;\n\n\t\t// Start wire placement\n\t\tconst inputPin = isInputPin ? pin : undefined;\n\t\tconst outputPin = !isInputPin ? pin : undefined;\n\t\tconst anchorPoint = this.mousePosition.clone;\n\n\t\tthis.placingWire = new Wire(this.circuit, \"red\", inputPin, outputPin, [anchorPoint]);\n\n\t\tif (!isInputPin)\n\t\t\tthis.placingWire.placedBackwards = true;\n\n\t\tthis.circuit.wires.push(this.placingWire);\n\t}\n\n\tsnapWireHorizontally(lastAnchorPoint: Vector2, previousAnchorPoint: Vector2) {\n\t\tlastAnchorPoint.x = this.mousePosition.x;\n\t\tlastAnchorPoint.y = previousAnchorPoint.y;\n\n\t\t// Snapping horizontal wire to other wires\n\t\tlet anchorPoints: Vector2[] = [];\n\n\t\tthis.circuit.wires.forEach((wire, index) => {\n\t\t\tif (index < this.circuit.wires.length - 1)\n\t\t\t\tanchorPoints = anchorPoints.concat(wire.anchorPoints);\n\t\t});\n\n\t\tlet closestPositionX: number | undefined;\n\t\tlet closestDistance: number | undefined;\n\n\t\tanchorPoints.forEach((point) => {\n\t\t\tconst distance = Math.abs(this.mousePosition.x - point.x) * this.circuit.size.x;\n\n\t\t\tif (closestDistance == null || closestDistance > distance) {\n\t\t\t\tclosestPositionX = point.x;\n\t\t\t\tclosestDistance = distance;\n\t\t\t}\n\t\t});\n\n\t\tif (closestDistance != null && closestPositionX != null && closestDistance < WIRE.snappingSensitivity)\n\t\t\tlastAnchorPoint.x = closestPositionX;\n\t}\n\n\tsnapWireVertically(lastAnchorPoint: Vector2, previousAnchorPoint: Vector2) {\n\t\tlastAnchorPoint.x = previousAnchorPoint.x;\n\t\tlastAnchorPoint.y = this.mousePosition.y;\n\n\t\t// Snapping vertical wire to pins\n\t\tlet pins: Pin[];\n\n\t\tif (!this.placingWire?.placedBackwards) {\n\t\t\tpins = this.circuit.outputPins;\n\n\t\t\tthis.circuit.chips.forEach((chip) => {\n\t\t\t\tpins = pins.concat(chip.inputPins);\n\t\t\t});\n\t\t} else {\n\t\t\tpins = this.circuit.inputPins;\n\n\t\t\tthis.circuit.chips.forEach((chip) => {\n\t\t\t\tpins = pins.concat(chip.outputPins);\n\t\t\t});\n\t\t}\n\n\t\tlet closestPositionY: number | undefined;\n\t\tlet closestDistance: number | undefined;\n\n\t\tpins.forEach((pin) => {\n\t\t\tconst distance = Math.abs(this.mousePosition.y - pin.position.y) * this.circuit.size.y;\n\n\t\t\tif (closestDistance == null || closestDistance > distance) {\n\t\t\t\tclosestPositionY = pin.position.y;\n\t\t\t\tclosestDistance = distance;\n\t\t\t}\n\t\t});\n\n\t\tif (closestDistance !== undefined && closestPositionY !== undefined && closestDistance < WIRE.snappingSensitivity)\n\t\t\tlastAnchorPoint.y = closestPositionY;\n\t}\n\n\tupdateWirePlacement() {\n\t\tconst anchorCount = this.placingWire?.anchorPoints.length;\n\t\tif (anchorCount == null) return;\n\t\tconst lastAnchorPoint = this.placingWire?.anchorPoints[anchorCount - 1];\n\t\tif (lastAnchorPoint == null) return;\n\n\t\tif (!this.snapping) {\n\t\t\tlastAnchorPoint.x = this.mousePosition.x;\n\t\t\tlastAnchorPoint.y = this.mousePosition.y;\n\t\t} else {\n\t\t\t// Wire snapping\n\t\t\tlet previousAnchorPoint: Vector2 | undefined;\n\n\t\t\tif (anchorCount >= 2) {\n\t\t\t\tpreviousAnchorPoint = this.placingWire?.anchorPoints[anchorCount - 2];\n\t\t\t} else if (!this.placingWire?.placedBackwards) {\n\t\t\t\tpreviousAnchorPoint = this.placingWire?.inputPin?.position;\n\t\t\t} else {\n\t\t\t\tpreviousAnchorPoint = this.placingWire?.outputPin?.position;\n\t\t\t}\n\n\t\t\tif (previousAnchorPoint == null) return;\n\t\n\t\t\tconst deltaX = Math.abs(this.mousePosition.x - previousAnchorPoint.x) * this.circuit.size.x;\n\t\t\tconst deltaY = Math.abs(this.mousePosition.y - previousAnchorPoint.y) * this.circuit.size.y;\n\t\n\t\t\tif (deltaX > deltaY) {\n\t\t\t\tthis.snapWireHorizontally(lastAnchorPoint, previousAnchorPoint);\n\t\t\t} else {\n\t\t\t\tthis.snapWireVertically(lastAnchorPoint, previousAnchorPoint);\n\t\t\t}\n\t\t}\n\t}\n\n\tanchorWirePlacement() {\n\t\tthis.placingWire?.anchorPoints.push(this.mousePosition.clone);\n\t}\n\n\tcancelWirePlacement() {\n\t\tthis.placingWire = null;\n\t\tthis.isPlacing = false;\n\t\tthis.circuit.wires.pop();\n\t}\n\n\tendWirePlacement(pin: Pin) {\n\t\tconst isInputPin = pin.isPointingRight;\n\n\t\tif (this.placingWire == null) return;\n\n\t\tlet correctPlacement = false;\n\t\tif (!isInputPin && !this.placingWire.placedBackwards) {\n\t\t\tthis.placingWire.outputPin = pin;\n\t\t\tcorrectPlacement = true;\n\t\t} else if (isInputPin && this.placingWire.placedBackwards) {\n\t\t\tthis.placingWire.inputPin = pin;\n\t\t\tcorrectPlacement = true;\n\t\t}\n\n\t\tif (correctPlacement) {\n\t\t\tthis.placingWire.anchorPoints.pop();\n\t\t\tthis.placingWire.inputPin?.addOutputWire(this.placingWire);\n\t\t\tthis.placingWire.inputPin?.update();\n\n\t\t\tthis.placingWire = null;\n\t\t\tthis.isPlacing = false;\n\t\t}\n\t}\n\n\tstartChipPlacement(chip: Chip) {\n\t\tconst newChip = new Chip(this.circuit, chip.name, chip.color, false, chip.inputCount, chip.outputCount);\n\t\tnewChip.setLogic(chip.logic);\n\t\tnewChip.position = new Vector2(\n\t\t\tthis.mousePosition.x - newChip.size.x / 2 / this.circuit.size.x,\n\t\t\tthis.mousePosition.y - newChip.size.y / 2 / this.circuit.size.y\n\t\t);\n\n\t\tthis.placingChip = newChip;\n\t\tthis.isPlacing = true;\n\t\tthis.circuit.chips.push(newChip);\n\t}\n\n\teditChipPlacement(chip: Chip, index: number) {\n\t\tthis.placingOffset = new Vector2(\n\t\t\tchip.position.x + chip.size.x / 2 / this.circuit.size.x - this.mousePosition.x,\n\t\t\tchip.position.y + chip.size.y / 2 / this.circuit.size.y - this.mousePosition.y\n\t\t);\n\t\tthis.previousPlacement = chip.position.clone;\n\t\tthis.circuit.chips.push(this.circuit.chips.splice(index, 1)[0]);\n\n\t\tthis.placingChip = chip;\n\t\tthis.isPlacing = true;\n\t}\n\n\tupdateChipPlacement() {\n\t\tif (this.placingChip == null) return;\n\t\tthis.placingChip.position.x = this.mousePosition.x - this.placingChip.size.x / 2 / this.circuit.size.x + this.placingOffset.x;\n\t\tthis.placingChip.position.y = this.mousePosition.y - this.placingChip.size.y / 2 / this.circuit.size.y + this.placingOffset.y;\n\t}\n\n\tcancelChipPlacement() {\n\t\tif (this.placingChip == null) return;\n\n\t\tif (this.previousPlacement != null) {\n\t\t\tthis.placingChip.position = this.previousPlacement;\n\t\t\tthis.previousPlacement = null;\n\t\t} else {\n\t\t\tthis.circuit.chips.pop();\n\t\t}\n\n\t\tthis.placingChip = null;\n\t\tthis.isPlacing = false;\n\t}\n\n\tendChipPlacement() {\n\t\tthis.placingChip = null;\n\t\tthis.isPlacing = false;\n\t\tthis.placingOffset = Vector2.ZERO;\n\t}\n\n\tstartPinPlacement(isInput: boolean) {\n\t\tconst newPin = new ControlledPin(this.circuit, \"PIN\", isInput);\n\n\t\tnewPin.position.x = (CONTROLLER.handleTrackWidth + CONTROLLER.pinOffset + CONTROLLER.radius) / this.circuit.size.x;\n\t\tnewPin.position.y = this.mousePosition.y;\n\n\t\tif (isInput) {\n\t\t\tthis.circuit.inputPins.push(newPin);\n\t\t} else {\n\t\t\tnewPin.position.x = 1 - newPin.position.x;\n\t\t\tthis.circuit.outputPins.push(newPin);\n\t\t}\n\n\t\tthis.placingPin = newPin;\n\t}\n\n\tupdatePinPlacement() {\n\t\tif (this.placingPin != null)\n\t\t\tthis.placingPin.position.y = this.mousePosition.y;\n\t}\n\n\tcancelPinPlacement() {\n\t\tif (this.placingPin == null) return;\n\n\t\tif (this.placingPin?.isInput) {\n\t\t\tthis.circuit.inputPins.pop();\n\t\t} else {\n\t\t\tthis.circuit.outputPins.pop();\n\t\t}\n\n\t\tthis.placingPin = null;\n\t}\n\n\tendPinPlacement() {\n\t\tthis.placingPin = null;\n\t}\n\n\tisPlacingPin(pin: Pin, index: number) {\n\t\tif (!pin.isControlled || this.placingPin == null || this.placingPin.isInput != pin.isInput)\n\t\t\treturn false;\n\n\t\tif (pin.isInput) {\n\t\t\treturn index == this.circuit.inputPins.length - 1;\n\t\t} else {\n\t\t\treturn index == this.circuit.outputPins.length - 1;\n\t\t}\n\t}\n}","import { ActionsProps, Modal } from \"@prozilla-os/core\";\nimport { Chip, ChipJson } from \"./chips/chip\";\nimport { ControlledPin } from \"./pins/controlledPin\";\nimport { InputHandler } from \"./inputHandler\";\nimport { Wire, WireJson } from \"./wires/wire\";\nimport { BACKGROUND, COLORS, CONTROLLER, CURSORS, ENABLE_COLOR_CACHING, FONT } from \"../constants/logicSim.const\";\nimport { clamp, Vector2 } from \"@prozilla-os/shared\";\n\nexport interface CircuitJson extends ChipJson {\n\twires?: WireJson[];\n\tchips?: ChipJson[];\n}\n\nexport class Circuit extends Chip {\n\tcanvas!: HTMLCanvasElement;\n\tsize = Vector2.ZERO;\n\tcontext!: CanvasRenderingContext2D;\n\tcolors: { [key: string]: string } = {};\n\tinputHandler: InputHandler;\n\topenContextMenu?: (position: Vector2, Actions: React.FC<ActionsProps>, params?: object) => Modal;\n\n\tinputPins: ControlledPin[] = [];\n\toutputPins: ControlledPin[] = [];\n\n\twires: Wire[] = [];\n\tchips: Chip[] = [];\n\n\tcursor = CURSORS.default;\n\n\tlastId = 0;\n\n\tconstructor(name: string, color: string, inputCount: number, outputCount: number) {\n\t\tsuper(null, name, color, false, inputCount, outputCount);\n\t\tthis.inputHandler = new InputHandler(this);\n\t}\n\n\tresize() {\n\t\tthis.size.x = this.canvas.clientWidth;\n\t\tthis.size.y = this.canvas.clientHeight;\n\t}\n\n\tinit(canvas: HTMLCanvasElement) {\n\t\tthis.canvas = canvas;\n\t\tthis.context = this.canvas.getContext(\"2d\") as CanvasRenderingContext2D;\n\t\tthis.resize();\n\n\t\t// Detect size changes of canvas\n\t\tconst observer = new ResizeObserver((entries) => {\n\t\t\tentries.forEach(({ target }) => {\n\t\t\t\tif (target === this.canvas && (target.clientWidth != this.size.x || target.clientHeight != this.size.y)) {\n\t\t\t\t\tthis.resize();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tobserver.observe(this.canvas);\n\n\t\tthis.inputHandler.init();\n\n\t\tthis.render();\n\t}\n\n\tcleanup() {\n\t\tthis.inputHandler.cleanup();\n\t}\n\n\treset() {\n\t\tthis.inputPins = [];\n\t\tthis.outputPins = [];\n\t\tthis.wires = [];\n\t\tthis.chips = [];\n\n\t\tthis.inputHandler.reset();\n\t}\n\n\tgetColor(key: string) {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n\t\tif (this.colors[key] != null)\n\t\t\treturn this.colors[key];\n\n\t\tconst color = getComputedStyle(this.canvas).getPropertyValue(\"--\" + key);\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n\t\tif (ENABLE_COLOR_CACHING)\n\t\t\tthis.colors[key] = color;\n\n\t\treturn color;\n\t}\n\n\tisPointInsideRect(rect: { position: Vector2, size: Vector2 }, point: Vector2) {\n\t\treturn point.x > rect.position.x && point.y > rect.position.y\n\t\t\t&& point.x < rect.position.x + rect.size.x && point.y < rect.position.y + rect.size.y;\n\t}\n\n\tgetUniqueId() {\n\t\treturn this.lastId++;\n\t}\n\n\tgetTextRect(size: number, content: string) {\n\t\tthis.context.textBaseline = \"middle\";\n\t\tthis.context.font = `bold ${size}px ${FONT}`;\n\t\tconst metrics = this.context.measureText(content);\n\n\t\tconst width = metrics.actualBoundingBoxRight + metrics.actualBoundingBoxLeft;\n\t\tconst height = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;\n\n\t\treturn { x: width, y: height };\n\t}\n\n\tdrawRect(style: string, positionX: number, positionY: number, sizeX: number, sizeY: number) {\n\t\tthis.context.fillStyle = style;\n\t\tthis.context.fillRect(positionX, positionY, sizeX, sizeY);\n\t}\n\n\tdrawCircle(style: string, positionX: number, positionY: number, radius: number) {\n\t\tthis.context.beginPath();\n\t\tthis.context.arc(positionX, positionY, radius, 0, 2 * Math.PI);\n\n\t\tthis.context.fillStyle = style;\n\t\tthis.context.fill();\n\t}\n\n\tdrawCurvedLine(style: string, positions: Vector2[], width: number, radius: number, resolution: number) {\n\t\tif (positions.length < 2)\n\t\t\treturn;\n\n\t\tthis.context.lineWidth = width;\n\t\tthis.context.lineJoin = \"round\";\n\t\tthis.context.lineCap = \"round\";\n\n\t\t/**\n\t\t * Based on https://github.com/SebLague/Digital-Logic-Sim/blob/main/Assets/Modules/Chip%20Creation/Scripts/Chip/Wires/WireRenderer.cs\n\t\t * TO DO: optimize.\n\t\t */\n\n\t\tconst drawPoints: Vector2[] = [];\n\t\tdrawPoints.push(positions[0]);\n\n\t\tfor (let i = 1; i < positions.length - 1; i++) {\n\t\t\tconst targetPoint = positions[i];\n\t\t\tconst targetDir = Vector2.normalize(Vector2.difference(positions[i], positions[i - 1]));\n\t\t\tconst distanceToTarget = Vector2.difference(positions[i], positions[i - 1]).magnitude;\n\t\t\tconst distanceToCurveStart = Math.max(distanceToTarget - radius, distanceToTarget / 2);\n\n\t\t\tconst nextTargetDir = Vector2.normalize(Vector2.difference(positions[i + 1], positions[i]));\n\t\t\tconst nextLineLength = Vector2.difference(positions[i + 1], positions[i]).magnitude;\n\n\t\t\tconst curveStartPoint = Vector2.sum(positions[i - 1], Vector2.scale(targetDir, distanceToCurveStart));\n\t\t\tconst curveEndPoint = Vector2.sum(targetPoint, Vector2.scale(nextTargetDir, Math.min(radius, nextLineLength / 2)));\n\n\t\t\t// Bezier\n\t\t\tfor (let j = 0; j < resolution; j++) {\n\t\t\t\tconst t = j / (resolution - 1);\n\t\t\t\tconst a = Vector2.lerp(curveStartPoint, targetPoint, t);\n\t\t\t\tconst b = Vector2.lerp(targetPoint, curveEndPoint, t);\n\t\t\t\tconst p = Vector2.lerp(a, b, t);\n\n\t\t\t\tif (p.getDistanceSquared(drawPoints[drawPoints.length - 1]) > 0.001) {\n\t\t\t\t\tdrawPoints.push(p);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdrawPoints.push(positions[positions.length - 1]);\n\n\t\tthis.context.beginPath();\n\t\tthis.context.moveTo(drawPoints[0].x, drawPoints[0].y);\n\n\t\tfor (let i = 1; i < drawPoints.length; i++) {\n\t\t\tthis.context.lineTo(drawPoints[i].x, drawPoints[i].y);\n\t\t}\n\n\t\tthis.context.strokeStyle = style;\n\t\tthis.context.stroke();\n\t}\n\n\tdrawText(style: string, align: CanvasTextAlign, positionX: number, positionY: number, size: number, content: string) {\n\t\tthis.context.fillStyle = style;\n\t\tthis.context.textAlign = align;\n\t\tthis.context.textBaseline = \"middle\";\n\t\tthis.context.font = `bold ${size}px ${FONT}`;\n\t\tthis.context.fillText(content, positionX, positionY);\n\t}\n\n\tsetDrawingOpacity(alpha: number) {\n\t\tthis.context.globalAlpha = clamp(alpha, 0, 1);\n\t}\n\n\tresetDrawingOpacity() {\n\t\tthis.setDrawingOpacity(1);\n\t}\n\n\tdrawBackground() {\n\t\tconst margin = CONTROLLER.handleTrackWidth;\n\t\tconst padding = BACKGROUND.padding;\n\n\t\tthis.drawRect(this.getColor(COLORS.background.margin), 0, 0, this.size.x, this.size.y);\n\n\t\tlet offset = 0;\n\n\t\tthis.drawRect(\n\t\t\tthis.getColor(COLORS.background.outer),\n\t\t\toffset + margin, offset,\n\t\t\tthis.size.x - margin * 2, this.size.y\n\t\t);\n\n\t\toffset = padding - BACKGROUND.borderWidth;\n\t\tthis.drawRect(\n\t\t\tthis.getColor(COLORS.background.border),\n\t\t\toffset + margin, offset,\n\t\t\tthis.size.x - offset * 2 - margin * 2, this.size.y - offset * 2\n\t\t);\n\n\t\toffset = padding;\n\t\tthis.drawRect(\n\t\t\tthis.getColor(COLORS.background.inner),\n\t\t\toffset + margin, offset,\n\t\t\tthis.size.x - offset * 2 - margin * 2, this.size.y - offset * 2\n\t\t);\n\t}\n\n\tdrawWires() {\n\t\tthis.wires.forEach((wire, index) => {\n\t\t\tconst isPlacingWire = this.inputHandler.placingWire != null && index == this.wires.length - 1;\n\t\t\twire.draw(isPlacingWire);\n\t\t});\n\t}\n\n\tdrawChips() {\n\t\tthis.chips.forEach((chip, index) => {\n\t\t\tconst isPlacingChip = this.inputHandler.placingChip != null && index == this.chips.length - 1;\n\t\t\tchip.draw(isPlacingChip);\n\t\t});\n\t}\n\n\tdraw() {\n\t\tthis.drawBackground();\n\t\tthis.drawWires();\n\t\tthis.drawChips();\n\t\tsuper.drawPins(false);\n\t}\n\n\trender() {\n\t\tif (this.canvas.width != this.size.x)\n\t\t\tthis.canvas.width = this.size.x;\n\t\tif (this.canvas.height != this.size.y)\n\t\t\tthis.canvas.height = this.size.y;\n\n\t\tthis.cursor = CURSORS.default;\n\n\t\tthis.draw();\n\n\t\tif (this.inputHandler.isPlacing) {\n\t\t\tthis.canvas.style.cursor = CURSORS.default;\n\t\t} else {\n\t\t\tthis.canvas.style.cursor = this.cursor;\n\t\t}\n\n\t\twindow.requestAnimationFrame(() => {\n\t\t\tthis.render();\n\t\t});\n\t}\n\n\ttoJson(): CircuitJson {\n\t\tconst object: CircuitJson = super.toJson();\n\n\t\tif (this.wires.length > 0)\n\t\t\tobject.wires = this.wires.map((wire) => wire.toJson());\n\n\t\tif (this.chips.length > 0)\n\t\t\tobject.chips = this.chips.map((chip) => chip.toJson());\n\n\t\treturn object;\n\t}\n\n\ttoString(): string {\n\t\tconst json = this.toJson();\n\t\treturn JSON.stringify(json);\n\t}\n}","import { Chip } from \"./chip\";\nimport { State } from \"../_utils/state\";\nimport { Circuit, CircuitJson } from \"../circuit\";\nimport { ControlledPin } from \"../pins/controlledPin\";\nimport { Pin } from \"../pins/pin\";\nimport { Wire } from \"../wires/wire\";\nimport { VirtualFolder } from \"@prozilla-os/core\";\nimport { Vector2 } from \"@prozilla-os/shared\";\n\nexport class ChipsManager {\n\tstatic CHIPS: Record<string, Chip> = {\n\t\tand: new Chip(null, \"AND\", \"blue\", true, 2, 1).setLogic((inputStates: State[]) => {\n\t\t\tif (inputStates[0].isHigh() && inputStates[1].isHigh()) {\n\t\t\t\treturn [State.HIGH];\n\t\t\t} else {\n\t\t\t\treturn [State.LOW];\n\t\t\t}\n\t\t}),\n\t\tnot: new Chip(null, \"NOT\", \"red\", true, 1, 1).setLogic((inputStates: State[]) => {\n\t\t\treturn [State.invert(inputStates[0])];\n\t\t}),\n\t\tor: new Chip(null, \"OR\", \"yellow\", true, 2, 1).setLogic((inputStates: State[]) => {\n\t\t\tif (inputStates[0].isHigh() || inputStates[1].isHigh()) {\n\t\t\t\treturn [State.HIGH];\n\t\t\t} else {\n\t\t\t\treturn [State.LOW];\n\t\t\t}\n\t\t}),\n\t\thigh: new Chip(null, \"HIGH\", \"green\", true, 0, 1).setLogic((_inputStates: State[]) => {\n\t\t\treturn [State.HIGH];\n\t\t}),\n\t\tlow: new Chip(null, \"LOW\", \"purple\", true, 0, 1).setLogic((_inputStates: State[]) => {\n\t\t\treturn [State.LOW];\n\t\t}),\n\t};\n\n\tstatic saveCircuit(circuit: Circuit, virtualFolder: VirtualFolder) {\n\t\tvirtualFolder.createFile(circuit.name, \"json\", (file) => {\n\t\t\tfile.setContent(circuit.toString());\n\t\t});\n\t}\n\n\tstatic loadCircuit(circuit: Circuit, virtualFolder: VirtualFolder) {\n\t\tcircuit.reset();\n\t\tconst virtualFile = virtualFolder.findFile(circuit.name, \"json\");\n\n\t\tif (virtualFile == null)\n\t\t\treturn;\n\n\t\tvirtualFile.read().then((content) => {\n\t\t\tif (!content)\n\t\t\t\treturn;\n\n\t\t\tconst data = JSON.parse(content) as CircuitJson;\n\n\t\t\tcircuit.color = data.color;\n\t\t\tcircuit.name = data.name;\n\n\t\t\tconst pins: Record<number, Pin> = {};\n\n\t\t\t// Load input pins\n\t\t\tcircuit.inputCount = data.inputPins?.length ?? 0;\n\t\t\tdata.inputPins?.forEach((pinData) => {\n\t\t\t\tconst newPin = new ControlledPin(circuit, pinData.name, true, pinData.id);\n\t\t\t\tnewPin.position = new Vector2(pinData.position.x, pinData.position.y);\n\n\t\t\t\tcircuit.inputPins.push(newPin);\n\t\t\t\tpins[pinData.id] = newPin;\n\t\t\t});\n\n\t\t\t// Load output pins\n\t\t\tcircuit.outputCount = data.outputPins?.length ?? 0;\n\t\t\tdata.outputPins?.forEach((pinData) => {\n\t\t\t\tconst newPin = new ControlledPin(circuit, pinData.name, false, pinData.id);\n\t\t\t\tnewPin.position = new Vector2(pinData.position.x, pinData.position.y);\n\n\t\t\t\tcircuit.outputPins.push(newPin);\n\t\t\t\tpins[pinData.id] = newPin;\n\t\t\t});\n\n\t\t\t// Load chips\n\t\t\tdata.chips?.forEach((chipData) => {\n\t\t\t\tconst newChip = new Chip(circuit, chipData.name, chipData.color, false, 0, 0);\n\t\t\t\tnewChip.position = new Vector2(chipData.position.x, chipData.position.y);\n\n\t\t\t\t// Load input pins\n\t\t\t\tnewChip.inputCount = chipData.inputPins?.length ?? 0;\n\t\t\t\tchipData.inputPins?.forEach((pinData) => {\n\t\t\t\t\tconst newPin = new Pin(circuit, pinData.name, true, newChip, pinData.id);\n\t\t\t\t\tnewChip.inputPins.push(newPin);\n\t\t\t\t\tpins[pinData.id] = newPin;\n\t\t\t\t});\n\n\t\t\t\t// Load output pins\n\t\t\t\tnewChip.outputCount = chipData.outputPins?.length ?? 0;\n\t\t\t\tchipData.outputPins?.forEach((pinData) => {\n\t\t\t\t\tconst newPin = new Pin(circuit, pinData.name, false, newChip, pinData.id);\n\t\t\t\t\tnewChip.outputPins.push(newPin);\n\t\t\t\t\tpins[pinData.id] = newPin;\n\t\t\t\t});\n\n\t\t\t\t// Load logic\n\t\t\t\tnewChip.setLogic(ChipsManager.CHIPS[chipData.name].logic);\n\t\t\t\tnewChip.update();\n\n\t\t\t\tcircuit.chips.push(newChip);\n\t\t\t});\n\n\t\t\t// Load wires\n\t\t\tdata.wires?.forEach((wireData) => {\n\t\t\t\tconst inputPin = wireData.inputId ? pins[wireData.inputId] : undefined;\n\t\t\t\tconst outputPin = wireData.outputId ? pins[wireData.outputId] : undefined;\n\t\t\t\tconst anchorPoints = wireData.anchorPoints?.map(({ x, y }) => new Vector2(x, y));\n\n\t\t\t\tconst newWire = new Wire(circuit, wireData.color, inputPin, outputPin, anchorPoints);\n\t\t\t\tinputPin?.addOutputWire(newWire);\n\t\t\t\tcircuit.wires.push(newWire);\n\t\t\t});\n\t\t}).catch((error) => {\n\t\t\tconsole.error(error);\n\t\t});\n\t}\n}","import { useEffect, useRef } from \"react\";\nimport styles from \"./CircuitView.module.css\";\nimport { App, ClickAction, Divider, DropdownAction, HeaderMenu, openUrl, useAppFolder, useManualContextMenu, useSingleton } from \"@prozilla-os/core\";\nimport { Circuit } from \"../core/circuit\";\nimport { ChipsManager } from \"../core/chips/chipsManager\";\n\ninterface CircuitViewProps {\n\tapp?: App;\n}\n\nexport function CircuitView({ app }: CircuitViewProps) {\n\tconst virtualFolder = useAppFolder(app);\n\tconst circuit = useSingleton(() => new Circuit(\"Chip\", \"#000\", 2, 1));\n\tconst canvasRef = useRef<HTMLCanvasElement | null>(null);\n\tconst { openContextMenu } = useManualContextMenu();\n\tcircuit.openContextMenu = openContextMenu;\n\n\tuseEffect(() => {\n\t\tif (canvasRef.current == null)\n\t\t\treturn;\n\n\t\tcircuit.init(canvasRef.current);\n\n\t\treturn () => {\n\t\t\tcircuit.cleanup();\n\t\t};\n\t}, [canvasRef, circuit]);\n\n\treturn <>\n\t\t<HeaderMenu>\n\t\t\t<DropdownAction label=\"Circuit\" showOnHover={false}>\n\t\t\t\t<ClickAction label=\"New\" onTrigger={() => { circuit.reset(); }}/>\n\t\t\t\t<ClickAction label=\"Save\" onTrigger={() => {\n\t\t\t\t\tif (virtualFolder != null)\n\t\t\t\t\t\tChipsManager.saveCircuit(circuit, virtualFolder);\n\t\t\t\t}}/>\n\t\t\t\t<ClickAction label=\"Load\" onTrigger={() => {\n\t\t\t\t\tif (virtualFolder != null)\n\t\t\t\t\t\tChipsManager.loadCircuit(circuit, virtualFolder);\n\t\t\t\t}}/>\n\t\t\t</DropdownAction>\n\t\t\t<DropdownAction label=\"Add\" showOnHover={false}>\n\t\t\t\t<ClickAction label=\"AND gate\" onTrigger={() => {\n\t\t\t\t\tcircuit.inputHandler.startChipPlacement(ChipsManager.CHIPS.and);\n\t\t\t\t}}/>\n\t\t\t\t<ClickAction label=\"NOT gate\" onTrigger={() => {\n\t\t\t\t\tcircuit.inputHandler.startChipPlacement(ChipsManager.CHIPS.not);\n\t\t\t\t}}/>\n\t\t\t\t<Divider/>\n\t\t\t\t<ClickAction label=\"OR gate\" onTrigger={() => {\n\t\t\t\t\tcircuit.inputHandler.startChipPlacement(ChipsManager.CHIPS.or);\n\t\t\t\t}}/>\n\t\t\t\t<Divider/>\n\t\t\t\t<ClickAction label=\"HIGH\" onTrigger={() => {\n\t\t\t\t\tcircuit.inputHandler.startChipPlacement(ChipsManager.CHIPS.high);\n\t\t\t\t}}/>\n\t\t\t\t<ClickAction label=\"LOW\" onTrigger={() => {\n\t\t\t\t\tcircuit.inputHandler.startChipPlacement(ChipsManager.CHIPS.low);\n\t\t\t\t}}/>\n\t\t\t</DropdownAction>\n\t\t\t<DropdownAction label=\"Help\" showOnHover={false}>\n\t\t\t\t<ClickAction label=\"Digital Electronics Glossary\" onTrigger={() => {\n\t\t\t\t\topenUrl(\"http://www.pmcgibbon.net/teachcte/electron/degloss1.htm\");\n\t\t\t\t}}/>\n\t\t\t</DropdownAction>\n\t\t</HeaderMenu>\n\t\t<div className={styles.CircuitView}>\n\t\t\t<canvas ref={canvasRef} className={styles.Canvas}/>\n\t\t</div>\n\t</>;\n}","import { WindowProps } from \"@prozilla-os/core\";\nimport { CircuitView } from \"./CircuitView\";\nimport styles from \"./LogicSim.module.css\";\n\nexport function LogicSim({ app }: WindowProps) {\n\treturn <div className={styles.LogicSim}>\n\t\t<CircuitView app={app}/>\n\t</div>;\n}","import { App } from \"@prozilla-os/core\";\nimport { LogicSim } from \"./components/LogicSim\";\n\nconst logicSim = new App(\"Logic Sim\", \"logic-sim\", LogicSim)\n\t.setIconUrl(\"https://os.prozilla.dev/assets/apps/icons/logic-sim.svg\")\n\t.setPinnedByDefault(false)\n\t.setCategory(\"Education\");\n\nexport { logicSim };"],"names":["State","value","state","CURSORS","FONT","BACKGROUND","CONTROLLER","WIRE","PIN","CHIP","COLORS","Pin","Vector2","circuit","name","isInput","attachedChip","id","wire","isPlacing","color","positionX","positionY","offsetPositionX","leftAligned","textRect","backgroundSize","Chip","isBlueprint","inputCount","outputCount","Circuit","width","minHeight","i","newPin","pin","logic","inputStates","outputStates","reposition","index","gap","isPlacingPin","position","size","removeFromArray","object","ControlledPin","rawPosition","rect","Wire","inputPin","outputPin","anchorPoints","positions","rawPositions","ChipContextMenu","chip","props","jsxs","Actions","jsx","ClickAction","InputHandler","event","isHoveringPinHandle","pinPositionY","top","bottom","invalidPlacement","eventComplete","rawPinPosition","hoveringPin","_event","isInputPin","anchorPoint","lastAnchorPoint","previousAnchorPoint","closestPositionX","closestDistance","point","distance","pins","closestPositionY","anchorCount","deltaX","deltaY","correctPlacement","newChip","canvas","entries","target","key","content","metrics","height","style","sizeX","sizeY","radius","resolution","drawPoints","targetPoint","targetDir","distanceToTarget","distanceToCurveStart","nextTargetDir","nextLineLength","curveStartPoint","curveEndPoint","j","t","a","b","p","align","alpha","clamp","margin","padding","offset","isPlacingWire","isPlacingChip","json","ChipsManager","_inputStates","virtualFolder","file","virtualFile","data","pinData","chipData","wireData","x","y","newWire","error","CircuitView","app","useAppFolder","useSingleton","canvasRef","useRef","openContextMenu","useManualContextMenu","useEffect","Fragment","HeaderMenu","DropdownAction","Divider","openUrl","styles","LogicSim","logicSim","App"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prozilla-os/logic-sim",
|
|
3
3
|
"description": "A ProzillaOS application for simulating digital logic.",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.21",
|
|
5
5
|
"homepage": "https://os.prozilla.dev/logic-sim",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Prozilla",
|
|
@@ -20,18 +20,18 @@
|
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"react": "^18.3.1",
|
|
23
|
-
"@prozilla-os/
|
|
24
|
-
"@prozilla-os/
|
|
23
|
+
"@prozilla-os/core": "2.0.1",
|
|
24
|
+
"@prozilla-os/shared": "1.3.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/node": "^20.14.5",
|
|
28
|
-
"@types/react": "^18.3.
|
|
28
|
+
"@types/react": "^18.3.27",
|
|
29
29
|
"@vitejs/plugin-react-swc": "^3.7.0",
|
|
30
30
|
"typescript": "^5.5.4",
|
|
31
|
-
"vite": "^
|
|
32
|
-
"vite-plugin-dts": "^
|
|
31
|
+
"vite": "^7.3.1",
|
|
32
|
+
"vite-plugin-dts": "^4.5.4",
|
|
33
33
|
"vite-plugin-lib-inject-css": "^2.1.1",
|
|
34
|
-
"@prozilla-os/dev-tools": "1.1.
|
|
34
|
+
"@prozilla-os/dev-tools": "1.1.13"
|
|
35
35
|
},
|
|
36
36
|
"files": [
|
|
37
37
|
"dist"
|