import {parseSources,parseSourceDetails} from './map-parser.js'; import {renderStorage} from './storage-view.js'; import { avatarFor, createSphereMap } from './sphere-map.js'; import { parseIdentityProfile } from './profile-parser.js'; const $ = selector => document.querySelector(selector); const esc = text => String(text).replaceAll('&','&').replaceAll('<','<').replaceAll('>','>').replaceAll('"','"'); const compact = number => new Intl.NumberFormat('en',{notation:'compact',maximumFractionDigits:1}).format(number); const exact = number => number.toLocaleString('en-US'); const profiles = new Map(); const domainFor = key => key.split('.').reverse().join('.'); const label = key => profiles.get(key)?.name || domainFor(key); // Recognition metadata is shared with every visitor in the deploy snapshot. function loadIdentities(items=[]){ for(const item of items){ try{ const profile=parseIdentityProfile(item); const key=profile.handle.toLowerCase().split('.').reverse().join('.'); if(!namespaces.some(ns=>ns.key===key))continue; profiles.set(key,{name:profile.displayName?.trim().slice(0,100)||'',avatar:profile.avatar?.startsWith('https://')?profile.avatar:null,handle:profile.handle}); }catch{/* An invalid cached entry leaves its default sphere intact. */} } } function decorateList(){ $('#list').querySelectorAll('button.row').forEach(button=>{ const key=button.dataset.namespace;const profile=profiles.get(key); if(button.dataset.collection==='false')button.querySelector('.row-label').textContent=label(key); const swatch=button.querySelector('.swatch'); if(profile?.avatar&&!swatch.querySelector('img')){ const img=document.createElement('img');img.src=avatarFor(profile.avatar,30*devicePixelRatio);img.alt='';img.referrerPolicy='no-referrer';img.onerror=()=>{img.remove();profile.avatar=null;};swatch.append(img); } }); } function renderMicrocosm(){ const key=selectedCollection||selectedNamespace; const panel=$('#microcosm');const shortcut=$('#map-ufos');panel.hidden=!key;shortcut.hidden=!key;if(!key){shortcut.removeAttribute('href');return;} const url=new URL('https://ufos.microcosm.blue/collection/'); url.searchParams.set(selectedCollection?'nsid':'prefix',key); const title=selectedCollection?`${label(selectedNamespace)} · ${shortCollection(key)}`:label(key); shortcut.href=url.href;shortcut.setAttribute('aria-label',`Explore ${title} on UFOs (opens a new tab)`); panel.innerHTML=` Take a closer look on UFOs (opens a new tab)
${esc(title)} — explore its activity over time with Microcosm.
`; } function renderSelection(){ const key=selectedNamespace;const ns=namespaces.find(n=>n.key===key);const profile=profiles.get(key); $('#crumb').textContent=label(key); $('#selection').innerHTML=`Choose what you’d like to explore below.
${exact(ns.count)} saved events across ${exact(ns.children.length)} record types.
${esc(key)}
${profile?`Name and avatar from the profile @${esc(profile.handle)}.`:`No profile resolved for ${esc(domainFor(key))}.` } The domain is obtained by reversing the namespace. This is a recognition hint, not proof that one app owns every record type.
Nothing found. Try a name or website address.
'; decorateList(); $('#more').hidden=rows.length<=pageSize; $('#more').textContent=`Show more (${exact(rows.length)} total)`; $('#list').querySelectorAll('button').forEach(button=>button.addEventListener('click',async()=>{if(button.dataset.collection==='true'){const ns=button.dataset.key.split('.').slice(0,2).join('.');if(ns!==selectedNamespace)await chooseNamespace(ns);chooseCollection(button.dataset.key);}else chooseNamespace(button.dataset.key);})); } async function chooseNamespace(key){const request=++selectionRequest;if(!data.collections.length&&data.collectionsUrl){$('#crumb').textContent='Loading source…';detailStatus('Loading source details…');try{await ensureCollections();}catch{if(request===selectionRequest){$('#crumb').textContent='Connection is slow — tap a source to retry';detailStatus('Couldn’t load the details. Try selecting a source again.');}return;}if(request!==selectionRequest)return;detailStatus('');}if(!$('#map-dialog').open)$('#explorer').open=true;selectedNamespace=key;selectedCollection=null;pageSize=14;$('#search').value='';$('#list').hidden=false;renderSelection();graph();renderList();renderMicrocosm();if($('#map-dialog').open)setMapPanel(false);} function chooseCollection(key){ selectedCollection=key;sphereMap.focus(key);renderMicrocosm();$('#map-announcement').textContent='Viewing '+shortCollection(key);if($('#map-dialog').open)setMapPanel(false); const row=data.collections.find(c=>c.nsid===key); $('#explorer').open=true; $('#selection').innerHTML=`Part of ${esc(label(row.ns))}
${exact(row.count)} saved events.
${esc(key)}
Counts come from Strata’s segment summaries of stream.waow.tech. ${hostedSnapshot?'Static preview snapshot. Refreshed on deployment. ':''}Summary updated ${new Date(data.progress.updatedAt).toLocaleString()}; loaded ${new Date(data.fetchedAt).toLocaleString()}. ${exact(data.progress.segments)} of ${exact(data.progress.archiveSegments)} reported sealed segments summarized.
Rows are archived events, not unique people, apps, or current records. Bootstrap observation time is not original publication time. Compaction removes deleted and superseded material; this is not a complete recording of every past value.
The expanded scale uses count^0.32 to make small streams visible. Actual volume uses unmodified entry counts. Colors identify namespaces, not subject categories. Namespaces and record types come directly from the archive summary. For recognition, namespace domains are reversed and looked up in the public Bluesky AppView, following at-me. Names and avatars come from matching profiles; otherwise the domain is shown. This is a profile association, not proof of application ownership. No curated aliases or subject categories are used. Profile associations are cached in a shared snapshot refreshed separately from deployment. Visitors make no profile API requests. Available logos are loaded without a zoom threshold, four canvas images at a time; small spheres use small cached drawing surfaces. Missing profiles retain their colors.
This preview opens no live connections and makes no historical record queries. It is a visual map of saved activity, not a content reader.
${esc(data.status)}Search by name or website, or browse the list.
';graph();renderList();renderMicrocosm();if($('#map-dialog').open)setMapPanel(false);});start(); const mapDialog=$('#map-dialog'); const workspace=$('.workspace'); let ownsFullscreen=false; let explorerWasOpen=false; const mapPanel=$('#map-panel'); const movable=['.toolbar','.camera-controls','#map-note','#microcosm','#explorer'].map(selector=>{const element=$(selector);const marker=document.createComment(selector);element.before(marker);return {element,marker};}); const closeHome=document.createComment('Close button');$('#close-map').before(closeHome); function setMapPanel(open){if(open)$('#explorer').open=true;mapPanel.hidden=!open;$('#map-menu').setAttribute('aria-expanded',String(open));$('#map-menu').textContent=open?'Done':'Controls';if(!open&&mapPanel.contains(document.activeElement))$('#map-menu').focus({preventScroll:true});} $('#map-menu').addEventListener('click',()=>setMapPanel(mapPanel.hidden)); const workspaceHome=document.createComment('Map position'); workspace.before(workspaceHome); function restoreMap(){ if(ownsFullscreen&&document.fullscreenElement)document.exitFullscreen().catch(()=>{}); ownsFullscreen=false; for(const {element,marker} of movable)marker.after(element); closeHome.after($('#close-map'));setMapPanel(false); workspaceHome.after(workspace);document.body.classList.remove('map-open'); $('#expand-map').hidden=false;$('#close-map').hidden=true;$('#explorer').open=explorerWasOpen; $('#expand-map').focus({preventScroll:true}); } $('#expand-map').addEventListener('click',()=>{ explorerWasOpen=$('#explorer').open;mapDialog.append(workspace);for(const {element} of movable)mapPanel.append(element);mapDialog.append($('#close-map'));setMapPanel(false);$('#expand-map').hidden=true;$('#close-map').hidden=false; $('#explorer').open=true;document.body.classList.add('map-open'); const open=()=>{mapDialog.showModal();mapDialog.focus({preventScroll:true});}; if(!document.fullscreenElement&&document.documentElement.requestFullscreen){ document.documentElement.requestFullscreen().then(()=>{ownsFullscreen=true;open();}).catch(open); }else open(); }); $('#close-map').addEventListener('click',()=>mapDialog.close()); mapDialog.addEventListener('close',restoreMap); mapDialog.addEventListener('cancel',event=>{if(!mapPanel.hidden){event.preventDefault();setMapPanel(false);$('#map-menu').focus();}}); document.addEventListener('fullscreenchange',()=>{if(ownsFullscreen&&!document.fullscreenElement&&mapDialog.open)mapDialog.close();}); // Keep the overlay below wrapping navigation, including enlarged text. const navigationObserver=new ResizeObserver(()=>{ const controls=$('#map-menu').getBoundingClientRect(); const back=$('#close-map').getBoundingClientRect(); if(mapDialog.open)mapDialog.style.setProperty('--navigation-bottom',Math.max(controls.bottom,back.bottom)+12+'px'); });navigationObserver.observe($('#map-menu'));navigationObserver.observe($('#close-map')); $('#map-all-sources').addEventListener('click',()=>{$('#home').click();$('#map-menu').focus({preventScroll:true});});