Docfile commited on
Commit
e91d2b6
·
verified ·
1 Parent(s): e2d63ac

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +142 -133
templates/index.html CHANGED
@@ -126,36 +126,53 @@
126
  text-align: left;
127
  line-height: 1.8;
128
  font-size: 16px;
129
- background-color: transparent;
130
  box-shadow: var(--box-shadow);
131
- overflow: hidden;
132
  }
133
 
134
- .step-section, .code-section, .output-section {
135
- margin: 0 0 1px 0; /* Reduced bottom margin to make sections appear connected */
136
  padding: 20px;
137
- border-radius: 0;
 
138
  overflow-x: auto;
139
- background-color: #f9f9f9;
 
 
 
140
  }
141
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  .step-section {
143
- border-left: 4px solid var(--primary-color);
144
- padding-left: calc(20px - 4px); /* Adjust padding to account for border */
145
- background-color: #f9f9f9;
146
- font-size: 16px;
147
- line-height: 1.8;
 
148
  }
149
 
150
- /* Improved LaTeX styling */
151
  .step-section .mjx-chtml {
152
- /* Default MathJax inline styling */
153
  display: inline-block;
154
  line-height: 0;
155
  text-indent: 0;
156
  text-align: left;
157
  text-transform: none;
158
- font-size: 100%; /* Ensure inline MathJax respects container font size */
159
  font-style: normal;
160
  font-weight: normal;
161
  font-family: MJXZERO, MJXTEX;
@@ -164,13 +181,16 @@
164
  margin: 0 0.2em; /* Small horizontal margin */
165
  }
166
 
167
- .step-section .MathJax {
168
- /* Default MathJax container styling */
169
- display: inline;
170
- font-size: 100% !important; /* Ensure inline MathJax respects container font size */
171
- text-align: left;
 
 
172
  }
173
 
 
174
  /* Fix for inline math to prevent weird line breaks */
175
  .step-section p {
176
  display: block; /* Paragraphs should be block elements */
@@ -180,21 +200,6 @@
180
  margin-inline-end: 0px;
181
  }
182
 
183
- /* Improve display for block equations */
184
- .latex-display {
185
- overflow-x: auto;
186
- padding: 10px 0;
187
- margin: 15px 0;
188
- text-align: center;
189
- display: block;
190
- width: 100%;
191
- }
192
-
193
- .code-section {
194
- background-color: transparent; /* Background handled by code-content */
195
- padding: 0; /* Padding handled by code-content */
196
- border-left: none; /* No left border */
197
- }
198
 
199
  .code-header {
200
  background-color: #343a40;
@@ -205,9 +210,9 @@
205
  display: flex;
206
  justify-content: space-between;
207
  align-items: center;
208
- /* Border radius handled by first/last child rules */
209
- border-top-left-radius: 0px;
210
- border-top-right-radius: 0px;
211
  }
212
 
213
  .code-content {
@@ -219,81 +224,85 @@
219
  font-family: 'Courier New', monospace;
220
  font-size: 14px;
221
  line-height: 1.5;
222
- /* Border radius handled by first/last child rules */
223
- border-bottom-left-radius: 0px;
224
- border-bottom-right-radius: 0px;
225
  }
226
 
227
- .output-section {
228
- background-color: var(--output-bg);
229
- padding: 15px;
230
- border-top: 1px solid #ddd;
231
- color: #333;
232
- font-family: 'Courier New', monospace;
233
- font-size: 14px;
234
- white-space: pre-wrap;
235
- overflow-x: auto;
236
- border-left: none; /* No left border */
237
- /* Border radius handled by first/last child rules */
238
- border-bottom-left-radius: 0px;
239
- border-bottom-right-radius: 0px;
240
- }
241
 
242
- /* Add border-radius back to the very first and very last child inside #solution */
 
 
243
  #solution > div:first-child {
244
  border-top-left-radius: 8px;
245
  border-top-right-radius: 8px;
246
  }
247
-
248
- #solution > div:first-child .code-header {
 
 
 
 
 
249
  border-top-left-radius: 8px;
250
  border-top-right-radius: 8px;
251
  }
252
 
253
 
 
254
  #solution > div:last-child {
255
  border-bottom-left-radius: 8px;
256
  border-bottom-right-radius: 8px;
257
- margin-bottom: 0; /* Remove extra margin on the last child */
258
  }
