Différences entre un exosquelette passif et un exosquelette actif

Les exosquelettes, de manière générale, constituent un chamboulement dans le véritable domaine de la mobilité. Et pour cause, ils ont réussi là où beaucoup d’autres ont échoué. En effet, et grâce aux exosquelettes, de nombreuses personnes ont pu reprendre le contrôle de leur mobilité et accroître leur force… Voir continuer leur vie le plus normalement … Lire la suite

/** * i18n-core.js * * Lightweight internationalisation runtime for multi-site WordPress deployments. * * How it works: * 1. A per-site language file (e.g. lang-fr.js) sets window.I18N.strings * before this script runs, or this script sets the default empty object. * 2. T(key) — resolves a dot-notation key like "quiz.step1.question" * against I18N.strings and returns the matching string. * Falls back to the key itself if not found, and warns in the console. * 3. Tf(key, vars) — same as T() but performs {placeholder} substitution * using the vars object, e.g. Tf('quiz.result', { n: 3, total: 7 }). * 4. On DOMContentLoaded the runtime auto-translates the DOM: * data-i18n="some.key" → element.textContent (or innerHTML * when the string contains \n, which * is converted to
after escaping) * data-i18n-placeholder="some.key" → element.placeholder attribute * * Load order (in or before body close): * * */ (function (window, document) { 'use strict'; /* ── namespace ─────────────────────────────────────────────────────────── */ window.I18N = window.I18N || {}; window.I18N.strings = window.I18N.strings || {}; /* ── internal helpers ───────────────────────────────────────────────────── */ /** * Resolve a dot-notation key against an object. * Returns undefined when any segment is missing. */ function _resolve(obj, key) { var parts = key.split('.'); var cursor = obj; for (var i = 0; i < parts.length; i++) { if (cursor === null || cursor === undefined || typeof cursor !== 'object') { return undefined; } cursor = cursor[parts[i]]; } return cursor; } /* ── public API ─────────────────────────────────────────────────────────── */ /** * T(key) — translate a dot-notation key. * Returns the translated string, or the key itself when not found. */ window.T = function T(key) { var value = _resolve(window.I18N.strings, key); if (value === undefined || value === null) { console.warn('[i18n] Missing key:', key); return key; } return String(value); }; /** * Tf(key, vars) — translate then replace {placeholders}. * vars is a plain object whose keys match the placeholder names. * Example: Tf('quiz.result', { n: 3, total: 7 }) * with string "You got {n} out of {total}" → "You got 3 out of 7" */ window.Tf = function Tf(key, vars) { var str = window.T(key); if (!vars || typeof vars !== 'object') { return str; } return str.replace(/\{([^}]+)\}/g, function (match, placeholder) { return Object.prototype.hasOwnProperty.call(vars, placeholder) ? String(vars[placeholder]) : match; }); }; /* ── DOM auto-translation ────────────────────────────────────────────────── */ function _translateDOM() { var textNodes = document.querySelectorAll('[data-i18n]'); for (var i = 0; i < textNodes.length; i++) { var el = textNodes[i]; var str = window.T(el.getAttribute('data-i18n')); if (str.indexOf('\n') !== -1) { // Escape HTML special chars first, then convert \n →
. // & must be escaped before < and > to avoid double-escaping &. el.innerHTML = str .replace(/&/g, '&') .replace(//g, '>') .replace(/\n/g, '
'); } else { el.textContent = str; } } var placeholderNodes = document.querySelectorAll('[data-i18n-placeholder]'); for (var j = 0; j < placeholderNodes.length; j++) { var pel = placeholderNodes[j]; pel.setAttribute( 'placeholder', window.T(pel.getAttribute('data-i18n-placeholder')) ); } } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', _translateDOM); } else { _translateDOM(); } }(window, document)); /** * lang-fr.js — Master French string file * * This is the source-of-truth language file. All other lang-xx.js files * are translations of the keys defined here. * * Load this BEFORE i18n-core.js so the strings are available at runtime: * * * * Structure mirrors the features that use it — add namespaces as more * snippets are migrated to the i18n system. */ window.I18N = window.I18N || {}; window.I18N.strings = { quiz: { header: { titlePart: "Quel exosquelette vous convient ?", titlePro: "Trouvez votre solution pro" }, progress: { stepLabel: "Étape {n} sur {total}", coordonneesLabel: "Vos coordonnées", confirmLabel: "Confirmation" }, step1: { question: "Vous êtes…", profilPart: { label: "Un particulier", sub: "Usage personnel, sport, sénior, rééducation" }, profilPro: { label: "Un professionnel", sub: "Entreprise, industrie, établissement médical" } }, step2: { question: "Pour quel usage ?", hint: "Vous pouvez sélectionner plusieurs réponses", options: { industrie: { label: "Travail / Industrie", sub: "Port de charges, TMS" }, sport: { label: "Sport & Loisir", sub: "Ski, randonnée, trail" }, senior: { label: "Particulier / Sénior", sub: "Mobilité quotidienne" } } }, step3work: { question: "Précisez votre contexte", hint: "Vous pouvez sélectionner plusieurs réponses", options: { prevention: { label: "Prévenir les accidents du travail / TMS", sub: "Réduire les risques de troubles musculosquelettiques" }, handicap: { label: "Maintenir dans l'emploi une personne en situation de handicap", sub: "Compensation du handicap, maintien au poste" }, autre: { label: "Autre", sub: "Précisez si vous le souhaitez" } }, autrePlaceholder: "Précisez votre contexte (facultatif)" }, step3med: { question: "Précisez votre contexte", hint: "Vous pouvez sélectionner plusieurs réponses", options: { reeducation: { label: "Retrouver de la mobilité après une blessure ou un arrêt", sub: "Récupérer des capacités motrices après un accident ou une pathologie" }, mobilite: { label: "Mobilité quotidienne ou ponctuelle", sub: "Faciliter la marche et les déplacements" }, compensation: { label: "Compenser une faiblesse physique ou une perte d'autonomie", sub: "Compenser une faiblesse musculaire ou neurologique" }, autonomie: { label: "Maintenir son autonomie physique", sub: "Maintenir la masse musculaire et les capacités physiques" }, autre: { label: "Autre" } } }, step4: { question: "Quelle partie du corps ?", hint: "Vous pouvez sélectionner plusieurs réponses", options: { dos: { label: "Dos / Lombaires", sub: "Flexions, charges" }, jambes: { label: "Jambes / Genoux", sub: "Marche, position debout" }, bras: { label: "Bras / Épaules", sub: "Travail en hauteur" }, entier: { label: "Corps entier", sub: "Rééducation complète" }, autre: { label: "Autre", sub: "Précisez si vous le souhaitez" } }, autrePlaceholder: "Précisez la partie du corps (facultatif)" }, step5: { question: "Quel type d'exosquelette ?", hint: "Vous pouvez sélectionner plusieurs réponses", options: { passif: { label: "Passif", sub: "Assistance mécanique, sans moteur" }, actif: { label: "Actif", sub: "Motorisé, assistance électrique" }, indecis: { label: "Je ne sais pas encore", sub: "Conseillez-moi" } } }, step6: { question: "Quelle enveloppe budgétaire ?", hint: "Plusieurs réponses possibles si vous hésitez entre des gammes", options: { low: { label: "Moins de 2 000 €", sub: "Exosquelettes passifs, sport, sénior" }, mid: { label: "1 500 € – 10 000 €", sub: "Semi-actifs, industrie légère" }, high: { label: "10 000 € – 50 000 €", sub: "Actifs, industrie lourde" }, premium: { label: "+ de 50 000 €", sub: "Solutions avancées" } } }, step7: { previewPart: { title: "Votre sélection personnalisée est prête !", text: "Recevez vos 3 meilleures recommandations par email avec comparatif complet et avis experts." }, previewPro: { title: "Vos recommandations pro sont prêtes !", text: "En plus du comparatif, nous pouvons vous mettre en contact directement avec les marques sélectionnées pour un devis personnalisé." }, form: { namePrenom: { label: "Nom et Prénom", placeholder: "Votre nom et prénom" }, email: { label: "Email", placeholder: "votre@email.com" }, entreprise: { label: "Nom de l'entreprise", placeholder: "Votre entreprise" }, tel: { label: "Téléphone", placeholder: "+33 6 00 00 00 00", optional: "(optionnel)" }, codePostal: { label: "Code postal", placeholder: "75000" }, secteur: { label: "Secteur d'activité", placeholder: "Sélectionnez votre secteur", options: { industrie: "Industrie", btp: "BTP", logistique: "Logistique", agriculture: "Agriculture", sante: "Santé", collectivite:"Collectivité", autre: "Autre" } } }, submit: "Recevoir mes recommandations →", legal: "Pas de spam. Désinscription en 1 clic. Données protégées (RGPD)." }, errors: { requiredFields: "Veuillez remplir votre nom/prénom et email.", invalidEmail: "Veuillez entrer un email valide." }, confirm: { title: "Merci pour votre confiance !", message: "Vous recevrez un mail dès aujourd'hui avec vos recommandations personnalisées pour votre besoin.", ctaPrompt: "Vous souhaitez avoir plus d'informations ?\nÉcrivez-nous", browseBtn: "🔍 Parcourir le site", contactBtn: "✉️ Nous contacter" }, buttons: { next: "Suivant →", back: "← Retour" } } };