diff --git a/sonar-project.properties b/sonar-project.properties
new file mode 100644
index 0000000000000000000000000000000000000000..7de185ab2d26b5e69b0a6f152315845410c7566e
--- /dev/null
+++ b/sonar-project.properties
@@ -0,0 +1,3 @@
+sonar.sources = src
+sonar.exclusions = build/**, node_modules/**
+#sonar.tests = api/tests/
diff --git a/src/App.vue b/src/App.vue
index 9eb34d3c845c7454120104f0ca28ccdb03bb3f7d..a303e546e081dbf70878c0c85c6c0f1c27574fff 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -22,12 +22,12 @@
               :key="'message-' + index"
               :class="['ui', message.level ? message.level : 'info', 'message']"
             >
-              <i
+              <em
                 class="close icon"
                 @click="DISCARD_MESSAGE(message)"
               />
               <div class="header">
-                <i class="info circle icon" />
+                <em class="info circle icon" />
                 Informations
               </div>
               <ul class="list">
diff --git a/src/assets/js/map-util.js b/src/assets/js/map-util.js
index 43ab500656d3111e91c06a985bb7536d3f9f1b2e..ad632c88defc4456eeaed18c12c9b4c3d210789b 100644
--- a/src/assets/js/map-util.js
+++ b/src/assets/js/map-util.js
@@ -298,7 +298,7 @@ const mapUtil = {
     return featureType.color;
   },
 
-  addVectorTileLayer: function (url, project_slug, featureTypes, form_filters) {
+  addVectorTileLayer: function (url, projectSlug, featureTypes, formFilters) {
     layerMVT = L.vectorGrid.protobuf(url, {
       noWrap:true,
       vectorTileLayerStyles: {
@@ -326,23 +326,22 @@ const mapUtil = {
             fill: true,
             color: colorValue,
           };
-            
 
           // Filtre sur le feature type
-          if (form_filters && form_filters.type.selected) {
-            if (featureType.title !== form_filters.type.selected) {
+          if (formFilters && formFilters.type.selected) {
+            if (featureType.title !== formFilters.type.selected) {
               return hiddenStyle;
             }
           }
           // Filtre sur le statut
-          if (form_filters && form_filters.status.selected.value) {
-            if (properties.status !== form_filters.status.selected.value) {
+          if (formFilters && formFilters.status.selected.value) {
+            if (properties.status !== formFilters.status.selected.value) {
               return hiddenStyle;
             }
           }
           // Filtre sur le titre
-          if (form_filters && form_filters.title) {
-            if (!properties.title.toLowerCase().includes(form_filters.title.toLowerCase())) {
+          if (formFilters && formFilters.title) {
+            if (!properties.title.toLowerCase().includes(formFilters.title.toLowerCase())) {
               return hiddenStyle;
             }
           }
@@ -358,7 +357,7 @@ const mapUtil = {
       }
     });
     layerMVT.on('click', (e) => {    // The .on method attaches an event handler
-      const popupContent = this._createContentPopup(e.layer, featureTypes, project_slug);
+      const popupContent = this._createContentPopup(e.layer, featureTypes, projectSlug);
       L.popup()
         .setContent(popupContent)
         .setLatLng(e.latlng)
@@ -368,7 +367,7 @@ const mapUtil = {
     window.layerMVT = layerMVT;
   },
 
-  addFeatures: function (features, filter, addToMap = true, featureTypes, project_slug) {
+  addFeatures: function (features, filter, addToMap = true, featureTypes, projectSlug) {
     const featureGroup = new L.FeatureGroup();
     features.forEach((feature) => {
       const featureProperties = feature.properties ? feature.properties : feature;
@@ -389,7 +388,7 @@ const mapUtil = {
         filters.length && filters.every(val => val !== false)
       ) {
         const geomJSON = flip(feature.geometry || feature.geom);
-        const popupContent = this._createContentPopup(feature, featureTypes, project_slug);
+        const popupContent = this._createContentPopup(feature, featureTypes, projectSlug);
 
         // Look for a custom field
         let customField;
@@ -425,10 +424,10 @@ const mapUtil = {
               featureType.colors_style.value.icons[customFieldOption] !== 'circle'
             ) {
               const iconHTML = `
-                <i
+                <em
                   class="fas fa-${featureType.colors_style.value.icons[customFieldOption]} fa-lg"
                   style="color: ${color}"
-                ></i>
+                ></em>
               `;
               const customMapIcon = L.divIcon({
                 html: iconHTML,
@@ -455,10 +454,10 @@ const mapUtil = {
           } else {
             if (featureType.icon && featureType.icon !== 'circle') {
               const iconHTML = `
-                <i
+                <em
                   class="fas fa-${featureType.icon} fa-lg"
                   style="color: ${color}"
-                ></i>
+                ></em>
               `;
               const customMapIcon = L.divIcon({
                 html: iconHTML,
@@ -512,39 +511,39 @@ const mapUtil = {
     map.on(eventName, callback);
   },
 
-  _createContentPopup: function (feature, featureTypes, project_slug) {
-    const formatDate = (current_datetime) => {
-      let formatted_date = current_datetime.getFullYear() + '-' + ('0' + (current_datetime.getMonth() + 1)).slice(-2) + '-' + ('0' + current_datetime.getDate()).slice(-2) + ' ' +
-        ('0' + current_datetime.getHours()).slice(-2) + ':' + ('0' + current_datetime.getMinutes()).slice(-2);
-      return formatted_date;
+  _createContentPopup: function (feature, featureTypes, projectSlug) {
+    const formatDate = (currentDatetime) => {
+      let formattedDate = currentDatetime.getFullYear() + '-' + ('0' + (currentDatetime.getMonth() + 1)).slice(-2) + '-' + ('0' + currentDatetime.getDate()).slice(-2) + ' ' +
+        ('0' + currentDatetime.getHours()).slice(-2) + ':' + ('0' + currentDatetime.getMinutes()).slice(-2);
+      return formattedDate;
     };
-    let feature_type = feature.properties ? feature.properties.feature_type : feature.feature_type;
-    let feature_url = feature.feature_url;
+    let featureType = feature.properties ? feature.properties.feature_type : feature.feature_type;
+    let featureUrl = feature.feature_url;
     let status = feature.status;
-    let feature_type_url = feature.feature_type_url;
-    let date_maj = feature.updated_on;
+    let featureTypeUrl = feature.feature_type_url;
+    let dateMaj = feature.updated_on;
     if (feature.properties) {
       status = feature.properties.status;
-      date_maj = feature.properties.updated_on ? formatDate(new Date(feature.properties.updated_on)) : '<i>indisponible</i>';
-      feature_type_url = feature.properties.feature_type_url;
-      feature_url = feature.properties.feature_url;
+      dateMaj = feature.properties.updated_on ? formatDate(new Date(feature.properties.updated_on)) : '<em>indisponible</em>';
+      featureTypeUrl = feature.properties.feature_type_url;
+      featureUrl = feature.properties.feature_url;
     }
 
     if (featureTypes && feature.properties) { // => VectorTile
-      feature_type = feature.properties.feature_type_id ?
+      featureType = feature.properties.feature_type_id ?
         featureTypes.find((x) => x.slug.split('-')[0] === '' + feature.properties.feature_type_id) :
-        featureTypes.find((f_type) => f_type.slug === feature.properties.feature_type); //* geojson
+        featureTypes.find((fType) => fType.slug === feature.properties.feature_type); //* geojson
       status = statusList.find((x) => x.value === feature.properties.status.value).name;
-      if (feature_type) feature_type_url = '/geocontrib/projet/' + project_slug + '/type-signalement/' + feature_type.slug + '/';
-      feature_url = feature_type_url + 'signalement/' + feature.properties.feature_id + '/';
+      if (featureType) featureTypeUrl = `/geocontrib/projet/${projectSlug}/type-signalement/${featureType.slug}/`;
+      featureUrl = `${featureTypeUrl}signalement/${feature.properties.feature_id}/`;
     } else {
       status = feature.properties ? feature.properties.status.label : feature.status.label;
     }
 
     //* adapt link url for shared-project restricted navigation
     if (window.location.pathname.includes('projet-partage')) {
-      feature_url = feature_url.replace('projet', 'projet-partage');
-      feature_type_url = feature_type_url.replace('projet', 'projet-partage');
+      featureUrl = featureUrl.replace('projet', 'projet-partage');
+      featureTypeUrl = featureTypeUrl.replace('projet', 'projet-partage');
     }
     let author = '';
     const creator = feature.properties ? feature.properties.creator : feature.creator;
@@ -557,28 +556,28 @@ const mapUtil = {
     }
 
     let title = feature.properties ? feature.properties.title : feature.title;
-    if (feature_url) {
-      title = `<a href="${feature_url}">${title}</a>`;
+    if (featureUrl) {
+      title = `<a href="${featureUrl}">${title}</a>`;
     } else {
-      title = `<span>${title|| '<i>indisponible</i>'}</span>`;
+      title = `<span>${title|| '<em>indisponible</em>'}</span>`;
     }
 
-    if (feature_type_url) {
-      `<a href="${feature_type_url}"> ${feature_type.title || '<i>indisponible</i>'} </a>`;
+    if (featureTypeUrl) {
+      `<a href="${featureTypeUrl}"> ${featureType.title || '<em>indisponible</em>'} </a>`;
     }
 
     return `
           <h4>
-            <${feature_url ? 'a href="' + feature_url + '"' : 'span'}>${title || '<i>indisponible</i>'}</${feature_url ? 'a' : 'span'}>
+            <${featureUrl ? `a href="${featureUrl}"` : 'span'}>${title || '<em>indisponible</em>'}</${featureUrl ? 'a' : 'span'}>
           </h4>
           <div>
-            Statut : ${status || '<i>indisponible</i>'}
+            Statut : ${status || '<em>indisponible</em>'}
           </div>
           <div>
-            Type : <${feature_type_url ? 'a href="'+ feature_type_url + '"' : 'span'}> ${feature_type.title || '<i>indisponible</i>'} </${feature_type_url ? 'a' : 'span'}>
+            Type : <${featureTypeUrl ? `a href="${featureTypeUrl}"` : 'span'}> ${featureType.title || '<em>indisponible</em>'} </${featureTypeUrl ? 'a' : 'span'}>
           </div>
           <div>
-            Dernière mise à jour : ${date_maj || '<i>indisponible</i>'}
+            Dernière mise à jour : ${dateMaj || '<em>indisponible</em>'}
           </div>
           ${author}
         `;
diff --git a/src/assets/styles/base.css b/src/assets/styles/base.css
index fbfa9584141b69afcfb3f37e44e8c7ad94887f71..38ffeaff89b4dd875a378bae03807670d17f896e 100644
--- a/src/assets/styles/base.css
+++ b/src/assets/styles/base.css
@@ -195,7 +195,6 @@ body {
   opacity: 0.9;
 }
 
-/*  */
 
 /* ---------------------------------- */
       /* LEAFLET DRAW TOOLBAR */
diff --git a/src/components/Account/UserActivity.vue b/src/components/Account/UserActivity.vue
index 1ad3a100551e9070f8a3bc2affab71af24635e79..b4cb302b11bf3b48ee211969602a69cdbefe6d2f 100644
--- a/src/components/Account/UserActivity.vue
+++ b/src/components/Account/UserActivity.vue
@@ -57,7 +57,7 @@
                   <span v-if="item.object_type === 'feature'">
                     Signalement supprimé({{ item.data.feature_title }})
                   </span>
-                  <i v-else>Événement inconnu</i>
+                  <em v-else>Événement inconnu</em>
                 </span>
                 <span
                   v-if="item.object_type !== 'project'"
@@ -69,17 +69,17 @@
                   }})
                 </span>
                 <div class="description">
-                  <i>[ {{ item.created_on }}
+                  <em>[ {{ item.created_on }}
                     <span v-if="user.is_authenticated">
                       , par {{ item.display_user }}
                     </span>
-                    ]</i>
+                    ]</em>
                 </div>
               </div>
             </div>
-            <i
+            <em
               v-if="!events || events.length === 0"
-            >Aucune notification pour le moment.</i>
+            >Aucune notification pour le moment.</em>
           </div>
         </div>
       </div>
@@ -110,17 +110,17 @@
                   ><del>{{ item.data.feature_title }}</del>&nbsp;(supprimé)</span>
                 </div>
                 <div class="description">
-                  <i>[ {{ item.created_on }}
+                  <em>[ {{ item.created_on }}
                     <span v-if="user.is_authenticated">
                       , par {{ item.display_user }}
                     </span>
-                    ]</i>
+                    ]</em>
                 </div>
               </div>
             </div>
-            <i
+            <em
               v-if="!features || features.length === 0"
-            >Aucun signalement pour le moment.</i>
+            >Aucun signalement pour le moment.</em>
           </div>
         </div>
       </div>
@@ -146,17 +146,17 @@
                   >"{{ item.related_comment.comment }}"</a>
                 </div>
                 <div class="description">
-                  <i>[ {{ item.created_on }}
+                  <em>[ {{ item.created_on }}
                     <span v-if="user.is_authenticated">
                       , par {{ item.display_user }}
                     </span>
-                    ]</i>
+                    ]</em>
                 </div>
               </div>
             </div>
-            <i
+            <em
               v-if="!comments || comments.length === 0"
-            >Aucun commentaire pour le moment.</i>
+            >Aucun commentaire pour le moment.</em>
           </div>
         </div>
       </div>