259
-
260
  #solution > .code-section:last-child .code-content {
261
- border-bottom-left-radius: 8px;
262
- border-bottom-right-radius: 8px;
263
- }
264
-
265
- /* Specific case for a single code section */
266
- #solution > .code-section:only-child .code-header {
267
- border-top-left-radius: 8px;
268
- border-top-right-radius: 8px;
269
- }
270
- #solution > .code-section:only-child .code-content {
271
  border-bottom-left-radius: 8px;
272
  border-bottom-right-radius: 8px;
273
  }
274
-
275
-
276
- #solution > .output-section:last-child {
277
  border-bottom-left-radius: 8px;
278
  border-bottom-right-radius: 8px;
279
- margin-bottom: 0;
280
  }
281
 
282
- /* Specific case for a single output section */
283
- #solution > .output-section:only-child {
 
 
 
 
 
284
  border-top-left-radius: 8px;
285
  border-top-right-radius: 8px;
 
 
286
  border-bottom-left-radius: 8px;
287
  border-bottom-right-radius: 8px;
288
- margin-bottom: 0;
 
 
 
289
  }
290
 
291
- /* Remove bottom border/margin for sections that are not the last child, */
292
- /* to make them appear connected to the next section */
 
293
  #solution > div:not(:last-child) {
294
- margin-bottom: 0;
295
  }
296
 
 
 
 
 
 
 
 
 
 
 
297
 
298
  /* Fixed display of MathJax content */
299
  .mjx-container {
@@ -306,14 +315,6 @@
306
  vertical-align: middle; /* Better vertical alignment for inline math */
307
  }
308
 
309
- .mjx-container.MJX-display {
310
- display: block !important;
311
- margin: 1em auto !important;
312
- text-align: center !important;
313
- max-width: 100%;
314
- overflow-x: auto; /* Allow horizontal scrolling for large block equations */
315
- overflow-y: hidden;
316
- }
317
 
318
  /* Fix markdown list rendering */
