Docfile commited on
Commit
4d059d2
·
verified ·
1 Parent(s): f3eea2e

Delete templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +0 -377
templates/index.html DELETED
@@ -1,377 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="fr">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Mariam M-0 | Solution Mathématique</title>
7
- <!-- Tailwind CSS -->
8
- <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
9
- <!-- Google Fonts -->
10
- <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;700&display=swap" rel="stylesheet">
11
- <!-- MathJax -->
12
- <script>
13
- window.MathJax = {
14
- tex: {
15
- inlineMath: [['$', '$']],
16
- displayMath: [['$$', '$$']],
17
- processEscapes: true,
18
- packages: {'[+]': ['autoload', 'ams']}
19
- },
20
- options: {
21
- enableMenu: false,
22
- messageStyle: 'none'
23
- },
24
- startup: {
25
- pageReady: () => {
26
- console.log('MathJax est complètement chargé.');
27
- window.mathJaxReady = true;
28
- }
29
- }
30
- };
31
- </script>
32
- <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" id="MathJax-script" async></script>
33
- <!-- Marked -->
34
- <script src="https://cdn.jsdelivr.net/npm/marked/lib/marked.umd.min.js"></script>
35
- <style>
36
- body {
37
- font-family: 'Space Grotesk', sans-serif;
38
- animation: fadeIn 0.8s ease-in;
39
- }
40
- @keyframes fadeIn {
41
- from { opacity: 0; }
42
- to { opacity: 1; }
43
- }
44
- .uploadArea {
45
- background: #f3f4f6;
46
- border: 2px dashed #d1d5db;
47
- transition: border-color 0.3s ease, transform 0.2s ease;
48
- }
49
- .uploadArea:hover {
50
- border-color: #3b82f6;
51
- transform: scale(1.02);
52
- }
53
- .blue-button {
54
- background: #3b82f6;
55
- transition: background-color 0.3s ease, transform 0.2s ease;
56
- }
57
- .blue-button:hover {
58
- background: #2563eb;
59
- transform: scale(1.05);
60
- }
61
- .loader {
62
- width: 48px;
63
- height: 48px;
64
- border: 3px solid #3b82f6;
65
- border-bottom-color: transparent;
66
- border-radius: 50%;
67
- display: inline-block;
68
- animation: rotation 1s linear infinite;
69
- }
70
- @keyframes rotation {
71
- 0% { transform: rotate(0deg); }
72
- 100% { transform: rotate(360deg); }
73
- }
74
- .thought-box {
75
- transition: max-height 0.4s ease-out, opacity 0.3s ease;
76
- max-height: 0;
77
- opacity: 0;
78
- overflow: hidden;
79
- }
80
- .thought-box.open {
81
- max-height: 500px;
82
- opacity: 1;
83
- }
84
- #thoughtsContent, #answerContent {
85
- max-height: 500px;
86
- overflow-y: auto;
87
- scroll-behavior: smooth;
88
- white-space: pre-wrap;
89
- }
90
- .preview-image {
91
- max-width: 100%;
92
- height: auto;
93
- object-fit: contain;
94
- transition: transform 0.3s ease;
95
- }
96
- .preview-image:hover {
97
- transform: scale(1.05);
98
- }
99
- .timestamp {
100
- color: #3b82f6;
101
- font-size: 0.9em;
102
- margin-left: 8px;
103
- }
104
- table {
105
- border-collapse: collapse;
106
- width: 100%;
107
- margin-bottom: 1rem;
108
- }
109
- th, td {
110
- border: 1px solid #d1d5db;
111
- padding: 0.5rem;
112
- text-align: left;
113
- }
114
- th {
115
- background-color: #f3f4f6;
116
- font-weight: 600;
117
- }
118
- .table-responsive {
119
- overflow-x: auto;
120
- }
121
- /* Effets visuels subtils */
122
- header, main {
123
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
124
- border-radius: 8px;
125
- }
126
- h1 {
127
- font-size: 2.5rem;
128
- font-weight: 700;
129
- }
130
- </style>
131
- </head>
132
- <body class="p-4">
133
- <div class="w-full">
134
- <header class="p-6 text-center mb-8 bg-white">
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
- </header>
138
-
139
- <main class="bg-white p-6">
140
- <form id="problemForm" class="space-y-6" novalidate>
141
- <!-- Zone de dépôt et sélection d'image -->
142
- <div class="uploadArea p-8 text-center relative" aria-label="Zone de dépôt d'image">
143
- <input type="file" id="imageInput" accept="image/*" class="absolute inset-0 w-full h-full opacity-0 cursor-pointer" aria-label="Choisir une image">
144
- <div class="space-y-3">
145
- <div class="w-16 h-16 mx-auto border-2 border-blue-400 rounded-full flex items-center justify-center">
146
- <svg class="w-8 h-8 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
147
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
148
- d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
149
- </svg>
150
- </div>
151
- <p class="text-gray-700 font-medium">Déposez votre image ici</p>
152
- <p class="text-gray-500 text-sm">ou cliquez pour sélectionner</p>
153
- </div>
154
- </div>
155
-
156
- <!-- Aperçu de l'image -->
157
- <div id="imagePreview" class="hidden text-center">
158
- <img id="previewImage" class="preview-image mx-auto" alt="Prévisualisation de l'image sélectionnée">
159
- </div>
160
-
161
- <button type="submit" class="blue-button w-full py-3 text-white font-medium rounded-lg">
162
- Résoudre le problème
163
- </button>
164
- </form>
165
-
166
- <!-- Loader d'analyse -->
167
- <div id="loader" class="hidden mt-8 text-center">
168
- <span class="loader"></span>
169
- <p class="mt-4 text-gray-600">Analyse en cours...</p>
170
- </div>
171
-
172
- <!-- Affichage de la solution -->
173
- <section id="solution" class="hidden mt-8 space-y-6">
174
- <div class="border-t pt-4">
175
- <button id="thoughtsToggle" type="button" class="w-full flex justify-between items-center p-2 hover:bg-gray-100 rounded">
176
- <span class="font-medium text-gray-700">Processus de Réflexion</span>
177
- <span id="timestamp" class="timestamp"></span>
178
- </button>
179
- <div id="thoughtsBox" class="thought-box">
180
- <div id="thoughtsContent" class="p-4 text-gray-600"></div>
181
- </div>
182
- </div>
183
- <div class="border-t pt-6">
184
- <h3 class="text-xl font-bold text-gray-800 mb-4">Solution</h3>
185
- <div id="answerContent" class="text-gray-700 table-responsive"></div>
186
- </div>
187
- </section>
188
- </main>
189
- </div>
190
-
191
- <script>
192
- document.addEventListener('DOMContentLoaded', () => {
193
- const form = document.getElementById('problemForm');
194
- const imageInput = document.getElementById('imageInput');
195
- const loader = document.getElementById('loader');
196
- const solutionSection = document.getElementById('solution');
197
- const thoughtsContent = document.getElementById('thoughtsContent');
198
- const answerContent = document.getElementById('answerContent');
199
- const thoughtsToggle = document.getElementById('thoughtsToggle');
200
- const thoughtsBox = document.getElementById('thoughtsBox');
201
- const imagePreview = document.getElementById('imagePreview');
202
- const previewImage = document.getElementById('previewImage');
203
- const timestamp = document.getElementById('timestamp');
204
-
205
- let startTime = null;
206
- let timerInterval = null;
207
- let thoughtsBuffer = '';
208
- let answerBuffer = '';
209
- let currentMode = null;
210
- let updateTimeout = null;
211
-
212
- const updateTimestamp = () => {
213
- if (startTime) {
214
- const seconds = Math.floor((Date.now() - startTime) / 1000);
215
- timestamp.textContent = `${seconds}s`;
216
- }
217
- };
218
-
219
- const startTimer = () => {
220
- startTime = Date.now();
221
- timerInterval = setInterval(updateTimestamp, 1000);
222
- updateTimestamp();
223
- };
224
-
225
- const stopTimer = () => {
226
- clearInterval(timerInterval);
227
- startTime = null;
228
- timestamp.textContent = '';
229
- };
230
-
231
- const handleFileSelect = file => {
232
- if (!file) return;
233
- const reader = new FileReader();
234
- reader.onload = e => {
235
- previewImage.src = e.target.result;
236
- imagePreview.classList.remove('hidden');
237
- imagePreview.classList.add('animate-fadeIn');
238
- };
239
- reader.readAsDataURL(file);
240
- };
241
-
242
- thoughtsToggle.addEventListener('click', () => {
243
- thoughtsBox.classList.toggle('open');
244
- });
245
-
246
- imageInput.addEventListener('change', e => handleFileSelect(e.target.files[0]));
247
-
248
- const dropZone = document.querySelector('.uploadArea');
249
- dropZone.addEventListener('dragover', e => {
250
- e.preventDefault();
251
- dropZone.classList.add('border-blue-400');
252
- });
253
- dropZone.addEventListener('dragleave', e => {
254
- e.preventDefault();
255
- dropZone.classList.remove('border-blue-400');
256
- });
257
- dropZone.addEventListener('drop', e => {
258
- e.preventDefault();
259
- dropZone.classList.remove('border-blue-400');
260
- handleFileSelect(e.dataTransfer.files[0]);
261
- });
262
-
263
- const typesetAnswerIfReady = async () => {
264
- if (window.mathJaxReady) {
265
- MathJax.startup.document.elements = [document.getElementById('answerContent')];
266
- await MathJax.typesetPromise();
267
- answerContent.scrollTop = answerContent.scrollHeight;
268
- } else {
269
- setTimeout(typesetAnswerIfReady, 200);
270
- }
271
- };
272
-
273
- const updateDisplay = async () => {
274
- thoughtsContent.innerHTML = marked.parse(thoughtsBuffer);
275
- answerContent.innerHTML = marked.parse(answerBuffer);
276
- await typesetAnswerIfReady();
277
- updateTimeout = null;
278
- };
279
-
280
- const scheduleUpdate = () => {
281
- if (updateTimeout) return;
282
- updateTimeout = setTimeout(updateDisplay, 200);
283
- };
284
-
285
- marked.setOptions({
286
- gfm: true,
287
- breaks: true
288
- });
289
-
290
- form.addEventListener('submit', async e => {
291
- e.preventDefault();
292
- const file = imageInput.files[0];
293
- if (!file) {
294
- alert('Veuillez sélectionner une image.');
295
- return;
296
- }
297
-
298
- startTimer();
299
- loader.classList.remove('hidden');
300
- loader.classList.add('animate-fadeIn');
301
- solutionSection.classList.add('hidden');
302
- thoughtsContent.innerHTML = '';
303
- answerContent.innerHTML = '';
304
- thoughtsBuffer = '';
305
- answerBuffer = '';
306
- currentMode = null;
307
- thoughtsBox.classList.add('open');
308
-
309
- const formData = new FormData();
310
- formData.append('image', file);
311
-
312
- try {
313
- const response = await fetch('/solve', {
314
- method: 'POST',
315
- body: formData
316
- });
317
-
318
- const reader = response.body.getReader();
319
- const decoder = new TextDecoder();
320
- let buffer = '';
321
-
322
- const processChunk = async chunk => {
323
- buffer += decoder.decode(chunk, { stream: true });
324
- const lines = buffer.split('\n\n');
325
- buffer = lines.pop();
326
-
327
- for (const line of lines) {
328
- if (!line.startsWith('data:')) continue;
329
- const data = JSON.parse(line.slice(5));
330
-
331
- if (data.mode) {
332
- currentMode = data.mode;
333
- loader.classList.add('hidden');
334
- solutionSection.classList.remove('hidden');
335
- solutionSection.classList.add('animate-fadeIn');
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
- });
374
- });
375
- </script>
376
- </body>
377
- </html>