1005 lines
41 KiB
JavaScript
1005 lines
41 KiB
JavaScript
// Script pour la gestion des pages de stratégie
|
||
(function() {
|
||
// Protection contre Fast Refresh : ignorer les tentatives de hot-reload
|
||
// Intercepter et ignorer les requêtes webpack hot-update pour éviter les rechargements en boucle
|
||
if (typeof window !== 'undefined') {
|
||
// Intercepter fetch
|
||
const originalFetch = window.fetch;
|
||
window.fetch = function(...args) {
|
||
const url = args[0];
|
||
if (typeof url === 'string' && url.includes('webpack.hot-update.json')) {
|
||
// Ignorer silencieusement les requêtes webpack hot-update
|
||
return Promise.resolve(new Response(JSON.stringify({}), {
|
||
status: 200,
|
||
headers: { 'Content-Type': 'application/json' }
|
||
}));
|
||
}
|
||
return originalFetch.apply(this, args);
|
||
};
|
||
|
||
// Intercepter XMLHttpRequest (utilisé par Next.js pour Fast Refresh)
|
||
const originalXHROpen = XMLHttpRequest.prototype.open;
|
||
XMLHttpRequest.prototype.open = function(method, url, ...rest) {
|
||
if (typeof url === 'string' && url.includes('webpack.hot-update.json')) {
|
||
// Créer un faux XHR qui ne fait rien
|
||
this._shouldIgnore = true;
|
||
return;
|
||
}
|
||
return originalXHROpen.apply(this, [method, url, ...rest]);
|
||
};
|
||
|
||
const originalXHRSend = XMLHttpRequest.prototype.send;
|
||
XMLHttpRequest.prototype.send = function(...args) {
|
||
if (this._shouldIgnore) {
|
||
// Simuler une réponse réussie pour éviter les erreurs
|
||
setTimeout(() => {
|
||
if (this.onload) this.onload();
|
||
if (this.onreadystatechange) {
|
||
this.readyState = 4;
|
||
this.status = 200;
|
||
this.responseText = '{}';
|
||
this.onreadystatechange();
|
||
}
|
||
}, 0);
|
||
return;
|
||
}
|
||
return originalXHRSend.apply(this, args);
|
||
};
|
||
}
|
||
|
||
// --- DÉBUT PROTECTION MOT DE PASSE ---
|
||
function checkAuth() {
|
||
const SESSION_KEY = 'radar_auth_session';
|
||
// Mot de passe simple
|
||
const PASSWORD = 'laplank-radar';
|
||
|
||
if (localStorage.getItem(SESSION_KEY) === 'valid') {
|
||
return; // Déjà connecté
|
||
}
|
||
|
||
// Créer l'écran de blocage
|
||
const overlay = document.createElement('div');
|
||
overlay.id = 'auth-overlay';
|
||
overlay.style.cssText = 'position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: #1a4d3a; z-index: 10000; display: flex; justify-content: center; align-items: center; flex-direction: column; font-family: sans-serif;';
|
||
|
||
overlay.innerHTML = `
|
||
<div style="background: white; padding: 40px; border-radius: 8px; text-align: center; box-shadow: 0 4px 15px rgba(0,0,0,0.3);">
|
||
<h2 style="margin-top: 0; color: #1a4d3a;">Accès Restreint</h2>
|
||
<p style="color: #666; margin-bottom: 20px;">Veuillez entrer le mot de passe pour accéder au Radar Stratégique.</p>
|
||
<input type="password" id="auth-pass" placeholder="Mot de passe" style="padding: 10px; border: 1px solid #ddd; border-radius: 4px; width: 200px; margin-bottom: 15px; display: block; margin: 0 auto 15px auto;">
|
||
<button id="auth-btn" style="background: #2ecc71; color: white; border: none; padding: 10px 20px; border-radius: 4px; cursor: pointer; font-weight: bold;">Valider</button>
|
||
<p id="auth-error" style="color: #e74c3c; display: none; margin-top: 10px; font-size: 0.9em;">Mot de passe incorrect</p>
|
||
</div>
|
||
`;
|
||
|
||
document.body.appendChild(overlay);
|
||
// Cacher le contenu principal pour éviter le flash
|
||
document.body.style.overflow = 'hidden';
|
||
|
||
const btn = document.getElementById('auth-btn');
|
||
const input = document.getElementById('auth-pass');
|
||
const errorMsg = document.getElementById('auth-error');
|
||
|
||
function validate() {
|
||
if (input.value === PASSWORD) {
|
||
localStorage.setItem(SESSION_KEY, 'valid');
|
||
overlay.remove();
|
||
document.body.style.overflow = 'auto';
|
||
} else {
|
||
errorMsg.style.display = 'block';
|
||
input.style.border = '1px solid #e74c3c';
|
||
}
|
||
}
|
||
|
||
btn.addEventListener('click', validate);
|
||
input.addEventListener('keypress', (e) => {
|
||
if (e.key === 'Enter') validate();
|
||
});
|
||
}
|
||
|
||
// Contenu des pages Markdown
|
||
const pagesContent = {
|
||
'strategie': `# Stratégie d'Évolution Technique - Laplank
|
||
|
||
**Date de mise à jour** : 02/12/2025
|
||
|
||
Date: 02/12/2025
|
||
|
||
## Vision Technique à 3 Ans
|
||
|
||
### Objectifs Stratégiques
|
||
|
||
1. **Renforcer la différenciation** : Maintenir et développer les technologies qui créent un avantage concurrentiel
|
||
2. **Réduire les risques** : Éliminer les dépendances critiques et les gaps de compétences
|
||
3. **Optimiser les coûts** : Réduire les coûts de maintenance des technologies de commodité
|
||
4. **Innover** : Explorer et adopter les technologies émergentes prometteuses
|
||
5. **Infrastructure décentralisée** : Développer l'expertise et l'adoption de ThreeFold pour une infrastructure autonome et résiliente
|
||
|
||
## Roadmap d'Évolution
|
||
|
||
### Axe Transversal : Data Visualization & UX (NOUVEAU)
|
||
|
||
**Objectif** : Devenir la référence en termes de transparence et d'accessibilité des données blockchain/crypto et infrastructure.
|
||
|
||
**Technologies Clés** :
|
||
- **D3.js / ECharts** : Pour des visualisations avancées et interactives.
|
||
- **Cytoscape.js** : Pour visualiser la "Toile de Confiance" (Web of Trust).
|
||
- **Grafana** : Pour le monitoring de l'infrastructure (Duniter & ThreeFold).
|
||
- **Leaflet** : Pour la cartographie des nœuds.
|
||
|
||
**Actions** :
|
||
1. Développer un explorateur de **Web of Trust visuel** (Graph).
|
||
2. Créer des dashboards de **santé du réseau** (Duniter & ThreeFold).
|
||
3. Former l'équipe front-end sur **D3.js** ou **ECharts**.
|
||
|
||
**KPIs** :
|
||
- Temps de compréhension pour un nouvel utilisateur.
|
||
- Adoption des outils de visualisation.
|
||
- Nombre de vues sur les dashboards publics.
|
||
|
||
### Année 1 : Consolidation et Réduction des Risques
|
||
|
||
#### Q1-Q2 : Gestion des Gaps de Compétences Critiques
|
||
|
||
**Objectif** : Réduire les risques liés aux compétences manquantes
|
||
|
||
**Actions** :
|
||
- Identifier les technologies critiques avec faible couverture d'équipe
|
||
- Mettre en place un plan de formation pour les technologies core
|
||
- Documenter les connaissances critiques
|
||
- Créer des plans de continuité en cas de départ
|
||
|
||
**Technologies prioritaires** :
|
||
- Rust / Substrate (blockchain core)
|
||
- Docker / Infrastructure
|
||
- PostgreSQL
|
||
- ThreeFold Grid (infrastructure décentralisée - bonne couverture mais à renforcer)
|
||
|
||
**Budget estimé** : Formation et documentation
|
||
|
||
#### Q3-Q4 : Optimisation des Commodités
|
||
|
||
**Objectif** : Réduire les coûts de maintenance des technologies non différenciantes
|
||
|
||
**Actions** :
|
||
- Auditer les coûts de maintenance
|
||
- Identifier les opportunités d'optimisation
|
||
- Standardiser les pratiques
|
||
- Automatiser les tâches répétitives
|
||
|
||
**Technologies cibles** :
|
||
- Infrastructure (Docker, Linux, PostgreSQL)
|
||
- Outils de développement
|
||
|
||
**Budget estimé** : Automatisation et optimisation
|
||
|
||
### Année 2 : Innovation et Différenciation
|
||
|
||
#### Q1-Q2 : Évaluation des Technologies Émergentes
|
||
|
||
**Objectif** : Identifier et évaluer les technologies prometteuses
|
||
|
||
**Actions** :
|
||
- POC (Proof of Concept) sur les technologies émergentes
|
||
- Évaluer l'impact business potentiel
|
||
- Mesurer la capacité de différenciation
|
||
- Tester l'adoption par l'équipe
|
||
|
||
**Technologies à évaluer** :
|
||
- IPFS (stockage distribué)
|
||
- Nostr (protocole décentralisé)
|
||
- Serverless (architecture)
|
||
- ThreeFold Grid (infrastructure décentralisée - opportunité majeure)
|
||
- Zero OS (système d'exploitation bare metal)
|
||
- ThreeFold Compute / Storage (capacités de calcul et stockage décentralisées)
|
||
- Mycelium Network (réseau overlay chiffré)
|
||
- AIBox (solution IA décentralisée)
|
||
|
||
**Budget estimé** : POC et évaluation
|
||
|
||
#### Q3-Q4 : Adoption Stratégique
|
||
|
||
**Objectif** : Adopter les technologies émergentes validées
|
||
|
||
**Actions** :
|
||
- Intégrer les technologies validées dans les projets
|
||
- Former l'équipe
|
||
- Documenter les bonnes pratiques
|
||
- Monitorer l'impact
|
||
|
||
**Budget estimé** : Développement et formation
|
||
|
||
### Année 3 : Maturité et Évolution Continue
|
||
|
||
#### Objectifs
|
||
|
||
- Maintenir un radar technologique à jour
|
||
- Continuer l'innovation
|
||
- Optimiser en continu
|
||
- Gérer les risques proactivement
|
||
|
||
## Priorités d'Investissement
|
||
|
||
### Priorité 1 : Technologies Core (Critiques)
|
||
|
||
**Investissement** : Maximum
|
||
**Focus** : Stabilité, performance, sécurité
|
||
|
||
**Technologies** :
|
||
- Rust / Substrate (blockchain)
|
||
- Infrastructure critique
|
||
- ThreeFold Grid (infrastructure décentralisée - bonne couverture)
|
||
|
||
**Actions** :
|
||
- Maintenance proactive
|
||
- Formation continue
|
||
- Documentation exhaustive
|
||
- Plans de continuité
|
||
- Développement de l'expertise ThreeFold
|
||
|
||
### Priorité 2 : Technologies Stratégiques
|
||
|
||
**Investissement** : Élevé
|
||
**Focus** : Croissance, différenciation
|
||
|
||
**Technologies** :
|
||
- Technologies différenciantes
|
||
- Technologies émergentes prometteuses
|
||
- ThreeFold (écosystème complet - opportunité stratégique majeure)
|
||
- ThreeFold Grid (infrastructure décentralisée)
|
||
- Zero OS (système bare metal)
|
||
- ThreeFold Compute / Storage (capacités décentralisées)
|
||
- Mycelium Network (réseau overlay)
|
||
- AIBox (IA décentralisée)
|
||
|
||
**Actions** :
|
||
- Développement actif
|
||
- Innovation
|
||
- Expérimentation
|
||
- POC sur infrastructure décentralisée
|
||
- Formation sur ThreeFold
|
||
|
||
### Priorité 3 : Technologies de Support
|
||
|
||
**Investissement** : Modéré
|
||
**Focus** : Efficacité, coût
|
||
|
||
**Technologies** :
|
||
- Technologies de commodité
|
||
- Outils de développement
|
||
|
||
**Actions** :
|
||
- Optimisation
|
||
- Standardisation
|
||
- Automatisation
|
||
|
||
### Priorité 4 : Technologies Legacy
|
||
|
||
**Investissement** : Minimal (migration)
|
||
**Focus** : Remplacement, réduction des risques
|
||
|
||
**Technologies** :
|
||
- Technologies obsolètes
|
||
- Technologies à risque
|
||
|
||
**Actions** :
|
||
- Planification de migration
|
||
- Réduction progressive
|
||
- Remplacement
|
||
|
||
## Plan de Migration
|
||
|
||
### Technologies à Migrer
|
||
|
||
#### Court Terme (0-6 mois)
|
||
|
||
Aucune migration urgente identifiée actuellement.
|
||
|
||
#### Moyen Terme (6-18 mois)
|
||
|
||
- Évaluer les technologies legacy
|
||
- Planifier les remplacements
|
||
- Identifier les alternatives
|
||
|
||
#### Long Terme (18+ mois)
|
||
|
||
- Exécuter les migrations planifiées
|
||
- Valider les alternatives
|
||
- Documenter les leçons apprises
|
||
|
||
## Gestion des Risques
|
||
|
||
### Risques Identifiés
|
||
|
||
1. **Gaps de compétences** : Technologies critiques avec faible couverture
|
||
2. **Dépendances uniques** : Technologies sans alternative
|
||
3. **Obsolescence** : Technologies vieillissantes
|
||
4. **Coûts** : Maintenance élevée de certaines technologies
|
||
|
||
### Stratégies de Mitigation
|
||
|
||
1. **Formation et recrutement** : Réduire les gaps de compétences
|
||
2. **Diversification** : Éviter les dépendances uniques
|
||
3. **Veille technologique** : Détecter l'obsolescence tôt
|
||
4. **Optimisation continue** : Réduire les coûts
|
||
|
||
## KPIs de Suivi
|
||
|
||
### Métriques Techniques
|
||
|
||
- **Couverture d'équipe** : Nombre moyen de personnes par technologie
|
||
- **Gaps de compétences** : Nombre de technologies avec gap élevé
|
||
- **Risques techniques** : Nombre de technologies à risque élevé
|
||
- **Coûts** : Coût total de maintenance
|
||
|
||
### Métriques Business
|
||
|
||
- **Différenciation** : Nombre de technologies différenciantes
|
||
- **Innovation** : Nombre de technologies émergentes adoptées
|
||
- **Efficacité** : Réduction des coûts de maintenance
|
||
- **Stabilité** : Réduction des incidents techniques
|
||
|
||
### Objectifs Annuels
|
||
|
||
**Année 1** :
|
||
- Réduire les gaps de compétences de 50%
|
||
- Documenter 100% des technologies core
|
||
- Réduire les coûts de maintenance de 20%
|
||
- POC ThreeFold Grid (déploiement de nœuds de test)
|
||
- Lancement du projet DataViz (POC Web of Trust visuelle)
|
||
|
||
**Année 2** :
|
||
- Adopter 2-3 technologies émergentes (dont ThreeFold Grid)
|
||
- Maintenir les gaps de compétences < 2 technologies
|
||
- Optimiser les coûts de 30%
|
||
- Déployer infrastructure ThreeFold en production (si POC validé)
|
||
- Former l'équipe sur Zero OS et ThreeFold
|
||
|
||
**Année 3** :
|
||
- Maintenir un radar à jour
|
||
- Continuer l'innovation
|
||
- Optimiser en continu
|
||
- Infrastructure décentralisée opérationnelle (ThreeFold)
|
||
- Réduire la dépendance aux infrastructures centralisées
|
||
|
||
## Communication et Gouvernance
|
||
|
||
### Comité Technique
|
||
|
||
- Réunion trimestrielle pour revue du radar
|
||
- Décisions sur les priorités d'investissement
|
||
- Validation des migrations
|
||
|
||
### Reporting
|
||
|
||
- Rapport mensuel sur les métriques
|
||
- Rapport trimestriel sur l'avancement
|
||
- Rapport annuel sur la stratégie
|
||
|
||
### Parties Prenantes
|
||
|
||
- Équipe technique
|
||
- Direction
|
||
- Financement (si applicable)
|
||
- Communauté (open source)
|
||
|
||
## Conclusion
|
||
|
||
Cette stratégie d'évolution technique vise à aligner les choix technologiques avec les objectifs business, réduire les risques, optimiser les coûts et favoriser l'innovation.
|
||
|
||
La mise en œuvre de cette stratégie nécessite un engagement continu de l'équipe et un suivi régulier des métriques définies.`,
|
||
|
||
'business': `# Stratégie Business : Data Visualization & Flux Économiques
|
||
|
||
**Date** : 02/12/2025
|
||
**Contexte** : En marge de l'écosystème Duniter/Ğ1, exploration des opportunités de marché autour de la visualisation de données économiques et logistiques.
|
||
|
||
---
|
||
|
||
## 1. Analyse du Marché de la Data Visualization
|
||
|
||
### Vue d'ensemble
|
||
Le marché de la visualisation de données est en pleine expansion, porté par la complexité croissante des flux d'informations et le besoin de transparence.
|
||
|
||
**Taille du marché** : En croissance constante (CAGR estimé à >10% annuel).
|
||
**Moteurs** :
|
||
- Besoin de prise de décision basée sur les données (Data-Driven Decision Making).
|
||
- Complexité des chaînes d'approvisionnement (Supply Chain).
|
||
- Demande de transparence financière et RSE (Responsabilité Sociétale des Entreprises).
|
||
|
||
### Segments Pertinents pour Laplank
|
||
|
||
1. **Visualisation de Flux Financiers Complexes (FinTech / DeFi)**
|
||
* **Besoin** : Comprendre les mouvements de fonds, la création monétaire, les graphes de transactions.
|
||
* **Cible** : DAOs, projets Blockchain, ONG, Auditeurs financiers.
|
||
* **Offre** : Dashboards interactifs de transparence, explorateurs de blockchain visuels (au-delà des simples listes de transactions).
|
||
* **Lien avec Duniter** : Utilisation possible de la blockchain pour certifier les étapes, visualisées ensuite pour le consommateur final.
|
||
|
||
2. **Transparence de la Supply Chain (Flux de Marchandises)**
|
||
* **Besoin** : Tracer l'origine et le parcours des produits (traçabilité).
|
||
* **Cible** : Coopératives, circuits courts, commerce équitable, industrie agroalimentaire.
|
||
|
||
3. **Visualisation de Réseaux et Communautés (Web of Trust)**
|
||
* **Besoin** : Cartographier les relations humaines, la confiance, la gouvernance décentralisée.
|
||
* **Cible** : Associations, collectifs, réseaux sociaux décentralisés.
|
||
|
||
---
|
||
|
||
## 2. Opportunité : Flux Économiques & Marchandises
|
||
|
||
C'est le segment le plus prometteur "en marge" de la crypto pure, car il touche l'économie réelle.
|
||
|
||
### Le Problème
|
||
- Les ERP (Enterprise Resource Planning) classiques sont austères et peu visuels.
|
||
- La donnée est silotée.
|
||
- Le consommateur ou le décideur ne "voit" pas le flux global.
|
||
|
||
### La Solution Laplank
|
||
Proposer une **plateforme de visualisation unifiée** capable de représenter graphiquement :
|
||
- **Flux monétaires** (€, Ğ1, Crypto)
|
||
- **Flux physiques** (Marchandises, Stocks, Logistique)
|
||
|
||
### Cas d'Usage Concret : "Le Circuit Court Augmenté"
|
||
Imaginez une coopérative de producteurs.
|
||
- **Input** : Données de production, transport, vente.
|
||
- **Visualisation** :
|
||
- **Carte interactive (Leaflet)** : Localisation des producteurs et trajets.
|
||
- **Graphe de flux (Sankey Diagram)** : Répartition de la valeur (combien va au producteur, au transporteur, à la coopérative). *Transparence radicale.*
|
||
- **Tableau de bord (ECharts/D3)** : Saisonnalité, stocks en temps réel.
|
||
|
||
### Avantage Concurrentiel (Différenciation)
|
||
- **Expertise Technique** : Maîtrise de technologies avancées (D3.js, Rust/Wasm pour la perf, ThreeFold pour l'hébergement souverain).
|
||
- **Approche Éthique/Souveraine** : Hébergement décentralisé (ThreeFold), pas de GAFAM, respect des données.
|
||
- **Double Compétence** : Capacité à lier Blockchain (certitude de la donnée) et DataViz (lisibilité de la donnée).
|
||
|
||
---
|
||
|
||
## 3. Modèle Économique Potentiel
|
||
|
||
1. **Service B2B (SaaS / On-Premise)**
|
||
- Abonnement pour les entreprises/coopératives souhaitant visualiser leurs données.
|
||
- Hébergement sur ThreeFold (revenus récurrents).
|
||
|
||
2. **Prestation de Conseil & Développement**
|
||
- Création de dashboards sur mesure pour des clients spécifiques.
|
||
- Audit de données et mise en qualité avant visualisation.
|
||
|
||
3. **Produit "Open Core"**
|
||
- Version de base open-source (attraction communautaire).
|
||
- Modules "Premium" pour connecteurs spécifiques (ERP propriétaires, Banques) ou fonctionnalités avancées d'analyse prédictive (IA).
|
||
|
||
---
|
||
|
||
## 4. Roadmap Business (Piste)
|
||
|
||
### Phase 1 : POC & Vitrine (6 mois)
|
||
- Utiliser l'écosystème Duniter/Ğ1 comme "Client Zéro".
|
||
- Développer l'explorateur visuel de Web of Trust et de flux monétaires.
|
||
- **Objectif** : Démontrer la capacité technique et l'impact visuel. "Rendre sexy la donnée complexe".
|
||
|
||
### Phase 2 : Extension aux Flux Physiques (6-12 mois)
|
||
- Trouver un partenaire dans l'économie réelle (ex: coopérative bio, réseau de logistique locale).
|
||
- Adapter les outils de visualisation pour tracer des produits physiques.
|
||
- **Objectif** : Valider le marché hors crypto.
|
||
|
||
### Phase 3 : Plateforme de Transparence Économique (12+ mois)
|
||
- Lancer une offre packagée.
|
||
- "Visualisez votre impact économique et écologique en temps réel".
|
||
|
||
---
|
||
|
||
## 5. Technologies Clés à Surveiller
|
||
|
||
- **Digital Twins (Jumeaux Numériques)** : Représentation virtuelle d'objets physiques.
|
||
- **IoT (Internet of Things)** : Capteurs pour alimenter les données de flux physiques.
|
||
- **Standardisation (GS1 / EPCIS)** : Normes d'échange de données logistiques.
|
||
|
||
---
|
||
|
||
## Conclusion
|
||
|
||
Le marché de la DataViz appliquée aux **flux économiques mixtes (monnaie + matière)** est une niche stratégique pertinente. Elle valorise l'expertise technique de l'équipe tout en s'ouvrant à des clients "traditionnels" cherchant transparence et optimisation. L'infrastructure ThreeFold apporte la couche de souveraineté nécessaire pour traiter ces données sensibles.`,
|
||
|
||
'dataviz': `# Opportunités d'Extension : Data Visualization
|
||
|
||
**Date** : 02/12/2025
|
||
**Objectif** : Identifier les secteurs porteurs pour l'expertise DataViz de l'équipe, au-delà des flux économiques.
|
||
|
||
---
|
||
|
||
## 1. Territoires & Open Data (Smart Cities Souveraines)
|
||
|
||
Les collectivités locales disposent de plus en plus de données (Open Data) mais manquent d'outils pour les rendre intelligibles aux citoyens.
|
||
|
||
* **Opportunité** : Créer des portails de transparence pour les mairies/collectivités.
|
||
* **Cas d'usage** :
|
||
* **Visualisation budgétaire** : "Où vont mes impôts ?" (Diagrammes de Sankey, Treemaps).
|
||
* **Urbanisme** : Cartographie des travaux, permis de construire, zones inondables.
|
||
* **Démocratie participative** : Visualiser les résultats de consultations citoyennes.
|
||
* **Synergie Technique** : Leaflet (cartes), D3.js (budgets), ThreeFold (hébergement local et souverain des données citoyennes).
|
||
|
||
## 2. Green Tech & Impact Environnemental
|
||
|
||
La mesure et la communication de l'impact écologique deviennent obligatoires (CSRD) et stratégiques.
|
||
|
||
* **Opportunité** : Tableaux de bord RSE (Responsabilité Sociétale des Entreprises) et empreinte carbone.
|
||
* **Cas d'usage** :
|
||
* **Visualisation de l'empreinte carbone** : Scope 1, 2, 3. Graphiques d'évolution.
|
||
* **Monitoring énergétique** : Visualisation temps réel de la consommation (bâtiments, serveurs). *Lien direct avec l'offre ThreeFold "Green IT".*
|
||
* **Traçabilité des déchets** : Suivre le cycle de vie des produits.
|
||
* **Synergie Technique** : IoT (capteurs), ECharts (séries temporelles), Rust (traitement performant de gros volumes de données capteurs).
|
||
|
||
## 3. Visualisation de la Connaissance (Knowledge Management)
|
||
|
||
Dans un monde infobèse, organiser et visualiser l'information est une valeur clé.
|
||
|
||
* **Opportunité** : Outils de "Second Cerveau" ou de gestion des connaissances pour entreprises/recherche.
|
||
* **Cas d'usage** :
|
||
* **Graphes de connaissances** : Visualiser les liens entre documents, personnes, projets (comme Obsidian ou Roam, mais version web/collaborative).
|
||
* **Cartographie des compétences** : Version avancée du Radar Technologique pour les RH (gestion des talents).
|
||
* **Exploration documentaire** : Naviguer visuellement dans des bases documentaires complexes (juridique, technique).
|
||
* **Synergie Technique** : Cytoscape.js (graphes), ElasticSearch/MeiliSearch (indexation), IA (pour générer les liens).
|
||
|
||
## 4. Cybersécurité & Réseaux
|
||
|
||
Visualiser l'invisible pour mieux protéger.
|
||
|
||
* **Opportunité** : Interfaces de monitoring sécurité pour PME.
|
||
* **Cas d'usage** :
|
||
* **Cartographie du réseau** : Visualiser tous les appareils connectés et leurs communications.
|
||
* **Visualisation d'attaques** : Représenter les tentatives d'intrusion en temps réel (cartes de chaleur, flux).
|
||
* **Analyse de logs** : Rendre les logs serveurs lisibles graphiquement.
|
||
* **Synergie Technique** : Rust (sondes réseau), WebGL/Canvas (visualisation haute performance), ThreeFold (réseau overlay).
|
||
|
||
---
|
||
|
||
## Matrice de Priorisation
|
||
|
||
| Secteur | Potentiel Marché | Synergie Technique Actuelle | Complexité Métier | Priorité |
|
||
| :--- | :---: | :---: | :---: | :---: |
|
||
| **Flux Éco (Business)** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | Moyenne | **1** |
|
||
| **Territoires (Smart City)** | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | Élevée (Politique) | **2** |
|
||
| **Green Tech** | ⭐⭐⭐⭐ | ⭐⭐⭐ | Moyenne | **3** |
|
||
| **Connaissance (KM)** | ⭐⭐⭐ | ⭐⭐⭐⭐ | Faible | **2** (Interne d'abord) |
|
||
| **Cybersécurité** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | Très Élevée | **4** |
|
||
|
||
## Conclusion
|
||
|
||
Si le focus principal reste les **Flux Économiques** (cohérent avec l'historique Duniter), l'axe **Territoires/Open Data** est le pivot le plus naturel : il s'agit toujours de visualiser des ressources et des flux, mais appliqués à la cité. De plus, l'argument de la "Souveraineté Numérique" (ThreeFold) y résonne très fort.`,
|
||
|
||
'dataviz-details': `# Analyse Détaillée : Opportunités DataViz, IA & Infrastructure
|
||
|
||
**Date** : 02/12/2025
|
||
**Type** : Approfondissement Technique & Business
|
||
**Réf** : Complément à \`opportunites-dataviz.md\`
|
||
|
||
Ce document détaille la faisabilité technique, les stacks recommandées et l'intégration spécifique avec l'infrastructure ThreeFold pour les opportunités identifiées.
|
||
|
||
---
|
||
|
||
## 1. Smart Cities & Territoires Souverains
|
||
|
||
Le marché des "Smart Cities" est souvent dominé par des solutions propriétaires cloud (Google, Cisco). Une approche **Open Source** et **Souveraine** est un différenciateur majeur pour les collectivités soucieuses de leurs données.
|
||
|
||
### Cas d'Usage : Le "City Dashboard" Citoyen
|
||
Un portail unique regroupant les flux de vie de la cité.
|
||
|
||
#### Fonctionnalités & Stack Technique
|
||
| Module | Fonctionnalité | Stack Technique Recommandée |
|
||
| :--- | :--- | :--- |
|
||
| **Mobilité** | Visualisation temps réel des bus/métros, vélos partagés. | **Front** : \`Deck.gl\` (haute perf pour objets mouvants) ou \`Mapbox GL JS\`.<br>**Data** : Protocole \`GTFS-RT\` (General Transit Feed Specification). |
|
||
| **Urbanisme** | Cadastre, PLU, Zones inondables, Travaux. | **Front** : \`Leaflet\` (léger, standard).<br>**Back** : \`PostGIS\` (Base de données spatiale). |
|
||
| **Démocratie** | Budget participatif interactif. | **Viz** : \`D3.js\` (Treemaps, Sunbursts pour explorer les budgets). |
|
||
|
||
#### Synergie ThreeFold (Infrastructure)
|
||
* **Edge Computing** : Les données de la ville (caméras, capteurs trafic) sont traitées sur des nœuds ThreeFold situés physiquement **dans la ville** (Mairies, Écoles).
|
||
* **Souveraineté** : Garantie que les données ne partent pas sur des serveurs étrangers (AWS/Azure). Argument politique fort.
|
||
|
||
#### Modèle Économique
|
||
* **B2G (Business to Government)** : Forfait d'installation + Maintenance annuelle.
|
||
* **Open Data Service** : API payante pour les acteurs privés (immo, logistique) qui veulent des données nettoyées et agrégées.
|
||
|
||
---
|
||
|
||
## 2. Green Tech : IoT & Pilotage Énergétique
|
||
|
||
Avec la crise énergétique et les obligations RSE (Directive CSRD), mesurer ne suffit plus, il faut piloter et visualiser pour réduire.
|
||
|
||
### Cas d'Usage : Jumeau Numérique Énergétique
|
||
Visualisation en temps réel de la consommation d'un parc immobilier ou industriel.
|
||
|
||
#### Architecture Technique
|
||
1. **Collecte (IoT)** : Capteurs (LoRaWAN, MQTT) remontent les données (Température, Conso élec).
|
||
2. **Ingestion (Rust)** : Service haute performance en Rust pour traiter des millions de points de mesure sans latence.
|
||
3. **Visualisation** :
|
||
* **Séries Temporelles** : \`Apache ECharts\` ou \`Grafana\` (si usage interne).
|
||
* **Heatmaps** : Visualiser les déperditions thermiques sur plan 2D/3D.
|
||
|
||
#### Synergie ThreeFold
|
||
* **Green IT** : Héberger la plateforme de monitoring sur ThreeFold permet d'afficher un bilan carbone numérique neutre ou négatif (si nœuds alimentés en solaire).
|
||
* **Sécurité** : Les données industrielles sensibles ne transitent pas par le cloud public.
|
||
|
||
---
|
||
|
||
## 3. Knowledge Management : Le "Cerveau d'Entreprise" (IA + Graphes)
|
||
|
||
C'est l'opportunité la plus disruptive. Transformer une base documentaire inerte en un **Graphe de Connaissances** navigable et interrogeable.
|
||
|
||
### Cas d'Usage : Assistant IA Privé & Cartographie
|
||
"Montre-moi tous les projets liés à la technologie 'Rust' et les développeurs qui y ont contribué."
|
||
|
||
#### Technologies Clés : Graph RAG (Retrieval Augmented Generation)
|
||
Au lieu de juste chercher des mots-clés, on utilise l'IA pour comprendre les relations.
|
||
|
||
* **Extraction** : Un LLM (ex: Mistral) analyse les docs et extrait les entités (Projets, Personnes, Technos) et leurs relations.
|
||
* **Visualisation** :
|
||
* **Librairie** : \`Cytoscape.js\` ou \`React Force Graph\`.
|
||
* **UX** : Navigation fluide dans le graphe. Clic sur un nœud = contexte IA.
|
||
* **Recherche** : \`MeiliSearch\` (vectorielle + sémantique).
|
||
|
||
#### Synergie ThreeFold (Private AI)
|
||
* **Confidentialité** : Les entreprises refusent d'envoyer leurs secrets industriels à ChatGPT.
|
||
* **Solution** : Déployer des modèles LLM Open Source (Llama 3, Mistral) directement sur des instances GPU/CPU ThreeFold **dédiées et isolées**.
|
||
* **Offre** : "Votre IA d'entreprise, chez vous, entraînée sur vos données, sans fuite possible."
|
||
|
||
---
|
||
|
||
## 4. Cybersécurité : Visualiser l'Invisible
|
||
|
||
La cybersécurité génère des logs massifs illisibles pour un humain. La DataViz est cruciale pour la détection d'anomalies.
|
||
|
||
### Cas d'Usage : SOC (Security Operation Center) Visuel
|
||
Interface de pilotage pour les responsables sécurité des PME.
|
||
|
||
#### Stack Technique
|
||
* **Backend** : \`Rust\` + \`eBPF\` (Extended Berkeley Packet Filter) pour capturer le trafic réseau au niveau noyau avec 0 impact sur les perfs.
|
||
* **Frontend** : \`WebGL\` (via \`Three.js\` ou \`PixiJS\`) obligatoire pour afficher des milliers de connexions simultanées (graphes de réseau) sans ralentir le navigateur.
|
||
|
||
---
|
||
|
||
## Matrice de Complexité vs Valeur
|
||
|
||
| Opportunité | Valeur Client | Complexité Tech | Maturité Marché | Recommandation |
|
||
| :--- | :---: | :---: | :---: | :---: |
|
||
| **Smart City** | ⭐⭐⭐⭐ | ⭐⭐ (Moyenne) | Mature | **Go** (Partenariats locaux) |
|
||
| **Green IoT** | ⭐⭐⭐ | ⭐⭐⭐ (Hardware) | En croissance | **Wait** (Besoin partenaire HW) |
|
||
| **KM + Private AI** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ (IA/RAG) | Émergent (Buzz) | **Prototype** (Usage interne d'abord) |
|
||
| **Cyber Viz** | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ (Très haute) | Saturé | **No Go** (Trop niché) |
|
||
|
||
## Synthèse Stratégique
|
||
|
||
1. **Court Terme (Quick Win)** : Capitaliser sur l'existant (Radar) pour proposer des **Dashboards de Transparence** (Smart City / Asso). C'est la suite logique de "Laplank".
|
||
2. **Moyen Terme (Innovation)** : Développer le **"Private AI Knowledge Graph"** sur ThreeFold. C'est un produit à très forte valeur ajoutée qui combine toutes les forces de l'équipe : DataViz + Infra Décentralisée + Souveraineté.`
|
||
};
|
||
|
||
const pageTitles = {
|
||
'strategie': 'Stratégie Technique',
|
||
'business': 'Business',
|
||
'dataviz': 'Opportunités DataViz',
|
||
'dataviz-details': 'DataViz Expert'
|
||
};
|
||
|
||
// Fonction pour convertir Markdown en HTML
|
||
function markdownToHtml(md) {
|
||
let html = md;
|
||
|
||
// Tableaux
|
||
html = html.replace(/\|(.+)\|/g, function(match) {
|
||
// Gestion basique des tableaux markdown
|
||
if (match.includes('---')) return ''; // Ignore la ligne de séparation
|
||
const cells = match.split('|').filter(c => c.trim() !== '');
|
||
const cellTag = match.includes('Secteur') || match.includes('Potentiel') || match.includes('Opportunité') || match.includes('Module') ? 'th' : 'td';
|
||
return '<tr>' + cells.map(c => `<${cellTag} style="border: 1px solid #ddd; padding: 8px; text-align: left;">${c.trim()}</${cellTag}>`).join('') + '</tr>';
|
||
});
|
||
|
||
// Envelopper les lignes de tableau dans une table si nécessaire (simplifié)
|
||
// Pour une vraie implémentation, utiliser une lib comme marked ou showdown
|
||
// Ici on fait un fix rapide pour que les tableaux s'affichent à peu près correctement
|
||
if (html.includes('<tr>')) {
|
||
// C'est très rudimentaire, idéalement on utiliserait une vraie lib
|
||
const parts = html.split('\n');
|
||
let inTable = false;
|
||
html = parts.map(line => {
|
||
if (line.startsWith('<tr>')) {
|
||
if (!inTable) {
|
||
inTable = true;
|
||
return '<table style="border-collapse: collapse; width: 100%; margin: 20px 0;">' + line;
|
||
}
|
||
return line;
|
||
} else {
|
||
if (inTable && line.trim() === '') {
|
||
inTable = false;
|
||
return '</table>';
|
||
}
|
||
return line;
|
||
}
|
||
}).join('\n');
|
||
if (inTable) html += '</table>';
|
||
}
|
||
|
||
// Titres
|
||
html = html.replace(/^# (.*$)/gim, '<h1>$1</h1>');
|
||
html = html.replace(/^## (.*$)/gim, '<h2>$1</h2>');
|
||
html = html.replace(/^### (.*$)/gim, '<h3>$1</h3>');
|
||
html = html.replace(/^#### (.*$)/gim, '<h4>$1</h4>');
|
||
|
||
// Gras et italique
|
||
html = html.replace(/\*\*(.*?)\*\*/gim, '<strong>$1</strong>');
|
||
html = html.replace(/\*(.*?)\*/gim, '<em>$1</em>');
|
||
|
||
// Listes
|
||
html = html.replace(/^- (.*$)/gim, '<li>$1</li>');
|
||
html = html.replace(/^\d+\. (.*$)/gim, '<li>$1</li>');
|
||
|
||
// Séparateurs
|
||
html = html.replace(/^---$/gim, '<hr>');
|
||
|
||
// Paragraphes
|
||
html = html.split('\n\n').map(block => {
|
||
const trimmed = block.trim();
|
||
if (!trimmed) return '';
|
||
if (trimmed.startsWith('<h') || trimmed.startsWith('<ul') || trimmed.startsWith('<li') || trimmed.startsWith('<hr') || trimmed.startsWith('<table') || trimmed.startsWith('<tr') || trimmed.startsWith('</table')) {
|
||
return block;
|
||
}
|
||
return '<p>' + trimmed + '</p>';
|
||
}).join('\n');
|
||
|
||
// Grouper les listes
|
||
html = html.replace(/(<li>.*?<\/li>(\s*<li>.*?<\/li>)*)/gim, function(match) {
|
||
return '<ul>' + match + '</ul>';
|
||
});
|
||
html = html.replace(/<\/ul>\s*<ul>/gim, '');
|
||
|
||
return html;
|
||
}
|
||
|
||
// Protection contre les exécutions multiples
|
||
let isInitialized = false;
|
||
let initTimeout = null;
|
||
|
||
function initStrategyLinks() {
|
||
// Éviter les exécutions multiples
|
||
if (isInitialized) return;
|
||
|
||
// Annuler toute tentative d'initialisation en cours
|
||
if (initTimeout) {
|
||
clearTimeout(initTimeout);
|
||
initTimeout = null;
|
||
}
|
||
|
||
// Marquer comme initialisé immédiatement
|
||
isInitialized = true;
|
||
|
||
addLinksToHeader();
|
||
handleRoute();
|
||
}
|
||
|
||
function normalizePath(pathname) {
|
||
if (!pathname) return '/';
|
||
const cleaned = pathname.replace(/\/+$/, '');
|
||
return cleaned === '' ? '/' : cleaned;
|
||
}
|
||
|
||
function handleRoute() {
|
||
const path = normalizePath(window.location.pathname);
|
||
const hash = window.location.hash;
|
||
|
||
// Détection simple
|
||
if (hash === '#strategie' || path === '/strategie') showPage('strategie');
|
||
else if (hash === '#business' || path === '/business') showPage('business');
|
||
else if (hash === '#dataviz' || path === '/dataviz') showPage('dataviz');
|
||
else if (hash === '#dataviz-details' || path === '/dataviz-details') showPage('dataviz-details');
|
||
}
|
||
|
||
function showPage(pageId) {
|
||
if (!pagesContent[pageId]) return;
|
||
|
||
if (!window.originalBodyContent) {
|
||
window.originalBodyContent = document.body.innerHTML;
|
||
}
|
||
|
||
const htmlContent = markdownToHtml(pagesContent[pageId]);
|
||
|
||
document.body.innerHTML = `
|
||
<div style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; background: #f5f5f5; min-height: 100vh;">
|
||
<div style="background: white; padding: 40px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
|
||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
|
||
<a href="#" id="back-to-radar" style="color: #2ecc71; text-decoration: none; font-weight: bold; cursor: pointer; font-size: 1.1em;">← Retour au Radar</a>
|
||
<div style="display: flex; gap: 15px;">
|
||
${Object.keys(pageTitles).map(key =>
|
||
`<a href="#${key}" class="nav-link" data-page="${key}" style="color: ${key === pageId ? '#1a4d3a' : '#2ecc71'}; text-decoration: ${key === pageId ? 'underline' : 'none'}; font-weight: bold; cursor: pointer;">${pageTitles[key]}</a>`
|
||
).join('')}
|
||
</div>
|
||
</div>
|
||
<div id="page-content" style="line-height: 1.8; color: #333;">
|
||
${htmlContent}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
// Styles
|
||
styleContent();
|
||
|
||
// Event listeners
|
||
document.getElementById('back-to-radar').addEventListener('click', function(e) {
|
||
e.preventDefault();
|
||
if (window.originalBodyContent) {
|
||
document.body.innerHTML = window.originalBodyContent;
|
||
window.history.pushState(null, null, '/');
|
||
// Réinitialiser le flag pour permettre la réinitialisation
|
||
isInitialized = false;
|
||
if (initTimeout) clearTimeout(initTimeout);
|
||
initTimeout = setTimeout(initStrategyLinks, 100);
|
||
} else {
|
||
window.location.href = '/';
|
||
}
|
||
});
|
||
|
||
document.querySelectorAll('.nav-link').forEach(link => {
|
||
link.addEventListener('click', function(e) {
|
||
e.preventDefault();
|
||
const target = this.getAttribute('data-page');
|
||
showPage(target);
|
||
});
|
||
});
|
||
|
||
window.history.pushState({page: pageId}, pageTitles[pageId], `/${pageId}`);
|
||
}
|
||
|
||
function styleContent() {
|
||
const contentDiv = document.getElementById('page-content');
|
||
if (!contentDiv) return;
|
||
|
||
contentDiv.querySelectorAll('h1').forEach(h => {
|
||
h.style.color = '#1a4d3a';
|
||
h.style.borderBottom = '3px solid #2ecc71';
|
||
h.style.paddingBottom = '10px';
|
||
h.style.marginTop = '30px';
|
||
});
|
||
contentDiv.querySelectorAll('h2').forEach(h => {
|
||
h.style.color = '#2ecc71';
|
||
h.style.marginTop = '30px';
|
||
h.style.marginBottom = '15px';
|
||
});
|
||
contentDiv.querySelectorAll('h3').forEach(h => {
|
||
h.style.color = '#3498db';
|
||
h.style.marginTop = '20px';
|
||
});
|
||
contentDiv.querySelectorAll('ul, ol').forEach(l => {
|
||
l.style.marginLeft = '20px';
|
||
l.style.marginBottom = '15px';
|
||
});
|
||
contentDiv.querySelectorAll('li').forEach(li => {
|
||
li.style.marginBottom = '5px';
|
||
});
|
||
contentDiv.querySelectorAll('p').forEach(p => {
|
||
p.style.marginBottom = '15px';
|
||
});
|
||
contentDiv.querySelectorAll('a').forEach(a => {
|
||
a.style.color = '#2ecc71';
|
||
a.style.textDecoration = 'none';
|
||
});
|
||
}
|
||
|
||
function addLinksToHeader() {
|
||
// Chercher le header
|
||
const header = document.querySelector('header') ||
|
||
document.querySelector('nav') ||
|
||
document.querySelector('div[role="banner"]');
|
||
|
||
let container = header;
|
||
|
||
// Si pas de header, créer une barre fixe
|
||
if (!header) {
|
||
let fixedBar = document.getElementById('custom-nav-bar');
|
||
if (!fixedBar) {
|
||
fixedBar = document.createElement('div');
|
||
fixedBar.id = 'custom-nav-bar';
|
||
fixedBar.style.cssText = 'position: fixed; top: 0; right: 0; padding: 10px 20px; z-index: 9999; display: flex; gap: 15px; background: rgba(255,255,255,0.9); border-bottom-left-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);';
|
||
document.body.appendChild(fixedBar);
|
||
}
|
||
container = fixedBar;
|
||
} else {
|
||
// Créer un conteneur pour nos liens s'il n'existe pas
|
||
let linkContainer = header.querySelector('#custom-nav-container');
|
||
if (!linkContainer) {
|
||
linkContainer = document.createElement('div');
|
||
linkContainer.id = 'custom-nav-container';
|
||
linkContainer.style.cssText = 'display: flex; gap: 15px; margin-left: auto; align-items: center; padding-right: 20px;';
|
||
header.appendChild(linkContainer);
|
||
}
|
||
container = linkContainer;
|
||
}
|
||
|
||
// Ajouter le lien vers la page Équipe (vérifier s'il n'existe pas déjà)
|
||
if (!document.getElementById('link-team')) {
|
||
const teamLink = document.createElement('a');
|
||
teamLink.id = 'link-team';
|
||
teamLink.className = 'custom-nav-link';
|
||
teamLink.href = '/team.html';
|
||
teamLink.textContent = '👥 Équipe';
|
||
teamLink.style.cssText = 'color: #2ecc71; text-decoration: none; font-weight: bold; cursor: pointer; font-size: 14px; padding: 5px 8px; border-radius: 4px; transition: background 0.2s;';
|
||
teamLink.addEventListener('mouseenter', () => teamLink.style.background = 'rgba(46, 204, 113, 0.1)');
|
||
teamLink.addEventListener('mouseleave', () => teamLink.style.background = 'transparent');
|
||
// Insérer au début du conteneur (ou à la fin si firstChild est null)
|
||
if (container.firstChild) {
|
||
container.insertBefore(teamLink, container.firstChild);
|
||
} else {
|
||
container.appendChild(teamLink);
|
||
}
|
||
console.log('✅ Lien Équipe ajouté au header');
|
||
} else {
|
||
console.log('ℹ️ Lien Équipe existe déjà');
|
||
}
|
||
|
||
// Ajouter les liens des pages de stratégie
|
||
Object.keys(pageTitles).forEach(key => {
|
||
if (document.getElementById(`link-${key}`)) return;
|
||
|
||
const link = document.createElement('a');
|
||
link.id = `link-${key}`;
|
||
link.className = 'custom-nav-link';
|
||
link.href = `#${key}`;
|
||
link.textContent = pageTitles[key];
|
||
link.style.cssText = 'color: #2ecc71; text-decoration: none; font-weight: bold; cursor: pointer; font-size: 14px; padding: 5px 8px; border-radius: 4px; transition: background 0.2s;';
|
||
|
||
link.addEventListener('mouseenter', () => link.style.background = 'rgba(46, 204, 113, 0.1)');
|
||
link.addEventListener('mouseleave', () => link.style.background = 'transparent');
|
||
|
||
link.addEventListener('click', (e) => {
|
||
e.preventDefault();
|
||
showPage(key);
|
||
});
|
||
|
||
container.appendChild(link);
|
||
});
|
||
}
|
||
|
||
window.addEventListener('popstate', function(event) {
|
||
if (event.state && event.state.page) {
|
||
showPage(event.state.page);
|
||
} else if (window.originalBodyContent) {
|
||
document.body.innerHTML = window.originalBodyContent;
|
||
// Réinitialiser le flag pour permettre la réinitialisation
|
||
isInitialized = false;
|
||
if (initTimeout) clearTimeout(initTimeout);
|
||
initTimeout = setTimeout(initStrategyLinks, 100);
|
||
}
|
||
});
|
||
|
||
// --- EXÉCUTION AU CHARGEMENT DE LA PAGE ---
|
||
// Déplacé à la fin pour s'assurer que toutes les fonctions et variables sont définies
|
||
// Protection globale contre les exécutions multiples
|
||
if (window.__strategieScriptLoaded) {
|
||
return; // Script déjà chargé, ne pas réexécuter
|
||
}
|
||
window.__strategieScriptLoaded = true;
|
||
|
||
// Éviter de modifier document.documentElement qui peut déclencher des rechargements Fast Refresh
|
||
// Attendre que le DOM soit complètement chargé, y compris le header
|
||
function initWhenReady() {
|
||
// Vérifier si le header existe, sinon attendre un peu
|
||
const header = document.querySelector('header') ||
|
||
document.querySelector('nav') ||
|
||
document.querySelector('div[role="banner"]');
|
||
|
||
if (header || document.body) {
|
||
checkAuth();
|
||
// Délai pour s'assurer que le header est complètement rendu
|
||
setTimeout(() => {
|
||
initStrategyLinks();
|
||
}, 100);
|
||
} else {
|
||
// Réessayer après un court délai
|
||
setTimeout(initWhenReady, 50);
|
||
}
|
||
}
|
||
|
||
if (document.readyState === 'loading') {
|
||
document.addEventListener('DOMContentLoaded', initWhenReady);
|
||
} else {
|
||
initWhenReady();
|
||
}
|
||
})();
|