+++ /dev/null
-<!DOCTYPE html>
-<head>
- <title>QAnsel - Quantum Computer Simulator</title>
- <link href="imports/istina-editor.css" rel="stylesheet" />
- <link href="imports/micromodal.css" rel="stylesheet" />
- <script src="imports/estouls-api.js"></script>
- <script src="imports/istina-editor.js"></script>
- <script src="imports/chart.js"></script>
- <script src="imports/micromodal.js"></script>
- <script src="imports/dom-to-image.js"></script>
- <style>
- body { background-color: #1f1f1f; user-select: none; }
- .program-track { table-layout: fixed; }
- [pidx*=','],.program-expand td { cursor: pointer; }
- span,sub { pointer-events: none; touch-action: none; }
- [class*=program] td
- {
- font-family: 'Courier New', Courier, monospace;
- text-align: center;
- user-select: none;
- background-color: #353535;
- color: #9cdcfe;
- border-color: grey;
- font-weight: bold;
- border-style: solid;
- border-collapse: collapse;
- }
- textarea
- {
- background-color: #353535;
- color: #dcdcaa;
- font-family: 'Courier New', Courier, monospace;
- width: 100%;
- height: 220px;
- }
-
- .top-button-row td:hover
- {
- background-color: gray;
- cursor: pointer;
- }
-
- @keyframes animation-reveal
- {
- from {
- clip-path: polygon(0% 0%, 0% 0%, 100% 0%, 100% 0%);
- }
- to {
- clip-path: polygon(0% 0%, 0% 100%, 100% 100%, 100% 0%);
- }
- }
- </style>
-</head>
-<body>
- <input type="file" id="file-input" style="display: none;" />
- <div class="modal micromodal-slide" id="modal-main" aria-hidden="true">
- <div class="modal__overlay" tabindex="-1" data-micromodal-close oncontextmenu="return false;">
- <div class="modal__container" role="dialog" aria-modal="true" aria-labelledby="modal-main-title">
- <header class="modal__header">
- <h2 class="modal__title" id="modal-main-title"></h2>
- <button class="modal__close" aria-label="Close modal" data-micromodal-close style="cursor: pointer;"></button>
- </header>
- <main class="modal__content" id="modal-main-content"></main>
- <footer class="modal__footer">
- <button class="modal__btn modal__btn-primary" id="modal-main-confirm">Confirm</button>
- <button class="modal__btn" id="modal-main-cancel" onclick="closeModal();">Cancel</button>
- </footer>
- </div>
- </div>
- </div>
- <table class="main-table" border="1" style="width: 100%;">
- <tr>
- <td colspan="2">
- <table style="width: 100%; text-align: center;" class="top-button-row">
- <tr oncontextmenu="return false;">
- <td onclick="menu('open');">๐</td>
- <td onclick="menu('clear');">๐งน</td>
- <td onclick="menu('save');">๐พ</td>
- <!--<td onclick="menu('download');">๐ฅ</td>-->
- <td onclick="menu('chart');">๐</td>
- <td style="color: green;" id="run">โถ</td>
- <td onclick="menu('screenshot');">๐ท</td>
- <td onmouseup="menu('sphere', event)">๐</td>
- <td onclick="menu('help');">๐ฅ</td>
- <td onclick="menu('settings');" style="color: lightgray">โ</td>
- </tr>
- </table>
- </td>
- </tr>
- <tr>
- <td colspan="2">
- <div style="overflow-y: auto; overflow-x: auto; height: 256px; width: 0px;" oncontextmenu="return false;" class="program-track-container">
- <table border=1 class="program-track"></table>
- <table border=1 class="program-expand" style="border-top: none;">
- <tr>
- <td style="width: 64px; height: 64px;" onclick="ProgramTrack.adjust(-1);">โ</td>
- <td style="width: 64px; height: 64px;" onclick="ProgramTrack.adjust(1);">๏ผ</td>
- </tr>
- </table>
- </div>
- </td>
- </tr>
- <tr>
- <td style="width: 50%; height: 100%;">
- <istina-editor style="height: 100%;"></istina-editor>
- </td>
- <td style="width: 50%;">
- <canvas id="resultsChart"></canvas>
- </td>
- </tr>
- </table>
- <table border=1 class="program-instr" oncontextmenu="return false;" style="display: none;" cellspacing="0" cellpadding="0"></table>
- <table border=1 class="program-drag" oncontextmenu="return false;" style="pointer-events: none; touch-action: none; visibility: hidden;"></table>
- <script>
- var shotsmax = 10000;
- var ismobile = typeof(document.body.ontouchstart) == "object";
- $ = x => { return document.querySelectorAll(x); };
- if (window.location.href.includes("apikey="))
- {
- var h = window.location.href;
- var k = h.split("apikey=")[1].split("&")[0];
- localStorage.setItem("apikey", unescape(k));
- h = h.replace("apikey=" + k + "&", "");
- h = h.replace("apikey=" + k, "");
- if (h.split("?")[1].trim().length == 0)
- h = h.substring(0, h.length - 1);
- window.location.href = h;
- }
- IstinaEditor.init();
- function overline(instr, pos, compare)
- {
- var r;
- switch (instr)
- {
- case "CX":
- switch (pos)
- {
- case "10": r = "<span style='text-decoration:overline;'>C</span>X"; break;
- case "01": r = "C<span style='text-decoration:overline;'>X</span>"; break;
- }
- break;
- case "SW":
- switch (pos)
- {
- case "10": r = "<span style='text-decoration:overline;'>S</span>W"; break;
- case "01": r = "S<span style='text-decoration:overline;'>W</span>"; break;
- }
- break;
- case "CCX":
- switch (pos)
- {
- case "100": r = "<span style='text-decoration:overline;'>C</span>CX"; break;
- case "010": r = "C<span style='text-decoration:overline;'>C</span>X"; break;
- case "001": r = "CC<span style='text-decoration:overline;'>X</span>"; break;
- }
- break;
- case "CSW":
- switch (pos)
- {
- case "100": r = "<span style='text-decoration:overline;'>C</span>SW"; break;
- case "010": r = "C<span style='text-decoration:overline;'>S</span>W"; break;
- case "001": r = "CS<span style='text-decoration:overline;'>W</span>"; break;
- }
- break;
- }
- if (compare == undefined) return r;
- return compare.toString().replace(/[\"]/g, "'").trim() == r;
- }
-
- var INSTRUCTIONS =
- [
- "X", "Pauli-X",
- "Y", "Pauli-Y",
- "Z", "Pauli-Z",
- "H", "Hadamard",
- "S", "Phase-S",
- "T", "Phase-T",
- "S<sup>†</sup>", "Phase-S Hermitian Transpose",
- "T<sup>†</sup>", "Phase-T Hermitian Transpose",
- "CX", "Controlled-NOT",
- "CCX", "Toffoli",
- "SW", "Swap",
- "CSW", "Fredkin",
- "RX", "Rotation-X",
- "RY", "Rotation-Y",
- "RZ", "Rotation-Z",
- "|0โฉ", "Qubit Set",
- "|1โฉ", "Qubit Reset",
- "<span class='measure'>๐</span>", "Measure",
- "=1", "Conditional Set",
- "=0", "Conditional Reset"
- ];
- var ProgramTrack =
- {
- SCALE: 64,
- STATE: [ [], [] ],
- DRAG: "",
- DRAGMODE: false,
- DRAGPOS: [0, 0],
- DRAGPOSINIT: [0, 0],
- DRAGELEM: undefined,
- DRAGHOLD: undefined,
- init: () =>
- {
- ProgramTrack.STATE = [ [], [] ];
- ProgramTrack.draw();
- displayResults([]);
- },
- adjust: x =>
- {
- if (x == 1)
- {
- if (ProgramTrack.STATE.length < 15)
- {
- var len = ProgramTrack.STATE[0].length;
- ProgramTrack.STATE[ProgramTrack.STATE.length] = new Array(len);
- for (var i = 0; i < len; i++)
- {
- ProgramTrack.STATE[ProgramTrack.STATE.length - 1][i] = ProgramTrack.STATE[ProgramTrack.STATE.length - 2][i];
- ProgramTrack.STATE[ProgramTrack.STATE.length - 2][i] = "";
- }
- }
- }
- else
- {
- if (ProgramTrack.STATE.length > 2)
- {
- var len = ProgramTrack.STATE[0].length;
- for (var i = 0; i < len; i++)
- {
- ProgramTrack.STATE[ProgramTrack.STATE.length - 2][i] = ProgramTrack.STATE[ProgramTrack.STATE.length - 1][i];
- }
- ProgramTrack.STATE.length -= 1;
- }
- }
- trackerCollapse(null);
- ProgramTrack.draw();
- $(".program-track-container")[0].scrollTop = 999999;
- },
- decode: () =>
- {
- var width = 0;
- for (var i = 0; i < ProgramTrack.STATE.length - 1; i++)
- {
- if (ProgramTrack.STATE[i].length > width)
- {
- width = ProgramTrack.STATE[i].length;
- }
- }
- var ret = "";
- var maxQ = -1;
- var maxC = -1;
- for (var i = 0; i < width; i++)
- {
- var ifblk = ProgramTrack.STATE[ProgramTrack.STATE.length - 1][i].trim();
- if (ifblk.length > 0)
- {
- var a = ifblk.split("<sub>")[0].includes("0") ? 0 : 1;
- var b = parseInt(ifblk.split("<sub>")[1].split("<")[0]) - 1;
- ifblk = "if(c[" + b + "]==" + a + ") ";
- b++;
- if (b > maxC) maxC = b;
- }
- var cx = [0, -1, -1];
- var sw = [0, -1, -1];
- var ccx = [0, -1, -1, -1];
- var csw = [0, -1, -1, -1];
- for (var j = 0; j < ProgramTrack.STATE.length - 1; j++)
- {
- var instr = ProgramTrack.STATE[j][i].trim();
- if (instr.length == 0) continue;
- if (j > maxQ) maxQ = j;
- switch (instr)
- {
- case "X": ret += ifblk + "x q[" + j + "];\n"; break;
- case "Y": ret += ifblk + "y q[" + j + "];\n"; break;
- case "Z": ret += ifblk + "z q[" + j + "];\n"; break;
- case "H": ret += ifblk + "h q[" + j + "];\n"; break;
- case "S": ret += ifblk + "s q[" + j + "];\n"; break;
- case "T": ret += ifblk + "t q[" + j + "];\n"; break;
- case "S<sup>โ </sup>": ret += ifblk + "sdg q[" + j + "];\n"; break;
- case "T<sup>โ </sup>": ret += ifblk + "tdg q[" + j + "];\n"; break;
- case "|1โฉ": ret += ifblk + "set q[" + j + "];\n"; break;
- case "|0โฉ": ret += ifblk + "reset q[" + j + "];\n"; break;
- default:
- if (instr.includes("๐"))
- {
- var num = parseInt(instr.split("<sub>")[1]);
- if (num > maxC) maxC = num;
- num -= 1;
- ret += ifblk + "measure q[" + j + "] -> c[" + num + "];\n";
- }
- else if (instr.includes("RX") || instr.includes("RY") || instr.includes("RZ"))
- {
- var tmpL = instr.replace("ฯ", "pi");
- var tmpR = tmpL.split("<span")[1].split("</span")[0].split(">")[1];
- tmpL = tmpL.split("<")[0].toLowerCase();
- ret += tmpL + "(" + tmpR + ") q[" + j + "];\n";
- }
- }
- if (overline("CX", "10", instr)) { if (cx[1] != -1) { cx[0] = 1; } cx[1] = j; }
- if (overline("CX", "01", instr)) { if (cx[2] != -1) { cx[0] = 1; } cx[2] = j; }
- if (overline("SW", "10", instr)) { if (sw[1] != -1) { sw[0] = 1; } sw[1] = j; }
- if (overline("SW", "01", instr)) { if (sw[2] != -1) { sw[0] = 1; } sw[2] = j; }
-
- if (overline("CCX", "100", instr)) { if (ccx[1] != -1) { ccx[0] = 1; } ccx[1] = j; }
- if (overline("CCX", "010", instr)) { if (ccx[2] != -1) { ccx[0] = 1; } ccx[2] = j; }
- if (overline("CCX", "001", instr)) { if (ccx[3] != -1) { ccx[0] = 1; } ccx[3] = j; }
- if (overline("CSW", "100", instr)) { if (csw[1] != -1) { csw[0] = 1; } csw[1] = j; }
- if (overline("CSW", "010", instr)) { if (csw[2] != -1) { csw[0] = 1; } csw[2] = j; }
- if (overline("CSW", "001", instr)) { if (csw[3] != -1) { csw[0] = 1; } csw[3] = j; }
- }
-
- if (cx[0]) { ret = "Duplicate `CX` at column " + (i + 1) + "."; break; }
- if (cx[1] != -1 && cx[2] != -1) { ret += ifblk + "cx q[" + cx[1] + "], q[" + cx[2] + "];\n"; }
- else if (cx[1] != -1 || cx[2] != -1) { ret = "Incomplete `CX` at column " + (i + 1) + "."; break; }
-
- if (sw[0]) { ret = "Duplicate `SW` at column " + (i + 1) + "."; break; }
- if (sw[1] != -1 && sw[2] != -1) { ret += ifblk + "swap q[" + sw[1] + "], q[" + sw[2] + "];\n"; }
- else if (sw[1] != -1 || sw[2] != -1) { ret = "Incomplete `SW` at column " + (i + 1) + "."; break; }
-
- if (ccx[0]) { ret = "Duplicate `CCX` at column " + (i + 1) + "."; break; }
- if (ccx[1] != -1 && ccx[2] != -1 && ccx[3] != -1) { ret += ifblk + "ccx q[" + ccx[1] + "], q[" + ccx[2] + "], q[" + ccx[3] + "];\n"; }
- else if (ccx[1] != -1 || ccx[2] != -1 || ccx[3] != -1) { ret = "Incomplete `CCX` at column " + (i + 1) + "."; break; }
-
- if (csw[0]) { ret = "Duplicate `CSW` at column " + (i + 1) + "."; break; }
- if (csw[1] != -1 && csw[2] != -1 && csw[3] != -1) { ret += ifblk + "cswap q[" + csw[1] + "], q[" + csw[2] + "], q[" + csw[3] + "];\n"; }
- else if (csw[1] != -1 || csw[2] != -1 || csw[3] != -1) { ret = "Incomplete `CSW` at column " + (i + 1) + "."; break; }
- }
- if (!ret.includes("Duplicate") && !ret.includes("Incomplete"))
- {
- if (maxC >= 0)
- {
- ret = "creg c[" + (maxC) + "];\n" + ret;
- }
- if (maxQ >= 0)
- {
-// ret = "qreg q[" + (maxQ + 1) + "];\n" + ret;
- ret = "qreg q[" + ($("[pidx*=',0'").length - 1) + "];\n" + ret;
- if (maxC >= 0)
- {
- ret += "sample c;\n";
- }
- else
- {
- ret += localStorage.getItem("nmpolicy") + " q;\n";
- }
- }
- }
- if (ProgramTrack.STATE[0].length == 0)
- {
- ret = "qreg q[" + (ProgramTrack.STATE.length - 1) + "];\n";
- ret += localStorage.getItem("nmpolicy") + " q;\n";
- }
-
- if (!ret.includes("Duplicate") && !ret.includes("Incomplete") && !ret.includes("born"))
- {
- if (localStorage.getItem("hvar") != null)
- {
- if (!isNaN(parseFloat(localStorage.getItem("hvar"))))
- {
- ret = "hvar " + localStorage.getItem("hvar") + ";\n" + ret;
- }
- }
- if (localStorage.getItem("noise") != null)
- {
- if (!isNaN(parseFloat(localStorage.getItem("noise"))))
- {
- if (parseFloat(localStorage.getItem("noise")) != 0)
- {
- ret = "noise " + localStorage.getItem("noise") + ";\n" + ret;
- }
- }
- }
- if (parseInt(localStorage.getItem("shots")) != shotsmax)
- {
- ret = "shots " + localStorage.getItem("shots") + ";\n" + ret;
- }
- }
- return ret;
- },
- drag: (e, erase, evt, dodrag) =>
- {
- var clientX, clientY;
- if (ismobile)
- {
- if (e.getAttribute("pidx") != null && dodrag)
- {
- var r = e.getBoundingClientRect();
- if (r.left > MobileInfo.x) return;
- if (r.right < MobileInfo.x) return;
- if ((window.scrollY + r.top) > MobileInfo.y) return;
- if ((window.scrollY + r.bottom) < MobileInfo.y) return;
- }
- MobileInfo.x = evt.touches[0].clientX;
- MobileInfo.y = evt.touches[0].clientY + window.scrollY;
- clientX = MobileInfo.x;
- clientY = MobileInfo.y;
- }
- else
- {
- clientX = evt.clientX;
- clientY = evt.clientY + window.scrollY;
- }
- ProgramTrack.DRAGMODE = erase;
- $(".program-instr")[0].style.display = "none";
- if (e.innerHTML.includes("Q") || e.innerHTML.includes("IF") || e.innerHTML.includes("..."))
- {
- return;
- }
- if (ismobile)
- {
- if (e.innerHTML != "..." && e.innerHTML != "" && e.getAttribute("pidx") != null)
- {
- if (dodrag == undefined)
- {
- MobileInfo.drag = new Date().getTime();
- setTimeout(() =>
- {
- var t = new Date().getTime();
- if (MobileInfo.drag != null)
- {
- if (t - MobileInfo.drag < 250)
- {
- return;
- }
- }
- ProgramTrack.drag(e, erase, evt, true);
- MobileInfo.drag = null;
- }, 250);
- evt.preventDefault();
- return;
- }
- else if (MobileInfo.drag == null)
- {
- evt.button = 2;
- }
- }
- }
- if (evt.button == 2)
- {
- if (e.getAttribute("pidx") != null)
- {
- var s = e.getAttribute("pidx").split(",");
- s[0] = parseInt(s[0]);
- s[1] = parseInt(s[1]);
- var state = ProgramTrack.STATE[s[0]][s[1]];
- if (overline("CX", "10", state)) ProgramTrack.STATE[s[0]][s[1]] = overline("CX", "01");
- if (overline("CX", "01", state)) ProgramTrack.STATE[s[0]][s[1]] = overline("CX", "10");
- if (overline("SW", "10", state)) ProgramTrack.STATE[s[0]][s[1]] = overline("SW", "01");
- if (overline("SW", "01", state)) ProgramTrack.STATE[s[0]][s[1]] = overline("SW", "10");
- if (overline("CCX", "100", state)) ProgramTrack.STATE[s[0]][s[1]] = overline("CCX", "010");
- if (overline("CCX", "010", state)) ProgramTrack.STATE[s[0]][s[1]] = overline("CCX", "001");
- if (overline("CCX", "001", state)) ProgramTrack.STATE[s[0]][s[1]] = overline("CCX", "100");
- if (overline("CSW", "100", state)) ProgramTrack.STATE[s[0]][s[1]] = overline("CSW", "010");
- if (overline("CSW", "010", state)) ProgramTrack.STATE[s[0]][s[1]] = overline("CSW", "001");
- if (overline("CSW", "001", state)) ProgramTrack.STATE[s[0]][s[1]] = overline("CSW", "100");
- if (state.includes("RX") || state.includes("RY") || state.includes("RZ"))
- {
- ProgramTrack.DRAGHOLD = [s[0], s[1]];
- getRotationAngle(state.split("<")[0]);
- }
- var instr = ProgramTrack.STATE[s[0]][s[1]].split("<sub>")[0];
- if (instr.includes("=1") || instr.includes("=0") || instr.includes("๐"))
- {
- var a = parseInt(ProgramTrack.STATE[s[0]][s[1]].split("<sub>")[1]) - 1;
- a = (a + 1) % 14;
- ProgramTrack.STATE[s[0]][s[1]] = instr + "<sub>" + (a + 1) + "</sub>";
- }
- ProgramTrack.draw();
- }
- evt.preventDefault();
- return false;
- }
-
- var px = ProgramTrack.SCALE + "px";
- var tr = "<tr style='height: " + px + "'>";
- var td = "<td style='width: " + px + "; height: " + px + "; cursor: grab;'>";
- if (ProgramTrack.DRAG == "" && e.innerHTML.trim().length > 0)
- {
- var h = e.innerHTML.replace(/[<].*?[>]/g, "");
- h = e.innerHTML;
- ProgramTrack.DRAG = h;
- ProgramTrack.DRAGPOS = [clientX, clientY];
- $(".program-drag")[0].innerHTML = tr + td + h + "</tr></td>";
- $(".program-drag")[0].style.visibility = "";
- }
- if (erase)
- {
- var s = e.getAttribute("pidx").split(",");
- s[0] = parseInt(s[0]);
- s[1] = parseInt(s[1]);
- ProgramTrack.STATE[s[0]][s[1]] = "";
- e.innerHTML = "";
- }
- var x = $(".program-drag")[0];
- var w = parseFloat(getComputedStyle(x).width.replace("px", "")) / 2;
- var h = parseFloat(getComputedStyle(x).height.replace("px", "")) / 2;
- x.style.position = "absolute";
- x.style.left = (clientX - w) + "px";
- x.style.top = (clientY - h) + "px";
- },
- draw: () =>
- {
- var drag_event = (ismobile ? "ontouchstart" : "onmousedown") + "='ProgramTrack.drag(this, true, event);'";
- var px = ProgramTrack.SCALE + "px";
- var tr = "<tr style='height: " + px + "'>";
- var td = "<td style='min-width: " + px + "; width: " + px + "; height: " + px + ";' qubit='1'";
- td += ">";
- var html = "";
- for (var i = 0; i < ProgramTrack.STATE.length; i++)
- {
- if (i == ProgramTrack.STATE.length - 1)
- {
- td = td.replace("qubit='1'", "qubit='0'");
- html += tr + td.replace(drag_event, "");
- html += "IF</td>";
- }
- else
- {
- td = td.replace("qubit='0'", "qubit='1'");
- html += tr + td.replace(drag_event, "");
- html += "Q<sub>" + (i + 1) + "</sub></td>";
- }
- td = td.replace(">", drag_event + ">");
- for (var j = 0; j < ProgramTrack.STATE[i].length; j++)
- {
- var tdi = td.replace("<td", "<td pidx='" + i + "," + j + "' ");
- html += tdi + ProgramTrack.STATE[i][j] + "</td>";
- }
- html += td.replace("<td", "<td pidx='" + i + "," + ProgramTrack.STATE[i].length + "' ").replace(drag_event, "") + "...</td></tr>";
- }
- $(".program-track")[0].innerHTML = html;
-
- td = "<td style='width: " + px + "; height: " + px + "; cursor: grab;'";
- td += " oncontextmenu='return false;'";
- td += " " + drag_event.replace("true", "false");
- var itr = 0;
- html = tr;
- for (var i = 0; i < INSTRUCTIONS.length; i += 2)
- {
- html += td + "title='" + INSTRUCTIONS[i + 1] + "'" + ">" + INSTRUCTIONS[i] + "</td>";
- itr++;
- if (itr > 4 && i != INSTRUCTIONS.length - 2)
- {
- html += "</tr>" + tr;
- itr = 0;
- }
- }
- html += "</tr>";
- $(".program-instr")[0].innerHTML = html;
- IstinaEditor.setText(ProgramTrack.decode());
- }
- };
-
- window.onload = function()
- {
- if (localStorage.getItem("noise") == null)
- localStorage.setItem("noise", 0);
- if (localStorage.getItem("hvar") == null)
- localStorage.setItem("hvar", "");
- if (localStorage.getItem("shots") == null)
- localStorage.setItem("shots", shotsmax);
- if (localStorage.getItem("nmpolicy") == null)
- localStorage.setItem("nmpolicy", "born");
- ProgramTrack.draw();
- //$(".program-track")[0].parentNode.style.height = Math.round($(".program-instr")[0].getBoundingClientRect().height) + "px";
- $(".program-track")[0].parentNode.style.width = "100%";
- //Math.round($(".program-instr")[0].getBoundingClientRect().width) + "px";
- $(".program-track-container")[0].style.height = (ProgramTrack.SCALE*4 + 10) + "px"
- $(".program-track-container")[0].style.width = $(".program-track-container")[0].parentNode.getBoundingClientRect().width + "px"
- $(".program-track-container")[0].scrollTo(0, 0);
- };
-
- document.body.addEventListener("keydown", e =>
- {
- modalFixes();
- });
- var MobileInfo = { x: 0, y: 0, time: 0 };
- document.body.addEventListener("touchstart", e =>
- {
- MobileInfo.x = e.touches[0].clientX;
- MobileInfo.y = e.touches[0].clientY + window.scrollY;
- MobileInfo.time = new Date().getTime();
- var clientX = MobileInfo.x;
- var clientY = MobileInfo.y;
- var trackerElem = $("[pidx*=','],.program-expand td");
- for (var i = 0; i < trackerElem.length; i++)
- {
- trackerElem[i].style.backgroundColor = "";
- var r = trackerElem[i].getBoundingClientRect();
- if (r.left > clientX) continue;
- if (r.right < clientX) continue;
- if ((window.scrollY + r.top) > clientY) continue;
- if ((window.scrollY + r.bottom) < clientY) continue;
- trackerElem[i].style.backgroundColor = "rgb(75, 0, 0)";
- }
- }, { passive: false });
- document.body.addEventListener(ismobile ? "touchmove" : "mousemove", e =>
- {
- var clientX, clientY;
- if (ismobile)
- {
- MobileInfo.x = e.touches[0].clientX
- MobileInfo.y = e.touches[0].clientY + window.scrollY;
- clientX = MobileInfo.x;
- clientY = MobileInfo.y;
- }
- else
- {
- clientX = e.clientX;
- clientY = e.clientY + window.scrollY;
- }
- modalFixes();
-
- var trackerElem = $("[pidx*=','],.program-expand td");
- for (var i = 0; i < trackerElem.length; i++)
- {
- trackerElem[i].style.backgroundColor = "";
- var r = trackerElem[i].getBoundingClientRect();
- if (r.left > clientX) continue;
- if (r.right < clientX) continue;
- if ((window.scrollY + r.top) > clientY) continue;
- if ((window.scrollY + r.bottom) < clientY) continue;
- trackerElem[i].style.backgroundColor = "rgb(75, 0, 0)";
- }
-
- var x = $(".program-drag")[0];
- var w = parseFloat(getComputedStyle(x).width.replace("px", "")) / 2;
- var h = parseFloat(getComputedStyle(x).height.replace("px", "")) / 2;
- x.style.position = "absolute";
- x.style.left = (clientX - w) + "px";
- x.style.top = (clientY - h) + "px";
- if ($(".program-drag")[0].style.visibility != "hidden") e.preventDefault();
- }, { passive: false });
- document.body.addEventListener(ismobile ? "touchstart" : "mousedown", e =>
- {
- var clientX, clientY;
- if (ismobile)
- {
- MobileInfo.x = e.touches[0].clientX
- MobileInfo.y = e.touches[0].clientY + window.scrollY;
- clientX = MobileInfo.x;
- clientY = MobileInfo.y;
- }
- else
- {
- clientX = e.clientX;
- clientY = e.clientY + window.scrollY;
- }
- ProgramTrack.DRAGPOSINIT = [ clientX, clientY ];
- });
- document.body.addEventListener(ismobile ? "touchend" : "mouseup", e =>
- {
- var clientX, clientY, touchTime;
- if (ismobile)
- {
- clientX = MobileInfo.x;
- clientY = MobileInfo.y;
- touchTime = new Date().getTime() - MobileInfo.time;
- MobileInfo.drag = null;
- }
- else
- {
- clientX = e.clientX;
- clientY = e.clientY + window.scrollY;
- }
- var trackerElem = $("[pidx*=',']");
- for (var i = 0; i < trackerElem.length; i++)
- {
- var r = trackerElem[i].getBoundingClientRect();
- if (r.left > clientX) continue;
- if (r.right < clientX) continue;
- if ((window.scrollY + r.top) > clientY) continue;
- if ((window.scrollY + r.bottom) < clientY) continue;
- trackerElem = trackerElem[i];
- break;
- }
- var rr = $("[pidx='1,0'")[0].getBoundingClientRect();
- if (trackerElem.length > 0)
- {
- trackerElem = document.body;
- }
- if ($(".program-drag")[0].style.visibility == "hidden")
- {
- var str = trackerElem.getAttribute("pidx");
- if (str) {} else {str = ""};
- if (str.includes(",") && (trackerElem.innerHTML == "..." || trackerElem.innerHTML == ""))
- {
- var dist = Math.sqrt(Math.pow(clientX - ProgramTrack.DRAGPOSINIT[0], 2) + Math.pow(clientY - ProgramTrack.DRAGPOSINIT[1], 2));
- if (dist > 32) return;
- $(".program-instr")[0].style.display = "";
- var w = Math.floor($(".program-instr")[0].getBoundingClientRect().width);
- var h = Math.floor($(".program-instr")[0].getBoundingClientRect().height);
- $(".program-instr")[0].style.display = "none";
- ProgramTrack.DRAGELEM = trackerElem;
- $(".program-instr")[0].className = $(".program-instr")[0].className.replace("menu-hidden", "").trim();
- $(".program-instr")[0].className += " menu-reveal";
- $(".program-instr")[0].style.position = "fixed";
- var t = (clientY - window.scrollY) + h;
- var l = clientX + w;
- var dt = t > window.innerHeight ? (window.innerHeight - t) : 0;
- var dl = l > window.innerWidth ? (window.innerWidth - l) : 0;
- $(".program-instr")[0].style.top = (clientY - window.scrollY + dt) + "px";
- $(".program-instr")[0].style.left = (clientX + dl) + "px";
- if ($(".program-instr")[0].getBoundingClientRect().right > window.innerWidth)
- {
- $(".program-instr")[0].style.left = (clientX - Math.ceil(window.innerWidth - $(".program-instr")[0].getBoundingClientRect().right)) + "px";
- }
- $(".program-instr")[0].style.animation = "animation-reveal 0.2s forwards";
- $(".program-instr")[0].style.display = "";
- }
- else
- {
- $(".program-instr")[0].style.display = "none";
- }
- return;
- }
- $(".program-instr")[0].style.display = "none";
- ProgramTrack.draw();
- $(".program-drag")[0].style.visibility = "hidden";
- ProgramTrack.DRAG = "";
-
- var dist = Math.sqrt(Math.pow(ProgramTrack.DRAGPOS[0] - clientX, 2) + Math.pow(ProgramTrack.DRAGPOS[1] - clientY, 2));
- if (dist <= 16 && !ProgramTrack.DRAGMODE) trackerElem = ProgramTrack.DRAGELEM;
- var attr = trackerElem.getAttribute("pidx");
- if (trackerElem.innerHTML.trim() != "...") trackerCollapse(attr);
- if (attr == null) return;
- attr = attr.split(",");
- attr[0] = parseInt(attr[0]);
- attr[1] = parseInt(attr[1]);
- var html = $(".program-drag td")[0].innerHTML;
- var qubit = parseInt(trackerElem.getAttribute("qubit"));
- switch (html.split("<")[0])
- {
- case "=1": case "=0":
- if (qubit) { trackerCollapse(null); return };
- break;
- default:
- if (!qubit) { trackerCollapse(null); return };
- }
- var f = [0, 0, 0];
- switch (html)
- {
- case "CX":
- if (ProgramTrack.STATE[attr[0]].length > attr[1])
- {
- for (var i = 0; i < ProgramTrack.STATE.length; i++)
- {
- if (i != attr[0])
- {
- if (overline("CX", "10", ProgramTrack.STATE[i][attr[1]])) f[0] = 1;
- if (overline("CX", "01", ProgramTrack.STATE[i][attr[1]])) f[1] = 1;
- }
- }
- }
- if (!f[0]) html = overline("CX", "10");
- else html = overline("CX", "01");
- break;
- case "SW":
- if (ProgramTrack.STATE[attr[0]].length > attr[1])
- {
- for (var i = 0; i < ProgramTrack.STATE.length; i++)
- {
- if (i != attr[0])
- {
- if (overline("SW", "10", ProgramTrack.STATE[i][attr[1]])) f[0] = 1;
- if (overline("SW", "01", ProgramTrack.STATE[i][attr[1]])) f[1] = 1;
- }
- }
- }
- if (!f[0]) html = overline("SW", "10");
- else html = overline("SW", "01");
- break;
- case "CCX":
- if (ProgramTrack.STATE[attr[0]].length > attr[1])
- {
- for (var i = 0; i < ProgramTrack.STATE.length; i++)
- {
- if (i != attr[0])
- {
- if (overline("CCX", "100", ProgramTrack.STATE[i][attr[1]])) f[0] = 1;
- if (overline("CCX", "010", ProgramTrack.STATE[i][attr[1]])) f[1] = 1;
- if (overline("CCX", "001", ProgramTrack.STATE[i][attr[1]])) f[2] = 1;
- }
- }
- }
- if (!f[0]) html = overline("CCX", "100");
- else if (!f[1]) html = overline("CCX", "010");
- else html = overline("CCX", "001");
- break;
- case "CSW":
- if (ProgramTrack.STATE[attr[0]].length > attr[1])
- {
- for (var i = 0; i < ProgramTrack.STATE.length; i++)
- {
- if (i != attr[0])
- {
- if (overline("CSW", "100", ProgramTrack.STATE[i][attr[1]])) f[0] = 1;
- if (overline("CSW", "010", ProgramTrack.STATE[i][attr[1]])) f[1] = 1;
- if (overline("CSW", "001", ProgramTrack.STATE[i][attr[1]])) f[2] = 1;
- }
- }
- }
- if (!f[0]) html = overline("CSW", "100");
- else if (!f[1]) html = overline("CSW", "010");
- else html = overline("CSW", "001");
- break;
- case "=1": html = "=1<sub>1</sub>"; break;
- case "=0": html = "=0<sub>1</sub>"; break;
- case "RX":
- case "RY":
- case "RZ":
- html += "<br /><span style='font-size: 12px'>0</span>";
- ProgramTrack.DRAGHOLD = [attr[0], attr[1]];
- getRotationAngle(html.split("<")[0]);
- break;
- default:
- if (html.includes("๐") && !html.includes("<sub>"))
- {
- html += "<sub>" + (attr[0] + 1) + "</sub>";
- }
- }
-
- ProgramTrack.STATE[attr[0]][attr[1]] = html;
- var mx = -1;
- for (var i = 0; i < ProgramTrack.STATE.length; i++)
- {
- if (ProgramTrack.STATE[i].length > mx)
- {
- mx = ProgramTrack.STATE[i].length;
- }
- }
- for (var i = 0; i < ProgramTrack.STATE.length; i++)
- {
- while (ProgramTrack.STATE[i].length < mx)
- {
- ProgramTrack.STATE[i][ProgramTrack.STATE[i].length] = "";
- }
- }
- ProgramTrack.draw();
- if (trackerElem.innerHTML.trim() == "...")
- {
- $(".program-track-container")[0].scrollLeft = 999999;
- }
- }, { passive: false });
- //Chart
- var resultsChart = new Chart(document.getElementById("resultsChart"),
- {
- type: 'bar',
- data:
- {
- labels: [ ],
- datasets:
- [{
- label: '',
- data: [],
- borderWidth: 1
- }]
- },
- options:
- {
- scales: { y: { beginAtZero: true } },
- plugins: { legend: { display: false } },
-
- animation:
- {
- onComplete: function()
- {
- $("[onclick*=screenshot]")[0].style.pointerEvents = "";
- }
- }
- }
- });
- function displayResults(results)
- {
- var bitCount = Math.ceil(Math.log2(results.length));
- resultsChart.data.datasets[0].data = results;
- resultsChart.data.labels = [];
- for (var i = 0; i < results.length; i++)
- {
- resultsChart.data.labels[resultsChart.data.labels.length] = i.toString(2).padStart(bitCount, "0");
- }
- resultsChart.update();
- }
- function downloadResults()
- {
- var csv = "";
- for (var i = 0; i < resultsChart.data.labels.length; i++)
- {
- csv += resultsChart.data.labels[i] + ",";
- csv += resultsChart.data.datasets[0].data[i] + "\r\n";
- }
- if (csv.length == 0)
- {
- errorModal("No data to download.");
- return;
- }
- var a = document.createElement("a");
- a.href = "data:text/plain;base64," + btoa(csv).replaceAll(/[=]/g, "");
- a.download = "data.csv";
- localStorage.setItem("downloadFileName", a.download);
- document.body.appendChild(a);
- a.click();
- a.remove();
- }
-
- $("#run")[0].addEventListener("click", () =>
- {
- $("[onclick*=screenshot]")[0].style.pointerEvents = "none";
- if (IstinaEditor.getText().trim().length == 0)
- {
- errorModal("There must be code in the code editor in order to execute the program.");
- return;
- }
- createBlocker();
- var key = localStorage.getItem("apikey");
- key = key ? key : "";
- try
- {
- key = atob(key);
- }
- catch
- {
- $("#blocker-div")[0].remove();
- $("#blocker-img")[0].remove();
- errorModal("Please click the gear icon and input your API key.");
- return;
- }
- if (key.split(":").length != 3)
- {
- $("#blocker-div")[0].remove();
- $("#blocker-img")[0].remove();
- errorModal("Please click the gear icon and input your API key.");
- return;
- }
- EstoulsAPI.username = key.split(":")[0];
- EstoulsAPI.apikey = key.split(":")[1];
- EstoulsAPI.endpoint = "https://" + key.split(":")[2];
- EstoulsAPI.request(IstinaEditor.getText()).then(x =>
- {
- $("#blocker-div")[0].remove();
- $("#blocker-img")[0].remove();
- if (x.success && x.response.trim().length > 0)
- {
- var lines = x.response.trim().split("\n");
- var type = lines[0].split("\t").length;
- var results = [];
- if (type == 3)
- {
- for (var i = 0; i < lines.length; i++)
- {
- results[results.length] = parseInt(lines[i].split("\t")[1]);
- }
- displayResults(results);
- }
- else if (type == 2)
- {
- for (var i = 0; i < lines.length; i++)
- {
- results[results.length] = parseFloat(lines[i].split("\t")[1].replace("%", "")) / 100.0;
- }
- displayResults(results);
- }
- else
- {
- errorModal(x.response, 1);
- }
- }
- else if (x.success && x.response.trim().length == 0)
- {
- errorModal(x.response, 1);
- }
- else
- {
- errorModal(x.response, 1);
- }
- }).catch(x =>
- {
- $("#blocker-div")[0].remove();
- $("#blocker-img")[0].remove();
- errorModal(x.message, 1);
- });
- });
- MicroModal.init();
- function resetDialog()
- {
- $(".modal__container")[0].style.width = "";
- $(".modal__container")[0].style.height = "";
- $(".modal__container")[0].style.paddingBottom = "";
- $(".modal__container")[0].style.maxWidth = "";
- $(".modal__container")[0].style.backgroundColor = "";
- $(".modal__footer")[0].style.display = "";
- }
- function menu(cmd, evt)
- {
- resetDialog();
- $(".program-instr")[0].style.display = "none";
- switch (cmd)
- {
- case "clear":
- $("#modal-main-title")[0].innerHTML = "Clear Project";
- $("#modal-main-content")[0].innerHTML = "<p>Are you sure you want to clear this project?</p>";
- $("#modal-main-cancel")[0].style.display = "";
- $("#modal-main-confirm")[0].style.display = "";
- $("#modal-main-confirm")[0].setAttribute("onclick", "ProgramTrack.init(); closeModal();");
- MicroModal.show("modal-main");
- break;
- case "settings":
- var apikey = localStorage.getItem("apikey");
- apikey = (apikey ? apikey : "").replace("'", "").replace("\"", "").replace("\n", "");
- $(".modal__container")[0].style.width = "500px";
- $("#modal-main-title")[0].innerHTML = "Settings";
- $("#modal-main-content")[0].innerHTML = `
- <p>API key: </p><input type='text' id='apikey' />
- <br />
- <table style='width: 100%;'>
- <tr>
- <td style='width: 50%;'>
- <p>Shots: </p><input type='number' id='shots' step='1' />
- </td>
- <td style='width: 50%;'>
- <p>Noise: </p><input type='number' id='noise' step='0.01' />
- </td>
- </tr>
- <tr>
- <td style='width: 50%;'>
- <p>No-Measurement Policy: </p>
- <select id='nmpolicy'>
- <option value='born'>Born Rule</option>
- <option value='sample'>Sample Qubits</option>
- </select>
- </td>
- <td style='width: 50%;'>
- <p>Hidden variable: </p><input type='number' id='hvar' step='0.01' />
- </td>
- </tr>
- </table>
- `;
- $("#apikey")[0].style.width = "100%";
- $("#noise")[0].style.width = "100%";
- $("#hvar")[0].style.width = "100%";
- $("#shots")[0].style.width = "100%";
- $("#nmpolicy")[0].style.width = "100%";
- $("#apikey")[0].addEventListener("click", () =>
- {
- $("#apikey")[0].selectionStart = 0;
- $("#apikey")[0].selectionEnd = $("#apikey")[0].value.length;
- });
- $("#apikey")[0].addEventListener("keydown", e => { if (e.key == "Enter") { $("#modal-main-confirm")[0].click(); } })
- $("#noise")[0].addEventListener("keydown", e => { if (e.key == "Enter") { $("#modal-main-confirm")[0].click(); } });
- $("#hvar")[0].addEventListener("keydown", e => { if (e.key == "Enter") { $("#modal-main-confirm")[0].click(); } });
- $("#shots")[0].addEventListener("keydown", e => { if (e.key == "Enter") { $("#modal-main-confirm")[0].click(); } });
- var noiseChange = () =>
- {
- var v = parseFloat($("#noise")[0].value);
- if (isNaN(v)) v = 0;
- if (v < 0) v = 0;
- if (v > 100) v = 100;
- $("#noise")[0].value = v;
- };
- var hvarChange = () =>
- {
- var v = parseFloat($("#hvar")[0].value);
- if (isNaN(v)) v = "";
- $("#hvar")[0].value = v;
- }
- var shotsChange = () =>
- {
- var v = parseInt($("#shots")[0].value);
- if (isNaN(v)) v = shotsmax;
- if (v <= 0) v = 1;
- if (v > shotsmax) v = shotsmax;
- $("#shots")[0].value = v;
- };
- var changeEvents = ["change", /*"keydown", "keyup",*/ "mouseenter", "mouseleave"];
- for (var i = 0; i < changeEvents.length; i++)
- {
- $("#noise")[0].addEventListener(changeEvents[i], e => { noiseChange(); });
- $("#hvar")[0].addEventListener(changeEvents[i], e => { hvarChange(); });
- $("#shots")[0].addEventListener(changeEvents[i], e => { shotsChange(); });
- }
- $("#apikey")[0].value = apikey;
- $("#noise")[0].value = localStorage.getItem("noise");
- $("#hvar")[0].value = localStorage.getItem("hvar");
- $("#shots")[0].value = localStorage.getItem("shots");
- $("#nmpolicy")[0].value = localStorage.getItem("nmpolicy");
- $("#modal-main-confirm")[0].style.display = "";
- $("#modal-main-cancel")[0].style.display = "";
- $("#modal-main-confirm")[0].setAttribute("onclick",
- `
- localStorage.setItem('apikey', $('#apikey')[0].value);
- localStorage.setItem('noise', $('#noise')[0].value);
- localStorage.setItem('hvar', $('#hvar')[0].value);
- localStorage.setItem('shots', $('#shots')[0].value);
- localStorage.setItem('nmpolicy', $('#nmpolicy')[0].value);
- closeModal();
- ProgramTrack.draw();
- `);
- MicroModal.show("modal-main");
- document.activeElement.blur();
- break;
- case "save":
- if (ProgramTrack.STATE[0].length == 0)
- {
- errorModal("You must place at least one logic gate.");
- return;
- }
- var a = document.createElement("a");
- var obj =
- {
- info: "QAnsel v0.5",
- data: ProgramTrack.STATE,
- graph: [ resultsChart.data.labels, resultsChart.data.datasets[0].data ],
- text: IstinaEditor.getText()
- };
- a.href = "data:text/plain;base64," + btoa(btoa(escape(JSON.stringify(obj)))).replaceAll(/[=]/g, "");
- a.download = "program.txt";
- localStorage.setItem("downloadFileName", a.download);
- document.body.appendChild(a);
- a.click();
- a.remove();
- break;
- case "chart":
- downloadResults();
- break;
- case "help":
- var h = "<select id='downloadSelect' style='width: 100%;'>";
- h += "<option value='imports/guide.pdf'>Quantum Computing Guide with QAnsel (PDF)</option>";
- if (!ismobile)
- {
- h += "<option value='imports/QAnsel.apk'>Mobile App (Android)</option>";
- h += "<option value='~' disabled>Desktop Executable (Windows) [Coming Soon!]</option>";
- h += "<option value='~' disabled>Source Code [Coming Soon!]</option>";
- }
- h += "</select>";
- $("#modal-main-title")[0].innerHTML = "Downloads";
- $("#modal-main-content")[0].innerHTML = h;
- $("#modal-main-confirm")[0].style.display = "";
- $("#modal-main-cancel")[0].style.display = "";
- $("#modal-main-confirm")[0].setAttribute("onclick", "downloadFile($('#downloadSelect')[0].value); closeModal();");
- MicroModal.show("modal-main");
- break;
- case "sphere":
- var sw = Math.floor(window.innerWidth * 0.9);
- var sh = Math.floor(window.innerHeight * 0.9);
- $(".modal__container")[0].style.width = sw + "px";
- $(".modal__container")[0].style.height = sh + "px";
- $(".modal__container")[0].style.paddingBottom = "0px";
- $(".modal__container")[0].style.maxWidth = sw + "px";
- var blochPictureMode = evt.button == 2;
- $(".modal__container")[0].style.backgroundColor = blochPictureMode ? "" : "black";
- $(".modal__footer")[0].style.display = "none";
- $("#modal-main-title")[0].innerHTML = "Bloch Sphere Visualizer";
- var h = "<iframe src='imports/bloch-sphere.html" + (blochPictureMode ? "?picturemode=true" : "") + "' style='border: 0; width: 100%; height: " + (sh - 130) + "px'></iframe>";
- $("#modal-main-content")[0].innerHTML = h;
- $("#modal-main-confirm")[0].style.display = "";
- $("#modal-main-cancel")[0].style.display = "none";
- $("#modal-main-confirm")[0].setAttribute("onclick", "closeModal();");
- MicroModal.show("modal-main");
- break;
- case "open":
- $("#file-input")[0].click();
- break;
- case "screenshot":
- createBlocker(true);
- var backups =
- [
- resultsChart.data.datasets[0].borderColor,
- resultsChart.data.datasets[0].backgroundColor,
- resultsChart.options.animation.duration,
- resultsChart.config.options.scales.y.ticks.color,
- resultsChart.config.options.scales.x.ticks.color,
- $(".program-track-container")[0].style.height,
- $(".main-table")[0].cellPadding,
- $(".main-table")[0].cellSpacing,
- $(".program-track")[0].cellPadding,
- $(".program-track")[0].cellSpacing,
- $(".istina-linecounter")[0].style.height,
- $(".istina-overlay")[0].style.height,
- $(".istina-basis")[0].style.height,
- $(".program-track-container")[0].style.width,
- resultsChart.canvas.getAttribute("style")
- ];
- $(".program-track-container")[0].style.height = "100%";
- $(".program-track-container")[0].style.width = "100%";
- document.body.style.backgroundColor = "rgba(0, 0, 0, 0)";
- $(".main-table tr")[0].style.display = "none";
- $("istina-editor div")[0].style.backgroundColor = "rgba(0, 0, 0, 0)";
- $(".istina-overlay")[0].style.backgroundColor = "rgba(0, 0, 0, 0)";
- $(".istina-overlay")[0].style.color = "black";
- $(".istina-basis")[0].style.opacity = "0%";
- $(".istina-linecounter")[0].style.color = "black"
- resultsChart.data.datasets[0].borderColor = "rgba(0, 0, 0, 255)";
- resultsChart.data.datasets[0].backgroundColor = "rgba(196, 196, 196, 0.5)";
- resultsChart.options.animation.duration = 0;
- resultsChart.config.options.scales.y.ticks.color = "black";
- resultsChart.config.options.scales.x.ticks.color = "black";
- Chart.defaults.font.weight = "bold";
- resultsChart.update();
- for (var i = 0; i < $(".program-track td").length; i++)
- {
- $(".program-track td")[i].style.backgroundColor = "rgba(0, 0, 0, 0)";
- $(".program-track td")[i].style.color = "black";
- }
- for (var i = 0; i < $(".program-expand td").length; i++)
- {
- $(".program-expand td")[i].style.backgroundColor = "rgba(0, 0, 0, 0)";
- $(".program-expand td")[i].style.color = "black";
- }
- for (var i = 0; i < $(".measure").length; i++)
- {
- $(".measure")[i].style.filter = "brightness(0%)";
- }
- for (var i = 0; i < $(".istina-overlay span").length; i++)
- {
- $(".istina-overlay span")[i].style.color = "rgba(0, 0, 0, 255)";
- }
- for (var i = 0; i < $("td[onclick*=adjust]").length; i++)
- {
- $("td[onclick*=adjust]")[i].style.display = "none";
- }
- for (var i = 0; i < $("[pidx*='," + ProgramTrack.STATE[0].length + "']").length; i++)
- {
- $("[pidx*='," + ProgramTrack.STATE[0].length + "']")[i].style.display = "none";
- }
- var doHide = true;
- for (var i = 0; i < ProgramTrack.STATE[0].length; i++)
- {
- var tmp = ProgramTrack.STATE[ProgramTrack.STATE.length - 1][i].trim();
- if (tmp.length > 0 && tmp != "...")
- {
- doHide = false;
- break;
- }
- }
- if (doHide) $(".program-track tr")[$(".program-track tr").length - 1].style.display = "none";
- $(".main-table")[0].cellPadding = 0;
- $(".main-table")[0].cellSpacing = 0;
- $(".program-track")[0].cellPadding = 0;
- $(".program-track")[0].cellSpacing = 0;
- $(".istina-linecounter")[0].style.height = "100%";
- $(".istina-overlay")[0].style.height = "100%";
- $(".istina-basis")[0].style.height = "100%";
- //$(".main-table")[0].border = "0";
- //$("istina-editor")[0].parentNode.style = "width: 50%; height: 100%; border-color black; border-width: 1px 0px 1px 1px; border-style: solid;";
- //$("#resultsChart")[0].parentNode.style = "width: 50%; border-color black; border-width: 1px 1px 1px 1px; border-style: solid;";
- domtoimage.toPng($(".main-table")[0]).then(x =>
- {
-
- var a = document.createElement("a");
- a.href = x.replaceAll(/[=]/g, "");
- a.download = "screenshot.png";
- localStorage.setItem("downloadFileName", a.download);
- document.body.appendChild(a);
- a.click();
- a.remove();
- $(".program-track-container")[0].style.height = backups[5];
- $(".program-track-container")[0].style.width = backups[13];
- $(".main-table")[0].border = 1;
- document.body.style.backgroundColor = "";
- $(".main-table tr")[0].style.display = "";
- $("istina-editor div")[0].style.backgroundColor = "";
- $(".istina-overlay")[0].style.backgroundColor = "";
- $(".istina-overlay")[0].style.color = "";
- $(".istina-basis")[0].style.opacity = "";
- $(".istina-linecounter")[0].style.color = ""
- resultsChart.data.datasets[0].borderColor = backups[0];
- resultsChart.data.datasets[0].backgroundColor = backups[1];
- resultsChart.config.options.scales.y.ticks.color = backups[3];
- resultsChart.config.options.scales.x.ticks.color = backups[4];
- Chart.defaults.font.weight = null;
- resultsChart.canvas.setAttribute("style", backups[14]);
- resultsChart.update();
- resultsChart.options.animation.duration = backups[2];
- for (var i = 0; i < $(".program-track td").length; i++)
- {
- $(".program-track td")[i].style.backgroundColor = "";
- $(".program-track td")[i].style.color = "";
- }
- for (var i = 0; i < $(".program-expand td").length; i++)
- {
- $(".program-expand td")[i].style.backgroundColor = "";
- $(".program-expand td")[i].style.color = "";
- }
- for (var i = 0; i < $(".istina-overlay span").length; i++)
- $(".istina-overlay span")[i].style.color = "";
- for (var i = 0; i < $(".measure").length; i++)
- {
- $(".measure")[i].style.filter = "";
- }
- $(".program-track-container")[0].style.height[5];
- for (var i = 0; i < $("td[onclick*=adjust]").length; i++)
- {
- $("td[onclick*=adjust]")[i].style.display = "";
- }
- for (var i = 0; i < $("[pidx*='," + ProgramTrack.STATE[0].length + "']").length; i++)
- {
- $("[pidx*='," + ProgramTrack.STATE[0].length + "']")[i].style.display = "";
- }
- $(".program-track tr")[$(".program-track tr").length - 1].style.display = "";
- $(".main-table")[0].cellPadding = backups[6];
- $(".main-table")[0].cellSpacing = backups[7];
- $(".program-track")[0].cellPadding = backups[8];
- $(".program-track")[0].cellSpacing = backups[9];
- $(".istina-linecounter")[0].style.height = backups[10];
- $(".istina-overlay")[0].style.height = backups[11];
- $(".istina-basis")[0].style.height = backups[12];
- //$(".main-table")[0].border = "1";
- //$("istina-editor")[0].parentNode.style = "width: 50%; height: 100%;";
- //$("#resultsChart")[0].parentNode.style = "width: 50%;";
- $("#blocker-div")[0].remove();
- $("#blocker-img")[0].remove();
- });
- break;
- }
- }
- function errorModal(err, mode)
- {
- resetDialog();
- $("[onclick*=screenshot]")[0].style.pointerEvents = "";
- if (mode == 1)
- {
- try
- {
- err = err.replace(/[\n]/g, "<br />");
- }
- catch
- {
- err = "Unknown server-side error.";
- }
- }
- $(".program-instr")[0].style.display = "none";
- $("#modal-main-confirm")[0].setAttribute("onclick", "closeModal();");
- $("#modal-main-cancel")[0].style.display = "none";
- $("#modal-main-title")[0].innerHTML = "An Error Occurred";
- if (err.trim().length == 0) err = "Empty response.";
- $("#modal-main-content")[0].innerHTML = "<p style='color: red;'>" + err + "</p>";
- MicroModal.show("modal-main");
- }
- function closeModal()
- {
- MicroModal.close();
- }
- $("#file-input")[0].addEventListener("change", e =>
- {
- var reader = new FileReader();
- reader.addEventListener("load", () =>
- {
- try
- {
- var obj = JSON.parse(unescape(atob(reader.result)));
- if (obj.data == undefined)
- {
- ProgramTrack.STATE = obj;
- ProgramTrack.draw();
- }
- else
- {
- ProgramTrack.STATE = obj.data;
- ProgramTrack.draw();
- if (parseFloat(obj.info.split("v")[1]) >= 0.5)
- {
- resultsChart.data.labels = obj.graph[0];
- resultsChart.data.datasets[0].data = obj.graph[1];
- IstinaEditor.setText(obj.text);
- resultsChart.update();
- }
- }
- }
- catch
- {
- errorModal("Could not open this file.");
- }
- }, false);
- if (e.target.files.length == 1)
- {
- reader.readAsText(e.target.files[0]);
- }
- });
- function downloadFile(file)
- {
- var xhr = new XMLHttpRequest();
- xhr.open("GET", file, true);
- xhr.responseType = "arraybuffer";
- xhr.onload = function()
- {
- if (xhr.status == 200)
- {
- var binary = "";
- var bytes = new Uint8Array(xhr.response);
- var len = bytes.byteLength;
- for (var i = 0; i < len; i++)
- binary += String.fromCharCode(bytes[i]);
- var base64 = window.btoa(binary);
- var dataUri = "data:;base64," + base64;
- var d = file.replace(/[\\]/g, "/").split("/");
- var a = document.createElement("a");
- a.href = dataUri;
- a.download = d[d.length - 1];
- localStorage.setItem("downloadFileName", a.download);
- a.click();
- a.remove();
- }
- }
- xhr.send();
- }
- function createBlocker(full)
- {
- var r;
- if (full == true)
- {
- r =
- {
- top: 0,
- left: 0,
- width: window.innerWidth,
- height: window.innerHeight
- };
- }
- else
- {
- r = $(".main-table")[0].getBoundingClientRect();
- }
- var div = document.createElement("div");
- div.setAttribute("id", "blocker-div");
- div.style.position = "absolute";
- div.style.top = Math.round(r.top) + "px";
- div.style.left = Math.round(r.left) + "px";
- div.style.width = Math.round(r.width) + "px";
- div.style.height = Math.round(r.height) + "px";
- div.style.backgroundColor = full == true ? getComputedStyle(document.body).backgroundColor : "black";
- div.style.opacity = full == true ? "100%" : "50%";
- var img = document.createElement("img");
- img.setAttribute("id", "blocker-img");
- img.src = "imports/spinner.gif";
- img.style.position = "absolute";
- img.style.width = "64px";
- img.style.height = "64px";
- img.style.left = Math.round(r.left + r.width / 2 - 32) + "px";
- img.style.top = Math.round(r.top + r.height / 2 - 32) + "px";
- document.body.appendChild(div);
- document.body.appendChild(img);
- }
- function modalFixes()
- {
- if (getComputedStyle($("#modal-main")[0]).display == "none")
- {
- $(".istina-basis")[0].style.visibility = "";
- }
- else
- {
- $(".istina-basis")[0].style.visibility = "hidden";
- }
- }
-
- function getRotationAngle(instr)
- {
- resetDialog();
- var el = ProgramTrack.STATE[ProgramTrack.DRAGHOLD[0]][ProgramTrack.DRAGHOLD[1]];
- var nnum = 1;
- var pnum = "";
- var nden = 1;
- var pden = "";
- var sign = "+";
- if (typeof(el) == "string" && el.includes("<span"))
- {
- var elv = el.split("<span")[1].split(">")[1].split("<")[0];
- nnum = elv.split("/")[0];
- if (nnum.includes("ฯ"))
- {
- nnum = nnum.replace("ฯ", "");
- pnum = "pi";
- }
- if (elv.includes("/"))
- {
- nden = elv.split("/")[1];
- if (nden.includes("ฯ"))
- {
- nden = nden.replace("ฯ", "");
- pden = "pi";
- }
- }
- if (nnum.includes("-"))
- {
- nnum = nnum.replace("-", "");
- sign = "-";
- }
- if (nnum == "") nnum = "1";
- if (nden == "") nden = "1";
- }
- var h = "<input type='number' step='1' value='1' size='4' min='1' max='99' id='constant_1' />";
- h += "<select id='pi_1'><option></option><option>pi</option></select>";
- h += " / " + h.replace(/[_][1]/g, "_2");
- h = "<select id='neg_1'><option>+</option><option>-</option></select>" + h;
- $("#modal-main-title")[0].innerHTML = "Rotation Angel";
- $("#modal-main-content")[0].innerHTML = "<center>" + h + "</center>";
- $("#modal-main-cancel")[0].style.display = "";
- $("#modal-main-confirm")[0].style.display = "";
- $("#modal-main-confirm")[0].setAttribute("onclick", "setRotationAngle('" + instr + "');");
- $("#constant_1")[0].value = nnum;
- $("#constant_2")[0].value = nden;
- $("#pi_1")[0].value = pnum;
- $("#pi_2")[0].value = pden;
- $("#neg_1")[0].value = sign;
- MicroModal.show("modal-main");
- }
-
- function setRotationAngle(instr)
- {
- var numerator = parseInt($("#constant_1")[0].value);
- if (isNaN(numerator) || numerator < 0 || numerator > 99) numerator = 1;
- var denominator = parseInt($("#constant_2")[0].value);
- if (isNaN(numerator) || numerator < 1 || numerator > 99) numerator = 1;
- var pinum = $("#pi_1")[0].value.trim() == "pi" ? "pi" : "";
- var piden = $("#pi_2")[0].value.trim() == "pi" ? "pi" : "";
- if (pinum == "pi" && piden == "pi") { pinum = ""; piden = ""; }
- var negnum = $("#neg_1")[0].value.trim() == "-" ? "-" : "";
- var fraction = negnum + numerator + pinum;
- if (denominator != 1 || piden != "")
- {
- fraction += "/" + denominator + piden;
- }
- if (numerator == denominator)
- {
- if (pinum == "" && piden == "pi")
- {
- fraction = negnum + "1/pi";
- }
- else
- {
- fraction = fraction.replace(numerator + "pi/" + denominator, "1pi");
- fraction = fraction.replace(numerator + "/" + denominator + "pi", "1pi");
- fraction = fraction.replace(numerator + "/" + denominator, "1");
- }
- }
- if (fraction.split("/")[0] == "1pi" || fraction.split("/")[0] == "-1pi")
- {
- var tmp = "";
- if (fraction.split("/").length == 2)
- {
- tmp = fraction.split("/")[1];
- }
- fraction = (fraction.includes("-") ? "-" : "") + "pi" + (tmp.length > 0 ? "/" + tmp : "");
- }
- fraction = fraction.replace("/1pi", "/pi");
- fraction = fraction.replace("pi", "ฯ").replace("pi", "ฯ");
- closeModal();
- ProgramTrack.STATE[ProgramTrack.DRAGHOLD[0]][ProgramTrack.DRAGHOLD[1]] = instr + "<br /><span style='font-size: 12px'>" + fraction + "</span>";
- ProgramTrack.draw();
- }
- function trackerCollapse(attr)
- {
- while (ProgramTrack.STATE[0].length > 0)
- {
- if (attr != null)
- {
- if (attr.split(",")[1] == ProgramTrack.STATE[0].length - 1)
- {
- break;
- }
- }
- var lastColumnIsEmpty = true;
- for (var i = 0; i < ProgramTrack.STATE.length; i++)
- {
- if (ProgramTrack.STATE[i][ProgramTrack.STATE[i].length - 1].trim().length > 0)
- {
- lastColumnIsEmpty = false;
- break;
- }
- }
- if (lastColumnIsEmpty)
- {
- for (var i = 0; i < ProgramTrack.STATE.length; i++)
- {
- ProgramTrack.STATE[i].length -= 1;
- }
- ProgramTrack.draw();
- }
- else
- {
- break;
- }
- }
- }
- function welcome()
- {
- $("#modal-main-title")[0].innerHTML = "Welcome!";
- $("#modal-main-content")[0].innerHTML = "<p>Welcome to the QAnsel Quantum Computer Simulator! QAnsel is a quantum computer simulator which uses real quantum optical effects to sample the results. Press the โ button in the top-right corner for assistance.</p>";
- $("#modal-main-cancel")[0].style.display = "none";
- $("#modal-main-confirm")[0].style.display = "";
- $("#modal-main-confirm")[0].setAttribute("onclick", "closeModal();");
- MicroModal.show("modal-main");
- }
- setInterval(() =>
- {
- if ($(".modal")[0].getAttribute("aria-hidden") == "true")
- {
- $(".istina-overlay")[0].style.pointerEvents = "";
- $(".istina-basis")[0].style.pointerEvents = "";
- }
- else
- {
- $(".istina-overlay")[0].style.pointerEvents = "none";
- $(".istina-basis")[0].style.pointerEvents = "none";
- }
- if ($(".program-drag")[0].style.visibility == "hidden")
- {
- document.body.style.overflowX = "";
- document.body.style.overflowY = "";
- $(".program-track-container")[0].style.overflowX = "auto";
- $(".program-track-container")[0].style.overflowY = "auto";
- }
- else
- {
- document.body.style.overflowX = "hidden";
- document.body.style.overflowY = "hidden";
- $(".program-track-container")[0].style.overflowX = "hidden";
- $(".program-track-container")[0].style.overflowY = "hidden";
- }
- }, 100);
- if (!ismobile)
- {
- window.doResize = function()
- {
- var resize =
- {
- state: ProgramTrack.STATE,
- text: IstinaEditor.getText(),
- graph: [ resultsChart.data.labels, resultsChart.data.datasets[0].data ]
- };
- localStorage.setItem("resize", JSON.stringify(resize));
- window.location.reload();
- };
- window.isActive = true;
- window.queuedResize = false;
- window.onblur = function() { window.isActive = false; }
- window.onfocus = function() { window.isActive = true; if (window.queuedResize) window.doResize(); }
- window.onresize = function()
- {
- if (window.isActive)
- {
- window.doResize();
- }
- else
- {
- window.queuedResize = true;
- }
- }
- var resizeData = localStorage.getItem("resize");
- if (resizeData != undefined && resizeData != null)
- {
- resizeData = JSON.parse(resizeData);
- ProgramTrack.STATE = resizeData.state;
- IstinaEditor.setText(resizeData.text);
- resultsChart.data.labels = resizeData.graph[0];
- resultsChart.data.datasets[0].data = resizeData.graph[1];
- localStorage.removeItem("resize");
- }
- }
- </script>
-
-</body>
-