diff --git a/.gitignore b/.gitignore
index 4798254e68a2d4da3e4fe043933c5edbbcdf1ebd..71e1d6beb9551a056bfc42d0c6ac04ceee25e7ea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,4 @@ www/lib/angular-ui-router
 www/lib/angular-moment
 www/lib/moment
 www/lib/waves
+www/dist
diff --git a/app/config.json b/app/config.json
index 2018d1bd948110f7f7ae4e275fb7ea43958a3c0a..5023d74cb9afa0b50a481c40c00ad58f40f26416 100644
--- a/app/config.json
+++ b/app/config.json
@@ -4,37 +4,15 @@
       "DUNITER_NODE": "cgeek.fr:9330",
       "NEW_ISSUE_LINK": "https://github.com/duniter/cesium/issues/new?labels=bug",
       "TIMEOUT": 4000,
-      "DEBUG": false,
-      "NATIVE_TRANSITION": false
-    }
-  },
-
-  "duniter-fr": {
-    "APP_CONFIG": {
-      "DUNITER_NODE": "cgeek.fr:9330",
-      "NEW_ISSUE_LINK": "https://github.com/duniter/cesium/issues/new?labels=bug",
-      "TIMEOUT": 4000,
-      "DEBUG": false,
-      "NATIVE_TRANSITION": false
-    }
-  },
-
-  "android": {
-    "APP_CONFIG": {
-      "DUNITER_NODE": "cgeek.fr:9330",
-      "NEW_ISSUE_LINK": "https://github.com/duniter/cesium/issues/new?labels=bug",
-      "TIMEOUT": 6000,
-      "DEBUG": false,
-      "NATIVE_TRANSITION": true
+      "DEBUG": false
     }
   },
 
   "dev": {
     "APP_CONFIG": {
       "DUNITER_NODE": "localhost:9201",
-      "TIMEOUT": 4000,
-      "DEBUG": false,
-      "NATIVE_TRANSITION": true
+      "TIMEOUT": 6000,
+      "DEBUG": true
     }
   }
 }
diff --git a/config.xml b/config.xml
index 8044726e78dcda5e40b62dc64a11a23fdbebdaf7..deb1d45dff105d44cdf9ad7ac9a3770ee85bca13 100644
--- a/config.xml
+++ b/config.xml
@@ -3,28 +3,32 @@
   xmlns="http://www.w3.org/ns/widgets"
   xmlns:cdv="http://cordova.apache.org/ns/1.0"
   id="fr.duniter.cesium"
-  version="0.1.15"
-  android-versionCode="3"
+  version="0.1.16"
+  android-versionCode="4"
   >
-    <name>Cesium</name>
-    <description>
-    A webapp client for Duniter
-    </description>
-    <author email="contact@duniter.fr" href="http://www.duniter.fr">
-      Duniter team
-    </author>
-    <content src="index.html" />
-    <access origin="*" />
-    <preference name="webviewbounce" value="false" />
-    <preference name="UIWebViewBounce" value="false" />
-    <preference name="DisallowOverscroll" value="true" />
-    <preference name="android-minSdkVersion" value="16" />
-    <preference name="BackupWebStorage" value="none" />
-    <preference name="SplashScreen" value="screen" />
-    <preference name="SplashScreenDelay" value="3000" />
-    <feature name="StatusBar">
-        <param name="ios-package" onload="true" value="CDVStatusBar" />
-    </feature>
+  <name>Cesium</name>
+  <description>
+  A webapp client for Duniter
+  </description>
+  <author email="contact@duniter.fr" href="http://www.duniter.fr">
+    Duniter team
+  </author>
+  <content src="index.html" />
+  <access origin="*" />
+  <!-- icon requirement for Ubuntu click packages -->
+  <icon src="www/img/logo.png" />
+  <preference name="webviewbounce" value="false" />
+  <preference name="UIWebViewBounce" value="false" />
+  <preference name="DisallowOverscroll" value="true" />
+  <preference name="android-minSdkVersion" value="16" />
+  <preference name="BackupWebStorage" value="none" />
+  <preference name="SplashScreen" value="screen" />
+  <preference name="SplashScreenDelay" value="3000" />
+  <preference name="CrosswalkAnimatable" value="true" />
+  <allow-navigation href="*" />
+  <feature name="StatusBar">
+    <param name="ios-package" onload="true" value="CDVStatusBar" />
+  </feature>
     <platform name="android">
         <icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" />
         <icon density="mdpi" src="resources/android/icon/drawable-mdpi-icon.png" />
@@ -73,5 +77,5 @@
         <splash height="960" src="resources/ios/splash/Default@2x~iphone.png" width="640" />
         <splash height="480" src="resources/ios/splash/Default~iphone.png" width="320" />
     </platform>
-    <allow-navigation href="*" />
+  <hook type="after_build" src="scripts/afterBuild.js" />
 </widget>
diff --git a/gulpfile.js b/gulpfile.js
index a20e9fc036aab1123dd22a993a2b19f7227350f9..c35ec637222b4282823570806d2e59fc8f69da91 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -13,15 +13,34 @@ var fs = require("fs");
 var argv = require('yargs').argv;
 var header = require('gulp-header');
 var removeCode = require('gulp-remove-code');
-//var bump = require('gulp-bump');
+var removeHtml = require('gulp-html-remove');
+var templateCache = require('gulp-angular-templatecache');
+var ngTranslate = require('gulp-angular-translate');
+var ngAnnotate = require('gulp-ng-annotate');
+var es = require('event-stream');
+var zip = require('gulp-zip');
+var del = require('del');
+var useref = require('gulp-useref');
+var filter = require('gulp-filter');
+var uglify = require('gulp-uglify');
+var csso = require('gulp-csso');
+var rev = require('gulp-rev');
+var revReplace = require('gulp-rev-replace');
+var clean = require('gulp-clean');
+var htmlmin = require('gulp-htmlmin');
+var deleteEmpty = require('delete-empty');
+var jshint = require('gulp-jshint');
 
 var paths = {
   sass: ['./scss/**/*.scss'],
   config: ['./app/config.json'],
-  templates: ['./www/templates/**/*.html']
+  templates: ['./www/templates/**/*.html'],
+  templatecache: ['./www/templates/**/*.html'],
+  ng_translate: ['./www/i18n/locale-*.json'],
+  ng_annotate: ['./www/js/*.js']
 };
 
