const firmwareFile = document.getElementById('firmwareFile'); const fileInfo = document.getElementById('fileInfo'); const flashBtn = document.getElementById('flashBtn'); const status = document.getElementById('status'); let selectedFile = null; firmwareFile.addEventListener('change', (e) => { selectedFile = e.target.files[0]; if (selectedFile) { fileInfo.textContent = `Выбран файл: ${selectedFile.name} (${(selectedFile.size / 1024).toFixed(1)} KB)`; flashBtn.disabled = false; } else { fileInfo.textContent = ''; flashBtn.disabled = true; } }); flashBtn.addEventListener('click', async () => { if (!selectedFile) return; status.textContent = 'Подключите радиостанцию к компьютеру и нажмите кнопку на устройстве...'; status.className = 'loading'; try { const device = await navigator.usb.requestDevice({ filters: [{ vendorId: 0x15e2, productId: 0x9100 }] }); await device.open(); await device.selectConfiguration(1); await device.claimInterface(0); const buffer = await selectedFile.arrayBuffer(); const chunkSize = 64; const totalChunks = Math.ceil(buffer.byteLength / chunkSize); for (let i = 0; i < totalChunks; i++) { const start = i * chunkSize; const end = Math.min(start + chunkSize, buffer.byteLength); const chunk = buffer.slice(start, end); await device.transferOut(1, chunk); status.textContent = `Загрузка: ${Math.round((i / totalChunks) * 100)}%`; await new Promise(r => setTimeout(r, 10)); } await device.releaseInterface(0); await device.close(); status.textContent = 'Прошивка успешно загружена!'; status.className = 'success'; } catch (err) { if (err.name === 'NotFoundError') { status.textContent = 'Устройство не найдено. Подключите радиостанцию и разрешите доступ.'; status.className = 'error'; } else { status.textContent = 'Ошибка: ' + err.message; status.className = 'error'; } } });