${escapeHtml(location.label)}
${details.map(escapeHtml).join(' · ')}
` : ''}(function initTitleWorkspace(root, factory) { const api = factory(); if (typeof module === 'object' && module.exports) module.exports = api; if (root) root.chimeraTitleWorkspace = api; })(typeof window !== 'undefined' ? window : globalThis, function createTitleWorkspace() { 'use strict'; const array = value => Array.isArray(value) ? value : []; const text = value => value == null || value === '' ? null : String(value); const first = (...values) => values.map(text).find(Boolean) || null; const lower = value => String(value || '').trim().toLowerCase(); const missingStates = new Set(['missing', 'unavailable', 'disconnected', 'offline', 'not_mounted']); function deviceState(item) { return first( item && item.deviceAvailabilityState, item && item.availabilityState, item && item.device && item.device.availabilityState, item && item.storageDevice && item.storageDevice.availabilityState, item && item.volume && item.volume.device && item.volume.device.availabilityState ); } function locationLabel(item, fallback) { return first( item && item.volume && item.volume.label, item && item.volume && item.volume.name, item && item.volumeLabel, item && item.device && item.device.label, item && item.storageDevice && item.storageDevice.label, item && item.console && item.console.name, item && item.consoleName, item && item.path, fallback ); } function isConfirmedInstall(install) { const state = lower(first(install && install.presenceState, install && install.state, install && install.installState)); return state === 'present' || state === 'installed' || state === 'confirmed'; } function isMissing(item) { return missingStates.has(lower(deviceState(item))); } function collectActivity(title, locations) { const entries = []; const add = (kind, value, label) => { if (!value) return; const timestamp = new Date(value); if (Number.isNaN(timestamp.getTime())) return; entries.push({ kind, label, timestamp: timestamp.toISOString() }); }; add('title', title.updatedAt || title.updated_at, 'Title metadata updated'); add('title', title.createdAt || title.created_at, 'Title first recorded'); locations.forEach(location => { add(location.kind, location.raw.lastSeenAt || location.raw.last_seen_at, `${location.label} last seen`); add(location.kind, location.raw.verifiedAt || location.raw.verified_at, `${location.label} verified`); add(location.kind, location.raw.detectedAt || location.raw.detected_at, `${location.label} detected`); }); array(title.media).forEach(item => add('media', item.importedAt || item.provenance?.importedAt, `Imported ${item.kind || 'media'}: ${item.originalName || item.name || 'asset'}`)); return entries.sort((a, b) => b.timestamp.localeCompare(a.timestamp)); } function project(title = {}) { const localCopies = array(title.localCopies); const consoleInstalls = array(title.consoleInstalls); const packages = array(title.packages); const saves = array(title.saves); const trophies = array(title.trophies); const media = array(title.media); const locations = [ ...localCopies.map((raw, index) => ({ kind: 'local-copy', label: locationLabel(raw, `Local copy ${index + 1}`), state: deviceState(raw) || 'unknown', version: first(raw.version && raw.version.value, raw.version, raw.appVersion), format: first(raw.format, raw.copyType, raw.type), path: first(raw.path, raw.relativePath), missing: isMissing(raw), raw })), ...consoleInstalls.map((raw, index) => ({ kind: 'console-install', label: locationLabel(raw, `Console install ${index + 1}`), state: first(raw.presenceState, raw.state, raw.installState, 'unknown'), version: first(raw.version && raw.version.value, raw.version, raw.appVersion), format: first(raw.format, raw.packageType), path: first(raw.path, raw.installPath), missing: isMissing(raw), confirmed: isConfirmedInstall(raw), raw })) ]; const missingDrive = Number(title.availability && title.availability.missingDeviceCount || 0) > 0 || locations.some(location => location.missing); const installed = consoleInstalls.some(isConfirmedInstall) || Number(title.availability && title.availability.confirmedInstallCount || 0) > 0; const protectionState = lower(first(title.protection && title.protection.state, title.protection && title.protection.status)); const protectedCopy = ['protected', 'healthy', 'verified', 'complete'].includes(protectionState) || Number(title.protection && title.protection.protectedCopyCount || 0) > 0; const badges = []; if (installed) badges.push({ code: 'installed', tone: 'positive' }); if (localCopies.length) badges.push({ code: 'local-copy', tone: 'info' }); if (missingDrive) badges.push({ code: 'missing-drive', tone: 'warning' }); if (protectedCopy) badges.push({ code: 'protected', tone: 'positive' }); if ((installed || localCopies.length) && !protectedCopy) badges.push({ code: 'needs-protection', tone: 'danger' }); if (!locations.length) badges.push({ code: 'metadata-only', tone: 'neutral' }); return Object.freeze({ title, badges, locations, localCopies, consoleInstalls, packages, saves, trophies, media, missingDrive, installed, protectedCopy, activity: collectActivity(title, locations) }); } function escapeHtml(value) { return String(value == null ? '' : value) .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } function tr(key, fallback) { if (typeof window === 'undefined' || typeof window.t !== 'function') return fallback; const translated = window.t(key); return translated && translated !== key ? translated : fallback; } function setCount(id, count) { const node = document.getElementById(id); if (!node) return; node.textContent = count ? String(count) : ''; node.hidden = !count; } function emptyState(key, fallback, action) { return `
${escapeHtml(tr(key, fallback))}
${action || ''}${details.map(escapeHtml).join(' · ')}
` : ''}