Docfile commited on
Commit
f2ed8a0
·
verified ·
1 Parent(s): 2ece82c

Update templates/maj.html

Browse files
Files changed (1) hide show
  1. templates/maj.html +125 -57
templates/maj.html CHANGED
@@ -1,4 +1,4 @@
1
- <!DOCTYPE html>
2
  <html lang="fr">
3
  <head>
4
  <meta charset="UTF-8">
@@ -29,6 +29,7 @@
29
  };
30
  </script>
31
  <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" id="MathJax-script" async></script>
 
32
  <script src="https://cdn.jsdelivr.net/npm/marked/lib/marked.umd.min.js"></script>
33
 
34
  <style>
@@ -77,14 +78,14 @@
77
  overflow: hidden;
78
  }
79
  .thought-box.open {
80
- max-height: 500px;
81
  }
82
 
83
  #thoughtsContent, #answerContent {
84
  max-height: 500px;
85
  overflow-y: auto;
86
  scroll-behavior: smooth;
87
- white-space: pre-wrap;
88
  }
89
 
90
  .preview-image {
@@ -99,10 +100,12 @@
99
  margin-left: 8px;
100
  }
101
 
 
102
  table {
103
  border-collapse: collapse;
104
  width: 100%;
105
  margin-bottom: 1rem;
 
106
  }
107
  th, td {
108
  border: 1px solid #d1d5db;
@@ -134,7 +137,7 @@
134
  <header class="p-6 text-center mb-8">
135
  <h1 class="text-4xl font-bold text-blue-600">Mariam - M-0</h1>
136
  <p class="text-gray-600">Solution Mathématique/Physique/Chimie Intelligente</p>
137
- <p class="performance-warning">
138
  Vous utilisez actuellement les modèles/performances moyens. Accédez à des performances supérieures avec un abonnement premium !
139
  </p>
140
  </header>
@@ -228,7 +231,8 @@
228
  const stopTimer = () => {
229
  clearInterval(timerInterval);
230
  startTime = null;
231
- timestamp.textContent = '';
 
232
  };
233
 
234
  const handleFileSelect = file => {
@@ -262,32 +266,65 @@
262
  handleFileSelect(e.dataTransfer.files[0]);
263
  });
264
 
265
- const typesetAnswerIfReady = async () => {
266
- if (window.mathJaxReady) {
267
- MathJax.startup.document.elements = [document.getElementById('answerContent')];
268
- await MathJax.typesetPromise();
269
- answerContent.scrollTop = answerContent.scrollHeight;
 
 
 
 
 
 
 
 
 
 
 
 
 
270
  } else {
271
- setTimeout(typesetAnswerIfReady, 200);
 
272
  }
273
  };
274
 
 
275
  const updateDisplay = async () => {
276
- thoughtsContent.innerHTML = marked.parse(thoughtsBuffer);
277
- answerContent.innerHTML = marked.parse(answerBuffer);
278
- await typesetAnswerIfReady();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
279
  updateTimeout = null;
280
  };
281
 
282
  const scheduleUpdate = () => {
283
  if (updateTimeout) return;
284
- updateTimeout = setTimeout(updateDisplay, 200);
 
285
  };
286
 
287
- marked.setOptions({
288
- gfm: true,
289
- breaks: true
290
- });
 
 
 
291
 
292
  form.addEventListener('submit', async e => {
293
  e.preventDefault();
@@ -305,7 +342,7 @@
305
  thoughtsBuffer = '';
306
  answerBuffer = '';
307
  currentMode = null;
308
- thoughtsBox.classList.add('open');
309
 
310
  const formData = new FormData();
311
  formData.append('image', file);
@@ -316,58 +353,89 @@
316
  body: formData
317
  });
318
 
 
 
 
 
 
 
 
319
  const reader = response.body.getReader();
320
  const decoder = new TextDecoder();
321
  let buffer = '';
 
322
 
323
- const processChunk = async chunk => {
324
- buffer += decoder.decode(chunk, { stream: true });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
  const lines = buffer.split('\n\n');
326
- buffer = lines.pop();
327
 
328
  for (const line of lines) {
329
  if (!line.startsWith('data:')) continue;
330
- const data = JSON.parse(line.slice(5));
331
-
332
- if (data.mode) {
333
- currentMode = data.mode;
334
- loader.classList.add('hidden');
335
- solutionSection.classList.remove('hidden');
336
- }
337
- if (data.content) {
338
- if (currentMode === 'thinking') {
339
- thoughtsBuffer += data.content;
340
- } else if (currentMode === 'answering') {
341
- answerBuffer += data.content;
342
- }
 
 
 
 
 
 
 
 
 
 
 
343
  }
344
  }
345
- scheduleUpdate();
346
  };
347
 
