Spaces:
Sleeping
Sleeping
| /** | |
| * UAIDE β Forensic Report Generator | |
| * Produces a self-contained, print-ready HTML report blob for download. | |
| */ | |
| const VERDICT_LABEL = { | |
| authentic: 'AUTHENTIC', | |
| ai_generated: 'AI-GENERATED', | |
| suspect: 'SUSPECT / INCONCLUSIVE', | |
| }; | |
| const VERDICT_COLOR = { | |
| authentic: '#00c67a', | |
| ai_generated: '#ff4757', | |
| suspect: '#f59e0b', | |
| }; | |
| const SEV_COLOR = { | |
| critical: '#ff4757', | |
| high: '#f59e0b', | |
| medium: '#7c3aed', | |
| low: '#8896ab', | |
| }; | |
| function escapeHtml(str) { | |
| return String(str ?? 'β') | |
| .replace(/&/g, '&') | |
| .replace(/</g, '<') | |
| .replace(/>/g, '>') | |
| .replace(/"/g, '"'); | |
| } | |
| function modelBreakdownRows(models) { | |
| return models.map(m => ` | |
| <tr> | |
| <td>${escapeHtml(m.model)}</td> | |
| <td class="mono">${m.score.toFixed(1)}%</td> | |
| <td> | |
| <div class="bar-track"> | |
| <div class="bar-fill" style="width:${m.score}%"></div> | |
| </div> | |
| </td> | |
| <td class="mono">${(m.weight * 100).toFixed(0)}%</td> | |
| </tr> | |
| `).join(''); | |
| } | |
| function artifactRows(artifacts) { | |
| return artifacts.map(a => ` | |
| <tr> | |
| <td><span class="sev-badge" style="background:${SEV_COLOR[a.severity]}20;color:${SEV_COLOR[a.severity]};border:1px solid ${SEV_COLOR[a.severity]}40">${a.severity.toUpperCase()}</span></td> | |
| <td><strong>${escapeHtml(a.type)}</strong></td> | |
| <td>${escapeHtml(a.detail)}</td> | |
| </tr> | |
| `).join(''); | |
| } | |
| function timelineSection(result) { | |
| if (result.type !== 'video' || !result.timeline) return ''; | |
| const segments = result.timeline.flaggedSegments.map(s => ` | |
| <tr> | |
| <td><span class="sev-badge" style="background:${SEV_COLOR[s.severity]}20;color:${SEV_COLOR[s.severity]};border:1px solid ${SEV_COLOR[s.severity]}40">${s.severity.toUpperCase()}</span></td> | |
| <td>${escapeHtml(s.reason)}</td> | |
| <td class="mono">${s.start.toFixed(1)}s β ${s.end.toFixed(1)}s</td> | |
| <td class="mono">${s.frames.length} frames</td> | |
| </tr> | |
| `).join(''); | |
| return ` | |
| <section> | |
| <h2>4. Temporal Analysis</h2> | |
| <p>Total flagged segments: <strong>${result.timeline.flaggedSegments.length}</strong> | | |
| Clean segments: <strong>${result.timeline.cleanSegments.length}</strong></p> | |
| <table> | |
| <thead> | |
| <tr><th>Severity</th><th>Anomaly</th><th>Timestamp</th><th>Frames</th></tr> | |
| </thead> | |
| <tbody>${segments}</tbody> | |
| </table> | |
| </section> | |
| `; | |
| } | |
| function metadataRows(meta) { | |
| return Object.entries(meta).map(([key, val]) => { | |
| const label = key.replace(/([A-Z])/g, ' $1').replace(/^./, s => s.toUpperCase()); | |
| return `<tr><td>${escapeHtml(label)}</td><td class="mono">${escapeHtml(val)}</td></tr>`; | |
| }).join(''); | |
| } | |
| function gradcamTable(regions) { | |
| return regions.map(r => ` | |
| <tr> | |
| <td>${escapeHtml(r.label)}</td> | |
| <td class="mono">${Math.round(r.intensity * 100)}%</td> | |
| <td> | |
| <span class="sev-badge" style="background:${r.intensity > 0.8 ? '#ff475720' : r.intensity > 0.5 ? '#f59e0b20' : '#00c67a20'}; | |
| color:${r.intensity > 0.8 ? '#ff4757' : r.intensity > 0.5 ? '#f59e0b' : '#00c67a'}; | |
| border:1px solid ${r.intensity > 0.8 ? '#ff475740' : r.intensity > 0.5 ? '#f59e0b40' : '#00c67a40'}"> | |
| ${r.intensity > 0.8 ? 'High' : r.intensity > 0.5 ? 'Medium' : 'Low'} | |
| </span> | |
| </td> | |
| <td class="mono">x:${r.x}% y:${r.y}% w:${r.w}% h:${r.h}%</td> | |
| </tr> | |
| `).join(''); | |
| } | |
| export function generateReport(result, previewUrl) { | |
| const verdictColor = VERDICT_COLOR[result.verdict]; | |
| const verdictLabel = VERDICT_LABEL[result.verdict]; | |
| const now = new Date().toUTCString(); | |
| const html = `<!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>UAIDE Forensic Report β ${escapeHtml(result.filename)}</title> | |
| <style> | |
| :root { | |
| --accent: #0066ff; | |
| --verdict: ${verdictColor}; | |
| --text: #141820; | |
| --muted: #6b7280; | |
| --border: #e2e8f0; | |
| --bg: #f8f9fc; | |
| --surface: #ffffff; | |
| } | |
| * { box-sizing: border-box; margin: 0; padding: 0; } | |
| body { | |
| font-family: 'Segoe UI', Inter, system-ui, sans-serif; | |
| background: var(--bg); | |
| color: var(--text); | |
| font-size: 13.5px; | |
| line-height: 1.65; | |
| padding: 0; | |
| } | |
| .mono { font-family: 'Cascadia Code', 'Fira Code', 'Courier New', monospace; font-size: 12.5px; } | |
| /* Cover */ | |
| .cover { | |
| background: linear-gradient(135deg, #0a0f1e 0%, #0d1930 60%, #091428 100%); | |
| color: white; | |
| padding: 56px 64px; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 0; | |
| page-break-after: always; | |
| min-height: 340px; | |
| } | |
| .cover-logo { | |
| display: flex; | |
| align-items: center; | |
| gap: 14px; | |
| margin-bottom: 36px; | |
| } | |
| .logo-mark { | |
| width: 44px; | |
| height: 44px; | |
| background: var(--accent); | |
| border-radius: 10px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-weight: 900; | |
| font-size: 17px; | |
| letter-spacing: -0.5px; | |
| color: white; | |
| flex-shrink: 0; | |
| } | |
| .logo-text { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 2px; | |
| } | |
| .logo-name { | |
| font-size: 17px; | |
| font-weight: 800; | |
| letter-spacing: -0.3px; | |
| color: white; | |
| } | |
| .logo-sub { | |
| font-size: 10px; | |
| font-weight: 500; | |
| color: rgba(255,255,255,0.45); | |
| letter-spacing: 1.2px; | |
| text-transform: uppercase; | |
| } | |
| .cover h1 { | |
| font-size: 28px; | |
| font-weight: 800; | |
| letter-spacing: -0.8px; | |
| margin-bottom: 10px; | |
| color: white; | |
| line-height: 1.2; | |
| } | |
| .cover-sub { | |
| font-size: 14px; | |
| color: rgba(255,255,255,0.55); | |
| margin-bottom: 32px; | |
| } | |
| .verdict-banner { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 10px; | |
| background: ${verdictColor}22; | |
| border: 1.5px solid ${verdictColor}55; | |
| border-radius: 10px; | |
| padding: 12px 20px; | |
| margin-bottom: 32px; | |
| } | |
| .verdict-dot { | |
| width: 10px; | |
| height: 10px; | |
| border-radius: 50%; | |
| background: ${verdictColor}; | |
| flex-shrink: 0; | |
| } | |
| .verdict-text { | |
| font-size: 22px; | |
| font-weight: 800; | |
| letter-spacing: -0.3px; | |
| color: ${verdictColor}; | |
| } | |
| .verdict-score { | |
| font-size: 13px; | |
| color: rgba(255,255,255,0.6); | |
| font-family: 'Fira Code', monospace; | |
| } | |
| .cover-meta { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 24px; | |
| margin-top: auto; | |
| padding-top: 32px; | |
| border-top: 1px solid rgba(255,255,255,0.1); | |
| } | |
| .cover-meta-item { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 3px; | |
| } | |
| .cover-meta-label { | |
| font-size: 10px; | |
| color: rgba(255,255,255,0.35); | |
| text-transform: uppercase; | |
| letter-spacing: 0.9px; | |
| font-weight: 600; | |
| } | |
| .cover-meta-value { | |
| font-size: 13px; | |
| color: rgba(255,255,255,0.85); | |
| font-family: 'Fira Code', monospace; | |
| font-weight: 500; | |
| } | |
| /* Body */ | |
| .body { | |
| padding: 48px 64px; | |
| max-width: 960px; | |
| margin: 0 auto; | |
| } | |
| section { | |
| margin-bottom: 44px; | |
| page-break-inside: avoid; | |
| } | |
| h2 { | |
| font-size: 17px; | |
| font-weight: 800; | |
| color: var(--text); | |
| letter-spacing: -0.4px; | |
| margin-bottom: 14px; | |
| padding-bottom: 10px; | |
| border-bottom: 2px solid var(--border); | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| h2::before { | |
| content: ''; | |
| width: 4px; | |
| height: 18px; | |
| background: var(--accent); | |
| border-radius: 2px; | |
| flex-shrink: 0; | |
| } | |
| h3 { | |
| font-size: 14px; | |
| font-weight: 700; | |
| color: var(--text); | |
| margin: 18px 0 10px; | |
| letter-spacing: -0.2px; | |
| } | |
| p { margin-bottom: 8px; } | |
| /* Summary grid */ | |
| .summary-grid { | |
| display: grid; | |
| grid-template-columns: repeat(3, 1fr); | |
| gap: 14px; | |
| margin-bottom: 16px; | |
| } | |
| .summary-card { | |
| background: var(--surface); | |
| border: 1px solid var(--border); | |
| border-radius: 10px; | |
| padding: 14px 16px; | |
| } | |
| .summary-card-label { | |
| font-size: 10px; | |
| font-weight: 700; | |
| color: var(--muted); | |
| text-transform: uppercase; | |
| letter-spacing: 0.7px; | |
| margin-bottom: 5px; | |
| } | |
| .summary-card-value { | |
| font-size: 22px; | |
| font-weight: 800; | |
| color: var(--text); | |
| letter-spacing: -0.5px; | |
| } | |
| .summary-card-value.verdict-val { | |
| font-size: 16px; | |
| color: var(--verdict); | |
| } | |
| /* Score arc */ | |
| .score-section { | |
| display: flex; | |
| align-items: center; | |
| gap: 28px; | |
| background: var(--surface); | |
| border: 1px solid var(--border); | |
| border-radius: 12px; | |
| padding: 20px 24px; | |
| margin-bottom: 16px; | |
| } | |
| .score-label-group { flex: 1; } | |
| .score-main { font-size: 48px; font-weight: 900; color: var(--verdict); letter-spacing: -2px; line-height: 1; } | |
| .score-unit { font-size: 18px; font-weight: 600; color: var(--muted); } | |
| .score-desc { font-size: 13px; color: var(--muted); margin-top: 6px; } | |
| /* Tables */ | |
| table { | |
| width: 100%; | |
| border-collapse: collapse; | |
| margin-top: 8px; | |
| font-size: 13px; | |
| } | |
| thead tr { | |
| background: var(--bg); | |
| } | |
| th { | |
| padding: 9px 12px; | |
| text-align: left; | |
| font-size: 10.5px; | |
| font-weight: 700; | |
| color: var(--muted); | |
| text-transform: uppercase; | |
| letter-spacing: 0.6px; | |
| border-bottom: 1.5px solid var(--border); | |
| } | |
| td { | |
| padding: 9px 12px; | |
| border-bottom: 1px solid var(--border); | |
| vertical-align: middle; | |
| color: var(--text); | |
| } | |
| tr:last-child td { border-bottom: none; } | |
| tr:nth-child(even) td { background: #fafbfd; } | |
| .bar-track { | |
| height: 6px; | |
| background: var(--border); | |
| border-radius: 99px; | |
| overflow: hidden; | |
| min-width: 80px; | |
| } | |
| .bar-fill { | |
| height: 100%; | |
| background: linear-gradient(90deg, var(--accent) 0%, #4d94ff 100%); | |
| border-radius: 99px; | |
| } | |
| .sev-badge { | |
| display: inline-block; | |
| padding: 2px 8px; | |
| border-radius: 99px; | |
| font-size: 10px; | |
| font-weight: 700; | |
| letter-spacing: 0.3px; | |
| white-space: nowrap; | |
| } | |
| /* Image preview */ | |
| .media-preview { | |
| text-align: center; | |
| background: #0e0e14; | |
| border-radius: 12px; | |
| overflow: hidden; | |
| padding: 16px; | |
| margin-bottom: 16px; | |
| } | |
| .media-preview img { | |
| max-width: 100%; | |
| max-height: 340px; | |
| border-radius: 8px; | |
| object-fit: contain; | |
| } | |
| .media-preview p { | |
| color: rgba(255,255,255,0.4); | |
| font-size: 12px; | |
| margin-top: 10px; | |
| margin-bottom: 0; | |
| font-family: monospace; | |
| } | |
| /* FFT */ | |
| .fft-grid { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 12px; | |
| } | |
| .fft-item { | |
| background: var(--surface); | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| padding: 12px 14px; | |
| } | |
| .fft-item-label { | |
| font-size: 10px; | |
| font-weight: 700; | |
| color: var(--muted); | |
| text-transform: uppercase; | |
| letter-spacing: 0.6px; | |
| margin-bottom: 4px; | |
| } | |
| .fft-item-value { | |
| font-size: 13px; | |
| font-weight: 600; | |
| color: var(--text); | |
| line-height: 1.5; | |
| } | |
| .anomaly-alert { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| background: #fff0f1; | |
| border: 1.5px solid #ff475740; | |
| border-radius: 8px; | |
| padding: 12px 16px; | |
| margin-bottom: 16px; | |
| font-size: 13px; | |
| font-weight: 600; | |
| color: #ff4757; | |
| } | |
| /* Disclaimer */ | |
| .disclaimer { | |
| background: #fffbeb; | |
| border: 1px solid #f59e0b40; | |
| border-radius: 10px; | |
| padding: 16px 20px; | |
| font-size: 12.5px; | |
| color: #92400e; | |
| line-height: 1.7; | |
| } | |
| .disclaimer strong { color: #78350f; } | |
| /* Footer */ | |
| .report-footer { | |
| background: #0a0f1e; | |
| color: rgba(255,255,255,0.4); | |
| padding: 20px 64px; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| font-size: 11px; | |
| margin-top: 60px; | |
| } | |
| .report-footer strong { color: rgba(255,255,255,0.7); } | |
| @media print { | |
| body { background: white; } | |
| .cover { page-break-after: always; } | |
| section { page-break-inside: avoid; } | |
| .body { padding: 32px 48px; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- ββ COVER PAGE βββββββββββββββββββββββββββββββββββββββββββ --> | |
| <div class="cover"> | |
| <div class="cover-logo"> | |
| <div class="logo-mark">U</div> | |
| <div class="logo-text"> | |
| <span class="logo-name">UAIDE</span> | |
| <span class="logo-sub">Unified AI Origin Detection Engine</span> | |
| </div> | |
| </div> | |
| <h1>Forensic Analysis Report</h1> | |
| <p class="cover-sub">${escapeHtml(result.filename)} Β· Analysis ID: ${escapeHtml(result.analysisId)}</p> | |
| <div class="verdict-banner"> | |
| <div class="verdict-dot"></div> | |
| <span class="verdict-text">${verdictLabel}</span> | |
| <span class="verdict-score"> β ${result.confidenceScore.toFixed(1)}% confidence</span> | |
| </div> | |
| <div class="cover-meta"> | |
| <div class="cover-meta-item"> | |
| <span class="cover-meta-label">File</span> | |
| <span class="cover-meta-value">${escapeHtml(result.filename)}</span> | |
| </div> | |
| <div class="cover-meta-item"> | |
| <span class="cover-meta-label">Type</span> | |
| <span class="cover-meta-value">${escapeHtml(result.format)}</span> | |
| </div> | |
| <div class="cover-meta-item"> | |
| <span class="cover-meta-label">Resolution</span> | |
| <span class="cover-meta-value">${escapeHtml(result.resolution)}</span> | |
| </div> | |
| <div class="cover-meta-item"> | |
| <span class="cover-meta-label">File Size</span> | |
| <span class="cover-meta-value">${escapeHtml(result.filesize)}</span> | |
| </div> | |
| <div class="cover-meta-item"> | |
| <span class="cover-meta-label">Processing Time</span> | |
| <span class="cover-meta-value">${escapeHtml(result.processingTime)}</span> | |
| </div> | |
| <div class="cover-meta-item"> | |
| <span class="cover-meta-label">Report Generated</span> | |
| <span class="cover-meta-value">${now}</span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- ββ BODY βββββββββββββββββββββββββββββββββββββββββββββββββ --> | |
| <div class="body"> | |
| <!-- 1. Executive Summary --> | |
| <section> | |
| <h2>1. Executive Summary</h2> | |
| <div class="score-section"> | |
| <div> | |
| <div class="score-main">${result.confidenceScore.toFixed(1)}<span class="score-unit">%</span></div> | |
| <div class="score-desc">AI Involvement Confidence Score</div> | |
| </div> | |
| <div class="score-label-group"> | |
| <p><strong>Verdict:</strong> <span style="color:${verdictColor};font-weight:800">${verdictLabel}</span></p> | |
| <p style="margin-top:6px;color:#6b7280;font-size:13px"> | |
| ${result.verdict === 'authentic' | |
| ? 'Multi-model ensemble analysis found no significant generative artifacts. Content is consistent with authentic human-captured media.' | |
| : result.verdict === 'ai_generated' | |
| ? 'Multi-model ensemble analysis detected strong generative artifacts consistent with GAN or diffusion model synthesis. Content is highly likely to be AI-generated.' | |
| : 'Multi-model ensemble analysis produced inconclusive results. The media exhibits some characteristics of synthetic generation but does not conclusively meet the threshold for either verdict. Manual expert review is advised.'} | |
| </p> | |
| </div> | |
| </div> | |
| <div class="summary-grid"> | |
| <div class="summary-card"> | |
| <div class="summary-card-label">Models Run</div> | |
| <div class="summary-card-value">${result.modelBreakdown.length}</div> | |
| </div> | |
| <div class="summary-card"> | |
| <div class="summary-card-label">Artifacts Found</div> | |
| <div class="summary-card-value">${result.artifacts.length}</div> | |
| </div> | |
| <div class="summary-card"> | |
| <div class="summary-card-label">Spectral Anomaly</div> | |
| <div class="summary-card-value" style="font-size:15px;color:${result.fft.spectralAnomaly ? '#ff4757' : '#00c67a'}"> | |
| ${result.fft.spectralAnomaly ? 'Detected' : 'Not Found'} | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- 2. Media Preview --> | |
| <section> | |
| <h2>2. Media Under Analysis</h2> | |
| <div class="media-preview"> | |
| ${result.type === 'image' | |
| ? `<img src="${previewUrl}" alt="Analysed media β ${escapeHtml(result.filename)}" />` | |
| : `<p style="color:rgba(255,255,255,0.5);font-size:14px;padding:40px 0">Video preview not embedded in static report<br><span style="font-size:11px">File: ${escapeHtml(result.filename)} Β· ${escapeHtml(result.duration)} Β· ${result.totalFrames} frames</span></p>` | |
| } | |
| <p>${escapeHtml(result.filename)} Β· ${escapeHtml(result.resolution)} Β· ${escapeHtml(result.filesize)}</p> | |
| </div> | |
| </section> | |
| <!-- 3. Model Ensemble Results --> | |
| <section> | |
| <h2>3. Model Ensemble Results</h2> | |
| <p>The following forensic deep learning models were run in ensemble. Each model independently scores the likelihood of AI generation; results are weighted and fused into the final confidence score.</p> | |
| <table> | |
| <thead> | |
| <tr> | |
| <th>Model</th> | |
| <th>Score</th> | |
| <th>Confidence Bar</th> | |
| <th>Weight</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| ${modelBreakdownRows(result.modelBreakdown)} | |
| </tbody> | |
| </table> | |
| </section> | |
| <!-- 4. Temporal Analysis (video only) --> | |
| ${timelineSection(result)} | |
| <!-- 5. Grad-CAM Artifact Localisation --> | |
| <section> | |
| <h2>${result.type === 'video' ? '5' : '4'}. Grad-CAM Artifact Localisation</h2> | |
| <p>Gradient-weighted Class Activation Mapping (Grad-CAM) was applied to highlight spatial regions in the media that contributed most to the AI-generation classification decision.</p> | |
| <table> | |
| <thead> | |
| <tr><th>Region</th><th>Intensity</th><th>Level</th><th>Bounding Box</th></tr> | |
| </thead> | |
| <tbody> | |
| ${gradcamTable(result.gradcam.regions)} | |
| </tbody> | |
| </table> | |
| </section> | |
| <!-- 6. Generative Fingerprints & Artifacts --> | |
| <section> | |
| <h2>${result.type === 'video' ? '6' : '5'}. Detected Artifacts & Generative Fingerprints</h2> | |
| <table> | |
| <thead> | |
| <tr><th>Severity</th><th>Type</th><th>Detail</th></tr> | |
| </thead> | |
| <tbody> | |
| ${artifactRows(result.artifacts)} | |
| </tbody> | |
| </table> | |
| </section> | |
| <!-- 7. Frequency Analysis (FFT) --> | |
| <section> | |
| <h2>${result.type === 'video' ? '7' : '6'}. Frequency Domain Analysis (FFT)</h2> | |
| ${result.fft.spectralAnomaly ? `<div class="anomaly-alert">⚠ Spectral anomaly detected in the frequency domain β a strong indicator of generative upsampling or GAN synthesis.</div>` : ''} | |
| <div class="fft-grid"> | |
| <div class="fft-item"> | |
| <div class="fft-item-label">Peak Frequency</div> | |
| <div class="fft-item-value mono">${escapeHtml(result.fft.peakFrequency)}</div> | |
| </div> | |
| <div class="fft-item"> | |
| <div class="fft-item-label">Anomaly Bands</div> | |
| <div class="fft-item-value mono">${escapeHtml(result.fft.anomalyBands.join(', '))}</div> | |
| </div> | |
| <div class="fft-item" style="grid-column: span 2"> | |
| <div class="fft-item-label">DCT Coefficients</div> | |
| <div class="fft-item-value">${escapeHtml(result.fft.dctCoefficients)}</div> | |
| </div> | |
| <div class="fft-item" style="grid-column: span 2"> | |
| <div class="fft-item-label">Noise Pattern</div> | |
| <div class="fft-item-value">${escapeHtml(result.fft.noisePattern)}</div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- 8. File Metadata --> | |
| <section> | |
| <h2>${result.type === 'video' ? '8' : '7'}. File Metadata</h2> | |
| <table> | |
| <thead><tr><th>Field</th><th>Value</th></tr></thead> | |
| <tbody>${metadataRows(result.metadata)}</tbody> | |
| </table> | |
| </section> | |
| <!-- Disclaimer --> | |
| <section> | |
| <div class="disclaimer"> | |
| <strong>Disclaimer:</strong> This report was generated automatically by UAIDE (Unified AI Origin Detection Engine) v2.4 β Research Preview. | |
| All results are probabilistic in nature and based on ensemble deep learning inference. No automated system can guarantee 100% accuracy in AI-generated content detection. | |
| These findings <strong>must be corroborated with expert human review</strong> before being used as evidence in any legal, academic, or journalistic context. | |
| UAIDE is developed for academic research and investigative purposes. | |
| <br /><br /> | |
| Report generated: ${now} Β· Analysis ID: ${escapeHtml(result.analysisId)} Β· github.com/Deshna24/UAIDE | |
| </div> | |
| </section> | |
| </div> | |
| <!-- ββ FOOTER βββββββββββββββββββββββββββββββββββββββββββββββ --> | |
| <div class="report-footer"> | |
| <div><strong>UAIDE</strong> β Unified AI Origin Detection Engine Β· Research Preview v2.4</div> | |
| <div>Analysis ID: <strong>${escapeHtml(result.analysisId)}</strong></div> | |
| <div>github.com/Deshna24/UAIDE</div> | |
| </div> | |
| </body> | |
| </html>`; | |
| return html; | |
| } | |
| export function downloadReport(result, previewUrl) { | |
| const html = generateReport(result, previewUrl); | |
| const blob = new Blob([html], { type: 'text/html;charset=utf-8' }); | |
| const url = URL.createObjectURL(blob); | |
| const a = document.createElement('a'); | |
| a.href = url; | |
| const safeName = result.filename.replace(/\.[^.]+$/, '').replace(/[^a-zA-Z0-9_-]/g, '_'); | |
| a.download = `UAIDE_Report_${safeName}_${result.analysisId}.html`; | |
| document.body.appendChild(a); | |
| a.click(); | |
| document.body.removeChild(a); | |
| setTimeout(() => URL.revokeObjectURL(url), 10000); | |
| } | |