LYRA Seal Builder — Canonical Mode

Import JSON/TXT • Edit • Validate • Live preview • Export archive
Recovered session available
Seals in archive: 0 Autosave: idle

Seal Schema (inline)

Active
Show/Hide Schema JSON
This schema validates each seal and drives UI hints.

Filters & Import

Parsed: 0
Drag & drop .json/.txt files here
GitHub export (Datasets via repo)

          

Seal Editor

No seal selected
Hover or focus a field to see hints. IDs auto-uppercase.
Each item: { type, url }

JSON Preview

{}
invalid SHA-256:

Notes Preview

Parsed Seals

Count: 0
#IDTitleToneTagsLinkedDateActions

Archive

Cycles: 0 Duplicates: 0
# ID Title Tone Tags Linked Date Actions
LYRA Scroll

LYRA — Canon Scroll

Exported ${new Date().toLocaleString()}
${archive.map(s=>`

${escapeHtml(s.id||'')} — ${escapeHtml(s.title||'')}

${escapeHtml(s.equation||'')}
tone: ${escapeHtml(s.tone||'')} • date: ${escapeHtml(s.date||'')}
${(s.tags||[]).map(t=>`${escapeHtml(t)}`).join('')}
${escapeHtml(s.notes||'')}
`).join('')} `; const w=window.open('about:blank','_blank'); w.document.open(); w.document.write(html); w.document.close(); if(doPrint){ w.focus(); w.print(); } } // ============= Tabs (if any future tabs) ============= // (kept simple; current layout is sectioned panels) // ============= Autosave wiring ============= function toast(msg){ refs.autosaveStatus.textContent=msg; setTimeout(()=>refs.autosaveStatus.textContent='Autosave: idle', 1200); } // ============= Init ============= (function init(){ // theme const savedTheme=localStorage.getItem(LS_THEME)||'lyra'; refs.themePreset.value=savedTheme; applyTheme(savedTheme); // schema refs.schemaText.value=JSON.stringify(DEFAULT_SEAL_SCHEMA,null,2); // LS archive try{ const saved=JSON.parse(localStorage.getItem(LS_ARCHIVE)||'[]'); if(Array.isArray(saved)) archive=saved; }catch{} renderArchive(); updateFiltersFromArchive(); detectCycles(); detectDuplicates(); // recovery option checkRecovery(); // parsed/editor clearEditor(); renderParsed(); // autosave any archive change via proxies on mutators already call archiveChanged(); here add periodic backup as well setInterval(saveBackup, 15000); // toggle rain refs.btnToggleRain.addEventListener('click', ()=>{ rain.running=!rain.running; refs.btnToggleRain.textContent='Matrix: '+(rain.running?'On':'Off'); }); })();