1
0
forked from javalsai/website

first commit

This commit is contained in:
2024-09-30 19:36:00 +02:00
commit ae59cb7ed9
35 changed files with 9562 additions and 0 deletions

22
tools/index.html Normal file
View File

@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Javalsai's Website - Tools</title>
<link rel="stylesheet" href="/styles/bundles/complete.css">
</head>
<body class="flex column">
<!--# include virtual="/components/header.html" -->
<main>
<h1><a class="reference" id="tools" href="#tools">Tools</a></h1>
<p>This is just a collection of tools or stuff I've made, out there for any to use.</p>
<ul>
<li><a href="qalc">qalc</a> - Popular libqalculate tool compiled for the web</li>
</ul>
</main>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@@ -0,0 +1,55 @@
let pendingRequests = [];
self.addEventListener('message', ({ data }) => {
if (pendingRequests) {
// gnuplot not loaded yet
pendingRequests.push(data);
} else {
doPlot(data);
}
});
var Module = {
noInitialRun: true,
postRun: () => {
shouldRunNow = true;
pendingRequests.forEach(doPlot);
pendingRequests = null;
},
print: (s) => {
console.log('GNUPLOT LOG: ' + s);
},
printErr: (s) => {
console.warn('GNUPLOT ERR: ' + s);
},
};
function doPlot({
fix_cmd = true,
data_files = {},
commands,
id,
// TODO: do something with these...?
extra_commandline,
persist,
}) {
const files = Object.keys(data_files);
for (const [file, data] of Object.entries(data_files)) {
FS.writeFile(file, data);
}
const cmd = fix_cmd
? commands.replace(
'set terminal pop',
"set terminal svg; set output '/output'"
)
: commands;
FS.writeFile('/commands', cmd);
callMain(['/commands']);
const output = FS.readFile('/output', { encoding: 'utf8' });
for (const file of ['/commands', '/output', ...files]) {
FS.unlink(file);
}
self.postMessage({ id, output });
}
importScripts('gnuplot.js');

File diff suppressed because it is too large Load Diff

BIN
tools/qalc/flaviut/gnuplot.wasm Executable file

Binary file not shown.

View File

@@ -0,0 +1,53 @@
<!doctype html>
<html lang="en-us" style="margin: 2em;">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
<link rel='icon' type='image/png' href='favicon.png'>
<title>Qalculate Web</title>
<link rel="preload" href="qalc.js" as="script">
<link rel="preload" href="qalc.wasm" as="fetch">
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Qalculate!</h1>
<p>This page is designed to test running Qalculate in the browser using
WASM. At the moment, currencies are not supported, as they require
external resources.</p>
<p>Plotting works, try <code>plot(3x^2; -10; 10)</code></p>
<p>The source code for this tool <a
href="https://github.com/flaviut/qalculate-wasm">can be found on
GitHub</a></p>
<div id="status">Downloading...</div>
<div class="hide" id="cell-template">
<div class="cell">
<input type="text" class="cell-input" placeholder="2x + 5 = 9">
<div class="cell-result"></div>
</div>
</div>
<div class="hide" id="plot-template">
<div class="plot-err">
<h2>Unable to plot</h2>
</div>
</div>
<div id="cells">
</div>
<script type='text/javascript' src='main.js'></script>
<script async type="text/javascript" src="qalc.js"></script>
<script data-goatcounter="https://j88og8.goatcounter.com/count"
async src="//gc.zgo.at/count.js"></script>
</body>
</html>

185
tools/qalc/flaviut/main.js Normal file
View File