348
- while (true) {
349
- const { done, value } = await reader.read();
350
- if (done) {
351
- if (buffer) {
352
- const data = JSON.parse(buffer.slice(5));
353
- if (data.content) {
354
- if (currentMode === 'thinking') {
355
- thoughtsBuffer += data.content;
356
- } else if (currentMode === 'answering') {
357
- answerBuffer += data.content;
358
- }
359
- }
360
- }
361
- scheduleUpdate();
362
- break;
363
- }
364
- await processChunk(value);
365
  }
366
- stopTimer();
367
  } catch (error) {
368
- console.error('Erreur:', error);
369
- alert('Une erreur est survenue.');
370
  loader.classList.add('hidden');
 
371
  stopTimer();
372
  }
373
  });
 
1
+ <!DOCTYPE html>
2
  <html lang="fr">
3
  <head>
4
  <meta charset="UTF-8">
 
29
  };
30
  </script>
31
  <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" id="MathJax-script" async></script>
32
+ <!-- Marked.js - Toujours inclus au cas où il serait utilisé pour thoughtsContent -->
33
  <script src="https://cdn.jsdelivr.net/npm/marked/lib/marked.umd.min.js"></script>
34
 
35
  <style>
 
78
  overflow: hidden;
79
  }
80
  .thought-box.open {
81
+ max-height: 500px; /* Ajusté si nécessaire */
82
  }
83
 
84
  #thoughtsContent, #answerContent {
85
  max-height: 500px;
86
  overflow-y: auto;
87
  scroll-behavior: smooth;
88
+ white-space: pre-wrap; /* Important pour préserver les espaces/retours ligne du LaTeX brut */
89
  }
90
 
91
  .preview-image {
 
100
  margin-left: 8px;
101
  }
102
 
103
+ /* Styles pour les tables générées par MathJax/Markdown si nécessaire */
104
  table {
105
  border-collapse: collapse;
106
  width: 100%;
107
  margin-bottom: 1rem;
108
+ border: 1px solid #d1d5db; /* Ajout bordure table */
109
  }
110
  th, td {
111
  border: 1px solid #d1d5db;
 
137
  <header class="p-6 text-center mb-8">
138
  <h1 class="text-4xl font-bold text-blue-600">Mariam - M-0</h1>
139
  <p class="text-gray-600">Solution Mathématique/Physique/Chimie Intelligente</p>
140
+ <p class="performance-warning">
141
  Vous utilisez actuellement les modèles/performances moyens. Accédez à des performances supérieures avec un abonnement premium !
142
  </p>
143
  </header>
 
231
  const stopTimer = () => {
232
  clearInterval(timerInterval);
233
  startTime = null;
234
+ // Ne pas effacer le timestamp final
235
+ // timestamp.textContent = '';
236
  };
237
 
238
  const handleFileSelect = file => {
 
266
  handleFileSelect(e.dataTransfer.files[0]);
267
  });
268
 
269
+ // --- Déclaration de typesetContentIfReady ---
270
+ const typesetContentIfReady = async () => {
271
+ if (window.mathJaxReady && typeof MathJax !== 'undefined' && MathJax.typesetPromise) {
272
+ // Cible les deux conteneurs si nécessaire, ou juste answerContent si seul lui contient du LaTeX
273
+ // Pour être sûr, on peut cibler la section solution entière ou des éléments spécifiques.
274
+ // Ici, on cible explicitement answerContent comme dans le code original.
275
+ // Si thoughtsContent peut aussi avoir du MathJax, ajoutez-le au tableau.
276
+ // MathJax.startup.document.elements = [answerContent, thoughtsContent];
277
+ MathJax.startup.document.elements = [answerContent]; // Cible uniquement answerContent
278
+ try {
279
+ await MathJax.typesetPromise();
280
+ // Fait défiler vers le bas après le rendu MathJax
281
+ answerContent.scrollTop = answerContent.scrollHeight;
282
+ // Si thoughtsContent est aussi traité:
283
+ // thoughtsContent.scrollTop = thoughtsContent.scrollHeight;
284
+ } catch (error) {
285
+ console.error("Erreur pendant MathJax typesetPromise:", error);
286
+ }
287
  } else {
288
+ console.log('MathJax pas prêt, report du rendu...');
289
+ setTimeout(typesetContentIfReady, 200); // Réessayer
290
  }
291
  };
292
 
293
+ // --- Déclaration de updateDisplay ---
294
  const updateDisplay = async () => {
295
+ // Utilise Marked pour thoughtsContent (supposant qu'il contient du Markdown)
296
+ if (typeof marked !== 'undefined') {
297
+ thoughtsContent.innerHTML = marked.parse(thoughtsBuffer);
298
+ } else {
299
+ thoughtsContent.textContent = thoughtsBuffer; // Fallback si Marked n'est pas chargé
300
+ }
301
+
302
+ // **CORRECTION:** Insère le contenu brut dans answerContent, sans passer par Marked
303
+ answerContent.innerHTML = answerBuffer;
304
+
305
+ // Déclenche le rendu MathJax sur le contenu mis à jour
306
+ await typesetContentIfReady();
307
+
308
+ // Scrolling (peut être redondant si fait dans typesetContentIfReady)
309
+ thoughtsContent.scrollTop = thoughtsContent.scrollHeight;
310
+ // answerContent.scrollTop = answerContent.scrollHeight; // Déplacé dans typesetContentIfReady
311
+
312
  updateTimeout = null;
313
  };
