${esc(p.Description)}` : ''}
`).join('');
}
// ---------- Download flow ----------
function setStatus(eyebrow, heading, sub, isError) {
const elEyebrow = document.querySelector('[data-status-eyebrow]');
const elTitle = document.querySelector('[data-status-title]');
const elSub = document.querySelector('[data-status-sub]');
if (eyebrow) elEyebrow.textContent = eyebrow;
if (heading) elTitle.textContent = heading;
if (sub != null) elSub.textContent = sub;
if (isError) elTitle.setAttribute('data-status-error', '');
else elTitle.removeAttribute('data-status-error');
}
function runDownloadFlow(r) {
if (!r.title || !r.download || !r.type) {
setStatus('Store', 'Missing download info',
'This link appears to be incomplete. Head back to the store and try again.', true);
return;
}
if (r.type === 'zip') {
setStatus('Download', r.title + ' download started',
'Check your browser for the downloaded .zip file.');
return;
}
// type === 'plugdata' — fetch the binary and save it with a .plugdata extension
setStatus('Download', 'Downloading ' + r.title + '…',
'Please keep this tab open while we prepare your patch.');
fetch(r.download)
.then(response => {
if (!response.ok) throw new Error('Network response was not ok: ' + response.statusText);
return response.blob();
})
.then(blob => {
const link = document.createElement('a');
link.download = r.title + '.plugdata';
link.href = URL.createObjectURL(blob);
document.body.appendChild(link);
link.click();
URL.revokeObjectURL(link.href);
document.body.removeChild(link);
setStatus('Download', 'Download complete',
r.title + ' has been saved to your downloads folder.');
})
.catch(err => {
console.error('Download failed:', err);
setStatus('Download', 'Download failed',
'Something went wrong while fetching the patch. Please try again or return to the store.', true);
});
}
// ---------- Bootstrap ----------
const yearEl = document.querySelector('[data-year]');
if (yearEl) yearEl.textContent = new Date().getFullYear();
route();
})();