-gulp.task('default', ['sass', 'config']);
+gulp.task('default', ['sass', 'config', 'templatecache', 'ng_translate', 'ng_annotate']);
 
 gulp.task('sass', function(done) {
   gulp.src('./scss/ionic.app.scss')
@@ -35,18 +54,12 @@ gulp.task('sass', function(done) {
     .on('end', done);
 });
 
-// TODO : enable to have a special buidl for phone
-//gulp.task('removeCode', function(done) {
-//  gulp.src('./www/templates/**/*.html')
-//    .pipe(removeCode({ production: true }))
-//    .pipe(gulp.dest('./dist/templates'))
-//    .on('end', done);
-//});
 
 gulp.task('watch', function() {
   gulp.watch(paths.sass, ['sass']);
-  //gulp.watch(paths.config, ['config']);
-  //gulp.watch(paths.templates, ['removeCode']);
+  gulp.watch(paths.templatecache, ['templatecache']);
+  gulp.watch(paths.ng_translate, ['ng_translate']);
+  gulp.watch(paths.ng_annotate, ['ng_annotate']);
 });
 
 gulp.task('install', ['git-check'], function() {
@@ -102,3 +115,180 @@ gulp.task('config', function (done) {
     .pipe(gulp.dest('www/js'))
     ;
 });
+
+gulp.task('templatecache', function (done) {
+  gulp.src('./www/templates/**/*.html')
+    .pipe(templateCache({
+      standalone:true,
+      module:"cesium.templates",
+      root: "templates/"
+     }))
+    .pipe(gulp.dest('./www/dist/dist_js/app'))
+    .on('end', done);
+});
+
+gulp.task('ng_annotate', function (done) {
+  gulp.src('./www/js/**/*.js')
+    .pipe(ngAnnotate({single_quotes: true}))
+    .pipe(gulp.dest('./www/dist/dist_js/app'))
+    .on('end', done);
+});
+
+gulp.task('ng_translate', function() {
+  return gulp.src('www/i18n/locale-*.json')
+    .pipe(ngTranslate({standalone:true, module: 'cesium.translations'}))
+    .pipe(gulp.dest('www/dist/dist_js/app'));
+});
+
+gulp.task('clean:tmp', function(done) {
+  return del([
+      './tmp'
+    ]);
+});
+
+gulp.task('clean:web', function(done) {
+  return del([
+      './platforms/web/www',
+      './platforms/web/build'
+    ]);
+});
+
+gulp.task('copy-files:web', ['clean:tmp', 'clean:web', 'sass', 'config'], function(done) {
+  var tmpPath = './platforms/web/www';
+  es.concat(
+    // Copy Js (and remove unused code)
+    gulp.src('./www/js/**/*.js')
+      .pipe(removeCode({"no-device": true}))
+      .pipe(jshint())
+      .pipe(gulp.dest(tmpPath + '/js')),
+
+    // Copy HTML templates (and remove unused code)
+    gulp.src('./www/templates/**/*.html')
+      .pipe(removeCode({"no-device": true}))
+      .pipe(removeHtml('.hidden-no-device'))
+      .pipe(removeHtml('[remove-if][remove-if="no-device"]'))
+      .pipe(htmlmin())
+      .pipe(gulp.dest(tmpPath + '/templates')),
+
+    // Copy index.html (and remove unused code)
+    gulp.src('./www/index.html')
+      .pipe(removeCode({"no-device": true}))
+      .pipe(removeHtml('.hidden-no-device'))
+      .pipe(removeHtml('[remove-if][remove-if="no-device"]'))
+      .pipe(htmlmin())
+      .pipe(gulp.dest(tmpPath)),
+
+    // Copy CSS
+    gulp.src('./www/css/**/*.*')
+      .pipe(gulp.dest(tmpPath + '/css')),
+
+    // Copy i18n
+    gulp.src('./www/i18n/locale-*.json')
+      .pipe(ngTranslate({standalone:true, module: 'cesium.translations'}))
+      .pipe(gulp.dest(tmpPath + '/js')),
+
+    // Copy img
+    gulp.src('./www/img/**/*.*')
+      .pipe(gulp.dest(tmpPath + '/img')),
+
+    // Copy lib/ionic
+    gulp.src('./www/lib/ionic/**/*.*')
+      .pipe(gulp.dest(tmpPath + '/lib/ionic'))
+  )
+  .on('end', done);
+});
+
+gulp.task('templatecache:web', ['copy-files:web'], function (done) {
+  var tmpPath = './platforms/web/www';
+  gulp.src(tmpPath + '/templates/**/*.html')
+    .pipe(templateCache({
+      standalone:true,
+      module:"cesium.templates",
+      root: "templates/"
+     }))
+    .pipe(gulp.dest(tmpPath + '/js'))
+    .on('end', done);
+});
+
+gulp.task('ng_annotate:web', ['templatecache:web'], function (done) {
+  var tmpPath = './platforms/web/www';
+  var jsFilter = filter(["**/*.js", "!**/vendor/*"]);
+
+  gulp.src(tmpPath + '/js/**/*.js')
+    .pipe(jsFilter)
+    .pipe(ngAnnotate({single_quotes: true}))
+    .pipe(gulp.dest(tmpPath + '/dist/dist_js/app'))
+    .on('end', done);
+});
+
+gulp.task('optimize-files:web', ['ng_annotate:web'], function(done) {
+  var tmpPath = './platforms/web/www';
+  var jsFilter = filter(["**/*.js", "!**/vendor/*"], { restore: true });
+  var cssFilter = filter("**/*.css", { restore: true });
+  var indexHtmlFilter = filter(['**/*', '!**/index.html'], { restore: true });
+
+  gulp.src(tmpPath + '/index.html')
+    .pipe(useref())      // Concatenate with gulp-useref
+    .pipe(jsFilter)
+    .pipe(uglify())             // Minify any javascript sources
+    .pipe(jsFilter.restore)
+    .pipe(cssFilter)
+    .pipe(csso())               // Minify any CSS sources
+    .pipe(cssFilter.restore)
+    .pipe(indexHtmlFilter)
+    .pipe(rev())                // Rename the concatenated files (but not index.html)
+    .pipe(indexHtmlFilter.restore)
+    .pipe(revReplace())         // Substitute in new filenames
+    .pipe(gulp.dest(tmpPath))
+    .on('end', done);
+});
+
+gulp.task('clean-unused-files:web', ['optimize-files:web'], function(done) {
+  var tmpPath = './platforms/web/www';
+  var jsFilter = filter(["**/*.js", "!**/cesium-*.js"]);
+  var cssFilter = filter(["**/*.css", "!**/cesium-*.css"]);
+
+  es.concat(
+    gulp.src(tmpPath + '/js/**/*.js', {read: false})
+      .pipe(jsFilter)
+      .pipe(clean()),
+
+    gulp.src(tmpPath + '/css/**/*.css', {read: false})
+      .pipe(cssFilter)
+      .pipe(clean())
+  )
+  .on ('end', done);
+});
+
+gulp.task('clean-unused-directories:web', ['clean-unused-files:web'], function(done) {
+  var tmpPath = './platforms/web/www';
+  return del([
+    tmpPath + '/css',
+    tmpPath + '/templates',
+    tmpPath + '/js',
+    tmpPath + '/dist',
+    tmpPath + '/lib/ionic/scss',
+    tmpPath + '/lib/ionic/css',
+    tmpPath + '/lib/ionic/js'
+  ]);
+});
+
+gulp.task('zip:web', ['clean-unused-directories:web'], function(done) {
+  var tmpPath = './platforms/web/www';
+  var version = JSON.parse(fs.readFileSync('./package.json', 'utf8')).version;
+  var fileFilter = filter(['**', '!*/templates', '!*/css', '!*/js']);
+
+  gulp.src(tmpPath + '/**/*.*')
+    .pipe(zip('cesium-web-'+version+'.zip'))
+    .pipe(fileFilter)
+    .pipe(gulp.dest('./platforms/web/build'))
+    .on('end', done);
+});
+
+gulp.task('build:web', ['zip:web'], function(done) {
+  var version = JSON.parse(fs.readFileSync('./package.json', 'utf8')).version;
+  gutil.log(gutil.colors.green("Build for web created at: 'plateforms/web/build/cesium-web-" + version + ".zip'"));
+  return del([
+      './tmp'
+    ]);
+});
diff --git a/hooks/after_prepare/020_remove_code.js b/hooks/after_prepare/020_remove_code.js
new file mode 100755
index 0000000000000000000000000000000000000000..b0d2e08949ce0101ad375a8ed6f5b26051424ce4
--- /dev/null
+++ b/hooks/after_prepare/020_remove_code.js
@@ -0,0 +1,64 @@
+#!/usr/bin/env node
+"use strict";
+var gulp = require('gulp');
+var gutil = require('gulp-util');
+var path = require("path");
+var removeCode = require('gulp-remove-code');
+var removeHtml = require('gulp-html-remove');
+var es = require('event-stream');
+var ngAnnotate = require('gulp-ng-annotate');
+var htmlmin = require('gulp-htmlmin');
+
+var cmd = process.env.CORDOVA_CMDLINE;
+var rootdir = process.argv[2];
+var argv = require('yargs').argv;
+
+if (rootdir) {
+
+  // go through each of the platform directories that have been prepared
+  var platforms = (process.env.CORDOVA_PLATFORMS ? process.env.CORDOVA_PLATFORMS.split(',') : []);
+
+  for(var x=0; x<platforms.length; x++) {
+
+    var platform = platforms[x].trim().toLowerCase();
+
+    var wwwPath;
+    if(platform == 'android') {
+      wwwPath = path.join(rootdir, 'platforms', platform, 'assets', 'www');
+    } else {
+      wwwPath = path.join(rootdir, 'platforms', platform, 'www');
+    }
+
+    var templatesPath = path.join(wwwPath, 'templates');
+    var jsPath = path.join(wwwPath, 'js');
+    var distJsPath = path.join(wwwPath, 'dist', 'dist_js', 'app');
+
+    // Removing unused code for device...
+    es.concat(
+      // Remove unused HTML tags
+      gulp.src(templatesPath + '/**/*.html')
+        .pipe(removeCode({device: true}))
+        .pipe(removeHtml('.hidden-xs.hidden-sm'))
+        .pipe(removeHtml('.hidden-device'))
+        .pipe(removeHtml('[remove-if][remove-if="device"]'))
+        .pipe(htmlmin())
+        .pipe(gulp.dest(templatesPath)),
+
+      gulp.src(path.join(wwwPath, 'index.html'))
+        .pipe(removeCode({device: true}))
+        .pipe(removeHtml('.hidden-xs.hidden-sm'))
+        .pipe(removeHtml('.hidden-device'))
+        .pipe(removeHtml('[remove-if][remove-if="device"]'))
+        .pipe(htmlmin())
+        .pipe(gulp.dest(wwwPath)),
+
+      // Remove unused JS code
+      gulp.src(jsPath +  + '/**/*.js')
+        .pipe(removeCode({device: true}))
+        .pipe(ngAnnotate({single_quotes: true}))
+        .pipe(gulp.dest(distJsPath))
+     );
+
+  }
+}
+
diff --git a/hooks/after_prepare/021_template_cache.js b/hooks/after_prepare/021_template_cache.js
new file mode 100755
index 0000000000000000000000000000000000000000..fc2327d362354e6a1c7a5903c0eed3a34ce35a36
--- /dev/null
+++ b/hooks/after_prepare/021_template_cache.js
@@ -0,0 +1,41 @@
+#!/usr/bin/env node
+"use strict";
+var gulp = require('gulp');
+var gutil = require('gulp-util');
+var path = require("path");
+var templateCache = require('gulp-angular-templatecache');
+
+var cmd = process.env.CORDOVA_CMDLINE;
+var rootdir = process.argv[2];
+var argv = require('yargs').argv;
+
+if (rootdir) {
+
+  // go through each of the platform directories that have been prepared
+  var platforms = (process.env.CORDOVA_PLATFORMS ? process.env.CORDOVA_PLATFORMS.split(',') : []);
+
+  for(var x=0; x<platforms.length; x++) {
+
+    var platform = platforms[x].trim().toLowerCase();
+
+    var wwwPath;
+    if(platform == 'android') {
+      wwwPath = path.join(rootdir, 'platforms', platform, 'assets', 'www');
+    } else {
+      wwwPath = path.join(rootdir, 'platforms', platform, 'www');
+    }
+
+    var templatesPath = path.join(wwwPath, 'templates');
+    var distJsPath = path.join(wwwPath, 'dist', 'dist_js', 'app');
+
+    // Concat templates into a JS
+    gulp.src(templatesPath + '/**/*.html')
+      .pipe(templateCache({
+        standalone:true,
+        module:"cesium.templates",
+        root: "templates/"
+       }))
+      .pipe(gulp.dest(distJsPath));
+  }
+}
+
diff --git a/hooks/after_prepare/040_useref.js b/hooks/after_prepare/040_useref.js
new file mode 100755
index 0000000000000000000000000000000000000000..c82c360100ad0d1f40944c83c5c6cda36b8b4fd4
--- /dev/null
+++ b/hooks/after_prepare/040_useref.js
@@ -0,0 +1,63 @@
+#!/usr/bin/env node
+"use strict";
+var gulp = require('gulp');
+var gutil = require('gulp-util');
+var path = require("path");
+var es = require('event-stream');
+var useref = require('gulp-useref');
+var filter = require('gulp-filter');
+var uglify = require('gulp-uglify');
+var csso = require('gulp-csso');
+var rev = require('gulp-rev');
+var revReplace = require('gulp-rev-replace');
+
+var cmd = process.env.CORDOVA_CMDLINE;
+var rootdir = process.argv[2];
+var argv = require('yargs').argv;
+
+var skip = true;
+if (cmd.indexOf("--release") > -1 || cmd.indexOf("--useref") > -1) {
+    skip = false;
+}
+
+if (rootdir && !skip) {
+
+  // go through each of the platform directories that have been prepared
+  var platforms = (process.env.CORDOVA_PLATFORMS ? process.env.CORDOVA_PLATFORMS.split(',') : []);
+
+  for(var x=0; x<platforms.length; x++) {
+
+    var platform = platforms[x].trim().toLowerCase();
+
+    var wwwPath;
+    if(platform == 'android') {
+      wwwPath = path.join(rootdir, 'platforms', platform, 'assets', 'www');
+    } else {
+      wwwPath = path.join(rootdir, 'platforms', platform, 'www');
+    }
+
+    var indexPath = path.join(wwwPath, 'index.html');
+
+    var jsFilter = filter(["**/*.js", "!**/vendor/*"], { restore: true });
+    var cssFilter = filter("**/*.css", { restore: true });
+    var indexHtmlFilter = filter(['**/*', '!**/index.html'], { restore: true });
+
+    // Removing unused code for device...
+    es.concat(
+      gulp.src(indexPath)
+        .pipe(useref())      // Concatenate with gulp-useref
+        .pipe(jsFilter)
+        .pipe(uglify())             // Minify any javascript sources
+        .pipe(jsFilter.restore)
+        .pipe(cssFilter)
+        .pipe(csso())               // Minify any CSS sources
+        .pipe(cssFilter.restore)
+        .pipe(indexHtmlFilter)
+        .pipe(rev())                // Rename the concatenated files (but not index.html)
+        .pipe(indexHtmlFilter.restore)
+        .pipe(revReplace())         // Substitute in new filenames
+        .pipe(gulp.dest(wwwPath))
+     );
+  }
+}
+
diff --git a/hooks/after_prepare/050_clean_unused_directories.js b/hooks/after_prepare/050_clean_unused_directories.js
new file mode 100755
index 0000000000000000000000000000000000000000..29fbfcbcf6352b7441d6156aaf6625599a5f42d5
--- /dev/null
+++ b/hooks/after_prepare/050_clean_unused_directories.js
@@ -0,0 +1,53 @@
+#!/usr/bin/env node
+"use strict";
+var gulp = require('gulp');
+var gutil = require('gulp-util');
+var allConfig = require('../../app/config.json');
+var path = require("path");
+var del = require('del');
+
+var cmd = process.env.CORDOVA_CMDLINE;
+var rootdir = process.argv[2];
+var argv = require('yargs').argv;
+
+var skip = true;
+if (cmd.indexOf("--release") > -1 || cmd.indexOf("--useref") > -1) {
+    skip = false;
+}
+
+if (rootdir && !skip) {
+
+  // go through each of the platform directories that have been prepared
+  var platforms = (process.env.CORDOVA_PLATFORMS ? process.env.CORDOVA_PLATFORMS.split(',') : []);
+
+  for(var x=0; x<platforms.length; x++) {
+
+    var platform = platforms[x].trim().toLowerCase();
+
+    var wwwPath;
+    if(platform == 'android') {
+      wwwPath = path.join(rootdir, 'platforms', platform, 'assets', 'www');
+    } else {
+      wwwPath = path.join(rootdir, 'platforms', platform, 'www');
+    }
+
+    // Clean unused directories
+    console.log('Cleaning dir ' + path.join(wwwPath, 'lib', '**'));
+    del([
+      path.join(wwwPath, 'i18n'),
+      path.join(wwwPath, 'js'),
+      path.join(wwwPath, 'templates'),
+      path.join(wwwPath, 'css'),
+      path.join(wwwPath, 'dist'),
+      path.join(wwwPath, 'js'),
+      path.join(wwwPath, 'cordova-js-src'),
+      path.join(wwwPath, 'lib', '**'),
+      // Keep Ionic lib/ionic/fonts directory
+      '!'+path.join(wwwPath, 'lib'),
+      '!'+path.join(wwwPath, 'lib', 'ionic'),
+      '!'+path.join(wwwPath, 'lib', 'ionic', 'fonts'),
+      '!'+path.join(wwwPath, 'lib', 'ionic', 'fonts', '*.*')
+    ]);
+  }
+}
+
diff --git a/hooks/after_prepare/ionic-minify.js b/hooks/after_prepare/ionic-minify.js
deleted file mode 100755
index 1ab2576cd51a7c363429ad9d59e3c966ab89aff9..0000000000000000000000000000000000000000
--- a/hooks/after_prepare/ionic-minify.js
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env node
-"use strict";
-var path = require("path");
-var ionic_minify_1 = require("ionic-minify");
-var config = require("../minify-conf.json");
-var minify = config.alwaysRun;
-var cmd = process.env.CORDOVA_CMDLINE;
-var rootDir = process.argv[2];
-var platforms = process.env.CORDOVA_PLATFORMS.split(',');
-var platformPath = path.join(rootDir, "platforms");
-if (cmd.indexOf("--release") > -1 || cmd.indexOf("--minify") > -1) {
-    if (cmd.indexOf("--release") > -1) {
-        console.log("WARN: The use of the --release flag is deprecated!! Use --minify instead!");
-    }
-    minify = true;
-}
-config.showErrStack = (config.showErrStack || false);
-config.jsOptions.fromString = true;
-if (minify === true) {
-    var ionicMinify = new ionic_minify_1.Minifier(config, platforms, platformPath);
-    console.log("Starting minifying your files...");
-    ionicMinify.run();
-}
diff --git a/hooks/minify-conf.json b/hooks/minify-conf.json
deleted file mode 100755
index 0d62bf6d44d79487c41dea41d0c440bb3a283f64..0000000000000000000000000000000000000000
--- a/hooks/minify-conf.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-    "foldersToProcess": [
-      "js",
-      "css",
-      "img"
-    ],
-    "jpgOptions":{
-      "quality": 50
-    },
-    "jsOptions": {
-      "compress": {
-        "drop_console": true
-      }
-    },
-    "cssOptions": {
-      "keepSpecialComments": 0
-    },
-    "alwaysRun": false,
-    "showErrStack": false
-}
diff --git a/ionic.project b/ionic.project
index 60c28f09c62e40b096b55ecb5d342cae63fdff93..614a09d13bc3a564929cf819562577dcf5c3f73b 100644
--- a/ionic.project
+++ b/ionic.project
@@ -7,6 +7,9 @@
   ],
   "gulpStartupTasks": [
     "sass",
+    "templatecache",
+    "ng_translate",
+    "ng_annotate",
     "watch"
   ],
   "defaultBrowser": "chrome",
diff --git a/package.json b/package.json
index 74871fa262b23b5b231afeae0c1124e71336206e..6a651a0e409584680bfc87ed9dd394e5cf2a7fdc 100644
--- a/package.json
+++ b/package.json
@@ -1,8 +1,9 @@
 {
   "name": "cesium",
-  "version": "0.1.15",
+  "version": "0.1.16",
   "description": "A webapp client for Duniter network",
   "dependencies": {
+    "delete-empty": "^0.1.3",
     "gulp": "^3.9.1",
     "gulp-bump": "^2.1.0",
     "gulp-concat": "^2.2.0",
@@ -14,11 +15,31 @@
   },
   "devDependencies": {
     "bower": "^1.7.3",
+    "cordova-uglify": "^0.2.3",
+    "del": "^2.2.0",
+    "fs": "0.0.2",
+    "gulp": "^3.9.1",
+    "gulp-angular-templatecache": "^1.8.0",
+    "gulp-angular-translate": "^0.1.4",
+    "gulp-clean": "^0.3.2",
+    "gulp-csso": "^2.0.0",
+    "gulp-filter": "^4.0.0",
     "gulp-header": "^1.7.1",
+    "gulp-html-remove": "^0.1.1",
+    "gulp-htmlmin": "^2.0.0",
+    "gulp-jshint": "^2.0.1",
+    "gulp-ng-annotate": "^2.0.0",
     "gulp-ng-constant": "^1.1.0",
     "gulp-remove-code": "^1.0.2",
+    "gulp-rev": "^7.0.0",
+    "gulp-rev-replace": "^0.4.3",
+    "gulp-uglify": "^1.5.3",
+    "gulp-useref": "^3.1.0",
     "gulp-util": "^2.2.14",
+    "gulp-zip": "^3.2.0",
     "ionic-minify": "^2.0.8",
+    "jshint": "^2.9.2",
+    "mv": "^2.1.1",
     "shelljs": "^0.3.0",
     "yargs": "^4.3.1"
   },
@@ -34,7 +55,8 @@
     {
       "locator": "https://github.com/phonegap/phonegap-plugin-barcodescanner.git",
       "id": "phonegap-plugin-barcodescanner"
-    }
+    },
+    "cordova-plugin-camera"
   ],
   "cordovaPlatforms": [
     "ios",
diff --git a/scripts/afterBuild.js b/scripts/afterBuild.js
new file mode 100644
index 0000000000000000000000000000000000000000..3bf6bcdf60a9596a015bf6ccdb84a8f4a45a2c41
--- /dev/null
+++ b/scripts/afterBuild.js
@@ -0,0 +1,23 @@
+module.exports = function(ctx) {
+    // make sure android platform is part of build
+    if (ctx.opts.platforms.indexOf('android') < 0) {
+        return;
+    }
+    var fs = ctx.requireCordovaModule('fs'),
+        path = ctx.requireCordovaModule('path'),
+        deferral = ctx.requireCordovaModule('q').defer();
+
+    var platformRoot = path.join(ctx.opts.projectRoot, 'platforms/android');
+    var apkFileLocation = path.join(platformRoot, 'build/outputs/apk/android-debug.apk');
+
+    fs.stat(apkFileLocation, function(err,stats) {
+        if (err) {
+                deferral.reject('Operation failed');
+        } else {
+            console.log('Size of ' + apkFileLocation + ' is ' + stats.size +' bytes');
+            deferral.resolve();
+        }
+    });
+
+    return deferral.promise;
+};
diff --git a/www/css/style-no-device.css b/www/css/style-no-device.css
new file mode 100644
index 0000000000000000000000000000000000000000..ee28d33120b3993998754458b99131b19e16972f
--- /dev/null
+++ b/www/css/style-no-device.css
@@ -0,0 +1,3 @@
+.hidden-no-device {
+  display: none !important;
+}
diff --git a/www/i18n/locale-en.json b/www/i18n/locale-en.json
index ae58968463d4e2826f88d1cda13bf32d0a641d9d..0f42130a215fcf8404e0d78d3afea371021390e4 100644
--- a/www/i18n/locale-en.json
+++ b/www/i18n/locale-en.json
@@ -39,7 +39,7 @@
     "CURRENCY": "Currency",
     "CURRENCIES": "Currencies",
     "ACCOUNT": "My Account",
-    "TRANSFER": "Pay",
+    "TRANSFER": "Send",
     "SCAN": "Scan",
     "SETTINGS": "Settings"
   },
@@ -146,8 +146,7 @@
     "BTN_MEMBERSHIP_RENEW": "Renew membership",
     "BTN_MEMBERSHIP_OUT": "Revoke membership",
     "BTN_SEND_IDENTITY": "Publish pseudonym (without register)",
-    "BTN_DETAILS": "Display technical details",
-    "BTN_HIDE_DETAILS": "Hide technical details",
+    "BTN_SHOW_DETAILS": "Display technical details",
     "NEW": {
       "TITLE": "New Account",
       "SLIDE_1_TITLE": "Select a money:",
diff --git a/www/i18n/locale-fr-FR.json b/www/i18n/locale-fr-FR.json
index cef3ceb4cdf9e4ec7ebec15b37792e636ada6b1c..7e1ad2021e9f9be534c918e46e62ef855e94b40b 100644
--- a/www/i18n/locale-fr-FR.json
+++ b/www/i18n/locale-fr-FR.json
@@ -147,7 +147,6 @@
     "BTN_MEMBERSHIP_OUT": "Arrêter son adhésion",
     "BTN_SEND_IDENTITY": "Publier le pseudonyme",
     "BTN_SHOW_DETAILS": "Afficher les infos techniques",
-    "BTN_HIDE_DETAILS": "Masquer les infos techniques",
     "NEW": {
       "TITLE": "Inscription",
       "SLIDE_1_TITLE": "Choix de la monnaie :",
diff --git a/www/index.html b/www/index.html
index c672d2c177d51ac368c1039c43709bded7860b44..d3a7ee04b32c1d2f71dc8f39d1463d9a380cd7b6 100644
--- a/www/index.html
+++ b/www/index.html
@@ -5,73 +5,81 @@
     <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
     <title></title>
 
+    <!-- build:css dist_css/cesium.css -->
+      <link href="css/ionic.app.css" rel="stylesheet">
+      <link href="css/style.css" rel="stylesheet">
+      <!--removeIf(device)-->
+      <link href="css/style-no-device.css" rel="stylesheet">
+      <!--endRemoveIf(device)-->
+    <!-- endbuild -->
 
-    <link href="lib/ionic/css/ionic.css" rel="stylesheet">
+    <!-- build:js dist_js/cesium.js -->
+      <!-- vendor js -->
+      <script src="js/vendor/moment.min.js"></script>
+      <script src="js/vendor/moment.fr.js"></script>
+      <script src="js/vendor/numeral.js"></script>
+      <script src="js/vendor/socket-io.js"></script>
+      <script src="js/vendor/underscore.js"></script>
+      <script src="js/vendor/qrcode.min.js"></script>
 
-    <!-- compiled css output -->
-    <link href="css/ionic.app.css" rel="stylesheet">
+      <!-- ionic/angularjs js -->
+      <script src="lib/ionic/js/ionic.bundle.js"></script>
+      <script src="lib/ionic/js/ionic.material.min.js"></script>
+      <script src="lib/ionic/js/ionic-native-transitions.min.js"></script>
+      <script src="lib/ionic/js/angular/angular-resource.min.js"></script>
+      <script src="lib/ionic/js/angular/angular-translate.min.js"></script>
+      <script src="lib/ionic/js/angular/angular-translate-loader-static-files.min.js"></script>
+      <script src="lib/ionic/js/angular/angular-messages.min.js"></script>
+      <script src="lib/ionic/js/angular/angular-moment.min.js"></script>
 
-    <link href="css/style.css" rel="stylesheet">
+      <!-- crypto libs -->
+      <script src="js/vendor/scrypt-em.js"></script>
+      <script src="js/vendor/nacl_factory.js"></script>
+      <script src="js/vendor/base58.js"></script>
+      <script src="js/vendor/base64.js"></script>
 
-    <!-- vendor js -->
-    <script src="js/vendor/moment.min.js"></script>
-    <script src="js/vendor/moment.fr.js"></script>
-    <script src="js/vendor/numeral.js"></script>
-    <script src="js/vendor/socket-io.js"></script>
-    <script src="js/vendor/underscore.js"></script>
-    <script src="js/vendor/qrcode.min.js"></script>
+      <!--removeIf(no-device)-->
+      <script src="js/vendor/ng-cordova.min.js"></script>
+      <script src="cordova.js"></script>
+      <!--endRemoveIf(no-device)-->
 
-    <!-- ionic/angularjs js -->
-    <script src="lib/ionic/js/ionic.bundle.js"></script>
-    <script src="lib/ionic/js/ionic.material.min.js"></script>
-    <script src="lib/ionic/js/ionic-native-transitions.min.js"></script>
-    <script src="lib/ionic/js/angular/angular-resource.min.js"></script>
-    <script src="lib/ionic/js/angular/angular-translate.min.js"></script>
-    <script src="lib/ionic/js/angular/angular-translate-loader-static-files.min.js"></script>
-    <script src="lib/ionic/js/angular/angular-messages.min.js"></script>
-    <script src="lib/ionic/js/angular/angular-moment.min.js"></script>
+      <!-- config -->
+      <script src="js/config.js"></script>
 
-    <!-- crypto libs -->
-    <script src="js/vendor/scrypt-em.js"></script>
-    <script src="js/vendor/nacl_factory.js"></script>
-    <script src="js/vendor/base58.js"></script>
-    <script src="js/vendor/base64.js"></script>
+      <!-- services -->
+      <script src="dist/dist_js/app/services/crypto-services.js"></script>
+      <script src="dist/dist_js/app/services/utils-services.js"></script>
+      <script src="dist/dist_js/app/services/storage-services.js"></script>
+      <script src="dist/dist_js/app/services/device-services.js"></script>
+      <script src="dist/dist_js/app/services/wallet-services.js"></script>
+      <script src="dist/dist_js/app/services/bma-services.js"></script>
+      <script src="dist/dist_js/app/services.js"></script>
 
-    <!-- cordova script (this will be a 404 during development) -->
-    <script src="js/vendor/ng-cordova.min.js"></script>
-    <script src="cordova.js"></script>
+      <!-- entities -->
+      <script src="dist/dist_js/app/entity/peer.js"></script>
 
-    <!-- config -->
-    <script src="js/config.js"></script>
+      <!-- controllers -->
+      <script src="dist/dist_js/app/controllers/app-controllers.js"></script>
+      <script src="dist/dist_js/app/controllers/home-controllers.js"></script>
+      <script src="dist/dist_js/app/controllers/wot-controllers.js"></script>
+      <script src="dist/dist_js/app/controllers/peer-controllers.js"></script>
+      <script src="dist/dist_js/app/controllers/currency-controllers.js"></script>
+      <script src="dist/dist_js/app/controllers/currency-charts-controllers.js"></script>
+      <script src="dist/dist_js/app/controllers/wallet-controllers.js"></script>
+      <script src="dist/dist_js/app/controllers/transfer-controllers.js"></script>
+      <script src="dist/dist_js/app/controllers/settings-controllers.js"></script>
+      <script src="dist/dist_js/app/controllers.js"></script>
 
-    <!-- services -->
-    <script src="js/services/crypto-services.js"></script>
-    <script src="js/services/utils-services.js"></script>
-    <script src="js/services/device-services.js"></script>
-    <script src="js/services/wallet-services.js"></script>
-    <script src="js/services/bma-services.js"></script>
-    <script src="js/services.js"></script>
+      <!-- templates -->
+    <script src="dist/dist_js/app/templates.js"></script>
+    <script src="dist/dist_js/app/translations.js"></script>
 
-    <!-- entities -->
-    <script src="js/entity/peer.js"></script>
-
-    <!-- controllers -->
-    <script src="js/controllers/app-controllers.js"></script>
-    <script src="js/controllers/home-controllers.js"></script>
-    <script src="js/controllers/wot-controllers.js"></script>
-    <script src="js/controllers/peer-controllers.js"></script>
-    <script src="js/controllers/currency-controllers.js"></script>
-    <script src="js/controllers/currency-charts-controllers.js"></script>
-    <script src="js/controllers/wallet-controllers.js"></script>
-    <script src="js/controllers/transfer-controllers.js"></script>
-    <script src="js/controllers/settings-controllers.js"></script>
-    <script src="js/controllers.js"></script>
-
-    <!-- App -->
-    <script src="js/app.js"></script>
+      <!-- App -->
+      <script src="dist/dist_js/app/app.js"></script>
+    <!-- endbuild -->
 
   </head>
-  <body ng-app="cesium" class="platform-ionic">
+  <body ng-app="cesium" ng-strict-di>
   <ion-nav-view></ion-nav-view>
   </body>
 </html>
diff --git a/www/js/app.js b/www/js/app.js
index 36c6aa4c6c381d2eedeb6c6d10eea33589405254..fb11723c951979b7a3df39d0a98076ee475c25ab 100644
--- a/www/js/app.js
+++ b/www/js/app.js
@@ -4,7 +4,12 @@
 // 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
 // the 2nd parameter is an array of 'requires'
 // 'starter.controllers' is found in controllers.js
-angular.module('cesium', ['ionic', 'ngCordova', 'ionic-material', 'ngMessages', 'pascalprecht.translate', 'angularMoment', 'cesium.controllers', 'ngAnimate', 'ionic-native-transitions'])
+angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'ngAnimate', 'pascalprecht.translate', 'angularMoment',
+  'cesium.controllers', 'cesium.templates','cesium.translations',
+   // removeIf(no-device)
+  'ngCordova', 'ionic-native-transitions',
+   // endRemoveIf(no-device)
+  ])
 
   .filter('formatInteger', function() {
     return function(input) {
@@ -85,10 +90,9 @@ angular.module('cesium', ['ionic', 'ngCordova', 'ionic-material', 'ngMessages',
 
   // Translation i18n
   .config(function ($translateProvider) {
-    $translateProvider.useStaticFilesLoader({
-        prefix: 'i18n/locale-',
-        suffix: '.json'
-    })
+    'ngInject';
+
+    $translateProvider
     .uniformLanguageTag('bcp47')
     .determinePreferredLanguage()
     // Cela fait bugger les placeholder (pb d'affichage des accents en FR)
@@ -99,51 +103,42 @@ angular.module('cesium', ['ionic', 'ngCordova', 'ionic-material', 'ngMessages',
     .useStorage('localStorage');
   })
 
-  .config(['$httpProvider', 'APP_CONFIG', function($httpProvider, APP_CONFIG) {
+  .config(function($httpProvider, APP_CONFIG) {
+    'ngInject';
+    // Set default timeout
     $httpProvider.defaults.timeout = !!APP_CONFIG.TIMEOUT ? APP_CONFIG.TIMEOUT : 4000 /* default timeout */;
-  }])
 
-  .config(['$compileProvider', 'APP_CONFIG', function($compileProvider, APP_CONFIG) {
-      $compileProvider.debugInfoEnabled(!!APP_CONFIG.DEBUG);
-  }])
+    //Enable cross domain calls
+    $httpProvider.defaults.useXDomain = true;
+
+    //Remove the header used to identify ajax call  that would prevent CORS from working
+    delete $httpProvider.defaults.headers.common['X-Requested-With'];
+  })
+
+  .config(function($compileProvider, APP_CONFIG) {
+    'ngInject';
+
+    $compileProvider.debugInfoEnabled(!!APP_CONFIG.DEBUG);
+  })
 
   .config(function($animateProvider) {
-      $animateProvider.classNameFilter( /\banimate-/ );
-  })
-
-  .config(['$ionicNativeTransitionsProvider', 'APP_CONFIG', function($ionicNativeTransitionsProvider, APP_CONFIG){
-    if (!!APP_CONFIG.NATIVE_TRANSITION) {
-      $ionicNativeTransitionsProvider.enable(true);
-      $ionicNativeTransitionsProvider.setDefaultOptions({
-          duration: 400, // in milliseconds (ms), default 400,
-          slowdownfactor: 4, // overlap views (higher number is more) or no overlap (1), default 4
-          iosdelay: -1, // ms to wait for the iOS webview to update before animation kicks in, default -1
-          androiddelay: -1, // same as above but for Android, default -1
-          winphonedelay: -1, // same as above but for Windows Phone, default -1,
-          fixedPixelsTop: 0, // the number of pixels of your fixed header, default 0 (iOS and Android)
-          fixedPixelsBottom: 0, // the number of pixels of your fixed footer (f.i. a tab bar), default 0 (iOS and Android)
-          triggerTransitionEvent: '$ionicView.afterEnter', // internal ionic-native-transitions option
-          backInOppositeDirection: false // Takes over default back transition and state back transition to use the opposite direction transition to go back
-      });
-      $ionicNativeTransitionsProvider.setDefaultTransition({
-        type: 'slide',
-        direction: 'left'
-      });
-      $ionicNativeTransitionsProvider.setDefaultBackTransition({
-          type: 'slide',
-          direction: 'right'
-      });
-    }
-    else {
-      $ionicNativeTransitionsProvider.enable(false);
-    }
-  }])
+    'ngInject';
+    $animateProvider.classNameFilter( /\banimate-/ );
+  })
+
+  // removeIf(no-device)
+  .config(function($ionicNativeTransitionsProvider){
+    'ngInject';
+    // Use native transition
+    var enableNativeTransitions = ionic.Platform.isAndroid() || ionic.Platform.isIOS();
+    $ionicNativeTransitionsProvider.enable(enableNativeTransitions);
+  })
+  // endRemoveIf(no-device)
 
   .config(function($ionicConfigProvider) {
-      if (ionic.Platform.isAndroid()) {
-        $ionicConfigProvider.scrolling.jsScrolling(false);
-      }
-      $ionicConfigProvider.views.maxCache(5);
+    'ngInject';
+    $ionicConfigProvider.scrolling.jsScrolling(false);
+    $ionicConfigProvider.views.maxCache(5);
   })
 
   // Add new compare-to directive (need for form validation)
@@ -167,28 +162,30 @@ angular.module('cesium', ['ionic', 'ngCordova', 'ionic-material', 'ngMessages',
   })
 
   // Add a copy-on-click directive
-  .directive('copyOnClick', ['$window', 'Device', function ($window, Device) {
-      return {
-          restrict: 'A',
-          link: function (scope, element, attrs) {
-              element.bind('click', function () {
-                if (!Device.clipboard.enable) {
-                  if ($window.getSelection && !$window.getSelection().toString() && this.value) {
-                    this.setSelectionRange(0, this.value.length);
-                  }
-                }
-              });
-              element.bind('hold', function () {
-                if (Device.clipboard.enable && this.value) {
-                  Device.clipboard.copy(this.value);
-                }
-              });
+  .directive('copyOnClick', function ($window, Device) {
+    'ngInject';
+    return {
+      restrict: 'A',
+      link: function (scope, element, attrs) {
+        element.bind('click', function () {
+          if (!Device.clipboard.enable) {
+            if ($window.getSelection && !$window.getSelection().toString() && this.value) {
+              this.setSelectionRange(0, this.value.length);
+            }
           }
-      };
-  }])
+        });
+        element.bind('hold', function () {
+          if (Device.clipboard.enable && this.value) {
+            Device.clipboard.copy(this.value);
+          }
+        });
+      }
+    };
+  })
 
   // Add a select-on-click directive
-  .directive('selectOnClick', ['$window', function ($window) {
+  .directive('selectOnClick', function ($window) {
+    'ngInject';
       return {
           restrict: 'A',
           link: function (scope, element, attrs) {
@@ -199,20 +196,29 @@ angular.module('cesium', ['ionic', 'ngCordova', 'ionic-material', 'ngMessages',
               });
           }
       };
-  }])
+  })
 
 .run(function($rootScope, amMoment, $translate, Device) {
-
-  $rootScope.translations = [];
+  'ngInject';
 
   // We use 'Device.ready()' instead of '$ionicPlatform.ready()', because it could be call many times
   Device.ready()
   .then(function() {
-    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
-    // for form inputs)
+
+    // Keyboard
     if (window.cordova && window.cordova.plugins.Keyboard) {
+      // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
+      // for form inputs)
       cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
+
+      // iOS: do not push header up when opening keyboard
+      // (see http://ionicframework.com/docs/api/page/keyboard/)
+      if (ionic.Platform.isIOS()) {
+        cordova.plugins.Keyboard.disableScroll(true);
+      }
     }
+
+    // Status bar
     if (window.StatusBar) {
       // org.apache.cordova.statusbar required
       StatusBar.styleDefault();
@@ -227,6 +233,5 @@ angular.module('cesium', ['ionic', 'ngCordova', 'ionic-material', 'ngMessages',
   // Set up moment translation
   $rootScope.$on('$translateChangeSuccess', $rootScope.onLanguageChange);
 
-
 })
 ;
diff --git a/www/js/config.js b/www/js/config.js
index 38d6abedc822718fb9c7746fe10ecb139d38d873..a3bb9fc053e4c803393aacf22c914eff788c5747 100644
--- a/www/js/config.js
+++ b/www/js/config.js
@@ -13,9 +13,8 @@ angular.module("cesium.config", [])
 	"NEW_ISSUE_LINK": "https://github.com/duniter/cesium/issues/new?labels=bug",
 	"TIMEOUT": 4000,
 	"DEBUG": false,
-	"NATIVE_TRANSITION": false,
-	"VERSION": "0.1.15",
-	"BUILD_DATE": "2016-06-09T19:28:59.710Z"
+	"VERSION": "0.1.16",
+	"BUILD_DATE": "2016-06-13T13:42:57.980Z"
 })
 
 ;
\ No newline at end of file
diff --git a/www/js/controllers.js b/www/js/controllers.js
index 0dadbc693df0c099895902dd36e86b435dbc6414..aaef8c848ed1a3c65b01f81ed6d2a6edcc8e12bf 100644
--- a/www/js/controllers.js
+++ b/www/js/controllers.js
@@ -9,12 +9,4 @@ angular.module('cesium.controllers', [
     'cesium.transfer.controllers',
     'cesium.settings.controllers'
   ])
-
-  .config(function($httpProvider) {
-    //Enable cross domain calls
-   $httpProvider.defaults.useXDomain = true;
-
-    //Remove the header used to identify ajax call  that would prevent CORS from working
-    delete $httpProvider.defaults.headers.common['X-Requested-With'];
-  })
 ;
diff --git a/www/js/controllers/app-controllers.js b/www/js/controllers/app-controllers.js
index a0c61a98c8e0b9038c97d1feab53a74f3002fabf..14b48ce1cd12efd88874e067d06f72f05aaca0ea 100644
--- a/www/js/controllers/app-controllers.js
+++ b/www/js/controllers/app-controllers.js
@@ -2,14 +2,18 @@
 angular.module('cesium.app.controllers', ['cesium.services'])
 
   .config(function($httpProvider) {
+    'ngInject';
+
     //Enable cross domain calls
-   $httpProvider.defaults.useXDomain = true;
+    $httpProvider.defaults.useXDomain = true;
 
     //Remove the header used to identify ajax call  that would prevent CORS from working
     delete $httpProvider.defaults.headers.common['X-Requested-With'];
   })
 
   .config(function($stateProvider, $urlRouterProvider) {
+    'ngInject';
+
     $stateProvider
 
       .state('app', {
@@ -29,6 +33,8 @@ angular.module('cesium.app.controllers', ['cesium.services'])
 ;
 
 function LoginModalController($scope, $rootScope, $ionicModal, Wallet, CryptoUtils, UIUtils, $q, $state, $timeout, $ionicSideMenuDelegate, $ionicHistory) {
+  'ngInject';
+
   // Login modal
   $scope.loginModal = null;
   $scope.loginData = {
@@ -134,6 +140,11 @@ function LoginModalController($scope, $rootScope, $ionicModal, Wallet, CryptoUti
     if(!$scope.loginForm.$valid) {
       return;
     }
+    // removeIf(no-device)
+    if (window.cordova && cordova.plugins.Keyboard) {
+      cordova.plugins.Keyboard.close();
+    }
+    // endRemoveIf(no-device)
     UIUtils.loading.show();
 
     $scope.loginModal.hide()
@@ -233,12 +244,10 @@ function LoginModalController($scope, $rootScope, $ionicModal, Wallet, CryptoUti
 function AppController($scope, $rootScope, $ionicModal, $state, $ionicSideMenuDelegate, UIUtils, $q, $timeout,
   CryptoUtils, BMA, Wallet, APP_CONFIG, $ionicHistory, Device, $translate, $ionicPopover
   ) {
+  'ngInject';
 
   $scope.knownCurrencies = null;
   $scope.search = { text: '', results: {} };
-  $scope.isExpanded = false;
-  $scope.hasHeaderFabLeft = false;
-  $scope.hasHeaderFabRight = false;
   $scope.config = APP_CONFIG;
 
   LoginModalController.call(this, $scope, $rootScope, $ionicModal, Wallet, CryptoUtils, UIUtils, $q, $state, $timeout, $ionicSideMenuDelegate, $ionicHistory);
@@ -304,70 +313,6 @@ function AppController($scope, $rootScope, $ionicModal, $state, $ionicSideMenuDe
   ////////////////////////////////////////
   // Layout Methods
   ////////////////////////////////////////
-  /*var navIcons = document.getElementsByClassName('ion-navicon');
-  for (var i = 0; i < navIcons.length; i++) {
-      navIcons.addEventListener('click', function() {
-          this.classList.toggle('active');
-      });
-  }*/
-
-  $scope.hideNavBar = function() {
-      document.getElementsByTagName('ion-nav-bar')[0].style.display = 'none';
-  };
-
-  $scope.showNavBar = function() {
-      document.getElementsByTagName('ion-nav-bar')[0].style.display = 'block';
-  };
-
-  $scope.noHeader = function() {
-      var content = document.getElementsByTagName('ion-content');
-      for (var i = 0; i < content.length; i++) {
-          if (content[i].classList.contains('has-header')) {
-              content[i].classList.toggle('has-header');
-          }
-      }
-  };
-
-  $scope.setExpanded = function(bool) {
-      $scope.isExpanded = bool;
-  };
-
-  $scope.setHeaderFab = function(location) {
-      var hasHeaderFabLeft = false;
-      var hasHeaderFabRight = false;
-
-      switch (location) {
-          case 'left':
-              hasHeaderFabLeft = true;
-              break;
-          case 'right':
-              hasHeaderFabRight = true;
-              break;
-      }
-
-      $scope.hasHeaderFabLeft = hasHeaderFabLeft;
-      $scope.hasHeaderFabRight = hasHeaderFabRight;
-  };
-
-  $scope.hasHeader = function() {
-      var content = document.getElementsByTagName('ion-content');
-      for (var i = 0; i < content.length; i++) {
-          if (!content[i].classList.contains('has-header')) {
-              content[i].classList.toggle('has-header');
-          }
-      }
-  };
-
-  $scope.hideHeader = function() {
-      $scope.hideNavBar();
-      $scope.noHeader();
-  };
-
-  $scope.showHeader = function() {
-      $scope.showNavBar();
-      $scope.hasHeader();
-  };
-
   $scope.showFab = function(id, timeout) {
     if (!timeout) {
       timeout = 900;
diff --git a/www/js/controllers/currency-charts-controllers.js b/www/js/controllers/currency-charts-controllers.js
index 7ea54720a9003b78321989852eb15a6c9d207063..57189f67101a43df02d629c32ef20f664b2c63af 100644
--- a/www/js/controllers/currency-charts-controllers.js
+++ b/www/js/controllers/currency-charts-controllers.js
@@ -2,10 +2,16 @@
 angular.module('cesium.currency-charts.controllers', ['cesium.services'])
 
 .config(function($stateProvider, $urlRouterProvider) {
+  'ngInject';
+
   $stateProvider
 
     .state('app.currency_ud', {
       url: "/currency/ud",
+      nativeTransitions: {
+          "type": "flip",
+          "direction": "up"
+      },
       views: {
         'menuContent': {
           templateUrl: "templates/currency/charts/ud.html",
@@ -21,6 +27,7 @@ angular.module('cesium.currency-charts.controllers', ['cesium.services'])
 ;
 
 function CurrencyUdController($scope, BMA, $q) {
+  'ngInject';
 
   $scope.$on('$ionicView.enter', function(e, $state) {
       $scope.loadUds()
diff --git a/www/js/controllers/currency-controllers.js b/www/js/controllers/currency-controllers.js
index c2b8c6abb4deaee41619f602c486f063f82b6d2f..fbe7871e5e9313d05f7b1595a784b8b6bf80e2f4 100644
--- a/www/js/controllers/currency-controllers.js
+++ b/www/js/controllers/currency-controllers.js
@@ -2,6 +2,8 @@
 angular.module('cesium.currency.controllers', ['cesium.services'])
 
 .config(function($stateProvider, $urlRouterProvider) {
+  'ngInject';
+
   $stateProvider
 
     .state('app.currency_lookup', {
@@ -36,6 +38,10 @@ angular.module('cesium.currency.controllers', ['cesium.services'])
 
     .state('app.view_peer', {
       url: "/peer/:server",
+      nativeTransitions: {
+          "type": "flip",
+          "direction": "right"
+      },
       views: {
         'menuContent': {
           templateUrl: "templates/currency/view_peer.html",
@@ -54,6 +60,7 @@ angular.module('cesium.currency.controllers', ['cesium.services'])
 ;
 
 function CurrencyLookupController($scope, $state, $q, $timeout, UIUtils, APP_CONFIG, BMA) {
+  'ngInject';
 
   $scope.selectedCurrency = '';
   $scope.knownCurrencies = [];
diff --git a/www/js/controllers/home-controllers.js b/www/js/controllers/home-controllers.js
index 7bcb615d76f6b88bde2486bb1f60245236be302e..15e35ca934a7dce0ad2a75615b515e0581e5df28 100644
--- a/www/js/controllers/home-controllers.js
+++ b/www/js/controllers/home-controllers.js
@@ -2,6 +2,7 @@
 angular.module('cesium.home.controllers', ['cesium.services'])
 
   .config(function($stateProvider, $urlRouterProvider) {
+    'ngInject';
     $stateProvider
 
       .state('app.home', {
@@ -37,6 +38,7 @@ angular.module('cesium.home.controllers', ['cesium.services'])
 
 
 function NewAccountWizardController($scope, $ionicModal, $state, $ionicSideMenuDelegate, UIUtils, $q, $timeout, CryptoUtils, BMA, Wallet) {
+  'ngInject';
 
   $scope.accountData = {};
   $scope.accountForm = {};
@@ -196,12 +198,14 @@ function NewAccountWizardController($scope, $ionicModal, $state, $ionicSideMenuD
 }
 
 function HomeController($scope, $ionicModal, $state, $ionicSideMenuDelegate, UIUtils, $q, $timeout, CryptoUtils, BMA, Wallet,  APP_CONFIG) {
+  'ngInject';
 
   NewAccountWizardController.call(this, $scope, $ionicModal, $state, $ionicSideMenuDelegate, UIUtils, $q, $timeout, CryptoUtils, BMA, Wallet);
 
 }
 
 function JoinController($scope, $ionicModal, $state, $ionicSideMenuDelegate, UIUtils, $q, $timeout, CryptoUtils, BMA, Wallet, APP_CONFIG) {
+  'ngInject';
 
   NewAccountWizardController.call(this, $scope, $ionicModal, $state, $ionicSideMenuDelegate, UIUtils, $q, $timeout, CryptoUtils, BMA, Wallet);
 
diff --git a/www/js/controllers/peer-controllers.js b/www/js/controllers/peer-controllers.js
index 54fe5bbbffb85298545571ef2d262707daa666d3..e0a1cce0a4700a61fbc6f156f7a9004c2f9743d2 100644
--- a/www/js/controllers/peer-controllers.js
+++ b/www/js/controllers/peer-controllers.js
@@ -1,5 +1,6 @@
 
 function PeerController($scope, $rootScope, $ionicSlideBoxDelegate, $ionicModal, BMA, $controller) {
+  'ngInject';
 
   $scope.$on('$ionicView.enter', function(e, $state) {
     $scope.showPeer($state.stateParams.server);
diff --git a/www/js/controllers/settings-controllers.js b/www/js/controllers/settings-controllers.js
index 5e4ba0c0adbc113bc8f34fcfb9990bcb7617d1f7..2acb70ac068c4239f4db4efdb3926a7c0db3f6aa 100644
--- a/www/js/controllers/settings-controllers.js
+++ b/www/js/controllers/settings-controllers.js
@@ -1,7 +1,8 @@
 
 angular.module('cesium.settings.controllers', ['cesium.services', 'cesium.currency.controllers'])
-
   .config(function($stateProvider, $urlRouterProvider) {
+    'ngInject';
+
     $stateProvider
 
       .state('app.settings', {
@@ -20,6 +21,7 @@ angular.module('cesium.settings.controllers', ['cesium.services', 'cesium.curren
 ;
 
 function SettingsController($scope, $state, UIUtils, Wallet, $translate, BMA, $q, $ionicPopup, $timeout, localStorage) {
+  'ngInject';
 
   $scope.locales = [
       {id:'fr-FR', label:'Français'},
diff --git a/www/js/controllers/transfer-controllers.js b/www/js/controllers/transfer-controllers.js
index 8e418bf50d31b6560931ec5511025d207d242387..bc56de1a8ea4d29c697286ebb7f821c0770823c8 100644
--- a/www/js/controllers/transfer-controllers.js
+++ b/www/js/controllers/transfer-controllers.js
@@ -1,6 +1,7 @@
 angular.module('cesium.transfer.controllers', ['cesium.services', 'cesium.currency.controllers'])
 
   .config(function($stateProvider, $urlRouterProvider) {
+    'ngInject';
     $stateProvider
 
       .state('app.new_transfer', {
@@ -39,6 +40,7 @@ angular.module('cesium.transfer.controllers', ['cesium.services', 'cesium.curren
 ;
 
 function TransferController($scope, $rootScope, $ionicModal, $state, BMA, Wallet, UIUtils, $timeout, Device, $ionicPopover) {
+  'ngInject';
 
   TransferModalController.call(this, $scope, $rootScope, $ionicModal, $state, BMA, Wallet, UIUtils, $timeout, Device, $ionicPopover);
 
@@ -64,6 +66,7 @@ function TransferController($scope, $rootScope, $ionicModal, $state, BMA, Wallet
 }
 
 function TransferModalController($scope, $rootScope, $ionicModal, $state, BMA, Wallet, UIUtils, $timeout, Device, $ionicPopover) {
+  'ngInject';
 
   $scope.walletData = {};
   $scope.convertedBalance = 0;
diff --git a/www/js/controllers/wallet-controllers.js b/www/js/controllers/wallet-controllers.js
index fbece05cbdface3372efa2d78744214b6961aba3..26a8125987e695952d33424c1d0b66ef266e6d30 100644
--- a/www/js/controllers/wallet-controllers.js
+++ b/www/js/controllers/wallet-controllers.js
@@ -2,6 +2,7 @@
 angular.module('cesium.wallet.controllers', ['cesium.services', 'cesium.currency.controllers'])
 
   .config(function($stateProvider, $urlRouterProvider) {
+    'ngInject';
     $stateProvider
 
       .state('app.view_wallet', {
@@ -21,6 +22,7 @@ angular.module('cesium.wallet.controllers', ['cesium.services', 'cesium.currency
 
 function WalletController($scope, $rootScope, $state, $q, $ionicPopup, $ionicActionSheet, $timeout,
   UIUtils, Wallet, BMA, $translate, Device, $ionicPopover) {
+  'ngInject';
 
   $scope.walletData = null;
   $scope.convertedBalance = null;
@@ -276,53 +278,6 @@ function WalletController($scope, $rootScope, $state, $q, $ionicPopup, $ionicAct
     .catch(UIUtils.onError('ERROR.REFRESH_WALLET_DATA'));
   };
 
-  // Triggered on a button click, or some other target
- $scope.showActionsheet = function() {
-
-  $translate(['ACCOUNT.MENU_TITLE', 'ACCOUNT.BTN_MEMBERSHIP_IN', 'ACCOUNT.BTN_MEMBERSHIP_RENEW', 'ACCOUNT.BTN_MEMBERSHIP_OUT', 'ACCOUNT.BTN_SEND_IDENTITY',
-  'ACCOUNT.POPUP_REGISTER.HELP', 'ACCOUNT.BTN_DETAILS', 'COMMON.BTN_ADD_ACCOUNT', 'COMMON.BTN_CANCEL'])
-    .then(function (translations) {
-
-      var buttons = [];
-      var callbacks = [];
-      if ($scope.walletData.requirements.needMembership) {
-        buttons.push({text: translations['ACCOUNT.BTN_MEMBERSHIP_IN']});
-        callbacks.push(function(){$scope.membershipIn();});
-      }
-      if ($scope.walletData.requirements.needRenew) {
-        buttons.push({text: translations['ACCOUNT.BTN_MEMBERSHIP_RENEW']});
-        callbacks.push(function(){$scope.membershipRenew();});
-      }
-      if ($scope.walletData.requirements.needSelf) {
-        buttons.push({text: translations['ACCOUNT.BTN_SEND_IDENTITY']});
-        callbacks.push(function(){$scope.self();});
-      }
-      if ($scope.walletData.requirements.needMembershipOut) {
-        buttons.push({text: translations['ACCOUNT.BTN_MEMBERSHIP_OUT']});
-        callbacks.push(function(){$scope.membershipOut();});
-      }
-
-      // Show the action sheet
-      var hideMenu = $ionicActionSheet.show({
-        buttons: buttons,
-        titleText: translations['ACCOUNT.MENU_TITLE'],
-        cancelText: translations['COMMON.BTN_CANCEL'],
-        cancel: function() {
-            // add cancel code..
-          },
-        buttonClicked: function(index) {
-          callbacks[index]();
-          return true;
-        }
-      });
-
-      // Hide the sheet after 3 seconds
-      $timeout(function() {
-        hideMenu();
-      }, 3000);
-    });
-  };
-
   $scope.showQRCode = function(id, text, timeout) {
     if (!!$scope.qrcode) {
       return;
diff --git a/www/js/controllers/wot-controllers.js b/www/js/controllers/wot-controllers.js
index d69eafbb107c77c7c54471b17545a1fb790e79c7..3311175a61ad3a4a5c819f2569d3a562e6945ce6 100644
--- a/www/js/controllers/wot-controllers.js
+++ b/www/js/controllers/wot-controllers.js
@@ -1,6 +1,7 @@
 angular.module('cesium.wot.controllers', ['cesium.services'])
 
   .config(function($stateProvider, $urlRouterProvider) {
+    'ngInject';
     $stateProvider
 
       .state('app.wot_lookup', {
@@ -25,6 +26,10 @@ angular.module('cesium.wot.controllers', ['cesium.services'])
 
       .state('app.view_certifications', {
         url: "/wot/cert/:pub",
+        nativeTransitions: {
+            "type": "flip",
+            "direction": "right"
+        },
         views: {
           'menuContent': {
             templateUrl: "templates/wot/view_certifications.html",
@@ -43,6 +48,7 @@ angular.module('cesium.wot.controllers', ['cesium.services'])
 ;
 
 function WotLookupController($scope, BMA, $state, UIUtils, $timeout, Device, Wallet) {
+  'ngInject';
 
   $scope.onWotSearchChanged = function() {
     $scope.search.looking = true;
@@ -126,6 +132,7 @@ function WotLookupController($scope, BMA, $state, UIUtils, $timeout, Device, Wal
 }
 
 function WotIdentityViewController($scope, $state, BMA, Wallet, UIUtils, $q, $timeout, Device) {
+  'ngInject';
 
   $scope.identity = {};
   $scope.hasSelf = false;
@@ -228,26 +235,6 @@ function WotIdentityViewController($scope, $state, BMA, Wallet, UIUtils, $q, $ti
       });
   };
 
-  // Certify click
-  $scope.certifyIdentity = function(identity) {
-    $scope.loadWallet()
-    .then(function(walletData) {
-      UIUtils.loading.show();
-
-      // TODO: ask user confirm - see issue https://github.com/duniter/cesium/issues/12
-      Wallet.certify($scope.identity.uid,
-                  $scope.identity.pub,
-                  $scope.identity.timestamp,
-                  $scope.identity.sig)
-      .then(function() {
-        UIUtils.loading.hide();
-        UIUtils.alert.info('INFO.CERTIFICATION_DONE');
-      })
-      .catch(UIUtils.onError('ERROR.SEND_CERTIFICATION_FAILED'));
-    })
-    .catch(UIUtils.onError('ERROR.LOGIN_FAILED'));
-  };
-
   // Copy
   $scope.copy = function(value) {
     if (value && Device.isEnable()) {
@@ -264,15 +251,11 @@ function WotIdentityViewController($scope, $state, BMA, Wallet, UIUtils, $q, $ti
     }
   };
 
-  // Set Header
-  $scope.$parent.showHeader();
-  $scope.isExpanded = false;
-  $scope.$parent.setExpanded(false);
-  $scope.$parent.setHeaderFab(false);
   $scope.showFab('fab-transfer');
 }
 
 function WotCertificationsViewController($scope, $state, BMA, Wallet, UIUtils, $q, $timeout, Device) {
+  'ngInject';
 
   $scope.certifications = [];
   $scope.identity = {};
@@ -430,11 +413,4 @@ function WotCertificationsViewController($scope, $state, BMA, Wallet, UIUtils, $
   $scope.doUpdate = function() {
     $scope.loadCertifications($scope.identity.pub, true);
   };
-
-  // Set Header
-  $scope.$parent.showHeader();
-  $scope.isExpanded = false;
-  $scope.$parent.setExpanded(false);
-  $scope.$parent.setHeaderFab(false);
-
 }
diff --git a/www/js/services.js b/www/js/services.js
index d93c2aabfbc425605ab444e07b24115f05beb886..6e0d3ed9d2e461e63120bfc40ae454f9b65cbea4 100644
--- a/www/js/services.js
+++ b/www/js/services.js
@@ -3,6 +3,7 @@ angular.module('cesium.services', [
     'cesium.bma.services',
     'cesium.crypto.services',
     'cesium.utils.services',
+    'cesium.storage.services',
     'cesium.device.services',
     'cesium.wallet.services'
     ])
diff --git a/www/js/services/bma-services.js b/www/js/services/bma-services.js
index a4329586ad365de4ecaef6cc92d2a9fe3f1b9b1a..390270542ca780cf473fd555834975337e30f2dc 100644
--- a/www/js/services/bma-services.js
+++ b/www/js/services/bma-services.js
@@ -4,6 +4,7 @@ angular.module('cesium.bma.services', ['ngResource',
     'cesium.config'])
 
 .factory('BMA', function($http, $q, APP_CONFIG) {
+  'ngInject';
 
   function BMA(server, timeout) {
 
diff --git a/www/js/services/crypto-services.js b/www/js/services/crypto-services.js
index 112356b52a31e9728bb33e89854339c7362df2ad..c386bba2f599498275254d144d969beb81eb8068 100644
--- a/www/js/services/crypto-services.js
+++ b/www/js/services/crypto-services.js
@@ -3,168 +3,169 @@
 angular.module('cesium.crypto.services', ['ngResource'])
 
 .factory('CryptoUtils', function($q, $timeout) {
+  'ngInject';
 
-    var async_load_scrypt = function() {
-        if (typeof module !== 'undefined' && module.exports) {
-            // add node.js implementations
-            require('scrypt-em');
-            return scrypt_module_factory();
-        }
-        else if (scrypt_module_factory !== null){
-            return scrypt_module_factory();
-        }
-        else {
-            return $timeout(async_load_scrypt, 100);
-        }
-    },
+  var async_load_scrypt = function() {
+      if (typeof module !== 'undefined' && module.exports) {
+          // add node.js implementations
+          require('scrypt-em');
+          return scrypt_module_factory();
+      }
+      else if (scrypt_module_factory !== null){
+          return scrypt_module_factory();
+      }
+      else {
+          return $timeout(async_load_scrypt, 100);
+      }
+  },
 
-    async_load_nacl = function() {
-        if (typeof module !== 'undefined' && module.exports) {
-            // add node.js implementations
-            require('nacl_factory');
-            return nacl_factory.instantiate();
-        }
-        else if (nacl_factory !== null){
-            return nacl_factory.instantiate();
-        }
-        else {
-            return $timeout(async_load_nacl, 100);
-        }
-    },
+  async_load_nacl = function() {
+      if (typeof module !== 'undefined' && module.exports) {
+          // add node.js implementations
+          require('nacl_factory');
+          return nacl_factory.instantiate();
+      }
+      else if (nacl_factory !== null){
+          return nacl_factory.instantiate();
+      }
+      else {
+          return $timeout(async_load_nacl, 100);
+      }
+  },
 
-    async_load_base58 = function() {
-        if (typeof module !== 'undefined' && module.exports) {
-            // add node.js implementations
-            require('base58');
-            return Base58;
-        }
-        else if (Base58 !== null){
-            return Base58;
-        }
-        else {
-            return $timeout(async_load_base58, 100);
-        }
-    },
+  async_load_base58 = function() {
+      if (typeof module !== 'undefined' && module.exports) {
+          // add node.js implementations
+          require('base58');
+          return Base58;
+      }
+      else if (Base58 !== null){
+          return Base58;
+      }
+      else {
+          return $timeout(async_load_base58, 100);
+      }
+  },
 
-    async_load_base64 = function() {
-        if (typeof module !== 'undefined' && module.exports) {
-            // add node.js implementations
-            require('base58');
-            return Base64;
-        }
-        else if (Base64 !== null){
-            return Base64;
-        }
-        else {
-            return setTimetout(async_load_base64, 100);
-        }
-    };
+  async_load_base64 = function() {
+      if (typeof module !== 'undefined' && module.exports) {
+          // add node.js implementations
+          require('base58');
+          return Base64;
+      }
+      else if (Base64 !== null){
+          return Base64;
+      }
+      else {
+          return setTimetout(async_load_base64, 100);
+      }
+  };
 
-    function CryptoUtils() {
-      var
-        // Const
-        crypto_sign_BYTES= 64,
-        SEED_LENGTH= 32, // Length of the key
-        SCRYPT_PARAMS= {
-                "N":4096,
-                "r":16,
-                "p":1
-              },
+  function CryptoUtils() {
+    var
+      // Const
+      crypto_sign_BYTES= 64,
+      SEED_LENGTH= 32, // Length of the key
+      SCRYPT_PARAMS= {
+              "N":4096,
+              "r":16,
+              "p":1
+            },
 
-        // load libraries
-        scrypt = async_load_scrypt(),
-        nacl = async_load_nacl(),
-        base58 = async_load_base58(),
-        base64 = async_load_base64(),
-        decode_utf8 = function(s) {
-            var i, d = unescape(encodeURIComponent(s)), b = new Uint8Array(d.length);
-            for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i);
-            return b;
-        },
-        encode_base58 = function(a) {
-            return base58.encode(a);
-        },
-        hash_sha256 = function(message) {
-          return $q(function(resolve, reject) {
-            var msg = decode_utf8(message);
-            var hash = nacl.to_hex(nacl.crypto_hash_sha256(msg));
-            resolve(hash.toUpperCase());
-          });
-        },
-
-       /**
-        * Create a key pair, from salt+password, and  return a wallet object
-        */
-        connect = function(salt, password) {
-              return $q(function(resolve, reject) {
-                  var seed = scrypt.crypto_scrypt(
-                                              nacl.encode_utf8(password),
-                                              nacl.encode_utf8(salt),
-                                              4096, 16, 1, 32 // TODO: put in var SCRYPT_PARAMS
-                                           );
-                   var keypair = nacl.crypto_sign_keypair_from_seed(seed);
-                   resolve(keypair);
-                });
-          },
+      // load libraries
+      scrypt = async_load_scrypt(),
+      nacl = async_load_nacl(),
+      base58 = async_load_base58(),
+      base64 = async_load_base64(),
+      decode_utf8 = function(s) {
+          var i, d = unescape(encodeURIComponent(s)), b = new Uint8Array(d.length);
+          for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i);
+          return b;
+      },
+      encode_base58 = function(a) {
+          return base58.encode(a);
+      },
+      hash_sha256 = function(message) {
+        return $q(function(resolve, reject) {
+          var msg = decode_utf8(message);
+          var hash = nacl.to_hex(nacl.crypto_hash_sha256(msg));
+          resolve(hash.toUpperCase());
+        });
+      },
 
-        /**
-        * Verify a signature of a message, for a pubkey
-        */
-        verify = function (message, signature, pubkey) {
+     /**
+      * Create a key pair, from salt+password, and  return a wallet object
+      */
+      connect = function(salt, password) {
             return $q(function(resolve, reject) {
-                var msg = decode_utf8(message);
-                var sig = base64.decode(signature);
-                var pub = base58.decode(pubkey);
-                var m = new Uint8Array(crypto_sign_BYTES + msg.length);
-                var sm = new Uint8Array(crypto_sign_BYTES + msg.length);
-                var i;
-                for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i];
-                for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i];
-
-                // Call to verification lib...
-                var verified = nacl.crypto_sign_open(sm, pub) !== null;
-                resolve(verified);
-            });
+                var seed = scrypt.crypto_scrypt(
+                                            nacl.encode_utf8(password),
+                                            nacl.encode_utf8(salt),
+                                            4096, 16, 1, 32 // TODO: put in var SCRYPT_PARAMS
+                                         );
+                 var keypair = nacl.crypto_sign_keypair_from_seed(seed);
+                 resolve(keypair);
+              });
         },
 
-        /**
-        * Sign a message, from a wallet
-        */
-        sign = function(message, keypair) {
+      /**
+      * Verify a signature of a message, for a pubkey
+      */
+      verify = function (message, signature, pubkey) {
           return $q(function(resolve, reject) {
-              var m = decode_utf8(message);
-              var sk = keypair.signSk;
-              var signedMsg = nacl.crypto_sign(m, sk);
-              var sig = new Uint8Array(crypto_sign_BYTES);
-              for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i];
-              var signature = base64.encode(sig);
-              resolve(signature);
-            });
-        };
+              var msg = decode_utf8(message);
+              var sig = base64.decode(signature);
+              var pub = base58.decode(pubkey);
+              var m = new Uint8Array(crypto_sign_BYTES + msg.length);
+              var sm = new Uint8Array(crypto_sign_BYTES + msg.length);
+              var i;
+              for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i];
+              for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i];
+
+              // Call to verification lib...
+              var verified = nacl.crypto_sign_open(sm, pub) !== null;
+              resolve(verified);
+          });
+      },
 
-      // Service's exposed methods
-      return {
-          /*
-          TODO: uncomment if need to expose
-          nacl: nacl,
-          scrypt: scrypt,
-          base58: base58,
-          base64: base64,*/
-          util: {
-            encode_utf8: nacl.encode_utf8,
-            decode_utf8: decode_utf8,
-            encode_base58: encode_base58,
-            hash: hash_sha256
-          },
-          connect: connect,
-          sign: sign,
-          verify: verify
-          //,isCompatible: isCompatible
-       };
-    }
+      /**
+      * Sign a message, from a wallet
+      */
+      sign = function(message, keypair) {
+        return $q(function(resolve, reject) {
+            var m = decode_utf8(message);
+            var sk = keypair.signSk;
+            var signedMsg = nacl.crypto_sign(m, sk);
+            var sig = new Uint8Array(crypto_sign_BYTES);
+            for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i];
+            var signature = base64.encode(sig);
+            resolve(signature);
+          });
+      };
+
+    // Service's exposed methods
+    return {
+        /*
+        TODO: uncomment if need to expose
+        nacl: nacl,
+        scrypt: scrypt,
+        base58: base58,
+        base64: base64,*/
+        util: {
+          encode_utf8: nacl.encode_utf8,
+          decode_utf8: decode_utf8,
+          encode_base58: encode_base58,
+          hash: hash_sha256
+        },
+        connect: connect,
+        sign: sign,
+        verify: verify
+        //,isCompatible: isCompatible
+     };
+  }
 
-    var service = CryptoUtils();
-    service.instance = CryptoUtils;
+  var service = CryptoUtils();
+  service.instance = CryptoUtils;
   return service;
 })
 ;
diff --git a/www/js/services/device-services.js b/www/js/services/device-services.js
index c5a3146e8eb0401034445a15297859f298231124..a15ff56223fbb6f5b527a84390e5cf74a3a0ec04 100644
--- a/www/js/services/device-services.js
+++ b/www/js/services/device-services.js
@@ -1,8 +1,14 @@
 
 angular.module('cesium.device.services', ['ngResource', 'cesium.utils.services'])
 
-.factory('Device', ['UIUtils', '$translate', '$ionicPopup', '$cordovaClipboard', '$cordovaBarcodeScanner', '$q', '$cordovaCamera', '$ionicPlatform',
-  function(UIUtils, $translate, $ionicPopup, $cordovaClipboard, $cordovaBarcodeScanner, $q, $cordovaCamera, $ionicPlatform) {
+.factory('Device',
+  function(UIUtils, $translate, $ionicPopup, $q,
+    // removeIf(no-device)
+    $cordovaClipboard, $cordovaBarcodeScanner, $cordovaCamera,
+    // endRemoveIf(no-device)
+    $ionicPlatform
+  ) {
+  'ngInject';
 
   var CONST = {
     MAX_HEIGHT: 400,
@@ -132,6 +138,6 @@ angular.module('cesium.device.services', ['ngResource', 'cesium.utils.services']
       scan: scan
     }
   };
-}])
+})
 
 ;
diff --git a/www/js/services/storage-services.js b/www/js/services/storage-services.js
new file mode 100644
index 0000000000000000000000000000000000000000..f4e68fb3ee170a694178aba6c407289d7455f033
--- /dev/null
+++ b/www/js/services/storage-services.js
@@ -0,0 +1,20 @@
+angular.module('cesium.storage.services', ['ngResource'])
+
+.factory('localStorage', function($window) {
+  'ngInject';
+  return {
+    put: function(key, value) {
+      $window.localStorage[key] = value;
+    },
+    get: function(key, defaultValue) {
+      return $window.localStorage[key] || defaultValue;
+    },
+    setObject: function(key, value) {
+      $window.localStorage[key] = JSON.stringify(value);
+    },
+    getObject: function(key) {
+      return JSON.parse($window.localStorage[key] || '{}');
+    }
+  };
+})
+;
diff --git a/www/js/services/utils-services.js b/www/js/services/utils-services.js
index 8e45b7babdb76675338863c61c56149d939ed71c..69441573a462bba5ec6e5c4c3162fea061df1466 100644
--- a/www/js/services/utils-services.js
+++ b/www/js/services/utils-services.js
@@ -1,9 +1,8 @@
-//var Base58, Base64, scrypt_module_factory = null, nacl_factory = null;
-
 angular.module('cesium.utils.services', ['ngResource'])
 
-.factory('UIUtils', ['$ionicLoading', '$ionicPopup', '$translate', '$q', 'ionicMaterialInk', 'ionicMaterialMotion', '$window', '$timeout',
+.factory('UIUtils',
   function($ionicLoading, $ionicPopup, $translate, $q, ionicMaterialInk, ionicMaterialMotion, $window, $timeout) {
+  'ngInject';
 
   var loadingTextCache=null;
 
@@ -215,9 +214,10 @@ angular.module('cesium.utils.services', ['ngResource'])
       resize: resizeImageFromFile
     }
   };
-}])
+})
 
-.factory('localStorage', ['$window', function($window) {
+.factory('localStorage', function($window) {
+  'ngInject';
   return {
     put: function(key, value) {
       $window.localStorage[key] = value;
@@ -232,71 +232,5 @@ angular.module('cesium.utils.services', ['ngResource'])
       return JSON.parse($window.localStorage[key] || '{}');
     }
   };
-}])
-
-// See http://plnkr.co/edit/vJQXtsZiX4EJ6Uvw9xtG?p=preview
-.factory('$focus', ['$timeout', '$window', function($timeout, $window) {
-  return function(id) {
-    // timeout makes sure that it is invoked after any other event has been triggered.
-    // e.g. click events that need to run before the focus or
-    // inputs elements that are in a disabled state but are enabled when those events
-    // are triggered.
-    $timeout(function() {
-      var element = $window.document.getElementById(id);
-      if(element)
-        element.focus();
-    });
-  };
-}])
-
-.service('ModalService', ['$ionicModal', '$rootScope', '$q', '$controllers', function($ionicModal, $rootScope, $q, $controllers) {
-
-  var show = function(tpl, $scope) {
-
-    var promise;
-    $scope = $scope || $rootScope.$new();
-
-    promise = $q(function(resolve, reject){
-      $ionicModal.fromTemplateUrl(tpl, {
-        scope: $scope,
-        animation: 'slide-in-up'
-      }).then(function(modal) {
-        $scope.modal = modal;
-        $scope.modal.show();
-      });
-    });
-
-     $scope.openModal = function() {
-       $scope.modal.show();
-     };
-     $scope.closeModal = function(result) {
-       $scope.modal.hide();
-       resolve(result);
-     };
-     $scope.$on('$destroy', function() {
-       $scope.modal.remove();
-     });
-
-    return promise;
-  };
-
-  return {
-    show: show
-  };
-
-}])
-
-.directive('eventFocus', function(focus) {
-  return function(scope, elem, attr) {
-    elem.on(attr.eventFocus, function() {
-      focus(attr.eventFocusId);
-    });
-
-    // Removes bound events in the element itself
-    // when the scope is destroyed
-    scope.$on('$destroy', function() {
-      elem.off(attr.eventFocus);
-    });
-  };
 })
 ;
diff --git a/www/js/services/wallet-services.js b/www/js/services/wallet-services.js
index cf08f8c6c2372b616149f7f181941d5717e4f043..67246131b75118b2070b3c527289b0f4e997c10c 100644
--- a/www/js/services/wallet-services.js
+++ b/www/js/services/wallet-services.js
@@ -1,8 +1,8 @@
-//var Base58, Base64, scrypt_module_factory = null, nacl_factory = null;
 
 angular.module('cesium.wallet.services', ['ngResource', 'cesium.bma.services', 'cesium.crypto.services', 'cesium.utils.services'])
 
-.factory('Wallet', ['$q', 'CryptoUtils', 'BMA', '$translate', 'localStorage', function($q, CryptoUtils, BMA, $translate, localStorage) {
+.factory('Wallet', function($q, CryptoUtils, BMA, $translate, localStorage) {
+  'ngInject';
 
   Wallet = function(id) {
 
@@ -823,5 +823,4 @@ angular.module('cesium.wallet.services', ['ngResource', 'cesium.bma.services', '
 
   service.instance = Wallet;
   return service;
-}])
-;
+});
diff --git a/www/js/vendor/qrcode.js b/www/js/vendor/qrcode.js
deleted file mode 100644
index 5507c154ffc1b9d061c55d88268a26eeba49a36e..0000000000000000000000000000000000000000
--- a/www/js/vendor/qrcode.js
+++ /dev/null
@@ -1,614 +0,0 @@
-/**
- * @fileoverview
- * - Using the 'QRCode for Javascript library'
- * - Fixed dataset of 'QRCode for Javascript library' for support full-spec.
- * - this library has no dependencies.
- * 
- * @author davidshimjs
- * @see <a href="http://www.d-project.com/" target="_blank">http://www.d-project.com/</a>
- * @see <a href="http://jeromeetienne.github.com/jquery-qrcode/" target="_blank">http://jeromeetienne.github.com/jquery-qrcode/</a>
- */
-var QRCode;
-
-(function () {
-	//---------------------------------------------------------------------
-	// QRCode for JavaScript
-	//
-	// Copyright (c) 2009 Kazuhiko Arase
-	//
-	// URL: http://www.d-project.com/
-	//
-	// Licensed under the MIT license:
-	//   http://www.opensource.org/licenses/mit-license.php
-	//
-	// The word "QR Code" is registered trademark of 
-	// DENSO WAVE INCORPORATED
-	//   http://www.denso-wave.com/qrcode/faqpatent-e.html
-	//
-	//---------------------------------------------------------------------
-	function QR8bitByte(data) {
-		this.mode = QRMode.MODE_8BIT_BYTE;
-		this.data = data;
-		this.parsedData = [];
-
-		// Added to support UTF-8 Characters
-		for (var i = 0, l = this.data.length; i < l; i++) {
-			var byteArray = [];
-			var code = this.data.charCodeAt(i);
-
-			if (code > 0x10000) {
-				byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18);
-				byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12);
-				byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6);
-				byteArray[3] = 0x80 | (code & 0x3F);
-			} else if (code > 0x800) {
-				byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12);
-				byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6);
-				byteArray[2] = 0x80 | (code & 0x3F);
-			} else if (code > 0x80) {
-				byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6);
-				byteArray[1] = 0x80 | (code & 0x3F);
-			} else {
-				byteArray[0] = code;
-			}
-
-			this.parsedData.push(byteArray);
-		}
-
-		this.parsedData = Array.prototype.concat.apply([], this.parsedData);
-
-		if (this.parsedData.length != this.data.length) {
-			this.parsedData.unshift(191);
-			this.parsedData.unshift(187);
-			this.parsedData.unshift(239);
-		}
-	}
-
-	QR8bitByte.prototype = {
-		getLength: function (buffer) {
-			return this.parsedData.length;
-		},
-		write: function (buffer) {
-			for (var i = 0, l = this.parsedData.length; i < l; i++) {
-				buffer.put(this.parsedData[i], 8);
-			}
-		}
-	};
-
-	function QRCodeModel(typeNumber, errorCorrectLevel) {
-		this.typeNumber = typeNumber;
-		this.errorCorrectLevel = errorCorrectLevel;
-		this.modules = null;
-		this.moduleCount = 0;
-		this.dataCache = null;
-		this.dataList = [];
-	}
-
-	QRCodeModel.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData);this.dataCache=null;},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col){throw new Error(row+","+col);}
-	return this.modules[row][col];},getModuleCount:function(){return this.moduleCount;},make:function(){this.makeImpl(false,this.getBestMaskPattern());},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17;this.modules=new Array(this.moduleCount);for(var row=0;row<this.moduleCount;row++){this.modules[row]=new Array(this.moduleCount);for(var col=0;col<this.moduleCount;col++){this.modules[row][col]=null;}}
-	this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(test,maskPattern);if(this.typeNumber>=7){this.setupTypeNumber(test);}
-	if(this.dataCache==null){this.dataCache=QRCodeModel.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);}
-	this.mapData(this.dataCache,maskPattern);},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getBestMaskPattern:function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}}
-	return pattern;},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth);var cs=1;this.make();for(var row=0;row<this.modules.length;row++){var y=row*cs;for(var col=0;col<this.modules[row].length;col++){var x=col*cs;var dark=this.modules[row][col];if(dark){qr_mc.beginFill(0,100);qr_mc.moveTo(x,y);qr_mc.lineTo(x+cs,y);qr_mc.lineTo(x+cs,y+cs);qr_mc.lineTo(x,y+cs);qr_mc.endFill();}}}
-	return qr_mc;},setupTimingPattern:function(){for(var r=8;r<this.moduleCount-8;r++){if(this.modules[r][6]!=null){continue;}
-	this.modules[r][6]=(r%2==0);}
-	for(var c=8;c<this.moduleCount-8;c++){if(this.modules[6][c]!=null){continue;}
-	this.modules[6][c]=(c%2==0);}},setupPositionAdjustPattern:function(){var pos=QRUtil.getPatternPosition(this.typeNumber);for(var i=0;i<pos.length;i++){for(var j=0;j<pos.length;j++){var row=pos[i];var col=pos[j];if(this.modules[row][col]!=null){continue;}
-	for(var r=-2;r<=2;r++){for(var c=-2;c<=2;c++){if(r==-2||r==2||c==-2||c==2||(r==0&&c==0)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}}}},setupTypeNumber:function(test){var bits=QRUtil.getBCHTypeNumber(this.typeNumber);for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;}
-	for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.moduleCount-8-3][Math.floor(i/3)]=mod;}},setupTypeInfo:function(test,maskPattern){var data=(this.errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.moduleCount-15+i][8]=mod;}}
-	for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.moduleCount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}}
-	this.modules[this.moduleCount-8][8]=(!test);},mapData:function(data,maskPattern){var inc=-1;var row=this.moduleCount-1;var bitIndex=7;var byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteIndex<data.length){dark=(((data[byteIndex]>>>bitIndex)&1)==1);}
-	var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask){dark=!dark;}
-	this.modules[row][col-c]=dark;bitIndex--;if(bitIndex==-1){byteIndex++;bitIndex=7;}}}
-	row+=inc;if(row<0||this.moduleCount<=row){row-=inc;inc=-inc;break;}}}}};QRCodeModel.PAD0=0xEC;QRCodeModel.PAD1=0x11;QRCodeModel.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=new QRBitBuffer();for(var i=0;i<dataList.length;i++){var data=dataList[i];buffer.put(data.mode,4);buffer.put(data.getLength(),QRUtil.getLengthInBits(data.mode,typeNumber));data.write(buffer);}
-	var totalDataCount=0;for(var i=0;i<rsBlocks.length;i++){totalDataCount+=rsBlocks[i].dataCount;}
-	if(buffer.getLengthInBits()>totalDataCount*8){throw new Error("code length overflow. ("
-	+buffer.getLengthInBits()
-	+">"
-	+totalDataCount*8
-	+")");}
-	if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);}
-	while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);}
-	while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;}
-	buffer.put(QRCodeModel.PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;}
-	buffer.put(QRCodeModel.PAD1,8);}
-	return QRCodeModel.createBytes(buffer,rsBlocks);};QRCodeModel.createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r++){var dcCount=rsBlocks[r].dataCount;var ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount);maxEcCount=Math.max(maxEcCount,ecCount);dcdata[r]=new Array(dcCount);for(var i=0;i<dcdata[r].length;i++){dcdata[r][i]=0xff&buffer.buffer[i+offset];}
-	offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount);var rawPoly=new QRPolynomial(dcdata[r],rsPoly.getLength()-1);var modPoly=rawPoly.mod(rsPoly);ecdata[r]=new Array(rsPoly.getLength()-1);for(var i=0;i<ecdata[r].length;i++){var modIndex=i+modPoly.getLength()-ecdata[r].length;ecdata[r][i]=(modIndex>=0)?modPoly.get(modIndex):0;}}
-	var totalCodeCount=0;for(var i=0;i<rsBlocks.length;i++){totalCodeCount+=rsBlocks[i].totalCount;}
-	var data=new Array(totalCodeCount);var index=0;for(var i=0;i<maxDcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<dcdata[r].length){data[index++]=dcdata[r][i];}}}
-	for(var i=0;i<maxEcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<ecdata[r].length){data[index++]=ecdata[r][i];}}}
-	return data;};var QRMode={MODE_NUMBER:1<<0,MODE_ALPHA_NUM:1<<1,MODE_8BIT_BYTE:1<<2,MODE_KANJI:1<<3};var QRErrorCorrectLevel={L:1,M:0,Q:3,H:2};var QRMaskPattern={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var QRUtil={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:(1<<10)|(1<<8)|(1<<5)|(1<<4)|(1<<2)|(1<<1)|(1<<0),G18:(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<5)|(1<<2)|(1<<0),G15_MASK:(1<<14)|(1<<12)|(1<<10)|(1<<4)|(1<<1),getBCHTypeInfo:function(data){var d=data<<10;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)>=0){d^=(QRUtil.G15<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)));}
-	return((data<<10)|d)^QRUtil.G15_MASK;},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0){d^=(QRUtil.G18<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)));}
-	return(data<<12)|d;},getBCHDigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;}
-	return digit;},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1];},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2==0;case QRMaskPattern.PATTERN001:return i%2==0;case QRMaskPattern.PATTERN010:return j%3==0;case QRMaskPattern.PATTERN011:return(i+j)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2==0;case QRMaskPattern.PATTERN101:return(i*j)%2+(i*j)%3==0;case QRMaskPattern.PATTERN110:return((i*j)%2+(i*j)%3)%2==0;case QRMaskPattern.PATTERN111:return((i*j)%3+(i+j)%2)%2==0;default:throw new Error("bad maskPattern:"+maskPattern);}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i<errorCorrectLength;i++){a=a.multiply(new QRPolynomial([1,QRMath.gexp(i)],0));}
-	return a;},getLengthInBits:function(mode,type){if(1<=type&&type<10){switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw new Error("mode:"+mode);}}else if(type<27){switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw new Error("mode:"+mode);}}else if(type<41){switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw new Error("mode:"+mode);}}else{throw new Error("type:"+type);}},getLostPoint:function(qrCode){var moduleCount=qrCode.getModuleCount();var lostPoint=0;for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount;col++){var sameCount=0;var dark=qrCode.isDark(row,col);for(var r=-1;r<=1;r++){if(row+r<0||moduleCount<=row+r){continue;}
-	for(var c=-1;c<=1;c++){if(col+c<0||moduleCount<=col+c){continue;}
-	if(r==0&&c==0){continue;}
-	if(dark==qrCode.isDark(row+r,col+c)){sameCount++;}}}
-	if(sameCount>5){lostPoint+=(3+sameCount-5);}}}
-	for(var row=0;row<moduleCount-1;row++){for(var col=0;col<moduleCount-1;col++){var count=0;if(qrCode.isDark(row,col))count++;if(qrCode.isDark(row+1,col))count++;if(qrCode.isDark(row,col+1))count++;if(qrCode.isDark(row+1,col+1))count++;if(count==0||count==4){lostPoint+=3;}}}
-	for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount-6;col++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row,col+1)&&qrCode.isDark(row,col+2)&&qrCode.isDark(row,col+3)&&qrCode.isDark(row,col+4)&&!qrCode.isDark(row,col+5)&&qrCode.isDark(row,col+6)){lostPoint+=40;}}}
-	for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount-6;row++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row+1,col)&&qrCode.isDark(row+2,col)&&qrCode.isDark(row+3,col)&&qrCode.isDark(row+4,col)&&!qrCode.isDark(row+5,col)&&qrCode.isDark(row+6,col)){lostPoint+=40;}}}
-	var darkCount=0;for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount;row++){if(qrCode.isDark(row,col)){darkCount++;}}}
-	var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;lostPoint+=ratio*10;return lostPoint;}};var QRMath={glog:function(n){if(n<1){throw new Error("glog("+n+")");}
-	return QRMath.LOG_TABLE[n];},gexp:function(n){while(n<0){n+=255;}
-	while(n>=256){n-=255;}
-	return QRMath.EXP_TABLE[n];},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var i=0;i<8;i++){QRMath.EXP_TABLE[i]=1<<i;}
-	for(var i=8;i<256;i++){QRMath.EXP_TABLE[i]=QRMath.EXP_TABLE[i-4]^QRMath.EXP_TABLE[i-5]^QRMath.EXP_TABLE[i-6]^QRMath.EXP_TABLE[i-8];}
-	for(var i=0;i<255;i++){QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]]=i;}
-	function QRPolynomial(num,shift){if(num.length==undefined){throw new Error(num.length+"/"+shift);}
-	var offset=0;while(offset<num.length&&num[offset]==0){offset++;}
-	this.num=new Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i++){this.num[i]=num[i+offset];}}
-	QRPolynomial.prototype={get:function(index){return this.num[index];},getLength:function(){return this.num.length;},multiply:function(e){var num=new Array(this.getLength()+e.getLength()-1);for(var i=0;i<this.getLength();i++){for(var j=0;j<e.getLength();j++){num[i+j]^=QRMath.gexp(QRMath.glog(this.get(i))+QRMath.glog(e.get(j)));}}
-	return new QRPolynomial(num,0);},mod:function(e){if(this.getLength()-e.getLength()<0){return this;}
-	var ratio=QRMath.glog(this.get(0))-QRMath.glog(e.get(0));var num=new Array(this.getLength());for(var i=0;i<this.getLength();i++){num[i]=this.get(i);}
-	for(var i=0;i<e.getLength();i++){num[i]^=QRMath.gexp(QRMath.glog(e.get(i))+ratio);}
-	return new QRPolynomial(num,0).mod(e);}};function QRRSBlock(totalCount,dataCount){this.totalCount=totalCount;this.dataCount=dataCount;}
-	QRRSBlock.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];QRRSBlock.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=QRRSBlock.getRsBlockTable(typeNumber,errorCorrectLevel);if(rsBlock==undefined){throw new Error("bad rs block @ typeNumber:"+typeNumber+"/errorCorrectLevel:"+errorCorrectLevel);}
-	var length=rsBlock.length/3;var list=[];for(var i=0;i<length;i++){var count=rsBlock[i*3+0];var totalCount=rsBlock[i*3+1];var dataCount=rsBlock[i*3+2];for(var j=0;j<count;j++){list.push(new QRRSBlock(totalCount,dataCount));}}
-	return list;};QRRSBlock.getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return undefined;}};function QRBitBuffer(){this.buffer=[];this.length=0;}
-	QRBitBuffer.prototype={get:function(index){var bufIndex=Math.floor(index/8);return((this.buffer[bufIndex]>>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i<length;i++){this.putBit(((num>>>(length-i-1))&1)==1);}},getLengthInBits:function(){return this.length;},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex){this.buffer.push(0);}
-	if(bit){this.buffer[bufIndex]|=(0x80>>>(this.length%8));}
-	this.length++;}};var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]];
-	
-	function _isSupportCanvas() {
-		return typeof CanvasRenderingContext2D != "undefined";
-	}
-	
-	// android 2.x doesn't support Data-URI spec
-	function _getAndroid() {
-		var android = false;
-		var sAgent = navigator.userAgent;
-		
-		if (/android/i.test(sAgent)) { // android
-			android = true;
-			var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i);
-			
-			if (aMat && aMat[1]) {
-				android = parseFloat(aMat[1]);
-			}
-		}
-		
-		return android;
-	}
-	
-	var svgDrawer = (function() {
-
-		var Drawing = function (el, htOption) {
-			this._el = el;
-			this._htOption = htOption;
-		};
-
-		Drawing.prototype.draw = function (oQRCode) {
-			var _htOption = this._htOption;
-			var _el = this._el;
-			var nCount = oQRCode.getModuleCount();
-			var nWidth = Math.floor(_htOption.width / nCount);
-			var nHeight = Math.floor(_htOption.height / nCount);
-
-			this.clear();
-
-			function makeSVG(tag, attrs) {
-				var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
-				for (var k in attrs)
-					if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]);
-				return el;
-			}
-
-			var svg = makeSVG("svg" , {'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight});
-			svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
-			_el.appendChild(svg);
-
-			svg.appendChild(makeSVG("rect", {"fill": _htOption.colorLight, "width": "100%", "height": "100%"}));
-			svg.appendChild(makeSVG("rect", {"fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template"}));
-
-			for (var row = 0; row < nCount; row++) {
-				for (var col = 0; col < nCount; col++) {
-					if (oQRCode.isDark(row, col)) {
-						var child = makeSVG("use", {"x": String(col), "y": String(row)});
-						child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template")
-						svg.appendChild(child);
-					}
-				}
-			}
-		};
-		Drawing.prototype.clear = function () {
-			while (this._el.hasChildNodes())
-				this._el.removeChild(this._el.lastChild);
-		};
-		return Drawing;
-	})();
-
-	var useSVG = document.documentElement.tagName.toLowerCase() === "svg";
-
-	// Drawing in DOM by using Table tag
-	var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () {
-		var Drawing = function (el, htOption) {
-			this._el = el;
-			this._htOption = htOption;
-		};
-			
-		/**
-		 * Draw the QRCode
-		 * 
-		 * @param {QRCode} oQRCode
-		 */
-		Drawing.prototype.draw = function (oQRCode) {
-            var _htOption = this._htOption;
-            var _el = this._el;
-			var nCount = oQRCode.getModuleCount();
-			var nWidth = Math.floor(_htOption.width / nCount);
-			var nHeight = Math.floor(_htOption.height / nCount);
-			var aHTML = ['<table style="border:0;border-collapse:collapse;">'];
-			
-			for (var row = 0; row < nCount; row++) {
-				aHTML.push('<tr>');
-				
-				for (var col = 0; col < nCount; col++) {
-					aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth + 'px;height:' + nHeight + 'px;background-color:' + (oQRCode.isDark(row, col) ? _htOption.colorDark : _htOption.colorLight) + ';"></td>');
-				}
-				
-				aHTML.push('</tr>');
-			}
-			
-			aHTML.push('</table>');
-			_el.innerHTML = aHTML.join('');
-			
-			// Fix the margin values as real size.
-			var elTable = _el.childNodes[0];
-			var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2;
-			var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2;
-			
-			if (nLeftMarginTable > 0 && nTopMarginTable > 0) {
-				elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px";	
-			}
-		};
-		
-		/**
-		 * Clear the QRCode
-		 */
-		Drawing.prototype.clear = function () {
-			this._el.innerHTML = '';
-		};
-		
-		return Drawing;
-	})() : (function () { // Drawing in Canvas
-		function _onMakeImage() {
-			this._elImage.src = this._elCanvas.toDataURL("image/png");
-			this._elImage.style.display = "block";
-			this._elCanvas.style.display = "none";			
-		}
-		
-		// Android 2.1 bug workaround
-		// http://code.google.com/p/android/issues/detail?id=5141
-		if (this._android && this._android <= 2.1) {
-	    	var factor = 1 / window.devicePixelRatio;
-	        var drawImage = CanvasRenderingContext2D.prototype.drawImage; 
-	    	CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) {
-	    		if (("nodeName" in image) && /img/i.test(image.nodeName)) {
-		        	for (var i = arguments.length - 1; i >= 1; i--) {
-		            	arguments[i] = arguments[i] * factor;
-		        	}
-	    		} else if (typeof dw == "undefined") {
-	    			arguments[1] *= factor;
-	    			arguments[2] *= factor;
-	    			arguments[3] *= factor;
-	    			arguments[4] *= factor;
-	    		}
-	    		
-	        	drawImage.apply(this, arguments); 
-	    	};
-		}
-		
-		/**
-		 * Check whether the user's browser supports Data URI or not
-		 * 
-		 * @private
-		 * @param {Function} fSuccess Occurs if it supports Data URI
-		 * @param {Function} fFail Occurs if it doesn't support Data URI
-		 */
-		function _safeSetDataURI(fSuccess, fFail) {
-            var self = this;
-            self._fFail = fFail;
-            self._fSuccess = fSuccess;
-
-            // Check it just once
-            if (self._bSupportDataURI === null) {
-                var el = document.createElement("img");
-                var fOnError = function() {
-                    self._bSupportDataURI = false;
-
-                    if (self._fFail) {
-                        self._fFail.call(self);
-                    }
-                };
-                var fOnSuccess = function() {
-                    self._bSupportDataURI = true;
-
-                    if (self._fSuccess) {
-                        self._fSuccess.call(self);
-                    }
-                };
-
-                el.onabort = fOnError;
-                el.onerror = fOnError;
-                el.onload = fOnSuccess;
-                el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data.
-                return;
-            } else if (self._bSupportDataURI === true && self._fSuccess) {
-                self._fSuccess.call(self);
-            } else if (self._bSupportDataURI === false && self._fFail) {
-                self._fFail.call(self);
-            }
-		};
-		
-		/**
-		 * Drawing QRCode by using canvas
-		 * 
-		 * @constructor
-		 * @param {HTMLElement} el
-		 * @param {Object} htOption QRCode Options 
-		 */
-		var Drawing = function (el, htOption) {
-    		this._bIsPainted = false;
-    		this._android = _getAndroid();
-		
-			this._htOption = htOption;
-			this._elCanvas = document.createElement("canvas");
-			this._elCanvas.width = htOption.width;
-			this._elCanvas.height = htOption.height;
-			el.appendChild(this._elCanvas);
-			this._el = el;
-			this._oContext = this._elCanvas.getContext("2d");
-			this._bIsPainted = false;
-			this._elImage = document.createElement("img");
-			this._elImage.alt = "Scan me!";
-			this._elImage.style.display = "none";
-			this._el.appendChild(this._elImage);
-			this._bSupportDataURI = null;
-		};
-			
-		/**
-		 * Draw the QRCode
-		 * 
-		 * @param {QRCode} oQRCode 
-		 */
-		Drawing.prototype.draw = function (oQRCode) {
-            var _elImage = this._elImage;
-            var _oContext = this._oContext;
-            var _htOption = this._htOption;
-            
-			var nCount = oQRCode.getModuleCount();
-			var nWidth = _htOption.width / nCount;
-			var nHeight = _htOption.height / nCount;
-			var nRoundedWidth = Math.round(nWidth);
-			var nRoundedHeight = Math.round(nHeight);
-
-			_elImage.style.display = "none";
-			this.clear();
-			
-			for (var row = 0; row < nCount; row++) {
-				for (var col = 0; col < nCount; col++) {
-					var bIsDark = oQRCode.isDark(row, col);
-					var nLeft = col * nWidth;
-					var nTop = row * nHeight;
-					_oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;
-					_oContext.lineWidth = 1;
-					_oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;					
-					_oContext.fillRect(nLeft, nTop, nWidth, nHeight);
-					
-					// 안티 앨리어싱 방지 처리
-					_oContext.strokeRect(
-						Math.floor(nLeft) + 0.5,
-						Math.floor(nTop) + 0.5,
-						nRoundedWidth,
-						nRoundedHeight
-					);
-					
-					_oContext.strokeRect(
-						Math.ceil(nLeft) - 0.5,
-						Math.ceil(nTop) - 0.5,
-						nRoundedWidth,
-						nRoundedHeight
-					);
-				}
-			}
-			
-			this._bIsPainted = true;
-		};
-			
-		/**
-		 * Make the image from Canvas if the browser supports Data URI.
-		 */
-		Drawing.prototype.makeImage = function () {
-			if (this._bIsPainted) {
-				_safeSetDataURI.call(this, _onMakeImage);
-			}
-		};
-			
-		/**
-		 * Return whether the QRCode is painted or not
-		 * 
-		 * @return {Boolean}
-		 */
-		Drawing.prototype.isPainted = function () {
-			return this._bIsPainted;
-		};
-		
-		/**
-		 * Clear the QRCode
-		 */
-		Drawing.prototype.clear = function () {
-			this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height);
-			this._bIsPainted = false;
-		};
-		
-		/**
-		 * @private
-		 * @param {Number} nNumber
-		 */
-		Drawing.prototype.round = function (nNumber) {
-			if (!nNumber) {
-				return nNumber;
-			}
-			
-			return Math.floor(nNumber * 1000) / 1000;
-		};
-		
-		return Drawing;
-	})();
-	
-	/**
-	 * Get the type by string length
-	 * 
-	 * @private
-	 * @param {String} sText
-	 * @param {Number} nCorrectLevel
-	 * @return {Number} type
-	 */
-	function _getTypeNumber(sText, nCorrectLevel) {			
-		var nType = 1;
-		var length = _getUTF8Length(sText);
-		
-		for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) {
-			var nLimit = 0;
-			
-			switch (nCorrectLevel) {
-				case QRErrorCorrectLevel.L :
-					nLimit = QRCodeLimitLength[i][0];
-					break;
-				case QRErrorCorrectLevel.M :
-					nLimit = QRCodeLimitLength[i][1];
-					break;
-				case QRErrorCorrectLevel.Q :
-					nLimit = QRCodeLimitLength[i][2];
-					break;
-				case QRErrorCorrectLevel.H :
-					nLimit = QRCodeLimitLength[i][3];
-					break;
-			}
-			
-			if (length <= nLimit) {
-				break;
-			} else {
-				nType++;
-			}
-		}
-		
-		if (nType > QRCodeLimitLength.length) {
-			throw new Error("Too long data");
-		}
-		
-		return nType;
-	}
-
-	function _getUTF8Length(sText) {
-		var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a');
-		return replacedText.length + (replacedText.length != sText ? 3 : 0);
-	}
-	
-	/**
-	 * @class QRCode
-	 * @constructor
-	 * @example 
-	 * new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie");
-	 *
-	 * @example
-	 * var oQRCode = new QRCode("test", {
-	 *    text : "http://naver.com",
-	 *    width : 128,
-	 *    height : 128
-	 * });
-	 * 
-	 * oQRCode.clear(); // Clear the QRCode.
-	 * oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode.
-	 *
-	 * @param {HTMLElement|String} el target element or 'id' attribute of element.
-	 * @param {Object|String} vOption
-	 * @param {String} vOption.text QRCode link data
-	 * @param {Number} [vOption.width=256]
-	 * @param {Number} [vOption.height=256]
-	 * @param {String} [vOption.colorDark="#000000"]
-	 * @param {String} [vOption.colorLight="#ffffff"]
-	 * @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H] 
-	 */
-	QRCode = function (el, vOption) {
-		this._htOption = {
-			width : 256, 
-			height : 256,
-			typeNumber : 4,
-			colorDark : "#000000",
-			colorLight : "#ffffff",
-			correctLevel : QRErrorCorrectLevel.H
-		};
-		
-		if (typeof vOption === 'string') {
-			vOption	= {
-				text : vOption
-			};
-		}
-		
-		// Overwrites options
-		if (vOption) {
-			for (var i in vOption) {
-				this._htOption[i] = vOption[i];
-			}
-		}
-		
-		if (typeof el == "string") {
-			el = document.getElementById(el);
-		}
-
-		if (this._htOption.useSVG) {
-			Drawing = svgDrawer;
-		}
-		
-		this._android = _getAndroid();
-		this._el = el;
-		this._oQRCode = null;
-		this._oDrawing = new Drawing(this._el, this._htOption);
-		
-		if (this._htOption.text) {
-			this.makeCode(this._htOption.text);	
-		}
-	};
-	
-	/**
-	 * Make the QRCode
-	 * 
-	 * @param {String} sText link data
-	 */
-	QRCode.prototype.makeCode = function (sText) {
-		this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel);
-		this._oQRCode.addData(sText);
-		this._oQRCode.make();
-		this._el.title = sText;
-		this._oDrawing.draw(this._oQRCode);			
-		this.makeImage();
-	};
-	
-	/**
-	 * Make the Image from Canvas element
-	 * - It occurs automatically
-	 * - Android below 3 doesn't support Data-URI spec.
-	 * 
-	 * @private
-	 */
-	QRCode.prototype.makeImage = function () {
-		if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) {
-			this._oDrawing.makeImage();
-		}
-	};
-	
-	/**
-	 * Clear the QRCode
-	 */
-	QRCode.prototype.clear = function () {
-		this._oDrawing.clear();
-	};
-	
-	/**
-	 * @name QRCode.CorrectLevel
-	 */
-	QRCode.CorrectLevel = QRErrorCorrectLevel;
-})();
diff --git a/www/templates/currency/view_currency_lg.html b/www/templates/currency/view_currency_lg.html
index 2cc9587a06fe362d91b5e38a4fb11cb0f44dae8a..a6e8f35e28c50066f656756b496040d1f0741caa 100644
--- a/www/templates/currency/view_currency_lg.html
+++ b/www/templates/currency/view_currency_lg.html
@@ -5,19 +5,16 @@
     </ion-nav-buttons>
 
     <ion-content>
