-
Notifications
You must be signed in to change notification settings - Fork 9
/
main.js
169 lines (149 loc) · 4.54 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
const classes = {1: 'stdout', 2: 'stderr text-danger'};
const workers = new Set();
function clearOutput() {
const output = document.getElementById('output');
output.innerHTML = '';
const results = document.getElementById('results-tbody');
results.innerHTML = '';
}
function stopAllWorkers() {
workers.forEach(worker => worker.terminate());
workers.clear();
}
function onRunButton() {
const runButton = document.getElementById('run');
function restoreRunButton() {
runButton.innerText = 'Run';
runButton.classList.remove('w3-red');
runButton.classList.remove('btn-danger');
}
if (workers.size) {
stopAllWorkers();
restoreRunButton();
}
else {
runFPTaylor(() => !workers.size && restoreRunButton());
runButton.innerText = 'Stop';
runButton.classList.add('btn-danger');
runButton.classList.add('w3-red');
}
}
function getError(errors, name) {
return errors.find(e => e.errorName === name) || {};
}
function displayResults(data) {
const results = document.getElementById('results-tbody');
function addCell(row, value) {
row.insertCell().appendChild(document.createTextNode(value || '-'));
}
for (const res of data) {
const row = results.insertRow();
addCell(row, res.name);
for (const err of ['absolute error', 'relative error', 'ULP error']) {
addCell(row, getError(res.errors, err + ' (exact)').errorStr ||
getError(res.errors, err + ' (approximate)').errorStr);
}
addCell(row, res.elapsedTime.toFixed(2) + 's');
// console.log(res);
}
}
function runFPTaylor(onFinished) {
const worker = new Worker('fptaylor.js');
workers.add(worker);
const output = document.getElementById('output');
const input = document.getElementById('input').value;
const config = document.getElementById('config').value;
worker.onerror = function(e) {
console.log(e);
workers.delete(worker);
if (onFinished) onFinished(null);
output.innerHTML += `<div class="${classes[2]}">Unexpected error: ${e}</div>`;
}
worker.onmessage = function(e) {
if (Array.isArray(e.data)) {
// Final results
displayResults(e.data);
workers.delete(worker);
if (onFinished) onFinished(e.data);
}
else {
const {ty, str} = e.data;
output.innerHTML += `<div class="${classes[ty]}">${str}</div>`;
}
};
output.innerHTML = '';
worker.postMessage({input, config, defaultcfg: default_config});
}
function populateSelect(examples, selectId, inputId, localId) {
const select = document.getElementById(selectId);
const input = document.getElementById(inputId);
function addOption(example) {
const opt = document.createElement('option');
opt.textContent = example.name;
opt.value = example.data.trim();
select.appendChild(opt);
}
addOption({name: '--', data: ''});
examples.forEach(addOption);
select.onchange = function(e) {
if (e.target.value) input.value = e.target.value;
};
input.oninput = function() {
select[0].selected = true;
}
input.onchange = function() {
if (localId) {
localStorage.setItem(localId, input.value);
}
}
const userInput = localId ? localStorage.getItem(localId) : null;
if (userInput) {
select[0].selected = true;
input.value = userInput;
}
else {
select[1].selected = true;
input.value = examples[0].data;
}
}
function switchTheme() {
const root = document.documentElement;
const dark = root.hasAttribute('dark');
if (dark) {
root.removeAttribute('dark');
}
else {
root.setAttribute('dark', '');
}
}
function openTab(tabs, tabId) {
for (const {tab, content} of tabs) {
if (tab.id === tabId) {
if (content) content.style.display = 'block';
tab.classList.add('tab-active');
}
else {
if (content) content.style.display = 'none';
tab.classList.remove('tab-active');
}
}
}
function initTabs(tabsContainer) {
const tabs = [];
for (const tab of tabsContainer.getElementsByClassName('tab-item')) {
const content = document.getElementById(tab.id.slice(4));
tab.onclick = () => openTab(tabs, tab.id);
tabs.push({tab, content});
}
}
window.onload = function() {
populateSelect(inputExamples, 'input-examples', 'input', 'user-input');
populateSelect(configExamples, 'config-examples', 'config', 'user-config');
for (const el of document.getElementsByClassName("tabs")) {
initTabs(el);
}
document.getElementById('run').onclick = onRunButton;
document.getElementById('clear').onclick = clearOutput;
let el = document.getElementById('tab-output');
if (el) el.click();
}