vicliv commited on
Commit
059253d
·
1 Parent(s): f7cc3fc

changed to ai-generated score

Browse files
Files changed (1) hide show
  1. app/static/index.html +49 -48
app/static/index.html CHANGED
@@ -113,7 +113,7 @@
113
  </div>
114
 
115
  <div>
116
- <div id="verdict-text" class="text-3xl sm:text-4xl font-extrabold leading-tight text-blue-600"></div>
117
  <div id="advice-text" class="mt-3 text-lg sm:text-xl font-semibold text-gray-900"></div>
118
  <div id="frames-info" class="mt-4 text-sm text-gray-500"></div>
119
  </div>
@@ -159,25 +159,25 @@
159
  clear: "Clear",
160
  analyzing: "Analyzing...",
161
  analyzing_video: "Sampling frames and running the model...",
162
- reliability_score: "Reliability score",
163
  how_calculated: "How is this calculated?",
164
- reliability: "Reliability",
165
- verdict_low_image: "This image is likely AI-generated,",
166
- verdict_low_video: "This video is likely AI-generated,",
167
- verdict_mid_image: "We're uncertain about this image,",
168
- verdict_mid_video: "We're uncertain about this video,",
169
- verdict_high_image: "This image is likely authentic,",
170
- verdict_high_video: "This video is likely authentic,",
171
- advice_low: "you should not share it with your network.",
172
- advice_mid: "verify it from trusted sources before sharing.",
173
- advice_high: "but always cross-check important content.",
174
  analyze_another: "Analyze another file",
175
  error_generic: "Something went wrong. Please try again.",
176
  error_size: "File is too large.",
177
  error_type: "Unsupported file type.",
178
  frames_info: "Averaged over {n} frames.",
179
  how_calculated_title: "How the score is computed",
180
- how_calculated_body: "We use a Swin Transformer V2 model fine-tuned to distinguish real photographs from AI-generated images. For videos, we sample 5 frames evenly across the duration and average the model's confidence. The reliability score is 1 minus the model's probability that the content is AI-generated.",
181
  close: "Close",
182
  privacy_note: "Files are processed in memory and not stored.",
183
  },
@@ -190,25 +190,25 @@
190
  clear: "Effacer",
191
  analyzing: "Analyse en cours...",
192
  analyzing_video: "Échantillonnage des images et exécution du modèle...",
193
- reliability_score: "Score de fiabilité",
194
  how_calculated: "Comment est-ce calculé ?",
195
- reliability: "Fiabilité",
196
- verdict_low_image: "Cette image est probablement générée par IA,",
197
- verdict_low_video: "Cette vidéo est probablement générée par IA,",
198
- verdict_mid_image: "Nous ne sommes pas certains pour cette image,",
199
- verdict_mid_video: "Nous ne sommes pas certains pour cette vidéo,",
200
- verdict_high_image: "Cette image est probablement authentique,",
201
- verdict_high_video: "Cette vidéo est probablement authentique,",
202
- advice_low: "vous ne devriez pas la partager avec votre réseau.",
203
- advice_mid: "vérifiez auprès de sources fiables avant de partager.",
204
- advice_high: "vérifiez tout de même les contenus importants.",
205
  analyze_another: "Analyser un autre fichier",
206
  error_generic: "Une erreur est survenue. Veuillez réessayer.",
207
  error_size: "Le fichier est trop volumineux.",
208
  error_type: "Type de fichier non pris en charge.",
209
  frames_info: "Moyenne sur {n} images.",
210
  how_calculated_title: "Comment le score est calculé",
211
- how_calculated_body: "Nous utilisons un modèle Swin Transformer V2 entraîné pour distinguer les vraies photographies des images générées par IA. Pour les vidéos, nous échantillonnons 5 images réparties uniformément sur la durée et faisons la moyenne de la confiance du modèle. Le score de fiabilité correspond à 1 moins la probabilité estimée que le contenu soit généré par IA.",
212
  close: "Fermer",
213
  privacy_note: "Les fichiers sont traités en mémoire et ne sont pas conservés.",
214
  },
@@ -249,26 +249,26 @@
249
  applyI18n();
250
  }
251
 
