(function() { 'use strict'; var accessibleProjects = []; // [{name, url}, ...] from server var presets = []; // [{name, projects[]}, ...] from localStorage var PRESETS_KEY = 'zddc_landing_presets'; // ── Initialise ────────────────────────────────────────────────────────── async function init() { loadPresets(); var urlProjects = getUrlProjects(); var projectList = document.getElementById('projectList'); projectList.innerHTML = '
Loading projects…<\/div>'; try { var resp = await fetch(location.origin + location.pathname.replace(/\/[^\/]*$/, '/'), { headers: { 'Accept': 'application/json' } }); if (!resp.ok) throw new Error('HTTP ' + resp.status); accessibleProjects = await resp.json(); } catch (e) { projectList.innerHTML = '
Could not load project list: ' + escapeHtml(e.message) + '<\/div>'; return; } // Warn about URL projects that are not accessible if (urlProjects.size > 0) { var missing = Array.from(urlProjects).filter(function(p) { return !accessibleProjects.some(function(ap) { return ap.name === p; }); }); if (missing.length > 0) { showWarning('This link includes projects you don\'t have access to: ' + missing.map(escapeHtml).join(', ')); } } renderProjects(urlProjects); renderPresetMenu(); // Close preset menu on outside click document.addEventListener('click', function(e) { var menu = document.getElementById('presetMenu'); var btn = document.getElementById('presetMenuBtn'); if (menu && !menu.classList.contains('hidden') && !menu.contains(e.target) && e.target !== btn) { menu.classList.add('hidden'); } }); } function getUrlProjects() { var params = new URLSearchParams(location.search); var val = params.get('projects'); if (!val) return new Set(); return new Set(val.split(',').map(function(p) { return p.trim(); }).filter(Boolean)); } // ── Rendering ──────────────────────────────────────────────────────────── function renderProjects(preCheck) { var container = document.getElementById('projectList'); if (accessibleProjects.length === 0) { container.innerHTML = '
No projects available.<\/div>'; return; } var html = accessibleProjects.map(function(p) { var checked = (preCheck.size === 0 || preCheck.has(p.name)) ? ' checked' : ''; return '
' + '' + '' + escapeHtml(p.name) + '<\/span>' + '<\/div>'; }).join(''); container.innerHTML = html; } function renderPresetMenu() { var menu = document.getElementById('presetMenu'); if (!menu) return; if (presets.length === 0) { menu.innerHTML = '
No presets saved.<\/div>'; return; } menu.innerHTML = presets.map(function(preset) { return '
' + '' + escapeHtml(preset.name) + '<\/span>' + '