All tools · All versions
Changelog
Unified release history across iLEAPP, ALEAPP, RLEAPP, VLEAPP, DLEAPP, GLEAPP, LAVA, and Batch LEAPP — newest first. Data pulled live from GitHub.
RSS Feed—
Total releases
8
Tools tracked
—
Latest release
';
let currentYear = null;
entries.forEach((entry, i) => {
const year = new Date(entry.date).getFullYear();
if (year !== currentYear) {
currentYear = year;
html += `
';
container.innerHTML = html;
}
function renderLatestRow(entries) {
const latestByTool = {};
entries.forEach(e => {
if (!latestByTool[e.tool] || new Date(e.date) > new Date(latestByTool[e.tool].date)) {
latestByTool[e.tool] = e;
}
});
const order = ['lava', 'ileapp', 'aleapp', 'rleapp', 'vleapp', 'dleapp', 'gleapp', 'batch'];
document.getElementById('latest-row').innerHTML = order.map(id => {
const e = latestByTool[id];
if (!e) return '';
const url = `https://github.com/${e.repo}/releases/tag/${e.tag}`;
return `
${e.name}
${escapeHtml(e.tag)}
${formatDate(e.date)}
`;
}).join('');
}
async function fetchAll() {
try {
const results = await Promise.all(tools.map(async t => {
const res = await fetch(`https://leapps-api.4n6-198.workers.dev/repos/${t.repo}/releases?per_page=100`);
if (!res.ok) return [];
const releases = (await res.json()).filter(r => !r.draft);
return releases.map(r => ({
tool: t.id,
name: t.name,
repo: t.repo,
tag: r.tag_name,
date: r.published_at,
body: r.body || ''
}));
}));
allEntries = results.flat();
renderLatestRow(allEntries);
renderChangelog(allEntries);
} catch(e) {
document.getElementById('changelog-container').innerHTML =
'${year}
`;
}
const body = truncateBody(entry.body);
const releaseUrl = `https://github.com/${entry.repo}/releases/tag/${entry.tag}`;
html += `
`;
});
html += 'Could not load changelog. View on GitHub →
';
}
}
fetchAll();
// Mobile hamburger
const hamburger = document.getElementById('lp-hamburger');
const mobileMenu = document.getElementById('lp-mobile-menu');
hamburger.addEventListener('click', function() {
hamburger.classList.toggle('open');
mobileMenu.classList.toggle('open');
});
function closeMobileMenu() {
hamburger.classList.remove('open');
mobileMenu.classList.remove('open');
}
document.addEventListener('click', function(e) {
if (!hamburger.contains(e.target) && !mobileMenu.contains(e.target)) closeMobileMenu();
});