252
- function getVerdict(reliability, mediaType) {
253
  const T = t();
254
- if (reliability >= 0.70) {
255
  return {
256
- verdict: mediaType === "video" ? T.verdict_high_video : T.verdict_high_image,
257
- advice: T.advice_high,
258
- tone: "high",
259
  };
260
  }
261
- if (reliability >= 0.40) {
262
  return {
263
- verdict: mediaType === "video" ? T.verdict_mid_video : T.verdict_mid_image,
264
- advice: T.advice_mid,
265
- tone: "mid",
266
  };
267
  }
268
  return {
269
- verdict: mediaType === "video" ? T.verdict_low_video : T.verdict_low_image,
270
- advice: T.advice_low,
271
- tone: "low",
272
  };
273
  }
274
 
@@ -335,18 +335,19 @@
335
 
336
  function renderResultText() {
337
  if (!state.result) return;
338
- const r = state.result.reliability;
339
- const v = getVerdict(r, state.result.media_type);
340
  $("verdict-text").textContent = v.verdict;
341
  $("advice-text").textContent = v.advice;
342
- $("reliability-pct").textContent = `${Math.round(r * 100)}%`;
343
- const arc = $("arc-fg");
344
  const tones = {
345
- high: "#16a34a",
346
- mid: "#d97706",
347
- low: "#1d4ed8",
348
  };
349
- arc.setAttribute("stroke", tones[v.tone]);
 
 
350
  if (state.result.media_type === "video") {
351
  $("frames-info").textContent = t().frames_info.replace("{n}", state.result.n_frames);
352
  } else {
@@ -354,14 +355,14 @@
354
  }
355
  }
356
 
357
- function animateArc(reliability) {
358
  const arc = $("arc-fg");
359
  arc.style.transition = "none";
360
  arc.setAttribute("stroke-dashoffset", CIRCUMFERENCE);
361
  requestAnimationFrame(() => {
362
  requestAnimationFrame(() => {
363
  arc.style.transition = "";
364
- const target = CIRCUMFERENCE * (1 - Math.max(0, Math.min(1, reliability)));
365
  arc.setAttribute("stroke-dashoffset", target);
366
  });
367
  });
@@ -399,7 +400,7 @@
399
  state.result = await res.json();
400
  renderResultText();
401
  showCard("result-card");
402
- animateArc(state.result.reliability);
403
  } catch (e) {
404
  showError(e.message);
405
  showCard("upload-card");
 
113
  </div>
114
 
115
  <div>
116
+ <div id="verdict-text" class="text-3xl sm:text-4xl font-extrabold leading-tight"></div>
117
  <div id="advice-text" class="mt-3 text-lg sm:text-xl font-semibold text-gray-900"></div>
118
  <div id="frames-info" class="mt-4 text-sm text-gray-500"></div>
119
  </div>
 
159
  clear: "Clear",
160
  analyzing: "Analyzing...",
161
  analyzing_video: "Sampling frames and running the model...",
162
+ ai_score: "AI-generated score",
163
  how_calculated: "How is this calculated?",
164
+ ai_label: "AI-generated",
165
+ verdict_ai_image: "This image is likely AI-generated,",
166
+ verdict_ai_video: "This video is likely AI-generated,",
167
+ verdict_uncertain_image: "We're uncertain about this image,",
168
+ verdict_uncertain_video: "We're uncertain about this video,",
169
+ verdict_real_image: "This image is likely authentic,",
170
+ verdict_real_video: "This video is likely authentic,",
171
+ advice_ai: "you should not share it with your network.",
172
+ advice_uncertain: "verify it from trusted sources before sharing.",
173
+ advice_real: "but always cross-check important content.",
174
  analyze_another: "Analyze another file",
175
  error_generic: "Something went wrong. Please try again.",
176
  error_size: "File is too large.",
177
  error_type: "Unsupported file type.",
178
  frames_info: "Averaged over {n} frames.",
179
  how_calculated_title: "How the score is computed",
180
+ how_calculated_body: "We use a Swin Transformer V2 model fine-tuned to distinguish real photographs from AI-generated images. For videos, we sample 5 frames evenly across the duration and average the model's confidence. The score shown is the model's estimated probability that the content was generated by AI.",
181
  close: "Close",
182
  privacy_note: "Files are processed in memory and not stored.",
183
  },
 
190
  clear: "Effacer",
191
  analyzing: "Analyse en cours...",
192
  analyzing_video: "Échantillonnage des images et exécution du modèle...",
