diff --git a/.gitignore b/.gitignore
index 8ed8afb5688418b53548f372904d1f877eb8c93a..2818f8321e56cb6589534d8d7ed80ee5d9141046 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,22 +3,22 @@
 # Specifies intentionally untracked files to ignore when using Git
 # http://git-scm.com/docs/gitignore
 
-node_modules/
-platforms/
-plugins/
+/node_modules/
+/platforms/
+/plugins/
 .idea/
-cesium.iml
-pom.xml
-www/css/ionic.app.css
-www/css/ionic.app.min.css
+/cesium.iml
+/pom.xml
+/www/css/ionic.app.css
+/www/css/ionic.app.min.css
 
-www/lib/angular
-www/lib/angular-animate
-www/lib/angular-messages
-www/lib/angular-sanitize
-www/lib/angular-ui-router
-www/lib/angular-moment
-www/lib/moment
-www/lib/waves
-www/dist
-hooks/playstore-config.json
+/www/lib/angular
+/www/lib/angular-animate
+/www/lib/angular-messages
+/www/lib/angular-sanitize
+/www/lib/angular-ui-router
+/www/lib/angular-moment
+/www/lib/moment
+/www/lib/waves
+/www/dist
+/hooks/playstore-config.json
diff --git a/www/plugins/es/css/style.market.css b/www/plugins/es/css/style.market.css
new file mode 100644
index 0000000000000000000000000000000000000000..923467f5201127e33ec48a3928b754d27c523610
--- /dev/null
+++ b/www/plugins/es/css/style.market.css
@@ -0,0 +1,74 @@
+
+/**********
+   Categories select
+**********/
+
+.item-category{
+  overflow: inherit ;
+  text-overflow: inherit ;
+  white-space: normal !important;
+}
+
+.row-record {
+  border-bottom: solid 1px #ccc !important;
+  padding: 0 !important;
+  height: 100px !important;
+  overflow: hidden;
+}
+
+.row-record .col {
+  padding-top: 5px;
+  padding-bottom: 0px;
+}
+
+.row-record .badge-picture-count {
+  position: absolute !important;
+  left: 67px !important;
+  bottom: 15px !important;
+  right: inherit !important;
+  top: inherit !important;
+}
+
+.row-record .badge-price {
+  position: absolute !important;
+  /*left: 80px !important;*/
+  bottom: 15px !important;
+  right: inherit !important;
+  top: inherit !important;
+}
+
+.col-text-wrap {
+    padding: 0;
+    margin: 0;
+}
+.col .text-wrap {
+    height: 93px;
+    white-space: normal;
+    position: relative;
+    word-wrap: break-word !important;
+    overflow: hidden !important;
+    text-overflow: ellipsis;
+    -o-text-overflow: ellipsis;
+    -webkit-hyphens: auto;
+    -moz-hyphens: auto;
+    -ms-hyphens: auto;
+    -o-hyphens: auto;
+    hyphens: auto;
+}
+
+/* Source: See doc: http://stackoverflow.com/questions/15814346 */
+.col .text-wrap:after {
+  content: '';
+  position: absolute;
+  bottom: 0;
+  right: 0;
+  width: 100%;
+  height: 30%;
+  background: -moz-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%);   /* FF3.6+ */
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0)), color-stop(100%,rgba(0255,255,255,1))); /* Chrome,Safari4+ */
+  background: -webkit-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 100%); /* Chrome10+,Safari5.1+ */
+  background: -o-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 100%); /* Opera 11.10+ */
+  background: -ms-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 100%); /* IE10+ */
+  background: linear-gradient(to bottom, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 100%); /* W3C */
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#ffffff',GradientType=0 ); /* IE6-9 */
+}
diff --git a/www/plugins/es/i18n/locale-en.json b/www/plugins/es/i18n/locale-en.json
new file mode 100644
index 0000000000000000000000000000000000000000..46686b1ddee6764b6c1d614cc052a75dd5ee7797
--- /dev/null
+++ b/www/plugins/es/i18n/locale-en.json
@@ -0,0 +1,89 @@
+{
+  "MARKET": {
+    "COMMON": {
+      "CATEGORY": "Category",
+      "CATEGORIES": "Categories",
+      "ISSUER": "Issuer",
+      "PRICE": "Price",
+      "BTN_BUY": "Buy",
+      "BTN_NEW_AD": "New ad"
+    },
+    "SEARCH": {
+      "TITLE": "Market",
+      "SEARCH_HELP": "Search (car, store)",
+      "BTN_ADD": "New",
+      "BTN_OPTIONS": "Advanced search",
+      "BTN_AROUND_ME": "Around me",
+      "LOCATION": "Location",
+      "LOCATION_HELP": "City",
+      "LAST_RECORDS": "Last records:",
+      "RESULTS": "Results:"
+    },
+    "VIEW": {
+      "TITLE": "Ad"
+    },
+    "EDIT": {
+      "TITLE": "Edit",
+      "RECORD_TITLE": "Title",
+      "RECORD_TITLE_HELP": "Title",
+      "RECORD_DESCRIPTION": "Description",
+      "RECORD_DESCRIPTION_HELP": "Description",
+      "RECORD_LOCATION": "Localization",
+      "RECORD_LOCATION_HELP": "Address, City",
+      "RECORD_PRICE": "Price",
+      "RECORD_PRICE_HELP": "Price (optional)",
+      "BTN_ADD_PICTURES": "Add pictures",
+      "BTN_PUBLISH": "Publish",
+      "BTN_SAVE": "Save"
+    },
+    "ERROR": {
+      "LOAD_CATEGORY_FAILED": "Error while loading market categories",
+      "LOAD_RECORD_FAILED": "Error while loading record."
+    }
+  },
+  "REGISTRY": {
+    "COMMON": {
+      "CATEGORY": "Category",
+      "CATEGORIES": "Categories",
+      "ISSUER": "Issuer",
+      "BTN_NEW": "Add"
+    },
+    "SEARCH": {
+      "TITLE": "Registry",
+      "SEARCH_HELP": "Search (name, pseudo, public key...)",
+      "BTN_ADD": "New",
+      "BTN_OPTIONS": "Search tool",
+      "LOCATION": "Location",
+      "LOCATION_HELP": "City",
+      "LAST_RECORDS": "Last records:",
+      "RESULTS": "Results:"
+    },
+    "VIEW": {
+      "TITLE": "Registry"
+    },
+    "NEW": {
+      "TITLE": "New",
+      "SELECT_TYPE": "Choose type:",
+      "TYPE_PARTICULAR": "Private individual",
+      "TYPE_COMPANY": "Company, organisation or institution"
+    },
+    "EDIT": {
+      "TITLE": "Edit",
+      "RECORD_TITLE": "Name",
+      "RECORD_TITLE_HELP": "Name",
+      "RECORD_DESCRIPTION": "About me",
+      "RECORD_DESCRIPTION_HELP": "Something about me",
+      "RECORD_LOCATION": "Localization",
+      "RECORD_LOCATION_HELP": "Localization (address, city)",
+      "RECORD_SOCIAL_NETWORKS": "Social networks",
+      "RECORD_PUBKEY": "Public key",
+      "BTN_ADD_PICTURES": "Add pictures",
+      "BTN_PUBLISH": "Publish",
+      "BTN_SAVE": "Save"
+    },
+    "ERROR": {
+      "LOAD_RECORD_FAILED": "Loading failed",
+      "SAVE_RECORD_FAILED": "Sending failed"
+    }
+  }
+}
diff --git a/www/plugins/es/i18n/locale-fr-FR.json b/www/plugins/es/i18n/locale-fr-FR.json
new file mode 100644
index 0000000000000000000000000000000000000000..395e30770e90c646e35adb6ff37103732437ef88
--- /dev/null
+++ b/www/plugins/es/i18n/locale-fr-FR.json
@@ -0,0 +1,89 @@
+{
+  "MARKET": {
+    "COMMON": {
+      "CATEGORY": "Catégorie",
+      "CATEGORIES": "Catégories",
+      "ISSUER": "Soumis par",
+      "PRICE": "Prix",
+      "BTN_BUY": "Acheter",
+      "BTN_NEW_AD": "Nouvelle annonce"
+    },
+    "SEARCH": {
+      "TITLE": "Annonces",
+      "SEARCH_HELP": "Recherche (voiture, livre...)",
+      "BTN_ADD": "Nouveau",
+      "BTN_OPTIONS": "Recherche avancée",
+      "BTN_AROUND_ME": "Autour de moi",
+      "LOCATION": "Localisation",
+      "LOCATION_HELP": "Ville",
+      "LAST_RECORDS": "Dernières annonces :",
+      "RESULTS": "Résultats :"
+    },
+    "VIEW": {
+      "TITLE": "Annonce"
+    },
+    "EDIT": {
+      "TITLE": "Edition",
+      "RECORD_TITLE": "Titre",
+      "RECORD_TITLE_HELP": "Titre",
+      "RECORD_DESCRIPTION": "Description",
+      "RECORD_DESCRIPTION_HELP": "Description",
+      "RECORD_LOCATION": "Ville",
+      "RECORD_LOCATION_HELP": "Adresse, Ville",
+      "RECORD_PRICE": "Prix",
+      "RECORD_PRICE_HELP": "Prix (optionnel)",
+      "BTN_ADD_PICTURES": "Ajouter des photos",
+      "BTN_PUBLISH": "Publier",
+      "BTN_SAVE": "Sauvegarder"
+    },
+    "ERROR": {
+      "LOAD_CATEGORY_FAILED": "Erreur d'initialisation des catégories",
+      "LOAD_RECORD_FAILED": "Erreur lors du chargement de l'enregistrement."
+    }
+  },
+  "REGISTRY": {
+    "COMMON": {
+      "CATEGORY": "Catégorie",
+      "CATEGORIES": "Catégories",
+      "ISSUER": "Soumis par",
+      "BTN_NEW": "Ajouter"
+    },
+    "SEARCH": {
+      "TITLE": "Annuaire",
+      "SEARCH_HELP": "Recherche (nom, pseudo, clé publique...)",
+      "BTN_ADD": "Nouveau",
+      "BTN_OPTIONS": "Recherche avancée",
+      "LOCATION": "Localisation",
+      "LOCATION_HELP": "Ville",
+      "LAST_RECORDS": "Derniers enregistrements :",
+      "RESULTS": "Résultats :"
+    },
+    "VIEW": {
+      "TITLE": "Annuaire"
+    },
+    "NEW": {
+      "TITLE": "Nouveau",
+      "SELECT_TYPE": "Type de référencement :",
+      "TYPE_PARTICULAR": "Particulier",
+      "TYPE_COMPANY": "Entreprise, organisme ou institution"
+    },
+    "EDIT": {
+      "TITLE": "Edition",
+      "RECORD_TITLE": "Nom",
+      "RECORD_TITLE_HELP": "Nom",
+      "RECORD_DESCRIPTION": "À propos de moi",
+      "RECORD_DESCRIPTION_HELP": "À propos de moi",
+      "RECORD_LOCATION": "Localisation",
+      "RECORD_LOCATION_HELP": "Localisation (adresse, ville)",
+      "RECORD_SOCIAL_NETWORKS": "Réseaux sociaux",
+      "RECORD_PUBKEY": "Clé publique",
+      "BTN_ADD_PICTURES": "Ajouter des photos",
+      "BTN_PUBLISH": "Publier",
+      "BTN_SAVE": "Sauvegarder"
+    },
+    "ERROR": {
+      "LOAD_RECORD_FAILED": "Chargement impossible",
+      "SAVE_RECORD_FAILED": "Erreur lors de la sauvegarde"
+    }
+  }
+}
diff --git a/www/plugins/es/js/controllers/market-controllers.js b/www/plugins/es/js/controllers/market-controllers.js
new file mode 100644
index 0000000000000000000000000000000000000000..74e3fcdbb2d719beed58ab78fc3d596e7903cd35
--- /dev/null
+++ b/www/plugins/es/js/controllers/market-controllers.js
@@ -0,0 +1,550 @@
+angular.module('cesium.market.controllers', ['cesium.services', 'ngSanitize'])
+
+  .config(function($stateProvider, $urlRouterProvider) {
+    'ngInject';
+
+    $stateProvider
+
+    .state('app.market_lookup', {
+      url: "/market?q",
+      views: {
+        'menuContent': {
+          templateUrl: "plugins/es/templates/market/lookup.html",
+          controller: 'MarketLookupCtrl'
+        }
+      }
+    })
+
+   .state('app.market_view_record', {
+      url: "/market/:id/:title",
+      views: {
+        'menuContent': {
+          templateUrl: "plugins/es/templates/market/view_record.html",
+          controller: 'MarketRecordViewCtrl'
+        }
+      }
+    })
+
+    .state('app.market_add_record', {
+      url: "/market/add",
+      views: {
+        'menuContent': {
+          templateUrl: "plugins/es/templates/market/edit_record.html",
+          controller: 'MarketRecordEditCtrl'
+        }
+      }
+    })
+
+    .state('app.market_edit_record', {
+      url: "/market/:id/edit",
+      views: {
+        'menuContent': {
+          templateUrl: "plugins/es/templates/market/edit_record.html",
+          controller: 'MarketRecordEditCtrl'
+        }
+      }
+    });
+  })
+
+ .controller('MarketLookupCtrl', MarketLookupController)
+
+ .controller('MarketRecordViewCtrl', MarketRecordViewController)
+
+ .controller('MarketRecordEditCtrl', MarketRecordEditController)
+
+;
+
+function MarketCategoryModalController($scope, Market, $state, $ionicModal, UIUtils) {
+  'ngInject';
+
+  $scope.categoryModal = null;
+  $scope.categories = {
+      all: null,
+      search: {
+        text: '',
+        results: {},
+        options: false
+      }
+  };
+
+  // category lookup modal
+  $ionicModal.fromTemplateUrl('plugins/es/templates/market/modal_category.html', {
+      scope: $scope,
+      focusFirstInput: true
+  }).then(function(modal) {
+    $scope.categoryModal = modal;
+    $scope.categoryModal.hide();
+  });
+
+  $scope.openCategoryModal = function() {
+
+    // load categories
+    Market.category.all()
+    .then(function(categories){
+      $scope.categories.search.text = '';
+      $scope.categories.search.results = categories;
+      $scope.categories.all = categories;
+      UIUtils.ink();
+      $scope.categoryModal.show();
+    });
+  };
+
+  $scope.closeCategoryModal = function() {
+    $scope.categoryModal.hide();
+  };
+
+  $scope.selectCategory = function(cat) {
+    if (!cat.parent) return;
+    console.log('Category ' + cat.name + 'selected. Method selectCategory(cat) not overwritten.');
+    $scope.closeCategoryModal();
+  };
+
+  $scope.searchCategoryChanged = function() {
+    $scope.categories.search.text = $scope.categories.search.text.toLowerCase();
+    if ($scope.categories.search.text.length > 1) {
+      $scope.doSearchCategory($scope.categories.search.text);
+    }
+    else {
+      $scope.categories.search.results = $scope.categories.all;
+    }
+  };
+
+  $scope.doSearchCategory = function(text) {
+    $scope.search.looking = true;
+
+    $scope.categories.search.results = $scope.categories.all.reduce(function(result, cat) {
+      if (cat.parent && cat.name.toLowerCase().search(text) != -1) {
+          return result.concat(cat);
+      }
+      return result;
+    }, []);
+
+    $scope.categories.search.looking = false;
+  };
+}
+
+function MarketLookupController($scope, Market, $state, $ionicModal, $focus, $timeout, UIUtils) {
+  'ngInject';
+
+  MarketCategoryModalController.call(this, $scope, Market, $state, $ionicModal, UIUtils);
+
+  $scope.search = {
+    text: '',
+    lastRecords: true,
+    results: [],
+    looking: true,
+    category: null,
+    location: null,
+    options: false
+  };
+
+  $scope.$on('$ionicView.enter', function(e, $state) {
+    if (!$scope.entered || !$scope.search.results || $scope.search.results.length === 0) {
+      if ($state.stateParams && $state.stateParams.q) { // Query parameter
+        $scope.search.text=$state.stateParams.q;
+        $timeout(function() {
+          $scope.doSearch();
+        }, 100);
+      }
+      else {
+        $timeout(function() {
+          $scope.doGetLastRecord();
+        }, 100);
+      }
+      $scope.entered = true;
+    }
+    $focus('searchText');
+  });
+
+  $scope.$watch('search.options', $scope.doSearch, true);
+
+  $scope.isFilter = function(filter) {
+    return ($scope.filter == filter);
+  };
+
+  $scope.selectCategory = function(cat) {
+    if (!cat.parent) return;
+    $scope.search.category = cat;
+    $scope.closeCategoryModal();
+    $scope.doSearch();
+  };
+
+  $scope.doSearch = function() {
+    $scope.search.looking = true;
+    $scope.search.lastRecords = false;
+    if (!$scope.search.options) {
+      $scope.search.options = false;
+    }
+
+    var request = {
+      query: {},
+      highlight: {
+        fields : {
+          title : {},
+          description : {}
+        }
+      },
+      from: 0,
+      size: 20,
+      _source: Market.record.fields.commons
+    };
+    var text = $scope.search.text.toLowerCase().trim();
+    var matches = [];
+    var filters = [];
+    if (text.length > 1) {
+      var matchFields = ["title", "description", "issuer", "location"];
+      matches.push({multi_match : { query: text,
+        fields: matchFields,
+        type: "phrase_prefix"
+      }});
+      matches.push({match: { title: text}});
+      matches.push({match: { description: text}});
+      matches.push({prefix: { location: text}});
+    }
+    if ($scope.search.options && $scope.search.category) {
+      filters.push({term: { category: $scope.search.category.id}});
+    }
+    if ($scope.search.options && $scope.search.location && $scope.search.location.length > 0) {
+      filters.push({match_phrase: { location: $scope.search.location}});
+    }
+
+    if (matches.length === 0 && filters.length === 0) {
+      $scope.doGetLastRecord();
+      return;
+    }
+    request.query.bool = {};
+    if (matches.length > 0) {
+      request.query.bool.should =  matches;
+    }
+    if (filters.length > 0) {
+      request.query.bool.filter =  filters;
+    }
+
+    $scope.doRequest(request);
+  };
+
+  $scope.doGetLastRecord = function() {
+    $scope.search.looking = true;
+    $scope.search.lastRecords = true;
+
+    var request = {
+      sort: {
+        "time" : "desc"
+      },
+      from: 0,
+      size: 20,
+      _source: Market.record.fields.commons
+    };
+
+    $scope.doRequest(request);
+  };
+
+
+  $scope.doRequest = function(request) {
+    $scope.search.looking = true;
+
+    Market.category.all()
+      .then(function(categories) {
+        return Market.record.search(request)
+          .then(function(res){
+            if (res.hits.total === 0) {
+              $scope.search.results = [];
+            }
+            else {
+              var records = res.hits.hits.reduce(function(result, hit) {
+                  var record = hit._source;
+                  record.id = hit._id;
+                  record.type = hit._type;
+                  record.urlTitle = record.title;
+                  if (record.category && record.category.id) {
+                    record.category = categories[record.category.id];
+                  }
+                  if (record.thumbnail) {
+                    record.thumbnail = UIUtils.image.fromAttachment(record.thumbnail);
+                  }
+                  if (hit.highlight) {
+                    if (hit.highlight.title) {
+                        record.title = hit.highlight.title[0];
+                    }
+                    if (hit.highlight.description) {
+                        record.description = hit.highlight.description[0];
+                    }
+                    if (hit.highlight.location) {
+                        record.location = hit.highlight.location[0];
+                    }
+                  }
+                  return result.concat(record);
+                }, []);
+              $scope.search.results = records;
+
+              // Set Motion
+              $timeout(function() {
+                UIUtils.motion.fadeSlideInRight({
+                  startVelocity: 3000
+                });
+              }, 10);
+
+              // Set Ink
+              UIUtils.ink();
+            }
+
+            $scope.search.looking = false;
+          })
+          .catch(function(err) {
+            $scope.search.looking = false;
+            $scope.search.results = [];
+          });
+      })
+      .catch(function(err) {
+        $scope.search.looking = false;
+        $scope.search.results = [];
+      });
+  };
+}
+
+function MarketRecordViewController($scope, $ionicModal, Wallet, Market, UIUtils, $state, CryptoUtils, $q, $timeout) {
+  'ngInject';
+
+  $scope.formData = {};
+  $scope.id = null;
+  $scope.isMember = false;
+  $scope.category = {};
+  $scope.pictures = [];
+  $scope.canEdit = false;
+
+  $scope.$on('$ionicView.enter', function(e, $state) {
+    if ($state.stateParams && $state.stateParams.id) { // Load by id
+       $scope.load($state.stateParams.id);
+    }
+    else {
+      $state.go('app.market_lookup');
+    }
+  });
+
+  $scope.load = function(id) {
+    UIUtils.loading.show();
+    Market.category.all()
+    .then(function(categories) {
+      Market.record.getCommons({id: id})
+      .then(function (hit) {
+        $scope.formData = hit._source;
+        if (hit._source.category && hit._source.category.id) {
+          $scope.category = categories[hit._source.category.id];
+        }
+        $scope.id= hit._id;
+        if (hit._source.thumbnail) {
+          $scope.thumbnail = UIUtils.image.fromAttachment(hit._source.thumbnail);
+        }
+        $scope.canEdit = !$scope.isLogged() || ($scope.formData && $scope.formData.issuer === Wallet.getData().pubkey);
+        UIUtils.loading.hide();
+
+        // launch get pictures
+        Market.record.getPictures({id: id})
+        .then(function(hit) {
+          if (hit._source.pictures) {
+            $scope.pictures = hit._source.pictures.reduce(function(res, pic) {
+              return res.concat(UIUtils.image.fromAttachment(pic.file));
+            }, []);
+            // Set Motion
+            $timeout(function() {
+              UIUtils.motion.fadeSlideIn({
+                startVelocity: 3000
+              });
+            }, 10);
+          }
+        })
+        .catch(function(err) {
+          $scope.pictures = [];
+        });
+      })
+      .catch(function(err) {
+        if (!$scope.secondTry) {
+          $scope.secondTry = true;
+          $q(function() {
+            $scope.load(id); // loop once
+          }, 100);
+        }
+        else {
+          UIUtils.onError('MARKET.ERROR.LOAD_RECORD_FAILED')(err);
+        }
+      });
+    })
+    .catch(function(){
+      $scope.loading = false;
+      UIUtils.onError('MARKET.ERROR.LOAD_CATEGORY_FAILED')(err);
+    });
+  };
+
+  $scope.edit = function() {
+    $state.go('app.market_edit_record', {id: $scope.id});
+  };
+}
+
+function MarketRecordEditController($scope, $ionicModal, Wallet, Market, UIUtils, $state, CryptoUtils, $q, $ionicPopup, Device, $timeout) {
+  'ngInject';
+
+  MarketCategoryModalController.call(this, $scope, Market, $state, $ionicModal, UIUtils);
+
+  $scope.walletData = {};
+  $scope.formData = {};
+  $scope.id = null;
+  $scope.isMember = false;
+  $scope.category = {};
+  $scope.pictures = [];
+
+  $scope.$on('$ionicView.enter', function(e, $state) {
+    $scope.loadWallet()
+    .then(function(walletData) {
+      $scope.walletData = walletData;
+      if ($state.stateParams && $state.stateParams.id) { // Load by id
+        UIUtils.loading.show();
+        $scope.load($state.stateParams.id);
+      }
+      else {
+        UIUtils.loading.hide();
+      }
+    });
+  });
+
+  $scope.load = function(id) {
+    UIUtils.loading.show();
+    $q.all([
+      Market.category.all()
+      .then(function(categories) {
+        Market.record.get({id: id})
+        .then(function (hit) {
+          $scope.formData = hit._source;
+          if (hit._source.category && hit._source.category.id) {
+            $scope.category = categories[hit._source.category.id];
+          }
+          $scope.id= hit._id;
+          if (hit._source.pictures) {
+            $scope.pictures = hit._source.pictures.reduce(function(res, pic) {
+              return res.concat(UIUtils.image.fromAttachment(pic.file));
+            }, []);
+          }
+          UIUtils.loading.hide();
+          UIUtils.motion.pushDown({
+                  selector: '.push-down'
+              });
+          UIUtils.motion.fadeSlideInRight({
+                  selector: '.animate-fade-slide-in .item'
+              });
+          // Set Ink
+          UIUtils.ink();
+        });
+      })
+    ])
+    .catch(UIUtils.onError('Could not load market'));
+  };
+
+  $scope.save = function() {
+    UIUtils.loading.show();
+    return $q(function(resolve, reject) {
+      var doFinishSave = function(formData) {
+        if (!$scope.id) { // Create
+          // Set time (UTC)
+          // TODO : use the block chain time
+          formData.time = Math.floor(moment().utc().valueOf() / 1000);
+          Market.record.add(formData, $scope.walletData.keypair)
+          .then(function(id) {
+            UIUtils.loading.hide();
+            $state.go('app.market_view_record', {id: id});
+            resolve();
+          })
+          .catch(UIUtils.onError('Could not save market'));
+        }
+        else { // Update
+          if (formData.time) {
+            // Set time (UTC)
+            // TODO : use the block chain time
+            formData.time = Math.floor(moment().utc().valueOf() / 1000);
+          }
+          Market.record.update(formData, {id: $scope.id}, $scope.walletData.keypair)
+          .then(function() {
+            UIUtils.loading.hide();
+            $state.go('app.market_view_record', {id: $scope.id});
+            resolve();
+          })
+          .catch(UIUtils.onError('Could not update market'));
+        }
+      };
+
+      $scope.formData.picturesCount = $scope.pictures.length
+      if ($scope.formData.picturesCount > 0) {
+        $scope.formData.pictures = $scope.pictures.reduce(function(res, pic) {
+          return res.concat({file: UIUtils.image.toAttachment(pic)});
+        }, []);
+        UIUtils.image.resizeSrc($scope.pictures[0].src, true)
+        .then(function(imageSrc) {
+          $scope.formData.thumbnail = UIUtils.image.toAttachment({src: imageSrc});
+
+          doFinishSave($scope.formData);
+        });
+      }
+      else {
+        delete $scope.formData.thumbnail;
+        delete $scope.formData.pictures;
+        doFinishSave($scope.formData);
+      }
+    });
+  };
+
+  $scope.selectCategory = function(cat) {
+    if (!cat.parent) return;
+    $scope.category = cat;
+    $scope.formData.category = cat;
+    $scope.closeCategoryModal();
+  };
+
+  $scope.getPicture = function() {
+    Device.camera.getPicture()
+    .then(function(imageData) {
+      $scope.pictures.push({src: "data:image/png;base64," + imageData});
+      $scope.$apply();
+    })
+    .catch(UIUtils.onError('ERROR.TAKE_PICTURE_FAILED'));
+  };
+
+  $scope.fileChanged = function(event) {
+    UIUtils.loading.show();
+    return $q(function(resolve, reject) {
+      var file = event.target.files[0];
+      UIUtils.image.resizeFile(file)
+      .then(function(imageData) {
+        $scope.pictures.push({src: imageData});
+        UIUtils.loading.hide();
+        //$scope.$apply();
+        resolve();
+      });
+    });
+  };
+
+  $scope.removePicture = function(index){
+    $scope.pictures.splice(index, 1);
+  };
+
+  $scope.favoritePicture = function(index){
+    if (index > 0) {
+      var item = $scope.pictures[index];
+      $scope.pictures.splice(index, 1);
+      $scope.pictures.splice(0, 0, item);
+    }
+  };
+
+  $scope.auth = function() {
+    $scope.loadWallet()
+    .then(function(walletData) {
+      UIUtils.loading.show();
+      $scope.walletData = walletData;
+      Market.auth.token(walletData.keypair)
+      .then(function(token) {
+        UIUtils.loading.hide();
+        console.log('authentication token is:' + token);
+      })
+      .catch(onError('Could not computed authentication token'));
+    })
+    .catch(onError('Could not computed authentication token'));
+  };
+
+}
diff --git a/www/plugins/es/js/controllers/registry-controllers.js b/www/plugins/es/js/controllers/registry-controllers.js
new file mode 100644
index 0000000000000000000000000000000000000000..840e4993c60ee8b83e9f21676fbe501e0987dce1
--- /dev/null
+++ b/www/plugins/es/js/controllers/registry-controllers.js
@@ -0,0 +1,711 @@
+angular.module('cesium.registry.controllers', ['cesium.services', 'ngSanitize'])
+
+  .config(function($stateProvider, $urlRouterProvider) {
+    'ngInject';
+
+    $stateProvider
+
+    .state('app.registry_lookup', {
+      url: "/registry?q",
+      views: {
+        'menuContent': {
+          templateUrl: "plugins/es/templates/registry/lookup.html",
+          controller: 'RegistryLookupCtrl'
+        }
+      }
+    })
+
+   .state('app.registry_view_record', {
+      url: "/registry/:id/:title",
+      views: {
+        'menuContent': {
+          templateUrl: "plugins/es/templates/registry/view_record.html",
+          controller: 'RegistryRecordViewCtrl'
+        }
+      }
+    })
+
+    .state('app.registry_add_record', {
+      url: "/registry/add",
+      views: {
+        'menuContent': {
+          templateUrl: "plugins/es/templates/registry/edit_record.html",
+          controller: 'RegistryRecordEditCtrl'
+        }
+      }
+    })
+
+    .state('app.registry_edit_record', {
+      url: "/registry/:id/edit",
+      views: {
+        'menuContent': {
+          templateUrl: "plugins/es/templates/registry/edit_record.html",
+          controller: 'RegistryRecordEditCtrl'
+        }
+      }
+    })
+    ;
+  })
+
+ .controller('RegistryLookupCtrl', RegistryLookupController)
+
+ .controller('RegistryRecordViewCtrl', RegistryRecordViewController)
+
+ .controller('RegistryRecordEditCtrl', RegistryRecordEditController)
+
+;
+
+function RegistryCategoryModalController($scope, Registry, $state, $ionicModal, UIUtils) {
+  'ngInject';
+
+  $scope.categoryModal = null;
+  $scope.categories = {
+      all: null,
+      search: {
+        text: '',
+        results: {},
+        options: false
+      }
+  };
+
+  // category lookup modal
+  $ionicModal.fromTemplateUrl('plugins/es/templates/registry/modal_category.html', {
+      scope: $scope,
+      focusFirstInput: true
+  }).then(function(modal) {
+    $scope.categoryModal = modal;
+    $scope.categoryModal.hide();
+  });
+
+  $scope.openCategoryModal = function() {
+    // load categories
+    Registry.category.all()
+    .then(function(categories){
+      $scope.categories.search.text = '';
+      $scope.categories.search.results = categories;
+      $scope.categories.all = categories;
+      UIUtils.ink();
+      $scope.categoryModal.show();
+    });
+  };
+
+  $scope.closeCategoryModal = function() {
+    $scope.categoryModal.hide();
+  };
+
+  $scope.selectCategory = function(cat) {
+    if (!cat.parent) return;
+    console.log('Category ' + cat.name + 'selected. Method selectCategory(cat) not overwritten.');
+    $scope.closeCategoryModal();
+  };
+
+  $scope.searchCategoryChanged = function() {
+    $scope.categories.search.text = $scope.categories.search.text.toLowerCase();
+    if ($scope.categories.search.text.length > 1) {
+      $scope.doSearchCategory($scope.categories.search.text);
+    }
+    else {
+      $scope.categories.search.results = $scope.categories.all;
+    }
+  };
+
+  $scope.doSearchCategory = function(text) {
+    $scope.search.looking = true;
+
+    $scope.categories.search.results = $scope.categories.all.reduce(function(result, cat) {
+      if (cat.parent && cat.name.toLowerCase().search(text) != -1) {
+          return result.concat(cat);
+      }
+      return result;
+    }, []);
+
+    $scope.categories.search.looking = false;
+  };
+}
+
+function RegistryLookupController($scope, $state, $ionicModal, $focus, $q, $timeout, Registry, UIUtils, $sanitize) {
+  'ngInject';
+
+  RegistryCategoryModalController.call(this, $scope, Registry, $state, $ionicModal, UIUtils);
+  RegistryNewRecordWizardController.call(this, $scope, $ionicModal, $state, UIUtils, $q, $timeout, Registry);
+
+  $scope.search = {
+    text: '',
+    results: [],
+    lastRecords: true,
+    category: null,
+    location: null,
+    options: null
+  };
+
+  $scope.$on('$ionicView.enter', function(e, $state) {
+    if (!$scope.entered || !$scope.search.results || $scope.search.results.length === 0) {
+      if ($state.stateParams && $state.stateParams.q) { // Query parameter
+        $scope.search.text=$state.stateParams.q;
+        $timeout(function() {
+          $scope.doSearch();
+        }, 100);
+      }
+      else {
+        $timeout(function() {
+          $scope.doGetLastRecord();
+        }, 100);
+      }
+      $scope.entered = true;
+    }
+    $focus('searchText');
+  });
+
+  $scope.$watch('search.options', $scope.doSearch, true);
+
+  $scope.isFilter = function(filter) {
+    return ($scope.filter == filter);
+  };
+
+  $scope.selectCategory = function(cat) {
+    if (!cat.parent) return;
+    $scope.search.category = cat;
+    $scope.closeCategoryModal();
+    $scope.doSearch();
+  };
+
+  $scope.doSearch = function() {
+    $scope.search.looking = true;
+    $scope.search.lastRecords = false;
+    if (!$scope.search.options) {
+      $scope.search.options = false;
+    }
+
+    var request = {
+      query: {},
+      highlight: {
+        fields : {
+          title : {},
+          description : {}
+        }
+      },
+      from: 0,
+      size: 20,
+      _source: ["title", "description", "time", "location", "pictures", "issuer", "category"]
+    };
+    var text = $scope.search.text.toLowerCase().trim();
+    var matches = [];
+    var filters = [];
+    if (text.length > 1) {
+      var matchFields = ["title", "description", "issuer", "location"];
+      matches.push({multi_match : { query: text,
+        fields: matchFields,
+        type: "phrase_prefix"
+      }});
+      matches.push({match : { title: text}});
+      matches.push({match : { description: text}});
+      matches.push({prefix : { location: text}});
+      matches.push({prefix : { issuer: text}});
+    }
+    if ($scope.search.options && $scope.search.category) {
+      filters.push({term: { category: $scope.search.category.id}});
+    }
+    if ($scope.search.options && $scope.search.location && $scope.search.location.length > 0) {
+      filters.push({match_phrase: { location: $scope.search.location}});
+    }
+
+    if (matches.length === 0 && filters.length === 0) {
+      $scope.search.results = [];
+      $scope.search.looking = false;
+      return;
+    }
+    request.query.bool = {};
+    if (matches.length > 0) {
+      request.query.bool.should =  matches;
+    }
+    if (filters.length > 0) {
+      request.query.bool.filter =  filters;
+    }
+
+    $scope.doRequest(request);
+  };
+
+
+  $scope.doGetLastRecord = function() {
+    $scope.search.looking = true;
+    $scope.search.lastRecords = true;
+
+    var request = {
+      sort: {
+        "time" : "desc"
+      },
+      from: 0,
+      size: 20,
+      _source: ["title", "description", "time", "location", "pictures", "issuer", "category"]
+    };
+
+    $scope.doRequest(request);
+  };
+
+  $scope.doRequest = function(request) {
+    $scope.search.looking = true;
+
+    Registry.category.all()
+      .then(function(categories) {
+        Registry.record.search(request)
+          .then(function(res){
+            if (res.hits.total === 0) {
+              $scope.search.results = [];
+            }
+            else {
+              var items = res.hits.hits.reduce(function(result, hit) {
+                  var registry = hit._source;
+                  registry.id = hit._id;
+                  registry.type = hit._type;
+                  registry.urlTitle = registry.title;
+                  if (registry.category) {
+                    registry.category = categories[registry.category];
+                  }
+                  if (hit.highlight) {
+                    if (hit.highlight.title) {
+                        registry.title = hit.highlight.title[0];
+                    }
+                    if (hit.highlight.description) {
+                        registry.description = hit.highlight.description[0];
+                    }
+                    if (hit.highlight.location) {
+                        registry.description = hit.highlight.location[0];
+                    }
+                  }
+                  return result.concat(registry);
+                }, []);
+              $scope.search.results = items;
+
+              // Set Motion
+              $timeout(function() {
+                UIUtils.motion.fadeSlideInRight({
+                  startVelocity: 3000
+                });
+              }, 10);
+
+              // Set Ink
+              UIUtils.ink();
+            }
+
+            $scope.search.looking = false;
+          })
+          .catch(function(err) {
+              $scope.search.looking = false;
+              $scope.search.results = [];
+            });
+      })
+      .catch(function(err) {
+        $scope.search.looking = false;
+        $scope.search.results = [];
+      });
+  };
+
+ // TODO: remove auto add account when done
+ /* $timeout(function() {
+    $scope.search.text='lavenier';
+    $scope.doSearch();
+  }, 400);
+  */
+}
+
+function RegistryRecordViewController($scope, $ionicModal, Wallet, Registry, UIUtils, $state, CryptoUtils, $q, BMA) {
+  'ngInject';
+
+  $scope.formData = {};
+  $scope.id = null;
+  $scope.isMember = false;
+  $scope.category = {};
+  $scope.pictures = [];
+  $scope.canEdit = false;
+  $scope.hasSelf = false;
+  $scope.identity = null;
+  $scope.isCompany = false;
+
+  $scope.$on('$ionicView.enter', function(e, $state) {
+    if ($state.stateParams && $state.stateParams.id) { // Load by id
+       $scope.load($state.stateParams.id);
+    }
+    else {
+      $state.go('app.lookup_registry');
+    }
+  });
+
+  $scope.load = function(id) {
+    UIUtils.loading.show();
+    $q.all([
+      Registry.category.all()
+      .then(function(categories) {
+        Registry.record.get({id: id})
+        .then(function (hit) {
+          $scope.formData = hit._source;
+          if (hit._source.category && hit._source.category.id){
+            $scope.category = categories[hit._source.category.id];
+          }
+          $scope.id= hit._id;
+          if (hit._source.pictures) {
+            $scope.pictures = hit._source.pictures.reduce(function(res, pic) {
+              return res.concat({src: pic.src});
+            }, []);
+          }
+          $scope.canEdit = !$scope.isLogged() || ($scope.formData && $scope.formData.issuer == Wallet.getData().pubkey);
+
+          $scope.isCompany = $scope.category.id == 'particulier';
+          if (!$scope.isCompany) {
+            BMA.wot.lookup({ search: $scope.formData.issuer })
+              .then(function(res){
+                $scope.identity = res.results.reduce(function(idties, res) {
+                  return idties.concat(res.uids.reduce(function(uids, idty) {
+                    return uids.concat({
+                      uid: idty.uid,
+                      pub: res.pubkey,
+                      timestamp: idty.meta.timestamp,
+                      sig: idty.self
+                    });
+                  }, []));
+                }, [])[0];
+                $scope.hasSelf = ($scope.identity.uid && $scope.identity.timestamp && $scope.identity.sig);
+                UIUtils.loading.hide();
+              })
+              .catch(function(err) {
+                if (err && err.ucode == 2001) {
+                  $scope.identity = {
+                    pub: $scope.formData.issuer
+                  };
+                  $scope.hasSelf = false;
+                  UIUtils.loading.hide();
+                }
+                else {
+                  UIUtils.onError('ERROR.WOT_LOOKUP_FAILED')(err);
+                }
+              });
+          }
+          else {
+            $scope.hasSelf = false;
+            $scope.identity = null;
+            UIUtils.loading.hide();
+          }
+        })
+        .catch(function(err) {
+          // Retry (ES could have error)
+          if (!$scope.secondTry) {
+            $scope.secondTry = true;
+            $q(function() {
+              $scope.load(id);
+            }, 100);
+          }
+          else {
+            UIUtils.onError('ERROR.LOAD_IDENTITY_FAILED')(err);
+          }
+        });
+      })
+    ]).catch(UIUtils.onError('REGISTRY.ERROR.LOAD_RECORD_FAILED'));
+  };
+
+  // Edit click
+  $scope.edit = function() {
+    UIUtils.loading.show();
+    $state.go('app.registry_edit_record', {id: $scope.id});
+  };
+
+  // Certify click
+  $scope.certifyIdentity = function(identity) {
+    $scope.loadWallet()
+    .then(function(walletData) {
+      UIUtils.loading.show();
+      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'));
+  };
+
+}
+
+function RegistryRecordEditController($scope, $ionicModal, Wallet, Registry, UIUtils, $state, CryptoUtils, $q, $ionicPopup, $translate, Device,
+  $ionicHistory) {
+  'ngInject';
+
+  RegistryCategoryModalController.call(this, $scope, Registry, $state, $ionicModal, UIUtils);
+
+  $scope.walletData = {};
+  $scope.recordData = {};
+  $scope.recordForm = {};
+  $scope.isCompany = null;
+  $scope.id = null;
+  $scope.isMember = false;
+  $scope.category = {};
+  $scope.pictures = [];
+
+  $scope.setRecordForm =  function(recordForm) {
+    $scope.recordForm = recordForm;
+  };
+
+  $scope.$on('$ionicView.enter', function(e, $state) {
+    $scope.loadWallet()
+    .then(function(walletData) {
+      $scope.walletData = walletData;
+      if ($state.stateParams && $state.stateParams.id) { // Load by id
+        $scope.load($state.stateParams.id);
+      }
+      else {
+        UIUtils.loading.hide();
+      }
+    });
+  });
+
+  $scope.load = function(id) {
+    UIUtils.loading.show();
+    $q.all([
+      Registry.category.all()
+      .then(function(categories) {
+        Registry.record.get({id: id})
+        .then(function (hit) {
+          $scope.recordData = hit._source;
+          if (hit._source.category && hit._source.category.id){
+            $scope.category = categories[hit._source.category.id];
+          }
+          $scope.id= hit._id;
+          if (hit._source.pictures) {
+            $scope.pictures = hit._source.pictures.reduce(function(res, pic) {
+              return res.concat({src: pic.src});
+            }, []);
+          }
+          UIUtils.loading.hide();
+        });
+      })
+    ])
+    .catch(UIUtils.onError('REGISTRY.ERROR.LOAD_RECORD_FAILED'));
+  };
+
+  $scope.save = function() {
+    UIUtils.loading.show();
+    return $q(function(resolve, reject) {
+      $scope.recordData.pictures = $scope.pictures.reduce(function(res, pic) {
+        return res.concat({src: pic.src});
+      }, []);
+      if (!$scope.id) { // Create
+          Registry.record.add($scope.recordData, $scope.walletData.keypair)
+          .then(function(id) {
+            UIUtils.loading.hide();
+            $state.go('app.registry_view_record', {id: id});
+            resolve();
+          })
+          .catch(UIUtils.onError('REGISTRY.ERROR.SAVE_RECORD_FAILED'));
+      }
+      else { // Update
+          Registry.record.update($scope.recordData, {id: $scope.id}, $scope.walletData.keypair)
+          .then(function() {
+            UIUtils.loading.hide();
+            $state.go('app.registry_view_record', {id: $scope.id});
+            resolve();
+          })
+          .catch(UIUtils.onError('REGISTRY.ERROR.SAVE_RECORD_FAILED'));
+      }
+    });
+  };
+
+  $scope.selectCategory = function(cat) {
+    if (!cat.parent) return;
+    $scope.category = cat;
+    $scope.recordData.category = cat.id;
+    $scope.closeCategoryModal();
+  };
+
+  $scope.openPicturePopup = function() {
+    Device.camera.getPicture()
+    .then(function(imageData) {
+      $scope.pictures.push({src: "data:image/png;base64," + imageData});
+      $scope.$apply();
+    })
+    .catch(UIUtils.onError('ERROR.TAKE_PICTURE_FAILED'));
+  };
+
+  $scope.fileChanged = function(event) {
+    UIUtils.loading.show();
+    return $q(function(resolve, reject) {
+      var file = event.target.files[0];
+      UIUtils.image.resizeFile(file)
+      .then(function(imageData) {
+        $scope.pictures.push({src: imageData});
+        UIUtils.loading.hide();
+        //$scope.$apply();
+        resolve();
+      });
+    });
+  };
+
+  $scope.removePicture = function(index){
+    $scope.pictures.splice(index, 1);
+  };
+
+  $scope.favoritePicture = function(index){
+    if (index > 0) {
+      var item = $scope.pictures[index];
+      $scope.pictures.splice(index, 1);
+      $scope.pictures.splice(0, 0, item);
+    }
+  };
+
+  $scope.auth = function() {
+    $scope.loadWallet()
+    .then(function(walletData) {
+      UIUtils.loading.show();
+      $scope.walletData = walletData;
+      Registry.auth.token(walletData.keypair)
+      .then(function(token) {
+        UIUtils.loading.hide();
+        console.log('authentication token is:' + token);
+      })
+      .catch(onError('Could not computed authentication token'));
+    })
+    .catch(onError('Could not computed authentication token'));
+  };
+
+  $scope.goBack = function() {
+    $ionicHistory.goBack();
+  };
+}
+
+function RegistryNewRecordWizardController($scope, $ionicModal, $state, UIUtils, $q, $timeout, Registry) {
+  'ngInject';
+
+  $scope.recordData = {};
+  $scope.isCompany = null;
+  $scope.recordForm = {};
+  $scope.pictures = [];
+  $scope.slides = {
+    slider: null,
+    options: {
+      loop: false,
+      effect: 'slide',
+      speed: 500
+    }
+  };
+
+  // Called to navigate to the main app
+  $scope.cancel = function() {
+    if ($scope.newRecordModal) {
+      $scope.newRecordModal.hide();
+      $scope.newRecordModal.remove();
+      $scope.newRecordModal = null;
+      $timeout(function(){
+        $scope.recordData = {};
+        $scope.recordForm = {};
+        $scope.isCompany = null;
+        $scope.pictures = [];
+        $scope.slides.slider.destroy();
+        delete $scope.slides.slider;
+      }, 200);
+    }
+  };
+
+  $scope.setRecordForm =  function(recordForm) {
+    $scope.recordForm = recordForm;
+  };
+
+  $scope.slidePrev = function() {
+    $scope.slides.slider.unlockSwipes();
+    $scope.slides.slider.slidePrev();
+    $scope.slides.slider.lockSwipes();
+  };
+
+  $scope.slideNext = function() {
+    $scope.slides.slider.unlockSwipes();
+    $scope.slides.slider.slideNext();
+    $scope.slides.slider.lockSwipes();
+  };
+
+  $scope.newRecord = function() {
+    var showModal = function() {
+      $scope.loadWallet()
+        .then(function(walletData) {
+          $scope.walletData = walletData;
+          $scope.slides.slider.slideTo(0);
+          $scope.slides.slider.lockSwipes();
+          UIUtils.loading.hide();
+          $scope.newRecordModal.show();
+          // TODO: remove default
+          /*$timeout(function() {
+            $scope.recordData.title="Benoit Lavenier";
+            $scope.recordData.description="J'aime le Sou !";
+            $scope.setIsCompany(false);
+          }, 300);*/
+        });
+    };
+
+    if (!$scope.newRecordModal) {
+      UIUtils.loading.show();
+      // Create the account modal that we will use later
+      $ionicModal.fromTemplateUrl('plugins/es/templates/registry/new_record_wizard.html', {
+        scope: $scope,
+        animation: 'slide-in-down'
+      }).then(function(modal) {
+        $scope.newRecordModal = modal;
+        $scope.newRecordModal.hide()
+        .then(function(){
+          showModal();
+        });
+
+      });
+    }
+    else {
+      showModal();
+    }
+  };
+
+  $scope.setIsCompany = function(bool) {
+    $scope.isCompany = bool;
+    $scope.slideNext();
+  };
+
+  $scope.doNewRecord = function() {
+    $scope.recordForm.$submitted=true;
+    if(!$scope.recordForm.$valid) {
+      return;
+    }
+
+    UIUtils.loading.show();
+    return $q(function(resolve, reject) {
+          $scope.recordData.pictures = $scope.pictures.reduce(function(res, pic) {
+            return res.concat({src: pic.src});
+          }, []);
+          // Use a default category if not a company
+          if (!$scope.isCompany) {
+            $scope.recordData.category={id:'particulier'};
+          }
+          // Set time (UTC)
+          // TODO : use the block chain time
+          $scope.recordData.time = Math.floor(moment().utc().valueOf() / 1000);
+          Registry.record.add($scope.recordData, $scope.walletData.keypair)
+          .then(function(id) {
+            $scope.cancel();
+            $state.go('app.registry_view_record', {id: id});
+            resolve();
+          })
+          .catch(UIUtils.onError('Could not save registry'));
+    });
+  };
+
+  //Cleanup the modal when hidden
+  $scope.$on('newRecordModal.hidden', function() {
+    $scope.cancel();
+  });
+
+  $scope.selectCategory = function(cat) {
+    if (!cat.parent) return;
+    $scope.recordData.category = cat;
+    $scope.closeCategoryModal();
+  };
+
+  // TODO: remove auto add account when done
+  /*$timeout(function() {
+    $scope.newRecord();
+  }, 400);
+  */
+}
diff --git a/www/plugins/es/js/services/market-services.js b/www/plugins/es/js/services/market-services.js
new file mode 100644
index 0000000000000000000000000000000000000000..cbceb34197a1c4e43c7766c1ad586c8b5854feb1
--- /dev/null
+++ b/www/plugins/es/js/services/market-services.js
@@ -0,0 +1,247 @@
+angular.module('cesium.market.services', ['ngResource', 'cesium.services', 'cesium.config'])
+
+.factory('Market', function($http, $q, CryptoUtils, APP_CONFIG) {
+  'ngInject';
+
+    function Market(server, wsServer) {
+
+      var
+        categories = [],
+        fields = {
+          commons: ["category", "title", "description", "issuer", "time", "location", "price", "unit", "currency", "thumbnail", "picturesCount"]
+        }
+      ;
+
+      if (wsServer) {
+        wsServer = server;
+      }
+
+      function processError(reject, data) {
+        if (data && data.message) {
+          reject(data);
+        }
+        else {
+          reject('Unknown error from Duniter ES node');
+        }
+      }
+
+      function prepare(uri, params, config, callback) {
+        var pkeys = [], queryParams = {}, newUri = uri;
+        if (typeof params == 'object') {
+          pkeys = _.keys(params);
+        }
+
+        _.forEach(pkeys, function(pkey){
+          var prevURI = newUri;
+          newUri = newUri.replace(new RegExp(':' + pkey), params[pkey]);
+          if (prevURI == newUri) {
+            queryParams[pkey] = params[pkey];
+          }
+        });
+        config.params = queryParams;
+        callback(newUri, config);
+      }
+
+      function getResource(uri) {
+        return function(params) {
+          return $q(function(resolve, reject) {
+            var config = {
+              timeout: 4000
+            };
+
+            prepare(uri, params, config, function(uri, config) {
+                $http.get(uri, config)
+                .success(function(data, status, headers, config) {
+                  resolve(data);
+                })
+                .error(function(data, status, headers, config) {
+                  processError(reject, data);
+                });
+            });
+          });
+        };
+      }
+
+      function postResource(uri) {
+        return function(data, params) {
+          return $q(function(resolve, reject) {
+            var config = {
+              timeout: 4000,
+              headers : {'Content-Type' : 'application/json'}
+            };
+
+            prepare(uri, params, config, function(uri, config) {
+                $http.post(uri, data, config)
+                .success(function(data, status, headers, config) {
+                  resolve(data);
+                })
+                .error(function(data, status, headers, config) {
+                  processError(reject, data);
+                });
+            });
+          });
+        };
+      }
+
+      function ws(uri) {
+        var sock = new WebSocket(uri);
+        return {
+          on: function(type, callback) {
+            sock.onmessage = function(e) {
+              callback(JSON.parse(e.data));
+            };
+          }
+        };
+      }
+
+      function getCategories() {
+        return $q(function(resolve, reject) {
+          if (categories.length !== 0) {
+            resolve(categories);
+            return;
+          }
+
+          getResource('http://' + server + '/market/category/_search?pretty&from=0&size=1000')()
+          .then(function(res) {
+            if (res.hits.total === 0) {
+                categories = [];
+            }
+            else {
+              categories = res.hits.hits.reduce(function(result, hit) {
+                var cat = hit._source;
+                cat.id = hit._id;
+                return result.concat(cat);
+              }, []);
+              // add as map also
+              _.forEach(categories, function(cat) {
+                categories[cat.id] = cat;
+              });
+            }
+            resolve(categories);
+          })
+          .catch(function(err) {
+             reject(err);
+           });
+        });
+      }
+
+      function getToken(keypair) {
+        return $q(function(resolve, reject) {
+          var errorFct = function(err) {
+            reject(err);
+          };
+          var getChallenge = getResource('http://' + server + '/auth');
+          var postAuth = postResource('http://' + server + '/auth');
+
+          getChallenge() // get the challenge phrase to sign
+          .then(function(challenge) {
+            CryptoUtils.sign(challenge, keypair) // sign the challenge
+            .then(function(signature) {
+              postAuth({
+                pubkey: CryptoUtils.util.encode_base58(keypair.signPk),
+                challenge: challenge,
+                signature: signature
+              }) // get token
+              .then(function(token) {
+                resolve(token);
+              })
+              .catch(errorFct);
+            })
+            .catch(errorFct);
+          })
+          .catch(errorFct);
+        });
+      }
+
+      var postRecord = postResource('http://' + server + '/market/record');
+
+      function addRecord(record, keypair) {
+        return $q(function(resolve, reject) {
+          var errorFct = function(err) {
+            reject(err);
+          };
+          var query = {};
+
+
+          var obj = {};
+          angular.copy(record, obj);
+          delete obj.signature;
+          delete obj.hash;
+          obj.issuer = CryptoUtils.util.encode_base58(keypair.signPk);
+          var str = JSON.stringify(obj);
+
+          CryptoUtils.util.hash(str)
+          .then(function(hash) {
+            CryptoUtils.sign(str, keypair)
+            .then(function(signature) {
+              obj.hash = hash;
+              obj.signature = signature;
+              postRecord(obj)
+              .then(function (id){
+                resolve(id);
+              })
+              .catch(errorFct);
+            })
+            .catch(errorFct);
+          })
+          .catch(errorFct);
+        });
+      }
+
+      function emptyHit() {
+        return {
+           _id: null,
+           _index: null,
+           _type: null,
+           _version: null,
+           _source: {}
+        };
+      }
+
+      function getCommons() {
+        var _source = fields.commons.reduce(function(res, field){
+          return res + ',' + field
+        }, '').substring(1);
+        return getResource('http://' + server + '/market/record/:id?_source=' + _source);
+      }
+
+      return {
+        auth: {
+            get: getResource('http://' + server + '/auth'),
+            post: postResource('http://' + server + '/auth'),
+            token: getToken
+        },
+        hit: {
+           empty: emptyHit
+        },
+        category: {
+          all: getCategories,
+          searchText: getResource('http://' + server + '/market/category/_search?q=:search'),
+          search: postResource('http://' + server + '/market/category/_search?pretty')
+        },
+        record: {
+          get: getResource('http://' + server + '/market/record/:id'),
+          getCommons: getCommons(),
+          getPictures: getResource('http://' + server + '/market/record/:id?_source=pictures'),
+          add: addRecord,
+          update: postResource('http://' + server + '/market/record/:id'),
+          searchText: getResource('http://' + server + '/market/record/_search?q=:search'),
+          search: postResource('http://' + server + '/market/record/_search?pretty'),
+          fields: {
+            commons: fields.commons
+          }
+        }
+      };
+    }
+
+    var ESNodeConfigured = !!APP_CONFIG.DUNITER_NODE_ES;
+    if (!ESNodeConfigured) {
+      return null;
+    }
+
+    var service = Market(APP_CONFIG.DUNITER_NODE_ES);
+
+    service.instance = Market;
+  return service;
+})
+;
diff --git a/www/plugins/es/js/services/registry-services.js b/www/plugins/es/js/services/registry-services.js
new file mode 100644
index 0000000000000000000000000000000000000000..25ba108332dd1def16b8e60f9d4851f0c0977b63
--- /dev/null
+++ b/www/plugins/es/js/services/registry-services.js
@@ -0,0 +1,275 @@
+angular.module('cesium.registry.services', ['ngResource', 'cesium.services'])
+
+.factory('Registry', function($http, $q, CryptoUtils, APP_CONFIG) {
+  'ngInject';
+
+    function Registry(server) {
+
+      var categories = [];
+
+      function processError(reject, data) {
+        if (data && data.message) {
+          reject(data);
+        }
+        else {
+          reject('Unknown error from Duniter node');
+        }
+      }
+
+      function prepare(uri, params, config, callback) {
+        var pkeys = [], queryParams = {}, newUri = uri;
+        if (typeof params == 'object') {
+          pkeys = _.keys(params);
+        }
+
+        _.forEach(pkeys, function(pkey){
+          var prevURI = newUri;
+          newUri = newUri.replace(new RegExp(':' + pkey), params[pkey]);
+          if (prevURI == newUri) {
+            queryParams[pkey] = params[pkey];
+          }
+        });
+        config.params = queryParams;
+        callback(newUri, config);
+      }
+
+      function getResource(uri) {
+        return function(params) {
+          return $q(function(resolve, reject) {
+            var config = {
+              timeout: 4000
+            };
+
+            prepare(uri, params, config, function(uri, config) {
+                $http.get(uri, config)
+                .success(function(data, status, headers, config) {
+                  resolve(data);
+                })
+                .error(function(data, status, headers, config) {
+                  processError(reject, data);
+                });
+            });
+          });
+        };
+      }
+
+      function postResource(uri) {
+        return function(data, params) {
+          return $q(function(resolve, reject) {
+            var config = {
+              timeout: 4000,
+              headers : {'Content-Type' : 'application/json'}
+            };
+
+            prepare(uri, params, config, function(uri, config) {
+                $http.post(uri, data, config)
+                .success(function(data, status, headers, config) {
+                  resolve(data);
+                })
+                .error(function(data, status, headers, config) {
+                  processError(reject, data);
+                });
+            });
+          });
+        };
+      }
+
+      function ws(uri) {
+        var sock = new WebSocket(uri);
+        return {
+          on: function(type, callback) {
+            sock.onmessage = function(e) {
+              callback(JSON.parse(e.data));
+            };
+          }
+        };
+      }
+
+      function getCategories() {
+        return $q(function(resolve, reject) {
+          if (categories.length !== 0) {
+            resolve(categories);
+            return;
+          }
+
+          getResource('http://' + server + '/registry/category/_search?pretty&from=0&size=1000')()
+          .then(function(res) {
+            if (res.hits.total === 0) {
+                categories = [];
+            }
+            else {
+              categories = res.hits.hits.reduce(function(result, hit) {
+                var cat = hit._source;
+                cat.id = hit._id;
+                return result.concat(cat);
+              }, []);
+              // add as map also
+              _.forEach(categories, function(cat) {
+                categories[cat.id] = cat;
+              });
+            }
+            resolve(categories);
+          })
+          .catch(function(err) {
+             reject(err);
+           });
+        });
+      }
+
+      function getToken(keypair) {
+        return $q(function(resolve, reject) {
+          var errorFct = function(err) {
+            reject(err);
+          };
+          var getChallenge = getResource('http://' + server + '/auth');
+          var postAuth = postResource('http://' + server + '/auth');
+
+          getChallenge() // get the challenge phrase to sign
+          .then(function(challenge) {
+            CryptoUtils.sign(challenge, keypair) // sign the challenge
+            .then(function(signature) {
+              postAuth({
+                pubkey: CryptoUtils.util.encode_base58(keypair.signPk),
+                challenge: challenge,
+                signature: signature
+              }) // get token
+              .then(function(token) {
+                resolve(token);
+              })
+              .catch(errorFct);
+            })
+            .catch(errorFct);
+          })
+          .catch(errorFct);
+        });
+      }
+
+      var addRecordRequest = postResource('http://' + server + '/registry/record');
+      var updateRecordRequest = postResource('http://' + server + '/registry/record/:id');
+
+      function sendRecord(record, keypair, postRequest, params) {
+        return $q(function(resolve, reject) {
+          var errorFct = function(err) {
+            reject(err);
+          };
+          var obj = {};
+          angular.copy(record, obj);
+          delete obj.signature;
+          delete obj.hash;
+          obj.issuer = CryptoUtils.util.encode_base58(keypair.signPk);
+          var str = JSON.stringify(obj);
+
+          CryptoUtils.util.hash(str)
+          .then(function(hash) {
+            CryptoUtils.sign(str, keypair)
+            .then(function(signature) {
+              obj.hash = hash;
+              obj.signature = signature;
+              postRequest(obj, params)
+              .then(function (id){
+                resolve(id);
+              })
+              .catch(errorFct);
+            })
+            .catch(errorFct);
+          })
+          .catch(errorFct);
+        });
+      }
+
+      function addRecord(record, keypair) {
+        return sendRecord(record, keypair, addRecordRequest);
+      }
+
+      function updateRecord(record, params, keypair) {
+        return sendRecord(record, keypair, updateRecordRequest, params);
+      }
+
+      var postAvatar = postResource('http://' + server + '/registry/record/_search');
+
+      function getAvatar(pubkey) {
+        return $q(function(resolve, reject) {
+          var errorFct = function(err) {
+            reject(err);
+          };
+          var request = {
+                query: {
+                  bool: {
+                    should: [
+                      {match_phrase: {issuer: pubkey}},
+                      {match_phrase: {category: 'particulier'}}
+                    ]
+                  }
+                },
+                from: 0,
+                size: 1,
+                _source: ["pictures.src"]
+              };
+
+          postAvatar(request)
+          .then(function(res) {
+            var imageData;
+            if (res.hits.total > 0) {
+                imageData = res.hits.hits.reduce(function(res, hit) {
+                  return res.concat(hit._source.pictures.reduce(function(res, pic) {
+                    return res.concat(pic.src);
+                  }, [])[0]);
+                }, [])[0];
+              }
+              else {
+                imageData = null;
+              }
+              resolve(imageData);
+            })
+            .catch(errorFct);
+          });
+        }
+
+      function emptyHit() {
+        return {
+           _id: null,
+           _index: null,
+           _type: null,
+           _version: null,
+           _source: {}
+        };
+      }
+
+      return {
+        auth: {
+            get: getResource('http://' + server + '/auth'),
+            post: postResource('http://' + server + '/auth'),
+            token: getToken
+        },
+        hit: {
+           empty: emptyHit
+        },
+        category: {
+          all: getCategories
+        },
+        record: {
+          get: getResource('http://' + server + '/registry/record/:id'),
+          add: addRecord,
+          update: updateRecord,
+          searchText: getResource('http://' + server + '/registry/record/_search?q=:search'),
+          search: postResource('http://' + server + '/registry/record/_search?pretty'),
+          avatar: getAvatar
+        },
+        currency: {
+          all: getResource('http://' + server + '/registry/currency/_search?_source=currencyName,peers.host,peers.port'),
+          get: getResource('http://' + server + '/registry/currency/:id/_source')
+        }
+      };
+    }
+
+    var ESNodeConfigured = !!APP_CONFIG.DUNITER_NODE_ES;
+    if (!ESNodeConfigured) {
+      return null;
+    }
+
+    var service = Registry(APP_CONFIG.DUNITER_NODE_ES);
+    service.instance = Registry;
+
+  return service;
+})
+;
diff --git a/www/plugins/es/templates/market/edit_record.html b/www/plugins/es/templates/market/edit_record.html
new file mode 100644
index 0000000000000000000000000000000000000000..0b183b3abf280858a2f6db5270fcc0ba88790b6c
--- /dev/null
+++ b/www/plugins/es/templates/market/edit_record.html
@@ -0,0 +1,121 @@
+<ion-view left-buttons="leftButtons">
+  <ion-nav-title>
+    <span translate>MARKET.EDIT.TITLE</span>
+  </ion-nav-title>
+
+  <ion-nav-buttons side="secondary">
+        <button class="button button-clear button-icon icon visible-xs visible-sm"
+                ng-class="{'ion-android-send':!id, 'ion-android-done': id}"
+                ng-click="save()">
+        </button>
+    </ion-nav-buttons>
+
+    <ion-content>
+        <div class="scroll">
+            <div class="list gallery" ng-if="pictures && pictures.length>0" >
+              <div ng-repeat="picture in pictures"
+                   class="item card card-gallery">
+                <div>
+                  <h2 ng-if="picture.title">{{picture.title}}</h2>
+                  <img ng-src="{{picture.src}}" ></img>
+                </div>
+                <div class="item tabs tabs-secondary tabs-icon-left">
+                  <a class="tab-item stable-bg assertive-900" ng-click="removePicture($index)">
+                    <i class="icon ion-close"></i>
+                    {{'COMMON.BTN_PICTURE_DELETE'|translate}}
+                  </a>
+                  <a class="tab-item stable-bg"
+                      ng-click="favoritePicture($index)"
+                      ng-class="{'dark': $index !== 0, 'positive-900': $index === 0}">
+                    <i class="icon ion-star"></i>
+                    {{'COMMON.BTN_PICTURE_FAVORISE'|translate}}
+                  </a>
+                </div>
+              </div>
+           </div>
+
+            <div class="list">
+
+                <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 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()">
+                        <i class="icon ion-plus"></i>
+                    </a-->
+                </div>
+
+                <span class="item item-icon-left" ng-if="id && formData.issuer">
+                    <i class="icon ion-key"></i>
+                    <span translate>MARKET.COMMON.ISSUER</span>
+                    <span class="badge">{{formData.issuer | formatPubkey}}</span>
+                </span>
+
+                <span class="item item-button-right" ng-click="openCategoryModal()">
+                    <span translate>MARKET.COMMON.CATEGORY</span>
+                    <span class="badge badge-royal">{{category.name}}</span>&nbsp;
+                    <i class="button button-clear ion-chevron-right"></i>
+                </span>
+
+                <div class="item item-input item-floating-label">
+                    <span class="input-label" translate>MARKET.EDIT.RECORD_TITLE</span>
+                    <input type="text" placeholder="{{'MARKET.EDIT.RECORD_TITLE_HELP'|translate}}" ng-model="formData.title"></input>
+                </div>
+
+                <div class="item item-input item-floating-label">
+                    <span class="input-label" translate>MARKET.EDIT.RECORD_DESCRIPTION</span>
+                    <textarea placeholder="{{'MARKET.EDIT.RECORD_DESCRIPTION_HELP'|translate}}"
+                              ng-model="formData.description"
+                              rows="8" cols="10"></textarea>
+                </div>
+
+                <div class="item item-input item-floating-label">
+                  <span class="input-label" translate>MARKET.EDIT.RECORD_PRICE</span>
+                      <input type="text" placeholder="{{'MARKET.EDIT.RECORD_PRICE_HELP'|translate}}"
+                                ng-model="formData.price"></input>
+                </div>
+
+                <div class="item item-floating-label" ng-if="location.enable">
+                    <span class="input-label" translate>MARKET.EDIT.RECORD_LOCATION</span>
+                    <div class="item-input-inset">
+                        <label class="item-input-wrapper">
+                            <input type="text" placeholder="{{'MARKET.EDIT.RECORD_LOCATION_HELP'|translate}}" ng-model="formData.location">
+                        </label>
+                        <button class="button button-small button-positive" ng-click="localize()" ng-if="location.enable">
+                            <i class="icon ion-pinpoint"></i>
+                        </button>
+                    </div>
+                </div>
+
+                <div class="item item-input item-floating-label" ng-if="!location.enable">
+                    <span class="input-label" translate>MARKET.EDIT.RECORD_LOCATION</span>
+                    <textarea placeholder="{{'MARKET.EDIT.RECORD_LOCATION_HELP'|translate}}" ng-model="formData.location"></textarea>
+                </div>
+
+            </div>
+
+            <div class="padding hidden-xs hidden-sm text-right">
+              <button class="button button-clear button-dark ink" ng-click="goBack()" type="button" translate>COMMON.BTN_CANCEL
+              </button>
+              <!--<button class="button button-small button-stable ink" ng-click="saveAsDirty()">-->
+                <!--{{'MARKET.EDIT.BTN_SAVE' | translate}}-->
+              <!--</button>-->
+              <button class="button button-positive button-raised ink" ng-click="save()" ng-show="!id">
+                {{'MARKET.EDIT.BTN_PUBLISH' | translate}}
+              </button>
+              <button class="button button-positive button-raised ink" ng-click="save()" ng-show="id">
+                {{'MARKET.EDIT.BTN_SAVE' | translate}}
+              </button>
+            </div>
+        </div>
+        <div class="scroll-bar scroll-bar-v"></div>
+    </ion-content>
+
+
+</ion-view>
diff --git a/www/plugins/es/templates/market/lookup.html b/www/plugins/es/templates/market/lookup.html
new file mode 100644
index 0000000000000000000000000000000000000000..217619a59151f4196b8c4bec30e19c57c5432e1b
--- /dev/null
+++ b/www/plugins/es/templates/market/lookup.html
@@ -0,0 +1,150 @@
+<ion-view left-buttons="leftButtons">
+  <ion-nav-title>
+    <span translate>MARKET.SEARCH.TITLE</span>
+  </ion-nav-title>
+
+  <ion-nav-buttons side="secondary">
+    <button class="button button-icon button-clear visible-xs"
+            ui-sref="app.market_add_record">
+      <i class="icon ion-plus"></i>
+    </button>
+  </ion-nav-buttons>
+
+  <ion-content class="lookupForm padding no-padding-xs">
+
+
+    <form ng-submit="doSearch()">
+      <label class="item item-input">
+        <i class="icon ion-search placeholder-icon"></i>
+        <input type="text" placeholder="{{'MARKET.SEARCH.SEARCH_HELP'|translate}}"
+               ng-model="search.text"
+               ng-model-options="{ debounce: 350 }"
+               ng-change="doSearch()" id="searchText">
+      </label>
+
+      <div class="item item-toggle dark" ng-if="!search.lastRecords">
+        <span translate>MARKET.SEARCH.BTN_OPTIONS</span>
+        <label class="toggle toggle-royal">
+          <input type="checkbox" ng-model="search.options">
+          <div class="track">
+            <div class="handle"></div>
+          </div>
+        </label>
+      </div>
+
+      <span class="item item-button-right" ng-click="openCategoryModal()" ng-if="search.options">
+        <span translate>MARKET.COMMON.CATEGORY</span>
+        <span class="badge badge-royal">{{search.category.name}}</span>&nbsp;
+        <i class="button button-clear ion-chevron-right"></i>
+      </span>
+
+      <span class="item item-button-right" ng-if="search.options && location.enable">
+        <span translate>MARKET.SEARCH.BTN_AROUND_ME</span>
+        <label class="toggle toggle-royal">
+          <input type="checkbox" ng-model="search.localize">
+          <div class="track">
+            <div class="handle"></div>
+          </div>
+        </label>
+      </span>
+
+      <span class="item item-button-right" ng-if="search.options && !location.enable">
+        <span translate>MARKET.SEARCH.LOCATION</span>
+        <div class="item-input-inset">
+          <label class="item-input-wrapper">
+            <input type="text" placeholder="{{'MARKET.SEARCH.LOCATION_HELP'|translate}}"
+                   ng-model="search.location"
+                   ng-model-options="{ debounce: 350 }"
+                   ng-change="doSearch()"/>
+          </label>
+        </div>
+      </span>
+    </form>
+
+    <div class="row no-padding">
+      <div class="col">
+        <h4
+          ng-if="!search.looking && search.lastRecords && search.results.length > 0" translate>
+          MARKET.SEARCH.LAST_RECORDS
+        </h4>
+        <h4
+          ng-if="!search.looking && !search.lastRecords && search.results.length > 0" translate>
+          MARKET.SEARCH.RESULTS
+        </h4>
+      </div>
+
+      <div class="col col-25 hidden-xs hidden-sm padding" style="text-align:right">
+        <button class="button button-raised button-full button-calm ink"
+                ui-sref="app.market_add_record">
+          {{'MARKET.COMMON.BTN_NEW_AD' | translate}}
+        </button>
+      </div>
+    </div>
+
+    <label class="center" ng-if="search.looking">
+      <ion-spinner icon="android"></ion-spinner>
+    </label>
+
+    <label class="center assertive animate-fade-slide-in-right" ng-if="!search.looking && search.results.length===0 && search.options != null" translate>
+      COMMON.SEARCH_NO_RESULT
+    </label>
+
+    <div class="list animate-fade-slide-in-right"
+         ng-if="!search.looking && search.results && search.results.length > 0">
+
+      <a ng-repeat="rec in search.results"
+         class="item item-record ink padding-xs"
+         ui-sref="app.market_view_record({id: rec.id, title: rec.title})"
+         >
+
+        <div class="visible-xs item-text-wrap" ng-class="{'item-thumbnail-left': rec.thumbnail}">
+          <img ng-src="{{::rec.thumbnail.src}}" ng-if="rec.thumbnail"></img>
+          <h2 ng-bind-html="rec.title"></h2>
+          <h4 class="gray">
+            <span ng-if="rec.location">
+              <i class="icon ion-location"></i>
+              <span ng-bind-html="rec.location"></span>
+            </span>
+            <span ng-show="rec.time">
+              <span ng-show="rec.location">|</span>
+              {{::rec.time | formatFromNow}}
+            </span>
+          </h4>
+        </div>
+        <!--<div class="visible-xs item-text-wrap">
+          <p ng-bind-html="rec.description"></p>
+        </div>-->
+
+        <div class="row row-record hidden-xs">
+          <div class="col item-text-wrap item-thumbnail-left-padding"
+               ng-class="{'item-thumbnail-left': rec.thumbnail}">
+            <img ng-src="{{::rec.thumbnail.src}}" ng-if="rec.thumbnail">
+            <h2 ng-bind-html="rec.title"></h2>
+            <h4 class="gray">
+              <i class="icon ion-location" ng-if="rec.location"></i>
+              <span ng-bind-html="rec.location"></span>
+            </h4>
+            <h4 class="gray" ng-if="rec.time">
+              <i class="icon ion-clock" ></i>
+              {{::rec.time | formatFromNow}}
+            </h4>
+            <span  ng-if="rec.picturesCount > 0"
+                   class="badge badge-balanced badge-picture-count">{{::rec.picturesCount}}&nbsp;<i class="icon ion-camera"></i></span>
+          </div>
+          <div class="col col-20">
+            <h3 class="gray" ng-if="rec.category">{{::rec.category.name|formatCategory}}</h3>
+            <h2 class="badge badge-price badge-calm" ng-bind-html="rec.price" ng-if="rec.price"></h2>
+          </div>
+          <div class="col">
+              <h3 class="gray text-wrap" ng-bind-html="rec.description" ng-if="rec.description"></h3>
+          </div>
+        </div>
+      </a>
+
+    </div>
+  </ion-content>
+
+  <button class="button button-fab button-fab-bottom-right button-assertive icon ion-plus hidden-md hidden-lg"
+          ui-sref="app.market_add_record">
+  </button>
+</ion-view>
diff --git a/www/plugins/es/templates/market/modal_category.html b/www/plugins/es/templates/market/modal_category.html
new file mode 100644
index 0000000000000000000000000000000000000000..c29b34d43dc1907d5f090cea4017dae5f07b5bba
--- /dev/null
+++ b/www/plugins/es/templates/market/modal_category.html
@@ -0,0 +1,25 @@
+<ion-modal-view>
+  <ion-header-bar class="bar-positive">
+      <button class="button button-clear" ng-click="closeCategoryModal()" translate>COMMON.BTN_CANCEL</button>
+      <h1 class="title" translate>MARKET.COMMON.CATEGORIES</h1>
+  </ion-header-bar>
+
+    <ion-content class="lookupForm">
+    	<div class="list">
+        <label class="item item-input">
+            <i class="icon ion-search placeholder-icon"></i>
+            <input type="text" placeholder="Search" ng-model="categories.search.text" ng-change="searchCategoryChanged()">
+        </label>
+
+        <label class="item center" ng-if="modal.categories.search.looking">
+            <ion-spinner icon="android"></ion-spinner>
+        </label>
+
+        <a class="item" ng-repeat="found in categories.search.results"
+           ng-class="{'item-divider': !found.parent, 'positive': !found.parent}"
+           ng-click="selectCategory(found)">
+            <h2 ng-bind-html="found.name"></h2>
+        </a>
+    </div>
+</ion-content>
+</ion-modal-view>
diff --git a/www/plugins/es/templates/market/view_record.html b/www/plugins/es/templates/market/view_record.html
new file mode 100644
index 0000000000000000000000000000000000000000..053923033f7aef89920fee9ddc957f2827fdd8df
--- /dev/null
+++ b/www/plugins/es/templates/market/view_record.html
@@ -0,0 +1,89 @@
+<ion-view left-buttons="leftButtons">
+  <ion-nav-title>
+    <span translate>MARKET.VIEW.TITLE</span>
+  </ion-nav-title>
+
+  <ion-nav-buttons side="secondary">
+      <button class="button button-positive button-clear button-icon ion-android-create" ng-click="edit()" ng-if="canEdit">
+      </button>
+  </ion-nav-buttons>
+
+  <ion-content class="viewRecord item-text-wrap">
+
+      <div class="scroll">
+        <div class="row no-padding">
+          <div class="col-20 visible-lg">
+          </div>
+          <div class="col-10 visible-md">
+          </div>
+
+          <div class="col no-padding">
+            <div class="list">
+
+              <div class="item" ng-class="{'item-thumbnail-left': pictures && pictures.length>0}">
+                  <img ng-src="{{pictures[0].src}}" nf-if="pictures && pictures.length>0">
+                  <h2 ng-bind-html="formData.title"></h2>
+                  <h4 class="gray">
+                      <i class="icon ion-location" ng-show="formData.location"></i>
+                      <span ng-bind-html="formData.location"></span>
+                      <span ng-shwo="formData.location && formData.time">&nbsp;&nbsp;</span>
+                      <i class="icon ion-calendar" ng-show="formData.time"></i>
+                      {{formData.time|formatDate}}
+                  </h4>
+              </div>
+
+              <div class="item" style="margin-top:10px">
+                  <p ng-bind-html="formData.description"></p>
+              </div>
+
+              <span class="item item-icon-left item-button-right" >
+                  <i class="icon ion-pricetag" ng-show="formData.price"></i>
+                  <span class="dark">{{formData.price}}</span>
+                  <button class="button button-raised button-calm ink-dark"
+                          ng-click="transfer(formData.issuer, null, formData.price)">
+                    {{'MARKET.COMMON.BTN_BUY' | translate}}
+                  </button>
+              </span>
+
+              <div class="hidden-xs hidden-sm padding">
+
+              </div>
+
+              <div class="item-divider visible-xs visible-sm">&nbsp;</div>
+
+              <a class="item item-icon-left ink" ui-sref="app.view_identity({pub:formData.issuer})">
+                  <i class="icon ion-person"></i>
+                  <span translate>MARKET.COMMON.ISSUER</span>
+                  <span class="badge" ng-class="{'badge-positive': isMember, 'badge-assertive': !isMember}">{{formData.issuer | formatPubkey}}</span>
+              </a>
+
+              <div class="item item-icon-left">
+                <i class="icon ion-flag"></i>
+                  <span translate>MARKET.COMMON.CATEGORY</span>
+                  <span class="badge badge-positive">{{category.name}}</span>
+              </div>
+            </div>
+
+            <div class="list gallery" ng-if="pictures && pictures.length>0" >
+              <div ng-repeat="picture in pictures"
+                   class="item card card-gallery">
+                <div class="ink">
+                  <h2 ng-if="picture.title">{{::picture.title}}</h2>
+                  <img ng-src="{{::picture.src}}" ></img>
+                </div>
+              </div>
+            </div>
+          </div>
+
+          <div class="col-20 visible-lg">
+          </div>
+          <div class="col-10 visible-md">
+          </div>
+        </div>
+      </div>
+
+
+      <div class="scroll-bar scroll-bar-v"></div>
+    </div>
+  </ion-content>
+</ion-view>
diff --git a/www/plugins/es/templates/registry/edit_record.html b/www/plugins/es/templates/registry/edit_record.html
new file mode 100644
index 0000000000000000000000000000000000000000..575c8c8dafa0e8b49dc26c341f8aa2ef61a98b2b
--- /dev/null
+++ b/www/plugins/es/templates/registry/edit_record.html
@@ -0,0 +1,30 @@
+<ion-view left-buttons="leftButtons">
+  <ion-nav-title>
+    <span translate>REGISTRY.EDIT.TITLE</span>
+  </ion-nav-title>
+
+  <ion-nav-buttons side="secondary">
+      <button class="button button-icon button-clear" ng-click="save()">
+          <i class="icon ion-android-send" ng-if="!id"></i>
+          <i class="icon ion-android-done" ng-if="id"></i>
+      </button>
+  </ion-nav-buttons>
+
+  <ion-content>
+      <div class="scroll">
+          <ng-include src="'plugins/es/templates/registry/record_form.html'"></ng-include>
+          <div class="scroll-bar scroll-bar-v"></div>
+      </div>
+
+      <div class="padding hidden-xs hidden-sm text-right">
+        <button class="button button-clear button-dark ink" ng-click="goBack()" type="button" translate>COMMON.BTN_CANCEL
+        </button>
+        <button class="button button-positive button-raised ink" ng-click="save()" ng-show="!id">
+          {{'REGISTRY.EDIT.BTN_PUBLISH' | translate}}
+        </button>
+        <button class="button button-positive button-raised ink" ng-click="save()" ng-show="id">
+          {{'REGISTRY.EDIT.BTN_SAVE' | translate}}
+        </button>
+      </div>
+  </ion-content>
+</ion-view>
diff --git a/www/plugins/es/templates/registry/lookup.html b/www/plugins/es/templates/registry/lookup.html
new file mode 100644
index 0000000000000000000000000000000000000000..851c0cb060a5d9e2924d9fdba5cd08bdd3701dd5
--- /dev/null
+++ b/www/plugins/es/templates/registry/lookup.html
@@ -0,0 +1,99 @@
+<ion-view view-title="{{'REGISTRY.SEARCH.TITLE'|translate}}" left-buttons="leftButtons">
+    <ion-nav-buttons side="secondary">
+        <!--<button class="button button-positive button-icon button-clear visible-xs"
+                ng-click="newRecord()">
+          <i class="icon ion-plus"></i>
+        </button>-->
+    </ion-nav-buttons>
+
+    <ion-content class="lookupForm padding no-padding-xs">
+
+      <form ng-submit="doSearch()"/>
+        <label class="item item-input">
+            <i class="icon ion-search placeholder-icon"></i>
+            <input type="text" placeholder="{{'REGISTRY.SEARCH.SEARCH_HELP'|translate}}"
+                   ng-model="search.text"
+                   ng-model-options="{ debounce: 350 }"
+                   ng-change="doSearch()"
+                   id="searchText">
+        </label>
+
+        <div class="item item-toggle dark" ng-if="!search.lastRecords">
+            <span translate>REGISTRY.SEARCH.BTN_OPTIONS</span>
+            <label class="toggle toggle-royal">
+                <input type="checkbox" ng-model="search.options">
+                <div class="track">
+                    <div class="handle"></div>
+                </div>
+            </label>
+        </div>
+
+        <span class="item item-button-right" ng-click="openCategoryModal()" ng-if="search.options">
+            <span translate>REGISTRY.COMMON.CATEGORY</span>
+            <span class="badge badge-royal">{{search.category.name}}</span>&nbsp;
+            <i class="button button-clear ion-chevron-right"></i>
+        </span>
+
+        <span class="item item-button-right" ng-if="search.options && !location.enable">
+            <span translate>REGISTRY.SEARCH.LOCATION</span>
+            <div class="item-input-inset">
+                <label class="item-input-wrapper">
+                    <input type="text" placeholder="{{'REGISTRY.SEARCH.LOCATION_HELP'|translate}}"
+                           ng-model="search.location"
+                           ng-model-options="{ debounce: 350 }"
+                           ng-change="doSearch()"/>
+                </label>
+            </div>
+        </span>
+
+      </form>
+
+      <div class="row no-padding">
+        <div class="col">
+          <h4
+            ng-if="!search.looking && search.lastRecords && search.results.length > 0" translate>
+            REGISTRY.SEARCH.LAST_RECORDS
+          </h4>
+          <h4
+            ng-if="!search.looking && !search.lastRecords && search.results.length > 0" translate>
+            REGISTRY.SEARCH.RESULTS
+          </h4>
+        </div>
+
+        <div class="col col-25 hidden-xs hidden-sm" style="text-align:right">
+          <button class="button button-full button-raised button-calm ink"
+                  ng-click="newRecord()">
+            {{'REGISTRY.COMMON.BTN_NEW' | translate}}
+          </button>
+        </div>
+      </div>
+
+      <label class="center" ng-if="search.looking">
+        <ion-spinner icon="android"></ion-spinner>
+      </label>
+
+      <label class="center assertive animate-fade-slide-in-right" ng-if="!search.looking && search.results.length===0 && search.options != null" translate>
+        COMMON.SEARCH_NO_RESULT
+      </label>
+
+      <div class="list animate-fade-slide-in-right"
+           ng-if="!search.looking && search.results && search.results.length > 0">
+
+          <a  ng-repeat="found in search.results"
+              class="item item-avatar ink"
+              ui-sref="app.registry_view_record({id: found.id, title: found.title})">
+
+              <img ng-src="{{::found.pictures[0].src}}" ng-if="found.pictures && found.pictures.length > 0">
+              <h2 class="item-text-wrap" ng-bind-html="found.title"></h2>
+              <h4 class="gray" ng-if="found.location">{{::found.location}}</h4>
+              <p class="gray item-text-wrap" ng-bind-html="found.description" ng-if="found.description"></p>
+              <span class="badge" ng-if="found.category && found.category.id=='particulier'">{{::found.issuer | formatPubkey}}</span>
+          </a>
+
+      </div>
+    </ion-content>
+
+    <button class="button button-fab button-fab-bottom-right button-assertive icon ion-plus hidden-md hidden-lg"
+            ng-click="newRecord()">
+    </button>
+</ion-view>
diff --git a/www/plugins/es/templates/registry/modal_category.html b/www/plugins/es/templates/registry/modal_category.html
new file mode 100644
index 0000000000000000000000000000000000000000..e332b5757cea627e40d71d3322c733caf32c560a
--- /dev/null
+++ b/www/plugins/es/templates/registry/modal_category.html
@@ -0,0 +1,25 @@
+<ion-modal-view>
+  <ion-header-bar class="bar-positive">
+      <button class="button button-clear" ng-click="closeCategoryModal()" translate>COMMON.BTN_CANCEL</button>
+      <h1 class="title" translate>REGISTRY.COMMON.CATEGORIES</h1>
+  </ion-header-bar>
+
+    <ion-content class="lookupForm">
+    	<div class="list">
+        <label class="item item-input">
+            <i class="icon ion-search placeholder-icon"></i>
+            <input type="text" placeholder="Search" ng-model="categories.search.text" ng-change="searchCategoryChanged()">
+        </label>
+
+        <label class="item center" ng-if="categories.search.looking">
+            <ion-spinner icon="android"></ion-spinner>
+        </label>
+
+        <a ng-repeat="found in categories.search.results"
+           ng-class="{'item-divider': !found.parent, 'item': !!found.parent}"
+           ng-click="selectCategory(found)">
+            <h2 ng-bind-html="found.name" class="item-category"></h2>
+        </a>
+    </div>
+</ion-content>
+</ion-modal-view>
diff --git a/www/plugins/es/templates/registry/new_record_wizard.html b/www/plugins/es/templates/registry/new_record_wizard.html
new file mode 100644
index 0000000000000000000000000000000000000000..f03d3124efbd8ebb9bbd468641e94a06553d76f6
--- /dev/null
+++ b/www/plugins/es/templates/registry/new_record_wizard.html
@@ -0,0 +1,42 @@
+<ion-modal-view class="modal slide-in-up ng-enter active ng-enter-active">
+
+    <ion-header-bar class="bar-positive">
+
+        <button class="button back-button button-clear buttons header-item" ng-click="slidePrev()" ng-show="slides.slider.activeIndex > 0">
+          <i class="icon ion-ios-arrow-back"></i>
+          <span translate>COMMON.BTN_BACK</span>
+        </button>
+        <button class="button button-clear" ng-click="cancel()" ng-show="slides.slider.activeIndex == 0" translate>COMMON.BTN_CANCEL</button>
+
+        <h1 class="title" translate>REGISTRY.NEW.TITLE</h1>
+
+        <button class="button button-clear button-icon ion-android-send" ng-click="doNewRecord()" ng-show="slides.slider.activeIndex == 1"></button>
+
+        </ion-nav-buttons>
+    </ion-header-bar>
+    <ion-slides options="slides.options" slider="slides.slider">
+        <ion-slide-page>
+          <ion-content class="has-header padding">
+            <h3 translate>REGISTRY.NEW.SELECT_TYPE</h3>
+            <button class="button button-block button-stable icon icon-left ion-person" ng-click="setIsCompany(false)" ng-class="{ selected: !isCompany && isCompany != null }" translate>REGISTRY.NEW.TYPE_PARTICULAR</button>
+            <button class="button button-block button-stable icon icon-left ion-android-cart" ng-click="setIsCompany(true)" ng-class="{ selected: isCompany && isCompany != null }" translate>REGISTRY.NEW.TYPE_COMPANY</button>
+          </ion-content>
+        </ion-slide-page>
+        <ion-slide-page>
+          <ion-content class="has-header">
+            <ng-include src="'plugins/es/templates/registry/record_form.html'"></ng-include>
+          </ion-content>
+        </ion-slide-page>
+    </ion-slides>
+</ion-modal-view>
+
+<script type="text/ng-template" id="error-messages">
+    <div class="error" ng-message="required">
+        <i class="ion-information-circled"></i>
+        <div translate="ERROR.FIELD_REQUIRED"></div>
+    </div>
+    <div class="error" ng-message="minlength">
+        <i class="ion-information-circled"></i>
+        <div translate="ERROR.FIELD_TOO_SHORT"></div>
+    </div>
+</script>
diff --git a/www/plugins/es/templates/registry/record_form.html b/www/plugins/es/templates/registry/record_form.html
new file mode 100644
index 0000000000000000000000000000000000000000..5fcdb48d31ad440d630c5372d45dde6e952db745
--- /dev/null
+++ b/www/plugins/es/templates/registry/record_form.html
@@ -0,0 +1,91 @@
+<form name="recordForm" novalidate="" ng-submit="doNewRecord()">
+  <div class="list"
+       ng-init="setRecordForm(recordForm)">
+
+        <div class="list gallery" ng-if="pictures && pictures.length>0" >
+          <div ng-repeat="picture in pictures"
+               class="item card card-gallery">
+            <div>
+              <h2 ng-if="picture.title">{{picture.title}}</h2>
+              <img ng-src="{{picture.src}}" ></img>
+            </div>
+            <div class="item tabs tabs-secondary tabs-icon-left">
+              <a class="tab-item stable-bg assertive-900" ng-click="removePicture($index)">
+                <i class="icon ion-close"></i>
+                {{'COMMON.BTN_PICTURE_DELETE'|translate}}
+              </a>
+              <a class="tab-item stable-bg"
+                 ng-click="favoritePicture($index)"
+                 ng-class="{'dark': $index !== 0, 'positive-900': $index === 0}">
+                <i class="icon ion-star"></i>
+                {{'COMMON.BTN_PICTURE_FAVORISE'|translate}}
+              </a>
+            </div>
+          </div>
+        </div>
+
+        <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 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()">
+              <i class="icon ion-plus"></i>
+          </a-->
+        </div>
+
+        <span class="item item-button-right ink" ng-click="openCategoryModal()" ng-show="isCompany">
+            <span translate>REGISTRY.COMMON.CATEGORY</span>
+            <span class="badge badge-royal">{{category.name | formatCategory}}</span>&nbsp;
+            <i class="button button-clear ion-chevron-right"></i>
+        </span>
+
+        <div class="item item-input item-floating-label">
+          <span class="input-label" translate>REGISTRY.EDIT.RECORD_TITLE</span>
+          <input type="text" placeholder="{{'REGISTRY.EDIT.RECORD_TITLE_HELP'|translate}}" ng-model="recordData.title" />
+        </div>
+
+        <div class="item item-input item-floating-label">
+          <span class="input-label" translate>REGISTRY.EDIT.RECORD_DESCRIPTION</span>
+          <textarea placeholder="{{'REGISTRY.EDIT.RECORD_DESCRIPTION_HELP'|translate}}"
+                    ng-model="recordData.description"
+                    rows="8" cols="10">
+          </textarea>
+        </div>
+
+        <div class="item item-floating-label" ng-if="location.enable">
+          <span class="input-label" translate>REGISTRY.EDIT.RECORD_LOCATION</span>
+          <div class="item-input-inset">
+            <label class="item-input-wrapper">
+              <input type="text" placeholder="{{'REGISTRY.EDIT.RECORD_LOCATION_HELP'|translate}}" ng-model="recordData.location">
+            </label>
+            <button class="button button-small button-positive" ng-click="localize()" ng-if="location.enable">
+              <i class="icon ion-pinpoint"></i>
+            </button>
+          </div>
+        </div>
+
+        <div class="item item-input item-floating-label" ng-if="!location.enable">
+          <span class="input-label" translate>REGISTRY.EDIT.RECORD_LOCATION</span>
+          <textarea placeholder="{{'REGISTRY.EDIT.RECORD_LOCATION_HELP'|translate}}" ng-model="recordData.location"></textarea>
+        </div>
+
+        <a class="item item-icon-left" ng-if="id && recordData.issuer && !isCompany">
+            <i class="icon ion-key"></i>
+            <span translate>REGISTRY.EDIT.RECORD_PUBKEY</span>
+            <h4 class="gray">{{recordData.issuer}}</h4>
+        </a>
+
+        <a class="item item-icon-left" ng-if="id && recordData.issuer && isCompany" >
+            <i class="icon ion-key"></i>
+            <span translate>REGISTRY.COMMON.ISSUER</span>
+            <h4>{{recordData.issuer | formatPubkey}}</h4>
+        </a>
+
+  </div>
+</form>
diff --git a/www/plugins/es/templates/registry/view_record.html b/www/plugins/es/templates/registry/view_record.html
new file mode 100644
index 0000000000000000000000000000000000000000..9956a87d4a6c1ec8ff4a3888cdcf27ce2dee965b
--- /dev/null
+++ b/www/plugins/es/templates/registry/view_record.html
@@ -0,0 +1,87 @@
+<ion-view left-buttons="leftButtons">
+  <ion-nav-title>
+    <span translate>REGISTRY.VIEW.TITLE</span>
+  </ion-nav-title>
+
+  <ion-nav-buttons side="secondary">
+      <button class="button button-icon button-clear ion-android-create" ng-click="edit()" ng-if="canEdit">
+      </button>
+  </ion-nav-buttons>
+
+  <ion-content class="item-text-wrap">
+
+      <div class="scroll">
+
+        <div class="positive-900-bg hero">
+          <div class="content">
+            <div class="avatar"
+                 ng-if="pictures && pictures.length > 0"
+                 style="background-image: url({{pictures[0].src}});"></div>
+            <i class="avatar avatar-member" ng-if="!pictures || pictures.length === 0"></i>
+            <h3 class="light">{{formData.title}}</h3>
+            <h4 class="gray">
+              <i class="icon ion-location" ng-show="formData.location"></i>
+              <span ng-bind-html="formData.location"></span>
+              <span ng-shwo="formData.location && formData.time">&nbsp;&nbsp;</span>
+              <i class="icon ion-calendar" ng-show="formData.time"></i>
+              {{formData.time|formatDate}}
+            </h4>
+          </div>
+        </div>
+
+        <div class="hidden-xs hidden-sm padding" style="text-align:center">
+          <button class="button button-raised button-assertive ink-dark"
+                  ng-click="transfer(formData.issuer, formData.title)">
+            {{'ACCOUNT.BTN_SEND_MONEY' | translate}}
+          </button>
+
+          <button class="button button-raised button-icon icon ion-ribbon-b" ng-click="certifyIdentity()" ng-if="hasSelf">
+            {{'WOT.BTN_CERTIFY' | translate}}
+          </button>
+        </div>
+
+        <div class="list">
+
+            <span class="item item-icon-left ink"
+                  ng-if="!isCompany"
+                  copy-on-click>
+                <i class="icon ion-key"></i>
+                <p class="gray">{{formData.issuer}}</p>
+            </span>
+
+            <div class="item">
+                <p ng-bind-html="formData.description"></p>
+            </div>
+
+            <div ng-if="isCompany">
+                <div class="item-divider"></div>
+
+                <div class="item">
+                    <span translate>REGISTRY.COMMON.CATEGORY</span>
+                    <span class="badge badge-positive">{{category.name || formatCategory}}</span>
+                </div>
+
+                <span class="item item-icon-left" >
+                    <i class="icon ion-person"></i>
+                    <h3><span translate>REGISTRY.COMMON.ISSUER</span></h3>
+                    <span class="badge" ng-class="{'badge-positive': isMember, 'badge-assertive': !isMember}">{{formData.issuer | formatPubkey}}</span>
+                </span>
+
+            </div>
+
+        </div>
+        <div class="scroll-bar scroll-bar-v"></div>
+      </div>
+  </ion-content>
+
+  <button class="button button-fab button-fab-bottom-right button-assertive icon ion-android-send visible-xs visible-sm"
+          ng-click="transfer(formData.issuer, formData.title)">
+  </button>
+
+  <button class="button button-fab button-fab-bottom-right button-assertive icon ion-ribbon-b visible-xs visible-sm"
+          ng-click="certifyIdentity()"
+          ng-if="hasSelf"
+          style="bottom:78px;">
+  </button>
+
+</ion-view>