diff --git a/README.md b/README.md
index 4692536a011f4b9785e1844193e222fa557f22cf..c0d1f11d4e488ec5a3ec94b96832c5c49948d634 100644
--- a/README.md
+++ b/README.md
@@ -70,9 +70,9 @@ and then :
 
 				constructor(rL: number, rW: number, rA:number=undefined) {
 					super();
-					this._L = new ParamDefinition(ComputeNodeType.LechaptCalmon, 'L', ParamDomainValue.POS, rL);
-					this._W = new ParamDefinition(ComputeNodeType.LechaptCalmon, 'W', ParamDomainValue.POS, rW);
-					this._A = new ParamDefinition(ComputeNodeType.LechaptCalmon, 'A', ParamDomainValue.POS, rA);
+					this._L = new ParamDefinition(this, ComputeNodeType.LechaptCalmon, 'L', ParamDomainValue.POS, rL);
+					this._W = new ParamDefinition(this, ComputeNodeType.LechaptCalmon, 'W', ParamDomainValue.POS, rW);
+					this._A = new ParamDefinition(this, ComputeNodeType.LechaptCalmon, 'A', ParamDomainValue.POS, rA);
 
 					this.addParamDefinition(this._L);
 					this.addParamDefinition(this._W);
diff --git a/angular.json b/angular.json
index 22d6bc06401c00abbb252322c55bcad87ace7c88..4f42d530dfc095135978945761b7bf9326194387 100644
--- a/angular.json
+++ b/angular.json
@@ -115,7 +115,8 @@
           "builder": "@angular-devkit/build-angular:protractor",
           "options": {
             "protractorConfig": "./protractor.conf.js",
-            "devServerTarget": "ngHyd:serve"
+            "devServerTarget": "ngHyd:serve",
+            "port": 4201
           }
         },
         "lint": {
diff --git a/e2e/app.e2e-spec.ts b/e2e/app.e2e-spec.ts
index a239abb972755744a063fea0a0de4124fcd784bc..721ce55a1ebc3c6e5fc1a6c3250a099af9ce8f36 100644
--- a/e2e/app.e2e-spec.ts
+++ b/e2e/app.e2e-spec.ts
@@ -1,14 +1,21 @@
-import { AppPage } from './app.po';
+import { AppPage } from "./app.po";
+import { browser } from "protractor";
 
-describe('ngHyd App', () => {
+describe("ngHyd − start page", () => {
   let page: AppPage;
 
   beforeEach(() => {
     page = new AppPage();
   });
 
-  it('should display welcome message', () => {
-    page.navigateTo();
-    expect(page.getParagraphText()).toEqual('Welcome to app!');
+  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 ?
+    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/app.po.ts b/e2e/app.po.ts
index 82ea75ba504ab2726e4bd08d89e69e99b7a711ba..8a58a9466d2ad766bee7fbf651100e2db215fd44 100644
--- a/e2e/app.po.ts
+++ b/e2e/app.po.ts
@@ -1,11 +1,7 @@
-import { browser, by, element } from 'protractor';
+import { browser } from "protractor";
 
 export class AppPage {
   navigateTo() {
-    return browser.get('/');
-  }
-
-  getParagraphText() {
-    return element(by.css('app-root h1')).getText();
+    return browser.get("/");
   }
 }
diff --git a/e2e/calculator.e2e-spec.ts b/e2e/calculator.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..58beabb11e1a15b082f9554744d028d9d8ce9a77
--- /dev/null
+++ b/e2e/calculator.e2e-spec.ts
@@ -0,0 +1,27 @@
+import { CalculatorPage } from "./calculator.po";
+import { ListPage } from "./list.po";
+
+describe("ngHyd − calculator page", () => {
+  let page: CalculatorPage;
+  let listPage: ListPage;
+
+  beforeEach(() => {
+    page = new CalculatorPage();
+    listPage = new ListPage();
+  });
+
+  it("when a calculator name is clicked on list page, a calculator should be opened", async () => {
+    await listPage.navigateTo();
+    await listPage.clickRandomCalculatorMenuEntry();
+    const text = await page.getHeader1().getText();
+    expect(text.length).toBeGreaterThan(0);
+  });
+
+  it("when a calculator is open, no label should be empty", async () => {
+    const labels = page.getInputLabels();
+    await labels.each(async (l) => {
+      const label = await l.getText();
+      expect(label.length).toBeGreaterThan(0);
+    });
+  });
+});
diff --git a/e2e/calculator.po.ts b/e2e/calculator.po.ts
new file mode 100644
index 0000000000000000000000000000000000000000..31a21411827e0f847484859bb5163d455ea97185
--- /dev/null
+++ b/e2e/calculator.po.ts
@@ -0,0 +1,16 @@
+import { browser, by, element } from "protractor";
+
+export class CalculatorPage {
+  navigateTo() {
+    // @TODO won't work
+    return browser.get("/#/calculator/0");
+  }
+
+  getInputLabels() {
+    return element.all(by.css("ngparam-input label"));
+  }
+
+  getHeader1() {
+    return element(by.css("h1"));
+  }
+}
diff --git a/e2e/list.e2e-spec.ts b/e2e/list.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..027322c634866a0ba3e80eaac8f57bc16cba143e
--- /dev/null
+++ b/e2e/list.e2e-spec.ts
@@ -0,0 +1,14 @@
+import { ListPage } from "./list.po";
+
+describe("ngHyd − list page", () => {
+  let page: ListPage;
+
+  beforeEach(() => {
+    page = new ListPage();
+  });
+
+  it("when list is open, user should see the list of available compute nodes", async () => {
+    await page.navigateTo();
+    expect(page.getCalculatorsMenuLength()).toBeGreaterThan(8);
+  });
+});
diff --git a/e2e/list.po.ts b/e2e/list.po.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8b21d46d14e7c398dda682b1b061711f774e07b8
--- /dev/null
+++ b/e2e/list.po.ts
@@ -0,0 +1,22 @@
+import { browser, by, element } from "protractor";
+
+export class ListPage {
+  navigateTo() {
+    return browser.get("/#/list");
+  }
+
+  getCalculatorsMenuEntries() {
+    return element.all(by.css("ul.list-group"));
+  }
+
+  getCalculatorsMenuLength() {
+    return this.getCalculatorsMenuEntries().count();
+  }
+
+  async clickRandomCalculatorMenuEntry() {
+    const menuEntries = this.getCalculatorsMenuEntries();
+    const l = await menuEntries.count();
+    const r = Math.min((Math.floor(Math.random() * l)), (l - 1));
+    return menuEntries.get(r).click();
+  }
+}
diff --git a/e2e/load-sesssion.e2e-spec.ts b/e2e/load-sesssion.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6b11ef387f0c8ce4f20d0439b38781ecc00a1d54
--- /dev/null
+++ b/e2e/load-sesssion.e2e-spec.ts
@@ -0,0 +1,28 @@
+import { AppPage } from "./app.po";
+import { Navbar } from "./navbar.po";
+import { SideNav } from "./sidenav.po";
+
+describe("ngHyd − start page", () => {
+  let page: AppPage;
+  let navbar: Navbar;
+  let sidenav: SideNav;
+
+  beforeEach(() => {
+    page = new AppPage();
+    navbar = new Navbar();
+    sidenav = new SideNav();
+  });
+
+  it("when loading session-6-calc.test.json file from home page, 6 calculators should be loaded", async () => {
+    await page.navigateTo();
+    await navbar.clickMenuButton();
+    await sidenav.clickLoadSessionButton();
+    await sidenav.loadSessionFile("./session-6-calc.test.json");
+    expect(await navbar.getAllCalculatorTabs().count()).toBe(6);
+  });
+
+  /*it("when app starts, user should see the list of available compute nodes", () => {
+    page.navigateTo();
+    expect(page.getListLength()).toBeGreaterThan(8);
+  });*/
+});
diff --git a/e2e/navbar.po.ts b/e2e/navbar.po.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4b7bc3715a7c9a5514178489f7323e1e7efeae06
--- /dev/null
+++ b/e2e/navbar.po.ts
@@ -0,0 +1,37 @@
+import { by, element } from "protractor";
+
+export class Navbar {
+  getAllCalculatorTabs() {
+    return element.all(by.css("ul#navbar > li.calculator-tab"));
+  }
+
+  getNewCalculatorButton() {
+    return element(by.css("#new-calculator"));
+  }
+
+  getMenuButton() {
+    return element(by.css("#open-menu"));
+  }
+
+  async clickCalculatorTab(n: number) {
+    const tabs = this.getAllCalculatorTabs();
+    await tabs.get(n).click();
+  }
+
+  async clickRandomCalculatorTab(n: number) {
+    const tabs = this.getAllCalculatorTabs();
+    const l = await tabs.count();
+    const r = Math.min((Math.floor(Math.random() * l)), (l - 1));
+    await tabs.get(r).click();
+  }
+
+  async clickNewCalculatorButton() {
+    const ncb = this.getNewCalculatorButton();
+    await ncb.click();
+  }
+
+  async clickMenuButton() {
+    const ncb = this.getMenuButton();
+    await ncb.click();
+  }
+}
diff --git a/e2e/navigate-through-calculators.e2e-spec.ts b/e2e/navigate-through-calculators.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e33480fa8d4d439069ee173f1e5bf9d0cd664f50
--- /dev/null
+++ b/e2e/navigate-through-calculators.e2e-spec.ts
@@ -0,0 +1,34 @@
+import { ListPage } from "./list.po";
+import { Navbar } from "./navbar.po";
+import { CalculatorPage } from "./calculator.po";
+
+describe("ngHyd − create calculators and navigate among them", () => {
+  let listPage: ListPage;
+  let calculatorPage: CalculatorPage;
+  let navbar: Navbar;
+
+  beforeEach(() => {
+    listPage = new ListPage();
+    calculatorPage = new CalculatorPage();
+    navbar = new Navbar();
+  });
+
+  it("when many calculators are open, navigating among them should not fail (all labels should be visible)", async () => {
+    // open 8 calculators
+    for (let i = 0; i < 8; i++) {
+      await navbar.clickNewCalculatorButton();
+      await listPage.clickRandomCalculatorMenuEntry();
+    }
+    // navigate among them
+    for (let i = 0; i < 16; i++) {
+      await navbar.clickRandomCalculatorTab(i);
+      // test all form labels
+      const labels = calculatorPage.getInputLabels();
+      await labels.each(async (l) => {
+        const label = await l.getText();
+        expect(label.length).toBeGreaterThan(0);
+      });
+    }
+    // expect no error ?
+  });
+});
diff --git a/e2e/preferences.e2e-spec.ts b/e2e/preferences.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5516cb68387f36a175f4e4ff547f2a52572a3ca3
--- /dev/null
+++ b/e2e/preferences.e2e-spec.ts
@@ -0,0 +1,24 @@
+import { PreferencesPage } from "./preferences.po";
+
+describe("ngHyd − preferences page", () => {
+  let page: PreferencesPage;
+
+  beforeEach(() => {
+    page = new PreferencesPage();
+  });
+
+  it("when preferences are open, user should see a heading title", async () => {
+    await page.navigateTo();
+    const text = await page.getHeader1().getText();
+    expect(text.length).toBeGreaterThan(0);
+  });
+
+  it("when preferences are open, no label should be empty", async () => {
+    // page.navigateTo();
+    const labels = page.getInputLabels();
+    await labels.each(async (l) => {
+      const label = await l.getText();
+      expect(label.length).toBeGreaterThan(0);
+    });
+  });
+});
diff --git a/e2e/preferences.po.ts b/e2e/preferences.po.ts
new file mode 100644
index 0000000000000000000000000000000000000000..96ea80f42cde862b53c26b64b7b7b3f9728fcf3f
--- /dev/null
+++ b/e2e/preferences.po.ts
@@ -0,0 +1,15 @@
+import { browser, by, element } from "protractor";
+
+export class PreferencesPage {
+  navigateTo() {
+    return browser.get("/#/setup");
+  }
+
+  getHeader1() {
+    return element(by.css("h1"));
+  }
+
+  getInputLabels() {
+    return element.all(by.css("base-param-input label"));
+  }
+}
diff --git a/e2e/session-6-calc.test.json b/e2e/session-6-calc.test.json
new file mode 100644
index 0000000000000000000000000000000000000000..070c2019ffbbcf04af8916c80df6de9adf073391
--- /dev/null
+++ b/e2e/session-6-calc.test.json
@@ -0,0 +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
diff --git a/e2e/sidenav.po.ts b/e2e/sidenav.po.ts
new file mode 100644
index 0000000000000000000000000000000000000000..07dd1cea1fffe9fe8d3171cb108883fe764e6efb
--- /dev/null
+++ b/e2e/sidenav.po.ts
@@ -0,0 +1,29 @@
+import { by, element } from "protractor";
+import * as path from "path";
+
+export class SideNav {
+  getLoadSessionButton() {
+    return element(by.css("#side-nav-load-session"));
+  }
+
+  getFileInput() {
+    // tslint:disable-next-line:quotemark
+    return element(by.css('load-calc input[type="file"]'));
+  }
+
+  getFileLoadButton() {
+    return element(by.css("load-calc .modal-footer button.btn-success"));
+  }
+
+  async clickLoadSessionButton() {
+    const ncb = this.getLoadSessionButton();
+    await ncb.click();
+  }
+
+  async loadSessionFile(file: string) {
+    const absolutePath = path.resolve(__dirname, file);
+    const input = this.getFileInput();
+    await input.sendKeys(absolutePath);
+    await this.getFileLoadButton().click();
+  }
+}
diff --git a/e2e/tsconfig.e2e.json b/e2e/tsconfig.e2e.json
index a1af29b001311850be4f2cec89e12c5b1a5f9c4d..801a822f4cfe1ac679c66be90206eb1997c969ef 100644
--- a/e2e/tsconfig.e2e.json
+++ b/e2e/tsconfig.e2e.json
@@ -4,7 +4,6 @@
     "outDir": "../out-tsc/e2e",
     "baseUrl": "./",
     "module": "commonjs",
-    "target": "es5",
     "downlevelIteration": true,
     "types": [
       "jasmine",
diff --git a/package.json b/package.json
index 7daf4f2e8d2ac71d86617d6d7e8a6436bf4d32ff..1d02b3f71309b155dc97269dab886340a974d5f4 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
     "mathjax": "rsync -az --delete node_modules/mathjax src/assets;",
     "mkdocs": "python3 -m mkdocs build",
     "preprocess": "node preprocessors.js; npm run mathjax; npm run mkdocs;",
+    "viz": "tsviz -recursive src/ nghyd_class_diagram.png",
     "compodoc-patch": "sed -i '/Application.prototype.detectAngularJSProjects = function () {/a return false; // patch cracra, voir https://github.com/compodoc/compodoc/issues/667' node_modules/@compodoc/compodoc/dist/index-cli.js",
     "compodoc": "nodejs node_modules/@compodoc/compodoc/bin/index-cli.js -p src/tsconfig.app.json -s --language fr-FR -d compodoc-fr"
   },
diff --git a/protractor.conf.js b/protractor.conf.js
index 7ee3b5ee863a74c87dbc4f4bee10b1fd1016cbf4..a2584537bfd8d7b18361bfb3ace681021ba2d824 100644
--- a/protractor.conf.js
+++ b/protractor.conf.js
@@ -12,7 +12,7 @@ exports.config = {
     'browserName': 'chrome'
   },
   directConnect: true,
-  baseUrl: 'http://localhost:4200/',
+  baseUrl: 'http://localhost:4201/',
   framework: 'jasmine',
   jasmineNodeOpts: {
     showColors: true,
diff --git a/src/app/app.component.html b/src/app/app.component.html
index ec852a1a452eb86e2062b9c1b84d9f0efd82fcc3..b1e92164976b1c922802f3cb14ebc8994a369903 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -2,7 +2,7 @@
   <!--Navbar -->
   <nav class="navbar navbar-expand-sm navbar-dark indigo">
     <!-- Ouverture du sidenav -->
-    <span style="font-size:30px;cursor:pointer;color:white" (click)="openNav()">☰</span>
+    <span id="open-menu" style="font-size:30px;cursor:pointer;color:white" (click)="openNav()">☰</span>
 
     <!-- lien vide pour que le toggler des liens apparaisse à droite -->
     <a class="navbar-brand"></a>
@@ -16,12 +16,12 @@
 
     <!-- Collapsible content -->
     <div class="collapse navbar-collapse" id="navbarSupportedContent">
-      <ul class="navbar-nav mr-auto">
-        <li class="nav-item" *ngFor="let c of calculators">
+      <ul id="navbar" class="navbar-nav mr-auto">
+        <li class="nav-item calculator-tab" *ngFor="let c of calculators">
           <a class="nav-link waves-light {{getHighlightClass(c.uid)}}" mdbRippleRadius [routerLink]="['/calculator/',c.uid]">{{ c.title }}</a>
         </li>
-        <li class="nav-item">
-            <i class="fa fa-plus-square fa-2x fa-inverse" style='vertical-align: middle' (click)='newCalc()'></i>
+        <li class="nav-item" id="add-calculator-tab">
+            <i id="new-calculator" class="fa fa-plus-square fa-2x fa-inverse" style='vertical-align: middle' routerLink="/list" (click)='closeNav()'></i>
         </li>
       </ul>
     </div>
@@ -35,11 +35,11 @@
     <div class="row">
       <div id="mySidenav" class="sidenav">
         <!-- ATTENTION ! pas de href="#" sous peine de rechargement de la page et réinitialisation de l'appli -->
-        <a class="closebtn" (click)="closeNav()">×</a>
-        <a (click)="newCalc()">{{ uitextSidenavNewCalc }}</a>
-        <a (click)="loadSession()">{{ uitextSidenavLoadSession }}</a>
-        <a (click)="params()">{{ uitextSidenavParams }}</a>
-        <a target="_blank" href="assets/docs-fr/">Aide</a>
+        <a id="close-side-nav" class="closebtn" (click)="closeNav()">×</a>
+        <a id="side-nav-list" routerLink="/list" (click)="closeNav()">{{ uitextSidenavNewCalc }}</a>
+        <a id="side-nav-load-session" (click)="loadSession()">{{ uitextSidenavLoadSession }}</a>
+        <a id="side-nav-setup" routerLink="/setup" (click)="closeNav()">{{ uitextSidenavParams }}</a>
+        <a id="side-nav-help" target="_blank" href="assets/docs-fr/" (click)="closeNav()">{{ uitextSidenavHelp }}</a>
         <div class="hyd_fillvertical"></div>
         <div class="hyd_version">
           JaLHyd version: {{ getDateRevision()[0] }}<br/>
@@ -50,10 +50,10 @@
   </div>
 
   <!-- chargement des calculettes -->
-  <div loadCalcDialogAnchor></div>
+  <div appLoadCalcDialogAnchor></div>
 
   <!-- sauvegarde des calculettes -->
-  <div saveCalcDialogAnchor></div>
+  <div appSaveCalcDialogAnchor></div>
 
   <!-- règle gradée des colonnes Bootstrap -->
   <div *ngIf="ruler" class="container-fluid">
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 28ec769737a8132e7d12ae1cf0e9436243a2cb39..811356e827b358e5e6951a1ea80686d848e3129b 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,5 +1,4 @@
 import { Component, ApplicationRef, OnInit, OnDestroy, HostListener, ViewChild, ComponentRef } from "@angular/core";
-// import { MdDialog } from '@angular/material';
 import { Router, ActivatedRoute } from "@angular/router";
 
 import { Observer, jalhydDateRev } from "jalhyd";
@@ -7,7 +6,6 @@ import { Observer, jalhydDateRev } from "jalhyd";
 import { environment } from "../environments/environment";
 import { InternationalisationService } from "./services/internationalisation/internationalisation.service";
 import { ErrorService } from "./services/error/error.service";
-// import { AlertDialog } from './components/alert-dialog/alert-dialog.component';
 import { FormulaireService } from "./services/formulaire/formulaire.service";
 import { FormulaireDefinition } from "./formulaire/definition/form-definition";
 import { ServiceFactory } from "./services/service-factory";
@@ -28,8 +26,6 @@ import { nghydDateRev } from "../date_revision";
   providers: [ErrorService]
 })
 export class AppComponent implements OnInit, OnDestroy, Observer {
-  private _displayErrorDialog = false;
-
   /**
    * liste des calculettes. Forme des objets :
    * "title": nom de la calculette
@@ -44,10 +40,10 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
   private _currentFormId: number;
 
   @ViewChild(LoadCalcDialogAnchorDirective)
-  private loadCalcDialogAnchor: LoadCalcDialogAnchorDirective;
+  private appLoadCalcDialogAnchor: LoadCalcDialogAnchorDirective;
 
   @ViewChild(SaveCalcDialogAnchorDirective)
-  private saveCalcDialogAnchor: SaveCalcDialogAnchorDirective;
+  private appSaveCalcDialogAnchor: SaveCalcDialogAnchorDirective;
 
   /**
    * composant actuellement affiché par l'élément <router-outlet>
@@ -61,7 +57,6 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
     private appRef: ApplicationRef,
     private errorService: ErrorService,
     private router: Router,
-    private route: ActivatedRoute,
     private formulaireService: FormulaireService,
     private httpService: HttpService
   ) {
@@ -99,7 +94,11 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
   }
 
   public get uitextSidenavLoadSession() {
-    return "Charger une session";
+    return this.intlService.localizeText("INFO_MENU_LOAD_SESSION_TITLE");
+  }
+
+  public get uitextSidenavHelp() {
+    return this.intlService.localizeText("INFO_MENU_HELP_TITLE");
   }
 
   public get calculators() {
@@ -188,9 +187,9 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
     }
   }
 
-  private getCalculatorIndexFromId(formId: number) {
+  private getCalculatorIndexFromId(formId: string) {
     const index = this._calculators.reduce((resultIndex, calc, currIndex) => {
-      if (resultIndex === -1 && +calc["uid"] === formId) {
+      if (resultIndex === -1 && calc["uid"] === formId) {
         resultIndex = currIndex;
       }
       return resultIndex;
@@ -210,12 +209,12 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
    */
   private saveForm(form: FormulaireDefinition) {
     // création du dialogue de sélection des formulaires à sauver
-    const compRef: ComponentRef<SaveCalculatorComponent> = this.saveCalcDialogAnchor.createDialog();
+    const compRef: ComponentRef<SaveCalculatorComponent> = this.appSaveCalcDialogAnchor.createDialog();
 
     // création de la liste des formulaires
     const list = [];
     for (const c of this._calculators) {
-      const uid = +c["uid"];
+      const uid = c["uid"];
       list.push({
         "selected": uid === form.uid,
         "title": c["title"],
@@ -253,7 +252,7 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
   }
 
   private closeCalculator(form: FormulaireDefinition) {
-    const formId: number = form.uid;
+    const formId: string = form.uid;
 
     // désabonnement en tant qu'observateur
 
@@ -269,27 +268,27 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
      * - ou celle avant celle supprimée si on supprime la dernière
      */
 
-    let newId = -1;
+    let newId = null;
     const l = this._calculators.length;
     if (l > 1) {
       if (closedIndex === l - 1) {
-        newId = +this._calculators[closedIndex - 1]["uid"];
+        newId = this._calculators[closedIndex - 1]["uid"];
       } else {
-        newId = +this._calculators[closedIndex + 1]["uid"];
+        newId = this._calculators[closedIndex + 1]["uid"];
       }
     }
 
     // suppression
 
     this._calculators = this._calculators.filter(calc => {
-      return formId !== +calc["uid"];
+      return formId !== calc["uid"];
     });
 
     // MAJ affichage
 
-    if (newId === -1) {
+    if (newId === null) {
       this.toList();
-      this._currentFormId = -1;
+      this._currentFormId = null;
     } else {
       this.toCalc(newId);
     }
@@ -331,16 +330,11 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
     document.getElementById("mySidenav").style.width = "0";
   }
 
-  public newCalc() {
-    this.closeNav();
-    this.toList();
-  }
-
   public loadSession() {
     this.closeNav();
 
     // création du dialogue de sélection des formulaires à sauver
-    const compRef: ComponentRef<LoadCalculatorComponent> = this.loadCalcDialogAnchor.createDialog();
+    const compRef: ComponentRef<LoadCalculatorComponent> = this.appLoadCalcDialogAnchor.createDialog();
 
     const prom: Promise<any[]> = compRef.instance.run();
     prom.then(list => {
@@ -349,11 +343,6 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
     }).catch(err => { });
   }
 
-  public params() {
-    this.closeNav();
-    this.router.navigate(["/setup"]);
-  }
-
   public getDateRevision(): string[] {
     const dr: string[] = [jalhydDateRev, nghydDateRev];
     return dr;
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 1650bd320089c47b16fc9ec5711e98c03b7624fc..0e611c9086bcec30853fd7b5ca3d525ccef61250 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -4,7 +4,6 @@ import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core";
 import { MDBBootstrapModule } from "angular-bootstrap-md";
 import { HttpClientModule } from "@angular/common/http";
 import { FormsModule } from "@angular/forms"; // <-- NgModel lives here
-// import { MdInputModule, MdDialogModule } from '@angular/material';
 import { ChartModule } from "angular2-chartjs";
 import { RouterModule, Routes } from "@angular/router";
 import { NgxMdModule } from "ngx-md";
@@ -56,15 +55,17 @@ const appRoutes: Routes = [
   { path: "list", component: CalculatorListComponent },
   { path: "calculator/:uid", component: GenericCalculatorComponent },
   { path: "setup", component: ApplicationSetupComponent },
-  { path: "**", component: CalculatorListComponent }
+  { path: "**", redirectTo: "list", pathMatch: "full" }
 ];
 
 @NgModule({
   imports: [
     RouterModule.forRoot(
       appRoutes,
-      // { enableTracing: true } // <-- debugging purposes only
-      { enableTracing: false }
+      {
+        useHash: true, // prevents reloading whole app when typing url in browser's navigation bar
+        enableTracing: false // debugging purposes only
+      }
     ),
     BrowserModule,
     NgxMdModule.forRoot(),
diff --git a/src/app/components/base-param-input/base-param-input.component.ts b/src/app/components/base-param-input/base-param-input.component.ts
index 8144f03d7d98e0861c8946980a46b773988e682d..2a3588fc0a1f882b17b3d5a4579568a1ddd579de 100644
--- a/src/app/components/base-param-input/base-param-input.component.ts
+++ b/src/app/components/base-param-input/base-param-input.component.ts
@@ -2,7 +2,7 @@
 
 import { Component, ChangeDetectorRef } from "@angular/core";
 
-import { NumericalString, Message, ParamDefinition, ParamDomain, ParamDomainValue, Observable } from "jalhyd";
+import { Message, ParamDefinition, ParamDomain, ParamDomainValue, Observable, isNumeric } from "jalhyd";
 
 import { InternationalisationService } from "../../services/internationalisation/internationalisation.service";
 import { GenericInputComponent } from "../generic-input/generic-input.component";
@@ -12,7 +12,7 @@ export class NgBaseParam extends Observable {
 
     constructor(symb: string, d: ParamDomain | ParamDomainValue, val: number) {
         super();
-        this._param = new ParamDefinition(symb, d, val);
+        this._param = new ParamDefinition(null, symb, d, val);
     }
 
     public get symbol() {
@@ -102,8 +102,7 @@ export class BaseParamInputComponent extends GenericInputComponent {
         let valid = false;
         let msg: string;
 
-        const v: NumericalString = new NumericalString(ui);
-        if (!v.isNumerical) {
+        if (! isNumeric(ui)) {
             msg = "Veuillez entrer une valeur numérique";
         } else {
             valid = true;
diff --git a/src/app/components/base/base.component.ts b/src/app/components/base/base.component.ts
index 0fefbaf2cf96b66d53d9c577610e319d0cec9c68..5bdc6df61c28d4a4c9a2e97548512497984899b6 100644
--- a/src/app/components/base/base.component.ts
+++ b/src/app/components/base/base.component.ts
@@ -15,10 +15,10 @@ export abstract class BaseComponent implements AfterViewChecked, OnChanges {
      * événement émis en même temps que l'appel à afterFirstViewChecked()
      */
     @Output()
-    private onFirstViewCheck: EventEmitter<void>;
+    private firstViewCheck: EventEmitter<void>;
 
     constructor() {
-        this.onFirstViewCheck = new EventEmitter();
+        this.firstViewCheck = new EventEmitter();
     }
 
     public ngAfterViewChecked() {
@@ -28,7 +28,7 @@ export abstract class BaseComponent implements AfterViewChecked, OnChanges {
             this.afterFirstViewChecked();
 
             if (this.emitFirstViewCheck) {
-                this.onFirstViewCheck.emit();
+                this.firstViewCheck.emit();
             }
         }
     }
diff --git a/src/app/components/calculator-results/calculator-results.component.ts b/src/app/components/calculator-results/calculator-results.component.ts
index 9457d73854937e97ae06aecbd3e2684d0c1906ef..c6489fa69a1f5b9fb11587a08c1239778ac93020 100644
--- a/src/app/components/calculator-results/calculator-results.component.ts
+++ b/src/app/components/calculator-results/calculator-results.component.ts
@@ -38,7 +38,7 @@ export class CalculatorResultsComponent implements AfterViewChecked {
 
     public set formulaire(f: FormulaireDefinition) {
         this._formulaire = f;
-        if (this._formulaire == undefined) {
+        if (this._formulaire === undefined) {
             this.fixedVarResultsComponent.results = undefined;
             this.sectionResultsComponent.results = undefined;
             this.remousResultsComponent.results = undefined;
diff --git a/src/app/components/check-field-line/check-field-line.component.html b/src/app/components/check-field-line/check-field-line.component.html
index d2f9a1efe722abb2eb36969fb7fe049ac129f1ba..f00f6fca5843423f7d52b41f5a509c5a70648fde 100644
--- a/src/app/components/check-field-line/check-field-line.component.html
+++ b/src/app/components/check-field-line/check-field-line.component.html
@@ -1,9 +1,6 @@
 <tr>
     <td align="right">{{ check.label }}</td>
     <td colspan="3">
-        <!--
-        <input type="checkbox" >
-        -->
         <input type="checkbox" [(ngModel)]=currentValue (ngModelChange)="onChange($event)">
     </td>
 </tr>
\ No newline at end of file
diff --git a/src/app/components/check-field-line/check-field-line.component.ts b/src/app/components/check-field-line/check-field-line.component.ts
index a70da00e01eba030c3786965fa121ad9ccb28584..ae159f511062947071e1ccfefddfec5653ecb09e 100644
--- a/src/app/components/check-field-line/check-field-line.component.ts
+++ b/src/app/components/check-field-line/check-field-line.component.ts
@@ -7,7 +7,7 @@ import { CheckField } from "../../formulaire/check-field";
     templateUrl: "./check-field-line.component.html",
 })
 export class CheckFieldLineComponent {
-    @Input("param")
+    @Input()
     public check: CheckField;
 
     public currentValue: boolean;
diff --git a/src/app/components/field-set/field-set.component.html b/src/app/components/field-set/field-set.component.html
index a372d6811a6ffc6b031df1443a17d6b03f7481b7..9fae14a33a4d08eb39ddaa0a71d2c2a894100b8a 100644
--- a/src/app/components/field-set/field-set.component.html
+++ b/src/app/components/field-set/field-set.component.html
@@ -21,11 +21,11 @@
 -->
 
 <ng-template ngFor let-p [ngForOf]="fields">
-    <param-field-line *ngIf="isInputField(p)" [param]=p (onRadio)=onRadioClick($event) (valid)=onParamLineValid() (inputChange)=onInputChange()>
+    <param-field-line *ngIf="isInputField(p)" [param]=p (radio)=onRadioClick($event) (valid)=onParamLineValid() (inputChange)=onInputChange()>
     </param-field-line>
 
     <select-field-line *ngIf="isSelectField(p)" [_select]=p>
     </select-field-line>
 
-    <check-field-line *ngIf="isCheckField(p)" [param]=p></check-field-line>
+    <check-field-line *ngIf="isCheckField(p)" [check]=p></check-field-line>
 </ng-template>
\ No newline at end of file
diff --git a/src/app/components/field-set/field-set.component.ts b/src/app/components/field-set/field-set.component.ts
index bacdb00a9184487cb57293d92703224d234e83cc..24a031d4df575d78117d2adf4c3c1e24bb8475a2 100644
--- a/src/app/components/field-set/field-set.component.ts
+++ b/src/app/components/field-set/field-set.component.ts
@@ -154,8 +154,9 @@ export class FieldSetComponent implements DoCheck {
     /**
      * événement de changement d'état d'un radio
      */
+    // tslint:disable-next-line:no-output-on-prefix
     @Output()
-    private onRadio = new EventEmitter<any>();
+    private radio = new EventEmitter<any>();
 
     private hasRadioFix(): boolean {
         if (this._fieldSet.hasInputs) {
@@ -225,7 +226,7 @@ export class FieldSetComponent implements DoCheck {
      */
     private onRadioClick(info: any) {
         // on renvoie l'info au parent
-        this.onRadio.emit(info);
+        this.radio.emit(info);
     }
 
     /**
diff --git a/src/app/components/fieldset-container/fieldset-container.component.html b/src/app/components/fieldset-container/fieldset-container.component.html
index 086ed2ba2f3605faac9fa1a83acd4ff1d1be55c4..84e4f78e5a5c47b81372383aafb6a8126856e52f 100644
--- a/src/app/components/fieldset-container/fieldset-container.component.html
+++ b/src/app/components/fieldset-container/fieldset-container.component.html
@@ -3,7 +3,7 @@
         <h4 class="col">{{ title }}</h4>
     </div>
 
-    <field-set *ngFor="let fs of fieldsets" [fieldSet]=fs (onRadio)=onRadioClick($event) (valid)=onFieldsetValid() (inputChange)=onInputChange()
+    <field-set *ngFor="let fs of fieldsets" [fieldSet]=fs (radio)=onRadioClick($event) (valid)=onFieldsetValid() (inputChange)=onInputChange()
         (addFieldset)=onAddFieldset($event) (removeFieldset)=onRemoveFieldset($event) (moveFieldsetUp)=onMoveFieldsetUp($event)
         (moveFieldsetDown)=onMoveFieldsetDown($event)>
     </field-set>
diff --git a/src/app/components/fieldset-container/fieldset-container.component.ts b/src/app/components/fieldset-container/fieldset-container.component.ts
index c4c1e5800de5ccfeb5d1bdaeb7071bea4dbb56a5..ccfedcec387e31e40bb4f141f2b30797459dbc1d 100644
--- a/src/app/components/fieldset-container/fieldset-container.component.ts
+++ b/src/app/components/fieldset-container/fieldset-container.component.ts
@@ -12,7 +12,7 @@ import { FormulaireDefinition } from "../../formulaire/definition/form-definitio
 export class FieldsetContainerComponent implements DoCheck, AfterViewInit {
 
     public get title(): string {
-        if (this._container == undefined) {
+        if (this._container === undefined) {
             return undefined;
         }
         return this._container.label;
@@ -25,7 +25,7 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit {
     public get isValid() {
         return this._isValid;
     }
-    @Input("container")
+    @Input()
     private _container: FieldsetContainer;
 
     /**
@@ -42,8 +42,9 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit {
     /**
      * événément de changement d'état d'un radio
      */
+    // tslint:disable-next-line:no-output-on-prefix
     @Output()
-    private onRadio = new EventEmitter<any>();
+    private radio = new EventEmitter<any>();
 
     /**
      * événément de changement de validité
@@ -70,7 +71,7 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit {
         this._fieldsetComponents.forEach(fs => fs.showButtons = true);
 
         // désactivation du bouton supprimer s'il n'en reste qu'un
-        if (this._fieldsetComponents.length == 1) {
+        if (this._fieldsetComponents.length === 1) {
             const fs = this._fieldsetComponents.last as FieldSetComponent;
             fs.enableRemoveButton = false;
         } else {
@@ -108,7 +109,7 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit {
      */
     private onRadioClick(info: any) {
         // on renvoie l'info au parent
-        this.onRadio.emit(info);
+        this.radio.emit(info);
     }
 
     public ngDoCheck() {
@@ -121,7 +122,7 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit {
     private updateValidity() {
         this._isValid = false;
 
-        if (this._fieldsetComponents != undefined) {
+        if (this._fieldsetComponents !== undefined) {
             this._isValid = this._fieldsetComponents.reduce(
                 // callback
                 (
diff --git a/src/app/components/fixedvar-results/fixed-results.component.html b/src/app/components/fixedvar-results/fixed-results.component.html
index 011abed0f0852afed2b74e9887ec325f5ab8c91b..703075f95dc6c55653e78138b4bdf88a723a8752 100644
--- a/src/app/components/fixedvar-results/fixed-results.component.html
+++ b/src/app/components/fixedvar-results/fixed-results.component.html
@@ -22,7 +22,7 @@
                         {{ formattedValue(r) }}
                     </td>
                 </tr>
-                <tr *ngIf="hasParameterResult" vertical-result-element [result-element]=resultElement [label]=resultLabel>
+                <tr *ngIf="hasParameterResult" vertical-result-element [result-element]=resultElement [_label]=resultLabel>
                 </tr>
             </table>
         </div>
diff --git a/src/app/components/fixedvar-results/fixed-results.component.ts b/src/app/components/fixedvar-results/fixed-results.component.ts
index b599d014a979f8bc741a0130ee57c530c48be2de..0b7056b8f244a26aa4ef8da2dde10109002e0bbf 100644
--- a/src/app/components/fixedvar-results/fixed-results.component.ts
+++ b/src/app/components/fixedvar-results/fixed-results.component.ts
@@ -65,8 +65,9 @@ export class FixedResultsComponent {
     }
 
     private getFixedParamClass(i: number) {
-        // if (this._results.isFixed && i == this._results.fixedResults.length - 1)
+        // if (this._results.isFixed && i === this._results.fixedResults.length - 1)
         // return "font-weight-bold";
+        // tslint:disable-next-line:no-bitwise
         return "result_id_" + String(i & 1);
     }
 
diff --git a/src/app/components/fixedvar-results/fixedvar-results.component.ts b/src/app/components/fixedvar-results/fixedvar-results.component.ts
index 218f0c0bf6f333d5037c4a73d12ba6f2f8769ed4..8ef80d00cd31c5d87f31be25ce9ab12d22620246 100644
--- a/src/app/components/fixedvar-results/fixedvar-results.component.ts
+++ b/src/app/components/fixedvar-results/fixedvar-results.component.ts
@@ -73,7 +73,7 @@ export class FixedVarResultsComponent implements DoCheck {
     public set results(rs: CalculatorResults[]) {
         this._fixedResults = undefined;
         this._varResults = undefined;
-        if (rs != undefined) {
+        if (rs !== undefined) {
             for (const r of rs) {
                 if (r instanceof FixedResults) {
                     this._fixedResults = r;
@@ -99,10 +99,10 @@ export class FixedVarResultsComponent implements DoCheck {
         }
 
         this._doUpdate = false;
-        if (this._fixedResults != undefined) {
+        if (this._fixedResults !== undefined) {
             this._doUpdate = this._fixedResults.hasResults || this._fixedResults.hasLog;
         }
-        if (this._varResults != undefined) {
+        if (this._varResults !== undefined) {
             this._doUpdate = this._doUpdate || this._varResults.hasResults || this._varResults.hasLog;
         }
     }
@@ -140,7 +140,7 @@ export class FixedVarResultsComponent implements DoCheck {
      * @returns true si les résultats ont pu être mis à jour
      */
     private updateResults() {
-        const fixedUpdated = this._fixedResults != undefined && this.fixedResultsComponent != undefined;
+        const fixedUpdated = this._fixedResults !== undefined && this.fixedResultsComponent !== undefined;
         if (fixedUpdated) {
             this.fixedResultsComponent.results = this._fixedResults;
         }
@@ -148,12 +148,12 @@ export class FixedVarResultsComponent implements DoCheck {
         let graphUpdated: boolean;
         let varUpdated: boolean;
         if (this._varResults && this._varResults.hasResults) {
-            varUpdated = this.varResultsComponent != undefined;
+            varUpdated = this.varResultsComponent !== undefined;
             if (varUpdated) {
                 this.varResultsComponent.results = this._varResults;
             }
 
-            graphUpdated = this.resultsGraphComponent != undefined;
+            graphUpdated = this.resultsGraphComponent !== undefined;
             if (graphUpdated) {
                 this.resultsGraphComponent.results = this._varResults;
                 this.resultsGraphComponent.updateView();
@@ -163,7 +163,7 @@ export class FixedVarResultsComponent implements DoCheck {
             graphUpdated = true;
         }
 
-        const logUpdated = this.logComponent != undefined;
+        const logUpdated = this.logComponent !== undefined;
         if (logUpdated) {
             this.logComponent.log = this.mergedGlobalLogs;
         }
@@ -186,6 +186,7 @@ export class FixedVarResultsComponent implements DoCheck {
     }
 
     private getFixedResultClass(i: number) {
+        // tslint:disable-next-line:no-bitwise
         return "result_id_" + String(i & 1);
     }
 
@@ -211,6 +212,6 @@ export class FixedVarResultsComponent implements DoCheck {
     }
 
     private get hasResults(): boolean {
-        return this._fixedResults != undefined && this._fixedResults.hasResults;
+        return this._fixedResults !== undefined && this._fixedResults.hasResults;
     }
 }
diff --git a/src/app/components/generic-calculator/calc-name.component.ts b/src/app/components/generic-calculator/calc-name.component.ts
index 45334b4abca1d98a572bfa205a5b4284c5d917fe..21e9d67ac354a551f1432f3422421d273ffcce74 100644
--- a/src/app/components/generic-calculator/calc-name.component.ts
+++ b/src/app/components/generic-calculator/calc-name.component.ts
@@ -23,7 +23,7 @@ export class CalculatorNameComponent extends GenericInputComponent {
      * retourne la valeur du modèle
      */
     protected getModelValue(): any {
-        if (this._form == undefined) {
+        if (this._form === undefined) {
             return undefined;
         }
         return this._form.calculatorName;
@@ -47,7 +47,7 @@ export class CalculatorNameComponent extends GenericInputComponent {
         let msg;
         let valid = false;
 
-        if (!(typeof (v) == "string") || v.length < 1) {
+        if (!(typeof (v) === "string") || v.length < 1) {
             msg = "Veuillez entrer un nom";
         } else {
             valid = true;
@@ -73,7 +73,7 @@ export class CalculatorNameComponent extends GenericInputComponent {
         let valid = false;
         let msg: string;
 
-        if (ui == undefined || ui.length < 1) {
+        if (ui === undefined || ui.length < 1) {
             msg = "Veuillez entrer un nom";
         } else {
             valid = true;
diff --git a/src/app/components/generic-calculator/calculator.component.html b/src/app/components/generic-calculator/calculator.component.html
index 72a35461382dc02658794c73f6dcf21a81ce6c21..1afebb5b545461c5004a1af63507d6cc11b172a3 100644
--- a/src/app/components/generic-calculator/calculator.component.html
+++ b/src/app/components/generic-calculator/calculator.component.html
@@ -27,10 +27,10 @@
         <div class="container-fluid">
             <!-- chapitres -->
             <ng-template ngFor let-fe [ngForOf]="formElements">
-                <field-set *ngIf="isFieldset(fe)" [style.display]="getFieldsetStyleDisplay(fe.id)" [fieldSet]=fe (onRadio)=onRadioClick($event)
+                <field-set *ngIf="isFieldset(fe)" [style.display]="getFieldsetStyleDisplay(fe.id)" [fieldSet]=fe (radio)=onRadioClick($event)
                     (validChange)=OnFieldsetValid() (inputChange)=onInputChange()></field-set>
 
-                <fieldset-container *ngIf="isFieldsetContainer(fe)" [container]=fe (onRadio)=onRadioClick($event) (validChange)=onFieldsetContainerValid()></fieldset-container>
+                <fieldset-container *ngIf="isFieldsetContainer(fe)" [_container]=fe (radio)=onRadioClick($event) (validChange)=onFieldsetContainerValid()></fieldset-container>
             </ng-template>
         </div>
 
diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts
index ebac5b87727e17a3f68ae25dda930169f6c97b28..c71f47b8597e18dc8d76f7aad080d6289e0eab7a 100644
--- a/src/app/components/generic-calculator/calculator.component.ts
+++ b/src/app/components/generic-calculator/calculator.component.ts
@@ -73,7 +73,7 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
     public isCalculateDisabled = true;
 
     /**
-     * flag (+info) indiquant un événement onRadio à traiter
+     * flag (+info) indiquant un événement radio à traiter
      * nécessaire avec l'introduction du mode de valeur LINK des paramètres car quand on modifie le mode à LINK, les possibles
      * paramètres liables ne sont pas encore connus
      */
@@ -172,8 +172,8 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
     private subscribeRouter() {
         // récupération des paramètres passés avec la route (URL)
         this._subscription = this.route.params.subscribe(params => {
-            const uid: number = params["uid"];
-            this.formulaireService.setCurrentForm(+uid);
+            const uid: string = params["uid"];
+            this.formulaireService.setCurrentForm(uid);
         });
     }
 
@@ -266,7 +266,7 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
         }
     }
 
-    private updateFormulaireResults(uid: number) {
+    private updateFormulaireResults(uid: string) {
         if (this._formulaire.uid === uid) {
             this.resultsComponent.updateView();
         }
@@ -280,7 +280,7 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
         } else if (sender instanceof FormulaireService) {
             switch (data["action"]) {
                 case "currentFormChanged":
-                    const uid: number = +data["formId"];
+                    const uid: string = data["formId"];
                     this.setForm(this.formulaireService.getFormulaireFromId(uid));
                     this.resultsComponent.formulaire = this._formulaire;
                     this._calculatorNameComponent.model = this._formulaire;
diff --git a/src/app/components/generic-input/generic-input.component.ts b/src/app/components/generic-input/generic-input.component.ts
index e5513138b57a21d92d89b82c262a947ab8cfd775..90c2e7c034564425ab9aad6bb68fb724a5f724a2 100644
--- a/src/app/components/generic-input/generic-input.component.ts
+++ b/src/app/components/generic-input/generic-input.component.ts
@@ -8,7 +8,7 @@ exemple de template :
 <div class="md-form form-sm">
     <input mdbActive type="text" id="form1" class="form-control" [disabled]="isDisabled"
         [ngModel]="uiValue" (ngModelChange)="setUIValue($event)">
-    <label for="form1">{{_title}}</label>
+    <label for="form1">{{title}}</label>
     <small class="text-danger">{{_message}}</small>
 </div>
 */
@@ -32,7 +32,7 @@ export abstract class GenericInputComponent extends BaseComponent implements OnC
     /**
      * flag de désactivation de l'input
      */
-    @Input("inputDisabled")
+    @Input()
     private _inputDisabled = false;
 
     /**
@@ -48,14 +48,14 @@ export abstract class GenericInputComponent extends BaseComponent implements OnC
     /**
      * chaîne affichée dans l'input quand aucune valeur n'est saisie
      */
-    @Input("title")
-    private _title: string;
+    @Input()
+    public title: string;
 
     /**
      * événement signalant un changement : valeur du modèle, validité, ...
      */
     @Output()
-    protected onChange = new EventEmitter<any>();
+    protected change = new EventEmitter<any>();
 
     /**
      * valeur saisie.
@@ -99,7 +99,7 @@ export abstract class GenericInputComponent extends BaseComponent implements OnC
      * événement de changement de la validité de la saisie
      */
     private emitValidChanged() {
-        this.onChange.emit({ "action": "valid", "value": this.isValid });
+        this.change.emit({ "action": "valid", "value": this.isValid });
     }
 
     /**
@@ -176,7 +176,7 @@ export abstract class GenericInputComponent extends BaseComponent implements OnC
      */
     private emitModelChanged() {
         // console.log("emit model change", this.constructor.name);
-        this.onChange.emit({ "action": "model", "value": this.getModelValue() });
+        this.change.emit({ "action": "model", "value": this.getModelValue() });
     }
 
     private setAndValidateModel(sender: any, v: any) {
@@ -206,10 +206,6 @@ export abstract class GenericInputComponent extends BaseComponent implements OnC
         return this._uiValue;
     }
 
-    public get title() {
-        return this._title;
-    }
-
     /*
      * fonction appelée lorsque l'utilisateur fait une saisie
      * @param ui valeur dans le contrôle
@@ -295,7 +291,7 @@ export abstract class GenericInputComponent extends BaseComponent implements OnC
 /*
 import { Component } from "@angular/core";
 
-import { NumericalString, Message } from "jalhyd";
+import { isNumeric, Message } from "jalhyd";
 
 // exemple où le modèle est un type simple (number)
 
@@ -303,7 +299,7 @@ import { NumericalString, Message } from "jalhyd";
     selector: "test-input",
     template: `<div class="md-form form-sm">
     <input mdbActive type="text" id="form1" class="form-control" [disabled]="isDisabled" [(ngModel)]="uiValue">
-    <label for="form1">{{_title}}</label>
+    <label for="form1">{{title}}</label>
     <small *ngIf="showError" class="text-danger">{{errorMessage}}</small>
 </div>`
 })
@@ -334,7 +330,7 @@ export class TestInputComponent extends GenericInputComponent {
     }
 
     protected modelToUI(v: any): string {
-        if (typeof (v) == "number")
+        if (typeof (v) === "number")
             return String(v);
         return undefined;
     }
@@ -343,8 +339,7 @@ export class TestInputComponent extends GenericInputComponent {
         let valid: boolean = false;
         let msg: string = undefined;
 
-        let v: NumericalString = new NumericalString(ui);
-        if (!v.isNumerical)
+        if (! isNumeric(ui))
             msg = "Veuillez entrer une valeur numérique";
         else
             valid = true;
@@ -366,7 +361,7 @@ import { ParamDefinition } from "jalhyd";
     selector: "test2-input",
     template: `<div class="md-form form-sm">
     <input mdbActive type="text" id="form1" class="form-control" [disabled]="isDisabled" [(ngModel)]="uiValue">
-    <label for="form1">{{_title}}</label>
+    <label for="form1">{{title}}</label>
     <small *ngIf="showError" class="text-danger">{{errorMessage}}</small>
 </div>`
 })
@@ -401,7 +396,7 @@ export class Test2InputComponent extends GenericInputComponent {
     }
 
     protected modelToUI(v: any): string {
-        if (typeof (v) == "number")
+        if (typeof (v) === "number")
             return String(v);
         return undefined;
     }
@@ -410,8 +405,7 @@ export class Test2InputComponent extends GenericInputComponent {
         let valid: boolean = false;
         let msg: string = undefined;
 
-        let v: NumericalString = new NumericalString(ui);
-        if (!v.isNumerical)
+        if (! isNumeric(ui))
             msg = "Veuillez entrer une valeur numérique";
         else
             valid = true;
diff --git a/src/app/components/load-calculator/load-calculator-anchor.directive.ts b/src/app/components/load-calculator/load-calculator-anchor.directive.ts
index dda9149986157dacc41587e57bc5ad7584027070..8d9b713edb554873a7758d464c188aef87ea5041 100644
--- a/src/app/components/load-calculator/load-calculator-anchor.directive.ts
+++ b/src/app/components/load-calculator/load-calculator-anchor.directive.ts
@@ -4,7 +4,7 @@ import { ViewContainerRef } from "@angular/core";
 import { LoadCalculatorComponent } from "./load-calculator.component";
 
 @Directive({
-    selector: "[loadCalcDialogAnchor]"
+    selector: "[appLoadCalcDialogAnchor]"
 })
 export class LoadCalcDialogAnchorDirective {
     constructor(
@@ -15,7 +15,8 @@ export class LoadCalcDialogAnchorDirective {
     public createDialog(): ComponentRef<LoadCalculatorComponent> {
         this.viewContainer.clear();
 
-        const compFactory: ComponentFactory<LoadCalculatorComponent> = this.componentFactoryResolver.resolveComponentFactory(LoadCalculatorComponent);
+        const compFactory: ComponentFactory<LoadCalculatorComponent>
+            = this.componentFactoryResolver.resolveComponentFactory(LoadCalculatorComponent);
         const compRef: ComponentRef<LoadCalculatorComponent> = this.viewContainer.createComponent(compFactory);
 
         // compRef.instance.confirmResult.subscribe(() => {
diff --git a/src/app/components/load-calculator/load-calculator.component.ts b/src/app/components/load-calculator/load-calculator.component.ts
index d008d92f9598b937231a84a3e77c0c819ebd5887..655d3baf237c65fd83cb55a0b718a97623ae2c94 100644
--- a/src/app/components/load-calculator/load-calculator.component.ts
+++ b/src/app/components/load-calculator/load-calculator.component.ts
@@ -90,13 +90,13 @@ export class LoadCalculatorComponent {
     }
 
     public get showSelectButtons(): boolean {
-        return this._calculators && this._calculators.length != 0;
+        return this._calculators && this._calculators.length !== 0;
     }
 
     private getSelectedFile(): File {
         const files: { [key: string]: File } = this.fileSelector.nativeElement.files;
         for (const key in files) {
-            if (!isNaN(parseInt(key))) {
+            if (!isNaN(Number(key))) {
                 return files[key];
             }
         }
@@ -131,7 +131,7 @@ export class LoadCalculatorComponent {
 
     private onCheckCalc(event: any) {
         for (const c of this._calculators) {
-            if (c.uid === +event.target.value) {
+            if (c.uid === event.target.value) {
                 c.selected = event.target.checked;
                 break;
             }
diff --git a/src/app/components/log-entry/log-entry.component.ts b/src/app/components/log-entry/log-entry.component.ts
index d7cfc0e93f9c0faae1161e0bfc36d5b823e3759c..3b53858779aff9a9eef7182fbe49a396640e6c46 100644
--- a/src/app/components/log-entry/log-entry.component.ts
+++ b/src/app/components/log-entry/log-entry.component.ts
@@ -19,7 +19,7 @@ import { ApplicationSetupService } from "../../services/app-setup/app-setup.serv
 
 })
 export class LogEntryComponent implements OnChanges {
-    @Input("message")
+    @Input()
     private _message: Message;
 
     /**
diff --git a/src/app/components/log/log.component.html b/src/app/components/log/log.component.html
index 2214487f0b43c7e61bed36fe34762b16f7feef6d..15d92c0f171cb2dff50912c2fd91978c5af3a986 100644
--- a/src/app/components/log/log.component.html
+++ b/src/app/components/log/log.component.html
@@ -6,7 +6,7 @@
 
             <!-- entrées du journal -->
             <ng-template ngFor let-m [ngForOf]="messages">
-                <log-entry [message]=m></log-entry>
+                <log-entry [_message]=m></log-entry>
             </ng-template>
         </div>
     </div>
diff --git a/src/app/components/log/log.component.ts b/src/app/components/log/log.component.ts
index b2dd3cde8dad3b0dc0eb7d871e3f66384261ce0c..67234e62f6a8bf6b9ec639660ac59bab4069c41b 100644
--- a/src/app/components/log/log.component.ts
+++ b/src/app/components/log/log.component.ts
@@ -43,7 +43,7 @@ export class LogComponent {
     }
 
     public get hasEntries(): boolean {
-        return this._log != undefined && this._log.messages.length != 0;
+        return this._log !== undefined && this._log.messages.length !== 0;
     }
 
     private get messages(): Message[] {
diff --git a/src/app/components/ngparam-input/ngparam-input.component.ts b/src/app/components/ngparam-input/ngparam-input.component.ts
index b02a87cf82547dfed1f32788c5fc8655269b60ff..44ba1ed15637c76ef47855b772446d73eecc82d6 100644
--- a/src/app/components/ngparam-input/ngparam-input.component.ts
+++ b/src/app/components/ngparam-input/ngparam-input.component.ts
@@ -2,7 +2,7 @@
 
 import { Component, ChangeDetectorRef, OnDestroy } from "@angular/core";
 
-import { NumericalString, Message, Observer } from "jalhyd";
+import { isNumeric, Message, Observer } from "jalhyd";
 
 import { InternationalisationService } from "../../services/internationalisation/internationalisation.service";
 import { NgParameter } from "../../formulaire/ngparam";
@@ -94,8 +94,7 @@ export class NgParamInputComponent extends GenericInputComponent implements Obse
         let valid = false;
         let msg: string;
 
-        const v: NumericalString = new NumericalString(ui);
-        if (!v.isNumerical) {
+        if (! isNumeric(ui)) {
             msg = "Veuillez entrer une valeur numérique";
         } else {
             valid = true;
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 b8d75ac73bb984f7d78bf4d3fcc86385752a4f13..41c5d1fead0e3e3405def7577ef33328870a42f3 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
@@ -1,7 +1,7 @@
 <div class="row">
     <!-- input de saisie de la valeur -->
     <div [ngClass]="(formHasResults) ? 'col-xl-6 pt-3':'col-md-6 col-xl-8 pt-3'">
-        <ngparam-input [inputDisabled]="isInputDisabled" [title]="title" (onChange)="onInputChange($event)"></ngparam-input>
+        <ngparam-input [_inputDisabled]="isInputDisabled" [title]="title" (change)="onInputChange($event)"></ngparam-input>
     </div>
 
     <div class="btn-group col" role="group">
diff --git a/src/app/components/param-field-line/param-field-line.component.ts b/src/app/components/param-field-line/param-field-line.component.ts
index 65263d2c0f29ca9c8d3fa63c427784b25dd2b1c9..6282e176e28510041610c853da5c6eedc24cb1f3 100644
--- a/src/app/components/param-field-line/param-field-line.component.ts
+++ b/src/app/components/param-field-line/param-field-line.component.ts
@@ -233,7 +233,7 @@ export class ParamFieldLineComponent implements OnChanges {
      */
 
     @Output()
-    private onRadio = new EventEmitter<any>();
+    private radio = new EventEmitter<any>();
 
     /**
      * classe du radio "fixé"
@@ -327,7 +327,7 @@ export class ParamFieldLineComponent implements OnChanges {
                 break;
         }
 
-        this.onRadio.emit({
+        this.radio.emit({
             "param": this.param,
             "oldValueMode": oldValue
         });
diff --git a/src/app/components/param-values/ngparam-max.component.ts b/src/app/components/param-values/ngparam-max.component.ts
index 8e4cc2c6c8536f90de25067e64250719434edfda..de13b6e24272dea9836d02097446c03b202ec1e0 100644
--- a/src/app/components/param-values/ngparam-max.component.ts
+++ b/src/app/components/param-values/ngparam-max.component.ts
@@ -1,6 +1,6 @@
 import { Component, Input, ChangeDetectorRef } from "@angular/core";
 
-import { NumericalString } from "jalhyd";
+import { isNumeric } from "jalhyd";
 
 import { GenericInputComponent } from "../generic-input/generic-input.component";
 import { InternationalisationService } from "../../services/internationalisation/internationalisation.service";
@@ -23,7 +23,7 @@ export class NgParamMaxComponent extends GenericInputComponent {
     }
 
     protected getModelValue(): any {
-        if (this._param == undefined) {
+        if (this._param === undefined) {
             return undefined;
         }
         return this._param.maxValue;
@@ -37,7 +37,7 @@ export class NgParamMaxComponent extends GenericInputComponent {
         let msg;
         let valid = false;
 
-        if (this._param == undefined) {
+        if (this._param === undefined) {
             msg = "internal error, model undefined";
         } else {
             if (!this._param.checkMax(v)) {
@@ -51,7 +51,7 @@ export class NgParamMaxComponent extends GenericInputComponent {
     }
 
     protected modelToUI(v: any): string {
-        if (typeof (v) == "number") {
+        if (typeof (v) === "number") {
             return String(v);
         }
         return undefined;
@@ -61,8 +61,7 @@ export class NgParamMaxComponent extends GenericInputComponent {
         let valid = false;
         let msg: string;
 
-        const v: NumericalString = new NumericalString(ui);
-        if (!v.isNumerical) {
+        if (! isNumeric(ui)) {
             msg = "Veuillez entrer une valeur numérique";
         } else {
             valid = true;
diff --git a/src/app/components/param-values/ngparam-min.component.ts b/src/app/components/param-values/ngparam-min.component.ts
index 5341e7330d42d3a0ac832cffd3abff1142f02327..89e119f03533bf517b83940c73f6db176b192270 100644
--- a/src/app/components/param-values/ngparam-min.component.ts
+++ b/src/app/components/param-values/ngparam-min.component.ts
@@ -1,6 +1,6 @@
 import { Component, Input, ChangeDetectorRef } from "@angular/core";
 
-import { NumericalString } from "jalhyd";
+import { isNumeric } from "jalhyd";
 
 import { GenericInputComponent } from "../generic-input/generic-input.component";
 import { InternationalisationService } from "../../services/internationalisation/internationalisation.service";
@@ -61,8 +61,7 @@ export class NgParamMinComponent extends GenericInputComponent {
         let valid = false;
         let msg: string;
 
-        const v: NumericalString = new NumericalString(ui);
-        if (!v.isNumerical) {
+        if (! isNumeric(ui)) {
             msg = "Veuillez entrer une valeur numérique";
         } else {
             valid = true;
diff --git a/src/app/components/param-values/ngparam-step.component.ts b/src/app/components/param-values/ngparam-step.component.ts
index 443eb1e8572b7a2b3f36afb8bbd4b93bd4b9ab60..bbddcebf2f27f0a2ac55e75d3957ebf292283e2e 100644
--- a/src/app/components/param-values/ngparam-step.component.ts
+++ b/src/app/components/param-values/ngparam-step.component.ts
@@ -1,6 +1,6 @@
 import { Component, Input, ChangeDetectorRef } from "@angular/core";
 
-import { NumericalString } from "jalhyd";
+import { isNumeric } from "jalhyd";
 
 import { GenericInputComponent } from "../generic-input/generic-input.component";
 import { InternationalisationService } from "../../services/internationalisation/internationalisation.service";
@@ -68,8 +68,7 @@ export class NgParamStepComponent extends GenericInputComponent {
         let valid = false;
         let msg: string;
 
-        const v: NumericalString = new NumericalString(ui);
-        if (!v.isNumerical) {
+        if (! isNumeric(ui)) {
             msg = "Veuillez entrer une valeur numérique";
         } else {
             valid = true;
diff --git a/src/app/components/param-values/param-values.component.ts b/src/app/components/param-values/param-values.component.ts
index 7a7431235642f026394cbd40c391622fab90f480..ef8c20a92bf590e6a63c3ad1d25c01ab051dd581 100644
--- a/src/app/components/param-values/param-values.component.ts
+++ b/src/app/components/param-values/param-values.component.ts
@@ -1,4 +1,4 @@
-import { Component, Input, Output, EventEmitter, ViewChild, AfterViewChecked } from "@angular/core";
+import { Component, Input, Output, EventEmitter, ViewChild, AfterViewChecked, OnChanges } from "@angular/core";
 
 import { ParamValueMode } from "jalhyd";
 
@@ -30,7 +30,7 @@ import { ValueListComponent } from "./value-list.component";
         }`
     ]
 })
-export class ParamValuesComponent extends BaseComponent implements AfterViewChecked {
+export class ParamValuesComponent extends BaseComponent implements AfterViewChecked, OnChanges {
     @Input()
     private param: NgParameter;
 
@@ -96,13 +96,13 @@ export class ParamValuesComponent extends BaseComponent implements AfterViewChec
     private _listComponent: ValueListComponent;
 
     @Output()
-    private onValid: EventEmitter<boolean>;
+    private valid: EventEmitter<boolean>;
 
     constructor(private intlService: InternationalisationService) {
         super();
         this._valueModes.push({ "value": ParamValueMode.MINMAX, "label": "Min/max" });
         this._valueModes.push({ "value": ParamValueMode.LISTE, "label": "Liste" });
-        this.onValid = new EventEmitter();
+        this.valid = new EventEmitter();
     }
 
     /**
@@ -114,13 +114,13 @@ export class ParamValuesComponent extends BaseComponent implements AfterViewChec
 
             // valeur pour min : celle déjà définie ou celle déduite de la valeur saisie
             let min: number = this.param.minValue;
-            if (min == undefined) {
+            if (min === undefined) {
                 min = this.param.getValue() / 2;
             }
 
             // valeur pour max : celle déjà définie ou celle déduite de la valeur saisie
             let max: number = this.param.maxValue;
-            if (max == undefined) {
+            if (max === undefined) {
                 max = this.param.getValue() * 2;
             }
 
@@ -132,7 +132,7 @@ export class ParamValuesComponent extends BaseComponent implements AfterViewChec
 
             // valeur du pas
             let step = this.param.stepValue;
-            if (step == undefined) {
+            if (step === undefined) {
                 step = (max - min) / 20;
             }
             this.param.stepValue = step;
@@ -153,10 +153,10 @@ export class ParamValuesComponent extends BaseComponent implements AfterViewChec
      * initialisation de la liste de valeurs avec celle du paramètre géré
      */
     private initList() {
-        if (this._doInitList && this._listComponent != undefined) {
+        if (this._doInitList && this._listComponent !== undefined) {
             this._doInitList = false;
             let l = this.param.valueList;
-            if (l == undefined) {
+            if (l === undefined) {
                 if (this.param.isDefined) {
                     l = [this.param.getValue()];
                 } else {
@@ -173,16 +173,16 @@ export class ParamValuesComponent extends BaseComponent implements AfterViewChec
      * revalidation de tous les composants enfants
      */
     private validateAll() {
-        if (this._minComponent != undefined) {
+        if (this._minComponent !== undefined) {
             this._minComponent.validate();
         }
-        if (this._maxComponent != undefined) {
+        if (this._maxComponent !== undefined) {
             this._maxComponent.validate();
         }
-        if (this._stepComponent != undefined) {
+        if (this._stepComponent !== undefined) {
             this._stepComponent.validate();
         }
-        if (this._listComponent != undefined) {
+        if (this._listComponent !== undefined) {
             this._listComponent.validate();
         }
     }
@@ -193,11 +193,11 @@ export class ParamValuesComponent extends BaseComponent implements AfterViewChec
     private emitValidity() {
         switch (this.param.valueMode) {
             case ParamValueMode.LISTE:
-                this.onValid.emit(this._validList);
+                this.valid.emit(this._validList);
                 break;
 
             case ParamValueMode.MINMAX:
-                this.onValid.emit(this._validMin && this._validMax && this._validStep);
+                this.valid.emit(this._validMin && this._validMax && this._validStep);
                 break;
         }
     }
diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts
index 290ae0548dcf768e0c49845303483651810f3d47..3d47a77084d5c90028e3fb5f7916593f843429ce 100644
--- a/src/app/components/remous-results/remous-results.component.ts
+++ b/src/app/components/remous-results/remous-results.component.ts
@@ -1,4 +1,4 @@
-import { Component, ViewChild } from "@angular/core";
+import { Component, ViewChild, DoCheck } from "@angular/core";
 
 import { ArrayReverseIterator, ResultElement, INumberIterator } from "jalhyd";
 
@@ -8,6 +8,183 @@ import { RemousResults } from "../../results/remous-results";
 import { CalculatorResults } from "../../results/calculator-results";
 import { VarResultsComponent } from "../fixedvar-results/var-results.component";
 
+/**
+ * données pour une ligne dans le graphe
+ */
+class LineData {
+    /**
+     * abscisses
+     */
+    private _tx: number[];
+
+    /**
+     * orodonnées
+     */
+    private _ty: number[] = [];
+
+    /**
+     * graphe auquel aapartient la ligne
+     */
+    private _parentGraph: GraphData;
+
+    /**
+     * données fournies à ChartJS
+     */
+    private _data = {};
+
+    /**
+     * profondeur à laquelle est dessinée la ligne
+     * les profondeurs les plus petites sont dessinées derrière les profondeurs les plus grandes
+     */
+    public z: number;
+
+    constructor(gr: GraphData) {
+        this._parentGraph = gr;
+        this._tx = gr.tx;
+        for (let i = this._tx.length - 1; i >= 0; i--) {
+            this._ty.push(null);
+        }
+    }
+
+    public getYat(x: number) {
+        const i = this._tx.indexOf(x);
+        return this._ty[i];
+    }
+
+    public setPoint(x: number, y: number) {
+        const i = this._tx.indexOf(x);
+        this._ty[i] = y;
+    }
+
+    public mapPoint(x: number, y: number) {
+        this.setPoint(x, this._parentGraph.mapY(x, y));
+    }
+
+    public get ty() {
+        return this._ty;
+    }
+
+    public get tx() {
+        return this._tx;
+    }
+
+    public hasYs(): boolean {
+        for (const y of this._ty) {
+            if (y !== null) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public get data() {
+        return this._data;
+    }
+
+    public set data(d: {}) {
+        this._data = d;
+        this._data["data"] = this._ty;
+    }
+}
+
+class GraphData {
+    /**
+     * tableau des (labels) des abscisses
+     */
+    private _tx: number[];
+
+    private _lines: LineData[] = [];
+
+    /**
+     * pente du fond
+    */
+    private _penteFond: number;
+
+    /**
+     * longueur du bief
+     */
+    private _longBief: number;
+
+    constructor(tX: number[], pente: number, bief: number) {
+        this._tx = tX;
+        this._penteFond = pente;
+        this._longBief = bief;
+    }
+
+    /**
+     * crée une ligne dans le graphe
+     * @param z profondeur de la lign
+     */
+    public newLine(z: number): LineData {
+        const res = new LineData(this);
+        res.z = z;
+        this._lines.push(res);
+        return res;
+    }
+
+    public get tx(): number[] {
+        return this._tx;
+    }
+
+    /**
+   * transforme une cote en tenant compte du fond
+   * @param x abscisse où se trouve la cote à transformer
+   * @param y cote à transformer
+   */
+    public mapY(x: number, y: number) {
+        let d: number;
+        if (this._penteFond >= 0) {
+            d = this._penteFond * (this._longBief - x);
+        } else {
+            d = -this._penteFond * x;
+        }
+        return y + d;
+    }
+
+    /**
+     * dessine une ligne droite
+     * @param y0 y en x=0
+     * @param ymax y en x=xmax
+     * @param color couleur de la ligne
+     * @param lbl légende de la ligne
+     * @param fillColor couleur de remplissage sous la ligne
+     */
+    public drawLine(y0: number, ymax: number, prof: number, color: string, lbl: string, fillColor?: string) {
+        const l = this.newLine(prof);
+        l.mapPoint(0, y0);
+        l.mapPoint(this._longBief, ymax);
+
+        // l.data = { label: lbl, data: l, fill: fillColor !== undefined, tension: 0,
+        // borderColor: color, backgroundColor: fillColor, pointRadius: 0 };
+        l.data = {
+            label: lbl, fill: fillColor !== undefined, tension: 0, spanGaps: true,
+            borderColor: color, backgroundColor: fillColor, pointRadius: 0
+        };
+    }
+
+    public get data() {
+        const ds = [];
+        this._lines.sort((a, b) => {
+            if (a.z > b.z) {
+                return -1;
+            }
+            if (a.z < b.z) {
+                return 1;
+            }
+            return 0;
+        });
+
+        for (const l of this._lines) {
+            ds.push(l.data);
+        }
+
+        return {
+            labels: this._tx,
+            datasets: ds
+        };
+    }
+}
+
 @Component({
     selector: "remous-results",
     templateUrl: "./remous-results.component.html",
@@ -32,7 +209,7 @@ import { VarResultsComponent } from "../fixedvar-results/var-results.component";
     `
     ]
 })
-export class RemousResultsComponent {
+export class RemousResultsComponent implements DoCheck {
     private _remousResults: RemousResults;
 
     /*
@@ -350,10 +527,24 @@ export class RemousResultsComponent {
         // ajout des données au graphique
 
         if (lineTor !== undefined) {
-            lineTor.data = { label: this.uitextLigneTorrentielle, tension: 0, borderColor: "#77A3CD", pointBackgroundColor: "#77A3CD", pointRadius: 4, backgroundColor: "#D1D0D4" };
+            lineTor.data = {
+                label: this.uitextLigneTorrentielle,
+                tension: 0,
+                borderColor: "#77A3CD",
+                pointBackgroundColor: "#77A3CD",
+                pointRadius: 4,
+                backgroundColor: "#D1D0D4"
+            };
         }
         if (lineFlu !== undefined) {
-            lineFlu.data = { label: this.uitextLigneFluviale, tension: 0, borderColor: "#0093BD", pointBackgroundColor: "#0093BD", pointRadius: 4, backgroundColor: "#D1D0D4" };
+            lineFlu.data = {
+                label: this.uitextLigneFluviale,
+                tension: 0,
+                borderColor: "#0093BD",
+                pointBackgroundColor: "#0093BD",
+                pointRadius: 4,
+                backgroundColor: "#D1D0D4"
+            };
         }
 
         this.graph1_data = gr1.data;
@@ -402,6 +593,7 @@ export class RemousResultsComponent {
     }
 
     private getResultClass(i: number) {
+        // tslint:disable-next-line:no-bitwise
         return "result_id_" + String(i & 1);
     }
 
@@ -413,179 +605,3 @@ export class RemousResultsComponent {
         return this._remousResults && this._remousResults.result && this._remousResults.result.ok;
     }
 }
-
-/**
- * données pour une ligne dans le graphe
- */
-class LineData {
-    /**
-     * abscisses
-     */
-    private _tx: number[];
-
-    /**
-     * orodonnées
-     */
-    private _ty: number[] = [];
-
-    /**
-     * graphe auquel aapartient la ligne
-     */
-    private _parentGraph: GraphData;
-
-    /**
-     * données fournies à ChartJS
-     */
-    private _data = {};
-
-    /**
-     * profondeur à laquelle est dessinée la ligne
-     * les profondeurs les plus petites sont dessinées derrière les profondeurs les plus grandes
-     */
-    public z: number;
-
-    constructor(gr: GraphData) {
-        this._parentGraph = gr;
-        this._tx = gr.tx;
-        for (let i = this._tx.length - 1; i >= 0; i--) {
-            this._ty.push(null);
-        }
-    }
-
-    public getYat(x: number) {
-        const i = this._tx.indexOf(x);
-        return this._ty[i];
-    }
-
-    public setPoint(x: number, y: number) {
-        const i = this._tx.indexOf(x);
-        this._ty[i] = y;
-    }
-
-    public mapPoint(x: number, y: number) {
-        this.setPoint(x, this._parentGraph.mapY(x, y));
-    }
-
-    public get ty() {
-        return this._ty;
-    }
-
-    public get tx() {
-        return this._tx;
-    }
-
-    public hasYs(): boolean {
-        for (const y of this._ty) {
-            if (y != null) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public get data() {
-        return this._data;
-    }
-
-    public set data(d: {}) {
-        this._data = d;
-        this._data["data"] = this._ty;
-    }
-}
-
-class GraphData {
-    /**
-     * tableau des (labels) des abscisses
-     */
-    private _tx: number[];
-
-    private _lines: LineData[] = [];
-
-    /**
-     * pente du fond
-    */
-    private _penteFond: number;
-
-    /**
-     * longueur du bief
-     */
-    private _longBief: number;
-
-    constructor(tX: number[], pente: number, bief: number) {
-        this._tx = tX;
-        this._penteFond = pente;
-        this._longBief = bief;
-    }
-
-    /**
-     * crée une ligne dans le graphe
-     * @param z profondeur de la lign
-     */
-    public newLine(z: number): LineData {
-        const res = new LineData(this);
-        res.z = z;
-        this._lines.push(res);
-        return res;
-    }
-
-    public get tx(): number[] {
-        return this._tx;
-    }
-
-    /**
-   * transforme une cote en tenant compte du fond
-   * @param x abscisse où se trouve la cote à transformer
-   * @param y cote à transformer
-   */
-    public mapY(x: number, y: number) {
-        let d: number;
-        if (this._penteFond >= 0) {
-            d = this._penteFond * (this._longBief - x);
-        } else {
-            d = -this._penteFond * x;
-        }
-        return y + d;
-    }
-
-    /**
-     * dessine une ligne droite
-     * @param y0 y en x=0
-     * @param ymax y en x=xmax
-     * @param color couleur de la ligne
-     * @param lbl légende de la ligne
-     * @param fillColor couleur de remplissage sous la ligne
-     */
-    public drawLine(y0: number, ymax: number, prof: number, color: string, lbl: string, fillColor: string = undefined) {
-        const l = this.newLine(prof);
-        l.mapPoint(0, y0);
-        l.mapPoint(this._longBief, ymax);
-
-        // l.data = { label: lbl, data: l, fill: fillColor != undefined, tension: 0, borderColor: color, backgroundColor: fillColor, pointRadius: 0 };
-        l.data = {
-            label: lbl, fill: fillColor !== undefined, tension: 0, spanGaps: true,
-            borderColor: color, backgroundColor: fillColor, pointRadius: 0
-        };
-    }
-
-    public get data() {
-        const ds = [];
-        this._lines.sort((a, b) => {
-            if (a.z > b.z) {
-                return -1;
-            }
-            if (a.z < b.z) {
-                return 1;
-            }
-            return 0;
-        });
-
-        for (const l of this._lines) {
-            ds.push(l.data);
-        }
-
-        return {
-            labels: this._tx,
-            datasets: ds
-        };
-    }
-}
diff --git a/src/app/components/result-element/horizontal-result-element.component.ts b/src/app/components/result-element/horizontal-result-element.component.ts
index 6404ab4ff488148dd5991f082456e0a6739d16ef..faa0174d6a02fb277d505d55fde34d25ec4846e1 100644
--- a/src/app/components/result-element/horizontal-result-element.component.ts
+++ b/src/app/components/result-element/horizontal-result-element.component.ts
@@ -1,9 +1,4 @@
 import { Component, Input, ViewChild, TemplateRef, ViewContainerRef } from "@angular/core";
-
-import { ResultElement } from "jalhyd";
-
-import { ApplicationSetupService } from "../../services/app-setup/app-setup.service";
-import { InternationalisationService } from "../../services/internationalisation/internationalisation.service";
 import { OnChanges } from "@angular/core/src/metadata/lifecycle_hooks";
 import { ResultElementBaseComponent } from "./result-element-base.component";
 
@@ -11,7 +6,7 @@ import { ResultElementBaseComponent } from "./result-element-base.component";
     selector: "[horizontal-result-element]",
     templateUrl: "./horizontal-result-element.component.html"
 })
-export class HorizontalResultElementComponent extends ResultElementBaseComponent {
+export class HorizontalResultElementComponent extends ResultElementBaseComponent implements OnChanges {
     // template des td pour les extraResult
     @ViewChild("extraResultTd") tdTemplate: TemplateRef<any>;
 
diff --git a/src/app/components/result-element/result-element-base.component.ts b/src/app/components/result-element/result-element-base.component.ts
index 519fd46650b81c4b5508c029a773f97c5b9add11..ac70e025720e4f16f956c0301103025967d9813e 100644
--- a/src/app/components/result-element/result-element-base.component.ts
+++ b/src/app/components/result-element/result-element-base.component.ts
@@ -73,15 +73,15 @@ export class ResultElementBaseComponent implements OnChanges {
 
         const nDigits = this.appSetupService.displayDigits;
         const r: ResultElement = this._resultElement;
-        this._hasValue = r != undefined && r.vCalc != undefined;
-        this._hasError = r == undefined || (r.vCalc == undefined && r.extraResults.length > 0);
+        this._hasValue = r !== undefined && r.vCalc !== undefined;
+        this._hasError = r === undefined || (r.vCalc === undefined && r.extraResults.length > 0);
         this._value = this._hasValue ? this._value = r.vCalc.toFixed(nDigits) : " ";
 
         // texte du tooltip
 
         let res = "";
 
-        if (this._resultElement != undefined) {
+        if (this._resultElement !== undefined) {
             for (const m of this._resultElement.log.messages) {
                 if (res.length > 0) {
                     res += "<br/>";
@@ -91,7 +91,7 @@ export class ResultElementBaseComponent implements OnChanges {
         }
 
         this._htmlTooltip = res;
-        this._emptyTooltip = this._htmlTooltip.length == 0;
+        this._emptyTooltip = this._htmlTooltip.length === 0;
     }
 
     public get hasValue() {
diff --git a/src/app/components/result-element/vertical-result-element.component.ts b/src/app/components/result-element/vertical-result-element.component.ts
index 91da588118cc0155f0eac6533baa3b5519161d47..8da84bab6b4f81e70a524568f8797f90f5f1cbfe 100644
--- a/src/app/components/result-element/vertical-result-element.component.ts
+++ b/src/app/components/result-element/vertical-result-element.component.ts
@@ -1,9 +1,4 @@
 import { Component, Input, ViewChild, TemplateRef, ViewContainerRef } from "@angular/core";
-
-import { ResultElement } from "jalhyd";
-
-import { ApplicationSetupService } from "../../services/app-setup/app-setup.service";
-import { InternationalisationService } from "../../services/internationalisation/internationalisation.service";
 import { OnChanges } from "@angular/core/src/metadata/lifecycle_hooks";
 import { ResultElementBaseComponent } from "./result-element-base.component";
 
@@ -25,11 +20,11 @@ import { ResultElementBaseComponent } from "./result-element-base.component";
         }`
     ]
 })
-export class VerticalResultElementComponent extends ResultElementBaseComponent {
+export class VerticalResultElementComponent extends ResultElementBaseComponent implements OnChanges {
     /**
      * nom de la variable
      */
-    @Input("label")
+    @Input()
     private _label: string;
 
     // template des tr pour les extraResult
diff --git a/src/app/components/save-calculator/save-calculator-anchor.directive.ts b/src/app/components/save-calculator/save-calculator-anchor.directive.ts
index 012ffef46f393f7a3e15713c2347f9c4bcab36b1..fa2d02f81584d9e9c2f5c32c6f0d3408f35bfa1e 100644
--- a/src/app/components/save-calculator/save-calculator-anchor.directive.ts
+++ b/src/app/components/save-calculator/save-calculator-anchor.directive.ts
@@ -4,7 +4,7 @@ import { ViewContainerRef } from "@angular/core";
 import { SaveCalculatorComponent } from "./save-calculator.component";
 
 @Directive({
-    selector: "[saveCalcDialogAnchor]"
+    selector: "[appSaveCalcDialogAnchor]"
 })
 export class SaveCalcDialogAnchorDirective {
     constructor(
@@ -15,7 +15,8 @@ export class SaveCalcDialogAnchorDirective {
     public createDialog(): ComponentRef<SaveCalculatorComponent> {
         this.viewContainer.clear();
 
-        const compFactory: ComponentFactory<SaveCalculatorComponent> = this.componentFactoryResolver.resolveComponentFactory(SaveCalculatorComponent);
+        const compFactory: ComponentFactory<SaveCalculatorComponent>
+            = this.componentFactoryResolver.resolveComponentFactory(SaveCalculatorComponent);
         const compRef: ComponentRef<SaveCalculatorComponent> = this.viewContainer.createComponent(compFactory);
 
         // dialogComponentRef.instance.close.subscribe(() => {
diff --git a/src/app/components/save-calculator/save-calculator.component.ts b/src/app/components/save-calculator/save-calculator.component.ts
index a8e3b3e1d7bbd7cffad73361f7f31f0b62221fe2..653e76c4bffce16c3a14360ffa357c5ac5987810 100644
--- a/src/app/components/save-calculator/save-calculator.component.ts
+++ b/src/app/components/save-calculator/save-calculator.component.ts
@@ -91,7 +91,7 @@ export class SaveCalculatorComponent {
 
     private onCheckCalc(event: any) {
         for (const c of this._calculators) {
-            if (c.uid == +event.target.value) {
+            if (c.uid === event.target.value) {
                 c.selected = event.target.checked;
             }
         }
diff --git a/src/app/components/section-results/section-results.component.ts b/src/app/components/section-results/section-results.component.ts
index 965475284c1650dad9fa96c238afa8dfa6fed642..ae3598d0fc1a560b047b9480d228f34caac61771 100644
--- a/src/app/components/section-results/section-results.component.ts
+++ b/src/app/components/section-results/section-results.component.ts
@@ -1,6 +1,6 @@
 import { Component, ViewChild, DoCheck } from "@angular/core";
 
-import { acSection, Result, ResultElement } from "jalhyd";
+import { ResultElement } from "jalhyd";
 
 import { SectionCanvasComponent } from "../section-canvas/section-canvas.component";
 import { SectionResults } from "../../results/section-results";
@@ -29,8 +29,7 @@ import { InternationalisationService } from "../../services/internationalisation
     .result_id_2 {
         font-weight: bold;
     }
-    `
-    ]
+    `]
 })
 export class SectionResultsComponent implements DoCheck {
 
@@ -135,6 +134,7 @@ export class SectionResultsComponent implements DoCheck {
     }
 
     private getResultClass(i: number) {
+        // tslint:disable-next-line:no-bitwise
         return "result_id_" + String(i & 1);
     }
 }
diff --git a/src/app/formulaire/check-field.ts b/src/app/formulaire/check-field.ts
index f508e699a1714362f7f21720c1431a943adcf734..073816613239ed3eea16a1b7d68aa8ba4b7b89d3 100644
--- a/src/app/formulaire/check-field.ts
+++ b/src/app/formulaire/check-field.ts
@@ -23,6 +23,6 @@ export class CheckField extends Field {
 
     public parseConfig(json: {}, data?: {}) {
         this._confId = json["id"];
-        this.setValue(json["value"] == "true");
+        this.setValue(json["value"] === "true");
     }
 }
diff --git a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
index 635c4029270d5a29c3ab02b08d535b6173add61c..b8f6b3543bb9423c8e80538257240822920a347b 100644
--- a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
+++ b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
@@ -64,7 +64,7 @@ export class FormulaireLechaptCalmon extends FormulaireDefinition implements Obs
     public update(sender: any, data: any) {
         // en cas de changement de valeur du select de matériau, effacement des résultats et MAJ des champs L,M,N
         if (sender instanceof SelectField) {
-            if (data.action == "select") {
+            if (data.action === "select") {
                 this.reset();
             }
         }
diff --git a/src/app/formulaire/definition/form-compute-courbe-remous.ts b/src/app/formulaire/definition/form-compute-courbe-remous.ts
index 6d996a2ab4af797a509ba2407534dc9d4f7f1080..e65553d0e21153774418e6bedb23ca0ef6e80b48 100644
--- a/src/app/formulaire/definition/form-compute-courbe-remous.ts
+++ b/src/app/formulaire/definition/form-compute-courbe-remous.ts
@@ -1,4 +1,4 @@
-import { SectionParametree, acSection, ParamsEquation, ComputeNode, Result, MethodeResolution, CourbeRemousParams, CourbeRemous, ResultElement, ParamValues, CalculatorType } from "jalhyd";
+import { acSection, Result, MethodeResolution, CourbeRemousParams, CourbeRemous } from "jalhyd";
 
 import { SelectField } from "../select-field";
 import { RemousResults } from "../../results/remous-results";
diff --git a/src/app/formulaire/definition/form-compute-parallel-structures.ts b/src/app/formulaire/definition/form-compute-parallel-structures.ts
index 1dd15b5c1906e241ae9e942f5192f1f05bebe676..f53ef23d8d62641495cafde08b99e4fe2fb8620d 100644
--- a/src/app/formulaire/definition/form-compute-parallel-structures.ts
+++ b/src/app/formulaire/definition/form-compute-parallel-structures.ts
@@ -47,7 +47,7 @@ export class FormComputeParallelStructures extends FormComputeFixedVar {
      */
     protected getParameterRefid(p: NgParameter) {
         const [fsc, fs, i] = this.structureParents(p);
-        if (i == -1) {
+        if (i === -1) {
             return super.getParameterRefid(p);
         }
 
@@ -56,7 +56,7 @@ export class FormComputeParallelStructures extends FormComputeFixedVar {
 
     protected setParameterValue(node: ComputeNode, p: NgParameter, val: number) {
         const [fsc, fs, i] = this.structureParents(p);
-        if (i == -1) {
+        if (i === -1) {
             super.setParameterValue(node, p, val);
         } else {
             const n: ParallelStructure = node as ParallelStructure;
diff --git a/src/app/formulaire/definition/form-def-fixedvar.ts b/src/app/formulaire/definition/form-def-fixedvar.ts
index a83d7839df702d5af50142136026fbfbf849c8fa..9e72537aad47170faa27b75b90e5a6df09bd57d5 100644
--- a/src/app/formulaire/definition/form-def-fixedvar.ts
+++ b/src/app/formulaire/definition/form-def-fixedvar.ts
@@ -2,9 +2,6 @@ import { ParamValueMode } from "jalhyd";
 
 import { ParamRadioConfig, NgParameter } from "../ngparam";
 import { FormulaireDefinition } from "./form-definition";
-import { FormulaireElement } from "../formulaire-element";
-import { InputField } from "../input-field";
-import { CheckField } from "../check-field";
 
 /**
  * gestion des formulaires avec "paramètre fixé" et "paramètre à varier"
@@ -19,10 +16,13 @@ export class FormDefFixedVar {
     /**
      * remet les radios de tous les paramètres à FIX sauf "me" et ceux (celui) à l'état "except"
      */
-    protected resetOtherRadio(me: NgParameter, except: ParamRadioConfig = undefined) {
+    protected resetOtherRadio(me: NgParameter, except?: ParamRadioConfig) {
         for (const p of this._formBase.allFormElements) {
             if (p instanceof NgParameter) {
-                if (p != me && p.radioState != except && p.radioState != ParamRadioConfig.LINK && p.radioConfig != ParamRadioConfig.FIX) {
+                if (p !== me && p.radioState !== except
+                    && p.radioState !== ParamRadioConfig.LINK
+                    && p.radioConfig !== ParamRadioConfig.FIX) {
+
                     p.valueMode = ParamValueMode.SINGLE;
                 }
             }
@@ -87,7 +87,7 @@ export class FormDefFixedVar {
                         } else {
                             const refParamValues = sourceParam.paramDefinition.referencedParamValues;
                             if (refParamValues !== undefined) { // cad si on référence un paramètre et non un Result par ex
-                                if (refParamValues.valueMode == ParamValueMode.LINK) {
+                                if (refParamValues.valueMode === ParamValueMode.LINK) {
                                     throw new Error(`références de paramètre en chaîne non pris en charge`);
                                 }
                             } // cas à traiter
@@ -138,12 +138,12 @@ export class FormDefFixedVar {
         this.processRadioStateChange(sourceParam, oldState);
 
         // on vérifie qu'il y a au moins un paramètre "à calculer" et sinon, on prend le 1er qui est à "fixé"
-        if (this._formBase.getDisplayedParamFromState(ParamRadioConfig.CAL) == undefined) {
+        if (this._formBase.getDisplayedParamFromState(ParamRadioConfig.CAL) === undefined) {
             let newCal: NgParameter;
 
             for (const p of this._formBase.allFormElements) {
                 if (p instanceof NgParameter) {
-                    if (p.radioConfig == ParamRadioConfig.CAL && p.radioState == ParamRadioConfig.FIX && p != sourceParam) {
+                    if (p.radioConfig === ParamRadioConfig.CAL && p.radioState === ParamRadioConfig.FIX && p !== sourceParam) {
                         newCal = p;
                         break;
                     }
diff --git a/src/app/formulaire/definition/form-def-paramcalc.ts b/src/app/formulaire/definition/form-def-paramcalc.ts
index e4820672183758da2297decdb44825f845bd73fc..b31c93a1489f3b2e13900640eeddc6e1071d806a 100644
--- a/src/app/formulaire/definition/form-def-paramcalc.ts
+++ b/src/app/formulaire/definition/form-def-paramcalc.ts
@@ -29,7 +29,7 @@ export class FormDefParamToCalculate extends FormDefFixedVar {
                 // id du paramètre à calculer par défaut
 
                 this._defaultCalculatedParam = o["idCal"];
-                if (this._defaultCalculatedParam != undefined) {
+                if (this._defaultCalculatedParam !== undefined) {
                     const p = this.setDefault();
                     p.isDefault = true;
                 }
@@ -41,7 +41,7 @@ export class FormDefParamToCalculate extends FormDefFixedVar {
      * met le paramètre par défaut à CAL sauf si c'est "except"
      * @param except paramètre à ne pas remettre à CAL
      */
-    private setDefault(except: NgParameter = undefined): NgParameter {
+    private setDefault(except?: NgParameter): NgParameter {
         const defaultParamCal: NgParameter = this._formBase.getParamFromSymbol(this._defaultCalculatedParam);
         if (except === undefined || defaultParamCal.uid !== except.uid) {
             defaultParamCal.valueMode = ParamValueMode.CALCUL;
diff --git a/src/app/formulaire/definition/form-def-section.ts b/src/app/formulaire/definition/form-def-section.ts
index 69fa4c92daa872d746a7245d409abd626a101bb3..734243db275a0149fe78bdf08219e4bd7df11932 100644
--- a/src/app/formulaire/definition/form-def-section.ts
+++ b/src/app/formulaire/definition/form-def-section.ts
@@ -27,7 +27,7 @@ export class FormDefSection {
     }
 
     private get hasSectionNodeTypeSource(): boolean {
-        return this._sectionSourceId != undefined;
+        return this._sectionSourceId !== undefined;
     }
 
     public getSectionVariatedParameter(): NgParameter {
diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index 0985db9573718d1191c0209954853ff407fce753..a8a00aaa62ccf32b5f1c5bd0fddf85c8805b0439 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -1,4 +1,4 @@
-import { CalculatorType, ComputeNodeType, Nub, ParamDefinition, Props, Observer } from "jalhyd";
+import { CalculatorType, ComputeNodeType, Nub, Props, Observer } from "jalhyd";
 
 import { FormulaireElement } from "../formulaire-element";
 import { NgParameter, ParamRadioConfig } from "../ngparam";
diff --git a/src/app/formulaire/definition/form-result-section.ts b/src/app/formulaire/definition/form-result-section.ts
index 0b828129e37bde7de751d534334dc6a844d63bcc..868b1de8e6f699338b0b7b766771d12324ea8e19 100644
--- a/src/app/formulaire/definition/form-result-section.ts
+++ b/src/app/formulaire/definition/form-result-section.ts
@@ -60,9 +60,9 @@ export class FormResultSection extends FormResult {
     }
 
     public get hasResults(): boolean {
-        return (this._fixedResults != undefined && this._fixedResults.hasResults)
-            || (this._varResults != undefined && this._varResults.hasResults)
-            || (this._sectionResults != undefined && this._sectionResults.hasResults);
+        return (this._fixedResults !== undefined && this._fixedResults.hasResults)
+            || (this._varResults !== undefined && this._varResults.hasResults)
+            || (this._sectionResults !== undefined && this._sectionResults.hasResults);
     }
 
     public get results(): CalculatorResults[] {
diff --git a/src/app/formulaire/dependency/dependency.ts b/src/app/formulaire/dependency/dependency.ts
index a7b8a4634e48fcfb248c8d471213a738a3b4e53e..368ac35a0078f35f65e8ea9b807484535e93223e 100644
--- a/src/app/formulaire/dependency/dependency.ts
+++ b/src/app/formulaire/dependency/dependency.ts
@@ -21,9 +21,9 @@ export abstract class Dependency {
 
     private getMasterElement(id: string): FormulaireElement {
         let parentNode = this._slave.parent;
-        while (parentNode != undefined) {
+        while (parentNode !== undefined) {
             const res: FormulaireElement = parentNode.getFormulaireNodeById(id) as FormulaireElement;
-            if (res != undefined) {
+            if (res !== undefined) {
                 return res;
             }
             parentNode = parentNode.parent;
diff --git a/src/app/formulaire/field.ts b/src/app/formulaire/field.ts
index d5f7c2df7f44ff88814ae3a882d6c62236df156b..c8d2f84b60290e67cbf9e3b570156758cb9a59ec 100644
--- a/src/app/formulaire/field.ts
+++ b/src/app/formulaire/field.ts
@@ -23,7 +23,7 @@ export abstract class Field extends FormulaireElement {
         super.parseDependencies(json);
 
         const dep = json["dep_value"];
-        if (dep != undefined) {
+        if (dep !== undefined) {
             this.parse_value_dependencies(dep);
         }
     }
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index f69701b00eaa7adb0dfed353ebd4197b70b68520..ed645c97bd70120813916c1d8e63e160e7d9b9bd 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -43,6 +43,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);
         if (update) {
             this.updateFields();
@@ -123,6 +124,9 @@ export class FieldSet extends FormulaireElement implements Observer {
         return this._jsonConfig;
     }
 
+    private setParentNubForAllFields() {
+    }
+
     /**
      * crée un input
      * @param json definition de l'input, extrait du fichier de conf de la calculette
@@ -158,6 +162,8 @@ export class FieldSet extends FormulaireElement implements Observer {
 
         if (res) {
             res.parseConfig(json, { "radioConfig": default_radio_config });
+            // set parent Nub on Parameter to ensure UID availability
+            res.paramDefinition.parent = this._nub;
         }
 
         return res;
diff --git a/src/app/formulaire/form-iterator/deep-element-iterator.ts b/src/app/formulaire/form-iterator/deep-element-iterator.ts
index a4a1aae30b0f7793ce161c01ac0c7bef915214be..8834c284738b5bc8011d30821f68012d6e851158 100644
--- a/src/app/formulaire/form-iterator/deep-element-iterator.ts
+++ b/src/app/formulaire/form-iterator/deep-element-iterator.ts
@@ -5,8 +5,11 @@ import { FormulaireElement } from "../formulaire-element";
  * itérateur qui extrait récursivement les FormulaireElement dans un tableau de FormulaireElement
  * (qui peut contenir des FieldsetContainer)
  */
-export class DeepFormulaireElementIterator extends AbstractFormulaireNodeIterator<FormulaireElement> implements IterableIterator<FormulaireElement> {
-    // interface IterableIterator
+export class DeepFormulaireElementIterator
+    extends AbstractFormulaireNodeIterator<FormulaireElement>
+    implements IterableIterator<FormulaireElement> {
+
+        // interface IterableIterator
 
     [Symbol.iterator](): IterableIterator<FormulaireElement> {
         return this;
diff --git a/src/app/formulaire/form-iterator/top-element-iterator.ts b/src/app/formulaire/form-iterator/top-element-iterator.ts
index 1b1f35dc67707e0b49512f258775962a4f98dd93..32f9e63e96e217f2fd5cd571b1917b3da5e77330 100644
--- a/src/app/formulaire/form-iterator/top-element-iterator.ts
+++ b/src/app/formulaire/form-iterator/top-element-iterator.ts
@@ -5,7 +5,10 @@ import { FormulaireElement } from "../formulaire-element";
  * itérateur qui extrait les FormulaireElement de 1er niveau dans un tableau de FormulaireElement
  * (qui peut contenir des FieldsetContainer)
  */
-export class TopFormulaireElementIterator extends AbstractFormulaireNodeIterator<FormulaireElement> implements IterableIterator<FormulaireElement> {
+export class TopFormulaireElementIterator
+    extends AbstractFormulaireNodeIterator<FormulaireElement>
+    implements IterableIterator<FormulaireElement> {
+
     protected isDeepIterator(): boolean {
         return false;
     }
diff --git a/src/app/formulaire/formulaire-node.ts b/src/app/formulaire/formulaire-node.ts
index 8d84e222d67e486335bc91ee8afb6152d608b96a..44245795e47a5a381c6f6382603a7d392ff6f5ac 100644
--- a/src/app/formulaire/formulaire-node.ts
+++ b/src/app/formulaire/formulaire-node.ts
@@ -12,7 +12,7 @@ export abstract class FormulaireNode implements IObservable {
     /**
     * id numérique unique
     */
-    private _uid: number;
+    private _uid: string;
 
     /**
      * parent direct
@@ -77,8 +77,8 @@ export abstract class FormulaireNode implements IObservable {
     /**
      * cherche un FormulaireNode par son id numérique unique
      */
-    public getFormulaireNodeByUid(uid: number): FormulaireNode {
-        if (this.uid == uid) {
+    public getFormulaireNodeByUid(uid: string): FormulaireNode {
+        if (this.uid === uid) {
             return this;
         }
 
@@ -100,7 +100,7 @@ export abstract class FormulaireNode implements IObservable {
     private kidIndex(kid: FormulaireNode): number {
         let n = 0;
         for (const k of this._kids) {
-            if (k._uid == kid._uid) {
+            if (k._uid === kid._uid) {
                 return n;
             }
             n++;
diff --git a/src/app/results/param-calc-results.ts b/src/app/results/param-calc-results.ts
index 3c768a3da21161250948f828e647320dffee43c7..5a3d6adecb6b00a17a7870c49198cbe012ff321c 100644
--- a/src/app/results/param-calc-results.ts
+++ b/src/app/results/param-calc-results.ts
@@ -54,20 +54,20 @@ export abstract class CalculatedParamResults extends CalculatorResults {
     }
 
     public get hasResults(): boolean {
-        if (this._result == undefined) {
+        if (this._result === undefined) {
             return false;
         }
         return this._result.ok;
     }
 
     public get hasLog(): boolean {
-        if (this._result == undefined) {
+        if (this._result === undefined) {
             return false;
         }
         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/remous-results.ts b/src/app/results/remous-results.ts
index fdcdadd6971f3d225ff45881ccb3285a20ef1b45..23c2eeb133de914ed704bb86f22e94c0fc0b2153 100644
--- a/src/app/results/remous-results.ts
+++ b/src/app/results/remous-results.ts
@@ -97,7 +97,7 @@ export class RemousResults extends CalculatorResults {
         const Dx = p.map.Dx.v;
 
         // série de valeurs de X
-        this._xValues = new ParamDefinition("Abscisse", ParamDomainValue.POS_NULL);
+        this._xValues = new ParamDefinition(p, "Abscisse", ParamDomainValue.POS_NULL);
         this._xValues.paramValues.setValues(0, Long, Dx);
     }
 
@@ -138,7 +138,8 @@ export class RemousResults extends CalculatorResults {
 
         this._varResults = new VarResults();
         this._varResults.variatedParameter = new NgParameter(this._xValues, undefined);
-        this._varResults.calculatedParameter = new NgParameter(new ParamDefinition("Ligne d'eau", ParamDomainValue.POS_NULL), undefined);
+        this._varResults.calculatedParameter
+            = new NgParameter(new ParamDefinition(null, "Ligne d'eau", ParamDomainValue.POS_NULL), undefined);
         this._varResults.result = this._result;
         const keys = [];
         if (this._hasFlu) {
@@ -199,10 +200,10 @@ export class RemousResults extends CalculatorResults {
     }
 
     public get hasResults(): boolean {
-        return this._hautBerge != undefined ||
-            this._penteFond != undefined ||
-            this._hautNormale != undefined ||
-            this._hautCritique != undefined ||
+        return this._hautBerge !== undefined ||
+            this._penteFond !== undefined ||
+            this._hautNormale !== undefined ||
+            this._hautCritique !== undefined ||
             (this._result && this._result.ok);
     }
 
diff --git a/src/app/results/section-results.ts b/src/app/results/section-results.ts
index 8e3d3b88db248950581e9897ad0c6b4f4e9a33ba..ee05b29435cdac3b9d928d6dd58a4770f52a3fa3 100644
--- a/src/app/results/section-results.ts
+++ b/src/app/results/section-results.ts
@@ -35,6 +35,6 @@ export class SectionResults extends CalculatorResults {
     }
 
     public get hasResults(): boolean {
-        return this._section != undefined && this._result != undefined;
+        return this._section !== undefined && this._result !== undefined;
     }
 }
diff --git a/src/app/services/formulaire/formulaire.service.ts b/src/app/services/formulaire/formulaire.service.ts
index 3fbec68f3b0a400e1edce4c870ba0d959934aca6..e5d27da4b176eb978a80a8340b852d1faf4a7272 100644
--- a/src/app/services/formulaire/formulaire.service.ts
+++ b/src/app/services/formulaire/formulaire.service.ts
@@ -29,7 +29,7 @@ import { NgParameter } from "../../formulaire/ngparam";
 export class FormulaireService extends Observable {
     private _formulaires: FormulaireDefinition[];
 
-    private _currentFormId = -1;
+    private _currentFormId: string = null;
 
     constructor() {
         super();
@@ -62,7 +62,7 @@ export class FormulaireService extends Observable {
      * @param formId id unique du formulaire
      * @param localisation ensemble id-message traduit
      */
-    private updateFormulaireLocalisation(formId: number, localisation: StringMap) {
+    private updateFormulaireLocalisation(formId: string, localisation: StringMap) {
         for (const f of this._formulaires) {
             if (f.uid === formId) {
                 f.updateLocalisation(localisation);
@@ -197,7 +197,7 @@ export class FormulaireService extends Observable {
         });
     }
 
-    public getFormulaireFromId(uid: number): FormulaireDefinition {
+    public getFormulaireFromId(uid: string): FormulaireDefinition {
         for (const f of this._formulaires) {
             if (f.uid === uid) {
                 return f;
@@ -207,7 +207,7 @@ export class FormulaireService extends Observable {
         return undefined;
     }
 
-    public getInputField(formId: number, elemId: string): InputField {
+    public getInputField(formId: string, elemId: string): InputField {
         const s = this.getFormulaireElementById(formId, elemId);
         if (!(s instanceof InputField)) {
             throw new Error("Form element with id '" + elemId + "' is not an input");
@@ -215,7 +215,7 @@ export class FormulaireService extends Observable {
         return <InputField>s;
     }
 
-    public getCheckField(formId: number, elemId: string): CheckField {
+    public getCheckField(formId: string, elemId: string): CheckField {
         const s = this.getFormulaireElementById(formId, elemId);
         if (!(s instanceof CheckField)) {
             throw new Error("Form element with id '" + elemId + "' is not a checkbox");
@@ -223,7 +223,7 @@ export class FormulaireService extends Observable {
         return <CheckField>s;
     }
 
-    public getSelectField(formId: number, elemId: string): SelectField {
+    public getSelectField(formId: string, elemId: string): SelectField {
         const s = this.getFormulaireElementById(formId, elemId);
         if (!(s instanceof SelectField)) {
             throw new Error("Form element with id '" + elemId + "' is not a select");
@@ -231,7 +231,7 @@ export class FormulaireService extends Observable {
         return <SelectField>s;
     }
 
-    private getFormulaireElementById(formId: number, elemId: string): FormulaireElement {
+    private getFormulaireElementById(formId: string, elemId: string): FormulaireElement {
         for (const f of this._formulaires) {
             if (f.uid === formId) {
                 const s = f.getFormulaireNodeById(elemId);
@@ -300,7 +300,7 @@ export class FormulaireService extends Observable {
         }
     }
 
-    public requestCloseForm(uid: number) {
+    public requestCloseForm(uid: string) {
         const form = this.getFormulaireFromId(uid);
         if (form !== undefined) {
             this._formulaires = this._formulaires.filter(f => f.uid !== uid);
@@ -316,10 +316,10 @@ export class FormulaireService extends Observable {
         return this._currentFormId;
     }
 
-    public setCurrentForm(formId: number) {
+    public setCurrentForm(formId: string) {
         const form = this.getFormulaireFromId(formId);
         if (form === undefined) {
-            this._currentFormId = -1;
+            this._currentFormId = null;
             this.notifyObservers({
                 "action": "invalidFormId",
                 "formId": formId
@@ -493,7 +493,6 @@ export class FormulaireService extends Observable {
 
                     // 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
                     const ps = sn.getLinkableValues(p.paramDefinition, undefined, exclude);
                     for (const npp of ps) {
diff --git a/src/app/services/param/param.service.ts b/src/app/services/param/param.service.ts
index 6e5362f391f07f5c3e99f459234c852ecebec92a..7f3ef4039a349d0262f1b77a944c5d906dea55e6 100644
--- a/src/app/services/param/param.service.ts
+++ b/src/app/services/param/param.service.ts
@@ -19,7 +19,7 @@ export class ParamService {
 
     private createAccuracyParameter(): ParamDefinition {
         const d = new ParamDomain(ParamDomainValue.INTERVAL, 1e-10, 100);
-        const p = new ParamDefinition("Pr", d, this._appSetupService.computePrecision);
+        const p = new ParamDefinition(null, "Pr", d, this._appSetupService.computePrecision);
         p.calculability = ParamCalculability.FREE;
         return p;
     }
@@ -37,7 +37,7 @@ export class ParamService {
             p.confId = "Pr";
         } else {
             const dom = new ParamDomain(ParamDomainValue.POS_NULL);
-            p = new NgParameter(new ParamDefinition(symbol, dom), parent);
+            p = new NgParameter(new ParamDefinition(null, symbol, dom), parent);
             p.confId = symbol;
 
             switch (symbol) {
diff --git a/src/app/services/service-factory.ts b/src/app/services/service-factory.ts
index f40bf9a5ce449e8326ea39237b133b4f5f8db343..682cc5c087028c83d8fa68fe58282fe8e783ab5e 100644
--- a/src/app/services/service-factory.ts
+++ b/src/app/services/service-factory.ts
@@ -20,7 +20,7 @@ export class ServiceFactory {
     public httpService: HttpService;
 
     public static get instance() {
-        if (ServiceFactory._instance == undefined) {
+        if (ServiceFactory._instance === undefined) {
             ServiceFactory._instance = new ServiceFactory();
         }
         return ServiceFactory._instance;
diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json
index b862dd8f92970d03e14ddf86b94c7c83a70c1639..754e065bf0ea54b2ac3eaedd841311a5bfd794a3 100644
--- a/src/locale/messages.en.json
+++ b/src/locale/messages.en.json
@@ -73,6 +73,8 @@
     "INFO_LIB_FS_PARAM_CALC": "Calculation parameters",
     "INFO_LIB_PR": "Display accuracy",
     "INFO_LIB_SELECT_LOIDEBIT": "Stage-discharge law",
+    "INFO_MENU_HELP_TITLE": "Help",
+    "INFO_MENU_LOAD_SESSION_TITLE": "Load session",
     "INFO_MENU_NOUVELLE_CALC": "New calculator",
     "INFO_OPTION_NO": "No",
     "INFO_OPTION_YES": "Yes",
diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json
index 9b6d70effa35e37cb2ff25124840c06ff66080c5..6dfeaa6a039ce6020eeb68d249d702ada50aa83f 100644
--- a/src/locale/messages.fr.json
+++ b/src/locale/messages.fr.json
@@ -88,6 +88,8 @@
     "INFO_LIB_BETA": "Coefficient béta",
     "INFO_LIB_ZRAM": "Cote du radier amont (m)",
     "INFO_LIB_ZT": "Cote haute du triangle (m)",
+    "INFO_MENU_HELP_TITLE": "Aide",
+    "INFO_MENU_LOAD_SESSION_TITLE": "Charger une session",
     "INFO_MENU_NOUVELLE_CALC": "Nouveau module de calcul",
     "INFO_OPTION_NO": "Non",
     "INFO_OPTION_YES": "Oui",
diff --git a/src/polyfills.ts b/src/polyfills.ts
index 7457894847c541a5a4de4c0364fbe65e38e6e8d1..a5d20e2715c4442f0c83530a3cf352b11dc8b832 100644
--- a/src/polyfills.ts
+++ b/src/polyfills.ts
@@ -74,3 +74,7 @@ import "zone.js/dist/zone";  // Included with Angular CLI.
  * Need to import at least one locale-data with intl.
  */
 // import 'intl/locale-data/jsonp/en';
+
+// Requis pour Buffer dans jalhyd (!?)
+(window as any).global = window;
+global.Buffer = global.Buffer || require("buffer").Buffer;
diff --git a/src/tsconfig.app.json b/src/tsconfig.app.json
index 39ba8dbacbbe051fdd02481b07af43219296a075..f0875f9b20c527390d3dc1cd926d0d2ab1f64e26 100644
--- a/src/tsconfig.app.json
+++ b/src/tsconfig.app.json
@@ -4,7 +4,8 @@
     "outDir": "../out-tsc/app",
     "baseUrl": "./",
     "module": "es2015",
-    "types": []
+    "types": [ "node" ],
+    "typeRoots": [ "../node_modules/@types" ]
   },
   "exclude": [
     "test.ts",
diff --git a/src/tsconfig.spec.json b/src/tsconfig.spec.json
index 23f020ba87f9e47b22d77e17db37bff95925646a..1a18e6d00cd89eb585ab635d861756f3aab09aa7 100644
--- a/src/tsconfig.spec.json
+++ b/src/tsconfig.spec.json
@@ -4,8 +4,6 @@
     "outDir": "../out-tsc/spec",
     "baseUrl": "./",
     "module": "commonjs",
-    "target": "es5",
-    "downlevelIteration": true,
     "types": [
       "jasmine",
       "node"
diff --git a/tslint.json b/tslint.json
index 8c60d4106c014263230eb4cb1aecc754aaed53fd..2da8f2207693ae54a9e19f6099608681c4eba647 100644
--- a/tslint.json
+++ b/tslint.json
@@ -103,7 +103,6 @@
         "variable-declaration": "nospace"
       }
     ],
-    "typeof-compare": true,
     "unified-signatures": true,
     "variable-name": false,
     "whitespace": [