Javare commited on
Commit
ace16dd
·
verified ·
1 Parent(s): 868778b

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +65 -140
index.html CHANGED
@@ -7,122 +7,36 @@
7
 
8
  <script type="module" crossorigin src="/assets/index-Btti6dN2.js"></script>
9
  <link rel="stylesheet" crossorigin href="/assets/index-CjAcR-nm.css">
10
-
11
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
12
 
13
  <style>
14
- /* Style du panneau flottant à droite */
15
  .benchmark-sidebar {
16
- position: fixed;
17
- top: 0;
18
- right: 0;
19
- width: 380px;
20
- height: 100vh;
21
- background: #ffffff;
22
- box-shadow: -4px 0 25px rgba(0,0,0,0.15);
23
- z-index: 999999; /* S'assure de passer au-dessus de l'IA */
24
- font-family: system-ui, -apple-system, sans-serif;
25
- display: flex;
26
- flex-direction: column;
27
- color: #2d3748;
28
- border-left: 1px solid #e2e8f0;
29
- }
30
-
31
- .benchmark-header {
32
- background: #1a202c;
33
- color: white;
34
- padding: 15px;
35
- text-align: center;
36
- margin: 0;
37
- font-size: 1.2rem;
38
- }
39
-
40
- .benchmark-content {
41
- padding: 20px;
42
- overflow-y: auto;
43
- flex: 1;
44
- }
45
-
46
- .form-group {
47
- margin-bottom: 12px;
48
- display: flex;
49
- flex-direction: column;
50
- gap: 4px;
51
- }
52
-
53
- .form-group label {
54
- font-size: 0.85rem;
55
- font-weight: 600;
56
- color: #4a5568;
57
- }
58
-
59
- .form-group input, .form-group select {
60
- padding: 8px 12px;
61
- border: 1px solid #cbd5e0;
62
- border-radius: 6px;
63
- font-size: 0.9rem;
64
- background: #f7fafc;
65
- }
66
-
67
- .power-selector {
68
- display: flex;
69
- gap: 10px;
70
- margin-top: 4px;
71
- }
72
-
73
- .power-btn {
74
- flex: 1;
75
- padding: 10px;
76
- border: 2px solid #e2e8f0;
77
- border-radius: 6px;
78
- background: #fff;
79
- cursor: pointer;
80
- font-weight: bold;
81
- transition: all 0.2s;
82
- font-size: 0.85rem;
83
- }
84
-
85
- .power-btn.active {
86
- border-color: #3182ce;
87
- background: #ebf8ff;
88
- color: #2b6cb0;
89
- }
90
-
91
- /* Style du tableau des scores */
92
- .leaderboard-table {
93
- width: 100%;
94
- border-collapse: collapse;
95
- margin-top: 15px;
96
- font-size: 0.85rem;
97
- }
98
-
99
- .leaderboard-table th, .leaderboard-table td {
100
- padding: 8px;
101
- text-align: left;
102
- border-bottom: 1px solid #e2e8f0;
103
- }
104
-
105
- .leaderboard-table th {
106
- background-color: #edf2f7;
107
- font-weight: 700;
108
- }
109
-
110
- .badge-top {
111
- background: #ecc94b;
112
- color: #744210;
113
- padding: 1px 4px;
114
- border-radius: 4px;
115
- font-weight: bold;
116
- }
117
-
118
- /* Ajustement pour que l'application principale ne soit pas cachée derrière le panneau */
119
- body {
120
- margin-right: 380px !important;
121
- }
122
  </style>
123
 
124
  <script>
125
  let selectedPower = '🔌 Secteur';
 
 
126
  let maxTpsRecorded = 0;
127
  let tokenLabels = [];
128
  let tpsData = [];
@@ -133,7 +47,7 @@
133
  document.getElementById('btnBatterie').classList.toggle('active', type === '🔋 Batterie');
134
  }
135
 
136
- // Interception magique du Web Worker pour le graphique et les performances
137
  const OriginalWorker = window.Worker;
138
  window.Worker = function(...args) {
139
  const worker = new OriginalWorker(...args);
@@ -142,6 +56,8 @@
142
  const data = e.data;
143
 
144
  if (data && data.status === 'start') {
 
 
145
  maxTpsRecorded = 0;
146
  tokenLabels = [];
147
  tpsData = [];
@@ -153,11 +69,17 @@
153
  }
154
 
155
  if (data && data.status === 'update' && data.tps !== undefined) {
156
- if (data.tps > maxTpsRecorded) {
157
- maxTpsRecorded = data.tps;
 
 
 
 
 
158
  }
159
- tokenLabels.push(data.numTokens);
160
- tpsData.push(parseFloat(data.tps.toFixed(2)));
 
161
  if (window.tpsChart) {
162
  window.tpsChart.data.labels = tokenLabels;
163
  window.tpsChart.data.datasets[0].data = tpsData;
@@ -165,60 +87,63 @@
165
  }
166
  }
167
 
168
- // Envoi automatique du score à l'API globale en fin de génération
169
  if (data && data.status === 'complete') {
170
- saveScore(maxTpsRecorded);
 
 
 
 
 
 
 
171
  }
172
  });