193
+ ai_score: "Score d'IA générée",
194
  how_calculated: "Comment est-ce calculé ?",
195
+ ai_label: "IA générée",
196
+ verdict_ai_image: "Cette image est probablement générée par IA,",
197
+ verdict_ai_video: "Cette vidéo est probablement générée par IA,",
198
+ verdict_uncertain_image: "Nous ne sommes pas certains pour cette image,",
199
+ verdict_uncertain_video: "Nous ne sommes pas certains pour cette vidéo,",
200
+ verdict_real_image: "Cette image est probablement authentique,",
201
+ verdict_real_video: "Cette vidéo est probablement authentique,",
202
+ advice_ai: "vous ne devriez pas la partager avec votre réseau.",
203
+ advice_uncertain: "vérifiez auprès de sources fiables avant de partager.",
204
+ advice_real: "vérifiez tout de même les contenus importants.",
205
  analyze_another: "Analyser un autre fichier",
206
  error_generic: "Une erreur est survenue. Veuillez réessayer.",
207
  error_size: "Le fichier est trop volumineux.",
208
  error_type: "Type de fichier non pris en charge.",
209
  frames_info: "Moyenne sur {n} images.",
210
  how_calculated_title: "Comment le score est calculé",
211
+ how_calculated_body: "Nous utilisons un modèle Swin Transformer V2 entraîné pour distinguer les vraies photographies des images générées par IA. Pour les vidéos, nous échantillonnons 5 images réparties uniformément sur la durée et faisons la moyenne de la confiance du modèle. Le score affiché correspond à la probabilité estimée que le contenu ait été généré par IA.",
212
  close: "Fermer",
213
  privacy_note: "Les fichiers sont traités en mémoire et ne sont pas conservés.",
214
  },
 
249
  applyI18n();
250
  }
251
 
252
+ function getVerdict(aiScore, mediaType) {
253
  const T = t();
254
+ if (aiScore >= 0.60) {
255
  return {
256
+ verdict: mediaType === "video" ? T.verdict_ai_video : T.verdict_ai_image,
257
+ advice: T.advice_ai,
258
+ tone: "ai",
259
  };
260
  }
261
+ if (aiScore >= 0.30) {
262
  return {
263
+ verdict: mediaType === "video" ? T.verdict_uncertain_video : T.verdict_uncertain_image,
264
+ advice: T.advice_uncertain,
265
+ tone: "uncertain",
266
  };
267
  }
268
  return {
269
+ verdict: mediaType === "video" ? T.verdict_real_video : T.verdict_real_image,
270
+ advice: T.advice_real,
271
+ tone: "real",
272
  };
273
  }
274
 
 
335
 
336
  function renderResultText() {
337
  if (!state.result) return;
338
+ const score = state.result.p_fake;
339
+ const v = getVerdict(score, state.result.media_type);
340
  $("verdict-text").textContent = v.verdict;
341
  $("advice-text").textContent = v.advice;
342
+ $("score-pct").textContent = `${Math.round(score * 100)}%`;
 
343
  const tones = {
344
+ ai: "#dc2626",
345
+ uncertain: "#d97706",
346
+ real: "#16a34a",
347
  };
348
+ const color = tones[v.tone];
349
+ $("arc-fg").setAttribute("stroke", color);
350
+ $("verdict-text").style.color = color;
351
  if (state.result.media_type === "video") {
352
  $("frames-info").textContent = t().frames_info.replace("{n}", state.result.n_frames);
353
  } else {
 
355
  }
356
  }
357
 
358
+ function animateArc(fraction) {
359
  const arc = $("arc-fg");
360
  arc.style.transition = "none";
361
  arc.setAttribute("stroke-dashoffset", CIRCUMFERENCE);
362
  requestAnimationFrame(() => {
363
  requestAnimationFrame(() => {
364
  arc.style.transition = "";
365
+ const target = CIRCUMFERENCE * (1 - Math.max(0, Math.min(1, fraction)));
366
  arc.setAttribute("stroke-dashoffset", target);
367
  });
368
  });
 
400
  state.result = await res.json();
401
  renderResultText();
402
  showCard("result-card");
403
+ animateArc(state.result.p_fake);
404
  } catch (e) {
405
  showError(e.message);
406
  showCard("upload-card");