319
  .step-section ul, .step-section ol {
@@ -368,18 +369,10 @@
368
 
369
  /* Unified consistent LaTeX size for all equations */
370
  /* Ensure MathJax respects container font size */
371
- .step-section .MathJax,
372
  .step-section .mjx-container {
373
- font-size: inherit !important;
374
  }
375
 
376
- .step-section .MathJax_Display {
377
- text-align: center !important;
378
- margin: 1em auto !important;
379
- display: block !important;
380
- overflow-x: auto;
381
- overflow-y: hidden;
382
- }
383
  </style>
384
  </head>
385
  <body>
@@ -454,8 +447,8 @@
454
  <script>
455
  window.MathJax = {
456
  tex: {
457
- inlineMath: [['$', '$'], ['\\(', '\\)']], // Correct inline delimiters
458
- displayMath: [['$$', '$$'], ['\\[', '\\]']], // Correct block delimiters
459
  processEscapes: true,
460
  processEnvironments: true,
461
  packages: {'[+]': ['noerrors', 'physics', 'cancel', 'color']}
@@ -532,6 +525,7 @@
532
  if (done) {
533
  loadingIndicator.style.display = 'none';
534
  // Force MathJax to reprocess entire solution when done
 
535
  if (typeof MathJax !== 'undefined') {
536
  MathJax.typesetPromise([solutionContainer]).catch(e => console.error('MathJax final typesetting error:', e));
537
  }
@@ -539,15 +533,15 @@
539
  }
540
 
541
  buffer += decoder.decode(value, { stream: true });
542
- // Split by double newline to separate chunks, but keep the last incomplete chunk in buffer
543
- const lines = buffer.split(/\r?\n\r?\n/);
544
- buffer = lines.pop(); // Store the last potentially incomplete chunk
545
 
546
- for (const line of lines) {
547
  // Only process lines that start with 'data: ' for SSE
548
- if (line.startsWith('data: ')) {
549
  try {
550
- const data = JSON.parse(line.substr(6)); // Extract JSON after 'data: '
551
 
552
  // Handle mode updates
553
  if (data.mode) {
@@ -561,10 +555,12 @@
561
  if (modeInfo) {
562
  loadingIndicator.className = modeInfo.class; // Update class for styling
563
  loadingIndicator.innerHTML = `<i class="fas ${modeInfo.icon} indicator-icon"></i><span>${modeInfo.text}</span>`; // Update icon and text
 
564
  } else {
565
  // Default or unknown mode
566
  loadingIndicator.className = 'thinking-indicator';
567
  loadingIndicator.innerHTML = `<i class="fas fa-sync-alt indicator-icon fa-spin"></i><span>Traitement...</span>`;
 
568
  }
569
  }
570
 
@@ -572,7 +568,7 @@
572
  if (data.content) {
573
  const content = data.content;
574
  const tempDiv = document.createElement('div');
575
- tempDiv.innerHTML = content; // Parse HTML chunk
576
 
577
  const codeSection = tempDiv.querySelector('.code-section');
578
  const outputSection = tempDiv.querySelector('.output-section');
@@ -583,8 +579,10 @@
583
  codeSection.querySelectorAll('pre code').forEach((block) => {
584
  hljs.highlightElement(block);
585
  });
 
586
  } else if (outputSection) {
587
  solutionContainer.appendChild(outputSection);
 
588
  } else {
589
  // Process regular text/LaTeX step section
590
  const stepDiv = document.createElement('div');
@@ -594,53 +592,64 @@
594
  let processedContent = content;
595
 
596
  // Convert markdown lists to HTML lists
597
- processedContent = processedContent.replace(/^(-|\*|\+)\s+(.*)$/gm, '<li>$2</li>'); // Handles -, *, + markers
598
- processedContent = processedContent.replace(/^(\d+)\.\s+(.*)$/gm, '<li>$2</li>'); // Handles numbered lists
599
-
600
- // Wrap consecutive list items in ul/ol tags
601
- let listHtml = '';
602
  let inList = false;
603
  let listType = ''; // 'ul' or 'ol'
604
 
605
- processedContent.split('\n').forEach(line => {
606
- if (line.startsWith('<li>')) {
607
- const itemType = line.match(/^\d+\./) ? 'ol' : 'ul';
 
 
 
 
 
 
 
 
 
 
608
  if (!inList) {
609
- listType = itemType;
610
- listHtml += `<${listType}>${line}`;
611
  inList = true;
612
- } else if (listType === itemType) {
613
- listHtml += line;
614
- } else {
615
- // Different list type, close previous and start new
616
- listHtml += `</${listType}><${itemType}>${line}`;
617
- listType = itemType;
618
  }
 
619
  } else {
620
  if (inList) {
621
- listHtml += `</${listType}>`;
622
  inList = false;
623
  }
624
- listHtml += `<p>${line}</p>`; // Wrap non-list lines in paragraphs
 
 
 
625
  }
626
- });
627
 
628
  if (inList) {
629
- listHtml += `</${listType}>`;
630
  }
631
 
632
- // Clean up empty paragraph tags that might have been created
633
- listHtml = listHtml.replace(/<p><\/p>/g, '');
634
-
635
 
636
- stepDiv.innerHTML = listHtml; // Use the processed HTML
637
  solutionContainer.appendChild(stepDiv);
638
 
639
- // Process MathJax for this section (will process the new content)
640
  if (typeof MathJax !== 'undefined') {
 
641
  MathJax.typesetPromise([stepDiv]).catch(e => console.error('MathJax typesetting error:', e));
642
  }
643
  }
 
 
644
  }
645
 
646
  // Handle error messages
@@ -655,18 +664,18 @@
655
  loadingIndicator.style.display = 'none'; // Hide loading indicator on error
656
  }
657
  } catch (e) {
658
- console.error('Error parsing JSON or processing chunk:', e, line);
659
  // Display a client-side processing error message
660
  const errorDiv = document.createElement('div');
661
  errorDiv.className = 'step-section';
662
  errorDiv.style.color = 'orange';
663
- errorDiv.textContent = `Erreur traitement chunk: ${line.substring(0, 100)}...`; // Show a snippet of the problematic line
664
  solutionContainer.appendChild(errorDiv);
665
  loadingIndicator.style.display = 'none';
666
  }
667
  } else {
668
  // Handle potential non-data lines if necessary, or ignore
669
- console.warn("Received non-data line:", line);
670
  }
671
  }
672
 
 
126
  text-align: left;
127
  line-height: 1.8;
128
  font-size: 16px;
129
+ background-color: transparent; /* Background of the container itself */
130
  box-shadow: var(--box-shadow);
131
+ overflow: hidden; /* Clip children borders to parent radius */
132
  }
