// ═══════════════════════════════════════════════════════ // Chmod Calculator // ═══════════════════════════════════════════════════════ async function chmodFromNumeric() { const val = document.getElementById('chmodNumeric').value.trim(); if (!val || !/^[0-7]{3,4}$/.test(val)) return; const d = await apiPost('/api/chmod/calculate', { numeric: val }); if (d.success) updateChmodUI(d); } async function chmodFromSymbolic() { const val = document.getElementById('chmodSymbolic').value.trim(); if (!val || val.length < 9) return; const d = await apiPost('/api/chmod/calculate', { symbolic: val }); if (d.success) updateChmodUI(d); } function updateChmodUI(d) { document.getElementById('chmodNumeric').value = d.numeric; document.getElementById('chmodSymbolic').value = d.symbolic; document.getElementById('chmodCommand').textContent = `chmod ${d.numeric} filename`; const roles = ['owner', 'group', 'others']; const perms = ['read', 'write', 'execute']; let html = '
'; html += '
' + perms.map(p => `
${p}
`).join(''); for (const role of roles) { html += `
${role}
`; for (const perm of perms) { const on = d[role][perm]; html += `
${on ? '✓' : '—'}
`; } } html += '
'; document.getElementById('chmodMatrix').innerHTML = html; setStatus('chmodStatus', 'success', `${d.numeric} = ${d.symbolic} ✓`); } setTimeout(chmodFromNumeric, 200);