-      <div class="scroll">
-        <div class="row">
-          </div>
+      <div class="row">
         </div>
-          <div class="row responsive-sm">
-              <div class="col col-50 ">
-                <ng-include src="'templates/currency/tabs/view_parameters.html'"></ng-include>
-              </div>
-              <div class="col col-50">
-                  <ng-include src="'templates/currency/tabs/view_network.html'"></ng-include>
-              </div>
-          </div>
-        <div class="scroll-bar scroll-bar-v"></div>
       </div>
+        <div class="row responsive-sm">
+            <div class="col col-50 ">
+              <ng-include src="'templates/currency/tabs/view_parameters.html'"></ng-include>
+            </div>
+            <div class="col col-50">
+                <ng-include src="'templates/currency/tabs/view_network.html'"></ng-include>
+            </div>
+        </div>
     </ion-content>
 </ion-view>
diff --git a/www/templates/home/home.html b/www/templates/home/home.html
index c8d947716ccf3d6e539ffa6b8a3bfce523fe320c..23a97f2ba43e5b20d737f4452d0f0b1165f7ae70 100644
--- a/www/templates/home/home.html
+++ b/www/templates/home/home.html
@@ -1,40 +1,38 @@
 <ion-view id="home">
   <ion-nav-title>
-    <!--<img src="img/logo.png">-->
     <!--span class="visible-xs visible-sm" translate>HOME.TITLE</span>-->
   </ion-nav-title>
 
   <ion-content class="has-header center padding-xs positive-900-bg">
 
