Glisse des briques ici

Depuis les tiroirs Ă  gauche — relie-les avec les poignĂ©es jaunes

đŸ€– Review des propositions Claude
0/0
—
—
— —
—
—
— —
—
Raccourcis : Y appliquer · N ignorer · ←→ naviguer · Esc fermer
📄
—
—
—
`; // 5. TĂ©lĂ©chargement const blob = new Blob([finalHtml], { type: 'text/html;charset=utf-8' }); const url = URL.createObjectURL(blob); const fname = 'SITE_' + (commune.commune.replace(/[^a-zA-Z0-9]/g, '_')) + '_' + Date.now() + '.html'; const a = document.createElement('a'); a.href = url; a.download = fname; document.body.appendChild(a); a.click(); setTimeout(() => { URL.revokeObjectURL(url); a.remove(); }, 1000); // 6. Aussi : ouvrir dans nouvel onglet pour aperçu immĂ©diat const previewWin = window.open('', '_blank'); if (previewWin) { previewWin.document.write(finalHtml); previewWin.document.close(); } toast('✓ Sanctuaire de ' + commune.commune + ' fabriquĂ© · ' + sections.length + ' pierres'); } function escapeHtml(s) { return String(s||'').replace(/[&<>"']/g, c => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])); } async function init() { state.data = await loadData(); if (!state.data.briques.length) { $('#drawers').innerHTML = '
Aucune brique chargée.

Vérifie que data/briques-clean.json ou mock/briques-mock.json existe.
'; return; } restore(); restoreOverrides(); applyOverrides(); renderFilters(); renderDrawers(); renderCanvas(); renderInspector(); updateStatus(); setupCanvasDrop(); // Events $('#search').addEventListener('input', (e) => { state.search = e.target.value; renderDrawers(); }); $('#btn-cmdk').addEventListener('click', openPalette); $('#btn-export').addEventListener('click', exportJSON); $('#btn-export-briques').addEventListener('click', exportOverrides); $('#btn-clear').addEventListener('click', () => { if (state.nodes.length && confirm('Vider le canvas ?')) { state.nodes = []; state.edges = []; state.selectedNode = null; renderCanvas(); renderInspector(); save(); } }); $('#btn-deploy').addEventListener('click', () => toast('🚀 Deploy vers turbos — Ă  cĂąbler quand on dĂ©finit le format cible')); $('#btn-genere').addEventListener('click', genererSiteFinal); // â›Ș Lecture commune depuis URL + bandeau or initCommuneBanner(); // đŸ„‰đŸ„ˆđŸ„‡ Toggle de pack (BASIC/SMART/PLUS/TOUT) document.querySelectorAll('#pack-toggle .pack-btn').forEach(btn => { btn.addEventListener('click', () => { const tier = btn.dataset.tier; if (!tier) return; state.tierFilter = tier; document.querySelectorAll('#pack-toggle .pack-btn').forEach(b => b.classList.remove('active')); btn.classList.add('active'); renderDrawers(); }); }); // 🎹 Toggle palette (Cimple / Sanctuaire / Marianne / Cassini) — persistĂ© localStorage // DĂ©faut au 1er chargement = Sanctuaire (palais bleu marine + or, ambiance institutionnelle) const savedTheme = localStorage.getItem('cimple_forge_theme') || 'sanctuaire'; applyTheme(savedTheme); document.querySelectorAll('#theme-toggle .tt-btn').forEach(btn => { btn.addEventListener('click', () => { const t = btn.dataset.theme; if (!t) return; applyTheme(t); try { localStorage.setItem('cimple_forge_theme', t); } catch(_){} }); }); function applyTheme(t) { document.body.dataset.theme = t; document.querySelectorAll('#theme-toggle .tt-btn').forEach(b => { b.classList.toggle('active', b.dataset.theme === t); }); } window.applyTheme = applyTheme; // Cmd+K document.addEventListener('keydown', (e) => { if ((e.metaKey || e.ctrlKey) && e.key === 'k') { e.preventDefault(); openPalette(); } else if (e.key === 'Escape') { closePalette(); closePeek(); cancelLinkMode(); closeReview(); } else if ($('#review-overlay').classList.contains('open') && !['INPUT','TEXTAREA'].includes(document.activeElement.tagName)) { if (e.key === 'ArrowRight') { e.preventDefault(); review.idx++; renderReviewCurrent(); } else if (e.key === 'ArrowLeft') { e.preventDefault(); prevProposal(); } else if (e.key === 'y' || e.key === 'Y' || e.key === 'Enter') { e.preventDefault(); applyProposal(); } else if (e.key === 'n' || e.key === 'N') { e.preventDefault(); ignoreProposal(); } } else if ($('#palette-overlay').classList.contains('open')) { const items = $('#palette-results')._items || []; if (e.key === 'ArrowDown') { e.preventDefault(); paletteSel = Math.min(paletteSel+1, items.length-1); updatePaletteSel(); } else if (e.key === 'ArrowUp') { e.preventDefault(); paletteSel = Math.max(paletteSel-1, 0); updatePaletteSel(); } else if (e.key === 'Enter') { e.preventDefault(); const r = items[paletteSel]; if (r) { runAction(r); closePalette(); } } } else if (e.key === 'Delete' || e.key === 'Backspace') { // delete selected node if not in input if (state.selectedNode && !['INPUT','TEXTAREA'].includes(document.activeElement.tagName)) { deleteNode(state.selectedNode); } } }); $('#palette-overlay').addEventListener('click', (e) => { if (e.target.id === 'palette-overlay') closePalette(); }); $('#palette-input').addEventListener('input', (e) => renderPalette(e.target.value)); // Peek panel $('#peek-close').addEventListener('click', closePeek); $('#peek-overlay').addEventListener('click', (e) => { if (e.target.id === 'peek-overlay') closePeek(); }); // Review agent $('#btn-review-agent').addEventListener('click', openReview); $('#review-close').addEventListener('click', closeReview); $('#review-overlay').addEventListener('click', (e) => { if (e.target.id === 'review-overlay') closeReview(); }); wireReviewButtons(); $$('#review-filters .rf').forEach(btn => { btn.addEventListener('click', () => { $$('#review-filters .rf').forEach(b => b.classList.remove('active')); btn.classList.add('active'); review.filter = btn.dataset.f; applyFilter(); }); }); console.log('✅ Cimple FORGE ready —', state.data.briques.length, 'briques chargĂ©es'); } init().catch(err => { console.error(err); document.body.innerHTML = `
Erreur init: ${err.message}\n${err.stack||''}
`; }); })();