import { getWasm } from '../wasm.js';
import { esc } from '../utils/html.js';
import { createExportBar } from '../utils/export.js';
import { trackFeatureUse } from '../utils/analytics.js';
import { insertTabIntro } from '../utils/help.js';
export function createHex(container, fileData, pageCount) {
container.innerHTML = `
<div class="p-6 space-y-4 overflow-auto max-h-full">
<div class="flex items-center gap-4 flex-wrap">
<h2 class="text-lg font-bold text-innodb-cyan">Hex Dump</h2>
<div class="flex items-center gap-2">
<label class="text-sm text-gray-500">Page:</label>
<input id="hex-page" type="number" min="0" max="${pageCount - 1}" value="0"
class="w-24 px-2 py-1 bg-surface-2 border border-gray-700 rounded text-sm text-gray-200 focus:border-innodb-cyan focus:outline-none" />
</div>
<div class="flex items-center gap-2">
<label class="text-sm text-gray-500">Offset:</label>
<input id="hex-offset" type="number" min="0" value="0"
class="w-24 px-2 py-1 bg-surface-2 border border-gray-700 rounded text-sm text-gray-200 focus:border-innodb-cyan focus:outline-none" />
</div>
<div class="flex items-center gap-2">
<label class="text-sm text-gray-500">Length:</label>
<input id="hex-length" type="number" min="0" value="256"
class="w-24 px-2 py-1 bg-surface-2 border border-gray-700 rounded text-sm text-gray-200 focus:border-innodb-cyan focus:outline-none" />
<span class="text-xs text-gray-600">0 = full page</span>
</div>
<button id="hex-go" class="px-3 py-1 bg-innodb-blue hover:bg-blue-600 text-white rounded text-sm">Dump</button>
<span id="hex-export"></span>
</div>
<div id="hex-output" class="bg-surface-1 rounded-lg p-4 font-mono text-xs overflow-auto max-h-[calc(100vh-16rem)]">
<span class="text-gray-600">Select a page and click Dump to view hex data.</span>
</div>
</div>
`;
insertTabIntro(container, 'hex');
const pageInput = container.querySelector('#hex-page');
const offsetInput = container.querySelector('#hex-offset');
const lengthInput = container.querySelector('#hex-length');
const goBtn = container.querySelector('#hex-go');
const output = container.querySelector('#hex-output');
let lastDumpRaw = '';
function doDump() {
const wasm = getWasm();
const page = parseInt(pageInput.value) || 0;
const offset = parseInt(offsetInput.value) || 0;
const length = parseInt(lengthInput.value) || 0;
try {
const dump = wasm.hex_dump_page(fileData, BigInt(page), offset, length);
lastDumpRaw = dump;
output.innerHTML = formatHexDump(dump);
} catch (e) {
lastDumpRaw = '';
output.innerHTML = `<span class="text-red-400">${esc(String(e))}</span>`;
}
}
goBtn.addEventListener('click', () => { trackFeatureUse('hex_dump'); doDump(); });
[pageInput, offsetInput, lengthInput].forEach((input) => {
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter') doDump();
});
});
const exportSlot = container.querySelector('#hex-export');
if (exportSlot) {
exportSlot.appendChild(createExportBar(() => lastDumpRaw, 'hex_dump', { text: true }));
}
doDump();
}
function formatHexDump(raw) {
return raw
.split('\n')
.map((line) => {
if (!line.trim()) return '';
const match = line.match(/^([0-9A-Fa-f]+)\s+((?:[0-9A-Fa-f]{2}\s*)+)\s*\|(.+)\|$/);
if (match) {
return `<span class="hex-offset">${esc(match[1])}</span> <span class="hex-byte">${esc(match[2].trim())}</span> <span class="hex-ascii">|${esc(match[3])}|</span>`;
}
return esc(line);
})
.join('\n');
}