WEVIA
INTELLIGENCE ARTIFICIELLE COGNITIVE
WEVIA est une IA et peut faire des erreurs. Veuillez vérifier les réponses.
Document
Aucun document à afficher
' + code.replace(/
' + code + '<\/body>';
} else if (type === "html" && code.indexOf("';
}
var w = window.open("", "_blank", "width=900,height=700");
if (w) { w.document.write(content); w.document.close(); }
}
// ─── Voice Input (Speech Recognition) ───
var isRecording = false, recognition = null;
function toggleMic() {
if (isRecording) { stopMic(); return; }
var SpeechRec = window.SpeechRecognition || window.webkitSpeechRecognition;
if (!SpeechRec) {
// Fallback: MediaRecorder → send audio to Whisper/Groq
startMediaRec(); return;
}
recognition = new SpeechRec();
recognition.lang = lang === "darija" ? "ar-MA" : lang === "en" ? "en-US" : lang === "ar" ? "ar-SA" : lang === "es" ? "es-ES" : lang === "de" ? "de-DE" : lang === "zh" ? "zh-CN" : lang === "ja" ? "ja-JP" : lang === "ko" ? "ko-KR" : lang === "it" ? "it-IT" : lang === "pt" ? "pt-BR" : lang === "ru" ? "ru-RU" : lang === "tr" ? "tr-TR" : lang === "hi" ? "hi-IN" : "fr-FR";
recognition.interimResults = true;
recognition.continuous = false;
recognition.maxAlternatives = 1;
var micBtn = document.getElementById("micBtn");
micBtn.style.background = "#ef4444"; micBtn.style.color = "#fff"; micBtn.textContent = "⏹";
isRecording = true;
var finalText = "";
recognition.onresult = function(e) {
var transcript = "";
for (var i = 0; i < e.results.length; i++) {
transcript += e.results[i][0].transcript;
if (e.results[i].isFinal) finalText += e.results[i][0].transcript;
}
document.getElementById("msgInput").value = transcript;
document.getElementById("msgInput").style.height = "auto";
document.getElementById("msgInput").style.height = Math.min(document.getElementById("msgInput").scrollHeight, 120) + "px";
};
recognition.onend = function() {
stopMic();
if (finalText.trim()) { document.getElementById("msgInput").value = finalText; }
};
recognition.onerror = function(e) {
if (e.error === "not-allowed") alert("Autorisez le microphone dans les paramètres du navigateur.");
stopMic();
if (e.error === "no-speech" || e.error === "network") startMediaRec();
};
recognition.start();
}
function stopMic() {
isRecording = false;
var micBtn = document.getElementById("micBtn");
micBtn.style.background = "var(--bg)"; micBtn.style.color = "var(--tx)"; micBtn.textContent = "🎤";
if (recognition) { try { recognition.stop(); } catch(e) {} recognition = null; }
if (mediaRec && mediaRec.state === "recording") mediaRec.stop();
}
// Fallback: MediaRecorder for browsers without SpeechRecognition
var mediaRec = null;
function startMediaRec() {
if (!navigator.mediaDevices) { alert("Microphone non disponible"); return; }
navigator.mediaDevices.getUserMedia({audio: true}).then(function(stream) {
var chunks = [];
mediaRec = new MediaRecorder(stream, {mimeType: MediaRecorder.isTypeSupported("audio/webm") ? "audio/webm" : "audio/mp4"});
mediaRec.ondataavailable = function(e) { if (e.data.size > 0) chunks.push(e.data); };
mediaRec.onstop = function() {
stream.getTracks().forEach(function(t) { t.stop(); });
var blob = new Blob(chunks, {type: mediaRec.mimeType});
var reader = new FileReader();
reader.onload = function(ev) {
var base64 = ev.target.result.split(",")[1];
pendingFile = {name: "voice.webm", type: mediaRec.mimeType, base64: base64, size: blob.size};
document.getElementById("fileName").textContent = "🎤 Message vocal (" + (blob.size/1024).toFixed(0) + " Ko)";
document.getElementById("filePreview").style.display = "flex";
document.getElementById("msgInput").value = "Transcris et réponds à ce message vocal";
document.getElementById("msgInput").focus();
};
reader.readAsDataURL(blob);
stopMic();
};
mediaRec.start();
var micBtn = document.getElementById("micBtn");
micBtn.style.background = "#ef4444"; micBtn.style.color = "#fff"; micBtn.textContent = "⏹";
isRecording = true;
}).catch(function() { alert("Microphone non disponible. Vérifiez les permissions."); });
}
// ─── File Upload ───
var pendingFile = null;
function handleFile(input) {
if (!input.files || !input.files[0]) return;
var file = input.files[0];
var reader = new FileReader();
reader.onload = function(e) {
var base64 = e.target.result.split(",")[1];
pendingFile = { name: file.name, type: file.type, base64: base64, size: file.size };
// Show preview bar
var bar = document.getElementById("filePreviewBar");
var fpIcon = document.getElementById("fpIcon");
var fpName = document.getElementById("fpName");
var fpSize = document.getElementById("fpSize");
var fpThumb = document.getElementById("fpThumb");
if (bar) {
bar.classList.add("visible");
fpName.textContent = file.name;
fpSize.textContent = (file.size / 1024).toFixed(0) + " KB";
if (file.type.startsWith("image/")) {
fpIcon.style.display = "none";
fpThumb.style.display = "block";
fpThumb.src = e.target.result;
} else {
fpIcon.style.display = "";
fpIcon.textContent = file.type.includes("pdf") ? "📄" : "📎";
fpThumb.style.display = "none";
}
}
document.getElementById("msgInput").focus();
};
reader.readAsDataURL(file);
}
function clearFile() {
pendingFile = null;
document.getElementById("fileInput").value = "";
var bar = document.getElementById("filePreviewBar");
if (bar) bar.classList.remove("visible");
var fpThumb = document.getElementById("fpThumb");
if (fpThumb) { fpThumb.style.display = "none"; fpThumb.src = ""; }
var old = document.getElementById("filePreview");
if (old) old.style.display = "none";
}
// ─── Drag & Drop (fullscreen-style) ───
var dropOverlay = document.getElementById("dropOverlay");
var dragCounter = 0;
document.addEventListener("dragenter", function(e) { e.preventDefault(); dragCounter++; if(dropOverlay) dropOverlay.classList.add("visible"); });
document.addEventListener("dragleave", function(e) { e.preventDefault(); dragCounter--; if(dragCounter <= 0) { if(dropOverlay) dropOverlay.classList.remove("visible"); dragCounter = 0; } });
document.addEventListener("dragover", function(e) { e.preventDefault(); });
document.addEventListener("drop", function(e) {
e.preventDefault(); dragCounter = 0; if(dropOverlay) dropOverlay.classList.remove("visible");
if (e.dataTransfer.files.length) {
document.getElementById("fileInput").files = e.dataTransfer.files;
handleFile(document.getElementById("fileInput"));
}
});
// ─── Paste images ───
document.addEventListener("paste", function(e) {
var items = Array.from((e.clipboardData || {}).items || []);
items.forEach(function(item) {
if (item.type.startsWith("image")) {
var file = item.getAsFile();
if (file) {
var dt = new DataTransfer(); dt.items.add(file);
document.getElementById("fileInput").files = dt.files;
handleFile(document.getElementById("fileInput"));
}
}
});
});
// ─── Auto-resize textarea ───
document.getElementById('msgInput').addEventListener('input', function() {
this.style.height = 'auto';
this.style.height = Math.min(this.scrollHeight, 120) + 'px';
});
// ═══ SIDEBAR ═══
function toggleSidebar() {
var sb = document.getElementById('sidebar');
sb.classList.toggle('collapsed');
localStorage.setItem('sb_collapsed', sb.classList.contains('collapsed'));
}
function newChat() {
session = 'web_' + Date.now().toString(36);
localStorage.setItem('wevia_session', session);
convId = null; chatHistory = [];
document.getElementById('messages').innerHTML = '';
document.querySelectorAll('.sb-item.active').forEach(function(el) { el.classList.remove('active'); });
}
function loadConversations() {
fetch('/api/sovereign/v1/chat/completions', {
method: 'POST', headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ action: 'list_conversations', session: localStorage.getItem('wevia_session') || session })
}).then(function(r) { return r.json(); }).then(function(data) {
var list = document.getElementById('sbList');
var convs = data.conversations || [];
if (!convs.length) { list.innerHTML = '';
} else {
msgs.innerHTML += '';
}
});
msgs.scrollTop = msgs.scrollHeight;
document.querySelectorAll('.sb-item').forEach(function(el) {
el.classList.toggle('active', el.getAttribute('data-id') == cid);
});
});
}
function filterConvs(q) {
q = q.toLowerCase();
document.querySelectorAll('.sb-item').forEach(function(el) {
el.style.display = !q || (el.getAttribute('data-title')||'').includes(q) ? '' : 'none';
});
}
function sbTimeAgo(dt) {
if (!dt) return '';
var diff = (Date.now() - new Date(dt).getTime()) / 1000;
if (diff < 60) return "maintenant";
if (diff < 3600) return Math.floor(diff/60) + ' min';
if (diff < 86400) return Math.floor(diff/3600) + 'h';
if (diff < 604800) return Math.floor(diff/86400) + 'j';
return new Date(dt).toLocaleDateString('fr-FR', {day:'numeric',month:'short'});
}
// Auto-init
(function() {
if (localStorage.getItem('sb_collapsed') === 'true') {
var sb = document.getElementById('sidebar');
if (sb) sb.classList.add('collapsed');
}
setTimeout(loadConversations, 500);
})();
// ═══ RLHF ═══
function sendFeedback(btn, rating, idx) {
btn.parentElement.querySelectorAll('.fb-btn').forEach(function(b) { b.classList.add('voted'); });
btn.classList.add(rating);
var msgs = document.querySelectorAll('.msg');
var q='', r='';
for (var i=msgs.length-1; i>=0; i--) {
if (msgs[i].classList.contains('assistant') && !r) { var b=msgs[i].querySelector('.bubble-ai')||msgs[i].querySelector('.bubble'); r=b?b.textContent.substring(0,500):''; }
if (msgs[i].classList.contains('user') && !q) { var b2=msgs[i].querySelector('.bubble'); q=b2?b2.textContent.substring(0,200):''; }
if (q && r) break;
}
fetch('/api/sovereign/v1/chat/completions', { method:'POST', headers:{'Content-Type':'application/json'},
body: JSON.stringify({action:'feedback', rating: rating==='up'?1:-1, message_id:convId, question:q, answer:r, session:session, provider:''})
}).catch(function(){});
}
// ===== BANANA VISUAL ENGINE v3.0 =====
// Nano Banana 2 (Photo) + Veo (Video) + Banana Edit
window.BananaEngine = {
_active: false,
providers: {
photo: { name: 'Nano Banana 2', endpoint: '/wevia-ia/wevia-image.php', badge: '🍌 Banana Photo' },
video: { name: 'Veo Engine', endpoint: '/wevia-ia/wevia-image.php', badge: '🎬 Veo Video' },
edit: { name: 'Banana Edit', endpoint: '/wevia-ia/wevia-image.php', badge: '✏️ Banana Edit' }
},
detect: function(text) {
var t = text.toLowerCase();
if(/vid[eé]o|animation|anim[eé]|clip|motion|cinematic/i.test(t)) return 'video';
if(/modifi|change|retouche|edit|ajout.*sur|remplace/i.test(t)) return 'edit';
if(/photo|image|portrait|illustration|dessin|logo|affiche|poster|g[eé]n[eé]r.*image|cr[eé].*image|fais.*image|montre.*moi/i.test(t)) return 'photo';
return null;
},
render: function(type, prompt, container) {
var prov = this.providers[type];
// Show studio overlay
container.innerHTML = 'WEVAL Technology Platform
Aucune discussion
'; return; }
list.innerHTML = '';
convs.forEach(function(cv) {
var d = document.createElement('div');
d.className = 'sb-item' + (convId == cv.id ? ' active' : '');
d.setAttribute('data-id', cv.id);
d.setAttribute('data-title', (cv.title || '').toLowerCase());
var ago = sbTimeAgo(cv.created_at);
d.innerHTML = (cv.title || 'Discussion') + '' + ago + '';
d.onclick = function() { openConv(cv.id); };
list.appendChild(d);
});
}).catch(function() {
document.getElementById('sbList').innerHTML = 'Erreur chargement
';
});
}
function openConv(cid) {
fetch('/api/sovereign/v1/chat/completions', {
method: 'POST', headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ action: 'get_conversation', conversation_id: cid })
}).then(function(r) { return r.json(); }).then(function(data) {
convId = cid; chatHistory = [];
var msgs = document.getElementById('messages');
msgs.innerHTML = '';
(data.messages || []).forEach(function(m) {
chatHistory.push({role: m.role, content: m.content});
if (m.role === 'user') {
msgs.innerHTML += '' + (m.content||'').replace(//g,'>') + '
' + formatMd(m.content) + '
' +
'' +
'
';
// Animate progress
var bar = container.querySelector('.banana-progress-bar');
var progress = 15;
var timer = setInterval(function(){ progress = Math.min(progress + Math.random()*8, 90); bar.style.width = progress+'%'; }, 300);
// Call API
var formData = new FormData();
formData.append('prompt', prompt);
formData.append('type', type);
formData.append('quality', 'ultra');
formData.append('session', window.session || '');
// Client-side generation via Pollinations (free, no server needed)
if(type === 'photo' || type === 'edit') {
var enriched = prompt + ', photorealistic, 8k, highly detailed, professional lighting';
var imgUrl = '/wevia-ia/wevia-image.php?prompt=' + encodeURIComponent(enriched);
var img = new Image();
img.onload = function() {
clearInterval(timer);
bar.style.width = '100%';
setTimeout(function(){
var typeBadge = '' + prov.badge + '';
container.innerHTML = '';
}, 400);
};
img._retries = 0; img.onerror = function() { if(this._retries < 4) { this._retries++; var self=this; setTimeout(function(){ self.src = imgUrl + '&r=' + Date.now(); }, 5000); return; }
clearInterval(timer);
container.innerHTML = '' +
'' + prov.badge + '' +
'
Génération en cours...
' + '' +
'
⚠️ Génération en cours, réessayez dans quelques secondes...
';
};
img.src = imgUrl;
return Promise.resolve();
}
// Fallback to server for video
return fetch(prov.endpoint, { method: 'POST', body: formData })
.then(function(r){ return r.json(); })
.then(function(data){
clearInterval(timer);
bar.style.width = '100%';
setTimeout(function(){
if(data.url || data.image_url) {
var url = data.url || data.image_url;
var typeBadge = '' + prov.badge + '';
if(type === 'video') {
container.innerHTML = '' + typeBadge + '
';
} else {
container.innerHTML = '';
}
} else if(data.error) {
container.innerHTML = '⚠️ ' + data.error + '
';
}
}, 500);
})
.catch(function(err){
clearInterval(timer);
container.innerHTML = '⚠️ Erreur réseau: ' + err.message + '
';
});
}
};
// ===== GRAPH-MASTER ENGINE =====
(function(){
// Init Mermaid
if(window.mermaid) {
mermaid.initialize({ startOnLoad:false, theme:'dark', themeVariables:{ primaryColor:'#6366f1', primaryTextColor:'#fff', primaryBorderColor:'#818cf8', lineColor:'#6b7280', secondaryColor:'#1e293b', tertiaryColor:'#faf7f5' }});
}
// Detect and render graphs in chatbot responses
window.renderGraphs = function(container) {
if(!container) return;
// If backend PNG exists, just hide raw code blocks
var hasPNG = container.querySelector('img[src*="merm_"]');
if(hasPNG) {
container.querySelectorAll('code.language-mermaid, pre code').forEach(function(b) {
var code = b.textContent.trim();
if(code.match(/^(graph|flowchart|sequence|gantt|pie)/)) {
var pre = b.closest('pre') || b; pre.style.display = 'none';
}
});
hasPNG.classList.add('organic-reveal');
return;
}
// No PNG — try client-side mermaid render with error handling
var blocks = container.querySelectorAll('code.language-mermaid, pre code');
blocks.forEach(function(block) {
var code = block.textContent.trim();
if(code.match(/^(graph|flowchart|sequence|gantt|pie|class|state|er|journey|mind|git)/)) {
var wrap = document.createElement('div');
wrap.className = 'wevia-graph';
wrap.innerHTML = 'Graph-Master' + code + '
';
var pre = block.closest('pre') || block;
pre.parentNode.replaceChild(wrap, pre);
if(window.mermaid) {
try {
mermaid.run({nodes: wrap.querySelectorAll('.mermaid')}).catch(function(e) {
var md = wrap.querySelector('.mermaid');
if(md) md.innerHTML = 'Le diagramme sera disponible sous forme d image ci-dessous.
';
});
} catch(e) {
var md = wrap.querySelector('.mermaid');
if(md) md.innerHTML = 'Diagramme en cours de traitement...
';
}
}
}
});
// 2. SVG detection (Ishikawa, custom)
var svgBlocks = container.querySelectorAll('code.language-svg');
svgBlocks.forEach(function(block) {
var wrap = document.createElement('div');
wrap.className = 'wevia-graph';
wrap.innerHTML = '🎨 SVG Render' + block.textContent;
var pre = block.closest('pre') || block;
pre.parentNode.replaceChild(wrap, pre);
});
};
// Graph hooks moved to unified post-processor
})();
// Auto-trigger Banana for image-related responses
// Banana hooks removed (unified)
// EXPORT PRO - Download conversation as formatted document
window.exportChat = function(format) {
var msgs = document.querySelectorAll('.msg');
var content = [];
msgs.forEach(function(m) {
var bubble = m.querySelector('.bubble-ai,.bubble');
if(bubble) content.push(bubble.innerText || bubble.textContent);
});
var text = content.join('\n\n---\n\n');
if(format === 'txt') {
var blob = new Blob([text], {type:'text/plain'});
var a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = 'WEVIA_Export_' + new Date().toISOString().slice(0,10) + '.txt';
a.click();
} else if(format === 'md') {
var md = '# WEVIA Export\n\n' + text;
var blob = new Blob([md], {type:'text/markdown'});
var a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = 'WEVIA_Export_' + new Date().toISOString().slice(0,10) + '.md';
a.click();
} else if(format === 'html') {
var html = '🧠 WEVIA Export
' + new Date().toLocaleString() + '
'; content.forEach(function(c){ html += '' + c.replace(/\n/g,'
') + '
'; });
html += '<\/body>';
var blob = new Blob([html], {type:'text/html'});
var a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = 'WEVIA_Export_' + new Date().toISOString().slice(0,10) + '.html';
a.click();
}
};
// ===== UNIFIED POST-PROCESSOR (Graph + Banana) =====
(function(){
var _realAddMsg = window.addMsg;
if(!_realAddMsg) return;
window.addMsg = function(role, text, time) {
var el = _realAddMsg.call(this, role, text, time);
if(role === 'assistant' && el && text) {
// Graph-Master rendering
if(window.renderGraphs) setTimeout(function(){ renderGraphs(el); }, 150);
// Banana auto-trigger
var bm = text.match(/\[BANANA:(photo|video|edit)\](.+?)\[\/BANANA\]/);
if(bm && window.BananaEngine) {
var imgDiv = document.createElement('div');
imgDiv.style.margin = '12px 0';
var bubble = el.querySelector('.bubble-ai,.bubble,.msg-inner');
if(bubble) { bubble.appendChild(imgDiv); BananaEngine.render(bm[1], bm[2], imgDiv); }
}
}
return el;
};
})();
// ===== KEYBOARD SHORTCUTS =====
document.addEventListener('keydown', function(e) {
var input = document.getElementById('msgInput');
// Ctrl+Enter = send
if(e.ctrlKey && e.key === 'Enter' && document.activeElement === input) {
e.preventDefault();
document.getElementById('sendBtn').click();
}
// Escape = stop TTS + clear input
if(e.key === 'Escape') {
if(window._ttsAudio) { try{window._ttsAudio.pause();}catch(x){} window._ttsAudio=null; }
if(window.speechSynthesis) window.speechSynthesis.cancel();
}
// Ctrl+Shift+D = toggle dark mode
if(e.ctrlKey && e.shiftKey && e.key === 'D') { e.preventDefault(); toggleTheme(); }
});
function useSuggestion(btn) {
var text = btn.textContent.replace(/^[^\s]+\s/, ''); // Remove emoji prefix
document.getElementById('msgInput').value = text;
document.getElementById('msgInput').focus();
document.getElementById('suggestedPrompts').style.display = 'none';
}
/* === UX: Follow-up chips - DYNAMIC per response === */
function generateFollowups(query, response) {
var chips = [];
var q = (query || '').toLowerCase();
var r = (response || '').substring(0, 2000).toLowerCase();
var qOrig = (query || '');
// Extract topic from user query (remove stopwords)
var stopwords = 'le la les de du des un une et ou en est que qui pour sur avec dans ce cette son mon pas plus tout tres bien comment quoi quel quelle peux tu me moi nous faire fait donne explique genere genre cree montre schema diagramme image photo fais'.split(' ');
var words = qOrig.split(/\s+/).filter(function(w){return w.length>2 && stopwords.indexOf(w.toLowerCase())===-1});
var topic = words.slice(0,3).join(' ') || 'ce sujet';
var shortTopic = words.slice(0,2).join(' ') || 'ce sujet';
// Detect response type
var hasImage = /img_|downloads\/img|image.genere|\!\[Image/.test(response||'');
var hasViz = /viz_|iframe|interactif|Interactive/.test(response||'');
var hasMermaid = /downloads\/merm_|mermaid\.ink|diagramme|flowchart/.test(response||'');
var hasCode = false;
var rawR = (response||'').substring(0,3000);
// Only count as "code" if there's a code block that's NOT mermaid or svg
var codeBlocks = rawR.match(/```(\w*)/g) || [];
for (var ci = 0; ci < codeBlocks.length; ci++) {
var cLang = codeBlocks[ci].replace('```','').toLowerCase();
if (cLang !== 'mermaid' && cLang !== 'svg' && cLang !== '') hasCode = true;
}
// Also check for inline code patterns (not just blocks)
if (!hasCode && /def |function |class |import |require|console\.log|echo |SELECT |INSERT /.test(rawR)) hasCode = true;
var hasTable = /\|.*\|.*\|/.test(response||'');
var hasList = (response||'').split('\n').filter(function(l){return /^\s*[-\*\d]/.test(l)}).length > 3;
// Dynamic chips based on WHAT was generated + WHAT was asked
if (hasViz) {
chips = [
'Exporter en PDF haute qualit\u00e9',
'Version anim\u00e9e avec transitions',
'Adapter pour pr\u00e9sentation PPTX'
];
} else if (hasImage) {
chips = [
'Régénérer dans un autre style',
'Ajouter du texte sur cette image',
'Version en haute résolution'
];
} else if (hasMermaid) {
chips = [
'Détailler ce schéma en sous-systèmes',
'Ajouter les métriques et KPIs',
'Exporter ce schéma en PDF'
];
} else if (hasCode && /python|php|java|node|react/.test(r)) {
var lang = 'ce code';
if (/python/.test(r)) lang = 'ce script Python';
else if (/php/.test(r)) lang = 'ce code PHP';
else if (/javascript|node|react/.test(r)) lang = 'ce code JS';
chips = [
'Optimiser ' + lang,
'Ajouter les tests unitaires',
'Documenter chaque fonction'
];
} else if (hasCode) {
chips = [
'Expliquer ce code pas \u00e0 pas',
'Am\u00e9liorer les performances',
''
];
} else if (/sap|s\/4|hana|fiori|vistex/.test(r)) {
chips = [
'ROI concret de ' + shortTopic,
'Planning de migration detaille',
'Risques et att\u00e9nuations'
];
} else if (/pharma|medicament|clinical|gmp|bpf/.test(r)) {
chips = [
'R\u00e9glementation applicable \u00e0 ' + shortTopic,
'Cas concret en industrie pharma',
'Impact sur la supply chain'
];
} else if (/marketing|email|campagne|conversion/.test(r)) {
chips = [
'Optimiser le taux de conversion',
'Strat\u00e9gie A/B test pour ' + shortTopic,
'Benchmark du secteur'
];
} else if (/security|owasp|vuln|audit|pentest/.test(r)) {
chips = [
'Plan de rem\u00e9diation prioritis\u00e9',
'Checklist conformit\u00e9 ' + shortTopic,
'Estimation du risque r\u00e9siduel'
];
} else if (/cloud|aws|azure|kubernetes|docker/.test(r)) {
chips = [
'Estimation des co\u00fbts ' + shortTopic,
'Architecture haute disponibilit\u00e9',
'Comparatif des alternatives'
];
} else if (/financ|budget|bilan|marge|investis|cout/.test(r)) {
chips = [
'Projection sur 3 ans',
'Analyse de sensibilit\u00e9',
'Tableau comparatif chiffr\u00e9'
];
} else if (/strateg|swot|pestel|business|canvas/.test(r)) {
chips = [
'Analyse SWOT de ' + shortTopic,
'Quick wins immediats',
'Feuille de route \u00e0 6 mois'
];
} else if (hasTable) {
chips = [
'Analyse les tendances',
'Ajoute des recommandations',
'Exporte en format Excel'
];
} else if (hasList) {
chips = [
'D\u00e9tailler le point cl\u00e9',
'Comparer ces \u00e9l\u00e9ments',
'Prioriser par impact'
];
} else {
// Dynamic fallback based on actual query
chips = [
'Approfondir ' + shortTopic,
'Exemple concret pour ' + topic,
'Comparer avec des alternatives'
];
}
// Create chips HTML
var container = document.createElement('div');
container.className = 'followup-chips';
chips.forEach(function(c) {
var btn = document.createElement('button');
btn.className = 'followup-chip';
btn.textContent = c;
btn.onclick = function() {
document.getElementById('msgInput').value = c;
sendMsg();
container.remove();
};
container.appendChild(btn);
});
document.getElementById('messages').appendChild(container);
var m = document.getElementById('messages');
m.scrollTo({top: m.scrollHeight, behavior: 'smooth'});
}
/* === UX: Smart thinking steps based on query === */
function addSmartThinkSteps(query) {
var q = (query || '').toLowerCase();
var steps = [];
if (q.includes('image') || q.includes('photo') || q.includes('dessine') || q.includes('génère')) {
steps = [{t:500,m:'🎨 Activation du moteur visuel...'},{t:1500,m:'🖼️ Composition de l\'image...'},{t:3000,m:'✨ Finalisation du rendu...'}];
} else if (q.includes('code') || q.includes('script') || q.includes('python') || q.includes('php')) {
steps = [{t:400,m:'💻 Analyse du contexte technique...'},{t:1200,m:'🔧 Génération du code...'},{t:2500,m:'✅ Vérification syntaxique...'}];
} else if (q.includes('schéma') || q.includes('diagram') || q.includes('ishikawa') || q.includes('mermaid')) {
steps = [{t:400,m:'📊 Initialisation Graph-Master...'},{t:1500,m:'🔗 Construction des relations...'},{t:2800,m:'🎨 Rendu visuel...'}];
} else if (q.includes('audit') || q.includes('sécurité') || q.includes('owasp')) {
steps = [{t:400,m:'🛡️ Scan de sécurité lancé...'},{t:1500,m:'🔍 Analyse des vulnérabilités...'},{t:3000,m:'📋 Compilation du rapport...'}];
} else if (q.includes('analyse') || q.includes('compare') || q.includes('recherche')) {
steps = [{t:400,m:'📚 Consultation de la base de connaissances...'},{t:1500,m:'🌐 Recherche web enrichie...'},{t:2800,m:'🧠 Synthèse des sources...'}];
} else {
steps = [{t:500,m:'🧠 Analyse de votre demande...'},{t:1500,m:'📚 Recherche dans la KB...'},{t:2800,m:'✍️ Rédaction de la réponse...'}];
}
window._thinkTimers = [];
steps.forEach(function(s) {
var timer = setTimeout(function() {
var body = document.getElementById('thinkBody');
if (body) {
var step = document.createElement('div');
step.className = 'think-step';
step.style.cssText = 'padding:3px 0;font-size:12px;color:var(--tx2);opacity:0;transition:opacity .3s;';
step.textContent = s.m;
body.appendChild(step);
setTimeout(function(){ step.style.opacity = '1'; }, 50);
}
}, s.t);
window._thinkTimers.push(timer);
});
}
') + '