From 1d5f03b5f94ecbcc9ca5b5dcf19efea7511004f7 Mon Sep 17 00:00:00 2001 From: Iftach Yakar Date: Wed, 8 Apr 2026 18:48:59 +0300 Subject: [PATCH 1/9] Added Zoom+pan for qubit grid (left view) + Added vertical scroll for timeline (right) view + changed some "magic numbers" to consts (QUBIT_HIGHLIGHT_SIZE, MAX_QUBIT_COORDINATE) --- glue/crumble/draw/config.js | 7 +- glue/crumble/draw/main_draw.js | 27 +++++-- glue/crumble/draw/state_snapshot.js | 14 +++- glue/crumble/draw/timeline_viewer.js | 33 +++++++-- glue/crumble/editor/editor_state.js | 18 ++--- glue/crumble/main.js | 105 ++++++++++++++++++++++++--- 6 files changed, 167 insertions(+), 37 deletions(-) diff --git a/glue/crumble/draw/config.js b/glue/crumble/draw/config.js index 25c6c739b..2ee965e8d 100644 --- a/glue/crumble/draw/config.js +++ b/glue/crumble/draw/config.js @@ -3,4 +3,9 @@ const rad = 10; const OFFSET_X = -pitch + Math.floor(pitch / 4) + 0.5; const OFFSET_Y = -pitch + Math.floor(pitch / 4) + 0.5; -export {pitch, rad, OFFSET_X, OFFSET_Y}; +const MIN_ZOOM = 0.25; +const MAX_ZOOM = 4; + +const MAX_QUBIT_COORDINATE = 100; + +export {pitch, rad, OFFSET_X, OFFSET_Y, MIN_ZOOM, MAX_ZOOM, MAX_QUBIT_COORDINATE}; diff --git a/glue/crumble/draw/main_draw.js b/glue/crumble/draw/main_draw.js index 4636133e2..30e8b7b3a 100644 --- a/glue/crumble/draw/main_draw.js +++ b/glue/crumble/draw/main_draw.js @@ -1,4 +1,4 @@ -import {pitch, rad, OFFSET_X, OFFSET_Y} from "./config.js" +import {pitch, rad, OFFSET_X, OFFSET_Y, MAX_QUBIT_COORDINATE} from "./config.js" import {marker_placement} from "../gates/gateset_markers.js"; import {drawTimeline} from "./timeline_viewer.js"; import {PropagatedPauliFrames} from "../circuit/propagated_pauli_frames.js"; @@ -192,6 +192,15 @@ function defensiveDraw(ctx, body) { } } +function switchToScreenCoordinates(ctx) { + ctx.setTransform(1, 0, 0, 1, 0, 0); +} + +function switchToTransformationCoordinates(ctx, snap) { + const zoom = snap.viewportZoom; + ctx.setTransform(zoom, 0, 0, zoom, snap.viewportX, snap.viewportY); +} + /** * @param {!CanvasRenderingContext2D} ctx * @param {!StateSnapshot} snap @@ -254,8 +263,10 @@ function draw(ctx, snap) { } defensiveDraw(ctx, () => { - ctx.fillStyle = 'white'; + switchToScreenCoordinates(ctx); ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + switchToTransformationCoordinates(ctx, snap); + let [focusX, focusY] = xyToPos(snap.curMouseX, snap.curMouseY); // Draw the background polygons. @@ -278,13 +289,13 @@ function draw(ctx, snap) { // Draw the grid of qubits. defensiveDraw(ctx, () => { - for (let qx = 0; qx < 100; qx += 0.5) { + for (let qx = 0; qx < MAX_QUBIT_COORDINATE; qx += 0.5) { let [x, _] = c2dCoordTransform(qx, 0); let s = `${qx}`; ctx.fillStyle = 'black'; ctx.fillText(s, x - ctx.measureText(s).width / 2, 15); } - for (let qy = 0; qy < 100; qy += 0.5) { + for (let qy = 0; qy < MAX_QUBIT_COORDINATE; qy += 0.5) { let [_, y] = c2dCoordTransform(0, qy); let s = `${qy}`; ctx.fillStyle = 'black'; @@ -292,12 +303,12 @@ function draw(ctx, snap) { } ctx.strokeStyle = 'black'; - for (let qx = 0; qx < 100; qx += 0.5) { + for (let qx = 0; qx < MAX_QUBIT_COORDINATE; qx += 0.5) { let [x, _] = c2dCoordTransform(qx, 0); let s = `${qx}`; ctx.fillStyle = 'black'; ctx.fillText(s, x - ctx.measureText(s).width / 2, 15); - for (let qy = qx % 1; qy < 100; qy += 1) { + for (let qy = qx % 1; qy < MAX_QUBIT_COORDINATE; qy += 1) { let [x, y] = c2dCoordTransform(qx, qy); ctx.fillStyle = 'white'; let isUnused = !usedQubitCoordSet.has(`${qx},${qy}`); @@ -384,7 +395,8 @@ function draw(ctx, snap) { }); }); - drawTimeline(ctx, snap, propagatedMarkerLayers, qubitDrawCoords, circuit.layers.length); + switchToScreenCoordinates(ctx); + const maxTimelineScrollY = drawTimeline(ctx, snap, propagatedMarkerLayers, qubitDrawCoords, circuit.layers.length); // Draw scrubber. ctx.save(); @@ -485,6 +497,7 @@ function draw(ctx, snap) { } finally { ctx.restore(); } + return maxTimelineScrollY; } export {xyToPos, draw, setDefensiveDrawEnabled, OFFSET_X, OFFSET_Y} diff --git a/glue/crumble/draw/state_snapshot.js b/glue/crumble/draw/state_snapshot.js index 3c31cb3d1..233a70cd7 100644 --- a/glue/crumble/draw/state_snapshot.js +++ b/glue/crumble/draw/state_snapshot.js @@ -17,8 +17,14 @@ class StateSnapshot { * @param {!number} mouseDownX * @param {!number} mouseDownY * @param {!Array} boxHighlightPreview + * @param {!number} viewportX + * @param {!number} viewportY + * @param {!number} viewportZoom + * @param {!number} timelineScrollY + * @param {!number} curMouseScreenX + * @param {!number} curMouseScreenY */ - constructor(circuit, curLayer, focusedSet, timelineSet, curMouseX, curMouseY, mouseDownX, mouseDownY, boxHighlightPreview) { + constructor(circuit, curLayer, focusedSet, timelineSet, curMouseX, curMouseY, mouseDownX, mouseDownY, boxHighlightPreview, viewportX=0, viewportY=0, viewportZoom=1, timelineScrollY=0, curMouseScreenX=undefined, curMouseScreenY=undefined) { this.circuit = circuit.copy(); this.curLayer = curLayer; this.focusedSet = new Map(focusedSet.entries()); @@ -28,6 +34,12 @@ class StateSnapshot { this.mouseDownX = mouseDownX; this.mouseDownY = mouseDownY; this.boxHighlightPreview = [...boxHighlightPreview]; + this.viewportX = viewportX; + this.viewportY = viewportY; + this.viewportZoom = viewportZoom; + this.timelineScrollY = timelineScrollY; + this.curMouseScreenX = curMouseScreenX; + this.curMouseScreenY = curMouseScreenY; while (this.circuit.layers.length <= this.curLayer) { this.circuit.layers.push(new Layer()); diff --git a/glue/crumble/draw/timeline_viewer.js b/glue/crumble/draw/timeline_viewer.js index 2bab08cfb..c8e63c616 100644 --- a/glue/crumble/draw/timeline_viewer.js +++ b/glue/crumble/draw/timeline_viewer.js @@ -1,8 +1,9 @@ -import {OFFSET_Y, rad} from "./config.js"; +import {rad} from "./config.js"; import {stroke_connector_to} from "../gates/gate_draw_util.js" import {marker_placement} from '../gates/gateset_markers.js'; -let TIMELINE_PITCH = 32; +const TIMELINE_PITCH = 32; +const QUBIT_HIGHLIGHT_SIZE = 40; /** * @param {!CanvasRenderingContext2D} ctx @@ -110,6 +111,7 @@ function drawTimeline(ctx, snap, propagatedMarkerLayers, timesliceQubitCoordsFun return x1 - x2; }); + // Calculate base coordinates. let base_y2xy = new Map(); let prev_y = undefined; let cur_x = 0; @@ -132,6 +134,17 @@ function drawTimeline(ctx, snap, propagatedMarkerLayers, timesliceQubitCoordsFun base_y2xy.set(`${x},${y}`, [Math.round(cur_x) + 0.5, Math.round(cur_y) + 0.5]); } + + // Apply vertical scroll offset. + const maxScrollY = Math.max(0, cur_y - ctx.canvas.height + TIMELINE_PITCH); // Restrict scroll based on qubits drawn + const scrollY = Math.max(0, Math.min(snap.timelineScrollY, maxScrollY)); + + if (scrollY !== 0) { + for (let [key, [x, y]] of base_y2xy) { + base_y2xy.set(key, [x, y - scrollY]); + } + } + let x_pitch = TIMELINE_PITCH + Math.ceil(rad*max_run*0.25); let num_cols_half = Math.floor(ctx.canvas.width / 4 / x_pitch); let min_t_free = snap.curLayer - num_cols_half + 1; @@ -211,22 +224,30 @@ function drawTimeline(ctx, snap, propagatedMarkerLayers, timesliceQubitCoordsFun // Draw links to timeslice viewer. ctx.globalAlpha = 0.5; + const mouseScreenX = snap.curMouseScreenX; + const mouseScreenY = snap.curMouseScreenY; + const zoom = snap.viewportZoom; + for (let q of qubits) { let [x0, y0] = qubitTimeCoords(q, min_t_clamp - 1); - let [x1, y1] = timesliceQubitCoordsFunc(q); - if (snap.curMouseX > ctx.canvas.width / 2 && snap.curMouseY >= y0 + OFFSET_Y - TIMELINE_PITCH * 0.55 && snap.curMouseY <= y0 + TIMELINE_PITCH * 0.55 + OFFSET_Y) { + const [wx1, wy1] = timesliceQubitCoordsFunc(q); + // Convert from world to screen coordinates for qubit highlight. + const x1 = wx1 * zoom + snap.viewportX; + const y1 = wy1 * zoom + snap.viewportY; + if (mouseScreenX > ctx.canvas.width / 2 && mouseScreenY >= y0 - TIMELINE_PITCH * 0.55 && mouseScreenY <= y0 + TIMELINE_PITCH * 0.55) { ctx.beginPath(); ctx.moveTo(x0, y0); ctx.lineTo(x1, y1); ctx.stroke(); ctx.fillStyle = 'black'; - ctx.fillRect(x1 - 20, y1 - 20, 40, 40); + ctx.fillRect(x1 - (QUBIT_HIGHLIGHT_SIZE/2) * zoom, y1 - (QUBIT_HIGHLIGHT_SIZE/2) * zoom, QUBIT_HIGHLIGHT_SIZE * zoom, QUBIT_HIGHLIGHT_SIZE * zoom); ctx.fillRect(ctx.canvas.width / 2, y0 - TIMELINE_PITCH / 3, ctx.canvas.width / 2, TIMELINE_PITCH * 2 / 3); } } } finally { ctx.restore(); } + return maxScrollY; } -export {drawTimeline} \ No newline at end of file +export {drawTimeline} diff --git a/glue/crumble/editor/editor_state.js b/glue/crumble/editor/editor_state.js index 9feef8227..7f1b972ff 100644 --- a/glue/crumble/editor/editor_state.js +++ b/glue/crumble/editor/editor_state.js @@ -47,6 +47,12 @@ class EditorState { this.mouseDownX = /** @type {undefined|!number} */ undefined; this.mouseDownY = /** @type {undefined|!number} */ undefined; this.obs_val_draw_state = /** @type {!ObservableValue} */ new ObservableValue(this.toSnapshot(undefined)); + this.curMouseScreenX = /** @type {undefined|!number} */ undefined; + this.curMouseScreenY = /** @type {undefined|!number} */ undefined; + this.viewportX = 0; + this.viewportY = 0; + this.viewportZoom = 1; + this.timelineScrollY = 0; } flipTwoQubitGateOrderAtFocus(preview) { @@ -201,17 +207,7 @@ class EditorState { if (previewCircuit === undefined) { previewCircuit = this.copyOfCurCircuit(); } - return new StateSnapshot( - previewCircuit, - this.curLayer, - this.focusedSet, - this.timelineSet, - this.curMouseX, - this.curMouseY, - this.mouseDownX, - this.mouseDownY, - this.currentPositionsBoxesByMouseDrag(this.chorder.curModifiers.has("alt")), - ); + return new StateSnapshot(previewCircuit, this.curLayer, this.focusedSet, this.timelineSet, this.curMouseX, this.curMouseY, this.mouseDownX, this.mouseDownY, this.currentPositionsBoxesByMouseDrag(this.chorder.curModifiers.has("alt")), this.viewportX, this.viewportY, this.viewportZoom, this.timelineScrollY, this.curMouseScreenX, this.curMouseScreenY); } force_redraw() { diff --git a/glue/crumble/main.js b/glue/crumble/main.js index 7888b9d32..ed3cff4db 100644 --- a/glue/crumble/main.js +++ b/glue/crumble/main.js @@ -1,6 +1,6 @@ import {Circuit} from "./circuit/circuit.js" import {minXY} from "./circuit/layer.js" -import {pitch} from "./draw/config.js" +import {MAX_QUBIT_COORDINATE, MAX_ZOOM, MIN_ZOOM, pitch} from "./draw/config.js" import {GATE_MAP} from "./gates/gateset.js" import {EditorState} from "./editor/editor_state.js"; import {initUrlCircuitSync} from "./editor/sync_url_to_state.js"; @@ -8,7 +8,6 @@ import {draw} from "./draw/main_draw.js"; import {drawToolbox} from "./keyboard/toolbox.js"; import {Operation} from "./circuit/operation.js"; import {make_mpp_gate} from './gates/gateset_mpp.js'; -import {PropagatedPauliFrames} from './circuit/propagated_pauli_frames.js'; const OFFSET_X = -pitch + Math.floor(pitch / 4) + 0.5; const OFFSET_Y = -pitch + Math.floor(pitch / 4) + 0.5; @@ -39,6 +38,14 @@ txtStimCircuit.addEventListener('keydown', ev => ev.stopPropagation()); let editorState = /** @type {!EditorState} */ new EditorState(document.getElementById('cvn')); +function toWorldMouseX(screenX) { + return (screenX - editorState.viewportX) / editorState.viewportZoom + OFFSET_X; +} + +function toWorldMouseY(screenY) { + return (screenY - editorState.viewportY) / editorState.viewportZoom + OFFSET_Y; +} + btnExport.addEventListener('click', _ev => { exportCurrentState(); }); @@ -144,8 +151,10 @@ function exportCurrentState() { } editorState.canvas.addEventListener('mousemove', ev => { - editorState.curMouseX = ev.offsetX + OFFSET_X; - editorState.curMouseY = ev.offsetY + OFFSET_Y; + editorState.curMouseScreenX = ev.offsetX; + editorState.curMouseScreenY = ev.offsetY; + editorState.curMouseX = toWorldMouseX(ev.offsetX); + editorState.curMouseY = toWorldMouseY(ev.offsetY); // Scrubber. let w = editorState.canvas.width / 2; @@ -159,10 +168,12 @@ editorState.canvas.addEventListener('mousemove', ev => { let isInScrubber = false; editorState.canvas.addEventListener('mousedown', ev => { - editorState.curMouseX = ev.offsetX + OFFSET_X; - editorState.curMouseY = ev.offsetY + OFFSET_Y; - editorState.mouseDownX = ev.offsetX + OFFSET_X; - editorState.mouseDownY = ev.offsetY + OFFSET_Y; + editorState.curMouseScreenX = ev.offsetX; + editorState.curMouseScreenY = ev.offsetY; + editorState.curMouseX = toWorldMouseX(ev.offsetX); + editorState.curMouseY = toWorldMouseY(ev.offsetY); + editorState.mouseDownX = toWorldMouseX(ev.offsetX); + editorState.mouseDownY = toWorldMouseY(ev.offsetY); // Scrubber. let w = editorState.canvas.width / 2; @@ -179,14 +190,80 @@ editorState.canvas.addEventListener('mouseup', ev => { let highlightedArea = editorState.currentPositionsBoxesByMouseDrag(ev.altKey); editorState.mouseDownX = undefined; editorState.mouseDownY = undefined; - editorState.curMouseX = ev.offsetX + OFFSET_X; - editorState.curMouseY = ev.offsetY + OFFSET_Y; + editorState.curMouseScreenX = ev.offsetX; + editorState.curMouseScreenY = ev.offsetY; + editorState.curMouseX = toWorldMouseX(ev.offsetX); + editorState.curMouseY = toWorldMouseY(ev.offsetY); editorState.changeFocus(highlightedArea, ev.shiftKey, ev.ctrlKey); if (ev.buttons === 1) { isInScrubber = false; } }); +// Make sure qubit grid and timeline don't deviate from the area of interest. +function restrictQubitGridAndTimeline() { + const width = editorState.canvas.width / 2; + const height = editorState.canvas.height; + const zoom = editorState.viewportZoom; + const gridMin = -1 * pitch - OFFSET_X; + const gridMax = MAX_QUBIT_COORDINATE * pitch - OFFSET_X; + + editorState.viewportX = Math.max( + width - gridMax * zoom, + Math.min(-gridMin * zoom, editorState.viewportX) + ); + editorState.viewportY = Math.max( + height - gridMax * zoom, + Math.min(-gridMin * zoom, editorState.viewportY) + ); + + editorState.timelineScrollY = Math.max( + 0, + editorState.timelineScrollY + ); +} + +function handleTimelineVerticalScroll(ev) { + editorState.timelineScrollY += ev.deltaY; + restrictQubitGridAndTimeline(); + editorState.force_redraw(); + return; +} + +function handleQubitGridZoomPan(ev) { + if (ev.ctrlKey || ev.metaKey) { + // Handle zoom. + const zoomMultiplier = ev.deltaY < 0 ? 1.05 : (1 / 1.05); + const newZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, editorState.viewportZoom * zoomMultiplier)); + const ratio = newZoom / editorState.viewportZoom; + editorState.viewportZoom = newZoom; + + // Center zoom around mouse. + editorState.viewportX = ev.offsetX - (ev.offsetX - editorState.viewportX) * ratio; + editorState.viewportY = ev.offsetY - (ev.offsetY - editorState.viewportY) * ratio; + } else { + // Handle pan. + editorState.viewportX -= ev.deltaX; + editorState.viewportY -= ev.deltaY; + } + + editorState.curMouseX = toWorldMouseX(ev.offsetX); + editorState.curMouseY = toWorldMouseY(ev.offsetY); + restrictQubitGridAndTimeline(); + editorState.force_redraw(); +} + +editorState.canvas.addEventListener('wheel', ev => { + ev.preventDefault(); + const width = editorState.canvas.width / 2; + + if (ev.offsetX > width) { + handleTimelineVerticalScroll(ev); + } else { + handleQubitGridZoomPan(ev); + } +}, { passive: false }); + /** * @return {!Map} */ @@ -504,7 +581,13 @@ editorState.rev.changes().subscribe(() => { drawToolbox(editorState.chorder.toEvent(false)); }); initUrlCircuitSync(editorState.rev); -editorState.obs_val_draw_state.observable().subscribe(ds => requestAnimationFrame(() => draw(editorState.canvas.getContext('2d'), ds))); +editorState.obs_val_draw_state.observable().subscribe(ds => requestAnimationFrame(() => { + const maxTimelineScrollY = draw(editorState.canvas.getContext('2d'), ds); + // Prevent over-scrolling. + if (editorState.timelineScrollY > maxTimelineScrollY) { + editorState.timelineScrollY = maxTimelineScrollY; + } +})); window.addEventListener('focus', () => { editorState.chorder.handleFocusChanged(); }); From d81ded256b096ad2d31ff2f550a2c9544e00c73c Mon Sep 17 00:00:00 2001 From: Iftach Yakar Date: Wed, 8 Apr 2026 19:32:11 +0300 Subject: [PATCH 2/9] Generated crumble_data.cc --- src/stim/diagram/crumble_data.cc | 179 ++++++++++++++++--------------- 1 file changed, 90 insertions(+), 89 deletions(-) diff --git a/src/stim/diagram/crumble_data.cc b/src/stim/diagram/crumble_data.cc index c81dfb58d..32c9a9e1f 100644 --- a/src/stim/diagram/crumble_data.cc +++ b/src/stim/diagram/crumble_data.cc @@ -584,57 +584,57 @@ std::string stim_draw_internal::make_crumble_html() { )CRUMBLE_PART"); result.append(R"CRUMBLE_PART( )CRUMBLE_PART"); From ded0af58716a4918f231b585ed549d6f094d84dc Mon Sep 17 00:00:00 2001 From: Iftach Yakar Date: Wed, 8 Apr 2026 21:44:28 +0300 Subject: [PATCH 3/9] Generated crumble_data.cc again --- src/stim/diagram/crumble_data.cc | 181 ++++++++++++++++--------------- 1 file changed, 91 insertions(+), 90 deletions(-) diff --git a/src/stim/diagram/crumble_data.cc b/src/stim/diagram/crumble_data.cc index 32c9a9e1f..0388719c5 100644 --- a/src/stim/diagram/crumble_data.cc +++ b/src/stim/diagram/crumble_data.cc @@ -584,57 +584,57 @@ std::string stim_draw_internal::make_crumble_html() { )CRUMBLE_PART"); result.append(R"CRUMBLE_PART( )CRUMBLE_PART"); From 7b49ef583434b564808c4e267ddeeae96de54217 Mon Sep 17 00:00:00 2001 From: Iftach Yakar Date: Tue, 14 Apr 2026 00:32:55 +0300 Subject: [PATCH 4/9] remove redundant default values --- glue/crumble/draw/state_snapshot.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glue/crumble/draw/state_snapshot.js b/glue/crumble/draw/state_snapshot.js index 233a70cd7..556b3172f 100644 --- a/glue/crumble/draw/state_snapshot.js +++ b/glue/crumble/draw/state_snapshot.js @@ -24,7 +24,7 @@ class StateSnapshot { * @param {!number} curMouseScreenX * @param {!number} curMouseScreenY */ - constructor(circuit, curLayer, focusedSet, timelineSet, curMouseX, curMouseY, mouseDownX, mouseDownY, boxHighlightPreview, viewportX=0, viewportY=0, viewportZoom=1, timelineScrollY=0, curMouseScreenX=undefined, curMouseScreenY=undefined) { + constructor(circuit, curLayer, focusedSet, timelineSet, curMouseX, curMouseY, mouseDownX, mouseDownY, boxHighlightPreview, viewportX, viewportY, viewportZoom, timelineScrollY, curMouseScreenX, curMouseScreenY) { this.circuit = circuit.copy(); this.curLayer = curLayer; this.focusedSet = new Map(focusedSet.entries()); From db19363281fd6553c26b824f6aa56dc12572a4b4 Mon Sep 17 00:00:00 2001 From: Iftach Yakar Date: Thu, 16 Apr 2026 14:09:46 +0300 Subject: [PATCH 5/9] Added Middle-click + drag to both timeline and timeslice panels + Add X Scroll for timeline panel; Draw all layers always (instead of restricting, like before); X scroll resets on next/prev layer. + Introduce DrawSummary class to include min/max offsets for drawing timeline --- glue/crumble/draw/main_draw.js | 4 +- glue/crumble/draw/state_snapshot.js | 8 ++- glue/crumble/draw/timeline_viewer.js | 90 +++++++++++++++++++--------- glue/crumble/editor/editor_state.js | 32 +++++++++- glue/crumble/main.js | 67 ++++++++++++++++----- 5 files changed, 151 insertions(+), 50 deletions(-) diff --git a/glue/crumble/draw/main_draw.js b/glue/crumble/draw/main_draw.js index 30e8b7b3a..7894b1808 100644 --- a/glue/crumble/draw/main_draw.js +++ b/glue/crumble/draw/main_draw.js @@ -396,7 +396,7 @@ function draw(ctx, snap) { }); switchToScreenCoordinates(ctx); - const maxTimelineScrollY = drawTimeline(ctx, snap, propagatedMarkerLayers, qubitDrawCoords, circuit.layers.length); + const timelineDrawSummary = drawTimeline(ctx, snap, propagatedMarkerLayers, qubitDrawCoords, circuit.layers.length); // Draw scrubber. ctx.save(); @@ -497,7 +497,7 @@ function draw(ctx, snap) { } finally { ctx.restore(); } - return maxTimelineScrollY; + return timelineDrawSummary; } export {xyToPos, draw, setDefensiveDrawEnabled, OFFSET_X, OFFSET_Y} diff --git a/glue/crumble/draw/state_snapshot.js b/glue/crumble/draw/state_snapshot.js index 556b3172f..bfd9f0a4d 100644 --- a/glue/crumble/draw/state_snapshot.js +++ b/glue/crumble/draw/state_snapshot.js @@ -20,11 +20,12 @@ class StateSnapshot { * @param {!number} viewportX * @param {!number} viewportY * @param {!number} viewportZoom - * @param {!number} timelineScrollY + * @param {!number} timelineOffsetX + * @param {!number} timelineOffsetY * @param {!number} curMouseScreenX * @param {!number} curMouseScreenY */ - constructor(circuit, curLayer, focusedSet, timelineSet, curMouseX, curMouseY, mouseDownX, mouseDownY, boxHighlightPreview, viewportX, viewportY, viewportZoom, timelineScrollY, curMouseScreenX, curMouseScreenY) { + constructor(circuit, curLayer, focusedSet, timelineSet, curMouseX, curMouseY, mouseDownX, mouseDownY, boxHighlightPreview, viewportX, viewportY, viewportZoom, timelineOffsetX, timelineOffsetY, curMouseScreenX, curMouseScreenY) { this.circuit = circuit.copy(); this.curLayer = curLayer; this.focusedSet = new Map(focusedSet.entries()); @@ -37,7 +38,8 @@ class StateSnapshot { this.viewportX = viewportX; this.viewportY = viewportY; this.viewportZoom = viewportZoom; - this.timelineScrollY = timelineScrollY; + this.timelineOffsetX = timelineOffsetX; + this.timelineOffsetY = timelineOffsetY; this.curMouseScreenX = curMouseScreenX; this.curMouseScreenY = curMouseScreenY; diff --git a/glue/crumble/draw/timeline_viewer.js b/glue/crumble/draw/timeline_viewer.js index c8e63c616..42931a57d 100644 --- a/glue/crumble/draw/timeline_viewer.js +++ b/glue/crumble/draw/timeline_viewer.js @@ -5,6 +5,20 @@ import {marker_placement} from '../gates/gateset_markers.js'; const TIMELINE_PITCH = 32; const QUBIT_HIGHLIGHT_SIZE = 40; +// Timeline panel changes size dynamically. These values are collected during draw and are used for restricting panning outside the relevant bounds. +class DrawSummary { + /** + * @param {!number} minOffsetX - Minimum allowed offsetX for timeline panel + * @param {!number} maxOffsetX - Maximum allowed offsetX for timeline panel + * @param {!number} maxOffsetY - Maximum Y offset for timeline panel + */ + constructor(minOffsetX, maxOffsetX, maxOffsetY) { + this.minOffsetX = minOffsetX; + this.maxOffsetX = maxOffsetX; + this.maxOffsetY = maxOffsetY; + } +} + /** * @param {!CanvasRenderingContext2D} ctx * @param {!StateSnapshot} ds @@ -135,21 +149,30 @@ function drawTimeline(ctx, snap, propagatedMarkerLayers, timesliceQubitCoordsFun } - // Apply vertical scroll offset. - const maxScrollY = Math.max(0, cur_y - ctx.canvas.height + TIMELINE_PITCH); // Restrict scroll based on qubits drawn - const scrollY = Math.max(0, Math.min(snap.timelineScrollY, maxScrollY)); + const x_pitch = TIMELINE_PITCH + Math.ceil(rad*max_run*0.25); + const num_cols_half = Math.floor(ctx.canvas.width / 4 / x_pitch); + + let min_t_free = snap.curLayer - num_cols_half + 1; + let min_t_clamp = Math.max(0, Math.min(min_t_free, numLayers - num_cols_half*2 + 1)); + + + const maxOffsetY = Math.max(0, cur_y - ctx.canvas.height + TIMELINE_PITCH); + const offsetY = Math.max(-maxOffsetY, Math.min(0, snap.timelineOffsetY ?? 0)); - if (scrollY !== 0) { + const lastLayerOffset = (numLayers - 1 - snap.curLayer - (min_t_clamp - min_t_free)) * x_pitch; + const minOffsetX = -Math.max(0, 0.5 * w + lastLayerOffset); + const maxOffsetX = Math.max(0, (min_t_clamp - 1) * x_pitch); + const offsetX = Math.max(minOffsetX, Math.min(maxOffsetX, snap.timelineOffsetX ?? 0)); + + // Apply x/y offset to base coordinates + if (offsetY !== 0 || offsetX !== 0) { for (let [key, [x, y]] of base_y2xy) { - base_y2xy.set(key, [x, y - scrollY]); + base_y2xy.set(key, [x + offsetX, y + offsetY]); } } - let x_pitch = TIMELINE_PITCH + Math.ceil(rad*max_run*0.25); - let num_cols_half = Math.floor(ctx.canvas.width / 4 / x_pitch); - let min_t_free = snap.curLayer - num_cols_half + 1; - let min_t_clamp = Math.max(0, Math.min(min_t_free, numLayers - num_cols_half*2 + 1)); - let max_t = Math.min(min_t_clamp + num_cols_half*2 + 2, numLayers); + const label_col_x = w * 1.5 + (min_t_free - 1 - snap.curLayer) * x_pitch; + let t2t = t => { let dt = t - snap.curLayer; dt -= min_t_clamp - min_t_free; @@ -172,17 +195,23 @@ function drawTimeline(ctx, snap, propagatedMarkerLayers, timesliceQubitCoordsFun try { ctx.clearRect(w, 0, w, ctx.canvas.height); + // Apply clipping to prevent content from overlapping on labels and outside timeline panel. + ctx.save(); + ctx.beginPath(); + ctx.rect(label_col_x, 0, ctx.canvas.width - label_col_x, ctx.canvas.height); + ctx.clip(); + // Draw colored indicators showing Pauli propagation. let hitCounts = new Map(); for (let [mi, p] of propagatedMarkerLayers.entries()) { - drawTimelineMarkers(ctx, snap, qubitTimeCoords, p, mi, min_t_clamp, max_t, x_pitch, hitCounts); + drawTimelineMarkers(ctx, snap, qubitTimeCoords, p, mi, 0, numLayers, x_pitch, hitCounts); } // Draw highlight of current layer. ctx.globalAlpha *= 0.5; ctx.fillStyle = 'black'; { - let x1 = t2t(snap.curLayer) + w * 1.5 - x_pitch / 2; + let x1 = t2t(snap.curLayer) + w * 1.5 - x_pitch / 2 + offsetX; ctx.fillRect(x1, 0, x_pitch, ctx.canvas.height); } ctx.globalAlpha *= 2; @@ -192,26 +221,16 @@ function drawTimeline(ctx, snap, propagatedMarkerLayers, timesliceQubitCoordsFun // Draw wire lines. for (let q of qubits) { - let [x0, y0] = qubitTimeCoords(q, min_t_clamp - 1); - let [x1, y1] = qubitTimeCoords(q, max_t + 1); + let [x0, y0] = qubitTimeCoords(q, -1); + let [x1, y1] = qubitTimeCoords(q, numLayers); ctx.beginPath(); ctx.moveTo(x0, y0); ctx.lineTo(x1, y1); ctx.stroke(); } - // Draw wire labels. - ctx.textAlign = 'right'; - ctx.textBaseline = 'middle'; - for (let q of qubits) { - let [x, y] = qubitTimeCoords(q, min_t_clamp - 1); - let qx = snap.circuit.qubitCoordData[q * 2]; - let qy = snap.circuit.qubitCoordData[q * 2 + 1]; - ctx.fillText(`${qx},${qy}:`, x, y); - } - // Draw layers of gates. - for (let time = min_t_clamp; time <= max_t; time++) { + for (let time = 0; time < numLayers; time++) { let qubitsCoordsFuncForLayer = q => qubitTimeCoords(q, time); let layer = snap.circuit.layers[time]; if (layer === undefined) { @@ -222,6 +241,21 @@ function drawTimeline(ctx, snap, propagatedMarkerLayers, timesliceQubitCoordsFun } } + ctx.restore(); // Stop clipping since labels and links to timeslice should be outside clipping area. + + // Draw wire labels. + ctx.strokeStyle = 'black'; + ctx.fillStyle = 'black'; + ctx.textAlign = 'right'; + ctx.textBaseline = 'middle'; + for (let q of qubits) { + let [x, y] = qubitTimeCoords(q, min_t_clamp - 1); + x -= offsetX; // Labels are frozen on horizontal axis. + let qx = snap.circuit.qubitCoordData[q * 2]; + let qy = snap.circuit.qubitCoordData[q * 2 + 1]; + ctx.fillText(`${qx},${qy}:`, x, y); + } + // Draw links to timeslice viewer. ctx.globalAlpha = 0.5; const mouseScreenX = snap.curMouseScreenX; @@ -230,6 +264,7 @@ function drawTimeline(ctx, snap, propagatedMarkerLayers, timesliceQubitCoordsFun for (let q of qubits) { let [x0, y0] = qubitTimeCoords(q, min_t_clamp - 1); + x0 -= offsetX; // Lines start at frozen position to math labels. const [wx1, wy1] = timesliceQubitCoordsFunc(q); // Convert from world to screen coordinates for qubit highlight. const x1 = wx1 * zoom + snap.viewportX; @@ -247,7 +282,8 @@ function drawTimeline(ctx, snap, propagatedMarkerLayers, timesliceQubitCoordsFun } finally { ctx.restore(); } - return maxScrollY; + + return new DrawSummary(minOffsetX, maxOffsetX, maxOffsetY); } -export {drawTimeline} +export {drawTimeline, DrawSummary} diff --git a/glue/crumble/editor/editor_state.js b/glue/crumble/editor/editor_state.js index 7f1b972ff..3b7c805be 100644 --- a/glue/crumble/editor/editor_state.js +++ b/glue/crumble/editor/editor_state.js @@ -31,6 +31,28 @@ function rotated45Transform(steps) { return (x, y) => [vx[0]*x + vy[0]*y, vx[1]*x + vy[1]*y]; } +const Panels = Object.freeze({ + TIMESLICE: 'timeslice', // qubit grid (left panel) + TIMELINE: 'timeline', // circuit timeline (right panel) +}); + +class PanDragAnchor { + /** + * @param {!number} screenX - X coordinate of drag start + * @param {!number} screenY - Y coordinate of drag start + * @param {!number} offsetX - X offset from drag start + * @param {!number} offsetY - Y offset from drag start + * @param {!string} activeDragPanel - marks which panel is currently used in drag: PanSide.TIMESLICE or PanSide.TIMELINE + */ + constructor(screenX, screenY, offsetX, offsetY, activeDragPanel) { + this.screenX = screenX; + this.screenY = screenY; + this.offsetX = offsetX; + this.offsetY = offsetY; + this.activeDragPanel = activeDragPanel; + } +} + class EditorState { /** * @param {!HTMLCanvasElement} canvas @@ -52,7 +74,10 @@ class EditorState { this.viewportX = 0; this.viewportY = 0; this.viewportZoom = 1; - this.timelineScrollY = 0; + this.timelineOffsetX = 0; + this.timelineOffsetY = 0; + this.isPanDragging = false; + this.panDragAnchor = /** @type {undefined|!PanDragAnchor} */ undefined; } flipTwoQubitGateOrderAtFocus(preview) { @@ -207,7 +232,7 @@ class EditorState { if (previewCircuit === undefined) { previewCircuit = this.copyOfCurCircuit(); } - return new StateSnapshot(previewCircuit, this.curLayer, this.focusedSet, this.timelineSet, this.curMouseX, this.curMouseY, this.mouseDownX, this.mouseDownY, this.currentPositionsBoxesByMouseDrag(this.chorder.curModifiers.has("alt")), this.viewportX, this.viewportY, this.viewportZoom, this.timelineScrollY, this.curMouseScreenX, this.curMouseScreenY); + return new StateSnapshot(previewCircuit, this.curLayer, this.focusedSet, this.timelineSet, this.curMouseX, this.curMouseY, this.mouseDownX, this.mouseDownY, this.currentPositionsBoxesByMouseDrag(this.chorder.curModifiers.has("alt")), this.viewportX, this.viewportY, this.viewportZoom, this.timelineOffsetX, this.timelineOffsetY, this.curMouseScreenX, this.curMouseScreenY); } force_redraw() { @@ -310,6 +335,7 @@ class EditorState { */ changeCurLayerTo(newLayer) { this.curLayer = Math.max(newLayer, 0); + this.timelineOffsetX = 0; this.force_redraw(); } @@ -776,4 +802,4 @@ class EditorState { } } -export {EditorState, StateSnapshot} +export {EditorState, StateSnapshot, PanDragAnchor, Panels} diff --git a/glue/crumble/main.js b/glue/crumble/main.js index ed3cff4db..1bbf7b5ee 100644 --- a/glue/crumble/main.js +++ b/glue/crumble/main.js @@ -2,7 +2,7 @@ import {Circuit} from "./circuit/circuit.js" import {minXY} from "./circuit/layer.js" import {MAX_QUBIT_COORDINATE, MAX_ZOOM, MIN_ZOOM, pitch} from "./draw/config.js" import {GATE_MAP} from "./gates/gateset.js" -import {EditorState} from "./editor/editor_state.js"; +import {EditorState, PanDragAnchor, Panels} from "./editor/editor_state.js"; import {initUrlCircuitSync} from "./editor/sync_url_to_state.js"; import {draw} from "./draw/main_draw.js"; import {drawToolbox} from "./keyboard/toolbox.js"; @@ -153,6 +153,24 @@ function exportCurrentState() { editorState.canvas.addEventListener('mousemove', ev => { editorState.curMouseScreenX = ev.offsetX; editorState.curMouseScreenY = ev.offsetY; + + // Handle middle click + drag panning. + if (editorState.isPanDragging) { + const anchor = editorState.panDragAnchor; + const newOffsetX = anchor.offsetX + (ev.offsetX - anchor.screenX); + const newOffsetY = anchor.offsetY + (ev.offsetY - anchor.screenY); + if (anchor.activeDragPanel === Panels.TIMESLICE) { + editorState.viewportX = newOffsetX; + editorState.viewportY = newOffsetY; + } else { + editorState.timelineOffsetX = newOffsetX; + editorState.timelineOffsetY = newOffsetY; + } + restrictTimeSliceAndTimelineViews(); + editorState.force_redraw(); + return; + } + editorState.curMouseX = toWorldMouseX(ev.offsetX); editorState.curMouseY = toWorldMouseY(ev.offsetY); @@ -168,6 +186,23 @@ editorState.canvas.addEventListener('mousemove', ev => { let isInScrubber = false; editorState.canvas.addEventListener('mousedown', ev => { + const w = editorState.canvas.width / 2; + + // Middle-click initiates pan drag. + if (ev.button === 1) { + ev.preventDefault(); + editorState.isPanDragging = true; + const targetPanel = ev.offsetX > w ? Panels.TIMELINE : Panels.TIMESLICE; + editorState.panDragAnchor = new PanDragAnchor( + ev.offsetX, + ev.offsetY, + targetPanel === Panels.TIMESLICE ? editorState.viewportX : editorState.timelineOffsetX, + targetPanel === Panels.TIMESLICE ? editorState.viewportY : editorState.timelineOffsetY, + targetPanel, + ); + return; + } + editorState.curMouseScreenX = ev.offsetX; editorState.curMouseScreenY = ev.offsetY; editorState.curMouseX = toWorldMouseX(ev.offsetX); @@ -176,7 +211,6 @@ editorState.canvas.addEventListener('mousedown', ev => { editorState.mouseDownY = toWorldMouseY(ev.offsetY); // Scrubber. - let w = editorState.canvas.width / 2; isInScrubber = ev.offsetY < 20 && ev.offsetX > w && ev.buttons === 1; if (isInScrubber) { editorState.changeCurLayerTo(Math.floor((ev.offsetX - w) / 8)); @@ -187,6 +221,12 @@ editorState.canvas.addEventListener('mousedown', ev => { }); editorState.canvas.addEventListener('mouseup', ev => { + if (ev.button === 1) { + editorState.isPanDragging = false; + editorState.panDragAnchor = undefined; + return; + } + let highlightedArea = editorState.currentPositionsBoxesByMouseDrag(ev.altKey); editorState.mouseDownX = undefined; editorState.mouseDownY = undefined; @@ -201,7 +241,7 @@ editorState.canvas.addEventListener('mouseup', ev => { }); // Make sure qubit grid and timeline don't deviate from the area of interest. -function restrictQubitGridAndTimeline() { +function restrictTimeSliceAndTimelineViews() { const width = editorState.canvas.width / 2; const height = editorState.canvas.height; const zoom = editorState.viewportZoom; @@ -217,15 +257,13 @@ function restrictQubitGridAndTimeline() { Math.min(-gridMin * zoom, editorState.viewportY) ); - editorState.timelineScrollY = Math.max( - 0, - editorState.timelineScrollY - ); + editorState.timelineOffsetY = Math.min(0, editorState.timelineOffsetY); } function handleTimelineVerticalScroll(ev) { - editorState.timelineScrollY += ev.deltaY; - restrictQubitGridAndTimeline(); + editorState.timelineOffsetX -= ev.deltaX; + editorState.timelineOffsetY -= ev.deltaY; + restrictTimeSliceAndTimelineViews(); editorState.force_redraw(); return; } @@ -249,7 +287,7 @@ function handleQubitGridZoomPan(ev) { editorState.curMouseX = toWorldMouseX(ev.offsetX); editorState.curMouseY = toWorldMouseY(ev.offsetY); - restrictQubitGridAndTimeline(); + restrictTimeSliceAndTimelineViews(); editorState.force_redraw(); } @@ -582,11 +620,10 @@ editorState.rev.changes().subscribe(() => { }); initUrlCircuitSync(editorState.rev); editorState.obs_val_draw_state.observable().subscribe(ds => requestAnimationFrame(() => { - const maxTimelineScrollY = draw(editorState.canvas.getContext('2d'), ds); - // Prevent over-scrolling. - if (editorState.timelineScrollY > maxTimelineScrollY) { - editorState.timelineScrollY = maxTimelineScrollY; - } + const drawSummary = draw(editorState.canvas.getContext('2d'), ds); + // Prevent timeline over-panning. + editorState.timelineOffsetX = Math.max(drawSummary.minOffsetX, Math.min(editorState.timelineOffsetX, drawSummary.maxOffsetX)); + editorState.timelineOffsetY = Math.max(editorState.timelineOffsetY, -drawSummary.maxOffsetY); })); window.addEventListener('focus', () => { editorState.chorder.handleFocusChanged(); From 9b84c6ae542cd86cdbdee34c6716580942eb196a Mon Sep 17 00:00:00 2001 From: Iftach Yakar Date: Thu, 16 Apr 2026 14:10:44 +0300 Subject: [PATCH 6/9] typo --- glue/crumble/draw/timeline_viewer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glue/crumble/draw/timeline_viewer.js b/glue/crumble/draw/timeline_viewer.js index 42931a57d..ecbfb31b8 100644 --- a/glue/crumble/draw/timeline_viewer.js +++ b/glue/crumble/draw/timeline_viewer.js @@ -264,7 +264,7 @@ function drawTimeline(ctx, snap, propagatedMarkerLayers, timesliceQubitCoordsFun for (let q of qubits) { let [x0, y0] = qubitTimeCoords(q, min_t_clamp - 1); - x0 -= offsetX; // Lines start at frozen position to math labels. + x0 -= offsetX; // Lines start at frozen position to match labels. const [wx1, wy1] = timesliceQubitCoordsFunc(q); // Convert from world to screen coordinates for qubit highlight. const x1 = wx1 * zoom + snap.viewportX; From 8047eec313fcddbc90f4609cf449019f91fc19a3 Mon Sep 17 00:00:00 2001 From: Iftach Yakar Date: Fri, 17 Apr 2026 00:35:33 +0300 Subject: [PATCH 7/9] Timeslice view - always show tickmarks, correctly positioned without zoom --- glue/crumble/draw/config.js | 3 +- glue/crumble/draw/main_draw.js | 58 +++++++++++++++++++++++----------- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/glue/crumble/draw/config.js b/glue/crumble/draw/config.js index 2ee965e8d..ad1efed02 100644 --- a/glue/crumble/draw/config.js +++ b/glue/crumble/draw/config.js @@ -7,5 +7,6 @@ const MIN_ZOOM = 0.25; const MAX_ZOOM = 4; const MAX_QUBIT_COORDINATE = 100; +const LABEL_GAP = 20; -export {pitch, rad, OFFSET_X, OFFSET_Y, MIN_ZOOM, MAX_ZOOM, MAX_QUBIT_COORDINATE}; +export {pitch, rad, OFFSET_X, OFFSET_Y, MIN_ZOOM, MAX_ZOOM, MAX_QUBIT_COORDINATE, LABEL_GAP}; diff --git a/glue/crumble/draw/main_draw.js b/glue/crumble/draw/main_draw.js index 7894b1808..73ef88662 100644 --- a/glue/crumble/draw/main_draw.js +++ b/glue/crumble/draw/main_draw.js @@ -1,4 +1,4 @@ -import {pitch, rad, OFFSET_X, OFFSET_Y, MAX_QUBIT_COORDINATE} from "./config.js" +import {pitch, rad, OFFSET_X, OFFSET_Y, MAX_QUBIT_COORDINATE, LABEL_GAP} from "./config.js" import {marker_placement} from "../gates/gateset_markers.js"; import {drawTimeline} from "./timeline_viewer.js"; import {PropagatedPauliFrames} from "../circuit/propagated_pauli_frames.js"; @@ -265,6 +265,45 @@ function draw(ctx, snap) { defensiveDraw(ctx, () => { switchToScreenCoordinates(ctx); ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + + // Draw grid tick-mark labels. + defensiveDraw(ctx, () => { + ctx.fillStyle = 'black'; + + let tickMarkInterval = 0.5; + if (snap.viewportZoom < 0.85) tickMarkInterval = 1; + if (snap.viewportZoom < 0.3) tickMarkInterval = 2; + + ctx.save(); + ctx.beginPath(); + ctx.rect(LABEL_GAP, 0, ctx.canvas.width - LABEL_GAP, ctx.canvas.height); + ctx.clip(); + for (let qx = 0; qx < MAX_QUBIT_COORDINATE; qx += tickMarkInterval) { + let [x, _] = c2dCoordTransform(qx, 0); + const screenX = x * snap.viewportZoom + snap.viewportX; + let s = `${qx}`; + ctx.fillText(s, screenX - ctx.measureText(s).width / 2, 15); + } + ctx.restore(); + + ctx.save(); + ctx.beginPath(); + ctx.rect(0, LABEL_GAP, ctx.canvas.width, ctx.canvas.height - LABEL_GAP); + ctx.clip(); + for (let qy = 0; qy < MAX_QUBIT_COORDINATE; qy += tickMarkInterval) { + let [_, y] = c2dCoordTransform(0, qy); + const screenY = y * snap.viewportZoom + snap.viewportY; + let s = `${qy}`; + ctx.fillText(s, 18 - ctx.measureText(s).width, screenY); + } + ctx.restore(); + }); + + // Apply clipping on all content so it doesn't overlap on tick labels. + ctx.save(); + ctx.beginPath(); + ctx.rect(LABEL_GAP, LABEL_GAP, ctx.canvas.width, ctx.canvas.height - LABEL_GAP); + ctx.clip(); switchToTransformationCoordinates(ctx, snap); let [focusX, focusY] = xyToPos(snap.curMouseX, snap.curMouseY); @@ -289,25 +328,8 @@ function draw(ctx, snap) { // Draw the grid of qubits. defensiveDraw(ctx, () => { - for (let qx = 0; qx < MAX_QUBIT_COORDINATE; qx += 0.5) { - let [x, _] = c2dCoordTransform(qx, 0); - let s = `${qx}`; - ctx.fillStyle = 'black'; - ctx.fillText(s, x - ctx.measureText(s).width / 2, 15); - } - for (let qy = 0; qy < MAX_QUBIT_COORDINATE; qy += 0.5) { - let [_, y] = c2dCoordTransform(0, qy); - let s = `${qy}`; - ctx.fillStyle = 'black'; - ctx.fillText(s, 18 - ctx.measureText(s).width, y); - } - ctx.strokeStyle = 'black'; for (let qx = 0; qx < MAX_QUBIT_COORDINATE; qx += 0.5) { - let [x, _] = c2dCoordTransform(qx, 0); - let s = `${qx}`; - ctx.fillStyle = 'black'; - ctx.fillText(s, x - ctx.measureText(s).width / 2, 15); for (let qy = qx % 1; qy < MAX_QUBIT_COORDINATE; qy += 1) { let [x, y] = c2dCoordTransform(qx, qy); ctx.fillStyle = 'white'; From 2f76e0fe1eda7eb68ccecd0978a59d65edc9354b Mon Sep 17 00:00:00 2001 From: Iftach Yakar Date: Fri, 17 Apr 2026 00:43:36 +0300 Subject: [PATCH 8/9] Fix right X offset --- glue/crumble/draw/timeline_viewer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glue/crumble/draw/timeline_viewer.js b/glue/crumble/draw/timeline_viewer.js index ecbfb31b8..525dc9d7f 100644 --- a/glue/crumble/draw/timeline_viewer.js +++ b/glue/crumble/draw/timeline_viewer.js @@ -160,7 +160,7 @@ function drawTimeline(ctx, snap, propagatedMarkerLayers, timesliceQubitCoordsFun const offsetY = Math.max(-maxOffsetY, Math.min(0, snap.timelineOffsetY ?? 0)); const lastLayerOffset = (numLayers - 1 - snap.curLayer - (min_t_clamp - min_t_free)) * x_pitch; - const minOffsetX = -Math.max(0, 0.5 * w + lastLayerOffset); + const minOffsetX = -Math.max(0, lastLayerOffset - 0.5 * w + 2*x_pitch); const maxOffsetX = Math.max(0, (min_t_clamp - 1) * x_pitch); const offsetX = Math.max(minOffsetX, Math.min(maxOffsetX, snap.timelineOffsetX ?? 0)); From 8b1f2c8bdc32341c459e854dcec5aa5100076e56 Mon Sep 17 00:00:00 2001 From: Iftach Yakar Date: Fri, 17 Apr 2026 00:57:31 +0300 Subject: [PATCH 9/9] regenerate crumble_data.cc --- src/stim/diagram/crumble_data.cc | 157 ++++++++++++++++--------------- 1 file changed, 79 insertions(+), 78 deletions(-) diff --git a/src/stim/diagram/crumble_data.cc b/src/stim/diagram/crumble_data.cc index 0388719c5..bb4590b60 100644 --- a/src/stim/diagram/crumble_data.cc +++ b/src/stim/diagram/crumble_data.cc @@ -586,51 +586,51 @@ std::string stim_draw_internal::make_crumble_html() { )CRUMBLE_PART"); result.append(R"CRUMBLE_PART(class l{constructor(t,r,e,i,o,a,n,s,h=void 0){this.name=t,this.t=r,this.i=i,this.o=e,this.h=o,this.l=a,this.v=n,this.u=s,this.X=h}M(t){return new l(this.name,this.t,this.o,this.i,this.h,this.l,this.v,this.u,t)}}function p(r){var e=[];for(let t=0;tr.get(t)))for(let t=0;t{var i,o,a,[r,n]=r(t.R[0]);void 0!==r&&voi)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(d 0!==n&&({dx:t,dy:i,_:o,A:a}=St(t.Y[0]),e.fillStyle=s,o===a?e.fillRect(r-t-2,n-i-2,o+4,a+4):(t=r+(t<0?1:-1)*gt,i=n+(i<0?1:-1)*gt,o=t+(o>gt?1:0)*gt*2,a=i+(a>gt?1:0)*gt*2,e.beginPath(),e.moveTo(r,n),e.lineTo(t,i),e.lineTo(o,a),e.lineTo(r,n),e.fill()))}}function*A(){yield new l("ISWAP",2,!0,!1,new Map([["IX","YZ"],["IZ","ZI"],["XI","ZY"],["ZI","IZ"]]),(t,r)=>t.k(r),(t,r)=>t.k(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),h(e,i,o),h(e,r,t)}),yield new l("ISWAP_DAG",2,!0,!1,new Map([["IX","YZ"],["IZ","ZI"],["XI","ZY"],["ZI","IZ"]]),(t,r)=>t.k(r),(t,r)=>t.k(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),h(e,i,o),h(e,r,t)}),yield new l("SWAP",2,!0,!1,new Map([["IX","XI"],["IZ","ZI"],["XI","IX"],["ZI","IZ"]]),(t,r)=>t.g(r),(t,r)=>t.g(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),b(e,i,o),b(e,r,t)}),yield new l("CXSWAP",2,!0,!1,new Map([["IX","XI"],["IZ","ZZ"],["XI","XX"],["ZI","IZ"]]),(t,r)=>t.C(r),(t,r)=>t.S(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),I(e)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(,i,o),i=e,o=t,void 0!==(e=r)&&void 0!==o&&(i.fillStyle="white",i.strokeStyle="black",i.beginPath(),i.arc(e,o,gt,0,2*Math.PI),i.fill(),i.stroke(),t=.4*gt,i.strokeStyle="black",i.lineWidth=3,i.beginPath(),i.moveTo(e-t,o-t),i.lineTo(e+t,o+t),i.stroke(),i.moveTo(e-t,o+t),i.lineTo(e+t,o-t),i.stroke(),i.lineWidth=1)}),yield new l("CZSWAP",2,!0,!1,new Map([["IX","XZ"],["IZ","ZI"],["XI","ZX"],["ZI","IZ"]]),(t,r)=>t.P(r),(t,r)=>t.P(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),I(e,i,o),I(e,r,t)})}function*k(){yield new l("CX",2,!0,!1,new Map([["IX","IX"],["IZ","ZZ"],["XI","XX"],["ZI","ZI"]]),(t,r)=>t.O(r),(t,r)=>t.O(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),s(e,i,o),a(e,r,t)}),yield new l("CY",2,!0,!1,new Map([["IX","ZX"],["IZ","ZZ"],["XI","XY"],["ZI","ZI"]]),(t,r)=>t.T(r),(t,r)=>t.T(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),s(e,i,o),n(e,r,t)}),yield new l("XCX",2,!0,!1,new Map([["IX","IX"],["IZ","XZ"],["XI","XI"],["ZI","ZX"]]),(t,r)=>t.N(r),(t,r)=>t.N(r),(t,r,e)=>{)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),a(e,i,o),a(e,r,t)}),yield new l("XCY",2,!0,!1,new Map([["IX","XX"],["IZ","XZ"],["XI","XI"],["ZI","ZY"]]),(t,r)=>t.D(r),(t,r)=>t.D(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),a(e,i,o),n(e,r,t)}),yield new l("YCY",2,!0,!1,new Map([["IX","YX"],["IZ","YZ"],["XI","XY"],["ZI","ZY"]]),(t,r)=>t.L(r),(t,r)=>t.L(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),n(e,i,o),n(e,r,t)}),yield new l("CZ",2,!0,!1,new Map([["IX","ZX"],["IZ","IZ"],["XI","XZ"],["ZI","ZI"]]),(t,r)=>t.F(r),(t,r)=>t.F(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),s(e,i,o),s(e,r,t)}),yield new l("MR",1,!0,!1,new Map([["X","ERR:I"],["Y","ERR:I"],["Z","I"]]),(t,r)=>t.U("Z",r),(t,r)=>t.U("Z",r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="gray",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("MR",r,t)}),yield new l("MRY",1,!0,!1,new Map([["X","ERR:I"],[)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART("Y","I"],["Z","ERR:I"]]),(t,r)=>t.U("Y",r),(t,r)=>t.U("Y",r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="gray",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("MRY",r,t)}),yield new l("MRX",1,!0,!1,new Map([["X","I"],["Y","ERR:I"],["Z","ERR:I"]]),(t,r)=>t.U("X",r),(t,r)=>t.U("X",r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="gray",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("MRX",r,t)}),yield new l("H",1,!0,!1,new Map([["X","Z"],["Z","X"]]),(t,r)=>t.G(r),(t,r)=>t.G(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("H",r,t)}),yield new l("H_NXZ",1,!0,!1,new Map([["X","Z"],["Z","X"]]),(t,r)=>t.G(r),(t,r)=>t.G(r),(t,r,e))CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("H",r,t-gt/3),e.fillText("NXZ",r,t+gt/3)}),yield new l("H_XY",1,!0,!1,new Map([["X","Y"],["Z","Z"]]),(t,r)=>t.H(r),(t,r)=>t.H(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("H",r,t-gt/3),e.fillText("XY",r,t+gt/3)}),yield new l("H_NXY",1,!0,!1,new Map([["X","Y"],["Z","Z"]]),(t,r)=>t.H(r),(t,r)=>t.H(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("H",r,t-gt/3),e.fillText("NXY",r,t+gt/3)}),yield new l("H_YZ",1,!0,!1,new Map([["X","X"],["Z","Y"]]),(t,r)=>t.K(r),(t,r)=>t.K(r),(t)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("H",r,t-gt/3),e.fillText("YZ",r,t+gt/3)}),yield new l("H_NYZ",1,!0,!1,new Map([["X","X"],["Z","Y"]]),(t,r)=>t.K(r),(t,r)=>t.K(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("H",r,t-gt/3),e.fillText("NYZ",r,t+gt/3)}),yield new l("POLYGON",void 0,!1,!0,void 0,()=>{},()=>{},(t,r,e)=>{var i,o=[];for(i of t.R){var[a,n]=r(i);o.push([a-=.5,n-=.5])}S(e,o),e.globalAlpha*=t.Y[3],e.fillStyle=`rgb(${255*t.Y[0]},${255*t.Y[1]},${255*t.Y[2]})`,e.fill()}),yield new l("DETECTOR",void 0,!1,!0,void 0,()=>{},()=>{},(t,r,e)=>{}),yield new l("OBSERVABLE_INCLUDE",void 0,!1,!0,void 0,()=>{},()=>{},(t,r,e)=>{}),yield new l("MARKX",1,!0,!0,void 0,()=>{},()=>{})CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(,E("red")),yield new l("MARKY",1,!0,!0,void 0,()=>{},()=>{},E("green")),yield new l("MARKZ",1,!0,!0,void 0,()=>{},()=>{},E("blue")),yield new l("MARK",1,!1,!0,void 0,()=>{},()=>{},(t,r,e)=>{var[r,t]=r(t.R[0]);void 0!==r&&void 0!==t&&(e.fillStyle="magenta",e.fillRect(r-gt,t-gt,gt,gt))}),yield new l("MXX",2,!0,!1,new Map([["II","II"],["IX","IX"],["IY","ERR:IY"],["IZ","ERR:IZ"],["XI","XI"],["XX","XX"],["XY","ERR:XY"],["XZ","ERR:XZ"],["YI","ERR:YI"],["YX","ERR:YX"],["YY","YY"],["YZ","YZ"],["ZI","ERR:ZI"],["ZX","ERR:ZX"],["ZY","ZY"],["ZZ","ZZ"]]),(t,r)=>t.$("XX",r),(t,r)=>t.$("XX",r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),e.fillStyle="gray",e.fillRect(i-gt,o-gt,2*gt,2*gt),e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(i-gt,o-gt,2*gt,2*gt),e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("MXX",i,o),e.fillText("MXX",r,t)}),yield new l("MYY",2,!0,!1,new Map([["II","II"],["IX","ERR:IX"],["IY","IY"],["IZ","ERR:IZ"],["XI")CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(,"ERR:XI"],["XX","XX"],["XY","ERR:XY"],["XZ","XZ"],["YI","YI"],["YX","ERR:YX"],["YY","YY"],["YZ","ERR:YZ"],["ZI","ERR:ZI"],["ZX","ZX"],["ZY","ERR:ZY"],["ZZ","ZZ"]]),(t,r)=>t.$("YY",r),(t,r)=>t.$("YY",r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),e.fillStyle="gray",e.fillRect(i-gt,o-gt,2*gt,2*gt),e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(i-gt,o-gt,2*gt,2*gt),e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("MYY",i,o),e.fillText("MYY",r,t)}),yield new l("MZZ",2,!0,!1,new Map([["II","II"],["IX","ERR:IX"],["IY","ERR:IY"],["IZ","IZ"],["XI","ERR:XI"],["XX","XX"],["XY","XY"],["XZ","ERR:XZ"],["YI","ERR:YI"],["YX","YX"],["YY","YY"],["YZ","ERR:YZ"],["ZI","ZI"],["ZX","ERR:ZX"],["ZY","ERR:ZY"],["ZZ","ZZ"]]),(t,r)=>t.$("ZZ",r),(t,r)=>t.$("ZZ",r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),e.fillStyle="gray",e.fillRect(i-gt,o-gt,2*gt,2*gt),e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(i-gt)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(,o-gt,2*gt,2*gt),e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("MZZ",i,o),e.fillText("MZZ",r,t)}),yield new l("ERR",1,!0,!1,new Map([["X","X"],["Z","Z"]]),()=>{},()=>{},(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="red",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("ERR",r,t)}),yield new l("I",1,!0,!1,new Map([["X","X"],["Z","Z"]]),()=>{},()=>{},(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="white",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("I",r,t)}),yield new l("X",1,!0,!1,new Map([["X","X"],["Z","Z"]]),()=>{},()=>{},(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="white",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.f)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(illText("X",r,t)}),yield new l("Y",1,!0,!1,new Map([["X","X"],["Z","Z"]]),()=>{},()=>{},(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="white",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("Y",r,t)}),yield new l("Z",1,!0,!1,new Map([["X","X"],["Z","Z"]]),()=>{},()=>{},(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="white",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("Z",r,t)}),yield new l("S",1,!0,!1,new Map([["X","Y"],["Z","Z"]]),(t,r)=>t.H(r),(t,r)=>t.H(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("S",r,t)}),yield new l("S_DAG",1,!0,!1,new Map([["X","Y"],["Z","Z"]]),(t,r)=>t.H(r),(t,r)=>t.H(r),(t,r,e)=>{var[r,t]=r(t.R)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART([0]);e.fillStyle="yellow",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("S†",r,t)}),yield new l("SQRT_X",1,!0,!1,new Map([["X","X"],["Z","Y"]]),(t,r)=>t.K(r),(t,r)=>t.K(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√X",r,t)}),yield new l("SQRT_X_DAG",1,!0,!1,new Map([["X","X"],["Z","Y"]]),(t,r)=>t.K(r),(t,r)=>t.K(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√X†",r,t)}),yield new l("SQRT_Y",1,!0,!1,new Map([["X","Z"],["Z","X"]]),(t,r)=>t.G(r),(t,r)=>t.G(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="blac)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(k",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√Y",r,t)}),yield new l("SQRT_Y_DAG",1,!0,!1,new Map([["X","Z"],["Z","X"]]),(t,r)=>t.G(r),(t,r)=>t.G(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√Y†",r,t)}),yield new l("R",1,!0,!1,new Map([["X","ERR:I"],["Y","ERR:I"],["Z","ERR:I"]]),(t,r)=>t.B(r),(t,r)=>t.U("Z",r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="gray",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("R",r,t)}),yield new l("RX",1,!0,!1,new Map([["X","ERR:I"],["Y","ERR:I"],["Z","ERR:I"]]),(t,r)=>t.B(r),(t,r)=>t.U("X",r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="gray",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("RX",r,t)}),yield new l("RY",1,!0,!1,new Map([["X","ERR:I"],["Y","ERR:I"],["Z","ERR:I"]]),(t,r)=>t.B(r),(t,r)=>t.U("Y",r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="gray",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("RY",r,t)}),yield new l("M",1,!0,!1,new Map([["X","ERR:X"],["Y","ERR:Y"],["Z","Z"]]),(t,r)=>t.$("Z",r),(t,r)=>t.$("Z",r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="gray",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("M",r,t),e.textAlign="left"}),yield new l("MX",1,!0,!1,new Map([["X","X"],["Y","ERR:Y"],["Z","ERR:Z"]]),(t,r)=>t.$("X",r),(t,r)=>t.$("X",r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="gray",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillS)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(tyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("MX",r,t),e.textAlign="left"}),yield new l("MY",1,!0,!1,new Map([["X","ERR:X"],["Y","Y"],["Z","ERR:Z"]]),(t,r)=>t.$("Y",r),(t,r)=>t.$("Y",r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="gray",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("MY",r,t),e.textAlign="left"}),yield new l("II",2,!0,!1,new Map([["IX","IX"],["IZ","IZ"],["XI","XI"],["ZI","ZI"]]),(t,r)=>{},(t,r)=>{},(t,r,e)=>{var i,o,[a,n]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,a,n,r,t);for([i,o]of[[a,n],[r,t]])e.fillStyle="white",e.fillRect(i-gt,o-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(i-gt,o-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("II",i,o)}),yield new l("SQRT_XX",2,!0,!1,new Map([["IX","IX"],["IZ","XY"],["XI","XI"],["ZI","YX"]]),(t,r)=>t.q(r),(t,r)=>t.q(r),(t,r,e)=>{var i,o,[a,n]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,a,n,r,t);for)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(([i,o]of[[a,n],[r,t]])e.fillStyle="yellow",e.fillRect(i-gt,o-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(i-gt,o-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√XX",i,o)}),yield new l("SQRT_XX_DAG",2,!0,!1,new Map([["IX","IX"],["IZ","XY"],["XI","XI"],["ZI","YX"]]),(t,r)=>t.q(r),(t,r)=>t.q(r),(t,r,e)=>{var i,o,[a,n]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,a,n,r,t);for([i,o]of[[a,n],[r,t]])e.fillStyle="yellow",e.fillRect(i-gt,o-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(i-gt,o-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√XX†",i,o)}),yield new l("SQRT_YY",2,!0,!1,new Map([["IX","YZ"],["IZ","YX"],["XI","ZY"],["ZI","XY"]]),(t,r)=>t.W(r),(t,r)=>t.W(r),(t,r,e)=>{var i,o,[a,n]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,a,n,r,t);for([i,o]of[[a,n],[r,t]])e.fillStyle="yellow",e.fillRect(i-gt,o-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(i-gt,o-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√YY",)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(i,o)}),yield new l("SQRT_YY_DAG",2,!0,!1,new Map([["IX","YZ"],["IZ","YX"],["XI","ZY"],["ZI","XY"]]),(t,r)=>t.W(r),(t,r)=>t.W(r),(t,r,e)=>{var i,o,[a,n]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,a,n,r,t);for([i,o]of[[a,n],[r,t]])e.fillStyle="yellow",e.fillRect(i-gt,o-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(i-gt,o-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√YY†",i,o)}),yield new l("SQRT_ZZ",2,!0,!1,new Map([["IX","ZY"],["IZ","IZ"],["XI","YZ"],["ZI","ZI"]]),(t,r)=>t.V(r),(t,r)=>t.V(r),(t,r,e)=>{var i,o,[a,n]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,a,n,r,t);for([i,o]of[[a,n],[r,t]])e.fillStyle="yellow",e.fillRect(i-gt,o-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(i-gt,o-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√ZZ",i,o)}),yield new l("SQRT_ZZ_DAG",2,!0,!1,new Map([["IX","ZY"],["IZ","IZ"],["XI","YZ"],["ZI","ZI"]]),(t,r)=>t.V(r),(t,r)=>t.V(r),(t,r,e)=>{var i,o,[a,n]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,a,n,r,t);for([i,o]of[[a,n],[r,t)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(]])e.fillStyle="yellow",e.fillRect(i-gt,o-gt,2*gt,2*gt),e.strokeStyle="black",e.strokeRect(i-gt,o-gt,2*gt,2*gt),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√ZZ†",i,o)}),yield*A(),yield new l("C_XYZ",1,!0,!1,new Map([["X","Y"],["Z","X"]]),(t,r)=>t.j(r),(t,r)=>t.J(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="teal",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.textAlign="center",e.textBaseline="middle",e.fillText("C",r,t-gt/3),e.fillText("XYZ",r,t+gt/3)}),yield new l("C_NXYZ",1,!0,!1,new Map([["X","Y"],["Z","X"]]),(t,r)=>t.j(r),(t,r)=>t.J(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="teal",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.textAlign="center",e.textBaseline="middle",e.fillText("C",r,t-gt/3),e.fillText("NXYZ",r,t+gt/3)}),yield new l("C_XNYZ",1,!0,!1,new Map([["X","Y"],["Z","X"]]),(t,r)=>t.j(r),(t,r)=>t.J(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillSty)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(le="teal",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.textAlign="center",e.textBaseline="middle",e.fillText("C",r,t-gt/3),e.fillText("XNYZ",r,t+gt/3)}),yield new l("C_XYNZ",1,!0,!1,new Map([["X","Y"],["Z","X"]]),(t,r)=>t.j(r),(t,r)=>t.J(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="teal",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.textAlign="center",e.textBaseline="middle",e.fillText("C",r,t-gt/3),e.fillText("XYNZ",r,t+gt/3)}),yield new l("C_ZYX",1,!0,!1,new Map([["X","Z"],["Z","Y"]]),(t,r)=>t.J(r),(t,r)=>t.j(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="teal",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.textAlign="center",e.textBaseline="middle",e.fillText("C",r,t-gt/3),e.fillText("ZYX",r,t+gt/3)}),yield new l("C_ZYNX",1,!0,!1,new Map([["X","Z"],["Z","Y"]]),(t,r)=>t.J(r),(t,r)=>t.j(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.f)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(illStyle="teal",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.textAlign="center",e.textBaseline="middle",e.fillText("C",r,t-gt/3),e.fillText("ZYNX",r,t+gt/3)}),yield new l("C_ZNYX",1,!0,!1,new Map([["X","Z"],["Z","Y"]]),(t,r)=>t.J(r),(t,r)=>t.j(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="teal",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.textAlign="center",e.textBaseline="middle",e.fillText("C",r,t-gt/3),e.fillText("ZNYX",r,t+gt/3)}),yield new l("C_NZYX",1,!0,!1,new Map([["X","Z"],["Z","Y"]]),(t,r)=>t.J(r),(t,r)=>t.j(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="teal",e.fillRect(r-gt,t-gt,2*gt,2*gt),e.fillStyle="black",e.strokeStyle="black",e.strokeRect(r-gt,t-gt,2*gt,2*gt),e.textAlign="center",e.textBaseline="middle",e.fillText("C",r,t-gt/3),e.fillText("NZYX",r,t+gt/3)})}const B=function(){var t,r=new Map;for(t of k())r.set(t.name,t);return r.set("MZ",r.get("M")),r.set("RZ",r.get(")CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(R")),r.set("MRZ",r.get("MR")),r}(),H=((t=new Map).set("CNOT",{name:"CX"}),t.set("MZ",{name:"M"}),t.set("MRZ",{name:"MR"}),t.set("RZ",{name:"R"}),t.set("H_XZ",{name:"H"}),t.set("SQRT_Z",{name:"S"}),t.set("SQRT_Z_DAG",{name:"S_DAG"}),t.set("ZCX",{name:"CX"}),t.set("ZCY",{name:"CY"}),t.set("ZCZ",{name:"CZ"}),t.set("SWAPCZ",{name:"CZSWAP"}),t.set("XCZ",{name:"CX",tt:!0}),t.set("YCX",{name:"XCY",tt:!0}),t.set("YCZ",{name:"CY",tt:!0}),t.set("SWAPCX",{name:"CXSWAP",tt:!0}),t.set("CORRELATED_ERROR",{rt:!0}),t.set("DEPOLARIZE1",{rt:!0}),t.set("DEPOLARIZE2",{rt:!0}),t.set("E",{rt:!0}),t.set("ELSE_CORRELATED_ERROR",{rt:!0}),t.set("PAULI_CHANNEL_1",{rt:!0}),t.set("PAULI_CHANNEL_2",{rt:!0}),t.set("X_ERROR",{rt:!0}),t.set("I_ERROR",{rt:!0}),t.set("II_ERROR",{rt:!0}),t.set("Y_ERROR",{rt:!0}),t.set("Z_ERROR",{rt:!0}),t.set("HERALDED_ERASE",{rt:!0}),t.set("HERALDED_PAULI_CHANNEL_1",{rt:!0}),t.set("MPAD",{rt:!0}),t.set("SHIFT_COORDS",{rt:!0}),t);function g(t,r){var e,i=new Map;for(e of t){var o=r(e),a=i.get(o);void 0===a?i.set)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART((o,[e]):a.push(e)}return i}class U{constructor(){this.et=new Map,this.it=[]}toString(){let t="Layer {\n";t+=" id_ops {\n";for(var[r,e]of this.et.entries())t+=` ${r}: ${e} + result.append(R"CRUMBLE_PART(Z.u(this,t,r),""!==this.tag&&0{var i,o,a,[r,n]=r(t.R[0]);void 0!==r)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(&&void 0!==n&&({dx:t,dy:i,_:o,A:a}=Ot(t.Y[0]),e.fillStyle=s,o===a?e.fillRect(r-t-2,n-i-2,o+4,a+4):(t=r+(t<0?1:-1)*St,i=n+(i<0?1:-1)*St,o=t+(o>St?1:0)*St*2,a=i+(a>St?1:0)*St*2,e.beginPath(),e.moveTo(r,n),e.lineTo(t,i),e.lineTo(o,a),e.lineTo(r,n),e.fill()))}}function*A(){yield new l("ISWAP",2,!0,!1,new Map([["IX","YZ"],["IZ","ZI"],["XI","ZY"],["ZI","IZ"]]),(t,r)=>t.k(r),(t,r)=>t.k(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),h(e,i,o),h(e,r,t)}),yield new l("ISWAP_DAG",2,!0,!1,new Map([["IX","YZ"],["IZ","ZI"],["XI","ZY"],["ZI","IZ"]]),(t,r)=>t.k(r),(t,r)=>t.k(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),h(e,i,o),h(e,r,t)}),yield new l("SWAP",2,!0,!1,new Map([["IX","XI"],["IZ","ZI"],["XI","IX"],["ZI","IZ"]]),(t,r)=>t.g(r),(t,r)=>t.g(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),b(e,i,o),b(e,r,t)}),yield new l("CXSWAP",2,!0,!1,new Map([["IX","XI"],["IZ","ZZ"],["XI","XX"],["ZI","IZ"]]),(t,r)=>t.C(r),(t,r)=>t.S(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(),I(e,i,o),i=e,o=t,void 0!==(e=r)&&void 0!==o&&(i.fillStyle="white",i.strokeStyle="black",i.beginPath(),i.arc(e,o,St,0,2*Math.PI),i.fill(),i.stroke(),t=.4*St,i.strokeStyle="black",i.lineWidth=3,i.beginPath(),i.moveTo(e-t,o-t),i.lineTo(e+t,o+t),i.stroke(),i.moveTo(e-t,o+t),i.lineTo(e+t,o-t),i.stroke(),i.lineWidth=1)}),yield new l("CZSWAP",2,!0,!1,new Map([["IX","XZ"],["IZ","ZI"],["XI","ZX"],["ZI","IZ"]]),(t,r)=>t.P(r),(t,r)=>t.P(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),I(e,i,o),I(e,r,t)})}function*k(){yield new l("CX",2,!0,!1,new Map([["IX","IX"],["IZ","ZZ"],["XI","XX"],["ZI","ZI"]]),(t,r)=>t.O(r),(t,r)=>t.O(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),s(e,i,o),a(e,r,t)}),yield new l("CY",2,!0,!1,new Map([["IX","ZX"],["IZ","ZZ"],["XI","XY"],["ZI","ZI"]]),(t,r)=>t.T(r),(t,r)=>t.T(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),s(e,i,o),n(e,r,t)}),yield new l("XCX",2,!0,!1,new Map([["IX","IX"],["IZ","XZ"],["XI","XI"],["ZI","ZX"]]),(t,r)=>t.N(r),(t,r)=>t.N(r),(t,r,)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),a(e,i,o),a(e,r,t)}),yield new l("XCY",2,!0,!1,new Map([["IX","XX"],["IZ","XZ"],["XI","XI"],["ZI","ZY"]]),(t,r)=>t.D(r),(t,r)=>t.D(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),a(e,i,o),n(e,r,t)}),yield new l("YCY",2,!0,!1,new Map([["IX","YX"],["IZ","YZ"],["XI","XY"],["ZI","ZY"]]),(t,r)=>t.L(r),(t,r)=>t.L(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),n(e,i,o),n(e,r,t)}),yield new l("CZ",2,!0,!1,new Map([["IX","ZX"],["IZ","IZ"],["XI","XZ"],["ZI","ZI"]]),(t,r)=>t.F(r),(t,r)=>t.F(r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),s(e,i,o),s(e,r,t)}),yield new l("MR",1,!0,!1,new Map([["X","ERR:I"],["Y","ERR:I"],["Z","I"]]),(t,r)=>t.U("Z",r),(t,r)=>t.U("Z",r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="gray",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("MR",r,t)}),yield new l("MRY",1,!0,!1,new Map([["X","ERR:)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(I"],["Y","I"],["Z","ERR:I"]]),(t,r)=>t.U("Y",r),(t,r)=>t.U("Y",r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="gray",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("MRY",r,t)}),yield new l("MRX",1,!0,!1,new Map([["X","I"],["Y","ERR:I"],["Z","ERR:I"]]),(t,r)=>t.U("X",r),(t,r)=>t.U("X",r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="gray",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("MRX",r,t)}),yield new l("H",1,!0,!1,new Map([["X","Z"],["Z","X"]]),(t,r)=>t.G(r),(t,r)=>t.G(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("H",r,t)}),yield new l("H_NXZ",1,!0,!1,new Map([["X","Z"],["Z","X"]]),(t,r)=>t.G(r),(t,r)=>t.G(r),(t)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("H",r,t-St/3),e.fillText("NXZ",r,t+St/3)}),yield new l("H_XY",1,!0,!1,new Map([["X","Y"],["Z","Z"]]),(t,r)=>t.H(r),(t,r)=>t.H(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("H",r,t-St/3),e.fillText("XY",r,t+St/3)}),yield new l("H_NXY",1,!0,!1,new Map([["X","Y"],["Z","Z"]]),(t,r)=>t.H(r),(t,r)=>t.H(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("H",r,t-St/3),e.fillText("NXY",r,t+St/3)}),yield new l("H_YZ",1,!0,!1,new Map([["X","X"],["Z","Y"]]),(t,r)=>t.K(r),(t,r)=>t.K()CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("H",r,t-St/3),e.fillText("YZ",r,t+St/3)}),yield new l("H_NYZ",1,!0,!1,new Map([["X","X"],["Z","Y"]]),(t,r)=>t.K(r),(t,r)=>t.K(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("H",r,t-St/3),e.fillText("NYZ",r,t+St/3)}),yield new l("POLYGON",void 0,!1,!0,void 0,()=>{},()=>{},(t,r,e)=>{var i,o=[];for(i of t.R){var[a,n]=r(i);o.push([a-=.5,n-=.5])}S(e,o),e.globalAlpha*=t.Y[3],e.fillStyle=`rgb(${255*t.Y[0]},${255*t.Y[1]},${255*t.Y[2]})`,e.fill()}),yield new l("DETECTOR",void 0,!1,!0,void 0,()=>{},()=>{},(t,r,e)=>{}),yield new l("OBSERVABLE_INCLUDE",void 0,!1,!0,void 0,()=>{},()=>{},(t,r,e)=>{}),yield new l("MARKX",1,!0,!0,void 0,()=>{},()CRUMBLE_PART"); + result.append(R"CRUMBLE_PART()=>{},E("red")),yield new l("MARKY",1,!0,!0,void 0,()=>{},()=>{},E("green")),yield new l("MARKZ",1,!0,!0,void 0,()=>{},()=>{},E("blue")),yield new l("MARK",1,!1,!0,void 0,()=>{},()=>{},(t,r,e)=>{var[r,t]=r(t.R[0]);void 0!==r&&void 0!==t&&(e.fillStyle="magenta",e.fillRect(r-St,t-St,St,St))}),yield new l("MXX",2,!0,!1,new Map([["II","II"],["IX","IX"],["IY","ERR:IY"],["IZ","ERR:IZ"],["XI","XI"],["XX","XX"],["XY","ERR:XY"],["XZ","ERR:XZ"],["YI","ERR:YI"],["YX","ERR:YX"],["YY","YY"],["YZ","YZ"],["ZI","ERR:ZI"],["ZX","ERR:ZX"],["ZY","ZY"],["ZZ","ZZ"]]),(t,r)=>t.$("XX",r),(t,r)=>t.$("XX",r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),e.fillStyle="gray",e.fillRect(i-St,o-St,2*St,2*St),e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(i-St,o-St,2*St,2*St),e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("MXX",i,o),e.fillText("MXX",r,t)}),yield new l("MYY",2,!0,!1,new Map([["II","II"],["IX","ERR:IX"],["IY","IY"],["IZ","ERR:IZ"],)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(["XI","ERR:XI"],["XX","XX"],["XY","ERR:XY"],["XZ","XZ"],["YI","YI"],["YX","ERR:YX"],["YY","YY"],["YZ","ERR:YZ"],["ZI","ERR:ZI"],["ZX","ZX"],["ZY","ERR:ZY"],["ZZ","ZZ"]]),(t,r)=>t.$("YY",r),(t,r)=>t.$("YY",r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),e.fillStyle="gray",e.fillRect(i-St,o-St,2*St,2*St),e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(i-St,o-St,2*St,2*St),e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("MYY",i,o),e.fillText("MYY",r,t)}),yield new l("MZZ",2,!0,!1,new Map([["II","II"],["IX","ERR:IX"],["IY","ERR:IY"],["IZ","IZ"],["XI","ERR:XI"],["XX","XX"],["XY","XY"],["XZ","ERR:XZ"],["YI","ERR:YI"],["YX","YX"],["YY","YY"],["YZ","ERR:YZ"],["ZI","ZI"],["ZX","ERR:ZX"],["ZY","ERR:ZY"],["ZZ","ZZ"]]),(t,r)=>t.$("ZZ",r),(t,r)=>t.$("ZZ",r),(t,r,e)=>{var[i,o]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,i,o,r,t),e.fillStyle="gray",e.fillRect(i-St,o-St,2*St,2*St),e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART((i-St,o-St,2*St,2*St),e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("MZZ",i,o),e.fillText("MZZ",r,t)}),yield new l("ERR",1,!0,!1,new Map([["X","X"],["Z","Z"]]),()=>{},()=>{},(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="red",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("ERR",r,t)}),yield new l("I",1,!0,!1,new Map([["X","X"],["Z","Z"]]),()=>{},()=>{},(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="white",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("I",r,t)}),yield new l("X",1,!0,!1,new Map([["X","X"],["Z","Z"]]),()=>{},()=>{},(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="white",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(",e.fillText("X",r,t)}),yield new l("Y",1,!0,!1,new Map([["X","X"],["Z","Z"]]),()=>{},()=>{},(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="white",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("Y",r,t)}),yield new l("Z",1,!0,!1,new Map([["X","X"],["Z","Z"]]),()=>{},()=>{},(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="white",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("Z",r,t)}),yield new l("S",1,!0,!1,new Map([["X","Y"],["Z","Z"]]),(t,r)=>t.H(r),(t,r)=>t.H(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("S",r,t)}),yield new l("S_DAG",1,!0,!1,new Map([["X","Y"],["Z","Z"]]),(t,r)=>t.H(r),(t,r)=>t.H(r),(t,r,e)=>{var[r,t]=)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("S†",r,t)}),yield new l("SQRT_X",1,!0,!1,new Map([["X","X"],["Z","Y"]]),(t,r)=>t.K(r),(t,r)=>t.K(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√X",r,t)}),yield new l("SQRT_X_DAG",1,!0,!1,new Map([["X","X"],["Z","Y"]]),(t,r)=>t.K(r),(t,r)=>t.K(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√X†",r,t)}),yield new l("SQRT_Y",1,!0,!1,new Map([["X","Z"],["Z","X"]]),(t,r)=>t.G(r),(t,r)=>t.G(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle=)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART("black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√Y",r,t)}),yield new l("SQRT_Y_DAG",1,!0,!1,new Map([["X","Z"],["Z","X"]]),(t,r)=>t.G(r),(t,r)=>t.G(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="yellow",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√Y†",r,t)}),yield new l("R",1,!0,!1,new Map([["X","ERR:I"],["Y","ERR:I"],["Z","ERR:I"]]),(t,r)=>t.B(r),(t,r)=>t.U("Z",r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="gray",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("R",r,t)}),yield new l("RX",1,!0,!1,new Map([["X","ERR:I"],["Y","ERR:I"],["Z","ERR:I"]]),(t,r)=>t.B(r),(t,r)=>t.U("X",r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="gray",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*S)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(t),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("RX",r,t)}),yield new l("RY",1,!0,!1,new Map([["X","ERR:I"],["Y","ERR:I"],["Z","ERR:I"]]),(t,r)=>t.B(r),(t,r)=>t.U("Y",r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="gray",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("RY",r,t)}),yield new l("M",1,!0,!1,new Map([["X","ERR:X"],["Y","ERR:Y"],["Z","Z"]]),(t,r)=>t.$("Z",r),(t,r)=>t.$("Z",r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="gray",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("M",r,t),e.textAlign="left"}),yield new l("MX",1,!0,!1,new Map([["X","X"],["Y","ERR:Y"],["Z","ERR:Z"]]),(t,r)=>t.$("X",r),(t,r)=>t.$("X",r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="gray",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("MX",r,t),e.textAlign="left"}),yield new l("MY",1,!0,!1,new Map([["X","ERR:X"],["Y","Y"],["Z","ERR:Z"]]),(t,r)=>t.$("Y",r),(t,r)=>t.$("Y",r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="gray",e.fillRect(r-St,t-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("MY",r,t),e.textAlign="left"}),yield new l("II",2,!0,!1,new Map([["IX","IX"],["IZ","IZ"],["XI","XI"],["ZI","ZI"]]),(t,r)=>{},(t,r)=>{},(t,r,e)=>{var i,o,[a,n]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,a,n,r,t);for([i,o]of[[a,n],[r,t]])e.fillStyle="white",e.fillRect(i-St,o-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(i-St,o-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("II",i,o)}),yield new l("SQRT_XX",2,!0,!1,new Map([["IX","IX"],["IZ","XY"],["XI","XI"],["ZI","YX"]]),(t,r)=>t.q(r),(t,r)=>t.q(r),(t,r,e)=>{var i,o,[a,n]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,a,n,r,t)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART();for([i,o]of[[a,n],[r,t]])e.fillStyle="yellow",e.fillRect(i-St,o-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(i-St,o-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√XX",i,o)}),yield new l("SQRT_XX_DAG",2,!0,!1,new Map([["IX","IX"],["IZ","XY"],["XI","XI"],["ZI","YX"]]),(t,r)=>t.q(r),(t,r)=>t.q(r),(t,r,e)=>{var i,o,[a,n]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,a,n,r,t);for([i,o]of[[a,n],[r,t]])e.fillStyle="yellow",e.fillRect(i-St,o-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(i-St,o-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√XX†",i,o)}),yield new l("SQRT_YY",2,!0,!1,new Map([["IX","YZ"],["IZ","YX"],["XI","ZY"],["ZI","XY"]]),(t,r)=>t.W(r),(t,r)=>t.W(r),(t,r,e)=>{var i,o,[a,n]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,a,n,r,t);for([i,o]of[[a,n],[r,t]])e.fillStyle="yellow",e.fillRect(i-St,o-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(i-St,o-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText(")CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(√YY",i,o)}),yield new l("SQRT_YY_DAG",2,!0,!1,new Map([["IX","YZ"],["IZ","YX"],["XI","ZY"],["ZI","XY"]]),(t,r)=>t.W(r),(t,r)=>t.W(r),(t,r,e)=>{var i,o,[a,n]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,a,n,r,t);for([i,o]of[[a,n],[r,t]])e.fillStyle="yellow",e.fillRect(i-St,o-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(i-St,o-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√YY†",i,o)}),yield new l("SQRT_ZZ",2,!0,!1,new Map([["IX","ZY"],["IZ","IZ"],["XI","YZ"],["ZI","ZI"]]),(t,r)=>t.V(r),(t,r)=>t.V(r),(t,r,e)=>{var i,o,[a,n]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,a,n,r,t);for([i,o]of[[a,n],[r,t]])e.fillStyle="yellow",e.fillRect(i-St,o-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(i-St,o-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√ZZ",i,o)}),yield new l("SQRT_ZZ_DAG",2,!0,!1,new Map([["IX","ZY"],["IZ","IZ"],["XI","YZ"],["ZI","ZI"]]),(t,r)=>t.V(r),(t,r)=>t.V(r),(t,r,e)=>{var i,o,[a,n]=r(t.R[0]),[r,t]=r(t.R[1]);c(e,a,n,r,t);for([i,o]of[[a,n])CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(,[r,t]])e.fillStyle="yellow",e.fillRect(i-St,o-St,2*St,2*St),e.strokeStyle="black",e.strokeRect(i-St,o-St,2*St,2*St),e.fillStyle="black",e.textAlign="center",e.textBaseline="middle",e.fillText("√ZZ†",i,o)}),yield*A(),yield new l("C_XYZ",1,!0,!1,new Map([["X","Y"],["Z","X"]]),(t,r)=>t.j(r),(t,r)=>t.J(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="teal",e.fillRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.textAlign="center",e.textBaseline="middle",e.fillText("C",r,t-St/3),e.fillText("XYZ",r,t+St/3)}),yield new l("C_NXYZ",1,!0,!1,new Map([["X","Y"],["Z","X"]]),(t,r)=>t.j(r),(t,r)=>t.J(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="teal",e.fillRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.textAlign="center",e.textBaseline="middle",e.fillText("C",r,t-St/3),e.fillText("NXYZ",r,t+St/3)}),yield new l("C_XNYZ",1,!0,!1,new Map([["X","Y"],["Z","X"]]),(t,r)=>t.j(r),(t,r)=>t.J(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fi)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(llStyle="teal",e.fillRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.textAlign="center",e.textBaseline="middle",e.fillText("C",r,t-St/3),e.fillText("XNYZ",r,t+St/3)}),yield new l("C_XYNZ",1,!0,!1,new Map([["X","Y"],["Z","X"]]),(t,r)=>t.j(r),(t,r)=>t.J(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="teal",e.fillRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.textAlign="center",e.textBaseline="middle",e.fillText("C",r,t-St/3),e.fillText("XYNZ",r,t+St/3)}),yield new l("C_ZYX",1,!0,!1,new Map([["X","Z"],["Z","Y"]]),(t,r)=>t.J(r),(t,r)=>t.j(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="teal",e.fillRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.textAlign="center",e.textBaseline="middle",e.fillText("C",r,t-St/3),e.fillText("ZYX",r,t+St/3)}),yield new l("C_ZYNX",1,!0,!1,new Map([["X","Z"],["Z","Y"]]),(t,r)=>t.J(r),(t,r)=>t.j(r),(t,r,e)=>{var[r,t]=r(t.R[0])CRUMBLE_PART"); + result.append(R"CRUMBLE_PART();e.fillStyle="teal",e.fillRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.textAlign="center",e.textBaseline="middle",e.fillText("C",r,t-St/3),e.fillText("ZYNX",r,t+St/3)}),yield new l("C_ZNYX",1,!0,!1,new Map([["X","Z"],["Z","Y"]]),(t,r)=>t.J(r),(t,r)=>t.j(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="teal",e.fillRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.textAlign="center",e.textBaseline="middle",e.fillText("C",r,t-St/3),e.fillText("ZNYX",r,t+St/3)}),yield new l("C_NZYX",1,!0,!1,new Map([["X","Z"],["Z","Y"]]),(t,r)=>t.J(r),(t,r)=>t.j(r),(t,r,e)=>{var[r,t]=r(t.R[0]);e.fillStyle="teal",e.fillRect(r-St,t-St,2*St,2*St),e.fillStyle="black",e.strokeStyle="black",e.strokeRect(r-St,t-St,2*St,2*St),e.textAlign="center",e.textBaseline="middle",e.fillText("C",r,t-St/3),e.fillText("NZYX",r,t+St/3)})}const B=function(){var t,r=new Map;for(t of k())r.set(t.name,t);return r.set("MZ",r.get("M")),r.set("RZ",r.)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(get("R")),r.set("MRZ",r.get("MR")),r}(),z=((t=new Map).set("CNOT",{name:"CX"}),t.set("MZ",{name:"M"}),t.set("MRZ",{name:"MR"}),t.set("RZ",{name:"R"}),t.set("H_XZ",{name:"H"}),t.set("SQRT_Z",{name:"S"}),t.set("SQRT_Z_DAG",{name:"S_DAG"}),t.set("ZCX",{name:"CX"}),t.set("ZCY",{name:"CY"}),t.set("ZCZ",{name:"CZ"}),t.set("SWAPCZ",{name:"CZSWAP"}),t.set("XCZ",{name:"CX",tt:!0}),t.set("YCX",{name:"XCY",tt:!0}),t.set("YCZ",{name:"CY",tt:!0}),t.set("SWAPCX",{name:"CXSWAP",tt:!0}),t.set("CORRELATED_ERROR",{rt:!0}),t.set("DEPOLARIZE1",{rt:!0}),t.set("DEPOLARIZE2",{rt:!0}),t.set("E",{rt:!0}),t.set("ELSE_CORRELATED_ERROR",{rt:!0}),t.set("PAULI_CHANNEL_1",{rt:!0}),t.set("PAULI_CHANNEL_2",{rt:!0}),t.set("X_ERROR",{rt:!0}),t.set("I_ERROR",{rt:!0}),t.set("II_ERROR",{rt:!0}),t.set("Y_ERROR",{rt:!0}),t.set("Z_ERROR",{rt:!0}),t.set("HERALDED_ERASE",{rt:!0}),t.set("HERALDED_PAULI_CHANNEL_1",{rt:!0}),t.set("MPAD",{rt:!0}),t.set("SHIFT_COORDS",{rt:!0}),t);function g(t,r){var e,i=new Map;for(e of t){var o=r(e),a=i.get(o);void 0===a?)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(i.set(o,[e]):a.push(e)}return i}class U{constructor(){this.et=new Map,this.it=[]}toString(){let t="Layer {\n";t+=" id_ops {\n";for(var[r,e]of this.et.entries())t+=` ${r}: ${e} )CRUMBLE_PART"); result.append(R"CRUMBLE_PART(`;t+=" }\n markers {\n";for(var i of this.it)t+=` ${i} )CRUMBLE_PART"); result.append(R"CRUMBLE_PART(`;return t=t+" }\n"+"}"}ot(){let r=g(this.nt(),t=>{let r=t.Z.name;return(r=(r=r.startsWith("MPP:")&&!B.has(r)?"MPP":r).startsWith("SPP:")&&!B.has(r)?"SPP":r).startsWith("SPP_DAG:")&&!B.has(r)&&(r="SPP_DAG"),""!==t.tag&&(r+="["+t.tag.replace("\\","\\B").replace("\r","\\r").replace("\n","\\n").replace("]","\\C")+"]"),0{var e=t.startsWith("MARK")||t.startsWith("POLY"),i=r.startsWith("MARK")||r.startsWith("POLY");return e!==i?e[t,r.get(t)]))}st(){var t=new U;return t.et=new Map(this.et),t.it=[...this.it],t}m(){let t=0;for(var[r,e]of this.et.entries())e.R[0]===r&&(t+=e.m());return t}ht(){var t,r=["M","MX","MY","MR","MRX","MRY","MXX","MYY","MZZ","RX","RY","R"];for(t of this.et.values())if(t.Z.name.startsWith("MPP:")||-1!==r.indexOf(t.Z.name))return!0;return!1}lt(){var t,r=["M","MX","MY","MR","MRX","MRY","MXX","MYY","MZZ","RX","RY","R"];for(t of this.et.values())if(1===t.R.length&&-1)CRUMBLE_PART"); result.append(R"CRUMBLE_PART(===r.indexOf(t.Z.name)&&0===t.m())return!0;return!1}ft(){var t,r=["MR","MRX","MRY","RX","RY","R"];for(t of this.et.values())if(-1!==r.indexOf(t.Z.name))return!0;return!1}vt(){var t,r=["M","MX","MY","MR","MRX","MRY","MXX","MYY","MZZ"];for(t of this.et.values())if(t.Z.name.startsWith("MPP:")||-1!==r.indexOf(t.Z.name))return!0;return!1}empty(){return 0===this.et.size&&0===this.it.length}ct(t){var r,e,i=new U;for(r of this.et.values())t(r)&&i.put(r);for(e of this.it)t(e)&&i.it.push(e);return i}dt(r){return this.ct(t=>!t.R.every(t=>!r(t)))}wt(e,t){var r,i,o=new Map,a=new Set;for(r of e.keys()){var n=e.get(r),s=this.et.get(r);if(void 0!==s){let r="";for(var h of s.R){a.has(h),a.add(h);let t=e.get(h);void 0===t&&(t="I"),r+=t}var l=s.p(r),f=l.startsWith("ERR:");for(let t=0;t-1===t.R.indexOf(r)),this.et.has(r)){var t,e=this.et.get(r);for(t of e.R)this.et.delete(t);return e}}Mt(r,e=void 0){this.it=this.it.filter(t=>void 0!==e&&t.Y[0]!==e||"MARKX"!==t.Z.name&&"MARKY"!==t.Z.name&&"MARKZ"!==t.Z.name||t.R[0]!==r)}put(t,r=!0){if(t.Z.i)"MARKX"!==t.Z.name&&"MARKY"!==t.Z.name&&"MARKZ"!==t.Z.name||this.Mt(t.R[0],t.Y[0]),this.it.push(t);else{for(var e of t.R)if(this.et.has(e)){if(!r)throw new Error("Collision");this.Xt(e)}for(var i of t.R)this.et.set(i,t)}}*nt(){for(var t of this.et.keys()){var r=this.et.get(t);r.R[0]===t&&(yield r)}yield*this.it}}function C(t){let r=void 0,e=void 0;for(var[i,o]of t)(void 0=)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(==r||it.Zt(f,r),(t,r)=>t.Zt(f,r),(r,e,i)=>{let o=void 0,a=void 0;for(let t=0;td){a.push("[...]");break}e=G(e,o-1),i=G(i,o-1);a.push(e+": "+i)}return`Map{${a.join(", ")}}`}if(t instanceof Set){var n,s=r,h=[];for(n of t){if(h.length>d){h.push("[...]");break}h.push(G(n,s-1))}return`Set{${h.join(", ")}}`}if(void 0!==t[Symbol.iterator]){var l,f=r,v=[])CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(;for(l of t){if(v.length>d){v.push("[...]");break}v.push(G(l,f-1))}return`${t=Array.isArray(t)?"":t.constructor.name}[${v.join(", ")}]`}}function $(t,r){try{var e=String(t);if(e!==P)return e}catch{}var i=t,o=r,a=[];for(s in i)if(i.hasOwnProperty(s)){if(a.length>d){a.push("[...]");break}var n=i[s],s=G(s,o-1),n=G(n,o-1);a.push(s+": "+n)}return void 0===i.constructor?"[an unknown non-primitive value with no constructor]":(e=(e=i.constructor.name)==={}.constructor.name?"":`(Type: ${e})`)+`{${a.join(", ")}}`}function G(t,r=K){return(null===(e=t)?"null":void 0===e?"undefined":"string"==typeof e?`"${e}"`:"number"==typeof e?""+e:void 0)||Q(t,r)||$(t,r);var e}function q(t){let r=[];var e,i=()=>{""!==o&&(r.push(o),o="")};let o="";for(e of t)" "===e?i():"*"===e?(i(),r.push("*")):o+=e;return i(),r}function W(e){var t=[];let i=0;for(;ie.length)throw Error(`Dangling combiner in ${e}.`);var o=[];for(let t=i;tt.Yt(f,r),(t,r)=>t.Yt(f,r),(r,e,i)=>{let o=void 0,a=void 0;for(let t=0;tt instanceof U))throw new Error("!layers.every(e => e instanceof Layer)");this.Rt=t,this.yt=r}static It(t){t=t.replaceAll(";","\n").replaceAll("#!pragma ERR","ERR").replaceAll("#!pragma MARK","MARK").replaceAll("#!pragma POLYGON","POLYGON").replaceAll("_"," ").replaceAll("Q(","QUBIT_COORDS(").replaceAll("DT","DETECTOR").replaceAll("OI","OBSERVABLE_INCLUDE").replaceAll(" COORDS","_COORDS").replaceAll(" ERROR","_ERROR").replaceAll("C XYZ","C_)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(==r||it.Zt(f,r),(t,r)=>t.Zt(f,r),(r,e,i)=>{let o=void 0,a=void 0;for(let t=0;td){a.push("[...]");break}e=G(e,o-1),i=G(i,o-1);a.push(e+": "+i)}return`Map{${a.join(", ")}}`}if(t instanceof Set){var n,s=r,h=[];for(n of t){if(h.length>d){h.push("[...]");break}h.push(G(n,s-1))}return`Set{${h.join(", ")}}`}if(void 0!==t[Symbol.iterator]){var l,f=r,v=[])CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(;for(l of t){if(v.length>d){v.push("[...]");break}v.push(G(l,f-1))}return`${t=Array.isArray(t)?"":t.constructor.name}[${v.join(", ")}]`}}function q(t,r){try{var e=String(t);if(e!==P)return e}catch{}var i=t,o=r,a=[];for(s in i)if(i.hasOwnProperty(s)){if(a.length>d){a.push("[...]");break}var n=i[s],s=G(s,o-1),n=G(n,o-1);a.push(s+": "+n)}return void 0===i.constructor?"[an unknown non-primitive value with no constructor]":(e=(e=i.constructor.name)==={}.constructor.name?"":`(Type: ${e})`)+`{${a.join(", ")}}`}function G(t,r=Q){return(null===(e=t)?"null":void 0===e?"undefined":"string"==typeof e?`"${e}"`:"number"==typeof e?""+e:void 0)||$(t,r)||q(t,r);var e}function W(t){let r=[];var e,i=()=>{""!==o&&(r.push(o),o="")};let o="";for(e of t)" "===e?i():"*"===e?(i(),r.push("*")):o+=e;return i(),r}function V(e){var t=[];let i=0;for(;ie.length)throw Error(`Dangling combiner in ${e}.`);var o=[];for(let t=i;tt.Yt(f,r),(t,r)=>t.Yt(f,r),(r,e,i)=>{let o=void 0,a=void 0;for(let t=0;tt instanceof U))throw new Error("!layers.every(e => e instanceof Layer)");this.Rt=t,this.yt=r}static It(t){t=t.replaceAll(";","\n").replaceAll("#!pragma ERR","ERR").replaceAll("#!pragma MARK","MARK").replaceAll("#!pragma POLYGON","POLYGON").replaceAll("_"," ").replaceAll("Q(","QUBIT_COORDS(").replaceAll("DT","DETECTOR").replaceAll("OI","OBSERVABLE_INCLUDE").replaceAll(" COORDS","_COORDS").replaceAll(" ERROR","_ERROR").replaceAll("C XYZ","C_)CRUMBLE_PART"); result.append(R"CRUMBLE_PART(XYZ").replaceAll("C NXYZ","C_NXYZ").replaceAll("C XNYZ","C_XNYZ").replaceAll("C XYNZ","C_XYNZ").replaceAll("H XY","H_XY").replaceAll("H XZ","H_XZ").replaceAll("H YZ","H_YZ").replaceAll("H NXY","H_NXY").replaceAll("H NXZ","H_NXZ").replaceAll("H NYZ","H_NYZ").replaceAll(" INCLUDE","_INCLUDE").replaceAll("SQRT ","SQRT_").replaceAll(" DAG ","_DAG ").replaceAll("C ZYX","C_ZYX").replaceAll("C NZYX","C_NZYX").replaceAll("C ZNYX","C_ZNYX").replaceAll("C ZYNX","C_ZYNX").split("\n");let T=[new U],N=0,D=new Map,x=new Set,s=(e,i,o,r)=>{T[T.length-1].empty()||T.push(new U);for(let t=0;t{let o=0;for(let r=t;r{let a=[],n=[],e="",s="",t=o.indexOf(" "),r=o.indexOf("("),i=o.indexOf("["),h)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(=o.indexOf("]");if(i!==-1&&t!==-1&&ti){e=o.substring(i+1,h).replaceAll("\\C","]").replaceAll("\\r","\r").replaceAll("\\n","\n").replaceAll("\\B","\\");o=o.substring(0,i)+" "+o.substring(h+1)}if(o.indexOf(")")!==-1){let[t,r]=o.split(")");let[e,i]=t.split("(");s=e.trim();a=i.split(",").map(t=>t.trim()).map(parseFloat);n=q(r)}else{let t=o.split(" ").map(t=>t.trim()).filter(t=>t!=="");if(t.length===0)return;let[r,...e]=t;s=r.trim();a=[];n=e.flatMap(q)}let l=false;if(""!==s){0=L.length)return console.warn("Ignoring instruction due to out of range record target: "+o);var Y=L[Z];T[Y.bt].it.push(new F(B.get(s),e,new Float32Array([X]),new Uint32Array([Y._t[0]])))}return N+=u}if("SPP"===s||"SPP_DAG"===s){var R="SPP_DAG"===s,y=W(n),m;let r=T[T.length-1];for(m of y)try{r.put(j(e,new Float32Array(a),R,m),!1)}catch(t){T.push(new U),(r=T[T.length-1]).put(j(e,new Float32Array(a),R,m),!1)}return}if(s.startsWith("QUBIT_COORDS")){var p=a.length<1?0:a[0],I=a.length<2?0:a[1],b;for(b of n){var _=parseInt(b);D.has(_)?console.warn(`Ignoring "${o}" because there's already coordinate data for qubit ${_}.`):x.has(p+","+I)?console.warn(`Ignoring "${o}" because there's already a qubit placed at ${p},${I}.`):(D.set(_,[p,I]),x)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(=o.indexOf("]");if(i!==-1&&t!==-1&&ti){e=o.substring(i+1,h).replaceAll("\\C","]").replaceAll("\\r","\r").replaceAll("\\n","\n").replaceAll("\\B","\\");o=o.substring(0,i)+" "+o.substring(h+1)}if(o.indexOf(")")!==-1){let[t,r]=o.split(")");let[e,i]=t.split("(");s=e.trim();a=i.split(",").map(t=>t.trim()).map(parseFloat);n=W(r)}else{let t=o.split(" ").map(t=>t.trim()).filter(t=>t!=="");if(t.length===0)return;let[r,...e]=t;s=r.trim();a=[];n=e.flatMap(W)}let l=false;if(""!==s){0=L.length)return console.warn("Ignoring instruction due to out of range record target: "+o);var Y=L[Z];T[Y.bt].it.push(new F(B.get(s),e,new Float32Array([X]),new Uint32Array([Y._t[0]])))}return N+=u}if("SPP"===s||"SPP_DAG"===s){var R="SPP_DAG"===s,y=V(n),m;let r=T[T.length-1];for(m of y)try{r.put(J(e,new Float32Array(a),R,m),!1)}catch(t){T.push(new U),(r=T[T.length-1]).put(J(e,new Float32Array(a),R,m),!1)}return}if(s.startsWith("QUBIT_COORDS")){var p=a.length<1?0:a[0],I=a.length<2?0:a[1],b;for(b of n){var _=parseInt(b);D.has(_)?console.warn(`Ignoring "${o}" because there's already coordinate data for qubit ${_}.`):x.has(p+","+I)?console.warn(`Ignoring "${o}" because there's already a qubit placed at ${p},${I}.`):(D.set(_,[p,I]),x)CRUMBLE_PART"); result.append(R"CRUMBLE_PART(.add(p+","+I))}return}}let t=!1;for(v of n)if(v.startsWith("rec["))"CX"!==s&&"CY"!==s&&"CZ"!==s&&"ZCX"!==s&&"ZCY"!==s||(t=!0);else if("number"!=typeof parseInt(v))throw new Error(o);if(t){var E=[];for(let t=0;t{let r=!0;for(;!D.has(t);){var e=r?t:o,i=e+",0";x.has(i)||(x.add(i),D.set(t,[e,0])),o+=!r,r=!1}};for(r of T)for(var i of r.nt())for(var a of i.R)e(a);var n=Math.max(...D.keys(),0)+1,h=new Float64Array(2*n);for(let t=0;t[t-r,t+r])}gt(){var t,r,e=new Map;for(let t=0;t1/256;)s/=2;let h;if(s<=1/256)h=1;else{h=1/s;let t=0;for(var[l,f]of e.values()){var v=(l-a+f-n)%(2*s),l=(l-a-f+n)%(2*s);t=t|(0==v?1:2)|(0==l?4:8)}5===t?h/=2:10===t&&(a-=s,h/=2)}let c=-a,d=-n;return(t,r)=>[)CRUMBLE_PART"); result.append(R"CRUMBLE_PART((t+c)*h,(r+d)*h]}Ct(){return this.kt(this.gt())}St(e,i){return this.kt((t,r)=>[t+e,r+i])}st(){return this.St(0,0)}kt(r){var e=new Float64Array(this.Rt.length);for(let t=0;tt.st());return new u(e,t)}Pt(r){var e=new Map;for(let t=0;tr-t),u=w.Tt.join(":"),Z.has(u)||(Z.add(u),Y.push(w)));for([X,M]of f.entries())(M=[...new Set(M)]).sort((t,r)=>r-t),f.set(X,M);return Y.sort((t,r)=>t.Tt[0]-r.Tt[0]),{Nt:Y,Dt:f}}xt(){var t,r=new Set;for(t of this.yt)for(var N of t.nt())for(var D of N.R)r.add(D);var{Nt:a,Dt:e}=this.Pt(!0);a.reverse();let n=0;var i,s=this.m(),o=[];for(i of r){var x=this.Rt[2*i],L=this.Rt[2*i+1];o.push({Lt:i,x:x,y:L})}o.sort((t,r)=>t.x!==r.x?t.x-r.x:t.y!==r.y?t.y-r.y:t.Lt-r.Lt);var h=new Map,l=[];for(let t=0;t=g.length&&(t=0,i+=1),e=`DETECTOR(${g[t]}, ${C[t]}, ${i})`,X.has(e);t++);X.add(e);var O,T=[e];for(O of E.Tt)T.push(`rec[${O+A}]`);l.push(T.join(" ")),o=Math.max(o,i+1)}f=o;for([w,u]of[...e.entries()]){var K=s-n;if(!(0<=u[0]+K)){e.delete(w);var Q,$=[`OBSERVABLE_INCLUDE(${w})`];for(Q of u)$.push(`rec[${Q+K}]`);l.push($.join(" "))}}l.push("TICK")}for(;0t.st()))}Ut(){var r=new Map;for(let t=0;t!(e instanceof t))){var s=t,h=r;if(s.length!==h.length)return!1;for(let t=0;tt.st()))}Ut(){var r=new Map;for(let t=0;t!(e instanceof t))){var s=t,h=r;if(s.length!==h.length)return!1;for(let t=0;t{performance.now(){this.er="idle",this.ir=-1/0,this.sr()},e)}}class i{constructor(t){this.hr=t}subscribe(t){return this.hr(t)}static of(...e){return new i(t=>{for(var r of e)t(r);return()=>{}})}lr(){let r=[];return this.subscribe(t=>r.push(t))(),r}map(e){return new i(r=>this.subscribe(t=>r(e(t))))}filter(e){return new i(r=>this.subscribe(t=>{e(t)&&r(t)}))}vr(s,h){return new i(r=>{)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(let e=!1,i=!1,o,a,t=this.subscribe(t=>{o=t,e=!0,i&&r(h(o,a))}),n=s.subscribe(t=>{a=t,i=!0,e&&r(h(o,a))});return()=>{t(),n()}})}static cr(){return new i(t=>{let r,e=!1;return(r=()=>{e||(t(void 0),window.requestAnimationFrame(r))})(),()=>{e=!0}})}dr(){return new i(e=>{let i=()=>{},o=!1,t=this.subscribe(t=>{var r;o||(r=i,i=t.subscribe(e),r())});return()=>{o=!0,i(),t()}})}wr(r){return this.map(t=>(r(t),t))}ur(){return new i(r=>{let e=[];return e.push(this.subscribe(t=>e.push(t.subscribe(r)))),()=>{for(var t of e)t()}})}Xr(a){return new i(t=>{let r=void 0,e=!1,i=new st(()=>{e||t(r)},a),o=this.subscribe(t=>{r=t,i.sr()});return()=>{e=!0,o()}})}static Mr(r,e){return new i(t=>(r.addEventListener(e,t),()=>r.removeEventListener(e,t)))}Zr(t){return new i(r=>{let e=t;return this.subscribe(t=>{0t===r);return new i(r=>{let e=!1,i=void 0;return this.subscribe(t=>{e&&o(i,t)||(i=t,e=!0,r(t))})})}}class ht{constructor(){this.Rr=[],this.yr=new i(t=>{this.Rr.push(t);let r=!1;return()=)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(>{r||(r=!0,this.Rr.splice(this.Rr.indexOf(t),1))}})}mr(){return this.yr}send(t){for(var r of this.Rr)r(t)}}class lt{constructor(t=void 0){this.pr=t,this.Ir=new ht,this.yr=new i(t=>(t(this.pr),this.Ir.mr().subscribe(t)))}mr(){return this.yr}set(t){this.pr=t,this.Ir.send(t)}get(){return this.pr}}class ft{constructor(t,r,e){if(r<0||r>=t.length)throw new Error("Bad index: "+{history:t,index:r,br:e});if(!Array.isArray(t))throw new Error("Bad history: "+{history:t,index:r,br:e});this.history=t,this.index=r,this.br=e,this._r=new ht,this.Er=new lt(this.history[this.index])}Ar(){return this._r.mr()}kr(){return this.Er.mr()}gr(){return this.Er.get()}static Cr(t){return new ft([t],0,!1)}Sr(){return 0===this.index&&!this.br}Pr(){return this.index===this.history.length-1}clear(t){this.history=[t],this.index=0,this.br=!1,this.Er.set(t),this._r.send(t)}Or(t){this.br=t!==this.history[this.index],this._r.send(void 0)}Tr(){this.br=!1;var t=this.history[this.index];return this.Er.set(t),this._r.send(t),t}commit(t){t===this.hist)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(ory[this.index]?this.Tr():(this.br=!1,this.index+=1,this.history.splice(this.index,this.history.length-this.index),this.history.push(t),this.Er.set(t),this._r.send(t))}Nr(){if(!this.br){if(0===this.index)return;--this.index}this.br=!1;var t=this.history[this.index];return this.Er.set(t),this._r.send(t),t}Dr(){var t;if(this.index+1!==this.history.length)return this.index+=1,this.br=!1,t=this.history[this.index],this.Er.set(t),this._r.send(t),t}toString(){return"Revision("+G({index:this.index,count:this.history.length,Lr:this.br,head:this.history[this.index]})+")"}Gt(t){return t instanceof ft&&this.index===t.index&&this.br===t.br&&w(this.history,t.history)}}const Pt=32,Ot=40;function vt(t,e,N,o,D){var x,r=Math.floor(t.canvas.width/2),i=e.Fr();i.sort((t,r)=>{var[t,e]=o(t),[r,i]=o(r);return e!==i?e-i:t-r});let a=new Map,L=void 0,n=0,s=0,h=0,l=0;for(x of i){var[F,f]=o(x);s+=Pt,L!==f?(L=f,n=1.5*r,h=Math.max(h,l),l=0,s+=.25*Pt):(n+=.25*gt,l++),a.set(F+","+f,[Math.round(n)+.5,Math.round(s)+.5])}var U=Math.max(0,s-t.c)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(anvas.height+Pt),G=Math.max(0,Math.min(e.Ur,U));if(0!==G)for(var[H,[z,K]]of a)a.set(H,[z,K-G]);let v=Pt+Math.ceil(gt*h*.25);var c=Math.floor(t.canvas.width/4/v);let Q=e.Gr-c+1,d=Math.max(0,Math.min(Q,D-2*c+1));var w=Math.min(d+2*c+2,D);let $=t=>{t-=e.Gr;return(t-=d-Q)*v},u=(t,r)=>{var[t,e]=o(t);return[t,e,r]=[[t,e,r]][0],t=t+","+e,a.has(t)?([e,t]=a.get(t),[e+$(r),t]):[void 0,void 0]};t.save();try{t.clearRect(r,0,r,t.canvas.height);var B,q,W=new Map;for([B,q]of N.entries()){E=_=b=ht=st=nt=at=I=S=C=ot=it=et=g=p=m=rt=tt=k=J=A=y=R=j=V=Y=Z=M=X=void 0;var X=t,M=u,Z=q,Y=B,V=d,j=w,R=v,y=W;for(let o=V-1;o<=j;o++){y.has(o)||y.set(o,new Map);var m,p,I,b,_,E,A=y.get(o),J=Z.Hr(o+.5),k=Z.Hr(o);for([m,p]of J.zr.entries()){let{dx:t,dy:r,_:e,A:i}=St(Y,m,A);0<=Y&&Y<4?(t=0,e=R,i=5,0===Y?r=10:1===Y?r=5:2===Y?r=0:3===Y&&(r=-5)):t-=R/2;var[tt,rt]=M(m,o);if(void 0!==tt&&void 0!==rt){if("X"===p)X.fillStyle="red";else if("Y"===p)X.fillStyle="green";else{if("Z"!==p)throw new Error("Not a pauli: "+p);X.fillStyle="blue"}X.fillRect(tt-t,)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(rt-r,e,i)}}for(I of k.Kr){var{dx:g,dy:et,_:it,A:ot}=St(Y,I,A),[C,S]=(g-=R/2,M(I,o-.5));void 0!==C&&void 0!==S&&(X.strokeStyle="magenta",X.lineWidth=8,X.strokeRect(C-g,S-et,it,ot),X.lineWidth=1,X.fillStyle="black",X.fillRect(C-g,S-et,it,ot))}for({Qr:b,$r:_,color:E}of k.Br){var[at,nt]=M(b,o),[st,ht]=M(_,o);"X"===E?X.strokeStyle="red":"Y"===E?X.strokeStyle="green":"Z"===E?X.strokeStyle="blue":X.strokeStyle="purple",X.lineWidth=8,Ct(X,at,nt,st,ht),X.lineWidth=1}}}t.globalAlpha*=.5,t.fillStyle="black";var lt,P,ft=$(e.Gr)+1.5*r-v/2;t.fillRect(ft,0,v,t.canvas.height),t.globalAlpha*=2,t.strokeStyle="black",t.fillStyle="black";for(lt of i){var[vt,ct]=u(lt,d-1),[dt,wt]=u(lt,w+1);t.beginPath(),t.moveTo(vt,ct),t.lineTo(dt,wt),t.stroke()}t.textAlign="right",t.textBaseline="middle";for(P of i){var[ut,Xt]=u(P,d-1),Mt=e.qr.Rt[2*P],Zt=e.qr.Rt[2*P+1];t.fillText(Mt+`,${Zt}:`,ut,Xt)}for(let r=d;r<=w;r++){var Yt=t=>u(t,r),Rt=e.qr.yt[r];if(void 0!==Rt)for(var yt of Rt.nt())yt.I(Yt,t)}t.globalAlpha=.5;var mt,pt=e.Wr,It=e.Vr,O=e.jr;)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(for(mt of i){var[bt,T]=u(mt,d-1),[_t,Et]=o(mt),At=_t*O+e.Jr,kt=Et*O+e.te;pt>t.canvas.width/2&&It>=T-.55*Pt&&It<=T+.55*Pt&&(t.beginPath(),t.moveTo(bt,T),t.lineTo(At,kt),t.stroke(),t.fillStyle="black",t.fillRect(At-Ot/2*O,kt-Ot/2*O,Ot*O,Ot*O),t.fillRect(t.canvas.width/2,T-Pt/3,t.canvas.width/2,2*Pt/3))}}finally{t.restore()}return U}class Z{constructor(t,r){if(32 32");this.t=r,this.re=t,this.ee=new Uint32Array(r),this.ie=new Uint32Array(r),this.flags=new Uint32Array(r)}st(){var r=new Z(this.re,this.t);for(let t=0;t>=1,r>>=1,e>>=1,i>>=1}return s}static ae(e){var t=e.len)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(gth;if(0===t)throw new Error("strings.length === 0");var r,i=e[0].length;for(r of e)if(r.length!==i)throw new Error("Inconsistent string length.");var o=new Z(t,i);for(let r=0;r>e&1,o=this.ee[t]>>e&1,a=this.ie[t]>>e&1;r+="_XZY!%$&"[o+2*a+4*i]}t.push(r)}return t}static se(e,i){var o=new Z(e.length,i.length);for(let r=0;rt-r),["PropagatedPauliFrames {"]);for(t of r)e.push(` ${t}: `+this.ce.get(t));return e.push("}"),e.join("\n")}Hr(t){let r=this.ce.get(t);return r=void 0===r?new Y(new Map,new Set,[]):r}static de(r,e){var i=new N(new Map);let o=new Map;for(let t=0;tt[1]-r[1]);for(let r=t.yt.length-1;-1<=r;r--){var s,h=0<=r?t.yt[r]:new U,l=[...h.et.keys()];l.reverse();for(s of l){var f=h.et.get(s);if(f.R[0]===s){o.le(f.Z,[...f.R]);for(let t=f.m();0"X"===t[0])?c.fillStyle="red":Y.every(t=>"Y"===t[0])?c.fillStyle="green":Y.every(t=>"Z"===t[0])?c.fillStyle="blue":c.fillStyle="black",c.strokeStyle=c.fillStyle;var R,y,Z=Y.map(t=>t[1]);let n=0,s=0;for([R,y]of Z)n+=R,s+=y;n/=Z.length,s/=Z.length,Z.sort((t,r)=>{var[t,e]=t,[r,i]=r;let o=Math.atan2(e-s,t-n),a=Math.atan2(i-s,r-n);return t===n&&e===s&&(o=-100),r===n&&i===s&&(a=-100),o-a}),S(c,Z),c.globalAlpha*=.25,c.fill(),c.globalAlpha*=4,c.lineWidth=2,c.stroke(),c.lineWidth=1}for([l,[f,v]]of Y){var{dx:m,dy:p,_:I,A:b}=St(X,f+":"+v,M);if("X"===l)c.fillStyle="red";else if("Y"===l)c.fillStyle="green";else{if("Z"!==l)throw new Error("Not a pau)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(li: "+l);c.fillStyle="blue"}c.fillRect(f-m,v-p,I,b)}for(_ of Z=u.Hr(d.Gr).Kr){var[_,E]=w(_),{dx:A,dy:k,_:g,A:C}=St(X,_+":"+E,M);c.lineWidth=X<0?2:8,c.strokeStyle="magenta",c.strokeRect(_-A,E-k,g,C),c.lineWidth=1,c.fillStyle="black",c.fillRect(_-A,E-k,g,C)}}}let wt=!0;function D(t,r){t.save();try{wt&&r()}finally{t.restore()}}function ut(t){t.setTransform(1,0,0,1,0,0)}function Xt(Z,Y){let R=Y.qr,r=0;for(var t of R.yt)for(var e of t.it){var i=e.Z;"MARKX"!==i.name&&"MARKY"!==i.name&&"MARKZ"!==i.name||(r=Math.max(r,e.Y[0]+1))}let y=(t,r)=>[t*O-x,r*O-L],m=t=>{var r=R.Rt[2*t],t=R.Rt[2*t+1];return y(r,t)},p=new Map;for(let t=0;t{ut(Z),Z.clearRect(0,0,Z.canvas.width,Z.canvas.height),t=Y.jr,Z.setTransform(t,0,0,t,Y.Jr,Y.te);var[t,r]=ct(Y.Me,Y.Ze);let e=Y.Gr;for(let t=0;t<=Y.Gr;t++)for(var i of R.yt[t].it)if("POLYGON"===i.Z.name){e=t;break}var o,a,n,s,h=[...R.yt[e].it];h.sort((t,r)=>r.R.length-t.R.length);for(o of h)"POLYGON"===o.Z.name&&o.I(m,Z);D(Z,()=>{for(let t=0;t{Z.globalAlpha*=.25;for(var[t,r]of Y.Ye.values()){var[t,r]=y(t,r);Z.fillStyle="yellow",Z.fillRect(t-1.25*gt,r-1.25*gt,2.5*gt,2.5*gt)}}),D(Z,()=>{Z.globalAlpha*=.5;for(var[t,r]of Y.Re.values()){var[t,r]=y(t,r);Z.fillStyle="blue",Z.fillRect(t-1.25*gt,r-1.25*gt,2.5*gt,2.5*gt)}}),dt(Z,Y,m,p),void 0!==t&&(Z.save(),Z.globalAlpha*=.5,[h,t]=y(t,r),Z.fillStyle="red",Z.fillRect(h-gt,t-gt,2*gt,2*gt),Z.restore()),D(Z,()=>{var t,r,e,i,o,a;Z.globalAlpha*=.25,Z.fillStyle="blue",void 0!==Y.ye&&void 0!==Y.Me&&(t=Math.min(Y.Me,Y.ye),r=Math.max(Y.Me,Y.ye),e=Math.min(Y.Ze,Y.me),i=Math.max(Y.Ze,Y.me),--t,r+=1,--e,i+=1,t-=x,r-=x,e-=L,i-=L,Z.fillRect(t,e,r-t,i-e));for([o,a]of Y.pe){var[n,s]=y(o,a);Z.fillRect(n)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(-gt,s-gt,2*gt,2*gt)}})}),ut(Z);var M=vt(Z,Y,p,m,R.yt.length);Z.save();try{Z.strokeStyle="black",Z.translate(Math.floor(Z.canvas.width/2),0);for(let n=0;n0===t.Hr(r).Kr.size);0r.has(t))}}function Zt(r){let e=[1,0],i=[0,1];var o=(t,r)=>[t-r,t+r];r=(r%8+8)%8;for(let t=0;t[e[0]*t+i[0]*r,e[1]*t+i[1]*r]}function Yt(){try{return window.self===window.top}catch(t){}}class Rt{constructor(){this.be=!1,this._e=void 0}Ee(){this._e={Ae:!0}}ke(t){this._e=t}ge(){this._e=void 0}Ce(t,r){if(!r.startsWith("#"))throw new Error('"Expected a hash URL: '+{Se:t,Pe:r});if(Yt()&&this._e!==t)if(this.be)document.location.hash=r;else try{void 0===this._e?history.replaceState(t,"",r):(history.pushState(t,"",r),this._e=void 0)}catch(t){console.warn("Calling 'history.replaceState/pushState' failed. Falling back to setting location.hash.",t),this.be=!0,document.location.hash=r}}}function yt(t){return"#circuit="+(t=-1===(t=t.replaceAll("QUBIT_COORDS","Q").replaceAll("DETECTOR","DT").replaceAll("OBSERVABLE_INCLUDE","OI").replaceAll(", ",",").replaceAll(") ",")").replaceAll(" ","_").replaceAll("\n",";")).indexOf("%")&&-1===t.indexOf("&")?t:encodeURICompone)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(nt(t))}let r=document.getElementById("toolbox"),M=10.5,R=["H","S","R","M","MR","C","W","SC","MC","P","1-9"],mt=[1,2,2,2,2,1,2,2,2,-1,-1,-1];let pt=function(){var r=new Map([["0,0",B.get("H_YZ")],["0,1",B.get("H")],["0,2",B.get("H_XY")],["1,0",B.get("SQRT_X")],["1,1",B.get("SQRT_Y")],["1,2",B.get("S")],["2,0",B.get("RX")],["2,1",B.get("RY")],["2,2",B.get("R")],["3,0",B.get("MX")],["3,1",B.get("MY")],["3,2",B.get("M")],["4,0",B.get("MRX")],["4,1",B.get("MRY")],["4,2",B.get("MRZ")],["5,0",B.get("CX")],["5,1",B.get("CY")],["5,2",B.get("CZ")],["6,0",B.get("CXSWAP")],["6,1",B.get("SWAP")],["6,2",B.get("CZSWAP")],["7,0",B.get("SQRT_XX")],["7,1",B.get("SQRT_YY")],["7,2",B.get("SQRT_ZZ")],["8,0",B.get("MXX")],["8,1",B.get("MYY")],["8,2",B.get("MZZ")]]);let e=9;for(let t=0;t<4;t++)r.set(e+",0",B.get("MARKX").M(t)),r.set(e+",1",B.get("MARKY").M(t)),r.set(e+",2",B.get("MARKZ").M(t)),r.set(e+",-1",B.get("MARK").M(t)),e+=1;return r}();function It(t){var r,e=function(t){var r,e;if(!t.ctrlKey)return r=+t.zt.has("x"),e=+t.zt.)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(has("y"),t=+t.zt.has("z"),r&&!e&&!t||!r&&e&&t?{Oe:0,strength:Math.max(r,Math.min(e,t))}:!r&&e&&!t||r&&!e&&t?{Oe:1,strength:Math.max(e,Math.min(r,t))}:!r&&!e&&t||r&&e&&!t?{Oe:2,strength:Math.max(t,Math.min(r,e))}:void 0}(t),t=function(i){if(!i.ctrlKey){let e=void 0;for(let r=0;r=e.strength)&&(e={Te:r,strength:t/R[r].length})}return e}}(t);let i=e,o=(void 0!==t&&void 0===e&&(r=mt[t.Te],i=void 0===r?void 0:{strength:0,Oe:r}),void 0);return void 0!==i&&void 0!==t&&(r=t.Te+","+i.Oe,pt.has(r))&&(o=pt.get(r)),{Ne:e,De:i,xe:t,Le:o}}const bt=-O+Math.floor(O/4)+.5,_t=-O+Math.floor(O/4)+.5;var t=document.getElementById("btnInsertLayer"),Et=document.getElementById("btnDeleteLayer"),At=document.getElementById("btnUndo"),kt=document.getElementById("btnRedo"),Tt=document.getElementById("btnClearMarkers");const Nt=document.getElementById("btnShowHideImportExport");var Dt=document.getElementById("btnNextLayer"),)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(xt=document.getElementById("btnPrevLayer"),Lt=document.getElementById("btnRotate45"),Ft=document.getElementById("btnRotate45Counter"),e=document.getElementById("btnExport"),Ut=document.getElementById("btnImport"),Gt=document.getElementById("clear");const o=document.getElementById("txtStimCircuit");var Ht=document.getElementById("btnTimelineFocus"),zt=document.getElementById("btnClearTimelineFocus"),Kt=document.getElementById("btnClearSelectedMarkers");const Qt=document.getElementById("btnShowExamples"),$t=document.getElementById("examples-div");o.addEventListener("keyup",t=>t.stopPropagation()),o.addEventListener("keydown",t=>t.stopPropagation());let y=new class{constructor(t){this.rev=ft.Cr(""),this.canvas=t,this.Ze=void 0,this.Me=void 0,this.Fe=new nt,this.Gr=0,this.Re=new Map,this.Ye=new Map,this.ye=void 0,this.me=void 0,this.Ue=new lt(this.Ge(void 0)),this.Wr=void 0,this.Vr=void 0,this.Jr=0,this.te=0,this.jr=1,this.Ur=0}He(t){var r,e,i,o=this.ze(),a=o.yt[this.Gr],n=new Set,s=new Map;for(r of[["CX","revers)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(e"],["CY","reverse"],["XCY","reverse"],["CXSWAP","reverse"],["XCZ","reverse"],["XCY","reverse"],["YCX","reverse"],["SWAPCX","reverse"],["RX","MX"],["R","M"],["RY","MY"]])s.set(r[0],r[1]),s.set(r[1],r[0]);for(e of this.Re.keys()){var h=a.et.get(o.Ut().get(e));void 0!==h&&s.has(h.Z.name)&&n.add(h.R[0])}for(i of n){var l=a.et.get(i),f=s.get(l.Z.name);"reverse"===f?a.et.get(i).R.reverse():l.Z=B.get(f)}this.Ke(o,t)}Qe(t){var r=this.ze();let e=this.Gr;for(;e"MARKX"!==t.Z.name&&"MARKY"!==t.Z.name&&"MARKZ"!==t.Z.name);this.commit(r)}Je(i){var t=this.Me,r=this.Ze,o=this.ye,a=this.me,n=[];if(void 0!==t&&void 0!==o){var[s,h]=ct(o,a),l=Math.min(t,o),f=Math.max(t,o),v=Math.min(r,a),c=Math.max(r,a),t=O/4-gt;l+=t,f-=t,v+=t,c-=t,l=Math.floor(2*l/O+.5)/2,f=Math.floor(2*f/O+.5)/2,v=Math.floor(2*v/O+.5)/2,c=Math.floor(2*c/O+.5)/2;let e=1;l!=f&&v!=c||(e=2);for(let r=l;r<=f;r+=.5)for(let t=v;t<=c;t+=.5)r%1!=t%1||i&&(s%e!=r%e||h%e!=t%e)||n.push([r,t])}return n}ei(o,t,r){let e=this.ze()CRUMBLE_PART"); - result.append(R"CRUMBLE_PART();e=e.kt(o),!t&&r&&(this.Ye=(r=t=>{var r,e,i=new Map;for([r,e]of t.values())[r,e]=o(r,e),i.set(r+","+e,[r,e]);return i})(this.Ye),this.Re=r(this.Re)),this.Ke(e,t)}ii(t,r){let e=Zt(t),i=this.ze().kt(e).gt();this.ei((t,r)=>([t,r]=e(t,r),i(t,r)),r,!0)}oi(t){this.Gr=Math.max(t,0),this.Be()}ai(t,r,e){r||e||this.Re.clear();for(var[i,o]of t){var a=i+","+o;e&&this.Re.has(a)?this.Re.delete(a):this.Re.set(a,[i,o])}this.Be()}ni(t){var r,e=new Map,i=this.ze().yt[this.Gr];for(r of[...t]){var o=i.et.get(r);if(void 0!==o)if("RX"===o.Z.name||"MX"===o.Z.name||"MRX"===o.Z.name)e.set(r,"X");else if("RY"===o.Z.name||"MY"===o.Z.name||"MRY"===o.Z.name)e.set(r,"Y");else if("R"===o.Z.name||"M"===o.Z.name||"MR"===o.Z.name)e.set(r,"Z");else if("MXX"===o.Z.name||"MYY"===o.Z.name||"MZZ"===o.Z.name){var a,n=o.Z.name[1];for(a of o.R)e.set(a,n)}else if(o.Z.name.startsWith("MPP:")&&void 0===o.Z.h&&o.R.length===o.Z.name.length-4){var s=o.Z.name.substring(4);for(let t=0;t{var[t,e]=t,[r,i]=r;return Math.atan2(e-a,t-o)-Math.atan2(i-a,r-o)});var s=this.ze().Ft(this.Re.values()),h=s.Ut(),l=new Uint32Array(this.Re.size);for(let t=0;t!t.Z.name.startsWith("MARK")||t.Y[0]!==r)}this.Ke(i,t)}Xi(t,i){var r,e=this.ze(),o=N.de(e,i),a=this.Gr,n=0===a?new Y(new Map,new Set,[]):o.Hr(a-.5),s=o.Hr(a+.5),h=e.yt[a],l=new Set;for(r of new Set([...n.zr.keys(),...s.zr.keys()]))if(!l.has(r)){var f=n.zr.get(r),v=s.zr.get(r),c=h.et.get(r);if(void 0!==c){var d=c.Z.name;let e=void 0;if("R"===d||"M"===d||"MR"===d)e="Z";else if("RX"===d||"MX"===d||"MRX"===d)e="X";else{if("RY"!==d&&"MY"!==d&&"MRY"!==d){if("MXX"===d||"MYY"===d||"MZZ"===d){e=d[1];let t=0;for(var w of c.R){if(l.has(w)){t=-1;break}t+=n.zr.get(w)===e}if(2===t)for(var u of c.R)l.add(u),h.it.push(new F(B.get("MARK"+e),"",new Float32)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(Array([i]),new Uint32Array([u])));continue}if(d.startsWith("MPP:")){let r=0;for(let t=0;tc.R.length/2)for(let t=0;t{var t,r,{Nt:e,Dt:i}=n.Pt(!1);for(let t=0;tt.Z.name!==e.Z.name||t.Y[0]!==e.Y[0])}this.Ke(a,t)}}}(document.getElementById("cvn"));function v(t){return(t-y.Jr)/y.jr+bt}function m(t){return(t-y.te)/y.jr+_t}function Bt(){var t=y.ze().xt().replaceAll("\nPOLYGON","\n#!pragma POLYGON").replaceAll("\nERR","\n#!pragma ERR").replaceAll("\nMARK","\n#!pragma MARK"),r=o;r.value=t+"\n",r.focus(),r.select()}e.addEventListener("click",t=>{Bt()}),Ut.addEventListener("click",t=>{var r=o.value,r=u.It(r);y.commit(r)}),Nt.addEventListener("click",t=>{var r=document.getElementById("divImpor)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(tExport");"none"===r.style.display?(r.style.display="block",Nt.textContent="Hide Import/Export",Bt()):(r.style.display="none",Nt.textContent="Show Import/Export",o.value=""),setTimeout(()=>{window.scrollTo(0,0)},0)}),Gt.addEventListener("click",t=>{y.ti()}),At.addEventListener("click",t=>{y.Nr()}),Ht.addEventListener("click",t=>{y.Ye=new Map(y.Re.entries()),y.Be()}),Kt.addEventListener("click",t=>{y.hi(!1),y.Be()}),Qt.addEventListener("click",t=>{"none"===$t.style.display?($t.style.display="block",Qt.textContent="Hide Example Circuits"):($t.style.display="none",Qt.textContent="Show Example Circuits")}),zt.addEventListener("click",t=>{y.Ye=new Map,y.Be()}),kt.addEventListener("click",t=>{y.Dr()}),Tt.addEventListener("click",t=>{y.ri()}),Lt.addEventListener("click",t=>{y.ii(1,!1)}),Ft.addEventListener("click",t=>{y.ii(-1,!1)}),t.addEventListener("click",t=>{y.Ve(!1)}),Et.addEventListener("click",t=>{y.We(!1)}),Dt.addEventListener("click",t=>{y.oi(y.Gr+1)}),xt.addEventListener("click",t=>{y.oi(y.Gr-1)}),window.a)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(ddEventListener("resize",t=>{y.canvas.width=y.canvas.scrollWidth,y.canvas.height=y.canvas.scrollHeight,y.Be()}),y.canvas.addEventListener("mousemove",t=>{y.Wr=t.offsetX,y.Vr=t.offsetY,y.Me=v(t.offsetX),y.Ze=m(t.offsetY);var r=y.canvas.width/2;qt&&1===t.buttons?y.oi(Math.floor((t.offsetX-r)/8)):y.Be()});let qt=!1;function Wt(){var t=y.canvas.width/2,r=y.canvas.height,e=y.jr,i=-1*O-bt,o=T*O-bt;y.Jr=Math.max(t-o*e,Math.min(-i*e,y.Jr)),y.te=Math.max(r-o*e,Math.min(-i*e,y.te)),y.Ur=Math.max(0,y.Ur)}y.canvas.addEventListener("mousedown",t=>{y.Wr=t.offsetX,y.Vr=t.offsetY,y.Me=v(t.offsetX),y.Ze=m(t.offsetY),y.ye=v(t.offsetX),y.me=m(t.offsetY);var r=y.canvas.width/2;(qt=t.offsetY<20&&t.offsetX>r&&1===t.buttons)?y.oi(Math.floor((t.offsetX-r)/8)):y.Be()}),y.canvas.addEventListener("mouseup",t=>{var r=y.Je(t.altKey);y.ye=void 0,y.me=void 0,y.Wr=t.offsetX,y.Vr=t.offsetY,y.Me=v(t.offsetX),y.Ze=m(t.offsetY),y.ai(r,t.shiftKey,t.ctrlKey),1===t.buttons&&(qt=!1)}),y.canvas.addEventListener("wheel",t=>{t.preventDefault();var r,e)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(=y.canvas.width/2;t.offsetX>e?(e=t,y.Ur+=e.deltaY):((e=t).ctrlKey||e.metaKey?(t=e.deltaY<0?1.05:1/1.05,r=(t=Math.max(.25,Math.min(4,y.jr*t)))/y.jr,y.jr=t,y.Jr=e.offsetX-(e.offsetX-y.Jr)*r,y.te=e.offsetY-(e.offsetY-y.te)*r):(y.Jr-=e.deltaX,y.te-=e.deltaY),y.Me=v(e.offsetX),y.Ze=m(e.offsetY)),Wt(),y.Be()},{passive:!1});let Vt=void 0;async function jt(){let e=y.ze();e.yt=[e.yt[y.Gr]],0{var r=e.Rt[2*t],t=e.Rt[2*t+1];return y.Re.has(r+","+t)}),[r,t]=C(y.Re.values()),e=e.St(-r,-t));var t,r=e.xt();Vt=r;try{await navigator.clipboard.writeText(r)}catch(t){console.warn("Failed to write to clipboard. Using fallback emulated clipboard.",t)}}async function Jt(e){let i;try{i=await navigator.clipboard.readText()}catch(t){console.warn("Failed to read from clipboard. Using fallback emulated clipboard.",t),i=Vt}if(void 0!==i){let r=u.It(i);if(1!==r.yt.length)throw new Error(i);let t=y.ze();0y.ii(-1,t)),o.set("t",t=>y.ii(1,t)),o.set("escape",()=>y.$e()),o.set("delete",t=>y.qe(t)),o.set("backspace",t=>y.qe(t)),o.set("ctrl+delete",t=>y.We(t)),o.set("ctrl+insert",t=>y.Ve(t)),o.set("ctrl+backspace",t=>y.We(t)),o.set("ctrl+z",t=>{t||y.Nr()}),o.set("ctrl+y",t=>{t||y.Dr()}),o.set("ctrl+shift+z",t=>{t||y.Dr()}),o.set("ctrl+c",async t=>{await jt()}),o.set("ctrl+v",Jt),o.set("ctrl+x",async t=>{var r;await jt(),0===y.Re.size?((r=y.ze()).yt[y.Gr].et.clear(),r.yt[y.Gr].it.length=0,y.Ke(r,t)):y.qe(t)}),o.set("l",t=>{t||(y.Ye=new Map(y.Re.entries()),y.Be())}),o.set(" ",t=>y.hi(t));for(let[t,r]of[["1",0],["2",1],["3",2],["4",3],["5",4],["6",5],["7",6],["8",7],["9",8],["0",9],["-",10],[")CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(=",11],["\\",12],["`",13]])o.set(""+t,t=>y.si(t,r)),o.set(t+"+x",t=>y.ci(t,B.get("MARKX").M(r))),o.set(t+"+y",t=>y.ci(t,B.get("MARKY").M(r))),o.set(t+"+z",t=>y.ci(t,B.get("MARKZ").M(r))),o.set(t+"+d",t=>y.ui(t,r)),o.set(t+"+o",t=>y.di(t,r)),o.set(t+"+j",t=>y.Mi(t,r)),o.set(t+"+k",t=>y.Xi(t,r));let r=.25;function a(t,r,e=void 0){for(var i of t){if(o.has(i))throw new Error("Chord collision: "+i);o.set(i,t=>y.ci(t,B.get(r)))}void 0!==e&&a(t.map(t=>"shift+"+t),e)}return o.set("p",t=>y.ci(t,B.get("POLYGON"),[1,0,0,r])),o.set("alt+p",t=>y.ci(t,B.get("POLYGON"),[0,1,0,r])),o.set("shift+p",t=>y.ci(t,B.get("POLYGON"),[0,0,1,r])),o.set("p+x",t=>y.ci(t,B.get("POLYGON"),[1,0,0,r])),o.set("p+y",t=>y.ci(t,B.get("POLYGON"),[0,1,0,r])),o.set("p+z",t=>y.ci(t,B.get("POLYGON"),[0,0,1,r])),o.set("p+x+y",t=>y.ci(t,B.get("POLYGON"),[1,1,0,r])),o.set("p+x+z",t=>y.ci(t,B.get("POLYGON"),[1,0,1,r])),o.set("p+y+z",t=>y.ci(t,B.get("POLYGON"),[0,1,1,r])),o.set("p+x+y+z",t=>y.ci(t,B.get("POLYGON"),[1,1,1,r])),o.set("m+p+x",t=>y.ci(t,f("X")CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(.repeat(y.Re.size)),[])),o.set("m+p+y",t=>y.ci(t,f("Y".repeat(y.Re.size)),[])),o.set("m+p+z",t=>y.ci(t,f("Z".repeat(y.Re.size)),[])),o.set("f",t=>y.He(t)),o.set("g",t=>y.Qe(t)),o.set("shift+>",t=>y.ei((t,r)=>[t+1,r],t,!1)),o.set("shift+<",t=>y.ei((t,r)=>[t-1,r],t,!1)),o.set("shift+v",t=>y.ei((t,r)=>[t,r+1],t,!1)),o.set("shift+^",t=>y.ei((t,r)=>[t,r-1],t,!1)),o.set(">",t=>y.ei((t,r)=>[t+1,r],t,!1)),o.set("<",t=>y.ei((t,r)=>[t-1,r],t,!1)),o.set("v",t=>y.ei((t,r)=>[t,r+1],t,!1)),o.set("^",t=>y.ei((t,r)=>[t,r-1],t,!1)),o.set(".",t=>y.ei((t,r)=>[t+.5,r+.5],t,!1)),a(["h","h+y","h+x+z"],"H","H"),a(["h+z","h+x+y"],"H_XY","H_XY"),a(["h+x","h+y+z"],"H_YZ","H_YZ"),a(["s+x","s+y+z"],"SQRT_X","SQRT_X_DAG"),a(["s+y","s+x+z"],"SQRT_Y","SQRT_Y_DAG"),a(["s","s+z","s+x+y"],"S","S_DAG"),a(["r+x","r+y+z"],"RX"),a(["r+y","r+x+z"],"RY"),a(["r","r+z","r+x+y"],"R"),a(["m+x","m+y+z"],"MX"),a(["m+y","m+x+z"],"MY"),a(["m","m+z","m+x+y"],"M"),a(["m+r+x","m+r+y+z"],"MRX"),a(["m+r+y","m+r+x+z"],"MRY"),a(["m+r","m+r+z","m+r+x+y"],"MR"),a([)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART("c"],"CX","CX"),a(["c+x"],"CX","CX"),a(["c+y"],"CY","CY"),a(["c+z"],"CZ","CZ"),a(["j+x"],"X","X"),a(["j+y"],"Y","Y"),a(["j+z"],"Z","Z"),a(["c+x+y"],"XCY","XCY"),a(["alt+c+x"],"XCX","XCX"),a(["alt+c+y"],"YCY","YCY"),a(["w"],"SWAP","SWAP"),a(["w+x"],"CXSWAP",void 0),a(["c+w+x"],"CXSWAP",void 0),a(["i+w"],"ISWAP","ISWAP_DAG"),a(["w+z"],"CZSWAP",void 0),a(["c+w+z"],"CZSWAP",void 0),a(["c+w"],"CZSWAP",void 0),a(["c+t"],"C_XYZ","C_ZYX"),a(["c+s+x"],"SQRT_XX","SQRT_XX_DAG"),a(["c+s+y"],"SQRT_YY","SQRT_YY_DAG"),a(["c+s+z"],"SQRT_ZZ","SQRT_ZZ_DAG"),a(["c+s"],"SQRT_ZZ","SQRT_ZZ_DAG"),a(["c+m+x"],"MXX","MXX"),a(["c+m+y"],"MYY","MYY"),a(["c+m+z"],"MZZ","MZZ"),a(["c+m"],"MZZ","MZZ"),o}();function rr(r){if(y.Fe.jt(r),"keydown"===r.type){if("q"===r.key.toLowerCase())return e=r.shiftKey?5:1,void y.oi(y.Gr-e);if("e"===r.key.toLowerCase())return e=r.shiftKey?5:1,void y.oi(y.Gr+e);if("Home"===r.key)return y.oi(0),void r.preventDefault();if("End"===r.key)return y.oi(y.ze().yt.length-1),void r.preventDefault()}var t=y.Fe.Bt;if(0!)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(==t.length){for(var e=t[t.length-1];0{y.Ue.set(y.Ge(void 0));var t=y.Fe.qt(!1),a=(r.width=r.scrollWidth,r.height=r.scrollHeight,r.getContext("2d"));a.clearRect(0,0,r.width,r.height),a.textAlign="right",a.textBaseline="middle",a.fillText("X",7.5,24.5),a.fillText("Y",7.5,56.5),a.fillText("Z",7.5,88.5),a.textAlign="center",a.textBaseline="bottom";for(let t=0;t{try{var t,r=(()=>{var t=document.location.hash.substring(1),r=new Map;if(""!==t)for(var e of t.split("&")){var i,o=e.indexOf("=");-1!==o&&(i=e.substring(0,o),e=decodeURIComponent(e.substring(o+1)),r.set(i,e))}return r})(),e=(r.has("circuit")||("[[[DEFAULT-CIRCUIT-CONTENT-LITERAL]]]"===(t=document.getElementById("txtDefaultCircuit")).value.replaceAll("_","-")?r.set("circuit",""):r.set("circuit",t.value)),u.It(r.get("circuit"))),i=e.xt();er.clear(i),e.yt.every(t=>t.ut())&&1===r.size&&i===r.get("circuit")?ir.ge():ir.Ce(i,yt(i))}catch(t){throw new Error(t)}},window.addEventListener("popstate",e),e(),er.kr().Yr().Zr(1).subscribe(t=>{ir.Ce(t,yt(t))})}y.Ue.mr().subscribe(r=>requestAnimationFrame(()=>{var t=Xt(y.canvas.getContext("2d"),r);y.Ur>t&&(y.Ur=t)})),window.addEventListener("focus",()=>{y.Fe.Vt()}),window.addEventListener("blur",()=>{y.Fe.Vt()});for(let r of document.getElementById("examples-div").querySelectorAll("a"))r.onclick=t=>{if(!(t.shiftKey||t.ctrlKey||t.altKey||0!==t.button))return t=r.)CRUMBLE_PART"); - result.append(R"CRUMBLE_PART(href.split("#circuit=")[1],y.rev.commit(t),!1}; + result.append(R"CRUMBLE_PART(let e=!1,i=!1,o,a,t=this.subscribe(t=>{o=t,e=!0,i&&r(h(o,a))}),n=s.subscribe(t=>{a=t,i=!0,e&&r(h(o,a))});return()=>{t(),n()}})}static cr(){return new i(t=>{let r,e=!1;return(r=()=>{e||(t(void 0),window.requestAnimationFrame(r))})(),()=>{e=!0}})}dr(){return new i(e=>{let i=()=>{},o=!1,t=this.subscribe(t=>{var r;o||(r=i,i=t.subscribe(e),r())});return()=>{o=!0,i(),t()}})}wr(r){return this.map(t=>(r(t),t))}ur(){return new i(r=>{let e=[];return e.push(this.subscribe(t=>e.push(t.subscribe(r)))),()=>{for(var t of e)t()}})}Xr(a){return new i(t=>{let r=void 0,e=!1,i=new ht(()=>{e||t(r)},a),o=this.subscribe(t=>{r=t,i.sr()});return()=>{e=!0,o()}})}static Mr(r,e){return new i(t=>(r.addEventListener(e,t),()=>r.removeEventListener(e,t)))}Zr(t){return new i(r=>{let e=t;return this.subscribe(t=>{0t===r);return new i(r=>{let e=!1,i=void 0;return this.subscribe(t=>{e&&o(i,t)||(i=t,e=!0,r(t))})})}}class lt{constructor(){this.Rr=[],this.yr=new i(t=>{this.Rr.push(t);let r=!1;return()=)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(>{r||(r=!0,this.Rr.splice(this.Rr.indexOf(t),1))}})}mr(){return this.yr}send(t){for(var r of this.Rr)r(t)}}class ft{constructor(t=void 0){this.pr=t,this.Ir=new lt,this.yr=new i(t=>(t(this.pr),this.Ir.mr().subscribe(t)))}mr(){return this.yr}set(t){this.pr=t,this.Ir.send(t)}get(){return this.pr}}class vt{constructor(t,r,e){if(r<0||r>=t.length)throw new Error("Bad index: "+{history:t,index:r,br:e});if(!Array.isArray(t))throw new Error("Bad history: "+{history:t,index:r,br:e});this.history=t,this.index=r,this.br=e,this._r=new lt,this.Er=new ft(this.history[this.index])}Ar(){return this._r.mr()}kr(){return this.Er.mr()}gr(){return this.Er.get()}static Cr(t){return new vt([t],0,!1)}Sr(){return 0===this.index&&!this.br}Pr(){return this.index===this.history.length-1}clear(t){this.history=[t],this.index=0,this.br=!1,this.Er.set(t),this._r.send(t)}Or(t){this.br=t!==this.history[this.index],this._r.send(void 0)}Tr(){this.br=!1;var t=this.history[this.index];return this.Er.set(t),this._r.send(t),t}commit(t){t===this.hist)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(ory[this.index]?this.Tr():(this.br=!1,this.index+=1,this.history.splice(this.index,this.history.length-this.index),this.history.push(t),this.Er.set(t),this._r.send(t))}Nr(){if(!this.br){if(0===this.index)return;--this.index}this.br=!1;var t=this.history[this.index];return this.Er.set(t),this._r.send(t),t}Dr(){var t;if(this.index+1!==this.history.length)return this.index+=1,this.br=!1,t=this.history[this.index],this.Er.set(t),this._r.send(t),t}toString(){return"Revision("+G({index:this.index,count:this.history.length,Lr:this.br,head:this.history[this.index]})+")"}Gt(t){return t instanceof vt&&this.index===t.index&&this.br===t.br&&w(this.history,t.history)}}const Tt=32,Nt=40;class Dt{constructor(t,r,e){this.Fr=t,this.Ur=r,this.Gr=e}}function ct(t,e,N,o,i){var D,r=Math.floor(t.canvas.width/2),a=e.Hr();a.sort((t,r)=>{var[t,e]=o(t),[r,i]=o(r);return e!==i?e-i:t-r});let n=new Map,x=void 0,s=0,h=0,l=0,f=0;for(D of a){var[L,v]=o(D);h+=Tt,x!==v?(x=v,s=1.5*r,l=Math.max(l,f),f=0,h+=.25*Tt):(s+=.25*St,f++),n.set(L+","+v,)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART([Math.round(s)+.5,Math.round(h)+.5])}const c=Tt+Math.ceil(St*l*.25);var d=Math.floor(t.canvas.width/4/c);let w=e.zr-d+1,u=Math.max(0,Math.min(w,i-2*d+1));var d=Math.max(0,h-t.canvas.height+Tt),F=Math.max(-d,Math.min(0,e.Kr??0)),X=(i-1-e.zr-(u-w))*c,X=-Math.max(0,X-.5*r+2*c),U=Math.max(0,(u-1)*c),M=Math.max(X,Math.min(U,e.Qr??0));if(0!==F||0!==M)for(var[G,[H,z]]of n)n.set(G,[H+M,z+F]);var K=1.5*r+(w-1-e.zr)*c;let Q=t=>{t-=e.zr;return(t-=u-w)*c},Z=(t,r)=>{var[t,e]=o(t);return[t,e,r]=[[t,e,r]][0],t=t+","+e,n.has(t)?([e,t]=n.get(t),[e+Q(r),t]):[void 0,void 0]};t.save();try{t.clearRect(r,0,r,t.canvas.height),t.save(),t.beginPath(),t.rect(K,0,t.canvas.width-K,t.canvas.height),t.clip();var $,B,q=new Map;for([$,B]of N.entries()){k=j=A=ft=lt=ht=st=E=S=C=nt=at=ot=g=_=b=it=et=rt=tt=J=I=p=V=W=m=y=R=Y=void 0;var Y=t,R=Z,y=B,m=$,W=0,V=i,p=c,I=q;for(let o=W-1;o<=V;o++){I.has(o)||I.set(o,new Map);var b,_,E,A,j,k,J=I.get(o),tt=y.$r(o+.5),rt=y.$r(o);for([b,_]of tt.Br.entries()){let{dx:t,dy:r,_:e,A:i}=Ot(m,b,J);0<=m&&m<4?(t=0,e)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(=p,i=5,0===m?r=10:1===m?r=5:2===m?r=0:3===m&&(r=-5)):t-=p/2;var[et,it]=R(b,o);if(void 0!==et&&void 0!==it){if("X"===_)Y.fillStyle="red";else if("Y"===_)Y.fillStyle="green";else{if("Z"!==_)throw new Error("Not a pauli: "+_);Y.fillStyle="blue"}Y.fillRect(et-t,it-r,e,i)}}for(E of rt.qr){var{dx:g,dy:ot,_:at,A:nt}=Ot(m,E,J),[C,S]=(g-=p/2,R(E,o-.5));void 0!==C&&void 0!==S&&(Y.strokeStyle="magenta",Y.lineWidth=8,Y.strokeRect(C-g,S-ot,at,nt),Y.lineWidth=1,Y.fillStyle="black",Y.fillRect(C-g,S-ot,at,nt))}for({Wr:A,Vr:j,color:k}of rt.jr){var[st,ht]=R(A,o),[lt,ft]=R(j,o);"X"===k?Y.strokeStyle="red":"Y"===k?Y.strokeStyle="green":"Z"===k?Y.strokeStyle="blue":Y.strokeStyle="purple",Y.lineWidth=8,Pt(Y,st,ht,lt,ft),Y.lineWidth=1}}}t.globalAlpha*=.5,t.fillStyle="black";var vt,P,ct=Q(e.zr)+1.5*r-c/2+M;t.fillRect(ct,0,c,t.canvas.height),t.globalAlpha*=2,t.strokeStyle="black",t.fillStyle="black";for(vt of a){var[dt,wt]=Z(vt,-1),[ut,Xt]=Z(vt,i);t.beginPath(),t.moveTo(dt,wt),t.lineTo(ut,Xt),t.stroke()}for(let r=0;rZ(t,r),Zt=e.Jr.yt[r];if(void 0!==Zt)for(var Yt of Zt.nt())Yt.I(Mt,t)}t.restore(),t.strokeStyle="black",t.fillStyle="black",t.textAlign="right",t.textBaseline="middle";for(P of a){var[Rt,yt]=Z(P,u-1),mt=(Rt-=M,e.Jr.Rt[2*P]),pt=e.Jr.Rt[2*P+1];t.fillText(mt+`,${pt}:`,Rt,yt)}t.globalAlpha=.5;var It,bt=e.te,_t=e.re,O=e.ee;for(It of a){var[Et,T]=Z(It,u-1),[At,kt]=(Et-=M,o(It)),gt=At*O+e.ie,Ct=kt*O+e.oe;bt>t.canvas.width/2&&_t>=T-.55*Tt&&_t<=T+.55*Tt&&(t.beginPath(),t.moveTo(Et,T),t.lineTo(gt,Ct),t.stroke(),t.fillStyle="black",t.fillRect(gt-Nt/2*O,Ct-Nt/2*O,Nt*O,Nt*O),t.fillRect(t.canvas.width/2,T-Tt/3,t.canvas.width/2,2*Tt/3))}}finally{t.restore()}return new Dt(X,U,d)}class Z{constructor(t,r){if(32 32");this.t=r,this.ae=t,this.ne=new Uint32Array(r),this.se=new Uint32Array(r),this.flags=new Uint32Array(r)}st(){var r=new Z(this.ae,this.t);for(let t=0;t>=1,r>>=1,e>>=1,i>>=1}return s}static le(e){var t=e.length;if(0===t)throw new Error("strings.length === 0");var r,i=e[0].length;for(r of e)if(r.length!==i)throw new Error("Inconsistent string length.");var o=new Z(t,i);for(let r=0;r>e)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(&1,o=this.ne[t]>>e&1,a=this.se[t]>>e&1;r+="_XZY!%$&"[o+2*a+4*i]}t.push(r)}return t}static ve(e,i){var o=new Z(e.length,i.length);for(let r=0;rt-r),["Propaga)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(tedPauliFrames {"]);for(t of r)e.push(` ${t}: `+this.Xe.get(t));return e.push("}"),e.join("\n")}$r(t){let r=this.Xe.get(t);return r=void 0===r?new Y(new Map,new Set,[]):r}static Me(r,e){var i=new D(new Map);let o=new Map;for(let t=0;tt[1]-r[1]);for(let r=t.yt.length-1;-1<=r;r--){var s,h=0<=r?t.yt[r]:new U,l=[...h.et.keys()];l.reverse();for(s of l){var f=h.et.get(s);if(f.R[0]===s){o.de(f.Z,[...f.R]);for(let t=f.m();0"X"===t[0])?c.fillStyle="red":Y.every(t=>"Y"===t[0])?c.fillStyle="green":Y.every(t=>"Z"===t[0])?c.fillStyle="blue":c.fillStyle="black",c.strokeStyle=c.fillStyle;var R,y,Z=Y.map(t=>t[1]);let n=0,s=0;for([R,y]of Z)n+=R,s+=y;n/=Z.length,s/=Z.length,Z.sort((t,r)=>{var[t,e]=t,[r,i]=r;let o=Math.atan2(e-s,t-)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(n),a=Math.atan2(i-s,r-n);return t===n&&e===s&&(o=-100),r===n&&i===s&&(a=-100),o-a}),S(c,Z),c.globalAlpha*=.25,c.fill(),c.globalAlpha*=4,c.lineWidth=2,c.stroke(),c.lineWidth=1}for([l,[f,v]]of Y){var{dx:m,dy:p,_:I,A:b}=Ot(X,f+":"+v,M);if("X"===l)c.fillStyle="red";else if("Y"===l)c.fillStyle="green";else{if("Z"!==l)throw new Error("Not a pauli: "+l);c.fillStyle="blue"}c.fillRect(f-m,v-p,I,b)}for(_ of Z=u.$r(d.zr).qr){var[_,E]=w(_),{dx:A,dy:k,_:g,A:C}=Ot(X,_+":"+E,M);c.lineWidth=X<0?2:8,c.strokeStyle="magenta",c.strokeRect(_-A,E-k,g,C),c.lineWidth=1,c.fillStyle="black",c.fillRect(_-A,E-k,g,C)}}}let ut=!0;function x(t,r){t.save();try{ut&&r()}finally{t.restore()}}function Xt(t){t.setTransform(1,0,0,1,0,0)}function Mt(Z,Y){let R=Y.Jr,r=0;for(var t of R.yt)for(var e of t.it){var i=e.Z;"MARKX"!==i.name&&"MARKY"!==i.name&&"MARKZ"!==i.name||(r=Math.max(r,e.Y[0]+1))}let y=(t,r)=>[t*O-L,r*O-H],m=t=>{var r=R.Rt[2*t],t=R.Rt[2*t+1];return y(r,t)},p=new Map;for(let t=0;t{Xt(Z),Z.clearRect(0,0,Z.canvas.width,Z.canvas.height),x(Z,()=>{Z.fillStyle="black";let r=.5;Y.ee<.85&&(r=1),Y.ee<.3&&(r=2),Z.save(),Z.beginPath(),Z.rect(N,0,Z.canvas.width-N,Z.canvas.height),Z.clip();for(let t=0;tr.R.length-t.R.length);for(o of h)"POLYGON"===o.Z.name&&o.I(m,Z);x(Z,()=>{Z.strokeStyle="black";for(let r=0;r{Z.globalAlpha*=.25;for(var[t,r]of Y.pe.values()){var[t,r]=y(t,r);Z.fillStyle="yellow",Z.fillRect(t-1.25*St,r-1.25*St,2.5*St,2.5*St)})CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(}),x(Z,()=>{Z.globalAlpha*=.5;for(var[t,r]of Y.Ie.values()){var[t,r]=y(t,r);Z.fillStyle="blue",Z.fillRect(t-1.25*St,r-1.25*St,2.5*St,2.5*St)}}),wt(Z,Y,m,p),void 0!==t&&(Z.save(),Z.globalAlpha*=.5,[h,t]=y(t,r),Z.fillStyle="red",Z.fillRect(h-St,t-St,2*St,2*St),Z.restore()),x(Z,()=>{var t,r,e,i,o,a;Z.globalAlpha*=.25,Z.fillStyle="blue",void 0!==Y.be&&void 0!==Y.ye&&(t=Math.min(Y.ye,Y.be),r=Math.max(Y.ye,Y.be),e=Math.min(Y.me,Y._e),i=Math.max(Y.me,Y._e),--t,r+=1,--e,i+=1,t-=L,r-=L,e-=H,i-=H,Z.fillRect(t,e,r-t,i-e));for([o,a]of Y.Ee){var[n,s]=y(o,a);Z.fillRect(n-St,s-St,2*St,2*St)}})}),Xt(Z);var M=ct(Z,Y,p,m,R.yt.length);Z.save();try{Z.strokeStyle="black",Z.translate(Math.floor(Z.canvas.width/2),0);for(let n=0;n0===t.$r(r).qr.size);0r.has(t))}}function Yt(r){let e=[1,0],i=[0,1];var o=(t,r)=>[t-r,t+r];r=(r%8+8)%8;for(let t=0;t[e[0]*t+i[0]*r,e[1]*t+i[1]*r]}const o=Object.freeze({ke:"timeslice",ge:"timeline"});class Rt{constructor(t,r,e,i,o){this.screenX=t,this.screenY=r,this.offsetX=e,this.offsetY=i,this.Ce=o}}function yt(){try{return window.self===window.top}catch(t){}}class mt{constructor(){this.Se=!1,this.Pe=void 0}Oe(){this.Pe={Te:!)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(0}}Ne(t){this.Pe=t}De(){this.Pe=void 0}xe(t,r){if(!r.startsWith("#"))throw new Error('"Expected a hash URL: '+{Le:t,Fe:r});if(yt()&&this.Pe!==t)if(this.Se)document.location.hash=r;else try{void 0===this.Pe?history.replaceState(t,"",r):(history.pushState(t,"",r),this.Pe=void 0)}catch(t){console.warn("Calling 'history.replaceState/pushState' failed. Falling back to setting location.hash.",t),this.Se=!0,document.location.hash=r}}}function pt(t){return"#circuit="+(t=-1===(t=t.replaceAll("QUBIT_COORDS","Q").replaceAll("DETECTOR","DT").replaceAll("OBSERVABLE_INCLUDE","OI").replaceAll(", ",",").replaceAll(") ",")").replaceAll(" ","_").replaceAll("\n",";")).indexOf("%")&&-1===t.indexOf("&")?t:encodeURIComponent(t))}let r=document.getElementById("toolbox"),M=10.5,R=["H","S","R","M","MR","C","W","SC","MC","P","1-9"],It=[1,2,2,2,2,1,2,2,2,-1,-1,-1];let bt=function(){var r=new Map([["0,0",B.get("H_YZ")],["0,1",B.get("H")],["0,2",B.get("H_XY")],["1,0",B.get("SQRT_X")],["1,1",B.get("SQRT_Y")],["1,2",B.get("S")],["2,0",B.ge)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(t("RX")],["2,1",B.get("RY")],["2,2",B.get("R")],["3,0",B.get("MX")],["3,1",B.get("MY")],["3,2",B.get("M")],["4,0",B.get("MRX")],["4,1",B.get("MRY")],["4,2",B.get("MRZ")],["5,0",B.get("CX")],["5,1",B.get("CY")],["5,2",B.get("CZ")],["6,0",B.get("CXSWAP")],["6,1",B.get("SWAP")],["6,2",B.get("CZSWAP")],["7,0",B.get("SQRT_XX")],["7,1",B.get("SQRT_YY")],["7,2",B.get("SQRT_ZZ")],["8,0",B.get("MXX")],["8,1",B.get("MYY")],["8,2",B.get("MZZ")]]);let e=9;for(let t=0;t<4;t++)r.set(e+",0",B.get("MARKX").M(t)),r.set(e+",1",B.get("MARKY").M(t)),r.set(e+",2",B.get("MARKZ").M(t)),r.set(e+",-1",B.get("MARK").M(t)),e+=1;return r}();function _t(t){var r,e=function(t){var r,e;if(!t.ctrlKey)return r=+t.zt.has("x"),e=+t.zt.has("y"),t=+t.zt.has("z"),r&&!e&&!t||!r&&e&&t?{Ue:0,strength:Math.max(r,Math.min(e,t))}:!r&&e&&!t||r&&!e&&t?{Ue:1,strength:Math.max(e,Math.min(r,t))}:!r&&!e&&t||r&&e&&!t?{Ue:2,strength:Math.max(t,Math.min(r,e))}:void 0}(t),t=function(i){if(!i.ctrlKey){let e=void 0;for(let r=0;r=e.strength)&&(e={Ge:r,strength:t/R[r].length})}return e}}(t);let i=e,o=(void 0!==t&&void 0===e&&(r=It[t.Ge],i=void 0===r?void 0:{strength:0,Ue:r}),void 0);return void 0!==i&&void 0!==t&&(r=t.Ge+","+i.Ue,bt.has(r))&&(o=bt.get(r)),{He:e,ze:i,Ke:t,Qe:o}}const Et=-O+Math.floor(O/4)+.5,At=-O+Math.floor(O/4)+.5;var t=document.getElementById("btnInsertLayer"),kt=document.getElementById("btnDeleteLayer"),gt=document.getElementById("btnUndo"),Ct=document.getElementById("btnRedo"),xt=document.getElementById("btnClearMarkers");const Lt=document.getElementById("btnShowHideImportExport");var Ft=document.getElementById("btnNextLayer"),Ut=document.getElementById("btnPrevLayer"),Gt=document.getElementById("btnRotate45"),Ht=document.getElementById("btnRotate45Counter"),zt=document.getElementById("btnExport"),Kt=document.getElementById("btnImport"),Qt=document.getElementById("clear");const e=document.getElementById("txtStimCircuit");var $t=documen)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(t.getElementById("btnTimelineFocus"),Bt=document.getElementById("btnClearTimelineFocus"),qt=document.getElementById("btnClearSelectedMarkers");const Wt=document.getElementById("btnShowExamples"),Vt=document.getElementById("examples-div");e.addEventListener("keyup",t=>t.stopPropagation()),e.addEventListener("keydown",t=>t.stopPropagation());let y=new class{constructor(t){this.rev=vt.Cr(""),this.canvas=t,this.me=void 0,this.ye=void 0,this.$e=new st,this.zr=0,this.Ie=new Map,this.pe=new Map,this.be=void 0,this._e=void 0,this.Be=new ft(this.qe(void 0)),this.te=void 0,this.re=void 0,this.ie=0,this.oe=0,this.ee=1,this.Qr=0,this.Kr=0,this.We=!1,this.Ve=void 0}je(t){var r,e,i,o=this.Je(),a=o.yt[this.zr],n=new Set,s=new Map;for(r of[["CX","reverse"],["CY","reverse"],["XCY","reverse"],["CXSWAP","reverse"],["XCZ","reverse"],["XCY","reverse"],["YCX","reverse"],["SWAPCX","reverse"],["RX","MX"],["R","M"],["RY","MY"]])s.set(r[0],r[1]),s.set(r[1],r[0]);for(e of this.Ie.keys()){var h=a.et.get(o.Ut().get(e));void 0!==h&&s.has()CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(h.Z.name)&&n.add(h.R[0])}for(i of n){var l=a.et.get(i),f=s.get(l.Z.name);"reverse"===f?a.et.get(i).R.reverse():l.Z=B.get(f)}this.ti(o,t)}ri(t){var r=this.Je();let e=this.zr;for(;e"MARKX"!==t.Z.name&&"MARKY"!==t.Z.name&&"MARKZ"!==t.Z.name);this.commit(r)}hi(i){var t=this.ye,r=this.me,o=this.be,a=this._e,n=[];if(void 0!==t&&void 0!==o){var[s,h]=dt(o,a),l=Math.min(t,o),f=Math.max(t,o),v=Math.min(r,a),c=Math.max(r,a),t=O/4-St;l+=t,f-=t,v+=t,c-=t,l=Math.floor(2*l/O+.5)/2,f=Math.floor(2*f/O+.5)/2,v=Math.floor(2*v/O+.5)/2,c=Math.floor(2*c/O+.5)/2;let e=1;l!=f&&v!=c||(e=2);for(let r=l;r<=f;r+=.5)for(let t=v;t<=c;t+=.5)r%1!=t%1||i&&(s%e!=r%e||h%e!=t%e)||n.push([r,t])}return n}vi(o,t,r){let e=this.Je();e=e.kt(o),!t&&r&&(this.pe=(r=t=>{var r,e,i=new Map;for([r,e]of t.values())[r,e]=o(r,e),i.set(r+","+e,[r,e]);return i})(this.pe),this.Ie=r(this.Ie)),this.ti(e,t)}ci(t,r){let e=Yt(t),i=this.Je().kt(e).gt();this.vi((t,r)=>([t,r]=e(t,r),i(t,r)),r,!0)}di(t){this.zr=Math.m)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(ax(t,0),this.Qr=0,this.ii()}wi(t,r,e){r||e||this.Ie.clear();for(var[i,o]of t){var a=i+","+o;e&&this.Ie.has(a)?this.Ie.delete(a):this.Ie.set(a,[i,o])}this.ii()}ui(t){var r,e=new Map,i=this.Je().yt[this.zr];for(r of[...t]){var o=i.et.get(r);if(void 0!==o)if("RX"===o.Z.name||"MX"===o.Z.name||"MRX"===o.Z.name)e.set(r,"X");else if("RY"===o.Z.name||"MY"===o.Z.name||"MRY"===o.Z.name)e.set(r,"Y");else if("R"===o.Z.name||"M"===o.Z.name||"MR"===o.Z.name)e.set(r,"Z");else if("MXX"===o.Z.name||"MYY"===o.Z.name||"MZZ"===o.Z.name){var a,n=o.Z.name[1];for(a of o.R)e.set(a,n)}else if(o.Z.name.startsWith("MPP:")&&void 0===o.Z.h&&o.R.length===o.Z.name.length-4){var s=o.Z.name.substring(4);for(let t=0;t{var[t,e]=t,[r,i]=r;return Math.atan2(e-a,t-o)-Math.atan2(i-a,r-o)});var s=this.Je().Ft(this.Ie.values()),h=s.Ut(),l=new Uint32Array(this.Ie.size);for(let t=0;t!t.Z.name.startsWith("MARK")||t.Y[0]!==r)}this.ti(i,t)}bi(t,i){var r,e=this.Je(),o=D.Me(e,i),a=this.zr,n=0===a?new Y(new Map,new Set,[]):o.$r(a-.5),s=o.$r(a+.5),h=e.yt[a],l=new Set;for(r of new Set([...n.Br.keys(),...s.Br.keys()]))if(!l.has(r)){var f=n.Br.get(r),v=s.Br.get(r),c=h.et.get(r);if(void 0!==c){var d=c.Z.name;let e=void 0;if("R"===d||"M"===d||"MR"===d)e="Z";else if("RX"===d||"MX"===d||"MRX"===d)e="X";else{if("RY"!==d&&"MY"!==d&&"MRY"!==d){if("MXX"===d||"MYY"===d||"MZZ"===d){e=d[1];let t=0;for(var w of c.R){if(l.has(w)){t=-1;break}t+=n.Br.get(w)===e}if(2===t)for(var u of c.R)l.add(u),h.it.push(new F(B.get("MARK"+e),"",new Float32Array([i]),new Uint32Array([u])));continue}if(d.startsWith("MPP:")){let r=0;for(let t=0;tc.R.length/2)for(let t=0;t{var t,r,{Nt:e,Dt:i}=n.Pt(!1);for(let t=0;tt.Z.name!==e.Z.name||t.Y[0]!==e.Y[0])}this.ti(a,t)}}}(document.getElementById("cvn"));function v(t){return(t-y.ie)/y.ee+Et}function m(t){return(t-y.oe)/y.ee+At}function jt(){var t=y.Je().xt().replaceAll("\nPOLYGON","\n#!pragma POLYGON").replaceAll("\nERR","\n#!pragma ERR").replaceAll("\nMARK","\n#!pragma MARK"),r=e;r.value=t+"\n",r.focus(),r.select()}zt.addEventListener("click",t=>{jt()}),Kt.addEventListener("click",t=>{var r=e.value,r=u.It(r);y.commit(r)}),Lt.addEventListener("click",t=>{var r=document.getElementById("divImportExport");"none"===r.style.display?(r.style.display="block",Lt.textContent="Hide Import/Export",jt()):(r.style.display="none",Lt.textContent="Show Import/Export",e.value=""),setTimeout(()=>{window.scrollTo(0,0)},0)}),Qt.addEventListener("click",t=>{y.li()}),)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(gt.addEventListener("click",t=>{y.Nr()}),$t.addEventListener("click",t=>{y.pe=new Map(y.Ie.entries()),y.ii()}),qt.addEventListener("click",t=>{y.Mi(!1),y.ii()}),Wt.addEventListener("click",t=>{"none"===Vt.style.display?(Vt.style.display="block",Wt.textContent="Hide Example Circuits"):(Vt.style.display="none",Wt.textContent="Show Example Circuits")}),Bt.addEventListener("click",t=>{y.pe=new Map,y.ii()}),Ct.addEventListener("click",t=>{y.Dr()}),xt.addEventListener("click",t=>{y.fi()}),Gt.addEventListener("click",t=>{y.ci(1,!1)}),Ht.addEventListener("click",t=>{y.ci(-1,!1)}),t.addEventListener("click",t=>{y.ni(!1)}),kt.addEventListener("click",t=>{y.ai(!1)}),Ft.addEventListener("click",t=>{y.di(y.zr+1)}),Ut.addEventListener("click",t=>{y.di(y.zr-1)}),window.addEventListener("resize",t=>{y.canvas.width=y.canvas.scrollWidth,y.canvas.height=y.canvas.scrollHeight,y.ii()}),y.canvas.addEventListener("mousemove",t=>{var r,e,i;y.te=t.offsetX,y.re=t.offsetY,y.We?(r=(i=y.Ve).offsetX+(t.offsetX-i.screenX),e=i.offsetY+(t.of)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(fsetY-i.screenY),i.Ce===o.ke?(y.ie=r,y.oe=e):(y.Qr=r,y.Kr=e),tr(),y.ii()):(y.ye=v(t.offsetX),y.me=m(t.offsetY),i=y.canvas.width/2,Jt&&1===t.buttons?y.di(Math.floor((t.offsetX-i)/8)):y.ii())});let Jt=!1;function tr(){var t=y.canvas.width/2,r=y.canvas.height,e=y.ee,i=-1*O-Et,o=T*O-Et;y.ie=Math.max(t-o*e,Math.min(-i*e,y.ie)),y.oe=Math.max(r-o*e,Math.min(-i*e,y.oe)),y.Kr=Math.min(0,y.Kr)}y.canvas.addEventListener("mousedown",t=>{var r,e=y.canvas.width/2;1===t.button?(t.preventDefault(),y.We=!0,r=t.offsetX>e?o.ge:o.ke,y.Ve=new Rt(t.offsetX,t.offsetY,r===o.ke?y.ie:y.Qr,r===o.ke?y.oe:y.Kr,r)):(y.te=t.offsetX,y.re=t.offsetY,y.ye=v(t.offsetX),y.me=m(t.offsetY),y.be=v(t.offsetX),y._e=m(t.offsetY),(Jt=t.offsetY<20&&t.offsetX>e&&1===t.buttons)?y.di(Math.floor((t.offsetX-e)/8)):y.ii())}),y.canvas.addEventListener("mouseup",t=>{var r;1===t.button?(y.We=!1,y.Ve=void 0):(r=y.hi(t.altKey),y.be=void 0,y._e=void 0,y.te=t.offsetX,y.re=t.offsetY,y.ye=v(t.offsetX),y.me=m(t.offsetY),y.wi(r,t.shiftKey,t.ctrlKey),1===t.buttons&&(Jt=!)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(1))}),y.canvas.addEventListener("wheel",t=>{t.preventDefault();var r,e=y.canvas.width/2;t.offsetX>e?(e=t,y.Qr-=e.deltaX,y.Kr-=e.deltaY):((e=t).ctrlKey||e.metaKey?(t=e.deltaY<0?1.05:1/1.05,r=(t=Math.max(.25,Math.min(4,y.ee*t)))/y.ee,y.ee=t,y.ie=e.offsetX-(e.offsetX-y.ie)*r,y.oe=e.offsetY-(e.offsetY-y.oe)*r):(y.ie-=e.deltaX,y.oe-=e.deltaY),y.ye=v(e.offsetX),y.me=m(e.offsetY)),tr(),y.ii()},{passive:!1});let rr=void 0;async function er(){let e=y.Je();e.yt=[e.yt[y.zr]],0{var r=e.Rt[2*t],t=e.Rt[2*t+1];return y.Ie.has(r+","+t)}),[r,t]=C(y.Ie.values()),e=e.St(-r,-t));var t,r=e.xt();rr=r;try{await navigator.clipboard.writeText(r)}catch(t){console.warn("Failed to write to clipboard. Using fallback emulated clipboard.",t)}}async function ir(e){let i;try{i=await navigator.clipboard.readText()}catch(t){console.warn("Failed to read from clipboard. Using fallback emulated clipboard.",t),i=rr}if(void 0!==i){let r=u.It(i);if(1!==r.yt.length)throw new Error(i);let t=y.Je();0y.ci(-1,t)),o.set("t",t=>y.ci(1,t)),o.set("escape",()=>y.ei()),o.set("delete",t=>y.oi(t)),o.set("backspace",t=>y.oi(t)),o.set("ctrl+delete",t=>y.ai(t)),o.set("ctrl+insert",t=>y.ni(t)),o.set("ctrl+backspace",t=>y.ai(t)),o.set("ctrl+z",t=>{t||y.Nr()}),o.set("ctrl+y",t=>{t||y.Dr()}),o.set("ctrl+shift+z",t=>{t||y.Dr()}),o.set("ctrl+c",async t=>{await er()}),o.set("ctrl+v",ir),o.set("ctrl+x",async t=>{var r;await er(),0===y.Ie.size?((r=y.Je()).yt[y.zr].et.clear(),r.yt[y.zr].it.length=0,y.ti(r,t)):y.oi(t)}),o.set("l",t=>{t||(y.pe=new Map(y.Ie.entries()),y.ii())}),o.set(" ",t=>y.Mi(t));for(let[t,r]of[["1",0)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(],["2",1],["3",2],["4",3],["5",4],["6",5],["7",6],["8",7],["9",8],["0",9],["-",10],["=",11],["\\",12],["`",13]])o.set(""+t,t=>y.Xi(t,r)),o.set(t+"+x",t=>y.yi(t,B.get("MARKX").M(r))),o.set(t+"+y",t=>y.yi(t,B.get("MARKY").M(r))),o.set(t+"+z",t=>y.yi(t,B.get("MARKZ").M(r))),o.set(t+"+d",t=>y.Ii(t,r)),o.set(t+"+o",t=>y.mi(t,r)),o.set(t+"+j",t=>y._i(t,r)),o.set(t+"+k",t=>y.bi(t,r));let r=.25;function a(t,r,e=void 0){for(var i of t){if(o.has(i))throw new Error("Chord collision: "+i);o.set(i,t=>y.yi(t,B.get(r)))}void 0!==e&&a(t.map(t=>"shift+"+t),e)}return o.set("p",t=>y.yi(t,B.get("POLYGON"),[1,0,0,r])),o.set("alt+p",t=>y.yi(t,B.get("POLYGON"),[0,1,0,r])),o.set("shift+p",t=>y.yi(t,B.get("POLYGON"),[0,0,1,r])),o.set("p+x",t=>y.yi(t,B.get("POLYGON"),[1,0,0,r])),o.set("p+y",t=>y.yi(t,B.get("POLYGON"),[0,1,0,r])),o.set("p+z",t=>y.yi(t,B.get("POLYGON"),[0,0,1,r])),o.set("p+x+y",t=>y.yi(t,B.get("POLYGON"),[1,1,0,r])),o.set("p+x+z",t=>y.yi(t,B.get("POLYGON"),[1,0,1,r])),o.set("p+y+z",t=>y.yi(t,B.get("POLYGON"),[0,1,1,r])))CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(,o.set("p+x+y+z",t=>y.yi(t,B.get("POLYGON"),[1,1,1,r])),o.set("m+p+x",t=>y.yi(t,f("X".repeat(y.Ie.size)),[])),o.set("m+p+y",t=>y.yi(t,f("Y".repeat(y.Ie.size)),[])),o.set("m+p+z",t=>y.yi(t,f("Z".repeat(y.Ie.size)),[])),o.set("f",t=>y.je(t)),o.set("g",t=>y.ri(t)),o.set("shift+>",t=>y.vi((t,r)=>[t+1,r],t,!1)),o.set("shift+<",t=>y.vi((t,r)=>[t-1,r],t,!1)),o.set("shift+v",t=>y.vi((t,r)=>[t,r+1],t,!1)),o.set("shift+^",t=>y.vi((t,r)=>[t,r-1],t,!1)),o.set(">",t=>y.vi((t,r)=>[t+1,r],t,!1)),o.set("<",t=>y.vi((t,r)=>[t-1,r],t,!1)),o.set("v",t=>y.vi((t,r)=>[t,r+1],t,!1)),o.set("^",t=>y.vi((t,r)=>[t,r-1],t,!1)),o.set(".",t=>y.vi((t,r)=>[t+.5,r+.5],t,!1)),a(["h","h+y","h+x+z"],"H","H"),a(["h+z","h+x+y"],"H_XY","H_XY"),a(["h+x","h+y+z"],"H_YZ","H_YZ"),a(["s+x","s+y+z"],"SQRT_X","SQRT_X_DAG"),a(["s+y","s+x+z"],"SQRT_Y","SQRT_Y_DAG"),a(["s","s+z","s+x+y"],"S","S_DAG"),a(["r+x","r+y+z"],"RX"),a(["r+y","r+x+z"],"RY"),a(["r","r+z","r+x+y"],"R"),a(["m+x","m+y+z"],"MX"),a(["m+y","m+x+z"],"MY"),a(["m","m+z","m+x+y"],"M"),a(["m+r+x")CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(,"m+r+y+z"],"MRX"),a(["m+r+y","m+r+x+z"],"MRY"),a(["m+r","m+r+z","m+r+x+y"],"MR"),a(["c"],"CX","CX"),a(["c+x"],"CX","CX"),a(["c+y"],"CY","CY"),a(["c+z"],"CZ","CZ"),a(["j+x"],"X","X"),a(["j+y"],"Y","Y"),a(["j+z"],"Z","Z"),a(["c+x+y"],"XCY","XCY"),a(["alt+c+x"],"XCX","XCX"),a(["alt+c+y"],"YCY","YCY"),a(["w"],"SWAP","SWAP"),a(["w+x"],"CXSWAP",void 0),a(["c+w+x"],"CXSWAP",void 0),a(["i+w"],"ISWAP","ISWAP_DAG"),a(["w+z"],"CZSWAP",void 0),a(["c+w+z"],"CZSWAP",void 0),a(["c+w"],"CZSWAP",void 0),a(["c+t"],"C_XYZ","C_ZYX"),a(["c+s+x"],"SQRT_XX","SQRT_XX_DAG"),a(["c+s+y"],"SQRT_YY","SQRT_YY_DAG"),a(["c+s+z"],"SQRT_ZZ","SQRT_ZZ_DAG"),a(["c+s"],"SQRT_ZZ","SQRT_ZZ_DAG"),a(["c+m+x"],"MXX","MXX"),a(["c+m+y"],"MYY","MYY"),a(["c+m+z"],"MZZ","MZZ"),a(["c+m"],"MZZ","MZZ"),o}();function ar(r){if(y.$e.jt(r),"keydown"===r.type){if("q"===r.key.toLowerCase())return e=r.shiftKey?5:1,void y.di(y.zr-e);if("e"===r.key.toLowerCase())return e=r.shiftKey?5:1,void y.di(y.zr+e);if("Home"===r.key)return y.di(0),void r.preventDefault();if("End)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART("===r.key)return y.di(y.Je().yt.length-1),void r.preventDefault()}var t=y.$e.Bt;if(0!==t.length){for(var e=t[t.length-1];0{y.Be.set(y.qe(void 0));var t=y.$e.qt(!1),a=(r.width=r.scrollWidth,r.height=r.scrollHeight,r.getContext("2d"));a.clearRect(0,0,r.width,r.height),a.textAlign="right",a.textBaseline="middle",a.fillText("X",7.5,24.5),a.fillText("Y",7.5,56.5),a.fillText("Z",7.5,88.5),a.textAlign="center",a.textBaseline="bottom";for(let t=0;t{try{var t,r=(()=>{var t=document.location.hash.substring(1),r=new Map;if(""!==t)for(var e of t.split("&")){var i,o=e.indexOf("=");-1!==o&&(i=e.substring(0,o),e=decodeURIComponent(e.substring(o+1)),r.set(i,e))}return r})(),e=(r.has("circuit")||("[[[DEFAULT-CIRCUIT-CONTENT-LITERAL]]]"===(t=document.getElementById("txtDefaultCircuit")).value.replaceAll("_","-")?r.set("circuit",""):r.set("circuit",t.value)),u.It(r.get("circuit"))),i=e.xt();nr.clear(i),e.yt.every(t=>t.ut())&&1===r.size&&i===r.get("circuit")?sr.De():sr.xe(i,pt(i))}catch(t){throw new Error(t)}},window.addEventListener("popstate",zt),zt(),nr.kr().Yr().Zr(1).subscribe(t=>{sr.xe(t,pt(t))})}y.Be.mr().subscribe(r=>requestAnimationFrame(()=>{var t=Mt(y.canvas.getContext("2d"),r);y.Qr=Math.max(t.Fr,Math.min(y.Qr,t.Ur)),y.Kr=Math.max(y.Kr,-t.Gr)})),window.addEventListener("focus",()=>{y.$e.Vt()}),window.addEventListener("blur",()=>{y.$e.Vt()});for(let r of do)CRUMBLE_PART"); + result.append(R"CRUMBLE_PART(cument.getElementById("examples-div").querySelectorAll("a"))r.onclick=t=>{if(!(t.shiftKey||t.ctrlKey||t.altKey||0!==t.button))return t=r.href.split("#circuit=")[1],y.rev.commit(t),!1}; )CRUMBLE_PART"); result.append(R"CRUMBLE_PART( )CRUMBLE_PART");