diff --git a/bower.json b/bower.json
index 8992e37e4dee6397a721bc038e2cbce5ceaced11..498c7e07368e8d2d6a741b959171c81338922bb6 100644
--- a/bower.json
+++ b/bower.json
@@ -14,7 +14,8 @@
     "angular": "1.5.3",
     "angular-bind-notifier": "^1.1.7",
     "angular-image-crop": "^2.0.0",
-    "ng-idle": "^1.3.2"
+    "ng-idle": "^1.3.2",
+    "chart.js": "chartjs#^2.6.0"
   },
   "resolutions": {
     "angular-sanitize": "1.5.3",
diff --git a/doc/fr/development_tutorial-02.md b/doc/fr/development_tutorial-02.md
index 1af9e3ca2e69cc6bbf6248f337c69fadcca7c884..596b7e60d3e907eab1fc2b8cd4e5d72d463bf847 100644
--- a/doc/fr/development_tutorial-02.md
+++ b/doc/fr/development_tutorial-02.md
@@ -18,7 +18,7 @@ Pour mettre en place votre environnement de développement, suivez le [1er tutor
 
 ## Niveau VI : Afficher un paramètre monétaire manquant
 
-__Objectif :__ Dans ce niveau, l'objectif est d'afficher dans la page [`Monnaie`](http://cesium.duniter.fr/#/app/currency/view/lg/) le paramètre monétaire `stepMax`.
+__Objectif :__ Dans ce niveau, l'objectif est d'afficher dans la page [`Monnaie`](http://g1.duniter.fr/#/app/currency/view/lg/) le paramètre monétaire `stepMax`.
 
 > Pour rappel, `stepMax` est la distance maximale entre un membre et un postulant, pour que ce dernier puisse rentrer dans la toile de confiance.
 
diff --git a/doc/fr/development_tutorial-04.md b/doc/fr/development_tutorial-04.md
index b83cb085e9368aef505ec4423a0e59e92f8d1664..dad2751631c8a764166944ba3b5a70c60c3c5e7e 100644
--- a/doc/fr/development_tutorial-04.md
+++ b/doc/fr/development_tutorial-04.md
@@ -15,36 +15,35 @@ Avant de faire ce tutoriel, vous devez :
 
 L'objectif ici est de réaliser un graphique représentant l'évolution de montant du dividende universel.
 
-Quand l'utilisateur cliquera sur le champ "dividende universel" de la page suivante : http://cesium.duniter.fr/#/app/currency/view/lg/  
+Quand l'utilisateur cliquera sur le champ "dividende universel" de la page suivante : http://g1.duniter.fr/#/app/currency/view/lg/  
 
 ### Récupérer le code (tag rml8)
 
 Passez sur la branche du code #rml8  : https://github.com/duniter/cesium/tree/rml8
 
-### Démarrer Cesium
 
-Lancer Cesium : 
+### Ajout de librairie dans Cesium
 
-```bash
-cd cesium
-ionic serve
-```
-### Démarrer le noeud ElasticSearch 
+#### librairie Chart.js
 
-Démarrer votre noeud ES :  
+[Chart.js](chartjs.org) est une librairie JS qui permet de faire de magnifiques graphiques.
 
-```bash
-cd duniter4j
-mvn install -DskipTests
-mvn install -Prun -pl duniter4j-elasticsearch 
+Vérifier que cette librairie est installé dans Cesium, en ouvrant la page principale de l'application  `www/index.html` et en repérant la ligne :
+```html
+<script src="js/vendor/Chart.js"></script>
+```
+
+Si ce n'est pas le cas, ajouté là avec la commande :
+```
+bower install chartjs --save
 ```
 
-### Ajout de la librairie D3.js
+Puis ajouter la librairie dans `www/index.html`.  
 
-D3.js est une puissante librairie JS qui permet de faire de magnifiques graphiques.
+#### librairie Angular Chart
 
-Vous pouvez utiliser `bower` pour installer la dépendance.
-Puis ajouter la librairie dans la page principale de l'application : `www/index.html` 
+[Angular Chart](https://jtblin.github.io/angular-chart.js/) est une librairie qui intègre pleinement `Chart.js` dans Angular JS, utilisé par Cesium.
+Cela permet de définir plus facilement un graphique. 
 
 ### Gestion du controlleur 
 
@@ -59,14 +58,35 @@ Editez le fichier `www/js/controllers/currency-charts-controllers.js`.
 
 A vous de jouer ! Il faut : 
 
-- Remplir la requete POST vers le noeud ES sur l'index `/test_net/block/_search`; cf méthode `$scope.loadUds()';
+- Remplir la requete POST vers le noeud ES sur l'index `/g1/block/_search`; cf méthode `$scope.loadUds()';
 - Traiter le retour de la requête, pour la transformer dans le format attendu par D3.js.
 
 ### Template
 
-Editez le template HTML, dans le fichier `www/templates/currency/charts/ud.html`
+Editez le template HTML.
+
+Regardez la documentation Chart.js pour savoir comment faire la suite !
+
+### Testez !
+
+#### Démarrer le noeud ElasticSearch 
 
-Regardez la documentation D3.js pour savoir comment faire la suite !
+Démarrer votre noeud ES :  
+
+```bash
+cd duniter4j
+mvn install -DskipTests
+mvn install -Prun -pl duniter4j-es-assembly 
+```
+
+#### Démarrer Cesium
+
+Lancer Cesium : 
+
+```bash
+cd cesium
+ionic serve
+```
 
 ## La suite ?
 
diff --git a/doc/fr/development_tutorial-05.md b/doc/fr/development_tutorial-05.md
new file mode 100644
index 0000000000000000000000000000000000000000..182b15364a9b26872e9cc8a53d01bf4e73b93e3d
--- /dev/null
+++ b/doc/fr/development_tutorial-05.md
@@ -0,0 +1,72 @@
+## Introduction
+
+Cet article est un tutoriel pour développer un plugin Cesium.
+
+## Prérequis
+
+Avant de faire ce tutoriel, vous devez : 
+ 
+ - Avoir suivi les tutoriels sur Cesium [jusqu'au niveau VII](./development_tutorial-02.md)
+
+## Niveau XIII
+
+### Objectif
+
+L'objectif ici est d'inésrer des fonctionnalités à Cesium, en exploitant le mécanisme de plugin.
+Dans la page `Mes opérations`, nous allons ajouter un bouton pour télécharger l'historique des opérations du compte. 
+
+### Récupérer le code (tag rml9)
+
+Passez sur la branche du code #rml9  : https://github.com/duniter/cesium/tree/rml9
+
+
+### Activation du plugin 
+
+Editer le fichier `www/index.html`, et décommenter LES DEUX lignes : 
+```html
+   (...)
+   <link href="dist/dist_css/plugins/graph/css/style.css" rel="stylesheet">
+   (...)
+   <script src="dist/dist_js/plugins/rml9/plugin.js"></script>
+   (...)
+```
+
+Editer le fichier `www/js/plugins.js`, et décommenter la ligne : 
+```json
+   (...)
+   ,'cesium.rml9.plugin'
+   (...)
+```
+
+Editer le fichier `www/js/config.js`, et ajouter ces lignes : 
+```json
+   (...)
+   "plugins": {
+   		(...)
+   		 // --- DEBUT des lignes à ajouter
+       "rml9": {   
+         "enable": true
+       }
+       // --- FIN des lignes à ajouter
+       (...)
+   	},
+```
+
+Le plugin RML9 est maintenan activer. Il ne reste plus qu'à lancer Cesium pour vérifier :
+```bash
+ionic serve
+```
+
+### Développement du plugin 
+
+Dans le fichier  `www/plugins/rml9/plugins.js`, identifier la méthode `onButtonClick`. 
+
+
+
+
+## La suite ?
+
+Il ne vous reste qu'à publier le résultat ! ;) 
+
+- sur le forum duniter,
+- ou mieux via un `pull request` sur github.
\ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
index 6f08d841149ecc200ae0e2da0e24008ac66e33ca..cbc1d7314936a558c70903cbcb90cd4fb48ea116 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -43,7 +43,7 @@ var paths = {
   // plugins:
   templatecache_plugin: ['./www/plugins/*/templates/**/*.html'],
   ng_translate_plugin: ['./www/plugins/*/i18n/locale-*.json'],
-  ng_annotate_plugin: ['./www/plugins/*/js/**/*.js', '!./www/plugins/*/js/vendor/*.js'],
+  ng_annotate_plugin: ['./www/plugins/*/**/*.js', '!./www/plugins/*/js/vendor/*.js'],
   css_plugin: ['./www/plugins/*/css/**/*.css']
 };
 
@@ -188,7 +188,6 @@ gulp.task('templatecache_plugin', function (done) {
       root: "plugins/"
      }))
     .pipe(gulp.dest('./www/dist/dist_js/plugins'))
-    //.pipe(gulp.dest('./www/plugins'))
     .on('end', done);
 });
 
@@ -203,7 +202,6 @@ gulp.task('ng_translate_plugin', function() {
   return gulp.src(paths.ng_translate_plugin)
     .pipe(ngTranslate({standalone:true, module: 'cesium.plugins.translations'}))
     .pipe(gulp.dest('www/dist/dist_js/plugins'));
-    //.pipe(gulp.dest('www/plugins'));
 });
 
 gulp.task('css_plugin', function (done) {
diff --git a/www/i18n/locale-en-GB.json b/www/i18n/locale-en-GB.json
index ade6d11f79abc88ecb6a39c9d5ada890dcfd308d..f4a7da74cd12da0b8ce36eb0a356e5f9dcbb33a5 100644
--- a/www/i18n/locale-en-GB.json
+++ b/www/i18n/locale-en-GB.json
@@ -31,6 +31,7 @@
     "BTN_ADD": "Add",
     "BTN_SEARCH": "Search",
     "BTN_REFRESH": "Refresh",
+    "BTN_START": "Start",
     "BTN_CONTINUE": "Continue",
     "BTN_UNDERSTOOD": "I understood",
     "BTN_OPTIONS": "Options",
@@ -197,17 +198,13 @@
     }
   },
   "CURRENCY": {
-    "SELECT": {
-      "TITLE": "Currencies",
-      "CURRENCIES": "Known currencies",
-      "MEMBERS_COUNT": "{{membersCount}} members"
-    },
     "VIEW": {
       "TITLE": "Currency",
       "TAB_CURRENCY": "Currency",
       "TAB_WOT": "Web of trust",
       "TAB_NETWORK": "Network",
       "TAB_BLOCKS": "Blocks",
+      "CURRENCY_SHORT_DESCRIPTION": "{{currency|capitalize}} is a <b>libre money</b>, started {{firstBlockTime | formatFromNow}}. It currently counts <b>{{N}} members </b>, who produce and collect a <a ng-click=\"showHelpModal('ud')\">Universal Dividend</a> (DU), each {{dt | formatPeriod}}.",
       "NETWORK_RULES_DIVIDER": "Network rules",
       "CURRENCY_NAME": "Currency name",
       "MEMBERS": "Members count",
@@ -253,7 +250,7 @@
     "VIEW": {
       "MEDIAN_TIME": "Blockchain time",
       "LOADING_PEERS": "Loading peers...",
-      "NODE_ADDRESS": "Node address",
+      "NODE_ADDRESS": "Peer address",
       "ENDPOINTS": {
         "BMAS": "Secure endpoint (SSL)",
         "BMATOR": "TOR endpoint",
@@ -278,7 +275,7 @@
     "POPOVER_FILTER_TITLE": "Filter",
     "OFFLINE": "Offline peers",
     "VIEW": {
-      "TITLE": "Node",
+      "TITLE": "Peer",
       "OWNER": "Owned by ",
       "SHOW_RAW_PEERING": "See peering document",
       "KNOWN_PEERS": "Known peers :",
@@ -405,8 +402,13 @@
     },
     "NEW": {
       "TITLE": "Registration",
-      "SLIDE_1_TITLE": "Select a currency:",
-      "SLIDE_2_TITLE": "Kind of account:",
+      "INTRO_WARNING_TIME": "Creating an account on {{name|capitalize}} is very simple. Please take sufficient time to do this correctly (not to forget the usernames, passwords, etc.).",
+      "INTRO_WARNING_SECURITY": "Check that the hardware you are currently using (computer, tablet, phone) <b>is secure and trustworthy </b>.",
+      "INTRO_WARNING_SECURITY_HELP": "Up-to-date anti-virus, firewall enabled, session protected by password or pin code...",
+      "INTRO_HELP": "Click <b> {{'COMMON.BTN_START'|translate}}</b> to begin creating an account. You will be guided step by step.",
+      "REGISTRATION_NODE": "Your registration will be registered via the Duniter peer <b>{{server}}</b> node, which will then be distributed to the rest of the currency network.",
+      "REGISTRATION_NODE_HELP": "If you do not trust this peer, please change <a ng-click=\"doQuickFix('settings')\">in the settings</a> of Cesium.",
+      "SELECT_ACCOUNT_TYPE": "Choose the type of account to create:",
       "MEMBER_ACCOUNT": "Member account",
       "MEMBER_ACCOUNT_HELP": "If you are not yet registered as an individual (one account possible per individual).",
       "WALLET_ACCOUNT": "Simple wallet",
@@ -425,8 +427,9 @@
       "LAST_SLIDE_CONGRATULATION": "You completed all required fields.<br/><b>You can send the account creation request</b>.<br/><br/>For information, the public key below identifies your future account.<br/>It can be communicated to third parties to receive their payment.<br/>Once your account has been approved, you can find this key under <b>{{'ACCOUNT.TITLE'|translate}}</b>.",
       "CONFIRMATION_MEMBER_ACCOUNT": "<b class=\"assertive\">Warning:</b> your secret identifier, password and pseudonym can not be changed.<br/><b>Make sure you always remember it!</b><br/><b>Are you sure</b> you want to send this account creation request?",
       "CONFIRMATION_WALLET_ACCOUNT": "<b class=\"assertive\">Warning:</b> your password and pseudonym can not be changed.<br/><b>Make sure you always remember it!</b><br/><b>Are you sure</b> you want to continue?",
-      "PSEUDO_AVAILABLE": "This nickname is available",
-      "PSEUDO_NOT_AVAILABLE": "This nickname is not available",
+      "CHECKING_PSEUDO": "Checking...",
+      "PSEUDO_AVAILABLE": "This pseudonym is available",
+      "PSEUDO_NOT_AVAILABLE": "This pseudonym is not available",
       "INFO_LICENSE": "To be able to adhere to the currency, we ask you to kindly read and accept this license.",
       "BTN_ACCEPT": "I accept",
       "BTN_ACCEPT_LICENSE": "I accept the license"
@@ -596,7 +599,7 @@
     "FIX_IDENTITY": "The pseudonym <b>{{uid}}</b> will be published again, replacing the old publication that has expired.<br/></br/><b>Are you sure</b> you want to continue?",
     "FIX_MEMBERSHIP": "Your application for membership will be sent.<br/></br/><b>Are you sure?</b>",
     "RENEW_MEMBERSHIP": "Your membership will be renewed.<br/></br/><b>Are you sure?</b>",
-    "REVOKE_IDENTITY": "You will <b>definitely revoke this identity</b>.<br/><br/>The public key and the associated nickname <b>will never be used again</b> (for a member account).<br/></br/><b>Are you sure</b> you want to revoke this identity?",
+    "REVOKE_IDENTITY": "You will <b>definitely revoke this identity</b>.<br/><br/>The public key and the associated pseudonym <b>will never be used again</b> (for a member account).<br/></br/><b>Are you sure</b> you want to revoke this identity?",
     "REVOKE_IDENTITY_2": "This operation is <b>irreversible</b>!<br/><br/>Are you sure you want to <b>revoke this identity</b>?",
     "NOT_NEED_RENEW_MEMBERSHIP": "Your membership does not need to be renewed (it will only expire in {{membershipExpiresIn|formatDuration}}).<br/></br/><b>Are you sure you</b> want to renew your membership?",
     "SAVE_BEFORE_LEAVE": "Do you want to <b>save your changes</b> before leaving the page?",
diff --git a/www/i18n/locale-en.json b/www/i18n/locale-en.json
index 813d4ffdb503906d5051017ab9d4db51ebd7b1dc..979d581f5c724b9e2f6d0d8bc1c4e26aa21690fe 100644
--- a/www/i18n/locale-en.json
+++ b/www/i18n/locale-en.json
@@ -31,6 +31,7 @@
     "BTN_ADD": "Add",
     "BTN_SEARCH": "Search",
     "BTN_REFRESH": "Refresh",
+    "BTN_START": "Start",
     "BTN_CONTINUE": "Continue",
     "BTN_UNDERSTOOD": "I understood",
     "BTN_OPTIONS": "Options",
@@ -197,17 +198,13 @@
     }
   },
   "CURRENCY": {
-    "SELECT": {
-      "TITLE": "Currencies",
-      "CURRENCIES": "Known currencies",
-      "MEMBERS_COUNT": "{{membersCount}} members"
-    },
     "VIEW": {
       "TITLE": "Currency",
       "TAB_CURRENCY": "Currency",
       "TAB_WOT": "Web of trust",
       "TAB_NETWORK": "Network",
       "TAB_BLOCKS": "Blocks",
+      "CURRENCY_SHORT_DESCRIPTION": "{{currency|capitalize}} is a <b>libre money</b>, started {{firstBlockTime | formatFromNow}}. It currently counts <b>{{N}} members </b>, who produce and collect a <a ng-click=\"showHelpModal('ud')\">Universal Dividend</a> (DU), each {{dt | formatPeriod}}.",
       "NETWORK_RULES_DIVIDER": "Network rules",
       "CURRENCY_NAME": "Currency name",
       "MEMBERS": "Members count",
@@ -253,7 +250,7 @@
     "VIEW": {
       "MEDIAN_TIME": "Blockchain time",
       "LOADING_PEERS": "Loading peers...",
-      "NODE_ADDRESS": "Node address",
+      "NODE_ADDRESS": "Peer address",
       "ENDPOINTS": {
         "BMAS": "Secure endpoint (SSL)",
         "BMATOR": "TOR endpoint",
@@ -278,7 +275,7 @@
     "POPOVER_FILTER_TITLE": "Filter",
     "OFFLINE": "Offline peers",
     "VIEW": {
-      "TITLE": "Node",
+      "TITLE": "Peer",
       "OWNER": "Owned by ",
       "SHOW_RAW_PEERING": "See peering document",
       "KNOWN_PEERS": "Known peers :",
@@ -405,8 +402,13 @@
     },
     "NEW": {
       "TITLE": "Registration",
-      "SLIDE_1_TITLE": "Select a currency:",
-      "SLIDE_2_TITLE": "Kind of account:",
+      "INTRO_WARNING_TIME": "Creating an account on {{name|capitalize}} is very simple. Please take sufficient time to do this correctly (not to forget the usernames, passwords, etc.).",
+      "INTRO_WARNING_SECURITY": "Check that the hardware you are currently using (computer, tablet, phone) <b>is secure and trustworthy </b>.",
+      "INTRO_WARNING_SECURITY_HELP": "Up-to-date anti-virus, firewall enabled, session protected by password or pin code...",
+      "INTRO_HELP": "Click <b> {{'COMMON.BTN_START'|translate}}</b> to begin creating an account. You will be guided step by step.",
+      "REGISTRATION_NODE": "Your registration will be registered via the Duniter peer <b>{{server}}</b> node, which will then be distributed to the rest of the currency network.",
+      "REGISTRATION_NODE_HELP": "If you do not trust this peer, please change <a ng-click=\"doQuickFix('settings')\">in the settings</a> of Cesium.",
+      "SELECT_ACCOUNT_TYPE": "Choose the type of account to create:",
       "MEMBER_ACCOUNT": "Member account",
       "MEMBER_ACCOUNT_HELP": "If you are not yet registered as an individual (one account possible per individual).",
       "WALLET_ACCOUNT": "Simple wallet",
@@ -425,8 +427,9 @@
       "LAST_SLIDE_CONGRATULATION": "You completed all required fields.<br/><b>You can send the account creation request</b>.<br/><br/>For information, the public key below identifies your future account.<br/>It can be communicated to third parties to receive their payment.<br/>Once your account has been approved, you can find this key under <b>{{'ACCOUNT.TITLE'|translate}}</b>.",
       "CONFIRMATION_MEMBER_ACCOUNT": "<b class=\"assertive\">Warning:</b> your secret identifier, password and pseudonym can not be changed.<br/><b>Make sure you always remember it!</b><br/><b>Are you sure</b> you want to send this account creation request?",
       "CONFIRMATION_WALLET_ACCOUNT": "<b class=\"assertive\">Warning:</b> your password and pseudonym can not be changed.<br/><b>Make sure you always remember it!</b><br/><b>Are you sure</b> you want to continue?",
-      "PSEUDO_AVAILABLE": "This nickname is available",
-      "PSEUDO_NOT_AVAILABLE": "This nickname is not available",
+      "CHECKING_PSEUDO": "Checking...",
+      "PSEUDO_AVAILABLE": "This pseudonym is available",
+      "PSEUDO_NOT_AVAILABLE": "This pseudonym is not available",
       "INFO_LICENSE": "To be able to adhere to the currency, we ask you to kindly read and accept this license.",
       "BTN_ACCEPT": "I accept",
       "BTN_ACCEPT_LICENSE": "I accept the license"
@@ -596,7 +599,7 @@
     "FIX_IDENTITY": "The pseudonym <b>{{uid}}</b> will be published again, replacing the old publication that has expired.<br/></br/><b>Are you sure</b> you want to continue?",
     "FIX_MEMBERSHIP": "Your application for membership will be sent.<br/></br/><b>Are you sure?</b>",
     "RENEW_MEMBERSHIP": "Your membership will be renewed.<br/></br/><b>Are you sure?</b>",
-    "REVOKE_IDENTITY": "You will <b>definitely revoke this identity</b>.<br/><br/>The public key and the associated nickname <b>will never be used again</b> (for a member account).<br/></br/><b>Are you sure</b> you want to revoke this identity?",
+    "REVOKE_IDENTITY": "You will <b>definitely revoke this identity</b>.<br/><br/>The public key and the associated pseudonym <b>will never be used again</b> (for a member account).<br/></br/><b>Are you sure</b> you want to revoke this identity?",
     "REVOKE_IDENTITY_2": "This operation is <b>irreversible</b>!<br/><br/>Are you sure you want to <b>revoke this identity</b>?",
     "NOT_NEED_RENEW_MEMBERSHIP": "Your membership does not need to be renewed (it will only expire in {{membershipExpiresIn|formatDuration}}).<br/></br/><b>Are you sure you</b> want to renew your membership?",
     "SAVE_BEFORE_LEAVE": "Do you want to <b>save your changes</b> before leaving the page?",
diff --git a/www/i18n/locale-es-ES.json b/www/i18n/locale-es-ES.json
index a29e26658140c4614d37582e5d970489a9a0dbde..29f30038ca200b50733242faae067282c2e10868 100644
--- a/www/i18n/locale-es-ES.json
+++ b/www/i18n/locale-es-ES.json
@@ -31,6 +31,7 @@
     "BTN_ADD": "Añadir",
     "BTN_SEARCH": "Buscar",
     "BTN_REFRESH": "Actualisar",
+    "BTN_START": "Empezar",
     "BTN_CONTINUE": "Continuar",
     "BTN_UNDERSTOOD": "He entendido",
     "BTN_OPTIONS": "Opciónes",
@@ -108,11 +109,12 @@
     "MESSAGE_SHORT": "Sigue sus cuentas <a href=\"http://duniter.org\" target=\"_blank\">Duniter</a><br/>en tiempo real !",
     "BTN_REGISTRY": "Anuario",
     "BTN_MARKET": "Ofertas/demandas",
-    "BTN_CURRENCIES": "Explorar las monedas",
     "BTN_CURRENCY": "Explorar la moneda",
     "BTN_ABOUT": "A propósito",
     "BTN_HELP": "Ayuda en línea",
-    "REPORT_ISSUE": "anomalía"
+    "REPORT_ISSUE": "anomalía",
+    "NOT_YOUR_ACCOUNT_QUESTION" : "Usted no es dueño de la cuenta <<b><i class=\"ion-key\"></i> {{pubkey|formatPubkey}}</b>?",
+    "BTN_CHANGE_ACCOUNT": "Desconectar esta cuenta"
   },
   "SETTINGS": {
     "TITLE": "Configuraciónes",
@@ -195,17 +197,13 @@
     }
   },
   "CURRENCY": {
-    "SELECT": {
-      "TITLE": "Monedas",
-      "CURRENCIES": "Monedas conocidas",
-      "MEMBERS_COUNT": "{{membersCount}} miembros"
-    },
     "VIEW": {
       "TITLE": "Moneda",
       "TAB_CURRENCY": "Moneda",
       "TAB_WOT": "Red de confianza",
       "TAB_NETWORK": "Red",
       "TAB_BLOCKS": "Bloques",
+      "CURRENCY_SHORT_DESCRIPTION": "{{currency|capitalizar}} es un <b>moneda libre</b>, iniciado {{firstBlockTime|formatFromNow}}. Ella actualmente <b>{{N}} miembros</b>, que producen y recibir un <a ng-click=\"showHelpModal('ud')\">Dividendo universal</a> (DU), cada {{dt|formatPeriod}}.",
       "NETWORK_RULES_DIVIDER": "Reglas de la red",
       "CURRENCY_NAME": "Nombre de la moneda",
       "MEMBERS": "Número de miembros",
@@ -403,8 +401,13 @@
     },
     "NEW": {
       "TITLE": "Inscripción",
-      "SLIDE_1_TITLE": "Elección de la moneda :",
-      "SLIDE_2_TITLE": "Tipo de cuenta :",
+      "INTRO_WARNING_TIME": "Crear una cuenta en {{name|capitalize}} es muy simple. Sin embargo, por favor tome el tiempo suficiente para tomar correctamente este paso (no olvidar los identificadores, contraseñas, etc.).",
+      "INTRO_WARNING_SECURITY": "Asegúrate de que el equipo que se utiliza actualmente (ordenador, tableta, teléfono) <b>es seguro y digno de confianza</b>.",
+      "INTRO_WARNING_SECURITY_HELP": "Actualizaciones de antivirus, firewall activado, sesión protegidos por contraseña o código PIN, etc.",
+      "INTRO_HELP": "Haga clic en <b>{{'COMMON.BTN_START'|translate}}</b> para iniciar la creación de la cuenta. Se le guiará paso a paso.",
+      "REGISTRATION_NODE": "Su registro será grabado a través del nodo Duniter <b>{{server}}</b>, que luego se transmitió al resto del sistema de moneda.",
+      "REGISTRATION_NODE_HELP": "Si usted no confía en este nodo, <a ng-click=\"doQuickFix('settings')\">cambie la configuración</a> de Cesium.",
+      "SELECT_ACCOUNT_TYPE": "Elegir el tipo de cuenta para crear:",
       "MEMBER_ACCOUNT": "Cuenta miembro",
       "MEMBER_ACCOUNT_HELP": "Si ya no está inscrito como un individuo (Solamente una cuenta posible por individuo).",
       "WALLET_ACCOUNT": "Simple monedero",
@@ -423,6 +426,7 @@
       "LAST_SLIDE_CONGRATULATION": "<b>Bravo !</b> Ha introducido todas las informaciónes necesarias.<br/><b>Puede mandar la solicitud</b> de creación de su cuenta.</b><br/><br/>Por su información, la llave pública más abajo identificará su cuenta futura.<br/>Podrá estar comunicada a terceros para recibir sus pagos.<br/>Sin embargo, <b>no es útil</b> anotarla aquí.",
       "CONFIRMATION_MEMBER_ACCOUNT": "<b class=\"assertive\">Advertencia :</b> el identificador secreto, la contraseña y el seudónimo no podrán estar modificados.<br/><b>Asegurase siempre se los recordar !</b><br/><br/><b>Está usted seguro</b> querer mandar esta solicitud de inscripción ?",
       "CONFIRMATION_WALLET_ACCOUNT": "<b class=\"assertive\">Advertencia :</b> el identificador secreto y la contraseña no podrán estar modificados.<br/><b>Asegurase siempre se los recordar !</b><br/><br/><b>Está usted seguro</b> querer continuar con estos identificadores ?",
+      "CHECKING_PSEUDO": "Comprobación de disponibilidad...",
       "PSEUDO_AVAILABLE": "Este nombre está disponible",
       "PSEUDO_NOT_AVAILABLE": "Este nombre de usuario no está disponible",
       "INFO_LICENSE": "Para unirse a la moneda, le pedimos que leer y aceptar esta licencia.",
diff --git a/www/i18n/locale-fr-FR.json b/www/i18n/locale-fr-FR.json
index 4cb3046c6b2ff2767aef38e7e8a2363ddff1cd11..74ffce440435caba87bf5ad8a48cb526c5ae213f 100644
--- a/www/i18n/locale-fr-FR.json
+++ b/www/i18n/locale-fr-FR.json
@@ -31,6 +31,7 @@
     "BTN_ADD": "Ajouter",
     "BTN_SEARCH": "Rechercher",
     "BTN_REFRESH": "Actualiser",
+    "BTN_START": "Commencer",
     "BTN_CONTINUE": "Continuer",
     "BTN_UNDERSTOOD": "J'ai compris",
     "BTN_OPTIONS": "Options",
@@ -104,12 +105,11 @@
   },
   "HOME": {
     "TITLE": "Cesium",
-    "MESSAGE": "Bienvenue dans l'application Cesium !<br/>Suivez vos comptes <a href=\"http://duniter.org\" target=\"_blank\">Duniter</a> en temps réel.",
-    "MESSAGE_SHORT": "Suivez vos comptes <a href=\"http://duniter.org\" target=\"_blank\">Duniter</a><br/>en temps réel !",
+    "MESSAGE": "Bienvenue dans l'application Cesium !<br/>Suivez vos comptes en monnaie libre <a href=\"http://duniter.org\" target=\"_blank\">Duniter</a>.",
+    "MESSAGE_SHORT": "Suivez vos comptes en monnaie libre <a href=\"http://duniter.org\" target=\"_blank\">Duniter</a> !",
     "BTN_REGISTRY": "Annuaire",
     "BTN_MARKET": "Offres/demandes",
-    "BTN_CURRENCIES": "Explorer les monnaies",
-    "BTN_CURRENCY": "Explorer la monnaie",
+    "BTN_CURRENCY": "Explorer la monnaie {{name|abbreviate}}",
     "BTN_ABOUT": "à propos",
     "BTN_HELP": "Aide en ligne",
     "REPORT_ISSUE": "anomalie",
@@ -197,17 +197,13 @@
     }
   },
   "CURRENCY": {
-    "SELECT": {
-      "TITLE": "Monnaies",
-      "CURRENCIES": "Monnaies connues",
-      "MEMBERS_COUNT": "{{membersCount}} membres"
-    },
     "VIEW": {
       "TITLE": "Monnaie",
       "TAB_CURRENCY": "Monnaie",
       "TAB_WOT": "Toile de confiance",
       "TAB_NETWORK": "Réseau",
       "TAB_BLOCKS": "Blocs",
+      "CURRENCY_SHORT_DESCRIPTION": "{{currency|abbreviate}} est une <b>monnaie libre</b>, démarrée {{firstBlockTime|formatFromNow}}. Elle compte actuellement <b>{{N}} membres</b>, qui produisent et perçoivent un <a ng-click=\"showHelpModal('ud')\">Dividende Universel</a> (DU), chaque {{dt|formatPeriod}}.",
       "NETWORK_RULES_DIVIDER": "Règles du réseau",
       "CURRENCY_NAME": "Nom de la monnaie",
       "MEMBERS": "Nombre de membres",
@@ -405,15 +401,20 @@
     },
     "NEW": {
       "TITLE": "Inscription",
-      "SLIDE_1_TITLE": "Choix de la monnaie :",
-      "SLIDE_2_TITLE": "Type de compte :",
+      "INTRO_WARNING_TIME": "La création d'un compte sur {{name|capitalize}} est très simple. Veuillez néanmoins prendre suffisament de temps pour faire correctement cette formalité (pour ne pas oublier les identifiants, mots de passe, etc.).",
+      "INTRO_WARNING_SECURITY": "Vérifier que le matériel que vous utilisez actuellement (ordinateur, tablette, téléphone) <b>est sécurisé et digne de confiance</b>.",
+      "INTRO_WARNING_SECURITY_HELP": "Anti-virus à jour, pare-feu activé, session protégée par mot de passe ou code pin, etc.",
+      "INTRO_HELP": "Cliquez sur <b>{{'COMMON.BTN_START'|translate}}</b> pour débuter la création de compte. Vous serez guidé étape par étape.",
+      "REGISTRATION_NODE": "Votre inscription sera enregistrée via le noeud Duniter <b>{{server}}</b>, qui le diffusera ensuite au reste du réseau de la monnaie.",
+      "REGISTRATION_NODE_HELP": "Si vous ne faites pas confiance en ce noeud, veuillez en changer <a ng-click=\"doQuickFix('settings')\">dans les paramètres</a> de Cesium.",
+      "SELECT_ACCOUNT_TYPE": "Choisissez le type de compte à créer :",
       "MEMBER_ACCOUNT": "Compte membre",
-      "MEMBER_ACCOUNT_HELP": "Si vous n'etes pas encore inscrit en tant qu'individu (Un seul compte possible par individu).",
+      "MEMBER_ACCOUNT_HELP": "Si vous n'êtes pas encore inscrit en tant qu'individu (un seul compte possible par individu). Ce compte permet de co-produire la monnaie, en recevant un <b>dividende universel</b> chaque {{parameters.dt|formatPeriod}}.",
       "WALLET_ACCOUNT": "Simple portefeuille",
       "WALLET_ACCOUNT_HELP": "Pour tous les autres cas, par exemple si vous avez besoin d'un compte supplémentaire.<br/>Aucun dividende universel ne sera créé par ce compte.",
       "SALT_WARNING": "Choisissez votre identifiant secret.<br/>Il vous sera demandé à chaque connexion sur ce compte.<br/><br/><b>Retenez le bien</b>.<br/>En cas de perte, plus personne ne pourra accéder à votre compte !",
       "PASSWORD_WARNING": "Choisissez un mot de passe.<br/>Il vous sera demandé à chaque connexion sur ce compte.<br/><br/><b>Retenez bien ce mot de passe</b>.<br/>En cas de perte, plus personne ne pourra accéder à votre compte !",
-      "PSEUDO_WARNING": "Choisissez un pseudonyme.<br/>Il sert aux autres membres, pour vous identifier plus facilement.<br/><br/>Il ne doit contenir <b>ni espace, ni de caractère accentué</b>.<div class='hidden-xs'><br/>Exemple : <span class='gray'>SophieDupond, MarcelChemin, etc.</span>",
+      "PSEUDO_WARNING": "Choisissez un pseudonyme.<br/>Il sert aux autres membres, pour vous identifier plus facilement.<div class='hidden-xs'><br/>Il <b>ne pourra pas être modifié</b>, sans refaire un compte.</div><br/><br/>Il ne doit contenir <b>ni espace, ni de caractère accentué</b>.<div class='hidden-xs'><br/>Exemple : <span class='gray'>SophieDupond, MarcelChemin, etc.</span>",
       "PSEUDO": "Pseudonyme",
       "PSEUDO_HELP": "Pseudonyme",
       "SALT_CONFIRM": "Confirmation",
@@ -425,6 +426,7 @@
       "LAST_SLIDE_CONGRATULATION": "<b>Bravo !</b> Vous avez saisi toutes les informations nécessaires.<br/><b>Vous pouvez envoyer la demande</b> de création de compte.</b><br/><br/>Pour information, la clé publique ci-dessous identifiera votre futur compte.<br/>Elle pourra être communiquée à des tiers pour recevoir leur paiement.<br/>Cependant, <b>il n'est pas utile</b> de la noter ici.",
       "CONFIRMATION_MEMBER_ACCOUNT": "<b class=\"assertive\">Avertissement :</b> l'identifiant secret, le mot de passe et le pseudonyme ne pourront plus être modifiés.<br/><br/><b>Assurez-vous de toujours vous en rappeller !</b><br/><br/><b>Etes-vous sûr</b> de vouloir envoyer cette demande d'inscription ?",
       "CONFIRMATION_WALLET_ACCOUNT": "<b class=\"assertive\">Avertissement :</b> l'identifiant secret et le mot de passe ne pourront plus être modifiés.<br/><br/><b>Assurez-vous de toujours vous en rappeller !</b><br/><br/><b>Etes-vous sûr</b> de vouloir continuer avec ces identifiants ?",
+      "CHECKING_PSEUDO": "Vérification...",
       "PSEUDO_AVAILABLE": "Pseudonyme disponible",
       "PSEUDO_NOT_AVAILABLE": "Pseudonyme non disponible",
       "INFO_LICENSE": "Avant de créer un compte membre, <b>veuillez lire et accepter la licence</b> d'usage de la monnaie :",
diff --git a/www/index.html b/www/index.html
index 4596ffbcc4c5f10ed0223ad7c33e6d6a6febaf1b..e3a2e99adf110124eb14b0fa31bd6f0f76e87a44 100644
--- a/www/index.html
+++ b/www/index.html
@@ -19,6 +19,7 @@
 
   <!--removeIf(no-plugin)-->
   <link href="dist/dist_css/plugins/es/css/style.css" rel="stylesheet">
+  <link href="dist/dist_css/plugins/graph/css/style.css" rel="stylesheet">
   <!--endRemoveIf(no-plugin)-->
   <!-- endbuild -->
   <!-- build:js dist_js/vendor.js -->
@@ -159,9 +160,15 @@
   <script src="dist/dist_js/plugins/graph/js/plugin.js"></script>
   <script src="dist/dist_js/plugins/graph/js/services.js"></script>
   <script src="dist/dist_js/plugins/graph/js/services/data-services.js"></script>
+  <script src="dist/dist_js/plugins/graph/js/services/color-services.js"></script>
+  <script src="dist/dist_js/plugins/graph/js/controllers/common-controllers.js"></script>
   <script src="dist/dist_js/plugins/graph/js/controllers/blockchain-controllers.js"></script>
   <script src="dist/dist_js/plugins/graph/js/controllers/network-controllers.js"></script>
   <script src="dist/dist_js/plugins/graph/js/controllers/currency-controllers.js"></script>
+  <script src="dist/dist_js/plugins/graph/js/controllers/account-controllers.js"></script>
+
+  <!-- RML9 plugin -->
+  <script src="dist/dist_js/plugins/rml9/plugin.js"></script>
 
   <!--endRemoveIf(no-plugin)-->
 
diff --git a/www/js/app.js b/www/js/app.js
index 9ec6877c9b55cd96747e8160da5e78c945fd37e9..56616c9b87f89ae6d8d88807b2f4368c3e5712b7 100644
--- a/www/js/app.js
+++ b/www/js/app.js
@@ -225,21 +225,32 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht
   })
 
   .filter('abbreviate', function() {
+    var _cache = {};
     return function(input) {
       var currency = input || '';
+      if (_cache[currency]) return _cache[currency];
       if (currency.length > 3) {
         var unit = '', sepChars = ['-', '_', ' '];
         for (var i = 0; i < currency.length; i++) {
           var c = currency[i];
-          if (i === 0 || (i > 0 && sepChars.indexOf(currency[i-1]) != -1)) {
+          if (i === 0) {
+            unit = (c === 'g' || c === 'G') ? 'Äž' : c ;
+          }
+          else if (i > 0 && sepChars.indexOf(currency[i-1]) != -1) {
             unit += c;
           }
         }
-        return unit.toUpperCase();
+        currency = unit.toUpperCase();
       }
       else {
-        return currency.toUpperCase();
+        currency = currency.toUpperCase();
+        if (currency.charAt(0) === 'G') {
+          currency = 'Äž' + (currency.length > 1 ? currency.substr(1) : '');
+        }
       }
+
+      _cache[input] = currency;
+      return currency;
     };
   })
 
@@ -364,11 +375,12 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht
     IdleProvider.timeout(csConfig.logoutTimeout||15); // display warning during 15s
   })
 
-.run(function($rootScope, $translate, $state, $window, ionicReady, Device, UIUtils, $ionicConfig, PluginService, csWallet, csSettings, csConfig) {
+.run(function($rootScope, $translate, $state, $window, ionicReady, Device, UIUtils, $ionicConfig, PluginService, csWallet, csSettings, csConfig, csCurrency) {
   'ngInject';
 
   $rootScope.config = csConfig;
   $rootScope.settings = csSettings.data;
+  $rootScope.currency = csCurrency.data;
   $rootScope.walletData = csWallet.data;
   $rootScope.device = Device;
 
@@ -477,7 +489,13 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht
       return csSettings.ready();
     })
 
-    // Trying to restore default wallet
+    // Load currency
+    .then(csCurrency.get)
+    .then(function(currency){
+      $rootScope.currency = currency;
+    })
+
+    // Trying to restore wallet
     .then(csWallet.restore)
 
     // Storing wallet to root scope
@@ -485,7 +503,6 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht
       $rootScope.walletData = walletData;
     });
 
-
 })
 ;
 
diff --git a/www/js/config.js b/www/js/config.js
index 08361de8bf372271e3f5152e389e52e11de73706..0cab57479bc07009d56d5613d68e06d4d1f1fe07 100644
--- a/www/js/config.js
+++ b/www/js/config.js
@@ -11,26 +11,21 @@ angular.module("cesium.config", [])
 .constant("csConfig", {
 	"cacheTimeMs": 60000,
 	"fallbackLanguage": "en",
-	"rememberMe": false,
+	"rememberMe": true,
 	"showUDHistory": false,
 	"timeout": 10000,
 	"timeWarningExpireMembership": 5184000,
 	"timeWarningExpire": 7776000,
-	"logoutIlde": 600,
 	"useLocalStorage": true,
 	"useRelative": false,
 	"initPhase": false,
-	"expertMode": false,
+	"expertMode": true,
 	"decimalCount": 2,
 	"httpsMode": false,
 	"helptip": {
-		"enable": true,
+		"enable": false,
 		"installDocUrl": "https://github.com/duniter/duniter/blob/master/doc/install-a-node.md"
 	},
-	"license": {
-		"fr-FR": "license/license_g1-fr-FR.txt",
-		"en": "license/license_g1-en.txt"
-	},
 	"node": {
 		"host": "g1.duniter.org",
 		"port": "443"
@@ -39,19 +34,23 @@ angular.module("cesium.config", [])
 		"es": {
 			"enable": true,
 			"askEnable": false,
-			"host": "g1.data.duniter.fr",
-			"port": "443",
-			"notifications": {
-				"txSent": true,
-				"txReceived": true,
-				"certSent": true,
-				"certReceived": true
-			}
-		}
+			"host": "localhost",
+			"port": "9200",
+			"wsPort": "9400"
+		},
+		"graph": {
+			"enable": true
+		},
+		"neo4j": {
+			"enable": true
+		},
+    "rml9": {
+      "enable": true
+    }
 	},
 	"version": "0.12.6",
-	"build": "2017-05-22T16:39:21.668Z",
+	"build": "2017-05-23T08:45:46.819Z",
 	"newIssueUrl": "https://github.com/duniter/cesium/issues/new?labels=bug"
 })
 
-;
\ No newline at end of file
+;
diff --git a/www/js/controllers/app-controllers.js b/www/js/controllers/app-controllers.js
index a4187af495d70558b33b9d880cbb9e08d4fe5db2..e52206a821d3dcd4645c9f649fb08303af9ca487 100644
--- a/www/js/controllers/app-controllers.js
+++ b/www/js/controllers/app-controllers.js
@@ -436,7 +436,6 @@ function AppController($scope, $rootScope, $state, $ionicSideMenuDelegate, $q, $
   $scope.doMotion = function(options) {
     return $scope.motion.show(options);
   };
-
 }
 
 
@@ -448,12 +447,11 @@ function AboutController($scope, csConfig) {
 
 function HomeController($scope) {
   'ngInject';
-
 }
 
+
 function PassCodeController($scope) {
   'ngInject';
-
 }
 
 
diff --git a/www/js/controllers/blockchain-controllers.js b/www/js/controllers/blockchain-controllers.js
index 87c96e52c428dbf2ce7e3d38cb266ad05d09d160..e64455399434cc5262c96384c9f41411b3e5d507 100644
--- a/www/js/controllers/blockchain-controllers.js
+++ b/www/js/controllers/blockchain-controllers.js
@@ -101,11 +101,11 @@ function BlockLookupController($scope, $timeout, $focus, $filter, $state, $ancho
       }
       // Load currency if need
       if (!$scope.currency) {
-        csCurrency.default()
+        csCurrency.get()
           .then(function(currency) {
             $scope.currency = currency ? currency.name : null;
-            $scope.node = !BMA.node.same(currency.peer.host, currency.peer.port) ?
-              BMA.instance(currency.peer.host, currency.peer.port) : BMA;
+            $scope.node = !BMA.node.same(currency.node.host, currency.node.port) ?
+              BMA.instance(currency.node.host, currency.node.port) : BMA;
 
             if (!$scope.currency) {
               UIUtils.alert.error('ERROR.GET_CURRENCY_FAILED');
@@ -434,12 +434,11 @@ function BlockViewController($scope, $ionicPopover, $state, UIUtils, BMA, csCurr
     $scope.hash = state && state.stateParams && state.stateParams.hash ? state.stateParams.hash : undefined;
 
     if (!$scope.currency) {
-      csCurrency.default()
+      csCurrency.get()
         .then(function (currency) {
           if (currency) {
             $scope.currency = currency.name;
-            $scope.node = !BMA.node.same(currency.peer.host, currency.peer.port) ?
-              BMA.instance(currency.peer.host, currency.peer.port) : BMA;
+            $scope.node = currency.node;
             $scope.load();
           }
         })
diff --git a/www/js/controllers/currency-controllers.js b/www/js/controllers/currency-controllers.js
index 907ebb1bf0e0e29468581601872c9fb34d967ec6..863d2158e660cf786720fed678fdbd02515cff0d 100644
--- a/www/js/controllers/currency-controllers.js
+++ b/www/js/controllers/currency-controllers.js
@@ -6,29 +6,6 @@ angular.module('cesium.currency.controllers', ['cesium.services'])
 
   $stateProvider
 
-    .state('app.currency_lookup', {
-      url: "/currencies?q",
-      views: {
-        'menuContent': {
-          templateUrl: "templates/currency/lookup.html",
-          controller: 'CurrencyLookupCtrl'
-        }
-      }
-    })
-
-    .state('app.currency_name', {
-      url: "/currencies/:currency",
-      views: {
-        'menuContent': {
-          templateUrl: "templates/currency/view_currency.html",
-          controller: 'CurrencyViewCtrl'
-        }
-      },
-      data: {
-        large: 'app.currency_name_lg'
-      }
-    })
-
     .state('app.currency', {
       url: "/currency",
       views: {
@@ -80,17 +57,6 @@ angular.module('cesium.currency.controllers', ['cesium.services'])
       }
     })
 
-    .state('app.currency_name_lg', {
-      url: "/currency/lg/:name",
-      cache: false,
-      views: {
-        'menuContent': {
-          templateUrl: "templates/currency/view_currency_lg.html",
-          controller: 'CurrencyViewCtrl'
-        }
-      }
-    })
-
     .state('app.currency_lg', {
       url: "/currency/lg",
       cache: false,
@@ -105,63 +71,12 @@ angular.module('cesium.currency.controllers', ['cesium.services'])
 
 })
 
-.controller('CurrencyLookupCtrl', CurrencyLookupController)
-
-.controller('CurrencyViewCtrl', CurrencyViewController)
+  .controller('CurrencyViewCtrl', CurrencyViewController)
 
   .controller('CurrencyLicenseModalCtrl', CurrencyLicenseModalController)
 ;
 
-function CurrencyLookupController($scope, $state, $q, UIUtils, BMA, csCurrency) {
-  'ngInject';
-
-  $scope.selectedCurrency = '';
-  $scope.knownCurrencies = [];
-  $scope.search = {
-    loading: true,
-    results: []
-  };
-  $scope.entered = false;
-
-  $scope.$on('$ionicView.enter', function(e, state) {
-    if (!$scope.entered) {
-      if (state && state.stateParams && state.stateParams.q) {
-        $scope.search.text = state.stateParams.q;
-      }
-
-      csCurrency.all()
-        .then(function (currencies) {
-
-          $q.all(currencies.map(function(currency) {
-            var bma = BMA.lightInstance(currency.peer.host,currency.peer.port);
-            return bma.blockchain.current()
-              .then(function(block) {
-                currency.membersCount = block.membersCount;
-              });
-          }))
-          .then(function() {
-            $scope.search.results = currencies;
-            $scope.search.loading = false;
-            if (!!currencies && currencies.length == 1) {
-              $scope.selectedCurrency = currencies[0].id;
-            }
-            // Set Ink
-            UIUtils.ink({selector: 'a.item'});
-          });
-
-
-        });
-    }
-  });
-
-  // Called to navigate to the main app
-  $scope.selectCurrency = function(currency) {
-    $scope.selectedCurrency = currency;
-    $state.go('app.currency_name', {currency: currency.name});
-  };
-}
-
-function CurrencyViewController($scope, $q, $timeout, $ionicPopover, BMA, UIUtils, csSettings, csCurrency, csNetwork, ModalUtils) {
+function CurrencyViewController($scope, $q, $timeout, $ionicPopover, Modals, BMA, UIUtils, csSettings, csCurrency, csNetwork, ModalUtils) {
 
   $scope.formData = {
     useRelative: csSettings.data.useRelative,
@@ -195,25 +110,23 @@ function CurrencyViewController($scope, $q, $timeout, $ionicPopover, BMA, UIUtil
       csSettings.data.expertMode,
     licenseUrl: csSettings.getLicenseUrl()
   };
-  $scope.node = null;
   $scope.loading = true;
   $scope.screen = UIUtils.screen;
 
   $scope.enter = function(e, state) {
     if ($scope.loading) { // run only once (first enter)
-      if (state.stateParams && state.stateParams.currency) { // Load by name
-        csCurrency.searchByName(state.stateParams.currency)
-        .then(function(currency){
-          $scope.init(currency);
-        });
-      }
-      else {
-        csCurrency.default()
-        .then(function (currency) {
-          $scope.init(currency);
+
+      UIUtils.loading.show();
+
+      csCurrency.get()
+        .then($scope.load)
+        .then(function() {
+          // Show help tip, if login
+          if ($scope.isLogin()) {
+            $scope.showHelpTip();
+          }
         })
         .catch(UIUtils.onError('ERROR.GET_CURRENCY_FAILED'));
-      }
 
       csNetwork.api.data.on.mainBlockChanged($scope, function(mainBlock) {
         if ($scope.loading) return;
@@ -228,34 +141,13 @@ function CurrencyViewController($scope, $q, $timeout, $ionicPopover, BMA, UIUtil
   };
   $scope.$on('$ionicView.enter', $scope.enter);
 
-  $scope.init = function(currency) {
-    $scope.formData.currency = currency.name;
-    $scope.node = !BMA.node.same(currency.peer.host, currency.peer.port) ?
-      BMA.instance(currency.peer.host, currency.peer.port) : BMA;
-
-    UIUtils.loading.show();
-
-    // Load data
-    $scope.load()
-      .then(function() {
-        // Show help tip, if login
-        if ($scope.isLogin()) {
-          $scope.showHelpTip();
-        }
-      });
-  };
-
   $scope.load = function() {
-    if (!$scope.node) {
-      return;
-    }
-
     // Load data from node
     var data = {}, M, lastUDTime, now = new Date().getTime();
     return $q.all([
 
       // Get the currency parameters
-      $scope.node.blockchain.parameters()
+      BMA.blockchain.parameters()
         .then(function(json){
           data.currency = json.currency;
           data.c = json.c;
@@ -279,7 +171,7 @@ function CurrencyViewController($scope, $q, $timeout, $ionicPopover, BMA, UIUtil
         }),
 
       // Get the current block informations
-      $scope.node.blockchain.current()
+      BMA.blockchain.current()
         .then(function(block){
           M = block.monetaryMass;
           data.N = block.membersCount;
@@ -299,11 +191,11 @@ function CurrencyViewController($scope, $q, $timeout, $ionicPopover, BMA, UIUtil
         }),
 
       // Get the UD informations
-      $scope.node.blockchain.stats.ud()
+      BMA.blockchain.stats.ud()
         .then(function(res){
           if (res.result.blocks.length) {
             var lastBlockWithUD = res.result.blocks[res.result.blocks.length - 1];
-            return $scope.node.blockchain.block({ block: lastBlockWithUD })
+            return BMA.blockchain.block({ block: lastBlockWithUD })
               .then(function(block){
                 data.currentUD = (block.unitbase > 0) ? block.dividend * Math.pow(10, block.unitbase) : block.dividend;
                 lastUDTime = block.medianTime;
@@ -314,7 +206,7 @@ function CurrencyViewController($scope, $q, $timeout, $ionicPopover, BMA, UIUtil
           else {
             lastUDTime=0;
             data.Nprev=0;
-            return $scope.node.blockchain.parameters()
+            return BMA.blockchain.parameters()
               .then(function(json){
                 data.currentUD = json.ud0;
               });
@@ -423,6 +315,10 @@ function CurrencyViewController($scope, $q, $timeout, $ionicPopover, BMA, UIUtil
     return ModalUtils.show('templates/currency/modal_license.html','CurrencyLicenseModalCtrl');
   };
 
+  $scope.showHelpModal = function(helpAnchor) {
+    Modals.showHelp({anchor: helpAnchor});
+  };
+
   /* -- popover -- */
 
   $scope.showActionsPopover = function(event) {
diff --git a/www/js/controllers/help-controllers.js b/www/js/controllers/help-controllers.js
index 6cc430a0462cbbbceb5ce9d8e5152c0e3de3ecaa..a76a801f310c28bbbe4fe89a01a3ed783510fdc5 100644
--- a/www/js/controllers/help-controllers.js
+++ b/www/js/controllers/help-controllers.js
@@ -60,6 +60,7 @@ function HelpController($scope, $state, $timeout, $anchorScroll, csSettings) {
   $scope.$on('$ionicView.enter', function(e) {
     $scope.locale = csSettings.data.locale.id;
     if ($state.stateParams && $state.stateParams.anchor) {
+      $scope.anchor = $state.stateParams.anchor;
       $timeout(function () {
         $anchorScroll($state.stateParams.anchor);
       }, 100);
@@ -70,13 +71,21 @@ function HelpController($scope, $state, $timeout, $anchorScroll, csSettings) {
 function HelpModalController($scope, $timeout, $anchorScroll, csSettings, parameters) {
   'ngInject';
 
+  $scope.itemsClass = {};
   $scope.locale = csSettings.data.locale.id;
 
   if (parameters && parameters.anchor) {
+
     $timeout(function() {
       $anchorScroll(parameters.anchor);
     }, 100);
+
+    // Change CSS classes
+    $scope.itemsClass = {};
+    $scope.itemsClass[parameters.anchor] = 'positive';
+    $scope.listClass = 'gray';
   }
+
 }
 
 
@@ -370,7 +379,7 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe
     ];
 
     // Get currency parameters, with currentUD
-    return csCurrency.default().then(function(currency) {
+    return csCurrency.get().then(function(currency) {
       contentParams = currency.parameters;
       // Launch steps
       return $scope.executeStep('currency', steps, startIndex);
@@ -481,8 +490,8 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe
     ];
 
     // Get currency parameters, with currentUD
-    return csCurrency.default().then(function(currency) {
-      contentParams = currency.parameters;
+    return csCurrency.parameters().then(function(parameters) {
+      contentParams = parameters;
       // Launch steps
       return $scope.executeStep('network', steps, startIndex);
     });
@@ -581,9 +590,9 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe
     ];
 
     // Get currency parameters, with currentUD
-    return csCurrency.default().then(function(currency) {
+    return csCurrency.get().then(function(currency) {
       contentParams = currency.parameters;
-      contentParams.currentUD = $rootScope.walletData.currentUD;
+      contentParams.currentUD = currency.currentUD;
       // Launch steps
       return $scope.executeStep('wot', steps, startIndex);
     });
@@ -732,10 +741,10 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe
     ];
 
     // Get currency parameters, with currentUD
-    return csCurrency.default()
+    return csCurrency.get()
       .then(function(currency) {
         contentParams = currency.parameters;
-        contentParams.currentUD = $rootScope.walletData.currentUD;
+        contentParams.currentUD = currency.currentUD;
         // Launch steps
         return $scope.executeStep('wallet', steps, startIndex);
       });
@@ -844,8 +853,8 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe
       }*/
     ];
 
-    return csCurrency.default().then(function(currency) {
-      contentParams = currency.parameters;
+    return csCurrency.parameters().then(function(parameters) {
+      contentParams = parameterss;
       return $scope.executeStep('certs', steps, startIndex);
     });
   };
@@ -908,10 +917,10 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe
     ];
 
     // Get currency parameters, with currentUD
-    return csCurrency.default()
+    return csCurrency.get()
       .then(function(currency) {
         contentParams = currency.parameters;
-        contentParams.currentUD = $rootScope.walletData.currentUD;
+        contentParams.currentUD = currency.currentUD;
         // Launch steps
         return $scope.executeStep('tx', steps, startIndex);
       });
@@ -1036,9 +1045,9 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe
       }
     ];
 
-    return csCurrency.default()
-      .then(function(currency) {
-        contentParams = currency.parameters;
+    return csCurrency.parameters()
+      .then(function(parameters) {
+        contentParams = parameters;
         return $scope.executeStep('settings', steps, startIndex);
       });
   };
@@ -1072,7 +1081,7 @@ function HelpTipController($scope, $rootScope, $state, $window, $ionicSideMenuDe
       return $q.all([
         $scope.showHome(),
 
-        csCurrency.default()
+        csCurrency.parameters()
           .then(function(parameters) {
             contentParams = parameters;
           })
diff --git a/www/js/controllers/join-controllers.js b/www/js/controllers/join-controllers.js
index 77e469e15cdb647c60796275c9dd99356a49562d..cc099bfe274962eabd66e3701943b173f2cef4ed 100644
--- a/www/js/controllers/join-controllers.js
+++ b/www/js/controllers/join-controllers.js
@@ -32,7 +32,7 @@ function JoinController($timeout, Modals) {
   }, 100);
 }
 
-function JoinChooseAccountTypeModalController($scope, $timeout, UIUtils, csCurrency) {
+function JoinChooseAccountTypeModalController($scope, $state, Modals, UIUtils, csCurrency) {
   'ngInject';
 
   $scope.formData = {};
@@ -48,10 +48,11 @@ function JoinChooseAccountTypeModalController($scope, $timeout, UIUtils, csCurre
 
   $scope.load = function() {
     if ($scope.loading) {
-      return csCurrency.load()
-        .then(function (data) {
-          if (!data) return;
-          $scope.currencies = data.currencies;
+      return csCurrency.get()
+        .then(function (currency) {
+          if (!currency) return;
+          $scope.currency = currency;
+          $scope.formData.currency = currency.name;
           $scope.loading = false;
         })
         .catch(UIUtils.onError('ERROR.GET_CURRENCIES_FAILED'));
@@ -76,16 +77,26 @@ function JoinChooseAccountTypeModalController($scope, $timeout, UIUtils, csCurre
     $scope.slides.slider.lockSwipes();
   };
 
-  $scope.selectCurrency = function(currency) {
-    $scope.formData.currency = currency;
-    $scope.slideNext();
-  };
-
   $scope.selectAccountTypeAndClose = function(type) {
     $scope.formData.accountType = type;
     $scope.closeModal($scope.formData);
   };
 
+  /**
+   * Catch click for quick fix
+   * @param fix
+   */
+  $scope.doQuickFix = function(event) {
+    if (event == 'settings') {
+      $scope.closeModal();
+      $state.go('app.settings');
+    }
+  };
+
+  $scope.showHelpModal = function(helpAnchor) {
+    Modals.showHelp({anchor: helpAnchor});
+  };
+
   // TODO DEV only
   //$timeout(function() {
    //$scope.selectCurrency('g1');
@@ -94,7 +105,7 @@ function JoinChooseAccountTypeModalController($scope, $timeout, UIUtils, csCurre
 }
 
 
-function JoinModalController($scope, $state, $interval, $timeout, UIUtils, CryptoUtils, csSettings, Modals, csWallet, csConfig, BMA, parameters) {
+function JoinModalController($scope, $state, $interval, $timeout, $focus, UIUtils, CryptoUtils, csSettings, Modals, csWallet, BMA, parameters) {
   'ngInject';
 
   $scope.formData = {
@@ -127,11 +138,11 @@ function JoinModalController($scope, $state, $interval, $timeout, UIUtils, Crypt
     if ($scope.loading) {
 
       $scope.licenseFileUrl = csSettings.getLicenseUrl();
-
-      $scope.startListenLicenseBottom();
+      if ($scope.licenseFileUrl) {
+        $scope.startListenLicenseBottom();
+      }
 
       $scope.slideBehavior = $scope.computeSlideBehavior();
-
       $scope.loading = false;
     }
   };
@@ -156,17 +167,18 @@ function JoinModalController($scope, $state, $interval, $timeout, UIUtils, Crypt
 
   $scope.showAccountPubkey = function() {
     $scope.formData.computing=true;
+
     CryptoUtils.connect($scope.formData.username, $scope.formData.password)
-    .then(function(keypair) {
-      $scope.formData.pubkey = CryptoUtils.util.encode_base58(keypair.signPk);
-      $scope.formData.computing=false;
-      $scope.checkAccountAvailable();
-    })
-    .catch(function(err) {
-      $scope.formData.computing=false;
-      console.error('>>>>>>>' , err);
-      UIUtils.alert.error('ERROR.CRYPTO_UNKNOWN_ERROR');
-    });
+      .then(function(keypair) {
+        $scope.formData.pubkey = CryptoUtils.util.encode_base58(keypair.signPk);
+        $scope.formData.computing=false;
+        $scope.checkAccountAvailable();
+      })
+      .catch(function(err) {
+        $scope.formData.computing=false;
+        console.error('>>>>>>>' , err);
+        UIUtils.alert.error('ERROR.CRYPTO_UNKNOWN_ERROR');
+      });
   };
 
   $scope.formDataChanged = function() {
@@ -177,6 +189,7 @@ function JoinModalController($scope, $state, $interval, $timeout, UIUtils, Crypt
   $scope.getCurrentFormName = function() {
     var index = $scope.slides.slider.activeIndex;
     if($scope.accountType === 'member') {
+      index += ($scope.licenseFileUrl ? 0 : 1); // skip index 0, when no license file
       if (index === 0) return "licenseForm";
       if (index === 1) return "pseudoForm";
       if (index === 2) return "saltForm";
@@ -193,45 +206,62 @@ function JoinModalController($scope, $state, $interval, $timeout, UIUtils, Crypt
   $scope.computeSlideBehavior = function() {
     var formName = $scope.getCurrentFormName();
 
+    var behavior;
     if (formName == "licenseForm") {
-      return {
+      behavior = {
         hasPreviousButton: false,
         hasNextButton: false,
         hasAcceptButton: true
       };
     }
     else if (formName == "pseudoForm") {
-      return {
+      behavior = {
         helpAnchor: 'join-pseudo',
-        hasPreviousButton: true,
-        hasNextButton: true
+        hasPreviousButton: $scope.licenseFileUrl && true,
+        hasNextButton: true,
+        focus: 'pseudo'
       };
     }
     else if (formName == "saltForm") {
-      return {
+      behavior = {
         helpAnchor: 'join-salt',
         hasPreviousButton: true,
-        hasNextButton: true
+        hasNextButton: true,
+        focus: 'salt'
       };
     }
     else if (formName == "passwordForm") {
-      return {
+      behavior = {
         helpAnchor: 'join-password',
         hasPreviousButton: true,
-        hasNextButton: true
+        hasNextButton: true,
+        focus: 'password'
       };
     }
     else if (formName == "confirmForm") {
-      return {
+      behavior = {
         hasPreviousButton: true,
         hasNextButton: false,
         hasSendButton: true
       };
     }
-    return {
-      hasPreviousButton: false,
-      hasNextButton: true
-    };
+    else {
+      behavior = {
+        hasPreviousButton: false,
+        hasNextButton: true
+      };
+    }
+
+    // removeIf(device)
+    // Focus input text (only if NOT device, to avoid keyboard opening)
+    if (behavior.focus) {
+      $timeout(function(){
+        $focus(behavior.focus);
+      }, 100);
+    }
+    // endRemoveIf(device)
+
+    return behavior;
   };
 
 
@@ -376,8 +406,9 @@ function JoinModalController($scope, $state, $interval, $timeout, UIUtils, Crypt
   };
 
   $scope.checkUid = function(){
-    if (!$scope.formData.pseudo || !$scope.formData.pseudo.length) {
-      $scope.uiAlreadyUsed = undefined;
+    if (!$scope.formData.pseudo || $scope.formData.pseudo.length < 3) {
+      $scope.formData.computing=false;
+      delete $scope.uiAlreadyUsed;
       return;
     }
 
@@ -395,6 +426,7 @@ function JoinModalController($scope, $state, $interval, $timeout, UIUtils, Crypt
         $scope.formData.computing=false;
       })
       .catch(function(err){
+        console.error(err);
         $scope.formData.computing=false;
         $scope.uiAlreadyUsed = false;
       });
@@ -402,9 +434,9 @@ function JoinModalController($scope, $state, $interval, $timeout, UIUtils, Crypt
   $scope.$watch('formData.pseudo', $scope.checkUid, true);
 
   $scope.checkAccountAvailable = function() {
-    var pub = $scope.formData.pubkey;
-    $scope.accountAvailable = false;
-    BMA.tx.sources({ pubkey: pub }) // search on pubkey
+    delete $scope.accountAvailable;
+    // Search for tx source, from pubkey
+    BMA.tx.sources({ pubkey:  $scope.formData.pubkey })
       .then(function(res) {
         if(!res.sources.length) {
           $scope.formData.computing=false;
@@ -412,7 +444,13 @@ function JoinModalController($scope, $state, $interval, $timeout, UIUtils, Crypt
         }
         else{
           $scope.formData.computing=false;
+          $scope.accountAvailable = false;
         }
+      })
+      .catch(function(err) {
+        console.error(err);
+        $scope.formData.computing=false;
+        $scope.accountAvailable = false;
       });
   };
 
diff --git a/www/js/controllers/network-controllers.js b/www/js/controllers/network-controllers.js
index 47758b5b3d7be5f05cb96b068b13a78071cf69f7..f2c90afe495921982e8f3ddc46e5b9c9d30d0a2f 100644
--- a/www/js/controllers/network-controllers.js
+++ b/www/js/controllers/network-controllers.js
@@ -65,11 +65,11 @@ function NetworkLookupController($scope,  $state, $ionicHistory, $ionicPopover,
     if ($scope.networkStarted) return;
     $scope.networkStarted = true;
     $scope.search.loading = true;
-    csCurrency.default()
+    csCurrency.get()
       .then(function (currency) {
         if (currency) {
-          $scope.node = !BMA.node.same(currency.peer.host, currency.peer.port) ?
-            BMA.instance(currency.peer.host, currency.peer.port) : BMA;
+          $scope.node = !BMA.node.same(currency.node.host, currency.node.port) ?
+            BMA.instance(currency.node.host, currency.node.port) : BMA;
           if (state && state.stateParams) {
             if (state.stateParams.type && ['mirror', 'member', 'offline'].indexOf(state.stateParams.type) != -1) {
               $scope.search.type = state.stateParams.type;
diff --git a/www/js/controllers/settings-controllers.js b/www/js/controllers/settings-controllers.js
index 9b87e7f1c9c1de9b211cc9ab4437cc8d383052e3..85158edd54a69d226c5da825d9c6885e61406b37 100644
--- a/www/js/controllers/settings-controllers.js
+++ b/www/js/controllers/settings-controllers.js
@@ -20,7 +20,7 @@ angular.module('cesium.settings.controllers', ['cesium.services', 'cesium.curren
   .controller('SettingsCtrl', SettingsController)
 ;
 
-function SettingsController($scope, $q, $ionicPopup, $timeout, $translate, csHttp,
+function SettingsController($scope, $q, $ionicHistory, $ionicPopup, $timeout, $translate, csHttp,
   UIUtils, BMA, csSettings, $ionicPopover, Modals) {
   'ngInject';
 
@@ -121,6 +121,9 @@ function SettingsController($scope, $q, $ionicPopup, $timeout, $translate, csHtt
           UIUtils.loading.hide();
           $scope.formData.node = newNode;
           BMA.copy(nodeBMA);
+
+          // Reset history cache
+          return $ionicHistory.clearCache();
         });
     });
   };
diff --git a/www/js/plugins.js b/www/js/plugins.js
index cbe68800eb9d6e49bf05049cd6bf074beb593243..cfc0d177e463a9975dd38fe3ddff3bba430b7e19 100644
--- a/www/js/plugins.js
+++ b/www/js/plugins.js
@@ -4,6 +4,7 @@ angular.module('cesium.plugins', [
   'cesium.plugins.templates',
   // Plugins
   'cesium.es.plugin',
-  'cesium.graph.plugin'
+  'cesium.graph.plugin',
+  'cesium.rml9.plugin'
   ])
 ;
diff --git a/www/js/services/bma-services.js b/www/js/services/bma-services.js
index dffc4a47127c873e0772e61bbdb9c77580ecc8bf..9c0351fe1b3c52c9c47bd7e87757e53d294cbfe0 100644
--- a/www/js/services/bma-services.js
+++ b/www/js/services/bma-services.js
@@ -337,7 +337,7 @@ angular.module('cesium.bma.services', ['ngResource', 'ngApi', 'cesium.http.servi
       node: {
         summary: get('/node/summary', csHttp.cache.LONG),
         same: function(host2, port2) {
-          return host2 == host && ((!port && !port2) || (port == port2));
+          return host2 == that.host && ((!that.port && !port2) || (that.port == port2||80));
         }
       },
       network: {
@@ -615,7 +615,7 @@ angular.module('cesium.bma.services', ['ngResource', 'ngApi', 'cesium.http.servi
             }
           })
           .catch(function(err){
-            if (err && err.ucode === errorCodes.HTTP_LIMITATION) {
+            if (err && err.ucode === exports.errorCodes.HTTP_LIMITATION) {
               resolve(result);
             }
             else {
@@ -625,6 +625,19 @@ angular.module('cesium.bma.services', ['ngResource', 'ngApi', 'cesium.http.servi
       });
     };
 
+    exports.raw.getHttpWithRetryIfLimitation = function(exec) {
+      return exec()
+        .catch(function(err){
+          // When too many request, retry in 3s
+          if (err && err.ucode == exports.errorCodes.HTTP_LIMITATION) {
+            return $timeout(function() {
+              // retry
+              return exports.raw.getHttpWithRetryIfLimitation(exec);
+            }, exports.constants.LIMIT_REQUEST_DELAY);
+          }
+        });
+    };
+
     exports.blockchain.lastUd = function() {
       return exports.blockchain.stats.ud()
         .then(function(res) {
diff --git a/www/js/services/currency-services.js b/www/js/services/currency-services.js
index 086b898ba6b06261e5e21e2c562166a791e7e08b..c2818e68513c587e9a48e8c3de7dd1645df47952 100644
--- a/www/js/services/currency-services.js
+++ b/www/js/services/currency-services.js
@@ -1,107 +1,190 @@
 
 angular.module('cesium.currency.services', ['ngResource', 'ngApi', 'cesium.bma.services'])
 
-.factory('csCurrency', function($q, BMA, Api, $rootScope) {
+.factory('csCurrency', function($q, BMA, Api) {
   'ngInject';
 
-  factory = function(id) {
-
+  function factory(id, BMA) {
     var
-      data = {
-        loaded: false,
-        currencies: null,
-        cache: {
-          loadPromise: null
+      constants = {
+        // Avoid to many call on well known currencies
+        WELL_KNOWN_CURRENCIES: {
+          g1: {
+            firstBlockTime: 1488987127
+          }
         }
       },
-      api = new Api(this, "csCurrency-" + id),
 
-      loadData = function() {
+      data = {},
+      api = new Api(this, "csCurrency-" + id);
+
+    function powBase(amount, base) {
+      return base <= 0 ? amount : amount * Math.pow(10, base);
+    }
+
+    function resetData() {
+      data.loaded = false;
+      data.name = null;
+      data.parameters = null;
+      data.firstBlockTime = null;
+      data.membersCount = null;
+      data.cache = {};
+      data.node = BMA;
+      data.currentUD = null;
+      api.data.raise.reset(data);
+    }
+
+    function loadData() {
+
+      console.debug('[currency] Starting...');
+      var now = new Date().getTime();
+
+      // Load currency from default node
+      data.cache.loadPromise = $q.all([
+
+        // get parameters
+        loadParameters()
+          .then(function(parameters) {
+            // load first block info
+            return loadFirstBlock(parameters.currency);
+          }),
+
+        // get current data (e.g. UD, members count)
+        loadCurrentData(),
+
+        // call extensions
+        api.data.raisePromise.load(data)
+      ])
+        .then(function() {
+          console.debug('[currency] Loaded in ' + (new Date().getTime() - now) + 'ms');
+          data.loaded = true;
+          delete data.cache.loadPromise;
+          return data;
+        })
+        .catch(function(err) {
+          resetData();
+          throw err;
+        });
+
+      return data.cache.loadPromise;
+    }
+
+    function loadParameters() {
+      return BMA.blockchain.parameters()
+        .then(function(res){
+          data.name = res.currency;
+          data.parameters = res;
+          return res;
+        });
+    }
+
+    function loadFirstBlock(currencyName) {
+      // Well known currencies
+      if (constants.WELL_KNOWN_CURRENCIES[currencyName]){
+        angular.merge(data, constants.WELL_KNOWN_CURRENCIES[currencyName]);
+        return $q.when();
+      }
+
+      return BMA.blockchain.block({block:0})
+        .then(function(json) {
+          // Need by graph plugin
+          data.firstBlockTime = json.medianTime;
+        })
+        .catch(function(err) {
+          // Special case, when currency not started yet
+          if (err && err.ucode === BMA.errorCodes.BLOCK_NOT_FOUND) {
+            data.firstBlockTime = 0;
+            return;
+          }
+          throw err;
+        });
+    }
+
+    function loadCurrentData() {
+      return BMA.blockchain.stats.ud()
+        .then(function(res){
+          // Special case for currency init
+          if (!res.result.blocks.length) {
+            data.currentUD = data.parameters ? data.parameters.ud0 : -1;
+            return data.currentUD ;
+          }
+          else {
+            var lastBlockWithUD = res.result.blocks[res.result.blocks.length - 1];
+            return BMA.blockchain.block({ block: lastBlockWithUD })
+              .then(function(block){
+                data.currentUD = powBase(block.dividend, block.unitbase);
+                data.membersCount = block.membersCount;
+                return data.currentUD;
+              })
+              .catch(function(err) {
+                data.currentUD = null;
+                throw err;
+              });
+          }
+        })
+        .catch(function(err) {
+          data.currentUD = null;
+          throw err;
+        });
+    }
+
+    function getData() {
+      if (data.loaded) { // load only once
+        return $q.when(data);
+      }
+
+      // Previous load not finished: return the existing promise - fix #452
+      if (data.cache.loadPromise) { // load only once
+        return $q.when(data.cache.loadPromise);
+      }
+
+      return loadData();
+    }
+
+    function getDataField(field) {
+      return function() {
         if (data.loaded) { // load only once
-          return $q.when(data);
+          return $q.when(data[field]);
         }
 
         // Previous load not finished: return the existing promise - fix #452
         if (data.cache.loadPromise) { // load only once
-          return $q.when(data.cache.loadPromise);
+          return $q.when(data.cache.loadPromise)
+            .then(function(){
+              return data[field];
+            });
         }
 
-        data.currencies = [];
-
-        var now = new Date().getTime();
-
-        // Load currency from default node
-        var promise = BMA.blockchain.parameters()
-          .then(function(res){
-            data.currencies.push({
-                name: res.currency,
-                peer: {
-                  host: BMA.host,
-                  port: BMA.port,
-                  server: BMA.server
-                },
-                parameters: res
-              });
-
-            // API extension point
-            return api.data.raisePromise.load(data);
-          })
-          .then(function() {
-            console.debug('[currency] Loaded in ' + (new Date().getTime() - now) + 'ms');
-            data.loaded = true;
-            delete data.cache.loadJobPromise;
-            return data;
-          })
-          .catch(function(err) {
-            data.loaded = false;
-            data.currencies = [];
-            delete data.cache.loadJobPromise;
-            throw err;
-          });
-
-        data.cache.loadPromise = promise;
-        return promise;
-      },
-
-      getAll = function() {
-        return loadData()
-        .then(function(data){
-          return data.currencies;
+        return loadData().then(function(){
+          return data[field];
         });
-      },
-
-      getDefault = function() {
-        return loadData()
-          .then(function(data){
-            if (!data || !data.currencies || !data.currencies.length) throw new Error('No default currency');
-            return data.currencies[0];
-          });
-      },
+      };
+    }
 
-      searchByName = function(name) {
-        return loadData()
-          .then(function(data){
-            return _.findWhere(data.currencies, {name: name});
-          });
-      }
-    ;
+    // TODO register new block event, to get new UD value
 
     // Register extension points
     api.registerEvent('data', 'load');
+    api.registerEvent('data', 'reset');
+
+    // init data
+    resetData();
 
     return {
-      id: id,
-      load: loadData,
-      all: getAll,
-      default: getDefault,
-      searchByName: searchByName,
+      get: getData,
+      parameters: getDataField('parameters'),
+      currentUD: getDataField('currentUD'),
       // api extension
-      api: api
+      api: api,
+      // deprecated methods
+      default: function() {
+        console.warn('[currency] \'csCurrency.default()\' has been DEPRECATED - Please use \'csCurrency.get()\' instead.');
+        return getData();
+      }
     };
-  };
-
-  var service = factory('default');
+  }
 
+  var service = factory('default', BMA);
   service.instance = factory;
   return service;
 });
diff --git a/www/js/services/wallet-services.js b/www/js/services/wallet-services.js
index 4d289cdd690c01916213137f04e3b11fc9658bfc..1af89938fb991061e717160e4dc44829b5d308cb 100644
--- a/www/js/services/wallet-services.js
+++ b/www/js/services/wallet-services.js
@@ -21,10 +21,10 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
     },
     data = {},
 
-
     api = new Api(this, 'csWallet-' + id),
 
     resetData = function(init) {
+      data.loaded = false;
       data.pubkey= null;
       data.keypair = {
           signSk: null,
@@ -48,7 +48,6 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
       data.sigDate = null;
       data.isMember = false;
       data.events = [];
-      data.loaded = false;
       if (init) {
         api.data.raise.init(data);
       }
@@ -316,12 +315,9 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
                   // Call extend api
                   api.data.raisePromise.login(data),
 
-                  // Load parameters
+                  // Load currency (e.g parameters)
                   // This prevent timeout error, when loading a market record after a browser refresh (e.g. F5)
-                  loadParameters(),
-
-                  // Load current UD is need by features tour
-                  loadCurrentUD()
+                  loadCurrency()
                 ]);
               }
               else */if (storedData && storedData.keypair && storedData.pubkey) {
@@ -340,18 +336,15 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
                   // Call extend api
                   api.data.raisePromise.login(data),
 
-                  // Load parameters
-                  // This prevent timeout error, when loading a market record after a browser refresh (e.g. F5)
-                  loadParameters(),
-
-                  // Load current UD is need by features tour
-                  loadCurrentUD()
+                  // Load currency
+                  // This prevent timeout error, when loading record after a browser refresh (e.g. F5)
+                  loadCurrency()
                 ]);
               }
               else {
-                // Load parameters
+                // Load currency
                 // This prevent timeout error, when loading a market record after a browser refresh (e.g. F5)
-                return loadParameters();
+                return loadCurrency();
               }
             })
             .then(function(){
@@ -686,49 +679,23 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
         });
     },
 
-    loadParameters = function() {
+    loadCurrency = function() {
       if (data.parameters && data.currency) return $q.when();
-      return BMA.blockchain.parameters()
-        .then(function(json){
-          data.currency = json.currency;
-          data.parameters = json;
-          if (data.currentUD == -1) data.currentUD = data.parameters.ud0;
+      return csCurrency.get()
+        .then(function(currency){
+          data.currency = currency.name;
+          data.parameters =currency.parameters;
+          data.currentUD = currency.currentUD;
         })
         .catch(function(err) {
           data.currency = null;
           data.parameters = null;
+          data.currentUD = -1;
           throw err;
         });
     },
 
-    loadCurrentUD = function() {
-      return BMA.blockchain.stats.ud()
-        .then(function(res){
-          // Special case for currency init
-          if (!res.result.blocks.length) {
-            data.currentUD = data.parameters ? data.parameters.ud0 : -1;
-            return data.currentUD ;
-          }
-          else {
-            var lastBlockWithUD = res.result.blocks[res.result.blocks.length - 1];
-            return BMA.blockchain.block({ block: lastBlockWithUD })
-              .then(function(block){
-                data.currentUD = powBase(block.dividend, block.unitbase);
-                return data.currentUD;
-              })
-              .catch(function(err) {
-                data.currentUD = null;
-                throw err;
-              });
-            }
-        })
-        .catch(function(err) {
-          data.currentUD = null;
-          throw err;
-        });
-    },
-
-    // Must be call after loadParameters() and loadRequirements()
+    // Must be call after loadCurrency() and loadRequirements()
     finishLoadRequirements = function() {
       data.requirements.needCertificationCount = (!data.requirements.needMembership && (data.requirements.certificationCount < data.parameters.sigQty)) ?
           (data.parameters.sigQty - data.requirements.certificationCount) : 0;
@@ -804,10 +771,7 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
       return $q.all([
 
           // Get currency parameters
-          loadParameters(),
-
-          // Get current UD
-          loadCurrentUD(),
+          loadCurrency(),
 
           // Get requirements
           loadRequirements(),
@@ -833,7 +797,7 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
           return processTransactionsAndSources();
         })
         .then(function() {
-          finishLoadRequirements(); // must be call after loadParameters() and loadRequirements()
+          finishLoadRequirements(); // must be call after loadCurrency() and loadRequirements()
           return api.data.raisePromise.finishLoad(data)
             .catch(function(err) {
               console.error('Error while finishing wallet data load, on extension point. Try to continue');
@@ -884,11 +848,8 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
       // Reset events
       cleanEventsByContext('requirements');
 
-      // Get parameters
-      if (options.parameters) jobs.push(loadParameters());
-
-      // Get current UD
-      if (options.currentUd) jobs.push(loadCurrentUD());
+      // Get currency (e.g parameters)
+      if (options.parameters || options.currentUd) jobs.push(loadCurrency());
 
       // Get requirements
       if (options.requirements) {
@@ -1291,8 +1252,8 @@ angular.module('cesium.wallet.services', ['ngResource', 'ngApi', 'cesium.bma.ser
         var block;
         return $q.all([
 
-          // Load parameters (need to known the currency)
-          loadParameters(),
+          // Load currency (e.g parameters)
+          loadCurrency(),
 
           // Get th current block
           BMA.blockchain.current()
diff --git a/www/plugins/es/i18n/locale-fr-FR.json b/www/plugins/es/i18n/locale-fr-FR.json
index 3d2878f322a714ad273321f7dba469d86a5ea44d..c09d707abc137907ccc6d331899b4b79cd392be4 100644
--- a/www/plugins/es/i18n/locale-fr-FR.json
+++ b/www/plugins/es/i18n/locale-fr-FR.json
@@ -474,6 +474,8 @@
     "NODE_BMA_UP": "Le noeud <b>{{params[0]}}:{{params[1]}}</b> est à nouveau accessible.",
     "MEMBER_JOIN": "Vous êtes maintenant <b>membre</b> de la monnaie <b>{{params[0]}}</b> !",
     "MEMBER_LEAVE": "Vous n'êtes <b>plus membre</b> de la monnaie <b>{{params[0]}}</b>!",
+    "MEMBER_EXCLUDE": "Vous n'êtes <b>plus membre</b> de la monnaie <b>{{params[0]}}</b>, faute de non renouvellement ou par manque de certifications.",
+    "MEMBER_REVOKE": "La révocation de votre compte a été effectuée. Il ne pourra plus être un compte membre de la monnaie <b>{{params[0]}}</b>.",
     "MEMBER_ACTIVE": "Votre renouvellement d'adhésion à la monnaie <b>{{params[0]}}</b> a été <b>pris en compte</b>.",
     "TX_SENT": "Votre <b>paiement</b> à <span ng-class=\"{'gray': !notification.uid, 'positive':notification.uid}\" ><i class=\"icon\" ng-class=\"{'ion-person': notification.uid, 'ion-key': !notification.uid}\"></i>&thinsp;{{name||uid||params[1]}}</span> a été effectué.",
     "TX_SENT_MULTI": "Votre <b>paiement</b> à <b>{{params[1]}}</b> a été effectué.",
diff --git a/www/plugins/es/js/controllers/market-controllers.js b/www/plugins/es/js/controllers/market-controllers.js
index 69194fa8653f96831c5b63a523fc075add84ba39..e545deb4c9b3cc588d8132f586f416af61a53e23 100644
--- a/www/plugins/es/js/controllers/market-controllers.js
+++ b/www/plugins/es/js/controllers/market-controllers.js
@@ -618,7 +618,7 @@ function ESMarketRecordEditController($scope, $q, $timeout, $state, $ionicPopove
           $scope.formData.type=state.stateParams.type;
         }
         // Set the default currency
-        csCurrency.default()
+        csCurrency.get()
           .then(function(currency){
             $scope.formData.currency = currency.name;
             $scope.loading = false;
diff --git a/www/plugins/es/js/services/market-services.js b/www/plugins/es/js/services/market-services.js
index f328be3e9f46904c6f1f90a38025f71cbdf06cb5..20ff1f1f4d82772f3412eff96343371a7ab5b2eb 100644
--- a/www/plugins/es/js/services/market-services.js
+++ b/www/plugins/es/js/services/market-services.js
@@ -191,7 +191,7 @@ angular.module('cesium.es.market.services', ['ngResource', 'cesium.services', 'c
 
               // Make sure currency if present (fix old data)
               if (!record.currency) {
-                return csCurrency.default()
+                return csCurrency.get()
                   .then(function (currency) {
                     record.currency = currency.name;
                     return data;
diff --git a/www/plugins/graph/css/style.css b/www/plugins/graph/css/style.css
new file mode 100644
index 0000000000000000000000000000000000000000..0d97c8161095b32e210b86648283f901df7acfd3
--- /dev/null
+++ b/www/plugins/graph/css/style.css
@@ -0,0 +1,9 @@
+
+/**********
+   Graph currency popover
+**********/
+
+.popover-graph-currency {
+  height: 300px !important;
+  max-width: 250px !important;
+}
diff --git a/www/plugins/graph/i18n/locale-en-GB.json b/www/plugins/graph/i18n/locale-en-GB.json
index b758ed2fb4dd4362c8d1bd68f72da3501222bd3a..1a64beadbf60d937bb2bd42246536f07b320125e 100644
--- a/www/plugins/graph/i18n/locale-en-GB.json
+++ b/www/plugins/graph/i18n/locale-en-GB.json
@@ -11,6 +11,16 @@
       "BTN_SHOW_STATS": "See statistics",
       "BTN_SHOW_DETAILED_STATS": "Detailed statistics"
     },
+    "ACCOUNT": {
+      "TITLE": "Statistics",
+      "BTN_SHOW_STATS": "View account Statistics",
+      "BALANCE_DIVIDER": "Account status",
+      "BALANCE_TITLE": "Evolution of the account {{pubkey|formatPubkey}}",
+      "TX_RECEIVED_LABEL": "Receipts",
+      "TX_SENT_LABEL": "Spending",
+      "UD_LABEL": "UD",
+      "BALANCE_LABEL": "Balance"
+    },
     "BLOCKCHAIN": {
       "TITLE": "Statistics",
       "BLOCKS_ISSUERS_DIVIDER": "Written blocks by members",
@@ -24,6 +34,7 @@
       "TX_COUNT_TITLE": "Number of written transactions",
       "TX_COUNT_LABEL": "Number of transactions",
       "TX_AVG_BY_BLOCK": "Average per block",
+      "TX_RANGE_DURATION_DIVIDER": "Step unit:",
       "TX_RANGE_DURATION": {
         "HOUR": "Group by <b>hour</b>",
         "DAY": "Group by <b>day</b>",
diff --git a/www/plugins/graph/i18n/locale-en.json b/www/plugins/graph/i18n/locale-en.json
index b758ed2fb4dd4362c8d1bd68f72da3501222bd3a..1a64beadbf60d937bb2bd42246536f07b320125e 100644
--- a/www/plugins/graph/i18n/locale-en.json
+++ b/www/plugins/graph/i18n/locale-en.json
@@ -11,6 +11,16 @@
       "BTN_SHOW_STATS": "See statistics",
       "BTN_SHOW_DETAILED_STATS": "Detailed statistics"
     },
+    "ACCOUNT": {
+      "TITLE": "Statistics",
+      "BTN_SHOW_STATS": "View account Statistics",
+      "BALANCE_DIVIDER": "Account status",
+      "BALANCE_TITLE": "Evolution of the account {{pubkey|formatPubkey}}",
+      "TX_RECEIVED_LABEL": "Receipts",
+      "TX_SENT_LABEL": "Spending",
+      "UD_LABEL": "UD",
+      "BALANCE_LABEL": "Balance"
+    },
     "BLOCKCHAIN": {
       "TITLE": "Statistics",
       "BLOCKS_ISSUERS_DIVIDER": "Written blocks by members",
@@ -24,6 +34,7 @@
       "TX_COUNT_TITLE": "Number of written transactions",
       "TX_COUNT_LABEL": "Number of transactions",
       "TX_AVG_BY_BLOCK": "Average per block",
+      "TX_RANGE_DURATION_DIVIDER": "Step unit:",
       "TX_RANGE_DURATION": {
         "HOUR": "Group by <b>hour</b>",
         "DAY": "Group by <b>day</b>",
diff --git a/www/plugins/graph/i18n/locale-fr-FR.json b/www/plugins/graph/i18n/locale-fr-FR.json
index 7e781d9af9d27b844e56894e71940e1742a4b8e4..99c5115c3a78c498254ac5fa0d94ef13df747aef 100644
--- a/www/plugins/graph/i18n/locale-fr-FR.json
+++ b/www/plugins/graph/i18n/locale-fr-FR.json
@@ -11,6 +11,24 @@
       "BTN_SHOW_STATS": "Voir les statistiques",
       "BTN_SHOW_DETAILED_STATS": "Statistiques détaillées"
     },
+    "ACCOUNT": {
+      "TITLE": "Statistiques",
+      "BTN_SHOW_STATS": "Voir les statistiques du compte",
+      "BALANCE_DIVIDER": "Situation du compte",
+      "BALANCE_TITLE": "Evolution du compte {{pubkey|formatPubkey}}",
+      "TX_RECEIVED_LABEL": "Recettes",
+      "TX_SENT_LABEL": "Dépenses",
+      "TX_ACCUMULATION_LABEL": "Bilan des transactions",
+      "UD_LABEL": "DU",
+      "UD_ACCUMULATION_LABEL": "Bilan des DU",
+      "BALANCE_LABEL": "Solde",
+      "WOT_DIVIDER": "Toile de confiance",
+      "CERTIFICATION_TITLE": "Nombre de certifications - {{pubkey|formatPubkey}}",
+      "RECEIVED_CERT_LABEL": "Total reçues",
+      "RECEIVED_CERT_DELTA_LABEL": "Variation reçues",
+      "GIVEN_CERT_LABEL": "Total envoyées",
+      "GIVEN_CERT_DELTA_LABEL": "Variation envoyées"
+    },
     "BLOCKCHAIN": {
       "TITLE": "Statistiques",
       "BLOCKS_ISSUERS_DIVIDER": "Analyse de la répartition du calcul",
@@ -24,10 +42,11 @@
       "TX_COUNT_TITLE": "Nombre de transactions écrites",
       "TX_COUNT_LABEL": "Nombre de transactions",
       "TX_AVG_BY_BLOCK": "Nombre moyen de transactions / bloc",
+      "TX_RANGE_DURATION_DIVIDER": "Unité de temps :",
       "TX_RANGE_DURATION": {
-        "HOUR": "Regrouper par <b>heure</b>",
-        "DAY": "Regrouper par <b>jour</b>",
-        "MONTH": "Regrouper par <b>mois</b>"
+        "HOUR": "Heure",
+        "DAY": "Jour",
+        "MONTH": "Mois"
       }
     },
     "CURRENCY": {
diff --git a/www/plugins/graph/js/controllers/account-controllers.js b/www/plugins/graph/js/controllers/account-controllers.js
new file mode 100644
index 0000000000000000000000000000000000000000..85c54ffaba105f878869a5d1cfb922826b8d6fc6
--- /dev/null
+++ b/www/plugins/graph/js/controllers/account-controllers.js
@@ -0,0 +1,477 @@
+
+angular.module('cesium.graph.account.controllers', ['chart.js', 'cesium.graph.services'])
+
+  .config(function($stateProvider, PluginServiceProvider, csConfig) {
+    'ngInject';
+
+    var enable = csConfig.plugins && csConfig.plugins.es;
+    if (enable) {
+
+      PluginServiceProvider
+        .extendState('app.view_wallet_tx', {
+          points: {
+            'buttons': {
+              templateUrl: "plugins/graph/templates/account/view_wallet_tx_extend.html",
+              controller: 'GpExtendCtrl'
+            }
+          }
+        })
+
+        .extendState('app.wot_identity', {
+          points: {
+            'buttons': {
+              templateUrl: "plugins/graph/templates/account/view_identity_extend.html",
+              controller: 'GpExtendCtrl'
+            }
+          }
+        })
+      ;
+
+      $stateProvider
+        .state('app.view_wallet_stats', {
+          url: "/wallet/stats?t&stepUnit",
+          views: {
+            'menuContent': {
+              templateUrl: "plugins/graph/templates/account/view_stats.html"
+            }
+          },
+          data: {
+            auth: true
+          }
+        })
+
+        .state('app.wot_identity_stats', {
+          url: "/wot/:pubkey/stats?t&stepUnit",
+          views: {
+            'menuContent': {
+              templateUrl: "plugins/graph/templates/account/view_stats.html"
+            }
+          }
+        });
+    }
+  })
+
+  .controller('GpExtendCtrl', GpExtendController)
+
+  .controller('GpAccountBalanceCtrl', GpAccountBalanceController)
+
+  .controller('GpAccountCertificationCtrl', GpAccountCertificationController)
+
+;
+
+function GpExtendController($scope, PluginService, esSettings, $state, csWallet) {
+  'ngInject';
+
+  $scope.extensionPoint = PluginService.extensions.points.current.get();
+  $scope.enable = esSettings.isEnable();
+
+  esSettings.api.state.on.changed($scope, function(enable) {
+    $scope.enable = enable;
+  });
+
+  $scope.showIdentityStats = function() {
+    if ($scope.formData && $scope.formData.pubkey) {
+      $state.go('app.wot_identity_stats', {pubkey: $scope.formData.pubkey});
+    }
+  };
+
+  $scope.showWalletStats = function() {
+    if (csWallet.isLogin()) {
+      $state.go('app.wot_identity_stats', {pubkey: csWallet.data.pubkey});
+    }
+  };
+}
+
+
+function GpAccountBalanceController($scope, $controller, $q, $state, $filter, $translate, csWot, gpData, gpColor, csWallet) {
+  'ngInject';
+
+  // Initialize the super class and extend it.
+  angular.extend(this, $controller('GpCurrencyAbstractCtrl', {$scope: $scope}));
+
+  $scope.init = function(e, state) {
+
+      if (state && state.stateParams && state.stateParams.pubkey) { // Currency parameter
+        $scope.formData.pubkey = state.stateParams.pubkey;
+      }
+      else if(csWallet.isLogin()) {
+        $scope.formData.pubkey = csWallet.data.pubkey;
+      }
+
+  };
+
+  $scope.inheritedSetScale = $scope.setScale;
+  $scope.setScale = function(scale) {
+    // linear scale: sent values as negative
+    if (scale === 'linear') {
+      $scope.data[$scope.data.length-2] = _.map($scope.data[$scope.data.length-2], function(value) {
+        return -1 * Math.abs(value);
+      });
+    }
+    // log scale: sent values as positive
+    else {
+      $scope.data[$scope.data.length-2] = _.map($scope.data[$scope.data.length-2], function(value) {
+        return Math.abs(value);
+      });
+    }
+
+    $scope.inheritedSetScale(scale);
+  };
+
+  $scope.load = function(updateTimePct) {
+
+    updateTimePct = angular.isDefined(updateTimePct) ? updateTimePct : true;
+
+    var withUD = true;
+
+    return csWot.load($scope.formData.pubkey)
+      .then(function(identity) {
+        $scope.identity = identity;
+        withUD = $scope.identity.isMember || $scope.identity.wasMember;
+
+        return $q.all([
+
+          $translate('GRAPH.ACCOUNT.BALANCE_TITLE', $scope.formData),
+
+          // translate i18n keys
+          $translate(['GRAPH.ACCOUNT.UD_LABEL',
+            'GRAPH.ACCOUNT.TX_RECEIVED_LABEL',
+            'GRAPH.ACCOUNT.TX_SENT_LABEL',
+            'GRAPH.ACCOUNT.UD_ACCUMULATION_LABEL',
+            'GRAPH.ACCOUNT.TX_ACCUMULATION_LABEL',
+            'GRAPH.ACCOUNT.BALANCE_LABEL',
+            'COMMON.DATE_PATTERN',
+            'COMMON.DATE_SHORT_PATTERN',
+            'COMMON.DATE_MONTH_YEAR_PATTERN']),
+
+          // get data
+          gpData.blockchain.movement($scope.formData.currency, angular.copy($scope.formData))
+        ]);
+      })
+      .then(function(result) {
+        var title = result[0];
+        var translations = result[1];
+        result = result[2];
+
+        if (!result || !result.times) return; // no data
+        $scope.times = result.times;
+
+        var formatInteger = $filter('formatInteger');
+        var formatAmount =  $filter('formatDecimal');
+        $scope.currencySymbol = $filter('currencySymbolNoHtml')($scope.formData.currency, $scope.formData.useRelative);
+
+        // Data
+        $scope.data = [
+          result.ud,
+          result.received,
+          result.sent,
+          result.balance
+        ];
+
+        var displayFormats = {
+          hour: translations['COMMON.DATE_PATTERN'],
+          day: translations['COMMON.DATE_SHORT_PATTERN'],
+          month: translations['COMMON.DATE_MONTH_YEAR_PATTERN']
+        };
+        var displayFormat = displayFormats[$scope.formData.rangeDuration];
+        // Labels
+        $scope.labels = result.times.reduce(function(res, time) {
+          return res.concat(moment.unix(time).local().format(displayFormat));
+        }, []);
+
+        // Colors
+        $scope.colors = gpColor.scale.fix(result.times.length);
+
+        // Update range with received values
+        $scope.updateRange(result.times[0], result.times[result.times.length-1], updateTimePct);
+
+        // Options
+        $scope.options = {
+          responsive: true,
+          maintainAspectRatio: true,
+          title: {
+            display: true,
+            text: title
+          },
+          scales: {
+            yAxes: [
+              {
+                id: 'y-axis-left',
+                type: 'linear',
+                position: 'left',
+                stacked: true
+              }
+            ]
+          },
+          legend: {
+            display: true
+          },
+          tooltips: {
+            enabled: true,
+            mode: 'index',
+            callbacks: {
+              label: function(tooltipItems, data) {
+                return data.datasets[tooltipItems.datasetIndex].label +
+                  ': ' +
+                  (!tooltipItems.yLabel ? '0' :
+                    (formatAmount(tooltipItems.yLabel) + ' ' + $scope.currencySymbol));
+              }
+            }
+          }
+        };
+        $scope.setScale($scope.scale);
+
+        $scope.datasetOverride = [
+          {
+            yAxisID: 'y-axis-left',
+            type: 'bar',
+            label: translations['GRAPH.ACCOUNT.UD_LABEL'],
+            backgroundColor: gpColor.rgba.energized(0.3),
+            hoverBackgroundColor: gpColor.rgba.energized(0.5),
+            borderWidth: 1
+          },
+          {
+            yAxisID: 'y-axis-left',
+            type: 'bar',
+            label: translations['GRAPH.ACCOUNT.TX_RECEIVED_LABEL'],
+            backgroundColor: gpColor.rgba.positive(0.4),
+            hoverBackgroundColor: gpColor.rgba.positive(0.6),
+            borderWidth: 1
+          },
+          {
+            yAxisID: 'y-axis-left',
+            type: 'bar',
+            label: translations['GRAPH.ACCOUNT.TX_SENT_LABEL'],
+            backgroundColor: gpColor.rgba.assertive(0.4),
+            hoverBackgroundColor: gpColor.rgba.assertive(0.6),
+            borderWidth: 1
+          },
+          {
+            yAxisID: 'y-axis-left',
+            type: 'line',
+            label: translations['GRAPH.ACCOUNT.BALANCE_LABEL'],
+            fill: 'origin',
+            borderColor: gpColor.rgba.calm(0.5),
+            borderWidth: 2,
+            pointBackgroundColor: gpColor.rgba.calm(0.5),
+            pointBorderColor: gpColor.rgba.white(),
+            pointHoverBackgroundColor: gpColor.rgba.calm(1),
+            pointHoverBorderColor: 'rgba(0,0,0,0)',
+            pointRadius: 3,
+            lineTension: 0.1
+          }
+        ];
+
+
+        if (!withUD) {
+          // remove UD
+          $scope.data.splice(0,1);
+          $scope.datasetOverride.splice(0,1);
+        }
+        else {
+          // FIXME: fund why UD data not working well
+          // remove UD
+          /*$scope.data.splice(0,1);
+          $scope.datasetOverride.splice(0,1);*/
+        }
+      });
+  };
+
+  $scope.onChartClick = function(data, e, item) {
+    if (!item) return;
+    var from = $scope.times[item._index];
+    var to = moment.unix(from).utc().add(1, $scope.formData.rangeDuration).unix();
+    var query = '_exists_:transactions AND medianTime:>={0} AND medianTime:<{1}'.format(from, to);
+    if ($scope.formData.pubkey) {
+      query += ' AND (transactions.issuers:' + $scope.formData.pubkey + ' OR transactions.outputs:*' + $scope.formData.pubkey + ')';
+    }
+    $state.go('app.blockchain_search', {q: query});
+  };
+}
+
+
+/**
+ * Graph that display received/sent certification
+ */
+function GpAccountCertificationController($scope, $controller, $q, $state, $filter, $translate, gpData, gpColor, csWallet) {
+  'ngInject';
+
+  // Initialize the super class and extend it.
+  angular.extend(this, $controller('GpCurrencyAbstractCtrl', {$scope: $scope}));
+
+  $scope.init = function(e, state) {
+      if (state && state.stateParams && state.stateParams.pubkey) { // Currency parameter
+        $scope.formData.pubkey = state.stateParams.pubkey;
+      }
+      else if(csWallet.isLogin()) {
+        $scope.formData.pubkey = csWallet.data.pubkey;
+      }
+
+      // for DEV only
+      //$scope.formData.pubkey = '38MEAZN68Pz1DTvT3tqgxx4yQP6snJCQhPqEFxbDk4aE';
+  };
+
+  $scope.load = function(updateTimePct) {
+
+    var formData = $scope.formData;
+
+    return $q.all([
+
+      $translate('GRAPH.ACCOUNT.CERTIFICATION_TITLE', formData),
+
+      // translate i18n keys
+      $translate(['GRAPH.ACCOUNT.GIVEN_CERT_LABEL',
+        'GRAPH.ACCOUNT.RECEIVED_CERT_LABEL',
+        'GRAPH.ACCOUNT.GIVEN_CERT_DELTA_LABEL',
+        'GRAPH.ACCOUNT.RECEIVED_CERT_DELTA_LABEL',
+        'COMMON.DATE_PATTERN',
+        'COMMON.DATE_SHORT_PATTERN',
+        'COMMON.DATE_MONTH_YEAR_PATTERN']),
+
+      // get data
+      gpData.wot.certifications(formData)
+    ])
+      .then(function(result) {
+
+        var title = result[0];
+        var translations = result[1];
+        result = result[2];
+
+        if (!result || !result.times) return; // no data
+        $scope.times = result.times;
+
+        var formatInteger = $filter('formatInteger');
+
+        // Data
+        $scope.data = [
+          result.deltaReceived,
+          result.received,
+          result.deltaGiven,
+          result.given
+        ];
+
+        // Labels
+        $scope.labels = result.labels;
+
+        var displayFormats = {
+          hour: translations['COMMON.DATE_PATTERN'],
+          day: translations['COMMON.DATE_SHORT_PATTERN'],
+          month: translations['COMMON.DATE_MONTH_YEAR_PATTERN']
+        };
+        var displayFormat = displayFormats[$scope.formData.rangeDuration];
+        // Labels
+        $scope.labels = result.times.reduce(function(res, time) {
+          return res.concat(moment.unix(time).local().format(displayFormat));
+        }, []);
+
+        // Colors
+        $scope.colors = gpColor.scale.fix(result.times.length);
+
+        // Update options with received values
+        $scope.updateRange(result.times[0], result.times[result.times.length-1], updateTimePct);
+
+        // Options
+        $scope.options = {
+          responsive: true,
+          maintainAspectRatio: true,
+          title: {
+            display: true,
+            text: title
+          },
+          scales: {
+            yAxes: [
+              {
+                id: 'y-axis-left',
+                type: 'linear',
+                position: 'left'
+              },
+              {
+                id: 'y-axis-hide',
+                type: 'linear',
+                display: false,
+                position: 'right'
+              }
+            ]
+          },
+          legend: {
+            display: true
+          },
+          tooltips: {
+            enabled: true,
+            mode: 'index',
+            callbacks: {
+              label: function(tooltipItems, data) {
+                // Should add a '+' before value ?
+                var addPlus = (tooltipItems.datasetIndex === 0 || tooltipItems.datasetIndex === 2) && tooltipItems.yLabel > 0;
+                return data.datasets[tooltipItems.datasetIndex].label +
+                  ': ' +
+                  (addPlus ? '+' : '') +
+                  !tooltipItems.yLabel ? '0' : formatInteger(tooltipItems.yLabel);
+              }
+            }
+          }
+        };
+
+        $scope.datasetOverride = [
+          {
+            yAxisID: 'y-axis-left',
+            type: 'bar',
+            label: translations['GRAPH.ACCOUNT.RECEIVED_CERT_DELTA_LABEL'],
+            borderColor: gpColor.rgba.positive(0.6),
+            borderWidth: 1,
+            backgroundColor: gpColor.rgba.positive(0.4),
+            hoverBackgroundColor: gpColor.rgba.positive(0.6)
+          },
+          {
+            yAxisID: 'y-axis-left',
+            type: 'line',
+            label: translations['GRAPH.ACCOUNT.RECEIVED_CERT_LABEL'],
+            fill: false,
+            borderColor: gpColor.rgba.positive(0.5),
+            borderWidth: 2,
+            backgroundColor: gpColor.rgba.positive(1),
+            pointBackgroundColor: gpColor.rgba.positive(0.5),
+            pointBorderColor: gpColor.rgba.white(),
+            pointHoverBackgroundColor: gpColor.rgba.positive(1),
+            pointHoverBorderColor: 'rgba(0,0,0,0)',
+            pointRadius: 3
+          },
+          {
+            yAxisID: 'y-axis-left',
+            type: 'bar',
+            label: translations['GRAPH.ACCOUNT.GIVEN_CERT_DELTA_LABEL'],
+            borderColor: gpColor.rgba.assertive(0.6),
+            borderWidth: 1,
+            backgroundColor: gpColor.rgba.assertive(0.4),
+            hoverBackgroundColor: gpColor.rgba.assertive(0.6)
+          },
+          {
+            yAxisID: 'y-axis-left',
+            type: 'line',
+            label: translations['GRAPH.ACCOUNT.GIVEN_CERT_LABEL'],
+            fill: false,
+            borderColor: gpColor.rgba.assertive(0.4),
+            borderWidth: 2,
+            backgroundColor: gpColor.rgba.assertive(1),
+            pointBackgroundColor: gpColor.rgba.assertive(0.4),
+            pointBorderColor: gpColor.rgba.white(),
+            pointHoverBackgroundColor: gpColor.rgba.assertive(1),
+            pointHoverBorderColor: 'rgba(0,0,0,0)',
+            pointRadius: 3,
+            lineTension: 0.1
+          }
+        ];
+      });
+  };
+
+  $scope.onChartClick = function(data, e, item) {
+    if (!item) return;
+    var from = $scope.times[item._index];
+    var to = moment.unix(from).utc().add(1, $scope.formData.rangeDuration).unix();
+    var query = '_exists_:transactions AND medianTime:>={0} AND medianTime:<{1}'.format(from, to);
+    if ($scope.formData.pubkey) {
+      query += ' AND (transactions.issuers:' + $scope.formData.pubkey + ' OR transactions.outputs:*' + $scope.formData.pubkey + ')';
+    }
+    $state.go('app.blockchain_search', {q: query});
+  };
+}
diff --git a/www/plugins/graph/js/controllers/blockchain-controllers.js b/www/plugins/graph/js/controllers/blockchain-controllers.js
index a7f0ba1a97ef964a0789d38010c4b4c931dbe983..f1befd6b58af37a47f69fec8aefc8e1d0af35d6b 100644
--- a/www/plugins/graph/js/controllers/blockchain-controllers.js
+++ b/www/plugins/graph/js/controllers/blockchain-controllers.js
@@ -31,61 +31,21 @@ angular.module('cesium.graph.blockchain.controllers', ['chart.js', 'cesium.servi
 ;
 
 
-function GpBlockchainTxCountController($scope, $q, $state, $filter, $translate, $ionicPopover, csCurrency, BMA, esHttp, gpData) {
+function GpBlockchainTxCountController($scope, $controller, $q, $state, $filter, $translate, gpData, gpColor) {
   'ngInject';
 
-  $scope.loading = true;
-  $scope.height=undefined;
-  $scope.width=undefined;
-  $scope.formData = {
-    timePct: 100,
-    useRelative: false /*csSettings.data.useRelative*/
-  };
-
-  // Default TX range duration
-  $scope.txOptions = {
-    rangeDuration: 'day'
-  };
-
-  $scope.enter = function(e, state) {
-    if ($scope.loading) {
-
-      if (state && state.stateParams && state.stateParams.currency) { // Currency parameter
-        $scope.currency = state.stateParams.currency;
-      }
-
-      // Make sure there is currency, or load it not
-      if (!$scope.currency) {
-        return csCurrency.default()
-          .then(function(currency) {
-            $scope.currency = currency ? currency.name : null;
-            return $scope.enter(e, state);
-          });
-      }
-
-      $scope.load()
-        .then(function() {
-          $scope.loading = false;
-        });
-    }
-  };
-  $scope.$on('$ionicParentView.enter', $scope.enter);
+  // Initialize the super class and extend it.
+  angular.extend(this, $controller('GpCurrencyAbstractCtrl', {$scope: $scope}));
 
   $scope.load = function(updateTimePct) {
 
-    updateTimePct = angular.isDefined(updateTimePct) ? updateTimePct : true;
-
-    var truncDate = function(time) {
-      return moment.unix(time).utc().startOf($scope.txOptions.rangeDuration).unix();
-    };
-
-    var txOptions = $scope.txOptions;
+    var formData = $scope.formData;
 
     return $q.all([
 
-      $translate($scope.txOptions.issuer?
+      $translate($scope.formData.issuer?
         'GRAPH.BLOCKCHAIN.TX_AMOUNT_PUBKEY_TITLE':
-        'GRAPH.BLOCKCHAIN.TX_AMOUNT_TITLE', txOptions),
+        'GRAPH.BLOCKCHAIN.TX_AMOUNT_TITLE', formData),
 
       // translate i18n keys
       $translate(['GRAPH.BLOCKCHAIN.TX_AMOUNT_LABEL',
@@ -95,38 +55,25 @@ function GpBlockchainTxCountController($scope, $q, $state, $filter, $translate,
         'COMMON.DATE_SHORT_PATTERN',
         'COMMON.DATE_MONTH_YEAR_PATTERN']),
 
-      // get block #0
-      $scope.firstBlockTime ?
-        $q.when({medianTime: $scope.firstBlockTime}) :
-        BMA.blockchain.block({block: 0})
-          .catch(function(err) {
-            if (err && err.ucode == BMA.errorCodes.BLOCK_NOT_FOUND) {
-              return {medianTime: esHttp.date.now()};
-            }
-          }),
-
       // get data
-      gpData.blockchain.txCount($scope.currency, txOptions)
+      gpData.blockchain.txCount($scope.formData.currency, formData)
     ])
       .then(function(result) {
 
         var title = result[0];
 
         var translations = result[1];
-        $scope.firstBlockTime = $scope.firstBlockTime || result[2].medianTime;
-        $scope.formData.firstBlockTime = $scope.formData.firstBlockTime || truncDate($scope.firstBlockTime);
-        $scope.formData.currencyAge = truncDate(esHttp.date.now()) - $scope.formData.firstBlockTime;
-        result = result[3];
+        result = result[2];
 
         if (!result || !result.times) return; // no data
         $scope.times = result.times;
 
         var formatInteger = $filter('formatInteger');
         var formatAmount =  $filter('formatDecimal');
-        $scope.currencySymbol = $filter('currencySymbolNoHtml')($scope.currency, false/*$scope.formData.useRelative*/);
+        $scope.currencySymbol = $filter('currencySymbolNoHtml')($scope.formData.currency, $scope.formData.useRelative);
 
         // Data
-        if ($scope.txOptions.rangeDuration != 'hour') {
+        if ($scope.formData.rangeDuration != 'hour') {
           $scope.data = [
             result.amount,
             result.count,
@@ -148,27 +95,17 @@ function GpBlockchainTxCountController($scope, $q, $state, $filter, $translate,
           day: translations['COMMON.DATE_SHORT_PATTERN'],
           month: translations['COMMON.DATE_MONTH_YEAR_PATTERN']
         };
-        var displayFormat = displayFormats[$scope.txOptions.rangeDuration];
+        var displayFormat = displayFormats[$scope.formData.rangeDuration];
         // Labels
         $scope.labels = result.times.reduce(function(res, time) {
           return res.concat(moment.unix(time).local().format(displayFormat));
         }, []);
 
         // Colors
-        $scope.colors = result.times.reduce(function(res) {
-          return res.concat('rgba(17,193,243,0.5)');
-        }, []);
+        $scope.colors = gpColor.scale.fix(result.times.length);
 
-        // Update options with received values
-        $scope.txOptions.startTime = result.times[0];
-        $scope.txOptions.endTime = result.times[result.times.length-1];
-        $scope.formData.timeWindow = $scope.formData.timeWindow || $scope.txOptions.endTime - $scope.txOptions.startTime;
-        $scope.formData.rangeDuration = $scope.formData.rangeDuration || $scope.formData.timeWindow / result.times.length;
-
-        if (updateTimePct) {
-          $scope.formData.timePct = Math.ceil(($scope.txOptions.startTime - $scope.formData.firstBlockTime) * 100 /
-            ($scope.formData.currencyAge - $scope.formData.timeWindow));
-        }
+        // Update range options with received values
+        $scope.updateRange(result.times[0], result.times[result.times.length-1], updateTimePct);
 
         // Options
         $scope.options = {
@@ -183,31 +120,19 @@ function GpBlockchainTxCountController($scope, $q, $state, $filter, $translate,
               {
                 id: 'y-axis-amount',
                 type: 'linear',
-                position: 'left',
-                ticks: {
-                  beginAtZero:true,
-                  callback: function(value) {
-                    return formatInteger(value);
-                  }
-                }
+                position: 'left'
               },
               {
                 id: 'y-axis-count',
                 display: false,
                 type: 'linear',
-                position: 'right',
-                ticks: {
-                  beginAtZero:true
-                }
+                position: 'right'
               },
               {
                 id: 'y-axis-avg',
                 display: false,
                 type: 'linear',
-                position: 'right',
-                ticks: {
-                  beginAtZero:true
-                }
+                position: 'right'
               }
             ]
           },
@@ -228,23 +153,25 @@ function GpBlockchainTxCountController($scope, $q, $state, $filter, $translate,
           }
         };
 
+        $scope.setScale($scope.scale);
+
         $scope.datasetOverride = [
           {
             yAxisID: 'y-axis-amount',
             type: 'bar',
             label: translations['GRAPH.BLOCKCHAIN.TX_AMOUNT_LABEL'],
-            hoverBackgroundColor: 'rgba(17,193,243,0.6)'
+            hoverBackgroundColor: gpColor.rgba.calm(0.6)
           },
           {
             yAxisID: 'y-axis-count',
             type: 'line',
             label: translations['GRAPH.BLOCKCHAIN.TX_COUNT_LABEL'],
             fill: false,
-            borderColor: 'rgba(150,150,150,0.5)',
+            borderColor: gpColor.rgba.gray(0.5),
             borderWidth: 2,
-            pointBackgroundColor: 'rgba(150,150,150,0.5)',
-            pointBorderColor: 'rgba(255,255,255,1)',
-            pointHoverBackgroundColor: 'rgba(150,150,150,1)',
+            pointBackgroundColor: gpColor.rgba.gray(0.5),
+            pointBorderColor: gpColor.rgba.white(),
+            pointHoverBackgroundColor: gpColor.rgba.gray(1),
             pointHoverBorderColor: 'rgba(0,0,0,0)',
             pointRadius: 3
           },
@@ -264,122 +191,25 @@ function GpBlockchainTxCountController($scope, $q, $state, $filter, $translate,
       });
   };
 
-  $scope.setSize = function(height, width, maintainAspectRatio) {
-    $scope.height = height;
-    $scope.width = width;
-    $scope.maintainAspectRatio = angular.isDefined(maintainAspectRatio) ? maintainAspectRatio : $scope.maintainAspectRatio;
-  };
-
-  $scope.showTxRange = function(data, e, item) {
-    if (!item) return
+  $scope.onChartClick = function(data, e, item) {
+    if (!item) return;
     var from = $scope.times[item._index];
-    var to = moment.unix(from).utc().add(1, $scope.txOptions.rangeDuration).unix();
+    var to = moment.unix(from).utc().add(1, $scope.formData.rangeDuration).unix();
     var query = '_exists_:transactions AND medianTime:>={0} AND medianTime:<{1}'.format(from, to);
-    if ($scope.txOptions.issuer) {
-      query += ' AND issuer:' + $scope.txOptions.issuer;
+    if ($scope.formData.issuer) {
+      query += ' AND issuer:' + $scope.formData.issuer;
     }
     $state.go('app.blockchain_search', {q: query});
   };
 
-  $scope.setTxRangeDuration = function(txRangeDuration) {
-    $scope.hideActionsPopover();
-    if ($scope.txOptions && txRangeDuration == $scope.txOptions.rangeDuration) return;
-
-    $scope.txOptions.rangeDuration = txRangeDuration;
-
-    // Restore default values
-    delete $scope.txOptions.startTime;
-    delete $scope.txOptions.endTime;
-    $scope.formData = {
-      timePct: 100
-    };
-
-    // Reload TX data
-    $scope.load();
-  };
-
-  $scope.loadPreviousTx = function() {
-    $scope.txOptions.startTime -= $scope.times.length * $scope.formData.rangeDuration;
-    if ($scope.txOptions.startTime < $scope.firstBlockTime) {
-      $scope.txOptions.startTime = $scope.firstBlockTime;
-    }
-    $scope.txOptions.endTime = $scope.txOptions.startTime + $scope.times.length * $scope.formData.rangeDuration;
-    // Reload TX data
-    $scope.load();
-  };
-
-  $scope.loadNextTx = function() {
-    $scope.txOptions.startTime += $scope.times.length * $scope.formData.rangeDuration;
-    if ($scope.txOptions.startTime > $scope.firstBlockTime + $scope.formData.currencyAge - $scope.formData.timeWindow) {
-      $scope.txOptions.startTime = $scope.firstBlockTime + $scope.formData.currencyAge - $scope.formData.timeWindow;
-    }
-    $scope.txOptions.endTime = $scope.txOptions.startTime + $scope.times.length * $scope.formData.rangeDuration;
-    // Reload TX data
-    $scope.load();
-  };
-
-  $scope.onTxTimeChanged = function() {
-    $scope.txOptions.startTime = $scope.firstBlockTime + (parseFloat($scope.formData.timePct) / 100) * ($scope.formData.currencyAge - $scope.formData.timeWindow) ;
-    $scope.txOptions.endTime = $scope.txOptions.startTime + $scope.times.length * $scope.formData.rangeDuration;
-
-    // Reload TX data
-    $scope.load(false);
-  };
-
-  /* -- Popover -- */
-
-  $scope.showTxActionsPopover = function(event) {
-    $scope.hideActionsPopover();
-    $ionicPopover.fromTemplateUrl('plugins/graph/templates/blockchain/popover_tx_actions.html', {
-      scope: $scope
-    }).then(function(popover) {
-      $scope.actionsPopover = popover;
-      //Cleanup the popover when we're done with it!
-      $scope.$on('$destroy', function() {
-        $scope.actionsPopover.remove();
-      });
-      $scope.actionsPopover.show(event);
-    });
-  };
-
-  $scope.hideActionsPopover = function() {
-    if ($scope.actionsPopover) {
-      $scope.actionsPopover.hide();
-    }
-  };
-
 }
 
 
-function GpBlockchainIssuersController($scope, $q, $state, $translate, csCurrency, gpData) {
+function GpBlockchainIssuersController($scope, $controller, $q, $state, $translate, gpColor, gpData) {
   'ngInject';
-  $scope.loading = true;
-  $scope.height = undefined;
-  $scope.width = undefined;
-
-  $scope.enter = function(e, state) {
-    if ($scope.loading) {
-
-      if (state && state.stateParams && state.stateParams.currency) { // Currency parameter
-        $scope.currency = state.stateParams.currency;
-      }
-
-      // Make sure there is currency, or load it not
-      if (!$scope.currency) {
-        return csCurrency.default()
-          .then(function(currency) {
-            $scope.currency = currency ? currency.name : null;
-            return $scope.enter(e, state);
-          });
-      }
-
-      $scope.load()
-        .then(function() {
-          $scope.loading = false;
-        });
-    }
-  };
-  $scope.$on('$ionicParentView.enter', $scope.enter);
+
+  // Initialize the super class and extend it.
+  angular.extend(this, $controller('GpCurrencyAbstractCtrl', {$scope: $scope}));
 
   $scope.load = function() {
     return $q.all([
@@ -387,7 +217,7 @@ function GpBlockchainIssuersController($scope, $q, $state, $translate, csCurrenc
         'GRAPH.BLOCKCHAIN.BLOCKS_ISSUERS_TITLE',
         'GRAPH.BLOCKCHAIN.BLOCKS_ISSUERS_LABEL'
       ]),
-      gpData.blockchain.countByIssuer($scope.currency)
+      gpData.blockchain.countByIssuer($scope.formData.currency)
     ])
       .then(function(result) {
         var translations =  result[0];
@@ -423,18 +253,12 @@ function GpBlockchainIssuersController($scope, $q, $state, $translate, csCurrenc
         };
 
         // Colors
-        $scope.colors = gpData.util.colors.custom(result.data.length);
+        $scope.colors = gpColor.scale.custom(result.data.length);
 
       });
   };
 
-  $scope.setSize = function(height, width, maintainAspectRatio) {
-    $scope.height = height;
-    $scope.width = width;
-    $scope.maintainAspectRatio = angular.isDefined(maintainAspectRatio) ? maintainAspectRatio : $scope.maintainAspectRatio;
-  };
-
-  $scope.showBlockIssuer = function(data, e, item) {
+  $scope.onChartClick = function(data, e, item) {
     if (!item) return;
     var issuer = $scope.issuers[item._index];
     $state.go('app.wot_identity', issuer);
diff --git a/www/plugins/graph/js/controllers/common-controllers.js b/www/plugins/graph/js/controllers/common-controllers.js
new file mode 100644
index 0000000000000000000000000000000000000000..69c80fd5b0c6d0d13d6dadf063f2ffa20133a920
--- /dev/null
+++ b/www/plugins/graph/js/controllers/common-controllers.js
@@ -0,0 +1,254 @@
+
+angular.module('cesium.graph.common.controllers', ['cesium.services'])
+
+  .controller('GpCurrencyAbstractCtrl', GpCurrencyAbstractController)
+;
+
+function GpCurrencyAbstractController($scope, $filter, $ionicPopover, $ionicHistory, $state, csSettings, csCurrency, esHttp) {
+  'ngInject';
+
+  $scope.loading = true;
+  $scope.formData = $scope.formData || {
+    useRelative: csSettings.data.useRelative,
+    timePct: 100,
+    rangeDuration: 'day',
+    firstBlockTime: 0
+  };
+  $scope.formData.useRelative = false; /*angular.isDefined($scope.formData.useRelative) ?
+    $scope.formData.useRelative : csSettings.data.useRelative;*/
+  $scope.scale = 'linear';
+  $scope.height = undefined;
+  $scope.width = undefined;
+  $scope.maintainAspectRatio = true;
+  $scope.times = [];
+
+  function _truncDate(time) {
+    return moment.unix(time).utc().startOf($scope.formData.rangeDuration).unix();
+  }
+
+  $scope.enter = function (e, state) {
+    if ($scope.loading) {
+
+      if (state && state.stateParams) {
+        // remember state, to be able to refresh location
+        $scope.stateName = state && state.stateName;
+        $scope.stateParams = angular.copy(state && state.stateParams||{});
+
+        if (!$scope.formData.currency && state && state.stateParams && state.stateParams.currency) { // Currency parameter
+          $scope.formData.currency = state.stateParams.currency;
+        }
+        if (state.stateParams.timePct) {
+          $scope.formData.timePct = state.stateParams.timePct;
+        }
+        if (state.stateParams.group) {
+          $scope.formData.rangeDuration = state.stateParams.group;
+        }
+      }
+
+      $scope.init(e, state);
+
+      // Make sure there is currency, or load it not
+      if (!$scope.formData.currency) {
+        return csCurrency.get()
+          .then(function (currency) {
+            $scope.formData.currency = currency ? currency.name : null;
+            $scope.formData.firstBlockTime = currency ? _truncDate(currency.firstBlockTime) : 0;
+            if (!$scope.formData.firstBlockTime){
+              console.warn('[graph] currency.firstBlockTime not loaded ! Should have been loaded by currrency service!');
+            }
+            $scope.formData.currencyAge = _truncDate(esHttp.date.now()) - $scope.formData.firstBlockTime;
+            return $scope.enter(e, state);
+          });
+      }
+
+      $scope.load()
+        .then(function () {
+          $scope.loading = false;
+        });
+    }
+  };
+  $scope.$on('$csExtension.enter', $scope.enter);
+  $scope.$on('$ionicParentView.enter', $scope.enter);
+
+  $scope.updateLocation = function() {
+    $ionicHistory.nextViewOptions({
+      disableAnimate: true,
+      disableBack: true,
+      historyRoot: true
+    });
+
+    $scope.stateParams = $scope.stateParams || {};
+    $scope.stateParams.t = $scope.formData.timePct < 100 || $scope.formData.timePct >= 0 ? $scope.formData.timePct : undefined;
+    $scope.stateParams.stepUnit = $scope.formData.rangeDuration != 'day' ? $scope.formData.rangeDuration : undefined;
+
+    $state.go($scope.stateName, $scope.stateParams, {
+      reload: false,
+      inherit: true,
+      notify: false}
+    );
+  };
+
+  // Allow to fixe size, form a template (e.g. in a 'ng-init' tag)
+  $scope.setSize = function(height, width, maintainAspectRatio) {
+    $scope.height = height;
+    $scope.width = width;
+    $scope.maintainAspectRatio = angular.isDefined(maintainAspectRatio) ? maintainAspectRatio : $scope.maintainAspectRatio;
+  };
+
+  // When parent view execute a refresh action
+  $scope.$on('csView.action.refresh', function(event, context) {
+    if (!context || context == 'currency') {
+      return $scope.load();
+    }
+  });
+
+  $scope.init = function(stateParams) {
+    // Should be override by subclasses
+  };
+
+  $scope.load = function() {
+    // Should be override by subclasses
+  };
+
+  $scope.toggleScale = function() {
+    $scope.setScale($scope.scale === 'linear' ? 'logarithmic' : 'linear');
+  };
+
+  $scope.setScale = function(scale) {
+    $scope.hideActionsPopover();
+    $scope.scale = scale;
+
+    var format = $filter('formatInteger');
+
+    _.forEach($scope.options.scales.yAxes, function(yAxe) {
+      yAxe.type = scale;
+      yAxe.ticks = yAxe.ticks || {};
+      if (scale == 'linear') {
+        yAxe.ticks.beginAtZero = true;
+        delete yAxe.ticks.min;
+        yAxe.ticks.callback = function(value) {
+          return format(value);
+        };
+      }
+      else {
+        //yAxe.ticks.min = 0;
+        delete yAxe.ticks.beginAtZero;
+        delete yAxe.ticks.callback;
+        yAxe.ticks.callback = function(value, index) {
+          if (!value) return;
+          if (Math.log10(value)%1 === 0 || Math.log10(value/3)%1 === 0) {
+            return format(value);
+          }
+          return '';
+        };
+      }
+    });
+  };
+
+  $scope.setRangeDuration = function(rangeDuration) {
+    $scope.hideActionsPopover();
+    if ($scope.formData && rangeDuration == $scope.formData.rangeDuration) return;
+
+    $scope.formData.rangeDuration = rangeDuration;
+
+    // Restore default values
+    delete $scope.formData.startTime;
+    delete $scope.formData.endTime;
+    delete $scope.formData.rangeDurationSec;
+    //$scope.formData.timePct = 100;
+
+    // Reload data
+    $scope.load();
+    // Update location
+    $scope.updateLocation();
+  };
+
+  $scope.goPreviousRange = function() {
+    if ($scope.loading) return;
+    $scope.loading = true;
+
+    $scope.formData.startTime -= $scope.times.length * $scope.formData.rangeDurationSec;
+    if ($scope.formData.startTime < $scope.formData.firstBlockTime) {
+      $scope.formData.startTime = $scope.formData.firstBlockTime;
+    }
+    $scope.formData.endTime = $scope.formData.startTime + $scope.times.length * $scope.formData.rangeDurationSec;
+
+    // Reload data
+    $scope.load().then(function(){
+      // Update location
+      $scope.updateLocation();
+
+      $scope.loading = false;
+    });
+  };
+
+  $scope.goNextRange = function() {
+    if ($scope.loading) return;
+    $scope.loading = true;
+    $scope.formData.startTime += $scope.times.length * $scope.formData.rangeDurationSec;
+    if ($scope.formData.startTime > $scope.formData.firstBlockTime + $scope.formData.currencyAge - $scope.formData.timeWindow) {
+      $scope.formData.startTime = $scope.formData.firstBlockTime + $scope.formData.currencyAge - $scope.formData.timeWindow;
+    }
+    $scope.formData.endTime = $scope.formData.startTime + $scope.times.length * $scope.formData.rangeDurationSec;
+
+    // Reload data
+    $scope.load().then(function(){
+      // Update location
+      $scope.updateLocation();
+
+      $scope.loading = false;
+    });
+  };
+
+  $scope.onRangeChanged = function() {
+    if ($scope.loading) return;
+    $scope.loading = true;
+
+    $scope.formData.startTime = $scope.formData.firstBlockTime + (parseFloat($scope.formData.timePct) / 100) * ($scope.formData.currencyAge - $scope.formData.timeWindow) ;
+    $scope.formData.endTime = $scope.formData.startTime + $scope.times.length * $scope.formData.rangeDurationSec;
+
+    // Reload data
+    $scope.load().then(function(){
+      // Update location
+      $scope.updateLocation();
+
+      $scope.loading = false;
+    });
+  };
+
+  $scope.updateRange = function(startTime, endTime, updateTimePct) {
+    updateTimePct = angular.isDefined(updateTimePct) ? updateTimePct : true;
+
+    $scope.formData.startTime = startTime;
+    $scope.formData.endTime = endTime;
+    $scope.formData.timeWindow = $scope.formData.timeWindow || $scope.formData.endTime - $scope.formData.startTime;
+    $scope.formData.rangeDurationSec = $scope.formData.rangeDurationSec || $scope.formData.timeWindow / ($scope.times.length-1);
+
+    if (updateTimePct) {
+      $scope.formData.timePct = Math.ceil(($scope.formData.startTime - $scope.formData.firstBlockTime) * 100 /
+        ($scope.formData.currencyAge - $scope.formData.timeWindow));
+    }
+  };
+
+  /* -- Popover -- */
+
+  $scope.showActionsPopover = function(event) {
+    $scope.hideActionsPopover();
+    $ionicPopover.fromTemplateUrl('plugins/graph/templates/common/popover_range_actions.html', {
+      scope: $scope
+    }).then(function(popover) {
+      $scope.actionsPopover = popover;
+      //Cleanup the popover when we're done with it!
+      $scope.$on('$destroy', function() {
+        $scope.actionsPopover.remove();
+      });
+      $scope.actionsPopover.show(event);
+    });
+  };
+
+  $scope.hideActionsPopover = function() {
+    if ($scope.actionsPopover) {
+      $scope.actionsPopover.hide();
+    }
+  };
+}
diff --git a/www/plugins/graph/js/controllers/currency-controllers.js b/www/plugins/graph/js/controllers/currency-controllers.js
index 056588024fcd84c5e42f33e97f8894e6c0e353fd..aaf200e9b7ef3034ae93efa5fc0f3968010a6f96 100644
--- a/www/plugins/graph/js/controllers/currency-controllers.js
+++ b/www/plugins/graph/js/controllers/currency-controllers.js
@@ -1,5 +1,5 @@
 
-angular.module('cesium.graph.currency.controllers', ['chart.js', 'cesium.graph.services', 'cesium.graph.blockchain.controllers'])
+angular.module('cesium.graph.currency.controllers', ['chart.js', 'cesium.graph.services', 'cesium.graph.common.controllers'])
 
   .config(function($stateProvider, PluginServiceProvider, csConfig) {
     'ngInject';
@@ -82,8 +82,6 @@ angular.module('cesium.graph.currency.controllers', ['chart.js', 'cesium.graph.s
 
   .controller('GpCurrencyViewExtendCtrl', GpCurrencyViewExtendController)
 
-  .controller('GpCurrencyAbstractCtrl', GpCurrencyAbstractController)
-
   .controller('GpCurrencyMonetaryMassCtrl', GpCurrencyMonetaryMassController)
 
   .controller('GpCurrencyDUCtrl', GpCurrencyDUController)
@@ -103,63 +101,7 @@ function GpCurrencyViewExtendController($scope, PluginService, UIUtils, esSettin
   });
 }
 
-
-
-function GpCurrencyAbstractController($scope, csCurrency) {
-  'ngInject';
-
-  $scope.loading = true;
-  $scope.formData = $scope.formData || {};
-  $scope.height = undefined;
-  $scope.width = undefined;
-  $scope.maintainAspectRatio = true;
-
-  $scope.enter = function (e, state) {
-    if ($scope.loading) {
-
-      if (!$scope.formData.currency && state && state.stateParams && state.stateParams.currency) { // Currency parameter
-        $scope.formData.currency = state.stateParams.currency;
-      }
-
-      // Make sure there is currency, or load it not
-      if (!$scope.formData.currency) {
-        return csCurrency.default()
-          .then(function (currency) {
-            $scope.formData.currency = currency ? currency.name : null;
-            return $scope.enter(e, state);
-          });
-      }
-
-      $scope.load()
-        .then(function () {
-          $scope.loading = false;
-        });
-    }
-  };
-  $scope.$on('$csExtension.enter', $scope.enter);
-  $scope.$on('$ionicParentView.enter', $scope.enter);
-
-  // Allow to fixe size, form a template (e.g. in a 'ng-init' tag)
-  $scope.setSize = function(height, width, maintainAspectRatio) {
-    $scope.height = height;
-    $scope.width = width;
-    $scope.maintainAspectRatio = angular.isDefined(maintainAspectRatio) ? maintainAspectRatio : $scope.maintainAspectRatio;
-  };
-
-  // When parent view execute a refresh action
-  $scope.$on('csView.action.refresh', function(event, context) {
-    if (!context || context == 'currency') {
-      return $scope.load();
-    }
-  });
-
-  $scope.load = function() {
-    // Should be override by subclasses
-  };
-
-}
-
-function GpCurrencyMonetaryMassController($scope, $controller, $q, $state, $translate, $ionicPopover, gpData, $filter, csSettings) {
+function GpCurrencyMonetaryMassController($scope, $controller, $q, $state, $translate, $ionicPopover, gpColor, gpData, $filter, csSettings) {
   'ngInject';
 
   // Initialize the super class and extend it.
@@ -168,7 +110,6 @@ function GpCurrencyMonetaryMassController($scope, $controller, $q, $state, $tran
   $scope.formData.useRelative = angular.isDefined($scope.formData.useRelative) ?
     $scope.formData.useRelative :
     csSettings.data.useRelative;
-  $scope.scale = 'linear';
   $scope.displayShareAxis = true;
 
   $scope.onUseRelativeChanged = function() {
@@ -198,10 +139,11 @@ function GpCurrencyMonetaryMassController($scope, $controller, $q, $state, $tran
       .then(function(result) {
         var translations = result[0];
         result = result[1];
-        if (!result || !result.blocks) return;
+        if (!result || !result.times) return;
+        $scope.times = result.times;
 
         // Choose a date formatter, depending on the blocks period
-        var blocksPeriod = result.blocks[result.blocks.length-1].medianTime - result.blocks[0].medianTime;
+        var blocksPeriod = result.times[result.times.length-1] - result.times[0];
         var formatDate;
         if (blocksPeriod < 15778800/* less than 6 months*/) {
           formatDate = $filter('formatDateShort');
@@ -247,14 +189,12 @@ function GpCurrencyMonetaryMassController($scope, $controller, $q, $state, $tran
         $scope.data = data;
 
         // Labels
-        $scope.labels = result.labels.reduce(function(res, time) {
+        $scope.labels = result.times.reduce(function(res, time) {
           return res.concat(formatDate(time));
         }, []);
 
         // Colors
-        $scope.colors = result.blocks.reduce(function(res) {
-          return res.concat('rgba(17,193,243,0.5)');
-        }, []);
+        $scope.colors = gpColor.scale.fix(result.times.length);
 
         // Options
         $scope.options = {
@@ -264,6 +204,9 @@ function GpCurrencyMonetaryMassController($scope, $controller, $q, $state, $tran
             display: true,
             text: translations['GRAPH.CURRENCY.MONETARY_MASS_TITLE']
           },
+          legend: {
+            display: $scope.displayShareAxis
+          },
           scales: {
             yAxes: [
               {
@@ -293,9 +236,10 @@ function GpCurrencyMonetaryMassController($scope, $controller, $q, $state, $tran
         $scope.datasetOverride = [
           {
             yAxisID: 'y-axis-mass',
-            type: 'bar',
+            type: 'line',
             label: translations['GRAPH.CURRENCY.MONETARY_MASS_LABEL'],
-            hoverBackgroundColor: 'rgba(17,193,243,0.6)'
+            hoverBackgroundColor: gpColor.rgba.calm(0.6),
+            borderWidth: 1
           },
           {
             yAxisID: 'y-axis-mn',
@@ -305,6 +249,7 @@ function GpCurrencyMonetaryMassController($scope, $controller, $q, $state, $tran
             showLine: true,
             borderColor: 'rgba(255,201,0,1)',
             borderWidth: 2,
+            backgroundColor: 'rgba(255,201,0,1)',
             pointBackgroundColor: 'rgba(255,201,0,1)',
             pointBorderColor: 'rgba(255,255,255,1)',
             pointHoverBackgroundColor: 'rgba(255,201,0,1)',
@@ -320,44 +265,12 @@ function GpCurrencyMonetaryMassController($scope, $controller, $q, $state, $tran
 
   };
 
-  $scope.showBlock = function(data, e, item) {
+  $scope.onChartClick = function(data, e, item) {
     if (!item) return;
     var number = $scope.blocks[item._index];
     $state.go('app.view_block', {number: number});
   };
 
-  $scope.setScale = function(scale) {
-    $scope.hideActionsPopover();
-    $scope.scale = scale;
-
-    var format = $filter('formatInteger');
-
-    _.forEach($scope.options.scales.yAxes, function(yAxe) {
-      yAxe.type = scale;
-      yAxe.ticks = yAxe.ticks || {};
-      if (scale == 'linear') {
-        yAxe.ticks.beginAtZero = true;
-        delete yAxe.ticks.min;
-        yAxe.ticks.callback = function(value) {
-          return format(value);
-        };
-      }
-      else {
-        yAxe.ticks.min = 0;
-        delete yAxe.ticks.beginAtZero;
-        delete yAxe.ticks.callback;
-        yAxe.ticks.callback = function(value, index) {
-          if (!value) return;
-          //console.log(value + '->' + Math.log10(value)%1);
-          if (Math.log10(value)%1 === 0 || Math.log10(value/3)%1 === 0) {
-            return format(value);
-          }
-          return '';
-        };
-      }
-    });
-  };
-
   /* -- Popover -- */
 
   $scope.showActionsPopover = function(event) {
@@ -403,10 +316,11 @@ function GpCurrencyDUController($scope, $q, $controller, $translate, gpData, $fi
       .then(function(result) {
         var translations = result[0];
         result = result[1];
-        if (!result || !result.blocks) return;
+        if (!result || !result.times) return;
+        $scope.times = result.times;
 
         // Choose a date formatter, depending on the blocks period
-        var blocksPeriod = result.blocks[result.blocks.length-1].medianTime - result.blocks[0].medianTime;
+        var blocksPeriod = result.times[result.times.length-1] - result.times[0];
         var dateFilter;
         if (blocksPeriod < 15778800/* less than 6 months*/) {
           dateFilter = $filter('formatDateShort');
@@ -426,7 +340,7 @@ function GpCurrencyDUController($scope, $q, $controller, $translate, gpData, $fi
         ];
 
         // Labels
-        $scope.labels = result.labels.reduce(function(res, time) {
+        $scope.labels = result.times.reduce(function(res, time) {
           return res.concat(dateFilter(time));
         }, []);
 
@@ -485,7 +399,7 @@ function GpCurrencyDUController($scope, $q, $controller, $translate, gpData, $fi
 }
 
 
-function GpCurrencyMembersCountController($scope, $controller, $q, $state, $translate, gpData, $filter) {
+function GpCurrencyMembersCountController($scope, $controller, $q, $state, $translate, gpColor, gpData, $filter) {
   'ngInject';
 
   // Initialize the super class and extend it.
@@ -506,10 +420,12 @@ function GpCurrencyMembersCountController($scope, $controller, $q, $state, $tran
       .then(function(result) {
         var translations = result[0];
         result = result[1];
-        if (!result || !result.blocks) return;
+
+        if (!result || !result.times) return;
+        $scope.times = result.times;
 
         // Choose a date formatter, depending on the blocks period
-        var blocksPeriod = result.blocks[result.blocks.length-1].medianTime - result.blocks[0].medianTime;
+        var blocksPeriod = result.times[result.blocks.length-1] - result.times[0].medianTime;
         var dateFormat;
         if (blocksPeriod < 15778800/* less than 6 months*/) {
           dateFormat = $filter('formatDateShort');
@@ -519,7 +435,7 @@ function GpCurrencyMembersCountController($scope, $controller, $q, $state, $tran
         }
 
         // Format time
-        $scope.labels = result.labels.reduce(function(res, time) {
+        $scope.labels = result.times.reduce(function(res, time) {
           return res.concat(dateFormat(time));
         }, []);
 
@@ -558,24 +474,17 @@ function GpCurrencyMembersCountController($scope, $controller, $q, $state, $tran
         ];
 
         // Colors
-        $scope.colors = result.blocks.reduce(function(res) {
-          return res.concat('rgba(17,193,243,0.5)');
-        }, []);
-
-        // Keep times (need for click)
-        $scope.blockTimes = result.blocks.reduce(function(res, block) {
-          return res.concat(block.medianTime);
-        }, []);
+        $scope.colors = gpColor.scale.fix(result.blocks.length);
       });
   };
 
-  $scope.showBlock = function(data, e, item) {
+  $scope.onChartClick = function(data, e, item) {
     if (!item) return;
     if (!item._index) {
       $state.go('app.view_block', {number: 0});
       return;
     }
-    var from = $scope.blockTimes[item._index-1];
+    var from = $scope.times[item._index-1];
     var to = moment.unix(from).utc().add(1, 'day').unix();
     $state.go('app.blockchain_search', {
       q: '(_exists_:joiners OR _exists_:leavers OR _exists_:revoked OR _exists_:excluded) AND medianTime:>{0} AND medianTime:<={1}'.format(from, to)
diff --git a/www/plugins/graph/js/controllers/network-controllers.js b/www/plugins/graph/js/controllers/network-controllers.js
index 89e9ff08db1dd513ca03fb40a1d488c79f63376c..5610d4a28989bcb2b8cff2dc6e721558fb5c074a 100644
--- a/www/plugins/graph/js/controllers/network-controllers.js
+++ b/www/plugins/graph/js/controllers/network-controllers.js
@@ -59,7 +59,7 @@ function GpNetworkViewExtendController($scope, PluginService, esSettings) {
   });
 }
 
-function GpPeerViewExtendController($scope, $q, $timeout, PluginService, esSettings, csCurrency, gpData) {
+function GpPeerViewExtendController($scope, $timeout, PluginService, esSettings, csCurrency, gpData) {
   'ngInject';
 
   $scope.extensionPoint = PluginService.extensions.points.current.get();
@@ -84,7 +84,7 @@ function GpPeerViewExtendController($scope, $q, $timeout, PluginService, esSetti
 
     // Make sure there is currency, or load if not
     if (!$scope.node.currency) {
-      return csCurrency.default()
+      return csCurrency.get()
         .then(function(currency) {
           $scope.node.currency = currency ? currency.name : null;
           return $scope.enter(e, state);
@@ -133,7 +133,7 @@ function GpPeerStatsController($scope, $controller, csCurrency) {
 
       // Make sure there is currency, or load it not
       if (!$scope.currency) {
-        return csCurrency.default()
+        return csCurrency.get()
           .then(function(currency) {
             $scope.currency = currency ? currency.name : null;
             return $scope.enter(e, state);
diff --git a/www/plugins/graph/js/plugin.js b/www/plugins/graph/js/plugin.js
index e2d4965ea4e3b7f547e7fa709061be3bee4cbf48..baa6ca01317f4d4f46d539cc1ed0bbb2a5d299c2 100644
--- a/www/plugins/graph/js/plugin.js
+++ b/www/plugins/graph/js/plugin.js
@@ -3,8 +3,10 @@ angular.module('cesium.graph.plugin', [
     // Services
     'cesium.graph.services',
     // Controllers
+    'cesium.graph.common.controllers',
     'cesium.graph.blockchain.controllers',
     'cesium.graph.network.controllers',
-    'cesium.graph.currency.controllers'
+    'cesium.graph.currency.controllers',
+    'cesium.graph.account.controllers'
   ])
 ;
diff --git a/www/plugins/graph/js/services.js b/www/plugins/graph/js/services.js
index 6cae46c6948f4d5cb752c78b6c91e03699951e61..ac325d0c5568336f71bb25e2010cb8a76e8af2be 100644
--- a/www/plugins/graph/js/services.js
+++ b/www/plugins/graph/js/services.js
@@ -1,6 +1,7 @@
 
 angular.module('cesium.graph.services', [
     // Services
+    'cesium.graph.color.services',
     'cesium.graph.data.services'
   ])
 ;
diff --git a/www/plugins/graph/js/services/color-services.js b/www/plugins/graph/js/services/color-services.js
new file mode 100644
index 0000000000000000000000000000000000000000..d123e545ae14f463c9717faf8b0fd0f2531d8e4f
--- /dev/null
+++ b/www/plugins/graph/js/services/color-services.js
@@ -0,0 +1,138 @@
+angular.module('cesium.graph.color.services', [])
+
+  .factory('gpColor', function($rootScope) {
+    'ngInject';
+
+    var
+      constants = {
+        css2Rgb: {
+          'white': [255, 255, 255],
+          'assertive': [239, 71, 58], // ok
+          'calm': [17, 193, 243], // ok
+          'positive': [56, 126, 245], // ok
+          'balanced': [51, 205, 95], // ok
+          'energized': [255, 201, 0], // ok
+          'royal': [136, 106, 234], // ok
+          'gray': [150, 150, 150], // ok
+          'stable': [248, 248, 248] // ok
+        }
+      },
+      exports = {
+        scale: {}
+      };
+
+
+    /**
+     * Compute colors scale
+     * @param count
+     * @param opacity
+     * @param startColor
+     * @param startState
+     * @returns {Array}
+     */
+    exports.scale.custom = function (count, opacity, startColor, startState) {
+
+      function _state2side(state) {
+        switch (state) {
+          case 0:
+            return 0;
+          case 1:
+            return -1;
+          case 2:
+            return 0;
+          case 3:
+            return 1;
+        }
+      }
+
+      // From [0,1]
+      opacity = opacity>0 && opacity|| '0.55';
+
+      var defaultStateSize = Math.round(count / 2.5/*=4 states max*/);
+
+      // Start color [r,v,b]
+      var color = startColor ? angular.copy(startColor) : [255, 0, 0]; // Red
+
+      // Colors state: 0=keep, 1=decrease, 2=keep, 3=increase
+      var states = startState ? angular.copy(startState) : [0, 2, 3]; // R=keep, V=keep, B=increase
+
+      var steps = startColor ? [
+        Math.round(255 / defaultStateSize),
+        Math.round(255 / defaultStateSize),
+        Math.round(255 / defaultStateSize)
+      ] : [
+        Math.round((color[0] - 50) / defaultStateSize),
+        Math.round((255 - color[1]) / defaultStateSize),
+        Math.round((255 - color[2]) / defaultStateSize)
+      ];
+
+
+      // Compute start sides (1=increase, 0=flat, -1=decrease)
+      var sides = [
+        _state2side(states[0]),
+        _state2side(states[1]),
+        _state2side(states[2])];
+
+      // Use to detect when need to change a 'flat' state (when state = 0 or 2)
+      var stateCounters = [0, 0, 0];
+
+      var result = [];
+      for (var i = 0; i < count; i++) {
+        for (var j = 0; j < 3; j++) {
+          color[j] += sides[j] * steps[j];
+          stateCounters[j]++;
+          // color has reach a limit
+          if (((color[j] <= 0 || color[j] >= 255) && sides[j] !== 0) ||
+            (sides[j] === 0 && stateCounters[j] == defaultStateSize)) {
+            // Max sure not overflow limit
+            if (color[j] <= 0) {
+              color[j] = 0;
+            }
+            else if (color[j] >= 255) {
+              color[j] = 255;
+            }
+            // Go to the next state, in [0..3]
+            states[j] = (states[j] + 1) % 4;
+
+            // Update side from this new state
+            sides[j] = _state2side(states[j]);
+
+            // Reset state counter
+            stateCounters[j] = 0;
+          }
+        }
+
+        // Add the color to result
+        result.push('rgba(' + color[0] + ',' + color[1] + ',' + color[2] + ',' + opacity + ')');
+
+      }
+      return result;
+    };
+
+    exports.scale.default = function () {
+      return exports.scale.custom(25);
+    };
+
+    /**
+     * Create a array with the given color
+     **/
+    exports.scale.fix = function (length, color) {
+      return Array.apply(null, Array(length||25))
+        .map(String.prototype.valueOf, color||exports.rgba.calm(0.5));
+    };
+
+    // Create a function to generate a rgba string, from
+    exports.rgba = _.mapObject(constants.css2Rgb, function(rgbArray){
+      var prefix = 'rgba(' + rgbArray.join(',') + ',';
+      return function(opacity){
+        if (!opacity || opacity < 0) {
+          return 'rgb(' + rgbArray.join(',') + ')';
+        }
+        return prefix + opacity + ')';
+      };
+    });
+
+    return exports;
+  })
+
+;
diff --git a/www/plugins/graph/js/services/data-services.js b/www/plugins/graph/js/services/data-services.js
index ddd2d7733e9e3c70f410147fd9ae27e70e9dc312..b2c6677bb9a96cd91851506f551a6ec03be67ec2 100644
--- a/www/plugins/graph/js/services/data-services.js
+++ b/www/plugins/graph/js/services/data-services.js
@@ -1,119 +1,72 @@
 angular.module('cesium.graph.data.services', ['cesium.wot.services', 'cesium.es.http.services'])
 
-  .factory('gpData', function($rootScope, $q, $timeout, esHttp, BMA, csWot, csCache) {
+  .factory('gpData', function($rootScope, $q, $timeout, esHttp, BMA, csWot, csCache, csCurrency) {
     'ngInject';
 
     var
       currencyCache = csCache.get('gpData-currency-', csCache.constants.SHORT),
       exports = {
         node: {},
+        wot: {},
         blockchain: {},
-        util: {
-          colors: {}
-        },
         raw: {
           block: {
             search: esHttp.post('/:currency/block/_search')
           },
           blockstat: {
-            search: esHttp.post('/:currency/blockstat/_search?pretty')
+            search: esHttp.post('/:currency/blockstat/_search')
+          },
+          movement: {
+            search: esHttp.post('/:currency/movement/_search')
+          },
+          user: {
+            event: esHttp.post('/user/event/_search?pretty')
           }
         },
         regex: {
         }
       };
 
+      function onCurrencyLoad(data, deferred) {
+        deferred = deferred || $q.defer();
+        var currency = data.currencies[data.currencies.length-1];
 
-    /**
-     * Compute colors scale
-     * @param count
-     * @param opacity
-     * @param startColor
-     * @param startState
-     * @returns {Array}
-     */
-    exports.util.colors.custom = function(count, opacity, startColor, startState) {
-
-      function _state2side(state) {
-        switch(state) {
-          case 0:
-            return 0;
-          case 1:
-            return -1;
-          case 2:
-            return 0;
-          case 3:
-            return 1;
+        if (currency.firstBlockTime) {
+          deferred.resolve();
+          return deferred.promise;
         }
+        // Fill first block time value
+        BMA.blockchain.block({block: 0})
+            .then(function(block) {
+              currency.firstBlockTime = block.medianTime;
+              deferred.resolve();
+            })
+            .catch(function(err) {
+              if (err && err.ucode == BMA.errorCodes.BLOCK_NOT_FOUND) {
+                currency.firstBlockTime = esHttp.date.now();
+                deferred.resolve();
+              }
+              deferred.reject(err);
+            });
+        return deferred.promise;
       }
 
-      // From [0,1]
-      opacity = opacity || '0.55';
-
-      var defaultStateSize = Math.round(count / 2.5/*=4 states max*/);
-
-      // Start color [r,v,b]
-      var color = startColor ? angular.copy(startColor) : [255,0,0]; // Red
-
-      // Colors state: 0=keep, 1=decrease, 2=keep, 3=increase
-      var states = startState ? angular.copy(startState) : [0,2,3]; // R=keep, V=keep, B=increase
-
-      var steps = startColor ? [
-        Math.round(255 / defaultStateSize),
-        Math.round(255 / defaultStateSize),
-        Math.round(255 / defaultStateSize)
-      ] : [
-        Math.round((color[0]-50) / defaultStateSize),
-        Math.round((255-color[1]) / defaultStateSize),
-        Math.round((255-color[2]) / defaultStateSize)
-      ];
-
-
-      // Compute start sides (1=increase, 0=flat, -1=decrease)
-      var sides = [
-        _state2side(states[0]),
-        _state2side(states[1]),
-        _state2side(states[2])];
-
-      // Use to detect when need to change a 'flat' state (when state = 0 or 2)
-      var stateCounters  = [0,0,0];
-
-      var result = [];
-      for (var i = 0; i<count; i++) {
-        for (var j=0; j<3;j++) {
-          color[j] +=  sides[j] * steps[j];
-          stateCounters[j]++;
-          // color has reach a limit
-          if (((color[j] <= 0 || color[j] >= 255) && sides[j] !== 0) ||
-            (sides[j] === 0 && stateCounters[j] == defaultStateSize)) {
-            // Max sure not overflow limit
-            if (color[j] <= 0) {
-              color[j] = 0;
-            }
-            else if (color[j] >= 255) {
-              color[j] = 255;
-            }
-            // Go to the next state, in [0..3]
-            states[j] = (states[j] + 1) % 4;
-
-            // Update side from this new state
-            sides[j] = _state2side(states[j]);
-
-            // Reset state counter
-            stateCounters[j] = 0;
-          }
-        }
 
-        // Add the color to result
-        result.push('rgba(' + color[0] + ',' + color[1] + ',' + color[2] + ',' + opacity+')');
+    function _powBase(amount, base) {
+      return base <= 0 ? amount : amount * Math.pow(10, base);
+    }
 
-      }
-      return result;
-    };
+    function _initRangeOptions(options) {
+      options = options || {};
+      options.maxRangeSize = options.maxRangeSize || 30;
+      options.defaultTotalRangeCount = options.defaultTotalRangeCount || options.maxRangeSize*2;
 
-    exports.util.colors.default = function() {
-      return exports.util.colors.custom(25);
-    };
+      options.rangeDuration = options.rangeDuration || 'day';
+      options.endTime = options.endTime || moment().utc().add(1, options.rangeDuration).unix();
+      options.startTime = options.startTime ||
+        moment.unix(options.endTime).utc().subtract(options.defaultTotalRangeCount, options.rangeDuration).unix();
+      return options;
+    }
 
     /**
      * Graph: "blocks count by issuer"
@@ -188,10 +141,6 @@ angular.module('cesium.graph.data.services', ['cesium.wot.services', 'cesium.es.
         }
       }
 
-      function _powBase(amount, base) {
-        return base <= 0 ? amount : amount * Math.pow(10, base);
-      }
-
       var request = {
         query: {
           filtered: {
@@ -255,7 +204,7 @@ angular.module('cesium.graph.data.services', ['cesium.wot.services', 'cesium.es.
             }
           }
 
-          result.labels = result.blocks.reduce(function(res, block){
+          result.times = result.blocks.reduce(function(res, block){
             return res.concat(block.medianTime);
           }, []);
 
@@ -275,20 +224,14 @@ angular.module('cesium.graph.data.services', ['cesium.wot.services', 'cesium.es.
      */
     exports.blockchain.txCount = function(currency, options) {
 
-      var maxRangeSize = 30;
-      var defaultTotalRangeCount = maxRangeSize*2;
-
-      options = options || {};
-      options.rangeDuration = options.rangeDuration || 'day';
-      options.endTime = options.endTime || moment.unix(esHttp.date.now()).utc().add(1, options.rangeDuration).unix();
-      options.startTime = options.startTime ||
-        moment.unix(options.endTime).utc().subtract(defaultTotalRangeCount, options.rangeDuration).unix();
+      options = _initRangeOptions(options);
 
       var jobs = [];
 
       var from = moment.unix(options.startTime).utc().startOf(options.rangeDuration);
+      var to = moment.unix(options.endTime).utc();
       var ranges = [];
-      while(from.unix() < options.endTime) {
+      while(from.isBefore(to)) {
 
         ranges.push({
           from: from.unix(),
@@ -296,7 +239,7 @@ angular.module('cesium.graph.data.services', ['cesium.wot.services', 'cesium.es.
         });
 
         // Do not exceed max range count
-        if (ranges.length == maxRangeSize) {
+        if (ranges.length == options.maxRangeSize) {
           var request = {
             size: 0,
             aggs: {
@@ -329,8 +272,11 @@ angular.module('cesium.graph.data.services', ['cesium.wot.services', 'cesium.es.
           // prepare next loop
           ranges = [];
 
-          if (jobs.length < 10) {
-
+          if (jobs.length == 10) {
+            console.error('Too many parallel jobs!');
+            from = moment.unix(options.endTime).utc(); // stop while
+          }
+          else {
             jobs.push(
               exports.raw.blockstat.search(request, {currency: currency})
                 .then(function (res) {
@@ -349,11 +295,6 @@ angular.module('cesium.graph.data.services', ['cesium.wot.services', 'cesium.es.
                 })
             );
           }
-          else {
-            console.error('Too many call of txCount request ! ');
-            from = moment.unix(options.endTime).utc();
-          }
-
         }
       }
 
@@ -366,23 +307,15 @@ angular.module('cesium.graph.data.services', ['cesium.wot.services', 'cesium.es.
 
           res = _.sortBy(res, 'from');
 
-          var result = {};
-          result.count =  res.reduce(function(res, hit){
-            return res.concat(hit.count);
-          }, []);
-          result.avgByBlock =  res.reduce(function(res, hit){
-            return res.concat(hit.avgByBlock);
-          }, []);
-          result.maxByBlock =  res.reduce(function(res, hit){
-            return res.concat(hit.maxByBlock);
-          }, []);
-          result.amount =  res.reduce(function(res, hit){
-            return res.concat(hit.amount/100);
-          }, []);
-          result.times =  res.reduce(function(res, hit){
-            return res.concat(hit.from);
-          }, []);
-          return result;
+          return {
+            count: _.pluck(res, 'count'),
+            avgByBlock: _.pluck(res, 'avgByBlock'),
+            maxByBlock: _.pluck(res, 'maxByBlock'),
+            amount:  res.reduce(function(res, hit){
+              return res.concat(hit.amount/100);
+            }, []),
+            times: _.pluck(res, 'from')
+          };
         });
     };
 
@@ -391,9 +324,7 @@ angular.module('cesium.graph.data.services', ['cesium.wot.services', 'cesium.es.
      * @param currency
      * @returns {*}
      */
-    exports.node.blockCount = function(currency, pubkey, options) {
-
-      options = options || {};
+    exports.node.blockCount = function(currency, pubkey) {
 
       var request = {
         size: 0,
@@ -406,6 +337,353 @@ angular.module('cesium.graph.data.services', ['cesium.wot.services', 'cesium.es.
         });
     };
 
+
+    exports.raw.movement.getByRange = function(currency, pubkey, ranges) {
+      if (!pubkey) {
+        throw new Error('Missing \'pubkey\' argument!');
+      }
+      var request = {
+        size: 0,
+        query: {
+          bool: {
+            should: [
+              {term: {recipient: pubkey}},
+              {term: {issuer: pubkey}}
+            ]
+          }
+        },
+        aggs: {
+          tx: {
+            range: {
+              field: "medianTime",
+              ranges: ranges
+            },
+            aggs: {
+              received: {
+                filter: {term: {recipient: pubkey}},
+                aggs: {
+                  received_stats: {
+                    stats: {
+                      field: "amount"
+                    }
+                  }
+                }
+              },
+              sent: {
+                filter: {term: {issuer: pubkey}},
+                aggs: {
+                  sent_stats: {
+                    stats: {
+                      field: "amount"
+                    }
+                  }
+                }
+              }
+            }
+
+          }
+        }
+      };
+
+      return exports.raw.movement.search(request, {currency: currency})
+        .then(function(res) {
+          var aggs = res.aggregations;
+          if (!aggs.tx || !aggs.tx.buckets || !aggs.tx.buckets.length) return;
+          return (aggs.tx.buckets || []).reduce(function (res, agg) {
+            var sent = agg.sent.sent_stats;
+            var received = agg.received.received_stats;
+            return res.concat({
+              from: agg.from,
+              to: agg.to,
+              sent: sent.sum ? (-sent.sum / 100) : 0,
+              received: received.sum ? (received.sum / 100) : 0
+            });
+          }, []);
+        });
+    };
+
+    exports.raw.movement.getUds = function(currency, ranges, fromMapping) {
+      var request = {
+        size: 0,
+        query: {
+          bool: {
+            should: [
+              {exists: {field: 'dividend'}}
+            ]
+          }
+        },
+        aggs: {
+          ud: {
+            range: {
+              field: 'medianTime',
+              ranges: ranges
+            },
+            aggs: {
+              ud_stats: {
+                stats: {
+                  field: 'dividend'
+                }
+              },
+              unitbase_stats: {
+                stats: {
+                  field: 'unitbase'
+                }
+              }
+            }
+          }
+        }
+      };
+
+      return exports.raw.block.search(request, {currency: currency})
+        .then(function(res) {
+          var aggs = res.aggregations;
+          if (!aggs.ud || !aggs.ud.buckets || !aggs.ud.buckets.length) return;
+          return (aggs.ud.buckets || []).reduce(function (res, agg) {
+            var from = fromMapping[agg.from];
+            res[from] = _powBase(agg.ud_stats.sum, agg.unitbase_stats.min) / 100;
+            return res;
+          }, {});
+        });
+    };
+
+    /**
+     * Graph: "tx count"
+     * @param currency
+     * @returns {*}
+     */
+    exports.blockchain.movement = function(currency, options) {
+
+      options = _initRangeOptions(options);
+      options.withUD = angular.isDefined(options.withUD) ? options.withUD : true;
+
+      var jobs = [];
+
+      // If need and missing: load membership periods
+      if (options.withUD && !options.memberships) {
+        return exports.wot.memberships(options)
+          .then(function(res) {
+            options.memberships = res || [];
+            return exports.blockchain.movement(currency, options);
+          });
+      }
+
+      var from = moment.unix(options.startTime).utc().startOf(options.rangeDuration);
+      var to = moment.unix(options.endTime).utc();
+
+      var ranges = [];
+      var udRanges = [];
+      var udFromMapping = {};
+      var memberships = angular.copy(options.memberships).reverse();
+      var membership = memberships.pop();
+
+      function addRange(range) {
+        ranges.push(range);
+        var member = membership && membership.joinTime < range.to;
+        if (member) {
+          var udRange = {
+            from: Math.max(membership.joinTime, range.from),
+            to: Math.min(membership.leaveTime, range.to)
+          };
+          udRanges.push(udRange);
+          udFromMapping[udRange.from] = range.from;
+          while (membership && (membership.leaveTime && membership.leaveTime < range.to)) {
+            membership = memberships.pop();
+          }
+        }
+      }
+
+      // Add a range to get TX before startTime
+      addRange({
+        from: 0,
+        to: from.unix()
+      });
+
+      while(from.isBefore(to)) {
+
+        addRange({
+          from: from.unix(),
+          to: from.add(1, options.rangeDuration).unix()
+        });
+
+        // Do not exceed max range count
+        if ((!jobs.length && ranges.length == options.maxRangeSize+1) || (jobs.length && ranges.length == options.maxRangeSize)) {
+
+          if (udRanges.length) {
+            jobs.push($q.all([
+              exports.raw.movement.getUds(currency, udRanges, udFromMapping),
+              exports.raw.movement.getByRange(currency, options.pubkey, ranges)
+            ])
+            .then(function(res){
+              var udsMap = res[0];
+              res = res[1];
+              // fill UD
+              res.forEach(function(hit){
+                hit.ud = (udsMap[hit.from]) || 0;
+              });
+              return res;
+            }));
+          }
+          else {
+            jobs.push(exports.raw.movement.getByRange(currency, options.pubkey, ranges)
+              .then(function(res){
+                // fill UD
+                res.forEach(function(hit){
+                  hit.ud = 0;
+                });
+                return res;
+              }));
+          }
+
+          // reset ranges for the next loop
+          ranges = [];
+        }
+      } // loop
+
+      return $q.all(jobs)
+        .then(function(res) {
+          // concat all results
+          res = res.reduce(function(res, hits){
+            if (!hits || !hits.length) return res;
+            return res.concat(hits);
+          }, []);
+
+          if (!res.length) return;
+
+          // Sort by 'from' field
+          res = _.sortBy(res, 'from');
+
+          // First item should be history (tx before startTime)
+          var history = res.splice(0,1)[0];
+          var balance = history.received + history.sent + history.ud;
+
+          return {
+            times: _.pluck(res, 'from'),
+            ud: _.pluck(res, 'ud'),
+            sent: _.pluck(res, 'sent'),
+            received: _.pluck(res, 'received'),
+            balance: res.reduce(function(res, hit){
+              balance += hit.received + hit.sent + hit.ud;
+              return res.concat(balance);
+            }, [])
+          };
+        });
+    };
+
+
+    /**
+     * Graph: "tx count"
+     * @param currency
+     * @returns {*}
+     */
+    exports.wot.certifications = function(options) {
+
+      options = _initRangeOptions(options);
+
+      return csWot.load(options.pubkey)
+        .then(function(idty) {
+          if (!idty) return;
+          var res = {};
+          _.forEach(idty.given_cert||[], function(cert){
+            var truncTime = moment.unix(cert.time).utc().startOf(options.rangeDuration).unix();
+            res[truncTime] = res[truncTime] || {time:truncTime,given:0,received:0};
+            res[truncTime].given++;
+          });
+          _.forEach(idty.received_cert||[], function(cert){
+            var truncTime = moment.unix(cert.time).utc().startOf(options.rangeDuration).unix();
+            res[truncTime] = res[truncTime] || {time:truncTime,given:0,received:0};
+            res[truncTime].received++;
+          });
+
+          // Sort by time
+          res = _.sortBy(_.values(res), 'time');
+
+          // create final result
+          var result = {
+            times: _.pluck(res, 'time'),
+            deltaGiven: _.pluck(res, 'given'),
+            deltaReceived: _.pluck(res, 'received')
+          };
+          var sum = 0;
+          result.given = result.deltaGiven.reduce(function(res, delta) {
+            sum += delta;
+            return res.concat(sum);
+          }, []);
+          sum = 0;
+          result.received = result.deltaReceived.reduce(function(res, delta) {
+            sum += delta;
+            return res.concat(sum);
+          }, []);
+          return result;
+
+        });
+    };
+
+
+    exports.wot.memberships = function(options) {
+
+      options = options || {};
+
+      // Get user events on membership state
+      var request = {
+        "size": 1000,
+        "query": {
+          "bool": {
+            "filter": [
+              {"term": {"recipient" : options.pubkey }},
+              {"terms": {"code" : ["MEMBER_JOIN","MEMBER_ACTIVE","MEMBER_LEAVE","MEMBER_EXCLUDE","MEMBER_REVOKE"] }}
+            ]
+          }
+        },
+        "sort" : [
+          { "time" : {"order" : "asc"}}
+        ],
+        _source: ["code", "time"]
+      };
+
+      return exports.raw.user.event(request)
+
+        .then(function(res) {
+          if (!res.hits || !res.hits.total) return;
+
+          // Compute member periods
+          var lastJoinTime;
+          var result = res.hits.hits.reduce(function(res, hit){
+            var isMember = hit._source.code == 'MEMBER_JOIN' || hit._source.code == 'MEMBER_ACTIVE';
+            // If join
+            if (isMember && !lastJoinTime) {
+              lastJoinTime = hit._source.time;
+            }
+            // If leave
+            else if (!isMember && lastJoinTime) {
+              // Add an entry
+              res = res.concat({
+                joinTime: lastJoinTime,
+                leaveTime: hit._source.time
+              });
+              lastJoinTime = 0; // reset
+            }
+            return res;
+          }, []);
+
+          if (lastJoinTime) {
+            // Add last entry if need
+            result.push({
+              joinTime: lastJoinTime,
+              leaveTime: moment().utc().unix()
+            });
+          }
+
+          return result;
+        });
+    };
+
+
+    // register listener
+//    csCurrency.api.data.on.load($rootScope, onCurrencyLoad, this);
+
     return exports;
   })
+
+
+
 ;
diff --git a/www/plugins/graph/templates/account/graph_balance.html b/www/plugins/graph/templates/account/graph_balance.html
new file mode 100644
index 0000000000000000000000000000000000000000..7939969f663c4fb884147d4536794ceac7cef274
--- /dev/null
+++ b/www/plugins/graph/templates/account/graph_balance.html
@@ -0,0 +1,24 @@
+
+    <!-- button bar -->
+    <div class="button-bar-inline "
+         style="top: 33px; margin-top:-33px; position: relative;">
+      <button
+        class="button button-stable button-clear no-padding-xs pull-right"
+        ng-click="showActionsPopover($event)">
+        <i class="icon ion-navicon-round"></i>
+      </button>
+    </div>
+
+    <div class="padding-left padding-right">
+      <canvas id="account-balance" class="chart-bar"
+              height="{{height}}" width="{{width}}"
+              chart-data="data"
+              chart-dataset-override="datasetOverride"
+              chart-colors="colors"
+              chart-options="options"
+              chart-labels="labels"
+              chart-click="onChartClick">
+      </canvas>
+    </div>
+
+    <ng-include src="'plugins/graph/templates/common/graph_range_bar.html'"></ng-include>
diff --git a/www/plugins/graph/templates/account/graph_certifications.html b/www/plugins/graph/templates/account/graph_certifications.html
new file mode 100644
index 0000000000000000000000000000000000000000..6e4816e12f11abf0994697373a5ddc6d06e93b09
--- /dev/null
+++ b/www/plugins/graph/templates/account/graph_certifications.html
@@ -0,0 +1,12 @@
+
+    <div class="padding-left padding-right">
+      <canvas id="account-certifications" class="chart-bar"
+              height="{{height}}" width="{{width}}"
+              chart-data="data"
+              chart-dataset-override="datasetOverride"
+              chart-colors="colors"
+              chart-options="options"
+              chart-labels="labels"
+              chart-click="onChartClick">
+      </canvas>
+    </div>
diff --git a/www/plugins/graph/templates/account/view_identity_extend.html b/www/plugins/graph/templates/account/view_identity_extend.html
new file mode 100644
index 0000000000000000000000000000000000000000..65ff216dbc2b9417ebb031c94e8af2aa22f0f7cb
--- /dev/null
+++ b/www/plugins/graph/templates/account/view_identity_extend.html
@@ -0,0 +1,9 @@
+<!-- Buttons section -->
+<ng-if ng-if="extensionPoint === 'buttons'">
+
+  <button class="button button-stable button-small-padding icon ion-stats-bars"
+          ng-click="showIdentityStats()"
+          title="{{'GRAPH.ACCOUNT.BTN_SHOW_STATS' | translate}}">
+  </button>
+
+</ng-if>
diff --git a/www/plugins/graph/templates/account/view_stats.html b/www/plugins/graph/templates/account/view_stats.html
new file mode 100644
index 0000000000000000000000000000000000000000..8b21f2ddcbda4652510d4a500904face8d79daec
--- /dev/null
+++ b/www/plugins/graph/templates/account/view_stats.html
@@ -0,0 +1,39 @@
+<ion-view left-buttons="leftButtons"
+          cache-view="false">
+  <ion-nav-title>
+    {{'GRAPH.ACCOUNT.TITLE' | translate}}{{id}}
+  </ion-nav-title>
+
+  <ion-content scroll="true" class="no-padding">
+
+    <div class="center padding" ng-if="loading">
+      <ion-spinner icon="android"></ion-spinner>
+    </div>
+
+    <div class="list" ng-if="!loading">
+
+      <!--  - - - - Balance - - - - -->
+      <div class="item item-divider" translate>
+        GRAPH.ACCOUNT.BALANCE_DIVIDER
+      </div>
+
+      <div class="item no-padding-xs"
+           ng-include="'plugins/graph/templates/account/graph_balance.html'"
+           ng-controller="GpAccountBalanceCtrl"
+           ng-init="setSize(350, 1000)">
+      </div>
+
+      <!--  - - - - WOT - - - - -->
+      <!--<div class="item item-divider" translate>
+        GRAPH.ACCOUNT.WOT_DIVIDER
+      </div>
+
+      <div class="item no-padding-xs"
+           ng-include="'plugins/graph/templates/account/graph_certifications.html'"
+           ng-controller="GpAccountCertificationCtrl"
+           ng-init="setSize(350, 1000)">
+      </div>-->
+
+  </ion-content>
+
+</ion-view>
diff --git a/www/plugins/graph/templates/account/view_wallet_tx_extend.html b/www/plugins/graph/templates/account/view_wallet_tx_extend.html
new file mode 100644
index 0000000000000000000000000000000000000000..b8cd1c04adaf3a3830be19e9902bec5c9dc7ec7d
--- /dev/null
+++ b/www/plugins/graph/templates/account/view_wallet_tx_extend.html
@@ -0,0 +1,9 @@
+<!-- Buttons section -->
+<ng-if ng-if="extensionPoint === 'buttons'">
+
+  <button class="button button-stable button-small-padding icon ion-stats-bars"
+          ng-click="showWalletStats()"
+          title="{{'GRAPH.ACCOUNT.BTN_SHOW_STATS' | translate}}">
+  </button>
+
+</ng-if>
diff --git a/www/plugins/graph/templates/blockchain/graph_block_issuers.html b/www/plugins/graph/templates/blockchain/graph_block_issuers.html
index 81ef7618a48a95fc40f396c33d63e60426977b49..c97178f57a54362cd3abb6ccf35b1a5ecb0d8e53 100644
--- a/www/plugins/graph/templates/blockchain/graph_block_issuers.html
+++ b/www/plugins/graph/templates/blockchain/graph_block_issuers.html
@@ -9,7 +9,7 @@
                 chart-labels="labels"
                 chart-colors="colors"
                 chart-options="barOptions"
-                chart-click="showBlockIssuer">
+                chart-click="onChartClick">
         </canvas>
       </div>
 
@@ -19,7 +19,7 @@
                 chart-data="data"
                 chart-labels="labels"
                 chart-colors="colors"
-                chart-click="showBlockIssuer">
+                chart-click="onChartClick">
         </canvas>
 
         <div class="gray padding-top text-center">
diff --git a/www/plugins/graph/templates/blockchain/graph_tx_count.html b/www/plugins/graph/templates/blockchain/graph_tx_count.html
index 93ea3734bd20d56567ec3feae2277451c91f640a..def80ecccdd8a248237444117435d4476ed015f0 100644
--- a/www/plugins/graph/templates/blockchain/graph_tx_count.html
+++ b/www/plugins/graph/templates/blockchain/graph_tx_count.html
@@ -4,7 +4,7 @@
          style="top: 33px; margin-top:-33px; position: relative;">
       <button
         class="button button-stable button-clear no-padding-xs pull-right"
-        ng-click="showTxActionsPopover($event)">
+        ng-click="showActionsPopover($event)">
         <i class="icon ion-navicon-round"></i>
       </button>
     </div>
@@ -17,26 +17,8 @@
               chart-colors="colors"
               chart-options="options"
               chart-labels="labels"
-              chart-click="showTxRange">
+              chart-click="onChartClick">
       </canvas>
     </div>
 
-    <div class="range range-positive no-padding-left no-padding-right">
-      <a
-        class="button button-stable button-clear no-padding pull-left"
-        ng-click="loadPreviousTx()">
-        <i class="icon ion-chevron-left"></i>
-      </a>
-      <input type="range"
-             ng-model="formData.timePct"
-             name="timePct"
-             min="0" max="100"
-             value="{{formData.timePct}}"
-             ng-change="onTxTimeChanged();"
-             ng-model-options="{ debounce: 250 }">
-      <a
-        class="button button-stable button-clear no-padding pull-right"
-        ng-click="loadNextTx($event)">
-        <i class="icon ion-chevron-right"></i>
-      </a>
-    </div>
+    <ng-include src="'plugins/graph/templates/common/graph_range_bar.html'"></ng-include>
diff --git a/www/plugins/graph/templates/blockchain/popover_tx_actions.html b/www/plugins/graph/templates/blockchain/popover_tx_actions.html
deleted file mode 100644
index 970a901d9fa6602797c1b0a03d18d280b2cb6aa3..0000000000000000000000000000000000000000
--- a/www/plugins/graph/templates/blockchain/popover_tx_actions.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<ion-popover-view class="fit has-header">
-  <ion-header-bar>
-    <h1 class="title" translate>COMMON.POPOVER_ACTIONS_TITLE</h1>
-  </ion-header-bar>
-  <ion-content scroll="false">
-    <div class="list item-text-wrap">
-
-      <!-- duration: hour -->
-      <a class="item item-icon-right ink"
-         ng-click="setTxRangeDuration('hour')">
-        <span ng-bind-html="'GRAPH.BLOCKCHAIN.TX_RANGE_DURATION.HOUR' | translate"></span>
-        <i class="icon ion-ios-checkmark-empty" ng-show="txOptions.rangeDuration=='hour'"></i>
-      </a>
-
-      <!-- duration: day -->
-      <a class="item item-icon-right ink"
-         ng-click="setTxRangeDuration('day')">
-        <span ng-bind-html="'GRAPH.BLOCKCHAIN.TX_RANGE_DURATION.DAY' | translate"></span>
-        <i class="icon ion-ios-checkmark-empty" ng-show="txOptions.rangeDuration=='day'"></i>
-      </a>
-
-      <!-- duration: month -->
-      <a class="item item-icon-right ink"
-         ng-click="setTxRangeDuration('month')">
-        <span ng-bind-html="'GRAPH.BLOCKCHAIN.TX_RANGE_DURATION.MONTH' | translate"></span>
-        <i class="icon ion-ios-checkmark-empty" ng-show="txOptions.rangeDuration=='month'"></i>
-      </a>
-
-    </div>
-  </ion-content>
-</ion-popover-view>
diff --git a/www/plugins/graph/templates/common/graph_range_bar.html b/www/plugins/graph/templates/common/graph_range_bar.html
new file mode 100644
index 0000000000000000000000000000000000000000..3a7c75a0648e5a6707e313eec8bfbdc8d40a74a0
--- /dev/null
+++ b/www/plugins/graph/templates/common/graph_range_bar.html
@@ -0,0 +1,20 @@
+
+  <div class="range range-positive no-padding-left no-padding-right">
+    <a
+      class="button button-stable button-clear no-padding pull-left"
+      ng-click="goPreviousRange($event)">
+      <i class="icon ion-chevron-left"></i>
+    </a>
+    <input type="range"
+           ng-model="formData.timePct"
+           name="timePct"
+           min="0" max="100"
+           value="{{formData.timePct}}"
+           ng-change="onRangeChanged();"
+           ng-model-options="{ debounce: 250 }">
+    <a
+      class="button button-stable button-clear no-padding pull-right"
+      ng-click="goNextRange($event)">
+      <i class="icon ion-chevron-right"></i>
+    </a>
+  </div>
diff --git a/www/plugins/graph/templates/common/popover_range_actions.html b/www/plugins/graph/templates/common/popover_range_actions.html
new file mode 100644
index 0000000000000000000000000000000000000000..31745aa69cad20d2ea164c0f3f4ba60b945c5915
--- /dev/null
+++ b/www/plugins/graph/templates/common/popover_range_actions.html
@@ -0,0 +1,43 @@
+<ion-popover-view class="has-header popover-graph-currency">
+  <ion-header-bar>
+    <h1 class="title" translate>COMMON.POPOVER_ACTIONS_TITLE</h1>
+  </ion-header-bar>
+  <ion-content scroll="false">
+    <div class="list item-text-wrap">
+
+      <!-- scale -->
+      <a class="item item-icon-left ink"
+         ng-click="toggleScale()">
+        <i class="icon ion-ios-checkmark-empty" ng-show="scale=='logarithmic'"></i>
+        <span ng-bind-html="'GRAPH.COMMON.LOGARITHMIC_SCALE' | translate"></span>
+      </a>
+
+      <!-- duration divider -->
+      <div class="item item-divider">
+        {{'GRAPH.BLOCKCHAIN.TX_RANGE_DURATION_DIVIDER'|translate}}
+      </div>
+
+      <!-- duration: hour -->
+      <a class="item item-icon-left ink"
+         ng-click="setRangeDuration('hour')">
+        <i class="icon ion-ios-checkmark-empty" ng-show="formData.rangeDuration=='hour'"></i>
+        <span ng-bind-html="'GRAPH.BLOCKCHAIN.TX_RANGE_DURATION.HOUR' | translate"></span>
+      </a>
+
+      <!-- duration: day -->
+      <a class="item item-icon-left ink"
+         ng-click="setRangeDuration('day')">
+        <i class="icon ion-ios-checkmark-empty" ng-show="formData.rangeDuration=='day'"></i>
+        <span ng-bind-html="'GRAPH.BLOCKCHAIN.TX_RANGE_DURATION.DAY' | translate"></span>
+      </a>
+
+      <!-- duration: month -->
+      <a class="item item-icon-left ink"
+         ng-click="setRangeDuration('month')">
+        <i class="icon ion-ios-checkmark-empty" ng-show="formData.rangeDuration=='month'"></i>
+        <span ng-bind-html="'GRAPH.BLOCKCHAIN.TX_RANGE_DURATION.MONTH' | translate"></span>
+      </a>
+
+    </div>
+  </ion-content>
+</ion-popover-view>
diff --git a/www/plugins/graph/templates/currency/graph_members_count.html b/www/plugins/graph/templates/currency/graph_members_count.html
index 2b26b0a4cb9760a31ff528350ce430bb7aeb6620..0b261fb47c03da64debe4bf15307864060e163ee 100644
--- a/www/plugins/graph/templates/currency/graph_members_count.html
+++ b/www/plugins/graph/templates/currency/graph_members_count.html
@@ -6,5 +6,5 @@
           chart-colors="colors"
           chart-options="options"
           chart-dataset-override="datasetOverride"
-          chart-click="showBlock">
+          chart-click="onChartClick">
   </canvas>
diff --git a/www/plugins/graph/templates/currency/graph_monetary_mass.html b/www/plugins/graph/templates/currency/graph_monetary_mass.html
index 2b34a02ac999b5c537c9ce34b5e15ea3bd8dd750..894e82b841d4b7375a9ca917d3d88d845ed95797 100644
--- a/www/plugins/graph/templates/currency/graph_monetary_mass.html
+++ b/www/plugins/graph/templates/currency/graph_monetary_mass.html
@@ -17,5 +17,5 @@
           chart-colors="colors"
           chart-dataset-override="datasetOverride"
           chart-options="options"
-          chart-click="showBlock">
+          chart-click="onChartClick">
   </canvas>
diff --git a/www/plugins/rml9/i18n/locale-fr-FR.json b/www/plugins/rml9/i18n/locale-fr-FR.json
new file mode 100644
index 0000000000000000000000000000000000000000..0dfad640d78c19e4bd81e0125c1c7978343d6c19
--- /dev/null
+++ b/www/plugins/rml9/i18n/locale-fr-FR.json
@@ -0,0 +1,8 @@
+{
+  "RML9": {
+    "BTN_EXPORT": "Exporter les transactions",
+    "VIEW": {
+      "TITLE": "RML9"
+    }
+  }
+}
diff --git a/www/plugins/rml9/plugin.js b/www/plugins/rml9/plugin.js
new file mode 100644
index 0000000000000000000000000000000000000000..d8766423fc546728d9c06729fc30c38767d301ea
--- /dev/null
+++ b/www/plugins/rml9/plugin.js
@@ -0,0 +1,106 @@
+
+angular.module('cesium.rml9.plugin', ['cesium.services'])
+
+  .config(function($stateProvider, PluginServiceProvider, csConfig) {
+    'ngInject';
+
+    var enable = csConfig.plugins && csConfig.plugins.rml9;
+    if (enable) {
+
+      // Extend existing view
+      PluginServiceProvider
+        .extendState('app.view_wallet_tx', {
+          points: {
+            'buttons': {
+              templateUrl: "plugins/rml9/templates/button.html",
+              controller: 'Rml9ButtonCtrl'
+            }
+          }
+        })
+
+        .extendState('app.wot_identity', {
+          points: {
+            'buttons': {
+              templateUrl: "plugins/rml9/templates/button.html",
+              controller: 'Rml9ButtonCtrl'
+            }
+          }
+        })
+      ;
+
+      // Add new view
+      $stateProvider
+
+        .state('app.rml9', {
+          url: "/rml9?pubkey",
+          views: {
+            'menuContent': {
+              templateUrl: "plugins/rml9/templates/view.html",
+              controller: 'Rml9ViewCtrl'
+            }
+          }
+        });
+    }
+
+
+  })
+
+  /**
+   * Les controlleurs sont chargés de gérer faire la liaison entre les services d'accès aux données, et l'interface graphique.
+   *
+   * Celui-ci sert à étendre la page 'Mes opérations'
+   */
+  .controller('Rml9ButtonCtrl', function($scope, $state, PluginService, FileSaver, BMA, csWallet) {
+    'ngInject';
+
+    $scope.extensionPoint = PluginService.extensions.points.current.get();
+
+    // Manage click on the export button
+    $scope.onButtonClick = function() {
+      console.debug("[RML9] calling onButtonClick()");
+
+      var pubkey = $scope.formData.pubkey || csWallet.isLogin() && csWallet.data.pubkey;
+      if (!pubkey) return;
+
+      BMA.tx.history.all({pubkey: pubkey})
+        .then(function(res){
+          if (!res || !res.history) return;
+
+          console.debug("[RML9] TODO: process the TX history:", res.history);
+
+          var fileContent = ["Hello Libre World !\n", "Second line example\n"];
+          var file = new Blob(fileContent, {type: 'text/plain; charset=utf-8'});
+          FileSaver.saveAs(file, 'transactions.txt');
+        });
+    };
+  })
+
+
+  /**
+   * Ce controlleur gère la page #/app/rml9
+   */
+  .controller('Rml9ViewCtrl', function($scope, csWallet) {
+
+    // Call when enter into the view
+    $scope.$on('$ionicView.enter', function(e, state) {
+
+      console.log("[RML9] entering RML9 view...");
+
+      // If need, a pubkey could be pass by URL params : #/app/rml9?pubkey=...
+      /*
+      var pubkey = (state && state.stateParams && state.stateParams.pubkey) || (csWallet.isLogin() && csWallet.data.pubkey);
+      if (!pubkey) return;
+      */
+
+      $scope.items = [
+        {amount: 100, time: 125454702, issuer:'5U2xuAUEPFeUQ4zpns6Zn33Q1ZWaHxEd3sPx689ZpaZV'},
+        {amount: -500, time: 125404702, issuer:'2RFPQGxYraKTFKKBXgpNn1QDEPdFM7rHNu7HdbmmF43v'}
+      ];
+
+
+    });
+
+
+  });
+
+
diff --git a/www/plugins/rml9/templates/button.html b/www/plugins/rml9/templates/button.html
new file mode 100644
index 0000000000000000000000000000000000000000..43dd317b43d6c511d2bea4fffe38735da8b1f798
--- /dev/null
+++ b/www/plugins/rml9/templates/button.html
@@ -0,0 +1,9 @@
+<!-- Buttons section -->
+<ng-if ng-if="extensionPoint === 'buttons'">
+
+  <button class="button button-stable button-small-padding icon ion-android-archive"
+          ng-click="onButtonClick()"
+          title="{{'RML9.BTN_EXPORT' | translate}}">
+  </button>
+
+</ng-if>
diff --git a/www/plugins/rml9/templates/view.html b/www/plugins/rml9/templates/view.html
new file mode 100644
index 0000000000000000000000000000000000000000..665f08658b7493e329198117c1ba174d04bcafe8
--- /dev/null
+++ b/www/plugins/rml9/templates/view.html
@@ -0,0 +1,23 @@
+<ion-view left-buttons="leftButtons">
+
+  <ion-nav-title>
+    {{'RML9.VIEW.TITLE' | translate}}
+  </ion-nav-title>
+
+  <ion-content>
+
+    <!-- items container -->
+    <div class="list">
+
+      <!-- an item -->
+      <div class="item" ng-repeat="item in items">
+        <h3>{{item.time|formatDate}}</h3>
+        <h4>{{item.issuer|formatPubkey}}</h4>
+        <div class="badge">{{item.amount}}</div>
+      </div>
+
+    </div>
+
+  </ion-content>
+
+</ion-view>
diff --git a/www/templates/currency/view_currency_lg.html b/www/templates/currency/view_currency_lg.html
index 5b2d96e74ac60d8ff4efcdb124e54e97cf4884f0..227d8a3b9ec19ca19c4166d5e14110f1e8d45383 100644
--- a/www/templates/currency/view_currency_lg.html
+++ b/www/templates/currency/view_currency_lg.html
@@ -1,11 +1,8 @@
 <ion-view left-buttons="leftButtons"
           cache-view="false">
     <ion-nav-title bind-notifier="{ rebind:formData.useRelative }">
-      <span>
-        {{'CURRENCY.VIEW.TITLE' | translate}} {{id}}
-      </span>
       <span ng-if="!loading">
-        {{formData.currency}} (<span ng-bind-html=":rebind:formData.currency | currencySymbol:formData.useRelative"></span>)
+         {{'CURRENCY.VIEW.TITLE' | translate}} {{formData.currency|abbreviate}}
       </span>
     </ion-nav-title>
 
@@ -21,6 +18,8 @@
 
       <!-- Buttons bar-->
       <div class="hidden-xs hidden-sm padding text-center">
+
+
         <button class="button button-stable icon-right ink"
                 ng-if="formData.licenseUrl"
                 ng-click="showLicenseModal()">
@@ -36,7 +35,16 @@
         <button class="button button-stable button-small-padding icon ion-android-more-vertical ink"
                 ng-click="showActionsPopover($event)">
         </button>
-        
+
+      </div>
+
+      <div class="item item-text-wrap no-border no-padding pull-left"
+           ng-if="!loading">
+        <div class="item-icon-left card padding stable-900-bg">
+          <i class="icon ion-help-circled calm"></i>
+          <div class="item-icon-left-padding" trust-as-html=":rebind:'CURRENCY.VIEW.CURRENCY_SHORT_DESCRIPTION'|translate:formData">
+          </div>
+        </div>
       </div>
 
       <div class="row responsive-sm">
diff --git a/www/templates/help/help.html b/www/templates/help/help.html
index 2926d62dfe42eed49b3132ab3f8d5c9dc1437b28..0eaf332633d0ba4a67c408c391a3f2eb8846527b 100644
--- a/www/templates/help/help.html
+++ b/www/templates/help/help.html
@@ -3,20 +3,23 @@
   <h2 translate>HELP.JOIN.SECTION</h2>
 
     <a name="join-salt"></a>
-    <div class="row responsive-sm">
-      <div class="col col-20 gray" translate>LOGIN.SALT</div>
+    <div class="row responsive-sm"
+         ng-class="itemsClass['join-salt']">
+      <div class="col col-20" translate>LOGIN.SALT</div>
       <div class="col" translate>HELP.JOIN.SALT</div>
     </div>
 
     <a name="join-password"></a>
-    <div class="row responsive-sm">
-      <div class="col col-20 gray" translate>LOGIN.PASSWORD</div>
+    <div class="row responsive-sm"
+         ng-class="itemsClass['join-password']">
+      <div class="col col-20" translate>LOGIN.PASSWORD</div>
       <div class="col" translate>HELP.JOIN.PASSWORD</div>
     </div>
 
     <a name="join-pseudo"></a>
-    <div class="row responsive-sm">
-      <div class="col col-20 gray" translate>ACCOUNT.NEW.PSEUDO</div>
+    <div class="row responsive-sm"
+         ng-class="itemsClass['join-pseudo']">
+      <div class="col col-20" translate>ACCOUNT.NEW.PSEUDO</div>
       <div class="col" translate>HELP.JOIN.PSEUDO</div>
     </div>
 
@@ -24,33 +27,37 @@
   <h2 translate>HELP.GLOSSARY.SECTION</h2>
 
     <a name="pubkey"></a>
-    <div class="row responsive-sm">
-      <div class="col col-20 gray" translate>COMMON.PUBKEY</div>
+    <div class="row responsive-sm"
+         ng-class="itemsClass.pubkey">
+      <div class="col col-20" translate>COMMON.PUBKEY</div>
       <div class="col" translate>HELP.GLOSSARY.PUBKEY_DEF</div>
     </div>
 
     <a name="blockchain"></a>
-    <div class="row responsive-sm">
-      <div class="col col-20 gray" translate>HELP.GLOSSARY.BLOCKCHAIN</div>
+    <div class="row responsive-sm"
+         ng-class="itemsClass.blockchain">
+      <div class="col col-20" translate>HELP.GLOSSARY.BLOCKCHAIN</div>
       <div class="col" translate>HELP.GLOSSARY.BLOCKCHAIN_DEF</div>
     </div>
 
     <a name="universal_dividend"></a>
-    <div class="row responsive-sm">
-      <div class="col col-20 gray" translate>COMMON.UNIVERSAL_DIVIDEND</div>
+    <a name="ud"></a>
+    <div class="row responsive-sm"
+         ng-class="itemsClass.ud">
+      <div class="col col-20" translate>COMMON.UNIVERSAL_DIVIDEND</div>
       <div class="col" translate>HELP.GLOSSARY.UNIVERSAL_DIVIDEND_DEF</div>
     </div>
 
     <a name="member"></a>
-    <div class="row responsive-sm">
-      <div class="col col-20 gray" translate>HELP.GLOSSARY.MEMBER</div>
+    <div class="row responsive-sm"
+         ng-class="itemsClass.member">
+      <div class="col col-20" translate>HELP.GLOSSARY.MEMBER</div>
       <div class="col" translate>HELP.GLOSSARY.MEMBER_DEF</div>
     </div>
 
-
     <a name="currency_rules"></a>
-    <div class="row responsive-sm">
-      <div class="col col-20 gray" translate>HELP.GLOSSARY.CURRENCY_RULES</div>
+    <div class="row responsive-sm"
+         ng-class="itemsClass.currency_rules">
+      <div class="col col-20" translate>HELP.GLOSSARY.CURRENCY_RULES</div>
       <div class="col" translate>HELP.GLOSSARY.CURRENCY_RULES_DEF</div>
     </div>
-
diff --git a/www/templates/help/modal_help.html b/www/templates/help/modal_help.html
index a0cfe9a64cd7bfccab12ea5ba4769e6727f56670..d0361b0951dac54a9d211261085aba3d7e13d7c0 100644
--- a/www/templates/help/modal_help.html
+++ b/www/templates/help/modal_help.html
@@ -1,4 +1,4 @@
-<ion-view class="modal slide-in-up ng-enter active ng-enter-active">
+<ion-modal-view class="modal-full-height modal-help">
 
     <ion-header-bar class="bar-positive">
       <button class="button button-clear" ng-click="closeModal()" translate>COMMON.BTN_CLOSE
@@ -7,9 +7,11 @@
       <h1 class="title" translate>HELP.TITLE</h1>
     </ion-header-bar>
 
-    <ion-content scroll="true" class="padding">
+    <ion-content croll="false" class="padding">
 
-      <ng-include src="'templates/help/help.html'"></ng-include>
+      <div ng-class="listClass">
+        <ng-include src="'templates/help/help.html'"></ng-include>
+      </div>
 
       <div class="padding hidden-xs text-center">
         <button class="button button-positive ink" type="submit"
@@ -19,4 +21,4 @@
       </div>
 
     </ion-content>
-</ion-view>
+</ion-modal-view>
diff --git a/www/templates/home/home.html b/www/templates/home/home.html
index 1f2175f0b8c8ef97486611c0eb70131edd58984a..a9795e2d3ae271bd3f7e81923f01cf6e3e735cb5 100644
--- a/www/templates/home/home.html
+++ b/www/templates/home/home.html
@@ -9,37 +9,30 @@
     <h4 class="hidden-xs" translate>HOME.MESSAGE</h4>
     <h4 class="visible-xs" translate>HOME.MESSAGE_SHORT</h4>
 
+    <!-- Help tour (NOT ready yet for small device) -->
     <div class="center">
 
-      <br class="hidden-xs"/>
-
-      <!-- Help tour (NOT ready yet for small device) -->
       <button type="button"
               class="button button-block button-stable button-raised icon-left icon ion-easel ink-dark hidden-xs"
               ng-click="startHelpTour()" >
         {{'COMMON.BTN_HELP_TOUR'|translate}}
       </button>
 
-      <!-- CURRENCY -->
-      <button type="button"
-              class="button button-block button-stable button-raised icon icon-left ion-ios-world-outline ink-dark"
-              ng-if="options.registry.enable"
-              ui-sref="app.currency_lookup" translate>HOME.BTN_CURRENCIES</button>
+      <!-- Currency-->
       <button type="button"
-              class="button button-block button-stable button-raised icon icon-left ion-ios-world-outline ink-dark hidden-sm hidden-xs"
-              ng-if="!options.registry || !options.registry.enable"
-              ui-sref="app.currency" translate>HOME.BTN_CURRENCY</button>
+              class="item button button-block button-stable button-raised icon icon-left ion-ios-world-outline ink-dark hidden-sm hidden-xs"
+              ui-sref="app.currency">{{'HOME.BTN_CURRENCY'|translate:$root.currency }}</button>
 
       <button type="button"
-              class="button button-block button-positive button-raised icon icon-left ion-locked ink-dark"
+              class="item button button-block button-positive button-raised icon icon-left ion-locked ink-dark"
               ng-click="loginAndGo('app.view_wallet')" ng-show="!login" translate>COMMON.BTN_LOGIN</button>
 
       <button type="button"
-              class="button button-block button-positive button-raised icon icon-left ion-person ink-dark"
+              class="item button button-block button-positive button-raised icon icon-left ion-person ink-dark"
               ui-sref="app.view_wallet" ng-show="login" translate>MENU.ACCOUNT</button>
 
       <button type="button"
-              class="button button-block button-positive button-raised icon icon-left ion-card ink-dark visible-xs"
+              class="item button button-block button-positive button-raised icon icon-left ion-card ink-dark visible-xs"
               ui-sref="app.view_wallet_tx" ng-show="login" translate>MENU.TRANSACTIONS</button>
 
       <br class="visible-xs visible-sm"/>
@@ -80,9 +73,9 @@
         <!-- about -->
         <a href="#" ng-click="showAboutModal()" translate>HOME.BTN_ABOUT</a>
       </div>
-    </div>
-
 
+    </div>
   </ion-content>
 
 </ion-view>
+
diff --git a/www/templates/join/modal_choose_account_type.html b/www/templates/join/modal_choose_account_type.html
index d2203fbf0e313c1ab0f5ecdec2cd39626b16e271..1de048038a6aad79caa8c7d54b61a7cedcf11b2b 100644
--- a/www/templates/join/modal_choose_account_type.html
+++ b/www/templates/join/modal_choose_account_type.html
@@ -10,15 +10,12 @@
             ng-click="slidePrev()"
             ng-if="slides.slider.activeIndex">
     </button>
-    <button class="button button-icon button-clear icon ion-ios-help-outline visible-xs"
-            ng-if="slides.slider.activeIndex > 1 && !isLastSlide"
-            ng-click="showHelpModal()"></button>
 
     <h1 class="title" translate>ACCOUNT.NEW.TITLE</h1>
 
     <button class="button button-clear icon-right visible-xs"
-            ng-if="!isLastSlide && slides.slider.activeIndex > 1"
-            ng-click="doNext()">
+            ng-if="slides.slider.activeIndex === 0"
+            ng-click="slideNext()">
       <span translate>COMMON.BTN_NEXT</span>
       <i class="icon ion-ios-arrow-right"></i>
     </button>
@@ -30,25 +27,50 @@
       <!-- STEP 1: currency -->
       <ion-slide-page>
         <ion-content class="has-header padding">
-          <h3 translate>ACCOUNT.NEW.SLIDE_1_TITLE</h3>
-          <div class="list">
-            <div class="item text-center" ng-if="loading">
-              <ion-spinner class="icon" icon="android"></ion-spinner>
-            </div>
-            <div ng-repeat="currency in currencies"
-                 ng-if="!loading"
-               class="item card item-icon-right stable-bg padding ink"
-               ng-class="{ selected: selectedCurrency == currency }"
-               ng-click="selectCurrency(currency.name, true)">
-              <h2>{{::currency.name}}</h2>
-              <h4 class="gray">{{::currency.peer.server}}</h4>
-              <i class="icon dark ion-ios-arrow-right"></i>
+          <div class="text-center" ng-if="loading">
+            <ion-spinner class="icon" icon="android"></ion-spinner>
+          </div>
+
+          <div ng-if="!loading">
+
+
+            <p ng-bind-html="'ACCOUNT.NEW.INTRO_WARNING_TIME'|translate:currency"></p>
+
+            <div class="row responsive-sm">
+              <div class="col">
+                <div class="item card item-icon-left padding item-text-wrap stable-bg">
+                  <i class="icon ion-android-warning  assertive"></i>
+
+                  <p class="item-content item-icon-left-padding ">
+                    <span class="dark" translate>ACCOUNT.NEW.INTRO_WARNING_SECURITY</span><br/>
+                    <small translate>ACCOUNT.NEW.INTRO_WARNING_SECURITY_HELP</small>
+                  </p>
+                </div>
+              </div>
+
+              <div class="col">
+                <div class="item card item-icon-left padding item-text-wrap stable-bg">
+                  <i class="icon ion-information-circled positive"></i>
+                  <p class="item-content item-icon-left-padding ">
+                    <span class="dark" trust-as-html="'ACCOUNT.NEW.REGISTRATION_NODE'|translate:currency.node"></span><br/>
+                    <small trust-as-html="'ACCOUNT.NEW.REGISTRATION_NODE_HELP'|translate:currency.node"></small>
+                  </p>
+                </div>
+              </div>
             </div>
+
+
           </div>
 
+          <p class="hidden-xs hidden-sm" ng-bind-html="'ACCOUNT.NEW.INTRO_HELP'|translate"></p>
+
           <div class="padding hidden-xs text-right">
             <button class="button button-clear button-dark ink" ng-click="closeModal()" type="button" translate>COMMON.BTN_CANCEL
             </button>
+            <button class="button button-positive icon-right ion-chevron-right ink" ng-click="slideNext()"
+                    ng-disabled="loading" type="button" translate>
+              COMMON.BTN_START
+            </button>
           </div>
         </ion-content>
       </ion-slide-page>
@@ -56,7 +78,7 @@
       <!-- STEP 2: account type -->
       <ion-slide-page>
         <ion-content class="has-header padding">
-          <h3 translate>ACCOUNT.NEW.SLIDE_2_TITLE</h3>
+          <p translate>ACCOUNT.NEW.SELECT_ACCOUNT_TYPE</p>
           <div class="list">
             <!-- member account -->
             <div class="item item-complex card stable-bg item-icon-left item-icon-right ink"
@@ -64,7 +86,7 @@
               <div class="item-content item-text-wrap">
                 <i class="item-image icon dark ion-person"></i>
                 <h2 translate>ACCOUNT.NEW.MEMBER_ACCOUNT</h2>
-                <h4 class="gray" translate>ACCOUNT.NEW.MEMBER_ACCOUNT_HELP</h4>
+                <h4 class="gray" ng-bind-html="'ACCOUNT.NEW.MEMBER_ACCOUNT_HELP'|translate:currency"></h4>
                 <i class="icon dark ion-ios-arrow-right"></i>
               </div>
             </div>
diff --git a/www/templates/join/modal_join_member.html b/www/templates/join/modal_join_member.html
index c4ab0c157c9f0ccec1f393484035eb27213a1932..b2ad690fe6d24f02d9174b42b997e6b548a172b3 100644
--- a/www/templates/join/modal_join_member.html
+++ b/www/templates/join/modal_join_member.html
@@ -44,7 +44,7 @@
     <ion-slides options="slides.options" slider="slides.slider" ng-init="console.log('START SLIDE');">
 
       <!-- STEP 1: license -->
-      <ion-slide-page>
+      <ion-slide-page ng-if="licenseFileUrl">
         <ion-content class="has-header" scroll="false">
             <div class="padding" translate>ACCOUNT.NEW.INFO_LICENSE</div>
 
@@ -75,8 +75,8 @@
         <ion-content class="has-header" scroll="false">
           <form name="pseudoForm" novalidate="" ng-submit="doNext('pseudoForm')">
 
-            <div class="item item-text-wrap text-center padding hidden-xs" >
-              <a class="pull-right icon-help" ng-click="showHelpModal('join-pseudo')"></a>
+            <div class="item item-text-wrap text-center padding" >
+              <a class="pull-right icon-help hidden-xs" ng-click="showHelpModal('join-pseudo')"></a>
               <span translate>ACCOUNT.NEW.PSEUDO_WARNING</span>
             </div>
 
@@ -87,7 +87,7 @@
               <div class="item item-input"
                    ng-class="{'item-input-error': (pseudoForm.$submitted && pseudoForm.pseudo.$invalid) || (uiAlreadyUsed && formData.pseudo)}">
                 <span class="input-label" translate>ACCOUNT.NEW.PSEUDO</span>
-                <input name="pseudo" type="text" placeholder="{{'ACCOUNT.NEW.PSEUDO_HELP' | translate}}"
+                <input id="pseudo" name="pseudo" type="text" placeholder="{{'ACCOUNT.NEW.PSEUDO_HELP' | translate}}"
                        ng-model="formData.pseudo"
                        ng-minlength="3"
                        ng-maxlength="100"
@@ -113,18 +113,23 @@
               </div>
 
               <!-- Show if valid pseudo-->
-              <div class="item item-button-right left" ng-if="formData.computing && formData.pseudo">
-                  <ion-spinner icon="android"></ion-spinner>
-              </div>
-              <div class="text-right" ng-if="!formData.computing">
-                <div class="form-error balanced" ng-if="!uiAlreadyUsed && formData.pseudo">
-                  <i class="icon ion-checkmark balanced"></i>
-                  <span translate>ACCOUNT.NEW.PSEUDO_AVAILABLE</span>
-                </div>
-                <div class="form-error" ng-if="uiAlreadyUsed && formData.pseudo">
-                  <i class="icon ion-close-circled assertive"></i>
-                  <span translate>ACCOUNT.NEW.PSEUDO_NOT_AVAILABLE</span>
+              <div class="text-right" style="min-height: 18px;">
+                <div class="form-error gray" ng-if="formData.computing && formData.pseudo">
+                  <ion-spinner class="icon ion-spinner-small" icon="android" ng-if="formData.computing && formData.pseudo"></ion-spinner>
+                  <span translate>ACCOUNT.NEW.CHECKING_PSEUDO</span>
                 </div>
+
+                <ng-if ng-if="!formData.computing && formData.pseudo">
+                  <div class="form-error balanced" ng-if="!uiAlreadyUsed ">
+                    <i class="icon ion-checkmark balanced"></i>
+                    <span translate>ACCOUNT.NEW.PSEUDO_AVAILABLE</span>
+                  </div>
+                  <div class="form-error" ng-if="uiAlreadyUsed">
+                    <i class="icon ion-close-circled assertive"></i>
+                    <span translate>ACCOUNT.NEW.PSEUDO_NOT_AVAILABLE</span>
+                  </div>
+                </ng-if>
+
               </div>
 
               <div class="padding hidden-xs text-right">
@@ -326,11 +331,9 @@
         <ion-content class="has-header" scroll="false">
 
           <!-- Computing -->
-
           <div class="padding text-center" ng-if="formData.computing">
             <ion-spinner icon="android"></ion-spinner>
           </div>
-          <!-- ng-if="formData.computing" -->
 
           <!-- Account available -->
           <div ng-if="accountAvailable && !formData.computing">
@@ -339,14 +342,8 @@
             <div class="list">
 
               <ion-item class="item item-text-wrap item-border">
-                <div class="dark pull-right padding-right" ng-if="formData.computing">
-                  <ion-spinner icon="android"></ion-spinner>
-                </div>
                 <span class="input-label" translate>COMMON.PUBKEY</span>
-                <span class="gray text-no-wrap" ng-if="formData.computing" translate>
-                  ACCOUNT.NEW.COMPUTING_PUBKEY
-                </span>
-                <span class="gray text-no-wrap" ng-if="formData.pubkey">
+                <span class="gray text-no-wrap" copy-on-click="{{formData.pubkey}}">
                   {{formData.pubkey}}
                 </span>
               </ion-item>
@@ -367,20 +364,14 @@
 
             <ion-item class="item-icon-left item-text-wrap text-center">
                 <i class="icon ion-minus-circled assertive"></i>
-                <span id="modal-license" translate>ERROR.EXISTING_ACCOUNT</span>
+                <span id="modal-license" trust-as-html="'ERROR.EXISTING_ACCOUNT'|translate"></span>
             </ion-item>
 
             <div class="list">
 
               <ion-item class="item item-text-wrap item-border">
-                <div class="dark pull-right padding-right" ng-if="formData.computing">
-                  <ion-spinner icon="android"></ion-spinner>
-                </div>
-                <span class="gray text-no-wrap" ng-if="formData.computing" translate>
-                  ACCOUNT.NEW.COMPUTING_PUBKEY
-                </span>
                 <div class="padding text-center">
-                  <span class="gray text-no-wrap" ng-if="formData.pubkey">
+                  <span class="gray text-no-wrap">
                     {{formData.pubkey}}
                   </span>
                 </div>
diff --git a/www/templates/network/view_peer.html b/www/templates/network/view_peer.html
index c8b1ec992c509ffb75a0b90bf8eea2954d013e22..2f52296f5794763aa23e78e2f423ecfd48f1bdb3 100644
--- a/www/templates/network/view_peer.html
+++ b/www/templates/network/view_peer.html
@@ -3,9 +3,9 @@
     <span translate>PEER.VIEW.TITLE</span>
   </ion-nav-title>
 
-  <ion-content class="has-header padding" scroll="true">
+  <ion-content class="has-header" scroll="true">
 
-    <div class="row">
+    <div class="row no-padding">
       <div class="col col-20 hidden-xs hidden-sm">&nbsp;
       </div>
 
diff --git a/www/templates/settings/popup_node.html b/www/templates/settings/popup_node.html
index 33e23fdf1b1093b39cc5d5397cf80bd4fe1c4665..77756efaae19ef1ff2d745416b72cda93e7e62a0 100644
--- a/www/templates/settings/popup_node.html
+++ b/www/templates/settings/popup_node.html
@@ -22,12 +22,13 @@
     </div>
   </div>
 
-  <small ng-bind-html="'SETTINGS.POPUP_PEER.BTN_SHOW_LIST_HELP' | translate"></small>
-
-  <button class="button button-positive button-clear positive button-outline button-full button-small-padding icon-left ink" ng-click="showNodeList()">
-    <i class="icon ion-wifi "></i>
-    {{'SETTINGS.POPUP_PEER.BTN_SHOW_LIST' | translate}}
-  </button>
+  <button type="submit" class="hide"></button>
 </form>
 
+<small ng-bind-html="'SETTINGS.POPUP_PEER.BTN_SHOW_LIST_HELP' | translate"></small>
+<button class="button button-positive button-clear positive button-outline button-full button-small-padding icon-left ink" ng-click="showNodeList()">
+  <i class="icon ion-wifi "></i>
+  {{'SETTINGS.POPUP_PEER.BTN_SHOW_LIST' | translate}}
+</button>
+
 
diff --git a/www/templates/wallet/view_wallet_tx.html b/www/templates/wallet/view_wallet_tx.html
index 4de31b92dea0d911fa7c0f2a9f297ade2e0c5bcc..a2be1f21f9dc2069635edfc3f5f7b35bb99587d9 100644
--- a/www/templates/wallet/view_wallet_tx.html
+++ b/www/templates/wallet/view_wallet_tx.html
@@ -5,6 +5,8 @@
   </ion-nav-title>
 
   <ion-nav-buttons side="secondary">
+    <cs-extension-point name="nav-buttons"></cs-extension-point>
+
     <button class="button button-icon button-clear icon ion-loop visible-xs visible-sm" ng-click="doUpdate()">
     </button>
   </ion-nav-buttons>
@@ -40,6 +42,8 @@
               title="{{'COMMON.BTN_REFRESH' | translate}}">
       </button>
 
+      <cs-extension-point name="buttons"></cs-extension-point>
+
       &nbsp;&nbsp;
 
       <button class="button button-calm ink"