The Course pane lists the 21 lessons, shows a lesson's text and exercise, loads its starter, and checks the program in the editor with the engine (engine_course_check in the page, the same commands in the desktop app): each case's verdict, each rule, What went wrong? from the diagnostics, the verdict and the critique, the hints one at a time with the engine's pointer, and a hint from the assistant when a model is connected, any program in its answer held back. Progress is kept only in this browser and says so. The interface's words are data, locales/<locale>/<area>.json for every part, English the source and Simplified Chinese marked machine-assisted; the Studio follows the browser's language until the reader picks one with the switch. test/locales.test.mjs holds every locale to every key and placeholder. The e2e checks the course in English and in Chinese. wai-web's engine tests pin 23 native and 16 wasm32, a course check the same bytes in both. Co-Authored-By: Claude Opus 5.5 <[email protected]>
27 lines
1.3 KiB
JavaScript
27 lines
1.3 KiB
JavaScript
import { t } from './i18n.js';
|
|
|
|
// An element with attributes and children: `class`, `text`, `on…` handlers, and
|
|
// boolean attributes as true. Built as nodes, never from HTML.
|
|
export const el = (tag, attrs = {}, ...kids) => {
|
|
const e = document.createElement(tag);
|
|
for (const [k, v] of Object.entries(attrs)) {
|
|
if (k === 'class') e.className = v;
|
|
else if (k === 'text') e.textContent = v;
|
|
else if (k.startsWith('on')) e.addEventListener(k.slice(2), v);
|
|
else if (v === true) e.setAttribute(k, '');
|
|
else if (v !== false && v != null) e.setAttribute(k, v);
|
|
}
|
|
for (const k of kids.flat()) if (k != null) e.append(k);
|
|
return e;
|
|
};
|
|
|
|
// The engine's equivalence verdict in words.
|
|
export function sameness(eq) {
|
|
if (!eq) return { text: t('dom.not_checked'), cls: '' };
|
|
if (eq.verdict === 'equivalent') {
|
|
const how = eq.how === 'tableau' ? t('dom.how_tableau') : eq.how === 'exact' ? t('dom.how_exact') : eq.how === 'rewrites' ? t('dom.how_rewrites') : eq.how === 'random' ? t('dom.how_random') : eq.how;
|
|
return { text: t('dom.same_circuit', { how }), cls: 'ok', why: eq.why };
|
|
}
|
|
if (eq.verdict === 'different') return { text: t('dom.different_circuit'), cls: 'bad', why: eq.why };
|
|
return { text: t('dom.not_checked'), cls: '', why: eq.why };
|
|
}
|