-      <!--img class="center" src="img/lesou-120px.png"/-->
-      <h2 class="hidden-xs" translate>HOME.WELCOME</h2>
-      <h4 class="hidden-xs" translate>HOME.MESSAGE</h4>
-      <h4 class="visible-xs" translate>HOME.MESSAGE_SHORT</h4>
+    <h2 class="hidden-xs" translate>HOME.WELCOME</h2>
+    <h4 class="hidden-xs" translate>HOME.MESSAGE</h4>
+    <h4 class="visible-xs" translate>HOME.MESSAGE_SHORT</h4>
 
-      <div class="row no-padding">
-        <div class="col-25 hidden-xs hidden-sm">&nbsp;
-        </div>
-        <div class="col">
-          <!-- 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>
-          <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_view_lg" translate>HOME.BTN_CURRENCY</button>
-          <button type="button"
-                  class="button button-block button-stable button-raised icon icon-left ion-ios-world-outline ink-dark visible-sm visible-xs"
-                  ng-if="!options.registry || !options.registry.enable"
-                  ui-sref="app.currency_view" translate>HOME.BTN_CURRENCY</button>
+    <div class="row no-padding">
+      <div class="col-25 hidden-xs hidden-sm">&nbsp;</div>
+      <div class="col">
+
+        <!-- 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>
+        <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_view_lg" translate>HOME.BTN_CURRENCY</button>
+        <button type="button"
+                class="button button-block button-stable button-raised icon icon-left ion-ios-world-outline ink-dark visible-sm visible-xs"
+                ng-if="!options.registry || !options.registry.enable"
+                ui-sref="app.currency_view" translate>HOME.BTN_CURRENCY</button>
 
