// Style // const machineStyles = document.getElementById("upp2025_w02"); machineStyles.disabled = false; // Extra rows // const rows = document.getElementById("worksheet").children[0]; const addrowsBtn = document.getElementById("addrows"); addrowsBtn.addEventListener('click', function() { let last = rows.children[rows.children.length - 2]; for (let i = 1; i <= 10; ++i) { let row = last.cloneNode(true); row.children[0].innerText = Number(row.children[0].innerText) + i rows.insertBefore(row, rows.children[rows.children.length - 1]); } memoryRefresh(); }); // Execution // const INPUT1 = document.getElementById("input1"); const INPUT2 = document.getElementById("input2"); const A = document.getElementById("regA"); const B = document.getElementById("regB"); const errorMsg = document.getElementById("errorMsg"); var speed = 1000; var running = false; var stop = false; var memory = null; var memoryLocation = -1; var parametrisedCommand = null; function memoryRefresh() { memory = document.querySelectorAll("#worksheet tr:not(:first-of-type) > td:first-of-type:not(:last-of-type)"); memoryLocation = memory.length; } memoryRefresh(); function executeInit() { running = true; A.innerText = 0; B.innerText = 0; errorMsg.innerText = ''; for (let i = 0; i < memory.length; ++i) { memory[i].innerText = memory[i].innerText .trim() .replace(' ', '') .replace('\n', ''); memory[i].classList.remove('error'); memory[i].classList.remove('selected'); } } function executeDeinit() { memoryLocation = memory.length; parametrisedCommand = null; stop = false; running = false; stopresumeBtn.innerText = 'Спри'; } function expectedCommand() { if (parametrisedCommand !== null) { error('Очакваше се число, не команда!'); return false; } return true; } function expectedNumber() { if (parametrisedCommand === null) { error('Очакваше се команда!'); return false; } if (isNaN(toNumber(memory[memoryLocation].innerText))) { error('Очакваше се валидно число!'); return false; } return true; } function error(msg) { errorMsg.innerText = msg; memory[memoryLocation].classList.add('error'); executeDeinit(); } function toNumber(text) { if (text === 'INPUT1') text = INPUT1.innerText; else if (text === 'INPUT2') text = INPUT2.innerText; return Number(text); } function execute() { if (stop) { running = false; return; } // After cell was set if (memoryLocation < memory.length) { memory[memoryLocation].classList.remove('selected'); switch (parametrisedCommand) { case null: break; case 'ASUM': if (!expectedNumber()) return; A.innerText = Number(A.innerText) + toNumber(memory[memoryLocation].innerText); break; case 'ASUBTRACT': if (!expectedNumber()) return; A.innerText = Number(A.innerText) - toNumber(memory[memoryLocation].innerText); break; case 'BSUM': if (!expectedNumber()) return; B.innerText = Number(B.innerText) + toNumber(memory[memoryLocation].innerText); break; case 'BSUBTRACT': if (!expectedNumber()) return; B.innerText = Number(B.innerText) - toNumber(memory[memoryLocation].innerText); break; case 'GOTOBZ': if (!expectedNumber()) return; if (Number(B.innerText) === 0) memoryLocation = toNumber(memory[memoryLocation].innerText) - 2; break; case 'GOTOBN': if (!expectedNumber()) return; if (Number(B.innerText) >= 0) memoryLocation = toNumber(memory[memoryLocation].innerText) - 2; break; } if (parametrisedCommand === null) { switch (memory[memoryLocation].innerText) { case '': executeDeinit(); return; case 'ASHOW': alert(A.innerText); break; case 'ASUM': case 'ASUBTRACT': case 'GOTOBZ': case 'GOTOBN': case 'BSUM': case 'BSUBTRACT': if (!expectedCommand()) return; parametrisedCommand = memory[memoryLocation].innerText; break; default: error('Невалидна команда!'); return; } } else parametrisedCommand = null; } // On execution start else { executeInit(); } memoryLocation = (memoryLocation + 1) % (memory.length + 1); memory[memoryLocation].classList.add('selected'); if (memoryLocation < memory.length) { setTimeout(execute, speed); } } const execBtn = document.getElementById("execute"); execBtn.addEventListener('click', function() { if (!running) executeDeinit(); if (memoryLocation == memory.length) execute(); }); const stopresumeBtn = document.getElementById('stopresume'); stopresumeBtn.addEventListener('click', function() { if (stop && !running) { stop = false; running = true; stopresumeBtn.innerText = 'Спри'; execute(); } else if (!stop && running) { stop = true; stopresumeBtn.innerText = 'Продължи'; } }); // Disallow newline function preventCharacters(evt) { if (evt.keyCode == 13 || evt.keyCode == 32) evt.preventDefault(); } for (let i = 0; i < memory.length; ++i) { memory[i].addEventListener('keydown', preventCharacters); } // Speed // const rbFast = document.getElementById('speedChoice1'); const rbSlow = document.getElementById('speedChoice2'); rbFast.addEventListener('change', function() { speed = rbFast.value; }); if (rbFast.checked) speed = rbFast.value; rbSlow.addEventListener('change', function() { speed = rbSlow.value; }); if (rbSlow.checked) speed = rbSlow.value; // Save/load // const saveBtn = document.getElementById('save'); const loadBtn = document.getElementById('load'); saveBtn.addEventListener('click', function() { let contents = ''; for (let i = 0; i < memory.length; ++i) { contents += memory[i].innerText + '\n'; } let now = new Date(); let datetime = now.getFullYear().toString() + (now.getMonth() < 10 ? '0' : '') + now.getMonth().toString() + (now.getDate() < 10 ? '0' : '') + now.getDate() + "_" + now.getHours() + now.getMinutes(); // Thanks https://stackoverflow.com/a/79383186 const download = document.createElement('a'); download.href = URL.createObjectURL(new Blob([contents], { type: 'text/csv' })); download.download = 'Таблица_' + datetime + '.csv'; download.click(); URL.revokeObjectURL(download.href); }); function loadMemory(text) { let rows = text.split("\n"); while (memory.length < rows.length) addrowsBtn.click(); for (let i = 0; i < rows.length; ++i) { memory[i].innerText = rows[i].split(',')[0]; } } loadBtn.addEventListener('click', function() { const upload = document.createElement('input'); upload.type = 'file'; upload.accept = 'text/csv'; upload.click(); upload.addEventListener('change', function(e) { let file = e.target.files[0]; if (!file) return; let reader = new FileReader(); reader.readAsText(file); reader.addEventListener('load', function(e) { loadMemory(e.target.result); }); }); });