diff --git a/docs-fr/calculators/pam/macrorugo.md b/docs-fr/calculators/pam/macrorugo.md
new file mode 100644
index 0000000000000000000000000000000000000000..6b4014b03e016a98e79878f67356ba4a731d7d77
--- /dev/null
+++ b/docs-fr/calculators/pam/macrorugo.md
@@ -0,0 +1,31 @@
+# Passe à macro-rugosité
+
+Le module de calcul passe à macro rugosité permet de calculer les caractéristiques d'une passe à macro-rugosité constituée de blocs uniformément répartis avec des espacements transversaux \(ay\) et longitudinaux \(ay\) égaux.
+
+![Schéma d'une disposition régulière des enrochements et notations](pam_schema_enrochement_regulier.png)
+
+*Extrait de Larinier et al., 2006[^1]*
+
+[^1]: Larinier, Michel, Courret, D., Gomes, P., 2006. Guide technique pour la conception des passes à poissons “naturelles,” Rapport GHAPPE RA. Compagnie Nationale du Rhône / Agence de l’Eau Adour Garonne. http://dx.doi.org/10.13140/RG.2.1.1834.8562
+
+
+L'outil permet de calculer l'une des valeurs suivantes :
+
+- La largeur de la passe (m) ;
+- La pente de la passe (m) ;
+- Le débit (m<sup>3</sup>/s) ;
+- La profondeur \(h\) (m) ;
+- La concentration des blocs \(C\).
+
+Il nécessite d'entrer les valeurs suivantes :
+
+- La cote de fond amont (m) ;
+- La longueur de la passe (m) ;
+- La rugosité de fond (m) ;
+- La largeur des blocs \(D\) face à l’écoulement (m) ;
+- La hauteur utile des blocs \(k\) (m) ;
+- Le paramètre de forme des blocs (1 pour rond, 2 pour carré)
+
+L'espacement entre les blocs se calcule ensuite avec la formule suivante :
+
+$$ax = ay = \frac{D}{\sqrt{C}}$$
diff --git a/docs-fr/calculators/pam/macrorugo_theorie.md b/docs-fr/calculators/pam/macrorugo_theorie.md
new file mode 100644
index 0000000000000000000000000000000000000000..328d5816ff5dffe166b796ce53f51a363e9457e0
--- /dev/null
+++ b/docs-fr/calculators/pam/macrorugo_theorie.md
@@ -0,0 +1,162 @@
+# Calcul du débit d'une passe à macro-rugosité
+
+Le calcul du débit d'une passe à macro-rugosité correspond à l'implémentation de l'algorithme et des équations présentent dans
+*Cassan L, Laurens P. 2016. Design of emergent and submerged rock-ramp fish passes. Knowl. Manag. Aquat. Ecosyst., 417, 45*.
+
+## Principe général du calcul
+
+
+La limite entre le cas émergent et le cas submergé se situe à \(h = 1.1 \times k\).
+
+## Cas submergé
+
+Le calcul du débit se fait par itérations successives qui consistent à trouver la valeur de débit permettant d'obtenir l'égalite entre la vitesse moyenne du lit donnée par&nbsp;:
+
+$$u_0 = \sqrt{2 g S D (1 - \sigma C)/(C_d C)}$$
+
+et la vitesse moyenne du lit donnée par intégration des débits entre et au-dessus des blocs&nbsp;:
+
+$$\bar{u} = \frac{Q_{inf} + Q_{sup}}{k}$$
+
+avec respectivement \(Q_{inf}\) et \(Q_{sup}\) les débits unitaires pour la partie dans la canopée et la partie au dessus de la canopée.
+
+### Calcul du débit unitaire *Q<sub>inf</sub>* dans la canopée
+
+Le débit dans la canopée est obtenu par intégration du profil de vitesse (Eq. 9, Cassan et al., 2016)&nbsp:
+
+$$Q_{inf} = \int_{0}^1 u(\tilde{z}) d \tilde{z}$$
+
+avec
+
+$$u(\tilde{z}) = u_0 \sqrt{\beta \left( \frac{h}{k} -1 \right) \frac{\sinh(\beta \tilde{z})}{\cosh(\beta)} + 1}$$
+
+avec
+
+$$\beta = \sqrt{(k / \alpha_t)(C_d C k / D)/(1 - \sigma C)}$$
+
+avec \(\sigma = 1\) pour \(C_{d0} = 2\), \(\sigma = \pi/4\) sinon
+
+et \(\alpha_t\) obtenu à partir de la résolution de l'équation suivante :
+
+$$\alpha_t u(1) - l_0 u_* = 0$$
+
+avec
+
+$$l_0 = \min \left( s, 0.15 k \right)$$
+
+avec
+
+$$s = D \left( \frac{1}{\sqrt{C}} - 1 \right)$$
+
+### Calcul du débit unitaire *Q<sub>sup</sub>* au dessus de la canopée
+
+$$Q_{sup} = \int_k^h u(z) dz$$
+
+avec (Eq. 12, Cassan et al., 2016)
+
+$$u(z) = \frac{u_*}{\kappa} \ln \left( \frac{z - d}{z_0} \right) - 1 $$
+
+avec (Eq. 14, Cassan et al., 2016)
+
+$$z_0 = (k - d) \exp \left( {\frac{-\kappa u_k}{u_*}} \right)$$
+
+et (Eq. 13, Cassan et al., 2016)
+
+$$ d =  k - \frac{\alpha_t u_k}{\kappa u_*}$$
+
+ce qui donne
+
+$$Q_{sup} = \frac{u_*}{\kappa} \left( (h - d) \left( \ln \left( \frac{h-d}{z_0} \right) - 1\right)  - \left( (k - d) \left( \ln \left( \frac{k-d}{z_0} \right) - 1 \right) \right) \right)$$
+
+## Cas émergent
+
+Le calcul du débit se fait par itérations successives qui consistent à trouver la valeur de débit permettant d'obtenir l'égalité entre la vitesse apparente \(V\) et la vitesse moyenne du lit donnée par&nbsp;:
+
+$$u_0 = \sqrt{\frac{2 g S D (1 - \sigma C)}{C_d C (1 + N)}}$$
+
+avec
+
+$$C_d = C_{d0} (1 + 0.4 / h_*^2) f_F(F)$$
+
+$$N = \frac{\alpha C_f}{C_d C h_*}$$
+
+avec
+
+$$\alpha = 1 - (a_y / a_x \times C)$$
+
+## Formules utilisées
+
+### Vitesse débitante *V*
+
+$$V = \frac{Q}{B \times h}$$
+
+### Vitesse entre les blocs *V<sub>g</sub>*
+
+$$V_g = \frac{V}{1 - \sqrt{(a_x/a_y)C}}$$
+
+### Froude *F*
+
+$$F = \frac{V_g}{\sqrt{gh}}$$
+
+### Fonction de correction du coefficient de trainée liée au Froude *f<sub>F</sub>(F)*
+
+Si \(F < 1.3\) (Eq. 5, Cassan et al., 2016)
+
+$$f_F(F) = \mathrm{min} \left( \frac{0.4 C_{d0} + 0.7}{1- (F^2 / 4)}, \frac{1}{F^{\frac{2}{3}}} \right)$$
+
+sinon
+
+$$f_F(F) = F^{\frac{-4}{3}}$$
+
+### Coefficient de friction du lit *C<inf>f</inf>*
+
+Si \(k_s < 10^{-6} \mathrm{m}\) alors
+
+$$C_f = 0.3164 / 4 * Re^{-0.25}$$
+
+avec
+
+$$Re = u_0 \times h / \nu$$
+
+Sinon (Eq. 3, Cassan et al., 2016)
+
+$$C_f = \frac{2}{(5.1 \mathrm{log} (h/k_s)+6)^2}$$
+
+### Vitesse de cisaillement *u<sub>&ast;</sub>*
+
+$$u_* = \sqrt{gS(h-k)}$$
+
+## Notations
+
+- \(\alpha\) : ratio de l'aire concernée par la friction du lits sur \(a_x \times a_y\)
+- \(\alpha_t\) : échelle de longueur de la turbulence dans la couche des blocs(m)
+- \(\beta\) : ratio entre la contrainte due à la trainée et la contrainte due aux turbulences
+- \(\kappa\) : constante de Von Karman = 0.41
+- \(\sigma\) : ratio entre l'aire du block dans le plan X,y et \(D^2\)
+- \(a_x\) :  largeur d'une cellule (perpendiculaire à l'écoulement) (m)
+- \(a_y\) :  longueur d'une cellule (parallèle à l'écoulement) (m)
+- \(B\) : largeur de la passe (m)
+- \(C\) : concentration de blocs
+- \(C_d\) : coefficient de trainée d'un bloc dans les conditions d'écoulement actuel
+- \(C_{d0}\) : coefficient de trainée d'un bloc considérant un bloc infiniment haut avec \(F \ll 1\)
+- \(C_f)\) : coefficient de friction du lit
+- \(d\) : déplacement dans le plan zéro du profil logarithmique (m)
+- \(D\) : largeur du bloc face à l'écoulement (m)
+- \(F\) : nombre de Froude basé sur \(h\) et \(V_g\)
+- \(g\) : accélération de la gravité = 9.81 m.s<sup>-2</sup>
+- \(h\) : profondeur moyenne (m)
+- \(h_*\) : profondeur adimensionnelle (\(h / D\))
+- \(k\) : hauteur utile des blocs (m)
+- \(k_s\) : hauteur de la rugosité (m)
+- \(l_0\) : échelle de longueur de la turbulence au sommet des blocs (m)
+- \(N\) : ratio entre la friction du lit et la force de trainée
+- \(Q\) : débit (m<sup>3</sup>/s)
+- \(S\) : pente de la passe (m/m)
+- \(u_0\) : vitesse moyenne dans le lit (m/s)
+- \(u_*\) : vitesse de cisaillement (m/s)
+- \(V\) : vitesse débitante (m/s)
+- \(V_g\) : vitesse entre les blocs (m/s)
+- \(s\) : distance minimale entre les blocs (m)
+- \(z\) : position verticale (m)
+- \(z_0\) : rugosité hydraulique (m)
+- \(\tilde{z}\) : position verticale adimensionnelle \(\tilde{z} = z / k\)
diff --git a/docs-fr/calculators/pam/pam_schema_enrochement_regulier.png b/docs-fr/calculators/pam/pam_schema_enrochement_regulier.png
new file mode 100755
index 0000000000000000000000000000000000000000..b8485ac803aaaae8e52355641e3e8cc4fc98c6df
Binary files /dev/null and b/docs-fr/calculators/pam/pam_schema_enrochement_regulier.png differ
diff --git a/jalhyd_branch b/jalhyd_branch
index 1f7391f92b6a3792204e07e99f71f643cc35e7e1..1708de1ed75a0c664861ea0bffa66800fa724d19 100644
--- a/jalhyd_branch
+++ b/jalhyd_branch
@@ -1 +1 @@
-master
+22-ajout-de-la-calculette-passe-a-enrochement-simple
diff --git a/mkdocs.yml b/mkdocs.yml
index 49160968803b799412254dd3ecc515ca38cf01b9..e19425da2ef8e5a6d94ec1d25d07a809ed3d1694 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -8,6 +8,7 @@ extra_javascript:
     - ../mathjax/MathJax.js?config=TeX-AMS_CHTML
 markdown_extensions:
     - mdx_math