-          <button type="button"
-                  class="button button-block button-positive button-raised icon icon-left ion-locked ink-dark"
-                  ng-click="login()" ng-show="!isLogged()" translate>COMMON.BTN_LOGIN</button>
-          <button type="button"
-                  class="button button-block button-light ink button-clear"
-                  ng-click="newAccount()" ng-show="!isLogged()" translate>COMMON.BTN_ADD_ACCOUNT</button>
+        <button type="button"
+                class="button button-block button-positive button-raised icon icon-left ion-locked ink-dark"
+                ng-click="login()" ng-show="!isLogged()" translate>COMMON.BTN_LOGIN</button>
+        <button type="button"
+                class="button button-block button-light ink button-clear"
+                ng-click="newAccount()" ng-show="!isLogged()" translate>COMMON.BTN_ADD_ACCOUNT</button>
 
         <!-- warning still dev -->
         <br class="hidden-xs"/>
@@ -69,8 +67,7 @@
           </p>
         </div>
       </div>
-      <div class="col-25 hidden-xs hidden-sm">&nbsp;
-      </div>
+      <div class="col-25 hidden-xs hidden-sm">&nbsp;</div>
     </div>
 
     <!-- fork me on github -->
@@ -78,11 +75,9 @@
        style="position: absolute; top: 0px; right: 0; margin: 0; padding: 0; border: 0;"
        target="_blank"
        href="https://github.com/duniter/cesium">
