diff --git a/.eslintignore b/.eslintignore
deleted file mode 100644
index 7d1076afea1fb64ca5faf82d7f3571398707174a..0000000000000000000000000000000000000000
--- a/.eslintignore
+++ /dev/null
@@ -1,8 +0,0 @@
-.angular/
-.git/
-.idea/
-.vscode/
-build/
-coverage/
-dist/
-node_modules/
\ No newline at end of file
diff --git a/.eslintrc.json b/.eslintrc.json
deleted file mode 100644
index 9ba7297321c400ed682d6a466502ea05f5cdb4c1..0000000000000000000000000000000000000000
--- a/.eslintrc.json
+++ /dev/null
@@ -1,37 +0,0 @@
-{
-  "root": true,
-  "ignorePatterns": ["projects/**/*"],
-  "overrides": [
-    {
-      "files": ["*.ts"],
-      "parserOptions": {
-        "project": ["tsconfig.json"],
-        "createDefaultProgram": true
-      },
-      "extends": ["plugin:@angular-eslint/recommended", "plugin:@angular-eslint/template/process-inline-templates"],
-      "rules": {
-        "@angular-eslint/directive-selector": [
-          "error",
-          {
-            "type": "attribute",
-            "prefix": "app",
-            "style": "camelCase"
-          }
-        ],
-        "@angular-eslint/component-selector": [
-          "error",
-          {
-            "type": "element",
-            "prefix": "app",
-            "style": "kebab-case"
-          }
-        ]
-      }
-    },
-    {
-      "files": ["*.html"],
-      "extends": ["plugin:@angular-eslint/template/recommended"],
-      "rules": {}
-    }
-  ]
-}
diff --git a/.gitignore b/.gitignore
index 16d341382ee247137cbff20b0f45ab9a1b5d6aa6..b9bb85dc0036123bb380b6fee60b128d2f6b70de 100644
--- a/.gitignore
+++ b/.gitignore
@@ -54,5 +54,9 @@ api/db.json
 # Documentation generated with compodoc
 documentation
 
+CHANGELOG.md
+
+package-lock.json
+
 # External libs
 /projects
diff --git a/.prettierrc b/.prettierrc
index 154ffae7c56d124b37eb3ed98dcd465e9075f4a8..8d3dfb047c8c168b52ced5119a342a3ff2339806 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -1,20 +1,8 @@
 {
-  "printWidth": 128,
-  "tabWidth": 2,
+  "printWidth": 120,
+  "singleQuote": true,
   "useTabs": false,
+  "tabWidth": 2,
   "semi": true,
-  "singleQuote": true,
-  "quoteProps": "as-needed",
-  "jsxSingleQuote": true,
-  "trailingComma": "none",
-  "bracketSpacing": true,
-  "bracketSameLine": true,
-  "arrowParens": "always",
-  "requirePragma": false,
-  "insertPragma": false,
-  "proseWrap": "preserve",
-  "htmlWhitespaceSensitivity": "ignore",
-  "vueIndentScriptAndStyle": false,
-  "endOfLine": "lf",
-  "embeddedLanguageFormatting": "auto"
+  "bracketSpacing": true
 }
diff --git a/Dockerfile b/Dockerfile
index 0ff4ce3b51ae5254dc74edbc6da0bc7246a5a3b8..ed43a52e792b667e1a3e60c707bc8f8ddbabecfc 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -15,7 +15,6 @@ RUN npm install --silent
 COPY angular.json .
 COPY tsconfig.json .
 COPY tsconfig.app.json .
-COPY tsconfig.base.json .
 COPY ngsw-config.json .
 COPY /nginx/nginx.conf .
 COPY /src ./src
diff --git a/angular.json b/angular.json
index 65ced314becae9fee01332c27255dbb26eccb17d..432e248a537d676d6ff0607603719794c3a8acda 100644
--- a/angular.json
+++ b/angular.json
@@ -35,10 +35,7 @@
             "polyfills": "src/polyfills.ts",
             "tsConfig": "tsconfig.app.json",
             "localize": true,
-            "allowedCommonJsDependencies": [
-              "lodash",
-              "leaflet.locatecontrol"
-            ],
+            "allowedCommonJsDependencies": ["lodash", "leaflet.locatecontrol"],
             "assets": [
               "src/favicon.ico",
               "src/assets",
@@ -98,14 +95,10 @@
               "ngswConfigPath": "ngsw-config.json"
             },
             "fr": {
-              "localize": [
-                "fr"
-              ]
+              "localize": ["fr"]
             },
             "en": {
-              "localize": [
-                "en"
-              ]
+              "localize": ["en"]
             }
           },
           "defaultConfiguration": ""
@@ -141,14 +134,8 @@
             "polyfills": "src/polyfills.ts",
             "tsConfig": "tsconfig.spec.json",
             "karmaConfig": "karma.conf.js",
-            "assets": [
-              "src/favicon.ico",
-              "src/assets",
-              "src/manifest.webmanifest"
-            ],
-            "styles": [
-              "src/styles.scss"
-            ],
+            "assets": ["src/favicon.ico", "src/assets", "src/manifest.webmanifest"],
+            "styles": ["src/styles.scss"],
             "scripts": []
           }
         },
diff --git a/jest.config.js b/jest.config.js
deleted file mode 100644
index e307628da37491a44b858c4336f005f9f73174c7..0000000000000000000000000000000000000000
--- a/jest.config.js
+++ /dev/null
@@ -1,7 +0,0 @@
-module.exports = {
-  preset: 'jest-preset-angular',
-  setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
-  moduleNameMapper: {
-    '@gouvfr-anct/(.*)': '<rootDir>/dist/@gouvfr-anct/$1',
-  },
-};
diff --git a/jest.setup.ts b/jest.setup.ts
deleted file mode 100644
index dfd9199e4bd73c6535a527e79252e1a9c641d592..0000000000000000000000000000000000000000
--- a/jest.setup.ts
+++ /dev/null
@@ -1 +0,0 @@
-import 'jest-preset-angular/jest-preset';
diff --git a/package-lock.json b/package-lock.json
index 075d640612bf912ff00b8eea9c0f2ed03e20844e..3495f16125622b664b3dea65d77776a071dc05a7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -116,13 +116,6 @@
             }
           }
         },
-        "@esbuild/linux-loong64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.7.tgz",
-          "integrity": "sha512-IKznSJOsVUuyt7cDzzSZyqBEcZe+7WlBqTVXiF1OXP/4Nm387ToaXZ0fyLwI1iBlI/bzpxVq411QE2/Bt2XWWw==",
-          "dev": true,
-          "optional": true
-        },
         "@jest/environment": {
           "version": "28.1.3",
           "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz",
@@ -310,146 +303,6 @@
             "esbuild-windows-arm64": "0.15.7"
           }
         },
-        "esbuild-android-64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.7.tgz",
-          "integrity": "sha512-p7rCvdsldhxQr3YHxptf1Jcd86dlhvc3EQmQJaZzzuAxefO9PvcI0GLOa5nCWem1AJ8iMRu9w0r5TG8pHmbi9w==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-android-arm64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.7.tgz",
-          "integrity": "sha512-L775l9ynJT7rVqRM5vo+9w5g2ysbOCfsdLV4CWanTZ1k/9Jb3IYlQ06VCI1edhcosTYJRECQFJa3eAvkx72eyQ==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-darwin-64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.7.tgz",
-          "integrity": "sha512-KGPt3r1c9ww009t2xLB6Vk0YyNOXh7hbjZ3EecHoVDxgtbUlYstMPDaReimKe6eOEfyY4hBEEeTvKwPsiH5WZg==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-darwin-arm64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.7.tgz",
-          "integrity": "sha512-kBIHvtVqbSGajN88lYMnR3aIleH3ABZLLFLxwL2stiuIGAjGlQW741NxVTpUHQXUmPzxi6POqc9npkXa8AcSZQ==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-freebsd-64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.7.tgz",
-          "integrity": "sha512-hESZB91qDLV5MEwNxzMxPfbjAhOmtfsr9Wnuci7pY6TtEh4UDuevmGmkUIjX/b+e/k4tcNBMf7SRQ2mdNuK/HQ==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-freebsd-arm64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.7.tgz",
-          "integrity": "sha512-dLFR0ChH5t+b3J8w0fVKGvtwSLWCv7GYT2Y2jFGulF1L5HftQLzVGN+6pi1SivuiVSmTh28FwUhi9PwQicXI6Q==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-linux-32": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.7.tgz",
-          "integrity": "sha512-v3gT/LsONGUZcjbt2swrMjwxo32NJzk+7sAgtxhGx1+ZmOFaTRXBAi1PPfgpeo/J//Un2jIKm/I+qqeo4caJvg==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-linux-64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.7.tgz",
-          "integrity": "sha512-LxXEfLAKwOVmm1yecpMmWERBshl+Kv5YJ/1KnyAr6HRHFW8cxOEsEfisD3sVl/RvHyW//lhYUVSuy9jGEfIRAQ==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-linux-arm": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.7.tgz",
-          "integrity": "sha512-JKgAHtMR5f75wJTeuNQbyznZZa+pjiUHV7sRZp42UNdyXC6TiUYMW/8z8yIBAr2Fpad8hM1royZKQisqPABPvQ==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-linux-arm64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.7.tgz",
-          "integrity": "sha512-P3cfhudpzWDkglutWgXcT2S7Ft7o2e3YDMrP1n0z2dlbUZghUkKCyaWw0zhp4KxEEzt/E7lmrtRu/pGWnwb9vw==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-linux-mips64le": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.7.tgz",
-          "integrity": "sha512-T7XKuxl0VpeFLCJXub6U+iybiqh0kM/bWOTb4qcPyDDwNVhLUiPcGdG2/0S7F93czUZOKP57YiLV8YQewgLHKw==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-linux-ppc64le": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.7.tgz",
-          "integrity": "sha512-6mGuC19WpFN7NYbecMIJjeQgvDb5aMuvyk0PDYBJrqAEMkTwg3Z98kEKuCm6THHRnrgsdr7bp4SruSAxEM4eJw==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-linux-riscv64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.7.tgz",
-          "integrity": "sha512-uUJsezbswAYo/X7OU/P+PuL/EI9WzxsEQXDekfwpQ23uGiooxqoLFAPmXPcRAt941vjlY9jtITEEikWMBr+F/g==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-linux-s390x": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.7.tgz",
-          "integrity": "sha512-+tO+xOyTNMc34rXlSxK7aCwJgvQyffqEM5MMdNDEeMU3ss0S6wKvbBOQfgd5jRPblfwJ6b+bKiz0g5nABpY0QQ==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-netbsd-64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.7.tgz",
-          "integrity": "sha512-yVc4Wz+Pu3cP5hzm5kIygNPrjar/v5WCSoRmIjCPWfBVJkZNb5brEGKUlf+0Y759D48BCWa0WHrWXaNy0DULTQ==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-openbsd-64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.7.tgz",
-          "integrity": "sha512-GsimbwC4FSR4lN3wf8XmTQ+r8/0YSQo21rWDL0XFFhLHKlzEA4SsT1Tl8bPYu00IU6UWSJ+b3fG/8SB69rcuEQ==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-sunos-64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.7.tgz",
-          "integrity": "sha512-8CDI1aL/ts0mDGbWzjEOGKXnU7p3rDzggHSBtVryQzkSOsjCHRVe0iFYUuhczlxU1R3LN/E7HgUO4NXzGGP/Ag==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-windows-32": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.7.tgz",
-          "integrity": "sha512-cOnKXUEPS8EGCzRSFa1x6NQjGhGsFlVgjhqGEbLTPsA7x4RRYiy2RKoArNUU4iR2vHmzqS5Gr84MEumO/wxYKA==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-windows-64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.7.tgz",
-          "integrity": "sha512-7MI08Ec2sTIDv+zH6StNBKO+2hGUYIT42GmFyW6MBBWWtJhTcQLinKS6ldIN1d52MXIbiJ6nXyCJ+LpL4jBm3Q==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-windows-arm64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.7.tgz",
-          "integrity": "sha512-R06nmqBlWjKHddhRJYlqDd3Fabx9LFdKcjoOy08YLimwmsswlFBJV4rXzZCxz/b7ZJXvrZgj8DDv1ewE9+StMw==",
-          "dev": true,
-          "optional": true
-        },
         "escodegen": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz",
@@ -657,12 +510,6 @@
           "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
           "dev": true
         },
-        "slash": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
-          "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
-          "dev": true
-        },
         "source-map": {
           "version": "0.6.1",
           "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -865,29 +712,6 @@
         "webpack-subresource-integrity": "5.1.0"
       },
       "dependencies": {
-        "@angular-devkit/architect": {
-          "version": "0.1402.2",
-          "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.2.tgz",
-          "integrity": "sha512-ICcK7OKViMhLkj4btnH/8nv0wjxuKchT/LDN6jfb9gUYUuoon190q0/L/U6ORDwvmjD6sUTurStzOxjuiS0KIg==",
-          "dev": true,
-          "requires": {
-            "@angular-devkit/core": "14.2.2",
-            "rxjs": "6.6.7"
-          }
-        },
-        "@angular-devkit/core": {
-          "version": "14.2.2",
-          "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.2.tgz",
-          "integrity": "sha512-ofDhTmJqoAkmkJP0duwUaCxDBMxPlc+AWYwgs3rKKZeJBb0d+tchEXHXevD5bYbbRfXtnwM+Vye2XYHhA4nWAA==",
-          "dev": true,
-          "requires": {
-            "ajv": "8.11.0",
-            "ajv-formats": "2.1.1",
-            "jsonc-parser": "3.1.0",
-            "rxjs": "6.6.7",
-            "source-map": "0.7.4"
-          }
-        },
         "@babel/code-frame": {
           "version": "7.18.6",
           "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
@@ -1092,6 +916,13 @@
             "to-fast-properties": "^2.0.0"
           }
         },
+        "@esbuild/linux-loong64": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.5.tgz",
+          "integrity": "sha512-UHkDFCfSGTuXq08oQltXxSZmH1TXyWsL+4QhZDWvvLl6mEJQqk3u7/wq1LjhrrAXYIllaTtRSzUXl4Olkf2J8A==",
+          "dev": true,
+          "optional": true
+        },
         "@jridgewell/gen-mapping": {
           "version": "0.3.2",
           "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
@@ -1112,18 +943,6 @@
             "debug": "4"
           }
         },
-        "ajv": {
-          "version": "8.11.0",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
-          "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
-          "dev": true,
-          "requires": {
-            "fast-deep-equal": "^3.1.1",
-            "json-schema-traverse": "^1.0.0",
-            "require-from-string": "^2.0.2",
-            "uri-js": "^4.2.2"
-          }
-        },
         "ansi-colors": {
           "version": "4.1.3",
           "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
@@ -1169,6 +988,152 @@
             "esbuild-windows-arm64": "0.15.5"
           }
         },
+        "esbuild-android-64": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.5.tgz",
+          "integrity": "sha512-dYPPkiGNskvZqmIK29OPxolyY3tp+c47+Fsc2WYSOVjEPWNCHNyqhtFqQadcXMJDQt8eN0NMDukbyQgFcHquXg==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-android-arm64": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.5.tgz",
+          "integrity": "sha512-YyEkaQl08ze3cBzI/4Cm1S+rVh8HMOpCdq8B78JLbNFHhzi4NixVN93xDrHZLztlocEYqi45rHHCgA8kZFidFg==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-darwin-64": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.5.tgz",
+          "integrity": "sha512-Cr0iIqnWKx3ZTvDUAzG0H/u9dWjLE4c2gTtRLz4pqOBGjfjqdcZSfAObFzKTInLLSmD0ZV1I/mshhPoYSBMMCQ==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-darwin-arm64": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.5.tgz",
+          "integrity": "sha512-WIfQkocGtFrz7vCu44ypY5YmiFXpsxvz2xqwe688jFfSVCnUsCn2qkEVDo7gT8EpsLOz1J/OmqjExePL1dr1Kg==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-freebsd-64": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.5.tgz",
+          "integrity": "sha512-M5/EfzV2RsMd/wqwR18CELcenZ8+fFxQAAEO7TJKDmP3knhWSbD72ILzrXFMMwshlPAS1ShCZ90jsxkm+8FlaA==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-freebsd-arm64": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.5.tgz",
+          "integrity": "sha512-2JQQ5Qs9J0440F/n/aUBNvY6lTo4XP/4lt1TwDfHuo0DY3w5++anw+jTjfouLzbJmFFiwmX7SmUhMnysocx96w==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-linux-32": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.5.tgz",
+          "integrity": "sha512-gO9vNnIN0FTUGjvTFucIXtBSr1Woymmx/aHQtuU+2OllGU6YFLs99960UD4Dib1kFovVgs59MTXwpFdVoSMZoQ==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-linux-64": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.5.tgz",
+          "integrity": "sha512-ne0GFdNLsm4veXbTnYAWjbx3shpNKZJUd6XpNbKNUZaNllDZfYQt0/zRqOg0sc7O8GQ+PjSMv9IpIEULXVTVmg==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-linux-arm": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.5.tgz",
+          "integrity": "sha512-wvAoHEN+gJ/22gnvhZnS/+2H14HyAxM07m59RSLn3iXrQsdS518jnEWRBnJz3fR6BJa+VUTo0NxYjGaNt7RA7Q==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-linux-arm64": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.5.tgz",
+          "integrity": "sha512-7EgFyP2zjO065XTfdCxiXVEk+f83RQ1JsryN1X/VSX2li9rnHAt2swRbpoz5Vlrl6qjHrCmq5b6yxD13z6RheA==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-linux-mips64le": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.5.tgz",
+          "integrity": "sha512-KdnSkHxWrJ6Y40ABu+ipTZeRhFtc8dowGyFsZY5prsmMSr1ZTG9zQawguN4/tunJ0wy3+kD54GaGwdcpwWAvZQ==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-linux-ppc64le": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.5.tgz",
+          "integrity": "sha512-QdRHGeZ2ykl5P0KRmfGBZIHmqcwIsUKWmmpZTOq573jRWwmpfRmS7xOhmDHBj9pxv+6qRMH8tLr2fe+ZKQvCYw==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-linux-riscv64": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.5.tgz",
+          "integrity": "sha512-p+WE6RX+jNILsf+exR29DwgV6B73khEQV0qWUbzxaycxawZ8NE0wA6HnnTxbiw5f4Gx9sJDUBemh9v49lKOORA==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-linux-s390x": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.5.tgz",
+          "integrity": "sha512-J2ngOB4cNzmqLHh6TYMM/ips8aoZIuzxJnDdWutBw5482jGXiOzsPoEF4j2WJ2mGnm7FBCO4StGcwzOgic70JQ==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-netbsd-64": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.5.tgz",
+          "integrity": "sha512-MmKUYGDizYjFia0Rwt8oOgmiFH7zaYlsoQ3tIOfPxOqLssAsEgG0MUdRDm5lliqjiuoog8LyDu9srQk5YwWF3w==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-openbsd-64": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.5.tgz",
+          "integrity": "sha512-2mMFfkLk3oPWfopA9Plj4hyhqHNuGyp5KQyTT9Rc8hFd8wAn5ZrbJg+gNcLMo2yzf8Uiu0RT6G9B15YN9WQyMA==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-sunos-64": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.5.tgz",
+          "integrity": "sha512-2sIzhMUfLNoD+rdmV6AacilCHSxZIoGAU2oT7XmJ0lXcZWnCvCtObvO6D4puxX9YRE97GodciRGDLBaiC6x1SA==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-wasm": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.15.5.tgz",
+          "integrity": "sha512-lTJOEKekN/4JI/eOEq0wLcx53co2N6vaT/XjBz46D1tvIVoUEyM0o2K6txW6gEotf31szFD/J1PbxmnbkGlK9A==",
+          "dev": true
+        },
+        "esbuild-windows-32": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.5.tgz",
+          "integrity": "sha512-e+duNED9UBop7Vnlap6XKedA/53lIi12xv2ebeNS4gFmu7aKyTrok7DPIZyU5w/ftHD4MUDs5PJUkQPP9xJRzg==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-windows-64": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.5.tgz",
+          "integrity": "sha512-v+PjvNtSASHOjPDMIai9Yi+aP+Vwox+3WVdg2JB8N9aivJ7lyhp4NVU+J0MV2OkWFPnVO8AE/7xH+72ibUUEnw==",
+          "dev": true,
+          "optional": true
+        },
+        "esbuild-windows-arm64": {
+          "version": "0.15.5",
+          "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.5.tgz",
+          "integrity": "sha512-Yz8w/D8CUPYstvVQujByu6mlf48lKmXkq6bkeSZZxTA626efQOJb26aDGLzmFWx6eg/FwrXgt6SZs9V8Pwy/aA==",
+          "dev": true,
+          "optional": true
+        },
         "gensync": {
           "version": "1.0.0-beta.2",
           "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -1198,12 +1163,6 @@
             "debug": "4"
           }
         },
-        "json-schema-traverse": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
-          "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
-          "dev": true
-        },
         "json5": {
           "version": "2.2.1",
           "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
@@ -1252,9 +1211,9 @@
           }
         },
         "source-map": {
-          "version": "0.7.4",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
-          "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
           "dev": true
         },
         "source-map-support": {
@@ -1265,14 +1224,6 @@
           "requires": {
             "buffer-from": "^1.0.0",
             "source-map": "^0.6.0"
-          },
-          "dependencies": {
-            "source-map": {
-              "version": "0.6.1",
-              "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-              "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-              "dev": true
-            }
           }
         }
       }
@@ -1287,47 +1238,6 @@
         "rxjs": "6.6.7"
       },
       "dependencies": {
-        "@angular-devkit/architect": {
-          "version": "0.1402.2",
-          "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.2.tgz",
-          "integrity": "sha512-ICcK7OKViMhLkj4btnH/8nv0wjxuKchT/LDN6jfb9gUYUuoon190q0/L/U6ORDwvmjD6sUTurStzOxjuiS0KIg==",
-          "dev": true,
-          "requires": {
-            "@angular-devkit/core": "14.2.2",
-            "rxjs": "6.6.7"
-          }
-        },
-        "@angular-devkit/core": {
-          "version": "14.2.2",
-          "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.2.tgz",
-          "integrity": "sha512-ofDhTmJqoAkmkJP0duwUaCxDBMxPlc+AWYwgs3rKKZeJBb0d+tchEXHXevD5bYbbRfXtnwM+Vye2XYHhA4nWAA==",
-          "dev": true,
-          "requires": {
-            "ajv": "8.11.0",
-            "ajv-formats": "2.1.1",
-            "jsonc-parser": "3.1.0",
-            "rxjs": "6.6.7",
-            "source-map": "0.7.4"
-          }
-        },
-        "ajv": {
-          "version": "8.11.0",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
-          "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
-          "dev": true,
-          "requires": {
-            "fast-deep-equal": "^3.1.1",
-            "json-schema-traverse": "^1.0.0",
-            "require-from-string": "^2.0.2",
-            "uri-js": "^4.2.2"
-          }
-        },
-        "json-schema-traverse": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
-          "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
-          "dev": true
-        },
         "rxjs": {
           "version": "6.6.7",
           "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
@@ -1337,12 +1247,6 @@
             "tslib": "^1.9.0"
           }
         },
-        "source-map": {
-          "version": "0.7.4",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
-          "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
-          "dev": true
-        },
         "tslib": {
           "version": "1.14.1",
           "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@@ -1418,60 +1322,14 @@
         "rxjs": "6.6.7"
       },
       "dependencies": {
-        "@angular-devkit/core": {
-          "version": "14.2.2",
-          "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.2.tgz",
-          "integrity": "sha512-ofDhTmJqoAkmkJP0duwUaCxDBMxPlc+AWYwgs3rKKZeJBb0d+tchEXHXevD5bYbbRfXtnwM+Vye2XYHhA4nWAA==",
-          "dev": true,
-          "requires": {
-            "ajv": "8.11.0",
-            "ajv-formats": "2.1.1",
-            "jsonc-parser": "3.1.0",
-            "rxjs": "6.6.7",
-            "source-map": "0.7.4"
-          }
-        },
-        "ajv": {
-          "version": "8.11.0",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
-          "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
-          "dev": true,
-          "requires": {
-            "fast-deep-equal": "^3.1.1",
-            "json-schema-traverse": "^1.0.0",
-            "require-from-string": "^2.0.2",
-            "uri-js": "^4.2.2"
-          }
-        },
-        "json-schema-traverse": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
-          "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
-          "dev": true
-        },
-        "magic-string": {
-          "version": "0.26.2",
-          "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.2.tgz",
-          "integrity": "sha512-NzzlXpclt5zAbmo6h6jNc8zl2gNRGHvmsZW4IvZhTC4W7k4OlLP+S5YLussa/r3ixNT66KOQfNORlXHSOy/X4A==",
-          "dev": true,
-          "requires": {
-            "sourcemap-codec": "^1.4.8"
-          }
-        },
         "rxjs": {
           "version": "6.6.7",
           "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
           "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
           "dev": true,
-          "requires": {
-            "tslib": "^1.9.0"
-          }
-        },
-        "source-map": {
-          "version": "0.7.4",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
-          "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
-          "dev": true
+          "requires": {
+            "tslib": "^1.9.0"
+          }
         },
         "tslib": {
           "version": "1.14.1",
@@ -1603,12 +1461,6 @@
             "lru-cache": "^6.0.0"
           }
         },
-        "slash": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
-          "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
-          "dev": true
-        },
         "tslib": {
           "version": "1.14.1",
           "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@@ -1649,18 +1501,6 @@
             "@typescript-eslint/visitor-keys": "5.36.2"
           }
         },
-        "@typescript-eslint/type-utils": {
-          "version": "5.36.2",
-          "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.36.2.tgz",
-          "integrity": "sha512-rPQtS5rfijUWLouhy6UmyNquKDPhQjKsaKH0WnY6hl/07lasj8gPaH2UD8xWkePn6SC+jW2i9c2DZVDnL+Dokw==",
-          "dev": true,
-          "requires": {
-            "@typescript-eslint/typescript-estree": "5.36.2",
-            "@typescript-eslint/utils": "5.36.2",
-            "debug": "^4.3.4",
-            "tsutils": "^3.21.0"
-          }
-        },
         "@typescript-eslint/types": {
           "version": "5.36.2",
           "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.2.tgz",
@@ -1759,12 +1599,6 @@
             "lru-cache": "^6.0.0"
           }
         },
-        "slash": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
-          "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
-          "dev": true
-        },
         "tslib": {
           "version": "1.14.1",
           "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@@ -1922,12 +1756,6 @@
             "lru-cache": "^6.0.0"
           }
         },
-        "slash": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
-          "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
-          "dev": true
-        },
         "tslib": {
           "version": "1.14.1",
           "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@@ -2003,41 +1831,6 @@
         "yargs": "17.5.1"
       },
       "dependencies": {
-        "@angular-devkit/architect": {
-          "version": "0.1402.2",
-          "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.2.tgz",
-          "integrity": "sha512-ICcK7OKViMhLkj4btnH/8nv0wjxuKchT/LDN6jfb9gUYUuoon190q0/L/U6ORDwvmjD6sUTurStzOxjuiS0KIg==",
-          "dev": true,
-          "requires": {
-            "@angular-devkit/core": "14.2.2",
-            "rxjs": "6.6.7"
-          }
-        },
-        "@angular-devkit/core": {
-          "version": "14.2.2",
-          "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.2.tgz",
-          "integrity": "sha512-ofDhTmJqoAkmkJP0duwUaCxDBMxPlc+AWYwgs3rKKZeJBb0d+tchEXHXevD5bYbbRfXtnwM+Vye2XYHhA4nWAA==",
-          "dev": true,
-          "requires": {
-            "ajv": "8.11.0",
-            "ajv-formats": "2.1.1",
-            "jsonc-parser": "3.1.0",
-            "rxjs": "6.6.7",
-            "source-map": "0.7.4"
-          }
-        },
-        "ajv": {
-          "version": "8.11.0",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
-          "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
-          "dev": true,
-          "requires": {
-            "fast-deep-equal": "^3.1.1",
-            "json-schema-traverse": "^1.0.0",
-            "require-from-string": "^2.0.2",
-            "uri-js": "^4.2.2"
-          }
-        },
         "ansi-colors": {
           "version": "4.1.3",
           "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
@@ -2068,12 +1861,6 @@
             "has": "^1.0.3"
           }
         },
-        "json-schema-traverse": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
-          "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
-          "dev": true
-        },
         "resolve": {
           "version": "1.22.1",
           "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
@@ -2085,15 +1872,6 @@
             "supports-preserve-symlinks-flag": "^1.0.0"
           }
         },
-        "rxjs": {
-          "version": "6.6.7",
-          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
-          "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
-          "dev": true,
-          "requires": {
-            "tslib": "^1.9.0"
-          }
-        },
         "semver": {
           "version": "7.3.7",
           "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
@@ -2103,18 +1881,6 @@
             "lru-cache": "^6.0.0"
           }
         },
-        "source-map": {
-          "version": "0.7.4",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
-          "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
-          "dev": true
-        },
-        "tslib": {
-          "version": "1.14.1",
-          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
-          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
-          "dev": true
-        },
         "uuid": {
           "version": "8.3.2",
           "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
@@ -2389,15 +2155,6 @@
           "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
           "dev": true
         },
-        "magic-string": {
-          "version": "0.26.3",
-          "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.3.tgz",
-          "integrity": "sha512-u1Po0NDyFcwdg2nzHT88wSK0+Rih0N1M+Ph1Sp08k8yvFFU3KR72wryS7e1qMPJypt99WB7fIFVCA92mQrMjrg==",
-          "dev": true,
-          "requires": {
-            "sourcemap-codec": "^1.4.8"
-          }
-        },
         "y18n": {
           "version": "5.0.8",
           "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
@@ -3260,9 +3017,9 @@
           "dev": true
         },
         "regenerate-unicode-properties": {
-          "version": "10.0.1",
-          "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz",
-          "integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==",
+          "version": "10.1.0",
+          "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz",
+          "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==",
           "dev": true,
           "requires": {
             "regenerate": "^1.4.2"
@@ -3320,9 +3077,9 @@
           "dev": true
         },
         "unicode-property-aliases-ecmascript": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz",
-          "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==",
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz",
+          "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==",
           "dev": true
         }
       }
@@ -8537,13 +8294,6 @@
             "universalify": "^2.0.0"
           }
         },
-        "fsevents": {
-          "version": "2.3.2",
-          "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
-          "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
-          "dev": true,
-          "optional": true
-        },
         "gensync": {
           "version": "1.0.0-beta.2",
           "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -8685,7 +8435,7 @@
         "object-assign": "^4.1.1",
         "open": "8.2.1",
         "proxy-middleware": "^0.15.0",
-        "send": "^0.17.2",
+        "send": "^0.18.0",
         "serve-index": "^1.9.1"
       },
       "dependencies": {
@@ -8743,7 +8493,7 @@
             "ms": {
               "version": "2.0.0",
               "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-              "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+              "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
               "dev": true
             }
           }
@@ -8757,26 +8507,6 @@
             "websocket-driver": ">=0.5.1"
           }
         },
-        "fsevents": {
-          "version": "2.3.2",
-          "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
-          "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
-          "dev": true,
-          "optional": true
-        },
-        "http-errors": {
-          "version": "1.8.1",
-          "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
-          "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==",
-          "dev": true,
-          "requires": {
-            "depd": "~1.1.2",
-            "inherits": "2.0.4",
-            "setprototypeof": "1.2.0",
-            "statuses": ">= 1.5.0 < 2",
-            "toidentifier": "1.0.1"
-          }
-        },
         "ms": {
           "version": "2.1.3",
           "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -8786,7 +8516,7 @@
         "object-assign": {
           "version": "4.1.1",
           "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-          "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+          "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
           "dev": true
         },
         "open": {
@@ -8800,6 +8530,12 @@
             "is-wsl": "^2.2.0"
           }
         },
+        "proxy-middleware": {
+          "version": "0.15.0",
+          "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz",
+          "integrity": "sha512-EGCG8SeoIRVMhsqHQUdDigB2i7qU7fCsWASwn54+nPutYO8n4q6EiwMzyfWlC+dzRFExP+kvcnDFdBDHoZBU7Q==",
+          "dev": true
+        },
         "readdirp": {
           "version": "3.6.0",
           "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -8810,37 +8546,48 @@
           }
         },
         "send": {
-          "version": "0.17.2",
-          "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz",
-          "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==",
+          "version": "0.18.0",
+          "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
+          "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
           "dev": true,
           "requires": {
             "debug": "2.6.9",
-            "depd": "~1.1.2",
-            "destroy": "~1.0.4",
+            "depd": "2.0.0",
+            "destroy": "1.2.0",
             "encodeurl": "~1.0.2",
             "escape-html": "~1.0.3",
             "etag": "~1.8.1",
             "fresh": "0.5.2",
-            "http-errors": "1.8.1",
+            "http-errors": "2.0.0",
             "mime": "1.6.0",
             "ms": "2.1.3",
-            "on-finished": "~2.3.0",
+            "on-finished": "2.4.1",
             "range-parser": "~1.2.1",
-            "statuses": "~1.5.0"
+            "statuses": "2.0.1"
+          },
+          "dependencies": {
+            "depd": {
+              "version": "2.0.0",
+              "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+              "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+              "dev": true
+            },
+            "on-finished": {
+              "version": "2.4.1",
+              "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+              "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+              "dev": true,
+              "requires": {
+                "ee-first": "1.1.1"
+              }
+            },
+            "statuses": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+              "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+              "dev": true
+            }
           }
-        },
-        "setprototypeof": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
-          "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
-          "dev": true
-        },
-        "toidentifier": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
-          "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
-          "dev": true
         }
       }
     },
@@ -9038,9 +8785,9 @@
       "dev": true
     },
     "@esbuild/linux-loong64": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.5.tgz",
-      "integrity": "sha512-UHkDFCfSGTuXq08oQltXxSZmH1TXyWsL+4QhZDWvvLl6mEJQqk3u7/wq1LjhrrAXYIllaTtRSzUXl4Olkf2J8A==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.7.tgz",
+      "integrity": "sha512-IKznSJOsVUuyt7cDzzSZyqBEcZe+7WlBqTVXiF1OXP/4Nm387ToaXZ0fyLwI1iBlI/bzpxVq411QE2/Bt2XWWw==",
       "dev": true,
       "optional": true
     },
@@ -9172,21 +8919,6 @@
       "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
       "dev": true
     },
-    "@gouvfr-anct/mediation-numerique": {
-      "version": "0.0.17",
-      "resolved": "https://registry.npmjs.org/@gouvfr-anct/mediation-numerique/-/mediation-numerique-0.0.17.tgz",
-      "integrity": "sha512-b36izQpeYWs4Qhx0mA62g893/kTFvP031LJpW6KyhxRhwhifAIDZ59Oh6FS7hkjTE0pUwJ9fx6+1aCWjZmq33Q==",
-      "requires": {
-        "tslib": "^2.3.0"
-      },
-      "dependencies": {
-        "tslib": {
-          "version": "2.4.0",
-          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
-          "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
-        }
-      }
-    },
     "@humanwhocodes/config-array": {
       "version": "0.10.4",
       "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz",
@@ -10255,60 +9987,6 @@
         "@angular-devkit/core": "14.2.2",
         "@angular-devkit/schematics": "14.2.2",
         "jsonc-parser": "3.1.0"
-      },
-      "dependencies": {
-        "@angular-devkit/core": {
-          "version": "14.2.2",
-          "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.2.tgz",
-          "integrity": "sha512-ofDhTmJqoAkmkJP0duwUaCxDBMxPlc+AWYwgs3rKKZeJBb0d+tchEXHXevD5bYbbRfXtnwM+Vye2XYHhA4nWAA==",
-          "dev": true,
-          "requires": {
-            "ajv": "8.11.0",
-            "ajv-formats": "2.1.1",
-            "jsonc-parser": "3.1.0",
-            "rxjs": "6.6.7",
-            "source-map": "0.7.4"
-          }
-        },
-        "ajv": {
-          "version": "8.11.0",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
-          "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
-          "dev": true,
-          "requires": {
-            "fast-deep-equal": "^3.1.1",
-            "json-schema-traverse": "^1.0.0",
-            "require-from-string": "^2.0.2",
-            "uri-js": "^4.2.2"
-          }
-        },
-        "json-schema-traverse": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
-          "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
-          "dev": true
-        },
-        "rxjs": {
-          "version": "6.6.7",
-          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
-          "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
-          "dev": true,
-          "requires": {
-            "tslib": "^1.9.0"
-          }
-        },
-        "source-map": {
-          "version": "0.7.4",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
-          "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
-          "dev": true
-        },
-        "tslib": {
-          "version": "1.14.1",
-          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
-          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
-          "dev": true
-        }
       }
     },
     "@sinclair/typebox": {
@@ -10526,9 +10204,9 @@
       "dev": true
     },
     "@types/express": {
-      "version": "4.17.13",
-      "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz",
-      "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==",
+      "version": "4.17.14",
+      "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz",
+      "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==",
       "dev": true,
       "requires": {
         "@types/body-parser": "*",
@@ -10538,9 +10216,9 @@
       }
     },
     "@types/express-serve-static-core": {
-      "version": "4.17.30",
-      "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.30.tgz",
-      "integrity": "sha512-gstzbTWro2/nFed1WXtf+TtrpwxH7Ggs4RLYTLbeVgIkUQOI3WG/JKjgeOU1zXDvezllupjrf8OPIdvTbIaVOQ==",
+      "version": "4.17.31",
+      "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz",
+      "integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==",
       "dev": true,
       "requires": {
         "@types/node": "*",
@@ -10611,16 +10289,6 @@
         "@types/jasmine": "*"
       }
     },
-    "@types/jest": {
-      "version": "27.5.1",
-      "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.1.tgz",
-      "integrity": "sha512-fUy7YRpT+rHXto1YlL+J9rs0uLGyiqVt3ZOTQR+4ROc47yNl8WLdVLgUloBRhOxP1PZvguHl44T3H0wAWxahYQ==",
-      "dev": true,
-      "requires": {
-        "jest-matcher-utils": "^27.0.0",
-        "pretty-format": "^27.0.0"
-      }
-    },
     "@types/jsdom": {
       "version": "16.2.15",
       "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-16.2.15.tgz",
@@ -10828,6 +10496,18 @@
             "@typescript-eslint/visitor-keys": "5.37.0"
           }
         },
+        "@typescript-eslint/type-utils": {
+          "version": "5.37.0",
+          "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.37.0.tgz",
+          "integrity": "sha512-BSx/O0Z0SXOF5tY0bNTBcDEKz2Ec20GVYvq/H/XNKiUorUFilH7NPbFUuiiyzWaSdN3PA8JV0OvYx0gH/5aFAQ==",
+          "dev": true,
+          "requires": {
+            "@typescript-eslint/typescript-estree": "5.37.0",
+            "@typescript-eslint/utils": "5.37.0",
+            "debug": "^4.3.4",
+            "tsutils": "^3.21.0"
+          }
+        },
         "@typescript-eslint/types": {
           "version": "5.37.0",
           "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.37.0.tgz",
@@ -10914,12 +10594,6 @@
             "lru-cache": "^6.0.0"
           }
         },
-        "slash": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
-          "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
-          "dev": true
-        },
         "tslib": {
           "version": "1.14.1",
           "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@@ -11031,12 +10705,6 @@
             "lru-cache": "^6.0.0"
           }
         },
-        "slash": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
-          "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
-          "dev": true
-        },
         "tslib": {
           "version": "1.14.1",
           "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@@ -11065,41 +10733,41 @@
       }
     },
     "@typescript-eslint/type-utils": {
-      "version": "5.37.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.37.0.tgz",
-      "integrity": "sha512-BSx/O0Z0SXOF5tY0bNTBcDEKz2Ec20GVYvq/H/XNKiUorUFilH7NPbFUuiiyzWaSdN3PA8JV0OvYx0gH/5aFAQ==",
+      "version": "5.36.2",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.36.2.tgz",
+      "integrity": "sha512-rPQtS5rfijUWLouhy6UmyNquKDPhQjKsaKH0WnY6hl/07lasj8gPaH2UD8xWkePn6SC+jW2i9c2DZVDnL+Dokw==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/typescript-estree": "5.37.0",
-        "@typescript-eslint/utils": "5.37.0",
+        "@typescript-eslint/typescript-estree": "5.36.2",
+        "@typescript-eslint/utils": "5.36.2",
         "debug": "^4.3.4",
         "tsutils": "^3.21.0"
       },
       "dependencies": {
         "@typescript-eslint/scope-manager": {
-          "version": "5.37.0",
-          "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.37.0.tgz",
-          "integrity": "sha512-F67MqrmSXGd/eZnujjtkPgBQzgespu/iCZ+54Ok9X5tALb9L2v3G+QBSoWkXG0p3lcTJsL+iXz5eLUEdSiJU9Q==",
+          "version": "5.36.2",
+          "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.2.tgz",
+          "integrity": "sha512-cNNP51L8SkIFSfce8B1NSUBTJTu2Ts4nWeWbFrdaqjmn9yKrAaJUBHkyTZc0cL06OFHpb+JZq5AUHROS398Orw==",
           "dev": true,
           "requires": {
-            "@typescript-eslint/types": "5.37.0",
-            "@typescript-eslint/visitor-keys": "5.37.0"
+            "@typescript-eslint/types": "5.36.2",
+            "@typescript-eslint/visitor-keys": "5.36.2"
           }
         },
         "@typescript-eslint/types": {
-          "version": "5.37.0",
-          "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.37.0.tgz",
-          "integrity": "sha512-3frIJiTa5+tCb2iqR/bf7XwU20lnU05r/sgPJnRpwvfZaqCJBrl8Q/mw9vr3NrNdB/XtVyMA0eppRMMBqdJ1bA==",
+          "version": "5.36.2",
+          "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.2.tgz",
+          "integrity": "sha512-9OJSvvwuF1L5eS2EQgFUbECb99F0mwq501w0H0EkYULkhFa19Qq7WFbycdw1PexAc929asupbZcgjVIe6OK/XQ==",
           "dev": true
         },
         "@typescript-eslint/typescript-estree": {
-          "version": "5.37.0",
-          "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.37.0.tgz",
-          "integrity": "sha512-JkFoFIt/cx59iqEDSgIGnQpCTRv96MQnXCYvJi7QhBC24uyuzbD8wVbajMB1b9x4I0octYFJ3OwjAwNqk1AjDA==",
+          "version": "5.36.2",
+          "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.2.tgz",
+          "integrity": "sha512-8fyH+RfbKc0mTspfuEjlfqA4YywcwQK2Amcf6TDOwaRLg7Vwdu4bZzyvBZp4bjt1RRjQ5MDnOZahxMrt2l5v9w==",
           "dev": true,
           "requires": {
-            "@typescript-eslint/types": "5.37.0",
-            "@typescript-eslint/visitor-keys": "5.37.0",
+            "@typescript-eslint/types": "5.36.2",
+            "@typescript-eslint/visitor-keys": "5.36.2",
             "debug": "^4.3.4",
             "globby": "^11.1.0",
             "is-glob": "^4.0.3",
@@ -11108,26 +10776,26 @@
           }
         },
         "@typescript-eslint/utils": {
-          "version": "5.37.0",
-          "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.37.0.tgz",
-          "integrity": "sha512-jUEJoQrWbZhmikbcWSMDuUSxEE7ID2W/QCV/uz10WtQqfOuKZUqFGjqLJ+qhDd17rjgp+QJPqTdPIBWwoob2NQ==",
+          "version": "5.36.2",
+          "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.36.2.tgz",
+          "integrity": "sha512-uNcopWonEITX96v9pefk9DC1bWMdkweeSsewJ6GeC7L6j2t0SJywisgkr9wUTtXk90fi2Eljj90HSHm3OGdGRg==",
           "dev": true,
           "requires": {
             "@types/json-schema": "^7.0.9",
-            "@typescript-eslint/scope-manager": "5.37.0",
-            "@typescript-eslint/types": "5.37.0",
-            "@typescript-eslint/typescript-estree": "5.37.0",
+            "@typescript-eslint/scope-manager": "5.36.2",
+            "@typescript-eslint/types": "5.36.2",
+            "@typescript-eslint/typescript-estree": "5.36.2",
             "eslint-scope": "^5.1.1",
             "eslint-utils": "^3.0.0"
           }
         },
         "@typescript-eslint/visitor-keys": {
-          "version": "5.37.0",
-          "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.37.0.tgz",
-          "integrity": "sha512-Hp7rT4cENBPIzMwrlehLW/28EVCOcE9U1Z1BQTc8EA8v5qpr7GRGuG+U58V5tTY48zvUOA3KHvw3rA8tY9fbdA==",
+          "version": "5.36.2",
+          "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.2.tgz",
+          "integrity": "sha512-BtRvSR6dEdrNt7Net2/XDjbYKU5Ml6GqJgVfXT0CxTCJlnIqK7rAGreuWKMT2t8cFUT2Msv5oxw0GMRD7T5J7A==",
           "dev": true,
           "requires": {
-            "@typescript-eslint/types": "5.37.0",
+            "@typescript-eslint/types": "5.36.2",
             "eslint-visitor-keys": "^3.3.0"
           }
         },
@@ -11172,12 +10840,6 @@
             "lru-cache": "^6.0.0"
           }
         },
-        "slash": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
-          "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
-          "dev": true
-        },
         "tslib": {
           "version": "1.14.1",
           "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@@ -11674,9 +11336,9 @@
       },
       "dependencies": {
         "ajv": {
-          "version": "8.8.2",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz",
-          "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==",
+          "version": "8.11.0",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
+          "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
           "dev": true,
           "requires": {
             "fast-deep-equal": "^3.1.1",
@@ -11959,9 +11621,9 @@
       "dev": true
     },
     "async": {
-      "version": "2.6.4",
-      "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
-      "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
+      "version": "2.6.3",
+      "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
+      "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
       "dev": true,
       "requires": {
         "lodash": "^4.17.14"
@@ -11986,13 +11648,13 @@
       "dev": true
     },
     "autoprefixer": {
-      "version": "10.4.9",
-      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.9.tgz",
-      "integrity": "sha512-Uu67eduPEmOeA0vyJby5ghu1AAELCCNSsLAjK+lz6kYzNM5sqnBO36MqfsjhPjQF/BaJM5U/UuFYyl7PavY/wQ==",
+      "version": "10.4.10",
+      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.10.tgz",
+      "integrity": "sha512-nMaiDARyp1e74c8IeAXkr+BmFKa8By4Zak7tyaNPF09Iu39WFpNXOWrVirmXjKr+5cOyERwvtbMOLYz6iBJYgQ==",
       "dev": true,
       "requires": {
         "browserslist": "^4.21.3",
-        "caniuse-lite": "^1.0.30001394",
+        "caniuse-lite": "^1.0.30001399",
         "fraction.js": "^4.2.0",
         "normalize-range": "^0.1.2",
         "picocolors": "^1.0.0",
@@ -12413,12 +12075,6 @@
           "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
           "dev": true
         },
-        "destroy": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
-          "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
-          "dev": true
-        },
         "ms": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -13606,9 +13262,9 @@
       }
     },
     "cookie": {
-      "version": "0.4.2",
-      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
-      "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
+      "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
       "dev": true
     },
     "cookie-signature": {
@@ -14215,9 +13871,9 @@
       "dev": true
     },
     "destroy": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
-      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+      "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
       "dev": true
     },
     "detect-indent": {
@@ -14441,9 +14097,9 @@
       }
     },
     "electron-to-chromium": {
-      "version": "1.4.248",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.248.tgz",
-      "integrity": "sha512-qShjzEYpa57NnhbW2K+g+Fl+eNoDvQ7I+2MRwWnU6Z6F0HhXekzsECCLv+y2OJUsRodjqoSfwHkIX42VUFtUzg==",
+      "version": "1.4.249",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.249.tgz",
+      "integrity": "sha512-GMCxR3p2HQvIw47A599crTKYZprqihoBL4lDSAUmr7IYekXFK5t/WgEBrGJDCa2HWIZFQEkGuMqPCi05ceYqPQ==",
       "dev": true
     },
     "emittery": {
@@ -14513,6 +14169,12 @@
         "ws": "~8.2.3"
       },
       "dependencies": {
+        "cookie": {
+          "version": "0.4.2",
+          "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
+          "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
+          "dev": true
+        },
         "debug": {
           "version": "4.3.4",
           "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -14722,148 +14384,148 @@
       }
     },
     "esbuild-android-64": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.5.tgz",
-      "integrity": "sha512-dYPPkiGNskvZqmIK29OPxolyY3tp+c47+Fsc2WYSOVjEPWNCHNyqhtFqQadcXMJDQt8eN0NMDukbyQgFcHquXg==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.7.tgz",
+      "integrity": "sha512-p7rCvdsldhxQr3YHxptf1Jcd86dlhvc3EQmQJaZzzuAxefO9PvcI0GLOa5nCWem1AJ8iMRu9w0r5TG8pHmbi9w==",
       "dev": true,
       "optional": true
     },
     "esbuild-android-arm64": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.5.tgz",
-      "integrity": "sha512-YyEkaQl08ze3cBzI/4Cm1S+rVh8HMOpCdq8B78JLbNFHhzi4NixVN93xDrHZLztlocEYqi45rHHCgA8kZFidFg==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.7.tgz",
+      "integrity": "sha512-L775l9ynJT7rVqRM5vo+9w5g2ysbOCfsdLV4CWanTZ1k/9Jb3IYlQ06VCI1edhcosTYJRECQFJa3eAvkx72eyQ==",
       "dev": true,
       "optional": true
     },
     "esbuild-darwin-64": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.5.tgz",
-      "integrity": "sha512-Cr0iIqnWKx3ZTvDUAzG0H/u9dWjLE4c2gTtRLz4pqOBGjfjqdcZSfAObFzKTInLLSmD0ZV1I/mshhPoYSBMMCQ==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.7.tgz",
+      "integrity": "sha512-KGPt3r1c9ww009t2xLB6Vk0YyNOXh7hbjZ3EecHoVDxgtbUlYstMPDaReimKe6eOEfyY4hBEEeTvKwPsiH5WZg==",
       "dev": true,
       "optional": true
     },
     "esbuild-darwin-arm64": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.5.tgz",
-      "integrity": "sha512-WIfQkocGtFrz7vCu44ypY5YmiFXpsxvz2xqwe688jFfSVCnUsCn2qkEVDo7gT8EpsLOz1J/OmqjExePL1dr1Kg==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.7.tgz",
+      "integrity": "sha512-kBIHvtVqbSGajN88lYMnR3aIleH3ABZLLFLxwL2stiuIGAjGlQW741NxVTpUHQXUmPzxi6POqc9npkXa8AcSZQ==",
       "dev": true,
       "optional": true
     },
     "esbuild-freebsd-64": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.5.tgz",
-      "integrity": "sha512-M5/EfzV2RsMd/wqwR18CELcenZ8+fFxQAAEO7TJKDmP3knhWSbD72ILzrXFMMwshlPAS1ShCZ90jsxkm+8FlaA==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.7.tgz",
+      "integrity": "sha512-hESZB91qDLV5MEwNxzMxPfbjAhOmtfsr9Wnuci7pY6TtEh4UDuevmGmkUIjX/b+e/k4tcNBMf7SRQ2mdNuK/HQ==",
       "dev": true,
       "optional": true
     },
     "esbuild-freebsd-arm64": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.5.tgz",
-      "integrity": "sha512-2JQQ5Qs9J0440F/n/aUBNvY6lTo4XP/4lt1TwDfHuo0DY3w5++anw+jTjfouLzbJmFFiwmX7SmUhMnysocx96w==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.7.tgz",
+      "integrity": "sha512-dLFR0ChH5t+b3J8w0fVKGvtwSLWCv7GYT2Y2jFGulF1L5HftQLzVGN+6pi1SivuiVSmTh28FwUhi9PwQicXI6Q==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-32": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.5.tgz",
-      "integrity": "sha512-gO9vNnIN0FTUGjvTFucIXtBSr1Woymmx/aHQtuU+2OllGU6YFLs99960UD4Dib1kFovVgs59MTXwpFdVoSMZoQ==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.7.tgz",
+      "integrity": "sha512-v3gT/LsONGUZcjbt2swrMjwxo32NJzk+7sAgtxhGx1+ZmOFaTRXBAi1PPfgpeo/J//Un2jIKm/I+qqeo4caJvg==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-64": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.5.tgz",
-      "integrity": "sha512-ne0GFdNLsm4veXbTnYAWjbx3shpNKZJUd6XpNbKNUZaNllDZfYQt0/zRqOg0sc7O8GQ+PjSMv9IpIEULXVTVmg==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.7.tgz",
+      "integrity": "sha512-LxXEfLAKwOVmm1yecpMmWERBshl+Kv5YJ/1KnyAr6HRHFW8cxOEsEfisD3sVl/RvHyW//lhYUVSuy9jGEfIRAQ==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-arm": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.5.tgz",
-      "integrity": "sha512-wvAoHEN+gJ/22gnvhZnS/+2H14HyAxM07m59RSLn3iXrQsdS518jnEWRBnJz3fR6BJa+VUTo0NxYjGaNt7RA7Q==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.7.tgz",
+      "integrity": "sha512-JKgAHtMR5f75wJTeuNQbyznZZa+pjiUHV7sRZp42UNdyXC6TiUYMW/8z8yIBAr2Fpad8hM1royZKQisqPABPvQ==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-arm64": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.5.tgz",
-      "integrity": "sha512-7EgFyP2zjO065XTfdCxiXVEk+f83RQ1JsryN1X/VSX2li9rnHAt2swRbpoz5Vlrl6qjHrCmq5b6yxD13z6RheA==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.7.tgz",
+      "integrity": "sha512-P3cfhudpzWDkglutWgXcT2S7Ft7o2e3YDMrP1n0z2dlbUZghUkKCyaWw0zhp4KxEEzt/E7lmrtRu/pGWnwb9vw==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-mips64le": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.5.tgz",
-      "integrity": "sha512-KdnSkHxWrJ6Y40ABu+ipTZeRhFtc8dowGyFsZY5prsmMSr1ZTG9zQawguN4/tunJ0wy3+kD54GaGwdcpwWAvZQ==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.7.tgz",
+      "integrity": "sha512-T7XKuxl0VpeFLCJXub6U+iybiqh0kM/bWOTb4qcPyDDwNVhLUiPcGdG2/0S7F93czUZOKP57YiLV8YQewgLHKw==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-ppc64le": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.5.tgz",
-      "integrity": "sha512-QdRHGeZ2ykl5P0KRmfGBZIHmqcwIsUKWmmpZTOq573jRWwmpfRmS7xOhmDHBj9pxv+6qRMH8tLr2fe+ZKQvCYw==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.7.tgz",
+      "integrity": "sha512-6mGuC19WpFN7NYbecMIJjeQgvDb5aMuvyk0PDYBJrqAEMkTwg3Z98kEKuCm6THHRnrgsdr7bp4SruSAxEM4eJw==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-riscv64": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.5.tgz",
-      "integrity": "sha512-p+WE6RX+jNILsf+exR29DwgV6B73khEQV0qWUbzxaycxawZ8NE0wA6HnnTxbiw5f4Gx9sJDUBemh9v49lKOORA==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.7.tgz",
+      "integrity": "sha512-uUJsezbswAYo/X7OU/P+PuL/EI9WzxsEQXDekfwpQ23uGiooxqoLFAPmXPcRAt941vjlY9jtITEEikWMBr+F/g==",
       "dev": true,
       "optional": true
     },
     "esbuild-linux-s390x": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.5.tgz",
-      "integrity": "sha512-J2ngOB4cNzmqLHh6TYMM/ips8aoZIuzxJnDdWutBw5482jGXiOzsPoEF4j2WJ2mGnm7FBCO4StGcwzOgic70JQ==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.7.tgz",
+      "integrity": "sha512-+tO+xOyTNMc34rXlSxK7aCwJgvQyffqEM5MMdNDEeMU3ss0S6wKvbBOQfgd5jRPblfwJ6b+bKiz0g5nABpY0QQ==",
       "dev": true,
       "optional": true
     },
     "esbuild-netbsd-64": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.5.tgz",
-      "integrity": "sha512-MmKUYGDizYjFia0Rwt8oOgmiFH7zaYlsoQ3tIOfPxOqLssAsEgG0MUdRDm5lliqjiuoog8LyDu9srQk5YwWF3w==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.7.tgz",
+      "integrity": "sha512-yVc4Wz+Pu3cP5hzm5kIygNPrjar/v5WCSoRmIjCPWfBVJkZNb5brEGKUlf+0Y759D48BCWa0WHrWXaNy0DULTQ==",
       "dev": true,
       "optional": true
     },
     "esbuild-openbsd-64": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.5.tgz",
-      "integrity": "sha512-2mMFfkLk3oPWfopA9Plj4hyhqHNuGyp5KQyTT9Rc8hFd8wAn5ZrbJg+gNcLMo2yzf8Uiu0RT6G9B15YN9WQyMA==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.7.tgz",
+      "integrity": "sha512-GsimbwC4FSR4lN3wf8XmTQ+r8/0YSQo21rWDL0XFFhLHKlzEA4SsT1Tl8bPYu00IU6UWSJ+b3fG/8SB69rcuEQ==",
       "dev": true,
       "optional": true
     },
     "esbuild-sunos-64": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.5.tgz",
-      "integrity": "sha512-2sIzhMUfLNoD+rdmV6AacilCHSxZIoGAU2oT7XmJ0lXcZWnCvCtObvO6D4puxX9YRE97GodciRGDLBaiC6x1SA==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.7.tgz",
+      "integrity": "sha512-8CDI1aL/ts0mDGbWzjEOGKXnU7p3rDzggHSBtVryQzkSOsjCHRVe0iFYUuhczlxU1R3LN/E7HgUO4NXzGGP/Ag==",
       "dev": true,
       "optional": true
     },
     "esbuild-wasm": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.15.5.tgz",
-      "integrity": "sha512-lTJOEKekN/4JI/eOEq0wLcx53co2N6vaT/XjBz46D1tvIVoUEyM0o2K6txW6gEotf31szFD/J1PbxmnbkGlK9A==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.15.7.tgz",
+      "integrity": "sha512-CBtlw6nnCYuyD83yjZCi778nTZXJzvzomwaxwhkNMcOGDiD56/5uKQZI8FjxAH3vAV09hRb17oN3gmp+bKnguw==",
       "dev": true
     },
     "esbuild-windows-32": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.5.tgz",
-      "integrity": "sha512-e+duNED9UBop7Vnlap6XKedA/53lIi12xv2ebeNS4gFmu7aKyTrok7DPIZyU5w/ftHD4MUDs5PJUkQPP9xJRzg==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.7.tgz",
+      "integrity": "sha512-cOnKXUEPS8EGCzRSFa1x6NQjGhGsFlVgjhqGEbLTPsA7x4RRYiy2RKoArNUU4iR2vHmzqS5Gr84MEumO/wxYKA==",
       "dev": true,
       "optional": true
     },
     "esbuild-windows-64": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.5.tgz",
-      "integrity": "sha512-v+PjvNtSASHOjPDMIai9Yi+aP+Vwox+3WVdg2JB8N9aivJ7lyhp4NVU+J0MV2OkWFPnVO8AE/7xH+72ibUUEnw==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.7.tgz",
+      "integrity": "sha512-7MI08Ec2sTIDv+zH6StNBKO+2hGUYIT42GmFyW6MBBWWtJhTcQLinKS6ldIN1d52MXIbiJ6nXyCJ+LpL4jBm3Q==",
       "dev": true,
       "optional": true
     },
     "esbuild-windows-arm64": {
-      "version": "0.15.5",
-      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.5.tgz",
-      "integrity": "sha512-Yz8w/D8CUPYstvVQujByu6mlf48lKmXkq6bkeSZZxTA626efQOJb26aDGLzmFWx6eg/FwrXgt6SZs9V8Pwy/aA==",
+      "version": "0.15.7",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.7.tgz",
+      "integrity": "sha512-R06nmqBlWjKHddhRJYlqDd3Fabx9LFdKcjoOy08YLimwmsswlFBJV4rXzZCxz/b7ZJXvrZgj8DDv1ewE9+StMw==",
       "dev": true,
       "optional": true
     },
@@ -15171,12 +14833,6 @@
           "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
           "dev": true
         },
-        "slash": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
-          "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
-          "dev": true
-        },
         "strip-ansi": {
           "version": "6.0.1",
           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -15340,7 +14996,7 @@
     "etag": {
       "version": "1.8.1",
       "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
-      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+      "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
       "dev": true
     },
     "event-emitter": {
@@ -15484,38 +15140,6 @@
           "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
           "dev": true
         },
-        "body-parser": {
-          "version": "1.20.0",
-          "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
-          "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==",
-          "dev": true,
-          "requires": {
-            "bytes": "3.1.2",
-            "content-type": "~1.0.4",
-            "debug": "2.6.9",
-            "depd": "2.0.0",
-            "destroy": "1.2.0",
-            "http-errors": "2.0.0",
-            "iconv-lite": "0.4.24",
-            "on-finished": "2.4.1",
-            "qs": "6.10.3",
-            "raw-body": "2.5.1",
-            "type-is": "~1.6.18",
-            "unpipe": "1.0.0"
-          }
-        },
-        "bytes": {
-          "version": "3.1.2",
-          "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
-          "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
-          "dev": true
-        },
-        "cookie": {
-          "version": "0.5.0",
-          "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
-          "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
-          "dev": true
-        },
         "debug": {
           "version": "2.6.9",
           "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -15531,12 +15155,6 @@
           "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
           "dev": true
         },
-        "destroy": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
-          "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
-          "dev": true
-        },
         "finalhandler": {
           "version": "1.2.0",
           "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
@@ -15552,19 +15170,6 @@
             "unpipe": "~1.0.0"
           }
         },
-        "http-errors": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
-          "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
-          "dev": true,
-          "requires": {
-            "depd": "2.0.0",
-            "inherits": "2.0.4",
-            "setprototypeof": "1.2.0",
-            "statuses": "2.0.1",
-            "toidentifier": "1.0.1"
-          }
-        },
         "mime-db": {
           "version": "1.52.0",
           "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@@ -15610,41 +15215,17 @@
             "side-channel": "^1.0.4"
           }
         },
-        "raw-body": {
-          "version": "2.5.1",
-          "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
-          "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
-          "dev": true,
-          "requires": {
-            "bytes": "3.1.2",
-            "http-errors": "2.0.0",
-            "iconv-lite": "0.4.24",
-            "unpipe": "1.0.0"
-          }
-        },
         "safe-buffer": {
           "version": "5.2.1",
           "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
           "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
           "dev": true
         },
-        "setprototypeof": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
-          "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
-          "dev": true
-        },
         "statuses": {
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
           "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
           "dev": true
-        },
-        "toidentifier": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
-          "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
-          "dev": true
         }
       }
     },
@@ -15918,9 +15499,9 @@
       "dev": true
     },
     "follow-redirects": {
-      "version": "1.15.2",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
-      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+      "version": "1.14.7",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
+      "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==",
       "dev": true
     },
     "forever-agent": {
@@ -15955,7 +15536,7 @@
     "fresh": {
       "version": "0.5.2",
       "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
-      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+      "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
       "dev": true
     },
     "from": {
@@ -15980,24 +15561,21 @@
       "dev": true
     },
     "fs-extra": {
-      "version": "8.1.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
-      "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
       "dev": true,
       "requires": {
         "graceful-fs": "^4.2.0",
-        "jsonfile": "^4.0.0",
-        "universalify": "^0.1.0"
+        "jsonfile": "^6.0.1",
+        "universalify": "^2.0.0"
       },
       "dependencies": {
-        "jsonfile": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
-          "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
-          "dev": true,
-          "requires": {
-            "graceful-fs": "^4.1.6"
-          }
+        "universalify": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+          "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+          "dev": true
         }
       }
     },
@@ -16367,6 +15945,14 @@
         "ignore": "^5.2.0",
         "merge2": "^1.4.1",
         "slash": "^4.0.0"
+      },
+      "dependencies": {
+        "slash": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz",
+          "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==",
+          "dev": true
+        }
       }
     },
     "graceful-fs": {
@@ -18067,13 +17653,6 @@
         "walker": "^1.0.7"
       },
       "dependencies": {
-        "fsevents": {
-          "version": "2.3.2",
-          "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
-          "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
-          "dev": true,
-          "optional": true
-        },
         "graceful-fs": {
           "version": "4.2.10",
           "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
@@ -19976,6 +19555,15 @@
       "integrity": "sha512-EIgv+QZ9r+814gjJj0Bt5vSLJLzswGmSUbUpbi9AIr/fsN2IWFBl2NucV9PAiek+U1STK468tEkxmVYUtuAN3g==",
       "dev": true
     },
+    "magic-string": {
+      "version": "0.26.2",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.2.tgz",
+      "integrity": "sha512-NzzlXpclt5zAbmo6h6jNc8zl2gNRGHvmsZW4IvZhTC4W7k4OlLP+S5YLussa/r3ixNT66KOQfNORlXHSOy/X4A==",
+      "dev": true,
+      "requires": {
+        "sourcemap-codec": "^1.4.8"
+      }
+    },
     "make-dir": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
@@ -20104,7 +19692,7 @@
     "media-typer": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
-      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+      "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
       "dev": true
     },
     "memfs": {
@@ -20399,9 +19987,9 @@
       }
     },
     "minimist": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
-      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
       "dev": true
     },
     "minimist-options": {
@@ -20662,13 +20250,6 @@
         "stylus": "^0.59.0"
       },
       "dependencies": {
-        "@esbuild/linux-loong64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.7.tgz",
-          "integrity": "sha512-IKznSJOsVUuyt7cDzzSZyqBEcZe+7WlBqTVXiF1OXP/4Nm387ToaXZ0fyLwI1iBlI/bzpxVq411QE2/Bt2XWWw==",
-          "dev": true,
-          "optional": true
-        },
         "ajv": {
           "version": "8.11.0",
           "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
@@ -20738,146 +20319,6 @@
             "esbuild-windows-arm64": "0.15.7"
           }
         },
-        "esbuild-android-64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.7.tgz",
-          "integrity": "sha512-p7rCvdsldhxQr3YHxptf1Jcd86dlhvc3EQmQJaZzzuAxefO9PvcI0GLOa5nCWem1AJ8iMRu9w0r5TG8pHmbi9w==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-android-arm64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.7.tgz",
-          "integrity": "sha512-L775l9ynJT7rVqRM5vo+9w5g2ysbOCfsdLV4CWanTZ1k/9Jb3IYlQ06VCI1edhcosTYJRECQFJa3eAvkx72eyQ==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-darwin-64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.7.tgz",
-          "integrity": "sha512-KGPt3r1c9ww009t2xLB6Vk0YyNOXh7hbjZ3EecHoVDxgtbUlYstMPDaReimKe6eOEfyY4hBEEeTvKwPsiH5WZg==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-darwin-arm64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.7.tgz",
-          "integrity": "sha512-kBIHvtVqbSGajN88lYMnR3aIleH3ABZLLFLxwL2stiuIGAjGlQW741NxVTpUHQXUmPzxi6POqc9npkXa8AcSZQ==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-freebsd-64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.7.tgz",
-          "integrity": "sha512-hESZB91qDLV5MEwNxzMxPfbjAhOmtfsr9Wnuci7pY6TtEh4UDuevmGmkUIjX/b+e/k4tcNBMf7SRQ2mdNuK/HQ==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-freebsd-arm64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.7.tgz",
-          "integrity": "sha512-dLFR0ChH5t+b3J8w0fVKGvtwSLWCv7GYT2Y2jFGulF1L5HftQLzVGN+6pi1SivuiVSmTh28FwUhi9PwQicXI6Q==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-linux-32": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.7.tgz",
-          "integrity": "sha512-v3gT/LsONGUZcjbt2swrMjwxo32NJzk+7sAgtxhGx1+ZmOFaTRXBAi1PPfgpeo/J//Un2jIKm/I+qqeo4caJvg==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-linux-64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.7.tgz",
-          "integrity": "sha512-LxXEfLAKwOVmm1yecpMmWERBshl+Kv5YJ/1KnyAr6HRHFW8cxOEsEfisD3sVl/RvHyW//lhYUVSuy9jGEfIRAQ==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-linux-arm": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.7.tgz",
-          "integrity": "sha512-JKgAHtMR5f75wJTeuNQbyznZZa+pjiUHV7sRZp42UNdyXC6TiUYMW/8z8yIBAr2Fpad8hM1royZKQisqPABPvQ==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-linux-arm64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.7.tgz",
-          "integrity": "sha512-P3cfhudpzWDkglutWgXcT2S7Ft7o2e3YDMrP1n0z2dlbUZghUkKCyaWw0zhp4KxEEzt/E7lmrtRu/pGWnwb9vw==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-linux-mips64le": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.7.tgz",
-          "integrity": "sha512-T7XKuxl0VpeFLCJXub6U+iybiqh0kM/bWOTb4qcPyDDwNVhLUiPcGdG2/0S7F93czUZOKP57YiLV8YQewgLHKw==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-linux-ppc64le": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.7.tgz",
-          "integrity": "sha512-6mGuC19WpFN7NYbecMIJjeQgvDb5aMuvyk0PDYBJrqAEMkTwg3Z98kEKuCm6THHRnrgsdr7bp4SruSAxEM4eJw==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-linux-riscv64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.7.tgz",
-          "integrity": "sha512-uUJsezbswAYo/X7OU/P+PuL/EI9WzxsEQXDekfwpQ23uGiooxqoLFAPmXPcRAt941vjlY9jtITEEikWMBr+F/g==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-linux-s390x": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.7.tgz",
-          "integrity": "sha512-+tO+xOyTNMc34rXlSxK7aCwJgvQyffqEM5MMdNDEeMU3ss0S6wKvbBOQfgd5jRPblfwJ6b+bKiz0g5nABpY0QQ==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-netbsd-64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.7.tgz",
-          "integrity": "sha512-yVc4Wz+Pu3cP5hzm5kIygNPrjar/v5WCSoRmIjCPWfBVJkZNb5brEGKUlf+0Y759D48BCWa0WHrWXaNy0DULTQ==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-openbsd-64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.7.tgz",
-          "integrity": "sha512-GsimbwC4FSR4lN3wf8XmTQ+r8/0YSQo21rWDL0XFFhLHKlzEA4SsT1Tl8bPYu00IU6UWSJ+b3fG/8SB69rcuEQ==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-sunos-64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.7.tgz",
-          "integrity": "sha512-8CDI1aL/ts0mDGbWzjEOGKXnU7p3rDzggHSBtVryQzkSOsjCHRVe0iFYUuhczlxU1R3LN/E7HgUO4NXzGGP/Ag==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-windows-32": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.7.tgz",
-          "integrity": "sha512-cOnKXUEPS8EGCzRSFa1x6NQjGhGsFlVgjhqGEbLTPsA7x4RRYiy2RKoArNUU4iR2vHmzqS5Gr84MEumO/wxYKA==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-windows-64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.7.tgz",
-          "integrity": "sha512-7MI08Ec2sTIDv+zH6StNBKO+2hGUYIT42GmFyW6MBBWWtJhTcQLinKS6ldIN1d52MXIbiJ6nXyCJ+LpL4jBm3Q==",
-          "dev": true,
-          "optional": true
-        },
-        "esbuild-windows-arm64": {
-          "version": "0.15.7",
-          "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.7.tgz",
-          "integrity": "sha512-R06nmqBlWjKHddhRJYlqDd3Fabx9LFdKcjoOy08YLimwmsswlFBJV4rXzZCxz/b7ZJXvrZgj8DDv1ewE9+StMw==",
-          "dev": true,
-          "optional": true
-        },
         "glob": {
           "version": "8.0.3",
           "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz",
@@ -21347,17 +20788,6 @@
             "micromatch": "^4.0.4"
           }
         },
-        "fs-extra": {
-          "version": "10.1.0",
-          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
-          "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
-          "dev": true,
-          "requires": {
-            "graceful-fs": "^4.2.0",
-            "jsonfile": "^6.0.1",
-            "universalify": "^2.0.0"
-          }
-        },
         "glob": {
           "version": "7.1.4",
           "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
@@ -21429,12 +20859,6 @@
             "rimraf": "^3.0.0"
           }
         },
-        "universalify": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
-          "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
-          "dev": true
-        },
         "y18n": {
           "version": "5.0.8",
           "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
@@ -22606,7 +22030,8 @@
         },
         "ansi-regex": {
           "version": "5.0.0",
-          "resolved": "",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
           "dev": true
         },
         "ansi-styles": {
@@ -22949,12 +22374,6 @@
         }
       }
     },
-    "proxy-middleware": {
-      "version": "0.15.0",
-      "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz",
-      "integrity": "sha1-o/3xvvtzD5UZZYcqwvYHTGFHelY=",
-      "dev": true
-    },
     "prr": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
@@ -23839,25 +23258,6 @@
           "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
           "dev": true
         },
-        "destroy": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
-          "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
-          "dev": true
-        },
-        "http-errors": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
-          "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
-          "dev": true,
-          "requires": {
-            "depd": "2.0.0",
-            "inherits": "2.0.4",
-            "setprototypeof": "1.2.0",
-            "statuses": "2.0.1",
-            "toidentifier": "1.0.1"
-          }
-        },
         "ms": {
           "version": "2.1.3",
           "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -23873,23 +23273,11 @@
             "ee-first": "1.1.1"
           }
         },
-        "setprototypeof": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
-          "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
-          "dev": true
-        },
         "statuses": {
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
           "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
           "dev": true
-        },
-        "toidentifier": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
-          "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
-          "dev": true
         }
       }
     },
@@ -24050,9 +23438,9 @@
       "dev": true
     },
     "slash": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz",
-      "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
       "dev": true
     },
     "smart-buffer": {
@@ -24658,6 +24046,26 @@
           "requires": {
             "ms": "2.1.2"
           }
+        },
+        "fs-extra": {
+          "version": "8.1.0",
+          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+          "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "^4.2.0",
+            "jsonfile": "^4.0.0",
+            "universalify": "^0.1.0"
+          }
+        },
+        "jsonfile": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+          "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "^4.1.6"
+          }
         }
       }
     },
@@ -25082,7 +24490,7 @@
     "text-table": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
-      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+      "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
       "dev": true
     },
     "throat": {
@@ -25608,7 +25016,7 @@
     "vary": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
-      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+      "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
       "dev": true
     },
     "verror": {
diff --git a/package.json b/package.json
index 71952d5da5d115db9b92371c9c428b4e73011cf6..3e3d43aa7310c98f94dd65d12f4343a91300b255 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,6 @@
     "@angular/router": "^14.2.1",
     "@angular/service-worker": "^14.2.1",
     "@asymmetrik/ngx-leaflet": "^8.1.0",
-    "@gouvfr-anct/mediation-numerique": "^0.0.17",
     "@ngx-translate/core": "^13.0.0",
     "ag-grid-angular": "^26.2.0",
     "ag-grid-community": "^26.2.1",
@@ -57,7 +56,6 @@
     "@compodoc/compodoc": "^1.1.16",
     "@types/jasmine": "~4.0.0",
     "@types/jasminewd2": "~2.0.3",
-    "@types/jest": "^27.5.0",
     "@types/leaflet": "^1.5.17",
     "@types/leaflet.locatecontrol": "^0.60.7",
     "@types/node": "^16.0.0",
@@ -81,7 +79,6 @@
     "prettier": "^2.1.2",
     "protractor": "~7.0.0",
     "standard-version": "^9.3.2",
-    "ts-jest": "^27.1.4",
     "ts-node": "~8.3.0",
     "tslint": "~6.1.0",
     "typescript": "~4.8.3"
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 7adad9d257c3ddcf4eafcbbfd9390049aebf8af3..54d1b57608e88214239ef3f3c171c63b462ff8a3 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -8,6 +8,7 @@ import { OrientationFormComponent } from './form/orientation-form/orientation-fo
 import { AdminGuard } from './guards/admin.guard';
 import { AuthGuard } from './guards/auth.guard';
 import { LoginGuard } from './guards/login.guard';
+import { DeactivateGuard } from './guards/deactivate.guard';
 import { LegalNoticeComponent } from './legal-notice/legal-notice.component';
 import { LoginComponent } from './login/login.component';
 import { NewsletterSubscriptionComponent } from './newsletter-subscription/newsletter-subscription.component';
@@ -17,9 +18,10 @@ import { ResetEmailComponent } from './reset-email/reset-email.component';
 import { ResetPasswordComponent } from './reset-password/reset-password.component';
 import { StructureResolver } from './resolvers/structure.resolver';
 import { PasswordFormComponent } from './shared/components';
-import { StructureDetailsWrapperComponent } from './structure/components/structure-details-wrapper/structure-details-wrapper.component';
-import { StructureExcludeComponent } from './structure/structure-exclude/structure-exclude.component';
 import { StructureJoinComponent } from './structure/structure-join/structure-join.component';
+import { StructureDetailsComponent } from './structure-list/components/structure-details/structure-details.component';
+import { StructureListComponent } from './structure-list/structure-list.component';
+import { StructureExcludeComponent } from './structure/structure-exclude/structure-exclude.component';
 
 const footerOutletRoute: Route = {
   path: '',
@@ -31,7 +33,7 @@ const routes: Routes = [
   {
     path: 'print',
     outlet: 'print',
-    children: [{ path: 'structure', component: StructureDetailsWrapperComponent }, footerOutletRoute],
+    children: [{ path: 'structure', component: StructureDetailsComponent }, footerOutletRoute],
   },
   {
     path: 'print',
@@ -58,7 +60,7 @@ const routes: Routes = [
       {
         path: '',
         outlet: 'left-pane',
-        component: StructureDetailsWrapperComponent,
+        component: StructureDetailsComponent,
       },
     ],
   },
@@ -72,6 +74,16 @@ const routes: Routes = [
       footerOutletRoute,
     ],
   },
+  {
+    path: 'structures',
+    children: [
+      {
+        path: '',
+        component: StructureListComponent,
+      },
+      footerOutletRoute,
+    ],
+  },
   {
     path: 'legal-notice',
     children: [
@@ -140,7 +152,7 @@ const routes: Routes = [
         path: '',
         outlet: 'left-pane',
         data: { fullScreen: true },
-        component: StructureDetailsWrapperComponent,
+        component: StructureDetailsComponent,
       },
     ],
   },
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 1c7cd7fc2f59d8ba4443859ef03677633ab88200..c8a2e3bb52ba34504346327d366444ac92896dee 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -4,6 +4,7 @@ import { ProfileService } from './profile/services/profile.service';
 import { AuthService } from './services/auth.service';
 import { RouterListenerService } from './services/routerListener.service';
 import { UpdateService } from './services/update.service';
+import { PrintService } from './shared/service/print.service';
 
 @Component({
   selector: 'app-root',
@@ -15,6 +16,7 @@ export class AppComponent implements OnInit {
   public loading = true;
 
   constructor(
+    public printService: PrintService,
     private authService: AuthService,
     private profilService: ProfileService,
     private routerListener: RouterListenerService,
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 4fb3e41a9ddb870211c306b1df5280e2eaed662e..81abddae8001a0d238da0439c834fa2bfd358820 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -1,55 +1,51 @@
-import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
 import { LOCALE_ID, NgModule } from '@angular/core';
+import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
 import { BrowserModule } from '@angular/platform-browser';
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
-import { ServiceWorkerModule } from '@angular/service-worker';
-import { GeometryPolygonConfiguration, MapModule, StructureModule } from '@gouvfr-anct/mediation-numerique';
 import { ToastrModule } from 'ngx-toastr';
-import metropole from '../assets/geojson/metropole.json';
-import { environment } from '../environments/environment';
+
 import { AppRoutingModule } from './app-routing.module';
+
 import { AppComponent } from './app.component';
 import { CartoComponent } from './carto/carto.component';
 import { CustomBreakPointsProvider } from './config/custom-breakpoint';
-import { CustomHttpInterceptor } from './config/http-interceptor';
-import { InitialPosition } from './config/map/initial-position';
-import { MarkerType } from './config/map/marker-type';
-import { ZoomLevel } from './config/map/zoomLevel.enum';
-import { ContactComponent } from './contact/contact.component';
 import { FooterComponent } from './footer/footer.component';
-import { FormViewModule } from './form/form-view/form-view.module';
-import { OrientationComponent } from './form/orientation-form/component/orientation-modal/orientation-modal.component';
-import { StructureDetailPrintComponent } from './form/orientation-form/component/structure-detail-print/structure-detail-print.component';
-import { StructureListPrintComponent } from './form/orientation-form/component/structure-list-print/structure-list-print.component';
-import { StructurePrintHeaderComponent } from './form/orientation-form/component/structure-print-header/structure-print-header.component';
-import { OrientationFormComponent } from './form/orientation-form/orientation-form.component';
-import { AdminGuard } from './guards/admin.guard';
-import { AuthGuard } from './guards/auth.guard';
-import { DeactivateGuard } from './guards/deactivate.guard';
-import { LoginGuard } from './guards/login.guard';
-import { RoleGuard } from './guards/role.guard';
 import { HeaderComponent } from './header/header.component';
+import { SharedModule } from './shared/shared.module';
+import { MapModule } from './map/map.module';
+import { StructureListComponent } from './structure-list/structure-list.component';
+import { CardComponent } from './structure-list/components/card/card.component';
+import { StructureListSearchComponent } from './structure-list/components/structure-list-search/structure-list-search.component';
+import { StructureDetailsComponent } from './structure-list/components/structure-details/structure-details.component';
+import { ModalFilterComponent } from './structure-list/components/modal-filter/modal-filter.component';
 import { LegalNoticeComponent } from './legal-notice/legal-notice.component';
-import { LoginComponent } from './login/login.component';
-import { NewsletterSubscriptionComponent } from './newsletter-subscription/newsletter-subscription.component';
 import { PageComponent } from './page/page.component';
+import { ContactComponent } from './contact/contact.component';
+import { AuthGuard } from './guards/auth.guard';
+import { LoginGuard } from './guards/login.guard';
+import { CustomHttpInterceptor } from './config/http-interceptor';
 import { ResetEmailComponent } from './reset-email/reset-email.component';
 import { ResetPasswordComponent } from './reset-password/reset-password.component';
-import { StructureResolver } from './resolvers/structure.resolver';
+import { AdminGuard } from './guards/admin.guard';
+import { DeactivateGuard } from './guards/deactivate.guard';
 import { TempUserResolver } from './resolvers/temp-user.resolver';
-import { GeojsonService } from './services/geojson.service';
+import { StructureJoinComponent } from './structure/structure-join/structure-join.component';
 import { RouterListenerService } from './services/routerListener.service';
-import { StructureService } from './services/structure.service';
+import { NewsletterSubscriptionComponent } from './newsletter-subscription/newsletter-subscription.component';
+import { OrientationFormComponent } from './form/orientation-form/orientation-form.component';
+import { StructureDetailPrintComponent } from './form/orientation-form/component/structure-detail-print/structure-detail-print.component';
+import { StructureListPrintComponent } from './form/orientation-form/component/structure-list-print/structure-list-print.component';
+import { StructurePrintHeaderComponent } from './form/orientation-form/component/structure-print-header/structure-print-header.component';
+import { OrientationComponent } from './form/orientation-form/component/orientation-modal/orientation-modal.component';
+import { ServiceWorkerModule } from '@angular/service-worker';
+import { environment } from '../environments/environment';
+import { StructureResolver } from './resolvers/structure.resolver';
+import { RoleGuard } from './guards/role.guard';
 import { UpdateService } from './services/update.service';
 import { DataShareConsentComponent } from './shared/components/data-share-consent/data-share-consent.component';
-import { SharedModule } from './shared/shared.module';
-import { SearchService } from './structure-list/services/search.service';
-import { StructureDetailsActionsComponent } from './structure/components/structure-details-actions/structure-details-actions.component';
-import { StructureDetailsModalsComponent } from './structure/components/structure-details-modals/structure-details-modals.component';
-import { StructureDetailsWrapperComponent } from './structure/components/structure-details-wrapper/structure-details-wrapper.component';
-import { TclAccessComponent } from './structure/components/tcl-access/tcl-access.component';
+import { FormViewModule } from './form/form-view/form-view.module';
+import { LoginComponent } from './login/login.component';
 import { StructureExcludeComponent } from './structure/structure-exclude/structure-exclude.component';
-import { StructureJoinComponent } from './structure/structure-join/structure-join.component';
 
 @NgModule({
   declarations: [
@@ -57,6 +53,11 @@ import { StructureJoinComponent } from './structure/structure-join/structure-joi
     HeaderComponent,
     FooterComponent,
     CartoComponent,
+    StructureListComponent,
+    CardComponent,
+    StructureListSearchComponent,
+    ModalFilterComponent,
+    StructureDetailsComponent,
     LegalNoticeComponent,
     PageComponent,
     ContactComponent,
@@ -71,27 +72,16 @@ import { StructureJoinComponent } from './structure/structure-join/structure-joi
     DataShareConsentComponent,
     OrientationComponent,
     LoginComponent,
-    TclAccessComponent,
-    StructureDetailsModalsComponent,
-    StructureDetailsActionsComponent,
     StructureExcludeComponent,
-    StructureDetailsWrapperComponent,
   ],
   imports: [
     BrowserModule,
     HttpClientModule,
     AppRoutingModule,
     SharedModule,
-    MapModule.forRoot(
-      metropole as GeometryPolygonConfiguration,
-      ZoomLevel,
-      InitialPosition,
-      MarkerType,
-      GeojsonService
-    ),
+    MapModule,
     BrowserAnimationsModule,
     ToastrModule.forRoot(),
-    StructureModule.forRoot(SearchService, StructureService),
     FormViewModule,
     ServiceWorkerModule.register('ngsw-worker.js', {
       enabled: environment.production,
diff --git a/src/app/carto/carto.component.html b/src/app/carto/carto.component.html
index 5069d39529f43f54388c99a223b5277a7efe37dd..c2a6236850b69c37d5cc5839f9e5da605f930a08 100644
--- a/src/app/carto/carto.component.html
+++ b/src/app/carto/carto.component.html
@@ -4,7 +4,6 @@
   </div>
   <div class="panes-container" fxLayout="row">
     <app-structure-list
-      #ref
       (searchEvent)="getStructures($event)"
       [structureList]="structures"
       [location]="currentLocation"
@@ -13,29 +12,9 @@
       [selectedStructure]="currentStructure"
       (updatedStructure)="updateStructures($event)"
       class="left-pane"
-      [ngClass]="{ mapPhone: isMapPhone === true }"
+      [ngClass]="{ mapPhone: isMapPhone == true }"
       fxLayout="column"
-    >
-      <div slot="structure-list-actions">
-        <app-button
-          tabindex="0"
-          (action)="addStructure()"
-          [text]="'Ajouter une structure'"
-          [style]="buttonTypeEnum.Secondary"
-          [extraClass]="'small-text'"
-        ></app-button>
-      </div>
-      <div slot="structure-list-elements">
-        <app-card
-          *ngFor="let structure of ref.structureList"
-          [structure]="structure"
-          [isClaimed]="isAdmin ? structure.isClaimed : true"
-          (showDetails)="ref.showDetails($event)"
-          (hover)="ref.handleCardHover($event)"
-          class="structure-card"
-        ></app-card>
-      </div>
-    </app-structure-list>
+    ></app-structure-list>
     <div class="btnSwitch">
       <app-button
         [style]="buttonTypeEnum.ButtonPhone"
@@ -52,7 +31,7 @@
       [isMapPhone]="isMapPhone"
       [searchedValue]="searchedValue"
       class="right-pane"
-      [ngClass]="{ mapPhone: isMapPhone === true }"
+      [ngClass]="{ mapPhone: isMapPhone == true }"
     ></app-map>
   </div>
 </div>
diff --git a/src/app/carto/carto.component.ts b/src/app/carto/carto.component.ts
index 25aee8c3b706a09d65cf26ce36a5c341f1ae475e..ede0edf85e8491f01ad55ffb5b253f2717d4fbd6 100644
--- a/src/app/carto/carto.component.ts
+++ b/src/app/carto/carto.component.ts
@@ -1,20 +1,21 @@
 import { Component, OnInit } from '@angular/core';
 import { Meta } from '@angular/platform-browser';
-import { ActivatedRoute, Router } from '@angular/router';
-import { Filter, GeoJson, Structure } from '@gouvfr-anct/mediation-numerique';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
+import { ActivatedRoute } from '@angular/router';
 import * as _ from 'lodash';
-import { Observable } from 'rxjs';
+import { GeoJson } from '../map/models/geojson.model';
 import { ProfileService } from '../profile/services/profile.service';
-import { AuthService } from '../services/auth.service';
+import { Structure } from '../models/structure.model';
 import { GeojsonService } from '../services/geojson.service';
 import { StructureService } from '../services/structure.service';
+import { ButtonType } from '../shared/components/button/buttonType.enum';
+import { Filter } from '../structure-list/models/filter.model';
 import { CustomRegExp } from '../utils/CustomRegExp';
+import { Observable } from 'rxjs';
 
 @Component({
   selector: 'app-carto',
   templateUrl: './carto.component.html',
-  styleUrls: ['./carto.component.scss'],
+  styleUrls: ['./carto.component.scss']
 })
 export class CartoComponent implements OnInit {
   public filters: Filter[] = [];
@@ -35,9 +36,7 @@ export class CartoComponent implements OnInit {
     private geoJsonService: GeojsonService,
     private activatedRoute: ActivatedRoute,
     private profileService: ProfileService,
-    private meta: Meta,
-    private router: Router,
-    private authService: AuthService
+    private meta: Meta
   ) {}
 
   ngOnInit(): void {
@@ -55,7 +54,7 @@ export class CartoComponent implements OnInit {
 
     this.meta.updateTag({
       name: 'description',
-      content: 'Recense tous les lieux, accompagnements et ateliers de médiation numérique de la Métropole de Lyon.',
+      content: 'Recense tous les lieux, accompagnements et ateliers de médiation numérique de la Métropole de Lyon.'
     });
   }
 
@@ -106,12 +105,7 @@ export class CartoComponent implements OnInit {
    * @param lat user latitde
    * @param sortByDistance if set to `true`, structures data is sort by distance. Default value is `true`
    */
-  private updateStructuresdistance(
-    structures: Structure[],
-    lon: number,
-    lat: number,
-    sortByDistance: boolean = true
-  ): void {
+  private updateStructuresdistance(structures: Structure[], lon: number, lat: number, sortByDistance: boolean = true): void {
     Promise.all(
       structures.map(async (structure) => {
         if (this.geolocation) {
@@ -122,7 +116,7 @@ export class CartoComponent implements OnInit {
         }
         return structure;
       })
-    ).then(async (structureList: Structure[]) => {
+    ).then((structureList) => {
       if (sortByDistance) {
         structureList = _.sortBy(structureList, ['distance']);
       }
@@ -160,10 +154,7 @@ export class CartoComponent implements OnInit {
    * @param lat number
    */
   private getStructurePosition(structure: Structure, lon: number, lat: number): Structure {
-    structure.distance = parseInt(
-      this.geoJsonService.getDistance(structure.getLat(), structure.getLon(), lat, lon, 'M'),
-      10
-    );
+    structure.distance = parseInt(this.geoJsonService.getDistance(structure.getLat(), structure.getLon(), lat, lon, 'M'), 10);
     return structure;
   }
 
@@ -216,14 +207,6 @@ export class CartoComponent implements OnInit {
     this.isMapPhone = !this.isMapPhone;
   }
 
-  public addStructure(): void {
-    if (!this.authService.isLoggedIn()) {
-      this.router.navigateByUrl('/login');
-    } else {
-      this.router.navigateByUrl('/form/structure');
-    }
-  }
-
   public get isAdmin(): boolean {
     return this.profileService.isAdmin();
   }
diff --git a/src/app/config/map/initial-position.ts b/src/app/config/map/initial-position.ts
deleted file mode 100644
index 6c530828f598387ffb8369cc4db7ec55bc912f26..0000000000000000000000000000000000000000
--- a/src/app/config/map/initial-position.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export enum InitialPosition {
-  latitude = 45.764043,
-  longitude = 4.835659,
-}
diff --git a/src/app/form/footer-form/footer-form.component.ts b/src/app/form/footer-form/footer-form.component.ts
index 718eb2abeab5adbfcb2b183d1fb266f27eb161bc..6ad1b384a181f59d95fbae9b880479345bdd7389 100644
--- a/src/app/form/footer-form/footer-form.component.ts
+++ b/src/app/form/footer-form/footer-form.component.ts
@@ -1,11 +1,11 @@
 import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
 import { UntypedFormGroup } from '@angular/forms';
 import { Router } from '@angular/router';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
 import { User } from '../../models/user.model';
 import { ProfileService } from '../../profile/services/profile.service';
 import { AuthService } from '../../services/auth.service';
 import { NewsletterService } from '../../services/newsletter.service';
+import { ButtonType } from '../../shared/components/button/buttonType.enum';
 import { Utils } from '../../utils/utils';
 import { accountFormStep } from '../form-view/account-form/accountFormStep.enum';
 import { formType } from '../form-view/formType.enum';
diff --git a/src/app/form/form-view/form-view.component.ts b/src/app/form/form-view/form-view.component.ts
index ec58518c16bb18cb1f7c9d0a24db80e1d3dab52d..f0cfa33ef8195890bd25a401139135ecc68498e4 100644
--- a/src/app/form/form-view/form-view.component.ts
+++ b/src/app/form/form-view/form-view.component.ts
@@ -1,9 +1,10 @@
 import { Component, OnInit } from '@angular/core';
 import { UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
 import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
-import { PersonalOffer, Structure } from '@gouvfr-anct/mediation-numerique';
 import { forkJoin, of } from 'rxjs';
 import { catchError, map } from 'rxjs/operators';
+import { PersonalOffer } from '../../models/personalOffer.model';
+import { Structure } from '../../models/structure.model';
 import { StructureWithOwners } from '../../models/structureWithOwners.model';
 import { User } from '../../models/user.model';
 import { ProfileService } from '../../profile/services/profile.service';
diff --git a/src/app/form/form-view/global-components/information-step/information-step.component.ts b/src/app/form/form-view/global-components/information-step/information-step.component.ts
index 8b8dcdc9abed30660520a59b7559124d10a1b52b..0c8cd021c53fc22b0cf62c6cb848ffaca0846275 100644
--- a/src/app/form/form-view/global-components/information-step/information-step.component.ts
+++ b/src/app/form/form-view/global-components/information-step/information-step.component.ts
@@ -1,6 +1,6 @@
 import { Component, EventEmitter, Input, Output } from '@angular/core';
 import { Router } from '@angular/router';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
+import { ButtonType } from '../../../../shared/components/button/buttonType.enum';
 import { accountFormStep } from '../../account-form/accountFormStep.enum';
 import { formType } from '../../formType.enum';
 import { personalOfferFormStep } from '../../personal-offer-form/personalOfferFormStep.enum';
diff --git a/src/app/form/form-view/personal-offer-form/personal-offer-accompaniment/personal-offer-accompaniment.component.ts b/src/app/form/form-view/personal-offer-form/personal-offer-accompaniment/personal-offer-accompaniment.component.ts
index 86f182b7a8a45903cc02a48380df1fe462b73635..7013868bbe658a59450c5288da604db4acb65025 100644
--- a/src/app/form/form-view/personal-offer-form/personal-offer-accompaniment/personal-offer-accompaniment.component.ts
+++ b/src/app/form/form-view/personal-offer-form/personal-offer-accompaniment/personal-offer-accompaniment.component.ts
@@ -1,7 +1,9 @@
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 import { UntypedFormGroup } from '@angular/forms';
-import { Category, Module } from '@gouvfr-anct/mediation-numerique';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
+import { Structure } from '../../../../models/structure.model';
+import { ButtonType } from '../../../../shared/components/button/buttonType.enum';
+import { Category } from '../../../../structure-list/models/category.model';
+import { Module } from '../../../../structure-list/models/module.model';
 import { SearchService } from '../../../../structure-list/services/search.service';
 
 @Component({
diff --git a/src/app/form/form-view/personal-offer-form/personal-offer-training-type/personal-offer-training-type.component.ts b/src/app/form/form-view/personal-offer-form/personal-offer-training-type/personal-offer-training-type.component.ts
index e1e36bf78d89ecf803d9ffce5619883a1ef9b757..59e5e07b9df3356954ce88e9309480e74cb7e49e 100644
--- a/src/app/form/form-view/personal-offer-form/personal-offer-training-type/personal-offer-training-type.component.ts
+++ b/src/app/form/form-view/personal-offer-form/personal-offer-training-type/personal-offer-training-type.component.ts
@@ -1,6 +1,6 @@
 import { Component, Input } from '@angular/core';
 import { UntypedFormGroup } from '@angular/forms';
-import { Category } from '@gouvfr-anct/mediation-numerique';
+import { Category } from '../../../../structure-list/models/category.model';
 
 @Component({
   selector: 'app-personal-offer-training-type',
diff --git a/src/app/form/form-view/profile-form/profile-employer-selection/profile-employer-selection.component.ts b/src/app/form/form-view/profile-form/profile-employer-selection/profile-employer-selection.component.ts
index 6a9b4d4423f59603ad41818c19f1e94d9878f574..bd6272479d9c0e44900b5f78947c92146b82e1f1 100644
--- a/src/app/form/form-view/profile-form/profile-employer-selection/profile-employer-selection.component.ts
+++ b/src/app/form/form-view/profile-form/profile-employer-selection/profile-employer-selection.component.ts
@@ -1,8 +1,8 @@
 import { Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core';
 import { UntypedFormGroup } from '@angular/forms';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
 import { Employer } from '../../../../models/employer.model';
 import { ProfileService } from '../../../../profile/services/profile.service';
+import { ButtonType } from '../../../../shared/components/button/buttonType.enum';
 
 @Component({
   selector: 'app-profile-employer-selection',
diff --git a/src/app/form/form-view/profile-form/profile-job-selection/profile-job-selection.component.ts b/src/app/form/form-view/profile-form/profile-job-selection/profile-job-selection.component.ts
index bcdc1655da332dfdfe8db964c96bee8e3339e5ee..03a2b57ad1d55d7e27932387d5097fed123116b6 100644
--- a/src/app/form/form-view/profile-form/profile-job-selection/profile-job-selection.component.ts
+++ b/src/app/form/form-view/profile-form/profile-job-selection/profile-job-selection.component.ts
@@ -1,8 +1,8 @@
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 import { UntypedFormGroup } from '@angular/forms';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
 import { Job } from '../../../../models/job.model';
 import { ProfileService } from '../../../../profile/services/profile.service';
+import { ButtonType } from '../../../../shared/components/button/buttonType.enum';
 
 @Component({
   selector: 'app-profile-job-selection',
diff --git a/src/app/form/form-view/profile-form/profile-structure-choice/profile-structure-choice.component.ts b/src/app/form/form-view/profile-form/profile-structure-choice/profile-structure-choice.component.ts
index 085a0706416ef1272d2b69a0db9bce6611cef967..cb9c5c7903b4eda7704d720eaf9f282046e647fd 100644
--- a/src/app/form/form-view/profile-form/profile-structure-choice/profile-structure-choice.component.ts
+++ b/src/app/form/form-view/profile-form/profile-structure-choice/profile-structure-choice.component.ts
@@ -1,9 +1,10 @@
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 import { UntypedFormGroup } from '@angular/forms';
-import { Filter, Structure } from '@gouvfr-anct/mediation-numerique';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
+import { Structure } from '../../../../models/structure.model';
 import { ProfileService } from '../../../../profile/services/profile.service';
 import { StructureService } from '../../../../services/structure.service';
+import { ButtonType } from '../../../../shared/components/button/buttonType.enum';
+import { Filter } from '../../../../structure-list/models/filter.model';
 
 @Component({
   selector: 'app-profile-structure-choice',
diff --git a/src/app/form/form-view/structure-form/structure-access-modality/structure-access-modality.component.ts b/src/app/form/form-view/structure-form/structure-access-modality/structure-access-modality.component.ts
index d2f130bbbbb636a6e765048e9d4116a69ba50101..aa0d7c280a2eedb8109d803c1fecd1d7378c4db2 100644
--- a/src/app/form/form-view/structure-form/structure-access-modality/structure-access-modality.component.ts
+++ b/src/app/form/form-view/structure-form/structure-access-modality/structure-access-modality.component.ts
@@ -1,6 +1,6 @@
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 import { UntypedFormGroup } from '@angular/forms';
-import { Category } from '@gouvfr-anct/mediation-numerique';
+import { Category } from '../../../../structure-list/models/category.model';
 
 @Component({
   selector: 'app-structure-access-modality',
diff --git a/src/app/form/form-view/structure-form/structure-digital-helping-accompaniment/structure-digital-helping-accompaniment.component.ts b/src/app/form/form-view/structure-form/structure-digital-helping-accompaniment/structure-digital-helping-accompaniment.component.ts
index 4d86cfb7257b8a1bd86e2e9ae59be6230c928428..53c04ed83a479f7cc075a49068ec6edc833cade2 100644
--- a/src/app/form/form-view/structure-form/structure-digital-helping-accompaniment/structure-digital-helping-accompaniment.component.ts
+++ b/src/app/form/form-view/structure-form/structure-digital-helping-accompaniment/structure-digital-helping-accompaniment.component.ts
@@ -1,7 +1,7 @@
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 import { UntypedFormGroup } from '@angular/forms';
-import { Category } from '@gouvfr-anct/mediation-numerique';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
+import { ButtonType } from '../../../../shared/components/button/buttonType.enum';
+import { Category } from '../../../../structure-list/models/category.model';
 
 @Component({
   selector: 'app-structure-digital-helping-accompaniment',
diff --git a/src/app/form/form-view/structure-form/structure-equipments/structure-equipments.component.ts b/src/app/form/form-view/structure-form/structure-equipments/structure-equipments.component.ts
index 646007d8bb2681aeb7d34b0cbb55429234ad00ac..a4e52968ad4bf028141333e45dd235a794e75937 100644
--- a/src/app/form/form-view/structure-form/structure-equipments/structure-equipments.component.ts
+++ b/src/app/form/form-view/structure-form/structure-equipments/structure-equipments.component.ts
@@ -1,6 +1,6 @@
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 import { AbstractControl, UntypedFormGroup } from '@angular/forms';
-import { Module } from '@gouvfr-anct/mediation-numerique';
+import { Module } from '../../../../structure-list/models/module.model';
 
 @Component({
   selector: 'app-structure-equipments',
diff --git a/src/app/form/form-view/structure-form/structure-form.component.ts b/src/app/form/form-view/structure-form/structure-form.component.ts
index dac57368eaa1224fe329a78ee8ee779e7e2a83ed..69d15eeebea56426a3899da6f7c2ac41e4759b06 100644
--- a/src/app/form/form-view/structure-form/structure-form.component.ts
+++ b/src/app/form/form-view/structure-form/structure-form.component.ts
@@ -1,10 +1,13 @@
 import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
 import { AbstractControl, UntypedFormArray, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
 import { ActivatedRoute } from '@angular/router';
-import { Address, Category, Module, Structure } from '@gouvfr-anct/mediation-numerique';
+import { Address } from '../../../models/address.model';
+import { Structure } from '../../../models/structure.model';
 import { User } from '../../../models/user.model';
 import { ProfileService } from '../../../profile/services/profile.service';
 import { CategoryEnum } from '../../../shared/enum/category.enum';
+import { Category } from '../../../structure-list/models/category.model';
+import { Module } from '../../../structure-list/models/module.model';
 import { SearchService } from '../../../structure-list/services/search.service';
 import { formType } from '../formType.enum';
 import { structureFormStep } from './structureFormStep.enum';
diff --git a/src/app/form/form-view/structure-form/structure-labels/structure-labels.component.ts b/src/app/form/form-view/structure-form/structure-labels/structure-labels.component.ts
index 46b2c712a9fdd3fdfec93c64a0a458e7900c9d22..b5db68fdec3c36dc284be111cc52d9dd303f6949 100644
--- a/src/app/form/form-view/structure-form/structure-labels/structure-labels.component.ts
+++ b/src/app/form/form-view/structure-form/structure-labels/structure-labels.component.ts
@@ -1,6 +1,6 @@
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 import { UntypedFormGroup } from '@angular/forms';
-import { Category } from '@gouvfr-anct/mediation-numerique';
+import { Category } from '../../../../structure-list/models/category.model';
 
 @Component({
   selector: 'app-structure-labels',
diff --git a/src/app/form/form-view/structure-form/structure-name-and-address/structure-name-and-address.component.ts b/src/app/form/form-view/structure-form/structure-name-and-address/structure-name-and-address.component.ts
index 68ba5ae02871f3cbb22b90a8f9ed4b12af9c0973..fed97c1604fdb9190c175cadf3e480f1d309345f 100644
--- a/src/app/form/form-view/structure-form/structure-name-and-address/structure-name-and-address.component.ts
+++ b/src/app/form/form-view/structure-form/structure-name-and-address/structure-name-and-address.component.ts
@@ -1,6 +1,7 @@
+import { ThisReceiver } from '@angular/compiler';
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 import { UntypedFormGroup } from '@angular/forms';
-import { Address } from '@gouvfr-anct/mediation-numerique';
+import { Address } from '../../../../models/address.model';
 
 @Component({
   selector: 'app-structure-name-and-address',
diff --git a/src/app/form/form-view/structure-form/structure-other-services/structure-other-services.component.ts b/src/app/form/form-view/structure-form/structure-other-services/structure-other-services.component.ts
index b22d43ff16ed4ad9ffb3129f4400680db876d709..2df67bf3fa23ad4a08c2db878b6d000be2a868d3 100644
--- a/src/app/form/form-view/structure-form/structure-other-services/structure-other-services.component.ts
+++ b/src/app/form/form-view/structure-form/structure-other-services/structure-other-services.component.ts
@@ -1,6 +1,6 @@
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 import { UntypedFormGroup } from '@angular/forms';
-import { Category } from '@gouvfr-anct/mediation-numerique';
+import { Category } from '../../../../structure-list/models/category.model';
 
 @Component({
   selector: 'app-structure-other-services',
diff --git a/src/app/form/form-view/structure-form/structure-public-target/structure-public-target.component.ts b/src/app/form/form-view/structure-form/structure-public-target/structure-public-target.component.ts
index a68ed6e86e67972088b60fe0b708aecdd9cba9ad..f72179bdad32368eadb5674102568336f61c062c 100644
--- a/src/app/form/form-view/structure-form/structure-public-target/structure-public-target.component.ts
+++ b/src/app/form/form-view/structure-form/structure-public-target/structure-public-target.component.ts
@@ -1,7 +1,7 @@
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 import { UntypedFormGroup } from '@angular/forms';
-import { Category } from '@gouvfr-anct/mediation-numerique';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
+import { ButtonType } from '../../../../shared/components/button/buttonType.enum';
+import { Category } from '../../../../structure-list/models/category.model';
 
 @Component({
   selector: 'app-structure-public-target',
diff --git a/src/app/form/form-view/structure-form/structure-training-type/structure-training-type.component.ts b/src/app/form/form-view/structure-form/structure-training-type/structure-training-type.component.ts
index de5cbbe42bb1fe1b54d74c3c1d1e09920f755761..08a6b93e7343cad7ec4d37f6f803e27a7084d24d 100644
--- a/src/app/form/form-view/structure-form/structure-training-type/structure-training-type.component.ts
+++ b/src/app/form/form-view/structure-form/structure-training-type/structure-training-type.component.ts
@@ -1,6 +1,6 @@
 import { Component, EventEmitter, Input, Output } from '@angular/core';
 import { UntypedFormGroup } from '@angular/forms';
-import { Category } from '@gouvfr-anct/mediation-numerique';
+import { Category } from '../../../../structure-list/models/category.model';
 
 @Component({
   selector: 'app-structure-training-type',
diff --git a/src/app/form/orientation-form/component/structure-detail-print/structure-detail-print.component.ts b/src/app/form/orientation-form/component/structure-detail-print/structure-detail-print.component.ts
index f8d1c4b8083fa9231ef4f39d8e43bcfb06574937..10ca2469315e01705afef5a3e112d90c133ff9e9 100644
--- a/src/app/form/orientation-form/component/structure-detail-print/structure-detail-print.component.ts
+++ b/src/app/form/orientation-form/component/structure-detail-print/structure-detail-print.component.ts
@@ -1,42 +1,42 @@
-import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
-import { Structure } from '@gouvfr-anct/mediation-numerique';
-import { AccessModality } from '../../../../config/map/access-modality.enum';
-import { TclStopPoint } from '../../../../models/tclStopPoint.model';
-import { AuthService } from '../../../../services/auth.service';
-import { TclService } from '../../../../services/tcl.service';
-
-@Component({
-  selector: 'app-structure-detail-print',
-  templateUrl: './structure-detail-print.component.html',
-  styleUrls: ['./structure-detail-print.component.scss'],
-})
-export class StructureDetailPrintComponent implements OnInit {
-  @Input() public structure: Structure;
-  @Output() public closeDetails: EventEmitter<boolean> = new EventEmitter<boolean>();
-  @Output() public dataReady: EventEmitter<boolean> = new EventEmitter<boolean>();
-  public accessModality = AccessModality;
-  public tclStopPoints: TclStopPoint[] = [];
-
-  constructor(private tclService: TclService, private authService: AuthService) {}
-
-  async ngOnInit(): Promise<void> {
-    // GetTclStopPoints
-    this.getTclStopPoints();
-    const index = this.structure.proceduresAccompaniment.indexOf('autres');
-    if (index > -1) {
-      this.structure.proceduresAccompaniment.splice(index, 1);
-    }
-  }
-
-  public keepOriginalOrder = (a, _b) => a.key;
-
-  public userIsLoggedIn(): boolean {
-    return this.authService.isLoggedIn();
-  }
-
-  public getTclStopPoints(): void {
-    this.tclService.getTclStopPointBycoord(this.structure.getLon(), this.structure.getLat()).subscribe((res) => {
-      this.tclStopPoints = res;
-    });
-  }
-}
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { Structure } from '../../../../models/structure.model';
+import * as _ from 'lodash';
+import { TclService } from '../../../../services/tcl.service';
+import { TclStopPoint } from '../../../../models/tclStopPoint.model';
+import { AuthService } from '../../../../services/auth.service';
+import { AccessModality } from '../../../../structure-list/enum/access-modality.enum';
+@Component({
+  selector: 'app-structure-detail-print',
+  templateUrl: './structure-detail-print.component.html',
+  styleUrls: ['./structure-detail-print.component.scss']
+})
+export class StructureDetailPrintComponent implements OnInit {
+  @Input() public structure: Structure;
+  @Output() public closeDetails: EventEmitter<boolean> = new EventEmitter<boolean>();
+  @Output() public dataReady: EventEmitter<boolean> = new EventEmitter<boolean>();
+  public accessModality = AccessModality;
+  public tclStopPoints: TclStopPoint[] = [];
+
+  constructor(private tclService: TclService, private authService: AuthService) {}
+
+  async ngOnInit(): Promise<void> {
+    // GetTclStopPoints
+    this.getTclStopPoints();
+    const index = this.structure.proceduresAccompaniment.indexOf('autres');
+    if (index > -1) {
+      this.structure.proceduresAccompaniment.splice(index, 1);
+    }
+  }
+
+  public keepOriginalOrder = (a, _b) => a.key;
+
+  public userIsLoggedIn(): boolean {
+    return this.authService.isLoggedIn();
+  }
+
+  public getTclStopPoints(): void {
+    this.tclService.getTclStopPointBycoord(this.structure.getLon(), this.structure.getLat()).subscribe((res) => {
+      this.tclStopPoints = res;
+    });
+  }
+}
diff --git a/src/app/form/orientation-form/component/structure-list-print/structure-list-print.component.ts b/src/app/form/orientation-form/component/structure-list-print/structure-list-print.component.ts
index 9f4c959cf4e66459a660170204ca1e17f75bffde..dc15a3df0d69e9e8c23574b7efe04899def8f0d5 100644
--- a/src/app/form/orientation-form/component/structure-list-print/structure-list-print.component.ts
+++ b/src/app/form/orientation-form/component/structure-list-print/structure-list-print.component.ts
@@ -1,17 +1,18 @@
-import { Component, Input } from '@angular/core';
-import { Filter, Structure } from '@gouvfr-anct/mediation-numerique';
-
-@Component({
-  selector: 'app-structure-list-print',
-  templateUrl: './structure-list-print.component.html',
-  styleUrls: ['./structure-list-print.component.scss'],
-})
-export class StructureListPrintComponent {
-  @Input() public structures: Structure[];
-  @Input() public filters: Filter[];
-  @Input() public beneficiaryNeedCommentary: string;
-  @Input() public beneficiaryName: string;
-  @Input() public structureAccompaniment: string;
-  @Input() public beneficiaryPassNumeric: boolean;
-  @Input() public contactAccompaniment: string;
-}
+import { Component, Input, OnInit } from '@angular/core';
+import { Structure } from '../../../../models/structure.model';
+import * as _ from 'lodash';
+import { Filter } from '../../../../structure-list/models/filter.model';
+@Component({
+  selector: 'app-structure-list-print',
+  templateUrl: './structure-list-print.component.html',
+  styleUrls: ['./structure-list-print.component.scss'],
+})
+export class StructureListPrintComponent {
+  @Input() public structures: Structure[];
+  @Input() public filters: Filter[];
+  @Input() public beneficiaryNeedCommentary: string;
+  @Input() public beneficiaryName: string;
+  @Input() public structureAccompaniment: string;
+  @Input() public beneficiaryPassNumeric: boolean;
+  @Input() public contactAccompaniment: string;
+}
diff --git a/src/app/form/orientation-form/component/structure-print-header/structure-print-header.component.ts b/src/app/form/orientation-form/component/structure-print-header/structure-print-header.component.ts
index 3d50bd4cf4a09017f8c8742938fe4e154c9cdc76..ee7b51cf1d9c8a0327cac110d73303a0fdadef44 100644
--- a/src/app/form/orientation-form/component/structure-print-header/structure-print-header.component.ts
+++ b/src/app/form/orientation-form/component/structure-print-header/structure-print-header.component.ts
@@ -1,69 +1,70 @@
-import { Component, Input, OnInit } from '@angular/core';
-import { ActivatedRoute } from '@angular/router';
-import { Filter } from '@gouvfr-anct/mediation-numerique';
-
-@Component({
-  selector: 'app-structure-print-header',
-  templateUrl: './structure-print-header.component.html',
-  styleUrls: ['./structure-print-header.component.scss'],
-})
-export class StructurePrintHeaderComponent implements OnInit {
-  @Input() public beneficiaryNeedCommentary: string | null;
-  @Input() public beneficiaryName: string | null;
-  @Input() public structureAccompaniment: string;
-  @Input() public beneficiaryPassNumeric: boolean;
-  @Input() public contactAccompaniment: string | null;
-  @Input() public contactAccompanimentPhone: string | null;
-  @Input() public filters: Filter[];
-
-  public date: string;
-  public formations: Filter[] = [];
-  public assistances: Filter[] = [];
-  public equipments: Filter[] = [];
-  public specificNeeds: Filter[] = [];
-
-  constructor(private route: ActivatedRoute) {}
-
-  async ngOnInit(): Promise<void> {
-    this.date = new Date().toLocaleDateString('fr-FR', {
-      weekday: 'long',
-      year: 'numeric',
-      month: 'long',
-      day: 'numeric',
-      hour: 'numeric',
-      minute: 'numeric',
-    });
-
-    this.filters.forEach((elem) => {
-      switch (elem.name) {
-        case 'proceduresAccompaniment':
-          this.assistances.push(elem);
-          break;
-        case 'publicsAccompaniment':
-          this.specificNeeds.push(elem);
-          break;
-        case 'equipmentsAndServices':
-          this.equipments.push(elem);
-          break;
-        case 'accessRight':
-          this.formations.push(elem);
-          break;
-        case 'baseSkills':
-          this.formations.push(elem);
-          break;
-        case 'socialAndProfessional':
-          this.formations.push(elem);
-          break;
-        case 'parentingHelp':
-          this.formations.push(elem);
-          break;
-        case 'digitalCultureSecurity':
-          this.formations.push(elem);
-          break;
-
-        default:
-          break;
-      }
-    });
-  }
-}
+import { Component, Input, OnInit } from '@angular/core';
+import * as _ from 'lodash';
+import { ActivatedRoute } from '@angular/router';
+import { PrintService } from '../../../../shared/service/print.service';
+import { Filter } from '../../../../structure-list/models/filter.model';
+@Component({
+  selector: 'app-structure-print-header',
+  templateUrl: './structure-print-header.component.html',
+  styleUrls: ['./structure-print-header.component.scss'],
+})
+export class StructurePrintHeaderComponent implements OnInit {
+  @Input() public beneficiaryNeedCommentary: string | null;
+  @Input() public beneficiaryName: string | null;
+  @Input() public structureAccompaniment: string;
+  @Input() public beneficiaryPassNumeric: boolean;
+  @Input() public contactAccompaniment: string | null;
+  @Input() public contactAccompanimentPhone: string | null;
+  @Input() public filters: Filter[];
+
+  public date: string;
+  public formations: Filter[] = [];
+  public assistances: Filter[] = [];
+  public equipments: Filter[] = [];
+  public specificNeeds: Filter[] = [];
+
+  constructor(private printService: PrintService, private route: ActivatedRoute) {}
+
+  async ngOnInit(): Promise<void> {
+    this.date = new Date().toLocaleDateString('fr-FR', {
+      weekday: 'long',
+      year: 'numeric',
+      month: 'long',
+      day: 'numeric',
+      hour: 'numeric',
+      minute: 'numeric',
+    });
+
+    this.filters.forEach((elem) => {
+      switch (elem.name) {
+        case 'proceduresAccompaniment':
+          this.assistances.push(elem);
+          break;
+        case 'publicsAccompaniment':
+          this.specificNeeds.push(elem);
+          break;
+        case 'equipmentsAndServices':
+          this.equipments.push(elem);
+          break;
+        case 'accessRight':
+          this.formations.push(elem);
+          break;
+        case 'baseSkills':
+          this.formations.push(elem);
+          break;
+        case 'socialAndProfessional':
+          this.formations.push(elem);
+          break;
+        case 'parentingHelp':
+          this.formations.push(elem);
+          break;
+        case 'digitalCultureSecurity':
+          this.formations.push(elem);
+          break;
+
+        default:
+          break;
+      }
+    });
+  }
+}
diff --git a/src/app/form/orientation-form/orientation-form.component.html b/src/app/form/orientation-form/orientation-form.component.html
index ef39b6dd10bbcd1432f872edc2a6dff1cc6bffd3..a31428cb853239ccb27f4137edd6d6266b0764f2 100644
--- a/src/app/form/orientation-form/orientation-form.component.html
+++ b/src/app/form/orientation-form/orientation-form.component.html
@@ -454,6 +454,12 @@
   [filters]="filters"
 ></app-structure-list-print>
 
+<app-structure-details
+  *ngIf="showStructureDetails"
+  [structure]="selectedStructure"
+  (closeDetails)="closeDetails()"
+></app-structure-details>
+
 <!-- <app-orientation-modal
   *ngIf="displayModal"
   [openned]="true"
diff --git a/src/app/form/orientation-form/orientation-form.component.ts b/src/app/form/orientation-form/orientation-form.component.ts
index a2023765182b63abab78ad02bad8d6623cc7f9e2..af6c80377e30c5e31a09a063152f9e6e3c47722a 100644
--- a/src/app/form/orientation-form/orientation-form.component.ts
+++ b/src/app/form/orientation-form/orientation-form.component.ts
@@ -1,12 +1,16 @@
 import { Component, HostListener, OnInit } from '@angular/core';
 import { AbstractControl, UntypedFormArray, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
 import { Meta } from '@angular/platform-browser';
-import { Address, Category, Filter, Module, Structure } from '@gouvfr-anct/mediation-numerique';
+import { Address } from '../../models/address.model';
 import { OrientationFormFilters } from '../../models/orientation-filter.object';
+import { Structure } from '../../models/structure.model';
 import { GeojsonService } from '../../services/geojson.service';
 import { RouterListenerService } from '../../services/routerListener.service';
 import { StructureService } from '../../services/structure.service';
 import { CategoryEnum } from '../../shared/enum/category.enum';
+import { Category } from '../../structure-list/models/category.model';
+import { Filter } from '../../structure-list/models/filter.model';
+import { Module } from '../../structure-list/models/module.model';
 import { SearchService } from '../../structure-list/services/search.service';
 import { CustomRegExp } from '../../utils/CustomRegExp';
 import { Utils } from '../../utils/utils';
diff --git a/src/app/header/header.component.ts b/src/app/header/header.component.ts
index 34c597c03db5312c4225e6ab42b5c33215919838..0ef560d72f13e46f3151e6a50b43f9de0eee9a0e 100644
--- a/src/app/header/header.component.ts
+++ b/src/app/header/header.component.ts
@@ -1,10 +1,10 @@
 import { animate, animateChild, query, style, transition, trigger } from '@angular/animations';
 import { Component } from '@angular/core';
 import { NavigationEnd, Router } from '@angular/router';
-import { Structure } from '@gouvfr-anct/mediation-numerique';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
+import { Structure } from '../models/structure.model';
 import { ProfileService } from '../profile/services/profile.service';
 import { AuthService } from '../services/auth.service';
+import { ButtonType } from '../shared/components/button/buttonType.enum';
 
 @Component({
   selector: 'app-header',
diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts
index 2244ac0c512e8f6b35391373cb4455a5a33556fd..db47a53afbf8b67a547cd0233509f1976e80cb5d 100644
--- a/src/app/login/login.component.ts
+++ b/src/app/login/login.component.ts
@@ -1,13 +1,13 @@
 import { Component, OnInit } from '@angular/core';
 import { AbstractControl, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
 import { ActivatedRoute, Router, UrlSegment } from '@angular/router';
-import { Structure } from '@gouvfr-anct/mediation-numerique';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
 import { combineLatest } from 'rxjs';
 import { first, map } from 'rxjs/operators';
+import { Structure } from '../models/structure.model';
 import { User } from '../models/user.model';
 import { AuthService } from '../services/auth.service';
 import { StructureService } from '../services/structure.service';
+import { ButtonType } from '../shared/components/button/buttonType.enum';
 import { CustomRegExp } from '../utils/CustomRegExp';
 
 @Component({
diff --git a/src/app/map/components/index.ts b/src/app/map/components/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..45941a73cbaa1d10fc7670c9d256c3b051669356
--- /dev/null
+++ b/src/app/map/components/index.ts
@@ -0,0 +1,6 @@
+import { MapComponent } from './map.component';
+
+export { MapComponent };
+
+// tslint:disable-next-line:variable-name
+export const MapComponents = [MapComponent];
diff --git a/src/app/map/components/layers.enum.ts b/src/app/map/components/layers.enum.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3878af93cdc11e780d3563cdeb364bc63b407b51
--- /dev/null
+++ b/src/app/map/components/layers.enum.ts
@@ -0,0 +1,5 @@
+export enum Layers {
+  mdm = 'mdm',
+  user = 'user',
+  structure = 'structure',
+}
diff --git a/src/app/map/components/map.component.html b/src/app/map/components/map.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..3f5bbc3ed071e86483b5fa3c55c1cf8c5d020db2
--- /dev/null
+++ b/src/app/map/components/map.component.html
@@ -0,0 +1,8 @@
+<div
+  id="map"
+  class="body-wrap"
+  [ngClass]="{ orientation: isOrientationForm }"
+  leaflet
+  [leafletOptions]="mapOptions"
+  (leafletMapReady)="onMapReady($event)"
+></div>
diff --git a/src/app/map/components/map.component.scss b/src/app/map/components/map.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..a699808a9befcca4813cbf074f4148a84bc9f69c
--- /dev/null
+++ b/src/app/map/components/map.component.scss
@@ -0,0 +1,132 @@
+@import '../../../assets/scss/color';
+@import '../../../assets/scss/layout';
+@import '../../../assets/scss/icons';
+@import '../../../assets/scss/typography';
+@import '../../../assets/scss/shapes';
+@import '../../../assets/scss/buttons';
+@import '../../../assets/scss/breakpoint';
+@import '../../../assets/scss/z-index';
+
+#map {
+  height: 100%;
+}
+
+/*** Right controls ***/
+::ng-deep .leaflet-popup-close-button {
+  display: none;
+}
+::ng-deep .leaflet-left {
+  right: 0;
+  left: unset;
+  .leaflet-control {
+    margin-left: 0;
+    margin-right: 10px;
+    border: none;
+    box-shadow: 0px 2px 8px rgba($black, 0.25);
+    &.leaflet-bar a:first-child {
+      border-top-left-radius: 8px;
+      border-top-right-radius: 8px;
+    }
+    &.leaflet-bar a:last-child {
+      border-bottom-left-radius: 8px;
+      border-bottom-right-radius: 8px;
+    }
+  }
+}
+::ng-deep .leaflet-control-zoom {
+  a {
+    color: $grey-1;
+    opacity: 0.55;
+    &:hover {
+      opacity: 1;
+    }
+  }
+}
+
+/*** Marker ***/
+::ng-deep .leaflet-marker-icon {
+  &:hover {
+    z-index: calc($map-selected-marker - 1) !important;
+    svg {
+      fill: $primary-color-dark;
+      &.mdm {
+        fill: $gold;
+      }
+      &.france-service {
+        fill: $primary-color;
+      }
+    }
+  }
+}
+
+/*** POP-UP ***/
+::ng-deep .leaflet-popup {
+  border-radius: 6px;
+  bottom: -15px !important;
+  h1 {
+    color: $grey-1;
+    @include lato-bold-20;
+    font-size: 18px;
+    margin: 0;
+  }
+  p {
+    color: $grey-3;
+    @include lato-regular-16;
+    font-size: 16px;
+    margin: 0 0 13px 0;
+    font-style: italic;
+  }
+  .pop-up {
+    text-align: center;
+    padding-top: 20px;
+    &.orientation {
+      padding: 0;
+      text-align: -webkit-center;
+    }
+
+    button {
+      @include btn-search-filter;
+      @include lato-bold-14;
+      font-size: 16px;
+    }
+
+    .orientationButton {
+      display: flex;
+      padding: 10px 20px;
+      border-radius: 20px;
+      margin: 0 4px;
+      color: $black;
+      background-color: $white;
+      border: solid 1px $grey-3;
+      min-width: 120px;
+    }
+  }
+  span {
+    margin-right: 4px;
+    &.eye {
+      margin-right: 11px;
+    }
+  }
+}
+::ng-deep .leaflet-popup-content-wrapper {
+  border-radius: 6px;
+}
+::ng-deep .leaflet-popup-content {
+  width: 240px;
+}
+::ng-deep .leaflet-popup-tip-container {
+  display: none;
+}
+@media print {
+  .map-wrapper {
+    display: none;
+  }
+}
+
+.body-wrap {
+  height: 400px;
+}
+
+::ng-deep .on-top-marker {
+  z-index: $map-selected-marker !important;
+}
diff --git a/src/app/map/components/map.component.ts b/src/app/map/components/map.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9666d18f5542f97b5b2ec3740c78003be600e95b
--- /dev/null
+++ b/src/app/map/components/map.component.ts
@@ -0,0 +1,327 @@
+import { Component, EventEmitter, HostListener, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
+import L, { geoJSON, latLng, layerGroup, Map, MapOptions, tileLayer } from 'leaflet';
+import * as _ from 'lodash';
+import metropole from '../../../assets/geojson/metropole.json';
+import { Structure } from '../../models/structure.model';
+import { GeojsonService } from '../../services/geojson.service';
+import { GeoJsonProperties } from '../models/geoJsonProperties.model';
+import { MapService } from '../services/map.service';
+import { MarkerType } from './markerType.enum';
+import { ZoomLevel } from './zoomLevel.enum';
+
+@Component({
+  selector: 'app-map',
+  templateUrl: './map.component.html',
+  styleUrls: ['./map.component.scss'],
+})
+export class MapComponent implements OnChanges {
+  @Input() public isOrientationForm = false;
+  @Input() public structures: Structure[] = [];
+  @Input() public structuresToPrint: Structure[] = [];
+  @Input() public toogleToolTipId: string;
+  @Input() public selectedMarkerId: string;
+  @Input() public isMapPhone: boolean;
+  @Input() public searchedValue: string | [number, number];
+  @Output() public selectedStructure: EventEmitter<Structure> = new EventEmitter<Structure>();
+  @Output() public onOrientationButtonClick: EventEmitter<Structure> = new EventEmitter<Structure>();
+  private currentStructure: Structure;
+
+  public map: Map;
+  public mapOptions: MapOptions;
+  public zoomOptions = { animate: true, duration: 0.5 };
+
+  // Add listener on the popup button to show details of structure
+  @HostListener('document:click', ['$event'])
+  public clickout(event): void {
+    if (event.target.classList.contains('btnShowDetails')) {
+      this.selectedStructure.emit(this.currentStructure);
+    }
+    if (event.target.classList.contains('add')) {
+      this.onOrientationButtonClick.emit(this.currentStructure);
+      this.getStructuresPositions(this.structures);
+    }
+  }
+
+  constructor(private mapService: MapService, private geoJsonService: GeojsonService) {
+    this.initializeMapOptions();
+  }
+
+  ngOnChanges(changes: SimpleChanges): void {
+    if (changes.searchedValue && !changes.searchedValue.firstChange) {
+      if (changes.searchedValue.currentValue) {
+        this.processTownCoordinate(changes.searchedValue.currentValue);
+      } else {
+        this.map.setView(this.mapOptions.center, this.mapOptions.zoom);
+      }
+    }
+    if (changes.isMapPhone) {
+      if (this.isMapPhone) {
+        setTimeout(() => {
+          this.map.invalidateSize();
+        }, 0);
+      }
+    }
+    if (changes.structures) {
+      this.handleStructurePosition(changes.structures.previousValue);
+    }
+    // Handle map marker tooltip
+    if (changes.toogleToolTipId && changes.toogleToolTipId.currentValue !== changes.toogleToolTipId.previousValue) {
+      if (changes.toogleToolTipId.previousValue !== undefined) {
+        if (this.isToPrint(changes.toogleToolTipId.previousValue)) {
+          this.mapService.setAddedToListMarker(
+            changes.toogleToolTipId.previousValue,
+            this.getMarkerTypeByStructureId(changes.toogleToolTipId.previousValue)
+          );
+        } else {
+          this.mapService.setUnactiveMarker(
+            changes.toogleToolTipId.previousValue,
+            this.getMarkerTypeByStructureId(changes.toogleToolTipId.previousValue)
+          );
+        }
+      }
+      if (changes.toogleToolTipId.currentValue !== undefined) {
+        this.mapService.setActiveMarker(
+          changes.toogleToolTipId.currentValue,
+          this.getMarkerTypeByStructureId(changes.toogleToolTipId.currentValue)
+        );
+      }
+    }
+    // Handle map marker if none selected
+    if (changes.selectedMarkerId && this.map) {
+      this.map.closePopup();
+      if (changes.selectedMarkerId.currentValue === undefined) {
+        this.mapService.setDefaultMarker(
+          changes.selectedMarkerId.previousValue,
+          this.getMarkerTypeByStructureId(changes.selectedMarkerId.previousValue)
+        );
+        this.map.setView(this.mapOptions.center, this.mapOptions.zoom);
+      }
+    }
+    // Handle map marker if one is set with url or selected
+    if (this.mapService.getMarker(this.selectedMarkerId)) {
+      this.mapService.setSelectedMarker(this.selectedMarkerId, this.getMarkerTypeByStructureId(this.selectedMarkerId));
+      this.centerLeafletMapOnMarker(this.selectedMarkerId);
+    }
+
+    this.closePreviousMarker(changes);
+
+    if (changes.structuresToPrint) {
+      if (changes.structuresToPrint.currentValue < changes.structuresToPrint.previousValue) {
+        this.mapService?.setUnactiveMarker(
+          this.toogleToolTipId,
+          this.getMarkerTypeByStructureId(changes.structuresToPrint.previousValue)
+        );
+      }
+      this.structuresToPrint.forEach((structure: Structure) => {
+        this.mapService.setAddedToListMarker(structure._id, this.getMarkerTypeByStructureId(structure._id));
+      });
+    }
+  }
+
+  public processTownCoordinate(queryString: string): void {
+    this.geoJsonService.getTownshipCoord(queryString).subscribe(
+      (townData) => {
+        if (townData.length > 0) {
+          const bounds = new L.LatLngBounds(townData.map((dataArray) => dataArray.reverse()));
+          this.map.fitBounds(bounds);
+        }
+      },
+      (err) => {
+        this.map.flyTo(this.mapOptions.center, this.mapOptions.zoom, this.zoomOptions);
+      }
+    );
+  }
+
+  /**
+   * Create a user position marcker and center the map on it with a zoom level defined in ZoomLevel
+   * @param coords {[number, number]} Map center position
+   */
+  public centerOnCoordinates(coords: [number, number]): void {
+    this.mapService.createMarker(coords[1], coords[0], MarkerType.user, 'userLocation').addTo(this.map);
+    this.map.flyTo(new L.LatLng(coords[1], coords[0]), ZoomLevel.userPosition, this.zoomOptions);
+  }
+
+  /**
+   * Get structures positions and add marker corresponding to those positons on the map
+   */
+  private handleStructurePosition(previousStructuresValue: Structure[]): void {
+    // If there is more structure than before, append them
+    if (
+      previousStructuresValue &&
+      previousStructuresValue.length > 0 &&
+      previousStructuresValue.length < this.structures.length
+    ) {
+      this.getStructuresPositions(_.differenceWith(this.structures, previousStructuresValue, _.isEqual));
+    } else if (this.structures) {
+      this.map = this.mapService.cleanMap(this.map);
+      this.getStructuresPositions(this.structures);
+      this.structuresToPrint.forEach((structure: Structure) => {
+        this.mapService.setAddedToListMarker(structure._id, this.getMarkerTypeByStructureId(structure._id));
+      });
+    }
+  }
+
+  private isToPrint(id: string): boolean {
+    return this.structuresToPrint.findIndex((elem) => elem._id == id) > -1 ? true : false;
+  }
+
+  /**
+   * Returns according marker type base on {MarkerType}
+   * @param {Structure} structure
+   * @returns {MarkerType}
+   */
+  private getMarkerType(structure: Structure): MarkerType {
+    return structure?.labelsQualifications?.includes('conseillerNumFranceServices')
+      ? MarkerType.conseillerFrance
+      : MarkerType.structure;
+  }
+
+  /**
+   * Return the map marker type given a structure id
+   * @param {string} id - Structure id
+   * @returns {MarkerType}
+   */
+  private getMarkerTypeByStructureId(id: string): MarkerType {
+    return this.getMarkerType(this.structures.find((structure) => structure._id === id));
+  }
+
+  private getStructuresPositions(structureList: Structure[]): void {
+    for (const structure of structureList) {
+      this.mapService
+        .createMarker(
+          structure.getLat(),
+          structure.getLon(),
+          this.getMarkerType(structure),
+          structure._id,
+          this.buildToolTip(structure)
+        )
+        .addTo(this.map)
+        // store structure before user click on button
+        .on('popupopen', () => {
+          this.currentStructure = structure;
+        });
+    }
+  }
+
+  /**
+   * Create tooltip for display
+   * @param structure Structure
+   */
+  private buildToolTip(structure: Structure): string {
+    let cssAvailabilityClass = structure.isOpen ? 'available' : null;
+    if (cssAvailabilityClass === null) {
+      if (structure.openedOn.day) {
+        cssAvailabilityClass = 'unavailable';
+      } else {
+        cssAvailabilityClass = 'unknown';
+      }
+    }
+    return (
+      '<h1>' +
+      structure.structureName +
+      '</h1>' +
+      '<p>' +
+      structure.getLabelTypeStructure() +
+      '</p>' +
+      (this.isOrientationForm
+        ? '<div class="pop-up orientation"><button type="button" class="orientationButton btnShowDetails"><span class="ico-gg-eye-alt eye"></span>Voir</button></div>'
+        : '<div class="pop-up"><button type="button" class="btnShowDetails">Voir</button></div>')
+    );
+  }
+
+  private buildMdmPopUp(mdmProperties: GeoJsonProperties): string {
+    return `<h1>${mdmProperties.nom}</h1><p>${mdmProperties.adresse}</p>`;
+  }
+
+  /**
+   * Add marker when map is ready to be showned
+   * @param map map
+   */
+  public onMapReady(map: Map): void {
+    this.map = map;
+    if (this.searchedValue) {
+      if (Array.isArray(this.searchedValue)) {
+        this.centerOnCoordinates(this.searchedValue);
+      }
+    }
+  }
+
+  /**
+   * Init map options :
+   * - Metropole bounds based on a WMS service hosted by data.grandlyon.com
+   * - Map Layer based on open street maps
+   */
+  private initializeMapOptions(): void {
+    // Init mdm
+    this.initMDMLayer();
+    // Init WMS service with param from data.grandlyon.com
+    layerGroup();
+    const carteLayer = tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png', {
+      attribution: '&copy; <a href="https://carto.com/attributions">CARTO</a>',
+      maxZoom: ZoomLevel.max,
+    });
+    // Center is set on townhall
+    // Zoom is blocked on 11 to prevent people to zoom out from metropole
+    this.mapOptions = {
+      center: latLng(45.764043, 4.835659),
+      maxZoom: ZoomLevel.max,
+      zoom: ZoomLevel.regular,
+      minZoom: ZoomLevel.min,
+      layers: [carteLayer],
+    };
+  }
+
+  private initMDMLayer(): void {
+    this.geoJsonService.getMDMGeoJson().subscribe((res) => {
+      res.forEach((mdm) => {
+        this.mapService
+          .createMarker(
+            mdm.geometry.getLat(),
+            mdm.geometry.getLon(),
+            MarkerType.mdm,
+            null,
+            this.buildMdmPopUp(mdm.properties)
+          )
+          .addTo(this.map);
+      });
+      this.initMetropoleLayer();
+    });
+  }
+
+  private centerLeafletMapOnMarker(markerId: string): void {
+    if (this.mapService.getMarker(markerId)) {
+      const marker = this.mapService.getMarker(markerId);
+      const latLngs = marker.getLatLng();
+      this.map.flyTo(new L.LatLng(latLngs.lat, latLngs.lng), ZoomLevel.max, this.zoomOptions);
+    }
+  }
+
+  private initMetropoleLayer(): void {
+    this.map.addLayer(
+      geoJSON(
+        {
+          type: metropole.features[0].geometry.type,
+          coordinates: metropole.features[0].geometry.coordinates,
+        } as any,
+        { style: () => ({ color: '#a00000', fillOpacity: 0, weight: 1 }) }
+      )
+    );
+  }
+
+  /**
+   * Close previous markers
+   * - if strucure is closed
+   * - if a new marker is selected
+   */
+  private closePreviousMarker(changes: SimpleChanges): void {
+    if (
+      (changes.selectedMarkerId?.currentValue === undefined && changes.selectedMarkerId?.previousValue) ||
+      changes.selectedMarkerId?.currentValue !== changes.selectedMarkerId?.previousValue
+    ) {
+      this.mapService.setUnactiveMarker(
+        changes.selectedMarkerId.previousValue,
+        this.getMarkerTypeByStructureId(changes.selectedMarkerId.previousValue)
+      );
+    }
+  }
+}
diff --git a/src/app/config/map/marker-type.ts b/src/app/map/components/markerType.enum.ts
similarity index 93%
rename from src/app/config/map/marker-type.ts
rename to src/app/map/components/markerType.enum.ts
index 3f1159bb9b417bfb1e2f71781b77e41c30e12858..ade600852dfb0fc14221e0b73e6e8efc8638dbff 100644
--- a/src/app/config/map/marker-type.ts
+++ b/src/app/map/components/markerType.enum.ts
@@ -1,6 +1,6 @@
-export enum MarkerType {
-  structure = 0,
-  mdm = 1,
-  conseillerFrance = 2,
-  user = 3,
-}
+export enum MarkerType {
+  structure = 0,
+  mdm = 1,
+  conseillerFrance = 2,
+  user = 3,
+}
diff --git a/src/app/config/map/zoomLevel.enum.ts b/src/app/map/components/zoomLevel.enum.ts
similarity index 93%
rename from src/app/config/map/zoomLevel.enum.ts
rename to src/app/map/components/zoomLevel.enum.ts
index 02e7a5e9432fbbc9f8562d86ee37a33fd501e4a0..fe020b772f172ac8fc926271fe7d10bb4e035449 100644
--- a/src/app/config/map/zoomLevel.enum.ts
+++ b/src/app/map/components/zoomLevel.enum.ts
@@ -1,6 +1,6 @@
-export enum ZoomLevel {
-  min = 10,
-  regular = 12,
-  userPosition = 15,
-  max = 19,
-}
+export enum ZoomLevel {
+  min = 10,
+  regular = 12,
+  userPosition = 15,
+  max = 19,
+}
diff --git a/src/app/map/map.module.ts b/src/app/map/map.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fbb935ca5b3f27df1df0efded58dccc7d0380c1a
--- /dev/null
+++ b/src/app/map/map.module.ts
@@ -0,0 +1,13 @@
+import { NgModule } from '@angular/core';
+import { CommonModule, DatePipe } from '@angular/common';
+import { SharedModule } from '../shared/shared.module';
+import { MapComponents } from './components';
+import { LeafletModule } from '@asymmetrik/ngx-leaflet';
+import { BrowserModule } from '@angular/platform-browser';
+@NgModule({
+  imports: [CommonModule, BrowserModule, SharedModule, LeafletModule],
+  declarations: [MapComponents],
+  providers: [DatePipe],
+  exports: [MapComponents],
+})
+export class MapModule {}
diff --git a/src/app/map/models/addressGeometry.model.ts b/src/app/map/models/addressGeometry.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b7612f2fc5fb6cd32127ca4e6779560bccd9f103
--- /dev/null
+++ b/src/app/map/models/addressGeometry.model.ts
@@ -0,0 +1,16 @@
+export class AddressGeometry {
+  public coordinates: Array<number>;
+  public type: string;
+
+  constructor(obj?: any) {
+    Object.assign(this, obj);
+  }
+
+  public getLat(): number {
+    return this.coordinates[1];
+  }
+
+  public getLon(): number {
+    return this.coordinates[0];
+  }
+}
diff --git a/src/app/map/models/geoJsonProperties.model.ts b/src/app/map/models/geoJsonProperties.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..adbd5378f31e46cf1e6c27283f758cf9f498f053
--- /dev/null
+++ b/src/app/map/models/geoJsonProperties.model.ts
@@ -0,0 +1,10 @@
+export class GeoJsonProperties {
+  public city: string;
+  public country: string;
+  public name: string;
+  public nom: string;
+  public postcode: string;
+  public state: string;
+  public adresse: string;
+  public ville: string;
+}
diff --git a/src/app/map/models/geojson.model.ts b/src/app/map/models/geojson.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8ca263895f084b62e528a5dc49280ded859bdab9
--- /dev/null
+++ b/src/app/map/models/geojson.model.ts
@@ -0,0 +1,14 @@
+import { AddressGeometry } from './addressGeometry.model';
+import { GeoJsonProperties } from './geoJsonProperties.model';
+
+export class GeoJson {
+  public geometry: AddressGeometry;
+  public type: string;
+  public properties: GeoJsonProperties;
+
+  constructor(obj?: any) {
+    Object.assign(this, obj, {
+      geometry: obj && obj.geometry ? new AddressGeometry(obj.geometry) : null,
+    });
+  }
+}
diff --git a/src/app/map/services/map.service.spec.ts b/src/app/map/services/map.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cd06fb3f41abb24d4fd933ea73c71ff3cbd27970
--- /dev/null
+++ b/src/app/map/services/map.service.spec.ts
@@ -0,0 +1,46 @@
+import { TestBed } from '@angular/core/testing';
+
+import { MapService } from './map.service';
+
+describe('MapService', () => {
+  let service: MapService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(MapService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+
+  it('should create marke with coord {lat: 45.764043, lng: 4.835659}', () => {
+    const marker = service.createMarker(45.764043, 4.835659, 1);
+
+    expect(marker.getLatLng().lat).toEqual(45.764043);
+    expect(marker.getLatLng().lng).toEqual(4.835659);
+  });
+  it('should add marker to map with icon ic_marker.png', () => {
+    const marker = service.createMarker(45.764043, 4.835659, 1);
+    expect(marker.getIcon().options.iconSize).toEqual([19, 24]);
+    expect(marker.getIcon().options.iconAnchor).toEqual([9, 0]);
+  });
+
+  it('should cerate marker with popup', () => {
+    const marker = service.createMarker(45.764043, 4.835659, 1, null, '<p>Hello <br/>World !</p>');
+
+    expect(marker.getPopup().getContent()).toEqual('<p>Hello <br/>World !</p>');
+  });
+
+  it('should get marker', () => {
+    const marker = service.createMarker(45.764043, 4.835659, 1, "53", '<p>Hello <br/>World !</p>');
+    expect(marker).toEqual(service.getMarker("53"));
+  });
+  it('should not get marker, with missing id', () => {
+    service.createMarker(45.764043, 4.835659, 1, null, '<p>Hello <br/>World !</p>');
+    expect(service.getMarker("2")).toEqual(null);
+  });
+  it('should not get marker, empty', () => {
+    expect(service.getMarker("2")).toEqual(null);
+  });
+});
diff --git a/src/app/map/services/map.service.ts b/src/app/map/services/map.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f5c641f9085d4a77dde27ac648bd0b9175979f69
--- /dev/null
+++ b/src/app/map/services/map.service.ts
@@ -0,0 +1,179 @@
+import { Injectable } from '@angular/core';
+import { DivIcon, Map, Marker } from 'leaflet';
+import { Layers } from '../components/layers.enum';
+import { MarkerType } from '../components/markerType.enum';
+import {
+  markerIcon,
+  markerIconActive,
+  markerIconAddedToList,
+  markerIconHover,
+  markerIconMdm,
+  markerIconMdmActive,
+  userLocationIcon,
+} from './marker';
+@Injectable({
+  providedIn: 'root',
+})
+export class MapService {
+  private static markersList = {};
+  private isMarkerActive = false;
+
+  public createMarker(lat: number, lon: number, markerType: MarkerType, id?: string, tooltip?: string): Marker {
+    const marker = new Marker([lat, lon], {
+      icon: this.getMarkerIcon(markerType),
+      attribution: this.getLayerAttributton(markerType),
+    });
+    marker.on('mouseclick', (evt) => {
+      evt.target.openPopup();
+    });
+
+    // handle icon change when select marker
+    marker.on('click', (evt) => {
+      evt.target.setIcon(this.getActiveMarkerIcon(markerType));
+    });
+
+    if (tooltip) {
+      marker.bindPopup(tooltip);
+
+      // handle icon change when unselect
+      marker.getPopup().on('remove', (evt) => {
+        marker.setIcon(this.getMarkerIcon(markerType));
+      });
+    }
+
+    if (id) {
+      MapService.markersList[id] = marker;
+    }
+    return marker;
+  }
+
+  private getLayerAttributton(markerType: MarkerType): string {
+    if (markerType === MarkerType.mdm) {
+      return Layers.mdm;
+    } else if (markerType === MarkerType.user) {
+      return Layers.user;
+    } else {
+      return Layers.structure;
+    }
+  }
+
+  // Note: Marke IconFranceService has been removed temporarly on order to rework on buisness needs.
+  // This comment is applied for the next 4 methods
+  private getMarkerIcon(markerType: MarkerType): DivIcon {
+    switch (markerType) {
+      case MarkerType.mdm:
+        return markerIconMdm;
+      case MarkerType.conseillerFrance:
+        return markerIcon;
+      case MarkerType.user:
+        return userLocationIcon;
+      default:
+        return markerIcon;
+    }
+  }
+
+  private getActiveMarkerIcon(markerType: MarkerType): DivIcon {
+    switch (markerType) {
+      case MarkerType.mdm:
+        return markerIconMdmActive;
+      case MarkerType.conseillerFrance:
+        // return markerIconFranceServiceActive;
+        return markerIconActive;
+      case MarkerType.user:
+        return userLocationIcon;
+      default:
+        return markerIconActive;
+    }
+  }
+
+  private getAddedToListMarkerIcon(markerType: MarkerType): DivIcon {
+    switch (markerType) {
+      case MarkerType.conseillerFrance:
+        // return markerIconFranceServiceAddedToList;
+        return markerIconAddedToList;
+      case MarkerType.user:
+        return userLocationIcon;
+      default:
+        return markerIconAddedToList;
+    }
+  }
+
+  private getHoverMarkerIcon(markerType: MarkerType): DivIcon {
+    switch (markerType) {
+      case MarkerType.conseillerFrance:
+        return markerIconHover;
+      case MarkerType.user:
+        return userLocationIcon;
+      default:
+        return markerIconHover;
+    }
+  }
+
+  /**
+   * @param id marker id
+   */
+  public setActiveMarker(id: string, type: MarkerType = MarkerType.structure): void {
+    this.getMarker(id).setIcon(this.getHoverMarkerIcon(type));
+  }
+
+  public setAddedToListMarker(id: string, type: MarkerType = MarkerType.structure): void {
+    this.getMarker(id).setIcon(this.getAddedToListMarkerIcon(type));
+  }
+
+  public setUnactiveMarker(id: string, type: MarkerType = MarkerType.structure): void {
+    // To skip mouseleave when user emit click on structure list
+    this.getMarker(id)?.setIcon(this.getMarkerIcon(type));
+    this.isMarkerActive = false;
+  }
+
+  /**
+   * Set a tooltip
+   * @param id markerId
+   * @param html html to display
+   */
+  public setToolTip(id: string, html: string): void {
+    this.getMarker(id).bindTooltip(html);
+  }
+
+  /**
+   * Set a marker as selected by changing icon color
+   * @param id markerId
+   * @param html html to display
+   */
+  public setSelectedMarker(id: string, type: MarkerType = MarkerType.structure): void {
+    if (id) {
+      this.getMarker(id)?.setIcon(this.getActiveMarkerIcon(type));
+      this.isMarkerActive = true;
+    }
+  }
+
+  /**
+   * Set a marker as selected by changing icon color
+   * @param id markerId
+   * @param html html to display
+   */
+  public setDefaultMarker(id: string, type: MarkerType = MarkerType.structure): void {
+    if (id) {
+      this.getMarker(id).setIcon(this.getMarkerIcon(type));
+    }
+  }
+
+  /**
+   * Get marker by id
+   */
+  public getMarker(id: string): Marker {
+    return MapService.markersList[id] ? MapService.markersList[id] : null;
+  }
+
+  public cleanMap(map: Map): Map {
+    MapService.markersList = {};
+    if (map) {
+      map.eachLayer((layer) => {
+        if (layer instanceof Marker && layer.options.attribution == Layers.structure) {
+          map.removeLayer(layer);
+        }
+      });
+    }
+    return map;
+  }
+}
diff --git a/src/app/map/services/marker.ts b/src/app/map/services/marker.ts
new file mode 100644
index 0000000000000000000000000000000000000000..35efbc6ed376d8781d8163247edf5a732eb43a6d
--- /dev/null
+++ b/src/app/map/services/marker.ts
@@ -0,0 +1,79 @@
+import { divIcon } from 'leaflet';
+
+export const markerIcon = divIcon({
+  className: null,
+  html: '<svg width="48" height="48" fill="#4C4D53"><use xlink:href="assets/ico/sprite.svg#map-marker"></use></svg>',
+  iconSize: [48, 48],
+  iconAnchor: [24, 48],
+  popupAnchor: [0, -48],
+});
+export const markerIconActive = divIcon({
+  className: 'on-top-marker',
+  html: '<svg width="48" height="48"><use xlink:href="assets/ico/sprite.svg#map-markerSelected"></use></svg>',
+  iconSize: [48, 48],
+  iconAnchor: [24, 48],
+  popupAnchor: [0, -48],
+});
+export const markerIconHover = divIcon({
+  className: 'on-top-marker',
+  html: '<svg width="48" height="48"><use xlink:href="assets/ico/sprite.svg#map-markerHover"></use></svg>',
+  iconSize: [48, 48],
+  iconAnchor: [24, 48],
+  popupAnchor: [0, -48],
+});
+export const markerIconAddedToList = divIcon({
+  className: null,
+  html: '<svg width="48" height="48"><use xlink:href="assets/ico/sprite.svg#map-marker-added"></use></svg>',
+  iconSize: [48, 48],
+  iconAnchor: [24, 48],
+  popupAnchor: [0, -48],
+});
+export const userLocationIcon = divIcon({
+  className: null,
+  html: '<svg width="34" height="34"><use xlink:href="assets/ico/sprite.svg#user-location"></use></svg>',
+  iconSize: [34, 34],
+  iconAnchor: [17, 0],
+});
+export const markerIconMdm = divIcon({
+  className: null,
+  html:
+    '<svg width="19" height="24" fill="#D4C4A9" class="mdm"><use xlink:href="assets/ico/sprite.svg#mdm"></use></svg>',
+  iconSize: [19, 24],
+  iconAnchor: [9, 0],
+});
+export const markerIconMdmActive = divIcon({
+  className: null,
+  html: '<svg width="19" height="24"><use xlink:href="assets/ico/sprite.svg#mdmActive"></use></svg>',
+  iconSize: [19, 24],
+  iconAnchor: [9, 0],
+});
+export const markerIconFranceService = divIcon({
+  className: null,
+  html:
+    '<svg width="48" height="48" fill="#ED3939" class="france-service"><use xlink:href="assets/ico/sprite.svg#conseillerFranceService"></use></svg>',
+  iconSize: [48, 48],
+  iconAnchor: [24, 48],
+  popupAnchor: [0, -48],
+});
+export const markerIconFranceServiceActive = divIcon({
+  className: null,
+  html:
+    '<svg width="48" height="48"><use xlink:href="assets/ico/sprite.svg#conseillerFranceServiceSelected"></use></svg>',
+  iconSize: [48, 48],
+  iconAnchor: [24, 48],
+  popupAnchor: [0, -48],
+});
+export const markerIconFranceServiceHover = divIcon({
+  className: null,
+  html: '<svg width="48" height="48"><use xlink:href="assets/ico/sprite.svg#conseillerFranceServiceHover"></use></svg>',
+  iconSize: [48, 48],
+  iconAnchor: [24, 48],
+  popupAnchor: [0, -48],
+});
+export const markerIconFranceServiceAddedToList = divIcon({
+  className: null,
+  html: '<svg width="48" height="48"><use xlink:href="assets/ico/sprite.svg#conseillerFranceServiceAdded"></use></svg>',
+  iconSize: [48, 48],
+  iconAnchor: [24, 48],
+  popupAnchor: [0, -48],
+});
diff --git a/src/app/models/address.model.ts b/src/app/models/address.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8ef6bc349a222c69531a34eac3331b4174c974a2
--- /dev/null
+++ b/src/app/models/address.model.ts
@@ -0,0 +1,7 @@
+export class Address {
+  numero: string = null;
+  street: string = null;
+  commune: string = null;
+  postcode?: number = null;
+  coordinates? = [];
+}
diff --git a/src/app/models/day.model.ts b/src/app/models/day.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..005ccfa242ebb935a533cd0d2f151dded3377e1f
--- /dev/null
+++ b/src/app/models/day.model.ts
@@ -0,0 +1,12 @@
+import { Time } from './time.model';
+
+export class Day {
+  open: boolean = false;
+  time: Time[];
+
+  constructor(obj?: any) {
+    Object.assign(this, obj, {
+      time: obj && obj.time ? obj.time.map((time) => new Time(time)) : [],
+    });
+  }
+}
diff --git a/src/app/models/openingDay.model.ts b/src/app/models/openingDay.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..71ba8d444c97b55c4393830dfa483caf5cff4845
--- /dev/null
+++ b/src/app/models/openingDay.model.ts
@@ -0,0 +1,9 @@
+export class OpeningDay {
+  day: string = null;
+  schedule: string = null;
+
+  constructor(day?: string, schedule?: string) {
+    this.day = day;
+    this.schedule = schedule;
+  }
+}
diff --git a/src/app/models/orientation-filter.object.ts b/src/app/models/orientation-filter.object.ts
index 65d327d9cf0bd0b47c4310e209112ae9e997029c..49fe9ca54662b52e32c1a6fe7afc51396d1e5a2c 100644
--- a/src/app/models/orientation-filter.object.ts
+++ b/src/app/models/orientation-filter.object.ts
@@ -1,13 +1,15 @@
-import { Address, Category } from '@gouvfr-anct/mediation-numerique';
-
-export class OrientationFormFilters {
-  specificProfile: Category;
-  handicap: boolean;
-  passNumeric: boolean;
-  structureAccompaniment: string;
-  contactAccompanimentPhone: string;
-  contactAccompanimentEmail: string;
-  beneficiaryName: string;
-  beneficiaryNeedCommentary: string;
-  address: Address;
-}
+import { Category } from '../structure-list/models/category.model';
+import { Module } from '../structure-list/models/module.model';
+import { Address } from './address.model';
+
+export class OrientationFormFilters {
+  specificProfile: Category;
+  handicap: boolean;
+  passNumeric: boolean;
+  structureAccompaniment: string;
+  contactAccompanimentPhone: string;
+  contactAccompanimentEmail: string;
+  beneficiaryName: string;
+  beneficiaryNeedCommentary: string;
+  address: Address;
+}
diff --git a/src/app/models/owner.model.ts b/src/app/models/owner.model.ts
index 55bc8c6c60a4f38d153d977935a5e5028a17bcef..45a6de715c2934e0fac3ff79d39b6890db89d016 100644
--- a/src/app/models/owner.model.ts
+++ b/src/app/models/owner.model.ts
@@ -1,5 +1,4 @@
 export class Owner {
   email: string;
   _id: string;
-  // id: string;
 }
diff --git a/src/app/models/personalOffer.model.ts b/src/app/models/personalOffer.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e2edde9968953196aab6d86608dece76363d9f32
--- /dev/null
+++ b/src/app/models/personalOffer.model.ts
@@ -0,0 +1,9 @@
+export class PersonalOffer {
+  public publicsAccompaniment: string[] = [];
+  public proceduresAccompaniment: string[] = [];
+  public baseSkills: string[] = [];
+  public accessRight: string[] = [];
+  public digitalCultureSecurity: string[] = [];
+  public socialAndProfessional: string[] = [];
+  public parentingHelp: string[] = [];
+}
diff --git a/src/app/models/structure.model.ts b/src/app/models/structure.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..344e442ea40ef2f2c895ea841c480a9954c9d73d
--- /dev/null
+++ b/src/app/models/structure.model.ts
@@ -0,0 +1,202 @@
+import { Equipment } from '../structure-list/enum/equipment.enum';
+import { typeStructureEnum } from '../shared/enum/typeStructure.enum';
+import { Weekday } from '../structure-list/enum/weekday.enum';
+import { Address } from './address.model';
+import { Day } from './day.model';
+import { OpeningDay } from './openingDay.model';
+import { Week } from './week.model';
+import { PersonalOffer } from './personalOffer.model';
+
+export class Structure {
+  public _id: string = null;
+  public numero: string = null;
+  public createdAt: string = null;
+  public updatedAt: string = null;
+  public structureName: string = null;
+  public structureType: string = null;
+  public description: string = null;
+  public address: Address = new Address();
+  public contactPhone: string = null;
+  public contactMail: string = null;
+  public website: string = null;
+  public facebook: string = null;
+  public twitter: string = null;
+  public instagram: string = null;
+  public linkedin: string = null;
+  public lockdownActivity: string = null;
+  public pmrAccess: boolean = null;
+  public placeOfReception: boolean = null;
+  public choiceCompletion: boolean = null;
+  public contactPersonFirstName: string = null;
+  public contactPersonLastName: string = null;
+  public contactPersonEmail: string = null;
+  public publicsAccompaniment: string[] = [];
+  public proceduresAccompaniment: string[] = [];
+  public remoteAccompaniment: boolean = null;
+  public accessModality: string[] = [];
+  public labelsQualifications: string[] = [];
+  public publics: string[] = [];
+  public nbComputers: number = null;
+  public nbPrinters: number = null;
+  public nbTablets: number = null;
+  public nbNumericTerminal: number = null;
+  public nbScanners: number = null;
+  public exceptionalClosures: string = null;
+  public equipmentsAndServices: string[] = [];
+  public hours: Week;
+  public freeWorkShop: boolean = null;
+  public otherDescription: string = null;
+
+  public isOpen: boolean = false;
+  public openedOn: OpeningDay = new OpeningDay();
+  public baseSkills: string[] = [];
+  public accessRight: string[] = [];
+  public parentingHelp: string[] = [];
+  public socialAndProfessional: string[] = [];
+  public digitalCultureSecurity: string[] = [];
+
+  public distance?: number;
+  public coord?: number[] = [];
+  public dataShareConsentDate?: string;
+
+  public accountVerified: boolean = false;
+
+  public personalOffers: PersonalOffer[] = [];
+
+  public alreadySelected? = false;
+  public isClaimed?: boolean = null;
+
+  constructor(obj?: any) {
+    Object.assign(this, obj, {
+      hours: obj && obj.hours ? new Week(obj.hours) : new Week(),
+    });
+  }
+
+  public getDayhours(day: Weekday): Day {
+    switch (day) {
+      case Weekday.monday:
+        return this.hours.monday;
+      case Weekday.tuesday:
+        return this.hours.tuesday;
+      case Weekday.thursday:
+        return this.hours.thursday;
+      case Weekday.wednesday:
+        return this.hours.wednesday;
+      case Weekday.friday:
+        return this.hours.friday;
+      case Weekday.saturday:
+        return this.hours.saturday;
+      case Weekday.sunday:
+        return this.hours.sunday;
+      default:
+        return null;
+    }
+  }
+
+  /**
+   * Check if a structure has equipments
+   */
+  public hasEquipments(): boolean {
+    if (this.equipmentsAndServices.length && this.hasNotOnlyEmptyEquipments()) {
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * Verify that a structure as not only equipments with 0 as value. This is mostly use for display.
+   * @returns {Boolean} validation
+   */
+  public hasNotOnlyEmptyEquipments(): boolean {
+    if (this.nbComputers + this.nbPrinters + this.nbTablets + this.nbNumericTerminal + this.nbScanners > 0) return true;
+    return false;
+  }
+
+  /**
+   * Check if a structure has pass Numeric label
+   */
+  public hasPassNumeric(): boolean {
+    return this.labelsQualifications.includes('passNumerique');
+  }
+
+  /**
+   * Return a range, according to the distance, between [1,3] to get a distance reference.
+   * - [0,5km] => 1
+   * - [5km,10km] => 2
+   * - [10km, [ => 3
+   */
+  public getDistanceRange(): number {
+    if (!this.distance) {
+      return 3;
+    } else {
+      // If it's in km
+      if (this.distance > 10000) {
+        return 3;
+      } else if (this.distance < 5000) {
+        // If it's between 0 and 500 m
+        return 1;
+      } else {
+        return 2;
+      }
+    }
+  }
+
+  public getLat(): number {
+    return this.coord[1];
+  }
+
+  public getLon(): number {
+    return this.coord[0];
+  }
+
+  public getEquipmentsIcon(equipment: Equipment): string {
+    switch (equipment) {
+      case Equipment.wifi:
+        return 'wifi';
+      case Equipment.bornes:
+        return 'borne';
+      case Equipment.printer:
+        return 'print';
+      case Equipment.tablet:
+        return 'tablet';
+      case Equipment.computer:
+        return 'computer';
+      case Equipment.scanner:
+        return 'scan';
+      default:
+        return null;
+    }
+  }
+
+  public getEquipmentsTitle(equipment: Equipment): string {
+    switch (equipment) {
+      case Equipment.wifi:
+        return 'Wifi en accès libre';
+      case Equipment.bornes:
+        return this.nbNumericTerminal > 1 ? 'Bornes numériques' : 'Borne numérique';
+      case Equipment.printer:
+        return this.nbPrinters > 1 ? 'Imprimantes' : 'Imprimante';
+      case Equipment.tablet:
+        return this.nbTablets > 1 ? 'Tablettes' : 'Tablette';
+      case Equipment.computer:
+        return this.nbComputers > 1 ? 'Ordinateurs' : 'Ordinateur';
+      case Equipment.scanner:
+        return this.nbScanners > 1 ? 'Scanners' : 'Scanner';
+      default:
+        return null;
+    }
+  }
+
+  public getLabelTypeStructure(): string {
+    return typeStructureEnum[this.structureType] ? typeStructureEnum[this.structureType] : '';
+  }
+
+  public hasSocialNetwork(): boolean {
+    return (
+      (this.facebook !== null && this.facebook !== '') ||
+      (this.instagram !== null && this.instagram !== '') ||
+      (this.linkedin !== null && this.linkedin !== '') ||
+      (this.twitter !== null && this.twitter !== '')
+    );
+  }
+}
diff --git a/src/app/models/structureWithOwners.model.ts b/src/app/models/structureWithOwners.model.ts
index cf8219dcb8a0d7e14443f3533513510d3e3d5c98..e3d2a6340abb8cf3ac225e16e43a0657c6f41d38 100644
--- a/src/app/models/structureWithOwners.model.ts
+++ b/src/app/models/structureWithOwners.model.ts
@@ -1,7 +1,7 @@
-import { Structure } from '@gouvfr-anct/mediation-numerique';
-import { Owner } from './owner.model';
-
-export class StructureWithOwners {
-  structure: Structure;
-  owners: Owner[];
-}
+import { Owner } from './owner.model';
+import { Structure } from './structure.model';
+
+export class StructureWithOwners {
+  structure: Structure;
+  owners: Owner[];
+}
diff --git a/src/app/models/time.model.ts b/src/app/models/time.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7db99ae8b9cd374e8e06e1cdb410a54810fd025c
--- /dev/null
+++ b/src/app/models/time.model.ts
@@ -0,0 +1,20 @@
+export class Time {
+  opening: string;
+  closing: string;
+
+  constructor(obj?: any) {
+    Object.assign(this, obj);
+  }
+
+  public formatOpeningDate(): string {
+    return this.formatDate(this.opening);
+  }
+
+  public formatClosingDate(): string {
+    return this.formatDate(this.closing);
+  }
+
+  private formatDate(n: string): string {
+    return n.replace(':', 'h');
+  }
+}
diff --git a/src/app/models/week.model.ts b/src/app/models/week.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..14942b10743042703483e7882544e0d1a238f5af
--- /dev/null
+++ b/src/app/models/week.model.ts
@@ -0,0 +1,59 @@
+import { Day } from './day.model';
+
+export class Week {
+  monday: Day;
+  tuesday: Day;
+  wednesday: Day;
+  thursday: Day;
+  friday: Day;
+  saturday: Day;
+  sunday: Day;
+
+  constructor(obj?: any) {
+    Object.assign(this, obj, {
+      monday: obj && obj.monday ? new Day(obj.monday) : new Day(),
+      tuesday: obj && obj.tuesday ? new Day(obj.tuesday) : new Day(),
+      wednesday: obj && obj.wednesday ? new Day(obj.wednesday) : new Day(),
+      thursday: obj && obj.thursday ? new Day(obj.thursday) : new Day(),
+      friday: obj && obj.friday ? new Day(obj.friday) : new Day(),
+      saturday: obj && obj.saturday ? new Day(obj.saturday) : new Day(),
+      sunday: obj && obj.sunday ? new Day(obj.sunday) : new Day(),
+    });
+  }
+
+  public getDayTranslation(day: string): string {
+    switch (day) {
+      case 'monday':
+        return 'lundi';
+      case 'tuesday':
+        return 'mardi';
+      case 'thursday':
+        return 'jeudi';
+      case 'wednesday':
+        return 'mercredi';
+      case 'friday':
+        return 'vendredi';
+      case 'saturday':
+        return 'samedi';
+      case 'sunday':
+        return 'dimanche';
+      default:
+        return null;
+    }
+  }
+
+  public hasData() {
+    if (
+      this.monday.time.length === 0 &&
+      this.tuesday.time.length === 0 &&
+      this.wednesday.time.length === 0 &&
+      this.thursday.time.length === 0 &&
+      this.friday.time.length === 0 &&
+      this.saturday.time.length === 0 &&
+      this.sunday.time.length === 0
+    ) {
+      return false;
+    }
+    return true;
+  }
+}
diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts
index 57146a1b7eeff793026b8fd572e4731b395c3817..ca4a6e47513ef01f48846487875952a5697faf60 100644
--- a/src/app/profile/edit/edit.component.ts
+++ b/src/app/profile/edit/edit.component.ts
@@ -1,15 +1,15 @@
-import { HttpErrorResponse } from '@angular/common/http';
 import { ChangeDetectorRef, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
+import { HttpErrorResponse } from '@angular/common/http';
 import { forkJoin, of } from 'rxjs';
 import { catchError, first, map } from 'rxjs/operators';
-import { Employer } from '../../models/employer.model';
 import { Job } from '../../models/job.model';
 import { User } from '../../models/user.model';
+import { Employer } from '../../models/employer.model';
 import { AuthService } from '../../services/auth.service';
+import { ProfileService } from '../services/profile.service';
 import { NotificationService } from '../../services/notification.service';
+import { ButtonType } from '../../shared/components/button/buttonType.enum';
 import { CustomRegExp } from '../../utils/CustomRegExp';
-import { ProfileService } from '../services/profile.service';
 
 enum tabsEnum {
   details,
diff --git a/src/app/profile/profile.component.ts b/src/app/profile/profile.component.ts
index d6534cc2ab5969752ea250db701015a4ea2a33cc..d977fbecdd4bd3f6e1f41cf44b30de1d48ad39f1 100644
--- a/src/app/profile/profile.component.ts
+++ b/src/app/profile/profile.component.ts
@@ -1,10 +1,10 @@
 import { UserService } from './../services/user.service';
 import { Component, OnInit } from '@angular/core';
 import { Router, ActivatedRoute } from '@angular/router';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
 import { StructureWithOwners } from '../models/structureWithOwners.model';
 import { User } from '../models/user.model';
 import { StructureService } from '../services/structure.service';
+import { ButtonType } from '../shared/components/button/buttonType.enum';
 import { ProfileService } from './services/profile.service';
 import { Utils } from '../utils/utils';
 import { catchError, map } from 'rxjs/operators';
diff --git a/src/app/profile/services/profile.service.ts b/src/app/profile/services/profile.service.ts
index 12787c79376f66de6e6a9e694e03e66ef059467d..50b1dadffdc7acbae1b9589e3e713f6cf95d63ac 100644
--- a/src/app/profile/services/profile.service.ts
+++ b/src/app/profile/services/profile.service.ts
@@ -1,15 +1,15 @@
 import { HttpClient } from '@angular/common/http';
 import { Injectable } from '@angular/core';
-import { Structure } from '@gouvfr-anct/mediation-numerique';
-import decode from 'jwt-decode';
 import { Observable } from 'rxjs';
-import { catchError, map } from 'rxjs/operators';
-import { Employer } from '../../models/employer.model';
-import { Job } from '../../models/job.model';
 import { User } from '../../models/user.model';
+import decode from 'jwt-decode';
+import { UserRole } from '../../shared/enum/userRole.enum';
 import { AuthService } from '../../services/auth.service';
+import { Structure } from '../../models/structure.model';
+import { Employer } from '../../models/employer.model';
+import { Job } from '../../models/job.model';
+import { catchError, map } from 'rxjs/operators';
 import { NotificationService } from '../../services/notification.service';
-import { UserRole } from '../../shared/enum/userRole.enum';
 
 @Injectable({
   providedIn: 'root',
@@ -116,6 +116,7 @@ export class ProfileService {
   }
 
   public updateDetails(newDetails: { name: string; surname: string; phone: string }): Observable<User | Error> {
+    console.log('profile service updates details');
     return this.http.post<User>(`${this.baseUrl}/details`, newDetails).pipe(
       map((user) => user),
       catchError(() => {
diff --git a/src/app/profile/structure-edition-summary/structure-edition-summary.component.ts b/src/app/profile/structure-edition-summary/structure-edition-summary.component.ts
index 4b54f47e35a85355770bb277bbb1334a9bdbbf79..dca4ba56fbd5d30d0826203db3ed9c1b82fd3f76 100644
--- a/src/app/profile/structure-edition-summary/structure-edition-summary.component.ts
+++ b/src/app/profile/structure-edition-summary/structure-edition-summary.component.ts
@@ -1,8 +1,8 @@
 import { Component, OnInit } from '@angular/core';
 import { UntypedFormGroup } from '@angular/forms';
 import { ActivatedRoute, Router } from '@angular/router';
-import { Structure } from '@gouvfr-anct/mediation-numerique';
 import { structureFormStep } from '../../form/form-view/structure-form/structureFormStep.enum';
+import { Structure } from '../../models/structure.model';
 import { formUtils, IStructureSummary } from '../../utils/formUtils';
 
 @Component({
diff --git a/src/app/reset-password/reset-password.component.ts b/src/app/reset-password/reset-password.component.ts
index 678801fb249c390a4654a72346bc3f3110b3a2b5..834a043f4ea2d441752b5be116429b6326aa4826 100644
--- a/src/app/reset-password/reset-password.component.ts
+++ b/src/app/reset-password/reset-password.component.ts
@@ -1,14 +1,14 @@
 import { Component, OnInit } from '@angular/core';
 import { AbstractControl, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
 import { Router } from '@angular/router';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
 import { AuthService } from '../services/auth.service';
 import { NotificationService } from '../services/notification.service';
+import { ButtonType } from '../shared/components/button/buttonType.enum';
 
 @Component({
   selector: 'app-reset-password',
   templateUrl: './reset-password.component.html',
-  styleUrls: ['./reset-password.component.scss'],
+  styleUrls: ['./reset-password.component.scss']
 })
 export class ResetPasswordComponent implements OnInit {
   public resetForm: UntypedFormGroup;
@@ -28,7 +28,7 @@ export class ResetPasswordComponent implements OnInit {
 
   ngOnInit(): void {
     this.resetForm = this.formBuilder.group({
-      email: ['', Validators.required],
+      email: ['', Validators.required]
     });
   }
 
diff --git a/src/app/resolvers/structure.resolver.ts b/src/app/resolvers/structure.resolver.ts
index 9e5a06d0ee42f3958a2725e1e4462da0d4c23edc..a7eb4d9ce340cdd8845b257f4b7b30be730ff03d 100644
--- a/src/app/resolvers/structure.resolver.ts
+++ b/src/app/resolvers/structure.resolver.ts
@@ -1,22 +1,22 @@
-import { Injectable } from '@angular/core';
-import { ActivatedRouteSnapshot, Resolve, Router } from '@angular/router';
-import { Structure } from '@gouvfr-anct/mediation-numerique';
-import { Observable } from 'rxjs';
-import { catchError, map } from 'rxjs/operators';
-import { StructureService } from '../services/structure.service';
-
-@Injectable()
-export class StructureResolver implements Resolve<Structure> {
-  constructor(private structureService: StructureService, private router: Router) {}
-
-  resolve(route: ActivatedRouteSnapshot): Observable<Structure> {
-    const structureId = route.params.id;
-    return this.structureService.getStructure(structureId).pipe(
-      map((res) => res),
-      catchError(() => {
-        this.router.navigate(['/home']);
-        return new Observable<Structure>();
-      })
-    );
-  }
-}
+import { Injectable } from '@angular/core';
+import { ActivatedRouteSnapshot, Resolve, Router } from '@angular/router';
+import { Observable } from 'rxjs';
+import { map, catchError } from 'rxjs/operators';
+import { Structure } from '../models/structure.model';
+import { StructureService } from '../services/structure.service';
+
+@Injectable()
+export class StructureResolver implements Resolve<Structure> {
+  constructor(private structureService: StructureService, private router: Router) {}
+
+  resolve(route: ActivatedRouteSnapshot): Observable<Structure> {
+    const structureId = route.params.id;
+    return this.structureService.getStructure(structureId).pipe(
+      map((res) => res),
+      catchError(() => {
+        this.router.navigate(['/home']);
+        return new Observable<Structure>();
+      })
+    );
+  }
+}
diff --git a/src/app/services/geojson.service.ts b/src/app/services/geojson.service.ts
index 35af50b1bfefa000ee27a4a9c78c96070ba4184d..b598e926a79fc6c9d463dbdaa8cbd401a32859a9 100644
--- a/src/app/services/geojson.service.ts
+++ b/src/app/services/geojson.service.ts
@@ -1,9 +1,9 @@
 import { HttpClient } from '@angular/common/http';
 import { Injectable } from '@angular/core';
-import { GeoJson } from '@gouvfr-anct/mediation-numerique';
-import * as _ from 'lodash';
 import { Observable } from 'rxjs';
 import { map } from 'rxjs/operators';
+import { GeoJson } from '../map/models/geojson.model';
+import * as _ from 'lodash';
 
 @Injectable({
   providedIn: 'root',
diff --git a/src/app/services/personal-offer.service.ts b/src/app/services/personal-offer.service.ts
index 62ef5ba1a2fcfd8c601dee24dac26c3e308e30fe..aa57be29be6269016ef634e2ca24a9403791c29f 100644
--- a/src/app/services/personal-offer.service.ts
+++ b/src/app/services/personal-offer.service.ts
@@ -1,7 +1,7 @@
 import { HttpClient } from '@angular/common/http';
 import { Injectable } from '@angular/core';
-import { PersonalOffer } from '@gouvfr-anct/mediation-numerique';
 import { Observable } from 'rxjs';
+import { PersonalOffer } from '../models/personalOffer.model';
 
 @Injectable({
   providedIn: 'root',
diff --git a/src/app/services/structure.service.spec.ts b/src/app/services/structure.service.spec.ts
index 9afc7dc24d32133be90149c369298d06e456355c..7d193dcb4c0169073060e00264b21b3ef6e80aa7 100644
--- a/src/app/services/structure.service.spec.ts
+++ b/src/app/services/structure.service.spec.ts
@@ -1,61 +1,63 @@
-import { HttpClientTestingModule } from '@angular/common/http/testing';
-import { TestBed } from '@angular/core/testing';
-import { Day, Structure, Time, Week } from '@gouvfr-anct/mediation-numerique';
-import { StructureService } from './structure.service';
-
-const { DateTime } = require('luxon');
-
-describe('StructureService', () => {
-  let structureService: StructureService;
-
-  beforeEach(() => {
-    TestBed.configureTestingModule({
-      imports: [HttpClientTestingModule],
-      providers: [StructureService],
-    });
-    structureService = TestBed.inject(StructureService);
-  });
-
-  it('Mise à jour ouverture de la structure : should return true', () => {
-    // Init structure avec aucun horaire
-    const s: Structure = new Structure();
-    s.hours = new Week();
-    s.hours.monday = new Day(false);
-    s.hours.tuesday = new Day(false);
-    s.hours.wednesday = new Day(false);
-    s.hours.thursday = new Day(false);
-    s.hours.friday = new Day(false);
-    s.hours.saturday = new Day(false);
-    s.hours.sunday = new Day(false);
-    s.hours.thursday.open = true;
-    s.hours.thursday.time = new Array(
-      new Time({ opening: 805, closing: 1200 }),
-      new Time({ opening: 1400, closing: 1600 })
-    );
-
-    // Init date sur un jeudi à 9h05
-    const dt = new DateTime.local(2020, 10, 8, 9, 5);
-    const result = structureService.updateOpeningStructure(s);
-    expect(result.isOpen).toEqual(true);
-  });
-
-  it('Mise à jour ouverture de la structure : should return false', () => {
-    // Init structure avec aucun horaire
-    const s: Structure = new Structure();
-    s.hours = new Week();
-    s.hours.monday = new Day();
-    s.hours.tuesday = new Day();
-    s.hours.wednesday = new Day();
-    s.hours.thursday = new Day();
-    s.hours.friday = new Day();
-    s.hours.saturday = new Day();
-    s.hours.sunday = new Day();
-
-    s.hours.thursday.open = true;
-    s.hours.thursday.time = new Array(new Time({ opening: 1400, closing: 1600 }));
-    // Init date sur un jeudi à 9h05
-    const dt = new DateTime.local(2020, 10, 8, 9, 5);
-    const result = structureService.updateOpeningStructure(s);
-    expect(result.isOpen).toEqual(false);
-  });
-});
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { TestBed } from '@angular/core/testing';
+import { Day } from '../models/day.model';
+import { Structure } from '../models/structure.model';
+import { Time } from '../models/time.model';
+import { Week } from '../models/week.model';
+import { StructureService } from './structure.service';
+const { DateTime } = require('luxon');
+
+describe('StructureService', () => {
+  let structureService: StructureService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({
+      imports: [HttpClientTestingModule],
+      providers: [StructureService],
+    });
+    structureService = TestBed.inject(StructureService);
+  });
+
+  it('Mise à jour ouverture de la structure : should return true', () => {
+    // Init structure avec aucun horaire
+    const s: Structure = new Structure();
+    s.hours = new Week();
+    s.hours.monday = new Day(false);
+    s.hours.tuesday = new Day(false);
+    s.hours.wednesday = new Day(false);
+    s.hours.thursday = new Day(false);
+    s.hours.friday = new Day(false);
+    s.hours.saturday = new Day(false);
+    s.hours.sunday = new Day(false);
+    s.hours.thursday.open = true;
+    s.hours.thursday.time = new Array(
+      new Time({ opening: 805, closing: 1200 }),
+      new Time({ opening: 1400, closing: 1600 })
+    );
+
+    // Init date sur un jeudi à 9h05
+    const dt = new DateTime.local(2020, 10, 8, 9, 5);
+    const result = structureService.updateOpeningStructure(s);
+    expect(result.isOpen).toEqual(true);
+  });
+
+  it('Mise à jour ouverture de la structure : should return false', () => {
+    // Init structure avec aucun horaire
+    const s: Structure = new Structure();
+    s.hours = new Week();
+    s.hours.monday = new Day();
+    s.hours.tuesday = new Day();
+    s.hours.wednesday = new Day();
+    s.hours.thursday = new Day();
+    s.hours.friday = new Day();
+    s.hours.saturday = new Day();
+    s.hours.sunday = new Day();
+
+    s.hours.thursday.open = true;
+    s.hours.thursday.time = new Array(new Time({ opening: 1400, closing: 1600 }));
+    // Init date sur un jeudi à 9h05
+    const dt = new DateTime.local(2020, 10, 8, 9, 5);
+    const result = structureService.updateOpeningStructure(s);
+    expect(result.isOpen).toEqual(false);
+  });
+});
diff --git a/src/app/services/structure.service.ts b/src/app/services/structure.service.ts
index 2d24291a6b1b841ce74db43743921c2d78d061eb..3c7e9eab88532c4fea1569dbae94338747e5de47 100644
--- a/src/app/services/structure.service.ts
+++ b/src/app/services/structure.service.ts
@@ -1,14 +1,20 @@
-import { WeekDay } from '@angular/common';
 import { HttpClient } from '@angular/common/http';
 import { Injectable } from '@angular/core';
-import { Filter, OpeningDay, Structure, Weekday } from '@gouvfr-anct/mediation-numerique';
-import * as _ from 'lodash';
+import { WeekDay } from '@angular/common';
 import { Observable } from 'rxjs';
 import { map } from 'rxjs/operators';
+import * as _ from 'lodash';
+const { DateTime } = require('luxon');
+
+import { Structure } from '../models/structure.model';
+import { Day } from '../models/day.model';
+import { OpeningDay } from '../models/openingDay.model';
+import { Weekday } from '../structure-list/enum/weekday.enum';
+import { Time } from '../models/time.model';
+import { Filter } from '../structure-list/models/filter.model';
+import { User } from '../models/user.model';
 import { StructureWithOwners } from '../models/structureWithOwners.model';
 import { TempUser } from '../models/temp-user.model';
-import { User } from '../models/user.model';
-const { DateTime } = require('luxon');
 
 @Injectable({
   providedIn: 'root',
@@ -166,9 +172,7 @@ export class StructureService {
   }
 
   public getStructureWithOwners(structureId: string, profile: User): Observable<StructureWithOwners> {
-    return this.http.post<StructureWithOwners>(`${this.baseUrl}/${structureId}/withOwners`, {
-      emailUser: profile?.email,
-    });
+    return this.http.post<any>(`${this.baseUrl}/${structureId}/withOwners`, { emailUser: profile?.email });
   }
 
   public sendMailOnStructureError(structureId: string, content: string): Observable<any> {
diff --git a/src/app/shared/components/address-autocomplete/address-autocomplete.component.ts b/src/app/shared/components/address-autocomplete/address-autocomplete.component.ts
index b7e7f683bae4aa69a0e4be16e5652c1bd717a31f..f079a7934fa946e79aea7cd21c6dbf759f4788e9 100644
--- a/src/app/shared/components/address-autocomplete/address-autocomplete.component.ts
+++ b/src/app/shared/components/address-autocomplete/address-autocomplete.component.ts
@@ -1,5 +1,5 @@
 import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
-import { Address } from '@gouvfr-anct/mediation-numerique';
+import { Address } from '../../../models/address.model';
 import { AddressService } from '../../service/address.service';
 
 @Component({
diff --git a/src/app/shared/components/button/button.component.html b/src/app/shared/components/button/button.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..e8495712311bdc7cdf0bd14feaadcdd8db6c65a5
--- /dev/null
+++ b/src/app/shared/components/button/button.component.html
@@ -0,0 +1,268 @@
+<ng-container *ngIf="style === buttonTypeEnum.Regular">
+  <button class="btn-regular" type="{{ type }}" (click)="doAction()" [disabled]="disabled">
+    <div *ngIf="!iconBtn" class="text">{{ text }}</div>
+    <div
+      *ngIf="iconBtn && iconPos === 'left'"
+      fxLayout="row center"
+      class="text withIcon left"
+      fxLayoutAlign="space-around center"
+    >
+      <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon>
+      <span>{{ text }}</span>
+    </div>
+    <div
+      *ngIf="iconBtn && iconPos === 'right'"
+      fxLayout="row center"
+      class="text withIcon right"
+      fxLayoutAlign="space-around center"
+    >
+      <span>{{ text }}</span>
+      <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon>
+    </div>
+  </button>
+</ng-container>
+
+<ng-container *ngIf="style === buttonTypeEnum.searchIcon">
+  <button class="searchIcon" type="{{ type }}" (click)="doAction()">
+    <div fxLayout="row center" class="searchIcon withIcon" fxLayoutAlign="space-between center">
+      <app-svg-icon [type]="'ico'" [icon]="iconBtn" [iconColor]="'currentColor'" [iconClass]="'icon-30'"></app-svg-icon>
+    </div>
+  </button>
+</ng-container>
+
+<ng-container *ngIf="style === buttonTypeEnum.Primary">
+  <button
+    class="btn-regular primary"
+    type="{{ type }}"
+    (click)="doAction()"
+    [disabled]="disabled"
+    [ngClass]="extraClass"
+  >
+    <div *ngIf="!iconBtn" class="text">{{ text }}</div>
+    <div
+      *ngIf="iconBtn && iconPos === 'left'"
+      fxLayout="row center"
+      class="text withIcon left"
+      fxLayoutAlign="space-around center"
+    >
+      <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon>
+      <span [ngClass]="extraClass">{{ text }}</span>
+    </div>
+    <div
+      *ngIf="iconBtn && iconPos === 'right'"
+      fxLayout="row center"
+      class="text withIcon right"
+      fxLayoutAlign="space-around center"
+    >
+      <span [ngClass]="extraClass">{{ text }}</span>
+      <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon>
+    </div>
+  </button>
+</ng-container>
+
+<ng-container *ngIf="style === buttonTypeEnum.modalPrimary">
+  <button class="btn-regular modal-primary" type="{{ type }}" (click)="doAction()" [disabled]="disabled">
+    <div *ngIf="!iconBtn" class="text">{{ text }}</div>
+    <div *ngIf="iconBtn && iconPos === 'left'" fxLayout="row center" class="text" fxLayoutAlign="space-around center">
+      <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon>
+      <span>{{ text }}</span>
+    </div>
+    <div *ngIf="iconBtn && iconPos === 'right'" fxLayout="row center" class="text" fxLayoutAlign="space-around center">
+      <span>{{ text }}</span>
+      <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon>
+    </div>
+  </button>
+</ng-container>
+
+<ng-container *ngIf="style === buttonTypeEnum.modalSecondary">
+  <button
+    class="btn-regular modal-secondary"
+    type="{{ type }}"
+    (click)="doAction()"
+    [disabled]="disabled"
+    [ngClass]="{ disabled: disabled }"
+  >
+    <div *ngIf="!iconBtn" class="text">{{ text }}</div>
+    <div *ngIf="iconBtn && iconPos === 'left'" fxLayout="row center" class="text" fxLayoutAlign="space-around center">
+      <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon>
+      <span>{{ text }}</span>
+    </div>
+    <div *ngIf="iconBtn && iconPos === 'right'" fxLayout="row center" class="text" fxLayoutAlign="space-around center">
+      <span>{{ text }}</span>
+      <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon>
+    </div>
+  </button>
+</ng-container>
+
+<ng-container *ngIf="style === buttonTypeEnum.Secondary || style === buttonTypeEnum.SecondaryWide">
+  <button
+    [ngClass]="{
+      'btn-regular secondary': true,
+      wide: style === buttonTypeEnum.SecondaryWide
+    }"
+    type="{{ type }}"
+    (click)="doAction()"
+    [disabled]="disabled"
+  >
+    <div *ngIf="!iconBtn" [ngClass]="extraClass" class="text">{{ text }}</div>
+    <div
+      *ngIf="iconBtn && iconPos === 'left'"
+      fxLayout="row center"
+      class="text withIcon left"
+      fxLayoutAlign="space-around center"
+    >
+      <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon>
+      <span>{{ text }}</span>
+    </div>
+    <div
+      *ngIf="iconBtn && iconPos === 'right'"
+      fxLayout="row center"
+      class="text withIcon right"
+      fxLayoutAlign="space-around center"
+    >
+      <span>{{ text }}</span>
+      <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon>
+    </div>
+  </button>
+</ng-container>
+
+<ng-container *ngIf="style === buttonTypeEnum.SecondaryUltraWide">
+  <button class="btn-regular secondary ultrawide" type="{{ type }}" (click)="doAction()" [disabled]="disabled">
+    <div *ngIf="!iconBtn" [ngClass]="extraClass" class="text">{{ text }}</div>
+    <div
+      *ngIf="iconBtn && iconPos === 'left'"
+      fxLayout="row center"
+      class="text withIcon left"
+      fxLayoutAlign="center center"
+    >
+      <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon>
+      <span>{{ text }}</span>
+    </div>
+    <div
+      *ngIf="iconBtn && iconPos === 'right'"
+      fxLayout="row center"
+      class="text withIcon right"
+      fxLayoutAlign="center center"
+    >
+      <span>{{ text }}</span>
+      <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon>
+    </div>
+  </button>
+</ng-container>
+
+<ng-container *ngIf="style === buttonTypeEnum.SecondaryOnlyIcon">
+  <button class="btn-regular secondary" type="{{ type }}" (click)="doAction()" [disabled]="disabled">
+    <div *ngIf="iconBtn" fxLayout="row center" class="text withIcon center" fxLayoutAlign="space-around center">
+      <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon>
+    </div>
+  </button>
+</ng-container>
+
+<ng-container *ngIf="style === buttonTypeEnum.ButtonPhone">
+  <button [disabled]="disabled" class="btn-switch-phone" type="{{ type }}" (click)="doAction()">
+    <div *ngIf="!iconBtn" class="text">{{ text }}</div>
+    <div
+      *ngIf="iconBtn"
+      fxLayout="row center"
+      class="text withIcon"
+      fxLayoutAlign="space-around center"
+      fxLayoutGap="13px"
+    >
+      <app-svg-icon
+        class="iconBtn"
+        [type]="'ico'"
+        [iconClass]="'icon-32'"
+        [icon]="iconBtn"
+        [iconColor]="'currentColor'"
+      ></app-svg-icon>
+      {{ text }}
+    </div>
+  </button>
+</ng-container>
+
+<ng-container *ngIf="style === buttonTypeEnum.Filter">
+  <button
+    [disabled]="disabled"
+    class="btn-filter-phone"
+    type="{{ type }}"
+    (click)="doAction()"
+    [ngClass]="{ disabled: disabled }"
+  >
+    <div *ngIf="!iconBtn" class="text">{{ text }}</div>
+    <div
+      *ngIf="iconBtn"
+      fxLayout="row center"
+      class="text withIcon"
+      fxLayoutAlign="space-around center"
+      fxLayoutGap="13px"
+    >
+      <app-svg-icon [type]="'ico'" [iconClass]="'icon-32'" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon>
+      {{ text }}
+    </div>
+  </button>
+</ng-container>
+
+<ng-container *ngIf="style === buttonTypeEnum.Tertiary">
+  <button
+    class="btn-regular tertiary"
+    type="{{ type }}"
+    (click)="doAction()"
+    [disabled]="disabled"
+    [ngClass]="extraClass"
+  >
+    <div>{{ text }}</div>
+  </button>
+</ng-container>
+
+<ng-container *ngIf="style === buttonTypeEnum.CheckButton">
+  <button
+    class="btn-regular tertiary checkButton"
+    type="{{ type }}"
+    (click)="doAction()"
+    [disabled]="disabled"
+    [ngClass]="extraClass"
+  >
+    <div fxLayout="row center" fxLayoutAlign="space-around center" fxLayoutGap="13px">
+      <app-svg-icon
+        *ngIf="extraClass"
+        [type]="'ico'"
+        [icon]="'validate'"
+        [iconClass]="'icon-28'"
+        [iconColor]="'currentColor'"
+      ></app-svg-icon>
+      {{ text }}
+    </div>
+  </button>
+</ng-container>
+
+<ng-container *ngIf="style === buttonTypeEnum.IconOnly">
+  <button
+    class="btn-regular icon-only"
+    type="{{ type }}"
+    (click)="doAction()"
+    [disabled]="disabled"
+    [ngClass]="{ active: active }"
+  >
+    <div *ngIf="iconBtn" class="text withIcon">
+      <app-svg-icon
+        *ngIf="iconBtn"
+        [type]="iconType"
+        [icon]="iconBtn"
+        [iconColor]=""
+        [iconClass]="'icon-28'"
+        [iconColor]="active ? 'green' : 'currentColor'"
+      ></app-svg-icon>
+    </div>
+  </button>
+</ng-container>
+<ng-container *ngIf="style === buttonTypeEnum.TagCloudButton">
+  <button class="btn-tags-cloud" fxLayout="row" (click)="doAction()">
+    <span>{{ text }}</span>
+    <app-svg-icon
+      [type]="'ico'"
+      [iconClass]="'icon-centered'"
+      [icon]="'tagDelete'"
+      [iconColor]="'white'"
+    ></app-svg-icon>
+  </button>
+</ng-container>
diff --git a/src/app/shared/components/button/button.component.scss b/src/app/shared/components/button/button.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..2f34723d86d217c1e9dc403474fffebd94e86834
--- /dev/null
+++ b/src/app/shared/components/button/button.component.scss
@@ -0,0 +1,320 @@
+@import '../../../../assets/scss/typography';
+@import '../../../../assets/scss/color';
+@import '../../../../assets/scss/breakpoint';
+@import '../../../../assets/scss/shapes';
+
+@mixin btn-bold {
+  @include lato-bold-13;
+  line-height: 18px;
+}
+@mixin btn-bold-underline {
+  @include btn-bold;
+  text-decoration: underline;
+}
+@mixin btn-regular {
+  @include lato-regular-13;
+  line-height: 19px;
+}
+button {
+  outline: none;
+  border-radius: 4px;
+  cursor: pointer;
+  border: 1px solid;
+  padding: 0;
+}
+.searchIcon {
+  background: transparent;
+  border: none;
+  & > svg {
+    width: 30px;
+    height: 30px;
+  }
+}
+.btnSearch {
+  @include background-hash($grey-2);
+  border-color: $grey-4;
+  padding: 0 0 4px 4px;
+}
+
+.btn-regular {
+  background: $grey-8;
+  border-radius: 5px 5px 4px 5px;
+  border: 0;
+  div:first-child {
+    width: 125px;
+  }
+  &:hover {
+    @include background-hash($grey-1);
+    padding: 0;
+  }
+  &:focus {
+    border-color: $primary-color;
+  }
+  &:active {
+    background: none;
+    border-color: $grey-8;
+  }
+  .searchButton {
+    background: $grey-6;
+  }
+  &.primary {
+    border: 0;
+    @include btn-bold;
+    .text {
+      background: $primary-color;
+      border: 1px solid $grey-1;
+      line-height: 15px;
+
+      color: $white;
+      &.withIcon {
+        color: $white;
+      }
+    }
+  }
+  &.modal-primary {
+    border: none;
+    width: 100%;
+    @include btn-bold;
+    .text {
+      display: flex;
+      text-align: center;
+      align-items: center;
+      justify-content: center;
+      background: $primary-color;
+      margin: auto;
+      color: $white;
+      width: auto;
+      line-height: 15px;
+      &.withIcon {
+        color: $white;
+      }
+    }
+  }
+  &.modal-secondary {
+    border: none;
+    width: 100%;
+    @include btn-regular;
+    .text {
+      display: flex;
+      text-align: center;
+      align-items: center;
+      justify-content: center;
+      margin: auto;
+      color: $grey-1;
+      width: auto;
+      line-height: 15px;
+      &.withIcon {
+        color: $grey-1;
+      }
+    }
+  }
+  &.secondary {
+    div:first-child {
+      width: unset;
+    }
+    border: 0;
+    background: $white;
+    @include btn-regular;
+    .text {
+      background: $white;
+      border: 1px solid $grey-1;
+      color: $grey-1;
+      font-size: 14px;
+      line-height: 15px;
+      &.withIcon {
+        color: $grey-1;
+      }
+    }
+    &.wide {
+      div:first-child {
+        min-width: 50px;
+        width: 184px;
+      }
+    }
+    &.ultrawide {
+      div:first-child {
+        min-width: 50px;
+        width: 400px;
+        @media #{$tablet} {
+          width: 200px;
+        }
+        span {
+          padding-inline: 4px;
+        }
+      }
+    }
+    .small-text {
+      height: 22px !important;
+    }
+    &.wide {
+      div:first-child {
+        min-width: 50px;
+        width: 184px;
+      }
+    }
+    &.ultrawide {
+      div:first-child {
+        min-width: 50px;
+        width: 400px;
+        @media #{$tablet} {
+          width: 200px;
+        }
+        span {
+          padding-inline: 4px;
+        }
+      }
+    }
+  }
+  &.tertiary {
+    div:first-child {
+      min-width: 50px;
+      width: unset;
+    }
+    &:hover {
+      border: 1px solid $grey-4;
+      box-sizing: border-box;
+      background: $grey-7 !important;
+    }
+    border: 1px solid transparent;
+    background: $grey-7;
+    height: 36px;
+    color: $black;
+    padding: 0px 16px;
+    border-radius: 20px;
+    min-width: 50px;
+
+    @include btn-regular;
+    &.selected {
+      background-color: $green-1 !important;
+      color: white !important;
+      &:hover {
+        background-color: $green-1 !important;
+      }
+    }
+    &.checkButton {
+      padding: 0px 14px;
+      font-weight: bold;
+      div:first-child {
+        padding: 0 14px;
+      }
+      &.selected {
+        padding: unset;
+      }
+    }
+  }
+
+  &.icon-only {
+    div:first-child {
+      width: unset;
+    }
+    &.active {
+      .text {
+        border-color: $green-1;
+      }
+      &:hover {
+        background: unset !important;
+      }
+    }
+    &.center {
+      padding-left: 6px !important;
+      padding-right: 6px !important;
+    }
+  }
+  .text {
+    position: relative;
+    top: -1px;
+    right: -1px;
+    border: 1px solid $grey-1;
+    background: $white;
+    height: 31px;
+    color: $grey-1;
+    padding: 3px 15px;
+    display: table-cell;
+    vertical-align: middle;
+    border-radius: 4px;
+    font-size: 14px;
+    line-height: 15px;
+    &.withIcon {
+      color: $black;
+      height: 36px;
+      &.left {
+        padding-left: 8px !important;
+      }
+      &.right {
+        padding-right: 8px !important;
+      }
+      &.center {
+        padding-left: 6px !important;
+        padding-right: 6px !important;
+      }
+    }
+  }
+}
+
+.btn-switch-phone {
+  background: $black;
+  height: 40px;
+  width: 124px;
+  color: $white;
+  padding: 4px 28px;
+  border-radius: 20px;
+  .iconBtn {
+    margin-right: 6px;
+  }
+}
+
+.btn-filter-phone {
+  background: $white;
+  height: 40px;
+  color: $grey-1;
+  padding: 4px 37px 4px 37px;
+  border-color: $grey-4;
+  @include btn-normal;
+  &.containCheckedFilters {
+    border-color: $primary-color;
+  }
+}
+.fullButton {
+  width: 125px !important;
+}
+.fullWidth {
+  width: 100% !important;
+}
+.bigButton {
+  width: 280px !important;
+  .text {
+    width: inherit !important;
+  }
+}
+.btn-tags-cloud {
+  appearance: none;
+
+  @include lato-regular-12;
+  justify-content: center;
+  align-items: center;
+  box-sizing: border-box;
+  height: 25px;
+  border-radius: 20px;
+  padding: 5px 10px 5px 15px;
+  max-width: 150px;
+  color: $grey-8;
+  border-style: none;
+  margin-top: 5px;
+  background: $grey-1;
+  text-overflow: ellipsis;
+
+  span {
+    text-overflow: ellipsis;
+    max-width: 130px;
+    white-space: nowrap;
+    overflow: hidden;
+    display: inline-block;
+  }
+  &.unchecked {
+    background: $grey-1;
+  }
+}
+button:disabled {
+  opacity: 0.4;
+  cursor: not-allowed;
+}
diff --git a/src/app/shared/components/button/button.component.spec.ts b/src/app/shared/components/button/button.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3b2d1343741e4a367e4dce58f1549fc88dd4b29d
--- /dev/null
+++ b/src/app/shared/components/button/button.component.spec.ts
@@ -0,0 +1,24 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ButtonComponent } from './button.component';
+
+describe('button', () => {
+  let component: ButtonComponent;
+  let fixture: ComponentFixture<ButtonComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ButtonComponent],
+    }).compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(ButtonComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/shared/components/button/button.component.ts b/src/app/shared/components/button/button.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..744ce81133ac79a5e30dda09fe2a513be37860e3
--- /dev/null
+++ b/src/app/shared/components/button/button.component.ts
@@ -0,0 +1,26 @@
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+import { ButtonType } from './buttonType.enum';
+
+@Component({
+  selector: 'app-button',
+  templateUrl: './button.component.html',
+  styleUrls: ['./button.component.scss'],
+})
+export class ButtonComponent {
+  @Input() public style: ButtonType = ButtonType.Regular;
+  @Input() public text: string;
+  @Input() public type: string;
+  @Input() public iconType = 'ico';
+  @Input() public iconBtn: string;
+  @Input() public iconPos = 'left';
+  @Input() public extraClass: string;
+  @Input() public disabled = false;
+  @Input() public active = false;
+  @Output() public action = new EventEmitter();
+
+  public buttonTypeEnum = ButtonType;
+
+  public doAction(): void {
+    this.action.emit();
+  }
+}
diff --git a/src/app/shared/components/button/buttonType.enum.ts b/src/app/shared/components/button/buttonType.enum.ts
new file mode 100644
index 0000000000000000000000000000000000000000..99cd644b020d619d231a142fa18c2f6e3d269344
--- /dev/null
+++ b/src/app/shared/components/button/buttonType.enum.ts
@@ -0,0 +1,17 @@
+export enum ButtonType {
+  Regular,
+  Primary,
+  Secondary,
+  SecondaryWide,
+  SecondaryUltraWide,
+  SecondaryOnlyIcon,
+  Tertiary,
+  ButtonPhone,
+  Filter,
+  IconOnly,
+  CheckButton,
+  searchIcon,
+  modalPrimary,
+  modalSecondary,
+  TagCloudButton,
+}
diff --git a/src/app/shared/components/data-share-consent/data-share-consent.component.ts b/src/app/shared/components/data-share-consent/data-share-consent.component.ts
index 48be3289a03185c4ff2e601f5a06a9499daca5a1..04717b46d6a0120e25af9cd5ebcbcd838a8b2154 100644
--- a/src/app/shared/components/data-share-consent/data-share-consent.component.ts
+++ b/src/app/shared/components/data-share-consent/data-share-consent.component.ts
@@ -1,7 +1,7 @@
 import { Component, Input, OnInit } from '@angular/core';
 import { AbstractControl, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
-import { Structure } from '@gouvfr-anct/mediation-numerique';
 import { Subject } from 'rxjs';
+import { Structure } from '../../../models/structure.model';
 import { StructureService } from '../../../services/structure.service';
 
 @Component({
diff --git a/src/app/shared/components/hour-picker/hour-picker.component.ts b/src/app/shared/components/hour-picker/hour-picker.component.ts
index a4b6a43bf13d19ff0473b3b42162790544fb7277..40b8366424ec6bae9a82d68e48c89463ae36a6ee 100644
--- a/src/app/shared/components/hour-picker/hour-picker.component.ts
+++ b/src/app/shared/components/hour-picker/hour-picker.component.ts
@@ -1,14 +1,15 @@
 import { Component, EventEmitter, Input, OnChanges, OnDestroy, Output } from '@angular/core';
 import { AbstractControl, UntypedFormArray, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
-import { Day, Time } from '@gouvfr-anct/mediation-numerique';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
+import { Day } from '../../../models/day.model';
+import { Time } from '../../../models/time.model';
+import { ButtonType } from '../button/buttonType.enum';
 import { WeekDayEnum } from '../../enum/weekDay.enum';
 import { CheckHours } from '../../validator/form';
 
 @Component({
   selector: 'app-hour-picker',
   templateUrl: './hour-picker.component.html',
-  styleUrls: ['./hour-picker.component.scss']
+  styleUrls: ['./hour-picker.component.scss'],
 })
 export class HourPickerComponent implements OnChanges, OnDestroy {
   @Input() modifiedFields: any;
@@ -23,7 +24,7 @@ export class HourPickerComponent implements OnChanges, OnDestroy {
   private isInputSelected = false;
   public copiedDayName = '';
   public structure = {
-    hours: this.initHoursDefault()
+    hours: this.initHoursDefault(),
   };
   public structureHoursDefault: any[] = this.initHoursDefault();
 
@@ -45,44 +46,44 @@ export class HourPickerComponent implements OnChanges, OnDestroy {
         name: 'Lundi',
         hours: [{ start: '', end: '', error: 'incomplete' }],
         open: false,
-        active: false
+        active: false,
       },
       {
         name: 'Mardi',
         hours: [{ start: '', end: '', error: 'incomplete' }],
         open: false,
-        active: false
+        active: false,
       },
       {
         name: 'Mercredi',
         hours: [{ start: '', end: '', error: 'incomplete' }],
         open: false,
-        active: false
+        active: false,
       },
       {
         name: 'Jeudi',
         hours: [{ start: '', end: '', error: 'incomplete' }],
         open: false,
-        active: false
+        active: false,
       },
       {
         name: 'Vendredi',
         hours: [{ start: '', end: '', error: 'incomplete' }],
         open: false,
-        active: false
+        active: false,
       },
       {
         name: 'Samedi',
         hours: [{ start: '', end: '', error: 'incomplete' }],
         open: false,
-        active: false
+        active: false,
       },
       {
         name: 'Dimanche',
         hours: [{ start: '', end: '', error: 'incomplete' }],
         open: false,
-        active: false
-      }
+        active: false,
+      },
     ];
   }
 
@@ -100,20 +101,20 @@ export class HourPickerComponent implements OnChanges, OnDestroy {
               return {
                 start: hour.opening,
                 end: hour.closing,
-                error: null
+                error: null,
               };
             } else {
               if (hour.opening) {
                 return {
                   start: hour.opening,
                   end: '',
-                  error: 'incomplete'
+                  error: 'incomplete',
                 };
               } else {
                 return {
                   start: '',
                   end: hour.closing,
-                  error: 'incomplete'
+                  error: 'incomplete',
                 };
               }
             }
@@ -125,16 +126,21 @@ export class HourPickerComponent implements OnChanges, OnDestroy {
     this.structure.hours = this.structureHoursDefault;
   }
 
-  private parseToDay(data: { name: string; hours: { start: string; end: string }[]; open: boolean; active: boolean }): Day {
+  private parseToDay(data: {
+    name: string;
+    hours: { start: string; end: string }[];
+    open: boolean;
+    active: boolean;
+  }): Day {
     return new Day({
       open: data.open,
       time: data.hours.map(
         (hour) =>
           new Time({
             opening: hour.start,
-            closing: hour.end
+            closing: hour.end,
           })
-      )
+      ),
     });
   }
 
@@ -146,7 +152,7 @@ export class HourPickerComponent implements OnChanges, OnDestroy {
       thursday: this.createDay(this.parseToDay(this.structure.hours[3])),
       friday: this.createDay(this.parseToDay(this.structure.hours[4])),
       saturday: this.createDay(this.parseToDay(this.structure.hours[5])),
-      sunday: this.createDay(this.parseToDay(this.structure.hours[6]))
+      sunday: this.createDay(this.parseToDay(this.structure.hours[6])),
     });
   }
 
@@ -209,7 +215,7 @@ export class HourPickerComponent implements OnChanges, OnDestroy {
     day.hours.push({
       start: '',
       end: '',
-      error: 'incomplete'
+      error: 'incomplete',
     });
     this.submitForm();
   }
@@ -298,14 +304,14 @@ export class HourPickerComponent implements OnChanges, OnDestroy {
   private createDay(day: Day): UntypedFormGroup {
     return new UntypedFormGroup({
       open: new UntypedFormControl(day.open, Validators.required),
-      time: new UntypedFormArray(day.time.map((oneTime) => this.createTime(oneTime))) as UntypedFormArray
+      time: new UntypedFormArray(day.time.map((oneTime) => this.createTime(oneTime))) as UntypedFormArray,
     });
   }
 
   private createTime(time: Time): UntypedFormGroup {
     return new UntypedFormGroup({
       opening: new UntypedFormControl(time.opening, Validators.required),
-      closing: new UntypedFormControl(time.closing, [Validators.required, CheckHours(time.opening)])
+      closing: new UntypedFormControl(time.closing, [Validators.required, CheckHours(time.opening)]),
     });
   }
 }
diff --git a/src/app/shared/components/index.ts b/src/app/shared/components/index.ts
index 5b59fcfe43d862110780eae044579c8f761fa971..b8449db73ec60f3a1a5985da8ee7824e5dc2be29 100644
--- a/src/app/shared/components/index.ts
+++ b/src/app/shared/components/index.ts
@@ -1,23 +1,28 @@
-import { InformationStepComponent } from '../../form/form-view/global-components/information-step/information-step.component';
+import { ButtonComponent } from './button/button.component';
+import { LogoCardComponent } from './logo-card/logo-card.component';
+import { SvgIconComponent } from './svg-icon/svg-icon.component';
+import { ValidatorFormComponent } from './validator-form/validator-form.component';
+import { CreateAccountFormComponent } from './create-account-form/create-account-form.component';
 import { AddressAutocompleteComponent } from './address-autocomplete/address-autocomplete.component';
+import { StructureTypePickerComponent } from './structure-type-picker/structure-type-picker.component';
 import { CheckboxFormComponent } from './checkbox-form/checkbox-form.component';
-import { CreateAccountFormComponent } from './create-account-form/create-account-form.component';
-import { CopyPasteComponent } from './hour-picker/copy-paste/copy-paste.component';
 import { HourPickerComponent } from './hour-picker/hour-picker.component';
-import { LogoCardComponent } from './logo-card/logo-card.component';
+import { CopyPasteComponent } from './hour-picker/copy-paste/copy-paste.component';
+import { RadioFormComponent } from './radio-form/radio-form.component';
 import { ModalConfirmationComponent } from './modal-confirmation/modal-confirmation.component';
 import { ModalJoinConfirmationComponent } from './modal-join-confirmation/modal-join-confirmation.component';
+import { StructureOptionsModalComponent } from './structure-options-modal/structure-options-modal.component';
 import { ModalOptionsComponent } from './modal-options/modal-options.component';
+import { TextInputModalComponent } from './text-input-modal/text-input-modal.component';
 import { PasswordFormComponent } from './password-form/password-form.component';
-import { RadioFormComponent } from './radio-form/radio-form.component';
-import { StructureOptionsModalComponent } from './structure-options-modal/structure-options-modal.component';
-import { StructureTypePickerComponent } from './structure-type-picker/structure-type-picker.component';
 import { TrainingTypePickerComponent } from './training-type-picker/training-type-picker.component';
-import { ValidatorFormComponent } from './validator-form/validator-form.component';
+import { InformationStepComponent } from '../../form/form-view/global-components/information-step/information-step.component';
 
 // tslint:disable-next-line: max-line-length
 export {
   LogoCardComponent,
+  SvgIconComponent,
+  ButtonComponent,
   ValidatorFormComponent,
   CreateAccountFormComponent,
   AddressAutocompleteComponent,
@@ -29,6 +34,7 @@ export {
   ModalConfirmationComponent,
   StructureOptionsModalComponent,
   ModalOptionsComponent,
+  TextInputModalComponent,
   PasswordFormComponent,
   TrainingTypePickerComponent,
 };
@@ -36,6 +42,8 @@ export {
 // tslint:disable-next-line:variable-name
 export const SharedComponents = [
   LogoCardComponent,
+  SvgIconComponent,
+  ButtonComponent,
   ValidatorFormComponent,
   CreateAccountFormComponent,
   AddressAutocompleteComponent,
@@ -48,6 +56,7 @@ export const SharedComponents = [
   ModalJoinConfirmationComponent,
   StructureOptionsModalComponent,
   ModalOptionsComponent,
+  TextInputModalComponent,
   PasswordFormComponent,
   TrainingTypePickerComponent,
   InformationStepComponent,
diff --git a/src/app/shared/components/logo-card/logo-card.component.ts b/src/app/shared/components/logo-card/logo-card.component.ts
index 69699d655c92211f6dd54cbb8fb82cd85ec30951..ef2c578380b08104f9e833e5475cfdc96fe14b49 100644
--- a/src/app/shared/components/logo-card/logo-card.component.ts
+++ b/src/app/shared/components/logo-card/logo-card.component.ts
@@ -1,21 +1,21 @@
-import { Component, Input } from '@angular/core';
-import { Demarches } from '../../enum/demarches.enum';
-import { Labels } from '../../enum/labels.enum';
-
-@Component({
-  selector: 'app-logo-card',
-  templateUrl: './logo-card.component.html',
-  styleUrls: ['./logo-card.component.scss'],
-})
-export class LogoCardComponent {
-  @Input() public logoPath: string;
-  @Input() public name: string;
-
-  public getName(key: string): string {
-    if (Labels[key]) {
-      return Labels[key];
-    } else {
-      return Demarches[key];
-    }
-  }
-}
+import { Component, Input } from '@angular/core';
+import { Demarches } from '../../enum/demarches.enum';
+import { Labels } from '../../enum/labels.emum';
+
+@Component({
+  selector: 'app-logo-card',
+  templateUrl: './logo-card.component.html',
+  styleUrls: ['./logo-card.component.scss']
+})
+export class LogoCardComponent {
+  @Input() public logoPath: string;
+  @Input() public name: string;
+
+  public getName(key: string): string {
+    if (Labels[key]) {
+      return Labels[key];
+    } else {
+      return Demarches[key];
+    }
+  }
+}
diff --git a/src/app/shared/components/modal-confirmation/modal-confirmation.component.ts b/src/app/shared/components/modal-confirmation/modal-confirmation.component.ts
index 65c1c7204df2d628c7fcea94ed98165ecbe9e251..34024d0048fe5a6d26c8f33d6da2dd59937bee83 100644
--- a/src/app/shared/components/modal-confirmation/modal-confirmation.component.ts
+++ b/src/app/shared/components/modal-confirmation/modal-confirmation.component.ts
@@ -1,5 +1,5 @@
 import { Component, EventEmitter, Input, Output } from '@angular/core';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
+import { ButtonType } from '../button/buttonType.enum';
 
 @Component({
   selector: 'app-modal-confirmation',
diff --git a/src/app/shared/components/modal-join-confirmation/modal-join-confirmation.component.ts b/src/app/shared/components/modal-join-confirmation/modal-join-confirmation.component.ts
index 68932b6fd23460184067117e5a94ecc91c19131b..cc82850fcd35daea219a13da47d8bac38e9a5607 100644
--- a/src/app/shared/components/modal-join-confirmation/modal-join-confirmation.component.ts
+++ b/src/app/shared/components/modal-join-confirmation/modal-join-confirmation.component.ts
@@ -1,5 +1,5 @@
 import { Component, EventEmitter, Input, Output } from '@angular/core';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
+import { ButtonType } from '../button/buttonType.enum';
 
 @Component({
   selector: 'app-join-modal-confirmation',
diff --git a/src/app/shared/components/password-form/password-form.component.ts b/src/app/shared/components/password-form/password-form.component.ts
index 4b5eda019f2a07a806c19941873b9e31e95feff3..7dc2c89ad6baab94f50a272cbf093b7e4fa5f5e0 100644
--- a/src/app/shared/components/password-form/password-form.component.ts
+++ b/src/app/shared/components/password-form/password-form.component.ts
@@ -1,12 +1,11 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 import { AbstractControl, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
 import { ActivatedRoute, Router } from '@angular/router';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
 import { ProfileService } from '../../../profile/services/profile.service';
 import { AuthService } from '../../../services/auth.service';
 import { CustomRegExp } from '../../../utils/CustomRegExp';
 import { MustMatch } from '../../validator/form';
-
+import { ButtonType } from '../button/buttonType.enum';
 @Component({
   selector: 'app-password-form',
   templateUrl: './password-form.component.html',
diff --git a/src/app/shared/components/structure-options-modal/structure-options-modal.component.ts b/src/app/shared/components/structure-options-modal/structure-options-modal.component.ts
index ac85deb9c332e0360f67a340e45bd43e1f799747..2ff02f91dbabe59b8258de79bb5c7c8a9e8ea59d 100644
--- a/src/app/shared/components/structure-options-modal/structure-options-modal.component.ts
+++ b/src/app/shared/components/structure-options-modal/structure-options-modal.component.ts
@@ -1,4 +1,4 @@
-import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
 import { AbstractControl, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
 import { Router } from '@angular/router';
 import { StructureWithOwners } from '../../../models/structureWithOwners.model';
@@ -10,6 +10,7 @@ import { AuthService } from '../../../services/auth.service';
 import { StructureService } from '../../../services/structure.service';
 import { CustomRegExp } from '../../../utils/CustomRegExp';
 import { FunctionTypeModalOptions } from '../../enum/functionTypeModalOptions.enum';
+import { MustMatch } from '../../validator/form';
 
 @Component({
   selector: 'app-structure-options-modal',
diff --git a/src/app/shared/components/structure-type-picker/structure-type-picker.component.ts b/src/app/shared/components/structure-type-picker/structure-type-picker.component.ts
index 315fa1b681891393e9c900945e0e703957ea67ca..f896a6258da62187a4f6ef730f8d5fe01c14e90d 100644
--- a/src/app/shared/components/structure-type-picker/structure-type-picker.component.ts
+++ b/src/app/shared/components/structure-type-picker/structure-type-picker.component.ts
@@ -1,8 +1,9 @@
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
-import { typeStructureEnum } from '@gouvfr-anct/mediation-numerique';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
 import { StructureType } from '../../../models/structure-type.model';
+import { Structure } from '../../../models/structure.model';
 import { StructureTypeService } from '../../../services/structure-type.service';
+import { typeStructureEnum } from '../../enum/typeStructure.enum';
+import { ButtonType } from '../button/buttonType.enum';
 
 export enum structureTypes {
   public = 'Publique',
diff --git a/src/app/shared/components/svg-icon/svg-icon.component.html b/src/app/shared/components/svg-icon/svg-icon.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..5c875441709253e2124049a08056d8bd3f5dbe7e
--- /dev/null
+++ b/src/app/shared/components/svg-icon/svg-icon.component.html
@@ -0,0 +1,8 @@
+<div app-tooltipDirective title="{{ title }}">
+  <ng-template #tooltipTemplate>
+    <div class="tooltip">{{ title }}</div>
+  </ng-template>
+  <svg aria-hidden="true" class="icon" [ngClass]="iconClass" [attr.fill]="iconColor" [attr.stroke]="iconColor">
+    <use [attr.xlink:href]="'assets/' + type + '/sprite.svg#' + icon"></use>
+  </svg>
+</div>
diff --git a/src/app/shared/components/svg-icon/svg-icon.component.scss b/src/app/shared/components/svg-icon/svg-icon.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..5630b1b400d76c7ab725362408ece7a0c9c22f50
--- /dev/null
+++ b/src/app/shared/components/svg-icon/svg-icon.component.scss
@@ -0,0 +1,104 @@
+@import '../../../../assets/scss/color';
+
+:host {
+  display: flex;
+  align-items: center;
+}
+
+.icon {
+  display: inline-block;
+  height: 2em;
+  width: 1.5em;
+  &.icon-full {
+    width: unset;
+    height: unset;
+  }
+  &.icon-16 {
+    height: 16px;
+    width: 16px;
+  }
+  &.icon-26 {
+    height: 26px;
+    width: 26px;
+  }
+  &.icon-28 {
+    width: 28px;
+    height: 28px;
+  }
+  &.icon-30 {
+    width: 30px;
+    height: 30px;
+  }
+  &.icon-32 {
+    width: 32px;
+    height: 32px;
+  }
+  &.icon-52 {
+    width: 52px;
+    height: 52px;
+  }
+  &.icon-40 {
+    width: 40px;
+    height: 40px;
+  }
+  &.icon-75 {
+    width: 4.688em;
+  }
+  &.icon-80 {
+    height: 80px;
+    width: 80px;
+  }
+  &.icon-112 {
+    height: 112px;
+    width: 112px;
+  }
+  &.validation {
+    height: 36px;
+    width: 20px;
+  }
+  &.validation-small {
+    height: 26px;
+    width: 20px;
+  }
+  &.hover {
+    cursor: pointer;
+    &:hover {
+      opacity: 0.8;
+    }
+  }
+  &.white {
+    fill: $white;
+    stroke: $white;
+    path {
+      stroke: $white;
+      fill: $white;
+    }
+  }
+  &.grey {
+    fill: $grey-3;
+    stroke: $grey-3;
+  }
+  &.grey-1 {
+    fill: $grey-1;
+    stroke: $grey-1;
+  }
+  &.green {
+    fill: $green-1;
+    stroke: $green-1;
+  }
+  &.backArrow {
+    height: 40px;
+    width: 40px;
+    margin-right: 1rem;
+  }
+}
+
+svg {
+  // Scale the SVG to cover the whole app-icon container.
+
+  top: 0.125em;
+  position: relative;
+}
+.icon-centered {
+  padding-top: 0.15rem;
+}
diff --git a/src/app/shared/components/svg-icon/svg-icon.component.spec.ts b/src/app/shared/components/svg-icon/svg-icon.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f4276b578fc651e589a56909d491cfdf6203cf1c
--- /dev/null
+++ b/src/app/shared/components/svg-icon/svg-icon.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SvgIconComponent } from './svg-icon.component';
+
+describe('SvgIconComponent', () => {
+  let component: SvgIconComponent;
+  let fixture: ComponentFixture<SvgIconComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ SvgIconComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(SvgIconComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/shared/components/svg-icon/svg-icon.component.ts b/src/app/shared/components/svg-icon/svg-icon.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..23badf796fc5f101a3262319ef4eeddec3fc7965
--- /dev/null
+++ b/src/app/shared/components/svg-icon/svg-icon.component.ts
@@ -0,0 +1,15 @@
+import { Component, Input } from '@angular/core';
+
+@Component({
+  selector: 'app-svg-icon',
+  templateUrl: './svg-icon.component.html',
+  styleUrls: ['./svg-icon.component.scss'],
+})
+export class SvgIconComponent {
+  @Input() icon: string;
+  @Input() iconClass: string;
+  @Input() type: string;
+  @Input() iconColor: string = 'none';
+  @Input() title: string = null;
+  constructor() {}
+}
diff --git a/src/app/shared/components/text-input-modal/text-input-modal.component.html b/src/app/shared/components/text-input-modal/text-input-modal.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..1ba0fc04d93cef1364cd11e8e0201c94aed4a6da
--- /dev/null
+++ b/src/app/shared/components/text-input-modal/text-input-modal.component.html
@@ -0,0 +1,13 @@
+<div *ngIf="openned" class="modalBackground" ng-controller="myCtrl">
+  <div class="modal">
+    <div class="contentModal" fxLayout="column" fxLayoutAlign="space-around center">
+      <h3>ATTENTION</h3>
+      <p>{{ content }}</p>
+      <textarea #myText id="story" class="textarea" name="story" rows="6" placeholder="{{ placeholder }}"></textarea>
+      <div class="footerModal" fxLayout="row" fxLayoutAlign="space-around center">
+        <button class="btn-primary small leave" (click)="closeModal(true, myText.value)">Confirmer</button>
+        <button class="btn-primary small" (click)="closeModal(false, myText.value)">Annuler</button>
+      </div>
+    </div>
+  </div>
+</div>
diff --git a/src/app/shared/components/text-input-modal/text-input-modal.component.scss b/src/app/shared/components/text-input-modal/text-input-modal.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..a085676ce7a73ec3b74f3a03979bf1dce7d0ee55
--- /dev/null
+++ b/src/app/shared/components/text-input-modal/text-input-modal.component.scss
@@ -0,0 +1,64 @@
+@import '../../../../assets/scss/color';
+@import '../../../../assets/scss/typography';
+@import '../../../../assets/scss/shapes';
+@import '../../../../assets/scss/z-index';
+
+.modalExitContainer {
+  width: 100%;
+  height: 100%;
+  z-index: $modal-z-index;
+  position: absolute;
+  content: '';
+  top: 0;
+  background-color: $modal-background;
+  .modal {
+    .contentModal {
+      width: 100%;
+      background: $white;
+      padding: 35px 20px 18px 20px;
+      h3 {
+        @include lato-bold-18;
+        color: $orange-warning;
+      }
+      p {
+        @include lato-bold-16;
+        color: $grey-1;
+        text-align: center;
+      }
+      .footerModal {
+        width: 100%;
+        margin-top: 14px;
+        @include lato-bold-16;
+        .leave {
+          background: none;
+          color: $grey-1;
+          text-decoration: underline;
+        }
+      }
+    }
+    width: 350px;
+    margin: auto;
+    border-radius: 6px;
+    @include background-hash($grey-2);
+    border: 1px solid $grey-4;
+    margin-top: 50vh;
+    transform: translateY(-50%);
+  }
+}
+.modalBackground {
+  .modal {
+    .contentModal {
+      padding: 20px;
+    }
+  }
+}
+
+.textarea {
+  padding: 13px 8px;
+  background: $grey-8;
+  border: 1px solid $grey-4;
+  border-radius: 1px;
+  resize: none;
+  width: 100%;
+  @include lato-regular-16;
+}
diff --git a/src/app/shared/components/text-input-modal/text-input-modal.component.spec.ts b/src/app/shared/components/text-input-modal/text-input-modal.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..75318c94dccbbe3ffb5cda8aea349fd58f4e7ca4
--- /dev/null
+++ b/src/app/shared/components/text-input-modal/text-input-modal.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { TextInputModalComponent } from './text-input-modal.component';
+
+describe('ModalConfirmationComponent', () => {
+  let component: TextInputModalComponent;
+  let fixture: ComponentFixture<TextInputModalComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ TextInputModalComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(TextInputModalComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/shared/components/text-input-modal/text-input-modal.component.ts b/src/app/shared/components/text-input-modal/text-input-modal.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..524396cda60cc474a8de4e2af85c3a3a06166244
--- /dev/null
+++ b/src/app/shared/components/text-input-modal/text-input-modal.component.ts
@@ -0,0 +1,21 @@
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+
+@Component({
+  selector: 'app-text-input-modal',
+  templateUrl: './text-input-modal.component.html',
+  styleUrls: ['./text-input-modal.component.scss'],
+})
+export class TextInputModalComponent {
+  @Input() public openned: boolean;
+  @Input() public content: string;
+  @Input() public placeholder: string;
+  @Output() closed = new EventEmitter<boolean>();
+  @Output() newContent = new EventEmitter<{ content: string; shouldSend: boolean }>();
+
+  public myContent: string;
+  constructor() {}
+
+  public closeModal(shouldSend: boolean, content: string) {
+    this.newContent.emit({ content, shouldSend });
+  }
+}
diff --git a/src/app/shared/components/training-type-picker/training-type-picker.component.ts b/src/app/shared/components/training-type-picker/training-type-picker.component.ts
index e2555e93cd423a191056615dc97046f22030e9aa..a82331982d7a860aedf41930355b31a1f82ba67c 100644
--- a/src/app/shared/components/training-type-picker/training-type-picker.component.ts
+++ b/src/app/shared/components/training-type-picker/training-type-picker.component.ts
@@ -1,8 +1,9 @@
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
-import { Category, Module } from '@gouvfr-anct/mediation-numerique';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
-import { cloneDeep, remove } from 'lodash';
+import { Category } from '../../../structure-list/models/category.model';
+import { Module } from '../../../structure-list/models/module.model';
 import { SearchService } from '../../../structure-list/services/search.service';
+import { cloneDeep, remove } from 'lodash';
+import { ButtonType } from '../button/buttonType.enum';
 
 @Component({
   selector: 'app-training-type-picker',
diff --git a/src/app/shared/directives/index.ts b/src/app/shared/directives/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..924e8410cadc985320d9a2af73b00218a316fe38
--- /dev/null
+++ b/src/app/shared/directives/index.ts
@@ -0,0 +1,7 @@
+import { TooltipDirective } from '../components/tooltip/tooltip.directive';
+import { ModalOutsideDirective } from './modalOutside.directive';
+
+export { ModalOutsideDirective };
+
+// tslint:disable-next-line:variable-name
+export const SharedDirectives = [ModalOutsideDirective, TooltipDirective];
diff --git a/src/app/shared/directives/modalOutside.directive.ts b/src/app/shared/directives/modalOutside.directive.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b8ebc284c1ccfb67aa0b0527df5e39322e834ec5
--- /dev/null
+++ b/src/app/shared/directives/modalOutside.directive.ts
@@ -0,0 +1,18 @@
+/* tslint:disable:member-ordering */
+import { Directive, ElementRef, HostListener, Output, EventEmitter } from '@angular/core';
+
+@Directive({
+  selector: '[clickOutside]',
+})
+export class ModalOutsideDirective {
+  constructor(private _elementRef: ElementRef) {}
+
+  @Output('clickOutside') clickOutside: EventEmitter<any> = new EventEmitter();
+
+  @HostListener('document:mousedown', ['$event.target']) onMouseEnter(targetElement) {
+    const clickedInside = this._elementRef.nativeElement.contains(targetElement);
+    if (!clickedInside) {
+      this.clickOutside.emit(null);
+    }
+  }
+}
diff --git a/src/app/shared/enum/labels.enum.ts b/src/app/shared/enum/labels.emum.ts
similarity index 97%
rename from src/app/shared/enum/labels.enum.ts
rename to src/app/shared/enum/labels.emum.ts
index 841a3a828c9043f508dbd36ef60fe7f44d9a1b9c..675f045002847e68277e09e9c743b84e16ca00ed 100644
--- a/src/app/shared/enum/labels.enum.ts
+++ b/src/app/shared/enum/labels.emum.ts
@@ -1,9 +1,9 @@
-export enum Labels {
-  passNumerique = 'Pass numérique',
-  maisonFranceService = 'Maison france service',
-  aidantsConnect = 'Aidants connect',
-  fabriqueDeTerritoire = 'Fabrique de territoire',
-  demarcheMetropolitaine = 'Démarches Métropolitaines',
-  pix = 'Évaluation des compétences numériques',
-  conseillerNumFranceServices = 'Conseiller numérique',
-}
+export enum Labels {
+  passNumerique = 'Pass numérique',
+  maisonFranceService = 'Maison france service',
+  aidantsConnect = 'Aidants connect',
+  fabriqueDeTerritoire = 'Fabrique de territoire',
+  demarcheMetropolitaine = 'Démarches Métropolitaines',
+  pix = 'Évaluation des compétences numériques',
+  conseillerNumFranceServices = 'Conseiller numérique',
+}
diff --git a/src/app/shared/enum/typeStructure.enum.ts b/src/app/shared/enum/typeStructure.enum.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a024b8b2ac4fb8fcdec36fd6e1ca40d456615dd0
--- /dev/null
+++ b/src/app/shared/enum/typeStructure.enum.ts
@@ -0,0 +1,33 @@
+export enum typeStructureEnum {
+  fablab = 'Fablab',
+  // A supprimer ?
+
+  //A remplacer par Association ?
+  associationQuartier = 'Structure associative de quartier',
+  associationCaritative = 'Association caritative',
+
+  // En attente de suppression remplacer par CAF CARSAT, Pole Emploi et CCAS
+  grandOrganismePublic = 'Grand organisme public (CAF, CARSAT, Pôle emploi...)',
+
+  mdm = 'Maison de la Métropole',
+  mairie = 'Mairie',
+  CAF = 'CAF',
+  CCAS = 'CCAS',
+  CARSAT = 'CARSAT',
+  poleEmploi = 'Pole Emploi',
+  mediatheque = 'Médiathèque/Bibliothèque',
+  prefecture = 'Préfecture',
+  bijPij = 'BIJ/PIJ',
+  logement = 'Logement',
+  MaisonFranceService = 'Maison France Service',
+
+  association = 'Association',
+  centreSocio = 'Centre socio-culturel',
+  mjc = 'MJC / Cyberbase',
+  pimms = 'PIMMS',
+  sij = 'Structure information jeunesse (SIJ)',
+  missionsLocales = 'Missions locales',
+
+  formation = 'Structure de formation',
+  insertion = "Structure d'insertion",
+}
diff --git a/src/app/shared/pipes/day.pipe.ts b/src/app/shared/pipes/day.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f8a64598e1b294a248e95e347875f853a63d5139
--- /dev/null
+++ b/src/app/shared/pipes/day.pipe.ts
@@ -0,0 +1,25 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({ name: 'day', pure: false })
+export class DayPipe implements PipeTransform {
+  transform(day: string): any {
+    switch (day) {
+      case 'monday':
+        return 'lundi';
+      case 'tuesday':
+        return 'mardi';
+      case 'thursday':
+        return 'jeudi';
+      case 'wednesday':
+        return 'mercredi';
+      case 'friday':
+        return 'vendredi';
+      case 'saturday':
+        return 'samedi';
+      case 'sunday':
+        return 'dimanche';
+      default:
+        return null;
+    }
+  }
+}
diff --git a/src/app/shared/pipes/index.ts b/src/app/shared/pipes/index.ts
index c8178d45addbcda9339634549dcd7fed6a29257a..21bf9cf7e194188fe39c2c3257bb4e42f813da2a 100644
--- a/src/app/shared/pipes/index.ts
+++ b/src/app/shared/pipes/index.ts
@@ -1,6 +1,8 @@
-import { UrlPipe } from './url.pipe';
-
-export { UrlPipe };
-
-// tslint:disable-next-line:variable-name
-export const SharedPipes = [UrlPipe];
+import { DayPipe } from './day.pipe';
+import { PhonePipe } from './phone.pipe';
+import { UrlPipe } from './url.pipe';
+
+export { DayPipe, PhonePipe, UrlPipe };
+
+// tslint:disable-next-line:variable-name
+export const SharedPipes = [DayPipe, PhonePipe, UrlPipe];
diff --git a/src/app/shared/pipes/phone.pipe.ts b/src/app/shared/pipes/phone.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..af1e964f77bab9faf286c0171103acb5573fa631
--- /dev/null
+++ b/src/app/shared/pipes/phone.pipe.ts
@@ -0,0 +1,10 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({ name: 'phone' })
+export class PhonePipe implements PipeTransform {
+  transform(value: string): string {
+    //Remove dot and space from the phone string and add space in each 2 numbers
+    const regexArray = value.replace(/\s|\./g, '').match(/.{1,2}/g);
+    return regexArray.join(' ');
+  }
+}
diff --git a/src/app/shared/service/print.service.ts b/src/app/shared/service/print.service.ts
index f8eac10b2c6e7ff0b2e59426dceade32e1376343..115614975ab825878c8f0f1c6a8205bdad81a8d2 100644
--- a/src/app/shared/service/print.service.ts
+++ b/src/app/shared/service/print.service.ts
@@ -1,48 +1,48 @@
-import { Injectable } from '@angular/core';
-import { Router } from '@angular/router';
-import { Structure } from '@gouvfr-anct/mediation-numerique';
-
-@Injectable({
-  providedIn: 'root',
-})
-export class PrintService {
-  public isPrinting = false;
-  public structure: Structure;
-  public structures: Structure[];
-
-  constructor(private router: Router) {}
-
-  public printDocument(documentName: string, structure: Structure): void {
-    this.isPrinting = true;
-    this.structure = structure;
-    this.router.navigate([
-      '/',
-      {
-        outlets: {
-          print: ['print', documentName],
-        },
-      },
-    ]);
-  }
-
-  public printDocuments(documentName: string, structures: Structure[]): void {
-    this.isPrinting = true;
-    this.structures = structures;
-    this.router.navigate([
-      '/',
-      {
-        outlets: {
-          print: ['print', documentName],
-        },
-      },
-    ]);
-  }
-
-  public onDataReady(): void {
-    setTimeout(() => {
-      window.print();
-      this.isPrinting = false;
-      this.router.navigate([{ outlets: { print: null } }]);
-    }, 1500);
-  }
-}
+import { Injectable } from '@angular/core';
+import { Router } from '@angular/router';
+import { Structure } from '../../models/structure.model';
+
+@Injectable({
+  providedIn: 'root',
+})
+export class PrintService {
+  public isPrinting = false;
+  public structure: Structure;
+  public structures: Structure[];
+
+  constructor(private router: Router) {}
+
+  public printDocument(documentName: string, structure: Structure): void {
+    this.isPrinting = true;
+    this.structure = structure;
+    this.router.navigate([
+      '/',
+      {
+        outlets: {
+          print: ['print', documentName],
+        },
+      },
+    ]);
+  }
+
+  public printDocuments(documentName: string, structures: Structure[]): void {
+    this.isPrinting = true;
+    this.structures = structures;
+    this.router.navigate([
+      '/',
+      {
+        outlets: {
+          print: ['print', documentName],
+        },
+      },
+    ]);
+  }
+
+  public onDataReady(): void {
+    setTimeout(() => {
+      window.print();
+      this.isPrinting = false;
+      this.router.navigate([{ outlets: { print: null } }]);
+    }, 1500);
+  }
+}
diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts
index 83111888f7149e97f5701c4fc98d52fee7772ee3..c0829cf6b1ac5f9abd45de845b404f473f5ed840 100644
--- a/src/app/shared/shared.module.ts
+++ b/src/app/shared/shared.module.ts
@@ -1,51 +1,33 @@
-import { CommonModule } from '@angular/common';
-import { NgModule } from '@angular/core';
-import { FlexLayoutModule } from '@angular/flex-layout';
-import { FormsModule, ReactiveFormsModule } from '@angular/forms';
-import { RouterModule } from '@angular/router';
-import {
-  ButtonModule,
-  DayModule,
-  ModalModule,
-  PhoneModule,
-  SvgIconModule,
-  TextInputModalModule,
-} from '@gouvfr-anct/mediation-numerique/shared';
-import { SharedComponents } from './components';
-import { AddressAutocompleteComponent } from './components/address-autocomplete/address-autocomplete.component';
-import { HourPickerComponent } from './components/hour-picker/hour-picker.component';
-import { SharedPipes } from './pipes';
-
-@NgModule({
-  imports: [
-    CommonModule,
-    FormsModule,
-    RouterModule,
-    FlexLayoutModule,
-    ReactiveFormsModule,
-    ButtonModule,
-    SvgIconModule,
-    TextInputModalModule,
-    ModalModule,
-    DayModule,
-    PhoneModule,
-  ],
-  declarations: [...SharedPipes, ...SharedComponents, AddressAutocompleteComponent, HourPickerComponent],
-  exports: [
-    ...SharedPipes,
-    ...SharedComponents,
-    CommonModule,
-    RouterModule,
-    FlexLayoutModule,
-    FormsModule,
-    ReactiveFormsModule,
-    ButtonModule,
-    ButtonModule,
-    SvgIconModule,
-    TextInputModalModule,
-    ModalModule,
-    DayModule,
-    PhoneModule,
-  ],
-})
-export class SharedModule {}
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { RouterModule } from '@angular/router';
+import { FlexLayoutModule } from '@angular/flex-layout';
+import { SharedComponents } from './components';
+import { SharedPipes } from './pipes';
+import { SharedDirectives } from './directives';
+import { SvgIconComponent } from './components/svg-icon/svg-icon.component';
+import { AddressAutocompleteComponent } from './components/address-autocomplete/address-autocomplete.component';
+import { HourPickerComponent } from './components/hour-picker/hour-picker.component';
+@NgModule({
+  imports: [CommonModule, FormsModule, RouterModule, FlexLayoutModule, ReactiveFormsModule],
+  declarations: [
+    ...SharedPipes,
+    ...SharedComponents,
+    ...SharedDirectives,
+    SvgIconComponent,
+    AddressAutocompleteComponent,
+    HourPickerComponent,
+  ],
+  exports: [
+    ...SharedPipes,
+    ...SharedComponents,
+    ...SharedDirectives,
+    CommonModule,
+    RouterModule,
+    FlexLayoutModule,
+    FormsModule,
+    ReactiveFormsModule,
+  ],
+})
+export class SharedModule {}
diff --git a/src/app/structure-list/components/card/card.component.html b/src/app/structure-list/components/card/card.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..79c33855b964fd6c7a72bede87c912c0361c1930
--- /dev/null
+++ b/src/app/structure-list/components/card/card.component.html
@@ -0,0 +1,46 @@
+<div
+  class="structure"
+  fxLayout="column"
+  (click)="cardClicked()"
+  (mouseenter)="cardHover()"
+  [ngClass]="{ orientation: isOrientation }"
+>
+  <div class="left">
+    <div fxLayout="row" fxLayoutAlign="space-between baseline" fxLayoutGap="16px">
+      <div fxLayout="column" fxLayoutAlign="end">
+        <span class="structure-name" [ngClass]="{ notClaimed: !isClaimed }">{{ structure.structureName }}</span>
+        <span class="typeStructure">{{ structure.getLabelTypeStructure() }}</span>
+      </div>
+      <div *ngIf="!isOrientation" fxLayout="column" fxLayoutAlign="none end">
+        <div class="distanceStructure">
+          {{ this.structure.address.commune }}
+        </div>
+        <div class="distance" *ngIf="structure.distance">
+          {{ this.formatDistance() }}
+        </div>
+      </div>
+    </div>
+    <div class="distance" *ngIf="isOrientation && structure.distance">
+      {{ this.formatDistance() }}
+    </div>
+  </div>
+  <div class="actions right" *ngIf="isOrientation">
+    <div
+      fxLayout="row"
+      *ngIf="!isSelected"
+      class="selection-button selected"
+      (click)="cardAddToList(); $event.stopPropagation()"
+    >
+      <app-svg-icon class="add-icon" [type]="'ico'" [icon]="'add'" [iconColor]="'green'"></app-svg-icon>Ajouter
+    </div>
+    <div
+      fxLayout="row"
+      *ngIf="isSelected"
+      class="selection-button to-select"
+      (click)="cardAddToList(); $event.stopPropagation()"
+    >
+      <app-svg-icon class="add-icon" [type]="'ico'" [icon]="'validate'" [iconColor]="'white'"></app-svg-icon>
+      Ajouté
+    </div>
+  </div>
+</div>
diff --git a/src/app/structure-list/components/card/card.component.scss b/src/app/structure-list/components/card/card.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..0613c38040988de6a4de619bccd1040db7a7385b
--- /dev/null
+++ b/src/app/structure-list/components/card/card.component.scss
@@ -0,0 +1,89 @@
+@import '../../../../assets/scss/icons';
+@import '../../../../assets/scss/color';
+@import '../../../../assets/scss/typography';
+@import '../../../../assets/scss/breakpoint';
+
+.structure {
+  padding: 12px 24px;
+  border-bottom: 1px solid $grey-8 !important;
+  min-height: 110px;
+  display: flex;
+  justify-content: center;
+  cursor: pointer;
+  @media #{$large-phone} {
+    height: unset;
+  }
+  .typeStructure {
+    color: $grey-3;
+    @include lato-regular-16;
+    font-style: italic;
+  }
+  &:hover {
+    .structure-name {
+      text-decoration: underline;
+    }
+  }
+  .structure-name {
+    @include lato-bold-18;
+    color: $grey-1;
+    padding-bottom: 5px;
+    width: 100%;
+
+    &.notClaimed {
+      color: $primary-color;
+    }
+  }
+  .distanceStructure {
+    @include lato-regular-16;
+    color: $grey-3;
+    text-align: right;
+  }
+}
+
+.selection-button {
+  font-style: normal;
+  font-weight: bold;
+  justify-content: center;
+  align-items: center;
+  min-width: 120px;
+  height: 40px;
+  border-radius: 20px;
+}
+
+.selected {
+  border: solid 1px $grey-3;
+  background-color: $white;
+  color: $black;
+}
+.to-select {
+  color: $white;
+  border-style: none;
+  background: #47c562;
+}
+
+.distance {
+  @include lato-regular-14;
+  color: $grey-3;
+}
+
+.add-icon {
+  color: $green-1;
+}
+
+.orientation {
+  flex-direction: row !important;
+
+  .left {
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+    width: 70%;
+  }
+
+  .right {
+    margin-top: 6%;
+    @media #{$large-phone} {
+      margin-left: unset;
+    }
+  }
+}
diff --git a/src/app/structure-list/components/card/card.component.spec.ts b/src/app/structure-list/components/card/card.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..873f374bc18036ca517fd9e0f3d48fecac66ee0b
--- /dev/null
+++ b/src/app/structure-list/components/card/card.component.spec.ts
@@ -0,0 +1,183 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { CardComponent } from './card.component';
+import { HttpClientModule } from '@angular/common/http';
+import { Structure } from '../../../models/structure.model';
+import { OpeningDay } from '../../../models/openingDay.model';
+
+describe('CardComponent', () => {
+  let component: CardComponent;
+  let fixture: ComponentFixture<CardComponent>;
+  let structure: Structure;
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [HttpClientModule],
+      declarations: [CardComponent],
+    }).compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(CardComponent);
+    component = fixture.debugElement.componentInstance;
+    structure = new Structure({
+      id: 1,
+      numero: '26-63',
+      updatedAt: '2020-10-08T15:17:00.000Z',
+      structureRepresentation: 'Un établissement principal (siège social)',
+      structureName: 'Régie de Quartier Armstrong',
+      structureType: 'Tiers-lieu & coworking, FabLab',
+      description: "Association loi 1901 dont l'objet est l'insertion par l'économie social et solidaire",
+      address: {
+        numero: 2,
+        street: 'rue du test',
+        commune: 'villeurbanne',
+      },
+
+      contactPhone: '04 72 21 03 07',
+      contactMail: 'sguillet@rqa.fr',
+      website: '',
+      facebook: '',
+      twitter: '@rqainfo69',
+      instagram: '',
+      gender: 'Madame',
+      contactName: 'GUILLET',
+      contactSurname: 'Séverine',
+      fonction: 'Autres',
+      pmrAccess: '',
+      publicsAccompaniment: 'Tout public',
+      exceptionalClosures: '',
+      proceduresAccompaniment: 'Accompagnant CAF',
+      autresAccompagnements: '',
+      baseSkills: 260,
+      accessRight: 176,
+      socialAndProfessional: 254,
+      parentingHelp: '',
+      digitalCultureSecurity: 264,
+      hours: {
+        monday: {
+          open: true,
+          time: [
+            {
+              opening: 1330,
+              closing: 1630,
+            },
+            {
+              opening: null,
+              closing: null,
+            },
+          ],
+        },
+        tuesday: {
+          open: true,
+          time: [
+            {
+              opening: 830,
+              closing: 1130,
+            },
+            {
+              opening: 1330,
+              closing: 1630,
+            },
+          ],
+        },
+        wednesday: {
+          open: true,
+          time: [
+            {
+              opening: 1330,
+              closing: 1630,
+            },
+            {
+              opening: null,
+              closing: null,
+            },
+          ],
+        },
+        thursday: {
+          open: true,
+          time: [
+            {
+              opening: 830,
+              closing: 1130,
+            },
+            {
+              opening: 1330,
+              closing: 1630,
+            },
+          ],
+        },
+        friday: {
+          open: true,
+          time: [
+            {
+              opening: 830,
+              closing: 1130,
+            },
+            {
+              opening: 1330,
+              closing: 1530,
+            },
+          ],
+        },
+        saturday: {
+          open: false,
+          time: [
+            {
+              opening: null,
+              closing: null,
+            },
+            {
+              opening: null,
+              closing: null,
+            },
+          ],
+        },
+        sunday: {
+          open: false,
+          time: [
+            {
+              opening: null,
+              closing: null,
+            },
+            {
+              opening: null,
+              closing: null,
+            },
+          ],
+        },
+        openedOn: new OpeningDay('monday', null),
+      },
+      openedOn: new OpeningDay('monday', null),
+    });
+    component.structure = structure;
+    fixture.detectChanges(); // calls NgOnit
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  it('should transform a distance into km', () => {
+    component.structure.distance = 4320;
+    const distance = component.formatDistance();
+    expect(distance).toEqual('4.3 km');
+  });
+  it('should transform a distance into m', () => {
+    component.structure.distance = 400;
+    const distance = component.formatDistance();
+    expect(distance).toEqual('400 m');
+  });
+
+  it('should emit structure to show details', () => {
+    spyOn(component.showDetails, 'emit');
+    component.cardClicked();
+    expect(component.showDetails.emit).toHaveBeenCalled();
+    expect(component.showDetails.emit).toHaveBeenCalledWith(structure);
+  });
+  it('should emit structure on cardHover', () => {
+    spyOn(component.hover, 'emit');
+    component.cardHover();
+    expect(component.hover.emit).toHaveBeenCalled();
+    expect(component.hover.emit).toHaveBeenCalledWith(structure);
+  });
+});
diff --git a/src/app/structure-list/components/card/card.component.ts b/src/app/structure-list/components/card/card.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5b891466c8c688140d7b4c833a201e33dba781cd
--- /dev/null
+++ b/src/app/structure-list/components/card/card.component.ts
@@ -0,0 +1,74 @@
+import { Component, Input, Output, OnInit, EventEmitter } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { Structure } from '../../../models/structure.model';
+import { ProfileService } from '../../../profile/services/profile.service';
+import { StructureService } from '../../../services/structure.service';
+
+@Component({
+  selector: 'app-card',
+  templateUrl: './card.component.html',
+  styleUrls: ['./card.component.scss'],
+})
+export class CardComponent implements OnInit {
+  @Input() public structure: Structure;
+  @Input() public isSelected: boolean;
+  @Input() public isOrientation: boolean;
+  @Output() public showDetails: EventEmitter<Structure> = new EventEmitter<Structure>();
+  @Output() public addToList: EventEmitter<Structure> = new EventEmitter<Structure>();
+  @Output() public hover: EventEmitter<Structure> = new EventEmitter<Structure>();
+  public isClaimed = true;
+
+  constructor(
+    private route: ActivatedRoute,
+    private router: Router,
+    private profileService: ProfileService,
+    private structureService: StructureService
+  ) {}
+  ngOnInit(): void {
+    if (this.profileService.isAdmin()) {
+      this.setClaimIndicator();
+    }
+  }
+
+  // Check if structure haven't owners to help admin vision.
+  async setClaimIndicator() {
+    this.isClaimed = await this.structureService.isClaimed(this.structure._id, null).toPromise();
+  }
+
+  /**
+   * Display distance in m or km according to value
+   */
+  public formatDistance(): string {
+    if (this.structure.distance > 1000) {
+      return (this.structure.distance / 1000).toFixed(1).toString() + ' km';
+    } else {
+      return this.structure.distance + ' m';
+    }
+  }
+
+  public cardClicked(): void {
+    this.showDetails.emit(this.structure);
+    if (!this.isOrientation) {
+      const queryString = this.route.snapshot.queryParamMap.get('search');
+      this.router.navigate([], {
+        relativeTo: this.route,
+        queryParams: queryString
+          ? {
+              id: this.structure._id,
+              search: queryString,
+            }
+          : {
+              id: this.structure._id,
+            },
+      });
+    }
+  }
+
+  public cardHover(): void {
+    this.hover.emit(this.structure);
+  }
+
+  public cardAddToList(): void {
+    this.addToList.emit(this.structure);
+  }
+}
diff --git a/src/app/structure-list/components/modal-filter/modal-filter.component.html b/src/app/structure-list/components/modal-filter/modal-filter.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..37b27ad7bc3765273f30aeba635e6bb7ef216304
--- /dev/null
+++ b/src/app/structure-list/components/modal-filter/modal-filter.component.html
@@ -0,0 +1,181 @@
+<div *ngIf="modalType" fxLayout="column" fxLayoutAlign="center center" [ngClass]="['modal', 'modal' + getModalType()]">
+  <div class="body-wrap" fxLayout="column" fxLayoutAlign="space-between">
+    <div class="titleFilter" fxLayout="row" fxLayoutAlign="space-between">
+      <span>Filtres</span>
+      <div (click)="closeModal()" class="ico-close-details"></div>
+    </div>
+    <!-- Filter with single category -->
+    <div class="contentModal" fxLayout="row wrap" fxLayoutAlign="flex-start" *ngIf="categories.length === 1">
+      <div class="blockFiltre" *ngFor="let c of categories">
+        <ul class="blockLigne">
+          <div fxLayout="row" fxLayoutAlign="start center" class="ligneFiltre" *ngFor="let module of c.modules">
+            <li class="checkbox">
+              <div class="checkboxItem">
+                <label fxLayout="row" fxLayoutAlign="start center">
+                  <input
+                    type="checkbox"
+                    [checked]="searchService.getIndex(checkedModules, module.id, c.id) > -1"
+                    [value]="module.id"
+                    (change)="onCheckboxChange($event, c.id, module.text)"
+                  />
+                  <span class="customCheck customCheckPrimary"></span>
+                  <div class="label">{{ module.text }}</div>
+                </label>
+              </div>
+            </li>
+          </div>
+        </ul>
+      </div>
+    </div>
+    <!-- "Other filters" backdrop fullwidth modal -->
+    <div
+      class="contentModal maxModal"
+      fxLayout="row wrap"
+      fxLayoutAlign="flex-start"
+      *ngIf="categories.length > 1 && getModalType() === 'moreFilters'"
+    >
+      <div
+        class="blockLigne"
+        (clickOutside)="getModalType() === 'moreFilters' ? closeModal() : ''"
+        [ngClass]="{ backDropModal: getModalType() === 'moreFilters' }"
+      >
+        <div class="headerMoreFilters" *ngIf="getModalType() === 'moreFilters'">
+          Plus de filtres
+          <div class="iconClose" (click)="closeModal()">
+            <app-svg-icon
+              [iconClass]="'icon-28'"
+              [iconColor]="'grey-1'"
+              [icon]="'closeModal'"
+              [type]="'ico'"
+            ></app-svg-icon>
+          </div>
+        </div>
+        <div class="scroll-container">
+          <div class="blockFiltre" *ngFor="let c of categories">
+            <p>{{ c.name }}</p>
+            <ul class="blockLigne smallList" [ngClass]="{ show: this.toggledCategories.includes(c.id) }">
+              <div fxLayout="row" fxLayoutAlign="start center" class="ligneFiltre" *ngFor="let module of c.modules">
+                <li class="checkbox">
+                  <div class="checkboxItem">
+                    <label fxLayout="row" fxLayoutAlign="start center">
+                      <input
+                        type="checkbox"
+                        [checked]="searchService.getIndex(checkedModules, module.id, c.id) > -1"
+                        [value]="module.id"
+                        (change)="onCheckboxChange($event, c.id, module.displayText)"
+                      />
+                      <span class="customCheck customCheckPrimary"></span>
+                      <div class="label">{{ module.text }}</div>
+                    </label>
+                  </div>
+                </li>
+              </div>
+            </ul>
+          </div>
+        </div>
+        <div
+          class="footer"
+          fxLayout="row"
+          fxLayoutAlign="center center"
+          [ngClass]="{ backDropModalFooter: getModalType() === 'moreFilters' }"
+        >
+          <div class="half-width">
+            <app-button
+              [style]="buttonTypeEnum.modalSecondary"
+              [text]="'Effacer'"
+              (click)="clearFilters()"
+              tabindex="0"
+            ></app-button>
+          </div>
+          <div class="half-width">
+            <app-button
+              [style]="buttonTypeEnum.modalPrimary"
+              [text]="'Appliquer'"
+              (click)="emitModules(checkedModules)"
+            ></app-button>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- Filter with multiple categories -->
+    <div
+      class="contentModal maxModal max-height"
+      fxLayout="row wrap"
+      fxLayoutAlign="flex-start"
+      *ngIf="categories.length > 1 && getModalType() !== 'moreFilters'"
+    >
+      <ul class="blockLigne">
+        <div class="blockFiltre" *ngFor="let c of categories">
+          <li class="checkbox">
+            <div class="checkboxItem categoryCheckBox">
+              <div fxLayout="row" fxLayoutAlign="start center">
+                <label>
+                  <input
+                    type="checkbox"
+                    class="multiCheck"
+                    [checked]="getCategoryCheckboxStatus(c) === 'checked'"
+                    (change)="handleCategoryCheckBox($event, c)"
+                  />
+                  <span
+                    class="customCheck customCheckPrimary"
+                    [ngClass]="{ halfCheck: getCategoryCheckboxStatus(c) === 'halfChecked' }"
+                  ></span>
+                </label>
+                <div
+                  fxLayout="row"
+                  fxLayoutAlign="space-between center"
+                  class="w-100 clickable"
+                  (click)="toggleShowCategory(c.id)"
+                >
+                  <div class="label">{{ c.name }}</div>
+                  <div class="arrow" [ngClass]="{ toggled: this.toggledCategories.includes(c.id) }"></div>
+                </div>
+              </div>
+              <ul class="blockLigne smallList" [ngClass]="{ show: this.toggledCategories.includes(c.id) }">
+                <div fxLayout="row" fxLayoutAlign="start center" class="ligneFiltre" *ngFor="let module of c.modules">
+                  <li class="checkbox">
+                    <div class="checkboxItem">
+                      <label fxLayout="row" fxLayoutAlign="start center">
+                        <input
+                          type="checkbox"
+                          [checked]="searchService.getIndex(checkedModules, module.id, c.id) > -1"
+                          [value]="module.id"
+                          (change)="onCheckboxChange($event, c.id, module.text)"
+                        />
+                        <span class="customCheck customCheckPrimary"></span>
+                        <div class="label">{{ module.text }}</div>
+                      </label>
+                    </div>
+                  </li>
+                </div>
+              </ul>
+            </div>
+          </li>
+        </div>
+      </ul>
+    </div>
+    <div
+      class="footer"
+      fxLayout="row"
+      fxLayoutAlign="center center"
+      [ngClass]="{ backDropModalFooter: getModalType() === 'moreFilters' }"
+      *ngIf="getModalType() !== 'moreFilters'"
+    >
+      <div class="half-width">
+        <app-button
+          [style]="buttonTypeEnum.modalSecondary"
+          [text]="'Effacer'"
+          (click)="clearFilters()"
+          tabindex="0"
+        ></app-button>
+      </div>
+      <div class="half-width">
+        <app-button
+          [style]="buttonTypeEnum.modalPrimary"
+          [text]="'Appliquer'"
+          (click)="emitModules(checkedModules)"
+        ></app-button>
+      </div>
+    </div>
+  </div>
+</div>
diff --git a/src/app/structure-list/components/modal-filter/modal-filter.component.scss b/src/app/structure-list/components/modal-filter/modal-filter.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..c443be97c66da9e684834422ef02baaa86034954
--- /dev/null
+++ b/src/app/structure-list/components/modal-filter/modal-filter.component.scss
@@ -0,0 +1,223 @@
+@import '../../../../assets/scss/icons';
+@import '../../../../assets/scss/color';
+@import '../../../../assets/scss/typography';
+@import '../../../../assets/scss/breakpoint';
+@import '../../../../assets/scss/shapes';
+@import '../../../../assets/scss/hyperlink';
+@import '../../../../assets/scss/z-index';
+
+.modalaccompaniment {
+  left: 212px;
+  @media #{$large-desktop} {
+    left: 273px;
+  }
+}
+.modaltraining {
+  left: 331px;
+  @media #{$large-desktop} {
+    left: 417px;
+  }
+}
+.modalpublic {
+  left: 431px;
+  @media #{$large-desktop} {
+    left: 513px;
+  }
+}
+.modalequipments {
+  left: 519px;
+  @media #{$large-desktop} {
+    left: 603px;
+  }
+}
+.maxModal .blockLigne {
+  box-sizing: border-box;
+  width: 360px;
+  .smallList {
+    display: block;
+    box-sizing: border-box;
+    background: $grey-8;
+    max-width: 300px;
+    padding: 0.5rem !important;
+    margin-top: 1rem !important;
+  }
+}
+.modal {
+  max-width: 360px;
+  width: auto;
+  z-index: $modal-z-index !important;
+  position: fixed;
+  box-shadow: 0px 4px 16px rgba(0, 0, 0, 0.25);
+  border-radius: 8px;
+  margin-top: 25px;
+  @media #{$large-phone} {
+    height: 100%;
+    max-height: auto;
+    max-width: auto;
+    width: 100%;
+    position: fixed;
+    top: 0;
+    left: 0;
+    border: none;
+    padding: 0;
+  }
+  background: white;
+  .body-wrap {
+    @media #{$large-phone} {
+      height: 100vh;
+      height: -webkit-fill-available;
+    }
+    .titleFilter {
+      display: none !important;
+      margin: 27px 25px 0px 25px;
+      @include lato-bold-26;
+      @media #{$large-phone} {
+        display: flex !important;
+      }
+    }
+  }
+  .contentModal {
+    overflow-y: auto;
+    max-width: 1100px;
+    border-bottom: 1px solid $grey;
+    @media #{$large-phone} {
+      max-height: none;
+      height: 100%;
+    }
+    .blockFiltre {
+      width: auto;
+      margin: 25px 20px;
+      margin-bottom: calc(25px - 1rem);
+      min-width: 200px;
+
+      @media #{$large-phone} {
+        margin: 0 18px;
+        padding: 25px 0;
+        min-width: 0;
+      }
+      .categoryCheckBox {
+        .halfCheck {
+          position: relative;
+          &:before {
+            content: '';
+            position: absolute;
+            display: block;
+            width: 10px;
+            left: 4px;
+            top: 8px;
+            transform: rotate(0deg);
+            border-bottom: solid 2px $grey-2;
+            border-radius: 0;
+          }
+        }
+        ul {
+          display: none;
+        }
+        .show {
+          display: block !important;
+        }
+      }
+    }
+    .blockLigne {
+      padding-left: 0;
+      margin: 0px;
+      li {
+        margin-bottom: 1rem;
+      }
+    }
+    label {
+      @include lato-regular-16;
+      color: $grey-1;
+    }
+
+    .arrow {
+      cursor: pointer;
+      margin-left: auto;
+      background-color: transparent;
+      border-bottom: 1px solid black;
+      border-right: 1px solid black;
+      transform: translateY(-25%) rotate(45deg);
+      height: 7px;
+      width: 7px;
+      transition: all 300ms ease;
+      margin-top: -5px;
+    }
+    .toggled {
+      transform: translateY(25%) rotate(-135deg);
+    }
+    &.max-height {
+      max-height: 50vh;
+      overflow-y: overlay;
+    }
+  }
+  .footer {
+    box-sizing: border-box;
+    padding: 0.5rem;
+    .reset {
+      width: 45%;
+      text-align: center;
+      color: $grey-4;
+    }
+    .half-width {
+      width: 50%;
+      padding: 0 4px;
+    }
+  }
+}
+.modalmoreFilters {
+  width: 100%;
+  min-width: 100%;
+  height: 100vh;
+  min-height: 100vh;
+  top: 0;
+  left: 0;
+  display: flex;
+  flex-direction: column;
+  background: rgba(0, 0, 0, 0.8) !important;
+  margin: 0;
+  border-radius: 0;
+  .scroll-container {
+    max-height: 390px;
+    overflow-y: scroll;
+  }
+  .maxModal {
+    max-width: 360px;
+    margin: auto;
+    background: white;
+    margin-top: 10%;
+    border-radius: 8px;
+    // overflow: hidden;
+  }
+  .backDropModal {
+    background: white;
+    width: 360px;
+    min-height: 40vh;
+  }
+  .backDropModalFooter {
+    background: white;
+    width: 360px;
+    margin: auto;
+    border-radius: 0 0 8px 8px;
+  }
+  .headerMoreFilters {
+    position: relative;
+    text-align: center;
+    color: $grey-1;
+    background: white;
+    padding: 1rem;
+    @include lato-bold-18;
+    align-items: center;
+    justify-content: center;
+    border-bottom: solid 1px $grey-6;
+    border-radius: 8px 8px 0 0;
+    .iconClose {
+      cursor: pointer;
+      position: absolute;
+      right: 14px;
+      top: 7px;
+    }
+  }
+}
+a {
+  @include hyperlink;
+}
diff --git a/src/app/structure-list/components/modal-filter/modal-filter.component.spec.ts b/src/app/structure-list/components/modal-filter/modal-filter.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..08583519907633fe953eb0ef7551c451e787c89d
--- /dev/null
+++ b/src/app/structure-list/components/modal-filter/modal-filter.component.spec.ts
@@ -0,0 +1,104 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { TypeModal } from '../../enum/typeModal.enum';
+import { Category } from '../../models/category.model';
+import { Module } from '../../models/module.model';
+
+import { ModalFilterComponent } from './modal-filter.component';
+
+describe('ModalFilterComponent', () => {
+  let component: ModalFilterComponent;
+  let fixture: ComponentFixture<ModalFilterComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ModalFilterComponent],
+      imports: [HttpClientTestingModule, ReactiveFormsModule],
+    }).compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(ModalFilterComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  // emitModules function
+  it('should emit modules', () => {
+    const modules: Module[] = [
+      { id: '176', text: 'training', count: 3 },
+      { id: '173', text: 'training', count: 2 },
+      { id: '172', text: 'training', count: 2 },
+    ];
+    spyOn(component.searchEvent, 'emit');
+    component.emitModules(modules);
+    expect(component.searchEvent.emit).toHaveBeenCalled();
+    expect(component.searchEvent.emit).toHaveBeenCalledWith(modules);
+  });
+
+  // onCheckboxChange function
+  it('should add a module to checkedModule array', () => {
+    const modules: Module[] = [
+      { id: '176', text: 'training', count: 0 },
+      { id: '173', text: 'training', count: 0 },
+      { id: '172', text: 'training', count: 0 },
+    ];
+    component.checkedModules = modules;
+    const evt = { target: { checked: true, value: '175' } };
+    component.onCheckboxChange(evt, 'training');
+    expect(component.checkedModules.length).toEqual(4);
+  });
+  it('should remove a module to checkedModule array', () => {
+    const modules: Module[] = [
+      { id: '176', text: 'training', count: 0 },
+      { id: '173', text: 'training', count: 0 },
+      { id: '172', text: 'training', count: 0 },
+    ];
+    component.checkedModules = modules;
+    const evt = { target: { checked: false, value: '173' } };
+    component.onCheckboxChange(evt, 'training');
+    expect(component.checkedModules.length).toEqual(2);
+  });
+
+  // clearFilters function
+  it('should remove all modules checked from same modal, here morefilters', () => {
+    const modules: Module[] = [
+      { id: '176', text: 'morefilters', count: 0 },
+      { id: '173', text: 'morefilters', count: 0 },
+      { id: '172', text: 'morefilters', count: 0 },
+      { id: '179', text: 'training', count: 0 },
+      { id: '190', text: 'training', count: 0 },
+      { id: '167', text: 'training', count: 0 },
+    ];
+    component.checkedModules = modules;
+    const category: Category = new Category({ id: 'morefilters', modules: [modules[0], modules[1], modules[2]] });
+    component.categories = [category];
+    component.clearFilters();
+    expect(component.checkedModules.length).toEqual(3);
+  });
+
+  // getModalType function
+  it('should return string of type about current enum', () => {
+    component.modalType = TypeModal.training;
+    const resultTraining = component.getModalType();
+    component.modalType = TypeModal.accompaniment;
+    const resultAccopaniment = component.getModalType();
+    component.modalType = TypeModal.moreFilters;
+    const resultMoreFilters = component.getModalType();
+    expect(resultTraining).toEqual('training');
+    expect(resultMoreFilters).toEqual('moreFilters');
+    expect(resultAccopaniment).toEqual('');
+  });
+
+  // closeModal function
+  it('should emit modules', () => {
+    spyOn(component.closeEvent, 'emit');
+    component.closeModal();
+    expect(component.closeEvent.emit).toHaveBeenCalled();
+  });
+});
diff --git a/src/app/structure-list/components/modal-filter/modal-filter.component.ts b/src/app/structure-list/components/modal-filter/modal-filter.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0620f70b841a8e71f8bea09dcd9de2e7a312af86
--- /dev/null
+++ b/src/app/structure-list/components/modal-filter/modal-filter.component.ts
@@ -0,0 +1,125 @@
+import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
+import { ButtonType } from '../../../shared/components/button/buttonType.enum';
+import { TypeModal } from '../../enum/typeModal.enum';
+import { Category } from '../../models/category.model';
+import { Module } from '../../models/module.model';
+import { SearchService } from '../../services/search.service';
+
+@Component({
+  selector: 'app-modal-filter',
+  templateUrl: './modal-filter.component.html',
+  styleUrls: ['./modal-filter.component.scss'],
+})
+export class ModalFilterComponent implements OnInit, OnChanges {
+  constructor(public searchService: SearchService) {}
+
+  @Input() public modalType: TypeModal;
+  @Input() public categories: Category[];
+  //checked modules filter list
+  @Input() public modules: Module[] = [];
+  @Output() searchEvent = new EventEmitter();
+  @Output() closeEvent = new EventEmitter();
+  public buttonTypeEnum = ButtonType;
+
+  // Checkbox variable
+  public checkedModules: Module[] = [];
+  public toggledCategories: string[] = [];
+  ngOnInit(): void {
+    // Manage checkbox
+    this.checkedModules = this.modules.slice();
+  }
+
+  ngOnChanges(changes: SimpleChanges): void {
+    if (changes.modalType) {
+      this.checkedModules = this.modules.slice();
+    }
+  }
+
+  // Management of the checkbox event (Check / Uncheck)
+  public onCheckboxChange(event, categ: string, text?: string): void {
+    const checkValue: string = event.target.value;
+    if (event.target.checked) {
+      this.checkedModules.push(new Module(checkValue, categ, text ? text : checkValue));
+    } else {
+      // Check if the module is present in the list and remove it
+      if (this.searchService.getIndex(this.checkedModules, checkValue, categ) > -1) {
+        this.checkedModules.splice(this.searchService.getIndex(this.checkedModules, checkValue, categ), 1);
+      }
+    }
+  }
+  // Clear only filters in the current modal
+  public clearFilters(): void {
+    this.categories.forEach((categ: Category) => {
+      categ.modules.forEach((module: Module) => {
+        const index = this.searchService.getIndex(this.checkedModules, module.id, categ.id);
+        if (index > -1) {
+          this.checkedModules.splice(index, 1);
+        }
+      });
+    });
+    this.emitModules(this.checkedModules);
+  }
+
+  // Sends an array containing all modules
+  public emitModules(m: Module[]): void {
+    this.searchEvent.emit(m);
+  }
+
+  public getModalType(): string {
+    switch (this.modalType) {
+      case TypeModal.accompaniment:
+        return 'accompaniment';
+      case TypeModal.training:
+        return 'training';
+      case TypeModal.public:
+        return 'public';
+      case TypeModal.equipments:
+        return 'equipments';
+      case TypeModal.moreFilters:
+        return 'moreFilters';
+      default:
+        return '';
+    }
+  }
+
+  public closeModal(): void {
+    this.closeEvent.emit();
+  }
+
+  public handleCategoryCheckBox(event, category: Category): void {
+    const modules = this.categories.filter((c: Category) => c.id === category.id)[0].modules;
+    if (event.target.checked) {
+      for (const module of modules) {
+        if (this.searchService.getIndex(this.checkedModules, module.id, category.id) === -1) {
+          this.checkedModules.push(new Module(module.id, category.id, module.displayText));
+        }
+      }
+    } else {
+      for (const module of modules) {
+        if (this.searchService.getIndex(this.checkedModules, module.id, category.id) > -1) {
+          this.checkedModules.splice(this.searchService.getIndex(this.checkedModules, module.id, category.id), 1);
+        }
+      }
+    }
+  }
+
+  public toggleShowCategory(categoryId: string): void {
+    if (this.toggledCategories.includes(categoryId)) {
+      const index = this.toggledCategories.indexOf(categoryId);
+      this.toggledCategories.splice(index);
+    } else {
+      this.toggledCategories.push(categoryId);
+    }
+  }
+
+  public getCategoryCheckboxStatus(c: Category): string {
+    const selectedModule: Module[] = this.checkedModules.filter((m) => m.text === c.id);
+    if (selectedModule.length === c.modules.length) {
+      return 'checked';
+    } else if (selectedModule.length === 0) {
+      return 'unchecked';
+    } else if (selectedModule.length && selectedModule.length > 0) {
+      return 'halfChecked';
+    }
+  }
+}
diff --git a/src/app/structure-list/components/structure-details/structure-details.component.html b/src/app/structure-list/components/structure-details/structure-details.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..785ae3639c958d1a26c6257ad5894fa496ee39df
--- /dev/null
+++ b/src/app/structure-list/components/structure-details/structure-details.component.html
@@ -0,0 +1,559 @@
+<div class="structure-details" [ngClass]="{ fullScreen: fullScreen === true }" [@slideInOut] *ngIf="structure">
+  <div class="structure-details-container">
+    <!-- Header info -->
+    <div class="structure-details-title" fxLayout="row" fxLayoutGap="8px" fxLayoutAlign="space-evenly center">
+      <app-svg-icon [type]="'ico'" [icon]="'structureAvatar'" [iconClass]="'icon-52'"></app-svg-icon>
+      <h1 class="bold">{{ structure.structureName }}</h1>
+      <div class="ico-close">
+        <div (click)="close()" class="ico-close-details"></div>
+      </div>
+    </div>
+    <div class="structure-details-content" fxLayout="row" fxLayoutAlign="center center" *ngIf="isLoading">
+      <img class="loader-gif" src="/assets/gif/loader_circle.gif" alt />
+    </div>
+    <!-- Content -->
+    <div class="structure-details-content" *ngIf="!isLoading">
+      <!-- Action buttons bar -->
+      <div class="structure-buttons hide-on-print" fxLayout="row" fxLayoutAlign="space-evenly">
+        <!-- Voir le conseiller numérique - Hidden until functionnality is developed -->
+        <!--div class="clickableDiv" role="button" tabindex="0">
+        <app-svg-icon
+          class="icon"
+          [type]="'ico'"
+          [icon]="'advisor'"
+          [iconClass]="'icon-32'"
+          fxLayoutAlign="space-evenly"
+        ></app-svg-icon>
+        <div class="iconTitle">Voir le conseiller numérique</div>
+      </div-->
+        <!-- Voir le site -->
+        <div *ngIf="structure.website" class="clickableDiv" role="button" (click)="goToWebsite()" tabindex="0">
+          <app-svg-icon class="icon" [type]="'ico'" [icon]="'web'" [iconClass]="'icon-32'"></app-svg-icon>
+          <div class="iconTitle">Voir le site</div>
+        </div>
+        <!-- Voir la plaquette - Hidden until functionnality is developed -->
+        <!--div class="clickableDiv" role="button" tabindex="0">
+        <app-svg-icon class="icon" [type]="'ico'" [icon]="'docs'" [iconClass]="'icon-32'"></app-svg-icon>
+        <div class="iconTitle">Voir la plaquette</div>
+      </div-->
+        <!-- Imprimer -->
+        <div role="button" class="printButton clickableDiv" (click)="print()" tabindex="0">
+          <app-svg-icon class="icon" [type]="'ico'" [icon]="'printStructure'" [iconClass]="'icon-32'"></app-svg-icon>
+          <div class="iconTitle">Imprimer</div>
+        </div>
+        <!-- Signaler une erreur -->
+        <div class="clickableDiv" role="button" (click)="displayModalError()" tabindex="0">
+          <app-svg-icon class="icon" [type]="'ico'" [icon]="'watch'" [iconClass]="'icon-32'"></app-svg-icon>
+          <div class="iconTitle">Signaler une erreur</div>
+        </div>
+        <!-- Je travaille ici -->
+        <div
+          *ngIf="!profileService.isLinkedToStructure(structure._id)"
+          class="clickableDiv"
+          role="button"
+          (click)="handleJoin()"
+          tabindex="0"
+        >
+          <app-svg-icon class="icon" [type]="'ico'" [icon]="'workhere'" [iconClass]="'icon-32'"></app-svg-icon>
+          <div class="iconTitle">Je travaille ici</div>
+        </div>
+        <!-- Modifier la structure -->
+        <div
+          *ngIf="profileService.isLinkedToStructure(structure._id) || profileService.isAdmin()"
+          class="clickableDiv"
+          role="button"
+          (click)="handleModify()"
+          tabindex="0"
+        >
+          <app-svg-icon class="icon" [type]="'ico'" [icon]="'modifyStructure'" [iconClass]="'icon-32'"></app-svg-icon>
+          <div class="iconTitle">Modifier cette structure</div>
+        </div>
+      </div>
+
+      <!-- Admin menu -->
+      <div *ngIf="profileService.isAdmin()" class="structure-details-block hide-on-print">
+        Administrateur(s) de cette structure:
+        <div *ngIf="structureAdmins.length === 0">Aucun administrateur</div>
+        <div *ngIf="structureAdmins.length > 0">
+          <div *ngFor="let structureAdmin of structureAdmins">
+            {{ structureAdmin.email }}
+          </div>
+        </div>
+        <a (click)="toggleDeleteModal()" class="primary" tabindex="0"> Supprimer cette structure </a>
+      </div>
+
+      <div class="structure-details-block">
+        <div fxLayout="column" fxLayoutGap="10px">
+          <!-- Informations-->
+          <div fxLayout="column">
+            <h2>Informations</h2>
+            <div class="info-block">
+              <div>
+                {{ structure.getLabelTypeStructure() }}
+              </div>
+              <div *ngIf="structure.address">
+                {{ structure.address.numero }} {{ structure.address.street }}, {{ structure.address.commune }}
+              </div>
+              <div *ngIf="structure.contactPhone">
+                {{ structure.contactPhone | phone }}
+              </div>
+              <div *ngIf="structure.contactMail && structure.contactMail !== 'unknown@unknown.com'">
+                <a href="mailto:{{ structure.contactMail }}">{{ structure.contactMail }}</a>
+              </div>
+            </div>
+            <!-- Social networks-->
+            <div *ngIf="structure.hasSocialNetwork()" fxLayout="row" fxLayoutAlign="none baseline" fxLayoutGap="4px">
+              <a
+                *ngIf="structure.facebook"
+                target="_blank"
+                class="custom-link"
+                rel="noopener noreferrer"
+                [href]="'http://' + structure.facebook"
+              >
+                <app-svg-icon
+                  [type]="'ico'"
+                  [icon]="'facebook'"
+                  [title]="'Facebook'"
+                  [iconClass]="'icon-30'"
+                ></app-svg-icon
+              ></a>
+              <a
+                *ngIf="structure.twitter"
+                target="_blank"
+                class="custom-link"
+                rel="noopener noreferrer"
+                [href]="'http://' + structure.twitter"
+              >
+                <app-svg-icon
+                  [type]="'ico'"
+                  [icon]="'twitter'"
+                  [title]="'Twitter'"
+                  [iconClass]="'icon-30'"
+                ></app-svg-icon
+              ></a>
+              <a
+                *ngIf="structure.instagram"
+                target="_blank"
+                class="custom-link"
+                rel="noopener noreferrer"
+                [href]="'http://' + structure.instagram"
+              >
+                <app-svg-icon
+                  [type]="'ico'"
+                  [icon]="'instagram'"
+                  [title]="'Instagram'"
+                  [iconClass]="'icon-30'"
+                ></app-svg-icon
+              ></a>
+              <a
+                *ngIf="structure.linkedin"
+                target="_blank"
+                class="custom-link"
+                rel="noopener noreferrer"
+                [href]="'http://' + structure.linkedin"
+              >
+                <app-svg-icon
+                  [type]="'ico'"
+                  [icon]="'linkedin'"
+                  [title]="'Linkedin'"
+                  [iconClass]="'icon-30'"
+                ></app-svg-icon
+              ></a>
+            </div>
+          </div>
+        </div>
+        <div *ngIf="structure.description" class="description">{{ structure.description }}</div>
+        <div *ngIf="structure.lockdownActivity && lockdownInfoDisplay" class="info">
+          {{ structure.lockdownActivity }}
+        </div>
+      </div>
+
+      <div
+        *ngIf="structure.accessModality.length > 0 || structure.hours.hasData() || structure.remoteAccompaniment"
+        class="structure-details-block"
+        fxLayout="column"
+      >
+        <div class="hours-services-block">
+          <!-- Opening Hours -->
+          <div *ngIf="structure.hours.hasData()" fxLayout="column">
+            <h2>Horaires</h2>
+            <div fxLayout="column" class="opening-hours">
+              <div *ngFor="let day of structure.hours | keyvalue: keepOriginalOrder">
+                <div *ngIf="day.value.open" class="opening-hour" fxLayout="row" fxLayoutAlign="flex-start flex-start">
+                  <h4 class="day">{{ day.key | day }}</h4>
+                  <div class="opening-time" fxLayout="column" fxLayoutAlign="none flex-start">
+                    <div *ngFor="let timeRange of day.value.time" class="daily-opening-time">
+                      <p *ngIf="timeRange.opening">
+                        {{ timeRange.formatOpeningDate() }} - {{ timeRange.formatClosingDate() }}
+                      </p>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <!-- services -->
+          <div *ngIf="structure.accessModality.length > 0" fxLayout="column">
+            <h2>Services</h2>
+            <div fxLayout="column" fxLayoutGap="10px" class="services-block">
+              <div fxLayout="column" fxLayoutGap="8px">
+                <div
+                  fxLayout="row"
+                  fxLayoutAlign="none flex-end"
+                  fxLayoutGap="8px"
+                  *ngFor="let acces of structure.accessModality"
+                >
+                  <p>{{ getAccessLabel(acces) }}</p>
+                </div>
+                <p *ngIf="structure.pmrAccess">Accessible aux personnes à mobilité réduite</p>
+              </div>
+              <div
+                *ngFor="let public of structure.publics"
+                fxLayout="row"
+                fxLayoutAlign="none flex-end"
+                fxLayoutGap="8px"
+              >
+                <p>{{ getPublicLabel(public) }}</p>
+              </div>
+              <div
+                *ngFor="let accompaniment of structure.publicsAccompaniment"
+                fxLayout="row"
+                fxLayoutAlign="none flex-end"
+                fxLayoutGap="8px"
+              >
+                <p>{{ accompaniment }}</p>
+              </div>
+            </div>
+          </div>
+        </div>
+        <div *ngIf="structure.exceptionalClosures" class="bold-info">
+          <p class="description">{{ structure.exceptionalClosures }}</p>
+        </div>
+        <div *ngIf="structure.remoteAccompaniment" class="bold-info">
+          <h3>Cette structure propose un accompagnement à distance.</h3>
+        </div>
+      </div>
+
+      <!-- Labellisation -->
+      <div
+        *ngIf="structure.labelsQualifications.length"
+        fxLayout="column"
+        class="structure-details-block"
+        fxLayoutAlign="baseline baseline"
+        fxLayoutGap="8px"
+      >
+        <h2>Labellisations</h2>
+        <div class="wrapper">
+          <div *ngFor="let labels of structure.labelsQualifications">
+            <app-logo-card [name]="labels"></app-logo-card>
+          </div>
+        </div>
+      </div>
+
+      <!-- Members -->
+      <div
+        *ngIf="userIsLoggedIn() && structureAdmins.length"
+        fxLayout="column"
+        class="structure-details-block"
+        fxLayoutAlign="baseline baseline"
+        fxLayoutGap="8px"
+      >
+        <h2>Membres</h2>
+        <div fxLayout="column" fxLayoutGap="8px" fxLayoutAlign="baseline baseline">
+          <div *ngFor="let member of structureAdmins" class="member-card">
+            <app-svg-icon
+              class="avatar"
+              [type]="'avatar'"
+              [icon]="'defaultAvatar'"
+              [iconClass]="'icon-40'"
+            ></app-svg-icon>
+            <div class="info-member">
+              <p class="member">{{ member.name | uppercase }} {{ member.surname | titlecase }}</p>
+              <p class="job" *ngIf="displayJobEmployer(member)">{{ displayJobEmployer(member) }}</p>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- Aides numérique -->
+      <div
+        *ngIf="structure.proceduresAccompaniment.length || structure.otherDescription"
+        fxLayout="column"
+        class="structure-details-block"
+        fxLayoutAlign="baseline baseline"
+        fxLayoutGap="12px"
+      >
+        <h2>Aides au numérique</h2>
+        <div fxLayout="column">
+          <div class="wrapper">
+            <div *ngFor="let accompagnement of structure.proceduresAccompaniment.sort()">
+              <app-logo-card *ngIf="accompagnement != 'autres'" [name]="accompagnement"></app-logo-card>
+            </div>
+          </div>
+          <p *ngIf="structure.otherDescription" fxLayout="column">
+            {{ structure.otherDescription }}
+          </p>
+        </div>
+      </div>
+
+      <!-- Formation -->
+      <div
+        *ngIf="
+          isBaseSkills() || isAccessRights() || isParentingHelp() || isSocialAndProfessional() || isDigitalSecurity()
+        "
+        fxLayout="column"
+        class="structure-details-block noSeparator"
+        fxLayoutAlign="baseline baseline"
+      >
+        <h2>Formations</h2>
+        <div *ngIf="structure.freeWorkShop">
+          <span *ngIf="multipleWorkshop()" class="bold-info">L'accès à ces formations est gratuit</span>
+          <span *ngIf="!multipleWorkshop()" class="bold-info">L'accès à cette formation est gratuit</span>
+        </div>
+        <div class="formationDetails">
+          <!--Toggle BaseSkills-->
+          <div *ngIf="isBaseSkills()" class="collapse" [ngClass]="{ notCollapsed: !showBaseSkills }">
+            <div fxLayout="column">
+              <div
+                class="collapseHeader"
+                fxLayout="row"
+                fxLayoutGap="20px"
+                fxLayoutAlign=" center"
+                (click)="toggleBaseSkills()"
+              >
+                <div class="titleCollapse">Compétences de base</div>
+                <div class="logo">
+                  <svg class="show" aria-hidden="true">
+                    <use [attr.xlink:href]="'assets/form/sprite.svg#unfold'"></use>
+                  </svg>
+                  <svg class="hide" aria-hidden="true">
+                    <use [attr.xlink:href]="'assets/form/sprite.svg#fold'"></use>
+                  </svg>
+                </div>
+              </div>
+              <div class="detailsContainer" [@show]="showBaseSkills">
+                <div class="details" *ngFor="let skill of baseSkills">{{ skill.text }}</div>
+              </div>
+            </div>
+          </div>
+          <!--Toggle accessRights-->
+          <div *ngIf="isAccessRights()" class="collapse" [ngClass]="{ notCollapsed: !showAccessRights }">
+            <div fxLayout="column">
+              <div
+                class="collapseHeader"
+                fxLayout="row"
+                fxLayoutGap="20px"
+                fxLayoutAlign=" center"
+                (click)="toggleAccessRights()"
+              >
+                <div class="titleCollapse">Accès aux droits</div>
+                <div class="logo">
+                  <svg class="show" aria-hidden="true">
+                    <use [attr.xlink:href]="'assets/form/sprite.svg#unfold'"></use>
+                  </svg>
+                  <svg class="hide" aria-hidden="true">
+                    <use [attr.xlink:href]="'assets/form/sprite.svg#fold'"></use>
+                  </svg>
+                </div>
+              </div>
+              <div class="detailsContainer" [@show]="showAccessRights">
+                <div class="details" *ngFor="let rights of accessRights">{{ rights.text }}</div>
+              </div>
+            </div>
+          </div>
+          <!--Toggle parentingHelp-->
+          <div *ngIf="isParentingHelp()" class="collapse" [ngClass]="{ notCollapsed: !showParentingHelp }">
+            <div fxLayout="column">
+              <div
+                class="collapseHeader"
+                fxLayout="row"
+                fxLayoutGap="20px"
+                fxLayoutAlign=" center"
+                (click)="toggleParentingHelp()"
+              >
+                <div class="titleCollapse">Aide à la parentalité</div>
+                <div class="logo">
+                  <svg class="show" aria-hidden="true">
+                    <use [attr.xlink:href]="'assets/form/sprite.svg#unfold'"></use>
+                  </svg>
+                  <svg class="hide" aria-hidden="true">
+                    <use [attr.xlink:href]="'assets/form/sprite.svg#fold'"></use>
+                  </svg>
+                </div>
+              </div>
+              <div class="detailsContainer" [@show]="showParentingHelp">
+                <div class="details" *ngFor="let help of parentingHelp">{{ help.text }}</div>
+              </div>
+            </div>
+          </div>
+          <!--Toggle socialAndProfessional-->
+          <div
+            *ngIf="isSocialAndProfessional()"
+            class="collapse"
+            [ngClass]="{ notCollapsed: !showSocialAndProfessional }"
+          >
+            <div fxLayout="column">
+              <div
+                class="collapseHeader"
+                fxLayout="row"
+                fxLayoutGap="20px"
+                fxLayoutAlign=" center"
+                (click)="toggleSocialAndProfessional()"
+              >
+                <div class="titleCollapse">Insertion sociale et professionnelle</div>
+                <div class="logo">
+                  <svg class="show" aria-hidden="true">
+                    <use [attr.xlink:href]="'assets/form/sprite.svg#unfold'"></use>
+                  </svg>
+                  <svg class="hide" aria-hidden="true">
+                    <use [attr.xlink:href]="'assets/form/sprite.svg#fold'"></use>
+                  </svg>
+                </div>
+              </div>
+              <div class="detailsContainer" [@show]="showSocialAndProfessional">
+                <div class="details" *ngFor="let skill of socialAndProfessional">{{ skill.text }}</div>
+              </div>
+            </div>
+          </div>
+          <!--Toggle digitalSecurity-->
+          <div *ngIf="isDigitalSecurity()" class="collapse" [ngClass]="{ notCollapsed: !showDigitalSecurity }">
+            <div fxLayout="column">
+              <div
+                class="collapseHeader"
+                fxLayout="row"
+                fxLayoutGap="20px"
+                fxLayoutAlign=" center"
+                (click)="toggleDigitalSecurity()"
+              >
+                <div class="titleCollapse">Culture et sécurité numérique</div>
+                <div class="logo">
+                  <svg class="show" aria-hidden="true">
+                    <use [attr.xlink:href]="'assets/form/sprite.svg#unfold'"></use>
+                  </svg>
+                  <svg class="hide" aria-hidden="true">
+                    <use [attr.xlink:href]="'assets/form/sprite.svg#fold'"></use>
+                  </svg>
+                </div>
+              </div>
+              <div class="detailsContainer" [@show]="showDigitalSecurity">
+                <div class="details" *ngFor="let skill of digitalCultureSecurity">{{ skill.text }}</div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- Matériel et wifi -->
+      <div
+        *ngIf="structure.hasEquipments()"
+        fxLayout="column"
+        class="structure-details-block"
+        fxLayoutAlign="baseline baseline"
+      >
+        <h2>Matériel et wifi</h2>
+        <div fxLayout="column">
+          <div *ngIf="filterOnlyEquipments(structure.equipmentsAndServices).includes('wifiEnAccesLibre')">
+            {{ getEquipmentsLabel('wifiEnAccesLibre') }}
+          </div>
+          <p *ngFor="let equipement of filterOnlyEquipments(structure.equipmentsAndServices)" class="no-margin-bottom">
+            <span *ngIf="equipement == 'ordinateurs' && structure.nbComputers"
+              >{{ getEquipmentsLabel(equipement) }} : {{ structure.nbComputers }}</span
+            >
+            <span *ngIf="equipement == 'tablettes' && structure.nbTablets"
+              >{{ getEquipmentsLabel(equipement) }} : {{ structure.nbTablets }}</span
+            >
+            <span *ngIf="equipement == 'bornesNumeriques' && structure.nbNumericTerminal">
+              {{ getEquipmentsLabel(equipement) }} : {{ structure.nbNumericTerminal }}</span
+            >
+            <span *ngIf="equipement == 'imprimantes' && structure.nbPrinters"
+              >{{ getEquipmentsLabel(equipement) }} : {{ structure.nbPrinters }}</span
+            >
+            <span *ngIf="equipement == 'scanners' && structure.nbScanners"
+              >{{ getEquipmentsLabel(equipement) }} : {{ structure.nbScanners }}</span
+            >
+          </p>
+        </div>
+      </div>
+
+      <!-- Transport -->
+      <div
+        *ngIf="tclStopPoints.length"
+        fxLayout="column"
+        class="structure-details-block noSeparator"
+        fxLayoutAlign="baseline baseline"
+      >
+        <h2>Accès</h2>
+        <div fxLayout="column wrap" fxLayoutGap="24px">
+          <div *ngFor="let tclStop of tclStopPoints | slice: 0:3">
+            {{ tclStop.name }}
+            <div fxLayout="row wrap" fxLayoutGap="16px">
+              <p *ngFor="let sub of tclStop.subLines">
+                <app-svg-icon [type]="'tcl'" [icon]="sub" [iconClass]="'icon-75'"></app-svg-icon>
+              </p>
+              <p *ngFor="let tram of tclStop.tramLines">
+                <app-svg-icon [type]="'tcl'" [icon]="tram" [iconClass]="'icon-75'"></app-svg-icon>
+              </p>
+              <p *ngFor="let bus of tclStop.busLines">
+                <app-svg-icon [type]="'tcl'" [icon]="bus" [iconClass]="'icon-75'"></app-svg-icon>
+              </p>
+            </div>
+          </div>
+        </div>
+      </div>
+      <!-- Mise à jour -->
+      <div fxLayout="column" class="structure-details-block" fxLayoutAlign="baseline baseline" fxLayoutGap="20px">
+        <div fxLayout="row" fxLayoutAlign="none flex-start" fxLayoutGap="13px">
+          <p class="updated">Mise à jour le {{ structure.updatedAt | date: 'mediumDate' }}</p>
+        </div>
+      </div>
+    </div>
+
+    <app-modal-confirmation
+      [openned]="deleteModalOpenned"
+      [content]="'Voulez-vous vraiment supprimer cette structure&nbsp;?'"
+      (closed)="deleteStructure($event)"
+    ></app-modal-confirmation>
+
+    <app-join-modal-confirmation
+      [openned]="claimModalOpenned"
+      [title]="'Travaillez-vous ici&nbsp;?'"
+      [primaryContent]="
+        'Un message sera envoyé aux administrateurs Rés\'IN pour valider l\'affectation de votre compte à la structure'
+      "
+      [secondaryContent]="structure.structureName"
+      [customConfirmationText]="'Rejoindre la structure'"
+      (closed)="claimStructure($event)"
+    ></app-join-modal-confirmation>
+
+    <app-join-modal-confirmation
+      [openned]="joinModalOpenned"
+      [title]="'Travaillez-vous ici&nbsp;?'"
+      [primaryContent]="'Un message sera envoyé à un administrateur de la structure'"
+      [secondaryContent]="structure.structureName"
+      [customConfirmationText]="'Rejoindre la structure'"
+      (closed)="joinStructure($event)"
+    ></app-join-modal-confirmation>
+
+    <app-join-modal-confirmation
+      [openned]="pendingModalOpenned"
+      [title]="'Travaillez-vous ici&nbsp;?'"
+      [primaryContent]="
+        'Un message a déjà été envoyé aux administrateurs Rés\'IN pour validation, vous recevrez un email quand votre compte sera rattaché à la structure'
+      "
+      [secondaryContent]="structure.structureName"
+      [customConfirmationText]="'OK'"
+      [displayCancelButton]="false"
+      (closed)="togglePendingModal()"
+    ></app-join-modal-confirmation>
+
+    <app-text-input-modal
+      [openned]="structureErrorModalOpenned"
+      [placeholder]="'Décrivez l\'erreur ici. Ex: Horaires faux...'"
+      [content]="
+        'Voulez-vous notifier res\'in d\'une erreur sur la fiche de cet acteur &nbsp;? Votre commentaire sera envoyé à l\'acteur en question ainsi qu\'aux administrateurs.'
+      "
+      (closed)="sendErrorEmail($event)"
+      (newContent)="sendErrorEmail($event)"
+    ></app-text-input-modal>
+  </div>
+</div>
diff --git a/src/app/structure-list/components/structure-details/structure-details.component.scss b/src/app/structure-list/components/structure-details/structure-details.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..79b7b871a907f892dca2993efc848ac047071392
--- /dev/null
+++ b/src/app/structure-list/components/structure-details/structure-details.component.scss
@@ -0,0 +1,341 @@
+@import '../../../../assets/scss/color';
+@import '../../../../assets/scss/typography';
+@import '../../../../assets/scss/breakpoint';
+@import '../../../../assets/scss/layout';
+@import '../../../../assets/scss/z-index';
+
+a {
+  padding: unset;
+  text-decoration: underline;
+  font-size: inherit;
+  font-weight: inherit;
+}
+
+p:empty {
+  margin: 0;
+}
+
+h1 {
+  @include lato-bold-20;
+  color: $grey-1;
+}
+h2 {
+  @include lato-bold-14;
+  color: $grey-3;
+  text-transform: uppercase;
+  margin-top: 0;
+  margin-bottom: 12px;
+}
+h3 {
+  @include lato-regular-16;
+  margin: 0 0 8px 0;
+}
+
+.structure-details-container {
+  position: absolute;
+  z-index: $structure-details-z-index;
+  height: calc(100vh - $header-height - 1px); // -1 is to prevent limit case
+  width: 100%;
+  background-color: $white;
+  overflow: hidden;
+  border-bottom: 1px solid $grey-5;
+  border-right: 1px solid $grey-5;
+}
+
+.structure-details-title {
+  height: 65px;
+  border-bottom: 1px solid $grey-5;
+  padding: 2px 16px 2px 24px;
+  .ico-close {
+    margin-left: auto;
+  }
+}
+
+.structure-details-content {
+  height: calc(100% - 65px);
+  padding: 0px 8px;
+  overflow-y: auto;
+  scrollbar-gutter: stable;
+  @include lato-regular-14;
+}
+
+.structure-buttons {
+  width: 100%;
+  margin: 0 0 16px 0;
+  position: relative;
+  .clickableDiv {
+    text-align: center;
+    height: 90px;
+    width: 115.2px;
+    display: flex;
+    flex-direction: column;
+    cursor: pointer;
+    .icon {
+      margin-top: 20px;
+      flex: 1;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+    }
+    .iconTitle {
+      @include lato-regular-13;
+      height: 36px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+    }
+    &:hover {
+      text-decoration: underline;
+    }
+  }
+  @media #{$tablet} {
+    .printButton {
+      display: none !important;
+    }
+  }
+}
+
+.structure-details-block {
+  margin: 0 20px;
+  padding: 24px 0;
+  border-bottom: 2px solid $grey-8;
+  &.noSeparator {
+    border-bottom: none;
+    padding-bottom: 0px;
+  }
+  .member-card {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    .avatar {
+      background-color: $grey-8;
+      border-radius: 4px;
+    }
+    .info-member {
+      margin-left: 1rem;
+      p {
+        margin: 0;
+      }
+      .member {
+        @include lato-bold-14;
+      }
+      .job {
+        @include lato-regular-14;
+      }
+    }
+  }
+
+  .info-block > div {
+    margin-top: 4px;
+    &:first-of-type {
+      margin-top: 0px;
+    }
+  }
+
+  .description {
+    white-space: pre-wrap;
+    margin-top: 8px;
+  }
+
+  .info {
+    color: $red-1;
+    margin-top: 8px;
+  }
+
+  .hours-services-block {
+    display: flex;
+    flex-direction: row;
+    & > div {
+      flex: 1;
+    }
+    @media #{$large-phone} {
+      flex-direction: column;
+    }
+
+    .opening-hours {
+      margin-bottom: 8px;
+      .opening-hour {
+        margin-bottom: 8px;
+        .day {
+          min-width: 70px;
+          margin-top: 0;
+          margin-left: 0;
+          margin-bottom: 0;
+          @include lato-regular-14;
+          color: $grey-3;
+          text-transform: capitalize;
+        }
+        .daily-opening-time {
+          p {
+            margin: 0 0 4px 0;
+          }
+        }
+      }
+    }
+  }
+
+  .services-block {
+    margin-bottom: 8px;
+    p {
+      display: list-item;
+      margin: 0 0 0 25px;
+    }
+  }
+
+  .wrapper {
+    display: grid;
+    grid-template-columns: 1fr 1fr;
+    @media #{$large-phone} {
+      grid-template-columns: 1fr;
+    }
+  }
+
+  .formationDetails {
+    width: 100%;
+    .collapse {
+      margin-bottom: 13px;
+      @media #{$small-phone} {
+        width: 95% !important;
+      }
+      &.notCollapsed {
+        border-bottom: 2px solid $grey-8;
+        .logo {
+          .hide {
+            display: none;
+          }
+          .show {
+            display: block;
+          }
+        }
+      }
+      .titleCollapse {
+        width: 100%;
+        @include lato-regular-16;
+      }
+      .collapseHeader {
+        cursor: pointer;
+      }
+      .logo {
+        height: 24px;
+        width: 24px;
+        svg {
+          width: 100%;
+          height: 100%;
+          fill: $grey-1;
+        }
+      }
+      .logo,
+      .titleCollapse {
+        .hide {
+          display: block;
+        }
+        .show {
+          display: none;
+        }
+      }
+      .detailsContainer {
+        margin: 8px 0px;
+        padding: 8px 0;
+        background-color: $grey-8;
+        overflow: hidden;
+      }
+      .details {
+        padding: 8px 16px;
+      }
+    }
+  }
+
+  .updated {
+    @include lato-regular-14;
+    color: $grey-3;
+    font-style: italic;
+  }
+}
+
+p,
+.custom-link {
+  @include lato-regular-16;
+  margin-top: 9px;
+  margin-bottom: 9px;
+  &.no-margin {
+    margin-top: unset;
+    margin-bottom: unset;
+  }
+  &.no-margin-bottom {
+    margin-bottom: unset;
+  }
+}
+.custom-link {
+  ::ng-deep svg {
+    border: 1px solid $white;
+    border-radius: 20px;
+  }
+  ::ng-deep svg:hover {
+    border-color: $grey-4;
+  }
+}
+
+.bold-info {
+  @include lato-bold-16;
+}
+
+@media print {
+  .structure-details {
+    height: unset !important;
+    overflow: hidden;
+    z-index: unset;
+    width: unset;
+    position: unset !important;
+  }
+  .structure-details-container,
+  .structure-details-content {
+    background-color: unset;
+    z-index: unset;
+    position: unset;
+    top: unset;
+    left: unset;
+    max-width: unset;
+    width: unset;
+    height: unset;
+    padding: unset;
+    overflow: hidden;
+    border-right: 0;
+  }
+
+  .hide-on-print {
+    display: none !important;
+  }
+}
+
+@keyframes fadeBackground {
+  0% {
+    background-color: $modal-background-transparent;
+  }
+  100% {
+    background-color: $modal-background;
+  }
+}
+.fullScreen {
+  width: calc(100% + 600px) !important;
+  background-color: $modal-background;
+  animation: fadeBackground 0.5s;
+  max-width: unset !important;
+  @media #{$tablet} {
+    width: 100% !important;
+  }
+}
+.structure-details {
+  position: fixed;
+  z-index: $structure-details-z-index;
+  height: calc(100vh - $header-height);
+  width: 100%;
+  max-width: 600px;
+
+  .structure-details-container {
+    max-width: 600px;
+    opacity: 1 !important;
+    @media #{$tablet} {
+      max-width: unset;
+    }
+  }
+}
diff --git a/src/app/structure-list/components/structure-details/structure-details.component.spec.ts b/src/app/structure-list/components/structure-details/structure-details.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d1e70665c38558bbc6f00435bab37ff7d5237aef
--- /dev/null
+++ b/src/app/structure-list/components/structure-details/structure-details.component.spec.ts
@@ -0,0 +1,75 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+import { Structure } from '../../../models/structure.model';
+import { AccessModality } from '../../enum/access-modality.enum';
+import { Category } from '../../models/category.model';
+import { Module } from '../../models/module.model';
+import { StructureDetailsComponent } from './structure-details.component';
+
+describe('StructureDetailsComponent', () => {
+  let component: StructureDetailsComponent;
+  let fixture: ComponentFixture<StructureDetailsComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [StructureDetailsComponent],
+      imports: [HttpClientTestingModule, RouterTestingModule],
+    }).compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(StructureDetailsComponent);
+    component = fixture.componentInstance;
+    let structure: Structure = new Structure();
+    structure.baseSkills = ['123', '234', '817'];
+    component.structure = structure;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  it('should emit close action', () => {
+    spyOn(component.closeDetails, 'emit');
+    component.close();
+    expect(component.closeDetails.emit).toHaveBeenCalled();
+    expect(component.closeDetails.emit).toHaveBeenCalledWith(true);
+  });
+
+  it('should return icon name with a string input', () => {
+    const iconNameGroup = component.getAccessIcon(AccessModality.free);
+    const iconNameCalendar = component.getAccessIcon(AccessModality.meeting);
+    const iconNameTel = component.getAccessIcon(AccessModality.numeric);
+    expect(iconNameGroup).toEqual('group');
+    expect(iconNameCalendar).toEqual('calendar');
+    expect(iconNameTel).toEqual('tel');
+  });
+
+  it('should update array with right modules', () => {
+    let baseSkillssReferentiel = new Category();
+    let accessRightsReferentiel = new Category();
+    const mo1 = new Module('132', 'Uniquement sur RDV');
+    const mo2 = new Module('145', 'Accès libre');
+    const mo3 = new Module('112', 'Téléphone / Visio');
+    const arrayModule: Module[] = [mo1, mo2, mo3];
+    const m1 = new Module('260', 'm1');
+    const m2 = new Module('259', 'm2');
+    const m3 = new Module('261', 'm3');
+    const m4 = new Module('249', 'm4');
+    const m5 = new Module('222', 'm5');
+    const arrayModuleBase: Module[] = [m1, m2, m3, m4, m5];
+    baseSkillssReferentiel.name = 'categ2';
+    baseSkillssReferentiel.modules = arrayModuleBase;
+    component.baseSkillssReferentiel = baseSkillssReferentiel;
+    accessRightsReferentiel.name = 'categ1';
+    accessRightsReferentiel.modules = arrayModule;
+    component.accessRightsReferentiel = accessRightsReferentiel;
+    component.structure.baseSkills = ['260', '261'];
+    component.structure.accessRight = ['145', '112'];
+    component.setServiceCategories();
+    expect(component.baseSkills).toEqual([m1, m3]);
+    expect(component.accessRights).toEqual([mo2, mo3]);
+  });
+});
diff --git a/src/app/structure-list/components/structure-details/structure-details.component.ts b/src/app/structure-list/components/structure-details/structure-details.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7fc9768db01d0e96a16ea666123bb449f9e39dfc
--- /dev/null
+++ b/src/app/structure-list/components/structure-details/structure-details.component.ts
@@ -0,0 +1,409 @@
+import { animate, AUTO_STYLE, state, style, transition, trigger } from '@angular/animations';
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { Location } from '@angular/common';
+import * as _ from 'lodash';
+import { ParametersService } from '../../../admin/services/parameters.service';
+import { Owner } from '../../../models/owner.model';
+import { Structure } from '../../../models/structure.model';
+import { TclStopPoint } from '../../../models/tclStopPoint.model';
+import { User } from '../../../models/user.model';
+import { ProfileService } from '../../../profile/services/profile.service';
+import { AuthService } from '../../../services/auth.service';
+import { StructureService } from '../../../services/structure.service';
+import { TclService } from '../../../services/tcl.service';
+import { PrintService } from '../../../shared/service/print.service';
+import { Utils } from '../../../utils/utils';
+import { AccessModality } from '../../enum/access-modality.enum';
+import { Equipment } from '../../enum/equipment.enum';
+import { PublicCategorie } from '../../enum/public.enum';
+import { Category } from '../../models/category.model';
+import { Module } from '../../models/module.model';
+import { SearchService } from '../../services/search.service';
+
+@Component({
+  selector: 'app-structure-details',
+  templateUrl: './structure-details.component.html',
+  styleUrls: ['./structure-details.component.scss'],
+  animations: [
+    trigger('slideInOut', [
+      transition(':enter', [style({ left: '-600px' }), animate('200ms ease-in', style({ left: '0' }))]),
+      transition(':leave', [animate('200ms ease-in', style({ left: '-600px' }))]),
+    ]),
+    trigger('fadeInOut', [
+      transition(':enter', [
+        style({ backgroundColor: 'rgb(00, 00, 00, 0)' }),
+        animate('200ms ease-in', style({ backgroundColor: 'rgb(00, 00, 00, 0.6)' })),
+      ]),
+      transition(':leave', [animate('200ms ease-in', style({ backgroundColor: 'rgb(00, 00, 00, 0)' }))]),
+    ]),
+    trigger('show', [
+      state('true', style({ height: AUTO_STYLE, visibility: AUTO_STYLE, margin: '8px 0' })),
+      state('false', style({ height: '0px', visibility: 'hidden', margin: '0' })),
+      transition('true => false', animate('300ms ease-out')),
+      transition('false => true', animate('300ms ease-out')),
+    ]),
+  ],
+})
+export class StructureDetailsComponent implements OnInit {
+  @Input() public structure: Structure;
+  @Output() public closeDetails: EventEmitter<boolean> = new EventEmitter<boolean>();
+  public accessModality = AccessModality;
+
+  public baseSkillssReferentiel: Category;
+  public accessRightsReferentiel: Category;
+  public digitalCultureSecuritysReferentiel: Category;
+  public socialAndProfessionalsReferentiel: Category;
+  public parentingHelpsReferentiel: Category;
+  public baseSkills: Module[];
+  public accessRights: Module[];
+  public parentingHelp: Module[];
+  public socialAndProfessional: Module[];
+  public digitalCultureSecurity: Module[];
+  public showBaseSkills = false;
+  public showAccessRights = false;
+  public showParentingHelp = false;
+  public showSocialAndProfessional = false;
+  public showDigitalSecurity = false;
+  public tclStopPoints: TclStopPoint[] = [];
+  public printMode = false;
+  public isLoading = true;
+  public lockdownInfoDisplay = false;
+  public currentProfile: User = null;
+  public deleteModalOpenned = false;
+  public structureErrorModalOpenned = false;
+  public claimModalOpenned: boolean;
+  public joinModalOpenned = false;
+  public pendingModalOpenned = false;
+  public structureAdmins: Owner[] = [];
+  public fullScreen = false;
+
+  constructor(
+    private printService: PrintService,
+    private searchService: SearchService,
+    private structureService: StructureService,
+    private tclService: TclService,
+    private profileService: ProfileService,
+    private authService: AuthService,
+    private route: ActivatedRoute,
+    private parametersService: ParametersService,
+    private location: Location,
+    private router: Router
+  ) {
+    this.route.url.subscribe((url) => {
+      if (url.length > 0 && url[0].path === 'structure') {
+        this.structure = new Structure(this.printService.structure);
+        this.printMode = true;
+        // Display formations for printing
+        this.toggleAccessRights();
+        this.toggleBaseSkills();
+        this.toggleDigitalSecurity();
+        this.toggleParentingHelp();
+        this.toggleSocialAndProfessional();
+        this.initForm();
+      }
+    });
+    this.parametersService.getParameters().subscribe((params) => {
+      this.lockdownInfoDisplay = params.lockdownInfoDisplay;
+    });
+  }
+
+  async ngOnInit(): Promise<void> {
+    this.route.queryParams.subscribe((queryParams) => {
+      if (queryParams.id) {
+        this.structureService.getStructure(queryParams.id).subscribe((structure) => {
+          this.structure = new Structure(structure);
+          this.initForm();
+        });
+      } else if (!this.printMode) {
+        this.structure = null;
+      }
+    });
+    this.route.data.subscribe((data) => {
+      if (data.fullScreen) {
+        this.fullScreen = true;
+      }
+    });
+  }
+
+  private async initForm(): Promise<void> {
+    if (this.userIsLoggedIn()) {
+      this.currentProfile = await this.profileService.getProfile();
+      this.structureService.getStructureWithOwners(this.structure._id, this.currentProfile).subscribe((res) => {
+        this.structureAdmins = res.owners;
+      });
+    }
+    this.structure.isClaimed = await this.structureService
+      .isClaimed(this.structure._id, this.currentProfile)
+      .toPromise();
+
+    // GetTclStopPoints
+    this.getTclStopPoints();
+    this.searchService.getCategoriesTraining().subscribe((referentiels) => {
+      referentiels.forEach((referentiel) => {
+        if (referentiel.isBaseSkills()) {
+          this.baseSkillssReferentiel = referentiel;
+        } else if (referentiel.isRigthtsAccess()) {
+          this.accessRightsReferentiel = referentiel;
+        } else if (referentiel.isDigitalCultureSecurity()) {
+          this.digitalCultureSecuritysReferentiel = referentiel;
+        } else if (referentiel.isParentingHelp()) {
+          this.parentingHelpsReferentiel = referentiel;
+        } else if (referentiel.isSocialAndProfessional()) {
+          this.socialAndProfessionalsReferentiel = referentiel;
+        }
+      });
+      this.setServiceCategories();
+      if (this.printMode) {
+        this.printService.onDataReady();
+      }
+      this.isLoading = false;
+    });
+    const index = this.structure.proceduresAccompaniment.indexOf('autres');
+    if (index > -1) {
+      this.structure.proceduresAccompaniment.splice(index, 1);
+    }
+  }
+
+  public userIsLoggedIn(): boolean {
+    return this.authService.isLoggedIn();
+  }
+
+  public getEquipmentsLabel(equipment: Equipment): string {
+    switch (equipment) {
+      case Equipment.wifi:
+        return 'Wifi en accès libre';
+      case Equipment.bornes:
+        return this.structure.nbNumericTerminal > 1 ? 'Bornes numériques' : 'Borne numérique';
+      case Equipment.printer:
+        return this.structure.nbPrinters > 1 ? 'Imprimantes' : 'Imprimante';
+      case Equipment.tablet:
+        return this.structure.nbTablets > 1 ? 'Tablettes' : 'Tablette';
+      case Equipment.computer:
+        return this.structure.nbComputers > 1 ? 'Ordinateurs' : 'Ordinateur';
+      case Equipment.scanner:
+        return this.structure.nbScanners > 1 ? 'Scanners' : 'Scanner';
+      default:
+        return null;
+    }
+  }
+
+  public close(): void {
+    this.route.url.subscribe((urls) => {
+      if (urls.length > 0 && urls[0].path !== 'orientation') {
+        this.router.navigate(['/acteurs'], {
+          relativeTo: this.route,
+          queryParams: {
+            id: null,
+          },
+          queryParamsHandling: 'merge',
+        });
+      } else {
+        this.isLoading = true;
+        this.location.back();
+      }
+    });
+  }
+
+  public print(): void {
+    this.printService.printDocument('structure', this.structure);
+  }
+
+  public toggleDeleteModal(): void {
+    this.deleteModalOpenned = !this.deleteModalOpenned;
+  }
+
+  public toggleClaimModal(): void {
+    this.claimModalOpenned = !this.claimModalOpenned;
+  }
+
+  public toggleJoinModal(): void {
+    this.joinModalOpenned = !this.joinModalOpenned;
+  }
+
+  public togglePendingModal(): void {
+    this.pendingModalOpenned = !this.pendingModalOpenned;
+  }
+
+  public handleJoin(): void {
+    if (this.userIsLoggedIn()) {
+      if (this.structure.isClaimed) {
+        if (this.profileService.isPendingLinkedToStructure(this.structure._id)) {
+          this.togglePendingModal();
+        } else {
+          this.toggleJoinModal();
+        }
+      } else {
+        this.toggleClaimModal();
+      }
+    } else {
+      this.router.navigate(['login'], { queryParams: { returnUrl: `acteurs?id=${this.structure._id}` } });
+    }
+  }
+  public handleModify(): void {
+    this.router.navigateByUrl(`/profile/edit-structure/${this.structure._id}`);
+  }
+
+  public deleteStructure(shouldDelete: boolean): void {
+    this.toggleDeleteModal();
+    if (shouldDelete) {
+      this.structureService.delete(this.structure._id).subscribe((res) => {
+        this.reload();
+      });
+    }
+  }
+
+  private reload(): void {
+    this.router.routeReuseStrategy.shouldReuseRoute = () => false;
+    this.router.onSameUrlNavigation = 'reload';
+    this.router.navigate(['./'], { relativeTo: this.route });
+  }
+
+  public claimStructure(shouldClaim: boolean): void {
+    this.toggleClaimModal();
+    if (shouldClaim) {
+      this.structureService
+        .claimStructureWithAccount(this.structure._id, this.authService.userValue.username)
+        .subscribe();
+      this.router.navigate(['join', this.structure._id], { state: { isClaimed: this.structure.isClaimed } });
+    }
+  }
+
+  public joinStructure(shouldJoin: boolean): void {
+    this.toggleJoinModal();
+    if (shouldJoin) {
+      this.structureService.joinStructure(this.structure._id, this.authService.userValue.username).subscribe();
+      this.router.navigate(['join', this.structure._id], { state: { isClaimed: this.structure.isClaimed } });
+    }
+  }
+
+  public getAccessLabel(accessModality: AccessModality): string {
+    switch (accessModality) {
+      case AccessModality.free:
+        return 'Accès libre';
+      case AccessModality.meeting:
+        return 'Sur rendez-vous';
+      case AccessModality.meetingOnly:
+        return 'Uniquement sur RDV';
+      case AccessModality.numeric:
+        return 'Téléphone / Visio';
+      default:
+        return null;
+    }
+  }
+
+  public getPublicLabel(tagetPublic: PublicCategorie): string {
+    switch (tagetPublic) {
+      case PublicCategorie.young:
+        return 'Jeunes (16 - 25 ans)';
+      case PublicCategorie.adult:
+        return 'Adultes';
+      case PublicCategorie.elderly:
+        return 'Séniors (+ de 65 ans)';
+      case PublicCategorie.all:
+        return 'Tout public';
+      case PublicCategorie.under16Years:
+        return 'Moins de 16 ans';
+      case PublicCategorie.women:
+        return 'Uniquement femmes';
+      default:
+        return null;
+    }
+  }
+
+  public setServiceCategories(): void {
+    this.baseSkills = this.structure.baseSkills.map((skill) =>
+      _.find(this.baseSkillssReferentiel.modules, { id: skill })
+    );
+    this.accessRights = this.structure.accessRight.map((rights) =>
+      _.find(this.accessRightsReferentiel.modules, { id: rights })
+    );
+    this.parentingHelp = this.structure.parentingHelp.map((help) =>
+      _.find(this.parentingHelpsReferentiel.modules, { id: help })
+    );
+    this.socialAndProfessional = this.structure.socialAndProfessional.map((skill) =>
+      _.find(this.socialAndProfessionalsReferentiel.modules, { id: skill })
+    );
+    this.digitalCultureSecurity = this.structure.digitalCultureSecurity.map((skill) =>
+      _.find(this.digitalCultureSecuritysReferentiel.modules, { id: skill })
+    );
+  }
+
+  public keepOriginalOrder = (a, b) => a.key;
+
+  public isBaseSkills(): boolean {
+    return this.baseSkills && this.baseSkills[0] !== undefined;
+  }
+  public isAccessRights(): boolean {
+    return this.accessRights && this.accessRights[0] !== undefined;
+  }
+  public isParentingHelp(): boolean {
+    return this.parentingHelp && this.parentingHelp[0] !== undefined;
+  }
+  public isSocialAndProfessional(): boolean {
+    return this.socialAndProfessional && this.socialAndProfessional[0] !== undefined;
+  }
+  public isDigitalSecurity(): boolean {
+    return this.digitalCultureSecurity && this.digitalCultureSecurity[0] !== undefined;
+  }
+
+  public getTclStopPoints(): void {
+    this.tclService.getTclStopPointBycoord(this.structure.getLon(), this.structure.getLat()).subscribe((res) => {
+      this.tclStopPoints = res;
+    });
+  }
+
+  public filterOnlyEquipments(equipmentsAndServices: string[]): string[] {
+    return equipmentsAndServices.filter((eqpt) =>
+      ['ordinateurs', 'tablettes', 'bornesNumeriques', 'imprimantes', 'scanners', 'wifiEnAccesLibre'].includes(eqpt)
+    );
+  }
+
+  public displayModalError(): void {
+    this.structureErrorModalOpenned = !this.structureErrorModalOpenned;
+  }
+
+  public sendErrorEmail(modalValue: any): void {
+    this.displayModalError();
+    if (modalValue.shouldSend) {
+      this.structureService.sendMailOnStructureError(this.structure._id, modalValue.content).subscribe(() => {});
+    }
+  }
+
+  public multipleWorkshop(): boolean {
+    if (
+      this.structure.baseSkills.length +
+        this.structure.accessRight.length +
+        this.structure.parentingHelp.length +
+        this.structure.socialAndProfessional.length +
+        this.structure.digitalCultureSecurity.length >
+      1
+    ) {
+      return true;
+    }
+    return false;
+  }
+
+  public toggleBaseSkills(): void {
+    this.showBaseSkills = !this.showBaseSkills;
+  }
+  public toggleAccessRights(): void {
+    this.showAccessRights = !this.showAccessRights;
+  }
+  public toggleParentingHelp(): void {
+    this.showParentingHelp = !this.showParentingHelp;
+  }
+  public toggleSocialAndProfessional(): void {
+    this.showSocialAndProfessional = !this.showSocialAndProfessional;
+  }
+  public toggleDigitalSecurity(): void {
+    this.showDigitalSecurity = !this.showDigitalSecurity;
+  }
+
+  public goToWebsite(): void {
+    window.open(this.structure.website, '_blank');
+  }
+  public displayJobEmployer(profile: User): string {
+    return new Utils().getJobEmployer(profile);
+  }
+}
diff --git a/src/app/structure-list/components/structure-list-search/structure-list-search.component.html b/src/app/structure-list/components/structure-list-search/structure-list-search.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..f73769ce693f3d75ff9126a24df29d26242895c5
--- /dev/null
+++ b/src/app/structure-list/components/structure-list-search/structure-list-search.component.html
@@ -0,0 +1,167 @@
+<div class="block">
+  <div class="content">
+    <form
+      class="inputSearch"
+      [formGroup]="searchForm"
+      fxLayout="row"
+      fxLayoutGap="4px"
+      fxLayoutAlign=" center"
+      (ngSubmit)="applyFilter(searchForm.value.searchTerm)"
+    >
+      <div fxLayout="row" fxLayoutAlign="space-between center" class="container">
+        <input type="text" formControlName="searchTerm" placeholder="Rechercher une association, une commune..." />
+        <button
+          *ngIf="this.searchForm.get('searchTerm').value?.length > 0"
+          (click)="clearInput()"
+          class="icon close"
+          type="button"
+        >
+          <div class="ico-close-search"></div>
+        </button>
+        <span *ngIf="this.searchForm.get('searchTerm').value?.length > 0" class="separation"></span>
+        <app-button [style]="buttonTypeEnum.searchIcon" [iconBtn]="'search'" [type]="'submit'"></app-button>
+      </div>
+    </form>
+    <div (clickOutside)="closeModal()" class="btn-container">
+      <div class="btnSection" fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="4px">
+        <button
+          class="btn-filter isntPhoneContent"
+          type="button"
+          fxLayout="row"
+          [ngClass]="{
+            selected: modalTypeOpened === TypeModal.accompaniment,
+            containCheckedFilters: numberAccompanimentChecked
+          }"
+          fxLayoutAlign="space-between center"
+          (click)="openModal(TypeModal.accompaniment)"
+        >
+          <span>Aide numérique</span>
+          <div class="arrow"></div>
+        </button>
+        <button
+          class="btn-filter isntPhoneContent"
+          type="button"
+          fxLayout="row"
+          [ngClass]="{
+            selected: modalTypeOpened === TypeModal.training,
+            containCheckedFilters: numberTrainingChecked
+          }"
+          fxLayoutAlign="space-between center"
+          (click)="openModal(TypeModal.training)"
+        >
+          <span>Ateliers</span>
+          <div class="arrow"></div>
+        </button>
+        <button
+          class="btn-filter isntPhoneContent"
+          type="button"
+          fxLayout="row"
+          [ngClass]="{
+            selected: modalTypeOpened === TypeModal.public,
+            containCheckedFilters: numberPublicChecked
+          }"
+          fxLayoutAlign="space-between center"
+          (click)="openModal(TypeModal.public)"
+        >
+          <span>Public</span>
+          <div class="arrow"></div>
+        </button>
+        <button
+          class="btn-filter isntPhoneContent"
+          type="button"
+          fxLayout="row"
+          [ngClass]="{
+            selected: modalTypeOpened === TypeModal.equipments,
+            containCheckedFilters: numberEquipmentChecked
+          }"
+          fxLayoutAlign="space-between center"
+          (click)="openModal(TypeModal.equipments)"
+        >
+          <span>Matériel et wifi</span>
+          <div class="arrow"></div>
+        </button>
+        <div
+          class="checkboxButton"
+          [ngClass]="{
+            checked: searchService.getIndex(checkedModulesFilter, 'passNumerique', 'labelsQualifications') > -1
+          }"
+        >
+          <label fxLayout="row" fxLayoutAlign="center center">
+            <input
+              type="checkbox"
+              value="passNumerique"
+              [checked]="searchService.getIndex(checkedModulesFilter, 'passNumerique', 'labelsQualifications') > -1"
+              (change)="externalCheckboxCheck($event, 'labelsQualifications', 'Pass numérique')"
+            />
+            <div class="label pass">Pass numérique</div>
+          </label>
+        </div>
+        <div
+          class="checkboxButton"
+          [ngClass]="{
+            checked:
+              searchService.getIndex(checkedModulesFilter, 'conseillerNumFranceServices', 'labelsQualifications') > -1
+          }"
+        >
+          <label fxLayout="row" fxLayoutAlign="center center">
+            <input
+              type="checkbox"
+              value="conseillerNumFranceServices"
+              [checked]="
+                searchService.getIndex(checkedModulesFilter, 'conseillerNumFranceServices', 'labelsQualifications') > -1
+              "
+              (change)="externalCheckboxCheck($event, 'labelsQualifications', 'Conseillers numériques')"
+            />
+            <div class="label pass">Conseillers numériques</div>
+          </label>
+        </div>
+        <div
+          class="checkboxButton isntPhoneContent"
+          [ngClass]="{
+            checked: searchService.getIndex(checkedModulesFilter, 'accesLibre', 'accessModality') > -1
+          }"
+        >
+          <label fxLayout="row" fxLayoutAlign="center center">
+            <input
+              type="checkbox"
+              value="accesLibre"
+              [checked]="searchService.getIndex(checkedModulesFilter, 'accesLibre', 'accessModality') > -1"
+              (change)="externalCheckboxCheck($event, 'accessModality', 'Accès libre')"
+            />
+            <div class="label pass">Accès libre</div>
+          </label>
+        </div>
+        <app-button
+          class="isntPhoneContent last-button"
+          [style]="buttonTypeEnum.Tertiary"
+          [text]="'Plus de filtres'"
+          fxLayout="row"
+          fxLayoutAlign="space-between center"
+          (action)="openModal(TypeModal.moreFilters)"
+        ></app-button>
+        <div *ngIf="modalTypeOpened">
+          <app-modal-filter
+            [modalType]="modalTypeOpened"
+            [categories]="getModalCategory()"
+            [modules]="checkedModulesFilter"
+            (searchEvent)="fetchResults($event)"
+            (closeEvent)="closeModal()"
+          ></app-modal-filter>
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <div *ngIf="checkedModulesFilter.length" fxLayout="row wrap" fxLayoutGap="4px" class="filterTags isntPhoneContent">
+    <div class="title">Filtres :</div>
+    <app-button
+      *ngFor="let filter of checkedModulesFilter"
+      [style]="buttonTypeEnum.TagCloudButton"
+      [text]="filter.displayText ? filter.displayText : filter.id"
+      (action)="removeFilter(filter)"
+    ></app-button>
+    <div class="reset-icon" (click)="resetFilters()">
+      <app-svg-icon [type]="'ico'" [icon]="'tagReset'" [iconColor]="'black'"></app-svg-icon>
+    </div>
+  </div>
+</div>
diff --git a/src/app/structure-list/components/structure-list-search/structure-list-search.component.scss b/src/app/structure-list/components/structure-list-search/structure-list-search.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..6b0c60d2b63c2553059431d7f6d14d3959a4d88a
--- /dev/null
+++ b/src/app/structure-list/components/structure-list-search/structure-list-search.component.scss
@@ -0,0 +1,258 @@
+@import '../../../../assets/scss/color';
+@import '../../../../assets/scss/typography';
+@import '../../../../assets/scss/inputs';
+@import '../../../../assets/scss/hyperlink';
+@import '../../../../assets/scss/breakpoint';
+@import '../../../../assets/scss/buttons';
+
+.block {
+  padding: 0 0.5rem;
+  border-bottom: solid 1px $grey-4;
+  @media #{$large-tablet} {
+    padding: 0 10px;
+  }
+}
+.content {
+  margin-bottom: 0.5rem;
+  display: flex;
+  align-items: center;
+
+  input {
+    @include lato-regular-13;
+    @include input-search;
+    margin-top: unset;
+  }
+  .inputSearch {
+    padding: 6px 10px 6px 6px;
+    width: 200px;
+    min-width: 200px;
+    background-color: $grey-8;
+    color: $grey-3;
+    height: 36px;
+    border-radius: 50px;
+    margin-right: 0.25rem;
+    @media #{$large-desktop} {
+      width: 300px;
+      min-width: 250px;
+    }
+    @media #{$large-tablet} {
+      width: 100%;
+      margin-bottom: 0.5rem;
+      margin-right: 0;
+    }
+    .container {
+      width: 100%;
+      height: 40px;
+      .separation {
+        border-right: solid 1px $grey-4;
+        width: 5px;
+        height: 23px;
+        margin-right: 5px;
+      }
+    }
+  }
+  @media #{$large-tablet} {
+    flex-direction: column !important;
+  }
+}
+.btn-container {
+  width: 100%;
+  display: flex;
+}
+.btnSection {
+  width: 100%;
+  @media #{$large-tablet} {
+    display: contents !important;
+  }
+  button {
+    background: $white;
+    height: 36px;
+    border: 1px solid $grey-4;
+    padding: 10px 12px;
+    outline: none;
+    border-radius: 50px;
+    cursor: pointer;
+    text-align: left;
+    transition: all 300ms ease;
+    line-height: 110%;
+    @include btn-normal;
+    @include lato-regular-13;
+    &:hover:not(.selected) {
+      background: $grey-7;
+    }
+    .arrow {
+      background-color: transparent;
+      border-bottom: 1px solid black;
+      border-right: 1px solid black;
+      transform: translateY(-25%) rotate(45deg);
+      margin: 0 5px 0 10px;
+      height: 7px;
+      width: 7px;
+      transition: all 300ms ease;
+    }
+    &:focus {
+      border-color: $focus-color;
+    }
+  }
+  .selected {
+    background-color: $primary-color;
+    border-color: $primary-color !important;
+    color: $white;
+    .arrow {
+      background-color: transparent;
+      border-bottom: 1px solid $white;
+      border-right: 1px solid $white;
+      transform: translateY(25%) rotate(-135deg);
+      margin: 0 5px 0 10px;
+      height: 7px;
+      width: 7px;
+    }
+  }
+  .btn-filter {
+    height: 40px;
+    span {
+      line-height: 110%;
+    }
+  }
+  .containCheckedFilters {
+    border-color: $primary-color;
+  }
+  .checkboxButton {
+    box-sizing: border-box;
+    @include btn-filter;
+    width: auto;
+    border-radius: 50px;
+    padding: 0px 10px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    transition: all 300ms ease;
+    @include lato-regular-13;
+    line-height: 110%;
+    @media #{$large-tablet} {
+      width: max-content;
+    }
+
+    &.checked {
+      border-color: $primary-color;
+      background: $primary-color-light;
+    }
+    &:hover:not(.checked) {
+      background: $grey-8;
+    }
+    label {
+      cursor: pointer;
+      font-size: inherit;
+      font-weight: inherit;
+    }
+    input[type='checkbox'] {
+      appearance: none;
+      border-radius: 50%;
+      width: 20px;
+      min-width: 20px;
+      height: 20px;
+      border: solid 1px $grey-4;
+      background: white;
+      margin: 0;
+      margin-right: 5px;
+      transition: all 300ms ease;
+      position: relative;
+
+      &:checked {
+        background: $primary-color;
+        border: none;
+        &:after {
+          border-bottom: 2px solid white;
+          border-left: 2px solid white;
+          content: '';
+          height: 4px;
+          left: 4px;
+          opacity: 1;
+          position: absolute;
+          top: 6px;
+          transform: rotate(-45deg);
+          width: 10px;
+        }
+      }
+    }
+  }
+}
+::ng-deep .btn-regular.tertiary {
+  height: 40px !important;
+  div {
+    line-height: normal;
+  }
+}
+.last-button {
+  margin-left: auto;
+}
+.footerSearchSection {
+  margin: 8px 0px 8px 0px;
+  height: 40px;
+}
+
+.icon {
+  background-color: transparent;
+  border: 1px solid transparent;
+  outline: none;
+  cursor: pointer;
+  &.pin {
+    padding: 4px 6px 8px 6px;
+    &:hover {
+      .ico-pin-search {
+        background-color: $primary-color;
+      }
+    }
+    &:focus {
+      border-color: $primary-color;
+      .ico-pin-search {
+        background-color: $primary-color;
+      }
+    }
+    &:active {
+      border-color: transparent;
+      .ico-pin-search {
+        background-color: $blue-light;
+      }
+    }
+  }
+  &.close {
+    &:focus {
+      border-color: $primary-color;
+    }
+    &:active {
+      border-color: transparent;
+    }
+  }
+}
+a {
+  @include hyperlink;
+  text-align: right;
+}
+
+.phoneSection {
+  margin: 9px 0px 18px 0px;
+  display: none;
+  .btnSection {
+    padding: 0;
+  }
+}
+@media #{$large-tablet} {
+  .isntPhoneContent {
+    display: none !important;
+  }
+  .phoneSection {
+    display: block;
+  }
+}
+.filterTags {
+  margin: 0.5rem 0 0 0;
+  .title {
+    margin-top: 5px;
+    color: $grey-3;
+  }
+  .reset-icon {
+    padding-top: 0.2rem;
+    cursor: pointer;
+  }
+}
diff --git a/src/app/structure-list/components/structure-list-search/structure-list-search.component.spec.ts b/src/app/structure-list/components/structure-list-search/structure-list-search.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1cac4adfa66f31be62dfaf480b0d3a1643612953
--- /dev/null
+++ b/src/app/structure-list/components/structure-list-search/structure-list-search.component.spec.ts
@@ -0,0 +1,149 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { of } from 'rxjs';
+import { GeoJson } from '../../../map/models/geojson.model';
+import { GeojsonService } from '../../../services/geojson.service';
+import { TypeModal } from '../../enum/typeModal.enum';
+import { Filter } from '../../models/filter.model';
+import { Module } from '../../models/module.model';
+import { StructureListSearchComponent } from './structure-list-search.component';
+
+describe('StructureListSearchComponent', () => {
+  let component: StructureListSearchComponent;
+  let fixture: ComponentFixture<StructureListSearchComponent>;
+  let geoService: GeojsonService;
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [StructureListSearchComponent],
+      imports: [HttpClientTestingModule, ReactiveFormsModule],
+    }).compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(StructureListSearchComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+    geoService = TestBed.inject(GeojsonService);
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  // applyFilter function
+  it('should emit filters', () => {
+    const filter: Filter[] = [new Filter('query', 'valInput')];
+    spyOn(component.searchEvent, 'emit');
+    component.applyFilter('valInput');
+    expect(component.searchEvent.emit).toHaveBeenCalled();
+    expect(component.searchEvent.emit).toHaveBeenCalledWith(filter);
+  });
+
+  // countCheckFiltersOnModules function
+  it('should return a number of checked elements in an array', () => {
+    const checkedModules: Module[] = [
+      { id: '176', text: 'training', count: 0 },
+      { id: '173', text: 'training', count: 0 },
+      { id: '172', text: 'training', count: 0 },
+    ];
+
+    const nbCheckedElements: number = component.countCheckFiltersOnModules(checkedModules, 2);
+    expect(nbCheckedElements).toEqual(1);
+  });
+  it('should return 0 of checked elements in an array', () => {
+    const checkedModules: Module[] = [
+      { id: '176', text: 'training', count: 0 },
+      { id: '173', text: 'training', count: 0 },
+      { id: '172', text: 'training', count: 0 },
+    ];
+
+    const nbCheckedElements: number = component.countCheckFiltersOnModules(checkedModules, 3);
+    expect(nbCheckedElements).toEqual(0);
+  });
+
+  // fetchResults function
+  it('should update number of checked elements in current filter', () => {
+    const checkedModules: Module[] = [
+      { id: '176', text: 'training', count: 0 },
+      { id: '173', text: 'accompaniment', count: 0 },
+      { id: '172', text: 'accompaniment', count: 0 },
+      { id: '180', text: 'moreFilters', count: 0 },
+      { id: '130', text: 'moreFilters', count: 0 },
+      { id: '219', text: 'moreFilters', count: 0 },
+    ];
+    component.modalTypeOpened = TypeModal.training;
+    component.numberAccompanimentChecked = 2;
+    component.numberMoreFiltersChecked = 3;
+    component.fetchResults(checkedModules);
+    expect(component.numberTrainingChecked).toEqual(1);
+  });
+  // openModal function
+  it('should open modal', () => {
+    component.openModal(TypeModal.training);
+    expect(component.modalTypeOpened).toEqual(TypeModal.training);
+  });
+  // closeModal function
+  it('should close modal', () => {
+    component.modalTypeOpened = TypeModal.training;
+    component.closeModal();
+    expect(component.modalTypeOpened).toBeUndefined();
+  });
+  // externalCheckboxCheck function
+  it('should add numericPass filter to array of current filters and increment by one number of moreFilters element', () => {
+    const evt = { target: { checked: true, value: 'Pass numérique' } };
+    const categ = 'Labels et qualifications';
+    component.externalCheckboxCheck(evt, categ);
+    const expectArray: Module[] = [new Module(evt.target.value, categ)];
+    expect(component.checkedModulesFilter).toEqual(expectArray);
+    expect(component.numberMoreFiltersChecked).toEqual(1);
+  });
+  it('should remove conseillerNumFranceServices filter to array of current filters and increment by one number of moreFilters element', () => {
+    const evt = { target: { checked: false, value: 'Conseiller numérique' } };
+    const categ = 'Labels et qualifications';
+    const checkedModules: Module[] = [{ id: evt.target.value, text: categ, count: 0 }];
+    component.checkedModulesFilter = checkedModules;
+    component.externalCheckboxCheck(evt, categ);
+    expect(component.checkedModulesFilter.length).toEqual(0);
+    expect(component.numberMoreFiltersChecked).toEqual(0);
+  });
+  it('should add conseillerNumFranceServices filter to array of current filters and increment by one number of moreFilters element', () => {
+    const evt = { target: { checked: true, value: 'Conseiller numérique' } };
+    const categ = 'Labels et qualifications';
+    component.externalCheckboxCheck(evt, categ);
+    const expectArray: Module[] = [new Module(evt.target.value, categ)];
+    expect(component.checkedModulesFilter).toEqual(expectArray);
+    expect(component.numberMoreFiltersChecked).toEqual(1);
+  });
+  it('should remove numericPass filter to array of current filters and increment by one number of moreFilters element', () => {
+    const evt = { target: { checked: false, value: 'Pass numérique' } };
+    const categ = 'Labels et qualifications';
+    const checkedModules: Module[] = [{ id: evt.target.value, text: categ, count: 0 }];
+    component.checkedModulesFilter = checkedModules;
+    component.externalCheckboxCheck(evt, categ);
+    expect(component.checkedModulesFilter.length).toEqual(0);
+    expect(component.numberMoreFiltersChecked).toEqual(0);
+  });
+  // learInput function
+  it('should reset form', () => {
+    component.searchForm.setValue({ searchTerm: 'someSearchTerm' });
+    component.clearInput();
+    expect(component.searchForm.get('searchTerm').value).toBeNull();
+  });
+  // locateMe function
+  it('should update form with the correct address ', () => {
+    let fakeGeo: GeoJson = new GeoJson({ properties: { name: 'Rue du lac' } });
+
+    spyOn(navigator.geolocation, 'getCurrentPosition').and.callFake(function () {
+      var position = { coords: { latitude: 45.7585243, longitude: 4.85442 } };
+      arguments[0](position);
+    });
+    spyOn(geoService, 'getAddressByCoord').and.callFake(function () {
+      return of(fakeGeo);
+    });
+    component.locateMe();
+    expect(navigator.geolocation.getCurrentPosition).toHaveBeenCalled();
+    expect(geoService.getAddressByCoord).toHaveBeenCalled();
+    expect(component.searchForm.get('searchTerm').value).toBe('Rue du lac');
+  });
+});
diff --git a/src/app/structure-list/components/structure-list-search/structure-list-search.component.ts b/src/app/structure-list/components/structure-list-search/structure-list-search.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fafe341d5c9efaf8495ef5e2b8f8f1b47dcf81a1
--- /dev/null
+++ b/src/app/structure-list/components/structure-list-search/structure-list-search.component.ts
@@ -0,0 +1,249 @@
+import { Component, EventEmitter, OnInit, Output } from '@angular/core';
+import { FormBuilder, FormGroup } from '@angular/forms';
+import { ActivatedRoute, Router } from '@angular/router';
+import { ButtonType } from '../../../shared/components/button/buttonType.enum';
+import { TypeModal } from '../../enum/typeModal.enum';
+import { Category } from '../../models/category.model';
+import { Filter } from '../../models/filter.model';
+import { Module } from '../../models/module.model';
+import { SearchService } from '../../services/search.service';
+
+@Component({
+  selector: 'app-structure-list-search',
+  templateUrl: './structure-list-search.component.html',
+  styleUrls: ['./structure-list-search.component.scss'],
+})
+export class StructureListSearchComponent implements OnInit {
+  @Output() searchEvent = new EventEmitter();
+  public locate = false;
+  // Show/hide form createStructure
+  public addStructureFormModal = false;
+  public buttonTypeEnum = ButtonType;
+
+  // Form search input
+  public searchForm: FormGroup;
+  public modalTypeOpened: TypeModal;
+  // Checkbox variable
+  public checkedModulesFilter: Module[];
+
+  public numberTrainingChecked = 0;
+  public numberAccompanimentChecked = 0;
+  public numberPublicChecked = 0;
+  public numberEquipmentChecked = 0;
+  public numberMoreFiltersChecked = 0;
+
+  // Modal categories
+  public categoriesTraining: Category[] = [];
+  public categoriesAccompaniment: Category[] = [];
+  public categoriesPublic: Category[] = [];
+  public categoriesEquipment: Category[] = [];
+  public categoriesMoreFilters: Category[] = [];
+
+  public queryString: string;
+  // Modal confirmation variable
+  public isConfirmationModalOpen = false;
+  public confirmationModalContent =
+    'Afin d’ajouter votre structure,vous allez être redirigé vers le formulaire Grand Lyon à remplir.';
+
+  constructor(
+    public searchService: SearchService,
+    private fb: FormBuilder,
+    private activatedRoute: ActivatedRoute,
+    private route: ActivatedRoute,
+    private router: Router
+  ) {
+    this.searchForm = this.fb.group({
+      searchTerm: this.activatedRoute.snapshot.queryParamMap.get('search')
+        ? this.activatedRoute.snapshot.queryParamMap.get('search')
+        : '',
+    });
+  }
+  ngOnInit(): void {
+    // Will store the different categories
+    this.getData();
+    this.queryString = this.activatedRoute.snapshot.queryParamMap.get('search');
+    this.checkedModulesFilter = new Array();
+    if (this.queryString) {
+      const filters: Filter[] = [];
+      filters.push(new Filter('query', this.queryString));
+      this.searchEvent.emit(filters);
+    }
+  }
+
+  public convertModulesTofilters(modules: Module[], term?: string): Filter[] {
+    const filters: Filter[] = [];
+    if (term) {
+      filters.push(new Filter('query', term));
+    }
+    // Add checked box filter
+    modules.forEach((cm) => {
+      filters.push(new Filter(cm.text, cm.id, cm.displayText));
+    });
+    return filters;
+  }
+
+  // Accessor to template angular.
+  public get TypeModal(): typeof TypeModal {
+    return TypeModal;
+  }
+
+  // Clear input search
+  public clearInput(): void {
+    this.searchForm.reset();
+    this.applyFilter(null);
+  }
+
+  // Sends an array containing all filters
+  public applyFilter(term: string): void {
+    // Add search input filter
+    if (term) {
+      this.router.navigate(['/acteurs'], {
+        relativeTo: this.route,
+        queryParams: {
+          search: term,
+        },
+        queryParamsHandling: 'merge',
+      });
+    } else if (!term) {
+      this.router.navigate(['/acteurs'], {
+        relativeTo: this.route,
+      });
+    }
+    const filters = this.convertModulesTofilters(this.checkedModulesFilter, term);
+    // Send filters
+    this.searchEvent.emit(filters);
+  }
+
+  public fetchResults(checkedModules: Module[]): void {
+    const inputTerm = this.searchForm.get('searchTerm').value;
+    // Check if some modules is checked in filters
+    if (this.checkedModulesFilter !== checkedModules) {
+      this.countCheckFiltersOnModules(checkedModules);
+    }
+    // Store checked modules
+    this.checkedModulesFilter = checkedModules;
+    // Close modal after receive filters from her.
+    this.closeModal();
+    this.applyFilter(inputTerm);
+  }
+
+  // Check if some modules is checked on filter and store number of modules checked
+  public countCheckFiltersOnModules(checkedModules: Module[]): void {
+    this.numberAccompanimentChecked = checkedModules.filter(
+      (module) => module.text === 'proceduresAccompaniment'
+    ).length;
+    this.numberTrainingChecked = checkedModules.filter(
+      (module) =>
+        module.text === 'baseSkills' ||
+        module.text === 'socialAndProfessional' ||
+        module.text === 'parentingHelp' ||
+        module.text === 'accessRight' ||
+        module.text === 'digitalCultureSecurity'
+    ).length;
+    this.numberPublicChecked = checkedModules.filter((module) => module.text === 'publicsAccompaniment').length;
+    this.numberEquipmentChecked = checkedModules.filter((module) => module.text === 'equipmentsAndServices').length;
+    this.numberMoreFiltersChecked = checkedModules.filter(
+      (module) => module.text === 'labelsQualifications' || module.text === 'accessModality'
+    ).length;
+  }
+
+  public getModalCategory(): Category[] {
+    switch (this.modalTypeOpened) {
+      case TypeModal.accompaniment:
+        return this.categoriesAccompaniment;
+      case TypeModal.training:
+        return this.categoriesTraining;
+
+      case TypeModal.public:
+        return this.categoriesPublic;
+
+      case TypeModal.equipments:
+        return this.categoriesEquipment;
+
+      case TypeModal.moreFilters:
+        return this.categoriesMoreFilters;
+      default:
+        throw new Error('Modal type not handle');
+    }
+  }
+
+  // Open the modal and display the list according to the right filter button
+  public openModal(modalType: TypeModal): void {
+    // if modal already opened, reset type
+    if (this.modalTypeOpened === modalType) {
+      this.closeModal();
+    } else if (this.modalTypeOpened !== modalType) {
+      this.modalTypeOpened = modalType;
+    }
+  }
+
+  public closeModal(): void {
+    this.modalTypeOpened = undefined;
+  }
+
+  // Management of the checkbox event (Check / Uncheck)
+  public externalCheckboxCheck(event, categ, displayName): void {
+    const checkValue: string = event.target.value;
+    const inputTerm = this.searchForm.get('searchTerm').value;
+    if (event.target.checked) {
+      this.checkedModulesFilter.push(new Module(checkValue, categ, displayName));
+      this.numberMoreFiltersChecked++;
+    } else {
+      // Check if the module is present in the list and remove it
+      const index = this.checkedModulesFilter.findIndex((m: Module) => m.id === checkValue && m.text === categ);
+      if (index > -1) {
+        this.checkedModulesFilter.splice(index, 1);
+        this.countCheckFiltersOnModules(this.checkedModulesFilter);
+      }
+    }
+    this.applyFilter(inputTerm);
+  }
+
+  // Get the categories for each modal type
+  private getData(): void {
+    this.searchService.getCategoriesAccompaniment().subscribe((res) => {
+      const categories: Category[] = res;
+      categories.forEach((category) => {
+        this.categoriesAccompaniment.push(category);
+      });
+    });
+    this.searchService.getCategoriesTraining().subscribe((res) => {
+      const categories: Category[] = res;
+      categories.forEach((category) => {
+        this.categoriesTraining.push(category);
+      });
+    });
+    this.searchService.getCategoriesOthers().subscribe((res) => {
+      const categories: Category[] = res;
+      categories.forEach((category) => {
+        if (category.id === 'publicsAccompaniment') {
+          this.categoriesPublic.push(category);
+        } else if (category.id === 'equipmentsAndServices') {
+          this.categoriesEquipment.push(category);
+        } else if (category.id === 'labelsQualifications' || category.id === 'accessModality') {
+          this.categoriesMoreFilters.push(category);
+        }
+      });
+    });
+  }
+
+  public resetFilters(): void {
+    this.checkedModulesFilter = [];
+    this.numberTrainingChecked = 0;
+    this.numberAccompanimentChecked = 0;
+    this.numberPublicChecked = 0;
+    this.numberEquipmentChecked = 0;
+    this.numberMoreFiltersChecked = 0;
+    const inputTerm = this.searchForm.get('searchTerm').value;
+    const filters = this.convertModulesTofilters(this.checkedModulesFilter, inputTerm);
+    this.searchEvent.emit(filters);
+  }
+  public removeFilter(module: Module): void {
+    const index = this.checkedModulesFilter.findIndex((m: Module) => m.id === module.id);
+    this.checkedModulesFilter.splice(index, 1);
+    const inputTerm = this.searchForm.get('searchTerm').value;
+    const filters = this.convertModulesTofilters(this.checkedModulesFilter, inputTerm);
+    this.countCheckFiltersOnModules(this.checkedModulesFilter);
+    this.searchEvent.emit(filters);
+  }
+}
diff --git a/src/app/config/map/access-modality.enum.ts b/src/app/structure-list/enum/access-modality.enum.ts
similarity index 95%
rename from src/app/config/map/access-modality.enum.ts
rename to src/app/structure-list/enum/access-modality.enum.ts
index a0a9f8db5bd6065decdaf5665d87beef4207d246..81c7f7edd2811afdaa458731d89af3532bf1d7e2 100644
--- a/src/app/config/map/access-modality.enum.ts
+++ b/src/app/structure-list/enum/access-modality.enum.ts
@@ -1,6 +1,6 @@
-export enum AccessModality {
-  free = 'accesLibre',
-  numeric = 'telephoneVisio',
-  meetingOnly = 'uniquementSurRdv',
-  meeting = 'surRdv',
-}
+export enum AccessModality {
+  free = 'accesLibre',
+  numeric = 'telephoneVisio',
+  meetingOnly = 'uniquementSurRdv',
+  meeting = 'surRdv',
+}
diff --git a/src/app/structure-list/enum/equipment.enum.ts b/src/app/structure-list/enum/equipment.enum.ts
new file mode 100644
index 0000000000000000000000000000000000000000..880b4a16d47af4ba2eb3245b417ec1075f4432c1
--- /dev/null
+++ b/src/app/structure-list/enum/equipment.enum.ts
@@ -0,0 +1,8 @@
+export enum Equipment {
+  wifi = 'wifiEnAccesLibre',
+  bornes = 'bornesNumeriques',
+  printer = 'imprimantes',
+  tablet = 'tablettes',
+  computer = 'ordinateurs',
+  scanner = 'scanners',
+}
diff --git a/src/app/structure-list/enum/public.enum.ts b/src/app/structure-list/enum/public.enum.ts
new file mode 100644
index 0000000000000000000000000000000000000000..905f79748193cb9859118321b0bfd92efce23f37
--- /dev/null
+++ b/src/app/structure-list/enum/public.enum.ts
@@ -0,0 +1,8 @@
+export enum PublicCategorie {
+  under16Years = 'moinsDe16Ans',
+  young = 'jeunes1625Ans',
+  adult = 'adultes',
+  elderly = 'seniorsPlusDe65Ans',
+  all = 'toutPublic',
+  women = 'uniquementFemmes',
+}
diff --git a/src/app/structure-list/enum/typeModal.enum.ts b/src/app/structure-list/enum/typeModal.enum.ts
new file mode 100644
index 0000000000000000000000000000000000000000..232ac284462a50e8d6437494984f0e6316ca705e
--- /dev/null
+++ b/src/app/structure-list/enum/typeModal.enum.ts
@@ -0,0 +1,7 @@
+export enum TypeModal {
+  accompaniment = 1,
+  training,
+  public,
+  equipments,
+  moreFilters,
+}
diff --git a/src/app/structure-list/enum/weekday.enum.ts b/src/app/structure-list/enum/weekday.enum.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f4889072c313a09838c9411201f1554cf7a3e931
--- /dev/null
+++ b/src/app/structure-list/enum/weekday.enum.ts
@@ -0,0 +1,9 @@
+export enum Weekday {
+  monday = 1,
+  tuesday,
+  wednesday,
+  thursday,
+  friday,
+  saturday,
+  sunday,
+}
diff --git a/src/app/structure-list/models/category.model.ts b/src/app/structure-list/models/category.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d269f41b886725b17861e30c8bddf9ae85bd9074
--- /dev/null
+++ b/src/app/structure-list/models/category.model.ts
@@ -0,0 +1,39 @@
+import { Module } from './module.model';
+
+export class Category {
+  name: string;
+  surname: string;
+  id: string;
+  modules: Module[];
+
+  constructor(obj?: any) {
+    Object.assign(this, obj, {
+      modules:
+        obj && obj.modules
+          ? obj.modules.map(
+              (module) => new Module(module.display_id ? module.display_id : module.id, module.text, module.text)
+            )
+          : null,
+    });
+  }
+
+  public isBaseSkills(): boolean {
+    return this.id === 'baseSkills';
+  }
+
+  public isRigthtsAccess(): boolean {
+    return this.id === 'accessRight';
+  }
+
+  public isParentingHelp(): boolean {
+    return this.id === 'parentingHelp';
+  }
+
+  public isDigitalCultureSecurity(): boolean {
+    return this.id === 'digitalCultureSecurity';
+  }
+
+  public isSocialAndProfessional(): boolean {
+    return this.id === 'socialAndProfessional';
+  }
+}
diff --git a/src/app/structure-list/models/filter.model.ts b/src/app/structure-list/models/filter.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..25d7ff8253cb742637510467035c853e8c7a77f0
--- /dev/null
+++ b/src/app/structure-list/models/filter.model.ts
@@ -0,0 +1,13 @@
+export class Filter {
+  name: string;
+  value: string;
+  text?: string;
+  checked: boolean;
+
+  constructor(name: string, value: any, text?: string) {
+    this.name = name;
+    this.value = value.toString();
+    this.text = text;
+    this.checked = true;
+  }
+}
diff --git a/src/app/structure-list/models/module.model.ts b/src/app/structure-list/models/module.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..be98b490fa32851530ecbe8720ab086dad3d040c
--- /dev/null
+++ b/src/app/structure-list/models/module.model.ts
@@ -0,0 +1,12 @@
+export class Module {
+  id: string;
+  text: string;
+  count: number;
+  displayText?: string;
+
+  constructor(id: string, text: string, displayText?: string) {
+    this.id = id;
+    this.text = text;
+    this.displayText = displayText;
+  }
+}
diff --git a/src/app/structure-list/services/search.service.ts b/src/app/structure-list/services/search.service.ts
index c96e86387858b452f702394db3b24783eef04924..edd0de785b39c8c3646097353949205cb54b82a6 100644
--- a/src/app/structure-list/services/search.service.ts
+++ b/src/app/structure-list/services/search.service.ts
@@ -1,8 +1,9 @@
 import { HttpClient } from '@angular/common/http';
 import { Injectable } from '@angular/core';
-import { Category, Module } from '@gouvfr-anct/mediation-numerique';
 import { Observable } from 'rxjs';
 import { map } from 'rxjs/operators';
+import { Category } from '../models/category.model';
+import { Module } from '../models/module.model';
 
 @Injectable({
   providedIn: 'root',
diff --git a/src/app/structure-list/structure-list.component.html b/src/app/structure-list/structure-list.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..68eda11340e9105ce29b7ea00c10858c0b54e24e
--- /dev/null
+++ b/src/app/structure-list/structure-list.component.html
@@ -0,0 +1,27 @@
+<div class="structureList-container">
+  <div class="structureListHeader hide-on-print">
+    <div class="nbStructuresLabel" [ngPlural]="structureList.length">
+      <ng-template ngPluralCase="0">0 structure</ng-template>
+      <ng-template ngPluralCase="1">1 structure</ng-template>
+      <ng-template ngPluralCase="other">{{ structureList.length }} structures</ng-template>
+    </div>
+    <app-button
+      tabindex="0"
+      (action)="addStructure()"
+      [text]="'Ajouter une structure'"
+      [style]="buttonTypeEnum.Secondary"
+      [extraClass]="'small-text'"
+    ></app-button>
+  </div>
+
+  <div id="listCard" class="listCard" (mouseleave)="mouseLeave()">
+    <app-card
+      *ngFor="let structure of structureList"
+      [structure]="structure"
+      (showDetails)="showDetails($event, filters)"
+      (hover)="handleCardHover($event)"
+      class="structure-card"
+    ></app-card>
+    <p *ngIf="structureList && structureList.length <= 0">Il n'y a aucune réponse correspondant à votre recherche</p>
+  </div>
+</div>
diff --git a/src/app/structure-list/structure-list.component.scss b/src/app/structure-list/structure-list.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..b8108121d4b2ce054cebaacb8247e14670da3e9a
--- /dev/null
+++ b/src/app/structure-list/structure-list.component.scss
@@ -0,0 +1,40 @@
+@import '../../assets/scss/color';
+@import '../../assets/scss/icons';
+@import '../../assets/scss/typography';
+@import '../../assets/scss/buttons';
+
+.structureList-container {
+  overflow-y: auto;
+  scrollbar-gutter: stable;
+}
+
+.listCard > p {
+  margin-left: 1rem;
+}
+
+.structureListHeader {
+  height: 50px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin: 8px 16px;
+  .nbStructuresLabel {
+    @include lato-regular-14;
+    color: $grey-3;
+    flex: 1;
+  }
+}
+
+::ng-deep .structure-card:last-child .structure {
+  border-bottom: unset !important;
+}
+
+@media print {
+  .listCard {
+    display: none;
+  }
+
+  .hide-on-print {
+    display: none !important;
+  }
+}
diff --git a/src/app/structure-list/structure-list.component.spec.ts b/src/app/structure-list/structure-list.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..77af804ccc53702dee9100089cf6bed6fe7f6d19
--- /dev/null
+++ b/src/app/structure-list/structure-list.component.spec.ts
@@ -0,0 +1,196 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { OpeningDay } from '../models/openingDay.model';
+import { Structure } from '../models/structure.model';
+import { StructureListComponent } from './structure-list.component';
+
+describe('StructureListComponent', () => {
+  let component: StructureListComponent;
+  let fixture: ComponentFixture<StructureListComponent>;
+  let structure: Structure;
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [StructureListComponent],
+    }).compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(StructureListComponent);
+    component = fixture.debugElement.componentInstance;
+    structure = new Structure({
+      id: 1,
+      numero: '26-63',
+      updatedAt: '2020-10-08T15:17:00.000Z',
+      nomDeLusager: 'Erwan Le luron',
+      structureRepresentation: 'Un établissement principal (siège social)',
+      structureName: 'Régie de Quartier Armstrong',
+      structureType: 'Tiers-lieu & coworking, FabLab',
+      description: "Association loi 1901 dont l'objet est l'insertion par l'économie social et solidaire",
+      n: 2,
+      adressWay: 21356,
+      contactPhone: '04 72 21 03 07',
+      contactMail: 'sguillet@rqa.fr',
+      website: '',
+      facebook: '',
+      twitter: '@rqainfo69',
+      instagram: '',
+      gender: 'Madame',
+      contactName: 'GUILLET',
+      contactSurname: 'Séverine',
+      fonction: 'Autres',
+      pmrAccess: '',
+      choixMultiples: 'Tout public',
+      exceptionalClosures: '',
+      proceduresAccompaniment: 'Accompagnant CAF',
+      autresAccompagnements: '',
+      baseSkills: 260,
+      accessRight: 176,
+      socialAndProfessional: 254,
+      parentingHelp: '',
+      digitalCultureSecurity: 264,
+      wifiEnAccesLibre: 'True',
+      nbComputers: '',
+      nombre: '',
+      tablettes: '',
+      bornesNumeriques: '',
+      imprimantes: '',
+      autresEspacesProposesParLaStructure: 'Espace libre service',
+      appartenezVousAUnReseauDeMediation: '',
+      precisezLequel: '',
+      idDeLitemStructureDansDirectus: 123,
+      statutDeLitemStructureDansDirectus: '',
+      idDeLitemOffreDansDirectus: '',
+      statut: 'Erreur lors du versement des données offre',
+      hours: {
+        monday: {
+          open: true,
+          time: [
+            {
+              opening: 1330,
+              closing: 1630,
+            },
+            {
+              opening: null,
+              closing: null,
+            },
+          ],
+        },
+        tuesday: {
+          open: true,
+          time: [
+            {
+              opening: 830,
+              closing: 1130,
+            },
+            {
+              opening: 1330,
+              closing: 1630,
+            },
+          ],
+        },
+        wednesday: {
+          open: true,
+          time: [
+            {
+              opening: 1330,
+              closing: 1630,
+            },
+            {
+              opening: null,
+              closing: null,
+            },
+          ],
+        },
+        thursday: {
+          open: true,
+          time: [
+            {
+              opening: 830,
+              closing: 1130,
+            },
+            {
+              opening: 1330,
+              closing: 1630,
+            },
+          ],
+        },
+        friday: {
+          open: true,
+          time: [
+            {
+              opening: 830,
+              closing: 1130,
+            },
+            {
+              opening: 1330,
+              closing: 1530,
+            },
+          ],
+        },
+        saturday: {
+          open: false,
+          time: [
+            {
+              opening: null,
+              closing: null,
+            },
+            {
+              opening: null,
+              closing: null,
+            },
+          ],
+        },
+        sunday: {
+          open: false,
+          time: [
+            {
+              opening: null,
+              closing: null,
+            },
+            {
+              opening: null,
+              closing: null,
+            },
+          ],
+        },
+      },
+      openedOn: new OpeningDay('monday', null),
+    });
+    const structureList = new Array<Structure>(structure);
+    structureList.length = 4;
+    component.structureList = structureList;
+    fixture.detectChanges(); // calls NgOnit
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  it('should emit id structure and update variables to open details', () => {
+    spyOn(component.selectedMarkerId, 'emit');
+    component.showDetails(structure);
+    expect(component.selectedMarkerId.emit).toHaveBeenCalled();
+    expect(component.selectedMarkerId.emit).toHaveBeenCalledWith(structure._id);
+    expect(component.structure).toBe(structure);
+  });
+
+  it('should emit id structure and update variables to close details', () => {
+    spyOn(component.selectedMarkerId, 'emit');
+    component.closeDetails();
+    expect(component.selectedMarkerId.emit).toHaveBeenCalled();
+    expect(component.selectedMarkerId.emit).toHaveBeenCalledWith();
+  });
+
+  it('should emit id structure to display map marker', () => {
+    spyOn(component.displayMapMarkerId, 'emit');
+    component.handleCardHover(structure);
+    expect(component.displayMapMarkerId.emit).toHaveBeenCalled();
+    expect(component.displayMapMarkerId.emit).toHaveBeenCalledWith([structure._id]);
+  });
+
+  it('should emit undefined id structure to remove map marker', () => {
+    spyOn(component.displayMapMarkerId, 'emit');
+    component.mouseLeave();
+    expect(component.displayMapMarkerId.emit).toHaveBeenCalled();
+    expect(component.displayMapMarkerId.emit).toHaveBeenCalledWith([undefined]);
+  });
+});
diff --git a/src/app/structure-list/structure-list.component.ts b/src/app/structure-list/structure-list.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..df44ef9e3d900f8e1451bfc45becc5a68e27b670
--- /dev/null
+++ b/src/app/structure-list/structure-list.component.ts
@@ -0,0 +1,83 @@
+import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { GeoJson } from '../map/models/geojson.model';
+import { Structure } from '../models/structure.model';
+import { AuthService } from '../services/auth.service';
+import { StructureService } from '../services/structure.service';
+import { ButtonType } from '../shared/components/button/buttonType.enum';
+
+@Component({
+  selector: 'app-structure-list',
+  templateUrl: './structure-list.component.html',
+  styleUrls: ['./structure-list.component.scss'],
+})
+export class StructureListComponent implements OnChanges {
+  @Input() public structureList: Structure[];
+  @Input() public location: GeoJson;
+  @Input() public selectedStructure: Structure = new Structure();
+  @Output() public displayMapMarkerId: EventEmitter<string> = new EventEmitter<string>();
+  @Output() public selectedMarkerId: EventEmitter<string> = new EventEmitter<string>();
+  @Output() public updatedStructure: EventEmitter<Structure> = new EventEmitter<Structure>();
+
+  public buttonTypeEnum = ButtonType;
+  public structure: Structure;
+
+  constructor(
+    private route: ActivatedRoute,
+    private router: Router,
+    private structureService: StructureService,
+    private authService: AuthService
+  ) {
+    this.route.queryParams.subscribe((queryParams) => {
+      if (queryParams.id) {
+        if (!this.structure) {
+          this.structureService.getStructure(queryParams.id).subscribe((s) => {
+            this.showDetails(new Structure(s));
+          });
+        }
+      } else {
+        this.closeDetails();
+      }
+    });
+  }
+
+  ngOnChanges(changes: SimpleChanges): void {
+    if (changes.selectedStructure && this.selectedStructure) {
+      this.showDetails(this.selectedStructure);
+      this.router.navigate([], {
+        relativeTo: this.route,
+        queryParams: {
+          id: this.selectedStructure._id,
+        },
+      });
+    }
+    if (changes.structureList) {
+      document.getElementById('listCard').scrollTo(0, 0);
+    }
+  }
+
+  public addStructure(): void {
+    if (!this.authService.isLoggedIn()) {
+      this.router.navigateByUrl('/login');
+    } else {
+      this.router.navigateByUrl('/form/structure');
+    }
+  }
+
+  public showDetails(event: Structure): void {
+    this.structure = event;
+    this.selectedMarkerId.emit(this.structure._id);
+  }
+
+  public closeDetails(): void {
+    this.selectedMarkerId.emit();
+  }
+
+  public handleCardHover(structure: Structure): void {
+    this.displayMapMarkerId.emit(structure._id);
+  }
+
+  public mouseLeave(): void {
+    this.displayMapMarkerId.emit(undefined);
+  }
+}
diff --git a/src/app/structure/components/structure-details-actions/structure-details-actions.component.html b/src/app/structure/components/structure-details-actions/structure-details-actions.component.html
deleted file mode 100644
index ef0a447f0909c8667212c248c9a1282b5f5d6524..0000000000000000000000000000000000000000
--- a/src/app/structure/components/structure-details-actions/structure-details-actions.component.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<div
-  *ngIf="!profileService.isLinkedToStructure(structure._id)"
-  fxLayout="column"
-  fxLayoutAlign="center center"
-  class="clickableDiv"
-  role="button"
-  (click)="handleJoin()"
-  tabindex="0"
->
-  <app-svg-icon class="icon" [type]="'ico'" [icon]="'workhere'" [iconClass]="'icon-32'"></app-svg-icon>
-  <div class="iconTitle">Je travaille ici</div>
-</div>
-<div
-  *ngIf="profileService.isLinkedToStructure(structure._id) || profileService.isAdmin()"
-  fxLayout="column"
-  fxLayoutAlign="center center"
-  class="clickableDiv"
-  role="button"
-  (click)="handleModify()"
-  tabindex="0"
->
-  <app-svg-icon class="icon" [type]="'ico'" [icon]="'modifyStructure'" [iconClass]="'icon-32'"></app-svg-icon>
-  <div class="iconTitle">Modifier cette structure</div>
-</div>
diff --git a/src/app/structure/components/structure-details-actions/structure-details-actions.component.scss b/src/app/structure/components/structure-details-actions/structure-details-actions.component.scss
deleted file mode 100644
index 687a84df76c8da089dbd0e8ec90581766c8f0cec..0000000000000000000000000000000000000000
--- a/src/app/structure/components/structure-details-actions/structure-details-actions.component.scss
+++ /dev/null
@@ -1,39 +0,0 @@
-@import '../../../../assets/scss/typography';
-@import '../../../../assets/scss/breakpoint';
-.clickableDiv {
-  text-align: center;
-  height: 90px;
-  width: 115.2px;
-  display: flex;
-  flex-direction: column;
-  cursor: pointer;
-  .icon {
-    margin-top: 20px;
-    flex: 1;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-  }
-  .iconTitle {
-    @include lato-regular-13;
-    height: 36px;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-  }
-  &:hover {
-    text-decoration: underline;
-  }
-  @media #{$large-phone} {
-    width: 50%;
-  }
-}
-
-.clickableDiv:first-child {
-  @media #{$tablet} {
-    margin-right: 16px;
-  }
-  @media #{$phone} {
-    margin-right: unset;
-  }
-}
diff --git a/src/app/structure/components/structure-details-actions/structure-details-actions.component.ts b/src/app/structure/components/structure-details-actions/structure-details-actions.component.ts
deleted file mode 100644
index 82f62e56796fda948a2db30953de3c87b7c8911f..0000000000000000000000000000000000000000
--- a/src/app/structure/components/structure-details-actions/structure-details-actions.component.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
-import { Router } from '@angular/router';
-import { Structure } from '@gouvfr-anct/mediation-numerique';
-import { Owner } from '../../../models/owner.model';
-import { User } from '../../../models/user.model';
-import { ProfileService } from '../../../profile/services/profile.service';
-import { AuthService } from '../../../services/auth.service';
-import { StructureService } from '../../../services/structure.service';
-
-@Component({
-  selector: 'app-structure-details-actions',
-  templateUrl: 'structure-details-actions.component.html',
-  styleUrls: ['./structure-details-actions.component.scss'],
-})
-export class StructureDetailsActionsComponent implements OnInit {
-  @Input() public structure: Structure;
-
-  @Output() public claimChange: EventEmitter<boolean> = new EventEmitter<boolean>();
-  @Output() public deleteModal: EventEmitter<void> = new EventEmitter<void>();
-  @Output() public pendingModal: EventEmitter<void> = new EventEmitter<void>();
-  @Output() public claimModal: EventEmitter<void> = new EventEmitter<void>();
-  @Output() public joinModal: EventEmitter<void> = new EventEmitter<void>();
-
-  public currentProfile: User = null;
-  public structureAdmins: Owner[] = [];
-  public joinModalOpenned = false;
-  public pendingModalOpenned = false;
-  public claimModalOpenned = false;
-
-  public constructor(
-    public readonly profileService: ProfileService,
-    private structureService: StructureService,
-    private router: Router,
-    private authService: AuthService
-  ) {}
-
-  public async ngOnInit(): Promise<void> {
-    if (this.userIsLoggedIn()) {
-      this.currentProfile = await this.profileService.getProfile();
-
-      if (this.profileService.isAdmin()) {
-        this.structureService.getStructureWithOwners(this.structure._id, this.currentProfile).subscribe((res) => {
-          this.structureAdmins = res.owners;
-        });
-      }
-    }
-    this.claimChange.emit(await this.structureService.isClaimed(this.structure._id, this.currentProfile).toPromise());
-  }
-
-  public userIsLoggedIn(): boolean {
-    return this.authService.isLoggedIn();
-  }
-
-  public togglePendingModal(): void {
-    // this.pendingModalOpenned = !this.pendingModalOpenned;
-    this.pendingModal.emit();
-  }
-
-  public toggleJoinModal(): void {
-    // this.joinModalOpenned = !this.joinModalOpenned;
-    this.joinModal.emit();
-  }
-
-  public toggleClaimModal(): void {
-    // this.claimModalOpenned = !this.claimModalOpenned;
-    this.claimModal.emit();
-  }
-
-  public handleJoin(): void {
-    if (this.userIsLoggedIn()) {
-      if (this.structure.isClaimed) {
-        if (this.profileService.isPendingLinkedToStructure(this.structure._id)) {
-          this.togglePendingModal();
-        } else {
-          this.toggleJoinModal();
-        }
-      } else {
-        this.toggleClaimModal();
-      }
-    } else {
-      this.router.navigate(['login'], { queryParams: { returnUrl: `acteurs?id=${this.structure._id}` } });
-    }
-  }
-
-  public handleModify(): void {
-    this.router.navigateByUrl(`/profile/edit-structure/${this.structure._id}`);
-  }
-}
diff --git a/src/app/structure/components/structure-details-modals/structure-details-modals.component.html b/src/app/structure/components/structure-details-modals/structure-details-modals.component.html
deleted file mode 100644
index c59aea08fdeda9805263f0efdd2a7ddc079accc1..0000000000000000000000000000000000000000
--- a/src/app/structure/components/structure-details-modals/structure-details-modals.component.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<app-modal-confirmation
-  [openned]="deleteModalOpenned"
-  [content]="'Voulez-vous vraiment supprimer cette structure&nbsp;?'"
-  (closed)="deleteStructure($event)"
-></app-modal-confirmation>
-
-<app-modal-confirmation
-  [openned]="claimModalOpenned"
-  [content]="
-    'Voulez-vous vraiment revendiquer cette structure&nbsp;? Une demande sera envoyée à l\'administrateur pour validation'
-  "
-  (closed)="claimStructure($event)"
-></app-modal-confirmation>
-
-<app-join-modal-confirmation
-  [openned]="claimModalOpenned"
-  [title]="'Travaillez-vous ici&nbsp;?'"
-  [primaryContent]="
-    'Un message sera envoyé aux administrateurs Rés\'IN pour valider l\'affectation de votre compte à la structure'
-  "
-  [secondaryContent]="structure.structureName"
-  [customConfirmationText]="'Rejoindre la structure'"
-  (closed)="claimStructure($event)"
-></app-join-modal-confirmation>
-
-<app-join-modal-confirmation
-  [openned]="joinModalOpenned"
-  [title]="'Travaillez-vous ici&nbsp;?'"
-  [primaryContent]="'Un message sera envoyé à un administrateur de la structure'"
-  [secondaryContent]="structure.structureName"
-  [customConfirmationText]="'Rejoindre la structure'"
-  (closed)="joinStructure($event)"
-></app-join-modal-confirmation>
-
-<app-join-modal-confirmation
-  [openned]="pendingModalOpenned"
-  [title]="'Travaillez-vous ici&nbsp;?'"
-  [primaryContent]="
-    'Un message a déjà été envoyé aux administrateurs Rés\'IN pour validation, vous recevrez un email quand votre compte sera rattaché à la structure'
-  "
-  [secondaryContent]="structure.structureName"
-  [customConfirmationText]="'OK'"
-  [displayCancelButton]="false"
-  (closed)="togglePendingModal()"
-></app-join-modal-confirmation>
diff --git a/src/app/structure/components/structure-details-modals/structure-details-modals.component.ts b/src/app/structure/components/structure-details-modals/structure-details-modals.component.ts
deleted file mode 100644
index f504eb5aab655eb1f56bf0c9989d950578ecddcb..0000000000000000000000000000000000000000
--- a/src/app/structure/components/structure-details-modals/structure-details-modals.component.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-import { Component, EventEmitter, Input, Output } from '@angular/core';
-import { ActivatedRoute, Router } from '@angular/router';
-import { Structure } from '@gouvfr-anct/mediation-numerique';
-import { User } from '../../../models/user.model';
-import { ProfileService } from '../../../profile/services/profile.service';
-import { AuthService } from '../../../services/auth.service';
-import { StructureService } from '../../../services/structure.service';
-
-@Component({
-  selector: 'app-structure-details-modals',
-  templateUrl: './structure-details-modals.component.html',
-})
-export class StructureDetailsModalsComponent {
-  @Input() public structure: Structure;
-  @Output() public claimChange: EventEmitter<boolean> = new EventEmitter<boolean>();
-
-  public deleteModalOpenned = false;
-  public claimModalOpenned = false;
-  public joinModalOpenned = false;
-  public pendingModalOpenned = false;
-
-  public constructor(
-    private profileService: ProfileService,
-    private authService: AuthService,
-    private route: ActivatedRoute,
-    private router: Router,
-    private structureService: StructureService
-  ) {}
-
-  public toggleClaimModal(): void {
-    this.claimModalOpenned = !this.claimModalOpenned;
-  }
-
-  public toggleDeleteModal(): void {
-    this.deleteModalOpenned = !this.deleteModalOpenned;
-  }
-
-  public toggleJoinModal(): void {
-    this.joinModalOpenned = !this.joinModalOpenned;
-  }
-
-  public togglePendingModal(): void {
-    this.pendingModalOpenned = !this.pendingModalOpenned;
-  }
-
-  private reload(): void {
-    this.router.routeReuseStrategy.shouldReuseRoute = () => false;
-    this.router.onSameUrlNavigation = 'reload';
-    this.router.navigate(['./'], { relativeTo: this.route });
-  }
-
-  public claimStructure(shouldClaim: boolean): void {
-    this.toggleClaimModal();
-    if (shouldClaim) {
-      this.structureService
-        .claimStructureWithAccount(this.structure._id, this.authService.userValue.username)
-        .subscribe();
-      this.router.navigate(['join', this.structure._id], { state: { isClaimed: this.structure.isClaimed } });
-    }
-  }
-
-  public deleteStructure(shouldDelete: boolean): void {
-    this.toggleDeleteModal();
-    if (shouldDelete) {
-      this.structureService.delete(this.structure._id).subscribe((_res) => {
-        this.reload();
-      });
-    }
-  }
-
-  public joinStructure(shouldClaim: boolean): void {
-    this.toggleJoinModal();
-    if (shouldClaim) {
-      this.structureService.joinStructure(this.structure._id, this.authService.userValue.username).subscribe((_res) => {
-        this.profileService.getProfile().then((_user: User) => {
-          this.claimChange.emit(true);
-        });
-      });
-    }
-  }
-}
diff --git a/src/app/structure/components/structure-details-wrapper/structure-details-wrapper.component.html b/src/app/structure/components/structure-details-wrapper/structure-details-wrapper.component.html
deleted file mode 100644
index 642b684ff581a1e48fa74dd7ae2407a235a10f97..0000000000000000000000000000000000000000
--- a/src/app/structure/components/structure-details-wrapper/structure-details-wrapper.component.html
+++ /dev/null
@@ -1,57 +0,0 @@
-<app-structure-details class="structureList-details" [structure]="structure" *ngIf="structure">
-  <app-structure-details-modals
-    #modals
-    [structure]="structure"
-    (claimChange)="updateClaim(structure._id, $event)"
-    slot="structure-details-modals"
-  ></app-structure-details-modals>
-  <app-tcl-access [structure]="structure" slot="structure-details-access"></app-tcl-access>
-  <app-structure-details-actions
-    [structure]="structure"
-    (deleteModal)="modals.toggleDeleteModal()"
-    (claimModal)="modals.toggleClaimModal()"
-    (joinModal)="modals.toggleJoinModal()"
-    (pendingModal)="modals.togglePendingModal()"
-    (claimChange)="updateClaim(structure._id, $event)"
-    class="structure-details-actions"
-    slot="structure-details-actions"
-  ></app-structure-details-actions>
-  <!-- Admin display -->
-  <div *ngIf="profileService.isAdmin()" slot="structure-admin-actions" class="structure-details-block hide-on-print">
-    Administrateur(s) de cette structure:
-    <div *ngIf="structureAdmins.length === 0">Aucun administrateur</div>
-    <div *ngIf="structureAdmins.length > 0">
-      <div *ngFor="let structureAdmin of structureAdmins">
-        {{ structureAdmin.email }}
-      </div>
-    </div>
-    <a (click)="modals.toggleDeleteModal()" class="primary" tabindex="0">Supprimer cette structure</a>
-  </div>
-  <!-- Members -->
-  <div
-    *ngIf="userIsLoggedIn() && structureAdmins.length"
-    fxLayout="column"
-    class="structure-details-block"
-    fxLayoutAlign="baseline baseline"
-    fxLayoutGap="8px"
-    slot="structure-members"
-  >
-    <h2>Membres</h2>
-    <div fxLayout="column" fxLayoutGap="8px" fxLayoutAlign="baseline baseline">
-      <div *ngFor="let member of structureAdmins" class="member-card">
-        <a [routerLink]="'/profile/' + member._id">
-          <app-svg-icon
-            class="avatar"
-            [type]="'avatar'"
-            [icon]="'defaultAvatar'"
-            [iconClass]="'icon-40'"
-          ></app-svg-icon>
-          <div class="info-member">
-            <p class="member">{{ member.name | uppercase }} {{ member.surname | titlecase }}</p>
-            <p class="job" *ngIf="displayJobEmployer(member)">{{ displayJobEmployer(member) }}</p>
-          </div>
-        </a>
-      </div>
-    </div>
-  </div>
-</app-structure-details>
diff --git a/src/app/structure/components/structure-details-wrapper/structure-details-wrapper.component.scss b/src/app/structure/components/structure-details-wrapper/structure-details-wrapper.component.scss
deleted file mode 100644
index 8dee4cd6877e3920aaa328ef043cbaa8bc3a39da..0000000000000000000000000000000000000000
--- a/src/app/structure/components/structure-details-wrapper/structure-details-wrapper.component.scss
+++ /dev/null
@@ -1,203 +0,0 @@
-@import '../../../../assets/scss/color';
-@import '../../../../assets/scss/typography';
-@import '../../../../assets/scss/breakpoint';
-
-a {
-  padding: unset;
-  text-decoration: underline;
-  font-size: inherit;
-  font-weight: inherit;
-}
-
-p:empty {
-  margin: 0;
-}
-
-h1 {
-  @include lato-bold-20;
-  color: $grey-1;
-}
-h2 {
-  @include lato-bold-14;
-  color: $grey-3;
-  text-transform: uppercase;
-  margin-top: 0;
-  margin-bottom: 12px;
-}
-h3 {
-  @include lato-regular-16;
-  margin: 0 0 8px 0;
-}
-
-.member-card {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  a {
-    text-decoration: none;
-    display: flex;
-    align-items: center;
-  }
-  a:hover {
-    text-decoration: underline;
-  }
-  .avatar {
-    background-color: $grey-8;
-    border-radius: 4px;
-  }
-  .info-member {
-    margin-left: 1rem;
-    p {
-      margin: 0;
-    }
-    .member {
-      @include lato-bold-14;
-    }
-    .job {
-      @include lato-regular-14;
-    }
-  }
-}
-.structure-details-actions {
-  flex-direction: row;
-  box-sizing: border-box;
-  display: flex;
-  place-content: stretch space-evenly;
-  align-items: stretch;
-}
-
-.structure-details-block {
-  margin: 0 20px;
-  padding: 24px 0;
-  border-bottom: 2px solid $grey-8;
-  &.noSeparator {
-    border-bottom: none;
-    padding-bottom: 0px;
-  }
-
-  .info-block > div {
-    margin-top: 4px;
-    &:first-of-type {
-      margin-top: 0px;
-    }
-  }
-
-  .description {
-    white-space: pre-wrap;
-    margin-top: 8px;
-  }
-
-  .info {
-    color: $red-1;
-    margin-top: 8px;
-  }
-
-  .hours-services-block {
-    display: flex;
-    flex-direction: row;
-    & > div {
-      flex: 1;
-    }
-    @media #{$large-phone} {
-      flex-direction: column;
-    }
-
-    .opening-hours {
-      margin-bottom: 8px;
-      .opening-hour {
-        margin-bottom: 8px;
-        .day {
-          min-width: 70px;
-          margin-top: 0;
-          margin-left: 0;
-          margin-bottom: 0;
-          @include lato-regular-14;
-          color: $grey-3;
-          text-transform: capitalize;
-        }
-        .daily-opening-time {
-          p {
-            margin: 0 0 4px 0;
-          }
-        }
-      }
-    }
-  }
-
-  .services-block {
-    margin-bottom: 8px;
-    p {
-      display: list-item;
-      margin: 0 0 0 25px;
-    }
-  }
-
-  .wrapper {
-    display: grid;
-    grid-template-columns: 1fr 1fr;
-    @media #{$large-phone} {
-      grid-template-columns: 1fr;
-    }
-  }
-
-  .formationDetails {
-    width: 100%;
-    .collapse {
-      margin-bottom: 13px;
-      @media #{$small-phone} {
-        width: 95% !important;
-      }
-      &.notCollapsed {
-        border-bottom: 2px solid $grey-8;
-        .logo {
-          .hide {
-            display: none;
-          }
-          .show {
-            display: block;
-          }
-        }
-      }
-      .titleCollapse {
-        width: 100%;
-        @include lato-regular-16;
-      }
-      .collapseHeader {
-        cursor: pointer;
-      }
-      .logo {
-        height: 24px;
-        width: 24px;
-        svg {
-          width: 100%;
-          height: 100%;
-          fill: $grey-1;
-        }
-      }
-      .logo,
-      .titleCollapse {
-        .hide {
-          display: block;
-        }
-        .show {
-          display: none;
-        }
-      }
-      .detailsContainer {
-        margin: 8px 0px;
-        padding: 8px 0;
-        background-color: $grey-8;
-        overflow: hidden;
-      }
-      .details {
-        padding: 8px 16px;
-      }
-    }
-  }
-
-  .updated {
-    @include lato-regular-14;
-    color: $grey-3;
-    font-style: italic;
-  }
-}
diff --git a/src/app/structure/components/structure-details-wrapper/structure-details-wrapper.component.spec.ts b/src/app/structure/components/structure-details-wrapper/structure-details-wrapper.component.spec.ts
deleted file mode 100644
index ad781c9bb655465dcdf1cf3580dd284727bb236c..0000000000000000000000000000000000000000
--- a/src/app/structure/components/structure-details-wrapper/structure-details-wrapper.component.spec.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { StructureDetailsWrapperComponent } from './structure-details-wrapper.component';
-
-describe('StructureDetailsWrapperComponent', () => {
-  let component: StructureDetailsWrapperComponent;
-  let fixture: ComponentFixture<StructureDetailsWrapperComponent>;
-
-  beforeEach(async () => {
-    await TestBed.configureTestingModule({
-      declarations: [ StructureDetailsWrapperComponent ]
-    })
-    .compileComponents();
-  });
-
-  beforeEach(() => {
-    fixture = TestBed.createComponent(StructureDetailsWrapperComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});
diff --git a/src/app/structure/components/structure-details-wrapper/structure-details-wrapper.component.ts b/src/app/structure/components/structure-details-wrapper/structure-details-wrapper.component.ts
deleted file mode 100644
index a5537dadbce59e13c93e6dcb82a12a4469c169a4..0000000000000000000000000000000000000000
--- a/src/app/structure/components/structure-details-wrapper/structure-details-wrapper.component.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-import { Component, Input, OnInit } from '@angular/core';
-import { ActivatedRoute } from '@angular/router';
-import { Structure } from '@gouvfr-anct/mediation-numerique';
-import { BehaviorSubject } from 'rxjs';
-import { ParametersService } from '../../../admin/services/parameters.service';
-import { Owner } from '../../../models/owner.model';
-import { User } from '../../../models/user.model';
-import { ProfileService } from '../../../profile/services/profile.service';
-import { AuthService } from '../../../services/auth.service';
-import { StructureService } from '../../../services/structure.service';
-import { Utils } from '../../../utils/utils';
-
-type StructureClaim = { [structureId: string]: boolean };
-
-@Component({
-  selector: 'app-structure-details-wrapper',
-  templateUrl: './structure-details-wrapper.component.html',
-  styleUrls: ['./structure-details-wrapper.component.scss'],
-})
-export class StructureDetailsWrapperComponent implements OnInit {
-  @Input() public structure: Structure;
-  public lockdownInfoDisplay = false;
-  private _structureClaimsState: StructureClaim = {};
-  private _structureClaims: BehaviorSubject<StructureClaim> = new BehaviorSubject({});
-  public structureAdmins: Owner[] = [];
-  constructor(
-    private route: ActivatedRoute,
-    private structureService: StructureService,
-    private parametersService: ParametersService,
-    private profileService: ProfileService,
-    private authService: AuthService
-  ) {
-    this.parametersService.getParameters().subscribe((params) => {
-      this.lockdownInfoDisplay = params.lockdownInfoDisplay;
-    });
-  }
-
-  ngOnInit(): void {
-    this.route.queryParams.subscribe((queryParams) => {
-      if (queryParams.id) {
-        this.structureService.getStructure(queryParams.id).subscribe((structure) => {
-          this.structure = new Structure(structure);
-          this.initData();
-        });
-      }
-    });
-  }
-
-  async initData(): Promise<void> {
-    let currentProfile = null;
-    if (this.userIsLoggedIn()) {
-      currentProfile = await this.profileService.getProfile();
-      this.structureService.getStructureWithOwners(this.structure._id, currentProfile).subscribe((res) => {
-        this.structureAdmins = res.owners;
-      });
-    }
-    this.structure.isClaimed = await this.structureService.isClaimed(this.structure._id, currentProfile).toPromise();
-  }
-
-  public updateClaim(structureId: string, isClaim: boolean): void {
-    this._structureClaimsState[structureId] = isClaim;
-    this._structureClaims.next(this._structureClaimsState);
-  }
-
-  public userIsLoggedIn(): boolean {
-    return this.authService.isLoggedIn();
-  }
-
-  public displayJobEmployer(profile: User): string {
-    return new Utils().getJobEmployer(profile);
-  }
-}
diff --git a/src/app/structure/components/tcl-access/tcl-access.component.html b/src/app/structure/components/tcl-access/tcl-access.component.html
deleted file mode 100644
index e533fc43867ba908df20ad491137116dfa79a117..0000000000000000000000000000000000000000
--- a/src/app/structure/components/tcl-access/tcl-access.component.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<div
-  *ngIf="tclStopPoints.length"
-  fxLayout="column"
-  class="structure-details-block noSeparator"
-  fxLayoutAlign="baseline baseline"
->
-  <h2>Accès</h2>
-  <div fxLayout="column wrap" fxLayoutGap="24px">
-    <div *ngFor="let tclStop of tclStopPoints | slice: 0:3">
-      {{ tclStop.name }}
-      <div fxLayout="row wrap" fxLayoutGap="16px">
-        <p *ngFor="let sub of tclStop.subLines">
-          <app-svg-icon [type]="'tcl'" [icon]="sub" [iconClass]="'icon-75'"></app-svg-icon>
-        </p>
-        <p *ngFor="let tram of tclStop.tramLines">
-          <app-svg-icon [type]="'tcl'" [icon]="tram" [iconClass]="'icon-75'"></app-svg-icon>
-        </p>
-        <p *ngFor="let bus of tclStop.busLines">
-          <app-svg-icon [type]="'tcl'" [icon]="bus" [iconClass]="'icon-75'"></app-svg-icon>
-        </p>
-      </div>
-    </div>
-  </div>
-</div>
diff --git a/src/app/structure/components/tcl-access/tcl-access.component.ts b/src/app/structure/components/tcl-access/tcl-access.component.ts
deleted file mode 100644
index d28757a771cc978ee1b5470c488a93643ba53621..0000000000000000000000000000000000000000
--- a/src/app/structure/components/tcl-access/tcl-access.component.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { Component, Input, OnInit } from '@angular/core';
-import { Structure } from '@gouvfr-anct/mediation-numerique';
-import { TclService } from '../../../services/tcl.service';
-
-export class TclStopPoint {
-  public name: string;
-  public tramLines: string[];
-  public subLines: string[];
-  public busLines: string[];
-
-  constructor(obj?: any) {
-    Object.assign(this, obj);
-  }
-}
-
-@Component({
-  selector: 'app-tcl-access',
-  templateUrl: 'tcl-access.component.html',
-  styleUrls: ['../structure-details-wrapper/structure-details-wrapper.component.scss'],
-})
-export class TclAccessComponent implements OnInit {
-  @Input() public structure: Structure;
-
-  public tclStopPoints: TclStopPoint[] = [];
-
-  public constructor(private tclService: TclService) {}
-
-  public async ngOnInit(): Promise<void> {
-    this.getTclStopPoints();
-  }
-
-  public getTclStopPoints(): void {
-    this.tclService.getTclStopPointBycoord(this.structure.getLon(), this.structure.getLat()).subscribe((res) => {
-      this.tclStopPoints = res;
-    });
-  }
-}
diff --git a/src/app/structure/structure-exclude/structure-exclude.component.ts b/src/app/structure/structure-exclude/structure-exclude.component.ts
index 6bd574af8b6655c7e52d6a49f5cb7930c0dff560..3bdcc5685c7dc102e17a7d03b4a1a5b669409f31 100644
--- a/src/app/structure/structure-exclude/structure-exclude.component.ts
+++ b/src/app/structure/structure-exclude/structure-exclude.component.ts
@@ -1,10 +1,10 @@
 import { Component, OnInit } from '@angular/core';
-import { ActivatedRoute, Router } from '@angular/router';
-import { Structure } from '@gouvfr-anct/mediation-numerique';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
-import { NotificationService } from '../../services/notification.service';
+import { ButtonType } from '../../shared/components/button/buttonType.enum';
+import { Router, ActivatedRoute } from '@angular/router';
 import { StructureService } from '../../services/structure.service';
 import { UserService } from '../../services/user.service';
+import { NotificationService } from '../../services/notification.service';
+import { Structure } from '../../models/structure.model';
 
 @Component({
   selector: 'app-structure-exclude',
diff --git a/src/app/structure/structure-join/structure-join.component.ts b/src/app/structure/structure-join/structure-join.component.ts
index ac6971da6e9fd2762c052a22a3044c09c0cc712b..19093c82abf070301de48268044d4d3d88c8fd7e 100644
--- a/src/app/structure/structure-join/structure-join.component.ts
+++ b/src/app/structure/structure-join/structure-join.component.ts
@@ -1,9 +1,9 @@
 import { Component, OnInit } from '@angular/core';
 import { ActivatedRoute } from '@angular/router';
-import { ButtonType } from '@gouvfr-anct/mediation-numerique/shared';
 import { formType } from '../../form/form-view/formType.enum';
 import { structureFormStep } from '../../form/form-view/structure-form/structureFormStep.enum';
 import { RouterListenerService } from '../../services/routerListener.service';
+import { ButtonType } from '../../shared/components/button/buttonType.enum';
 @Component({
   selector: 'app-structure-join',
   templateUrl: './structure-join.component.html',
diff --git a/src/app/utils/formUtils.ts b/src/app/utils/formUtils.ts
index a32b44a60c4e8183ad51e1f6f5f5504e21d4f2f0..8eb7a98849e4669c86eb96f15af91b2e23b13707 100644
--- a/src/app/utils/formUtils.ts
+++ b/src/app/utils/formUtils.ts
@@ -1,6 +1,8 @@
 import { UntypedFormArray, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
-import { Day, Structure, Time } from '@gouvfr-anct/mediation-numerique';
 import { structureFormStep } from '../form/form-view/structure-form/structureFormStep.enum';
+import { Day } from '../models/day.model';
+import { Time } from '../models/time.model';
+import { Structure } from '../models/structure.model';
 import { CustomRegExp } from './CustomRegExp';
 
 export interface IStructureSummary {
@@ -82,13 +84,19 @@ export class formUtils {
         street: new UntypedFormControl(structure.address.street, Validators.required),
         commune: new UntypedFormControl(structure.address.commune, Validators.required),
       }),
-      contactMail: new UntypedFormControl(structure.contactMail === 'unknown@unknown.com' ? null : structure.contactMail, [
-        Validators.required,
-        Validators.pattern(CustomRegExp.EMAIL),
-      ]),
+      contactMail: new UntypedFormControl(
+        structure.contactMail === 'unknown@unknown.com' ? null : structure.contactMail,
+        [Validators.required, Validators.pattern(CustomRegExp.EMAIL)]
+      ),
       contactPhone: new UntypedFormControl(structure.contactPhone, [Validators.pattern(CustomRegExp.PHONE)]),
-      contactPersonFirstname: new UntypedFormControl(structure.contactPersonLastName, !isEditMode && Validators.required),
-      contactPersonLastname: new UntypedFormControl(structure.contactPersonLastName, !isEditMode && Validators.required),
+      contactPersonFirstname: new UntypedFormControl(
+        structure.contactPersonLastName,
+        !isEditMode && Validators.required
+      ),
+      contactPersonLastname: new UntypedFormControl(
+        structure.contactPersonLastName,
+        !isEditMode && Validators.required
+      ),
       contactPersonEmail: new UntypedFormControl(
         structure.contactPersonEmail,
         !isEditMode && [Validators.pattern(CustomRegExp.EMAIL), Validators.required]
@@ -126,18 +134,24 @@ export class formUtils {
           Validators.max(1000),
         ]
       ),
-      nbPrinters: new UntypedFormControl(structure.equipmentsAndServices.includes('imprimantes') ? structure.nbPrinters : 0, [
-        Validators.required,
-        Validators.pattern(CustomRegExp.NO_NEGATIVE_NUMBER),
-        Validators.min(0),
-        Validators.max(1000),
-      ]),
-      nbTablets: new UntypedFormControl(structure.equipmentsAndServices.includes('tablettes') ? structure.nbTablets : 0, [
-        Validators.required,
-        Validators.pattern(CustomRegExp.NO_NEGATIVE_NUMBER),
-        Validators.min(0),
-        Validators.max(1000),
-      ]),
+      nbPrinters: new UntypedFormControl(
+        structure.equipmentsAndServices.includes('imprimantes') ? structure.nbPrinters : 0,
+        [
+          Validators.required,
+          Validators.pattern(CustomRegExp.NO_NEGATIVE_NUMBER),
+          Validators.min(0),
+          Validators.max(1000),
+        ]
+      ),
+      nbTablets: new UntypedFormControl(
+        structure.equipmentsAndServices.includes('tablettes') ? structure.nbTablets : 0,
+        [
+          Validators.required,
+          Validators.pattern(CustomRegExp.NO_NEGATIVE_NUMBER),
+          Validators.min(0),
+          Validators.max(1000),
+        ]
+      ),
       nbNumericTerminal: new UntypedFormControl(
         structure.equipmentsAndServices.includes('bornesNumeriques') ? structure.nbNumericTerminal : 0,
         [
@@ -147,12 +161,15 @@ export class formUtils {
           Validators.max(1000),
         ]
       ),
-      nbScanners: new UntypedFormControl(structure.equipmentsAndServices.includes('scanners') ? structure.nbScanners : 0, [
-        Validators.required,
-        Validators.pattern(CustomRegExp.NO_NEGATIVE_NUMBER),
-        Validators.min(0),
-        Validators.max(1000),
-      ]),
+      nbScanners: new UntypedFormControl(
+        structure.equipmentsAndServices.includes('scanners') ? structure.nbScanners : 0,
+        [
+          Validators.required,
+          Validators.pattern(CustomRegExp.NO_NEGATIVE_NUMBER),
+          Validators.min(0),
+          Validators.max(1000),
+        ]
+      ),
       freeWorkShop: new UntypedFormControl(structure.freeWorkShop, [Validators.required]),
       dataShareConsentDate: new UntypedFormControl(structure.dataShareConsentDate),
       personalOffers: new UntypedFormControl(structure.personalOffers),
diff --git a/tsconfig.base.json b/tsconfig.base.json
deleted file mode 100644
index 1fb0d63f775580e464fd08754fe4e36740493046..0000000000000000000000000000000000000000
--- a/tsconfig.base.json
+++ /dev/null
@@ -1,19 +0,0 @@
-/* To learn more about this file see: https://angular.io/config/tsconfig. */
-{
-  "compileOnSave": false,
-  "compilerOptions": {
-    "baseUrl": "./",
-    "outDir": "./dist/out-tsc",
-    "sourceMap": true,
-    "declaration": false,
-    "downlevelIteration": true,
-    "experimentalDecorators": true,
-    "moduleResolution": "node",
-    "importHelpers": true,
-    "target": "es2015",
-    "module": "es2020",
-    "lib": ["es2018", "dom"],
-    "resolveJsonModule": true,
-    "esModuleInterop": true
-  }
-}
diff --git a/tsconfig.json b/tsconfig.json
index b8e7b47302e7cec88f60945eb2a2ca6717e7d4de..9a937470c1a287467538d83f95928792f6ea9506 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,9 +1,19 @@
-/* To learn more about this file see: https://angular.io/config/tsconfig. */
-{
-  "extends": "./tsconfig.base.json",
-  "compilerOptions": {
-    "paths": {
-      "@gouvfr-anct/*": ["dist/@gouvfr-anct/*"]
-    }
-  }
-}
+/* To learn more about this file see: https://angular.io/config/tsconfig. */
+{
+  "compileOnSave": false,
+  "compilerOptions": {
+    "baseUrl": "./",
+    "outDir": "./dist/out-tsc",
+    "sourceMap": true,
+    "declaration": false,
+    "downlevelIteration": true,
+    "experimentalDecorators": true,
+    "moduleResolution": "node",
+    "importHelpers": true,
+    "target": "es2015",
+    "module": "es2020",
+    "lib": ["es2018", "dom"],
+    "resolveJsonModule": true,
+    "esModuleInterop": true
+  }
+}
diff --git a/tsconfig.spec.json b/tsconfig.spec.json
index 28a3525e6b52ad2f3d74057e33030a4b2d19fbf9..1fde99220b26798b39cfc44013c710d00ef00853 100644
--- a/tsconfig.spec.json
+++ b/tsconfig.spec.json
@@ -1,10 +1,10 @@
-/* To learn more about this file see: https://angular.io/config/tsconfig. */
-{
-  "extends": "./tsconfig.json",
-  "compilerOptions": {
-    "outDir": "./out-tsc/spec",
-    "types": ["node", "jasmine", "jest"]
-  },
-  "files": ["src/test.ts", "src/polyfills.ts"],
-  "include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
-}
+/* To learn more about this file see: https://angular.io/config/tsconfig. */
+{
+  "extends": "./tsconfig.json",
+  "compilerOptions": {
+    "outDir": "./out-tsc/spec",
+    "types": ["node", "jasmine"]
+  },
+  "files": ["src/test.ts", "src/polyfills.ts"],
+  "include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
+}