@@ -170,7 +170,7 @@ import { mapState } from 'vuex';
 import miscAPI from '@/services/misc-api';
 
 export default {
-  
+
   name: 'UserActivity',
 
   data() {
@@ -214,4 +214,4 @@ export default {
   }
 
 };
-</script>
\ No newline at end of file
+</script>
diff --git a/src/components/Account/UserProfile.vue b/src/components/Account/UserProfile.vue
index 739919478880d7d54ade39014876543371f9fa8e..a082d517de45ca433a70a12f8f4f77ba4f8e8b76 100644
--- a/src/components/Account/UserProfile.vue
+++ b/src/components/Account/UserProfile.vue
@@ -56,7 +56,7 @@
 import { mapState } from 'vuex';
 
 export default {
-  
+
   name: 'UserProfile',
 
   computed: {
@@ -66,7 +66,7 @@ export default {
 
     userFullname() {
       if (this.user.first_name || this.user.last_name)
-        return this.user.first_name + ' ' + this.user.last_name;
+        return `${this.user.first_name} ${this.user.last_name}`;
       return null;
     },
   }
@@ -76,4 +76,4 @@ export default {
 
 <style lang="less" scoped>
 
-</style>
\ No newline at end of file
+</style>
diff --git a/src/components/Account/UserProjectsList.vue b/src/components/Account/UserProjectsList.vue
index 47d6174cabed7ce8d05ba990757950c7c0538ed6..e95b914fd79aa6abe3e6bb1a03ceb328336cc6d1 100644
--- a/src/components/Account/UserProjectsList.vue
+++ b/src/components/Account/UserProjectsList.vue
@@ -66,18 +66,18 @@
                 class="right floated"
                 :data-tooltip="`Projet créé le ${project.created_on}`"
               >
-                <i class="calendar icon" />&nbsp;{{ project.created_on }}
+                <em class="calendar icon" />&nbsp;{{ project.created_on }}
               </span>
               <span data-tooltip="Membres">
-                {{ project.nb_contributors }}&nbsp;<i class="user icon" />
+                {{ project.nb_contributors }}&nbsp;<em class="user icon" />
               </span>
               <span data-tooltip="Signalements publiés">
-                {{ project.nb_published_features }}&nbsp;<i
+                {{ project.nb_published_features }}&nbsp;<em
                   class="map marker icon"
                 />
               </span>
               <span data-tooltip="Commentaires">
-                {{ project.nb_published_features_comments }}&nbsp;<i
+                {{ project.nb_published_features_comments }}&nbsp;<em
                   class="comment icon"
                 />
               </span>
@@ -104,7 +104,7 @@ import { mapState, mapMutations, mapActions } from 'vuex';
 import Pagination from '@/components/Pagination.vue';
 
 export default {
-  
+
   name: 'UserProjectList',
 
   components: {
@@ -166,7 +166,9 @@ export default {
     ]),
 
     refreshId() {
-      return '?ver=' + Math.random();
+      const crypto = window.crypto || window.msCrypto;
+      var array = new Uint32Array(1);
+      return '?ver=' + crypto.getRandomValues(array); // Compliant for security-sensitive use cases
     },
 
     getData(page) {
@@ -183,4 +185,4 @@ export default {
   }
 
 };
-</script>
\ No newline at end of file
+</script>
diff --git a/src/components/AppFooter.vue b/src/components/AppFooter.vue
index 9d178cb47d4409d73e87df5490dc31530f1fee39..0e8a245c10b6178d531eef6abd38b2e6a12760e5 100644
--- a/src/components/AppFooter.vue
+++ b/src/components/AppFooter.vue
@@ -22,7 +22,7 @@
 
 <script>
 export default {
-  
+
   name: 'AppFooter',
 
   computed: {
diff --git a/src/components/AppHeader.vue b/src/components/AppHeader.vue
index 6379091836bba256d4a77f407b20bfcf909edb4c..6ff9f77d38bb8f356be23bce793d8ac85a7ab7ee 100644
--- a/src/components/AppHeader.vue
+++ b/src/components/AppHeader.vue
@@ -25,7 +25,7 @@
           <span>
             <span v-if="project"> Projet : {{ project.title }} </span>
           </span>
-          <i class="dropdown icon" />
+          <em class="dropdown icon" />
           <div
             :class="[
               'menu dropdown-list',
@@ -41,7 +41,7 @@
               }"
               class="item"
             >
-              <i class="home icon" />Accueil
+              <em class="home icon" />Accueil
             </router-link>
             <router-link
               v-if="project"
@@ -51,7 +51,7 @@
               }"
               class="item"
             >
-              <i class="list icon" />Liste & Carte
+              <em class="list icon" />Liste & Carte
             </router-link>
             <router-link
               v-if="
@@ -64,7 +64,7 @@
               }"
               class="item"
             >
-              <i class="map icon" />Fonds cartographiques
+              <em class="map icon" />Fonds cartographiques
             </router-link>
             <router-link
               v-if="
@@ -77,7 +77,7 @@
               }"
               class="item"
             >
-              <i class="users icon" />Membres
+              <em class="users icon" />Membres
             </router-link>
             <div class="mobile">
               <router-link
@@ -111,7 +111,7 @@
                   v-if="user"
                   class="item"
                   @click="logout"
-                ><i class="ui logout icon" />
+                ><em class="ui logout icon" />
                 </a>
                 <router-link
                   v-else-if="!user && !SSO_LOGIN_URL"
@@ -166,7 +166,7 @@
               v-if="user"
               class="item log-item"
               @click="logout"
-            ><i class="ui logout icon" />
+            ><em class="ui logout icon" />
             </a>
             <router-link
               v-else-if="!user && !SSO_LOGIN_URL"
@@ -192,7 +192,7 @@
 import { mapState } from 'vuex';
 
 export default {
-  
+
   name: 'AppHeader',
 
   data() {
@@ -234,7 +234,7 @@ export default {
     },
     userFullname() {
       if (this.user.first_name || this.user.last_name)
-        return this.user.first_name + ' ' + this.user.last_name;
+        return `${this.user.first_name} ${this.user.last_name}`;
       return null;
     },
     isAdmin() {
@@ -300,4 +300,4 @@ export default {
   height: 100% !important;
 }
 
-</style>
\ No newline at end of file
+</style>
diff --git a/src/components/Dropdown.vue b/src/components/Dropdown.vue
index 0fa9ba3d802b323bae63aa1286874cd830e7a27e..b7cc3d7a3a87b8f749a064c3d016f8715c4d4077 100644
--- a/src/components/Dropdown.vue
+++ b/src/components/Dropdown.vue
@@ -32,7 +32,7 @@
         {{ selected }}
       </div>
     </div>
-    <i
+    <em
       :class="['dropdown icon', { clear: clearable && selected }]"
       @click="clear"
     />
@@ -186,4 +186,4 @@ export default {
 .italic {
   font-style: italic;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/src/components/Feature/Detail/FeatureAttachements.vue b/src/components/Feature/Detail/FeatureAttachements.vue
index 54e9ee382f4ae926523cfa4eb75931bf5b1fbede..56ac02da76f3ae603870c93b26a3d479be2984bc 100644
--- a/src/components/Feature/Detail/FeatureAttachements.vue
+++ b/src/components/Feature/Detail/FeatureAttachements.vue
@@ -36,9 +36,9 @@
         </div>
       </div>
     </div>
-    <i v-if="attachments.length === 0">
+    <em v-if="attachments.length === 0">
       Aucune pièce jointe associée au signalement.
-    </i>
+    </em>
   </div>
 </template>
 
diff --git a/src/components/Feature/Detail/FeatureComments.vue b/src/components/Feature/Detail/FeatureComments.vue
index 027fbd15f1854efb32f8ee5ef0048cd2d8c33b63..52910059d5d03bb21bea8e7672a5ec78cbfa5722 100644
--- a/src/components/Feature/Detail/FeatureComments.vue
+++ b/src/components/Feature/Detail/FeatureComments.vue
@@ -51,7 +51,7 @@
                         event.related_comment.attachment.url
                     "
                     target="_blank"
-                  ><i class="paperclip fitted icon" />
+                  ><em class="paperclip fitted icon" />
                     {{ event.related_comment.attachment.title }}</a>
                 </div>
               </div>
@@ -107,7 +107,7 @@
               class="ui icon button"
               for="attachment_file"
             >
-              <i class="paperclip icon" />
+              <em class="paperclip icon" />
               <span class="label">{{
                 comment_form.attachment_file.value
                   ? comment_form.attachment_file.value
@@ -146,7 +146,7 @@
           class="ui compact green icon button"
           @click="postComment"
         >
-          <i class="plus icon" /> Poster le commentaire
+          <em class="plus icon" /> Poster le commentaire
         </button>
       </form>
     </div>
@@ -160,7 +160,7 @@ import { mapState, mapGetters } from 'vuex';
 import featureAPI from '@/services/feature-api';
 
 export default {
-  
+
   name: 'FeatureComments',
 
   props: {
@@ -262,7 +262,7 @@ export default {
           this.comment_form.attachment_file.fileName = title; //* name of the file
           const fileExtension = title.substring(title.lastIndexOf('.') + 1);
           if ((title.length - fileExtension.length) > 11) {
-            title = title.slice(0, 10) + '[...].' + fileExtension;
+            title = `${title.slice(0, 10)}[...].${fileExtension}`;
           }
           this.comment_form.attachment_file.title = title; //* title for display
           this.comment_form.attachment_file.errors = null;
diff --git a/src/components/Feature/Detail/FeatureHeader.vue b/src/components/Feature/Detail/FeatureHeader.vue
index 7f4ffc23edc58879edf4ebbfe882e9be3fdaf98e..bdf8616eb701f57f1025d4ca848bb9fdd981c0f5 100644
--- a/src/components/Feature/Detail/FeatureHeader.vue
+++ b/src/components/Feature/Detail/FeatureHeader.vue
@@ -16,7 +16,7 @@
             data-tooltip="Ajouter un signalement"
             data-position="bottom left"
           >
-            <i class="plus fitted icon" />
+            <em class="plus fitted icon" />
           </router-link>
           <router-link
             v-if="
@@ -33,7 +33,7 @@
             }"
             class="ui button button-hover-orange"
           >
-            <i class="inverted grey pencil alternate icon" />
+            <em class="inverted grey pencil alternate icon" />
           </router-link>
           <a
             v-if="((permissions && permissions.can_update_feature) || isFeatureCreator) && isOnline"
@@ -41,7 +41,7 @@
             class="ui button button-hover-red"
             @click="isCanceling = true"
           >
-            <i class="inverted grey trash alternate icon" />
+            <em class="inverted grey trash alternate icon" />
           </a>
         </div>
         <div class="ui hidden divider" />
@@ -58,7 +58,7 @@
 import { mapState, mapGetters } from 'vuex';
 
 export default {
-  
+
   name: 'FeatureHeader',
 
   computed: {
diff --git a/src/components/Feature/Detail/FeatureTable.vue b/src/components/Feature/Detail/FeatureTable.vue
index fbaeddf460a6edf5bf06a47239a01b3e5c2009a6..171ceb5a03a0554089310c8533b69035126943ce 100644
--- a/src/components/Feature/Detail/FeatureTable.vue
+++ b/src/components/Feature/Detail/FeatureTable.vue
@@ -12,7 +12,7 @@
             </td>
             <td>
               <b>
-                <i
+                <em
                   v-if="field.field_type === 'boolean'"
                   :class="[
                     'icon',
@@ -33,7 +33,7 @@
         <tr>
           <td>Statut</td>
           <td>
-            <i
+            <em
               v-if="currentFeature.status"
               :class="['icon', statusIcon]"
             />
@@ -79,7 +79,7 @@
 import { mapState } from 'vuex';
 
 export default {
-  
+
   name: 'FeatureTable',
 
   filters: {
diff --git a/src/components/Feature/Edit/FeatureExtraForm.vue b/src/components/Feature/Edit/FeatureExtraForm.vue
index 5981ad2cde4b20cbb51232df2a27dbe10a0ac040..38734ee77de0e254bacd56d903c6c64dcc1bc55c 100644
--- a/src/components/Feature/Edit/FeatureExtraForm.vue
+++ b/src/components/Feature/Edit/FeatureExtraForm.vue
@@ -135,4 +135,4 @@ export default {
     },
   },
 };
-</script>
\ No newline at end of file
+</script>
diff --git a/src/components/Feature/FeatureAttachmentForm.vue b/src/components/Feature/FeatureAttachmentForm.vue
index 922f3c6a6d8714106b9c1294bb28ef43667ff4c1..78e714c6b4912757f10e6fe36759c5b21f3dfcc7 100644
--- a/src/components/Feature/FeatureAttachmentForm.vue
+++ b/src/components/Feature/FeatureAttachmentForm.vue
@@ -8,7 +8,7 @@
           type="button"
           @click="removeAttachmentFormset(form.dataKey)"
         >
-          <i class="ui times icon" />
+          <em class="ui times icon" />
         </button>
       </h4>
       <!-- {{ form.errors }} -->
@@ -42,7 +42,7 @@
               class="ui icon button"
               :for="'attachment_file' + attachmentForm.dataKey"
             >
-              <i class="file icon" />
+              <em class="file icon" />
               <span
                 v-if="form.attachment_file.value"
                 class="label"
@@ -262,4 +262,4 @@ export default {
     },
   },
 };
-</script>
\ No newline at end of file
+</script>
diff --git a/src/components/Feature/FeatureEditModal.vue b/src/components/Feature/FeatureEditModal.vue
index f7474fe277301a05a425883a673d22f91038ed2a..e005c820817de50dfa05a01dbe40181ae77ee133 100644
--- a/src/components/Feature/FeatureEditModal.vue
+++ b/src/components/Feature/FeatureEditModal.vue
@@ -1,7 +1,7 @@
 
 <template>
   <div class="ui mini modal">
-    <i class="close icon" />
+    <em class="close icon" />
     <div class="content">
       <h3>Importer une image géoréférencée</h3>
       <form
@@ -21,7 +21,7 @@
             class="ui icon button"
             for="image_file"
           >
-            <i class="file icon" />
+            <em class="file icon" />
             <span class="label">Sélectionner une image ...</span>
           </label>
           <input
@@ -44,7 +44,7 @@
           class="ui positive right labeled icon button"
         >
           Importer
-          <i class="checkmark icon" />
+          <em class="checkmark icon" />
         </button>
       </form>
     </div>
@@ -55,4 +55,4 @@
 export default {
   name: 'FeatureEditModal'
 };
-</script>
\ No newline at end of file
+</script>
diff --git a/src/components/Feature/FeatureLinkedForm.vue b/src/components/Feature/FeatureLinkedForm.vue
index 47f8c2375471694f60f34aa91ffa75ef1d97ff1f..bbd2b1ab1bbcd82020ca31bb859a562b2694f1c0 100644
--- a/src/components/Feature/FeatureLinkedForm.vue
+++ b/src/components/Feature/FeatureLinkedForm.vue
@@ -7,7 +7,7 @@
         type="button"
         @click="remove_linked_formset"
       >
-        <i class="ui times icon" />
+        <em class="ui times icon" />
       </button>
     </h4>
     <ul
@@ -164,4 +164,4 @@ export default {
     },
   },
 };
-</script>
\ No newline at end of file
+</script>
diff --git a/src/components/Feature/FeatureListMassToggle.vue b/src/components/Feature/FeatureListMassToggle.vue
index 02aaa775df28a1cb77c6dbbf47ff1111b31a5e16..ef0bd866e2729328b35c18f836a2202c7e4d705b 100644
--- a/src/components/Feature/FeatureListMassToggle.vue
+++ b/src/components/Feature/FeatureListMassToggle.vue
@@ -4,9 +4,9 @@
     :data-tooltip="`Passer en mode ${massMode === 'modify' ? 'suppression':'édition'}`"
     @click="switchMode"
   >
-    <div><i :class="['icon pencil', {disabled: massMode !== 'modify'}]" /></div>
+    <div><em :class="['icon pencil', {disabled: massMode !== 'modify'}]" /></div>
     <span class="grey">|&nbsp;</span>
-    <div><i :class="['icon trash', {disabled: massMode !== 'delete'}]" /></div>
+    <div><em :class="['icon trash', {disabled: massMode !== 'delete'}]" /></div>
   </div>
 </template>
 
@@ -45,4 +45,4 @@ export default {
   color: #bbbbbb;
 }
 
-</style>
\ No newline at end of file
+</style>
diff --git a/src/components/FeatureType/FeatureTypeCustomForm.vue b/src/components/FeatureType/FeatureTypeCustomForm.vue
index 39b4ed79ec6a5994c979c1d2a6ef75f5cd60479f..05a34dbf2ab751a0db1d581f3db591983d8619d4 100644
--- a/src/components/FeatureType/FeatureTypeCustomForm.vue
+++ b/src/components/FeatureType/FeatureTypeCustomForm.vue
@@ -7,7 +7,7 @@
         type="button"
         @click="removeCustomForm()"
       >
-        <i class="ui times icon" />
+        <em class="ui times icon" />
       </button>
     </h4>
     <div class="visible-fields">
diff --git a/src/components/FeatureType/SymbologySelector.vue b/src/components/FeatureType/SymbologySelector.vue
index 3715aa104d805a5553b4822bef257d3f21b0d4c3..5db2a4dbf6303969484d555d7fe29ed2d94dd246 100644
--- a/src/components/FeatureType/SymbologySelector.vue
+++ b/src/components/FeatureType/SymbologySelector.vue
@@ -45,7 +45,7 @@
           class="icon-container"
           @click="selectIcon(icon)"
         >
-          <i
+          <em
             :class="`fa-${icon}`"
             class="icon alt fas"
           />
diff --git a/src/components/ImportTask.vue b/src/components/ImportTask.vue
index e9af29366b9a267d225141e45d1b6e19e66be14f..5d239b8582c3789ae4fdd9067fa45b9a87294dce 100644
--- a/src/components/ImportTask.vue
+++ b/src/components/ImportTask.vue
@@ -29,19 +29,19 @@
               :data-tooltip="importFile.infos"
               class="ui icon margin-left"
             >
-              <i
+              <em
                 v-if="importFile.status === 'processing'"
                 class="orange hourglass half icon"
               />
-              <i
+              <em
                 v-else-if="importFile.status === 'finished'"
                 class="green check circle outline icon"
               />
-              <i
+              <em
                 v-else-if="importFile.status === 'failed'"
                 class="red x icon"
               />
-              <i
+              <em
                 v-else
                 class="red ban icon"
               />
@@ -50,7 +50,7 @@
               v-if="importFile.status === 'pending'"
               data-tooltip="Statut en attente. Clickez pour rafraichir."
             >
-              <i
+              <em
                 :class="['orange icon', ready && !reloading ? 'sync' : 'hourglass half rotate']"
                 @click="fetchImports()"
               />
@@ -216,4 +216,4 @@ and also iPads specifically.
     margin-left: 94%;
   }
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/src/components/Pagination.vue b/src/components/Pagination.vue
index 2afc85dfff08547813bd8d477c290efe1632ddd3..30ef334a6c89e0f488fb0d760966fa47eeedc12e 100644
--- a/src/components/Pagination.vue
+++ b/src/components/Pagination.vue
@@ -11,7 +11,7 @@
             :href="currentLocation"
             @click="page -= 1"
           >
-            <i class="ui icon big angle left" />
+            <em class="ui icon big angle left" />
           </a>
         </li>
         <div
@@ -61,7 +61,7 @@
             :href="currentLocation"
             @click="page += 1"
           >
-            <i class="ui icon big angle right" />
+            <em class="ui icon big angle right" />
           </a>
         </li>
       </ul>
@@ -90,7 +90,7 @@ export default {
   data() {
     return {
       page: 1,
-      currentLocation: window.location.origin + window.location.pathname + '#',
+      currentLocation: `${window.location.origin}${window.location.pathname}#`,
     };
   },
 
diff --git a/src/components/Project/Basemaps/BasemapListItem.vue b/src/components/Project/Basemaps/BasemapListItem.vue
index 53314e43feda027713042596ab69d57f685d10fa..7107d3cf9d1084b24ec17b0c1537982939a2e280 100644
--- a/src/components/Project/Basemaps/BasemapListItem.vue
+++ b/src/components/Project/Basemaps/BasemapListItem.vue
@@ -37,7 +37,7 @@
           class="ui compact small icon left floated button green"
           @click="addLayer"
         >
-          <i class="ui plus icon" />
+          <em class="ui plus icon" />
           <span>Ajouter une couche</span>
         </a>
       </div>
@@ -58,7 +58,7 @@
             button button-hover-green
           "
         >
-          <i class="ui trash alternate icon" />
+          <em class="ui trash alternate icon" />
           <span>Supprimer ce fond cartographique</span>
         </a>
       </div>
@@ -205,4 +205,4 @@ export default {
 .button {
   margin-right: 0.5em !important;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/src/components/Project/Basemaps/ProjectMappingContextLayer.vue b/src/components/Project/Basemaps/ProjectMappingContextLayer.vue
index 46d0968998eba574c939f5578fe4a5b6b7d771e6..a914f3ef391bc5927112ec0cd22b9db8e6b96318 100644
--- a/src/components/Project/Basemaps/ProjectMappingContextLayer.vue
+++ b/src/components/Project/Basemaps/ProjectMappingContextLayer.vue
@@ -12,7 +12,7 @@
           for="form.layer.id_for_label"
           class="layer-handle-sort"
         >
-          <i class="th icon" />couche
+          <em class="th icon" />couche
         </label>
         <Dropdown
           :options="availableLayerOptions"
@@ -57,7 +57,7 @@
         @click="removeLayer"
       >
         <div class="ui compact small icon floated button button-hover-red">
-          <i class="ui grey trash alternate icon" />
+          <em class="ui grey trash alternate icon" />
           <span>Supprimer cette couche</span>
         </div>
       </div>
@@ -173,4 +173,4 @@ export default {
     },
   },
 };
-</script>
\ No newline at end of file
+</script>
diff --git a/src/components/Project/Detail/ProjectFeatureTypes.vue b/src/components/Project/Detail/ProjectFeatureTypes.vue
index dffb31046d4c1f8f0a5783328398a389c19b4148..7b5bf2d858849069b2d8770a9c86ed93e626b682 100644
--- a/src/components/Project/Detail/ProjectFeatureTypes.vue
+++ b/src/components/Project/Detail/ProjectFeatureTypes.vue
@@ -73,7 +73,7 @@
               data-position="top right"
               data-variation="mini"
             >
-              <i class="ui plus icon" />
+              <em class="ui plus icon" />
             </router-link>
             <router-link
               v-if="
@@ -99,13 +99,13 @@
               data-position="top right"
               data-variation="mini"
             >
-              <i class="inverted grey copy alternate icon" />
+              <em class="inverted grey copy alternate icon" />
             </router-link>
             <div
               v-if="isImporting(type)"
               class="import-message"
             >
-              <i class="info circle icon" />
+              <em class="info circle icon" />
               Import en cours
             </div>
             <div
@@ -127,7 +127,7 @@
                 data-variation="mini"
                 @click="toggleDeleteFeatureType(type)"
               >
-                <i class="inverted grey trash alternate icon" />
+                <em class="inverted grey trash alternate icon" />
               </a>
               <router-link
                 v-if="
@@ -153,7 +153,7 @@
                 data-position="top center"
                 data-variation="mini"
               >
-                <i class="inverted grey paint brush alternate icon" />
+                <em class="inverted grey paint brush alternate icon" />
               </router-link>
               <router-link
                 v-if="
@@ -180,14 +180,14 @@
                 data-position="top center"
                 data-variation="mini"
               >
-                <i class="inverted grey pencil alternate icon" />
+                <em class="inverted grey pencil alternate icon" />
               </router-link>
             </div>
           </div>
         </div>
       </div>
       <div v-if="feature_types.length === 0">
-        <i> Le projet ne contient pas encore de type de signalements. </i>
+        <em> Le projet ne contient pas encore de type de signalements. </em>
       </div>
     </div>
 
@@ -204,7 +204,7 @@
         }"
         class="ui compact basic button"
       >
-        <i class="ui plus icon" />Créer un nouveau type de signalement
+        <em class="ui plus icon" />Créer un nouveau type de signalement
       </router-link>
     </div>
     <div class="nouveau-type-signalement">
@@ -222,7 +222,7 @@
           button-align-left
         "
       >
-        <i class="ui plus icon" />
+        <em class="ui plus icon" />
         <label
           class="ui"
           for="json_file"
@@ -258,7 +258,7 @@
           button-align-left
         "
       >
-        <i class="ui plus icon" />
+        <em class="ui plus icon" />
         <label
           class="ui"
           for="csv_file"
@@ -296,7 +296,7 @@
         }"
         class="ui compact basic button button-align-left"
       >
-        <i class="ui plus icon" />
+        <em class="ui plus icon" />
         Créer un nouveau type de signalement à partir du catalogue {{ CATALOG_NAME|| 'IDGO' }}
       </router-link>
     </div>
@@ -310,7 +310,7 @@
         class="ui fluid teal icon button"
         @click="toNewGeojsonFeatureType"
       >
-        <i class="upload icon" /> Lancer l'import avec le fichier
+        <em class="upload icon" /> Lancer l'import avec le fichier
         {{ geojsonFileToImport.name }}
       </button>
     </div>
@@ -324,7 +324,7 @@
         class="ui fluid teal icon button"
         @click="toNewCsvFeatureType"
       >
-        <i class="upload icon" /> Lancer l'import avec le fichier
+        <em class="upload icon" /> Lancer l'import avec le fichier
         {{ csvFileToImport.name }}
       </button>
     </div>
@@ -332,7 +332,7 @@
       v-if="csvError"
       class="ui negative message"
     >
-      <i
+      <em
         class="close icon"
         @click="csvError = null"
       />
@@ -680,4 +680,4 @@ export default {
   color: teal;
 }
 
-</style>
\ No newline at end of file
+</style>
diff --git a/src/components/Project/Detail/ProjectHeader.vue b/src/components/Project/Detail/ProjectHeader.vue
index 81cab8d4385b5c1a565247af55712c2527f6f915..b442c78d4a4aec71ef835aa61320e92f0499641c 100644
--- a/src/components/Project/Detail/ProjectHeader.vue
+++ b/src/components/Project/Detail/ProjectHeader.vue
@@ -15,19 +15,19 @@
           class="ui basic teal label"
           data-tooltip="Membres"
         >
-          <i class="user icon" />{{ project.nb_contributors }}
+          <em class="user icon" />{{ project.nb_contributors }}
         </div>
         <div
           class="ui basic teal label"
           data-tooltip="Signalements publiés"
         >
-          <i class="map marker icon" />{{ project.nb_published_features }}
+          <em class="map marker icon" />{{ project.nb_published_features }}
         </div>
         <div
           class="ui basic teal label"
           data-tooltip="Commentaires"
         >
-          <i class="comment icon" />{{
+          <em class="comment icon" />{{
             project.nb_published_features_comments
           }}
         </div>
@@ -59,7 +59,7 @@
             data-variation="mini"
             @click="OPEN_PROJECT_MODAL('subscribe')"
           >
-            <i class="inverted grey envelope icon" />
+            <em class="inverted grey envelope icon" />
           </a>
           <router-link
             v-if="
@@ -73,7 +73,7 @@
             data-position="top center"
             data-variation="mini"
           >
-            <i class="inverted grey pencil alternate icon" />
+            <em class="inverted grey pencil alternate icon" />
           </router-link>
           <a
             v-if="isProjectAdmin && isOffline() !== true"
@@ -84,7 +84,7 @@
             data-variation="mini"
             @click="OPEN_PROJECT_MODAL('deleteProject')"
           >
-            <i class="inverted grey trash icon" />
+            <em class="inverted grey trash icon" />
           </a>
         </div>
 
@@ -93,7 +93,7 @@
           class="ui teal left labeled icon button share-button"
           @click="copyLink"
         >
-          <i class="left icon share square" />
+          <em class="left icon share square" />
           Copier le lien de partage
         </button>
 
@@ -103,7 +103,7 @@
               Le lien a été copié dans le presse-papier
             </span>
             &nbsp;
-            <i
+            <em
               class="close icon"
               @click="confirmMsg = ''"
             />
@@ -118,7 +118,7 @@
           class="ui fluid labeled teal icon button"
           @click="sendOfflineFeatures"
         >
-          <i class="upload icon" />
+          <em class="upload icon" />
           Envoyer au serveur
         </button>
       </div>
@@ -133,7 +133,7 @@ import { mapState, mapGetters, mapMutations } from 'vuex';
 import featureAPI from '@/services/feature-api';
 
 export default {
-  
+
   name: 'ProjectHeader',
 
   props: {
@@ -190,7 +190,9 @@ export default {
     ]),
 
     refreshId() {
-      return '?ver=' + Math.random();
+      const crypto = window.crypto || window.msCrypto;
+      var array = new Uint32Array(1);
+      return '?ver=' + crypto.getRandomValues(array); // Compliant for security-sensitive use cases
     },
 
     isOffline() {
diff --git a/src/components/Project/Detail/ProjectLastComments.vue b/src/components/Project/Detail/ProjectLastComments.vue
index d8eae6f809a777fb29c2519e1750e2bb6fc69f74..4a9bbe487ac60004fd25177977fdfb318d768b59 100644
--- a/src/components/Project/Detail/ProjectLastComments.vue
+++ b/src/components/Project/Detail/ProjectLastComments.vue
@@ -28,18 +28,18 @@
                 </router-link>
               </div>
               <div class="description">
-                <i>[ {{ item.created_on
+                <em>[ {{ item.created_on
                 }}<span
                   v-if="user && item.display_author"
                 >, par {{ item.display_author }}
                 </span>
-                  ]</i>
+                  ]</em>
               </div>
             </div>
           </div>
-          <i
+          <em
             v-if="!last_comments || last_comments.length === 0"
-          >Aucun commentaire pour le moment.</i>
+          >Aucun commentaire pour le moment.</em>
         </div>
       </div>
     </div>
@@ -51,7 +51,7 @@
 import { mapState } from 'vuex';
 
 export default {
-  
+
   name: 'ProjectsLastComments',
 
   props: {
diff --git a/src/components/Project/Detail/ProjectLastFeatures.vue b/src/components/Project/Detail/ProjectLastFeatures.vue
index bc9e8cf82a41510f4932524d4b3438b37940248b..aa3e3521ce34e76f56a33c5eebe731d6addef9cb 100644
--- a/src/components/Project/Detail/ProjectLastFeatures.vue
+++ b/src/components/Project/Detail/ProjectLastFeatures.vue
@@ -36,7 +36,7 @@
                 </router-link>
               </div>
               <div class="description">
-                <i>
+                <em>
                   [{{ item.properties.created_on }}
                   <span v-if="user && item.properties.creator">
                     , par
@@ -47,13 +47,13 @@
                     }}
                   </span>
                   ]
-                </i>
+                </em>
               </div>
             </div>
           </div>
-          <i
+          <em
             v-if="features.length === 0 && !loading"
-          >Aucun signalement pour le moment.</i>
+          >Aucun signalement pour le moment.</em>
         </div>
       </div>
     </div>
@@ -65,7 +65,7 @@
 import { mapState } from 'vuex';
 
 export default {
-  
+
   name: 'ProjectLastFeatures',
 
   props: {
diff --git a/src/components/Project/Detail/ProjectModal.vue b/src/components/Project/Detail/ProjectModal.vue
index 5487c60302fa0813dd9a490e8b76bf1177a4b4e1..c11c641d4c9e4813848be7838a4adb44c3935e7f 100644
--- a/src/components/Project/Detail/ProjectModal.vue
+++ b/src/components/Project/Detail/ProjectModal.vue
@@ -10,12 +10,12 @@
         { 'transition visible active': projectModalType },
       ]"
     >
-      <i
+      <em
         class="close icon"
         @click="CLOSE_PROJECT_MODAL"
       />
       <div class="ui icon header">
-        <i :class="[projectModalType === 'subscribe' ? 'envelope' : 'trash', 'icon']" />
+        <em :class="[projectModalType === 'subscribe' ? 'envelope' : 'trash', 'icon']" />
         {{
           projectModalType === 'subscribe' ? 'Notifications' : 'Suppression'
         }} du {{
@@ -64,7 +64,7 @@
 import { mapState, mapMutations } from 'vuex';
 
 export default {
-  
+
   name: 'ProjectModal',
 
   props: {
@@ -103,4 +103,4 @@ export default {
   text-align: center;
 }
 
-</style>
\ No newline at end of file
+</style>
diff --git a/src/components/Project/Detail/ProjectParameters.vue b/src/components/Project/Detail/ProjectParameters.vue
index e838dfb31e43ba4d4712d5ebaf4a5915b145bdff..03cd229bb54f01e7fb6330d9236acb8b5c90c18a 100644
--- a/src/components/Project/Detail/ProjectParameters.vue
+++ b/src/components/Project/Detail/ProjectParameters.vue
@@ -7,7 +7,7 @@
       <div class="card">
         <div class="center aligned content">
           <h4 class="ui center aligned icon header">
-            <i class="disabled grey archive icon" />
+            <em class="disabled grey archive icon" />
             <div class="content">
               Délai avant archivage automatique
             </div>
@@ -20,7 +20,7 @@
       <div class="card">
         <div class="content">
           <h4 class="ui center aligned icon header">
-            <i class="disabled grey trash alternate icon" />
+            <em class="disabled grey trash alternate icon" />
             <div class="content">
               Délai avant suppression automatique
             </div>
@@ -33,7 +33,7 @@
       <div class="card">
         <div class="content">
           <h4 class="ui center aligned icon header">
-            <i class="disabled grey eye icon" />
+            <em class="disabled grey eye icon" />
             <div class="content">
               Visibilité des signalements publiés
             </div>
@@ -46,7 +46,7 @@
       <div class="card">
         <div class="content">
           <h4 class="ui center aligned icon header">
-            <i class="disabled grey eye icon" />
+            <em class="disabled grey eye icon" />
             <div class="content">
               Visibilité des signalements archivés
             </div>
@@ -59,7 +59,7 @@
       <div class="card">
         <div class="content">
           <h4 class="ui center aligned icon header">
-            <i class="disabled grey cogs icon" />
+            <em class="disabled grey cogs icon" />
             <div class="content">
               Modération
             </div>
@@ -75,7 +75,7 @@
 
 <script>
 export default {
-  
+
   name: 'ProjectParameters',
 
   props: {
diff --git a/src/components/Project/FeaturesListAndMap/FeatureListTable.vue b/src/components/Project/FeaturesListAndMap/FeatureListTable.vue
index 28b9833d068cda289609ce75b202c24d43fcb9a8..e90fd6edad417e3de69f3431feac053b303a3cdc 100644
--- a/src/components/Project/FeaturesListAndMap/FeatureListTable.vue
+++ b/src/components/Project/FeaturesListAndMap/FeatureListTable.vue
@@ -23,7 +23,7 @@
                 @click="changeSort('status')"
               >
                 Statut
-                <i
+                <em
                   :class="{
                     down: isSortedAsc('status'),
                     up: isSortedDesc('status'),
@@ -38,7 +38,7 @@
                 @click="changeSort('feature_type')"
               >
                 Type
-                <i
+                <em
                   :class="{
                     down: isSortedAsc('feature_type'),
                     up: isSortedDesc('feature_type'),
@@ -53,7 +53,7 @@
                 @click="changeSort('title')"
               >
                 Nom
-                <i
+                <em
                   :class="{
                     down: isSortedAsc('title'),
                     up: isSortedDesc('title'),
@@ -68,7 +68,7 @@
                 @click="changeSort('updated_on')"
               >
                 Dernière modification
-                <i
+                <em
                   :class="{
                     down: isSortedAsc('updated_on'),
                     up: isSortedDesc('updated_on'),
@@ -86,7 +86,7 @@
                 @click="changeSort('display_creator')"
               >
                 Auteur
-                <i
+                <em
                   :class="{
                     down: isSortedAsc('display_creator'),
                     up: isSortedDesc('display_creator'),
@@ -104,7 +104,7 @@
                 @click="changeSort('display_last_editor')"
               >
                 Dernier éditeur
-                <i
+                <em
                   :class="{
                     down: isSortedAsc('display_last_editor'),
                     up: isSortedDesc('display_last_editor'),
@@ -142,25 +142,25 @@
                 v-if="feature.status === 'archived'"
                 data-tooltip="Archivé"
               >
-                <i class="grey archive icon" />
+                <em class="grey archive icon" />
               </div>
               <div
                 v-else-if="feature.status === 'pending'"
                 data-tooltip="En attente de publication"
               >
-                <i class="teal hourglass outline icon" />
+                <em class="teal hourglass outline icon" />
               </div>
               <div
                 v-else-if="feature.status === 'published'"
                 data-tooltip="Publié"
               >
-                <i class="olive check icon" />
+                <em class="olive check icon" />
               </div>
               <div
                 v-else-if="feature.status === 'draft'"
                 data-tooltip="Brouillon"
               >
-                <i class="orange pencil alternate icon" />
+                <em class="orange pencil alternate icon" />
               </div>
             </td>
             <td class="dt-center">
@@ -497,7 +497,6 @@ table.dataTable th.dt-center, table.dataTable td.dt-center, table.dataTable td.d
 .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
   color: #333 !important;
   border: 1px solid #979797;
-  background-color: white;
   background: -webkit-gradient(
     linear,
     left top,
@@ -527,7 +526,6 @@ table.dataTable th.dt-center, table.dataTable td.dt-center, table.dataTable td.d
 .dataTables_wrapper .dataTables_paginate .paginate_button:hover {
   color: white !important;
   border: 1px solid #111;
-  background-color: #585858;
   background: -webkit-gradient(
     linear,
     left top,
diff --git a/src/components/Project/FeaturesListAndMap/FeaturesMap.vue b/src/components/Project/FeaturesListAndMap/FeaturesMap.vue
index 292d88641361556805986cfaf84b6e7d63d77f9e..75b80c9ab7960cf617ded491b57b5e8065bd208c 100644
--- a/src/components/Project/FeaturesListAndMap/FeaturesMap.vue
+++ b/src/components/Project/FeaturesListAndMap/FeaturesMap.vue
@@ -4,8 +4,8 @@
 
 <script>
 export default {
-  
+
   name: 'FeaturesMap',
   
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/src/components/Projects/DropdownMenuItem.vue b/src/components/Projects/DropdownMenuItem.vue
index d2dd36901f01d4ec950df772e12b39a9af356323..a50e4cada8937a26ec07a4aec34ccb43c76afddc 100644
--- a/src/components/Projects/DropdownMenuItem.vue
+++ b/src/components/Projects/DropdownMenuItem.vue
@@ -73,4 +73,3 @@ export default {
   }
 };
 </script>
-
diff --git a/src/components/Projects/ProjectsListItem.vue b/src/components/Projects/ProjectsListItem.vue
index b384451d47faab6f654183e34561d752600e722e..a9560dc654bb90a9fe7f174d4d9d765ac41398e2 100644
--- a/src/components/Projects/ProjectsListItem.vue
+++ b/src/components/Projects/ProjectsListItem.vue
@@ -41,18 +41,18 @@
       </div>
       <div class="meta">
         <span class="right floated">
-          <i class="calendar icon" />&nbsp; {{ project.created_on }}
+          <em class="calendar icon" />&nbsp; {{ project.created_on }}
         </span>
         <span data-tooltip="Membres">
-          {{ project.nb_contributors }}&nbsp;<i class="user icon" />
+          {{ project.nb_contributors }}&nbsp;<em class="user icon" />
         </span>
         <span data-tooltip="Signalements publiés">
-          {{ project.nb_published_features }}&nbsp;<i
+          {{ project.nb_published_features }}&nbsp;<em
             class="map marker icon"
           />
         </span>
         <span data-tooltip="Commentaires">
-          {{ project.nb_published_features_comments }}&nbsp;<i
+          {{ project.nb_published_features_comments }}&nbsp;<em
             class="comment icon"
           />
         </span>
@@ -90,8 +90,9 @@ export default {
 
   methods: {
     refreshId() {
-      //* change path of thumbnail to update image
-      return '?ver=' + Math.random();
+      const crypto = window.crypto || window.msCrypto;
+      var array = new Uint32Array(1);
+      return '?ver=' + crypto.getRandomValues(array); // Compliant for security-sensitive use cases
     },
   }
 };
diff --git a/src/components/Projects/ProjectsMenu.vue b/src/components/Projects/ProjectsMenu.vue
index c70a951675ec7f17cfc499f8f376ee55947360de..619e7aac2c317166257274f8e4425e356593055b 100644
--- a/src/components/Projects/ProjectsMenu.vue
+++ b/src/components/Projects/ProjectsMenu.vue
@@ -5,7 +5,7 @@
         class="title collapsible-filters"
       >
         FILTRES
-        <i
+        <em
           class="ui icon caret right down"
         />
       </div>
diff --git a/src/components/Projects/SearchProjects.vue b/src/components/Projects/SearchProjects.vue
index 25d04fdd463de612a0777e4173381a829c3aaa82..703197cb85dc4333b7bdc413db0b295777915845 100644
--- a/src/components/Projects/SearchProjects.vue
+++ b/src/components/Projects/SearchProjects.vue
@@ -75,4 +75,4 @@ export default {
     box-shadow: 0 0 1px grey;
   }
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/src/components/SearchFeature.vue b/src/components/SearchFeature.vue
index c1692eba7482fd18b6cc82ed8203bd4400e07278..6a5b191a2208ee63600b9e089cf6287e1e86c662 100644
--- a/src/components/SearchFeature.vue
+++ b/src/components/SearchFeature.vue
@@ -27,7 +27,7 @@
           class="multiselect__clear"
           @click.prevent.stop="selection = null"
         >
-          <i class="close icon" />
+          <em class="close icon" />
         </div>
       </template>
       <span slot="noResult">
diff --git a/src/components/SidebarLayers.vue b/src/components/SidebarLayers.vue
index 9e9782e1827b4b228434b1c5509f1c4128721b9c..2707712780b9229e8389c5f5894cd0b2a91b5c9c 100644
--- a/src/components/SidebarLayers.vue
+++ b/src/components/SidebarLayers.vue
@@ -48,7 +48,7 @@
 
         <!-- <span data-tooltip="Il est possible pour chaque fond cartographique de modifier l'ordre des couches"
             data-position="bottom left">
-                <i class="question circle outline icon"></i>
+                <em class="question circle outline icon"></em>
             </span> -->
       </h4>
     </div>
@@ -90,7 +90,7 @@
           :data-id="layer.id"
         >
           <p class="layer-handle-sort">
-            <i class="th icon" />{{ layer.title }}
+            <em class="th icon" />{{ layer.title }}
           </p>
           <label>Opacité &nbsp;<span>(%)</span></label>
           <div class="range-container">
@@ -380,4 +380,4 @@ export default {
 .queryable-layers-dropdown > label {
   font-weight: bold;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/src/views/Catalog.vue b/src/views/Catalog.vue
index 6782dceace701e3968464b76dca5fae8bcaeffd0..3033f489161fd156263febf53c462f61e9cf6ef1 100644
--- a/src/views/Catalog.vue
+++ b/src/views/Catalog.vue
@@ -89,7 +89,7 @@
         class="ui fluid teal icon button"
         @click="launchImport"
       >
-        <i class="upload icon" /> Lancer l'import avec le fichier
+        <em class="upload icon" /> Lancer l'import avec le fichier
         <span v-if="selectedResource">
           {{ selectedResource.resource }}
         </span>
@@ -289,7 +289,6 @@ h1 {
 .dataTables_paginate .paginate_button.current:hover {
   color: #333 !important;
   border: 1px solid #979797;
-  background-color: white;
   background: -webkit-gradient(
     linear,
     left top,
@@ -319,7 +318,6 @@ h1 {
 .dataTables_paginate .paginate_button:hover {
   color: white !important;
   border: 1px solid #111;
-  background-color: #585858;
   background: -webkit-gradient(
     linear,
     left top,
diff --git a/src/views/Feature/FeatureDetail.vue b/src/views/Feature/FeatureDetail.vue
index eb946a52ad7aae5cc4a6cc80457412970ac7c2fc..54ef274846b0bdc3ecd6d7c217c7a2047f7808ec 100644
--- a/src/views/Feature/FeatureDetail.vue
+++ b/src/views/Feature/FeatureDetail.vue
@@ -48,12 +48,12 @@
             { 'active visible': isCanceling },
           ]"
         >
-          <i
+          <em
             class="close icon"
             @click="isCanceling = false"
           />
           <div class="ui icon header">
-            <i class="trash alternate icon" />
+            <em class="trash alternate icon" />
             Supprimer le signalement
           </div>
           <div class="actions">
diff --git a/src/views/Feature/FeatureEdit.vue b/src/views/Feature/FeatureEdit.vue
index c61eb81add1ae97f6b94ef26c1cc2dd7a42cad86..1f95ceb22f8d4be968597038dda2a24e99df099d 100644
--- a/src/views/Feature/FeatureEdit.vue
+++ b/src/views/Feature/FeatureEdit.vue
@@ -82,7 +82,7 @@
               class="ui compact button"
               @click="toggleGeoRefModal"
             >
-              <i class="file image icon" />Importer une image géoréférencée
+              <em class="file image icon" />Importer une image géoréférencée
             </button>
             Vous pouvez utiliser une image géoréférencée pour localiser le
             signalement.
@@ -96,7 +96,7 @@
               class="ui mini modal transition visible active"
               style="display: block !important"
             >
-              <i
+              <em
                 class="close icon"
                 @click="toggleGeoRefModal"
               />
@@ -117,7 +117,7 @@
                       class="ui icon button"
                       for="image_file"
                     >
-                      <i class="file icon" />
+                      <em class="file icon" />
                       <span class="label">{{ geoRefFileLabel }}</span>
                     </label>
                     <input
@@ -149,7 +149,7 @@
                     ]"
                     @click="georeferencement"
                   >
-                    <i class="plus icon" />
+                    <em class="plus icon" />
                     Importer
                   </button>
                 </form>
@@ -163,7 +163,7 @@
               class="ui compact button"
               @click="create_point_geoposition"
             >
-              <i class="ui map marker alternate icon" />Positionner le
+              <em class="ui map marker alternate icon" />Positionner le
               signalement à partir de votre géolocalisation
             </button>
           </p>
@@ -249,7 +249,7 @@
           class="ui compact basic button"
           @click="add_attachement_formset"
         >
-          <i class="ui plus icon" />Ajouter une pièce jointe
+          <em class="ui plus icon" />Ajouter une pièce jointe
         </button>
       </div>
 
@@ -272,7 +272,7 @@
           class="ui compact basic button"
           @click="add_linked_formset"
         >
-          <i class="ui plus icon" />Ajouter une liaison
+          <em class="ui plus icon" />Ajouter une liaison
         </button>
       </div>
       <div class="ui divider" />
@@ -281,7 +281,7 @@
         class="ui teal icon button"
         @click="postForm"
       >
-        <i class="white save icon" /> Enregistrer les changements
+        <em class="white save icon" /> Enregistrer les changements
       </button>
     </form>
   </div>
diff --git a/src/views/Feature/FeatureOffline.vue b/src/views/Feature/FeatureOffline.vue
index 8bbe1718e7dff467c10f594dcf6921b1ee310d07..a568e976b6fe06e2edc44e5dc743fe0ccc08b7b5 100644
--- a/src/views/Feature/FeatureOffline.vue
+++ b/src/views/Feature/FeatureOffline.vue
@@ -16,7 +16,7 @@
       }"
       class="ui positive left labeled icon button margin-1"
     >
-      <i class="arrow left icon" />Retour au projet
+      <em class="arrow left icon" />Retour au projet
     </router-link>
   </div>
 </template>
diff --git a/src/views/FeatureType/FeatureTypeDetail.vue b/src/views/FeatureType/FeatureTypeDetail.vue
index 2f76d0e2eed70a697724258529a4287a103d873b..8c07e4a391456eae7570aa12ab3d15fd28974dd1 100644
--- a/src/views/FeatureType/FeatureTypeDetail.vue
+++ b/src/views/FeatureType/FeatureTypeDetail.vue
@@ -72,7 +72,7 @@
             :class="['title', { active: showImport && isOnline, nohover: !isOnline }]"
             @click="toggleShowImport"
           >
-            <i class="dropdown icon" />
+            <em class="dropdown icon" />
             Importer des signalements
           </div>
           <div :class="['content', { active: showImport && isOnline }]">
@@ -85,7 +85,7 @@
                   class="ui icon button ellipsis"
                   for="json_file"
                 >
-                  <i class="file icon" />
+                  <em class="file icon" />
                   <span class="label">{{ geojsonFileToImport.name }}</span>
                 </label>
                 <input
@@ -103,7 +103,7 @@
                   class="ui icon button ellipsis"
                   for="csv_file"
                 >
-                  <i class="file icon" />
+                  <em class="file icon" />
                   <span class="label">{{ csvFileToImport.name }}</span>
                 </label>
                 <input
@@ -142,7 +142,7 @@
                     class="ui icon button ellipsis"
                     for="json_file"
                   >
-                    <i class="file icon" />
+                    <em class="file icon" />
                     <span class="label">{{ fileToImport.name }}</span>
                   </label>
                   <input
@@ -191,7 +191,7 @@
                   class="ui fluid teal icon button"
                   @click="importGeoJson"
                 >
-                  <i class="upload icon" /> Lancer l'import
+                  <em class="upload icon" /> Lancer l'import
                 </button>
                 <ImportTask
                   v-if="importFeatureTypeData && importFeatureTypeData.length"
@@ -206,7 +206,7 @@
               :class="['title', { active: !showImport }]"
               @click="toggleShowImport"
             >
-              <i class="dropdown icon" />
+              <em class="dropdown icon" />
               Exporter les signalements
             </div>
             <div :class="['content', { active: !showImport }]">
@@ -222,7 +222,7 @@
                 class="ui fluid teal icon button"
                 @click="geojsonFileToImport.size !== 0 ? importGeoJson() : importCSV()"
               >
-                <i class="download icon" /> Exporter
+                <em class="download icon" /> Exporter
               </button>
             </div>
           </div>
@@ -232,7 +232,7 @@
             :class="['title', { active: !showImport && isOnline, nohover: !isOnline }]"
             @click="toggleShowImport"
           >
-            <i class="dropdown icon" />
+            <em class="dropdown icon" />
             Exporter les signalements
           </div>
           <div :class="['content', { active: !showImport && isOnline}]">
@@ -243,7 +243,7 @@
 
             <!-- <div class="ui selection dropdown fluid">
               <input type="hidden" name="format">
-              <i class="dropdown icon"></i>
+              <em class="dropdown icon"></em>
               <div class="default text">Format</div>
               <div class="menu">
                 <div class="item" data-value="1">GeoJSON</div>
@@ -269,7 +269,7 @@
               class="ui fluid teal icon button"
               @click="exportFeatures"
             >
-              <i class="download icon" /> Exporter
+              <em class="download icon" /> Exporter
             </button>
           </div>
         </div>
@@ -318,25 +318,25 @@
             v-if="feature.status === 'archived'"
             data-tooltip="Archivé"
           >
-            <i class="grey archive icon" />
+            <em class="grey archive icon" />
           </span>
           <span
             v-else-if="feature.status === 'pending'"
             data-tooltip="En attente de publication"
           >
-            <i class="teal hourglass outline icon" />
+            <em class="teal hourglass outline icon" />
           </span>
           <span
             v-else-if="feature.status === 'published'"
             data-tooltip="Publié"
           >
-            <i class="olive check icon" />
+            <em class="olive check icon" />
           </span>
           <span
             v-else-if="feature.status === 'draft'"
             data-tooltip="Brouillon"
           >
-            <i class="orange pencil alternate icon" />
+            <em class="orange pencil alternate icon" />
           </span>
           <router-link
             :to="{
@@ -371,7 +371,7 @@
           :to="{ name: 'liste-signalements', params: { slug } }"
           class="ui right labeled icon button margin-25"
         >
-          <i class="right arrow icon" />
+          <em class="right arrow icon" />
           Voir tous les signalements
         </router-link>
         <router-link
diff --git a/src/views/FeatureType/FeatureTypeEdit.vue b/src/views/FeatureType/FeatureTypeEdit.vue
index fe65967f34f1b11e2b3ee6fd923554c51b2b09bd..9b013bd1a68bf46b44f5946d583fecaf33ffd721 100644
--- a/src/views/FeatureType/FeatureTypeEdit.vue
+++ b/src/views/FeatureType/FeatureTypeEdit.vue
@@ -11,7 +11,7 @@
         v-if="error"
         class="ui negative message"
       >
-        <p><i class="cross icon" /> {{ error }}</p>
+        <p><em class="cross icon" /> {{ error }}</p>
       </div>
     </div>
     <div class="fourteen wide column">
@@ -213,7 +213,7 @@
             "
             @click="setCSVCoordsFields"
           >
-            <i class="white save icon" />
+            <em class="white save icon" />
             Continuer
           </button>
         </div> -->
@@ -237,7 +237,7 @@
             class="ui compact basic button"
             @click="addCustomForm"
           >
-            <i class="ui plus icon" />Ajouter un champ personnalisé
+            <em class="ui plus icon" />Ajouter un champ personnalisé
           </button>
 
           <div class="ui divider" />
@@ -246,7 +246,7 @@
             type="button"
             @click="sendFeatureType"
           >
-            <i class="white save icon" />
+            <em class="white save icon" />
             {{ action === "create" ? "Créer" : "Sauvegarder" }} le type de
             signalement
           </button>
@@ -256,7 +256,7 @@
             type="button"
             @click="postFeatureTypeThenFeatures"
           >
-            <i class="white save icon" />
+            <em class="white save icon" />
             Créer et importer le(s) signalement(s) du geojson
           </button>
         </div>
diff --git a/src/views/FeatureType/FeatureTypeSymbology.vue b/src/views/FeatureType/FeatureTypeSymbology.vue
index 39d0eb96f97bd192f366ad604a8b560ff7b9f21b..4ed4de46de41d5540db3b6838b2c9c6ae3ddfa8b 100644
--- a/src/views/FeatureType/FeatureTypeSymbology.vue
+++ b/src/views/FeatureType/FeatureTypeSymbology.vue
@@ -14,13 +14,13 @@
         v-if="error"
         class="ui negative message"
       >
-        <p><i class="close icon" /> {{ error }}</p>
+        <p><em class="close icon" /> {{ error }}</p>
       </div>
       <div
         v-if="success"
         class="ui positive message"
       >
-        <i
+        <em
           class="close icon"
           @click="success = null"
         />
@@ -103,7 +103,7 @@
           :disabled="!canSaveSymbology"
           @click="sendFeatureSymbology"
         >
-          <i class="white save icon" />
+          <em class="white save icon" />
           Sauvegarder la symbologie du type de signalement
         </button>
       </form>
diff --git a/src/views/Login.vue b/src/views/Login.vue
index 41b036981c4a3a265bcb2ae92af58260f2dd7ef2..904ea9b70c2dbaed70e253fc9f170408bab1efe2 100644
--- a/src/views/Login.vue
+++ b/src/views/Login.vue
@@ -41,7 +41,7 @@
           <div class="ui stacked secondary segment">
             <div class="six field required">
               <div class="ui left icon input">
-                <i class="user icon" />
+                <em class="user icon" />
                 <input
                   v-model="username_value"
                   type="text"
@@ -52,7 +52,7 @@
             </div>
             <div class="six field required">
               <div class="ui left icon input">
-                <i class="lock icon" />
+                <em class="lock icon" />
                 <input
                   v-model="password_value"
                   type="password"
diff --git a/src/views/Project/FeaturesListAndMap.vue b/src/views/Project/FeaturesListAndMap.vue
index 8ced48da357060dadd3edd4365569e9d5e7769b0..08c9d8d64262825e23a3db039ce83306f8a16c61 100644
--- a/src/views/Project/FeaturesListAndMap.vue
+++ b/src/views/Project/FeaturesListAndMap.vue
@@ -21,14 +21,14 @@
             data-tooltip="Carte"
             data-position="bottom left"
             @click="showMap = true"
-          ><i class="map fitted icon" /></a>
+          ><em class="map fitted icon" /></a>
           <a
             :class="['item no-margin', { active: !showMap }]"
             data-tab="list"
             data-tooltip="Liste"
             data-position="bottom left"
             @click="showMap = false"
-          ><i class="list fitted icon" /></a>
+          ><em class="list fitted icon" /></a>
           <div class="item">
             <h4>
               {{ featuresCount }} signalement{{ featuresCount > 1 ? "s" : "" }}
@@ -50,7 +50,7 @@
               data-position="bottom right"
               @click="toggleAddFeature"
             >
-              <i class="plus fitted icon" />
+              <em class="plus fitted icon" />
               <div
                 v-if="showAddFeature"
                 class="menu left transition visible"
@@ -82,7 +82,7 @@
               data-position="bottom right"
               @click="toggleModifyStatus"
             >
-              <i class="pencil fitted icon" />
+              <em class="pencil fitted icon" />
               <div
                 v-if="showModifyStatus"
                 class="menu left transition visible"
@@ -111,7 +111,7 @@
               data-position="bottom right"
               @click="toggleDeleteModal"
             >
-              <i class="grey trash fitted icon" />
+              <em class="grey trash fitted icon" />
             </div>
           </div>
         </div>
@@ -146,7 +146,7 @@
       <div class="field wide four column">
         <label>Nom</label>
         <div class="ui icon input">
-          <i class="search icon" />
+          <em class="search icon" />
           <div class="ui action input">
             <input
               v-model="form.title"
@@ -159,7 +159,7 @@
               class="ui teal icon button"
               @click="resetPaginationNfetchFeatures"
             >
-              <i class="search icon" />
+              <em class="search icon" />
             </button>
           </div>
         </div>
@@ -218,12 +218,12 @@
           { 'active visible': isDeleteModalOpen },
         ]"
       >
-        <i
+        <em
           class="close icon"
           @click="isDeleteModalOpen = false"
         />
         <div class="ui icon header">
-          <i class="trash alternate icon" />
+          <em class="trash alternate icon" />
           Êtes-vous sûr de vouloir effacer
           <span v-if="checkedFeatures.length === 1"> un signalement ? </span>
           <span v-else> ces {{ checkedFeatures.length }} signalements ? </span>
diff --git a/src/views/Project/ProjectBasemaps.vue b/src/views/Project/ProjectBasemaps.vue
index a2cc746e0c6d28c31645a6ffdd4272aa1c69105b..f0ef8a8416f5886be01fd0bd1ba646219db8929b 100644
--- a/src/views/Project/ProjectBasemaps.vue
+++ b/src/views/Project/ProjectBasemaps.vue
@@ -15,7 +15,7 @@
           style="text-align: left"
         >
           <div class="header">
-            <i class="info circle icon" /> Informations
+            <em class="info circle icon" /> Informations
           </div>
           {{ message.comment }}
         </div>
@@ -39,7 +39,7 @@
           data-variation="mini"
           @click="addBasemap"
         >
-          <i class="ui plus icon" />
+          <em class="ui plus icon" />
           <span>&nbsp;Créer un fond cartographique</span>
         </a>
       </div>
@@ -60,7 +60,7 @@
           class="ui teal icon floated button"
           @click="saveChanges"
         >
-          <i class="white save icon" /> Enregistrer les changements
+          <em class="white save icon" /> Enregistrer les changements
         </button>
       </div>
     </form>
diff --git a/src/views/Project/ProjectDetail.vue b/src/views/Project/ProjectDetail.vue
index 41ca311df2ecf6901d59d5b74748b6331ecebfa9..d858d924ff5fc8ee7f936aa5caf5a3c693442745 100644
--- a/src/views/Project/ProjectDetail.vue
+++ b/src/views/Project/ProjectDetail.vue
@@ -13,7 +13,7 @@
           v-if="tempMessage"
           class="ui positive message"
         >
-          <p><i class="check icon" /> {{ tempMessage }}</p>
+          <p><em class="check icon" /> {{ tempMessage }}</p>
         </div>
       </div>
       <div
@@ -26,7 +26,7 @@
           style="text-align: left"
         >
           <div class="header">
-            <i class="info circle icon" /> Informations
+            <em class="info circle icon" /> Informations
           </div>
           <ul class="list">
             {{
@@ -91,7 +91,7 @@
     </div>
 
     <span v-else-if="!projectInfoLoading">
-      <i class="icon exclamation triangle" />
+      <em class="icon exclamation triangle" />
       <span>Vous ne disposez pas des droits nécessaires pour consulter ce
         projet.</span>
     </span>
diff --git a/src/views/Project/ProjectEdit.vue b/src/views/Project/ProjectEdit.vue
index 7301277187bed95a701420c1e63a3728e4871609..7e1a43f3b258c543a716d61bc9839475b64e3c1b 100644
--- a/src/views/Project/ProjectEdit.vue
+++ b/src/views/Project/ProjectEdit.vue
@@ -64,7 +64,7 @@
             class="ui icon button"
             for="thumbnail"
           >
-            <i class="file icon" />
+            <em class="file icon" />
             <span class="label">{{
               form.thumbnail_name ? form.thumbnail_name : fileToImport.name
             }}</span>
@@ -239,7 +239,7 @@
         class="ui teal icon button"
         @click="postForm"
       >
-        <i class="white save icon" /> Enregistrer les changements
+        <em class="white save icon" /> Enregistrer les changements
       </button>
     </form>
   </div>
diff --git a/src/views/Project/ProjectMembers.vue b/src/views/Project/ProjectMembers.vue
index 4d677888ebb8cc2465d53f78c7c6886321e62c99..41f117594bf94f9ac4de85f26f95f285e025c52d 100644
--- a/src/views/Project/ProjectMembers.vue
+++ b/src/views/Project/ProjectMembers.vue
@@ -49,7 +49,7 @@
         :disabled="!newMember.user.name"
         @click="addMember"
       >
-        <i class="white add icon" />
+        <em class="white add icon" />
         <span class="padding-1">Ajouter</span>
       </button>
     </div>
@@ -64,7 +64,7 @@
           <tr>
             <th>
               Membre
-              <i
+              <em
                 :class="{
                   down: isSortedAsc('member'),
                   up: isSortedDesc('member'),
@@ -75,7 +75,7 @@
             </th>
             <th>
               Niveau d'autorisation
-              <i
+              <em
                 :class="{
                   down: isSortedAsc('role'),
                   up: isSortedDesc('role'),
@@ -92,7 +92,7 @@
             :key="member.username"
           >
             <td>
-              {{ member.user.last_name }} {{ member.user.first_name }}<br><i>{{ member.user.username }}</i>
+              {{ member.user.last_name }} {{ member.user.first_name }}<br><em>{{ member.user.username }}</em>
             </td>
             <td>
               <div class="required field online">
@@ -108,7 +108,7 @@
                   data-tooltip="Retirer ce membre"
                   @click="removeMember(member)"
                 >
-                  <i class="times icon" />
+                  <em class="times icon" />
                 </button>
               </div>
             </td>
@@ -123,7 +123,7 @@
         class="ui teal icon button"
         @click="saveMembers"
       >
-        <i class="white save icon" />&nbsp;Enregistrer les changements
+        <em class="white save icon" />&nbsp;Enregistrer les changements
       </button>
     </div>
   </div>
diff --git a/src/views/Projects/ProjectsList.vue b/src/views/Projects/ProjectsList.vue
index e817ef18b74dd81cadf5f5f81a8f1578ae079e7c..41da0d7e04c15fe414708c0111a342cf2126a7ec 100644
--- a/src/views/Projects/ProjectsList.vue
+++ b/src/views/Projects/ProjectsList.vue
@@ -13,7 +13,7 @@
         :to="{ name: 'project_create', params: { action: 'create' } }"
         class="ui green basic button"
       >
-        <i class="plus icon" /> Créer un nouveau projet
+        <em class="plus icon" /> Créer un nouveau projet
       </router-link>
       <router-link
         v-if="user && user.can_create_project && isOnline"
@@ -22,7 +22,7 @@
         }"
         class="ui blue basic button"
       >
-        <i class="copy icon" /> Accéder à la liste des modèles de projets
+        <em class="copy icon" /> Accéder à la liste des modèles de projets
       </router-link>
     </div>
 
diff --git a/src/views/Projects/ProjectsTypes.vue b/src/views/Projects/ProjectsTypes.vue
index a11a898b7858765a6817a89464a0321b8e801547..30e644b9e71cad832e89f933abb31e720e49ba14 100644
--- a/src/views/Projects/ProjectsTypes.vue
+++ b/src/views/Projects/ProjectsTypes.vue
@@ -38,25 +38,25 @@
           </div>
           <div class="meta">
             <span data-tooltip="Délai avant archivage">
-              {{ project.archive_feature }}&nbsp;<i class="box icon" />
+              {{ project.archive_feature }}&nbsp;<em class="box icon" />
             </span>
             <span data-tooltip="Délai avant suppression">
-              {{ project.archive_feature }}&nbsp;<i
+              {{ project.archive_feature }}&nbsp;<em
                 class="trash alternate icon"
               />
             </span>
             <span data-tooltip="Date de création">
-              {{ project.created_on }}&nbsp;<i class="calendar icon" />
+              {{ project.created_on }}&nbsp;<em class="calendar icon" />
             </span>
           </div>
           <div class="meta">
             <span data-tooltip="Visibilité des signalement publiés">
-              {{ project.access_level_pub_feature }}&nbsp;<i
+              {{ project.access_level_pub_feature }}&nbsp;<em
                 class="eye icon"
               />
             </span>
             <span data-tooltip="Visibilité des signalement archivés">
-              {{ project.access_level_arch_feature }}&nbsp;<i
+              {{ project.access_level_arch_feature }}&nbsp;<em
                 class="archive icon"
               />
             </span>
@@ -100,7 +100,9 @@ export default {
 
   methods: {
     refreshId() {
-      return '?ver=' + Math.random();
+      const crypto = window.crypto || window.msCrypto;
+      var array = new Uint32Array(1);
+      return '?ver=' + crypto.getRandomValues(array); // Compliant for security-sensitive use cases
     },
   },
 };
diff --git a/src/views/feature/Feature_detail.vue b/src/views/feature/Feature_detail.vue
deleted file mode 100644
index 05bb5e28621fcd381efe032624c845f00497c8e3..0000000000000000000000000000000000000000
--- a/src/views/feature/Feature_detail.vue
+++ /dev/null
@@ -1,869 +0,0 @@
-<template>
-  <div v-frag>
-    <div class="row">
-      <div class="fourteen wide column">
-        <h1 class="ui header">
-          <div
-            v-if="feature"
-            class="content"
-          >
-            {{ feature.title || feature.feature_id }}
-            <div class="ui icon right floated compact buttons">
-              <router-link
-                v-if="permissions && permissions.can_create_feature"
-                :to="{
-                  name: 'ajouter-signalement',
-                  params: {
-                    slug_type_signal: $route.params.slug_type_signal,
-                  },
-                }"
-                class="ui button button-hover-orange"
-                data-tooltip="Ajouter un signalement"
-                data-position="bottom left"
-              >
-                <i class="plus fitted icon" />
-              </router-link>
-              <router-link
-                v-if="
-                  (permissions && permissions.can_update_feature) ||
-                    isFeatureCreator ||
-                    isModerator
-                "
-                :to="{
-                  name: 'editer-signalement',
-                  params: {
-                    slug_signal: $route.params.slug_signal,
-                    slug_type_signal: $route.params.slug_type_signal,
-                  },
-                }"
-                class="ui button button-hover-orange"
-              >
-                <i class="inverted grey pencil alternate icon" />
-              </router-link>
-              <a
-                v-if="((permissions && permissions.can_update_feature) || isFeatureCreator) && isOnline"
-                id="feature-delete"
-                class="ui button button-hover-red"
-                @click="isCanceling = true"
-              >
-                <i class="inverted grey trash alternate icon" />
-              </a>
-            </div>
-            <div class="ui hidden divider" />
-            <div class="sub header prewrap">
-              {{ feature.description }}
-            </div>
-          </div>
-        </h1>
-      </div>
-    </div>
-
-    <div v-if="!feature && !loader.isLoading">
-      Pas de signalement correspondant trouvé
-    </div>
-
-    <div class="row">
-      <div class="seven wide column">
-        <table
-          v-if="feature"
-          class="ui very basic table"
-        >
-          <tbody>
-            <tr v-if="feature_type">
-              <td>
-                <b> Type de signalement </b>
-              </td>
-              <td>
-                <router-link
-                  :to="{
-                    name: 'details-type-signalement',
-                    params: { feature_type_slug: feature_type.slug },
-                  }"
-                  class="feature-type-title"
-                >
-                  <img
-                    v-if="feature_type.geom_type === 'point'"
-                    class="list-image-type"
-                    src="@/assets/img/marker.png"
-                  >
-                  <img
-                    v-if="feature_type.geom_type === 'linestring'"
-                    class="list-image-type"
-                    src="@/assets/img/line.png"
-                  >
-                  <img
-                    v-if="feature_type.geom_type === 'polygon'"
-                    class="list-image-type"
-                    src="@/assets/img/polygon.png"
-                  >
-                  {{ feature_type.title }}
-                </router-link>
-              </td>
-            </tr>
-
-            <div
-              v-for="(field, index) in feature.feature_data"
-              :key="'field' + index"
-              v-frag
-            >
-              <tr v-if="field">
-                <td>
-                  <b>{{ field.label }}</b>
-                </td>
-                <td>
-                  <b>
-                    <i
-                      v-if="field.field_type === 'boolean'"
-                      :class="[
-                        'icon',
-                        field.value ? 'olive check' : 'grey times',
-                      ]"
-                    />
-                    <span v-else>
-                      {{ field.value }}
-                    </span>
-                  </b>
-                </td>
-              </tr>
-            </div>
-            <tr>
-              <td>Auteur</td>
-              <td>{{ feature.display_creator }}</td>
-            </tr>
-            <tr>
-              <td>Statut</td>
-              <td>
-                <i
-                  v-if="feature.status"
-                  :class="['icon', statusIcon]"
-                />
-                {{ statusLabel }}
-              </td>
-            </tr>
-            <tr>
-              <td>Date de création</td>
-              <td v-if="feature.created_on">
-                {{ feature.created_on | formatDate }}
-              </td>
-            </tr>
-            <tr>
-              <td>Date de dernière modification</td>
-              <td v-if="feature.updated_on">
-                {{ feature.updated_on | formatDate }}
-              </td>
-            </tr>
-          </tbody>
-        </table>
-
-        <h3 v-if="feature">
-          Liaison entre signalements
-        </h3>
-        <table
-          v-if="feature"
-          class="ui very basic table"
-        >
-          <tbody>
-            <tr
-              v-for="(link, index) in linked_features"
-              :key="link.feature_to.title + index"
-            >
-              <td v-if="link.feature_to.feature_type_slug">
-                {{ link.relation_type_display }}
-                <a
-                  class="pointer"
-                  @click="pushNgo(link)"
-                >{{ link.feature_to.title }} </a>
-                ({{ link.feature_to.display_creator }} -
-                {{ link.feature_to.created_on }})
-              </td>
-            </tr>
-          </tbody>
-        </table>
-      </div>
-
-      <div class="seven wide column">
-        <div
-          id="map"
-          ref="map"
-        />
-      </div>
-    </div>
-
-    <div
-      v-if="feature"
-      class="row"
-    >
-      <div
-        class="seven wide column"
-      >
-        <h2 class="ui header">
-          Pièces jointes
-        </h2>
-
-        <div
-          v-for="pj in attachments"
-          :key="pj.id"
-          class="ui divided items"
-        >
-          <div class="item">
-            <a
-              class="ui tiny image"
-              target="_blank"
-              :href="pj.attachment_file"
-            >
-              <img
-                :src="
-                  pj.extension === '.pdf'
-                    ? require('@/assets/img/pdf.png')
-                    : pj.attachment_file
-                "
-              >
-            </a>
-            <div class="middle aligned content">
-              <a
-                class="header"
-                target="_blank"
-                :href="pj.attachment_file"
-              >{{
-                pj.title
-              }}</a>
-              <div class="description">
-                {{ pj.info }}
-              </div>
-            </div>
-          </div>
-        </div>
-        <i
-          v-if="attachments.length === 0"
-        >Aucune pièce jointe associée au signalement.</i>
-      </div>
-
-      <div class="seven wide column">
-        <h2 class="ui header">
-          Activité et commentaires
-        </h2>
-
-        <div
-          id="feed-event"
-          class="ui feed"
-        >
-          <div
-            v-for="(event, index) in events"
-            :key="'event' + index"
-            v-frag
-          >
-            <div
-              v-if="event.event_type === 'create'"
-              v-frag
-            >
-              <div
-                v-if="event.object_type === 'feature'"
-                class="event"
-              >
-                <div class="content">
-                  <div class="summary">
-                    <div class="date">
-                      {{ event.created_on }}
-                    </div>
-                    Création du signalement
-                    <span v-if="user">par {{ event.display_user }}</span>
-                  </div>
-                </div>
-              </div>
-              <div
-                v-else-if="event.object_type === 'comment'"
-                class="event"
-              >
-                <div class="content">
-                  <div class="summary">
-                    <div class="date">
-                      {{ event.created_on }}
-                    </div>
-                    Commentaire
-                    <span v-if="user">par {{ event.display_user }}</span>
-                  </div>
-                  <div class="extra text">
-                    {{ event.related_comment.comment }}
-                    <div
-                      v-if="event.related_comment.attachment"
-                      v-frag
-                    >
-                      <br><a
-                        :href="
-                          DJANGO_BASE_URL +
-                            event.related_comment.attachment.url
-                        "
-                        target="_blank"
-                      ><i class="paperclip fitted icon" />
-                        {{ event.related_comment.attachment.title }}</a>
-                    </div>
-                  </div>
-                </div>
-              </div>
-            </div>
-            <div
-              v-else-if="event.event_type === 'update'"
-              class="event"
-            >
-              <div class="content">
-                <div class="summary">
-                  <div class="date">
-                    {{ event.created_on }}
-                  </div>
-                  Signalement mis à jour
-                  <span v-if="user">par {{ event.display_user }}</span>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-
-        <div
-          v-if="permissions && permissions.can_create_feature && isOnline"
-          class="ui segment"
-        >
-          <form
-            id="form-comment"
-            class="ui form"
-          >
-            <div class="required field">
-              <label
-                :for="comment_form.comment.id_for_label"
-              >Ajouter un commentaire</label>
-              <ul
-                v-if="comment_form.comment.errors"
-                class="errorlist"
-              >
-                <li>
-                  {{ comment_form.comment.errors }}
-                </li>
-              </ul>
-              <textarea
-                v-model="comment_form.comment.value"
-                :name="comment_form.comment.html_name"
-                rows="2"
-              />
-            </div>
-            <label>Pièce jointe (facultative)</label>
-            <div class="two fields">
-              <div class="field">
-                <label
-                  class="ui icon button"
-                  for="attachment_file"
-                >
-                  <i class="paperclip icon" />
-                  <span class="label">{{
-                    comment_form.attachment_file.value
-                      ? comment_form.attachment_file.value
-                      : "Sélectionner un fichier ..."
-                  }}</span>
-                </label>
-                <input
-                  id="attachment_file"
-                  type="file"
-                  accept="application/pdf, image/jpeg, image/png"
-                  style="display: none"
-                  name="attachment_file"
-                  @change="onFileChange"
-                >
-              </div>
-              <div class="field">
-                <input
-                  id="title"
-                  v-model="comment_form.attachment_file.title"
-                  type="text"
-                  name="title"
-                >
-                {{ comment_form.attachment_file.errors }}
-              </div>
-            </div>
-            <ul
-              v-if="comment_form.attachment_file.errors"
-              class="errorlist"
-            >
-              <li>
-                {{ comment_form.attachment_file.errors }}
-              </li>
-            </ul>
-            <button
-              type="button"
-              class="ui compact green icon button"
-              @click="postComment"
-            >
-              <i class="plus icon" /> Poster le commentaire
-            </button>
-          </form>
-        </div>
-      </div>
-    </div>
-
-    <div
-      v-if="isCanceling"
-      class="ui dimmer modals page transition visible active"
-      style="display: flex !important"
-    >
-      <div
-        :class="[
-          'ui mini modal subscription',
-          { 'active visible': isCanceling },
-        ]"
-      >
-        <i
-          class="close icon"
-          @click="isCanceling = false"
-        />
-        <div class="ui icon header">
-          <i class="trash alternate icon" />
-          Supprimer le signalement
-        </div>
-        <div class="actions">
-          <button
-            type="button"
-            class="ui red compact fluid button"
-            @click="deleteFeature"
-          >
-            Confirmer la suppression
-          </button>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import frag from 'vue-frag';
-import { mapGetters, mapState, mapActions, mapMutations } from 'vuex';
-import { formatStringDate } from '@/utils';
-import { mapUtil } from '@/assets/js/map-util.js';
-import featureAPI from '@/services/feature-api';
-import axios from '@/axios-client.js';
-
-export default {
-  name: 'FeatureDetail',
-
-  directives: {
-    frag,
-  },
-
-
-  filters: {
-    formatDate(value) {
-      return formatStringDate(value);
-    },
-  },
-
-  data() {
-    return {
-      attachments: [],
-      comment_form: {
-        attachment_file: {
-          errors: null,
-          title: '',
-          file: null,
-        },
-        comment: {
-          id_for_label: 'add-comment',
-          html_name: 'add-comment',
-          errors: '',
-          value: null,
-        },
-      },
-      events: [],
-      isCanceling: false,
-      projectSlug: this.$route.params.slug,
-    };
-  },
-
-  computed: {
-    ...mapState([
-      'user',
-      'USER_LEVEL_PROJECTS',
-      'isOnline',
-      'loader',
-    ]),
-    ...mapState('projects', [
-      'project'
-    ]),
-    ...mapGetters([
-      'permissions',
-    ]),
-    ...mapGetters('feature_type', [
-      'feature_type',
-    ]),
-    ...mapState('feature', {
-      linked_features: 'linked_features',
-      statusChoices: 'statusChoices',
-      feature: 'current_feature',
-    }),
-    DJANGO_BASE_URL() {
-      return this.$store.state.configuration.VUE_APP_DJANGO_BASE;
-    },
-
-    isFeatureCreator() {
-      if (this.feature && this.user) {
-        return this.feature.creator === this.user.id;
-      }
-      return false;
-    },
-
-    isModerator() {
-      return this.USER_LEVEL_PROJECTS && this.project &&
-        this.USER_LEVEL_PROJECTS[this.projectSlug] === 'Modérateur'
-        ? true
-        : false;
-    },
-
-    statusIcon() {
-      switch (this.feature.status) {
-      case 'archived':
-        return 'grey archive';
-      case 'pending':
-        return 'teal hourglass outline';
-      case 'published':
-        return 'olive check';
-      case 'draft':
-        return 'orange pencil alternate';
-      default:
-        return '';
-      }
-    },
-
-    statusLabel() {
-      const status = this.statusChoices.find(
-        (el) => el.value === this.feature.status
-      );
-      return status ? status.name : '';
-    },
-  },
-
-  created() {
-    this.$store.commit(
-      'feature_type/SET_CURRENT_FEATURE_TYPE_SLUG',
-      this.$route.params.slug_type_signal
-    );
-    this.getFeatureEvents();
-    this.getFeatureAttachments();
-    this.getLinkedFeatures();
-  },
-
-  mounted() {
-    this.DISPLAY_LOADER('Recherche du signalement');
-
-    if (!this.project) {
-      // Chargements des features et infos projet en cas d'arrivée directe sur la page ou de refresh
-      axios.all([
-        this.GET_PROJECT(this.$route.params.slug),
-        this.GET_PROJECT_INFO(this.$route.params.slug),
-        this.GET_PROJECT_FEATURE({
-          project_slug: this.$route.params.slug,
-          feature_id: this.$route.params.slug_signal
-        })])
-        .then(() => {
-          this.DISCARD_LOADER();
-          this.initMap();
-        })
-        .catch(() => this.DISCARD_LOADER());
-    } else if (!this.feature || this.feature.feature_id !== this.$route.params.slug_signal) {
-      this.GET_PROJECT_FEATURE({
-        project_slug: this.$route.params.slug,
-        feature_id: this.$route.params.slug_signal
-      })
-        .then(() => {
-          this.DISCARD_LOADER();
-          this.initMap();
-        })
-        .catch(() => this.DISCARD_LOADER());
-    } else {
-      this.DISCARD_LOADER();
-      this.initMap();
-    }
-  },
-
-  beforeDestroy() {
-    this.$store.commit('CLEAR_MESSAGES');
-  },
-
-  methods: {
-    ...mapMutations([
-      'DISCARD_LOADER',
-      'DISPLAY_LOADER',
-    ]),
-    ...mapActions('projects', [
-      'GET_PROJECT',
-      'GET_PROJECT_INFO'
-    ]),
-    ...mapActions('feature', [
-      'GET_PROJECT_FEATURES',
-      'GET_PROJECT_FEATURE'
-    ]),
-
-    pushNgo(link) {
-      this.DISPLAY_LOADER('Recherche du signalement');
-      this.$router.push({
-        name: 'details-signalement',
-        params: {
-          slug_type_signal: link.feature_to.feature_type_slug,
-          slug_signal: link.feature_to.feature_id,
-        },
-      });
-      this.GET_PROJECT_FEATURE({
-        project_slug: this.$route.params.slug,
-        feature_id: this.$route.params.slug_signal,
-      })
-        .then(()=> {
-          this.addFeatureToMap();
-          this.DISCARD_LOADER();
-        })
-        .catch(() => this.DISCARD_LOADER());
-      this.getFeatureEvents();
-      this.getFeatureAttachments();
-      this.getLinkedFeatures();
-    },
-
-    validateForm() {
-      this.comment_form.comment.errors = '';
-      if (!this.comment_form.comment.value) {
-        this.comment_form.comment.errors = 'Le commentaire ne peut pas être vide';
-        return false;
-      }
-      return true;
-    },
-
-    postComment() {
-      if (this.validateForm()) {
-        featureAPI
-          .postComment({
-            featureId: this.$route.params.slug_signal,
-            comment: this.comment_form.comment.value,
-          })
-          .then((response) => {
-            if (response && this.comment_form.attachment_file.file) {
-              featureAPI
-                .postCommentAttachment({
-                  featureId: this.$route.params.slug_signal,
-                  file: this.comment_form.attachment_file.file,
-                  fileName: this.comment_form.attachment_file.fileName,
-                  title: this.comment_form.attachment_file.title,
-                  commentId: response.data.id,
-                })
-                .then(() => {
-                  this.confirmComment();
-                });
-            } else {
-              this.confirmComment();
-            }
-          });
-      }
-    },
-
-    confirmComment() {
-      this.$store.commit('DISPLAY_MESSAGE', { comment: 'Ajout du commentaire confirmé', level: 'positive' });
-      this.getFeatureEvents(); //* display new comment on the page
-      this.comment_form.attachment_file.file = null;
-      this.comment_form.attachment_file.fileName = '';
-      this.comment_form.attachment_file.title = '';
-      this.comment_form.comment.value = null;
-    },
-
-    validateImgFile(files, handleFile) {
-      let url = window.URL || window.webkitURL;
-      let image = new Image();
-      image.onload = function () {
-        handleFile(true);
-        URL.revokeObjectURL(image.src);
-      };
-      image.onerror = function () {
-        handleFile(false);
-        URL.revokeObjectURL(image.src);
-      };
-      image.src = url.createObjectURL(files);
-    },
-
-    onFileChange(e) {
-      // * read image file
-      const files = e.target.files || e.dataTransfer.files;
-
-      const handleFile = (isValid) => {
-        if (isValid) {
-          this.comment_form.attachment_file.file = files[0]; //* store the file to post afterwards
-          let title = files[0].name;
-          this.comment_form.attachment_file.fileName = title; //* name of the file
-          const fileExtension = title.substring(title.lastIndexOf('.') + 1);
-          if ((title.length - fileExtension.length) > 11) {
-            title = title.slice(0, 10) + '[...].' + fileExtension;
-          }
-          this.comment_form.attachment_file.title = title; //* title for display
-          this.comment_form.attachment_file.errors = null;
-        } else {
-          this.comment_form.attachment_file.errors =
-            "Transférez une image valide. Le fichier que vous avez transféré n'est pas une image, ou il est corrompu.";
-        }
-      };
-
-      if (files.length) {
-        //* exception for pdf
-        if (files[0].type === 'application/pdf') {
-          handleFile(true);
-        } else {
-          this.comment_form.attachment_file.errors = null;
-          //* check if file is an image and pass callback to handle file
-          this.validateImgFile(files[0], handleFile);
-        }
-      }
-    },
-
-    goBackToProject(message) {
-      this.$router.push({
-        name: 'project_detail',
-        params: {
-          slug: this.$route.params.slug,
-          message,
-        },
-      });
-    },
-
-    deleteFeature() {
-      this.$store
-        .dispatch('feature/DELETE_FEATURE', { feature_id: this.feature.feature_id })
-        .then((response) => {
-          if (response.status === 204) {
-            this.GET_PROJECT_FEATURES({
-              project_slug: this.$route.params.slug
-            });
-            this.goBackToProject();
-          }
-        });
-    },
-
-    initMap() {
-      var mapDefaultViewCenter =
-        this.$store.state.configuration.DEFAULT_MAP_VIEW.center;
-      var mapDefaultViewZoom =
-        this.$store.state.configuration.DEFAULT_MAP_VIEW.zoom;
-      this.map = mapUtil.createMap(this.$refs.map, {
-        mapDefaultViewCenter,
-        mapDefaultViewZoom,
-      });
-
-      // Update link to feature list with map zoom and center
-      mapUtil.addMapEventListener('moveend', function () {
-        // update link to feature list with map zoom and center
-        /*var $featureListLink = $("#feature-list-link")
-        var baseUrl = $featureListLink.attr("href").split("?")[0]
-
-        $featureListLink.attr("href", baseUrl +`?zoom=${this.map.getZoom()}&lat=${this.map.getCenter().lat}&lng=${this.map.getCenter().lng}`)*/
-      });
-
-      // Load the layers.
-      // - if one basemap exists, we load the layers of the first one
-      // - if not, load the default map and service options
-      let layersToLoad = null;
-      var baseMaps = this.$store.state.map.basemaps;
-      var layers = this.$store.state.map.availableLayers;
-      if (baseMaps && baseMaps.length > 0) {
-        const basemapIndex = 0;
-        layersToLoad = baseMaps[basemapIndex].layers;
-        layersToLoad.forEach((layerToLoad) => {
-          layers.forEach((layer) => {
-            if (layer.id === layerToLoad.id) {
-              layerToLoad = Object.assign(layerToLoad, layer);
-            }
-          });
-        });
-        layersToLoad.reverse();
-      }
-      mapUtil.addLayers(
-        layersToLoad,
-        this.$store.state.configuration.DEFAULT_BASE_MAP_SERVICE,
-        this.$store.state.configuration.DEFAULT_BASE_MAP_OPTIONS,
-        this.$store.state.configuration.DEFAULT_BASE_MAP_SCHEMA_TYPE,
-      );
-
-      mapUtil.getMap().dragging.disable();
-      mapUtil.getMap().doubleClickZoom.disable();
-      mapUtil.getMap().scrollWheelZoom.disable();
-
-      this.addFeatureToMap();
-    },
-
-    addFeatureToMap() {
-      const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.$route.params.slug}/feature/` +
-                  `?feature_id=${this.$route.params.slug_signal}&output=geojson`;
-      axios
-        .get(url)
-        .then((response) => {
-          if (response.data.features.length > 0) {
-            const featureGroup = mapUtil.addFeatures(
-              response.data.features,
-              {},
-              true,
-              this.$store.state.feature_type.feature_types
-            );
-            mapUtil
-              .getMap()
-              .fitBounds(featureGroup.getBounds(), { padding: [25, 25] });
-          }
-        })
-        .catch((error) => {
-          throw error;
-        });
-    },
-
-    getFeatureEvents() {
-      featureAPI
-        .getFeatureEvents(this.$route.params.slug_signal)
-        .then((data) => (this.events = data))
-        .catch((err)=> console.error(err));
-    },
-
-    getFeatureAttachments() {
-      featureAPI
-        .getFeatureAttachments(this.$route.params.slug_signal)
-        .then((data) => (this.attachments = data))
-        .catch((err)=> console.error(err));
-    },
-
-    getLinkedFeatures() {
-      featureAPI
-        .getFeatureLinks(this.$route.params.slug_signal)
-        .then((data) =>
-          this.$store.commit('feature/SET_LINKED_FEATURES', data)
-        )
-        .catch((err)=> console.error(err));
-    },
-  },
-};
-</script>
-
-<style scoped>
-#map {
-  width: 100%;
-  height: 100%;
-  min-height: 250px;
-  max-height: 70vh;
-}
-#feed-event .event {
-  margin-bottom: 1em;
-}
-#feed-event .event .date {
-  margin-right: 1em !important;
-}
-#feed-event .event .extra.text {
-  margin-left: 107px;
-  margin-top: 0;
-}
-.prewrap {
-  white-space: pre-wrap;
-}
-.feature-type-title {
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-  line-height: 1.5em;
-}
-.list-image-type {
-  margin-right: 5px;
-  height: 25px;
-  vertical-align: bottom;
-  }
-</style>
\ No newline at end of file
diff --git a/src/views/project/Project_detail.vue b/src/views/project/Project_detail.vue
deleted file mode 100644
index 6de997ad6e2c2e671c01bb614d5534a879b482d4..0000000000000000000000000000000000000000
--- a/src/views/project/Project_detail.vue
+++ /dev/null
@@ -1,1442 +0,0 @@
-<template>
-  <div v-frag>
-    <div
-      v-if="permissions && permissions.can_view_project && project"
-      v-frag
-    >
-      <div
-        id="message"
-        class="fullwidth"
-      >
-        <div
-          v-if="tempMessage"
-          class="ui positive message"
-        >
-          <p><i class="check icon" /> {{ tempMessage }}</p>
-        </div>
-      </div>
-      <div
-        id="message_info"
-        class="fullwidth"
-      >
-        <div
-          v-if="infoMessage"
-          class="ui info message"
-          style="text-align: left"
-        >
-          <div class="header">
-            <i class="info circle icon" /> Informations
-          </div>
-          <ul class="list">
-            {{
-              infoMessage
-            }}
-          </ul>
-        </div>
-      </div>
-
-      <div class="row">
-        <div class="four wide middle aligned column">
-          <img
-            class="ui small spaced image"
-            :src="
-              project.thumbnail.includes('default')
-                ? require('@/assets/img/default.png')
-                : DJANGO_BASE_URL + project.thumbnail + refreshId()
-            "
-          >
-          <div class="ui hidden divider" />
-          <div
-            class="ui basic teal label"
-            data-tooltip="Membres"
-          >
-            <i class="user icon" />{{ project.nb_contributors }}
-          </div>
-          <div
-            class="ui basic teal label"
-            data-tooltip="Signalements publiés"
-          >
-            <i class="map marker icon" />{{ project.nb_published_features }}
-          </div>
-          <div
-            class="ui basic teal label"
-            data-tooltip="Commentaires"
-          >
-            <i class="comment icon" />{{
-              project.nb_published_features_comments
-            }}
-          </div>
-        </div>
-        <div class="ten wide column important-flex space-between">
-          <div>
-            <h1 class="ui header">
-              {{ project.title }}
-            </h1>
-            <div class="ui hidden divider" />
-            <div class="sub header">
-              {{ project.description }}
-            </div>
-          </div>
-
-          <div class="content flex flex-column-right">
-            <div class="flex flex-column-right">
-              <div class="ui icon right compact buttons flex-column-right">
-                <div>
-                  <a
-                    v-if="
-                      user &&
-                        permissions &&
-                        permissions.can_view_project &&
-                        isOnline
-                    "
-                    id="subscribe-button"
-                    class="ui button button-hover-green"
-                    data-tooltip="S'abonner au projet"
-                    data-position="top center"
-                    data-variation="mini"
-                    @click="modalType = 'subscribe'"
-                  >
-                    <i class="inverted grey envelope icon" />
-                  </a>
-                  <router-link
-                    v-if="
-                      permissions &&
-                        permissions.can_update_project &&
-                        isOnline
-                    "
-                    :to="{ name: 'project_edit', params: { slug } }"
-                    class="ui button button-hover-orange"
-                    data-tooltip="Modifier le projet"
-                    data-position="top center"
-                    data-variation="mini"
-                  >
-                    <i class="inverted grey pencil alternate icon" />
-                  </router-link>
-                  <a
-                    v-if="isProjectAdmin && isOnline"
-                    id="delete-button"
-                    class="ui button button-hover-red"
-                    data-tooltip="Supprimer le projet"
-                    data-position="top center"
-                    data-variation="mini"
-                    @click="modalType = 'deleteProject'"
-                  >
-                    <i class="inverted grey trash icon" />
-                  </a>
-                </div>
-                <button
-                  v-if="isProjectAdmin &&
-                    !isSharedProject && project.generate_share_link"
-                  class="ui teal left labeled icon button"
-                  @click="copyLink"
-                >
-                  <i class="left icon share square" />
-                  Copier le lien de partage
-                </button>
-              </div>
-              <div v-if="confirmMsg">
-                <div class="ui positive tiny-margin message">
-                  <span>
-                    Le lien a été copié dans le presse-papier
-                  </span>
-                  &nbsp;
-                  <i
-                    class="close icon"
-                    @click="confirmMsg = ''"
-                  />
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div v-if="arraysOffline.length > 0">
-          {{ arraysOffline.length }} modification<span v-if="arraysOffline.length>1">s</span> en attente
-          <button
-            :disabled="!isOnline"
-            class="ui fluid labeled teal icon button"
-            @click="sendOfflineFeatures"
-          >
-            <i class="upload icon" />
-            Envoyer au serveur
-          </button>
-        </div>
-      </div>
-
-      <div class="row">
-        <div class="seven wide column">
-          <h3 class="ui header">
-            Types de signalements
-          </h3>
-          <div class="ui middle aligned divided list">
-            <div
-              :class="{ active: projectInfoLoading }"
-              class="ui inverted dimmer"
-            >
-              <div class="ui text loader">
-                Récupération des types de signalements en cours...
-              </div>
-            </div>
-            <div
-              :class="{ active: featureTypeImporting }"
-              class="ui inverted dimmer"
-            >
-              <div class="ui text loader">
-                Traitement du fichier en cours ...
-              </div>
-            </div>
-            <div
-              v-for="(type, index) in feature_types"
-              :key="type.title + '-' + index"
-              class="item"
-            >
-              <div class="feature-type-container">
-                <router-link
-                  :to="{
-                    name: 'details-type-signalement',
-                    params: { feature_type_slug: type.slug },
-                  }"
-                  class="feature-type-title"
-                >
-                  <img
-                    v-if="type.geom_type === 'point'"
-                    class="list-image-type"
-                    src="@/assets/img/marker.png"
-                  >
-                  <img
-                    v-if="type.geom_type === 'linestring'"
-                    class="list-image-type"
-                    src="@/assets/img/line.png"
-                  >
-                  <img
-                    v-if="type.geom_type === 'polygon'"
-                    class="list-image-type"
-                    src="@/assets/img/polygon.png"
-                  >
-                  {{ type.title }}
-                </router-link>
-
-                <div class="middle aligned content">
-                  <router-link
-                    v-if="
-                      project && permissions && permissions.can_create_feature
-                    "
-                    :to="{
-                      name: 'ajouter-signalement',
-                      params: { slug_type_signal: type.slug },
-                    }"
-                    class="
-                      ui
-                      compact
-                      small
-                      icon
-                      right
-                      floated
-                      button button-hover-green
-                    "
-                    data-tooltip="Ajouter un signalement"
-                    data-position="top right"
-                    data-variation="mini"
-                  >
-                    <i class="ui plus icon" />
-                  </router-link>
-                  <router-link
-                    v-if="
-                      project &&
-                        permissions &&
-                        permissions.can_create_feature_type &&
-                        isOnline
-                    "
-                    :to="{
-                      name: 'dupliquer-type-signalement',
-                      params: { slug_type_signal: type.slug },
-                    }"
-                    class="
-                      ui
-                      compact
-                      small
-                      icon
-                      right
-                      floated
-                      button button-hover-green
-                    "
-                    data-tooltip="Dupliquer un type de signalement"
-                    data-position="top right"
-                    data-variation="mini"
-                  >
-                    <i class="inverted grey copy alternate icon" />
-                  </router-link>
-                  <div
-                    v-if="isImporting(type)"
-                    class="import-message"
-                  >
-                    <i class="info circle icon" />
-                    Import en cours
-                  </div>
-                  <div
-                    v-else
-                    v-frag
-                  >
-                    <a
-                      v-if="isProjectAdmin && isOnline"
-                      class="
-                        ui
-                        compact
-                        small
-                        icon
-                        right
-                        floated
-                        button button-hover-red
-                      "
-                      data-tooltip="Supprimer le type de signalement"
-                      data-position="top center"
-                      data-variation="mini"
-                      @click="toggleDeleteFeatureType(type)"
-                    >
-                      <i class="inverted grey trash alternate icon" />
-                    </a>
-                    <router-link
-                      v-if="
-                        project &&
-                          permissions &&
-                          permissions.can_create_feature_type &&
-                          isOnline
-                      "
-                      :to="{
-                        name: 'editer-symbologie-signalement',
-                        params: { slug_type_signal: type.slug },
-                      }"
-                      class="
-                        ui
-                        compact
-                        small
-                        icon
-                        right
-                        floated
-                        button button-hover-orange
-                      "
-                      data-tooltip="Éditer la symbologie du type de signalement"
-                      data-position="top center"
-                      data-variation="mini"
-                    >
-                      <i class="inverted grey paint brush alternate icon" />
-                    </router-link>
-                    <router-link
-                      v-if="
-                        project &&
-                          type.is_editable &&
-                          permissions &&
-                          permissions.can_create_feature_type &&
-                          isOnline
-                      "
-                      :to="{
-                        name: 'editer-type-signalement',
-                        params: { slug_type_signal: type.slug },
-                      }"
-                      class="
-                        ui
-                        compact
-                        small
-                        icon
-                        right
-                        floated
-                        button button-hover-orange
-                      "
-                      data-tooltip="Éditer le type de signalement"
-                      data-position="top center"
-                      data-variation="mini"
-                    >
-                      <i class="inverted grey pencil alternate icon" />
-                    </router-link>
-                  </div>
-                </div>
-              </div>
-            </div>
-            <div v-if="feature_types.length === 0">
-              <i> Le projet ne contient pas encore de type de signalements. </i>
-            </div>
-          </div>
-
-          <div id="nouveau-type-signalement">
-            <router-link
-              v-if="
-                permissions &&
-                  permissions.can_update_project &&
-                  isOnline
-              "
-              :to="{
-                name: 'ajouter-type-signalement',
-                params: { slug },
-              }"
-              class="ui compact basic button"
-            >
-              <i class="ui plus icon" />Créer un nouveau type de signalement
-            </router-link>
-          </div>
-
-          <div class="nouveau-type-signalement">
-            <div
-              v-if="
-                permissions &&
-                  permissions.can_update_project &&
-                  isOnline
-              "
-              class="
-                ui
-                compact
-                basic
-                button
-                button-align-left
-              "
-            >
-              <i class="ui plus icon" />
-              <label
-                class="ui"
-                for="json_file"
-              >
-                <span
-                  class="label"
-                >Créer un nouveau type de signalement à partir d'un
-                  GeoJSON</span>
-              </label>
-              <input
-                id="json_file"
-                type="file"
-                accept="application/json, .json, .geojson"
-                style="display: none"
-                name="json_file"
-                @change="onGeoJSONFileChange"
-              >
-            </div>
-          </div>
-
-          <div class="nouveau-type-signalement">
-            <div
-              v-if="
-                permissions &&
-                  permissions.can_update_project &&
-                  isOnline
-              "
-              class="
-                ui
-                compact
-                basic
-                button
-                button-align-left
-              "
-            >
-              <i class="ui plus icon" />
-              <label
-                class="ui"
-                for="csv_file"
-              >
-                <span
-                  class="label"
-                >Créer un nouveau type de signalement à partir d'un
-                  CSV</span>
-              </label>
-              <input
-                id="csv_file"
-                type="file"
-                accept="application/csv, .csv"
-                style="display: none"
-                name="csv_file"
-                @change="onCSVFileChange"
-              >
-            </div>
-          </div>
-
-          <div class="nouveau-type-signalement">
-            <router-link
-              v-if="
-                IDGO &&
-                  permissions &&
-                  permissions.can_update_project &&
-                  isOnline
-              "
-              :to="{
-                name: 'catalog-import',
-                params: {
-                  slug,
-                  feature_type_slug: 'create'
-                },
-              }"
-              class="ui compact basic button button-align-left"
-            >
-              <i class="ui plus icon" />
-              Créer un nouveau type de signalement à partir du catalogue {{ CATALOG_NAME|| 'IDGO' }}
-            </router-link>
-          </div>
-
-          <div
-            v-if="geojsonFileToImport.size > 0"
-            id="button-import"
-          >
-            <button
-              :disabled="geojsonFileToImport.size === 0"
-              class="ui fluid teal icon button"
-              @click="toNewGeojsonFeatureType"
-            >
-              <i class="upload icon" /> Lancer l'import avec le fichier
-              {{ geojsonFileToImport.name }}
-            </button>
-          </div>
-
-          <div
-            v-if="csvFileToImport.size > 0 && !csvError"
-            id="button-import"
-          >
-            <button
-              :disabled="csvFileToImport.size === 0"
-              class="ui fluid teal icon button"
-              @click="toNewCsvFeatureType"
-            >
-              <i class="upload icon" /> Lancer l'import avec le fichier
-              {{ csvFileToImport.name }}
-            </button>
-          </div>
-          <div
-            v-if="csvError"
-            class="ui negative message"
-          >
-            <i
-              class="close icon"
-              @click="csvError = null"
-            />
-            {{ csvError }}
-          </div>
-        </div>
-
-        <div
-          id="map-column"
-          class="seven wide column"
-        >
-          <div
-            :class="{ active: mapLoading }"
-            class="ui inverted dimmer"
-          >
-            <div class="ui text loader">
-              Chargement de la carte...
-            </div>
-          </div>
-          <div
-            id="map"
-            ref="map"
-          />
-          <div
-            class="ui button teal"
-            @click="$router.push({
-              name: 'liste-signalements',
-              params: { slug: slug },
-            })"
-          >
-            <i class="ui icon arrow right" />
-            Voir tous les signalements
-          </div>
-        </div>
-      </div>
-
-      <div class="row">
-        <div class="fourteen wide column">
-          <div class="ui two stackable cards">
-            <div class="red card">
-              <div class="content">
-                <div class="center aligned header">
-                  Derniers signalements
-                </div>
-                <div class="center aligned description">
-                  <div
-                    :class="{ active: featuresLoading }"
-                    class="ui inverted dimmer"
-                  >
-                    <div class="ui text loader">
-                      Récupération des signalements en cours...
-                    </div>
-                  </div>
-                  <div class="ui relaxed list">
-                    <div
-                      v-for="(item, index) in features.slice(-5)"
-                      :key="item.properties.title + index"
-                      class="item"
-                    >
-                      <div class="content">
-                        <div>
-                          <router-link
-                            :to="{
-                              name: 'details-signalement',
-                              params: {
-                                slug,
-                                slug_type_signal:
-                                  item.properties.feature_type.slug,
-                                slug_signal: item.id,
-                              },
-                            }"
-                          >
-                            {{ item.properties.title || item.id }}
-                          </router-link>
-                        </div>
-                        <div class="description">
-                          <i>
-                            [{{ item.properties.created_on }}
-                            <span v-if="user && item.properties.creator">
-                              , par
-                              {{
-                                item.properties.creator.full_name
-                                  ? item.properties.creator.full_name
-                                  : item.properties.creator.username
-                              }}
-                            </span>
-                            ]
-                          </i>
-                        </div>
-                      </div>
-                    </div>
-                    <i
-                      v-if="features.length === 0"
-                    >Aucun signalement pour le moment.</i>
-                  </div>
-                </div>
-              </div>
-            </div>
-            <div class="orange card">
-              <div class="content">
-                <div class="center aligned header">
-                  Derniers commentaires
-                </div>
-                <div class="center aligned description">
-                  <div
-                    :class="{ active: projectInfoLoading }"
-                    class="ui inverted dimmer"
-                  >
-                    <div class="ui text loader">
-                      Récupération des commentaires en cours...
-                    </div>
-                  </div>
-                  <div class="ui relaxed list">
-                    <div
-                      v-for="(item, index) in last_comments"
-                      :key="'comment ' + index"
-                      class="item"
-                    >
-                      <div class="content">
-                        <div>
-                          <router-link
-                            :to="getRouteUrl(item.related_feature.feature_url)"
-                          >
-                            "{{ item.comment }}"
-                          </router-link>
-                        </div>
-                        <div class="description">
-                          <i>[ {{ item.created_on
-                          }}<span
-                            v-if="user && item.display_author"
-                          >, par {{ item.display_author }}
-                          </span>
-                            ]</i>
-                        </div>
-                      </div>
-                    </div>
-                    <i
-                      v-if="!last_comments || last_comments.length === 0"
-                    >Aucun commentaire pour le moment.</i>
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-
-      <div class="row">
-        <div class="fourteen wide column">
-          <div class="ui grey segment">
-            <h3 class="ui header">
-              Paramètres du projet
-            </h3>
-            <div class="ui three stackable cards">
-              <!-- <div class="card">
-                <div class="center aligned content">
-                  <h4 class="ui center aligned icon header">
-                    <i class="disabled grey archive icon" />
-                    <div class="content">
-                      Délai avant archivage automatique
-                    </div>
-                  </h4>
-                </div>
-                <div class="center aligned extra content">
-                  {{ project.archive_feature }} jours
-                </div>
-              </div>
-              <div class="card">
-                <div class="content">
-                  <h4 class="ui center aligned icon header">
-                    <i class="disabled grey trash alternate icon" />
-                    <div class="content">
-                      Délai avant suppression automatique
-                    </div>
-                  </h4>
-                </div>
-                <div class="center aligned extra content">
-                  {{ project.delete_feature }} jours
-                </div>
-              </div> -->
-              <div class="card">
-                <div class="content">
-                  <h4 class="ui center aligned icon header">
-                    <i class="disabled grey eye icon" />
-                    <div class="content">
-                      Visibilité des signalements publiés
-                    </div>
-                  </h4>
-                </div>
-                <div class="center aligned extra content">
-                  {{ project.access_level_pub_feature }}
-                </div>
-              </div>
-              <div class="card">
-                <div class="content">
-                  <h4 class="ui center aligned icon header">
-                    <i class="disabled grey eye icon" />
-                    <div class="content">
-                      Visibilité des signalements archivés
-                    </div>
-                  </h4>
-                </div>
-                <div class="center aligned extra content">
-                  {{ project.access_level_arch_feature }}
-                </div>
-              </div>
-              <div class="card">
-                <div class="content">
-                  <h4 class="ui center aligned icon header">
-                    <i class="disabled grey cogs icon" />
-                    <div class="content">
-                      Modération
-                    </div>
-                  </h4>
-                </div>
-                <div class="center aligned extra content">
-                  {{ project.moderation ? "Oui" : "Non" }}
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-    <span v-else>
-      <i class="icon exclamation triangle" />
-      <span>Vous ne disposez pas des droits nécessaires pour consulter ce
-        projet.</span>
-    </span>
-
-    <div
-      v-if="modalType"
-      class="ui dimmer modals page transition visible active"
-      style="display: flex !important"
-    >
-      <div
-        :class="[
-          'ui mini modal subscription',
-          { 'transition visible active': modalType },
-        ]"
-      >
-        <i
-          class="close icon"
-          @click="modalType = false"
-        />
-        <div class="ui icon header">
-          <i :class="[modalType === 'subscribe' ? 'envelope' : 'trash', 'icon']" />
-          {{
-            modalType === 'subscribe' ? 'Notifications' : 'Suppression'
-          }} du {{
-            modalType === 'deleteFeatureType' ? 'type de signalement ' + featureTypeToDelete.title : 'projet'
-          }}
-        </div>
-        <div class="content">
-          <div v-if="modalType !== 'subscribe'">
-            <p class="centered-text">
-              Confirmez vous la suppression du {{
-                modalType === 'deleteProject' ?
-                  'projet, ainsi que les types de signalements' :
-                  'type de signalement'
-              }} et tous les signalements associés&nbsp;?
-            </p>
-            <p class="centered-text alert">
-              Attention cette action est irreversible !
-            </p>
-          </div>
-          <button
-            :class="['ui compact fluid button', modalType === 'subscribe' && !is_suscriber ? 'green' : 'red']"
-            @click="handleModalClick"
-          >
-            <span v-if="modalType === 'subscribe'">
-              {{
-                is_suscriber
-                  ? "Se désabonner de ce projet"
-                  : "S'abonner à ce projet"
-              }}
-            </span>
-            <span v-else>
-              Supprimer le 
-              {{
-                modalType === 'deleteProject'
-                  ? 'projet'
-                  : 'type de signalement'
-              }}
-            </span>
-          </button>
-        </div>
-      </div>
-    </div>
-    <div
-      :class="isFileSizeModalOpen ? 'active' : ''"
-      class="ui dimmer"
-    >
-      <div
-        :class="isFileSizeModalOpen ? 'active' : ''"
-        class="ui modal tiny"
-        style="top: 20%"
-      >
-        <div class="header">
-          Fichier trop grand!
-        </div>
-        <div class="content">
-          <p>
-            Impossible de créer un type de signalement à partir d'un fichier
-            GeoJSON de plus de 10Mo (celui importé fait {{ geojsonFileSize > 0 ? geojsonFileSize : csvFileSize }} Mo).
-          </p>
-        </div>
-        <div class="actions">
-          <div
-            class="ui button teal"
-            @click="closeFileSizeModal"
-          >
-            Fermer
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { featureCollection, point } from '@turf/helpers';
-import bbox from '@turf/bbox';
-import frag from 'vue-frag';
-import { mapUtil } from '@/assets/js/map-util.js';
-import { mapGetters, mapState, mapActions, mapMutations } from 'vuex';
-import projectAPI from '@/services/project-api';
-import featureTypeAPI from '@/services/featureType-api';
-import featureAPI from '@/services/feature-api';
-
-import { fileConvertSizeToMo, csvToJson } from '@/assets/js/utils';
-
-export default {
-  name: 'ProjectDetails',
-
-  directives: {
-    frag,
-  },
-
-  props: {
-    message: {
-      type: String,
-      default: ''
-    }
-  },
-
-  data() {
-    return {
-      infoMessage: '',
-      importMessage: null,
-      arraysOffline: [],
-      arraysOfflineErrors: [],
-      confirmMsg: false,
-      geojsonImport: [],
-      csvImport: null,
-      csvError: null,
-      geojsonFileToImport: { name: '', size: 0 },
-      csvFileToImport: { name: '', size: 0 },
-      slug: this.$route.params.slug,
-      modalType: false,
-      is_suscriber: false,
-      tempMessage: null,
-      projectInfoLoading: true,
-      featureTypeImporting: false,
-      featureTypeToDelete: null,
-      featuresLoading: true,
-      isFileSizeModalOpen: false,
-      mapLoading: true,
-    };
-  },
-
-  computed: {
-    ...mapGetters([
-      'permissions'
-    ]),
-    ...mapState('projects', [
-      'project'
-    ]),
-    ...mapState([
-      'configuration',
-      'isOnline',
-    ]),
-    ...mapState('feature_type', [
-      'feature_types',
-      'importFeatureTypeData'
-    ]),
-    ...mapState('feature', [
-      'features'
-    ]),
-    ...mapState([
-      'last_comments',
-      'user',
-      'user_permissions',
-      'reloadIntervalId',
-    ]),
-    ...mapState('map', [
-      'map'
-    ]),
-    DJANGO_BASE_URL() {
-      return this.configuration.VUE_APP_DJANGO_BASE;
-    },
-    API_BASE_URL() {
-      return this.configuration.VUE_APP_DJANGO_API_BASE;
-    },
-    CATALOG_NAME() {
-      return this.configuration.VUE_APP_CATALOG_NAME;
-    },
-    IDGO() {
-      return this.$store.state.configuration.VUE_APP_IDGO;
-    },
-    geojsonFileSize() {
-      return fileConvertSizeToMo(this.geojsonFileToImport.size);
-    },
-    csvFileSize() {
-      return fileConvertSizeToMo(this.csvFileToImport.size);
-    },
-    isSharedProject() {
-      return this.$route.path.includes('projet-partage');
-    },
-    isProjectAdmin() {
-      return this.user_permissions && this.user_permissions[this.slug] &&
-        this.user_permissions[this.slug].is_project_administrator;
-    },
-  },
-
-  watch: {
-    feature_types: {
-      deep: true,
-      handler(newValue, oldValue) {
-        if (newValue && newValue !== oldValue) {
-          this.GET_IMPORTS({
-            project_slug: this.$route.params.slug,
-          });
-        }
-      },
-    },
-
-    importFeatureTypeData: {
-      deep: true,
-      handler(newValue) {
-        if (
-          newValue &&
-          newValue.some((el) => el.status === 'pending') &&
-          !this.reloadIntervalId
-        ) {
-          this.SET_RELOAD_INTERVAL_ID(
-            setInterval(() => {
-              this.GET_IMPORTS({
-                project_slug: this.$route.params.slug,
-              });
-            }, this.$store.state.configuration.VUE_APP_RELOAD_INTERVAL)
-          );
-        } else if (
-          newValue &&
-          !newValue.some((el) => el.status === 'pending') &&
-          this.reloadIntervalId
-        ) {
-          this.GET_PROJECT_FEATURE_TYPES(this.slug);
-          this.CLEAR_RELOAD_INTERVAL_ID();
-        }
-      },
-    },
-  },
-
-  created() {
-    if (this.user) {
-      projectAPI
-        .getProjectSubscription({
-          baseUrl: this.$store.state.configuration.VUE_APP_DJANGO_API_BASE,
-          projectSlug: this.$route.params.slug
-        })
-        .then((data) => (this.is_suscriber = data.is_suscriber));
-    }
-    this.$store.commit('feature/SET_FEATURES', []); //* empty features remaining in case they were in geojson format and will be fetch after map initialization anyway
-    this.$store.commit('feature_type/SET_FEATURE_TYPES', []); //* empty feature_types remaining from previous project
-  },
-
-  mounted() {
-    this.retrieveProjectInfo();
-
-    if (this.message) {
-      this.tempMessage = this.message;
-      document
-        .getElementById('message')
-        .scrollIntoView({ block: 'end', inline: 'nearest' });
-      setTimeout(() => (this.tempMessage = null), 5000); //* hide message after 5 seconds
-    }
-  },
-
-  destroyed() {
-    this.CLEAR_RELOAD_INTERVAL_ID();
-  },
-
-  methods: {
-    ...mapMutations([
-      'SET_RELOAD_INTERVAL_ID',
-      'CLEAR_RELOAD_INTERVAL_ID',
-      'DISPLAY_MESSAGE',
-      'DISPLAY_LOADER',
-      'DISCARD_LOADER',
-    ]),
-    ...mapActions('projects', [
-      'GET_PROJECT_INFO',
-      'GET_PROJECT',
-    ]),
-    ...mapActions('map', [
-      'INITIATE_MAP'
-    ]),
-    ...mapActions('feature_type', [
-      'GET_IMPORTS'
-    ]),
-    ...mapActions('feature', [
-      'GET_PROJECT_FEATURES'
-    ]),
-    ...mapActions('feature_type', [
-      'GET_PROJECT_FEATURE_TYPES'
-    ]),
-    refreshId() {
-      return '?ver=' + Math.random();
-    },
-    getRouteUrl(url) {
-      if (this.isSharedProject) {
-        url = url.replace('projet', 'projet-partage');
-      }
-      return url.replace(this.$store.state.configuration.BASE_URL, ''); //* remove duplicate /geocontrib
-    },
-    isImporting(type) {
-      if (this.importFeatureTypeData) {
-        const singleImportData = this.importFeatureTypeData.find(
-          (el) => el.feature_type_title === type.slug
-        );
-        return singleImportData && singleImportData.status === 'pending';
-      }
-      return false;
-    },
-
-    copyLink() {
-      const sharedLink = window.location.href.replace('projet', 'projet-partage');
-      navigator.clipboard.writeText(sharedLink).then(()=> {
-        this.confirmMsg = true;
-      }, () => {
-        console.log('failed');
-      }
-      );
-    },
-
-    retrieveProjectInfo() {
-      this.DISPLAY_LOADER('Projet en cours de chargement.');
-      Promise.all([
-        this.GET_PROJECT(this.slug),
-        this.GET_PROJECT_INFO(this.slug)
-      ])
-        .then(() => {
-          this.DISCARD_LOADER();
-          this.projectInfoLoading = false;
-          setTimeout(() => {
-            let map = mapUtil.getMap();
-            if (map) map.remove();
-            this.initMap();
-          }, 1000);
-        })
-        .catch((err) => {
-          console.error(err);
-          this.DISCARD_LOADER();
-          this.projectInfoLoading = false;
-        });
-    },
-
-    checkForOfflineFeature() {
-      let arraysOffline = [];
-      const localStorageArray = localStorage.getItem('geocontrib_offline');
-      if (localStorageArray) {
-        arraysOffline = JSON.parse(localStorageArray);
-        this.arraysOffline = arraysOffline.filter(
-          (x) => x.project === this.slug
-        );
-      }
-    },
-
-    sendOfflineFeatures() {
-      this.arraysOfflineErrors = [];
-      const promises = this.arraysOffline.map((feature) => featureAPI.postOrPutFeature({
-        data: feature.geojson,
-        feature_id: feature.featureId,
-        project__slug: feature.project,
-        feature_type__slug: feature.geojson.properties.feature_type,
-        method: feature.type.toUpperCase(),
-      })
-        .then((response) => {
-          if (!response) this.arraysOfflineErrors.push(feature);
-        })
-        .catch((error) => {
-          console.error(error);
-          this.arraysOfflineErrors.push(feature);
-        })
-      );
-      this.DISPLAY_LOADER('Envoi des signalements en cours.');
-      Promise.all(promises).then(() => {
-        this.updateLocalStorage();
-        this.retrieveProjectInfo();
-      });
-    },
-
-    updateLocalStorage() {
-      let arraysOffline = [];
-      const localStorageArray = localStorage.getItem('geocontrib_offline');
-      if (localStorageArray) {
-        arraysOffline = JSON.parse(localStorageArray);
-      }
-      const arraysOfflineOtherProject = arraysOffline.filter(
-        (x) => x.project !== this.slug
-      );
-      this.arraysOffline = [];
-      arraysOffline = arraysOfflineOtherProject.concat(
-        this.arraysOfflineErrors
-      );
-      localStorage.setItem('geocontrib_offline', JSON.stringify(arraysOffline));
-    },
-
-    toNewGeojsonFeatureType() {
-      this.featureTypeImporting = true;
-      this.$router.push({
-        name: 'ajouter-type-signalement',
-        params: {
-          geojson: this.geojsonImport,
-          fileToImport: this.geojsonFileToImport,
-        },
-      });
-      this.featureTypeImporting = false;
-    },
-
-    toNewCsvFeatureType() {
-      this.featureTypeImporting = true;
-      this.$router.push({
-        name: 'ajouter-type-signalement',
-        params: {
-          csv: this.csvImport,
-          fileToImport: this.csvFileToImport,
-        },
-      });
-      this.featureTypeImporting = false;
-    },
-
-    onGeoJSONFileChange(e) {
-      this.featureTypeImporting = true;
-      var files = e.target.files || e.dataTransfer.files;
-      if (!files.length) return;
-      this.geojsonFileToImport = files[0];
-      // TODO : VALIDATION IF FILE IS JSON
-      if (parseFloat(fileConvertSizeToMo(this.geojsonFileToImport.size)) > 10) {
-        this.isFileSizeModalOpen = true;
-      } else if (this.geojsonFileToImport.size > 0) {
-        const fr = new FileReader();
-        try {
-          fr.onload = (e) => {
-            this.geojsonImport = JSON.parse(e.target.result);
-            this.featureTypeImporting = false;
-          };
-          fr.readAsText(this.geojsonFileToImport);
-          //* stock filename to import features afterward
-          this.$store.commit(
-            'feature_type/SET_FILE_TO_IMPORT',
-            this.geojsonFileToImport
-          );
-        } catch (err) {
-          console.error(err);
-          this.featureTypeImporting = false;
-        }
-      } else {
-        this.featureTypeImporting = false;
-      }
-    },
-
-    onCSVFileChange(e) {
-      this.featureTypeImporting = true;
-      var files = e.target.files || e.dataTransfer.files;
-      if (!files.length) return;
-      this.csvFileToImport = files[0];
-      if (parseFloat(fileConvertSizeToMo(this.csvFileToImport.size)) > 10) {
-        this.isFileSizeModalOpen = true;
-      } else if (this.csvFileToImport.size > 0) {
-        const fr = new FileReader();
-        try {
-          fr.readAsText(this.csvFileToImport);
-          fr.onloadend = () => {
-
-            // Check if file contains 'lat' and 'long' fields
-            const headersLine =
-              fr.result
-                .split('\n')[0]
-                .split(',')
-                .filter(el => {
-                  return el === 'lat' || el === 'lon';
-                });
-
-            // Look for 2 decimal fields in first line of csv
-            // corresponding to lon and lat
-            const sampleLine =
-              fr.result
-                .split('\n')[1]
-                .split(',')
-                .map(el => {
-                  return !isNaN(el) && el.indexOf('.') != -1;
-                })
-                .filter(Boolean);
-
-            if (sampleLine.length > 1 && headersLine.length === 2) {
-              this.csvError = null;
-              this.csvImport = csvToJson(fr.result);
-              this.featureTypeImporting = false;
-              //* stock filename to import features afterward
-              this.$store.commit(
-                'feature_type/SET_FILE_TO_IMPORT',
-                this.csvFileToImport
-              );
-            } else {
-              // File doesn't seem to contain coords
-              this.csvError = `Le fichier ${this.csvFileToImport.name} ne semble pas contenir de coordonnées`;
-              this.featureTypeImporting = false;
-            }
-          };
-        } catch (err) {
-          console.error(err);
-          this.featureTypeImporting = false;
-        }
-      } else {
-        this.featureTypeImporting = false;
-      }
-    },
-
-    closeFileSizeModal() {
-      this.geojsonFileToImport = { name: '', size: 0 };
-      this.csvFileToImport = { name: '', size: 0 };
-      this.featureTypeImporting = false;
-      this.isFileSizeModalOpen = false;
-    },
-
-    subscribeProject() {
-      projectAPI
-        .subscribeProject({
-          baseUrl: this.$store.state.configuration.VUE_APP_DJANGO_API_BASE,
-          suscribe: !this.is_suscriber,
-          projectSlug: this.$route.params.slug,
-        })
-        .then((data) => {
-          this.is_suscriber = data.is_suscriber;
-          this.modalType = false;
-          if (this.is_suscriber)
-            this.infoMessage =
-              'Vous êtes maintenant abonné aux notifications de ce projet.';
-          else
-            this.infoMessage =
-              'Vous ne recevrez plus les notifications de ce projet.';
-          setTimeout(() => (this.infoMessage = ''), 3000);
-        });
-    },
-
-    deleteProject() {
-      projectAPI.deleteProject(this.API_BASE_URL, this.slug)
-        .then((response) => {
-          if (response === 'success') {
-            this.$router.push('/');
-            this.DISPLAY_MESSAGE({
-              comment: `Le projet ${this.project.title} a bien été supprimé.`, level: 'positive'
-            });
-          } else {
-            this.DISPLAY_MESSAGE({
-              comment: `Une erreur est survenu lors de la suppression du projet ${this.project.title}.`,
-              level: 'negative'
-            });
-          }
-        });
-    },
-
-    deleteFeatureType() {
-      featureTypeAPI.deleteFeatureType(this.featureTypeToDelete.slug)
-        .then((response) => {
-          this.modalType = false;
-          if (response === 'success') {
-            this.retrieveProjectInfo();
-            this.DISPLAY_MESSAGE({
-              comment: `Le type de signalement ${this.featureTypeToDelete.title} a bien été supprimé.`,
-              level: 'positive',
-            });
-          } else {
-            this.DISPLAY_MESSAGE({
-              comment: `Une erreur est survenu lors de la suppression du type de signalement ${this.featureTypeToDelete.title}.`,
-              level: 'negative',
-            });
-          }
-          this.featureTypeToDelete = null;
-        });
-    },
-
-    handleModalClick() {
-      switch (this.modalType) {
-      case 'subscribe':
-        this.subscribeProject();
-        break;
-      case 'deleteProject':
-        this.deleteProject();
-        break;
-      case 'deleteFeatureType':
-        this.deleteFeatureType();
-        break;
-      }
-    },
-
-    toggleDeleteFeatureType(featureType) {
-      this.featureTypeToDelete = featureType;
-      this.modalType = 'deleteFeatureType';
-    },
-
-    async initMap() {
-      if (this.project && this.permissions.can_view_project) {
-        await this.INITIATE_MAP(this.$refs.map);
-        this.checkForOfflineFeature();
-        let project_id = this.$route.params.slug.split('-')[0];
-        const mvtUrl = `${this.API_BASE_URL}features.mvt/?tile={z}/{x}/{y}&project_id=${project_id}`;
-        mapUtil.addVectorTileLayer(
-          mvtUrl,
-          this.$route.params.slug,
-          this.feature_types
-        );
-        this.mapLoading = false;
-        const featuresOffline = this.arraysOffline.map((x) => {
-          return { ...x.geojson, overideColor: '#ff0000' }; //* red (hex format is better for perf)
-        });
-        this.featuresLoading = false;
-        mapUtil.addFeatures(
-          featuresOffline,
-          {},
-          true,
-          this.feature_types,
-          this.$route.params.slug,
-        );
-
-        featureAPI.getFeaturesBbox(this.slug).then((featuresBbox) => {
-          if (featuresBbox) {
-            if (featuresOffline.length > 0) {//* add offline features to BBOX with Turf
-              const allFeatures = [...featuresBbox.map((coordinates) => point(coordinates)), ...featuresOffline];
-              const featureCollect = featureCollection(allFeatures);
-              const newBbox = bbox(featureCollect);
-              if (newBbox) featuresBbox = [[newBbox[0], newBbox[1]], [newBbox[2], newBbox[3]]];
-            }
-            mapUtil.getMap().fitBounds(featuresBbox, { padding: [25, 25] });
-          }
-        });
-      }
-    },
-  },
-};
-</script>
-
-<style>
-
-#map-column {
-  display: flex;
-  flex-direction: column;
-}
-#map {
-  width: 100%;
-  height: 100%;
-  min-height: 250px;
-  margin-bottom: 1em;
-}
-/* // ! missing style in semantic.min.css, je ne comprends pas comment... */
-.ui.right.floated.button {
-  float: right;
-}
-</style>
-
-<style scoped>
-.list-image-type {
-  margin-right: 5px;
-  height: 25px;
-  vertical-align: bottom;
-}
-.feature-type-container {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-}
-
-.feature-type-container > .middle.aligned.content {
-  width: 50%;
-}
-
-.feature-type-title {
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-  line-height: 1.5em;
-}
-
-.nouveau-type-signalement {
-  margin-top: 1em;
-}
-.nouveau-type-signalement .label{
-  cursor: pointer;
-}
-
-#button-import {
-  margin-top: 0.5em;
-}
-.fullwidth {
-  width: 100%;
-}
-.button-align-left {
-  display: flex;
-  align-items: center;
-  text-align: left;
-  width: fit-content;
-}
-.space-between {
-  justify-content: space-between;
-}
-
-.flex-column-right {
-  flex-direction: column !important;
-  align-items: flex-end;
-}
-
-.import-message {
-  width: fit-content;
-  line-height: 2em;
-  color: teal;
-}
-</style>
-
-<style scoped>
-.ui.button, .ui.button .button, .tiny-margin {
-  margin:  0.1rem 0 0.1rem 0.1rem !important;
-}
-.alert {
-  color: red;
-}
-.centered-text {
-  text-align: center;
-}
-</style>