@@ -0,0 +1,185 @@
const statusElement = document.getElementById('status');
const cellTmpl = document.querySelector('#cell-template .cell');
const plotErrTmpl = document.querySelector('#plot-template .plot-err');
const cells = document.getElementById('cells');
/** @typedef {node: HTMLElement, input: HTMLInputElement, result: HTMLElement} Cell */
/** @type {Cell} */
let curCell;
/** @returns {Cell} */
const getCell = (cellNode) => ({
node: cellNode,
input: cellNode.querySelector('.cell-input'),
result: cellNode.querySelector('.cell-result'),
});
let cellNum = 0;
function newCell() {
if (curCell) {
curCell.input.readOnly = true;
}
curCell = getCell(cellTmpl.cloneNode(true));
cellNum += 1;
curCell.node.id = 'cell_' + cellNum;
curCell.input.addEventListener('keydown', onKey);
cells.append(curCell.node);
focusCell(curCell);
}
/** @param {Cell} cell */
function focusCell(cell) {
cell.input.focus({ preventScroll: true });
if (cell.input.readOnly) {
cell.input.select();
}
cell.node.scrollIntoView({ behavior: 'smooth' });
}
/** @param {KeyboardEvent} ev */
function onKey(ev) {
/** @type {HTMLInputElement} */
const inp = ev.target;
if (ev.key === 'Enter') {
const text = inp.value;
if (inp === curCell.input) {
if (text.trim() !== '') {
curCell.result.textContent = calc.calculateAndPrint(text, 1000);
}
newCell();
} else {
if (text.trim() !== '') {
curCell.input.value = text;
}
focusCell(curCell);
}
} else if (ev.key === 'ArrowUp' || ev.key === 'ArrowDown') {
const cellNode = inp.parentElement;
const adjacent =
ev.key === 'ArrowUp'
? 'previousElementSibling'
: 'nextElementSibling';
let adjacentCellNode = cellNode;
do {
// this would be null if e.g. we're at the top and try to go up
adjacentCellNode = adjacentCellNode[adjacent];
} while (
adjacentCellNode != null &&
!adjacentCellNode.classList.contains('cell')
);
if (adjacentCellNode) {
focusCell(getCell(adjacentCellNode));
}
ev.preventDefault();
}
}
const emptySvg = `<?xml version="1.0" encoding="utf-8" standalone="no"?>
<svg
width="600" height="480"
viewBox="0 0 600 480"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
/>`;
let emptySvgUrl;
let plot_id = 0;
let gnuplotWorker;
const makeSvgUrl = (data) =>
URL.createObjectURL(new Blob([data], { type: 'image/svg+xml' }));
function runGnuplot(data_files, commands, extra_commandline, persist) {
if (!gnuplotWorker) {
gnuplotWorker = new Worker('gnuplot-worker.js');
gnuplotWorker.addEventListener('message', (ev) => {
const { id, output } = ev.data;
const plot = document.getElementById('plot_' + id);
if (output) {
plot.src = makeSvgUrl(output);
setTimeout(() => {
focusCell(curCell);
}, 10);
} else {
plot.replaceWith(plotErrTmpl.cloneNode(true));
}
});
}
if (!emptySvgUrl) {
emptySvgUrl = makeSvgUrl(emptySvg);
}
const img = new Image();
img.classList.add('plot');
img.src = emptySvgUrl;
const id = plot_id++;
img.id = 'plot_' + id;
curCell.node.insertAdjacentElement('afterend', img);
gnuplotWorker.postMessage({
data_files,
commands,
extra_commandline,
persist,
id,
});
return true;
}
var Module = {
postRun: () => {
console.time('new');
window.calc = new Module.Calculator();
calc.loadGlobalDefinitions();
console.timeEnd('new');
newCell();
},
print: function (text) {
if (arguments.length > 1)
text = Array.prototype.slice.call(arguments).join(' ');
console.log(text);
},
printErr: function (text) {
if (arguments.length > 1)
text = Array.prototype.slice.call(arguments).join(' ');
console.error(text);
},
setStatus: function (text) {
if (!Module.setStatus.last)
Module.setStatus.last = { time: Date.now(), text: '' };
if (text === Module.setStatus.last.text) return;
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
var now = Date.now();
if (m && now - Module.setStatus.last.time < 30) return; // if this is a progress update, skip it if too soon
Module.setStatus.last.time = now;
Module.setStatus.last.text = text;
if (m) {
text = m[1];
}
statusElement.innerHTML = text;
},
totalDependencies: 0,
monitorRunDependencies: function (left) {
this.totalDependencies = Math.max(this.totalDependencies, left);
Module.setStatus(
left
? 'Preparing... (' +
(this.totalDependencies - left) +
'/' +
this.totalDependencies +
')'
: 'All downloads complete.'
);
},
};
Module.setStatus('Downloading...');
window.onerror = function (event) {
// TODO: do not warn on ok events like simulating an infinite loop or exitStatus
Module.setStatus('Exception thrown, see JavaScript console');
Module.setStatus = function (text) {
if (text) Module.printErr('[post-exception status] ' + text);
};
};

3955
tools/qalc/flaviut/qalc.js Normal file

File diff suppressed because it is too large Load Diff

BIN
tools/qalc/flaviut/qalc.wasm Executable file

Binary file not shown.

View File

@@ -0,0 +1,81 @@
@import url("/styles/common.css");
body {
max-width: 1300px;
min-width: 300px;
background: var(--background);
font-family: var(--mono-font);
font-weight: 400;
font-size: 15px;
color: var(--text);
caret-color: var(--primary);
}
*, *::before, *::after {
transition: all .3s ease-out;
}
.cell-result {
background: var(--background-lighter) !important;
}
img {
background: var(--background-lighter);
border-radius: 10px;
}
img:hover {
filter: brightness(1.5);
}
input {
border-radius: 5px;
}
/* original (except padding) */
.cell {
margin: 1em 0;
border-radius: 0.5em;
border: 1px solid black;
padding: 1em;
}
.cell-input {
width: 100%;
box-sizing: border-box;
margin-bottom: 1em;
padding: 0.6em;
}
.cell-result {
border-radius: 0.75em;
background: #eee;
padding: 0.75em;
}
.cell-input,
.cell-result {
font-family: sans-serif;
font-size: 0.9em;
}
body {
max-width: 600px;
margin-left: auto;
margin-right: auto;
}
.hide {
display: none;
}
.plot {
display: block;
}
.plot-err {
color: red;
width: 600px;
height: 480px;
display: flex;
flex-direction: column;
justify-content: center;
}
.plot-err h2 {
text-align: center;
}

24
tools/qalc/index.html Normal file
View File

@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Javalsai's Website - Tools::Qalc</title>
<link rel="stylesheet" href="/styles/bundles/complete.css">
</head>
<body class="flex column">
<!--# include virtual="/components/header.html" -->
<main>
<h1><a class="reference" id="qalc" href="#qalc">Qalc</a></h1>
<p>Popular libqalculate tool compiled for the web, I wanna wrap the library for with own style, but I'll also
leave the default example from <a
href="https://github.com/flaviut/qalculate-wasm">flaviut/qalculate-wasm</a> as it supports graphs too,
I'll just inject some CSS for dark mode:
<a href="flaviut">live example</a>
</p>
</main>
</body>
</html>