Update ai-check.html
Browse files- ai-check.html +62 -93
ai-check.html
CHANGED
|
@@ -228,8 +228,8 @@
|
|
| 228 |
Ideal for anyone curious about AI detection or building their own detector interface.
|
| 229 |
</p>
|
| 230 |
|
| 231 |
-
<div class="grid md:grid-cols-3 gap-5 mt-3
|
| 232 |
-
<div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-4">
|
| 233 |
<div class="flex items-center gap-3 mb-2">
|
| 234 |
<div class="w-9 h-9 rounded-full bg-sky-500/20 flex items-center justify-center">
|
| 235 |
<span class="text-lg">π</span>
|
|
@@ -241,7 +241,7 @@
|
|
| 241 |
</p>
|
| 242 |
</div>
|
| 243 |
|
| 244 |
-
<div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-4">
|
| 245 |
<div class="flex items-center gap-3 mb-2">
|
| 246 |
<div class="w-9 h-9 rounded-full bg-amber-500/20 flex items-center justify-center">
|
| 247 |
<span class="text-lg">π§βπ«</span>
|
|
@@ -253,7 +253,7 @@
|
|
| 253 |
</p>
|
| 254 |
</div>
|
| 255 |
|
| 256 |
-
<div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-4">
|
| 257 |
<div class="flex items-center gap-3 mb-2">
|
| 258 |
<div class="w-9 h-9 rounded-full bg-rose-500/20 flex items-center justify-center">
|
| 259 |
<span class="text-lg">π»</span>
|
|
@@ -267,53 +267,6 @@
|
|
| 267 |
</div>
|
| 268 |
</section>
|
| 269 |
|
| 270 |
-
<section class="mt-10 space-y-4">
|
| 271 |
-
<h2 class="text-xl md:text-2xl font-semibold">How does this AI content checker work?</h2>
|
| 272 |
-
<p class="text-sm text-slate-300">
|
| 273 |
-
The scoring is intentionally simple, so you can read the JavaScript and fully understand it.
|
| 274 |
-
</p>
|
| 275 |
-
|
| 276 |
-
<div class="grid md:grid-cols-3 gap-5 mt-3 text-xs">
|
| 277 |
-
<div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-4">
|
| 278 |
-
<div class="flex items-center gap-3 mb-2">
|
| 279 |
-
<div class="w-9 h-9 rounded-full bg-fuchsia-500/20 flex items-center justify-center">
|
| 280 |
-
<span class="text-lg">1οΈβ£</span>
|
| 281 |
-
</div>
|
| 282 |
-
<p class="font-semibold text-sm">Tokenise the text</p>
|
| 283 |
-
</div>
|
| 284 |
-
<p>
|
| 285 |
-
Text is lower-cased and split into words and sentences for basic statistics.
|
| 286 |
-
</p>
|
| 287 |
-
</div>
|
| 288 |
-
|
| 289 |
-
<div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-4">
|
| 290 |
-
<div class="flex items-center gap-3 mb-2">
|
| 291 |
-
<div class="w-9 h-9 rounded-full bg-indigo-500/20 flex items-center justify-center">
|
| 292 |
-
<span class="text-lg">2οΈβ£</span>
|
| 293 |
-
</div>
|
| 294 |
-
<p class="font-semibold text-sm">Measure patterns</p>
|
| 295 |
-
</div>
|
| 296 |
-
<p>
|
| 297 |
-
It looks at vocabulary variety and average sentence length β long, repetitive text can
|
| 298 |
-
look more AI-like.
|
| 299 |
-
</p>
|
| 300 |
-
</div>
|
| 301 |
-
|
| 302 |
-
<div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-4">
|
| 303 |
-
<div class="flex items-center gap-3 mb-2">
|
| 304 |
-
<div class="w-9 h-9 rounded-full bg-emerald-500/20 flex items-center justify-center">
|
| 305 |
-
<span class="text-lg">3οΈβ£</span>
|
| 306 |
-
</div>
|
| 307 |
-
<p class="font-semibold text-sm">Compute a score</p>
|
| 308 |
-
</div>
|
| 309 |
-
<p>
|
| 310 |
-
Those metrics are combined into an AI-generated probability (0β100%), displayed and
|
| 311 |
-
saved in your PDF report.
|
| 312 |
-
</p>
|
| 313 |
-
</div>
|
| 314 |
-
</div>
|
| 315 |
-
</section>
|
| 316 |
-
|
| 317 |
<section class="mt-12">
|
| 318 |
<h2 class="text-xl md:text-2xl font-semibold mb-3">Reviews for this AI checker</h2>
|
| 319 |
<div class="bg-slate-900/80 border border-slate-800 rounded-2xl p-5 md:p-6 relative overflow-hidden">
|
|
@@ -349,11 +302,10 @@
|
|
| 349 |
window.location.href = "login.html";
|
| 350 |
}
|
| 351 |
|
| 352 |
-
// jsPDF helper
|
| 353 |
function getJsPDF() {
|
| 354 |
if (window.jspdf && window.jspdf.jsPDF) return window.jspdf.jsPDF;
|
| 355 |
if (window.jsPDF) return window.jsPDF;
|
| 356 |
-
alert("PDF library (jsPDF) did not load. Check your internet connection or CDN access.");
|
| 357 |
return null;
|
| 358 |
}
|
| 359 |
|
|
@@ -545,7 +497,8 @@
|
|
| 545 |
word_count: wc,
|
| 546 |
avg_sentence_length: avg,
|
| 547 |
summary,
|
| 548 |
-
text: textarea.value
|
|
|
|
| 549 |
};
|
| 550 |
} catch (err) {
|
| 551 |
console.error(err);
|
|
@@ -556,55 +509,71 @@
|
|
| 556 |
}
|
| 557 |
};
|
| 558 |
|
| 559 |
-
//
|
| 560 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 561 |
if (!lastResult) {
|
| 562 |
alert("Run at least one scan before downloading a report.");
|
| 563 |
return;
|
| 564 |
}
|
| 565 |
|
| 566 |
-
const
|
| 567 |
-
|
| 568 |
-
|
| 569 |
-
|
| 570 |
-
|
| 571 |
-
|
| 572 |
-
|
| 573 |
-
|
| 574 |
-
|
| 575 |
-
|
| 576 |
-
|
| 577 |
-
|
| 578 |
-
|
| 579 |
-
|
| 580 |
-
|
| 581 |
-
|
| 582 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 583 |
|
| 584 |
-
|
| 585 |
-
|
| 586 |
-
|
|
|
|
| 587 |
|
| 588 |
-
|
| 589 |
-
|
| 590 |
-
|
| 591 |
-
|
| 592 |
-
|
| 593 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 594 |
}
|
| 595 |
-
|
| 596 |
-
doc.setFontSize(11);
|
| 597 |
-
doc.text("--- Original text (truncated) ---", 40, y); y += 18;
|
| 598 |
-
const original = lastResult.text || "";
|
| 599 |
-
const truncated = original.length > 4000 ? original.slice(0, 4000) + "\n\n[TRUNCATED]" : original;
|
| 600 |
-
const textLines = doc.splitTextToSize(truncated, 520);
|
| 601 |
-
doc.setFontSize(10);
|
| 602 |
-
doc.text(textLines, 40, y);
|
| 603 |
-
|
| 604 |
-
doc.save("truewrite-ai-report.pdf");
|
| 605 |
};
|
| 606 |
|
| 607 |
-
// Reviews slider
|
|
|
|
| 608 |
const reviews = [
|
| 609 |
{
|
| 610 |
name: "Aarav S.",
|
|
|
|
| 228 |
Ideal for anyone curious about AI detection or building their own detector interface.
|
| 229 |
</p>
|
| 230 |
|
| 231 |
+
<div class="grid md:grid-cols-3 gap-5 mt-3">
|
| 232 |
+
<div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-4 text-xs">
|
| 233 |
<div class="flex items-center gap-3 mb-2">
|
| 234 |
<div class="w-9 h-9 rounded-full bg-sky-500/20 flex items-center justify-center">
|
| 235 |
<span class="text-lg">π</span>
|
|
|
|
| 241 |
</p>
|
| 242 |
</div>
|
| 243 |
|
| 244 |
+
<div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-4 text-xs">
|
| 245 |
<div class="flex items-center gap-3 mb-2">
|
| 246 |
<div class="w-9 h-9 rounded-full bg-amber-500/20 flex items-center justify-center">
|
| 247 |
<span class="text-lg">π§βπ«</span>
|
|
|
|
| 253 |
</p>
|
| 254 |
</div>
|
| 255 |
|
| 256 |
+
<div class="bg-slate-900/70 border border-slate-800 rounded-2xl p-4 text-xs">
|
| 257 |
<div class="flex items-center gap-3 mb-2">
|
| 258 |
<div class="w-9 h-9 rounded-full bg-rose-500/20 flex items-center justify-center">
|
| 259 |
<span class="text-lg">π»</span>
|
|
|
|
| 267 |
</div>
|
| 268 |
</section>
|
| 269 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 270 |
<section class="mt-12">
|
| 271 |
<h2 class="text-xl md:text-2xl font-semibold mb-3">Reviews for this AI checker</h2>
|
| 272 |
<div class="bg-slate-900/80 border border-slate-800 rounded-2xl p-5 md:p-6 relative overflow-hidden">
|
|
|
|
| 302 |
window.location.href = "login.html";
|
| 303 |
}
|
| 304 |
|
| 305 |
+
// jsPDF helper (kept for backwards compatibility β not used for server PDF)
|
| 306 |
function getJsPDF() {
|
| 307 |
if (window.jspdf && window.jspdf.jsPDF) return window.jspdf.jsPDF;
|
| 308 |
if (window.jsPDF) return window.jsPDF;
|
|
|
|
| 309 |
return null;
|
| 310 |
}
|
| 311 |
|
|
|
|
| 497 |
word_count: wc,
|
| 498 |
avg_sentence_length: avg,
|
| 499 |
summary,
|
| 500 |
+
text: textarea.value,
|
| 501 |
+
file: file || null
|
| 502 |
};
|
| 503 |
} catch (err) {
|
| 504 |
console.error(err);
|
|
|
|
| 509 |
}
|
| 510 |
};
|
| 511 |
|
| 512 |
+
// Helper to parse filename from Content-Disposition
|
| 513 |
+
function filenameFromContentDisposition(header) {
|
| 514 |
+
if (!header) return null;
|
| 515 |
+
// Try utf-8 filename* then filename
|
| 516 |
+
const fnStar = header.match(/filename\*\s*=\s*UTF-8''([^;]+)/i);
|
| 517 |
+
if (fnStar && fnStar[1]) return decodeURIComponent(fnStar[1].replace(/["']/g, ''));
|
| 518 |
+
const fn = header.match(/filename\s*=\s*["']?([^;"']+)["']?/i);
|
| 519 |
+
if (fn && fn[1]) return fn[1].replace(/["']/g, '');
|
| 520 |
+
return null;
|
| 521 |
+
}
|
| 522 |
+
|
| 523 |
+
// Download PDF (calls backend /report/ai or /report/ai-file)
|
| 524 |
+
downloadBtn.onclick = async () => {
|
| 525 |
if (!lastResult) {
|
| 526 |
alert("Run at least one scan before downloading a report.");
|
| 527 |
return;
|
| 528 |
}
|
| 529 |
|
| 530 |
+
const file = lastResult.file;
|
| 531 |
+
try {
|
| 532 |
+
let res;
|
| 533 |
+
if (file && !(file.type === "text/plain" || file.name.toLowerCase().endsWith(".txt"))) {
|
| 534 |
+
// POST file to /report/ai-file
|
| 535 |
+
const form = new FormData();
|
| 536 |
+
form.append("file", file, file.name);
|
| 537 |
+
res = await fetch(`${BACKEND_URL}/report/ai-file`, {
|
| 538 |
+
method: "POST",
|
| 539 |
+
headers: { "Authorization": `Bearer ${token}` },
|
| 540 |
+
body: form
|
| 541 |
+
});
|
| 542 |
+
} else {
|
| 543 |
+
// Use GET with text param (URL-encode)
|
| 544 |
+
const txt = lastResult.text || "";
|
| 545 |
+
const q = encodeURIComponent(txt);
|
| 546 |
+
res = await fetch(`${BACKEND_URL}/report/ai?text=${q}`, {
|
| 547 |
+
method: "GET",
|
| 548 |
+
headers: { "Authorization": `Bearer ${token}` }
|
| 549 |
+
});
|
| 550 |
+
}
|
| 551 |
|
| 552 |
+
if (!res.ok) {
|
| 553 |
+
const text = await res.text();
|
| 554 |
+
throw new Error(text || `Server error: ${res.status}`);
|
| 555 |
+
}
|
| 556 |
|
| 557 |
+
const blob = await res.blob();
|
| 558 |
+
const cd = res.headers.get('content-disposition');
|
| 559 |
+
const fname = filenameFromContentDisposition(cd) || "TrueWrite_AiReport.pdf";
|
| 560 |
+
|
| 561 |
+
const url = URL.createObjectURL(blob);
|
| 562 |
+
const a = document.createElement('a');
|
| 563 |
+
a.href = url;
|
| 564 |
+
a.download = fname;
|
| 565 |
+
document.body.appendChild(a);
|
| 566 |
+
a.click();
|
| 567 |
+
a.remove();
|
| 568 |
+
URL.revokeObjectURL(url);
|
| 569 |
+
} catch (err) {
|
| 570 |
+
console.error(err);
|
| 571 |
+
alert("Failed to download report: " + (err.message || err));
|
| 572 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 573 |
};
|
| 574 |
|
| 575 |
+
// Reviews slider and other UI (unchanged) ...
|
| 576 |
+
// (kept exactly as you provided)
|
| 577 |
const reviews = [
|
| 578 |
{
|
| 579 |
name: "Aarav S.",
|