133
 
134
+ /* Apply common padding and margin to sections */
135
+ #solution > div {
136
  padding: 20px;
137
+ margin: 0; /* Remove default margin */
138
+ border-radius: 0; /* Reset radius, applied to first/last children */
139
  overflow-x: auto;
140
+ background-color: #f9f9f9; /* Default background */
141
+ border-left: 4px solid var(--primary-color); /* Default left border */
142
+ /* Added border-bottom to create separation between sections */
143
+ border-bottom: 1px solid #eee;
144
  }
145
 
146
+ .code-section {
147
+ background-color: transparent !important; /* Background handled by code-content */
148
+ padding: 0 !important; /* Padding handled by code-content */
149
+ border-left: none !important; /* No left border for code section parent */
150
+ border-bottom: none !important; /* No border bottom on code section parent */
151
+ }
152
+
153
+ .output-section {
154
+ background-color: var(--output-bg) !important; /* Override default section background */
155
+ border-left: none !important; /* No left border for output section parent */
156
+ }
157
+
158
+
159
  .step-section {
160
+ /* Specific styles for steps */
161
+ border-left: 4px solid var(--primary-color);
162
+ padding-left: calc(20px - 4px); /* Adjust padding to account for border */
163
+ background-color: #f9f9f9;
164
+ font-size: 16px;
165
+ line-height: 1.8;
166
  }
167
 
168
+ /* Improved LaTeX styling (MathJax v3 specific) */
169
  .step-section .mjx-chtml {
 
170
  display: inline-block;
171
  line-height: 0;
172
  text-indent: 0;
173
  text-align: left;
174
  text-transform: none;
175
+ font-size: 1em !important; /* Ensure inline MathJax respects container font size */
176
  font-style: normal;
177
  font-weight: normal;
178
  font-family: MJXZERO, MJXTEX;
 
181
  margin: 0 0.2em; /* Small horizontal margin */
182
  }
183
 
184
+ .step-section .mjx-container.MJX-display {
185
+ display: block !important;
186
+ margin: 1em auto !important;
187
+ text-align: center !important;
188
+ max-width: 100%;
189
+ overflow-x: auto; /* Allow horizontal scrolling for large block equations */
190
+ overflow-y: hidden;
191
  }
192
 
193
+
194
  /* Fix for inline math to prevent weird line breaks */
195
  .step-section p {
196
  display: block; /* Paragraphs should be block elements */
 
200
  margin-inline-end: 0px;
201
  }
202
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
 
204
  .code-header {
205
  background-color: #343a40;
 
210
  display: flex;
211
  justify-content: space-between;
212
  align-items: center;
213
+ /* Border radius handled by first child rules below */
214
+ border-top-left-radius: 0;
215
+ border-top-right-radius: 0;
216
  }
217
 
218
  .code-content {
 
224
  font-family: 'Courier New', monospace;
225
  font-size: 14px;
226
  line-height: 1.5;
227
+ /* Border radius handled by last child rules below */
228
+ border-bottom-left-radius: 0;
229
+ border-bottom-right-radius: 0;
230
  }
231
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
 
233
+ /* Add border-radius back to the very first and very last child INSIDE #solution */
234
+
235
+ /* First child in #solution */
236
  #solution > div:first-child {
237
  border-top-left-radius: 8px;
238
  border-top-right-radius: 8px;
239
  }
240
+ /* Special handling for the first child if it's a code section (header needs radius) */
241
+ #solution > .code-section:first-child .code-header {
242
+ border-top-left-radius: 8px;
243
+ border-top-right-radius: 8px;
244
+ }
245
+ /* Special handling for the first child if it's an output section */
246
+ #solution > .output-section:first-child {
247
  border-top-left-radius: 8px;
248
  border-top-right-radius: 8px;
249
  }
250
 
251
 
252
+ /* Last child in #solution */
253
  #solution > div:last-child {
254
  border-bottom-left-radius: 8px;
255
  border-bottom-right-radius: 8px;
256
+ border-bottom: none; /* Remove the bottom border on the very last section */
257
  }
258
+ /* Special handling for the last child if it's a code section (content needs radius) */
259
  #solution > .code-section:last-child .code-content {
 
 
 
 
 
 
 
 
 
 
260
  border-bottom-left-radius: 8px;
261
  border-bottom-right-radius: 8px;
262
  }
