diff --git a/e2e/app.e2e-spec.ts b/e2e/app.e2e-spec.ts
index 721ce55a1ebc3c6e5fc1a6c3250a099af9ce8f36..67303435373ba06522f814d17ff0947601bc6ad5 100644
--- a/e2e/app.e2e-spec.ts
+++ b/e2e/app.e2e-spec.ts
@@ -1,6 +1,9 @@
 import { AppPage } from "./app.po";
 import { browser } from "protractor";
 
+/**
+ * Start app
+ */
 describe("ngHyd − start page", () => {
   let page: AppPage;
 
@@ -10,12 +13,7 @@ describe("ngHyd − start page", () => {
 
   it("when app starts, user should be redirected to /list page", async () => {
     await page.navigateTo();
-    const url = await browser.driver.getCurrentUrl(); // @TODO move brower related stuff to .po ?
+    const url = await browser.driver.getCurrentUrl();
     expect(url).toContain("/list");
   });
-
-  /*it("when app starts, user should see the list of available compute nodes", () => {
-    page.navigateTo();
-    expect(page.getListLength()).toBeGreaterThan(8);
-  });*/
 });
diff --git a/e2e/calculate-all-params.e2e-spec.ts b/e2e/calculate-all-params.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e71105a5496733ae74e92a9956249268417cb4a5
--- /dev/null
+++ b/e2e/calculate-all-params.e2e-spec.ts
@@ -0,0 +1,60 @@
+import { AppPage } from "./app.po";
+import { ListPage } from "./list.po";
+import { CalculatorPage } from "./calculator.po";
+import { Navbar } from "./navbar.po";
+import { SideNav } from "./sidenav.po";
+import { browser } from "protractor";
+
+/**
+ * For all calculators, try to calculate every parameter: check that only one parameter
+ * is set to CAL mode, trigger the calculation, check that result is not empty
+ */
+describe("ngHyd − calculate all parameters of all calculators", () => {
+  let listPage: ListPage;
+  let calcPage: CalculatorPage;
+
+  beforeEach(() => {
+    listPage = new ListPage();
+    calcPage = new CalculatorPage();
+  });
+
+  // get calculators list (IDs) @TODO read it from config !
+  const calcTypes = [ 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11 ];
+
+  // for each calculator
+  for (const ct of calcTypes) {
+    describe(" − calculate all parameters of calculator type [" + ct + "]", async () => {
+      it("", async () => {
+        // go to list page
+        await listPage.navigateTo();
+        // click calculator button (instanciate)
+        await listPage.clickMenuEntryForCalcType(ct);
+        // get all parameters IDs
+        const inputs = await calcPage.getParamInputsHavingCalcMode();
+
+        // console.log("> Inputs having calc", inputs.length);
+        if (inputs.length > 0) {
+          // for each param
+          for (const input of inputs) {
+            // console.log(">> Trying", await input.getAttribute("id"));
+            // click "calc" mode button for this parameter
+            await calcPage.setParamMode(input, "cal");
+            // check that only 1 button is in "calc" state
+            const nbParamsCalc = await calcPage.getCheckedCalcModeButtons().count();
+            expect(nbParamsCalc).toBe(1);
+            // check that "compute" button is active
+            const calcButton = calcPage.getCalculateButton();
+            const disabledState = await calcButton.getAttribute("disabled");
+            expect(disabledState).not.toBe("disabled");
+            // click "compute" button
+            await calcButton.click();
+            // check that result is not empty
+            const hasResults = await calcPage.hasResults();
+            expect(hasResults).toBe(true);
+          }
+        }
+      });
+    });
+  }
+
+});
diff --git a/e2e/calculator.e2e-spec.ts b/e2e/calculator.e2e-spec.ts
index f7e986344c299fcb0117e168b4feeb81f0eea51a..835e71536eef3a94b2414014c6f3b9de913291df 100644
--- a/e2e/calculator.e2e-spec.ts
+++ b/e2e/calculator.e2e-spec.ts
@@ -1,6 +1,9 @@
 import { CalculatorPage } from "./calculator.po";
 import { ListPage } from "./list.po";
 
+/**
+ * Create a random calculator
+ */
 describe("ngHyd − calculator page", () => {
   let page: CalculatorPage;
   let listPage: ListPage;
diff --git a/e2e/calculator.po.ts b/e2e/calculator.po.ts
index 9d05454ed7dc9e1d90855850777fa2d4b79e76f6..75d501000108cad0f8829f67d9638d5414f1ee2e 100644
--- a/e2e/calculator.po.ts
+++ b/e2e/calculator.po.ts
@@ -6,6 +6,21 @@ export class CalculatorPage {
     return element.all(by.css("ngparam-input input:not([disabled]) label"));
   }
 
+  getParamInputs() {
+    return element.all(by.css("ngparam-input input.form-control"));
+  }
+
+  async getParamInputsHavingCalcMode() {
+    const ret = [];
+    const inputs = this.getParamInputs();
+    await inputs.each(async (i) => {
+      if (await this.inputHasCalcModeButton(i)) {
+        ret.push(i);
+      }
+    });
+    return ret;
+  }
+
   getHeader1() {
     return element(by.css("h1"));
   }
@@ -22,12 +37,37 @@ export class CalculatorPage {
     return element(by.css("dialog-save-session button[type=submit]"));
   }
 
+  getCalculateButton() {
+    return element(by.css("button#trigger-calculate"));
+  }
+
+  getCheckedCalcModeButtons() {
+    // tslint:disable-next-line:quotemark
+    return element.all(by.css('mat-button-toggle.radio_cal[ng-reflect-checked="true"]'));
+  }
+
   scrollTo(elt: ElementFinder) {
     browser.controlFlow().execute(function() {
       browser.executeScript("arguments[0].scrollIntoView(true)", elt.getWebElement());
     });
   }
 
+  async inputHasCalcModeButton(input: ElementFinder) {
+    // get parent (div.container)
+    const container = await this.findParentContainer(input);
+    // find radio buttons
+    const button: ElementFinder = container.element(by.css("mat-button-toggle.radio_cal > button"));
+    return await button.isPresent();
+  }
+
+  async hasResults() {
+    return (
+      await element(by.css("fixedvar-results fixed-results > .fixed-results-container")).isPresent()
+      ||
+      await element(by.css("fixedvar-results results-graph > graph-results-container")).isPresent()
+    );
+  }
+
   async clickSaveCalcButton() {
     return await element(by.css("#save-calc")).click();
   }
@@ -63,7 +103,8 @@ export class CalculatorPage {
     // get parent (div.container)
     const container = await this.findParentContainer(elt);
     // find radio buttons
-    const button = container.element(by.css("button#radio_" + mode + "-button"));
+    const button = container.element(by.css("mat-button-toggle.radio_" + mode + " > button"));
+    await browser.executeScript("window.scrollTo(0, 0);"); // sometimes button slides behind navbar and click() fails
     await button.click();
     // for "var" mode, close the modal
     if (mode === "var") {
@@ -71,4 +112,31 @@ export class CalculatorPage {
       await element(by.css("dialog-edit-param-values .mat-dialog-actions button")).click();
     }
   }
+
+  /**
+   * Returns an object containing all the calculator's inputs values, indexed
+   * by parameter ID
+   */
+  async storeAllInputValues() {
+    const inputs = this.getParamInputs();
+    const values = {};
+    await inputs.each(async (i) => {
+      const inputId = await i.getAttribute("id");
+      const inputValue = await i.getAttribute("value");
+      values[inputId] = inputValue;
+    });
+    return values;
+  }
+
+  /**
+   * Modifies all the calculator's editable inputs values by adding a random digit other than 0 at the end
+   */
+  async modifyAllInputValues() {
+    const inputs = this.getParamInputs();
+    await inputs.each(async (i) => {
+      if (await i.isDisplayed()) {
+        await i.sendKeys("" + Math.floor(Math.random() * 9) + 1);
+      }
+    });
+  }
 }
diff --git a/e2e/clone-all-calc.e2e-spec.ts b/e2e/clone-all-calc.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..69ab364174db3b13cfa2883dceac5afecd5c6692
--- /dev/null
+++ b/e2e/clone-all-calc.e2e-spec.ts
@@ -0,0 +1,56 @@
+import { ListPage } from "./list.po";
+import { CalculatorPage } from "./calculator.po";
+import { Navbar } from "./navbar.po";
+import { browser } from "protractor";
+
+/**
+ * Clone calculators
+ */
+describe("ngHyd − clone all calculators with all possible <select> values", () => {
+  let listPage: ListPage;
+  let calcPage: CalculatorPage;
+  let navbar: Navbar;
+
+  beforeEach(() => {
+    listPage = new ListPage();
+    calcPage = new CalculatorPage();
+    navbar = new Navbar();
+  });
+
+  // get calculators list (IDs) @TODO read it from config !
+  const calcTypes = [ 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11 ];
+
+  // for each calculator
+  for (const ct of calcTypes) {
+    describe(" − clone all variations of calculator type [" + ct + "]", async () => {
+      it("", async () => {
+        await listPage.navigateTo();
+        // click calculator button (instanciate)
+        await listPage.clickMenuEntryForCalcType(ct);
+
+        // get all select IDs outside Structures
+        // get select IDs inside Structures
+        // @TODO set configuration to every combination of <select> options
+
+        // modify all <input> values and store them
+        await calcPage.modifyAllInputValues();
+        const sourceValues = await calcPage.storeAllInputValues();
+
+        // clone calculator
+        await browser.executeScript("window.scrollTo(0, 0);");
+        await calcPage.clickCloneCalcButton();
+        await browser.sleep(300);
+
+        // check existence of the cloned module
+        expect(await navbar.getAllCalculatorTabs().count()).toBe(2);
+
+        // @TODO check <select> values
+
+        // read all <input> values and compare them to stored ones
+        const cloneValues = await calcPage.storeAllInputValues();
+        expect(cloneValues).toEqual(sourceValues);
+      });
+    });
+  }
+
+});
diff --git a/e2e/clone-calc.e2e-spec.ts b/e2e/clone-calc.e2e-spec.ts
index 21b6206f784d2e219f8ab845a1437a26c73a3570..459b3d7677ad34afc3e41932b10226fc678d8eb6 100644
--- a/e2e/clone-calc.e2e-spec.ts
+++ b/e2e/clone-calc.e2e-spec.ts
@@ -5,6 +5,9 @@ import { Navbar } from "./navbar.po";
 import { SideNav } from "./sidenav.po";
 import { browser } from "protractor";
 
+/**
+ * Clone calculators
+ */
 describe("ngHyd − clone a calculator", () => {
   let startPage: AppPage;
   let listPage: ListPage;
@@ -44,9 +47,9 @@ describe("ngHyd − clone a calculator", () => {
       k: 0.6,
       Ks: 42
     };
-    // await calcPage.changeSelectValue(calcPage.getSelectById("select_section"), 3); // mode "parabolique"
-    // await calcPage.getInputById("k").clear();
-    // await calcPage.getInputById("k").sendKeys(sourceValues["k"]);
+    await calcPage.changeSelectValue(calcPage.getSelectById("select_section"), 3); // mode "parabolique"
+    await calcPage.getInputById("k").clear();
+    await calcPage.getInputById("k").sendKeys(sourceValues["k"]);
     await calcPage.getInputById("Ks").clear();
     await calcPage.getInputById("Ks").sendKeys(sourceValues["Ks"]);
     // link "Débit" to "Courbe de remous"
@@ -60,9 +63,34 @@ describe("ngHyd − clone a calculator", () => {
     await browser.executeScript("window.scrollTo(0, 0);");
     await calcPage.clickCloneCalcButton();
     await browser.sleep(500);
-    // 4. check the cloned module
+
+    // 4. check existence of the cloned module
     expect(await navbar.getAllCalculatorTabs().count()).toBe(4);
     await navbar.clickCalculatorTab(3); // n°3 should be the latest
+    await browser.sleep(500);
+
+    // 5. compare values
+    Object.keys(sourceValues).forEach(async (k) => {
+      const v = sourceValues[k];
+      const displayedVal = await calcPage.getInputById(k).getAttribute("value");
+      expect(displayedVal).toBe("" + v);
+    });
+  });
+
+  it("cloning a parallel-structures calculator should work", async () => {
+    await startPage.navigateTo();
+
+    // create source module to clone
+    await navbar.clickNewCalculatorButton();
+    await listPage.clickMenuEntryForCalcType(8); // Lois d'ouvrages
+    await browser.sleep(500);
+
+    // otherwise clickCloneCalcButton() fails with "Element is not clickable at point"
+    // await browser.executeScript("window.scrollTo(0, 0);");
+    await calcPage.clickCloneCalcButton();
+    await browser.sleep(500);
 
+    // check existence of the cloned module
+    expect(await navbar.getAllCalculatorTabs().count()).toBe(2);
   });
 });
diff --git a/e2e/list.e2e-spec.ts b/e2e/list.e2e-spec.ts
index 775a2735ff0c673b32a7f677ed115e7548116097..3100e72748de99cbbbb4a403f8aec3ffd7679ce1 100644
--- a/e2e/list.e2e-spec.ts
+++ b/e2e/list.e2e-spec.ts
@@ -1,5 +1,8 @@
 import { ListPage } from "./list.po";
 
+/**
+ * Show calculators list (home page)
+ */
 describe("ngHyd − list page", () => {
   let page: ListPage;
 
diff --git a/e2e/list.po.ts b/e2e/list.po.ts
index 4e32624df6e5941c5b92c91bcf08d71044e4bf24..ce64e022eaa6ca88072263944eb5127fd1738985 100644
--- a/e2e/list.po.ts
+++ b/e2e/list.po.ts
@@ -21,6 +21,21 @@ export class ListPage {
     return await this.getCalculatorsMenuEntries().count();
   }
 
+  async getAvailableCalcTypes() {
+    const ids = [];
+    const menuEntries = this.getCalculatorsMenuEntries();
+    await menuEntries.each(async (elt, i) => {
+      const eltid = await elt.getAttribute("id");
+      const ct = eltid.replace("create-calc-", "");
+      const nct = Number(ct);
+      // remove duplicates
+      if (! ids.includes(nct)) {
+        ids.push(nct);
+      }
+    });
+    return ids;
+  }
+
   async clickRandomCalculatorMenuEntry() {
     const menuEntries = this.getCalculatorsMenuEntries();
     const l = await menuEntries.count();
@@ -32,4 +47,9 @@ export class ListPage {
     const but = element(by.css("#create-calc-" + type));
     return but.click();
   }
+
+  async getCalcMenuTextForCalcType(type: number): Promise<string> {
+    const but = element(by.css("#create-calc-" + type));
+    return but.getText();
+  }
 }
diff --git a/e2e/load-save-session.e2e-spec.ts b/e2e/load-save-session.e2e-spec.ts
index b288a375f9e67fb0f83f6f2a90386fae3d058624..8ea125de99cdbb46a40da69bceb6c8f287d138c3 100644
--- a/e2e/load-save-session.e2e-spec.ts
+++ b/e2e/load-save-session.e2e-spec.ts
@@ -5,6 +5,9 @@ import { Navbar } from "./navbar.po";
 import { SideNav } from "./sidenav.po";
 import { browser } from "protractor";
 
+/**
+ * Save and load (serialise and unserialise) calculators to/from JSON files
+ */
 describe("ngHyd − save and load sessions", () => {
   let startPage: AppPage;
   let listPage: ListPage;
@@ -78,9 +81,9 @@ describe("ngHyd − save and load sessions", () => {
     const fileContent = fs.readFileSync(filename, { encoding: "utf8" });
 
     // tslint:disable-next-line:quotemark
-    expect(fileContent).toContain('{"id":"select_section","selected_id":"select_section_circ"}');
+    expect(fileContent).toContain('"nodeType":3');
     // tslint:disable-next-line:quotemark
-    expect(fileContent).toContain('{"param":{"id":"Ks","values":{"mode":"SINGLE","value":42}}}');
+    expect(fileContent).toContain('{"symbol":"Ks","mode":"SINGLE","value":42}');
   });
 
 });
diff --git a/e2e/navigate-through-calculators.e2e-spec.ts b/e2e/navigate-through-calculators.e2e-spec.ts
index f2f91340e01c80d132312f9d96bfab31a9268eb6..f886d7ca1a4e018880ab1136d81d8ef0ed6b75ec 100644
--- a/e2e/navigate-through-calculators.e2e-spec.ts
+++ b/e2e/navigate-through-calculators.e2e-spec.ts
@@ -3,6 +3,9 @@ import { Navbar } from "./navbar.po";
 import { CalculatorPage } from "./calculator.po";
 import { browser } from "protractor";
 
+/**
+ * Use navbar buttons to navigate from one open calculator to another
+ */
 describe("ngHyd − create calculators and navigate among them", () => {
   let listPage: ListPage;
   let calculatorPage: CalculatorPage;
diff --git a/e2e/preferences.e2e-spec.ts b/e2e/preferences.e2e-spec.ts
index 42d4dc61172797b981bdf909383289bc347dbc18..0321b2856f63d6e41c0da3f267d238842cf56c9c 100644
--- a/e2e/preferences.e2e-spec.ts
+++ b/e2e/preferences.e2e-spec.ts
@@ -1,6 +1,9 @@
 import { PreferencesPage } from "./preferences.po";
 import { browser } from "protractor";
 
+/**
+ * Open app preferences, check the default values, the validators, the language change
+ */
 describe("ngHyd − preferences page", () => {
   let page: PreferencesPage;
 
diff --git a/e2e/session-6-calc.test.json b/e2e/session-6-calc.test.json
index 4dab5ec3d21e82dee47b8e81bc24a04328e71317..54df75d63bd35b630fa75b19a592a9d41be3e817 100644
--- a/e2e/session-6-calc.test.json
+++ b/e2e/session-6-calc.test.json
@@ -1,811 +1 @@
-{
-    "session": {
-        "elements": [
-            {
-                "form": {
-                    "id": "Conduite distributrice (MTJmNH)",
-                    "uid": "MTJmNH",
-                    "props": {
-                        "calcType": 0,
-                        "nodeType": 0
-                    },
-                    "elements": [
-                        {
-                            "fieldset": {
-                                "id": "fs_hydraulique",
-                                "props": {
-                                    "calcType": 0,
-                                    "nodeType": 0
-                                },
-                                "elements": [
-                                    {
-                                        "param": {
-                                            "id": "Q",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 3
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "D",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 1.2
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "J",
-                                            "values": {
-                                                "mode": "CALCUL"
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "Lg",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 100
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "Nu",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 0.000001
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_param_calc",
-                                "props": {
-                                    "calcType": 0,
-                                    "nodeType": 0
-                                },
-                                "elements": [
-                                    {
-                                        "param": {
-                                            "id": "Pr",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 0.0001
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        }
-                    ]
-                }
-            },
-            {
-                "form": {
-                    "id": "Lechapt-Calmon (NHdtdT)",
-                    "uid": "NHdtdT",
-                    "props": {
-                        "calcType": 1,
-                        "nodeType": 0
-                    },
-                    "elements": [
-                        {
-                            "fieldset": {
-                                "id": "fs_materiau",
-                                "props": {
-                                    "calcType": 1,
-                                    "nodeType": 0
-                                },
-                                "elements": [
-                                    {
-                                        "select": {
-                                            "id": "select_material",
-                                            "selected_id": "select_material_1"
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "L",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 1.863
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "M",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 2
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "N",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 5.33
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_hydraulique",
-                                "props": {
-                                    "calcType": 1,
-                                    "nodeType": 0
-                                },
-                                "elements": [
-                                    {
-                                        "param": {
-                                            "id": "Q",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 3
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "D",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 1.2
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "J",
-                                            "values": {
-                                                "mode": "CALCUL"
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "Lg",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 100
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_param_calc",
-                                "props": {
-                                    "calcType": 1,
-                                    "nodeType": 0
-                                },
-                                "elements": [
-                                    {
-                                        "param": {
-                                            "id": "Pr",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 0.0001
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        }
-                    ]
-                }
-            },
-            {
-                "form": {
-                    "id": "Section paramétrée (YjZxc2)",
-                    "uid": "YjZxc2",
-                    "props": {
-                        "calcType": 2,
-                        "nodeType": 2
-                    },
-                    "elements": [
-                        {
-                            "fieldset": {
-                                "id": "fs_section",
-                                "props": {
-                                    "calcType": 2,
-                                    "nodeType": 2
-                                },
-                                "elements": [
-                                    {
-                                        "select": {
-                                            "id": "select_section",
-                                            "selected_id": "select_section_rect"
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "LargeurBerge",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 2.5
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_bief",
-                                "props": {
-                                    "calcType": 2,
-                                    "nodeType": 2
-                                },
-                                "elements": [
-                                    {
-                                        "param": {
-                                            "id": "Ks",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 40
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "If",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 0.001
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "YB",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 1
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_hydraulique",
-                                "props": {
-                                    "calcType": 2,
-                                    "nodeType": 2
-                                },
-                                "elements": [
-                                    {
-                                        "param": {
-                                            "id": "Q",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 1.2
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "Y",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 0.8
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_param_calc",
-                                "props": {
-                                    "calcType": 2,
-                                    "nodeType": 2
-                                },
-                                "elements": [
-                                    {
-                                        "param": {
-                                            "id": "Pr",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 0.0001
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_computed_var",
-                                "props": {
-                                    "calcType": 2,
-                                    "nodeType": 2
-                                },
-                                "elements": [
-                                    {
-                                        "select": {
-                                            "id": "select_target",
-                                            "selected_id": "select_target_Hs"
-                                        }
-                                    }
-                                ]
-                            }
-                        }
-                    ]
-                }
-            },
-            {
-                "form": {
-                    "id": "Régime uniforme (ZmEwcX)",
-                    "uid": "ZmEwcX",
-                    "props": {
-                        "calcType": 3,
-                        "nodeType": 2
-                    },
-                    "elements": [
-                        {
-                            "fieldset": {
-                                "id": "fs_section",
-                                "props": {
-                                    "calcType": 3,
-                                    "nodeType": 2
-                                },
-                                "elements": [
-                                    {
-                                        "select": {
-                                            "id": "select_section",
-                                            "selected_id": "select_section_rect"
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "LargeurBerge",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 2.5
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_bief",
-                                "props": {
-                                    "calcType": 3,
-                                    "nodeType": 2
-                                },
-                                "elements": [
-                                    {
-                                        "param": {
-                                            "id": "Ks",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 40
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "If",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 0.001
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "YB",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 1
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_hydraulique",
-                                "props": {
-                                    "calcType": 3,
-                                    "nodeType": 2
-                                },
-                                "elements": [
-                                    {
-                                        "param": {
-                                            "id": "Q",
-                                            "values": {
-                                                "mode": "CALCUL"
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "Y",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 0.8
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_param_calc",
-                                "props": {
-                                    "calcType": 3,
-                                    "nodeType": 2
-                                },
-                                "elements": [
-                                    {
-                                        "param": {
-                                            "id": "Pr",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 0.0001
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        }
-                    ]
-                }
-            },
-            {
-                "form": {
-                    "id": "Courbes de remous (NHdmeG)",
-                    "uid": "NHdmeG",
-                    "props": {
-                        "calcType": 4,
-                        "nodeType": 2
-                    },
-                    "elements": [
-                        {
-                            "fieldset": {
-                                "id": "fs_section",
-                                "props": {
-                                    "calcType": 4,
-                                    "nodeType": 2
-                                },
-                                "elements": [
-                                    {
-                                        "select": {
-                                            "id": "select_section",
-                                            "selected_id": "select_section_rect"
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "LargeurBerge",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 2.5
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_bief",
-                                "props": {
-                                    "calcType": 4,
-                                    "nodeType": 2
-                                },
-                                "elements": [
-                                    {
-                                        "param": {
-                                            "id": "Ks",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 40
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "Long",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 100
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "If",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 0.001
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "YB",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 1
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_condlim",
-                                "props": {
-                                    "calcType": 4,
-                                    "nodeType": 2
-                                },
-                                "elements": [
-                                    {
-                                        "param": {
-                                            "id": "Q",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 1.2
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "Yaval",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 0.4
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "Yamont",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 0.15
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_param_calc",
-                                "props": {
-                                    "calcType": 4,
-                                    "nodeType": 2
-                                },
-                                "elements": [
-                                    {
-                                        "param": {
-                                            "id": "Dx",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 5
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "Pr",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 0.0001
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "select": {
-                                            "id": "select_resolution",
-                                            "selected_id": "select_resolution_trap"
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_target_data",
-                                "props": {
-                                    "calcType": 4,
-                                    "nodeType": 2
-                                },
-                                "elements": [
-                                    {
-                                        "select": {
-                                            "id": "select_target",
-                                            "selected_id": "select_target_none"
-                                        }
-                                    }
-                                ]
-                            }
-                        }
-                    ]
-                }
-            },
-            {
-                "form": {
-                    "id": "Lois d'ouvrages (Yzgxan)",
-                    "uid": "Yzgxan",
-                    "props": {
-                        "calcType": 8,
-                        "nodeType": 0
-                    },
-                    "elements": [
-                        {
-                            "fieldset": {
-                                "id": "fs_param_hydro",
-                                "props": {
-                                    "calcType": 8,
-                                    "nodeType": 0
-                                },
-                                "elements": [
-                                    {
-                                        "param": {
-                                            "id": "Q",
-                                            "values": {
-                                                "mode": "CALCUL"
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "Z1",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 102
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "Z2",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 101.5
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset_container": {
-                                "id": "struct_container",
-                                "elements": [
-                                    {
-                                        "fieldset": {
-                                            "id": "fs_ouvrage",
-                                            "props": {
-                                                "calcType": 7,
-                                                "nodeType": 5,
-                                                "structureType": 1,
-                                                "loiDebit": 1
-                                            },
-                                            "elements": [
-                                                {
-                                                    "select": {
-                                                        "id": "select_ouvrage",
-                                                        "selected_id": "select_ouvrage_vanne_rect"
-                                                    }
-                                                },
-                                                {
-                                                    "select": {
-                                                        "id": "select_loidebit1",
-                                                        "selected_id": "select_loidebit1_cem88d"
-                                                    }
-                                                },
-                                                {
-                                                    "select": {
-                                                        "id": "select_loidebit2",
-                                                        "selected_id": "select_loidebit2_cem88v"
-                                                    }
-                                                },
-                                                {
-                                                    "select": {
-                                                        "id": "select_loidebit3",
-                                                        "selected_id": "select_loidebit3_seuiltriang"
-                                                    }
-                                                },
-                                                {
-                                                    "select": {
-                                                        "id": "select_loidebit4",
-                                                        "selected_id": "select_loidebit4_seuiltriangtrunc"
-                                                    }
-                                                },
-                                                {
-                                                    "param": {
-                                                        "id": "ZDV",
-                                                        "values": {
-                                                            "mode": "SINGLE",
-                                                            "value": 100
-                                                        }
-                                                    }
-                                                },
-                                                {
-                                                    "param": {
-                                                        "id": "L",
-                                                        "values": {
-                                                            "mode": "SINGLE",
-                                                            "value": 2
-                                                        }
-                                                    }
-                                                },
-                                                {
-                                                    "param": {
-                                                        "id": "W",
-                                                        "values": {
-                                                            "mode": "SINGLE",
-                                                            "value": null
-                                                        }
-                                                    }
-                                                },
-                                                {
-                                                    "param": {
-                                                        "id": "Cd",
-                                                        "values": {
-                                                            "mode": "SINGLE",
-                                                            "value": 0.4
-                                                        }
-                                                    }
-                                                }
-                                            ]
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_param_calc",
-                                "props": {
-                                    "calcType": 8,
-                                    "nodeType": 0
-                                },
-                                "elements": [
-                                    {
-                                        "param": {
-                                            "id": "Pr",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 0.0001
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        }
-                    ]
-                }
-            }
-        ]
-    }
-}
\ No newline at end of file
+{"session":[{"uid":"NHY0cX","props":{"calcType":5,"nodeType":0},"meta":{"title":"PAB : dimensions"},"parameters":[{"symbol":"Pr","mode":"SINGLE","value":0.0001},{"symbol":"L","mode":"SINGLE","value":2},{"symbol":"W","mode":"SINGLE","value":1},{"symbol":"Y","mode":"SINGLE","value":0.5},{"symbol":"V","mode":"CALCUL"}]},{"uid":"YzAwMW","props":{"calcType":11,"nodeType":0},"meta":{"title":"Macro-rugo."},"parameters":[{"symbol":"Pr","mode":"SINGLE","value":0.0001},{"symbol":"ZF1","mode":"SINGLE","value":12.5},{"symbol":"L","mode":"SINGLE","value":6},{"symbol":"B","mode":"SINGLE","value":1},{"symbol":"If","mode":"SINGLE","value":0.05},{"symbol":"Q","mode":"CALCUL"},{"symbol":"Y","mode":"SINGLE","value":0.6},{"symbol":"Ks","mode":"SINGLE","value":0.01},{"symbol":"C","mode":"SINGLE","value":0.05},{"symbol":"PBD","mode":"SINGLE","value":0.5},{"symbol":"PBH","mode":"SINGLE","value":0.8},{"symbol":"Cd0","mode":"SINGLE","value":1.5}]},{"uid":"dGc5MD","props":{"calcType":8,"nodeType":0},"meta":{"title":"Ouvrages"},"structures":[{"uid":"NjZob3","props":{"calcType":7,"nodeType":5,"structureType":1,"loiDebit":1},"parameters":[{"symbol":"ZDV","mode":"SINGLE","value":100},{"symbol":"W","mode":"SINGLE","value":0.5},{"symbol":"L","mode":"SINGLE","value":2},{"symbol":"Cd","mode":"SINGLE","value":0.6}]}],"parameters":[{"symbol":"Pr","mode":"SINGLE","value":0.0001},{"symbol":"Q","mode":"CALCUL"},{"symbol":"Z1","mode":"SINGLE","value":102},{"symbol":"Z2","mode":"SINGLE","value":101.5}]},{"uid":"OGZ4cm","props":{"varCalc":"Hs","calcType":2,"nodeType":2},"meta":{"title":"Sec. param."},"parameters":[{"symbol":"Pr","mode":"SINGLE","value":0.0001},{"symbol":"Ks","mode":"SINGLE","value":40},{"symbol":"Q","mode":"SINGLE","value":1.2},{"symbol":"If","mode":"SINGLE","value":0.001},{"symbol":"YB","mode":"SINGLE","value":1},{"symbol":"Y","mode":"SINGLE","value":0.8},{"symbol":"LargeurBerge","mode":"SINGLE","value":2.5}]},{"uid":"ZTNvMD","props":{"methodeResolution":0,"calcType":4,"nodeType":2},"meta":{"title":"Remous"},"parameters":[{"symbol":"Pr","mode":"SINGLE","value":0.0001},{"symbol":"Yamont","mode":"SINGLE","value":0.15},{"symbol":"Yaval","mode":"SINGLE","value":0.4},{"symbol":"Long","mode":"SINGLE","value":100},{"symbol":"Dx","mode":"SINGLE","value":5},{"symbol":"Ks","mode":"SINGLE","value":40},{"symbol":"Q","mode":"SINGLE","value":1.2},{"symbol":"If","mode":"SINGLE","value":0.001},{"symbol":"YB","mode":"SINGLE","value":1},{"symbol":"Y","mode":"SINGLE","value":0.2863766123093061},{"symbol":"LargeurBerge","mode":"SINGLE","value":2.5}]},{"uid":"eWllan","props":{"calcType":1,"nodeType":0},"meta":{"title":"Lechapt-Calmon"},"parameters":[{"symbol":"Pr","mode":"SINGLE","value":0.0001},{"symbol":"Q","mode":"SINGLE","value":3},{"symbol":"D","mode":"SINGLE","value":1.2},{"symbol":"J","mode":"CALCUL"},{"symbol":"Lg","mode":"SINGLE","value":100},{"symbol":"L","mode":"SINGLE","value":"1.863"},{"symbol":"M","mode":"SINGLE","value":"2"},{"symbol":"N","mode":"SINGLE","value":"5.33"}]}]}
\ No newline at end of file
diff --git a/e2e/session-optional-params.test.json b/e2e/session-optional-params.test.json
index 0d5cea59ec6fed688895456e8abe90f0e8a53188..804c559cb54b2dfa3f367b66a9ca29de7e953e4a 100644
--- a/e2e/session-optional-params.test.json
+++ b/e2e/session-optional-params.test.json
@@ -1,160 +1 @@
-{
-    "session": {
-        "elements": [
-            {
-                "form": {
-                    "id": "Section paramétrée",
-                    "uid": "ZDZ1Yn",
-                    "props": {
-                        "calcType": 2,
-                        "nodeType": 4
-                    },
-                    "elements": [
-                        {
-                            "fieldset": {
-                                "id": "fs_section",
-                                "props": {
-                                    "calcType": 2,
-                                    "nodeType": 4
-                                },
-                                "elements": [
-                                    {
-                                        "select": {
-                                            "id": "select_section",
-                                            "selected_id": "select_section_puiss"
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "k",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 0.5
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "LargeurBerge",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 4
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_bief",
-                                "props": {
-                                    "calcType": 2,
-                                    "nodeType": 4
-                                },
-                                "elements": [
-                                    {
-                                        "param": {
-                                            "id": "Ks",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 40
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "If",
-                                            "values": {
-                                                "mode": "MINMAX",
-                                                "min": 0.0005,
-                                                "max": 0.002,
-                                                "step": 0.00007500000000000001
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "YB",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 1
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_hydraulique",
-                                "props": {
-                                    "calcType": 2,
-                                    "nodeType": 4
-                                },
-                                "elements": [
-                                    {
-                                        "param": {
-                                            "id": "Q",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 1.2
-                                            }
-                                        }
-                                    },
-                                    {
-                                        "param": {
-                                            "id": "Y",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 0.8
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_param_calc",
-                                "props": {
-                                    "calcType": 2,
-                                    "nodeType": 4
-                                },
-                                "elements": [
-                                    {
-                                        "param": {
-                                            "id": "Pr",
-                                            "values": {
-                                                "mode": "SINGLE",
-                                                "value": 0.0001
-                                            }
-                                        }
-                                    }
-                                ]
-                            }
-                        },
-                        {
-                            "fieldset": {
-                                "id": "fs_computed_var",
-                                "props": {
-                                    "calcType": 2,
-                                    "nodeType": 4,
-                                    "varCalc": "B"
-                                },
-                                "elements": [
-                                    {
-                                        "select": {
-                                            "id": "select_target",
-                                            "selected_id": "select_target_B"
-                                        }
-                                    }
-                                ]
-                            }
-                        }
-                    ]
-                }
-            }
-        ]
-    }
-}
\ No newline at end of file
+{"session":[{"uid":"N2U4OH","props":{"varCalc":"Hs","calcType":2,"nodeType":4},"meta":{"title":"Sec. param."},"parameters":[{"symbol":"Pr","mode":"SINGLE","value":0.0001},{"symbol":"Ks","mode":"SINGLE","value":40},{"symbol":"Q","mode":"SINGLE","value":1.2},{"symbol":"If","mode":"SINGLE","value":0.001},{"symbol":"YB","mode":"SINGLE","value":1},{"symbol":"Y","mode":"SINGLE","value":0.8},{"symbol":"LargeurBerge","mode":"SINGLE","value":4},{"symbol":"k","mode":"SINGLE","value":0.5}]}]}
\ No newline at end of file
diff --git a/jalhyd_branch b/jalhyd_branch
index 1f7391f92b6a3792204e07e99f71f643cc35e7e1..5da74c213bbd159c5b4201e919e54b83e0e994be 100644
--- a/jalhyd_branch
+++ b/jalhyd_branch
@@ -1 +1 @@
-master
+64-implementer-la-de-serialisation-au-niveau-du-nub
diff --git a/package-lock.json b/package-lock.json
index bead599e1f868212b954745b7ec76f9f61afa37a..e4a04b40cc569cffe4f1fd5751be5aeffd4909f9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6899,369 +6899,6 @@
       "version": "file:../jalhyd",
       "requires": {
         "buffer": "^5.2.1"
-      },
-      "dependencies": {
-        "@types/jasmine": {
-          "version": "2.8.8",
-          "bundled": true
-        },
-        "@types/node": {
-          "version": "10.5.2",
-          "bundled": true
-        },
-        "ansi-regex": {
-          "version": "2.1.1",
-          "bundled": true
-        },
-        "ansi-styles": {
-          "version": "2.2.1",
-          "bundled": true
-        },
-        "argparse": {
-          "version": "1.0.10",
-          "bundled": true,
-          "requires": {
-            "sprintf-js": "~1.0.2"
-          }
-        },
-        "babel-code-frame": {
-          "version": "6.26.0",
-          "bundled": true,
-          "requires": {
-            "chalk": "^1.1.3",
-            "esutils": "^2.0.2",
-            "js-tokens": "^3.0.2"
-          },
-          "dependencies": {
-            "chalk": {
-              "version": "1.1.3",
-              "bundled": true,
-              "requires": {
-                "ansi-styles": "^2.2.1",
-                "escape-string-regexp": "^1.0.2",
-                "has-ansi": "^2.0.0",
-                "strip-ansi": "^3.0.0",
-                "supports-color": "^2.0.0"
-              }
-            }
-          }
-        },
-        "balanced-match": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "base64-js": {
-          "version": "1.3.0",
-          "bundled": true
-        },
-        "brace-expansion": {
-          "version": "1.1.8",
-          "bundled": true,
-          "requires": {
-            "balanced-match": "^1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "buffer": {
-          "version": "5.2.1",
-          "bundled": true,
-          "requires": {
-            "base64-js": "^1.0.2",
-            "ieee754": "^1.1.4"
-          }
-        },
-        "builtin-modules": {
-          "version": "1.1.1",
-          "bundled": true
-        },
-        "chalk": {
-          "version": "2.3.0",
-          "bundled": true,
-          "requires": {
-            "ansi-styles": "^3.1.0",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^4.0.0"
-          },
-          "dependencies": {
-            "ansi-styles": {
-              "version": "3.2.0",
-              "bundled": true,
-              "requires": {
-                "color-convert": "^1.9.0"
-              }
-            },
-            "supports-color": {
-              "version": "4.5.0",
-              "bundled": true,
-              "requires": {
-                "has-flag": "^2.0.0"
-              }
-            }
-          }
-        },
-        "coffeescript": {
-          "version": "2.3.1",
-          "bundled": true
-        },
-        "color-convert": {
-          "version": "1.9.1",
-          "bundled": true,
-          "requires": {
-            "color-name": "^1.1.1"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "bundled": true
-        },
-        "commander": {
-          "version": "2.12.2",
-          "bundled": true
-        },
-        "concat-map": {
-          "version": "0.0.1",
-          "bundled": true
-        },
-        "diff": {
-          "version": "3.4.0",
-          "bundled": true
-        },
-        "escape-string-regexp": {
-          "version": "1.0.5",
-          "bundled": true
-        },
-        "esprima": {
-          "version": "4.0.1",
-          "bundled": true
-        },
-        "esutils": {
-          "version": "2.0.2",
-          "bundled": true
-        },
-        "fs.realpath": {
-          "version": "1.0.0",
-          "bundled": true
-        },
-        "glob": {
-          "version": "7.1.2",
-          "bundled": true,
-          "requires": {
-            "fs.realpath": "^1.0.0",
-            "inflight": "^1.0.4",
-            "inherits": "2",
-            "minimatch": "^3.0.4",
-            "once": "^1.3.0",
-            "path-is-absolute": "^1.0.0"
-          }
-        },
-        "globule": {
-          "version": "1.2.1",
-          "bundled": true,
-          "requires": {
-            "glob": "~7.1.1",
-            "lodash": "~4.17.10",
-            "minimatch": "~3.0.2"
-          }
-        },
-        "has-ansi": {
-          "version": "2.0.0",
-          "bundled": true,
-          "requires": {
-            "ansi-regex": "^2.0.0"
-          }
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "bundled": true
-        },
-        "ieee754": {
-          "version": "1.1.12",
-          "bundled": true
-        },
-        "inflight": {
-          "version": "1.0.6",
-          "bundled": true,
-          "requires": {
-            "once": "^1.3.0",
-            "wrappy": "1"
-          }
-        },
-        "inherits": {
-          "version": "2.0.3",
-          "bundled": true
-        },
-        "jasmine": {
-          "version": "3.1.0",
-          "bundled": true,
-          "requires": {
-            "glob": "^7.0.6",
-            "jasmine-core": "~3.1.0"
-          }
-        },
-        "jasmine-core": {
-          "version": "3.1.0",
-          "bundled": true
-        },
-        "jasmine-node": {
-          "version": "1.15.0",
-          "bundled": true,
-          "requires": {
-            "coffeescript": ">=1.0.1",
-            "gaze": "~1.1.2",
-            "jasmine-growl-reporter": "~1.0.1",
-            "jasmine-reporters": "~1.0.0",
-            "mkdirp": "~0.3.5",
-            "requirejs": ">=0.27.1",
-            "underscore": ">= 1.3.1",
-            "walkdir": ">= 0.0.1"
-          },
-          "dependencies": {
-            "gaze": {
-              "version": "1.1.3",
-              "bundled": true,
-              "requires": {
-                "globule": "^1.0.0"
-              }
-            },
-            "growl": {
-              "version": "1.10.5",
-              "bundled": true
-            },
-            "jasmine-growl-reporter": {
-              "version": "1.0.1",
-              "bundled": true,
-              "requires": {
-                "growl": "^1.10.2"
-              }
-            }
-          }
-        },
-        "jasmine-reporters": {
-          "version": "1.0.2",
-          "bundled": true,
-          "requires": {
-            "mkdirp": "~0.3.5"
-          }
-        },
-        "js-tokens": {
-          "version": "3.0.2",
-          "bundled": true
-        },
-        "js-yaml": {
-          "version": "3.12.0",
-          "bundled": true,
-          "requires": {
-            "argparse": "^1.0.7",
-            "esprima": "^4.0.0"
-          }
-        },
-        "lodash": {
-          "version": "4.17.10",
-          "bundled": true
-        },
-        "minimatch": {
-          "version": "3.0.4",
-          "bundled": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
-        },
-        "mkdirp": {
-          "version": "0.3.5",
-          "bundled": true
-        },
-        "once": {
-          "version": "1.4.0",
-          "bundled": true,
-          "requires": {
-            "wrappy": "1"
-          }
-        },
-        "path-is-absolute": {
-          "version": "1.0.1",
-          "bundled": true
-        },
-        "path-parse": {
-          "version": "1.0.5",
-          "bundled": true
-        },
-        "requirejs": {
-          "version": "2.3.5",
-          "bundled": true
-        },
-        "resolve": {
-          "version": "1.5.0",
-          "bundled": true,
-          "requires": {
-            "path-parse": "^1.0.5"
-          }
-        },
-        "semver": {
-          "version": "5.4.1",
-          "bundled": true
-        },
-        "sprintf-js": {
-          "version": "1.0.3",
-          "bundled": true
-        },
-        "strip-ansi": {
-          "version": "3.0.1",
-          "bundled": true,
-          "requires": {
-            "ansi-regex": "^2.0.0"
-          }
-        },
-        "supports-color": {
-          "version": "2.0.0",
-          "bundled": true
-        },
-        "tslib": {
-          "version": "1.8.1",
-          "bundled": true
-        },
-        "tslint": {
-          "version": "5.11.0",
-          "bundled": true,
-          "requires": {
-            "babel-code-frame": "^6.22.0",
-            "builtin-modules": "^1.1.1",
-            "chalk": "^2.3.0",
-            "commander": "^2.12.1",
-            "diff": "^3.2.0",
-            "glob": "^7.1.1",
-            "js-yaml": "^3.7.0",
-            "minimatch": "^3.0.4",
-            "resolve": "^1.3.2",
-            "semver": "^5.3.0",
-            "tslib": "^1.8.0",
-            "tsutils": "^2.27.2"
-          },
-          "dependencies": {
-            "tsutils": {
-              "version": "2.28.0",
-              "bundled": true,
-              "requires": {
-                "tslib": "^1.8.1"
-              }
-            }
-          }
-        },
-        "typescript": {
-          "version": "2.9.2",
-          "bundled": true
-        },
-        "underscore": {
-          "version": "1.8.3",
-          "bundled": true
-        },
-        "walkdir": {
-          "version": "0.0.12",
-          "bundled": true
-        },
-        "wrappy": {
-          "version": "1.0.2",
-          "bundled": true
-        }
       }
     },
     "jasmine": {
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index acecbe6d6c16af6261b8478879d8b08402f9371a..968194eae05f5be6a9ad2153d9b61192ffa6656e 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -3,7 +3,7 @@ import { Router, Event, NavigationEnd, ActivationEnd } from "@angular/router";
 import { MatSidenav, MatToolbar, MatDialog, MatIconRegistry } from "@angular/material";
 import { DomSanitizer } from "@angular/platform-browser";
 
-import { Observer, jalhydDateRev, CalculatorType } from "jalhyd";
+import { Observer, jalhydDateRev, CalculatorType, Session } from "jalhyd";
 
 import { environment } from "../environments/environment";
 import { I18nService } from "./services/internationalisation/internationalisation.service";
@@ -11,7 +11,6 @@ import { ErrorService } from "./services/error/error.service";
 import { FormulaireService } from "./services/formulaire/formulaire.service";
 import { FormulaireDefinition } from "./formulaire/definition/form-definition";
 import { ServiceFactory } from "./services/service-factory";
-import { ParamService } from "./services/param/param.service";
 import { HttpService } from "./services/http/http.service";
 import { ApplicationSetupService } from "./services/app-setup/app-setup.service";
 import { nghydDateRev } from "../date_revision";
@@ -61,7 +60,6 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
 
   constructor(
     private intlService: I18nService,
-    private paramService: ParamService,
     private appSetupService: ApplicationSetupService,
     private appRef: ApplicationRef,
     private errorService: ErrorService,
@@ -76,7 +74,6 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
   ) {
     ServiceFactory.instance.httpService = httpService;
     ServiceFactory.instance.applicationSetupService = appSetupService;
-    ServiceFactory.instance.paramService = paramService;
     ServiceFactory.instance.i18nService = intlService;
     ServiceFactory.instance.formulaireService = formulaireService;
 
@@ -290,16 +287,23 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
     this._calculators[formIndex]["title"] = title;
   }
 
+  /**
+   * Saves a JSON serialised session file, for one or more calc modules
+   * @param calcList modules to save
+   * @param filename
+   */
   private saveSession(calcList: any[], filename) {
     const elems = [];
+    const serialiseOptions: { [key: string]: {} } = {};
     for (const c of calcList) {
       if (c.selected) {
-        const form: FormulaireDefinition = this.formulaireService.getFormulaireFromId(c.uid);
-        elems.push(form.JSONserialise());
+        serialiseOptions[c.uid] = { // GUI-dependent metadata to add to the session file
+          title: c.title
+        };
       }
     }
-    const session = { "session": { "elements": elems } };
-    this.formulaireService.saveSession(session, filename);
+    const session: string = Session.getInstance().serialise(serialiseOptions);
+    this.formulaireService.downloadTextFile(session, filename);
   }
 
   /**
@@ -377,6 +381,8 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
           const form = this.formulaireService.getFormulaireFromId(c.uid);
           this.formulaireService.requestCloseForm(form.uid);
         }
+        // just to be sure, get rid of any Nub possibly stuck in session without any form attached
+        Session.getInstance().clearSession();
       }
     });
   }
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index e20d5253434d242703797cfb785a3a3fda1a78e7..13c9b193d338e87f41f9f17ee3ce0c753f01d169 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -37,7 +37,6 @@ import { RouterModule, Routes } from "@angular/router";
 import { NgxMdModule } from "ngx-md";
 
 import { FormulaireService } from "./services/formulaire/formulaire.service";
-import { ParamService } from "./services/param/param.service";
 import { I18nService } from "./services/internationalisation/internationalisation.service";
 import { HttpService } from "./services/http/http.service";
 import { ApplicationSetupService } from "./services/app-setup/app-setup.service";
@@ -184,7 +183,6 @@ const appRoutes: Routes = [
     FormulaireService,
     HttpService,
     I18nService,
-    ParamService,
     {
       provide: ErrorStateMatcher,
       useClass: ImmediateErrorStateMatcher
diff --git a/src/app/calculators/cloisons/cloisons.en.json b/src/app/calculators/cloisons/cloisons.en.json
new file mode 100644
index 0000000000000000000000000000000000000000..c8bc712cdb1427e56b8e57d3729bc83e287bb353
--- /dev/null
+++ b/src/app/calculators/cloisons/cloisons.en.json
@@ -0,0 +1,17 @@
+{
+    "fs_param_hydro": "Paramètres hydrauliques",
+    "Q": "Débit total",
+    "Z1": "Cote de l'eau amont",
+    "ZR": "Cote du lit amont",
+    "LB": "Longueur du bassin",
+    "BB": "Largeur du bassin",
+    "PB": "Profondeur moyenne du bassin",
+    "DH": "Chute",
+    "S": "Surface de l'orifice",
+    "select_ouvrage_orifice": "Orifice",
+    "select_ouvrage_seuil_rect": "Seuil rectangulaire",
+    "select_loidebit1_kivi": "Kindsvater-Carter et Villemonte",
+    "select_loidebit1_fente": "Fente noyée (Larinier 1992)",
+    "select_loidebit2_orifice": "Orifice noyé",
+    "struct_container": "Ouvrages"
+}
\ No newline at end of file
diff --git a/src/app/calculators/dever/dever.en.json b/src/app/calculators/dever/dever.en.json
new file mode 100644
index 0000000000000000000000000000000000000000..4157c047f09aba29d60e5a8fae7d2698196eb544
--- /dev/null
+++ b/src/app/calculators/dever/dever.en.json
@@ -0,0 +1,36 @@
+{
+    "fs_param_hydro": "Paramètres hydrauliques",
+    "Q": "Débit total",
+    "Z1": "Cote de l'eau amont",
+    "ZR": "Cote du lit amont",
+    "BR": "Largeur du lit amont",
+    "fs_ouvrage": "Ouvrage",
+    "select_ouvrage": "Ouvrage",
+    "select_ouvrage_vanne_circ": "Vanne circulaire",
+    "select_ouvrage_vanne_rect": "Vanne rectangulaire",
+    "select_ouvrage_seuil_rect": "Seuil rectangulaire",
+    "select_ouvrage_seuil_trap": "Seuil trapézoïdal",
+    "select_ouvrage_vanne_trap": "Vanne trapézoïdale",
+    "select_ouvrage_seuil_triang": "Seuil triangulaire",
+    "select_ouvrage_seuil_triangtrunc": "Seuil triangulaire tronqué",
+    "W": "Ouverture de vanne",
+    "select_loidebit1_seuildenoye": "Seuil dénoyé",
+    "select_loidebit1_cunge80": "Cunge 80",
+    "select_loidebit1_cem88d": "Déversoir/Orifice Cemagref 88",
+    "select_loidebit1_cem88v": "Déversoir/Vanne de fond Cemagref 88",
+    "select_loidebit1_kivi": "Kindsvater-Carter et Villemonte",
+    "select_loidebit2_vannedenoye": "Vanne dénoyé",
+    "select_loidebit2_vannenoye": "Vanne noyé",
+    "select_loidebit2_cunge80": "Cunge 80",
+    "select_loidebit2_cem88d": "Déversoir/Orifice Cemagref 88",
+    "select_loidebit2_cem88v": "Déversoir/Vanne de fond Cemagref 88",
+    "select_loidebit3_seuiltriang": "Déversoir triangulaire dénoyé",
+    "select_loidebit4_seuiltriangtrunc": "Déversoir triangulaire tronqué dénoyé",
+    "ZDV": "Cote de la crête du déversoir ou du radier de la vanne",
+    "L": "Largeur du déversoir",
+    "Cd": "Coefficient de débit",
+    "alpha": "Coefficient alpha",
+    "beta": "Coefficient béta",
+    "ZRAM": "Cote du radier amont",
+    "struct_container": "Ouvrages"
+}
\ No newline at end of file
diff --git a/src/app/calculators/lechapt-calmon/lechapt-calmon.config.json b/src/app/calculators/lechapt-calmon/lechapt-calmon.config.json
index b2bf6dac92a98fac7570a238c91511713b3c4902..fd24f30d650775f9769a53fc14fc21bc4232f17a 100644
--- a/src/app/calculators/lechapt-calmon/lechapt-calmon.config.json
+++ b/src/app/calculators/lechapt-calmon/lechapt-calmon.config.json
@@ -8,6 +8,9 @@
                 "id": "select_material",
                 "type": "select",
                 "select": [
+                    {
+                        "id": "select_material_0"
+                    },
                     {
                         "id": "select_material_1"
                     },
diff --git a/src/app/calculators/lechapt-calmon/lechapt-calmon.en.json b/src/app/calculators/lechapt-calmon/lechapt-calmon.en.json
index 47b3a9b00faeaab095e1c60c8a544e5662bce852..8a22b96b9ad4e7f81f85786843ac91d85390699b 100644
--- a/src/app/calculators/lechapt-calmon/lechapt-calmon.en.json
+++ b/src/app/calculators/lechapt-calmon/lechapt-calmon.en.json
@@ -1,6 +1,7 @@
 {
     "fs_materiau": "Type of material",
     "select_material": "Choice of material",
+    "select_material_0": "",
     "select_material_1": "Unlined cast iron - Coarse concrete (corrosive water)",
     "select_material_2": "Cast steel or uncoated - Coarse concrete (somewhat corrosive water)",
     "select_material_3": "Cast steel or cement coating",
diff --git a/src/app/calculators/lechapt-calmon/lechapt-calmon.fr.json b/src/app/calculators/lechapt-calmon/lechapt-calmon.fr.json
index 2db51b945f5cacf25da4614be96179bc7f4bfe13..4455f5680c386f07a28138217f11eff49cc65ff3 100644
--- a/src/app/calculators/lechapt-calmon/lechapt-calmon.fr.json
+++ b/src/app/calculators/lechapt-calmon/lechapt-calmon.fr.json
@@ -1,6 +1,7 @@
 {
     "fs_materiau": "Type du matériau",
     "select_material": "Choix du matériau",
+    "select_material_0": "",
     "select_material_1": "Fonte ou acier non revêtus - Béton grossier (eau corrosive)",
     "select_material_2": "Fonte ou acier non revêtus - Béton grossier (eau peu corrosive)",
     "select_material_3": "Fonte ou acier revêtement ciment",
diff --git a/src/app/calculators/macrorugo/macrorugo.en.json b/src/app/calculators/macrorugo/macrorugo.en.json
new file mode 100644
index 0000000000000000000000000000000000000000..0fb76a0b9ff14c1299c2f222a3f2d03a2d27921e
--- /dev/null
+++ b/src/app/calculators/macrorugo/macrorugo.en.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.en.json b/src/app/calculators/ouvrages/ouvrages.en.json
new file mode 100644
index 0000000000000000000000000000000000000000..16ac2c4c787d12539dea7db7ca98d213b6014776
--- /dev/null
+++ b/src/app/calculators/ouvrages/ouvrages.en.json
@@ -0,0 +1,29 @@
+{
+    "fs_ouvrage": "Type d'ouvrage",
+    "select_ouvrage": "Ouvrage",
+    "select_ouvrage_vanne_rect": "Vanne rectangulaire",
+    "select_loidebit1": "Loi de débit",
+    "select_loidebit1_cemagref88": "Déversoir/Orifice Cemagref 88",
+    "select_loidebit1_vannedenoye": "Vanne dénoyé",
+    "select_loidebit1_vannenoye": "Vanne noyé",
+    "select_loidebit2": "Loi de débit",
+    "select_loidebit2_cemagref88": "Déversoir/Orifice Cemagref 88",
+    "select_ouvrage_circ": "Vanne circulaire",
+    "select_ouvrage_seuil_rect": "Seuil rectangulaire",
+    "select_ouvrage_seuil_trap": "Seuil trapézoïdal",
+    "select_ouvrage_vanne_trap": "Vanne trapézoïdale",
+    "fs_caract_1": "Caractéristiques de l'ouvrage",
+    "larg": "Largeur",
+    "ouv": "Ouverture",
+    "kq": "Coefficient de débit",
+    "fs_caract_2": "Caractéristiques de l'ouvrage",
+    "fs_caract_3": "Caractéristiques de l'ouvrage",
+    "largf": "Largeur au fond",
+    "kqr": "Coefficient de débit partie rectangulaire",
+    "kqt": "Coefficient de débit partie triangulaire",
+    "fruit": "Fruit",
+    "fs_surverse": "Surverse",
+    "fs_hydraulique": "Caractéristiques globales",
+    "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/parallel-structures/parallel-structures.config.json b/src/app/calculators/parallel-structures/parallel-structures.config.json
index 8ba966d2715785286851985709a4f8a68c2ccd1e..2949378bbf21fcb91014096e88b5d104c460dffa 100644
--- a/src/app/calculators/parallel-structures/parallel-structures.config.json
+++ b/src/app/calculators/parallel-structures/parallel-structures.config.json
@@ -29,7 +29,7 @@
         "calcType": "Structure",
         "defaultNodeType": "StructureRectangle",
         "defaultStructType": "VanneRectangulaire",
-        "defaultLoiDebit": "Cem88v",
+        "defaultLoiDebit": "GateCem88v",
         "option": "cal",
         "fields": [
             {
@@ -60,11 +60,11 @@
                 "select": [
                     {
                         "id": "select_loidebit1_cem88d",
-                        "enum": "LoiDebit.Cem88d"
+                        "enum": "LoiDebit.WeirCem88d"
                     },
                     {
                         "id": "select_loidebit1_cem88v",
-                        "enum": "LoiDebit.Cem88v"
+                        "enum": "LoiDebit.WeirCem88v"
                     },
                     {
                         "id": "select_loidebit1_seuildenoye",
@@ -92,11 +92,11 @@
                 "select": [
                     {
                         "id": "select_loidebit2_cem88v",
-                        "enum": "LoiDebit.Cem88v"
+                        "enum": "LoiDebit.GateCem88v"
                     },
                     {
                         "id": "select_loidebit2_cem88d",
-                        "enum": "LoiDebit.Cem88d"
+                        "enum": "LoiDebit.GateCem88d"
                     },
                     {
                         "id": "select_loidebit2_vannedenoye",
diff --git a/src/app/calculators/parallel-structures/parallel-structures.en.json b/src/app/calculators/parallel-structures/parallel-structures.en.json
new file mode 100644
index 0000000000000000000000000000000000000000..41e09372681b99dee1115211a0a79aace5a23b2e
--- /dev/null
+++ b/src/app/calculators/parallel-structures/parallel-structures.en.json
@@ -0,0 +1,32 @@
+{
+    "fs_param_hydro": "Paramètres hydrauliques",
+    "Q": "Débit total",
+    "Z1": "Cote amont",
+    "Z2": "Cote aval",
+    "fs_ouvrage": "Ouvrage",
+    "select_ouvrage": "Ouvrage",
+    "select_ouvrage_vanne_circ": "Vanne circulaire",
+    "select_ouvrage_vanne_rect": "Vanne rectangulaire",
+    "select_ouvrage_seuil_rect": "Seuil rectangulaire",
+    "select_ouvrage_seuil_triang": "Seuil triangulaire",
+    "select_ouvrage_seuil_triangtrunc": "Seuil triangulaire tronqué",
+    "select_ouvrage_seuil_trap": "Seuil trapézoïdal",
+    "select_ouvrage_vanne_trap": "Vanne trapézoïdale",
+    "W": "Ouverture de vanne",
+    "select_loidebit1_seuildenoye": "Seuil dénoyé",
+    "select_loidebit1_cunge80": "Cunge 80",
+    "select_loidebit1_cem88d": "Déversoir/Orifice Cemagref 88",
+    "select_loidebit1_cem88v": "Déversoir/Vanne de fond Cemagref 88",
+    "select_loidebit1_kivi": "Kindsvater-Carter et Villemonte",
+    "select_loidebit2_vannedenoye": "Vanne dénoyé",
+    "select_loidebit2_vannenoye": "Vanne noyé",
+    "select_loidebit2_cunge80": "Cunge 80",
+    "select_loidebit2_cem88d": "Déversoir/Orifice Cemagref 88",
+    "select_loidebit2_cem88v": "Déversoir/Vanne de fond Cemagref 88",
+    "select_loidebit3_seuiltriang": "Déversoir triangulaire dénoyé",
+    "select_loidebit4_seuiltriangtrunc": "Déversoir triangulaire tronqué dénoyé",
+    "alpha2": "Demi-angle au sommet (°)",
+    "BT": "Demi-ouverture du triangle (m)",
+    "ZT": "Cote haute du triangle (m)",
+    "struct_container": "Ouvrages"
+}
\ No newline at end of file
diff --git a/src/app/calculators/section-param/section-param.en.json b/src/app/calculators/section-param/section-param.en.json
index 22e76429874dec90ce7a7afc5da5a1197a33a236..e84aae88ddd504bf1e4ba0335e6a364bd6b7d843 100644
--- a/src/app/calculators/section-param/section-param.en.json
+++ b/src/app/calculators/section-param/section-param.en.json
@@ -41,5 +41,23 @@
     "select_target_J": "Head loss (m)",
     "select_target_I-J": "Linear variation of specific head (m/m)",
     "select_target_Imp": "Impulse (N)",
-    "select_target_Tau0": "Tractive force (Pa)"
-}
\ No newline at end of file
+    "select_target_Tau0": "Tractive force (Pa)",
+
+    "Hs": "Charge spécifique",
+    "Hsc": "Charge critique",
+    "B": "Largeur au miroir",
+    "P": "Périmètre mouillé",
+    "S": "Surface mouillée",
+    "R": "Rayon hydraulique",
+    "V": "Vitesse moyenne",
+    "Fr": "Froude",
+    "Yc": "Tirant d'eau critique",
+    "Yn": "Tirant d'eau normal",
+    "Yf": "Tirant d'eau fluvial",
+    "Yt": "Tirant d'eau torrentiel",
+    "Yco": "Tirant d'eau conjugué",
+    "J": "Perte de charge",
+    "I-J": "Variation linéaire de l'énergie spécifique",
+    "Imp": "Impulsion",
+    "Tau0": "Force tractrice"
+}
diff --git a/src/app/calculators/section-param/section-param.fr.json b/src/app/calculators/section-param/section-param.fr.json
index 3620678ebb05f5925ca984d4b85538be3e0b1d8f..891e7b95eb8d399f66a6ddaec27cc4e6e59562a6 100644
--- a/src/app/calculators/section-param/section-param.fr.json
+++ b/src/app/calculators/section-param/section-param.fr.json
@@ -40,5 +40,23 @@
     "select_target_J": "La perte de charge (m)",
     "select_target_I-J": "Variation linéaire de l'énergie spécifique (m/m)",
     "select_target_Imp": "Impulsion (N)",
-    "select_target_Tau0": "La force tractrice (Pa)"
-}
\ No newline at end of file
+    "select_target_Tau0": "La force tractrice (Pa)",
+
+    "Hs": "Charge spécifique",
+    "Hsc": "Charge critique",
+    "B": "Largeur au miroir",
+    "P": "Périmètre mouillé",
+    "S": "Surface mouillée",
+    "R": "Rayon hydraulique",
+    "V": "Vitesse moyenne",
+    "Fr": "Froude",
+    "Yc": "Tirant d'eau critique",
+    "Yn": "Tirant d'eau normal",
+    "Yf": "Tirant d'eau fluvial",
+    "Yt": "Tirant d'eau torrentiel",
+    "Yco": "Tirant d'eau conjugué",
+    "J": "Perte de charge",
+    "I-J": "Variation linéaire de l'énergie spécifique",
+    "Imp": "Impulsion",
+    "Tau0": "Force tractrice"
+}
diff --git a/src/app/components/field-set/field-set.component.html b/src/app/components/field-set/field-set.component.html
index 3217d50f0ba485c834824abf92139f58b47292d8..e048b39153d6154fea40eec191fbefd36abab6e6 100644
--- a/src/app/components/field-set/field-set.component.html
+++ b/src/app/components/field-set/field-set.component.html
@@ -3,16 +3,16 @@
         {{ title }}
     </mat-card-title>
     <div *ngIf="showButtons" class="hyd-window-btns">
-        <button mat-icon-button (click)="onAddClick()">
+        <button type="button" mat-icon-button (click)="onAddClick()">
             <mat-icon>add_box</mat-icon>
         </button>
-        <button mat-icon-button [disabled]="! enableRemoveButton" (click)="onRemoveClick()">
+        <button type="button" mat-icon-button [disabled]="! enableRemoveButton" (click)="onRemoveClick()">
             <mat-icon>delete</mat-icon>
         </button>
-        <button mat-icon-button [disabled]="! enableUpButton" (click)="onMoveUpClick()">
+        <button type="button" mat-icon-button [disabled]="! enableUpButton" (click)="onMoveUpClick()">
             <mat-icon>arrow_upward</mat-icon>
         </button>
-        <button mat-icon-button [disabled]="! enableDownButton" (click)="onMoveDownClick()">
+        <button type="button" mat-icon-button [disabled]="! enableDownButton" (click)="onMoveDownClick()">
             <mat-icon>arrow_downward</mat-icon>
         </button>
     </div>
diff --git a/src/app/components/field-set/field-set.component.ts b/src/app/components/field-set/field-set.component.ts
index 5848aa4c1f961ab145c586232f86d6717386db71..170ba7cda872e75c9591c4b2022933f40cec04cf 100644
--- a/src/app/components/field-set/field-set.component.ts
+++ b/src/app/components/field-set/field-set.component.ts
@@ -32,7 +32,7 @@ export class FieldSetComponent implements DoCheck {
         if (! this._fieldSet) {
             return "fs undefined";
         }
-        if (! this._fieldSet.label) { // @TODO allow "" ?
+        if (! this._fieldSet.label) {
             return "label undefined";
         }
         return this._fieldSet.label;
diff --git a/src/app/components/fieldset-container/fieldset-container.component.ts b/src/app/components/fieldset-container/fieldset-container.component.ts
index 75caa880fcfb96ab8300ad8a00a09e162b39874a..15ca4d3e33a0c30d819d8b731ed32d8d20ffec51 100644
--- a/src/app/components/fieldset-container/fieldset-container.component.ts
+++ b/src/app/components/fieldset-container/fieldset-container.component.ts
@@ -68,7 +68,7 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit {
         }
     }
 
-    private onFielsetListChange() {
+    private onFieldsetListChange() {
         // affichage des boutons ajouter, supprimer, monter, descendre
         this._fieldsetComponents.forEach(fs => fs.showButtons = true);
 
@@ -100,8 +100,8 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit {
     }
 
     public ngAfterViewInit() {
-        this.onFielsetListChange();
-        this._fieldsetComponents.changes.subscribe(_ => this.onFielsetListChange());
+        this.onFieldsetListChange();
+        this._fieldsetComponents.changes.subscribe(_ => this.onFieldsetListChange());
     }
 
     /*
@@ -131,13 +131,13 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit {
                     // accumulator (valeur précédente du résultat)
                     acc,
                     // currentValue (élément courant dans le tableau)
-                    fielset,
+                    fieldset,
                     // currentIndex (indice courant dans le tableau)
                     currIndex,
                     // array (tableau parcouru)
                     array
                 ) => {
-                    return acc && fielset.isValid;
+                    return acc && fieldset.isValid;
                 }
                 // valeur initiale
                 , this._fieldsetComponents.length > 0);
diff --git a/src/app/components/generic-calculator/calculator.component.html b/src/app/components/generic-calculator/calculator.component.html
index 4c2623ff5d94eb7fc43befc6dd660c8dc4efcafc..064f4f5ec4d42f0052b33b5f54b6984c728e1d2d 100644
--- a/src/app/components/generic-calculator/calculator.component.html
+++ b/src/app/components/generic-calculator/calculator.component.html
@@ -40,7 +40,7 @@
 
                     <mat-card-actions>
                         <!-- bouton calculer -->
-                        <button mat-raised-button color="accent" name="Calculer" (click)="doCompute()"[disabled]="isCalculateDisabled">
+                        <button type="submit" id="trigger-calculate" mat-raised-button color="accent" name="Calculer" (click)="doCompute()"[disabled]="isCalculateDisabled">
                             {{ uitextCalculer }}
                         </button>
                     </mat-card-actions>
diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts
index e8c97032324028131f9dda6cb21bf7938681d244..14e30fc0ae9ce2238c615817ca6830a996171a4b 100644
--- a/src/app/components/generic-calculator/calculator.component.ts
+++ b/src/app/components/generic-calculator/calculator.component.ts
@@ -1,7 +1,7 @@
 import { Component, OnInit, DoCheck, OnDestroy, ViewChild, ViewChildren, QueryList, AfterViewChecked } from "@angular/core";
-import { ActivatedRoute } from "@angular/router";
+import { ActivatedRoute, Router } from "@angular/router";
 
-import { Observer } from "jalhyd";
+import { Observer, Session, ParallelStructure } from "jalhyd";
 
 import { FormulaireService } from "../../services/formulaire/formulaire.service";
 import { I18nService } from "../../services/internationalisation/internationalisation.service";
@@ -97,6 +97,7 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
 
     constructor(
         private route: ActivatedRoute,
+        private router: Router,
         private confirmCloseCalcDialog: MatDialog
     ) {
         super();
@@ -208,17 +209,6 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
         this.formulaireService.requestCloseForm(this._formulaire.uid);
     }
 
-    /**
-     * met à jour l'interface
-     */
-    // private updateUI() {
-    //     // this.appRef.tick();
-    //     // this.changeDetectorRef.detectChanges();  // provoque une détection des changements dans les contrôles
-    //     // if (!this.changeDetectorRef['destroyed']) // pour éviter l'erreur "Attempt to use a destroyed view: detectChanges"
-    //     //     this.changeDetectorRef.detectChanges();
-    //     this.changeDetectorRef.markForCheck();
-    // }
-
     /**
      * relit les valeurs dans l'interface et met à jour les NgParameter
      */
@@ -408,8 +398,14 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
         });
     }
 
+    /**
+     * Duplicates the current calculator form
+     */
     public cloneCalculator() {
-        const serializedForm = this._formulaire.JSONserialise()["form"];
-        this.formulaireService.deserialiseForm(serializedForm);
+        const serialisedNub: string = this._formulaire.currentNub.serialise({ title: this._formulaire.calculatorName });
+        const nubPointer = Session.getInstance().unserialiseSingleNub(serialisedNub);
+        this.formulaireService.createFormulaire(nubPointer.nub.calcType, nubPointer.nub, nubPointer.meta.title).then((f) => {
+            this.router.navigate(["/calculator", f.uid]);
+        });
     }
 }
diff --git a/src/app/components/param-computed/param-computed.component.html b/src/app/components/param-computed/param-computed.component.html
index eb582f98d402700628c2885a1ea772e7fa60e078..ee50ccaaf0f680caab6e02f0e50c2dcdca5ece1b 100644
--- a/src/app/components/param-computed/param-computed.component.html
+++ b/src/app/components/param-computed/param-computed.component.html
@@ -1,7 +1,7 @@
 <!-- a fake input bound to nothing, for the sake of UI consistency -->
 <mat-form-field>
     <input matInput disabled [id]="inputId" class="form-control" type="text" [ngModel]="infoText" [placeholder]="param.title">
-    <button *ngIf="isDicho" mat-icon-button class="param-computed-more" (click)="openDialog()">
+    <button type="button" *ngIf="isDicho" mat-icon-button class="param-computed-more" (click)="openDialog()">
         <mat-icon>more_horiz</mat-icon>
     </button>
 </mat-form-field>
diff --git a/src/app/components/param-field-line/param-field-line.component.html b/src/app/components/param-field-line/param-field-line.component.html
index f1ea01b5c1bd30da5d008c0a6a00601f180d398d..a9847d2b272656a448098d22908b4487672e131b 100644
--- a/src/app/components/param-field-line/param-field-line.component.html
+++ b/src/app/components/param-field-line/param-field-line.component.html
@@ -19,25 +19,25 @@
     <div class="toggle-group-container" fxFlex="0 0 auto">
         <mat-button-toggle-group *ngIf="hasRadioFix() || hasRadioVar() || hasRadioCal() || hasRadioLink()">
 
-            <mat-button-toggle id="radio_fix" value="radio_fix" 
+            <mat-button-toggle class="radio_fix" value="radio_fix" 
                 (click)="onRadioClick('fix')" [checked]="isRadioFixChecked">
                 <span fxHide.xxs>{{ uitextParamFixe }}</span>
                 <span fxHide.gt-xxs>F</span>
             </mat-button-toggle>
         
-            <mat-button-toggle id="radio_var" value="radio_var" *ngIf="hasRadioVar()"
+            <mat-button-toggle class="radio_var" value="radio_var" *ngIf="hasRadioVar()"
                 (click)="onRadioClick('var')" [checked]="isRadioVarChecked">
                 <span fxHide.xxs>{{ uitextParamVarier }}</span>
                 <span fxHide.gt-xxs>V</span>
             </mat-button-toggle>
         
-            <mat-button-toggle id="radio_cal" value="radio_cal" *ngIf="hasRadioCal()"
+            <mat-button-toggle class="radio_cal" value="radio_cal" *ngIf="hasRadioCal()"
                 (click)="onRadioClick('cal')" [checked]="isRadioCalChecked">
                 <span fxHide.xxs>{{ uitextParamCalculer }}</span>
                 <span fxHide.gt-xxs>C</span>
             </mat-button-toggle>
         
-            <mat-button-toggle id="radio_link" value="radio_link" *ngIf="hasRadioLink()"
+            <mat-button-toggle class="radio_link" value="radio_link" *ngIf="hasRadioLink()"
                 (click)="onRadioClick('link')" [checked]="isRadioLinkChecked">
                 <span fxHide.xxs>{{ uitextParamLie }}</span>
                 <span fxHide.gt-xxs>L</span>
diff --git a/src/app/components/param-link/param-link.component.ts b/src/app/components/param-link/param-link.component.ts
index bbc231d26787ae7f477592eab92ca90f68c9365b..2ef78c3ab9db95ce51c6fe149d7ad56100a9bae5 100644
--- a/src/app/components/param-link/param-link.component.ts
+++ b/src/app/components/param-link/param-link.component.ts
@@ -2,7 +2,7 @@ import { Component, Input, Output, EventEmitter, OnChanges, OnDestroy } from "@a
 
 import { NgParameter } from "../../formulaire/ngparam";
 import { ServiceFactory } from "../../services/service-factory";
-import { ParamValueMode, Observer } from "jalhyd";
+import { ParamValueMode, Observer, Structure } from "jalhyd";
 import { FormulaireService } from "../../services/formulaire/formulaire.service";
 import { I18nService } from "../..//services/internationalisation/internationalisation.service";
 
@@ -116,11 +116,20 @@ export class ParamLinkComponent implements OnChanges, Observer, OnDestroy {
         const s = i.name; // nom associé au paramètre/à la valeur
         const c = i.formTitle; // nom du module de calcul
 
-        const re5 = /(\d+)\.(.+)\.$/;  // forme <nombre>.xxx. (résultat d'ouvrage)
-        const match5 = re5.exec(s);
-        if (match5 !== null) {
-            const n = +match5[1] + 1;
-            return `${match5[2]} (résultat de ${c}, ouvrage n°${n})`;
+        // pointeur direct vers une Structure dans un Nub de type parallèle
+        if (i.nub && i.nub instanceof Structure) {
+            let p: number;
+            p = i.nub.findPositionInParent();
+            // forme xxx. (résultat)
+            const re4 = /([^\.]+)\.$/;
+            const match4 = re4.exec(s);
+            if (match4 !== null) {
+                // résultat d'ouvrage
+                return `${match4[1]} (résultat de ${c}, ouvrage ${p + 1})`;
+            } else {
+                // paramètre d'ouvrage
+                return `${s} (${c}, ouvrage ${p + 1})`;
+            }
         }
 
         const re1 = /([^\.]+)\.$/;  // forme xxx. (résultat)
@@ -129,13 +138,6 @@ export class ParamLinkComponent implements OnChanges, Observer, OnDestroy {
             return `${match1[1]} (résultat de ${c})`;
         }
 
-        const re4 = /(\d+)\.(.+)/;  // forme <nombre>.xxx (ouvrage)
-        const match4 = re4.exec(s);
-        if (match4 !== null) {
-            const n = +match4[1] + 1;
-            return `${match4[2]} (${c}, ouvrage n°${n})`;
-        }
-
         const re2 = /([^\.]+)\.(.+)/;  // forme xxx.yyy (résultat complémentaire)
         const match2 = re2.exec(s);
         if (match2 !== null) {
@@ -159,14 +161,12 @@ export class ParamLinkComponent implements OnChanges, Observer, OnDestroy {
         if (this._currentIndex !== index) {
             this._currentIndex = index;
             const lp = this._linkableParams[index];
-
             this.param.linkToParameter(lp.nub, lp.name);
         }
     }
 
     public updateParamList() {
         // liste des paramètres liables
-
         if (this.param.valueMode === ParamValueMode.LINK) {
             this._linkableParams = this._formService.filterLinkableValues(this._formService.getLinkableValues(this.param));
         } else {
diff --git a/src/app/components/param-values/param-values.component.html b/src/app/components/param-values/param-values.component.html
index 37cda318bfbb8ac4581d6f45ab2188656e7f89fd..171010493d0967599e36da5d580215e4ef64ba36 100644
--- a/src/app/components/param-values/param-values.component.html
+++ b/src/app/components/param-values/param-values.component.html
@@ -1,7 +1,7 @@
 <!-- a fake input bound to nothing, for the sake of UI consistency -->
 <mat-form-field>
     <input matInput disabled class="form-control" type="text" [ngModel]="infoText" [placeholder]="param.title">
-    <button mat-icon-button class="param-values-more" (click)="openDialog()">
+    <button type="button" mat-icon-button class="param-values-more" (click)="openDialog()">
         <mat-icon>more_horiz</mat-icon>
     </button>
 </mat-form-field>
diff --git a/src/app/formulaire/definition/concrete/form-base.ts b/src/app/formulaire/definition/concrete/form-base.ts
index ca294f0b280cb68588c637e8e2dbe3b1c5e004f3..6b28a0a2f5c228bfe4b62389295b7470d6ab58d3 100644
--- a/src/app/formulaire/definition/concrete/form-base.ts
+++ b/src/app/formulaire/definition/concrete/form-base.ts
@@ -7,8 +7,6 @@ import { FormComputeFixedVar } from "../form-compute-fixedvar";
 
 export class FormulaireBase extends FormulaireDefinition {
 
-    private _formFixedVar: FormDefFixedVar;
-
     private _formParamCalc: FormDefParamToCalculate;
 
     private _formCompute: FormComputeFixedVar;
@@ -23,10 +21,6 @@ export class FormulaireBase extends FormulaireDefinition {
         this._formCompute = new FormComputeFixedVar(this, this._formResult);
     }
 
-    protected initParse() {
-        this._formParamCalc.initParse();
-    }
-
     protected completeParse(json: {}) {
         this._formParamCalc.parseOptions(json);
     }
diff --git a/src/app/formulaire/definition/concrete/form-courbe-remous.ts b/src/app/formulaire/definition/concrete/form-courbe-remous.ts
index 2789da339cc20b63ed17e9c810c528ff3698e95b..a10cd4b88cd0d29662c4cdbbad88a584acd61d83 100644
--- a/src/app/formulaire/definition/concrete/form-courbe-remous.ts
+++ b/src/app/formulaire/definition/concrete/form-courbe-remous.ts
@@ -1,4 +1,4 @@
-import { IObservable } from "jalhyd";
+import { IObservable, MethodeResolution } from "jalhyd";
 
 import { FormResultRemous } from "../form-result-remous";
 import { FormDefSection } from "../form-def-section";
@@ -24,6 +24,9 @@ export class FormulaireCourbeRemous extends FormulaireDefinition {
         this._formSection = new FormDefSection(this);
         this._formResult = new FormResultRemous(this);
         this._formCompute = new FormComputeCourbeRemous(this, this._formSection, this._formResult);
+        // default properties
+        this._props["methodeResolution"] = MethodeResolution.Trapezes;
+        this._props["varCalc"] = undefined; // important
     }
 
     protected parseOptions(json: {}) {
@@ -72,6 +75,8 @@ export class FormulaireCourbeRemous extends FormulaireDefinition {
                     this.replaceCurrentNub(sender.properties);
                     for (const fs of this.allFieldsets) {
                         fs.setNub(this._currentNub);
+                        // treat the fieldset as new to re-seubscribe to Nub properties change events
+                        this.afterParseFieldset(fs);
                     }
                     this.reset();
                     break;
diff --git a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
index 586bd933087e2fbf390f25c96277c26fd90463df..69124f6461849b5fb874de3a0806496a761876e4 100644
--- a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
+++ b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
@@ -1,6 +1,7 @@
 import { Observer } from "jalhyd";
 import { SelectField } from "../../select-field";
 import { FormulaireBase } from "./form-base";
+import { NgParamInputComponent } from "../../../components/ngparam-input/ngparam-input.component";
 
 export class FormulaireLechaptCalmon extends FormulaireBase implements Observer {
 
@@ -8,6 +9,10 @@ export class FormulaireLechaptCalmon extends FormulaireBase implements Observer
         super.completeParse(json);
         // abonnement au changement de valeur du select de matériau
         this.getFormulaireNodeById("select_material").addObserver(this);
+        // abonnement au changement de valeur de l'un dex trois champs affectés par le changement de matériau
+        this.getParamFromSymbol("L").addObserver(this);
+        this.getParamFromSymbol("M").addObserver(this);
+        this.getParamFromSymbol("N").addObserver(this);
     }
 
     // interface Observer
@@ -19,5 +24,13 @@ export class FormulaireLechaptCalmon extends FormulaireBase implements Observer
                 this.reset();
             }
         }
+        if (sender instanceof NgParamInputComponent) {
+            if (data.action === "ngparamAfterValue") {
+                // value of L, M or N changed
+                const materialSelect = this.getFormulaireNodeById("select_material") as SelectField;
+                // reset material select field to "" (empty)
+                materialSelect.setValue(materialSelect.entries[0]);
+            }
+        }
     }
 }
diff --git a/src/app/formulaire/definition/concrete/form-parallel-structures.ts b/src/app/formulaire/definition/concrete/form-parallel-structures.ts
index 8e563f732817ee5ff32917aefa00ea3a4764fb40..615bf5c2687e0478f54d72c1c42a588ef124b86e 100644
--- a/src/app/formulaire/definition/concrete/form-parallel-structures.ts
+++ b/src/app/formulaire/definition/concrete/form-parallel-structures.ts
@@ -1,9 +1,8 @@
-import { Structure, Nub, ParallelStructure, StructureType, LoiDebit, StructureProperties, Props } from "jalhyd";
+import { Structure, Nub, ParallelStructure, StructureType, LoiDebit, StructureProperties, Props, Session } from "jalhyd";
 
 import { FormulaireDefinition } from "../form-definition";
 import { CalculatorResults } from "../../../results/calculator-results";
 import { FormDefParamToCalculate } from "../form-def-paramcalc";
-import { FormDefFixedVar } from "../form-def-fixedvar";
 import { FormDefParallelStructures } from "../form-def-parallel-structures";
 import { FormComputeParallelStructures } from "../form-compute-parallel-structures";
 import { FormResultFixedVar } from "../form-result-fixedvar";
@@ -52,7 +51,7 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
         params["structureType"] = templ.defaultStructTypeFromConfig;
         params["loiDebit"] = templ.defaultLoiDebitFromConfig;
 
-        return this.createNub(params);
+        return this.createStructure(new Props(params));
     }
 
     /**
@@ -68,14 +67,48 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
         return this.currentNub as ParallelStructure;
     }
 
-    public createFieldset(parent: FormulaireNode, json: {}, data?: {}): FieldSet {
+    /**
+     * Asks JaLHyd to create a Structure Nub as a child of the current Calculator Module
+     * and return it; does not store it in the Session (for Structures, not for Calculator Modules)
+     * @param p properties for the new Nub
+     */
+    protected createStructure(p: Props): Structure {
+        return Session.getInstance().createNub(p, this.currentNub as ParallelStructure) as Structure;
+    }
+
+    /**
+     * Replaces the current Nub in the current calculator module, with a new one built with properties "params"
+     * @param params properties to build the new Nub (calcType, loiDebit...)
+     */
+    protected replaceNub(sn: Structure, params: Props): Nub {
+        const parent = (this.currentNub as ParallelStructure);
+        const newStructure = this.createStructure(params);
+        parent.replaceStructureInplace(sn, newStructure);
+        return newStructure;
+    }
+
+    /**
+     * Deleted the given child Nub in the current calculator module
+     * @param params properties to build the new Nub (calcType, loiDebit...)
+     */
+    protected deleteNub(sn: Structure) {
+        const parent = (this.currentNub as ParallelStructure);
+        parent.deleteStructure(parent.getIndexForStructure(sn));
+    }
+
+    public createFieldset(parent: FormulaireNode, json: {}, data?: {}, nub?: Nub): FieldSet {
         if (json["calcType"] === "Structure") {
             // indice après lequel insérer le nouveau FieldSet
             const after = data["after"];
 
             const res: FieldSet = new FieldSet(parent);
-            const sn = this.createStructNub(data["template"]);
-            this.addStructureNub(sn as Structure, after);
+            let sn: Nub;
+            if (nub) { // use existing Nub (build interface based on model)
+                sn = nub;
+            } else {
+                sn = this.createStructNub(data["template"]);
+                this.addStructureNub(sn as Structure, after);
+            }
             res.setNub(sn, false);
 
             if (after !== undefined) {
@@ -92,10 +125,6 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
         }
     }
 
-    protected initParse() {
-        this._formParamCalc.initParse();
-    }
-
     protected parseOptions(json: {}) {
         super.parseOptions(json);
 
@@ -139,12 +168,14 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
     }
 
     public removeFieldset(fs: FieldSet) {
+        // console.log("==> FormParallelStructures removeFieldset", fs.uid);
         if (fs.nub instanceof Structure) {
-            // suppression du nub
-            this._paramService.deleteNub(fs.nub);
+            // suppression du sous-nub dans le Nub parent
+            this.deleteNub(fs.nub);
 
             // suppression du fieldset
             this.fieldsetContainer.removeFieldset(fs);
+            // console.log("====> nb struct dans le parent après", (this.currentNub as ParallelStructure).structures.length);
 
             this.resetResults();
         } else { super.removeFieldset(fs); }
@@ -282,7 +313,9 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
             throw new Error(`pas de select trouvé avec une dépendance au select 'type de structure' pour la valeur ${structSelect.select.id}=${structSelect.entry.id} (2)`);
         }
 
-        res.setPropValue("loiDebit", StructureProperties.findCompatibleLoiDebit(structType, loisDebit));
+        res.setPropValue("loiDebit", StructureProperties.findCompatibleLoiDebit(
+            structType, loisDebit, this.currentNub as ParallelStructure) // currentNub should always be a ParallelStructure here
+        );
 
         return res;
     }
@@ -303,7 +336,9 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
         // (par ex, s'il existe un select de lois de débit dépendant du select de types
         // d'ouvrage, on prend la 1ère entrée du select de lois de débit compatible)
         if (name === "structureType") {
-            if (!StructureProperties.isCompatibleValues(val, fs.properties.getPropValue("loiDebit"))) {
+            if (!StructureProperties.isCompatibleValues(
+                val, fs.properties.getPropValue("loiDebit"), this.currentNub as ParallelStructure)
+            ) {
                 return this.adjustLoiDebit(fs, val);
             }
         }
@@ -357,8 +392,10 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
             switch (sender.id) {
                 case "fs_ouvrage":
                     const props = this.adjustProperties(sender, data["name"], data["value"]);
-                    const newNub = this.replaceNub(sender.nub, props);
+                    const newNub = this.replaceNub((sender.nub as Structure), props);
                     sender.setNub(newNub);
+                    // treat the fieldset as new to re-seubscribe to Nub properties change events
+                    this.afterParseFieldset(sender);
                     this.reset();
                     break;
             }
diff --git a/src/app/formulaire/definition/concrete/form-regime-uniforme.ts b/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
index 63ed5d5a8249cba95173d3ce91ed355774f7accf..611098f1f32d6dde1ca681f775d3b68b9e8ddee1 100644
--- a/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
+++ b/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
@@ -28,10 +28,6 @@ export class FormulaireRegimeUniforme extends FormulaireDefinition implements Ob
         this._formCompute = new FormComputeFixedVar(this, this._formResult);
     }
 
-    protected initParse() {
-        this._formParamCalc.initParse();
-    }
-
     protected parseOptions(json: {}) {
         super.parseOptions(json);
         this._formSection.parseOptions(json);
@@ -82,6 +78,8 @@ export class FormulaireRegimeUniforme extends FormulaireDefinition implements Ob
             this.replaceCurrentNub(sender.properties);
             for (const fs of this.allFieldsets) {
                 fs.setNub(this._currentNub);
+                // treat the fieldset as new to re-seubscribe to Nub properties change events
+                this.afterParseFieldset(fs);
             }
             this.reset();
         }
diff --git a/src/app/formulaire/definition/concrete/form-section-parametree.ts b/src/app/formulaire/definition/concrete/form-section-parametree.ts
index 651ec045358362be6e6a3efbd4e21b7a2b5a1c13..5e4409b9178a327f8039e4f2bbb26219aaf99879 100644
--- a/src/app/formulaire/definition/concrete/form-section-parametree.ts
+++ b/src/app/formulaire/definition/concrete/form-section-parametree.ts
@@ -23,6 +23,8 @@ export class FormulaireSectionParametree extends FormulaireDefinition {
         this._formSection = new FormDefSection(this);
         this._formSectionResult = new FormResultSection(this, this._formSection);
         this._formCompute = new FormComputeSectionParametree(this, this._formSection, this._formSectionResult);
+        // default properties
+        this._props["varCalc"] = "Hs";
     }
 
     protected parseOptions(json: {}) {
@@ -68,6 +70,8 @@ export class FormulaireSectionParametree extends FormulaireDefinition {
                     this.replaceCurrentNub(sender.properties);
                     for (const fs of this.allFieldsets) {
                         fs.setNub(this._currentNub);
+                        // treat the fieldset as new to re-seubscribe to Nub properties change events
+                        this.afterParseFieldset(fs);
                     }
                     this.reset();
                     break;
diff --git a/src/app/formulaire/definition/form-compute-courbe-remous.ts b/src/app/formulaire/definition/form-compute-courbe-remous.ts
index e65553d0e21153774418e6bedb23ca0ef6e80b48..dc3a6a2e26789f4c9f2431fbb663e1150b4fbd81 100644
--- a/src/app/formulaire/definition/form-compute-courbe-remous.ts
+++ b/src/app/formulaire/definition/form-compute-courbe-remous.ts
@@ -1,6 +1,5 @@
 import { acSection, Result, MethodeResolution, CourbeRemousParams, CourbeRemous } from "jalhyd";
 
-import { SelectField } from "../select-field";
 import { RemousResults } from "../../results/remous-results";
 import { FormulaireDefinition } from "./form-definition";
 import { FormDefSection } from "./form-def-section";
@@ -19,7 +18,7 @@ export class FormComputeCourbeRemous extends FormCompute {
 
     protected compute() {
         const cr: CourbeRemous = this._formBase.currentNub as CourbeRemous;
-        const prmCR: CourbeRemousParams = cr.parameters as CourbeRemousParams;
+        const prmCR: CourbeRemousParams = cr.prms as CourbeRemousParams;
         const sect: acSection = prmCR.Sn;
 
         const Yn: Result = sect.Calc("Yn"); // hauteur normale
@@ -27,21 +26,13 @@ export class FormComputeCourbeRemous extends FormCompute {
 
         this.remousResults.parameters = prmCR;
 
-        // méthode de résolution
-
-        const msf: SelectField = <SelectField>this._formBase.getFormulaireNodeById("select_resolution");
-        const methRes: MethodeResolution = msf.getValue().value;
-
         // variable supplémentaire à calculer
-
-        this.remousResults.extraParamSymbol = this._formBase.getSelectedValue("select_target");
+        this.remousResults.extraParamSymbol = this._formBase.currentNub.properties.getPropValue("varCalc");
 
         // calcul
-
         this.remousResults.result = cr.calculRemous(this.remousResults.extraParamSymbol);
 
         // données du graphe
-
         this.remousResults.hauteurNormale = Yn.resultElement;
         this.remousResults.hauteurCritique = Yc.resultElement;
         if (this.remousResults.extraParamSymbol) {
diff --git a/src/app/formulaire/definition/form-compute-fixedvar.ts b/src/app/formulaire/definition/form-compute-fixedvar.ts
index 7b64ec15da3be9b36d88fe94169fe05562f711c0..300703a6dbea78fe966754cfff313d30b6bdd468 100644
--- a/src/app/formulaire/definition/form-compute-fixedvar.ts
+++ b/src/app/formulaire/definition/form-compute-fixedvar.ts
@@ -44,27 +44,18 @@ export class FormComputeFixedVar extends FormCompute {
 
     protected compute() {
         const nub: Nub = this._formBase.currentNub;
-        let computePrec: number;
-        if (this._formBase.hasParameter("Pr")) {
-            computePrec = this._formBase.getParameterValue("Pr"); // précision de calcul
-        }
-
         const computedParam: NgParameter = this.getComputedParameter();
-
         this.formResult.addFixedParameters();
-
         const varParam: NgParameter = this.getVariatedParameter();
 
         if (varParam === undefined) {
             // pas de paramètre à varier
-
-            const res: Result = this.runNubCalc(nub, computedParam, computePrec);
+            const res: Result = this.runNubCalc(nub, computedParam);
             this.formResult.fixedResults.result = res;
             this.formResult.fixedResults.calculatedParameter = computedParam;
         } else {
             // il y a un paramètre à varier
-
-            const res: Result = this.runNubCalc(nub, computedParam, computePrec);
+            const res: Result = this.runNubCalc(nub, computedParam);
 
             this.formResult.varResults.variatedParameter = varParam;
             this.formResult.varResults.calculatedParameter = computedParam;
diff --git a/src/app/formulaire/definition/form-compute-parallel-structures.ts b/src/app/formulaire/definition/form-compute-parallel-structures.ts
index f53ef23d8d62641495cafde08b99e4fe2fb8620d..9daa4cbd6cf61b2db18eb0e1173ee28dfc3ed49d 100644
--- a/src/app/formulaire/definition/form-compute-parallel-structures.ts
+++ b/src/app/formulaire/definition/form-compute-parallel-structures.ts
@@ -1,13 +1,8 @@
-import {
-    ComputeNode, ParamsEquation, ParallelStructure, ParallelStructureParams, CalculatorType, StructureParams,
-    Structure, CreateStructure, StructureType, ComputeNodeType, LoiDebit
-} from "jalhyd";
+import { ComputeNode, ParallelStructure } from "jalhyd";
 
 import { FormComputeFixedVar } from "./form-compute-fixedvar";
 import { FormResultFixedVar } from "./form-result-fixedvar";
 import { FormulaireDefinition } from "./form-definition";
-import { SelectField } from "../select-field";
-import { FormulaireElement } from "../formulaire-element";
 import { NgParameter } from "../ngparam";
 import { FormulaireNode } from "../formulaire-node";
 import { FieldSet } from "../fieldset";
diff --git a/src/app/formulaire/definition/form-compute-section-parametree.ts b/src/app/formulaire/definition/form-compute-section-parametree.ts
index ab2c327b54088ca42c14fb962d9590b6a6886923..1da49fa7e4ac4516f2f60bcb113878b54676e791 100644
--- a/src/app/formulaire/definition/form-compute-section-parametree.ts
+++ b/src/app/formulaire/definition/form-compute-section-parametree.ts
@@ -1,33 +1,25 @@
-import { SectionParametree, acSection, Result } from "jalhyd";
+import { SectionParametree, acSection, Result, ParamDomain, ParamDefinition, ParamDomainValue } from "jalhyd";
 
 import { FormCompute } from "./form-compute";
 import { NgParameter } from "../ngparam";
 import { FormResult } from "./form-result";
 import { FormDefSection } from "./form-def-section";
 import { FormResultSection } from "./form-result-section";
-import { FixedResults } from "../../results/fixed-results";
 import { VarResults } from "../../results/var-results";
 import { SectionResults } from "../../results/section-results";
 import { FormulaireDefinition } from "./form-definition";
-import { ServiceFactory } from "../../services/service-factory";
-import { ParamService } from "../../services/param/param.service";
+import { FormulaireNode } from "../formulaire-node";
 
 export class FormComputeSectionParametree extends FormCompute {
-    private _paramService: ParamService;
 
     constructor(formBase: FormulaireDefinition, private _formSection: FormDefSection, formResult: FormResult) {
         super(formBase, formResult);
-        this._paramService = ServiceFactory.instance.paramService;
     }
 
     private get _formSectionResult(): FormResultSection {
         return this._formResult as FormResultSection;
     }
 
-    private get _fixResults(): FixedResults {
-        return this._formSectionResult.fixedResults;
-    }
-
     private get _varResults(): VarResults {
         return this._formSectionResult.varResults;
     }
@@ -41,8 +33,6 @@ export class FormComputeSectionParametree extends FormCompute {
      * @param varParam paramètre à varier
      */
     private doComputeSectionVar(varParam: NgParameter) {
-        const computePrec: number = this._formBase.getParameterValue("Pr"); // précision de calcul
-        const nDigits = -Math.log10(computePrec);
 
         this._formSectionResult.addSectionFixedParameters(false);
 
@@ -51,18 +41,15 @@ export class FormComputeSectionParametree extends FormCompute {
 
         const sectNub: SectionParametree = this._formBase.currentNub as SectionParametree;
         const sect: acSection = sectNub.section;
-        const prms = sectNub.parameters;
 
         this._sectionResults.section = sect;
 
         this._varResults.variatedParameter = varParam;
 
-        const computedParam: NgParameter = this._paramService.createParameter(computedParamInfo.symbol, this._formBase);
+        const computedParam: NgParameter = this.createParameter(computedParamInfo.symbol, this._formBase);
         this._varResults.calculatedParameter = computedParam;
 
-        const compSymbol: string = computedParamInfo["symbol"];
-
-        this._varResults.result = this.runNubCalc(sectNub, computedParam, computePrec);
+        this._varResults.result = this.runNubCalc(sectNub, computedParam);
         this._varResults.graphTitle = computedParamInfo.symbol + " = f( " + varParam.symbol + " )";
         this._varResults.update(false);
     }
@@ -79,8 +66,7 @@ export class FormComputeSectionParametree extends FormCompute {
         const sect: acSection = sectNub.section;
         this._sectionResults.section = sect;
 
-        const computePrec: number = this._formBase.getParameterValue("Pr"); // précision de calcul
-        const tmpResult: Result = sectNub.CalcSerie(computePrec,
+        const tmpResult: Result = sectNub.CalcSerie(
             undefined, // valeur initiale, non utilisée dans ce cas
             undefined // variable à calculer, non utilisée
         );
@@ -92,4 +78,65 @@ export class FormComputeSectionParametree extends FormCompute {
         this._formSectionResult.addSectionFixedParameters(false);
         this._formSectionResult.fixedResults.result = tmpResult;
     }
+
+    /**
+     *
+     * @param calcType crée un NgParameter n'appartenant pas à un ComputeNode
+     * @param symbol symbole du paramètre à créer
+     */
+    private createParameter(symbol: string, parent: FormulaireNode): NgParameter {
+        let p: NgParameter;
+        const dom = new ParamDomain(ParamDomainValue.POS_NULL);
+        p = new NgParameter(new ParamDefinition(null, symbol, dom), parent);
+        p.confId = symbol;
+
+        switch (symbol) {
+            case "Hs":
+            case "Hsc":
+            case "B":
+            case "P":
+            case "R":
+            case "Yc":
+            case "Yn":
+            case "Yf":
+            case "Yt":
+            case "Yco":
+            case "J":
+                p.unit = "m";
+                break;
+
+            case "S":
+                p.unit = "m2";
+                break;
+
+            case "V":
+                p.unit = "m/s";
+                break;
+
+            case "I-J":
+                p.unit = "m/m";
+                break;
+
+            case "Fr":
+                p.unit = "";
+                break;
+
+            case "Imp":
+                p.unit = "N";
+                break;
+
+            case "Tau0":
+                p.unit = "Pa";
+                break;
+
+            case "Pr":
+                break;
+
+            default:
+                throw new Error(`ParamService.createParameter() : symbole ${symbol} non pris en charge`);
+        }
+        p.updateLocalisation(this._formBase.specificLocalisation);
+
+        return p;
+    }
 }
diff --git a/src/app/formulaire/definition/form-compute.ts b/src/app/formulaire/definition/form-compute.ts
index 6d9b33ea20285e770a68cf981789972c2b3eece5..4e8494753862af7cb478da8204cf880959a5a5b5 100644
--- a/src/app/formulaire/definition/form-compute.ts
+++ b/src/app/formulaire/definition/form-compute.ts
@@ -25,7 +25,7 @@ export abstract class FormCompute {
     /**
      * lance le calcul d'un paramètre en déterminant une valeur initiale
      */
-    protected runNubCalc(nub: Nub, computedParam: NgParameter, prec: number): Result {
+    protected runNubCalc(nub: Nub, computedParam: NgParameter): Result {
         let init: number;
         switch (computedParam.domain.domain) {
             case ParamDomainValue.ANY:
@@ -69,7 +69,7 @@ export abstract class FormCompute {
                 break;
         }
 
-        return nub.CalcSerie(prec, init, this.getParameterRefid(computedParam));
+        return nub.CalcSerie(init, this.getParameterRefid(computedParam));
     }
 
     public doCompute() {
diff --git a/src/app/formulaire/definition/form-def-paramcalc.ts b/src/app/formulaire/definition/form-def-paramcalc.ts
index b31c93a1489f3b2e13900640eeddc6e1071d806a..c78cbc8e7cc238bc60d9fc4cedf63f54adcb6172 100644
--- a/src/app/formulaire/definition/form-def-paramcalc.ts
+++ b/src/app/formulaire/definition/form-def-paramcalc.ts
@@ -1,9 +1,8 @@
 import { ParamValueMode } from "jalhyd";
 
-import { ParamRadioConfig, NgParameter } from "../ngparam";
+import { NgParameter } from "../ngparam";
 import { FormulaireDefinition } from "./form-definition";
 import { FormDefFixedVar } from "./form-def-fixedvar";
-import { NgParamInputComponent } from "../../components/ngparam-input/ngparam-input.component";
 
 /**
  * gestion des formulaires avec "paramètre à calculer" (conduite distributrice, Lechapt-Calmon, régime uniforme, passes à bassin)
@@ -18,18 +17,16 @@ export class FormDefParamToCalculate extends FormDefFixedVar {
         super(base);
     }
 
-    public initParse() {
-        this._defaultCalculatedParam = undefined;
-    }
-
     public parseOptions(json: {}) {
+        this._defaultCalculatedParam = undefined;
+        // browse config file to find "options" chapter
         for (const k in json) {
             const o = json[k];
             if (o.type === "options") {
                 // id du paramètre à calculer par défaut
-
                 this._defaultCalculatedParam = o["idCal"];
-                if (this._defaultCalculatedParam !== undefined) {
+                // this._formBase
+                if (this._defaultCalculatedParam && ! this.findCalculatedParam()) {
                     const p = this.setDefault();
                     p.isDefault = true;
                 }
@@ -37,6 +34,17 @@ export class FormDefParamToCalculate extends FormDefFixedVar {
         }
     }
 
+    /**
+     * Find the parameter that is set to CALC mode
+     */
+    private findCalculatedParam() {
+        for (const p of this._formBase.currentNub.parameterIterator) {
+            if (p.valueMode === ParamValueMode.CALCUL) {
+                return p;
+            }
+        }
+    }
+
     /**
      * met le paramètre par défaut à CAL sauf si c'est "except"
      * @param except paramètre à ne pas remettre à CAL
diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index 390718dcd6c94fe67c1efa92400c9b13a1958617..c78215b082df55369ad6e52f31f3e50df1c10159 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -1,12 +1,10 @@
-import { CalculatorType, ComputeNodeType, Nub, Props, Observer } from "jalhyd";
+import { CalculatorType, ComputeNodeType, Nub, Props, Observer, Session, ParallelStructure } from "jalhyd";
 
 import { FormulaireElement } from "../formulaire-element";
 import { NgParameter, ParamRadioConfig } from "../ngparam";
 import { Field } from "../field";
 import { StringMap } from "../../stringmap";
 import { FormulaireNode } from "../formulaire-node";
-import { ServiceFactory } from "../../services/service-factory";
-import { ParamService } from "../../services/param/param.service";
 import { FieldSet } from "../fieldset";
 import { FieldsetContainer } from "../fieldset-container";
 import { SelectField } from "../select-field";
@@ -19,36 +17,40 @@ import { CalculatorResults } from "../../results/calculator-results";
  * classe de base pour tous les formulaires
  */
 export abstract class FormulaireDefinition extends FormulaireNode implements Observer {
-    /**
-     * nom du module de calcul
-     */
+    /** nom du module de calcul */
     private _calculatorName: string;
 
-    /**
-     * Nub courant
-     */
+    /** Nub courant */
     protected _currentNub: Nub;
 
-    /**
-     * propriétés par défaut (lues si _currentNub === undefined )
-     */
-    private _props = {};
+    /** propriétés par défaut (lues si _currentNub === undefined ) */
+    protected _props = {};
 
-    /**
-     * fichier de configuration
-     */
+    /** fichier de configuration */
     private _jsonConfig: {};
 
-    /**
-     * aide en ligne
-     */
+    /** aide en ligne */
     private _helpLink: string;
 
-    protected _paramService: ParamService;
+    /** clé-valeurs du fichier de localisation spécifique à ce module */
+    private _specificLocalisation: StringMap;
 
     constructor() {
         super(undefined);
-        this._paramService = ServiceFactory.instance.paramService;
+    }
+
+    // surcharge de FormulaireNode::get:uid()
+    // l'UID d'un formulaire est l'UID de son Nub !
+    public get uid() {
+        if (this._currentNub) {
+            return this._currentNub.uid;
+        } else {
+            throw new Error("Aucun Nub associé au formulaire !");
+        }
+    }
+
+    public get specificLocalisation() {
+        return this._specificLocalisation;
     }
 
     public get calculatorType(): CalculatorType {
@@ -81,8 +83,8 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
         return this._props;
     }
 
-    public initNub(props?: {}) {
-        this._currentNub = this.createNub(props === undefined ? this.defaultProperties : props);
+    public initNub(props?: Props) {
+        this._currentNub = this.createNub(props ? props : new Props(this.defaultProperties));
     }
 
     public get currentNub(): Nub {
@@ -99,24 +101,25 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
         this._currentNub = n;
     }
 
-    protected createNub(params: Props | {}): Nub {
-        const props = params instanceof Props ? params : new Props(params);
-        return this._paramService.createNub(props);
+    /**
+     * Asks JaLHyd to create a Nub and keep in in the Session (for Calculator Modules, not for Structures)
+     * @param p properties for the new Nub
+     * @param parentNub optional parent Nub when creating a Structure Nub, for admissible laws check
+     */
+    protected createNub(p: Props): Nub {
+        return Session.getInstance().createSessionNub(p);
     }
 
     protected replaceCurrentNub(params: Props) {
-        this.currentNub = this._paramService.replaceNub(this._currentNub, params);
+        this.currentNub = Session.getInstance().replaceNub(this._currentNub, params);
     }
 
     protected replaceNub(sn: Nub, params: Props): Nub {
-        return this._paramService.replaceNub(sn, params);
+        return Session.getInstance().replaceNub(sn, params);
     }
 
     protected deleteNub(sn: Nub) {
-        this._paramService.deleteNub(sn);
-    }
-
-    protected initParse() {
+        Session.getInstance().deleteNub(sn);
     }
 
     protected parseOptions(json: {}) {
@@ -137,7 +140,7 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
     public afterParseFieldset(fs: FieldSet) {
     }
 
-    public createFieldset(parent: FormulaireNode, json: {}, data?: {}): FieldSet {
+    public createFieldset(parent: FormulaireNode, json: {}, data?: {}, nub?: Nub): FieldSet {
         const res: FieldSet = new FieldSet(parent);
         res.setNub(this._currentNub, false);
         this.kids.push(res);
@@ -161,8 +164,8 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
     public removeFieldset(fs: FieldSet) {
     }
 
-    private parse_fieldset(json: {}) {
-        const fs = this.createFieldset(this, json);
+    private parse_fieldset(json: {}, nub?: Nub) {
+        const fs = this.createFieldset(this, json, undefined, nub);
         fs.parseConfig(json);
         this.afterParseFieldset(fs);
     }
@@ -208,8 +211,6 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
     public preparseConfig(json: {}) {
         this._jsonConfig = json;
 
-        this.initParse();
-
         // analyse des options globales
         // il est utile de le faire avant le reste pour les modules de calcul utilisant
         // des sections (id des selects type de section/variable à calculer)
@@ -395,6 +396,7 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
     public abstract get results(): CalculatorResults[];
 
     public updateLocalisation(localisation: StringMap) {
+        this._specificLocalisation = localisation;
         for (const fe of this.topFormElements) {
             fe.updateLocalisation(localisation);
         }
@@ -455,78 +457,7 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
     }
 
     /**
-     * sérialisation en JSON
-     */
-    public JSONserialise(): {} {
-        const res = {};
-        res["id"] = this.calculatorName;
-        res["uid"] = this.uid;
-        res["props"] = (this._currentNub.properties as Props).props;
-        res["elements"] = this.serialiseKids();
-        return { "form": res };
-    }
-
-    private deserialiseFieldset(elements: {}): FieldSet {
-        const res: FieldSet = this.getFormulaireNodeById(elements["id"]) as FieldSet;
-        res.deserialiseJSON(elements);
-        return res;
-    }
-
-    private deserialiseFieldsetContainer(elements: {}): FieldsetContainer {
-        const res: FieldsetContainer = this.getFormulaireNodeById(elements["id"]) as FieldsetContainer;
-        res.deserialiseJSON(elements);
-        return res;
-    }
-
-    private deserialiseElement(element: {}) {
-        const keys = Object.keys(element);
-        if (keys.length !== 1) {
-            throw new Error(`session file : invalid form object '${element}'`);
-        }
-
-        switch (keys[0]) {
-            case "fieldset":
-                this.deserialiseFieldset(element[keys[0]]);
-                break;
-
-            case "fieldset_container":
-                this.deserialiseFieldsetContainer(element[keys[0]]);
-                break;
-
-            default:
-                throw new Error(`session file : invalid key '${keys[0]}' in form object`);
-        }
-    }
-
-    /**
-     * désérialisation depuis JSON
-     */
-    public deserialiseJSON(elements: {}) {
-        // tslint:disable-next-line:forin
-        for (const k in elements) {
-            switch (k) {
-                case "id":
-                    this._calculatorName = elements[k];
-                    break;
-
-                case "uid":
-                case "props":
-                    break;
-
-                case "elements":
-                    for (const e of elements[k]) {
-                        this.deserialiseElement(e);
-                    }
-                    break;
-
-                default:
-                    throw new Error(`session file : invalid key '${k}' in form object`);
-            }
-        }
-    }
-
-    /**
-     * MAJ des liens entre paramètres lors de la désérialisation JSON
+     * MAJ des liens entre paramètres lors de la désérialisation
      */
 
     private getNthFieldset(n: number): FieldSet {
diff --git a/src/app/formulaire/fieldset-container.ts b/src/app/formulaire/fieldset-container.ts
index 6f2898e7f166625b41ba2cc5bd3a74ecb7c59d97..b94eac578c34f46b2f06282bee26055c983f2a36 100644
--- a/src/app/formulaire/fieldset-container.ts
+++ b/src/app/formulaire/fieldset-container.ts
@@ -3,6 +3,7 @@ import { FieldSet } from "./fieldset";
 import { FieldsetTemplate } from "./fieldset-template";
 import { StringMap } from "../stringmap";
 import { FormulaireNode } from "./formulaire-node";
+import { Nub } from "jalhyd";
 
 export class FieldsetContainer extends FormulaireElement {
     private _templates: FieldsetTemplate[];
@@ -75,10 +76,10 @@ export class FieldsetContainer extends FormulaireElement {
      * @param templateIndex indice du template dans la liste
      * @param after insère le nouveau FieldSet après cette position, à la fin sinon
      */
-    public addFromTemplate(templateIndex: number, after?: number): FieldSet {
+    public addFromTemplate(templateIndex: number, after?: number, nub?: Nub): FieldSet {
         const templ: FieldsetTemplate = this._templates[templateIndex];
 
-        const inst: FieldSet = templ.instantiateTemplate(this, after);
+        const inst: FieldSet = templ.instantiateTemplate(this, after, nub);
 
         this.updateLocalisation();
 
@@ -115,65 +116,4 @@ export class FieldsetContainer extends FormulaireElement {
             super.updateLocalisation(loc);
         }
     }
-
-    /**
-     * sérialisation en JSON
-     */
-    public JSONserialise(): {} {
-        const res = {};
-        res["id"] = this.id;
-        res["elements"] = this.serialiseKids();
-        return { "fieldset_container": res };
-    }
-
-    private deserialiseFieldset(elements: {}): FieldSet {
-        const ind = this.getTemplateIndex(elements["id"]);
-        const res: FieldSet = this.addFromTemplate(ind);
-        const props = elements["props"];
-        for (const k in props) {
-            if (k !== "calcType" && k !== "nodeType") {
-                res.setPropValue(k, props[k]);
-            }
-        }
-        res.deserialiseJSON(elements);
-        return res;
-    }
-
-    private deserialiseElement(element: {}) {
-        const keys = Object.keys(element);
-        if (keys.length !== 1) {
-            throw new Error(`session file : invalid fieldset object '${element}'`);
-        }
-
-        switch (keys[0]) {
-            case "fieldset":
-                this.deserialiseFieldset(element[keys[0]]);
-                break;
-
-            default:
-                throw new Error(`session file : invalid key '${keys[0]}' in fieldset object`);
-        }
-    }
-
-    /**
-     * désérialisation depuis JSON
-     */
-    public deserialiseJSON(elements: {}) {
-        for (const k in elements) {
-            switch (k) {
-                case "id":
-                    this._confId = elements[k];
-                    break;
-
-                case "elements":
-                    for (const e of elements[k]) {
-                        this.deserialiseElement(e);
-                    }
-                    break;
-
-                default:
-                    throw new Error(`session file : invalid key '${k}' in form object`);
-            }
-        }
-    }
 }
diff --git a/src/app/formulaire/fieldset-template.ts b/src/app/formulaire/fieldset-template.ts
index 3b12fa0d1f3e9cb7d0417618d9b3971970787630..1a47ec12dfe196b3dc4800e112042a9c09a3f286 100644
--- a/src/app/formulaire/fieldset-template.ts
+++ b/src/app/formulaire/fieldset-template.ts
@@ -1,5 +1,5 @@
 import { FieldSet } from "./fieldset";
-import { CalculatorType, ComputeNodeType, StructureType, LoiDebit } from "jalhyd";
+import { CalculatorType, ComputeNodeType, StructureType, LoiDebit, Nub } from "jalhyd";
 import { FormulaireDefinition } from "./definition/form-definition";
 import { FieldsetContainer } from "./fieldset-container";
 
@@ -40,11 +40,12 @@ export class FieldsetTemplate {
     /**
      * crée une instance de Fieldset et l'ajoute dans un conteneur
      * @param cont conteneur
-     * @param at position à laquelle on ajoute le nouveau FieldSet
+     * @param after position à laquelle on ajoute le nouveau FieldSet
+     * @param nub Nub existant à injecter dans le Fieldset
      */
-    public instantiateTemplate(cont: FieldsetContainer, after: number): FieldSet {
+    public instantiateTemplate(cont: FieldsetContainer, after: number, nub?: Nub): FieldSet {
         const parentForm = cont.parent as FormulaireDefinition;
-        const res = parentForm.createFieldset(cont, this._jsonConfig, { "template": this, "after": after });
+        const res = parentForm.createFieldset(cont, this._jsonConfig, { "template": this, "after": after }, nub);
         res.parseConfig(this._jsonConfig);
         parentForm.afterParseFieldset(res);
         return res;
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index 73740f7ecee0809098836692fa016d378084349b..5dd19f2e5d86440901aa34acfc4c06a75c06677f 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -1,4 +1,4 @@
-import { CalculatorType, ComputeNodeType, ParamDefinition, LoiDebit, StructureType, Props, Observer, Nub } from "jalhyd";
+import { CalculatorType, ComputeNodeType, ParamDefinition, LoiDebit, StructureType, Props, Observer, Nub, MethodeResolution } from "jalhyd";
 
 import { FormulaireElement } from "./formulaire-element";
 import { Field } from "./field";
@@ -6,10 +6,10 @@ import { CheckField } from "./check-field";
 import { SelectField } from "./select-field";
 import { NgParameter, ParamRadioConfig } from "./ngparam";
 import { ServiceFactory } from "../services/service-factory";
-import { ParamService } from "../services/param/param.service";
 import { FormulaireDefinition } from "./definition/form-definition";
 import { StringMap } from "../stringmap";
 import { FormulaireNode } from "./formulaire-node";
+import { ApplicationSetupService } from "../services/app-setup/app-setup.service";
 
 export class FieldSet extends FormulaireElement implements Observer {
     /**
@@ -27,14 +27,11 @@ export class FieldSet extends FormulaireElement implements Observer {
      */
     private _jsonConfig: {};
 
-    /**
-     * propriétés déterminant l'état actuel du FieldSet (type de section, loi de débit, ...)
-     */
-    private _props: Props;
+    private _appSetupService: ApplicationSetupService;
 
     constructor(parent: FormulaireNode) {
         super(parent);
-        this._props = new Props();
+        this._appSetupService = ServiceFactory.instance.applicationSetupService;
     }
 
     public get nub(): Nub {
@@ -44,7 +41,7 @@ export class FieldSet extends FormulaireElement implements Observer {
     public setNub(sn: Nub, update: boolean = true) {
         this._nub = sn;
         this.setParentNubForAllFields();
-        this._props.setProps(sn.properties || new Props({}), this);
+        // this._props.setProps(sn.properties || new Props({}), this);
         if (update) {
             this.updateFields();
         }
@@ -104,15 +101,16 @@ export class FieldSet extends FormulaireElement implements Observer {
     }
 
     public get properties(): Props {
-        return this._props;
+        return this.nub.properties;
+        // return this._props;
     }
 
     private getPropValue(key: string): any {
-        return this._props.getPropValue(key);
+        return this.properties.getPropValue(key);
     }
 
     public setPropValue(key: string, val: any): boolean {
-        return this._props.setPropValue(key, val, this);
+        return this.properties.setPropValue(key, val, this);
     }
 
     private getNubParamFromSymbol(symbol: string): ParamDefinition {
@@ -134,29 +132,22 @@ export class FieldSet extends FormulaireElement implements Observer {
      */
     private parse_input(json: {}, default_radio_config: string): NgParameter {
         const input_id: string = json["id"];
-        const paramService: ParamService = ServiceFactory.instance.paramService;
 
         let res: NgParameter;
 
-        switch (input_id) {
-            case "Pr":
-                res = paramService.createParameter(input_id, this);
-                break;
+        const nt: string = json["nodeType"];
+        const nodeType: ComputeNodeType = nt ? ComputeNodeType[nt] : this.getPropValue("nodeType");
 
-            default:
-                const nt: string = json["nodeType"];
-                const nodeType: ComputeNodeType = nt ? ComputeNodeType[nt] : this.getPropValue("nodeType");
-
-                if (nodeType === this.getPropValue("nodeType")) { // si le nodeType du paramètre est le même que celui du fieldset
-                    let nubParam: ParamDefinition;
-                    try {
-                        nubParam = this.getNubParamFromSymbol(input_id);
-                    } catch (e) {
-                    }
-                    if (nubParam) {
-                        res = new NgParameter(nubParam, this);
-                    }
-                }
+        if (nodeType === this.getPropValue("nodeType")) { // si le nodeType du paramètre est le même que celui du fieldset
+            let nubParam: ParamDefinition;
+            try {
+                nubParam = this.getNubParamFromSymbol(input_id);
+            } catch (e) {
+                console.error(`FieldSet::parse_input : cannot find param from symbol ${input_id}`);
+            }
+            if (nubParam) {
+                res = new NgParameter(nubParam, this);
+            }
         }
 
         if (res) {
@@ -211,7 +202,7 @@ export class FieldSet extends FormulaireElement implements Observer {
     }
 
     /**
-     * @param createOrUpdate true pour forcer la création d'un Nub
+     * Reflects all properties values in the interface, through the values of the <select> fields
      */
     private updateFields() {
         this.clearFields();
@@ -221,39 +212,78 @@ export class FieldSet extends FormulaireElement implements Observer {
 
         // MAJ des selects avec les valeurs actuelles des propriétés
         // spécifique à chaque modul de calcul, à revoir
+        switch (this._confId) {
 
-        if (this._confId === "fs_ouvrage") {
-            const sf1: SelectField = this.getFormulaireNodeById("select_ouvrage") as SelectField;
-            const st: StructureType = this.getPropValue("structureType");
-            const se1 = sf1.getSelectedEntryFromValue(st);
-            sf1.setValue(se1);
-
-            switch (st) {
-                case StructureType.SeuilRectangulaire:
-                    const sf2: SelectField = this.getFormulaireNodeById("select_loidebit1") as SelectField;
-                    const se2 = sf2.getSelectedEntryFromValue(this.getPropValue("loiDebit"));
-                    sf2.setValue(se2);
-                    break;
+            case "fs_ouvrage":
+                this.setSelectValueFromProperty("select_ouvrage", "structureType");
 
-                case StructureType.VanneRectangulaire:
-                    const sf3: SelectField = this.getFormulaireNodeById("select_loidebit2") as SelectField;
-                    const se3 = sf3.getSelectedEntryFromValue(this.getPropValue("loiDebit"));
-                    sf3.setValue(se3);
-                    break;
-            }
-        } else if (this._confId === "fs_section") {
-            const sf: SelectField = this.getFormulaireNodeById("select_section") as SelectField;
-            const nt: ComputeNodeType = this.getPropValue("nodeType");
-            const se = sf.getSelectedEntryFromValue(nt);
-            sf.setValue(se);
-        }
+                const st: StructureType = this.getPropValue("structureType");
+                switch (st) {
+                    case StructureType.SeuilRectangulaire:
+                        this.setSelectValueFromProperty("select_loidebit1", "loiDebit");
+                        break;
 
+                    case StructureType.VanneRectangulaire:
+                        this.setSelectValueFromProperty("select_loidebit2", "loiDebit");
+                        break;
+                }
+                break;
 
-        // fin MAJ selects
+            case "fs_section":
+                this.setSelectValueFromProperty("select_section", "nodeType");
+                break;
+
+            case "fs_param_calc":
+                this.setSelectValueFromProperty("select_resolution", "methodeResolution");
+                break;
 
+            case "fs_target_data": // courbe de remous
+            case "fs_computed_var": // section paramétrée
+                this.setSelectValueFromProperty("select_target", "varCalc");
+                break;
+
+        }
+
+        // fin MAJ selects
         this.applyDependencies();
     }
 
+    /**
+     * Reflects a property value in the interface, through the value of a <select> field, if this select exists
+     */
+    private setSelectValueFromProperty(selectId: string, propertyKey: string) {
+        const selectField: SelectField = this.getFormulaireNodeById(selectId) as SelectField;
+        if (selectField) {
+            const propVal: any = this.getPropValue(propertyKey);
+            const selectElement = selectField.getSelectedEntryFromValue(propVal); // @TODO juste setValue() ?
+            try {
+                selectField.setValue(selectElement);
+            } catch (e) {
+                console.error(`setSelectValueFromProperty: cannot set value ${propVal} on <select> ${selectId}`);
+            }
+        }
+    }
+
+    /**
+     * Sets Nub default property from config file, unless this property is already set
+     */
+    private setPropertyValueFromConfig(json: {}, configKey: string, propertyKey: string, enumClass?) {
+        const configValue: string = json[configKey];
+        const currentValue = this.properties.getPropValue(propertyKey);
+        if (configValue && (currentValue === undefined)) {
+            let formalValue =  configValue;
+            if (enumClass) {
+                formalValue = enumClass[configValue];
+            }
+            this.setPropValue(propertyKey, formalValue);
+        }
+    }
+
+    /**
+     * Sets Nub default properties from config file, unless properties values are already set
+     * (when deserialising an existing Nub)
+     * @TODO default values should be held by model, not interface !
+     */
     public parseConfig(json: {}, data?: {}) {
         this._jsonConfig = json;
 
@@ -261,21 +291,19 @@ export class FieldSet extends FormulaireElement implements Observer {
 
         const parentForm = this.parentForm as FormulaireDefinition;
         const ct: string = json["calcType"];
-        const calc_type: CalculatorType = ct ? CalculatorType[ct] : parentForm.calculatorType;
+        const currentCt = this.properties.getPropValue("calcType");
+        const calc_type: CalculatorType = currentCt ? currentCt : (ct ? CalculatorType[ct] : parentForm.calculatorType);
         this.setPropValue("calcType", calc_type);
 
         const dnt: string = json["defaultNodeType"];
-        const node_type: ComputeNodeType = dnt ? ComputeNodeType[dnt] : parentForm.nodeType;
+        const currentNt = this.properties.getPropValue("nodeType");
+        const node_type: ComputeNodeType = currentNt ? currentNt : (dnt ? ComputeNodeType[dnt] : parentForm.nodeType);
         this.setPropValue("nodeType", node_type);
 
-        const st: string = json["defaultStructType"];
-        if (st) {
-            this.setPropValue("structureType", StructureType[st]);
-        }
-        const ld: string = json["defaultLoiDebit"];
-        if (ld) {
-            this.setPropValue("loiDebit", LoiDebit[ld]);
-        }
+        this.setPropertyValueFromConfig(json, "defaultStructType", "structureType", StructureType);
+        this.setPropertyValueFromConfig(json, "defaultLoiDebit", "loiDebit", LoiDebit);
+        this.setPropertyValueFromConfig(json, "methodeResolution", "methodeResolution", MethodeResolution);
+        this.setPropertyValueFromConfig(json, "varCalc", "varCalc");
 
         this.updateFields();
     }
@@ -375,75 +403,7 @@ export class FieldSet extends FormulaireElement implements Observer {
     }
 
     /**
-     * sérialisation en JSON
-     */
-    public JSONserialise(): {} {
-        const res = {};
-        res["id"] = this.id;
-        res["props"] = this._props.props;
-        res["elements"] = this.serialiseKids();
-        return { "fieldset": res };
-    }
-
-    private deserialiseParam(elements: {}): NgParameter {
-        const res: NgParameter = this.getFormulaireNodeById(elements["id"]) as NgParameter;
-        res.deserialiseJSON(elements);
-        return res;
-    }
-
-    private deserialiseSelect(elements: {}): SelectField {
-        const res: SelectField = this.getFormulaireNodeById(elements["id"]) as SelectField;
-        res.deserialiseJSON(elements);
-        return res;
-    }
-
-    private deserialiseElement(element: {}) {
-        const keys = Object.keys(element);
-        if (keys.length !== 1) {
-            throw new Error(`session file : invalid fieldset object '${element}'`);
-        }
-
-        switch (keys[0]) {
-            case "param":
-                this.deserialiseParam(element[keys[0]]);
-                break;
-
-            case "select":
-                this.deserialiseSelect(element[keys[0]]);
-                break;
-
-            default:
-                throw new Error(`session file : invalid key '${keys[0]}' in fieldset object`);
-        }
-    }
-
-    /**
-     * désérialisation depuis JSON
-     */
-    public deserialiseJSON(elements: {}) {
-        for (const k in elements) {
-            switch (k) {
-                case "id":
-                    break;
-
-                case "props":
-                    this._props = new Props(elements[k]);
-                    break;
-
-                case "elements":
-                    for (const e of elements[k]) {
-                        this.deserialiseElement(e);
-                    }
-                    break;
-
-                default:
-                    throw new Error(`session file : invalid key '${k}' in form object`);
-            }
-        }
-    }
-
-    /**
-     * MAJ des liens entre paramètres lors de la désérialisation JSON
+     * MAJ des liens entre paramètres lors de la désérialisation
      * @param json conf du fieldset issue du fichier
      * @param uidMap table de correspondance uid dans le fichier de conf <-> uid en mémoire
      */
@@ -459,7 +419,7 @@ export class FieldSet extends FormulaireElement implements Observer {
                                 const oldFormUid = +prm["values"]["form_uid"];
 
                                 // correspondance avec l'objet mémoire
-                                let newFormUid;
+                                let newFormUid: string;
                                 for (const m of uidMap) {
                                     if (m["type"] === "form" && m["old"] === oldFormUid) {
                                         newFormUid = m["new"];
diff --git a/src/app/formulaire/formulaire-element.ts b/src/app/formulaire/formulaire-element.ts
index c2347b6ee8574b780f72c560a8e617024fd087bf..fd3f87b746074a49131d56bb16e3630a79e212c5 100644
--- a/src/app/formulaire/formulaire-element.ts
+++ b/src/app/formulaire/formulaire-element.ts
@@ -188,7 +188,7 @@ export abstract class FormulaireElement extends FormulaireNode {
         if (loc[key] !== undefined) {
             this._label = this.intlService.localizeText(key, loc);
         } else {
-            // Recherche du code dans locale/error_message.xx.json
+            // Recherche du code dans locale/message.xx.json
             this._label = this.intlService.localizeText("INFO_LIB_" + key.replace(/\d+$/, "").toLocaleUpperCase());
         }
         for (const f of this.getKids()) {
diff --git a/src/app/formulaire/formulaire-node.ts b/src/app/formulaire/formulaire-node.ts
index 128f39a675a5501b93bc4bb4692c411e4c910f1d..918c6d8da06ddab9dacd36d950cd3edee4bc09e7 100644
--- a/src/app/formulaire/formulaire-node.ts
+++ b/src/app/formulaire/formulaire-node.ts
@@ -56,11 +56,6 @@ export abstract class FormulaireNode implements IObservable {
         return this._uid;
     }
 
-    /** utiliser uniquement pour charger des sessions (désérialisation JSON) */
-    public setUid(uid: string) {
-        this._uid = uid;
-    }
-
     /**
      * cherche un FormulaireNode par son id de conf
      */
@@ -149,19 +144,4 @@ export abstract class FormulaireNode implements IObservable {
     notifyObservers(data: any, sender?: any) {
         this._observable.notifyObservers(data, sender);
     }
-
-    protected serialiseKids() {
-        const elems = [];
-        for (const k of this.kids) {
-            elems.push(k.JSONserialise());
-        }
-        return elems;
-    }
-
-    /**
-     * sérialisation en JSON
-     */
-    public JSONserialise(): {} {
-        return {};
-    }
 }
diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts
index 1c82a275adb49d278b97f3ed65f4fe198f67fe51..56006d64d44761227a9c9e80da50ad2f13160439 100644
--- a/src/app/formulaire/ngparam.ts
+++ b/src/app/formulaire/ngparam.ts
@@ -281,17 +281,11 @@ export class NgParameter extends InputField implements Observer {
     }
 
     public parseConfig(json: {}, data?: {}) {
-        const appSetupService: ApplicationSetupService = ServiceFactory.instance.applicationSetupService;
         const radioConfig: string = data["radioConfig"];
 
         this._confId = json["id"];
         this.unit = json["unit"];
-        let val: number;
-        if (this.symbol === "Pr") {
-            val = appSetupService.computePrecision;
-        } else {
-            val = json["value"];
-        }
+        const val: number = json["value"];
         if (val) {
             this.setValue(this, +val);
         }
@@ -319,101 +313,6 @@ export class NgParameter extends InputField implements Observer {
         }
     }
 
-    private paramValuesJSON(): any {
-        const res = {};
-        const vm = this._paramDef.valueMode;
-        res["mode"] = ParamValueMode[vm];
-        switch (vm) {
-            case ParamValueMode.SINGLE:
-                res["value"] = this.getValue();
-                break;
-
-            case ParamValueMode.MINMAX:
-                res["min"] = this.minValue;
-                res["max"] = this.maxValue;
-                res["step"] = this.stepValue;
-                break;
-
-            case ParamValueMode.LISTE:
-                res["values"] = this.valueList;
-                break;
-
-            case ParamValueMode.LINK:
-                res["form_uid"] = ServiceFactory.instance.formulaireService.getFormulaireFromNubId(this._paramDef.referencedNub["uid"]).uid;
-                res["ref"] = this.paramDefinition.referenceDefinition;
-                break;
-        }
-        return res;
-    }
-
-    /**
-     * sérialisation en JSON
-     */
-    public JSONserialise(): {} {
-        const res = {};
-        res["id"] = this.id;
-        res["values"] = this.paramValuesJSON();
-        return { "param": res };
-    }
-
-    private deserialiseValues(json: {}) {
-        const m: ParamValueMode = (<any>ParamValueMode)[json["mode"]];
-        switch (m) {
-            case ParamValueMode.SINGLE:
-                this._paramValues.setValues(+json["value"]);
-                break;
-
-            case ParamValueMode.MINMAX:
-                this._paramValues.setValues(+json["min"], +json["max"], +json["step"]);
-                break;
-
-            case ParamValueMode.LISTE:
-                this._paramValues.setValues(json["values"]);
-                break;
-
-            case ParamValueMode.CALCUL:
-                this._paramValues.valueMode = ParamValueMode.CALCUL;
-                break;
-
-            case ParamValueMode.LINK:
-                const uid: string = json["form_uid"];
-                const ref: string = json["ref"];
-                this._paramValues.valueMode = ParamValueMode.LINK;
-                // formulaire dont le Nub est la cible du lien
-                const destForm = ServiceFactory.instance.formulaireService.getFormulaireFromId(uid);
-                if (destForm) {
-                    this._paramValues.defineReference(destForm.currentNub, ref);
-                } else {
-                    // @TODO et si la cible du lien n'existe pas ??
-                    // cf FormulaireService.updateParamsLinks()
-                    console.log("LA CIBLE DU LIEN N'EXISTE PAS !!");
-                }
-                break;
-
-            default:
-                throw new Error(`session file : invalid value mode '${json["mode"]}' in param object`);
-        }
-    }
-
-    /**
-     * désérialisation depuis JSON
-     */
-    public deserialiseJSON(elements: {}) {
-        for (const k in elements) {
-            switch (k) {
-                case "id":
-                    break;
-
-                case "values":
-                    this.deserialiseValues(elements[k]);
-                    break;
-
-                default:
-                    throw new Error(`session file : invalid key '${k}' in param object`);
-            }
-        }
-    }
-
     // interface Observer
 
     public update(sender: any, data: any) {
diff --git a/src/app/formulaire/select-entry.ts b/src/app/formulaire/select-entry.ts
index fdd7597cda3c53d588cf60eacd3861f8bb370f8a..cb4082fa3596be1db9fee16e080b987defcb7388 100644
--- a/src/app/formulaire/select-entry.ts
+++ b/src/app/formulaire/select-entry.ts
@@ -27,14 +27,4 @@ export class SelectEntry {
     get value(): any {
         return this._value;
     }
-
-    /**
-     * sérialisation en JSON
-     */
-    public JSONserialise() {
-        const res = {};
-        res["id"] = this.id;
-        res["value"] = this._value;
-        return res;
-    }
 }
diff --git a/src/app/formulaire/select-field.ts b/src/app/formulaire/select-field.ts
index a8162bac46fbaf3563160d4ae82548ed13faacac..df078bfbf1a912061129b46786d72cb03e331b7d 100644
--- a/src/app/formulaire/select-field.ts
+++ b/src/app/formulaire/select-field.ts
@@ -43,7 +43,6 @@ export class SelectField extends Field {
 
     public setValue(v: SelectEntry) {
         if (this._selectedEntry !== v) {
-            console.log("++++ select field : notify observers", v);
             this._selectedEntry = v;
             this.notifyObservers({
                 "action": "select",
@@ -121,40 +120,4 @@ export class SelectField extends Field {
             this.addEntry(e);
         }
     }
-
-    /**
-     * sérialisation en JSON
-     */
-    public JSONserialise(): {} {
-        const res = {};
-        res["id"] = this.id;
-        res["selected_id"] = this._selectedEntry.id;
-        return { "select": res };
-    }
-
-    /**
-     * désérialisation depuis JSON
-     */
-    public deserialiseJSON(elements: {}) {
-        for (const k in elements) {
-            switch (k) {
-                case "id":
-                    this._confId = elements[k];
-                    break;
-
-                case "selected_id":
-                    const sel = elements[k];
-                    for (const e of this._entries) {
-                        if (e.id === sel) {
-                            this.setValue(e);
-                            break;
-                        }
-                    }
-                    break;
-
-                default:
-                    throw new Error(`session file : invalid key '${k}' in select object`);
-            }
-        }
-    }
 }
diff --git a/src/app/results/param-calc-results.ts b/src/app/results/param-calc-results.ts
index 5a3d6adecb6b00a17a7870c49198cbe012ff321c..bdcabde2d0ce7879a4e4a88f71af88cb3f27d176 100644
--- a/src/app/results/param-calc-results.ts
+++ b/src/app/results/param-calc-results.ts
@@ -15,17 +15,17 @@ export abstract class CalculatedParamResults extends CalculatorResults {
     /**
      * titre de la colonne
      */
-    private _calculatedParamHeader: string;
+    public calculatedParameterHeader: string;
 
     /**
      * résultat du calcul sur le paramètre calculé
      */
-    protected _result: Result;
+    public result: Result;
 
     protected reset() {
         this._calculatedParam = undefined;
-        this._calculatedParamHeader = undefined;
-        this._result = undefined;
+        this.calculatedParameterHeader = undefined;
+        this.result = undefined;
     }
 
     public get calculatedParameter(): NgParameter {
@@ -34,40 +34,24 @@ export abstract class CalculatedParamResults extends CalculatorResults {
 
     public set calculatedParameter(p: NgParameter) {
         this._calculatedParam = p;
-        this._calculatedParamHeader = CalculatorResults.paramLabel(this._calculatedParam, true);
-    }
-
-    public get calculatedParameterHeader() {
-        return this._calculatedParamHeader;
-    }
-
-    public set calculatedParameterHeader(s: string) {
-        this._calculatedParamHeader = s;
-    }
-
-    public get result(): Result {
-        return this._result;
-    }
-
-    public set result(r: Result) {
-        this._result = r;
+        this.calculatedParameterHeader = CalculatorResults.paramLabel(this._calculatedParam, true);
     }
 
     public get hasResults(): boolean {
-        if (this._result === undefined) {
+        if (this.result === undefined) {
             return false;
         }
-        return this._result.ok;
+        return this.result.ok;
     }
 
     public get hasLog(): boolean {
-        if (this._result === undefined) {
+        if (this.result === undefined) {
             return false;
         }
-        return this._result.hasLog;
+        return this.result.hasLog;
     }
 
     public get log(): cLog {
-        return this._result && this._result.log;  // return x === undefined ? undefined : x.y
+        return this.result && this.result.log;  // return x === undefined ? undefined : x.y
     }
 }
diff --git a/src/app/results/var-results.ts b/src/app/results/var-results.ts
index 657dd44f690b3ea84912c475aa618697e1421765..177f36a60c21f185616cd8b0bf4b6a7ebdc574d2 100644
--- a/src/app/results/var-results.ts
+++ b/src/app/results/var-results.ts
@@ -93,7 +93,7 @@ export class VarResults extends CalculatedParamResults {
     }
 
     public get resultElements(): ResultElement[] {
-        return this._result.resultElements;
+        return this.result.resultElements;
     }
 
     public get graphTitle() {
@@ -122,14 +122,14 @@ export class VarResults extends CalculatedParamResults {
         }
 
         // valeurs du paramètre à calculer
-        for (const r of this._result.resultElements) {
+        for (const r of this.result.resultElements) {
             this._yValues.push(r.vCalc);
         }
 
         // clés des résultats supplémentaires
 
         if (this._extraResultKeys.length === 0) {
-            for (const re of this._result.resultElements) { // re:ResultElement
+            for (const re of this.result.resultElements) { // re:ResultElement
                 for (const erk in re.extraResults) {
                     if (!this._extraResultKeys.includes(erk)) {
                         this._extraResultKeys.push(erk);
diff --git a/src/app/services/formulaire/formulaire.service.ts b/src/app/services/formulaire/formulaire.service.ts
index 8be740fa20060504a1e71e02822e473b9664318d..85e6bb0ac6cb3f0cb4d8cc76ba42fa7674db19f0 100644
--- a/src/app/services/formulaire/formulaire.service.ts
+++ b/src/app/services/formulaire/formulaire.service.ts
@@ -3,7 +3,7 @@ import { Injectable } from "@angular/core";
 import { decode } from "he";
 import { saveAs } from "file-saver";
 
-import { CalculatorType, EnumEx, Observable, ParamDefinition } from "jalhyd";
+import { CalculatorType, EnumEx, Observable, ParamDefinition, Session, Nub, ParallelStructure } from "jalhyd";
 
 import { HttpService } from "../../services/http/http.service";
 import { I18nService } from "../../services/internationalisation/internationalisation.service";
@@ -20,6 +20,7 @@ import { FormulaireCourbeRemous } from "../../formulaire/definition/concrete/for
 import { FormulaireRegimeUniforme } from "../../formulaire/definition/concrete/form-regime-uniforme";
 import { FormulaireParallelStructure } from "../../formulaire/definition/concrete/form-parallel-structures";
 import { NgParameter } from "../../formulaire/ngparam";
+import { FieldsetContainer } from "../..//formulaire/fieldset-container";
 
 @Injectable()
 export class FormulaireService extends Observable {
@@ -81,20 +82,6 @@ export class FormulaireService extends Observable {
             });
     }
 
-    /**
-     * retourne true si l'uid passé en paramètre est déjà utilisé par un formulaire
-     * @param uid uid à tester
-     */
-    private formUIDAlreadyUsed(uid: string): boolean {
-        let alreadyUsed = false;
-        for (const f of this._formulaires) {
-            if (f.uid === uid) {
-                alreadyUsed = true;
-            }
-        }
-        return alreadyUsed;
-    }
-
     public updateLocalisation() {
         for (const c of EnumEx.getValues(CalculatorType)) {
             const prom: Promise<StringMap> = this.loadLocalisation(c);
@@ -109,11 +96,58 @@ export class FormulaireService extends Observable {
         }
     }
 
+    /**
+     * Retourne le titre complet du type de module de calcul, dans la langue en cours
+     */
     public getLocalisedTitleFromCalculatorType(type: CalculatorType) {
         const sCalculator: string = CalculatorType[type].toUpperCase();
         return this._intlService.localizeText(`INFO_${sCalculator}_TITRE`);
     }
 
+    /**
+     * Retourne le titre cour du type de module de calcul, dans la langue en cours
+     * (pour les titres d'onglets par défaut)
+     */
+    public getLocalisedShortTitleFromCalculatorType(type: CalculatorType) {
+        const sCalculator: string = CalculatorType[type].toUpperCase();
+        return this._intlService.localizeText(`INFO_${sCalculator}_TITRE_COURT`);
+    }
+
+    /**
+     * Checks if the given calculator name (tab title) is already used by any existing
+     * form; if so, adds a number after it
+     */
+    private suffixNameIfNeeded(name: string) {
+        let found = false;
+        let maxNumber = 0;
+
+        // extract base name
+        let baseName = name;
+        const re1 = new RegExp("^.+( \\d+)$");
+        const matches1 = re1.exec(name);
+        if (matches1) {
+            baseName = baseName.replace(matches1[1], "");
+        }
+
+        // browse session calculators
+        const re2 = new RegExp("^" + baseName + "( (\\d+))?$");
+        for (const f of this.formulaires) {
+            const matches2 = re2.exec(f.calculatorName);
+            if (matches2) {
+                found = true;
+                if (matches2[2] !== undefined) {
+                    const nb = Number(matches2[2]);
+                    maxNumber = Math.max(maxNumber, nb);
+                }
+            }
+        }
+        // suffix if needed
+        if (found) {
+            name = baseName + " " + (maxNumber + 1);
+        }
+        return name;
+    }
+
     public loadConfig(ct: CalculatorType): Promise<any> {
         const f: string = this.getConfigPathPrefix(ct) + "config.json";
         return this._httpService.httpGetRequestPromise(f);
@@ -163,32 +197,47 @@ export class FormulaireService extends Observable {
     /**
      * crée un formulaire d'un type donné
      * @param ct type de formulaire
-     * @param jsonState descripteur sérialisé du formulaire, le cal échéant
+     * @param nub nub existant à associer au formulaire (chargement de session / duplication de module)
+     * @param calculatorName nom du module, à afficher dans l'interface
      */
-    public createFormulaire(ct: CalculatorType, jsonState?: {}): Promise<FormulaireDefinition> {
+    public createFormulaire(ct: CalculatorType, nub?: Nub, calculatorName?: string): Promise<FormulaireDefinition> {
+        // Crée un formulaire du bon type
         const f: FormulaireDefinition = this.newFormulaire(ct);
-        // conserver l'UID d'origine, sauf en cas de collision
-        if (jsonState !== undefined) {
-            const originalUID = jsonState["uid"];
-            if (originalUID !== undefined && ! this.formUIDAlreadyUsed(originalUID)) {
-                f.setUid(originalUID);
-            }
-        }
         this._formulaires.push(f);
-
+        // Charge la configuration dépendamment du type
         const prom: Promise<any> = this.loadConfig(ct);
         return prom.then(s => {
             f.preparseConfig(s);
-            if (jsonState === undefined) {
-                f.calculatorName = decode(this.getLocalisedTitleFromCalculatorType(ct));
+
+            // Associe le Nub fourni (chargement de session / duplication de module), sinon en crée un nouveau
+            if (nub) {
+                f.currentNub = nub;
+            } else {
+                f.initNub();
+            }
+
+            // Restaure le nom du module, sinon affecte le nom par défaut
+            let tempName: string;
+            if (calculatorName) {
+                tempName = calculatorName;
+            } else {
+                tempName = decode(this.getLocalisedShortTitleFromCalculatorType(ct));
             }
-            f.initNub();
+            // Suffixe le nom du module si nécessaire
+            f.calculatorName = this.suffixNameIfNeeded(tempName);
+
             f.parseConfig();
-            if (jsonState !== undefined) {
-                f.deserialiseJSON(jsonState);
+
+            // add fieldsets for existing structures if needed
+            if (f.currentNub instanceof ParallelStructure) {
+                for (s of f.currentNub.structures) {
+                    for (const e of f.allFormElements) {
+                        if (e instanceof FieldsetContainer) { // @TODO manage many containers one day ?
+                            e.addFromTemplate(0, undefined, s);
+                        }
+                    }
+                }
             }
-            // la méthode loadUpdateFormulaireLocalisation retourne une Promise; le fait de retourner une Promise dans un then
-            // fait que le then suivant est exécuté juste après.
             return this.loadUpdateFormulaireLocalisation(f);
         }).then(fi => {
             fi.applyDependencies();
@@ -314,9 +363,14 @@ export class FormulaireService extends Observable {
         }
     }
 
+    /**
+     * Supprime le formulaire ciblé, et demande à JaLHyd d'effacer son Nub de la Session
+     * @param uid formulaire à supprimer
+     */
     public requestCloseForm(uid: string) {
         const form = this.getFormulaireFromId(uid);
-        if (form !== undefined) {
+        const nub = form.currentNub;
+        if (form) {
             this._formulaires = this._formulaires.filter(f => f.uid !== uid);
 
             this.notifyObservers({
@@ -324,6 +378,9 @@ export class FormulaireService extends Observable {
                 "form": form
             });
         }
+        if (nub) {
+            Session.getInstance().deleteNub(nub);
+        }
     }
 
     public get currentFormId() {
@@ -384,24 +441,27 @@ export class FormulaireService extends Observable {
      */
     public loadSession(f: File, formInfos: any[]) {
         this.readSingleFile(f).then(s => {
-            const session = JSON.parse(s);
-            for (const k in session) {
-                switch (k) {
-                    case "session":
-                        this.deserialiseSession(session[k], formInfos);
-                        break;
-
-                    default:
-                        throw new Error(`session file : invalid key '${k}'`);
+            const uids: string[] = [];
+            formInfos.forEach((fi) => {
+                if (fi.selected) {
+                    uids.push(fi.uid);
                 }
-            }
+            });
+            const newNubs = Session.getInstance().unserialise(s, uids);
+            // for each new Nub, create the related form, set its title
+            newNubs.forEach((nn) => {
+                this.createFormulaire(nn.nub.calcType, nn.nub, nn.meta.title);
+            });
         }).catch(err => {
             throw err;
         });
     }
 
-    public saveSession(session: {}, filename?: string) {
-        const blob = new Blob([JSON.stringify(session)], { type: "text/plain;charset=utf-8" });
+    /**
+     * Sends an UTF-8 text file for download
+     */
+    public downloadTextFile(session: string, filename: string = "file_1") {
+        const blob = new Blob([session], { type: "text/plain;charset=utf-8" });
         saveAs(blob, filename);
     }
 
@@ -412,27 +472,15 @@ export class FormulaireService extends Observable {
     public calculatorInfosFromSessionFile(f: File): Promise<any[]> {
         return this.readSingleFile(f).then(s => {
             const res: any[] = [];
-            const session = JSON.parse(s);
-
+            const data = JSON.parse(s);
             // liste des noms de modules de calcul
-            for (const k in session) {
-                switch (k) {
-                    case "session":
-                        const sess = session[k];
-                        const elems = sess["elements"];
-                        for (const e of elems) {
-                            for (const l in e) {
-                                if (l === "form") {
-                                    const form = e[l];
-                                    res.push({ "uid": form["uid"], "title": form["id"] });
-                                }
-                            }
-                        }
-                        break;
-
-                    default:
-                        throw new Error(`session file : invalid key '${k}'`);
-                }
+            if (data.session && Array.isArray(data.session)) {
+                data.session.forEach((e: any) => {
+                   res.push({
+                       uid: e.uid,
+                       title: e.meta && e.meta.title ? e.meta.title : undefined
+                    });
+                });
             }
             return res;
         });
@@ -445,35 +493,6 @@ export class FormulaireService extends Observable {
         });
     }
 
-    public deserialiseForm(elements: {}): Promise<FormulaireDefinition> {
-        const props = elements["props"];
-        const ct: CalculatorType = props["calcType"];
-        return this.createFormulaire(ct, elements);
-    }
-
-    private deserialiseSessionElement(element: {}, formInfos: any[]): Promise<FormulaireDefinition> {
-        const keys = Object.keys(element);
-        if (keys.length !== 1) {
-            throw new Error(`session file : invalid session object '${element}'`);
-        }
-
-        switch (keys[0]) {
-            case "form":
-                const form = element[keys[0]];
-
-                for (const i of formInfos) {
-                    // on the loadSession dialog, was the checkbox checked for this calculator ?
-                    if (i["uid"] === form["uid"] && i["selected"]) {
-                        return this.deserialiseForm(form);
-                    }
-                }
-                break;
-
-            default:
-                throw new Error(`session file : invalid key '${keys[0]}' in session object`);
-        }
-    }
-
     /**
      * met à jour les liens d'un formulaire
      * @param json conf du formulaire
@@ -490,16 +509,14 @@ export class FormulaireService extends Observable {
     }
 
     /**
-     * MAJ des liens entre paramètres lors de la désérialisation JSON
+     * MAJ des liens entre paramètres lors de la désérialisation
      */
-
-    private updateParamsLinks(json: {}, formInfos: any[], oldFormCount: number) {
+    /* private updateParamsLinks(json: {}, formInfos: any[], oldFormCount: number) {
         // table de correspondance des uid fichier <-> objets mémoire
         // forme : tableau d'objets de la forme :
         // { "type" : <type de l'objet. "form" pour formulaire>,
         //   "old": <uid dans le fichier>,
         //   "new": <uid de l'objet mémoire>}
-
         const uidMap = [];
         for (const ks in json) {
             switch (ks) {
@@ -517,9 +534,7 @@ export class FormulaireService extends Observable {
                     }
             }
         }
-
         // MAJ liens
-
         for (const ks in json) {
             switch (ks) {
                 case "elements":
@@ -536,32 +551,7 @@ export class FormulaireService extends Observable {
                     throw new Error(`session file : invalid key '${ks}' in session object`);
             }
         }
-    }
-
-    private deserialiseSession(elements: {}, formInfos: any[]) {
-        let p: Promise<FormulaireDefinition>;
-
-        const oldFormCount = this._formulaires.length;
-        for (const ks in elements) {
-            switch (ks) {
-                case "elements":
-                    for (const e of elements[ks]) {
-                        if (p === undefined) {
-                            p = this.deserialiseSessionElement(e, formInfos);
-                        } else {
-                            p = p.then(_ => {
-                                return this.deserialiseSessionElement(e, formInfos);
-                            });
-                        }
-                    }
-                    break;
-
-                default:
-                    throw new Error(`session file : invalid key '${ks}' in session object`);
-            }
-        }
-        p.then(_ => this.updateParamsLinks(elements, formInfos, oldFormCount));
-    }
+    } */
 
     /**
      * @returns liste des valeurs liables à un paramètre sous la forme d'un tableau d'objets
@@ -570,16 +560,13 @@ export class FormulaireService extends Observable {
      */
     public getLinkableValues(p: NgParameter): any[] {
         const res: any[] = [];
-
         if (p !== undefined) {
             for (const f of this._formulaires) {
                 // nub associé au formulaire
                 const sn = f.currentNub;
-
                 try {
                     // on vérifie que le paramètre en entrée appartient au nub
                     const np = sn.getParameter(p.symbol);
-
                     // si oui, on demande à exclure des valeurs retournées le résultat du même nom que le paramètre
                     const exclude = np !== undefined ? p.paramDefinition.uid === np.uid : false;
                     // valeurs liables
@@ -593,7 +580,6 @@ export class FormulaireService extends Observable {
                 }
             }
         }
-
         return res;
     }
 
diff --git a/src/app/services/param/param.service.ts b/src/app/services/param/param.service.ts
deleted file mode 100644
index d8d36ce021e17b7983832358c5f14dcdcea10a99..0000000000000000000000000000000000000000
--- a/src/app/services/param/param.service.ts
+++ /dev/null
@@ -1,111 +0,0 @@
-import { ParamDomain, ParamDefinition, ParamDomainValue, ParamCalculability, Session, Props, Nub } from "jalhyd";
-
-import { NgParameter } from "../../formulaire/ngparam";
-import { Injectable } from "@angular/core";
-import { I18nService } from "../internationalisation/internationalisation.service";
-import { ApplicationSetupService } from "../app-setup/app-setup.service";
-import { FormulaireNode } from "../../formulaire/formulaire-node";
-
-@Injectable()
-export class ParamService {
-
-    constructor(
-        private i18nService: I18nService,
-        private applicationSetupService: ApplicationSetupService
-        ) { }
-
-    private get _intlService(): I18nService {
-        return this.i18nService;
-    }
-
-    private get _appSetupService(): ApplicationSetupService {
-        return this.applicationSetupService;
-    }
-
-    private createAccuracyParameter(): ParamDefinition {
-        const d = new ParamDomain(ParamDomainValue.INTERVAL, 1e-10, 100);
-        const p = new ParamDefinition(null, "Pr", d, this._appSetupService.computePrecision);
-        p.calculability = ParamCalculability.FREE;
-        return p;
-    }
-
-    /**
-     *
-     * @param calcType crée un NgParameter n'appartenant pas à un ComputeNode
-     * @param symbol symbole du paramètre à créer
-     */
-    public createParameter(symbol: string, parent: FormulaireNode): NgParameter {
-        let p: NgParameter;
-        if (symbol === "Pr") {
-            const prmDef: ParamDefinition = this.createAccuracyParameter();
-            p = new NgParameter(prmDef.clone(), parent);
-            p.confId = "Pr";
-        } else {
-            const dom = new ParamDomain(ParamDomainValue.POS_NULL);
-            p = new NgParameter(new ParamDefinition(null, symbol, dom), parent);
-            p.confId = symbol;
-
-            switch (symbol) {
-                case "Hs":
-                case "Hsc":
-                case "B":
-                case "P":
-                case "R":
-                case "Yc":
-                case "Yn":
-                case "Yf":
-                case "Yt":
-                case "Yco":
-                case "J":
-                    p.unit = "m";
-                    break;
-
-                case "S":
-                    p.unit = "m2";
-                    break;
-
-                case "V":
-                    p.unit = "m/s";
-                    break;
-
-                case "I-J":
-                    p.unit = "m/m";
-                    break;
-
-                case "Fr":
-                    p.unit = "";
-                    break;
-
-                case "Imp":
-                    p.unit = "N";
-                    break;
-
-                case "Tau0":
-                    p.unit = "Pa";
-                    break;
-
-                case "Pr":
-                    break;
-
-                default:
-                    throw new Error(`ParamService.createParameter() : symbole ${symbol} non pris en charge`);
-            }
-            p.updateLocalisation(this._intlService.currentMap);
-        }
-
-        return p;
-    }
-
-    public createNub(params: Props | {}): Nub {
-        const truc = Session.getInstance().createSessionNub(params);
-        return truc;
-    }
-
-    public replaceNub(sn: Nub, params: Props): Nub {
-        return Session.getInstance().replaceNub(sn, params);
-    }
-
-    public deleteNub(sn: Nub) {
-        Session.getInstance().deleteNub(sn);
-    }
-}
diff --git a/src/app/services/service-factory.ts b/src/app/services/service-factory.ts
index 0e84febabaaa2f1120406de9e2370b4be7b5d9da..0627bdf99a223a0bf9b7712945dcdb7849075c1a 100644
--- a/src/app/services/service-factory.ts
+++ b/src/app/services/service-factory.ts
@@ -1,5 +1,4 @@
 import { ApplicationSetupService } from "./app-setup/app-setup.service";
-import { ParamService } from "./param/param.service";
 import { FormulaireService } from "./formulaire/formulaire.service";
 import { I18nService } from "./internationalisation/internationalisation.service";
 import { HttpService } from "./http/http.service";
@@ -11,8 +10,6 @@ export class ServiceFactory {
 
     public applicationSetupService: ApplicationSetupService;
 
-    public paramService: ParamService;
-
     public formulaireService: FormulaireService;
 
     public i18nService: I18nService;
diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json
index 4e0057b97cfc9a65f15972f8dee961f13c8a1693..4c96c5aa529c5c762ae469348b291a11780edf5b 100644
--- a/src/locale/messages.en.json
+++ b/src/locale/messages.en.json
@@ -41,11 +41,15 @@
     "INFO_CALCULATOR_RESULTS_TITLE": "Results",
     "INFO_CALCULATOR_VALEURS": "Values",
     "INFO_CLOISONS_TITRE": "Fish ladder: Cross walls",
+    "INFO_CLOISONS_TITRE_COURT": "Cross walls",
     "INFO_CLOSE_DIALOGUE_TEXT": "Warning ! Parameters and results will be lost. Really close?",
     "INFO_CLOSE_DIALOGUE_TITRE": "Please confirm",
     "INFO_CONDUITEDISTRIBUTRICE_TITRE": "Distributor pipe",
+    "INFO_CONDUITEDISTRIBUTRICE_TITRE_COURT": "D. pipe",
     "INFO_COURBEREMOUS_TITRE": "Backwater curves",
+    "INFO_COURBEREMOUS_TITRE_COURT": "B. curves",
     "INFO_DEVER_TITRE": "Free flow weir stage-discharge laws",
+    "INFO_DEVER_TITRE_COURT": "Free flow SD",
     "INFO_EXTRARES_ENUM_MACRORUGOFLOWTYPE_0": "Emergent",
     "INFO_EXTRARES_ENUM_MACRORUGOFLOWTYPE_1": "Quasi-emergent",
     "INFO_EXTRARES_ENUM_MACRORUGOFLOWTYPE_2": "Submerged",
@@ -104,10 +108,11 @@
     "INFO_EXTRARES_LIB_YT": "Supercritical depth (m)",
     "INFO_EXTRARES_LIB_ZF2": "Downstream bottom elevation (m)",
     "INFO_LECHAPTCALMON_TITRE": "Lechapt-Calmon",
+    "INFO_LECHAPTCALMON_TITRE_COURT": "Lechapt-Calmon",
     "INFO_LIB_ALPHA": "Alpha coefficient",
     "INFO_LIB_BETA": "Beta coefficient",
     "INFO_LIB_CD": "Discharge coefficient",
-    "INFO_LIB_BT": "Half opening of the triangle (m)",
+    "INFO_LIB_BT": "Half opening of the triangle",
     "INFO_LIB_FS_PARAM_CALC": "Calculation parameters",
     "INFO_LIB_FS_OUVRAGE": "Device",
     "INFO_LIB_L": "Weir width",
@@ -118,9 +123,10 @@
     "INFO_LIB_SELECT_OUVRAGE": "Device",
     "INFO_LIB_SELECT_OUVRAGE_SEUIL_RECT": "Rectangular weir",
     "INFO_LIB_ZDV": "Crest weir elevation or gate base",
-    "INFO_LIB_ZRAM": "Upstream apron elevation (m)",
-    "INFO_LIB_ZT": "Triangle top elevation (m)",
+    "INFO_LIB_ZRAM": "Upstream apron elevation",
+    "INFO_LIB_ZT": "Triangle top elevation",
     "INFO_MACRORUGO_TITRE": "Rock-ramp fishpasses",
+    "INFO_MACRORUGO_TITRE_COURT": "RR fishpasses",
     "INFO_MENU_HELP_TITLE": "Help",
     "INFO_MENU_LOAD_SESSION_TITLE": "Load session",
     "INFO_MENU_NOUVELLE_CALC": "New calculation module",
@@ -140,8 +146,11 @@
     "INFO_OPTION_NONE_F": "None",
     "INFO_OUVRAGE": "Structure",
     "INFO_PABDIMENSIONS_TITRE": "Fish ladder: dimensions",
+    "INFO_PABDIMENSIONS_TITRE_COURT": "FL: dimensions",
     "INFO_PABPUISSANCE_TITRE": "Fish ladder: dissipated power",
+    "INFO_PABPUISSANCE_TITRE_COURT": "FL: diss. power",
     "INFO_PARALLELSTRUCTURE_TITRE": "Parallel structures",
+    "INFO_PARALLELSTRUCTURE_TITRE_COURT": "// structures",
     "INFO_PARAMFIELD_GRAPH_TYPE": "Graph type",
     "INFO_PARAMFIELD_GRAPH_TYPE_HISTOGRAM": "Histogram",
     "INFO_PARAMFIELD_IN_CALCULATION": "In calculation",
@@ -167,6 +176,7 @@
     "INFO_PARAMMODE_MINMAX": "Min/max",
     "INFO_PARAMMODE_LIST": "Values list",
     "INFO_REGIMEUNIFORME_TITRE": "Uniform flow calculation",
+    "INFO_REGIMEUNIFORME_TITRE_COURT": "Uniform flow",
     "INFO_REMOUSRESULTS_ABSCISSE": "Abscissa (m)",
     "INFO_REMOUSRESULTS_BERGE": "Embankment",
     "INFO_REMOUSRESULTS_FOND": "Bottom",
@@ -182,6 +192,7 @@
     "INFO_REMOUS_RESSAUT_DEHORS": "Hydraulic jump detected %sens% abscissa %x% m",
     "INFO_REMOUS_RESSAUT_HYDRO": "Hydraulic jump detected between abscissa %xmin% and %xmax% m",
     "INFO_SECTIONPARAMETREE_TITRE": "Parametric section",
+    "INFO_SECTIONPARAMETREE_TITRE_COURT": "Param. section",
     "INFO_SETUP_NEWTON_MAX_ITER": "Newton iteration limit",
     "INFO_SETUP_PRECISION_AFFICHAGE": "Display accuracy",
     "INFO_SETUP_PRECISION_CALCUL": "Computation accuracy",
diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json
index 0b88860267614c05862ab3569966e0fb4a9ac758..69ceb18ec82ee75e9a9173fb7c36863143559722 100644
--- a/src/locale/messages.fr.json
+++ b/src/locale/messages.fr.json
@@ -41,11 +41,15 @@
     "INFO_CALCULATOR_RESULTS_TITLE": "Résultats",
     "INFO_CALCULATOR_VALEURS": "Valeurs",
     "INFO_CLOISONS_TITRE": "Passe à bassin&nbsp;: Cloisons",
+    "INFO_CLOISONS_TITRE_COURT": "Cloisons",
     "INFO_CLOSE_DIALOGUE_TEXT": "Attention&nbsp;! Les paramètres et résultats du module de calcul seront perdus. Vraiment fermer&nbsp;?",
     "INFO_CLOSE_DIALOGUE_TITRE": "Confirmer la fermeture",
     "INFO_CONDUITEDISTRIBUTRICE_TITRE": "Conduite distributrice",
+    "INFO_CONDUITEDISTRIBUTRICE_TITRE_COURT": "Conduite distri.",
     "INFO_COURBEREMOUS_TITRE": "Courbes de remous",
+    "INFO_COURBEREMOUS_TITRE_COURT": "Remous",
     "INFO_DEVER_TITRE": "Lois de déversoirs dénoyés",
+    "INFO_DEVER_TITRE_COURT": "Déver. dénoyés",
     "INFO_EXTRARES_ENUM_MACRORUGOFLOWTYPE_0": "Emergent",
     "INFO_EXTRARES_ENUM_MACRORUGOFLOWTYPE_1": "Quasi-émergent",
     "INFO_EXTRARES_ENUM_MACRORUGOFLOWTYPE_2": "Immergé",
@@ -104,10 +108,11 @@
     "INFO_EXTRARES_LIB_YT": "Tirant d'eau torrentiel (m)",
     "INFO_EXTRARES_LIB_ZF2": "Cote de fond aval (m)",
     "INFO_LECHAPTCALMON_TITRE": "Lechapt-Calmon",
+    "INFO_LECHAPTCALMON_TITRE_COURT": "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_BT": "Demi-ouverture du triangle",
     "INFO_LIB_FS_PARAM_CALC": "Paramètres de calcul",
     "INFO_LIB_FS_OUVRAGE": "Ouvrage",
     "INFO_LIB_L": "Largeur du déversoir",
@@ -118,8 +123,8 @@
     "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_ZRAM": "Cote du radier amont (m)",
-    "INFO_LIB_ZT": "Cote haute du triangle (m)",
+    "INFO_LIB_ZRAM": "Cote du radier amont",
+    "INFO_LIB_ZT": "Cote haute du triangle",
     "INFO_MENU_HELP_TITLE": "Aide",
     "INFO_MENU_LOAD_SESSION_TITLE": "Charger une session",
     "INFO_MENU_SAVE_SESSION_TITLE": "Enregistrer la session",
@@ -127,6 +132,7 @@
     "INFO_MENU_EMPTY_SESSION_TITLE": "Nouvelle session",
     "INFO_MENU_NOUVELLE_CALC": "Nouveau module de calcul",
     "INFO_MACRORUGO_TITRE": "Passe à macro-rugosités",
+    "INFO_MACRORUGO_TITRE_COURT": "Macro-rugo.",
     "INFO_OPTION_NO": "Non",
     "INFO_OPTION_YES": "Oui",
     "INFO_OPTION_CANCEL": "Annuler",
@@ -140,8 +146,11 @@
     "INFO_OPTION_NONE_F": "Aucune",
     "INFO_OUVRAGE": "Ouvrage",
     "INFO_PABDIMENSIONS_TITRE": "Passe à bassin&nbsp;: dimensions",
+    "INFO_PABDIMENSIONS_TITRE_COURT": "PAB&nbsp;: dimensions",
     "INFO_PABPUISSANCE_TITRE": "Passe à bassin&nbsp;: puissance dissipée",
+    "INFO_PABPUISSANCE_TITRE_COURT": "PAB&nbsp;: puissance",
     "INFO_PARALLELSTRUCTURE_TITRE": "Lois d'ouvrages",
+    "INFO_PARALLELSTRUCTURE_TITRE_COURT": "Ouvrages",
     "INFO_PARAMFIELD_GRAPH_TYPE": "Type de graphe",
     "INFO_PARAMFIELD_GRAPH_TYPE_HISTOGRAM": "Histogramme",
     "INFO_PARAMFIELD_IN_CALCULATION": "En calcul",
@@ -167,6 +176,7 @@
     "INFO_PARAMMODE_MINMAX": "Min/max",
     "INFO_PARAMMODE_LIST": "Liste de valeurs",
     "INFO_REGIMEUNIFORME_TITRE": "Régime uniforme",
+    "INFO_REGIMEUNIFORME_TITRE_COURT": "R. uniforme",
     "INFO_REMOUSRESULTS_ABSCISSE": "Abscisse (m)",
     "INFO_REMOUSRESULTS_BERGE": "Berge",
     "INFO_REMOUSRESULTS_FOND": "Fond",
@@ -182,6 +192,7 @@
     "INFO_REMOUS_RESSAUT_DEHORS": "Ressaut hydraulique détecté à l'%sens% de l'abscisse %x% m",
     "INFO_REMOUS_RESSAUT_HYDRO": "Ressaut hydraulique détecté entre les abscisses %xmin% et %xmax% m",
     "INFO_SECTIONPARAMETREE_TITRE": "Section paramétrée",
+    "INFO_SECTIONPARAMETREE_TITRE_COURT": "Sec. param.",
     "INFO_SETUP_NEWTON_MAX_ITER": "Newton : nombre d'itérations maximum",
     "INFO_SETUP_PRECISION_AFFICHAGE": "Précision d'affichage",
     "INFO_SETUP_PRECISION_CALCUL": "Précision de calcul",