173
 
174
  return worker;
175
  };
176
 
177
- // Appels API vers le serveur Python (FastAPI)
178
  async function loadLeaderboard() {
179
  try {
180
  const response = await fetch('/api/scores');
181
  const scores = await response.json();
182
-
183
  const tbody = document.getElementById('leaderboardBody');
184
  tbody.innerHTML = '';
185
 
186
  if(!scores || scores.length === 0) {
187
- tbody.innerHTML = '<tr><td colspan="4" style="text-align:center; color:#888;">Aucun score global.</td></tr>';
188
  return;
189
  }
190
 
191
  scores.forEach((item, index) => {
192
  const row = document.createElement('tr');
193
  const isTop3 = index < 3 ? `<span class="badge-top">🥇 ${index + 1}</span>` : index + 1;
 
194
  row.innerHTML = `
195
  <td>${isTop3}</td>
196
- <td><strong>${item.config}</strong><br><small style="color:#718096">${item.browser} • ${item.power}</small></td>
197
- <td style="color: #2b6cb0; font-weight: bold; text-align: right;">${item.score.toFixed(1)} tps</td>
 
 
198
  `;
199
  tbody.appendChild(row);
200
  });
201
  } catch (error) {
202
- console.error("Erreur classement global:", error);
203
  }
204
  }
205
 
206
- async function saveScore(finalScore) {
207
- if (finalScore <= 0) return;
208
-
209
  const type = document.getElementById('deviceType').value;
210
  const model = document.getElementById('deviceModel').value || "Inconnu";
211
  const os = document.getElementById('osType').value;
212
  const browser = document.getElementById('browserType').value;
213
 
214
- // Structure propre de la configuration de l'appareil
215
  const configString = `${type} [${os}] (${model})`;
216
 
217
  const payload = {
218
- config: configString,
219
- browser: browser,
220
- power: selectedPower,
221
- score: finalScore
222
  };
223
 
224
  try {
@@ -235,11 +160,10 @@
235
 
236
  document.addEventListener("DOMContentLoaded", () => {
237
  loadLeaderboard();
238
-
239
  const ctx = document.getElementById('stressTestChart').getContext('2d');
240
  window.tpsChart = new Chart(ctx, {
241
  type: 'line',
242
- data: { labels: [], datasets: [{ label: 'Tokens/Sec', data: [], borderColor: '#3182ce', tension: 0.1, pointRadius: 0, borderWidth: 2 }] },
243
  options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: true } } }
244
  });
245
  });
@@ -256,7 +180,7 @@
256
  <div class="form-group">
257
  <label>Type d'appareil</label>
258
  <select id="deviceType">
259
- <option value="💻 UC (Bureau)">💻 UC (Bureau)</option>
260
  <option value="💻 Laptop">💻 Laptop</option>
261
  <option value="🖥️ All in One">🖥️ All in One</option>
262
  <option value="📱 Tablette">📱 Tablette</option>
@@ -266,7 +190,7 @@
266
 
267
  <div class="form-group">
268
  <label>Modèle (CPU / GPU / Modèle exact)</label>
269
- <input type="text" id="deviceModel" placeholder="Ex: RTX 4070 / Apple M3 / Galaxy S24" required>
270
  </div>
271
 
272
  <div class="form-group">
@@ -300,20 +224,21 @@
300
  </div>
301
  </div>
302
 
303
- <hr style="border: 0; border-top: 1px solid #e2e8f0; margin: 15px 0;">
304
 
305
- <label style="font-size: 0.85rem; font-weight: 600; color: #4a5568; display:block; margin-bottom:5px;">Performances graphiques (tps)</label>
306
- <div style="height: 140px; position: relative; margin-bottom: 20px;">
307
  <canvas id="stressTestChart"></canvas>
308
  </div>
309
 
310
- <h4 style="margin: 15px 0 5px 0; color: #1a202c;">🏆 TOP 10 Global</h4>
311
  <table class="leaderboard-table">
312
  <thead>
313
  <tr>
