diff --git a/bower.json b/bower.json
index 3dd6aebb391f62a08b0075308e0014124d2539f8..e8dd3c8e2755350cdfd2c7b2e9ad302dbb757668 100644
--- a/bower.json
+++ b/bower.json
@@ -2,7 +2,7 @@
   "name": "cesium",
   "private": "true",
   "devDependencies": {
-    "ionic": "driftyco/ionic-bower#1.3.2",
+    "ionic": "driftyco/ionic-bower#1.3.1",
     "ionic-material": "0.4.2"
   },
   "dependencies": {
@@ -27,6 +27,6 @@
     "angular-sanitize": "1.5.3",
     "angular-animate": "1.5.3",
     "angular": "1.5.3",
-    "ionic": "1.3.2"
+    "ionic": "1.3.1"
   }
 }
diff --git a/www/index.html b/www/index.html
index 451caedeff0a2d9e9f7b7af0760c8606bb2689a7..99346e3fab42e67488d968c51001380ab4c4d939 100644
--- a/www/index.html
+++ b/www/index.html
@@ -11,6 +11,7 @@
   <!-- build:css dist_css/cesium.css -->
   <link rel="stylesheet" type="text/css" href="css/ionic.app.min.css">
   <link rel="stylesheet" type="text/css" href="css/style.css">
+  <link rel="stylesheet" type="text/css" href="css/angular-image-crop.css">
   <!--removeIf(device)-->
   <link rel="stylesheet" type="text/css" href="css/style-no-device.css">
   <!--endRemoveIf(device)-->
diff --git a/www/js/app.js b/www/js/app.js
index c4ee9698cd4956458592d4dfb1aa9b58d4b4c567..bfb9c484e036898af47ab1bd1374cb7a84a7bffe 100644
--- a/www/js/app.js
+++ b/www/js/app.js
@@ -104,8 +104,8 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht
   })
 
 