-          <img style="border: 0;"
-            src="https://camo.githubusercontent.com/652c5b9acfaddf3a9c326fa6bde407b87f7be0f4/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6f72616e67655f6666373630302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png">
+        <img style="border: 0;"
+          src="https://camo.githubusercontent.com/652c5b9acfaddf3a9c326fa6bde407b87f7be0f4/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6f72616e67655f6666373630302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png">
     </a>
-
-
   </ion-content>
 
   <ion-footer-bar align-title="center" class="bar-dark footer visible-xs visible-sm">
diff --git a/www/templates/market/edit_record.html b/www/templates/market/edit_record.html
index c1c94bca2b85dbf3d387e99308050adb08497e65..f2dfba46d3bbb0f60a814301252483ec4718be2f 100644
--- a/www/templates/market/edit_record.html
+++ b/www/templates/market/edit_record.html
@@ -32,14 +32,14 @@
 
             <div class="list">
 
-                <div class="item item-icon-right" ng-if="isDeviceEnable()">
+                <div class="item item-icon-right hidden-no-device">
                     <span translate>MARKET.EDIT.BTN_ADD_PICTURES</span>
                     <a class="dark" href="#" ng-click="openPicturePopup()">
                         <i class="icon ion-camera"></i>
                     </a>
                 </div>
 
