#!/usr/bin/env python3
"""
Convert enhanced HTML to C string format for embedding
"""
def escape_c_string(s):
"""Escape string for C embedding"""
s = s.replace('\\', '\\\\')
s = s.replace('"', '\\"')
s = s.replace('\n', '\\n')
return s
# Read the enhanced HTML
with open('enhanced_ui.html', 'r') as f:
html_content = f.read()
# Add complete JavaScript functionality
js_complete = '''
// Complete JavaScript implementation
const charts = {};
let networkActivityData = { labels: [], datasets: [{ label: 'Networks', data: [], borderColor: '#00ff41', backgroundColor: 'rgba(0,255,65,0.1)' }] };
let rssiData = { labels: [], datasets: [{ label: 'RSSI Distribution', data: [], backgroundColor: '#00ff41' }] };
let packetFlowData = { labels: [], datasets: [{ label: 'Packets/sec', data: [], borderColor: '#00d4ff' }] };
let signalTimeData = { labels: [], datasets: [] };
let channelUtilData = { labels: [], datasets: [{ label: 'Utilization %', data: [], backgroundColor: '#00ff41' }] };
let selected24ghz = null;
let selected5ghz = null;
let autoScanInterval = null;
let packetCount = 0;
let startTime = Date.now();
function initCharts() {
const chartOptions = {
responsive: true,
maintainAspectRatio: false,
animation: { duration: 0 },
plugins: {
legend: { labels: { color: '#00ff41', font: { family: 'JetBrains Mono' } } }
},
scales: {
x: {
ticks: { color: '#00ff41', font: { family: 'JetBrains Mono' } },
grid: { color: 'rgba(0,255,65,0.1)' }
},
y: {
ticks: { color: '#00ff41', font: { family: 'JetBrains Mono' } },
grid: { color: 'rgba(0,255,65,0.1)' }
}
}
};
charts.networkActivity = new Chart(document.getElementById('network-activity-chart'), {
type: 'line',
data: networkActivityData,
options: chartOptions
});
charts.rssi = new Chart(document.getElementById('rssi-chart'), {
type: 'bar',
data: rssiData,
options: chartOptions
});
charts.packetFlow = new Chart(document.getElementById('packet-flow-chart'), {
type: 'line',
data: packetFlowData,
options: {
...chartOptions,
scales: {
x: {
ticks: { color: '#00d4ff', font: { family: 'JetBrains Mono' } },
grid: { color: 'rgba(0,212,255,0.1)' }
},
y: {
ticks: { color: '#00d4ff', font: { family: 'JetBrains Mono' } },
grid: { color: 'rgba(0,212,255,0.1)' }
}
}
}
});
charts.signalTime = new Chart(document.getElementById('signal-time-chart'), {
type: 'line',
data: signalTimeData,
options: chartOptions
});
charts.channelUtil = new Chart(document.getElementById('channel-util-chart'), {
type: 'bar',
data: channelUtilData,
options: {
...chartOptions,
scales: {
...chartOptions.scales,
y: {
...chartOptions.scales.y,
max: 100
}
}
}
});
}
function updateDashboard() {
fetch('/api/system-info')
.then(r => r.json())
.then(data => {
document.getElementById('free-heap').textContent = formatBytes(data.free_heap);
const uptime = Math.floor((Date.now() - startTime) / 1000);
document.getElementById('uptime').textContent = formatTime(uptime);
const sysInfo = document.getElementById('system-info');
sysInfo.innerHTML = `
root@esp32-c5: IDF Version: ${data.idf_version}
root@esp32-c5: Chip Model: ${data.chip_model}
root@esp32-c5: Cores: ${data.chip_cores}
root@esp32-c5: MAC: ${data.mac_address}
root@esp32-c5: Features: ${data.features}
`;
});
}
function formatBytes(bytes) {
if (bytes < 1024) return bytes + ' B';
if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB';
return (bytes / 1048576).toFixed(2) + ' MB';
}
function formatTime(seconds) {
const h = Math.floor(seconds / 3600);
const m = Math.floor((seconds % 3600) / 60);
const s = seconds % 60;
return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`;
}
// WiFi Scanner
document.getElementById('scan-btn')?.addEventListener('click', function() {
this.disabled = true;
const status = document.getElementById('scan-status');
status.className = 'status-indicator active';
document.getElementById('scan-status-text').textContent = 'SCANNING...';
fetch('/api/scan')
.then(r => r.json())
.then(data => {
if (data.status === 'success') {
displayNetworks(data.networks);
updateRSSIChart(data.networks);
document.getElementById('networks-count').textContent = data.networks.length;
}
this.disabled = false;
status.className = 'status-indicator inactive';
document.getElementById('scan-status-text').textContent = 'READY';
});
});
function displayNetworks(networks) {
const tbody = document.querySelector('#networks-table tbody');
tbody.innerHTML = '';
networks.forEach(net => {
const row = document.createElement('tr');
const rssiPercent = Math.min(100, Math.max(0, (net.rssi + 100) * 2));
row.innerHTML = `
${net.ssid || '(HIDDEN)'} |
${net.bssid} |
${net.band} |
${net.channel} |
${net.rssi} dBm |
${net.security} |
|
`;
tbody.appendChild(row);
});
}
function updateRSSIChart(networks) {
const rssiRanges = { '-90 to -80': 0, '-80 to -70': 0, '-70 to -60': 0, '-60 to -50': 0, '-50 to -40': 0, '-40+': 0 };
networks.forEach(net => {
if (net.rssi < -90) rssiRanges['-90 to -80']++;
else if (net.rssi < -80) rssiRanges['-80 to -70']++;
else if (net.rssi < -70) rssiRanges['-70 to -60']++;
else if (net.rssi < -60) rssiRanges['-60 to -50']++;
else if (net.rssi < -50) rssiRanges['-50 to -40']++;
else rssiRanges['-40+']++;
});
rssiData.labels = Object.keys(rssiRanges);
rssiData.datasets[0].data = Object.values(rssiRanges);
charts.rssi.update();
}
// Packet Sniffer
let sniffing = false;
let sniffInterval = null;
document.getElementById('start-sniff')?.addEventListener('click', function() {
const channel = document.getElementById('sniff-channel').value;
const filter = document.getElementById('packet-filter').value;
fetch(`/api/sniff/start?channel=${channel}&filter=${filter}`)
.then(r => r.json())
.then(data => {
if (data.status === 'success') {
sniffing = true;
this.disabled = true;
document.getElementById('stop-sniff').disabled = false;
sniffInterval = setInterval(fetchPackets, 1000);
}
});
});
document.getElementById('stop-sniff')?.addEventListener('click', function() {
fetch('/api/sniff/stop')
.then(r => r.json())
.then(data => {
sniffing = false;
this.disabled = true;
document.getElementById('start-sniff').disabled = false;
if (sniffInterval) {
clearInterval(sniffInterval);
sniffInterval = null;
}
});
});
function fetchPackets() {
if (!sniffing) return;
fetch('/api/sniff/packets')
.then(r => r.json())
.then(data => {
if (data.packets && data.packets.length > 0) {
data.packets.forEach(pkt => addPacketToLog(pkt));
packetCount += data.packets.length;
document.getElementById('packets-count').textContent = packetCount;
updatePacketFlowChart(data.packets.length);
}
});
}
function addPacketToLog(packet) {
const log = document.getElementById('packet-log');
const time = new Date().toLocaleTimeString();
const line = document.createElement('div');
line.className = 'terminal-line';
line.innerHTML = `[${time}] ${packet.type} SRC: ${packet.src} DST: ${packet.dst} RSSI: ${packet.rssi} dBm`;
log.appendChild(line);
log.scrollTop = log.scrollHeight;
if (log.children.length > 100) log.removeChild(log.firstChild);
}
function updatePacketFlowChart(count) {
const now = new Date().toLocaleTimeString();
packetFlowData.labels.push(now);
packetFlowData.datasets[0].data.push(count);
if (packetFlowData.labels.length > 20) {
packetFlowData.labels.shift();
packetFlowData.datasets[0].data.shift();
}
charts.packetFlow.update('none');
}
// Bluetooth Scanner
document.getElementById('bt-scan-btn')?.addEventListener('click', function() {
this.disabled = true;
document.getElementById('bt-scan-stop-btn').disabled = false;
document.getElementById('bt-scan-status').className = 'status-indicator active';
fetch('/api/bt/scan/start')
.then(r => r.json())
.then(data => {
if (data.status === 'success') {
setInterval(fetchBTDevices, 2000);
}
});
});
function fetchBTDevices() {
fetch('/api/bt/devices')
.then(r => r.json())
.then(data => {
if (data.devices) {
displayBTDevices(data.devices);
}
});
}
function displayBTDevices(devices) {
const tbody = document.querySelector('#bt-devices-table tbody');
tbody.innerHTML = '';
devices.forEach(dev => {
const row = document.createElement('tr');
row.innerHTML = `
${dev.name || 'Unknown'} |
${formatBTAddr(dev.addr)} |
${dev.rssi} dBm |
${dev.type === 1 ? 'BLE' : 'Classic'} |
|
`;
tbody.appendChild(row);
});
}
function formatBTAddr(addr) {
return addr.map(b => b.toString(16).padStart(2, '0')).join(':').toUpperCase();
}
// Deauth Engine
document.getElementById('deauth-scan-btn')?.addEventListener('click', function() {
fetch('/api/scan')
.then(r => r.json())
.then(data => {
if (data.status === 'success') {
displayDeauthNetworks(data.networks);
}
});
});
function displayDeauthNetworks(networks) {
const targets = document.getElementById('deauth-targets');
let html = '| SSID | BSSID | BAND | CH | SELECT |
';
networks.forEach(net => {
html += `| ${net.ssid || '(HIDDEN)'} | ${net.bssid} | ${net.band} | ${net.channel} | `;
if (net.band === '2.4GHz') {
html += ``;
}
if (net.band === '5GHz') {
html += ``;
}
html += ' |
';
});
html += '
';
targets.innerHTML = html;
}
function selectDeauthTarget(band, ssid, bssid, channel) {
const target = {ssid, bssid, channel};
if (band === '24ghz') selected24ghz = target;
else selected5ghz = target;
updateDeauthTargets();
}
function updateDeauthTargets() {
const targets = document.getElementById('deauth-targets');
let html = '';
if (selected24ghz) {
html += `2.4GHz: ${selected24ghz.ssid} (${selected24ghz.bssid}) CH:${selected24ghz.channel}
`;
}
if (selected5ghz) {
html += `5GHz: ${selected5ghz.ssid} (${selected5ghz.bssid}) CH:${selected5ghz.channel}
`;
}
targets.innerHTML = html;
}
document.getElementById('deauth-start-btn')?.addEventListener('click', function() {
if (!selected24ghz && !selected5ghz) {
alert('SELECT AT LEAST ONE TARGET');
return;
}
const duration = parseInt(document.getElementById('deauth-duration').value);
const body = {duration};
if (selected24ghz) body.target_24ghz = selected24ghz;
if (selected5ghz) body.target_5ghz = selected5ghz;
if (!confirm('START DEAUTH ATTACK? USE ONLY ON YOUR NETWORKS!')) return;
fetch('/api/deauth/start', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(body)
})
.then(r => r.json())
.then(data => {
if (data.status === 'success') {
this.disabled = true;
document.getElementById('deauth-stop-btn').disabled = false;
setInterval(updateDeauthStats, 1000);
}
});
});
function updateDeauthStats() {
fetch('/api/deauth/status')
.then(r => r.json())
.then(data => {
document.getElementById('deauth-total').textContent = data.total_packets || 0;
document.getElementById('deauth-24').textContent = data.packets_24ghz || 0;
document.getElementById('deauth-5').textContent = data.packets_5ghz || 0;
document.getElementById('deauth-time').textContent = (data.elapsed_time || 0) + 's';
});
}
// Navigation
document.querySelectorAll('.nav-item').forEach(item => {
item.addEventListener('click', () => {
document.querySelectorAll('.nav-item').forEach(i => i.classList.remove('active'));
item.classList.add('active');
document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
document.getElementById(item.getAttribute('data-page')).classList.add('active');
});
});
// Initialize
document.addEventListener('DOMContentLoaded', function() {
initCharts();
loadSystemInfo();
updateDashboard();
setInterval(updateDashboard, 1000);
});
function loadSystemInfo() {
updateDashboard();
}
'''
# Replace the placeholder JavaScript
html_content = html_content.replace(
' // API functions and event handlers would go here...\n // (This is a template - full implementation continues)',
js_complete
)
# Convert to C string format
c_string = 'static const char index_html[] = \\\n'
lines = html_content.split('\n')
for i, line in enumerate(lines):
escaped = escape_c_string(line)
if i < len(lines) - 1:
c_string += f'"{escaped}\\n"\\\n'
else:
c_string += f'"{escaped}";'
# Write output
with open('enhanced_ui_c_string.txt', 'w') as f:
f.write(c_string)
print(f"Converted HTML to C string format")
print(f"Original size: {len(html_content)} bytes")
print(f"C string size: {len(c_string)} bytes")
print("File: enhanced_ui_c_string.txt")