-.run(function($rootScope, $translate, $state, $window, $urlRouter, ionicReady, localStorage,
-              filterTranslations, Device, BMA, UIUtils, csHttp, $ionicConfig, PluginService, csPlatform, csWallet, csSettings, csConfig, csCurrency) {
+.run(function($rootScope, $translate, $state, $window, $urlRouter, ionicReady,
+              Device, UIUtils, $ionicConfig, PluginService, csPlatform, csWallet, csSettings, csConfig, csCurrency) {
   'ngInject';
 
   // Allow access to service data, from HTML templates
@@ -224,14 +224,20 @@ angular.module('cesium', ['ionic', 'ionic-material', 'ngMessages', 'pascalprecht
   // endRemoveIf(android)
 
   // Prevent $urlRouter's default handler from firing (don't sync ui router)
-  $rootScope.$on('$locationChangeSuccess', function(e, newUrl, oldUrl) {
+  $rootScope.$on('$locationChangeSuccess', function(event, newUrl, oldUrl) {
     if ($state.current.data && $state.current.data.silentLocationChange === true) {
-      console.debug('[app] Skipping state sync (silent location change)');
-      e.preventDefault();
-    }
-    else {
-      $urlRouter.sync();
+      var oldPath = oldUrl.split('?')[0];
+      var newPath = newUrl.split('?')[0];
+      if (newPath === oldPath) {
+        console.debug('[app] Skipping state sync (silent location change)');
+
+        event.preventDefault();
+        return;
+      }
     }
+
+    // default action, propagate to ui-router
+    //$urlRouter.sync();
   });
   // Configures $urlRouter's listener *after* the previous listener
   $urlRouter.listen();
diff --git a/www/js/services/crypto-services.js b/www/js/services/crypto-services.js
index a85cd15e06040c60b9bbd1831920ef1954e55fad..5fcfb9c63472484aa6dbb175c18e640152b0b94a 100644
--- a/www/js/services/crypto-services.js
+++ b/www/js/services/crypto-services.js
@@ -802,7 +802,7 @@ angular.module('cesium.crypto.services', ['cesium.utils.services'])
     isDevice = false;
     // endRemoveIf(device)
 
-    console.debug("[crypto] Created CryptotUtils service. device=" + isDevice);
+    //console.debug("[crypto] Created CryptotUtils service. device=" + isDevice);
 
     ionicReady().then(function() {
       console.debug('[crypto] Starting...');
diff --git a/www/plugins/es/i18n/locale-fr-FR.json b/www/plugins/es/i18n/locale-fr-FR.json
index 0181266c1329187bf18cfd2265344fe9e03301af..1cae69a3fc901717cbba8b3031dfda486a7c36f0 100644
--- a/www/plugins/es/i18n/locale-fr-FR.json
+++ b/www/plugins/es/i18n/locale-fr-FR.json
@@ -502,12 +502,6 @@
     "TX_RECEIVED_MULTI": "Vous avez <b>reçu un paiement</b> de <b>{{params[1]}}</b>.",
     "CERT_SENT": "Votre <b>certification</b> à <span ng-class=\"{'gray': !notification.uid, 'positive':notification.uid}\" ><i class=\"icon\" ng-class=\"{'ion-person': notification.uid, 'ion-key': !notification.uid}\"></i>&thinsp;{{name||uid||params[1]}}</span> a été effectuée.",
     "CERT_RECEIVED": "Vous avez <b>reçu une certification</b> de <span ng-class=\"{'gray': !notification.uid, 'positive':notification.uid}\"><i class=\"icon\" ng-class=\"{'ion-person': notification.uid, 'ion-key': !notification.uid}\"></i>&thinsp;{{name||uid||params[1]}}</span>.",
-    "MARKET": {
-      "NEW_COMMENT": "<span ng-class=\"{'gray': !notification.uid, 'positive':notification.uid }\"><i class=\"icon\" ng-class=\"{'ion-person': notification.uid, 'ion-key': !notification.uid}\"></i>&thinsp;{{name||uid||params[1]}}</span> a commenté votre annonce : <b>{{params[2]}}</b>",
-      "UPDATE_COMMENT": "<span ng-class=\"{'gray': !notification.uid, 'positive':notification.uid }\"><i class=\"icon\" ng-class=\"{'ion-person': notification.uid, 'ion-key': !notification.uid}\"></i>&thinsp;{{name||uid||params[1]}}</span> a modifié son commentaire sur votre annonce : <b>{{params[2]}}</b>",
-      "NEW_REPLY_COMMENT": "<span ng-class=\"{'gray': !notification.uid, 'positive':notification.uid }\"><i class=\"icon\" ng-class=\"{'ion-person': notification.uid, 'ion-key': !notification.uid}\"></i>&thinsp;{{name||uid||params[1]}}</span> a répondu votre commentaire sur l'annonce : <b>{{params[2]}}</b>",
-      "UPDATE_REPLY_COMMENT": "<span ng-class=\"{'gray': !notification.uid, 'positive':notification.uid }\"><i class=\"icon\" ng-class=\"{'ion-person': notification.uid, 'ion-key': !notification.uid}\"></i>&thinsp;{{name||uid||params[1]}}</span> a modifié la réponse à votre commentaire, sur l'annonce : <b>{{params[2]}}</b>"
-    },
     "REGISTRY": {
       "NEW_COMMENT": "<span ng-class=\"{'gray': !notification.uid, 'positive':notification.uid}\"><i class=\"icon\" ng-class=\"{'ion-person': notification.uid, 'ion-key': !notification.uid}\"></i>&thinsp;{{name||uid||params[1]}}</span> a commenté votre référencement : <b>{{params[2]}}</b>",
       "UPDATE_COMMENT": "<span ng-class=\"{'gray': !notification.uid, 'positive':notification.uid }\"><i class=\"icon\" ng-class=\"{'ion-person': notification.uid, 'ion-key': !notification.uid}\"></i>&thinsp;{{name||uid||params[1]}}</span> a modifié son commentaire sur votre référencement : <b>{{params[2]}}</b>",
diff --git a/www/plugins/es/js/services/http-services.js b/www/plugins/es/js/services/http-services.js
index 9756b492d65538f95b3d8113fcdb2f72bcf41e51..7f7569bdd0dd73d454d4f147dfabbf9ea93c1698 100644
--- a/www/plugins/es/js/services/http-services.js
+++ b/www/plugins/es/js/services/http-services.js
@@ -15,7 +15,7 @@ angular.module('cesium.es.http.services', ['ngResource', 'ngApi', 'cesium.servic
       },
       regexp = {
         IMAGE_SRC: exact('data:([A-Za-z//]+);base64,(.+)'),
-        HASH_TAG: match('#([\\wḡĞğàáâãäåçèéêëìíîïðòóôõöùúûüýÿ]+)'),
+        HASH_TAG: match('#([\\wḡĞǦğàáâãäåçèéêëìíîïðòóôõöùúûüýÿ]+)'),
         USER_TAG: match('@('+BMA.constants.regexp.USER_ID+')'),
         ES_USER_API_ENDPOINT: exact(constants.ES_USER_API_ENDPOINT)
       };
diff --git a/www/plugins/map/js/controllers/wot-controllers.js b/www/plugins/map/js/controllers/wot-controllers.js
index 89c69ba62f73536039958fb00db7f7e9127a1a44..65e415ab663c304907bc705bed08f0ab58db3651 100644
--- a/www/plugins/map/js/controllers/wot-controllers.js
+++ b/www/plugins/map/js/controllers/wot-controllers.js
@@ -92,8 +92,9 @@ angular.module('cesium.map.wot.controllers', ['cesium.services', 'cesium.map.ser
           }
         }
       },
-      loading: true,
-      markers: {}
+      bounds: {},
+      markers: {},
+      loading: true
     });
 
     // [NEW] When opening the view
@@ -158,7 +159,7 @@ angular.module('cesium.map.wot.controllers', ['cesium.services', 'cesium.map.ser
       $scope.loading = true;
 
       // Load wot data
-      return mapWot.load()
+      return mapWot.load({bounds: $scope.map.bounds})
 
         .then(function(res) {
           if (res && res.length) {
@@ -192,23 +193,26 @@ angular.module('cesium.map.wot.controllers', ['cesium.services', 'cesium.map.ser
                 message: markerTemplate
               };
               var id = hit.uid ? (hit.uid + ':' + hit.pubkey) : hit.pubkey;
+              var wasExisting = !!$scope.map.markers[id];
               $scope.map.markers[id] = marker;
 
               // Create a search marker (will be hide)
-              var searchText = hit.name + ((hit.uid && hit.uid != hit.name) ? (' | ' + hit.uid) : '') + ' | ' + shortPubkey;
-              var searchMarker = angular.merge({
-                type: type,
-                opacity: 0,
-                icon: L.divIcon({
-                  className: type + ' ng-hide',
-                  iconSize: L.point(0, 0)
-                })
-              }, {title: searchText, pubkey: hit.pubkey, uid: hit.uid, name: hit.name, pending: hit.pending});
-              markersSearchLayer.addLayer(new L.Marker({
-                  lat: hit.geoPoint.lat,
-                  lng: hit.geoPoint.lon
-                },
-                searchMarker));
+              if (!wasExisting) {
+                var searchText = hit.name + ((hit.uid && hit.uid != hit.name) ? (' | ' + hit.uid) : '') + ' | ' + shortPubkey;
+                var searchMarker = angular.merge({
+                  type: type,
+                  opacity: 0,
+                  icon: L.divIcon({
+                    className: type + ' ng-hide',
+                    iconSize: L.point(0, 0)
+                  })
+                }, {title: searchText, pubkey: hit.pubkey, uid: hit.uid, name: hit.name, pending: hit.pending});
+                markersSearchLayer.addLayer(new L.Marker({
+                    lat: hit.geoPoint.lat,
+                    lng: hit.geoPoint.lon
+                  },
+                  searchMarker));
+              }
             });
           }
 
@@ -231,6 +235,8 @@ angular.module('cesium.map.wot.controllers', ['cesium.services', 'cesium.map.ser
     // Update the browser location, to be able to refresh the page
     $scope.$on("centerUrlHash", function(event, centerHash) {
       if (!$scope.loading) {
+        $scope.load();
+
         return $timeout(function() {
           $scope.updateLocationHref(centerHash);
         }, 300);
diff --git a/www/plugins/map/js/services/wot-services.js b/www/plugins/map/js/services/wot-services.js
index 1e97a6d753dcef9213fb43fd837e61568c3a2297..e38f4ba5c3f9dd38d23eb9cdedc9c060b8926251 100644
--- a/www/plugins/map/js/services/wot-services.js
+++ b/www/plugins/map/js/services/wot-services.js
@@ -10,7 +10,7 @@ angular.module('cesium.map.wot.services', ['cesium.services'])
       DEFAULT_LOAD_SIZE: 1000
     },
     fields = {
-      profile: ["title", "geoPoint", "avatar._content_type"]
+      profile: ["title", "geoPoint", "avatar._content_type", "city", "description"]
     };
 
   that.raw = {
@@ -28,6 +28,25 @@ angular.module('cesium.map.wot.services', ['cesium.services'])
       }
     };
 
+    // Filter on bounding box
+    // see https://www.elastic.co/guide/en/elasticsearch/reference/2.4/geo-point.html
+    if (options && options.bounds) {
+
+      query.bool.filter = {
+        "geo_bounding_box" : {
+          "geoPoint" : {
+            "top_left" : {
+              "lat" : Math.max(Math.min(options.bounds.northEast.lat, 90), -90),
+              "lon" : Math.max(Math.min(options.bounds.southWest.lng, 180), -180)
+            },
+            "bottom_right" : {
+              "lat" : Math.max(Math.min(options.bounds.southWest.lat, 90), -90),
+              "lon" : Math.max(Math.min(options.bounds.northEast.lng, 180), -180)
+            }
+          }
+        }
+      };
+    }
     return query;
   }
 
@@ -107,7 +126,12 @@ angular.module('cesium.map.wot.services', ['cesium.services'])
           if (item.name && item.name.length > 30) {
             item.name = item.name.substr(0, 27) + '...';
           }
-          console.log(item);
+
+          // Description
+          item.description = esHttp.util.trustAsHtml(hit._source.description);
+
+          // City
+          item.city = hit._source.city;
 
           return res.concat(item);
         }, []);
diff --git a/www/plugins/map/templates/wot/popup_marker.html b/www/plugins/map/templates/wot/popup_marker.html
index 9145a95e47b26ab907fe652d3fc97bf732bb066b..ec551fee3e1ec948a23c98f2bfa9e62755c3e852 100644
--- a/www/plugins/map/templates/wot/popup_marker.html
+++ b/www/plugins/map/templates/wot/popup_marker.html
@@ -8,12 +8,16 @@
         <b class="ion-person"></b>
         {{::hit.uid}}
       </span>
+      <span class="gray" title="{{::hit.pubkey}}"><b class="ion-key"></b> {{::hit.pubkey|formatPubkey}}</span>
       <span class="assertive" ng-if="!hit.uid">
         {{::'WOT.NOT_MEMBER_PARENTHESIS'|translate}}
       </span>
     </h4>
-    <h4>
-      <span class="gray" title="{{::hit.pubkey}}"><b class="ion-key"></b> {{::hit.pubkey|formatPubkey}}</span>
+    <h4 ng-if="::hit.city" class="gray" title="{{::hit.city}}">
+      <b class="ion-location"></b> {{::hit.city}}
     </h4>
   </div>
 </div>
+<div class="item no-border no-padding item-text-wrap" ng-if="::hit.description">
+  <small ng-bind-html="::hit.description"></small>
+</div>
diff --git a/www/plugins/map/templates/wot/view_map.html b/www/plugins/map/templates/wot/view_map.html
index 0e90bf019d296364149991ee5139de3f95fcf4d1..15fa14034d2e539e6702d48fba9320833a5f74ec 100644
--- a/www/plugins/map/templates/wot/view_map.html
+++ b/www/plugins/map/templates/wot/view_map.html
@@ -9,9 +9,10 @@
     <leaflet id="{{mapId}}"
              height="100%"
              url-hash-center="yes"
-             lf-center="map.center"
+             layers="map.layers"
              markers="map.markers"
-             layers="map.layers">
+             lf-center="map.center"
+             bounds="map.bounds">
     </leaflet>
   </ion-content>
 </ion-view>