case QANSEL_INSTRUCTION_IF_L: return "if<";
case QANSEL_INSTRUCTION_IF_LE: return "if<=";
case QANSEL_INSTRUCTION_PRINT: return "print";
+ case QANSEL_INSTRUCTION_SET: return "set";
case QANSEL_INSTRUCTION_RESET: return "reset";
case QANSEL_INSTRUCTION_BARRIER: return "barrier";
case QANSEL_INSTRUCTION_EXIT: return "exit";
if ((a0 > QANSEL_CBOUND_UPPER || a0 < QANSEL_CBOUND_LOWER) && a0 != QANSEL_ALL_CLASSIC) return 0;
if (a0 != QANSEL_ALL_CLASSIC) *bitmax = (a0 - QANSEL_CBOUND_LOWER) + 1;
return 1;
+ case QANSEL_INSTRUCTION_SET:
case QANSEL_INSTRUCTION_RESET:
case QANSEL_INSTRUCTION_PRINT:
a0 = ptr[offset + 1];
case QANSEL_INSTRUCTION_IF_GE: return 1 + 1 + sizeof(unsigned short);
case QANSEL_INSTRUCTION_IF_L: return 1 + 1 + sizeof(unsigned short);
case QANSEL_INSTRUCTION_IF_LE: return 1 + 1 + sizeof(unsigned short);
+ case QANSEL_INSTRUCTION_SET: return 1 + 1;
case QANSEL_INSTRUCTION_RESET: return 1 + 1;
case QANSEL_INSTRUCTION_PRINT: return 1 + 1;
case QANSEL_INSTRUCTION_BARRIER: return 1 + 1;
case QANSEL_INSTRUCTION_BORN:
case QANSEL_INSTRUCTION_BARRIER:
case QANSEL_INSTRUCTION_PRINT:
+ case QANSEL_INSTRUCTION_SET:
case QANSEL_INSTRUCTION_RESET:
switch ((*qbc)[idx].bytes[1])
{
return ret;
}
-void qansel_reset(QAnselContext* ctx, cpx_mtx_t* stateVector, unsigned char* bitVector, int qubitCount, int bitCount, unsigned char q0)
+void qansel_set(QAnselContext* ctx, cpx_mtx_t* stateVector, unsigned char* bitVector, int qubitCount, int bitCount, unsigned char q0, unsigned char value)
{
unsigned int qubitCountPow2 = (unsigned int)pow(2, qubitCount);
if (q0 == QANSEL_ALL)
else if (q0 <= QANSEL_QBOUND_UPPER)
{
unsigned char bit = qansel_measure(ctx, stateVector, qubitCount, q0);
- if (bit)
+ if (bit != value)
{
qansel_instruction(ctx, stateVector, qubitCount, QANSEL_INSTRUCTION_X, q0, 0, 0, 0, NULL);
}
case QANSEL_INSTRUCTION_BARRIER:
a0 = program[PC + 1];
break;
+ case QANSEL_INSTRUCTION_SET:
+ a0 = program[PC + 1];
+ qansel_set(ctx, &stateVector, bitVector, qubitCount, bitCount, a0, 1);
+ break;
case QANSEL_INSTRUCTION_RESET:
a0 = program[PC + 1];
- qansel_reset(ctx, &stateVector, bitVector, qubitCount, bitCount, a0);
+ qansel_set(ctx, &stateVector, bitVector, qubitCount, bitCount, a0, 0);
break;
case QANSEL_INSTRUCTION_IF_E:
a0 = program[PC + 1];
<script src="imports/chart.js"></script>
<script src="imports/micromodal.js"></script>
<style>
- body { background-color: #1f1f1f; }
+ body { background-color: #1f1f1f; user-select: none; }
@font-face
{
font-family: "SmileBASIC";
color: #9cdcfe;
border-color: grey;
font-weight: bold;
+ border-style: solid;
+ border-collapse: collapse;
}
.program-track
{
table-layout: fixed;
}
+ [pidx*=',']:hover
+ {
+ background-color: rgb(75, 0, 0);
+ cursor: pointer;
+ }
+ /*.program-instr td:hover
+ {
+ background-color: rgb(75, 0, 0);
+ }*/
textarea
{
background-color: #353535;
width: 100%;
height: 220px;
}
+ /*
.optionspanel
{
text-align: right;
#save,#help { font-size: 20px; }
#load,#clear,#apk { font-size: 20px; }
#apkwrapper { display: none; }
+ */
-</style>
+ .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>
- <div class="modal micromodal-slide" id="modal-1" aria-hidden="true">
+ <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>
- <div class="modal__container" role="dialog" aria-modal="true" aria-labelledby="modal-1-title">
+ <div class="modal__container" role="dialog" aria-modal="true" aria-labelledby="modal-main-title" style="width: 640px;">
<header class="modal__header">
- <h2 class="modal__title" id="modal-1-title">
- Micromodal
- </h2>
- <button class="modal__close" aria-label="Close modal" data-micromodal-close></button>
+ <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-1-content">
- <p>
- Try hitting the <code>tab</code> key and notice how the focus stays within the modal itself. Also, <code>esc</code> to close modal.
- </p>
- </main>
+ <main class="modal__content" id="modal-main-content"></main>
<footer class="modal__footer">
- <button class="modal__btn modal__btn-primary">Continue</button>
- <button class="modal__btn" data-micromodal-close aria-label="Close this dialog window">Close</button>
+ <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 border="1" style="width: 100%;">
+ <table class="main-table" border="1" style="width: 100%;">
<tr>
<td colspan="2">
- <div class="optionspanel">
- <button class="option" id="load">๐</button>
- <button class="option" id="clear">๐งน</button>
- <button class="option" id="save">๐พ</button><!-- -->
- <button class="option" id="run">โถ</button><!-- -->
- <button class="option" id="help">โ</button>
- <div id="apkwrapper"><button class="option" id="apk">๐ฒ</button> </div>
- <button class="option" id="setup">โ</button>
-
- </div>
+ <table style="width: 100%; text-align: center;" class="top-button-row">
+ <tr>
+ <td onclick="menu('open');">๐</td>
+ <td onclick="menu('clear');">๐งน</td>
+ <td onclick="menu('save');">๐พ</td>
+ <td style="color: green;" id="run">โถ</td>
+ <td onclick="menu('download');">๐ฅ</td>
+ <td>โ</td>
+ <td onclick="menu('settings');" style="color: lightgray">โ</td>
+ </tr>
+ </table>
</td>
</tr>
<tr>
- <td>
- <div style="overflow-y: scroll; overflow-x: scroll; height: 256px;" class="program-track-container">
+ <td colspan="2">
+ <div style="overflow-y: scroll; overflow-x: scroll; height: 256px; width: 0px;" oncontextmenu="return false;" class="program-track-container">
<table border=1 class="program-track"></table>
</div>
</td>
- <td>
- <table border=1 class="program-instr" style="width: 100%;"></table>
- <table border=1 class="program-drag" style="visibility: hidden;"></table>
- </td>
</tr>
<tr>
<td style="width: 50%; height: 100%;">
</td>
</tr>
</table>
-
+ <table border=1 class="program-instr" style="display: none;" cellspacing="0" cellpadding="0"></table>
+ <table border=1 class="program-drag" style="visibility: hidden;"></table>
<script>
$ = x => { return document.querySelectorAll(x); };
IstinaEditor.init();
SCALE: 64,
STATE: [ [], [], [], [], [], [], [], [], [], [], [], [], [], [], [] ],
DRAG: "",
+ init: () =>
+ {
+ for (var i = 0; i < ProgramTrack.STATE.length; i++)
+ {
+ ProgramTrack.STATE[i] = [];
+ }
+ ProgramTrack.draw();
+ },
decode: () =>
{
var width = 0;
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 "RST": ret += ifblk + "reset 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("๐"))
{
},
drag: (e, erase, evt) =>
{
+ $(".program-instr")[0].style.display = "none";
if (e.innerHTML.includes("Q") || e.innerHTML.includes("IF") || e.innerHTML.includes("..."))
{
return;
var s = e.getAttribute("pidx").split(",");
s[0] = parseInt(s[0]);
s[1] = parseInt(s[1]);
- switch (ProgramTrack.STATE[s[0]][s[1]])
+ var state = ProgramTrack.STATE[s[0]][s[1]].replace(/[\"]/g, "'");
+ switch (state)
{
case overline("CX", "10"): ProgramTrack.STATE[s[0]][s[1]] = overline("CX", "01"); break;
case overline("CX", "01"): ProgramTrack.STATE[s[0]][s[1]] = overline("CX", "10"); break;
if (ProgramTrack.DRAG == "" && e.innerHTML.trim().length > 0)
{
var h = e.innerHTML.replace(/[<].*?[>]/g, "");
- switch (h)
- {
- case "CX":
- case "CCX":
- case "SW":
- case "CSW":
- break;
- default: h = e.innerHTML;
- }
+ h = e.innerHTML;
ProgramTrack.DRAG = h;
$(".program-drag")[0].innerHTML = tr + td + h + "</tr></td>";
$(".program-drag")[0].style.visibility = "";
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 += " oncontextmenu='return false;'";
td += ">";
var html = "";
for (var i = 0; i < ProgramTrack.STATE.length; i++)
window.onload = function()
{
ProgramTrack.draw();
- $(".program-track")[0].parentNode.style.height = Math.round($(".program-instr")[0].getBoundingClientRect().height) + "px";
- $(".program-track")[0].parentNode.style.width = Math.round($(".program-instr")[0].getBoundingClientRect().width) + "px";
+ //$(".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"
};
-
+
document.body.addEventListener("mousemove", e =>
{
var x = $(".program-drag")[0];
{
if ($(".program-drag")[0].style.visibility == "hidden")
{
+ var trackerElem = document.elementFromPoint(e.clientX, e.clientY);
+ var str = trackerElem.getAttribute("pidx");
+ if (str) {} else {str = ""};
+ if (str.includes(",") && (trackerElem.innerHTML == "..." || trackerElem.innerHTML == ""))
+ {
+ $(".program-instr")[0].style.display = "none";
+ $(".program-instr")[0].className = $(".program-instr")[0].className.replace("menu-hidden", "").trim();
+ $(".program-instr")[0].className += " menu-reveal";
+ $(".program-instr")[0].style.position = "fixed";
+ $(".program-instr")[0].style.top = e.clientY + "px";
+ $(".program-instr")[0].style.left = e.clientX + "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 resultsChart = new Chart(document.getElementById("resultsChart"), {
type: 'bar',
data: {
- labels: ['000', '001', '010', '011', '100', '101', '110', '111'],
- datasets: [{
- label: '# of =1',
- data: [],
- borderWidth: 1
+ labels: [ ],
+ datasets:
+ [{
+ label: '# of |1โฉ',
+ data: [],
+ borderWidth: 1
}]
},
options: {
}
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";
+ }
+ var a = document.createElement("a");
+ a.href = "data:text/plain," + escape(csv);
+ a.download = "data.csv";
+ document.body.appendChild(a);
+ a.click();
+ a.remove();
+ }
+
$("#run")[0].addEventListener("click", () =>
{
- var key = "public:7e69f36a1a89ea70ec4a420fb9b830c420ab93e14e9a2f6da68bc1d355c611ef:foleosoft.com/qansel";
+ createBlocker();
+ var key = localStorage.getItem("apikey");
+ key = key ? key : "";
+ if (key.split(":").length != 3)
+ {
+ 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 = [];
- console.clear();
- console.log(type);
- console.log(lines);
if (type == 3)
{
for (var i = 0; i < lines.length; i++)
}
else
{
- IstinaEditor.setText(x.response);
+ errorModal(x.response, 1);
}
}
else if (x.success && x.response.trim().length == 0)
{
- IstinaEditor.setText(x.response);
+ errorModal(x.response, 1);
}
else
{
- IstinaEditor.setText(x.response);
+ errorModal(x.response, 1);
}
- }).catch(x => IstinaEditor.setText(x.response));
+ }).catch(x => errorModal(x.message, 1));
});
MicroModal.init();
- function modalShow()
+ function menu(cmd)
{
+ $(".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-confirm")[0].style.display = "";
+ $("#modal-main-confirm")[0].setAttribute("onclick", "ProgramTrack.init(); closeModal();");
+ $(".istina-basis")[0].style.visibility = "hidden";
+ MicroModal.show("modal-main");
+ break;
+ case "settings":
+ var apikey = localStorage.getItem("apikey");
+ apikey = (apikey ? apikey : "").replace("'", "").replace("\"", "").replace("\n", "");
+ $("#modal-main-title")[0].innerHTML = "API Settings";
+ $("#modal-main-content")[0].innerHTML = "<p>Please enter your API key: </p><input type='text' id='apikey' />";
+ $("#apikey")[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();
+ }
+ });
+ $("#apikey")[0].value = apikey;
+ $("#modal-main-confirm")[0].style.display = "";
+ $("#modal-main-confirm")[0].setAttribute("onclick", "localStorage.setItem('apikey', $('#modal-main-content input')[0].value); closeModal();");
+ $(".istina-basis")[0].style.visibility = "hidden";
+ MicroModal.show("modal-main");
+ break;
+ case "save":
+ var a = document.createElement("a");
+ a.href = "data:text/plain," + btoa(escape(JSON.stringify(ProgramTrack.STATE)));
+ a.download = "program.txt";
+ document.body.appendChild(a);
+ a.click();
+ a.remove();
+ break;
+ case "download":
+ downloadResults();
+ break;
+ case "open":
+ $("#file-input")[0].click();
+ break;
+ }
+ }
+ function errorModal(err, mode)
+ {
+ if (mode == 1)
+ {
+ err = err.replace(/[\n]/g, "<br />");
+ }
+ $(".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";
+ $("#modal-main-content")[0].innerHTML = "<p style='color: red;'>" + err + "</p>";
$(".istina-basis")[0].style.visibility = "hidden";
- MicroModal.show("modal-1");
+ MicroModal.show("modal-main");
+ }
+ function closeModal()
+ {
+ $(".istina-basis")[0].style.visibility = "";
+ MicroModal.close();
+ }
+ $("#file-input")[0].addEventListener("change", e =>
+ {
+ var reader = new FileReader();
+ reader.addEventListener("load", () =>
+ {
+ try
+ {
+ ProgramTrack.STATE = JSON.parse(unescape(atob(reader.result)));
+ ProgramTrack.draw();
+ }
+ catch
+ {
+ errorModal("Could not open this file.");
+ }
+ }, false);
+ if (e.target.files.length == 1)
+ {
+ reader.readAsText(e.target.files[0]);
+ }
+ });
+ function createBlocker()
+ {
+ var 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 = "black";
+ div.style.opacity = "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);
}
</script>