oh gott was mach ich nur
This commit is contained in:
@@ -2,26 +2,105 @@
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
// Nur im Web-Kontext (nicht in CLI-Skripten)
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Session starten
|
||||
// -----------------------------------------------------------
|
||||
if (php_sapi_name() !== 'cli') {
|
||||
// Session nur starten, wenn noch keine läuft
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
|
||||
// Optional: Session-Konfiguration vor session_start
|
||||
session_name('usbcheck_session');
|
||||
|
||||
session_set_cookie_params([
|
||||
'lifetime' => 0, // Session-Cookie
|
||||
'lifetime' => 0,
|
||||
'path' => '/',
|
||||
'domain' => '', // leer = aktuelle Domain
|
||||
'domain' => '',
|
||||
'secure' => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'),
|
||||
'httponly' => true,
|
||||
'samesite' => 'Lax', // oder 'Strict' falls du sehr streng sein willst
|
||||
'samesite' => 'Lax',
|
||||
]);
|
||||
|
||||
session_start();
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// 1) Sprache bestimmen (vor dem Laden der JSON-Dateien!)
|
||||
// -----------------------------------------------------------
|
||||
$lang = $_GET['lang'] ?? null;
|
||||
$lang = strtolower($lang);
|
||||
|
||||
if (!preg_match('/^[a-z]{2}$/', $lang)) {
|
||||
$lang = null;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// 2) Verfügbare JSON-Sprachen erkennen
|
||||
// -----------------------------------------------------------
|
||||
$i18nDir = __DIR__ . '/../public/assets/i18n';
|
||||
$langFiles = glob($i18nDir . '/*.json') ?: [];
|
||||
|
||||
$availableLangs = [];
|
||||
|
||||
foreach ($langFiles as $file) {
|
||||
$json = json_decode(file_get_contents($file), true);
|
||||
if (!$json || !isset($json['meta'])) continue;
|
||||
|
||||
$meta = $json['meta'];
|
||||
$code = strtolower($meta['code'] ?? basename($file, ".json"));
|
||||
|
||||
$availableLangs[$code] = [
|
||||
'code' => $code,
|
||||
'label' => $meta['label'] ?? strtoupper($code),
|
||||
'flag' => $meta['flag'] ?? '🏳️'
|
||||
];
|
||||
}
|
||||
|
||||
// Falls Sprache ungültig → erste verfügbare Sprache wählen
|
||||
if (!$lang || !isset($availableLangs[$lang])) {
|
||||
$lang = array_key_first($availableLangs) ?: 'en';
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// 3) Aktive Sprachdatei laden
|
||||
// -----------------------------------------------------------
|
||||
$activeLangFile = $i18nDir . '/' . $lang . '.json';
|
||||
$activeLangData = [];
|
||||
|
||||
if (is_readable($activeLangFile)) {
|
||||
$json = json_decode(file_get_contents($activeLangFile), true);
|
||||
if (is_array($json)) {
|
||||
$activeLangData = $json;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// 4) Fallback-Sprache (EN)
|
||||
// -----------------------------------------------------------
|
||||
$fallbackLangData = [];
|
||||
$fallbackFile = $i18nDir . '/en.json';
|
||||
|
||||
if ($lang !== 'en' && is_readable($fallbackFile)) {
|
||||
$json = json_decode(file_get_contents($fallbackFile), true);
|
||||
if (is_array($json)) {
|
||||
$fallbackLangData = $json;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// 5) Globale i18n-Struktur bereitstellen
|
||||
// -----------------------------------------------------------
|
||||
$GLOBALS['lang'] = $lang;
|
||||
$GLOBALS['availableLangs'] = $availableLangs;
|
||||
|
||||
$GLOBALS['i18n'] = [
|
||||
'current' => $activeLangData,
|
||||
'fallback' => $fallbackLangData,
|
||||
];
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// 6) Rest des Systems laden
|
||||
// -----------------------------------------------------------
|
||||
require_once __DIR__ . "/config.php";
|
||||
require_once __DIR__ . "/db.php";
|
||||
require_once __DIR__ . '/../src/functions.php';
|
||||
|
||||
@@ -1,17 +1,30 @@
|
||||
<?php
|
||||
// partials/structure/app_config.php
|
||||
|
||||
// Host-Infos ermitteln (für URLs / Redirects etc.)
|
||||
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
|
||||
$host = $_SERVER['HTTP_HOST'] ?? app_primary_domain();
|
||||
$requestUri = $_SERVER['REQUEST_URI'] ?? '/';
|
||||
|
||||
// -----------------------------------------------
|
||||
// USBCheck JavaScript-Konfiguration
|
||||
// (für fakecheck.*, header.js, i18n, usw.)
|
||||
// -----------------------------------------------
|
||||
$usbConfig = [
|
||||
'lang' => $lang ?? 'en',
|
||||
|
||||
// Basis-Pfade
|
||||
'assetsBase' => '/assets',
|
||||
// NEU: Versionierung für JS/CSS aus PHP-Config
|
||||
|
||||
// Versionierung für JS/CSS
|
||||
// → wenn ASSET_VERSION definiert ist, wird sie genutzt
|
||||
// → sonst null (JS-Loader sorgt für ?v= fallback)
|
||||
'assetVersion'=> defined('ASSET_VERSION') ? ASSET_VERSION : null,
|
||||
|
||||
// Environment (prod, staging, dev)
|
||||
'env' => $GLOBALS['ENV'] ?? 'prod',
|
||||
|
||||
// Domains
|
||||
'domains' => [
|
||||
'primaryDomain' => app_primary_domain(),
|
||||
'primaryUrl' => app_primary_url(),
|
||||
@@ -19,13 +32,32 @@ $usbConfig = [
|
||||
'fakecheckUrl' => app_fakecheck_url(),
|
||||
],
|
||||
|
||||
// Fakecheck-Tool-Config
|
||||
'fakecheck' => [
|
||||
'baseUrl' => $GLOBALS['usb_base_url'] ?? '',
|
||||
'apiBaseUrl' => $GLOBALS['usb_api_base'] ?? 'https://api.usbcheck.it',
|
||||
'locale' => $lang ?? 'en',
|
||||
],
|
||||
|
||||
// -----------------------------------------------
|
||||
// i18n: aus fileload.php gefüllt
|
||||
// -----------------------------------------------
|
||||
'i18n' => [
|
||||
// Alle verfügbaren Sprachen (code, label, flag)
|
||||
'available' => $availableLangs ?? [],
|
||||
|
||||
// Aktuelle Sprache als Code (de/en/fr/it …)
|
||||
'current' => $lang ?? 'en',
|
||||
],
|
||||
];
|
||||
|
||||
// -----------------------------------------------
|
||||
// Javascript-Konfiguration in die Seite schreiben
|
||||
// -----------------------------------------------
|
||||
?>
|
||||
<script>
|
||||
window.usbConfig = <?= json_encode($usbConfig, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ?>;
|
||||
window.usbConfig = <?= json_encode(
|
||||
$usbConfig,
|
||||
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE
|
||||
) ?>;
|
||||
</script>
|
||||
|
||||
@@ -44,13 +44,52 @@ if ($isLoggedIn) {
|
||||
$userInitials = mb_strtoupper($initials);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
// Dynamische Sprachliste
|
||||
// kommt aus app_config.php:
|
||||
//
|
||||
// $usbConfig['i18n']['available'] = [
|
||||
// 'de' => ['code'=>'de','label'=>'Deutsch','flag'=>'🇩🇪'],
|
||||
// ...
|
||||
// ];
|
||||
// $usbConfig['i18n']['current'] = 'de';
|
||||
// -----------------------------------------
|
||||
|
||||
// aktuelle Sprache aus globalem Kontext
|
||||
$currentLang = $usbConfig['i18n']['current'] ?? ($lang ?? 'en');
|
||||
|
||||
// verfügbare Sprachen aus Config
|
||||
$availableLangs = $usbConfig['i18n']['available'] ?? [];
|
||||
|
||||
// Fallback: Wenn Config noch nichts liefert, nimm nur die aktuelle Sprache
|
||||
if (!$availableLangs || !is_array($availableLangs)) {
|
||||
$availableLangs = [
|
||||
$currentLang => [
|
||||
'code' => $currentLang,
|
||||
'label' => strtoupper($currentLang),
|
||||
'flag' => '🏳️'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
// Sicherstellen, dass currentLang in der Liste ist
|
||||
if (!isset($availableLangs[$currentLang])) {
|
||||
$currentLang = array_key_first($availableLangs);
|
||||
}
|
||||
|
||||
// aktuelle Sprache-Info
|
||||
$currentLangInfo = $availableLangs[$currentLang] ?? ['code' => $currentLang];
|
||||
$currentLangFlag = $currentLangInfo['flag'] ?? '🏳️';
|
||||
$currentLangCode = strtoupper($currentLangInfo['code'] ?? $currentLang);
|
||||
$currentLangLabel = $currentLangInfo['label'] ?? $currentLangCode;
|
||||
?>
|
||||
<header class="sticky top-0 z-40 border-b border-brand-border/70 backdrop-blur bg-brand-bg/85">
|
||||
<div class="mx-auto max-w-6xl px-4 sm:px-6 lg:px-8 flex items-center justify-between h-16">
|
||||
|
||||
<!-- Logo -->
|
||||
<div class="flex items-center gap-3">
|
||||
<a href="/?lang=<?= htmlspecialchars($lang ?? 'de') ?>" class="flex items-center gap-3">
|
||||
<a href="/?lang=<?= htmlspecialchars($currentLang) ?>" class="flex items-center gap-3">
|
||||
<img src="<?= $baseUrl ?>/assets/img/logo_slogan.png"
|
||||
alt="<?= htmlspecialchars(app_primary_domain()) ?> Logo"
|
||||
class="h-9 w-auto">
|
||||
@@ -84,38 +123,28 @@ if ($isLoggedIn) {
|
||||
<button id="langCurrent"
|
||||
type="button"
|
||||
class="flex items-center gap-1 text-xs uppercase tracking-[0.18em] text-brand-muted hover:text-brand-primary transition">
|
||||
<span id="langCurrentLabel"><?= strtoupper($lang ?? 'de') ?></span>
|
||||
<span class="text-base mr-1" id="langCurrentFlag"><?= htmlspecialchars($currentLangFlag) ?></span>
|
||||
<span id="langCurrentLabel"><?= htmlspecialchars($currentLangCode) ?></span>
|
||||
<svg class="w-3 h-3 opacity-70" viewBox="0 0 20 20" aria-hidden="true">
|
||||
<path d="M5 7l5 6 5-6" fill="currentColor" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<div id="langMenu"
|
||||
class="hidden absolute right-0 mt-2 w-24 rounded-xl bg-brand-surface border border-brand-border shadow-lg py-1 text-xs z-40">
|
||||
class="hidden absolute right-0 mt-2 w-32 rounded-xl bg-brand-surface border border-brand-border shadow-lg py-1 text-xs z-40">
|
||||
<?php foreach ($availableLangs as $code => $info): ?>
|
||||
<?php
|
||||
$isActive = ($code === $currentLang);
|
||||
$flag = $info['flag'] ?? '🏳️';
|
||||
$label = strtoupper($info['code'] ?? $code);
|
||||
?>
|
||||
<button type="button"
|
||||
class="lang-pill flex items-center gap-2 w-full text-left px-3 py-1.5 uppercase tracking-[0.18em] text-brand-muted hover:text-brand-primary hover:bg-brand-bg/60"
|
||||
data-lang="de">
|
||||
<span class="text-base">🇩🇪</span>
|
||||
<span>DE</span>
|
||||
</button>
|
||||
<button type="button"
|
||||
class="lang-pill flex items-center gap-2 w-full text-left px-3 py-1.5 uppercase tracking-[0.18em] text-brand-muted hover:text-brand-primary hover:bg-brand-bg/60"
|
||||
data-lang="en">
|
||||
<span class="text-base">🇬🇧</span>
|
||||
<span>EN</span>
|
||||
</button>
|
||||
<button type="button"
|
||||
class="lang-pill flex items-center gap-2 w-full text-left px-3 py-1.5 uppercase tracking-[0.18em] text-brand-muted hover:text-brand-primary hover:bg-brand-bg/60"
|
||||
data-lang="it">
|
||||
<span class="text-base">🇮🇹</span>
|
||||
<span>IT</span>
|
||||
</button>
|
||||
<button type="button"
|
||||
class="lang-pill flex items-center gap-2 w-full text-left px-3 py-1.5 uppercase tracking-[0.18em] text-brand-muted hover:text-brand-primary hover:bg-brand-bg/60"
|
||||
data-lang="fr">
|
||||
<span class="text-base">🇫🇷</span>
|
||||
<span>FR</span>
|
||||
class="lang-pill flex items-center gap-2 w-full text-left px-3 py-1.5 uppercase tracking-[0.18em] text-brand-muted hover:text-brand-primary hover:bg-brand-bg/60 <?= $isActive ? 'bg-brand-bg/60' : '' ?>"
|
||||
data-lang="<?= htmlspecialchars($code) ?>">
|
||||
<span class="text-base"><?= htmlspecialchars($flag) ?></span>
|
||||
<span><?= htmlspecialchars($label) ?></span>
|
||||
</button>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -127,7 +156,7 @@ if ($isLoggedIn) {
|
||||
type="button"
|
||||
class="relative inline-flex items-center justify-center rounded-full bg-brand-primary px-4 py-1.5 text-xs font-semibold uppercase tracking-[0.18em] text-brand-bg shadow-soft hover:bg-cyan-400 transition-colors"
|
||||
data-i18n="header_btn_login"
|
||||
data-login-url="/login/?lang=<?= htmlspecialchars($lang ?? 'de') ?>">
|
||||
data-login-url="/login/?lang=<?= htmlspecialchars($currentLang) ?>">
|
||||
Login
|
||||
</button>
|
||||
<?php else: ?>
|
||||
@@ -143,7 +172,7 @@ if ($isLoggedIn) {
|
||||
|
||||
<div id="userMenu"
|
||||
class="hidden absolute right-0 mt-2 w-44 rounded-xl bg-brand-surface border border-brand-border shadow-lg py-1 text-xs z-40">
|
||||
<a href="/dashboard/?lang=<?= htmlspecialchars($lang ?? 'de') ?>"
|
||||
<a href="/dashboard/?lang=<?= htmlspecialchars($currentLang) ?>"
|
||||
class="flex items-center gap-2 px-3 py-2 text-brand-muted hover:text-brand-primary hover:bg-brand-bg/60 transition-colors"
|
||||
data-i18n="header_menu_dashboard">
|
||||
Dashboard
|
||||
@@ -151,7 +180,7 @@ if ($isLoggedIn) {
|
||||
<button type="button"
|
||||
class="flex items-center gap-2 w-full text-left px-3 py-2 text-brand-muted hover:text-red-400 hover:bg-red-500/10 transition-colors"
|
||||
data-logout-link="true"
|
||||
data-logout-href="/auth/logout?lang=<?= htmlspecialchars($lang ?? 'de') ?>"
|
||||
data-logout-href="/auth/logout?lang=<?= htmlspecialchars($currentLang) ?>"
|
||||
data-i18n="header_menu_logout">
|
||||
Logout
|
||||
</button>
|
||||
|
||||
@@ -2,44 +2,62 @@
|
||||
// public/partials/layout_start.php
|
||||
|
||||
// Erwartet (vor require):
|
||||
// - $lang (de|en|it|fr) – bereits validiert
|
||||
// - $pageTitle (string)
|
||||
// - $pageDescription (string, optional)
|
||||
// - $userInitials (optional, kann null sein)
|
||||
// - optional: $canonical (string) → überschreibt die automatisch berechnete Canonical-URL
|
||||
// - $pageKey (string) – Seiten-Key für i18n, z. B. 'landing', 'fakecheck', 'login', 'dashboard'
|
||||
// - $lang (2-letter ISO, z. B. 'de', 'en', 'it', 'fr'), möglichst bereits aus fileload.php
|
||||
// - optional: $pageTitle (string)
|
||||
// - optional: $pageDescription (string)
|
||||
// - optional: $canonical (string)
|
||||
// - optional: $userInitials (string|null)
|
||||
|
||||
// Fallbacks:
|
||||
if (!isset($lang) || !in_array($lang, ['de', 'en', 'it', 'fr'], true)) {
|
||||
$lang = 'en';
|
||||
// -----------------------------------------------------------
|
||||
// Fallbacks & i18n Title/Description
|
||||
// -----------------------------------------------------------
|
||||
|
||||
// Sicherstellen, dass availableLangs existiert (kommt aus fileload.php)
|
||||
$availableLangs = $availableLangs ?? [];
|
||||
|
||||
// Page-Key Fallback
|
||||
if (!isset($pageKey) || !is_string($pageKey) || $pageKey === '') {
|
||||
$pageKey = 'landing';
|
||||
}
|
||||
|
||||
// Fallback für Sprache: lieber auf $availableLangs statt feste Liste
|
||||
if (!isset($lang) || !isset($availableLangs[$lang])) {
|
||||
$lang = array_key_first($availableLangs) ?: 'en';
|
||||
}
|
||||
|
||||
// Title aus i18n, falls nichts explizit gesetzt wurde
|
||||
if (!isset($pageTitle) || !is_string($pageTitle) || $pageTitle === '') {
|
||||
$pageTitle = app_primary_domain();
|
||||
// pages.{pageKey}.meta.title
|
||||
$pageTitle = i18n_get("pages.$pageKey.meta.title", app_primary_domain());
|
||||
}
|
||||
|
||||
if (!isset($pageDescription) || !is_string($pageDescription)) {
|
||||
$pageDescription = '';
|
||||
// Description aus i18n, falls nichts explizit gesetzt wurde
|
||||
if (!isset($pageDescription) || !is_string($pageDescription) || $pageDescription === '') {
|
||||
// pages.{pageKey}.meta.description
|
||||
$pageDescription = i18n_get("pages.$pageKey.meta.description", '');
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Standard-Script für Header-Interaktionen
|
||||
// -----------------------------------------------------------
|
||||
if (function_exists('tpl_add_script')) {
|
||||
// header.js kommt wie gehabt in den Footer
|
||||
tpl_add_script('/assets/js/header.js', 'footer', true, false, '', null);
|
||||
}
|
||||
|
||||
// Scheme + Host + Request-URI für Canonical & sonstige Host-bezogene Dinge
|
||||
// -----------------------------------------------------------
|
||||
// Canonical-URL bestimmen
|
||||
// -----------------------------------------------------------
|
||||
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
|
||||
$host = $_SERVER['HTTP_HOST'] ?? app_primary_domain();
|
||||
$requestUri = $_SERVER['REQUEST_URI'] ?? '/';
|
||||
|
||||
// Canonical bestimmen:
|
||||
// - Wenn $canonical gesetzt ist (z. B. auf einer Landingpage explizit)
|
||||
// → diese URL verwenden
|
||||
// - Sonst: aktuelle URL ohne Query-Parameter (alles hinter '?')
|
||||
// Wenn $canonical gesetzt → verwenden, sonst aktuelle URL ohne Query-String
|
||||
$effectiveCanonical = isset($canonical) && is_string($canonical) && $canonical !== ''
|
||||
? $canonical
|
||||
: ($scheme . '://' . $host . strtok($requestUri, '?'));
|
||||
|
||||
// Kann später genutzt werden, falls du host-spezifische Sachen brauchst
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="<?= htmlspecialchars($lang) ?>">
|
||||
@@ -59,13 +77,14 @@ $effectiveCanonical = isset($canonical) && is_string($canonical) && $canonical !
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&family=Montserrat:wght@600;700;800&display=swap" rel="stylesheet">
|
||||
<?php tpl('app_config', 'structure'); ?>
|
||||
|
||||
<?php
|
||||
<?php
|
||||
// App-Config (usbConfig + i18n.available/current) ins Fenster schreiben
|
||||
tpl('app_config', 'structure');
|
||||
|
||||
// CSS im Header
|
||||
foreach ($GLOBALS['page_styles'] as $style) {
|
||||
if ($style['pos'] !== 'header') {
|
||||
// CSS im Header aus der zentralen Registry
|
||||
foreach ($GLOBALS['page_styles'] as $style) {
|
||||
if (($style['pos'] ?? 'header') !== 'header') {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -75,28 +94,28 @@ foreach ($GLOBALS['page_styles'] as $style) {
|
||||
}
|
||||
|
||||
echo '<link rel="stylesheet" href="' . htmlspecialchars($href) . '">' . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
// Scripts im Header
|
||||
foreach ($GLOBALS['page_header_scripts'] as $script) {
|
||||
// Scripts im Header aus der zentralen Registry
|
||||
foreach ($GLOBALS['page_header_scripts'] as $script) {
|
||||
$src = $script['src'];
|
||||
if (!empty($script['version'])) {
|
||||
$src .= (str_contains($src, '?') ? '&' : '?') . 'v=' . urlencode($script['version']);
|
||||
}
|
||||
|
||||
$attr = '';
|
||||
if ($script['async']) {
|
||||
if (!empty($script['async'])) {
|
||||
$attr .= ' async';
|
||||
} elseif ($script['defer']) {
|
||||
} elseif (!empty($script['defer'])) {
|
||||
$attr .= ' defer';
|
||||
}
|
||||
if ($script['type']) {
|
||||
if (!empty($script['type'])) {
|
||||
$attr .= ' type="' . htmlspecialchars($script['type']) . '"';
|
||||
}
|
||||
|
||||
echo '<script src="' . htmlspecialchars($src) . '"' . $attr . '></script>' . PHP_EOL;
|
||||
}
|
||||
?>
|
||||
}
|
||||
?>
|
||||
|
||||
<script>
|
||||
window.tailwind = window.tailwind || {};
|
||||
@@ -129,8 +148,7 @@ foreach ($GLOBALS['page_header_scripts'] as $script) {
|
||||
<!-- Tailwind (Dev) -->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
|
||||
|
||||
<!-- Eigenes CSS -->
|
||||
<!-- Eigenes CSS (falls du das irgendwann auch versionieren willst, gerne über tpl_add_style) -->
|
||||
<link rel="stylesheet" href="/assets/css/main.css">
|
||||
</head>
|
||||
|
||||
|
||||
173
public/assets/i18n/at.json
Normal file
173
public/assets/i18n/at.json
Normal file
@@ -0,0 +1,173 @@
|
||||
{
|
||||
"meta": {
|
||||
"code": "at",
|
||||
"label": "Deutsch (AT)",
|
||||
"flag": "🇦🇹"
|
||||
},
|
||||
|
||||
"header": {
|
||||
"header_slogan": "USB-Sticks testen",
|
||||
"btn_login": "Login",
|
||||
|
||||
"nav_how": "Wie es funktioniert",
|
||||
"nav_problem": "Warum es wichtig ist",
|
||||
"nav_features": "Funktionen",
|
||||
"nav_security": "Sicherheit",
|
||||
"nav_faq": "FAQ"
|
||||
},
|
||||
|
||||
"brand": {
|
||||
"brand_wordmark": "{{primary_domain}}",
|
||||
"brand_subtitle": "USB-Sticks auf Fakes testen"
|
||||
},
|
||||
|
||||
"footer": {
|
||||
"footer_imprint": "Impressum",
|
||||
"footer_privacy": "Datenschutz",
|
||||
"footer_copy": "© {year} {{primary_domain}}. Alle Rechte vorbehalten."
|
||||
},
|
||||
|
||||
"fake_ui": {
|
||||
"error_fsapi_not_supported": "Die File System Access API wird von diesem Browser nicht unterstützt.",
|
||||
"error_no_directory_selected": "Kein Verzeichnis ausgewählt.",
|
||||
"error_no_space_detected": "Es konnte kein freier Speicher im gewählten Verzeichnis reserviert werden.",
|
||||
|
||||
"log_capacity_probe_start": "Ermittle verfügbaren Speicherplatz im gewählten Verzeichnis...",
|
||||
"log_capacity_probe_result": "Ermittelter für Tests nutzbarer Speicher: {size} (Schreibprobe).",
|
||||
|
||||
"log_quick_prepare": "Quick-Check: Vorbereitung... (Testgröße: {size})",
|
||||
"log_quick_verify_start": "Quick-Check: Schreiben abgeschlossen. Verifiziere Daten...",
|
||||
"log_quick_data_error": "Quick-Check: Datenfehler bei Byte {byte}.",
|
||||
"error_quick_data_error": "Datenfehler im Quick-Check bei Byte {byte}.",
|
||||
"log_quick_delete_warn": "Quick-Check: Konnte Testdatei nicht löschen (nicht kritisch).",
|
||||
"log_quick_success": "Quick-Check: Erfolgreich abgeschlossen.",
|
||||
|
||||
"log_bench_start": "Benchmark: Start – schreibe Testdatei ({size})...",
|
||||
"log_bench_read_start": "Benchmark: Lesen & Timing...",
|
||||
"log_bench_delete_warn": "Benchmark: Konnte Testdatei nicht löschen (nicht kritisch).",
|
||||
"log_bench_success": "Benchmark: Erfolgreich abgeschlossen.",
|
||||
|
||||
"log_wv_start": "Write/Verify: Start – {blocks} Blöcke à {size} (gesamt {total})...",
|
||||
"log_wv_block_start": "Write/Verify: Block {num}/{blocks} – {file}",
|
||||
"log_wv_data_error": "Write/Verify: Datenfehler in Block {num} bei Byte {byte}.",
|
||||
"error_wv_data_error": "Datenfehler in Block {num} bei Byte {byte}.",
|
||||
"log_wv_delete_warn": "Write/Verify: Konnte Blockdatei {file} nicht löschen (nicht kritisch).",
|
||||
"log_wv_success": "Write/Verify: Alle Blöcke erfolgreich verifiziert.",
|
||||
|
||||
"log_all_subtest_start": "All-Inclusive: Starte Teiltest \"{mode}\" ({num}/{total})...",
|
||||
"error_unknown_mode": "Unbekannter Modus: {mode}",
|
||||
|
||||
"log_fsapi_partial": "Dein Browser unterstützt die File System Access API nicht voll. Einige Funktionen sind deaktiviert.",
|
||||
|
||||
"selected_path_label": "USB-Ordner ausgewählt (Name: \"{name}\").",
|
||||
"selected_path_none": "Noch kein Verzeichnis gewählt.",
|
||||
|
||||
"status_ready": "Bereit. Wähle zuerst deinen USB-Stick aus.",
|
||||
"status_mode_none": "Kein Modus selektiert",
|
||||
"status_dir_selected": "USB-Verzeichnis ausgewählt. Wähle jetzt einen Testmodus.",
|
||||
"status_mode_selected": "Modus \"{mode}\" ausgewählt. Du kannst den Test jetzt starten.",
|
||||
"status_running": "Test läuft... bitte USB-Stick nicht entfernen.",
|
||||
"status_done": "Test abgeschlossen.",
|
||||
"status_aborted": "Test wurde abgebrochen.",
|
||||
"status_error": "Fehler: {msg}",
|
||||
"status_error_unknown": "Unbekannter Fehler im Test.",
|
||||
|
||||
"overall_initial": "Noch kein Test durchgeführt.",
|
||||
"overall_running": "Test läuft...",
|
||||
"overall_done": "Browser-Test erfolgreich abgeschlossen.",
|
||||
"overall_aborted": "Test abgebrochen.",
|
||||
"overall_error": "Fehler im Browser-Test.",
|
||||
|
||||
"log_dir_selected": "Verzeichnis ausgewählt: {name}",
|
||||
"log_dir_reset": "Verzeichnisauswahl zurückgesetzt.",
|
||||
"log_pick_abort": "Verzeichnisauswahl abgebrochen.",
|
||||
"log_pick_error": "Fehler bei Verzeichnisauswahl: {msg}",
|
||||
"log_pick_error_unknown": "Unbekannter Fehler bei Verzeichnisauswahl.",
|
||||
"log_mode_selected": "Modus gewählt: {mode}",
|
||||
"log_test_start": "Starte Tests im Modus: {mode}",
|
||||
"log_test_aborted": "Test wurde vom Benutzer abgebrochen.",
|
||||
"log_test_error": "Fehler im Test: {msg}",
|
||||
"log_test_error_unknown": "Unbekannter Fehler im Test.",
|
||||
"log_loaded": "USB-Browser-Test (fakecheck) geladen. Warte auf Verzeichnisauswahl und Modus.",
|
||||
|
||||
"mode_quick": "Quick-Check",
|
||||
"mode_benchmark": "Benchmark",
|
||||
"mode_writeverify": "Write & Verify",
|
||||
"mode_all": "All-Inclusive (alle Browser-Tests)",
|
||||
|
||||
"log_backend_save_error_status": "Backend: Konnte Ergebnis nicht speichern ({status}).",
|
||||
"log_backend_save_ok": "Backend: Testergebnis gespeichert{suffix}.",
|
||||
"log_backend_save_error": "Fehler beim Speichern im Backend: {msg}"
|
||||
},
|
||||
|
||||
"serial": {
|
||||
"rating_label": "Bewertung",
|
||||
|
||||
"rating": {
|
||||
"ok": {
|
||||
"label": "Plausibel",
|
||||
"desc": "Keine deutlichen Auffälligkeiten erkannt."
|
||||
},
|
||||
"needs_review": {
|
||||
"label": "Überprüfung empfohlen",
|
||||
"desc": "Leichte Auffälligkeiten. In Kombination mit einem technischen Test ergibt sich ein klareres Bild."
|
||||
},
|
||||
"suspicious": {
|
||||
"label": "Auffällig / Verdächtig",
|
||||
"desc": "Deutliche Auffälligkeiten erkannt. Ein Kapazitäts- oder Schreib-/Lesetest ist dringend empfohlen."
|
||||
},
|
||||
"invalid": {
|
||||
"label": "Ungültig",
|
||||
"desc": "Die Seriennummer konnte nicht sinnvoll bewertet werden."
|
||||
},
|
||||
"unknown": {
|
||||
"label": "Unklar",
|
||||
"desc": "Bewertung nicht eindeutig möglich."
|
||||
}
|
||||
},
|
||||
|
||||
"heading_input": "Eingabedaten",
|
||||
"heading_analysis": "Seriennummer-Analyse",
|
||||
"heading_consistency": "Hersteller-Konsistenz",
|
||||
|
||||
"input": {
|
||||
"manufacturer": "Hersteller (Angabe):",
|
||||
"vidpid": "VID/PID:",
|
||||
"vendor_detected": "Vendor aus VID:"
|
||||
},
|
||||
|
||||
"analysis": {
|
||||
"serial": "Seriennummer:",
|
||||
"length": "Länge:",
|
||||
"category": "Kategorie:",
|
||||
"score": "Score:",
|
||||
"issues": "Auffälligkeiten:"
|
||||
},
|
||||
|
||||
"chars": "Zeichen",
|
||||
"none": "keine Angabe",
|
||||
|
||||
"issues_none": "Keine besonderen Auffälligkeiten.",
|
||||
|
||||
"vendor_detected": "{vendor} (VID {vid})",
|
||||
"vendor_unknown": "Unbekannter Hersteller für VID {vid}",
|
||||
"vendor_none": "Keine Vendor-ID angegeben",
|
||||
|
||||
"disclaimer": "Diese Einschätzung basiert auf Heuristiken und kann keine Echtheit garantieren.",
|
||||
|
||||
"error": {
|
||||
"no_serial": "Bitte gib eine Seriennummer ein.",
|
||||
"api": "Fehler bei der Prüfung: {msg}",
|
||||
"unknown": "Unerwartete Antwort vom Server."
|
||||
}
|
||||
},
|
||||
|
||||
"pages": {
|
||||
"landing": {
|
||||
"meta": {
|
||||
"title": "{{primary_domain}} – USB-Sticks auf Fakes testen",
|
||||
"description": "USBCheck kombiniert einen schnellen Browser-Schnelltest mit einem professionellen Pro-Modus. So erkennst du gefälschte USB-Sticks, zu kleine echte Kapazität und langsame Billig-Controller – bevor deine Dateien verschwinden."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
344
public/assets/i18n/ch.json
Normal file
344
public/assets/i18n/ch.json
Normal file
@@ -0,0 +1,344 @@
|
||||
{
|
||||
"meta": {
|
||||
"code": "ch",
|
||||
"label": "Schwiizerdütsch (Züri)",
|
||||
"flag": "🇨🇭"
|
||||
},
|
||||
"header": {
|
||||
"header_slogan": "USB-Sticks testen",
|
||||
"btn_login": "Login",
|
||||
"nav_how": "Wie es funktioniert",
|
||||
"nav_problem": "Wieso es wichtig ist",
|
||||
"nav_features": "Funktionen",
|
||||
"nav_security": "Sicherheit",
|
||||
"nav_faq": "FAQ"
|
||||
},
|
||||
"brand": {
|
||||
"brand_wordmark": "{{primary_domain}}",
|
||||
"brand_subtitle": "USB-Sticks auf Fakes testen"
|
||||
},
|
||||
"footer": {
|
||||
"footer_imprint": "Impressum",
|
||||
"footer_privacy": "Datenschutz",
|
||||
"footer_copy": "© {year} {{primary_domain}}. Alle Rechte vorbehalten."
|
||||
},
|
||||
"fake_ui": {
|
||||
"error_fsapi_not_supported": "Die File System Access API wird von diesem Browser nicht unterstützt.",
|
||||
"error_no_directory_selected": "Kein Verzeichnis ausgewählt.",
|
||||
"error_no_space_detected": "Es konnte kein freier Speicher im gewählten Verzeichnis reserviert werden.",
|
||||
"log_capacity_probe_start": "Ermittle verfügbaren Speicherplatz im gewählten Verzeichnis...",
|
||||
"log_capacity_probe_result": "Ermittelter für Tests nutzbarer Speicher: {size} (Schreibprobe).",
|
||||
"log_quick_prepare": "Quick-Check: Vorbereitung... (Testgrösse: {size})",
|
||||
"log_quick_verify_start": "Quick-Check: Schreiben abgeschlossen. Verifiziere Daten...",
|
||||
"log_quick_data_error": "Quick-Check: Datenfehler bei Byte {byte}.",
|
||||
"error_quick_data_error": "Datenfehler im Quick-Check bei Byte {byte}.",
|
||||
"log_quick_delete_warn": "Quick-Check: Konnte Testdatei nicht löschen (nicht kritisch).",
|
||||
"log_quick_success": "Quick-Check: Erfolgreich abgeschlossen.",
|
||||
"log_bench_start": "Benchmark: Start – schreibe Testdatei ({size})...",
|
||||
"log_bench_read_start": "Benchmark: Lesen & Timing...",
|
||||
"log_bench_delete_warn": "Benchmark: Konnte Testdatei nicht löschen (nicht kritisch).",
|
||||
"log_bench_success": "Benchmark: Erfolgreich abgeschlossen.",
|
||||
"log_wv_start": "Write/Verify: Start – {blocks} Blöcke à {size} (gesamt {total})...",
|
||||
"log_wv_block_start": "Write/Verify: Block {num}/{blocks} – {file}",
|
||||
"log_wv_data_error": "Write/Verify: Datenfehler in Block {num} bei Byte {byte}.",
|
||||
"error_wv_data_error": "Datenfehler in Block {num} bei Byte {byte}.",
|
||||
"log_wv_delete_warn": "Write/Verify: Konnte Blockdatei {file} nicht löschen (nicht kritisch).",
|
||||
"log_wv_success": "Write/Verify: Alle Blöcke erfolgreich verifiziert.",
|
||||
"log_all_subtest_start": "All-Inclusive: Starte Teiltest \"{mode}\" ({num}/{total})...",
|
||||
"error_unknown_mode": "Unbekannter Modus: {mode}",
|
||||
"log_fsapi_partial": "Dein Browser unterstützt die File System Access API nicht voll. Einige Funktionen sind deaktiviert.",
|
||||
"selected_path_label": "USB-Ordner ausgewählt (Name: \"{name}\").",
|
||||
"selected_path_none": "Noch kein Verzeichnis gewählt.",
|
||||
"status_ready": "Bereit. Wähle zuerst deinen USB-Stick aus.",
|
||||
"status_mode_none": "Kein Modus selektiert",
|
||||
"status_dir_selected": "USB-Verzeichnis ausgewählt. Wähle jetzt einen Testmodus.",
|
||||
"status_mode_selected": "Modus \"{mode}\" ausgewählt. Du kannst den Test jetzt starten.",
|
||||
"status_running": "Test läuft... bitte USB-Stick nicht entfernen.",
|
||||
"status_done": "Test abgeschlossen.",
|
||||
"status_aborted": "Test wurde abgebrochen.",
|
||||
"status_error": "Fehler: {msg}",
|
||||
"status_error_unknown": "Unbekannter Fehler im Test.",
|
||||
"overall_initial": "Noch kein Test durchgeführt.",
|
||||
"overall_running": "Test läuft...",
|
||||
"overall_done": "Browser-Test erfolgreich abgeschlossen.",
|
||||
"overall_aborted": "Test abgebrochen.",
|
||||
"overall_error": "Fehler im Browser-Test.",
|
||||
"log_dir_selected": "Verzeichnis ausgewählt: {name}",
|
||||
"log_dir_reset": "Verzeichnisauswahl zurückgesetzt.",
|
||||
"log_pick_abort": "Verzeichnisauswahl abgebrochen.",
|
||||
"log_pick_error": "Fehler bei Verzeichnisauswahl: {msg}",
|
||||
"log_pick_error_unknown": "Unbekannter Fehler bei Verzeichnisauswahl.",
|
||||
"log_mode_selected": "Modus gewählt: {mode}",
|
||||
"log_test_start": "Starte Tests im Modus: {mode}",
|
||||
"log_test_aborted": "Test wurde vom Benutzer abgebrochen.",
|
||||
"log_test_error": "Fehler im Test: {msg}",
|
||||
"log_test_error_unknown": "Unbekannter Fehler im Test.",
|
||||
"log_loaded": "USB-Browser-Test (fakecheck) geladen. Warte auf Verzeichnisauswahl und Modus.",
|
||||
"mode_quick": "Quick-Check",
|
||||
"mode_benchmark": "Benchmark",
|
||||
"mode_writeverify": "Write & Verify",
|
||||
"mode_all": "All-Inclusive (alle Browser-Tests)",
|
||||
"log_backend_save_error_status": "Backend: Konnte Ergebnis nicht speichern ({status}).",
|
||||
"log_backend_save_ok": "Backend: Testergebnis gespeichert{suffix}.",
|
||||
"log_backend_save_error": "Fehler beim Speichern im Backend: {msg}"
|
||||
},
|
||||
"serial": {
|
||||
"rating_label": "Bewertung",
|
||||
"rating": {
|
||||
"ok": {
|
||||
"label": "Plausibel",
|
||||
"desc": "Keine deutlichen Auffälligkeiten erkannt."
|
||||
},
|
||||
"needs_review": {
|
||||
"label": "Überprüfung empfohlen",
|
||||
"desc": "Leichte Auffälligkeiten. In Kombination mit einem technischen Test ergibt sich ein klareres Bild."
|
||||
},
|
||||
"suspicious": {
|
||||
"label": "Auffällig / Verdächtig",
|
||||
"desc": "Deutliche Auffälligkeiten erkannt. Ein Kapazitäts- oder Schreib-/Lesetest ist dringend empfohlen."
|
||||
},
|
||||
"invalid": {
|
||||
"label": "Ungültig",
|
||||
"desc": "Die Seriennummer konnte nicht sinnvoll bewertet werden."
|
||||
},
|
||||
"unknown": {
|
||||
"label": "Unklar",
|
||||
"desc": "Bewertung nicht eindeutig möglich."
|
||||
}
|
||||
},
|
||||
"heading_input": "Eingabedaten",
|
||||
"heading_analysis": "Seriennummer-Analyse",
|
||||
"heading_consistency": "Hersteller-Konsistenz",
|
||||
"input": {
|
||||
"manufacturer": "Hersteller (Angabe):",
|
||||
"vidpid": "VID/PID:",
|
||||
"vendor_detected": "Vendor aus VID:"
|
||||
},
|
||||
"analysis": {
|
||||
"serial": "Seriennummer:",
|
||||
"length": "Länge:",
|
||||
"category": "Kategorie:",
|
||||
"score": "Score:",
|
||||
"issues": "Auffälligkeiten:"
|
||||
},
|
||||
"chars": "Zeichen",
|
||||
"none": "keine Angabe",
|
||||
"issues_none": "Keine besonderen Auffälligkeiten.",
|
||||
"vendor_detected": "{vendor} (VID {vid})",
|
||||
"vendor_unknown": "Unbekannter Hersteller für VID {vid}",
|
||||
"vendor_none": "Keine Vendor-ID angegeben",
|
||||
"disclaimer": "Diese Einschätzung basiert auf Heuristiken und kann keine Echtheit garantieren.",
|
||||
"error": {
|
||||
"no_serial": "Bitte gib eine Seriennummer ein.",
|
||||
"api": "Fehler bei der Prüfung: {msg}",
|
||||
"unknown": "Unerwartete Antwort vom Server."
|
||||
}
|
||||
},
|
||||
"pages": {
|
||||
"landing": {
|
||||
"meta": {
|
||||
"title": "{{primary_domain}} – USB-Sticks auf Fakes testen",
|
||||
"description": "USBCheck kombiniert einen schnellen Browser-Schnelltest mit einem professionellen Pro-Modus. So erkennst du gefälschte USB-Sticks, zu kleine echte Kapazität und langsame Billig-Controller – bevor deine Dateien verschwinden."
|
||||
},
|
||||
"sections": {
|
||||
"hero": {
|
||||
"kicker": "Erkenne Fake-USB-Sticks, bevor du Daten verlierst",
|
||||
"title": "Ist mein USB-Stick ein Fake?",
|
||||
"lead": "USBCheck kombiniert einen schnellen Browser-Schnelltest mit einem professionellen Pro-Modus. So erkennst du gefälschte USB-Sticks, zu kleine echte Kapazität und langsame Billig-Controller – bevor deine Dateien verschwinden.",
|
||||
"cta_quick": "Gratis Schnelltest starten",
|
||||
"cta_learn": "Mehr zu Free & Pro"
|
||||
},
|
||||
"trust": {
|
||||
"t1_title": "Keine Installation für Schnelltest",
|
||||
"t1_text": "Browser-basierter Test direkt auf deinem Stick.",
|
||||
"t2_title": "Echte Schreib- & Lesetests",
|
||||
"t2_text": "Schreib-/Lesetests mit realen Daten – keine synthetischen Benchmarks.",
|
||||
"t3_title": "Privacy first",
|
||||
"t3_text": "Deine Testdaten bleiben lokal – Reports nur auf Wunsch."
|
||||
},
|
||||
"quick": {
|
||||
"label": "Schnelltest-Vorschau",
|
||||
"title": "USB-Stick in unter 2 Minuten testen",
|
||||
"badge_free": "Gratis",
|
||||
"intro": "Der Schnelltest prüft eine definierte Datenmenge auf deinem Stick und misst:",
|
||||
"li1": "Schreib- und Leserate",
|
||||
"li2": "Datenintegrität (Hash-Vergleich)",
|
||||
"li3": "Verdächtige Abbrüche oder Fehler",
|
||||
"metric1_label": "Schreibleistung",
|
||||
"metric1_value": "~ 75–120 MB/s*",
|
||||
"metric2_label": "Integritätsprüfung",
|
||||
"metric2_value": "512 MB Testdaten",
|
||||
"footnote": "*Beispielwerte – deine Ergebnisse hängen von Stick, Port & System ab.",
|
||||
"cta": "Zum gratis Schnelltest",
|
||||
"visual_title": "Schnelltest-Anzeige",
|
||||
"visual_text": "So sieht die Quick-Check-Vorschau aus: Grün markiert stabile Daten, Orange warnt, wenn die Schreibrate einbricht.",
|
||||
"visual_window": "Ergebnisfenster"
|
||||
},
|
||||
"how": {
|
||||
"kicker": "So funktioniert USBCheck",
|
||||
"title": "Schnelltest im Browser, Pro-Modus mit Tiefenanalyse.",
|
||||
"intro": "USBCheck wurde entwickelt, um zwei Welten zu verbinden: einen einfachen Schnelltest für alle und einen tiefgehenden Pro-Modus für Power-User, Techniker und Admins. Der Schnelltest läuft direkt im Browser, ohne Installation. Für den Pro-Modus wird ein kleines Helfer-Tool verwendet, das auf Wunsch F3- / badblocks-ähnliche Tests ausführt und damit Kapazitäts-Fakes sicher enttarnt.",
|
||||
"step1_title": "Browser-Test starten",
|
||||
"step1_text": "Du öffnest den Schnelltest unter <strong>{{primary_url}}/fakecheck/</strong>, wählst deinen USB-Stick bzw. einen Ordner darauf aus und definierst, wie viel Daten getestet werden sollen.",
|
||||
"step2_title": "Schreib-, Lese- und Integritätsprüfung",
|
||||
"step2_text": "Der Browser erstellt Testdateien, misst Schreib- und Leserate und vergleicht Hash-Werte, um Datenfehler zu erkennen – alles lokal und ohne Übertragung deiner Inhalte.",
|
||||
"step3_title": "Optional: Pro-Modus für Vollscan",
|
||||
"step3_text": "Wer mehr wissen will, installiert das optionale Helfer-Tool. Dieses kann die gesamte Kapazität des Sticks prüfen, Fakes identifizieren und detaillierte Reports erzeugen – ideal für Refurbisher, IT-Abteilungen oder Labore.",
|
||||
"side_title": "Free vs. Pro auf einen Blick",
|
||||
"side_free": "<strong>Free Quick Check:</strong> Geschwindigkeit & Integritätstest im Browser – ideal für schnelle Einschätzungen.",
|
||||
"side_pro": "<strong>Pro-Modus:</strong> Tiefenscan, Kapazitätsvalidierung, erweiterte Berichte und API-Integration für Unternehmen.",
|
||||
"side_account": "<strong>Account & Login:</strong> Nach dem Login kannst du Tests speichern, Berichte exportieren und mehrere Geräte verwalten."
|
||||
},
|
||||
"problem": {
|
||||
"kicker": "Wieso gefälschte USB-Sticks gefährlich sind",
|
||||
"title": "Gefälschte USB-Sticks kosten Geld – und im schlimmsten Fall deine Daten.",
|
||||
"p1": "Viele Billig-USB-Sticks werben mit unrealistisch hohen Kapazitäten. In Wahrheit wurde der Controller manipuliert: Der Stick meldet z. B. 256 GB, obwohl physisch nur 32 GB verbaut sind. Die Folge: Daten werden scheinbar korrekt kopiert, später aber stillschweigend überschrieben oder beschädigt.",
|
||||
"p2": "USBCheck hilft dir, solche Fakes zu erkennen, bevor du sie produktiv einsetzt – egal ob du einzelne Sticks privat nutzt oder grössere Chargen für dein Unternehmen prüfst.",
|
||||
"card1_title": "Verlust wichtiger Dateien",
|
||||
"card1_text": "Fotos, Projektdateien, Backups – alles kann betroffen sein, wenn der Stick weniger speichert als behauptet. Defekte Sektoren bleiben oft unbemerkt, bis es zu spät ist.",
|
||||
"card2_title": "Kosten durch defekte Chargen",
|
||||
"card2_text": "Unternehmen, Reseller und Agenturen verteilen USB-Sticks oft in grosser Stückzahl. Fakes bedeuten Reklamationen, Imageschaden und erneute Produktionskosten.",
|
||||
"card3_title": "Unsichere Performance",
|
||||
"card3_text": "Langsame Controller, instabile Firmware und schwankende Schreibraten sind typisch für Fake-Sticks. Das erhöht das Risiko von Fehlern – besonders bei grossen Dateien."
|
||||
},
|
||||
"features": {
|
||||
"kicker": "Free & Pro Features",
|
||||
"title": "Starte mit dem gratis Schnelltest – wechsle in den Pro-Modus, wenn du mehr brauchst.",
|
||||
"intro": "USBCheck wächst mit deinen Anforderungen: Private Nutzer brauchen oft nur eine schnelle Einschätzung. Profis möchten tiefer einsteigen, Kapazitäten verifizieren und Reports archivieren. Genau dafür ist der Pro-Modus gedacht.",
|
||||
"free_title": "Free Quick Check",
|
||||
"free_badge": "Empfohlen für die meisten Nutzer",
|
||||
"free_text": "Ideal für alle, die schnell prüfen möchten, ob ein USB-Stick zumindest grundlegend performant und stabil arbeitet – ganz ohne Installation.",
|
||||
"free_li1": "• Browser-basierter Schnelltest direkt auf deinem Stick",
|
||||
"free_li2": "• Schreib- und Lesegeschwindigkeit mit realen Testdaten",
|
||||
"free_li3": "• Hash-basierte Integritätsprüfung einer Testmenge",
|
||||
"free_li4": "• Auswahl verschiedener Teststufen (z. B. 200 MB, 2 GB)",
|
||||
"free_li5": "• Keine Registrierung erforderlich",
|
||||
"free_cta": "Gratis Schnelltest starten",
|
||||
"pro_title": "Pro Mode",
|
||||
"pro_badge": "Für Power-User & Teams",
|
||||
"pro_text": "Für alle, die volle Kontrolle brauchen: IT-Abteilungen, Techniker, Refurbisher, Labore oder Unternehmen, die regelmässig grössere Stick-Mengen testen.",
|
||||
"pro_li1": "• Tiefenscan der gesamten Kapazität (ähnlich F3 / badblocks)",
|
||||
"pro_li2": "• Erkennung von Kapazitäts-Fakes und defekten Bereichen",
|
||||
"pro_li3": "• Detaillierte, speicherbare Testberichte (JSON, PDF)",
|
||||
"pro_li4": "• Optional: API-Zugriff für automatisierte Testprozesse",
|
||||
"pro_li5": "• Multi-Device- und Multi-User-Support (über Login-Bereich)",
|
||||
"pro_note": "Der Pro-Modus erfordert ein kleines Helfer-Tool auf deinem System. Dieses arbeitet lokal und kann bei Bedarf mit deinem Account auf USBCheck verbunden werden."
|
||||
},
|
||||
"security": {
|
||||
"kicker": "Security & Privacy",
|
||||
"title": "Privacy-first-Design: Deine Testdaten gehören dir.",
|
||||
"intro": "USBCheck wurde von Anfang an so konzipiert, dass deine Daten geschützt bleiben. Der Browser-Schnelltest arbeitet ausschliesslich mit Testdateien. Deine eigenen Dokumente, Bilder oder Backups werden weder gelesen noch übertragen. Im Pro-Modus hast du volle Kontrolle, ob und welche Reports mit deinem Account synchronisiert werden.",
|
||||
"card1_title": "Local-only Tests",
|
||||
"card1_text": "Alle Schreib- und Lesetests erfolgen lokal auf deinem USB-Stick. Der Browser greift nur auf die Testdateien zu – nicht auf deine privaten Inhalte.",
|
||||
"card2_title": "Transparente Reports",
|
||||
"card2_text": "Wenn du dich einloggst, kannst du Testberichte in deinem Account speichern, exportieren oder wieder löschen. Du entscheidest, welche Daten im System bleiben.",
|
||||
"card3_title": "Schonend für deine Hardware",
|
||||
"card3_text": "Der Schnelltest arbeitet mit moderaten Datenmengen, um unnötigen Verschleiss zu vermeiden. Der Pro-Modus warnt deutlich, wenn ein Vollscan mit hoher Schreiblast ausgeführt wird."
|
||||
},
|
||||
"faq": {
|
||||
"kicker": "FAQ",
|
||||
"title": "Häufige Fragen zu USBCheck",
|
||||
"intro": "Hier findest du Antworten auf häufig gestellte Fragen. Der FAQ-Bereich kann jederzeit erweitert werden, wenn neue Anwendungsfälle hinzukommen oder du Feedback von Nutzern erhältst.",
|
||||
"q1": "Ist der Schnelltest wirklich komplett im Browser?",
|
||||
"a1": "Ja. Der Schnelltest läuft vollständig im Browser und nutzt moderne Browser-APIs, um Testdateien auf deinem Stick zu schreiben und wieder auszulesen. Es wird nichts ohne deine Zustimmung hochgeladen.",
|
||||
"q2": "Brauche ich ein Konto, um den Schnelltest zu benutzen?",
|
||||
"a2": "Nein. Der gratise Schnelltest ist ohne Registrierung nutzbar. Ein Login ist nur notwendig, wenn du Testberichte speichern, mehrere Sticks verwalten oder den Pro-Modus nutzen möchtest.",
|
||||
"q3": "Kann USBCheck jeden Fake-Stick sicher erkennen?",
|
||||
"a3": "Kein Tool kann eine 100 %-Garantie geben. Der Pro-Modus mit Vollscan ist jedoch darauf ausgelegt, typische Fälschungsmuster (Manipulation der gemeldeten Kapazität, instabile Bereiche, Fehler ab einer bestimmten Füllmenge) sehr zuverlässig zu erkennen.",
|
||||
"q4": "Wie fügt sich das Tool in mein bestehendes System ein?",
|
||||
"a4": "USBCheck ist von Anfang an für Automatisierung gedacht. Über den Pro-Modus und die geplante API kannst du Tests in bestehende Workflows integrieren – beispielsweise in Wareneingangsprüfungen oder Qualitätskontrollen."
|
||||
}
|
||||
}
|
||||
},
|
||||
"fakecheck": {
|
||||
"meta": {
|
||||
"title": "FakeCheck – Browser-Test für USB-Sticks",
|
||||
"description": "Der FakeCheck hilft dir, typische Fake-Sticks aufzuspüren: Browser-basierte Schreib-/Lesetests und Plausibilitätsprüfungen der nutzbaren Kapazität – ohne Installation."
|
||||
},
|
||||
"sections": {
|
||||
"hero": {
|
||||
"kicker": "FakeCheck – Browser-Modus",
|
||||
"title": "Ist mein USB-Stick fake?",
|
||||
"lead": "Der FakeCheck hilft dir, typische Fake-Sticks aufzuspüren: Browser-basierte Schreib-/Lesetests und Plausibilitätsprüfungen der nutzbaren Kapazität – ohne Installation.",
|
||||
"cta_start": "Browser-Test starten (Demo)",
|
||||
"cta_back_home": "Zur Übersicht zurück",
|
||||
"hint": "Der FakeCheck im Browser arbeitet mit Testdateien und Lese-/Schreibmustern, die du in einem ausgewählten Ordner anlegst. Deine echten Dateien bleiben unangetastet."
|
||||
},
|
||||
"capabilities": {
|
||||
"title": "Was der Browser-Test leisten kann",
|
||||
"point1_title": "Schreib-/Lesetest mit Testdateien",
|
||||
"point1_text": "Der Browser legt Testdateien im gewählten Ordner an, misst Schreib- und Leseraten und prüft, ob gelesene Daten mit den geschriebenen Mustern übereinstimmen.",
|
||||
"point2_title": "Plausibilitätscheck der Kapazität",
|
||||
"point2_text": "Aus der Menge der erfolgreich geschriebenen und verifizierten Daten ergibt sich ein realistischer Eindruck, wie viel Nutzkapazität tatsächlich stabil ankommt.",
|
||||
"point3_title": "JSON-Report für deine Dokumentation",
|
||||
"point3_text": "Alle Ergebnisse werden in einem strukturierten JSON-Report gesammelt, den du speichern, hochladen oder für spätere Vergleiche nutzen kannst."
|
||||
},
|
||||
"app": {
|
||||
"title": "Browser-Testoberfläche (Preview)",
|
||||
"intro": "Hier entsteht die eigentliche FakeCheck-Web-App: Auswahl des Testordners, Konfiguration der Testmenge, Fortschrittsanzeige und Ergebnisübersicht. Aktuell zeigt der Button oben nur eine Demo-Ausgabe.",
|
||||
"point1": "Quick-Test mit kleiner Datenmenge.",
|
||||
"point2": "Light-Benchmark: Schreib-/Lesegeschwindigkeit über begrenzte Zeit.",
|
||||
"point3": "Write/Verify: Testdateien schreiben und direkt wieder verifizieren."
|
||||
},
|
||||
"result": {
|
||||
"title": "Demo-Ausgabe des Browser-Tests",
|
||||
"hint": "Diese Ausgabe dient nur als Vorschau. Später wird hier der echte JSON-Report aus dem Browser-Test angezeigt."
|
||||
}
|
||||
}
|
||||
},
|
||||
"login": {
|
||||
"meta": {
|
||||
"title": "Login – {{primary_domain}}",
|
||||
"description": "Melde dich bei {{primary_domain}} an, um Tests zu speichern, den Pro-Modus zu nutzen und mehrere Geräte zu verwalten."
|
||||
},
|
||||
"sections": {
|
||||
"auth": {
|
||||
"kicker": "Account & Login",
|
||||
"title": "Melde dich bei USBCheck an",
|
||||
"intro": "Mit einem Account kannst du Tests speichern, Reports exportieren und den Pro-Modus auf mehreren Geräten nutzen. Die Registrierung ist gratis – du kannst später jederzeit auf Pro upgraden.",
|
||||
"tab_login": "Login",
|
||||
"tab_register": "Registrieren",
|
||||
"login_title": "Login",
|
||||
"login_text": "Melde dich mit deiner E-Mail-Adresse und deinem Passwort an.",
|
||||
"login_email_label": "E-Mail-Adresse",
|
||||
"login_password_label": "Passwort",
|
||||
"login_submit": "Einloggen",
|
||||
"login_forgot": "Passwort vergessen?",
|
||||
"register_title": "Gratis registrieren",
|
||||
"register_text": "Erstelle einen gratis Account, um Tests zu speichern, Berichte zu exportieren und den Pro-Modus später freizuschalten.",
|
||||
"register_name_label": "Name",
|
||||
"register_email_label": "E-Mail-Adresse",
|
||||
"register_password_label": "Passwort",
|
||||
"register_submit": "Account erstellen",
|
||||
"register_hint": "Durch die Registrierung akzeptierst du die Datenschutzerklärung und das Impressum von USBCheck."
|
||||
}
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
"meta": {
|
||||
"title": "Dashboard – {{primary_domain}}",
|
||||
"description": "Verwalte deine USB-Tests, Geräte und Pro-Modus-Einstellungen in deinem persönlichen Dashboard."
|
||||
},
|
||||
"sections": {
|
||||
"main": {
|
||||
"kicker": "Dashboard",
|
||||
"title": "Willkommen",
|
||||
"intro": "Hier kannst du deine USB-Tests verwalten, Geräte übersichtlich organisieren und später den Pro-Modus aktivieren. Dieser Bereich ist aktuell noch im Aufbau – du bekommst aber schon einen ersten Überblick.",
|
||||
"plan_label": "Aktueller Plan",
|
||||
"card_tests_title": "Letzte Tests",
|
||||
"card_tests_text": "Hier werden später deine letzten Schnelltests und Pro-Scans angezeigt – inklusive Status, Geschwindigkeit und Integritätsprüfung.",
|
||||
"card_tests_empty": "Noch keine Testdaten vorhanden. Starte einen ersten Test über den Browser oder den Pro-Modus.",
|
||||
"card_devices_title": "Deine USB-Geräte",
|
||||
"card_devices_text": "Später kannst du hier deine getesteten Sticks verwalten: Hersteller, Modell, Seriennummer und erkannte Kapazität.",
|
||||
"card_devices_empty": "Noch keine Geräte gespeichert. Nach deinen ersten Tests kannst du USB-Sticks hier als Geräte anlegen.",
|
||||
"card_next_title": "Nächste Schritte",
|
||||
"card_next_text": "USBCheck ist noch im Aufbau. Du gehörst zu den ersten Nutzern – später findest du hier Pro-Optionen, API-Zugänge und Detail-Reports.",
|
||||
"card_next_item1": "• Browser-FakeCheck testen und Feedback geben",
|
||||
"card_next_item2": "• Pro-Modus-Features definieren (z. B. Vollscan, Reports, API)",
|
||||
"card_next_item3": "• Accounts & SSO (my-log.in) finalisieren",
|
||||
"card_next_cta": "Zum Browser-FakeCheck"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,10 @@
|
||||
{
|
||||
"meta": {
|
||||
"code": "de",
|
||||
"label": "Deutsch",
|
||||
"flag": "🇩🇪"
|
||||
},
|
||||
|
||||
"header": {
|
||||
"header_slogan": "USB-Sticks testen",
|
||||
"btn_login": "Login",
|
||||
@@ -15,152 +21,362 @@
|
||||
"brand_subtitle": "USB-Sticks auf Fakes testen"
|
||||
},
|
||||
|
||||
"hero": {
|
||||
"hero_kicker": "Erkenne Fake-USB-Sticks, bevor du Daten verlierst",
|
||||
"hero_title": "Ist mein USB-Stick ein Fake?<br><span class=\"text-brand-primary\">Finde es in wenigen Minuten heraus.</span>",
|
||||
"hero_lead": "USBCheck kombiniert einen schnellen Browser-Schnelltest mit einem professionellen Pro-Modus. So erkennst du gefälschte USB-Sticks, zu kleine echte Kapazität und langsame Billig-Controller – bevor deine Dateien verschwinden.",
|
||||
"cta_quick": "Kostenlosen Schnelltest starten",
|
||||
"cta_learn": "Mehr zu Free & Pro"
|
||||
},
|
||||
|
||||
"trust": {
|
||||
"trust1_title": "Keine Installation für Schnelltest",
|
||||
"trust1_text": "Browser-basierter Test direkt auf deinem Stick.",
|
||||
"trust2_title": "Echte Schreib- & Lesetests",
|
||||
"trust2_text": "Schreib-/Lesetests mit realen Daten – keine synthetischen Benchmarks.",
|
||||
"trust3_title": "Privacy first",
|
||||
"trust3_text": "Deine Testdaten bleiben lokal – Reports nur auf Wunsch."
|
||||
},
|
||||
|
||||
"quick": {
|
||||
"quick_label": "Schnelltest-Vorschau",
|
||||
"quick_title": "USB-Stick in unter 2 Minuten testen",
|
||||
"badge_free": "Kostenlos",
|
||||
"quick_intro": "Der Schnelltest prüft eine definierte Datenmenge auf deinem Stick und misst:",
|
||||
"quick_li1": "Schreib- und Leserate",
|
||||
"quick_li2": "Datenintegrität (Hash-Vergleich)",
|
||||
"quick_li3": "Verdächtige Abbrüche oder Fehler",
|
||||
"quick_metric1_label": "Schreibleistung",
|
||||
"quick_metric1_value": "~ 75–120 MB/s*",
|
||||
"quick_metric2_label": "Integritätsprüfung",
|
||||
"quick_metric2_value": "512 MB Testdaten",
|
||||
"quick_footnote": "*Beispielwerte – deine Ergebnisse hängen von Stick, Port & System ab.",
|
||||
"quick_cta": "Zum kostenlosen Schnelltest",
|
||||
"quick_visual_title": "Schnelltest-Anzeige",
|
||||
"quick_visual_text": "So sieht die Quick-Check-Vorschau aus: Grün markiert stabile Daten, Orange warnt, wenn die Schreibrate einbricht.",
|
||||
"quick_visual_window": "Ergebnisfenster"
|
||||
},
|
||||
|
||||
"how": {
|
||||
"how_kicker": "So funktioniert USBCheck",
|
||||
"how_title": "Schnelltest im Browser, Pro-Modus mit Tiefenanalyse.",
|
||||
"how_intro": "USBCheck wurde entwickelt, um zwei Welten zu verbinden: einen einfachen Schnelltest für alle und einen tiefgehenden Pro-Modus für Power-User, Techniker und Admins. Der Schnelltest läuft direkt im Browser, ohne Installation. Für den Pro-Modus wird ein kleines Helfer-Tool verwendet, das auf Wunsch F3- / badblocks-ähnliche Tests ausführt und damit Kapazitäts-Fakes sicher enttarnt.",
|
||||
"how_step1_title": "Browser-Test starten",
|
||||
"how_step1_text": "Du öffnest den Schnelltest unter <strong>{{primary_url}}/fakecheck/</strong>, wählst deinen USB-Stick bzw. einen Ordner darauf aus und definierst, wie viel Daten getestet werden sollen.",
|
||||
"how_step2_title": "Schreib-, Lese- und Integritätsprüfung",
|
||||
"how_step2_text": "Der Browser erstellt Testdateien, misst Schreib- und Leserate und vergleicht Hash-Werte, um Datenfehler zu erkennen – alles lokal und ohne Übertragung deiner Inhalte.",
|
||||
"how_step3_title": "Optional: Pro-Modus für Vollscan",
|
||||
"how_step3_text": "Wer mehr wissen will, installiert das optionale Helfer-Tool. Dieses kann die gesamte Kapazität des Sticks prüfen, Fakes identifizieren und detaillierte Reports erzeugen – ideal für Refurbisher, IT-Abteilungen oder Labore.",
|
||||
"how_side_title": "Free vs. Pro auf einen Blick",
|
||||
"how_side_free": "<strong>Free Quick Check:</strong> Geschwindigkeit & Integritätstest im Browser – ideal für schnelle Einschätzungen.",
|
||||
"how_side_pro": "<strong>Pro-Modus:</strong> Tiefenscan, Kapazitätsvalidierung, erweiterte Berichte und API-Integration für Unternehmen.",
|
||||
"how_side_account": "<strong>Account & Login:</strong> Nach dem Login kannst du Tests speichern, Berichte exportieren und mehrere Geräte verwalten."
|
||||
},
|
||||
|
||||
"problem": {
|
||||
"problem_kicker": "Warum gefälschte USB-Sticks gefährlich sind",
|
||||
"problem_title": "Gefälschte USB-Sticks kosten Geld – und im schlimmsten Fall deine Daten.",
|
||||
"problem_p1": "Viele Billig-USB-Sticks werben mit unrealistisch hohen Kapazitäten. In Wahrheit wurde der Controller manipuliert: Der Stick meldet z. B. 256 GB, obwohl physisch nur 32 GB verbaut sind. Die Folge: Daten werden scheinbar korrekt kopiert, später aber stillschweigend überschrieben oder beschädigt.",
|
||||
"problem_p2": "USBCheck hilft dir, solche Fakes zu erkennen, bevor du sie produktiv einsetzt – egal ob du einzelne Sticks privat nutzt oder größere Chargen für dein Unternehmen prüfst.",
|
||||
"problem_card1_title": "Verlust wichtiger Dateien",
|
||||
"problem_card1_text": "Fotos, Projektdateien, Backups – alles kann betroffen sein, wenn der Stick weniger speichert als behauptet. Defekte Sektoren bleiben oft unbemerkt, bis es zu spät ist.",
|
||||
"problem_card2_title": "Kosten durch defekte Chargen",
|
||||
"problem_card2_text": "Unternehmen, Reseller und Agenturen verteilen USB-Sticks oft in großer Stückzahl. Fakes bedeuten Reklamationen, Imageschaden und erneute Produktionskosten.",
|
||||
"problem_card3_title": "Unsichere Performance",
|
||||
"problem_card3_text": "Langsame Controller, instabile Firmware und schwankende Schreibraten sind typisch für Fake-Sticks. Das erhöht das Risiko von Fehlern – besonders bei großen Dateien."
|
||||
},
|
||||
|
||||
"features": {
|
||||
"features_kicker": "Free & Pro Features",
|
||||
"features_title": "Starte mit dem kostenlosen Schnelltest – wechsle in den Pro-Modus, wenn du mehr brauchst.",
|
||||
"features_intro": "USBCheck wächst mit deinen Anforderungen: Private Nutzer brauchen oft nur eine schnelle Einschätzung. Profis möchten tiefer einsteigen, Kapazitäten verifizieren und Reports archivieren. Genau dafür ist der Pro-Modus gedacht.",
|
||||
|
||||
"features_free_title": "Free Quick Check",
|
||||
"features_free_badge": "Empfohlen für die meisten Nutzer",
|
||||
"features_free_text": "Ideal für alle, die schnell prüfen möchten, ob ein USB-Stick zumindest grundlegend performant und stabil arbeitet – ganz ohne Installation.",
|
||||
"features_free_li1": "• Browser-basierter Schnelltest direkt auf deinem Stick",
|
||||
"features_free_li2": "• Schreib- und Lesegeschwindigkeit mit realen Testdaten",
|
||||
"features_free_li3": "• Hash-basierte Integritätsprüfung einer Testmenge",
|
||||
"features_free_li4": "• Auswahl verschiedener Teststufen (z. B. 200 MB, 2 GB)",
|
||||
"features_free_li5": "• Keine Registrierung erforderlich",
|
||||
"features_free_cta": "Kostenlosen Schnelltest starten",
|
||||
|
||||
"features_pro_title": "Pro Mode",
|
||||
"features_pro_badge": "Für Power-User & Teams",
|
||||
"features_pro_text": "Für alle, die volle Kontrolle brauchen: IT-Abteilungen, Techniker, Refurbisher, Labore oder Unternehmen, die regelmäßig größere Stick-Mengen testen.",
|
||||
"features_pro_li1": "• Tiefenscan der gesamten Kapazität (ähnlich F3 / badblocks)",
|
||||
"features_pro_li2": "• Erkennung von Kapazitäts-Fakes und defekten Bereichen",
|
||||
"features_pro_li3": "• Detaillierte, speicherbare Testberichte (JSON, PDF)",
|
||||
"features_pro_li4": "• Optional: API-Zugriff für automatisierte Testprozesse",
|
||||
"features_pro_li5": "• Multi-Device- und Multi-User-Support (über Login-Bereich)",
|
||||
"features_pro_note": "Der Pro-Modus erfordert ein kleines Helfer-Tool auf deinem System. Dieses arbeitet lokal und kann bei Bedarf mit deinem Account auf USBCheck verbunden werden."
|
||||
},
|
||||
|
||||
"security": {
|
||||
"security_kicker": "Security & Privacy",
|
||||
"security_title": "Privacy-first-Design: Deine Testdaten gehören dir.",
|
||||
"security_intro": "USBCheck wurde von Anfang an so konzipiert, dass deine Daten geschützt bleiben. Der Browser-Schnelltest arbeitet ausschließlich mit Testdateien. Deine eigenen Dokumente, Bilder oder Backups werden weder gelesen noch übertragen. Im Pro-Modus hast du volle Kontrolle, ob und welche Reports mit deinem Account synchronisiert werden.",
|
||||
"security_card1_title": "Local-only Tests",
|
||||
"security_card1_text": "Alle Schreib- und Lesetests erfolgen lokal auf deinem USB-Stick. Der Browser greift nur auf die Testdateien zu – nicht auf deine privaten Inhalte.",
|
||||
"security_card2_title": "Transparente Reports",
|
||||
"security_card2_text": "Wenn du dich einloggst, kannst du Testberichte in deinem Account speichern, exportieren oder wieder löschen. Du entscheidest, welche Daten im System bleiben.",
|
||||
"security_card3_title": "Schonend für deine Hardware",
|
||||
"security_card3_text": "Der Schnelltest arbeitet mit moderaten Datenmengen, um unnötigen Verschleiß zu vermeiden. Der Pro-Modus warnt deutlich, wenn ein Vollscan mit hoher Schreiblast ausgeführt wird."
|
||||
},
|
||||
|
||||
"faq": {
|
||||
"faq_kicker": "FAQ",
|
||||
"faq_title": "Häufige Fragen zu USBCheck",
|
||||
"faq_intro": "Hier findest du Antworten auf häufig gestellte Fragen. Der FAQ-Bereich kann jederzeit erweitert werden, wenn neue Anwendungsfälle hinzukommen oder du Feedback von Nutzern erhältst.",
|
||||
"faq_q1": "Ist der Schnelltest wirklich komplett im Browser?",
|
||||
"faq_a1": "Ja. Der Schnelltest läuft vollständig im Browser und nutzt moderne Browser-APIs, um Testdateien auf deinem Stick zu schreiben und wieder auszulesen. Es wird nichts ohne deine Zustimmung hochgeladen.",
|
||||
"faq_q2": "Brauche ich ein Konto, um den Schnelltest zu benutzen?",
|
||||
"faq_a2": "Nein. Der kostenlose Schnelltest ist ohne Registrierung nutzbar. Ein Login ist nur notwendig, wenn du Testberichte speichern, mehrere Sticks verwalten oder den Pro-Modus nutzen möchtest.",
|
||||
"faq_q3": "Kann USBCheck jeden Fake-Stick sicher erkennen?",
|
||||
"faq_a3": "Kein Tool kann eine 100 %-Garantie geben. Der Pro-Modus mit Vollscan ist jedoch darauf ausgelegt, typische Fälschungsmuster (Manipulation der gemeldeten Kapazität, instabile Bereiche, Fehler ab einer bestimmten Füllmenge) sehr zuverlässig zu erkennen.",
|
||||
"faq_q4": "Wie fügt sich das Tool in mein bestehendes System ein?",
|
||||
"faq_a4": "USBCheck ist von Anfang an für Automatisierung gedacht. Über den Pro-Modus und die geplante API kannst du Tests in bestehende Workflows integrieren – beispielsweise in Wareneingangsprüfungen oder Qualitätskontrollen."
|
||||
},
|
||||
|
||||
"footer": {
|
||||
"footer_imprint": "Impressum",
|
||||
"footer_privacy": "Datenschutz",
|
||||
"footer_copy": "© {year} {{primary_domain}}. Alle Rechte vorbehalten."
|
||||
},
|
||||
"fake": {
|
||||
"fake_hero_kicker": "FakeCheck – Browser-Modus",
|
||||
"fake_hero_title": "Ist mein USB-Stick fake?",
|
||||
"fake_hero_lead": "Der FakeCheck hilft dir, typische Fake-Sticks aufzuspüren: Browser-basierte Schreib-/Lesetests und Plausibilitätsprüfungen der nutzbaren Kapazität – ohne Installation.",
|
||||
"fake_cta_start": "Browser-Test starten (Demo)",
|
||||
"fake_cta_back_home": "Zur Übersicht zurück",
|
||||
"fake_hero_hint": "Der FakeCheck im Browser arbeitet mit Testdateien und Lese-/Schreibmustern, die du in einem ausgewählten Ordner anlegst. Deine echten Dateien bleiben unangetastet.",
|
||||
|
||||
"fake_box_title": "Was der Browser-Test leisten kann",
|
||||
"fake_box_point1_title": "Schreib-/Lesetest mit Testdateien",
|
||||
"fake_box_point1_text": "Der Browser legt Testdateien im gewählten Ordner an, misst Schreib- und Leseraten und prüft, ob gelesene Daten mit den geschriebenen Mustern übereinstimmen.",
|
||||
"fake_box_point2_title": "Plausibilitätscheck der Kapazität",
|
||||
"fake_box_point2_text": "Aus der Menge der erfolgreich geschriebenen und verifizierten Daten ergibt sich ein realistischer Eindruck, wie viel Nutzkapazität tatsächlich stabil ankommt.",
|
||||
"fake_box_point3_title": "JSON-Report für deine Dokumentation",
|
||||
"fake_box_point3_text": "Alle Ergebnisse werden in einem strukturierten JSON-Report gesammelt, den du speichern, hochladen oder für spätere Vergleiche nutzen kannst.",
|
||||
"fake_ui": {
|
||||
"error_fsapi_not_supported": "Die File System Access API wird von diesem Browser nicht unterstützt.",
|
||||
"error_no_directory_selected": "Kein Verzeichnis ausgewählt.",
|
||||
"error_no_space_detected": "Es konnte kein freier Speicher im gewählten Verzeichnis reserviert werden.",
|
||||
|
||||
"fake_app_title": "Browser-Testoberfläche (Preview)",
|
||||
"fake_app_intro": "Hier entsteht die eigentliche FakeCheck-Web-App: Auswahl des Testordners, Konfiguration der Testmenge, Fortschrittsanzeige und Ergebnisübersicht. Aktuell zeigt der Button oben nur eine Demo-Ausgabe.",
|
||||
"fake_app_point1": "Quick-Test mit kleiner Datenmenge.",
|
||||
"fake_app_point2": "Light-Benchmark: Schreib-/Lesegeschwindigkeit über begrenzte Zeit.",
|
||||
"fake_app_point3": "Write/Verify: Testdateien schreiben und direkt wieder verifizieren.",
|
||||
|
||||
"fake_result_title": "Demo-Ausgabe des Browser-Tests",
|
||||
"fake_result_hint": "Diese Ausgabe dient nur als Vorschau. Später wird hier der echte JSON-Report aus dem Browser-Test angezeigt."
|
||||
}
|
||||
"log_capacity_probe_start": "Ermittle verfügbaren Speicherplatz im gewählten Verzeichnis...",
|
||||
"log_capacity_probe_result": "Ermittelter für Tests nutzbarer Speicher: {size} (Schreibprobe).",
|
||||
|
||||
"log_quick_prepare": "Quick-Check: Vorbereitung... (Testgröße: {size})",
|
||||
"log_quick_verify_start": "Quick-Check: Schreiben abgeschlossen. Verifiziere Daten...",
|
||||
"log_quick_data_error": "Quick-Check: Datenfehler bei Byte {byte}.",
|
||||
"error_quick_data_error": "Datenfehler im Quick-Check bei Byte {byte}.",
|
||||
"log_quick_delete_warn": "Quick-Check: Konnte Testdatei nicht löschen (nicht kritisch).",
|
||||
"log_quick_success": "Quick-Check: Erfolgreich abgeschlossen.",
|
||||
|
||||
"log_bench_start": "Benchmark: Start – schreibe Testdatei ({size})...",
|
||||
"log_bench_read_start": "Benchmark: Lesen & Timing...",
|
||||
"log_bench_delete_warn": "Benchmark: Konnte Testdatei nicht löschen (nicht kritisch).",
|
||||
"log_bench_success": "Benchmark: Erfolgreich abgeschlossen.",
|
||||
|
||||
"log_wv_start": "Write/Verify: Start – {blocks} Blöcke à {size} (gesamt {total})...",
|
||||
"log_wv_block_start": "Write/Verify: Block {num}/{blocks} – {file}",
|
||||
"log_wv_data_error": "Write/Verify: Datenfehler in Block {num} bei Byte {byte}.",
|
||||
"error_wv_data_error": "Datenfehler in Block {num} bei Byte {byte}.",
|
||||
"log_wv_delete_warn": "Write/Verify: Konnte Blockdatei {file} nicht löschen (nicht kritisch).",
|
||||
"log_wv_success": "Write/Verify: Alle Blöcke erfolgreich verifiziert.",
|
||||
|
||||
"log_all_subtest_start": "All-Inclusive: Starte Teiltest \"{mode}\" ({num}/{total})...",
|
||||
"error_unknown_mode": "Unbekannter Modus: {mode}",
|
||||
|
||||
"log_fsapi_partial": "Dein Browser unterstützt die File System Access API nicht voll. Einige Funktionen sind deaktiviert.",
|
||||
|
||||
"selected_path_label": "USB-Ordner ausgewählt (Name: \"{name}\").",
|
||||
"selected_path_none": "Noch kein Verzeichnis gewählt.",
|
||||
|
||||
"status_ready": "Bereit. Wähle zuerst deinen USB-Stick aus.",
|
||||
"status_mode_none": "Kein Modus selektiert",
|
||||
"status_dir_selected": "USB-Verzeichnis ausgewählt. Wähle jetzt einen Testmodus.",
|
||||
"status_mode_selected": "Modus \"{mode}\" ausgewählt. Du kannst den Test jetzt starten.",
|
||||
"status_running": "Test läuft... bitte USB-Stick nicht entfernen.",
|
||||
"status_done": "Test abgeschlossen.",
|
||||
"status_aborted": "Test wurde abgebrochen.",
|
||||
"status_error": "Fehler: {msg}",
|
||||
"status_error_unknown": "Unbekannter Fehler im Test.",
|
||||
|
||||
"overall_initial": "Noch kein Test durchgeführt.",
|
||||
"overall_running": "Test läuft...",
|
||||
"overall_done": "Browser-Test erfolgreich abgeschlossen.",
|
||||
"overall_aborted": "Test abgebrochen.",
|
||||
"overall_error": "Fehler im Browser-Test.",
|
||||
|
||||
"log_dir_selected": "Verzeichnis ausgewählt: {name}",
|
||||
"log_dir_reset": "Verzeichnisauswahl zurückgesetzt.",
|
||||
"log_pick_abort": "Verzeichnisauswahl abgebrochen.",
|
||||
"log_pick_error": "Fehler bei Verzeichnisauswahl: {msg}",
|
||||
"log_pick_error_unknown": "Unbekannter Fehler bei Verzeichnisauswahl.",
|
||||
"log_mode_selected": "Modus gewählt: {mode}",
|
||||
"log_test_start": "Starte Tests im Modus: {mode}",
|
||||
"log_test_aborted": "Test wurde vom Benutzer abgebrochen.",
|
||||
"log_test_error": "Fehler im Test: {msg}",
|
||||
"log_test_error_unknown": "Unbekannter Fehler im Test.",
|
||||
"log_loaded": "USB-Browser-Test (fakecheck) geladen. Warte auf Verzeichnisauswahl und Modus.",
|
||||
|
||||
"mode_quick": "Quick-Check",
|
||||
"mode_benchmark": "Benchmark",
|
||||
"mode_writeverify": "Write & Verify",
|
||||
"mode_all": "All-Inclusive (alle Browser-Tests)",
|
||||
|
||||
"log_backend_save_error_status": "Backend: Konnte Ergebnis nicht speichern ({status}).",
|
||||
"log_backend_save_ok": "Backend: Testergebnis gespeichert{suffix}.",
|
||||
"log_backend_save_error": "Fehler beim Speichern im Backend: {msg}"
|
||||
},
|
||||
|
||||
"serial": {
|
||||
"rating_label": "Bewertung",
|
||||
|
||||
"rating": {
|
||||
"ok": {
|
||||
"label": "Plausibel",
|
||||
"desc": "Keine deutlichen Auffälligkeiten erkannt."
|
||||
},
|
||||
"needs_review": {
|
||||
"label": "Überprüfung empfohlen",
|
||||
"desc": "Leichte Auffälligkeiten. In Kombination mit einem technischen Test ergibt sich ein klareres Bild."
|
||||
},
|
||||
"suspicious": {
|
||||
"label": "Auffällig / Verdächtig",
|
||||
"desc": "Deutliche Auffälligkeiten erkannt. Ein Kapazitäts- oder Schreib-/Lesetest ist dringend empfohlen."
|
||||
},
|
||||
"invalid": {
|
||||
"label": "Ungültig",
|
||||
"desc": "Die Seriennummer konnte nicht sinnvoll bewertet werden."
|
||||
},
|
||||
"unknown": {
|
||||
"label": "Unklar",
|
||||
"desc": "Bewertung nicht eindeutig möglich."
|
||||
}
|
||||
},
|
||||
|
||||
"heading_input": "Eingabedaten",
|
||||
"heading_analysis": "Seriennummer-Analyse",
|
||||
"heading_consistency": "Hersteller-Konsistenz",
|
||||
|
||||
"input": {
|
||||
"manufacturer": "Hersteller (Angabe):",
|
||||
"vidpid": "VID/PID:",
|
||||
"vendor_detected": "Vendor aus VID:"
|
||||
},
|
||||
|
||||
"analysis": {
|
||||
"serial": "Seriennummer:",
|
||||
"length": "Länge:",
|
||||
"category": "Kategorie:",
|
||||
"score": "Score:",
|
||||
"issues": "Auffälligkeiten:"
|
||||
},
|
||||
|
||||
"chars": "Zeichen",
|
||||
"none": "keine Angabe",
|
||||
|
||||
"issues_none": "Keine besonderen Auffälligkeiten.",
|
||||
|
||||
"vendor_detected": "{vendor} (VID {vid})",
|
||||
"vendor_unknown": "Unbekannter Hersteller für VID {vid}",
|
||||
"vendor_none": "Keine Vendor-ID angegeben",
|
||||
|
||||
"disclaimer": "Diese Einschätzung basiert auf Heuristiken und kann keine Echtheit garantieren.",
|
||||
|
||||
"error": {
|
||||
"no_serial": "Bitte gib eine Seriennummer ein.",
|
||||
"api": "Fehler bei der Prüfung: {msg}",
|
||||
"unknown": "Unerwartete Antwort vom Server."
|
||||
}
|
||||
},
|
||||
|
||||
"pages": {
|
||||
"landing": {
|
||||
"meta": {
|
||||
"title": "{{primary_domain}} – USB-Sticks auf Fakes testen",
|
||||
"description": "USBCheck kombiniert einen schnellen Browser-Schnelltest mit einem professionellen Pro-Modus. So erkennst du gefälschte USB-Sticks, zu kleine echte Kapazität und langsame Billig-Controller – bevor deine Dateien verschwinden."
|
||||
},
|
||||
"sections": {
|
||||
"hero": {
|
||||
"kicker": "Erkenne Fake-USB-Sticks, bevor du Daten verlierst",
|
||||
"title": "Ist mein USB-Stick ein Fake?",
|
||||
"lead": "USBCheck kombiniert einen schnellen Browser-Schnelltest mit einem professionellen Pro-Modus. So erkennst du gefälschte USB-Sticks, zu kleine echte Kapazität und langsame Billig-Controller – bevor deine Dateien verschwinden.",
|
||||
"cta_quick": "Kostenlosen Schnelltest starten",
|
||||
"cta_learn": "Mehr zu Free & Pro"
|
||||
},
|
||||
"trust": {
|
||||
"t1_title": "Keine Installation für Schnelltest",
|
||||
"t1_text": "Browser-basierter Test direkt auf deinem Stick.",
|
||||
"t2_title": "Echte Schreib- & Lesetests",
|
||||
"t2_text": "Schreib-/Lesetests mit realen Daten – keine synthetischen Benchmarks.",
|
||||
"t3_title": "Privacy first",
|
||||
"t3_text": "Deine Testdaten bleiben lokal – Reports nur auf Wunsch."
|
||||
},
|
||||
"quick": {
|
||||
"label": "Schnelltest-Vorschau",
|
||||
"title": "USB-Stick in unter 2 Minuten testen",
|
||||
"badge_free": "Kostenlos",
|
||||
"intro": "Der Schnelltest prüft eine definierte Datenmenge auf deinem Stick und misst:",
|
||||
"li1": "Schreib- und Leserate",
|
||||
"li2": "Datenintegrität (Hash-Vergleich)",
|
||||
"li3": "Verdächtige Abbrüche oder Fehler",
|
||||
"metric1_label": "Schreibleistung",
|
||||
"metric1_value": "~ 75–120 MB/s*",
|
||||
"metric2_label": "Integritätsprüfung",
|
||||
"metric2_value": "512 MB Testdaten",
|
||||
"footnote": "*Beispielwerte – deine Ergebnisse hängen von Stick, Port & System ab.",
|
||||
"cta": "Zum kostenlosen Schnelltest",
|
||||
"visual_title": "Schnelltest-Anzeige",
|
||||
"visual_text": "So sieht die Quick-Check-Vorschau aus: Grün markiert stabile Daten, Orange warnt, wenn die Schreibrate einbricht.",
|
||||
"visual_window": "Ergebnisfenster"
|
||||
},
|
||||
"how": {
|
||||
"kicker": "So funktioniert USBCheck",
|
||||
"title": "Schnelltest im Browser, Pro-Modus mit Tiefenanalyse.",
|
||||
"intro": "USBCheck wurde entwickelt, um zwei Welten zu verbinden: einen einfachen Schnelltest für alle und einen tiefgehenden Pro-Modus für Power-User, Techniker und Admins. Der Schnelltest läuft direkt im Browser, ohne Installation. Für den Pro-Modus wird ein kleines Helfer-Tool verwendet, das auf Wunsch F3- / badblocks-ähnliche Tests ausführt und damit Kapazitäts-Fakes sicher enttarnt.",
|
||||
"step1_title": "Browser-Test starten",
|
||||
"step1_text": "Du öffnest den Schnelltest unter <strong>{{primary_url}}/fakecheck/</strong>, wählst deinen USB-Stick bzw. einen Ordner darauf aus und definierst, wie viel Daten getestet werden sollen.",
|
||||
"step2_title": "Schreib-, Lese- und Integritätsprüfung",
|
||||
"step2_text": "Der Browser erstellt Testdateien, misst Schreib- und Leserate und vergleicht Hash-Werte, um Datenfehler zu erkennen – alles lokal und ohne Übertragung deiner Inhalte.",
|
||||
"step3_title": "Optional: Pro-Modus für Vollscan",
|
||||
"step3_text": "Wer mehr wissen will, installiert das optionale Helfer-Tool. Dieses kann die gesamte Kapazität des Sticks prüfen, Fakes identifizieren und detaillierte Reports erzeugen – ideal für Refurbisher, IT-Abteilungen oder Labore.",
|
||||
"side_title": "Free vs. Pro auf einen Blick",
|
||||
"side_free": "<strong>Free Quick Check:</strong> Geschwindigkeit & Integritätstest im Browser – ideal für schnelle Einschätzungen.",
|
||||
"side_pro": "<strong>Pro-Modus:</strong> Tiefenscan, Kapazitätsvalidierung, erweiterte Berichte und API-Integration für Unternehmen.",
|
||||
"side_account": "<strong>Account & Login:</strong> Nach dem Login kannst du Tests speichern, Berichte exportieren und mehrere Geräte verwalten."
|
||||
},
|
||||
"problem": {
|
||||
"kicker": "Warum gefälschte USB-Sticks gefährlich sind",
|
||||
"title": "Gefälschte USB-Sticks kosten Geld – und im schlimmsten Fall deine Daten.",
|
||||
"p1": "Viele Billig-USB-Sticks werben mit unrealistisch hohen Kapazitäten. In Wahrheit wurde der Controller manipuliert: Der Stick meldet z. B. 256 GB, obwohl physisch nur 32 GB verbaut sind. Die Folge: Daten werden scheinbar korrekt kopiert, später aber stillschweigend überschrieben oder beschädigt.",
|
||||
"p2": "USBCheck hilft dir, solche Fakes zu erkennen, bevor du sie produktiv einsetzt – egal ob du einzelne Sticks privat nutzt oder größere Chargen für dein Unternehmen prüfst.",
|
||||
"card1_title": "Verlust wichtiger Dateien",
|
||||
"card1_text": "Fotos, Projektdateien, Backups – alles kann betroffen sein, wenn der Stick weniger speichert als behauptet. Defekte Sektoren bleiben oft unbemerkt, bis es zu spät ist.",
|
||||
"card2_title": "Kosten durch defekte Chargen",
|
||||
"card2_text": "Unternehmen, Reseller und Agenturen verteilen USB-Sticks oft in großer Stückzahl. Fakes bedeuten Reklamationen, Imageschaden und erneute Produktionskosten.",
|
||||
"card3_title": "Unsichere Performance",
|
||||
"card3_text": "Langsame Controller, instabile Firmware und schwankende Schreibraten sind typisch für Fake-Sticks. Das erhöht das Risiko von Fehlern – besonders bei großen Dateien."
|
||||
},
|
||||
"features": {
|
||||
"kicker": "Free & Pro Features",
|
||||
"title": "Starte mit dem kostenlosen Schnelltest – wechsle in den Pro-Modus, wenn du mehr brauchst.",
|
||||
"intro": "USBCheck wächst mit deinen Anforderungen: Private Nutzer brauchen oft nur eine schnelle Einschätzung. Profis möchten tiefer einsteigen, Kapazitäten verifizieren und Reports archivieren. Genau dafür ist der Pro-Modus gedacht.",
|
||||
"free_title": "Free Quick Check",
|
||||
"free_badge": "Empfohlen für die meisten Nutzer",
|
||||
"free_text": "Ideal für alle, die schnell prüfen möchten, ob ein USB-Stick zumindest grundlegend performant und stabil arbeitet – ganz ohne Installation.",
|
||||
"free_li1": "• Browser-basierter Schnelltest direkt auf deinem Stick",
|
||||
"free_li2": "• Schreib- und Lesegeschwindigkeit mit realen Testdaten",
|
||||
"free_li3": "• Hash-basierte Integritätsprüfung einer Testmenge",
|
||||
"free_li4": "• Auswahl verschiedener Teststufen (z. B. 200 MB, 2 GB)",
|
||||
"free_li5": "• Keine Registrierung erforderlich",
|
||||
"free_cta": "Kostenlosen Schnelltest starten",
|
||||
"pro_title": "Pro Mode",
|
||||
"pro_badge": "Für Power-User & Teams",
|
||||
"pro_text": "Für alle, die volle Kontrolle brauchen: IT-Abteilungen, Techniker, Refurbisher, Labore oder Unternehmen, die regelmäßig größere Stick-Mengen testen.",
|
||||
"pro_li1": "• Tiefenscan der gesamten Kapazität (ähnlich F3 / badblocks)",
|
||||
"pro_li2": "• Erkennung von Kapazitäts-Fakes und defekten Bereichen",
|
||||
"pro_li3": "• Detaillierte, speicherbare Testberichte (JSON, PDF)",
|
||||
"pro_li4": "• Optional: API-Zugriff für automatisierte Testprozesse",
|
||||
"pro_li5": "• Multi-Device- und Multi-User-Support (über Login-Bereich)",
|
||||
"pro_note": "Der Pro-Modus erfordert ein kleines Helfer-Tool auf deinem System. Dieses arbeitet lokal und kann bei Bedarf mit deinem Account auf USBCheck verbunden werden."
|
||||
},
|
||||
"security": {
|
||||
"kicker": "Security & Privacy",
|
||||
"title": "Privacy-first-Design: Deine Testdaten gehören dir.",
|
||||
"intro": "USBCheck wurde von Anfang an so konzipiert, dass deine Daten geschützt bleiben. Der Browser-Schnelltest arbeitet ausschließlich mit Testdateien. Deine eigenen Dokumente, Bilder oder Backups werden weder gelesen noch übertragen. Im Pro-Modus hast du volle Kontrolle, ob und welche Reports mit deinem Account synchronisiert werden.",
|
||||
"card1_title": "Local-only Tests",
|
||||
"card1_text": "Alle Schreib- und Lesetests erfolgen lokal auf deinem USB-Stick. Der Browser greift nur auf die Testdateien zu – nicht auf deine privaten Inhalte.",
|
||||
"card2_title": "Transparente Reports",
|
||||
"card2_text": "Wenn du dich einloggst, kannst du Testberichte in deinem Account speichern, exportieren oder wieder löschen. Du entscheidest, welche Daten im System bleiben.",
|
||||
"card3_title": "Schonend für deine Hardware",
|
||||
"card3_text": "Der Schnelltest arbeitet mit moderaten Datenmengen, um unnötigen Verschleiß zu vermeiden. Der Pro-Modus warnt deutlich, wenn ein Vollscan mit hoher Schreiblast ausgeführt wird."
|
||||
},
|
||||
"faq": {
|
||||
"kicker": "FAQ",
|
||||
"title": "Häufige Fragen zu USBCheck",
|
||||
"intro": "Hier findest du Antworten auf häufig gestellte Fragen. Der FAQ-Bereich kann jederzeit erweitert werden, wenn neue Anwendungsfälle hinzukommen oder du Feedback von Nutzern erhältst.",
|
||||
"q1": "Ist der Schnelltest wirklich komplett im Browser?",
|
||||
"a1": "Ja. Der Schnelltest läuft vollständig im Browser und nutzt moderne Browser-APIs, um Testdateien auf deinem Stick zu schreiben und wieder auszulesen. Es wird nichts ohne deine Zustimmung hochgeladen.",
|
||||
"q2": "Brauche ich ein Konto, um den Schnelltest zu benutzen?",
|
||||
"a2": "Nein. Der kostenlose Schnelltest ist ohne Registrierung nutzbar. Ein Login ist nur notwendig, wenn du Testberichte speichern, mehrere Sticks verwalten oder den Pro-Modus nutzen möchtest.",
|
||||
"q3": "Kann USBCheck jeden Fake-Stick sicher erkennen?",
|
||||
"a3": "Kein Tool kann eine 100 %-Garantie geben. Der Pro-Modus mit Vollscan ist jedoch darauf ausgelegt, typische Fälschungsmuster (Manipulation der gemeldeten Kapazität, instabile Bereiche, Fehler ab einer bestimmten Füllmenge) sehr zuverlässig zu erkennen.",
|
||||
"q4": "Wie fügt sich das Tool in mein bestehendes System ein?",
|
||||
"a4": "USBCheck ist von Anfang an für Automatisierung gedacht. Über den Pro-Modus und die geplante API kannst du Tests in bestehende Workflows integrieren – beispielsweise in Wareneingangsprüfungen oder Qualitätskontrollen."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"fakecheck": {
|
||||
"meta": {
|
||||
"title": "FakeCheck – Browser-Test für USB-Sticks",
|
||||
"description": "Der FakeCheck hilft dir, typische Fake-Sticks aufzuspüren: Browser-basierte Schreib-/Lesetests und Plausibilitätsprüfungen der nutzbaren Kapazität – ohne Installation."
|
||||
},
|
||||
"sections": {
|
||||
"hero": {
|
||||
"kicker": "FakeCheck – Browser-Modus",
|
||||
"title": "Ist mein USB-Stick fake?",
|
||||
"lead": "Der FakeCheck hilft dir, typische Fake-Sticks aufzuspüren: Browser-basierte Schreib-/Lesetests und Plausibilitätsprüfungen der nutzbaren Kapazität – ohne Installation.",
|
||||
"cta_start": "Browser-Test starten (Demo)",
|
||||
"cta_back_home": "Zur Übersicht zurück",
|
||||
"hint": "Der FakeCheck im Browser arbeitet mit Testdateien und Lese-/Schreibmustern, die du in einem ausgewählten Ordner anlegst. Deine echten Dateien bleiben unangetastet."
|
||||
},
|
||||
"capabilities": {
|
||||
"title": "Was der Browser-Test leisten kann",
|
||||
"point1_title": "Schreib-/Lesetest mit Testdateien",
|
||||
"point1_text": "Der Browser legt Testdateien im gewählten Ordner an, misst Schreib- und Leseraten und prüft, ob gelesene Daten mit den geschriebenen Mustern übereinstimmen.",
|
||||
"point2_title": "Plausibilitätscheck der Kapazität",
|
||||
"point2_text": "Aus der Menge der erfolgreich geschriebenen und verifizierten Daten ergibt sich ein realistischer Eindruck, wie viel Nutzkapazität tatsächlich stabil ankommt.",
|
||||
"point3_title": "JSON-Report für deine Dokumentation",
|
||||
"point3_text": "Alle Ergebnisse werden in einem strukturierten JSON-Report gesammelt, den du speichern, hochladen oder für spätere Vergleiche nutzen kannst."
|
||||
},
|
||||
"app": {
|
||||
"title": "Browser-Testoberfläche (Preview)",
|
||||
"intro": "Hier entsteht die eigentliche FakeCheck-Web-App: Auswahl des Testordners, Konfiguration der Testmenge, Fortschrittsanzeige und Ergebnisübersicht. Aktuell zeigt der Button oben nur eine Demo-Ausgabe.",
|
||||
"point1": "Quick-Test mit kleiner Datenmenge.",
|
||||
"point2": "Light-Benchmark: Schreib-/Lesegeschwindigkeit über begrenzte Zeit.",
|
||||
"point3": "Write/Verify: Testdateien schreiben und direkt wieder verifizieren."
|
||||
},
|
||||
"result": {
|
||||
"title": "Demo-Ausgabe des Browser-Tests",
|
||||
"hint": "Diese Ausgabe dient nur als Vorschau. Später wird hier der echte JSON-Report aus dem Browser-Test angezeigt."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"login": {
|
||||
"meta": {
|
||||
"title": "Login – {{primary_domain}}",
|
||||
"description": "Melde dich bei {{primary_domain}} an, um Tests zu speichern, den Pro-Modus zu nutzen und mehrere Geräte zu verwalten."
|
||||
},
|
||||
"sections": {
|
||||
"auth": {
|
||||
"kicker": "Account & Login",
|
||||
"title": "Melde dich bei USBCheck an",
|
||||
"intro": "Mit einem Account kannst du Tests speichern, Reports exportieren und den Pro-Modus auf mehreren Geräten nutzen. Die Registrierung ist kostenlos – du kannst später jederzeit auf Pro upgraden.",
|
||||
|
||||
"tab_login": "Login",
|
||||
"tab_register": "Registrieren",
|
||||
|
||||
"login_title": "Login",
|
||||
"login_text": "Melde dich mit deiner E-Mail-Adresse und deinem Passwort an.",
|
||||
"login_email_label": "E-Mail-Adresse",
|
||||
"login_password_label": "Passwort",
|
||||
"login_submit": "Einloggen",
|
||||
"login_forgot": "Passwort vergessen?",
|
||||
|
||||
"register_title": "Kostenlos registrieren",
|
||||
"register_text": "Erstelle einen kostenlosen Account, um Tests zu speichern, Berichte zu exportieren und den Pro-Modus später freizuschalten.",
|
||||
"register_name_label": "Name",
|
||||
"register_email_label": "E-Mail-Adresse",
|
||||
"register_password_label": "Passwort",
|
||||
"register_submit": "Account erstellen",
|
||||
"register_hint": "Durch die Registrierung akzeptierst du die Datenschutzerklärung und das Impressum von USBCheck."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"dashboard": {
|
||||
"meta": {
|
||||
"title": "Dashboard – {{primary_domain}}",
|
||||
"description": "Verwalte deine USB-Tests, Geräte und Pro-Modus-Einstellungen in deinem persönlichen Dashboard."
|
||||
},
|
||||
"sections": {
|
||||
"main": {
|
||||
"kicker": "Dashboard",
|
||||
"title": "Willkommen",
|
||||
"intro": "Hier kannst du deine USB-Tests verwalten, Geräte übersichtlich organisieren und später den Pro-Modus aktivieren. Dieser Bereich ist aktuell noch im Aufbau – du bekommst aber schon einen ersten Überblick.",
|
||||
|
||||
"plan_label": "Aktueller Plan",
|
||||
|
||||
"card_tests_title": "Letzte Tests",
|
||||
"card_tests_text": "Hier werden später deine letzten Schnelltests und Pro-Scans angezeigt – inklusive Status, Geschwindigkeit und Integritätsprüfung.",
|
||||
"card_tests_empty": "Noch keine Testdaten vorhanden. Starte einen ersten Test über den Browser oder den Pro-Modus.",
|
||||
|
||||
"card_devices_title": "Deine USB-Geräte",
|
||||
"card_devices_text": "Später kannst du hier deine getesteten Sticks verwalten: Hersteller, Modell, Seriennummer und erkannte Kapazität.",
|
||||
"card_devices_empty": "Noch keine Geräte gespeichert. Nach deinen ersten Tests kannst du USB-Sticks hier als Geräte anlegen.",
|
||||
|
||||
"card_next_title": "Nächste Schritte",
|
||||
"card_next_text": "USBCheck ist noch im Aufbau. Du gehörst zu den ersten Nutzern – später findest du hier Pro-Optionen, API-Zugänge und Detail-Reports.",
|
||||
"card_next_item1": "• Browser-FakeCheck testen und Feedback geben",
|
||||
"card_next_item2": "• Pro-Modus-Features definieren (z. B. Vollscan, Reports, API)",
|
||||
"card_next_item3": "• Accounts & SSO (my-log.in) finalisieren",
|
||||
"card_next_cta": "Zum Browser-FakeCheck"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
173
public/assets/i18n/dk.json
Normal file
173
public/assets/i18n/dk.json
Normal file
@@ -0,0 +1,173 @@
|
||||
{
|
||||
"meta": {
|
||||
"code": "dk",
|
||||
"label": "Dansk",
|
||||
"flag": "🇩🇰"
|
||||
},
|
||||
|
||||
"header": {
|
||||
"header_slogan": "Test USB-drev",
|
||||
"btn_login": "Login",
|
||||
|
||||
"nav_how": "Sådan fungerer det",
|
||||
"nav_problem": "Hvorfor det er vigtigt",
|
||||
"nav_features": "Funktioner",
|
||||
"nav_security": "Sikkerhed",
|
||||
"nav_faq": "FAQ"
|
||||
},
|
||||
|
||||
"brand": {
|
||||
"brand_wordmark": "{{primary_domain}}",
|
||||
"brand_subtitle": "Tjek USB-drev for forfalskninger"
|
||||
},
|
||||
|
||||
"footer": {
|
||||
"footer_imprint": "Imprint",
|
||||
"footer_privacy": "Privatliv",
|
||||
"footer_copy": "© {year} {{primary_domain}}. Alle rettigheder forbeholdes."
|
||||
},
|
||||
|
||||
"fake_ui": {
|
||||
"error_fsapi_not_supported": "Denne browser understøtter ikke File System Access API.",
|
||||
"error_no_directory_selected": "Ingen mappe valgt.",
|
||||
"error_no_space_detected": "Det var ikke muligt at reservere ledig plads i den valgte mappe.",
|
||||
|
||||
"log_capacity_probe_start": "Finder ledig plads i den valgte mappe...",
|
||||
"log_capacity_probe_result": "Registreret plads der kan bruges til tests: {size} (skriveprobe).",
|
||||
|
||||
"log_quick_prepare": "Quick-check: forbereder... (teststørrelse: {size})",
|
||||
"log_quick_verify_start": "Quick-check: skrivning færdig. Verificerer data...",
|
||||
"log_quick_data_error": "Quick-check: datafejl ved byte {byte}.",
|
||||
"error_quick_data_error": "Datafejl i quick-check ved byte {byte}.",
|
||||
"log_quick_delete_warn": "Quick-check: kunne ikke slette testfil (ikke kritisk).",
|
||||
"log_quick_success": "Quick-check: gennemført med succes.",
|
||||
|
||||
"log_bench_start": "Benchmark: start – skriver testfil ({size})...",
|
||||
"log_bench_read_start": "Benchmark: læser og måler...",
|
||||
"log_bench_delete_warn": "Benchmark: kunne ikke slette testfil (ikke kritisk).",
|
||||
"log_bench_success": "Benchmark: afsluttet med succes.",
|
||||
|
||||
"log_wv_start": "Write/Verify: start – {blocks} blokke á {size} (i alt {total})...",
|
||||
"log_wv_block_start": "Write/Verify: blok {num}/{blocks} – {file}",
|
||||
"log_wv_data_error": "Write/Verify: datafejl i blok {num} ved byte {byte}.",
|
||||
"error_wv_data_error": "Datafejl i blok {num} ved byte {byte}.",
|
||||
"log_wv_delete_warn": "Write/Verify: kunne ikke slette blokfilen {file} (ikke kritisk).",
|
||||
"log_wv_success": "Write/Verify: alle blokke verificeret med succes.",
|
||||
|
||||
"log_all_subtest_start": "All-inclusive: starter deltest \"{mode}\" ({num}/{total})...",
|
||||
"error_unknown_mode": "Ukendt tilstand: {mode}",
|
||||
|
||||
"log_fsapi_partial": "Din browser understøtter ikke File System Access API fuldt ud. Visse funktioner er deaktiveret.",
|
||||
|
||||
"selected_path_label": "USB-mappe valgt (navn: \"{name}\").",
|
||||
"selected_path_none": "Der er endnu ikke valgt en mappe.",
|
||||
|
||||
"status_ready": "Klar. Vælg først dit USB-drev.",
|
||||
"status_mode_none": "Ingen tilstand valgt",
|
||||
"status_dir_selected": "USB-mappe valgt. Vælg nu en testtilstand.",
|
||||
"status_mode_selected": "Tilstand \"{mode}\" valgt. Du kan starte testen nu.",
|
||||
"status_running": "Test kører... fjern venligst ikke USB-drevet.",
|
||||
"status_done": "Test afsluttet.",
|
||||
"status_aborted": "Testen blev afbrudt.",
|
||||
"status_error": "Fejl: {msg}",
|
||||
"status_error_unknown": "Ukendt fejl i testen.",
|
||||
|
||||
"overall_initial": "Der er endnu ikke kørt en test.",
|
||||
"overall_running": "Test kører...",
|
||||
"overall_done": "Browser-test gennemført med succes.",
|
||||
"overall_aborted": "Test afbrudt.",
|
||||
"overall_error": "Fejl i browser-testen.",
|
||||
|
||||
"log_dir_selected": "Mappe valgt: {name}",
|
||||
"log_dir_reset": "Mappevalg nulstillet.",
|
||||
"log_pick_abort": "Mappevalg annulleret.",
|
||||
"log_pick_error": "Fejl ved valg af mappe: {msg}",
|
||||
"log_pick_error_unknown": "Ukendt fejl ved valg af mappe.",
|
||||
"log_mode_selected": "Tilstand valgt: {mode}",
|
||||
"log_test_start": "Starter tests i tilstand: {mode}",
|
||||
"log_test_aborted": "Test blev annulleret af brugeren.",
|
||||
"log_test_error": "Fejl under testen: {msg}",
|
||||
"log_test_error_unknown": "Ukendt fejl under testen.",
|
||||
"log_loaded": "USB-browser-test (fakecheck) indlæst. Venter på mappevalg og tilstand.",
|
||||
|
||||
"mode_quick": "Quick-Check",
|
||||
"mode_benchmark": "Benchmark",
|
||||
"mode_writeverify": "Write & Verify",
|
||||
"mode_all": "All-Inclusive (alle browser-tests)",
|
||||
|
||||
"log_backend_save_error_status": "Backend: kunne ikke gemme resultat ({status}).",
|
||||
"log_backend_save_ok": "Backend: testresultat gemt{suffix}.",
|
||||
"log_backend_save_error": "Fejl ved lagring i backend: {msg}"
|
||||
},
|
||||
|
||||
"serial": {
|
||||
"rating_label": "Vurdering",
|
||||
|
||||
"rating": {
|
||||
"ok": {
|
||||
"label": "Plausibel",
|
||||
"desc": "Ingen tydelige afvigelser registreret."
|
||||
},
|
||||
"needs_review": {
|
||||
"label": "Bør kontrolleres",
|
||||
"desc": "Små afvigelser. Kombinér med en teknisk test for et klarere billede."
|
||||
},
|
||||
"suspicious": {
|
||||
"label": "Mistænkelig",
|
||||
"desc": "Kraftige afvigelser registreret. En kapacitets- eller skrive-/læs-test anbefales."
|
||||
},
|
||||
"invalid": {
|
||||
"label": "Ugyldig",
|
||||
"desc": "Serienummeret kunne ikke vurderes."
|
||||
},
|
||||
"unknown": {
|
||||
"label": "Uklart",
|
||||
"desc": "Det var ikke muligt at give en entydig vurdering."
|
||||
}
|
||||
},
|
||||
|
||||
"heading_input": "Indtastede data",
|
||||
"heading_analysis": "Analyse af serienummer",
|
||||
"heading_consistency": "Sammenhæng til producent",
|
||||
|
||||
"input": {
|
||||
"manufacturer": "Producent (angivet):",
|
||||
"vidpid": "VID/PID:",
|
||||
"vendor_detected": "Producent ud fra VID:"
|
||||
},
|
||||
|
||||
"analysis": {
|
||||
"serial": "Serienummer:",
|
||||
"length": "Længde:",
|
||||
"category": "Kategori:",
|
||||
"score": "Score:",
|
||||
"issues": "Afvigelser:"
|
||||
},
|
||||
|
||||
"chars": "tegn",
|
||||
"none": "ingen oplysning",
|
||||
|
||||
"issues_none": "Ingen særlige afvigelser.",
|
||||
|
||||
"vendor_detected": "{vendor} (VID {vid})",
|
||||
"vendor_unknown": "Ukendt producent for VID {vid}",
|
||||
"vendor_none": "Ingen vendor-ID angivet",
|
||||
|
||||
"disclaimer": "Denne vurdering er heuristisk og kan ikke garantere ægthed.",
|
||||
|
||||
"error": {
|
||||
"no_serial": "Angiv venligst et serienummer.",
|
||||
"api": "Fejl under kontrollen: {msg}",
|
||||
"unknown": "Uventet svar fra serveren."
|
||||
}
|
||||
},
|
||||
|
||||
"pages": {
|
||||
"landing": {
|
||||
"meta": {
|
||||
"title": "{{primary_domain}} – Tjek USB-drev for forfalskninger",
|
||||
"description": "USBCheck kombinerer en hurtig browser-test med en professionel Pro Mode, så du opdager falske USB-drev, for lille reel kapacitet og langsomme controllere, før dine filer forsvinder."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
{
|
||||
"header": {
|
||||
"header_slogan": "Test USB drives",
|
||||
"btn_login": "Login",
|
||||
|
||||
"nav_how": "How it works",
|
||||
"nav_problem": "Why it matters",
|
||||
"nav_features": "Features",
|
||||
"nav_security": "Security",
|
||||
"nav_faq": "FAQ"
|
||||
},
|
||||
|
||||
"brand": {
|
||||
"brand_wordmark": "{{primary_domain}}",
|
||||
"brand_subtitle": "Test USB drives for fakes"
|
||||
},
|
||||
|
||||
"hero": {
|
||||
"hero_kicker": "Detect fake USB sticks before you lose data",
|
||||
"hero_title": "Is my USB drive fake?<br><span class=\"text-brand-primary\">Find out in minutes.</span>",
|
||||
"hero_lead": "USBCheck combines a fast browser-based quick test with a professional Pro mode. Detect fake USB drives, real capacity losses and slow low-cost controllers – before your files disappear.",
|
||||
"cta_quick": "Start free quick check",
|
||||
"cta_learn": "Learn more about Free & Pro"
|
||||
},
|
||||
|
||||
"trust": {
|
||||
"trust1_title": "No install for quick check",
|
||||
"trust1_text": "Browser-based test directly on your drive.",
|
||||
"trust2_title": "Real write & read tests",
|
||||
"trust2_text": "Write/read tests with real data – no synthetic benchmarks.",
|
||||
"trust3_title": "Privacy first",
|
||||
"trust3_text": "Your test data stays local – reports only if you opt in."
|
||||
},
|
||||
|
||||
"quick": {
|
||||
"quick_label": "Quick check preview",
|
||||
"quick_title": "Test a USB drive in under 2 minutes",
|
||||
"badge_free": "Free",
|
||||
"quick_intro": "The quick check writes and reads a defined amount of data on your drive and measures:",
|
||||
"quick_li1": "Write and read speed",
|
||||
"quick_li2": "Data integrity (hash comparison)",
|
||||
"quick_li3": "Suspicious aborts or errors",
|
||||
"quick_metric1_label": "Write performance",
|
||||
"quick_metric1_value": "~ 75–120 MB/s*",
|
||||
"quick_metric2_label": "Integrity checks",
|
||||
"quick_metric2_value": "512 MB sample",
|
||||
"quick_footnote": "*Example values – your results depend on drive, port & system.",
|
||||
"quick_cta": "Go to free quick check",
|
||||
"quick_visual_title": "Quick test indicator",
|
||||
"quick_visual_text": "See how the quick check highlights fake patterns: the green bar marks stable data, orange alerts you when writes collapse.",
|
||||
"quick_visual_window": "Result window"
|
||||
},
|
||||
|
||||
"how": {
|
||||
"how_kicker": "How USBCheck works",
|
||||
"how_title": "Browser quick test, Pro mode for deep analysis.",
|
||||
"how_intro": "USBCheck was built to combine two worlds: a simple quick test for everyone and a deep Pro mode for power users, technicians and admins. The quick test runs directly in your browser, no install required. The Pro mode uses a small helper tool that can run F3 / badblocks-like checks and reliably detect capacity fakes.",
|
||||
"how_step1_title": "Start browser test",
|
||||
"how_step1_text": "Open the quick check at <strong>{{primary_url}}/fakecheck/</strong>, select your USB drive or a folder on it and define how much data should be tested.",
|
||||
"how_step2_title": "Write, read & integrity check",
|
||||
"how_step2_text": "The browser creates test files, measures write and read speed and compares hash values to detect data errors – all locally, without uploading your content.",
|
||||
"how_step3_title": "Optional: Pro mode full scan",
|
||||
"how_step3_text": "If you need more, install the optional helper tool. It can scan the full capacity, detect fakes and generate detailed reports – ideal for refurbishers, IT departments or labs.",
|
||||
"how_side_title": "Free vs. Pro at a glance",
|
||||
"how_side_free": "<strong>Free Quick Check:</strong> Speed & integrity test in your browser – perfect for quick checks.",
|
||||
"how_side_pro": "<strong>Pro mode:</strong> Full scan, capacity validation, advanced reports and API integration for businesses.",
|
||||
"how_side_account": "<strong>Account & login:</strong> Once logged in you can save tests, export reports and manage multiple devices."
|
||||
},
|
||||
|
||||
"problem": {
|
||||
"problem_kicker": "Why fake USB drives are dangerous",
|
||||
"problem_title": "Fake USB drives cost money – and in the worst case your data.",
|
||||
"problem_p1": "Many cheap USB drives advertise unrealistic capacities. In reality the controller is manipulated: the drive reports e.g. 256 GB while only 32 GB are physically available. The result: data appears to copy fine, but is silently overwritten or corrupted later.",
|
||||
"problem_p2": "USBCheck helps you detect such fakes before you use them in production – whether you just use a single stick privately or test larger batches for your business.",
|
||||
"problem_card1_title": "Loss of important files",
|
||||
"problem_card1_text": "Photos, project files, backups – all can be affected when a drive stores less than it claims. Bad sectors often remain unnoticed until it’s too late.",
|
||||
"problem_card2_title": "Costs from bad batches",
|
||||
"problem_card2_text": "Companies, resellers and agencies often distribute USB drives in bulk. Fakes mean returns, damage to your reputation and additional production costs.",
|
||||
"problem_card3_title": "Unreliable performance",
|
||||
"problem_card3_text": "Slow controllers, unstable firmware and fluctuating write speeds are typical for fake drives. That raises the risk of errors – especially with large files."
|
||||
},
|
||||
|
||||
"features": {
|
||||
"features_kicker": "Free & Pro features",
|
||||
"features_title": "Start with the free quick check – upgrade to Pro when you need more.",
|
||||
"features_intro": "USBCheck grows with your needs: private users often just need a quick assessment. Professionals want to dig deeper, verify capacities and archive reports. That’s exactly what the Pro mode is for.",
|
||||
|
||||
"features_free_title": "Free Quick Check",
|
||||
"features_free_badge": "Recommended for most users",
|
||||
"features_free_text": "Perfect if you want to quickly verify that a USB drive is reasonably fast and stable – with no installation.",
|
||||
"features_free_li1": "• Browser-based quick test directly on your drive",
|
||||
"features_free_li2": "• Write and read speed using real data",
|
||||
"features_free_li3": "• Hash-based integrity check of a data sample",
|
||||
"features_free_li4": "• Multiple test levels (e.g. 200 MB, 2 GB)",
|
||||
"features_free_li5": "• No registration required",
|
||||
"features_free_cta": "Start free quick check",
|
||||
|
||||
"features_pro_title": "Pro Mode",
|
||||
"features_pro_badge": "For power users & teams",
|
||||
"features_pro_text": "For everyone who needs full control: IT departments, technicians, refurbishers, labs or companies that regularly test large numbers of drives.",
|
||||
"features_pro_li1": "• Full-capacity deep scan (F3 / badblocks-like)",
|
||||
"features_pro_li2": "• Detection of capacity fakes and bad regions",
|
||||
"features_pro_li3": "• Detailed, storable reports (JSON, PDF)",
|
||||
"features_pro_li4": "• Optional API access for automated workflows",
|
||||
"features_pro_li5": "• Multi-device and multi-user support (via login area)",
|
||||
"features_pro_note": "The Pro mode requires a small helper tool on your system. It runs locally and can optionally be linked to your USBCheck account."
|
||||
},
|
||||
|
||||
"security": {
|
||||
"security_kicker": "Security & privacy",
|
||||
"security_title": "Privacy-first design: your test data is yours.",
|
||||
"security_intro": "USBCheck was designed from day one to protect your data. The browser quick test only works with test files. Your own documents, photos and backups are never read or uploaded. In Pro mode you decide if and which reports are synced to your account.",
|
||||
"security_card1_title": "Local-only tests",
|
||||
"security_card1_text": "All write and read tests run locally on your USB drive. The browser only accesses test files – not your private content.",
|
||||
"security_card2_title": "Transparent reports",
|
||||
"security_card2_text": "When logged in, you can store test reports in your account, export them or delete them again. You stay in control of what remains in the system.",
|
||||
"security_card3_title": "Gentle on your hardware",
|
||||
"security_card3_text": "The quick test uses moderate data sizes to avoid unnecessary wear. The Pro mode clearly warns you before running full-capacity stress tests."
|
||||
},
|
||||
|
||||
"faq": {
|
||||
"faq_kicker": "FAQ",
|
||||
"faq_title": "Frequently asked questions about USBCheck",
|
||||
"faq_intro": "Here you’ll find answers to common questions. You can expand the FAQ section at any time as new use cases and user feedback come in.",
|
||||
"faq_q1": "Is the quick test really fully browser-based?",
|
||||
"faq_a1": "Yes. The quick test runs entirely in your browser, using modern browser APIs to write and read test files on your drive. Nothing is uploaded without your consent.",
|
||||
"faq_q2": "Do I need an account to use the quick test?",
|
||||
"faq_a2": "No. The free quick test can be used without registration. A login is only required if you want to save reports, manage multiple drives or use Pro mode.",
|
||||
"faq_q3": "Can USBCheck reliably detect every fake drive?",
|
||||
"faq_a3": "No tool can provide a 100% guarantee. However, the Pro mode with full scan is designed to detect typical fraud patterns (manipulated reported capacity, unstable regions, errors beyond a certain fill level) very reliably.",
|
||||
"faq_q4": "How does the tool integrate into my existing setup?",
|
||||
"faq_a4": "USBCheck is built for automation. Through Pro mode and the planned API you can integrate tests into existing workflows, e.g. incoming goods checks or QA pipelines."
|
||||
},
|
||||
|
||||
"footer": {
|
||||
"footer_imprint": "Imprint",
|
||||
"footer_privacy": "Privacy policy",
|
||||
"footer_copy": "© {year} {{primary_domain}}. All rights reserved."
|
||||
},
|
||||
"fake": {
|
||||
"fake_hero_kicker": "FakeCheck – Browser mode",
|
||||
"fake_hero_title": "Is my USB stick fake?",
|
||||
"fake_hero_lead": "FakeCheck helps you detect typical fake USB drives: browser-based write/read tests and plausibility checks of the usable capacity – without installation.",
|
||||
"fake_cta_start": "Start browser test (demo)",
|
||||
"fake_cta_back_home": "Back to overview",
|
||||
"fake_hero_hint": "FakeCheck only creates test files in the selected folder. Your real files are never touched.",
|
||||
|
||||
"fake_box_title": "What the browser test can do",
|
||||
"fake_box_point1_title": "Write/read test with test files",
|
||||
"fake_box_point1_text": "The browser creates test files in the selected folder, measures write/read speeds and checks if the read data matches the written patterns.",
|
||||
"fake_box_point2_title": "Capacity plausibility check",
|
||||
"fake_box_point2_text": "From the amount of successfully written and verified data, you get a realistic impression of how much usable capacity actually exists.",
|
||||
"fake_box_point3_title": "JSON report for documentation",
|
||||
"fake_box_point3_text": "All results are collected in a structured JSON report that you can save, upload or reuse later.",
|
||||
|
||||
"fake_app_title": "Browser test interface (preview)",
|
||||
"fake_app_intro": "This will become the actual FakeCheck web app: choose a test folder, configure test size, view progress and results. The button above currently shows demo output only.",
|
||||
"fake_app_point1": "Quick test with small data size.",
|
||||
"fake_app_point2": "Light benchmark: write/read over a limited time.",
|
||||
"fake_app_point3": "Write/verify: write test files and verify them immediately.",
|
||||
|
||||
"fake_result_title": "Demo output of the browser test",
|
||||
"fake_result_hint": "This is only a preview. Later the actual JSON report will appear here."
|
||||
}
|
||||
|
||||
}
|
||||
173
public/assets/i18n/es.json
Normal file
173
public/assets/i18n/es.json
Normal file
@@ -0,0 +1,173 @@
|
||||
{
|
||||
"meta": {
|
||||
"code": "es",
|
||||
"label": "Español",
|
||||
"flag": "🇪🇸"
|
||||
},
|
||||
|
||||
"header": {
|
||||
"header_slogan": "Prueba memorias USB",
|
||||
"btn_login": "Iniciar sesión",
|
||||
|
||||
"nav_how": "Cómo funciona",
|
||||
"nav_problem": "Por qué importa",
|
||||
"nav_features": "Funciones",
|
||||
"nav_security": "Seguridad",
|
||||
"nav_faq": "FAQ"
|
||||
},
|
||||
|
||||
"brand": {
|
||||
"brand_wordmark": "{{primary_domain}}",
|
||||
"brand_subtitle": "Detecta memorias USB falsas"
|
||||
},
|
||||
|
||||
"footer": {
|
||||
"footer_imprint": "Aviso legal",
|
||||
"footer_privacy": "Privacidad",
|
||||
"footer_copy": "© {year} {{primary_domain}}. Todos los derechos reservados."
|
||||
},
|
||||
|
||||
"fake_ui": {
|
||||
"error_fsapi_not_supported": "Este navegador no admite la File System Access API.",
|
||||
"error_no_directory_selected": "No se ha seleccionado ninguna carpeta.",
|
||||
"error_no_space_detected": "No fue posible reservar espacio libre en la carpeta elegida.",
|
||||
|
||||
"log_capacity_probe_start": "Comprobando el espacio disponible en la carpeta seleccionada...",
|
||||
"log_capacity_probe_result": "Espacio utilizable detectado para las pruebas: {size} (escritura de prueba).",
|
||||
|
||||
"log_quick_prepare": "Quick-Check: preparando… (tamaño del test: {size})",
|
||||
"log_quick_verify_start": "Quick-Check: escritura completada. Verificando datos...",
|
||||
"log_quick_data_error": "Quick-Check: error de datos en el byte {byte}.",
|
||||
"error_quick_data_error": "Error de datos en el Quick-Check en el byte {byte}.",
|
||||
"log_quick_delete_warn": "Quick-Check: no se pudo borrar el archivo de prueba (no crítico).",
|
||||
"log_quick_success": "Quick-Check finalizado correctamente.",
|
||||
|
||||
"log_bench_start": "Benchmark: inicio – escribiendo archivo de prueba ({size})...",
|
||||
"log_bench_read_start": "Benchmark: lectura y cronometraje...",
|
||||
"log_bench_delete_warn": "Benchmark: no se pudo borrar el archivo de prueba (no crítico).",
|
||||
"log_bench_success": "Benchmark completado con éxito.",
|
||||
|
||||
"log_wv_start": "Write/Verify: inicio – {blocks} bloques de {size} (total {total})...",
|
||||
"log_wv_block_start": "Write/Verify: bloque {num}/{blocks} – {file}",
|
||||
"log_wv_data_error": "Write/Verify: error de datos en el bloque {num} en el byte {byte}.",
|
||||
"error_wv_data_error": "Error de datos en el bloque {num} en el byte {byte}.",
|
||||
"log_wv_delete_warn": "Write/Verify: no se pudo borrar el archivo {file} (no crítico).",
|
||||
"log_wv_success": "Write/Verify: todos los bloques verificados correctamente.",
|
||||
|
||||
"log_all_subtest_start": "All-Inclusive: iniciando subtest \"{mode}\" ({num}/{total})...",
|
||||
"error_unknown_mode": "Modo desconocido: {mode}",
|
||||
|
||||
"log_fsapi_partial": "Tu navegador no admite completamente la File System Access API. Algunas funciones se desactivarán.",
|
||||
|
||||
"selected_path_label": "Carpeta USB seleccionada (nombre: \"{name}\").",
|
||||
"selected_path_none": "Aún no se ha elegido carpeta.",
|
||||
|
||||
"status_ready": "Listo. Primero selecciona tu memoria USB.",
|
||||
"status_mode_none": "Ningún modo seleccionado",
|
||||
"status_dir_selected": "Carpeta USB seleccionada. Elige ahora un modo.",
|
||||
"status_mode_selected": "Modo \"{mode}\" seleccionado. Ya puedes iniciar la prueba.",
|
||||
"status_running": "Prueba en curso… no desconectes la memoria.",
|
||||
"status_done": "Prueba finalizada.",
|
||||
"status_aborted": "Prueba cancelada.",
|
||||
"status_error": "Error: {msg}",
|
||||
"status_error_unknown": "Error desconocido durante la prueba.",
|
||||
|
||||
"overall_initial": "Aún no se ha realizado ninguna prueba.",
|
||||
"overall_running": "Prueba en curso…",
|
||||
"overall_done": "Prueba del navegador completada con éxito.",
|
||||
"overall_aborted": "Prueba cancelada.",
|
||||
"overall_error": "Error en la prueba del navegador.",
|
||||
|
||||
"log_dir_selected": "Carpeta seleccionada: {name}",
|
||||
"log_dir_reset": "Selección de carpeta reiniciada.",
|
||||
"log_pick_abort": "Selección de carpeta cancelada.",
|
||||
"log_pick_error": "Error al seleccionar carpeta: {msg}",
|
||||
"log_pick_error_unknown": "Error desconocido al seleccionar carpeta.",
|
||||
"log_mode_selected": "Modo elegido: {mode}",
|
||||
"log_test_start": "Iniciando pruebas en modo: {mode}",
|
||||
"log_test_aborted": "Prueba cancelada por el usuario.",
|
||||
"log_test_error": "Error durante la prueba: {msg}",
|
||||
"log_test_error_unknown": "Error desconocido durante la prueba.",
|
||||
"log_loaded": "Test del navegador USB (fakecheck) cargado. Esperando carpeta y modo.",
|
||||
|
||||
"mode_quick": "Quick-Check",
|
||||
"mode_benchmark": "Benchmark",
|
||||
"mode_writeverify": "Write & Verify",
|
||||
"mode_all": "All-Inclusive (todas las pruebas)",
|
||||
|
||||
"log_backend_save_error_status": "Backend: no se pudo guardar el resultado ({status}).",
|
||||
"log_backend_save_ok": "Backend: resultado guardado{suffix}.",
|
||||
"log_backend_save_error": "Error al guardar en el backend: {msg}"
|
||||
},
|
||||
|
||||
"serial": {
|
||||
"rating_label": "Valoración",
|
||||
|
||||
"rating": {
|
||||
"ok": {
|
||||
"label": "Plausible",
|
||||
"desc": "No se detectaron anomalías importantes."
|
||||
},
|
||||
"needs_review": {
|
||||
"label": "Revisión recomendada",
|
||||
"desc": "Pequeñas irregularidades. Combina con una prueba técnica para mayor claridad."
|
||||
},
|
||||
"suspicious": {
|
||||
"label": "Sospechoso",
|
||||
"desc": "Se detectaron anomalías importantes. Se recomienda un test de capacidad o de escritura/lectura."
|
||||
},
|
||||
"invalid": {
|
||||
"label": "Inválido",
|
||||
"desc": "No fue posible evaluar este número de serie."
|
||||
},
|
||||
"unknown": {
|
||||
"label": "No claro",
|
||||
"desc": "No se pudo determinar una valoración clara."
|
||||
}
|
||||
},
|
||||
|
||||
"heading_input": "Datos introducidos",
|
||||
"heading_analysis": "Análisis del número de serie",
|
||||
"heading_consistency": "Coherencia del fabricante",
|
||||
|
||||
"input": {
|
||||
"manufacturer": "Fabricante (dato del usuario):",
|
||||
"vidpid": "VID/PID:",
|
||||
"vendor_detected": "Fabricante detectado por la VID:"
|
||||
},
|
||||
|
||||
"analysis": {
|
||||
"serial": "Número de serie:",
|
||||
"length": "Longitud:",
|
||||
"category": "Categoría:",
|
||||
"score": "Puntuación:",
|
||||
"issues": "Observaciones:"
|
||||
},
|
||||
|
||||
"chars": "caracteres",
|
||||
"none": "sin dato",
|
||||
|
||||
"issues_none": "Sin observaciones destacables.",
|
||||
|
||||
"vendor_detected": "{vendor} (VID {vid})",
|
||||
"vendor_unknown": "Fabricante desconocido para la VID {vid}",
|
||||
"vendor_none": "No se indicó VID",
|
||||
|
||||
"disclaimer": "Esta valoración es heurística y no garantiza la autenticidad.",
|
||||
|
||||
"error": {
|
||||
"no_serial": "Introduce un número de serie.",
|
||||
"api": "Error durante la verificación: {msg}",
|
||||
"unknown": "Respuesta inesperada del servidor."
|
||||
}
|
||||
},
|
||||
|
||||
"pages": {
|
||||
"landing": {
|
||||
"meta": {
|
||||
"title": "{{primary_domain}} – Prueba tus USB contra falsificaciones",
|
||||
"description": "USBCheck combina un test rápido en el navegador con un modo Pro profesional para detectar memorias falsas antes de perder tus datos."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,12 @@
|
||||
{
|
||||
"meta": {
|
||||
"code": "fr",
|
||||
"label": "Français",
|
||||
"flag": "🇫🇷"
|
||||
},
|
||||
|
||||
"header": {
|
||||
"header_slogan": "Tester vos clés USB",
|
||||
"header_slogan": "Tester des clés USB",
|
||||
"btn_login": "Connexion",
|
||||
|
||||
"nav_how": "Fonctionnement",
|
||||
@@ -12,124 +18,7 @@
|
||||
|
||||
"brand": {
|
||||
"brand_wordmark": "{{primary_domain}}",
|
||||
"brand_subtitle": "Tester les clés USB contrefaites"
|
||||
},
|
||||
|
||||
"hero": {
|
||||
"hero_kicker": "Détectez les clés USB contrefaites avant de perdre vos données",
|
||||
"hero_title": "Ma clé USB est-elle une contrefaçon ?<br><span class=\"text-brand-primary\">Obtenez la réponse en quelques minutes.</span>",
|
||||
"hero_lead": "USBCheck combine un test rapide dans le navigateur et un mode Pro professionnel. Vous détectez ainsi les clés USB contrefaites, la capacité réelle trop faible et les contrôleurs lents avant de perdre vos fichiers.",
|
||||
"cta_quick": "Lancer le test rapide gratuit",
|
||||
"cta_learn": "En savoir plus sur Free & Pro"
|
||||
},
|
||||
|
||||
"trust": {
|
||||
"trust1_title": "Aucune installation pour le test rapide",
|
||||
"trust1_text": "Test basé sur le navigateur directement sur votre clé.",
|
||||
"trust2_title": "Tests réels d’écriture et de lecture",
|
||||
"trust2_text": "Tests avec de vraies données, pas uniquement des benchmarks synthétiques.",
|
||||
"trust3_title": "La confidentialité d’abord",
|
||||
"trust3_text": "Vos données de test restent locales – les rapports ne sont envoyés qu’avec votre accord."
|
||||
},
|
||||
|
||||
"quick": {
|
||||
"quick_label": "Aperçu du test rapide",
|
||||
"quick_title": "Tester une clé USB en moins de 2 minutes",
|
||||
"badge_free": "Gratuit",
|
||||
"quick_intro": "Le test rapide écrit et lit une certaine quantité de données sur la clé et mesure :",
|
||||
"quick_li1": "La vitesse d’écriture et de lecture",
|
||||
"quick_li2": "L’intégrité des données (comparaison de hash)",
|
||||
"quick_li3": "Les erreurs ou interruptions suspectes",
|
||||
"quick_metric1_label": "Performances en écriture",
|
||||
"quick_metric1_value": "~ 75–120 Mo/s*",
|
||||
"quick_metric2_label": "Contrôles d’intégrité",
|
||||
"quick_metric2_value": "Échantillon de 512 Mo",
|
||||
"quick_footnote": "*Valeurs indicatives – les résultats dépendent de la clé, du port et du système.",
|
||||
"quick_cta": "Accéder au test rapide gratuit",
|
||||
"quick_visual_title": "Indicateur du test rapide",
|
||||
"quick_visual_text": "Voici l’aspect visuel du contrôle rapide : le vert signale des données stables, l’orange avertit lorsque l’écriture s’effondre.",
|
||||
"quick_visual_window": "Fenêtre de résultat"
|
||||
},
|
||||
|
||||
"how": {
|
||||
"how_kicker": "Fonctionnement d’USBCheck",
|
||||
"how_title": "Test rapide dans le navigateur, mode Pro pour une analyse approfondie.",
|
||||
"how_intro": "USBCheck a été conçu pour réunir deux mondes : un test rapide simple pour tous et un mode Pro avancé pour les utilisateurs experts, techniciens et administrateurs. Le test rapide s’exécute dans le navigateur sans installation. Le mode Pro utilise un petit outil pouvant effectuer des tests similaires à F3/badblocks pour détecter les capacités truquées.",
|
||||
"how_step1_title": "Démarrer le test dans le navigateur",
|
||||
"how_step1_text": "Ouvrez le test rapide sur <strong>{{primary_url}}/fakecheck/</strong>, sélectionnez votre clé ou un dossier puis définissez la quantité de données à tester.",
|
||||
"how_step2_title": "Écriture, lecture et contrôle d’intégrité",
|
||||
"how_step2_text": "Le navigateur crée des fichiers de test, mesure les vitesses d’écriture/lecture et compare les hash pour détecter les erreurs – le tout localement, sans envoyer vos contenus.",
|
||||
"how_step3_title": "Optionnel : mode Pro avec analyse complète",
|
||||
"how_step3_text": "Si vous avez besoin de plus, installez l’outil optionnel. Il peut tester toute la capacité, détecter les contrefaçons et générer des rapports détaillés – idéal pour les refurbishers, services IT ou laboratoires.",
|
||||
"how_side_title": "Free et Pro en un coup d’œil",
|
||||
"how_side_free": "<strong>Free Quick Check :</strong> Test de vitesse et d’intégrité dans le navigateur – idéal pour un contrôle rapide.",
|
||||
"how_side_pro": "<strong>Mode Pro :</strong> Analyse complète, vérification de capacité, rapports avancés et API pour les entreprises.",
|
||||
"how_side_account": "<strong>Compte & connexion :</strong> Une fois connecté, vous pouvez sauvegarder les tests, exporter les rapports et gérer plusieurs appareils."
|
||||
},
|
||||
|
||||
"problem": {
|
||||
"problem_kicker": "Pourquoi les clés USB contrefaites sont dangereuses",
|
||||
"problem_title": "Les clés USB contrefaites coûtent de l’argent – et parfois vos données.",
|
||||
"problem_p1": "De nombreuses clés USB bon marché annoncent des capacités irréalistes. En réalité, le contrôleur est manipulé : la clé annonce par exemple 256 Go alors que seuls 32 Go sont présents physiquement. Résultat : les données semblent copiées, mais sont ensuite écrasées ou corrompues.",
|
||||
"problem_p2": "USBCheck vous aide à détecter ces contrefaçons avant de les utiliser en production – que ce soit pour une seule clé ou pour des lots entiers dans votre entreprise.",
|
||||
"problem_card1_title": "Perte de fichiers importants",
|
||||
"problem_card1_text": "Photos, projets, sauvegardes – tout peut être perdu si la clé stocke moins que ce qu’elle annonce. Les secteurs défectueux sont souvent découverts trop tard.",
|
||||
"problem_card2_title": "Coûts liés aux lots défectueux",
|
||||
"problem_card2_text": "Les entreprises et revendeurs distribuent souvent des clés USB en grandes quantités. Les contrefaçons entraînent des retours, des plaintes et un coût d’image.",
|
||||
"problem_card3_title": "Performances peu fiables",
|
||||
"problem_card3_text": "Contrôleurs lents, firmware instable et vitesses fluctuantes sont typiques des clés contrefaites. Le risque d’erreurs augmente, surtout avec de gros fichiers."
|
||||
},
|
||||
|
||||
"features": {
|
||||
"features_kicker": "Fonctionnalités Free & Pro",
|
||||
"features_title": "Commencez avec le test rapide gratuit – passez en mode Pro si nécessaire.",
|
||||
"features_intro": "USBCheck évolue avec vos besoins : les particuliers ont souvent besoin d’un simple contrôle rapide. Les professionnels souhaitent analyser en profondeur, vérifier les capacités et archiver les rapports.",
|
||||
|
||||
"features_free_title": "Free Quick Check",
|
||||
"features_free_badge": "Recommandé pour la plupart des utilisateurs",
|
||||
"features_free_text": "Idéal pour vérifier rapidement si une clé est suffisamment rapide et stable – sans installation.",
|
||||
"features_free_li1": "• Test rapide dans le navigateur directement sur la clé",
|
||||
"features_free_li2": "• Vitesse d’écriture et de lecture avec des données réelles",
|
||||
"features_free_li3": "• Contrôle d’intégrité basé sur les hash",
|
||||
"features_free_li4": "• Différents niveaux de test (ex. 200 Mo, 2 Go)",
|
||||
"features_free_li5": "• Aucune inscription requise",
|
||||
"features_free_cta": "Lancer le test rapide gratuit",
|
||||
|
||||
"features_pro_title": "Mode Pro",
|
||||
"features_pro_badge": "Pour power users et équipes",
|
||||
"features_pro_text": "Pour tous ceux qui ont besoin d’un contrôle complet : services IT, techniciens, refurbishers, laboratoires ou entreprises testant régulièrement de nombreuses clés.",
|
||||
"features_pro_li1": "• Analyse complète de la capacité (similaire à F3/badblocks)",
|
||||
"features_pro_li2": "• Détection des capacités truquées et des zones défectueuses",
|
||||
"features_pro_li3": "• Rapports détaillés enregistrables (JSON, PDF)",
|
||||
"features_pro_li4": "• Accès API optionnel pour des flux automatisés",
|
||||
"features_pro_li5": "• Support multi-appareils et multi-utilisateurs (via compte)",
|
||||
"features_pro_note": "Le mode Pro nécessite un petit outil sur votre système. Il fonctionne en local et peut être relié à votre compte USBCheck."
|
||||
},
|
||||
|
||||
"security": {
|
||||
"security_kicker": "Sécurité & confidentialité",
|
||||
"security_title": "Conception privacy-first : vos données de test vous appartiennent.",
|
||||
"security_intro": "USBCheck a été conçu dès le départ pour protéger vos données. Le test rapide dans le navigateur utilise uniquement des fichiers de test. Vos documents, photos et sauvegardes ne sont ni lus ni envoyés. En mode Pro, vous décidez si et quels rapports sont synchronisés.",
|
||||
"security_card1_title": "Tests uniquement locaux",
|
||||
"security_card1_text": "Tous les tests de lecture/écriture se font en local sur la clé. Le navigateur n’accède qu’aux fichiers de test, pas à vos contenus privés.",
|
||||
"security_card2_title": "Rapports transparents",
|
||||
"security_card2_text": "Avec un compte, vous pouvez sauvegarder les rapports, les exporter ou les supprimer. Vous gardez le contrôle sur ce qui reste dans le système.",
|
||||
"security_card3_title": "Respectueux du matériel",
|
||||
"security_card3_text": "Le test rapide utilise des volumes de données modérés pour limiter l’usure. Le mode Pro vous avertit clairement avant les tests intensifs."
|
||||
},
|
||||
|
||||
"faq": {
|
||||
"faq_kicker": "FAQ",
|
||||
"faq_title": "Questions fréquentes sur USBCheck",
|
||||
"faq_intro": "Vous trouverez ici les réponses aux questions les plus fréquentes. La section FAQ peut être enrichie à tout moment en fonction des nouveaux cas d’usage et des retours utilisateurs.",
|
||||
"faq_q1": "Le test rapide est-il vraiment uniquement dans le navigateur ?",
|
||||
"faq_a1": "Oui. Le test rapide s’exécute entièrement dans le navigateur et utilise des API modernes pour écrire et lire des fichiers de test. Rien n’est envoyé sans votre accord.",
|
||||
"faq_q2": "Ai-je besoin d’un compte pour utiliser le test rapide ?",
|
||||
"faq_a2": "Non. Le test rapide gratuit est accessible sans inscription. La connexion n’est requise que si vous souhaitez sauvegarder des rapports, gérer plusieurs clés ou utiliser le mode Pro.",
|
||||
"faq_q3": "USBCheck peut-il détecter toutes les clés contrefaites ?",
|
||||
"faq_a3": "Aucun outil ne peut garantir 100 %. Cependant, le mode Pro avec analyse complète est conçu pour détecter de manière fiable les schémas de fraude typiques.",
|
||||
"faq_q4": "Comment intégrer l’outil dans mon système existant ?",
|
||||
"faq_a4": "USBCheck est pensé pour l’automatisation. Grâce au mode Pro et à l’API prévue, vous pouvez intégrer les tests dans vos flux existants, par exemple dans le contrôle qualité ou la réception de marchandises."
|
||||
"brand_subtitle": "Tester les clés USB contre les contrefaçons"
|
||||
},
|
||||
|
||||
"footer": {
|
||||
@@ -137,30 +26,148 @@
|
||||
"footer_privacy": "Confidentialité",
|
||||
"footer_copy": "© {year} {{primary_domain}}. Tous droits réservés."
|
||||
},
|
||||
"fake": {
|
||||
"fake_hero_kicker": "FakeCheck – Mode navigateur",
|
||||
"fake_hero_title": "Ma clé USB est-elle une contrefaçon ?",
|
||||
"fake_hero_lead": "FakeCheck vous aide à détecter les clés USB contrefaites : tests d’écriture/lecture dans le navigateur et contrôles de capacité – sans installation.",
|
||||
"fake_cta_start": "Lancer le test navigateur (démo)",
|
||||
"fake_cta_back_home": "Retour à l’accueil",
|
||||
"fake_hero_hint": "FakeCheck crée uniquement des fichiers de test dans le dossier sélectionné. Vos fichiers personnels restent intacts.",
|
||||
|
||||
"fake_box_title": "Ce que le test navigateur peut faire",
|
||||
"fake_box_point1_title": "Test écriture/lecture avec fichiers de test",
|
||||
"fake_box_point1_text": "Le navigateur crée des fichiers de test, mesure les vitesses et vérifie que les données lues correspondent aux données écrites.",
|
||||
"fake_box_point2_title": "Vérification de la capacité réelle",
|
||||
"fake_box_point2_text": "La quantité de données écrites et vérifiées permet d’estimer la capacité réellement utilisable.",
|
||||
"fake_box_point3_title": "Rapport JSON pour documentation",
|
||||
"fake_box_point3_text": "Tous les résultats sont regroupés dans un rapport JSON structuré que vous pouvez enregistrer, envoyer ou réutiliser ensuite.",
|
||||
"fake_ui": {
|
||||
"error_fsapi_not_supported": "Ce navigateur ne prend pas en charge l’API File System Access.",
|
||||
"error_no_directory_selected": "Aucun dossier sélectionné.",
|
||||
"error_no_space_detected": "Impossible de réserver de l’espace libre dans le dossier choisi.",
|
||||
|
||||
"fake_app_title": "Interface test navigateur (aperçu)",
|
||||
"fake_app_intro": "Voici la future interface FakeCheck : dossier, quantité de test, progression et résultats. Le bouton ci-dessus montre une démonstration.",
|
||||
"fake_app_point1": "Quick-test avec une petite quantité de données.",
|
||||
"fake_app_point2": "Light benchmark : test écriture/lecture sur un temps limité.",
|
||||
"fake_app_point3": "Write/verify : écrit et vérifie immédiatement les fichiers de test.",
|
||||
|
||||
"fake_result_title": "Sortie démo du test navigateur",
|
||||
"fake_result_hint": "Ceci n’est qu’un aperçu. Le vrai rapport JSON apparaîtra ici."
|
||||
}
|
||||
"log_capacity_probe_start": "Mesure de l’espace disponible dans le dossier choisi...",
|
||||
"log_capacity_probe_result": "Espace utilisable détecté pour les tests : {size} (écriture de test).",
|
||||
|
||||
"log_quick_prepare": "Quick Check : préparation... (taille du test : {size})",
|
||||
"log_quick_verify_start": "Quick Check : écriture terminée. Vérification des données...",
|
||||
"log_quick_data_error": "Quick Check : erreur de données à l’octet {byte}.",
|
||||
"error_quick_data_error": "Erreur de données dans le Quick Check à l’octet {byte}.",
|
||||
"log_quick_delete_warn": "Quick Check : impossible de supprimer le fichier de test (non critique).",
|
||||
"log_quick_success": "Quick Check terminé avec succès.",
|
||||
|
||||
"log_bench_start": "Benchmark : démarrage – écriture du fichier ({size})...",
|
||||
"log_bench_read_start": "Benchmark : lecture et timing...",
|
||||
"log_bench_delete_warn": "Benchmark : impossible de supprimer le fichier de test (non critique).",
|
||||
"log_bench_success": "Benchmark terminé avec succès.",
|
||||
|
||||
"log_wv_start": "Write/Verify : démarrage – {blocks} blocs de {size} (total {total})...",
|
||||
"log_wv_block_start": "Write/Verify : bloc {num}/{blocks} – {file}",
|
||||
"log_wv_data_error": "Write/Verify : erreur de données dans le bloc {num} à l’octet {byte}.",
|
||||
"error_wv_data_error": "Erreur de données dans le bloc {num} à l’octet {byte}.",
|
||||
"log_wv_delete_warn": "Write/Verify : impossible de supprimer le fichier {file} (non critique).",
|
||||
"log_wv_success": "Write/Verify : tous les blocs vérifiés avec succès.",
|
||||
|
||||
"log_all_subtest_start": "All-Inclusive : lancement du sous-test « {mode} » ({num}/{total})...",
|
||||
"error_unknown_mode": "Mode inconnu : {mode}",
|
||||
|
||||
"log_fsapi_partial": "Votre navigateur ne prend pas totalement en charge l’API File System Access. Certaines fonctions seront désactivées.",
|
||||
|
||||
"selected_path_label": "Dossier USB sélectionné (nom : « {name} »).",
|
||||
"selected_path_none": "Aucun dossier sélectionné pour l’instant.",
|
||||
|
||||
"status_ready": "Prêt. Sélectionnez d’abord votre clé USB.",
|
||||
"status_mode_none": "Aucun mode sélectionné",
|
||||
"status_dir_selected": "Dossier USB sélectionné. Choisissez un mode de test.",
|
||||
"status_mode_selected": "Mode « {mode} » sélectionné. Vous pouvez lancer la preuve.",
|
||||
"status_running": "Test en cours... laissez la clé connectée.",
|
||||
"status_done": "Test terminé.",
|
||||
"status_aborted": "Test interrompu.",
|
||||
"status_error": "Erreur : {msg}",
|
||||
"status_error_unknown": "Erreur inconnue durant le test.",
|
||||
|
||||
"overall_initial": "Aucun test n’a encore été effectué.",
|
||||
"overall_running": "Test en cours...",
|
||||
"overall_done": "Test navigateur terminé avec succès.",
|
||||
"overall_aborted": "Test interrompu.",
|
||||
"overall_error": "Échec du test navigateur.",
|
||||
|
||||
"log_dir_selected": "Dossier sélectionné : {name}",
|
||||
"log_dir_reset": "Sélection du dossier réinitialisée.",
|
||||
"log_pick_abort": "Sélection du dossier annulée.",
|
||||
"log_pick_error": "Erreur de sélection du dossier : {msg}",
|
||||
"log_pick_error_unknown": "Erreur inconnue lors de la sélection du dossier.",
|
||||
"log_mode_selected": "Mode choisi : {mode}",
|
||||
"log_test_start": "Démarrage des tests en mode : {mode}",
|
||||
"log_test_aborted": "Test annulé par l’utilisateur.",
|
||||
"log_test_error": "Erreur pendant le test : {msg}",
|
||||
"log_test_error_unknown": "Erreur inconnue pendant le test.",
|
||||
"log_loaded": "Test navigateur USB (fakecheck) chargé. En attente du dossier et du mode.",
|
||||
|
||||
"mode_quick": "Quick-Check",
|
||||
"mode_benchmark": "Benchmark",
|
||||
"mode_writeverify": "Write & Verify",
|
||||
"mode_all": "All-Inclusive (tous les tests)",
|
||||
|
||||
"log_backend_save_error_status": "Backend : impossible d’enregistrer le résultat ({status}).",
|
||||
"log_backend_save_ok": "Backend : résultat enregistré{suffix}.",
|
||||
"log_backend_save_error": "Erreur lors de l’enregistrement côté serveur : {msg}"
|
||||
},
|
||||
|
||||
"serial": {
|
||||
"rating_label": "Évaluation",
|
||||
|
||||
"rating": {
|
||||
"ok": {
|
||||
"label": "Plausible",
|
||||
"desc": "Aucune anomalie majeure détectée."
|
||||
},
|
||||
"needs_review": {
|
||||
"label": "À vérifier",
|
||||
"desc": "Légères irrégularités. Combinez avec un test technique pour être sûr."
|
||||
},
|
||||
"suspicious": {
|
||||
"label": "Suspect",
|
||||
"desc": "Anomalies importantes détectées. Un test de capacité ou d’écriture/lecture est fortement recommandé."
|
||||
},
|
||||
"invalid": {
|
||||
"label": "Invalide",
|
||||
"desc": "Le numéro de série n’a pas pu être évalué."
|
||||
},
|
||||
"unknown": {
|
||||
"label": "Indéterminé",
|
||||
"desc": "Impossible d’obtenir un verdict clair."
|
||||
}
|
||||
},
|
||||
|
||||
"heading_input": "Données saisies",
|
||||
"heading_analysis": "Analyse du numéro de série",
|
||||
"heading_consistency": "Cohérence fabricant",
|
||||
|
||||
"input": {
|
||||
"manufacturer": "Fabricant (déclaré) :",
|
||||
"vidpid": "VID/PID :",
|
||||
"vendor_detected": "Fabricant détecté via la VID :"
|
||||
},
|
||||
|
||||
"analysis": {
|
||||
"serial": "Numéro de série :",
|
||||
"length": "Longueur :",
|
||||
"category": "Catégorie :",
|
||||
"score": "Score :",
|
||||
"issues": "Observations :"
|
||||
},
|
||||
|
||||
"chars": "caractères",
|
||||
"none": "non renseigné",
|
||||
|
||||
"issues_none": "Aucune observation particulière.",
|
||||
|
||||
"vendor_detected": "{vendor} (VID {vid})",
|
||||
"vendor_unknown": "Fabricant inconnu pour la VID {vid}",
|
||||
"vendor_none": "Aucune VID fournie",
|
||||
|
||||
"disclaimer": "Cette évaluation est heuristique et ne garantit pas l’authenticité.",
|
||||
|
||||
"error": {
|
||||
"no_serial": "Veuillez saisir un numéro de série.",
|
||||
"api": "Erreur lors de la vérification : {msg}",
|
||||
"unknown": "Réponse inattendue du serveur."
|
||||
}
|
||||
},
|
||||
|
||||
"pages": {
|
||||
"landing": {
|
||||
"meta": {
|
||||
"title": "{{primary_domain}} – Tester vos clés USB contre les faux",
|
||||
"description": "USBCheck combine un test rapide dans le navigateur et un mode Pro professionnel pour détecter les clés contrefaites avant la perte de données."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
{
|
||||
"meta": {
|
||||
"code": "it",
|
||||
"label": "Italiano",
|
||||
"flag": "🇮🇹"
|
||||
},
|
||||
|
||||
"header": {
|
||||
"header_slogan": "Test delle chiavette USB",
|
||||
"btn_login": "Accesso",
|
||||
"header_slogan": "Testare chiavette USB",
|
||||
"btn_login": "Login",
|
||||
|
||||
"nav_how": "Come funziona",
|
||||
"nav_problem": "Perché è importante",
|
||||
@@ -12,124 +18,7 @@
|
||||
|
||||
"brand": {
|
||||
"brand_wordmark": "{{primary_domain}}",
|
||||
"brand_subtitle": "Controlla le chiavette USB contraffatte"
|
||||
},
|
||||
|
||||
"hero": {
|
||||
"hero_kicker": "Individua le chiavette USB false prima di perdere i dati",
|
||||
"hero_title": "La mia chiavetta USB è falsa?<br><span class=\"text-brand-primary\">Scoprilo in pochi minuti.</span>",
|
||||
"hero_lead": "USBCheck combina un rapido test nel browser con una modalità Pro professionale. Così puoi individuare chiavette USB contraffatte, capacità reali inferiori e controller lenti prima che i tuoi file vadano persi.",
|
||||
"cta_quick": "Avvia il test rapido gratuito",
|
||||
"cta_learn": "Scopri di più su Free & Pro"
|
||||
},
|
||||
|
||||
"trust": {
|
||||
"trust1_title": "Nessuna installazione per il test rapido",
|
||||
"trust1_text": "Test basato su browser direttamente sulla chiavetta.",
|
||||
"trust2_title": "Test reali di scrittura e lettura",
|
||||
"trust2_text": "Test con dati reali, non solo benchmark sintetici.",
|
||||
"trust3_title": "Privacy al primo posto",
|
||||
"trust3_text": "I tuoi dati di test restano in locale – i report solo su richiesta."
|
||||
},
|
||||
|
||||
"quick": {
|
||||
"quick_label": "Anteprima test rapido",
|
||||
"quick_title": "Testa una chiavetta USB in meno di 2 minuti",
|
||||
"badge_free": "Gratuito",
|
||||
"quick_intro": "Il test rapido scrive e legge una certa quantità di dati sulla chiavetta e misura:",
|
||||
"quick_li1": "Velocità di scrittura e lettura",
|
||||
"quick_li2": "Integrità dei dati (confronto hash)",
|
||||
"quick_li3": "Errori o interruzioni sospette",
|
||||
"quick_metric1_label": "Prestazioni in scrittura",
|
||||
"quick_metric1_value": "~ 75–120 MB/s*",
|
||||
"quick_metric2_label": "Controlli di integrità",
|
||||
"quick_metric2_value": "Campione da 512 MB",
|
||||
"quick_footnote": "*Valori di esempio – i risultati dipendono da chiavetta, porta e sistema.",
|
||||
"quick_cta": "Vai al test rapido gratuito",
|
||||
"quick_visual_title": "Indicatore quick test",
|
||||
"quick_visual_text": "Ecco l’aspetto visivo del controllo rapido: il verde mostra dati stabili, l’arancione avvisa quando la scrittura crolla.",
|
||||
"quick_visual_window": "Finestra risultato"
|
||||
},
|
||||
|
||||
"how": {
|
||||
"how_kicker": "Come funziona USBCheck",
|
||||
"how_title": "Test rapido nel browser, modalità Pro per analisi profonde.",
|
||||
"how_intro": "USBCheck è pensato per unire due mondi: un test rapido semplice per tutti e una modalità Pro avanzata per utenti esperti, tecnici e amministratori. Il test rapido gira nel browser senza installazione. La modalità Pro usa un piccolo tool che può eseguire test simili a F3/badblocks e individuare capacità contraffatte.",
|
||||
"how_step1_title": "Avvia il test nel browser",
|
||||
"how_step1_text": "Apri il test rapido su <strong>{{primary_url}}/fakecheck/</strong>, seleziona la chiavetta o una cartella e definisci quanta quantità di dati deve essere testata.",
|
||||
"how_step2_title": "Scrittura, lettura e controllo integrità",
|
||||
"how_step2_text": "Il browser crea file di test, misura la velocità di scrittura/lettura e confronta gli hash per individuare errori – tutto in locale, senza caricare i tuoi contenuti.",
|
||||
"how_step3_title": "Opzionale: modalità Pro con scansione completa",
|
||||
"how_step3_text": "Se hai bisogno di più dati, installa il tool opzionale. Può testare l’intera capacità, individuare chiavette false e generare report dettagliati – ideale per refurbisher, reparti IT o laboratori.",
|
||||
"how_side_title": "Free e Pro a colpo d’occhio",
|
||||
"how_side_free": "<strong>Free Quick Check:</strong> Test di velocità e integrità nel browser – ideale per controlli veloci.",
|
||||
"how_side_pro": "<strong>Modalità Pro:</strong> Scansione completa, verifica capacità, report avanzati e API per aziende.",
|
||||
"how_side_account": "<strong>Account & login:</strong> Dopo il login puoi salvare i test, esportare i report e gestire più dispositivi."
|
||||
},
|
||||
|
||||
"problem": {
|
||||
"problem_kicker": "Perché le USB false sono pericolose",
|
||||
"problem_title": "Le chiavette USB contraffatte costano denaro e, nel peggiore dei casi, i tuoi dati.",
|
||||
"problem_p1": "Molte chiavette USB economiche dichiarano capacità irrealistiche. In realtà il controller è manipolato: la chiavetta dichiara ad esempio 256 GB, ma fisicamente ce ne sono solo 32 GB. Risultato: i dati sembrano copiarsi correttamente, ma vengono sovrascritti o danneggiati.",
|
||||
"problem_p2": "USBCheck ti aiuta a rilevare queste falsificazioni prima che tu le usi in produzione – che si tratti di una chiavetta privata o di grandi lotti per la tua azienda.",
|
||||
"problem_card1_title": "Perdita di file importanti",
|
||||
"problem_card1_text": "Foto, progetti, backup – tutto può andare perso se la chiavetta memorizza meno di quanto dichiara. I settori difettosi vengono spesso scoperti troppo tardi.",
|
||||
"problem_card2_title": "Costi dovuti a lotti difettosi",
|
||||
"problem_card2_text": "Aziende e rivenditori distribuiscono spesso chiavette USB in grandi quantità. Le falsificazioni portano a resi, danni di immagine e costi aggiuntivi.",
|
||||
"problem_card3_title": "Prestazioni inaffidabili",
|
||||
"problem_card3_text": "Controller lenti, firmware instabili e velocità variabili sono tipici delle chiavette false. Aumentano il rischio di errori, soprattutto con file grandi."
|
||||
},
|
||||
|
||||
"features": {
|
||||
"features_kicker": "Funzioni Free & Pro",
|
||||
"features_title": "Inizia con il test rapido gratuito – passa alla modalità Pro quando ti serve di più.",
|
||||
"features_intro": "USBCheck cresce con le tue esigenze: gli utenti privati hanno spesso bisogno solo di una valutazione rapida. I professionisti vogliono analizzare in profondità, verificare la capacità e archiviare i report.",
|
||||
|
||||
"features_free_title": "Free Quick Check",
|
||||
"features_free_badge": "Consigliato per la maggior parte degli utenti",
|
||||
"features_free_text": "Ideale per verificare rapidamente se una chiavetta è sufficientemente veloce e stabile – senza installazione.",
|
||||
"features_free_li1": "• Test rapido basato su browser direttamente sulla chiavetta",
|
||||
"features_free_li2": "• Velocità di scrittura e lettura con dati reali",
|
||||
"features_free_li3": "• Controllo integrità basato su hash di un campione di dati",
|
||||
"features_free_li4": "• Vari livelli di test (es. 200 MB, 2 GB)",
|
||||
"features_free_li5": "• Nessuna registrazione necessaria",
|
||||
"features_free_cta": "Avvia il test rapido gratuito",
|
||||
|
||||
"features_pro_title": "Modalità Pro",
|
||||
"features_pro_badge": "Per power user e team",
|
||||
"features_pro_text": "Per chi ha bisogno di controllo totale: reparti IT, tecnici, refurbisher, laboratori o aziende che testano regolarmente molte chiavette.",
|
||||
"features_pro_li1": "• Scansione completa della capacità (simile a F3/badblocks)",
|
||||
"features_pro_li2": "• Rilevamento di capacità false e aree difettose",
|
||||
"features_pro_li3": "• Report dettagliati (JSON, PDF) salvabili",
|
||||
"features_pro_li4": "• Accesso API opzionale per flussi automatici",
|
||||
"features_pro_li5": "• Supporto multi-device e multi-utente (tramite login)",
|
||||
"features_pro_note": "La modalità Pro richiede un piccolo tool sul tuo sistema. Funziona in locale e può essere collegato al tuo account USBCheck."
|
||||
},
|
||||
|
||||
"security": {
|
||||
"security_kicker": "Sicurezza e privacy",
|
||||
"security_title": "Design privacy-first: i dati di test sono tuoi.",
|
||||
"security_intro": "USBCheck è stato progettato fin dall’inizio per proteggere i tuoi dati. Il test rapido nel browser utilizza solo file di test. I tuoi documenti, foto e backup non vengono letti né caricati. In modalità Pro decidi tu se e quali report vengono sincronizzati.",
|
||||
"security_card1_title": "Test solo in locale",
|
||||
"security_card1_text": "Tutti i test di lettura e scrittura vengono eseguiti in locale sulla chiavetta. Il browser accede solo ai file di test, non ai tuoi contenuti privati.",
|
||||
"security_card2_title": "Report trasparenti",
|
||||
"security_card2_text": "Con il login puoi salvare i report nel tuo account, esportarli o cancellarli. Tu decidi cosa rimane nel sistema.",
|
||||
"security_card3_title": "Delicato sull’hardware",
|
||||
"security_card3_text": "Il test rapido utilizza quantità moderate di dati per evitare usura inutile. La modalità Pro ti avvisa chiaramente prima di test intensivi."
|
||||
},
|
||||
|
||||
"faq": {
|
||||
"faq_kicker": "FAQ",
|
||||
"faq_title": "Domande frequenti su USBCheck",
|
||||
"faq_intro": "Qui trovi le risposte alle domande più comuni. La sezione FAQ può essere ampliata in qualsiasi momento con nuovi casi d’uso e feedback degli utenti.",
|
||||
"faq_q1": "Il test rapido è davvero solo nel browser?",
|
||||
"faq_a1": "Sì. Il test rapido viene eseguito interamente nel browser e utilizza API moderne per scrivere e leggere file di test sulla chiavetta. Nulla viene caricato senza il tuo consenso.",
|
||||
"faq_q2": "Serve un account per usare il test rapido?",
|
||||
"faq_a2": "No. Il test rapido gratuito è disponibile senza registrazione. Il login è necessario solo se vuoi salvare i report, gestire più chiavette o usare la modalità Pro.",
|
||||
"faq_q3": "USBCheck può rilevare con certezza ogni chiavetta falsa?",
|
||||
"faq_a3": "Nessuno strumento può garantire il 100%. Tuttavia, la modalità Pro con scansione completa è progettata per rilevare in modo affidabile i pattern di frode tipici.",
|
||||
"faq_q4": "Come si integra lo strumento nel mio sistema?",
|
||||
"faq_a4": "USBCheck è pensato per l’automazione. Tramite la modalità Pro e l’API pianificata puoi integrare i test nei flussi esistenti, ad esempio nei controlli di qualità o in ingresso merci."
|
||||
"brand_subtitle": "Controlla le chiavette USB contro i falsi"
|
||||
},
|
||||
|
||||
"footer": {
|
||||
@@ -137,30 +26,148 @@
|
||||
"footer_privacy": "Privacy",
|
||||
"footer_copy": "© {year} {{primary_domain}}. Tutti i diritti riservati."
|
||||
},
|
||||
"fake": {
|
||||
"fake_hero_kicker": "FakeCheck – Modalità browser",
|
||||
"fake_hero_title": "La mia chiavetta USB è falsa?",
|
||||
"fake_hero_lead": "FakeCheck ti aiuta a individuare le chiavette USB contraffatte: test di scrittura/lettura nel browser e controlli di capacità – senza installazione.",
|
||||
"fake_cta_start": "Avvia test nel browser (demo)",
|
||||
"fake_cta_back_home": "Torna alla panoramica",
|
||||
"fake_hero_hint": "FakeCheck crea solo file di test nella cartella selezionata. I tuoi file reali non vengono mai toccati.",
|
||||
|
||||
"fake_box_title": "Cosa può fare il test nel browser",
|
||||
"fake_box_point1_title": "Test di scrittura/lettura con file di test",
|
||||
"fake_box_point1_text": "Il browser crea file di test, misura le velocità di scrittura/lettura e verifica che i dati letti corrispondano ai dati scritti.",
|
||||
"fake_box_point2_title": "Verifica della capacità reale",
|
||||
"fake_box_point2_text": "La quantità di dati scritti e verificati permette di stimare la capacità realmente utilizzabile.",
|
||||
"fake_box_point3_title": "Report JSON per documentazione",
|
||||
"fake_box_point3_text": "Tutti i risultati vengono raccolti in un report JSON strutturato che puoi salvare, inviare o riutilizzare in seguito.",
|
||||
"fake_ui": {
|
||||
"error_fsapi_not_supported": "Questo browser non supporta la File System Access API.",
|
||||
"error_no_directory_selected": "Nessuna cartella selezionata.",
|
||||
"error_no_space_detected": "Impossibile riservare spazio libero nella cartella scelta.",
|
||||
|
||||
"fake_app_title": "Interfaccia test browser (anteprima)",
|
||||
"fake_app_intro": "Questa sarà la vera interfaccia FakeCheck: scegliere cartella, configurare dimensione test, vedere progresso e risultati. Il pulsante sopra mostra solo una demo.",
|
||||
"fake_app_point1": "Quick-test con piccoli dati.",
|
||||
"fake_app_point2": "Light benchmark: scrittura/lettura per un periodo limitato.",
|
||||
"fake_app_point3": "Write/verify: scrive i file di test e li verifica subito.",
|
||||
|
||||
"fake_result_title": "Output demo del test browser",
|
||||
"fake_result_hint": "Questa è solo un’anteprima. Qui verrà visualizzato il vero report JSON."
|
||||
}
|
||||
"log_capacity_probe_start": "Verifico lo spazio disponibile nella cartella selezionata...",
|
||||
"log_capacity_probe_result": "Spazio utilizzabile rilevato per i test: {size} (scrittura di prova).",
|
||||
|
||||
"log_quick_prepare": "Quick-Check: preparazione... (dimensione test: {size})",
|
||||
"log_quick_verify_start": "Quick-Check: scrittura completata. Verifico i dati...",
|
||||
"log_quick_data_error": "Quick-Check: errore dati al byte {byte}.",
|
||||
"error_quick_data_error": "Errore dati nel Quick-Check al byte {byte}.",
|
||||
"log_quick_delete_warn": "Quick-Check: impossibile eliminare il file di test (non critico).",
|
||||
"log_quick_success": "Quick-Check: completato con successo.",
|
||||
|
||||
"log_bench_start": "Benchmark: inizio – scrivo il file di test ({size})...",
|
||||
"log_bench_read_start": "Benchmark: lettura e timing...",
|
||||
"log_bench_delete_warn": "Benchmark: impossibile eliminare il file di test (non critico).",
|
||||
"log_bench_success": "Benchmark: completato con successo.",
|
||||
|
||||
"log_wv_start": "Write/Verify: avvio – {blocks} blocchi da {size} (totale {total})...",
|
||||
"log_wv_block_start": "Write/Verify: blocco {num}/{blocks} – {file}",
|
||||
"log_wv_data_error": "Write/Verify: errore dati nel blocco {num} al byte {byte}.",
|
||||
"error_wv_data_error": "Errore dati nel blocco {num} al byte {byte}.",
|
||||
"log_wv_delete_warn": "Write/Verify: impossibile eliminare il file {file} (non critico).",
|
||||
"log_wv_success": "Write/Verify: tutti i blocchi verificati correttamente.",
|
||||
|
||||
"log_all_subtest_start": "All-Inclusive: avvio del sotto-test \"{mode}\" ({num}/{total})...",
|
||||
"error_unknown_mode": "Modalità sconosciuta: {mode}",
|
||||
|
||||
"log_fsapi_partial": "Il tuo browser non supporta completamente la File System Access API. Alcune funzioni saranno disattivate.",
|
||||
|
||||
"selected_path_label": "Cartella USB selezionata (nome: \"{name}\").",
|
||||
"selected_path_none": "Nessuna cartella selezionata.",
|
||||
|
||||
"status_ready": "Pronto. Seleziona prima la chiavetta USB.",
|
||||
"status_mode_none": "Nessuna modalità selezionata",
|
||||
"status_dir_selected": "Cartella USB selezionata. Scegli una modalità.",
|
||||
"status_mode_selected": "Modalità \"{mode}\" selezionata. Puoi avviare la prova.",
|
||||
"status_running": "Test in corso... non scollegare la chiavetta.",
|
||||
"status_done": "Test completato.",
|
||||
"status_aborted": "Test annullato.",
|
||||
"status_error": "Errore: {msg}",
|
||||
"status_error_unknown": "Errore sconosciuto durante il test.",
|
||||
|
||||
"overall_initial": "Nessuna prova eseguita finora.",
|
||||
"overall_running": "Test in corso...",
|
||||
"overall_done": "Test del browser completato con successo.",
|
||||
"overall_aborted": "Test annullato.",
|
||||
"overall_error": "Errore nel test del browser.",
|
||||
|
||||
"log_dir_selected": "Cartella selezionata: {name}",
|
||||
"log_dir_reset": "Selezione cartella reimpostata.",
|
||||
"log_pick_abort": "Selezione della cartella annullata.",
|
||||
"log_pick_error": "Errore durante la selezione della cartella: {msg}",
|
||||
"log_pick_error_unknown": "Errore sconosciuto durante la selezione della cartella.",
|
||||
"log_mode_selected": "Modalità scelta: {mode}",
|
||||
"log_test_start": "Avvio test in modalità: {mode}",
|
||||
"log_test_aborted": "Test annullato dall'utente.",
|
||||
"log_test_error": "Errore durante il test: {msg}",
|
||||
"log_test_error_unknown": "Errore sconosciuto durante il test.",
|
||||
"log_loaded": "Test del browser USB (fakecheck) caricato. In attesa di cartella e modalità.",
|
||||
|
||||
"mode_quick": "Quick-Check",
|
||||
"mode_benchmark": "Benchmark",
|
||||
"mode_writeverify": "Write & Verify",
|
||||
"mode_all": "All-Inclusive (tutti i test)",
|
||||
|
||||
"log_backend_save_error_status": "Backend: impossibile salvare il risultato ({status}).",
|
||||
"log_backend_save_ok": "Backend: risultato salvato{suffix}.",
|
||||
"log_backend_save_error": "Errore durante il salvataggio nel backend: {msg}"
|
||||
},
|
||||
|
||||
"serial": {
|
||||
"rating_label": "Valutazione",
|
||||
|
||||
"rating": {
|
||||
"ok": {
|
||||
"label": "Plausibile",
|
||||
"desc": "Nessuna anomalia significativa rilevata."
|
||||
},
|
||||
"needs_review": {
|
||||
"label": "Serve verifica",
|
||||
"desc": "Piccole irregolarità. Un test tecnico fornisce maggiore chiarezza."
|
||||
},
|
||||
"suspicious": {
|
||||
"label": "Sospetto",
|
||||
"desc": "Anomalie notevoli. Consigliato un test di capacità o di scrittura/lettura."
|
||||
},
|
||||
"invalid": {
|
||||
"label": "Non valido",
|
||||
"desc": "Numero di serie non valutabile."
|
||||
},
|
||||
"unknown": {
|
||||
"label": "Non chiaro",
|
||||
"desc": "Non è stato possibile determinare un verdetto."
|
||||
}
|
||||
},
|
||||
|
||||
"heading_input": "Dati inseriti",
|
||||
"heading_analysis": "Analisi numero di serie",
|
||||
"heading_consistency": "Coerenza del produttore",
|
||||
|
||||
"input": {
|
||||
"manufacturer": "Produttore (dato utente):",
|
||||
"vidpid": "VID/PID:",
|
||||
"vendor_detected": "Produttore ricavato dalla VID:"
|
||||
},
|
||||
|
||||
"analysis": {
|
||||
"serial": "Numero di serie:",
|
||||
"length": "Lunghezza:",
|
||||
"category": "Categoria:",
|
||||
"score": "Punteggio:",
|
||||
"issues": "Osservazioni:"
|
||||
},
|
||||
|
||||
"chars": "caratteri",
|
||||
"none": "non indicato",
|
||||
|
||||
"issues_none": "Nessuna osservazione particolare.",
|
||||
|
||||
"vendor_detected": "{vendor} (VID {vid})",
|
||||
"vendor_unknown": "Produttore sconosciuto per VID {vid}",
|
||||
"vendor_none": "Nessuna VID fornita",
|
||||
|
||||
"disclaimer": "Questa valutazione è euristica e non garantisce l'autenticità.",
|
||||
|
||||
"error": {
|
||||
"no_serial": "Inserisci un numero di serie.",
|
||||
"api": "Errore durante la verifica: {msg}",
|
||||
"unknown": "Risposta inattesa dal server."
|
||||
}
|
||||
},
|
||||
|
||||
"pages": {
|
||||
"landing": {
|
||||
"meta": {
|
||||
"title": "{{primary_domain}} – Testa le tue USB contro i falsi",
|
||||
"description": "USBCheck combina un test rapido nel browser con un Pro Mode professionale. Scopri i falsi prima di perdere i tuoi dati."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
173
public/assets/i18n/us.json
Normal file
173
public/assets/i18n/us.json
Normal file
@@ -0,0 +1,173 @@
|
||||
{
|
||||
"meta": {
|
||||
"code": "us",
|
||||
"label": "English (US)",
|
||||
"flag": "🇺🇸"
|
||||
},
|
||||
|
||||
"header": {
|
||||
"header_slogan": "Test USB drives",
|
||||
"btn_login": "Login",
|
||||
|
||||
"nav_how": "How it works",
|
||||
"nav_problem": "Why it matters",
|
||||
"nav_features": "Features",
|
||||
"nav_security": "Security",
|
||||
"nav_faq": "FAQ"
|
||||
},
|
||||
|
||||
"brand": {
|
||||
"brand_wordmark": "{{primary_domain}}",
|
||||
"brand_subtitle": "Check USB drives for fakes"
|
||||
},
|
||||
|
||||
"footer": {
|
||||
"footer_imprint": "Legal",
|
||||
"footer_privacy": "Privacy",
|
||||
"footer_copy": "© {year} {{primary_domain}}. All rights reserved."
|
||||
},
|
||||
|
||||
"fake_ui": {
|
||||
"error_fsapi_not_supported": "This browser doesn’t support the File System Access API.",
|
||||
"error_no_directory_selected": "No directory selected.",
|
||||
"error_no_space_detected": "Couldn’t reserve free space in the selected directory.",
|
||||
|
||||
"log_capacity_probe_start": "Measuring available space in the selected directory...",
|
||||
"log_capacity_probe_result": "Writable space detected for tests: {size} (write probe).",
|
||||
|
||||
"log_quick_prepare": "Quick check: preparing… (test size: {size})",
|
||||
"log_quick_verify_start": "Quick check: write completed. Verifying data...",
|
||||
"log_quick_data_error": "Quick check: data error at byte {byte}.",
|
||||
"error_quick_data_error": "Data error in the quick check at byte {byte}.",
|
||||
"log_quick_delete_warn": "Quick check: couldn’t delete test file (not critical).",
|
||||
"log_quick_success": "Quick check finished successfully.",
|
||||
|
||||
"log_bench_start": "Benchmark: starting – writing test file ({size})...",
|
||||
"log_bench_read_start": "Benchmark: reading & timing...",
|
||||
"log_bench_delete_warn": "Benchmark: couldn’t delete test file (not critical).",
|
||||
"log_bench_success": "Benchmark completed successfully.",
|
||||
|
||||
"log_wv_start": "Write/Verify: starting – {blocks} blocks of {size} (total {total})...",
|
||||
"log_wv_block_start": "Write/Verify: block {num}/{blocks} – {file}",
|
||||
"log_wv_data_error": "Write/Verify: data error in block {num} at byte {byte}.",
|
||||
"error_wv_data_error": "Data error in block {num} at byte {byte}.",
|
||||
"log_wv_delete_warn": "Write/Verify: couldn’t delete block file {file} (not critical).",
|
||||
"log_wv_success": "Write/Verify: all blocks verified successfully.",
|
||||
|
||||
"log_all_subtest_start": "All-inclusive: starting subtest \"{mode}\" ({num}/{total})...",
|
||||
"error_unknown_mode": "Unknown mode: {mode}",
|
||||
|
||||
"log_fsapi_partial": "Your browser only partially supports the File System Access API. Some features are disabled.",
|
||||
|
||||
"selected_path_label": "USB folder selected (name: \"{name}\").",
|
||||
"selected_path_none": "No directory selected yet.",
|
||||
|
||||
"status_ready": "Ready. Select your USB drive first.",
|
||||
"status_mode_none": "No mode selected",
|
||||
"status_dir_selected": "USB directory selected. Choose a test mode next.",
|
||||
"status_mode_selected": "Mode \"{mode}\" selected. You can start the test now.",
|
||||
"status_running": "Test running... please keep the drive connected.",
|
||||
"status_done": "Test finished.",
|
||||
"status_aborted": "Test was canceled.",
|
||||
"status_error": "Error: {msg}",
|
||||
"status_error_unknown": "Unknown test error.",
|
||||
|
||||
"overall_initial": "No test has been run yet.",
|
||||
"overall_running": "Test running...",
|
||||
"overall_done": "Browser test completed successfully.",
|
||||
"overall_aborted": "Test canceled.",
|
||||
"overall_error": "Browser test failed.",
|
||||
|
||||
"log_dir_selected": "Directory selected: {name}",
|
||||
"log_dir_reset": "Directory selection cleared.",
|
||||
"log_pick_abort": "Directory selection canceled.",
|
||||
"log_pick_error": "Error while selecting directory: {msg}",
|
||||
"log_pick_error_unknown": "Unknown error while selecting directory.",
|
||||
"log_mode_selected": "Mode selected: {mode}",
|
||||
"log_test_start": "Starting tests in mode: {mode}",
|
||||
"log_test_aborted": "Test was canceled by the user.",
|
||||
"log_test_error": "Test failed: {msg}",
|
||||
"log_test_error_unknown": "Unknown error during the test.",
|
||||
"log_loaded": "USB browser test (fakecheck) loaded. Waiting for directory selection and mode.",
|
||||
|
||||
"mode_quick": "Quick check",
|
||||
"mode_benchmark": "Benchmark",
|
||||
"mode_writeverify": "Write & Verify",
|
||||
"mode_all": "All-inclusive (all browser tests)",
|
||||
|
||||
"log_backend_save_error_status": "Backend: couldn’t save result ({status}).",
|
||||
"log_backend_save_ok": "Backend: test result saved{suffix}.",
|
||||
"log_backend_save_error": "Error while saving to the backend: {msg}"
|
||||
},
|
||||
|
||||
"serial": {
|
||||
"rating_label": "Rating",
|
||||
|
||||
"rating": {
|
||||
"ok": {
|
||||
"label": "Plausible",
|
||||
"desc": "No obvious irregularities detected."
|
||||
},
|
||||
"needs_review": {
|
||||
"label": "Needs review",
|
||||
"desc": "Minor anomalies. Combine with a technical test for a clearer picture."
|
||||
},
|
||||
"suspicious": {
|
||||
"label": "Suspicious",
|
||||
"desc": "Significant anomalies detected. A capacity or write/read test is strongly recommended."
|
||||
},
|
||||
"invalid": {
|
||||
"label": "Invalid",
|
||||
"desc": "The serial number couldn’t be evaluated."
|
||||
},
|
||||
"unknown": {
|
||||
"label": "Unclear",
|
||||
"desc": "No clear verdict possible."
|
||||
}
|
||||
},
|
||||
|
||||
"heading_input": "Input data",
|
||||
"heading_analysis": "Serial number analysis",
|
||||
"heading_consistency": "Manufacturer consistency",
|
||||
|
||||
"input": {
|
||||
"manufacturer": "Manufacturer (user entry):",
|
||||
"vidpid": "VID/PID:",
|
||||
"vendor_detected": "Vendor from VID:"
|
||||
},
|
||||
|
||||
"analysis": {
|
||||
"serial": "Serial number:",
|
||||
"length": "Length:",
|
||||
"category": "Category:",
|
||||
"score": "Score:",
|
||||
"issues": "Findings:"
|
||||
},
|
||||
|
||||
"chars": "characters",
|
||||
"none": "not provided",
|
||||
|
||||
"issues_none": "No notable issues.",
|
||||
|
||||
"vendor_detected": "{vendor} (VID {vid})",
|
||||
"vendor_unknown": "Unknown manufacturer for VID {vid}",
|
||||
"vendor_none": "No vendor ID provided",
|
||||
|
||||
"disclaimer": "This assessment is heuristic and cannot guarantee authenticity.",
|
||||
|
||||
"error": {
|
||||
"no_serial": "Please enter a serial number.",
|
||||
"api": "Error during the check: {msg}",
|
||||
"unknown": "Unexpected response from the server."
|
||||
}
|
||||
},
|
||||
|
||||
"pages": {
|
||||
"landing": {
|
||||
"meta": {
|
||||
"title": "{{primary_domain}} – Test USB drives for fakes",
|
||||
"description": "USBCheck combines a fast browser quick check with a professional Pro mode so you recognize fake drives before they wipe your data."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,9 @@
|
||||
setOverallStatus,
|
||||
formatBytes,
|
||||
formatMbps,
|
||||
formatDuration
|
||||
formatDuration,
|
||||
t,
|
||||
tFmt
|
||||
} = window.usbcheck;
|
||||
|
||||
const root = document.getElementById("fc-root");
|
||||
@@ -55,17 +57,17 @@
|
||||
constructor() {
|
||||
this.rootHandle = null;
|
||||
this.abortController = null;
|
||||
this.capacityBytes = null;
|
||||
this.capacityProbeFile = "usbcheck_capacity_probe.bin";
|
||||
}
|
||||
|
||||
hasFsApiSupport() {
|
||||
return "showDirectoryPicker" in window;
|
||||
}
|
||||
|
||||
// Wird aktuell nicht mehr verwendet (Picker ist direkt im Click-Handler),
|
||||
// kann aber als Fallback/Refactoring-Hook bleiben.
|
||||
async pickDirectory() {
|
||||
if (!this.hasFsApiSupport()) {
|
||||
throw new Error("File System Access API wird von diesem Browser nicht unterstützt.");
|
||||
throw new Error(t("fake_ui.error_fsapi_not_supported", "File System Access API wird von diesem Browser nicht unterstützt."));
|
||||
}
|
||||
const handle = await window.showDirectoryPicker();
|
||||
this.rootHandle = handle;
|
||||
@@ -74,21 +76,120 @@
|
||||
|
||||
async clearSelection() {
|
||||
this.rootHandle = null;
|
||||
this.capacityBytes = null;
|
||||
}
|
||||
|
||||
// Freispeicher-Ermittlung
|
||||
async ensureCapacity(abortSignal) {
|
||||
if (this.capacityBytes != null) return this.capacityBytes;
|
||||
if (!this.rootHandle) {
|
||||
throw new Error(t("fake_ui.error_no_directory_selected", "Kein Verzeichnis ausgewählt."));
|
||||
}
|
||||
|
||||
const dirHandle = this.rootHandle;
|
||||
const PROBE_FILENAME = this.capacityProbeFile;
|
||||
const CHUNK_SIZE = 1024 * 1024; // 1 MiB
|
||||
const MAX_BYTES = 128 * 1024 * 1024; // max. 128 MiB testen
|
||||
|
||||
logLine(t("fake_ui.log_capacity_probe_start", "Ermittle verfügbaren Speicherplatz im gewählten Verzeichnis..."), "info");
|
||||
|
||||
let bytesWritten = 0;
|
||||
let writable = null;
|
||||
|
||||
try {
|
||||
const fileHandle = await dirHandle.getFileHandle(PROBE_FILENAME, { create: true });
|
||||
writable = await fileHandle.createWritable();
|
||||
|
||||
const chunk = new Uint8Array(CHUNK_SIZE);
|
||||
chunk.fill(0x5a);
|
||||
|
||||
while (bytesWritten + CHUNK_SIZE <= MAX_BYTES) {
|
||||
if (abortSignal && abortSignal.aborted) {
|
||||
await writable.abort();
|
||||
throw new DOMException("Abgebrochen", "AbortError");
|
||||
}
|
||||
|
||||
await writable.write(chunk);
|
||||
bytesWritten += CHUNK_SIZE;
|
||||
}
|
||||
|
||||
await writable.close();
|
||||
} catch (err) {
|
||||
if (writable) {
|
||||
try { await writable.close(); } catch (e) {}
|
||||
}
|
||||
if (err && err.name === "AbortError") {
|
||||
throw err;
|
||||
}
|
||||
// sonst: „Out of space“ → okay, wir nehmen bytesWritten als Limit
|
||||
} finally {
|
||||
try {
|
||||
await dirHandle.removeEntry(PROBE_FILENAME);
|
||||
} catch (e) {
|
||||
// egal
|
||||
}
|
||||
}
|
||||
|
||||
if (!bytesWritten) {
|
||||
throw new Error(t("fake_ui.error_no_space_detected", "Es konnte kein freier Speicher im gewählten Verzeichnis reserviert werden."));
|
||||
}
|
||||
|
||||
this.capacityBytes = bytesWritten;
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_capacity_probe_result",
|
||||
"Ermittelter für Tests nutzbarer Speicher: {size} (Schreibprobe).",
|
||||
{ size: formatBytes(bytesWritten) }
|
||||
),
|
||||
"info"
|
||||
);
|
||||
|
||||
return this.capacityBytes;
|
||||
}
|
||||
|
||||
planSizeBytes({ defaultMB, minMB, maxFraction }) {
|
||||
const MiB = 1024 * 1024;
|
||||
const cap = this.capacityBytes || (64 * MiB);
|
||||
|
||||
const minBytes = (minMB || 1) * MiB;
|
||||
const defaultBytes = (defaultMB || 8) * MiB;
|
||||
const maxBytesByCap = Math.max(minBytes, cap * (maxFraction || 0.25));
|
||||
|
||||
let target = Math.min(defaultBytes, maxBytesByCap);
|
||||
|
||||
const CHUNK_SIZE = MiB;
|
||||
target = Math.floor(target / CHUNK_SIZE) * CHUNK_SIZE;
|
||||
if (target < CHUNK_SIZE) target = CHUNK_SIZE;
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
// Quick-Check
|
||||
async runQuickCheck(report, progressCb, abortSignal) {
|
||||
const TEST_FILENAME = "usbcheck_quick_test.bin";
|
||||
const TEST_SIZE_MB = 8;
|
||||
const CHUNK_SIZE = 1024 * 1024;
|
||||
|
||||
const dirHandle = this.rootHandle;
|
||||
if (!dirHandle) throw new Error("Kein Verzeichnis ausgewählt.");
|
||||
if (!dirHandle) throw new Error(t("fake_ui.error_no_directory_selected", "Kein Verzeichnis ausgewählt."));
|
||||
|
||||
const totalBytes = this.planSizeBytes({
|
||||
defaultMB: 8,
|
||||
minMB: 1,
|
||||
maxFraction: 0.25
|
||||
});
|
||||
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_quick_prepare",
|
||||
"Quick-Check: Vorbereitung... (Testgröße: {size})",
|
||||
{ size: formatBytes(totalBytes) }
|
||||
),
|
||||
"info"
|
||||
);
|
||||
|
||||
logLine("Quick-Check: Vorbereitung...", "info");
|
||||
const fileHandle = await dirHandle.getFileHandle(TEST_FILENAME, { create: true });
|
||||
const writable = await fileHandle.createWritable();
|
||||
|
||||
const totalBytes = TEST_SIZE_MB * 1024 * 1024;
|
||||
let writtenBytes = 0;
|
||||
|
||||
const writeStart = performance.now();
|
||||
@@ -110,7 +211,7 @@
|
||||
await writable.close();
|
||||
const writeEnd = performance.now();
|
||||
|
||||
logLine("Quick-Check: Schreiben abgeschlossen. Verifiziere Daten...", "info");
|
||||
logLine(t("fake_ui.log_quick_verify_start", "Quick-Check: Schreiben abgeschlossen. Verifiziere Daten..."), "info");
|
||||
|
||||
const file = await fileHandle.getFile();
|
||||
const readStart = performance.now();
|
||||
@@ -129,8 +230,21 @@
|
||||
for (let i = 0; i < chunk.length; i++) {
|
||||
const expected = (offset + i) % 251;
|
||||
if (chunk[i] !== expected) {
|
||||
logLine(`Quick-Check: Datenfehler bei Byte ${offset + i}`, "error");
|
||||
throw new Error(`Datenfehler im Quick-Check bei Byte ${offset + i}`);
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_quick_data_error",
|
||||
"Quick-Check: Datenfehler bei Byte {byte}",
|
||||
{ byte: (offset + i).toString() }
|
||||
),
|
||||
"error"
|
||||
);
|
||||
throw new Error(
|
||||
tFmt(
|
||||
"fake_ui.error_quick_data_error",
|
||||
"Datenfehler im Quick-Check bei Byte {byte}",
|
||||
{ byte: (offset + i).toString() }
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
offset += chunk.length;
|
||||
@@ -156,22 +270,41 @@
|
||||
ok: true
|
||||
};
|
||||
|
||||
logLine("Quick-Check: Erfolgreich abgeschlossen.", "info");
|
||||
try {
|
||||
await dirHandle.removeEntry(TEST_FILENAME);
|
||||
} catch (e) {
|
||||
logLine(t("fake_ui.log_quick_delete_warn", "Quick-Check: Konnte Testdatei nicht löschen (nicht kritisch)."), "warn");
|
||||
}
|
||||
|
||||
logLine(t("fake_ui.log_quick_success", "Quick-Check: Erfolgreich abgeschlossen."), "info");
|
||||
}
|
||||
|
||||
// Benchmark
|
||||
async runBenchmark(report, progressCb, abortSignal) {
|
||||
const TEST_FILENAME = "usbcheck_benchmark.bin";
|
||||
const TEST_SIZE_MB = 32;
|
||||
const CHUNK_SIZE = 1024 * 1024;
|
||||
|
||||
const dirHandle = this.rootHandle;
|
||||
if (!dirHandle) throw new Error("Kein Verzeichnis ausgewählt.");
|
||||
if (!dirHandle) throw new Error(t("fake_ui.error_no_directory_selected", "Kein Verzeichnis ausgewählt."));
|
||||
|
||||
const totalBytes = this.planSizeBytes({
|
||||
defaultMB: 32,
|
||||
minMB: 4,
|
||||
maxFraction: 0.5
|
||||
});
|
||||
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_bench_start",
|
||||
"Benchmark: Start – schreibe Testdatei ({size})...",
|
||||
{ size: formatBytes(totalBytes) }
|
||||
),
|
||||
"info"
|
||||
);
|
||||
|
||||
logLine("Benchmark: Start – schreibe Testdatei...", "info");
|
||||
const fileHandle = await dirHandle.getFileHandle(TEST_FILENAME, { create: true });
|
||||
const writable = await fileHandle.createWritable();
|
||||
|
||||
const totalBytes = TEST_SIZE_MB * 1024 * 1024;
|
||||
let writtenBytes = 0;
|
||||
|
||||
const writeStart = performance.now();
|
||||
@@ -193,7 +326,7 @@
|
||||
await writable.close();
|
||||
const writeEnd = performance.now();
|
||||
|
||||
logLine("Benchmark: Lesen & Timing...", "info");
|
||||
logLine(t("fake_ui.log_bench_read_start", "Benchmark: Lesen & Timing..."), "info");
|
||||
|
||||
const file = await fileHandle.getFile();
|
||||
const readStart = performance.now();
|
||||
@@ -227,21 +360,50 @@
|
||||
ok: true
|
||||
};
|
||||
|
||||
logLine("Benchmark: Erfolgreich abgeschlossen.", "info");
|
||||
try {
|
||||
await dirHandle.removeEntry(TEST_FILENAME);
|
||||
} catch (e) {
|
||||
logLine(t("fake_ui.log_bench_delete_warn", "Benchmark: Konnte Testdatei nicht löschen (nicht kritisch)."), "warn");
|
||||
}
|
||||
|
||||
logLine(t("fake_ui.log_bench_success", "Benchmark: Erfolgreich abgeschlossen."), "info");
|
||||
}
|
||||
|
||||
// Write/Verify
|
||||
async runWriteVerify(report, progressCb, abortSignal) {
|
||||
const BASE_FILENAME = "usbcheck_block_";
|
||||
const BLOCKS = 4;
|
||||
const BLOCK_SIZE_MB = 32;
|
||||
const CHUNK_SIZE = 1024 * 1024;
|
||||
|
||||
const dirHandle = this.rootHandle;
|
||||
if (!dirHandle) throw new Error("Kein Verzeichnis ausgewählt.");
|
||||
if (!dirHandle) throw new Error(t("fake_ui.error_no_directory_selected", "Kein Verzeichnis ausgewählt."));
|
||||
|
||||
logLine("Write/Verify: Start – mehrere Blöcke werden getestet...", "info");
|
||||
const totalBytesPlanned = this.planSizeBytes({
|
||||
defaultMB: 128,
|
||||
minMB: 8,
|
||||
maxFraction: 0.75
|
||||
});
|
||||
|
||||
const blockBytes = Math.max(
|
||||
CHUNK_SIZE,
|
||||
Math.floor(totalBytesPlanned / BLOCKS / CHUNK_SIZE) * CHUNK_SIZE
|
||||
);
|
||||
|
||||
const totalBytes = blockBytes * BLOCKS;
|
||||
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_wv_start",
|
||||
"Write/Verify: Start – {blocks} Blöcke à {size} (gesamt {total})...",
|
||||
{
|
||||
blocks: BLOCKS.toString(),
|
||||
size: formatBytes(blockBytes),
|
||||
total: formatBytes(totalBytes)
|
||||
}
|
||||
),
|
||||
"info"
|
||||
);
|
||||
|
||||
const totalBytes = BLOCKS * BLOCK_SIZE_MB * 1024 * 1024;
|
||||
let writtenBytes = 0;
|
||||
let verifiedBytes = 0;
|
||||
|
||||
@@ -251,21 +413,32 @@
|
||||
|
||||
for (let b = 0; b < BLOCKS; b++) {
|
||||
const filename = `${BASE_FILENAME}${String(b + 1).padStart(2, "0")}.bin`;
|
||||
logLine(`Write/Verify: Block ${b + 1}/${BLOCKS} – ${filename}`, "info");
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_wv_block_start",
|
||||
"Write/Verify: Block {num}/{blocks} – {file}",
|
||||
{
|
||||
num: (b + 1).toString(),
|
||||
blocks: BLOCKS.toString(),
|
||||
file: filename
|
||||
}
|
||||
),
|
||||
"info"
|
||||
);
|
||||
|
||||
const fileHandle = await dirHandle.getFileHandle(filename, { create: true });
|
||||
const writable = await fileHandle.createWritable();
|
||||
|
||||
const blockBytes = BLOCK_SIZE_MB * 1024 * 1024;
|
||||
const blockBytesTotal = blockBytes;
|
||||
let blockWritten = 0;
|
||||
const blockWriteStart = performance.now();
|
||||
|
||||
while (blockWritten < blockBytes) {
|
||||
while (blockWritten < blockBytesTotal) {
|
||||
if (abortSignal.aborted) {
|
||||
await writable.abort();
|
||||
throw new DOMException("Abgebrochen", "AbortError");
|
||||
}
|
||||
const remaining = blockBytes - blockWritten;
|
||||
const remaining = blockBytesTotal - blockWritten;
|
||||
const chunkLen = Math.min(CHUNK_SIZE, remaining);
|
||||
const chunk = new Uint8Array(chunkLen);
|
||||
for (let i = 0; i < chunkLen; i++) {
|
||||
@@ -281,7 +454,7 @@
|
||||
const blockWriteEnd = performance.now();
|
||||
writeDetails.push({
|
||||
block: b + 1,
|
||||
bytes: blockBytes,
|
||||
bytes: blockBytesTotal,
|
||||
duration_s: (blockWriteEnd - blockWriteStart) / 1000
|
||||
});
|
||||
|
||||
@@ -301,8 +474,27 @@
|
||||
for (let i = 0; i < chunk.length; i++) {
|
||||
const expected = (i + blockOffset + b * 13) % 251;
|
||||
if (chunk[i] !== expected) {
|
||||
logLine(`Write/Verify: Datenfehler in Block ${b + 1} bei Byte ${blockOffset + i}`, "error");
|
||||
throw new Error(`Datenfehler in Block ${b + 1} bei Byte ${blockOffset + i}`);
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_wv_data_error",
|
||||
"Write/Verify: Datenfehler in Block {num} bei Byte {byte}",
|
||||
{
|
||||
num: (b + 1).toString(),
|
||||
byte: (blockOffset + i).toString()
|
||||
}
|
||||
),
|
||||
"error"
|
||||
);
|
||||
throw new Error(
|
||||
tFmt(
|
||||
"fake_ui.error_wv_data_error",
|
||||
"Datenfehler in Block {num} bei Byte {byte}",
|
||||
{
|
||||
num: (b + 1).toString(),
|
||||
byte: (blockOffset + i).toString()
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
blockOffset += chunk.length;
|
||||
@@ -313,9 +505,22 @@
|
||||
const blockReadEnd = performance.now();
|
||||
readDetails.push({
|
||||
block: b + 1,
|
||||
bytes: blockBytes,
|
||||
bytes: blockBytesTotal,
|
||||
duration_s: (blockReadEnd - blockReadStart) / 1000
|
||||
});
|
||||
|
||||
try {
|
||||
await dirHandle.removeEntry(filename);
|
||||
} catch (e) {
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_wv_delete_warn",
|
||||
"Write/Verify: Konnte Blockdatei {file} nicht löschen (nicht kritisch).",
|
||||
{ file: filename }
|
||||
),
|
||||
"warn"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const globalEnd = performance.now();
|
||||
@@ -329,7 +534,7 @@
|
||||
report.writeverify = {
|
||||
mode: "writeverify",
|
||||
blocks: BLOCKS,
|
||||
block_size_mb: BLOCK_SIZE_MB,
|
||||
block_size_bytes: blockBytes,
|
||||
total_bytes: totalBytes,
|
||||
written_bytes: writtenBytes,
|
||||
verified_bytes: verifiedBytes,
|
||||
@@ -342,14 +547,16 @@
|
||||
|
||||
report.writeverify_total_duration_s = totalDuration;
|
||||
|
||||
logLine("Write/Verify: Alle Blöcke erfolgreich verifiziert.", "info");
|
||||
logLine(t("fake_ui.log_wv_success", "Write/Verify: Alle Blöcke erfolgreich verifiziert."), "info");
|
||||
}
|
||||
|
||||
async run(mode, updateProgressCb, abortSignal) {
|
||||
if (!this.rootHandle) {
|
||||
throw new Error("Kein USB-Verzeichnis ausgewählt.");
|
||||
throw new Error(t("fake_ui.error_no_directory_selected", "Kein Verzeichnis ausgewählt."));
|
||||
}
|
||||
|
||||
await this.ensureCapacity(abortSignal);
|
||||
|
||||
const report = {
|
||||
meta: {
|
||||
base_url: cfg.baseUrl || "",
|
||||
@@ -375,11 +582,21 @@
|
||||
} else if (mode === "writeverify") {
|
||||
await this.runWriteVerify(report, updateProgressCb, abortSignal);
|
||||
} else if (mode === "all") {
|
||||
// Alle drei Tests nacheinander im selben Report
|
||||
const modes = ["quick", "benchmark", "writeverify"];
|
||||
for (let i = 0; i < modes.length; i++) {
|
||||
const subMode = modes[i];
|
||||
logLine(`All-Inclusive: Starte Teiltest "${subMode}" (${i + 1}/${modes.length})...`, "info");
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_all_subtest_start",
|
||||
"All-Inclusive: Starte Teiltest \"{mode}\" ({num}/{total})...",
|
||||
{
|
||||
mode: subMode,
|
||||
num: (i + 1).toString(),
|
||||
total: modes.length.toString()
|
||||
}
|
||||
),
|
||||
"info"
|
||||
);
|
||||
|
||||
const base = (i / modes.length) * 100;
|
||||
const span = (1 / modes.length) * 100;
|
||||
@@ -397,7 +614,7 @@
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new Error("Unbekannter Modus: " + mode);
|
||||
throw new Error(tFmt("fake_ui.error_unknown_mode", "Unbekannter Modus: {mode}", { mode }));
|
||||
}
|
||||
|
||||
const t1 = performance.now();
|
||||
@@ -415,7 +632,7 @@
|
||||
if (!tester.hasFsApiSupport()) {
|
||||
if (fsapiWarning) fsapiWarning.style.display = "block";
|
||||
logLine(
|
||||
"Dein Browser unterstützt die File System Access API nicht voll. Einige Funktionen sind deaktiviert.",
|
||||
t("fake_ui.log_fsapi_partial", "Dein Browser unterstützt die File System Access API nicht voll. Einige Funktionen sind deaktiviert."),
|
||||
"warn"
|
||||
);
|
||||
}
|
||||
@@ -429,8 +646,6 @@
|
||||
|
||||
// --- Event-Handler ------------------------------------------------------
|
||||
|
||||
// Wichtig: showDirectoryPicker direkt im Click-Handler per Promise,
|
||||
// kein async/await direkt im Listener → vermeidet "User activation is required".
|
||||
let isPickingDir = false;
|
||||
|
||||
if (btnPickDir) {
|
||||
@@ -439,7 +654,7 @@
|
||||
isPickingDir = true;
|
||||
|
||||
if (!("showDirectoryPicker" in window)) {
|
||||
logLine("File System Access API wird von diesem Browser nicht unterstützt.", "error");
|
||||
logLine(t("fake_ui.error_fsapi_not_supported", "File System Access API wird von diesem Browser nicht unterstützt."), "error");
|
||||
if (fsapiWarning) fsapiWarning.style.display = "block";
|
||||
isPickingDir = false;
|
||||
return;
|
||||
@@ -448,22 +663,41 @@
|
||||
window.showDirectoryPicker()
|
||||
.then((handle) => {
|
||||
tester.rootHandle = handle;
|
||||
tester.capacityBytes = null;
|
||||
|
||||
if (selectedPathText) {
|
||||
selectedPathText.textContent =
|
||||
'USB-Ordner ausgewählt (Name: "' + (handle.name || "Unbekannt") + '").';
|
||||
selectedPathText.textContent = tFmt(
|
||||
"fake_ui.selected_path_label",
|
||||
'USB-Ordner ausgewählt (Name: "{name}").',
|
||||
{ name: (handle.name || "Unbekannt") }
|
||||
);
|
||||
}
|
||||
if (btnClearSel) btnClearSel.disabled = false;
|
||||
setStatus("USB-Verzeichnis ausgewählt. Wähle jetzt einen Testmodus.");
|
||||
logLine("Verzeichnis ausgewählt: " + (handle.name || "[ohne Namen]"));
|
||||
setStatus(t("fake_ui.status_dir_selected", "USB-Verzeichnis ausgewählt. Wähle jetzt einen Testmodus."));
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_dir_selected",
|
||||
"Verzeichnis ausgewählt: {name}",
|
||||
{ name: (handle.name || "[ohne Namen]") }
|
||||
),
|
||||
"info"
|
||||
);
|
||||
updateStartButtonState();
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err && err.name === "AbortError") {
|
||||
logLine("Verzeichnisauswahl abgebrochen.", "warn");
|
||||
logLine(t("fake_ui.log_pick_abort", "Verzeichnisauswahl abgebrochen."), "warn");
|
||||
} else if (err) {
|
||||
logLine("Fehler bei Verzeichnisauswahl: " + err.message, "error");
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_pick_error",
|
||||
"Fehler bei Verzeichnisauswahl: {msg}",
|
||||
{ msg: err.message || "unbekannt" }
|
||||
),
|
||||
"error"
|
||||
);
|
||||
} else {
|
||||
logLine("Unbekannter Fehler bei Verzeichnisauswahl.", "error");
|
||||
logLine(t("fake_ui.log_pick_error_unknown", "Unbekannter Fehler bei Verzeichnisauswahl."), "error");
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -476,11 +710,11 @@
|
||||
btnClearSel.addEventListener("click", async () => {
|
||||
await tester.clearSelection();
|
||||
if (selectedPathText) {
|
||||
selectedPathText.textContent = "Noch kein Verzeichnis gewählt.";
|
||||
selectedPathText.textContent = t("fake_ui.selected_path_none", "Noch kein Verzeichnis gewählt.");
|
||||
}
|
||||
btnClearSel.disabled = true;
|
||||
setStatus("Bereit. Wähle zuerst deinen USB-Stick aus.");
|
||||
logLine("Verzeichnisauswahl zurückgesetzt.", "info");
|
||||
setStatus(t("fake_ui.status_ready", "Bereit. Wähle zuerst deinen USB-Stick aus."));
|
||||
logLine(t("fake_ui.log_dir_reset", "Verzeichnisauswahl zurückgesetzt."), "info");
|
||||
updateStartButtonState();
|
||||
});
|
||||
}
|
||||
@@ -489,14 +723,27 @@
|
||||
tile.addEventListener("click", () => {
|
||||
if (tile.classList.contains("disabled")) return;
|
||||
if (isRunning) return;
|
||||
modeTiles.forEach((t) => t.classList.remove("selected"));
|
||||
modeTiles.forEach((tEl) => tEl.classList.remove("selected"));
|
||||
tile.classList.add("selected");
|
||||
currentMode = tile.getAttribute("data-mode");
|
||||
const titleEl = tile.querySelector("h4");
|
||||
const label = titleEl ? titleEl.textContent : currentMode;
|
||||
setModeLabel(label || "");
|
||||
setStatus(`Modus "${label}" ausgewählt. Du kannst den Test jetzt starten.`);
|
||||
logLine("Modus gewählt: " + currentMode, "info");
|
||||
setStatus(
|
||||
tFmt(
|
||||
"fake_ui.status_mode_selected",
|
||||
'Modus "{mode}" ausgewählt. Du kannst den Test jetzt starten.',
|
||||
{ mode: label || currentMode || "" }
|
||||
)
|
||||
);
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_mode_selected",
|
||||
"Modus gewählt: {mode}",
|
||||
{ mode: currentMode || "" }
|
||||
),
|
||||
"info"
|
||||
);
|
||||
updateStartButtonState();
|
||||
});
|
||||
});
|
||||
@@ -509,9 +756,16 @@
|
||||
if (btnCancel) btnCancel.disabled = false;
|
||||
if (saveError) saveError.style.display = "none";
|
||||
setProgress(0);
|
||||
logLine("Starte Tests im Modus: " + currentMode.toUpperCase(), "info");
|
||||
setStatus("Test läuft... bitte USB-Stick nicht entfernen.");
|
||||
setOverallStatus("warn", "Test läuft...");
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_test_start",
|
||||
"Starte Tests im Modus: {mode}",
|
||||
{ mode: (currentMode || "").toUpperCase() }
|
||||
),
|
||||
"info"
|
||||
);
|
||||
setStatus(t("fake_ui.status_running", "Test läuft... bitte USB-Stick nicht entfernen."));
|
||||
setOverallStatus("warn", t("fake_ui.overall_running", "Test läuft..."));
|
||||
|
||||
const abortController = new AbortController();
|
||||
tester.abortController = abortController;
|
||||
@@ -523,8 +777,8 @@
|
||||
report = await tester.run(currentMode, updateProgressCb, abortController.signal);
|
||||
|
||||
setProgress(100);
|
||||
setStatus("Test abgeschlossen.");
|
||||
setOverallStatus("ok", "Browser-Test erfolgreich abgeschlossen.");
|
||||
setStatus(t("fake_ui.status_done", "Test abgeschlossen."));
|
||||
setOverallStatus("ok", t("fake_ui.overall_done", "Browser-Test erfolgreich abgeschlossen."));
|
||||
applyReportToDashboard(report);
|
||||
|
||||
console.log("USB Browser Test Report (fakecheck):", report);
|
||||
@@ -532,17 +786,30 @@
|
||||
await saveReportToBackend(report);
|
||||
} catch (err) {
|
||||
if (err && err.name === "AbortError") {
|
||||
setStatus("Test wurde abgebrochen.");
|
||||
setOverallStatus("warn", "Test abgebrochen.");
|
||||
logLine("Test wurde vom Benutzer abgebrochen.", "warn");
|
||||
setStatus(t("fake_ui.status_aborted", "Test wurde abgebrochen."));
|
||||
setOverallStatus("warn", t("fake_ui.overall_aborted", "Test abgebrochen."));
|
||||
logLine(t("fake_ui.log_test_aborted", "Test wurde vom Benutzer abgebrochen."), "warn");
|
||||
} else if (err) {
|
||||
setStatus("Fehler: " + err.message);
|
||||
setOverallStatus("bad", "Fehler im Browser-Test.");
|
||||
logLine("Fehler im Test: " + err.message, "error");
|
||||
setStatus(
|
||||
tFmt(
|
||||
"fake_ui.status_error",
|
||||
"Fehler: {msg}",
|
||||
{ msg: err.message || "unbekannt" }
|
||||
)
|
||||
);
|
||||
setOverallStatus("bad", t("fake_ui.overall_error", "Fehler im Browser-Test."));
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_test_error",
|
||||
"Fehler im Test: {msg}",
|
||||
{ msg: err.message || "unbekannt" }
|
||||
),
|
||||
"error"
|
||||
);
|
||||
} else {
|
||||
setStatus("Unbekannter Fehler im Test.");
|
||||
setOverallStatus("bad", "Fehler im Browser-Test.");
|
||||
logLine("Unbekannter Fehler im Test.", "error");
|
||||
setStatus(t("fake_ui.status_error_unknown", "Unbekannter Fehler im Test."));
|
||||
setOverallStatus("bad", t("fake_ui.overall_error", "Fehler im Browser-Test."));
|
||||
logLine(t("fake_ui.log_test_error_unknown", "Unbekannter Fehler im Test."), "error");
|
||||
}
|
||||
} finally {
|
||||
isRunning = false;
|
||||
@@ -564,10 +831,10 @@
|
||||
|
||||
function applyReportToDashboard(report) {
|
||||
const modeLabelMap = {
|
||||
quick: "Quick-Check",
|
||||
benchmark: "Benchmark",
|
||||
writeverify: "Write & Verify",
|
||||
all: "All-Inclusive (alle Browser-Tests)"
|
||||
quick: t("fake_ui.mode_quick", "Quick-Check"),
|
||||
benchmark: t("fake_ui.mode_benchmark", "Benchmark"),
|
||||
writeverify: t("fake_ui.mode_writeverify", "Write & Verify"),
|
||||
all: t("fake_ui.mode_all", "All-Inclusive (alle Browser-Tests)")
|
||||
};
|
||||
|
||||
if (resMode) {
|
||||
@@ -631,7 +898,14 @@
|
||||
|
||||
if (!response.ok) {
|
||||
const msg = "HTTP " + response.status;
|
||||
logLine("Backend: Konnte Ergebnis nicht speichern (" + msg + ").", "warn");
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_backend_save_error_status",
|
||||
"Backend: Konnte Ergebnis nicht speichern ({status}).",
|
||||
{ status: msg }
|
||||
),
|
||||
"warn"
|
||||
);
|
||||
if (response.status >= 500 && saveError) {
|
||||
saveError.style.display = "block";
|
||||
}
|
||||
@@ -640,21 +914,34 @@
|
||||
|
||||
const data = await response.json().catch(() => null);
|
||||
logLine(
|
||||
"Backend: Testergebnis gespeichert" +
|
||||
(data && data.id ? ` (ID: ${data.id})` : ""),
|
||||
tFmt(
|
||||
"fake_ui.log_backend_save_ok",
|
||||
"Backend: Testergebnis gespeichert{suffix}",
|
||||
{ suffix: (data && data.id ? ` (ID: ${data.id})` : "") }
|
||||
),
|
||||
"info"
|
||||
);
|
||||
} catch (err) {
|
||||
if (saveError) saveError.style.display = "block";
|
||||
logLine("Fehler beim Speichern im Backend: " + (err ? err.message : "unbekannt"), "error");
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_backend_save_error",
|
||||
"Fehler beim Speichern im Backend: {msg}",
|
||||
{ msg: err ? err.message || "unbekannt" : "unbekannt" }
|
||||
),
|
||||
"error"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Initialzustand -----------------------------------------------------
|
||||
|
||||
setStatus("Bereit. Wähle zuerst deinen USB-Stick aus.");
|
||||
setModeLabel("Kein Modus selektiert");
|
||||
setOverallStatus("ok", "Noch kein Test durchgeführt.");
|
||||
logLine("USB-Browser-Test (fakecheck) geladen. Warte auf Verzeichnisauswahl und Modus.");
|
||||
setStatus(t("fake_ui.status_ready", "Bereit. Wähle zuerst deinen USB-Stick aus."));
|
||||
setModeLabel(t("fake_ui.status_mode_none", "Kein Modus selektiert"));
|
||||
setOverallStatus("ok", t("fake_ui.overall_initial", "Noch kein Test durchgeführt."));
|
||||
logLine(
|
||||
t("fake_ui.log_loaded", "USB-Browser-Test (fakecheck) geladen. Warte auf Verzeichnisauswahl und Modus."),
|
||||
"info"
|
||||
);
|
||||
updateStartButtonState();
|
||||
})();
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
// Namespace
|
||||
window.usbcheck = window.usbcheck || {};
|
||||
const usbcheck = window.usbcheck;
|
||||
|
||||
const cfg = window.usbConfig || {};
|
||||
|
||||
@@ -16,14 +17,81 @@
|
||||
return "https://api.usbcheck.it";
|
||||
}
|
||||
|
||||
// Locale aus Config:
|
||||
// - bevorzugt fakecheck.locale (aus PHP fakecheck-Block)
|
||||
// - sonst cfg.lang
|
||||
const locale =
|
||||
(cfg.fakecheck && cfg.fakecheck.locale)
|
||||
|| cfg.lang
|
||||
|| "en";
|
||||
|
||||
// Config bereitstellen
|
||||
usbcheck.cfg = {
|
||||
baseUrl: cfg.baseUrl || "",
|
||||
locale: (cfg.lang || "en").toLowerCase(),
|
||||
apiBase: cfg.apiBaseUrl || detectApiBaseUrl(),
|
||||
// wenn fakecheck.baseUrl vorhanden ist → bevorzugen
|
||||
baseUrl: (cfg.fakecheck && cfg.fakecheck.baseUrl) || cfg.baseUrl || "",
|
||||
locale: (locale || "en").toLowerCase(),
|
||||
apiBase: (cfg.fakecheck && cfg.fakecheck.apiBaseUrl) || cfg.apiBaseUrl || detectApiBaseUrl(),
|
||||
loggedIn: !!cfg.isLoggedIn
|
||||
};
|
||||
|
||||
// -----------------------------------
|
||||
// i18n – JSON laden + Helfer
|
||||
// -----------------------------------
|
||||
|
||||
usbcheck.locale = usbcheck.cfg.locale || "en";
|
||||
usbcheck.i18n = {};
|
||||
|
||||
function loadI18n() {
|
||||
// Pfad wie bei deinen JSONs: /public/assets/i18n/de.json etc.
|
||||
const assetsBase = cfg.assetsBase || "/assets";
|
||||
const url = assetsBase.replace(/\/+$/, "") + "/i18n/" + usbcheck.locale + ".json";
|
||||
|
||||
fetch(url)
|
||||
.then(res => {
|
||||
if (!res.ok) throw new Error("HTTP " + res.status);
|
||||
return res.json();
|
||||
})
|
||||
.then(data => {
|
||||
usbcheck.i18n = data || {};
|
||||
// console.debug("usbcheck i18n loaded:", usbcheck.locale, usbcheck.i18n);
|
||||
})
|
||||
.catch(err => {
|
||||
console.warn("usbcheck i18n konnte nicht geladen werden:", err);
|
||||
usbcheck.i18n = {};
|
||||
});
|
||||
}
|
||||
|
||||
// Key-Lookup: "fake_ui.status_ready"
|
||||
usbcheck.t = function t(key, fallback) {
|
||||
if (!key) return (fallback != null ? fallback : "");
|
||||
const parts = String(key).split(".");
|
||||
let cur = usbcheck.i18n;
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
const p = parts[i];
|
||||
if (!cur || typeof cur !== "object" || !(p in cur)) {
|
||||
return (fallback != null ? fallback : key);
|
||||
}
|
||||
cur = cur[p];
|
||||
}
|
||||
if (cur == null) return (fallback != null ? fallback : key);
|
||||
return cur;
|
||||
};
|
||||
|
||||
// Format-Variante mit Platzhaltern {name}, {mode}, {size}, ...
|
||||
usbcheck.tFmt = function tFmt(key, fallback, vars) {
|
||||
let str = usbcheck.t(key, fallback);
|
||||
if (!vars) return str;
|
||||
for (const k in vars) {
|
||||
if (!Object.prototype.hasOwnProperty.call(vars, k)) continue;
|
||||
const re = new RegExp("\\{" + k.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&") + "\\}", "g");
|
||||
str = str.replace(re, vars[k]);
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
// direkt beim Laden JSON holen
|
||||
loadI18n();
|
||||
|
||||
|
||||
// ---------- Hilfsfunktionen ----------
|
||||
usbcheck.log = function logLine(message, level = "info") {
|
||||
|
||||
@@ -1,25 +1,178 @@
|
||||
// /public/assets/js/fakecheck.js
|
||||
// /public/assets/js/fakecheck/fakecheck.serial.js
|
||||
|
||||
(function() {
|
||||
const base = "/assets/js/fakecheck/";
|
||||
(function () {
|
||||
if (!window.usbcheck) return;
|
||||
|
||||
const scripts = [
|
||||
base + "core.js?v=1",
|
||||
base + "fakecheck.browser.js?v=1",
|
||||
base + "fakecheck.serial.js?v=1"
|
||||
];
|
||||
const {
|
||||
cfg,
|
||||
t,
|
||||
tFmt,
|
||||
log: logLine
|
||||
} = window.usbcheck;
|
||||
|
||||
function loadScript(src) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const s = document.createElement("script");
|
||||
s.src = src;
|
||||
s.async = false; // Reihenfolge sicherstellen
|
||||
s.onload = resolve;
|
||||
s.onerror = () => reject(new Error("Konnte " + src + " nicht laden"));
|
||||
document.head.appendChild(s);
|
||||
});
|
||||
const rootSc = document.getElementById("serialcheck-root");
|
||||
if (!rootSc) return; // Partial nicht eingebunden → nichts tun
|
||||
|
||||
// Elemente
|
||||
const form = rootSc.querySelector("#serialcheck-form");
|
||||
const errorBox = rootSc.querySelector("#serialcheck-error");
|
||||
const resultBox = rootSc.querySelector("#serialcheck-result");
|
||||
|
||||
const manufacturerInput = rootSc.querySelector("#sc-manufacturer");
|
||||
const vidInput = rootSc.querySelector("#sc-vid");
|
||||
const pidInput = rootSc.querySelector("#sc-pid");
|
||||
const serialInput = rootSc.querySelector("#sc-serial");
|
||||
|
||||
const apiUrl = cfg.apiBase.replace(/\/+$/, "") + "/quickcheck";
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Fehleranzeige
|
||||
// -------------------------------------------------------
|
||||
function showScError(msgKey, fallback, vars = {}) {
|
||||
if (!errorBox) return;
|
||||
const msg = tFmt(msgKey, fallback, vars);
|
||||
errorBox.textContent = msg;
|
||||
errorBox.classList.remove("hidden");
|
||||
if (resultBox) resultBox.classList.add("hidden");
|
||||
}
|
||||
|
||||
scripts.reduce((p, src) => p.then(() => loadScript(src)), Promise.resolve())
|
||||
.catch(err => console.error("Fakecheck Loader Fehler:", err));
|
||||
function clearScError() {
|
||||
if (!errorBox) return;
|
||||
errorBox.classList.add("hidden");
|
||||
errorBox.textContent = "";
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Ergebnis rendern
|
||||
// -------------------------------------------------------
|
||||
function renderScResult(data) {
|
||||
if (!resultBox) return;
|
||||
|
||||
clearScError();
|
||||
resultBox.classList.remove("hidden");
|
||||
|
||||
const rating = data.rating || "unknown";
|
||||
const input = data.input || {};
|
||||
const vendorInfo = data.vendor_detected || {};
|
||||
const serialInfo = data.serial_analysis || {};
|
||||
const consistency = data.consistency || {};
|
||||
|
||||
// Rating → Label + Beschreibung
|
||||
const ratingLabel = t(`serial.rating.${rating}.label`, rating);
|
||||
const ratingDesc = t(`serial.rating.${rating}.desc`, "");
|
||||
|
||||
// Auffälligkeiten
|
||||
const issues = serialInfo.issues || [];
|
||||
const issuesHtml = issues.length
|
||||
? '<ul class="list-disc list-inside mt-1">' +
|
||||
issues.map(i => `<li>${i}</li>`).join("") +
|
||||
'</ul>'
|
||||
: `<span class="text-emerald-600 text-[11px]">${t("serial.issues_none", "Keine besonderen Auffälligkeiten.")}</span>`;
|
||||
|
||||
// Vendor
|
||||
const vendorLine = vendorInfo.found
|
||||
? tFmt("serial.vendor_detected", "{vendor} (VID {vid})", {
|
||||
vendor: vendorInfo.vendor,
|
||||
vid: vendorInfo.vid
|
||||
})
|
||||
: vendorInfo.vid
|
||||
? tFmt("serial.vendor_unknown", "Unbekannter Hersteller für VID {vid}", { vid: vendorInfo.vid })
|
||||
: t("serial.vendor_none", "Keine Vendor-ID angegeben");
|
||||
|
||||
// Konsistenz-Notizen
|
||||
const notes = consistency.notes || [];
|
||||
const notesHtml = notes.length
|
||||
? '<ul class="list-disc list-inside mt-1 text-[11px]">' +
|
||||
notes.map(n => `<li>${n}</li>`).join("") +
|
||||
'</ul>'
|
||||
: "";
|
||||
|
||||
// HTML einsetzen
|
||||
resultBox.innerHTML = `
|
||||
<div class="mb-3">
|
||||
<span class="inline-flex items-center rounded-full px-3 py-1 text-[11px] font-semibold
|
||||
${rating === "ok" ? "bg-emerald-100 text-emerald-800" : ""}
|
||||
${rating === "needs_review" ? "bg-amber-100 text-amber-800" : ""}
|
||||
${rating === "suspicious" ? "bg-red-100 text-red-800" : ""}
|
||||
${rating === "invalid" ? "bg-slate-100 text-slate-700" : ""}
|
||||
">
|
||||
${t("serial.rating_label", "Bewertung")}: ${ratingLabel}
|
||||
</span>
|
||||
<p class="mt-1 text-xs text-slate-600 dark:text-slate-300">${ratingDesc}</p>
|
||||
</div>
|
||||
|
||||
<div class="border border-slate-200 dark:border-slate-700 rounded-xl p-3 mb-3">
|
||||
<h3 class="text-xs font-semibold mb-1">${t("serial.heading_input", "Eingabedaten")}</h3>
|
||||
<dl class="text-[11px] space-y-1 text-slate-600 dark:text-slate-300">
|
||||
<div><dt class="font-medium">${t("serial.input.manufacturer", "Hersteller (Angabe):")}</dt><dd>${input.manufacturer || '<span class="text-slate-400">' + t("serial.none", "keine Angabe") + '</span>'}</dd></div>
|
||||
<div><dt class="font-medium">${t("serial.input.vidpid", "VID/PID:")}</dt><dd>${(input.vid || "–") + " / " + (input.pid || "–")}</dd></div>
|
||||
<div><dt class="font-medium">${t("serial.input.vendor_detected", "Vendor aus VID:")}</dt><dd>${vendorLine}</dd></div>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="border border-slate-200 dark:border-slate-700 rounded-xl p-3 mb-3">
|
||||
<h3 class="text-xs font-semibold mb-1">${t("serial.heading_analysis", "Seriennummer-Analyse")}</h3>
|
||||
<dl class="text-[11px] space-y-1 text-slate-600 dark:text-slate-300">
|
||||
<div><dt class="font-medium">${t("serial.analysis.serial", "Seriennummer:")}</dt><dd><code class="text-[10px] bg-slate-100 dark:bg-slate-800 px-1.5 py-0.5 rounded">${serialInfo.serial || ""}</code></dd></div>
|
||||
<div><dt class="font-medium">${t("serial.analysis.length", "Länge:")}</dt><dd>${serialInfo.length || 0} ${t("serial.chars", "Zeichen")}</dd></div>
|
||||
<div><dt class="font-medium">${t("serial.analysis.category", "Kategorie:")}</dt><dd>${serialInfo.category || "-"}</dd></div>
|
||||
<div><dt class="font-medium">${t("serial.analysis.score", "Score:")}</dt><dd>${typeof serialInfo.score === "number" ? serialInfo.score : "-"} / 100</dd></div>
|
||||
<div><dt class="font-medium">${t("serial.analysis.issues", "Auffälligkeiten:")}</dt><dd>${issuesHtml}</dd></div>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="border border-slate-200 dark:border-slate-700 rounded-xl p-3">
|
||||
<h3 class="text-xs font-semibold mb-1">${t("serial.heading_consistency", "Hersteller-Konsistenz")}</h3>
|
||||
${notesHtml}
|
||||
<p class="mt-2 text-[10px] text-slate-500">
|
||||
${t("serial.disclaimer", "Diese Einschätzung basiert auf Heuristiken und kann keine Echtheit garantieren.")}
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
// Submit-Handler
|
||||
// -------------------------------------------------------
|
||||
if (!form) return;
|
||||
|
||||
form.addEventListener("submit", (e) => {
|
||||
e.preventDefault();
|
||||
clearScError();
|
||||
if (resultBox) resultBox.classList.add("hidden");
|
||||
|
||||
const payload = {
|
||||
manufacturer: manufacturerInput ? manufacturerInput.value.trim() : "",
|
||||
vid: vidInput ? vidInput.value.trim() : "",
|
||||
pid: pidInput ? pidInput.value.trim() : "",
|
||||
serial: serialInput ? serialInput.value.trim() : ""
|
||||
};
|
||||
|
||||
if (!payload.serial) {
|
||||
showScError("serial.error.no_serial", "Bitte gib eine Seriennummer ein.");
|
||||
return;
|
||||
}
|
||||
|
||||
fetch(apiUrl, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(payload)
|
||||
})
|
||||
.then(res => {
|
||||
if (!res.ok) {
|
||||
throw new Error("HTTP " + res.status);
|
||||
}
|
||||
return res.json();
|
||||
})
|
||||
.then(data => {
|
||||
if (!data || !data.success) {
|
||||
throw new Error((data && data.error) || t("serial.error.unknown", "Unerwartete Antwort vom Server."));
|
||||
}
|
||||
renderScResult(data);
|
||||
})
|
||||
.catch(err => {
|
||||
showScError("serial.error.api", "Fehler bei der Prüfung: {msg}", { msg: err.message });
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
$pageKey = 'landing';
|
||||
require __DIR__ . "/../config/fileload.php";
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
// public/dashboard/index.php
|
||||
|
||||
$pageKey = 'dashboard';
|
||||
require __DIR__ . '/../../../config/fileload.php';
|
||||
|
||||
// Sprachlogik
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
$pageKey = 'fakecheck';
|
||||
require __DIR__ . "/../../../config/fileload.php";
|
||||
|
||||
// public/fakecheck/index.php
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
$pageKey = 'login';
|
||||
require __DIR__ . "/../../../config/fileload.php";
|
||||
|
||||
tpl_add_script('/assets/js/auth.js', 'footer', true, false, '', 'auth-1');
|
||||
|
||||
@@ -135,6 +135,7 @@ function tpl(string $file, string $type = 'structure', string $site = 'main'): v
|
||||
*
|
||||
* @param string $type z.B. 'success', 'error', 'info', 'warning'
|
||||
* @param string $message Die Meldung für den Nutzer
|
||||
* @param string|null $context Optionaler Kontext (z.B. 'login', 'register')
|
||||
*/
|
||||
function flash_set(string $type, string $message, ?string $context = null): void
|
||||
{
|
||||
@@ -152,7 +153,7 @@ function flash_set(string $type, string $message, ?string $context = null): void
|
||||
/**
|
||||
* Flash-Meldung holen und direkt löschen (Einmal-Anzeige).
|
||||
*
|
||||
* @return array|null ['type' => 'success|error|info|warning', 'message' => '...']
|
||||
* @return array|null ['type' => 'success|error|info|warning', 'message' => '...', 'context' => '...']
|
||||
*/
|
||||
function flash_get(): ?array
|
||||
{
|
||||
@@ -173,3 +174,103 @@ function flash_get(): ?array
|
||||
|
||||
return $flash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interne Helper-Funktion: traversiert ein Array mit "dot notation"-Segmenten.
|
||||
*
|
||||
* @param array $data
|
||||
* @param string $key z.B. 'pages.landing.meta.title'
|
||||
* @return mixed|null
|
||||
*/
|
||||
function _i18n_traverse_array(array $data, string $key)
|
||||
{
|
||||
$segments = explode('.', $key);
|
||||
$node = $data;
|
||||
|
||||
foreach ($segments as $seg) {
|
||||
if (!is_array($node) || !array_key_exists($seg, $node)) {
|
||||
return null;
|
||||
}
|
||||
$node = $node[$seg];
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zentrale Funktion zum Laden eines i18n-Strings mit Fallback.
|
||||
*
|
||||
* - greift zuerst auf $GLOBALS['i18n']['current'] zu
|
||||
* - dann auf $GLOBALS['i18n']['fallback']
|
||||
* - unterstützt Platzhalter {key} und {{key}}
|
||||
* - eingebaute Platzhalter:
|
||||
* {year}
|
||||
* {{primary_domain}}
|
||||
* {{primary_url}}
|
||||
*
|
||||
* @param string $path z.B. 'pages.login.meta.title'
|
||||
* @param mixed $default Fallback, falls nichts gefunden wird
|
||||
* @param array $replacements ['name' => 'Lars']
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function i18n_get(string $path, $default = null, array $replacements = []): string
|
||||
{
|
||||
if (!isset($GLOBALS['i18n']) || !is_array($GLOBALS['i18n'])) {
|
||||
return $default !== null ? (string)$default : '';
|
||||
}
|
||||
|
||||
$current = $GLOBALS['i18n']['current'] ?? [];
|
||||
$fallback = $GLOBALS['i18n']['fallback'] ?? [];
|
||||
|
||||
// zuerst in der aktiven Sprache suchen
|
||||
$value = _i18n_traverse_array($current, $path);
|
||||
|
||||
// wenn dort nichts → Fallback-Sprache
|
||||
if ($value === null && !empty($fallback)) {
|
||||
$value = _i18n_traverse_array($fallback, $path);
|
||||
}
|
||||
|
||||
if (!is_string($value)) {
|
||||
return $default !== null ? (string)$default : '';
|
||||
}
|
||||
|
||||
$text = $value;
|
||||
|
||||
// eingebaute Platzhalter
|
||||
$builtIn = [
|
||||
'{year}' => date('Y'),
|
||||
'{{primary_domain}}' => function_exists('app_primary_domain') ? app_primary_domain() : '',
|
||||
'{{primary_url}}' => function_exists('app_primary_url') ? app_primary_url() : '',
|
||||
];
|
||||
|
||||
foreach ($builtIn as $ph => $val) {
|
||||
$text = str_replace($ph, $val, $text);
|
||||
}
|
||||
|
||||
// zusätzliche Platzhalter aus $replacements
|
||||
foreach ($replacements as $key => $val) {
|
||||
$val = (string)$val;
|
||||
// Variante {key}
|
||||
$text = str_replace('{' . $key . '}', $val, $text);
|
||||
// Variante {{key}}
|
||||
$text = str_replace('{{' . $key . '}}', $val, $text);
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience-Wrapper für i18n_get, etwas "kürzer" zu tippen
|
||||
* und vom bisherigen Code kompatibel genutzt.
|
||||
*
|
||||
* Beispiel:
|
||||
* i18n_get_fmt('fake_ui.log_capacity_probe_result', 'Fallback', ['size' => '2 GB']);
|
||||
*/
|
||||
function i18n_get_fmt(string $path, $default = '', array $vars = []): string
|
||||
{
|
||||
// Falls $default explizit null ist → leere String als Basis
|
||||
$def = $default ?? '';
|
||||
|
||||
return i18n_get($path, $def, $vars);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user