-                <div class="item item-input item-icon-right" ng-if="!isDeviceEnable()" >
+                <div class="item item-input item-icon-right hidden-device">
                     <span class="input-label has-input" translate>MARKET.EDIT.BTN_ADD_PICTURES</span>
                     <input type="file" id="file" accept=".png,.jpeg,.jpg" onchange="angular.element(this).scope().fileChanged(event)"/>
                     <!--a class="dark" href="#" ng-if="!camera" ng-click="addPictureFile()">
diff --git a/www/templates/menu.html b/www/templates/menu.html
index c04fb5af16e7747fa6d9d9410bf023c9eca61846..c090ed39533646451d1c5d0e210f65bb21acf5a8 100644
--- a/www/templates/menu.html
+++ b/www/templates/menu.html
@@ -1,7 +1,8 @@
 <ion-side-menus enable-menu-with-back-views="true">
   <!-- HEADER -->
-  <ion-side-menu-content>
-    <ion-nav-bar class="bar-dark" ng-class="{expanded: isExpanded, 'has-header-fab-left': hasHeaderFabLeft, 'has-header-fab-right': hasHeaderFabRight}" title-align="left">
+  <ion-side-menu-content
+    >
+    <ion-nav-bar class="bar-dark" title-align="left">
       <ion-nav-back-button class="no-text">
       </ion-nav-back-button>
 
@@ -14,7 +15,11 @@
   </ion-side-menu-content>
 
   <!-- MENU -->
-  <ion-side-menu side="left" id="menu" expose-aside-when="large" enable-menu-with-back-views="false">
+  <ion-side-menu id="menu"
+                 side="left"
+                 expose-aside-when="large"
+                 enable-menu-with-back-views="false"
+                 width="225">
     <ion-header-bar class="bar">
       <h1 class="title" translate>
         MENU.TITLE
@@ -60,9 +65,6 @@
           <span translate>MENU.ACCOUNT</span>
         </ion-item>
 
-        <!-- <ion-item menu-close ng-click="addAccount()">
-          Add account
-        </ion-item> -->
         <ion-item menu-close class="item item-icon-left" href="#/app/settings">
           <i class="icon ion-android-settings"></i>
           <span translate>MENU.SETTINGS</span>
@@ -83,6 +85,7 @@
             <i class="icon ion-qr-scanner"></i>
           </button>
         </ion-item>
+        <!-- log out -->
         <ion-item menu-close class="item item-button-right" ng-if="isLogged()">
           <span translate>COMMON.BTN_LOGOUT</span>
           <button class="button button-energized-900" ng-click="logout()">
@@ -90,7 +93,6 @@
           </button>
         </ion-item>
 
-
       </ion-list>
     </ion-content>
 
diff --git a/www/templates/registry/record_form.html b/www/templates/registry/record_form.html
index da276e376646a56456c839a3a9a837cdf4f2ed06..5fcdb48d31ad440d630c5372d45dde6e952db745 100644
--- a/www/templates/registry/record_form.html
+++ b/www/templates/registry/record_form.html
@@ -24,14 +24,14 @@
           </div>
         </div>
 
-        <div class="item item-icon-right" ng-if="isDeviceEnable()">
+        <div class="item item-icon-right hidden-no-device">
           <span translate>REGISTRY.EDIT.BTN_ADD_PICTURES</span>
           <a class="dark" href="#" ng-click="openPicturePopup()">
             <i class="icon ion-camera"></i>
           </a>
         </div>
 
-        <div class="item item-input item-icon-right" ng-if="!isDeviceEnable()" >
+        <div class="item item-input item-icon-right hidden-device">
           <span class="input-label has-input" translate>REGISTRY.EDIT.BTN_ADD_PICTURES</span>
           <input type="file" id="file" accept=".png,.jpeg,.jpg" onchange="angular.element(this).scope().fileChanged(event)"/>
           <!--a class="dark" href="#" ng-if="!camera" ng-click="addPictureFile()">
diff --git a/www/templates/settings/settings.html b/www/templates/settings/settings.html
index 824191ed915d0ef1c2ae29ed3b8af473a740bb8d..442751fc08210a05310531e22b0d9a5a22b17f4a 100644
--- a/www/templates/settings/settings.html
+++ b/www/templates/settings/settings.html
@@ -37,6 +37,23 @@
         </label>
       </div>
 
+      <span class="item item-divider">
+        {{'SETTINGS.AUTHENTICATION_SETTINGS' | translate}}
+      </span>
+
+      <div class="item item-toggle" >
+        <div class="input-label" ng-class="{'gray': !formData.useLocalStorage}">
+          {{'SETTINGS.REMEMBER_ME' | translate}}
+        </div>
+        <label class="toggle" ng-class="{'toggle-stable': !formData.useLocalStorage, 'toggle-royal': formData.useLocalStorage}">
+          <input type="checkbox" ng-model="formData.rememberMe" ng-disabled="!formData.useLocalStorage"
+          >
+          <div class="track">
+            <div class="handle"></div>
+          </div>
+        </label>
+      </div>
+
       <span class="item item-divider">
         {{'SETTINGS.HISTORY_SETTINGS' | translate}}
       </span>
@@ -64,22 +81,5 @@
         <span class="item-note">{{formData.node}}</span>
       </div>
 
-      <span class="item item-divider" ng-if="formData.useLocalStorage">
-        {{'SETTINGS.AUTHENTICATION_SETTINGS' | translate}}
-      </span>
-
-      <div class="item item-toggle dark" ng-if="formData.useLocalStorage">
-        <div class="input-label">
-          {{'SETTINGS.REMEMBER_ME' | translate}}
-        </div>
-        <label class="toggle toggle-royal">
-          <input type="checkbox" ng-model="formData.rememberMe"
-            >
-          <div class="track">
-            <div class="handle"></div>
-          </div>
-        </label>
-      </div>
-
     </ion-content>
 </ion-view>
diff --git a/www/templates/wallet/popover_actions.html b/www/templates/wallet/popover_actions.html
index 4f443e154cf9c64fc50a3cccd27216a528a6b2cb..1050c3ff332c08ae294375cec7ddfbf257ec0d65 100644
--- a/www/templates/wallet/popover_actions.html
+++ b/www/templates/wallet/popover_actions.html
@@ -5,31 +5,38 @@
   <ion-content>
     <div class="list">
 
-      <a class="item item-icon-left"
+      <a class="item item-icon-left ink"
          ng-click="setShowDetails(!showDetails)">
         <i class="icon"
            ng-class="{'ion-ios-checkmark-empty': showDetails}"></i>
         {{'ACCOUNT.BTN_SHOW_DETAILS' | translate}}
       </a>
 
-      <a class="item item-icon-left"
+      <a class="item item-icon-left ink"
               ng-if="walletData.requirements.needMembership"
               ng-click="membershipIn()">
-        <i class="icon ion-person "></i>
+        <i class="icon ion-person"></i>
         {{'ACCOUNT.BTN_MEMBERSHIP_IN' | translate}}
       </a>
 
-      <a class="item item-icon-left assertive"
+      <button class="button button-raised item-icon-left ink visible-xs visible-sm"
+              ng-if="walletData.requirements.needRenew"
+              ng-click="membershipRenew()">
+        <i class="icon ion-loop"></i>
+        {{'ACCOUNT.BTN_MEMBERSHIP_RENEW' | translate}}
+      </button>
+
+      <a class="item item-icon-left assertive ink"
               ng-if="walletData.requirements.needMembershipOut"
               ng-click="membershipOut()">
-        <i class="icon ion-log-out "></i>
+        <i class="icon ion-log-out"></i>
         {{'ACCOUNT.BTN_MEMBERSHIP_OUT' | translate}}
       </a>
 
-      <a class="item item-icon-left"
+      <a class="item item-icon-left ink"
             ng-if="walletData.requirements.needSelf"
             ng-click="self()">
-        <i class="icon ion-flag "></i>
+        <i class="icon ion-flag"></i>
         {{'ACCOUNT.BTN_SEND_IDENTITY' | translate}}
       </a>
     </div>
diff --git a/www/templates/wallet/view_wallet.html b/www/templates/wallet/view_wallet.html
index 67df7c9ae14038a6af4afc0245d1673cbedd1fa2..ecb0992c6373d461fd86e1534a2a6a46c561d5b3 100644
--- a/www/templates/wallet/view_wallet.html
+++ b/www/templates/wallet/view_wallet.html
@@ -1,171 +1,162 @@
 <ion-view left-buttons="leftButtons"
-          view-title=""
+          view-title=" "
           id="wallet">
 
   <ion-nav-buttons side="secondary">
 
     <button class="button button-icon button-clear icon ion-loop" ng-click="doUpdate()">
     </button>
-    <button class="button button-icon button-clear icon ion-android-more-vertical visible-xs visible-sm" ng-click="showActionsheet()">
-    </button>
-    <button class="button button-icon button-clear icon ion-android-more-vertical hidden-xs hidden-sm" ng-click="actionsPopover.show($event)">
+    <button class="button button-icon button-clear" ng-click="actionsPopover.show($event)">
+      <i class="icon ion-android-more-vertical"></i>
     </button>
   </ion-nav-buttons>
 