314
 
315
  const scheduleUpdate = () => {
316
  if (updateTimeout) return;
317
+ // Délai légèrement augmenté pour laisser le temps au DOM de se mettre à jour avant MathJax
318
+ updateTimeout = setTimeout(updateDisplay, 250);
319
  };
320
 
321
+ // Configure Marked (si utilisé pour thoughtsContent)
322
+ if (typeof marked !== 'undefined') {
323
+ marked.setOptions({
324
+ gfm: true,
325
+ breaks: true
326
+ });
327
+ }
328
 
329
  form.addEventListener('submit', async e => {
330
  e.preventDefault();
 
342
  thoughtsBuffer = '';
343
  answerBuffer = '';
344
  currentMode = null;
345
+ thoughtsBox.classList.add('open'); // Ouvre par défaut
346
 
347
  const formData = new FormData();
348
  formData.append('image', file);
 
353
  body: formData
354
  });
355
 
356
+ if (!response.ok) {
357
+ throw new Error(`Erreur HTTP: ${response.status} ${response.statusText}`);
358
+ }
359
+ if (!response.body) {
360
+ throw new Error("La réponse ne contient pas de corps.");
361
+ }
362
+
363
  const reader = response.body.getReader();
364
  const decoder = new TextDecoder();
365
  let buffer = '';
366
+ let firstChunkReceived = false; // Pour afficher la section dès réception
367
 
368
+ const processChunk = async ({ done, value }) => {
369
+ if (done) {
370
+ // Traiter le reste du buffer s'il y en a
371
+ if (buffer && buffer.startsWith('data:')) {
372
+ try {
373
+ const data = JSON.parse(buffer.slice(5));
374
+ if (data.content) {
375
+ if (currentMode === 'thinking') {
376
+ thoughtsBuffer += data.content;
377
+ } else if (currentMode === 'answering') {
378
+ answerBuffer += data.content;
379
+ }
380
+ }
381
+ } catch(jsonError){
382
+ console.error("Erreur JSON dans le buffer final:", jsonError, "Buffer:", buffer);
383
+ }
384
+ }
385
+ // Assurer une dernière mise à jour après la fin du stream
386
+ await updateDisplay();
387
+ stopTimer(); // Arrêter le timer à la fin
388
+ console.log("Stream terminé.");
389
+ return true; // Indique que le stream est terminé
390
+ }
391
+
392
+ buffer += decoder.decode(value, { stream: true });
393
  const lines = buffer.split('\n\n');
394
+ buffer = lines.pop() || ''; // Garde la partie incomplète pour le prochain chunk
395
 
396
  for (const line of lines) {
397
  if (!line.startsWith('data:')) continue;
398
+ try {
399
+ const data = JSON.parse(line.slice(5));
400
+
401
+ if (data.mode) {
402
+ currentMode = data.mode;
403
+ // Afficher la section dès la première donnée reçue après le début du mode
404
+ if (!firstChunkReceived) {
405
+ loader.classList.add('hidden');
406
+ solutionSection.classList.remove('hidden');
407
+ firstChunkReceived = true;
408
+ }
409
+ }
410
+ if (data.content) {
411
+ if (currentMode === 'thinking') {
412
+ thoughtsBuffer += data.content;
413
+ } else if (currentMode === 'answering') {
414
+ answerBuffer += data.content;
415
+ }
416
+ // Mise à jour programmée pour éviter trop d'appels DOM/MathJax
417
+ scheduleUpdate();
418
+ }
419
+ } catch(jsonError) {
420
+ console.error("Erreur JSON dans le stream:", jsonError, "Ligne:", line);
421
+ // Continuer avec les lignes suivantes si possible
422
  }
423
  }
424
+ return false; // Indique que le stream n'est pas terminé
425
  };
426
 
427
+ // Boucle de lecture du stream
428
+ let streamFinished = false;
429
+ while (!streamFinished) {
430
+ const { done, value } = await reader.read();
431
+ streamFinished = await processChunk({ done, value });
 
 
 
 
 
 
 
 
 
 
 
 
432
  }
433
+
434
  } catch (error) {
435
+ console.error('Erreur lors de la récupération ou du traitement:', error);
436
+ alert(`Une erreur est survenue: ${error.message}`);
437
  loader.classList.add('hidden');
438
+ solutionSection.classList.add('hidden'); // Cacher si erreur
439
  stopTimer();
440
  }
441
  });