Docfile commited on
Commit
25182e7
·
verified ·
1 Parent(s): 3c9e253

Upload templates_index (17).html

Browse files
Files changed (1) hide show
  1. templates/templates_index (17).html +351 -0
templates/templates_index (17).html ADDED
@@ -0,0 +1,351 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
8
+ <script>
9
+ window.MathJax = {
10
+ tex: {
11
+ inlineMath: [['$', '$'], ['\\(', '\\)']],
12
+ displayMath: [['$$', '$$'], ['\\[', '\\]']],
13
+ processEscapes: true,
14
+ packages: ['base', 'ams', 'noerrors', 'noundefined']
15
+ },
16
+ options: {
17
+ ignoreHtmlClass: 'tex2jax_ignore',
18
+ processHtmlClass: 'tex2jax_process'
19
+ },
20
+ svg: {
21
+ fontCache: 'global'
22
+ }
23
+ };
24
+ </script>
25
+ <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
26
+ <style>
27
+ @import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&display=swap');
28
+
29
+ body {
30
+ font-family: 'Space Grotesk', sans-serif;
31
+ background-color: white;
32
+ }
33
+
34
+ .uploadArea {
35
+ background: #f3f4f6;
36
+ border: 2px dashed #d1d5db;
37
+ }
38
+
39
+ .uploadArea:hover {
40
+ border-color: #3b82f6;
41
+ transform: translateY(-2px);
42
+ }
43
+
44
+ .blue-button {
45
+ background: #3b82f6;
46
+ transition: all 0.3s ease;
47
+ }
48
+
49
+ .blue-button:hover {
50
+ background: #2563eb;
51
+ transform: translateY(-2px);
52
+ }
53
+
54
+ .loader {
55
+ width: 48px;
56
+ height: 48px;
57
+ border: 3px solid #3b82f6;
58
+ border-bottom-color: transparent;
59
+ border-radius: 50%;
60
+ display: inline-block;
61
+ box-sizing: border-box;
62
+ animation: rotation 1s linear infinite;
63
+ }
64
+
65
+ @keyframes rotation {
66
+ 0% { transform: rotate(0deg); }
67
+ 100% { transform: rotate(360deg); }
68
+ }
69
+
70
+ .thought-box {
71
+ transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
72
+ max-height: 0;
73
+ overflow: hidden;
74
+ }
75
+
76
+ .thought-box.open {
77
+ max-height: 1000px;
78
+ }
79
+
80
+ .preview-container {
81
+ display: flex;
82
+ justify-content: center;
83
+ align-items: center;
84
+ margin-top: 20px;
85
+ }
86
+
87
+ .preview-image {
88
+ max-width: 300px;
89
+ max-height: 300px;
90
+ border-radius: 8px;
91
+ }
92
+
93
+ #thoughtsContent, #answerContent {
94
+ max-height: 500px;
95
+ overflow-y: auto;
96
+ }
97
+
98
+ .timestamp {
99
+ color: #3b82f6;
100
+ margin-left: 10px;
101
+ font-size: 0.9em;
102
+ }
103
+ </style>
104
+ </head>
105
+ <body class="p-4">
106
+ <div class="w-full">
107
+ <div class="p-8">
108
+ <div class="text-center mb-12">
109
+ <h1 class="text-4xl font-bold text-blue-600 mb-4">Mariam M-0</h1>
110
+ <p class="text-gray-600 text-lg">Solution Mathématique Intelligente</p>
111
+ </div>
112
+
113
+ <form id="problemForm" class="space-y-8" enctype="multipart/form-data">
114
+ <div class="relative">
115
+ <div class="uploadArea p-12 text-center transition-all duration-300 cursor-pointer">
116
+ <input type="file" id="imageInput" name="image" accept="image/*" class="absolute inset-0 w-full h-full opacity-0 cursor-pointer">
117
+ <div class="space-y-4">
118
+ <div class="w-20 h-20 mx-auto border-2 border-blue-400 rounded-full flex items-center justify-center">
119
+ <svg class="w-10 h-10 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
120
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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" />
121
+ </svg>
122
+ </div>
123
+ <div class="text-gray-700 text-lg font-medium">Déposez votre image ici</div>
124
+ <div class="text-gray-500 text-sm">ou cliquez pour sélectionner</div>
125
+ </div>
126
+ </div>
127
+ <div id="imagePreview" class="preview-container hidden">
128
+ <img id="previewImage" src="#" alt="Prévisualisation de l'image" class="preview-image">
129
+ </div>
130
+ </div>
131
+
132
+ <button type="submit" class="blue-button w-full py-4 text-white font-medium text-lg transition-all duration-300">
133
+ Résoudre le problème
134
+ </button>
135
+ </form>
136
+
137
+ <div id="loader" class="hidden mt-12">
138
+ <div class="flex flex-col items-center justify-center space-y-4">
139
+ <span class="loader"></span>
140
+ <div class="text-gray-600 text-lg">Analyse en cours...</div>
141
+ </div>
142
+ </div>
143
+
144
+ <div id="solution" class="hidden mt-12 space-y-8">
145
+ <div class="border-t pt-6">
146
+ <button id="thoughtsToggle" class="w-full flex justify-between items-center text-left text-lg font-medium text-gray-700 hover:text-blue-600 transition-colors">
147
+ <div class="flex items-center">
148
+ <span>Processus de Réflexion</span>
149
+ <span id="timestamp" class="timestamp"></span>
150
+ </div>
151
+ <svg class="w-6 h-6 transform transition-transform duration-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
152
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
153
+ </svg>
154
+ </button>
155
+ <div id="thoughtsBox" class="thought-box">
156
+ <div id="thoughtsContent" class="prose max-w-none text-gray-600 mt-4"></div>
157
+ </div>
158
+ </div>
159
+
160
+ <div class="border-t pt-8">
161
+ <h3 class="text-2xl font-bold text-gray-800 mb-6">Solution</h3>
162
+ <div id="answerContent" class="prose max-w-none text-gray-700"></div>
163
+ </div>
164
+ </div>
165
+ </div>
166
+ </div>
167
+
168
+ <script>
169
+ document.addEventListener('DOMContentLoaded', () => {
170
+ const form = document.getElementById('problemForm');
171
+ const imageInput = document.getElementById('imageInput');
172
+ const loader = document.getElementById('loader');
173
+ const solutionDiv = document.getElementById('solution');
174
+ const thoughtsContent = document.getElementById('thoughtsContent');
175
+ const answerContent = document.getElementById('answerContent');
176
+ const thoughtsToggle = document.getElementById('thoughtsToggle');
177
+ const thoughtsBox = document.getElementById('thoughtsBox');
178
+ const imagePreview = document.getElementById('imagePreview');
179
+ const previewImage = document.getElementById('previewImage');
180
+ const timestamp = document.getElementById('timestamp');
181
+
182
+ let startTime = null;
183
+ let timerInterval = null;
184
+
185
+ function updateTimestamp() {
186
+ if (startTime) {
187
+ const elapsed = Math.floor((Date.now() - startTime) / 1000);
188
+ timestamp.textContent = elapsed + "s";
189
+ }
190
+ }
191
+
192
+ function startTimer() {
193
+ startTime = Date.now();
194
+ timerInterval = setInterval(updateTimestamp, 1000);
195
+ updateTimestamp();
196
+ }
197
+
198
+ function stopTimer() {
199
+ if (timerInterval) {
200
+ clearInterval(timerInterval);
201
+ timerInterval = null;
202
+ }
203
+ startTime = null;
204
+ timestamp.textContent = "";
205
+ }
206
+
207
+ thoughtsToggle.addEventListener('click', () => {
208
+ thoughtsBox.classList.toggle('open');
209
+ thoughtsToggle.querySelector('svg').classList.toggle('rotate-180');
210
+ });
211
+
212
+ imageInput.addEventListener('change', function(e) {
213
+ const file = this.files[0];
214
+ if (file) {
215
+ const reader = new FileReader();
216
+ reader.onload = function(e) {
217
+ previewImage.src = e.target.result;
218
+ imagePreview.classList.remove('hidden');
219
+ }
220
+ reader.readAsDataURL(file);
221
+ } else {
222
+ previewImage.src = "";
223
+ imagePreview.classList.add('hidden');
224
+ }
225
+ });
226
+
227
+ const dropZone = document.querySelector('.uploadArea');
228
+
229
+ ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
230
+ dropZone.addEventListener(eventName, preventDefaults, false);
231
+ });
232
+
233
+ function preventDefaults(e) {
234
+ e.preventDefault();
235
+ e.stopPropagation();
236
+ }
237
+
238
+ ['dragenter', 'dragover'].forEach(eventName => {
239
+ dropZone.addEventListener(eventName, highlight, false);
240
+ });
241
+
242
+ ['dragleave', 'drop'].forEach(eventName => {
243
+ dropZone.addEventListener(eventName, unhighlight, false);
244
+ });
245
+
246
+ function highlight(e) {
247
+ dropZone.classList.add('border-blue-400');
248
+ }
249
+
250
+ function unhighlight(e) {
251
+ dropZone.classList.remove('border-blue-400');
252
+ }
253
+
254
+ dropZone.addEventListener('drop', handleDrop, false);
255
+
256
+ function handleDrop(e) {
257
+ const dt = e.dataTransfer;
258
+ const files = dt.files;
259
+
260
+ if (files.length) {
261
+ imageInput.files = files;
262
+ const file = files[0];
263
+ const reader = new FileReader();
264
+ reader.onload = function(e) {
265
+ previewImage.src = e.target.result;
266
+ imagePreview.classList.remove('hidden');
267
+ }
268
+ reader.readAsDataURL(file);
269
+ }
270
+ }
271
+
272
+ form.addEventListener('submit', async (event) => {
273
+ event.preventDefault();
274
+ const file = imageInput.files[0];
275
+ if (!file) {
276
+ alert('Veuillez sélectionner une image.');
277
+ return;
278
+ }
279
+
280
+ startTimer();
281
+
282
+ loader.classList.remove('hidden');
283
+ solutionDiv.classList.add('hidden');
284
+ thoughtsContent.innerHTML = '';
285
+ answerContent.innerHTML = '';
286
+ thoughtsBox.classList.add('open');
287
+
288
+ const formData = new FormData();
289
+ formData.append('image', file);
290
+
291
+ try {
292
+ let currentMode = null;
293
+ const response = await fetch('/solve', {
294
+ method: 'POST',
295
+ body: formData
296
+ });
297
+
298
+ const reader = response.body.getReader();
299
+ const decoder = new TextDecoder();
300
+ let buffer = '';
301
+
302
+ while (true) {
303
+ const { done, value } = await reader.read();
304
+ if (done) {
305
+ stopTimer();
306
+ break;
307
+ }
308
+
309
+ buffer += decoder.decode(value, { stream: true });
310
+ let eolIndex;
311
+
312
+ while ((eolIndex = buffer.indexOf('\n\n')) >= 0) {
313
+ const line = buffer.slice(0, eolIndex).trim();
314
+ buffer = buffer.slice(eolIndex + 2);
315
+
316
+ if (line.startsWith('data:')) {
317
+ const data = JSON.parse(line.slice(5));
318
+
319
+ if (data.mode) {
320
+ currentMode = data.mode;
321
+ loader.classList.add('hidden');
322
+ solutionDiv.classList.remove('hidden');
323
+ }
324
+
325
+ if (data.content) {
326
+ const content = data.content;
327
+ if (currentMode === 'thinking') {
328
+ thoughtsContent.innerHTML += `<p>${content}</p>`;
329
+ thoughtsContent.scrollTop = thoughtsContent.scrollHeight;
330
+ } else if (currentMode === 'answering') {
331
+ answerContent.innerHTML += content;
332
+ if (window.MathJax) {
333
+ MathJax.typesetPromise([answerContent]).catch((err) => console.log('MathJax error:', err));
334
+ }
335
+ }
336
+ }
337
+ }
338
+ }
339
+ }
340
+
341
+ } catch (error) {
342
+ console.error('Erreur:', error);
343
+ alert('Une erreur est survenue lors du traitement de la requête.');
344
+ loader.classList.add('hidden');
345
+ stopTimer();
346
+ }
347
+ });
348
+ });
349
+ </script>
350
+ </body>
351
+ </html>