263
+ /* Special handling for the last child if it's an output section */
264
+ #solution > .output-section:last-child {
 
265
  border-bottom-left-radius: 8px;
266
  border-bottom-right-radius: 8px;
267
+ border-bottom: none;
268
  }
269
 
270
+
271
+ /* Specific case for a single child (both first and last) */
272
+ #solution > div:only-child {
273
+ border-radius: 8px;
274
+ border-bottom: none;
275
+ }
276
+ #solution > .code-section:only-child .code-header {
277
  border-top-left-radius: 8px;
278
  border-top-right-radius: 8px;
279
+ }
280
+ #solution > .code-section:only-child .code-content {
281
  border-bottom-left-radius: 8px;
282
  border-bottom-right-radius: 8px;
283
+ }
284
+ #solution > .output-section:only-child {
285
+ border-radius: 8px;
286
+ border-bottom: none;
287
  }
288
 
289
+
290
+ /* Remove bottom border for sections that are not the last child,
291
+ to make them appear connected to the next section */
292
  #solution > div:not(:last-child) {
293
+ border-bottom: 1px solid #eee;
294
  }
295
 
296
+ /* Code section should not have a bottom border even if not last */
297
+ #solution > .code-section {
298
+ border-bottom: none;
299
+ }
300
+
301
+ /* Output section should not have a bottom border even if not last */
302
+ #solution > .output-section:not(:last-child) {
303
+ border-bottom: 1px solid #ddd; /* Keep the separator line */
304
+ }
305
+
306
 
307
  /* Fixed display of MathJax content */
308
  .mjx-container {
 
315
  vertical-align: middle; /* Better vertical alignment for inline math */
316
  }
317
 
 
 
 
 
 
 
 
 
318
 
319
  /* Fix markdown list rendering */
