Commit Graph

82 Commits

Author SHA1 Message Date
eda6821632 i18n: fix missing keys and translate all non-admin frontend strings
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m43s
- Add 12 missing i18n keys (t() was returning the literal key string) to
  all 13 locales: dashboard.topbar.premiumAccess,
  dashboard.translate.complete.toastOkDesc,
  dashboard.translate.progress.{connectionLost,processingFallback},
  glossaries.card.{term,created}, glossaries.termEditor.{addTerm,maxReached},
  login.google.{connecting,errorFailed,errorGeneric}, login.orContinueWith
- Add 6 FR-drift keys (landing.pricing.{free,enterprise}.{name,desc,cta})
- Add ~120 new i18n keys covering site header/footer, file-uploader,
  checkout success, dashboard pages, translate page, provider selector
  themes, language selector, translation complete, api-keys, services,
  settings, pricing (~1800 new key/locale pairs)
- Wrap hardcoded French/English in components with t() calls
- Convert LLM_THEMES/CLASSIC_THEMES/FALLBACK_PROVIDERS maps from
  hardcoded constants to t()-driven factories
- Admin pages intentionally left untouched per request

Files: 15 components/pages + src/lib/i18n.tsx
Typecheck: passes (tsc --noEmit exit 0)
2026-06-14 12:45:12 +02:00
9b0b2ae6f9 docs: remove remaining Claude 3.5 references and display page credit costs in translation provider selector
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m11s
2026-06-14 11:41:47 +02:00
c7506e6aca fix: resolve critical security and UI session mismatch by clearing React Query cache on login/logout and invalidating on subscription updates
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m24s
2026-06-14 11:15:09 +02:00
136d40c7d8 feat: update to June 2026 models (Claude Sonnet 4.6, Gemini 3.5 Flash), add glossary button, and implement cost factor quota & vision fallback
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m4s
2026-06-14 11:05:53 +02:00
feea02033b fix: resolve Google login hydration mismatch and dynamic env load
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m42s
2026-06-07 12:21:06 +02:00
Sepehr
fb6740f333 fix(glossaries): correct source/target display mapping (FR=source, EN=target, others=translations[lang])
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m55s
Avant : getDisplaySource(term, 'en') lisait term.translations.en
(qui n'existe pas) puis fallback sur term.source = francais.
C'est ce qui affichait du francais et du néerlandais au mauvais endroit.

Apres : le mapping reflete la structure reelle des donnees :
- FR (lang='fr') → term.source
- EN (lang='en') → term.target
- autres (de, es, it, pt, nl, ru, ja, ko, zh, ar, fa)
  → term.translations[lang]
- si manquant → '' (placeholder, JAMAIS une autre langue en fallback)

Memes regles pour getDisplayTarget, inversees (defaut = target).

Edition (handleTermChange) ecrit au bon endroit :
- FR → term.source
- EN (ou multi) → term.target
- autres → translations[lang]

Le remap automatique de term.target au changement de targetLanguage
est supprime (lecture a la volee maintenant, plus besoin de modifier
l'etat des termes).

Aucun changement de donnees, aucun changement backend, aucun
changement de schema. Fix purement frontend.
2026-06-07 10:59:57 +02:00
Sepehr
79848230c0 fix(glossaries): restore selectable source language (data was already there)
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m37s
Revert du commit e11a6b1 : la langue source doit etre selectionnable
(car l'utilisateur peut vouloir traduire depuis n'importe quelle
des 12 langues supportees, pas seulement le francais).

Le data modele support deja le cas : chaque terme a un champ
\	ranslations\ (dict de 11 langues) qui contient la traduction du
terme source. Donc pour traduire depuis l'italien, on lit
\	erm.translations.it\ comme source, et \	erm.translations.es\
comme cible si la cible est l'espagnol.

Changements :
- Le combobox 'Langue source' est restaure (12 langues)
- Nouvelle fonction \getDisplaySource(term, lang)\ :
  * 'fr' ou 'multi' → term.source (le francais original)
  * autre → term.translations[lang] (la traduction dans la langue)
  * fallback → term.source si la traduction manque
- handleTermChange ecrit au bon endroit selon la langue :
  * source FR → term.source
  * autre source → term.translations[sourceLanguage]
  * target 'multi'/'en' → term.target
  * autre target → term.translations[targetLanguage]
- hasUnsavedChanges compare aussi le dict translations (avant
  il ne comparait que source|target, donc un edit dans une autre
  langue ne declenchait pas l'alerte 'non enregistre')
- Note sous le combobox source explique la regle
  (FR = source originale, autre = champ translations)
- i18n : nouvelle cle \glossaries.detail.sourceLangNote\
  ajoutee aux 13 locales (FR + EN traduit)

L'utilisateur peut maintenant choisir 'Italien' comme source et
'Espagnol' comme cible, et voir les termes correspondants.
2026-06-07 10:11:19 +02:00
Sepehr
e11a6b16a0 fix(glossaries): source language combobox was a lie — replace with fixed FR label
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m32s
Les templates data/glossaires/*.json ne stockent les termes sources
qu'en francais. Le combobox 'Langue source' laissait l'utilisateur
croire qu'il pouvait traduire depuis une autre langue, mais le
backend renverrait toujours des termes en francais.

Fix : remplacer le select par un label fixe 'Francais' avec un badge
'fixe' et une note explicative indiquant que le multilingue source
est sur la roadmap.

Le select 'Langue cible' reste : il determine quelle traduction du
terme est affichee dans la colonne 'Cible' (FR+10 langues via le
champ translations).
2026-06-07 09:58:16 +02:00
Sepehr
e497f2d218 refactor(glossaries): single source of truth + dedicated detail page
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m15s
UX refonte :
- Retire la section 'Glossaires professionnels' de la vue principale
  (les 8 cartes de templates sont maintenant dans le dialog de creation)
- Cartes 'Vos glossaires' plus simples : nom, langues, termes, date
  - Cliquer sur la carte navigue vers /dashboard/glossaries/[id]
  - Plus de boutons Edit/Delete sur la carte (deplaces dans la page detail)
- Recherche par nom (visible si > 3 glossaires)
- Badge 'Non enregistre' si modifications non sauvegardees

Nouvelle page /dashboard/glossaries/[id] :
- Edition inline du nom (input), langues source/cible (select)
- Tableau des termes avec recherche et edition en place
- Ajout/suppression de termes (max 500)
- Export / Import CSV (meme logique que l'edit dialog)
- Zone danger : confirmation en 2 temps pour la suppression
- Back link vers la liste
- i18n : 40 nouvelles cles ajoutees aux 13 locales (FR + EN traduit,
  les autres utilisent le fallback EN)

Design preserve : editorial-card, brand-accent, meme typographie,
meme palette. Refactor structurel uniquement, pas de restyling.

Le system prompt (Instructions de contexte) reste tel quel, au-dessus
de la liste des glossaires, comme dans le design actuel.
2026-06-07 09:38:19 +02:00
818eac5490 feat: prevent duplicate glossary presets + fix i18n source warning bug
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m5s
- Add template_id column to Glossary model (nullable, indexed)
- Backend: return 409 Conflict if user already imported a template
- Frontend: disable preset cards already imported, show 'Imported' badge
- Fix duplicated text in GlossarySelector source warning (hardcoded FR text removed)
- Complete i18n migration for glossaries page and GlossarySelector
- Add glossaries.presets.alreadyImported key in all 13 locales
2026-06-01 23:39:53 +02:00
ce53f0df16 fix(admin): resolve hydration layout crash by removing layout-level return null and using mount-conditional text
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m5s
2026-06-01 23:24:03 +02:00
6da8a85b1d fix(admin): secure routes, add real IP detection, SMTP header validation, and fix Next.js layout hydration mismatch
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m5s
2026-06-01 23:16:03 +02:00
6d27dc4cda feat(i18n): Phase 1 — migrate 5 critical files from hardcoded text to i18n
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m51s
47 new i18n keys added across all 13 locales (en, fr, es, de, pt, it,
nl, ru, ja, ko, zh, ar, fa). English and French are fully translated,
remaining locales use French as placeholder.

Files migrated:
- EditGlossaryDialog.tsx (18 strings)
- DeleteGlossaryDialog.tsx (7 strings)
- ProUpgradePrompt.tsx (10 strings)
- WebhookSnippet.tsx (4 strings)
- TranslationModeToggle.tsx (8 strings)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 00:28:24 +02:00
c82e70681f fix: edit dialog remaps terms when target language changes
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m20s
When the user changes the target language dropdown in the edit dialog,
terms now remap to show the language-specific translation from the
translations dict. E.g. changing to Spanish shows 'servidor' instead
of 'server'. Falls back to default English if no translation exists.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 00:08:27 +02:00
0efdf6a3f4 feat: add source/target language selectors to edit glossary dialog
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m24s
Users can now change the language pair when editing a glossary:
- EditGlossaryDialog has source/target language dropdowns
- Default target_language changed from 'en' to 'multi' in create dialog
- onSave passes source_language and target_language to the backend
- Backend PATCH endpoint already supports updating these fields

Also fixes:
- CreateGlossaryDialog defaults to 'multi' instead of 'en'
- SUPPORTED_LANGUAGES now includes 'multi' option for target

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 00:03:22 +02:00
9ab166c31e fix: glossaries page support for multilingual (target_language='multi')
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m58s
The /dashboard/glossaries page had two issues:
1. SUPPORTED_LANGUAGES had no 'multi' code, so multilingual glossaries
   showed '🌐 undefined' instead of '🌐 Multilingue'
2. The Compatible/Autre cible badge compared target_language directly
   with currentTargetLang, so 'multi' never matched → always showed
   'Autre cible'. Now 'multi' is treated as compatible with any target.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 23:48:48 +02:00
e9ac30ed1d style: use same serif/typography font styles on profile page as translate page
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m47s
2026-05-31 23:33:32 +02:00
b4096fd2ca fix: show target-language-specific translations in preview + rename migration
Some checks failed
Deploy to Production / Build and Deploy (push) Has been cancelled
Two issues found in screenshot review:
1. Glossary preview always showed English 'target' field (foie → liver)
   instead of the language-specific translation. Now looks up
   term.translations[targetLang] first, falls back to term.target.
   When target is Persian, preview shows 'foie → کبد' (Persian).

2. Previous migration b7c8d9e0f1a2 was already applied on server before
   the rename was added. New migration c8d9e0f1a2b3 handles the rename
   separately: glossaries with target_language='multi' get their name
   changed from 'Anglais' to 'Multilingue'.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 23:22:50 +02:00
a79ce0fc9b fix: comprehensive glossary system audit — 6 critical fixes
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m27s
Full audit found 18 issues across backend, frontend, and data files.
Root cause: target_language had no single source of truth — 'en' was
hardcoded as default in 6+ places while templates are actually multilingual.

Fixes applied:
- routes/glossary_routes.py: list_glossaries() fallback 'en' → 'multi'
- routes/glossary_routes.py: import reads target_lang from index.json
  (source of truth) instead of template file
- data/glossaries/*.json: all 8 template files target_lang 'en' → 'multi'
- services/glossary_service.py: get_glossary_terms() now returns
  target_language field (was missing entirely)
- schemas/glossary_schemas.py: all defaults 'en' → 'multi'
  (GlossaryCreate, GlossaryResponse, GlossaryListItem)
- useTranslationConfig.ts: only reset glossary on sourceLang change,
  not targetLang (multilingual glossaries work with any target)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 23:14:41 +02:00
2386e94c6d fix: page /checkout/success qui auto-sync le plan apres paiement Stripe (success_url corrige)
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 3m5s
2026-05-31 23:05:01 +02:00
ab296ea259 fix: Stripe billing portal auto-config programmatique, separation changer-forfait vs gerer-facturation
Some checks failed
Deploy to Production / Build and Deploy (push) Has been cancelled
2026-05-31 22:45:45 +02:00
00c54997bf fix: sync plan+tier after checkout, portal same-tab nav, cancel button always visible for paid plans, portal return URL to profile tab
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m44s
2026-05-31 22:37:51 +02:00
c66252bed4 feat: mark glossary templates as multilingual — support 11 target languages
Some checks failed
Deploy to Production / Build and Deploy (push) Failing after 1m30s
Templates enriched by enrich_glossary_templates.py already contain
translations for de, es, it, pt, nl, ru, ja, ko, zh, ar, fa (including
Persian). But they were labeled FR→EN, causing incorrect filtering and
warnings when translating to other languages.

Changes:
- index.json: set target_lang='multi' for all 8 templates
- GlossarySelector: treat target_language='multi' as compatible with
  any target language (no false warnings, auto-select works)
- GlossarySelector: display '🌐 MULTILINGUE' badge instead of EN flag
- glossary_routes: default target_language to 'multi' instead of 'en'
- Migration: detect existing multilingual glossaries in DB (5+ keys in
  translations JSON) and set their target_language to 'multi'

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 22:32:27 +02:00
ad8ac089a4 fix: don't auto-select glossary when no target language match
When activating the glossary toggle, only auto-select a glossary if it
matches BOTH source and target language. If no matching glossary exists
(e.g. translating to Persian but only have FR→EN glossaries), leave the
selector empty so the user picks manually instead of forcing an
incompatible glossary.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 22:22:05 +02:00
5122bfdf99 fix: glossary selection respects target language — sort by source+target, reset on lang change, fix template import
Some checks failed
Deploy to Production / Build and Deploy (push) Has been cancelled
- GlossarySelector: filteredGlossaries now sorts matching target_language
  first so FR→FA appears before FR→EN when translating to Persian
- GlossarySelector: toggle auto-select prefers glossary matching
  targetLang, falls back to first available
- useTranslationConfig: reset glossaryId when targetLang changes (was
  only resetting on sourceLang change)
- glossary_routes: set target_language from template data on import
  (was missing, defaulted to None/en)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 22:00:40 +02:00
89c31f8298 fix: safe JSON parse in checkout handlers, show proper error on 500
Some checks failed
Deploy to Production / Build and Deploy (push) Failing after 1m32s
2026-05-31 21:59:18 +02:00
fbe39d81e1 fix: align landing page prices with backend, pass billing mode in URL to /pricing
Some checks failed
Deploy to Production / Build and Deploy (push) Failing after 1m50s
2026-05-31 21:54:15 +02:00
374c605027 feat: Stripe integration complete - products created, DB migration, payment_failed handler, credit buttons wired
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m5s
- Create Stripe products/prices (Starter/Pro/Business monthly+yearly)
- Fix CRITICAL bug: add subscription_ends_at + cancel_at_period_end columns to users table
- Alembic migration: f6a7b8c9d0e1_add_subscription_ends_at_cancel_at_period_end
- Fix: implement handle_payment_failed() to set subscription_status=PAST_DUE
- Fix: harmonize .env.production Stripe variable names to match pricing_config.py
- Fix: add missing FRONTEND_URL and STRIPE_PUBLISHABLE_KEY to .env.production
- Add all Stripe Price IDs (test mode) to .env.production
- Wire credit purchase buttons to /api/v1/auth/create-credits-checkout
- Dashboard sync post-checkout was already implemented (no change needed)

Stripe test keys: configured in .env.production
Webhook: must be configured on server via stripe CLI or Stripe Dashboard
Webhook URL: https://wordly.art/api/v1/auth/webhook/stripe
2026-05-31 21:40:31 +02:00
3a9de12f26 fix: glossary cards UX - boutons clairs, badge compatible/incompatible, alerte cible dans sidebar
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m39s
2026-05-31 13:46:13 +02:00
d657b65adb fix: FORMAT NATIF hors cadre, apercu glossaire toujours FR/IR, prompt juridique par defaut
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m32s
2026-05-31 13:29:12 +02:00
85cd5456f8 feat(glossaries): add target_language support - DB migration, API, and UI language pair display
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m52s
2026-05-31 13:25:12 +02:00
fecb3f7abb ux(glossaries): add how-it-works guide, status badges and activation hints
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m41s
2026-05-31 13:02:19 +02:00
6d800b1077 design(frontend): align glossaries page typography with translation page editorial style
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m44s
2026-05-31 11:36:55 +02:00
f33da82c29 fix(frontend): improve glossary selector responsiveness and add contextual warning logic
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 3m10s
2026-05-31 11:24:52 +02:00
58d9d8a74c fix(frontend): increase translation config legibility and integrate templates in glossary selector
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m31s
2026-05-31 11:18:57 +02:00
3f635e809e feat(translate): implement intelligent language filtering and creation links for glossaries
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m34s
2026-05-31 11:09:56 +02:00
8ab45f1b6e style(translate): make LLM cards compact in a 3-column grid, remove glossary language filtering, and add contextual help under engine selection
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m58s
2026-05-31 11:05:34 +02:00
cd8a57324d style(translate): redesign glossary and translate images card layout to match mockup compact styling
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m31s
2026-05-31 10:58:22 +02:00
78eca6d453 feat(translate): refonte complete du composant GlossarySelector (Etape 4)
Some checks failed
Deploy to Production / Build and Deploy (push) Has been cancelled
2026-05-31 10:33:57 +02:00
a0de00a4e7 fix(translate): ajout des cles de traduction manquantes et re-positionnement intelligent du bouton de traduction
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m41s
2026-05-31 10:28:12 +02:00
c1ea65f10f feat(translate): refonte du design de la page de traduction et du sélecteur de moteurs (Etapes 1-3)
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m12s
2026-05-31 10:14:23 +02:00
9532fef2cd fix: remove DeepSeek/MiniMax branding, fix glossary visibility, improve translate page UX
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m7s
- US1: Replace exposed provider names (DeepSeek V3 → IA Express, MiniMax → IA Avancée)
  in legacy_routes.py, remove 52 DeepSeek references from i18n pricing/landing keys,
  add generic modelName key across all 13 languages
- US2: Fix glossary selector filtering (fallback to all glossaries when source lang
  filter returns empty), show templates by default, fix 3 broken presets
  (hvac/construction/automotive → hr/scientific/ecommerce)
- US3: Replace 15 hardcoded French strings with i18n t() calls, increase font sizes
  from 8-9px to 11px, improve text contrast (opacity /20→/40, /25→/45, /30→/50)
- US4: Add missing provider labels in admin ProviderStatus (deepseek, minimax, zai,
  google_cloud, openrouter, openrouter_premium)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 08:24:33 +02:00
b472dcd4b7 style: apply Inter + Playfair Display fonts matching reference landing page
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m16s
- Add Playfair Display as serif font via next/font/google
- Hero headings: font-serif font-medium tracking-tight (was font-extrabold uppercase)
- Body text: font-light (was font-medium)
- Section headings: font-serif tracking-tight (was heavy sans-serif)
- Pricing titles: font-serif font-medium (was font-black uppercase)
- CTA button: rounded-[32px] larger pill style
- Overall softer, more editorial feel matching architectural-grid reference

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 13:45:44 +02:00
03cf4cd276 fix: show current language flag instead of next language in landing page button
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m24s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 13:36:58 +02:00
bacbf6cce8 fix: compact glossary dropdown, sticky translate button, and mode badge
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m10s
- Restructure right sidebar as flex-col with scrollable config and
  fixed translate button (never scrolls away)
- Replace expanded GlossarySelector list with compact dropdown (~80px
  instead of ~400px), collapsible templates section, click-outside close
- Add visible Classic/IA mode badge after provider selector with hint
  about glossary availability for Pro users in classic mode

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 21:41:16 +02:00
e41dca6fe3 fix: cache headers and frontend pro tier resolution
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m34s
2026-05-17 20:06:26 +02:00
669cf7fde8 fix(ui): critical translation workflow improvements
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2s
- Extracted Translate button to sticky bottom wrapper (always visible)
- Added humanFriendlyError mapper for readable error messages
- Added 'Réessayer' and 'Nouveau fichier' buttons to FAILED state
- Hid GlossarySelector for non-Pro users
- Fixed silent failure: attempted=0 now fails explicitly
2026-05-17 16:54:59 +02:00
3e41bee470 fix: remove Ollama from all default fallback chains - cloud-only defaults
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2s
2026-05-17 16:43:17 +02:00
3eb418e7ec fix: send template_id as query param (not JSON body) for glossary import
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m19s
The backend expects template_id as a Query parameter, but the frontend
was sending it as a JSON body — causing validation error on every click.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 01:14:54 +02:00
6ba39cc01b fix: glossary selector — clear selected state, error feedback, click existing templates to select
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 1m33s
- Round check icon on selected glossary (unmissable)
- Error banner when import fails (no more silent spinner)
- Click template that already exists = select it (no re-import)
- Single fetch for glossaries + templates (faster load)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 01:11:18 +02:00