'use strict'; (function initChimeraNavigation() { const contract = window.ChimeraNavigationContract; if (!contract) { console.error('[navigation] ChimeraNavigationContract is missing.'); return; } const routeById = new Map(contract.routes.map(route => [route.id, route])); const groupById = new Map(contract.groups.map(group => [group.id, group])); const expandedGroups = new Set(); const iconPaths = { home: '', library: '', console: '', payload: '', shield: '', tools: '', settings: '', action: '', more: '', }; let currentRouteId = null; let activePayloadStage = 'discover'; let navigationSequence = 0; let commandGameCache = null; let commandGameCacheAt = 0; let commandSearchSequence = 0; let currentTransferState = { jobs: [], activeCount: 0, queuedCount: 0, paused: false }; let currentActionCount = 0; let expertMode = false; const tr = (key, fallback) => typeof window.t === 'function' ? window.t(key, fallback) : fallback; const routeKey = route => `navigation.routes.${route.id.replace(/\//g, '.')}`; const routeLabel = route => tr(`${routeKey(route)}.label`, route.label); const routeDescription = route => tr(`${routeKey(route)}.description`, route.description); const groupLabel = group => tr(`navigation.groups.${group.id}`, group.label); const activeLocale = () => window.i18n?.current === 'nl' ? 'nl-BE' : 'en-GB'; const escapeText = value => String(value ?? '') .replace(/&/g, '&').replace(//g, '>') .replace(/"/g, '"').replace(/'/g, '''); function icon(name) { return ``; } function normalizeRoute(value) { let routeId = String(value || '').trim().replace(/^#\/?/, '').replace(/^\/+|\/+$/g, ''); try { routeId = decodeURIComponent(routeId); } catch (_) {} routeId = contract.legacyAliases[routeId] || routeId; if (!routeById.has(routeId)) return contract.defaultRoute; const route = routeById.get(routeId); if (route.expert && !expertMode) return groupById.get(route.group)?.defaultRoute || contract.defaultRoute; return routeId; } async function syncExpertPermission() { if (typeof window.pork?.sessionExpertMode !== 'function') return expertMode; try { const result = await window.pork.sessionExpertMode(expertMode, expertMode ? 'ENABLE EXPERT MODE' : undefined); expertMode = result?.enabled === true; } catch (_) { expertMode = false; } document.body.classList.toggle('chimera-expert-mode', expertMode); const toggle = document.getElementById('chimera-expert-mode'); if (toggle) toggle.checked = expertMode; return expertMode; } setTimeout(syncExpertPermission); function routeFromLocation() { return normalizeRoute(window.location.hash); } function routeUrl(routeId) { return `#/${encodeURI(routeId)}`; } function mountSidebar() { const navList = document.querySelector('#sidebar .nav-list'); if (!navList) return; navList.className = 'nav-list chimera-nav-root'; navList.setAttribute('aria-label', 'Chimera main navigation'); navList.innerHTML = contract.groups.map(group => { const isHome = group.routes.length === 1 && group.routes[0].id === 'home'; const routeLinks = group.routes.map(route => `
  • ${escapeText(routeLabel(route))} ${route.risk === 'confirm' ? `!` : ''} ${route.badge === 'transfer' ? '' : ''}
  • `).join(''); return `
  • ${isHome ? ` ${icon(group.icon)}${escapeText(groupLabel(group))} ` : ` `}
  • `; }).join('') + `
  • `; document.body.classList.toggle('chimera-expert-mode', expertMode); const aboutLabel = document.querySelector('#sidebar-donate .donate-label'); if (aboutLabel) { aboutLabel.removeAttribute('data-i18n'); aboutLabel.textContent = tr('navigation.about', 'About Chimera'); aboutLabel.dataset.i18n = 'navigation.about'; } } function mountShell() { document.body.classList.add('chimera-shell-v2'); const content = document.getElementById('content'); if (!content) return; const toolbar = document.createElement('div'); toolbar.id = 'chimera-shell-toolbar'; toolbar.innerHTML = `
    Console Disconnected
    `; const mobileToggle = document.getElementById('mobile-nav-toggle'); if (mobileToggle) toolbar.prepend(mobileToggle); const header = document.createElement('header'); header.id = 'chimera-route-header'; header.innerHTML = `

    Chimera

    `; content.prepend(header); content.prepend(toolbar); const palette = document.createElement('div'); palette.id = 'chimera-command-overlay'; palette.className = 'chimera-overlay'; palette.hidden = true; palette.innerHTML = ` `; document.body.appendChild(palette); const drawer = document.createElement('div'); drawer.id = 'chimera-jobs-overlay'; drawer.className = 'chimera-overlay chimera-drawer-overlay'; drawer.hidden = true; drawer.innerHTML = ` `; document.body.appendChild(drawer); } function mountCompanionDock() { if (document.getElementById('chimera-companion-dock')) return; const dock = document.createElement('nav'); dock.id = 'chimera-companion-dock'; dock.className = 'chimera-companion-dock'; dock.setAttribute('aria-label', tr('navigation.companion.label', 'Companion shortcuts')); dock.dataset.i18nAriaLabel = 'navigation.companion.label'; dock.innerHTML = ` ${icon('home')}Home ${icon('library')}Games ${icon('console')}Console `; document.body.appendChild(dock); } function mountHomeCommandCenter() { const page = document.getElementById('page-dashboard'); const template = document.getElementById('chimera-home-command-center-template'); if (!page || !template || document.getElementById('chimera-home-command-center')) return; const launchpad = document.createElement('section'); launchpad.id = 'chimera-home-command-center'; launchpad.setAttribute('aria-label', 'Chimera status and next steps'); launchpad.append(template.content.cloneNode(true)); const pageHeader = page.querySelector(':scope > .page-header'); if (pageHeader) pageHeader.insertAdjacentElement('afterend', launchpad); else page.prepend(launchpad); } function mountSettingsNavigator() { const page = document.getElementById('page-settings'); if (!page || document.getElementById('chimera-settings-navigator')) return; const cards = [...page.querySelectorAll(':scope > .card')]; if (!cards.length) return; const categoryFor = (card, label) => { const id = String(card.id || ''); const value = `${id} ${label}`.toLowerCase(); if (/appearance|language/.test(value)) return 'setup'; if (/console profile|console identity|ftp connection|payload manager|cheats manager|save manager/.test(value)) return 'console'; if (/game source|conversion|remote game|metadata|ps4 package|package preservation/.test(value)) return 'storage'; if (/automation advisor/.test(value)) return 'automation'; if (/two-factor|passkey|security/.test(value)) return 'security'; if (/payload remote|integration|notification|companion/.test(value)) return 'integrations'; return 'advanced'; }; const sections = cards.map((card, index) => { const heading = card.querySelector('h2, h3, h4'); const label = heading?.textContent?.trim() || `${tr('settingsNavigator.section', 'Section')} ${index + 1}`; if (!card.id) card.id = `settings-section-${index + 1}`; card.style.scrollMarginTop = '108px'; const category = categoryFor(card, label); card.dataset.settingsCategory = category; return { card, id: card.id, label, category }; }); const categories = [ ['setup', tr('settingsNavigator.setup', 'Setup')], ['console', tr('settingsNavigator.console', 'Console')], ['storage', tr('settingsNavigator.storage', 'Storage')], ['automation', tr('settingsNavigator.automation', 'Automation')], ['integrations', tr('settingsNavigator.integrations', 'Integrations')], ['security', tr('settingsNavigator.security', 'Security')], ['advanced', tr('settingsNavigator.advanced', 'Advanced')], ]; let activeCategory = 'setup'; const navigator = document.createElement('section'); navigator.id = 'chimera-settings-navigator'; navigator.className = 'chimera-settings-navigator'; navigator.setAttribute('aria-label', 'Search and navigate settings'); navigator.innerHTML = `
    Find a setting quickly ${sections.length} ${tr('settingsNavigator.sections', 'sections')}
    ${categories.map(([id, label], index) => ``).join('')}
    `; const pageHeader = page.querySelector(':scope > .page-header'); if (pageHeader) pageHeader.insertAdjacentElement('afterend', navigator); else page.prepend(navigator); const input = navigator.querySelector('#chimera-settings-search'); const clearButton = navigator.querySelector('#chimera-settings-clear'); const status = navigator.querySelector('#chimera-settings-filter-status'); const jump = navigator.querySelector('#chimera-settings-jump'); const syncSections = () => { sections.forEach((section, index) => { const liveLabel = section.card.querySelector('h2, h3, h4')?.textContent?.trim() || section.label; section.label = liveLabel; if (jump.options[index + 1]) jump.options[index + 1].textContent = liveLabel; }); }; const applyFilter = value => { const query = String(value || '').trim().toLocaleLowerCase(activeLocale()); let visible = 0; sections.forEach(section => { const searchText = section.card.textContent.toLocaleLowerCase(activeLocale()); const matchesCategory = activeCategory === 'all' || section.category === activeCategory; const matches = matchesCategory && (!query || searchText.includes(query)); section.card.toggleAttribute('data-settings-filter-hidden', !matches); if (matches) visible += 1; }); clearButton.hidden = !query; status.textContent = query || activeCategory !== 'all' ? `${visible} ${tr('settingsNavigator.of', 'of')} ${sections.length} ${tr('settingsNavigator.sections', 'sections')}` : `${sections.length} ${tr('settingsNavigator.sections', 'sections')}`; }; applyFilter(''); navigator.querySelector('.chimera-settings-categories').addEventListener('click', event => { const button = event.target.closest('[data-settings-category]'); if (!button) return; activeCategory = button.dataset.settingsCategory; navigator.querySelectorAll('[data-settings-category]').forEach(candidate => candidate.setAttribute('aria-selected', String(candidate === button))); applyFilter(input.value); }); input.addEventListener('input', event => applyFilter(event.target.value)); clearButton.addEventListener('click', () => { input.value = ''; applyFilter(''); input.focus(); }); jump.addEventListener('focus', syncSections); jump.addEventListener('pointerdown', syncSections); jump.addEventListener('change', event => { const section = sections.find(item => item.id === event.target.value); if (!section) return; input.value = ''; activeCategory = section.category; navigator.querySelectorAll('[data-settings-category]').forEach(candidate => candidate.setAttribute('aria-selected', String(candidate.dataset.settingsCategory === activeCategory))); applyFilter(''); section.card.scrollIntoView({ behavior: window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 'auto' : 'smooth', block: 'center', }); event.target.value = ''; }); window.addEventListener('chimera:language-changed', () => { syncSections(); applyFilter(input.value); }); window.setTimeout(syncSections, 0); } function setExpandedGroup(groupId, expanded) { if (expanded) { for (const openGroup of [...expandedGroups]) { if (openGroup !== groupId) setExpandedGroup(openGroup, false); } } if (expanded) expandedGroups.add(groupId); else expandedGroups.delete(groupId); const domain = [...document.querySelectorAll('[data-nav-group]')].find(item => item.dataset.navGroup === groupId); if (!domain) return; const button = domain.querySelector('[data-group-toggle]'); const routes = domain.querySelector('[data-group-routes]'); if (button) button.setAttribute('aria-expanded', String(expanded)); if (routes) routes.hidden = !expanded; domain.classList.toggle('expanded', expanded); } function updateSidebar(route) { const group = groupById.get(route.group); if (group && group.id !== 'home') setExpandedGroup(group.id, true); document.querySelectorAll('[data-route]:not([data-payload-stage])').forEach(element => { const active = element.dataset.route === route.id; element.classList.toggle('active', active); if (element.matches('a,button')) { if (active) element.setAttribute('aria-current', 'page'); else element.removeAttribute('aria-current'); } }); updatePayloadWorkspaceStage(route.id); document.querySelectorAll('[data-nav-group]').forEach(element => element.classList.toggle('active', element.dataset.navGroup === route.group)); document.querySelectorAll('#chimera-companion-dock [data-companion-group]').forEach(element => { const active = element.dataset.route === 'library/games' ? route.id === 'library/games' : element.dataset.companionGroup === route.group; element.classList.toggle('active', active); if (active) element.setAttribute('aria-current', 'page'); else element.removeAttribute('aria-current'); }); document.getElementById('chimera-companion-more')?.classList.toggle( 'active', !['home', 'library', 'console'].includes(route.group), ); } function defaultPayloadStage(routeId) { if (routeId === 'payloads/updates') return 'review'; if (routeId === 'payloads/boot') return 'boot'; if (routeId === 'payloads/installed') return 'discover'; return null; } function updatePayloadWorkspaceStage(routeId, requestedStage = null) { const currentButton = document.querySelector(`[data-payload-stage="${activePayloadStage}"]`); const stage = requestedStage || (currentButton?.dataset.route === routeId ? activePayloadStage : defaultPayloadStage(routeId)); if (!stage) return; activePayloadStage = stage; const stages = ['discover', 'review', 'stage', 'boot']; const currentIndex = stages.indexOf(stage); document.querySelectorAll('[data-payload-stage]').forEach(button => { const buttonIndex = stages.indexOf(button.dataset.payloadStage); const current = button.dataset.payloadStage === stage; button.classList.toggle('is-current', current); button.classList.toggle('is-complete', buttonIndex >= 0 && buttonIndex < currentIndex); button.setAttribute('aria-pressed', String(current)); if (current) button.setAttribute('aria-current', 'step'); else button.removeAttribute('aria-current'); }); } function localizeSidebar() { contract.routes.forEach(route => { document.querySelectorAll(`.chimera-route-link[data-route="${route.id}"]`).forEach(link => { const label = link.querySelector(':scope > span:first-child'); if (label) label.textContent = routeLabel(route); link.title = routeDescription(route); }); }); contract.groups.forEach(group => { const label = document.querySelector(`[data-nav-group="${group.id}"] .chimera-domain-button > span:not(.chimera-domain-chevron)`); if (label) label.textContent = groupLabel(group); }); const aboutLabel = document.querySelector('#sidebar-donate .donate-label'); if (aboutLabel) aboutLabel.textContent = tr('navigation.about', 'About Chimera'); } function updateRouteHeader(route) { const group = groupById.get(route.group); const localizedGroup = groupLabel(group); const localizedLabel = routeLabel(route); const localizedDescription = routeDescription(route); const breadcrumbs = document.getElementById('chimera-breadcrumbs'); if (breadcrumbs) breadcrumbs.innerHTML = route.id === 'home' ? 'Home' : `${escapeText(localizedLabel)}`; const title = document.getElementById('chimera-route-title'); const description = document.getElementById('chimera-route-description'); const risk = document.getElementById('chimera-route-risk'); if (title) title.textContent = localizedLabel; if (description) description.textContent = localizedDescription; if (risk) risk.hidden = route.risk !== 'confirm'; document.title = `${localizedLabel} — Chimera`; } function clearRouteFocus() { document.querySelectorAll('[data-route-hidden="true"]').forEach(element => element.removeAttribute('data-route-hidden')); document.querySelectorAll('[data-route-focus]').forEach(element => element.removeAttribute('data-route-focus')); } function hideElement(element) { if (element) element.setAttribute('data-route-hidden', 'true'); } function showOnlyPageChildren(pageId, allowedIds) { const page = document.getElementById(pageId); if (!page) return; const allowed = new Set(allowedIds); [...page.children].forEach(child => { if (child.classList.contains('page-header') || child.hasAttribute('data-route-persistent')) return; if (!child.id || !allowed.has(child.id)) hideElement(child); }); } function applyJailbreakFocus(focus) { if (!focus) return; const profiles = { payloads: ['ps5-payload-manager-card', 'console-services-card', 'payload-update-card', 'payload-manager-card'], boot: ['payload-manager-card', 'y2jb-generator-card', 'bdjb-generator-card'], power: ['system-state-card'], }; showOnlyPageChildren('page-jailbreak', profiles[focus] || profiles.payloads); const workspaceNav = document.querySelector('#page-jailbreak > .payload-workspace-nav'); if (workspaceNav && focus === 'power') hideElement(workspaceNav); const sectionVisibility = { payloads: ['payload-local-section', 'payload-sender-section'], boot: ['payload-autoloader-section', 'autoloader-snapshots-section'], }; if (sectionVisibility[focus]) { const visible = new Set(sectionVisibility[focus]); document.querySelectorAll('#payload-manager-card > .jb-section').forEach(section => { if (!visible.has(section.id)) hideElement(section); }); } document.getElementById('page-jailbreak')?.setAttribute('data-route-focus', focus); } function applyReliabilityFocus(focus) { if (!focus) return; const visibleIds = { replication: ['operations-reliability-warning', 'operations-replication-card'], monitoring: ['operations-monitoring-card'], security: ['operations-sessions-card', 'operations-password-card'], }[focus]; if (!visibleIds) return; const visible = new Set(visibleIds); document.querySelectorAll('[data-operations-panel="reliability"] .card[id]').forEach(card => { if (!visible.has(card.id)) hideElement(card); }); document.querySelectorAll('[data-operations-panel="reliability"] .operations-two-column').forEach(column => { const cards = [...column.querySelectorAll(':scope > .card')]; if (cards.length && cards.every(card => card.hasAttribute('data-route-hidden'))) hideElement(column); }); document.querySelector('[data-operations-panel="reliability"]')?.setAttribute('data-route-focus', focus); } function applyRouteFocus(route) { if (route.page === 'jailbreak') return applyJailbreakFocus(route.focus); if (route.page === 'operations' && route.panel === 'reliability') return applyReliabilityFocus(route.focus); } function activatePage(page) { document.querySelectorAll('.page').forEach(element => element.classList.toggle('active', element.id === `page-${page}`)); const isEmbed = page === 'savemgr'; document.getElementById('content')?.classList.toggle('embed-page-active', isEmbed); if (!isEmbed) { const content = document.getElementById('content'); if (content) content.scrollTop = 0; } closeMobileNav(); if (typeof syncPinStates === 'function') syncPinStates(); if (typeof scheduleBackgroundWarm === 'function') scheduleBackgroundWarm(800); } function selectEcosystemPanel(tab) { document.querySelectorAll('.ecosystem-tab').forEach(button => { const active = button.dataset.ecosystemTab === tab; button.classList.toggle('active', active); button.setAttribute('aria-selected', String(active)); button.tabIndex = active ? 0 : -1; }); document.querySelectorAll('.ecosystem-panel').forEach(panel => { const active = panel.dataset.ecosystemPanel === tab; panel.classList.toggle('active', active); panel.hidden = !active; }); } async function loadEcosystemRoute(route, force) { const wasStale = force || pageIsStale('ecosystem'); window.chimeraRequestedEcosystemTab = route.tab; await ensurePageReady('ecosystem', { force: !!force }); selectEcosystemPanel(route.tab); if (!wasStale && typeof loadEcosystemTab === 'function') await loadEcosystemTab(route.tab); } async function loadOperationsRoute(route, force) { await ensurePageReady('operations', { force: !!force }); document.querySelectorAll('.operations-tab').forEach(button => { const active = button.dataset.operationsTab === route.panel; button.classList.toggle('active', active); button.setAttribute('aria-selected', String(active)); button.tabIndex = active ? 0 : -1; }); document.querySelectorAll('.operations-panel').forEach(panel => { const active = panel.dataset.operationsPanel === route.panel; panel.classList.toggle('active', active); panel.hidden = !active; }); if (route.panel === 'shadowmount' && typeof loadOperationsShadowMount === 'function') await loadOperationsShadowMount(); if (route.panel === 'packages' && typeof loadOperationsPackages === 'function') await loadOperationsPackages(); if (route.panel === 'reliability' && typeof loadOperationsReliability === 'function') await loadOperationsReliability({ focus: route.focus }); if (route.panel === 'audit' && typeof loadOperationsAudit === 'function') await loadOperationsAudit(); if (route.panel === 'diagnostics' && typeof loadKlog === 'function') await loadKlog(); } async function hydrateRoute(route, force) { if (route.page === 'ecosystem') await loadEcosystemRoute(route, force); else if (route.page === 'operations') await loadOperationsRoute(route, force); else await ensurePageReady(route.page, { force: !!force }); } function writeHistory(routeId, mode) { const url = routeUrl(routeId); if (mode === 'push') window.history.pushState({ chimeraRoute: routeId }, '', url); if (mode === 'replace') window.history.replaceState({ chimeraRoute: routeId }, '', url); } async function navigateRoute(value, options = {}) { const routeId = normalizeRoute(value); const route = routeById.get(routeId); const historyMode = options.history ?? 'push'; if (!route) return; if (currentRouteId === routeId && !options.force) { closeMobileNav(); if (historyMode === 'replace') writeHistory(routeId, 'replace'); return; } const sequence = ++navigationSequence; clearRouteFocus(); currentRouteId = routeId; if (historyMode !== 'none') writeHistory(routeId, historyMode); updateSidebar(route); updateRouteHeader(route); // Apply deep-route disclosure while the destination page is still hidden. // This prevents unrelated Reliability cards from flashing for one frame. applyRouteFocus(route); activatePage(route.page); document.body.setAttribute('data-chimera-route', route.id); const refresh = document.getElementById('chimera-route-refresh'); const availability = document.getElementById('chimera-route-availability'); if (availability) availability.hidden = true; if (refresh) { refresh.disabled = true; refresh.textContent = tr('common.loading', 'Loading…'); } try { await window.chimeraI18nReady; if (sequence !== navigationSequence) return; await hydrateRoute(route, options.force); if (sequence !== navigationSequence) return; applyRouteFocus(route); } catch (error) { if (typeof isExpectedUnavailable === 'function' && isExpectedUnavailable(error)) { console.info(`[navigation] ${route.id} temporarily unavailable: ${error.message}`); if (availability) { availability.textContent = `${tr('navigation.unavailable', 'Unavailable')}: ${friendlyMessage(error?.message || error)}`; availability.hidden = false; } } else { console.error(`[navigation] ${route.id}`, error); const failure = `${tr('navigation.loadFailed', 'Could not fully load')} ${routeLabel(route)}: ${friendlyMessage(error?.message || error)}`; if (availability) { availability.textContent = `${failure}. ${tr('navigation.retryHint', 'Use Refresh to retry.')}`; availability.hidden = false; } else if (typeof showToast === 'function') { showToast(failure, 'error', 9000); } } } finally { if (sequence === navigationSequence && refresh) { refresh.disabled = false; refresh.innerHTML = `↻ ${escapeText(tr('common.refresh', 'Refresh'))}`; } } } function openCommandPalette() { const overlay = document.getElementById('chimera-command-overlay'); if (!overlay) return; document.body.classList.add('chimera-modal-open'); const input = document.getElementById('chimera-command-input'); input.value = ''; document.getElementById('chimera-command-clear')?.setAttribute('hidden', ''); renderCommandResults(''); if (typeof openAccessibleDialog === 'function') openAccessibleDialog(overlay, input); else { overlay.hidden = false; requestAnimationFrame(() => input.focus()); } } function closeCommandPalette() { const overlay = document.getElementById('chimera-command-overlay'); if (typeof closeAccessibleDialog === 'function') closeAccessibleDialog(overlay); else if (overlay) overlay.hidden = true; if (document.getElementById('chimera-jobs-overlay')?.hidden !== false) document.body.classList.remove('chimera-modal-open'); } function routeMatches(route, query) { const group = groupById.get(route.group); return [route.label, routeLabel(route), route.description, routeDescription(route), route.id, group?.label, groupLabel(group), ...(route.keywords || [])].join(' ').toLocaleLowerCase(activeLocale()).includes(query); } function commandRouteMarkup(routes) { if (!routes.length) return ''; return `${routes.map(route => { const group = groupById.get(route.group); return ``; }).join('')}`; } function commandGameMarkup(games) { if (!games.length) return ''; return `${games.map(game => { const name = game.prospero_name || game.title || game.game_id; return ``; }).join('')}`; } function recentCommandQueries() { try { const value = JSON.parse(localStorage.getItem('chimera.search.recent') || '[]'); return Array.isArray(value) ? value.filter(item => typeof item === 'string' && item.trim()).slice(0, 6) : []; } catch (_) { return []; } } function rememberCommandQuery(value) { const query = String(value || '').trim(); if (query.length < 2) return; const recent = [query, ...recentCommandQueries().filter(item => item.toLocaleLowerCase(activeLocale()) !== query.toLocaleLowerCase(activeLocale()))].slice(0, 6); localStorage.setItem('chimera.search.recent', JSON.stringify(recent)); } function recentCommandMarkup() { const recent = recentCommandQueries(); if (!recent.length) return ''; return `
    ${recent.map(query => ``).join('')}
    `; } function resetCommandSelection() { const first = document.querySelector('#chimera-command-results .chimera-command-result'); if (first) { first.classList.add('selected'); first.setAttribute('aria-selected', 'true'); } } function updateCommandStatus(message, busy = false) { const results = document.getElementById('chimera-command-results'); const status = document.getElementById('chimera-command-status'); if (results) results.setAttribute('aria-busy', String(busy)); if (status) status.textContent = message; } async function getCommandGames(query = '') { if (!window.pork.isWebMode && Array.isArray(state?.games) && state.games.length) return state.games; const cacheKey = String(query || '').trim().toLocaleLowerCase(activeLocale()); if (commandGameCache?.key === cacheKey && Date.now() - commandGameCacheAt < 60_000) return commandGameCache.games; const result = await window.pork.listGames(cacheKey ? { search: cacheKey, limit: 24 } : { limit: 24 }); commandGameCache = { key: cacheKey, games: Array.isArray(result) ? result : (result?.games || []) }; commandGameCacheAt = Date.now(); return commandGameCache.games; } async function renderCommandResults(value) { const results = document.getElementById('chimera-command-results'); if (!results) return; const query = String(value || '').trim().toLocaleLowerCase(activeLocale()); const sequence = ++commandSearchSequence; const clearButton = document.getElementById('chimera-command-clear'); if (clearButton) clearButton.hidden = !query; const availableRoutes = contract.routes.filter(route => expertMode || !route.expert); const routes = (query ? availableRoutes.filter(route => routeMatches(route, query)) : availableRoutes.filter(route => ['home', 'library/games', 'console/status', 'payloads/installed', 'tools/transfers', 'settings/general'].includes(route.id))).slice(0, 12); const recentMarkup = query ? '' : recentCommandMarkup(); results.innerHTML = `${recentMarkup}${commandRouteMarkup(routes)}` || `

    ${escapeText(tr('navigation.search.noFeature', 'No feature found. Keep typing to search games.'))}

    `; resetCommandSelection(); if (query.length < 2) { updateCommandStatus(query ? `${routes.length} ${tr('navigation.search.featuresLower', 'features')} · ${tr('navigation.search.oneMore', 'type 1 more character for games')}` : `${routes.length} ${tr('navigation.search.quickRoutes', 'quick routes')}`); return; } updateCommandStatus(`${routes.length} ${tr('navigation.search.featuresLower', 'features')} · ${tr('navigation.search.searchingGames', 'searching games…')}`, true); try { const games = (await getCommandGames(query)).filter(game => [game.prospero_name, game.title, game.game_id, game.prospero_publisher].filter(Boolean).join(' ').toLocaleLowerCase(activeLocale()).includes(query)).slice(0, 8); if (sequence !== commandSearchSequence) return; results.innerHTML = `${commandRouteMarkup(routes)}${commandGameMarkup(games)}` || `

    ${escapeText(tr('navigation.search.noMatches', 'No matches found.'))}

    `; resetCommandSelection(); updateCommandStatus(`${routes.length + games.length} ${tr('navigation.search.results', 'results')}`); } catch (_) { if (!routes.length && sequence === commandSearchSequence) results.innerHTML = `

    ${escapeText(tr('navigation.search.gamesUnavailable', 'Game search is currently unavailable.'))}

    `; if (sequence === commandSearchSequence) updateCommandStatus(routes.length ? `${routes.length} ${tr('navigation.search.featuresLower', 'features')} · ${tr('navigation.search.gamesUnavailableShort', 'games unavailable')}` : tr('navigation.search.noResults', 'No results')); } } async function activateCommandResult(button) { if (!button) return; rememberCommandQuery(document.getElementById('chimera-command-input')?.value); closeCommandPalette(); if (button.dataset.commandRoute) return navigateRoute(button.dataset.commandRoute); if (button.dataset.commandGame) { await navigateRoute('library/games'); const input = document.getElementById('games-search'); if (input) { input.value = button.dataset.commandGame; input.dispatchEvent(new Event('input', { bubbles: true })); } } } function moveCommandSelection(direction) { const buttons = [...document.querySelectorAll('#chimera-command-results .chimera-command-result')]; if (!buttons.length) return; let index = buttons.findIndex(button => button.classList.contains('selected')); buttons.forEach(button => { button.classList.remove('selected'); button.setAttribute('aria-selected', 'false'); }); index = (index + direction + buttons.length) % buttons.length; buttons[index].classList.add('selected'); buttons[index].setAttribute('aria-selected', 'true'); buttons[index].scrollIntoView({ block: 'nearest' }); } function transferStatusLabel(status) { const fallback = { queued: 'Queued', active: 'Active', done: 'Completed', error: 'Error', cancelled: 'Cancelled', interrupted: 'Interrupted', retrying: 'Retry scheduled', }[status] || status || 'Unknown'; return tr(`navigation.jobs.status.${status || 'unknown'}`, fallback); } function renderJobs(stateValue) { currentTransferState = stateValue || currentTransferState; const active = Number(currentTransferState.activeCount || 0); const queued = Number(currentTransferState.queuedCount || 0); const count = active + queued; const homeTransferTruth = document.getElementById('home-truth-transfers'); if (homeTransferTruth) { homeTransferTruth.textContent = active ? `${active} active` : queued ? `${queued} queued` : currentTransferState.paused ? 'Queue paused' : 'No active work'; } const badge = document.getElementById('chimera-job-count'); const navBadge = document.getElementById('nav-transfer-badge'); if (badge) { const total = count + currentActionCount; badge.hidden = total === 0; badge.textContent = String(total); } if (navBadge) { navBadge.hidden = count === 0; navBadge.textContent = String(count); } const companionBadge = document.getElementById('chimera-companion-count'); if (companionBadge) { const total = count + currentActionCount; companionBadge.hidden = total === 0; companionBadge.textContent = String(total); } document.querySelector('.chimera-jobs-pulse')?.classList.toggle('active', active > 0); const summary = document.getElementById('chimera-jobs-summary'); const list = document.getElementById('chimera-jobs-list'); if (summary) summary.innerHTML = `
    ${active}${escapeText(tr('navigation.jobs.active', 'active'))}
    ${queued}${escapeText(tr('navigation.jobs.queued', 'queued'))}
    ${escapeText(currentTransferState.paused ? tr('common.yes', 'Yes') : tr('common.no', 'No'))}${escapeText(tr('navigation.jobs.paused', 'paused'))}
    `; if (!list) return; const jobs = (currentTransferState.jobs || []).filter(job => job.status !== 'cancelled').slice(-20).reverse(); list.innerHTML = jobs.length ? jobs.map(job => { const progress = Math.max(0, Math.min(100, Number(job.progress?.percent || (job.status === 'done' ? 100 : 0)))); return `
    ${escapeText(job.label || job.progress?.file || 'Transfer')}${escapeText(transferStatusLabel(job.status))}${job.progress?.file ? ` · ${escapeText(job.progress.file)}` : ''}
    ${Math.round(progress)}%
    ${job.error ? `${escapeText(job.error)}` : ''}
    `; }).join('') : `
    ${escapeText(tr('navigation.jobs.emptyTitle', 'No transfers'))}${escapeText(tr('navigation.jobs.emptyDetail', 'New uploads and downloads will appear here automatically.'))}
    `; } function actionRoute(action = {}) { if (action.tab) return contract.routes.find(route => route.page === 'ecosystem' && route.tab === action.tab)?.id || 'console/status'; if (action.panel) return contract.routes.find(route => route.page === 'operations' && route.panel === action.panel)?.id || 'settings/automation'; return contract.legacyAliases[action.page] || (routeById.has(action.page) ? action.page : 'console/status'); } function renderActions(packet) { const list = document.getElementById('chimera-action-list'); if (!list) return; const report = packet?.report || null; const alerts = (report?.alerts || []).filter(alert => !alert.acknowledged).slice(0, 12); currentActionCount = alerts.length; const badge = document.getElementById('chimera-job-count'); if (badge) { const total = Number(currentTransferState.activeCount || 0) + Number(currentTransferState.queuedCount || 0) + currentActionCount; badge.hidden = total === 0; badge.textContent = String(total); } const companionBadge = document.getElementById('chimera-companion-count'); if (companionBadge) { const total = Number(currentTransferState.activeCount || 0) + Number(currentTransferState.queuedCount || 0) + currentActionCount; companionBadge.hidden = total === 0; companionBadge.textContent = String(total); } if (!report) { list.innerHTML = `
    ${escapeText(tr('navigation.actionCenter.notScanned', 'No health scan yet'))}${escapeText(tr('navigation.actionCenter.notScannedDetail', 'Open Console health to run the first bounded scan.'))}
    `; return; } list.innerHTML = alerts.length ? alerts.map(alert => { const count = String(alert.title || '').match(/\d+(?:\/\d+)?/)?.[0] || ''; const values = { count }; const translatedTitle = window.tf?.(`navigation.alerts.${alert.id}.title`, alert.title, values) || alert.title; const translatedDetail = window.tf?.(`navigation.alerts.${alert.id}.detail`, alert.detail, values) || alert.detail; return `
    ${escapeText(translatedTitle)}${escapeText(translatedDetail)}
    `; }).join('') : `
    ${escapeText(tr('navigation.actionCenter.clear', 'Nothing needs attention'))}${escapeText(tr('navigation.actionCenter.clearDetail', 'No open alerts were found in the latest health scan.'))}
    `; } async function openJobsDrawer() { const overlay = document.getElementById('chimera-jobs-overlay'); if (!overlay) return; document.body.classList.add('chimera-modal-open'); const [transfers, health] = await Promise.allSettled([ window.pork.transferState(), window.pork.ecosystemHealthLatest(), ]); renderJobs(transfers.status === 'fulfilled' ? transfers.value : currentTransferState); renderActions(health.status === 'fulfilled' ? health.value : null); const closeButton = overlay.querySelector('[data-jobs-close]'); if (typeof openAccessibleDialog === 'function') openAccessibleDialog(overlay, closeButton); else { overlay.hidden = false; requestAnimationFrame(() => closeButton?.focus()); } } function closeJobsDrawer() { const overlay = document.getElementById('chimera-jobs-overlay'); if (typeof closeAccessibleDialog === 'function') closeAccessibleDialog(overlay); else if (overlay) overlay.hidden = true; if (document.getElementById('chimera-command-overlay')?.hidden !== false) document.body.classList.remove('chimera-modal-open'); } function openAboutDialog() { const overlay = document.getElementById('chimera-about-overlay'); if (!overlay) return; const closeButton = overlay.querySelector('[data-about-close]'); if (typeof openAccessibleDialog === 'function') openAccessibleDialog(overlay, closeButton); else { overlay.hidden = false; requestAnimationFrame(() => closeButton?.focus()); } } function closeAboutDialog() { const overlay = document.getElementById('chimera-about-overlay'); if (typeof closeAccessibleDialog === 'function') closeAccessibleDialog(overlay); else if (overlay) overlay.hidden = true; } function bindEvents() { document.addEventListener('click', async event => { const routeTarget = event.target.closest('[data-route]'); if (routeTarget) { event.preventDefault(); closeCommandPalette(); closeJobsDrawer(); closeAboutDialog(); const requestedStage = routeTarget.dataset.payloadStage || (!routeTarget.closest('.payload-workspace-nav') ? defaultPayloadStage(routeTarget.dataset.route) : null); if (requestedStage) activePayloadStage = requestedStage; await navigateRoute(routeTarget.dataset.route); const focusTarget = routeTarget.dataset.focusTarget ? document.getElementById(routeTarget.dataset.focusTarget) : null; if (focusTarget) { focusTarget.scrollIntoView({ behavior: window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 'auto' : 'smooth', block: 'center', }); requestAnimationFrame(() => focusTarget.focus({ preventScroll: true })); } if (requestedStage) updatePayloadWorkspaceStage(routeTarget.dataset.route, requestedStage); const payloadTarget = routeTarget.dataset.payloadTarget ? document.getElementById(routeTarget.dataset.payloadTarget) : null; if (payloadTarget) { payloadTarget.scrollIntoView({ behavior: 'smooth', block: 'start' }); payloadTarget.classList.remove('payload-workspace-highlight'); requestAnimationFrame(() => payloadTarget.classList.add('payload-workspace-highlight')); window.setTimeout(() => payloadTarget.classList.remove('payload-workspace-highlight'), 1800); } return; } const groupToggle = event.target.closest('[data-group-toggle]'); if (groupToggle) { const groupId = groupToggle.dataset.groupToggle; setExpandedGroup(groupId, !expandedGroups.has(groupId)); } const commandResult = event.target.closest('[data-command-route], [data-command-game]'); if (commandResult) activateCommandResult(commandResult); const commandQuery = event.target.closest('[data-command-query]'); if (commandQuery) { const input = document.getElementById('chimera-command-input'); if (input) { input.value = commandQuery.dataset.commandQuery; renderCommandResults(input.value); input.focus(); } } if (event.target.closest('[data-command-close]') || event.target.id === 'chimera-command-overlay') closeCommandPalette(); if (event.target.closest('[data-jobs-close]') || event.target.id === 'chimera-jobs-overlay') closeJobsDrawer(); if (event.target.closest('[data-about-close]') || event.target.id === 'chimera-about-overlay') closeAboutDialog(); }); document.getElementById('chimera-command-open')?.addEventListener('click', openCommandPalette); document.getElementById('chimera-jobs-open')?.addEventListener('click', openJobsDrawer); document.getElementById('chimera-companion-actions')?.addEventListener('click', openJobsDrawer); document.getElementById('chimera-companion-more')?.addEventListener('click', event => { document.getElementById('mobile-nav-toggle')?.click(); event.currentTarget.setAttribute('aria-expanded', String(document.body.classList.contains('mobile-nav-open'))); }); document.getElementById('chimera-route-refresh')?.addEventListener('click', () => navigateRoute(currentRouteId, { history: 'none', force: true })); document.getElementById('chimera-expert-mode')?.addEventListener('change', async event => { expertMode = event.target.checked; document.body.classList.toggle('chimera-expert-mode', expertMode); await syncExpertPermission(); window.dispatchEvent(new CustomEvent('chimera:expert-mode-changed', { detail: { enabled: expertMode }, })); if (!expertMode && routeById.get(currentRouteId)?.expert) navigateRoute(currentRouteId, { history: 'replace', force: true }); }); document.getElementById('chimera-command-input')?.addEventListener('input', event => renderCommandResults(event.target.value)); document.getElementById('chimera-command-clear')?.addEventListener('click', () => { const input = document.getElementById('chimera-command-input'); if (!input) return; input.value = ''; renderCommandResults(''); input.focus(); }); document.getElementById('chimera-command-input')?.addEventListener('keydown', event => { if (event.key === 'ArrowDown' || event.key === 'ArrowUp') { event.preventDefault(); moveCommandSelection(event.key === 'ArrowDown' ? 1 : -1); } if (event.key === 'Enter') { event.preventDefault(); activateCommandResult(document.querySelector('#chimera-command-results .chimera-command-result.selected')); } }); document.addEventListener('keydown', event => { if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'k') { event.preventDefault(); openCommandPalette(); } if (event.key === 'Escape') { closeCommandPalette(); closeJobsDrawer(); closeAboutDialog(); } }); const syncFromLocation = () => navigateRoute(routeFromLocation(), { history: 'none' }); window.addEventListener('popstate', syncFromLocation); window.addEventListener('hashchange', syncFromLocation); window.addEventListener('chimera:language-changed', () => { localizeSidebar(); const route = routeById.get(currentRouteId); if (route) updateRouteHeader(route); const input = document.getElementById('chimera-command-input'); if (input && document.getElementById('chimera-command-overlay')?.hidden === false) renderCommandResults(input.value); renderJobs(currentTransferState); if (document.getElementById('chimera-jobs-overlay')?.hidden === false) { window.pork.ecosystemHealthLatest().then(renderActions).catch(() => renderActions(null)); } }); window.pork?.on?.('transfer:update', renderJobs); } mountSidebar(); mountShell(); mountCompanionDock(); mountHomeCommandCenter(); mountSettingsNavigator(); bindEvents(); window.chimeraOpenAbout = openAboutDialog; const compatibleNavigate = page => navigateRoute(contract.legacyAliases[page] || page); navigate = compatibleNavigate; window.navigate = compatibleNavigate; window.chimeraNavigate = navigateRoute; window.chimeraNavigationContract = contract; const initialRoute = routeFromLocation(); const initialGroup = routeById.get(initialRoute)?.group; if (initialGroup && initialGroup !== 'home') expandedGroups.add(initialGroup); requestAnimationFrame(() => navigateRoute(initialRoute, { history: 'replace' })); window.pork?.transferState?.().then(renderJobs).catch(() => {}); window.pork?.ecosystemHealthLatest?.().then(renderActions).catch(() => {}); })();