-    <ion-content
-      ng-class="{expanded:isExpanded}">
-        <div class="scroll">
-
-          <div class="positive-900-bg hero">
-            <div class="content">
-              <div class="avatar"
-                   ng-if="!!walletData.avatar"
-                   style="background-image: url({{::walletData.avatar}});"></div>
-              <i class="avatar" ng-class="{'avatar-wallet': !walletData.isMember, 'avatar-member': walletData.isMember}"></i>
-              <h3 class="light" ng-if="walletData.isMember">{{walletData.uid}}</h3>
-              <h3 class="light" ng-if="!walletData.isMember">{{::walletData.pubkey | formatPubkey}}</h3>
-              <h4 class="light" ng-if="isLogged() && convertedBalance != null">
-                  <span ng-if="!walletData.settings.useRelative">{{convertedBalance | formatInteger}} {{unit | abbreviate}}</span>
-                  <span ng-if="walletData.settings.useRelative">{{convertedBalance | formatDecimal}} {{'COMMON.UD' | translate}}<sub>{{unit | abbreviate}}</sub></span>
-              </h4>
-              <h4 class="light" ng-if="!isLogged() || convertedBalance == null">
-                <ion-spinner icon="android"></ion-spinner>
-              </h4>
-            </div>
+  <ion-content scroll="true">
+    <div class="positive-900-bg hero">
+      <div class="content">
+        <div class="avatar"
+             ng-if="!!walletData.avatar"
+             style="background-image: url({{::walletData.avatar}});"></div>
+        <i class="avatar" ng-class="{'avatar-wallet': !walletData.isMember, 'avatar-member': walletData.isMember}"></i>
+        <h3 class="light" ng-if="walletData.isMember">{{walletData.uid}}</h3>
+        <h3 class="light" ng-if="!walletData.isMember">{{::walletData.pubkey | formatPubkey}}</h3>
+        <h4 class="light" ng-if="isLogged() && convertedBalance != null">
+            <span ng-if="!walletData.settings.useRelative">{{convertedBalance | formatInteger}} {{unit | abbreviate}}</span>
+            <span ng-if="walletData.settings.useRelative">{{convertedBalance | formatDecimal}} {{'COMMON.UD' | translate}}<sub>{{unit | abbreviate}}</sub></span>
+        </h4>
+        <h4 class="light" ng-if="!isLogged() || convertedBalance == null">
+          <ion-spinner icon="android"></ion-spinner>
+        </h4>
+      </div>
+    </div>
+
+    <div id="qrcode" class="qrcode visible-xs visible-sm spin" ></div>
+
+    <!-- Buttons bar-->
+    <div class="hidden-xs hidden-sm padding" style="text-align:center"
+         ng-if="!!convertedBalance">
+      <button class="button button-raised button-energized-900 ink-dark"
+              ng-click="openTransfer()">
+        {{'ACCOUNT.BTN_SEND_MONEY' | translate}}
+      </button>
+
+      <button class="button button-raised icon-left ion-loop ink"
+              ng-if="walletData.requirements.needRenew"
+              ng-click="membershipRenew()">
+        {{'ACCOUNT.BTN_MEMBERSHIP_RENEW' | translate}}
+      </button>
+    </div>
+
+    <div class="row no-padding">
+      <div class="col col-20 hidden-xs hidden-sm">&nbsp;
+      </div>
+
+      <div class="col list animate-fade-slide-in-right">
+
+        <!-- Certifications -->
+        <a class="item item-icon-left item-icon-right item-text-wrap ink" ng-if="walletData.isMember && walletData.requirements.certificationCount > 0"
+           ui-sref="app.view_certifications({pub:walletData.pubkey})">
+          <i class="icon ion-ribbon-b"></i>
+          <span clas="input-label">{{'ACCOUNT.CERTIFICATION_COUNT'|translate}}</span>
+          <span class="badge"
+                ng-class="{'badge-balanced': walletData.requirements.needCertificationCount==0 && walletData.requirements.willNeedCertificationCount==0, 'badge-assertive': walletData.requirements.needCertificationCount>0 || walletData.requirements.willNeedCertificationCount>0}">{{walletData.requirements.certificationCount}}</span>
+          <i class="gray icon ion-ios-arrow-right"></i>
+        </a>
+
+        <!-- Events -->
+        <span class="item item-divider" ng-if="walletData.requirements.pendingMembership||walletData.requirements.needCertificationCount > 0||walletData.requirements.willNeedCertificationCount > 0">
+          {{'ACCOUNT.EVENTS' | translate}}
+        </span>
+
+        <span class="item item-text-wrap" ng-if="walletData.requirements.pendingMembership">
+          <h3>
+            <i class="icon ion-clock"></i>
+            {{'ACCOUNT.WAITING_MEMBERSHIP' | translate}}
+          </h3>
+        </span>
+        <span class="item item-text-wrap" ng-if="walletData.requirements.needCertificationCount > 0">
+          <h3>
+            <i class="icon ion-alert-circled"></i>
+            {{'ACCOUNT.WAITING_CERTIFICATIONS' | translate:walletData.requirements}}
+          </h3>
+        </span>
+        <span class="item item-text-wrap" ng-if="walletData.requirements.willNeedCertificationCount > 0">
+          <h3>
+            <i class="icon ion-alert-circled"></i>
+            {{'ACCOUNT.WILL_MISSING_CERTIFICATIONS' | translate:walletData.requirements}}
+          </h3>
+        </span>
+
+        <!-- Public key -->
+        <span class="item item-icon-left item-text-wrap ink in done"
+                  on-hold="copy(walletData.pubkey)"
+                  ng-if="showDetails"
+                  copy-on-click>
+          <i class="icon ion-key"></i>
+          <h4 id="pubkey" class="dark">{{walletData.pubkey}}</h4>
+        </span>
+
+        <!-- Last Transactions -->
+        <span class="item item-divider">
+          <span translate>ACCOUNT.LAST_TX</span>
+          <div class="badge item-note">
+            <span ng-if="!walletData.settings.useRelative">({{unit | abbreviate}})</span>
+            <span ng-if="walletData.settings.useRelative">({{'COMMON.UD' | translate}}<sub>{{unit | abbreviate}}</sub>)</span>
           </div>
-
-          <div id="qrcode" class="qrcode visible-xs visible-sm spin" ></div>
-
-          <div class="hidden-xs hidden-sm padding" style="text-align:center" ng-if="!!convertedBalance">
-              <button class="button button-raised button-energized-900 ink-dark"
-                      ng-click="openTransfer()">
-                {{'ACCOUNT.BTN_SEND_MONEY' | translate}}
-              </button>
-
-           <!-- <button class="button button-raised button-positive ink-dark"
-                    ng-click="openReceive()">
-              {{'ACCOUNT.BTN_RECEIVE_MONEY' | translate}}
-            </button>-->
-
-              <button class="button button-raised icon-left ion-loop ink"
-                      ng-if="walletData.requirements.needRenew"
-                      ng-click="membershipRenew()">
-                {{'ACCOUNT.BTN_MEMBERSHIP_RENEW' | translate}}
-              </button>
-            </div>
-
-            <div class="row no-padding">
-              <div class="col col-20 hidden-xs hidden-sm">&nbsp;
-              </div>
-
-              <div class="col list animate-fade-slide-in-right" >
-
-                <!-- Certifications -->
-                <a class="item item-icon-left item-icon-right item-text-wrap ink" ng-if="walletData.isMember && walletData.requirements.certificationCount > 0"
-                   ui-sref="app.view_certifications({pub:walletData.pubkey})">
-                  <i class="icon ion-ribbon-b"></i>
-                  <span clas="input-label">{{'ACCOUNT.CERTIFICATION_COUNT'|translate}}</span>
-                  <span class="badge"
-                        ng-class="{'badge-balanced': walletData.requirements.needCertificationCount==0 && walletData.requirements.willNeedCertificationCount==0, 'badge-assertive': walletData.requirements.needCertificationCount>0 || walletData.requirements.willNeedCertificationCount>0}">{{walletData.requirements.certificationCount}}</span>
-                  <i class="gray icon ion-ios-arrow-right"></i>
-                </a>
-
-                <!-- Events -->
-                <span class="item item-divider" ng-if="walletData.requirements.pendingMembership||walletData.requirements.needCertificationCount > 0||walletData.requirements.willNeedCertificationCount > 0">
-                  {{'ACCOUNT.EVENTS' | translate}}
-                </span>
-
-                <span class="item item-text-wrap" ng-if="walletData.requirements.pendingMembership">
-                  <h3>
-                    <i class="icon ion-clock"></i>
-                    {{'ACCOUNT.WAITING_MEMBERSHIP' | translate}}
-                  </h3>
-                </span>
-                <span class="item item-text-wrap" ng-if="walletData.requirements.needCertificationCount > 0">
-                  <h3>
-                    <i class="icon ion-alert-circled"></i>
-                    {{'ACCOUNT.WAITING_CERTIFICATIONS' | translate:walletData.requirements}}
-                  </h3>
-                </span>
-                <span class="item item-text-wrap" ng-if="walletData.requirements.willNeedCertificationCount > 0">
-                  <h3>
-                    <i class="icon ion-alert-circled"></i>
-                    {{'ACCOUNT.WILL_MISSING_CERTIFICATIONS' | translate:walletData.requirements}}
-                  </h3>
-                </span>
-
-                <!-- Public key -->
-                <span class="item item-icon-left item-text-wrap ink in done"
-                          on-hold="copy(walletData.pubkey)"
-                          ng-if="showDetails"
-                          copy-on-click>
-                  <i class="icon ion-key"></i>
-                  <h4 id="pubkey" class="dark">{{walletData.pubkey}}</h4>
-                </span>
-
-                <!-- Last Transactions -->
-                <span class="item item-divider">
-                  <span translate>ACCOUNT.LAST_TX</span>
-                  <div class="badge item-note">
-                    <span ng-if="!walletData.settings.useRelative">({{unit | abbreviate}})</span>
-                    <span ng-if="walletData.settings.useRelative">({{'COMMON.UD' | translate}}<sub>{{unit | abbreviate}}</sub>)</span>
-                  </div>
-                </span>
-
-                <span class="item" ng-if="!walletData.history || walletData.history.length == 0">
-                  <h3 translate>ACCOUNT.NO_TX</h3>
-                </span>
-
-                <span class="item ink" ng-repeat="tx in walletData.history" ng-if="walletData.history && walletData.history.length > 0">
-                  <h2><i class="icon ion-clock" ng-if="!tx.block_number"> </i>
-                    <span class="positive" ng-if="tx.uid" ui-sref="app.view_identity({pub:tx.pubkey})">
-                      <i class="icon ion-person"></i>
-                      {{::tx.uid}}
-                    </span>
-                    <span class="positive" ng-if="!tx.uid && !tx.isUD" ui-sref="app.view_identity({pub:tx.pubkey})">
-                      <i class="icon ion-key"></i>
-                      {{::tx.pubkey | formatPubkey}}
-                    </span>
-                    <span class="energized" ng-if="tx.isUD">
-                      <i class="icon ion-arrow-up-c"></i>
-                      {{'COMMON.UNIVERSAL_DIVIDEND' | translate}}
-                    </span>
-                    <span  ng-if="tx.comment" class="hidden-xs">&nbsp;
-                      <i class="icon ion-ios-chatbubble-outline"></i>
-                      {{::tx.comment}}
-                    </span>
-                  </h2>
-                  <h3 ng-if="tx.comment" class="visible-xs">
-                    <i class="icon ion-ios-chatbubble-outline"></i>
-                    {{::tx.comment}}<br/>
-                  </h3>
-                  <h3 class="dark">
-                    {{::tx.time | formatFromNow}}
-                    <span class="gray hidden-xs">|
-                      <i class="icon ion-calendar"></i>
-                      {{::tx.time | formatDate}}
-                    </span>
-                  </h3>
-                  <div class="badge item-note"
-                       ng-class="{'badge-balanced': tx.amount > 0 && !tx.isUD, 'badge-energized': tx.isUD}">
-                    <span ng-if="!walletData.settings.useRelative">{{tx.amount | formatInteger}}</span>
-                    <span ng-if="walletData.settings.useRelative">{{tx.amount/walletData.currentUD | formatDecimal}}</span>
-                  </div >
-                </span>
-              </div>
-
-              <div class="col col-20 hidden-xs hidden-sm">&nbsp;
-              </div>
-            </div>
-          <div class="scroll-bar scroll-bar-v"></div>
-        </div>
-
-    </ion-content>
-
-    <button id="fab-transfer"
-            ng-if="walletData"
-            class="button button-fab button-fab-bottom-right button-energized-900 hidden-md hidden-lg drop"
-            ng-click="openTransfer()">
-      <i class="icon ion-android-send"></i>
-    </button>
+        </span>
+
+        <span class="item" ng-if="!walletData.history || walletData.history.length == 0">
+          <h3 translate>ACCOUNT.NO_TX</h3>
+        </span>
+
+        <span class="item ink" ng-repeat="tx in walletData.history" ng-if="walletData.history && walletData.history.length > 0">
+          <h2>
+            <i class="icon ion-clock" ng-if="!tx.block_number"> </i>
+            <span class="positive" ng-if="tx.uid" ui-sref="app.view_identity({pub:tx.pubkey})">
+              <i class="icon ion-person"></i>
+              {{::tx.uid}}
+            </span>
+            <span class="positive" ng-if="!tx.uid && !tx.isUD" ui-sref="app.view_identity({pub:tx.pubkey})">
+              <i class="icon ion-key"></i>
+              {{::tx.pubkey | formatPubkey}}
+            </span>
+            <span class="energized" ng-if="tx.isUD">
+              <i class="icon ion-arrow-up-c"></i>
+              {{'COMMON.UNIVERSAL_DIVIDEND' | translate}}
+            </span>
+            <span  ng-if="tx.comment" class="dark hidden-xs">&nbsp;
+              <i class="icon ion-ios-chatbubble-outline"></i>
+              <smaller>{{::tx.comment}}</smaller>
+            </span>
+          </h2>
+          <h3 ng-if="tx.comment" class="dark visible-xs">
+            <i class="icon ion-ios-chatbubble-outline"></i>
+            {{::tx.comment}}<br/>
+          </h3>
+          <h3 class="dark">
+            {{::tx.time | formatFromNow}}
+            <span class="gray hidden-xs">|
+              <i class="icon ion-calendar"></i>
+              {{::tx.time | formatDate}}
+            </span>
+          </h3>
+          <div class="badge item-note"
+               ng-class="{'badge-balanced': tx.amount > 0 && !tx.isUD, 'badge-energized': tx.isUD}">
+            <span ng-if="!walletData.settings.useRelative">{{tx.amount | formatInteger}}</span>
+            <span ng-if="walletData.settings.useRelative">{{tx.amount/walletData.currentUD | formatDecimal}}</span>
+          </div >
+        </span>
+      </div>
+
+      <div class="col col-20 hidden-xs hidden-sm">&nbsp;
+      </div>
+    </div>
+  </ion-content>
+
+  <button id="fab-transfer"
+          ng-if="walletData"
+          class="button button-fab button-fab-bottom-right button-energized-900 hidden-md hidden-lg drop"
+          ng-click="openTransfer()">
+    <i class="icon ion-android-send"></i>
+  </button>
 </ion-view>
diff --git a/www/templates/wot/lookup.html b/www/templates/wot/lookup.html
index 8c3c89ae300c85723ab1fe165c2abcb7e293ce25..80910a03121de6a94811c5e41375b211dee034d9 100644
--- a/www/templates/wot/lookup.html
+++ b/www/templates/wot/lookup.html
@@ -1,7 +1,6 @@
 <ion-view view-title="{{'WOT.LOOKUP.TITLE' | translate}}">
   <ion-nav-buttons side="secondary">
-    <button class="button button-icon button-clear icon ion-qr-scanner"
-            ng-if="isDeviceEnable()"
+    <button class="button button-icon button-clear icon ion-qr-scanner hidden-no-device"
             ng-click="scanQrCode()">
     </button>
   </ion-nav-buttons>
diff --git a/www/templates/wot/modal_lookup.html b/www/templates/wot/modal_lookup.html
index a6e6397f8cc8870eec5c0dbac0af626603abd9a3..64446cda9b2e17f751bda3fdd6ec857e02688aba 100644
--- a/www/templates/wot/modal_lookup.html
+++ b/www/templates/wot/modal_lookup.html
@@ -3,7 +3,7 @@
     <button class="button button-clear" ng-click="closeLookup()" translate>COMMON.BTN_CANCEL</button>
     <h1 class="title" translate>WOT.MODAL.TITLE</h1>
 
-    <button class="button button-icon button-clear icon ion-qr-scanner visible-xs"
+    <button class="button button-icon button-clear icon ion-qr-scanner visible-xs hidden-no-device"
             ng-if="isDeviceEnable()"
             ng-click="scanQrCode()">
     </button>
diff --git a/www/templates/wot/view_identity.html b/www/templates/wot/view_identity.html
index 9a5e67282eba00f63cead8df58f53a4d5a370878..dfe429b1b480ac28741c6565989fc921bf6e3fca 100644
--- a/www/templates/wot/view_identity.html
+++ b/www/templates/wot/view_identity.html
@@ -2,7 +2,7 @@
   <ion-nav-title>
   </ion-nav-title>
 
-  <ion-content ng-class="{expanded:$scope.isExpanded}">
+  <ion-content scroll="true">
     <div class="positive-900-bg hero animate-pan-in-left">
       <div class="content">
         <div class="avatar"
@@ -19,50 +19,45 @@
       </div>
     </div>
 
-    <div class="scroll">
+    <div class="hidden-xs hidden-sm padding" style="text-align:center">
+      <button class="button button-raised button-assertive ink-dark"
+              ng-click="transfer(identity.pub, identity.uid)">
+        {{'ACCOUNT.BTN_SEND_MONEY' | translate}}
+      </button>
+    </div>
 
-      <div class="hidden-xs hidden-sm padding" style="text-align:center">
-        <button class="button button-raised button-assertive ink-dark"
-                ng-click="transfer(identity.pub, identity.uid)">
-          {{'ACCOUNT.BTN_SEND_MONEY' | translate}}
-        </button>
+    <div class="row no-padding">
+      <div class="col col-20 hidden-xs hidden-sm">&nbsp;
       </div>
 
-      <div class="row no-padding">
-        <div class="col col-20 hidden-xs hidden-sm">&nbsp;
-        </div>
-
-        <div class="col list animate-fade-slide-in">
+      <div class="col list animate-fade-slide-in">
 
-          <!-- Certifications count -->
-          <a class="item item-icon-left item-text-wrap item-icon-right ink" ng-if="hasSelf"
-             ui-sref="app.view_certifications({pub:identity.pub})">
-            <i class="icon ion-ribbon-b"></i>
-            <span>{{'ACCOUNT.CERTIFICATION_COUNT'|translate}}</span>
-            <span class="badge" ng-class="{'badge-balanced': sigQty && certificationCount >= sigQty, 'badge-assertive': sigQty && certificationCount < sigQty}">{{certificationCount}}</span>
-            <i class="gray icon ion-ios-arrow-right"></i>
-          </a>
+        <!-- Certifications count -->
+        <a class="item item-icon-left item-text-wrap item-icon-right ink" ng-if="hasSelf"
+           ui-sref="app.view_certifications({pub:identity.pub})">
+          <i class="icon ion-ribbon-b"></i>
+          <span>{{'ACCOUNT.CERTIFICATION_COUNT'|translate}}</span>
+          <span class="badge" ng-class="{'badge-balanced': sigQty && certificationCount >= sigQty, 'badge-assertive': sigQty && certificationCount < sigQty}">{{certificationCount}}</span>
+          <i class="gray icon ion-ios-arrow-right"></i>
+        </a>
 
-          <ion-item class="item-icon-left" ng-if="identity.sigDate">
-            <i class="icon ion-calendar"></i>
-            <span>{{'WOT.REGISTERED_SINCE' | translate}}</span>
-            <h5 class="dark">{{::identity.sigDate | formatDate}}</h5>
-            <span class="badge badge-balanced">{{::identity.sigDate | formatFromNow}}</span>
-          </ion-item>
+        <ion-item class="item-icon-left" ng-if="identity.sigDate">
+          <i class="icon ion-calendar"></i>
+          <span>{{'WOT.REGISTERED_SINCE' | translate}}</span>
+          <h5 class="dark">{{::identity.sigDate | formatDate}}</h5>
+          <span class="badge badge-balanced">{{::identity.sigDate | formatFromNow}}</span>
+        </ion-item>
 
-          <ion-item class="item-icon-left item-text-wrap ink"
-                    on-hold="copy(identity.pub)"
-                    copy-on-click>
-            <i class="icon ion-key"></i>
-            <h4 id="pubkey" class="dark">{{::identity.pub}}</h4>
-          </ion-item>
-        </div>
-
-        <div class="col col-20 hidden-xs hidden-sm">&nbsp;
-        </div>
+        <ion-item class="item-icon-left item-text-wrap ink"
+                  on-hold="copy(identity.pub)"
+                  copy-on-click>
+          <i class="icon ion-key"></i>
+          <h4 id="pubkey" class="dark">{{::identity.pub}}</h4>
+        </ion-item>
       </div>
 
-      <div class="scroll-bar scroll-bar-v"></div>
+      <div class="col col-20 hidden-xs hidden-sm">&nbsp;
+      </div>
     </div>
   </ion-content>