const EVENT_UP = 0; const EVENT_DOWN = 1; const EVENT_SELECT = 2; const EVENT_BACK = 3; const canvas = document.getElementById('display'); const context = canvas.getContext('2d'); const status = document.getElementById('status'); const buttons = Array.from(document.querySelectorAll('[data-event]')); let wasm; async function loadWasm() { const imports = {}; const response = fetch('./pkg/kinda.wasm'); if ('instantiateStreaming' in WebAssembly) { try { return await WebAssembly.instantiateStreaming(response, imports); } catch (error) { console.warn('Falling back to ArrayBuffer WebAssembly load', error); } } const bytes = await (await fetch('./pkg/kinda.wasm')).arrayBuffer(); return WebAssembly.instantiate(bytes, imports); } function render() { const width = wasm.kinda_sim_width(); const height = wasm.kinda_sim_height(); const pixelPointer = wasm.kinda_sim_pixels(); const pixelLength = wasm.kinda_sim_pixel_len(); const pixels = new Uint8Array(wasm.memory.buffer, pixelPointer, pixelLength); canvas.width = width; canvas.height = height; const image = context.createImageData(width, height); for (let source = 0, target = 0; source < pixels.length; source += 1, target += 4) { const value = Math.round(18 + (pixels[source] * 230) / 255); image.data[target] = value; image.data[target + 1] = value; image.data[target + 2] = value; image.data[target + 3] = 255; } context.putImageData(image, 0, 0); } function sendInput(eventCode) { if (!wasm) { return; } wasm.kinda_sim_input(eventCode); render(); } function keyboardEventCode(event) { if (event.key === 'ArrowUp') { return EVENT_UP; } if (event.key === 'ArrowDown') { return EVENT_DOWN; } if (event.key === 'Enter') { return EVENT_SELECT; } if (event.key === 'Escape' || event.key === 'Backspace') { return EVENT_BACK; } return null; } buttons.forEach((button) => { button.disabled = true; button.addEventListener('click', () => sendInput(Number(button.dataset.event))); }); window.addEventListener('keydown', (event) => { const eventCode = keyboardEventCode(event); if (eventCode === null) { return; } event.preventDefault(); sendInput(eventCode); }); try { const instance = await loadWasm(); wasm = instance.instance.exports; wasm.kinda_sim_init(); render(); buttons.forEach((button) => { button.disabled = false; }); status.textContent = 'Ready. Select scans with mock WiFi results.'; } catch (error) { console.error(error); status.textContent = error instanceof Error ? error.message : 'Could not load simulator.'; }