314
- <th>Rang</th>
315
- <th>Configuration</th>
316
- <th style="text-align: right;">Vitesse</th>
 
 
317
  </tr>
318
  </thead>
319
  <tbody id="leaderboardBody">
 
7
 
8
  <script type="module" crossorigin src="/assets/index-Btti6dN2.js"></script>
9
  <link rel="stylesheet" crossorigin href="/assets/index-CjAcR-nm.css">
 
10
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
11
 
12
  <style>
 
13
  .benchmark-sidebar {
14
+ position: fixed; top: 0; right: 0; width: 420px; height: 100vh;
15
+ background: #ffffff; box-shadow: -4px 0 25px rgba(0,0,0,0.15);
16
+ z-index: 999999; font-family: system-ui, -apple-system, sans-serif;
17
+ display: flex; flex-direction: column; color: #2d3748; border-left: 1px solid #e2e8f0;
18
+ }
19
+ .benchmark-header { background: #1a202c; color: white; padding: 15px; text-align: center; margin: 0; font-size: 1.2rem; }
20
+ .benchmark-content { padding: 15px; overflow-y: auto; flex: 1; }
21
+ .form-group { margin-bottom: 10px; display: flex; flex-direction: column; gap: 4px; }
22
+ .form-group label { font-size: 0.85rem; font-weight: 600; color: #4a5568; }
23
+ .form-group input, .form-group select { padding: 8px 12px; border: 1px solid #cbd5e0; border-radius: 6px; font-size: 0.9rem; background: #f7fafc; }
24
+ .power-selector { display: flex; gap: 10px; margin-top: 4px; }
25
+ .power-btn { flex: 1; padding: 10px; border: 2px solid #e2e8f0; border-radius: 6px; background: #fff; cursor: pointer; font-weight: bold; font-size: 0.85rem; display: flex; justify-content: center; gap: 6px; }
26
+ .power-btn.active { border-color: #3182ce; background: #ebf8ff; color: #2b6cb0; }
27
+
28
+ .leaderboard-table { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: 0.78rem; }
29
+ .leaderboard-table th, .leaderboard-table td { padding: 6px 4px; text-align: left; border-bottom: 1px solid #e2e8f0; }
30
+ .leaderboard-table th { background-color: #edf2f7; font-weight: 700; color: #4a5568; }
31
+ .badge-top { background: #ecc94b; color: #744210; padding: 1px 4px; border-radius: 4px; font-weight: bold; }
32
+ .text-muted { color: #718096; font-size: 0.72rem; }
33
+ body { margin-right: 420px !important; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  </style>
35
 
36
  <script>
37
  let selectedPower = '🔌 Secteur';
38
+ let startTime = 0;
39
+ let minTpsRecorded = Infinity;
40
  let maxTpsRecorded = 0;
41
  let tokenLabels = [];
42
  let tpsData = [];
 
47
  document.getElementById('btnBatterie').classList.toggle('active', type === '🔋 Batterie');
48
  }
49
 
50
+ // Interception du Web Worker
51
  const OriginalWorker = window.Worker;
52
  window.Worker = function(...args) {
53
  const worker = new OriginalWorker(...args);
 
56
  const data = e.data;
57
 
58
  if (data && data.status === 'start') {
59
+ startTime = performance.now();
60
+ minTpsRecorded = Infinity;
61
  maxTpsRecorded = 0;
62
  tokenLabels = [];
63
  tpsData = [];
 
69
  }
70
 
71
  if (data && data.status === 'update' && data.tps !== undefined) {
72
+ const currentTps = data.tps;
73
+ const currentTokens = data.numTokens;
74
+
75
+ // On commence à enregistrer min/max après 5 tokens pour éviter le lag de départ
76
+ if (currentTokens > 5) {
77
+ if (currentTps > maxTpsRecorded) maxTpsRecorded = currentTps;
78
+ if (currentTps < minTpsRecorded) minTpsRecorded = currentTps;
79
  }
80
+
81
+ tokenLabels.push(currentTokens);
82
+ tpsData.push(parseFloat(currentTps.toFixed(2)));
83
  if (window.tpsChart) {
84
  window.tpsChart.data.labels = tokenLabels;
85
  window.tpsChart.data.datasets[0].data = tpsData;
 
87
  }
88
  }
89
 
 
90
  if (data && data.status === 'complete') {
91
+ const totalTime = (performance.now() - startTime) / 1000;
92
+ const totalTokens = data.numTokens || tokenLabels.length;
93
+ const finalAvgTps = totalTokens / totalTime;
94
+
95
+ if (minTpsRecorded === Infinity) minTpsRecorded = finalAvgTps;
96
+
97
+ // Envoi des statistiques complètes au serveur
98
+ saveScore(minTpsRecorded, maxTpsRecorded, finalAvgTps, totalTokens, totalTime);
99
  }
100
  });
101
 
102
  return worker;
103
  };
104
 
 
105
  async function loadLeaderboard() {
106
  try {
107
  const response = await fetch('/api/scores');
108
  const scores = await response.json();
 
109
  const tbody = document.getElementById('leaderboardBody');
110
  tbody.innerHTML = '';
111
 
112
  if(!scores || scores.length === 0) {
113
+ tbody.innerHTML = '<tr><td colspan="5" style="text-align:center; color:#888;">Aucun score.</td></tr>';
114
  return;
115
  }
116
 
117
  scores.forEach((item, index) => {
118
  const row = document.createElement('tr');
119
  const isTop3 = index < 3 ? `<span class="badge-top">🥇 ${index + 1}</span>` : index + 1;
120
+
121
  row.innerHTML = `
122
  <td>${isTop3}</td>
123
+ <td><strong>${item.config}</strong><br><span class="text-muted">${item.browser} • ${item.power}</span></td>
124
+ <td>Min: ${item.min_tps.toFixed(1)}<br>Max: <strong>${item.max_tps.toFixed(1)}</strong></td>
125
+ <td style="color: #2b6cb0; font-weight: bold;">${item.avg_tps.toFixed(1)} tps</td>
126
+ <td>${item.total_tokens} tok<br><span class="text-muted">en ${item.duration.toFixed(1)}s</span></td>
127
  `;
128
  tbody.appendChild(row);
129
  });
130
  } catch (error) {
131
+ console.error("Erreur chargement classement:", error);
132
  }
133
  }
134
 
135
+ async function saveScore(minTps, maxTps, avgTps, totalTokens, duration) {
 
 
136
  const type = document.getElementById('deviceType').value;
137
  const model = document.getElementById('deviceModel').value || "Inconnu";
138
  const os = document.getElementById('osType').value;
139
  const browser = document.getElementById('browserType').value;
140
 
 
141
  const configString = `${type} [${os}] (${model})`;
142
 
143
  const payload = {
144
+ config: configString, browser: browser, power: selectedPower,
145
+ min_tps: minTps, max_tps: maxTps, avg_tps: avgTps,
146
+ total_tokens: parseInt(totalTokens), duration: parseFloat(duration)
 
147
  };
148
 
149
  try {
 
160
 
161
  document.addEventListener("DOMContentLoaded", () => {
162
  loadLeaderboard();
 
163
  const ctx = document.getElementById('stressTestChart').getContext('2d');
164
  window.tpsChart = new Chart(ctx, {
165
  type: 'line',
166
+ data: { labels: [], datasets: [{ label: 'tps', data: [], borderColor: '#3182ce', tension: 0.1, pointRadius: 0, borderWidth: 2 }] },
167
  options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: true } } }
168
  });
169
  });
 
180
  <div class="form-group">
181
  <label>Type d'appareil</label>
182
  <select id="deviceType">
183
+ <option value="🖥️ UC (Bureau)">🖥️ UC (Bureau)</option>
184
  <option value="💻 Laptop">💻 Laptop</option>
185
  <option value="🖥️ All in One">🖥️ All in One</option>
186
  <option value="📱 Tablette">📱 Tablette</option>
 
190
 
191
  <div class="form-group">
192
  <label>Modèle (CPU / GPU / Modèle exact)</label>
193
+ <input type="text" id="deviceModel" placeholder="Ex: RTX 4070 / Apple M3 / Galaxy S26" required>
194
  </div>
195
 
196
  <div class="form-group">
 
224
  </div>
225
  </div>
226
 
227
+ <hr style="border: 0; border-top: 1px solid #e2e8f0; margin: 10px 0;">
228
 
229
+ <div style="height: 110px; position: relative; margin-bottom: 10px;">
 
230
  <canvas id="stressTestChart"></canvas>
231
  </div>
232
 
233
+ <h4 style="margin: 10px 0 5px 0; color: #1a202c;">🏆 TOP 10 Global</h4>
234
  <table class="leaderboard-table">
235
  <thead>
236
  <tr>
237
+ <th style="width: 8%">Rg</th>
238
+ <th style="width: 42%">Configuration</th>
239
+ <th style="width: 20%">TPS (Min/Max)</th>
240
+ <th style="width: 15%">Moyenne</th>
241
+ <th style="width: 15%">Tokens/Tps</th>
242
  </tr>
243
  </thead>
244
  <tbody id="leaderboardBody">