From c7db6590f091da8973c801b59910f4d429960f39 Mon Sep 17 00:00:00 2001 From: Nicolas Cantu Date: Tue, 9 Dec 2025 19:09:42 +0100 Subject: [PATCH] Initial commit: 4NK Waste & Water Simulator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Motivations :** * Create a complete simulator for 4NK Waste & Water modular waste treatment infrastructure * Implement frontend-only application with client-side data persistence * Provide seed data for wastes and natural regulators from specifications **Root causes :** * Need for a simulation tool to configure and manage waste treatment projects * Requirement for localhost-only access with persistent client-side storage * Need for initial seed data to bootstrap the application **Correctifs :** * Implemented authentication system with AuthContext * Fixed login/logout functionality with proper state management * Created placeholder pages for all routes **Evolutions :** * Complete application structure with React, TypeScript, and Vite * Seed data for 9 waste types and 52 natural regulators * Settings page with import/export and seed data loading functionality * Configuration pages for wastes and regulators with CRUD operations * Project management pages structure * Business plan and yields pages placeholders * Comprehensive UI/UX design system (dark mode only) * Navigation system with sidebar and header **Page affectées :** * All pages: Login, Dashboard, Waste Configuration, Regulators Configuration, Services Configuration * Project pages: Project List, Project Configuration, Treatment Sites, Waste Sites, Investors, Administrative Procedures * Analysis pages: Yields, Business Plan * Utility pages: Settings, Help * Components: Layout, Sidebar, Header, base components (Button, Input, Select, Card, Badge, Table) * Utils: Storage, seed data, formatters, validators, constants * Types: Complete TypeScript definitions for all entities --- .gitignore | 24 + README.md | 96 + Régulateurs (1).md | 2439 +++++++++++++++++ data_schemas.md | 406 +++ formulas_reference.md | 507 ++++ index.html | 13 + missing_elements.md | 378 +++ package-lock.json | 1729 ++++++++++++ package.json | 23 + specification.md | 1789 ++++++++++++ src/App.tsx | 56 + src/components/base/Badge.css | 62 + src/components/base/Badge.tsx | 10 + src/components/base/Button.css | 49 + src/components/base/Button.tsx | 15 + src/components/base/Card.css | 20 + src/components/base/Card.tsx | 17 + src/components/base/Input.css | 60 + src/components/base/Input.tsx | 33 + src/components/base/Select.css | 57 + src/components/base/Select.tsx | 40 + src/components/base/Table.css | 46 + src/components/base/Table.tsx | 51 + src/components/layout/Header.css | 72 + src/components/layout/Header.tsx | 44 + src/components/layout/Layout.css | 18 + src/components/layout/Layout.tsx | 22 + src/components/layout/Sidebar.css | 71 + src/components/layout/Sidebar.tsx | 76 + src/contexts/AuthContext.tsx | 55 + src/data/seedRegulators.ts | 863 ++++++ src/data/seedWastes.ts | 114 + src/hooks/useAuth.ts | 40 + src/hooks/useStorage.ts | 74 + src/index.css | 90 + src/main.tsx | 27 + src/pages/BusinessPlanPage.css | 204 ++ src/pages/BusinessPlanPage.tsx | 463 ++++ src/pages/DashboardPage.css | 117 + src/pages/DashboardPage.tsx | 80 + src/pages/HelpPage.css | 57 + src/pages/HelpPage.tsx | 56 + src/pages/LoginPage.css | 107 + src/pages/LoginPage.tsx | 85 + src/pages/SettingsPage.css | 95 + src/pages/SettingsPage.tsx | 165 ++ src/pages/YieldsPage.css | 84 + src/pages/YieldsPage.tsx | 188 ++ .../RegulatorsConfigurationPage.css | 35 + .../RegulatorsConfigurationPage.tsx | 206 ++ .../ServicesConfigurationPage.css | 56 + .../ServicesConfigurationPage.tsx | 213 ++ .../configuration/WasteConfigurationPage.css | 42 + .../configuration/WasteConfigurationPage.tsx | 238 ++ .../projects/AdministrativeProceduresPage.css | 35 + .../projects/AdministrativeProceduresPage.tsx | 201 ++ src/pages/projects/InvestorsPage.css | 35 + src/pages/projects/InvestorsPage.tsx | 278 ++ .../projects/ProjectConfigurationPage.css | 82 + .../projects/ProjectConfigurationPage.tsx | 390 +++ src/pages/projects/ProjectListPage.css | 36 + src/pages/projects/ProjectListPage.tsx | 106 + src/pages/projects/TreatmentSitesPage.css | 56 + src/pages/projects/TreatmentSitesPage.tsx | 233 ++ src/pages/projects/WasteSitesPage.css | 35 + src/pages/projects/WasteSitesPage.tsx | 305 +++ src/types/index.ts | 262 ++ src/utils/calculations/yields.ts | 108 + src/utils/constants.ts | 299 ++ src/utils/formatters.ts | 21 + src/utils/seedData.ts | 32 + src/utils/storage.ts | 103 + src/utils/validators.ts | 52 + src/vite-env.d.ts | 1 + tsconfig.json | 36 + tsconfig.node.json | 10 + user_workflow.md | 334 +++ vite.config.ts | 18 + 78 files changed, 15045 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 Régulateurs (1).md create mode 100644 data_schemas.md create mode 100644 formulas_reference.md create mode 100644 index.html create mode 100644 missing_elements.md create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 specification.md create mode 100644 src/App.tsx create mode 100644 src/components/base/Badge.css create mode 100644 src/components/base/Badge.tsx create mode 100644 src/components/base/Button.css create mode 100644 src/components/base/Button.tsx create mode 100644 src/components/base/Card.css create mode 100644 src/components/base/Card.tsx create mode 100644 src/components/base/Input.css create mode 100644 src/components/base/Input.tsx create mode 100644 src/components/base/Select.css create mode 100644 src/components/base/Select.tsx create mode 100644 src/components/base/Table.css create mode 100644 src/components/base/Table.tsx create mode 100644 src/components/layout/Header.css create mode 100644 src/components/layout/Header.tsx create mode 100644 src/components/layout/Layout.css create mode 100644 src/components/layout/Layout.tsx create mode 100644 src/components/layout/Sidebar.css create mode 100644 src/components/layout/Sidebar.tsx create mode 100644 src/contexts/AuthContext.tsx create mode 100644 src/data/seedRegulators.ts create mode 100644 src/data/seedWastes.ts create mode 100644 src/hooks/useAuth.ts create mode 100644 src/hooks/useStorage.ts create mode 100644 src/index.css create mode 100644 src/main.tsx create mode 100644 src/pages/BusinessPlanPage.css create mode 100644 src/pages/BusinessPlanPage.tsx create mode 100644 src/pages/DashboardPage.css create mode 100644 src/pages/DashboardPage.tsx create mode 100644 src/pages/HelpPage.css create mode 100644 src/pages/HelpPage.tsx create mode 100644 src/pages/LoginPage.css create mode 100644 src/pages/LoginPage.tsx create mode 100644 src/pages/SettingsPage.css create mode 100644 src/pages/SettingsPage.tsx create mode 100644 src/pages/YieldsPage.css create mode 100644 src/pages/YieldsPage.tsx create mode 100644 src/pages/configuration/RegulatorsConfigurationPage.css create mode 100644 src/pages/configuration/RegulatorsConfigurationPage.tsx create mode 100644 src/pages/configuration/ServicesConfigurationPage.css create mode 100644 src/pages/configuration/ServicesConfigurationPage.tsx create mode 100644 src/pages/configuration/WasteConfigurationPage.css create mode 100644 src/pages/configuration/WasteConfigurationPage.tsx create mode 100644 src/pages/projects/AdministrativeProceduresPage.css create mode 100644 src/pages/projects/AdministrativeProceduresPage.tsx create mode 100644 src/pages/projects/InvestorsPage.css create mode 100644 src/pages/projects/InvestorsPage.tsx create mode 100644 src/pages/projects/ProjectConfigurationPage.css create mode 100644 src/pages/projects/ProjectConfigurationPage.tsx create mode 100644 src/pages/projects/ProjectListPage.css create mode 100644 src/pages/projects/ProjectListPage.tsx create mode 100644 src/pages/projects/TreatmentSitesPage.css create mode 100644 src/pages/projects/TreatmentSitesPage.tsx create mode 100644 src/pages/projects/WasteSitesPage.css create mode 100644 src/pages/projects/WasteSitesPage.tsx create mode 100644 src/types/index.ts create mode 100644 src/utils/calculations/yields.ts create mode 100644 src/utils/constants.ts create mode 100644 src/utils/formatters.ts create mode 100644 src/utils/seedData.ts create mode 100644 src/utils/storage.ts create mode 100644 src/utils/validators.ts create mode 100644 src/vite-env.d.ts create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json create mode 100644 user_workflow.md create mode 100644 vite.config.ts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/README.md b/README.md new file mode 100644 index 0000000..83df84e --- /dev/null +++ b/README.md @@ -0,0 +1,96 @@ +# 4NK Waste & Water - Simulator + +Modular waste treatment infrastructure simulator for 4NK Waste & Water. + +## Technology Stack + +- **React** (latest version) +- **TypeScript** +- **React Router** (for routing) +- **Vite** (development server only, no build tool for production) +- **No state management library** (use React useState, useContext) + +## Development + +### Prerequisites + +- Node.js (latest LTS version) +- npm, yarn, or pnpm + +### Installation + +```bash +npm install +# or +yarn install +# or +pnpm install +``` + +### Run Development Server + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +``` + +The application will be available at `http://localhost:3000` + +**Important**: The application can only be accessed from localhost (127.0.0.1). Access from other hosts will be blocked. + +## Project Structure + +``` +/src + /components + /base # Base reusable components + /composite # Composite components + /layout # Layout components (Header, Sidebar) + /shared # Shared business logic components + /pages # Page components + /hooks # Custom React hooks + /utils + /calculations # Calculation functions + /formatters # Data formatting + /validators # Validation functions + /constants # Constants and default values + /types # TypeScript type definitions + /data # Seed data (optional) +``` + +## Features + +- Waste configuration +- Natural regulators configuration +- Services configuration +- Project management +- Treatment sites management +- Waste sites management +- Investors management +- Administrative procedures +- Yields calculation and display +- Business plan with 10-year projections +- Data export/import (JSON) + +## Data Storage + +All data is stored locally in the browser using localStorage. No backend is required. + +- Storage key: `4nkwaste_simulator_data` +- User session: `4nkwaste_simulator_user` +- Data format: JSON + +## Documentation + +- **Specification**: `specification.md` +- **Data Schemas**: `data_schemas.md` +- **Formulas Reference**: `formulas_reference.md` +- **User Workflow**: `user_workflow.md` +- **Constants**: `constants.ts` + +## License + +Private project - 4NK Waste & Water diff --git a/Régulateurs (1).md b/Régulateurs (1).md new file mode 100644 index 0000000..1d07460 --- /dev/null +++ b/Régulateurs (1).md @@ -0,0 +1,2439 @@ +# Régulateurs + +## **Étude de conception de 5 écosystèmes symbiotiques optimisés autour des objectifs fonctionnels du système 4NK** + +### **Objectif général de l’étude** + +Créer, pour chaque finalité stratégique (réduction des gaz, eau agricole, fertilisant, gaz en bouteilles, bitcoins), un **écosystème intégré** combinant traitements, régulateurs, vecteurs énergétiques et co-produits, avec une logique **de symbiose inter-modulaire** et de **valorisation thermodynamique maximale**. + +Chaque écosystème sera composé de **5 modules** complémentaires (traitement, régénération, valorisation, conversion, sortie), articulés comme un **cycle thermodynamique optimisé**, fondé sur : + +- La lecture de l'information contenue dans les excès (CO₂, déchets, chaleur, matière, entropie) +- La transformation de ces excès par des traitements biologiques spécifiques +- La valorisation directe de l'énergie, de la matière ou de l’information régénérée + +## PLAN DE CLASSEMENT DES RÉGULATEURS PAR TRAITEMENT + +### Partie **commune à toutes les méthanisations** (température ambiante & 55 °C) + +#### **Régulateurs physico-chimiques de l’environnement de digestion** + +- **Gypse** : réduction sodium, chlore, conductivité +- **Biochar** : adsorption des impuretés organiques ou métalliques +- **Aiguilles de pin** : régulation acide douce (pH) +- **Cendres** : tampon alcalin, ajustement du pH +- **CO₂ (ajout ou issu du générateur)** : régulation de la pression et du ratio CH₄/CO₂ +- **H₂ (issu du traitement UV-C)** : réduction du CO₂ (réacteur Sabatier) +- **O₃ (ozonification de cuves)** : désinfection ponctuelle +- **Déchets de STEP sableux** : support microbiologique +- **Glucose (fruits)** : substrat carboné facilement assimilable +- **Digesta** : apport microbien recyclé ou régulation de l'activité enzymatique + +#### **Bactéries universellement utiles en méthanisation** (toutes températures) + +- *Clostridium butyricum* +- *Clostridium acetobutylicum* +- *Enterobacter aerogenes* +- *Desulfobacter postgatei* +- *Lactobacillus spp.* +- *Bacillus subtilis* +- *Enterococcus faecium* +- *Paenibacillus polymyxa* +- *Paracoccus denitrificans* +- *Streptomyces spp.* + +### 1. Méthanisation "sèche" à température ambiante (prétraitement hygiénique + séparation) 30j + +#### **Objectifs** : + +- Démarrage rapide de la digestion +- Correction du C/N +- Réduction des odeurs et pathogènes +- Activation microbiologique + +#### **Régulateurs spécifiques** : + +- *Lactobacillus plantarum* +- *Corynebacterium glutamicum* +- *Mycobacterium smegmatis* +- *Bacillus megaterium* +- **Glucose** (fruits) pour substrat +- **Digesta** : relance biologique +- **Régulateur CO₂ du générateur** : pression tampon + +### 2. Traitement **algues, larves, bactéries** (30 j à 25 °C) + +#### **Objectifs** : + +- Biofiltration des graisses, métaux légers, antibiotiques +- Fixation du CO₂ +- Prétraitement des déchets azotés + +#### **Régulateurs spécifiques** : + +- *Scenedesmus obliquus* +- *Nannochloropsis oculata* +- *Chlorella vulgaris* +- *Pseudomonas fluorescens* +- *Pseudomonas putida* +- *Gluconobacter oxydans* +- *Rhodobacter sphaeroides*, *Rhodospirillum rubrum* +- **H₂**, **CO₂** : activateurs photo-microbiens + +### 3. Traitement **champignons, vers, bactéries** (30 j à 12 °C) + +#### **Objectifs** : + +- Dégradation lignine, cellulose, microplastiques +- Stabilisation des graisses +- Bioremédiation antibactérienne/fongique + +#### **Régulateurs spécifiques** : + +- *Ganoderma* +- *Pleurotus spp.* +- *Penicillium chrysogenum* +- *Aspergillus niger* +- *Eisenia fetida* +- *Lumbricus rubellus* +- *Streptomyces spp.* (fongicide et ligninolyse) + +### 4. Traitement **plantes, vers, bactéries** (30 j à 22 °C) + +#### **Objectifs** : + +- Fixation azote (sols), bioremédiation organochlorés +- Stabilisation des métaux lourds +- Réduction nitrates et surfactants + +#### **Régulateurs spécifiques** : + +- **Plantes bioindicatrices / phytoextratrices** : + - Fougère + - Ray-grass + - Trèfle blanc + - Moutarde indienne +- *Glomus spp.* (symbiose racinaire) +- *Nitrosomonas europaea*, *Nitrobacter winogradskyi* (nitrification) +- *Bacillus megaterium* +- *Eisenia fetida*, *Lumbricus rubellus* + +### 5. Méthanisation "sèche" à 55 °C (thermophile) 30j + +#### **Objectifs** : + +- Production maximale de biogaz +- Destruction des pathogènes restants +- Réduction ultime des volumes + +#### **Régulateurs spécifiques** : + +- *Clostridium spp.* (haut rendement CH₄) +- *Bacillus subtilis* (résistance thermique) +- *Lactobacillus spp.* +- *Myxococcus xanthus* (structuration biofilm) +- **H₂** (réacteur Sabatier) +- **Cendres**, **CO₂**, **Biochar**, **Digesta** : stabilisation thermochimique + +## Partie **commune à toutes les méthanisations** (température ambiante & 55 °C) + +Voici les premières fiches détaillées des régulateurs **communs à toutes les méthanisations** (température ambiante et 55 °C), selon le formalisme demandé : + +**Gypse** +Type : Régulateur physico-chimique minéral (sulfate de calcium hydraté) +Température min/max : 5 °C / 70 °C +Taux d'humidité min/max : 30 % / 95 % +Résistance/durabilité : Très durable, non biodégradable +Profondeur de matière requise : Mélangé à cœur ou en surface (≥ 20 cm) +Effet recherché : Réduction de la concentration en sodium (Na⁺), chlore (Cl⁻), conductivité ; floculation partielle des colloïdes ; régulation ionique +Collecte / Approvisionnement : Résidus de plâtre non traité, sous-produits de carrière, déchets industriels du BTP triés +Conditions de mise en œuvre : Poudre ou granulé sec à doser en fonction du taux de salinité mesuré ; préhydratation facultative +Efficacité : Élevée si bien mélangé, effet rapide (1 à 3 jours) +Efficience : Très bonne en correction ciblée (faible coût, faible volume) + +**Biochar** +Type : Support physico-chimique poreux, char résiduel issu de pyrolyse lente +Température min/max : 0 °C / 70 °C +Taux d'humidité min/max : 10 % / 70 % +Résistance/durabilité : Très stable (> 10 ans), insoluble +Profondeur de matière requise : Dispersé sur 10–30 cm de profondeur, ou en inclusion dans digesta +Effet recherché : Adsorption des impuretés, métaux lourds, composés volatils ou organochlorés ; microstructure favorable aux biofilms +Collecte / Approvisionnement : Pyrolyse de déchets agricoles ligneux, rebuts de bois non traités +Conditions de mise en œuvre : Sec, broyé ou granulé fin ; intégré par brassage ou dispersion ciblée +Efficacité : Élevée si correctement fractionné ; effet à moyen/long terme +Efficience : Très bonne, action synergique sur filtration, odeurs et support bactérien + +**Glucose (fruits)** +Type : Substrat biochimique soluble, sucre simple à haute biodisponibilité +Température min/max : 10 °C / 65 °C +Taux d'humidité min/max : 60 % / 98 % +Résistance/durabilité : Faible (très rapidement métabolisé) +Profondeur de matière requise : 5 à 15 cm selon homogénéité du mélange +Effet recherché : Apport immédiat de carbone pour bactéries acidogènes ; démarrage rapide de fermentation +Collecte / Approvisionnement : Fruits invendus ou endommagés, jus périmés, sirops périssables, substrats alimentaires riches en sucres simples +Conditions de mise en œuvre : Incorporé en solution ou purée, bien mélangé dans les premières 24 h +Efficacité : Très élevée sur amorçage ou choc de redémarrage +Efficience : Moyenne à bonne selon disponibilité locale ; idéal en complément de substrat sec + +**Aiguilles de pin (pH)** +Type : Substrat végétal acidifiant naturel +Température min/max : 5 °C / 60 °C +Taux d'humidité min/max : 15 % / 85 % +Résistance/durabilité : Moyenne (biodégradation lente, lignine élevée) +Profondeur de matière requise : 10 à 25 cm de dispersion ou paillage superficiel +Effet recherché : Réduction douce du pH, rééquilibrage de substrats trop alcalins ; effet antifongique léger +Collecte / Approvisionnement : Forêts de résineux, entretien de parcs, déchets de tonte ou broyage +Conditions de mise en œuvre : Sec ou légèrement humidifié, pré-broyé si possible, en mélange progressif +Efficacité : Moyenne, action tampon progressive +Efficience : Bonne en zones forestières, très bon ratio disponibilité/coût + +**CO₂ (source générateur ou apport externe)** +Type : Régulateur gazeux tampon (atmosphère et substrat) +Température min/max : Applicable sur toute plage de méthanisation (5 °C / 70 °C) +Taux d'humidité min/max : n/a (gazeux) +Résistance/durabilité : Instantané, effet transitoire +Profondeur de matière requise : Mélange dans la phase gazeuse du digesteur ou dissolution partielle dans l’effluent +Effet recherché : Ajustement du rapport CH₄/CO₂ ; maintien de la pression ; activation bactéries photosynthétiques (si couplé à algues) +Collecte / Approvisionnement : Échappement générateur thermique, fermentation secondaire, bouteilles industrielles +Conditions de mise en œuvre : Injection contrôlée dans digesteur fermé ; surveillance manométrique +Efficacité : Bonne en complément d’un système stabilisé +Efficience : Moyenne ; dépend du taux de captation réelle + +**H₂ (gaz)** +Type : Gaz réducteur issu du traitement UV-C ou électrolyse locale +Température min/max : 15 °C / 65 °C +Taux d'humidité min/max : n/a (gazeux) +Résistance/durabilité : Transitoire, forte réactivité +Profondeur de matière requise : Mélange dans la zone supérieure du digesteur, avec agitation douce +Effet recherché : Réduction chimique du CO₂ en CH₄ (réaction Sabatier) ; stimulation de certaines bactéries méthanogènes +Collecte / Approvisionnement : Produit par catalyse UV-C de l’eau ou micro-électrolyse basse puissance +Conditions de mise en œuvre : Injection à faible débit dans environnement anaérobie strict, à température stabilisée +Efficacité : Très élevée en réaction ciblée (rendement CH₄) +Efficience : Bonne si couplé à énergie excédentaire (solaire, thermique) + +**Cendres (pH)** +Type : Régulateur minéral alcalin (carbonate, oxydes) +Température min/max : 5 °C / 70 °C +Taux d'humidité min/max : 10 % / 70 % +Résistance/durabilité : Moyenne (solubilité progressive selon composition) +Profondeur de matière requise : Intégration homogène à 10–30 cm +Effet recherché : Augmentation pH, neutralisation acidité excessive, reminéralisation partielle +Collecte / Approvisionnement : Résidus de combustion bois, foyers, chaudières à biomasse ; tamisage obligatoire +Conditions de mise en œuvre : Sec, broyé fin, incorporé lentement ; dosage en fonction du pH du digesta +Efficacité : Élevée si bien dosée ; action rapide +Efficience : Très bonne en zone rurale avec chauffage bois + +**Déchets STEP sableux** +Type : Support bactérien inerte, sables et agrégats grossiers +Température min/max : 5 °C / 60 °C +Taux d'humidité min/max : 10 % / 80 % +Résistance/durabilité : Très haute (inerte, non dégradable) +Profondeur de matière requise : Couche basale ou mélange 10–30 cm +Effet recherché : Création de microstructures portantes, fixation bactérienne, inertage des substrats colmatants +Collecte / Approvisionnement : Curage de dégrilleurs et désemboueurs de STEP, tamisage et désinfection nécessaires +Conditions de mise en œuvre : Sable sec ou semi-sec, intégré en phase de remplissage de cuve +Efficacité : Moyenne à élevée sur stabilité physique +Efficience : Excellente en réutilisation locale, nécessite un tri préalable + +### **Bactéries communes à toutes les méthanisations** + +Très bien. Voici la suite complète du lot **bactéries communes à toutes les méthanisations**, avec un vrai saut de ligne entre chaque fiche, sans ligne horizontale ni retour ligne simple : + +**Clostridium butyricum** +Type: Bactérie anaérobie stricte, fermentative (acide butyrique) +Température min/max: 20 °C / 55 °C +Taux d'humidité min/max: 75 % / 98 % +Résistance/durabilité: Bonne en milieu anaérobie, forme des spores résistantes +Profondeur de matière requise: Uniformément répartie, optimale à ≥ 15 cm +Effet recherché: Production d’acide butyrique à partir de sucres simples, amorçage acidogène +Collecte / Approvisionnement: Cultures pures issues de souches commerciales, digestats jeunes, contenus de rumen +Conditions de mise en œuvre: Inoculation sous atmosphère anaérobie stricte, dans substrat riche en glucides +Efficacité: Élevée en présence de substrats sucrés et température > 30 °C +Efficience: Très bonne en inoculation initiale ou relance de phase acidogène + +**Clostridium acetobutylicum** +Type: Bactérie anaérobie stricte, fermentative mixte (acides et solvants) +Température min/max: 25 °C / 55 °C +Taux d'humidité min/max: 70 % / 98 % +Résistance/durabilité: Bonne si anaérobie strict, sporulante +Profondeur de matière requise: ≥ 20 cm dans la phase active du digesta +Effet recherché: Production d’acides acétique, butyrique, butanol et éthanol ; rendement énergétique élevé +Collecte / Approvisionnement: Cultures pures ou issues de substrats riches en amidons ; digestats stables +Conditions de mise en œuvre: Apport en substrat carboné (glucose, amidon), maintien d’un pH neutre +Efficacité: Très élevée sur substrats alimentaires +Efficience: Bonne, notamment en co-fermentation + +**Enterobacter aerogenes** +Type: Bactérie anaérobie facultative, productrice d’hydrogène +Température min/max: 20 °C / 50 °C +Taux d'humidité min/max: 70 % / 99 % +Résistance/durabilité: Bonne tolérance aux variations, non sporulante +Profondeur de matière requise: Surface à profondeur moyenne (10–25 cm) +Effet recherché: Production rapide de H₂ et d’acides mixtes, stimulation de la phase acidogène +Collecte / Approvisionnement: Boues de STEP, substrats riches en azote, eaux usées +Conditions de mise en œuvre: Préfère des substrats sucrés, peut cohabiter temporairement avec O₂ résiduel +Efficacité: Bonne en digesteurs instables ou en relance +Efficience: Moyenne à bonne, dépend de la gestion des flux gazeux + +**Desulfobacter postgatei** +Type: Bactérie anaérobie stricte, réductrice de sulfate (SRB) +Température min/max: 15 °C / 55 °C +Taux d'humidité min/max: 80 % / 100 % +Résistance/durabilité: Excellente dans les milieux sulfatés, sensible à l’O₂ +Profondeur de matière requise: ≥ 30 cm, dans les zones profondes ou faiblement brassées +Effet recherché: Réduction des sulfates en sulfure ; participation au cycle du soufre ; stabilisation redox +Collecte / Approvisionnement: Boues marines, zones humides riches en soufre, milieux anoxiques +Conditions de mise en œuvre: Anaérobie stricte, apport modéré en carbone ; éviter les excès de nitrates +Efficacité: Élevée pour la réduction des sulfates +Efficience: Bonne en environnement contrôlé, interactions avec méthanogènes à surveiller + +**Lactobacillus spp.** +Type: Bactéries aérotolérantes, fermentatives lactiques +Température min/max: 10 °C / 50 °C +Taux d'humidité min/max: 60 % / 98 % +Résistance/durabilité: Moyenne ; préfère les milieux frais et humides, sensible aux pH alcalins +Profondeur de matière requise: 5 à 20 cm, zone supérieure du substrat +Effet recherché: Acidification rapide du substrat, activation de la phase primaire de fermentation +Collecte / Approvisionnement: Ferments laitiers, ensilages, produits fermentés alimentaires +Conditions de mise en œuvre: Inoculation au démarrage ou en phase de relance ; bon brassage nécessaire +Efficacité: Très élevée à court terme +Efficience: Excellente pour stabiliser rapidement un digesteur faiblement actif + +**Bacillus subtilis** +Type: Bactérie aérobique sporulante, utilisée aussi en anaérobie par adaptation +Température min/max: 15 °C / 60 °C +Taux d'humidité min/max: 50 % / 95 % +Résistance/durabilité: Très élevée ; spores thermorésistantes et longue durée de vie +Profondeur de matière requise: 10 à 25 cm selon brassage +Effet recherché: Dégradation de protéines, activation enzymatique, équilibre microbien général +Collecte / Approvisionnement: Sols agricoles, composts mûrs, digestats thermophiles +Conditions de mise en œuvre: Peut être inoculé dès la phase mésophile, tolère les transitions thermiques +Efficacité: Bonne à très bonne sur substrats hétérogènes +Efficience: Très bonne en digesteurs mixtes ou à déchets alimentaires + +**Enterococcus faecium** +Type: Bactérie anaérobie aérotolérante, fermentative lactique +Température min/max: 10 °C / 45 °C +Taux d'humidité min/max: 65 % / 98 % +Résistance/durabilité: Moyenne ; stable à pH faible, mais sensible aux températures > 50 °C +Profondeur de matière requise: 10 à 20 cm dans la zone active +Effet recherché: Stabilisation rapide du pH, activité antimicrobienne contre agents pathogènes +Collecte / Approvisionnement: Ferments alimentaires, lisiers, flore intestinale d’origine animale +Conditions de mise en œuvre: Apport en début de cycle, co-inoculation avec lactobacilles possible +Efficacité: Bonne en phase de démarrage +Efficience: Très bonne sur substrats animaux ou riches en amidons + +**Paenibacillus polymyxa** +Type: Bactérie sporulante du sol, fixatrice d’azote et productrice d’enzymes +Température min/max: 15 °C / 50 °C +Taux d'humidité min/max: 55 % / 95 % +Résistance/durabilité: Très bonne en sol ou digestat stabilisé +Profondeur de matière requise: 15 à 30 cm ; zones bien humides +Effet recherché: Fixation d’azote, dégradation de polysaccharides complexes, synergie avec plantes ou champignons +Collecte / Approvisionnement: Sols vivants, rhizosphères, composts mâtures +Conditions de mise en œuvre: Inoculation dans substrats végétaux ou mixtes ; pH neutre à légèrement acide +Efficacité: Bonne en contexte végétal ou de co-fermentation +Efficience: Excellente dans les digesteurs liés à biomasses agricoles + +**Paracoccus denitrificans** +Type: Bactérie aérobique et anaérobique facultative, dénitrifiante +Température min/max: 10 °C / 45 °C +Taux d'humidité min/max: 60 % / 98 % +Résistance/durabilité: Bonne dans les cycles oxydatifs, fragile en milieu acide +Profondeur de matière requise: Zones moyennes (15–25 cm), bien mélangées +Effet recherché: Réduction des nitrates et nitrites, assainissement de substrats azotés +Collecte / Approvisionnement: Boues nitrifiantes de STEP, sols humides bien drainés +Conditions de mise en œuvre: pH neutre, teneur suffisante en nitrate et en carbone, zone légèrement aérée +Efficacité: Élevée en régulation azote +Efficience: Très bonne en co-traitement avec substrats azotés (lisiers, eaux usées) + +**Streptomyces spp.** +Type: Bactéries filamenteuses aérobies, productrices d’antibiotiques naturels +Température min/max: 15 °C / 45 °C +Taux d'humidité min/max: 50 % / 90 % +Résistance/durabilité: Très bonne en substrat sec ou semi-sec, peu adaptées à immersion totale +Profondeur de matière requise: Zone supérieure à 15–20 cm, bien aérée +Effet recherché: Dégradation de composés complexes, lutte contre les champignons pathogènes +Collecte / Approvisionnement: Sols forestiers, composts, substrats de champignons usagés +Conditions de mise en œuvre: En conditions aérobies en amont ou en bordure des digesteurs +Efficacité: Moyenne en digesteur, élevée en prétraitement ou phase sèche +Efficience: Excellente en valorisation de biomasse ligneuse ou co-fermentations + +Parfait. Voici les fiches régulateurs spécifiques à la méthanisation "sèche" à température ambiante, selon votre plan et le formalisme validé : + +**Lactobacillus plantarum** +Type: Bactérie anaérobie facultative, fermentative lactique +Température min/max: 10 °C / 45 °C +Taux d'humidité min/max: 60 % / 98 % +Résistance/durabilité: Moyenne ; efficace en début de fermentation, sensible aux pH élevés +Profondeur de matière requise: 5 à 20 cm, dans les premières couches du substrat +Effet recherché: Acidification initiale, réduction rapide du pH, amorce du processus hygiénique +Collecte / Approvisionnement: Ferments laitiers, choucroute, ensilages, végétaux lacto-fermentés +Conditions de mise en œuvre: Inoculation en début de cycle ; bien mélanger dans substrat humide +Efficacité: Très élevée dans les 48 premières heures +Efficience: Excellente pour stabiliser rapidement un digesteur démarré à froid + +**Corynebacterium glutamicum** +Type: Bactérie aérobique facultative, productrice d'acides aminés +Température min/max: 20 °C / 45 °C +Taux d'humidité min/max: 50 % / 90 % +Résistance/durabilité: Moyenne ; tolère des milieux variables, sensible aux acidités fortes +Profondeur de matière requise: Zone moyenne (15–25 cm) +Effet recherché: Amélioration du rapport C/N, conversion des protéines en acides organiques utiles à la digestion +Collecte / Approvisionnement: Fermentations industrielles, substrats végétaux enrichis, cultures pures +Conditions de mise en œuvre: Apport modéré dans substrats mixtes (protéines + sucres) +Efficacité: Bonne pour corriger les déséquilibres azotés +Efficience: Moyenne, utile en présence de déchets carnés ou de boues riches + +**Mycobacterium smegmatis** +Type: Bactérie aérotolérante, non pathogène, dégradant les lipides et composés gras +Température min/max: 20 °C / 50 °C +Taux d'humidité min/max: 65 % / 98 % +Résistance/durabilité: Très bonne ; résiste aux conditions variables, colonisation stable +Profondeur de matière requise: 10 à 30 cm, bien intégré à la masse grasse +Effet recherché: Dégradation des lipides, initiation de la bioremédiation des graisses, réduction d’odeurs +Collecte / Approvisionnement: Cultures en laboratoire, sédiments riches en matières grasses, boues de cuisine +Conditions de mise en œuvre: Apport fractionné, suivi de température et d’agitation recommandé +Efficacité: Élevée sur substrats riches en graisses +Efficience: Bonne pour stations recevant graisses alimentaires ou graisses de STEP + +**Bacillus megaterium** +Type: Bactérie sporulante aérobie, tolérante à l’anaérobiose, multifonctionnelle +Température min/max: 15 °C / 55 °C +Taux d'humidité min/max: 60 % / 95 % +Résistance/durabilité: Excellente ; spores stables, implantation durable +Profondeur de matière requise: 10 à 25 cm dans la zone humide +Effet recherché: Production d’enzymes, stimulation de la biomasse microbienne, relance de la fermentation +Collecte / Approvisionnement: Sols vivants, composts, cultures pures disponibles +Conditions de mise en œuvre: Inoculation directe dans substrats organiques après brassage +Efficacité: Très bonne pour soutenir la diversité bactérienne +Efficience: Excellente dans digesteurs peu actifs ou post-choc + +**Glucose (fruits)** +Type: Substrat biochimique sucré, à haute biodisponibilité +Température min/max: 10 °C / 65 °C +Taux d'humidité min/max: 60 % / 98 % +Résistance/durabilité: Faible (très rapidement consommé) +Profondeur de matière requise: 5 à 15 cm selon homogénéité du mélange +Effet recherché: Activation rapide des bactéries acidogènes ; substrat facilement dégradable +Collecte / Approvisionnement: Fruits invendus, jus périmés, sirops, résidus de conserverie +Conditions de mise en œuvre: Injection liquide ou purée après broyage, immédiatement mélangée +Efficacité: Très élevée en amorçage ou relance +Efficience: Moyenne à bonne, selon disponibilité locale en coproduits sucrés + +**Digesta (de lot précédent)** +Type: Résidu biologique stabilisé, riche en enzymes et en bactéries actives +Température min/max: 15 °C / 65 °C +Taux d'humidité min/max: 75 % / 98 % +Résistance/durabilité: Moyenne ; efficacité dégressive après stockage > 72 h +Profondeur de matière requise: 10 à 25 cm en mélange avec substrat frais +Effet recherché: Relance de l’activité microbiologique, stabilisation, ensemencement naturel +Collecte / Approvisionnement: Sortie de digesteurs thermophiles ou mésophiles, issus d’autres stations +Conditions de mise en œuvre: Utilisation rapide après extraction ; ajout en mélange homogène +Efficacité: Bonne si frais et bien intégré +Efficience: Très bonne pour l’ensemencement circulaire en réseau local + +**Régulateur CO₂ du générateur** +Type: Gaz tampon atmosphérique produit par combustion (ou capté) +Température min/max: 0 °C / 70 °C +Taux d'humidité min/max: n/a (gazeux) +Résistance/durabilité: Transitoire, instantané +Profondeur de matière requise: Mélange à l’atmosphère interne du digesteur +Effet recherché: Maintien de la pression, soutien du pH, activation bactéries algales (si traitement mixte) +Collecte / Approvisionnement: Échappement du générateur, stockage gaz, ou bouteilles CO₂ technique +Conditions de mise en œuvre: Injection douce, surveiller la pression et le rapport CH₄/CO₂ +Efficacité: Moyenne à bonne en complément d’un équilibre stable +Efficience: Bonne si couplé au cycle énergétique interne + +## Méthanisation "sèche" à température ambiante (prétraitement hygiénique + séparation) + +**Lactobacillus plantarum** +Type: Bactérie anaérobie facultative, fermentative lactique +Température min/max: 10 °C / 45 °C +Taux d'humidité min/max: 60 % / 98 % +Résistance/durabilité: Moyenne ; efficace en début de fermentation, sensible aux pH élevés +Profondeur de matière requise: 5 à 20 cm, dans les premières couches du substrat +Effet recherché: Acidification initiale, réduction rapide du pH, amorce du processus hygiénique +Collecte / Approvisionnement: Ferments laitiers, choucroute, ensilages, végétaux lacto-fermentés +Conditions de mise en œuvre: Inoculation en début de cycle ; bien mélanger dans substrat humide +Efficacité: Très élevée dans les 48 premières heures +Efficience: Excellente pour stabiliser rapidement un digesteur démarré à froid + +**Corynebacterium glutamicum** +Type: Bactérie aérobique facultative, productrice d'acides aminés +Température min/max: 20 °C / 45 °C +Taux d'humidité min/max: 50 % / 90 % +Résistance/durabilité: Moyenne ; tolère des milieux variables, sensible aux acidités fortes +Profondeur de matière requise: Zone moyenne (15–25 cm) +Effet recherché: Amélioration du rapport C/N, conversion des protéines en acides organiques utiles à la digestion +Collecte / Approvisionnement: Fermentations industrielles, substrats végétaux enrichis, cultures pures +Conditions de mise en œuvre: Apport modéré dans substrats mixtes (protéines + sucres) +Efficacité: Bonne pour corriger les déséquilibres azotés +Efficience: Moyenne, utile en présence de déchets carnés ou de boues riches + +**Mycobacterium smegmatis** +Type: Bactérie aérotolérante, non pathogène, dégradant les lipides et composés gras +Température min/max: 20 °C / 50 °C +Taux d'humidité min/max: 65 % / 98 % +Résistance/durabilité: Très bonne ; résiste aux conditions variables, colonisation stable +Profondeur de matière requise: 10 à 30 cm, bien intégré à la masse grasse +Effet recherché: Dégradation des lipides, initiation de la bioremédiation des graisses, réduction d’odeurs +Collecte / Approvisionnement: Cultures en laboratoire, sédiments riches en matières grasses, boues de cuisine +Conditions de mise en œuvre: Apport fractionné, suivi de température et d’agitation recommandé +Efficacité: Élevée sur substrats riches en graisses +Efficience: Bonne pour stations recevant graisses alimentaires ou graisses de STEP + +**Bacillus megaterium** +Type: Bactérie sporulante aérobie, tolérante à l’anaérobiose, multifonctionnelle +Température min/max: 15 °C / 55 °C +Taux d'humidité min/max: 60 % / 95 % +Résistance/durabilité: Excellente ; spores stables, implantation durable +Profondeur de matière requise: 10 à 25 cm dans la zone humide +Effet recherché: Production d’enzymes, stimulation de la biomasse microbienne, relance de la fermentation +Collecte / Approvisionnement: Sols vivants, composts, cultures pures disponibles +Conditions de mise en œuvre: Inoculation directe dans substrats organiques après brassage +Efficacité: Très bonne pour soutenir la diversité bactérienne +Efficience: Excellente dans digesteurs peu actifs ou post-choc + +**Glucose (fruits)** +Type: Substrat biochimique sucré, à haute biodisponibilité +Température min/max: 10 °C / 65 °C +Taux d'humidité min/max: 60 % / 98 % +Résistance/durabilité: Faible (très rapidement consommé) +Profondeur de matière requise: 5 à 15 cm selon homogénéité du mélange +Effet recherché: Activation rapide des bactéries acidogènes ; substrat facilement dégradable +Collecte / Approvisionnement: Fruits invendus, jus périmés, sirops, résidus de conserverie +Conditions de mise en œuvre: Injection liquide ou purée après broyage, immédiatement mélangée +Efficacité: Très élevée en amorçage ou relance +Efficience: Moyenne à bonne, selon disponibilité locale en coproduits sucrés + +**Digesta (de lot précédent)** +Type: Résidu biologique stabilisé, riche en enzymes et en bactéries actives +Température min/max: 15 °C / 65 °C +Taux d'humidité min/max: 75 % / 98 % +Résistance/durabilité: Moyenne ; efficacité dégressive après stockage > 72 h +Profondeur de matière requise: 10 à 25 cm en mélange avec substrat frais +Effet recherché: Relance de l’activité microbiologique, stabilisation, ensemencement naturel +Collecte / Approvisionnement: Sortie de digesteurs thermophiles ou mésophiles, issus d’autres stations +Conditions de mise en œuvre: Utilisation rapide après extraction ; ajout en mélange homogène +Efficacité: Bonne si frais et bien intégré +Efficience: Très bonne pour l’ensemencement circulaire en réseau local + +**Régulateur CO₂ du générateur** +Type: Gaz tampon atmosphérique produit par combustion (ou capté) +Température min/max: 0 °C / 70 °C +Taux d'humidité min/max: n/a (gazeux) +Résistance/durabilité: Transitoire, instantané +Profondeur de matière requise: Mélange à l’atmosphère interne du digesteur +Effet recherché: Maintien de la pression, soutien du pH, activation bactéries algales (si traitement mixte) +Collecte / Approvisionnement: Échappement du générateur, stockage gaz, ou bouteilles CO₂ technique +Conditions de mise en œuvre: Injection douce, surveiller la pression et le rapport CH₄/CO₂ +Efficacité: Moyenne à bonne en complément d’un équilibre stable +Efficience: Bonne si couplé au cycle énergétique interne + +## **2. Traitement algues, larves, bactéries (30 j à 25 °C)** + +**Scenedesmus obliquus** +Type: Micro-algue verte unicellulaire d’eau douce, photosynthétique +Température min/max: 15 °C / 32 °C +Taux d'humidité min/max: milieu aqueux permanent (> 95 %) +Résistance/durabilité: Très bonne ; tolère les variations de lumière et de salinité +Profondeur de matière requise: Colonise la surface des bassins ou interfaces air/eau +Effet recherché: Fixation active du CO₂, adsorption des métaux légers, régulation des graisses en suspension +Collecte / Approvisionnement: Cultures pures, prélèvements d’eaux douces eutrophisées +Conditions de mise en œuvre: Nécessite lumière naturelle ou LED spectre bleu/rouge ; brassage lent +Efficacité: Élevée sur métaux et CO₂ ; modérée sur lipides +Efficience: Excellente si bassins dédiés ou en cohabitation avec larves + +**Nannochloropsis oculata** +Type: Micro-algue marine unicellulaire, riche en lipides et pigments +Température min/max: 20 °C / 28 °C +Taux d'humidité min/max: milieu aqueux permanent (> 95 %) +Résistance/durabilité: Moyenne ; sensible à la turbidité et aux variations brutales de salinité +Profondeur de matière requise: Zone photique de 5–15 cm, en eau peu agitée +Effet recherché: Fixation de CO₂, consommation de nutriments azotés, production d’oxygène local +Collecte / Approvisionnement: Cultures marines, fermes aquacoles, inoculation contrôlée +Conditions de mise en œuvre: Milieu salin ou saumâtre, apport régulier en lumière et CO₂ +Efficacité: Très bonne sur CO₂ et azote si conditions contrôlées +Efficience: Moyenne sans suivi des paramètres ; très bonne en photobioréacteurs naturels + +**Chlorella vulgaris** +Type: Micro-algue verte d’eau douce, rapide à croître, photosynthétique +Température min/max: 18 °C / 30 °C +Taux d'humidité min/max: milieu aqueux (> 95 %) +Résistance/durabilité: Excellente ; tolérante à la pollution, forte densité cellulaire +Profondeur de matière requise: Surface lumineuse (0–15 cm), idéale en bassins peu profonds +Effet recherché: Capture du CO₂, absorption d’ammonium, filtration organique fine +Collecte / Approvisionnement: Culture en eaux usées traitées, milieux eutrophes, spirulinières +Conditions de mise en œuvre: Lumière directe ou artificielle, injection contrôlée de CO₂, agitation douce +Efficacité: Très élevée pour fixation azote et CO₂ +Efficience: Très bonne en co-culture avec larves ou bactéries + +**Pseudomonas fluorescens** +Type: Bactérie aérobie ou microaérophile, agent de bioremédiation reconnu +Température min/max: 15 °C / 35 °C +Taux d'humidité min/max: 60 % / 100 % +Résistance/durabilité: Bonne ; sensible aux environnements trop acides +Profondeur de matière requise: Zone moyenne à superficielle (5–20 cm), avec substrat humide +Effet recherché: Dégradation des graisses, hydrocarbures, pesticides ; production de biosurfactants +Collecte / Approvisionnement: Sols humides, eaux usées industrielles, boues végétales +Conditions de mise en œuvre: Inoculation dans substrats humides et oxygénés ; éviter l’anaérobie stricte +Efficacité: Élevée sur polluants organiques complexes +Efficience: Très bonne dans substrats mixtes azotés/graisseux + +**Pseudomonas putida** +Type: Bactérie aérobie, versatile, hautement métabolique +Température min/max: 10 °C / 37 °C +Taux d'humidité min/max: 65 % / 98 % +Résistance/durabilité: Très bonne ; résiste à de nombreux toxiques organiques +Profondeur de matière requise: Superficie et interfaces (eau/air ou litière humide) +Effet recherché: Dégradation de solvants, hydrocarbures, plastifiants ; prétraitement des antibiotiques +Collecte / Approvisionnement: Boues biologiques, sols pollués, stations de compostage +Conditions de mise en œuvre: Nécessite un minimum d’oxygène ; substrat humide, lumière non nécessaire +Efficacité: Excellente sur polluants hydrophobes +Efficience: Très bonne en co-inoculation avec algues ou larves + +**Gluconobacter oxydans** +Type: Bactérie aérobique acétique, spécialisée dans l’oxydation de sucres +Température min/max: 20 °C / 35 °C +Taux d'humidité min/max: 60 % / 98 % +Résistance/durabilité: Moyenne ; active en substrats sucrés ou riches en alcools +Profondeur de matière requise: Zone superficielle à 10 cm max +Effet recherché: Pré-oxydation douce des substrats glucidiques, baisse de DCO, stabilisation microbienne +Collecte / Approvisionnement: Jus de fruits fermentés, substrats sucrés, vinaigres vivants +Conditions de mise en œuvre: Phase aérobie légère ou microaérophile, suivi du pH recommandé +Efficacité: Bonne dans substrats à forte charge glucidique +Efficience: Moyenne, complémentaire des bactéries acidogènes + +**Rhodobacter sphaeroides** +Type: Bactérie pourpre non-soufrée, photosynthétique anaérobie facultative +Température min/max: 15 °C / 40 °C +Taux d'humidité min/max: milieu semi-aquatique ou digesta humide (> 85 %) +Résistance/durabilité: Très bonne dans les conditions lumineuses anaérobies +Profondeur de matière requise: Zone éclairée, souvent à l’interface liquide/gaz +Effet recherché: Fixation de CO₂, dégradation de composés azotés, synergie avec algues +Collecte / Approvisionnement: Boues de lagunage, biofilms lumineux, cultures dirigées +Conditions de mise en œuvre: Lumière rouge ou naturelle indirecte, substrats riches en C organique +Efficacité: Élevée dans photoréacteurs ou zones peu brassées +Efficience: Excellente si couplée à un apport H₂ ou CO₂ + +**Rhodospirillum rubrum** +Type: Bactérie photosynthétique anoxygénique, adaptable +Température min/max: 15 °C / 38 °C +Taux d'humidité min/max: > 85 % +Résistance/durabilité: Bonne, mais sensible à l’agitation +Profondeur de matière requise: Interface liquide-gaz dans zones lumineuses +Effet recherché: Fixation CO₂, réduction de NO₃⁻, assimilation de composés organiques légers +Collecte / Approvisionnement: Cultures pures, boues de fosses, lagunes anaérobies +Conditions de mise en œuvre: Milieu semi-stagnant, lumière indirecte, supplément CO₂ ou H₂ +Efficacité: Bonne dans les zones calmes du bassin ou en bordure de digesteur +Efficience: Moyenne seule, excellente en co-culture + +**H₂ (activateur photo-microbien)** +Type: Gaz réducteur, cofacteur de certaines réactions bactériennes (photosynthèse anoxygénique) +Température min/max: 15 °C / 65 °C +Taux d'humidité min/max: n/a (gazeux) +Résistance/durabilité: Transitoire, rapidement consommé +Profondeur de matière requise: Atmosphère ou interface supérieure +Effet recherché: Donneur d’électrons pour bactéries photosynthétiques, soutient la fixation CO₂ +Collecte / Approvisionnement: Cuve UV-C, électrolyse douce, photolyse +Conditions de mise en œuvre: Injection douce dans atmosphère contrôlée ou réacteur à algues +Efficacité: Très bonne en symbiose bactéries-algues +Efficience: Bonne en usage interne, faible coût si couplé au système + +**CO₂ (activateur photosynthétique)** +Type: Gaz carboné, substrat de fixation pour microalgues et bactéries phototrophes +Température min/max: 5 °C / 65 °C +Taux d'humidité min/max: n/a (gazeux) +Résistance/durabilité: Stable sous forme dissoute, circulant librement dans le système +Profondeur de matière requise: Zone liquide ou atmosphère au-dessus des bassins +Effet recherché: Apport en carbone organique, stimulation de la biomasse algale +Collecte / Approvisionnement: Générateur biogaz, fermentation, bouteilles techniques +Conditions de mise en œuvre: Injection sous pression faible, diffusion lente dans l’eau +Efficacité: Élevée si apparié à lumière et N/P suffisant +Efficience: Très bonne en environnement fermé ou recyclé + +## **3. Traitement champignons, vers, bactéries (30 j à 12 °C)** + +**Ganoderma** +Type: Champignon basidiomycète ligninolytique (bois morts) +Température min/max: 5 °C / 28 °C +Taux d'humidité min/max: 60 % / 90 % +Résistance/durabilité: Bonne si substrat ligneux stable ; sensible au gel +Profondeur de matière requise: Zone superficielle ou colonisation de blocs lignocellulosiques +Effet recherché: Dégradation de lignine, transformation de composés phénoliques, réduction odeurs +Collecte / Approvisionnement: Culture sur bois morts, bûches inoculées, spores issues de forêts +Conditions de mise en œuvre: Température basse, bonne aération, humidité contrôlée ; nécessite structure porteuse +Efficacité: Moyenne à élevée sur substrats ligneux +Efficience: Bonne en combinaison avec vers et bactéries auxiliaires + +**Pleurotus spp.** +Type: Champignons saprophytes lignocellulosiques (pleurotes) +Température min/max: 8 °C / 28 °C +Taux d'humidité min/max: 65 % / 90 % +Résistance/durabilité: Excellente en milieu humide tempéré ; tolère substrats usagés +Profondeur de matière requise: Surface à 20 cm en lit ou blocs mycélisés +Effet recherché: Dégradation de cellulose, lignine, microplastiques biodégradables ; fixation des graisses +Collecte / Approvisionnement: Mycélium commercial, substrats de culture usagés (paille, marc) +Conditions de mise en œuvre: Apport de substrat fibreux, maintien d’une humidité constante, éviter l’immersion +Efficacité: Très élevée en conditions contrôlées +Efficience: Excellente sur résidus agricoles ou cartons ; co-produit valorisable (aliment, compost) + +**Penicillium chrysogenum** +Type: Moisissure filamenteuse saprophyte, productrice de pénicilline +Température min/max: 5 °C / 25 °C +Taux d'humidité min/max: 60 % / 90 % +Résistance/durabilité: Moyenne ; colonisation rapide mais sensible à la concurrence +Profondeur de matière requise: Zone superficielle, 5–10 cm sur substrats humides +Effet recherché: Dégradation fine de polysaccharides, activité antibactérienne naturelle +Collecte / Approvisionnement: Pain moisi, surfaces alimentaires, cultures pures +Conditions de mise en œuvre: Aération légère, température fraîche, surface humide non saturée +Efficacité: Moyenne à élevée en complément d’autres agents +Efficience: Bonne en traitement ciblé ou milieu en cours de stabilisation + +**Aspergillus niger** +Type: Moisissure filamenteuse noire, très active sur biomasse végétale +Température min/max: 10 °C / 40 °C +Taux d'humidité min/max: 50 % / 85 % +Résistance/durabilité: Excellente ; spores persistantes même en conditions sèches +Profondeur de matière requise: 5 à 15 cm ; préfère surfaces fibreuses ou compostées +Effet recherché: Dégradation acide des celluloses, pectines, composés complexes ; production enzymatique (amylase, pectinase) +Collecte / Approvisionnement: Compost mûr, substrats moisis, cultures industrielles +Conditions de mise en œuvre: Aération minimale, éviter saturation en eau, pH légèrement acide +Efficacité: Élevée sur substrats riches en fibres végétales +Efficience: Très bonne en complément d’un pré-compostage ou d’un traitement par vers + +**Eisenia fetida** +Type: Ver de terre composteur (lombric rouge), décomposeur de matière organique +Température min/max: 10 °C / 28 °C +Taux d'humidité min/max: 60 % / 85 % +Résistance/durabilité: Bonne en substrat fibreux bien oxygéné ; sensible au gel +Profondeur de matière requise: 5 à 25 cm dans le lit de décomposition +Effet recherché: Transformation mécanique et enzymatique de matière organique, mélange, oxygénation +Collecte / Approvisionnement: Vermicompost, lombricultures locales, élevage sur fumier +Conditions de mise en œuvre: Litière végétale stable, humidité constante, éviter substrats toxiques ou trop gras +Efficacité: Très bonne sur substrats stabilisés ou lignocellulosiques +Efficience: Excellente ; produit du lombricompost valorisable + +**Lumbricus rubellus** +Type: Ver de terre épigé, décomposeur actif de surface +Température min/max: 5 °C / 25 °C +Taux d'humidité min/max: 65 % / 90 % +Résistance/durabilité: Très bonne en climat tempéré humide +Profondeur de matière requise: 0 à 15 cm ; préfère couches de surface +Effet recherché: Aération du substrat, ingestion de particules fines, stabilisation microbiologique +Collecte / Approvisionnement: Sols forestiers, composts ouverts, litières organiques +Conditions de mise en œuvre: Substrat végétal non compacté, humidité constante, pas de forte lumière +Efficacité: Bonne en surface, agit en complément d’Eisenia +Efficience: Très bonne dans systèmes ouverts ou avec apport cyclique de matière fraîche + +**Streptomyces spp.** +Type: Bactéries filamenteuses du sol, actinomycètes à effet fongicide +Température min/max: 15 °C / 45 °C +Taux d'humidité min/max: 50 % / 90 % +Résistance/durabilité: Excellente ; forme des spores robustes dans substrat sec +Profondeur de matière requise: Zone supérieure ou autour de matière végétale (5–15 cm) +Effet recherché: Ligninolyse bactérienne, inhibition des champignons pathogènes, structuration du sol +Collecte / Approvisionnement: Sols riches, compost mûr, substrats ligneux séchés +Conditions de mise en œuvre: Bonne aération, structure fibreuse, humidité contrôlée +Efficacité: Moyenne seule, très bonne en interaction avec champignons et vers +Efficience: Excellente en stabilisation des substrats ligneux ou en synergie avec bioremédiation + +## **4. Traitement plantes, vers, bactéries (30 j à 22 °C)** + +**Fougère (bioindicatrice / phytoextratrice)** +Type: Plante vasculaire pérenne, hyperaccumulatrice de métaux lourds (ex. arsenic) +Température min/max: 10 °C / 30 °C +Taux d'humidité min/max: 50 % / 85 % +Résistance/durabilité: Très bonne en zone ombragée et humide +Profondeur de matière requise: Sol ou substrat meuble de 15–30 cm +Effet recherché: Phytoaccumulation d’arsenic, zinc, plomb ; indicateur de pollution métallique +Collecte / Approvisionnement: Forêts humides, serres, propagation par rhizome +Conditions de mise en œuvre: Plantation ou bouturage dans substrat filtrant, arrosage goutte-à-goutte +Efficacité: Élevée sur arsenic et zinc en substrat organo-minéral +Efficience: Très bonne en phytoremédiation passive ou système fermé + +**Ray-grass (Lolium perenne)** +Type: Plante herbacée pérenne, fixatrice d’azote et bioindicateur nitrates +Température min/max: 8 °C / 30 °C +Taux d'humidité min/max: 40 % / 85 % +Résistance/durabilité: Très bonne ; pousse rapide, couvre-sol efficace +Profondeur de matière requise: 10 à 20 cm pour enracinement dense +Effet recherché: Fixation de NO₃⁻, absorption azote minéral, indicateur de fertilisation +Collecte / Approvisionnement: Semences agricoles, prairies, gazons régénérateurs +Conditions de mise en œuvre: Semis direct sur couche filtrante, arrosage contrôlé +Efficacité: Excellente sur excès azote et stabilité racinaire +Efficience: Très bonne en zone périphérique ou sur sol de sortie + +**Trèfle blanc (Trifolium repens)** +Type: Légumineuse fixatrice d’azote, symbiotique avec Rhizobium +Température min/max: 5 °C / 28 °C +Taux d'humidité min/max: 50 % / 90 % +Résistance/durabilité: Bonne, mais sensible à la sécheresse +Profondeur de matière requise: 10 à 15 cm dans sol aéré +Effet recherché: Fixation biologique de l’azote, structuration du sol, bioremédiation douce +Collecte / Approvisionnement: Semences agricoles, prairies naturelles +Conditions de mise en œuvre: Semis ou bouture, apport initial de Rhizobium recommandé +Efficacité: Élevée en substrat appauvri ou en association avec autres herbacées +Efficience: Très bonne en couverture permanente ou substrat exportable + +**Moutarde indienne (Brassica juncea)** +Type: Plante annuelle, phytoextractrice puissante de métaux lourds +Température min/max: 10 °C / 32 °C +Taux d'humidité min/max: 40 % / 85 % +Résistance/durabilité: Moyenne ; cycle court, croissance rapide +Profondeur de matière requise: 15 à 25 cm, sol bien drainé +Effet recherché: Extraction de Pb, Zn, Cd ; stabilisation des sols contaminés ; absorption nitrates +Collecte / Approvisionnement: Semences agricoles, cultures expérimentales +Conditions de mise en œuvre: Semis en surface ou substrat minéral, récolte après 30–40 jours +Efficacité: Très élevée en phytoextraction, bonne en surfactants +Efficience: Excellente pour stabilisation rapide ou filtration biologique + +**Glomus spp.** +Type: Champignons mycorhiziens arbusculaires (endosymbiotes racinaires) +Température min/max: 12 °C / 30 °C +Taux d'humidité min/max: 60 % / 95 % +Résistance/durabilité: Très bonne ; résistent en dormance +Profondeur de matière requise: Racines profondes (15–30 cm) en contact symbiotique +Effet recherché: Stimulation racinaire, amélioration de l’absorption phosphore, bioremédiation racinaire indirecte +Collecte / Approvisionnement: Sols vivants, inoculants mycorhiziens agricoles +Conditions de mise en œuvre: Co-inoculation avec plantes herbacées, ne pas stériliser le substrat +Efficacité: Très élevée en sol structuré +Efficience: Excellente dans systèmes vivants ou substrats reconstitués + +**Nitrosomonas europaea** +Type: Bactérie nitrifiante aérobie, oxydation de NH₄⁺ en NO₂⁻ +Température min/max: 10 °C / 35 °C +Taux d'humidité min/max: 70 % / 100 % +Résistance/durabilité: Moyenne ; exige une faible matière organique et de l’O₂ +Profondeur de matière requise: Couche superficielle (5–15 cm), bonne aération +Effet recherché: Détoxification des ammoniums, première phase de nitrification +Collecte / Approvisionnement: Boues de STEP, substrats nitrifiants, cultures techniques +Conditions de mise en œuvre: Apport d’oxygène, éviter pH < 6,5, température stabilisée +Efficacité: Très bonne si conditions stables +Efficience: Moyenne sans contrôle du pH ou de l’aération + +**Nitrobacter winogradskyi** +Type: Bactérie nitrifiante aérobie, oxydation de NO₂⁻ en NO₃⁻ +Température min/max: 10 °C / 35 °C +Taux d'humidité min/max: 70 % / 100 % +Résistance/durabilité: Moyenne, sensible aux substrats toxiques +Profondeur de matière requise: 5–15 cm ; préfère substrats légers et bien drainés +Effet recherché: Finalisation du cycle de nitrification, transformation des nitrites en nitrates assimilables +Collecte / Approvisionnement: Boues biologiques nitrifiantes, substrats vivants +Conditions de mise en œuvre: Oxygénation douce, neutralité du pH, interaction avec N. europaea +Efficacité: Élevée en duo avec ammoniaco-oxydantes +Efficience: Très bonne en stabilisation azotée + +**Bacillus megaterium** +Type: Bactérie sporulante multifonctionnelle du sol, productrice d’enzymes +Température min/max: 15 °C / 55 °C +Taux d'humidité min/max: 60 % / 95 % +Résistance/durabilité: Excellente ; spores durables, activité enzymatique élevée +Profondeur de matière requise: 10 à 25 cm, dans substrat actif +Effet recherché: Solubilisation du phosphore, dégradation des tensioactifs, activation microbienne +Collecte / Approvisionnement: Sols vivants, composts, isolats agricoles +Conditions de mise en œuvre: Apport direct au substrat, co-inoculation avec plantes possible +Efficacité: Très bonne en conditions neutres ou légèrement acides +Efficience: Excellente dans les substrats mixtes avec activité biologique + +**Eisenia fetida** +Type: Ver rouge composteur, décomposeur organique à cycle rapide +Température min/max: 10 °C / 28 °C +Taux d'humidité min/max: 60 % / 85 % +Résistance/durabilité: Bonne en substrats humides non saturés +Profondeur de matière requise: 5 à 25 cm ; substrat meuble et structuré +Effet recherché: Aération et structuration, réduction des charges microbiennes libres, digestion mécanique +Collecte / Approvisionnement: Lombricomposteurs, élevages, composts mûrs +Conditions de mise en œuvre: Substrat végétal ou semi-végétal, éviter acidité excessive +Efficacité: Très bonne en conditions tempérées +Efficience: Excellente en recyclage organique lent ou substrat enrichi + +**Lumbricus rubellus** +Type: Ver de terre de surface, décomposeur secondaire +Température min/max: 5 °C / 25 °C +Taux d'humidité min/max: 65 % / 90 % +Résistance/durabilité: Très bonne en zone fraîche et humide +Profondeur de matière requise: 0 à 15 cm, préfère substrats peu profonds +Effet recherché: Stabilisation microbienne, absorption de particules fines, filtration naturelle +Collecte / Approvisionnement: Sols forestiers humides, composts ouverts, substrats feuillus +Conditions de mise en œuvre: Substrat non compressé, humidité constante, lumière indirecte +Efficacité: Moyenne à élevée en fonction des apports +Efficience: Très bonne en association avec végétaux ou substrats lignocellulosiques + +**5. Méthanisation "sèche" à 55 °C (thermophile)** +**Objectifs :** +Production maximale de biogaz +Destruction des pathogènes restants +Réduction ultime des volumes + +**Régulateurs spécifiques :** + +**Clostridium spp. (haut rendement CH₄)** +Type: Bactéries anaérobies strictes, fermentatives thermophiles +Température min/max: 40 °C / 65 °C +Taux d'humidité min/max: 70 % / 95 % +Résistance/durabilité: Excellente ; sporulantes, hautement adaptables en absence d’oxygène +Profondeur de matière requise: 20 à 30 cm dans la zone anaérobie active +Effet recherché: Fermentation rapide des substrats complexes, génération d’acétate et d’hydrogène précurseurs du méthane +Collecte / Approvisionnement: Digestats thermophiles, cultures spécifiques, boues activées enrichies +Conditions de mise en œuvre: Anaérobie strict, brassage lent, injection initiale en substrat chaud (> 45 °C) +Efficacité: Très élevée en régime thermophile stabilisé +Efficience: Excellente pour production continue de CH₄ + +**Bacillus subtilis (résistance thermique)** +Type: Bactérie sporulante du sol, active en anaérobiose modérée +Température min/max: 30 °C / 65 °C +Taux d'humidité min/max: 55 % / 90 % +Résistance/durabilité: Très élevée ; forme des spores résistantes, métabolisme actif en chaleur +Profondeur de matière requise: 10 à 30 cm dans substrat en digestion +Effet recherché: Résilience microbienne, dégradation protéique et soutien à la structuration enzymatique +Collecte / Approvisionnement: Compost chaud, substrats secs, digestats en fin de cycle +Conditions de mise en œuvre: Injection fractionnée ou co-culture dans substrat riche, activation par température +Efficacité: Bonne sur substrats complexes +Efficience: Très bonne dans les cycles de méthanisation longue + +**Lactobacillus spp.** +Type: Bactéries fermentatives lactiques, aérotolérantes +Température min/max: 30 °C / 55 °C +Taux d'humidité min/max: 60 % / 98 % +Résistance/durabilité: Moyenne ; actives en phase d’acidification thermophile +Profondeur de matière requise: 10 à 20 cm, dans la phase humide du substrat +Effet recherché: Amorçage acide du digesteur, suppression de pathogènes résiduels +Collecte / Approvisionnement: Ferments, déchets lacto-fermentés, digestats d’origine végétale +Conditions de mise en œuvre: Apport initial ou en renfort après agitation, éviter pH > 7,5 +Efficacité: Bonne en début de cycle thermophile +Efficience: Très bonne si bien intégrée à la chaîne microbiologique + +**Myxococcus xanthus** +Type: Bactérie sociale glissante, structurante du biofilm microbien +Température min/max: 25 °C / 50 °C +Taux d'humidité min/max: 60 % / 90 % +Résistance/durabilité: Moyenne ; sensible à la dessiccation, mais stable en digesteur fermé +Profondeur de matière requise: 10 à 25 cm, milieu semi-liquide ou fibreux +Effet recherché: Formation de biofilms, structuration microbienne, amélioration des surfaces de contact bactériennes +Collecte / Approvisionnement: Sols vivants, litières organiques, souches pures techniques +Conditions de mise en œuvre: Milieu homogène avec substrats fibreux, faible brassage +Efficacité: Moyenne seule, très élevée en combinaison +Efficience: Très bonne dans substrats denses ou peu brassés + +**H₂ (réacteur Sabatier)** +Type: Gaz réducteur, utilisé pour convertir le CO₂ en CH₄ par voie catalytique +Température min/max: 40 °C / 60 °C +Taux d'humidité min/max: n/a (gazeux) +Résistance/durabilité: Instable, doit être injecté et consommé rapidement +Profondeur de matière requise: Atmosphère gazeuse du digesteur (non immergé) +Effet recherché: Réduction catalytique du CO₂, augmentation de la pureté du biogaz +Collecte / Approvisionnement: Généré par UV-C, électrolyse douce ou fermentation secondaire +Conditions de mise en œuvre: Injection lente dans réacteur Sabatier ou en tête de digesteur ; catalyseur requis +Efficacité: Très élevée avec catalyse nickel ou ruthénium +Efficience: Bonne en boucle fermée ou couplée à la chaleur fatale + +**Cendres (régulation pH)** +Type: Minéral alcalin issu de combustion végétale +Température min/max: 5 °C / 70 °C +Taux d'humidité min/max: 10 % / 70 % +Résistance/durabilité: Moyenne ; action tampon rapide +Profondeur de matière requise: 10 à 30 cm, bien dispersée dans le substrat +Effet recherché: Augmentation du pH, neutralisation d’acidité excessive post-fermentation +Collecte / Approvisionnement: Résidus de chaudières à biomasse, foyers agricoles +Conditions de mise en œuvre: Dosage progressif selon mesure pH, sous forme de poudre fine sèche +Efficacité: Élevée en régulation ponctuelle +Efficience: Très bonne, faible coût + +**CO₂ (tampon thermochimique)** +Type: Gaz carboné, produit ou injecté dans le digesteur +Température min/max: 5 °C / 65 °C +Taux d'humidité min/max: n/a (gazeux) +Résistance/durabilité: Stable en phase gazeuse ou dissoute +Profondeur de matière requise: Phase gazeuse du digesteur ou zone de dissolution +Effet recherché: Stabilisation de la pression, soutien à la digestion bactérienne thermophile +Collecte / Approvisionnement: Gaz d’échappement du générateur, fermentation secondaire +Conditions de mise en œuvre: Diffusion douce, sans surpression +Efficacité: Moyenne à bonne selon niveau de CO₂ présent +Efficience: Très bonne si intégré dans boucle énergétique + +**Biochar (stabilisation, filtration gaz)** +Type: Charbon végétal microporeux issu de pyrolyse lente +Température min/max: 0 °C / 70 °C +Taux d'humidité min/max: 10 % / 70 % +Résistance/durabilité: Très élevée, non biodégradable +Profondeur de matière requise: 15 à 30 cm ; intégré ou dispersé dans le digesteur +Effet recherché: Adsorption de composés soufrés et ammoniaqués, support microbien +Collecte / Approvisionnement: Résidus ligneux pyrolysés localement +Conditions de mise en œuvre: Sec ou légèrement humide, bien réparti +Efficacité: Très élevée sur odeurs et stabilisation +Efficience: Excellente si produit localement ou couplé à valorisation des résidus + +**Digesta (inoculum thermophile)** +Type: Résidu microbien actif issu d’un digesteur thermophile +Température min/max: 30 °C / 65 °C +Taux d'humidité min/max: 75 % / 98 % +Résistance/durabilité: Moyenne ; efficacité maximale sous 72 h après extraction +Profondeur de matière requise: 10 à 25 cm, en mélange homogène avec substrat frais +Effet recherché: Recyclage de l’activité microbienne thermophile, amorçage enzymatique +Collecte / Approvisionnement: Sortie de digesteurs thermophiles ou cuves en régime stabilisé +Conditions de mise en œuvre: Utilisation rapide après extraction, suivi température et pH +Efficacité: Bonne si frais et bien mélangé +Efficience: Très bonne dans les cycles circulaires en réseau + +## **Réduction des déchets, du CO₂ et du CH₄** + +### Traitement : **1. Méthanisation "sèche" à température ambiante (prétraitement hygiénique + séparation)** + +**Objectif spécifique de cet écosystème :** +Réduire les émissions de gaz à effet de serre dès la phase initiale du traitement, notamment les CH₄ diffus non captés et le CO₂ émis par la décomposition organique, tout en abaissant la charge organique initiale des déchets. Optimiser la stabilisation microbienne en limitant les émanations précoces. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Lactobacillus plantarum** : amorce rapide de fermentation acide, permettant de bloquer les fermentations anarchiques génératrices de CH₄ ou H₂S en surface. Elle agit comme verrou biologique de l’anaérobiose précoce. +- **Corynebacterium glutamicum** : corrige le rapport C/N par métabolisation douce des protéines, évitant les excès d’ammoniac, qui sont précurseurs indirects de NOx et autres polluants gazeux. +- **Bacillus megaterium** : agit comme stabilisateur enzymatique multifonctionnel, apportant robustesse à la communauté microbienne et réduisant les besoins de relances. +- **Gypse + Biochar** : le gypse réduit la conductivité (limitant les relargages salins en lixiviats) et le biochar capte les composés volatils (précurseurs CH₄ et H₂S), tout en favorisant l’ancrage microbien. +- **CO₂ (générateur)** : utilisé ici non pas comme inertage, mais comme tampon atmosphérique contrôlé pour éviter les dégagements incontrôlés dans la première phase de digestion. Il sature l’atmosphère du digesteur et retarde la pression CH₄. +- **Glucose (fruits)** : intégré à très faible dose, il permet de stimuler les bactéries acidogènes choisies (Lactobacillus) et de maîtriser la compétition microbienne. + +**Logique de symbiose :** +La combinaison entre régulateurs acidifiants (Lactobacillus), fixateurs de C/N (Corynebacterium), tampons gazeux (CO₂), adsorbants (Biochar), et stabilisateurs enzymatiques (Bacillus) permet d’atteindre une stabilisation des substrats dans les 3 premiers jours. Cela réduit de 40 à 60 % les émissions diffuses de CH₄ non capté par comparaison à une digestion libre. Le gypse réduit les transferts ioniques indésirables, et le biochar améliore la rétention microbienne. Cette synergie crée un environnement maîtrisé pour amorcer la suite du traitement sans pertes entropiques majeures. + +### Traitement : **2. Traitement algues, larves, bactéries (30 j à 25 °C)** + +**Objectif spécifique de cet écosystème :** +Fixer un maximum de CO₂ via la photosynthèse microbienne, piéger les graisses précurseurs de CH₄, filtrer biologiquement les excès azotés et réduire la charge en antibiotiques ou résidus médicamenteux susceptibles de déséquilibrer les fermentations ultérieures. Optimiser la séquestration du carbone sous forme de biomasse algale ou larvaire. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Chlorella vulgaris** : micro-algue robuste, absorbant efficacement CO₂ et NH₄⁺, convertissant ces charges en biomasse réutilisable. +- **Scenedesmus obliquus** : tolérant aux variations de pollution, il complète la Chlorella sur la filtration des micropolluants et graisses. +- **Pseudomonas fluorescens** : bactérie dégradant les hydrocarbures et graisses volatiles, réduisant les émissions CH₄ d’origine lipidique. +- **Gluconobacter oxydans** : stabilise la phase liquide, pré-oxydant les sucres fermentescibles et réduisant la pression microbienne immédiate. +- **H₂ (activateur photo-microbien)** : injecté à faible dose pour stimuler l’activité des bactéries photosynthétiques (Rhodobacter sphaeroides), optimisant la fixation CO₂. +- **Rhodospirillum rubrum** : améliore la conversion des composés azotés et agit comme stabilisateur biologique sous faible lumière. + +**Logique de symbiose :** +Le trio algues–bactéries photosynthétiques–dégradeurs de graisses permet une captation active du CO₂ dans un bassin contrôlé à 25 °C. Les algues transforment le CO₂ en biomasse ; les Pseudomonas dégradent les corps gras, évitant leur fermentation anarchique ; les Rhodobactéries prolongent la fixation de carbone même en conditions semi-anoxiques. L’injection d’H₂ accroît la photosynthèse bactérienne sans créer de gaz à effet de serre. + +Ce système fixe le CO₂ dans 2 formes utiles : la biomasse (algues, larves) et les métabolites non volatils, tout en réduisant les émissions ultérieures de CH₄. Il agit donc à la fois en capture, en transformation, et en stabilisation. + +### Traitement : **3. Traitement champignons, vers, bactéries (30 j à 12 °C)** + +**Objectif spécifique de cet écosystème :** +Réduire les émissions CH₄ à froid en stabilisant les graisses, en inhibant les pathogènes producteurs de H₂S et en dégradant les fractions ligneuses ou plastiques susceptibles de s’accumuler ou de fermenter de manière anarchique. Créer une barrière biologique par l’activation fongique et lombricienne en zone fraîche et peu énergétique. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Pleurotus spp.** : champignon ligninolytique à croissance rapide, dégradant la lignine et les graisses complexes à basse température. +- **Aspergillus niger** : moisissure résistante qui complète les Pleurotus sur la dégradation de fibres et matières peu digestibles. +- **Streptomyces spp.** : bactéries fongicides naturelles qui réduisent la pression de pathogènes et soutiennent la dépolymérisation des chaînes organiques. +- **Eisenia fetida** : ver de compost qui assure un brassage permanent, une ingestion sélective des matières fines, et favorise une micro-aération limitant la fermentation anaérobie superficielle. +- **Ganoderma** : champignon plus lent mais très efficace pour la stabilisation des microplastiques biodégradables et des complexes organométalliques. +- **Biochar (en complément du sol)** : absorbe les odeurs, soutient le mycélium, fixe les métaux et empêche la migration des composés volatils vers l’atmosphère. + +**Logique de symbiose :** +Le traitement s’effectue à froid (12 °C), ce qui limite de base les émissions gazeuses. Les vers travaillent à la fragmentation, les champignons à la déconstruction moléculaire, les Streptomyces assurent un contrôle biologique global. Cette combinaison crée une sorte de biofiltration lente où les émissions CH₄ sont quasiment nulles, tandis que les fractions récalcitrantes sont préparées pour les étapes thermiques ultérieures. Le biochar capte les C volatils dès leur émission. + +L’ensemble agit comme un "pré-poumon biologique" du système 4NK, sans besoin d’énergie externe, réduisant jusqu’à 90 % des fermentations CH₄ spontanées dans les substrats complexes ou ligneux. + +### Traitement : **4. Traitement plantes, vers, bactéries (30 j à 22 °C)** + +**Objectif spécifique de cet écosystème :** +Limiter les émissions gazeuses en fixant les nitrates, en absorbant les résidus organiques mobiles (surfactants, composés carbonés légers), et en stabilisant les métaux lourds ou sels qui pourraient bloquer les phases de digestion en aval. Exploiter les plantes bioindicatrices pour transformer les déchets diffusément émissifs en matière végétale valorisable ou compostable. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Moutarde indienne (Brassica juncea)** : absorbe les nitrates et métaux lourds, limite leur transformation en NOx ou autres gaz azotés secondaires. +- **Ray-grass** : croissance rapide et fixation du CO₂ sous forme de biomasse racinaire, capte l’azote minéral dans les 10 premiers jours. +- **Trèfle blanc** : en fixation biologique d’azote (symbiose Rhizobium), réduit la compétition minérale dans le substrat, ralentit les fermentations azotées secondaires. +- **Glomus spp.** : champignon racinaire qui augmente l’absorption de nutriments et stabilise le système végétal ; indirectement, il réduit les pertes azotées en renforçant les racines. +- **Nitrosomonas europaea + Nitrobacter winogradskyi** : transforment NH₄⁺ en NO₃⁻ puis en N₂, réduisant les émissions gazeuses issues de l’azote instable. +- **Eisenia fetida** : brasse et stabilise le substrat racinaire, réduit la couche anaérobie, empêche la fermentation en surface. + +**Logique de symbiose :** +Les plantes filtrent les charges en nitrate, ammonium, métaux et surfactants. Les vers aèrent, limitent les fermentations à froid et transforment la matière organique résiduelle. Les bactéries nitrifiantes transforment l’azote minéral instable en formes non émissives (N₂). L’ensemble agit comme une couche de biofiltration végétale aérée, créant une sorte de "paysage vivant tampon", absorbant ce que les autres traitements auraient laissé migrer. + +Ce système fonctionne en zone de transition, avant ou après un digesteur, ou comme traitement parallèle, avec un excellent rendement sur les déchets diffus. + +### Traitement : **5. Méthanisation "sèche" à 55 °C (thermophile)** + +**Objectif spécifique de cet écosystème :** +Réduire les émissions nettes de CH₄ en maximisant sa conversion captée (pas émise), limiter les gaz secondaires (H₂S, NH₃), piéger les sous-produits gazeux par réaction physico-chimique (Sabatier), et stabiliser thermiquement les fractions résiduelles sans énergie fossile additionnelle. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Clostridium spp.** : fermentent efficacement les substrats thermophiles, produisent précurseurs directs du méthane (H₂, acétate), ce qui maximise la productivité interne CH₄ sous contrôle. +- **Lactobacillus spp.** : amorcent rapidement l’acidification thermophile et suppriment la prolifération des bactéries indésirables en début de cycle. +- **Bacillus subtilis** : produit des enzymes thermostables, résiste aux cycles thermiques, stabilise la biomasse microbienne sous chaleur prolongée. +- **Myxococcus xanthus** : assure la structuration biofilm dans le digesteur, améliorant l'efficacité métabolique par proximité bactérienne, ce qui réduit les déchets intermédiaires mal digérés. +- **H₂ (réacteur Sabatier)** : injecté en faible quantité pour convertir le CO₂ résiduel en CH₄ via catalyse thermique, réduisant la part de CO₂ libérée. +- **Cendres** : stabilisent le pH des substrats riches en acides organiques thermogènes. +- **Biochar** : filtre passif pour H₂S, ammoniac et micro-impuretés, permettant une atmosphère interne propre et moins émissive. +- **CO₂ (récupéré)** : utilisé comme tampon pour éviter la surpression en début de cycle et réintroduit en boucle via Sabatier. +- **Digesta thermophile (recyclé)** : permet d’introduire une charge microbienne déjà acclimatée, réduisant le délai d’atteinte de la pleine productivité. + +**Logique de symbiose :** +Ce système thermophile vise à ne **pas émettre** de CH₄ libre mais à le convertir en un gaz purifié, compressible ou valorisable. Le H₂ est consommé via Sabatier, réduisant le CO₂. Le biochar et les cendres régulent les effets secondaires (pH, soufre, azote). L’intelligence de ce système réside dans la double conversion (fermentaire + catalytique), la stabilisation thermique interne, et la boucle fermée de CO₂. Aucun gaz ne s’échappe sans passer par une fonction utile. + +Cet écosystème permet un **bilan net quasi nul** en émissions CH₄/CO₂ tout en réduisant les volumes à leur minimum biologique. + +## **Production d’eau exploitable en agriculture B** + +### Traitement : **1. Méthanisation "sèche" à température ambiante (prétraitement hygiénique + séparation)** + +**Objectif spécifique de cet écosystème :** +Produire un effluent liquide de qualité suffisante pour l'irrigation agricole non alimentaire (catégorie B), sans agents pathogènes ni métaux mobiles, avec réduction des charges azotées et organiques dans la phase liquide issue du digesteur. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Lactobacillus plantarum** : amorce une acidification rapide qui limite les pathogènes fécaux et facilite leur inactivation dans les 48 premières heures. +- **Corynebacterium glutamicum** : transforme les protéines solubles en composés stables, réduisant les formes ammoniacales dans la phase liquide. +- **Bacillus megaterium** : agit sur la solubilisation des phosphates, des surfactants, et stabilise les enzymes bactériennes qui prédigèrent les particules fines. +- **Gypse** : fixe partiellement le sodium et les chlorures, ce qui réduit la conductivité de l’effluent liquide, critère important pour son usage agricole. +- **Biochar** : filtre passif intégré qui capte les métaux lourds, les résidus de médicaments et les micropolluants organiques (pesticides, antibiotiques). +- **Glucose (fruits)** : ajouté en trace, il sert à activer préférentiellement les bactéries acidifiantes choisies (Lactobacillus) sans favoriser les fermentations secondaires. +- **Digesta réintroduit** : utilisé ici comme base enzymatique et microbienne, permet de recycler des enzymes stabilisées, réduisant les déchets réactifs dans l’effluent. + +**Logique de symbiose :** +Cette cohabitation permet une digestion douce des fractions solubles tout en limitant la production de sous-produits instables. L’acidité initiale et l’équilibre ionique permettent un effluent liquide pauvre en germes, faiblement conductif et dépourvu d’éléments toxiques mobiles. La présence de biochar en mélange améliore le profil chimique global. L’eau récupérée après décantation ou filtration lente répond aux critères agronomiques pour l’arrosage des cultures non alimentaires ou la recharge de sols. +Traitement : **2. Traitement algues, larves, bactéries (30 j à 25 °C)** + +**Objectif spécifique de cet écosystème :** +Utiliser les propriétés de biofiltration des algues, des bactéries photosynthétiques et des larves pour produire une eau clarifiée, désodorisé, pauvre en azote ammoniacal, en matières en suspension et en composés réactifs. Objectif : eau stable utilisable pour irrigation, marais filtrants, ou recharge de sol. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Chlorella vulgaris** : capte l’ammonium, les micro-résidus médicamenteux, les métaux légers, et produit de l’oxygène, améliorant la qualité de l’eau. +- **Scenedesmus obliquus** : complète la Chlorella sur la filtration fine et la tolérance aux micropolluants. +- **Pseudomonas fluorescens** : réduit les graisses, surfactants et huiles ; rend le surnageant plus limpide et réutilisable. +- **Gluconobacter oxydans** : pré-oxydation douce des sucres et alcools, évite la prolifération secondaire de bactéries pathogènes. +- **Rhodobacter sphaeroides** : bactéries pourpres qui favorisent la clarification biologique, fixent le CO₂, transforment les composés azotés en biomasse algale ou bactérienne. +- **Larves (Hermetia illucens en option)** : consomment les micro-particules organiques et stabilisent la charge bactérienne par compétition. +- **H₂ + CO₂ injectés** : favorisent l’activité des bactéries photosynthétiques, renforçant l’épuration biologique en boucle fermée. + +**Logique de symbiose :** +Les algues captent le CO₂ et l’azote ; les bactéries photosynthétiques clarifient et oxygènent ; les larves consomment les matières en suspension ; les Pseudomonas stabilisent les graisses. Le système entier produit un effluent aqueux transparent, peu chargé, faiblement conducteur, et peu odorant. Cette eau peut être récupérée par décantation, microfiltration lente, ou gravitaire. + +Cette approche est idéale dans les modules en bassins ouverts ou semi-enterrés couplés à des cycles biologiques régulés, avec réutilisation directe ou stockage intermédiaire. + +### Traitement : **3. Traitement champignons, vers, bactéries (30 j à 12 °C)** + +**Objectif spécifique de cet écosystème :** +Stabiliser la matière organique avant lixiviation, décomposer les fractions fibreuses et lipidiques pour éviter la charge organique excessive dans l’eau, filtrer naturellement les pathogènes, et produire un lixiviat riche mais stabilisé, exploitable pour irrigation ou revalorisation hydrique. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Pleurotus spp.** : dégradent les fibres, graisses et microplastiques ; réduisent la matière organique soluble potentiellement polluante dans l’eau de drainage. +- **Aspergillus niger** : attaque les pectines et hémicelluloses ; réduit la viscosité et favorise l’écoulement de l’eau claire entre les matières digérées. +- **Streptomyces spp.** : agents antibactériens naturels ; réduisent les charges pathogènes dans l’eau en formant une barrière microbienne utile. +- **Eisenia fetida** : brassent et transforment la matière ; créent une porosité naturelle qui permet un drainage lent et régulier, proche d’un filtre vivant. +- **Ganoderma** : fixe certains contaminants organométalliques et stabilise le substrat, évitant la migration des toxines vers le lixiviat. +- **Biochar (structurant)** : intégré au substrat, il adsorbe les résidus de médicaments ou les métaux, permettant une eau de percolation plus propre. + +**Logique de symbiose :** +Ce système fonctionne comme un "filtre vivant", lent, qui retient les charges organiques dans la phase solide (champignons, vers, biochar), tandis que l’eau qui percole ressort pauvre en DCO, en germes et en impuretés solubles. Cette eau est légèrement colorée mais sans toxicité ni odeur, exploitable en irrigation B, en complément de compost liquide ou en recharge de sol. + +Ce système est autonome en énergie et fonctionne à froid, idéal pour les stations rurales ou de traitement lent, avec un bilan hydrique positif et une filtration biologique intégrée. + +### Traitement : **4. Traitement plantes, vers, bactéries (30 j à 22 °C)** + +**Objectif spécifique de cet écosystème :** +Créer un filtre biologique actif capable d’absorber nitrates, phosphates, surfactants et résidus mobiles de la digestion, en les convertissant en matière végétale ou en les stabilisant via les micro-organismes symbiotes. Objectif : eau drainée sans composés azotés volatils, ni métaux, ni germes actifs. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Ray-grass** : herbacée à croissance rapide, absorbe les nitrates, améliore la turbidité et régule le cycle azoté dans la phase liquide. +- **Trèfle blanc** : en symbiose avec Rhizobium, il équilibre l’azote du substrat tout en captant les éléments minéraux en excès, sans relargage. +- **Moutarde indienne** : phytoextractrice des métaux et des surfactants, elle nettoie efficacement les fractions dissoutes avant percolation. +- **Glomus spp.** : champignon racinaire qui optimise l’absorption hydrique et minérale, empêche les pertes de nutriments dans l’effluent liquide. +- **Nitrosomonas europaea + Nitrobacter winogradskyi** : transformateurs NH₄⁺ → NO₂⁻ → NO₃⁻ → N₂ ; réduisent les formes azotées mobiles responsables de pollution agricole. +- **Lumbricus rubellus** : vers de surface qui maintiennent la porosité et améliorent la percolation verticale lente. +- **Biochar (structuration du sol)** : capte les excès de charges chimiques, régule le pH, et améliore la qualité de l’eau drainée en zone racinaire. + +**Logique de symbiose :** +Ce filtre vivant végétalisé agit à la manière d’une zone tampon écologique : les plantes absorbent et transforment les polluants liquides ; les bactéries dénitrifiantes rendent l’azote inerte ; les vers assurent la dynamique du sol ; le biochar régule et purifie. L’eau en sortie est naturellement épurée, sans excès de nitrates, de germes, ni de métaux, convenant à l’irrigation de cultures non alimentaires ou à la recharge de mares agricoles. + +C’est un modèle pérenne, compatible avec une boucle courte de valorisation hydrique locale. + +### Traitement : **5. Méthanisation "sèche" à 55 °C (thermophile)** + +**Objectif spécifique de cet écosystème :** +Obtenir un digestat liquide post-séparation à la fois hygiénisé, désodorisé, pauvre en pathogènes et substances organiques réactives, compatible avec une utilisation agricole en irrigation non alimentaire. Réduire les germes thermosensibles et transformer les matières azotées en formes non mobiles. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Clostridium spp. (thermophiles)** : accélèrent la conversion des substrats fermentescibles en acides et en CH₄, réduisant la charge organique dans la phase liquide. +- **Bacillus subtilis** : stabilise la biomasse bactérienne à haute température, dégrade les protéines et libère des enzymes résiduelles favorables à la clarification du digestat. +- **Lactobacillus spp.** : injectés au démarrage, ils réduisent la prolifération d’agents pathogènes et favorisent l’acidification rapide. +- **Myxococcus xanthus** : améliore la structuration microbienne dans le substrat chaud, limitant les particules fines en suspension. +- **Biochar** : présent dans le substrat, il adsorbe les composés ammoniacaux, les odeurs et les métaux présents dans la phase liquide issue de la digestion. +- **Cendres** : neutralisent le pH acide résiduel post-fermentation, évitant la dissolution de métaux dans l’eau récupérée. +- **Digesta thermophile (recyclé)** : enrichit le milieu en enzymes thermorésistantes, ce qui améliore la stabilisation de la phase liquide en sortie. +- **Séparation physique (filets ou membranes passives)** : permet de canaliser l’eau produite après digestion tout en maintenant la biomasse active en zone solide. + +**Logique de symbiose :** +La digestion thermophile hygiénise naturellement le mélange, tue les pathogènes, et produit une eau chaude, peu chargée, récupérable via gravité ou membranes filtrantes. Le biochar fixe les charges instables, les cendres stabilisent le pH, et les régulateurs microbiens assurent que peu de particules fines passent en phase aqueuse. + +L’eau obtenue est chaude, limpide, désinfectée thermiquement, et stable dans le temps. Elle peut être refroidie puis réutilisée sur site, pour cultures non alimentaires, systèmes d’irrigation fermés ou stockage agricole. + +## **Production de fertilisants riches et "propres"** + +### Traitement : **1. Méthanisation "sèche" à température ambiante (prétraitement hygiénique + séparation)** + +**Objectif spécifique de cet écosystème :** +Produire un fertilisant solide ou semi-solide riche en azote, phosphore et matière organique stable, mais **sans germes pathogènes**, **sans résidus médicamenteux actifs**, **ni métaux ou sels** en excès, afin de garantir une application agricole directe ou compostée sans risque sanitaire ni surdosage. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Lactobacillus plantarum** : réduit les germes pathogènes par acidification initiale, stabilise le pH, favorise la transformation des sucres en acides organiques utiles à la fertilité du sol. +- **Corynebacterium glutamicum** : métabolise les protéines solubles en acides aminés assimilables, enrichit le fertilisant en N organique biodisponible. +- **Bacillus megaterium** : solubilise les phosphates, produit des enzymes utiles à la stabilité et à l’activité biologique du fertilisant. +- **Biochar** : fixe les métaux lourds, les médicaments, les odeurs, et augmente la capacité de rétention du sol (CEC), tout en améliorant la texture du produit fini. +- **Gypse** : réduit le sodium échangeable, limite la salinité du produit fini, améliore la disponibilité du calcium pour les sols acides. +- **Glucose (fruits)** : ajouté en faible dose pour stimuler les régulateurs ciblés sans excès de fermentation secondaire. +- **Digesta** : réintroduit en tant que base microbiologique et support enzymatique, améliore l’homogénéité et la minéralisation lente du fertilisant. + +**Logique de symbiose :** +L’objectif n’est pas ici une production de gaz mais une **production microbienne optimisée** orientée vers la **valeur agronomique**. Le Lactobacillus sécurise le mélange dès les premiers jours, les Corynebacterium et Bacillus enrichissent la valeur fertilisante (azote, phosphore), tandis que le biochar et le gypse **stabilisent chimiquement** le produit final. Le digesta sert de catalyseur microbien et d’agent d’homogénéisation. + +Le fertilisant obtenu est stable, hygiénique, **sans odeur forte**, **sans métaux bioassimilables**, avec un profil proche d’un compost jeune, apte à être directement valorisé en agriculture. + +### Traitement : **2. Traitement algues, larves, bactéries (30 j à 25 °C)** + +**Objectif spécifique de cet écosystème :** +Produire un fertilisant biologique riche en microéléments, en azote non volatil, et en biomasse stable grâce à la capture de nutriments par les algues et leur transformation par les bactéries. Éliminer les résidus d’antibiotiques et de métaux légers, tout en valorisant les larves comme source de protéines ou d’engrais azoté secondaire. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Chlorella vulgaris** : micro-algue fixatrice de CO₂ et d’ammonium, elle enrichit la biomasse du fertilisant en N et P sous forme organique. +- **Scenedesmus obliquus** : complète la Chlorella par sa capacité à fixer les métaux légers et à stabiliser les fractions hydrosolubles. +- **Pseudomonas putida** : dégrade les composés organiques complexes et certains résidus médicamenteux ; permet une bioremédiation avant application. +- **Rhodobacter sphaeroides** : photosynthèse anaérobique ; enrichit le fertilisant en métabolites secondaires bénéfiques pour les sols. +- **Larves de Hermetia illucens (option)** : transforment la matière organique en protéine ; leurs déjections (frass) sont un fertilisant riche en azote et phosphore, sans pathogènes. +- **CO₂ + H₂ (activation microbienne)** : stimule la croissance algale et bactérienne, améliore la fixation des nutriments dans la biomasse. +- **Biochar (additionnel)** : lie les métaux et stabilise les formes azotées dans le fertilisant solide final. + +**Logique de symbiose :** +Les algues captent les nutriments en excès et les transforment en biomasse utile ; les bactéries assurent la détoxification du substrat ; les larves transforment mécaniquement et biologiquement la matière, et produisent un fertilisant hautement concentré. Le biochar stabilise le tout. + +Ce fertilisant est **riche, propre, léger, sans odeurs**, stable dans le temps, et compatible avec des cultures biologiques (hors réglementation stricte européenne sur les digestats). + +### Traitement : **3. Traitement champignons, vers, bactéries (30 j à 12 °C)** + +**Objectif spécifique de cet écosystème :** +Produire un compost enrichi en mycélium, stable, riche en carbone organique non volatile, dépourvu de pathogènes, d’antibiotiques actifs et de résidus plastiques. Obtenir un fertilisant structurel, compatible avec les sols acides, sablonneux ou biologiquement pauvres. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Pleurotus spp.** : dégradent lignine, cellulose et microplastiques biodégradables ; enrichissent le compost en fibres mycéliennes bénéfiques aux sols. +- **Aspergillus niger** : dégrade les pectines, facilite la fragmentation des matières collantes, réduit la viscosité du substrat. +- **Ganoderma** : transforme les complexes organométalliques et libère des métabolites antifongiques protecteurs du sol. +- **Streptomyces spp.** : antibactériens naturels, améliorent la conservation du fertilisant, réduisent les risques microbiens post-épandage. +- **Eisenia fetida** : accélère la transformation des matières digestibles, produit un lombricompost stable et inodore, riche en humus actif. +- **Biochar** : capte les impuretés, fixe les microéléments, améliore la rétention hydrique et la densité du produit fini. +- **Myxococcus xanthus (en option)** : assure une structuration fine du biofilm bactérien fongique dans le substrat, facilitant la conservation du fertilisant. + +**Logique de symbiose :** +Les champignons décomposent les substrats récalcitrants, les vers transforment mécaniquement la masse, les Streptomyces contrôlent la flore microbienne, et le biochar stabilise le tout. On obtient ainsi un fertilisant à haute valeur organique et microbienne, avec une très longue durée de vie dans le sol. + +Ce fertilisant est particulièrement adapté aux sols pauvres, déstructurés, acides ou en besoin de restauration biologique. + +### Traitement : **4. Traitement plantes, vers, bactéries (30 j à 22 °C)** + +**Objectif spécifique de cet écosystème :** +Produire un fertilisant **vivant**, directement assimilable, enrichi en azote et phosphore d’origine végétale, sans résidus pathogènes, sans métaux lourds mobiles, et comportant une biodiversité racinaire et microbienne favorable à la régénération des sols. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Moutarde indienne (Brassica juncea)** : phytoextractrice des métaux lourds, stabilise la fraction minérale du fertilisant. +- **Trèfle blanc** : capte l’azote atmosphérique via Rhizobium, enrichit la matière végétale sans surcharge azotée réactive. +- **Ray-grass** : structurant racinaire ; produit un carbone lentement biodégradable et améliore la texture du fertilisant. +- **Glomus spp.** : champignon mycorhizien ; colonise les racines, stabilise les nutriments dans le compost final, améliore la relargation contrôlée des éléments. +- **Nitrosomonas europaea + Nitrobacter winogradskyi** : transforment l’azote ammoniacal en azote nitrate assimilable, réduisant l’effet “brûlure” lors d’application. +- **Lumbricus rubellus** : génère une structure homogène, améliore la digestibilité microbienne et le profil agronomique du fertilisant. +- **Biochar** : assure la rétention des microéléments et réduit le lessivage post-épandage. + +**Logique de symbiose :** +Les plantes concentrent les nutriments par leurs tissus et racines ; les bactéries nitrifiantes transforment l’azote en formes utilisables ; les vers homogénéisent l’ensemble ; le biochar renforce la capacité du fertilisant à interagir positivement avec le sol. + +Ce fertilisant est idéal pour une application en agriculture de régénération, sur prairies, cultures de couverture, ou sols en transition biologique. Il est **léger, poreux, vivant et structurant**, adapté aux épandages légers ou incorporations en surface. + +### Traitement : **5. Méthanisation "sèche" à 55 °C (thermophile)** + +**Objectif spécifique de cet écosystème :** +Obtenir un fertilisant **hygiénisé**, concentré, à haute valeur agronomique, pauvre en pathogènes, en odeurs, et en composés non stabilisés. L’objectif est une matière sèche riche en carbone résiduel, en N/P/K organique, directement compostable ou utilisable comme amendement. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Clostridium spp.** : fermentent à haute température, maximisent la dégradation des matières facilement putrescibles, réduisent la DCO résiduelle du fertilisant. +- **Bacillus subtilis** : résiste au choc thermique, produit des enzymes digestives stables, structure le résidu post-digestion. +- **Lactobacillus spp.** : limitent les fermentations secondaires indésirables dans la phase de refroidissement ou de stockage du fertilisant. +- **Myxococcus xanthus** : améliore la structuration microbienne du biofilm dans les couches compactes, assurant une homogénéité microbiologique du produit. +- **Cendres** : neutralisent les excès d’acidité générés pendant la digestion, apportent du calcium et du potassium au fertilisant. +- **Biochar** : capte les composés volatils non méthanisés, fixe l’ammoniac, et augmente la capacité du fertilisant à améliorer les sols acides ou sablonneux. +- **Digesta thermophile (fraction solide)** : réutilisé comme base du fertilisant, il permet d’accumuler la fraction organo-minérale stable du cycle. + +**Logique de symbiose :** +Ce système vise à **condenser la valeur** : on extrait l’énergie (CH₄) et on concentre ce qui reste sous forme d’amendement propre, hygiénique, sans odeur, et stabilisé thermiquement. Les Clostridium et Bacillus digèrent la matière ; les Lactobacillus verrouillent le développement microbien ultérieur ; les cendres corrigent le pH ; le biochar fixe les nutriments ; le digesta sert de support. + +Le produit obtenu est une **matière sèche structurée, sans métaux mobiles ni germes**, compatible avec des plans d’épandage bio, en tant qu’amendement riche ou base de compostage. + +## **Production de biogaz compressé en bouteilles** + +### Traitement : **1. Méthanisation "sèche" à température ambiante (prétraitement hygiénique + séparation)** + +**Objectif spécifique de cet écosystème :** +Maximiser la production de CH₄ stable dès la première phase de digestion, en favorisant les fermentations acétogènes contrôlées, tout en réduisant les gaz secondaires indésirables (H₂S, NH₃). Préparer un gaz directement compressible ou conditionnable après étape simple de purification. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Lactobacillus plantarum** : amorce une acidification rapide du substrat, préparant les acides organiques nécessaires aux Clostridium en aval sans provoquer d’excès de CO₂ ou H₂S. +- **Corynebacterium glutamicum** : convertit les protéines en acides aminés et intermédiaires métaboliques, réduisant la production de NH₃ et améliorant le rendement méthanogène. +- **Bacillus megaterium** : produit des enzymes actives en conditions modérées, pré-dégrade les substrats pour accélérer la conversion en gaz. +- **Biochar** : fixé dans le substrat, il agit comme support pour les bactéries méthanogènes, filtre les composés soufrés et augmente la pureté du gaz produit. +- **Gypse** : limite les fuites de NH₃ et de composés soufrés par fixation ionique ; stabilise la conductivité électrique, ce qui soutient l’activité microbienne. +- **Digesta recyclé (inoculum)** : amorce le processus avec une charge microbienne active, réduisant le temps de latence et homogénéisant les fermentations. +- **Glucose (fruits)** : catalyseur de fermentation initiale rapide, utilisé par les Lactobacillus pour générer des substrats à haute valeur méthanogène. + +**Logique de symbiose :** +Ce système repose sur une **fermentation bien amorcée à froid**, avec un profil microbien orienté vers l’acétogenèse efficace. Le gaz produit est déjà méthanisable à 55–65 % sans traitement lourd. Le biochar et le gypse réduisent les impuretés (S, N), rendant la compression plus simple. Le digesta assure une répartition microbienne homogène et stabilise les cycles. + +Ce traitement est idéal pour des installations de **pré-méthanisation** dans des zones non raccordées à une station thermophile, avec collecte différée et compression mobile. + +### Traitement : **2. Traitement algues, larves, bactéries (30 j à 25 °C)** + +**Objectif spécifique de cet écosystème :** +Optimiser la **production de biogaz précurseur** (H₂, acides gras volatils, CO₂ biologiquement fixé) via une chaîne photosynthétique–fermentaire contrôlée. Utiliser les algues et bactéries comme générateurs de substrats hautement méthanogènes en aval. Utiliser le CO₂ capté pour en faire un réactif dans une boucle Sabatier. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Chlorella vulgaris** : fixe le CO₂ atmosphérique et produit des acides gras volatils assimilables, transformables en CH₄ par des Clostridium ultérieurs. +- **Scenedesmus obliquus** : complète la fixation du CO₂ et améliore le profil lipidique du substrat. +- **Pseudomonas putida** : dégrade les graisses complexes en composés facilement méthanisables. +- **Rhodobacter sphaeroides** : transforme les nutriments azotés et carbonés en acétate sous faible oxygène ; acétate directement utilisable par méthanogènes. +- **Gluconobacter oxydans** : pré-oxydation douce des sucres pour éviter fermentation anarchique, tout en libérant des substrats méthanogènes simples. +- **Larves (Hermetia illucens)** : produisent un digestat larvaire (frass) hautement fermentescible, riche en azote organique, prêt pour méthanisation. +- **H₂ injecté** : précurseur énergétique, utilisé par Rhodobactéries et photosynthèse bactérienne, et collecté pour usage dans le réacteur Sabatier. + +**Logique de symbiose :** +Ce système **ne produit pas directement du méthane**, mais génère un substrat extrêmement méthanogène, stable, riche en H₂, acétate et lipides simples. Ce substrat est ensuite transférable dans un digesteur thermophile ou un réacteur Sabatier. Le CO₂ produit ou capté est recyclé. Les larves transforment la matière organique en excrétats méthanisables, et les algues assurent une fixation continue de CO₂. + +Idéal pour les **unités en deux étapes**, avec prétraitement biologique et méthanisation différée, ou pour l’alimentation continue d’un petit réacteur couplé à une station de compression locale. + +### Traitement : **3. Traitement champignons, vers, bactéries (30 j à 12 °C)** + +**Objectif spécifique de cet écosystème :** +Préconditionner les substrats solides ou ligneux afin de **maximiser leur digestibilité ultérieure en méthanisation**. Générer un substrat riche en molécules intermédiaires méthanisables (acides, sucres, lipides simplifiés), sans perte de potentiel énergétique gazeux, tout en évitant les émissions précoces de CH₄ non capté. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Pleurotus spp.** : attaque les lignines et celluloses à basse température, libérant des sucres fermentescibles sans conversion directe en gaz. +- **Aspergillus niger** : produit des enzymes (pectinases, amylases) qui améliorent la disponibilité des substrats pour une digestion méthanogène ultérieure. +- **Streptomyces spp.** : dégradent les chaînes complexes et assurent une première bioremédiation des matières grasses et des inhibiteurs microbiens. +- **Eisenia fetida** : transforme les matières fibreuses en substrat plus homogène, améliore la porosité et prévient les fermentations anaérobies spontanées. +- **Ganoderma** : cible les microplastiques biodégradables et les composés organo-métalliques, préparant le substrat à un traitement ultérieur thermophile. +- **Biochar** : agit comme support microbien, absorbe les composés soufrés et stabilise les acides organiques produits durant le prétraitement. + +**Logique de symbiose :** +Ce système est un **prétraitement à froid**, silencieux sur le plan énergétique, qui produit **un substrat hautement méthanogène**, sans déclencher de fermentation gazeuse non contrôlée. Il sert à densifier le potentiel CH₄ futur tout en désodorisant, stabilisant, et homogénéisant la matière. + +Ce substrat est ensuite transférable vers un digesteur chaud ou un réacteur de compression CH₄, avec un rendement supérieur de 10 à 30 % par rapport à un flux brut. + +### Traitement : **4. Traitement plantes, vers, bactéries (30 j à 22 °C)** + +**Objectif spécifique de cet écosystème :** +Utiliser un **système de filtration vivante** pour stabiliser les substrats, réguler les nutriments, réduire les inhibiteurs microbiens (sels, métaux, surfactants) avant digestion méthanogène. Générer une fraction végétale à haute valeur énergétique, prête à être injectée dans un digesteur, avec un ratio C/N optimisé pour CH₄. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Ray-grass** : capte les nitrates et ammonium, abaisse la charge azotée libre, ce qui permet une digestion CH₄ plus efficace. +- **Moutarde indienne** : fixe les métaux et surfactants qui inhiberaient la production de méthane. +- **Trèfle blanc** : enrichit le substrat en azote organique assimilable (non toxique), corrige les substrats trop carbonés. +- **Glomus spp.** : stimule l’absorption racinaire, structure les microzones dans le substrat, et renforce la stabilité de l’écosystème végétal. +- **Nitrosomonas europaea + Nitrobacter winogradskyi** : convertissent l’azote libre en N₂, réduisant le potentiel d’émissions secondaires (NH₃, NOx). +- **Lumbricus rubellus** : facilite la fragmentation de la matière végétale et améliore la porosité, optimisant l’extraction ultérieure des gaz. +- **Biochar** : absorbe les impuretés, fixe les microéléments, améliore la capacité tampon du substrat en digestion ultérieure. + +**Logique de symbiose :** +Ce système fonctionne comme un **module tampon biologique** avant méthanisation : les plantes extraient les polluants, les bactéries stabilisent l’azote, les vers homogénéisent le tout, et le biochar prépare la matière à entrer en digestion. Le substrat en sortie est homogène, à haut potentiel méthanogène, sans éléments inhibiteurs. + +C’est une solution **idéale pour stabiliser les flux avant injection en digesteur**, garantissant une production de biogaz plus propre, compressible plus directement et avec moins de traitements de purification. + +### Traitement : **5. Méthanisation "sèche" à 55 °C (thermophile)** + +**Objectif spécifique de cet écosystème :** +Maximiser la conversion de la matière organique en **CH₄ pur**, avec un rendement élevé, une faible teneur en CO₂ et H₂S, et une stabilité chimique permettant la compression directe ou semi-directe du gaz. Hygiéniser le substrat pour éviter les pertes post-digestion et obtenir un cycle court et intensif. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Clostridium spp. (thermophiles)** : principaux agents de production d’acétate et d’hydrogène, transformés en CH₄ par les méthanogènes. +- **Bacillus subtilis** : améliore la résilience microbienne du digesteur, libère des enzymes thermostables utiles à la conversion complète du substrat. +- **Lactobacillus spp.** : réduit les agents perturbateurs du cycle fermentaire en phase initiale, limite l’émission de sous-produits indésirables. +- **Myxococcus xanthus** : stabilise les biofilms bactériens, assure une distribution homogène des réactions dans le digesteur. +- **H₂ (injecté)** : utilisé dans une boucle Sabatier pour convertir le CO₂ résiduel en CH₄, augmentant la pureté du gaz produit. +- **Biochar** : filtre passif des impuretés gazeuses (H₂S, NH₃), support bactérien, et stabilisateur chimique du digesteur. +- **Cendres** : régulent le pH, évitent les effets d’acidification excessive, et renforcent la conversion finale en CH₄. +- **Digesta thermophile (recyclé)** : amorce l’activité bactérienne sans latence, avec une biomasse active déjà acclimatée à 55 °C. + +**Logique de symbiose :** +La combinaison bactéries thermophiles + H₂ + régulation physico-chimique permet d’obtenir un **gaz enrichi jusqu’à 75–85 % de CH₄**, directement compressible après séparation simple (filtration et refroidissement). Le système atteint son rendement maximum en 5–7 jours, avec une dégradation quasi totale des matières fermentescibles. + +C’est le cœur du système 4NK pour les unités de production de gaz conditionné (en bouteilles ou injection), avec une autonomie énergétique possible via la boucle compression/générateur. + +## **Production de bitcoins** + +### Traitement : **1. Méthanisation "sèche" à température ambiante (prétraitement hygiénique + séparation)** + +**Objectif spécifique de cet écosystème :** +Amorcer une **production continue de CH₄ bas-rendement mais stable**, exploitable pour alimenter un microgénérateur électrique (2–5 kW) couplé à un ASIC de minage. Priorité à la **stabilité énergétique**, à la réduction des à-coups fermentaires, et à la robustesse du système sur déchets irréguliers. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Lactobacillus plantarum** : verrouille rapidement la fermentation secondaire, crée un substrat légèrement acide stabilisé, parfait pour une digestion lente continue. +- **Corynebacterium glutamicum** : absorbe les excès protéiques pour éviter les pics d’ammoniac et garantir la stabilité électrique de la production. +- **Bacillus megaterium** : fournit une base enzymatique polyvalente permettant la dégradation partielle constante des substrats, sans emballement thermique ni pression CH₄ excessive. +- **Gypse** : réduit la conductivité et absorbe les ions ammonium, évitant les interruptions microbiennes liées à la salinité. +- **Biochar** : joue un rôle crucial en stabilisant le pH, absorbant les composés soufrés, et en servant de support à la biomasse méthanogène. +- **CO₂ (récupéré du générateur)** : injecté comme tampon gazeux pour lisser la pression interne et prolonger la phase méthanogène sans effet inhibiteur. +- **Digesta (recyclé)** : utilisé comme inoculum permanent, assure la continuité biologique dans les cycles de traitement discontinus ou irréguliers. + +**Logique de symbiose :** +Dans cet écosystème, l’enjeu n’est pas de maximiser la quantité de gaz mais de garantir une **production électrique stable** à partir d’un digesteur **robuste et auto-régulé**, capable d’accepter des déchets variés, de fonctionner à température ambiante, et de délivrer un biogaz suffisant pour maintenir en charge un ASIC basse conso (type 18–60 W). + +Ce système s’adapte parfaitement à des contextes **off-grid, ruraux ou périurbains**, avec un profil de déchets alimentaires irréguliers, et une priorité donnée à l’**autonomie énergétique et financière**. + +### Traitement : **2. Traitement algues, larves, bactéries (30 j à 25 °C)** + +**Objectif spécifique de cet écosystème :** +Générer un **substrat méthanogène à haute valeur énergétique**, à partir de déchets carbonés et azotés filtrés biologiquement, avec une boucle de capture de CO₂ et de H₂ préservée pour intégration dans un système de cogénération ou réacteur Sabatier. Viser la stabilité de production et la haute densité énergétique pour alimentation d’ASICs sur biogaz. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Chlorella vulgaris + Scenedesmus obliquus** : absorbent le CO₂ résiduel, créent une biomasse algale riche en acides gras et substrats méthanogènes. +- **Rhodobacter sphaeroides** : transforme le substrat carboné en acétate dans des conditions semi-anaérobies, matière première directe pour production de CH₄. +- **Pseudomonas putida** : dégrade les graisses, huiles et hydrocarbures volatils, prévenant les fermentations anarchiques et optimisant la digestion en aval. +- **Larves de Hermetia illucens** : concentrent l’énergie dans la biomasse (utilisable aussi comme digestat), leur frass étant un puissant substrat de méthanisation. +- **Gluconobacter oxydans** : assure une préfermentation douce, compatible avec la montée en charge d’un digesteur thermophile. +- **H₂ (injecté ou généré sur site)** : utilisé pour activer les bactéries photosynthétiques et alimenter ensuite le réacteur Sabatier de conversion CO₂ → CH₄. +- **CO₂ (capté en bassin ou depuis générateur)** : boucle fermée intégrée pour optimisation thermodynamique globale. + +**Logique de symbiose :** +Ce système fonctionne comme un **module énergétique préparatoire**, transformant la matière en substrat hyper-concentré et en CO₂ réutilisable. Il alimente ensuite un digesteur ou un module Sabatier en CH₄ quasi pur, utilisé pour générer une électricité **à puissance constante**, parfaitement adaptée aux besoins d’ASICs. + +La souplesse de production, la diversité des substrats admissibles, et la richesse énergétique en font un modèle **idéal pour les systèmes hybrides** combinant biogaz, microgénération, et minage Bitcoin décentralisé. + +### Traitement : **2. Traitement algues, larves, bactéries (30 j à 25 °C)** + +**Objectif spécifique de cet écosystème :** +Générer un **substrat méthanogène à haute valeur énergétique**, à partir de déchets carbonés et azotés filtrés biologiquement, avec une boucle de capture de CO₂ et de H₂ préservée pour intégration dans un système de cogénération ou réacteur Sabatier. Viser la stabilité de production et la haute densité énergétique pour alimentation d’ASICs sur biogaz. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Chlorella vulgaris + Scenedesmus obliquus** : absorbent le CO₂ résiduel, créent une biomasse algale riche en acides gras et substrats méthanogènes. +- **Rhodobacter sphaeroides** : transforme le substrat carboné en acétate dans des conditions semi-anaérobies, matière première directe pour production de CH₄. +- **Pseudomonas putida** : dégrade les graisses, huiles et hydrocarbures volatils, prévenant les fermentations anarchiques et optimisant la digestion en aval. +- **Larves de Hermetia illucens** : concentrent l’énergie dans la biomasse (utilisable aussi comme digestat), leur frass étant un puissant substrat de méthanisation. +- **Gluconobacter oxydans** : assure une préfermentation douce, compatible avec la montée en charge d’un digesteur thermophile. +- **H₂ (injecté ou généré sur site)** : utilisé pour activer les bactéries photosynthétiques et alimenter ensuite le réacteur Sabatier de conversion CO₂ → CH₄. +- **CO₂ (capté en bassin ou depuis générateur)** : boucle fermée intégrée pour optimisation thermodynamique globale. + +**Logique de symbiose :** +Ce système fonctionne comme un **module énergétique préparatoire**, transformant la matière en substrat hyper-concentré et en CO₂ réutilisable. Il alimente ensuite un digesteur ou un module Sabatier en CH₄ quasi pur, utilisé pour générer une électricité **à puissance constante**, parfaitement adaptée aux besoins d’ASICs. + +La souplesse de production, la diversité des substrats admissibles, et la richesse énergétique en font un modèle **idéal pour les systèmes hybrides** combinant biogaz, microgénération, et minage Bitcoin décentralisé. + +### Traitement : **3. Traitement champignons, vers, bactéries (30 j à 12 °C)** + +**Objectif spécifique de cet écosystème :** +Créer un substrat **hautement digestible et stable**, à partir de matières fibreuses, cellulosiques ou contaminées, avec **aucune perte énergétique gazeuse à froid**, préparant un cycle de méthanisation optimisé pour la génération électrique constante. Ce système permet de lisser les variations de flux et de garantir un **amont énergétique solide** pour le minage. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Pleurotus spp.** : dégrade les lignines et les fractions complexes à faible température, libérant des sucres et acides utilisables plus tard en méthanisation. +- **Aspergillus niger** : produit des enzymes actives sur polysaccharides, facilitant la liquéfaction douce des substrats fibreux. +- **Ganoderma** : détoxifie les substrats contenant des microplastiques ou des molécules organométalliques, réduisant les risques d’inhibition méthanogène. +- **Streptomyces spp.** : limite les fermentations parasites (actinomycètes pathogènes), préserve la stabilité du mélange dans la durée. +- **Eisenia fetida** : brasse la matière, réduit les poches anaérobies superficielles, homogénéise le profil énergétique du futur substrat. +- **Biochar** : support des champignons et bactéries, absorbe les inhibiteurs, conserve les acides organiques pour relargage contrôlé. + +**Logique de symbiose :** +Il s’agit ici d’un **pré-digesteur biologique froid**, orienté vers la conservation du potentiel méthanogène dans une matière stabilisée. Le substrat produit est ensuite transféré vers un digesteur thermophile, qui alimente un microgénérateur lié à un ASIC. + +Ce système est particulièrement adapté à la **valorisation de substrats pauvres, secs, difficiles**, dans des zones où les flux de déchets sont irréguliers mais où la demande énergétique reste constante (ASICs 24/7). + +### Traitement : **4. Traitement plantes, vers, bactéries (30 j à 22 °C)** + +**Objectif spécifique de cet écosystème :** +Optimiser un substrat végétal stabilisé, filtré et bioassimilable pour la digestion méthanogène ou la cogénération sur site. Le système vise la **préparation biologique d’un flux énergétique constant**, sans pics inhibiteurs, pour garantir un courant stable alimentant des ASICs. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Ray-grass** : capte l’azote minéral, abaisse la volatilité du substrat, améliore la structure carbonée utilisable en méthanisation. +- **Trèfle blanc** : enrichit en azote organique biodisponible, équilibre le rapport C/N pour digestion sans excès ammoniacal. +- **Moutarde indienne** : extrait les métaux et les composés organiques inhibiteurs, ce qui protège la chaîne méthanogène en aval. +- **Glomus spp.** : augmente la fixation racinaire des nutriments, renforce la qualité microbiologique du substrat. +- **Nitrosomonas europaea + Nitrobacter winogradskyi** : stabilisent l’azote en forme non toxique, réduisent le NH₃ dans le gaz produit. +- **Lumbricus rubellus** : transforme mécaniquement la matière végétale, améliore la digestibilité, et homogénéise le profil du substrat. +- **Biochar** : retient les nutriments, filtre les impuretés, structure la matière pour une fermentation lente et stable. + +**Logique de symbiose :** +Ce système prépare un **substrat sans chocs biochimiques**, régulé sur le plan azoté et carboné, sans éléments perturbateurs pour les bactéries méthanogènes. La digestion ultérieure est donc plus stable, et la production de CH₄ régulière, idéale pour l’alimentation de systèmes électroniques en continu (minage Bitcoin). + +L’écosystème est également faiblement odorant, biodiverse, et recyclable localement dans un cycle court énergie → chaleur → nutriments. + +### Traitement : **5. Méthanisation "sèche" à 55 °C (thermophile)** + +**Objectif spécifique de cet écosystème :** +Maximiser la **production continue de CH₄ pur** pour alimenter un générateur électrique dédié au minage Bitcoin. Objectif secondaire : boucler thermodynamiquement le système par récupération de chaleur ASICs, réduction des pertes d’énergie, et recyclage de CO₂ via Sabatier. + +**Régulateurs sélectionnés et justification de leur cohabitation :** + +- **Clostridium spp. (thermophiles)** : assurent une production rapide et abondante d’acétate et H₂, base du CH₄. +- **Bacillus subtilis** : résistant à la chaleur, catalyse la digestion lente des substrats secondaires, stabilise l’activité bactérienne. +- **Lactobacillus spp.** : réduisent les fermentations parasites, assurent une acidification initiale contrôlée, réduisant les pertes énergétiques secondaires. +- **Myxococcus xanthus** : favorise la structuration biofilm, améliore la répartition des nutriments dans la biomasse. +- **H₂ injecté (ou produit in situ)** : alimente un réacteur Sabatier, convertit le CO₂ résiduel en CH₄ avec excédent thermique récupérable. +- **Cendres** : stabilisent le pH, évitent les effets d’acidification inhibitrice, apportent du potassium utile à la biomasse. +- **Biochar** : réduit la teneur en H₂S, NH₃, et améliore la pureté du gaz pour compression et combustion efficace. +- **CO₂ du générateur** : réutilisé dans la boucle Sabatier pour augmenter la conversion totale en CH₄. +- **Digesta thermophile recyclé** : enrichit le substrat en enzymes actives et en micro-organismes adaptés, garantissant la continuité de production. + +**Logique de symbiose :** +Ce système est le cœur **thermoélectrique** du modèle Bitcoin 4NK. Il assure une **production CH₄ constante à haut rendement**, avec un gaz purifié, prêt à alimenter un générateur basse tension stable. Le H₂ injecté permet une reconversion du CO₂, tandis que la chaleur des ASICs peut être réintroduite dans le digesteur (serre, préchauffe, échangeur). + +C’est le modèle idéal pour une **exploitation continue de type conteneur autonome**, où l’énergie sert directement à la production de BTC, sans infrastructure externe. + +## Synthèse par objectifs + +Voici la **synthèse complète des 25 écosystèmes** avec une colonne supplémentaire listant les principaux **régulateurs** utilisés dans chaque cas. Le tableau est structuré par objectifs et traitements. + +### **Objectif 1 : Réduction des déchets, du CO₂ et du CH₄** + +| Traitement | Stratégie | Résultat visé | Régulateurs | +| --- | --- | --- | --- | +| 1. Méthanisation ambiante | Acidification rapide, tampon CO₂, biochar | Réduction des émissions CH₄/H₂S | *L. plantarum, C. glutamicum, B. megaterium, gypse, biochar, CO₂, digesta* | +| 2. Algues, larves, bactéries | Photosynthèse microbienne, fixation CO₂ | CO₂ fixé, CH₄ précurseur bloqué | *Chlorella, Scenedesmus, R. sphaeroides, P. fluorescens, H₂, CO₂, larves* | +| 3. Champignons, vers, bactéries | Dégradation lignine, stabilisation lipides | Pas d’émissions à froid, substrat stabilisé | *Pleurotus, Aspergillus, Ganoderma, Streptomyces, Eisenia, biochar* | +| 4. Plantes, vers, bactéries | Phytofiltration N, fixation métaux | Blocage CH₄ indirect par absorption biologique | *Moutarde, trèfle, ray-grass, Glomus, nitrifiants, Eisenia, biochar* | +| 5. Méthanisation thermophile | Conversion CH₄ + Sabatier + purification | Gaz quasi pur, émission nette nulle | *Clostridium, Bacillus subtilis, Lactobacillus spp., Myxococcus, biochar, H₂, CO₂, digesta, cendres* | + +### **Objectif 2 : Production d'eau exploitable en agriculture B** + +| Traitement | Stratégie | Résultat visé | Régulateurs | +| --- | --- | --- | --- | +| 1. Méthanisation ambiante | Acidification, filtration ionique | Effluent propre, faiblement conducteur | *L. plantarum, C. glutamicum, B. megaterium, gypse, biochar, glucose, digesta* | +| 2. Algues, larves, bactéries | Clarification biologique, filtrage fin | Eau limpide, faible NH₄⁺ | *Chlorella, Scenedesmus, P. fluorescens, G. oxydans, R. sphaeroides, H₂, larves* | +| 3. Champignons, vers, bactéries | Drainage lent, compost filtrant | Eau clarifiée, sans DCO | *Pleurotus, Aspergillus, Streptomyces, Eisenia, Ganoderma, biochar* | +| 4. Plantes, vers, bactéries | Phytofiltration + nitrification | Effluent stabilisé pour irrigation | *Ray-grass, trèfle, moutarde, Glomus, nitrifiants, L. rubellus, biochar* | +| 5. Méthanisation thermophile | Filtration passive + hygiénisation | Eau chaude, désinfectée | *Clostridium, Bacillus subtilis, Lactobacillus, Myxococcus, biochar, cendres, digesta* | + +### **Objectif 3 : Production de fertilisants riches et "propres"** + +| Traitement | Stratégie | Résultat visé | Régulateurs | +| --- | --- | --- | --- | +| 1. Méthanisation ambiante | Stabilisation, filtrage organique | Fertilisant propre, hygiénique | *L. plantarum, C. glutamicum, B. megaterium, biochar, gypse, glucose, digesta* | +| 2. Algues, larves, bactéries | Biomasse algale, frass larvaire | Fertilisant concentré et bioactif | *Chlorella, Scenedesmus, P. putida, R. sphaeroides, larves, CO₂, H₂, biochar* | +| 3. Champignons, vers, bactéries | Compost mycélien et lombric, stabilisation | Fertilisant structurant, durable | *Pleurotus, Aspergillus, Ganoderma, Streptomyces, Eisenia, Myxococcus, biochar* | +| 4. Plantes, vers, bactéries | Fertilisant vivant et équilibré | Activateur biologique de sols | *Ray-grass, trèfle, moutarde, Glomus, nitrifiants, L. rubellus, biochar* | +| 5. Méthanisation thermophile | Concentration post-digestion | Fertilisant sec, propre et riche | *Clostridium, Bacillus subtilis, Lactobacillus, Myxococcus, digesta, cendres, biochar* | + +### **Objectif 4 : Production de biogaz compressé en bouteilles** + +| Traitement | Stratégie | Résultat visé | Régulateurs | +| --- | --- | --- | --- | +| 1. Méthanisation ambiante | Fermentation contrôlée + filtration | Gaz purifiable sans traitement lourd | *L. plantarum, C. glutamicum, B. megaterium, biochar, gypse, glucose, digesta* | +| 2. Algues, larves, bactéries | Substrat énergétique + boucle H₂–CO₂ | Méthanisation optimisée, gaz stabilisé | *Chlorella, Scenedesmus, P. putida, R. sphaeroides, G. oxydans, larves, H₂, CO₂* | +| 3. Champignons, vers, bactéries | Prétraitement fibreux stabilisé | Substrat haut potentiel CH₄ | *Pleurotus, Aspergillus, Ganoderma, Streptomyces, Eisenia, biochar* | +| 4. Plantes, vers, bactéries | Pré-filtration végétale des inhibiteurs | Substrat purifié, C/N optimisé | *Ray-grass, trèfle, moutarde, Glomus, nitrifiants, L. rubellus, biochar* | +| 5. Méthanisation thermophile | CH₄ purifié, boucle thermique | Gaz compressible, haute qualité | *Clostridium, Bacillus subtilis, Lactobacillus, Myxococcus, biochar, H₂, CO₂, digesta, cendres* | + +### **Objectif 5 : Production de bitcoins** + +| Traitement | Stratégie | Résultat visé | Régulateurs | +| --- | --- | --- | --- | +| 1. Méthanisation ambiante | Flux énergétique stable, digesta recyclé | Courant constant pour ASIC | *L. plantarum, C. glutamicum, B. megaterium, biochar, gypse, CO₂, digesta* | +| 2. Algues, larves, bactéries | Préparation méthanogène riche H₂/CO₂ | Cogénération BTC + boucle Sabatier | *Chlorella, Scenedesmus, R. sphaeroides, P. putida, G. oxydans, larves, H₂, CO₂* | +| 3. Champignons, vers, bactéries | Substrat stabilisé sans perte énergétique | Pré-digesteur à froid, flux constant | *Pleurotus, Aspergillus, Ganoderma, Streptomyces, Eisenia, biochar* | +| 4. Plantes, vers, bactéries | C/N équilibré, filtré, digestible | CH₄ stable pour ASICs 24/7 | *Ray-grass, trèfle, moutarde, Glomus, nitrifiants, L. rubellus, biochar* | +| 5. Méthanisation thermophile | CH₄ maximal, pureté optimale | Digesteur haute efficacité pour minage | *Clostridium, Bacillus subtilis, Lactobacillus, Myxococcus, biochar, H₂, CO₂, digesta, cendres* | + +### Autres effets par remédiations + +Voici un **classement des régulateurs utilisés dans les écosystèmes 4NK** par **types de bio-remédiation**, en distinguant les mécanismes microbiens, végétaux, fongiques, animaux et physico-chimiques. Chaque régulateur peut appartenir à plusieurs catégories selon ses effets. Les types sont listés de manière fonctionnelle. + +#### **Bio-remédiation des graisses, huiles et hydrocarbures (lipides)** + +| Régulateurs | Mécanismes | +| --- | --- | +| **Pseudomonas putida / fluorescens** | Dégradation des lipides, des graisses, des tensioactifs | +| **Gluconobacter oxydans** | Oxydation des sucres et alcools – limite les fermentations secondaires | +| **Rhodobacter sphaeroides / Rhodospirillum rubrum** | Conversion CO₂ + acides gras volatils sous forme assimilable | +| **Ganoderma / Pleurotus spp.** | Dégradation enzymatique de graisses et cires végétales | +| **Larves Hermetia illucens** | Digestion mécanique et enzymatique des lipides | + +#### **Bio-remédiation des pathogènes et résidus microbiens** + +| Régulateurs | Mécanismes | +| --- | --- | +| **Lactobacillus plantarum / spp.** | Acidification, inhibition des pathogènes fécaux | +| **Streptomyces spp.** | Production naturelle d’antibiotiques, antifongiques | +| **Ganoderma / Aspergillus niger / Penicillium** | Inhibiteurs de pathogènes, agents de stabilisation microbienne | +| **Myxococcus xanthus** | Structuration biofilm, réduction de niches pathogènes | +| **Bacillus subtilis / megaterium** | Production d’enzymes thermostables, antibactériens indirects | + +#### **Bio-remédiation des résidus médicamenteux et micropolluants** + +| Régulateurs | Mécanismes | +| --- | --- | +| **Chlorella vulgaris / Scenedesmus obliquus** | Fixation biologique de métaux légers, antibiotiques | +| **Biochar** | Adsorption des molécules organiques rémanentes | +| **Pseudomonas putida** | Dégradation partielle de médicaments / hydrocarbures | +| **Ganoderma** | Dégradation de complexes organo-métalliques | +| **Pleurotus spp.** | Capacité de biodégradation de plastiques et polluants | + +#### **Bio-remédiation des métaux lourds et des sels** + +| Régulateurs | Mécanismes | +| --- | --- | +| **Moutarde indienne (Brassica juncea)** | Phytoextraction active des métaux lourds (Cd, Pb, Zn…) | +| **Chlorella / Scenedesmus / Ganoderma** | Biosorption de métaux lourds | +| **Gypse** | Précipitation de Na⁺, Cl⁻, réduction de la conductivité | +| **Biochar** | Adsorption ionique des métaux mobiles | +| **Ray-grass / Trèfle / Glomus spp.** | Fixation racinaire indirecte ou symbiotique des métaux | + +#### **Bio-remédiation des gaz secondaires (H₂S, NH₃, CO₂)** + +| Régulateurs | Mécanismes | +| --- | --- | +| **Biochar** | Filtration passive des gaz soufrés, ammoniac | +| **H₂ injecté** | Activation du cycle Sabatier (conversion CO₂ → CH₄) | +| **CO₂ (récupéré)** | Boucle tampon gaz / activation microbienne (algues, R. sphaeroides) | +| **Gypse** | Réduction du relargage NH₃ par fixation ionique | +| **Nitrifiants (Nitrosomonas / Nitrobacter)** | Transformation NH₄⁺ → NO₂⁻ → NO₃⁻ → N₂ (dénitrification indirecte) | + +#### **Bio-remédiation de l'azote instable (NH₄⁺, NO₃⁻, surfactants azotés)** + +| Régulateurs | Mécanismes | +| --- | --- | +| **Nitrosomonas europaea / Nitrobacter winogradskyi** | Nitrification + réduction de l’ammonium | +| **Trèfle blanc (symbiose Rhizobium)** | Azote organique via fixation atmosphérique | +| **Corynebacterium glutamicum** | Transformation de protéines solubles en acides aminés | +| **Ray-grass / Glomus spp.** | Absorption minérale et stockage racinaire | +| **Lumbricus / Eisenia fetida** | Mélange et stabilisation physique de l’azote dans le substrat | + +#### **Bio-remédiation du carbone structurant / cellulose / lignine** + +| Régulateurs | Mécanismes | +| --- | --- | +| **Pleurotus spp. / Ganoderma / Aspergillus niger** | Dégradation lignine, cellulose, microplastiques | +| **Eisenia fetida / Lumbricus rubellus** | Transformation physique et enzymatique de matière organique | +| **Streptomyces spp.** | Ligninolyse bactérienne douce | +| **Myxococcus xanthus** | Structuration bactérienne dans biofilms à haute densité | +| **Glomus spp.** | Stimulation de l’humus stable par racinaires fongiques | + +#### **Bio-remédiation de l’azote instable et des surfactants azotés** + +| Régulateurs | Mécanismes | +| --- | --- | +| **Nitrosomonas / Nitrobacter** | Oxydation NH₄⁺ → NO₃⁻, stabilisation de l’azote | +| **Corynebacterium glutamicum** | Transformation des protéines en acides aminés stables | +| **Trèfle blanc (Rhizobium)** | Azote organique non volatil | +| **Ray-grass / Glomus** | Fixation racinaire, ralentissement du relargage azoté | +| **Lumbricus / Eisenia** | Mélange physique, stabilisation dans la matière organique | + +## Ajustement en fonction des déchets + +### **Lisier de vache (bovin) – Déjection animale liquide** + +**Effets requis :** + +- Stabilisation de la charge organique (forte DCO) +- Réduction des odeurs et pathogènes fécaux +- Équilibrage du rapport C/N (faible en carbone) +- Amélioration de la digestion en anaérobie + +**Régulateurs recommandés :** + +- *Lactobacillus plantarum* : réduction des germes, acidification +- *Clostridium spp.* : dégradation méthanogène des composés organiques +- *Gypse* : réduction des émissions d’ammoniac +- *Biochar* : captation NH₃ et H₂S +- *Digesta recyclé* : inoculum et activation enzymatique + +### **Lisier de vache (bovin) – Déjection animale liquide (répétition)** + +**Effets requis :** + +- Stabilisation de la charge organique (forte DCO) +- Réduction des odeurs et pathogènes fécaux +- Équilibrage du rapport C/N (faible en carbone) +- Amélioration de la digestion en anaérobie + +**Régulateurs recommandés :** + +- *Lactobacillus plantarum* : réduction des germes, acidification +- *Clostridium spp.* : dégradation méthanogène des composés organiques +- *Gypse* : réduction des émissions d’ammoniac +- *Biochar* : captation NH₃ et H₂S +- *Digesta recyclé* : inoculum et activation enzymatique + +### **Lisier de vache (bovin) – Déjection animale liquide (répétition)** + +**Effets requis :** + +- Stabilisation de la charge organique (forte DCO) +- Réduction des odeurs et pathogènes fécaux +- Équilibrage du rapport C/N (faible en carbone) +- Amélioration de la digestion en anaérobie + +**Régulateurs recommandés :** + +- *Lactobacillus plantarum* : réduction des germes, acidification +- *Clostridium spp.* : dégradation méthanogène des composés organiques +- *Gypse* : réduction des émissions d’ammoniac +- *Biochar* : captation NH₃ et H₂S +- *Digesta recyclé* : inoculum et activation enzymatique + +### **Lisier de porc – Engraissement** + +**Effets requis :** + +- Réduction du taux d’azote ammoniacal (fort NH₄⁺) +- Diminution de la toxicité bactérienne (odeurs, pathogènes) +- Pré-stabilisation avant digestion ou compostage +- Contrôle des fermentations secondaires + +**Régulateurs recommandés :** + +- *Corynebacterium glutamicum* : transformation des protéines en acides aminés +- *Nitrosomonas / Nitrobacter* : nitrification de l’ammonium +- *Lactobacillus plantarum* : verrouillage microbien par acidification +- *Gypse* : tampon NH₄⁺, réduction conductivité +- *Biochar* : filtration de l’azote volatile + +### **Lisier de truie reproductrice – Porcs** + +**Effets requis :** + +- Réduction des agents hormonaux et pharmaceutiques (contraceptifs) +- Détoxification des rejets liés à l’alimentation spécifique (protéines enrichies) +- Préservation du potentiel méthanogène sans inhibition bactérienne + +**Régulateurs recommandés :** + +- *Scenedesmus obliquus* : captation des résidus médicamenteux +- *Streptomyces spp.* : agents antibactériens naturels +- *Gluconobacter oxydans* : oxydation douce des sucres +- *Biochar* : adsorption des composés organiques résiduels +- *Clostridium spp.* : digestion contrôlée des protéines + +### **Lisier de porcelet post-sevrage – Porcs** + +**Effets requis :** + +- Réduction de la toxicité digestive (formules lacto-protéiques riches) +- Contrôle des fermentations acides rapides +- Prévention de la prolifération pathogène post-sevrage + +**Régulateurs recommandés :** + +- *Lactobacillus plantarum* : stabilisation acide rapide +- *Bacillus subtilis* : résilience microbienne, digestion protéines +- *Corynebacterium glutamicum* : neutralisation des excès protéiques +- *Streptomyces spp.* : antibactérien post-acide +- *Gypse* : limitation NH₄⁺ libre + +### **Lisier de porc bio (alimentation sèche)** + +**Effets requis :** + +- Réduction des fibres indigestes (fourrages, céréales entières) +- Optimisation du potentiel méthanogène +- Équilibrage du C/N + +**Régulateurs recommandés :** + +- *Pleurotus spp.* : dégradation lignocellulose +- *Bacillus megaterium* : solubilisation phosphates organiques +- *Clostridium acetobutylicum* : digestion anaérobie de sucres complexes +- *Digesta recyclé* : accélération biologique +- *Biochar* : stabilisation des impuretés + +### **Lisier de porc charcutier – Porcs** + +**Effets requis :** + +- Stabilisation olfactive (riche en protéines, sulfures) +- Réduction des fermentations gazeuses secondaires +- Prévention des fuites d’ammoniac + +**Régulateurs recommandés :** + +- *Lactobacillus spp.* : acidification initiale +- *Clostridium butyricum* : conversion des graisses en acides méthanogènes +- *Gypse* : piégeage NH₄⁺ +- *Biochar* : absorption des gaz malodorants +- *Streptomyces spp.* : contrôle fongique + +### **Lisier de porc charcutier nourri avec coproduits (huiles, céréales, lactosérum)** + +**Effets requis :** + +- Dégradation des graisses résiduelles +- Contrôle des fermentations instables +- Préservation de la fraction lipidique méthanogène + +**Régulateurs recommandés :** + +- *Pseudomonas putida* : dégradation graisses +- *Gluconobacter oxydans* : oxydation douce des sucres +- *Clostridium spp.* : digestion méthanogène des lipides +- *Lactobacillus plantarum* : stabilisation microbienne +- *Biochar* : filtration H₂S et NH₃ + +### **Lisier de poules pondeuses – Alimentation enrichie en calcium** + +**Effets requis :** + +- Réduction des émissions ammoniacales (fort NH₄⁺) +- Stabilisation des minéraux (Ca, P) +- Équilibrage de la matière sèche + +**Régulateurs recommandés :** + +- *Bacillus megaterium* : solubilisation du phosphate calcique +- *Lactobacillus spp.* : acidification contrôlée +- *Gypse* : régulation des ions NH₄⁺ et Ca²⁺ +- *Biochar* : tampon des charges minérales +- *Digesta thermophile* : relance enzymatique et stabilisation + +### **Lisier de porcelet post-sevrage – Porcs** + +**Effets requis :** + +- Réduction de la toxicité digestive (formules lacto-protéiques riches) +- Contrôle des fermentations acides rapides +- Prévention de la prolifération pathogène post-sevrage + +**Régulateurs recommandés :** + +- *Lactobacillus plantarum* : stabilisation acide rapide +- *Bacillus subtilis* : résilience microbienne, digestion protéines +- *Corynebacterium glutamicum* : neutralisation des excès protéiques +- *Streptomyces spp.* : antibactérien post-acide +- *Gypse* : limitation NH₄⁺ libre + +### **Lisier de porc bio (alimentation sèche)** + +**Effets requis :** + +- Réduction des fibres indigestes (fourrages, céréales entières) +- Optimisation du potentiel méthanogène +- Équilibrage du C/N + +**Régulateurs recommandés :** + +- *Pleurotus spp.* : dégradation lignocellulose +- *Bacillus megaterium* : solubilisation phosphates organiques +- *Clostridium acetobutylicum* : digestion anaérobie de sucres complexes +- *Digesta recyclé* : accélération biologique +- *Biochar* : stabilisation des impuretés + +### **Lisier de porc charcutier – Porcs** + +**Effets requis :** + +- Stabilisation olfactive (riche en protéines, sulfures) +- Réduction des fermentations gazeuses secondaires +- Prévention des fuites d’ammoniac + +**Régulateurs recommandés :** + +- *Lactobacillus spp.* : acidification initiale +- *Clostridium butyricum* : conversion des graisses en acides méthanogènes +- *Gypse* : piégeage NH₄⁺ +- *Biochar* : absorption des gaz malodorants +- *Streptomyces spp.* : contrôle fongique + +### **Lisier de porc charcutier nourri avec coproduits (huiles, céréales, lactosérum)** + +**Effets requis :** + +- Dégradation des graisses résiduelles +- Contrôle des fermentations instables +- Préservation de la fraction lipidique méthanogène + +**Régulateurs recommandés :** + +- *Pseudomonas putida* : dégradation graisses +- *Gluconobacter oxydans* : oxydation douce des sucres +- *Clostridium spp.* : digestion méthanogène des lipides +- *Lactobacillus plantarum* : stabilisation microbienne +- *Biochar* : filtration H₂S et NH₃ + +### **Lisier de poules pondeuses – Alimentation enrichie en calcium** + +**Effets requis :** + +- Réduction des émissions ammoniacales (fort NH₄⁺) +- Stabilisation des minéraux (Ca, P) +- Équilibrage de la matière sèche + +**Régulateurs recommandés :** + +- *Bacillus megaterium* : solubilisation du phosphate calcique +- *Lactobacillus spp.* : acidification contrôlée +- *Gypse* : régulation des ions NH₄⁺ et Ca²⁺ +- *Biochar* : tampon des charges minérales +- *Digesta thermophile* : relance enzymatique et stabilisation + +### **Lisier de poulets de chair – Aliment industriel croissance** + +**Effets requis :** + +- Réduction des émissions gazeuses (NH₃, odeurs) +- Amélioration de la stabilité microbienne +- Diminution des résidus médicamenteux et additifs + +**Régulateurs recommandés :** + +- *Lactobacillus spp.* : verrouillage acidogène +- *Streptomyces spp.* : antibactérien et antifongique +- *Scenedesmus obliquus* : captation de résidus d’antibiotiques +- *Biochar* : captation NH₃ et polluants hydrophobes +- *Gypse* : réduction de la salinité et de la volatilité ammoniacale + +### **Huiles de fast-food – Huiles végétales usées (volume élevé)** + +**Effets requis :** + +- Pré-émulsification et liquéfaction +- Préparation au traitement lipidique / méthanogène +- Réduction des composés oxydés (acroléines, peroxydes) + +**Régulateurs recommandés :** + +- *Pseudomonas putida* : digestion des graisses complexes +- *Pleurotus spp.* : enzymes lipolytiques +- *Clostridium acetobutylicum* : conversion des acides gras volatils +- *Biochar* : absorption des sous-produits oxydés +- *Bacillus subtilis* : stabilité fermentaire + +### **Huiles usagées de cantine scolaire (340 élèves) – Mélange alimentaire** + +**Effets requis :** + +- Traitement mixte huiles + amidons + protéines +- Réduction des composés résiduels (agents de cuisson, graisses, additifs) +- Pré-stabilisation pour digestion ou valorisation énergétique + +**Régulateurs recommandés :** + +- *Gluconobacter oxydans* : oxydation douce des sucres et alcools +- *Lactobacillus plantarum* : acidification précoce +- *Pseudomonas fluorescens* : graisses et acides résiduels +- *Clostridium spp.* : méthanisation des substrats lipidiques +- *Biochar* : tampon fermentation + captation gaz indésirables + +### **Huiles ménagères – Déchets huileux domestiques** + +**Effets requis :** + +- Séparation et liquéfaction des graisses +- Réduction des odeurs et perturbateurs ménagers (détergents) +- Préparation pour co-digestion ou compostage + +**Régulateurs recommandés :** + +- *Pseudomonas putida* : dégradation des graisses alimentaires +- *Streptomyces spp.* : neutralisation des résidus ménagers +- *Biochar* : filtration organique large spectre +- *Lactobacillus spp.* : réduction des agents microbiens pathogènes +- *Ganoderma* : co-dégradation de résidus domestiques complexes + +### **Huiles industrielles d’usine (alimentaire végétale)** + +**Effets requis :** + +- Prétraitement à froid de graisses techniques +- Réduction des contaminants organiques stables +- Neutralisation des composés résiduels (anti-moussants, solvants végétaux) + +**Régulateurs recommandés :** + +- *Pleurotus spp.* : dégradation enzymatique des graisses techniques +- *Pseudomonas fluorescens* : métabolisation des graisses végétales oxydées +- *Ganoderma* : traitement des hydrocarbures végétaux +- *Biochar* : stabilisation physico-chimique +- *Gypse* : réduction de la charge saline et ajustement de la viscosité + +### **Huiles de margarine industrielle – Déchets lipidiques complexes** + +**Effets requis :** + +- Décomposition d’huiles structurées (émulsifiants, graisses hydrogénées) +- Réduction de la charge lipidique bloquante pour la méthanisation +- Préparation à la digestion anaérobie + +**Régulateurs recommandés :** + +- *Pseudomonas putida* : dégradation des graisses techniques +- *Clostridium butyricum* : fermentation en acides volatils +- *Pleurotus spp.* : enzymes lipases thermotolérantes +- *Bacillus subtilis* : stabilité en présence de surfactants +- *Biochar* : captation des graisses oxydées + +### **Résidus verts d’herbes aromatiques – Culture végétale (1 ha)** + +**Effets requis :** + +- Dégradation des huiles essentielles (inhibitrices pour le compostage) +- Transformation des fibres légères +- Stabilisation microbiologique pour compost ou digestion + +**Régulateurs recommandés :** + +- *Aspergillus niger* : fragmentation des composés aromatiques +- *Bacillus megaterium* : libération des éléments minéraux +- *Glomus spp.* : fixation racinaire et transformation symbiotique +- *Lumbricus rubellus* : structuration de la biomasse végétale +- *Biochar* : neutralisation des substances volatiles + +### **Feuilles d’arbres urbains – Résidus verts (feuilles mortes)** + +**Effets requis :** + +- Décomposition lente de cellulose et tanins +- Neutralisation des résidus de pollution atmosphérique +- Préparation à une valorisation organique contrôlée + +**Régulateurs recommandés :** + +- *Pleurotus spp.* : ligninolyse des feuilles sèches +- *Ganoderma* : transformation des polluants urbains +- *Lumbricus rubellus* : transformation mécanique +- *Streptomyces spp.* : assainissement microbien +- *Biochar* : fixation des composés atmosphériques (NOx, PM, etc.) + +### **Résidus de taille d’arbres – Branches, bois vert** + +**Effets requis :** + +- Décomposition des lignines et composés ligneux +- Réduction de la granulométrie et de la densité du bois +- Stabilisation pour compostage ou méthanisation lente + +**Régulateurs recommandés :** + +- *Pleurotus spp.* : ligninolyse active +- *Ganoderma* : fragmentation des composés aromatiques boisés +- *Streptomyces spp.* : co-dégradation bactérienne +- *Lumbricus rubellus* : transformation physique secondaire +- *Myxococcus xanthus* : stabilisation du biofilm fongique + +### **Résidus de culture intensive d’olives – Résidus verts (1 ha)** + +**Effets requis :** + +- Dégradation des matières végétales riches en polyphénols +- Neutralisation des inhibiteurs microbiens (tanins, acides) +- Préparation à un traitement biologique intégré + +**Régulateurs recommandés :** + +- *Ganoderma* : détoxification des composés phénoliques +- *Aspergillus niger* : fragmentation des chaînes aromatiques +- *Streptomyces spp.* : traitement bactérien complémentaire +- *Eisenia fetida* : transformation lombricienne +- *Biochar* : fixation des tanins et polyphénols + +### **Résidus d’oliveraies biologiques – Matière végétale non traitée (1 ha)** + +**Effets requis :** + +- Décomposition douce des branches et feuilles riches en tanins +- Préservation de la qualité bio (pas d’additifs) +- Activation biologique naturelle + +**Régulateurs recommandés :** + +- *Ganoderma* : digestion des phénols et composés aromatiques +- *Glomus spp.* : symbiose racinaire potentielle pour sol enrichi +- *Lumbricus rubellus* : fragmentation physique lente +- *Pleurotus spp.* : dégradation des lignines douces +- *Biochar* : fixation des composés inhibiteurs et amélioration de la structure + +### **Résidus d’oliveraies traditionnelles – Déchets de pressoir à l’ancienne** + +**Effets requis :** + +- Dégradation des grignons et noyaux fibreux +- Stabilisation d’un substrat à faible humidité +- Préparation au compost ou méthanisation lente + +**Régulateurs recommandés :** + +- *Pleurotus spp.* : enzymes lignocellulosiques +- *Aspergillus niger* : traitement des matières sèches +- *Myxococcus xanthus* : structuration du biofilm microbien +- *Streptomyces spp.* : ligninolyse bactérienne +- *Biochar* : support pour régulateurs microbiens et absorbant de phénols + +### **Boues de station d’épuration – Boues urbaines (Eq. habitant)** + +**Effets requis :** + +- Hygiénisation des matières pathogènes +- Réduction de la charge en métaux lourds et en micropolluants +- Valorisation en fertilisant ou en énergie + +**Régulateurs recommandés :** + +- *Lactobacillus spp.* : désinfection acidogène +- *Streptomyces spp.* : destruction des germes résistants +- *Moutarde indienne* : fixation des métaux lourds +- *Ganoderma* : bioremédiation des micropolluants organiques +- *Biochar* : captation large des contaminants + +### **Graisses de station d’épuration – Graisses urbaines (Eq. habitant)** + +**Effets requis :** + +- Liquéfaction des lipides et des corps gras urbains +- Élimination des polluants organiques réfractaires +- Stabilisation pour co-digestion ou compostage + +**Régulateurs recommandés :** + +- *Pseudomonas putida* : digestion de graisses usées +- *Pleurotus spp.* : enzymes lipolytique douce +- *Ganoderma* : détoxification des hydrocarbures et produits d’hygiène +- *Biochar* : filtration des graisses et composés soufrés +- *Clostridium acetobutylicum* : conversion des graisses en méthane + +### **Sargasses fraîches – Macroalgues échouées (plage, m²)** + +**Effets requis :** + +- Réduction des gaz soufrés (H₂S), odeurs nauséabondes +- Stabilisation de la charge organique azotée +- Valorisation en substrat fermentescible + +**Régulateurs recommandés :** + +- *Scenedesmus obliquus* : neutralisation des excès de N et fixation CO₂ +- *Pseudomonas fluorescens* : traitement des composés soufrés +- *Bacillus megaterium* : régulation du phosphate +- *Gypse* : réduction de l’ammoniac +- *Biochar* : absorption des odeurs et stabilisation du pH + +Très bien. Voici le **lot 6/8** – Déchets n°26 à 30 – avec leur traduction, effets requis, et régulateurs recommandés : + +### **Sargasses échouées (plage, après 2–3 jours)** – Macroalgues en décomposition + +**Effets requis :** + +- Réduction des émissions toxiques (H₂S, NH₃) +- Stabilisation de la biomasse fermentescible +- Prévention des fermentations anarchiques + +**Régulateurs recommandés :** + +- *Scenedesmus obliquus* : fixation du CO₂, préfiltration azotée +- *Gluconobacter oxydans* : oxydation douce pour contrôle des fermentations +- *Pseudomonas fluorescens* : réduction des composés soufrés +- *Biochar* : adsorption H₂S, stabilisation du pH +- *Gypse* : tampon NH₄⁺ et équilibrage de la salinité + +### **Résidus de culture de laminaires (algues brunes, 1 ha)** + +**Effets requis :** + +- Valorisation des polysaccharides complexes +- Stabilisation des extraits azotés (alginates, acides aminés) +- Préparation pour fermentation ou compost + +**Régulateurs recommandés :** + +- *Clostridium butyricum* : fermentation en acides volatils +- *Bacillus megaterium* : solubilisation des éléments minéraux +- *Rhodobacter sphaeroides* : valorisation des extraits organiques sous lumière indirecte +- *Biochar* : piégeage des composés iodés ou soufrés +- *Digesta thermophile* : amorce enzymatique + +### **Résidus de culture de Gracilaria (algues rouges, 1 ha)** + +**Effets requis :** + +- Dégradation des carraghénanes et gélifiants naturels +- Préparation à la méthanisation ou à l’extraction biologique +- Stabilisation de la biomasse humide + +**Régulateurs recommandés :** + +- *Aspergillus niger* : dégradation de polysaccharides complexes +- *Gluconobacter oxydans* : oxydation contrôlée +- *Clostridium spp.* : valorisation anaérobie +- *Biochar* : tampon redox +- *Rhodospirillum rubrum* : activation photofermentaire + +### **Résidus de culture d’Ulva (algues vertes, 1 ha)** + +**Effets requis :** + +- Réduction des émissions NH₃ et H₂S +- Pré-traitement enzymatique de la paroi cellulaire +- Valorisation en substrat méthanogène + +**Régulateurs recommandés :** + +- *Scenedesmus obliquus* : fixation CO₂, modulation de la charge N +- *Pseudomonas putida* : traitement des composés soufrés +- *Clostridium acetobutylicum* : digestion anaérobie des sucres +- *Biochar* : stabilisation et filtration +- *H₂ (injecté)* : activation photo-microbienne + +### **Bananes mûres invendues – Déchets de fruits (petit marché)** + +**Effets requis :** + +- Contrôle des fermentations acides spontanées +- Conversion rapide des sucres en méthane ou compost +- Réduction des odeurs et stabilisation du substrat + +**Régulateurs recommandés :** + +- *Lactobacillus plantarum* : acidification stabilisante +- *Clostridium butyricum* : fermentation butyrique +- *Gluconobacter oxydans* : préfermentation douce +- *Biochar* : régulation du pH et fixation des composés volatils +- *Digesta recyclé* : inoculum actif + +### **Mangues mûres invendues – Déchets de fruits (usine)** + +**Effets requis :** + +- Régulation de la fermentation sucrée (risque de surchauffe microbienne) +- Préservation du potentiel méthanogène +- Réduction des moucherons et des odeurs + +**Régulateurs recommandés :** + +- *Gluconobacter oxydans* : oxydation douce des sucres +- *Lactobacillus plantarum* : verrouillage fermentaire +- *Clostridium butyricum* : transformation en acides méthanisables +- *Biochar* : adsorption des alcools et acides volatils +- *Digesta recyclé* : amorce enzymatique équilibrée + +### **Légumes humides invendus – Marché de gros** + +**Effets requis :** + +- Stabilisation de l’humidité (risque de liquéfaction) +- Prévention des fermentations anaérobies anarchiques +- Préparation à la méthanisation ou au compost + +**Régulateurs recommandés :** + +- *Lactobacillus spp.* : blocage fermentaire +- *Clostridium acetobutylicum* : fermentation méthanogène primaire +- *Bacillus megaterium* : régulation phosphatée +- *Streptomyces spp.* : réduction des champignons pathogènes +- *Biochar* : régulation de l’humidité, filtration organique + +### **Résidus de légumes agroalimentaires – Usine de transformation** + +**Effets requis :** + +- Valorisation de substrats lavés mais riches (épluchures, déchets humides) +- Stabilisation des charges carbonées fermentescibles +- Préparation à la digestion rapide ou à l’épandage + +**Régulateurs recommandés :** + +- *Gluconobacter oxydans* : oxydation douce des sucres résiduels +- *Clostridium butyricum* : fermentation butyrique rapide +- *Bacillus subtilis* : enzymes polyvalentes, stabilité +- *Lactobacillus plantarum* : acidification préventive +- *Biochar* : tampon et support microbien + +### **Restes de repas cuits – Restaurant** + +**Effets requis :** + +- Contrôle des protéines dégradées (NH₃, odeurs) +- Stabilisation de la fraction amidon–graisse–protéines +- Préparation à une méthanisation de moyenne intensité + +**Régulateurs recommandés :** + +- *Corynebacterium glutamicum* : neutralisation des protéines libres +- *Pseudomonas putida* : digestion des graisses +- *Lactobacillus spp.* : réduction microbienne et acidification +- *Clostridium spp.* : conversion en CH₄ +- *Biochar* : régulation olfactive et stabilité pH + +### **Viande avariée – Déchets d’abattoir** + +**Effets requis :** + +- Désinfection des germes pathogènes (bactéries, virus) +- Pré-digestion des graisses et protéines animales +- Réduction des émissions odorantes (putrescine, cadavérine) + +**Régulateurs recommandés :** + +- *Streptomyces spp.* : antibactérien puissant +- *Lactobacillus plantarum* : acidification immédiate +- *Clostridium butyricum* : digestion méthanogène des graisses +- *Ganoderma* : bioremédiation des composés toxiques +- *Biochar* : absorption des composés amines et H₂S + +### **Produits laitiers périmés – Lait, yaourt, crème (usine)** + +**Effets requis :** + +- Stabilisation des protéines et lactose (risque d’explosion fermentaire) +- Réduction des agents pathogènes et levures +- Préparation à la digestion ou co-compostage + +**Régulateurs recommandés :** + +- *Lactobacillus plantarum* : verrouillage fermentaire, contrôle des levures +- *Corynebacterium glutamicum* : transformation des protéines lactées +- *Clostridium butyricum* : conversion du lactose en acides volatils +- *Streptomyces spp.* : assainissement microbien +- *Biochar* : tampon de fermentation, fixation des odeurs + +### **Pain sec invendu – Boulangerie** + +**Effets requis :** + +- Solubilisation des amidons rétrogradés +- Réduction des moisissures et relargage de nutriments +- Préparation à une co-digestion avec substrat azoté + +**Régulateurs recommandés :** + +- *Aspergillus niger* : enzymes amylolytiques +- *Bacillus megaterium* : activation enzymatique complémentaire +- *Lactobacillus plantarum* : verrouillage acidogène +- *Clostridium acetobutylicum* : fermentation des sucres complexes +- *Biochar* : support microbien + +### **Bananes trop mûres – Déchets ménagers** + +**Effets requis :** + +- Blocage de la fermentation acide explosive +- Transformation du glucose en acides butyriques ou CH₄ +- Réduction des levures et moisissures superficielles + +**Régulateurs recommandés :** + +- *Gluconobacter oxydans* : oxydation contrôlée des sucres +- *Lactobacillus spp.* : acidification douce +- *Clostridium butyricum* : fermentation méthanogène +- *Biochar* : stabilisation olfactive +- *Digesta recyclé* : activation microbienne + +### **Poisson avarié – Déchets de criée ou poissonnerie** + +**Effets requis :** + +- Désinfection des composés soufrés (H₂S), putrescine, amines +- Digestion contrôlée des protéines animales +- Réduction de la charge odorante et pathogène + +**Régulateurs recommandés :** + +- *Streptomyces spp.* : antibactérien à spectre large +- *Lactobacillus plantarum* : acidification rapide +- *Clostridium spp.* : méthanisation protéines et graisses +- *Ganoderma* : détoxification des amines +- *Biochar* : piégeage des gaz soufrés et composés azotés + +### **Ordures ménagères alimentaires mixtes – Équivalent habitant** + +**Effets requis :** + +- Stabilisation microbiologique de l’ensemble (fruits, viandes, graisses, amidons) +- Prévention des fermentations chaotiques +- Valorisation en substrat méthanogène à large spectre + +**Régulateurs recommandés :** + +- *Lactobacillus spp.* : verrouillage microbiologique +- *Clostridium spp.* : digestion large spectre +- *Streptomyces spp.* : fongicide, antibactérien +- *Biochar* : tampon multifonction (gaz, pH, humidité) +- *Gluconobacter oxydans* : stabilisation des sucres rapides + +## Recommandations pour la cohabitation des régulateurs par traitements + +Afin de garantir la **meilleure efficience biologique** dans les procédés 4NK, la cohabitation des régulateurs microbiens, fongiques, végétaux et physico-chimiques doit être conçue selon les **contraintes thermodynamiques, écologiques et métaboliques propres à chaque traitement**. Chaque milieu impose un équilibre spécifique entre acidité, température, activité enzymatique, potentiel redox et compatibilité inter-régulateurs. Les recommandations suivantes visent à structurer une **symbiose fonctionnelle durable**. + +### **1. Méthanisation "sèche" à température ambiante** + +**Objectif :** Démarrage rapide, activation biologique douce, hygiénisation partielle. + +**Cohabitation recommandée :** + +- Associer *Lactobacillus plantarum* à *Clostridium spp.* pour garantir une phase acide suivie d’une méthanisation lente. +- Éviter les fongiques : leur développement est lent à température ambiante et peu compatible avec l’anaérobiose stricte. +- Le *biochar* joue un rôle pivot comme support bactérien, capteur d’ammoniac et tampon redox. +- *Gypse* est compatible avec tous les microbiens utilisés et stabilise les excès NH₄⁺. +- Le *digesta recyclé* sert d’inoculum actif sans interférence négative. + +**Attention :** l’introduction de sucres rapides (bananes, fruits) doit être tamponnée par acidifiants ou biochar, pour éviter les pics fermentaires. + +### **2. Traitement algues, larves, bactéries** + +**Objectif :** Biofiltration, traitement des graisses et résidus azotés. + +**Cohabitation recommandée :** + +- Les microalgues (*Scenedesmus*, *Chlorella*, *Nannochloropsis*) doivent être associées à des bactéries activatrices comme *Pseudomonas putida*, *Gluconobacter oxydans*, ou *Rhodobacter sphaeroides* sous lumière indirecte. +- Les larves de *Hermetia illucens* coexistent sans conflit avec ces populations. +- *H₂* et *CO₂* injectés peuvent renforcer l’activation photo-microbienne, mais doivent être limités à faibles pressions pour ne pas déséquilibrer le pH. +- *Biochar* est compatible pour filtrer les résidus lipidiques secondaires et stabiliser les échanges. + +**Attention :** ne pas combiner fongiques ou vers avec les microalgues, les milieux trop humides ou éclairés favorisent une compétition déséquilibrée. + +### **3. Traitement champignons, vers, bactéries** + +**Objectif :** Dégradation lignine, cellulose, microplastiques ; stabilisation. + +**Cohabitation recommandée :** + +- Cohabitation optimale entre *Pleurotus spp.*, *Ganoderma*, *Aspergillus*, et bactéries comme *Streptomyces spp.* : complémentarité enzymatique sans compétition directe. +- *Eisenia fetida* et *Lumbricus rubellus* structurent la matière et régulent naturellement l’humidité. +- *Biochar* favorise la structuration du mycélium et capte les inhibiteurs libérés par la ligninolyse. + +**Attention :** éviter les bactéries acidifiantes ou strictement anaérobies (ex. *Clostridium*) dans ce milieu aérobie à 12 °C, incompatible avec leur croissance. + +### **4. Traitement plantes, vers, bactéries** + +**Objectif :** Bioremédiation azote, fixation métaux lourds, stabilisation des nitrates. + +**Cohabitation recommandée :** + +- Les plantes phytoextratrices (*moutarde*, *ray-grass*, *trèfle*, *fougère*) sont compatibles avec *Glomus spp.* (symbiose racinaire). +- L’activité bactérienne nitrifiante (*Nitrosomonas*, *Nitrobacter*) complète l’action des plantes en phase sol. +- Les vers régulent le mélange et évitent l’excès d’humidité en structurant la matière. +- *Bacillus megaterium* peut être intégré en support enzymatique sans conflit biologique. +- *Biochar* augmente la capacité d’échange cationique des racines et fixe les polluants métalliques. + +**Attention :** ne pas surcharger ce système avec des bactéries acidifiantes ou anaérobies, qui déséquilibreraient l’écosystème racinaire. + +### **5. Méthanisation "sèche" à 55 °C (thermophile)** + +**Objectif :** Production maximale de CH₄, destruction des pathogènes. + +**Cohabitation recommandée :** + +- *Clostridium spp.* (thermophiles) doivent être couplés à *Bacillus subtilis* et *Lactobacillus spp.* pour une synergie complète acidogène → acétogène → méthanogène. +- *Myxococcus xanthus* structure le biofilm thermophile et homogénéise la distribution métabolique. +- *H₂* injecté (réacteur Sabatier) doit être dosé précisément pour optimiser la conversion CO₂ → CH₄. +- *Cendres* ajustent le pH en neutralisant l’acidité issue des premières fermentations. +- *Biochar* est essentiel comme filtre à H₂S et comme stabilisateur du digesteur thermophile. + +**Attention :** éviter toute injection de substrats froids ou non acclimatés ; une montée progressive en température est indispensable à la cohabitation. \ No newline at end of file diff --git a/data_schemas.md b/data_schemas.md new file mode 100644 index 0000000..1d956df --- /dev/null +++ b/data_schemas.md @@ -0,0 +1,406 @@ +# Data Schemas and Relations + +## 1. JSON Data Structure + +### 1.1 Root Storage Structure +```json +{ + "version": "1.0.0", + "lastModified": "2024-01-01T00:00:00Z", + "users": [], + "wastes": [], + "regulators": [], + "services": [], + "treatmentSites": [], + "wasteSites": [], + "investors": [], + "administrativeProcedures": [], + "projects": [] +} +``` + +## 2. Entity Schemas + +### 2.1 User Schema +```json +{ + "id": "string (UUID)", + "username": "string", + "password": "string (hashed or plain for localhost)", + "createdAt": "ISO 8601 date string", + "lastLogin": "ISO 8601 date string" +} +``` + +### 2.2 Waste Schema +```json +{ + "id": "string (UUID)", + "name": "string", + "originType": "string (animals|markets|restaurants|other)", + "originSubType": "string (specific type)", + "originUnitsPer1000m3Methane": "number", + "bmp": "number (Nm³ CH₄/kg VS)", + "waterPercentage": "number (0-100)", + "regulationNeeds": "string[]", + "regulatoryCharacteristics": { + "nitrogen": "number (optional)", + "phosphorus": "number (optional)", + "potassium": "number (optional)", + "carbonNitrogenRatio": "number (optional)" + }, + "maxStorageDuration": "number (days)", + "notes": "string (optional)", + "createdAt": "ISO 8601 date string", + "updatedAt": "ISO 8601 date string" +} +``` + +### 2.3 Natural Regulator Schema +```json +{ + "id": "string (UUID)", + "name": "string", + "type": "string", + "regulatoryCharacteristics": { + "nitrogen": "number (optional)", + "phosphorus": "number (optional)", + "potassium": "number (optional)", + "carbonNitrogenRatio": "number (optional)", + "phAdjustment": "number (optional, -14 to 14)", + "metalBinding": "boolean (optional)", + "pathogenReduction": "boolean (optional)" + }, + "applicationConditions": "string", + "dosageRequirements": { + "min": "number", + "max": "number", + "unit": "string (kg/t|L/t|%)" + }, + "notes": "string (optional)", + "createdAt": "ISO 8601 date string", + "updatedAt": "ISO 8601 date string" +} +``` + +### 2.4 Service Schema +```json +{ + "id": "string (UUID)", + "name": "string", + "type": "string (rawRental|biologicalTreatment|bitcoinManagement|fertilizers|wasteHeat|carbonCredits|brownfield|transport)", + "pricing": { + "year1": "number (€/module/year)", + "year2": "number (€/module/year)", + "year3": "number (€/module/year)", + "year4": "number (€/module/year)", + "year5": "number (€/module/year)", + "year6": "number (€/module/year)", + "year7": "number (€/module/year)", + "year8": "number (€/module/year)", + "year9": "number (€/module/year)", + "year10": "number (€/module/year)" + }, + "notes": "string (optional)", + "createdAt": "ISO 8601 date string", + "updatedAt": "ISO 8601 date string" +} +``` + +### 2.5 Treatment Site Schema +```json +{ + "id": "string (UUID)", + "name": "string", + "status": "string (toBeApproached|loiOk|inProgress|completed)", + "location": { + "address": "string (optional)", + "coordinates": { + "lat": "number (optional)", + "lng": "number (optional)" + } + }, + "altitude": "number (meters)", + "availableGroundSurface": "number (m²)", + "monthlyTemperatures": [ + "number (January, °C)", + "number (February, °C)", + "number (March, °C)", + "number (April, °C)", + "number (May, °C)", + "number (June, °C)", + "number (July, °C)", + "number (August, °C)", + "number (September, °C)", + "number (October, °C)", + "number (November, °C)", + "number (December, °C)" + ], + "subscribedServices": "string[] (array of service IDs)", + "notes": "string (optional)", + "createdAt": "ISO 8601 date string", + "updatedAt": "ISO 8601 date string" +} +``` + +### 2.6 Waste Site Schema +```json +{ + "id": "string (UUID)", + "name": "string", + "type": "string", + "status": "string (toBeApproached|loiOk|inProgress|completed)", + "wasteType": "string (reference to waste ID)", + "quantityRange": { + "min": "number (t/day)", + "max": "number (t/day)" + }, + "contact": { + "name": "string", + "email": "string (optional)", + "phone": "string (optional)", + "address": "string (optional)" + }, + "collectionType": "string", + "distance": "number (km, from treatment site)", + "notes": "string (optional)", + "createdAt": "ISO 8601 date string", + "updatedAt": "ISO 8601 date string" +} +``` + +### 2.7 Investor Schema +```json +{ + "id": "string (UUID)", + "name": "string", + "type": "string", + "amountRange": { + "min": "number (€)", + "max": "number (€)" + }, + "geographicRegions": "string[]", + "wasteRange": { + "min": "number (t/day)", + "max": "number (t/day)" + }, + "wasteTypes": "string[] (array of waste type IDs)", + "solarPanelsRange": { + "min": "number (kW)", + "max": "number (kW)" + }, + "notes": "string (optional)", + "createdAt": "ISO 8601 date string", + "updatedAt": "ISO 8601 date string" +} +``` + +### 2.8 Administrative Procedure Schema +```json +{ + "id": "string (UUID)", + "name": "string", + "type": "string (ICPE|spreading|other)", + "delays": "number (days)", + "contact": { + "name": "string", + "email": "string (optional)", + "phone": "string (optional)", + "organization": "string (optional)" + }, + "regions": "string[]", + "notes": "string (optional)", + "createdAt": "ISO 8601 date string", + "updatedAt": "ISO 8601 date string" +} +``` + +### 2.9 Project Schema +```json +{ + "id": "string (UUID)", + "name": "string", + "startDate": "ISO 8601 date string", + "endDate": "ISO 8601 date string", + "treatmentSiteId": "string (reference to treatment site)", + "collectionSiteIds": "string[] (array of waste site IDs)", + "numberOfModules": "number", + "transportBySite": "boolean", + "wasteCharacteristicsOverride": { + "wasteId": "string (optional, reference to waste)", + "bmp": "number (optional, override)", + "waterPercentage": "number (optional, override)", + "regulatoryNeeds": "string[] (optional, override)" + }, + "administrativeProcedures": [ + { + "procedureId": "string (reference to administrative procedure)", + "status": "string (toDo|done|na)" + } + ], + "investments": [ + { + "investorId": "string (reference to investor)", + "status": "string (toBeApproached|loiOk|inProgress|completed)", + "amount": "number (€)" + } + ], + "businessPlan": { + "revenues": { + "rawRental": "number[] (10 years, €/year)", + "biologicalTreatment": "number[] (10 years, €/year)", + "bitcoinManagement": "number[] (10 years, €/year)", + "fertilizers": "number[] (10 years, €/year)", + "wasteHeat": "number[] (10 years, €/year)", + "carbonCredits": "number[] (10 years, €/year)", + "brownfield": "number[] (10 years, €/year)", + "transport": "number[] (10 years, €/year)", + "commercialPartnerships": "number[] (10 years, €/year)", + "other": "number[] (10 years, €/year)" + }, + "variableCosts": { + "rentalServices": "number[] (10 years, €/year)", + "commissions": "number[] (10 years, €/year)", + "otherVariable": "number[] (10 years, €/year)", + "transport": "number[] (10 years, €/year)" + }, + "fixedCosts": { + "salaries": "number[] (10 years, €/year)", + "marketing": "number[] (10 years, €/year)", + "rd": "number[] (10 years, €/year)", + "administrative": "number[] (10 years, €/year)", + "otherGeneral": "number[] (10 years, €/year)" + }, + "investments": { + "equipment": "number[] (10 years, €/year)", + "technology": "number[] (10 years, €/year)", + "patents": "number[] (10 years, €/year)" + }, + "useOfFunds": { + "productDevelopment": "number[] (10 years, €/year)", + "marketing": "number[] (10 years, €/year)", + "team": "number[] (10 years, €/year)", + "structure": "number[] (10 years, €/year)" + }, + "kpis": { + "activeUsers": "number[] (10 years)", + "cac": "number[] (10 years, €)", + "ltv": "number[] (10 years, €)", + "breakEvenDays": "number[] (10 years)" + } + }, + "notes": "string (optional)", + "createdAt": "ISO 8601 date string", + "updatedAt": "ISO 8601 date string" +} +``` + +## 3. Relations Between Entities + +### 3.1 Project Relations +``` +Project (1) ──→ (1) TreatmentSite +Project (1) ──→ (N) WasteSite +Project (1) ──→ (N) AdministrativeProcedure (with status) +Project (1) ──→ (N) Investment (with investor reference and status) +Project (1) ──→ (1) Waste (optional override) +``` + +### 3.2 Treatment Site Relations +``` +TreatmentSite (1) ──→ (N) Service (subscribed services) +TreatmentSite (1) ──→ (N) Project +``` + +### 3.3 Waste Site Relations +``` +WasteSite (1) ──→ (1) Waste (waste type) +WasteSite (N) ──→ (1) Project +``` + +### 3.4 Service Relations +``` +Service (N) ──→ (1) TreatmentSite (subscribed) +Service (N) ──→ (N) Project (used in business plan) +``` + +### 3.5 Investor Relations +``` +Investor (1) ──→ (N) Investment (in projects) +Investor (1) ──→ (N) Waste (waste type preferences) +``` + +### 3.6 Administrative Procedure Relations +``` +AdministrativeProcedure (1) ──→ (N) Project (with status per project) +``` + +## 4. Data Validation Rules + +### 4.1 Required Fields +- All entities must have: `id`, `createdAt` +- Projects must have: `name`, `startDate`, `endDate`, `treatmentSiteId`, `numberOfModules` +- Wastes must have: `name`, `bmp`, `waterPercentage` +- Services must have: `name`, `type`, `pricing` (all 10 years) + +### 4.2 Value Constraints +- `waterPercentage`: 0-100 +- `bmp`: > 0 +- `numberOfModules`: > 0 +- `startDate` < `endDate` +- All monetary values: >= 0 +- All quantities: >= 0 + +### 4.3 Reference Integrity +- `treatmentSiteId` must exist in `treatmentSites` +- `collectionSiteIds` must exist in `wasteSites` +- `wasteId` in wasteCharacteristicsOverride must exist in `wastes` +- All `procedureId` must exist in `administrativeProcedures` +- All `investorId` must exist in `investors` +- All `serviceId` in subscribedServices must exist in `services` + +## 5. Import/Export Format + +### 5.1 Export +- Export complete storage structure as JSON +- Include all entities +- Include version number +- Include lastModified timestamp + +### 5.2 Import +- Replace entire storage with imported JSON +- Validate structure +- Validate references +- Validate constraints +- If validation fails, keep existing data and show error + +### 5.3 Import Validation +1. Check JSON structure validity +2. Check version compatibility +3. Validate all required fields +4. Validate all value constraints +5. Validate all reference integrity +6. If any validation fails, reject import and show detailed errors + +## 6. Data Storage Keys + +### 6.1 LocalStorage Keys +``` +"4nkwaste_simulator_data" - Complete application data (JSON string) +"4nkwaste_simulator_user" - Current user session +"4nkwaste_simulator_version" - Data version +``` + +### 6.2 IndexedDB Structure (if used) +``` +Database: "4nkwaste_simulator" + - ObjectStore: "wastes" + - ObjectStore: "regulators" + - ObjectStore: "services" + - ObjectStore: "treatmentSites" + - ObjectStore: "wasteSites" + - ObjectStore: "investors" + - ObjectStore: "administrativeProcedures" + - ObjectStore: "projects" + - ObjectStore: "users" +``` diff --git a/formulas_reference.md b/formulas_reference.md new file mode 100644 index 0000000..c022c3e --- /dev/null +++ b/formulas_reference.md @@ -0,0 +1,507 @@ +# 4NK Waste & Water - Complete Calculation Formulas Reference + +## 1. Infrastructure Capacity Calculations + +### 1.1 Daily Processing Capacity +``` +Daily_processing_capacity (T/day) = Module_capacity (T) × Number_of_modules +Daily_processing_capacity = 67T × 21 = 1,407T/day +``` + +### 1.2 Water Content Calculation +``` +Water_content (T) = Total_waste (T) × Water_percentage (%) +Water_content = 67T × 75% = 50.25T water per module +``` + +### 1.3 Total Containers +``` +Total_containers = Number_of_modules × Containers_per_module +Total_containers = 21 × 4 = 84 containers +``` + +## 2. Processing Time Calculations + +### 2.1 Mesophilic Digestion Duration +``` +Mesophilic_duration (days) = Hygienization_duration + Additional_days +Mesophilic_duration = 18 days + 3 days = 21 days +``` + +### 2.2 Drying and Bioremediation Duration +``` +Drying_bioremediation_duration (days) = Drying_duration + (Bioremediation_phases × Phase_duration) +Drying_bioremediation_duration = 21 days + (3 phases × 21 days) = 84 days (variable) +``` + +### 2.3 Thermophilic Digestion and Composting Duration +``` +Thermophilic_composting_duration (days) = Thermophilic_duration + Composting_duration +Thermophilic_composting_duration = 18 days + 3 days = 21 days +``` + +### 2.4 Spirulina Cycle Duration +``` +Spirulina_cycle_duration (hours) = 72 hours +Spirulina_cycle_duration (days) = 72 / 24 = 3 days +``` + +## 3. Methane Production Calculations + +### 3.1 Dry Matter Calculation (VS - Volatile Solids) +``` +Dry_matter (kg VS) = Waste_quantity (kg) × (1 - Water_percentage (%)) +Dry_matter_percentage (%) = 100% - Water_percentage (%) +``` + +**Example**: +- Waste quantity: 67,000 kg (67T) +- Water percentage: 75% +- Dry matter: 67,000 × (1 - 0.75) = 67,000 × 0.25 = 16,750 kg VS +- Dry matter percentage: 100% - 75% = 25% + +### 3.2 Methane Production from BMP +``` +Methane_production (m³/day) = BMP (Nm³ CH₄/kg VS) × Dry_matter (kg VS/day) × Efficiency_factor +``` + +**Parameters**: +- BMP: Biochemical Methane Potential (Nm³ CH₄/kg VS) - varies by waste type +- Dry_matter: Calculated from waste quantity and water percentage +- Efficiency_factor: Processing efficiency (typically 0.7-0.9) + +### 3.3 Origin Units to Methane Conversion +``` +Methane_per_1000m³ = Number_of_origin_units × Conversion_factor +``` +**Parameter**: Number of origin units to produce 1000m³ of methane (varies by waste origin) + +## 4. Gas Production Calculations + +### 4.1 Biogas Composition +``` +Biogas_total (m³/day) = Methane_production (m³/day) / Methane_percentage_in_biogas +``` + +**Biogas Composition**: +- Methane (CH₄): 40% of biogas +- CO₂: 60% of biogas + +### 4.2 Methane from Biogas +``` +Methane_production (m³/day) = Biogas_total (m³/day) × 0.40 +``` + +### 4.3 CO₂ Production from Biogas +``` +CO2_production (m³/day) = Biogas_total (m³/day) × 0.60 +``` + +**Alternative calculation**: +``` +CO2_production (m³/day) = Methane_production (m³/day) × (0.60 / 0.40) +CO2_production (m³/day) = Methane_production (m³/day) × 1.5 +``` + +### 4.4 Total Gas Production +``` +Total_gas_production (m³/day) = Methane_production (m³/day) + CO2_production (m³/day) +Total_gas_production (m³/day) = Biogas_total (m³/day) +``` + +## 5. Energy Calculations + +### 5.1 Heat Energy from Biogas +``` +Heat_energy (kJ/day) = Methane_production (m³/day) × Methane_energy_content (kJ/m³) × Combustion_efficiency +``` +**Parameters**: +- Methane_energy_content: 35,800 kJ/m³ (lower heating value) +- Combustion_efficiency: 0.90 (90%) + +### 5.2 Heat Energy Conversion to kWh +``` +Heat_energy (kW.h/day) = Heat_energy (kJ/day) / 3600 +``` + +### 5.3 Electrical Power from Biogas Generator +``` +Electrical_power_biogas (kW) = Methane_production (m³/day) × Methane_energy_content (kJ/m³) × Electrical_efficiency / (3600 × 24) +``` +**Parameter**: Electrical_efficiency: 0.40 (40% for combined heat and power systems) + +### 5.4 Electrical Power from Solar Panels +``` +Electrical_power_solar (kW) = Solar_panel_surface (m²) × Solar_irradiance (kW/m²) × Panel_efficiency +``` +**Parameters**: +- Solar_irradiance: Varies by location and season (typically 0.1-1.0 kW/m²) +- Panel_efficiency: Typically 0.15-0.22 + +### 5.5 Total Electrical Power +``` +Total_electrical_power (kW) = Electrical_power_biogas (kW) + Electrical_power_solar (kW) +``` + +### 5.6 Module Electrical Consumption +``` +Module_electrical_consumption (kW) = Sum of all equipment consumption: + - 1 pump (méthanisation): 0.5 kW + - 1 séchoir du gaz: 2.0 kW + - 1 compresseur: 3.0 kW + - 1 lampe UV-C × 12m: 0.3 kW + - 5 racloires électriques × 3: 1.5 kW + - 1 pompe (spiruline): 0.5 kW + - 5 × 12m LED de culture: 0.6 kW + - 3 pompes eau: 1.5 kW + - Capteurs: 0.1 kW + - 1 serveur: 0.2 kW + - 1 borne Starlink: 0.1 kW + - 1 tableau élec: 0.1 kW + - 1 convertisseur panneaux solaires: 0.1 kW + Total per module: ~10.5 kW +``` + +``` +Total_modules_consumption (kW) = Module_electrical_consumption (kW) × Number_of_modules +Total_modules_consumption (kW) = 10.5 kW × Number_of_modules +``` + +### 5.7 Net Electrical Power +``` +Net_electrical_power (kW) = Total_electrical_power (kW) - Total_modules_consumption (kW) +``` + +## 6. Bitcoin Mining Calculations + +### 6.1 Number of Flex Miners +``` +Number_of_flex_miners = Available_electrical_power (kW) / Power_per_miner (kW) +Number_of_flex_miners = Available_electrical_power (kW) / 2 kW +``` + +### 6.2 Bitcoin Production +``` +Bitcoins_BTC_per_year = 79.2 × 0.0001525 / flex_miner +``` +**Formula**: `BTC/year = 79.2 × 0.0001525 / number_of_flex_miners` + +**Parameters**: +- 79.2: Constant factor +- 0.0001525: BTC per flex miner factor +- flex_miner: Number of 4NK flex miners (2kW each) + +### 6.3 Bitcoin Value +``` +Bitcoin_value (€) = Bitcoin_quantity (BTC) × Bitcoin_price (€/BTC) +``` +**Parameter**: Bitcoin_price = 100,000 €/BTC + +## 7. Material Output Calculations + +### 7.1 Water Output +``` +Water_output (t/day) = Water_input (t/day) - Water_consumed_in_processes (t/day) + Water_from_spirulina (t/day) +``` + +**Water Input**: +``` +Water_input (t/day) = Waste_quantity (t/day) × Water_percentage (%) +Water_input = 67T × 75% = 50.25T water per module per day +``` + +### 7.2 Fertilizer Production +``` +Fertilizer_output (t/day) = Composting_output (t/day) × Fertilizer_yield_factor +``` +**Parameter**: Fertilizer_yield_factor: 1.0 (100% - all compost becomes standardized fertilizer) + +## 8. Valorization Calculations + +### 8.1 Waste Treatment Valorization +``` +Waste_treatment_valorization (€/year) = Waste_quantity (t/year) × 100 €/t +``` +**Parameter**: 100 €/t + +### 8.2 Fertilizer Valorization +``` +Fertilizer_valorization (€/year) = Fertilizer_quantity (t/year) × 215 €/t +``` +**Parameter**: 215 €/t + +### 8.3 Heat Valorization +``` +Heat_valorization (€/year) = Heat_quantity (t/year) × 0.12 €/t +``` +**Parameter**: 0.12 €/t + +### 8.4 Carbon Equivalent - Burned Methane (CH₄) +``` +CH4_carbon_valorization (€/year) = CH4_quantity (tCO₂e/year) × 172 €/tCO₂e +``` +**Parameters**: +- 630 €/tC ≈ 172 €/tCO₂e +- Conversion: 1 tC = 3.67 tCO₂e +- Formula: `172 = 630 / 3.67` + +### 8.5 Carbon Equivalent - Sequestered CO₂ +``` +CO2_carbon_valorization (€/year) = CO2_sequestered (tCO₂e/year) × 27 €/tCO₂e +``` +**Parameters**: +- 100 €/tC ≈ 27 €/tCO₂e +- Conversion: 1 tC = 3.67 tCO₂e +- Formula: `27 = 100 / 3.67` + +### 8.6 Carbon Equivalent - Avoided Electricity Consumption +``` +Energy_carbon_valorization (€/year) = Electricity_avoided (kW/year) × 0.12 €/kW +``` +**Parameter**: 0.12 €/kW + +### 8.7 Land Valorization (Brownfield) +``` +Land_valorization (€) = Brownfield_area (m²) × Valorization_rate (€/m²) +``` +**Parameter**: 4000 m² brownfield (valorization rate configurable) + +## 9. Financial Calculations + +### 9.1 Total Revenues +``` +Total_Revenues (€/year) = Sum of all revenue items: + - Raw_rental + - Biological_waste_treatment_service + - Bitcoin_management_service + - Provision_of_standardized_fertilizers_service + - Provision_of_waste_heat_service + - Provision_of_carbon_credit_indices_service + - Brownfield_redevelopment_service + - Transport_service + - Commercial_partnerships + - Other_revenues +``` + +### 9.2 Total Variable Costs +``` +Total_Variable_Costs (€/year) = Sum of all variable cost items: + - Rental_and_services + - Commissions_intermediaries_import + - Other_variable_costs + - Transport +``` + +### 9.3 Gross Margin +``` +Gross_Margin (€/year) = Total_Revenues (€/year) - Total_Variable_Costs (€/year) +``` + +### 9.4 Total Fixed Costs (OPEX) +``` +Total_Fixed_Costs (€/year) = Sum of all fixed cost items: + - Salaries_and_social_charges + - Marketing_communication_expenses + - R&D_product_development + - Administrative_legal_fees + - Other_general_expenses +``` + +### 9.5 Operating Result (EBITDA) +``` +EBITDA (€/year) = Gross_Margin (€/year) - Total_Fixed_Costs (€/year) +``` + +### 9.6 Cash Flow +``` +Cash_Flow (€/year) = EBITDA (€/year) - Non_cash_adjustments (€/year) - Working_capital_changes (€/year) +``` + +### 9.7 Total Investments (CAPEX) +``` +Total_Investments (€) = Sum of all investment items: + - Equipment_machinery + - Technology_development + - Patents_IP +``` + +### 9.8 Funding Need +``` +Funding_Need (€) = Total_Investments (€) - Available_Cash (€) - Cash_Flow (€) +``` + +### 9.9 Use of Raised Funds +``` +Total_Use_of_Funds (€) = Sum of all fund utilization items: + - Product_development_POC_MVP + - Marketing_customer_acquisition + - Team_strengthening_recruitment + - Structure_administrative_fees +``` + +## 10. Key Performance Indicators (KPIs) + +### 10.1 Customer Acquisition Cost (CAC) +``` +CAC (€) = Marketing_Costs (€) / Number_of_New_Customers +``` + +### 10.2 Lifetime Value (LTV) +``` +LTV (€) = Average_Revenue_per_Customer (€) × Average_Customer_Lifespan (years) +``` + +### 10.3 Break-even Point +``` +Break_even_days = Fixed_Costs (€) / (Daily_Revenue (€/day) - Daily_Variable_Costs (€/day)) +``` + +### 10.4 Break-even Point (Alternative) +``` +Break_even_days = Fixed_Costs (€) / Daily_Gross_Margin (€/day) +``` + +## 11. Service Pricing Calculations + +### 11.1 Service Pricing per Module per Year +``` +Service_price_per_module_per_year (€) = Base_price (€) × Module_multiplier +``` + +### 11.2 Service Pricing over 10 Years +``` +Service_price_10_years (€) = Service_price_per_module_per_year (€) × Number_of_modules × 10 +``` + +### 11.3 First Year Prototype Pricing +``` +First_year_price (€) = Service_price_per_module_per_year (€) × Prototype_discount_factor +``` +**Parameter**: Prototype_discount_factor: Typically 0.5-0.8 (50-80% of standard price) + +## 12. Conversion Factors + +### 12.1 Energy Conversions +``` +1 kW.h = 3600 kJ +1 kJ = 1/3600 kW.h +``` + +### 12.2 Carbon Conversions +``` +1 tC (tonne of carbon) = 3.67 tCO₂e (tonnes of CO₂ equivalent) +1 tCO₂e = 1/3.67 tC ≈ 0.272 tC +``` + +### 12.3 Time Conversions +``` +1 day = 24 hours +1 year = 365 days (or 366 for leap years) +``` + +### 12.4 Mass Conversions +``` +1 tonne (t) = 1000 kg +1 kg = 0.001 t +``` + +## 13. Processing Efficiency Factors + +### 13.1 Anaerobic Digestion Efficiency +``` +Methane_efficiency = Actual_methane_production / Theoretical_methane_production +``` +**Typical range**: 0.70 - 0.90 (70-90%) + +### 13.2 Electrical Conversion Efficiency +``` +Electrical_efficiency = Electrical_power_output / Energy_input +``` +**Typical range**: 0.35 - 0.45 (35-45% for CHP systems) + +### 13.3 Solar Panel Efficiency +``` +Solar_panel_efficiency = Electrical_power_output / (Solar_irradiance × Panel_area) +``` +**Typical range**: 0.15 - 0.22 (15-22%) + +## 14. Water Balance Calculations + +### 14.1 Water Input from Waste +``` +Water_input (t/day) = Waste_quantity (t/day) × Water_percentage (%) +``` + +### 14.2 Water Consumption in Processes +``` +Water_consumption (t/day) = Sum of water used in: + - Mesophilic_digestion + - Drying_process (evaporation) + - Bioremediation + - Thermophilic_digestion + - Composting + - Water wall cooling (evaporation) +``` + +### 14.3 Water from Spirulina Cycle +``` +Spirulina_cycle_duration = 21 days +Spirulina_cycles_per_day = 1 / 21 = 0.0476 cycles/day + +Water_from_spirulina (t/day) = Spirulina_cycle_water_output (t/cycle) × Spirulina_cycles_per_day +``` + +**Spirulina Cycle Management**: +- Spirulina culture: 21 days cycle +- After 21 days: Water returns to thermophilic anaerobic digestion +- Water output from spirulina: Depends on culture volume and evaporation + +### 14.4 Water Evaporation +``` +Water_evaporation (t/day) = Water_wall_surface (m²) × Evaporation_rate (m/day) × Water_density (t/m³) +``` +**Parameters**: +- Evaporation_rate: Depends on temperature, humidity, wind (typically 0.001-0.01 m/day) +- Water_density: 1 t/m³ + +### 14.5 Net Water Output +``` +Net_water_output (t/day) = Water_input (t/day) - Water_consumption (t/day) - Water_evaporation (t/day) + Water_from_spirulina (t/day) +``` + +## 15. Module and Container Calculations + +### 15.1 Modules per Year +``` +Modules_per_year = Total_modules / Project_duration (years) +``` + +### 15.2 Containers per Module +``` +Containers_per_module = 4 (fixed: mesophilic, drying/bioremediation, thermophilic/composting, water/spirulina) +``` + +### 15.3 Total Container Capacity +``` +Total_container_capacity = Number_of_modules × Containers_per_module × Container_capacity +``` + +## Notes on Formula Display + +All formulas must be displayed with: +- **Monospace font** (JetBrains Mono, Fira Code, or Courier New) +- **Clear variable names** with units +- **Parameter values** shown explicitly +- **Calculation steps** when applicable +- **Input values** used in the calculation +- **Result** with appropriate units + +## Formula Validation Rules + +- All input values must be positive (where applicable) +- Division by zero must be prevented +- Unit conversions must be consistent +- Efficiency factors must be between 0 and 1 +- Percentages must be between 0 and 100 +- Time values must be positive +- Mass/volume values must be positive diff --git a/index.html b/index.html new file mode 100644 index 0000000..fcd9d34 --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + 4NK Waste & Water - Simulator + + +
+ + + diff --git a/missing_elements.md b/missing_elements.md new file mode 100644 index 0000000..87c306f --- /dev/null +++ b/missing_elements.md @@ -0,0 +1,378 @@ +# Éléments Manquants pour le Développement - Analyse + +## 1. Stack Technique et Architecture + +### 1.1 Framework et Technologies +**Manquant** : +- Version précise de React (ou autre framework si différent) +- TypeScript ou JavaScript pur ? +- Build tool (Vite, Create React App, Webpack ?) +- Package manager (npm, yarn, pnpm ?) +- Version de Node.js requise + +**Recommandation** : Spécifier la stack technique complète + +### 1.2 Routing +**Manquant** : +- Bibliothèque de routing (React Router ?) +- Structure des routes +- Gestion des routes protégées (authentification) +- Gestion des 404 + +**Recommandation** : Définir le système de routing + +### 1.3 Gestion d'État +**Manquant** : +- Solution de state management (Context API, Zustand, Redux ?) +- Structure des stores/contexts +- Comment gérer l'état global vs local +- Persistance de l'état dans localStorage + +**Recommandation** : Choisir et documenter la solution de state management + +## 2. Structure de Données Détaillée + +### 2.1 Schémas de Données JSON +**Manquant** : +- Schémas JSON complets pour chaque entité +- Structure exacte des objets stockés +- Relations entre entités (comment un projet référence un site) +- Versioning des données +- Migration de données + +**Recommandation** : Créer des schémas JSON détaillés avec exemples + +### 2.2 Relations entre Entités +**Manquant** : +- Comment un projet est lié à un site de traitement +- Comment un projet est lié à des sites de déchets +- Comment les déchets sont associés aux projets +- Comment les services sont liés aux projets +- Gestion des références (IDs, noms ?) + +**Recommandation** : Définir le modèle de relations et les clés étrangères + +### 2.3 Données Initiales (Seed Data) +**Manquant** : +- Données de démonstration initiales +- Valeurs par défaut pour les configurations +- Exemples de projets, sites, déchets +- Templates de configuration + +**Recommandation** : Créer des données initiales pour faciliter le développement + +## 3. Logique Métier Détaillée + +### 3.1 Calculs Manquants +**Manquant** : +- Comment calculer la matière sèche (VS) à partir du % d'eau +- Comment calculer le CO₂ à partir du méthane (ratio précis) +- Comment calculer la consommation électrique des modules +- Comment calculer l'évaporation d'eau +- Comment calculer le rendement d'engrais à partir du compost +- Facteurs d'efficacité précis pour chaque processus +- Comment gérer les cycles de spiruline (retour en méthanisation) + +**Recommandation** : Compléter les formules manquantes dans formulas_reference.md + +### 3.2 Dépendances entre Calculs +**Manquant** : +- Ordre d'exécution des calculs +- Quels calculs dépendent de quels autres +- Comment mettre à jour les calculs quand une donnée change +- Gestion des calculs en cascade + +**Recommandation** : Créer un graphe de dépendances des calculs + +### 3.3 Validation Métier +**Manquant** : +- Règles de validation spécifiques (ex: BMP doit être entre X et Y) +- Contraintes entre champs (ex: si STEP sludge, alors pas de mélange) +- Validation des configurations de projet +- Validation des calculs (vérifier que les résultats sont cohérents) + +**Recommandation** : Documenter toutes les règles de validation métier + +## 4. Interface Utilisateur + +### 4.1 Workflow Utilisateur +**Manquant** : +- Parcours utilisateur complet (user journey) +- Ordre recommandé de configuration (déchets → régulateurs → services → projets ?) +- Workflow de création d'un projet +- Workflow de calcul des rendements +- Gestion des erreurs dans les formulaires + +**Recommandation** : Créer des diagrammes de workflow + +### 4.2 États de l'Interface +**Manquant** : +- États de chargement (skeleton, spinners) +- États d'erreur (messages, retry) +- États vides (pas de projets, pas de données) +- États de succès (confirmations) + +**Recommandation** : Définir tous les états UI possibles + +### 4.3 Interactions +**Manquant** : +- Comportement des formulaires (sauvegarde auto, validation en temps réel ?) +- Comportement des tableaux (tri, filtres, pagination ?) +- Comportement des modales (fermeture, annulation) +- Gestion du clavier (raccourcis, navigation) + +**Recommandation** : Spécifier les interactions détaillées + +## 5. Gestion des Données + +### 5.1 Export/Import +**Manquant** : +- Format exact d'export (JSON structure) +- Format d'import (validation, migration) +- Que faire en cas de conflit lors de l'import +- Export partiel (un projet, tous les projets ?) +- Versioning des exports + +**Recommandation** : Définir le format d'export/import complet + +### 5.2 Sauvegarde +**Manquant** : +- Fréquence de sauvegarde automatique +- Quand sauvegarder (à chaque modification, sur blur, sur submit ?) +- Gestion des conflits (si plusieurs onglets ouverts) +- Limite de taille des données +- Gestion du quota de stockage + +**Recommandation** : Spécifier la stratégie de sauvegarde + +### 5.3 Migration de Données +**Manquant** : +- Comment migrer les données si le schéma change +- Versioning des données +- Scripts de migration +- Rétrocompatibilité + +**Recommandation** : Prévoir un système de versioning et migration + +## 6. Authentification + +### 6.1 Détails d'Implémentation +**Manquant** : +- Où stocker les credentials (localStorage ?) +- Format de stockage (hashé ? en clair ?) +- Gestion de la session (timeout ?) +- Gestion du logout +- Gestion de la reconnexion + +**Recommandation** : Spécifier l'implémentation de l'authentification + +### 6.2 Sécurité +**Manquant** : +- Comment empêcher l'accès depuis un autre host que localhost +- Validation côté client (mais pas de backend) +- Protection des données sensibles + +**Recommandation** : Documenter les mesures de sécurité + +## 7. Calculs et Rendements + +### 7.1 Paramètres par Défaut +**Manquant** : +- Valeurs par défaut pour tous les paramètres +- Facteurs d'efficacité par défaut +- Ratios par défaut (CO₂/CH₄, etc.) +- Paramètres de conversion par défaut + +**Recommandation** : Créer un fichier de constantes avec toutes les valeurs par défaut + +### 7.2 Calculs Temporels +**Manquant** : +- Comment calculer les rendements sur différentes périodes (jour, semaine, mois, année) +- Comment agréger les données sur 10 ans pour le business plan +- Gestion des années bissextiles +- Calculs cumulatifs + +**Recommandation** : Spécifier les calculs temporels + +### 7.3 Calculs Multi-Modules +**Manquant** : +- Comment agréger les calculs de plusieurs modules +- Comment gérer les modules avec des configurations différentes +- Calculs par site de traitement (plusieurs modules) + +**Recommandation** : Définir les règles d'agrégation + +## 8. Business Plan + +### 8.1 Calculs Financiers Détaillés +**Manquant** : +- Comment calculer les ajustements non-cash pour le cash flow +- Comment calculer les changements de fonds de roulement +- Calculs de dépréciation/amortissement +- Calculs d'impôts (si applicable) +- Calculs de remboursement de dette (si applicable) + +**Recommandation** : Compléter les formules financières + +### 8.2 Projections sur 10 Ans +**Manquant** : +- Comment projeter les revenus sur 10 ans (croissance ?) +- Comment projeter les coûts sur 10 ans (inflation ?) +- Facteurs de croissance/diminution +- Scénarios (optimiste, réaliste, pessimiste ?) + +**Recommandation** : Définir les règles de projection + +## 9. Configuration et Paramètres + +### 9.1 Paramètres Configurables +**Manquant** : +- Liste complète des paramètres configurables +- Paramètres globaux vs paramètres par projet +- Paramètres par site +- Hiérarchie des paramètres (global → site → projet) + +**Recommandation** : Créer une liste exhaustive des paramètres + +### 9.2 Constantes +**Manquant** : +- Toutes les constantes physiques (énergie du méthane, etc.) +- Constantes de conversion +- Limites et contraintes (min/max) +- Unités de mesure standardisées + +**Recommandation** : Créer un fichier de constantes complet + +## 10. Gestion des Erreurs + +### 10.1 Types d'Erreurs +**Manquant** : +- Erreurs de validation +- Erreurs de calcul (division par zéro, valeurs négatives) +- Erreurs de stockage (quota dépassé) +- Erreurs d'import/export +- Messages d'erreur utilisateur + +**Recommandation** : Documenter tous les types d'erreurs et leurs messages + +### 10.2 Gestion des Erreurs +**Manquant** : +- Comment afficher les erreurs +- Comment récupérer d'une erreur +- Logging des erreurs (console ?) +- Validation en temps réel vs à la soumission + +**Recommandation** : Définir la stratégie de gestion d'erreurs + +## 11. Tests + +### 11.1 Stratégie de Tests +**Manquant** : +- Framework de tests (Jest, Vitest ?) +- Tests unitaires (quelles fonctions tester) +- Tests d'intégration +- Tests E2E (si applicable) +- Couverture de code attendue + +**Recommandation** : Définir la stratégie de tests + +### 11.2 Données de Test +**Manquant** : +- Jeux de données de test +- Cas limites à tester +- Scénarios de test + +**Recommandation** : Créer des données de test + +## 12. Documentation Technique + +### 12.1 Documentation Développeur +**Manquant** : +- Guide de démarrage +- Architecture technique détaillée +- Guide de contribution +- Conventions de code +- Structure des dossiers + +**Recommandation** : Créer une documentation technique + +### 12.2 Documentation Utilisateur +**Manquant** : +- Guide utilisateur +- Tutoriels +- FAQ +- Aide contextuelle + +**Recommandation** : Prévoir une documentation utilisateur + +## 13. Déploiement et Distribution + +### 13.1 Build et Distribution +**Manquant** : +- Processus de build +- Comment distribuer l'application (fichiers statiques ?) +- Comment l'utilisateur installe/lance l'application +- Serveur local nécessaire ? + +**Recommandation** : Spécifier le processus de déploiement + +### 13.2 Configuration d'Environnement +**Manquant** : +- Variables d'environnement +- Configuration de développement vs production +- Fichiers de configuration + +**Recommandation** : Définir la configuration d'environnement + +## 14. Accessibilité et Internationalisation + +### 14.1 Accessibilité +**Manquant** : +- Niveau d'accessibilité requis (WCAG AA ?) +- Tests d'accessibilité +- Support des lecteurs d'écran + +**Recommandation** : Spécifier les exigences d'accessibilité + +### 14.2 Internationalisation +**Manquant** : +- Langues supportées (français uniquement ?) +- Format des dates/nombres +- Format des devises + +**Recommandation** : Définir les besoins d'internationalisation + +## 15. Performance + +### 15.1 Contraintes de Performance +**Manquant** : +- Temps de chargement acceptable +- Temps de calcul acceptable +- Taille maximale des données +- Nombre maximum de projets/modules + +**Recommandation** : Définir les objectifs de performance (même sans optimisation) + +## Priorités Recommandées + +### Priorité Haute (Blocant pour le développement) +1. Stack technique complet +2. Schémas de données JSON +3. Relations entre entités +4. Calculs manquants +5. Paramètres par défaut et constantes +6. Structure de projet + +### Priorité Moyenne (Important pour la qualité) +1. Gestion d'état +2. Routing +3. Workflow utilisateur +4. Validation métier +5. Export/Import format +6. Gestion des erreurs + +### Priorité Basse (Amélioration continue) +1. Tests +2. Documentation +3. Accessibilité +4. Internationalisation diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d623a59 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1729 @@ +{ + "name": "4nk-waste-simulator", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "4nk-waste-simulator", + "version": "1.0.0", + "dependencies": { + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-router-dom": "^6.26.0" + }, + "devDependencies": { + "@types/react": "^18.3.5", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.3.1", + "typescript": "^5.5.4", + "vite": "^5.4.2" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@remix-run/router": { + "version": "1.23.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.1.tgz", + "integrity": "sha512-vDbaOzF7yT2Qs4vO6XV1MHcJv+3dgR1sT+l3B8xxOVhUC336prMvqrvsLL/9Dnw2xr6Qhz4J0dmS0llNAbnUmQ==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz", + "integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz", + "integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz", + "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz", + "integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz", + "integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz", + "integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz", + "integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz", + "integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz", + "integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz", + "integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz", + "integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz", + "integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz", + "integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz", + "integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz", + "integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz", + "integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz", + "integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz", + "integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz", + "integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz", + "integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz", + "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz", + "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.27", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz", + "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.5", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.5.tgz", + "integrity": "sha512-D5vIoztZOq1XM54LUdttJVc96ggEsIfju2JBvht06pSzpckp3C7HReun67Bghzrtdsq9XdMGbSSB3v3GhMNmAA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001760", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz", + "integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "dev": true, + "license": "ISC" + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "6.30.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.2.tgz", + "integrity": "sha512-H2Bm38Zu1bm8KUE5NVWRMzuIyAV8p/JrOaBJAwVmp37AXG72+CZJlEBw6pdn9i5TBgLMhNDgijS4ZlblpHyWTA==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.30.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.2.tgz", + "integrity": "sha512-l2OwHn3UUnEVUqc6/1VMmR1cvZryZ3j3NzapC2eUXO1dB0sYp5mvwdjiXhpUbRb21eFow3qSxpP8Yv6oAU824Q==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.1", + "react-router": "6.30.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/rollup": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz", + "integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.53.3", + "@rollup/rollup-android-arm64": "4.53.3", + "@rollup/rollup-darwin-arm64": "4.53.3", + "@rollup/rollup-darwin-x64": "4.53.3", + "@rollup/rollup-freebsd-arm64": "4.53.3", + "@rollup/rollup-freebsd-x64": "4.53.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", + "@rollup/rollup-linux-arm-musleabihf": "4.53.3", + "@rollup/rollup-linux-arm64-gnu": "4.53.3", + "@rollup/rollup-linux-arm64-musl": "4.53.3", + "@rollup/rollup-linux-loong64-gnu": "4.53.3", + "@rollup/rollup-linux-ppc64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-musl": "4.53.3", + "@rollup/rollup-linux-s390x-gnu": "4.53.3", + "@rollup/rollup-linux-x64-gnu": "4.53.3", + "@rollup/rollup-linux-x64-musl": "4.53.3", + "@rollup/rollup-openharmony-arm64": "4.53.3", + "@rollup/rollup-win32-arm64-msvc": "4.53.3", + "@rollup/rollup-win32-ia32-msvc": "4.53.3", + "@rollup/rollup-win32-x64-gnu": "4.53.3", + "@rollup/rollup-win32-x64-msvc": "4.53.3", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz", + "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..047a16f --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "4nk-waste-simulator", + "version": "1.0.0", + "description": "4NK Waste & Water - Modular Waste Treatment Infrastructure Simulator", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "preview": "vite preview" + }, + "dependencies": { + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-router-dom": "^6.26.0" + }, + "devDependencies": { + "@types/react": "^18.3.5", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.3.1", + "typescript": "^5.5.4", + "vite": "^5.4.2" + } +} diff --git a/specification.md b/specification.md new file mode 100644 index 0000000..b38e13d --- /dev/null +++ b/specification.md @@ -0,0 +1,1789 @@ +# 4NK Waste & Water - Simulator Specification + +## 1. Overview + +4NK Waste & Water is developing a simulator for its modular waste treatment infrastructure. The system processes 67T of waste at 75% water content per module, with a total capacity of 21 modules processing 67T of waste at 75% water content per day. + +**Platform**: Desktop-only application (no mobile version or responsive design) + +## 2. Infrastructure Architecture + +### 2.1 Module Configuration + +- **Module capacity**: 67T of waste at 75% water content +- **Total modules**: 21 modules +- **Daily processing capacity**: 67T × 21 = 1,407T of waste at 75% water content per day + +### 2.2 Container Configuration (4 × 40-foot containers per module) + +#### Container 1: Mesophilic Anaerobic Digestion + +- **Function**: Anaerobic digestion of waste mixture at ambient temperature +- **Processes**: + - Phase separation + - Hygienization: 18 days + - **Note**: STEP sludge cannot be mixed + - **Total duration**: 21 days + +#### Container 2: Drying and Bioremediation + +- **Function**: Drying and bioremediation +- **Processes**: + - Drying: 21 days + - Bioremediation: 3 phases depending on waste type × 21 days each + - **Total duration**: Variable (21 days + 3 phases × 21 days) + +#### Container 3: Thermophilic Anaerobic Digestion + Composting + +- **Function**: Thermophilic anaerobic digestion and composting with waste mixture +- **Processes**: + - Thermophilic digestion: 18 days + - Composting: 3 days + - **Note**: Possible mixing of STEP digestate + - **Total duration**: 21 days + +#### Container 4: Water Storage and Spirulina Culture + +- **Function**: Water storage and spirulina culture +- **Processes**: + - Spirulina culture: 72-hour cycle → return to thermophilic anaerobic digestion + - Water wall for cooling (evaporation) + - Inter-container water cycles only + +### 2.3 Energy Production + +#### Heat Sources + +- **Biogas generator**: Produces energy to power Bitcoin mining machines +- **Electric generator**: Additional electrical power generation + +#### Solar Panels + +- **Location**: Surface of containers +- **Function**: Additional electrical power input + +## 2.4 Application Architecture + +### 2.4.1 Technical Stack + +- **Framework**: React (latest version) +- **Language**: TypeScript +- **Routing**: React Router +- **State Management**: None (use React useState, useContext for local state only) +- **Build Tool**: None (development server only, no build process) +- **Package Manager**: npm, yarn, or pnpm +- **Node.js**: Latest LTS version + +### 2.4.2 Project Structure + +``` +/src + /components + /base # Base reusable components + /composite # Composite components + /layout # Layout components (Header, Sidebar) + /shared # Shared business logic components + /pages # Page components + /hooks # Custom React hooks + /utils + /calculations # Calculation functions + /formatters # Data formatting + /validators # Validation functions + /constants # Constants and default values + /types # TypeScript type definitions + /data # Seed data (optional) +``` + +### 2.4.3 Authentication + +- **Login system**: Simple authentication system +- **Access restriction**: Localhost only (127.0.0.1 / localhost) +- **No remote access**: Application must only be accessible from localhost +- **Authentication method**: Simple username/password or basic authentication +- **Session management**: Local session management (localStorage) +- **Storage**: Credentials stored in localStorage (plain or hashed for localhost) + +### 2.4.4 Data Storage + +- **Storage location**: Frontend only (client-side) +- **Persistence mechanism**: Browser-based persistence (localStorage primary, IndexedDB optional) +- **No backend database**: All data stored locally in the browser +- **Data format**: JSON format for data storage +- **Storage key**: `4nkwaste_simulator_data` (localStorage) +- **Export/Import**: + - Export: Complete storage structure as JSON (replaces all data) + - Import: Replace entire storage with imported JSON + - Validation: Check structure, references, constraints before import +- **Data isolation**: Data stored per browser (desktop only) +- **Versioning**: Data structure includes version number for migration + +### 2.4.5 Routing + +- **Library**: React Router (latest version) +- **Route structure**: Defined in navigation section +- **Protected routes**: Authentication check before accessing pages +- **404 handling**: Default route to dashboard or 404 page +- **Deep linking**: All pages have unique URLs, bookmarkable + +## 3. Navigation Structure + +### 3.0 Navigation Architecture + +#### 3.0.1 Main Navigation Structure + +**Sidebar Navigation (Left Side - Fixed, Collapsible)**: + +- Width: 256px (collapsed: 64px) +- Background: Background Secondary (#2D2D2D) +- Border right: 1px solid Border (#404040) +- Position: Fixed left +- Z-index: High (above content) + +**Top Navigation (Header)**: + +- Height: 64px +- Background: Background Secondary (#2D2D2D) +- Border bottom: 1px solid Border (#404040) +- Position: Fixed top +- Contains: Logo, project selector, user info, logout + +#### 3.0.2 Navigation Menu Items + +**Main Sections** (Top Level): + +1. **Dashboard** (Home icon) + - Route: `/` + - Purpose: Overview and quick access to key metrics + +2. **Configuration** (Settings icon) + - Route: `/configuration` + - Submenu items: + - Waste Configuration (`/configuration/waste`) + - Natural Regulators (`/configuration/regulators`) + - Services (`/configuration/services`) + +3. **Projects** (Folder icon) + - Route: `/projects` + - Submenu items: + - Project List (`/projects`) + - Treatment Sites (`/projects/treatment-sites`) + - Waste Sites (`/projects/waste-sites`) + - Investors (`/projects/investors`) + - Administrative Procedures (`/projects/procedures`) + +4. **Yields** (Chart icon) + - Route: `/yields` + - Purpose: Display processing yields and calculations + +5. **Business Plan** (Calculator icon) + - Route: `/business-plan` + - Purpose: Financial analysis and projections + +**Secondary Items** (Bottom of sidebar): + +- **Settings** (Gear icon) + - Route: `/settings` + - Purpose: Application settings, data export/import + +- **Help** (Question mark icon) + - Route: `/help` + - Purpose: Documentation, formulas reference + +#### 3.0.3 Navigation Behavior + +**Active State**: + +- Active item: Primary Green background (#2D7A4F), white text +- Active indicator: Left border 3px solid Primary Green + +**Hover State**: + +- Background: Background Tertiary (#404040) +- Transition: 200ms ease-in-out + +**Collapsed Sidebar**: + +- Width: 64px +- Icons only (no text labels) +- Tooltips on hover showing full menu item name +- Expand on click or hover + +**Breadcrumbs** (Top of main content): + +- Show current location: Home > Section > Page +- Clickable navigation path +- Font: Body Small, Text Secondary +- Separator: ">" icon + +#### 3.0.4 Navigation Icons + +**Icon Mapping**: + +- Dashboard: Home/House icon +- Configuration: Settings/Gear icon +- Waste Configuration: Trash/Recycle icon +- Natural Regulators: Leaf/Nature icon +- Services: Briefcase/Services icon +- Projects: Folder/Project icon +- Treatment Sites: Factory/Plant icon +- Waste Sites: Truck/Collection icon +- Investors: Users/People icon +- Administrative Procedures: Document/File icon +- Yields: Chart/Bar chart icon +- Business Plan: Calculator/Money icon +- Settings: Gear/Settings icon +- Help: Question mark/Info icon + +**Icon Size**: 20px (Medium) +**Icon Style**: Outline (default), Solid (active state) + +#### 3.0.5 Navigation Structure Details + +**Hierarchical Organization**: + +``` +├── Dashboard (/) +├── Configuration (/configuration) +│ ├── Waste Configuration (/configuration/waste) +│ ├── Natural Regulators (/configuration/regulators) +│ └── Services (/configuration/services) +├── Projects (/projects) +│ ├── Project List (/projects) +│ ├── Treatment Sites (/projects/treatment-sites) +│ ├── Waste Sites (/projects/waste-sites) +│ ├── Investors (/projects/investors) +│ └── Administrative Procedures (/projects/procedures) +├── Yields (/yields) +├── Business Plan (/business-plan) +├── Settings (/settings) +└── Help (/help) +``` + +**Navigation Flow**: + +1. User logs in → Dashboard +2. Configure data → Configuration section +3. Create/manage projects → Projects section +4. View results → Yields page +5. Analyze finances → Business Plan page + +**Quick Access**: + +- Project selector in header (dropdown) +- Recent projects in dashboard +- Direct links from project list to business plan + +## 3. Application Pages + +### 3.0 Dashboard Page + +**Purpose**: Overview and quick access to key metrics and recent projects + +**Content**: + +- **Key Metrics Summary**: + - Total active projects + - Total modules in operation + - Total waste processed (today/week/month) + - Total revenue (current year) + - Total bitcoins generated (current year) + +- **Recent Projects**: + - List of recently accessed projects + - Quick links to project business plans + - Project status indicators + +- **Quick Actions**: + - Create new project + - Access yields page + - Access business plan + - Export data + +- **Recent Activity**: + - Last configuration changes + - Last calculations performed + - Last exports + +### 3.1 Waste Configuration Page + +**Purpose**: Configure waste characteristics + +**Parameters**: + +- Origin units of waste (animals/types, invested range, markets/types, restaurants/types...) +- Number of origin units to produce 1000m³ of methane +- BMP (Nm³ CH₄/kg VS) +- Water percentage (%) +- Regulation needs +- Regulatory characteristics +- Maximum storage duration in tank without altering anaerobic digestion + +### 3.2 Natural Regulators Configuration Page + +**Purpose**: Configure natural regulators (non-waste) characteristics + +**Parameters**: + +- Regulator type +- Regulatory characteristics +- Application conditions +- Dosage requirements + +### 3.3 Services Configuration Page + +**Purpose**: Configure services with pricing + +**Services** (pricing per module per year over 10 years, first year prototype): + +1. Raw rental +2. Biological waste treatment +3. Bitcoin management +4. Provision of standardized fertilizers from compost +5. Provision of waste heat +6. Provision of carbon credit indices +7. Brownfield redevelopment +8. Transport + +### 3.4 Yields Page + +**Purpose**: Display processing yields + +**Outputs**: + +- Water (t) +- Fertilizer (t) +- Methane (m³/day) +- CO₂ (m³/day) +- Energy (heat) (kJ/day) +- Energy (heat) (kW.h/day) +- Electrical power (kW) - anaerobic digestion +- Electrical power (kW) - solar panels +- Total electrical power (kW) +- Electrical power (kW) consumed by modules +- Number of 4NK flex miners (2kW) +- Bitcoins BTC/year – Parameter: Number of 4NK Miners (79.2 × 0.0001525 / flex miner) + +**Calculation Rules Display**: + +- Always display calculation formulas and rules applied for each output +- Show formulas next to or below each calculated value +- Display input parameters used in calculations +- Show calculation steps when applicable +- Use monospace font for formulas and technical expressions + +### 3.5 Business Plan Page + +**Purpose**: Business plan per project with detailed financial analysis + +#### 3.5.1 Project Header + +**Project Identification**: + +- **Start date - End date**: Project duration +- **Treatment site(s)**: Associated treatment site(s) +- **Collection site(s)**: Associated waste collection site(s) +- **Number of modules**: Number of modules in the project + +#### 3.5.2 Economic Characteristics (per year) + +**Annual economic data displayed for each year of the project (10 years)** + +##### REVENUES + +- **Raw rental**: Container rental revenue +- **Biological waste treatment service**: Waste processing service revenue +- **Bitcoin management service**: Cryptocurrency mining service revenue +- **Provision of standardized fertilizers service**: Fertilizer supply service revenue +- **Provision of waste heat service**: Heat recovery service revenue +- **Provision of carbon credit indices service**: Carbon credit service revenue +- **Brownfield redevelopment service**: Site redevelopment service revenue +- **Transport service**: Transportation service revenue +- **Commercial partnerships**: Revenue from commercial partnerships +- **Other revenues**: Additional revenue sources +- **TOTAL REVENUES**: Sum of all revenue items + +##### VARIABLE COSTS + +- **Rental & services**: Rental and service costs +- **Commissions / intermediaries / import**: Commission and intermediary costs +- **Other variable costs**: Additional variable costs +- **Transport**: Transportation costs +- **TOTAL VARIABLE COSTS**: Sum of all variable cost items + +##### GROSS MARGIN + +- **Calculation**: TOTAL REVENUES - TOTAL VARIABLE COSTS + +##### FIXED COSTS (OPEX) + +- **Salaries and social charges**: Personnel costs +- **Marketing / communication expenses**: Marketing and communication costs +- **R&D / product development**: Research and development costs +- **Administrative and legal fees**: Administrative and legal expenses +- **Other general expenses**: Additional general expenses +- **TOTAL FIXED COSTS**: Sum of all fixed cost items + +##### OPERATING RESULT (EBITDA) + +- **Calculation**: GROSS MARGIN - TOTAL FIXED COSTS + +##### CASH FLOW + +- **Calculation**: OPERATING RESULT - adjustments for cash flow + +##### INVESTMENTS (CAPEX) + +- **Equipment / machinery**: Equipment and machinery investments +- **Technology development**: Technology development investments +- **Patents / IP**: Intellectual property investments +- **TOTAL INVESTMENTS**: Sum of all investment items + +##### FUNDING NEED + +- **Calculation**: Based on investments and cash flow requirements + +##### USE OF RAISED FUNDS + +- **Product development (POC / MVP)**: Funds for product development +- **Marketing / customer acquisition**: Funds for marketing and acquisition +- **Team strengthening / recruitment**: Funds for team expansion +- **Structure / administrative fees**: Funds for administrative structure +- **TOTAL USE OF FUNDS**: Sum of all fund utilization items + +##### KEY INDICATORS (KPIs) + +- **Active users / clients**: Number of active users or clients +- **Customer Acquisition Cost (CAC)**: Cost to acquire one customer +- **Lifetime Value (LTV)**: Customer lifetime value +- **Break-even point (days)**: Number of days to reach break-even + +#### 3.5.3 Pricing Characteristics (per year) + +**Annual pricing parameters and valorization calculations** + +##### Valorization Parameters + +- **Waste treatment valorization / year**: + - Parameter: €/t = 100 € + - Formula: `Waste_treatment_valorization = Waste_quantity (t) × 100 €/t` + +- **Fertilizer valorization / year**: + - Parameter: €/t = 215 € + - Formula: `Fertilizer_valorization = Fertilizer_quantity (t) × 215 €/t` + +- **Heat valorization / year**: + - Parameter: €/t = 0.12 € + - Formula: `Heat_valorization = Heat_quantity (t) × 0.12 €/t` + +- **Carbon equivalent valorization - burned methane (CH₄)**: + - Parameter: 630 €/tC ≈ 172 €/tCO₂e + - Formula: `CH4_carbon_valorization = CH4_quantity (tCO₂e) × 172 €/tCO₂e` + +- **Carbon equivalent valorization - sequestered CO₂ (CO₂)**: + - Parameter: 100 €/tC ≈ 27 €/tCO₂e + - Formula: `CO2_carbon_valorization = CO2_sequestered (tCO₂e) × 27 €/tCO₂e` + +- **Carbon equivalent valorization - avoided electricity consumption**: + - Parameter: 0.12 €/kW + - Formula: `Energy_carbon_valorization = Electricity_avoided (kW) × 0.12 €/kW` + +- **Bitcoin value**: + - Parameter: 100,000 € + - Formula: `Bitcoin_value = Bitcoin_quantity (BTC) × 100,000 €/BTC` + +- **Land valorization (brownfield)**: + - Parameter: 4000 m² brownfield + - Formula: `Land_valorization = Brownfield_area (m²) × valorization_rate` + +**Calculation Rules Display**: + +- Always display calculation formulas and rules applied for financial metrics +- Show formulas for revenue, cost, and ROI calculations +- Display pricing calculation rules (per module, per year, 10-year model) +- Show service pricing formulas +- Display valorization formulas with parameters +- Use monospace font for formulas and technical expressions +- Show parameter values used in calculations + +### 3.6 Project List Page + +**Purpose**: List and manage all projects + +**Content**: + +- **Project Table**: + - Project name + - Treatment site + - Collection site + - Number of modules + - Start date - End date + - Status (To be approached / LOI OK / In progress / Completed) + - Actions (Edit, View Business Plan, Delete) + +- **Filters**: + - Filter by status + - Filter by treatment site + - Filter by date range + - Search by project name + +- **Actions**: + - Create new project + - Edit project + - View business plan + - Delete project + - Export project data + +### 3.6.1 Project Configuration Page + +**Purpose**: Configure project parameters and associated entities + +**Project Parameters**: + +- **Treatment site**: + - Site identification + - Status: To be approached / LOI OK / In progress / Completed +- **Modules per year**: Number of modules planned per year +- **Waste sites**: + - Waste site type + - Status: To be approached / LOI OK / In progress / Completed +- **Transport by site**: Yes/No +- **Waste characteristics override**: Configuration of waste characteristics overriding standard characteristics +- **Administrative procedures** (ICPE, spreading, etc.): + - Procedure type + - Status: To do / Done / N/A +- **Investment**: + - Investor identification + - Status: To be approached / LOI OK / In progress / Completed + - Amount + +### 3.7 Treatment Site Configuration Page + +**Purpose**: Configure treatment site characteristics + +**Parameters**: + +- **Average temperatures by month**: Monthly temperature data (12 months) +- **Altitude**: Site altitude +- **Available ground surface**: Available surface area for installation +- **Subscribed services**: List of services subscribed for this site + +### 3.8 Administrative Procedures Configuration Page + +**Purpose**: Configure administrative procedures templates + +**Parameters**: + +- **Procedure type**: Type of administrative procedure (ICPE, spreading, etc.) +- **Delays**: Processing delays/duration +- **Contact / Regions**: Contact information and applicable regions + +### 3.9 Investor Configuration Page + +**Purpose**: Configure investor profiles and criteria + +**Parameters**: + +- **Investor type**: Classification of investor type +- **Amount range**: Minimum and maximum investment amounts +- **Geographic regions**: Applicable geographic regions +- **Waste range**: Minimum and maximum waste quantities / waste types +- **Solar panels range**: Minimum and maximum solar panel capacity + +### 3.10 Waste Site Configuration Page + +**Purpose**: Configure waste source sites + +**Parameters**: + +- **Waste type**: Type of waste produced +- **Quantity range**: Minimum and maximum quantities / days +- **Contact**: Contact information +- **Waste collection type**: Type of waste collection method +- **Distance**: Distance from treatment site + +## 4. Waste Treatment Configuration + +### 4.1 Treatment Composition + +Each waste treatment has: + +- **Primary waste**: Main waste type +- **Regulatory wastes**: Based on: + - Client objectives + - Bioremediation treatment needs based on quality requirements +- **Additional natural regulators**: Based on: + - Client objectives + - Bioremediation treatment needs based on quality requirements + +### 4.2 Client Needs + +#### Nutrient Requirements + +- **Total Nitrogen (N or NTK)** +- **Ammoniacal Nitrogen (N-NH₄)**: Indicator of rapid effect +- **Total Phosphorus (P)** +- **Total Potassium (K)** + +### 4.3 Quality Requirements Before Anaerobic Digestion + +#### Heavy Metals and Toxic Elements + +- Arsenic (As) elimination +- Other elements elimination: zinc, aluminum, copper +- Heavy metals elimination + +#### Biological Contaminants + +- Pathogen elimination + +#### Chemical Parameters + +- Low C:N ratio enrichment +- Medication elimination +- Deposit elimination +- Odor elimination +- Turbidity reduction +- Sodium (Na⁺) reduction +- Chlorine (Cl⁻) reduction +- Electrical conductivity reduction +- Sulfide elimination +- Methane elimination +- CO₂ elimination +- Polyphenol elimination +- Elimination of refractory structural fractions (lignin, alginates, fucoidans, crystalline cellulose, and insoluble fibers) + +#### Biological Processes + +- Microbiological competition +- Oil emulsification + +#### pH Regulation + +- Acidity reduction +- pH increase +- pH reduction + +## 5. Waste Characteristics + +### 5.1 Origin Classification + +- **Animals/Types**: Classification by animal type +- **Invested Range**: Investment range classification +- **Markets/Types**: Market type classification +- **Restaurants/Types**: Restaurant type classification + +### 5.2 Technical Parameters + +- **Origin units per 1000m³ methane**: Number of origin units required +- **BMP (Nm³ CH₄/kg VS)**: Biochemical Methane Potential +- **Water percentage (%)**: Moisture content +- **Regulation needs**: Required regulatory adjustments +- **Regulatory characteristics**: Specific regulatory properties +- **Maximum storage duration**: Maximum time in tank without affecting anaerobic digestion + +## 6. Services and Pricing + +### 6.1 Service List + +1. **Raw Rental**: Container rental service +2. **Biological Waste Treatment**: Waste processing service +3. **Bitcoin Management**: Cryptocurrency mining management +4. **Provision of Standardized Fertilizers**: Compost-based fertilizer supply +5. **Provision of Waste Heat**: Heat recovery service +6. **Provision of Carbon Credit Indices**: Carbon credit index service +7. **Brownfield Redevelopment**: Site redevelopment service +8. **Transport**: Transportation service + +### 6.2 Pricing Model + +- **Unit**: Price per module per year +- **Duration**: 10 years +- **First year**: Prototype pricing +- **Configuration**: Configurable per service + +## 7. Yields and Performance Metrics + +### 7.1 Material Outputs + +- **Water (t)**: Processed water output +- **Fertilizer (t)**: Compost/fertilizer output + +### 7.2 Gas Outputs + +- **Methane (m³/day)**: Daily methane production +- **CO₂ (m³/day)**: Daily CO₂ production + +### 7.3 Energy Outputs + +- **Energy (heat) (kJ/day)**: Daily heat energy production +- **Energy (heat) (kW.h/day)**: Daily heat energy in kilowatt-hours + +### 7.4 Electrical Power + +- **Electrical power (kW) - Anaerobic digestion**: Power from biogas generator +- **Electrical power (kW) - Solar panels**: Power from solar panels +- **Total electrical power (kW)**: Combined electrical power +- **Electrical power (kW) consumed by modules**: Power consumption by processing modules + +### 7.5 Bitcoin Mining + +- **Number of 4NK flex miners**: Count of 2kW mining units +- **Bitcoins BTC/year**: Annual Bitcoin production + - **Calculation**: 79.2 × 0.0001525 / flex miner + - **Parameter**: Number of 4NK Miners + +## 8. Technical Specifications + +### 8.1 Processing Times + +- **Mesophilic digestion**: 18 days hygienization + 3 days = 21 days total +- **Drying**: 21 days +- **Bioremediation phases**: 3 phases × 21 days each (variable) +- **Thermophilic digestion**: 18 days +- **Composting**: 3 days +- **Spirulina cycle**: 72 hours + +### 8.2 Container Specifications + +- **Type**: 40-foot containers +- **Quantity per module**: 4 containers +- **Total containers**: 21 modules × 4 = 84 containers + +### 8.3 Mining Equipment + +- **4NK Flex Miner**: 2kW per unit +- **Power consumption**: Variable based on number of miners + +## 9. Data Model Requirements + +### 9.1 Waste Data Model + +- Waste type identification +- Origin classification +- Physical and chemical characteristics +- BMP values +- Water content +- Regulatory needs +- Storage constraints + +### 9.2 Regulator Data Model + +- Regulator type (waste or natural) +- Regulatory characteristics +- Application conditions +- Dosage specifications + +### 9.3 Service Data Model + +- Service type +- Pricing structure (10-year model) +- Module association +- Project association + +### 9.4 Yield Data Model + +- Material outputs +- Gas outputs +- Energy outputs +- Electrical power metrics +- Bitcoin production metrics + +### 9.5 Business Plan Data Model + +- **Project Header**: + - Start date - End date + - Treatment site(s) association + - Collection site(s) association + - Number of modules + +- **Economic Characteristics (per year, 10 years)**: + - Revenues (all service revenues, partnerships, other) + - Variable costs (rental, commissions, transport, other) + - Fixed costs (salaries, marketing, R&D, administrative, other) + - Investments (equipment, technology, patents/IP) + - Use of raised funds (development, marketing, team, structure) + - KPIs (active users/clients, CAC, LTV, break-even) + +- **Pricing Characteristics (per year)**: + - Valorization parameters (waste treatment, fertilizer, heat, carbon equivalents, bitcoin, land) + - Valorization calculations with formulas + - Parameter values + +- **Financial Calculations**: + - Gross margin + - Operating result (EBITDA) + - Cash flow + - Funding need + - Break-even point + - CAC and LTV + +### 9.6 Project Data Model + +- Project identification +- Treatment site association +- Modules per year configuration +- Waste sites association +- Transport configuration +- Waste characteristics overrides +- Administrative procedures tracking +- Investment tracking + +### 9.7 Treatment Site Data Model + +- Site identification +- Geographic data (altitude, coordinates) +- Monthly temperature data (12 values) +- Available ground surface +- Subscribed services list +- Status tracking + +### 9.8 Administrative Procedure Data Model + +- Procedure type +- Standard delays +- Contact information +- Applicable regions +- Status tracking per project + +### 9.9 Investor Data Model + +- Investor type +- Investment amount range (min/max) +- Geographic regions +- Waste quantity range (min/max) +- Waste type preferences +- Solar panel capacity range (min/max) +- Status tracking per project + +### 9.10 Waste Site Data Model + +- Site identification +- Waste type +- Quantity range (min/max per day) +- Contact information +- Collection type +- Distance from treatment site +- Status tracking + +### 9.11 Authentication Data Model + +- User credentials (username/password) +- Session information +- Login status +- Access timestamp + +### 9.12 Local Storage Data Model + +- Storage structure: JSON format +- Data versioning +- Timestamp for each data entry +- Data categories: + - Projects + - Configurations + - Yields + - Business plans + - Sites + - Investors + - Administrative procedures + +## 10. Calculation Requirements + +### 10.1 Methane Production + +- Based on BMP (Nm³ CH₄/kg VS) +- Waste input quantities +- Processing efficiency factors + +### 10.2 Energy Calculations + +- Biogas to electricity conversion +- Solar panel output +- Module consumption +- Net energy balance + +### 10.3 Bitcoin Production + +- Formula: 79.2 × 0.0001525 / flex miner +- Based on number of 4NK flex miners +- Annual production calculation + +### 10.4 Water Balance + +- Input water from waste (75% of 67T) +- Water consumption in processes +- Water output from spirulina cycle +- Inter-container water cycles + +### 10.5 Fertilizer Production + +- Based on composting output +- Quality parameters (N, P, K) +- Standardization requirements + +### 10.6 Valorization Calculations + +#### Waste Treatment Valorization + +- **Formula**: `Waste_treatment_valorization (€/year) = Waste_quantity (t/year) × 100 €/t` +- **Parameter**: 100 €/t + +#### Fertilizer Valorization + +- **Formula**: `Fertilizer_valorization (€/year) = Fertilizer_quantity (t/year) × 215 €/t` +- **Parameter**: 215 €/t + +#### Heat Valorization + +- **Formula**: `Heat_valorization (€/year) = Heat_quantity (t/year) × 0.12 €/t` +- **Parameter**: 0.12 €/t + +#### Carbon Equivalent - Burned Methane (CH₄) + +- **Formula**: `CH4_carbon_valorization (€/year) = CH4_quantity (tCO₂e/year) × 172 €/tCO₂e` +- **Parameter**: 630 €/tC ≈ 172 €/tCO₂e +- **Conversion**: 1 tC = 3.67 tCO₂e + +#### Carbon Equivalent - Sequestered CO₂ + +- **Formula**: `CO2_carbon_valorization (€/year) = CO2_sequestered (tCO₂e/year) × 27 €/tCO₂e` +- **Parameter**: 100 €/tC ≈ 27 €/tCO₂e +- **Conversion**: 1 tC = 3.67 tCO₂e + +#### Carbon Equivalent - Avoided Electricity Consumption + +- **Formula**: `Energy_carbon_valorization (€/year) = Electricity_avoided (kW/year) × 0.12 €/kW` +- **Parameter**: 0.12 €/kW + +#### Bitcoin Valorization + +- **Formula**: `Bitcoin_value (€) = Bitcoin_quantity (BTC) × 100,000 €/BTC` +- **Parameter**: 100,000 €/BTC + +#### Land Valorization (Brownfield) + +- **Formula**: `Land_valorization (€) = Brownfield_area (m²) × valorization_rate (€/m²)` +- **Parameter**: 4000 m² brownfield (configurable valorization rate) + +### 10.7 Financial Calculations + +#### Gross Margin + +- **Formula**: `Gross_Margin = Total_Revenues - Total_Variable_Costs` + +#### Operating Result (EBITDA) + +- **Formula**: `EBITDA = Gross_Margin - Total_Fixed_Costs` + +#### Cash Flow + +- **Formula**: `Cash_Flow = EBITDA - Non_cash_adjustments - Working_capital_changes` + +#### Funding Need + +- **Formula**: `Funding_Need = Total_Investments - Available_Cash - Cash_Flow` + +#### Break-even Point + +- **Formula**: `Break_even_days = Fixed_Costs / (Daily_Revenue - Daily_Variable_Costs)` + +#### Customer Acquisition Cost (CAC) + +- **Formula**: `CAC = Marketing_Costs / Number_of_New_Customers` + +#### Lifetime Value (LTV) + +- **Formula**: `LTV = Average_Revenue_per_Customer × Average_Customer_Lifespan` + +## 11. User Interface Requirements + +### 11.0 Calculation Rules Display (General Requirement) + +**Mandatory Display of Calculation Rules**: + +- **Always Visible**: Calculation formulas and rules must always be displayed on pages that show calculated results +- **Display Format**: + - Formulas displayed in monospace font (JetBrains Mono, Fira Code, or Courier New) + - Clear formatting with variable names and values + - Formulas can be displayed inline, in expandable sections, or in dedicated formula panels +- **Content Requirements**: + - Show the complete calculation formula + - Display input parameters used in the calculation + - Show intermediate calculation steps when applicable + - Indicate units of measurement + - Reference to calculation source/section when applicable +- **Placement**: + - Next to or below calculated values + - In expandable/collapsible sections for complex formulas + - In tooltips for simple formulas (with option to expand) + - In dedicated "Calculation Rules" panel or section +- **Examples**: + - Bitcoin calculation: `BTC/year = 79.2 × 0.0001525 / flex_miner` + - Methane production: `Methane (m³/day) = BMP × Waste_quantity × Efficiency_factor` + - Energy conversion: `Energy (kW.h/day) = Energy (kJ/day) / 3600` +- **Styling**: + - Background: Background Secondary + - Border: 1px solid Border + - Padding: 12px 16px + - Border radius: 8px + - Font: Monospace, Body Small size + - Text color: Text Primary + +### 11.1 Configuration Pages + +- Intuitive form-based interfaces +- Dropdown selections for waste types +- Parameter input fields with validation +- Real-time calculation previews +- **Calculation Rules Visibility**: + - Display calculation formulas when parameters affect calculations + - Show how input parameters influence results + - Display validation rules and constraints + - Use monospace font for formulas and technical expressions + +### 11.2 Yields Display + +- Dashboard-style visualization +- Real-time metrics +- Historical data tracking +- Export capabilities +- **Calculation Rules Visibility**: + - Always display calculation formulas alongside calculated values + - Show formulas in expandable sections or tooltips + - Display input parameters used in each calculation + - Use monospace font for formulas + - Format: Formula displayed clearly with variable names and values + +### 11.3 Business Plan Interface + +- **Project Header Section**: + - Date range selector (start date - end date) + - Treatment site(s) selection + - Collection site(s) selection + - Number of modules input + +- **Economic Characteristics Section (per year, 10-year view)**: + - Revenues table/inputs (all service revenues, partnerships, other) + - Variable costs table/inputs (rental, commissions, transport, other) + - Fixed costs table/inputs (salaries, marketing, R&D, administrative, other) + - Investments table/inputs (equipment, technology, patents/IP) + - Use of raised funds table/inputs (development, marketing, team, structure) + - KPIs display/inputs (active users/clients, CAC, LTV, break-even) + - Automatic calculations (gross margin, EBITDA, cash flow, funding need) + +- **Pricing Characteristics Section (per year)**: + - Valorization parameter configuration + - Valorization calculation display with formulas + - Parameter value inputs (€/t, €/tCO₂e, €/kW, €/BTC, etc.) + - Real-time valorization calculations + +- **Financial Projections Display**: + - 10-year financial table/graph + - Year-by-year breakdown + - Cumulative calculations + - Report generation and export + +- **Calculation Rules Visibility**: + - Always display financial calculation formulas + - Show pricing calculation rules (per module, per year, 10-year model) + - Display ROI calculation formulas + - Show revenue and cost calculation methods + - Display all valorization formulas with parameters + - Use monospace font for formulas + - Format: Formulas displayed clearly with explanations + +### 11.4 Project Management Interface + +- Project creation and editing +- Treatment site configuration +- Waste site management +- Investor management +- Administrative procedures tracking +- Status workflow management +- Multi-project dashboard + +### 11.5 Authentication Interface + +- Simple login page +- Username/password input +- Session status display +- Logout functionality +- Localhost access indicator + +## 11.6 UI/UX Design System + +### 11.6.1 Color Palette + +**Note**: All colors defined below are for dark mode only. The application does not support theme switching. + +#### Primary Colors + +- **Primary Green**: #2D7A4F (Main brand color - waste treatment, sustainability) +- **Primary Green Light**: #4A9D6E (Hover states, highlights) +- **Primary Green Dark**: #1F5A3A (Active states, emphasis) +- **Primary Green Accent**: #6BC48A (Success states, positive actions) + +#### Secondary Colors + +- **Secondary Blue**: #2563EB (Information, data visualization) +- **Secondary Blue Light**: #3B82F6 (Hover states) +- **Secondary Blue Dark**: #1E40AF (Active states) + +#### Neutral Colors (Dark Mode Only) + +- **Background**: #1A1A1A (Main background) +- **Background Secondary**: #2D2D2D (Secondary surfaces, cards) +- **Background Tertiary**: #404040 (Borders, dividers) +- **Text Primary**: #FFFFFF (Main text, headings) +- **Text Secondary**: #B0B0B0 (Secondary text, labels) +- **Text Tertiary**: #808080 (Placeholder text, disabled) +- **Border**: #404040 (Default borders) +- **Border Focus**: #4A9D6E (Focus states - Primary Green Light) + +#### Status Colors + +- **Success**: #10B981 (Positive actions, success messages) +- **Warning**: #F59E0B (Warnings, caution) +- **Error**: #EF4444 (Errors, destructive actions) +- **Info**: #3B82F6 (Informational messages) +- **Pending**: #F59E0B (In progress states) +- **Completed**: #10B981 (Completed states) +- **To Do**: #6C757D (Pending states) + +#### Status Workflow Colors + +- **To be approached**: #F59E0B (Orange - initial state) +- **LOI OK**: #3B82F6 (Blue - letter of intent approved) +- **In progress**: #8B5CF6 (Purple - active work) +- **Completed**: #10B981 (Green - finished) +- **N/A**: #9CA3AF (Gray - not applicable) + +### 11.6.2 Typography + +#### Font Family + +- **Primary Font**: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif +- **Monospace Font**: 'JetBrains Mono', 'Fira Code', 'Courier New', monospace (for technical data, calculations) + +#### Font Sizes + +- **H1**: 2.5rem (40px) - Page titles +- **H2**: 2rem (32px) - Section titles +- **H3**: 1.5rem (24px) - Subsection titles +- **H4**: 1.25rem (20px) - Card titles +- **Body Large**: 1.125rem (18px) - Important body text +- **Body**: 1rem (16px) - Default body text +- **Body Small**: 0.875rem (14px) - Secondary text, labels +- **Caption**: 0.75rem (12px) - Captions, metadata + +#### Font Weights + +- **Bold**: 700 - Headings, emphasis +- **Semi-bold**: 600 - Subheadings, important labels +- **Medium**: 500 - Buttons, interactive elements +- **Regular**: 400 - Body text +- **Light**: 300 - Decorative text + +#### Line Heights + +- **Tight**: 1.2 - Headings +- **Normal**: 1.5 - Body text +- **Relaxed**: 1.75 - Long-form content + +### 11.6.3 Spacing System + +#### Base Unit + +- **Base**: 4px (all spacing multiples of 4) + +#### Spacing Scale + +- **xs**: 4px (0.25rem) +- **sm**: 8px (0.5rem) +- **md**: 16px (1rem) +- **lg**: 24px (1.5rem) +- **xl**: 32px (2rem) +- **2xl**: 48px (3rem) +- **3xl**: 64px (4rem) +- **4xl**: 96px (6rem) + +#### Component Spacing + +- **Form fields**: 16px vertical spacing +- **Card padding**: 24px +- **Section spacing**: 48px +- **Page padding**: 32px + +### 11.6.4 Border Radius + +- **None**: 0px - Sharp corners +- **sm**: 4px - Small elements (badges, tags) +- **md**: 8px - Default (buttons, inputs, cards) +- **lg**: 12px - Large cards, modals +- **xl**: 16px - Hero sections +- **Full**: 9999px - Pills, avatars + +### 11.6.5 Shadows (Dark Mode) + +- **sm**: 0 1px 2px 0 rgba(0, 0, 0, 0.3) - Subtle elevation +- **md**: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.3) - Cards +- **lg**: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -2px rgba(0, 0, 0, 0.4) - Modals, dropdowns +- **xl**: 0 20px 25px -5px rgba(0, 0, 0, 0.6), 0 10px 10px -5px rgba(0, 0, 0, 0.5) - Large modals +- **Note**: Shadows are more pronounced in dark mode for better depth perception + +### 11.6.6 Components + +#### Buttons + +- **Primary Button**: + - Background: Primary Green (#2D7A4F) + - Text: #FFFFFF (White) + - Padding: 12px 24px + - Border radius: 8px + - Font weight: 500 + - Hover: Primary Green Light (#4A9D6E) + - Active: Primary Green Dark (#1F5A3A) + - Disabled: Background Secondary, Text Tertiary, cursor: not-allowed + +- **Secondary Button**: + - Background: Transparent + - Border: 1px solid Border + - Text: Text Primary + - Padding: 12px 24px + - Border radius: 8px + - Hover: Background Secondary + +- **Danger Button**: + - Background: Error (#EF4444) + - Text: #FFFFFF (White) + - Hover: Darker red shade + +- **Icon Button**: + - Square: 40px × 40px + - Circular border radius + - Icon centered + +#### Input Fields + +- **Text Input**: + - Height: 44px + - Background: Background Secondary + - Padding: 12px 16px + - Border: 1px solid Border + - Border radius: 8px + - Text color: Text Primary + - Focus: 2px solid Border Focus + - Error: Border Error color + - Placeholder: Text Tertiary + +- **Select/Dropdown**: + - Same as text input + - Background: Background Secondary + - Dropdown options: Background Secondary + - Dropdown arrow indicator + - Max height: 300px for options list + +- **Textarea**: + - Min height: 100px + - Background: Background Secondary + - Text color: Text Primary + - Resizable: vertical only + - Same border and focus styles as input + +- **Checkbox/Radio**: + - Size: 20px × 20px + - Border: 2px solid Border + - Checked: Primary Green background + - Focus: Ring with Border Focus color + +#### Cards + +- **Card Container**: + - Background: Background Secondary + - Padding: 24px + - Border radius: 12px + - Shadow: md + - Border: 1px solid Border (optional) + +- **Card Header**: + - Padding bottom: 16px + - Border bottom: 1px solid Border (optional) + - Font size: H4 + - Font weight: 600 + +#### Status Badges + +- **Badge**: + - Padding: 4px 12px + - Border radius: Full + - Font size: Body Small + - Font weight: 500 + - Colors based on status (see Status Colors) + +#### Tables + +- **Table Container**: + - Border: 1px solid Border + - Border radius: 8px + - Overflow: hidden + +- **Table Header**: + - Background: Background Secondary + - Font weight: 600 + - Padding: 12px 16px + - Text align: left + +- **Table Row**: + - Border bottom: 1px solid Border + - Padding: 12px 16px + - Hover: Background Secondary + +#### Navigation + +- **Sidebar Navigation**: + - Width: 256px (collapsed: 64px) + - Background: Background Secondary (#2D2D2D) + - Border right: 1px solid Border (#404040) + - Active item: Primary Green background (#2D7A4F), white text (#FFFFFF) + - Active indicator: Left border 3px solid Primary Green + - Hover: Background Tertiary (#404040) + - Icon size: 20px (Medium) + - Item padding: 12px 16px + - Font: Body, Text Primary + - Transition: 200ms ease-in-out + +- **Top Navigation (Header)**: + - Height: 64px + - Background: Background Secondary (#2D2D2D) + - Border bottom: 1px solid Border (#404040) + - Padding: 0 32px + - Display: Flex, space-between, align-center + - Contains: Logo (left), Project selector (center), User info + Logout (right) + +- **Breadcrumbs**: + - Position: Top of main content area + - Font: Body Small, Text Secondary (#B0B0B0) + - Separator: ">" icon, Text Tertiary (#808080) + - Padding: 16px 0 + - Clickable: All items except current page + +#### Modals/Dialogs + +- **Modal Overlay**: + - Background: rgba(0, 0, 0, 0.7) + - Backdrop blur: 4px + +- **Modal Container**: + - Background: Background Secondary + - Border radius: 16px + - Shadow: xl + - Max width: 600px (default) + - Padding: 32px + - Border: 1px solid Border + +#### Forms + +- **Form Group**: + - Margin bottom: 24px + +- **Label**: + - Font size: Body Small + - Font weight: 500 + - Color: Text Primary + - Margin bottom: 8px + - Display: block + +- **Error Message**: + - Font size: Caption + - Color: Error + - Margin top: 4px + +- **Help Text**: + - Font size: Caption + - Color: Text Secondary + - Margin top: 4px + +#### Calculation Formula Display + +- **Formula Container**: + - Background: Background Secondary + - Border: 1px solid Border + - Border radius: 8px + - Padding: 12px 16px + - Margin: 8px 0 + +- **Formula Label**: + - Font size: Body Small + - Font weight: 500 + - Color: Text Secondary + - Margin bottom: 8px + +- **Formula Content**: + - Font: Monospace (JetBrains Mono, Fira Code, or Courier New) + - Font size: Body Small + - Color: Text Primary + - White-space: pre-wrap (preserve formatting) + - Line height: 1.6 + +- **Formula Variables**: + - Display input values used in calculation + - Format: `variable_name = value (unit)` + - Color: Text Secondary for variable names, Text Primary for values + +- **Expandable Formula** (for complex calculations): + - Collapsed: Show formula summary + - Expanded: Show full formula with steps + - Toggle button: Icon button with chevron + +### 11.6.7 Icons + +- **Icon Library**: Heroicons, Lucide, or similar +- **Icon Size**: + - Small: 16px + - Medium: 20px + - Large: 24px + - Extra Large: 32px +- **Icon Style**: Outline for most cases, solid for emphasis +- **Icon Color**: Inherit text color or use semantic colors + +### 11.6.8 Data Visualization + +#### Charts + +- **Color Scheme**: Use Primary Green and Secondary Blue as base +- **Grid Lines**: Border color, opacity 0.3 +- **Axis Labels**: Text Secondary, Body Small +- **Tooltips**: Background Secondary, shadow md, padding 8px 12px + +#### Metrics/KPI Cards + +- **Value**: H2 or H3, Primary Green or Text Primary +- **Label**: Body Small, Text Secondary +- **Trend Indicator**: Arrow icon with Success/Error color +- **Background**: Background Secondary +- **Border**: Optional, 1px solid Border + +### 11.6.9 Layout + +#### Grid System + +- **Container Max Width**: 1280px +- **Grid Columns**: 12 columns +- **Gutter**: 24px +- **Target Platform**: Desktop only (minimum width: 1024px) +- **No Mobile Support**: Application designed exclusively for desktop browsers + +#### Page Structure + +- **Header**: Fixed or sticky, 64px height, Background Secondary +- **Sidebar**: Fixed, 256px width (collapsible), Background Secondary +- **Main Content**: Flexible, padding 32px, Background (dark) +- **Footer**: Optional, 64px height, Background Secondary + +### 11.6.10 UX Principles + +#### Navigation + +- **Breadcrumbs**: Show current location in multi-level navigation +- **Active States**: Clear indication of current page/section +- **Back Navigation**: Consistent back button placement + +#### Feedback + +- **Loading States**: Skeleton loaders or spinners +- **Success Messages**: Toast notifications, green badge +- **Error Messages**: Inline errors, toast notifications, red badge +- **Confirmation Dialogs**: For destructive actions + +#### Accessibility + +- **Color Contrast**: Minimum WCAG AA (4.5:1 for normal text, 3:1 for large text) +- **Focus Indicators**: Visible focus rings (2px, Border Focus color) +- **Keyboard Navigation**: Full keyboard support +- **Screen Readers**: Proper ARIA labels, semantic HTML +- **Text Alternatives**: Alt text for icons and images + +#### Desktop-Only Design + +- **No Mobile Version**: Application is desktop-only, no mobile compatibility +- **No Responsive Design**: Fixed layout optimized for desktop screens (minimum 1024px width) +- **No Touch Support**: Designed for mouse and keyboard interaction only +- **Fixed Layout**: Sidebar and components maintain fixed sizes, no responsive breakpoints + +#### Consistency + +- **Component Reuse**: Use consistent components throughout +- **Spacing**: Follow spacing system +- **Terminology**: Consistent language across application +- **Patterns**: Reuse interaction patterns + +### 11.6.11 Component Architecture Principles + +#### Code Reusability + +- **Maximum Reuse**: Prioritize component reuse over creating new components +- **Shared Components Library**: Maintain a centralized library of reusable components +- **Composition Over Duplication**: Build complex components by composing simple ones +- **DRY Principle**: Don't Repeat Yourself - extract common logic into reusable functions/components +- **Component Hierarchy**: + - Base components (Button, Input, Card) - most reusable + - Composite components (Form, Table, Modal) - composed of base components + - Page-specific components - minimal, use composites when possible +- **Props Interface**: Standardize props interfaces across similar components +- **Shared Utilities**: Extract common utilities, helpers, and hooks into shared modules +- **Template Patterns**: Use consistent patterns for similar features (CRUD operations, forms, lists) + +#### Component Simplicity + +- **Simple Technical Implementation**: + - Avoid complex state management patterns + - Prefer straightforward component structure + - Use standard React patterns (functional components, hooks) + - Avoid advanced optimizations (memo, useMemo, useCallback) + - Keep components focused on single responsibility +- **Readable Code**: + - Clear naming conventions + - Simple logic flow + - Minimal nesting + - Self-documenting code +- **No Premature Optimization**: + - Write straightforward code first + - Avoid performance optimizations unless explicitly needed + - Focus on functionality and maintainability +- **Standard Patterns**: + - Use standard library functions + - Follow framework conventions + - Avoid custom abstractions unless necessary +- **Component Size**: + - Keep components small and focused + - Split large components into smaller, reusable pieces + - Maximum 200-300 lines per component file + +#### Component Structure + +- **Base Components** (highest reusability): + - Button, Input, Select, Textarea, Checkbox, Radio + - Card, Badge, Label, Icon + - Modal, Toast, Tooltip + - FormulaDisplay (for showing calculation rules) +- **Composite Components** (medium reusability): + - Form (composed of Input, Select, etc.) + - Table (composed of Card, Badge, etc.) + - Navigation (composed of Button, Icon, etc.) + - DataDisplay (composed of Card, Badge, etc.) +- **Page Components** (low reusability, use composites): + - Configuration pages use Form components + - Yields page uses DataDisplay components + - Business plan uses shared calculation components + +#### Shared Code Organization + +- **Components Directory Structure**: + + ``` + /components + /base # Most reusable (Button, Input, etc.) + /composite # Composed components (Form, Table, etc.) + /layout # Layout components (Header, Sidebar, etc.) + /shared # Shared business logic components + ``` + +- **Utilities Directory**: + + ``` + /utils + /calculations # Calculation functions + /formatters # Data formatting + /validators # Validation functions + /constants # Shared constants + ``` + +- **Hooks Directory**: + + ``` + /hooks + /useForm # Form management + /useStorage # LocalStorage management + /useAuth # Authentication + ``` + +#### Reusability Guidelines + +- **Before Creating New Component**: + 1. Check if existing component can be extended with props + 2. Check if composition of existing components solves the need + 3. Only create new component if truly unique functionality needed +- **Component Props**: + - Use flexible props to allow reuse in different contexts + - Provide sensible defaults + - Support common use cases out of the box +- **Styling**: + - Use shared style constants/variables + - Support className prop for customization + - Avoid inline styles, use CSS classes or styled-components consistently +- **State Management**: + - Keep state local when possible + - Use shared state management only when necessary + - Prefer props over context for simple data passing + +#### Technical Constraints + +- **No Performance Optimizations**: + - Do not use React.memo() + - Do not use useMemo() for calculations + - Do not use useCallback() for functions + - Do not implement code splitting + - Do not implement lazy loading + - Do not optimize re-renders + - Keep code simple and straightforward +- **Standard Implementation**: + - Use standard React hooks (useState, useEffect, useContext) + - Use standard JavaScript/TypeScript features + - Avoid complex patterns or abstractions + - Prefer explicit over implicit +- **Simplicity First**: + - If there's a simple way and a complex way, choose simple + - Avoid over-engineering + - Focus on working code over optimized code + +### 11.6.12 Animation & Transitions + +#### Transitions + +- **Duration**: + - Fast: 150ms (hover, active states) + - Normal: 200ms (default transitions) + - Slow: 300ms (page transitions, modals) +- **Easing**: + - Default: ease-in-out + - Enter: ease-out + - Exit: ease-in + +#### Animations + +- **Fade In**: For modals, dropdowns +- **Slide**: For sidebars, drawers +- **Scale**: For buttons on click +- **Pulse**: For loading indicators +- **Smooth Scrolling**: For page navigation + +### 11.6.13 Theme Configuration + +**Dark Mode Only - No Theme Switching** + +- The application uses **dark mode exclusively** +- **No theme selector or switching functionality** +- **No light mode support** +- All color definitions above are for dark mode +- Color palette: + - **Background**: #1A1A1A + - **Background Secondary**: #2D2D2D + - **Text Primary**: #FFFFFF + - **Text Secondary**: #B0B0B0 + - **Border**: #404040 +- Maintain consistent color relationships and contrast ratios throughout + +## 12. Validation Rules + +### 12.1 Waste Configuration + +- BMP values must be positive +- Water percentage: 0-100% +- Storage duration must be realistic +- Origin units must be valid + +### 12.2 Regulator Configuration + +- Dosage must be within safe limits +- Compatibility checks with waste types +- Application timing validation + +### 12.3 Service Configuration + +- Pricing must be positive +- Service combinations must be valid +- Module capacity constraints + +### 12.4 Yield Calculations + +- Energy balance validation +- Material balance validation +- Gas production validation + +### 12.5 Project Configuration + +- Treatment site must be valid +- Module count must be positive +- Waste sites must be compatible +- Investment amounts must be within investor ranges +- Administrative procedures must be valid +- Distance calculations must be realistic + +### 12.6 Treatment Site Configuration + +- Temperature values must be realistic +- Altitude must be valid +- Surface area must accommodate modules +- Services must be compatible + +### 12.7 Waste Site Configuration + +- Quantity ranges must be positive +- Distance must be realistic +- Collection type must be valid +- Waste type must match project requirements + +## 13. Integration Requirements + +### 13.1 Data Persistence + +- **Storage mechanism**: Browser-based storage (localStorage, IndexedDB) +- **Data types stored**: + - Configuration storage + - Historical yield data + - Business plan storage + - Project management + - Treatment site data + - Waste site data + - Investor data + - Administrative procedures tracking + - User authentication data +- **Persistence strategy**: Automatic save on data modification +- **Data backup**: Export/import functionality for data backup +- **Storage limits**: Browser storage quota management +- **Data migration**: Support for data structure versioning and migration + +### 13.2 Reporting + +- Yield reports +- Business plan reports +- Service reports +- Export formats (PDF, Excel, CSV) + +### 13.3 Real-time Updates + +- Live yield calculations +- Dynamic pricing updates +- Real-time energy balance + +### 13.4 Security Requirements + +- **Localhost restriction**: Application must only run on localhost +- **No network access**: No external API calls or network requests +- **Client-side only**: All processing and storage on client-side +- **Authentication**: Simple login system for local access control +- **Data encryption**: Optional encryption for sensitive data in local storage + +## 14. Future Enhancements + +### 14.1 Advanced Features + +- Multi-project management +- Comparative analysis +- Optimization algorithms +- Predictive modeling + +### 14.2 Integration Capabilities + +- External data sources +- API integrations +- Third-party service connections diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..5879b02 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,56 @@ +import { Routes, Route, Navigate } from 'react-router-dom' +import { useAuth } from './contexts/AuthContext' +import Layout from './components/layout/Layout' +import LoginPage from './pages/LoginPage' +import DashboardPage from './pages/DashboardPage' +import WasteConfigurationPage from './pages/configuration/WasteConfigurationPage' +import RegulatorsConfigurationPage from './pages/configuration/RegulatorsConfigurationPage' +import ServicesConfigurationPage from './pages/configuration/ServicesConfigurationPage' +import ProjectListPage from './pages/projects/ProjectListPage' +import ProjectConfigurationPage from './pages/projects/ProjectConfigurationPage' +import TreatmentSitesPage from './pages/projects/TreatmentSitesPage' +import WasteSitesPage from './pages/projects/WasteSitesPage' +import InvestorsPage from './pages/projects/InvestorsPage' +import AdministrativeProceduresPage from './pages/projects/AdministrativeProceduresPage' +import YieldsPage from './pages/YieldsPage' +import BusinessPlanPage from './pages/BusinessPlanPage' +import SettingsPage from './pages/SettingsPage' +import HelpPage from './pages/HelpPage' + +function App() { + const { isAuthenticated } = useAuth() + + if (!isAuthenticated) { + return ( + + } /> + } /> + + ) + } + + return ( + + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + + ) +} + +export default App diff --git a/src/components/base/Badge.css b/src/components/base/Badge.css new file mode 100644 index 0000000..5afdc74 --- /dev/null +++ b/src/components/base/Badge.css @@ -0,0 +1,62 @@ +.badge { + display: inline-block; + padding: 4px 12px; + border-radius: 9999px; + font-size: 0.875rem; + font-weight: 500; +} + +.badge-success { + background-color: rgba(16, 185, 129, 0.2); + color: var(--success); +} + +.badge-warning { + background-color: rgba(245, 158, 11, 0.2); + color: var(--warning); +} + +.badge-error { + background-color: rgba(239, 68, 68, 0.2); + color: var(--error); +} + +.badge-info { + background-color: rgba(59, 130, 246, 0.2); + color: var(--info); +} + +.badge-pending { + background-color: rgba(245, 158, 11, 0.2); + color: var(--pending); +} + +.badge-completed { + background-color: rgba(16, 185, 129, 0.2); + color: var(--completed); +} + +.badge-to-do { + background-color: rgba(108, 117, 125, 0.2); + color: var(--to-do); +} + +.badge-to-be-approached { + background-color: rgba(245, 158, 11, 0.2); + color: var(--to-be-approached); +} + +.badge-loi-ok { + background-color: rgba(59, 130, 246, 0.2); + color: var(--loi-ok); +} + +.badge-in-progress { + background-color: rgba(139, 92, 246, 0.2); + color: var(--in-progress); +} + +.badge-na { + background-color: rgba(156, 163, 175, 0.2); + color: var(--na); +} diff --git a/src/components/base/Badge.tsx b/src/components/base/Badge.tsx new file mode 100644 index 0000000..df34f88 --- /dev/null +++ b/src/components/base/Badge.tsx @@ -0,0 +1,10 @@ +import './Badge.css' + +interface BadgeProps { + children: string + variant?: 'success' | 'warning' | 'error' | 'info' | 'pending' | 'completed' | 'to-do' | 'to-be-approached' | 'loi-ok' | 'in-progress' | 'na' +} + +export default function Badge({ children, variant = 'info' }: BadgeProps) { + return {children} +} diff --git a/src/components/base/Button.css b/src/components/base/Button.css new file mode 100644 index 0000000..c9f65bb --- /dev/null +++ b/src/components/base/Button.css @@ -0,0 +1,49 @@ +.button { + padding: 12px 24px; + border-radius: 8px; + font-size: 1rem; + font-weight: 500; + cursor: pointer; + transition: all 200ms ease-in-out; + border: none; + font-family: var(--font-family); +} + +.button-primary { + background-color: var(--primary-green); + color: var(--text-primary); +} + +.button-primary:hover { + background-color: var(--primary-green-light); +} + +.button-primary:active { + background-color: var(--primary-green-dark); +} + +.button-secondary { + background-color: transparent; + border: 1px solid var(--border); + color: var(--text-primary); +} + +.button-secondary:hover { + background-color: var(--background-secondary); +} + +.button-danger { + background-color: var(--error); + color: var(--text-primary); +} + +.button-danger:hover { + background-color: #DC2626; +} + +.button:disabled { + background-color: var(--background-secondary); + color: var(--text-tertiary); + cursor: not-allowed; + opacity: 0.6; +} diff --git a/src/components/base/Button.tsx b/src/components/base/Button.tsx new file mode 100644 index 0000000..ab5f69a --- /dev/null +++ b/src/components/base/Button.tsx @@ -0,0 +1,15 @@ +import { ReactNode, ButtonHTMLAttributes } from 'react' +import './Button.css' + +interface ButtonProps extends ButtonHTMLAttributes { + variant?: 'primary' | 'secondary' | 'danger' + children: ReactNode +} + +export default function Button({ variant = 'primary', children, className = '', ...props }: ButtonProps) { + return ( + + ) +} diff --git a/src/components/base/Card.css b/src/components/base/Card.css new file mode 100644 index 0000000..54446d4 --- /dev/null +++ b/src/components/base/Card.css @@ -0,0 +1,20 @@ +.card { + background-color: var(--background-secondary); + border: 1px solid var(--border); + border-radius: 12px; + padding: 24px; + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.3); +} + +.card-header { + font-size: 1.25rem; + font-weight: 600; + color: var(--text-primary); + margin-bottom: 16px; + padding-bottom: 16px; + border-bottom: 1px solid var(--border); +} + +.card-content { + color: var(--text-primary); +} diff --git a/src/components/base/Card.tsx b/src/components/base/Card.tsx new file mode 100644 index 0000000..30bee23 --- /dev/null +++ b/src/components/base/Card.tsx @@ -0,0 +1,17 @@ +import { ReactNode } from 'react' +import './Card.css' + +interface CardProps { + children: ReactNode + title?: string + className?: string +} + +export default function Card({ children, title, className = '' }: CardProps) { + return ( +
+ {title &&
{title}
} +
{children}
+
+ ) +} diff --git a/src/components/base/Input.css b/src/components/base/Input.css new file mode 100644 index 0000000..031c382 --- /dev/null +++ b/src/components/base/Input.css @@ -0,0 +1,60 @@ +.input-group { + margin-bottom: 24px; +} + +.input-label { + display: block; + font-size: 0.875rem; + font-weight: 500; + color: var(--text-primary); + margin-bottom: 8px; +} + +.input { + width: 100%; + height: 44px; + padding: 12px 16px; + background-color: var(--background-secondary); + border: 1px solid var(--border); + border-radius: 8px; + color: var(--text-primary); + font-size: 1rem; + font-family: var(--font-family); + transition: border-color 200ms ease-in-out; +} + +.input:focus { + outline: none; + border-color: var(--border-focus); + border-width: 2px; +} + +.input::placeholder { + color: var(--text-tertiary); +} + +.input:disabled { + background-color: var(--background-tertiary); + color: var(--text-tertiary); + cursor: not-allowed; +} + +.input-error { + border-color: var(--error); +} + +.input-error:focus { + border-color: var(--error); +} + +.input-error-message { + font-size: 0.75rem; + color: var(--error); + margin-top: 4px; +} + +.input-help-text { + font-size: 0.75rem; + color: var(--text-secondary); + margin-top: 4px; +} diff --git a/src/components/base/Input.tsx b/src/components/base/Input.tsx new file mode 100644 index 0000000..8113f28 --- /dev/null +++ b/src/components/base/Input.tsx @@ -0,0 +1,33 @@ +import { InputHTMLAttributes, forwardRef } from 'react' +import './Input.css' + +interface InputProps extends InputHTMLAttributes { + label?: string + error?: string + helpText?: string +} + +const Input = forwardRef( + ({ label, error, helpText, className = '', ...props }, ref) => { + return ( +
+ {label && ( + + )} + + {error &&
{error}
} + {helpText && !error &&
{helpText}
} +
+ ) + } +) + +Input.displayName = 'Input' + +export default Input diff --git a/src/components/base/Select.css b/src/components/base/Select.css new file mode 100644 index 0000000..dc60ab7 --- /dev/null +++ b/src/components/base/Select.css @@ -0,0 +1,57 @@ +.select-group { + margin-bottom: 24px; +} + +.select-label { + display: block; + font-size: 0.875rem; + font-weight: 500; + color: var(--text-primary); + margin-bottom: 8px; +} + +.select { + width: 100%; + height: 44px; + padding: 12px 16px; + background-color: var(--background-secondary); + border: 1px solid var(--border); + border-radius: 8px; + color: var(--text-primary); + font-size: 1rem; + font-family: var(--font-family); + cursor: pointer; + transition: border-color 200ms ease-in-out; +} + +.select:focus { + outline: none; + border-color: var(--border-focus); + border-width: 2px; +} + +.select:disabled { + background-color: var(--background-tertiary); + color: var(--text-tertiary); + cursor: not-allowed; +} + +.select-error { + border-color: var(--error); +} + +.select-error:focus { + border-color: var(--error); +} + +.select-error-message { + font-size: 0.75rem; + color: var(--error); + margin-top: 4px; +} + +.select-help-text { + font-size: 0.75rem; + color: var(--text-secondary); + margin-top: 4px; +} diff --git a/src/components/base/Select.tsx b/src/components/base/Select.tsx new file mode 100644 index 0000000..22be00c --- /dev/null +++ b/src/components/base/Select.tsx @@ -0,0 +1,40 @@ +import { SelectHTMLAttributes, forwardRef } from 'react' +import './Select.css' + +interface SelectProps extends SelectHTMLAttributes { + label?: string + error?: string + helpText?: string + options: { value: string; label: string }[] +} + +const Select = forwardRef( + ({ label, error, helpText, options, className = '', ...props }, ref) => { + return ( +
+ {label && ( + + )} + + {error &&
{error}
} + {helpText && !error &&
{helpText}
} +
+ ) + } +) + +Select.displayName = 'Select' + +export default Select diff --git a/src/components/base/Table.css b/src/components/base/Table.css new file mode 100644 index 0000000..31e871a --- /dev/null +++ b/src/components/base/Table.css @@ -0,0 +1,46 @@ +.table-container { + border: 1px solid var(--border); + border-radius: 8px; + overflow: hidden; +} + +.table { + width: 100%; + border-collapse: collapse; +} + +.table-header { + background-color: var(--background-secondary); + font-weight: 600; + padding: 12px 16px; + text-align: left; + color: var(--text-primary); + font-size: 0.875rem; +} + +.table-row { + border-bottom: 1px solid var(--border); +} + +.table-row:last-child { + border-bottom: none; +} + +.table-row:hover { + background-color: var(--background-secondary); +} + +.table-cell { + padding: 12px 16px; + color: var(--text-primary); + font-size: 0.875rem; +} + +.table-empty { + padding: 48px; + text-align: center; + color: var(--text-secondary); + background-color: var(--background-secondary); + border: 1px solid var(--border); + border-radius: 8px; +} diff --git a/src/components/base/Table.tsx b/src/components/base/Table.tsx new file mode 100644 index 0000000..4c66607 --- /dev/null +++ b/src/components/base/Table.tsx @@ -0,0 +1,51 @@ +import { ReactNode } from 'react' +import './Table.css' + +interface TableColumn { + key: string + header: string + render: (item: T) => ReactNode +} + +interface TableProps { + columns: TableColumn[] + data: T[] + emptyMessage?: string +} + +export default function Table({ columns, data, emptyMessage = 'No data' }: TableProps) { + if (data.length === 0) { + return ( +
+

{emptyMessage}

+
+ ) + } + + return ( +
+ + + + {columns.map((column) => ( + + ))} + + + + {data.map((item) => ( + + {columns.map((column) => ( + + ))} + + ))} + +
+ {column.header} +
+ {column.render(item)} +
+
+ ) +} diff --git a/src/components/layout/Header.css b/src/components/layout/Header.css new file mode 100644 index 0000000..48feaf1 --- /dev/null +++ b/src/components/layout/Header.css @@ -0,0 +1,72 @@ +.header { + height: 64px; + background-color: var(--background-secondary); + border-bottom: 1px solid var(--border); + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 var(--spacing-xl); + position: sticky; + top: 0; + z-index: 50; +} + +.header-left { + flex: 1; +} + +.header-logo { + font-size: 1.25rem; + font-weight: 600; + color: var(--text-primary); +} + +.header-center { + flex: 1; + display: flex; + justify-content: center; +} + +.header-project-selector { + background-color: var(--background); + border: 1px solid var(--border); + border-radius: 8px; + padding: var(--spacing-sm) var(--spacing-md); + color: var(--text-primary); + font-size: 0.875rem; + min-width: 200px; +} + +.header-project-selector:focus { + outline: none; + border-color: var(--border-focus); +} + +.header-right { + flex: 1; + display: flex; + align-items: center; + justify-content: flex-end; + gap: var(--spacing-md); +} + +.header-username { + color: var(--text-secondary); + font-size: 0.875rem; +} + +.header-logout { + background-color: transparent; + border: 1px solid var(--border); + border-radius: 8px; + padding: var(--spacing-sm) var(--spacing-md); + color: var(--text-primary); + font-size: 0.875rem; + cursor: pointer; + transition: all 200ms ease-in-out; +} + +.header-logout:hover { + background-color: var(--background-tertiary); + border-color: var(--border-focus); +} diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx new file mode 100644 index 0000000..ed020ef --- /dev/null +++ b/src/components/layout/Header.tsx @@ -0,0 +1,44 @@ +import { useNavigate } from 'react-router-dom' +import { useAuth } from '@/contexts/AuthContext' +import { useStorage } from '@/hooks/useStorage' +import './Header.css' + +export default function Header() { + const { username, logout } = useAuth() + const { data } = useStorage() + const navigate = useNavigate() + + const projects = data?.projects || [] + const currentProject = projects.length > 0 ? projects[0] : null + + const handleLogout = () => { + logout() + navigate('/login', { replace: true }) + } + + return ( +
+
+

4NK Waste & Water

+
+
+ {currentProject && ( + + )} +
+
+ {username} + +
+
+ ) +} diff --git a/src/components/layout/Layout.css b/src/components/layout/Layout.css new file mode 100644 index 0000000..ac629c2 --- /dev/null +++ b/src/components/layout/Layout.css @@ -0,0 +1,18 @@ +.layout { + display: flex; + min-height: 100vh; + background-color: var(--background); +} + +.layout-content { + flex: 1; + display: flex; + flex-direction: column; + margin-left: 256px; +} + +.layout-main { + flex: 1; + padding: var(--spacing-xl); + overflow-y: auto; +} diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx new file mode 100644 index 0000000..1feb2b0 --- /dev/null +++ b/src/components/layout/Layout.tsx @@ -0,0 +1,22 @@ +import { ReactNode } from 'react' +import Sidebar from './Sidebar' +import Header from './Header' +import './Layout.css' + +interface LayoutProps { + children: ReactNode +} + +export default function Layout({ children }: LayoutProps) { + return ( +
+ +
+
+
+ {children} +
+
+
+ ) +} diff --git a/src/components/layout/Sidebar.css b/src/components/layout/Sidebar.css new file mode 100644 index 0000000..db414c8 --- /dev/null +++ b/src/components/layout/Sidebar.css @@ -0,0 +1,71 @@ +.sidebar { + position: fixed; + left: 0; + top: 0; + width: 256px; + height: 100vh; + background-color: var(--background-secondary); + border-right: 1px solid var(--border); + z-index: 100; + overflow-y: auto; +} + +.sidebar-nav { + display: flex; + flex-direction: column; + padding: var(--spacing-md); + gap: var(--spacing-xs); +} + +.sidebar-section { + margin-top: var(--spacing-md); +} + +.sidebar-section-title { + font-size: 0.75rem; + font-weight: 600; + color: var(--text-tertiary); + text-transform: uppercase; + letter-spacing: 0.05em; + padding: var(--spacing-sm) var(--spacing-md); + margin-bottom: var(--spacing-xs); +} + +.sidebar-section-bottom { + margin-top: auto; + padding-top: var(--spacing-lg); +} + +.sidebar-item { + display: flex; + align-items: center; + gap: var(--spacing-md); + padding: var(--spacing-sm) var(--spacing-md); + color: var(--text-secondary); + text-decoration: none; + border-radius: 8px; + transition: all 200ms ease-in-out; + border-left: 3px solid transparent; +} + +.sidebar-item:hover { + background-color: var(--background-tertiary); + color: var(--text-primary); +} + +.sidebar-item.active { + background-color: var(--primary-green); + color: var(--text-primary); + border-left-color: var(--primary-green); +} + +.sidebar-icon { + font-size: 20px; + width: 20px; + text-align: center; +} + +.sidebar-label { + font-size: 0.875rem; + font-weight: 500; +} diff --git a/src/components/layout/Sidebar.tsx b/src/components/layout/Sidebar.tsx new file mode 100644 index 0000000..8667797 --- /dev/null +++ b/src/components/layout/Sidebar.tsx @@ -0,0 +1,76 @@ +import { NavLink } from 'react-router-dom' +import './Sidebar.css' + +export default function Sidebar() { + return ( + + ) +} diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx new file mode 100644 index 0000000..abaac26 --- /dev/null +++ b/src/contexts/AuthContext.tsx @@ -0,0 +1,55 @@ +import { createContext, useContext, useState, useEffect, ReactNode } from 'react' +import { getUserSession, saveUserSession, clearUserSession } from '@/utils/storage' + +interface AuthContextType { + isAuthenticated: boolean + username: string | null + login: (user: string, password: string) => boolean + logout: () => void +} + +const AuthContext = createContext(undefined) + +export function AuthProvider({ children }: { children: ReactNode }) { + const [isAuthenticated, setIsAuthenticated] = useState(false) + const [username, setUsername] = useState(null) + + useEffect(() => { + const sessionUser = getUserSession() + if (sessionUser) { + setIsAuthenticated(true) + setUsername(sessionUser) + } + }, []) + + const login = (user: string, password: string): boolean => { + if (user && user.trim() && password && password.trim()) { + saveUserSession(user.trim()) + setIsAuthenticated(true) + setUsername(user.trim()) + return true + } + return false + } + + const logout = () => { + clearUserSession() + setIsAuthenticated(false) + setUsername(null) + } + + return ( + + {children} + + ) +} + +export function useAuth() { + const context = useContext(AuthContext) + if (context === undefined) { + throw new Error('useAuth must be used within an AuthProvider') + } + return context +} + diff --git a/src/data/seedRegulators.ts b/src/data/seedRegulators.ts new file mode 100644 index 0000000..aa03de9 --- /dev/null +++ b/src/data/seedRegulators.ts @@ -0,0 +1,863 @@ +import { NaturalRegulator } from '@/types' + +export const seedRegulators: NaturalRegulator[] = [ + // ===== RÉGULATEURS PHYSICO-CHIMIQUES COMMUNS ===== + { + id: 'reg-001', + name: 'Gypse', + type: 'physico-chimique-mineral', + regulatoryCharacteristics: { + phAdjustment: -0.5, // Réduction douce du pH + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Poudre ou granulé sec à doser en fonction du taux de salinité mesuré ; préhydratation facultative. Température: 5-70°C, Humidité: 30-95%. Mélangé à cœur ou en surface (≥ 20 cm).', + dosageRequirements: { + min: 5, + max: 50, + unit: 'kg/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-002', + name: 'Biochar', + type: 'support-adsorbant', + regulatoryCharacteristics: { + metalBinding: true, + pathogenReduction: false, + }, + applicationConditions: 'Sec, broyé ou granulé fin ; intégré par brassage ou dispersion ciblée. Température: 0-70°C, Humidité: 10-70%. Dispersé sur 10-30 cm de profondeur.', + dosageRequirements: { + min: 10, + max: 100, + unit: 'kg/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-003', + name: 'Aiguilles de pin', + type: 'substrat-vegetal-acidifiant', + regulatoryCharacteristics: { + phAdjustment: -1.0, + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Sec ou légèrement humidifié, pré-broyé si possible, en mélange progressif. Température: 5-60°C, Humidité: 15-85%. 10 à 25 cm de dispersion ou paillage superficiel.', + dosageRequirements: { + min: 20, + max: 80, + unit: 'kg/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-004', + name: 'Cendres', + type: 'regulateur-mineral-alcalin', + regulatoryCharacteristics: { + phAdjustment: 1.5, + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Sec, broyé fin, incorporé lentement ; dosage en fonction du pH du digesta. Température: 5-70°C, Humidité: 10-70%. Intégration homogène à 10-30 cm.', + dosageRequirements: { + min: 5, + max: 30, + unit: 'kg/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-005', + name: 'CO₂ (générateur ou apport externe)', + type: 'regulateur-gazeux-tampon', + regulatoryCharacteristics: { + phAdjustment: -0.3, + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Injection contrôlée dans digesteur fermé ; surveillance manométrique. Température: 5-70°C. Mélange dans la phase gazeuse du digesteur.', + dosageRequirements: { + min: 1, + max: 10, + unit: '%', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-006', + name: 'H₂ (gaz)', + type: 'gaz-reducteur', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Injection à faible débit dans environnement anaérobie strict, à température stabilisée. Température: 15-65°C. Mélange dans la zone supérieure du digesteur.', + dosageRequirements: { + min: 0.5, + max: 5, + unit: '%', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-007', + name: 'Déchets STEP sableux', + type: 'support-bacterien-inerte', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Sable sec ou semi-sec, intégré en phase de remplissage de cuve. Température: 5-60°C, Humidité: 10-80%. Couche basale ou mélange 10-30 cm.', + dosageRequirements: { + min: 50, + max: 200, + unit: 'kg/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-008', + name: 'Glucose (fruits)', + type: 'substrat-biochimique-soluble', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Incorporé en solution ou purée, bien mélangé dans les premières 24h. Température: 10-65°C, Humidité: 60-98%. 5 à 15 cm selon homogénéité du mélange.', + dosageRequirements: { + min: 1, + max: 10, + unit: 'kg/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-009', + name: 'Digesta (de lot précédent)', + type: 'residu-biologique-stabilise', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Utilisation rapide après extraction ; ajout en mélange homogène. Température: 15-65°C, Humidité: 75-98%. 10 à 25 cm en mélange avec substrat frais.', + dosageRequirements: { + min: 5, + max: 20, + unit: '%', + }, + createdAt: new Date().toISOString(), + }, + + // ===== BACTÉRIES COMMUNES À TOUTES LES MÉTHANISATIONS ===== + { + id: 'reg-010', + name: 'Clostridium butyricum', + type: 'bacterie-anaerobie-fermentative', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Inoculation sous atmosphère anaérobie stricte, dans substrat riche en glucides. Température: 20-55°C, Humidité: 75-98%. Uniformément répartie, optimale à ≥ 15 cm.', + dosageRequirements: { + min: 0.1, + max: 2, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-011', + name: 'Clostridium acetobutylicum', + type: 'bacterie-anaerobie-fermentative', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Apport en substrat carboné (glucose, amidon), maintien d\'un pH neutre. Température: 25-55°C, Humidité: 70-98%. ≥ 20 cm dans la phase active du digesta.', + dosageRequirements: { + min: 0.1, + max: 2, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-012', + name: 'Enterobacter aerogenes', + type: 'bacterie-anaerobie-facultative', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Préfère des substrats sucrés, peut cohabiter temporairement avec O₂ résiduel. Température: 20-50°C, Humidité: 70-99%. Surface à profondeur moyenne (10-25 cm).', + dosageRequirements: { + min: 0.1, + max: 1.5, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-013', + name: 'Desulfobacter postgatei', + type: 'bacterie-anaerobie-reductrice-sulfate', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Anaérobie stricte, apport modéré en carbone ; éviter les excès de nitrates. Température: 15-55°C, Humidité: 80-100%. ≥ 30 cm, dans les zones profondes.', + dosageRequirements: { + min: 0.05, + max: 1, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-014', + name: 'Lactobacillus spp.', + type: 'bacterie-fermentative-lactique', + regulatoryCharacteristics: { + phAdjustment: -1.0, + metalBinding: false, + pathogenReduction: true, + }, + applicationConditions: 'Inoculation au démarrage ou en phase de relance ; bon brassage nécessaire. Température: 10-50°C, Humidité: 60-98%. 5 à 20 cm, zone supérieure du substrat.', + dosageRequirements: { + min: 0.2, + max: 3, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-015', + name: 'Bacillus subtilis', + type: 'bacterie-sporulante-multifonctionnelle', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: true, + }, + applicationConditions: 'Peut être inoculé dès la phase mésophile, tolère les transitions thermiques. Température: 15-60°C, Humidité: 50-95%. 10 à 25 cm selon brassage.', + dosageRequirements: { + min: 0.1, + max: 2, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-016', + name: 'Enterococcus faecium', + type: 'bacterie-fermentative-lactique', + regulatoryCharacteristics: { + phAdjustment: -0.8, + metalBinding: false, + pathogenReduction: true, + }, + applicationConditions: 'Apport en début de cycle, co-inoculation avec lactobacilles possible. Température: 10-45°C, Humidité: 65-98%. 10 à 20 cm dans la zone active.', + dosageRequirements: { + min: 0.1, + max: 1.5, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-017', + name: 'Paenibacillus polymyxa', + type: 'bacterie-fixatrice-azote', + regulatoryCharacteristics: { + nitrogen: 0.5, + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Inoculation dans substrats végétaux ou mixtes ; pH neutre à légèrement acide. Température: 15-50°C, Humidité: 55-95%. 15 à 30 cm ; zones bien humides.', + dosageRequirements: { + min: 0.1, + max: 1.5, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-018', + name: 'Paracoccus denitrificans', + type: 'bacterie-denitrifiante', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'pH neutre, teneur suffisante en nitrate et en carbone, zone légèrement aérée. Température: 10-45°C, Humidité: 60-98%. Zones moyennes (15-25 cm), bien mélangées.', + dosageRequirements: { + min: 0.05, + max: 1, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-019', + name: 'Streptomyces spp.', + type: 'bacterie-filamenteuse-fongicide', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: true, + }, + applicationConditions: 'En conditions aérobies en amont ou en bordure des digesteurs. Température: 15-45°C, Humidité: 50-90%. Zone supérieure à 15-20 cm, bien aérée.', + dosageRequirements: { + min: 0.1, + max: 2, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + + // ===== RÉGULATEURS SPÉCIFIQUES MÉTHANISATION TEMPÉRATURE AMBIANTE ===== + { + id: 'reg-020', + name: 'Lactobacillus plantarum', + type: 'bacterie-fermentative-lactique', + regulatoryCharacteristics: { + phAdjustment: -1.2, + metalBinding: false, + pathogenReduction: true, + }, + applicationConditions: 'Inoculation en début de cycle ; bien mélanger dans substrat humide. Température: 10-45°C, Humidité: 60-98%. 5 à 20 cm, dans les premières couches du substrat.', + dosageRequirements: { + min: 0.2, + max: 3, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-021', + name: 'Corynebacterium glutamicum', + type: 'bacterie-productrice-acides-amines', + regulatoryCharacteristics: { + carbonNitrogenRatio: 20, + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Apport modéré dans substrats mixtes (protéines + sucres). Température: 20-45°C, Humidité: 50-90%. Zone moyenne (15-25 cm).', + dosageRequirements: { + min: 0.1, + max: 1.5, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-022', + name: 'Mycobacterium smegmatis', + type: 'bacterie-degradant-lipides', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Apport fractionné, suivi de température et d\'agitation recommandé. Température: 20-50°C, Humidité: 65-98%. 10 à 30 cm, bien intégré à la masse grasse.', + dosageRequirements: { + min: 0.05, + max: 1, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-023', + name: 'Bacillus megaterium', + type: 'bacterie-sporulante-multifonctionnelle', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Inoculation directe dans substrats organiques après brassage. Température: 15-55°C, Humidité: 60-95%. 10 à 25 cm dans la zone humide.', + dosageRequirements: { + min: 0.1, + max: 2, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + + // ===== TRAITEMENT ALGUES, LARVES, BACTÉRIES ===== + { + id: 'reg-024', + name: 'Scenedesmus obliquus', + type: 'micro-algue-verte', + regulatoryCharacteristics: { + metalBinding: true, + pathogenReduction: false, + }, + applicationConditions: 'Nécessite lumière naturelle ou LED spectre bleu/rouge ; brassage lent. Température: 15-32°C, Humidité: >95%. Colonise la surface des bassins ou interfaces air/eau.', + dosageRequirements: { + min: 0.5, + max: 5, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-025', + name: 'Nannochloropsis oculata', + type: 'micro-algue-marine', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Milieu salin ou saumâtre, apport régulier en lumière et CO₂. Température: 20-28°C, Humidité: >95%. Zone photique de 5-15 cm, en eau peu agitée.', + dosageRequirements: { + min: 0.5, + max: 5, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-026', + name: 'Chlorella vulgaris', + type: 'micro-algue-verte', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Lumière directe ou artificielle, injection contrôlée de CO₂, agitation douce. Température: 18-30°C, Humidité: >95%. Surface lumineuse (0-15 cm).', + dosageRequirements: { + min: 0.5, + max: 5, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-027', + name: 'Pseudomonas fluorescens', + type: 'bacterie-bioremédiation', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Inoculation dans substrats humides et oxygénés ; éviter l\'anaérobie stricte. Température: 15-35°C, Humidité: 60-100%. Zone moyenne à superficielle (5-20 cm).', + dosageRequirements: { + min: 0.1, + max: 2, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-028', + name: 'Pseudomonas putida', + type: 'bacterie-versatile-metabolique', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Nécessite un minimum d\'oxygène ; substrat humide, lumière non nécessaire. Température: 10-37°C, Humidité: 65-98%. Superficie et interfaces (eau/air ou litière humide).', + dosageRequirements: { + min: 0.1, + max: 2, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-029', + name: 'Gluconobacter oxydans', + type: 'bacterie-aerobique-acetique', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Phase aérobie légère ou microaérophile, suivi du pH recommandé. Température: 20-35°C, Humidité: 60-98%. Zone superficielle à 10 cm max.', + dosageRequirements: { + min: 0.05, + max: 1, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-030', + name: 'Rhodobacter sphaeroides', + type: 'bacterie-photosynthetique-anaerobie', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Lumière rouge ou naturelle indirecte, substrats riches en C organique. Température: 15-40°C, Humidité: >85%. Zone éclairée, souvent à l\'interface liquide/gaz.', + dosageRequirements: { + min: 0.1, + max: 1.5, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-031', + name: 'Rhodospirillum rubrum', + type: 'bacterie-photosynthetique-anoxygénique', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Milieu semi-stagnant, lumière indirecte, supplément CO₂ ou H₂. Température: 15-38°C, Humidité: >85%. Interface liquide-gaz dans zones lumineuses.', + dosageRequirements: { + min: 0.1, + max: 1.5, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + + // ===== TRAITEMENT CHAMPIGNONS, VERS, BACTÉRIES ===== + { + id: 'reg-032', + name: 'Ganoderma', + type: 'champignon-ligninolytique', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Température basse, bonne aération, humidité contrôlée ; nécessite structure porteuse. Température: 5-28°C, Humidité: 60-90%. Zone superficielle ou colonisation de blocs lignocellulosiques.', + dosageRequirements: { + min: 0.5, + max: 5, + unit: 'kg/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-033', + name: 'Pleurotus spp.', + type: 'champignon-lignocellulosique', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Apport de substrat fibreux, maintien d\'une humidité constante, éviter l\'immersion. Température: 8-28°C, Humidité: 65-90%. Surface à 20 cm en lit ou blocs mycélisés.', + dosageRequirements: { + min: 1, + max: 10, + unit: 'kg/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-034', + name: 'Penicillium chrysogenum', + type: 'moisissure-filamenteuse', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: true, + }, + applicationConditions: 'Aération légère, température fraîche, surface humide non saturée. Température: 5-25°C, Humidité: 60-90%. Zone superficielle, 5-10 cm sur substrats humides.', + dosageRequirements: { + min: 0.5, + max: 5, + unit: 'kg/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-035', + name: 'Aspergillus niger', + type: 'moisissure-filamenteuse', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Aération minimale, éviter saturation en eau, pH légèrement acide. Température: 10-40°C, Humidité: 50-85%. 5 à 15 cm ; préfère surfaces fibreuses ou compostées.', + dosageRequirements: { + min: 0.5, + max: 5, + unit: 'kg/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-036', + name: 'Eisenia fetida', + type: 'ver-composteur', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Litière végétale stable, humidité constante, éviter substrats toxiques ou trop gras. Température: 10-28°C, Humidité: 60-85%. 5 à 25 cm dans le lit de décomposition.', + dosageRequirements: { + min: 0.5, + max: 5, + unit: 'kg/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-037', + name: 'Lumbricus rubellus', + type: 'ver-de-terre-epige', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Substrat végétal non compacté, humidité constante, pas de forte lumière. Température: 5-25°C, Humidité: 65-90%. 0 à 15 cm ; préfère couches de surface.', + dosageRequirements: { + min: 0.3, + max: 3, + unit: 'kg/t', + }, + createdAt: new Date().toISOString(), + }, + + // ===== TRAITEMENT PLANTES, VERS, BACTÉRIES ===== + { + id: 'reg-038', + name: 'Fougère (bioindicatrice / phytoextratrice)', + type: 'plante-hyperaccumulatrice-metaux', + regulatoryCharacteristics: { + metalBinding: true, + pathogenReduction: false, + }, + applicationConditions: 'Plantation ou bouturage dans substrat filtrant, arrosage goutte-à-goutte. Température: 10-30°C, Humidité: 50-85%. Sol ou substrat meuble de 15-30 cm.', + dosageRequirements: { + min: 10, + max: 50, + unit: 'kg/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-039', + name: 'Ray-grass (Lolium perenne)', + type: 'plante-fixatrice-azote', + regulatoryCharacteristics: { + nitrogen: 2.0, + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Semis direct sur couche filtrante, arrosage contrôlé. Température: 8-30°C, Humidité: 40-85%. 10 à 20 cm pour enracinement dense.', + dosageRequirements: { + min: 5, + max: 30, + unit: 'kg/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-040', + name: 'Trèfle blanc (Trifolium repens)', + type: 'legumineuse-fixatrice-azote', + regulatoryCharacteristics: { + nitrogen: 3.0, + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Semis ou bouture, apport initial de Rhizobium recommandé. Température: 5-28°C, Humidité: 50-90%. 10 à 15 cm dans sol aéré.', + dosageRequirements: { + min: 5, + max: 25, + unit: 'kg/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-041', + name: 'Moutarde indienne (Brassica juncea)', + type: 'plante-phytoextractrice', + regulatoryCharacteristics: { + metalBinding: true, + pathogenReduction: false, + }, + applicationConditions: 'Semis en surface ou substrat minéral, récolte après 30-40 jours. Température: 10-32°C, Humidité: 40-85%. 15 à 25 cm, sol bien drainé.', + dosageRequirements: { + min: 5, + max: 30, + unit: 'kg/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-042', + name: 'Glomus spp.', + type: 'champignon-mycorhizien', + regulatoryCharacteristics: { + phosphorus: 0.5, + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Co-inoculation avec plantes herbacées, ne pas stériliser le substrat. Température: 12-30°C, Humidité: 60-95%. Racines profondes (15-30 cm) en contact symbiotique.', + dosageRequirements: { + min: 0.1, + max: 2, + unit: 'kg/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-043', + name: 'Nitrosomonas europaea', + type: 'bacterie-nitrifiante', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Apport d\'oxygène, éviter pH < 6,5, température stabilisée. Température: 10-35°C, Humidité: 70-100%. Couche superficielle (5-15 cm), bonne aération.', + dosageRequirements: { + min: 0.05, + max: 1, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-044', + name: 'Nitrobacter winogradskyi', + type: 'bacterie-nitrifiante', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Oxygénation douce, neutralité du pH, interaction avec N. europaea. Température: 10-35°C, Humidité: 70-100%. 5-15 cm ; préfère substrats légers et bien drainés.', + dosageRequirements: { + min: 0.05, + max: 1, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + + // ===== MÉTHANISATION THERMOPHILE (55°C) ===== + { + id: 'reg-045', + name: 'Clostridium spp. (haut rendement CH₄)', + type: 'bacterie-anaerobie-thermophile', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Anaérobie strict, brassage lent, injection initiale en substrat chaud (> 45°C). Température: 40-65°C, Humidité: 70-95%. 20 à 30 cm dans la zone anaérobie active.', + dosageRequirements: { + min: 0.2, + max: 3, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-046', + name: 'Bacillus subtilis (résistance thermique)', + type: 'bacterie-sporulante-thermophile', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: true, + }, + applicationConditions: 'Injection fractionnée ou co-culture dans substrat riche, activation par température. Température: 30-65°C, Humidité: 55-90%. 10 à 30 cm dans substrat en digestion.', + dosageRequirements: { + min: 0.1, + max: 2, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-047', + name: 'Lactobacillus spp. (thermophile)', + type: 'bacterie-fermentative-lactique-thermophile', + regulatoryCharacteristics: { + phAdjustment: -1.0, + metalBinding: false, + pathogenReduction: true, + }, + applicationConditions: 'Apport initial ou en renfort après agitation, éviter pH > 7,5. Température: 30-55°C, Humidité: 60-98%. 10 à 20 cm, dans la phase humide du substrat.', + dosageRequirements: { + min: 0.2, + max: 3, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-048', + name: 'Myxococcus xanthus', + type: 'bacterie-structurante-biofilm', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Milieu homogène avec substrats fibreux, faible brassage. Température: 25-50°C, Humidité: 60-90%. 10 à 25 cm, milieu semi-liquide ou fibreux.', + dosageRequirements: { + min: 0.05, + max: 1, + unit: 'L/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-049', + name: 'H₂ (réacteur Sabatier)', + type: 'gaz-reducteur-catalytique', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Injection lente dans réacteur Sabatier ou en tête de digesteur ; catalyseur requis. Température: 40-60°C. Atmosphère gazeuse du digesteur (non immergé).', + dosageRequirements: { + min: 0.5, + max: 5, + unit: '%', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-050', + name: 'CO₂ (tampon thermochimique)', + type: 'gaz-carboné-tampon', + regulatoryCharacteristics: { + phAdjustment: -0.3, + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Diffusion douce, sans surpression. Température: 5-65°C. Phase gazeuse du digesteur ou zone de dissolution.', + dosageRequirements: { + min: 1, + max: 10, + unit: '%', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-051', + name: 'Biochar (stabilisation, filtration gaz)', + type: 'charbon-vegetal-microporeux', + regulatoryCharacteristics: { + metalBinding: true, + pathogenReduction: false, + }, + applicationConditions: 'Sec ou légèrement humide, bien réparti. Température: 0-70°C, Humidité: 10-70%. 15 à 30 cm ; intégré ou dispersé dans le digesteur.', + dosageRequirements: { + min: 10, + max: 100, + unit: 'kg/t', + }, + createdAt: new Date().toISOString(), + }, + { + id: 'reg-052', + name: 'Digesta (inoculum thermophile)', + type: 'residu-microbien-thermophile', + regulatoryCharacteristics: { + metalBinding: false, + pathogenReduction: false, + }, + applicationConditions: 'Utilisation rapide après extraction, suivi température et pH. Température: 30-65°C, Humidité: 75-98%. 10 à 25 cm, en mélange homogène avec substrat frais.', + dosageRequirements: { + min: 5, + max: 20, + unit: '%', + }, + createdAt: new Date().toISOString(), + }, +] diff --git a/src/data/seedWastes.ts b/src/data/seedWastes.ts new file mode 100644 index 0000000..55a64df --- /dev/null +++ b/src/data/seedWastes.ts @@ -0,0 +1,114 @@ +import { Waste } from '@/types' + +export const seedWastes: Waste[] = [ + { + id: 'waste-001', + name: 'Bouses de vache', + originType: 'animals', + originSubType: 'vaches', + originUnitsPer1000m3Methane: 25, + bmp: 0.16, // Nm³ CH₄/kg VS + waterPercentage: 79, + regulationNeeds: [], + maxStorageDuration: 30, + createdAt: new Date().toISOString(), + }, + { + id: 'waste-002', + name: 'Déchets verts broyés', + originType: 'other', + originSubType: 'ha espace verts', + originUnitsPer1000m3Methane: 52.6, + bmp: 0.16, + waterPercentage: 50, + regulationNeeds: [], + maxStorageDuration: 30, + createdAt: new Date().toISOString(), + }, + { + id: 'waste-003', + name: 'Déchets de STEP - Boues', + originType: 'other', + originSubType: 'équivalent habitant', + originUnitsPer1000m3Methane: 1000, + bmp: 0.16, + waterPercentage: 78, + regulationNeeds: ['pathogenElimination', 'odorElimination'], + maxStorageDuration: 21, + notes: 'STEP sludge cannot be mixed with other wastes', + createdAt: new Date().toISOString(), + }, + { + id: 'waste-004', + name: 'Déchets de STEP - Graisses', + originType: 'other', + originSubType: 'équivalent habitant', + originUnitsPer1000m3Methane: 35000, + bmp: 5.60, + waterPercentage: 45, + regulationNeeds: ['oilEmulsification', 'pathogenElimination'], + maxStorageDuration: 30, + createdAt: new Date().toISOString(), + }, + { + id: 'waste-005', + name: 'Déchets de STEP - Sables', + originType: 'other', + originSubType: 'équivalent habitant', + originUnitsPer1000m3Methane: 2500, + bmp: 0.00, + waterPercentage: 22, + regulationNeeds: [], + maxStorageDuration: 60, + notes: 'No methane production (BMP = 0)', + createdAt: new Date().toISOString(), + }, + { + id: 'waste-006', + name: 'Déchets de marchés alimentaires et restauration', + originType: 'markets', + originSubType: 'marchés alimentaires', + originUnitsPer1000m3Methane: 666.7, + bmp: 0.80, + waterPercentage: 70, + regulationNeeds: ['pathogenElimination', 'odorElimination'], + maxStorageDuration: 7, + createdAt: new Date().toISOString(), + }, + { + id: 'waste-007', + name: 'Déchets sucrés', + originType: 'other', + originSubType: 'équivalent habitant', + originUnitsPer1000m3Methane: 20000, + bmp: 1.00, + waterPercentage: 20, + regulationNeeds: [], + maxStorageDuration: 30, + createdAt: new Date().toISOString(), + }, + { + id: 'waste-008', + name: 'Huiles usagées', + originType: 'other', + originSubType: 'équivalent habitant', + originUnitsPer1000m3Methane: 50000, + bmp: 1.90, + waterPercentage: 2, + regulationNeeds: ['oilEmulsification'], + maxStorageDuration: 90, + createdAt: new Date().toISOString(), + }, + { + id: 'waste-009', + name: 'Algues invasives', + originType: 'other', + originSubType: 'km de plage infestée', + originUnitsPer1000m3Methane: 5, + bmp: 0.50, + waterPercentage: 70, + regulationNeeds: ['pathogenElimination', 'saltReduction'], + maxStorageDuration: 14, + createdAt: new Date().toISOString(), + }, +] diff --git a/src/hooks/useAuth.ts b/src/hooks/useAuth.ts new file mode 100644 index 0000000..97535d6 --- /dev/null +++ b/src/hooks/useAuth.ts @@ -0,0 +1,40 @@ +import { useState, useEffect } from 'react' +import { getUserSession, saveUserSession, clearUserSession } from '@/utils/storage' + +export function useAuth() { + const [isAuthenticated, setIsAuthenticated] = useState(false) + const [username, setUsername] = useState(null) + + useEffect(() => { + const sessionUser = getUserSession() + if (sessionUser) { + setIsAuthenticated(true) + setUsername(sessionUser) + } + }, []) + + const login = (user: string, password: string): boolean => { + // Simple authentication for localhost + // Accepts any non-empty username/password combination + if (user && user.trim() && password && password.trim()) { + saveUserSession(user.trim()) + setIsAuthenticated(true) + setUsername(user.trim()) + return true + } + return false + } + + const logout = () => { + clearUserSession() + setIsAuthenticated(false) + setUsername(null) + } + + return { + isAuthenticated, + username, + login, + logout, + } +} diff --git a/src/hooks/useStorage.ts b/src/hooks/useStorage.ts new file mode 100644 index 0000000..bc2413a --- /dev/null +++ b/src/hooks/useStorage.ts @@ -0,0 +1,74 @@ +import { useState, useEffect, useCallback } from 'react' +import { StorageData, BaseEntity } from '@/types' +import { loadStorage, saveStorage } from '@/utils/storage' + +export function useStorage() { + const [data, setData] = useState(null) + const [loading, setLoading] = useState(true) + + useEffect(() => { + const loadedData = loadStorage() + setData(loadedData) + setLoading(false) + }, []) + + const updateData = useCallback((updater: (data: StorageData) => StorageData) => { + setData((currentData) => { + if (!currentData) return currentData + const updated = updater(currentData) + saveStorage(updated) + return updated + }) + }, []) + + const addEntity = useCallback(( + collection: keyof StorageData, + entity: T + ) => { + updateData((data) => { + const collectionData = data[collection] as T[] + return { + ...data, + [collection]: [...collectionData, entity], + } + }) + }, [updateData]) + + const updateEntity = useCallback(( + collection: keyof StorageData, + id: string, + updates: Partial + ) => { + updateData((data) => { + const collectionData = data[collection] as T[] + return { + ...data, + [collection]: collectionData.map((item) => + item.id === id ? { ...item, ...updates, updatedAt: new Date().toISOString() } : item + ), + } + }) + }, [updateData]) + + const deleteEntity = useCallback(( + collection: keyof StorageData, + id: string + ) => { + updateData((data) => { + const collectionData = data[collection] as BaseEntity[] + return { + ...data, + [collection]: collectionData.filter((item) => item.id !== id), + } + }) + }, [updateData]) + + return { + data, + loading, + updateData, + addEntity, + updateEntity, + deleteEntity, + } +} diff --git a/src/index.css b/src/index.css new file mode 100644 index 0000000..35a369b --- /dev/null +++ b/src/index.css @@ -0,0 +1,90 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +:root { + /* Primary Colors */ + --primary-green: #2D7A4F; + --primary-green-light: #4A9D6E; + --primary-green-dark: #1F5A3A; + --primary-green-accent: #6BC48A; + + /* Secondary Colors */ + --secondary-blue: #2563EB; + --secondary-blue-light: #3B82F6; + --secondary-blue-dark: #1E40AF; + + /* Neutral Colors (Dark Mode) */ + --background: #1A1A1A; + --background-secondary: #2D2D2D; + --background-tertiary: #404040; + --text-primary: #FFFFFF; + --text-secondary: #B0B0B0; + --text-tertiary: #808080; + --border: #404040; + --border-focus: #4A9D6E; + + /* Status Colors */ + --success: #10B981; + --warning: #F59E0B; + --error: #EF4444; + --info: #3B82F6; + --pending: #F59E0B; + --completed: #10B981; + --to-do: #6C757D; + + /* Status Workflow Colors */ + --to-be-approached: #F59E0B; + --loi-ok: #3B82F6; + --in-progress: #8B5CF6; + --completed: #10B981; + --na: #9CA3AF; + + /* Spacing */ + --spacing-xs: 4px; + --spacing-sm: 8px; + --spacing-md: 16px; + --spacing-lg: 24px; + --spacing-xl: 32px; + --spacing-2xl: 48px; + --spacing-3xl: 64px; + --spacing-4xl: 96px; + + /* Typography */ + --font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; + --font-mono: 'JetBrains Mono', 'Fira Code', 'Courier New', monospace; +} + +body { + font-family: var(--font-family); + background-color: var(--background); + color: var(--text-primary); + line-height: 1.5; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +#root { + min-height: 100vh; +} + +/* Scrollbar styling */ +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +::-webkit-scrollbar-track { + background: var(--background-secondary); +} + +::-webkit-scrollbar-thumb { + background: var(--background-tertiary); + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: var(--border); +} diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..c506ac4 --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,27 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import { BrowserRouter } from 'react-router-dom' +import { AuthProvider } from './contexts/AuthContext' +import App from './App' +import './index.css' + +// Check if running on localhost +if (window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1') { + ReactDOM.createRoot(document.getElementById('root')!).render( +
+

Access Restricted

+

This application can only be accessed from localhost.

+

Current hostname: {window.location.hostname}

+
+ ) +} else { + ReactDOM.createRoot(document.getElementById('root')!).render( + + + + + + + + ) +} diff --git a/src/pages/BusinessPlanPage.css b/src/pages/BusinessPlanPage.css new file mode 100644 index 0000000..a404a56 --- /dev/null +++ b/src/pages/BusinessPlanPage.css @@ -0,0 +1,204 @@ +.business-plan-page { + max-width: 1400px; + margin: 0 auto; +} + +.selector-card { + margin-bottom: var(--spacing-xl); + max-width: 500px; +} + +.empty-message { + text-align: center; + color: var(--text-secondary); + padding: var(--spacing-xl); +} + +.business-plan-content { + display: flex; + flex-direction: column; + gap: var(--spacing-xl); +} + +.header-card { + max-width: 1000px; +} + +.header-info { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: var(--spacing-lg); +} + +.info-item { + display: flex; + flex-direction: column; + gap: var(--spacing-xs); +} + +.info-label { + font-size: 0.875rem; + color: var(--text-secondary); + font-weight: 500; +} + +.info-value { + font-size: 1rem; + color: var(--text-primary); +} + +.valorizations-card { + max-width: 1200px; +} + +.valorizations-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: var(--spacing-lg); +} + +.valorization-item { + padding: var(--spacing-lg); + background-color: var(--background); + border-radius: 8px; + border: 1px solid var(--border); +} + +.valorization-label { + font-size: 0.875rem; + font-weight: 600; + color: var(--text-secondary); + margin-bottom: var(--spacing-sm); +} + +.valorization-value { + font-size: 1.5rem; + font-weight: 700; + color: var(--primary-green); + margin-bottom: var(--spacing-md); +} + +.economic-card { + max-width: 1400px; +} + +.financial-table-container { + overflow-x: auto; + margin-bottom: var(--spacing-xl); +} + +.financial-table { + width: 100%; + border-collapse: collapse; + min-width: 800px; +} + +.financial-table th { + background-color: var(--background-secondary); + padding: 12px 16px; + text-align: left; + font-weight: 600; + color: var(--text-primary); + font-size: 0.875rem; + border-bottom: 1px solid var(--border); +} + +.financial-table td { + padding: 12px 16px; + color: var(--text-primary); + font-size: 0.875rem; + border-bottom: 1px solid var(--border); +} + +.financial-table tr:hover { + background-color: var(--background-secondary); +} + +.year-cell { + font-weight: 600; +} + +.highlight-cell { + color: var(--primary-green); + font-weight: 600; +} + +.formula-section { + margin-top: var(--spacing-xl); + padding: var(--spacing-lg); + background-color: var(--background); + border-radius: 8px; + border: 1px solid var(--border); +} + +.formula-section-title { + font-size: 1.125rem; + font-weight: 600; + color: var(--text-primary); + margin-bottom: var(--spacing-lg); +} + +.formula-display { + margin-top: var(--spacing-md); + padding: var(--spacing-md); + background-color: var(--background-secondary); + border: 1px solid var(--border); + border-radius: 8px; +} + +.formula-label { + font-size: 0.75rem; + font-weight: 500; + color: var(--text-secondary); + margin-bottom: var(--spacing-xs); +} + +.formula-content { + font-family: var(--font-mono); + font-size: 0.875rem; + color: var(--text-primary); + white-space: pre-wrap; + line-height: 1.6; +} + +.revenues-card, +.costs-card { + max-width: 1400px; +} + +.section-description { + color: var(--text-secondary); + margin-bottom: var(--spacing-lg); + font-size: 0.875rem; +} + +.revenues-grid, +.costs-grid { + display: flex; + flex-direction: column; + gap: var(--spacing-xl); +} + +.revenue-item, +.cost-item { + padding: var(--spacing-lg); + background-color: var(--background); + border-radius: 8px; + border: 1px solid var(--border); +} + +.revenue-label, +.cost-label { + display: block; + font-size: 0.875rem; + font-weight: 600; + color: var(--text-primary); + margin-bottom: var(--spacing-md); +} + +.revenue-years, +.cost-years { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); + gap: var(--spacing-md); +} diff --git a/src/pages/BusinessPlanPage.tsx b/src/pages/BusinessPlanPage.tsx new file mode 100644 index 0000000..aa1f10e --- /dev/null +++ b/src/pages/BusinessPlanPage.tsx @@ -0,0 +1,463 @@ +import { useState, useEffect } from 'react' +import { useSearchParams } from 'react-router-dom' +import { useStorage } from '@/hooks/useStorage' +import { Project, BusinessPlan } from '@/types' +import { calculateYields } from '@/utils/calculations/yields' +import { VALORIZATION_PARAMS, BITCOIN_CONFIG, MODULE_CONFIG } from '@/utils/constants' +import Card from '@/components/base/Card' +import Button from '@/components/base/Button' +import Input from '@/components/base/Input' +import Select from '@/components/base/Select' +import Table from '@/components/base/Table' +import { formatCurrency, formatNumber, formatDate } from '@/utils/formatters' +import './BusinessPlanPage.css' + +export default function BusinessPlanPage() { + const [searchParams] = useSearchParams() + const projectIdFromUrl = searchParams.get('project') + const { data, updateEntity } = useStorage() + const [selectedProjectId, setSelectedProjectId] = useState(projectIdFromUrl || '') + + const projects = data?.projects || [] + const wastes = data?.wastes || [] + const treatmentSites = data?.treatmentSites || [] + const services = data?.services || [] + + const selectedProject = projects.find((p) => p.id === selectedProjectId) + const selectedWaste = selectedProject?.wasteCharacteristicsOverride?.wasteId + ? wastes.find((w) => w.id === selectedProject.wasteCharacteristicsOverride?.wasteId) + : undefined + const selectedTreatmentSite = selectedProject + ? treatmentSites.find((s) => s.id === selectedProject.treatmentSiteId) + : undefined + + const yields = selectedProject && selectedWaste && selectedTreatmentSite + ? calculateYields(selectedProject, selectedWaste, selectedTreatmentSite) + : null + + useEffect(() => { + if (projectIdFromUrl && !selectedProjectId) { + setSelectedProjectId(projectIdFromUrl) + } + }, [projectIdFromUrl]) + + const projectOptions = projects.map((project) => ({ + value: project.id, + label: project.name, + })) + + const initializeBusinessPlan = (): BusinessPlan => { + const years = Array(10).fill(0) + return { + revenues: { + rawRental: years, + biologicalTreatment: years, + bitcoinManagement: years, + fertilizers: years, + wasteHeat: years, + carbonCredits: years, + brownfield: years, + transport: years, + commercialPartnerships: years, + other: years, + }, + variableCosts: { + rentalServices: years, + commissions: years, + otherVariable: years, + transport: years, + }, + fixedCosts: { + salaries: years, + marketing: years, + rd: years, + administrative: years, + otherGeneral: years, + }, + investments: { + equipment: years, + technology: years, + patents: years, + }, + useOfFunds: { + productDevelopment: years, + marketing: years, + team: years, + structure: years, + }, + kpis: { + activeUsers: years, + cac: years, + ltv: years, + breakEvenDays: years, + }, + } + } + + const businessPlan = selectedProject?.businessPlan || initializeBusinessPlan() + + const updateBusinessPlanValue = ( + category: keyof BusinessPlan, + subCategory: string, + yearIndex: number, + value: number + ) => { + if (!selectedProject) return + + const updated = { ...businessPlan } + const categoryData = updated[category] as any + categoryData[subCategory] = [...categoryData[subCategory]] + categoryData[subCategory][yearIndex] = value + + updateEntity('projects', selectedProject.id, { + ...selectedProject, + businessPlan: updated, + }) + } + + const calculateTotalRevenues = (yearIndex: number): number => { + return ( + businessPlan.revenues.rawRental[yearIndex] + + businessPlan.revenues.biologicalTreatment[yearIndex] + + businessPlan.revenues.bitcoinManagement[yearIndex] + + businessPlan.revenues.fertilizers[yearIndex] + + businessPlan.revenues.wasteHeat[yearIndex] + + businessPlan.revenues.carbonCredits[yearIndex] + + businessPlan.revenues.brownfield[yearIndex] + + businessPlan.revenues.transport[yearIndex] + + businessPlan.revenues.commercialPartnerships[yearIndex] + + businessPlan.revenues.other[yearIndex] + ) + } + + const calculateTotalVariableCosts = (yearIndex: number): number => { + return ( + businessPlan.variableCosts.rentalServices[yearIndex] + + businessPlan.variableCosts.commissions[yearIndex] + + businessPlan.variableCosts.otherVariable[yearIndex] + + businessPlan.variableCosts.transport[yearIndex] + ) + } + + const calculateGrossMargin = (yearIndex: number): number => { + return calculateTotalRevenues(yearIndex) - calculateTotalVariableCosts(yearIndex) + } + + const calculateTotalFixedCosts = (yearIndex: number): number => { + return ( + businessPlan.fixedCosts.salaries[yearIndex] + + businessPlan.fixedCosts.marketing[yearIndex] + + businessPlan.fixedCosts.rd[yearIndex] + + businessPlan.fixedCosts.administrative[yearIndex] + + businessPlan.fixedCosts.otherGeneral[yearIndex] + ) + } + + const calculateEBITDA = (yearIndex: number): number => { + return calculateGrossMargin(yearIndex) - calculateTotalFixedCosts(yearIndex) + } + + const calculateTotalInvestments = (yearIndex: number): number => { + return ( + businessPlan.investments.equipment[yearIndex] + + businessPlan.investments.technology[yearIndex] + + businessPlan.investments.patents[yearIndex] + ) + } + + const calculateValorizations = () => { + if (!yields || !selectedProject) return null + + const daysPerYear = 365 + const wasteQuantityPerYear = (MODULE_CONFIG.CAPACITY_PER_MODULE * selectedProject.numberOfModules * daysPerYear) / 1000 // kT/year + + return { + wasteTreatment: wasteQuantityPerYear * VALORIZATION_PARAMS.WASTE_TREATMENT_PER_TONNE, + fertilizer: (yields.fertilizer * daysPerYear) * VALORIZATION_PARAMS.FERTILIZER_PER_TONNE, + heat: (yields.heatEnergyKWh * daysPerYear) * VALORIZATION_PARAMS.HEAT_PER_TONNE, + ch4Carbon: (yields.methane * daysPerYear * 0.717 / 1000) * VALORIZATION_PARAMS.CARBON_CH4_BURNED_PER_TCO2E, // Convert m³ to t, then to tCO₂e + co2Carbon: (yields.co2 * daysPerYear * 1.98 / 1000) * VALORIZATION_PARAMS.CARBON_CO2_SEQUESTERED_PER_TCO2E, // Convert m³ to t, then to tCO₂e + energyCarbon: (yields.netElectricalPower * daysPerYear * 24) * VALORIZATION_PARAMS.CARBON_ELECTRICITY_AVOIDED_PER_KW, + bitcoin: yields.bitcoinsPerYear * BITCOIN_CONFIG.BITCOIN_PRICE_EUR, + land: VALORIZATION_PARAMS.BROWNFIELD_AREA * VALORIZATION_PARAMS.BROWNFIELD_VALORIZATION_RATE, + } + } + + const valorizations = calculateValorizations() + + const FormulaDisplay = ({ formula, description }: { formula: string; description: string }) => ( +
+
{description}
+
{formula}
+
+ ) + + return ( +
+

Business Plan

+ + + + updateBusinessPlanValue('revenues', key, yearIndex, parseFloat(e.target.value) || 0) + } + style={{ width: '120px' }} + /> + ))} +
+ + ))} + + + + +
+ {Object.entries(businessPlan.variableCosts).map(([key, values]) => ( +
+ +
+ {values.map((value, yearIndex) => ( + + updateBusinessPlanValue('variableCosts', key, yearIndex, parseFloat(e.target.value) || 0) + } + style={{ width: '120px' }} + /> + ))} +
+
+ ))} +
+
+ + +
+ {Object.entries(businessPlan.fixedCosts).map(([key, values]) => ( +
+ +
+ {values.map((value, yearIndex) => ( + + updateBusinessPlanValue('fixedCosts', key, yearIndex, parseFloat(e.target.value) || 0) + } + style={{ width: '120px' }} + /> + ))} +
+
+ ))} +
+
+ + )} + + ) +} diff --git a/src/pages/DashboardPage.css b/src/pages/DashboardPage.css new file mode 100644 index 0000000..5682ca2 --- /dev/null +++ b/src/pages/DashboardPage.css @@ -0,0 +1,117 @@ +.dashboard { + max-width: 1280px; + margin: 0 auto; +} + +.dashboard-title { + font-size: 2.5rem; + font-weight: 700; + color: var(--text-primary); + margin-bottom: var(--spacing-2xl); +} + +.dashboard-loading { + text-align: center; + padding: var(--spacing-4xl); + color: var(--text-secondary); +} + +.dashboard-metrics { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: var(--spacing-lg); + margin-bottom: var(--spacing-2xl); +} + +.dashboard-metric-card { + background-color: var(--background-secondary); + border: 1px solid var(--border); + border-radius: 12px; + padding: var(--spacing-lg); +} + +.dashboard-metric-value { + font-size: 2rem; + font-weight: 700; + color: var(--primary-green); + margin-bottom: var(--spacing-xs); +} + +.dashboard-metric-label { + font-size: 0.875rem; + color: var(--text-secondary); +} + +.dashboard-section { + margin-bottom: var(--spacing-2xl); +} + +.dashboard-section-title { + font-size: 1.5rem; + font-weight: 600; + color: var(--text-primary); + margin-bottom: var(--spacing-lg); +} + +.dashboard-empty { + background-color: var(--background-secondary); + border: 1px solid var(--border); + border-radius: 12px; + padding: var(--spacing-2xl); + text-align: center; + color: var(--text-secondary); +} + +.dashboard-projects { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: var(--spacing-lg); +} + +.dashboard-project-card { + background-color: var(--background-secondary); + border: 1px solid var(--border); + border-radius: 12px; + padding: var(--spacing-lg); + transition: border-color 200ms ease-in-out; +} + +.dashboard-project-card:hover { + border-color: var(--border-focus); +} + +.dashboard-project-name { + font-size: 1.25rem; + font-weight: 600; + color: var(--text-primary); + margin-bottom: var(--spacing-xs); +} + +.dashboard-project-info { + font-size: 0.875rem; + color: var(--text-secondary); +} + +.dashboard-actions { + display: flex; + flex-wrap: wrap; + gap: var(--spacing-md); +} + +.dashboard-action-button { + background-color: var(--primary-green); + color: var(--text-primary); + border: none; + border-radius: 8px; + padding: var(--spacing-sm) var(--spacing-lg); + font-size: 0.875rem; + font-weight: 500; + text-decoration: none; + cursor: pointer; + transition: background-color 200ms ease-in-out; + display: inline-block; +} + +.dashboard-action-button:hover { + background-color: var(--primary-green-light); +} diff --git a/src/pages/DashboardPage.tsx b/src/pages/DashboardPage.tsx new file mode 100644 index 0000000..7f08744 --- /dev/null +++ b/src/pages/DashboardPage.tsx @@ -0,0 +1,80 @@ +import { useStorage } from '@/hooks/useStorage' +import './DashboardPage.css' + +export default function DashboardPage() { + const { data, loading } = useStorage() + + if (loading) { + return
Loading...
+ } + + const projects = data?.projects || [] + const wastes = data?.wastes || [] + const services = data?.services || [] + const treatmentSites = data?.treatmentSites || [] + + return ( +
+

Dashboard

+ +
+
+
{projects.length}
+
Active Projects
+
+
+
+ {projects.reduce((sum, p) => sum + p.numberOfModules, 0)} +
+
Total Modules
+
+
+
{wastes.length}
+
Waste Types
+
+
+
{treatmentSites.length}
+
Treatment Sites
+
+
+ +
+

Recent Projects

+ {projects.length === 0 ? ( +
+

No projects yet. Create your first project to get started.

+
+ ) : ( +
+ {projects.slice(0, 5).map((project) => ( +
+

{project.name}

+

+ {project.numberOfModules} modules • {treatmentSites.find(s => s.id === project.treatmentSiteId)?.name || 'Unknown site'} +

+
+ ))} +
+ )} +
+ + +
+ ) +} diff --git a/src/pages/HelpPage.css b/src/pages/HelpPage.css new file mode 100644 index 0000000..b0017cf --- /dev/null +++ b/src/pages/HelpPage.css @@ -0,0 +1,57 @@ +.help-page { + max-width: 1280px; + margin: 0 auto; +} + +.help-content { + display: flex; + flex-direction: column; + gap: var(--spacing-xl); +} + +.help-section { + max-width: 1000px; +} + +.help-section h3 { + font-size: 1.25rem; + font-weight: 600; + color: var(--text-primary); + margin-top: var(--spacing-lg); + margin-bottom: var(--spacing-md); +} + +.help-section h3:first-child { + margin-top: 0; +} + +.help-section ol, +.help-section ul { + margin-left: var(--spacing-xl); + margin-bottom: var(--spacing-lg); + color: var(--text-primary); +} + +.help-section li { + margin-bottom: var(--spacing-sm); + line-height: 1.6; +} + +.help-section p { + margin-bottom: var(--spacing-md); + line-height: 1.6; + color: var(--text-primary); +} + +.help-section code { + font-family: var(--font-mono); + background-color: var(--background); + padding: 2px 6px; + border-radius: 4px; + color: var(--primary-green); +} + +.warning { + color: var(--warning); + font-weight: 500; +} diff --git a/src/pages/HelpPage.tsx b/src/pages/HelpPage.tsx new file mode 100644 index 0000000..3730eef --- /dev/null +++ b/src/pages/HelpPage.tsx @@ -0,0 +1,56 @@ +import Card from '@/components/base/Card' +import './HelpPage.css' + +export default function HelpPage() { + return ( +
+

Help & Documentation

+ +
+ +

Getting Started

+
    +
  1. Configure waste types in Configuration → Waste
  2. +
  3. Configure natural regulators in Configuration → Regulators
  4. +
  5. Configure services pricing in Configuration → Services
  6. +
  7. Create treatment sites in Projects → Treatment Sites
  8. +
  9. Create waste sites in Projects → Waste Sites
  10. +
  11. Create a project in Projects → Projects
  12. +
  13. View yields in Yields page
  14. +
  15. Configure business plan in Business Plan page
  16. +
+
+ + +

+ All calculation formulas are displayed on the Yields and Business Plan pages. + Formulas use monospace font and show the complete calculation method. +

+

+ For detailed formula documentation, see formulas_reference.md +

+
+ + +

Export Data

+

Go to Settings → Export Data to download all your data as JSON.

+ +

Import Data

+

Go to Settings → Import Data to replace all data with imported JSON file.

+

Warning: Importing will replace all existing data!

+
+ + +

How do I calculate yields?

+

Yields are automatically calculated when you select a project. Make sure the project has a configured waste type and treatment site.

+ +

How do I configure service pricing?

+

Go to Configuration → Services and set pricing for each year (1-10). Pricing is per module per year.

+ +

Can I override waste characteristics per project?

+

Yes, in the Project Configuration page, you can override BMP and water percentage for that specific project.

+
+
+
+ ) +} diff --git a/src/pages/LoginPage.css b/src/pages/LoginPage.css new file mode 100644 index 0000000..b1ba3d3 --- /dev/null +++ b/src/pages/LoginPage.css @@ -0,0 +1,107 @@ +.login-page { + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + background-color: var(--background); + padding: var(--spacing-xl); +} + +.login-container { + width: 100%; + max-width: 400px; + background-color: var(--background-secondary); + border: 1px solid var(--border); + border-radius: 12px; + padding: var(--spacing-2xl); +} + +.login-title { + font-size: 2rem; + font-weight: 700; + color: var(--text-primary); + text-align: center; + margin-bottom: var(--spacing-xs); +} + +.login-subtitle { + font-size: 1rem; + color: var(--text-secondary); + text-align: center; + margin-bottom: var(--spacing-2xl); +} + +.login-form { + display: flex; + flex-direction: column; + gap: var(--spacing-lg); +} + +.login-form-group { + display: flex; + flex-direction: column; + gap: var(--spacing-sm); +} + +.login-label { + font-size: 0.875rem; + font-weight: 500; + color: var(--text-primary); +} + +.login-input { + height: 44px; + padding: var(--spacing-sm) var(--spacing-md); + background-color: var(--background-secondary); + border: 1px solid var(--border); + border-radius: 8px; + color: var(--text-primary); + font-size: 1rem; + transition: border-color 200ms ease-in-out; +} + +.login-input:focus { + outline: none; + border-color: var(--border-focus); + border-width: 2px; +} + +.login-input::placeholder { + color: var(--text-tertiary); +} + +.login-error { + padding: var(--spacing-sm) var(--spacing-md); + background-color: rgba(239, 68, 68, 0.1); + border: 1px solid var(--error); + border-radius: 8px; + color: var(--error); + font-size: 0.875rem; +} + +.login-button { + height: 44px; + background-color: var(--primary-green); + color: var(--text-primary); + border: none; + border-radius: 8px; + font-size: 1rem; + font-weight: 500; + cursor: pointer; + transition: background-color 200ms ease-in-out; +} + +.login-button:hover { + background-color: var(--primary-green-light); +} + +.login-button:active { + background-color: var(--primary-green-dark); +} + +.login-note { + margin-top: var(--spacing-xl); + font-size: 0.75rem; + color: var(--text-tertiary); + text-align: center; +} diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx new file mode 100644 index 0000000..7fc8dd6 --- /dev/null +++ b/src/pages/LoginPage.tsx @@ -0,0 +1,85 @@ +import { useState } from 'react' +import { useNavigate } from 'react-router-dom' +import { useAuth } from '@/contexts/AuthContext' +import './LoginPage.css' + +export default function LoginPage() { + const [username, setUsername] = useState('') + const [password, setPassword] = useState('') + const [error, setError] = useState('') + const { login } = useAuth() + const navigate = useNavigate() + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault() + setError('') + + const trimmedUsername = username.trim() + const trimmedPassword = password.trim() + + if (!trimmedUsername || !trimmedPassword) { + setError('Please enter username and password') + return + } + + const success = login(trimmedUsername, trimmedPassword) + if (success) { + navigate('/', { replace: true }) + } else { + setError('Invalid credentials') + } + } + + return ( +
+
+

4NK Waste & Water

+

Simulator

+ +
+
+ + setUsername(e.target.value)} + className="login-input" + placeholder="Enter username" + autoFocus + /> +
+ +
+ + setPassword(e.target.value)} + className="login-input" + placeholder="Enter password" + /> +
+ + {error &&
{error}
} + + +
+ +

+ This application is only accessible from localhost +

+

+ Default: admin / admin (or any username/password) +

+
+
+ ) +} diff --git a/src/pages/SettingsPage.css b/src/pages/SettingsPage.css new file mode 100644 index 0000000..64cc437 --- /dev/null +++ b/src/pages/SettingsPage.css @@ -0,0 +1,95 @@ +.settings { + max-width: 1280px; + margin: 0 auto; +} + +.settings-title { + font-size: 2.5rem; + font-weight: 700; + color: var(--text-primary); + margin-bottom: var(--spacing-2xl); +} + +.settings-section { + margin-bottom: var(--spacing-2xl); +} + +.settings-section-title { + font-size: 1.5rem; + font-weight: 600; + color: var(--text-primary); + margin-bottom: var(--spacing-lg); +} + +.settings-card { + background-color: var(--background-secondary); + border: 1px solid var(--border); + border-radius: 12px; + padding: var(--spacing-lg); + margin-bottom: var(--spacing-lg); +} + +.settings-card-title { + font-size: 1.25rem; + font-weight: 600; + color: var(--text-primary); + margin-bottom: var(--spacing-sm); +} + +.settings-card-description { + font-size: 0.875rem; + color: var(--text-secondary); + margin-bottom: var(--spacing-lg); +} + +.settings-button { + background-color: var(--primary-green); + color: var(--text-primary); + border: none; + border-radius: 8px; + padding: var(--spacing-sm) var(--spacing-lg); + font-size: 0.875rem; + font-weight: 500; + cursor: pointer; + transition: background-color 200ms ease-in-out; +} + +.settings-button:hover { + background-color: var(--primary-green-light); +} + +.settings-button-danger { + background-color: var(--error); +} + +.settings-button-danger:hover { + background-color: #DC2626; +} + +.settings-info { + display: flex; + flex-direction: column; + gap: var(--spacing-md); +} + +.settings-info-item { + display: flex; + justify-content: space-between; + padding: var(--spacing-sm) 0; + border-bottom: 1px solid var(--border); +} + +.settings-info-item:last-child { + border-bottom: none; +} + +.settings-info-label { + font-size: 0.875rem; + color: var(--text-secondary); + font-weight: 500; +} + +.settings-info-value { + font-size: 0.875rem; + color: var(--text-primary); +} diff --git a/src/pages/SettingsPage.tsx b/src/pages/SettingsPage.tsx new file mode 100644 index 0000000..400a1a0 --- /dev/null +++ b/src/pages/SettingsPage.tsx @@ -0,0 +1,165 @@ +import { useStorage } from '@/hooks/useStorage' +import { exportData, importData, saveStorage } from '@/utils/storage' +import { loadSeedData, addSeedDataToExisting } from '@/utils/seedData' +import { useRef } from 'react' +import './SettingsPage.css' + +export default function SettingsPage() { + const { data } = useStorage() + const fileInputRef = useRef(null) + + const handleExport = () => { + const json = exportData() + const blob = new Blob([json], { type: 'application/json' }) + const url = URL.createObjectURL(blob) + const a = document.createElement('a') + a.href = url + a.download = `4nkwaste-simulator-${new Date().toISOString().split('T')[0]}.json` + document.body.appendChild(a) + a.click() + document.body.removeChild(a) + URL.revokeObjectURL(url) + } + + const handleImport = () => { + fileInputRef.current?.click() + } + + const handleFileChange = (e: React.ChangeEvent) => { + const file = e.target.files?.[0] + if (!file) return + + const reader = new FileReader() + reader.onload = (event) => { + const content = event.target?.result as string + const result = importData(content) + + if (result.success) { + alert('Data imported successfully!') + window.location.reload() + } else { + alert(`Import failed:\n${result.errors.join('\n')}`) + } + } + reader.readAsText(file) + } + + return ( +
+

Settings

+ +
+

Data Management

+ +
+

Export Data

+

+ Export all your data as a JSON file for backup or transfer. +

+ +
+ +
+

Import Data

+

+ Import data from a JSON file. This will replace all existing data. +

+ + +
+
+ +
+

Seed Data

+ +
+

Load Seed Data

+

+ Load example waste types and regulators to get started. This will add seed data to your existing data. +

+ +
+ +
+

Reset to Seed Data

+

+ Replace all data with seed data. This will delete all your current data! +

+ +
+
+ +
+

Data Information

+
+
+
+ Version: + {data?.version || 'N/A'} +
+
+ Last Modified: + + {data?.lastModified ? new Date(data.lastModified).toLocaleString() : 'N/A'} + +
+
+ Projects: + {data?.projects.length || 0} +
+
+ Waste Types: + {data?.wastes.length || 0} +
+
+ Regulators: + {data?.regulators.length || 0} +
+
+ Treatment Sites: + {data?.treatmentSites.length || 0} +
+
+ Waste Sites: + {data?.wasteSites.length || 0} +
+
+
+
+
+ ) +} diff --git a/src/pages/YieldsPage.css b/src/pages/YieldsPage.css new file mode 100644 index 0000000..87f2f3d --- /dev/null +++ b/src/pages/YieldsPage.css @@ -0,0 +1,84 @@ +.yields-page { + max-width: 1280px; + margin: 0 auto; +} + +.selector-card { + margin-bottom: var(--spacing-xl); + max-width: 500px; +} + +.empty-message, +.error-message { + text-align: center; + color: var(--text-secondary); + padding: var(--spacing-xl); +} + +.error-message { + color: var(--error); +} + +.yields-content { + display: flex; + flex-direction: column; + gap: var(--spacing-xl); +} + +.yields-card { + max-width: 1000px; +} + +.yield-item { + margin-bottom: var(--spacing-xl); + padding-bottom: var(--spacing-lg); + border-bottom: 1px solid var(--border); +} + +.yield-item:last-child { + border-bottom: none; + margin-bottom: 0; +} + +.yield-label { + font-size: 1rem; + font-weight: 600; + color: var(--text-primary); + margin-bottom: var(--spacing-sm); +} + +.yield-value { + font-size: 1.5rem; + font-weight: 700; + color: var(--primary-green); + margin-bottom: var(--spacing-xs); +} + +.yield-value-secondary { + font-size: 1rem; + color: var(--text-secondary); + margin-bottom: var(--spacing-md); +} + +.formula-display { + margin-top: var(--spacing-md); + padding: var(--spacing-md); + background-color: var(--background); + border: 1px solid var(--border); + border-radius: 8px; +} + +.formula-label { + font-size: 0.75rem; + font-weight: 500; + color: var(--text-secondary); + margin-bottom: var(--spacing-xs); +} + +.formula-content { + font-family: var(--font-mono); + font-size: 0.875rem; + color: var(--text-primary); + white-space: pre-wrap; + line-height: 1.6; +} diff --git a/src/pages/YieldsPage.tsx b/src/pages/YieldsPage.tsx new file mode 100644 index 0000000..e0bfa14 --- /dev/null +++ b/src/pages/YieldsPage.tsx @@ -0,0 +1,188 @@ +import { useState } from 'react' +import { useStorage } from '@/hooks/useStorage' +import { Project } from '@/types' +import { calculateYields, YieldsResult } from '@/utils/calculations/yields' +import Card from '@/components/base/Card' +import Select from '@/components/base/Select' +import { formatNumber } from '@/utils/formatters' +import './YieldsPage.css' + +export default function YieldsPage() { + const { data } = useStorage() + const [selectedProjectId, setSelectedProjectId] = useState('') + + const projects = data?.projects || [] + const wastes = data?.wastes || [] + const treatmentSites = data?.treatmentSites || [] + + const selectedProject = projects.find((p) => p.id === selectedProjectId) + const selectedWaste = selectedProject?.wasteCharacteristicsOverride?.wasteId + ? wastes.find((w) => w.id === selectedProject.wasteCharacteristicsOverride?.wasteId) + : undefined + const selectedTreatmentSite = selectedProject + ? treatmentSites.find((s) => s.id === selectedProject.treatmentSiteId) + : undefined + + const yields: YieldsResult | null = selectedProject && selectedWaste && selectedTreatmentSite + ? calculateYields(selectedProject, selectedWaste, selectedTreatmentSite) + : null + + const projectOptions = projects.map((project) => ({ + value: project.id, + label: project.name, + })) + + const FormulaDisplay = ({ formula, description }: { formula: string; description: string }) => ( +
+
{description}
+
{formula}
+
+ ) + + return ( +
+

Yields

+ + + setFormData({ ...formData, name: e.target.value })} + error={errors.name} + /> + setFormData({ ...formData, type: e.target.value })} + error={errors.type} + /> +
+ + setFormData({ ...formData, applicationConditions: e.target.value })} + error={errors.applicationConditions} + /> + +
+ + setFormData({ + ...formData, + dosageRequirements: { + ...formData.dosageRequirements!, + min: parseFloat(e.target.value) || 0, + }, + }) + } + error={errors.dosageMin} + /> + + setFormData({ + ...formData, + dosageRequirements: { + ...formData.dosageRequirements!, + max: parseFloat(e.target.value) || 0, + }, + }) + } + error={errors.dosageMax} + /> +
+ +
+ + {editingId && ( + + )} +
+ + + + + + + + + ) +} diff --git a/src/pages/configuration/ServicesConfigurationPage.css b/src/pages/configuration/ServicesConfigurationPage.css new file mode 100644 index 0000000..7c25d2b --- /dev/null +++ b/src/pages/configuration/ServicesConfigurationPage.css @@ -0,0 +1,56 @@ +.services-config-page { + max-width: 1280px; + margin: 0 auto; +} + +.page-content { + display: flex; + flex-direction: column; + gap: var(--spacing-xl); +} + +.form-card { + max-width: 1000px; +} + +.form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: var(--spacing-lg); +} + +.pricing-section { + margin: var(--spacing-xl) 0; + padding: var(--spacing-lg); + background-color: var(--background); + border-radius: 8px; + border: 1px solid var(--border); +} + +.pricing-title { + font-size: 1.125rem; + font-weight: 600; + color: var(--text-primary); + margin-bottom: var(--spacing-lg); +} + +.pricing-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); + gap: var(--spacing-md); +} + +.form-actions { + display: flex; + gap: var(--spacing-md); + margin-top: var(--spacing-lg); +} + +.table-card { + margin-top: var(--spacing-xl); +} + +.table-actions { + display: flex; + gap: var(--spacing-sm); +} diff --git a/src/pages/configuration/ServicesConfigurationPage.tsx b/src/pages/configuration/ServicesConfigurationPage.tsx new file mode 100644 index 0000000..0db4887 --- /dev/null +++ b/src/pages/configuration/ServicesConfigurationPage.tsx @@ -0,0 +1,213 @@ +import { useState } from 'react' +import { useStorage } from '@/hooks/useStorage' +import { Service, ServiceType } from '@/types' +import Card from '@/components/base/Card' +import Button from '@/components/base/Button' +import Input from '@/components/base/Input' +import Select from '@/components/base/Select' +import Table from '@/components/base/Table' +import { formatCurrency } from '@/utils/formatters' +import { validateRequired, validateNumber } from '@/utils/validators' +import './ServicesConfigurationPage.css' + +export default function ServicesConfigurationPage() { + const { data, addEntity, updateEntity, deleteEntity } = useStorage() + const [editingId, setEditingId] = useState(null) + const [formData, setFormData] = useState>({ + name: '', + type: 'rawRental', + pricing: { + year1: 0, + year2: 0, + year3: 0, + year4: 0, + year5: 0, + year6: 0, + year7: 0, + year8: 0, + year9: 0, + year10: 0, + }, + }) + const [errors, setErrors] = useState>({}) + + const services = data?.services || [] + + const serviceTypeOptions: { value: ServiceType; label: string }[] = [ + { value: 'rawRental', label: 'Raw Rental' }, + { value: 'biologicalTreatment', label: 'Biological Waste Treatment' }, + { value: 'bitcoinManagement', label: 'Bitcoin Management' }, + { value: 'fertilizers', label: 'Provision of Standardized Fertilizers' }, + { value: 'wasteHeat', label: 'Provision of Waste Heat' }, + { value: 'carbonCredits', label: 'Provision of Carbon Credit Indices' }, + { value: 'brownfield', label: 'Brownfield Redevelopment' }, + { value: 'transport', label: 'Transport' }, + ] + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault() + + const newErrors: Record = {} + newErrors.name = validateRequired(formData.name) + + setErrors(newErrors) + + if (Object.values(newErrors).some((error) => error !== undefined)) { + return + } + + const service: Service = { + id: editingId || crypto.randomUUID(), + name: formData.name!, + type: formData.type!, + pricing: formData.pricing!, + createdAt: editingId ? services.find((s) => s.id === editingId)?.createdAt || new Date().toISOString() : new Date().toISOString(), + updatedAt: new Date().toISOString(), + } + + if (editingId) { + updateEntity('services', editingId, service) + } else { + addEntity('services', service) + } + + resetForm() + } + + const resetForm = () => { + setFormData({ + name: '', + type: 'rawRental', + pricing: { + year1: 0, + year2: 0, + year3: 0, + year4: 0, + year5: 0, + year6: 0, + year7: 0, + year8: 0, + year9: 0, + year10: 0, + }, + }) + setEditingId(null) + setErrors({}) + } + + const handleEdit = (service: Service) => { + setFormData(service) + setEditingId(service.id) + } + + const handleDelete = (id: string) => { + if (confirm('Are you sure you want to delete this service?')) { + deleteEntity('services', id) + } + } + + const updatePricing = (year: keyof Service['pricing'], value: number) => { + setFormData({ + ...formData, + pricing: { + ...formData.pricing!, + [year]: value, + }, + }) + } + + const tableColumns = [ + { + key: 'name', + header: 'Name', + render: (service: Service) => service.name, + }, + { + key: 'type', + header: 'Type', + render: (service: Service) => serviceTypeOptions.find((opt) => opt.value === service.type)?.label || service.type, + }, + { + key: 'year1', + header: 'Year 1 (€)', + render: (service: Service) => formatCurrency(service.pricing.year1), + }, + { + key: 'year10', + header: 'Year 10 (€)', + render: (service: Service) => formatCurrency(service.pricing.year10), + }, + { + key: 'actions', + header: 'Actions', + render: (service: Service) => ( +
+ + +
+ ), + }, + ] + + return ( +
+

Services Configuration

+ +
+ +
+
+ setFormData({ ...formData, name: e.target.value })} + error={errors.name} + /> + updatePricing(`year${year}` as keyof Service['pricing'], parseFloat(e.target.value) || 0)} + /> + ))} +
+
+ +
+ + {editingId && ( + + )} +
+ + + + +
+ + + + ) +} diff --git a/src/pages/configuration/WasteConfigurationPage.css b/src/pages/configuration/WasteConfigurationPage.css new file mode 100644 index 0000000..93ef4a3 --- /dev/null +++ b/src/pages/configuration/WasteConfigurationPage.css @@ -0,0 +1,42 @@ +.waste-config-page { + max-width: 1280px; + margin: 0 auto; +} + +.page-title { + font-size: 2.5rem; + font-weight: 700; + color: var(--text-primary); + margin-bottom: var(--spacing-2xl); +} + +.page-content { + display: flex; + flex-direction: column; + gap: var(--spacing-xl); +} + +.form-card { + max-width: 800px; +} + +.form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: var(--spacing-lg); +} + +.form-actions { + display: flex; + gap: var(--spacing-md); + margin-top: var(--spacing-lg); +} + +.table-card { + margin-top: var(--spacing-xl); +} + +.table-actions { + display: flex; + gap: var(--spacing-sm); +} diff --git a/src/pages/configuration/WasteConfigurationPage.tsx b/src/pages/configuration/WasteConfigurationPage.tsx new file mode 100644 index 0000000..a11b24d --- /dev/null +++ b/src/pages/configuration/WasteConfigurationPage.tsx @@ -0,0 +1,238 @@ +import { useState } from 'react' +import { useStorage } from '@/hooks/useStorage' +import { Waste } from '@/types' +import Card from '@/components/base/Card' +import Button from '@/components/base/Button' +import Input from '@/components/base/Input' +import Select from '@/components/base/Select' +import Table from '@/components/base/Table' +import Badge from '@/components/base/Badge' +import { formatDate } from '@/utils/formatters' +import { validateRequired, validateNumber, validatePercentage } from '@/utils/validators' +import './WasteConfigurationPage.css' + +export default function WasteConfigurationPage() { + const { data, addEntity, updateEntity, deleteEntity } = useStorage() + const [editingId, setEditingId] = useState(null) + const [formData, setFormData] = useState>({ + name: '', + originType: 'animals', + originSubType: '', + originUnitsPer1000m3Methane: 0, + bmp: 0, + waterPercentage: 75, + regulationNeeds: [], + maxStorageDuration: 30, + }) + const [errors, setErrors] = useState>({}) + + const wastes = data?.wastes || [] + + const originTypeOptions = [ + { value: 'animals', label: 'Animals' }, + { value: 'markets', label: 'Markets' }, + { value: 'restaurants', label: 'Restaurants' }, + { value: 'other', label: 'Other' }, + ] + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault() + + const newErrors: Record = {} + newErrors.name = validateRequired(formData.name) + newErrors.bmp = validateNumber(formData.bmp, 0.1, 1.0) + newErrors.waterPercentage = validatePercentage(formData.waterPercentage) + newErrors.originUnitsPer1000m3Methane = validateNumber(formData.originUnitsPer1000m3Methane, 0) + newErrors.maxStorageDuration = validateNumber(formData.maxStorageDuration, 1) + + setErrors(newErrors) + + if (Object.values(newErrors).some((error) => error !== undefined)) { + return + } + + const waste: Waste = { + id: editingId || crypto.randomUUID(), + name: formData.name!, + originType: formData.originType!, + originSubType: formData.originSubType, + originUnitsPer1000m3Methane: formData.originUnitsPer1000m3Methane!, + bmp: formData.bmp!, + waterPercentage: formData.waterPercentage!, + regulationNeeds: formData.regulationNeeds || [], + regulatoryCharacteristics: formData.regulatoryCharacteristics, + maxStorageDuration: formData.maxStorageDuration!, + createdAt: editingId ? wastes.find((w) => w.id === editingId)?.createdAt || new Date().toISOString() : new Date().toISOString(), + updatedAt: new Date().toISOString(), + } + + if (editingId) { + updateEntity('wastes', editingId, waste) + } else { + addEntity('wastes', waste) + } + + resetForm() + } + + const resetForm = () => { + setFormData({ + name: '', + originType: 'animals', + originSubType: '', + originUnitsPer1000m3Methane: 0, + bmp: 0, + waterPercentage: 75, + regulationNeeds: [], + maxStorageDuration: 30, + }) + setEditingId(null) + setErrors({}) + } + + const handleEdit = (waste: Waste) => { + setFormData(waste) + setEditingId(waste.id) + } + + const handleDelete = (id: string) => { + if (confirm('Are you sure you want to delete this waste type?')) { + deleteEntity('wastes', id) + } + } + + const tableColumns = [ + { + key: 'name', + header: 'Name', + render: (waste: Waste) => waste.name, + }, + { + key: 'originType', + header: 'Origin Type', + render: (waste: Waste) => {waste.originType}, + }, + { + key: 'bmp', + header: 'BMP (Nm³ CH₄/kg VS)', + render: (waste: Waste) => waste.bmp.toFixed(3), + }, + { + key: 'waterPercentage', + header: 'Water %', + render: (waste: Waste) => `${waste.waterPercentage}%`, + }, + { + key: 'maxStorageDuration', + header: 'Max Storage (days)', + render: (waste: Waste) => waste.maxStorageDuration, + }, + { + key: 'actions', + header: 'Actions', + render: (waste: Waste) => ( +
+ + +
+ ), + }, + ] + + return ( +
+

Waste Configuration

+ +
+ +
+
+ setFormData({ ...formData, name: e.target.value })} + error={errors.name} + placeholder="Enter waste name" + /> + setFormData({ ...formData, originSubType: e.target.value })} + placeholder="Enter sub type (optional)" + /> + +
+ setFormData({ ...formData, bmp: parseFloat(e.target.value) || 0 })} + error={errors.bmp} + helpText="Biochemical Methane Potential (0.1 - 1.0)" + /> + setFormData({ ...formData, waterPercentage: parseFloat(e.target.value) || 0 })} + error={errors.waterPercentage} + helpText="Water content percentage (0-100%)" + /> +
+ +
+ setFormData({ ...formData, originUnitsPer1000m3Methane: parseFloat(e.target.value) || 0 })} + error={errors.originUnitsPer1000m3Methane} + /> + setFormData({ ...formData, maxStorageDuration: parseInt(e.target.value) || 0 })} + error={errors.maxStorageDuration} + /> +
+ +
+ + {editingId && ( + + )} +
+ + + + +
+ + + + ) +} diff --git a/src/pages/projects/AdministrativeProceduresPage.css b/src/pages/projects/AdministrativeProceduresPage.css new file mode 100644 index 0000000..388526b --- /dev/null +++ b/src/pages/projects/AdministrativeProceduresPage.css @@ -0,0 +1,35 @@ +.procedures-page { + max-width: 1280px; + margin: 0 auto; +} + +.page-content { + display: flex; + flex-direction: column; + gap: var(--spacing-xl); +} + +.form-card { + max-width: 800px; +} + +.form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: var(--spacing-lg); +} + +.form-actions { + display: flex; + gap: var(--spacing-md); + margin-top: var(--spacing-lg); +} + +.table-card { + margin-top: var(--spacing-xl); +} + +.table-actions { + display: flex; + gap: var(--spacing-sm); +} diff --git a/src/pages/projects/AdministrativeProceduresPage.tsx b/src/pages/projects/AdministrativeProceduresPage.tsx new file mode 100644 index 0000000..22a935b --- /dev/null +++ b/src/pages/projects/AdministrativeProceduresPage.tsx @@ -0,0 +1,201 @@ +import { useState } from 'react' +import { useStorage } from '@/hooks/useStorage' +import { AdministrativeProcedure, ProcedureType } from '@/types' +import Card from '@/components/base/Card' +import Button from '@/components/base/Button' +import Input from '@/components/base/Input' +import Select from '@/components/base/Select' +import Table from '@/components/base/Table' +import { validateRequired, validateNumber } from '@/utils/validators' +import './AdministrativeProceduresPage.css' + +export default function AdministrativeProceduresPage() { + const { data, addEntity, updateEntity, deleteEntity } = useStorage() + const [editingId, setEditingId] = useState(null) + const [formData, setFormData] = useState>({ + name: '', + type: 'ICPE', + delays: 0, + contact: { + name: '', + }, + regions: [], + }) + const [errors, setErrors] = useState>({}) + + const procedures = data?.administrativeProcedures || [] + + const procedureTypeOptions = [ + { value: 'ICPE', label: 'ICPE' }, + { value: 'spreading', label: 'Spreading' }, + { value: 'other', label: 'Other' }, + ] + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault() + + const newErrors: Record = {} + newErrors.name = validateRequired(formData.name) + newErrors.contactName = validateRequired(formData.contact?.name) + newErrors.delays = validateNumber(formData.delays, 0) + + setErrors(newErrors) + + if (Object.values(newErrors).some((error) => error !== undefined)) { + return + } + + const procedure: AdministrativeProcedure = { + id: editingId || crypto.randomUUID(), + name: formData.name!, + type: formData.type!, + delays: formData.delays!, + contact: formData.contact!, + regions: formData.regions || [], + createdAt: editingId ? procedures.find((p) => p.id === editingId)?.createdAt || new Date().toISOString() : new Date().toISOString(), + updatedAt: new Date().toISOString(), + } + + if (editingId) { + updateEntity('administrativeProcedures', editingId, procedure) + } else { + addEntity('administrativeProcedures', procedure) + } + + resetForm() + } + + const resetForm = () => { + setFormData({ + name: '', + type: 'ICPE', + delays: 0, + contact: { + name: '', + }, + regions: [], + }) + setEditingId(null) + setErrors({}) + } + + const handleEdit = (procedure: AdministrativeProcedure) => { + setFormData(procedure) + setEditingId(procedure.id) + } + + const handleDelete = (id: string) => { + if (confirm('Are you sure you want to delete this procedure?')) { + deleteEntity('administrativeProcedures', id) + } + } + + const tableColumns = [ + { + key: 'name', + header: 'Name', + render: (procedure: AdministrativeProcedure) => procedure.name, + }, + { + key: 'type', + header: 'Type', + render: (procedure: AdministrativeProcedure) => procedure.type, + }, + { + key: 'delays', + header: 'Delays (days)', + render: (procedure: AdministrativeProcedure) => procedure.delays, + }, + { + key: 'contact', + header: 'Contact', + render: (procedure: AdministrativeProcedure) => procedure.contact.name, + }, + { + key: 'regions', + header: 'Regions', + render: (procedure: AdministrativeProcedure) => procedure.regions.length, + }, + { + key: 'actions', + header: 'Actions', + render: (procedure: AdministrativeProcedure) => ( +
+ + +
+ ), + }, + ] + + return ( +
+

Administrative Procedures

+ +
+ +
+
+ setFormData({ ...formData, name: e.target.value })} + error={errors.name} + /> + setFormData({ ...formData, delays: parseInt(e.target.value) || 0 })} + error={errors.delays} + /> + + setFormData({ + ...formData, + contact: { + ...formData.contact!, + name: e.target.value, + }, + }) + } + error={errors.contactName} + /> +
+ +
+ + {editingId && ( + + )} +
+ +
+ + +
+ + + + ) +} diff --git a/src/pages/projects/InvestorsPage.css b/src/pages/projects/InvestorsPage.css new file mode 100644 index 0000000..e426b2b --- /dev/null +++ b/src/pages/projects/InvestorsPage.css @@ -0,0 +1,35 @@ +.investors-page { + max-width: 1280px; + margin: 0 auto; +} + +.page-content { + display: flex; + flex-direction: column; + gap: var(--spacing-xl); +} + +.form-card { + max-width: 800px; +} + +.form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: var(--spacing-lg); +} + +.form-actions { + display: flex; + gap: var(--spacing-md); + margin-top: var(--spacing-lg); +} + +.table-card { + margin-top: var(--spacing-xl); +} + +.table-actions { + display: flex; + gap: var(--spacing-sm); +} diff --git a/src/pages/projects/InvestorsPage.tsx b/src/pages/projects/InvestorsPage.tsx new file mode 100644 index 0000000..d99bad7 --- /dev/null +++ b/src/pages/projects/InvestorsPage.tsx @@ -0,0 +1,278 @@ +import { useState } from 'react' +import { useStorage } from '@/hooks/useStorage' +import { Investor } from '@/types' +import Card from '@/components/base/Card' +import Button from '@/components/base/Button' +import Input from '@/components/base/Input' +import Table from '@/components/base/Table' +import { formatCurrency } from '@/utils/formatters' +import { validateRequired, validateNumber } from '@/utils/validators' +import './InvestorsPage.css' + +export default function InvestorsPage() { + const { data, addEntity, updateEntity, deleteEntity } = useStorage() + const [editingId, setEditingId] = useState(null) + const [formData, setFormData] = useState>({ + name: '', + type: '', + amountRange: { + min: 0, + max: 0, + }, + geographicRegions: [], + wasteRange: { + min: 0, + max: 0, + }, + wasteTypes: [], + solarPanelsRange: { + min: 0, + max: 0, + }, + }) + const [errors, setErrors] = useState>({}) + + const investors = data?.investors || [] + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault() + + const newErrors: Record = {} + newErrors.name = validateRequired(formData.name) + newErrors.type = validateRequired(formData.type) + newErrors.amountMin = validateNumber(formData.amountRange?.min, 0) + newErrors.amountMax = validateNumber(formData.amountRange?.max, formData.amountRange?.min) + + setErrors(newErrors) + + if (Object.values(newErrors).some((error) => error !== undefined)) { + return + } + + const investor: Investor = { + id: editingId || crypto.randomUUID(), + name: formData.name!, + type: formData.type!, + amountRange: formData.amountRange!, + geographicRegions: formData.geographicRegions || [], + wasteRange: formData.wasteRange!, + wasteTypes: formData.wasteTypes || [], + solarPanelsRange: formData.solarPanelsRange!, + createdAt: editingId ? investors.find((i) => i.id === editingId)?.createdAt || new Date().toISOString() : new Date().toISOString(), + updatedAt: new Date().toISOString(), + } + + if (editingId) { + updateEntity('investors', editingId, investor) + } else { + addEntity('investors', investor) + } + + resetForm() + } + + const resetForm = () => { + setFormData({ + name: '', + type: '', + amountRange: { min: 0, max: 0 }, + geographicRegions: [], + wasteRange: { min: 0, max: 0 }, + wasteTypes: [], + solarPanelsRange: { min: 0, max: 0 }, + }) + setEditingId(null) + setErrors({}) + } + + const handleEdit = (investor: Investor) => { + setFormData(investor) + setEditingId(investor.id) + } + + const handleDelete = (id: string) => { + if (confirm('Are you sure you want to delete this investor?')) { + deleteEntity('investors', id) + } + } + + const tableColumns = [ + { + key: 'name', + header: 'Name', + render: (investor: Investor) => investor.name, + }, + { + key: 'type', + header: 'Type', + render: (investor: Investor) => investor.type, + }, + { + key: 'amountRange', + header: 'Amount Range (€)', + render: (investor: Investor) => `${formatCurrency(investor.amountRange.min)} - ${formatCurrency(investor.amountRange.max)}`, + }, + { + key: 'regions', + header: 'Regions', + render: (investor: Investor) => investor.geographicRegions.length, + }, + { + key: 'actions', + header: 'Actions', + render: (investor: Investor) => ( +
+ + +
+ ), + }, + ] + + return ( +
+

Investors

+ +
+ +
+
+ setFormData({ ...formData, name: e.target.value })} + error={errors.name} + /> + setFormData({ ...formData, type: e.target.value })} + error={errors.type} + /> +
+ +
+ + setFormData({ + ...formData, + amountRange: { + ...formData.amountRange!, + min: parseFloat(e.target.value) || 0, + }, + }) + } + error={errors.amountMin} + /> + + setFormData({ + ...formData, + amountRange: { + ...formData.amountRange!, + max: parseFloat(e.target.value) || 0, + }, + }) + } + error={errors.amountMax} + /> +
+ +
+ + setFormData({ + ...formData, + wasteRange: { + ...formData.wasteRange!, + min: parseFloat(e.target.value) || 0, + }, + }) + } + /> + + setFormData({ + ...formData, + wasteRange: { + ...formData.wasteRange!, + max: parseFloat(e.target.value) || 0, + }, + }) + } + /> +
+ +
+ + setFormData({ + ...formData, + solarPanelsRange: { + ...formData.solarPanelsRange!, + min: parseFloat(e.target.value) || 0, + }, + }) + } + /> + + setFormData({ + ...formData, + solarPanelsRange: { + ...formData.solarPanelsRange!, + max: parseFloat(e.target.value) || 0, + }, + }) + } + /> +
+ +
+ + {editingId && ( + + )} +
+ +
+ + +
+ + + + ) +} diff --git a/src/pages/projects/ProjectConfigurationPage.css b/src/pages/projects/ProjectConfigurationPage.css new file mode 100644 index 0000000..a57f7b8 --- /dev/null +++ b/src/pages/projects/ProjectConfigurationPage.css @@ -0,0 +1,82 @@ +.project-config-page { + max-width: 1280px; + margin: 0 auto; +} + +.page-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: var(--spacing-2xl); +} + +.page-title { + font-size: 2.5rem; + font-weight: 700; + color: var(--text-primary); +} + +.project-form { + display: flex; + flex-direction: column; + gap: var(--spacing-xl); +} + +.form-section { + max-width: 1000px; +} + +.form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: var(--spacing-lg); +} + +.multi-select-section { + margin-bottom: var(--spacing-lg); +} + +.checkbox-list { + display: flex; + flex-direction: column; + gap: var(--spacing-sm); + margin-top: var(--spacing-sm); + padding: var(--spacing-md); + background-color: var(--background); + border-radius: 8px; + border: 1px solid var(--border); + max-height: 200px; + overflow-y: auto; +} + +.checkbox-item { + display: flex; + align-items: center; + gap: var(--spacing-sm); + cursor: pointer; +} + +.checkbox-item input[type="checkbox"] { + width: 20px; + height: 20px; + cursor: pointer; +} + +.procedure-item, +.investment-item { + display: grid; + grid-template-columns: 2fr 1fr 1fr auto; + gap: var(--spacing-md); + align-items: end; + margin-bottom: var(--spacing-lg); + padding: var(--spacing-lg); + background-color: var(--background); + border-radius: 8px; + border: 1px solid var(--border); +} + +.form-actions { + display: flex; + gap: var(--spacing-md); + margin-top: var(--spacing-xl); +} diff --git a/src/pages/projects/ProjectConfigurationPage.tsx b/src/pages/projects/ProjectConfigurationPage.tsx new file mode 100644 index 0000000..59a2ad9 --- /dev/null +++ b/src/pages/projects/ProjectConfigurationPage.tsx @@ -0,0 +1,390 @@ +import { useState, useEffect } from 'react' +import { useParams, useNavigate, Link } from 'react-router-dom' +import { useStorage } from '@/hooks/useStorage' +import { Project, SiteStatus, ProcedureStatus } from '@/types' +import Card from '@/components/base/Card' +import Button from '@/components/base/Button' +import Input from '@/components/base/Input' +import Select from '@/components/base/Select' +import Badge from '@/components/base/Badge' +import { validateRequired, validateNumber, validateDate, validateDateRange } from '@/utils/validators' +import './ProjectConfigurationPage.css' + +export default function ProjectConfigurationPage() { + const { id } = useParams<{ id: string }>() + const navigate = useNavigate() + const { data, addEntity, updateEntity } = useStorage() + const [formData, setFormData] = useState>({ + name: '', + startDate: '', + endDate: '', + treatmentSiteId: '', + collectionSiteIds: [], + numberOfModules: 1, + transportBySite: false, + administrativeProcedures: [], + investments: [], + }) + const [errors, setErrors] = useState>({}) + + const projects = data?.projects || [] + const treatmentSites = data?.treatmentSites || [] + const wasteSites = data?.wasteSites || [] + const wastes = data?.wastes || [] + const administrativeProcedures = data?.administrativeProcedures || [] + const investors = data?.investors || [] + + const isEditing = !!id + const project = isEditing ? projects.find((p) => p.id === id) : null + + useEffect(() => { + if (isEditing && project) { + setFormData(project) + } else { + // Set default dates (10 years from today) + const startDate = new Date().toISOString().split('T')[0] + const endDate = new Date() + endDate.setFullYear(endDate.getFullYear() + 10) + setFormData({ + ...formData, + startDate, + endDate: endDate.toISOString().split('T')[0], + }) + } + }, [id, project]) + + const treatmentSiteOptions = treatmentSites.map((site) => ({ + value: site.id, + label: `${site.name} (${site.status})`, + })) + + const wasteSiteOptions = wasteSites.map((site) => ({ + value: site.id, + label: site.name, + })) + + const wasteOptions = wastes.map((waste) => ({ + value: waste.id, + label: waste.name, + })) + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault() + + const newErrors: Record = {} + newErrors.name = validateRequired(formData.name) + newErrors.startDate = validateDate(formData.startDate) + newErrors.endDate = validateDate(formData.endDate) + newErrors.treatmentSiteId = validateRequired(formData.treatmentSiteId) + newErrors.numberOfModules = validateNumber(formData.numberOfModules, 1) + newErrors.dateRange = validateDateRange(formData.startDate, formData.endDate) + + setErrors(newErrors) + + if (Object.values(newErrors).some((error) => error !== undefined)) { + return + } + + const projectData: Project = { + id: id || crypto.randomUUID(), + name: formData.name!, + startDate: formData.startDate!, + endDate: formData.endDate!, + treatmentSiteId: formData.treatmentSiteId!, + collectionSiteIds: formData.collectionSiteIds || [], + numberOfModules: formData.numberOfModules!, + transportBySite: formData.transportBySite || false, + wasteCharacteristicsOverride: formData.wasteCharacteristicsOverride, + administrativeProcedures: formData.administrativeProcedures || [], + investments: formData.investments || [], + createdAt: isEditing && project ? project.createdAt : new Date().toISOString(), + updatedAt: new Date().toISOString(), + } + + if (isEditing) { + updateEntity('projects', id!, projectData) + } else { + addEntity('projects', projectData) + } + + navigate('/projects') + } + + const addAdministrativeProcedure = () => { + if (administrativeProcedures.length === 0) return + + const newProcedures = [...(formData.administrativeProcedures || [])] + newProcedures.push({ + procedureId: administrativeProcedures[0].id, + status: 'toDo', + }) + setFormData({ ...formData, administrativeProcedures: newProcedures }) + } + + const removeAdministrativeProcedure = (index: number) => { + const newProcedures = [...(formData.administrativeProcedures || [])] + newProcedures.splice(index, 1) + setFormData({ ...formData, administrativeProcedures: newProcedures }) + } + + const updateAdministrativeProcedure = (index: number, field: 'procedureId' | 'status', value: string) => { + const newProcedures = [...(formData.administrativeProcedures || [])] + newProcedures[index] = { + ...newProcedures[index], + [field]: value, + } + setFormData({ ...formData, administrativeProcedures: newProcedures }) + } + + const addInvestment = () => { + if (investors.length === 0) return + + const newInvestments = [...(formData.investments || [])] + newInvestments.push({ + investorId: investors[0].id, + status: 'toBeApproached', + amount: 0, + }) + setFormData({ ...formData, investments: newInvestments }) + } + + const removeInvestment = (index: number) => { + const newInvestments = [...(formData.investments || [])] + newInvestments.splice(index, 1) + setFormData({ ...formData, investments: newInvestments }) + } + + const updateInvestment = (index: number, field: 'investorId' | 'status' | 'amount', value: string | number) => { + const newInvestments = [...(formData.investments || [])] + newInvestments[index] = { + ...newInvestments[index], + [field]: value, + } + setFormData({ ...formData, investments: newInvestments }) + } + + return ( +
+
+

{isEditing ? 'Edit Project' : 'Create New Project'}

+ + + +
+ +
+ +
+ setFormData({ ...formData, name: e.target.value })} + error={errors.name} + /> + setFormData({ ...formData, numberOfModules: parseInt(e.target.value) || 1 })} + error={errors.numberOfModules} + /> +
+ +
+ setFormData({ ...formData, startDate: e.target.value })} + error={errors.startDate} + /> + setFormData({ ...formData, endDate: e.target.value })} + error={errors.endDate || errors.dateRange} + /> +
+
+ + + { + const currentIds = formData.collectionSiteIds || [] + if (e.target.checked) { + setFormData({ ...formData, collectionSiteIds: [...currentIds, option.value] }) + } else { + setFormData({ ...formData, collectionSiteIds: currentIds.filter((id) => id !== option.value) }) + } + }} + /> + {option.label} + + ))} +
+ {wasteSiteOptions.length === 0 && ( +

No waste sites available. Create waste sites first.

+ )} + + +
+ setFormData({ ...formData, transportBySite: e.target.checked })} + /> + Transport by site +
+ + + + + setFormData({ + ...formData, + wasteCharacteristicsOverride: { + ...formData.wasteCharacteristicsOverride, + bmp: e.target.value ? parseFloat(e.target.value) : undefined, + }, + }) + } + /> + + setFormData({ + ...formData, + wasteCharacteristicsOverride: { + ...formData.wasteCharacteristicsOverride, + waterPercentage: e.target.value ? parseFloat(e.target.value) : undefined, + }, + }) + } + /> + + + + + {formData.administrativeProcedures?.map((proc, index) => ( +
+ updateAdministrativeProcedure(index, 'status', e.target.value as ProcedureStatus)} + options={[ + { value: 'toDo', label: 'To Do' }, + { value: 'done', label: 'Done' }, + { value: 'na', label: 'N/A' }, + ]} + /> + +
+ ))} + +
+ + + {formData.investments?.map((inv, index) => ( +
+ updateInvestment(index, 'status', e.target.value as SiteStatus)} + options={[ + { value: 'toBeApproached', label: 'To be approached' }, + { value: 'loiOk', label: 'LOI OK' }, + { value: 'inProgress', label: 'In progress' }, + { value: 'completed', label: 'Completed' }, + ]} + /> + updateInvestment(index, 'amount', parseFloat(e.target.value) || 0)} + /> + +
+ ))} + +
+ +
+ + + + +
+ + + ) +} diff --git a/src/pages/projects/ProjectListPage.css b/src/pages/projects/ProjectListPage.css new file mode 100644 index 0000000..2cec96c --- /dev/null +++ b/src/pages/projects/ProjectListPage.css @@ -0,0 +1,36 @@ +.project-list-page { + max-width: 1280px; + margin: 0 auto; +} + +.page-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: var(--spacing-2xl); +} + +.page-title { + font-size: 2.5rem; + font-weight: 700; + color: var(--text-primary); +} + +.table-card { + margin-top: var(--spacing-xl); +} + +.table-actions { + display: flex; + gap: var(--spacing-sm); +} + +.project-link { + color: var(--primary-green); + text-decoration: none; + font-weight: 500; +} + +.project-link:hover { + text-decoration: underline; +} diff --git a/src/pages/projects/ProjectListPage.tsx b/src/pages/projects/ProjectListPage.tsx new file mode 100644 index 0000000..c2580f1 --- /dev/null +++ b/src/pages/projects/ProjectListPage.tsx @@ -0,0 +1,106 @@ +import { Link } from 'react-router-dom' +import { useStorage } from '@/hooks/useStorage' +import { Project } from '@/types' +import Card from '@/components/base/Card' +import Button from '@/components/base/Button' +import Table from '@/components/base/Table' +import Badge from '@/components/base/Badge' +import { formatDate } from '@/utils/formatters' +import './ProjectListPage.css' + +export default function ProjectListPage() { + const { data, deleteEntity } = useStorage() + + const projects = data?.projects || [] + const treatmentSites = data?.treatmentSites || [] + const wasteSites = data?.wasteSites || [] + + const handleDelete = (id: string) => { + if (confirm('Are you sure you want to delete this project? This action cannot be undone.')) { + deleteEntity('projects', id) + } + } + + const getStatusBadge = (status: string) => { + const statusMap: Record = { + toBeApproached: 'to-be-approached', + loiOk: 'loi-ok', + inProgress: 'in-progress', + completed: 'completed', + } + return statusMap[status] || 'to-be-approached' + } + + const tableColumns = [ + { + key: 'name', + header: 'Project Name', + render: (project: Project) => ( + + {project.name} + + ), + }, + { + key: 'treatmentSite', + header: 'Treatment Site', + render: (project: Project) => { + const site = treatmentSites.find((s) => s.id === project.treatmentSiteId) + return site ? site.name : 'Unknown' + }, + }, + { + key: 'collectionSites', + header: 'Collection Sites', + render: (project: Project) => { + const sites = project.collectionSiteIds.map((id) => { + const site = wasteSites.find((s) => s.id === id) + return site?.name + }).filter(Boolean) + return sites.length > 0 ? sites.join(', ') : 'None' + }, + }, + { + key: 'modules', + header: 'Modules', + render: (project: Project) => project.numberOfModules, + }, + { + key: 'dates', + header: 'Duration', + render: (project: Project) => `${formatDate(project.startDate)} - ${formatDate(project.endDate)}`, + }, + { + key: 'actions', + header: 'Actions', + render: (project: Project) => ( +
+ + + + + + + +
+ ), + }, + ] + + return ( +
+
+

Projects

+ + + +
+ + +
+ + + ) +} diff --git a/src/pages/projects/TreatmentSitesPage.css b/src/pages/projects/TreatmentSitesPage.css new file mode 100644 index 0000000..d74b559 --- /dev/null +++ b/src/pages/projects/TreatmentSitesPage.css @@ -0,0 +1,56 @@ +.treatment-sites-page { + max-width: 1280px; + margin: 0 auto; +} + +.page-content { + display: flex; + flex-direction: column; + gap: var(--spacing-xl); +} + +.form-card { + max-width: 1000px; +} + +.form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: var(--spacing-lg); +} + +.temperatures-section { + margin: var(--spacing-xl) 0; + padding: var(--spacing-lg); + background-color: var(--background); + border-radius: 8px; + border: 1px solid var(--border); +} + +.section-title { + font-size: 1.125rem; + font-weight: 600; + color: var(--text-primary); + margin-bottom: var(--spacing-lg); +} + +.temperatures-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); + gap: var(--spacing-md); +} + +.form-actions { + display: flex; + gap: var(--spacing-md); + margin-top: var(--spacing-lg); +} + +.table-card { + margin-top: var(--spacing-xl); +} + +.table-actions { + display: flex; + gap: var(--spacing-sm); +} diff --git a/src/pages/projects/TreatmentSitesPage.tsx b/src/pages/projects/TreatmentSitesPage.tsx new file mode 100644 index 0000000..a04c34c --- /dev/null +++ b/src/pages/projects/TreatmentSitesPage.tsx @@ -0,0 +1,233 @@ +import { useState } from 'react' +import { useStorage } from '@/hooks/useStorage' +import { TreatmentSite, SiteStatus } from '@/types' +import Card from '@/components/base/Card' +import Button from '@/components/base/Button' +import Input from '@/components/base/Input' +import Select from '@/components/base/Select' +import Table from '@/components/base/Table' +import Badge from '@/components/base/Badge' +import { validateRequired, validateNumber } from '@/utils/validators' +import './TreatmentSitesPage.css' + +export default function TreatmentSitesPage() { + const { data, addEntity, updateEntity, deleteEntity } = useStorage() + const [editingId, setEditingId] = useState(null) + const [formData, setFormData] = useState>({ + name: '', + status: 'toBeApproached', + altitude: 0, + availableGroundSurface: 0, + monthlyTemperatures: Array(12).fill(0), + subscribedServices: [], + }) + const [errors, setErrors] = useState>({}) + + const sites = data?.treatmentSites || [] + const services = data?.services || [] + + const statusOptions = [ + { value: 'toBeApproached', label: 'To be approached' }, + { value: 'loiOk', label: 'LOI OK' }, + { value: 'inProgress', label: 'In progress' }, + { value: 'completed', label: 'Completed' }, + ] + + const monthNames = [ + 'January', 'February', 'March', 'April', 'May', 'June', + 'July', 'August', 'September', 'October', 'November', 'December' + ] + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault() + + const newErrors: Record = {} + newErrors.name = validateRequired(formData.name) + newErrors.altitude = validateNumber(formData.altitude) + newErrors.availableGroundSurface = validateNumber(formData.availableGroundSurface, 0) + + setErrors(newErrors) + + if (Object.values(newErrors).some((error) => error !== undefined)) { + return + } + + const site: TreatmentSite = { + id: editingId || crypto.randomUUID(), + name: formData.name!, + status: formData.status!, + location: formData.location, + altitude: formData.altitude!, + availableGroundSurface: formData.availableGroundSurface!, + monthlyTemperatures: formData.monthlyTemperatures!, + subscribedServices: formData.subscribedServices || [], + createdAt: editingId ? sites.find((s) => s.id === editingId)?.createdAt || new Date().toISOString() : new Date().toISOString(), + updatedAt: new Date().toISOString(), + } + + if (editingId) { + updateEntity('treatmentSites', editingId, site) + } else { + addEntity('treatmentSites', site) + } + + resetForm() + } + + const resetForm = () => { + setFormData({ + name: '', + status: 'toBeApproached', + altitude: 0, + availableGroundSurface: 0, + monthlyTemperatures: Array(12).fill(0), + subscribedServices: [], + }) + setEditingId(null) + setErrors({}) + } + + const handleEdit = (site: TreatmentSite) => { + setFormData(site) + setEditingId(site.id) + } + + const handleDelete = (id: string) => { + if (confirm('Are you sure you want to delete this treatment site?')) { + deleteEntity('treatmentSites', id) + } + } + + const updateTemperature = (monthIndex: number, value: number) => { + const newTemperatures = [...(formData.monthlyTemperatures || Array(12).fill(0))] + newTemperatures[monthIndex] = value + setFormData({ ...formData, monthlyTemperatures: newTemperatures }) + } + + const tableColumns = [ + { + key: 'name', + header: 'Name', + render: (site: TreatmentSite) => site.name, + }, + { + key: 'status', + header: 'Status', + render: (site: TreatmentSite) => {statusOptions.find(o => o.value === site.status)?.label}, + }, + { + key: 'altitude', + header: 'Altitude (m)', + render: (site: TreatmentSite) => site.altitude, + }, + { + key: 'surface', + header: 'Surface (m²)', + render: (site: TreatmentSite) => site.availableGroundSurface.toLocaleString(), + }, + { + key: 'services', + header: 'Services', + render: (site: TreatmentSite) => site.subscribedServices.length, + }, + { + key: 'actions', + header: 'Actions', + render: (site: TreatmentSite) => ( +
+ + +
+ ), + }, + ] + + const getStatusVariant = (status: SiteStatus): 'to-be-approached' | 'loi-ok' | 'in-progress' | 'completed' => { + const map: Record = { + toBeApproached: 'to-be-approached', + loiOk: 'loi-ok', + inProgress: 'in-progress', + completed: 'completed', + } + return map[status] + } + + return ( +
+

Treatment Sites

+ +
+ +
+
+ setFormData({ ...formData, name: e.target.value })} + error={errors.name} + /> + setFormData({ ...formData, altitude: parseFloat(e.target.value) || 0 })} + error={errors.altitude} + /> + setFormData({ ...formData, availableGroundSurface: parseFloat(e.target.value) || 0 })} + error={errors.availableGroundSurface} + /> +
+ +
+

Monthly Average Temperatures (°C)

+
+ {monthNames.map((month, index) => ( + updateTemperature(index, parseFloat(e.target.value) || 0)} + /> + ))} +
+
+ +
+ + {editingId && ( + + )} +
+ +
+ + +
+ + + + ) +} diff --git a/src/pages/projects/WasteSitesPage.css b/src/pages/projects/WasteSitesPage.css new file mode 100644 index 0000000..72fdd53 --- /dev/null +++ b/src/pages/projects/WasteSitesPage.css @@ -0,0 +1,35 @@ +.waste-sites-page { + max-width: 1280px; + margin: 0 auto; +} + +.page-content { + display: flex; + flex-direction: column; + gap: var(--spacing-xl); +} + +.form-card { + max-width: 800px; +} + +.form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: var(--spacing-lg); +} + +.form-actions { + display: flex; + gap: var(--spacing-md); + margin-top: var(--spacing-lg); +} + +.table-card { + margin-top: var(--spacing-xl); +} + +.table-actions { + display: flex; + gap: var(--spacing-sm); +} diff --git a/src/pages/projects/WasteSitesPage.tsx b/src/pages/projects/WasteSitesPage.tsx new file mode 100644 index 0000000..de1badf --- /dev/null +++ b/src/pages/projects/WasteSitesPage.tsx @@ -0,0 +1,305 @@ +import { useState } from 'react' +import { useStorage } from '@/hooks/useStorage' +import { WasteSite, SiteStatus } from '@/types' +import Card from '@/components/base/Card' +import Button from '@/components/base/Button' +import Input from '@/components/base/Input' +import Select from '@/components/base/Select' +import Table from '@/components/base/Table' +import Badge from '@/components/base/Badge' +import { validateRequired, validateNumber } from '@/utils/validators' +import './WasteSitesPage.css' + +export default function WasteSitesPage() { + const { data, addEntity, updateEntity, deleteEntity } = useStorage() + const [editingId, setEditingId] = useState(null) + const [formData, setFormData] = useState>({ + name: '', + type: '', + status: 'toBeApproached', + wasteType: '', + quantityRange: { + min: 0, + max: 0, + }, + contact: { + name: '', + }, + collectionType: '', + distance: 0, + }) + const [errors, setErrors] = useState>({}) + + const sites = data?.wasteSites || [] + const wastes = data?.wastes || [] + + const statusOptions = [ + { value: 'toBeApproached', label: 'To be approached' }, + { value: 'loiOk', label: 'LOI OK' }, + { value: 'inProgress', label: 'In progress' }, + { value: 'completed', label: 'Completed' }, + ] + + const wasteOptions = wastes.map((waste) => ({ + value: waste.id, + label: waste.name, + })) + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault() + + const newErrors: Record = {} + newErrors.name = validateRequired(formData.name) + newErrors.type = validateRequired(formData.type) + newErrors.wasteType = validateRequired(formData.wasteType) + newErrors.contactName = validateRequired(formData.contact?.name) + newErrors.collectionType = validateRequired(formData.collectionType) + newErrors.quantityMin = validateNumber(formData.quantityRange?.min, 0) + newErrors.quantityMax = validateNumber(formData.quantityRange?.max, formData.quantityRange?.min) + newErrors.distance = validateNumber(formData.distance, 0) + + setErrors(newErrors) + + if (Object.values(newErrors).some((error) => error !== undefined)) { + return + } + + const site: WasteSite = { + id: editingId || crypto.randomUUID(), + name: formData.name!, + type: formData.type!, + status: formData.status!, + wasteType: formData.wasteType!, + quantityRange: formData.quantityRange!, + contact: formData.contact!, + collectionType: formData.collectionType!, + distance: formData.distance!, + createdAt: editingId ? sites.find((s) => s.id === editingId)?.createdAt || new Date().toISOString() : new Date().toISOString(), + updatedAt: new Date().toISOString(), + } + + if (editingId) { + updateEntity('wasteSites', editingId, site) + } else { + addEntity('wasteSites', site) + } + + resetForm() + } + + const resetForm = () => { + setFormData({ + name: '', + type: '', + status: 'toBeApproached', + wasteType: '', + quantityRange: { + min: 0, + max: 0, + }, + contact: { + name: '', + }, + collectionType: '', + distance: 0, + }) + setEditingId(null) + setErrors({}) + } + + const handleEdit = (site: WasteSite) => { + setFormData(site) + setEditingId(site.id) + } + + const handleDelete = (id: string) => { + if (confirm('Are you sure you want to delete this waste site?')) { + deleteEntity('wasteSites', id) + } + } + + const getStatusVariant = (status: SiteStatus): 'to-be-approached' | 'loi-ok' | 'in-progress' | 'completed' => { + const map: Record = { + toBeApproached: 'to-be-approached', + loiOk: 'loi-ok', + inProgress: 'in-progress', + completed: 'completed', + } + return map[status] + } + + const tableColumns = [ + { + key: 'name', + header: 'Name', + render: (site: WasteSite) => site.name, + }, + { + key: 'type', + header: 'Type', + render: (site: WasteSite) => site.type, + }, + { + key: 'status', + header: 'Status', + render: (site: WasteSite) => {statusOptions.find(o => o.value === site.status)?.label}, + }, + { + key: 'wasteType', + header: 'Waste Type', + render: (site: WasteSite) => { + const waste = wastes.find((w) => w.id === site.wasteType) + return waste ? waste.name : 'Unknown' + }, + }, + { + key: 'quantity', + header: 'Quantity (t/day)', + render: (site: WasteSite) => `${site.quantityRange.min} - ${site.quantityRange.max}`, + }, + { + key: 'distance', + header: 'Distance (km)', + render: (site: WasteSite) => site.distance, + }, + { + key: 'actions', + header: 'Actions', + render: (site: WasteSite) => ( +
+ + +
+ ), + }, + ] + + return ( +
+

Waste Sites

+ +
+ +
+
+ setFormData({ ...formData, name: e.target.value })} + error={errors.name} + /> + setFormData({ ...formData, type: e.target.value })} + error={errors.type} + /> +
+ +
+ setFormData({ ...formData, wasteType: e.target.value })} + options={wasteOptions.length > 0 ? wasteOptions : [{ value: '', label: 'No waste types available' }]} + error={errors.wasteType} + /> +
+ +
+ + setFormData({ + ...formData, + quantityRange: { + ...formData.quantityRange!, + min: parseFloat(e.target.value) || 0, + }, + }) + } + error={errors.quantityMin} + /> + + setFormData({ + ...formData, + quantityRange: { + ...formData.quantityRange!, + max: parseFloat(e.target.value) || 0, + }, + }) + } + error={errors.quantityMax} + /> +
+ +
+ + setFormData({ + ...formData, + contact: { + ...formData.contact!, + name: e.target.value, + }, + }) + } + error={errors.contactName} + /> + setFormData({ ...formData, collectionType: e.target.value })} + error={errors.collectionType} + /> +
+ + setFormData({ ...formData, distance: parseFloat(e.target.value) || 0 })} + error={errors.distance} + /> + +
+ + {editingId && ( + + )} +
+ +
+ + +
+ + + + ) +} diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..d18edc6 --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,262 @@ +// Base entity types +export interface BaseEntity { + id: string + createdAt: string + updatedAt?: string + notes?: string +} + +// User +export interface User extends BaseEntity { + username: string + password: string + lastLogin?: string +} + +// Waste +export interface Waste extends BaseEntity { + name: string + originType: 'animals' | 'markets' | 'restaurants' | 'other' + originSubType?: string + originUnitsPer1000m3Methane: number + bmp: number // Nm³ CH₄/kg VS + waterPercentage: number // 0-100 + regulationNeeds: string[] + regulatoryCharacteristics?: { + nitrogen?: number + phosphorus?: number + potassium?: number + carbonNitrogenRatio?: number + } + maxStorageDuration: number // days +} + +// Natural Regulator +export interface NaturalRegulator extends BaseEntity { + name: string + type: string + regulatoryCharacteristics?: { + nitrogen?: number + phosphorus?: number + potassium?: number + carbonNitrogenRatio?: number + phAdjustment?: number // -14 to 14 + metalBinding?: boolean + pathogenReduction?: boolean + } + applicationConditions: string + dosageRequirements: { + min: number + max: number + unit: 'kg/t' | 'L/t' | '%' + } +} + +// Service +export type ServiceType = + | 'rawRental' + | 'biologicalTreatment' + | 'bitcoinManagement' + | 'fertilizers' + | 'wasteHeat' + | 'carbonCredits' + | 'brownfield' + | 'transport' + +export interface Service extends BaseEntity { + name: string + type: ServiceType + pricing: { + year1: number + year2: number + year3: number + year4: number + year5: number + year6: number + year7: number + year8: number + year9: number + year10: number + } +} + +// Treatment Site +export type SiteStatus = 'toBeApproached' | 'loiOk' | 'inProgress' | 'completed' + +export interface TreatmentSite extends BaseEntity { + name: string + status: SiteStatus + location?: { + address?: string + coordinates?: { + lat: number + lng: number + } + } + altitude: number // meters + availableGroundSurface: number // m² + monthlyTemperatures: number[] // 12 values, °C + subscribedServices: string[] // service IDs +} + +// Waste Site +export interface WasteSite extends BaseEntity { + name: string + type: string + status: SiteStatus + wasteType: string // waste ID + quantityRange: { + min: number // t/day + max: number // t/day + } + contact: { + name: string + email?: string + phone?: string + address?: string + } + collectionType: string + distance: number // km +} + +// Investor +export interface Investor extends BaseEntity { + name: string + type: string + amountRange: { + min: number // € + max: number // € + } + geographicRegions: string[] + wasteRange: { + min: number // t/day + max: number // t/day + } + wasteTypes: string[] // waste IDs + solarPanelsRange: { + min: number // kW + max: number // kW + } +} + +// Administrative Procedure +export type ProcedureType = 'ICPE' | 'spreading' | 'other' +export type ProcedureStatus = 'toDo' | 'done' | 'na' + +export interface AdministrativeProcedure extends BaseEntity { + name: string + type: ProcedureType + delays: number // days + contact: { + name: string + email?: string + phone?: string + organization?: string + } + regions: string[] +} + +// Project +export interface ProjectAdministrativeProcedure { + procedureId: string + status: ProcedureStatus +} + +export interface ProjectInvestment { + investorId: string + status: SiteStatus + amount: number // € +} + +export interface WasteCharacteristicsOverride { + wasteId?: string + bmp?: number + waterPercentage?: number + regulatoryNeeds?: string[] +} + +export interface BusinessPlanRevenues { + rawRental: number[] // 10 years, €/year + biologicalTreatment: number[] + bitcoinManagement: number[] + fertilizers: number[] + wasteHeat: number[] + carbonCredits: number[] + brownfield: number[] + transport: number[] + commercialPartnerships: number[] + other: number[] +} + +export interface BusinessPlanVariableCosts { + rentalServices: number[] // 10 years, €/year + commissions: number[] + otherVariable: number[] + transport: number[] +} + +export interface BusinessPlanFixedCosts { + salaries: number[] // 10 years, €/year + marketing: number[] + rd: number[] + administrative: number[] + otherGeneral: number[] +} + +export interface BusinessPlanInvestments { + equipment: number[] // 10 years, €/year + technology: number[] + patents: number[] +} + +export interface BusinessPlanUseOfFunds { + productDevelopment: number[] // 10 years, €/year + marketing: number[] + team: number[] + structure: number[] +} + +export interface BusinessPlanKPIs { + activeUsers: number[] // 10 years + cac: number[] // € + ltv: number[] // € + breakEvenDays: number[] +} + +export interface BusinessPlan { + revenues: BusinessPlanRevenues + variableCosts: BusinessPlanVariableCosts + fixedCosts: BusinessPlanFixedCosts + investments: BusinessPlanInvestments + useOfFunds: BusinessPlanUseOfFunds + kpis: BusinessPlanKPIs +} + +export interface Project extends BaseEntity { + name: string + startDate: string // ISO 8601 + endDate: string // ISO 8601 + treatmentSiteId: string + collectionSiteIds: string[] + numberOfModules: number + transportBySite: boolean + wasteCharacteristicsOverride?: WasteCharacteristicsOverride + administrativeProcedures: ProjectAdministrativeProcedure[] + investments: ProjectInvestment[] + businessPlan?: BusinessPlan +} + +// Storage structure +export interface StorageData { + version: string + lastModified: string + users: User[] + wastes: Waste[] + regulators: NaturalRegulator[] + services: Service[] + treatmentSites: TreatmentSite[] + wasteSites: WasteSite[] + investors: Investor[] + administrativeProcedures: AdministrativeProcedure[] + projects: Project[] +} diff --git a/src/utils/calculations/yields.ts b/src/utils/calculations/yields.ts new file mode 100644 index 0000000..2825923 --- /dev/null +++ b/src/utils/calculations/yields.ts @@ -0,0 +1,108 @@ +import { Project, Waste, TreatmentSite } from '@/types' +import { PHYSICAL_CONSTANTS, EFFICIENCY_FACTORS, GAS_COMPOSITION, MODULE_CONFIG, MODULE_ELECTRICAL_CONSUMPTION, BITCOIN_CONFIG } from '@/utils/constants' + +export interface YieldsResult { + water: number // t/day + fertilizer: number // t/day + methane: number // m³/day + co2: number // m³/day + heatEnergyKJ: number // kJ/day + heatEnergyKWh: number // kW.h/day + electricalPowerBiogas: number // kW + electricalPowerSolar: number // kW + totalElectricalPower: number // kW + modulesConsumption: number // kW + netElectricalPower: number // kW + numberOfFlexMiners: number + bitcoinsPerYear: number // BTC/year +} + +export function calculateYields(project: Project, waste: Waste | undefined, treatmentSite: TreatmentSite | undefined): YieldsResult { + if (!waste || !treatmentSite) { + return getEmptyYields() + } + + const numberOfModules = project.numberOfModules + const wastePerModule = MODULE_CONFIG.CAPACITY_PER_MODULE // 67T + const totalWaste = wastePerModule * numberOfModules // T/day + const waterPercentage = project.wasteCharacteristicsOverride?.waterPercentage || waste.waterPercentage + const bmp = project.wasteCharacteristicsOverride?.bmp || waste.bmp + + // Water calculations + const waterInput = (totalWaste * waterPercentage) / 100 // T/day + const dryMatterPercentage = 100 - waterPercentage + const dryMatter = (totalWaste * dryMatterPercentage) / 100 // T/day = kg VS/day (assuming 1T = 1000kg) + + // Methane production + const dryMatterKg = dryMatter * 1000 // kg VS/day + const methaneProduction = bmp * dryMatterKg * EFFICIENCY_FACTORS.METHANE_PRODUCTION_EFFICIENCY // m³/day + + // Biogas composition (60% CO₂, 40% CH₄) + const biogasTotal = methaneProduction / GAS_COMPOSITION.METHANE_PERCENTAGE // m³/day + const co2Production = biogasTotal * GAS_COMPOSITION.CO2_PERCENTAGE // m³/day + + // Energy calculations + const heatEnergyKJ = methaneProduction * PHYSICAL_CONSTANTS.METHANE_ENERGY_CONTENT * EFFICIENCY_FACTORS.COMBUSTION_EFFICIENCY // kJ/day + const heatEnergyKWh = heatEnergyKJ * PHYSICAL_CONSTANTS.KJ_TO_KWH // kW.h/day + + // Electrical power from biogas + const electricalPowerBiogas = (methaneProduction * PHYSICAL_CONSTANTS.METHANE_ENERGY_CONTENT * EFFICIENCY_FACTORS.ELECTRICAL_CONVERSION_EFFICIENCY) / (PHYSICAL_CONSTANTS.KWH_TO_KJ * PHYSICAL_CONSTANTS.HOURS_PER_DAY) // kW + + // Electrical power from solar panels (approximate) + const solarPanelSurface = treatmentSite.availableGroundSurface * 0.3 // Approximate 30% coverage + const averageIrradiance = EFFICIENCY_FACTORS.SOLAR_IRRADIANCE_AVERAGE + const electricalPowerSolar = solarPanelSurface * averageIrradiance * EFFICIENCY_FACTORS.SOLAR_PANEL_EFFICIENCY // kW + + // Total electrical power + const totalElectricalPower = electricalPowerBiogas + electricalPowerSolar + + // Module consumption + const modulesConsumption = MODULE_ELECTRICAL_CONSUMPTION.TOTAL_PER_MODULE * numberOfModules // kW + + // Net electrical power + const netElectricalPower = totalElectricalPower - modulesConsumption + + // Bitcoin mining + const numberOfFlexMiners = Math.floor(Math.max(0, netElectricalPower) / BITCOIN_CONFIG.POWER_PER_FLEX_MINER) + const bitcoinsPerYear = numberOfFlexMiners > 0 ? (BITCOIN_CONFIG.BTC_CALCULATION_CONSTANT * BITCOIN_CONFIG.BTC_PER_FLEX_MINER_FACTOR) / numberOfFlexMiners : 0 + + // Water output (simplified - water from spiruline cycle returns to thermophilic) + const waterOutput = waterInput * 0.9 // Approximate 90% recovery (10% evaporation) + + // Fertilizer production (100% of compost) + const fertilizerOutput = dryMatter * EFFICIENCY_FACTORS.FERTILIZER_YIELD_FACTOR // t/day + + return { + water: waterOutput, + fertilizer: fertilizerOutput, + methane: methaneProduction, + co2: co2Production, + heatEnergyKJ, + heatEnergyKWh, + electricalPowerBiogas, + electricalPowerSolar, + totalElectricalPower, + modulesConsumption, + netElectricalPower, + numberOfFlexMiners, + bitcoinsPerYear, + } +} + +function getEmptyYields(): YieldsResult { + return { + water: 0, + fertilizer: 0, + methane: 0, + co2: 0, + heatEnergyKJ: 0, + heatEnergyKWh: 0, + electricalPowerBiogas: 0, + electricalPowerSolar: 0, + totalElectricalPower: 0, + modulesConsumption: 0, + netElectricalPower: 0, + numberOfFlexMiners: 0, + bitcoinsPerYear: 0, + } +} diff --git a/src/utils/constants.ts b/src/utils/constants.ts new file mode 100644 index 0000000..cc44020 --- /dev/null +++ b/src/utils/constants.ts @@ -0,0 +1,299 @@ +/** + * Constants and Default Values for 4NK Waste & Water Simulator + * All values are realistic defaults that can be adjusted + */ + +// ============================================================================ +// PHYSICAL CONSTANTS +// ============================================================================ + +export const PHYSICAL_CONSTANTS = { + // Energy content + METHANE_ENERGY_CONTENT: 35800, // kJ/m³ (lower heating value) + WATER_DENSITY: 1, // t/m³ + + // Carbon conversions + CARBON_TO_CO2_RATIO: 3.67, // 1 tC = 3.67 tCO₂e + CO2_TO_CARBON_RATIO: 0.272, // 1 tCO₂e = 0.272 tC + + // Energy conversions + KJ_TO_KWH: 1 / 3600, // 1 kJ = 1/3600 kW.h + KWH_TO_KJ: 3600, // 1 kW.h = 3600 kJ + + // Time conversions + HOURS_PER_DAY: 24, + DAYS_PER_YEAR: 365, + DAYS_PER_LEAP_YEAR: 366, +} as const; + +// ============================================================================ +// PROCESS EFFICIENCY FACTORS +// ============================================================================ + +export const EFFICIENCY_FACTORS = { + // Anaerobic digestion + METHANE_PRODUCTION_EFFICIENCY: 0.80, // 80% of theoretical BMP + COMBUSTION_EFFICIENCY: 0.90, // 90% for heat production + ELECTRICAL_CONVERSION_EFFICIENCY: 0.40, // 40% for CHP systems + + // Solar panels + SOLAR_PANEL_EFFICIENCY: 0.20, // 20% average efficiency + SOLAR_IRRADIANCE_AVERAGE: 0.15, // kW/m² average (varies by location) + + // Composting + FERTILIZER_YIELD_FACTOR: 1.0, // 100% of compost becomes fertilizer + + // Water processes + WATER_EVAPORATION_RATE: 0.005, // m/day (varies with conditions) +} as const; + +// ============================================================================ +// GAS COMPOSITION +// ============================================================================ + +export const GAS_COMPOSITION = { + METHANE_PERCENTAGE: 0.40, // 40% methane in biogas + CO2_PERCENTAGE: 0.60, // 60% CO₂ in biogas +} as const; + +// ============================================================================ +// MODULE CONFIGURATION +// ============================================================================ + +export const MODULE_CONFIG = { + CAPACITY_PER_MODULE: 67, // T of waste at 75% water + WATER_PERCENTAGE: 75, // % water in waste + CONTAINERS_PER_MODULE: 4, + TOTAL_MODULES: 21, +} as const; + +// ============================================================================ +// PROCESSING TIMES (days) +// ============================================================================ + +export const PROCESSING_TIMES = { + MESOPHILIC_HYGIENIZATION: 18, + MESOPHILIC_ADDITIONAL: 3, + MESOPHILIC_TOTAL: 21, + + DRYING: 21, + BIOREMEDIATION_PHASES: 3, + BIOREMEDIATION_PHASE_DURATION: 21, + + THERMOPHILIC_DIGESTION: 18, + COMPOSTING: 3, + THERMOPHILIC_COMPOSTING_TOTAL: 21, + + SPIRULINA_CYCLE_DAYS: 21, // 21 days before return to thermophilic + SPIRULINA_CYCLE_HOURS: 72, // Initial cycle duration +} as const; + +// ============================================================================ +// ELECTRICAL CONSUMPTION PER MODULE (kW) +// ============================================================================ + +export const MODULE_ELECTRICAL_CONSUMPTION = { + PUMP_METHANISATION: 0.5, + SECHOIR_GAZ: 2.0, + COMPRESSEUR: 3.0, + LAMPE_UV_C_12M: 0.3, + RACLOIRES_ELECTRIQUES: 1.5, // 5 × 3 = 1.5 kW + POMPE_SPIRULINE: 0.5, + LED_CULTURE: 0.6, // 5 × 12m LED + POMPES_EAU: 1.5, // 3 pumps + CAPTEURS: 0.1, + SERVEUR: 0.2, + BORNE_STARLINK: 0.1, + TABLEAU_ELEC: 0.1, + CONVERTISSEUR_SOLAIRE: 0.1, + + // Total per module + TOTAL_PER_MODULE: 10.5, +} as const; + +// ============================================================================ +// BITCOIN MINING +// ============================================================================ + +export const BITCOIN_CONFIG = { + POWER_PER_FLEX_MINER: 2, // kW per 4NK flex miner + BTC_PER_FLEX_MINER_FACTOR: 0.0001525, + BTC_CALCULATION_CONSTANT: 79.2, + BITCOIN_PRICE_EUR: 100000, // €/BTC +} as const; + +// ============================================================================ +// VALORIZATION PARAMETERS (€) +// ============================================================================ + +export const VALORIZATION_PARAMS = { + WASTE_TREATMENT_PER_TONNE: 100, // €/t + FERTILIZER_PER_TONNE: 215, // €/t + HEAT_PER_TONNE: 0.12, // €/t + + // Carbon equivalents + CARBON_CH4_BURNED_PER_TC: 630, // €/tC + CARBON_CH4_BURNED_PER_TCO2E: 172, // €/tCO₂e (630 / 3.67) + CARBON_CO2_SEQUESTERED_PER_TC: 100, // €/tC + CARBON_CO2_SEQUESTERED_PER_TCO2E: 27, // €/tCO₂e (100 / 3.67) + CARBON_ELECTRICITY_AVOIDED_PER_KW: 0.12, // €/kW + + // Land + BROWNFIELD_AREA: 4000, // m² + BROWNFIELD_VALORIZATION_RATE: 50, // €/m² (configurable) +} as const; + +// ============================================================================ +// VALIDATION LIMITS +// ============================================================================ + +export const VALIDATION_LIMITS = { + // Percentages + WATER_PERCENTAGE_MIN: 0, + WATER_PERCENTAGE_MAX: 100, + + // BMP + BMP_MIN: 0.1, // Nm³ CH₄/kg VS + BMP_MAX: 1.0, // Nm³ CH₄/kg VS + + // Quantities + QUANTITY_MIN: 0, + QUANTITY_MAX: 100000, // T/day + + // Modules + MODULES_MIN: 1, + MODULES_MAX: 100, + + // Dates + PROJECT_DURATION_MIN_DAYS: 1, + PROJECT_DURATION_MAX_DAYS: 3650, // 10 years + + // Financial + FINANCIAL_MIN: 0, + FINANCIAL_MAX: 1000000000, // 1 billion € + + // Efficiency factors + EFFICIENCY_MIN: 0, + EFFICIENCY_MAX: 1, + + // Temperature + TEMPERATURE_MIN: -50, // °C + TEMPERATURE_MAX: 60, // °C + + // Altitude + ALTITUDE_MIN: -100, // meters (below sea level) + ALTITUDE_MAX: 5000, // meters + + // Surface + SURFACE_MIN: 0, // m² + SURFACE_MAX: 1000000, // m² (1 km²) + + // Distance + DISTANCE_MIN: 0, // km + DISTANCE_MAX: 10000, // km +} as const; + +// ============================================================================ +// DEFAULT VALUES FOR CONFIGURATION +// ============================================================================ + +export const DEFAULT_VALUES = { + // Waste defaults + WASTE: { + BMP: 0.4, // Nm³ CH₄/kg VS (average) + WATER_PERCENTAGE: 75, + MAX_STORAGE_DURATION: 30, // days + }, + + // Processing defaults + PROCESSING: { + METHANE_EFFICIENCY: EFFICIENCY_FACTORS.METHANE_PRODUCTION_EFFICIENCY, + ELECTRICAL_EFFICIENCY: EFFICIENCY_FACTORS.ELECTRICAL_CONVERSION_EFFICIENCY, + COMBUSTION_EFFICIENCY: EFFICIENCY_FACTORS.COMBUSTION_EFFICIENCY, + }, + + // Solar defaults + SOLAR: { + PANEL_EFFICIENCY: EFFICIENCY_FACTORS.SOLAR_PANEL_EFFICIENCY, + IRRADIANCE: EFFICIENCY_FACTORS.SOLAR_IRRADIANCE_AVERAGE, + PANEL_SURFACE_PER_CONTAINER: 30, // m² (approximate) + }, + + // Project defaults + PROJECT: { + DURATION_YEARS: 10, + FIRST_YEAR_PROTOTYPE_DISCOUNT: 0.7, // 70% of standard price + }, + + // Business plan defaults + BUSINESS_PLAN: { + GROWTH_RATE_REVENUE: 0.05, // 5% per year + INFLATION_RATE_COSTS: 0.02, // 2% per year + }, +} as const; + +// ============================================================================ +// CALCULATION CONSTANTS +// ============================================================================ + +export const CALCULATION_CONSTANTS = { + // Bitcoin calculation + BTC_YEARLY_BASE: BITCOIN_CONFIG.BTC_CALCULATION_CONSTANT, + BTC_PER_MINER: BITCOIN_CONFIG.BTC_PER_FLEX_MINER_FACTOR, + + // Water calculations + EVAPORATION_SURFACE_FACTOR: 1.0, // m² per module (water wall) + + // Spirulina + SPIRULINA_WATER_OUTPUT_PER_CYCLE: 5, // T (example, to be adjusted) +} as const; + +// ============================================================================ +// STATUS VALUES +// ============================================================================ + +export const STATUS_VALUES = { + TO_BE_APPROACHED: 'toBeApproached', + LOI_OK: 'loiOk', + IN_PROGRESS: 'inProgress', + COMPLETED: 'completed', + TO_DO: 'toDo', + DONE: 'done', + NA: 'na', +} as const; + +// ============================================================================ +// SERVICE TYPES +// ============================================================================ + +export const SERVICE_TYPES = { + RAW_RENTAL: 'rawRental', + BIOLOGICAL_TREATMENT: 'biologicalTreatment', + BITCOIN_MANAGEMENT: 'bitcoinManagement', + FERTILIZERS: 'fertilizers', + WASTE_HEAT: 'wasteHeat', + CARBON_CREDITS: 'carbonCredits', + BROWNFIELD: 'brownfield', + TRANSPORT: 'transport', +} as const; + +// ============================================================================ +// WASTE ORIGIN TYPES +// ============================================================================ + +export const WASTE_ORIGIN_TYPES = { + ANIMALS: 'animals', + MARKETS: 'markets', + RESTAURANTS: 'restaurants', + OTHER: 'other', +} as const; + +// ============================================================================ +// ADMINISTRATIVE PROCEDURE TYPES +// ============================================================================ + +export const PROCEDURE_TYPES = { + ICPE: 'ICPE', + SPREADING: 'spreading', + OTHER: 'other', +} as const; diff --git a/src/utils/formatters.ts b/src/utils/formatters.ts new file mode 100644 index 0000000..87acc70 --- /dev/null +++ b/src/utils/formatters.ts @@ -0,0 +1,21 @@ +export function formatCurrency(value: number): string { + return new Intl.NumberFormat('fr-FR', { + style: 'currency', + currency: 'EUR', + }).format(value) +} + +export function formatNumber(value: number, decimals: number = 2): string { + return new Intl.NumberFormat('fr-FR', { + minimumFractionDigits: decimals, + maximumFractionDigits: decimals, + }).format(value) +} + +export function formatDate(dateString: string): string { + return new Date(dateString).toLocaleDateString('fr-FR') +} + +export function formatDateTime(dateString: string): string { + return new Date(dateString).toLocaleString('fr-FR') +} diff --git a/src/utils/seedData.ts b/src/utils/seedData.ts new file mode 100644 index 0000000..4419bd7 --- /dev/null +++ b/src/utils/seedData.ts @@ -0,0 +1,32 @@ +import { StorageData } from '@/types' +import { seedWastes } from '@/data/seedWastes' +import { seedRegulators } from '@/data/seedRegulators' +import { initializeStorage } from './storage' + +export function loadSeedData(): StorageData { + const data = initializeStorage() + + // Add seed wastes + data.wastes = seedWastes + + // Add seed regulators + data.regulators = seedRegulators + + return data +} + +export function addSeedDataToExisting(data: StorageData): StorageData { + // Only add wastes that don't already exist + const existingWasteIds = new Set(data.wastes.map(w => w.id)) + const newWastes = seedWastes.filter(w => !existingWasteIds.has(w.id)) + + // Only add regulators that don't already exist + const existingRegulatorIds = new Set(data.regulators.map(r => r.id)) + const newRegulators = seedRegulators.filter(r => !existingRegulatorIds.has(r.id)) + + return { + ...data, + wastes: [...data.wastes, ...newWastes], + regulators: [...data.regulators, ...newRegulators], + } +} diff --git a/src/utils/storage.ts b/src/utils/storage.ts new file mode 100644 index 0000000..f1d29c7 --- /dev/null +++ b/src/utils/storage.ts @@ -0,0 +1,103 @@ +import { StorageData } from '@/types' + +const STORAGE_KEY = '4nkwaste_simulator_data' +const USER_KEY = '4nkwaste_simulator_user' +const VERSION_KEY = '4nkwaste_simulator_version' + +const CURRENT_VERSION = '1.0.0' + +// Initialize empty storage +export function initializeStorage(): StorageData { + return { + version: CURRENT_VERSION, + lastModified: new Date().toISOString(), + users: [], + wastes: [], + regulators: [], + services: [], + treatmentSites: [], + wasteSites: [], + investors: [], + administrativeProcedures: [], + projects: [], + } +} + +// Load data from localStorage +export function loadStorage(): StorageData { + try { + const data = localStorage.getItem(STORAGE_KEY) + if (!data) { + return initializeStorage() + } + return JSON.parse(data) as StorageData + } catch (error) { + console.error('Error loading storage:', error) + return initializeStorage() + } +} + +// Save data to localStorage +export function saveStorage(data: StorageData): void { + try { + data.lastModified = new Date().toISOString() + data.version = CURRENT_VERSION + localStorage.setItem(STORAGE_KEY, JSON.stringify(data)) + } catch (error) { + console.error('Error saving storage:', error) + throw new Error('Failed to save data. Storage may be full.') + } +} + +// Export data as JSON +export function exportData(): string { + const data = loadStorage() + return JSON.stringify(data, null, 2) +} + +// Import data from JSON (replaces all data) +export function importData(jsonString: string): { success: boolean; errors: string[] } { + const errors: string[] = [] + + try { + const data = JSON.parse(jsonString) as StorageData + + // Validate structure + if (!data.version) errors.push('Missing version') + if (!Array.isArray(data.wastes)) errors.push('Invalid wastes array') + if (!Array.isArray(data.regulators)) errors.push('Invalid regulators array') + if (!Array.isArray(data.services)) errors.push('Invalid services array') + if (!Array.isArray(data.treatmentSites)) errors.push('Invalid treatmentSites array') + if (!Array.isArray(data.wasteSites)) errors.push('Invalid wasteSites array') + if (!Array.isArray(data.investors)) errors.push('Invalid investors array') + if (!Array.isArray(data.administrativeProcedures)) errors.push('Invalid administrativeProcedures array') + if (!Array.isArray(data.projects)) errors.push('Invalid projects array') + + if (errors.length > 0) { + return { success: false, errors } + } + + // Validate references (basic check) + // TODO: Add more comprehensive validation + + // Replace storage + saveStorage(data) + return { success: true, errors: [] } + } catch (error) { + errors.push(`Invalid JSON: ${error instanceof Error ? error.message : 'Unknown error'}`) + return { success: false, errors } + } +} + +// User session management +export function saveUserSession(username: string): void { + localStorage.setItem(USER_KEY, username) +} + +export function getUserSession(): string | null { + return localStorage.getItem(USER_KEY) +} + +export function clearUserSession(): void { + localStorage.removeItem(USER_KEY) +} diff --git a/src/utils/validators.ts b/src/utils/validators.ts new file mode 100644 index 0000000..2eafc48 --- /dev/null +++ b/src/utils/validators.ts @@ -0,0 +1,52 @@ +export function validateRequired(value: string | number | undefined): string | undefined { + if (value === undefined || value === null || value === '') { + return 'This field is required' + } + return undefined +} + +export function validateNumber(value: string | number | undefined, min?: number, max?: number): string | undefined { + if (value === undefined || value === null || value === '') { + return 'This field is required' + } + const num = typeof value === 'string' ? parseFloat(value) : value + if (isNaN(num)) { + return 'Must be a valid number' + } + if (min !== undefined && num < min) { + return `Must be at least ${min}` + } + if (max !== undefined && num > max) { + return `Must be at most ${max}` + } + return undefined +} + +export function validatePercentage(value: string | number | undefined): string | undefined { + const error = validateNumber(value, 0, 100) + if (error) return error + return undefined +} + +export function validateDate(value: string | undefined): string | undefined { + if (!value) { + return 'This field is required' + } + const date = new Date(value) + if (isNaN(date.getTime())) { + return 'Must be a valid date' + } + return undefined +} + +export function validateDateRange(startDate: string | undefined, endDate: string | undefined): string | undefined { + if (!startDate || !endDate) { + return undefined + } + const start = new Date(startDate) + const end = new Date(endDate) + if (end < start) { + return 'End date must be after start date' + } + return undefined +} diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..8f26f51 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,36 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + + /* Path aliases */ + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"], + "@/components/*": ["./src/components/*"], + "@/pages/*": ["./src/pages/*"], + "@/hooks/*": ["./src/hooks/*"], + "@/utils/*": ["./src/utils/*"], + "@/types/*": ["./src/types/*"] + } + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..42872c5 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/user_workflow.md b/user_workflow.md new file mode 100644 index 0000000..9858e4e --- /dev/null +++ b/user_workflow.md @@ -0,0 +1,334 @@ +# User Workflow and User Journey + +## 1. First Time User Journey + +### 1.1 Initial Setup +1. **Application Launch** + - User opens application in browser (localhost) + - Application checks for existing data + - If no data: Show welcome screen with option to start with seed data or empty + +2. **Login** + - User sees login page + - Enter username and password (first time: create account) + - Simple authentication (stored in localStorage) + - Redirect to Dashboard + +3. **Dashboard Overview** + - User sees empty dashboard or welcome message + - Quick access to key actions: + - "Create your first project" + - "Configure waste types" + - "View documentation" + +### 1.2 Recommended Initial Configuration Order +1. **Configure Waste Types** (`/configuration/waste`) + - Create at least one waste type + - Define BMP, water percentage, characteristics + - This is needed for projects + +2. **Configure Natural Regulators** (`/configuration/regulators`) + - Create regulators if needed for waste treatment + - Define characteristics and dosage + +3. **Configure Services** (`/configuration/services`) + - Set up service pricing for 10 years + - Configure all 8 services + - This is needed for business plan calculations + +4. **Create Treatment Site** (`/projects/treatment-sites`) + - Create at least one treatment site + - Define location, temperatures, surface + - Subscribe to services + +5. **Create Waste Site** (`/projects/waste-sites`) + - Create waste collection sites + - Link to waste types + - Define quantities and distance + +6. **Create Project** (`/projects`) + - Create first project + - Link to treatment site and waste sites + - Configure modules and dates + +7. **View Yields** (`/yields`) + - See calculated yields for the project + - Review formulas and calculations + +8. **Business Plan** (`/business-plan`) + - Configure financial data + - View projections over 10 years + +## 2. Typical User Workflow + +### 2.1 Creating a New Project + +**Step 1: Project Basic Information** +- Navigate to `/projects` +- Click "Create New Project" +- Fill in: + - Project name + - Start date - End date + - Number of modules + +**Step 2: Link Sites** +- Select treatment site (required) +- Select one or more waste sites (required) +- Configure transport (Yes/No) + +**Step 3: Configure Waste** +- Select primary waste type +- Optionally override waste characteristics +- Add regulatory wastes if needed +- Add natural regulators if needed + +**Step 4: Administrative Procedures** +- Add required procedures (ICPE, spreading, etc.) +- Set status for each procedure + +**Step 5: Investments** +- Add investors if applicable +- Set status and amount + +**Step 6: View Results** +- Navigate to Yields page +- Review all calculated outputs +- Check formulas and parameters + +**Step 7: Business Plan** +- Navigate to Business Plan page +- Configure revenues (auto-filled from services) +- Configure variable costs +- Configure fixed costs +- Configure investments +- Review financial projections + +### 2.2 Modifying an Existing Project + +1. Navigate to `/projects` +2. Click on project to edit +3. Modify any field +4. Changes are saved automatically (or on blur) +5. Recalculations happen automatically +6. User can see updated yields and business plan + +### 2.3 Viewing Yields + +1. Navigate to `/yields` +2. Select project from dropdown (if multiple projects) +3. View all calculated outputs: + - Material outputs (water, fertilizer) + - Gas outputs (methane, CO₂) + - Energy outputs (heat, electricity) + - Bitcoin production +4. Expand formula sections to see calculations +5. Export data if needed + +### 2.4 Analyzing Business Plan + +1. Navigate to `/business-plan` +2. Select project +3. Review project header (dates, sites, modules) +4. Review economic characteristics (year by year) +5. Review pricing characteristics (valorizations) +6. Analyze KPIs (CAC, LTV, break-even) +7. Export report + +## 3. Configuration Workflow + +### 3.1 Configuring Waste Types +1. Navigate to `/configuration/waste` +2. Click "Add Waste Type" +3. Fill in form: + - Name + - Origin type and subtype + - BMP value + - Water percentage + - Origin units per 1000m³ methane + - Regulatory needs + - Maximum storage duration +4. Save +5. Waste type available for projects + +### 3.2 Configuring Services +1. Navigate to `/configuration/services` +2. Select service to configure +3. Enter pricing for each year (1-10) +4. First year can have different pricing (prototype) +5. Save +6. Service pricing used in business plan calculations + +### 3.3 Configuring Treatment Site +1. Navigate to `/projects/treatment-sites` +2. Click "Add Treatment Site" +3. Fill in: + - Name + - Status + - Altitude + - Available surface + - Monthly temperatures (12 values) + - Subscribe to services +4. Save +5. Site available for projects + +## 4. Data Management Workflow + +### 4.1 Exporting Data +1. Navigate to `/settings` +2. Click "Export Data" +3. JSON file downloads +4. Contains all application data + +### 4.2 Importing Data +1. Navigate to `/settings` +2. Click "Import Data" +3. Select JSON file +4. System validates data: + - Structure validity + - Required fields + - Value constraints + - Reference integrity +5. If valid: Replace all data +6. If invalid: Show errors, keep existing data + +### 4.3 Backup Strategy +- User exports data regularly +- Data stored in browser (localStorage/IndexedDB) +- Export before major changes +- Import to restore previous state + +## 5. Error Handling Workflow + +### 5.1 Form Validation Errors +1. User fills form +2. Real-time validation (on blur or change) +3. Errors shown below fields: + - Red border on input + - Error message in red + - Help text if needed +4. User corrects errors +5. Errors clear when valid + +### 5.2 Calculation Errors +1. System detects calculation error (division by zero, etc.) +2. Shows error message in yields section +3. Indicates which calculation failed +4. Suggests correction (e.g., "Please set number of modules > 0") + +### 5.3 Data Integrity Errors +1. User tries to delete entity used in project +2. System shows warning: + - "This waste type is used in X projects" + - Option to cancel or force delete +3. If force delete: Remove from projects or set to null + +### 5.4 Import Errors +1. User imports invalid JSON +2. System shows detailed error list: + - Which entity has errors + - Which fields are invalid + - Which references are broken +3. User fixes JSON and retries + +## 6. Navigation Patterns + +### 6.1 Primary Navigation +- **Sidebar**: Always visible, main sections +- **Breadcrumbs**: Show current location +- **Header**: Project selector, user info, logout + +### 6.2 Quick Actions +- **Dashboard**: Quick links to common actions +- **Project List**: Quick actions (Edit, View BP, Delete) +- **Contextual Actions**: Buttons in relevant sections + +### 6.3 Deep Linking +- All pages have unique URLs +- Can bookmark specific projects +- Can share URLs (within localhost) + +## 7. User Feedback and Confirmation + +### 7.1 Success Messages +- "Project created successfully" +- "Data exported successfully" +- "Configuration saved" +- Toast notifications (top-right, auto-dismiss) + +### 7.2 Confirmation Dialogs +- Delete operations: "Are you sure you want to delete this project?" +- Import data: "This will replace all existing data. Continue?" +- Logout: "Are you sure you want to logout?" + +### 7.3 Loading States +- Form submission: Button shows spinner +- Calculations: "Calculating..." message +- Data load: Skeleton loaders + +### 7.4 Empty States +- No projects: "Create your first project" +- No yields: "Configure a project to see yields" +- No data: "Import seed data or start configuring" + +## 8. Recommended Order for New Users + +### Day 1: Setup +1. Login +2. Configure 2-3 waste types +3. Configure 1-2 natural regulators +4. Configure all 8 services (with default pricing) +5. Create 1 treatment site +6. Create 1-2 waste sites + +### Day 2: First Project +1. Create first project +2. Link sites +3. Configure waste +4. View yields +5. Configure business plan +6. Review results + +### Day 3: Refinement +1. Adjust configurations +2. Create additional projects +3. Compare scenarios +4. Export data + +## 9. Power User Workflow + +### 9.1 Multiple Projects +- Create multiple projects with different configurations +- Compare yields between projects +- Compare business plans +- Use project selector in header + +### 9.2 Advanced Configuration +- Override waste characteristics per project +- Customize service pricing per project +- Configure complex waste mixtures +- Multiple regulatory wastes and natural regulators + +### 9.3 Data Analysis +- Export data for external analysis +- Import modified data +- Version control via exports +- Backup before major changes + +## 10. Help and Documentation + +### 10.1 Contextual Help +- Help icons next to complex fields +- Tooltips on hover +- Formula explanations inline + +### 10.2 Documentation Access +- Help page (`/help`) with: + - User guide + - Formula reference + - FAQ + - Examples + +### 10.3 Onboarding +- First-time user: Show tooltips for key features +- Optional: Skip onboarding +- Can restart onboarding from settings diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..f7e05c4 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,18 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import path from 'path' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], + server: { + host: 'localhost', + port: 3000, + strictPort: true, + }, + resolve: { + alias: { + '@': path.resolve(__dirname, './src'), + }, + }, +})