+    - footnotes
 nav:
     - avant-propos.md
     - Présentation de Cassiopée:
@@ -28,5 +29,7 @@ nav:
             - Volume: calculators/pab/volume.md
             - Dimensions: calculators/pab/dimensions.md
             - Cloisons: calculators/pab/cloisons.md
-
+        - Passes à macro-rugosité:
+            - calculators/pam/macrorugo.md
+            - calculators/pam/macrorugo_theorie.md
 
diff --git a/src/app/calculators/cond_distri/cond_distri.fr.json b/src/app/calculators/cond_distri/cond_distri.fr.json
index c092d188e93466ecbe7924ca4fd2fe7c71365330..5d775d9dede334303c269471aadaf3cc2fd0035a 100644
--- a/src/app/calculators/cond_distri/cond_distri.fr.json
+++ b/src/app/calculators/cond_distri/cond_distri.fr.json
@@ -1,6 +1,5 @@
 {
     "fs_hydraulique": "Caractéristiques hydrauliques",
-    "Q": "Débit",
     "D": "Diamètre du tuyau",
     "J": "Perte de charge",
     "Lg": "Longueur du tuyau",
diff --git a/src/app/calculators/lechapt-calmon/lechapt-calmon.fr.json b/src/app/calculators/lechapt-calmon/lechapt-calmon.fr.json
index f3b6465da14b5fe31e8f0752672a27f472f9e096..2db51b945f5cacf25da4614be96179bc7f4bfe13 100644
--- a/src/app/calculators/lechapt-calmon/lechapt-calmon.fr.json
+++ b/src/app/calculators/lechapt-calmon/lechapt-calmon.fr.json
@@ -14,7 +14,6 @@
     "M": "M",
     "N": "N",
     "fs_hydraulique": "Caractéristiques hydrauliques",
-    "Q": "Débit",
     "D": "Diamètre du tuyau",
     "J": "Perte de charge",
     "Lg": "Longueur du tuyau",
diff --git a/src/app/calculators/macrorugo/macrorugo.config.json b/src/app/calculators/macrorugo/macrorugo.config.json
new file mode 100644
index 0000000000000000000000000000000000000000..1b693b635b223382faf411ac305ef33c8c18a690
--- /dev/null
+++ b/src/app/calculators/macrorugo/macrorugo.config.json
@@ -0,0 +1,94 @@
+[
+    {
+        "id": "fs_hydraulique_fix",
+        "type": "fieldset",
+        "option": "var",
+        "fields": [
+            {
+                "type": "input",
+                "id": "ZF1",
+                "unit": "m"
+            },
+            {
+                "type": "input",
+                "id": "L",
+                "unit": "m"
+            },
+            {
+                "type": "input",
+                "id": "Ks",
+                "unit": "m"
+            }
+        ]
+    },
+    {
+        "id": "fs_hydraulique_cal",
+        "type": "fieldset",
+        "option": "cal",
+        "fields": [
+            {
+                "type": "input",
+                "id": "B",
+                "unit": "m"
+            },
+            {
+                "type": "input",
+                "id": "If",
+                "unit": "m/m"
+            },
+            {
+                "type": "input",
+                "id": "Q",
+                "unit": "m³/s"
+            },
+            {
+                "type": "input",
+                "id": "Y",
+                "unit": "m"
+            },
+            {
+                "type": "input",
+                "id": "C",
+                "unit": ""
+            }
+        ]
+    },
+    {
+        "id": "fs_bloc",
+        "type": "fieldset",
+        "option": "var",
+        "fields": [
+            {
+                "type": "input",
+                "id": "PBD",
+                "unit": "m"
+            },
+            {
+                "type": "input",
+                "id": "PBH",
+                "unit": "m"
+            },
+            {
+                "type": "input",
+                "id": "Cd0",
+                "unit": ""
+            }
+        ]
+    },
+    {
+        "id": "fs_param_calc",
+        "type": "fieldset",
+        "option": "fix",
+        "fields": [
+            {
+                "type": "input",
+                "id": "Pr"
+            }
+        ]
+    },
+    {
+        "type": "options",
+        "idCal": "Q",
+        "help": "pam/macrorugo"
+    }
+]
\ No newline at end of file
diff --git a/src/app/calculators/macrorugo/macrorugo.fr.json b/src/app/calculators/macrorugo/macrorugo.fr.json
new file mode 100644
index 0000000000000000000000000000000000000000..0fb76a0b9ff14c1299c2f222a3f2d03a2d27921e
--- /dev/null
+++ b/src/app/calculators/macrorugo/macrorugo.fr.json
@@ -0,0 +1,15 @@
+{
+    "fs_hydraulique_fix": "Données hydrauliques fixées",
+    "fs_hydraulique_cal": "Données hydrauliques calculables",
+    "fs_bloc": "Paramètres des blocs",
+    "ZF1": "Cote de fond amont",
+    "L": "Longueur",
+    "B": "Largeur",
+    "If": "Pente",
+    "Y": "Profondeur",
+    "Ks": "Rugosité de fond",
+    "C": "Concentration de blocs",
+    "PBD": "Paramètre de bloc : Diamètre",
+    "PBH": "Paramètre de bloc : Hauteur",
+    "Cd0": "Paramètre de bloc : Forme (1 pour rond, 2 pour carré)"
+}
\ No newline at end of file
diff --git a/src/app/calculators/ouvrages/ouvrages.fr.json b/src/app/calculators/ouvrages/ouvrages.fr.json
index 6bb2421291ee456e3d6d56bbc8889a831c282133..16ac2c4c787d12539dea7db7ca98d213b6014776 100644
--- a/src/app/calculators/ouvrages/ouvrages.fr.json
+++ b/src/app/calculators/ouvrages/ouvrages.fr.json
@@ -24,7 +24,6 @@
     "fruit": "Fruit",
     "fs_surverse": "Surverse",
     "fs_hydraulique": "Caractéristiques globales",
-    "Q": "Débit",
     "Y_A": "Cote de l'eau à l'amont",
     "Y_a": "Cote de l'eau à l'aval"
 }
