diff --git a/index.html b/index.html
index 1520018..85c0302 100644
--- a/index.html
+++ b/index.html
@@ -125,6 +125,13 @@
+
+
diff --git a/js/langs/en.json b/js/langs/en.json
new file mode 100644
index 0000000..85dbcac
--- /dev/null
+++ b/js/langs/en.json
@@ -0,0 +1,4 @@
+{
+ "filter_title": "Filters",
+ "filter_description": "Display stations with a power greater than:"
+}
\ No newline at end of file
diff --git a/js/langs/fr.json b/js/langs/fr.json
new file mode 100644
index 0000000..b00f5e3
--- /dev/null
+++ b/js/langs/fr.json
@@ -0,0 +1,4 @@
+{
+ "filter_title": "Filtres",
+ "filter_description": "Afficher les stations avec une puissance supérieure à:"
+}
\ No newline at end of file
diff --git a/js/lcm_i18n.js b/js/lcm_i18n.js
new file mode 100644
index 0000000..82357e7
--- /dev/null
+++ b/js/lcm_i18n.js
@@ -0,0 +1,70 @@
+
+/**
+ * Gestion des traductions dans libre charge map
+ */
+class LcmI18n {
+
+ constructor() {
+ this.i18n = {};
+ this.language = this.detectLanguage();
+ }
+
+ /**
+ * Détecte la langue préférée du navigateur
+ * @returns {string} Code de langue sur 2 caractères (ex: 'fr', 'en')
+ */
+ detectLanguage() {
+ // Récupérer la langue du navigateur
+ const browserLang = navigator.language || navigator.userLanguage;
+
+ // Extraire les 2 premiers caractères (code langue)
+ const lang = browserLang.substring(0, 2).toLowerCase();
+
+ // Par défaut retourner 'en' si la langue n'est pas reconnue
+ return lang || 'en';
+ }
+
+ /**
+ * Récupère la langue courante
+ * @returns {string} Code de langue sur 2 caractères (ex: 'fr', 'en')
+ */
+ getCurrentLanguage() {
+ return this.language;
+ }
+
+ /**
+ * Traduit une chaîne de caractères dans la langue courante
+ * @param {string} key - Clé de traduction
+ * @param {Object} params - Paramètres optionnels pour la substitution
+ * @returns {string} Chaîne traduite
+ */
+ translate(key, params = {}) {
+ // Vérifier si la clé existe dans les traductions
+ if (!this.i18n[this.language] || !this.i18n[this.language][key]) {
+ console.error(`[LcmI18n] Clé de traduction introuvable: "${key}" pour la langue "${this.language}"`);
+
+ return 'I18N_RROR[' + key + ']';
+ }
+ // Obtenir les traductions pour la langue courante
+ const translations = this.i18n[this.language] || {};
+
+ // Récupérer la traduction ou utiliser la clé par défaut
+ let translation = translations[key] || key;
+
+ // Remplacer les paramètres dans la traduction
+ Object.keys(params).forEach(param => {
+ translation = translation.replace(`{${param}}`, params[param]);
+ });
+
+ return translation;
+ }
+
+ /**
+ * Alias raccourci pour la méthode translate()
+ */
+ t(key, params = {}) {
+ return this.translate(key, params);
+ }
+}
+
+export const lcm_i18n = new LcmI18n();
\ No newline at end of file
diff --git a/js/lcm_main.js b/js/lcm_main.js
index ccd29c0..9a68631 100644
--- a/js/lcm_main.js
+++ b/js/lcm_main.js
@@ -13,6 +13,7 @@ let geojsondata;
let lastLatLng;
let searchLocationMarker = null;
let count_hidden_by_filters = 0;
+let averageChargeKwh = 26;
@@ -691,9 +692,22 @@ function eachFeature(feature, layer, stats) {
}
+ // Calcul du temps de recharge
+ let rechargeTimeText = '';
+ if (outPowerGuessed && outPowerGuessed > 0) {
+ const hours = averageChargeKwh / outPowerGuessed;
+ const minutes = Math.round(hours * 60);
+ const h = Math.floor(minutes / 60);
+ const m = minutes % 60;
+ rechargeTimeText = `
+ ⏱️ Temps moyen de recharge :
+ ${h > 0 ? h + 'h ' : ''}${m} min
+
`;
+ }
+
// contenu de la popup
let html = `
${displayOutPowerGuessed}
-
+ ${rechargeTimeText}