'use strict'; // ── State ──────────────────────────────────────────────────────────────────── const state = { rules: [], // current rule list (order matters) interfaces: [], // available interface names for autocomplete editIdx: -1, // index in state.rules being edited (-1 = new) }; // ── API helpers ────────────────────────────────────────────────────────────── async function api(method, path, body) { const res = await fetch(path, { method, headers: body ? { 'Content-Type': 'application/json' } : {}, body: body ? JSON.stringify(body) : undefined, }); const json = await res.json(); if (!res.ok || !json.success) throw new Error(json.error || `HTTP ${res.status}`); return json.data; } const get = p => api('GET', p); const post = (p, b) => api('POST', p, b); // ── Load ───────────────────────────────────────────────────────────────────── async function loadAll() { try { const data = await get('/api/firewall'); state.rules = data.rules || []; state.interfaces = data.interfaces || []; document.getElementById('vlanIsolation').checked = !!data.vlan_isolation; const notInstalled = document.getElementById('notInstalledBanner'); if (!data.installed) { notInstalled.classList.remove('hidden'); } else { notInstalled.classList.add('hidden'); } // Populate datalist for interface autocomplete. const dl = document.getElementById('ifaceList'); dl.innerHTML = state.interfaces.map(n => `