Browse Source

Merge branch 'release/0.1.0'

Warafear 1 year ago
parent
commit
dc330c9aa4
84 changed files with 6222 additions and 1243 deletions
  1. 5 1
      .gitignore
  2. 1009 0
      .nx/cache/d/daemon.log
  3. 1 1
      .nx/cache/d/server-process.json
  4. 2493 1068
      package-lock.json
  5. 4 2
      package.json
  6. 52 6
      src/app/character/character-creator/character-creator.component.html
  7. 56 0
      src/app/character/character-creator/character-creator.component.scss
  8. 113 44
      src/app/character/character-creator/character-creator.component.ts
  9. 27 2
      src/app/character/character-picker/character-card/character-card.component.html
  10. 74 4
      src/app/character/character-picker/character-card/character-card.component.scss
  11. 36 3
      src/app/character/character-picker/character-card/character-card.component.ts
  12. 41 11
      src/app/character/character-picker/character-picker.component.html
  13. 71 5
      src/app/character/character-picker/character-picker.component.scss
  14. 34 14
      src/app/character/character-picker/character-picker.component.ts
  15. 7 0
      src/app/character/character-picker/deletion-confirm/deletion-confirm.component.html
  16. 7 0
      src/app/character/character-picker/deletion-confirm/deletion-confirm.component.scss
  17. 23 0
      src/app/character/character-picker/deletion-confirm/deletion-confirm.component.spec.ts
  18. 27 0
      src/app/character/character-picker/deletion-confirm/deletion-confirm.component.ts
  19. 14 1
      src/app/character/character.module.ts
  20. 1 0
      src/app/journal/journal-character/background/background.component.html
  21. 0 0
      src/app/journal/journal-character/background/background.component.scss
  22. 23 0
      src/app/journal/journal-character/background/background.component.spec.ts
  23. 10 0
      src/app/journal/journal-character/background/background.component.ts
  24. 17 0
      src/app/journal/journal-character/class/class.component.html
  25. 43 0
      src/app/journal/journal-character/class/class.component.scss
  26. 23 0
      src/app/journal/journal-character/class/class.component.spec.ts
  27. 23 0
      src/app/journal/journal-character/class/class.component.ts
  28. 143 0
      src/app/journal/journal-character/general/general.component.html
  29. 157 0
      src/app/journal/journal-character/general/general.component.scss
  30. 23 0
      src/app/journal/journal-character/general/general.component.spec.ts
  31. 45 0
      src/app/journal/journal-character/general/general.component.ts
  32. 75 14
      src/app/journal/journal-character/journal-character.component.html
  33. 101 0
      src/app/journal/journal-character/journal-character.component.scss
  34. 15 1
      src/app/journal/journal-character/journal-character.component.ts
  35. 18 0
      src/app/journal/journal-character/species/species.component.html
  36. 33 0
      src/app/journal/journal-character/species/species.component.scss
  37. 23 0
      src/app/journal/journal-character/species/species.component.spec.ts
  38. 21 0
      src/app/journal/journal-character/species/species.component.ts
  39. 1 0
      src/app/journal/journal-character/story/story.component.html
  40. 0 0
      src/app/journal/journal-character/story/story.component.scss
  41. 23 0
      src/app/journal/journal-character/story/story.component.spec.ts
  42. 10 0
      src/app/journal/journal-character/story/story.component.ts
  43. 17 0
      src/app/journal/journal-character/subclass/subclass.component.html
  44. 42 0
      src/app/journal/journal-character/subclass/subclass.component.scss
  45. 23 0
      src/app/journal/journal-character/subclass/subclass.component.spec.ts
  46. 46 0
      src/app/journal/journal-character/subclass/subclass.component.ts
  47. 2 2
      src/app/journal/journal-home/navigation-panel/navigation-panel.component.html
  48. 16 18
      src/app/journal/journal-home/navigation-panel/navigation-panel.component.scss
  49. 10 10
      src/app/journal/journal-stats/ability-panel/spellslots/spellslots.component.html
  50. 46 0
      src/app/journal/journal-stats/ability-panel/spellslots/spellslots.component.ts
  51. 8 5
      src/app/journal/journal-stats/life-container/life/life.component.html
  52. 55 15
      src/app/journal/journal-stats/life-container/life/life.component.scss
  53. 2 2
      src/app/journal/journal-stats/weapons-container/spell-table/spell-table.component.ts
  54. 18 1
      src/app/journal/journal.module.ts
  55. 0 1
      src/assets/icons/UIIcons/character.svg
  56. 1 0
      src/assets/icons/UIIcons/characters.svg
  57. 1 0
      src/assets/icons/UIIcons/damage.svg
  58. 1 0
      src/assets/icons/UIIcons/delete.svg
  59. 1 0
      src/assets/icons/UIIcons/heal.svg
  60. 1 0
      src/assets/icons/UIIcons/image.svg
  61. 0 1
      src/assets/icons/UIIcons/life-minus.svg
  62. 0 1
      src/assets/icons/UIIcons/life-plus.svg
  63. 0 1
      src/assets/icons/UIIcons/life-temporary.svg
  64. 1 1
      src/assets/icons/UIIcons/settings.svg
  65. 1 0
      src/assets/icons/UIIcons/temporary.svg
  66. 1 0
      src/assets/icons/UIIcons/upload.svg
  67. BIN
      src/assets/images/character_coming_soon.jpeg
  68. BIN
      src/assets/images/diverse.jpg
  69. BIN
      src/assets/images/eliane.jpg
  70. BIN
      src/assets/images/female.jpg
  71. BIN
      src/assets/images/male.jpg
  72. BIN
      src/assets/images/tel.jpg
  73. 16 0
      src/services/class/class.service.spec.ts
  74. 522 0
      src/services/class/class.service.ts
  75. 52 5
      src/services/data/data.service.ts
  76. 1 0
      src/services/modal/modal.service.ts
  77. 16 0
      src/services/species/species.service.spec.ts
  78. 124 0
      src/services/species/species.service.ts
  79. 29 0
      src/services/spells/spells.service.ts
  80. 16 0
      src/services/subclass/subclass.service.spec.ts
  81. 115 0
      src/services/subclass/subclass.service.ts
  82. 16 0
      src/services/translator/translator.service.spec.ts
  83. 77 0
      src/services/translator/translator.service.ts
  84. 23 3
      src/styles.scss

+ 5 - 1
.gitignore

@@ -19,7 +19,8 @@ yarn-error.log
 *.launch
 .settings/
 *.sublime-workspace