\ No newline at end of file
diff --git a/src/app/calculators/pab-puissance/pab-puissance.fr.json b/src/app/calculators/pab-puissance/pab-puissance.fr.json
index c3b45436cde69d54d545613658bb898603f97cfe..d1f891a181718cc68a16820a27332f8ec46a42e0 100644
--- a/src/app/calculators/pab-puissance/pab-puissance.fr.json
+++ b/src/app/calculators/pab-puissance/pab-puissance.fr.json
@@ -1,7 +1,6 @@
 {
     "fs_puissance": "Paramètres",
     "DH": "Chute entre bassins",
-    "Q": "Débit",
     "V": "Volume",
     "PV": "Puissance dissipée"
 }
\ No newline at end of file
diff --git a/src/app/calculators/parallel-structures/parallel-structures.config.json b/src/app/calculators/parallel-structures/parallel-structures.config.json
index cefbd84a989157a5452eba8987c25e8ccbd1fe6a..8ba966d2715785286851985709a4f8a68c2ccd1e 100644
--- a/src/app/calculators/parallel-structures/parallel-structures.config.json
+++ b/src/app/calculators/parallel-structures/parallel-structures.config.json
@@ -285,7 +285,7 @@
             {
                 "type": "input",
                 "id": "ZRAM",
-                "unit": "",
+                "unit": "m",
                 "nodeType": "StructureRectangle",
                 "dep_exist": [
                     {
diff --git a/src/app/calculators/regime-uniforme/regime-uniforme.fr.json b/src/app/calculators/regime-uniforme/regime-uniforme.fr.json
index 2b36f059c4f954ef5cdcbaf066b6914ecd721287..9b3bf77dbe38fa44707a4abb51ae9a624df5b57e 100644
--- a/src/app/calculators/regime-uniforme/regime-uniforme.fr.json
+++ b/src/app/calculators/regime-uniforme/regime-uniforme.fr.json
@@ -19,6 +19,5 @@
     "If": "Pente du fond",
     "YB": "Hauteur de berge",
     "fs_hydraulique": "Caractéristiques hydrauliques",
-    "Q": "Débit",
     "Y": "Tirant d'eau"
 }
\ No newline at end of file
diff --git a/src/app/calculators/section-param/section-param.fr.json b/src/app/calculators/section-param/section-param.fr.json
index 3f29b000bd75aef48e7090a91d33bd6f54cf65c1..3620678ebb05f5925ca984d4b85538be3e0b1d8f 100644
--- a/src/app/calculators/section-param/section-param.fr.json
+++ b/src/app/calculators/section-param/section-param.fr.json
@@ -19,7 +19,6 @@
     "If": "Pente du fond",
     "YB": "Hauteur de berge",
     "fs_hydraulique": "Caractéristiques hydrauliques",
-    "Q": "Débit",
     "Y": "Tirant d'eau",
     "fs_param_calc": "Paramètres de calcul",
     "Pr": "Précision de calcul",
diff --git a/src/app/components/result-element/horizontal-result-element.component.ts b/src/app/components/result-element/horizontal-result-element.component.ts
index 48b269ce9d3a3c227641d7bea716cdfd072dda33..d53b5f5e9803cb406b2824ab480246eadedf7be9 100644
--- a/src/app/components/result-element/horizontal-result-element.component.ts
+++ b/src/app/components/result-element/horizontal-result-element.component.ts
@@ -33,12 +33,14 @@ export class HorizontalResultElementComponent extends ResultElementBaseComponent
         super.ngOnChanges();
 
         this.vcRef.clear();
-        if (this._headerKeys && this._resultElement)
+        if (this._headerKeys && this._resultElement) {
             for (const h of this._headerKeys) {
                 let v = this._resultElement.extraResults[h];
-                if (typeof (v) === "number")
+                if (typeof (v) === "number") {
                     v = this.intlService.formatResult(h, v);
+                }
                 this.vcRef.createEmbeddedView(this.tdTemplate, { extraResultValue: v });
             }
+        }
     }
 }
