diff --git a/pyzx/js/zx_viewer3d.js b/pyzx/js/zx_viewer3d.js index 1dbb3295..90233d7d 100644 --- a/pyzx/js/zx_viewer3d.js +++ b/pyzx/js/zx_viewer3d.js @@ -23,19 +23,14 @@ import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer export function showGraph3D(tag, graph, width, height, show_labels) { const scene = new THREE.Scene(); - const aspect = height/width; - const scale = 20; - const camera = new THREE.OrthographicCamera(-scale, scale, scale*aspect, -scale*aspect); const renderer = new THREE.WebGLRenderer({ antialias: true }); const labelRenderer = new CSS2DRenderer(); const light = new THREE.DirectionalLight( 0xffffff, 2); scene.background = new THREE.Color(0xffffff); - camera.layers.enableAll(); scene.add(new THREE.AmbientLight(0xffffff, 1.5)); light.position.set(1, 1, 1).normalize(); scene.add(light); - camera.position.z = 10; renderer.setSize(width, height); labelRenderer.setSize(width, height); labelRenderer.domElement.style.position = 'absolute'; @@ -61,35 +56,29 @@ export function showGraph3D(tag, graph, width, height, show_labels) { rightButton.innerHTML = '🡆'; buttons.appendChild(rightButton); - const controls = new OrbitControls( camera, labelRenderer.domElement ); - const raycaster = new THREE.Raycaster(); - const mouse = new THREE.Vector2(); - let highlightRow = -1; - controls.minDistance = 1; - controls.maxDistance = 100; - - var ntab = {}; const rows = new Set(); - let minY = null, maxY = null, minZ = null, maxZ = null; + let minX = null, maxX = null, minY = null, maxY = null, minZ = null, maxZ = null; graph.nodes.forEach(function(d) { ntab[d.name] = d; d.nhd = []; rows.add(d.x); + minX = (minX == null) ? d.x : Math.min(d.x, minX); minY = (minY == null) ? d.y : Math.min(d.y, minY); minZ = (minZ == null) ? d.z : Math.min(d.z, minZ); + maxX = (maxX == null) ? d.x : Math.max(d.x, maxX); maxY = (maxY == null) ? d.y : Math.max(d.y, maxY); maxZ = (maxZ == null) ? d.z : Math.max(d.z, maxZ); - let color = 0x000000, radius = 0.1; + let color = 0x000000, radius = 0.05; if (d.t == 1) { color = Number('0x' + '#99dd99'.substring(1)); - radius = 0.15; + radius = 0.1; } else if (d.t == 2) { color = Number('0x' + '#ff8888'.substring(1)); - radius = 0.15; + radius = 0.1; } const geometry = new THREE.SphereGeometry(radius, 48, 24); @@ -98,7 +87,7 @@ export function showGraph3D(tag, graph, width, height, show_labels) { d.sphere.name = d.name; d.sphere.position.set(d.x, d.y, d.z); d.sphere.layers.enableAll(); - d.sphere.renderOrder = 0.0; + d.sphere.renderOrder = 0.5; scene.add(d.sphere); if (d.phase != '') { @@ -139,7 +128,7 @@ export function showGraph3D(tag, graph, width, height, show_labels) { new THREE.Vector3(t.x, t.y, t.z) ]); d.line = new Line2(geometry, material); - d.line.renderOrder = 0.5; + d.line.renderOrder = 0.6; scene.add(d.line); }); @@ -152,24 +141,43 @@ export function showGraph3D(tag, graph, width, height, show_labels) { highlightPlane.renderOrder = 1.0; scene.add(highlightPlane); + const aspect = height/width; + let scale = 20; + if (minX != null) { + scale = Math.max((maxX - minX)/2, (maxY-minY)/(2*aspect)) + 2; + } + const camera = new THREE.OrthographicCamera(-scale, scale, scale*aspect, -scale*aspect); + camera.layers.enableAll(); + camera.position.z = 5; + if (minX != null) { + camera.position.z = 2*Math.max(maxX, maxY, maxZ); + } + + const controls = new OrbitControls(camera, labelRenderer.domElement); + const raycaster = new THREE.Raycaster(); + const mouse = new THREE.Vector2(); + let highlightRow = -1; + controls.minDistance = 1; + controls.maxDistance = 100; + + + function checkIntersection() { raycaster.setFromCamera(mouse, camera); const intersects = raycaster.intersectObject(scene, true); - if (intersects.length > 0) { - const selectedObject = intersects[0].object; + highlightRow = -1; + for (let obj of intersects) { + const selectedObject = obj.object; if (Object.hasOwn(selectedObject, 'name') && selectedObject.name != '') { const d = ntab[selectedObject.name]; highlightRow = rowList.indexOf(d.x); - } else { - highlightRow = -1; + break; } - } else { - highlightRow = -1; } - update(); } + function update() { if (highlightRow == -1) { highlightPlane.material.opacity = 0.0; @@ -181,8 +189,10 @@ export function showGraph3D(tag, graph, width, height, show_labels) { graph.nodes.forEach(function (d) { if (highlightRow == -1 || rowList[highlightRow] == d.x) { d.sphere.material.opacity = 1.0; + d.sphere.renderOrder = 0.5; } else { d.sphere.material.opacity = 0.4; + d.sphere.renderOrder = 0.7; } }); @@ -193,8 +203,10 @@ export function showGraph3D(tag, graph, width, height, show_labels) { } else { d.line.material.opacity = 1.0; } + d.line.renderOrder = 0.6; } else { d.line.material.opacity = 0.25; + d.line.renderOrder = 0.8; } }); } diff --git a/scratchpads/ak.ipynb b/scratchpads/ak.ipynb index 84a246b3..c70ccaff 100644 --- a/scratchpads/ak.ipynb +++ b/scratchpads/ak.ipynb @@ -86,7 +86,7 @@ "data": { "text/html": [ "\n", - "
\n", + " \n", " \n", @@ -117,19 +117,14 @@ "\n", "export function showGraph3D(tag, graph, width, height, show_labels) {\n", " const scene = new THREE.Scene();\n", - " const aspect = height/width;\n", - " const scale = 20;\n", - " const camera = new THREE.OrthographicCamera(-scale, scale, scale*aspect, -scale*aspect);\n", " const renderer = new THREE.WebGLRenderer({ antialias: true });\n", " const labelRenderer = new CSS2DRenderer();\n", " const light = new THREE.DirectionalLight( 0xffffff, 2);\n", "\n", " scene.background = new THREE.Color(0xffffff);\n", - " camera.layers.enableAll();\n", " scene.add(new THREE.AmbientLight(0xffffff, 1.5));\n", " light.position.set(1, 1, 1).normalize();\n", " scene.add(light);\n", - " camera.position.z = 10;\n", " renderer.setSize(width, height);\n", " labelRenderer.setSize(width, height);\n", " labelRenderer.domElement.style.position = 'absolute';\n", @@ -155,7 +150,104 @@ " rightButton.innerHTML = '🡆';\n", " buttons.appendChild(rightButton);\n", "\n", - " const controls = new OrbitControls( camera, labelRenderer.domElement );\n", + " var ntab = {};\n", + "\n", + " const rows = new Set();\n", + " let minX = null, maxX = null, minY = null, maxY = null, minZ = null, maxZ = null;\n", + "\n", + " graph.nodes.forEach(function(d) {\n", + " ntab[d.name] = d;\n", + " d.nhd = [];\n", + " rows.add(d.x);\n", + " minX = (minX == null) ? d.x : Math.min(d.x, minX);\n", + " minY = (minY == null) ? d.y : Math.min(d.y, minY);\n", + " minZ = (minZ == null) ? d.z : Math.min(d.z, minZ);\n", + " maxX = (maxX == null) ? d.x : Math.max(d.x, maxX);\n", + " maxY = (maxY == null) ? d.y : Math.max(d.y, maxY);\n", + " maxZ = (maxZ == null) ? d.z : Math.max(d.z, maxZ);\n", + "\n", + " let color = 0x000000, radius = 0.05;\n", + " if (d.t == 1) {\n", + " color = Number('0x' + '#99dd99'.substring(1));\n", + " radius = 0.1;\n", + " } else if (d.t == 2) {\n", + " color = Number('0x' + '#ff8888'.substring(1));\n", + " radius = 0.1;\n", + " }\n", + "\n", + " const geometry = new THREE.SphereGeometry(radius, 48, 24);\n", + " const material = new THREE.MeshLambertMaterial({ color: color, transparent: true });\n", + " d.sphere = new THREE.Mesh(geometry, material);\n", + " d.sphere.name = d.name;\n", + " d.sphere.position.set(d.x, d.y, d.z);\n", + " d.sphere.layers.enableAll();\n", + " d.sphere.renderOrder = 0.5;\n", + " scene.add(d.sphere);\n", + "\n", + " if (d.phase != '') {\n", + " const phaseDiv = document.createElement('div');\n", + " phaseDiv.className = 'label';\n", + " phaseDiv.textContent = d.phase;\n", + " phaseDiv.style.backgroundColor = 'transparent';\n", + " phaseDiv.style.textAlign = 'center';\n", + " phaseDiv.style.color = '#0000ff';\n", + " const phaseLabel = new CSS2DObject(phaseDiv);\n", + " phaseLabel.position.set(0.25, 0.5);\n", + " phaseLabel.center.set(0, 0);\n", + " d.sphere.add(phaseLabel);\n", + " phaseLabel.layers.set(1);\n", + " }\n", + "\n", + " });\n", + "\n", + " const rowList = [...rows].sort((a,b) => a-b);\n", + " console.log(rowList);\n", + "\n", + " graph.links.forEach(function(d) {\n", + " var s = ntab[d.source];\n", + " var t = ntab[d.target];\n", + " d.source = s;\n", + " d.target = t;\n", + " s.nhd.push(t);\n", + " t.nhd.push(s);\n", + " let color = 0x000000;\n", + " if (d.t == 2) {\n", + " color = 0xffff66;\n", + " }\n", + "\n", + " const material = new LineMaterial({ color: color, linewidth: 2, transparent: true });\n", + " if (s.x != t.x) { material.opacity = 0.5; }\n", + " const geometry = new LineGeometry().setFromPoints([\n", + " new THREE.Vector3(s.x, s.y, s.z),\n", + " new THREE.Vector3(t.x, t.y, t.z)\n", + " ]);\n", + " d.line = new Line2(geometry, material);\n", + " d.line.renderOrder = 0.6;\n", + " scene.add(d.line);\n", + " });\n", + "\n", + " const highlightPlane = new THREE.Mesh(\n", + " new THREE.PlaneGeometry(maxZ - minZ + 0.5, maxY - minY + 0.5),\n", + " new THREE.MeshLambertMaterial({color: 0xddddff, side: THREE.DoubleSide, transparent: true}));\n", + " highlightPlane.rotation.set(0,0.5*Math.PI,0);\n", + " highlightPlane.position.set(0,(minY+maxY)/2, (minZ+maxZ)/2);\n", + " highlightPlane.material.opacity = 0.0;\n", + " highlightPlane.renderOrder = 1.0;\n", + " scene.add(highlightPlane);\n", + "\n", + " const aspect = height/width;\n", + " let scale = 20;\n", + " if (minX != null) {\n", + " scale = Math.max((maxX - minX)/2, (maxY-minY)/(2*aspect)) + 2;\n", + " }\n", + " const camera = new THREE.OrthographicCamera(-scale, scale, scale*aspect, -scale*aspect);\n", + " camera.layers.enableAll();\n", + " camera.position.z = 5;\n", + " if (minX != null) {\n", + " camera.position.z = 2*Math.max(maxX, maxY, maxZ);\n", + " }\n", + "\n", + " const controls = new OrbitControls(camera, labelRenderer.domElement);\n", " const raycaster = new THREE.Raycaster();\n", " const mouse = new THREE.Vector2();\n", " let highlightRow = -1;\n", @@ -163,27 +255,268 @@ " controls.maxDistance = 100;\n", "\n", "\n", + "\n", + " function checkIntersection() {\n", + " raycaster.setFromCamera(mouse, camera);\n", + " const intersects = raycaster.intersectObject(scene, true);\n", + " highlightRow = -1;\n", + " for (let obj of intersects) {\n", + " const selectedObject = obj.object;\n", + " if (Object.hasOwn(selectedObject, 'name') && selectedObject.name != '') {\n", + " const d = ntab[selectedObject.name];\n", + " highlightRow = rowList.indexOf(d.x);\n", + " break;\n", + " }\n", + " }\n", + " update();\n", + " }\n", + "\n", + "\n", + " function update() {\n", + " if (highlightRow == -1) {\n", + " highlightPlane.material.opacity = 0.0;\n", + " } else {\n", + " highlightPlane.position.setComponent(0, rowList[highlightRow]);\n", + " highlightPlane.material.opacity = 0.5;\n", + " }\n", + "\n", + " graph.nodes.forEach(function (d) {\n", + " if (highlightRow == -1 || rowList[highlightRow] == d.x) {\n", + " d.sphere.material.opacity = 1.0;\n", + " d.sphere.renderOrder = 0.5;\n", + " } else {\n", + " d.sphere.material.opacity = 0.4;\n", + " d.sphere.renderOrder = 0.7;\n", + " }\n", + " });\n", + "\n", + " graph.links.forEach(function (d) {\n", + " if (highlightRow == -1 || (rowList[highlightRow] == d.target.x && rowList[highlightRow] == d.source.x)) {\n", + " if (d.source.x != d.target.x) {\n", + " d.line.material.opacity = 0.5;\n", + " } else {\n", + " d.line.material.opacity = 1.0;\n", + " }\n", + " d.line.renderOrder = 0.6;\n", + " } else {\n", + " d.line.material.opacity = 0.25;\n", + " d.line.renderOrder = 0.8;\n", + " }\n", + " });\n", + " }\n", + "\n", + " let mouseX = 0;\n", + " let mouseY = 0;\n", + "\n", + " function onMouseDown(event) {\n", + " mouseX = event.clientX;\n", + " mouseY = event.clientY;\n", + " }\n", + " \n", + " function onMouseUp(event) {\n", + " if (event.isPrimary === false) return;\n", + " const dx = event.clientX - mouseX;\n", + " const dy = event.clientY - mouseY;\n", + "\n", + " if (dx == 0 && dy == 0) {\n", + " const rect = element.getBoundingClientRect();\n", + " const x = event.clientX - rect.left;\n", + " const y = event.clientY - rect.top;\n", + "\n", + " mouse.x = ((x / width) * 2 - 1);\n", + " mouse.y = (-(y / height) * 2 + 1);\n", + " checkIntersection();\n", + " }\n", + " }\n", + "\n", + " function goLeft() {\n", + " if (rowList.length > 0) {\n", + " if (highlightRow == -1) {\n", + " highlightRow = rowList.length - 1;\n", + " } else {\n", + " if (highlightRow == 0) {\n", + " highlightRow = rowList.length - 1;\n", + " } else {\n", + " highlightRow = highlightRow - 1;\n", + " }\n", + " }\n", + " }\n", + " update();\n", + " }\n", + "\n", + " function goRight() {\n", + " if (rowList.length > 0) {\n", + " if (highlightRow == -1) {\n", + " highlightRow = 0;\n", + " } else {\n", + " highlightRow = (highlightRow + 1) % rowList.length;\n", + " }\n", + " }\n", + " update();\n", + " }\n", + "\n", + " labelRenderer.domElement.addEventListener('mousedown', onMouseDown);\n", + " labelRenderer.domElement.addEventListener('mouseup', onMouseUp);\n", + " leftButton.addEventListener('click', goLeft);\n", + " rightButton.addEventListener('click', goRight);\n", + " labelRenderer.tabIndex = 0;\n", + "\n", + " function animate() {\n", + " renderer.render(scene, camera);\n", + " labelRenderer.render(scene, camera);\n", + " }\n", + " renderer.setAnimationLoop(animate);\n", + "}\n", + "\n", + " showGraph3D('graph-output-3d-iH5jIY41', JSON.parse('{\"nodes\": [{\"name\": \"0\", \"x\": -5.5, \"y\": -1.0, \"z\": -1.0, \"t\": 0, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"1\", \"x\": -5.5, \"y\": 0.0, \"z\": -1.0, \"t\": 0, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"2\", \"x\": -5.5, \"y\": 1.0, \"z\": -1.0, \"t\": 0, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"3\", \"x\": -5.5, \"y\": -1.0, \"z\": 0.0, \"t\": 0, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"4\", \"x\": -5.5, \"y\": 0.0, \"z\": 0.0, \"t\": 0, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"5\", \"x\": -5.5, \"y\": 1.0, \"z\": 0.0, \"t\": 0, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"6\", \"x\": -5.5, \"y\": -1.0, \"z\": 1.0, \"t\": 0, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"7\", \"x\": -5.5, \"y\": 0.0, \"z\": 1.0, \"t\": 0, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"8\", \"x\": -5.5, \"y\": 1.0, \"z\": 1.0, \"t\": 0, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"9\", \"x\": -4.5, \"y\": 1.0, \"z\": 0.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"10\", \"x\": -4.5, \"y\": 1.0, \"z\": 1.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"11\", \"x\": -3.5, \"y\": 0.0, \"z\": 1.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"12\", \"x\": -3.5, \"y\": 1.0, \"z\": 1.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"13\", \"x\": -4.5, \"y\": 0.0, \"z\": -1.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"14\", \"x\": -4.5, \"y\": 0.0, \"z\": 0.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"15\", \"x\": -3.5, \"y\": 1.0, \"z\": 0.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"16\", \"x\": -3.5, \"y\": 0.0, \"z\": 0.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"17\", \"x\": -2.5, \"y\": 0.0, \"z\": 0.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"18\", \"x\": -2.5, \"y\": 1.0, \"z\": 0.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"19\", \"x\": -2.5, \"y\": 1.0, \"z\": 1.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"20\", \"x\": -2.5, \"y\": 0.0, \"z\": 1.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"21\", \"x\": -4.5, \"y\": -1.0, \"z\": 0.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"22\", \"x\": -4.5, \"y\": -1.0, \"z\": 1.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"23\", \"x\": -1.5, \"y\": 0.0, \"z\": -1.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"24\", \"x\": -1.5, \"y\": 0.0, \"z\": 0.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"25\", \"x\": -1.5, \"y\": 1.0, \"z\": 0.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"26\", \"x\": -1.5, \"y\": 1.0, \"z\": -1.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"27\", \"x\": -0.5, \"y\": 1.0, \"z\": 0.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"28\", \"x\": -0.5, \"y\": 1.0, \"z\": -1.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"29\", \"x\": -3.5, \"y\": -1.0, \"z\": 0.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"30\", \"x\": -3.5, \"y\": -1.0, \"z\": -1.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"31\", \"x\": 0.5, \"y\": 1.0, \"z\": 0.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"32\", \"x\": 0.5, \"y\": 1.0, \"z\": 1.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"33\", \"x\": 1.5, \"y\": 0.0, \"z\": 0.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"34\", \"x\": 1.5, \"y\": 1.0, \"z\": 0.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"35\", \"x\": 0.5, \"y\": 0.0, \"z\": -1.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"36\", \"x\": 0.5, \"y\": 1.0, \"z\": -1.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"37\", \"x\": -2.5, \"y\": -1.0, \"z\": 1.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"38\", \"x\": -2.5, \"y\": -1.0, \"z\": 0.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"39\", \"x\": 1.5, \"y\": 0.0, \"z\": -1.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"40\", \"x\": 1.5, \"y\": 1.0, \"z\": -1.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"41\", \"x\": 2.5, \"y\": 0.0, \"z\": -1.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"42\", \"x\": 2.5, \"y\": 1.0, \"z\": -1.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"43\", \"x\": 2.5, \"y\": 0.0, \"z\": 0.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"44\", \"x\": 2.5, \"y\": -1.0, \"z\": 0.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"45\", \"x\": 3.5, \"y\": 0.0, \"z\": 0.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"46\", \"x\": 3.5, \"y\": 0.0, \"z\": 1.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"47\", \"x\": 4.5, \"y\": 0.0, \"z\": 0.0, \"t\": 2, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"48\", \"x\": 4.5, \"y\": 0.0, \"z\": -1.0, \"t\": 1, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"49\", \"x\": 5.5, \"y\": -1.0, \"z\": -1.0, \"t\": 0, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"50\", \"x\": 5.5, \"y\": 0.0, \"z\": -1.0, \"t\": 0, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"51\", \"x\": 5.5, \"y\": 1.0, \"z\": -1.0, \"t\": 0, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"52\", \"x\": 5.5, \"y\": -1.0, \"z\": 0.0, \"t\": 0, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"53\", \"x\": 5.5, \"y\": 0.0, \"z\": 0.0, \"t\": 0, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"54\", \"x\": 5.5, \"y\": 1.0, \"z\": 0.0, \"t\": 0, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"55\", \"x\": 5.5, \"y\": -1.0, \"z\": 1.0, \"t\": 0, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"56\", \"x\": 5.5, \"y\": 0.0, \"z\": 1.0, \"t\": 0, \"phase\": \"\", \"ground\": false, \"vdata\": []}, {\"name\": \"57\", \"x\": 5.5, \"y\": 1.0, \"z\": 1.0, \"t\": 0, \"phase\": \"\", \"ground\": false, \"vdata\": []}], \"links\": [{\"source\": \"0\", \"target\": \"30\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"1\", \"target\": \"13\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"2\", \"target\": \"26\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"3\", \"target\": \"21\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"4\", \"target\": \"14\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"5\", \"target\": \"9\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"6\", \"target\": \"22\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"7\", \"target\": \"11\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"8\", \"target\": \"10\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"9\", \"target\": \"10\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"9\", \"target\": \"15\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"10\", \"target\": \"12\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"11\", \"target\": \"12\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"11\", \"target\": \"20\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"12\", \"target\": \"19\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"13\", \"target\": \"14\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"13\", \"target\": \"23\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"14\", \"target\": \"16\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"15\", \"target\": \"16\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"15\", \"target\": \"18\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"16\", \"target\": \"17\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"17\", \"target\": \"18\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"17\", \"target\": \"24\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"18\", \"target\": \"25\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"19\", \"target\": \"20\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"19\", \"target\": \"32\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"20\", \"target\": \"46\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"21\", \"target\": \"22\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"21\", \"target\": \"29\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"22\", \"target\": \"37\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"23\", \"target\": \"24\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"23\", \"target\": \"35\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"24\", \"target\": \"33\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"25\", \"target\": \"26\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"25\", \"target\": \"27\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"26\", \"target\": \"28\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"27\", \"target\": \"28\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"27\", \"target\": \"31\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"28\", \"target\": \"36\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"29\", \"target\": \"30\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"29\", \"target\": \"38\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"30\", \"target\": \"49\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"31\", \"target\": \"32\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"31\", \"target\": \"34\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"32\", \"target\": \"57\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"33\", \"target\": \"34\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"33\", \"target\": \"43\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"34\", \"target\": \"54\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"35\", \"target\": \"36\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"35\", \"target\": \"39\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"36\", \"target\": \"40\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"37\", \"target\": \"38\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"37\", \"target\": \"55\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"38\", \"target\": \"44\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"39\", \"target\": \"40\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"39\", \"target\": \"41\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"40\", \"target\": \"42\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"41\", \"target\": \"42\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"41\", \"target\": \"48\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"42\", \"target\": \"51\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"43\", \"target\": \"44\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"43\", \"target\": \"45\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"44\", \"target\": \"52\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"45\", \"target\": \"46\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"45\", \"target\": \"47\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"46\", \"target\": \"56\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"47\", \"target\": \"48\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"47\", \"target\": \"53\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}, {\"source\": \"48\", \"target\": \"50\", \"t\": 1, \"index\": 0, \"num_parallel\": 1}], \"pauli_web\": []}'), 1000, 500, false);\n", + " \n", + " " + ], + "text/plain": [ + "