320
  .step-section ul, .step-section ol {
 
369
 
370
  /* Unified consistent LaTeX size for all equations */
371
  /* Ensure MathJax respects container font size */
 
372
  .step-section .mjx-container {
373
+ font-size: 1em !important; /* Use relative units */
374
  }
375
 
 
 
 
 
 
 
 
376
  </style>
377
  </head>
378
  <body>
 
447
  <script>
448
  window.MathJax = {
449
  tex: {
450
+ inlineMath: [['$', '$'], ['\\(', '\\)']], // Standard inline delimiters
451
+ displayMath: [['$$', '$$'], ['\\[', '\\]']], // Standard block delimiters
452
  processEscapes: true,
453
  processEnvironments: true,
454
  packages: {'[+]': ['noerrors', 'physics', 'cancel', 'color']}
 
525
  if (done) {
526
  loadingIndicator.style.display = 'none';
527
  // Force MathJax to reprocess entire solution when done
528
+ // Use the specific container element
529
  if (typeof MathJax !== 'undefined') {
530
  MathJax.typesetPromise([solutionContainer]).catch(e => console.error('MathJax final typesetting error:', e));
531
  }
 
533
  }
534
 
535
  buffer += decoder.decode(value, { stream: true });
536
+ // Split by double newline to separate SSE messages, but keep the last incomplete chunk in buffer
537
+ const messages = buffer.split(/\r?\n\r?\n/);
538
+ buffer = messages.pop(); // Store the last potentially incomplete chunk
539
 
540
+ for (const message of messages) {
541
  // Only process lines that start with 'data: ' for SSE
542
+ if (message.startsWith('data: ')) {
543
  try {
544
+ const data = JSON.parse(message.substr(6)); // Extract JSON after 'data: '
545
 
546
  // Handle mode updates
547
  if (data.mode) {
 
555
  if (modeInfo) {
556
  loadingIndicator.className = modeInfo.class; // Update class for styling
557
  loadingIndicator.innerHTML = `<i class="fas ${modeInfo.icon} indicator-icon"></i><span>${modeInfo.text}</span>`; // Update icon and text
558
+ loadingIndicator.style.display = 'flex'; // Ensure indicator is visible when a mode is set
559
  } else {
560
  // Default or unknown mode
561
  loadingIndicator.className = 'thinking-indicator';
562
  loadingIndicator.innerHTML = `<i class="fas fa-sync-alt indicator-icon fa-spin"></i><span>Traitement...</span>`;
563
+ loadingIndicator.style.display = 'flex';
564
  }
565
  }
566
 
 
568
  if (data.content) {
569
  const content = data.content;
570
  const tempDiv = document.createElement('div');
571
+ tempDiv.innerHTML = content; // Parse HTML chunk received from server
572
 
573
  const codeSection = tempDiv.querySelector('.code-section');
574
  const outputSection = tempDiv.querySelector('.output-section');
 
579
  codeSection.querySelectorAll('pre code').forEach((block) => {
580
  hljs.highlightElement(block);
581
  });
582
+ // MathJax should ignore code blocks based on options
583
  } else if (outputSection) {
584
  solutionContainer.appendChild(outputSection);
585
+ // MathJax should ignore output blocks based on options
586
  } else {
587
  // Process regular text/LaTeX step section
588
  const stepDiv = document.createElement('div');
 
592
  let processedContent = content;
593
 
594
  // Convert markdown lists to HTML lists
595
+ // This is a basic approach and might not cover all markdown complexities
596
+ const lines = processedContent.split('\n');
597
+ let htmlOutput = '';
 
 
598
  let inList = false;
599
  let listType = ''; // 'ul' or 'ol'
600
 
601
+ for (const line of lines) {
602
+ const trimmedLine = line.trim();
603
+ if (trimmedLine.match(/^(-|\*|\+)\s/)) { // Unordered list item
604
+ if (!inList) {
605
+ htmlOutput += '<ul>';
606
+ inList = true;
607
+ listType = 'ul';
608
+ } else if (listType !== 'ul') {
609
+ htmlOutput += `</${listType}><ul>`;
610
+ listType = 'ul';
611
+ }
612
+ htmlOutput += `<li>${trimmedLine.replace(/^(-|\*|\+)\s+/, '')}</li>`;
613
+ } else if (trimmedLine.match(/^(\d+)\.\s/)) { // Ordered list item
614
  if (!inList) {
615
+ htmlOutput += '<ol>';
 
616
  inList = true;
617
+ listType = 'ol';
618
+ } else if (listType !== 'ol') {
619
+ htmlOutput += `</${listType}><ol>`;
620
+ listType = 'ol';
 
 
621
  }
622
+ htmlOutput += `<li>${trimmedLine.replace(/^(\d+)\.\s+/, '')}</li>`;
623
  } else {
624
  if (inList) {
625
+ htmlOutput += `</${listType}>`;
626
  inList = false;
627
  }
628
+ // Add non-list content wrapped in paragraphs, handling double newlines
629
+ if (line.trim() !== '') {
630
+ htmlOutput += `<p>${line}</p>`;
631
+ }
632
  }
633
+ }
634
 
635
  if (inList) {
636
+ htmlOutput += `</${listType}>`;
637
  }
638
 
639
+ // Remove empty paragraph tags that might have been created
640
+ htmlOutput = htmlOutput.replace(/<p>\s*<\/p>/g, '');
 
641
 
642
+ stepDiv.innerHTML = htmlOutput; // Use the processed HTML
643
  solutionContainer.appendChild(stepDiv);
644
 
645
+ // Process MathJax for this specific section (will process the new content)
646
  if (typeof MathJax !== 'undefined') {
647
+ // Use typesetPromise and target the newly added stepDiv
648
  MathJax.typesetPromise([stepDiv]).catch(e => console.error('MathJax typesetting error:', e));
649
  }
650
  }
651
+ // Hide the loading indicator once content starts arriving (optional, but can feel more responsive)
652
+ // loadingIndicator.style.display = 'none'; // Keep it visible to show mode changes
653
  }
654
 
655
  // Handle error messages
 
664
  loadingIndicator.style.display = 'none'; // Hide loading indicator on error
665
  }
666
  } catch (e) {
667
+ console.error('Error parsing JSON or processing message:', e, message);
668
  // Display a client-side processing error message
669
  const errorDiv = document.createElement('div');
670
  errorDiv.className = 'step-section';
671
  errorDiv.style.color = 'orange';
672
+ errorDiv.textContent = `Erreur traitement message: ${message.substring(0, 100)}...`; // Show a snippet of the problematic line
673
  solutionContainer.appendChild(errorDiv);
674
  loadingIndicator.style.display = 'none';
675
  }
676
  } else {
677
  // Handle potential non-data lines if necessary, or ignore
678
+ // console.warn("Received non-data line:", message); // Uncomment for debugging
679
  }
680
  }
681