diff --git a/src/app/components/result-element/result-element-base.component.ts b/src/app/components/result-element/result-element-base.component.ts
index 90247172240ecaae5672a9734a265ce51467cb14..94c088431d49f1844851cd2d331ce409dd21b59f 100644
--- a/src/app/components/result-element/result-element-base.component.ts
+++ b/src/app/components/result-element/result-element-base.component.ts
@@ -49,7 +49,7 @@ export class ResultElementBaseComponent implements OnChanges {
     /**
      * true si pas de texte à afficher dans le tooltip
      */
-    protected _emptyTooltip: boolean = false;
+    protected _emptyTooltip = false;
 
     protected appSetupService: ApplicationSetupService;
 
@@ -73,23 +73,24 @@ export class ResultElementBaseComponent implements OnChanges {
 
         const nDigits = this.appSetupService.displayDigits;
         const r: ResultElement = this._resultElement;
-        this._hasValue = r != undefined && r.vCalc != undefined;
-        this._hasError = r == undefined || (r.vCalc == undefined && r.extraResults.length > 0);
+        this._hasValue = r !== undefined && r.vCalc !== undefined;
+        this._hasError = r === undefined || (r.vCalc === undefined && r.extraResults.length > 0);
         this._value = this._hasValue ? this._value = r.vCalc.toFixed(nDigits) : " ";
 
         // texte du tooltip
 
         let res = "";
 
-        if (this._resultElement != undefined)
-            for (let m of this._resultElement.log.messages) {
-                if (res.length > 0)
+        if (this._resultElement !== undefined) {
+            for (const m of this._resultElement.log.messages) {
+                if (res.length > 0) {
                     res += "<br/>";
+                }
                 res += this.intlService.localizeMessage(m);
             }
-
+        }
         this._htmlTooltip = res;
-        this._emptyTooltip = this._htmlTooltip.length == 0;
+        this._emptyTooltip = this._htmlTooltip.length === 0;
     }
 
     private get hasValue() {
diff --git a/src/app/formulaire/definition/concrete/form-cond-distri.ts b/src/app/formulaire/definition/concrete/form-base.ts
similarity index 95%
rename from src/app/formulaire/definition/concrete/form-cond-distri.ts
rename to src/app/formulaire/definition/concrete/form-base.ts
index 9229f2ce6e364acf9829ffde10c94f9e1cc40c77..ece4ec92cd5f3d32ff7150e3399493eaffd23129 100644
--- a/src/app/formulaire/definition/concrete/form-cond-distri.ts
+++ b/src/app/formulaire/definition/concrete/form-base.ts
@@ -6,7 +6,8 @@ import { CalculatorResults } from "../../../results/calculator-results";
 import { FormDefParamToCalculate } from "../form-def-paramcalc";
 import { FormComputeFixedVar } from "../form-compute-fixedvar";
 
-export class FormulaireConduiteDistributrice extends FormulaireDefinition {
+export class FormulaireBase extends FormulaireDefinition {
+
     private _formFixedVar: FormDefFixedVar;
 
     private _formParamCalc: FormDefParamToCalculate;
diff --git a/src/app/formulaire/definition/concrete/form-dever.ts b/src/app/formulaire/definition/concrete/form-dever.ts
deleted file mode 100644
index 01543d811a6e4bcfe339a30468428352587a45f4..0000000000000000000000000000000000000000
--- a/src/app/formulaire/definition/concrete/form-dever.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { FormDefParallelStructures } from "../form-def-parallel-structures";
-import { FormDefParamToCalculate } from "../form-def-paramcalc";
-import { FormComputeParallelStructures } from "../form-compute-parallel-structures";
-import { FormResultFixedVar } from "../form-result-fixedvar";
-import { CalculatorType, ComputeNodeType, StructureType, LoiDebit } from "jalhyd";
-import { FormulaireParallelStructure } from "./form-parallel-structures";
-
-export class FormulaireDever extends FormulaireParallelStructure {
-    constructor() {
-        super();
-    }
-}
diff --git a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
index 04427e3db3008c31e8955cc00ea4364916731526..586bd933087e2fbf390f25c96277c26fd90463df 100644
--- a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
+++ b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
@@ -1,71 +1,23 @@
-import { CalculatorType, ComputeNodeType, Observer } from "jalhyd";
-
-import { FormResultFixedVar } from "../form-result-fixedvar";
-import { FormDefFixedVar } from "../form-def-fixedvar";
-import { FormulaireDefinition } from "../form-definition";
-import { CalculatorResults } from "../../../results/calculator-results";
-import { FormDefParamToCalculate } from "../form-def-paramcalc";
+import { Observer } from "jalhyd";
 import { SelectField } from "../../select-field";
-import { FormComputeFixedVar } from "../form-compute-fixedvar";
-
-export class FormulaireLechaptCalmon extends FormulaireDefinition implements Observer {
-    private _formFixedVar: FormDefFixedVar;
-
-    private _formParamCalc: FormDefParamToCalculate;
+import { FormulaireBase } from "./form-base";
 
-    private _formCompute: FormComputeFixedVar;
-
-    private _formResult: FormResultFixedVar;
-
-    constructor() {
-        super();
-        this._formFixedVar = new FormDefFixedVar(this);
-        this._formParamCalc = new FormDefParamToCalculate(this);
-        this._formResult = new FormResultFixedVar(this, false);
-        this._formCompute = new FormComputeFixedVar(this, this._formResult);
-    }
-
-    protected initParse() {
-        this._formParamCalc.initParse();
-    }
+export class FormulaireLechaptCalmon extends FormulaireBase implements Observer {
 
     protected completeParse(json: {}) {
-        this._formParamCalc.parseOptions(json);
+        super.completeParse(json);
         // abonnement au changement de valeur du select de matériau
         this.getFormulaireNodeById("select_material").addObserver(this);
     }
 
-    /**
-     * gestion du clic sur les radios "paramètre fixé, à varier, à calculer"    
-     */
-    public onRadioClick(info: string) {
-        super.onRadioClick(info);
-        this._formParamCalc.onRadioClick(info);
-    }
-
-    public resetResults() {
-        this._formResult.resetResults();
-    }
-
-    public doCompute() {
-        this._formCompute.doCompute();
-    }
-
-    public get hasResults(): boolean {
-        return this._formResult.hasResults;
-    }
-
-    public get results(): CalculatorResults[] {
-        return this._formResult.results;
-    }
-
     // interface Observer
 
     public update(sender: any, data: any) {
         // en cas de changement de valeur du select de matériau, effacement des résultats et MAJ des champs L,M,N
         if (sender instanceof SelectField) {
-            if (data.action == "select")
+            if (data.action === "select") {
                 this.reset();
+            }
         }
     }
 }
diff --git a/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts b/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts
deleted file mode 100644
index bb7de04b6cf375f3e3aad38d2e96834e34ead84f..0000000000000000000000000000000000000000
--- a/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import { CalculatorType, ComputeNodeType } from "jalhyd";
-
-import { CalculatorResults } from "../../../results/calculator-results";
-import { FormulaireDefinition } from "../form-definition";
-import { FormDefFixedVar } from "../form-def-fixedvar";
-import { FormDefParamToCalculate } from "../form-def-paramcalc";
-import { FormResultFixedVar } from "../form-result-fixedvar";
-import { FormComputeFixedVar } from "../form-compute-fixedvar";
-
-export class FormulairePasseBassinDimensions extends FormulaireDefinition {
-    private _formFixedVar: FormDefFixedVar;
-
-    private _formParamCalc: FormDefParamToCalculate;
-
-    private _formCompute: FormComputeFixedVar;
-
-    private _formResult: FormResultFixedVar;
-
-    constructor() {
-        super();
-        this._formFixedVar = new FormDefFixedVar(this);
-        this._formParamCalc = new FormDefParamToCalculate(this);
-        this._formResult = new FormResultFixedVar(this, false);
-        this._formCompute = new FormComputeFixedVar(this, this._formResult);
-    }
-
-    protected initParse() {
-        this._formParamCalc.initParse();
-    }
-
-    protected completeParse(json: {}) {
-        this._formParamCalc.parseOptions(json);
-    }
-
-    /**
-     * gestion du clic sur les radios "paramètre fixé, à varier, à calculer"    
-     */
-    public onRadioClick(info: string) {
-        super.onRadioClick(info);
-        this._formParamCalc.onRadioClick(info);
-    }
-
-    public resetResults() {
-        this._formResult.resetResults();
-    }
-
-    public doCompute() {
-        this._formCompute.doCompute();
-    }
-
-    public get hasResults(): boolean {
-        return this._formResult.hasResults;
-    }
-
-    public get results(): CalculatorResults[] {
-        return this._formResult.results;
-    }
-}
diff --git a/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts b/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts
deleted file mode 100644
index ba57242df8937f4a065fa58c74fc5a9dc46199d3..0000000000000000000000000000000000000000
--- a/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import { CalculatorType, ComputeNodeType } from "jalhyd";
-
-import { FormDefFixedVar } from "../form-def-fixedvar";
-import { FormResultFixedVar } from "../form-result-fixedvar";
-import { FormulaireDefinition } from "../form-definition";
-import { CalculatorResults } from "../../../results/calculator-results";
-import { FormDefParamToCalculate } from "../form-def-paramcalc";
-import { FormComputeFixedVar } from "../form-compute-fixedvar";
-
-export class FormulairePasseBassinPuissance extends FormulaireDefinition {
-    private _formFixedVar: FormDefFixedVar;
-
-    private _formParamCalc: FormDefParamToCalculate;
-
-    private _formCompute: FormComputeFixedVar;
-
-    private _formResult: FormResultFixedVar;
-
-    constructor() {
-        super();
-        this._formFixedVar = new FormDefFixedVar(this);
-        this._formParamCalc = new FormDefParamToCalculate(this);
-        this._formResult = new FormResultFixedVar(this, false);
-        this._formCompute = new FormComputeFixedVar(this, this._formResult);
-    }
-
-    protected initParse() {
-        this._formParamCalc.initParse();
-    }
-
-    protected completeParse(json: {}) {
-        this._formParamCalc.parseOptions(json);
-    }
-
-    /**
-     * gestion du clic sur les radios "paramètre fixé, à varier, à calculer"    
-     */
-    public onRadioClick(info: string) {
-        super.onRadioClick(info);
-        this._formParamCalc.onRadioClick(info);
-    }
-
-    public resetResults() {
-        this._formResult.resetResults();
-    }
-
-    public doCompute() {
-        this._formCompute.doCompute();
-    }
-
-    public get hasResults(): boolean {
-        return this._formResult.hasResults;
-    }
-
-    public get results(): CalculatorResults[] {
-        return this._formResult.results;
-    }
-}
diff --git a/src/app/formulaire/definition/concrete/form-regime-uniforme.ts b/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
index 64164746e23499c4052bc4e7b242617725367610..23af0f0c23e1690516a60eb1676a108fb2ce2139 100644
--- a/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
+++ b/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
@@ -47,7 +47,7 @@ export class FormulaireRegimeUniforme extends FormulaireDefinition implements Ob
     }
 
     /**
-     * gestion du clic sur les radios "paramètre fixé, à varier, à calculer"    
+     * gestion du clic sur les radios "paramètre fixé, à varier, à calculer"
      */
     public onRadioClick(info: string) {
         super.onRadioClick(info);
@@ -78,10 +78,11 @@ export class FormulaireRegimeUniforme extends FormulaireDefinition implements Ob
 
     update(sender: IObservable, data: any) {
         // changement de propriété du FieldSet contenant le select de choix du type de section
-        if (sender instanceof FieldSet && sender.id === "fs_section" && data.action == "propertyChange") {
+        if (sender instanceof FieldSet && sender.id === "fs_section" && data.action === "propertyChange") {
             this.replaceCurrentSessionNub(sender.properties);
-            for (const fs of this.allFieldsets)
+            for (const fs of this.allFieldsets) {
                 fs.setSessionNub(this._currentSessionNub);
+            }
             this.reset();
         }
     }
diff --git a/src/app/services/formulaire/formulaire.service.ts b/src/app/services/formulaire/formulaire.service.ts
index 1146f4a962ec8b8165d64168913ddb6dff302782..abf0e218154dce698ceb7bd5f6954ee192416cb5 100644
--- a/src/app/services/formulaire/formulaire.service.ts
+++ b/src/app/services/formulaire/formulaire.service.ts
@@ -16,13 +16,11 @@ import { InputField } from "../../formulaire/input-field";
 import { SelectField } from "../../formulaire/select-field";
 import { CheckField } from "../../formulaire/check-field";
 import { StringMap } from "../../stringmap";
-import { FormulaireConduiteDistributrice } from "../../formulaire/definition/concrete/form-cond-distri";
+import { FormulaireBase } from "../../formulaire/definition/concrete/form-base";
 import { FormulaireLechaptCalmon } from "../../formulaire/definition/concrete/form-lechapt-calmon";
 import { FormulaireSectionParametree } from "../../formulaire/definition/concrete/form-section-parametree";
 import { FormulaireCourbeRemous } from "../../formulaire/definition/concrete/form-courbe-remous";
 import { FormulaireRegimeUniforme } from "../../formulaire/definition/concrete/form-regime-uniforme";
-import { FormulairePasseBassinDimensions } from "../../formulaire/definition/concrete/form-passe-bassin-dim";
-import { FormulairePasseBassinPuissance } from "../../formulaire/definition/concrete/form-passe-bassin-puissance";
 import { FormulaireParallelStructure } from "../../formulaire/definition/concrete/form-parallel-structures";
 import { NgParameter } from "../../formulaire/ngparam";
 
@@ -105,7 +103,7 @@ export class FormulaireService extends Observable {
     }
 
     public loadConfig(ct: CalculatorType): Promise<any> {
-        let f: string = this.getConfigPathPrefix(ct) + "config.json"
+        let f: string = this.getConfigPathPrefix(ct) + "config.json";
         return this._httpService.httpGetRequest2(undefined, undefined, undefined, f);
     }
 
@@ -113,7 +111,10 @@ export class FormulaireService extends Observable {
         let f: FormulaireDefinition;
         switch (ct) {
             case CalculatorType.ConduiteDistributrice:
-                f = new FormulaireConduiteDistributrice();
+            case CalculatorType.PabDimensions:
+            case CalculatorType.PabPuissance:
+            case CalculatorType.MacroRugo:
+                f = new FormulaireBase();
                 break;
 
             case CalculatorType.LechaptCalmon:
@@ -132,14 +133,6 @@ export class FormulaireService extends Observable {
                 f = new FormulaireCourbeRemous();
                 break;
 
-            case CalculatorType.PabDimensions:
-                f = new FormulairePasseBassinDimensions();
-                break;
-
-            case CalculatorType.PabPuissance:
-                f = new FormulairePasseBassinPuissance();
-                break;
-
             case CalculatorType.ParallelStructure:
             case CalculatorType.Dever:
             case CalculatorType.Cloisons:
@@ -286,6 +279,9 @@ export class FormulaireService extends Observable {
             case CalculatorType.Cloisons:
                 return "app/calculators/cloisons/cloisons.";
 
+            case CalculatorType.MacroRugo:
+                return "app/calculators/macrorugo/macrorugo.";
+
             default:
                 throw new Error("FormulaireService.getConfigPathPrefix() : valeur de CalculatorType " + ct + " non implémentée")
         }
diff --git a/src/app/services/internationalisation/internationalisation.service.ts b/src/app/services/internationalisation/internationalisation.service.ts
index 346d18504333c87acdc1b401345ec86c553ab8c3..38e27c01e268148f6114dd20b219f18377fc59ad 100644
--- a/src/app/services/internationalisation/internationalisation.service.ts
+++ b/src/app/services/internationalisation/internationalisation.service.ts
@@ -212,19 +212,15 @@ export class InternationalisationService extends Observable {
     }
 
     /**
-     * met en forme ou traduit un résultat en fonction du libellé qui l'accompagne
-     * @todo Il manque un formalisme clair permettant de différencier les valeurs numériques des ENUM
+     * Met en forme un extraResult en fonction du libellé qui l'accompagne
+     * Les extraResult avec le terme "ENUM_" sont traduit avec le message INFO_EXTRARES_ENUM_[Nom de la variable après ENUM_]
      */
     public formatResult(label: string, value: number): string {
-        const match = this.parseLabel(label);
-        if (match) {
-            if (match[3] !== "Q") { // Le débit est une valeur numérique, tous les autres sont des ENUM ???
-                // Label du type ouvrage[n].XXX => message INFO_EXTRARES_ENUM_OUVRAGE_XXX_value
-                return this.localizeText(`INFO_EXTRARES_ENUM_${match[1].toUpperCase()}_${match[3].toUpperCase()}_${value}`);
-            }
+        const match = label.indexOf("ENUM_");
+        if (match > -1) {
+                return this.localizeText(`INFO_EXTRARES_${label.substring(match).toUpperCase()}_${value}`);
         }
-        const appSetupService = ServiceFactory.instance.applicationSetupService;
-        const nDigits = appSetupService.displayDigits;
+        const nDigits = ServiceFactory.instance.applicationSetupService.displayDigits;
         return value.toFixed(nDigits);
     }
 
diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json
index 0336da276707e18bbb46a3972b5ff18d68ed58e3..009816ca474d25844489f33deac770cac3c7c3a9 100644
--- a/src/locale/messages.fr.json
+++ b/src/locale/messages.fr.json
@@ -38,17 +38,21 @@
     "INFO_CONDUITEDISTRIBUTRICE_TITRE": "Conduite distributrice",
     "INFO_COURBEREMOUS_TITRE": "Courbes de remous",
     "INFO_DEVER_TITRE": "Lois de déversoirs dénoyés",
-    "INFO_EXTRARES_ENUM_OUVRAGE_Q_MODE_0": "Surface libre",
-    "INFO_EXTRARES_ENUM_OUVRAGE_Q_MODE_1": "En charge",
-    "INFO_EXTRARES_ENUM_OUVRAGE_Q_MODE_2": "Débit nul",
-    "INFO_EXTRARES_ENUM_OUVRAGE_Q_REGIME_0": "Dénoyé",
-    "INFO_EXTRARES_ENUM_OUVRAGE_Q_REGIME_1": "Partiellement noyé",
-    "INFO_EXTRARES_ENUM_OUVRAGE_Q_REGIME_2": "Noyé",
-    "INFO_EXTRARES_ENUM_OUVRAGE_Q_REGIME_3": "Débit nul",
+    "INFO_EXTRARES_ENUM_MACRORUGOFLOWTYPE_0": "Emergent",
+    "INFO_EXTRARES_ENUM_MACRORUGOFLOWTYPE_1": "Quasi-émergent",
+    "INFO_EXTRARES_ENUM_MACRORUGOFLOWTYPE_2": "Immergé",
+    "INFO_EXTRARES_ENUM_STRUCTUREFLOWMODE_0": "Surface libre",
+    "INFO_EXTRARES_ENUM_STRUCTUREFLOWMODE_1": "En charge",
+    "INFO_EXTRARES_ENUM_STRUCTUREFLOWMODE_2": "Débit nul",
+    "INFO_EXTRARES_ENUM_STRUCTUREFLOWREGIME_0": "Dénoyé",
+    "INFO_EXTRARES_ENUM_STRUCTUREFLOWREGIME_1": "Partiellement noyé",
+    "INFO_EXTRARES_ENUM_STRUCTUREFLOWREGIME_2": "Noyé",
+    "INFO_EXTRARES_ENUM_STRUCTUREFLOWREGIME_3": "Débit nul",
     "INFO_EXTRARES_LIB_B": "Largeur au miroir (m)",
     "INFO_EXTRARES_LIB_CV": "Cv: Coefficient de vitesse d'approche",
     "INFO_EXTRARES_LIB_CVQT": "CV.QT: Débit corrigé (m³/s)",
     "INFO_EXTRARES_LIB_EC": "EC: Énergie cinétique (m)",
+    "INFO_EXTRARES_LIB_ENUM_MACRORUGOFLOWTYPE": "Type d'écoulement",
     "INFO_EXTRARES_LIB_FLU": "Ligne d'eau fluviale",
     "INFO_EXTRARES_LIB_FR": "Froude",
     "INFO_EXTRARES_LIB_HS": "Charge spécifique (m)",
@@ -57,37 +61,43 @@
     "INFO_EXTRARES_LIB_IMP": "Impulsion (N)",
     "INFO_EXTRARES_LIB_J": "Perte de charge (m)",
     "INFO_EXTRARES_LIB_OUVRAGE_Q": "Débit (m³/s)",
-    "INFO_EXTRARES_LIB_OUVRAGE_Q_MODE": "Type d'écoulement",
-    "INFO_EXTRARES_LIB_OUVRAGE_Q_REGIME": "Régime",
+    "INFO_EXTRARES_LIB_OUVRAGE_Q_ENUM_STRUCTUREFLOWMODE": "Type d'écoulement",
+    "INFO_EXTRARES_LIB_OUVRAGE_Q_ENUM_STRUCTUREFLOWREGIME": "Régime",
     "INFO_EXTRARES_LIB_P": "Périmètre mouillé (m)",
     "INFO_EXTRARES_LIB_PV": "Puissance volumique dissipée (W/m³)",
     "INFO_EXTRARES_LIB_Q": "Débit (m³/s)",
+    "INFO_EXTRARES_LIB_Q_GUIDETECH": "Débit Guide technique (m³/s)",
     "INFO_EXTRARES_LIB_R": "Rayon hydraulique (m)",
     "INFO_EXTRARES_LIB_S": "Surface mouillée (m²)",
     "INFO_EXTRARES_LIB_TAU0": "Force tractrice (Pa)",
     "INFO_EXTRARES_LIB_TOR": "Ligne d'eau torrentielle",
     "INFO_EXTRARES_LIB_V": "Vitesse moyenne (m/s)",
+    "INFO_EXTRARES_LIB_V_GUIDETECH": "Vitesse Guide technique (m/s)",
+    "INFO_EXTRARES_LIB_VDEB": "Vitesse débitante (m/s)",
     "INFO_EXTRARES_LIB_YC": "Tirant d'eau critique (m)",
     "INFO_EXTRARES_LIB_YCO": "Tirant d'eau conjugué (m)",
     "INFO_EXTRARES_LIB_YF": "Tirant d'eau fluvial (m)",
     "INFO_EXTRARES_LIB_YN": "Tirant d'eau normal (m)",
     "INFO_EXTRARES_LIB_YT": "Tirant d'eau torrentiel (m)",
+    "INFO_EXTRARES_LIB_ZF2": "Cote de fond aval (m)",
     "INFO_LECHAPTCALMON_TITRE": "Lechapt-Calmon",
+    "INFO_LIB_ALPHA": "Coefficient alpha",
+    "INFO_LIB_BETA": "Coefficient béta",
+    "INFO_LIB_CD": "Coefficient de débit",
     "INFO_LIB_BT": "Demi-ouverture du triangle (m)",
     "INFO_LIB_FS_PARAM_CALC": "Paramètres de calcul",
     "INFO_LIB_FS_OUVRAGE": "Ouvrage",
+    "INFO_LIB_L": "Largeur du déversoir",
     "INFO_LIB_PR": "Précision de calcul",
+    "INFO_LIB_Q": "Débit",
     "INFO_LIB_SELECT_LOIDEBIT": "Loi de débit",
     "INFO_LIB_SELECT_LOIDEBIT1_KIVI": "Kindsvater-Carter et Villemonte",
     "INFO_LIB_SELECT_OUVRAGE": "Ouvrage",
     "INFO_LIB_SELECT_OUVRAGE_SEUIL_RECT": "Seuil rectangulaire",
     "INFO_LIB_ZDV": "Cote de la crête du déversoir ou du radier de la vanne",
-    "INFO_LIB_L": "Largeur du déversoir (m)",
-    "INFO_LIB_CD": "Coefficient de débit",
-    "INFO_LIB_ALPHA": "Coefficient alpha",
-    "INFO_LIB_BETA": "Coefficient béta",
     "INFO_LIB_ZRAM": "Cote du radier amont (m)",
     "INFO_LIB_ZT": "Cote haute du triangle (m)",
+    "INFO_MACRORUGO_TITRE": "Passe à macro-rugosité",
     "INFO_MENU_NOUVELLE_CALC": "Nouvelle calculette",
     "INFO_OPTION_NO": "Non",
     "INFO_OPTION_YES": "Oui",