-*.nx
+.nx/cache/d/*
+/nx/cache/d/*
 
 # Visual Studio Code
 .vscode/*
@@ -41,3 +42,6 @@ testem.log
 # System files
 .DS_Store
 Thumbs.db
+
+.nx/cache/d/daemon.log
+.nx/cache/d/server-process.json

+ 1009 - 0
.nx/cache/d/daemon.log

@@ -461726,3 +461726,1012 @@ To fix this, set a unique name for each project in a project.json inside the pro
     at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
 [NX Daemon Server] - 2023-12-17T17:53:05.996Z - Time taken for 'hash changed files from watcher' 25.149699985980988ms
 [NX Daemon Server] - 2023-12-17T17:53:05.996Z - Done responding to the client null
+[NX Daemon Server] - 2023-12-19T07:59:24.558Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2023-12-19T07:59:24.562Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2023-12-19T07:59:24.571Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2023-12-19T07:59:24.573Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2023-12-19T07:59:24.573Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2023-12-19T07:59:24.574Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2023-12-19T07:59:25.238Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2023-12-19T07:59:25.238Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2023-12-19T07:59:25.239Z - Time taken for 'hash changed files from watcher' 28.08399999141693ms
+[NX Daemon Server] - 2023-12-19T07:59:25.240Z - Done responding to the client null
+[NX Daemon Server] - 2023-12-19T20:03:43.363Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2023-12-19T20:03:43.372Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2023-12-19T20:03:43.374Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2023-12-19T20:03:43.375Z - Established a connection. Number of open connections: 2
+[NX Daemon Server] - 2023-12-19T20:03:43.378Z - Closed a connection. Number of open connections: 1
+[NX Daemon Server] - 2023-12-19T20:03:43.381Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2023-12-19T20:03:44.296Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2023-12-19T20:03:44.296Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2023-12-19T20:03:44.297Z - Time taken for 'hash changed files from watcher' 15.42689996957779ms
+[NX Daemon Server] - 2023-12-19T20:03:44.298Z - Done responding to the client null
+[NX Daemon Server] - 2023-12-21T06:46:19.463Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2023-12-21T06:46:19.475Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2023-12-21T06:46:19.479Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2023-12-21T06:46:19.480Z - Established a connection. Number of open connections: 2
+[NX Daemon Server] - 2023-12-21T06:46:19.483Z - Closed a connection. Number of open connections: 1
+[NX Daemon Server] - 2023-12-21T06:46:19.493Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2023-12-21T06:46:20.210Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2023-12-21T06:46:20.210Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2023-12-21T06:46:20.212Z - Time taken for 'hash changed files from watcher' 37.13029992580414ms
+[NX Daemon Server] - 2023-12-21T06:46:20.212Z - Done responding to the client null
+[NX Daemon Server] - 2023-12-21T06:48:27.122Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2023-12-21T06:48:27.126Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2023-12-21T06:48:27.128Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2023-12-21T06:48:27.131Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2023-12-21T06:48:27.131Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2023-12-21T06:48:27.133Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2023-12-21T06:48:27.260Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2023-12-21T06:48:27.261Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2023-12-21T06:48:27.263Z - Time taken for 'hash changed files from watcher' 39.510900020599365ms
+[NX Daemon Server] - 2023-12-21T06:48:27.263Z - Done responding to the client null
+[NX Daemon Server] - 2023-12-21T16:53:22.581Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2023-12-21T16:53:22.586Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2023-12-21T16:53:22.587Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2023-12-21T16:53:22.588Z - Established a connection. Number of open connections: 2
+[NX Daemon Server] - 2023-12-21T16:53:22.590Z - Closed a connection. Number of open connections: 1
+[NX Daemon Server] - 2023-12-21T16:53:22.592Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2023-12-21T16:53:22.712Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2023-12-21T16:53:22.712Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2023-12-21T16:53:22.714Z - Time taken for 'hash changed files from watcher' 26.250100016593933ms
+[NX Daemon Server] - 2023-12-21T16:53:22.715Z - Done responding to the client null
+[NX Daemon Server] - 2023-12-22T06:49:44.576Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2023-12-22T06:49:44.582Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2023-12-22T06:49:44.585Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2023-12-22T06:49:44.587Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2023-12-22T06:49:44.587Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2023-12-22T06:49:44.588Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2023-12-22T06:49:45.567Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2023-12-22T06:49:45.567Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2023-12-22T06:49:45.568Z - Time taken for 'hash changed files from watcher' 6.833899974822998ms
+[NX Daemon Server] - 2023-12-22T06:49:45.569Z - Done responding to the client null
+[NX Daemon Server] - 2023-12-23T10:49:53.739Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2023-12-23T10:49:53.799Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2023-12-23T10:49:53.848Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2023-12-23T10:49:53.861Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2023-12-23T10:49:53.862Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2023-12-23T10:49:53.873Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2023-12-23T10:50:00.829Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2023-12-23T10:50:00.831Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2023-12-23T10:50:00.859Z - Time taken for 'hash changed files from watcher' 41.45780003070831ms
+[NX Daemon Server] - 2023-12-23T10:50:00.867Z - Done responding to the client null
+[NX Daemon Server] - 2023-12-27T11:41:17.309Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2023-12-27T11:41:17.313Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2023-12-27T11:41:17.332Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2023-12-27T11:41:17.334Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2023-12-27T11:41:17.335Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2023-12-27T11:41:17.337Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2023-12-27T11:41:18.261Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2023-12-27T11:41:18.261Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2023-12-27T11:41:18.263Z - Time taken for 'hash changed files from watcher' 19.6149001121521ms
+[NX Daemon Server] - 2023-12-27T11:41:18.263Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-04T06:51:00.725Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-04T06:51:00.732Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-04T06:51:00.744Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-04T06:51:00.746Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2024-01-04T06:51:00.746Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-04T06:51:00.748Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-04T06:51:01.346Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-04T06:51:01.346Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-04T06:51:01.347Z - Time taken for 'hash changed files from watcher' 51.083799839019775ms
+[NX Daemon Server] - 2024-01-04T06:51:01.348Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-05T06:57:17.805Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-05T06:57:17.809Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-05T06:57:17.810Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-05T06:57:17.811Z - Established a connection. Number of open connections: 2
+[NX Daemon Server] - 2024-01-05T06:57:17.812Z - Closed a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-05T06:57:17.813Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-05T06:57:18.318Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-05T06:57:18.318Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-05T06:57:18.319Z - Time taken for 'hash changed files from watcher' 41.231199979782104ms
+[NX Daemon Server] - 2024-01-05T06:57:18.320Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-08T06:52:32.014Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-08T06:52:32.017Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-08T07:10:37.293Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-08T07:10:37.295Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2024-01-08T07:10:37.295Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-08T07:10:37.304Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-08T07:10:38.186Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-08T07:10:38.187Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-08T07:10:38.189Z - Time taken for 'hash changed files from watcher' 1.509899616241455ms
+[NX Daemon Server] - 2024-01-08T07:10:38.190Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-09T09:03:38.264Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-09T09:03:38.267Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-09T09:03:38.278Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-09T09:03:38.279Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2024-01-09T09:03:38.280Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-09T09:03:38.281Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-09T09:03:38.949Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-09T09:03:38.949Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-09T09:03:38.951Z - Time taken for 'hash changed files from watcher' 15.533100128173828ms
+[NX Daemon Server] - 2024-01-09T09:03:38.951Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-12T06:51:44.854Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-12T06:51:44.857Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-12T06:51:44.861Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-12T06:51:44.863Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2024-01-12T06:51:44.864Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-12T06:51:44.866Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-12T06:51:45.652Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-12T06:51:45.652Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-12T06:51:45.654Z - Time taken for 'hash changed files from watcher' 18.79670000076294ms
+[NX Daemon Server] - 2024-01-12T06:51:45.654Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-12T08:54:53.951Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-12T08:54:53.956Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-12T08:54:53.958Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-12T08:54:53.960Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2024-01-12T08:54:53.960Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-12T08:54:53.962Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-12T08:54:54.838Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-12T08:54:54.838Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-12T08:54:54.839Z - Time taken for 'hash changed files from watcher' 43.397900104522705ms
+[NX Daemon Server] - 2024-01-12T08:54:54.840Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-13T08:50:08.268Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-13T08:50:08.272Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-13T08:50:08.274Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-13T08:50:08.276Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2024-01-13T08:50:08.276Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-13T08:50:08.278Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-13T08:50:08.807Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-13T08:50:08.807Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-13T08:50:08.809Z - Time taken for 'hash changed files from watcher' 43.34740000002785ms
+[NX Daemon Server] - 2024-01-13T08:50:08.809Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-13T11:42:37.268Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-13T11:42:37.272Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-13T11:42:37.283Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-13T11:42:37.295Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2024-01-13T11:42:37.295Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-13T11:42:37.307Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-13T11:42:37.854Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-13T11:42:37.855Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-13T11:42:37.856Z - Time taken for 'hash changed files from watcher' 48.85109999962151ms
+[NX Daemon Server] - 2024-01-13T11:42:37.857Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-15T16:14:40.922Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-15T16:14:40.925Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-15T16:14:40.933Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-15T16:14:40.935Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2024-01-15T16:14:40.935Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-15T16:14:40.937Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-15T16:14:41.712Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-15T16:14:41.713Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-15T16:14:41.714Z - Time taken for 'hash changed files from watcher' 51.3518999999942ms
+[NX Daemon Server] - 2024-01-15T16:14:41.714Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-16T06:25:33.169Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-16T06:25:33.173Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-16T06:25:33.177Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-16T06:25:33.179Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2024-01-16T06:25:33.179Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-16T06:25:33.182Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-16T06:25:33.675Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-16T06:25:33.675Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-16T06:25:33.676Z - Time taken for 'hash changed files from watcher' 15.80629999935627ms
+[NX Daemon Server] - 2024-01-16T06:25:33.676Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-17T16:54:49.384Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-17T16:54:49.393Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-17T16:54:49.394Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-17T16:54:49.395Z - Established a connection. Number of open connections: 2
+[NX Daemon Server] - 2024-01-17T16:54:49.396Z - Closed a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-17T16:54:49.398Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-17T16:54:50.146Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-17T16:54:50.146Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-17T16:54:50.147Z - Time taken for 'hash changed files from watcher' 36.4316000000108ms
+[NX Daemon Server] - 2024-01-17T16:54:50.148Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-18T14:42:11.819Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-18T14:42:11.824Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-18T14:42:11.826Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-18T14:42:11.827Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2024-01-18T14:42:11.827Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-18T14:42:11.829Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-18T14:42:11.978Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-18T14:42:11.979Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-18T14:42:11.980Z - Time taken for 'hash changed files from watcher' 62.82770000398159ms
+[NX Daemon Server] - 2024-01-18T14:42:11.980Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-19T18:24:40.739Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-19T18:24:40.743Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-19T18:24:40.754Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-19T18:24:40.756Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2024-01-19T18:24:40.756Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-19T18:24:40.758Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-19T18:24:41.390Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-19T18:24:41.390Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-19T18:24:41.391Z - Time taken for 'hash changed files from watcher' 12.50719999987632ms
+[NX Daemon Server] - 2024-01-19T18:24:41.391Z - [WATCHER]: Processing file changes in outputs
+[NX Daemon Server] - 2024-01-19T18:24:41.392Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-19T18:26:37.974Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-19T18:26:37.980Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-19T18:26:37.982Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-19T18:26:37.984Z - Established a connection. Number of open connections: 2
+[NX Daemon Server] - 2024-01-19T18:26:37.988Z - Closed a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-19T18:26:37.990Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-19T18:26:38.092Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-19T18:26:38.092Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-19T18:26:38.096Z - Time taken for 'hash changed files from watcher' 17.971000000368804ms
+[NX Daemon Server] - 2024-01-19T18:26:38.099Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-19T18:26:38.457Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-19T18:26:38.462Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-19T18:26:38.464Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-19T18:26:38.467Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2024-01-19T18:26:38.468Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-19T18:26:38.471Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-19T18:26:38.628Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-19T18:26:38.628Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-19T18:26:38.630Z - Time taken for 'hash changed files from watcher' 67.50439999997616ms
+[NX Daemon Server] - 2024-01-19T18:26:38.630Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-19T18:26:40.338Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-19T18:26:40.341Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-19T18:26:40.343Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-19T18:26:40.345Z - Established a connection. Number of open connections: 2
+[NX Daemon Server] - 2024-01-19T18:26:40.348Z - Closed a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-19T18:26:40.351Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-19T18:26:40.460Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-19T18:26:40.461Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-19T18:26:40.463Z - Time taken for 'hash changed files from watcher' 21.03759999992326ms
+[NX Daemon Server] - 2024-01-19T18:26:40.466Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-19T18:32:37.366Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-19T18:32:37.368Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-19T18:32:37.371Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-19T18:32:37.374Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2024-01-19T18:32:37.374Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-19T18:32:37.375Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-19T18:32:37.453Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-19T18:32:37.453Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-19T18:32:37.454Z - Time taken for 'hash changed files from watcher' 26.98909999988973ms
+[NX Daemon Server] - 2024-01-19T18:32:37.455Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-19T18:32:38.771Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-19T18:32:38.774Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-19T18:32:38.776Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-19T18:32:38.778Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2024-01-19T18:32:38.778Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-19T18:32:38.780Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-19T18:32:38.873Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-19T18:32:38.873Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-19T18:32:38.874Z - Time taken for 'hash changed files from watcher' 43.67879999987781ms
+[NX Daemon Server] - 2024-01-19T18:32:38.876Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-19T18:32:47.482Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-19T18:32:47.486Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-19T18:32:47.499Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-19T18:32:47.502Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2024-01-19T18:32:47.502Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-19T18:32:47.503Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-19T18:32:47.566Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-19T18:32:47.566Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-19T18:32:47.568Z - Time taken for 'hash changed files from watcher' 11.379799999762326ms
+[NX Daemon Server] - 2024-01-19T18:32:47.568Z - Done responding to the client null
+[NX Daemon Server] - 2024-01-19T18:32:48.798Z - Started listening on: \\.\pipe\nx\C:\Users\chris\AppData\Local\Temp\83d14e7134fc08a15480\d.sock
+[NX Daemon Server] - 2024-01-19T18:32:48.801Z - [WATCHER]: Subscribed to changes within: c:\Softwareprojekte\DnD (native)
+[NX Daemon Server] - 2024-01-19T18:32:48.813Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-19T18:32:48.815Z - Closed a connection. Number of open connections: 0
+[NX Daemon Server] - 2024-01-19T18:32:48.815Z - Established a connection. Number of open connections: 1
+[NX Daemon Server] - 2024-01-19T18:32:48.817Z - [REQUEST]: Client Request for Project Graph Received
+[NX Daemon Server] - 2024-01-19T18:32:48.887Z - Error detected when recomputing project file map: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+[NX Daemon Server] - 2024-01-19T18:32:48.888Z - [REQUEST]: Responding to the client with an error. Error when preparing serialized project graph. The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+Error: The following projects are defined in multiple locations:
+- DnDTools: 
+  - 
+  - .
+
+To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.
+    at readProjectConfigurationsFromRootMap (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:97:15)
+    at buildProjectsConfigurationsFromProjectPathsAndPlugins (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\project-configuration-utils.js:70:19)
+    at createProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:131:129)
+    at WorkspaceContext.<anonymous> (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:82:39)
+    at getProjectConfigurationsFromContext (c:\Softwareprojekte\DnD\node_modules\nx\src\utils\workspace-context.js:26:29)
+    at _retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:81:72)
+    at retrieveProjectConfigurations (c:\Softwareprojekte\DnD\node_modules\nx\src\project-graph\utils\retrieve-workspace-files.js:58:12)
+    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
+    at async processCollectedUpdatedAndDeletedFiles (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:102:34)
+    at async processFilesAndCreateAndSerializeProjectGraph (c:\Softwareprojekte\DnD\node_modules\nx\src\daemon\server\project-graph-incremental-recomputation.js:138:17)
+[NX Daemon Server] - 2024-01-19T18:32:48.889Z - Time taken for 'hash changed files from watcher' 25.820900000166148ms
+[NX Daemon Server] - 2024-01-19T18:32:48.890Z - Done responding to the client null

+ 1 - 1
.nx/cache/d/server-process.json

@@ -1 +1 @@
-{"processId":16860}
+{"processId":14664}

+ 2493 - 1068
package-lock.json

@@ -22,6 +22,8 @@
         "@popperjs/core": "^2.11.6",
         "bootstrap": "^5.2.3",
         "localbase": "^0.7.5",
+        "marked": "^9.0.0",
+        "ngx-markdown": "^17.1.1",
         "rxjs": "~7.8.0",
         "tslib": "^2.3.0",
         "zone.js": "~0.14.2"
@@ -2446,6 +2448,12 @@
       "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
       "dev": true
     },
+    "node_modules/@braintree/sanitize-url": {
+      "version": "6.0.4",
+      "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz",
+      "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==",
+      "optional": true
+    },
     "node_modules/@colors/colors": {
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
@@ -7789,6 +7797,36 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@types/d3-scale": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz",
+      "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==",
+      "optional": true,
+      "dependencies": {
+        "@types/d3-time": "*"
+      }
+    },
+    "node_modules/@types/d3-scale-chromatic": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz",
+      "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==",
+      "optional": true
+    },
+    "node_modules/@types/d3-time": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz",
+      "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==",
+      "optional": true
+    },
+    "node_modules/@types/debug": {
+      "version": "4.1.12",
+      "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
+      "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
+      "optional": true,
+      "dependencies": {
+        "@types/ms": "*"
+      }
+    },
     "node_modules/@types/eslint": {
       "version": "8.44.6",
       "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.6.tgz",
@@ -7899,12 +7937,27 @@
       "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==",
       "dev": true
     },
+    "node_modules/@types/mdast": {
+      "version": "3.0.15",
+      "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz",
+      "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==",
+      "optional": true,
+      "dependencies": {
+        "@types/unist": "^2"
+      }
+    },
     "node_modules/@types/mime": {
       "version": "1.3.4",
       "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.4.tgz",
       "integrity": "sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw==",
       "dev": true
     },
+    "node_modules/@types/ms": {
+      "version": "0.7.34",
+      "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz",
+      "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==",
+      "optional": true
+    },
     "node_modules/@types/node": {
       "version": "20.8.8",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.8.tgz",
@@ -7989,6 +8042,12 @@
       "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
       "dev": true
     },
+    "node_modules/@types/unist": {
+      "version": "2.0.10",
+      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz",
+      "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==",
+      "optional": true
+    },
     "node_modules/@types/ws": {
       "version": "8.5.8",
       "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.8.tgz",
@@ -9944,6 +10003,16 @@
         "node": ">=10"
       }
     },
+    "node_modules/character-entities": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
+      "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
+      "optional": true,
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
     "node_modules/chardet": {
       "version": "0.7.0",
       "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
@@ -10057,6 +10126,17 @@
         "node": ">= 12"
       }
     },
+    "node_modules/clipboard": {
+      "version": "2.0.11",
+      "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.11.tgz",
+      "integrity": "sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==",
+      "optional": true,
+      "dependencies": {
+        "good-listener": "^1.2.2",
+        "select": "^1.1.2",
+        "tiny-emitter": "^2.0.0"
+      }
+    },
     "node_modules/cliui": {
       "version": "8.0.1",
       "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
@@ -10412,6 +10492,15 @@
         "node": ">= 0.4.0"
       }
     },
+    "node_modules/cose-base": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz",
+      "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==",
+      "optional": true,
+      "dependencies": {
+        "layout-base": "^1.0.0"
+      }
+    },
     "node_modules/cosmiconfig": {
       "version": "8.3.6",
       "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
@@ -10864,1278 +10953,1863 @@
       "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==",
       "dev": true
     },
-    "node_modules/date-format": {
-      "version": "4.0.14",
-      "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz",
-      "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==",
-      "dev": true,
+    "node_modules/cytoscape": {
+      "version": "3.28.1",
+      "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.28.1.tgz",
+      "integrity": "sha512-xyItz4O/4zp9/239wCcH8ZcFuuZooEeF8KHRmzjDfGdXsj3OG9MFSMA0pJE0uX3uCN/ygof6hHf4L7lst+JaDg==",
+      "optional": true,
+      "dependencies": {
+        "heap": "^0.2.6",
+        "lodash": "^4.17.21"
+      },
       "engines": {
-        "node": ">=4.0"
+        "node": ">=0.10"
       }
     },
-    "node_modules/debug": {
-      "version": "4.3.4",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
-      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+    "node_modules/cytoscape-cose-bilkent": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz",
+      "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==",
+      "optional": true,
       "dependencies": {
-        "ms": "2.1.2"
-      },
-      "engines": {
-        "node": ">=6.0"
+        "cose-base": "^1.0.0"
       },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
+      "peerDependencies": {
+        "cytoscape": "^3.2.0"
       }
     },
-    "node_modules/deep-is": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
-      "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
-      "dev": true,
-      "peer": true
+    "node_modules/cytoscape-fcose": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz",
+      "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==",
+      "optional": true,
+      "dependencies": {
+        "cose-base": "^2.2.0"
+      },
+      "peerDependencies": {
+        "cytoscape": "^3.2.0"
+      }
     },
-    "node_modules/deepmerge": {
-      "version": "4.3.1",
-      "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
-      "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
+    "node_modules/cytoscape-fcose/node_modules/cose-base": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz",
+      "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==",
+      "optional": true,
+      "dependencies": {
+        "layout-base": "^2.0.0"
       }
     },
-    "node_modules/default-gateway": {
-      "version": "6.0.3",
-      "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz",
-      "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==",
-      "dev": true,
+    "node_modules/cytoscape-fcose/node_modules/layout-base": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz",
+      "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==",
+      "optional": true
+    },
+    "node_modules/d3": {
+      "version": "7.8.5",
+      "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz",
+      "integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==",
+      "optional": true,
       "dependencies": {
-        "execa": "^5.0.0"
+        "d3-array": "3",
+        "d3-axis": "3",
+        "d3-brush": "3",
+        "d3-chord": "3",
+        "d3-color": "3",
+        "d3-contour": "4",
+        "d3-delaunay": "6",
+        "d3-dispatch": "3",
+        "d3-drag": "3",
+        "d3-dsv": "3",
+        "d3-ease": "3",
+        "d3-fetch": "3",
+        "d3-force": "3",
+        "d3-format": "3",
+        "d3-geo": "3",
+        "d3-hierarchy": "3",
+        "d3-interpolate": "3",
+        "d3-path": "3",
+        "d3-polygon": "3",
+        "d3-quadtree": "3",
+        "d3-random": "3",
+        "d3-scale": "4",
+        "d3-scale-chromatic": "3",
+        "d3-selection": "3",
+        "d3-shape": "3",
+        "d3-time": "3",
+        "d3-time-format": "4",
+        "d3-timer": "3",
+        "d3-transition": "3",
+        "d3-zoom": "3"
       },
       "engines": {
-        "node": ">= 10"
+        "node": ">=12"
       }
     },
-    "node_modules/defaults": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
-      "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
-      "dev": true,
+    "node_modules/d3-array": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
+      "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
+      "optional": true,
       "dependencies": {
-        "clone": "^1.0.2"
+        "internmap": "1 - 2"
       },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+      "engines": {
+        "node": ">=12"
       }
     },
-    "node_modules/define-data-property": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz",
-      "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==",
-      "dev": true,
+    "node_modules/d3-axis": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz",
+      "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==",
+      "optional": true,
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-brush": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz",
+      "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==",
+      "optional": true,
       "dependencies": {
-        "get-intrinsic": "^1.2.1",
-        "gopd": "^1.0.1",
-        "has-property-descriptors": "^1.0.0"
+        "d3-dispatch": "1 - 3",
+        "d3-drag": "2 - 3",
+        "d3-interpolate": "1 - 3",
+        "d3-selection": "3",
+        "d3-transition": "3"
       },
       "engines": {
-        "node": ">= 0.4"
+        "node": ">=12"
       }
     },
-    "node_modules/define-lazy-prop": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
-      "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
-      "dev": true,
+    "node_modules/d3-chord": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz",
+      "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==",
+      "optional": true,
+      "dependencies": {
+        "d3-path": "1 - 3"
+      },
       "engines": {
-        "node": ">=8"
+        "node": ">=12"
       }
     },
-    "node_modules/delayed-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
-      "dev": true,
+    "node_modules/d3-color": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
+      "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
+      "optional": true,
       "engines": {
-        "node": ">=0.4.0"
+        "node": ">=12"
       }
     },
-    "node_modules/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,
+    "node_modules/d3-contour": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz",
+      "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==",
+      "optional": true,
+      "dependencies": {
+        "d3-array": "^3.2.0"
+      },
       "engines": {
-        "node": ">= 0.8"
+        "node": ">=12"
       }
     },
-    "node_modules/destroy": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
-      "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
-      "dev": true,
+    "node_modules/d3-delaunay": {
+      "version": "6.0.4",
+      "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz",
+      "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==",
+      "optional": true,
+      "dependencies": {
+        "delaunator": "5"
+      },
       "engines": {
-        "node": ">= 0.8",
-        "npm": "1.2.8000 || >= 1.4.16"
+        "node": ">=12"
       }
     },
-    "node_modules/detect-newline": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
-      "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
-      "dev": true,
+    "node_modules/d3-dispatch": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
+      "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==",
+      "optional": true,
       "engines": {
-        "node": ">=8"
+        "node": ">=12"
       }
     },
-    "node_modules/detect-node": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
-      "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
-      "dev": true
-    },
-    "node_modules/detect-port": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz",
-      "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==",
-      "dev": true,
+    "node_modules/d3-drag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz",
+      "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",
+      "optional": true,
       "dependencies": {
-        "address": "^1.0.1",
-        "debug": "4"
+        "d3-dispatch": "1 - 3",
+        "d3-selection": "3"
       },
-      "bin": {
-        "detect": "bin/detect-port.js",
-        "detect-port": "bin/detect-port.js"
+      "engines": {
+        "node": ">=12"
       }
     },
-    "node_modules/dev-ip": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz",
-      "integrity": "sha512-LmVkry/oDShEgSZPNgqCIp2/TlqtExeGmymru3uCELnfyjY11IzpAproLYs+1X88fXO6DBoYP3ul2Xo2yz2j6A==",
-      "dev": true,
+    "node_modules/d3-dsv": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz",
+      "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==",
+      "optional": true,
+      "dependencies": {
+        "commander": "7",
+        "iconv-lite": "0.6",
+        "rw": "1"
+      },
       "bin": {
-        "dev-ip": "lib/dev-ip.js"
+        "csv2json": "bin/dsv2json.js",
+        "csv2tsv": "bin/dsv2dsv.js",
+        "dsv2dsv": "bin/dsv2dsv.js",
+        "dsv2json": "bin/dsv2json.js",
+        "json2csv": "bin/json2dsv.js",
+        "json2dsv": "bin/json2dsv.js",
+        "json2tsv": "bin/json2dsv.js",
+        "tsv2csv": "bin/dsv2dsv.js",
+        "tsv2json": "bin/dsv2json.js"
       },
       "engines": {
-        "node": ">= 0.8.0"
+        "node": ">=12"
       }
     },
-    "node_modules/di": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz",
-      "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==",
-      "dev": true
+    "node_modules/d3-dsv/node_modules/commander": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+      "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+      "optional": true,
+      "engines": {
+        "node": ">= 10"
+      }
     },
-    "node_modules/diff": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
-      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
-      "dev": true,
+    "node_modules/d3-dsv/node_modules/iconv-lite": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+      "optional": true,
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
+      },
       "engines": {
-        "node": ">=0.3.1"
+        "node": ">=0.10.0"
       }
     },
-    "node_modules/diff-sequences": {
-      "version": "29.6.3",
-      "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
-      "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
-      "dev": true,
+    "node_modules/d3-ease": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
+      "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
+      "optional": true,
       "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+        "node": ">=12"
       }
     },
-    "node_modules/dir-glob": {
+    "node_modules/d3-fetch": {
       "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
-      "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
-      "dev": true,
+      "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz",
+      "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==",
+      "optional": true,
       "dependencies": {
-        "path-type": "^4.0.0"
+        "d3-dsv": "1 - 3"
       },
       "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/dns-equal": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
-      "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==",
-      "dev": true
-    },
-    "node_modules/dns-packet": {
-      "version": "5.6.1",
-      "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
-      "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==",
-      "dev": true,
-      "dependencies": {
-        "@leichtgewicht/ip-codec": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=6"
+        "node": ">=12"
       }
     },
-    "node_modules/doctrine": {
+    "node_modules/d3-force": {
       "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
-      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
-      "dev": true,
-      "peer": true,
+      "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz",
+      "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==",
+      "optional": true,
       "dependencies": {
-        "esutils": "^2.0.2"
+        "d3-dispatch": "1 - 3",
+        "d3-quadtree": "1 - 3",
+        "d3-timer": "1 - 3"
       },
       "engines": {
-        "node": ">=6.0.0"
+        "node": ">=12"
       }
     },
-    "node_modules/dom-serialize": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz",
-      "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==",
-      "dev": true,
-      "dependencies": {
-        "custom-event": "~1.0.0",
-        "ent": "~2.2.0",
-        "extend": "^3.0.0",
-        "void-elements": "^2.0.0"
+    "node_modules/d3-format": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
+      "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
+      "optional": true,
+      "engines": {
+        "node": ">=12"
       }
     },
-    "node_modules/dom-serializer": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
-      "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
-      "dev": true,
+    "node_modules/d3-geo": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz",
+      "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==",
+      "optional": true,
       "dependencies": {
-        "domelementtype": "^2.3.0",
-        "domhandler": "^5.0.2",
-        "entities": "^4.2.0"
+        "d3-array": "2.5.0 - 3"
       },
-      "funding": {
-        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+      "engines": {
+        "node": ">=12"
       }
     },
-    "node_modules/domelementtype": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
-      "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/fb55"
-        }
-      ]
+    "node_modules/d3-hierarchy": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz",
+      "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==",
+      "optional": true,
+      "engines": {
+        "node": ">=12"
+      }
     },
-    "node_modules/domhandler": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
-      "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
-      "dev": true,
+    "node_modules/d3-interpolate": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
+      "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
+      "optional": true,
       "dependencies": {
-        "domelementtype": "^2.3.0"
+        "d3-color": "1 - 3"
       },
       "engines": {
-        "node": ">= 4"
-      },
-      "funding": {
-        "url": "https://github.com/fb55/domhandler?sponsor=1"
+        "node": ">=12"
       }
     },
-    "node_modules/domutils": {
+    "node_modules/d3-path": {
       "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
-      "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
-      "dev": true,
-      "dependencies": {
-        "dom-serializer": "^2.0.0",
-        "domelementtype": "^2.3.0",
-        "domhandler": "^5.0.3"
-      },
-      "funding": {
-        "url": "https://github.com/fb55/domutils?sponsor=1"
+      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
+      "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
+      "optional": true,
+      "engines": {
+        "node": ">=12"
       }
     },
-    "node_modules/dotenv": {
-      "version": "16.3.1",
-      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
-      "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==",
-      "dev": true,
+    "node_modules/d3-polygon": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz",
+      "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==",
+      "optional": true,
       "engines": {
         "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/motdotla/dotenv?sponsor=1"
       }
     },
-    "node_modules/dotenv-expand": {
-      "version": "10.0.0",
-      "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz",
-      "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==",
-      "dev": true,
+    "node_modules/d3-quadtree": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz",
+      "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==",
+      "optional": true,
       "engines": {
         "node": ">=12"
       }
     },
-    "node_modules/duplexer": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
-      "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
-      "dev": true
+    "node_modules/d3-random": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz",
+      "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==",
+      "optional": true,
+      "engines": {
+        "node": ">=12"
+      }
     },
-    "node_modules/eastasianwidth": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
-      "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
-      "dev": true
+    "node_modules/d3-sankey": {
+      "version": "0.12.3",
+      "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz",
+      "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==",
+      "optional": true,
+      "dependencies": {
+        "d3-array": "1 - 2",
+        "d3-shape": "^1.2.0"
+      }
     },
-    "node_modules/easy-extender": {
-      "version": "2.3.4",
-      "resolved": "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.4.tgz",
-      "integrity": "sha512-8cAwm6md1YTiPpOvDULYJL4ZS6WfM5/cTeVVh4JsvyYZAoqlRVUpHL9Gr5Fy7HA6xcSZicUia3DeAgO3Us8E+Q==",
-      "dev": true,
+    "node_modules/d3-sankey/node_modules/d3-array": {
+      "version": "2.12.1",
+      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",
+      "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
+      "optional": true,
       "dependencies": {
-        "lodash": "^4.17.10"
+        "internmap": "^1.0.0"
+      }
+    },
+    "node_modules/d3-sankey/node_modules/d3-path": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
+      "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==",
+      "optional": true
+    },
+    "node_modules/d3-sankey/node_modules/d3-shape": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz",
+      "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",
+      "optional": true,
+      "dependencies": {
+        "d3-path": "1"
+      }
+    },
+    "node_modules/d3-sankey/node_modules/internmap": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz",
+      "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==",
+      "optional": true
+    },
+    "node_modules/d3-scale": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
+      "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
+      "optional": true,
+      "dependencies": {
+        "d3-array": "2.10.0 - 3",
+        "d3-format": "1 - 3",
+        "d3-interpolate": "1.2.0 - 3",
+        "d3-time": "2.1.1 - 3",
+        "d3-time-format": "2 - 4"
       },
       "engines": {
-        "node": ">= 4.0.0"
+        "node": ">=12"
       }
     },
-    "node_modules/eazy-logger": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-4.0.1.tgz",
-      "integrity": "sha512-2GSFtnnC6U4IEKhEI7+PvdxrmjJ04mdsj3wHZTFiw0tUtG4HCWzTr13ZYTk8XOGnA1xQMaDljoBOYlk3D/MMSw==",
-      "dev": true,
+    "node_modules/d3-scale-chromatic": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz",
+      "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==",
+      "optional": true,
       "dependencies": {
-        "chalk": "4.1.2"
+        "d3-color": "1 - 3",
+        "d3-interpolate": "1 - 3"
       },
       "engines": {
-        "node": ">= 0.8.0"
+        "node": ">=12"
       }
     },
-    "node_modules/eazy-logger/node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "dev": true,
+    "node_modules/d3-selection": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
+      "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
+      "optional": true,
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-shape": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
+      "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
+      "optional": true,
       "dependencies": {
-        "color-convert": "^2.0.1"
+        "d3-path": "^3.1.0"
       },
       "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+        "node": ">=12"
       }
     },
-    "node_modules/eazy-logger/node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-      "dev": true,
+    "node_modules/d3-time": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
+      "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
+      "optional": true,
       "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
+        "d3-array": "2 - 3"
       },
       "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
+        "node": ">=12"
       }
     },
-    "node_modules/eazy-logger/node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dev": true,
+    "node_modules/d3-time-format": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
+      "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
+      "optional": true,
       "dependencies": {
-        "color-name": "~1.1.4"
+        "d3-time": "1 - 3"
       },
       "engines": {
-        "node": ">=7.0.0"
+        "node": ">=12"
       }
     },
-    "node_modules/eazy-logger/node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "dev": true
-    },
-    "node_modules/eazy-logger/node_modules/has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "dev": true,
+    "node_modules/d3-timer": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
+      "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
+      "optional": true,
       "engines": {
-        "node": ">=8"
+        "node": ">=12"
       }
     },
-    "node_modules/eazy-logger/node_modules/supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-      "dev": true,
+    "node_modules/d3-transition": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz",
+      "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",
+      "optional": true,
       "dependencies": {
-        "has-flag": "^4.0.0"
+        "d3-color": "1 - 3",
+        "d3-dispatch": "1 - 3",
+        "d3-ease": "1 - 3",
+        "d3-interpolate": "1 - 3",
+        "d3-timer": "1 - 3"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=12"
+      },
+      "peerDependencies": {
+        "d3-selection": "2 - 3"
       }
     },
-    "node_modules/ee-first": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
-      "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
-      "dev": true
-    },
-    "node_modules/ejs": {
-      "version": "3.1.9",
-      "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz",
-      "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==",
-      "dev": true,
+    "node_modules/d3-zoom": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz",
+      "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==",
+      "optional": true,
       "dependencies": {
-        "jake": "^10.8.5"
-      },
-      "bin": {
-        "ejs": "bin/cli.js"
+        "d3-dispatch": "1 - 3",
+        "d3-drag": "2 - 3",
+        "d3-interpolate": "1 - 3",
+        "d3-selection": "2 - 3",
+        "d3-transition": "2 - 3"
       },
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">=12"
       }
     },
-    "node_modules/electron-to-chromium": {
-      "version": "1.4.565",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.565.tgz",
-      "integrity": "sha512-XbMoT6yIvg2xzcbs5hCADi0dXBh4//En3oFXmtPX+jiyyiCTiM9DGFT2SLottjpEs9Z8Mh8SqahbR96MaHfuSg=="
+    "node_modules/dagre-d3-es": {
+      "version": "7.0.10",
+      "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz",
+      "integrity": "sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==",
+      "optional": true,
+      "dependencies": {
+        "d3": "^7.8.2",
+        "lodash-es": "^4.17.21"
+      }
     },
-    "node_modules/emittery": {
-      "version": "0.13.1",
-      "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
-      "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
+    "node_modules/date-format": {
+      "version": "4.0.14",
+      "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz",
+      "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==",
       "dev": true,
       "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sindresorhus/emittery?sponsor=1"
+        "node": ">=4.0"
       }
     },
-    "node_modules/emoji-regex": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+    "node_modules/dayjs": {
+      "version": "1.11.10",
+      "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz",
+      "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==",
+      "optional": true
     },
-    "node_modules/emojis-list": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
-      "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
-      "dev": true,
+    "node_modules/debug": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+      "dependencies": {
+        "ms": "2.1.2"
+      },
       "engines": {
-        "node": ">= 4"
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
       }
     },
-    "node_modules/encodeurl": {
+    "node_modules/decode-named-character-reference": {
       "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
-      "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.8"
+      "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz",
+      "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==",
+      "optional": true,
+      "dependencies": {
+        "character-entities": "^2.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
       }
     },
-    "node_modules/encoding": {
-      "version": "0.1.13",
-      "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
-      "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+    "node_modules/deep-is": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+      "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
       "dev": true,
-      "optional": true,
-      "dependencies": {
-        "iconv-lite": "^0.6.2"
+      "peer": true
+    },
+    "node_modules/deepmerge": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+      "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
       }
     },
-    "node_modules/encoding/node_modules/iconv-lite": {
-      "version": "0.6.3",
-      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
-      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+    "node_modules/default-gateway": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz",
+      "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==",
       "dev": true,
-      "optional": true,
       "dependencies": {
-        "safer-buffer": ">= 2.1.2 < 3.0.0"
+        "execa": "^5.0.0"
       },
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">= 10"
       }
     },
-    "node_modules/end-of-stream": {
-      "version": "1.4.4",
-      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
-      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+    "node_modules/defaults": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
+      "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
       "dev": true,
       "dependencies": {
-        "once": "^1.4.0"
+        "clone": "^1.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/engine.io": {
-      "version": "6.5.3",
-      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.3.tgz",
-      "integrity": "sha512-IML/R4eG/pUS5w7OfcDE0jKrljWS9nwnEfsxWCIJF5eO6AHo6+Hlv+lQbdlAYsiJPHzUthLm1RUjnBzWOs45cw==",
+    "node_modules/define-data-property": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz",
+      "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==",
       "dev": true,
       "dependencies": {
-        "@types/cookie": "^0.4.1",
-        "@types/cors": "^2.8.12",
-        "@types/node": ">=10.0.0",
-        "accepts": "~1.3.4",
-        "base64id": "2.0.0",
-        "cookie": "~0.4.1",
-        "cors": "~2.8.5",
-        "debug": "~4.3.1",
-        "engine.io-parser": "~5.2.1",
-        "ws": "~8.11.0"
+        "get-intrinsic": "^1.2.1",
+        "gopd": "^1.0.1",
+        "has-property-descriptors": "^1.0.0"
       },
       "engines": {
-        "node": ">=10.2.0"
+        "node": ">= 0.4"
       }
     },
-    "node_modules/engine.io-client": {
-      "version": "6.5.3",
-      "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz",
-      "integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==",
+    "node_modules/define-lazy-prop": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
+      "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
       "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/delaunator": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz",
+      "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==",
+      "optional": true,
       "dependencies": {
-        "@socket.io/component-emitter": "~3.1.0",
-        "debug": "~4.3.1",
-        "engine.io-parser": "~5.2.1",
-        "ws": "~8.11.0",
-        "xmlhttprequest-ssl": "~2.0.0"
+        "robust-predicates": "^3.0.0"
       }
     },
-    "node_modules/engine.io-parser": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz",
-      "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==",
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
       "dev": true,
       "engines": {
-        "node": ">=10.0.0"
+        "node": ">=0.4.0"
       }
     },
-    "node_modules/enhanced-resolve": {
-      "version": "5.15.0",
-      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
-      "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
+    "node_modules/delegate": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
+      "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
+      "optional": true
+    },
+    "node_modules/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,
-      "dependencies": {
-        "graceful-fs": "^4.2.4",
-        "tapable": "^2.2.0"
-      },
       "engines": {
-        "node": ">=10.13.0"
+        "node": ">= 0.8"
       }
     },
-    "node_modules/enquirer": {
-      "version": "2.3.6",
-      "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
-      "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
-      "dev": true,
-      "dependencies": {
-        "ansi-colors": "^4.1.1"
-      },
+    "node_modules/dequal": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+      "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+      "optional": true,
       "engines": {
-        "node": ">=8.6"
+        "node": ">=6"
       }
     },
-    "node_modules/ent": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz",
-      "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==",
-      "dev": true
-    },
-    "node_modules/entities": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
-      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
-      "devOptional": true,
+    "node_modules/destroy": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+      "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+      "dev": true,
       "engines": {
-        "node": ">=0.12"
-      },
-      "funding": {
-        "url": "https://github.com/fb55/entities?sponsor=1"
+        "node": ">= 0.8",
+        "npm": "1.2.8000 || >= 1.4.16"
       }
     },
-    "node_modules/env-paths": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
-      "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+    "node_modules/detect-newline": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+      "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
       "dev": true,
       "engines": {
-        "node": ">=6"
+        "node": ">=8"
       }
     },
-    "node_modules/err-code": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
-      "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
+    "node_modules/detect-node": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
+      "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
       "dev": true
     },
-    "node_modules/errno": {
-      "version": "0.1.8",
-      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
-      "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
+    "node_modules/detect-port": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz",
+      "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==",
       "dev": true,
-      "optional": true,
       "dependencies": {
-        "prr": "~1.0.1"
+        "address": "^1.0.1",
+        "debug": "4"
       },
       "bin": {
-        "errno": "cli.js"
+        "detect": "bin/detect-port.js",
+        "detect-port": "bin/detect-port.js"
       }
     },
-    "node_modules/error-ex": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
-      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+    "node_modules/dev-ip": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz",
+      "integrity": "sha512-LmVkry/oDShEgSZPNgqCIp2/TlqtExeGmymru3uCELnfyjY11IzpAproLYs+1X88fXO6DBoYP3ul2Xo2yz2j6A==",
       "dev": true,
-      "dependencies": {
-        "is-arrayish": "^0.2.1"
+      "bin": {
+        "dev-ip": "lib/dev-ip.js"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
       }
     },
-    "node_modules/es-module-lexer": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.1.tgz",
-      "integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==",
+    "node_modules/di": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz",
+      "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==",
       "dev": true
     },
-    "node_modules/esbuild": {
-      "version": "0.19.5",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz",
-      "integrity": "sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==",
+    "node_modules/diff": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
       "dev": true,
-      "hasInstallScript": true,
-      "optional": true,
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
       "engines": {
-        "node": ">=12"
-      },
-      "optionalDependencies": {
-        "@esbuild/android-arm": "0.19.5",
-        "@esbuild/android-arm64": "0.19.5",
-        "@esbuild/android-x64": "0.19.5",
-        "@esbuild/darwin-arm64": "0.19.5",
-        "@esbuild/darwin-x64": "0.19.5",
-        "@esbuild/freebsd-arm64": "0.19.5",
-        "@esbuild/freebsd-x64": "0.19.5",
-        "@esbuild/linux-arm": "0.19.5",
-        "@esbuild/linux-arm64": "0.19.5",
-        "@esbuild/linux-ia32": "0.19.5",
-        "@esbuild/linux-loong64": "0.19.5",
-        "@esbuild/linux-mips64el": "0.19.5",
-        "@esbuild/linux-ppc64": "0.19.5",
-        "@esbuild/linux-riscv64": "0.19.5",
-        "@esbuild/linux-s390x": "0.19.5",
-        "@esbuild/linux-x64": "0.19.5",
-        "@esbuild/netbsd-x64": "0.19.5",
-        "@esbuild/openbsd-x64": "0.19.5",
-        "@esbuild/sunos-x64": "0.19.5",
-        "@esbuild/win32-arm64": "0.19.5",
-        "@esbuild/win32-ia32": "0.19.5",
-        "@esbuild/win32-x64": "0.19.5"
+        "node": ">=0.3.1"
       }
     },
-    "node_modules/esbuild-wasm": {
-      "version": "0.19.5",
-      "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.19.5.tgz",
-      "integrity": "sha512-7zmLLn2QCj93XfMmHtzrDJ1UBuOHB2CZz1ghoCEZiRajxjUvHsF40PnbzFIY/pmesqPRaEtEWii0uzsTbnAgrA==",
+    "node_modules/diff-sequences": {
+      "version": "29.6.3",
+      "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
+      "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
       "dev": true,
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
       "engines": {
-        "node": ">=12"
+        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
-    "node_modules/escalade": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
-      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+    "node_modules/dir-glob": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+      "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+      "dev": true,
+      "dependencies": {
+        "path-type": "^4.0.0"
+      },
       "engines": {
-        "node": ">=6"
+        "node": ">=8"
       }
     },
-    "node_modules/escape-html": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
-      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+    "node_modules/dns-equal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
+      "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==",
       "dev": true
     },
-    "node_modules/escape-string-regexp": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/eslint": {
-      "version": "8.53.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.53.0.tgz",
-      "integrity": "sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==",
+    "node_modules/dns-packet": {
+      "version": "5.6.1",
+      "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
+      "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==",
       "dev": true,
-      "peer": true,
       "dependencies": {
-        "@eslint-community/eslint-utils": "^4.2.0",
-        "@eslint-community/regexpp": "^4.6.1",
-        "@eslint/eslintrc": "^2.1.3",
-        "@eslint/js": "8.53.0",
-        "@humanwhocodes/config-array": "^0.11.13",
-        "@humanwhocodes/module-importer": "^1.0.1",
-        "@nodelib/fs.walk": "^1.2.8",
-        "@ungap/structured-clone": "^1.2.0",
-        "ajv": "^6.12.4",
-        "chalk": "^4.0.0",
-        "cross-spawn": "^7.0.2",
-        "debug": "^4.3.2",
-        "doctrine": "^3.0.0",
-        "escape-string-regexp": "^4.0.0",
-        "eslint-scope": "^7.2.2",
-        "eslint-visitor-keys": "^3.4.3",
-        "espree": "^9.6.1",
-        "esquery": "^1.4.2",
-        "esutils": "^2.0.2",
-        "fast-deep-equal": "^3.1.3",
-        "file-entry-cache": "^6.0.1",
-        "find-up": "^5.0.0",
-        "glob-parent": "^6.0.2",
-        "globals": "^13.19.0",
-        "graphemer": "^1.4.0",
-        "ignore": "^5.2.0",
-        "imurmurhash": "^0.1.4",
-        "is-glob": "^4.0.0",
-        "is-path-inside": "^3.0.3",
-        "js-yaml": "^4.1.0",
-        "json-stable-stringify-without-jsonify": "^1.0.1",
-        "levn": "^0.4.1",
-        "lodash.merge": "^4.6.2",
-        "minimatch": "^3.1.2",
-        "natural-compare": "^1.4.0",
-        "optionator": "^0.9.3",
-        "strip-ansi": "^6.0.1",
-        "text-table": "^0.2.0"
-      },
-      "bin": {
-        "eslint": "bin/eslint.js"
+        "@leichtgewicht/ip-codec": "^2.0.1"
       },
       "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
+        "node": ">=6"
       }
     },
-    "node_modules/eslint-scope": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
-      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+    "node_modules/doctrine": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
       "dev": true,
+      "peer": true,
       "dependencies": {
-        "esrecurse": "^4.3.0",
-        "estraverse": "^4.1.1"
+        "esutils": "^2.0.2"
       },
       "engines": {
-        "node": ">=8.0.0"
+        "node": ">=6.0.0"
       }
     },
-    "node_modules/eslint-scope/node_modules/estraverse": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
-      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+    "node_modules/dom-serialize": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz",
+      "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==",
       "dev": true,
-      "engines": {
-        "node": ">=4.0"
+      "dependencies": {
+        "custom-event": "~1.0.0",
+        "ent": "~2.2.0",
+        "extend": "^3.0.0",
+        "void-elements": "^2.0.0"
       }
     },
-    "node_modules/eslint-visitor-keys": {
-      "version": "3.4.3",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
-      "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+    "node_modules/dom-serializer": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+      "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
       "dev": true,
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      "dependencies": {
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.2",
+        "entities": "^4.2.0"
       },
       "funding": {
-        "url": "https://opencollective.com/eslint"
+        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
       }
     },
-    "node_modules/eslint/node_modules/ajv": {
-      "version": "6.12.6",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+    "node_modules/domelementtype": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+      "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
       "dev": true,
-      "peer": true,
-      "dependencies": {
-        "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
-        "uri-js": "^4.2.2"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
-      }
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ]
     },
-    "node_modules/eslint/node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+    "node_modules/domhandler": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+      "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
       "dev": true,
-      "peer": true,
       "dependencies": {
-        "color-convert": "^2.0.1"
+        "domelementtype": "^2.3.0"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">= 4"
       },
       "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+        "url": "https://github.com/fb55/domhandler?sponsor=1"
       }
     },
-    "node_modules/eslint/node_modules/argparse": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
-      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
-      "dev": true,
-      "peer": true
+    "node_modules/dompurify": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.6.tgz",
+      "integrity": "sha512-ilkD8YEnnGh1zJ240uJsW7AzE+2qpbOUYjacomn3AvJ6J4JhKGSZ2nh4wUIXPZrEPppaCLx5jFe8T89Rk8tQ7w==",
+      "optional": true
     },
-    "node_modules/eslint/node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+    "node_modules/domutils": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
+      "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
       "dev": true,
-      "peer": true,
       "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
-      "engines": {
-        "node": ">=10"
+        "dom-serializer": "^2.0.0",
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.3"
       },
       "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
+        "url": "https://github.com/fb55/domutils?sponsor=1"
       }
     },
-    "node_modules/eslint/node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+    "node_modules/dotenv": {
+      "version": "16.3.1",
+      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
+      "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==",
       "dev": true,
-      "peer": true,
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
       "engines": {
-        "node": ">=7.0.0"
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/motdotla/dotenv?sponsor=1"
       }
     },
-    "node_modules/eslint/node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+    "node_modules/dotenv-expand": {
+      "version": "10.0.0",
+      "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz",
+      "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==",
       "dev": true,
-      "peer": true
+      "engines": {
+        "node": ">=12"
+      }
     },
-    "node_modules/eslint/node_modules/escape-string-regexp": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
-      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+    "node_modules/duplexer": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
+      "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
+      "dev": true
+    },
+    "node_modules/eastasianwidth": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+      "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+      "dev": true
+    },
+    "node_modules/easy-extender": {
+      "version": "2.3.4",
+      "resolved": "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.4.tgz",
+      "integrity": "sha512-8cAwm6md1YTiPpOvDULYJL4ZS6WfM5/cTeVVh4JsvyYZAoqlRVUpHL9Gr5Fy7HA6xcSZicUia3DeAgO3Us8E+Q==",
       "dev": true,
-      "peer": true,
-      "engines": {
-        "node": ">=10"
+      "dependencies": {
+        "lodash": "^4.17.10"
       },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+      "engines": {
+        "node": ">= 4.0.0"
       }
     },
-    "node_modules/eslint/node_modules/eslint-scope": {
-      "version": "7.2.2",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
-      "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+    "node_modules/eazy-logger": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-4.0.1.tgz",
+      "integrity": "sha512-2GSFtnnC6U4IEKhEI7+PvdxrmjJ04mdsj3wHZTFiw0tUtG4HCWzTr13ZYTk8XOGnA1xQMaDljoBOYlk3D/MMSw==",
       "dev": true,
-      "peer": true,
       "dependencies": {
-        "esrecurse": "^4.3.0",
-        "estraverse": "^5.2.0"
+        "chalk": "4.1.2"
       },
       "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
+        "node": ">= 0.8.0"
       }
     },
-    "node_modules/eslint/node_modules/find-up": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
-      "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+    "node_modules/eazy-logger/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
       "dev": true,
-      "peer": true,
       "dependencies": {
-        "locate-path": "^6.0.0",
-        "path-exists": "^4.0.0"
+        "color-convert": "^2.0.1"
       },
       "engines": {
-        "node": ">=10"
+        "node": ">=8"
       },
       "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
-    "node_modules/eslint/node_modules/glob-parent": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
-      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+    "node_modules/eazy-logger/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
       "dev": true,
-      "peer": true,
       "dependencies": {
-        "is-glob": "^4.0.3"
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
       },
       "engines": {
-        "node": ">=10.13.0"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
-    "node_modules/eslint/node_modules/globals": {
-      "version": "13.23.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz",
-      "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==",
+    "node_modules/eazy-logger/node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
       "dev": true,
-      "peer": true,
       "dependencies": {
-        "type-fest": "^0.20.2"
+        "color-name": "~1.1.4"
       },
       "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "node": ">=7.0.0"
       }
     },
-    "node_modules/eslint/node_modules/has-flag": {
+    "node_modules/eazy-logger/node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true
+    },
+    "node_modules/eazy-logger/node_modules/has-flag": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
       "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
       "dev": true,
-      "peer": true,
       "engines": {
         "node": ">=8"
       }
     },
-    "node_modules/eslint/node_modules/js-yaml": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
-      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+    "node_modules/eazy-logger/node_modules/supports-color": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
       "dev": true,
-      "peer": true,
       "dependencies": {
-        "argparse": "^2.0.1"
+        "has-flag": "^4.0.0"
       },
-      "bin": {
-        "js-yaml": "bin/js-yaml.js"
+      "engines": {
+        "node": ">=8"
       }
     },
-    "node_modules/eslint/node_modules/json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-      "dev": true,
-      "peer": true
+    "node_modules/ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+      "dev": true
     },
-    "node_modules/eslint/node_modules/locate-path": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
-      "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+    "node_modules/ejs": {
+      "version": "3.1.9",
+      "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz",
+      "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==",
       "dev": true,
-      "peer": true,
       "dependencies": {
-        "p-locate": "^5.0.0"
+        "jake": "^10.8.5"
       },
-      "engines": {
-        "node": ">=10"
+      "bin": {
+        "ejs": "bin/cli.js"
       },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+      "engines": {
+        "node": ">=0.10.0"
       }
     },
-    "node_modules/eslint/node_modules/p-limit": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
-      "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+    "node_modules/electron-to-chromium": {
+      "version": "1.4.565",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.565.tgz",
+      "integrity": "sha512-XbMoT6yIvg2xzcbs5hCADi0dXBh4//En3oFXmtPX+jiyyiCTiM9DGFT2SLottjpEs9Z8Mh8SqahbR96MaHfuSg=="
+    },
+    "node_modules/elkjs": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.8.2.tgz",
+      "integrity": "sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ==",
+      "optional": true
+    },
+    "node_modules/emittery": {
+      "version": "0.13.1",
+      "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
+      "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
       "dev": true,
-      "peer": true,
-      "dependencies": {
-        "yocto-queue": "^0.1.0"
-      },
       "engines": {
-        "node": ">=10"
+        "node": ">=12"
       },
       "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "url": "https://github.com/sindresorhus/emittery?sponsor=1"
       }
     },
-    "node_modules/eslint/node_modules/p-locate": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
-      "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+    "node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+    },
+    "node_modules/emoji-toolkit": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-toolkit/-/emoji-toolkit-8.0.0.tgz",
+      "integrity": "sha512-Vz8YIqQJsQ+QZ4yuKMMzliXceayqfWbNjb6bST+vm77QAhU2is3I+/PRxrNknW+q1bvHHMgjLCQXxzINWLVapg==",
+      "optional": true
+    },
+    "node_modules/emojis-list": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+      "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
       "dev": true,
-      "peer": true,
-      "dependencies": {
-        "p-limit": "^3.0.2"
-      },
       "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "node": ">= 4"
       }
     },
-    "node_modules/eslint/node_modules/supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+    "node_modules/encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
       "dev": true,
-      "peer": true,
-      "dependencies": {
-        "has-flag": "^4.0.0"
-      },
       "engines": {
-        "node": ">=8"
+        "node": ">= 0.8"
       }
     },
-    "node_modules/eslint/node_modules/type-fest": {
-      "version": "0.20.2",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
-      "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+    "node_modules/encoding": {
+      "version": "0.1.13",
+      "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
+      "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
       "dev": true,
-      "peer": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+      "optional": true,
+      "dependencies": {
+        "iconv-lite": "^0.6.2"
       }
     },
-    "node_modules/eslint/node_modules/yocto-queue": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
-      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
-      "dev": true,
-      "peer": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/espree": {
-      "version": "9.6.1",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
-      "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+    "node_modules/encoding/node_modules/iconv-lite": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
       "dev": true,
-      "peer": true,
+      "optional": true,
       "dependencies": {
-        "acorn": "^8.9.0",
-        "acorn-jsx": "^5.3.2",
-        "eslint-visitor-keys": "^3.4.1"
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
       },
       "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
+        "node": ">=0.10.0"
       }
     },
-    "node_modules/esprima": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
-      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+    "node_modules/end-of-stream": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
       "dev": true,
-      "bin": {
-        "esparse": "bin/esparse.js",
-        "esvalidate": "bin/esvalidate.js"
-      },
-      "engines": {
-        "node": ">=4"
+      "dependencies": {
+        "once": "^1.4.0"
       }
     },
-    "node_modules/esquery": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
-      "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+    "node_modules/engine.io": {
+      "version": "6.5.3",
+      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.3.tgz",
+      "integrity": "sha512-IML/R4eG/pUS5w7OfcDE0jKrljWS9nwnEfsxWCIJF5eO6AHo6+Hlv+lQbdlAYsiJPHzUthLm1RUjnBzWOs45cw==",
       "dev": true,
       "dependencies": {
-        "estraverse": "^5.1.0"
+        "@types/cookie": "^0.4.1",
+        "@types/cors": "^2.8.12",
+        "@types/node": ">=10.0.0",
+        "accepts": "~1.3.4",
+        "base64id": "2.0.0",
+        "cookie": "~0.4.1",
+        "cors": "~2.8.5",
+        "debug": "~4.3.1",
+        "engine.io-parser": "~5.2.1",
+        "ws": "~8.11.0"
       },
       "engines": {
-        "node": ">=0.10"
+        "node": ">=10.2.0"
       }
     },
-    "node_modules/esrecurse": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
-      "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+    "node_modules/engine.io-client": {
+      "version": "6.5.3",
+      "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz",
+      "integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==",
       "dev": true,
       "dependencies": {
-        "estraverse": "^5.2.0"
-      },
-      "engines": {
-        "node": ">=4.0"
+        "@socket.io/component-emitter": "~3.1.0",
+        "debug": "~4.3.1",
+        "engine.io-parser": "~5.2.1",
+        "ws": "~8.11.0",
+        "xmlhttprequest-ssl": "~2.0.0"
       }
     },
-    "node_modules/estraverse": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+    "node_modules/engine.io-parser": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz",
+      "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==",
       "dev": true,
       "engines": {
-        "node": ">=4.0"
+        "node": ">=10.0.0"
       }
     },
-    "node_modules/esutils": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
-      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+    "node_modules/enhanced-resolve": {
+      "version": "5.15.0",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
+      "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
       "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.2.4",
+        "tapable": "^2.2.0"
+      },
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">=10.13.0"
       }
     },
-    "node_modules/etag": {
-      "version": "1.8.1",
-      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
-      "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+    "node_modules/enquirer": {
+      "version": "2.3.6",
+      "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
+      "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
       "dev": true,
+      "dependencies": {
+        "ansi-colors": "^4.1.1"
+      },
       "engines": {
-        "node": ">= 0.6"
+        "node": ">=8.6"
       }
     },
-    "node_modules/eventemitter-asyncresource": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz",
-      "integrity": "sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ==",
-      "dev": true
-    },
-    "node_modules/eventemitter3": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
-      "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+    "node_modules/ent": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz",
+      "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==",
       "dev": true
     },
-    "node_modules/events": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
-      "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.8.x"
-      }
-    },
-    "node_modules/execa": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
-      "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
-      "dev": true,
-      "dependencies": {
-        "cross-spawn": "^7.0.3",
-        "get-stream": "^6.0.0",
-        "human-signals": "^2.1.0",
-        "is-stream": "^2.0.0",
-        "merge-stream": "^2.0.0",
-        "npm-run-path": "^4.0.1",
-        "onetime": "^5.1.2",
-        "signal-exit": "^3.0.3",
-        "strip-final-newline": "^2.0.0"
-      },
+    "node_modules/entities": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+      "devOptional": true,
       "engines": {
-        "node": ">=10"
+        "node": ">=0.12"
       },
       "funding": {
-        "url": "https://github.com/sindresorhus/execa?sponsor=1"
+        "url": "https://github.com/fb55/entities?sponsor=1"
       }
     },
-    "node_modules/exit": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
-      "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
+    "node_modules/env-paths": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+      "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
       "dev": true,
       "engines": {
-        "node": ">= 0.8.0"
+        "node": ">=6"
       }
     },
-    "node_modules/expect": {
-      "version": "29.7.0",
-      "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz",
-      "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==",
+    "node_modules/err-code": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
+      "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
+      "dev": true
+    },
+    "node_modules/errno": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
+      "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
       "dev": true,
+      "optional": true,
       "dependencies": {
-        "@jest/expect-utils": "^29.7.0",
-        "jest-get-type": "^29.6.3",
-        "jest-matcher-utils": "^29.7.0",
-        "jest-message-util": "^29.7.0",
-        "jest-util": "^29.7.0"
+        "prr": "~1.0.1"
       },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+      "bin": {
+        "errno": "cli.js"
       }
     },
-    "node_modules/exponential-backoff": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz",
-      "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==",
-      "dev": true
-    },
-    "node_modules/express": {
-      "version": "4.18.2",
-      "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
-      "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
+    "node_modules/error-ex": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
       "dev": true,
       "dependencies": {
-        "accepts": "~1.3.8",
-        "array-flatten": "1.1.1",
-        "body-parser": "1.20.1",
-        "content-disposition": "0.5.4",
-        "content-type": "~1.0.4",
-        "cookie": "0.5.0",
-        "cookie-signature": "1.0.6",
-        "debug": "2.6.9",
-        "depd": "2.0.0",
-        "encodeurl": "~1.0.2",
-        "escape-html": "~1.0.3",
-        "etag": "~1.8.1",
-        "finalhandler": "1.2.0",
-        "fresh": "0.5.2",
-        "http-errors": "2.0.0",
-        "merge-descriptors": "1.0.1",
-        "methods": "~1.1.2",
-        "on-finished": "2.4.1",
-        "parseurl": "~1.3.3",
-        "path-to-regexp": "0.1.7",
-        "proxy-addr": "~2.0.7",
-        "qs": "6.11.0",
-        "range-parser": "~1.2.1",
-        "safe-buffer": "5.2.1",
-        "send": "0.18.0",
-        "serve-static": "1.15.0",
-        "setprototypeof": "1.2.0",
-        "statuses": "2.0.1",
-        "type-is": "~1.6.18",
-        "utils-merge": "1.0.1",
-        "vary": "~1.1.2"
-      },
-      "engines": {
-        "node": ">= 0.10.0"
+        "is-arrayish": "^0.2.1"
       }
     },
-    "node_modules/express/node_modules/array-flatten": {
+    "node_modules/es-module-lexer": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.1.tgz",
+      "integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==",
+      "dev": true
+    },
+    "node_modules/esbuild": {
+      "version": "0.19.5",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz",
+      "integrity": "sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==",
+      "dev": true,
+      "hasInstallScript": true,
+      "optional": true,
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "@esbuild/android-arm": "0.19.5",
+        "@esbuild/android-arm64": "0.19.5",
+        "@esbuild/android-x64": "0.19.5",
+        "@esbuild/darwin-arm64": "0.19.5",
+        "@esbuild/darwin-x64": "0.19.5",
+        "@esbuild/freebsd-arm64": "0.19.5",
+        "@esbuild/freebsd-x64": "0.19.5",
+        "@esbuild/linux-arm": "0.19.5",
+        "@esbuild/linux-arm64": "0.19.5",
+        "@esbuild/linux-ia32": "0.19.5",
+        "@esbuild/linux-loong64": "0.19.5",
+        "@esbuild/linux-mips64el": "0.19.5",
+        "@esbuild/linux-ppc64": "0.19.5",
+        "@esbuild/linux-riscv64": "0.19.5",
+        "@esbuild/linux-s390x": "0.19.5",
+        "@esbuild/linux-x64": "0.19.5",
+        "@esbuild/netbsd-x64": "0.19.5",
+        "@esbuild/openbsd-x64": "0.19.5",
+        "@esbuild/sunos-x64": "0.19.5",
+        "@esbuild/win32-arm64": "0.19.5",
+        "@esbuild/win32-ia32": "0.19.5",
+        "@esbuild/win32-x64": "0.19.5"
+      }
+    },
+    "node_modules/esbuild-wasm": {
+      "version": "0.19.5",
+      "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.19.5.tgz",
+      "integrity": "sha512-7zmLLn2QCj93XfMmHtzrDJ1UBuOHB2CZz1ghoCEZiRajxjUvHsF40PnbzFIY/pmesqPRaEtEWii0uzsTbnAgrA==",
+      "dev": true,
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/escalade": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+      "dev": true
+    },
+    "node_modules/escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/eslint": {
+      "version": "8.53.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.53.0.tgz",
+      "integrity": "sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "@eslint-community/eslint-utils": "^4.2.0",
+        "@eslint-community/regexpp": "^4.6.1",
+        "@eslint/eslintrc": "^2.1.3",
+        "@eslint/js": "8.53.0",
+        "@humanwhocodes/config-array": "^0.11.13",
+        "@humanwhocodes/module-importer": "^1.0.1",
+        "@nodelib/fs.walk": "^1.2.8",
+        "@ungap/structured-clone": "^1.2.0",
+        "ajv": "^6.12.4",
+        "chalk": "^4.0.0",
+        "cross-spawn": "^7.0.2",
+        "debug": "^4.3.2",
+        "doctrine": "^3.0.0",
+        "escape-string-regexp": "^4.0.0",
+        "eslint-scope": "^7.2.2",
+        "eslint-visitor-keys": "^3.4.3",
+        "espree": "^9.6.1",
+        "esquery": "^1.4.2",
+        "esutils": "^2.0.2",
+        "fast-deep-equal": "^3.1.3",
+        "file-entry-cache": "^6.0.1",
+        "find-up": "^5.0.0",
+        "glob-parent": "^6.0.2",
+        "globals": "^13.19.0",
+        "graphemer": "^1.4.0",
+        "ignore": "^5.2.0",
+        "imurmurhash": "^0.1.4",
+        "is-glob": "^4.0.0",
+        "is-path-inside": "^3.0.3",
+        "js-yaml": "^4.1.0",
+        "json-stable-stringify-without-jsonify": "^1.0.1",
+        "levn": "^0.4.1",
+        "lodash.merge": "^4.6.2",
+        "minimatch": "^3.1.2",
+        "natural-compare": "^1.4.0",
+        "optionator": "^0.9.3",
+        "strip-ansi": "^6.0.1",
+        "text-table": "^0.2.0"
+      },
+      "bin": {
+        "eslint": "bin/eslint.js"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/eslint-scope": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+      "dev": true,
+      "dependencies": {
+        "esrecurse": "^4.3.0",
+        "estraverse": "^4.1.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/eslint-scope/node_modules/estraverse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/eslint-visitor-keys": {
+      "version": "3.4.3",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+      "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+      "dev": true,
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/eslint/node_modules/ajv": {
+      "version": "6.12.6",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
+      }
+    },
+    "node_modules/eslint/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/eslint/node_modules/argparse": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+      "dev": true,
+      "peer": true
+    },
+    "node_modules/eslint/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/eslint/node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/eslint/node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true,
+      "peer": true
+    },
+    "node_modules/eslint/node_modules/escape-string-regexp": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+      "dev": true,
+      "peer": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/node_modules/eslint-scope": {
+      "version": "7.2.2",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+      "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "esrecurse": "^4.3.0",
+        "estraverse": "^5.2.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/eslint/node_modules/find-up": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+      "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "locate-path": "^6.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/node_modules/glob-parent": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "is-glob": "^4.0.3"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/eslint/node_modules/globals": {
+      "version": "13.23.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz",
+      "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "type-fest": "^0.20.2"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "dev": true,
+      "peer": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/eslint/node_modules/js-yaml": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "argparse": "^2.0.1"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
+      }
+    },
+    "node_modules/eslint/node_modules/json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+      "dev": true,
+      "peer": true
+    },
+    "node_modules/eslint/node_modules/locate-path": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+      "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "p-locate": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/node_modules/p-limit": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+      "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "yocto-queue": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/node_modules/p-locate": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+      "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "p-limit": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/node_modules/supports-color": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/eslint/node_modules/type-fest": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+      "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+      "dev": true,
+      "peer": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/node_modules/yocto-queue": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+      "dev": true,
+      "peer": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/espree": {
+      "version": "9.6.1",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+      "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+      "dev": true,
+      "peer": true,
+      "dependencies": {
+        "acorn": "^8.9.0",
+        "acorn-jsx": "^5.3.2",
+        "eslint-visitor-keys": "^3.4.1"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/esprima": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+      "dev": true,
+      "bin": {
+        "esparse": "bin/esparse.js",
+        "esvalidate": "bin/esvalidate.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/esquery": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+      "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+      "dev": true,
+      "dependencies": {
+        "estraverse": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/esrecurse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+      "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+      "dev": true,
+      "dependencies": {
+        "estraverse": "^5.2.0"
+      },
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/estraverse": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/esutils": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/eventemitter-asyncresource": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz",
+      "integrity": "sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ==",
+      "dev": true
+    },
+    "node_modules/eventemitter3": {
+      "version": "4.0.7",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+      "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+      "dev": true
+    },
+    "node_modules/events": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+      "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.x"
+      }
+    },
+    "node_modules/execa": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+      "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+      "dev": true,
+      "dependencies": {
+        "cross-spawn": "^7.0.3",
+        "get-stream": "^6.0.0",
+        "human-signals": "^2.1.0",
+        "is-stream": "^2.0.0",
+        "merge-stream": "^2.0.0",
+        "npm-run-path": "^4.0.1",
+        "onetime": "^5.1.2",
+        "signal-exit": "^3.0.3",
+        "strip-final-newline": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sindresorhus/execa?sponsor=1"
+      }
+    },
+    "node_modules/exit": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+      "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/expect": {
+      "version": "29.7.0",
+      "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz",
+      "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==",
+      "dev": true,
+      "dependencies": {
+        "@jest/expect-utils": "^29.7.0",
+        "jest-get-type": "^29.6.3",
+        "jest-matcher-utils": "^29.7.0",
+        "jest-message-util": "^29.7.0",
+        "jest-util": "^29.7.0"
+      },
+      "engines": {
+        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+      }
+    },
+    "node_modules/exponential-backoff": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz",
+      "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==",
+      "dev": true
+    },
+    "node_modules/express": {
+      "version": "4.18.2",
+      "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
+      "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
+      "dev": true,
+      "dependencies": {
+        "accepts": "~1.3.8",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.20.1",
+        "content-disposition": "0.5.4",
+        "content-type": "~1.0.4",
+        "cookie": "0.5.0",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "finalhandler": "1.2.0",
+        "fresh": "0.5.2",
+        "http-errors": "2.0.0",
+        "merge-descriptors": "1.0.1",
+        "methods": "~1.1.2",
+        "on-finished": "2.4.1",
+        "parseurl": "~1.3.3",
+        "path-to-regexp": "0.1.7",
+        "proxy-addr": "~2.0.7",
+        "qs": "6.11.0",
+        "range-parser": "~1.2.1",
+        "safe-buffer": "5.2.1",
+        "send": "0.18.0",
+        "serve-static": "1.15.0",
+        "setprototypeof": "1.2.0",
+        "statuses": "2.0.1",
+        "type-is": "~1.6.18",
+        "utils-merge": "1.0.1",
+        "vary": "~1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.10.0"
+      }
+    },
+    "node_modules/express/node_modules/array-flatten": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
       "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
@@ -12952,6 +13626,15 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/good-listener": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
+      "integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==",
+      "optional": true,
+      "dependencies": {
+        "delegate": "^3.1.2"
+      }
+    },
     "node_modules/gopd": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
@@ -13071,6 +13754,12 @@
         "he": "bin/he"
       }
     },
+    "node_modules/heap": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz",
+      "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==",
+      "optional": true
+    },
     "node_modules/hosted-git-info": {
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz",
@@ -13733,6 +14422,15 @@
         "node": ">=8"
       }
     },
+    "node_modules/internmap": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
+      "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
+      "optional": true,
+      "engines": {
+        "node": ">=12"
+      }
+    },
     "node_modules/ip": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
@@ -16075,6 +16773,31 @@
         "node": ">=10"
       }
     },
+    "node_modules/katex": {
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.9.tgz",
+      "integrity": "sha512-fsSYjWS0EEOwvy81j3vRA8TEAhQhKiqO+FQaKWp0m39qwOzHVBgAUBIXWj1pB+O2W3fIpNa6Y9KSKCVbfPhyAQ==",
+      "funding": [
+        "https://opencollective.com/katex",
+        "https://github.com/sponsors/katex"
+      ],
+      "optional": true,
+      "dependencies": {
+        "commander": "^8.3.0"
+      },
+      "bin": {
+        "katex": "cli.js"
+      }
+    },
+    "node_modules/katex/node_modules/commander": {
+      "version": "8.3.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
+      "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
+      "optional": true,
+      "engines": {
+        "node": ">= 12"
+      }
+    },
     "node_modules/keyv": {
       "version": "4.5.4",
       "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -16085,6 +16808,12 @@
         "json-buffer": "3.0.1"
       }
     },
+    "node_modules/khroma": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz",
+      "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==",
+      "optional": true
+    },
     "node_modules/kind-of": {
       "version": "6.0.3",
       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
@@ -16094,6 +16823,15 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/kleur": {
+      "version": "4.1.5",
+      "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
+      "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
+      "optional": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/klona": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz",
@@ -16113,6 +16851,12 @@
         "shell-quote": "^1.8.1"
       }
     },
+    "node_modules/layout-base": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz",
+      "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==",
+      "optional": true
+    },
     "node_modules/less": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/less/-/less-4.2.0.tgz",
@@ -16408,7 +17152,13 @@
       "version": "4.17.21",
       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
       "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
-      "dev": true
+      "devOptional": true
+    },
+    "node_modules/lodash-es": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+      "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
+      "optional": true
     },
     "node_modules/lodash.debounce": {
       "version": "4.0.8",
@@ -16451,225 +17201,756 @@
         "is-unicode-supported": "^0.1.0"
       },
       "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/log-symbols/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/log-symbols/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/log-symbols/node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/log-symbols/node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true
+    },
+    "node_modules/log-symbols/node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/log-symbols/node_modules/supports-color": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/log4js": {
+      "version": "6.9.1",
+      "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz",
+      "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==",
+      "dev": true,
+      "dependencies": {
+        "date-format": "^4.0.14",
+        "debug": "^4.3.4",
+        "flatted": "^3.2.7",
+        "rfdc": "^1.3.0",
+        "streamroller": "^3.1.5"
+      },
+      "engines": {
+        "node": ">=8.0"
+      }
+    },
+    "node_modules/lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dependencies": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "node_modules/magic-string": {
+      "version": "0.30.5",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz",
+      "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/sourcemap-codec": "^1.4.15"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/make-dir": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+      "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+      "dev": true,
+      "dependencies": {
+        "semver": "^7.5.3"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/make-error": {
+      "version": "1.3.6",
+      "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+      "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+      "dev": true
+    },
+    "node_modules/make-fetch-happen": {
+      "version": "13.0.0",
+      "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.0.tgz",
+      "integrity": "sha512-7ThobcL8brtGo9CavByQrQi+23aIfgYU++wg4B87AIS8Rb2ZBt/MEaDqzA00Xwv/jUjAjYkLHjVolYuTLKda2A==",
+      "dev": true,
+      "dependencies": {
+        "@npmcli/agent": "^2.0.0",
+        "cacache": "^18.0.0",
+        "http-cache-semantics": "^4.1.1",
+        "is-lambda": "^1.0.1",
+        "minipass": "^7.0.2",
+        "minipass-fetch": "^3.0.0",
+        "minipass-flush": "^1.0.5",
+        "minipass-pipeline": "^1.2.4",
+        "negotiator": "^0.6.3",
+        "promise-retry": "^2.0.1",
+        "ssri": "^10.0.0"
+      },
+      "engines": {
+        "node": "^16.14.0 || >=18.0.0"
       }
     },
-    "node_modules/log-symbols/node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+    "node_modules/makeerror": {
+      "version": "1.0.12",
+      "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
+      "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
       "dev": true,
       "dependencies": {
-        "color-convert": "^2.0.1"
+        "tmpl": "1.0.5"
+      }
+    },
+    "node_modules/marked": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/marked/-/marked-9.0.0.tgz",
+      "integrity": "sha512-37yoTpjU+TSXb9OBYY5n78z/CqXh76KiQj9xsKxEdztzU9fRLmbWO5YqKxgCVGKlNdexppnbKTkwB3RipVri8w==",
+      "bin": {
+        "marked": "bin/marked.js"
       },
       "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+        "node": ">= 16"
       }
     },
-    "node_modules/log-symbols/node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-      "dev": true,
+    "node_modules/mdast-util-from-markdown": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz",
+      "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==",
+      "optional": true,
       "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
-      "engines": {
-        "node": ">=10"
+        "@types/mdast": "^3.0.0",
+        "@types/unist": "^2.0.0",
+        "decode-named-character-reference": "^1.0.0",
+        "mdast-util-to-string": "^3.1.0",
+        "micromark": "^3.0.0",
+        "micromark-util-decode-numeric-character-reference": "^1.0.0",
+        "micromark-util-decode-string": "^1.0.0",
+        "micromark-util-normalize-identifier": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "unist-util-stringify-position": "^3.0.0",
+        "uvu": "^0.5.0"
       },
       "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
       }
     },
-    "node_modules/log-symbols/node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dev": true,
+    "node_modules/mdast-util-to-string": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz",
+      "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==",
+      "optional": true,
       "dependencies": {
-        "color-name": "~1.1.4"
+        "@types/mdast": "^3.0.0"
       },
-      "engines": {
-        "node": ">=7.0.0"
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
       }
     },
-    "node_modules/log-symbols/node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+    "node_modules/mdn-data": {
+      "version": "2.0.30",
+      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
+      "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
       "dev": true
     },
-    "node_modules/log-symbols/node_modules/has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+    "node_modules/media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
       "dev": true,
       "engines": {
-        "node": ">=8"
+        "node": ">= 0.6"
       }
     },
-    "node_modules/log-symbols/node_modules/supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+    "node_modules/memfs": {
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz",
+      "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==",
       "dev": true,
       "dependencies": {
-        "has-flag": "^4.0.0"
+        "fs-monkey": "^1.0.4"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">= 4.0.0"
       }
     },
-    "node_modules/log4js": {
-      "version": "6.9.1",
-      "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz",
-      "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==",
-      "dev": true,
-      "dependencies": {
-        "date-format": "^4.0.14",
-        "debug": "^4.3.4",
-        "flatted": "^3.2.7",
-        "rfdc": "^1.3.0",
-        "streamroller": "^3.1.5"
-      },
+    "node_modules/merge-descriptors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+      "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==",
+      "dev": true
+    },
+    "node_modules/merge-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+      "dev": true
+    },
+    "node_modules/merge2": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
       "engines": {
-        "node": ">=8.0"
+        "node": ">= 8"
       }
     },
-    "node_modules/lru-cache": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
-      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+    "node_modules/mermaid": {
+      "version": "10.6.1",
+      "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.6.1.tgz",
+      "integrity": "sha512-Hky0/RpOw/1il9X8AvzOEChfJtVvmXm+y7JML5C//ePYMy0/9jCEmW1E1g86x9oDfW9+iVEdTV/i+M6KWRNs4A==",
+      "optional": true,
       "dependencies": {
-        "yallist": "^3.0.2"
+        "@braintree/sanitize-url": "^6.0.1",
+        "@types/d3-scale": "^4.0.3",
+        "@types/d3-scale-chromatic": "^3.0.0",
+        "cytoscape": "^3.23.0",
+        "cytoscape-cose-bilkent": "^4.1.0",
+        "cytoscape-fcose": "^2.1.0",
+        "d3": "^7.4.0",
+        "d3-sankey": "^0.12.3",
+        "dagre-d3-es": "7.0.10",
+        "dayjs": "^1.11.7",
+        "dompurify": "^3.0.5",
+        "elkjs": "^0.8.2",
+        "khroma": "^2.0.0",
+        "lodash-es": "^4.17.21",
+        "mdast-util-from-markdown": "^1.3.0",
+        "non-layered-tidy-tree-layout": "^2.0.2",
+        "stylis": "^4.1.3",
+        "ts-dedent": "^2.2.0",
+        "uuid": "^9.0.0",
+        "web-worker": "^1.2.0"
+      }
+    },
+    "node_modules/mermaid/node_modules/uuid": {
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
+      "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+      "funding": [
+        "https://github.com/sponsors/broofa",
+        "https://github.com/sponsors/ctavan"
+      ],
+      "optional": true,
+      "bin": {
+        "uuid": "dist/bin/uuid"
       }
     },
-    "node_modules/magic-string": {
-      "version": "0.30.5",
-      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz",
-      "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==",
+    "node_modules/methods": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+      "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
       "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/micromark": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz",
+      "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true,
+      "dependencies": {
+        "@types/debug": "^4.0.0",
+        "debug": "^4.0.0",
+        "decode-named-character-reference": "^1.0.0",
+        "micromark-core-commonmark": "^1.0.1",
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-combine-extensions": "^1.0.0",
+        "micromark-util-decode-numeric-character-reference": "^1.0.0",
+        "micromark-util-encode": "^1.0.0",
+        "micromark-util-normalize-identifier": "^1.0.0",
+        "micromark-util-resolve-all": "^1.0.0",
+        "micromark-util-sanitize-uri": "^1.0.0",
+        "micromark-util-subtokenize": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.1",
+        "uvu": "^0.5.0"
+      }
+    },
+    "node_modules/micromark-core-commonmark": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz",
+      "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true,
+      "dependencies": {
+        "decode-named-character-reference": "^1.0.0",
+        "micromark-factory-destination": "^1.0.0",
+        "micromark-factory-label": "^1.0.0",
+        "micromark-factory-space": "^1.0.0",
+        "micromark-factory-title": "^1.0.0",
+        "micromark-factory-whitespace": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-classify-character": "^1.0.0",
+        "micromark-util-html-tag-name": "^1.0.0",
+        "micromark-util-normalize-identifier": "^1.0.0",
+        "micromark-util-resolve-all": "^1.0.0",
+        "micromark-util-subtokenize": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.1",
+        "uvu": "^0.5.0"
+      }
+    },
+    "node_modules/micromark-factory-destination": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz",
+      "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true,
+      "dependencies": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-factory-label": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz",
+      "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true,
+      "dependencies": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
+      }
+    },
+    "node_modules/micromark-factory-space": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz",
+      "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true,
+      "dependencies": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-factory-title": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz",
+      "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true,
+      "dependencies": {
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-factory-whitespace": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz",
+      "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true,
+      "dependencies": {
+        "micromark-factory-space": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-character": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz",
+      "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true,
+      "dependencies": {
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-chunked": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz",
+      "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true,
+      "dependencies": {
+        "micromark-util-symbol": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-classify-character": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz",
+      "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true,
+      "dependencies": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-combine-extensions": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz",
+      "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true,
+      "dependencies": {
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-types": "^1.0.0"
+      }
+    },
+    "node_modules/micromark-util-decode-numeric-character-reference": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz",
+      "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true,
       "dependencies": {
-        "@jridgewell/sourcemap-codec": "^1.4.15"
-      },
-      "engines": {
-        "node": ">=12"
+        "micromark-util-symbol": "^1.0.0"
       }
     },
-    "node_modules/make-dir": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
-      "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
-      "dev": true,
+    "node_modules/micromark-util-decode-string": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz",
+      "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true,
       "dependencies": {
-        "semver": "^7.5.3"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "decode-named-character-reference": "^1.0.0",
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-decode-numeric-character-reference": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0"
       }
     },
-    "node_modules/make-error": {
-      "version": "1.3.6",
-      "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
-      "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
-      "dev": true
+    "node_modules/micromark-util-encode": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz",
+      "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true
     },
-    "node_modules/make-fetch-happen": {
-      "version": "13.0.0",
-      "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.0.tgz",
-      "integrity": "sha512-7ThobcL8brtGo9CavByQrQi+23aIfgYU++wg4B87AIS8Rb2ZBt/MEaDqzA00Xwv/jUjAjYkLHjVolYuTLKda2A==",
-      "dev": true,
+    "node_modules/micromark-util-html-tag-name": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz",
+      "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true
+    },
+    "node_modules/micromark-util-normalize-identifier": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz",
+      "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true,
       "dependencies": {
-        "@npmcli/agent": "^2.0.0",
-        "cacache": "^18.0.0",
-        "http-cache-semantics": "^4.1.1",
-        "is-lambda": "^1.0.1",
-        "minipass": "^7.0.2",
-        "minipass-fetch": "^3.0.0",
-        "minipass-flush": "^1.0.5",
-        "minipass-pipeline": "^1.2.4",
-        "negotiator": "^0.6.3",
-        "promise-retry": "^2.0.1",
-        "ssri": "^10.0.0"
-      },
-      "engines": {
-        "node": "^16.14.0 || >=18.0.0"
+        "micromark-util-symbol": "^1.0.0"
       }
     },
-    "node_modules/makeerror": {
-      "version": "1.0.12",
-      "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
-      "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
-      "dev": true,
+    "node_modules/micromark-util-resolve-all": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz",
+      "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true,
       "dependencies": {
-        "tmpl": "1.0.5"
+        "micromark-util-types": "^1.0.0"
       }
     },
-    "node_modules/mdn-data": {
-      "version": "2.0.30",
-      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
-      "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
-      "dev": true
-    },
-    "node_modules/media-typer": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
-      "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
+    "node_modules/micromark-util-sanitize-uri": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz",
+      "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true,
+      "dependencies": {
+        "micromark-util-character": "^1.0.0",
+        "micromark-util-encode": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0"
       }
     },
-    "node_modules/memfs": {
-      "version": "3.5.3",
-      "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz",
-      "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==",
-      "dev": true,
+    "node_modules/micromark-util-subtokenize": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz",
+      "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true,
       "dependencies": {
-        "fs-monkey": "^1.0.4"
-      },
-      "engines": {
-        "node": ">= 4.0.0"
+        "micromark-util-chunked": "^1.0.0",
+        "micromark-util-symbol": "^1.0.0",
+        "micromark-util-types": "^1.0.0",
+        "uvu": "^0.5.0"
       }
     },
-    "node_modules/merge-descriptors": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
-      "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==",
-      "dev": true
-    },
-    "node_modules/merge-stream": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
-      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
-      "dev": true
-    },
-    "node_modules/merge2": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
-      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
-      "engines": {
-        "node": ">= 8"
-      }
+    "node_modules/micromark-util-symbol": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz",
+      "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true
     },
-    "node_modules/methods": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
-      "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
+    "node_modules/micromark-util-types": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz",
+      "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==",
+      "funding": [
+        {
+          "type": "GitHub Sponsors",
+          "url": "https://github.com/sponsors/unifiedjs"
+        },
+        {
+          "type": "OpenCollective",
+          "url": "https://opencollective.com/unified"
+        }
+      ],
+      "optional": true
     },
     "node_modules/micromatch": {
       "version": "4.0.5",
@@ -16994,6 +18275,15 @@
         "mkdirp": "bin/cmd.js"
       }
     },
+    "node_modules/mri": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
+      "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
+      "optional": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/mrmime": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz",
@@ -17110,6 +18400,29 @@
       "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
       "dev": true
     },
+    "node_modules/ngx-markdown": {
+      "version": "17.1.1",
+      "resolved": "https://registry.npmjs.org/ngx-markdown/-/ngx-markdown-17.1.1.tgz",
+      "integrity": "sha512-BGNWGJ6tmfPx+ScZFq5qeGLgWJwsakjScZ2e+oUzm+97DAHpIHSl8gptNZvZgRhOiFdjLcKBcuY2Rz8WB6J6UQ==",
+      "dependencies": {
+        "tslib": "^2.3.0"
+      },
+      "optionalDependencies": {
+        "clipboard": "^2.0.11",
+        "emoji-toolkit": "^8.0.0",
+        "katex": "^0.16.0",
+        "mermaid": "^10.6.0",
+        "prismjs": "^1.28.0"
+      },
+      "peerDependencies": {
+        "@angular/common": "^17.0.0",
+        "@angular/core": "^17.0.0",
+        "@angular/platform-browser": "^17.0.0",
+        "marked": "^9.0.0",
+        "rxjs": "^6.5.3 || ^7.4.0",
+        "zone.js": "~0.14.0"
+      }
+    },
     "node_modules/nice-napi": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz",
@@ -17270,6 +18583,12 @@
       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
       "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ=="
     },
+    "node_modules/non-layered-tidy-tree-layout": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz",
+      "integrity": "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==",
+      "optional": true
+    },
     "node_modules/nopt": {
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.0.tgz",
@@ -19063,6 +20382,15 @@
         "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
+    "node_modules/prismjs": {
+      "version": "1.29.0",
+      "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
+      "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==",
+      "optional": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/proc-log": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz",
@@ -19633,6 +20961,12 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
+    "node_modules/robust-predicates": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz",
+      "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==",
+      "optional": true
+    },
     "node_modules/rollup": {
       "version": "3.29.4",
       "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
@@ -19680,6 +21014,12 @@
         "queue-microtask": "^1.2.2"
       }
     },
+    "node_modules/rw": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
+      "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==",
+      "optional": true
+    },
     "node_modules/rx": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz",
@@ -19694,6 +21034,18 @@
         "tslib": "^2.1.0"
       }
     },
+    "node_modules/sade": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
+      "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
+      "optional": true,
+      "dependencies": {
+        "mri": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/safe-buffer": {
       "version": "5.2.1",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -19718,7 +21070,7 @@
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
       "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
-      "dev": true
+      "devOptional": true
     },
     "node_modules/safevalues": {
       "version": "0.3.4",
@@ -19811,6 +21163,12 @@
       "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==",
       "dev": true
     },
+    "node_modules/select": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
+      "integrity": "sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==",
+      "optional": true
+    },
     "node_modules/select-hose": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
@@ -20601,6 +21959,12 @@
         "postcss": "^8.2.15"
       }
     },
+    "node_modules/stylis": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.0.tgz",
+      "integrity": "sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ==",
+      "optional": true
+    },
     "node_modules/stylus": {
       "version": "0.59.0",
       "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.59.0.tgz",
@@ -20941,6 +22305,12 @@
       "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
       "dev": true
     },
+    "node_modules/tiny-emitter": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
+      "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
+      "optional": true
+    },
     "node_modules/tmp": {
       "version": "0.0.33",
       "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@@ -21008,6 +22378,15 @@
         "typescript": ">=4.2.0"
       }
     },
+    "node_modules/ts-dedent": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz",
+      "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==",
+      "optional": true,
+      "engines": {
+        "node": ">=6.10"
+      }
+    },
     "node_modules/ts-loader": {
       "version": "9.5.1",
       "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz",
@@ -21449,6 +22828,19 @@
         "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
       }
     },
+    "node_modules/unist-util-stringify-position": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz",
+      "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==",
+      "optional": true,
+      "dependencies": {
+        "@types/unist": "^2.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/unified"
+      }
+    },
     "node_modules/universalify": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
@@ -21535,6 +22927,33 @@
         "uuid": "dist/bin/uuid"
       }
     },
+    "node_modules/uvu": {
+      "version": "0.5.6",
+      "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz",
+      "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==",
+      "optional": true,
+      "dependencies": {
+        "dequal": "^2.0.0",
+        "diff": "^5.0.0",
+        "kleur": "^4.0.3",
+        "sade": "^1.7.3"
+      },
+      "bin": {
+        "uvu": "bin.js"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/uvu/node_modules/diff": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
+      "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==",
+      "optional": true,
+      "engines": {
+        "node": ">=0.3.1"
+      }
+    },
     "node_modules/v8-compile-cache": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
@@ -22091,6 +23510,12 @@
         "defaults": "^1.0.3"
       }
     },
+    "node_modules/web-worker": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz",
+      "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==",
+      "optional": true
+    },
     "node_modules/webpack": {
       "version": "5.89.0",
       "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz",

+ 4 - 2
package.json

@@ -1,6 +1,6 @@
 {
   "name": "dn-dtools",
-  "version": "0.0.0",
+  "version": "0.1.0",
   "scripts": {
     "ng": "ng",
     "start": "nx serve",
@@ -25,6 +25,8 @@
     "@popperjs/core": "^2.11.6",
     "bootstrap": "^5.2.3",
     "localbase": "^0.7.5",
+    "marked": "^9.0.0",
+    "ngx-markdown": "^17.1.1",
     "rxjs": "~7.8.0",
     "tslib": "^2.3.0",
     "zone.js": "~0.14.2"
@@ -49,4 +51,4 @@
     "nx": "17.0.2",
     "typescript": "~5.2.2"
   }
-}
+}

+ 52 - 6
src/app/character/character-creator/character-creator.component.html

@@ -1,7 +1,53 @@
-<div>
-  <div>
-    <label>Name</label>
-    <input [(ngModel)]="characterName" />
-  </div>
-  <button (click)="createCharacter()">Neuen Charakter erstellen</button>
+<div class="creation-container">
+  <form class="form-box">
+    <h3 style="text-align: center">Neuen Charakter erstellen</h3>
+    <mat-form-field appearance="outline">
+      <mat-label>Name</mat-label>
+      <input matInput [(ngModel)]="characterName" name="name" />
+    </mat-form-field>
+    <mat-form-field appearance="outline">
+      <mat-label>Volk</mat-label>
+      <mat-select [(ngModel)]="characterSpecies" name="species">
+        @for (species of species; track species) {
+        <mat-option [value]="species.value">{{ species.view }}</mat-option>
+        }
+      </mat-select>
+    </mat-form-field>
+    <mat-form-field appearance="outline">
+      <mat-label>Klasse</mat-label>
+      <mat-select [(ngModel)]="characterClass" name="class">
+        @for (characterClass of classes; track characterClass) {
+        <mat-option [value]="characterClass.value">{{
+          characterClass.view
+        }}</mat-option>
+        }
+      </mat-select>
+    </mat-form-field>
+    <mat-form-field appearance="outline">
+      <mat-label>Hintergrund</mat-label>
+      <mat-select [(ngModel)]="characterBackground" name="background">
+        @for (background of backgrounds; track background) {
+        <mat-option [value]="background.value">{{
+          background.view
+        }}</mat-option>
+        }
+      </mat-select>
+    </mat-form-field>
+    <mat-form-field appearance="outline">
+      <mat-label>Geschlecht</mat-label>
+      <mat-select [(ngModel)]="characterGender" name="gender">
+        @for (gender of genders; track gender) {
+        <mat-option [value]="gender.value">{{ gender.view }}</mat-option>
+        }
+      </mat-select>
+    </mat-form-field>
+    <div class="button-row">
+      <button class="create-button" (click)="createCharacter()">
+        Erstellen
+      </button>
+      <button class="cancel-button" [routerLink]="'character/picker'">
+        Abbrechen
+      </button>
+    </div>
+  </form>
 </div>

+ 56 - 0
src/app/character/character-creator/character-creator.component.scss

@@ -0,0 +1,56 @@
+.creation-container {
+    background-color: var(--background-color);
+    background-size: cover;
+    height: 100%;
+    width: 100%;
+    padding-top: 3rem;
+    // display: flex;
+}
+
+.form-box {
+    padding: 1rem;
+    margin: auto;
+    width: 800px;
+    border: 1px solid var(--border-color);
+    background-color: var(--secondary-color-light);
+    box-shadow: var(--shadow);
+    border-radius: 10px;
+    display: flex;
+    flex-direction: column;
+    gap: 1rem;
+}
+
+@mixin button {
+    color: black;
+    border: none;
+    border-radius: 10px;
+    box-shadow: var(--shadow);
+    height: 4rem;
+    width: 12rem;
+    font-size: 1.125rem;
+    font-weight: 600;
+    transition: all 0.2s ease-in-out;
+}
+
+.button-row {
+    display: flex;
+    justify-content: space-around;
+    margin-top: 1rem;
+}
+.cancel-button {
+    background: var(--delete);
+    @include button;
+    &:hover {
+        background: var(--delete-hover);
+        scale: 1.03;
+    }
+}
+
+.create-button {
+    background: var(--accept);
+    @include button;
+    &:hover {
+        background: var(--accept-hover);
+        scale: 1.03;
+    }
+}

+ 113 - 44
src/app/character/character-creator/character-creator.component.ts

@@ -2,20 +2,103 @@ import { Component } from '@angular/core';
 import { DataService } from 'src/services/data/data.service';
 import { Router } from '@angular/router';
 
+interface characterData {
+  view: string;
+  value: string;
+}
+
 @Component({
   selector: 'app-character-creator',
   templateUrl: './character-creator.component.html',
   styleUrls: ['./character-creator.component.scss'],
 })
 export class CharacterCreatorComponent {
+  selectedValue: string = '';
+
+  // TODO: Implement the species
+  public species: characterData[] = [
+    { view: 'Mensch', value: 'Human' },
+    { view: 'Zwerg', value: 'Dwarf' },
+    { view: 'Elf', value: 'Elf' },
+    { view: 'Halbelf', value: 'HalfElf' },
+    { view: 'Halbelf (Mal des Entdeckens)', value: 'HalfElfDetection' },
+    { view: 'Halbling', value: 'Halfling' },
+    { view: 'Gnom', value: 'Gnome' },
+    { view: 'Halbork', value: 'HalfOrc' },
+    { view: 'Tiefling', value: 'Tiefling' },
+  ];
+
+  // TODO: Implement the classes
+  public classes: characterData[] = [
+    { view: 'Barbar', value: 'Barbarian' },
+    { view: 'Barde', value: 'Bard' },
+    { view: 'Druide', value: 'Druid' },
+    { view: 'Hexenmeister', value: 'Warlock' },
+    { view: 'Kämpfer', value: 'Fighter' },
+    { view: 'Kleriker', value: 'Cleric' },
+    { view: 'Magier', value: 'Wizard' },
+    { view: 'Mönch', value: 'Monk' },
+    { view: 'Paladin', value: 'Paladin' },
+    { view: 'Schurke', value: 'Rogue' },
+    { view: 'Waldläufer', value: 'Ranger' },
+    { view: 'Zauberer', value: 'Sorcerer' },
+  ];
+
+  public backgrounds: characterData[] = [
+    { view: 'Akolyth', value: 'acolyte' },
+    { view: 'Scharlatan', value: 'charlatan' },
+    { view: 'Edelmann', value: 'noble' },
+    { view: 'Entertainer', value: 'entertainer' },
+    { view: 'Folk Held', value: 'folkHero' },
+    { view: 'Gelehrter', value: 'sage' },
+    { view: 'Gladiator', value: 'gladiator' },
+    { view: 'Gildenhändler', value: 'guildArtisan' },
+    { view: 'Gildehandwerker', value: 'guildMerchant' },
+    { view: 'Herumtreiber', value: 'outlander' },
+    { view: 'Krimineller', value: 'criminal' },
+    { view: 'Künstler', value: 'artist' },
+    { view: 'Marine', value: 'sailor' },
+    { view: 'Scharlatan', value: 'charlatan' },
+    { view: 'Soldat', value: 'soldier' },
+    { view: 'Stadtwache', value: 'cityWatch' },
+    { view: 'Urchin', value: 'urchin' },
+  ];
+
+  public genders: characterData[] = [
+    { view: 'Weiblich', value: 'Female' },
+    { view: 'Männlich', value: 'Male' },
+    { view: 'Divers', value: 'Diverse' },
+  ];
+
+  public spellcastingAttributes: any = {
+    Barbarian: null,
+    Bard: 'Charisma',
+    Cleric: 'Wisdom',
+    Druid: 'Wisdom',
+    Fighter: null,
+    Monk: 'Wisdom',
+    Paladin: 'Charisma',
+    Ranger: 'Wisdom',
+    Rogue: 'Intelligence',
+    Sorcerer: 'Charisma',
+    Warlock: 'Charisma',
+    Wizard: 'Intelligence',
+  };
+
+  public characterName: string = '';
+  public characterClass: string = '';
+  public characterSpecies: string = '';
+  public characterBackground: string = '';
+  public characterGender: string = '';
+
   public constructor(
     public dataAccessor: DataService,
     private Router: Router
   ) {}
 
-  public characterName: string = '';
-
   public async createCharacter(): Promise<void> {
+    console.log(this.characterName);
+
     // Creates a new entry in the character collection
     this.dataAccessor.addData('characters', { name: this.characterName });
     // Creates a new collection with the character name
@@ -34,19 +117,31 @@ export class CharacterCreatorComponent {
       this.dataAccessor.addData(
         this.characterName,
         {
-          name: this.characterName,
-          class: '',
-          race: '',
-          level: '',
+          class: this.characterClass,
           subclass: '',
-          proficiency: '',
-          background: '',
-          experience: '',
-          inspiration: '',
-          proficiencyBonus: '',
+          race: this.characterSpecies,
+          background: this.characterBackground,
+          level: 1,
+          experience: 0,
+          image: '',
+          gender: this.characterGender,
+          age: '',
+          height: '',
+          weight: '',
+          eyes: '',
+          skin: '',
+          hair: '',
         },
         'characterData'
       ),
+      // Character Image
+      this.dataAccessor.addData(
+        this.characterName,
+        {
+          value: undefined,
+        },
+        'image'
+      ),
       // Character Attributes
       this.dataAccessor.addData(
         this.characterName,
@@ -161,6 +256,8 @@ export class CharacterCreatorComponent {
         {
           spellslots: [],
           showSpellslots: false,
+          spellcastingAttribute:
+            this.spellcastingAttributes[this.characterClass],
         },
         'spellslots'
       ),
@@ -174,31 +271,6 @@ export class CharacterCreatorComponent {
         },
         'kiPoints'
       ),
-
-      // Character Appearance
-      this.dataAccessor.addData(
-        this.characterName,
-        {
-          age: '',
-          height: '',
-          weight: '',
-          eyes: '',
-          skin: '',
-          hair: '',
-        },
-        'appearance'
-      ),
-      // Character Personality
-      this.dataAccessor.addData(
-        this.characterName,
-        {
-          personalityTraits: '',
-          ideals: '',
-          bonds: '',
-          flaws: '',
-        },
-        'personality'
-      ),
       // Weapons
       this.dataAccessor.addData(
         this.characterName,
@@ -207,7 +279,7 @@ export class CharacterCreatorComponent {
         },
         'favoriteWeapons'
       ),
-      // Inventory
+      // WEAPONS AND ARMOR
       this.dataAccessor.addData(
         this.characterName,
         {
@@ -215,6 +287,7 @@ export class CharacterCreatorComponent {
         },
         'weaponsAndArmor'
       ),
+      // MISCELLANEOUS
       this.dataAccessor.addData(
         this.characterName,
         {
@@ -222,6 +295,7 @@ export class CharacterCreatorComponent {
         },
         'miscellaneous'
       ),
+      // CONSUMABLES
       this.dataAccessor.addData(
         this.characterName,
         {
@@ -229,13 +303,7 @@ export class CharacterCreatorComponent {
         },
         'consumables'
       ),
-      this.dataAccessor.addData(
-        this.characterName,
-        {
-          data: [],
-        },
-        'money'
-      ),
+      // MONEY
       this.dataAccessor.addData(
         this.characterName,
         {
@@ -247,6 +315,7 @@ export class CharacterCreatorComponent {
         },
         'money'
       ),
+      // FOOD
       this.dataAccessor.addData(
         this.characterName,
         {

+ 27 - 2
src/app/character/character-picker/character-card/character-card.component.html

@@ -1,3 +1,28 @@
-<div class="character-card">
-  <div class="character-card__name">{{ character }}</div>
+<div class="character-card" (click)="selectCharacter()">
+  <div
+    class="delete-area"
+    (click)="deleteCharacter(); $event.stopPropagation()"
+  >
+    <img
+      style="width: 50%"
+      src="assets/icons/UIIcons/delete.svg"
+      alt="Delete Button"
+    />
+  </div>
+  <!-- The characterData is not loaded initially, so this is a workaround. Maybe add a resolver first -->
+  @if(image){
+  <img [src]="image" alt="portrait" />
+  } @else {
+  <img
+    [src]="'assets/images/' + characterData.gender + '.jpg'"
+    alt="character"
+  />
+  }
+  <div class="content">
+    <div class="name">{{ character }}</div>
+    <div class="level">Stufe {{ characterData.level }}</div>
+    <div class="species">{{ races[characterData.race].display }}</div>
+    <div class="class">{{ classes[characterData.class].display }}</div>
+    <!-- <div class="subclass">{{ characterData.class }}</div> -->
+  </div>
 </div>

+ 74 - 4
src/app/character/character-picker/character-card/character-card.component.scss

@@ -1,6 +1,76 @@
-.character-card{
-    width: 30vw;
-    height: 30vh;
+.character-card {
+    width: 35rem;
+    height: 20rem;
     border-radius: 10px;
     box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
-}
+    display: flex;
+    overflow: hidden;
+    position: relative;
+    background-color: var(--field-background-color);
+    box-shadow: var(--shadow);
+    position: relative;
+    &:hover {
+        filter: brightness(0.9);
+        .delete-area {
+            width: 5rem;
+        }
+        .content {
+            margin: 1rem 0.25rem 0 0.25rem;
+            transition: all 0.2s ease-in-out;
+        }
+    }
+    transition: all 0.2s ease-in-out;
+}
+
+.delete-area {
+    height: 20rem;
+    width: 0rem;
+    background-color: var(--delete);
+    transition: all 0.2s ease-in-out;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    &:hover {
+        background-color: var(--delete-hover);
+    }
+}
+
+img {
+    width: 20rem;
+    height: 20rem;
+}
+
+.content {
+    width: 15rem;
+    margin: 1rem;
+}
+
+.name {
+    font-size: 1.75rem;
+    font-weight: 600;
+    text-align: center;
+}
+
+.level {
+    position: absolute;
+    right: 0.5rem;
+    bottom: 8rem;
+}
+
+.species {
+    position: absolute;
+    right: 0.5rem;
+    bottom: 6rem;
+}
+
+.class {
+    position: absolute;
+    right: 0.5rem;
+    bottom: 4rem;
+}
+
+.subclass {
+    position: absolute;
+    right: 0.5rem;
+    bottom: 2rem;
+}

+ 36 - 3
src/app/character/character-picker/character-card/character-card.component.ts

@@ -1,11 +1,44 @@
-import { Component, Input } from '@angular/core';
-import { Character } from 'src/interfaces/character';
+import { Component, Input, Output, EventEmitter } from '@angular/core';
+import { DataService } from 'src/services/data/data.service';
+import { TranslatorService } from 'src/services/translator/translator.service';
 
 @Component({
-  selector: 'app-character-card',
+  selector: 'character-card',
   templateUrl: './character-card.component.html',
   styleUrls: ['./character-card.component.scss'],
 })
 export class CharacterCardComponent {
   @Input() character: string = '';
+  @Output() delete: EventEmitter<string> = new EventEmitter<string>();
+  @Output() select: EventEmitter<string> = new EventEmitter<string>();
+  public characterData: any = {};
+  public image: any;
+  public races: any;
+  public classes: any;
+
+  constructor(
+    private dataAccessor: DataService,
+    private translator: TranslatorService
+  ) {}
+
+  ngOnInit() {
+    this.races = this.translator.races;
+    this.classes = this.translator.classes;
+    this.dataAccessor
+      .getData(this.character, 'characterData')
+      .then((characterData: any) => {
+        this.characterData = characterData;
+      });
+    this.dataAccessor.getData(this.character, 'image').then((image: any) => {
+      this.image = image.value;
+    });
+  }
+
+  public deleteCharacter(): void {
+    this.delete.emit();
+  }
+
+  public selectCharacter(): void {
+    this.select.emit();
+  }
 }

+ 41 - 11
src/app/character/character-picker/character-picker.component.html

@@ -1,13 +1,43 @@
-<div class="charater-picker-page">
-  <div class="character-card-container">
-    <ng-container *ngFor="let character of characters">
-      <app-character-card
-        [character]="character"
-        (click)="selectCharacter(character)"
-      ></app-character-card>
-    </ng-container>
+<div class="header">
+  <h1>DND-TOOLS</h1>
+</div>
+<div class="character-card-container">
+  @for (card of [0,1,2,3,4,5]; track card){ @if(characters[card]){
+  <character-card
+    [character]="characters[card].name"
+    (select)="selectCharacter(characters[card])"
+    (delete)="open(content, card)"
+  ></character-card>
+  }@else {
+  <div class="card-placeholder" (click)="addCharacter()">
+    <!-- <icon [size]="'l'" [type]="'UI'" [icon]="'add'"></icon> -->
+    <img
+      src="assets/icons/UIIcons/add.svg"
+      style="width: 6%"
+      alt="Add Button"
+    />
   </div>
-
-  <button (click)="addCharacter()">Add Character</button>
-  <button (click)="getCharacters()">Print Characters</button>
+  } }
 </div>
+
+<ng-template #content let-modal>
+  <div class="modal-header">
+    <h4 class="modal-title" id="modal-basic-title">Charakter löschen</h4>
+    <button
+      type="button"
+      class="btn-close"
+      aria-label="Close"
+      (click)="modal.dismiss('dismiss')"
+    ></button>
+  </div>
+  <div class="modal-body">
+    Möchest du <b>{{ currentCharacter }}</b> unwiderruflich löschen?
+  </div>
+  <div class="modal-footer">
+    <div class="button-row">
+      <button class="delete-button" (click)="modal.dismiss('delete')">
+        Löschen
+      </button>
+    </div>
+  </div>
+</ng-template>

+ 71 - 5
src/app/character/character-picker/character-picker.component.scss

@@ -1,10 +1,76 @@
+// HEADER
+.header {
+    background-color: var(--header);
+    height: 8rem;
+    box-shadow: var(--shadow);
+    position: relative;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+::ng-deep body {
+    background-color: var(--background-color);
+}
+
+// CARDS
+
 .character-card-container {
     display: flex;
     flex-direction: row;
-    align-items: center;
+    justify-content: space-evenly;
     flex-wrap: wrap;
-    column-gap: 2.5vw;
-    row-gap: 2.5vh;
+    padding-top: 2.5rem;
+    row-gap: 2.5rem;
+    overflow: auto;
+    height: calc(100% - 8rem);
+    background-color: var(--background-color);
+}
+
+character-card {
+    cursor: pointer;
+    max-height: 20rem;
+}
+
+.card-placeholder {
+    height: 20rem;
+    width: 35rem;
+    background-color: lightgrey;
+    border-radius: 10px;
+    box-shadow: var(--shadow);
+    display: flex;
     justify-content: center;
-    width: 100%;
-}
+    align-items: center;
+    font-size: 1.5rem;
+    font-weight: 600;
+    transition: all 0.2s ease-in-out;
+    &:hover {
+        background-color: rgb(191, 191, 191);
+    }
+}
+
+@mixin button {
+    color: black;
+    border: none;
+    border-radius: 10px;
+    box-shadow: var(--shadow);
+    height: 4rem;
+    width: 10rem;
+    font-size: 1.125rem;
+    font-weight: 600;
+    transition: all 0.2s ease-in-out;
+}
+
+.button-row {
+    display: flex;
+    justify-content: space-around;
+    margin-top: 1rem;
+}
+.delete-button {
+    background: var(--delete);
+    @include button;
+    &:hover {
+        background: var(--delete-hover);
+        scale: 1.03;
+    }
+}

+ 34 - 14
src/app/character/character-picker/character-picker.component.ts

@@ -1,7 +1,7 @@
-import { Component } from '@angular/core';
+import { Component, inject, TemplateRef } from '@angular/core';
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
 import { DataService } from 'src/services/data/data.service';
 import { Router } from '@angular/router';
-import { Character } from 'src/interfaces/character';
 
 @Component({
   selector: 'app-character-picker',
@@ -9,18 +9,14 @@ import { Character } from 'src/interfaces/character';
   styleUrls: ['./character-picker.component.scss'],
 })
 export class CharacterPickerComponent {
-  public constructor(public dataService: DataService, private Router: Router) {
-    this.getCharacters();
-  }
+  public characters: any[] = [];
+  public currentCharacter: string = '';
+  private modalService = inject(NgbModal);
 
-  public characters: string[] = [];
-  public index = 0;
-
-  public getCharacters() {
+  public constructor(public dataService: DataService, private Router: Router) {
+    this.dataService.dataLoaded = false;
     this.dataService.getCollection('characters').then((characters: any) => {
-      characters.forEach((character: any) => {
-        this.characters.push(character.name);
-      });
+      this.characters = characters;
     });
   }
 
@@ -28,8 +24,32 @@ export class CharacterPickerComponent {
     this.Router.navigate(['character/creator']);
   }
 
-  public selectCharacter(character: string) {
-    sessionStorage.setItem('characterName', character);
+  open(content: TemplateRef<any>, index: number) {
+    this.currentCharacter = this.characters[index].name;
+    this.modalService
+      .open(content, { ariaLabelledBy: 'modal-basic-title' })
+      .result.then(
+        (result) => {},
+        (reason) => {
+          if (reason == 'delete') {
+            this.deleteCharacter(index);
+          }
+        }
+      );
+  }
+
+  public deleteCharacter(index: number) {
+    this.characters.splice(index, 1);
+    this.dataService.deleteCollection(this.currentCharacter);
+    this.dataService.deleteCollection('characters');
+    setTimeout(() => {
+      this.dataService.setCollection('characters', this.characters);
+    }, 1000);
+  }
+
+  public selectCharacter(character: any) {
+    console.log(character);
+    sessionStorage.setItem('characterName', character.name);
     this.Router.navigate(['journal']);
   }
 }

+ 7 - 0
src/app/character/character-picker/deletion-confirm/deletion-confirm.component.html

@@ -0,0 +1,7 @@
+<div class="modal-dimensions">
+  Wollen Sie {{ name }} endgültig löschen?
+
+  <button (click)="delete()">Ja</button>
+
+  <button (click)="cancel()">Nein</button>
+</div>

+ 7 - 0
src/app/character/character-picker/deletion-confirm/deletion-confirm.component.scss

@@ -0,0 +1,7 @@
+.modal-dimensions {
+    width: 15rem;
+    background-color: var(--modal-background);
+    border-radius: 10px;
+    border: 1px solid var(--border-color);
+    padding: 1rem;
+}

+ 23 - 0
src/app/character/character-picker/deletion-confirm/deletion-confirm.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DeletionConfirmComponent } from './deletion-confirm.component';
+
+describe('DeletionConfirmComponent', () => {
+  let component: DeletionConfirmComponent;
+  let fixture: ComponentFixture<DeletionConfirmComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [DeletionConfirmComponent]
+    })
+    .compileComponents();
+    
+    fixture = TestBed.createComponent(DeletionConfirmComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 27 - 0
src/app/character/character-picker/deletion-confirm/deletion-confirm.component.ts

@@ -0,0 +1,27 @@
+import { Component, Input } from '@angular/core';
+import { ModalService } from 'src/services/modal/modal.service';
+
+@Component({
+  selector: 'deletion-confirm',
+  templateUrl: './deletion-confirm.component.html',
+  styleUrl: './deletion-confirm.component.scss',
+})
+export class DeletionConfirmComponent {
+  @Input() name: string = '';
+
+  public constructor(private modalAccessor: ModalService) {}
+
+  ngOnInit() {
+    console.log('DeletionConfirmComponent initialized');
+  }
+
+  // RESPONSES
+
+  public cancel(): void {
+    this.modalAccessor.handleModalClosing('cancel', undefined);
+  }
+
+  public delete(): void {
+    this.modalAccessor.handleModalClosing('add', undefined);
+  }
+}

+ 14 - 1
src/app/character/character.module.ts

@@ -1,23 +1,36 @@
 import { NgModule } from '@angular/core';
 import { CommonModule } from '@angular/common';
-import { FormsModule } from '@angular/forms';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
 import { CharacterRoutingModule } from './character-routing.module';
 import { CharacterPickerComponent } from './character-picker/character-picker.component';
 import { CharacterCreatorComponent } from './character-creator/character-creator.component';
 import { CharacterCardComponent } from './character-picker/character-card/character-card.component';
 import { MatSlideToggleModule } from '@angular/material/slide-toggle';
+import { MatIconModule } from '@angular/material/icon';
+import { MatInputModule } from '@angular/material/input';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatSelectModule } from '@angular/material/select';
+import { MatAutocompleteModule } from '@angular/material/autocomplete';
+import { DeletionConfirmComponent } from './character-picker/deletion-confirm/deletion-confirm.component';
 
 @NgModule({
   declarations: [
     CharacterPickerComponent,
     CharacterCreatorComponent,
     CharacterCardComponent,
+    DeletionConfirmComponent,
   ],
   imports: [
     CommonModule,
     CharacterRoutingModule,
     FormsModule,
+    ReactiveFormsModule,
     MatSlideToggleModule,
+    MatIconModule,
+    MatInputModule,
+    MatFormFieldModule,
+    MatSelectModule,
+    MatAutocompleteModule,
   ],
 })
 export class CharacterModule {}

+ 1 - 0
src/app/journal/journal-character/background/background.component.html

@@ -0,0 +1 @@
+<p>background works!</p>

+ 0 - 0
src/app/journal/journal-character/background/background.component.scss


+ 23 - 0
src/app/journal/journal-character/background/background.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { BackgroundComponent } from './background.component';
+
+describe('BackgroundComponent', () => {
+  let component: BackgroundComponent;
+  let fixture: ComponentFixture<BackgroundComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [BackgroundComponent]
+    })
+    .compileComponents();
+    
+    fixture = TestBed.createComponent(BackgroundComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 10 - 0
src/app/journal/journal-character/background/background.component.ts

@@ -0,0 +1,10 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'app-background',
+  templateUrl: './background.component.html',
+  styleUrl: './background.component.scss'
+})
+export class BackgroundComponent {
+
+}

+ 17 - 0
src/app/journal/journal-character/class/class.component.html

@@ -0,0 +1,17 @@
+<div class="class-container">
+  <div class="title">{{ class.title }}</div>
+
+  <markdown [data]="class.description"></markdown>
+
+  <div class="features">
+    @for(feature of class.features; track feature){
+    <div class="feature">
+      <div class="feature-name">{{ feature.name }}</div>
+      <markdown
+        class="feature-description"
+        [data]="feature.description"
+      ></markdown>
+    </div>
+    }
+  </div>
+</div>

+ 43 - 0
src/app/journal/journal-character/class/class.component.scss

@@ -0,0 +1,43 @@
+.class-container {
+    width: 800px;
+    height: 100%;
+    overflow: auto;
+    margin: auto;
+    border: 1px solid black;
+    padding: 2rem;
+    border-radius: 10px;
+}
+
+.title {
+    text-align: center;
+    font-size: 2em;
+    font-weight: bold;
+    margin: 0 0 2rem 0;
+}
+
+.description {
+}
+
+.feature {
+    margin-top: 2rem;
+}
+
+.feature-name {
+    font-size: 1.5rem;
+    font-weight: 600;
+    margin-bottom: 1rem;
+    // text-align: center;
+}
+
+.feature-description {
+    margin-top: 1rem;
+}
+
+:host ::ng-deep p {
+    margin: 0;
+}
+
+:host ::ng-deep h3,
+:host ::ng-deep h4 {
+    margin-top: 1rem;
+}

+ 23 - 0
src/app/journal/journal-character/class/class.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ClassComponent } from './class.component';
+
+describe('ClassComponent', () => {
+  let component: ClassComponent;
+  let fixture: ComponentFixture<ClassComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ClassComponent]
+    })
+    .compileComponents();
+    
+    fixture = TestBed.createComponent(ClassComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 23 - 0
src/app/journal/journal-character/class/class.component.ts

@@ -0,0 +1,23 @@
+import { Component } from '@angular/core';
+import { ClassService } from 'src/services/class/class.service';
+import { DataService } from 'src/services/data/data.service';
+
+@Component({
+  selector: 'class',
+  templateUrl: './class.component.html',
+  styleUrl: './class.component.scss',
+})
+export class ClassComponent {
+  public className: string = '';
+  public class: any;
+  public constructor(
+    private classAccessor: ClassService,
+    private dataAccessor: DataService
+  ) {}
+
+  public ngOnInit(): void {
+    this.className = this.dataAccessor.characterData.class;
+    this.class = this.classAccessor.getClassDetails(this.className);
+    console.log(this.class);
+  }
+}

+ 143 - 0
src/app/journal/journal-character/general/general.component.html

@@ -0,0 +1,143 @@
+<div class="general-container">
+  <div class="first-row">
+    <div class="image-container">
+      <img
+        class="image-icon"
+        *ngIf="!image"
+        src="assets/icons/UIIcons/image.svg"
+        alt="Bild"
+      />
+      <img class="portrait" *ngIf="image" [src]="image" alt="portrait" />
+      <img
+        class="upload-icon"
+        src="assets/icons/UIIcons/upload.svg"
+        alt="upload"
+      />
+      <input
+        id="fileInput"
+        class="upload-input"
+        type="file"
+        (change)="onImageUpload($event)"
+      />
+    </div>
+    <!-- LOOKS -->
+    <div class="looks">
+      <div class="looks-entry">
+        <label class="looks-label">Volk</label>
+        <div class="looks-field">
+          {{ races[data.race].display }}
+        </div>
+      </div>
+      <div class="looks-entry">
+        <label class="looks-label">Klasse</label>
+        <div class="looks-field">
+          {{ classes[data.class].display }}
+        </div>
+      </div>
+      <div class="looks-entry">
+        <label class="looks-label">Geschlecht</label>
+        <div class="looks-field">
+          {{ genders[data.gender].display }}
+        </div>
+      </div>
+      <div class="looks-entry">
+        <div class="looks-label">Alter</div>
+        <input
+          type="text"
+          class="looks-input"
+          [(ngModel)]="data.age"
+          (change)="updateData()"
+        />
+      </div>
+      <div class="looks-entry">
+        <div class="looks-label">Größe</div>
+        <input
+          type="text"
+          class="looks-input"
+          [(ngModel)]="data.height"
+          (change)="updateData()"
+        />
+      </div>
+      <div class="looks-entry">
+        <div class="looks-label">Gewicht</div>
+        <input
+          type="text"
+          class="looks-input"
+          [(ngModel)]="data.weight"
+          (change)="updateData()"
+        />
+      </div>
+      <div class="looks-entry">
+        <div class="looks-label">Haarfarbe</div>
+        <input
+          type="text"
+          class="looks-input"
+          [(ngModel)]="data.hair"
+          (change)="updateData()"
+        />
+      </div>
+      <div class="looks-entry">
+        <div class="looks-label">Augenfarbe</div>
+        <input
+          type="text"
+          class="looks-input"
+          [(ngModel)]="data.eyes"
+          (change)="updateData()"
+        />
+      </div>
+      <div class="looks-entry">
+        <div class="looks-label">Hautfarbe</div>
+        <input
+          type="text"
+          class="looks-input"
+          [(ngModel)]="data.skin"
+          (change)="updateData()"
+        />
+      </div>
+    </div>
+    <!-- DESCRIPTION -->
+    <div class="description">
+      <textarea
+        class="description-area"
+        [(ngModel)]="data.description"
+        (change)="updateData()"
+      ></textarea>
+      <label class="description-label">Beschreibung</label>
+    </div>
+  </div>
+  <!-- PERSONALITY -->
+  <div class="personality">
+    <div class="personality-box">
+      <textarea
+        class="personality-area"
+        [(ngModel)]="data.personalityTraits"
+        (change)="updateData()"
+      ></textarea>
+      <label class="personality-label">Persönlichkeitsmerkmale</label>
+    </div>
+    <div class="personality-box">
+      <textarea
+        class="personality-area"
+        [(ngModel)]="data.ideals"
+        (change)="updateData()"
+      ></textarea>
+      <label class="personality-label">Ideale</label>
+    </div>
+    <div class="personality-box">
+      <textarea
+        class="personality-area"
+        [(ngModel)]="data.bonds"
+        (change)="updateData()"
+      ></textarea>
+      <label class="personality-label">Bindungen</label>
+    </div>
+    <div class="personality-box">
+      <textarea
+        class="personality-area"
+        [(ngModel)]="data.flaws"
+        (change)="updateData()"
+      ></textarea>
+      <label class="personality-label">Makel</label>
+    </div>
+  </div>
+</div>

+ 157 - 0
src/app/journal/journal-character/general/general.component.scss

@@ -0,0 +1,157 @@
+.general-container {
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    row-gap: 2rem;
+}
+
+.first-row {
+    display: flex;
+    justify-content: space-between;
+}
+
+.image-container {
+    width: 24rem;
+    height: 24rem;
+    position: relative;
+    border: 1px solid var(--border-color);
+    border-radius: 10px;
+    box-shadow: var(--shadow);
+    border-radius: 10px;
+    overflow: hidden;
+
+    &:hover {
+        .upload-icon {
+            opacity: 1;
+        }
+        .image-icon {
+            opacity: 0;
+        }
+        .portrait {
+            filter: brightness(0.8);
+        }
+    }
+
+    .portrait {
+        width: 24rem;
+        height: 24rem;
+        object-fit: cover;
+        transition: all 0.2s ease-in-out;
+    }
+
+    .upload-icon {
+        position: absolute;
+        opacity: 0;
+        left: 12rem;
+        top: 12rem;
+        width: 3rem;
+        height: 3rem;
+        transform: translate(-50%, -50%);
+        transition: all 0.2s ease-in-out;
+        background-color: #b7b7b763;
+        border-radius: 10px;
+    }
+
+    .image-icon {
+        position: absolute;
+        opacity: 1;
+        left: 12rem;
+        top: 12rem;
+        width: 3rem;
+        height: 3rem;
+        transform: translate(-50%, -50%);
+        transition: all 0.2s ease-in-out;
+    }
+
+    .upload-input {
+        width: 100%;
+        height: 100%;
+        position: absolute;
+        opacity: 0;
+        top: 0;
+        left: 0;
+        cursor: pointer;
+    }
+}
+
+.looks {
+    width: 25rem;
+    padding: 0 2rem;
+    display: flex;
+    flex-direction: column;
+    gap: 1rem;
+
+    .looks-entry {
+        display: flex;
+        justify-content: space-between;
+
+        .looks-input {
+            border-radius: 4px;
+            border: 1px solid var(--border-color);
+            box-shadow: var(--shadow);
+            padding-left: 1rem;
+        }
+
+        .looks-field {
+            width: 12.5rem;
+            height: 1.75rem;
+            background-color: white;
+            border-radius: 4px;
+            border: 1px solid var(--border-color);
+            box-shadow: var(--shadow);
+            padding-left: 1rem;
+        }
+    }
+}
+
+.description {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    gap: 1rem;
+
+    .description-area {
+        width: 20rem;
+        height: 90%;
+        border: 1px solid var(--border-color);
+        border-radius: 10px;
+        box-shadow: var(--shadow);
+        resize: none;
+        padding: 1rem;
+    }
+
+    .description-label {
+        font-weight: 500;
+    }
+}
+
+.personality {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    gap: 3rem;
+
+    .personality-box {
+        width: 25%;
+        height: 15rem;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        gap: 0.75rem;
+        margin-top: 1rem;
+
+        .personality-area {
+            width: 100%;
+            height: 100%;
+            border: 1px solid var(--border-color);
+            border-radius: 10px;
+            box-shadow: var(--shadow);
+            resize: none;
+            padding: 1rem;
+        }
+
+        .personality-label {
+            font-weight: 500;
+        }
+    }
+}

+ 23 - 0
src/app/journal/journal-character/general/general.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { GeneralComponent } from './general.component';
+
+describe('GeneralComponent', () => {
+  let component: GeneralComponent;
+  let fixture: ComponentFixture<GeneralComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [GeneralComponent]
+    })
+    .compileComponents();
+    
+    fixture = TestBed.createComponent(GeneralComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 45 - 0
src/app/journal/journal-character/general/general.component.ts

@@ -0,0 +1,45 @@
+import { Component } from '@angular/core';
+import { DataService } from 'src/services/data/data.service';
+import { TranslatorService } from 'src/services/translator/translator.service';
+
+@Component({
+  selector: 'general',
+  templateUrl: './general.component.html',
+  styleUrl: './general.component.scss',
+})
+export class GeneralComponent {
+  public data: any;
+  public image: any;
+  public races: any;
+  public classes: any;
+  public genders: any;
+
+  public constructor(
+    public dataAccessor: DataService,
+    private translator: TranslatorService
+  ) {}
+
+  ngOnInit(): void {
+    this.data = this.dataAccessor.characterData;
+    this.image = this.dataAccessor.image.value;
+    this.races = this.translator.races;
+    this.classes = this.translator.classes;
+    this.genders = this.translator.genders;
+  }
+
+  public updateData(): void {
+    console.log(this.data);
+
+    this.dataAccessor.characterData = this.data;
+  }
+
+  public onImageUpload(event: any): void {
+    const file = event.target.files[0];
+    const reader = new FileReader();
+    reader.onload = () => {
+      this.image = reader.result;
+      this.dataAccessor.image = { value: reader.result };
+    };
+    reader.readAsDataURL(file);
+  }
+}

+ 75 - 14
src/app/journal/journal-character/journal-character.component.html

@@ -1,15 +1,76 @@
-<div
-  style="
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    height: 100%;
-    width: 100%;
-  "
->
-  <img
-    style="height: 100%"
-    src="assets/images/character_coming_soon.jpeg"
-    alt=""
-  />
+<div class="header">
+  <div class="header-data">
+    <input type="number" [(ngModel)]="data.level" (change)="updateData()" />
+    <div class="horizontal-ruler"></div>
+    Stufe
+  </div>
+  <div class="name">{{ name }}</div>
+  <div class="header-data">
+    <input
+      type="number"
+      [(ngModel)]="data.experience"
+      (change)="updateData()"
+    />
+    <div class="horizontal-ruler"></div>
+    Erfahrungspunkte
+  </div>
+</div>
+<div class="character-body">
+  <div class="d-flex">
+    <div
+      ngbNav
+      #nav="ngbNav"
+      [(activeId)]="activeTab"
+      class="flex-column navigation-bar"
+      orientation="vertical"
+    >
+      <ng-container ngbNavItem="general">
+        <button ngbNavLink>Allgemeines</button>
+        <ng-template ngbNavContent>
+          <general></general>
+        </ng-template>
+      </ng-container>
+      <ng-container ngbNavItem="species">
+        <button ngbNavLink>Volk</button>
+        <ng-template ngbNavContent>
+          <species></species>
+        </ng-template>
+      </ng-container>
+      <ng-container ngbNavItem="class">
+        <button ngbNavLink>Klasse</button>
+        <ng-template ngbNavContent>
+          <class></class>
+        </ng-template>
+      </ng-container>
+      <ng-container ngbNavItem="subclass">
+        <button ngbNavLink>Unterklasse</button>
+        <ng-template ngbNavContent>
+          <subclass></subclass>
+        </ng-template>
+      </ng-container>
+      <ng-container ngbNavItem="combined">
+        <button ngbNavLink>Kombinierte Ansicht</button>
+        <ng-template ngbNavContent>
+          <!-- <class></class> -->
+          combined works!
+        </ng-template>
+      </ng-container>
+      <ng-container ngbNavItem="background">
+        <button ngbNavLink>Hintergrund</button>
+        <ng-template ngbNavContent>
+          <!-- <class></class> -->
+          background works!
+        </ng-template>
+      </ng-container>
+      <ng-container ngbNavItem="stroy">
+        <button ngbNavLink>Geschichte</button>
+        <ng-template ngbNavContent>
+          <!-- <class></class> -->
+          story works!
+        </ng-template>
+      </ng-container>
+    </div>
+
+    <div [ngbNavOutlet]="nav" class="outlet"></div>
+  </div>
 </div>

+ 101 - 0
src/app/journal/journal-character/journal-character.component.scss

@@ -0,0 +1,101 @@
+.header {
+    display: flex;
+    justify-content: space-between;
+    height: 6.5rem;
+    background-color: var(--header);
+    box-shadow: var(--shadow);
+
+    .header-data {
+        margin: 0 5rem;
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        align-items: center;
+        height: 100%;
+
+        input {
+            width: 6rem;
+            border: none;
+            background: none;
+            font-size: 1.75rem;
+            font-weight: 600;
+            text-align: center;
+        }
+
+        input[type="number"]::-webkit-inner-spin-button,
+        input[type="number"]::-webkit-outer-spin-button {
+            -webkit-appearance: none;
+            margin: 0;
+        }
+        input[type="number"] {
+            -moz-appearance: textfield;
+        }
+    }
+
+    .name {
+        text-align: center;
+        font-size: 3em;
+        font-weight: bold;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        height: 100%;
+    }
+
+    .horizontal-ruler {
+        width: 8rem;
+        height: 1px;
+        border-top: 1px solid var(--border-color);
+    }
+}
+
+.character-body {
+    height: calc(100% - 11.5rem);
+
+    .navigation-bar {
+        padding-top: 1.5rem;
+        gap: 2rem;
+        box-shadow: var(--shadow);
+        height: calc(100% + 20rem);
+        align-items: center;
+
+        .nav-link {
+            // width: 80%;
+            // background-color: var(--button-color);
+            // border-radius: 10px;
+            // border: 1px solid var(--border-color);
+            // box-shadow: var(--shadow);
+
+            width: 90%;
+            border-radius: 10px;
+            transition: all 0.25s ease-in-out;
+            font-size: 1.25rem;
+            font-weight: 600;
+            color: var(--text);
+
+            &:hover {
+                background-color: var(--button-color-hover);
+                box-shadow: var(--shadow-hover);
+            }
+
+            &.active {
+                background-color: var(--button-color-hover);
+                box-shadow: var(--shadow-hover);
+            }
+        }
+    }
+
+    .outlet {
+        margin: 2.5rem 1.5rem 0 1.5rem;
+        width: 100%;
+    }
+
+    .d-flex {
+        height: 100%;
+    }
+
+    ::ng-deep .tab-pane {
+        height: 100%;
+        width: 100%;
+    }
+}

+ 15 - 1
src/app/journal/journal-character/journal-character.component.ts

@@ -1,10 +1,24 @@
 import { Component } from '@angular/core';
+import { DataService } from 'src/services/data/data.service';
 
 @Component({
   selector: 'app-journal-character',
   templateUrl: './journal-character.component.html',
-  styleUrls: ['./journal-character.component.scss']
+  styleUrls: ['./journal-character.component.scss'],
 })
 export class JournalCharacterComponent {
+  public activeTab: string = 'general';
 
+  public data: any = {};
+  public name = sessionStorage.getItem('characterName');
+
+  public constructor(public dataAccessor: DataService) {}
+
+  ngOnInit(): void {
+    this.data = this.dataAccessor.characterData;
+  }
+
+  public updateData(): void {
+    this.dataAccessor.characterData = this.data;
+  }
 }

+ 18 - 0
src/app/journal/journal-character/species/species.component.html

@@ -0,0 +1,18 @@
+<div class="species-container">
+  <div class="title">{{ species.title }}</div>
+  <!-- <div class="description" markdown="species.description">hi</div> -->
+
+  <markdown [data]="species.description"></markdown>
+
+  <div class="abilities">
+    @for(ability of species.abilities; track ability){
+    <div class="ability">
+      <div class="ability-name">{{ ability.name }}</div>
+      <markdown
+        class="ability-description"
+        [data]="ability.description"
+      ></markdown>
+    </div>
+    }
+  </div>
+</div>

+ 33 - 0
src/app/journal/journal-character/species/species.component.scss

@@ -0,0 +1,33 @@
+.species-container {
+    width: 800px;
+    height: 100%;
+    overflow: auto;
+    margin: auto;
+    border: 1px solid black;
+    padding: 2rem;
+    border-radius: 10px;
+}
+
+.title {
+    text-align: center;
+    font-size: 2em;
+    font-weight: bold;
+    margin: 0 0 2rem 0;
+}
+
+.description {
+}
+
+.abilities {
+    margin-top: 2rem;
+}
+
+.ability-name {
+    font-size: 1.25rem;
+    font-weight: 600;
+    text-align: center;
+}
+
+.ability-description {
+    margin-top: 1rem;
+}

+ 23 - 0
src/app/journal/journal-character/species/species.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SpeciesComponent } from './species.component';
+
+describe('SpeciesComponent', () => {
+  let component: SpeciesComponent;
+  let fixture: ComponentFixture<SpeciesComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [SpeciesComponent]
+    })
+    .compileComponents();
+    
+    fixture = TestBed.createComponent(SpeciesComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 21 - 0
src/app/journal/journal-character/species/species.component.ts

@@ -0,0 +1,21 @@
+import { Component } from '@angular/core';
+import { DataService } from 'src/services/data/data.service';
+import { SpeciesService } from 'src/services/species/species.service';
+
+@Component({
+  selector: 'species',
+  templateUrl: './species.component.html',
+  styleUrl: './species.component.scss',
+})
+export class SpeciesComponent {
+  species: any;
+  speciesName: string = '';
+
+  public constructor(
+    public speciesAccessor: SpeciesService,
+    public dataAccessor: DataService
+  ) {
+    this.speciesName = this.dataAccessor.characterData.race;
+    this.species = speciesAccessor.getSpeciesDetails(this.speciesName);
+  }
+}

+ 1 - 0
src/app/journal/journal-character/story/story.component.html

@@ -0,0 +1 @@
+<p>story works!</p>

+ 0 - 0
src/app/journal/journal-character/story/story.component.scss


+ 23 - 0
src/app/journal/journal-character/story/story.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { StoryComponent } from './story.component';
+
+describe('StoryComponent', () => {
+  let component: StoryComponent;
+  let fixture: ComponentFixture<StoryComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [StoryComponent]
+    })
+    .compileComponents();
+    
+    fixture = TestBed.createComponent(StoryComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 10 - 0
src/app/journal/journal-character/story/story.component.ts

@@ -0,0 +1,10 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'app-story',
+  templateUrl: './story.component.html',
+  styleUrl: './story.component.scss'
+})
+export class StoryComponent {
+
+}

+ 17 - 0
src/app/journal/journal-character/subclass/subclass.component.html

@@ -0,0 +1,17 @@
+<div class="subclass-container">
+  <div class="title">{{ subclass.title }}</div>
+
+  <markdown [data]="subclass.description"></markdown>
+
+  <div class="features">
+    @for(feature of subclass.features; track feature){
+    <div class="feature">
+      <div class="feature-name">{{ feature.name }}</div>
+      <markdown
+        class="feature-description"
+        [data]="feature.description"
+      ></markdown>
+    </div>
+    }
+  </div>
+</div>

+ 42 - 0
src/app/journal/journal-character/subclass/subclass.component.scss

@@ -0,0 +1,42 @@
+.subclass-container {
+    width: 800px;
+    height: 100%;
+    overflow: auto;
+    margin: auto;
+    border: 1px solid black;
+    padding: 2rem;
+    border-radius: 10px;
+}
+
+.title {
+    text-align: center;
+    font-size: 2em;
+    font-weight: bold;
+    margin: 0 0 2rem 0;
+}
+
+.description {
+}
+
+.feature {
+    margin-top: 2rem;
+}
+
+.feature-name {
+    font-size: 1.5rem;
+    font-weight: 600;
+    margin-bottom: 1rem;
+}
+
+.feature-description {
+    margin-top: 1rem;
+}
+
+:host ::ng-deep p {
+    margin: 0;
+}
+
+:host ::ng-deep h3,
+:host ::ng-deep h4 {
+    margin-top: 1rem;
+}

+ 23 - 0
src/app/journal/journal-character/subclass/subclass.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SubclassComponent } from './subclass.component';
+
+describe('SubclassComponent', () => {
+  let component: SubclassComponent;
+  let fixture: ComponentFixture<SubclassComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [SubclassComponent]
+    })
+    .compileComponents();
+    
+    fixture = TestBed.createComponent(SubclassComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 46 - 0
src/app/journal/journal-character/subclass/subclass.component.ts

@@ -0,0 +1,46 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'subclass',
+  templateUrl: './subclass.component.html',
+  styleUrl: './subclass.component.scss',
+})
+export class SubclassComponent {
+  public subclass: any = {
+    title: 'Peace Domain',
+    description: `
+      The balm of peace thrives at the heart of healthy communities, between friendly nations, and in the souls of the kindhearted. The gods of peace inspire people of all sorts to resolve conflict and to stand up against those forces that try to prevent peace from flourishing. See the Peace Deities table for a list of some of the gods associated with this domain.
+
+      Clerics of the Peace Domain preside over the signing of treaties, and they are often asked to arbitrate in disputes. These clerics' blessings draw people together and help them shoulder one another's burdens, and the clerics' magic aids those who are driven to fight for the way of peace.
+    `,
+    features: [
+      {
+        name: 'Implement of Peace',
+        level: 1,
+        description: `
+          When you choose this domain at 1st level, you gain proficiency in the Insight, Performance, or Persuasion skill (your choice).
+        `,
+      },
+      {
+        name: 'Emboldening Bond',
+        level: 1,
+        description: `
+          Starting at 1st level, you can forge an empowering bond among people who are at peace with one another. As an action, you choose a number of willing creatures within 30 feet of you (this can include yourself) equal to your proficiency bonus. You create a magical bond among them for 10 minutes or until you use this feature again. While any bonded creature is within 30 feet of another, the creature can roll a d4 and add the number rolled to an attack roll, an ability check, or a saving throw it makes. Each creature can add the d4 no more than once per turn.
+
+          You can use this feature a number of times equal to your proficiency bonus, and you regain all expended uses when you finish a long rest.
+        `,
+      },
+      {
+        name: 'Channel Divinity: Balm of Peace',
+        level: 2,
+        description: `
+          Starting at 2nd level, you can use your Channel Divinity to make your very presence a soothing balm. As an action, you can move up to your speed, without provoking opportunity attacks, and when you move within 5 feet of any other creature during this action, you can restore a number of hit points to that creature equal to 2d6 + your Wisdom modifier (minimum of 1 hit point). A creature can receive this healing only once whenever you take this action.
+        `,
+      },
+    ],
+  };
+
+  public subClassName: string = '';
+
+  // public constru
+}

+ 2 - 2
src/app/journal/journal-home/navigation-panel/navigation-panel.component.html

@@ -108,8 +108,8 @@
 
   <div class="settings-container">
     <button class="settings-button" [routerLink]="'../'">
-      <icon [size]="'s'" [type]="'UI'" [icon]="'character'"></icon>
-      <div>Charakterauswahl</div>
+      <icon [size]="'s'" [type]="'UI'" [icon]="'characters'"></icon>
+      <div>Charaktere</div>
     </button>
 
     <button class="settings-button">

+ 16 - 18
src/app/journal/journal-home/navigation-panel/navigation-panel.component.scss

@@ -1,20 +1,20 @@
-.backdrop{
+.backdrop {
     position: fixed;
     top: 0;
     left: 0;
-    right:0;
+    right: 0;
     bottom: 0;
     visibility: hidden;
-    background: rgba(0,0,0,0.2);
+    background: rgba(0, 0, 0, 0.2);
     z-index: 1000;
     cursor: pointer;
 }
 
-.backdrop--open{
+.backdrop--open {
     visibility: visible;
 }
 
-.panel{
+.panel {
     position: fixed;
     top: 0;
     left: 0;
@@ -25,21 +25,19 @@
     padding: 1.5rem;
     transform: translateX(-100%);
     transition: transform 0.3s ease-in-out;
+    overflow: hidden;
 }
 
-.panel--open{
-    transform: translateX(0)
+.panel--open {
+    transform: translateX(0);
 }
 
-.li{
-}
-
-ul{
+ul {
     padding: 0;
     list-style: none;
 }
 
-.navigation-entry{
+.navigation-entry {
     font-size: 1.25rem;
     font-weight: 500;
     margin-bottom: 1rem;
@@ -52,22 +50,23 @@ ul{
     border-radius: 10px;
     transition: transform 0.2s ease-in-out;
 }
-.navigation-entry:hover{
+.navigation-entry:hover {
     background-color: var(--primary-color);
     transform: scale(1.05);
     cursor: pointer;
 }
 
-.settings-container{
+.settings-container {
     display: flex;
     justify-content: space-between;
     position: absolute;
     bottom: 2rem;
-    width: calc(25vw - 3rem)
+    width: calc(25vw - 3rem);
 }
 
-.settings-button{
+.settings-button {
     font-size: 1.25rem;
+    width: 9rem;
     font-weight: 500;
     padding: 0.5rem;
     border: solid 1px var(--border-color);
@@ -77,8 +76,7 @@ ul{
     transition: transform 0.2s ease-in-out;
 }
 
-.settings-button:hover{
+.settings-button:hover {
     background-color: var(--primary-color);
     transform: scale(1.05);
 }
-

+ 10 - 10
src/app/journal/journal-stats/ability-panel/spellslots/spellslots.component.html

@@ -29,6 +29,16 @@
         />
       </ng-container>
     </div>
+    <div style="display: flex; justify-content: space-around; margin-top: 2rem">
+      <div>
+        <div class="value-box">{{ spellSaveDC }}</div>
+        <div class="value-label">Rettungswurf-SG</div>
+      </div>
+      <div>
+        <div class="value-box">{{ spellAttackModifier }}</div>
+        <div class="value-label">Zauber-Angriffsbonus</div>
+      </div>
+    </div>
   </div>
   @if(!kiPoints.showKiPoints && !showSpellslots){
   <div
@@ -42,14 +52,4 @@
     Weder KI-Punkte noch Zauberplätze hinzugefügt
   </div>
   }
-  <div style="display: flex; justify-content: space-around; margin-top: 2rem">
-    <div>
-      <div class="value-box">14</div>
-      <div class="value-label">Rettungswurf-SG</div>
-    </div>
-    <div>
-      <div class="value-box">+6</div>
-      <div class="value-label">Zauber-Angriffsbonus</div>
-    </div>
-  </div>
 </div>

+ 46 - 0
src/app/journal/journal-stats/ability-panel/spellslots/spellslots.component.ts

@@ -12,6 +12,12 @@ export class SpellslotsComponent {
   public spellslots: any[] = [];
   public showSpellslots: boolean = false;
   public kiPoints: any;
+  public spellcastingAttribute: string | undefined = undefined;
+  public proficiencyBonus: number = 2;
+  public attributeValue: number = 0;
+
+  public spellAttackModifier: number = 0;
+  public spellSaveDC: number = 0;
 
   public slotNumber: number = 1;
 
@@ -20,7 +26,11 @@ export class SpellslotsComponent {
     const kiPoints = this.dataAccessor.kiPoints;
     this.spellslots = spells.spellslots;
     this.showSpellslots = spells.showSpellslots;
+    this.spellcastingAttribute = spells.spellcastingAttribute;
     this.kiPoints = kiPoints;
+    // this.calculateModifiers();
+    this.subscribeToProficiency();
+    this.subscribeToAttribute();
   }
 
   public ngAfterViewInit(): void {
@@ -57,6 +67,41 @@ export class SpellslotsComponent {
     );
   }
 
+  private calculateModifiers(): void {
+    const spellcastingAttribute = this.spellcastingAttribute;
+    console.log('calculateModifiers wurde aufgerufen');
+    console.log('Proficiency: ', this.proficiencyBonus);
+
+    console.log('Attribute: ', this.spellcastingAttribute);
+    console.log('Value: ', this.attributeValue);
+
+    if (spellcastingAttribute !== undefined) {
+      const modifier = (this.attributeValue - 10) / 2;
+      this.spellAttackModifier = modifier + this.proficiencyBonus;
+      this.spellSaveDC = 8 + modifier + this.proficiencyBonus;
+      console.log('Attack: ', this.spellAttackModifier);
+      console.log('Save: ', this.spellSaveDC);
+    }
+  }
+
+  private subscribeToAttribute(): void {
+    if (this.spellcastingAttribute !== undefined) {
+      const command =
+        'this.dataAccessor.' +
+        this.spellcastingAttribute.toLowerCase() +
+        '$.subscribe((attribute) => {this.attributeValue = attribute.value; this.calculateModifiers();});';
+      console.log(command);
+      eval(command);
+    }
+  }
+
+  private subscribeToProficiency(): void {
+    this.dataAccessor.proficiency$.subscribe((value) => {
+      this.proficiencyBonus = value;
+      this.calculateModifiers();
+    });
+  }
+
   // ki points
 
   public handleUsedKiPoints(pointIndex: number, eventTarget: any): void {
@@ -152,6 +197,7 @@ export class SpellslotsComponent {
     this.dataAccessor.spellslots = {
       spellslots: this.spellslots,
       showSpellslots: this.showSpellslots,
+      spellcastingAttribute: this.spellcastingAttribute,
     };
   }
 

+ 8 - 5
src/app/journal/journal-stats/life-container/life/life.component.html

@@ -1,7 +1,6 @@
 <div class="life-box">
   <div class="life-box-name" (click)="openDetailsPanel()">Trefferpunkte</div>
   <div class="life-box-bar" (click)="openDetailsPanel()">
-    <!-- FIXME: The percentages are not shown correctly when using the details panel -->
     <div
       class="life-box-bar-current"
       [style.width.%]="currentHitPointsPercentage"
@@ -20,10 +19,14 @@
     </div>
   </div>
   <div class="life-box-buttons">
-    <button class="life-button" (click)="addHitPoints()">Heilung +</button>
-    <button class="life-button" (click)="addTemporaryHitPoints()">
-      Temporäre Trefferpunkte +
+    <button class="life-button add" (click)="addHitPoints()">
+      <img src="assets/icons/UIIcons/heal.svg" alt="heal" />
+    </button>
+    <button class="life-button temp" (click)="addTemporaryHitPoints()">
+      <img src="assets/icons/UIIcons/temporary.svg" alt="temporary" />
+    </button>
+    <button class="life-button remove" (click)="removeHitPoints()">
+      <img src="assets/icons/UIIcons/damage.svg" alt="damage" />
     </button>
-    <button class="life-button" (click)="removeHitPoints()">Schaden -</button>
   </div>
 </div>

+ 55 - 15
src/app/journal/journal-stats/life-container/life/life.component.scss

@@ -1,4 +1,4 @@
-.life-box{
+.life-box {
     width: 100%;
     height: 100%;
     border: solid 1px var(--border-color);
@@ -7,14 +7,14 @@
     border-radius: 10px;
 }
 
-.life-box-name{
+.life-box-name {
     font-size: 1.4rem;
     font-weight: bold;
     text-align: center;
     cursor: pointer;
 }
 
-.life-box-bar{
+.life-box-bar {
     position: relative;
     display: flex;
     flex-direction: row;
@@ -23,21 +23,37 @@
     border-radius: 10px;
     overflow: hidden;
     cursor: pointer;
+    &:hover {
+        .life-box-bar-current {
+            background-color: var(--accept-hover);
+        }
+
+        .life-box-bar-temporary {
+            background-color: var(--edit-hover);
+        }
+
+        .life-box-bar-missing {
+            background-color: var(--delete-hover);
+        }
+    }
 }
 
-.life-box-bar-current{
-    background-color: rgba(12, 105, 1, 0.4);
+.life-box-bar-current {
+    background-color: var(--accept);
+    transition: all 0.2s ease-in-out;
 }
 
-.life-box-bar-temporary{
-    background-color: rgba(140, 254, 125, 0.4);
+.life-box-bar-temporary {
+    background-color: var(--edit);
+    transition: all 0.2s ease-in-out;
 }
 
-.life-box-bar-missing{
-    background-color: rgba(111, 0, 0, 0.5);
+.life-box-bar-missing {
+    background-color: var(--delete);
+    transition: all 0.2s ease-in-out;
 }
 
-.life-box-bar-label{
+.life-box-bar-label {
     font-size: 1.5rem;
     font-weight: bold;
     position: absolute;
@@ -46,19 +62,43 @@
     transform: translate(-50%, -50%);
 }
 
-.life-box-buttons{
+.life-box-buttons {
     display: flex;
     justify-content: space-between;
     margin: 1rem;
     // flex-direction: column;
 }
 
-.life-button{
-    min-height: 2rem;
+.life-button {
+    height: 2.5rem;
+    width: 6rem;
     font-size: 1.25rem;
     font-weight: 500;
-    border: solid 1px var(--border-color);
-    background-color: var(--quaternary-color-light);
+    border: none;
     box-shadow: var(--shadow-small);
     border-radius: 10px;
 }
+
+.add {
+    background-color: var(--accept);
+    transition: all 0.2s ease-in-out;
+    &:hover {
+        background-color: var(--accept-hover);
+    }
+}
+
+.temp {
+    background-color: var(--edit);
+    transition: all 0.2s ease-in-out;
+    &:hover {
+        background-color: var(--edit-hover);
+    }
+}
+
+.remove {
+    background-color: var(--delete);
+    transition: all 0.2s ease-in-out;
+    &:hover {
+        background-color: var(--delete-hover);
+    }
+}

+ 2 - 2
src/app/journal/journal-stats/weapons-container/spell-table/spell-table.component.ts

@@ -179,7 +179,7 @@ export class SpellTableComponent {
 
   private subscribeToData(): void {
     // TODO: this.dataAccessor.getSpellcastingAttribute() oder so
-    this.spellcastingAttribute = 'intelligence';
+    this.spellcastingAttribute = 'wisdom';
 
     this.dataAccessor.proficiency$.subscribe((value) => {
       this.proficiencyBonus = value;
@@ -188,7 +188,7 @@ export class SpellTableComponent {
       }
     });
     // TODO: Modify depending on the actual spellcasting attribute
-    this.dataAccessor.intelligence$.subscribe((value) => {
+    this.dataAccessor.wisdom$.subscribe((value) => {
       this.spellcastingAttributeModifier = Math.floor((value.value - 10) / 2);
       this.computeSpellAttackBonusAndSaveDC();
     });

+ 18 - 1
src/app/journal/journal.module.ts

@@ -1,16 +1,18 @@
 import { NgModule } from '@angular/core';
 import { CommonModule } from '@angular/common';
-import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgbModule, NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
 import { FormsModule } from '@angular/forms';
 import { CdkTableModule } from '@angular/cdk/table';
 import { DragDropModule } from '@angular/cdk/drag-drop';
 import { ReactiveFormsModule } from '@angular/forms';
+import { MarkdownModule } from 'ngx-markdown';
 
 // Material Design
 import { MatSlideToggleModule } from '@angular/material/slide-toggle';
 import { MatSelectModule } from '@angular/material/select';
 import { MatInputModule } from '@angular/material/input';
 import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatTabsModule } from '@angular/material/tabs';
 
 import { JournalRoutingModule } from './journal-routing.module';
 import { JournalHomeComponent } from './journal-home/journal-home.component';
@@ -84,6 +86,12 @@ import { FoodDetailsComponent } from './journal-inventory/food-details/food-deta
 import { TabBarComponent } from './journal-home/tab-bar/tab-bar.component';
 import { SpellcardComponent } from './journal-spellcards/spellcard/spellcard.component';
 import { AddCardComponent } from './journal-spellcards/add-card/add-card.component';
+import { GeneralComponent } from './journal-character/general/general.component';
+import { ClassComponent } from './journal-character/class/class.component';
+import { SubclassComponent } from './journal-character/subclass/subclass.component';
+import { SpeciesComponent } from './journal-character/species/species.component';
+import { BackgroundComponent } from './journal-character/background/background.component';
+import { StoryComponent } from './journal-character/story/story.component';
 
 @NgModule({
   declarations: [
@@ -156,11 +164,18 @@ import { AddCardComponent } from './journal-spellcards/add-card/add-card.compone
     WeaponModalComponent,
     SpellcardComponent,
     AddCardComponent,
+    GeneralComponent,
+    ClassComponent,
+    SubclassComponent,
+    SpeciesComponent,
+    BackgroundComponent,
+    StoryComponent,
   ],
   imports: [
     CommonModule,
     JournalRoutingModule,
     NgbModule,
+    NgbDropdownModule,
     FormsModule,
     CdkTableModule,
     DragDropModule,
@@ -170,6 +185,8 @@ import { AddCardComponent } from './journal-spellcards/add-card/add-card.compone
     MatSelectModule,
     MatInputModule,
     MatFormFieldModule,
+    MatTabsModule,
+    MarkdownModule.forRoot(),
   ],
 })
 export class JournalModule {}

+ 0 - 1
src/assets/icons/UIIcons/character.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 512px; width: 512px;"><g class="" transform="translate(0,0)" style=""><path d="M255 45.4c-24.5 0-47 11.8-63.9 33.4-16.9 21.5-27.1 52.6-27.1 86.5 0 36 12.1 67.5 31 89.5l13.5 15-19.6 4.6c-52.3 11.9-77.4 36.9-91.75 75.2-13.7 35.7-15.6 84.8-16.1 143.3H431c-.2-58.7-.5-109.3-13-145.5-13.4-39.4-37.9-64.3-94-75.4l-19.9-3.7 12.9-15.7c17.7-21.9 28.8-52.6 28.8-87.5 0-33.9-10.3-64.9-27.2-86.3-16.8-21.7-39.3-33.6-63.6-33.4z" fill="#000000" fill-opacity="1"></path></g></svg>

+ 1 - 0
src/assets/icons/UIIcons/characters.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M480-480q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 66-47 113t-113 47ZM160-160v-112q0-34 17.5-62.5T224-378q62-31 126-46.5T480-440q66 0 130 15.5T736-378q29 15 46.5 43.5T800-272v112H160Zm80-80h480v-32q0-11-5.5-20T700-306q-54-27-109-40.5T480-360q-56 0-111 13.5T260-306q-9 5-14.5 14t-5.5 20v32Zm240-320q33 0 56.5-23.5T560-640q0-33-23.5-56.5T480-720q-33 0-56.5 23.5T400-640q0 33 23.5 56.5T480-560Zm0-80Zm0 400Z"/></svg>

+ 1 - 0
src/assets/icons/UIIcons/damage.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M440-501Zm0 381L313-234q-72-65-123.5-116t-85-96q-33.5-45-49-87T40-621q0-94 63-156.5T260-840q52 0 99 22t81 62q34-40 81-62t99-22q84 0 153 59t69 160q0 14-2 29.5t-6 31.5h-85q5-18 8-34t3-30q0-75-50-105.5T620-760q-51 0-88 27.5T463-660h-46q-31-45-70.5-72.5T260-760q-57 0-98.5 39.5T120-621q0 33 14 67t50 78.5q36 44.5 98 104T440-228q26-23 61-53t56-50l9 9 19.5 19.5L605-283l9 9q-22 20-56 49.5T498-172l-58 52Zm160-280v-80h320v80H600Z"/></svg>

+ 1 - 0
src/assets/icons/UIIcons/delete.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M280-120q-33 0-56.5-23.5T200-200v-520h-40v-80h200v-40h240v40h200v80h-40v520q0 33-23.5 56.5T680-120H280Zm400-600H280v520h400v-520ZM360-280h80v-360h-80v360Zm160 0h80v-360h-80v360ZM280-720v520-520Z"/></svg>

+ 1 - 0
src/assets/icons/UIIcons/heal.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M440-501Zm0 381L313-234q-72-65-123.5-116t-85-96q-33.5-45-49-87T40-621q0-94 63-156.5T260-840q52 0 99 22t81 62q34-40 81-62t99-22q81 0 136 45.5T831-680h-85q-18-40-53-60t-73-20q-51 0-88 27.5T463-660h-46q-31-45-70.5-72.5T260-760q-57 0-98.5 39.5T120-621q0 33 14 67t50 78.5q36 44.5 98 104T440-228q26-23 61-53t56-50l9 9 19.5 19.5L605-283l9 9q-22 20-56 49.5T498-172l-58 52Zm280-160v-120H600v-80h120v-120h80v120h120v80H800v120h-80Z"/></svg>

+ 1 - 0
src/assets/icons/UIIcons/image.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560H200v560Zm40-80h480L570-480 450-320l-90-120-120 160Zm-40 80v-560 560Z"/></svg>

+ 0 - 1
src/assets/icons/UIIcons/life-minus.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 512px; width: 512px;"><g class="" transform="translate(0,0)" style=""><path d="M372.48 31.215c-77.65 0-116.48 65.73-116.48 65.73s-38.83-65.72-116.48-65.72c-37.14 0-107.77 33.72-107.77 125.13 0 161.24 224.25 324.43 224.25 324.43s224.25-163.19 224.25-324.43c0-91.42-70.63-125.13-107.77-125.14zM146.924 225.65h220v60.7h-220z" fill="#060606" fill-opacity="1"></path></g></svg>

+ 0 - 1
src/assets/icons/UIIcons/life-plus.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 512px; width: 512px;"><g class="" transform="translate(0,0)" style=""><path d="M372.48 31.215c-77.65 0-116.48 65.73-116.48 65.73s-38.83-65.72-116.48-65.72c-37.14 0-107.77 33.72-107.77 125.13 0 161.24 224.25 324.43 224.25 324.43s224.25-163.19 224.25-324.43c0-91.42-70.63-125.13-107.77-125.14zm-145.492 115.02h60.698v79.415h79.238v60.7h-79.238v79.884h-60.698V286.35h-80.064v-60.7h80.064z" fill="#060606" fill-opacity="1"></path></g></svg>

+ 0 - 1
src/assets/icons/UIIcons/life-temporary.svg

@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 512px; width: 512px;"><g class="" transform="translate(0,0)" style=""><path d="M256 32c-64 48-128 64-224 96 0 128 160 320 224 368 64-48 224-240 224-368-96-32-160-48-224-96zm0 34.75l5.4 4.05c49.7 37.3 99.6 49.9 176.7 75.6l6.2 2v6.5c0 55-33.1 119.7-72 176.4-38.9 56.8-83.6 105-110.9 125.5l-5.4 4.1-5.4-4.1c-27.3-20.5-72-68.7-110.9-125.5-38.9-56.7-72-121.4-72-176.4v-6.5l6.15-2C150.9 120.7 200.9 108 250.6 70.8l5.4-4.05zm0 22.18c-49.4 35.37-99.8 49.17-170.05 72.37 2.58 46.7 32.35 107 68.65 159.9 35.3 51.5 76.6 96.3 101.4 116.8 24.8-20.5 66.1-65.3 101.4-116.8 36.3-52.9 66.1-113.2 68.6-159.9-70.3-23.2-120.6-37-170-72.37zm-45.5 54.97c19.7.5 38.1 14.4 45.5 48.1 18-86.3 110-42.5 110 22.5-1 63.9-92 107.7-110 162.1-19-54.4-108-98.2-110-162.1 0-39.6 33.8-71.3 64.5-70.6z" fill="#060606" fill-opacity="1"></path></g></svg>

+ 1 - 1
src/assets/icons/UIIcons/settings.svg

@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 512px; width: 512px;"><g class="" transform="translate(0,0)" style=""><path d="M234.875 18.78c-26.087 2.367-51.557 8.56-74.875 18.782 15.37 32.763 14.222 66.706-6.72 82.407-20.835 15.617-54.055 7.965-81.124-15.69-16.246 19.452-29.336 41.36-38.875 65.626 33.83 12.333 56.635 37.665 52.94 63.5-3.698 25.835-32.697 43.74-68.626 46.094 2.338 25.796 8.91 50.778 18.937 73.875 17.81-8.182 35.793-11.09 51.095-8.938 13.032 1.87 23.927 7.015 31.156 16.657 15.817 21.097 7.603 54.713-16.78 81.97 19.516 16.35 42.216 29.444 66.594 39.03 12.33-33.828 37.655-56.634 63.5-52.938 25.844 3.697 43.74 32.696 46.094 68.625 26.087-2.365 51.557-8.555 74.875-18.78-15.766-32.997-14.26-67.588 6.843-83.406 9.64-7.23 22.568-9.022 35.594-7.125 15.112 2.16 31.19 10.25 45.563 22.78 16.088-19.345 29.4-41.51 38.875-65.594-33.83-12.332-56.635-37.653-52.938-63.5 3.697-25.846 32.665-43.772 68.594-46.125-2.36-25.944-8.774-50.663-18.906-73.874-32.612 15.117-66.66 13.145-82.282-7.687-15.696-20.944-7.252-53.86 16.688-81-19.52-16.352-42.248-29.447-66.625-39.032-12.332 33.828-37.657 56.66-63.5 52.968-25.846-3.693-43.744-32.696-46.095-68.625zm21.656 95.126c79.626 0 144.376 64.752 144.376 144.375 0 79.626-64.75 144.376-144.375 144.376-79.624 0-144.374-64.75-144.374-144.375 0-79.624 64.75-144.374 144.375-144.374zm0 18.688c-69.524 0-125.686 56.162-125.686 125.687 0 69.526 56.162 125.69 125.687 125.69 69.526 0 125.69-56.164 125.69-125.69 0-69.522-56.164-125.686-125.69-125.686zm.033 15.125c61.094 0 110.625 49.53 110.625 110.624 0 61.095-49.53 110.625-110.625 110.625s-110.625-49.53-110.625-110.626c0-61.095 49.53-110.625 110.625-110.625z" fill="#000000" fill-opacity="1"></path></g></svg>
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="m370-80-16-128q-13-5-24.5-12T307-235l-119 50L78-375l103-78q-1-7-1-13.5v-27q0-6.5 1-13.5L78-585l110-190 119 50q11-8 23-15t24-12l16-128h220l16 128q13 5 24.5 12t22.5 15l119-50 110 190-103 78q1 7 1 13.5v27q0 6.5-2 13.5l103 78-110 190-118-50q-11 8-23 15t-24 12L590-80H370Zm70-80h79l14-106q31-8 57.5-23.5T639-327l99 41 39-68-86-65q5-14 7-29.5t2-31.5q0-16-2-31.5t-7-29.5l86-65-39-68-99 42q-22-23-48.5-38.5T533-694l-13-106h-79l-14 106q-31 8-57.5 23.5T321-633l-99-41-39 68 86 64q-5 15-7 30t-2 32q0 16 2 31t7 30l-86 65 39 68 99-42q22 23 48.5 38.5T427-266l13 106Zm42-180q58 0 99-41t41-99q0-58-41-99t-99-41q-59 0-99.5 41T342-480q0 58 40.5 99t99.5 41Zm-2-140Z"/></svg>

+ 1 - 0
src/assets/icons/UIIcons/temporary.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M480-320q102-92 131-129.5t29-74.5q0-36-26-62t-62-26q-21 0-40.5 8.5T480-580q-12-15-31-23.5t-41-8.5q-36 0-62 26t-26 62q0 19 5 35t22 37.5q17 21.5 48.5 52.5t84.5 79Zm0 240q-139-35-229.5-159.5T160-516v-244l320-120 320 120v244q0 152-90.5 276.5T480-80Zm0-84q104-33 172-132t68-220v-189l-240-90-240 90v189q0 121 68 220t172 132Zm0-316Z"/></svg>

+ 1 - 0
src/assets/icons/UIIcons/upload.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M440-320v-326L336-542l-56-58 200-200 200 200-56 58-104-104v326h-80ZM240-160q-33 0-56.5-23.5T160-240v-120h80v120h480v-120h80v120q0 33-23.5 56.5T720-160H240Z"/></svg>

BIN
src/assets/images/character_coming_soon.jpeg


BIN
src/assets/images/diverse.jpg


BIN
src/assets/images/eliane.jpg


BIN
src/assets/images/female.jpg


BIN
src/assets/images/male.jpg


BIN
src/assets/images/tel.jpg


+ 16 - 0
src/services/class/class.service.spec.ts

@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { ClassService } from './class.service';
+
+describe('ClassService', () => {
+  let service: ClassService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(ClassService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});

+ 522 - 0
src/services/class/class.service.ts

@@ -0,0 +1,522 @@
+import { Injectable } from '@angular/core';
+
+@Injectable({
+  providedIn: 'root',
+})
+export class ClassService {
+  constructor() {}
+
+  // FUNCTIONS
+
+  public getClassDetails(className: string): any {
+    switch (className) {
+      case 'Fighter':
+        return this.fighter;
+      case 'Barbarian':
+        return this.barbarian;
+      case 'Cleric':
+        return this.cleric;
+      default:
+        return this.notImplementedYet;
+    }
+  }
+
+  // CLASS DETAILS
+
+  public fighter: any = {
+    title: 'Kämpfer',
+    description: `
+    Fighters share an unparalleled mastery with weapons and armor, and a thorough knowledge of the skills of combat. They are well acquainted with death, both meting it out and staring it defiantly in the face.
+
+
+    ### Class Features
+
+    As a fighter, you gain the following class features.
+
+    #### Hit Points
+
+    **Hit Dice:** 1d10 per fighter level
+    
+    **Hit Points at 1st Level:** 10 + your Constitution modifier
+    
+    **Hit Points at Higher Levels:** 1d10 (or 6) + your Constitution modifier per fighter level after 1st
+
+    #### Proficiencies
+    **Armor:** All armor, shields
+
+    **Weapons:** Simple weapons, martial weapons
+
+    **Tools:** None
+
+    **Saving Throws:** Strength, Constitution
+
+    **Skills:** Choose two skills from Acrobatics, Animal Handling, Athletics, History, Insight, Intimidation, Perception, and Survival
+
+    #### Equipment
+    - (a) chain mail or (b) leather, longbow, and 20 arrows
+    - (a) a martial weapon and a shield or (b) two martial weapons
+    - (a) a light crossbow and 20 bolts or (b) two handaxes
+    - (a) a dungeoneer's pack or (b) an explorer's pack
+    `,
+    features: [
+      {
+        name: 'Fighting Style',
+        level: 1,
+        description: `
+
+      You adopt a particular style of fighting as your specialty. Choose one of the following options. You can't take a Fighting Style option more than once, even if you later get to choose again.
+
+      - Archery (PHB). You gain a +2 bonus to attack rolls you make with ranged weapons.
+      - Blind Fighting (TCE). You have blindsight with a range of 10 feet. Within that range, you can effectively see anything that isn't behind total cover, even if you're blinded or in darkness. Moreover, you can see an invisible creature within that range, unless the creature successfully hides from you.
+      - Defense (PHB). While you are wearing armor, you gain a +1 bonus to AC.
+      - Dueling (PHB). When you are wielding a melee weapon in one hand and no other weapons, you gain a +2 bonus to damage rolls with that weapon.
+      - Great Weapon Fighting (PHB). When you roll a 1 or 2 on a damage die for an attack you make with a melee weapon that you are wielding with two hands, you can reroll the die and must use the new roll, even if the new roll is a 1 or a 2. The weapon must have the two-handed or versatile property for you to gain this benefit.
+      - Interception (TCE). When a creature you can see hits a target, other than you, within 5 feet of you with an attack, you can use your reaction to reduce the damage the target takes by 1d10 + your proficiency bonus (to a minimum of 0 damage). You must be wielding a shield or a simple or martial weapon to use this reaction.
+      - Protection (PHB). When a creature you can see attacks a target other than you that is within 5 feet of you, you can use your reaction to impose disadvantage on the attack roll. You must be wielding a shield.
+      - Superior Technique (TCE). You learn one maneuver of your choice from among those available to the Battle Master archetype. If a maneuver you use requires your target to make a saving throw to resist the maneuver's effects, the saving throw DC equals 8 + your proficiency bonus + your Strength or Dexterity modifier (your choice.)
+      - You gain one superiority die, which is a d6 (this die is added to any superiority dice you have from another source). This die is used to fuel your maneuvers. A superiority die is expended when you use it. You regain your expended superiority dice when you finish a short or long rest.
+      - Thrown Weapon Fighting (TCE). You can draw a weapon that has the thrown property as part of the attack you make with the weapon.
+      - In addition, when you hit with a ranged attack using a thrown weapon, you gain a +2 bonus to the damage roll.
+      - Two-Weapon Fighting (PHB). When you engage in two-weapon fighting, you can add your ability modifier to the damage of the second attack.
+      - Unarmed Fighting (TCE). Your unarmed strikes can deal bludgeoning damage equal to 1d6 + your Strength modifier on a hit. If you aren't wielding any weapons or a shield when you make the attack roll, the d6 becomes a d8.
+      - At the start of each of your turns, you can deal 1d4 bludgeoning damage to one creature grappled by you.
+      - Close Quarters Shooter (UA). When making a ranged attack while you are within 5 feet of a hostile creature, you do not have disadvantage on the attack roll. Your ranged attacks ignore half cover and three-quarters cover against targets within 30 feet of you. You have a +1 bonus to attack rolls on ranged attacks.
+      - Mariner (UA). As long as you are not wearing heavy armor or using a shield, you have a swimming speed and a climbing speed equal to your normal speed, and you gain a +1 bonus to armor class.
+      - Tunnel Fighter (UA). As a bonus action, you can enter a defensive stance that lasts until the start of your next turn. While in your defensive stance, you can make opportunity attacks without using your reaction, and you can use your reaction to make a melee attack against a creature that moves more than 5 feet while within your reach.
+      
+      `,
+      },
+      {
+        name: 'Second Wind',
+        level: 1,
+        description: `
+          You have a limited well of stamina that you can draw on to protect yourself from harm. On your turn, you can use a bonus action to regain hit points equal to 1d10 + your fighter level.
+
+          Once you use this feature, you must finish a short or long rest before you can use it again.
+      
+        `,
+      },
+      {
+        name: 'Action Surge',
+        level: 2,
+        description: `
+          Starting at 2nd level, you can push yourself beyond your normal limits for a moment. On your turn, you can take one additional action.
+
+          Once you use this feature, you must finish a short or long rest before you can use it again. Starting at 17th level, you can use it twice before a rest, but only once on the same turn.
+      
+        `,
+      },
+      {
+        name: 'Martial Archetype',
+        level: 3,
+        description: `
+          At 3rd level, you choose an archetype that you strive to emulate in your combat styles and techniques. The archetype you choose grants you features at 3rd level and again at 7th, 10th, 15th, and 18th level.    
+        `,
+      },
+      {
+        name: 'Ability Score Improvement',
+        level: 4,
+        description: `
+          When you reach 4th level, and again at 6th, 8th, 12th, 14th, 16th, and 19th level, you can increase one ability score of your choice by 2, or you can increase two ability scores of your choice by 1. As normal, you can't increase an ability score above 20 using this feature.  
+        `,
+      },
+      {
+        name: 'Extra Attack',
+        level: 5,
+        description: `
+          Beginning at 5th level, you can attack twice, instead of once, whenever you take the Attack action on your turn.
+
+          The number of attacks increases to three when you reach 11th level in this class and to four when you reach 20th level in this class.    
+        `,
+      },
+      {
+        name: 'Ability Score Improvement',
+        level: 6,
+        description: `
+          When you reach 4th level, and again at 6th, 8th, 12th, 14th, 16th, and 19th level, you can increase one ability score of your choice by 2, or you can increase two ability scores of your choice by 1. As normal, you can't increase an ability score above 20 using this feature.  
+        `,
+      },
+      {
+        name: 'Ability Score Improvement',
+        level: 8,
+        description: `
+          When you reach 4th level, and again at 6th, 8th, 12th, 14th, 16th, and 19th level, you can increase one ability score of your choice by 2, or you can increase two ability scores of your choice by 1. As normal, you can't increase an ability score above 20 using this feature.  
+        `,
+      },
+      {
+        name: 'Indomitable',
+        level: 9,
+        description: `
+          Beginning at 9th level, you can reroll a saving throw that you fail. If you do so, you must use the new roll, and you can't use this feature again until you finish a long rest.  
+        `,
+      },
+      {
+        name: 'Extra Attack (x3)',
+        level: 11,
+        description: `
+          You can now attack thrice whenever you take the Attack action on your turn.   
+        `,
+      },
+      {
+        name: 'Ability Score Improvement',
+        level: 12,
+        description: `
+          When you reach 4th level, and again at 6th, 8th, 12th, 14th, 16th, and 19th level, you can increase one ability score of your choice by 2, or you can increase two ability scores of your choice by 1. As normal, you can't increase an ability score above 20 using this feature.  
+        `,
+      },
+      {
+        name: 'Indomitable (x2)',
+        level: 13,
+        description: `
+          You can reroll a saving throw that you fail. If you do so, you must use the new roll, and you can't use this feature again until you finish a long rest. You can now use this feature twice between long rests.  
+        `,
+      },
+      {
+        name: 'Ability Score Improvement',
+        level: 14,
+        description: `
+          When you reach 4th level, and again at 6th, 8th, 12th, 14th, 16th, and 19th level, you can increase one ability score of your choice by 2, or you can increase two ability scores of your choice by 1. As normal, you can't increase an ability score above 20 using this feature.  
+        `,
+      },
+      {
+        name: 'Ability Score Improvement',
+        level: 16,
+        description: `
+          When you reach 4th level, and again at 6th, 8th, 12th, 14th, 16th, and 19th level, you can increase one ability score of your choice by 2, or you can increase two ability scores of your choice by 1. As normal, you can't increase an ability score above 20 using this feature.  
+        `,
+      },
+      {
+        name: 'Indomitable (x3)',
+        level: 17,
+        description: `
+          You can reroll a saving throw that you fail. If you do so, you must use the new roll, and you can't use this feature again until you finish a long rest. You can now use this feature thrice between long rests.  
+        `,
+      },
+      {
+        name: 'Action Surge (x2)',
+        level: 17,
+        description: `
+          Starting at 17th level, you can use it twice before a rest, but only once on the same turn.
+      
+        `,
+      },
+      {
+        name: 'Ability Score Improvement',
+        level: 19,
+        description: `
+          When you reach 4th level, and again at 6th, 8th, 12th, 14th, 16th, and 19th level, you can increase one ability score of your choice by 2, or you can increase two ability scores of your choice by 1. As normal, you can't increase an ability score above 20 using this feature.  
+        `,
+      },
+      {
+        name: 'Extra Attack (x4)',
+        level: 20,
+        description: `
+          You can now attack four times whenever you take the Attack action on your turn. 
+        `,
+      },
+    ],
+  };
+
+  public barbarian: any = {
+    title: 'Barbar',
+    description: `
+    Barbarians are savage warriors who deal with their opponents through a combination of sheer brute force and terrifying rage. Their strength and ferocity make them well suited for melee combat. Barbarians are also able to wreak havoc on their enemies using unorthodox methods, such as throwing improvised weapons or even their own bodies.
+
+    ### Class Features
+
+    As a barbarian, you gain the following class features.
+
+    #### Hit Points
+
+    **Hit Dice:** 1d12 per barbarian level
+    
+    **Hit Points at 1st Level:** 12 + your Constitution modifier
+    
+    **Hit Points at Higher Levels:** 1d12 (or 7) + your Constitution modifier per barbarian level after 1st
+
+    #### Proficiencies
+    **Armor:** Light armor, medium armor, shields
+
+    **Weapons:** Simple weapons, martial weapons
+
+    **Tools:** None
+
+    **Saving Throws:** Strength, Constitution
+
+    **Skills:** Choose two skills from Animal Handling, Athletics, Intimidation, Nature, Perception, and Survival
+
+    #### Equipment
+    - (a) a greataxe or (b) any martial melee weapon
+    - (a) two handaxes or (b) any simple weapon
+    - An explorer's pack and four javelins
+    `,
+    features: [
+      {
+        name: 'Rage',
+        level: 1,
+        description: `
+          In battle, you fight with primal ferocity. On your turn, you can enter a rage as a bonus action.
+
+          While raging, you gain the following benefits if you aren't wearing heavy armor:
+
+          - You have advantage on Strength checks and Strength saving throws.
+          - When you make a melee weapon attack using Strength, you gain a bonus to the damage roll that increases as you gain levels as a barbarian, as shown in the Rage Damage column of the Barbarian table.
+          - You have resistance to bludgeoning, piercing, and slashing damage.
+          - If you are able to cast spells, you can't cast them or concentrate on them while raging.
+          - Your rage lasts for 1 minute. It ends early if you are knocked unconscious or if your turn ends and you haven't attacked a hostile creature since your last turn or taken damage since then. You can also end your rage on your turn as a bonus action.
+          - Once you have raged the number of times shown for your barbarian level in the Rages column of the Barbarian table, you must finish a long rest before you can rage again.
+        `,
+      },
+      {
+        name: 'Unarmored Defense',
+        level: 1,
+        description: `
+          While you are not wearing any armor, your Armor Class equals 10 + your Dexterity modifier + your Constitution modifier. You can use a shield and still gain this benefit.
+        `,
+      },
+      {
+        name: 'Reckless Attack',
+        level: 2,
+        description: `
+          Starting at 2nd level, you can throw aside all concern for defense to attack with fierce desperation. When you make your first attack on your turn, you can decide to attack recklessly. Doing so gives you advantage on melee weapon attack rolls using Strength during this turn, but attack rolls against you have advantage until your next turn.
+        `,
+      },
+      {
+        name: 'Danger Sense',
+        level: 2,
+        description: `
+          At 2nd level, you gain an uncanny sense of when things nearby aren't as they should be, giving you an edge when you dodge away from danger.
+
+          You have advantage on Dexterity saving throws against effects that you can see, such as traps and spells. To gain this benefit, you can't be blinded, deafened, or incapacitated.
+        `,
+      },
+      {
+        name: 'Ability Score Improvement',
+        level: 4,
+        description: `
+          When you reach 4th level, and again at 6th, 8th, 12th, 14th, 16th, and 19th level, you can increase one ability score of your choice by 2, or you can increase two ability scores of your choice by 1. As normal, you can't increase an ability score above 20 using this feature.  
+        `,
+      },
+      {
+        name: 'Extra Attack',
+        level: 5,
+        description: `
+          Beginning at 5th level, you can attack twice, instead of once, whenever you take the Attack action on your turn.
+
+          The number of attacks increases to three when you reach 11th level in this class and to four when you reach 20th level in this class.    
+        `,
+      },
+      {
+        name: 'Fast Movement',
+        level: 5,
+        description: `
+          Starting at 5th level, your speed increases by 10 feet while you aren't wearing heavy armor.
+        `,
+      },
+      {
+        name: 'Feral Instinct',
+        level: 7,
+        description: `
+          By 7th level, your instincts are so honed that you have advantage on initiative rolls.
+
+          Additionally, if you are surprised at the beginning of combat and aren't incapacitated, you can act normally on your first turn, but only if you enter your rage before doing anything else on that turn.
+        `,
+      },
+      {
+        name: 'Brutal Critical',
+        level: 9,
+        description: `
+          Beginning at 9th level, you can roll one additional weapon damage die when determining the extra damage for a critical hit with a melee attack.
+
+          This increases to two additional dice at 13th level and three additional dice at 17th level.
+        `,
+      },
+      {
+        name: 'Relentless Rage',
+        level: 11,
+        description: `
+          Starting at 11th level, your rage can keep you fighting despite grievous wounds. If you drop to 0 hit points while you're raging and don't die outright, you can make a DC 10 Constitution saving throw. If you succeed, you drop to 1 hit point instead.
+
+          Each time you use this feature after the first, the DC increases by 5. When you finish a short or long rest, the DC resets to 10.
+        `,
+      },
+      {
+        name: 'Ability Score Improvement',
+        level: 12,
+        description: `
+          When you reach 4th level, and again at 6th, 8th, 12th, 14th, 16th, and 19th level, you can increase one ability score of your choice by 2, or you can increase two ability scores of your choice by 1. As normal, you can't increase an ability score above 20 using this feature.  
+        `,
+      },
+      {
+        name: 'Persistent Rage',
+        level: 15,
+        description: `
+          Beginning at 15th level, your rage is so fierce that it ends early only if you fall unconscious or if you choose to end it.
+        `,
+      },
+      {
+        name: 'Indomitable Might',
+        level: 18,
+        description: `
+          Beginning at 18th level, if your total for a Strength check is less than your Strength score, you can use that score in place of the total.
+
+          ### Primal Champion
+
+          At 20th level, you embody the power of the wilds. Your Strength and Constitution scores increase by 4. Your maximum for those scores is now 24.
+        `,
+      },
+    ],
+  };
+
+  public cleric: any = {
+    title: 'Cleric',
+    description: `
+    Clerics are intermediaries between the mortal world and the distant planes of the gods. As varied as the gods they serve, clerics strive to embody the handiwork of their deities. No ordinary priest, a cleric is imbued with divine magic.
+
+    ### Class Features
+
+    As a cleric, you gain the following class features.
+
+    #### Hit Points
+
+    **Hit Dice:** 1d8 per cleric level
+    
+    **Hit Points at 1st Level:** 8 + your Constitution modifier
+    
+    **Hit Points at Higher Levels:** 1d8 (or 5) + your Constitution modifier per cleric level after 1st
+
+    #### Proficiencies
+    **Armor:** Light armor, medium armor, shields
+
+    **Weapons:** Simple weapons
+
+    **Tools:** None
+
+    **Saving Throws:** Wisdom, Charisma
+
+    **Skills:** Choose two from History, Insight, Medicine, Persuasion, and Religion
+
+    #### Equipment
+    - (a) a mace or (b) a warhammer (if proficient)
+    - (a) scale mail, (b) leather armor, or (c) chain mail (if proficient)
+    - (a) a light crossbow and 20 bolts or (b) any simple weapon
+    - (a) a priest's pack or (b) an explorer's pack
+    - A shield and a holy symbol
+
+    ### Spellcasting
+
+    As a conduit for divine power, you can cast cleric spells.
+
+    #### Cantrips
+
+    At 1st level, you know three cantrips of your choice from the cleric spell list. You learn additional cleric cantrips of your choice at higher levels, as shown in the Cantrips Known column of the Cleric table.
+
+    #### Spell Slots
+
+    The Cleric table shows how many spell slots you have to cast your cleric spells of 1st level and higher. To cast one of these spells, you must expend a slot of the spell's level or higher. You regain all expended spell slots when you finish a long rest.
+
+    You prepare the list of cleric spells that are available for you to cast, choosing from the cleric spell list. When you do so, choose a number of cleric spells equal to your Wisdom modifier + your cleric level (minimum of one spell). The spells must be of a level for which you have spell slots.
+
+    For example, if you are a 3rd-level cleric, you have four 1st-level and two 2nd-level spell slots. With a Wisdom of 16, your list of prepared spells can include six spells of 1st or 2nd level, in any combination. If you prepare the 1st-level spell Cure Wounds, you can cast it using a 1st-level or 2nd-level slot. Casting the spell doesn't remove it from your list of prepared spells.
+
+    You can change your list of prepared spells when you finish a long rest. Preparing a new list of cleric spells requires time spent in prayer and meditation: at least 1 minute per spell level for each spell on your list.
+
+    #### Spellcasting Ability
+
+    Wisdom is your spellcasting ability for your cleric spells. The power of your spells comes from your devotion to your deity. You use your Wisdom whenever a cleric spell refers to your spellcasting ability. In addition, you use your Wisdom modifier when setting the saving throw DC for a cleric spell you cast and when making an attack roll with one.
+
+    **Spell save DC:** 8 + your proficiency bonus + your Wisdom modifier
+
+    **Spell attack modifier:** your proficiency bonus + your Wisdom modifier
+
+    `,
+    features: [
+      {
+        name: 'Divine Domain',
+        level: 1,
+        description: `
+          At 1st level, you choose a domain shaped by your choice of Deity and the gifts they grant you. Your choice grants you domain spells and other features when you choose it at 1st level. It also grants you additional ways to use Channel Divinity when you gain that feature at 2nd level, and additional benefits at 6th, 8th, and 17th levels.
+          `,
+      },
+      {
+        name: 'Channel Divinity',
+        level: 2,
+        description: `
+          At 2nd level, you gain the ability to channel divine energy directly from your deity, using that energy to fuel magical effects. You start with two such effects: Turn Undead and an effect determined by your domain. Some domains grant you additional effects as you advance in levels, as noted in the domain description.
+
+          When you use your Channel Divinity, you choose which effect to create. You must then finish a short or long rest to use your Channel Divinity again.
+
+          Some Channel Divinity effects require saving throws. When you use such an effect from this class, the DC equals your cleric spell save DC.
+
+          Beginning at 6th level, you can use your Channel Divinity twice between rests, and beginning at 18th level, you can use it three times between rests. When you finish a short or long rest, you regain your expended uses.
+          `,
+      },
+      {
+        name: 'Channel Divinity Turn Undead',
+        level: 2,
+        description: `
+          As an action, you present your holy symbol and speak a prayer censuring the undead. Each undead that can see or hear you within 30 feet of you must make a Wisdom saving throw. If the creature fails its saving throw, it is turned for 1 minute or until it takes any damage.
+
+          A turned creature must spend its turns trying to move as far away from you as it can, and it can't willingly move to a space within 30 feet of you. It also can't take reactions. For its action, it can use only the Dash action or try to escape from an effect that prevents it from moving. If there's nowhere to move, the creature can use the Dodge action.
+          `,
+      },
+      {
+        name: 'Harness Divine Power',
+        level: 2,
+        description: `
+          At 2nd level, you can expend a use of your Channel Divinity to fuel your spells. As a bonus action, you touch your holy symbol, utter a prayer, and regain one expended spell slot, the level of which can be no higher than half your proficiency bonus (rounded up). The number of times you can use this feature is based on the level you've reached in this class: 2nd level, once; 6th level, twice; and 18th level, thrice. You regain all expended uses when you finish a long rest.
+          `,
+      },
+      {
+        name: 'Ability Score Improvement',
+        level: 4,
+        description: `
+          When you reach 4th level, and again at 8th, 12th, 16th, and 19th level, you can increase one ability score of your choice by 2, or you can increase two ability scores of your choice by 1. As normal, you can't increase an ability score above 20 using this feature.  
+          `,
+      },
+      {
+        name: 'Destroy Undead',
+        level: 5,
+        description: `
+          Starting at 5th level, when an undead fails its saving throw against your Turn Undead feature, the creature is instantly destroyed if its challenge rating is at or below a certain threshold, as shown in the Cleric table above.          `,
+      },
+      {
+        name: 'Blessed Strikes',
+        level: 8,
+        description: `
+          Replaces the Divine Strike or Potent Spellcasting feature
+
+          When you reach 8th level, you are blessed with divine might in battle. When a creature takes damage from one of your cantrips or weapon attacks, you can also deal 1d8 radiant damage to that creature. Once you deal this damage, you can't use this feature again until the start of your next turn.
+        `,
+      },
+      {
+        name: 'Ability Score Improvement',
+        level: 8,
+        description: `
+          When you reach 4th level, and again at 8th, 12th, 16th, and 19th level, you can increase one ability score of your choice by 2, or you can increase two ability scores of your choice by 1. As normal, you can't increase an ability score above 20 using this feature.  
+          `,
+      },
+      {
+        name: 'Divine Intervention',
+        level: 10,
+        description: `
+          Beginning at 10th level, you can call on your deity to intervene on your behalf when your need is great.
+
+          Imploring your deity's aid requires you to use your action. Describe the assistance you seek, and roll percentile dice. If you roll a number equal to or lower than your cleric level, your deity intervenes. The GM chooses the nature of the intervention; the effect of any cleric spell or cleric domain spell would be appropriate.
+
+          If your deity intervenes, you can't use this feature again for 7 days. Otherwise, you can use it again after you finish a long rest.
+
+          At 20th level, your call for intervention succeeds automatically, no roll required.
+        `,
+      },
+    ],
+  };
+
+  private notImplementedYet: any = {
+    title: 'Not implemented yet',
+    description: `
+    This class is not implemented yet. Please check back later.
+    `,
+    features: [],
+  };
+}

+ 52 - 5
src/services/data/data.service.ts

@@ -1,6 +1,5 @@
 import { Injectable } from '@angular/core';
 import Localbase from 'localbase';
-import { Router } from '@angular/router';
 import { BehaviorSubject } from 'rxjs';
 import { Attribute } from 'src/interfaces/attribute';
 import { Skill } from 'src/interfaces/skill';
@@ -20,7 +19,7 @@ export class DataService {
   public dataLoaded = false;
   public characterName: string = '';
 
-  constructor(private Router: Router) {
+  constructor() {
     this.db = new Localbase('DNDTools');
     // this.db.config.debug = false;
   }
@@ -41,7 +40,6 @@ export class DataService {
   private buildCurrentCharacter(currentCharacterData: any): void {
     const [
       abilitiesData,
-      appearanceData,
       attributesData,
       characterData,
       combatStatsData,
@@ -50,10 +48,10 @@ export class DataService {
       favoriteWeaponsData,
       foodData,
       hitPointsData,
+      imageData,
       kiPointsData,
       miscellaneousData,
       moneyData,
-      personalityData,
       proficienciesData,
       skillsData,
       spellLevel0,
@@ -71,6 +69,13 @@ export class DataService {
       weaponsAndArmorData,
     ] = currentCharacterData.map((entry: any) => entry.data);
 
+    // Character Data
+    this.characterData = characterData;
+
+    //Character Image
+
+    this.image = imageData;
+
     // Attributes
     Object.keys(attributesData).forEach((key: string) => {
       this.updateAttribute(attributesData[key]);
@@ -126,6 +131,41 @@ export class DataService {
 
   // #endregion
 
+  // #region # Character and Image DATA
+
+  private _image: any = {
+    value: '',
+  };
+
+  public get image(): any {
+    return this._image;
+  }
+
+  public set image(newValue: any) {
+    this._image = newValue;
+    this.setData('image', newValue);
+  }
+
+  private _characterData: any = {
+    class: '',
+    subclass: '',
+    race: '',
+    background: '',
+    level: 1,
+    experience: 0,
+  };
+
+  public get characterData(): any {
+    return this._characterData;
+  }
+
+  public set characterData(newValue: any) {
+    this._characterData = newValue;
+    this.setData('characterData', newValue);
+  }
+
+  // #endregion
+
   // #region # SPELLS
 
   private _favoriteSpells: Spell[] = [];
@@ -271,7 +311,7 @@ export class DataService {
 
   // #endregion
 
-  // #region ABILITIES
+  // #region # ABILITIES
 
   private _abilities: Ability[] = [];
 
@@ -298,6 +338,7 @@ export class DataService {
   private _spellslots: any = {
     spellslots: [],
     showSpellslots: true,
+    spellcastingAttribute: undefined,
   };
 
   public get spellslots(): any {
@@ -768,6 +809,10 @@ export class DataService {
     return this.db.collection(collection).get({ keys: true });
   }
 
+  public setCollection(collection: string, data: any) {
+    return this.db.collection(collection).set(data);
+  }
+
   public setData(key: string, data: any) {
     return this.db
       .collection(this.characterName)
@@ -777,6 +822,8 @@ export class DataService {
   }
 
   public deleteCollection(collection: string) {
+    console.log('delete collection', collection);
+
     this.db.collection(collection).delete();
   }
 

+ 1 - 0
src/services/modal/modal.service.ts

@@ -15,6 +15,7 @@ export class ModalService {
   result$ = this._resultSubject.asObservable();
 
   public openModal(component: any, data: any) {
+    console.log('ModalService: openModal');
     this._modalSubject.next({ component, data });
   }
 

+ 16 - 0
src/services/species/species.service.spec.ts

@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { SpeciesService } from './species.service';
+
+describe('SpeciesService', () => {
+  let service: SpeciesService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(SpeciesService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});

+ 124 - 0
src/services/species/species.service.ts

@@ -0,0 +1,124 @@
+import { Injectable } from '@angular/core';
+
+@Injectable({
+  providedIn: 'root',
+})
+export class SpeciesService {
+  constructor() {}
+
+  public getSpeciesDetails(name: string): any {
+    switch (name) {
+      case 'Eladrin':
+        return this.eladrin;
+      case 'HalfElfDetection':
+        return this.halfElfDetection;
+      default:
+        // throw new Error(`DND-Error: Species ${name} not found`);
+        return this.notImplementedYet;
+    }
+  }
+
+  private eladrin: any = {
+    title: 'Eladrin',
+    description: `
+    Eladrin are elves of the Feywild, a realm of perilous beauty and boundless magic. Using that magic, eladrin can step from one place to another in the blink of an eye, and each eladrin resonates with emotions captured in the Feywild in the form of seasons — affinities that affect the eladrin’s mood and appearance. An eladrin’s season can change, though some remain in one season forever. Like other elves, eladrin can live to be over 750 years old.
+
+    #### Eladrin Seasons
+
+    1. **Autumn:** peace and goodwill, when summer's harvest is shared with all.
+    2. **Winter:** contemplation and dolor, when the vibrant energy of the world slumbers.
+    3. **Spring:** cheerfulness and celebration, marked by merriment and hope as winter's sorrow passes.
+    4. **Summer:** boldness and aggression, a time of unfettered energy and calls to action.
+
+    **Ability Score Increase:** When determining your character’s ability scores, increase one score by 2 and increase a different score by 1, or increase three different scores by 1. You can't raise any of your scores above 20.
+    
+    **Creature Type:** You are a Humanoid. You are also considered an elf for any prerequisite or effect that requires you to be an elf.
+    
+    **Size:** You are Medium.
+    
+    **Speed:** Your walking speed is 30 feet.
+    
+    **Darkvision:** You can see in dim light within 60 feet of you as if it were bright light and in darkness as if it were dim light. You discern colors in that darkness only as shades of gray.
+    
+    **Fey Ancestry:** You have advantage on saving throws you make to avoid or end the charmed condition on yourself.
+    
+    **Fey Step:** As a bonus action, you can magically teleport up to 30 feet to an unoccupied space you can see. You can use this trait a number of times equal to your proficiency bonus, and you regain all expended uses when you finish a long rest.
+    When you reach 3rd level, your Fey Step gains an additional effect based on your season; if the effect requires a saving throw, the DC equals 8 + your proficiency bonus + your Intelligence, Wisdom, or Charisma modifier (choose when you select this race):
+    - **Autumn** Immediately after you use your Fey Step, up to two creatures of your choice that you can see within 10 feet of you must succeed on a Wisdom saving throw or be charmed by you for 1 minute, or until you or your companions deal any damage to the creatures.
+    - **Winter** When you use your Fey Step, one creature of your choice that you can see within 5 feet of you before you teleport must succeed on a Wisdom saving throw or be frightened of you until the end of your next turn.
+    - **Spring** When you use your Fey Step, you can touch one willing creature within 5 feet of you. That creature then teleports instead of you, appearing in an unoccupied space of your choice that you can see within 30 feet of you.
+    - **Summer** Immediately after you use your Fey Step, each creature of your choice that you can see within 5 feet of you takes fire damage equal to your proficiency bonus.
+   
+    **Keen Senses** You have proficiency in the Perception skill.
+   
+    **Trance** You don’t need to sleep, and magic can’t put you to sleep. You can finish a long rest in 4 hours if you spend those hours in a trancelike meditation, during which you retain consciousness.
+    - Whenever you finish this trance, you can change your season, and you can gain two proficiencies that you don’t have, each one with a weapon or a tool of your choice selected from the Player’s Handbook. You mystically acquire these proficiencies by drawing them from shared elven memory, and you retain them until you finish your next long rest.
+   
+    **Languages** Your character can speak, read, and write Common and one other language that you and your DM agree is appropriate for the character. The Player’s Handbook offers a list of languages to choose from. The DM is free to modify that list for a campaign.
+    
+    `,
+    abilities: [
+      {
+        name: 'Fey Step',
+        level: 0,
+        description: `
+        **Fey Step:** As a bonus action, you can magically teleport up to 30 feet to an unoccupied space you can see. You can use this trait a number of times equal to your proficiency bonus, and you regain all expended uses when you finish a long rest.
+        When you reach 3rd level, your Fey Step gains an additional effect based on your season; if the effect requires a saving throw, the DC equals 8 + your proficiency bonus + your Intelligence, Wisdom, or Charisma modifier (choose when you select this race):
+        - **Autumn** Immediately after you use your Fey Step, up to two creatures of your choice that you can see within 10 feet of you must succeed on a Wisdom saving throw or be charmed by you for 1 minute, or until you or your companions deal any damage to the creatures.
+        - **Winter** When you use your Fey Step, one creature of your choice that you can see within 5 feet of you before you teleport must succeed on a Wisdom saving throw or be frightened of you until the end of your next turn.
+        - **Spring** When you use your Fey Step, you can touch one willing creature within 5 feet of you. That creature then teleports instead of you, appearing in an unoccupied space of your choice that you can see within 30 feet of you.
+        - **Summer** Immediately after you use your Fey Step, each creature of your choice that you can see within 5 feet of you takes fire damage equal to your proficiency bonus.
+   
+        `,
+      },
+    ],
+  };
+
+  private halfElfDetection: any = {
+    title: 'Half-Elf (Mark of Detection)',
+    description: `
+    Walking in two worlds but truly belonging to neither, half-elves combine what some say are the best qualities of their elf and human parents: human curiosity, inventiveness, and ambition tempered by the refined senses, love of nature, and artistic tastes of the elves.
+
+    **Ability Score Increase:** Your Wisdom score increases by 2, and one other Ability Score of your choice increases by 1.
+    
+    **Creature Type:** You are a Humanoid. You are also considered an elf for any prerequisite or effect that requires you to be an elf.
+    
+    **Size:** You are Medium.
+    
+    **Speed:** Your walking speed is 35 feet.
+    
+    **Darkvision:** You can see in dim light within 60 feet of you as if it were bright light and in darkness as if it were dim light. You discern colors in that darkness only as shades of gray.
+    
+    **Fey Ancestry:** You have advantage on saving throws you make to avoid or end the charmed condition on yourself.
+    
+    **Skill Versatility:** You gain proficiency in two skills of your choice.
+    
+    **Languages:** Your character can speak, read, and write Common, Elvish, and one extra language of your choice.
+    
+    **Deductive Intuition:** Whenever you make a Intelligence (Investigation) or a Wisdom (Insight) check, you can roll a d4 and add the number rolled to the total ability check.
+
+    **Magical Detection:** You can cast the Detect Magic and the Detect Poison and Disease spells with this trait. Starting at 3rd level, you can also cast the See Invisibility spell with it. Once you cast either spell with this trait, you can't cast that spell again until you finish a Long Rest. Intelligence is your Spellcasting Ability for these spells, and you don't require material components for them.
+
+    **Spells of the Mark:** If you have the Spellcasting or Pact Magic class feature, the spells on the Mark of Detection Spells table are added to the spell list of your Spellcasting class.
+
+    **Mark of Detection Spells**
+
+    | Spell Level | Spells |
+    | ----------- | ------ |
+    | 1st | Detect Magic, Detect Poison and Disease |
+    | 2nd | See Invisibility |
+    | 3rd | Clairvoyance, Tongues |
+    | 4th | Arcane Eye, Locate Creature |
+    | 5th | Legend Lore, Rary's Telepathic Bond |
+    
+    `,
+    abilities: [],
+  };
+
+  private notImplementedYet: any = {
+    title: 'Not Implemented Yet',
+    description: `
+    `,
+    abilities: [],
+  };
+}

+ 29 - 0
src/services/spells/spells.service.ts

@@ -25,6 +25,7 @@ export class SpellsService {
 
   private level1: string[] = [
     'Wunden Heilen (Cure Wounds)',
+    'Wunden hinzufügen (Inflict Wounds)',
     'Magie entdecken (Detect Magic)',
     'Gift und Krankheiten entdecken (Detect Poison and Disease)',
     'Segnen (Bless)',
@@ -87,6 +88,8 @@ export class SpellsService {
         return this.thaumaturgie;
       case 'Wunden Heilen (Cure Wounds)':
         return this.cureWounds;
+      case 'Wunden hinzufügen (Inflict Wounds)':
+        return this.inflictWounds;
       case 'Magie entdecken (Detect Magic)':
         return this.detectMagic;
       case 'Segnen (Bless)':
@@ -106,6 +109,32 @@ export class SpellsService {
     }
   }
 
+  private inflictWounds: Spell = {
+    name: 'Wunden hinzufügen',
+    level: 1,
+    cost: 'action',
+    duration: 0,
+    canRitual: false,
+    needsVerbal: true,
+    needsSomatic: true,
+    needsMaterial: false,
+    needsConcentration: false,
+    needsAttackRoll: true,
+    needsSavingThrow: false,
+    doesDamage: true,
+    damage: [{ diceNumber: '3', diceType: 'd10', damageType: 'necrotic' }],
+    doesHeal: false,
+    heal: { diceNumber: '', diceType: '', additionalHeal: 0 },
+    description:
+      'Mach einen Nahkampf-Zauberangriff gegen eine Kreatur deiner Wahl. Bei einem Erfolg erleidet das Ziel 3W10 Nekrotischen Schaden. Auf höheren Graden: Wirkst du diesen Zauber, indem du einen Zauberplatz des 2. Grades oder höher nutzt, steigt der Schaden für jeden Grad über dem 1. um 1W10.',
+    school: 'necromancy',
+    isRanged: false,
+    range: 5,
+    hasAreaOfEffect: false,
+    areaOfEffectType: '',
+    radius: 0,
+  };
+
   private guidance: Spell = {
     name: 'Göttliche Führung',
     level: 0,

+ 16 - 0
src/services/subclass/subclass.service.spec.ts

@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { SubclassService } from './subclass.service';
+
+describe('SubclassService', () => {
+  let service: SubclassService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(SubclassService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});

+ 115 - 0
src/services/subclass/subclass.service.ts

@@ -0,0 +1,115 @@
+import { Injectable } from '@angular/core';
+
+@Injectable({
+  providedIn: 'root',
+})
+export class SubclassService {
+  public getSubclassDetails(subclass: string): any {
+    switch (subclass) {
+      case 'Echo Knight':
+        return this.echoKnight;
+      case 'PeaceDomain':
+        return this.peaceDomain;
+      default:
+        return null;
+    }
+  }
+
+  private peaceDomain: any = {
+    title: 'Peace Domain',
+    description: `
+      The balm of peace thrives at the heart of healthy communities, between friendly nations, and in the souls of the kindhearted. The gods of peace inspire people of all sorts to resolve conflict and to stand up against those forces that try to prevent peace from flourishing. See the Peace Deities table for a list of some of the gods associated with this domain.
+
+      Clerics of the Peace Domain preside over the signing of treaties, and they are often asked to arbitrate in disputes. These clerics' blessings draw people together and help them shoulder one another's burdens, and the clerics' magic aids those who are driven to fight for the way of peace.
+    `,
+    features: [
+      {
+        name: 'Implement of Peace',
+        level: 1,
+        description: `
+          When you choose this domain at 1st level, you gain proficiency in the Insight, Performance, or Persuasion skill (your choice).
+        `,
+      },
+      {
+        name: 'Emboldening Bond',
+        level: 1,
+        description: `
+          Starting at 1st level, you can forge an empowering bond among people who are at peace with one another. As an action, you choose a number of willing creatures within 30 feet of you (this can include yourself) equal to your proficiency bonus. You create a magical bond among them for 10 minutes or until you use this feature again. While any bonded creature is within 30 feet of another, the creature can roll a d4 and add the number rolled to an attack roll, an ability check, or a saving throw it makes. Each creature can add the d4 no more than once per turn.
+
+          You can use this feature a number of times equal to your proficiency bonus, and you regain all expended uses when you finish a long rest.
+        `,
+      },
+      {
+        name: 'Channel Divinity: Balm of Peace',
+        level: 2,
+        description: `
+          Starting at 2nd level, you can use your Channel Divinity to make your very presence a soothing balm. As an action, you can move up to your speed, without provoking opportunity attacks, and when you move within 5 feet of any other creature during this action, you can restore a number of hit points to that creature equal to 2d6 + your Wisdom modifier (minimum of 1 hit point). A creature can receive this healing only once whenever you take this action.
+        `,
+      },
+    ],
+  };
+  private echoKnight: any = {
+    title: 'Echo Knight',
+    description: `
+     A mysterious and feared frontline warrior of the Kryn Dynasty, the Echo Knight has mastered the art of using dunamis to summon the fading shades of unrealized timelines to aid them in battle. Surrounded by echoes of their own might, they charge into the fray as a cycling swarm of shadows and strikes.
+    `,
+    features: [
+      {
+        name: 'Manifest Echo',
+        level: 3,
+        description: `
+          At 3rd level, you can use a bonus action to magically manifest an echo of yourself in an unoccupied space you can see within 15 feet of you. This echo is a magical, translucent, gray image of you that lasts until it is destroyed, until you dismiss it as a bonus action, until you manifest another echo, or until you're incapacitated.
+
+          Your echo has AC 14 + your proficiency bonus, 1 hit point, and immunity to all conditions. If it has to make a saving throw, it uses your saving throw bonus for the roll. It is the same size as you, and it occupies its space. On your turn, you can mentally command the echo to move up to 30 feet in any direction (no action required). If your echo is ever more than 30 feet from you at the end of your turn, it is destroyed.
+
+          - As a bonus action, you can teleport, magically swapping places with your echo at a cost of 15 feet of your movement, regardless of the distance between the two of you.
+          - When you take the Attack action on your turn, any attack you make with that action can originate from your space or the echo's space. You make this choice for each attack.
+          - When a creature that you can see within 5 feet of your echo moves at least 5 feet away from it, you can use your reaction to make an opportunity attack against that creature as if you were in the echo's space.
+        `,
+      },
+      {
+        name: 'Unleash Incarnation',
+        level: 3,
+        description: `
+          At 3rd level, you can heighten your echo's fury. Whenever you take the Attack action, you can make one additional melee attack from the echo's position.
+
+          You can use this feature a number of times equal to your Constitution modifier (a minimum of once). You regain all expended uses when you finish a long rest.
+        `,
+      },
+      {
+        name: 'Echo Avatar',
+        level: 7,
+        description: `
+          Starting at 7th level, you can temporarily transfer your consciousness to your echo. As an action, you can see through your echo's eyes and hear through its ears. During this time, you are deafened and blinded. You can sustain this effect for up to 10 minutes, and you can end it at any time (requires no action). While your echo is being used in this way, it can be up to 1,000 feet away from you without being destroyed.
+        `,
+      },
+      {
+        name: 'Shadow Martyr',
+        level: 10,
+        description: `
+          Starting at 10th level, you can make your echo throw itself in front of an attack directed at another creature that you can see. Before the attack roll is made, you can use your reaction to teleport the echo to an unoccupied space within 5 feet of the targeted creature. The attack roll that triggered the reaction is instead made against your echo.
+
+          Once you use this feature, you can't use it again until you finish a short or long rest.
+        `,
+      },
+      {
+        name: 'Reclaim Potential',
+        level: 15,
+        description: `
+          By 15th level, you've learned to absorb the fleeting magic of your echo. When an echo of yours is destroyed by taking damage, you can gain a number of temporary hit points equal to 2d6 + your Constitution modifier, provided you don't already have temporary hit points.
+
+          You can use this feature a number of times equal to your Constitution modifier (a minimum of once). You regain all expended uses when you finish a long rest.
+        `,
+      },
+      {
+        name: 'Legion of One',
+        level: 15,
+        description: `
+          At 18th level, you can use a bonus action to create two echos with your Manifest Echo feature, and these echoes can co-exist. If you try to create a third echo, the previous two echoes are destroyed. Anything you can do from one echo's position can be done from the other's instead.
+
+          In addition, when you roll initiative and have no uses of your Unleash Incarnation feature left, you regain one use of that feature.
+        `,
+      },
+    ],
+  };
+}

+ 16 - 0
src/services/translator/translator.service.spec.ts

@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { TranslatorService } from './translator.service';
+
+describe('TranslatorService', () => {
+  let service: TranslatorService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(TranslatorService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});

+ 77 - 0
src/services/translator/translator.service.ts

@@ -0,0 +1,77 @@
+import { Injectable } from '@angular/core';
+
+@Injectable({
+  providedIn: 'root',
+})
+export class TranslatorService {
+  constructor() {}
+
+  public races: any = {
+    Aarakocra: { display: 'Aarakocra', value: 'Aarakocra' },
+    Aasimar: { display: 'Aasimar', value: 'Aasimar' },
+    Autognome: { display: 'Autognom', value: 'Autognome' },
+    Bugbear: { display: 'Grottenschrat', value: 'Bugbear' },
+    Centaur: { display: 'Zentaur', value: 'Centaur' },
+    Changeling: { display: 'Wechselbalg ', value: 'Changeling' },
+    Dragonborn: { display: 'Drachenblütiger', value: 'Dragonborn' },
+    Duergar: { display: 'Duergar', value: 'Duergar' },
+    Dwarf: { display: 'Zwerg', value: 'Dwarf' },
+    Fairy: { display: 'Fee', value: 'Fairy' },
+    Firbolg: { display: 'Firbolg', value: 'Firbolg' },
+    Genasi: { display: 'Genasi', value: 'Genasi' },
+    Gith: { display: 'Gedankenschinder', value: 'Gith' },
+    Gnome: { display: 'Gnom', value: 'Gnome' },
+    Goblin: { display: 'Goblin', value: 'Goblin' },
+    Goliath: { display: 'Goliath', value: 'Goliath' },
+    HalfElf: { display: 'Halbelf', value: 'HalfElf' },
+    HalfElfDetection: {
+      view: 'Halbelf (Mal des Entdeckens)',
+      value: 'HalfElfDetection',
+    },
+    HalfOrc: { display: 'Halbork', value: 'HalfOrc' },
+    Halfling: { display: 'Halbling', value: 'Halfling' },
+    Hobgoblin: { display: 'Hobgoblin', value: 'Hobgoblin' },
+    Human: { display: 'Mensch', value: 'Human' },
+    Kalashtar: { display: 'Kalashtar', value: 'Kalashtar' },
+    Kenku: { display: 'Kenku', value: 'Kenku' },
+    Kobold: { display: 'Kobold', value: 'Kobold' },
+    Leonin: { display: 'Leonin', value: 'Leonin' },
+    Lizardfolk: { display: 'Echsenmensch', value: 'Lizardfolk' },
+    Locathah: { display: 'Locathah', value: 'Locathah' },
+    Loxodon: { display: 'Loxodon', value: 'Loxodon' },
+    Minotaur: { display: 'Minotaurus', value: 'Minotaur' },
+    Orc: { display: 'Ork', value: 'Orc' },
+    Owlin: { display: 'Eulenmensch', value: 'Owlin' },
+    Satyr: { display: 'Satyr', value: 'Satyr' },
+    Shifter: { display: 'Wandler', value: 'Shifter' },
+    Tabaxi: { display: 'Tabaxi', value: 'Tabaxi' },
+    Tiefling: { display: 'Tiefling', value: 'Tiefling' },
+    Tortle: { display: 'Tortle', value: 'Tortle' },
+    Triton: { display: 'Triton', value: 'Triton' },
+    Vedalken: { display: 'Vedalken', value: 'Vedalken' },
+    Verdan: { display: 'Verdan', value: 'Verdan' },
+    Warforged: { display: 'Kriegsgeschmiedeter', value: 'Warforged' },
+    YuanTi: { display: 'Yuan-Ti', value: 'YuanTi' },
+  };
+
+  public classes: any = {
+    Barbarian: { display: 'Barbar', value: 'Barbarian' },
+    Bard: { display: 'Barde', value: 'Bard' },
+    Cleric: { display: 'Kleriker', value: 'Cleric' },
+    Druid: { display: 'Druide', value: 'Druid' },
+    Fighter: { display: 'Kämpfer', value: 'Fighter' },
+    Monk: { display: 'Mönch', value: 'Monk' },
+    Paladin: { display: 'Paladin', value: 'Paladin' },
+    Ranger: { display: 'Waldläufer', value: 'Ranger' },
+    Rogue: { display: 'Schurke', value: 'Rogue' },
+    Sorcerer: { display: 'Zauberer', value: 'Sorcerer' },
+    Warlock: { display: 'Hexenmeister', value: 'Warlock' },
+    Wizard: { display: 'Magier', value: 'Wizard' },
+  };
+
+  public genders: any = {
+    Male: { display: 'Männlich', value: 'Male' },
+    Female: { display: 'Weiblich', value: 'Female' },
+    Diverse: { display: 'Divers', value: 'Diverse' },
+  };
+}

+ 23 - 3
src/styles.scss

@@ -5,7 +5,7 @@
 @import "bootstrap/scss/bootstrap";
 
 :root {
-    // COLORS
+    // COLORS to use but not official
     --primary-color: #d8ac96;
     --primary-color-light: #e8c7b5;
     --primary-color-dark: #d89777;
@@ -25,6 +25,15 @@
 
     --border-color: #8d8c8c;
 
+    --modal-background: antiquewhite;
+
+    --button-color: #efc8af;
+    --button-color-hover: #e7b295;
+
+    --header: #ffdec6;
+
+    --text: #000000;
+
     // OFFICIAL COLORS
     --accept: #84a36f;
     --accept-hover: #6f9158;
@@ -33,14 +42,15 @@
     --edit: #86a5b7;
     --edit-hover: #6f8e9f;
 
-    --modal-background: antiquewhite;
-
     // shadows
     --shadow: 0px 5px 10px 0px rgba(0, 0, 0, 0.5);
+    --shadow-hover: 0px 5px 10px 0px rgba(0, 0, 0, 0.7);
     --shadow-small: 4px 4px 10px 4px rgba(0, 0, 0, 0.2);
     --shadow-medium: 4px 4px 10px 6px rgba(0, 0, 0, 0.2);
     --shadow-large: 4px 4px 10px 8px rgba(0, 0, 0, 0.2);
 
+    // MIXINS
+
     @mixin field-styling {
         border: solid 1px var(--border-color);
         background-color: var(--field-background-color);
@@ -48,7 +58,17 @@
         border-radius: 10px;
     }
 
+    @mixin button-styling {
+        border: solid 1px var(--border-color);
+        box-shadow: var(--shadow);
+        border-radius: 10px;
+    }
+
     //
+
+    // input {
+
+    // }
     .responsive-small {
         display: none;
     }