diff --git a/css/style.css b/css/style.css
index 91f23cc..3fc2f31 100644
--- a/css/style.css
+++ b/css/style.css
@@ -3798,7 +3798,9 @@ a.ms1-trad-link.btn-aide-trad{
.inscr-gestion-list-head{
display:flex;
justify-content:space-between;
- align-items:center;
+ align-items:flex-start;
+ gap:10px 16px;
+ flex-wrap:wrap;
font-size:13px;
font-weight:600;
color:#004085;
@@ -3810,9 +3812,46 @@ a.ms1-trad-link.btn-aide-trad{
border-radius:6px;
}
+.inscr-gestion-list-head__main{
+ display:flex;
+ flex-wrap:wrap;
+ align-items:center;
+ gap:6px 8px;
+ min-width:0;
+ flex:1 1 12rem;
+}
+
+.inscr-gestion-list-head__count{
+ white-space:nowrap;
+}
+
+.inscr-gestion-list-head__filters{
+ display:inline-flex;
+ flex-wrap:wrap;
+ gap:4px 6px;
+ align-items:center;
+ font-weight:500;
+}
+
+.inscr-gestion-list-head__chip{
+ display:inline-block;
+ max-width:100%;
+ padding:2px 8px;
+ border-radius:999px;
+ background:#fff;
+ border:1px solid #b8d0ef;
+ color:#1a4a7a;
+ font-size:12px;
+ font-weight:500;
+ line-height:1.35;
+ word-break:break-word;
+}
+
.inscr-gestion-list-head__pg{
font-weight:500;
color:#6c757d;
+ white-space:nowrap;
+ margin-left:auto;
}
.inscr-gestion-list{
diff --git a/js/v2/inscr-gestion.js b/js/v2/inscr-gestion.js
index 2ab1fb7..cb01d1c 100644
--- a/js/v2/inscr-gestion.js
+++ b/js/v2/inscr-gestion.js
@@ -802,17 +802,27 @@
// soit le prefixe (inscr_gestion_, ancien inscr_mobile_, etc.) : une vraie
// traduction contient des espaces/accents, jamais ce motif "cle_technique".
function isRawI18nKey(str) {
- return typeof str === 'string' && /^[a-z][a-z0-9_]*$/.test(str) && str.indexOf('_') !== -1;
+ return typeof str === 'string' && /^[a-z][a-z0-9_]*$/i.test(str) && str.indexOf('_') !== -1;
}
- // Renvoie la valeur de l'attribut si elle est traduite, sinon le texte
- // integre (bilingue) — evite d'afficher une clef brute a l'usager.
+ var SCAN_MSG_I18N = {
+ 'data-msg-scanning': 'bibScanScanning',
+ 'data-msg-loading': 'bibScanLoading',
+ 'data-msg-ready': 'bibScanReady',
+ 'data-msg-found': 'bibScanFound',
+ 'data-msg-found-search': 'bibScanFoundSearch',
+ 'data-msg-invalid': 'bibScanInvalid',
+ 'data-msg-camera': 'bibScanCamera'
+ };
+
+ // Attribut data-* si traduit, sinon libelle injecte (cfg.i18n) — jamais une clef brute.
function scanMsg(panel, attr) {
var value = panel ? panel.getAttribute(attr) : '';
if (value && !isRawI18nKey(value)) {
return value;
}
- return '';
+ var i18nKey = SCAN_MSG_I18N[attr];
+ return i18nKey ? t(i18nKey) : '';
}
BibScanSession.prototype.showReady = function () {
diff --git a/php/inc_fx_inscriptions_gestion.php b/php/inc_fx_inscriptions_gestion.php
index e165cb8..d57b086 100644
--- a/php/inc_fx_inscriptions_gestion.php
+++ b/php/inc_fx_inscriptions_gestion.php
@@ -303,7 +303,8 @@ function fxInscrGestionLookupTexteDb($strClef, $strLangue) {
LIMIT 1";
$strTexte = $objDatabase->fxGetVar($sql);
- if ($strTexte === null || trim((string)$strTexte) === '' || trim((string)$strTexte) === $strClef) {
+ if ($strTexte === null || trim((string)$strTexte) === '' || trim((string)$strTexte) === $strClef
+ || fxInscrGestionIsRawI18nKey($strTexte)) {
$tabMemo[$strMemoKey] = null;
return null;
}
@@ -312,6 +313,20 @@ function fxInscrGestionLookupTexteDb($strClef, $strLangue) {
return $tabMemo[$strMemoKey];
}
+/**
+ * True si $str ressemble a une clef info technique (ex. inscr_gestion_bib_scan_tap),
+ * pas a un vrai libelle (espaces/accents/points). Ignore marqueurs ZWSP trad.
+ */
+function fxInscrGestionIsRawI18nKey($str) {
+ $str = preg_replace('/[\x{200B}\x{200C}]/u', '', (string)$str);
+ // Payload base64 eventuel (mode edition textes) entre ZWSP deja retire.
+ $str = trim($str);
+ if ($str === '') {
+ return false;
+ }
+ return (bool)preg_match('/^[a-z][a-z0-9]*(_[a-z0-9]+)+$/i', $str);
+}
+
function fxInscrGestionResolveTexte($strClef, $strLangue) {
global $vtexte_page;
@@ -319,20 +334,20 @@ function fxInscrGestionResolveTexte($strClef, $strLangue) {
if (isset($tab[$strClef]['info_texte'])) {
$str = trim((string)$tab[$strClef]['info_texte']);
- if ($str !== '' && $str !== $strClef) {
+ if ($str !== '' && $str !== $strClef && !fxInscrGestionIsRawI18nKey($str)) {
return $str;
}
}
if (is_array($vtexte_page) && isset($vtexte_page[$strClef]['info_texte'])) {
$str = trim((string)$vtexte_page[$strClef]['info_texte']);
- if ($str !== '' && $str !== $strClef) {
+ if ($str !== '' && $str !== $strClef && !fxInscrGestionIsRawI18nKey($str)) {
return $str;
}
}
$strDb = fxInscrGestionLookupTexteDb($strClef, $strLangue);
- if ($strDb !== null) {
+ if ($strDb !== null && !fxInscrGestionIsRawI18nKey($strDb)) {
return $strDb;
}
@@ -345,7 +360,8 @@ function fxInscrGestionResolveTexte($strClef, $strLangue) {
if (strpos($str, '*') === 0 && substr($str, -1) === '*') {
return fxInscrGestionFallbackTexte($strClef, $strLangue);
}
- if (trim($str) === '' || trim($str) === $strClef) {
+ $strPlain = trim(preg_replace('/[\x{200B}\x{200C}]/u', '', (string)$str));
+ if ($strPlain === '' || $strPlain === $strClef || fxInscrGestionIsRawI18nKey($strPlain)) {
return fxInscrGestionFallbackTexte($strClef, $strLangue);
}
return $str;
@@ -459,6 +475,10 @@ function fxInscrGestionFallbackTexte($strClef, $strLangue) {
'inscr_gestion_list_count_one' => $blnFr ? '%d inscription' : '%d registration',
'inscr_gestion_list_count_many' => $blnFr ? '%d inscriptions' : '%d registrations',
'inscr_gestion_list_page' => $blnFr ? 'Page %d / %d' : 'Page %d / %d',
+ 'inscr_gestion_list_filter_kv' => $blnFr ? '%s : %s' : '%s: %s',
+ 'inscr_gestion_rech_bib_equipe' => $blnFr ? 'Dossard ou équipe' : 'Bib or team',
+ 'chk_bib' => $blnFr ? 'Sans numéro de dossard' : 'Without bib number',
+ 'inscr_gestion_reset_search' => $blnFr ? 'Réinitialiser la recherche' : 'Reset search',
);
}
@@ -486,8 +506,9 @@ function fxInscrGestionT($strClef) {
}
$strTexte = fxInscrGestionResolveTexte($strClef, $strLangue);
+ $strPlain = trim(preg_replace('/[\x{200B}\x{200C}]/u', '', (string)$strTexte));
- if ($strTexte === $strClef || trim((string)$strTexte) === '') {
+ if ($strPlain === '' || $strPlain === $strClef || fxInscrGestionIsRawI18nKey($strPlain)) {
$strFallback = fxInscrGestionFallbackTexte($strClef, $strLangue);
if ($strFallback !== $strClef && trim((string)$strFallback) !== '') {
$strTexte = $strFallback;
@@ -505,18 +526,16 @@ function fxInscrGestionT($strClef) {
}
/**
- * Libelle "robuste" pour les pastilles du scanner : si la table info renvoie une
- * clef i18n brute (donnee corrompue, ex. ancien 'inscr_mobile_bib_scan_tap' jamais
- * traduit), on l'ignore et on prend le libelle integre. Evite d'afficher une clef
- * technique a l'usager. Pas de marqueur d'edition ici (texte affiche dans la video).
+ * Libelle "robuste" pour le scanner : jamais de clef technique ni marqueur trad
+ * (affiche dans la video / data-msg lus par le JS).
*/
function fxInscrGestionScanLabel($strClef) {
global $strLangue;
$strLang = (isset($strLangue) && $strLangue !== '') ? $strLangue : 'fr';
- $strTexte = trim((string)fxInscrGestionResolveTexte($strClef, $strLang));
+ $strTexte = trim(preg_replace('/[\x{200B}\x{200C}]/u', '', (string)fxInscrGestionResolveTexte($strClef, $strLang)));
- if ($strTexte === '' || preg_match('/^[a-z][a-z0-9]*(_[a-z0-9]+)+$/', $strTexte)) {
+ if ($strTexte === '' || $strTexte === $strClef || fxInscrGestionIsRawI18nKey($strTexte)) {
$strTexte = fxInscrGestionFallbackTexte($strClef, $strLang);
}
@@ -1688,28 +1707,93 @@ function fxInscrGestionVisionReadBibNumber($strImageBase64) {
function fxInscrGestionRenderBibScanBlock($strBibInputId, $strLangue) {
echo '
';
+ // MSIN-4401 — ScanLabel : jamais de clef brute ni marqueur trad dans data-* / pastille.
+ echo ' data-msg-scanning="' . fxInscrGestionEsc(fxInscrGestionScanLabel('inscr_gestion_bib_scan_scanning')) . '"';
+ echo ' data-msg-loading="' . fxInscrGestionEsc(fxInscrGestionScanLabel('inscr_gestion_bib_scan_loading')) . '"';
+ echo ' data-msg-ready="' . fxInscrGestionEsc(fxInscrGestionScanLabel('inscr_gestion_bib_scan_ready')) . '"';
+ echo ' data-msg-found="' . fxInscrGestionEsc(fxInscrGestionScanLabel('inscr_gestion_bib_scan_found')) . '"';
+ echo ' data-msg-found-search="' . fxInscrGestionEsc(fxInscrGestionScanLabel('inscr_gestion_bib_scan_found_search')) . '"';
+ echo ' data-msg-invalid="' . fxInscrGestionEsc(fxInscrGestionScanLabel('inscr_gestion_bib_scan_invalid')) . '"';
+ echo ' data-msg-camera="' . fxInscrGestionEsc(fxInscrGestionScanLabel('inscr_gestion_qr_camera_error')) . '">';
echo '
'
- . fxInscrGestionEsc(fxInscrGestionT('inscr_gestion_bib_scan_hint')) . '
';
+ . fxInscrGestionEsc(fxInscrGestionScanLabel('inscr_gestion_bib_scan_hint')) . '';
echo '
';
echo '
';
echo '
';
- // Zone-cible centrale (eclaircie) : aligne le repere visuel sur la region
- // reellement lue par l'OCR (captureCenterFrame : ~55% largeur x 30% hauteur).
echo '
';
- // Pastille courte — texte Info (inscr_gestion_bib_scan_tap).
echo '
'
- . fxInscrGestionEsc(fxInscrGestionT('inscr_gestion_bib_scan_tap')) . '';
+ . fxInscrGestionEsc(fxInscrGestionScanLabel('inscr_gestion_bib_scan_tap')) . '';
echo '
';
echo '
';
}
+/**
+ * MSIN-4401 — Pastilles des filtres actifs (non vides) pour la barre de resultats.
+ * @return array liste de libelles deja pret a afficher (non escapes).
+ */
+function fxInscrGestionActiveFilterLabels($arrReq, $strLangue) {
+ $tab = array();
+ $strKv = fxInscrGestionT('inscr_gestion_list_filter_kv');
+ if ($strKv === 'inscr_gestion_list_filter_kv' || fxInscrGestionIsRawI18nKey($strKv)) {
+ $strKv = ($strLangue === 'en') ? '%s: %s' : '%s : %s';
+ }
+
+ if ($arrReq['rech_prenom'] !== '') {
+ $tab[] = sprintf($strKv, fxInscrGestionT('rech_prenom'), $arrReq['rech_prenom']);
+ }
+ if ($arrReq['rech_nom'] !== '') {
+ $tab[] = sprintf($strKv, fxInscrGestionT('rech_nom'), $arrReq['rech_nom']);
+ }
+ if ($arrReq['rech_no_commande'] !== '') {
+ $tab[] = sprintf($strKv, fxInscrGestionT('rech_no_commande'), $arrReq['rech_no_commande']);
+ }
+ if ($arrReq['rech_nom_equipe'] !== '') {
+ $tab[] = sprintf(
+ $strKv,
+ fxInscrGestionT('inscr_gestion_rech_bib_equipe'),
+ $arrReq['rech_nom_equipe']
+ );
+ }
+ if ($arrReq['sel_rech_epreuve'] > 0) {
+ $tab[] = sprintf(
+ $strKv,
+ fxInscrGestionT('sel_rech_epreuve'),
+ fxInscrGestionEpreuveLabel($arrReq['sel_rech_epreuve'], $strLangue)
+ );
+ }
+ if (!empty($arrReq['sel_rech_statut']) && is_array($arrReq['sel_rech_statut'])) {
+ $tabOptions = fxInscrGestionGetStatutCourseOptions($strLangue);
+ $tabMap = array();
+ foreach ($tabOptions as $arrOpt) {
+ $strCode = trim((string)$arrOpt['info_option2']);
+ if ($strCode !== '') {
+ $tabMap[$strCode] = trim((string)$arrOpt['info_texte']);
+ }
+ }
+ $tabStatLabels = array();
+ foreach ($arrReq['sel_rech_statut'] as $strCode) {
+ $tabStatLabels[] = isset($tabMap[$strCode]) && $tabMap[$strCode] !== ''
+ ? $tabMap[$strCode]
+ : $strCode;
+ }
+ if (count($tabStatLabels) > 0) {
+ $tab[] = sprintf(
+ $strKv,
+ fxInscrGestionT('inscr_gestion_rech_statut'),
+ implode(', ', $tabStatLabels)
+ );
+ }
+ }
+ if ($arrReq['chk_bib']) {
+ $tab[] = fxInscrGestionT('chk_bib');
+ }
+ if ($arrReq['chk_cancelled']) {
+ $tab[] = fxInscrGestionT('inscr_gestion_chk_cancelled');
+ }
+
+ return $tab;
+}
+
function fxInscrGestionRenderList($intEveId, $strLangue, $strBaseUrl, $arrReq) {
global $vDomaine;
@@ -1864,8 +1948,20 @@ function fxInscrGestionRenderList($intEveId, $strLangue, $strBaseUrl, $arrReq) {
}
echo '';
+ echo '
';
$strCountKey = ($intNbTotal === 1) ? 'inscr_gestion_list_count_one' : 'inscr_gestion_list_count_many';
- echo '' . fxInscrGestionEsc(sprintf(fxInscrGestionT($strCountKey), $intNbTotal)) . '';
+ echo ''
+ . fxInscrGestionEsc(sprintf(fxInscrGestionT($strCountKey), $intNbTotal)) . '';
+ // MSIN-4401 — Rappel des filtres / criteres non vides a cote du compteur.
+ $tabFilters = fxInscrGestionActiveFilterLabels($arrReq, $strLangue);
+ if (count($tabFilters) > 0) {
+ echo '';
+ foreach ($tabFilters as $strFilt) {
+ echo '' . fxInscrGestionEsc($strFilt) . '';
+ }
+ echo '';
+ }
+ echo '
';
if ($intNbTotal > $intNbItemsParPage) {
$intNbPages = (int)ceil($intNbTotal / $intNbItemsParPage);
echo '
'
diff --git a/php/inc_settings.php b/php/inc_settings.php
index fc15460..d0e2b95 100644
--- a/php/inc_settings.php
+++ b/php/inc_settings.php
@@ -7,7 +7,7 @@
* Constantes *
*
**************/
-define('_VERSION_CODE', '4.72.813');
+define('_VERSION_CODE', '4.72.814');
define('_DATE_CODE', '2026-07-13');
//MSIN-4290
define('QR_SECRET_KEY', 'ms1_qr_2026_cle_secrete_longue_et_fixe');
diff --git a/php/inc_v2_assets.php b/php/inc_v2_assets.php
index 60812be..c54b182 100644
--- a/php/inc_v2_assets.php
+++ b/php/inc_v2_assets.php
@@ -74,11 +74,42 @@ if (!function_exists('fxV2RegisterScript')) {
'errNetwork' => fxInscrGestionT('inscr_gestion_err_network'),
'errRefund' => fxInscrGestionT('inscr_gestion_err_refund'),
'refundOk' => fxInscrGestionT('inscr_gestion_refund_ok'),
- 'bibOcrNotConfigured' => fxInscrGestionT('inscr_gestion_bib_ocr_not_configured'),
- 'bibOcrVisionPrefix' => fxInscrGestionT('inscr_gestion_bib_ocr_vision_prefix'),
- 'bibOcrImageInvalid' => fxInscrGestionT('inscr_gestion_bib_ocr_image_invalid'),
- 'bibOcrNetwork' => fxInscrGestionT('inscr_gestion_bib_ocr_network'),
- 'bibOcrUnreadable' => fxInscrGestionT('inscr_gestion_bib_scan_invalid'),
+ 'bibOcrNotConfigured' => function_exists('fxInscrGestionScanLabel')
+ ? fxInscrGestionScanLabel('inscr_gestion_bib_ocr_not_configured')
+ : fxInscrGestionT('inscr_gestion_bib_ocr_not_configured'),
+ 'bibOcrVisionPrefix' => function_exists('fxInscrGestionScanLabel')
+ ? fxInscrGestionScanLabel('inscr_gestion_bib_ocr_vision_prefix')
+ : fxInscrGestionT('inscr_gestion_bib_ocr_vision_prefix'),
+ 'bibOcrImageInvalid' => function_exists('fxInscrGestionScanLabel')
+ ? fxInscrGestionScanLabel('inscr_gestion_bib_ocr_image_invalid')
+ : fxInscrGestionT('inscr_gestion_bib_ocr_image_invalid'),
+ 'bibOcrNetwork' => function_exists('fxInscrGestionScanLabel')
+ ? fxInscrGestionScanLabel('inscr_gestion_bib_ocr_network')
+ : fxInscrGestionT('inscr_gestion_bib_ocr_network'),
+ 'bibOcrUnreadable' => function_exists('fxInscrGestionScanLabel')
+ ? fxInscrGestionScanLabel('inscr_gestion_bib_scan_invalid')
+ : fxInscrGestionT('inscr_gestion_bib_scan_invalid'),
+ 'bibScanScanning' => function_exists('fxInscrGestionScanLabel')
+ ? fxInscrGestionScanLabel('inscr_gestion_bib_scan_scanning')
+ : '',
+ 'bibScanLoading' => function_exists('fxInscrGestionScanLabel')
+ ? fxInscrGestionScanLabel('inscr_gestion_bib_scan_loading')
+ : '',
+ 'bibScanReady' => function_exists('fxInscrGestionScanLabel')
+ ? fxInscrGestionScanLabel('inscr_gestion_bib_scan_ready')
+ : '',
+ 'bibScanFound' => function_exists('fxInscrGestionScanLabel')
+ ? fxInscrGestionScanLabel('inscr_gestion_bib_scan_found')
+ : '',
+ 'bibScanFoundSearch' => function_exists('fxInscrGestionScanLabel')
+ ? fxInscrGestionScanLabel('inscr_gestion_bib_scan_found_search')
+ : '',
+ 'bibScanInvalid' => function_exists('fxInscrGestionScanLabel')
+ ? fxInscrGestionScanLabel('inscr_gestion_bib_scan_invalid')
+ : '',
+ 'bibScanCamera' => function_exists('fxInscrGestionScanLabel')
+ ? fxInscrGestionScanLabel('inscr_gestion_qr_camera_error')
+ : '',
] : [],
];
}
diff --git a/sql/MSIN-4401-inscr-gestion-bib-scan-i18n.sql b/sql/MSIN-4401-inscr-gestion-bib-scan-i18n.sql
new file mode 100644
index 0000000..355ded3
--- /dev/null
+++ b/sql/MSIN-4401-inscr-gestion-bib-scan-i18n.sql
@@ -0,0 +1,52 @@
+-- MSIN-4401 — Libellés Info scan dossard + pastille filtres liste
+-- Prérequis : aucun (complète MSIN-inscriptions-mobile-qr-i18n / v2-info-complet)
+-- Idempotent (DELETE + INSERT). Corrige les textes manquants ou corrompus (clef brute).
+
+DELETE FROM info
+WHERE info_prg = 'compte.php'
+ AND info_clef IN (
+ 'inscr_gestion_bib_scan_btn',
+ 'inscr_gestion_bib_scan_hint',
+ 'inscr_gestion_bib_scan_ready',
+ 'inscr_gestion_bib_scan_tap',
+ 'inscr_gestion_bib_scan_scanning',
+ 'inscr_gestion_bib_scan_loading',
+ 'inscr_gestion_bib_scan_found',
+ 'inscr_gestion_bib_scan_found_search',
+ 'inscr_gestion_bib_scan_invalid',
+ 'inscr_gestion_bib_ocr_not_configured',
+ 'inscr_gestion_bib_ocr_vision_prefix',
+ 'inscr_gestion_bib_ocr_image_invalid',
+ 'inscr_gestion_bib_ocr_network',
+ 'inscr_gestion_list_filter_kv'
+ );
+
+INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation) VALUES
+('inscr_gestion_bib_scan_btn', 'fr', 'Scanner le numéro', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_scan_btn', 'en', 'Scan number', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_scan_hint', 'fr', 'Cadrez le numéro dans le cadre, puis touchez l''image.', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_scan_hint', 'en', 'Frame the number in the box, then tap the image.', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_scan_ready', 'fr', 'Touchez l''image pour lire', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_scan_ready', 'en', 'Tap the image to read', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_scan_tap', 'fr', 'Touchez pour lire', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_scan_tap', 'en', 'Tap to read', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_scan_scanning', 'fr', 'Lecture en cours...', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_scan_scanning', 'en', 'Reading...', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_scan_loading', 'fr', 'Initialisation (1re fois)...', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_scan_loading', 'en', 'Initializing (first time)...', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_scan_found', 'fr', 'Numéro %s détecté — validez avec OK.', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_scan_found', 'en', 'Number %s detected — press OK.', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_scan_found_search', 'fr', 'Numéro %s détecté — recherche...', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_scan_found_search', 'en', 'Number %s detected — searching...', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_scan_invalid', 'fr', 'Numéro illisible. Cadrez un seul numéro.', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_scan_invalid', 'en', 'Unreadable number. Frame a single number.', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_ocr_not_configured', 'fr', 'OCR non configuré (clé Vision absente sur le serveur).', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_ocr_not_configured', 'en', 'OCR not configured (Vision API key missing on server).', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_ocr_vision_prefix', 'fr', 'Erreur Vision : ', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_ocr_vision_prefix', 'en', 'Vision error: ', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_ocr_image_invalid', 'fr', 'Image invalide.', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_ocr_image_invalid', 'en', 'Invalid image capture.', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_ocr_network', 'fr', 'Erreur réseau ou capture.', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_bib_ocr_network', 'en', 'Network or capture error.', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_list_filter_kv', 'fr', '%s : %s', '', 'compte.php', '', 0, 1, '', '', '', NOW()),
+('inscr_gestion_list_filter_kv', 'en', '%s: %s', '', 'compte.php', '', 0, 1, '', '', '', NOW());