From 06c48a1863764441c5691c4acdbc0967c515bc01 Mon Sep 17 00:00:00 2001
From: Justin DuJardin <justin@dujardinconsulting.com>
Date: Fri, 9 Feb 2024 13:08:52 -0800
Subject: [PATCH] style: auto format code

---
 e2e/protractor.conf.js                        |    2 +-
 e2e/src/app.e2e-spec.ts                       |    2 +-
 package-lock.json                             | 3739 ++++++++---------
 package.json                                  |    6 +-
 src/app/app.component.ts                      |    2 +-
 src/app/app.effects.ts                        |   60 +-
 src/app/app.imports.ts                        |    3 +-
 src/app/app.testing.ts                        |   22 +-
 src/app/behaviors/animated-sprite.behavior.ts |    3 +-
 src/app/behaviors/base-player.behavior.ts     |    3 +-
 src/app/behaviors/camera-behavior.ts          |    3 +-
 src/app/behaviors/collision.behavior.ts       |    5 +-
 src/app/behaviors/damage.behavior.ts          |    1 -
 src/app/behaviors/movable-behavior.ts         |    4 +-
 src/app/behaviors/sound-behavior.ts           |    1 -
 src/app/behaviors/sprite-render.behavior.ts   |    3 +-
 src/app/behaviors/sprite.behavior.ts          |    3 +-
 src/app/behaviors/ticked-behavior.ts          |    1 -
 src/app/behaviors/tile-map-path.behavior.ts   |    1 -
 src/app/behaviors/tile-object-behavior.ts     |    1 -
 .../components/animated/animated.component.ts |    4 +-
 .../debug-menu/debug-menu.component.ts        |    6 +-
 src/app/components/index.ts                   |    1 -
 .../components/loading/loading.component.scss |   14 +-
 .../notification/notification.component.ts    |    3 +-
 .../notification/notification.service.ts      |    1 -
 .../party-inventory.component.ts              |   24 +-
 .../party-menu/party-menu.component.scss      |    4 +-
 .../party-menu/party-menu.component.ts        |    2 +-
 .../player-card/player-card.component.ts      |    5 +-
 .../player-stats/player-stats.component.ts    |   16 +-
 src/app/components/sprite/sprite.component.ts |   11 +-
 src/app/components/sprite/sprite.stories.ts   |    5 +-
 src/app/core/animator.ts                      |    1 -
 src/app/core/api.ts                           |    1 -
 src/app/core/behavior-host.ts                 |    2 +-
 src/app/core/behavior.ts                      |    1 -
 src/app/core/errors.ts                        |    2 -
 src/app/core/input.ts                         |    1 -
 src/app/core/point.ts                         |    1 -
 src/app/core/rect.spec.ts                     |    2 +-
 src/app/core/rect.ts                          |    1 -
 src/app/core/resource.ts                      |    6 +-
 src/app/core/resources/audio.resource.ts      |    1 -
 src/app/core/resources/image.resource.ts      |    1 -
 src/app/core/resources/json.resource.ts       |    1 -
 .../resources/tiled/tiled-tmx.resource.ts     |    5 +-
 .../resources/tiled/tiled-tsx.resource.ts     |    7 +-
 src/app/core/resources/tiled/tiled.ts         |    2 +-
 src/app/core/resources/xml.resource.ts        |    3 +-
 src/app/core/state-machine.ts                 |    7 +-
 src/app/core/state.ts                         |    1 -
 src/app/core/time.ts                          |    1 -
 src/app/core/world.ts                         |    1 -
 src/app/models/combat/combat.effects.ts       |  230 +-
 src/app/models/combat/combat.reducer.spec.ts  |   18 +-
 src/app/models/combat/combat.reducer.ts       |    8 +-
 src/app/models/combat/combat.service.ts       |    6 +-
 src/app/models/entity-collections.ts          |   16 +-
 src/app/models/entity/entity.reducer.spec.ts  |   42 +-
 src/app/models/entity/entity.reducer.ts       |   26 +-
 src/app/models/game-data/game-data.model.ts   |    6 +-
 .../models/game-state/game-state.actions.ts   |   10 +-
 .../game-state/game-state.effects.spec.ts     |    4 +-
 .../models/game-state/game-state.effects.ts   |  146 +-
 .../game-state/game-state.reducer.spec.ts     |   26 +-
 .../models/game-state/game-state.reducer.ts   |   16 +-
 .../models/game-state/game-state.service.ts   |   15 +-
 src/app/models/index.ts                       |    2 +-
 src/app/models/levels.ts                      |    2 +-
 src/app/models/mechanics.spec.ts              |    2 +-
 src/app/models/mechanics.ts                   |   30 +-
 src/app/models/selectors.ts                   |   30 +-
 .../models/sprites/sprites.effects.spec.ts    |    2 +-
 src/app/models/sprites/sprites.effects.ts     |   35 +-
 src/app/models/sprites/sprites.reducer.ts     |    2 +-
 src/app/models/sprites/sprites.service.ts     |    8 +-
 src/app/models/util.ts                        |    4 +-
 .../actions/combat-attack.behavior.ts         |   14 +-
 .../actions/combat-guard.behavior.ts          |    8 +-
 .../behaviors/actions/combat-item.behavior.ts |    2 +-
 .../actions/combat-magic.behavior.ts          |    8 +-
 .../behaviors/actions/combat-run.behavior.ts  |    7 +-
 .../routes/combat/behaviors/actions/index.ts  |    2 -
 .../behaviors/choose-action.machine.spec.ts   |    2 +-
 .../combat/behaviors/choose-action.machine.ts |    2 +-
 .../behaviors/combat-action.behavior.ts       |    8 +-
 .../routes/combat/combat-enemy.component.ts   |    2 +-
 src/app/routes/combat/combat-hud.component.ts |    4 +-
 .../routes/combat/combat-player.component.ts  |    2 +-
 src/app/routes/combat/combat.component.ts     |   18 +-
 src/app/routes/combat/combat.guards.ts        |    9 +-
 src/app/routes/combat/combat.testing.ts       |   14 +-
 src/app/routes/combat/index.ts                |    1 -
 .../routes/combat/states/combat-base.state.ts |    2 -
 .../states/combat-begin-turn.state.spec.ts    |    2 +-
 .../combat/states/combat-begin-turn.state.ts  |    3 +-
 .../states/combat-choose-action.state.ts      |    9 +-
 .../combat/states/combat-defeat.state.ts      |    1 -
 .../combat/states/combat-end-turn.state.ts    |    1 -
 .../combat/states/combat-escape.state.ts      |    1 -
 .../combat/states/combat-start.state.ts       |    1 -
 .../states/combat-victory.state.spec.ts       |    4 +-
 .../combat/states/combat-victory.state.ts     |    5 +-
 .../combat/states/combat.machine.spec.ts      |    4 +-
 .../routes/combat/states/combat.machine.ts    |   10 +-
 src/app/routes/combat/states/index.ts         |    1 -
 src/app/routes/game/game.component.ts         |    2 +-
 src/app/routes/game/game.resolver.ts          |    7 +-
 .../behaviors/combat-encounter.behavior.ts    |    8 +-
 .../behaviors/map-feature-input.behavior.ts   |    1 -
 .../routes/world/behaviors/player-behavior.ts |    3 +-
 .../world/behaviors/player-camera.behavior.ts |    5 +-
 .../world/behaviors/player-look.behavior.ts   |    7 +-
 .../behaviors/player-map-path.behavior.ts     |    5 +-
 .../world/behaviors/player-render.behavior.ts |    1 -
 .../world/features/block-feature.component.ts |    1 -
 .../features/combat-feature.component.spec.ts |    4 +-
 .../features/combat-feature.component.ts      |    7 +-
 .../features/dialog-feature.component.spec.ts |    2 +-
 .../features/dialog-feature.component.ts      |    8 +-
 .../features/door-feature.component.spec.ts   |    4 +-
 .../world/features/door-feature.component.ts  |   18 +-
 .../features/portal-feature.component.spec.ts |    4 +-
 .../features/portal-feature.component.ts      |    3 +-
 .../features/ship-feature.component.spec.ts   |    6 +-
 .../world/features/ship-feature.component.ts  |    3 +-
 .../features/store-feature.component.spec.ts  |   12 +-
 .../world/features/store-feature.component.ts |   34 +-
 .../features/temple-feature.component.spec.ts |   12 +-
 .../features/temple-feature.component.ts      |   12 +-
 .../treasure-feature.component.spec.ts        |    2 +-
 .../features/treasure-feature.component.ts    |    1 -
 src/app/routes/world/map-feature.component.ts |    2 +-
 .../routes/world/world-player.component.ts    |    6 +-
 src/app/routes/world/world.component.ts       |   40 +-
 src/app/routes/world/world.guards.ts          |   11 +-
 src/app/routes/world/world.stories.ts         |    5 +-
 .../scene/objects/game-entity-object.spec.ts  |    2 +-
 src/app/scene/objects/game-entity-object.ts   |    1 -
 src/app/scene/objects/game-feature-object.ts  |    4 +-
 src/app/scene/render/tile-map-renderer.ts     |    9 +-
 src/app/scene/render/tile-object-renderer.ts  |    6 +-
 src/app/scene/scene-object.ts                 |    9 +-
 src/app/scene/scene-view.ts                   |    9 +-
 src/app/scene/scene.model.ts                  |    4 +-
 src/app/scene/scene.ts                        |    1 -
 src/app/scene/spatial-database.ts             |    1 -
 src/app/scene/tile-map.ts                     |    3 +-
 src/app/scene/tile-object.ts                  |    1 -
 src/app/services/animate.ts                   |    1 -
 src/app/services/game-world.ts                |    4 +-
 src/app/services/index.ts                     |    1 -
 src/app/services/rpg-game.ts                  |   12 +-
 src/app/services/sprite-render.ts             |    3 +-
 src/app/services/window.ts                    |    1 -
 src/app/style/mixins.scss                     |   14 +-
 src/app/style/theme.scss                      |    1 -
 src/app/style/variables.scss                  |   15 +-
 src/assets/fonts/iconfont/material-icons.css  |    4 +-
 src/assets/images/animation.json              |    2 +-
 src/assets/images/characters.json             |  242 +-
 src/assets/images/creatures.json              |    2 +-
 src/assets/images/environment.json            |    2 +-
 src/assets/images/equipment.json              |    2 +-
 src/assets/images/index.json                  |    2 +-
 src/assets/images/items.json                  |    2 +-
 src/assets/images/magic.json                  |  386 +-
 src/assets/images/objects.json                |    2 +-
 src/assets/images/punch.json                  |  338 +-
 src/assets/images/vehicles.json               |   22 +-
 src/assets/maps/tiles/creatures.tsx           |  703 ++--
 src/assets/maps/tiles/environment.tsx         | 1063 +++--
 src/assets/maps/tiles/objects.tsx             |  201 +-
 src/index.html                                |   34 +-
 src/test.ts                                   |    7 +-
 src/tiled/follow-portal.js                    |   14 +-
 src/tiled/portal-tool.ts                      |    2 +-
 src/tiled/prune-tileset-tool.ts               |   10 +-
 src/tiled/tsconfig.tiled.json                 |   17 +-
 src/tsconfig.write-game-data.json             |    6 +-
 src/typings.d.ts                              |    2 +-
 src/webpack/game-data-plugin/index.js         |    4 +-
 src/webpack/sprite-sheet-plugin/README.md     |    2 +-
 src/webpack/sprite-sheet-plugin/index.js      |    2 +-
 .../sprite-sheet-plugin/sprite-packer.js      |  120 +-
 .../sprite-sheet-plugin/test/test.entry.js    |    2 +-
 .../test/webpack.config.js                    |   26 +-
 188 files changed, 4075 insertions(+), 4326 deletions(-)

diff --git a/e2e/protractor.conf.js b/e2e/protractor.conf.js
index 727e6e68..7f49a730 100644
--- a/e2e/protractor.conf.js
+++ b/e2e/protractor.conf.js
@@ -30,7 +30,7 @@ exports.config = {
         spec: {
           displayStacktrace: StacktraceOption.PRETTY,
         },
-      })
+      }),
     );
   },
 };
diff --git a/e2e/src/app.e2e-spec.ts b/e2e/src/app.e2e-spec.ts
index 9bec89eb..29d42f71 100644
--- a/e2e/src/app.e2e-spec.ts
+++ b/e2e/src/app.e2e-spec.ts
@@ -19,7 +19,7 @@ describe('workspace-project App', () => {
     expect(logs).not.toContain(
       jasmine.objectContaining({
         level: logging.Level.SEVERE,
-      } as logging.Entry)
+      } as logging.Entry),
     );
   });
 });
diff --git a/package-lock.json b/package-lock.json
index 74d75788..74fe0f57 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -72,9 +72,9 @@
         "karma-jasmine-html-reporter": "^2.0.0",
         "memory-streams": "^0.1.3",
         "pngjs": "^6.0.0",
-        "prettier": "^2.1.2",
-        "prettier-eslint-cli": "^5.0.0",
-        "prettier-plugin-organize-imports": "^1.1.1",
+        "prettier": "^3.2.5",
+        "prettier-eslint-cli": "^8.0.1",
+        "prettier-plugin-organize-imports": "^3.2.4",
         "protractor": "~7.0.0",
         "react-is": "^16.13.1",
         "semantic-release": "^19.0.5",
@@ -83,6 +83,15 @@
         "typescript": "~5.3.3"
       }
     },
+    "node_modules/@aashutoshrathi/word-wrap": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
+      "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/@aduh95/viz.js": {
       "version": "3.5.0",
       "dev": true,
@@ -1288,53 +1297,6 @@
         "yarn": ">= 1.13.0"
       }
     },
-    "node_modules/@angular/cli/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/@angular/cli/node_modules/cliui": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
-      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
-      "dev": true,
-      "dependencies": {
-        "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.1",
-        "wrap-ansi": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@angular/cli/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/@angular/cli/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/@angular/cli/node_modules/jsonc-parser": {
       "version": "3.2.0",
       "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
@@ -1394,59 +1356,6 @@
         "node": ">=10"
       }
     },
-    "node_modules/@angular/cli/node_modules/wrap-ansi": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
-      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
-      }
-    },
-    "node_modules/@angular/cli/node_modules/y18n": {
-      "version": "5.0.8",
-      "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
-      "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/@angular/cli/node_modules/yargs": {
-      "version": "17.7.2",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
-      "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
-      "dev": true,
-      "dependencies": {
-        "cliui": "^8.0.1",
-        "escalade": "^3.1.1",
-        "get-caller-file": "^2.0.5",
-        "require-directory": "^2.1.1",
-        "string-width": "^4.2.3",
-        "y18n": "^5.0.5",
-        "yargs-parser": "^21.1.1"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@angular/cli/node_modules/yargs-parser": {
-      "version": "21.1.1",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
-      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      }
-    },
     "node_modules/@angular/common": {
       "version": "17.1.3",
       "resolved": "https://registry.npmjs.org/@angular/common/-/common-17.1.3.tgz",
@@ -1554,46 +1463,6 @@
         "semver": "bin/semver.js"
       }
     },
-    "node_modules/@angular/compiler-cli/node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/@angular/compiler-cli/node_modules/cliui": {
-      "version": "7.0.4",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.0",
-        "wrap-ansi": "^7.0.0"
-      }
-    },
-    "node_modules/@angular/compiler-cli/node_modules/color-convert": {
-      "version": "2.0.1",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/@angular/compiler-cli/node_modules/color-name": {
-      "version": "1.1.4",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/@angular/compiler-cli/node_modules/debug": {
       "version": "4.3.4",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -1617,55 +1486,6 @@
       "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
       "dev": true
     },
-    "node_modules/@angular/compiler-cli/node_modules/wrap-ansi": {
-      "version": "7.0.0",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
-      }
-    },
-    "node_modules/@angular/compiler-cli/node_modules/y18n": {
-      "version": "5.0.8",
-      "dev": true,
-      "license": "ISC",
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/@angular/compiler-cli/node_modules/yargs": {
-      "version": "17.5.1",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "cliui": "^7.0.2",
-        "escalade": "^3.1.1",
-        "get-caller-file": "^2.0.5",
-        "require-directory": "^2.1.1",
-        "string-width": "^4.2.3",
-        "y18n": "^5.0.5",
-        "yargs-parser": "^21.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@angular/compiler-cli/node_modules/yargs-parser": {
-      "version": "21.1.1",
-      "dev": true,
-      "license": "ISC",
-      "engines": {
-        "node": ">=12"
-      }
-    },
     "node_modules/@angular/core": {
       "version": "17.1.3",
       "resolved": "https://registry.npmjs.org/@angular/core/-/core-17.1.3.tgz",
@@ -4904,17 +4724,52 @@
         "node": ">=12"
       }
     },
+    "node_modules/@eslint-community/eslint-utils": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+      "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+      "dev": true,
+      "dependencies": {
+        "eslint-visitor-keys": "^3.3.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "peerDependencies": {
+        "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+      }
+    },
+    "node_modules/@eslint-community/eslint-utils/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-community/regexpp": {
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
+      "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
+      "dev": true,
+      "engines": {
+        "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+      }
+    },
     "node_modules/@eslint/eslintrc": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz",
-      "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==",
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+      "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "ajv": "^6.12.4",
         "debug": "^4.3.2",
-        "espree": "^9.3.2",
-        "globals": "^13.15.0",
+        "espree": "^9.6.0",
+        "globals": "^13.19.0",
         "ignore": "^5.2.0",
         "import-fresh": "^3.2.1",
         "js-yaml": "^4.1.0",
@@ -4923,21 +4778,22 @@
       },
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
       }
     },
     "node_modules/@eslint/eslintrc/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
+      "dev": true
     },
     "node_modules/@eslint/eslintrc/node_modules/debug": {
       "version": "4.3.4",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
       "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "ms": "2.1.2"
       },
@@ -4951,11 +4807,10 @@
       }
     },
     "node_modules/@eslint/eslintrc/node_modules/globals": {
-      "version": "13.17.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz",
-      "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==",
+      "version": "13.24.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+      "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "type-fest": "^0.20.2"
       },
@@ -4971,7 +4826,6 @@
       "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"
       },
@@ -4983,15 +4837,13 @@
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
       "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-      "dev": true,
-      "peer": true
+      "dev": true
     },
     "node_modules/@eslint/eslintrc/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"
       },
@@ -4999,6 +4851,15 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/@eslint/js": {
+      "version": "8.56.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz",
+      "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==",
+      "dev": true,
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      }
+    },
     "node_modules/@fal-works/esbuild-plugin-global-externals": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/@fal-works/esbuild-plugin-global-externals/-/esbuild-plugin-global-externals-2.1.2.tgz",
@@ -5063,15 +4924,14 @@
       "license": "MIT"
     },
     "node_modules/@humanwhocodes/config-array": {
-      "version": "0.10.4",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz",
-      "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==",
+      "version": "0.11.14",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
+      "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
       "dev": true,
-      "peer": true,
       "dependencies": {
-        "@humanwhocodes/object-schema": "^1.2.1",
-        "debug": "^4.1.1",
-        "minimatch": "^3.0.4"
+        "@humanwhocodes/object-schema": "^2.0.2",
+        "debug": "^4.3.1",
+        "minimatch": "^3.0.5"
       },
       "engines": {
         "node": ">=10.10.0"
@@ -5082,7 +4942,6 @@
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
       "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "ms": "2.1.2"
       },
@@ -5099,26 +4958,26 @@
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
       "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-      "dev": true,
-      "peer": true
+      "dev": true
     },
-    "node_modules/@humanwhocodes/gitignore-to-minimatch": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz",
-      "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==",
+    "node_modules/@humanwhocodes/module-importer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+      "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
       "dev": true,
-      "peer": true,
+      "engines": {
+        "node": ">=12.22"
+      },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/nzakas"
       }
     },
     "node_modules/@humanwhocodes/object-schema": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
-      "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
-      "dev": true,
-      "peer": true
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz",
+      "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==",
+      "dev": true
     },
     "node_modules/@isaacs/cliui": {
       "version": "8.0.2",
@@ -5247,6 +5106,18 @@
         "node": ">=8"
       }
     },
+    "node_modules/@jest/schemas": {
+      "version": "29.6.3",
+      "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
+      "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
+      "dev": true,
+      "dependencies": {
+        "@sinclair/typebox": "^0.27.8"
+      },
+      "engines": {
+        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+      }
+    },
     "node_modules/@jest/transform": {
       "version": "26.6.2",
       "dev": true,
@@ -6409,6 +6280,50 @@
         "url": "https://opencollective.com/unified"
       }
     },
+    "node_modules/@messageformat/core": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/@messageformat/core/-/core-3.3.0.tgz",
+      "integrity": "sha512-YcXd3remTDdeMxAlbvW6oV9d/01/DZ8DHUFwSttO3LMzIZj3iO0NRw+u1xlsNNORFI+u0EQzD52ZX3+Udi0T3g==",
+      "dev": true,
+      "dependencies": {
+        "@messageformat/date-skeleton": "^1.0.0",
+        "@messageformat/number-skeleton": "^1.0.0",
+        "@messageformat/parser": "^5.1.0",
+        "@messageformat/runtime": "^3.0.1",
+        "make-plural": "^7.0.0",
+        "safe-identifier": "^0.4.1"
+      }
+    },
+    "node_modules/@messageformat/date-skeleton": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@messageformat/date-skeleton/-/date-skeleton-1.0.1.tgz",
+      "integrity": "sha512-jPXy8fg+WMPIgmGjxSlnGJn68h/2InfT0TNSkVx0IGXgp4ynnvYkbZ51dGWmGySEK+pBiYUttbQdu5XEqX5CRg==",
+      "dev": true
+    },
+    "node_modules/@messageformat/number-skeleton": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@messageformat/number-skeleton/-/number-skeleton-1.2.0.tgz",
+      "integrity": "sha512-xsgwcL7J7WhlHJ3RNbaVgssaIwcEyFkBqxHdcdaiJzwTZAWEOD8BuUFxnxV9k5S0qHN3v/KzUpq0IUpjH1seRg==",
+      "dev": true
+    },
+    "node_modules/@messageformat/parser": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/@messageformat/parser/-/parser-5.1.0.tgz",
+      "integrity": "sha512-jKlkls3Gewgw6qMjKZ9SFfHUpdzEVdovKFtW1qRhJ3WI4FW5R/NnGDqr8SDGz+krWDO3ki94boMmQvGke1HwUQ==",
+      "dev": true,
+      "dependencies": {
+        "moo": "^0.5.1"
+      }
+    },
+    "node_modules/@messageformat/runtime": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/@messageformat/runtime/-/runtime-3.0.1.tgz",
+      "integrity": "sha512-6RU5ol2lDtO8bD9Yxe6CZkl0DArdv0qkuoZC+ZwowU+cdRlVE1157wjCmlA5Rsf1Xc/brACnsZa5PZpEDfTFFg==",
+      "dev": true,
+      "dependencies": {
+        "make-plural": "^7.0.0"
+      }
+    },
     "node_modules/@ndelangen/get-tarball": {
       "version": "3.0.9",
       "resolved": "https://registry.npmjs.org/@ndelangen/get-tarball/-/get-tarball-3.0.9.tgz",
@@ -7074,6 +6989,158 @@
         "node": ">=14"
       }
     },
+    "node_modules/@prettier/eslint": {
+      "name": "prettier-eslint",
+      "version": "16.3.0",
+      "resolved": "https://registry.npmjs.org/prettier-eslint/-/prettier-eslint-16.3.0.tgz",
+      "integrity": "sha512-Lh102TIFCr11PJKUMQ2kwNmxGhTsv/KzUg9QYF2Gkw259g/kPgndZDWavk7/ycbRvj2oz4BPZ1gCU8bhfZH/Xg==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/parser": "^6.7.5",
+        "common-tags": "^1.4.0",
+        "dlv": "^1.1.0",
+        "eslint": "^8.7.0",
+        "indent-string": "^4.0.0",
+        "lodash.merge": "^4.6.0",
+        "loglevel-colored-level-prefix": "^1.0.0",
+        "prettier": "^3.0.1",
+        "pretty-format": "^29.7.0",
+        "require-relative": "^0.8.7",
+        "typescript": "^5.2.2",
+        "vue-eslint-parser": "^9.1.0"
+      },
+      "engines": {
+        "node": ">=16.10.0"
+      },
+      "peerDependencies": {
+        "prettier-plugin-svelte": "^3.0.0",
+        "svelte-eslint-parser": "*"
+      },
+      "peerDependenciesMeta": {
+        "prettier-plugin-svelte": {
+          "optional": true
+        },
+        "svelte-eslint-parser": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@prettier/eslint/node_modules/ansi-styles": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/@prettier/eslint/node_modules/debug": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.1.2"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@prettier/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,
+      "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/@prettier/eslint/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/@prettier/eslint/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/@prettier/eslint/node_modules/ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+      "dev": true
+    },
+    "node_modules/@prettier/eslint/node_modules/pretty-format": {
+      "version": "29.7.0",
+      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
+      "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
+      "dev": true,
+      "dependencies": {
+        "@jest/schemas": "^29.6.3",
+        "ansi-styles": "^5.0.0",
+        "react-is": "^18.0.0"
+      },
+      "engines": {
+        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+      }
+    },
+    "node_modules/@prettier/eslint/node_modules/react-is": {
+      "version": "18.2.0",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+      "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+      "dev": true
+    },
+    "node_modules/@prettier/eslint/node_modules/vue-eslint-parser": {
+      "version": "9.4.2",
+      "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz",
+      "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==",
+      "dev": true,
+      "dependencies": {
+        "debug": "^4.3.4",
+        "eslint-scope": "^7.1.1",
+        "eslint-visitor-keys": "^3.3.0",
+        "espree": "^9.3.1",
+        "esquery": "^1.4.0",
+        "lodash": "^4.17.21",
+        "semver": "^7.3.6"
+      },
+      "engines": {
+        "node": "^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/mysticatea"
+      },
+      "peerDependencies": {
+        "eslint": ">=6.0.0"
+      }
+    },
     "node_modules/@rollup/rollup-android-arm-eabi": {
       "version": "4.9.6",
       "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz",
@@ -7650,6 +7717,12 @@
         "node": "^16.14.0 || >=18.0.0"
       }
     },
+    "node_modules/@sinclair/typebox": {
+      "version": "0.27.8",
+      "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
+      "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
+      "dev": true
+    },
     "node_modules/@socket.io/base64-arraybuffer": {
       "version": "1.0.2",
       "dev": true,
@@ -11174,6 +11247,21 @@
         "node": ">=10"
       }
     },
+    "node_modules/@storybook/cli/node_modules/prettier": {
+      "version": "2.8.8",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
+      "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+      "dev": true,
+      "bin": {
+        "prettier": "bin-prettier.js"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      },
+      "funding": {
+        "url": "https://github.com/prettier/prettier?sponsor=1"
+      }
+    },
     "node_modules/@storybook/cli/node_modules/ramda": {
       "version": "0.29.0",
       "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.0.tgz",
@@ -11371,6 +11459,21 @@
         "node": ">=8"
       }
     },
+    "node_modules/@storybook/codemod/node_modules/prettier": {
+      "version": "2.8.8",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
+      "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+      "dev": true,
+      "bin": {
+        "prettier": "bin-prettier.js"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      },
+      "funding": {
+        "url": "https://github.com/prettier/prettier?sponsor=1"
+      }
+    },
     "node_modules/@storybook/codemod/node_modules/shebang-command": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -16271,7 +16374,9 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
       "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "node_modules/@types/estree": {
       "version": "1.0.5",
@@ -16662,6 +16767,8 @@
       "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz",
       "integrity": "sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "@types/json-schema": "^7.0.3",
         "@typescript-eslint/typescript-estree": "1.13.0",
@@ -16679,6 +16786,8 @@
       "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
       "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "esrecurse": "^4.1.0",
         "estraverse": "^4.1.1"
@@ -16687,11 +16796,146 @@
         "node": ">=4.0.0"
       }
     },
+    "node_modules/@typescript-eslint/parser": {
+      "version": "6.21.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
+      "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/scope-manager": "6.21.0",
+        "@typescript-eslint/types": "6.21.0",
+        "@typescript-eslint/typescript-estree": "6.21.0",
+        "@typescript-eslint/visitor-keys": "6.21.0",
+        "debug": "^4.3.4"
+      },
+      "engines": {
+        "node": "^16.0.0 || >=18.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^7.0.0 || ^8.0.0"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": {
+      "version": "6.21.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
+      "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/types": "6.21.0",
+        "@typescript-eslint/visitor-keys": "6.21.0",
+        "debug": "^4.3.4",
+        "globby": "^11.1.0",
+        "is-glob": "^4.0.3",
+        "minimatch": "9.0.3",
+        "semver": "^7.5.4",
+        "ts-api-utils": "^1.0.1"
+      },
+      "engines": {
+        "node": "^16.0.0 || >=18.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/@typescript-eslint/parser/node_modules/debug": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.1.2"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/parser/node_modules/minimatch": {
+      "version": "9.0.3",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+      "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@typescript-eslint/parser/node_modules/ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+      "dev": true
+    },
+    "node_modules/@typescript-eslint/scope-manager": {
+      "version": "6.21.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
+      "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/types": "6.21.0",
+        "@typescript-eslint/visitor-keys": "6.21.0"
+      },
+      "engines": {
+        "node": "^16.0.0 || >=18.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      }
+    },
+    "node_modules/@typescript-eslint/types": {
+      "version": "6.21.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
+      "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
+      "dev": true,
+      "engines": {
+        "node": "^16.0.0 || >=18.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      }
+    },
     "node_modules/@typescript-eslint/typescript-estree": {
       "version": "1.13.0",
       "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz",
       "integrity": "sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "lodash.unescape": "4.0.1",
         "semver": "5.5.0"
@@ -16705,10 +16949,47 @@
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
       "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "bin": {
         "semver": "bin/semver"
       }
     },
+    "node_modules/@typescript-eslint/visitor-keys": {
+      "version": "6.21.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
+      "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/types": "6.21.0",
+        "eslint-visitor-keys": "^3.4.1"
+      },
+      "engines": {
+        "node": "^16.0.0 || >=18.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      }
+    },
+    "node_modules/@typescript-eslint/visitor-keys/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/@ungap/structured-clone": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
+      "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
+      "dev": true
+    },
     "node_modules/@webassemblyjs/ast": {
       "version": "1.11.6",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
@@ -17767,6 +18048,8 @@
       "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
       "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=4"
       }
@@ -19207,58 +19490,17 @@
       }
     },
     "node_modules/cliui": {
-      "version": "5.0.0",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "string-width": "^3.1.0",
-        "strip-ansi": "^5.2.0",
-        "wrap-ansi": "^5.1.0"
-      }
-    },
-    "node_modules/cliui/node_modules/ansi-regex": {
-      "version": "4.1.1",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/cliui/node_modules/emoji-regex": {
-      "version": "7.0.3",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/cliui/node_modules/is-fullwidth-code-point": {
-      "version": "2.0.0",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/cliui/node_modules/string-width": {
-      "version": "3.1.0",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "emoji-regex": "^7.0.1",
-        "is-fullwidth-code-point": "^2.0.0",
-        "strip-ansi": "^5.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/cliui/node_modules/strip-ansi": {
-      "version": "5.2.0",
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
-        "ansi-regex": "^4.1.0"
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.1",
+        "wrap-ansi": "^7.0.0"
       },
       "engines": {
-        "node": ">=6"
+        "node": ">=12"
       }
     },
     "node_modules/clone": {
@@ -19448,9 +19690,10 @@
       "dev": true
     },
     "node_modules/common-tags": {
-      "version": "1.8.0",
+      "version": "1.8.2",
+      "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
+      "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": ">=4.0.0"
       }
@@ -19905,10 +20148,11 @@
       }
     },
     "node_modules/core-js": {
-      "version": "3.20.3",
+      "version": "3.35.1",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.35.1.tgz",
+      "integrity": "sha512-IgdsbxNyMskrTFxa9lWHyMwAJU5gXOPP+1yO+K59d50VLVAIDAbs7gIv705KzALModfK3ZrSZTPNpC0PQgIZuw==",
       "dev": true,
       "hasInstallScript": true,
-      "license": "MIT",
       "funding": {
         "type": "opencollective",
         "url": "https://opencollective.com/core-js"
@@ -21632,51 +21876,49 @@
       }
     },
     "node_modules/eslint": {
-      "version": "8.21.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.21.0.tgz",
-      "integrity": "sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "@eslint/eslintrc": "^1.3.0",
-        "@humanwhocodes/config-array": "^0.10.4",
-        "@humanwhocodes/gitignore-to-minimatch": "^1.0.2",
-        "ajv": "^6.10.0",
+      "version": "8.56.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz",
+      "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==",
+      "dev": true,
+      "dependencies": {
+        "@eslint-community/eslint-utils": "^4.2.0",
+        "@eslint-community/regexpp": "^4.6.1",
+        "@eslint/eslintrc": "^2.1.4",
+        "@eslint/js": "8.56.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.1.1",
-        "eslint-utils": "^3.0.0",
-        "eslint-visitor-keys": "^3.3.0",
-        "espree": "^9.3.3",
-        "esquery": "^1.4.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",
-        "functional-red-black-tree": "^1.0.1",
-        "glob-parent": "^6.0.1",
-        "globals": "^13.15.0",
-        "globby": "^11.1.0",
-        "grapheme-splitter": "^1.0.4",
+        "glob-parent": "^6.0.2",
+        "globals": "^13.19.0",
+        "graphemer": "^1.4.0",
         "ignore": "^5.2.0",
-        "import-fresh": "^3.0.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.1",
-        "regexpp": "^3.2.0",
+        "optionator": "^0.9.3",
         "strip-ansi": "^6.0.1",
-        "strip-json-comments": "^3.1.0",
-        "text-table": "^0.2.0",
-        "v8-compile-cache": "^2.0.3"
+        "text-table": "^0.2.0"
       },
       "bin": {
         "eslint": "bin/eslint.js"
@@ -21734,39 +21976,12 @@
         "node": ">=8.0.0"
       }
     },
-    "node_modules/eslint-utils": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
-      "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "eslint-visitor-keys": "^2.0.0"
-      },
-      "engines": {
-        "node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/mysticatea"
-      },
-      "peerDependencies": {
-        "eslint": ">=5"
-      }
-    },
-    "node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-      "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
-      "dev": true,
-      "peer": true,
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/eslint-visitor-keys": {
       "version": "1.3.0",
       "dev": true,
       "license": "Apache-2.0",
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=4"
       }
@@ -21776,7 +21991,6 @@
       "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"
       },
@@ -21791,15 +22005,13 @@
       "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
+      "dev": 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"
@@ -21816,7 +22028,6 @@
       "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"
       },
@@ -21828,15 +22039,13 @@
       "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
+      "dev": true
     },
     "node_modules/eslint/node_modules/cross-spawn": {
       "version": "7.0.3",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
       "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "path-key": "^3.1.0",
         "shebang-command": "^2.0.0",
@@ -21850,7 +22059,6 @@
       "version": "4.3.2",
       "dev": true,
       "license": "MIT",
-      "peer": true,
       "dependencies": {
         "ms": "2.1.2"
       },
@@ -21868,7 +22076,6 @@
       "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"
       },
@@ -21877,27 +22084,31 @@
       }
     },
     "node_modules/eslint/node_modules/eslint-scope": {
-      "version": "7.1.1",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
-      "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
+      "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/eslint-visitor-keys": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
-      "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
+      "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,
-      "peer": true,
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
       }
     },
     "node_modules/eslint/node_modules/estraverse": {
@@ -21905,7 +22116,6 @@
       "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
       "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
       "dev": true,
-      "peer": true,
       "engines": {
         "node": ">=4.0"
       }
@@ -21915,7 +22125,6 @@
       "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"
@@ -21928,11 +22137,10 @@
       }
     },
     "node_modules/eslint/node_modules/globals": {
-      "version": "13.17.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz",
-      "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==",
+      "version": "13.24.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+      "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "type-fest": "^0.20.2"
       },
@@ -21948,7 +22156,6 @@
       "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"
       }
@@ -21958,7 +22165,6 @@
       "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"
       },
@@ -21971,7 +22177,6 @@
       "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
       "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "prelude-ls": "^1.2.1",
         "type-check": "~0.4.0"
@@ -21985,7 +22190,6 @@
       "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"
       },
@@ -21999,22 +22203,20 @@
     "node_modules/eslint/node_modules/ms": {
       "version": "2.1.2",
       "dev": true,
-      "license": "MIT",
-      "peer": true
+      "license": "MIT"
     },
     "node_modules/eslint/node_modules/optionator": {
-      "version": "0.9.1",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
-      "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+      "version": "0.9.3",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
+      "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
       "dev": true,
-      "peer": true,
       "dependencies": {
+        "@aashutoshrathi/word-wrap": "^1.2.3",
         "deep-is": "^0.1.3",
         "fast-levenshtein": "^2.0.6",
         "levn": "^0.4.1",
         "prelude-ls": "^1.2.1",
-        "type-check": "^0.4.0",
-        "word-wrap": "^1.2.3"
+        "type-check": "^0.4.0"
       },
       "engines": {
         "node": ">= 0.8.0"
@@ -22025,7 +22227,6 @@
       "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"
       },
@@ -22041,7 +22242,6 @@
       "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"
       },
@@ -22057,7 +22257,6 @@
       "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
       "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
       "dev": true,
-      "peer": true,
       "engines": {
         "node": ">=8"
       }
@@ -22067,7 +22266,6 @@
       "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
       "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
       "dev": true,
-      "peer": true,
       "engines": {
         "node": ">= 0.8.0"
       }
@@ -22077,7 +22275,6 @@
       "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
       "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "shebang-regex": "^3.0.0"
       },
@@ -22090,7 +22287,6 @@
       "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
       "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
       "dev": true,
-      "peer": true,
       "engines": {
         "node": ">=8"
       }
@@ -22100,7 +22296,6 @@
       "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"
       },
@@ -22113,7 +22308,6 @@
       "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
       "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "prelude-ls": "^1.2.1"
       },
@@ -22126,7 +22320,6 @@
       "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"
       },
@@ -22139,7 +22332,6 @@
       "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
       "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "isexe": "^2.0.0"
       },
@@ -22151,15 +22343,14 @@
       }
     },
     "node_modules/espree": {
-      "version": "9.3.3",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz",
-      "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==",
+      "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.8.0",
+        "acorn": "^8.9.0",
         "acorn-jsx": "^5.3.2",
-        "eslint-visitor-keys": "^3.3.0"
+        "eslint-visitor-keys": "^3.4.1"
       },
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -22169,13 +22360,15 @@
       }
     },
     "node_modules/espree/node_modules/eslint-visitor-keys": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
-      "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
+      "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,
-      "peer": true,
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
       }
     },
     "node_modules/esprima": {
@@ -22191,9 +22384,10 @@
       }
     },
     "node_modules/esquery": {
-      "version": "1.4.0",
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+      "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
       "dev": true,
-      "license": "BSD-3-Clause",
       "dependencies": {
         "estraverse": "^5.1.0"
       },
@@ -22870,7 +23064,6 @@
       "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
       "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "flat-cache": "^3.0.4"
       },
@@ -23050,7 +23243,6 @@
       "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
       "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
       "dev": true,
-      "peer": true,
       "dependencies": {
         "flatted": "^3.1.0",
         "rimraf": "^3.0.2"
@@ -23617,7 +23809,9 @@
     "node_modules/functional-red-black-tree": {
       "version": "1.0.1",
       "dev": true,
-      "license": "MIT"
+      "license": "MIT",
+      "optional": true,
+      "peer": true
     },
     "node_modules/functions-have-names": {
       "version": "1.2.3",
@@ -23927,12 +24121,11 @@
       "dev": true,
       "license": "ISC"
     },
-    "node_modules/grapheme-splitter": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
-      "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
-      "dev": true,
-      "peer": true
+    "node_modules/graphemer": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+      "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+      "dev": true
     },
     "node_modules/gunzip-maybe": {
       "version": "1.4.2",
@@ -24813,9 +25006,10 @@
       "license": "MIT"
     },
     "node_modules/ignore": {
-      "version": "5.2.0",
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
+      "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": ">= 4"
       }
@@ -26695,20 +26889,6 @@
         "source-map-support": "^0.5.5"
       }
     },
-    "node_modules/karma/node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
     "node_modules/karma/node_modules/cliui": {
       "version": "7.0.4",
       "dev": true,
@@ -26719,22 +26899,6 @@
         "wrap-ansi": "^7.0.0"
       }
     },
-    "node_modules/karma/node_modules/color-convert": {
-      "version": "2.0.1",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/karma/node_modules/color-name": {
-      "version": "1.1.4",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/karma/node_modules/mime": {
       "version": "2.6.0",
       "dev": true,
@@ -26776,22 +26940,6 @@
         "node": ">=8.17.0"
       }
     },
-    "node_modules/karma/node_modules/wrap-ansi": {
-      "version": "7.0.0",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
-      }
-    },
     "node_modules/karma/node_modules/y18n": {
       "version": "5.0.8",
       "dev": true,
@@ -27139,7 +27287,9 @@
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz",
       "integrity": "sha512-DhhGRshNS1aX6s5YdBE3njCCouPgnG29ebyHvImlZzXZf2SHgt+J08DHgytTPnpywNbO1Y8mNUFyQuIDBq2JZg==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "node_modules/lodash.uniq": {
       "version": "4.5.0",
@@ -27456,15 +27606,10 @@
       }
     },
     "node_modules/make-plural": {
-      "version": "4.3.0",
-      "dev": true,
-      "license": "ISC",
-      "bin": {
-        "make-plural": "bin/make-plural"
-      },
-      "optionalDependencies": {
-        "minimist": "^1.2.0"
-      }
+      "version": "7.3.0",
+      "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.3.0.tgz",
+      "integrity": "sha512-/K3BC0KIsO+WK2i94LkMPv3wslMrazrQhfi5We9fMbLlLjzoOSJWr7TAdupLlDWaJcWxwoNosBkhFDejiu5VDw==",
+      "dev": true
     },
     "node_modules/makeerror": {
       "version": "1.0.12",
@@ -27843,26 +27988,6 @@
         "node": ">= 8"
       }
     },
-    "node_modules/messageformat": {
-      "version": "2.3.0",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "make-plural": "^4.3.0",
-        "messageformat-formatters": "^2.0.1",
-        "messageformat-parser": "^4.1.2"
-      }
-    },
-    "node_modules/messageformat-formatters": {
-      "version": "2.0.1",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/messageformat-parser": {
-      "version": "4.1.3",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/methods": {
       "version": "1.1.2",
       "dev": true,
@@ -28243,6 +28368,12 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/moo": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz",
+      "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==",
+      "dev": true
+    },
     "node_modules/morgan": {
       "version": "1.10.0",
       "dev": true,
@@ -32950,15 +33081,15 @@
       }
     },
     "node_modules/prettier": {
-      "version": "2.8.8",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
-      "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+      "version": "3.2.5",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
+      "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
       "dev": true,
       "bin": {
-        "prettier": "bin-prettier.js"
+        "prettier": "bin/prettier.cjs"
       },
       "engines": {
-        "node": ">=10.13.0"
+        "node": ">=14"
       },
       "funding": {
         "url": "https://github.com/prettier/prettier?sponsor=1"
@@ -32968,6 +33099,8 @@
       "version": "9.0.2",
       "dev": true,
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "@typescript-eslint/parser": "^1.10.2",
         "common-tags": "^1.4.0",
@@ -32988,63 +33121,58 @@
       }
     },
     "node_modules/prettier-eslint-cli": {
-      "version": "5.0.1",
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/prettier-eslint-cli/-/prettier-eslint-cli-8.0.1.tgz",
+      "integrity": "sha512-jru4JUDHzWEtM/SOxqagU7hQTVP8BVrxO2J0qNauWZuPRld6Ea2eyNaEzIGx6I+yjmOLCsjNM+vU1AJgaW1ZSQ==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
+        "@messageformat/core": "^3.2.0",
+        "@prettier/eslint": "npm:prettier-eslint@^16.1.0",
         "arrify": "^2.0.1",
-        "boolify": "^1.0.0",
-        "camelcase-keys": "^6.0.0",
-        "chalk": "^2.4.2",
-        "common-tags": "^1.8.0",
-        "core-js": "^3.1.4",
-        "eslint": "^5.0.0",
-        "find-up": "^4.1.0",
-        "get-stdin": "^7.0.0",
-        "glob": "^7.1.4",
-        "ignore": "^5.1.2",
+        "boolify": "^1.0.1",
+        "camelcase-keys": "^9.1.0",
+        "chalk": "^4.1.2",
+        "common-tags": "^1.8.2",
+        "core-js": "^3.33.0",
+        "eslint": "^8.51.0",
+        "find-up": "^5.0.0",
+        "get-stdin": "^8.0.0",
+        "glob": "^10.3.10",
+        "ignore": "^5.2.4",
+        "indent-string": "^4.0.0",
         "lodash.memoize": "^4.1.2",
         "loglevel-colored-level-prefix": "^1.0.0",
-        "messageformat": "^2.2.1",
-        "prettier-eslint": "^9.0.0",
-        "rxjs": "^6.5.2",
-        "yargs": "^13.2.4"
+        "rxjs": "^7.8.1",
+        "yargs": "^17.7.2"
       },
       "bin": {
         "prettier-eslint": "dist/index.js"
       },
       "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/prettier-eslint-cli/node_modules/acorn": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
-      "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
-      "dev": true,
-      "bin": {
-        "acorn": "bin/acorn"
+        "node": ">=16.10.0"
       },
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
-    "node_modules/prettier-eslint-cli/node_modules/ansi-escapes": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
-      "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
+      "peerDependencies": {
+        "prettier-eslint": "*"
+      },
+      "peerDependenciesMeta": {
+        "prettier-eslint": {
+          "optional": true
+        }
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/ansi-regex": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
-      "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
+    "node_modules/prettier-eslint-cli/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": ">=4"
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
     "node_modules/prettier-eslint-cli/node_modules/arrify": {
@@ -33055,365 +33183,262 @@
         "node": ">=8"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/cli-cursor": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
-      "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==",
+    "node_modules/prettier-eslint-cli/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
       "dev": true,
       "dependencies": {
-        "restore-cursor": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=4"
+        "balanced-match": "^1.0.0"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/cli-width": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
-      "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==",
-      "dev": true
-    },
-    "node_modules/prettier-eslint-cli/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/prettier-eslint-cli/node_modules/camelcase": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz",
+      "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==",
       "dev": true,
-      "dependencies": {
-        "ms": "2.1.2"
-      },
       "engines": {
-        "node": ">=6.0"
+        "node": ">=16"
       },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/eslint": {
-      "version": "5.16.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz",
-      "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==",
+    "node_modules/prettier-eslint-cli/node_modules/camelcase-keys": {
+      "version": "9.1.3",
+      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-9.1.3.tgz",
+      "integrity": "sha512-Rircqi9ch8AnZscQcsA1C47NFdaO3wukpmIRzYcDOrmvgt78hM/sj5pZhZNec2NM12uk5vTwRHZ4anGcrC4ZTg==",
       "dev": true,
       "dependencies": {
-        "@babel/code-frame": "^7.0.0",
-        "ajv": "^6.9.1",
-        "chalk": "^2.1.0",
-        "cross-spawn": "^6.0.5",
-        "debug": "^4.0.1",
-        "doctrine": "^3.0.0",
-        "eslint-scope": "^4.0.3",
-        "eslint-utils": "^1.3.1",
-        "eslint-visitor-keys": "^1.0.0",
-        "espree": "^5.0.1",
-        "esquery": "^1.0.1",
-        "esutils": "^2.0.2",
-        "file-entry-cache": "^5.0.1",
-        "functional-red-black-tree": "^1.0.1",
-        "glob": "^7.1.2",
-        "globals": "^11.7.0",
-        "ignore": "^4.0.6",
-        "import-fresh": "^3.0.0",
-        "imurmurhash": "^0.1.4",
-        "inquirer": "^6.2.2",
-        "js-yaml": "^3.13.0",
-        "json-stable-stringify-without-jsonify": "^1.0.1",
-        "levn": "^0.3.0",
-        "lodash": "^4.17.11",
-        "minimatch": "^3.0.4",
-        "mkdirp": "^0.5.1",
-        "natural-compare": "^1.4.0",
-        "optionator": "^0.8.2",
-        "path-is-inside": "^1.0.2",
-        "progress": "^2.0.0",
-        "regexpp": "^2.0.1",
-        "semver": "^5.5.1",
-        "strip-ansi": "^4.0.0",
-        "strip-json-comments": "^2.0.1",
-        "table": "^5.2.3",
-        "text-table": "^0.2.0"
-      },
-      "bin": {
-        "eslint": "bin/eslint.js"
+        "camelcase": "^8.0.0",
+        "map-obj": "5.0.0",
+        "quick-lru": "^6.1.1",
+        "type-fest": "^4.3.2"
       },
       "engines": {
-        "node": "^6.14.0 || ^8.10.0 || >=9.10.0"
-      }
-    },
-    "node_modules/prettier-eslint-cli/node_modules/eslint-scope": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
-      "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
-      "dev": true,
-      "dependencies": {
-        "esrecurse": "^4.1.0",
-        "estraverse": "^4.1.1"
+        "node": ">=16"
       },
-      "engines": {
-        "node": ">=4.0.0"
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/eslint-utils": {
-      "version": "1.4.3",
-      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
-      "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
+    "node_modules/prettier-eslint-cli/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": {
-        "eslint-visitor-keys": "^1.1.0"
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
       },
       "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/prettier-eslint-cli/node_modules/eslint/node_modules/ignore": {
-      "version": "4.0.6",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
-      "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 4"
-      }
-    },
-    "node_modules/prettier-eslint-cli/node_modules/espree": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz",
-      "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==",
-      "dev": true,
-      "dependencies": {
-        "acorn": "^6.0.7",
-        "acorn-jsx": "^5.0.0",
-        "eslint-visitor-keys": "^1.0.0"
+        "node": ">=10"
       },
-      "engines": {
-        "node": ">=6.0.0"
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/figures": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
-      "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==",
+    "node_modules/prettier-eslint-cli/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": {
-        "escape-string-regexp": "^1.0.5"
+        "color-name": "~1.1.4"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=7.0.0"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/file-entry-cache": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
-      "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
-      "dev": true,
-      "dependencies": {
-        "flat-cache": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=4"
-      }
+    "node_modules/prettier-eslint-cli/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/prettier-eslint-cli/node_modules/flat-cache": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
-      "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
+    "node_modules/prettier-eslint-cli/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,
       "dependencies": {
-        "flatted": "^2.0.0",
-        "rimraf": "2.6.3",
-        "write": "1.0.3"
+        "locate-path": "^6.0.0",
+        "path-exists": "^4.0.0"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/flatted": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
-      "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
-      "dev": true
-    },
     "node_modules/prettier-eslint-cli/node_modules/get-stdin": {
-      "version": "7.0.0",
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz",
+      "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==",
       "dev": true,
-      "license": "MIT",
       "engines": {
-        "node": ">=8"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/inquirer": {
-      "version": "6.5.2",
-      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz",
-      "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==",
+    "node_modules/prettier-eslint-cli/node_modules/glob": {
+      "version": "10.3.10",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
+      "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==",
       "dev": true,
       "dependencies": {
-        "ansi-escapes": "^3.2.0",
-        "chalk": "^2.4.2",
-        "cli-cursor": "^2.1.0",
-        "cli-width": "^2.0.0",
-        "external-editor": "^3.0.3",
-        "figures": "^2.0.0",
-        "lodash": "^4.17.12",
-        "mute-stream": "0.0.7",
-        "run-async": "^2.2.0",
-        "rxjs": "^6.4.0",
-        "string-width": "^2.1.0",
-        "strip-ansi": "^5.1.0",
-        "through": "^2.3.6"
+        "foreground-child": "^3.1.0",
+        "jackspeak": "^2.3.5",
+        "minimatch": "^9.0.1",
+        "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
+        "path-scurry": "^1.10.1"
+      },
+      "bin": {
+        "glob": "dist/esm/bin.mjs"
       },
       "engines": {
-        "node": ">=6.0.0"
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/inquirer/node_modules/ansi-regex": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
-      "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
+    "node_modules/prettier-eslint-cli/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": ">=6"
+        "node": ">=8"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/inquirer/node_modules/strip-ansi": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
-      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+    "node_modules/prettier-eslint-cli/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,
       "dependencies": {
-        "ansi-regex": "^4.1.0"
+        "p-locate": "^5.0.0"
       },
       "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/prettier-eslint-cli/node_modules/is-fullwidth-code-point": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
-      "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/mimic-fn": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
-      "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+    "node_modules/prettier-eslint-cli/node_modules/map-obj": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-5.0.0.tgz",
+      "integrity": "sha512-2L3MIgJynYrZ3TYMriLDLWocz15okFakV6J12HXvMXDHui2x/zgChzg1u9mFFGbbGWE+GsLpQByt4POb9Or+uA==",
       "dev": true,
       "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/prettier-eslint-cli/node_modules/mkdirp": {
-      "version": "0.5.6",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
-      "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
-      "dev": true,
-      "dependencies": {
-        "minimist": "^1.2.6"
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
       },
-      "bin": {
-        "mkdirp": "bin/cmd.js"
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/ms": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-      "dev": true
-    },
-    "node_modules/prettier-eslint-cli/node_modules/mute-stream": {
-      "version": "0.0.7",
-      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
-      "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==",
-      "dev": true
-    },
-    "node_modules/prettier-eslint-cli/node_modules/onetime": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
-      "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==",
+    "node_modules/prettier-eslint-cli/node_modules/minimatch": {
+      "version": "9.0.3",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+      "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
       "dev": true,
       "dependencies": {
-        "mimic-fn": "^1.0.0"
+        "brace-expansion": "^2.0.1"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/regexpp": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
-      "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
+    "node_modules/prettier-eslint-cli/node_modules/minipass": {
+      "version": "7.0.4",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
+      "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
       "dev": true,
       "engines": {
-        "node": ">=6.5.0"
+        "node": ">=16 || 14 >=14.17"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/restore-cursor": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
-      "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==",
+    "node_modules/prettier-eslint-cli/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,
       "dependencies": {
-        "onetime": "^2.0.0",
-        "signal-exit": "^3.0.2"
+        "yocto-queue": "^0.1.0"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/rimraf": {
-      "version": "2.6.3",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
-      "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+    "node_modules/prettier-eslint-cli/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,
       "dependencies": {
-        "glob": "^7.1.3"
+        "p-limit": "^3.0.2"
       },
-      "bin": {
-        "rimraf": "bin.js"
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/semver": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+    "node_modules/prettier-eslint-cli/node_modules/quick-lru": {
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-6.1.2.tgz",
+      "integrity": "sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==",
       "dev": true,
-      "bin": {
-        "semver": "bin/semver"
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/string-width": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
-      "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+    "node_modules/prettier-eslint-cli/node_modules/rxjs": {
+      "version": "7.8.1",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
+      "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
       "dev": true,
       "dependencies": {
-        "is-fullwidth-code-point": "^2.0.0",
-        "strip-ansi": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=4"
+        "tslib": "^2.1.0"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/strip-ansi": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
-      "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
+    "node_modules/prettier-eslint-cli/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": {
-        "ansi-regex": "^3.0.0"
+        "has-flag": "^4.0.0"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
-    "node_modules/prettier-eslint-cli/node_modules/strip-json-comments": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
-      "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+    "node_modules/prettier-eslint-cli/node_modules/type-fest": {
+      "version": "4.10.2",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.10.2.tgz",
+      "integrity": "sha512-anpAG63wSpdEbLwOqH8L84urkL6PiVIov3EMmgIhhThevh9aiMQov+6Btx0wldNcvm4wV+e2/Rt1QdDwKHFbHw==",
       "dev": true,
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">=16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/prettier-eslint/node_modules/@typescript-eslint/parser": {
@@ -33421,6 +33446,8 @@
       "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.13.0.tgz",
       "integrity": "sha512-ITMBs52PCPgLb2nGPoeT4iU3HdQZHcPaZVw+7CsFagRJHUhyeTgorEwHXhFf3e7Evzi8oujKNpHc8TONth8AdQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "@types/eslint-visitor-keys": "^1.0.0",
         "@typescript-eslint/experimental-utils": "1.13.0",
@@ -33439,6 +33466,8 @@
       "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
       "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "bin": {
         "acorn": "bin/acorn"
       },
@@ -33451,6 +33480,8 @@
       "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
       "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=4"
       }
@@ -33460,6 +33491,8 @@
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
       "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=4"
       }
@@ -33469,6 +33502,8 @@
       "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
       "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "restore-cursor": "^2.0.0"
       },
@@ -33480,13 +33515,17 @@
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
       "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "node_modules/prettier-eslint/node_modules/debug": {
       "version": "4.3.4",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
       "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "ms": "2.1.2"
       },
@@ -33504,6 +33543,8 @@
       "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz",
       "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "@babel/code-frame": "^7.0.0",
         "ajv": "^6.9.1",
@@ -33554,6 +33595,8 @@
       "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
       "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "esrecurse": "^4.1.0",
         "estraverse": "^4.1.1"
@@ -33567,6 +33610,8 @@
       "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
       "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "eslint-visitor-keys": "^1.1.0"
       },
@@ -33579,6 +33624,8 @@
       "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz",
       "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "acorn": "^6.0.7",
         "acorn-jsx": "^5.0.0",
@@ -33593,6 +33640,8 @@
       "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
       "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "escape-string-regexp": "^1.0.5"
       },
@@ -33605,6 +33654,8 @@
       "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
       "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "flat-cache": "^2.0.1"
       },
@@ -33617,6 +33668,8 @@
       "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
       "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "flatted": "^2.0.0",
         "rimraf": "2.6.3",
@@ -33630,13 +33683,17 @@
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
       "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "node_modules/prettier-eslint/node_modules/ignore": {
       "version": "4.0.6",
       "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
       "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">= 4"
       }
@@ -33646,6 +33703,8 @@
       "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz",
       "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "ansi-escapes": "^3.2.0",
         "chalk": "^2.4.2",
@@ -33670,6 +33729,8 @@
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
       "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=6"
       }
@@ -33679,6 +33740,8 @@
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
       "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "ansi-regex": "^4.1.0"
       },
@@ -33691,6 +33754,8 @@
       "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
       "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=4"
       }
@@ -33700,6 +33765,8 @@
       "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
       "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=4"
       }
@@ -33709,6 +33776,8 @@
       "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
       "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "minimist": "^1.2.6"
       },
@@ -33720,19 +33789,25 @@
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
       "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "node_modules/prettier-eslint/node_modules/mute-stream": {
       "version": "0.0.7",
       "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
       "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "node_modules/prettier-eslint/node_modules/onetime": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
       "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "mimic-fn": "^1.0.0"
       },
@@ -33744,6 +33819,8 @@
       "version": "1.19.1",
       "dev": true,
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "bin": {
         "prettier": "bin-prettier.js"
       },
@@ -33756,6 +33833,8 @@
       "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
       "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=6.5.0"
       }
@@ -33765,6 +33844,8 @@
       "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
       "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "onetime": "^2.0.0",
         "signal-exit": "^3.0.2"
@@ -33778,6 +33859,8 @@
       "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
       "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "glob": "^7.1.3"
       },
@@ -33790,6 +33873,8 @@
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
       "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "bin": {
         "semver": "bin/semver"
       }
@@ -33799,6 +33884,8 @@
       "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
       "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "is-fullwidth-code-point": "^2.0.0",
         "strip-ansi": "^4.0.0"
@@ -33812,6 +33899,8 @@
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
       "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "ansi-regex": "^3.0.0"
       },
@@ -33824,6 +33913,8 @@
       "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
       "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=0.10.0"
       }
@@ -33832,6 +33923,8 @@
       "version": "3.9.10",
       "dev": true,
       "license": "Apache-2.0",
+      "optional": true,
+      "peer": true,
       "bin": {
         "tsc": "bin/tsc",
         "tsserver": "bin/tsserver"
@@ -33852,12 +33945,23 @@
       }
     },
     "node_modules/prettier-plugin-organize-imports": {
-      "version": "1.1.1",
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.2.4.tgz",
+      "integrity": "sha512-6m8WBhIp0dfwu0SkgfOxJqh+HpdyfqSSLfKKRZSFbDuEQXDDndb8fTpRWkUrX/uBenkex3MgnVk0J3b3Y5byog==",
       "dev": true,
-      "license": "MIT",
       "peerDependencies": {
-        "prettier": ">=1.10",
-        "typescript": ">=2.8.2"
+        "@volar/vue-language-plugin-pug": "^1.0.4",
+        "@volar/vue-typescript": "^1.0.4",
+        "prettier": ">=2.0",
+        "typescript": ">=2.9"
+      },
+      "peerDependenciesMeta": {
+        "@volar/vue-language-plugin-pug": {
+          "optional": true
+        },
+        "@volar/vue-typescript": {
+          "optional": true
+        }
       }
     },
     "node_modules/pretty-bytes": {
@@ -33886,6 +33990,8 @@
       "version": "23.6.0",
       "dev": true,
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "ansi-regex": "^3.0.0",
         "ansi-styles": "^3.2.0"
@@ -33895,6 +34001,8 @@
       "version": "3.0.1",
       "dev": true,
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=4"
       }
@@ -35170,19 +35278,6 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/regexpp": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
-      "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
-      "dev": true,
-      "peer": true,
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/mysticatea"
-      }
-    },
     "node_modules/regexpu-core": {
       "version": "5.3.2",
       "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz",
@@ -35700,6 +35795,8 @@
       "version": "2.4.1",
       "dev": true,
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=0.12.0"
       }
@@ -35753,6 +35850,12 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/safe-identifier": {
+      "version": "0.4.2",
+      "resolved": "https://registry.npmjs.org/safe-identifier/-/safe-identifier-0.4.2.tgz",
+      "integrity": "sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w==",
+      "dev": true
+    },
     "node_modules/safe-regex": {
       "version": "1.1.0",
       "dev": true,
@@ -36217,20 +36320,6 @@
         "node": ">=14.17"
       }
     },
-    "node_modules/semantic-release/node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
     "node_modules/semantic-release/node_modules/cliui": {
       "version": "7.0.4",
       "dev": true,
@@ -36241,22 +36330,6 @@
         "wrap-ansi": "^7.0.0"
       }
     },
-    "node_modules/semantic-release/node_modules/color-convert": {
-      "version": "2.0.1",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/semantic-release/node_modules/color-name": {
-      "version": "1.1.4",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/semantic-release/node_modules/debug": {
       "version": "4.3.4",
       "dev": true,
@@ -36286,22 +36359,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/semantic-release/node_modules/wrap-ansi": {
-      "version": "7.0.0",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
-      }
-    },
     "node_modules/semantic-release/node_modules/y18n": {
       "version": "5.0.8",
       "dev": true,
@@ -36736,6 +36793,8 @@
       "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
       "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "ansi-styles": "^3.2.0",
         "astral-regex": "^1.0.0",
@@ -36750,6 +36809,8 @@
       "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
       "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=4"
       }
@@ -37969,6 +38030,8 @@
       "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
       "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "ajv": "^6.10.2",
         "lodash": "^4.17.14",
@@ -37984,6 +38047,8 @@
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
       "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=6"
       }
@@ -37992,13 +38057,17 @@
       "version": "7.0.3",
       "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
       "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "node_modules/table/node_modules/is-fullwidth-code-point": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
       "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=4"
       }
@@ -38008,6 +38077,8 @@
       "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
       "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "emoji-regex": "^7.0.1",
         "is-fullwidth-code-point": "^2.0.0",
@@ -38022,6 +38093,8 @@
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
       "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "ansi-regex": "^4.1.0"
       },
@@ -38504,6 +38577,18 @@
         "url": "https://github.com/sponsors/wooorm"
       }
     },
+    "node_modules/ts-api-utils": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz",
+      "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==",
+      "dev": true,
+      "engines": {
+        "node": ">=16"
+      },
+      "peerDependencies": {
+        "typescript": ">=4.2.0"
+      }
+    },
     "node_modules/ts-dedent": {
       "version": "2.2.0",
       "dev": true,
@@ -39388,13 +39473,6 @@
       "dev": true,
       "license": "MIT"
     },
-    "node_modules/v8-compile-cache": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
-      "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
-      "dev": true,
-      "peer": true
-    },
     "node_modules/v8-compile-cache-lib": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
@@ -39519,6 +39597,8 @@
       "version": "2.0.3",
       "dev": true,
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "debug": "^3.1.0",
         "eslint-scope": "^3.7.1",
@@ -39538,6 +39618,8 @@
       "version": "5.7.4",
       "dev": true,
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "bin": {
         "acorn": "bin/acorn"
       },
@@ -39549,6 +39631,8 @@
       "version": "3.0.1",
       "dev": true,
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "acorn": "^3.0.4"
       }
@@ -39557,6 +39641,8 @@
       "version": "3.3.0",
       "dev": true,
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "bin": {
         "acorn": "bin/acorn"
       },
@@ -39568,6 +39654,8 @@
       "version": "3.7.3",
       "dev": true,
       "license": "BSD-2-Clause",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "esrecurse": "^4.1.0",
         "estraverse": "^4.1.1"
@@ -39580,6 +39668,8 @@
       "version": "3.5.4",
       "dev": true,
       "license": "BSD-2-Clause",
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "acorn": "^5.5.0",
         "acorn-jsx": "^3.0.0"
@@ -40232,16 +40322,20 @@
       }
     },
     "node_modules/wrap-ansi": {
-      "version": "5.1.0",
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
-        "ansi-styles": "^3.2.0",
-        "string-width": "^3.0.0",
-        "strip-ansi": "^5.0.0"
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
       },
       "engines": {
-        "node": ">=6"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
       }
     },
     "node_modules/wrap-ansi-cjs": {
@@ -40295,51 +40389,39 @@
       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
       "dev": true
     },
-    "node_modules/wrap-ansi/node_modules/ansi-regex": {
-      "version": "4.1.1",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/wrap-ansi/node_modules/emoji-regex": {
-      "version": "7.0.3",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": {
-      "version": "2.0.0",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/wrap-ansi/node_modules/string-width": {
-      "version": "3.1.0",
+    "node_modules/wrap-ansi/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,
-      "license": "MIT",
       "dependencies": {
-        "emoji-regex": "^7.0.1",
-        "is-fullwidth-code-point": "^2.0.0",
-        "strip-ansi": "^5.1.0"
+        "color-convert": "^2.0.1"
       },
       "engines": {
-        "node": ">=6"
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
-    "node_modules/wrap-ansi/node_modules/strip-ansi": {
-      "version": "5.2.0",
+    "node_modules/wrap-ansi/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,
-      "license": "MIT",
       "dependencies": {
-        "ansi-regex": "^4.1.0"
+        "color-name": "~1.1.4"
       },
       "engines": {
-        "node": ">=6"
+        "node": ">=7.0.0"
       }
     },
+    "node_modules/wrap-ansi/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/wrappy": {
       "version": "1.0.2",
       "dev": true,
@@ -40350,6 +40432,8 @@
       "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
       "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "mkdirp": "^0.5.1"
       },
@@ -40373,6 +40457,8 @@
       "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
       "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "minimist": "^1.2.6"
       },
@@ -40456,116 +40542,39 @@
       }
     },
     "node_modules/yargs": {
-      "version": "13.3.2",
+      "version": "17.7.2",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+      "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
-        "cliui": "^5.0.0",
-        "find-up": "^3.0.0",
-        "get-caller-file": "^2.0.1",
+        "cliui": "^8.0.1",
+        "escalade": "^3.1.1",
+        "get-caller-file": "^2.0.5",
         "require-directory": "^2.1.1",
-        "require-main-filename": "^2.0.0",
-        "set-blocking": "^2.0.0",
-        "string-width": "^3.0.0",
-        "which-module": "^2.0.0",
-        "y18n": "^4.0.0",
-        "yargs-parser": "^13.1.2"
-      }
-    },
-    "node_modules/yargs-parser": {
-      "version": "13.1.2",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "camelcase": "^5.0.0",
-        "decamelize": "^1.2.0"
-      }
-    },
-    "node_modules/yargs/node_modules/ansi-regex": {
-      "version": "4.1.1",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/yargs/node_modules/emoji-regex": {
-      "version": "7.0.3",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/yargs/node_modules/find-up": {
-      "version": "3.0.0",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "locate-path": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/yargs/node_modules/is-fullwidth-code-point": {
-      "version": "2.0.0",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/yargs/node_modules/locate-path": {
-      "version": "3.0.0",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "p-locate": "^3.0.0",
-        "path-exists": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/yargs/node_modules/p-locate": {
-      "version": "3.0.0",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "p-limit": "^2.0.0"
+        "string-width": "^4.2.3",
+        "y18n": "^5.0.5",
+        "yargs-parser": "^21.1.1"
       },
       "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/yargs/node_modules/path-exists": {
-      "version": "3.0.0",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=4"
+        "node": ">=12"
       }
     },
-    "node_modules/yargs/node_modules/string-width": {
-      "version": "3.1.0",
+    "node_modules/yargs-parser": {
+      "version": "21.1.1",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
       "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "emoji-regex": "^7.0.1",
-        "is-fullwidth-code-point": "^2.0.0",
-        "strip-ansi": "^5.1.0"
-      },
       "engines": {
-        "node": ">=6"
+        "node": ">=12"
       }
     },
-    "node_modules/yargs/node_modules/strip-ansi": {
-      "version": "5.2.0",
+    "node_modules/yargs/node_modules/y18n": {
+      "version": "5.0.8",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+      "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
       "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-regex": "^4.1.0"
-      },
       "engines": {
-        "node": ">=6"
+        "node": ">=10"
       }
     },
     "node_modules/yauzl": {
@@ -40616,6 +40625,12 @@
     }
   },
   "dependencies": {
+    "@aashutoshrathi/word-wrap": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
+      "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
+      "dev": true
+    },
     "@aduh95/viz.js": {
       "version": "3.5.0",
       "dev": true
@@ -41438,41 +41453,6 @@
             "rxjs": "7.8.1"
           }
         },
-        "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,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "cliui": {
-          "version": "8.0.1",
-          "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
-          "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
-          "dev": true,
-          "requires": {
-            "string-width": "^4.2.0",
-            "strip-ansi": "^6.0.1",
-            "wrap-ansi": "^7.0.0"
-          }
-        },
-        "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,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "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
-        },
         "jsonc-parser": {
           "version": "3.2.0",
           "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
@@ -41516,44 +41496,6 @@
           "requires": {
             "lru-cache": "^6.0.0"
           }
-        },
-        "wrap-ansi": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
-          "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.0.0",
-            "string-width": "^4.1.0",
-            "strip-ansi": "^6.0.0"
-          }
-        },
-        "y18n": {
-          "version": "5.0.8",
-          "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
-          "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
-          "dev": true
-        },
-        "yargs": {
-          "version": "17.7.2",
-          "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
-          "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
-          "dev": true,
-          "requires": {
-            "cliui": "^8.0.1",
-            "escalade": "^3.1.1",
-            "get-caller-file": "^2.0.5",
-            "require-directory": "^2.1.1",
-            "string-width": "^4.2.3",
-            "y18n": "^5.0.5",
-            "yargs-parser": "^21.1.1"
-          }
-        },
-        "yargs-parser": {
-          "version": "21.1.1",
-          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
-          "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
-          "dev": true
         }
       }
     },
@@ -41626,33 +41568,6 @@
             }
           }
         },
-        "ansi-styles": {
-          "version": "4.3.0",
-          "dev": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "cliui": {
-          "version": "7.0.4",
-          "dev": true,
-          "requires": {
-            "string-width": "^4.2.0",
-            "strip-ansi": "^6.0.0",
-            "wrap-ansi": "^7.0.0"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "dev": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "dev": true
-        },
         "debug": {
           "version": "4.3.4",
           "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -41667,36 +41582,6 @@
           "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
           "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
           "dev": true
-        },
-        "wrap-ansi": {
-          "version": "7.0.0",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.0.0",
-            "string-width": "^4.1.0",
-            "strip-ansi": "^6.0.0"
-          }
-        },
-        "y18n": {
-          "version": "5.0.8",
-          "dev": true
-        },
-        "yargs": {
-          "version": "17.5.1",
-          "dev": true,
-          "requires": {
-            "cliui": "^7.0.2",
-            "escalade": "^3.1.1",
-            "get-caller-file": "^2.0.5",
-            "require-directory": "^2.1.1",
-            "string-width": "^4.2.3",
-            "y18n": "^5.0.5",
-            "yargs-parser": "^21.0.0"
-          }
-        },
-        "yargs-parser": {
-          "version": "21.1.1",
-          "dev": true
         }
       }
     },
@@ -43803,17 +43688,39 @@
       "dev": true,
       "optional": true
     },
+    "@eslint-community/eslint-utils": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+      "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+      "dev": true,
+      "requires": {
+        "eslint-visitor-keys": "^3.3.0"
+      },
+      "dependencies": {
+        "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
+        }
+      }
+    },
+    "@eslint-community/regexpp": {
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
+      "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
+      "dev": true
+    },
     "@eslint/eslintrc": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz",
-      "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==",
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+      "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
       "dev": true,
-      "peer": true,
       "requires": {
         "ajv": "^6.12.4",
         "debug": "^4.3.2",
-        "espree": "^9.3.2",
-        "globals": "^13.15.0",
+        "espree": "^9.6.0",
+        "globals": "^13.19.0",
         "ignore": "^5.2.0",
         "import-fresh": "^3.2.1",
         "js-yaml": "^4.1.0",
@@ -43825,25 +43732,22 @@
           "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
+          "dev": true
         },
         "debug": {
           "version": "4.3.4",
           "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
           "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
           "dev": true,
-          "peer": true,
           "requires": {
             "ms": "2.1.2"
           }
         },
         "globals": {
-          "version": "13.17.0",
-          "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz",
-          "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==",
+          "version": "13.24.0",
+          "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+          "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
           "dev": true,
-          "peer": true,
           "requires": {
             "type-fest": "^0.20.2"
           }
@@ -43853,7 +43757,6 @@
           "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
           "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
           "dev": true,
-          "peer": true,
           "requires": {
             "argparse": "^2.0.1"
           }
@@ -43862,18 +43765,22 @@
           "version": "2.1.2",
           "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
           "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-          "dev": true,
-          "peer": true
+          "dev": true
         },
         "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
+          "dev": true
         }
       }
     },
+    "@eslint/js": {
+      "version": "8.56.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz",
+      "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==",
+      "dev": true
+    },
     "@fal-works/esbuild-plugin-global-externals": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/@fal-works/esbuild-plugin-global-externals/-/esbuild-plugin-global-externals-2.1.2.tgz",
@@ -43932,15 +43839,14 @@
       "dev": true
     },
     "@humanwhocodes/config-array": {
-      "version": "0.10.4",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz",
-      "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==",
+      "version": "0.11.14",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
+      "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
       "dev": true,
-      "peer": true,
       "requires": {
-        "@humanwhocodes/object-schema": "^1.2.1",
-        "debug": "^4.1.1",
-        "minimatch": "^3.0.4"
+        "@humanwhocodes/object-schema": "^2.0.2",
+        "debug": "^4.3.1",
+        "minimatch": "^3.0.5"
       },
       "dependencies": {
         "debug": {
@@ -43948,7 +43854,6 @@
           "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
           "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
           "dev": true,
-          "peer": true,
           "requires": {
             "ms": "2.1.2"
           }
@@ -43957,24 +43862,21 @@
           "version": "2.1.2",
           "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
           "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-          "dev": true,
-          "peer": true
+          "dev": true
         }
       }
     },
-    "@humanwhocodes/gitignore-to-minimatch": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz",
-      "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==",
-      "dev": true,
-      "peer": true
+    "@humanwhocodes/module-importer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+      "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+      "dev": true
     },
     "@humanwhocodes/object-schema": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
-      "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
-      "dev": true,
-      "peer": true
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz",
+      "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==",
+      "dev": true
     },
     "@isaacs/cliui": {
       "version": "8.0.2",
@@ -44062,6 +43964,15 @@
       "version": "0.1.3",
       "dev": true
     },
+    "@jest/schemas": {
+      "version": "29.6.3",
+      "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
+      "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
+      "dev": true,
+      "requires": {
+        "@sinclair/typebox": "^0.27.8"
+      }
+    },
     "@jest/transform": {
       "version": "26.6.2",
       "dev": true,
@@ -45086,6 +44997,50 @@
       "version": "1.6.22",
       "dev": true
     },
+    "@messageformat/core": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/@messageformat/core/-/core-3.3.0.tgz",
+      "integrity": "sha512-YcXd3remTDdeMxAlbvW6oV9d/01/DZ8DHUFwSttO3LMzIZj3iO0NRw+u1xlsNNORFI+u0EQzD52ZX3+Udi0T3g==",
+      "dev": true,
+      "requires": {
+        "@messageformat/date-skeleton": "^1.0.0",
+        "@messageformat/number-skeleton": "^1.0.0",
+        "@messageformat/parser": "^5.1.0",
+        "@messageformat/runtime": "^3.0.1",
+        "make-plural": "^7.0.0",
+        "safe-identifier": "^0.4.1"
+      }
+    },
+    "@messageformat/date-skeleton": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@messageformat/date-skeleton/-/date-skeleton-1.0.1.tgz",
+      "integrity": "sha512-jPXy8fg+WMPIgmGjxSlnGJn68h/2InfT0TNSkVx0IGXgp4ynnvYkbZ51dGWmGySEK+pBiYUttbQdu5XEqX5CRg==",
+      "dev": true
+    },
+    "@messageformat/number-skeleton": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@messageformat/number-skeleton/-/number-skeleton-1.2.0.tgz",
+      "integrity": "sha512-xsgwcL7J7WhlHJ3RNbaVgssaIwcEyFkBqxHdcdaiJzwTZAWEOD8BuUFxnxV9k5S0qHN3v/KzUpq0IUpjH1seRg==",
+      "dev": true
+    },
+    "@messageformat/parser": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/@messageformat/parser/-/parser-5.1.0.tgz",
+      "integrity": "sha512-jKlkls3Gewgw6qMjKZ9SFfHUpdzEVdovKFtW1qRhJ3WI4FW5R/NnGDqr8SDGz+krWDO3ki94boMmQvGke1HwUQ==",
+      "dev": true,
+      "requires": {
+        "moo": "^0.5.1"
+      }
+    },
+    "@messageformat/runtime": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/@messageformat/runtime/-/runtime-3.0.1.tgz",
+      "integrity": "sha512-6RU5ol2lDtO8bD9Yxe6CZkl0DArdv0qkuoZC+ZwowU+cdRlVE1157wjCmlA5Rsf1Xc/brACnsZa5PZpEDfTFFg==",
+      "dev": true,
+      "requires": {
+        "make-plural": "^7.0.0"
+      }
+    },
     "@ndelangen/get-tarball": {
       "version": "3.0.9",
       "resolved": "https://registry.npmjs.org/@ndelangen/get-tarball/-/get-tarball-3.0.9.tgz",
@@ -45556,6 +45511,103 @@
       "dev": true,
       "optional": true
     },
+    "@prettier/eslint": {
+      "version": "npm:prettier-eslint@16.3.0",
+      "resolved": "https://registry.npmjs.org/prettier-eslint/-/prettier-eslint-16.3.0.tgz",
+      "integrity": "sha512-Lh102TIFCr11PJKUMQ2kwNmxGhTsv/KzUg9QYF2Gkw259g/kPgndZDWavk7/ycbRvj2oz4BPZ1gCU8bhfZH/Xg==",
+      "dev": true,
+      "requires": {
+        "@typescript-eslint/parser": "^6.7.5",
+        "common-tags": "^1.4.0",
+        "dlv": "^1.1.0",
+        "eslint": "^8.7.0",
+        "indent-string": "^4.0.0",
+        "lodash.merge": "^4.6.0",
+        "loglevel-colored-level-prefix": "^1.0.0",
+        "prettier": "^3.0.1",
+        "pretty-format": "^29.7.0",
+        "require-relative": "^0.8.7",
+        "typescript": "^5.2.2",
+        "vue-eslint-parser": "^9.1.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+          "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+          "dev": true
+        },
+        "debug": {
+          "version": "4.3.4",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+          "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+          "dev": true,
+          "requires": {
+            "ms": "2.1.2"
+          }
+        },
+        "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,
+          "requires": {
+            "esrecurse": "^4.3.0",
+            "estraverse": "^5.2.0"
+          }
+        },
+        "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
+        },
+        "estraverse": {
+          "version": "5.3.0",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+          "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+          "dev": true
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        },
+        "pretty-format": {
+          "version": "29.7.0",
+          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
+          "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
+          "dev": true,
+          "requires": {
+            "@jest/schemas": "^29.6.3",
+            "ansi-styles": "^5.0.0",
+            "react-is": "^18.0.0"
+          }
+        },
+        "react-is": {
+          "version": "18.2.0",
+          "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+          "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+          "dev": true
+        },
+        "vue-eslint-parser": {
+          "version": "9.4.2",
+          "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz",
+          "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==",
+          "dev": true,
+          "requires": {
+            "debug": "^4.3.4",
+            "eslint-scope": "^7.1.1",
+            "eslint-visitor-keys": "^3.3.0",
+            "espree": "^9.3.1",
+            "esquery": "^1.4.0",
+            "lodash": "^4.17.21",
+            "semver": "^7.3.6"
+          }
+        }
+      }
+    },
     "@rollup/rollup-android-arm-eabi": {
       "version": "4.9.6",
       "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz",
@@ -45931,6 +45983,12 @@
         "@sigstore/protobuf-specs": "^0.2.1"
       }
     },
+    "@sinclair/typebox": {
+      "version": "0.27.8",
+      "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
+      "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
+      "dev": true
+    },
     "@socket.io/base64-arraybuffer": {
       "version": "1.0.2",
       "dev": true
@@ -48076,6 +48134,12 @@
             "find-up": "^5.0.0"
           }
         },
+        "prettier": {
+          "version": "2.8.8",
+          "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
+          "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+          "dev": true
+        },
         "ramda": {
           "version": "0.29.0",
           "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.0.tgz",
@@ -48220,6 +48284,12 @@
           "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
           "dev": true
         },
+        "prettier": {
+          "version": "2.8.8",
+          "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
+          "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+          "dev": true
+        },
         "shebang-command": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -51424,7 +51494,9 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
       "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "@types/estree": {
       "version": "1.0.5",
@@ -51781,6 +51853,8 @@
       "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz",
       "integrity": "sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "@types/json-schema": "^7.0.3",
         "@typescript-eslint/typescript-estree": "1.13.0",
@@ -51792,6 +51866,8 @@
           "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
           "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "esrecurse": "^4.1.0",
             "estraverse": "^4.1.1"
@@ -51799,11 +51875,93 @@
         }
       }
     },
+    "@typescript-eslint/parser": {
+      "version": "6.21.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
+      "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
+      "dev": true,
+      "requires": {
+        "@typescript-eslint/scope-manager": "6.21.0",
+        "@typescript-eslint/types": "6.21.0",
+        "@typescript-eslint/typescript-estree": "6.21.0",
+        "@typescript-eslint/visitor-keys": "6.21.0",
+        "debug": "^4.3.4"
+      },
+      "dependencies": {
+        "@typescript-eslint/typescript-estree": {
+          "version": "6.21.0",
+          "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
+          "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
+          "dev": true,
+          "requires": {
+            "@typescript-eslint/types": "6.21.0",
+            "@typescript-eslint/visitor-keys": "6.21.0",
+            "debug": "^4.3.4",
+            "globby": "^11.1.0",
+            "is-glob": "^4.0.3",
+            "minimatch": "9.0.3",
+            "semver": "^7.5.4",
+            "ts-api-utils": "^1.0.1"
+          }
+        },
+        "brace-expansion": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+          "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+          "dev": true,
+          "requires": {
+            "balanced-match": "^1.0.0"
+          }
+        },
+        "debug": {
+          "version": "4.3.4",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+          "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+          "dev": true,
+          "requires": {
+            "ms": "2.1.2"
+          }
+        },
+        "minimatch": {
+          "version": "9.0.3",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+          "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^2.0.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        }
+      }
+    },
+    "@typescript-eslint/scope-manager": {
+      "version": "6.21.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
+      "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
+      "dev": true,
+      "requires": {
+        "@typescript-eslint/types": "6.21.0",
+        "@typescript-eslint/visitor-keys": "6.21.0"
+      }
+    },
+    "@typescript-eslint/types": {
+      "version": "6.21.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
+      "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
+      "dev": true
+    },
     "@typescript-eslint/typescript-estree": {
       "version": "1.13.0",
       "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz",
       "integrity": "sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "lodash.unescape": "4.0.1",
         "semver": "5.5.0"
@@ -51813,10 +51971,36 @@
           "version": "5.5.0",
           "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
           "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
+          "dev": true,
+          "optional": true,
+          "peer": true
+        }
+      }
+    },
+    "@typescript-eslint/visitor-keys": {
+      "version": "6.21.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
+      "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
+      "dev": true,
+      "requires": {
+        "@typescript-eslint/types": "6.21.0",
+        "eslint-visitor-keys": "^3.4.1"
+      },
+      "dependencies": {
+        "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
         }
       }
     },
+    "@ungap/structured-clone": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
+      "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
+      "dev": true
+    },
     "@webassemblyjs/ast": {
       "version": "1.11.6",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
@@ -52610,7 +52794,9 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
       "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "async": {
       "version": "3.2.5",
@@ -53585,42 +53771,14 @@
       "dev": true
     },
     "cliui": {
-      "version": "5.0.0",
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
       "dev": true,
       "requires": {
-        "string-width": "^3.1.0",
-        "strip-ansi": "^5.2.0",
-        "wrap-ansi": "^5.1.0"
-      },
-      "dependencies": {
-        "ansi-regex": {
-          "version": "4.1.1",
-          "dev": true
-        },
-        "emoji-regex": {
-          "version": "7.0.3",
-          "dev": true
-        },
-        "is-fullwidth-code-point": {
-          "version": "2.0.0",
-          "dev": true
-        },
-        "string-width": {
-          "version": "3.1.0",
-          "dev": true,
-          "requires": {
-            "emoji-regex": "^7.0.1",
-            "is-fullwidth-code-point": "^2.0.0",
-            "strip-ansi": "^5.1.0"
-          }
-        },
-        "strip-ansi": {
-          "version": "5.2.0",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^4.1.0"
-          }
-        }
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.1",
+        "wrap-ansi": "^7.0.0"
       }
     },
     "clone": {
@@ -53750,7 +53908,9 @@
       "dev": true
     },
     "common-tags": {
-      "version": "1.8.0",
+      "version": "1.8.2",
+      "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
+      "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
       "dev": true
     },
     "commondir": {
@@ -54072,7 +54232,9 @@
       }
     },
     "core-js": {
-      "version": "3.20.3",
+      "version": "3.35.1",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.35.1.tgz",
+      "integrity": "sha512-IgdsbxNyMskrTFxa9lWHyMwAJU5gXOPP+1yO+K59d50VLVAIDAbs7gIv705KzALModfK3ZrSZTPNpC0PQgIZuw==",
       "dev": true
     },
     "core-js-compat": {
@@ -55332,51 +55494,49 @@
       }
     },
     "eslint": {
-      "version": "8.21.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.21.0.tgz",
-      "integrity": "sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "@eslint/eslintrc": "^1.3.0",
-        "@humanwhocodes/config-array": "^0.10.4",
-        "@humanwhocodes/gitignore-to-minimatch": "^1.0.2",
-        "ajv": "^6.10.0",
+      "version": "8.56.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz",
+      "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==",
+      "dev": true,
+      "requires": {
+        "@eslint-community/eslint-utils": "^4.2.0",
+        "@eslint-community/regexpp": "^4.6.1",
+        "@eslint/eslintrc": "^2.1.4",
+        "@eslint/js": "8.56.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.1.1",
-        "eslint-utils": "^3.0.0",
-        "eslint-visitor-keys": "^3.3.0",
-        "espree": "^9.3.3",
-        "esquery": "^1.4.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",
-        "functional-red-black-tree": "^1.0.1",
-        "glob-parent": "^6.0.1",
-        "globals": "^13.15.0",
-        "globby": "^11.1.0",
-        "grapheme-splitter": "^1.0.4",
+        "glob-parent": "^6.0.2",
+        "globals": "^13.19.0",
+        "graphemer": "^1.4.0",
         "ignore": "^5.2.0",
-        "import-fresh": "^3.0.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.1",
-        "regexpp": "^3.2.0",
+        "optionator": "^0.9.3",
         "strip-ansi": "^6.0.1",
-        "strip-json-comments": "^3.1.0",
-        "text-table": "^0.2.0",
-        "v8-compile-cache": "^2.0.3"
+        "text-table": "^0.2.0"
       },
       "dependencies": {
         "ansi-styles": {
@@ -55384,7 +55544,6 @@
           "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
           "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
           "dev": true,
-          "peer": true,
           "requires": {
             "color-convert": "^2.0.1"
           }
@@ -55393,15 +55552,13 @@
           "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
+          "dev": true
         },
         "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,
           "requires": {
             "ansi-styles": "^4.1.0",
             "supports-color": "^7.1.0"
@@ -55412,7 +55569,6 @@
           "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
           "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
           "dev": true,
-          "peer": true,
           "requires": {
             "color-name": "~1.1.4"
           }
@@ -55421,15 +55577,13 @@
           "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
+          "dev": true
         },
         "cross-spawn": {
           "version": "7.0.3",
           "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
           "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
           "dev": true,
-          "peer": true,
           "requires": {
             "path-key": "^3.1.0",
             "shebang-command": "^2.0.0",
@@ -55439,7 +55593,6 @@
         "debug": {
           "version": "4.3.2",
           "dev": true,
-          "peer": true,
           "requires": {
             "ms": "2.1.2"
           }
@@ -55448,51 +55601,45 @@
           "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
+          "dev": true
         },
         "eslint-scope": {
-          "version": "7.1.1",
-          "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
-          "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
+          "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,
           "requires": {
             "esrecurse": "^4.3.0",
             "estraverse": "^5.2.0"
           }
         },
         "eslint-visitor-keys": {
-          "version": "3.3.0",
-          "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
-          "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
-          "dev": true,
-          "peer": true
+          "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
         },
         "estraverse": {
           "version": "5.3.0",
           "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
           "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
-          "dev": true,
-          "peer": true
+          "dev": true
         },
         "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,
           "requires": {
             "locate-path": "^6.0.0",
             "path-exists": "^4.0.0"
           }
         },
         "globals": {
-          "version": "13.17.0",
-          "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz",
-          "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==",
+          "version": "13.24.0",
+          "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+          "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
           "dev": true,
-          "peer": true,
           "requires": {
             "type-fest": "^0.20.2"
           }
@@ -55501,15 +55648,13 @@
           "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
+          "dev": true
         },
         "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,
           "requires": {
             "argparse": "^2.0.1"
           }
@@ -55519,7 +55664,6 @@
           "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
           "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
           "dev": true,
-          "peer": true,
           "requires": {
             "prelude-ls": "^1.2.1",
             "type-check": "~0.4.0"
@@ -55530,29 +55674,26 @@
           "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
           "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
           "dev": true,
-          "peer": true,
           "requires": {
             "p-locate": "^5.0.0"
           }
         },
         "ms": {
           "version": "2.1.2",
-          "dev": true,
-          "peer": true
+          "dev": true
         },
         "optionator": {
-          "version": "0.9.1",
-          "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
-          "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+          "version": "0.9.3",
+          "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
+          "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
           "dev": true,
-          "peer": true,
           "requires": {
+            "@aashutoshrathi/word-wrap": "^1.2.3",
             "deep-is": "^0.1.3",
             "fast-levenshtein": "^2.0.6",
             "levn": "^0.4.1",
             "prelude-ls": "^1.2.1",
-            "type-check": "^0.4.0",
-            "word-wrap": "^1.2.3"
+            "type-check": "^0.4.0"
           }
         },
         "p-limit": {
@@ -55560,7 +55701,6 @@
           "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
           "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
           "dev": true,
-          "peer": true,
           "requires": {
             "yocto-queue": "^0.1.0"
           }
@@ -55570,7 +55710,6 @@
           "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,
           "requires": {
             "p-limit": "^3.0.2"
           }
@@ -55579,22 +55718,19 @@
           "version": "3.1.1",
           "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
           "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-          "dev": true,
-          "peer": true
+          "dev": true
         },
         "prelude-ls": {
           "version": "1.2.1",
           "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
           "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
-          "dev": true,
-          "peer": true
+          "dev": true
         },
         "shebang-command": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
           "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
           "dev": true,
-          "peer": true,
           "requires": {
             "shebang-regex": "^3.0.0"
           }
@@ -55603,15 +55739,13 @@
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
           "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-          "dev": true,
-          "peer": true
+          "dev": true
         },
         "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,
           "requires": {
             "has-flag": "^4.0.0"
           }
@@ -55621,7 +55755,6 @@
           "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
           "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
           "dev": true,
-          "peer": true,
           "requires": {
             "prelude-ls": "^1.2.1"
           }
@@ -55630,15 +55763,13 @@
           "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
+          "dev": true
         },
         "which": {
           "version": "2.0.2",
           "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
           "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
           "dev": true,
-          "peer": true,
           "requires": {
             "isexe": "^2.0.0"
           }
@@ -55667,47 +55798,28 @@
         "estraverse": "^4.1.1"
       }
     },
-    "eslint-utils": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
-      "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "eslint-visitor-keys": "^2.0.0"
-      },
-      "dependencies": {
-        "eslint-visitor-keys": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-          "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
-          "dev": true,
-          "peer": true
-        }
-      }
-    },
     "eslint-visitor-keys": {
       "version": "1.3.0",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "espree": {
-      "version": "9.3.3",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz",
-      "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==",
+      "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,
       "requires": {
-        "acorn": "^8.8.0",
+        "acorn": "^8.9.0",
         "acorn-jsx": "^5.3.2",
-        "eslint-visitor-keys": "^3.3.0"
+        "eslint-visitor-keys": "^3.4.1"
       },
       "dependencies": {
         "eslint-visitor-keys": {
-          "version": "3.3.0",
-          "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
-          "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
-          "dev": true,
-          "peer": true
+          "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
         }
       }
     },
@@ -55716,7 +55828,9 @@
       "dev": true
     },
     "esquery": {
-      "version": "1.4.0",
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+      "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
       "dev": true,
       "requires": {
         "estraverse": "^5.1.0"
@@ -56211,7 +56325,6 @@
       "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
       "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
       "dev": true,
-      "peer": true,
       "requires": {
         "flat-cache": "^3.0.4"
       }
@@ -56351,7 +56464,6 @@
       "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
       "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
       "dev": true,
-      "peer": true,
       "requires": {
         "flatted": "^3.1.0",
         "rimraf": "^3.0.2"
@@ -56728,7 +56840,9 @@
     },
     "functional-red-black-tree": {
       "version": "1.0.1",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "functions-have-names": {
       "version": "1.2.3",
@@ -56934,12 +57048,11 @@
       "version": "4.2.10",
       "dev": true
     },
-    "grapheme-splitter": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
-      "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
-      "dev": true,
-      "peer": true
+    "graphemer": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+      "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+      "dev": true
     },
     "gunzip-maybe": {
       "version": "1.4.2",
@@ -57524,7 +57637,9 @@
       "dev": true
     },
     "ignore": {
-      "version": "5.2.0",
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
+      "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
       "dev": true
     },
     "ignore-walk": {
@@ -58674,13 +58789,6 @@
         "yargs": "^16.1.1"
       },
       "dependencies": {
-        "ansi-styles": {
-          "version": "4.3.0",
-          "dev": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
         "cliui": {
           "version": "7.0.4",
           "dev": true,
@@ -58690,17 +58798,6 @@
             "wrap-ansi": "^7.0.0"
           }
         },
-        "color-convert": {
-          "version": "2.0.1",
-          "dev": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "dev": true
-        },
         "mime": {
           "version": "2.6.0",
           "dev": true
@@ -58723,15 +58820,6 @@
             "rimraf": "^3.0.0"
           }
         },
-        "wrap-ansi": {
-          "version": "7.0.0",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.0.0",
-            "string-width": "^4.1.0",
-            "strip-ansi": "^6.0.0"
-          }
-        },
         "y18n": {
           "version": "5.0.8",
           "dev": true
@@ -59054,7 +59142,9 @@
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz",
       "integrity": "sha512-DhhGRshNS1aX6s5YdBE3njCCouPgnG29ebyHvImlZzXZf2SHgt+J08DHgytTPnpywNbO1Y8mNUFyQuIDBq2JZg==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "lodash.uniq": {
       "version": "4.5.0",
@@ -59266,11 +59356,10 @@
       }
     },
     "make-plural": {
-      "version": "4.3.0",
-      "dev": true,
-      "requires": {
-        "minimist": "^1.2.0"
-      }
+      "version": "7.3.0",
+      "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.3.0.tgz",
+      "integrity": "sha512-/K3BC0KIsO+WK2i94LkMPv3wslMrazrQhfi5We9fMbLlLjzoOSJWr7TAdupLlDWaJcWxwoNosBkhFDejiu5VDw==",
+      "dev": true
     },
     "makeerror": {
       "version": "1.0.12",
@@ -59529,23 +59618,6 @@
       "version": "1.4.1",
       "dev": true
     },
-    "messageformat": {
-      "version": "2.3.0",
-      "dev": true,
-      "requires": {
-        "make-plural": "^4.3.0",
-        "messageformat-formatters": "^2.0.1",
-        "messageformat-parser": "^4.1.2"
-      }
-    },
-    "messageformat-formatters": {
-      "version": "2.0.1",
-      "dev": true
-    },
-    "messageformat-parser": {
-      "version": "4.1.3",
-      "dev": true
-    },
     "methods": {
       "version": "1.1.2",
       "dev": true
@@ -59812,6 +59884,12 @@
       "version": "1.0.1",
       "dev": true
     },
+    "moo": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz",
+      "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==",
+      "dev": true
+    },
     "morgan": {
       "version": "1.10.0",
       "dev": true,
@@ -63064,14 +63142,16 @@
       "dev": true
     },
     "prettier": {
-      "version": "2.8.8",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
-      "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+      "version": "3.2.5",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
+      "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
       "dev": true
     },
     "prettier-eslint": {
       "version": "9.0.2",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "@typescript-eslint/parser": "^1.10.2",
         "common-tags": "^1.4.0",
@@ -63093,6 +63173,8 @@
           "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.13.0.tgz",
           "integrity": "sha512-ITMBs52PCPgLb2nGPoeT4iU3HdQZHcPaZVw+7CsFagRJHUhyeTgorEwHXhFf3e7Evzi8oujKNpHc8TONth8AdQ==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "@types/eslint-visitor-keys": "^1.0.0",
             "@typescript-eslint/experimental-utils": "1.13.0",
@@ -63104,355 +63186,33 @@
           "version": "6.4.2",
           "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
           "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
-          "dev": true
-        },
-        "ansi-escapes": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
-          "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
-          "dev": true
-        },
-        "ansi-regex": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
-          "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
-          "dev": true
-        },
-        "cli-cursor": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
-          "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==",
-          "dev": true,
-          "requires": {
-            "restore-cursor": "^2.0.0"
-          }
-        },
-        "cli-width": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
-          "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==",
-          "dev": true
-        },
-        "debug": {
-          "version": "4.3.4",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
-          "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
-          "dev": true,
-          "requires": {
-            "ms": "2.1.2"
-          }
-        },
-        "eslint": {
-          "version": "5.16.0",
-          "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz",
-          "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==",
           "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.0.0",
-            "ajv": "^6.9.1",
-            "chalk": "^2.1.0",
-            "cross-spawn": "^6.0.5",
-            "debug": "^4.0.1",
-            "doctrine": "^3.0.0",
-            "eslint-scope": "^4.0.3",
-            "eslint-utils": "^1.3.1",
-            "eslint-visitor-keys": "^1.0.0",
-            "espree": "^5.0.1",
-            "esquery": "^1.0.1",
-            "esutils": "^2.0.2",
-            "file-entry-cache": "^5.0.1",
-            "functional-red-black-tree": "^1.0.1",
-            "glob": "^7.1.2",
-            "globals": "^11.7.0",
-            "ignore": "^4.0.6",
-            "import-fresh": "^3.0.0",
-            "imurmurhash": "^0.1.4",
-            "inquirer": "^6.2.2",
-            "js-yaml": "^3.13.0",
-            "json-stable-stringify-without-jsonify": "^1.0.1",
-            "levn": "^0.3.0",
-            "lodash": "^4.17.11",
-            "minimatch": "^3.0.4",
-            "mkdirp": "^0.5.1",
-            "natural-compare": "^1.4.0",
-            "optionator": "^0.8.2",
-            "path-is-inside": "^1.0.2",
-            "progress": "^2.0.0",
-            "regexpp": "^2.0.1",
-            "semver": "^5.5.1",
-            "strip-ansi": "^4.0.0",
-            "strip-json-comments": "^2.0.1",
-            "table": "^5.2.3",
-            "text-table": "^0.2.0"
-          }
-        },
-        "eslint-scope": {
-          "version": "4.0.3",
-          "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
-          "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
-          "dev": true,
-          "requires": {
-            "esrecurse": "^4.1.0",
-            "estraverse": "^4.1.1"
-          }
-        },
-        "eslint-utils": {
-          "version": "1.4.3",
-          "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
-          "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
-          "dev": true,
-          "requires": {
-            "eslint-visitor-keys": "^1.1.0"
-          }
-        },
-        "espree": {
-          "version": "5.0.1",
-          "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz",
-          "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==",
-          "dev": true,
-          "requires": {
-            "acorn": "^6.0.7",
-            "acorn-jsx": "^5.0.0",
-            "eslint-visitor-keys": "^1.0.0"
-          }
-        },
-        "figures": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
-          "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==",
-          "dev": true,
-          "requires": {
-            "escape-string-regexp": "^1.0.5"
-          }
-        },
-        "file-entry-cache": {
-          "version": "5.0.1",
-          "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
-          "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
-          "dev": true,
-          "requires": {
-            "flat-cache": "^2.0.1"
-          }
-        },
-        "flat-cache": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
-          "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
-          "dev": true,
-          "requires": {
-            "flatted": "^2.0.0",
-            "rimraf": "2.6.3",
-            "write": "1.0.3"
-          }
-        },
-        "flatted": {
-          "version": "2.0.2",
-          "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
-          "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
-          "dev": true
-        },
-        "ignore": {
-          "version": "4.0.6",
-          "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
-          "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
-          "dev": true
-        },
-        "inquirer": {
-          "version": "6.5.2",
-          "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz",
-          "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==",
-          "dev": true,
-          "requires": {
-            "ansi-escapes": "^3.2.0",
-            "chalk": "^2.4.2",
-            "cli-cursor": "^2.1.0",
-            "cli-width": "^2.0.0",
-            "external-editor": "^3.0.3",
-            "figures": "^2.0.0",
-            "lodash": "^4.17.12",
-            "mute-stream": "0.0.7",
-            "run-async": "^2.2.0",
-            "rxjs": "^6.4.0",
-            "string-width": "^2.1.0",
-            "strip-ansi": "^5.1.0",
-            "through": "^2.3.6"
-          },
-          "dependencies": {
-            "ansi-regex": {
-              "version": "4.1.1",
-              "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
-              "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
-              "dev": true
-            },
-            "strip-ansi": {
-              "version": "5.2.0",
-              "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
-              "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
-              "dev": true,
-              "requires": {
-                "ansi-regex": "^4.1.0"
-              }
-            }
-          }
-        },
-        "is-fullwidth-code-point": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
-          "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
-          "dev": true
-        },
-        "mimic-fn": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
-          "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
-          "dev": true
-        },
-        "mkdirp": {
-          "version": "0.5.6",
-          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
-          "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
-          "dev": true,
-          "requires": {
-            "minimist": "^1.2.6"
-          }
-        },
-        "ms": {
-          "version": "2.1.2",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-          "dev": true
-        },
-        "mute-stream": {
-          "version": "0.0.7",
-          "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
-          "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==",
-          "dev": true
-        },
-        "onetime": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
-          "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==",
-          "dev": true,
-          "requires": {
-            "mimic-fn": "^1.0.0"
-          }
-        },
-        "prettier": {
-          "version": "1.19.1",
-          "dev": true
-        },
-        "regexpp": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
-          "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
-          "dev": true
-        },
-        "restore-cursor": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
-          "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==",
-          "dev": true,
-          "requires": {
-            "onetime": "^2.0.0",
-            "signal-exit": "^3.0.2"
-          }
-        },
-        "rimraf": {
-          "version": "2.6.3",
-          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
-          "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
-          "dev": true,
-          "requires": {
-            "glob": "^7.1.3"
-          }
-        },
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-          "dev": true
-        },
-        "string-width": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
-          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
-          "dev": true,
-          "requires": {
-            "is-fullwidth-code-point": "^2.0.0",
-            "strip-ansi": "^4.0.0"
-          }
-        },
-        "strip-ansi": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
-          "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^3.0.0"
-          }
-        },
-        "strip-json-comments": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
-          "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
-          "dev": true
-        },
-        "typescript": {
-          "version": "3.9.10",
-          "dev": true
-        }
-      }
-    },
-    "prettier-eslint-cli": {
-      "version": "5.0.1",
-      "dev": true,
-      "requires": {
-        "arrify": "^2.0.1",
-        "boolify": "^1.0.0",
-        "camelcase-keys": "^6.0.0",
-        "chalk": "^2.4.2",
-        "common-tags": "^1.8.0",
-        "core-js": "^3.1.4",
-        "eslint": "^5.0.0",
-        "find-up": "^4.1.0",
-        "get-stdin": "^7.0.0",
-        "glob": "^7.1.4",
-        "ignore": "^5.1.2",
-        "lodash.memoize": "^4.1.2",
-        "loglevel-colored-level-prefix": "^1.0.0",
-        "messageformat": "^2.2.1",
-        "prettier-eslint": "^9.0.0",
-        "rxjs": "^6.5.2",
-        "yargs": "^13.2.4"
-      },
-      "dependencies": {
-        "acorn": {
-          "version": "6.4.2",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
-          "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
-          "dev": true
+          "optional": true,
+          "peer": true
         },
         "ansi-escapes": {
           "version": "3.2.0",
           "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
           "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         },
         "ansi-regex": {
           "version": "3.0.1",
           "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
           "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
-          "dev": true
-        },
-        "arrify": {
-          "version": "2.0.1",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         },
         "cli-cursor": {
           "version": "2.1.0",
           "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
           "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "restore-cursor": "^2.0.0"
           }
@@ -63461,13 +63221,17 @@
           "version": "2.2.1",
           "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
           "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         },
         "debug": {
           "version": "4.3.4",
           "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
           "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "ms": "2.1.2"
           }
@@ -63477,6 +63241,8 @@
           "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz",
           "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "@babel/code-frame": "^7.0.0",
             "ajv": "^6.9.1",
@@ -63514,14 +63280,6 @@
             "strip-json-comments": "^2.0.1",
             "table": "^5.2.3",
             "text-table": "^0.2.0"
-          },
-          "dependencies": {
-            "ignore": {
-              "version": "4.0.6",
-              "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
-              "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
-              "dev": true
-            }
           }
         },
         "eslint-scope": {
@@ -63529,6 +63287,8 @@
           "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
           "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "esrecurse": "^4.1.0",
             "estraverse": "^4.1.1"
@@ -63539,6 +63299,8 @@
           "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
           "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "eslint-visitor-keys": "^1.1.0"
           }
@@ -63548,6 +63310,8 @@
           "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz",
           "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "acorn": "^6.0.7",
             "acorn-jsx": "^5.0.0",
@@ -63559,6 +63323,8 @@
           "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
           "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "escape-string-regexp": "^1.0.5"
           }
@@ -63568,6 +63334,8 @@
           "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
           "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "flat-cache": "^2.0.1"
           }
@@ -63577,6 +63345,8 @@
           "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
           "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "flatted": "^2.0.0",
             "rimraf": "2.6.3",
@@ -63587,17 +63357,25 @@
           "version": "2.0.2",
           "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
           "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         },
-        "get-stdin": {
-          "version": "7.0.0",
-          "dev": true
+        "ignore": {
+          "version": "4.0.6",
+          "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+          "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+          "dev": true,
+          "optional": true,
+          "peer": true
         },
         "inquirer": {
           "version": "6.5.2",
           "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz",
           "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "ansi-escapes": "^3.2.0",
             "chalk": "^2.4.2",
@@ -63618,13 +63396,17 @@
               "version": "4.1.1",
               "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
               "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
-              "dev": true
+              "dev": true,
+              "optional": true,
+              "peer": true
             },
             "strip-ansi": {
               "version": "5.2.0",
               "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
               "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
               "dev": true,
+              "optional": true,
+              "peer": true,
               "requires": {
                 "ansi-regex": "^4.1.0"
               }
@@ -63635,19 +63417,25 @@
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
           "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         },
         "mimic-fn": {
           "version": "1.2.0",
           "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
           "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         },
         "mkdirp": {
           "version": "0.5.6",
           "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
           "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "minimist": "^1.2.6"
           }
@@ -63656,34 +63444,50 @@
           "version": "2.1.2",
           "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
           "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         },
         "mute-stream": {
           "version": "0.0.7",
           "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
           "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         },
         "onetime": {
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
           "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "mimic-fn": "^1.0.0"
           }
         },
+        "prettier": {
+          "version": "1.19.1",
+          "dev": true,
+          "optional": true,
+          "peer": true
+        },
         "regexpp": {
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
           "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         },
         "restore-cursor": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
           "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "onetime": "^2.0.0",
             "signal-exit": "^3.0.2"
@@ -63694,6 +63498,8 @@
           "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
           "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "glob": "^7.1.3"
           }
@@ -63702,13 +63508,17 @@
           "version": "5.7.1",
           "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
           "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         },
         "string-width": {
           "version": "2.1.1",
           "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
           "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "is-fullwidth-code-point": "^2.0.0",
             "strip-ansi": "^4.0.0"
@@ -63719,6 +63529,8 @@
           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
           "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "ansi-regex": "^3.0.0"
           }
@@ -63727,6 +63539,220 @@
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
           "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+          "dev": true,
+          "optional": true,
+          "peer": true
+        },
+        "typescript": {
+          "version": "3.9.10",
+          "dev": true,
+          "optional": true,
+          "peer": true
+        }
+      }
+    },
+    "prettier-eslint-cli": {
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/prettier-eslint-cli/-/prettier-eslint-cli-8.0.1.tgz",
+      "integrity": "sha512-jru4JUDHzWEtM/SOxqagU7hQTVP8BVrxO2J0qNauWZuPRld6Ea2eyNaEzIGx6I+yjmOLCsjNM+vU1AJgaW1ZSQ==",
+      "dev": true,
+      "requires": {
+        "@messageformat/core": "^3.2.0",
+        "@prettier/eslint": "npm:prettier-eslint@^16.1.0",
+        "arrify": "^2.0.1",
+        "boolify": "^1.0.1",
+        "camelcase-keys": "^9.1.0",
+        "chalk": "^4.1.2",
+        "common-tags": "^1.8.2",
+        "core-js": "^3.33.0",
+        "eslint": "^8.51.0",
+        "find-up": "^5.0.0",
+        "get-stdin": "^8.0.0",
+        "glob": "^10.3.10",
+        "ignore": "^5.2.4",
+        "indent-string": "^4.0.0",
+        "lodash.memoize": "^4.1.2",
+        "loglevel-colored-level-prefix": "^1.0.0",
+        "rxjs": "^7.8.1",
+        "yargs": "^17.7.2"
+      },
+      "dependencies": {
+        "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,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "arrify": {
+          "version": "2.0.1",
+          "dev": true
+        },
+        "brace-expansion": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+          "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+          "dev": true,
+          "requires": {
+            "balanced-match": "^1.0.0"
+          }
+        },
+        "camelcase": {
+          "version": "8.0.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz",
+          "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==",
+          "dev": true
+        },
+        "camelcase-keys": {
+          "version": "9.1.3",
+          "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-9.1.3.tgz",
+          "integrity": "sha512-Rircqi9ch8AnZscQcsA1C47NFdaO3wukpmIRzYcDOrmvgt78hM/sj5pZhZNec2NM12uk5vTwRHZ4anGcrC4ZTg==",
+          "dev": true,
+          "requires": {
+            "camelcase": "^8.0.0",
+            "map-obj": "5.0.0",
+            "quick-lru": "^6.1.1",
+            "type-fest": "^4.3.2"
+          }
+        },
+        "chalk": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "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,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "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
+        },
+        "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,
+          "requires": {
+            "locate-path": "^6.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "get-stdin": {
+          "version": "8.0.0",
+          "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz",
+          "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==",
+          "dev": true
+        },
+        "glob": {
+          "version": "10.3.10",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz",
+          "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==",
+          "dev": true,
+          "requires": {
+            "foreground-child": "^3.1.0",
+            "jackspeak": "^2.3.5",
+            "minimatch": "^9.0.1",
+            "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
+            "path-scurry": "^1.10.1"
+          }
+        },
+        "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
+        },
+        "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,
+          "requires": {
+            "p-locate": "^5.0.0"
+          }
+        },
+        "map-obj": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-5.0.0.tgz",
+          "integrity": "sha512-2L3MIgJynYrZ3TYMriLDLWocz15okFakV6J12HXvMXDHui2x/zgChzg1u9mFFGbbGWE+GsLpQByt4POb9Or+uA==",
+          "dev": true
+        },
+        "minimatch": {
+          "version": "9.0.3",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+          "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^2.0.1"
+          }
+        },
+        "minipass": {
+          "version": "7.0.4",
+          "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
+          "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
+          "dev": true
+        },
+        "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,
+          "requires": {
+            "yocto-queue": "^0.1.0"
+          }
+        },
+        "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,
+          "requires": {
+            "p-limit": "^3.0.2"
+          }
+        },
+        "quick-lru": {
+          "version": "6.1.2",
+          "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-6.1.2.tgz",
+          "integrity": "sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==",
+          "dev": true
+        },
+        "rxjs": {
+          "version": "7.8.1",
+          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
+          "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
+          "dev": true,
+          "requires": {
+            "tslib": "^2.1.0"
+          }
+        },
+        "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,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        },
+        "type-fest": {
+          "version": "4.10.2",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.10.2.tgz",
+          "integrity": "sha512-anpAG63wSpdEbLwOqH8L84urkL6PiVIov3EMmgIhhThevh9aiMQov+6Btx0wldNcvm4wV+e2/Rt1QdDwKHFbHw==",
           "dev": true
         }
       }
@@ -63739,7 +63765,9 @@
       }
     },
     "prettier-plugin-organize-imports": {
-      "version": "1.1.1",
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.2.4.tgz",
+      "integrity": "sha512-6m8WBhIp0dfwu0SkgfOxJqh+HpdyfqSSLfKKRZSFbDuEQXDDndb8fTpRWkUrX/uBenkex3MgnVk0J3b3Y5byog==",
       "dev": true,
       "requires": {}
     },
@@ -63762,6 +63790,8 @@
     "pretty-format": {
       "version": "23.6.0",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "ansi-regex": "^3.0.0",
         "ansi-styles": "^3.2.0"
@@ -63769,7 +63799,9 @@
       "dependencies": {
         "ansi-regex": {
           "version": "3.0.1",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         }
       }
     },
@@ -64677,13 +64709,6 @@
         "functions-have-names": "^1.2.2"
       }
     },
-    "regexpp": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
-      "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
-      "dev": true,
-      "peer": true
-    },
     "regexpu-core": {
       "version": "5.3.2",
       "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz",
@@ -65041,7 +65066,9 @@
     },
     "run-async": {
       "version": "2.4.1",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "run-parallel": {
       "version": "1.2.0",
@@ -65072,6 +65099,12 @@
       "version": "5.1.2",
       "dev": true
     },
+    "safe-identifier": {
+      "version": "0.4.2",
+      "resolved": "https://registry.npmjs.org/safe-identifier/-/safe-identifier-0.4.2.tgz",
+      "integrity": "sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w==",
+      "dev": true
+    },
     "safe-regex": {
       "version": "1.1.0",
       "dev": true,
@@ -65407,13 +65440,6 @@
           "version": "3.0.0",
           "dev": true
         },
-        "ansi-styles": {
-          "version": "4.3.0",
-          "dev": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
         "cliui": {
           "version": "7.0.4",
           "dev": true,
@@ -65423,17 +65449,6 @@
             "wrap-ansi": "^7.0.0"
           }
         },
-        "color-convert": {
-          "version": "2.0.1",
-          "dev": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "dev": true
-        },
         "debug": {
           "version": "4.3.4",
           "dev": true,
@@ -65449,15 +65464,6 @@
           "version": "5.0.0",
           "dev": true
         },
-        "wrap-ansi": {
-          "version": "7.0.0",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.0.0",
-            "string-width": "^4.1.0",
-            "strip-ansi": "^6.0.0"
-          }
-        },
         "y18n": {
           "version": "5.0.8",
           "dev": true
@@ -65779,6 +65785,8 @@
       "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
       "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "ansi-styles": "^3.2.0",
         "astral-regex": "^1.0.0",
@@ -65789,7 +65797,9 @@
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
           "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         }
       }
     },
@@ -66679,6 +66689,8 @@
       "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
       "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "ajv": "^6.10.2",
         "lodash": "^4.17.14",
@@ -66690,25 +66702,33 @@
           "version": "4.1.1",
           "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
           "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         },
         "emoji-regex": {
           "version": "7.0.3",
           "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
           "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         },
         "is-fullwidth-code-point": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
           "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         },
         "string-width": {
           "version": "3.1.0",
           "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
           "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "emoji-regex": "^7.0.1",
             "is-fullwidth-code-point": "^2.0.0",
@@ -66720,6 +66740,8 @@
           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
           "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "ansi-regex": "^4.1.0"
           }
@@ -67068,6 +67090,13 @@
       "version": "1.0.5",
       "dev": true
     },
+    "ts-api-utils": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz",
+      "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==",
+      "dev": true,
+      "requires": {}
+    },
     "ts-dedent": {
       "version": "2.2.0",
       "dev": true
@@ -67657,13 +67686,6 @@
       "version": "3.1.0",
       "dev": true
     },
-    "v8-compile-cache": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
-      "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
-      "dev": true,
-      "peer": true
-    },
     "v8-compile-cache-lib": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
@@ -67739,6 +67761,8 @@
     "vue-eslint-parser": {
       "version": "2.0.3",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "debug": "^3.1.0",
         "eslint-scope": "^3.7.1",
@@ -67750,24 +67774,32 @@
       "dependencies": {
         "acorn": {
           "version": "5.7.4",
-          "dev": true
+          "dev": true,
+          "optional": true,
+          "peer": true
         },
         "acorn-jsx": {
           "version": "3.0.1",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "acorn": "^3.0.4"
           },
           "dependencies": {
             "acorn": {
               "version": "3.3.0",
-              "dev": true
+              "dev": true,
+              "optional": true,
+              "peer": true
             }
           }
         },
         "eslint-scope": {
           "version": "3.7.3",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "esrecurse": "^4.1.0",
             "estraverse": "^4.1.1"
@@ -67776,6 +67808,8 @@
         "espree": {
           "version": "3.5.4",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "acorn": "^5.5.0",
             "acorn-jsx": "^3.0.0"
@@ -68220,41 +68254,39 @@
       }
     },
     "wrap-ansi": {
-      "version": "5.1.0",
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
       "dev": true,
       "requires": {
-        "ansi-styles": "^3.2.0",
-        "string-width": "^3.0.0",
-        "strip-ansi": "^5.0.0"
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
       },
       "dependencies": {
-        "ansi-regex": {
-          "version": "4.1.1",
-          "dev": true
-        },
-        "emoji-regex": {
-          "version": "7.0.3",
-          "dev": true
-        },
-        "is-fullwidth-code-point": {
-          "version": "2.0.0",
-          "dev": true
-        },
-        "string-width": {
-          "version": "3.1.0",
+        "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,
           "requires": {
-            "emoji-regex": "^7.0.1",
-            "is-fullwidth-code-point": "^2.0.0",
-            "strip-ansi": "^5.1.0"
+            "color-convert": "^2.0.1"
           }
         },
-        "strip-ansi": {
-          "version": "5.2.0",
+        "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,
           "requires": {
-            "ansi-regex": "^4.1.0"
+            "color-name": "~1.1.4"
           }
+        },
+        "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
         }
       }
     },
@@ -68304,6 +68336,8 @@
       "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
       "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "mkdirp": "^0.5.1"
       },
@@ -68313,6 +68347,8 @@
           "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
           "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
           "dev": true,
+          "optional": true,
+          "peer": true,
           "requires": {
             "minimist": "^1.2.6"
           }
@@ -68372,84 +68408,33 @@
       "dev": true
     },
     "yargs": {
-      "version": "13.3.2",
+      "version": "17.7.2",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+      "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
       "dev": true,
       "requires": {
-        "cliui": "^5.0.0",
-        "find-up": "^3.0.0",
-        "get-caller-file": "^2.0.1",
+        "cliui": "^8.0.1",
+        "escalade": "^3.1.1",
+        "get-caller-file": "^2.0.5",
         "require-directory": "^2.1.1",
-        "require-main-filename": "^2.0.0",
-        "set-blocking": "^2.0.0",
-        "string-width": "^3.0.0",
-        "which-module": "^2.0.0",
-        "y18n": "^4.0.0",
-        "yargs-parser": "^13.1.2"
+        "string-width": "^4.2.3",
+        "y18n": "^5.0.5",
+        "yargs-parser": "^21.1.1"
       },
       "dependencies": {
-        "ansi-regex": {
-          "version": "4.1.1",
-          "dev": true
-        },
-        "emoji-regex": {
-          "version": "7.0.3",
-          "dev": true
-        },
-        "find-up": {
-          "version": "3.0.0",
-          "dev": true,
-          "requires": {
-            "locate-path": "^3.0.0"
-          }
-        },
-        "is-fullwidth-code-point": {
-          "version": "2.0.0",
-          "dev": true
-        },
-        "locate-path": {
-          "version": "3.0.0",
-          "dev": true,
-          "requires": {
-            "p-locate": "^3.0.0",
-            "path-exists": "^3.0.0"
-          }
-        },
-        "p-locate": {
-          "version": "3.0.0",
-          "dev": true,
-          "requires": {
-            "p-limit": "^2.0.0"
-          }
-        },
-        "path-exists": {
-          "version": "3.0.0",
+        "y18n": {
+          "version": "5.0.8",
+          "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+          "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
           "dev": true
-        },
-        "string-width": {
-          "version": "3.1.0",
-          "dev": true,
-          "requires": {
-            "emoji-regex": "^7.0.1",
-            "is-fullwidth-code-point": "^2.0.0",
-            "strip-ansi": "^5.1.0"
-          }
-        },
-        "strip-ansi": {
-          "version": "5.2.0",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^4.1.0"
-          }
         }
       }
     },
     "yargs-parser": {
-      "version": "13.1.2",
-      "dev": true,
-      "requires": {
-        "camelcase": "^5.0.0",
-        "decamelize": "^1.2.0"
-      }
+      "version": "21.1.1",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+      "dev": true
     },
     "yauzl": {
       "version": "2.10.0",
diff --git a/package.json b/package.json
index 22913f01..82dc0df2 100644
--- a/package.json
+++ b/package.json
@@ -111,9 +111,9 @@
     "karma-jasmine-html-reporter": "^2.0.0",
     "memory-streams": "^0.1.3",
     "pngjs": "^6.0.0",
-    "prettier": "^2.1.2",
-    "prettier-eslint-cli": "^5.0.0",
-    "prettier-plugin-organize-imports": "^1.1.1",
+    "prettier": "^3.2.5",
+    "prettier-eslint-cli": "^8.0.1",
+    "prettier-plugin-organize-imports": "^3.2.4",
     "protractor": "~7.0.0",
     "react-is": "^16.13.1",
     "semantic-release": "^19.0.5",
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 7d20463f..00588f7f 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -14,7 +14,7 @@ export class AppComponent {
   constructor(
     public store: Store<AppState>,
     public world: GameWorld,
-    public notifications: NotificationService
+    public notifications: NotificationService,
   ) {
     // TODO: Game "creation" here, or state update from stored file.
     //  - "create" will setup the ngrx/store for a new game file. It will download the latest game data from
diff --git a/src/app/app.effects.ts b/src/app/app.effects.ts
index faf3656f..6d05b394 100644
--- a/src/app/app.effects.ts
+++ b/src/app/app.effects.ts
@@ -17,34 +17,46 @@ export class AppEffects {
   constructor(
     private actions$: Actions,
     private router: Router,
-    private loadingService: LoadingService
+    private loadingService: LoadingService,
   ) {}
 
   /** When the game is loading or traveling, show the loading ui. */
-  loadingIndicator$ = createEffect(() => this.actions$.pipe(
-    ofType(GameStateTravelAction.typeId),
-    distinctUntilChanged(),
-    map((action: GameStateTravelAction) => {
-      this.loadingService.message = `Traveling to ${action.payload.location}...`;
-      this.loadingService.loading = true;
-    })
-  ), { dispatch: false });
+  loadingIndicator$ = createEffect(
+    () =>
+      this.actions$.pipe(
+        ofType(GameStateTravelAction.typeId),
+        distinctUntilChanged(),
+        map((action: GameStateTravelAction) => {
+          this.loadingService.message = `Traveling to ${action.payload.location}...`;
+          this.loadingService.loading = true;
+        }),
+      ),
+    { dispatch: false },
+  );
   /** When the game is done loading or traveling, hide the loading ui. */
-  loadingDoneIndicator$ = createEffect(() => this.actions$.pipe(
-    ofType(GameStateTravelSuccessAction.typeId, GameStateTravelFailAction.typeId),
-    distinctUntilChanged(),
-    map((action: GameStateTravelSuccessAction | GameStateTravelFailAction) => {
-      this.loadingService.loading = false;
-    })
-  ), { dispatch: false });
+  loadingDoneIndicator$ = createEffect(
+    () =>
+      this.actions$.pipe(
+        ofType(GameStateTravelSuccessAction.typeId, GameStateTravelFailAction.typeId),
+        distinctUntilChanged(),
+        map((action: GameStateTravelSuccessAction | GameStateTravelFailAction) => {
+          this.loadingService.loading = false;
+        }),
+      ),
+    { dispatch: false },
+  );
 
   /** route update to world map */
-  navigateToWorldRoute$ = createEffect(() => this.actions$.pipe(
-    ofType(GameStateTravelSuccessAction.typeId),
-    debounceTime(100),
-    distinctUntilChanged(),
-    map((action: GameStateTravelSuccessAction) => {
-      this.router.navigate(['world', action.payload]);
-    })
-  ), { dispatch: false });
+  navigateToWorldRoute$ = createEffect(
+    () =>
+      this.actions$.pipe(
+        ofType(GameStateTravelSuccessAction.typeId),
+        debounceTime(100),
+        distinctUntilChanged(),
+        map((action: GameStateTravelSuccessAction) => {
+          this.router.navigate(['world', action.payload]);
+        }),
+      ),
+    { dispatch: false },
+  );
 }
diff --git a/src/app/app.imports.ts b/src/app/app.imports.ts
index b9df8a9d..266f4287 100644
--- a/src/app/app.imports.ts
+++ b/src/app/app.imports.ts
@@ -41,7 +41,8 @@ if (environment.useDevTools) {
       maxAge: 25, // Retains last 25 states
       logOnly: environment.production, // Restrict extension to log-only mode
       autoPause: true, // Pauses recording actions and state changes when the extension window is not open
-     connectInZone: true}),
+      connectInZone: true,
+    }),
   ]);
 }
 
diff --git a/src/app/app.testing.ts b/src/app/app.testing.ts
index 88f5a97d..bfdb3ccf 100644
--- a/src/app/app.testing.ts
+++ b/src/app/app.testing.ts
@@ -54,7 +54,7 @@ export function testAppGetBoarded(store: Store<AppState>): boolean {
 
 export function testAppGetKeyData(
   store: Store<AppState>,
-  keyName?: string
+  keyName?: string,
 ): boolean | undefined {
   if (!keyName) {
     return false;
@@ -73,21 +73,21 @@ export function testAppGetParty(store: Store<AppState>): IPartyMember[] {
     .select(getGameParty)
     .pipe(
       map((f) => f.toJS()),
-      take(1)
+      take(1),
     )
     .subscribe((s) => (result = s));
   return result;
 }
 
 export function testAppGetPartyWithEquipment(
-  store: Store<AppState>
+  store: Store<AppState>,
 ): EntityWithEquipment[] {
   let result: EntityWithEquipment[] = [];
   store
     .select(getGamePartyWithEquipment)
     .pipe(
       map((f) => f.toJS()),
-      take(1)
+      take(1),
     )
     .subscribe((s) => (result = s));
   return result;
@@ -99,7 +99,7 @@ export function testAppGetInventory(store: Store<AppState>): EntityItemTypes[] {
     .select(getGameInventory)
     .pipe(
       take(1),
-      map((f) => f.toJS())
+      map((f) => f.toJS()),
     )
     .subscribe((s) => (result = s));
   return result as EntityItemTypes[];
@@ -118,11 +118,11 @@ export function testAppAddToInventory<T extends Item>(
   store: Store<AppState>,
   itemId: string,
   from: ITemplateBaseItem[],
-  values?: Partial<T>
+  values?: Partial<T>,
 ): T {
   const itemInstance = instantiateEntity<T>(
     from.find((f) => f.id === itemId),
-    values
+    values,
   );
   store.dispatch(new EntityAddItemAction(itemInstance));
   store.dispatch(new GameStateAddInventoryAction(itemInstance));
@@ -132,10 +132,10 @@ export function testAppAddToInventory<T extends Item>(
 export function testAppDamageParty(
   store: Store<AppState>,
   party: EntityWithEquipment[],
-  damage: number
+  damage: number,
 ) {
   store.dispatch(
-    new GameStateHurtPartyAction({ partyIds: party.map((p) => p.eid), damage })
+    new GameStateHurtPartyAction({ partyIds: party.map((p) => p.eid), damage }),
   );
 }
 
@@ -152,7 +152,7 @@ export async function testAppLoadSprites() {
 export function testAppMockNotificationService() {
   const spy: jasmine.SpyObj<NotificationService> = jasmine.createSpyObj(
     'NotificationService',
-    ['show', 'dismiss']
+    ['show', 'dismiss'],
   );
   spy.show.and.callFake(
     (message: string, done: () => void, duration?: number): INotifyItem => {
@@ -166,7 +166,7 @@ export function testAppMockNotificationService() {
         duration: 0,
       };
       return obj;
-    }
+    },
   );
   return { provide: NotificationService, useValue: spy };
 }
diff --git a/src/app/behaviors/animated-sprite.behavior.ts b/src/app/behaviors/animated-sprite.behavior.ts
index 941f0ab0..98a07866 100644
--- a/src/app/behaviors/animated-sprite.behavior.ts
+++ b/src/app/behaviors/animated-sprite.behavior.ts
@@ -1,4 +1,3 @@
-
 import { EventEmitter } from '@angular/core';
 import * as _ from 'underscore';
 import { TileObject } from '../scene/tile-object';
@@ -23,7 +22,7 @@ export class AnimatedSpriteBehavior extends TickedBehavior {
     options: AnimatedSpriteComponentOptions = {
       lengthMS: 500,
       spriteName: null,
-    }
+    },
   ) {
     super();
     if (typeof options !== 'undefined') {
diff --git a/src/app/behaviors/base-player.behavior.ts b/src/app/behaviors/base-player.behavior.ts
index 5c64d9c3..f3305ac0 100644
--- a/src/app/behaviors/base-player.behavior.ts
+++ b/src/app/behaviors/base-player.behavior.ts
@@ -1,4 +1,3 @@
-
 import { EventEmitter } from '@angular/core';
 import * as _ from 'underscore';
 import { Point } from '../../app/core/point';
@@ -34,7 +33,7 @@ export class BasePlayerComponent extends MovableBehavior {
 
   syncBehavior(): boolean {
     this.sprite = this.host.findBehavior<PlayerRenderBehaviorComponent>(
-      PlayerRenderBehaviorComponent
+      PlayerRenderBehaviorComponent,
     );
     return super.syncBehavior();
   }
diff --git a/src/app/behaviors/camera-behavior.ts b/src/app/behaviors/camera-behavior.ts
index 82d872af..23e3425d 100644
--- a/src/app/behaviors/camera-behavior.ts
+++ b/src/app/behaviors/camera-behavior.ts
@@ -1,4 +1,3 @@
-
 import { Point } from '../../app/core/point';
 import { SceneView } from '../scene/scene-view';
 import { SceneObjectBehavior } from './scene-object-behavior';
@@ -12,7 +11,7 @@ export class CameraBehavior extends SceneObjectBehavior {
     view.cameraScale = view.context.canvas.width > 768 ? 4 : 2;
     const screenPoint = new Point(
       view.context.canvas.width,
-      view.context.canvas.height
+      view.context.canvas.height,
     );
     const canvasSize = view.screenToWorld(screenPoint, view.cameraScale);
     view.camera.extent.set(canvasSize);
diff --git a/src/app/behaviors/collision.behavior.ts b/src/app/behaviors/collision.behavior.ts
index 81c7281d..81b89da0 100644
--- a/src/app/behaviors/collision.behavior.ts
+++ b/src/app/behaviors/collision.behavior.ts
@@ -1,4 +1,3 @@
-
 import { Component } from '@angular/core';
 import { Rect } from '../../app/core/rect';
 import { SceneObject } from '../scene/scene-object';
@@ -17,7 +16,7 @@ export class CollisionBehaviorComponent extends SceneObjectBehavior {
     x: number,
     y: number,
     type: Function = SceneObject,
-    results: T[] = []
+    results: T[] = [],
   ): boolean {
     if (!this.host || !this.host.scene) {
       return false;
@@ -37,7 +36,7 @@ export class CollisionBehaviorComponent extends SceneObjectBehavior {
     const hit: boolean = this.host.scene.db.queryRect(
       this.collideBox,
       type,
-      this.resultsArray
+      this.resultsArray,
     );
     return hit ? this.resultsArray[0] : null;
   }
diff --git a/src/app/behaviors/damage.behavior.ts b/src/app/behaviors/damage.behavior.ts
index fba049d8..0d8f64dd 100644
--- a/src/app/behaviors/damage.behavior.ts
+++ b/src/app/behaviors/damage.behavior.ts
@@ -1,4 +1,3 @@
-
 import { EventEmitter } from '@angular/core';
 import { GameEntityObject } from '../scene/objects/game-entity-object';
 import { AnimatedSpriteBehavior } from './animated-sprite.behavior';
diff --git a/src/app/behaviors/movable-behavior.ts b/src/app/behaviors/movable-behavior.ts
index ef1fdc68..4b6ccf85 100644
--- a/src/app/behaviors/movable-behavior.ts
+++ b/src/app/behaviors/movable-behavior.ts
@@ -1,5 +1,3 @@
-
-
 import { Point } from '../core';
 import { KeyCode } from '../core/input';
 import { SceneObject } from '../scene/scene-object';
@@ -37,7 +35,7 @@ export class MovableBehavior extends TickedBehavior {
 
   syncBehavior(): boolean {
     this.collider = this.host.findBehavior(
-      CollisionBehaviorComponent
+      CollisionBehaviorComponent,
     ) as CollisionBehaviorComponent;
     return super.syncBehavior();
   }
diff --git a/src/app/behaviors/sound-behavior.ts b/src/app/behaviors/sound-behavior.ts
index b442d782..1339f6f6 100644
--- a/src/app/behaviors/sound-behavior.ts
+++ b/src/app/behaviors/sound-behavior.ts
@@ -1,4 +1,3 @@
-
 import { EventEmitter } from '@angular/core';
 import * as _ from 'underscore';
 import { AudioResource } from '../core';
diff --git a/src/app/behaviors/sprite-render.behavior.ts b/src/app/behaviors/sprite-render.behavior.ts
index 6107b1e0..213ee742 100644
--- a/src/app/behaviors/sprite-render.behavior.ts
+++ b/src/app/behaviors/sprite-render.behavior.ts
@@ -1,4 +1,3 @@
-
 import { AfterViewInit, Component, Input, OnDestroy } from '@angular/core';
 import { BehaviorSubject, Observable, Subscription } from 'rxjs';
 import { distinctUntilChanged, map } from 'rxjs/operators';
@@ -53,7 +52,7 @@ export class SpriteRenderBehaviorComponent
                 this.image = images[0].data;
               });
           }
-        })
+        }),
       )
       .subscribe();
   }
diff --git a/src/app/behaviors/sprite.behavior.ts b/src/app/behaviors/sprite.behavior.ts
index 556d1ca8..f3f87d99 100644
--- a/src/app/behaviors/sprite.behavior.ts
+++ b/src/app/behaviors/sprite.behavior.ts
@@ -1,4 +1,3 @@
-
 import * as _ from 'underscore';
 import { ImageResource } from '../core';
 import { ISpriteMeta } from '../core/api';
@@ -65,7 +64,7 @@ export class SpriteComponent extends SceneObjectBehavior {
     this.meta = this.host.world.sprites.getSpriteMeta(name);
     assertTrue(this.meta?.source, `invalid sprite source: ${name}`);
     const images: ImageResource[] = await this.host.world.sprites.getSpriteSheet(
-      this.meta.source
+      this.meta.source,
     );
     this.image = images[0].data;
     return this.icon;
diff --git a/src/app/behaviors/ticked-behavior.ts b/src/app/behaviors/ticked-behavior.ts
index 0fb4353c..d709a000 100644
--- a/src/app/behaviors/ticked-behavior.ts
+++ b/src/app/behaviors/ticked-behavior.ts
@@ -1,4 +1,3 @@
-
 import { SceneObjectBehavior } from './scene-object-behavior';
 /**
  * A behavior that receives tick and interpolateTick callbacks
diff --git a/src/app/behaviors/tile-map-path.behavior.ts b/src/app/behaviors/tile-map-path.behavior.ts
index ac24efb7..9109ec6c 100644
--- a/src/app/behaviors/tile-map-path.behavior.ts
+++ b/src/app/behaviors/tile-map-path.behavior.ts
@@ -1,4 +1,3 @@
-
 import * as astar from 'javascript-astar';
 import { Subscription } from 'rxjs';
 import * as _ from 'underscore';
diff --git a/src/app/behaviors/tile-object-behavior.ts b/src/app/behaviors/tile-object-behavior.ts
index 535ba938..de01e7c7 100644
--- a/src/app/behaviors/tile-object-behavior.ts
+++ b/src/app/behaviors/tile-object-behavior.ts
@@ -1,4 +1,3 @@
-
 import { EventEmitter } from '@angular/core';
 import { TileMap } from '../scene/tile-map';
 import { TileObject } from '../scene/tile-object';
diff --git a/src/app/components/animated/animated.component.ts b/src/app/components/animated/animated.component.ts
index 90329e27..e26712a0 100644
--- a/src/app/components/animated/animated.component.ts
+++ b/src/app/components/animated/animated.component.ts
@@ -139,7 +139,7 @@ export class AnimatedComponent extends TileObject {
           const interpolated: Point = task.value.interpolate(
             task.start,
             task.target,
-            factor
+            factor,
           );
           task.host.point.x = interpolated.x;
           task.host.point.y = interpolated.y;
@@ -170,7 +170,7 @@ export class AnimatedComponent extends TileObject {
         .map((cfg) => {
           assertTrue(cfg.preload, 'invalid preload function not filtered out');
           return cfg.preload(cfg);
-        })
+        }),
     );
   }
 }
diff --git a/src/app/components/debug-menu/debug-menu.component.ts b/src/app/components/debug-menu/debug-menu.component.ts
index 0363bc28..a4d610c3 100644
--- a/src/app/components/debug-menu/debug-menu.component.ts
+++ b/src/app/components/debug-menu/debug-menu.component.ts
@@ -175,7 +175,7 @@ export class DebugMenuComponent implements AfterViewInit {
             exp: gainedXp,
           };
           this.store.dispatch(new CombatVictoryAction(summary));
-        })
+        }),
       )
       .subscribe();
   }
@@ -188,7 +188,7 @@ export class DebugMenuComponent implements AfterViewInit {
       new GameStateTravelAction({
         location: map,
         position: { x, y },
-      })
+      }),
     );
   }
 
@@ -197,6 +197,6 @@ export class DebugMenuComponent implements AfterViewInit {
     public store: Store<AppState>,
     public gameStateService: GameStateService,
     public notify: NotificationService,
-    private _liveAnnouncer: LiveAnnouncer
+    private _liveAnnouncer: LiveAnnouncer,
   ) {}
 }
diff --git a/src/app/components/index.ts b/src/app/components/index.ts
index a18ae2e7..56027613 100644
--- a/src/app/components/index.ts
+++ b/src/app/components/index.ts
@@ -1,4 +1,3 @@
-
 import { CommonModule } from '@angular/common';
 import { ModuleWithProviders, NgModule } from '@angular/core';
 import { MatButtonModule as MatButtonModule } from '@angular/material/button';
diff --git a/src/app/components/loading/loading.component.scss b/src/app/components/loading/loading.component.scss
index 3473f05b..1508192a 100644
--- a/src/app/components/loading/loading.component.scss
+++ b/src/app/components/loading/loading.component.scss
@@ -38,15 +38,21 @@
   .hero-container > h1 a {
     text-decoration: none;
     color: inherit;
-    text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1), -8px 0 rgba(255, 255, 255, 0.2),
-      0px 0 rgba(0, 0, 0, 0.1), -4px 4px 0 rgba(255, 255, 255, 0.2);
+    text-shadow:
+      4px 4px 0 rgba(0, 0, 0, 0.1),
+      -8px 0 rgba(255, 255, 255, 0.2),
+      0px 0 rgba(0, 0, 0, 0.1),
+      -4px 4px 0 rgba(255, 255, 255, 0.2);
   }
 
   .hero-container p {
     padding: 15px;
     font-size: 1.2em;
-    text-shadow: -2px 0 rgba(255, 255, 255, 0.2), 1px 1px 0 rgba(0, 0, 0, 0.1),
-      -1px 1px 0 rgba(255, 255, 255, 0.2), 0px 0 rgba(0, 0, 0, 0.1);
+    text-shadow:
+      -2px 0 rgba(255, 255, 255, 0.2),
+      1px 1px 0 rgba(0, 0, 0, 0.1),
+      -1px 1px 0 rgba(255, 255, 255, 0.2),
+      0px 0 rgba(0, 0, 0, 0.1);
     color: #eeaa13;
   }
 }
diff --git a/src/app/components/notification/notification.component.ts b/src/app/components/notification/notification.component.ts
index 6c490c8e..173314da 100644
--- a/src/app/components/notification/notification.component.ts
+++ b/src/app/components/notification/notification.component.ts
@@ -1,4 +1,3 @@
-
 import { Component, ElementRef } from '@angular/core';
 import { LoadingService } from '../loading/loading.service';
 import { NotificationService } from './notification.service';
@@ -17,7 +16,7 @@ export class RPGNotificationComponent {
   constructor(
     public notify: NotificationService,
     public loadingService: LoadingService,
-    private element: ElementRef
+    private element: ElementRef,
   ) {
     notify.container = element.nativeElement;
   }
diff --git a/src/app/components/notification/notification.service.ts b/src/app/components/notification/notification.service.ts
index 84ebb758..f4ea8241 100644
--- a/src/app/components/notification/notification.service.ts
+++ b/src/app/components/notification/notification.service.ts
@@ -1,4 +1,3 @@
-
 import { Injectable } from '@angular/core';
 import { IProcessObject } from '../../../app/core/time';
 import { IWorldObject } from '../../../app/core/world';
diff --git a/src/app/components/party-inventory/party-inventory.component.ts b/src/app/components/party-inventory/party-inventory.component.ts
index 4570323c..4a39a468 100644
--- a/src/app/components/party-inventory/party-inventory.component.ts
+++ b/src/app/components/party-inventory/party-inventory.component.ts
@@ -77,7 +77,7 @@ export class PartyInventoryComponent implements OnDestroy {
         return party.count() - 1;
       }
       return index;
-    })
+    }),
   );
 
   /** The currently selected player entity with its equipment resolved to items rather than item ids */
@@ -87,7 +87,7 @@ export class PartyInventoryComponent implements OnDestroy {
     }),
     switchMap((entity: Entity) => {
       return entity?.eid ? this.store.select(getEntityEquipment(entity.eid)) : EMPTY;
-    })
+    }),
   );
   /** Stream of inventory that the currentEntity$ can equip */
   inventory$: Observable<EntityItemTypes[]> = this.store.select(getGameInventory).pipe(
@@ -114,8 +114,8 @@ export class PartyInventoryComponent implements OnDestroy {
           })
           .toList()
           .toJS();
-      }
-    )
+      },
+    ),
   );
   /** Action generator from equip stream */
   private _equipSubscription: Subscription = this.doEquip$
@@ -134,7 +134,7 @@ export class PartyInventoryComponent implements OnDestroy {
                 entityId: entity.eid,
                 slot: slot,
                 itemId: oldItem.eid,
-              })
+              }),
             );
           }
           this.store.dispatch(
@@ -142,10 +142,10 @@ export class PartyInventoryComponent implements OnDestroy {
               entityId: entity.eid,
               slot: slot,
               itemId: event.item.eid,
-            })
+            }),
           );
-        }
-      )
+        },
+      ),
     )
     .subscribe();
 
@@ -161,10 +161,10 @@ export class PartyInventoryComponent implements OnDestroy {
               entityId: entity.eid,
               slot: slot,
               itemId: event.item.eid,
-            })
+            }),
           );
-        }
-      )
+        },
+      ),
     )
     .subscribe();
 
@@ -172,7 +172,7 @@ export class PartyInventoryComponent implements OnDestroy {
     public game: RPGGame,
     public store: Store<AppState>,
     public combatService: CombatService,
-    public notify: NotificationService
+    public notify: NotificationService,
   ) {}
 
   ngOnDestroy(): void {
diff --git a/src/app/components/party-menu/party-menu.component.scss b/src/app/components/party-menu/party-menu.component.scss
index b7c51900..134a61e1 100644
--- a/src/app/components/party-menu/party-menu.component.scss
+++ b/src/app/components/party-menu/party-menu.component.scss
@@ -98,7 +98,9 @@
     max-width: 600px;
     max-height: 500px;
     overflow-y: auto;
-    transition: max-width 0.2s ease-out 0.2s, max-height 0.2s ease-out 0.2s,
+    transition:
+      max-width 0.2s ease-out 0.2s,
+      max-height 0.2s ease-out 0.2s,
       font-size 0.2s ease-in 0.1s;
     @media (min-width: 961px) {
       /* tablet, landscape iPad, lo-res laptops ands desktops */
diff --git a/src/app/components/party-menu/party-menu.component.ts b/src/app/components/party-menu/party-menu.component.ts
index 5726ac74..ec3c8149 100644
--- a/src/app/components/party-menu/party-menu.component.ts
+++ b/src/app/components/party-menu/party-menu.component.ts
@@ -86,6 +86,6 @@ export class PartyMenuComponent {
     public game: RPGGame,
     public store: Store<AppState>,
     public gameStateService: GameStateService,
-    public notify: NotificationService
+    public notify: NotificationService,
   ) {}
 }
diff --git a/src/app/components/player-card/player-card.component.ts b/src/app/components/player-card/player-card.component.ts
index 14e0cda8..fc25b1b1 100644
--- a/src/app/components/player-card/player-card.component.ts
+++ b/src/app/components/player-card/player-card.component.ts
@@ -20,5 +20,8 @@ export class PlayerCardComponent {
     this._model$.next(value);
   }
 
-  constructor(public game: RPGGame, public store: Store<AppState>) {}
+  constructor(
+    public game: RPGGame,
+    public store: Store<AppState>,
+  ) {}
 }
diff --git a/src/app/components/player-stats/player-stats.component.ts b/src/app/components/player-stats/player-stats.component.ts
index 33f7fe2f..d7eb9453 100644
--- a/src/app/components/player-stats/player-stats.component.ts
+++ b/src/app/components/player-stats/player-stats.component.ts
@@ -64,7 +64,7 @@ export class PlayerStatsComponent {
   entityWithEquipment$ = this.model$.pipe(
     switchMap((entity: EntityWithEquipment) => {
       return entity?.eid ? this.store.select(getEntityEquipment(entity.eid)) : EMPTY;
-    })
+    }),
   );
 
   /**
@@ -87,7 +87,7 @@ export class PlayerStatsComponent {
         equipment,
         state: equipped,
       });
-    })
+    }),
   );
   /**
    * Total defense including armor and accessories
@@ -96,7 +96,7 @@ export class PlayerStatsComponent {
     map((equipped: EntityWithEquipment) => {
       const equipment = this.combatService.getArmors(equipped);
       return this.combatService.party.getDefense({ equipment, state: equipped });
-    })
+    }),
   );
   /**
    * Total evasion including armor and accessories
@@ -105,7 +105,7 @@ export class PlayerStatsComponent {
     map((equipped: EntityWithEquipment) => {
       const equipment = this.combatService.getArmors(equipped);
       return this.combatService.party.getEvasion({ equipment, state: equipped });
-    })
+    }),
   );
 
   /**
@@ -114,7 +114,7 @@ export class PlayerStatsComponent {
   nextLevelExp$: Observable<number> = this.model$.pipe(
     map((entity: EntityWithEquipment) => {
       return entity ? getXPForLevel(entity.level + 1) : 0;
-    })
+    }),
   );
 
   /**
@@ -133,7 +133,7 @@ export class PlayerStatsComponent {
           ((entity.exp - currentLevelExp) / (nextLevelExp - currentLevelExp)) * 100;
       }
       return Math.round(width);
-    })
+    }),
   );
 
   /**
@@ -142,13 +142,13 @@ export class PlayerStatsComponent {
   healthPercentage$: Observable<number> = this.model$.pipe(
     map((entity: EntityWithEquipment) => {
       return entity ? Math.round((entity.hp / entity.maxhp) * 100) : 0;
-    })
+    }),
   );
 
   constructor(
     public game: RPGGame,
     public world: GameWorld,
     public combatService: CombatService,
-    public store: Store<AppState>
+    public store: Store<AppState>,
   ) {}
 }
diff --git a/src/app/components/sprite/sprite.component.ts b/src/app/components/sprite/sprite.component.ts
index f25238c1..3f33149d 100644
--- a/src/app/components/sprite/sprite.component.ts
+++ b/src/app/components/sprite/sprite.component.ts
@@ -69,10 +69,13 @@ export class RPGSpriteComponent {
   private static _renderCanvas: HTMLCanvasElement;
   private _canvasAcquired: boolean = false;
 
-  constructor(private sanitizer: DomSanitizer, private renderer: SpriteRender) {
+  constructor(
+    private sanitizer: DomSanitizer,
+    private renderer: SpriteRender,
+  ) {
     if (!RPGSpriteComponent._renderCanvas) {
       RPGSpriteComponent._renderCanvas = document.createElement(
-        'canvas'
+        'canvas',
       ) as HTMLCanvasElement;
       RPGSpriteComponent._renderCanvas.width =
         RPGSpriteComponent._renderCanvas.height = 64;
@@ -90,7 +93,7 @@ export class RPGSpriteComponent {
     if (this._canvasAcquired) {
       throw new Error(
         'Only one rendering canvas is available at a time.' +
-          ' Check for calls to this function without corresponding releaseCanvas() calls.'
+          ' Check for calls to this function without corresponding releaseCanvas() calls.',
       );
     }
     this._canvasAcquired = true;
@@ -129,7 +132,7 @@ export class RPGSpriteComponent {
         renderContext.clearRect(0, 0, width, height);
         renderContext.drawImage(sprite, 0, 0, width, height);
         const imageDataUrl = this.sanitizer.bypassSecurityTrustResourceUrl(
-          this.releaseRenderContext()
+          this.releaseRenderContext(),
         );
         this._dataUrl$.next(imageDataUrl);
       });
diff --git a/src/app/components/sprite/sprite.stories.ts b/src/app/components/sprite/sprite.stories.ts
index 1ac0adf7..4c899f3d 100644
--- a/src/app/components/sprite/sprite.stories.ts
+++ b/src/app/components/sprite/sprite.stories.ts
@@ -17,7 +17,10 @@ interface ISpriteInputs {
   template: `<rpg-sprite [width]="width" [height]="height" [name]="name"></rpg-sprite>`,
 })
 class Wrapper implements AfterViewInit {
-  constructor(public store: Store<AppState>, public loadingService: LoadingService) {}
+  constructor(
+    public store: Store<AppState>,
+    public loadingService: LoadingService,
+  ) {}
   @Input() width: number;
   @Input() height: number;
   @Input() name: string;
diff --git a/src/app/core/animator.ts b/src/app/core/animator.ts
index 3e1372b0..af3ef20d 100644
--- a/src/app/core/animator.ts
+++ b/src/app/core/animator.ts
@@ -1,4 +1,3 @@
-
 import { getSpriteMeta } from './api';
 /**
  * Really Janky class to play animations associated with a pow2 sprite.
diff --git a/src/app/core/api.ts b/src/app/core/api.ts
index 3474f0fc..587c6e9f 100644
--- a/src/app/core/api.ts
+++ b/src/app/core/api.ts
@@ -1,4 +1,3 @@
-
 import * as _ from 'underscore';
 
 export const NAME: string = 'core';
diff --git a/src/app/core/behavior-host.ts b/src/app/core/behavior-host.ts
index 696b06f6..078e2c4d 100644
--- a/src/app/core/behavior-host.ts
+++ b/src/app/core/behavior-host.ts
@@ -90,7 +90,7 @@ export class BehaviorHost implements IBehaviorHost {
 
   removeBehaviorByType<T extends IBehavior>(
     componentType: any,
-    silent: boolean = false
+    silent: boolean = false,
   ): boolean {
     const component = this.findBehavior<T>(componentType);
     if (!component) {
diff --git a/src/app/core/behavior.ts b/src/app/core/behavior.ts
index 6cd70559..17173af7 100644
--- a/src/app/core/behavior.ts
+++ b/src/app/core/behavior.ts
@@ -1,4 +1,3 @@
-
 import * as _ from 'underscore';
 import { BehaviorHost } from './behavior-host';
 /**
diff --git a/src/app/core/errors.ts b/src/app/core/errors.ts
index 79181172..a3665712 100644
--- a/src/app/core/errors.ts
+++ b/src/app/core/errors.ts
@@ -1,5 +1,3 @@
-
-
 /**
  * Constant strings for use in throwing Error with messages.  Used to
  * make checking thrown errors doable without an explosion of Error subclasses.
diff --git a/src/app/core/input.ts b/src/app/core/input.ts
index 3a42481f..f4689ca3 100644
--- a/src/app/core/input.ts
+++ b/src/app/core/input.ts
@@ -1,4 +1,3 @@
-
 import * as $ from 'jquery';
 import * as _ from 'underscore';
 import { assertTrue } from '../models/util';
diff --git a/src/app/core/point.ts b/src/app/core/point.ts
index e1a0cbd1..515207e6 100644
--- a/src/app/core/point.ts
+++ b/src/app/core/point.ts
@@ -1,4 +1,3 @@
-
 import { errors } from './errors';
 
 export interface IPoint {
diff --git a/src/app/core/rect.spec.ts b/src/app/core/rect.spec.ts
index 05f3f89c..5d5afe30 100644
--- a/src/app/core/rect.spec.ts
+++ b/src/app/core/rect.spec.ts
@@ -201,7 +201,7 @@ describe('Rect', () => {
     it('should return half of the extent of the rectangle', () => {
       expect(new Rect(5, 5, 10, 10).getHalfSize().equal(new Point(5, 5))).toBeTruthy();
       expect(
-        new Rect(0, 0, 9, 9).getHalfSize().equal(new Point(4.5, 4.5))
+        new Rect(0, 0, 9, 9).getHalfSize().equal(new Point(4.5, 4.5)),
       ).toBeTruthy();
     });
   });
diff --git a/src/app/core/rect.ts b/src/app/core/rect.ts
index d2f03f44..78d96902 100644
--- a/src/app/core/rect.ts
+++ b/src/app/core/rect.ts
@@ -1,4 +1,3 @@
-
 import { errors } from './errors';
 import { IPoint, Point } from './point';
 export interface IRect {
diff --git a/src/app/core/resource.ts b/src/app/core/resource.ts
index 798ed8b2..7aa5fc8b 100644
--- a/src/app/core/resource.ts
+++ b/src/app/core/resource.ts
@@ -1,4 +1,3 @@
-
 import { errors } from './errors';
 
 export interface IResource {
@@ -15,7 +14,10 @@ export interface IResource {
 export class Resource implements IResource {
   extension: string;
 
-  constructor(public url: string | null = null, public data: any = null) {}
+  constructor(
+    public url: string | null = null,
+    public data: any = null,
+  ) {}
 
   load(data?: any): Promise<Resource> {
     return Promise.reject(errors.CLASS_NOT_IMPLEMENTED);
diff --git a/src/app/core/resources/audio.resource.ts b/src/app/core/resources/audio.resource.ts
index a57910aa..4a80f598 100644
--- a/src/app/core/resources/audio.resource.ts
+++ b/src/app/core/resources/audio.resource.ts
@@ -1,4 +1,3 @@
-
 import * as _ from 'underscore';
 import { assertTrue } from '../../models/util';
 import { errors } from '../errors';
diff --git a/src/app/core/resources/image.resource.ts b/src/app/core/resources/image.resource.ts
index 6d707230..b0864078 100644
--- a/src/app/core/resources/image.resource.ts
+++ b/src/app/core/resources/image.resource.ts
@@ -1,4 +1,3 @@
-
 import { assertTrue } from '../../models/util';
 import { Resource } from '../resource';
 /**
diff --git a/src/app/core/resources/json.resource.ts b/src/app/core/resources/json.resource.ts
index 281064ec..b5b967e1 100644
--- a/src/app/core/resources/json.resource.ts
+++ b/src/app/core/resources/json.resource.ts
@@ -1,4 +1,3 @@
-
 import * as $ from 'jquery';
 import { assertTrue } from '../../models/util';
 import { Resource } from '../resource';
diff --git a/src/app/core/resources/tiled/tiled-tmx.resource.ts b/src/app/core/resources/tiled/tiled-tmx.resource.ts
index e746de93..f87b85e8 100644
--- a/src/app/core/resources/tiled/tiled-tmx.resource.ts
+++ b/src/app/core/resources/tiled/tiled-tmx.resource.ts
@@ -1,4 +1,3 @@
-
 import 'jquery';
 import * as $ from 'jquery';
 import * as _ from 'underscore';
@@ -113,7 +112,7 @@ export class TiledTMXResource extends XMLResource {
         const source: string = this.getElAttribute(ts, 'source');
         const firstGid: number = parseInt(
           this.getElAttribute(ts, 'firstgid') || '-1',
-          10
+          10,
         );
         if (source) {
           tileSetDeps.push({
@@ -147,7 +146,7 @@ export class TiledTMXResource extends XMLResource {
           if (!encoding || encoding.toLowerCase() !== 'csv') {
             failed = true;
             return reject(
-              `pow-core only supports CSV maps. Edit the Map Properties (for:${this.url}) to use the CSV`
+              `pow-core only supports CSV maps. Edit the Map Properties (for:${this.url}) to use the CSV`,
             );
           }
           tileLayer.data = JSON.parse('[' + $.trim(layerData.text()) + ']');
diff --git a/src/app/core/resources/tiled/tiled-tsx.resource.ts b/src/app/core/resources/tiled/tiled-tsx.resource.ts
index bd1f903e..d2b6bbc5 100644
--- a/src/app/core/resources/tiled/tiled-tsx.resource.ts
+++ b/src/app/core/resources/tiled/tiled-tsx.resource.ts
@@ -1,4 +1,3 @@
-
 import * as _ from 'underscore';
 import { assertTrue } from '../../../models/util';
 import { ImageResource } from '../image.resource';
@@ -12,7 +11,7 @@ export class TilesetTile {
     public id: number,
     public image: string,
     public width: number,
-    public height: number
+    public height: number,
   ) {}
 }
 /**
@@ -54,7 +53,7 @@ export class TiledTSXResource extends XMLResource {
         const sourceImage = this.getChild(ts, 'image');
         if (!sourceImage) {
           throw new Error(
-            'tileset tiles must be image collections that reference the soruce sprite image'
+            'tileset tiles must be image collections that reference the soruce sprite image',
           );
         }
         // extract only the filename from the source image path
@@ -71,7 +70,7 @@ export class TiledTSXResource extends XMLResource {
       assertTrue(source, `invalid source name in tileset: ${source}`);
       this.imageUrl = compactUrl(
         this.relativeTo ? this.relativeTo : relativePath,
-        source
+        source,
       );
 
       new ImageResource(this.imageUrl)
diff --git a/src/app/core/resources/tiled/tiled.ts b/src/app/core/resources/tiled/tiled.ts
index 633266ae..49dcc7b8 100644
--- a/src/app/core/resources/tiled/tiled.ts
+++ b/src/app/core/resources/tiled/tiled.ts
@@ -168,7 +168,7 @@ export function getChildren(el: any, tag: string): any[] {
     _.map(list, (c: any) => {
       const child: any = $(c);
       return child.parent()[0] !== el[0] ? null : child;
-    })
+    }),
   );
 }
 
diff --git a/src/app/core/resources/xml.resource.ts b/src/app/core/resources/xml.resource.ts
index eebcd6f9..23b14657 100644
--- a/src/app/core/resources/xml.resource.ts
+++ b/src/app/core/resources/xml.resource.ts
@@ -1,4 +1,3 @@
-
 import * as $ from 'jquery';
 import * as _ from 'underscore';
 import { Resource } from '../resource';
@@ -53,7 +52,7 @@ export class XMLResource extends Resource {
       _.map(list, (c: any) => {
         const child: any = $(c);
         return (child.parent()[0] !== el[0] ? null : child) as T;
-      })
+      }),
     );
   }
 
diff --git a/src/app/core/state-machine.ts b/src/app/core/state-machine.ts
index 08c86397..425ea1ee 100644
--- a/src/app/core/state-machine.ts
+++ b/src/app/core/state-machine.ts
@@ -1,4 +1,3 @@
-
 // State Machine Interfaces
 // -------------------------------------------------------------------------
 import { EventEmitter } from '@angular/core';
@@ -78,7 +77,7 @@ export class StateMachine<StateNames extends string> {
     // Already in the desired state.
     if (this._currentState && state.name === this._currentState.name) {
       console.warn(
-        `${this._currentState.name}: Attempting to set current state to already active state`
+        `${this._currentState.name}: Attempting to set current state to already active state`,
       );
       return true;
     }
@@ -94,7 +93,7 @@ export class StateMachine<StateNames extends string> {
     // DEBUG:
     if (StateMachine.DEBUG_STATES) {
       console.log(
-        `STATE: ${oldState ? oldState.name : 'NULL'} -> ${this._currentState.name}`
+        `STATE: ${oldState ? oldState.name : 'NULL'} -> ${this._currentState.name}`,
       );
     }
     if (oldState) {
@@ -151,7 +150,7 @@ export class StateAsyncEmitter<T> extends EventEmitter<T> {
   notifyWait(): IResumeCallback {
     if (!this._asyncCurrentCallback) {
       throw new Error(
-        'No valid async callback set!  Perhaps you called this outside of a notify event handler?'
+        'No valid async callback set!  Perhaps you called this outside of a notify event handler?',
       );
     }
     this._asyncProcessing++;
diff --git a/src/app/core/state.ts b/src/app/core/state.ts
index 9f8ca70f..01cceb3f 100644
--- a/src/app/core/state.ts
+++ b/src/app/core/state.ts
@@ -1,4 +1,3 @@
-
 // State Interfaces
 // -------------------------------------------------------------------------
 
diff --git a/src/app/core/time.ts b/src/app/core/time.ts
index db30972f..41172a2c 100644
--- a/src/app/core/time.ts
+++ b/src/app/core/time.ts
@@ -1,4 +1,3 @@
-
 import { Injectable } from '@angular/core';
 import * as _ from 'underscore';
 
diff --git a/src/app/core/world.ts b/src/app/core/world.ts
index 616ea220..f88bea07 100644
--- a/src/app/core/world.ts
+++ b/src/app/core/world.ts
@@ -1,4 +1,3 @@
-
 import { Injectable } from '@angular/core';
 import { Time } from './time';
 
diff --git a/src/app/models/combat/combat.effects.ts b/src/app/models/combat/combat.effects.ts
index 3892c4f0..38941843 100644
--- a/src/app/models/combat/combat.effects.ts
+++ b/src/app/models/combat/combat.effects.ts
@@ -40,130 +40,144 @@ export class CombatEffects {
     private store: Store<AppState>,
     private notificationService: NotificationService,
     private combatService: CombatService,
-    private router: Router
+    private router: Router,
   ) {}
 
-  beginCombat$ = createEffect(() => this.actions$.pipe(
-    ofType(CombatEncounterAction.typeId),
-    switchMap((action: CombatEncounterAction) => {
-      return this.combatService.loadEncounter(action.payload);
-    }),
-    map((encounter: CombatEncounter) => {
-      return new CombatEncounterReadyAction(encounter);
-    }),
-    catchError((e) => {
-      return of(new CombatEncounterErrorAction(e.toString()));
-    })
-  ))
+  beginCombat$ = createEffect(() =>
+    this.actions$.pipe(
+      ofType(CombatEncounterAction.typeId),
+      switchMap((action: CombatEncounterAction) => {
+        return this.combatService.loadEncounter(action.payload);
+      }),
+      map((encounter: CombatEncounter) => {
+        return new CombatEncounterReadyAction(encounter);
+      }),
+      catchError((e) => {
+        return of(new CombatEncounterErrorAction(e.toString()));
+      }),
+    ),
+  );
 
   /** route update to combat encounter */
-  navigateToCombatRoute$ = createEffect(() => this.actions$.pipe(
-    ofType(CombatEncounterReadyAction.typeId),
-    debounceTime(100),
-    distinctUntilChanged(),
-    map((action: CombatEncounterAction) => {
-      const encounter: CombatEncounter = action.payload;
-      assertTrue(
-        encounter.id || encounter.zone,
-        'combat must either be in a zone or have an id'
-      );
-      return this.router.navigate(['combat', encounter.id || encounter.zone]);
-    })
-  ), { dispatch: false });
+  navigateToCombatRoute$ = createEffect(
+    () =>
+      this.actions$.pipe(
+        ofType(CombatEncounterReadyAction.typeId),
+        debounceTime(100),
+        distinctUntilChanged(),
+        map((action: CombatEncounterAction) => {
+          const encounter: CombatEncounter = action.payload;
+          assertTrue(
+            encounter.id || encounter.zone,
+            'combat must either be in a zone or have an id',
+          );
+          return this.router.navigate(['combat', encounter.id || encounter.zone]);
+        }),
+      ),
+    { dispatch: false },
+  );
 
   /**
    * When a combat escape action is dispatched
    */
-  combatEscape$ = createEffect(() => this.actions$.pipe(
-    ofType(CombatEscapeAction.typeId),
-    map((action: CombatEscapeAction) => {
-      // TODO: add a switcMap before this and notify something?
-      return new CombatEscapeCompleteAction();
-    })
-  ))
+  combatEscape$ = createEffect(() =>
+    this.actions$.pipe(
+      ofType(CombatEscapeAction.typeId),
+      map((action: CombatEscapeAction) => {
+        // TODO: add a switcMap before this and notify something?
+        return new CombatEscapeCompleteAction();
+      }),
+    ),
+  );
 
   /**
    * When a combat victory action is dispatched, notify the user about what they've won.
    */
-  combatVictory$ = createEffect(() => this.actions$.pipe(
-    ofType(CombatVictoryAction.typeId),
-    switchMap((action: CombatVictoryAction) => {
-      const data: CombatVictorySummary = action.payload;
-      return new Observable((subject: Subscriber<CombatVictoryAction>) => {
-        // Gold
-        this.notificationService.show(`Found ${data.gold} gold!`, undefined, 0);
-        // Looted items
-        if (data.items) {
-          data.items.forEach((item: Item) => {
-            this.notificationService.show(`Found ${item.name}`, undefined, 0);
+  combatVictory$ = createEffect(() =>
+    this.actions$.pipe(
+      ofType(CombatVictoryAction.typeId),
+      switchMap((action: CombatVictoryAction) => {
+        const data: CombatVictorySummary = action.payload;
+        return new Observable((subject: Subscriber<CombatVictoryAction>) => {
+          // Gold
+          this.notificationService.show(`Found ${data.gold} gold!`, undefined, 0);
+          // Looted items
+          if (data.items) {
+            data.items.forEach((item: Item) => {
+              this.notificationService.show(`Found ${item.name}`, undefined, 0);
+            });
+          }
+          // Experience
+          this.notificationService.show(`Gained ${data.exp} experience!`, undefined, 0);
+          // Party Level ups
+
+          data.levels.forEach((entityDiff: IPartyStatsDiff) => {
+            this.notificationService.show(
+              `${entityDiff.name} reached level ${entityDiff.level}!`,
+              undefined,
+              0,
+            );
+            let note = '\n';
+            if (entityDiff.hp > 0) {
+              note += `HP went up by ${entityDiff.hp}\n\n`;
+            }
+            if (entityDiff.mp > 0) {
+              note += `MP went up by ${entityDiff.mp}\n\n`;
+            }
+            if (entityDiff.strength > 0) {
+              note += `Strength went up by ${entityDiff.strength}\n\n`;
+            }
+            if (entityDiff.agility > 0) {
+              note += `Agility went up by ${entityDiff.agility}\n\n`;
+            }
+            if (entityDiff.intelligence > 0) {
+              note += `Intelligence went up by ${entityDiff.intelligence}\n\n`;
+            }
+            if (entityDiff.luck > 0) {
+              note += `Luck went up by ${entityDiff.luck}\n\n`;
+            }
+            if (note !== '\n') {
+              this.notificationService.show(note, undefined, 0);
+            }
+          });
+          // Fin.
+          this.notificationService.show('Enemies Defeated!', () => {
+            subject.next(action);
+            subject.complete();
           });
-        }
-        // Experience
-        this.notificationService.show(`Gained ${data.exp} experience!`, undefined, 0);
-        // Party Level ups
 
-        data.levels.forEach((entityDiff: IPartyStatsDiff) => {
-          this.notificationService.show(
-            `${entityDiff.name} reached level ${entityDiff.level}!`,
-            undefined,
-            0
-          );
-          let note = '\n';
-          if (entityDiff.hp > 0) {
-            note += `HP went up by ${entityDiff.hp}\n\n`;
-          }
-          if (entityDiff.mp > 0) {
-            note += `MP went up by ${entityDiff.mp}\n\n`;
-          }
-          if (entityDiff.strength > 0) {
-            note += `Strength went up by ${entityDiff.strength}\n\n`;
-          }
-          if (entityDiff.agility > 0) {
-            note += `Agility went up by ${entityDiff.agility}\n\n`;
+          // Also, hide the encounter if it was fixed.
+          if (data.type === 'fixed') {
+            this.store.dispatch(new GameStateSetKeyDataAction(data.id, true));
           }
-          if (entityDiff.intelligence > 0) {
-            note += `Intelligence went up by ${entityDiff.intelligence}\n\n`;
-          }
-          if (entityDiff.luck > 0) {
-            note += `Luck went up by ${entityDiff.luck}\n\n`;
-          }
-          if (note !== '\n') {
-            this.notificationService.show(note, undefined, 0);
-          }
-        });
-        // Fin.
-        this.notificationService.show('Enemies Defeated!', () => {
-          subject.next(action);
-          subject.complete();
-        });
-
-        // Also, hide the encounter if it was fixed.
-        if (data.type === 'fixed') {
-          this.store.dispatch(new GameStateSetKeyDataAction(data.id, true));
-        }
 
-        return () => {
-          // No cleanup
-        };
-      });
-    }),
-    map((action: CombatVictoryAction) => {
-      return new CombatVictoryCompleteAction(action.payload);
-    })
-  ))
+          return () => {
+            // No cleanup
+          };
+        });
+      }),
+      map((action: CombatVictoryAction) => {
+        return new CombatVictoryCompleteAction(action.payload);
+      }),
+    ),
+  );
 
   /** route update back to map after a combat encounter */
-  navigateToMapRoute$ = createEffect(() => this.actions$.pipe(
-    ofType(CombatVictoryCompleteAction.typeId, CombatEscapeCompleteAction.typeId),
-    debounceTime(100),
-    switchMap(() => this.store.select(getGameMap)),
-    map((targetMap: string) => {
-      assertTrue(map, 'cannot return to invalid map from combat');
-      // Save game
-      if (localStorage.getItem('autoSave') === 'true') {
-        this.store.dispatch(new GameStateSaveAction());
-      }
-      return this.router.navigate(['world', targetMap]);
-    })
-  ), { dispatch: false });
+  navigateToMapRoute$ = createEffect(
+    () =>
+      this.actions$.pipe(
+        ofType(CombatVictoryCompleteAction.typeId, CombatEscapeCompleteAction.typeId),
+        debounceTime(100),
+        switchMap(() => this.store.select(getGameMap)),
+        map((targetMap: string) => {
+          assertTrue(map, 'cannot return to invalid map from combat');
+          // Save game
+          if (localStorage.getItem('autoSave') === 'true') {
+            this.store.dispatch(new GameStateSaveAction());
+          }
+          return this.router.navigate(['world', targetMap]);
+        }),
+      ),
+    { dispatch: false },
+  );
 }
diff --git a/src/app/models/combat/combat.reducer.spec.ts b/src/app/models/combat/combat.reducer.spec.ts
index 01093f88..25fd9ff0 100644
--- a/src/app/models/combat/combat.reducer.spec.ts
+++ b/src/app/models/combat/combat.reducer.spec.ts
@@ -38,7 +38,7 @@ function combatant(values?: Partial<CombatantTypes>): CombatantTypes {
       hp: 0,
       maxhp: 0,
     },
-    values || {}
+    values || {},
   ) as any;
 }
 
@@ -74,7 +74,7 @@ describe('Combat', () => {
         expect(state.party.count()).toBe(1);
         const actual = combatReducer(
           state,
-          new CombatVictoryCompleteAction(victorySummary)
+          new CombatVictoryCompleteAction(victorySummary),
         );
         expect(actual.enemies.count()).toBe(0);
         expect(actual.party.count()).toBe(0);
@@ -85,7 +85,7 @@ describe('Combat', () => {
         expect(() => {
           combatReducer(
             combatStateFactory(),
-            new CombatAttackAction(attack(combatant(), combatant(), 0))
+            new CombatAttackAction(attack(combatant(), combatant(), 0)),
           );
         }).toThrow();
       });
@@ -100,7 +100,7 @@ describe('Combat', () => {
         });
         const actual = combatReducer(
           state,
-          new CombatAttackAction(attack(attacker, defender, 3))
+          new CombatAttackAction(attack(attacker, defender, 3)),
         );
         expect(actual.party.get(0).hp).toBe(2);
       });
@@ -115,7 +115,7 @@ describe('Combat', () => {
         });
         const actual = combatReducer(
           state,
-          new CombatAttackAction(attack(attacker, defender, 13))
+          new CombatAttackAction(attack(attacker, defender, 13)),
         );
         expect(actual.party.get(0).hp).toBe(0);
       });
@@ -130,7 +130,7 @@ describe('Combat', () => {
         });
         const actual = combatReducer(
           state,
-          new CombatAttackAction(attack(attacker, defender, -10))
+          new CombatAttackAction(attack(attacker, defender, -10)),
         );
         expect(actual.party.get(0).hp).toBe(5);
       });
@@ -145,7 +145,7 @@ describe('Combat', () => {
         });
         const actual = combatReducer(
           state,
-          new CombatAttackAction(attack(attacker, defender, -4))
+          new CombatAttackAction(attack(attacker, defender, -4)),
         );
         expect(actual.party.get(0).hp).toBe(5);
       });
@@ -160,7 +160,7 @@ describe('Combat', () => {
         });
         const actual = combatReducer(
           state,
-          new CombatAttackAction(attack(attacker, defender, 3))
+          new CombatAttackAction(attack(attacker, defender, 3)),
         );
         expect(actual.enemies.get(0).hp).toBe(2);
       });
@@ -183,7 +183,7 @@ describe('Combat', () => {
         });
         const actual = combatReducer(
           state,
-          new CombatAttackAction(attack(attacker, defender, 10))
+          new CombatAttackAction(attack(attacker, defender, 10)),
         );
         expect(actual.enemies.get(0).hp).toBe(0);
       });
diff --git a/src/app/models/combat/combat.reducer.ts b/src/app/models/combat/combat.reducer.ts
index d067f6ff..891fbbf6 100644
--- a/src/app/models/combat/combat.reducer.ts
+++ b/src/app/models/combat/combat.reducer.ts
@@ -60,7 +60,7 @@ export function combatFromJSON(object: CombatState): CombatState {
 
 export function combatReducer(
   state: CombatStateRecord = combatStateFactory(),
-  action: CombatActions
+  action: CombatActions,
 ): CombatStateRecord {
   switch (action.type) {
     case CombatEncounterAction.typeId: {
@@ -138,7 +138,7 @@ export function combatReducer(
           assertTrue(current, 'invalid target for attack action');
           const newHp: number = Math.min(
             current.maxhp || 10000,
-            Math.max(current.hp - data.damage, 0)
+            Math.max(current.hp - data.damage, 0),
           );
           return items.set(index, {
             ...current,
@@ -155,7 +155,7 @@ export function combatReducer(
           assertTrue(current, 'invalid target for attack action');
           const newHp: number = Math.min(
             current.maxhp || 10000,
-            Math.max(current.hp - data.damage, 0)
+            Math.max(current.hp - data.damage, 0),
           );
           return items.set(index, {
             ...current,
@@ -165,7 +165,7 @@ export function combatReducer(
       }
       assertTrue(
         index !== -1,
-        'attack target found in neither enemies nor party lists'
+        'attack target found in neither enemies nor party lists',
       );
       return state;
     }
diff --git a/src/app/models/combat/combat.service.ts b/src/app/models/combat/combat.service.ts
index bcf6fc9e..9b6c41cf 100644
--- a/src/app/models/combat/combat.service.ts
+++ b/src/app/models/combat/combat.service.ts
@@ -54,7 +54,7 @@ export class CombatService {
         });
         this._combatMap$.next(result);
         return result;
-      })
+      }),
     );
   }
 
@@ -74,7 +74,7 @@ export class CombatService {
    */
   attackCombatant(
     attacker: CombatantTypes | EntityWithEquipment,
-    defender: CombatantTypes | EntityWithEquipment
+    defender: CombatantTypes | EntityWithEquipment,
   ): ICombatDamage {
     const attackerEntity = attacker as EntityWithEquipment;
     const defenderEntity = defender as EntityWithEquipment;
@@ -103,7 +103,7 @@ export class CombatService {
           inventory: config.inventory.slice() as EntityItemTypes[],
           weapons: this.getWeapons(entity),
         };
-      }
+      },
     );
 
     const casterEntity = config.caster as EntityWithEquipment;
diff --git a/src/app/models/entity-collections.ts b/src/app/models/entity-collections.ts
index 06b11d12..62e24724 100644
--- a/src/app/models/entity-collections.ts
+++ b/src/app/models/entity-collections.ts
@@ -28,7 +28,7 @@ export interface EntityCollectionRecord
 export function addEntityToCollection(
   collection: EntityCollectionRecord,
   entity: EntityCollectionItem,
-  entityId: string
+  entityId: string,
 ): EntityCollectionRecord {
   const index = collection.allIds.indexOf(entityId);
   assertTrue(index === -1, `item (${entityId}) already exists in collection`);
@@ -39,7 +39,7 @@ export function addEntityToCollection(
     ['byId'],
     (byId: Immutable.Map<string, EntityCollectionItem>) => {
       return byId.set(entityId, entity);
-    }
+    },
   );
 }
 
@@ -50,14 +50,14 @@ export function addEntityToCollection(
 export function mergeEntityInCollection(
   collection: EntityCollectionRecord,
   entity: Partial<CombatantTypes | ITemplateId>,
-  entityId: string
+  entityId: string,
 ): EntityCollectionRecord {
   const index = collection.allIds.indexOf(entityId);
   assertTrue(index !== -1, `item (${entityId}) does not exist in collection`);
   return collection.updateIn(['byId'], (byId: Immutable.Map<string, IEntityObject>) => {
     return byId.set(
       entityId,
-      Immutable.Map<string, any>(byId.get(entityId)).merge(entity).toJS()
+      Immutable.Map<string, any>(byId.get(entityId)).merge(entity).toJS(),
     );
   });
 }
@@ -68,15 +68,15 @@ export function mergeEntityInCollection(
  */
 export function removeEntityFromCollection(
   collection: EntityCollectionRecord,
-  entityId: string
+  entityId: string,
 ): EntityCollectionRecord {
   const index = collection.allIds.indexOf(entityId);
   assertTrue(index !== -1, `item (${entityId}) does not exist in collection`);
   collection = collection.updateIn(['allIds'], (allIds) =>
-    allIds.filter((id: string) => id !== entityId)
+    allIds.filter((id: string) => id !== entityId),
   );
   return collection.updateIn(['byId'], (byId: Immutable.Map<string, IEntityObject>) =>
-    byId.remove(entityId)
+    byId.remove(entityId),
   );
 }
 
@@ -85,7 +85,7 @@ export function removeEntityFromCollection(
  * @param object The input values.
  */
 export function entityCollectionFromJSON(
-  object: EntityCollection<any>
+  object: EntityCollection<any>,
 ): EntityCollection<any> {
   return {
     byId: Immutable.Map<string, any>(object.byId),
diff --git a/src/app/models/entity/entity.reducer.spec.ts b/src/app/models/entity/entity.reducer.spec.ts
index e11a657f..54d69ff9 100644
--- a/src/app/models/entity/entity.reducer.spec.ts
+++ b/src/app/models/entity/entity.reducer.spec.ts
@@ -23,7 +23,7 @@ describe('Entity', () => {
 
   function defaultState(
     collection?: 'items' | 'beings',
-    entities?: any[]
+    entities?: any[],
   ): EntityStateRecord {
     let resultState: EntityStateRecord = entityStateFactory();
     if (collection && entities) {
@@ -120,7 +120,7 @@ describe('Entity', () => {
           const item: Item = fakeItem();
           const state = entityReducer(
             defaultState(),
-            new EntityAddItemAction(item)
+            new EntityAddItemAction(item),
           ) as EntityStateRecord;
           entityReducer(
             state,
@@ -128,7 +128,7 @@ describe('Entity', () => {
               entityId: 'invalid',
               itemId: item.eid,
               slot: 'armor',
-            })
+            }),
           );
         }).toThrow();
       });
@@ -140,7 +140,7 @@ describe('Entity', () => {
           });
           const state = entityReducer(
             defaultState(),
-            new EntityAddBeingAction(entity)
+            new EntityAddBeingAction(entity),
           ) as EntityStateRecord;
           entityReducer(
             state,
@@ -148,7 +148,7 @@ describe('Entity', () => {
               entityId: 'foo',
               itemId: 'invalid',
               slot: 'armor',
-            })
+            }),
           );
         }).toThrow();
       });
@@ -159,11 +159,11 @@ describe('Entity', () => {
         const item = fakeItem();
         let state = entityReducer(
           defaultState(),
-          new EntityAddItemAction(item)
+          new EntityAddItemAction(item),
         ) as EntityStateRecord;
         state = entityReducer(
           state,
-          new EntityAddBeingAction(entity)
+          new EntityAddBeingAction(entity),
         ) as EntityStateRecord;
         state = entityReducer(
           state,
@@ -171,7 +171,7 @@ describe('Entity', () => {
             entityId: entity.eid,
             itemId: item.eid,
             slot: 'armor',
-          })
+          }),
         ) as EntityStateRecord;
         expect(state.beings.byId.get(entity.eid).armor).toBe(item.eid);
       });
@@ -183,7 +183,7 @@ describe('Entity', () => {
           const item: Item = fakeItem();
           const state = entityReducer(
             defaultState(),
-            new EntityAddItemAction(item)
+            new EntityAddItemAction(item),
           ) as EntityStateRecord;
           entityReducer(
             state,
@@ -191,7 +191,7 @@ describe('Entity', () => {
               entityId: 'invalid',
               itemId: item.eid,
               slot: 'armor',
-            })
+            }),
           );
         }).toThrow();
       });
@@ -202,7 +202,7 @@ describe('Entity', () => {
           });
           const state = entityReducer(
             defaultState(),
-            new EntityAddBeingAction(entity)
+            new EntityAddBeingAction(entity),
           ) as EntityStateRecord;
           entityReducer(
             state,
@@ -210,7 +210,7 @@ describe('Entity', () => {
               entityId: 'foo',
               itemId: 'invalid',
               slot: 'armor',
-            })
+            }),
           );
         }).toThrow();
       });
@@ -222,11 +222,11 @@ describe('Entity', () => {
         });
         let state = entityReducer(
           defaultState(),
-          new EntityAddItemAction(item)
+          new EntityAddItemAction(item),
         ) as EntityStateRecord;
         state = entityReducer(
           state,
-          new EntityAddBeingAction(entity)
+          new EntityAddBeingAction(entity),
         ) as EntityStateRecord;
         state = entityReducer(
           state,
@@ -234,7 +234,7 @@ describe('Entity', () => {
             entityId: entity.eid,
             itemId: item.eid,
             slot: 'armor',
-          })
+          }),
         ) as EntityStateRecord;
         expect(state.beings.byId.get(entity.eid).armor).toBe(null);
       });
@@ -263,7 +263,7 @@ describe('Entity', () => {
           new GameStateHealPartyAction({
             cost: 0,
             partyIds: [testId, secondId],
-          })
+          }),
         );
         const firstHealed: IPartyMember = actual.beings.byId.get(testId);
         expect(firstHealed.hp).toBe(firstHealed.maxhp);
@@ -298,7 +298,7 @@ describe('Entity', () => {
           new GameStateHurtPartyAction({
             damage,
             partyIds: [testId, secondId],
-          })
+          }),
         );
         const firstHurt: IPartyMember = actual.beings.byId.get(testId);
         expect(firstHurt.hp).toBe(first.hp - damage);
@@ -310,7 +310,7 @@ describe('Entity', () => {
 
     describe('CombatVictoryAction', () => {
       function summaryData(
-        values?: Partial<CombatVictorySummary>
+        values?: Partial<CombatVictorySummary>,
       ): CombatVictorySummary {
         return Object.assign(
           {
@@ -323,7 +323,7 @@ describe('Entity', () => {
             gold: 0,
             exp: 0,
           },
-          values || {}
+          values || {},
         );
       }
 
@@ -363,8 +363,8 @@ describe('Entity', () => {
           new CombatVictoryAction(
             summaryData({
               party: [victoryMemberAfter, victorySecondAfter],
-            })
-          )
+            }),
+          ),
         );
         const entity: Entity = actual.beings.byId.get(victoryMemberId);
         expect(entity.hp).toBe(victoryMemberAfter.hp);
diff --git a/src/app/models/entity/entity.reducer.ts b/src/app/models/entity/entity.reducer.ts
index b60984e0..52fbc4d6 100644
--- a/src/app/models/entity/entity.reducer.ts
+++ b/src/app/models/entity/entity.reducer.ts
@@ -107,31 +107,31 @@ type EntityReducerTypes =
 
 export function entityReducer(
   state: EntityStateRecord = entityStateFactory(),
-  action: EntityReducerTypes
+  action: EntityReducerTypes,
 ): EntityState {
   switch (action.type) {
     case EntityAddBeingAction.typeId: {
       const entity: IEntityObject = action.payload;
       return state.updateIn(['beings'], (items) =>
-        addEntityToCollection(items, entity, entity.eid)
+        addEntityToCollection(items, entity, entity.eid),
       );
     }
     case EntityRemoveBeingAction.typeId: {
       const entityId: string = action.payload;
       return state.updateIn(['beings'], (items) =>
-        removeEntityFromCollection(items, entityId)
+        removeEntityFromCollection(items, entityId),
       );
     }
     case EntityAddItemAction.typeId: {
       const entity: Item = action.payload;
       return state.updateIn(['items'], (items) =>
-        addEntityToCollection(items, entity, entity.eid)
+        addEntityToCollection(items, entity, entity.eid),
       );
     }
     case EntityRemoveItemAction.typeId: {
       const entityId: string = action.payload;
       return state.updateIn(['items'], (items) =>
-        removeEntityFromCollection(items, entityId)
+        removeEntityFromCollection(items, entityId),
       );
     }
     case GameStateHealPartyAction.typeId: {
@@ -148,7 +148,7 @@ export function entityReducer(
               hp: newHp,
               mp: newMp,
             },
-            partyMemberId
+            partyMemberId,
           );
         });
         return updateBeingsResult;
@@ -165,7 +165,7 @@ export function entityReducer(
           updateBeingsResult = mergeEntityInCollection(
             updateBeingsResult,
             { hp: newHp },
-            partyMemberId
+            partyMemberId,
           );
         });
         return updateBeingsResult;
@@ -179,7 +179,7 @@ export function entityReducer(
         !current[action.payload.slot],
         `entity already has item ${current[action.payload.slot]} in ${
           action.payload.slot
-        }`
+        }`,
       );
       return result.updateIn(
         ['beings', 'byId', action.payload.entityId],
@@ -188,7 +188,7 @@ export function entityReducer(
             ...entity,
             [action.payload.slot]: action.payload.itemId,
           };
-        }
+        },
       );
     }
     case GameStateUnequipItemAction.typeId: {
@@ -199,7 +199,7 @@ export function entityReducer(
         current[action.payload.slot] === action.payload.itemId,
         `entity does not have item ${current[action.payload.slot]} equipped ${
           action.payload.slot
-        }`
+        }`,
       );
       return result.updateIn(
         ['beings', 'byId', action.payload.entityId],
@@ -208,7 +208,7 @@ export function entityReducer(
             ...entity,
             [action.payload.slot]: null,
           };
-        }
+        },
       );
     }
     case CombatVictoryAction.typeId: {
@@ -219,12 +219,12 @@ export function entityReducer(
         victoryAction.payload.party.forEach((partyEntity: Entity) => {
           assertTrue(
             !!(partyEntity && partyEntity.eid),
-            'invalid party entity in combat victory action'
+            'invalid party entity in combat victory action',
           );
           updateBeingsResult = mergeEntityInCollection(
             updateBeingsResult,
             partyEntity,
-            partyEntity.eid
+            partyEntity.eid,
           );
         });
         return updateBeingsResult;
diff --git a/src/app/models/game-data/game-data.model.ts b/src/app/models/game-data/game-data.model.ts
index feb137ce..fd28b259 100644
--- a/src/app/models/game-data/game-data.model.ts
+++ b/src/app/models/game-data/game-data.model.ts
@@ -17,7 +17,7 @@ export type ItemElements = 'holy' | 'water' | 'wind' | 'heal';
 export const EQUIPMENT_SLOTS = ['armor', 'helm', 'boots', 'shield', 'weapon'] as const;
 
 /** Valid equipment slot strings type */
-export type EquipmentSlotTypes = typeof EQUIPMENT_SLOTS[number];
+export type EquipmentSlotTypes = (typeof EQUIPMENT_SLOTS)[number];
 
 export type ItemWeaponType = 'weapon';
 
@@ -211,7 +211,7 @@ export interface ITemplateRandomEncounter extends ITemplateEncounter {
  */
 export function instantiateEntity<T extends ITemplateId>(
   from: any,
-  values?: Partial<T>
+  values?: Partial<T>,
 ): T {
   return Object.assign(
     {
@@ -219,7 +219,7 @@ export function instantiateEntity<T extends ITemplateId>(
       status: [],
     },
     from,
-    values || {}
+    values || {},
   ) as T;
 }
 
diff --git a/src/app/models/game-state/game-state.actions.ts b/src/app/models/game-state/game-state.actions.ts
index 755dc1f0..e83125e3 100644
--- a/src/app/models/game-state/game-state.actions.ts
+++ b/src/app/models/game-state/game-state.actions.ts
@@ -127,7 +127,7 @@ export class GameStateTravelAction implements Action {
     public payload: {
       location: string;
       position: IPoint;
-    }
+    },
   ) {}
 }
 
@@ -190,7 +190,7 @@ export class GameStateHealPartyAction implements Action {
     public payload: {
       cost: number;
       partyIds: string[];
-    }
+    },
   ) {}
 }
 
@@ -202,7 +202,7 @@ export class GameStateHurtPartyAction implements Action {
     public payload: {
       damage: number;
       partyIds: string[];
-    }
+    },
   ) {}
 }
 
@@ -222,7 +222,7 @@ export class GameStateEquipItemAction implements Action {
       entityId: string;
       itemId: string;
       slot: keyof EntitySlots;
-    }
+    },
   ) {}
 }
 
@@ -235,7 +235,7 @@ export class GameStateUnequipItemAction implements Action {
       entityId: string;
       itemId: string;
       slot: keyof EntitySlots;
-    }
+    },
   ) {}
 }
 
diff --git a/src/app/models/game-state/game-state.effects.spec.ts b/src/app/models/game-state/game-state.effects.spec.ts
index 0bbd54e0..943ad45f 100644
--- a/src/app/models/game-state/game-state.effects.spec.ts
+++ b/src/app/models/game-state/game-state.effects.spec.ts
@@ -42,7 +42,7 @@ describe('GameState', () => {
         },
         provideMockActions(() => actions$),
       ],
-    })
+    }),
   );
 
   function setup() {
@@ -87,7 +87,7 @@ describe('GameState', () => {
           new GameStateTravelAction({
             location: 'map',
             position: { x: 0, y: 0 },
-          })
+          }),
         );
         effects.travel$.subscribe((result) => {
           expect(mockStateService.loadMapCalls).toBe(1);
diff --git a/src/app/models/game-state/game-state.effects.ts b/src/app/models/game-state/game-state.effects.ts
index da86c7d8..d245495d 100644
--- a/src/app/models/game-state/game-state.effects.ts
+++ b/src/app/models/game-state/game-state.effects.ts
@@ -27,91 +27,105 @@ export class GameStateEffects {
   constructor(
     private actions$: Actions,
     private notify: NotificationService,
-    private gameStateService: GameStateService
+    private gameStateService: GameStateService,
   ) {}
 
   /**
    * When a load action is dispatched, async load the state and then dispatch
    * a Success action.
    */
-  initLoadedGame$ = createEffect(() => this.actions$.pipe(
-    ofType(GameStateLoadAction.typeId),
-    switchMap((action: GameStateLoadAction) => this.gameStateService.load()),
-    map((state: AppState) => new GameStateLoadSuccessAction(state)),
-    catchError((e) => {
-      return of(new GameStateLoadFailAction(e.toString()));
-    })
-  ))
+  initLoadedGame$ = createEffect(() =>
+    this.actions$.pipe(
+      ofType(GameStateLoadAction.typeId),
+      switchMap((action: GameStateLoadAction) => this.gameStateService.load()),
+      map((state: AppState) => new GameStateLoadSuccessAction(state)),
+      catchError((e) => {
+        return of(new GameStateLoadFailAction(e.toString()));
+      }),
+    ),
+  );
 
   /**
    * When a save action is dispatched, serialize the app state to local storage.
    */
-  saveGameState$ = createEffect(() => this.actions$.pipe(
-    ofType(GameStateSaveAction.typeId),
-    switchMap(() => this.gameStateService.save()),
-    map(() => new GameStateSaveSuccessAction()),
-    catchError((e) => {
-      return of(new GameStateSaveFailAction(e.toString()));
-    })
-  ))
+  saveGameState$ = createEffect(() =>
+    this.actions$.pipe(
+      ofType(GameStateSaveAction.typeId),
+      switchMap(() => this.gameStateService.save()),
+      map(() => new GameStateSaveSuccessAction()),
+      catchError((e) => {
+        return of(new GameStateSaveFailAction(e.toString()));
+      }),
+    ),
+  );
 
   /**
    * When a delete action is dispatched, remove the saved state in localstorage.
    */
-  clearGameState$ = createEffect(() => this.actions$.pipe(
-    ofType(GameStateDeleteAction.typeId),
-    switchMap(() => this.gameStateService.resetGame()),
-    map(() => new GameStateDeleteSuccessAction()),
-    catchError((e) => {
-      return of(new GameStateDeleteFailAction(e.toString()));
-    })
-  ))
+  clearGameState$ = createEffect(() =>
+    this.actions$.pipe(
+      ofType(GameStateDeleteAction.typeId),
+      switchMap(() => this.gameStateService.resetGame()),
+      map(() => new GameStateDeleteSuccessAction()),
+      catchError((e) => {
+        return of(new GameStateDeleteFailAction(e.toString()));
+      }),
+    ),
+  );
 
   /** When game data is deleted, notify the user. */
-  clearGameSuccess$ = createEffect(() => this.actions$.pipe(
-    ofType(GameStateDeleteSuccessAction.typeId),
-    tap(() => {
-      this.notify.show(
-        'Game data deleted.  Next time you refresh you will begin a new game.'
-      );
-    })
-  ), { dispatch: false });
+  clearGameSuccess$ = createEffect(
+    () =>
+      this.actions$.pipe(
+        ofType(GameStateDeleteSuccessAction.typeId),
+        tap(() => {
+          this.notify.show(
+            'Game data deleted.  Next time you refresh you will begin a new game.',
+          );
+        }),
+      ),
+    { dispatch: false },
+  );
 
   /**
    * After a successful game create/load, travel to the initial location
    */
-  afterLoadTravelToCurrentLocation$ = createEffect(() => this.actions$.pipe(
-    ofType(GameStateNewSuccessAction.typeId, GameStateLoadSuccessAction.typeId),
-    debounceTime(10),
-    map((action: GameStateNewSuccessAction | GameStateLoadSuccessAction) => {
-      let gameState: GameState;
-      switch (action.type) {
-        case GameStateNewSuccessAction.typeId:
-          gameState = action.payload;
-          break;
-        case GameStateLoadSuccessAction.typeId:
-          gameState = action.payload.gameState;
-          break;
-      }
-      return new GameStateTravelAction(gameState);
-    })
-  ))
+  afterLoadTravelToCurrentLocation$ = createEffect(() =>
+    this.actions$.pipe(
+      ofType(GameStateNewSuccessAction.typeId, GameStateLoadSuccessAction.typeId),
+      debounceTime(10),
+      map((action: GameStateNewSuccessAction | GameStateLoadSuccessAction) => {
+        let gameState: GameState;
+        switch (action.type) {
+          case GameStateNewSuccessAction.typeId:
+            gameState = action.payload;
+            break;
+          case GameStateLoadSuccessAction.typeId:
+            gameState = action.payload.gameState;
+            break;
+        }
+        return new GameStateTravelAction(gameState);
+      }),
+    ),
+  );
 
-  travel$ = createEffect(() => this.actions$.pipe(
-    ofType(GameStateTravelAction.typeId),
-    switchMap((action: GameStateTravelAction) => {
-      return this.gameStateService
-        .loadMap(action.payload.location)
-        .pipe(map(() => action.payload.location));
-    }),
-    // TODO: This debounce is to let the UI transition to a loading screen for at least and appropriate
-    //       amount of time to let the map hide (to flashes of camera movement and map changing)
-    debounceTime(10),
-    map((newMap: string) => {
-      return new GameStateTravelSuccessAction(newMap);
-    }),
-    catchError((e) => {
-      return of(new GameStateTravelFailAction(e.toString()));
-    })
-  ))
+  travel$ = createEffect(() =>
+    this.actions$.pipe(
+      ofType(GameStateTravelAction.typeId),
+      switchMap((action: GameStateTravelAction) => {
+        return this.gameStateService
+          .loadMap(action.payload.location)
+          .pipe(map(() => action.payload.location));
+      }),
+      // TODO: This debounce is to let the UI transition to a loading screen for at least and appropriate
+      //       amount of time to let the map hide (to flashes of camera movement and map changing)
+      debounceTime(10),
+      map((newMap: string) => {
+        return new GameStateTravelSuccessAction(newMap);
+      }),
+      catchError((e) => {
+        return of(new GameStateTravelFailAction(e.toString()));
+      }),
+    ),
+  );
 }
diff --git a/src/app/models/game-state/game-state.reducer.spec.ts b/src/app/models/game-state/game-state.reducer.spec.ts
index 73dfa108..39a3a205 100644
--- a/src/app/models/game-state/game-state.reducer.spec.ts
+++ b/src/app/models/game-state/game-state.reducer.spec.ts
@@ -51,7 +51,7 @@ describe('GameState', () => {
           new GameStateHealPartyAction({
             cost: 50,
             partyIds: [],
-          })
+          }),
         );
         expect(actual.gold).toEqual(50);
       });
@@ -69,7 +69,7 @@ describe('GameState', () => {
               slot: 'weapon',
               itemId: 'foo',
               entityId: 'fooUser',
-            })
+            }),
           );
         }).toThrow();
       });
@@ -82,7 +82,7 @@ describe('GameState', () => {
               slot: 'weapon',
               itemId: 'foo',
               entityId: 'asd',
-            })
+            }),
           );
         }).toThrow();
       });
@@ -98,7 +98,7 @@ describe('GameState', () => {
             slot: 'weapon',
             itemId: 'foo',
             entityId: 'fooUser',
-          })
+          }),
         );
         expect(actual.inventory.count()).toBe(0);
       });
@@ -116,7 +116,7 @@ describe('GameState', () => {
               slot: 'weapon',
               itemId: 'foo',
               entityId: '',
-            })
+            }),
           );
         }).toThrow();
       });
@@ -129,7 +129,7 @@ describe('GameState', () => {
               slot: 'weapon',
               itemId: 'foo',
               entityId: 'asd',
-            })
+            }),
           );
         }).toThrow();
       });
@@ -144,7 +144,7 @@ describe('GameState', () => {
             slot: 'weapon',
             itemId: 'foo',
             entityId: 'fooUser',
-          })
+          }),
         );
         expect(actual.inventory.count()).toBe(1);
       });
@@ -158,7 +158,7 @@ describe('GameState', () => {
         expect(state.keyData.get(newKey)).toBeUndefined();
         const newState = gameStateReducer(
           state,
-          new GameStateSetKeyDataAction(newKey, newValue)
+          new GameStateSetKeyDataAction(newKey, newValue),
         );
         expect(newState.keyData.get(newKey)).toBe(newValue);
       });
@@ -172,7 +172,7 @@ describe('GameState', () => {
         expect(state.keyData.get(keyName)).toBe(true);
         const newState = gameStateReducer(
           state,
-          new GameStateSetKeyDataAction(keyName, false)
+          new GameStateSetKeyDataAction(keyName, false),
         );
         expect(newState.keyData.get(keyName)).toBe(false);
       });
@@ -189,7 +189,7 @@ describe('GameState', () => {
           new GameStateTravelAction({
             location: newMap,
             position: state.position,
-          })
+          }),
         );
         expect(actual.location).toBe(newMap);
       });
@@ -203,7 +203,7 @@ describe('GameState', () => {
           new GameStateTravelAction({
             location: '',
             position: expected,
-          })
+          }),
         );
         expect(actual.position).toEqual(expected);
       });
@@ -251,7 +251,7 @@ describe('GameState', () => {
           const expected = !value;
           const actual = gameStateReducer(
             state,
-            new GameStateBoardShipAction(expected)
+            new GameStateBoardShipAction(expected),
           );
           expect(actual.boardedShip).toEqual(expected);
         });
@@ -304,7 +304,7 @@ describe('GameState', () => {
         });
         const actual = gameStateReducer(
           state,
-          new GameStateRemoveInventoryAction(item)
+          new GameStateRemoveInventoryAction(item),
         );
         expect(actual.inventory.count()).toBe(0);
       });
diff --git a/src/app/models/game-state/game-state.reducer.ts b/src/app/models/game-state/game-state.reducer.ts
index d609f181..141b4fb8 100644
--- a/src/app/models/game-state/game-state.reducer.ts
+++ b/src/app/models/game-state/game-state.reducer.ts
@@ -78,7 +78,7 @@ export function gameStateFromJSON(object: GameState): GameState {
 
 export function gameStateReducer(
   state: GameStateRecord = gameStateFactory(),
-  action: GameStateActions
+  action: GameStateActions,
 ): GameState {
   switch (action.type) {
     case GameStateNewAction.typeId: {
@@ -96,11 +96,11 @@ export function gameStateReducer(
     case GameStateEquipItemAction.typeId:
       assertTrue(
         state.party.find((i) => i === action.payload.entityId),
-        'cannot equip item on entity that is not in the party'
+        'cannot equip item on entity that is not in the party',
       );
       assertTrue(
         state.inventory.find((i) => i === action.payload.itemId),
-        'item does not exist in inventory'
+        'item does not exist in inventory',
       );
       return state.merge({
         inventory: state.inventory.filter((i: string) => i !== action.payload.itemId),
@@ -108,11 +108,11 @@ export function gameStateReducer(
     case GameStateUnequipItemAction.typeId:
       assertTrue(
         state.party.find((i) => i === action.payload.entityId),
-        'cannot remove item from entity that is not in the party'
+        'cannot remove item from entity that is not in the party',
       );
       assertTrue(
         !state.inventory.find((i) => i === action.payload.itemId),
-        'item already exists in inventory'
+        'item already exists in inventory',
       );
       return state.merge({
         inventory: state.inventory.push(action.payload.itemId),
@@ -172,11 +172,11 @@ export function gameStateReducer(
       assertTrue(item, 'cannot add invalid item to inventory');
       assertTrue(
         item.eid,
-        'item must have an eid. consider using "entityId" or "instantiateEntity" during creation'
+        'item must have an eid. consider using "entityId" or "instantiateEntity" during creation',
       );
       assertTrue(
         item.id,
-        'item must have a template id. see game-data models for more information'
+        'item must have a template id. see game-data models for more information',
       );
       const exists: boolean = !!state.inventory.find((i: string) => i === item.eid);
       assertTrue(!exists, 'item already exists in inventory');
@@ -189,7 +189,7 @@ export function gameStateReducer(
       const inventory = state.inventory.filter((i: string) => i !== item.eid);
       assertTrue(
         inventory.count() === state.inventory.count() - 1,
-        'item does not exist in party inventory to remove'
+        'item does not exist in party inventory to remove',
       );
       return state.merge({
         inventory,
diff --git a/src/app/models/game-state/game-state.service.ts b/src/app/models/game-state/game-state.service.ts
index f2baf8bd..5164c0d6 100644
--- a/src/app/models/game-state/game-state.service.ts
+++ b/src/app/models/game-state/game-state.service.ts
@@ -9,7 +9,10 @@ import { getMapUrl } from '../../core/api';
 
 @Injectable()
 export class GameStateService {
-  constructor(private loader: ResourceManager, private store: Store<AppState>) {}
+  constructor(
+    private loader: ResourceManager,
+    private store: Store<AppState>,
+  ) {}
 
   private _worldMap$ = new ReplaySubject<TiledTMXResource>(1);
   worldMap$: Observable<TiledTMXResource> = this._worldMap$;
@@ -23,7 +26,7 @@ export class GameStateService {
       this.loader.load(mapUrl).then((maps: TiledTMXResource[]) => {
         this._worldMap$.next(maps[0]);
         return maps[0];
-      })
+      }),
     );
   }
 
@@ -34,7 +37,7 @@ export class GameStateService {
       first(),
       map(() => {
         localStorage.removeItem(GameStateService.STATE_KEY);
-      })
+      }),
     );
   }
 
@@ -47,10 +50,10 @@ export class GameStateService {
       first(),
       map(() => {
         const data = JSON.parse(
-          localStorage.getItem(GameStateService.STATE_KEY) || '{}'
+          localStorage.getItem(GameStateService.STATE_KEY) || '{}',
         ) as AppState;
         return data;
-      })
+      }),
     );
   }
 
@@ -69,7 +72,7 @@ export class GameStateService {
 
         localStorage.setItem(GameStateService.STATE_KEY, jsonData);
         return state;
-      })
+      }),
     );
   }
 }
diff --git a/src/app/models/index.ts b/src/app/models/index.ts
index d0c6e06d..deb1bcfb 100644
--- a/src/app/models/index.ts
+++ b/src/app/models/index.ts
@@ -41,7 +41,7 @@ export const metaReducers: MetaReducer<State>[] = !environment.production
 
 // Generate a reducer to set the root state in dev mode for HMR
 function stateSetter(
-  reducer: ActionReducer<any, PowAction>
+  reducer: ActionReducer<any, PowAction>,
 ): ActionReducer<any, PowAction> {
   return (state, action) => {
     switch (action.type) {
diff --git a/src/app/models/levels.ts b/src/app/models/levels.ts
index 74d7dfcc..87995be6 100644
--- a/src/app/models/levels.ts
+++ b/src/app/models/levels.ts
@@ -127,7 +127,7 @@ const CLASS_STAT_LEVEL_MAP: IClassStatLevelMap = {
 
 export function getStatIncreaseForLevelUp(
   model: IPartyMember,
-  name: PartyMemberStatNames
+  name: PartyMemberStatNames,
 ): number {
   if (!CLASS_STAT_LEVEL_MAP.hasOwnProperty(model.type)) {
     throw new Error(`Unknown class: ${model.type}`);
diff --git a/src/app/models/mechanics.spec.ts b/src/app/models/mechanics.spec.ts
index a52aa71a..8ad80d0c 100644
--- a/src/app/models/mechanics.spec.ts
+++ b/src/app/models/mechanics.spec.ts
@@ -12,7 +12,7 @@ describe('Game Mechanics', () => {
         // The weapon is additive
         const weapon = new Club();
         expect(PartyMechanics.getAttack({ state: w, equipment: [weapon] })).toBe(
-          halfStrength + weapon.attack
+          halfStrength + weapon.attack,
         );
       });
     });
diff --git a/src/app/models/mechanics.ts b/src/app/models/mechanics.ts
index 287333cf..43d16210 100644
--- a/src/app/models/mechanics.ts
+++ b/src/app/models/mechanics.ts
@@ -17,7 +17,7 @@ import { assertTrue } from './util';
 export interface IMechanicsQuery<
   StateType = CombatantTypes,
   EquipmentType = ITemplateBaseItem,
-  AgainstType = CombatantTypes
+  AgainstType = CombatantTypes,
 > {
   /** The query entity */
   state: StateType;
@@ -111,7 +111,7 @@ export class EnemyMechanics {
 export type MagicFunction = (
   caster: EntityWithEquipment,
   spell: ITemplateMagic,
-  target: ICalculateMagicTarget
+  target: ICalculateMagicTarget,
 ) => IMagicTargetDelta;
 
 export interface ICombatDamage {
@@ -183,7 +183,7 @@ export interface ICalculateMagicEffectsConfig {
 }
 
 export function calculateMagicEffects(
-  config: ICalculateMagicEffectsConfig
+  config: ICalculateMagicEffectsConfig,
 ): IMagicEffects {
   const magic = (config.spells ? config.spells[0] : null) as ITemplateMagic;
   assertTrue(magic, 'invalid spell in calculateMagicEffects');
@@ -196,7 +196,7 @@ export function calculateMagicEffects(
   const targetDeltas: IMagicTargetDelta[] = config.targets.map(
     (target: ICalculateMagicTarget) => {
       return spell(config.caster as EntityWithEquipment, magic, target);
-    }
+    },
   );
 
   return {
@@ -215,7 +215,7 @@ export type MagicFunctionNames = keyof typeof SPELLS;
 export function spellElementalDamage(
   caster: EntityWithEquipment,
   spell: ITemplateMagic,
-  target: ICalculateMagicTarget
+  target: ICalculateMagicTarget,
 ): IMagicTargetDelta {
   // TODO: Check equipment for element-specific bonuses
   return {
@@ -227,7 +227,7 @@ export function spellElementalDamage(
 export function spellModifyHP(
   caster: EntityWithEquipment,
   spell: ITemplateMagic,
-  target: ICalculateMagicTarget
+  target: ICalculateMagicTarget,
 ): IMagicTargetDelta {
   // If the spell benefits a user, it restores health, otherwise it drains health.
   const directionMultiplier = spell.benefit ? 1 : -1;
@@ -241,7 +241,7 @@ export function spellModifyHP(
 export function spellModifyMP(
   caster: EntityWithEquipment,
   spell: ITemplateMagic,
-  target: ICalculateMagicTarget
+  target: ICalculateMagicTarget,
 ): IMagicTargetDelta {
   // If the spell benefits a user, it restores mana, otherwise it drains mana.
   const directionMultiplier = spell.benefit ? 1 : -1;
@@ -298,7 +298,7 @@ export function calculateDamage(config: ICalculateDamageConfig): ICombatDamage {
   // Min of 1, Max of 2
   const numHits = Math.min(
     2,
-    Math.max(1, Math.floor((1 + hitPct / doubleHitThreshold) * hitMultiply))
+    Math.max(1, Math.floor((1 + hitPct / doubleHitThreshold) * hitMultiply)),
   );
   const damages: number[] = [];
   for (let i = 0; i < numHits; i++) {
@@ -309,7 +309,7 @@ export function calculateDamage(config: ICalculateDamageConfig): ICombatDamage {
     const attackMax = attackMin * 2;
     const adjustedAttack = Math.max(
       1,
-      Math.floor(Math.random() * (attackMax - attackMin + 1)) + attackMin
+      Math.floor(Math.random() * (attackMax - attackMin + 1)) + attackMin,
     );
     const defense: number = defenseMechanics.getDefense({
       state: defender as any,
@@ -368,22 +368,22 @@ export function awardLevelUp(model: IPartyMember): IPartyMember {
   const strength = newStatValue(
     model,
     model.strength,
-    getStatIncreaseForLevelUp(model, 'strength')
+    getStatIncreaseForLevelUp(model, 'strength'),
   );
   const agility = newStatValue(
     model,
     model.agility,
-    getStatIncreaseForLevelUp(model, 'agility')
+    getStatIncreaseForLevelUp(model, 'agility'),
   );
   const intelligence = newStatValue(
     model,
     model.intelligence,
-    getStatIncreaseForLevelUp(model, 'intelligence')
+    getStatIncreaseForLevelUp(model, 'intelligence'),
   );
   const luck = newStatValue(
     model,
     model.luck,
-    getStatIncreaseForLevelUp(model, 'luck')
+    getStatIncreaseForLevelUp(model, 'luck'),
   );
   const magicdefense = newStatValue(model, model.magicdefense);
   const hitpercent = newStatValue(model, model.hitpercent);
@@ -419,7 +419,7 @@ export function awardExperience(exp: number, model: IPartyMember): IPartyMember
 export function newStatValue(
   model: IPartyMember,
   stat: number[],
-  add: number = 0
+  add: number = 0,
 ): number[] {
   let newValue = stat[0] + add;
   if (stat.length > 1) {
@@ -464,7 +464,7 @@ export interface IPartyStatsDiff {
  */
 export function diffPartyMember(
   before: IPartyMember,
-  after: IPartyMember
+  after: IPartyMember,
 ): IPartyStatsDiff {
   return {
     name: after.name,
diff --git a/src/app/models/selectors.ts b/src/app/models/selectors.ts
index 0956b68a..7f5d8a63 100644
--- a/src/app/models/selectors.ts
+++ b/src/app/models/selectors.ts
@@ -60,15 +60,15 @@ export const getCombatType = createSelector(sliceCombatState, sliceCombatType);
 export const getCombatLoading = createSelector(sliceCombatState, sliceCombatLoading);
 export const getCombatEncounterParty = createSelector(
   sliceCombatState,
-  sliceCombatEncounterParty
+  sliceCombatEncounterParty,
 );
 export const getCombatEncounterEnemies = createSelector(
   sliceCombatState,
-  sliceCombatEncounterEnemies
+  sliceCombatEncounterEnemies,
 );
 export const getCombatEncounter = createSelector(
   sliceCombatState,
-  sliceCombatEncounter
+  sliceCombatEncounter,
 );
 
 //
@@ -99,7 +99,7 @@ export const sliceEntitiesState = (state: AppState) => state.entities;
  */
 export const entitiesToArray = (
   object: Immutable.Map<string, IEntityObject>,
-  ids: Immutable.List<string>
+  ids: Immutable.List<string>,
 ) => {
   return ids.map((id?: string) => object.get(id || '')).toArray();
 };
@@ -108,7 +108,7 @@ export const entitiesToArray = (
 export const getEntityBeingById = createSelector(sliceEntitiesState, sliceEntityBeings);
 export const getEntityBeingIds = createSelector(
   sliceEntitiesState,
-  sliceEntityBeingIds
+  sliceEntityBeingIds,
 );
 
 /** Select just one entity by its ID */
@@ -117,7 +117,7 @@ export const getEntityById = (id: string) => {
     getEntityBeingById,
     (entities: Immutable.Map<string, Entity>) => {
       return entities.get(id);
-    }
+    },
   );
 };
 
@@ -127,7 +127,7 @@ export const getEntityItemIds = createSelector(sliceEntitiesState, sliceEntityIt
 
 /** Resolve equipment slots to their item entity objects for representation in the UI */
 export const getEntityEquipment = (
-  entityId: string
+  entityId: string,
 ): Selector<AppState, EntityWithEquipment> => {
   return createSelector(getEntityById(entityId), getEntityItemById, (entity, items) => {
     if (!entity) {
@@ -147,11 +147,11 @@ export const getEntityEquipment = (
 
 /** Resolve equipment slots to their item entity objects for representation in the UI */
 export const getCombatEntityEquipment = (
-  entityId: string
+  entityId: string,
 ): Selector<AppState, EntityWithEquipment | null> => {
   return createSelector(getCombatEncounterParty, getEntityItemById, (party, items) => {
     const entity: Entity | undefined = party.find(
-      (p?: IPartyMember) => !!(p && p.eid === entityId)
+      (p?: IPartyMember) => !!(p && p.eid === entityId),
     );
     if (!entity) {
       return null;
@@ -192,7 +192,7 @@ export const getGameParty = createSelector(
   getGamePartyIds,
   (entities, ids): Immutable.List<Entity | undefined> => {
     return ids.map((id) => entities.get(id || '')).toList();
-  }
+  },
 );
 /** Select just one data key from the gamesate keyData object. */
 export const getGameKey = (key: string) => {
@@ -206,7 +206,7 @@ export const getGameInventory = createSelector(
   getGameInventoryIds,
   (
     entities: Immutable.Map<string, EntityItemTypes>,
-    ids: Immutable.List<string>
+    ids: Immutable.List<string>,
   ): Immutable.List<EntityItemTypes> => {
     return ids
       .map((id) => {
@@ -215,12 +215,12 @@ export const getGameInventory = createSelector(
         // instead of crashing hard in an obscure place.
         assertTrue(
           result,
-          `${id} is present in inventory but not in entity collection. Did you forget to dispatch EntityAddItemAction?`
+          `${id} is present in inventory but not in entity collection. Did you forget to dispatch EntityAddItemAction?`,
         );
         return result;
       })
       .toList();
-  }
+  },
 );
 
 /** Get game Party with equipment objects resolved */
@@ -229,7 +229,7 @@ export const getGamePartyWithEquipment = createSelector(
   getEntityItemById,
   (
     party: Immutable.List<Entity>,
-    items: Immutable.Map<string, EntityItemTypes>
+    items: Immutable.Map<string, EntityItemTypes>,
   ): Immutable.List<EntityWithEquipment> => {
     return party
       .filter((r) => !!r)
@@ -246,5 +246,5 @@ export const getGamePartyWithEquipment = createSelector(
         return Object.assign({}, entity, result) as EntityWithEquipment;
       })
       .toList();
-  }
+  },
 );
diff --git a/src/app/models/sprites/sprites.effects.spec.ts b/src/app/models/sprites/sprites.effects.spec.ts
index 7aedaa99..54cd7c91 100644
--- a/src/app/models/sprites/sprites.effects.spec.ts
+++ b/src/app/models/sprites/sprites.effects.spec.ts
@@ -23,7 +23,7 @@ describe('Sprites', () => {
         { provide: SpritesService, useValue: mockSpritesService },
         provideMockActions(() => actions$),
       ],
-    })
+    }),
   );
 
   function setup() {
diff --git a/src/app/models/sprites/sprites.effects.ts b/src/app/models/sprites/sprites.effects.ts
index 1d66fba6..cfccddb2 100644
--- a/src/app/models/sprites/sprites.effects.ts
+++ b/src/app/models/sprites/sprites.effects.ts
@@ -11,20 +11,25 @@ import { SpritesService } from './sprites.service';
 
 @Injectable()
 export class SpritesEffects {
-  constructor(private actions$: Actions, private spritesService: SpritesService) {}
+  constructor(
+    private actions$: Actions,
+    private spritesService: SpritesService,
+  ) {}
 
-  loadSprites$ = createEffect(() => this.actions$.pipe(
-    ofType(SpritesLoadAction.typeId),
-    switchMap((action: SpritesLoadAction) => {
-      return this.spritesService
-        .loadSprites(action.payload)
-        .pipe(map(() => action.payload));
-    }),
-    map((url: string) => {
-      return new SpritesLoadSuccessAction(url);
-    }),
-    catchError((e) => {
-      return of(new SpritesLoadFailAction(e.toString()));
-    })
-  ))
+  loadSprites$ = createEffect(() =>
+    this.actions$.pipe(
+      ofType(SpritesLoadAction.typeId),
+      switchMap((action: SpritesLoadAction) => {
+        return this.spritesService
+          .loadSprites(action.payload)
+          .pipe(map(() => action.payload));
+      }),
+      map((url: string) => {
+        return new SpritesLoadSuccessAction(url);
+      }),
+      catchError((e) => {
+        return of(new SpritesLoadFailAction(e.toString()));
+      }),
+    ),
+  );
 }
diff --git a/src/app/models/sprites/sprites.reducer.ts b/src/app/models/sprites/sprites.reducer.ts
index 09ae81fd..5c641167 100644
--- a/src/app/models/sprites/sprites.reducer.ts
+++ b/src/app/models/sprites/sprites.reducer.ts
@@ -36,7 +36,7 @@ export function spritesFromJSON(object: SpriteState): SpriteState {
 
 export function spritesReducer(
   state: SpritesStateRecord = spritesStateFactory(),
-  action: SpriteActions
+  action: SpriteActions,
 ): SpritesStateRecord {
   switch (action.type) {
     case SpritesRegisterAction.typeId: {
diff --git a/src/app/models/sprites/sprites.service.ts b/src/app/models/sprites/sprites.service.ts
index ab989353..10b3ac3f 100644
--- a/src/app/models/sprites/sprites.service.ts
+++ b/src/app/models/sprites/sprites.service.ts
@@ -15,7 +15,7 @@ import { SpriteDataMap } from './sprites.model';
 export class SpritesService {
   constructor(
     private resourceLoader: ResourceManager,
-    private store: Store<AppState>
+    private store: Store<AppState>,
   ) {}
 
   /** Preload sprite sheet metadata */
@@ -43,12 +43,12 @@ export class SpritesService {
                       this.store.dispatch(new SpritesRegisterAction(meta));
                       registerSprites(fileName, meta);
                     });
-                })
+                }),
               );
             })
-            .then(() => Promise.resolve<void>(undefined))
+            .then(() => Promise.resolve<void>(undefined)),
         );
-      })
+      }),
     );
   }
 }
diff --git a/src/app/models/util.ts b/src/app/models/util.ts
index 7852bce5..55f1e7d3 100644
--- a/src/app/models/util.ts
+++ b/src/app/models/util.ts
@@ -40,7 +40,7 @@ export function exhaustiveCheck(input: never) {
  */
 export function makeRecordFactory<E, T extends TypedRecord<T> & E>(
   obj: E,
-  name?: string
+  name?: string,
 ): (val?: Partial<E>) => T {
   return makeTypedFactory<E, T>(obj, name);
 }
@@ -50,7 +50,7 @@ export function makeRecordFactory<E, T extends TypedRecord<T> & E>(
  */
 export function assertTrue<T>(
   expression: T,
-  message: string
+  message: string,
 ): asserts expression is NonNullable<T> {
   if (!expression) {
     throw new Error(`Assertion Failed: ${message}`);
diff --git a/src/app/routes/combat/behaviors/actions/combat-attack.behavior.ts b/src/app/routes/combat/behaviors/actions/combat-attack.behavior.ts
index 666aa66a..bd951a8b 100644
--- a/src/app/routes/combat/behaviors/actions/combat-attack.behavior.ts
+++ b/src/app/routes/combat/behaviors/actions/combat-attack.behavior.ts
@@ -52,7 +52,7 @@ export class CombatAttackBehaviorComponent extends CombatActionBehavior {
     private store: Store<AppState>,
     private combatService: CombatService,
     protected gameWorld: GameWorld,
-    protected loader: ResourceManager
+    protected loader: ResourceManager,
   ) {
     super(loader, gameWorld);
   }
@@ -104,7 +104,7 @@ export class CombatAttackBehaviorComponent extends CombatActionBehavior {
     const defenderModel: CombatantTypes = defender.model as CombatantTypes;
     assertTrue(
       attackerModel && defenderModel,
-      'invalid attacker/defender model attack behavior'
+      'invalid attacker/defender model attack behavior',
     );
     const playerRender =
       attacker instanceof CombatPlayerComponent
@@ -115,7 +115,7 @@ export class CombatAttackBehaviorComponent extends CombatActionBehavior {
     const actionCompletePromise = done$
       .pipe(
         filter((d) => d === true),
-        take(1)
+        take(1),
       )
       .toPromise();
 
@@ -148,7 +148,7 @@ export class CombatAttackBehaviorComponent extends CombatActionBehavior {
     attacker: GameEntityObject,
     defender: GameEntityObject,
     equippedAttacker: EntityWithEquipment,
-    equippedDefender: EntityWithEquipment
+    equippedDefender: EntityWithEquipment,
   ) {
     const playerRender =
       attacker instanceof CombatPlayerComponent
@@ -160,18 +160,18 @@ export class CombatAttackBehaviorComponent extends CombatActionBehavior {
     const defenderModel: CombatantTypes = defender.model as CombatantTypes;
     const damageOutput = this.combatService.attackCombatant(
       equippedAttacker || attacker.model,
-      equippedDefender || defender.model
+      equippedDefender || defender.model,
     );
     const defending: boolean = defenderModel.status.includes('guarding');
     const hitSound = this.getHitSound(
       defenderModel.hp,
       damageOutput.totalDamage,
-      defending
+      defending,
     );
     const damageAnimation = this.getDamageAnimation(
       damageOutput.totalDamage,
       damageOutput.damages.length,
-      defending
+      defending,
     );
     const damage = damageOutput.totalDamage;
     const didKill: boolean = defenderModel.hp - damage <= 0;
diff --git a/src/app/routes/combat/behaviors/actions/combat-guard.behavior.ts b/src/app/routes/combat/behaviors/actions/combat-guard.behavior.ts
index 22a86cf9..8fe3d3e2 100644
--- a/src/app/routes/combat/behaviors/actions/combat-guard.behavior.ts
+++ b/src/app/routes/combat/behaviors/actions/combat-guard.behavior.ts
@@ -30,7 +30,7 @@ export class CombatGuardBehavior extends CombatActionBehavior {
   constructor(
     public store: Store<AppState>,
     protected loader: ResourceManager,
-    protected gameWorld: GameWorld
+    protected gameWorld: GameWorld,
   ) {
     super(loader, gameWorld);
   }
@@ -54,10 +54,10 @@ export class CombatGuardBehavior extends CombatActionBehavior {
     assertTrue(this._subscription === null, 'subscription leak in guard behavior');
     assertTrue(this._changedModel === null, 'changed model leak in guard behavior');
     this._subscription = this.combat.machine.onEnterState$.subscribe((v) =>
-      this.enterStateHandler(v)
+      this.enterStateHandler(v),
     );
     this.store.dispatch(
-      new CombatSetStatusAction({ target: model, classes: ['guarding'] })
+      new CombatSetStatusAction({ target: model, classes: ['guarding'] }),
     );
   }
 
@@ -76,7 +76,7 @@ export class CombatGuardBehavior extends CombatActionBehavior {
         new CombatClearStatusAction({
           target: model,
           classes: ['guarding'],
-        })
+        }),
       );
       this._changedModel = null;
       assertTrue(this._subscription, 'unmatched subscription in guard behavior');
diff --git a/src/app/routes/combat/behaviors/actions/combat-item.behavior.ts b/src/app/routes/combat/behaviors/actions/combat-item.behavior.ts
index 691f592c..2165ea02 100644
--- a/src/app/routes/combat/behaviors/actions/combat-item.behavior.ts
+++ b/src/app/routes/combat/behaviors/actions/combat-item.behavior.ts
@@ -39,7 +39,7 @@ export class CombatItemBehavior extends CombatActionBehavior {
   constructor(
     public store: Store<AppState>,
     protected loader: ResourceManager,
-    protected gameWorld: GameWorld
+    protected gameWorld: GameWorld,
   ) {
     super(loader, gameWorld);
   }
diff --git a/src/app/routes/combat/behaviors/actions/combat-magic.behavior.ts b/src/app/routes/combat/behaviors/actions/combat-magic.behavior.ts
index e31eb063..e2d519d3 100644
--- a/src/app/routes/combat/behaviors/actions/combat-magic.behavior.ts
+++ b/src/app/routes/combat/behaviors/actions/combat-magic.behavior.ts
@@ -62,7 +62,7 @@ export class CombatMagicBehavior extends CombatActionBehavior {
     public store: Store<AppState>,
     public combatService: CombatService,
     public gameWorld: GameWorld,
-    protected loader: ResourceManager
+    protected loader: ResourceManager,
   ) {
     super(loader, gameWorld);
   }
@@ -110,7 +110,7 @@ export class CombatMagicBehavior extends CombatActionBehavior {
     const attackEffectsPromise = done$
       .pipe(
         filter((d) => d === true),
-        take(1)
+        take(1),
       )
       .toPromise();
     const attackAnimPromise = attackerPlayer.magic(async () => {
@@ -166,7 +166,7 @@ export class CombatMagicBehavior extends CombatActionBehavior {
     const actionCompletePromise = done$
       .pipe(
         filter((d) => d === true),
-        take(1)
+        take(1),
       )
       .toPromise();
 
@@ -194,7 +194,7 @@ export class CombatMagicBehavior extends CombatActionBehavior {
   private async doHurtSpellAction(
     equippedAttacker: EntityWithEquipment,
     equippedDefender: EntityWithEquipment | null,
-    inventory: Immutable.List<Item>
+    inventory: Immutable.List<Item>,
   ) {
     const caster: GameEntityObject | null = this.from;
     const target: GameEntityObject | null = this.to;
diff --git a/src/app/routes/combat/behaviors/actions/combat-run.behavior.ts b/src/app/routes/combat/behaviors/actions/combat-run.behavior.ts
index 046c99a6..facfd966 100644
--- a/src/app/routes/combat/behaviors/actions/combat-run.behavior.ts
+++ b/src/app/routes/combat/behaviors/actions/combat-run.behavior.ts
@@ -15,7 +15,10 @@ export class CombatRunBehaviorComponent extends CombatActionBehavior {
   name: string = 'run';
   @Input() combat: CombatComponent;
 
-  constructor(protected loader: ResourceManager, protected gameWorld: GameWorld) {
+  constructor(
+    protected loader: ResourceManager,
+    protected gameWorld: GameWorld,
+  ) {
     super(loader, gameWorld);
   }
 
@@ -27,7 +30,7 @@ export class CombatRunBehaviorComponent extends CombatActionBehavior {
     const success: boolean = this.rollEscape();
     assertTrue(
       this.combat.machine.current,
-      'CombatRunBehaviorComponent: invalid escape player'
+      'CombatRunBehaviorComponent: invalid escape player',
     );
     const data: CombatRunSummary = {
       success,
diff --git a/src/app/routes/combat/behaviors/actions/index.ts b/src/app/routes/combat/behaviors/actions/index.ts
index 4ec3297f..ff9311f1 100644
--- a/src/app/routes/combat/behaviors/actions/index.ts
+++ b/src/app/routes/combat/behaviors/actions/index.ts
@@ -1,5 +1,3 @@
-
-
 export * from './combat-attack.behavior';
 export * from './combat-guard.behavior';
 export * from './combat-item.behavior';
diff --git a/src/app/routes/combat/behaviors/choose-action.machine.spec.ts b/src/app/routes/combat/behaviors/choose-action.machine.spec.ts
index 75c598d1..d77ddf7b 100644
--- a/src/app/routes/combat/behaviors/choose-action.machine.spec.ts
+++ b/src/app/routes/combat/behaviors/choose-action.machine.spec.ts
@@ -37,7 +37,7 @@ function getMachine() {
     combat.enemies.toArray(),
     (a) => {
       actionCalled = a;
-    }
+    },
   );
   return { machine, combat, fixture, selectedAction };
 }
diff --git a/src/app/routes/combat/behaviors/choose-action.machine.ts b/src/app/routes/combat/behaviors/choose-action.machine.ts
index 97424946..b7654cd9 100644
--- a/src/app/routes/combat/behaviors/choose-action.machine.ts
+++ b/src/app/routes/combat/behaviors/choose-action.machine.ts
@@ -53,7 +53,7 @@ export class ChooseActionStateMachine extends StateMachine<CombatChooseActionSta
     public scene: Scene,
     public players: GameEntityObject[],
     public enemies: GameEntityObject[],
-    submit: (action: CombatActionBehavior) => any
+    submit: (action: CombatActionBehavior) => any,
   ) {
     super();
     this.states = [
diff --git a/src/app/routes/combat/behaviors/combat-action.behavior.ts b/src/app/routes/combat/behaviors/combat-action.behavior.ts
index ddb852e6..42b5e692 100644
--- a/src/app/routes/combat/behaviors/combat-action.behavior.ts
+++ b/src/app/routes/combat/behaviors/combat-action.behavior.ts
@@ -1,4 +1,3 @@
-
 import _ from 'underscore';
 import { SceneObjectBehavior } from '../../../behaviors/scene-object-behavior';
 import { AudioResource, ImageResource, ResourceManager } from '../../../core';
@@ -22,7 +21,10 @@ export class CombatActionBehavior extends SceneObjectBehavior implements IPlayer
   /** A map of key/icon for sprites this action uses. Calling preload() will load these */
   sprites: { [key: string]: string } | null = null;
 
-  constructor(protected loader: ResourceManager, protected gameWorld: GameWorld) {
+  constructor(
+    protected loader: ResourceManager,
+    protected gameWorld: GameWorld,
+  ) {
     super();
   }
 
@@ -68,7 +70,7 @@ export class CombatActionBehavior extends SceneObjectBehavior implements IPlayer
         const meta = this.gameWorld.sprites.getSpriteMeta(spriteName);
         assertTrue(meta, `no metadata for sprite: ${spriteName}`);
         return meta.source;
-      })
+      }),
     );
     const sounds = _.uniq(Object.values(this.sounds || []));
     return Promise.all([
diff --git a/src/app/routes/combat/combat-enemy.component.ts b/src/app/routes/combat/combat-enemy.component.ts
index 92dfcac1..74bfa4f2 100644
--- a/src/app/routes/combat/combat-enemy.component.ts
+++ b/src/app/routes/combat/combat-enemy.component.ts
@@ -53,7 +53,7 @@ export class CombatEnemyComponent
         distinctUntilChanged(),
         map((m: IEnemy) => {
           this.setSprite(m.icon);
-        })
+        }),
       )
       .subscribe();
   }
diff --git a/src/app/routes/combat/combat-hud.component.ts b/src/app/routes/combat/combat-hud.component.ts
index 5b14a215..0e12ac33 100644
--- a/src/app/routes/combat/combat-hud.component.ts
+++ b/src/app/routes/combat/combat-hud.component.ts
@@ -27,12 +27,12 @@ export class CombatHUDComponent {
   constructor(
     public store: Store<AppState>,
     public loadingService: LoadingService,
-    public loader: ResourceManager
+    public loader: ResourceManager,
   ) {}
 
   getMemberClass(
     member: CombatantTypes,
-    focused?: CombatantTypes | null
+    focused?: CombatantTypes | null,
   ): { [key: string]: boolean } {
     return {
       focused: !!(focused && member && member.name === focused.name),
diff --git a/src/app/routes/combat/combat-player.component.ts b/src/app/routes/combat/combat-player.component.ts
index e38065d0..421c46d8 100644
--- a/src/app/routes/combat/combat-player.component.ts
+++ b/src/app/routes/combat/combat-player.component.ts
@@ -226,7 +226,7 @@ export class CombatPlayerComponent
           result.move = result.move.clone();
         }
         return result;
-      }
+      },
     );
     this.animating = true;
     await this.animation.playChain(animations);
diff --git a/src/app/routes/combat/combat.component.ts b/src/app/routes/combat/combat.component.ts
index 26c469ac..7e65661d 100644
--- a/src/app/routes/combat/combat.component.ts
+++ b/src/app/routes/combat/combat.component.ts
@@ -125,14 +125,14 @@ export class CombatComponent
     map((result: TiledTMXResource) => {
       this.map.setMap(result);
       return result;
-    })
+    }),
   );
 
   /** Features can be derived after a new map resource has been loaded */
   features$: Observable<ITiledObject[]> = this.resource$.pipe(
     map(() => {
       return this.map.features?.objects || [];
-    })
+    }),
   );
 
   /**
@@ -151,7 +151,7 @@ export class CombatComponent
     public combatService: CombatService,
     public store: Store<AppState>,
     public world: GameWorld,
-    private cd: ChangeDetectorRef
+    private cd: ChangeDetectorRef,
   ) {
     super();
     this.world.mark(this.scene);
@@ -220,7 +220,7 @@ export class CombatComponent
         () => {
           this.game.initGame().then(done);
         },
-        0
+        0,
       );
     });
     this.scene?.addObject(this);
@@ -239,7 +239,7 @@ export class CombatComponent
               e.setPoint(new Point(battleSpawn.x / 16, battleSpawn.y / 16));
             }
           });
-        })
+        }),
       )
       .subscribe();
 
@@ -296,7 +296,7 @@ export class CombatComponent
         0,
         0,
         this.context.canvas.width,
-        this.context.canvas.height
+        this.context.canvas.height,
       );
       this.cameraScale = w > 1024 ? 6 : w > 768 ? 4 : w > 480 ? 3 : 2;
       this.camera = this.screenToWorld(screenRect, this.cameraScale);
@@ -319,7 +319,7 @@ export class CombatComponent
       this.objectRenderer.render(
         component as TileRenderable,
         component.renderPoint || component.point,
-        this
+        this,
       );
       const sprites = component.findBehaviors(SpriteComponent) as SpriteComponent[];
       sprites.forEach((sprite: SpriteComponent) => {
@@ -330,7 +330,7 @@ export class CombatComponent
       this.objectRenderer.render(
         component as TileRenderable,
         component.renderPoint || component.point,
-        this
+        this,
       );
       const sprites: SpriteComponent[] = component.findBehaviors(SpriteComponent);
       sprites.forEach((sprite: SpriteComponent) => {
@@ -360,7 +360,7 @@ export class CombatComponent
     const screenPos: Point = this.worldToScreen(targetPos, this.cameraScale);
     screenPos.add(
       this.canvasElementRef.nativeElement.offsetLeft,
-      this.canvasElementRef.nativeElement.offsetTop
+      this.canvasElementRef.nativeElement.offsetTop,
     );
     this.damages.push({
       id: _.uniqueId('dmg'),
diff --git a/src/app/routes/combat/combat.guards.ts b/src/app/routes/combat/combat.guards.ts
index 7bf93f8a..4a4923b3 100644
--- a/src/app/routes/combat/combat.guards.ts
+++ b/src/app/routes/combat/combat.guards.ts
@@ -7,8 +7,11 @@ import { CombatState } from '../../models/combat/combat.model';
 import { sliceCombatState } from '../../models/selectors';
 
 @Injectable()
-export class CanActivateCombat  {
-  constructor(private store: Store<AppState>, private router: Router) {}
+export class CanActivateCombat {
+  constructor(
+    private store: Store<AppState>,
+    private router: Router,
+  ) {}
 
   canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
     return this.store.select(sliceCombatState).pipe(
@@ -19,7 +22,7 @@ export class CanActivateCombat  {
           return false;
         }
         return combatState.id === route.params['id'];
-      })
+      }),
     );
   }
 }
diff --git a/src/app/routes/combat/combat.testing.ts b/src/app/routes/combat/combat.testing.ts
index b530b0d4..b0fbe1a9 100644
--- a/src/app/routes/combat/combat.testing.ts
+++ b/src/app/routes/combat/combat.testing.ts
@@ -41,7 +41,7 @@ export function testCombatGetStateMachine(): CombatStateMachineComponent {
 export function testCombatAddPartyCombatants(
   store: Store<AppState>,
   comp: CombatComponent,
-  onlyFirst: boolean = false
+  onlyFirst: boolean = false,
 ): CombatPlayerComponent[] {
   const party = testAppGetParty(store);
   const players = [];
@@ -65,7 +65,7 @@ export function testCombatAddPartyCombatants(
 }
 
 export function testCombatAddEnemyCombatants(
-  comp: CombatComponent
+  comp: CombatComponent,
 ): CombatEnemyComponent[] {
   const items = ['imp', 'imp', 'imp'].map((id) => {
     const itemTemplate: IEnemy = getEnemyById(id) as any;
@@ -91,7 +91,7 @@ export function testCombatAddEnemyCombatants(
 
 export function testCombatSetEnemyCombatants(
   comp: CombatStateMachineComponent,
-  enemies: IEnemy[]
+  enemies: IEnemy[],
 ): CombatEnemyComponent[] {
   const results = [];
   for (let i = 0; i < enemies.length; i++) {
@@ -112,7 +112,7 @@ export function testCombatSetEnemyCombatants(
 export function testCombatSetRandomEncounter(
   store: Store<AppState>,
   party: Entity[],
-  encounter: ITemplateRandomEncounter
+  encounter: ITemplateRandomEncounter,
 ) {
   const toCombatant = (id: string): IEnemy => {
     const itemTemplate: IEnemy = getEnemyById(id) as any;
@@ -141,7 +141,7 @@ export function testCombatSetRandomEncounter(
 export function testCombatSetFixedEncounter(
   store: Store<AppState>,
   party: Entity[],
-  encounter: ITemplateFixedEncounter
+  encounter: ITemplateFixedEncounter,
 ) {
   const toCombatant = (id: string): IEnemy => {
     const itemTemplate: IEnemy = getEnemyById(id) as any;
@@ -193,7 +193,7 @@ export function testCombatGetParty(store: Store<AppState>): IPartyMember[] {
 
 export function testCombatCreateComponent(
   defaultState?: CombatStateNames | null,
-  encounter = RANDOM_ENCOUNTERS_DATA[0]
+  encounter = RANDOM_ENCOUNTERS_DATA[0],
 ): CombatComponent {
   const { combat } = testCombatCreateComponentFixture(defaultState, encounter);
   return combat;
@@ -201,7 +201,7 @@ export function testCombatCreateComponent(
 
 export function testCombatCreateComponentFixture(
   defaultState: CombatStateNames | null = null,
-  encounter = RANDOM_ENCOUNTERS_DATA[0]
+  encounter = RANDOM_ENCOUNTERS_DATA[0],
 ) {
   const combatFixture = TestBed.createComponent(CombatComponent);
   const store = combatFixture.componentInstance.store;
diff --git a/src/app/routes/combat/index.ts b/src/app/routes/combat/index.ts
index 96b5f8a4..40ef818a 100644
--- a/src/app/routes/combat/index.ts
+++ b/src/app/routes/combat/index.ts
@@ -1,4 +1,3 @@
-
 import { CommonModule } from '@angular/common';
 import { ModuleWithProviders, NgModule } from '@angular/core';
 import { BehaviorsModule } from '../../behaviors/index';
diff --git a/src/app/routes/combat/states/combat-base.state.ts b/src/app/routes/combat/states/combat-base.state.ts
index 4baba1ed..3fcba007 100644
--- a/src/app/routes/combat/states/combat-base.state.ts
+++ b/src/app/routes/combat/states/combat-base.state.ts
@@ -1,5 +1,3 @@
-
-
 import { State } from '../../../core/state';
 import { CombatStateNames } from './states';
 
diff --git a/src/app/routes/combat/states/combat-begin-turn.state.spec.ts b/src/app/routes/combat/states/combat-begin-turn.state.spec.ts
index 58ea9ddf..e5e08342 100644
--- a/src/app/routes/combat/states/combat-begin-turn.state.spec.ts
+++ b/src/app/routes/combat/states/combat-begin-turn.state.spec.ts
@@ -110,7 +110,7 @@ describe('CombatBeginTurnStateComponent', () => {
     const enemies = combat.enemies.toArray();
     const enemy = enemies[0];
     const attackComponent = enemy.findBehavior<CombatAttackBehaviorComponent>(
-      CombatAttackBehaviorComponent
+      CombatAttackBehaviorComponent,
     );
     assertTrue(attackComponent, 'enemy has no attack component');
     let called = false;
diff --git a/src/app/routes/combat/states/combat-begin-turn.state.ts b/src/app/routes/combat/states/combat-begin-turn.state.ts
index 74ac7efd..9837c739 100644
--- a/src/app/routes/combat/states/combat-begin-turn.state.ts
+++ b/src/app/routes/combat/states/combat-begin-turn.state.ts
@@ -1,4 +1,3 @@
-
 import { Component } from '@angular/core';
 import { CombatService } from '../../../models/combat/combat.service';
 import { assertTrue } from '../../../models/util';
@@ -44,7 +43,7 @@ export class CombatBeginTurnStateComponent extends CombatMachineState {
       choice = machine.playerChoices[machine.current._uid];
     } else {
       choice = machine.current.findBehavior<CombatAttackBehaviorComponent>(
-        CombatAttackBehaviorComponent
+        CombatAttackBehaviorComponent,
       );
       // TODO: This config should not be here.   Just pick a random person to attack.
       if (choice) {
diff --git a/src/app/routes/combat/states/combat-choose-action.state.ts b/src/app/routes/combat/states/combat-choose-action.state.ts
index b1f0a488..96aba67b 100644
--- a/src/app/routes/combat/states/combat-choose-action.state.ts
+++ b/src/app/routes/combat/states/combat-choose-action.state.ts
@@ -1,4 +1,3 @@
-
 import { Component, Input } from '@angular/core';
 import { interval, Observable } from 'rxjs';
 import { distinctUntilChanged, filter, map } from 'rxjs/operators';
@@ -70,12 +69,12 @@ export class CombatChooseActionStateComponent extends CombatMachineState {
       // Convert to screen coordinates
       const screenPos: Point = this.view.worldToScreen(
         targetPos,
-        this.view.cameraScale
+        this.view.cameraScale,
       );
       return screenPos;
     }),
     filter<Point>(Boolean),
-    distinctUntilChanged()
+    distinctUntilChanged(),
   );
 
   async enter(machine: CombatStateMachineComponent) {
@@ -99,7 +98,7 @@ export class CombatChooseActionStateComponent extends CombatMachineState {
       machine.scene,
       this.pending,
       machine.getLiveEnemies(),
-      this.submitChoice.bind(this)
+      this.submitChoice.bind(this),
     );
     this._next();
   }
@@ -137,7 +136,7 @@ export class CombatChooseActionStateComponent extends CombatMachineState {
   /** Show the pointer element next to the given object, aligned to left/right side */
   setPointerTarget(
     object: GameEntityObject | null,
-    directionClass: 'left' | 'right' = 'right'
+    directionClass: 'left' | 'right' = 'right',
   ) {
     this.pointAtDir = directionClass;
     this.pointAt = object;
diff --git a/src/app/routes/combat/states/combat-defeat.state.ts b/src/app/routes/combat/states/combat-defeat.state.ts
index fb8448f1..eb7ca555 100644
--- a/src/app/routes/combat/states/combat-defeat.state.ts
+++ b/src/app/routes/combat/states/combat-defeat.state.ts
@@ -1,4 +1,3 @@
-
 import { Component } from '@angular/core';
 import { assertTrue } from '../../../models/util';
 import { GameEntityObject } from '../../../scene/objects/game-entity-object';
diff --git a/src/app/routes/combat/states/combat-end-turn.state.ts b/src/app/routes/combat/states/combat-end-turn.state.ts
index 53516b7b..5908429f 100644
--- a/src/app/routes/combat/states/combat-end-turn.state.ts
+++ b/src/app/routes/combat/states/combat-end-turn.state.ts
@@ -1,4 +1,3 @@
-
 import { Component } from '@angular/core';
 import { CombatService } from '../../../models/combat/combat.service';
 import { CombatMachineState } from './combat-base.state';
diff --git a/src/app/routes/combat/states/combat-escape.state.ts b/src/app/routes/combat/states/combat-escape.state.ts
index aa673b3f..37d348cf 100644
--- a/src/app/routes/combat/states/combat-escape.state.ts
+++ b/src/app/routes/combat/states/combat-escape.state.ts
@@ -1,4 +1,3 @@
-
 import { Component } from '@angular/core';
 import { Store } from '@ngrx/store';
 import { AppState } from '../../../../app/app.model';
diff --git a/src/app/routes/combat/states/combat-start.state.ts b/src/app/routes/combat/states/combat-start.state.ts
index d725c776..06cec778 100644
--- a/src/app/routes/combat/states/combat-start.state.ts
+++ b/src/app/routes/combat/states/combat-start.state.ts
@@ -1,4 +1,3 @@
-
 import { Component } from '@angular/core';
 import * as _ from 'underscore';
 import { NotificationService } from '../../../components/notification/notification.service';
diff --git a/src/app/routes/combat/states/combat-victory.state.spec.ts b/src/app/routes/combat/states/combat-victory.state.spec.ts
index d9dfd8fc..6fdbfaaa 100644
--- a/src/app/routes/combat/states/combat-victory.state.spec.ts
+++ b/src/app/routes/combat/states/combat-victory.state.spec.ts
@@ -52,7 +52,7 @@ describe('CombatVictoryStateComponent', () => {
     expect(machine.store.dispatch).toHaveBeenCalledWith(
       jasmine.objectContaining({
         type: CombatVictoryAction.typeId,
-      })
+      }),
     );
   });
 
@@ -76,7 +76,7 @@ describe('CombatVictoryStateComponent', () => {
       jasmine.objectContaining({
         type: GameStateAddGoldAction.typeId,
         payload: enemy.gold * 2,
-      })
+      }),
     );
   });
   it('awards items/gold from fixed encounters', async () => {
diff --git a/src/app/routes/combat/states/combat-victory.state.ts b/src/app/routes/combat/states/combat-victory.state.ts
index 8e6d7a57..0d147c0d 100644
--- a/src/app/routes/combat/states/combat-victory.state.ts
+++ b/src/app/routes/combat/states/combat-victory.state.ts
@@ -41,7 +41,10 @@ export class CombatVictoryStateComponent extends CombatMachineState {
   static NAME: CombatStateNames = 'victory';
   name: CombatStateNames = CombatVictoryStateComponent.NAME;
 
-  constructor(public store: Store<AppState>, public combatService: CombatService) {
+  constructor(
+    public store: Store<AppState>,
+    public combatService: CombatService,
+  ) {
     super();
   }
 
diff --git a/src/app/routes/combat/states/combat.machine.spec.ts b/src/app/routes/combat/states/combat.machine.spec.ts
index 31b1fba7..982d1a5b 100644
--- a/src/app/routes/combat/states/combat.machine.spec.ts
+++ b/src/app/routes/combat/states/combat.machine.spec.ts
@@ -95,7 +95,7 @@ describe('CombatStateMachineComponent', () => {
           damage: 1000,
           attacker: enemy.model,
           defender: player.model,
-        })
+        }),
       );
       fixture.detectChanges();
       expect(machine.getLiveParty().length).toEqual(combat.party.length - 1);
@@ -123,7 +123,7 @@ describe('CombatStateMachineComponent', () => {
           damage: 1000,
           attacker: player.model,
           defender: enemy.model,
-        })
+        }),
       );
       fixture.detectChanges();
       expect(machine.getLiveEnemies().length).toEqual(encounter.enemies.length - 1);
diff --git a/src/app/routes/combat/states/combat.machine.ts b/src/app/routes/combat/states/combat.machine.ts
index 9c4fd708..b7ea2619 100644
--- a/src/app/routes/combat/states/combat.machine.ts
+++ b/src/app/routes/combat/states/combat.machine.ts
@@ -1,4 +1,3 @@
-
 import {
   AfterViewInit,
   Component,
@@ -72,7 +71,10 @@ export class CombatStateMachineComponent
     return this._spells$.value;
   }
 
-  constructor(private combatService: CombatService, public store: Store<AppState>) {
+  constructor(
+    private combatService: CombatService,
+    public store: Store<AppState>,
+  ) {
     super();
   }
   world: GameWorld;
@@ -115,12 +117,12 @@ export class CombatStateMachineComponent
           const weapons = inventory.filter((i) => i?.type === 'weapon').toList();
           const armors = inventory
             .filter((i?) =>
-              ['helm', 'boots', 'shield', 'armor'].includes(i?.type || '')
+              ['helm', 'boots', 'shield', 'armor'].includes(i?.type || ''),
             )
             .toList();
           const spells = inventory.filter((i) => i?.type === 'spell').toList();
           return { items, weapons, armors, spells };
-        })
+        }),
       )
       .subscribe((values) => {
         const { items, weapons, armors, spells } = values;
diff --git a/src/app/routes/combat/states/index.ts b/src/app/routes/combat/states/index.ts
index 95aa3a81..8d4f0655 100644
--- a/src/app/routes/combat/states/index.ts
+++ b/src/app/routes/combat/states/index.ts
@@ -1,4 +1,3 @@
-
 import { CombatBeginTurnStateComponent } from './combat-begin-turn.state';
 import { CombatChooseActionStateComponent } from './combat-choose-action.state';
 import { CombatDefeatStateComponent } from './combat-defeat.state';
diff --git a/src/app/routes/game/game.component.ts b/src/app/routes/game/game.component.ts
index 17e463c5..106fcb55 100644
--- a/src/app/routes/game/game.component.ts
+++ b/src/app/routes/game/game.component.ts
@@ -13,7 +13,7 @@ export class GameComponent implements OnInit {
   constructor(
     public game: RPGGame,
     public notify: NotificationService,
-    public world: GameWorld
+    public world: GameWorld,
   ) {}
 
   ngOnInit() {
diff --git a/src/app/routes/game/game.resolver.ts b/src/app/routes/game/game.resolver.ts
index 805b5b68..bee902db 100644
--- a/src/app/routes/game/game.resolver.ts
+++ b/src/app/routes/game/game.resolver.ts
@@ -5,8 +5,11 @@ import { LoadingService } from '../../components/loading/loading.service';
 import { GameWorld } from '../../services/game-world';
 
 @Injectable()
-export class GameResolver  {
-  constructor(private world: GameWorld, private loadingService: LoadingService) {}
+export class GameResolver {
+  constructor(
+    private world: GameWorld,
+    private loadingService: LoadingService,
+  ) {}
 
   /** Resolve when the world ready$ observable emits */
   resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
diff --git a/src/app/routes/world/behaviors/combat-encounter.behavior.ts b/src/app/routes/world/behaviors/combat-encounter.behavior.ts
index 9fe7b7f5..8ff0c540 100644
--- a/src/app/routes/world/behaviors/combat-encounter.behavior.ts
+++ b/src/app/routes/world/behaviors/combat-encounter.behavior.ts
@@ -92,7 +92,7 @@ export class CombatEncounterBehaviorComponent extends SceneObjectBehavior {
 
     // Stop the moving entity until it has defeated the combat encounter.
     const mover = this.player.findBehavior(
-      PlayerBehaviorComponent
+      PlayerBehaviorComponent,
     ) as PlayerBehaviorComponent;
     if (mover) {
       mover.velocity.zero();
@@ -111,7 +111,7 @@ export class CombatEncounterBehaviorComponent extends SceneObjectBehavior {
                 } else {
                   return !target.water;
                 }
-              }
+              },
             );
 
             const viableEncounters = RANDOM_ENCOUNTERS_DATA.filter((enc: any) => {
@@ -143,9 +143,9 @@ export class CombatEncounterBehaviorComponent extends SceneObjectBehavior {
               party: List<Entity>(party),
             };
             this.store.dispatch(new CombatEncounterAction(payload));
-          }
+          },
         ),
-        take(1)
+        take(1),
       )
       .subscribe();
   }
diff --git a/src/app/routes/world/behaviors/map-feature-input.behavior.ts b/src/app/routes/world/behaviors/map-feature-input.behavior.ts
index 7f6a8512..d413f1a1 100644
--- a/src/app/routes/world/behaviors/map-feature-input.behavior.ts
+++ b/src/app/routes/world/behaviors/map-feature-input.behavior.ts
@@ -1,4 +1,3 @@
-
 import { Component, Input } from '@angular/core';
 import * as _ from 'underscore';
 import { Rect } from '../../../../app/core/rect';
diff --git a/src/app/routes/world/behaviors/player-behavior.ts b/src/app/routes/world/behaviors/player-behavior.ts
index ff92bf49..e3c7e005 100644
--- a/src/app/routes/world/behaviors/player-behavior.ts
+++ b/src/app/routes/world/behaviors/player-behavior.ts
@@ -1,4 +1,3 @@
-
 import { Component, EventEmitter, Input, Output } from '@angular/core';
 import { BasePlayerComponent } from '../../../behaviors/base-player.behavior';
 import { IMoveDescription } from '../../../behaviors/movable-behavior';
@@ -47,7 +46,7 @@ export class PlayerBehaviorComponent extends BasePlayerComponent {
       x,
       y,
       GameFeatureObject,
-      results
+      results,
     );
     if (collision) {
       for (i = 0; i < results.length; i++) {
diff --git a/src/app/routes/world/behaviors/player-camera.behavior.ts b/src/app/routes/world/behaviors/player-camera.behavior.ts
index 25e50d08..54fb446f 100644
--- a/src/app/routes/world/behaviors/player-camera.behavior.ts
+++ b/src/app/routes/world/behaviors/player-camera.behavior.ts
@@ -1,4 +1,3 @@
-
 import { Component } from '@angular/core';
 import { Point } from '../../../../app/core/point';
 import { CameraBehavior } from '../../../behaviors/camera-behavior';
@@ -31,11 +30,11 @@ export class PlayerCameraBehaviorComponent extends CameraBehavior {
     if (this.host.tileMap) {
       view.camera.point.x = Math.min(
         view.camera.point.x,
-        this.host.tileMap.bounds.extent.x - view.camera.extent.x
+        this.host.tileMap.bounds.extent.x - view.camera.extent.x,
       );
       view.camera.point.y = Math.min(
         view.camera.point.y,
-        this.host.tileMap.bounds.extent.y - view.camera.extent.y
+        this.host.tileMap.bounds.extent.y - view.camera.extent.y,
       );
       view.camera.point.x = Math.max(0, view.camera.point.x);
       view.camera.point.y = Math.max(0, view.camera.point.y);
diff --git a/src/app/routes/world/behaviors/player-look.behavior.ts b/src/app/routes/world/behaviors/player-look.behavior.ts
index a94e0bd6..e01ae04b 100644
--- a/src/app/routes/world/behaviors/player-look.behavior.ts
+++ b/src/app/routes/world/behaviors/player-look.behavior.ts
@@ -1,4 +1,3 @@
-
 import { Component, EventEmitter, Output } from '@angular/core';
 import { CollisionBehaviorComponent } from '../../../behaviors/collision.behavior';
 import { TickedBehavior } from '../../../behaviors/ticked-behavior';
@@ -35,10 +34,10 @@ export class PlayerTriggerBehaviorComponent extends TickedBehavior {
   syncBehavior(): boolean {
     super.syncBehavior();
     this.player = this.host.findBehavior(
-      PlayerBehaviorComponent
+      PlayerBehaviorComponent,
     ) as PlayerBehaviorComponent;
     this.collider = this.host.findBehavior(
-      CollisionBehaviorComponent
+      CollisionBehaviorComponent,
     ) as CollisionBehaviorComponent;
     return !!(this.player && this.collider);
   }
@@ -55,7 +54,7 @@ export class PlayerTriggerBehaviorComponent extends TickedBehavior {
       headingX,
       headingY,
       GameFeatureObject,
-      results
+      results,
     );
     const touched = results[0];
     const currentTouchId: string | null = this.featureObject?._uid || null;
diff --git a/src/app/routes/world/behaviors/player-map-path.behavior.ts b/src/app/routes/world/behaviors/player-map-path.behavior.ts
index d6897835..0dbaa934 100644
--- a/src/app/routes/world/behaviors/player-map-path.behavior.ts
+++ b/src/app/routes/world/behaviors/player-map-path.behavior.ts
@@ -1,4 +1,3 @@
-
 import { AfterViewInit, Component, Input, OnDestroy } from '@angular/core';
 import { Store } from '@ngrx/store';
 import { Subscription } from 'rxjs';
@@ -42,7 +41,7 @@ export class PlayerMapPathBehaviorComponent
       .subscribe((boarded) => {
         assertTrue(this.host, 'invalid host object');
         const player = this.host.findBehavior<PlayerBehaviorComponent>(
-          PlayerBehaviorComponent
+          PlayerBehaviorComponent,
         );
         if (player) {
           player.passableKeys = boarded ? ['shipPassable'] : ['passable'];
@@ -58,7 +57,7 @@ export class PlayerMapPathBehaviorComponent
 
     assertTrue(this.host, 'cannot build weighted graph without host object');
     const player = this.host.findBehavior<PlayerBehaviorComponent>(
-      PlayerBehaviorComponent
+      PlayerBehaviorComponent,
     );
     assertTrue(player, 'cannot build weighted graph without player object');
 
diff --git a/src/app/routes/world/behaviors/player-render.behavior.ts b/src/app/routes/world/behaviors/player-render.behavior.ts
index 491ac4f1..96aed1a2 100644
--- a/src/app/routes/world/behaviors/player-render.behavior.ts
+++ b/src/app/routes/world/behaviors/player-render.behavior.ts
@@ -1,4 +1,3 @@
-
 import { Component } from '@angular/core';
 import { Subscription } from 'rxjs';
 import { TickedBehavior } from '../../../behaviors/ticked-behavior';
diff --git a/src/app/routes/world/features/block-feature.component.ts b/src/app/routes/world/features/block-feature.component.ts
index 70380d94..52e09336 100644
--- a/src/app/routes/world/features/block-feature.component.ts
+++ b/src/app/routes/world/features/block-feature.component.ts
@@ -1,4 +1,3 @@
-
 import { Component, Input } from '@angular/core';
 import { ITiledObject } from '../../../core/resources/tiled/tiled.model';
 import { TileObject } from '../../../scene/tile-object';
diff --git a/src/app/routes/world/features/combat-feature.component.spec.ts b/src/app/routes/world/features/combat-feature.component.spec.ts
index 201173f6..10270742 100644
--- a/src/app/routes/world/features/combat-feature.component.spec.ts
+++ b/src/app/routes/world/features/combat-feature.component.spec.ts
@@ -30,7 +30,7 @@ class CombatFeatureTestMap extends TileMap {
 
 function getFeature(
   values: Partial<ITiledObject<ICombatFeatureProperties>> = {},
-  properties: Partial<ICombatFeatureProperties> = {}
+  properties: Partial<ICombatFeatureProperties> = {},
 ): ITiledObject<ICombatFeatureProperties> {
   return {
     name: 'feature',
@@ -60,7 +60,7 @@ function getEncounterType(store: Store<AppState>): string {
 function getScene(
   comp: CombatFeatureComponent,
   map: TileMap | null = null,
-  addPlayer: boolean = true
+  addPlayer: boolean = true,
 ): {
   scene: Scene;
   object: GameFeatureObject;
diff --git a/src/app/routes/world/features/combat-feature.component.ts b/src/app/routes/world/features/combat-feature.component.ts
index 222a7844..dcccef02 100644
--- a/src/app/routes/world/features/combat-feature.component.ts
+++ b/src/app/routes/world/features/combat-feature.component.ts
@@ -1,4 +1,3 @@
-
 import { Component, Input } from '@angular/core';
 import { getEnemyById } from 'app/models/game-data/enemies';
 import { getFixedEncounterById } from 'app/models/game-data/fixed-encounters';
@@ -70,14 +69,14 @@ export class CombatFeatureComponent extends MapFeatureComponent {
       .pipe(
         map((party: Immutable.List<Entity>) => {
           const encounter: ITemplateFixedEncounter | null = getFixedEncounterById(
-            properties.id
+            properties.id,
           );
 
           if (!encounter) {
             this.notify.show(
               `There is no encounter named: ${properties.id}.`,
               undefined,
-              0
+              0,
             );
             return;
           }
@@ -99,7 +98,7 @@ export class CombatFeatureComponent extends MapFeatureComponent {
           };
           this.store.dispatch(new CombatEncounterAction(payload));
         }),
-        take(1)
+        take(1),
       )
       .subscribe();
     return true;
diff --git a/src/app/routes/world/features/dialog-feature.component.spec.ts b/src/app/routes/world/features/dialog-feature.component.spec.ts
index e069265f..a27aa9ac 100644
--- a/src/app/routes/world/features/dialog-feature.component.spec.ts
+++ b/src/app/routes/world/features/dialog-feature.component.spec.ts
@@ -14,7 +14,7 @@ import {
 
 function getFeature(
   values: Partial<ITiledObject<IDialogFeatureProperties>> = {},
-  properties: Partial<IDialogFeatureProperties> = {}
+  properties: Partial<IDialogFeatureProperties> = {},
 ): ITiledObject<IDialogFeatureProperties> {
   return {
     name: 'feature',
diff --git a/src/app/routes/world/features/dialog-feature.component.ts b/src/app/routes/world/features/dialog-feature.component.ts
index 230d3c40..372c1dbf 100644
--- a/src/app/routes/world/features/dialog-feature.component.ts
+++ b/src/app/routes/world/features/dialog-feature.component.ts
@@ -36,14 +36,14 @@ export class DialogFeatureComponent extends MapFeatureComponent {
   text$: Observable<string> = this.feature$.pipe(
     map((f: ITiledObject) => {
       return f.properties.text;
-    })
+    }),
   );
 
   /** The dialog title */
   title$: Observable<string> = this.feature$.pipe(
     map((f: ITiledObject) => {
       return f.properties.title;
-    })
+    }),
   );
 
   /** The icon to display for the dialog speaker */
@@ -58,14 +58,14 @@ export class DialogFeatureComponent extends MapFeatureComponent {
       }
       // Fallback to using the "icon" custom property
       return f.properties.icon;
-    })
+    }),
   );
 
   /** An optional additional icon to display for the dialog */
   altIcon$: Observable<string> = this.feature$.pipe(
     map((f: ITiledObject) => {
       return f.properties.altIcon;
-    })
+    }),
   );
 
   exit(object: TileObject): boolean {
diff --git a/src/app/routes/world/features/door-feature.component.spec.ts b/src/app/routes/world/features/door-feature.component.spec.ts
index 3b9bc003..0ea85d1d 100644
--- a/src/app/routes/world/features/door-feature.component.spec.ts
+++ b/src/app/routes/world/features/door-feature.component.spec.ts
@@ -12,7 +12,7 @@ import { DoorFeatureComponent, IDoorFeatureProperties } from './door-feature.com
 
 function getFeature(
   values: Partial<ITiledObject<IDoorFeatureProperties>> = {},
-  properties: Partial<IDoorFeatureProperties> = {}
+  properties: Partial<IDoorFeatureProperties> = {},
 ): ITiledObject<IDoorFeatureProperties> {
   return {
     name: 'feature',
@@ -85,7 +85,7 @@ describe('DoorFeatureComponent', () => {
 
     // Acquire the key
     world.store.dispatch(
-      new GameStateSetKeyDataAction(comp.feature.properties?.requiredKey || '', true)
+      new GameStateSetKeyDataAction(comp.feature.properties?.requiredKey || '', true),
     );
 
     comp.enter(tileObject);
diff --git a/src/app/routes/world/features/door-feature.component.ts b/src/app/routes/world/features/door-feature.component.ts
index 470a4ea5..c7dc97ff 100644
--- a/src/app/routes/world/features/door-feature.component.ts
+++ b/src/app/routes/world/features/door-feature.component.ts
@@ -37,12 +37,12 @@ export class DoorFeatureComponent extends MapFeatureComponent {
   requiredKey$: Observable<string> = this.feature$.pipe(
     map((f: ITiledObject) => {
       return f.properties?.requiredKey || '';
-    })
+    }),
   );
   id$: Observable<string> = this.feature$.pipe(
     map((f: ITiledObject) => {
       return f.properties?.id || '';
-    })
+    }),
   );
   canUnlock$: Observable<boolean> = this.feature$.pipe(
     switchMap((f: ITiledObject) => {
@@ -51,28 +51,28 @@ export class DoorFeatureComponent extends MapFeatureComponent {
       }
       return this.store.select(getGameKey(f.properties.requiredKey));
     }),
-    map((value) => !!value)
+    map((value) => !!value),
   );
   cantUnlock$: Observable<boolean> = this.canUnlock$.pipe(map((value) => !value));
   icon$: Observable<string> = this.feature$.pipe(
     map((f: ITiledObject) => {
       return f.properties?.icon || '';
-    })
+    }),
   );
   title$: Observable<string> = this.feature$.pipe(
     map((f: ITiledObject) => {
       return f.properties?.title || '';
-    })
+    }),
   );
   lockedText$: Observable<string> = this.feature$.pipe(
     map((f: ITiledObject) => {
       return f.properties?.lockedText || '';
-    })
+    }),
   );
   unlockText$: Observable<string> = this.feature$.pipe(
     map((f: ITiledObject) => {
       return f.properties?.unlockText || '';
-    })
+    }),
   );
 
   exit(object: TileObject): boolean {
@@ -89,9 +89,9 @@ export class DoorFeatureComponent extends MapFeatureComponent {
             return;
           }
           this.store.dispatch(
-            new GameStateSetKeyDataAction(this.feature.properties.id, true)
+            new GameStateSetKeyDataAction(this.feature.properties.id, true),
           );
-        })
+        }),
       )
       .subscribe();
     return true;
diff --git a/src/app/routes/world/features/portal-feature.component.spec.ts b/src/app/routes/world/features/portal-feature.component.spec.ts
index d8b9f998..d348c3ad 100644
--- a/src/app/routes/world/features/portal-feature.component.spec.ts
+++ b/src/app/routes/world/features/portal-feature.component.spec.ts
@@ -25,7 +25,7 @@ function getPartyLocationInfo(store: Store<AppState>): IPortalFeatureProperties
         const position = args[0];
         const target = args[1];
         return { target, targetX: position.x, targetY: position.y };
-      })
+      }),
     )
     .subscribe((r) => (result = r));
   assertTrue(result, 'invalid party data');
@@ -34,7 +34,7 @@ function getPartyLocationInfo(store: Store<AppState>): IPortalFeatureProperties
 
 function getFeature(
   values: Partial<ITiledObject<IPortalFeatureProperties>> = {},
-  properties: Partial<IPortalFeatureProperties> = {}
+  properties: Partial<IPortalFeatureProperties> = {},
 ): ITiledObject<IPortalFeatureProperties> {
   return {
     name: 'feature',
diff --git a/src/app/routes/world/features/portal-feature.component.ts b/src/app/routes/world/features/portal-feature.component.ts
index 59e90d8d..77172070 100644
--- a/src/app/routes/world/features/portal-feature.component.ts
+++ b/src/app/routes/world/features/portal-feature.component.ts
@@ -1,4 +1,3 @@
-
 import { Component, Input } from '@angular/core';
 import { ITiledObject } from '../../../core/resources/tiled/tiled.model';
 import { GameStateTravelAction } from '../../../models/game-state/game-state.actions';
@@ -34,7 +33,7 @@ export class PortalFeatureComponent extends MapFeatureComponent {
           x: props.targetX,
           y: props.targetY,
         },
-      })
+      }),
     );
     return true;
   }
diff --git a/src/app/routes/world/features/ship-feature.component.spec.ts b/src/app/routes/world/features/ship-feature.component.spec.ts
index 1d0e16af..6ed939be 100644
--- a/src/app/routes/world/features/ship-feature.component.spec.ts
+++ b/src/app/routes/world/features/ship-feature.component.spec.ts
@@ -14,7 +14,7 @@ import { IShipFeatureProperties, ShipFeatureComponent } from './ship-feature.com
 
 function getFeature(
   values: Partial<ITiledObject<IShipFeatureProperties>> = {},
-  properties: Partial<IShipFeatureProperties> = {}
+  properties: Partial<IShipFeatureProperties> = {},
 ): ITiledObject<IShipFeatureProperties> {
   return {
     name: 'feature',
@@ -38,7 +38,7 @@ function getScene(comp: ShipFeatureComponent): {
   const scene = new Scene();
   const object = new GameFeatureObject();
   object.addBehavior(
-    TestBed.createComponent(PlayerBehaviorComponent).componentInstance
+    TestBed.createComponent(PlayerBehaviorComponent).componentInstance,
   );
   scene.addObject(object);
   scene.addObject(comp);
@@ -75,7 +75,7 @@ describe('ShipFeatureComponent', () => {
       // Add a party
       const tileObject = new GameFeatureObject();
       tileObject.addBehavior(
-        TestBed.createComponent(PlayerBehaviorComponent).componentInstance
+        TestBed.createComponent(PlayerBehaviorComponent).componentInstance,
       );
 
       comp.feature = getFeature();
diff --git a/src/app/routes/world/features/ship-feature.component.ts b/src/app/routes/world/features/ship-feature.component.ts
index 163cbb3c..983e1578 100644
--- a/src/app/routes/world/features/ship-feature.component.ts
+++ b/src/app/routes/world/features/ship-feature.component.ts
@@ -1,4 +1,3 @@
-
 import { AfterViewInit, Component, OnDestroy } from '@angular/core';
 import { Subscription } from 'rxjs';
 import { debounceTime, distinctUntilChanged, first } from 'rxjs/operators';
@@ -45,7 +44,7 @@ export class ShipFeatureComponent
       .subscribe((boarded: boolean) => {
         if (boarded && this.scene) {
           const playerObj = this.scene.objectByComponent<GameFeatureObject>(
-            PlayerBehaviorComponent
+            PlayerBehaviorComponent,
           );
           if (playerObj) {
             this.enter(playerObj);
diff --git a/src/app/routes/world/features/store-feature.component.spec.ts b/src/app/routes/world/features/store-feature.component.spec.ts
index b5a5c16f..36360a9f 100644
--- a/src/app/routes/world/features/store-feature.component.spec.ts
+++ b/src/app/routes/world/features/store-feature.component.spec.ts
@@ -32,7 +32,7 @@ import {
 
 function getFeature(
   values: Partial<ITiledObject<IStoreFeatureProperties>> = {},
-  properties: Partial<IStoreFeatureProperties> = {}
+  properties: Partial<IStoreFeatureProperties> = {},
 ): ITiledObject<IStoreFeatureProperties> {
   return {
     name: 'feature',
@@ -140,11 +140,11 @@ describe('StoreFeatureComponent', () => {
 
       // Equip a short-sword
       const warrior = testAppGetPartyWithEquipment(world.store).find(
-        (p) => p.type === 'warrior'
+        (p) => p.type === 'warrior',
       );
       assertTrue(warrior, 'no warrior class in default party');
       const itemInstance = instantiateEntity<Weapon>(
-        WEAPONS_DATA.find((f) => f.id === 'short-sword')
+        WEAPONS_DATA.find((f) => f.id === 'short-sword'),
       );
       world.store.dispatch(new EntityAddItemAction(itemInstance));
       world.store.dispatch(new GameStateAddInventoryAction(itemInstance));
@@ -154,14 +154,14 @@ describe('StoreFeatureComponent', () => {
           entityId: warrior.eid,
           slot: 'weapon',
           itemId: warrior.weapon?.eid || '',
-        })
+        }),
       );
       world.store.dispatch(
         new GameStateEquipItemAction({
           entityId: warrior.eid,
           slot: 'weapon',
           itemId: itemInstance.eid,
-        })
+        }),
       );
 
       comp.enter(tileObject);
@@ -179,7 +179,7 @@ describe('StoreFeatureComponent', () => {
       let selection = getStoreSelection(comp.selected$);
       expect(selection.length).toBe(1);
       expect(
-        fixture.debugElement.query(By.css('.warrior > .downgrade'))
+        fixture.debugElement.query(By.css('.warrior > .downgrade')),
       ).not.toBeNull();
 
       // Selecting short-sword shows neither upgrade or downgrade
diff --git a/src/app/routes/world/features/store-feature.component.ts b/src/app/routes/world/features/store-feature.component.ts
index f418cc50..9cab2554 100644
--- a/src/app/routes/world/features/store-feature.component.ts
+++ b/src/app/routes/world/features/store-feature.component.ts
@@ -94,7 +94,7 @@ export class StoreFeatureComponent extends MapFeatureComponent {
    * The name of this (fine) establishment.
    */
   name$: Observable<string> = this.feature$.pipe(
-    map((f: ITiledObject<any> | null) => f?.name || '')
+    map((f: ITiledObject<any> | null) => f?.name || ''),
   );
 
   /**
@@ -111,7 +111,7 @@ export class StoreFeatureComponent extends MapFeatureComponent {
       map((inventory: Immutable.List<Item>) => {
         const result = inventory.toList();
         return result;
-      })
+      }),
     );
 
   /**
@@ -135,8 +135,8 @@ export class StoreFeatureComponent extends MapFeatureComponent {
           ITemplateMagic[] | null,
           ITiledObject<any> | null,
           boolean,
-          Immutable.List<Item> | null
-        ]
+          Immutable.List<Item> | null,
+        ],
       ): ITemplateBaseItem[] => {
         const weapons: ITemplateWeapon[] | null = params[0];
         const armors: ITemplateArmor[] | null = params[1];
@@ -174,8 +174,8 @@ export class StoreFeatureComponent extends MapFeatureComponent {
             data = items.concat(weapons).concat(armors);
         }
         return data;
-      }
-    )
+      },
+    ),
   );
 
   dataSource$ = this.inventory$.pipe(map((data) => new MatTableDataSource(data)));
@@ -197,7 +197,7 @@ export class StoreFeatureComponent extends MapFeatureComponent {
   ]).pipe(
     map(
       (
-        params: [Set<Item>, Immutable.List<EntityWithEquipment>]
+        params: [Set<Item>, Immutable.List<EntityWithEquipment>],
       ): IEquipmentDifference[] => {
         const selected: Set<Item> = params[0];
         const party: Immutable.List<EntityWithEquipment> = params[1];
@@ -264,8 +264,8 @@ export class StoreFeatureComponent extends MapFeatureComponent {
           }
           return r;
         });
-      }
-    )
+      },
+    ),
   );
 
   /** The GameState, but only valid when buying */
@@ -280,7 +280,7 @@ export class StoreFeatureComponent extends MapFeatureComponent {
         const isSelling: boolean = params[1];
         const party: Immutable.List<EntityWithEquipment> = params[2];
         return !isSelling ? [state, party] : null;
-      })
+      }),
     );
 
   close() {
@@ -315,7 +315,7 @@ export class StoreFeatureComponent extends MapFeatureComponent {
     console.log('selling', items);
     const totalCost: number = items.reduce(
       (prev: number, current: Item) => prev + current.value,
-      0
+      0,
     );
     this._selected$.next(new Set());
     items.forEach((item) => {
@@ -326,14 +326,14 @@ export class StoreFeatureComponent extends MapFeatureComponent {
     this.notify.show(
       `Sold ${items.length} items for ${totalCost} gold.`,
       undefined,
-      1500
+      1500,
     );
   }
   buyItems(state: GameState, party: Immutable.List<EntityWithEquipment>) {
     const items: Item[] = [...this._selected$.value];
     const totalCost: number = items.reduce(
       (prev: number, current: Item) => prev + current.value,
-      0
+      0,
     );
     if (totalCost > state.gold) {
       this.notify.show("You don't have enough money");
@@ -382,7 +382,7 @@ export class StoreFeatureComponent extends MapFeatureComponent {
                 entityId: toEquip.eid,
                 slot: toEquipItem.type as keyof EntitySlots,
                 itemId: oldItem.eid,
-              })
+              }),
             );
           }
         }
@@ -391,13 +391,13 @@ export class StoreFeatureComponent extends MapFeatureComponent {
             entityId: toEquip.eid,
             slot: toEquipItem.type as keyof EntitySlots,
             itemId: toEquipItem.eid,
-          })
+          }),
         );
       }
       this.notify.show(
         `Purchased ${toEquipItem.name} for ${totalCost} gold and equipped it on ${toEquip?.name}.`,
         undefined,
-        5000
+        5000,
       );
       return;
     }
@@ -406,7 +406,7 @@ export class StoreFeatureComponent extends MapFeatureComponent {
     this.notify.show(
       `Purchased ${itemText} items for ${totalCost} gold.`,
       undefined,
-      1500
+      1500,
     );
   }
 
diff --git a/src/app/routes/world/features/temple-feature.component.spec.ts b/src/app/routes/world/features/temple-feature.component.spec.ts
index f1752cd6..6f53b995 100644
--- a/src/app/routes/world/features/temple-feature.component.spec.ts
+++ b/src/app/routes/world/features/temple-feature.component.spec.ts
@@ -18,7 +18,7 @@ import {
 
 function getFeature(
   values: Partial<ITiledObject<ITempleFeatureProperties>> = {},
-  properties: Partial<ITempleFeatureProperties> = {}
+  properties: Partial<ITempleFeatureProperties> = {},
 ): ITiledObject<ITempleFeatureProperties> {
   return {
     name: 'feature',
@@ -66,7 +66,7 @@ describe('TempleFeatureComponent', () => {
 
     // Assert members are damaged by 10
     testAppGetPartyWithEquipment(world.store).forEach((p) =>
-      expect(p.hp).toBe(p.maxhp - 10)
+      expect(p.hp).toBe(p.maxhp - 10),
     );
 
     const doRest = fixture.debugElement.query(By.css('.rest'));
@@ -74,7 +74,7 @@ describe('TempleFeatureComponent', () => {
 
     // Party at max health again
     testAppGetPartyWithEquipment(world.store).forEach((p) =>
-      expect(p.maxhp).toBe(p.hp)
+      expect(p.maxhp).toBe(p.hp),
     );
   });
   it('should fail to heal when party does not have enough money', async () => {
@@ -91,7 +91,7 @@ describe('TempleFeatureComponent', () => {
 
     // Assert members are damaged by 10
     testAppGetPartyWithEquipment(world.store).forEach((p) =>
-      expect(p.hp).toBe(p.maxhp - 10)
+      expect(p.hp).toBe(p.maxhp - 10),
     );
 
     const doRest = fixture.debugElement.query(By.css('.rest'));
@@ -99,7 +99,7 @@ describe('TempleFeatureComponent', () => {
 
     // Party still at damaged health
     testAppGetPartyWithEquipment(world.store).forEach((p) =>
-      expect(p.hp).toBe(p.maxhp - 10)
+      expect(p.hp).toBe(p.maxhp - 10),
     );
   });
   it('should not take money when party is already healed', async () => {
@@ -111,7 +111,7 @@ describe('TempleFeatureComponent', () => {
     fixture.detectChanges();
     // Party at full health
     testAppGetPartyWithEquipment(world.store).forEach((p) =>
-      expect(p.hp).toBe(p.maxhp)
+      expect(p.hp).toBe(p.maxhp),
     );
     expect(testAppGetPartyGold(world.store)).toBe(100);
 
diff --git a/src/app/routes/world/features/temple-feature.component.ts b/src/app/routes/world/features/temple-feature.component.ts
index e7b2e317..123eabdc 100644
--- a/src/app/routes/world/features/temple-feature.component.ts
+++ b/src/app/routes/world/features/temple-feature.component.ts
@@ -44,19 +44,19 @@ export class TempleFeatureComponent
   name$: Observable<string> = this.feature$.pipe(
     map((data: ITiledObject | null) => {
       return data?.name || 'temple';
-    })
+    }),
   );
 
   icon$: Observable<string> = this.feature$.pipe(
     map((data: ITiledObject | null) => {
       return data?.properties?.icon;
-    })
+    }),
   );
 
   cost$: Observable<number> = this.feature$.pipe(
     map((data: ITiledObject | null) => {
       return parseInt(data?.properties?.cost, 10);
-    })
+    }),
   );
 
   public _onRest$ = new Subject<void>();
@@ -86,7 +86,7 @@ export class TempleFeatureComponent
                 new GameStateHealPartyAction({
                   cost,
                   partyIds,
-                })
+                }),
               );
               const msg =
                 'Your party has been healed! \nYou have (' +
@@ -95,8 +95,8 @@ export class TempleFeatureComponent
               this.notify.show(msg, undefined, 5000);
             }
             this.onClose.next({});
-          }
-        )
+          },
+        ),
       )
       .subscribe();
   }
diff --git a/src/app/routes/world/features/treasure-feature.component.spec.ts b/src/app/routes/world/features/treasure-feature.component.spec.ts
index ef696682..a8d1861b 100644
--- a/src/app/routes/world/features/treasure-feature.component.spec.ts
+++ b/src/app/routes/world/features/treasure-feature.component.spec.ts
@@ -13,7 +13,7 @@ import {
 
 function getFeature(
   values: Partial<ITiledObject<ITreasureFeatureProperties>> = {},
-  properties: Partial<ITreasureFeatureProperties> = {}
+  properties: Partial<ITreasureFeatureProperties> = {},
 ): ITiledObject<ITreasureFeatureProperties> {
   return {
     name: 'feature',
diff --git a/src/app/routes/world/features/treasure-feature.component.ts b/src/app/routes/world/features/treasure-feature.component.ts
index ffefec30..c93c3211 100644
--- a/src/app/routes/world/features/treasure-feature.component.ts
+++ b/src/app/routes/world/features/treasure-feature.component.ts
@@ -1,4 +1,3 @@
-
 import { AfterViewInit, Component, Input } from '@angular/core';
 import { getArmorById } from 'app/models/game-data/armors';
 import { getItemById } from 'app/models/game-data/items';
diff --git a/src/app/routes/world/map-feature.component.ts b/src/app/routes/world/map-feature.component.ts
index e78c16e3..a971fec5 100644
--- a/src/app/routes/world/map-feature.component.ts
+++ b/src/app/routes/world/map-feature.component.ts
@@ -99,7 +99,7 @@ export class MapFeatureComponent
   constructor(
     public store: Store<AppState>,
     public notify: NotificationService,
-    public game: RPGGame
+    public game: RPGGame,
   ) {
     super(null, null);
   }
diff --git a/src/app/routes/world/world-player.component.ts b/src/app/routes/world/world-player.component.ts
index 69aa96bb..ac4dd5de 100644
--- a/src/app/routes/world/world-player.component.ts
+++ b/src/app/routes/world/world-player.component.ts
@@ -150,14 +150,14 @@ export class WorldPlayerComponent
         destination.y -= 0.5;
 
         const screenTile: Rect = view.worldToScreen(
-          new Rect(destination, new Point(1, 1))
+          new Rect(destination, new Point(1, 1)),
         );
         view.context.fillStyle = this.targetFill;
         view.context.fillRect(
           screenTile.point.x,
           screenTile.point.y,
           screenTile.extent.x,
-          screenTile.extent.y
+          screenTile.extent.y,
         );
         view.context.strokeStyle = this.targetStroke;
         view.context.lineWidth = this.targetStrokeWidth;
@@ -165,7 +165,7 @@ export class WorldPlayerComponent
           screenTile.point.x,
           screenTile.point.y,
           screenTile.extent.x,
-          screenTile.extent.y
+          screenTile.extent.y,
         );
 
         view.context.restore();
diff --git a/src/app/routes/world/world.component.ts b/src/app/routes/world/world.component.ts
index 59c90d0c..2d492c9a 100644
--- a/src/app/routes/world/world.component.ts
+++ b/src/app/routes/world/world.component.ts
@@ -78,14 +78,14 @@ export class WorldComponent extends SceneView implements AfterViewInit, OnDestro
     map((result: TiledTMXResource) => {
       this.map.setMap(result);
       return result;
-    })
+    }),
   );
 
   /** Features can be derived after a new map resource has been loaded */
   features$: Observable<ITiledObject[]> = this.resource$.pipe(
     map(() => {
       return this.map.features?.objects || [];
-    })
+    }),
   );
 
   /**
@@ -116,11 +116,11 @@ export class WorldComponent extends SceneView implements AfterViewInit, OnDestro
         return true;
       });
       return out;
-    }
+    },
   );
 
   notTraveling$: Observable<boolean> = this.loadingService.loading$.pipe(
-    map((loading: boolean) => !loading)
+    map((loading: boolean) => !loading),
   );
 
   /** Observable of the current player position in the world. Keeps renderPoint in sync after each move. */
@@ -129,17 +129,17 @@ export class WorldComponent extends SceneView implements AfterViewInit, OnDestro
     map((position: IPoint) => {
       this.renderPoint = new Point(position);
       return this.renderPoint;
-    })
+    }),
   );
 
   /** Observable of Entity representing the player-card leader to be rendered in the world */
   partyLeader$: Observable<Entity | null> = this.store.select(getGameParty).pipe(
     map((party: Immutable.List<Entity>) => {
       return party.get(0) || null;
-    })
+    }),
   );
   private _renderPoint$: BehaviorSubject<IPoint> = new BehaviorSubject(
-    this.renderPoint
+    this.renderPoint,
   );
 
   /** Observable of the current player position in the world */
@@ -148,7 +148,7 @@ export class WorldComponent extends SceneView implements AfterViewInit, OnDestro
     (point: IPoint, renderPoint: IPoint) => {
       this.renderPoint.set(point || renderPoint);
       return this.renderPoint;
-    }
+    },
   );
 
   /**
@@ -195,7 +195,7 @@ export class WorldComponent extends SceneView implements AfterViewInit, OnDestro
     public gameStateService: GameStateService,
     public loadingService: LoadingService,
     public store: Store<AppState>,
-    public world: GameWorld
+    public world: GameWorld,
   ) {
     super();
     this.world.mark(this.scene);
@@ -253,13 +253,13 @@ export class WorldComponent extends SceneView implements AfterViewInit, OnDestro
     const pathComponent =
       this.player.findBehavior<TileMapPathBehavior>(TileMapPathBehavior);
     const playerComponent = this.player.findBehavior<PlayerBehaviorComponent>(
-      PlayerBehaviorComponent
+      PlayerBehaviorComponent,
     );
     if (pathComponent && playerComponent && this.mouse) {
       PowInput.mouseOnView(e, this.mouse.view, this.mouse);
       playerComponent.path = pathComponent.calculatePath(
         playerComponent.targetPoint,
-        this.mouse.world
+        this.mouse.world,
       );
       e.preventDefault();
       return false;
@@ -279,7 +279,7 @@ export class WorldComponent extends SceneView implements AfterViewInit, OnDestro
           this.objectRenderer.render(
             data as TileRenderable,
             data.renderPoint || data.point,
-            this
+            this,
           );
         }
       });
@@ -300,18 +300,18 @@ export class WorldComponent extends SceneView implements AfterViewInit, OnDestro
   debugRender() {
     const debugStrings = [`Camera: (${this.camera.point.x},${this.camera.point.y})`];
     const player = this.scene.objectByComponent<WorldPlayerComponent>(
-      PlayerBehaviorComponent
+      PlayerBehaviorComponent,
     );
     if (!player) {
       return;
     }
     debugStrings.push(`Player: (${player.point.x},${player.point.y})`);
     const playerBehavior = player.findBehavior<PlayerBehaviorComponent>(
-      PlayerBehaviorComponent
+      PlayerBehaviorComponent,
     );
     const clipRect = this.getCameraClip();
     debugStrings.push(
-      `Clip: (${clipRect.point.x},${clipRect.point.y}) (${clipRect.extent.x},${clipRect.extent.y})`
+      `Clip: (${clipRect.point.x},${clipRect.point.y}) (${clipRect.extent.x},${clipRect.extent.y})`,
     );
 
     if (!this.context) {
@@ -325,7 +325,7 @@ export class WorldComponent extends SceneView implements AfterViewInit, OnDestro
       screenClip.point.x,
       screenClip.point.y,
       screenClip.extent.x,
-      screenClip.extent.y
+      screenClip.extent.y,
     );
 
     // Render impassable tiles on the map in the clip rect
@@ -346,13 +346,13 @@ export class WorldComponent extends SceneView implements AfterViewInit, OnDestro
             const key = playerBehavior.passableKeys[j];
             if (tile.properties && tile.properties[key] === false) {
               const screenTile: Rect = this.worldToScreen(
-                new Rect(new Point(x - 0.5, y - 0.5), new Point(1, 1))
+                new Rect(new Point(x - 0.5, y - 0.5), new Point(1, 1)),
               );
               this.context?.strokeRect(
                 screenTile.point.x,
                 screenTile.point.y,
                 screenTile.extent.x,
-                screenTile.extent.y
+                screenTile.extent.y,
               );
             }
           }
@@ -366,13 +366,13 @@ export class WorldComponent extends SceneView implements AfterViewInit, OnDestro
     tiles.forEach((object: any) => {
       const point = object.renderPoint || object.point;
       const screenTile: Rect = this.worldToScreen(
-        new Rect(new Point(point.x - 0.5, point.y - 0.5), new Point(1, 1))
+        new Rect(new Point(point.x - 0.5, point.y - 0.5), new Point(1, 1)),
       );
       this.context?.strokeRect(
         screenTile.point.x,
         screenTile.point.y,
         screenTile.extent.x,
-        screenTile.extent.y
+        screenTile.extent.y,
       );
     });
 
diff --git a/src/app/routes/world/world.guards.ts b/src/app/routes/world/world.guards.ts
index 65beeb40..2b758f9e 100644
--- a/src/app/routes/world/world.guards.ts
+++ b/src/app/routes/world/world.guards.ts
@@ -7,12 +7,15 @@ import { AppState } from '../../app.model';
 import { getGameMap } from '../../models/selectors';
 
 @Injectable()
-export class CanActivateWorld  {
-  constructor(private store: Store<AppState>, private router: Router) {}
+export class CanActivateWorld {
+  constructor(
+    private store: Store<AppState>,
+    private router: Router,
+  ) {}
 
   canActivate(
     route: ActivatedRouteSnapshot,
-    state: RouterStateSnapshot
+    state: RouterStateSnapshot,
   ): Observable<boolean> {
     // TODO: This check is hosed if a reasonable default value is set for the initial state for
     // map. Investigate whether this is sane.
@@ -29,7 +32,7 @@ export class CanActivateWorld  {
           return false;
         }
         return true;
-      })
+      }),
     );
   }
 }
diff --git a/src/app/routes/world/world.stories.ts b/src/app/routes/world/world.stories.ts
index 93b0bd51..be6a0edb 100644
--- a/src/app/routes/world/world.stories.ts
+++ b/src/app/routes/world/world.stories.ts
@@ -19,7 +19,10 @@ import { Warrior } from '../../models/mechanics.mock';
   template: `<loading></loading><world [debug]="debug"></world>`,
 })
 class Wrapper implements AfterViewInit {
-  constructor(public store: Store<AppState>, public loadingService: LoadingService) {}
+  constructor(
+    public store: Store<AppState>,
+    public loadingService: LoadingService,
+  ) {}
   @Input() debug: boolean;
   @Input() location: string = 'town';
   @Input() position: IPoint;
diff --git a/src/app/scene/objects/game-entity-object.spec.ts b/src/app/scene/objects/game-entity-object.spec.ts
index 5c950ff1..8b618d81 100644
--- a/src/app/scene/objects/game-entity-object.spec.ts
+++ b/src/app/scene/objects/game-entity-object.spec.ts
@@ -12,7 +12,7 @@ describe('GameEntityObject', () => {
         hp: 0,
         maxhp: 0,
       },
-      values || {}
+      values || {},
     ) as any;
   }
 
diff --git a/src/app/scene/objects/game-entity-object.ts b/src/app/scene/objects/game-entity-object.ts
index 932d533e..2ad6f01d 100644
--- a/src/app/scene/objects/game-entity-object.ts
+++ b/src/app/scene/objects/game-entity-object.ts
@@ -1,4 +1,3 @@
-
 import { CombatantTypes } from '../../models/base-entity';
 import { GameWorld } from '../../services/game-world';
 import { TileObject } from '../tile-object';
diff --git a/src/app/scene/objects/game-feature-object.ts b/src/app/scene/objects/game-feature-object.ts
index 996cf4fa..2af6a50a 100644
--- a/src/app/scene/objects/game-feature-object.ts
+++ b/src/app/scene/objects/game-feature-object.ts
@@ -1,5 +1,3 @@
-
-
 import { BehaviorSubject, Observable } from 'rxjs';
 import { ITiledObject } from '../../core/resources/tiled/tiled.model';
 import { GameWorld } from '../../services/game-world';
@@ -33,7 +31,7 @@ export class GameFeatureObject extends TileObject {
 
   constructor(
     feature: ITiledObject | null = null,
-    public tileMap: TileMap | null = null
+    public tileMap: TileMap | null = null,
   ) {
     super();
     this.feature = feature;
diff --git a/src/app/scene/render/tile-map-renderer.ts b/src/app/scene/render/tile-map-renderer.ts
index 8b856445..73c12cb2 100644
--- a/src/app/scene/render/tile-map-renderer.ts
+++ b/src/app/scene/render/tile-map-renderer.ts
@@ -1,4 +1,3 @@
-
 import * as _ from 'underscore';
 import { Rect } from '../../core/rect';
 import { ITileInstanceMeta } from '../../core/resources/tiled/tiled';
@@ -94,7 +93,7 @@ export class TileMapRenderer {
                         dstX,
                         dstY,
                         dstW,
-                        dstH
+                        dstH,
                       );
                     }
                   });
@@ -105,7 +104,7 @@ export class TileMapRenderer {
               // var dataImage = new Image();
               // dataImage.src = ctx.canvas.toDataURL();
               // $('body').append(dataImage);
-            }
+            },
           );
         }
       }
@@ -123,7 +122,7 @@ export class TileMapRenderer {
           col * squareUnits - 0.5,
           row * squareUnits - 0.5,
           squareUnits,
-          squareUnits
+          squareUnits,
         );
         view.fastWorldToScreenRect(this._renderRect, this._renderRect);
         if (!this._renderRect.intersect(this._clipRect)) {
@@ -141,7 +140,7 @@ export class TileMapRenderer {
           this._renderRect.point.x,
           this._renderRect.point.y,
           squareScreen,
-          squareScreen
+          squareScreen,
         );
       }
     }
diff --git a/src/app/scene/render/tile-object-renderer.ts b/src/app/scene/render/tile-object-renderer.ts
index 6f86e9d2..f8bf6903 100644
--- a/src/app/scene/render/tile-object-renderer.ts
+++ b/src/app/scene/render/tile-object-renderer.ts
@@ -1,5 +1,3 @@
-
-
 import { IPoint, Point } from '../../core';
 import { ISpriteMeta } from '../../core/api';
 import { SceneView } from '../scene-view';
@@ -58,7 +56,7 @@ export class TileObjectRenderer {
         point.x,
         point.y,
         sourceWidth * scale,
-        sourceHeight * scale
+        sourceHeight * scale,
       );
     } else {
       view.context.drawImage(
@@ -66,7 +64,7 @@ export class TileObjectRenderer {
         point.x,
         point.y,
         sourceWidth * scale,
-        sourceHeight * scale
+        sourceHeight * scale,
       );
     }
   }
diff --git a/src/app/scene/scene-object.ts b/src/app/scene/scene-object.ts
index b4f230a6..8cea8673 100644
--- a/src/app/scene/scene-object.ts
+++ b/src/app/scene/scene-object.ts
@@ -1,4 +1,3 @@
-
 import * as _ from 'underscore';
 import { SceneObjectBehavior } from '../behaviors/scene-object-behavior';
 import { BehaviorHost, IPoint, Point } from '../core';
@@ -37,7 +36,7 @@ export class SceneObject extends BehaviorHost implements ISceneObject {
     for (let i = 0; i < l; i++) {
       if (!values[i]) {
         throw new Error(
-          'Component deleted during tick, use _.defer to delay removal until the callstack unwinds'
+          'Component deleted during tick, use _.defer to delay removal until the callstack unwinds',
         );
       }
       if (values[i].tick) {
@@ -56,7 +55,7 @@ export class SceneObject extends BehaviorHost implements ISceneObject {
     for (let i = 0; i < l; i++) {
       if (!values[i]) {
         throw new Error(
-          'Component deleted during interpolateTick, delay removal until the callstack unwinds'
+          'Component deleted during interpolateTick, delay removal until the callstack unwinds',
         );
       }
       if (values[i].interpolateTick) {
@@ -94,7 +93,7 @@ export class SceneObject extends BehaviorHost implements ISceneObject {
     }
     if (failed) {
       console.log(
-        `Failed to add component set to host. Component ${failed.toString()} failed to connect to host.`
+        `Failed to add component set to host. Component ${failed.toString()} failed to connect to host.`,
       );
     } else {
       this.syncBehaviors();
@@ -118,7 +117,7 @@ export class SceneObject extends BehaviorHost implements ISceneObject {
           return false;
         }
         return true;
-      }
+      },
     );
     const change: boolean = this._connectedBehaviors.length === previousCount;
     if (change && silent !== true) {
diff --git a/src/app/scene/scene-view.ts b/src/app/scene/scene-view.ts
index f5f23d6b..587193fb 100644
--- a/src/app/scene/scene-view.ts
+++ b/src/app/scene/scene-view.ts
@@ -1,4 +1,3 @@
-
 import { CameraBehavior } from '../behaviors/camera-behavior';
 import { Point, Rect } from '../core';
 import { TileMapRenderer } from './render/tile-map-renderer';
@@ -60,7 +59,7 @@ export class SceneView extends SceneObject implements ISceneView {
   renderToCanvas(
     width: number,
     height: number,
-    renderFunction: (ctx: CanvasRenderingContext2D) => void
+    renderFunction: (ctx: CanvasRenderingContext2D) => void,
   ) {
     const buffer = document.createElement('canvas');
     buffer.width = width;
@@ -122,7 +121,7 @@ export class SceneView extends SceneObject implements ISceneView {
     let worldTilePos = this.worldToScreen(this.map.bounds.point).floor();
     this.context.translate(
       worldTilePos.x - worldCameraPos.x,
-      worldTilePos.y - worldCameraPos.y
+      worldTilePos.y - worldCameraPos.y,
     );
   }
 
@@ -157,7 +156,7 @@ export class SceneView extends SceneObject implements ISceneView {
         innerRadius,
         center.x,
         center.y,
-        outerRadius
+        outerRadius,
       );
       gradient.addColorStop(0, 'rgba(0,0,0,0)');
       gradient.addColorStop(1, 'rgba(0,0,0,1)');
@@ -226,7 +225,7 @@ export class SceneView extends SceneObject implements ISceneView {
       x,
       y,
       this.context.canvas.width,
-      this.context.canvas.height
+      this.context.canvas.height,
     );
   }
 
diff --git a/src/app/scene/scene.model.ts b/src/app/scene/scene.model.ts
index da255ad3..9b0715ae 100644
--- a/src/app/scene/scene.model.ts
+++ b/src/app/scene/scene.model.ts
@@ -1,5 +1,3 @@
-
-
 import {
   IBehavior,
   IBehaviorHost,
@@ -79,7 +77,7 @@ export interface ISceneView {
   renderToCanvas(
     width: number,
     height: number,
-    renderFunction: (ctx: CanvasRenderingContext2D) => void
+    renderFunction: (ctx: CanvasRenderingContext2D) => void,
   ): void;
 
   // Render a frame. Subclass this to do your specific rendering.
diff --git a/src/app/scene/scene.ts b/src/app/scene/scene.ts
index 523c5e87..f5a88afa 100644
--- a/src/app/scene/scene.ts
+++ b/src/app/scene/scene.ts
@@ -1,4 +1,3 @@
-
 import * as _ from 'underscore';
 import { IBehavior, IProcessObject, IWorld, IWorldObject } from '../core';
 import { GameWorld } from '../services/game-world';
diff --git a/src/app/scene/spatial-database.ts b/src/app/scene/spatial-database.ts
index d6e4b01c..2e9d0958 100644
--- a/src/app/scene/spatial-database.ts
+++ b/src/app/scene/spatial-database.ts
@@ -1,4 +1,3 @@
-
 import * as _ from 'underscore';
 import { Point, Rect } from '../core';
 import { ISceneObject } from './scene.model';
diff --git a/src/app/scene/tile-map.ts b/src/app/scene/tile-map.ts
index 68972d6c..7668d17d 100644
--- a/src/app/scene/tile-map.ts
+++ b/src/app/scene/tile-map.ts
@@ -1,4 +1,3 @@
-
 // TODO: TileMap isn't getting added to Spatial DB properly.  Can't query for it!
 // Scene assuming something about the spatial properties on objects?
 import { EventEmitter } from '@angular/core';
@@ -76,7 +75,7 @@ export class TileMap extends SceneObject {
       Object.values(this.map.tilesets),
       (o: TiledTSXResource) => {
         return o.firstgid;
-      }
+      },
     );
     this.tiles.length = 0;
     idSortedSets.forEach((tiles: TiledTSXResource) => {
diff --git a/src/app/scene/tile-object.ts b/src/app/scene/tile-object.ts
index c50741e8..72ef6736 100644
--- a/src/app/scene/tile-object.ts
+++ b/src/app/scene/tile-object.ts
@@ -1,4 +1,3 @@
-
 import { EventEmitter } from '@angular/core';
 import { MovableBehavior } from '../behaviors/movable-behavior';
 import { ImageResource, IPoint, Point } from '../core';
diff --git a/src/app/services/animate.ts b/src/app/services/animate.ts
index 6478a29b..860de759 100644
--- a/src/app/services/animate.ts
+++ b/src/app/services/animate.ts
@@ -1,4 +1,3 @@
-
 import { Injectable } from '@angular/core';
 /**
  * Provide an API for animating elements with CSS transitions
diff --git a/src/app/services/game-world.ts b/src/app/services/game-world.ts
index 685b8847..7bf50c45 100644
--- a/src/app/services/game-world.ts
+++ b/src/app/services/game-world.ts
@@ -27,7 +27,7 @@ export class GameWorld extends World {
       return spritesLoaded;
     }),
     filter((b) => b),
-    map(() => undefined)
+    map(() => undefined),
   );
 
   constructor(
@@ -35,7 +35,7 @@ export class GameWorld extends World {
     public store: Store<AppState>,
     public sprites: SpriteRender,
     public gameStateService: GameStateService,
-    public notify: NotificationService
+    public notify: NotificationService,
   ) {
     super();
     _sharedGameWorld = this;
diff --git a/src/app/services/index.ts b/src/app/services/index.ts
index 43a3f189..63b29b0c 100644
--- a/src/app/services/index.ts
+++ b/src/app/services/index.ts
@@ -1,4 +1,3 @@
-
 import { ModuleWithProviders, NgModule } from '@angular/core';
 import { EffectsModule } from '@ngrx/effects';
 import { StoreModule } from '@ngrx/store';
diff --git a/src/app/services/rpg-game.ts b/src/app/services/rpg-game.ts
index c89aa57e..92d0ba88 100644
--- a/src/app/services/rpg-game.ts
+++ b/src/app/services/rpg-game.ts
@@ -1,4 +1,3 @@
-
 import { Injectable } from '@angular/core';
 import { Store } from '@ngrx/store';
 import { getArmorById } from 'app/models/game-data/armors';
@@ -30,7 +29,10 @@ import { Item } from '../models/item';
 
 @Injectable()
 export class RPGGame {
-  constructor(public loader: ResourceManager, private store: Store<AppState>) {}
+  constructor(
+    public loader: ResourceManager,
+    private store: Store<AppState>,
+  ) {}
 
   public create(type: EntityType, name: string): IPartyMember {
     const HERO_DEFAULTS: Partial<IPartyMember> = {
@@ -96,7 +98,7 @@ export class RPGGame {
   giveItemToPlayer(
     player: IPartyMember,
     templateItem: ITemplateBaseItem | null,
-    equipSlot: keyof EntitySlots
+    equipSlot: keyof EntitySlots,
   ) {
     if (!templateItem) {
       return;
@@ -109,7 +111,7 @@ export class RPGGame {
         entityId: player.eid,
         slot: equipSlot,
         itemId: itemInstance.eid,
-      })
+      }),
     );
   }
 
@@ -118,7 +120,7 @@ export class RPGGame {
    * is new or was loaded from save data.  Resolves with true if the game is new.
    */
   initGame(
-    load: boolean = !!localStorage.getItem(GameStateService.STATE_KEY)
+    load: boolean = !!localStorage.getItem(GameStateService.STATE_KEY),
   ): Promise<boolean> {
     return new Promise<boolean>(async (resolve, reject) => {
       if (load) {
diff --git a/src/app/services/sprite-render.ts b/src/app/services/sprite-render.ts
index fc694c0b..dced4a63 100644
--- a/src/app/services/sprite-render.ts
+++ b/src/app/services/sprite-render.ts
@@ -1,4 +1,3 @@
-
 import { Injectable } from '@angular/core';
 import { Rect } from '../../app/core/rect';
 import { ResourceManager } from '../../app/core/resource-manager';
@@ -73,7 +72,7 @@ export class SpriteRender {
           0,
           // target width,height
           this.canvas.width,
-          this.canvas.height
+          this.canvas.height,
         );
 
         // Serialize the canvas and return as an HTMLImageElement
diff --git a/src/app/services/window.ts b/src/app/services/window.ts
index 3fc27490..a1b526e9 100644
--- a/src/app/services/window.ts
+++ b/src/app/services/window.ts
@@ -1,4 +1,3 @@
-
 import { Injectable } from '@angular/core';
 
 /**
diff --git a/src/app/style/mixins.scss b/src/app/style/mixins.scss
index 8ffc6d16..23352525 100644
--- a/src/app/style/mixins.scss
+++ b/src/app/style/mixins.scss
@@ -5,8 +5,11 @@
   $lightColor: rgba(255, 255, 255, 0.2),
   $shadowColor: rgba(0, 0, 0, 0.1)
 ) {
-  text-shadow: $width $width 0 $shadowColor, (-$width) (-$width) 0 $lightColor,
-    $width (-$width) 0 $shadowColor, (-$width) $width 0 $lightColor;
+  text-shadow:
+    $width $width 0 $shadowColor,
+    (-$width) (-$width) 0 $lightColor,
+    $width (-$width) 0 $shadowColor,
+    (-$width) $width 0 $lightColor;
 }
 
 @mixin inset-stroke-text(
@@ -14,8 +17,11 @@
   $lightColor: rgba(255, 255, 255, 0.2),
   $shadowColor: rgba(0, 0, 0, 0.1)
 ) {
-  text-shadow: (-$width) (-$width) 0 $lightColor, $width $width 0 $shadowColor,
-    (-$width) $width 0 $lightColor, $width (-$width) 0 $shadowColor;
+  text-shadow:
+    (-$width) (-$width) 0 $lightColor,
+    $width $width 0 $shadowColor,
+    (-$width) $width 0 $lightColor,
+    $width (-$width) 0 $shadowColor;
 }
 
 @mixin stroke-text($width: 2px, $color: rgba(255, 255, 255, 0.2)) {
diff --git a/src/app/style/theme.scss b/src/app/style/theme.scss
index a1d9f9ce..81e78d3a 100644
--- a/src/app/style/theme.scss
+++ b/src/app/style/theme.scss
@@ -90,4 +90,3 @@ $rpg-app-theme: mat.define-dark-theme($rpg-app-primary, $rpg-app-accent, $rpg-ap
 @include mat.slide-toggle-theme($rpg-app-theme);
 // @include mat.card-theme($rpg-app-theme);
 @include mat.progress-bar-theme($rpg-app-theme);
-
diff --git a/src/app/style/variables.scss b/src/app/style/variables.scss
index 8651e3fb..1dfa5855 100644
--- a/src/app/style/variables.scss
+++ b/src/app/style/variables.scss
@@ -72,23 +72,28 @@ $shadow-ambient-shadow-opacity: $shadow-multiplier * 0.12;
 
 // NOTE(shyndman): gulp-sass seems to be failing if I split the shadow defs across
 //    multiple lines. Ugly. Sorry.
-$whiteframe-shadow-z1: 0px 3px 1px -2px rgba(0, 0, 0, $shadow-key-umbra-opacity),
+$whiteframe-shadow-z1:
+  0px 3px 1px -2px rgba(0, 0, 0, $shadow-key-umbra-opacity),
   0px 2px 2px 0px rgba(0, 0, 0, $shadow-key-penumbra-opacity),
   0px 1px 5px 0px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
 $whiteframe-zindex-z1: 1 !default;
-$whiteframe-shadow-z2: 0 2px 4px -1px rgba(0, 0, 0, $shadow-key-umbra-opacity),
+$whiteframe-shadow-z2:
+  0 2px 4px -1px rgba(0, 0, 0, $shadow-key-umbra-opacity),
   0 4px 5px 0 rgba(0, 0, 0, $shadow-key-penumbra-opacity),
   0 1px 10px 0 rgba(0, 0, 0, $shadow-ambient-shadow-opacity);
 $whiteframe-zindex-z2: 2 !default;
-$whiteframe-shadow-z3: 0px 3px 5px -1px rgba(0, 0, 0, $shadow-key-umbra-opacity),
+$whiteframe-shadow-z3:
+  0px 3px 5px -1px rgba(0, 0, 0, $shadow-key-umbra-opacity),
   0px 6px 10px 0px rgba(0, 0, 0, $shadow-key-penumbra-opacity),
   0px 1px 18px 0px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
 $whiteframe-zindex-z3: 3 !default;
-$whiteframe-shadow-z4: 0px 5px 5px -3px rgba(0, 0, 0, $shadow-key-umbra-opacity),
+$whiteframe-shadow-z4:
+  0px 5px 5px -3px rgba(0, 0, 0, $shadow-key-umbra-opacity),
   0px 8px 10px 1px rgba(0, 0, 0, $shadow-key-penumbra-opacity),
   0px 3px 14px 2px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
 $whiteframe-zindex-z4: 4 !default;
-$whiteframe-shadow-z5: 0px 8px 10px -5px rgba(0, 0, 0, $shadow-key-umbra-opacity),
+$whiteframe-shadow-z5:
+  0px 8px 10px -5px rgba(0, 0, 0, $shadow-key-umbra-opacity),
   0px 16px 24px 2px rgba(0, 0, 0, $shadow-key-penumbra-opacity),
   0px 6px 30px 5px rgba(0, 0, 0, $shadow-ambient-shadow-opacity) !default;
 $whiteframe-zindex-z5: 5 !default;
diff --git a/src/assets/fonts/iconfont/material-icons.css b/src/assets/fonts/iconfont/material-icons.css
index a0d18e0a..8d308a13 100755
--- a/src/assets/fonts/iconfont/material-icons.css
+++ b/src/assets/fonts/iconfont/material-icons.css
@@ -3,7 +3,9 @@
   font-style: normal;
   font-weight: 400;
   src: url(MaterialIcons-Regular.eot); /* For IE6-8 */
-  src: local("Material Icons"), local("MaterialIcons-Regular"),
+  src:
+    local("Material Icons"),
+    local("MaterialIcons-Regular"),
     url(MaterialIcons-Regular.woff2) format("woff2"),
     url(MaterialIcons-Regular.woff) format("woff"),
     url(MaterialIcons-Regular.ttf) format("truetype");
diff --git a/src/assets/images/animation.json b/src/assets/images/animation.json
index 259febd6..9751f675 100644
--- a/src/assets/images/animation.json
+++ b/src/assets/images/animation.json
@@ -208,4 +208,4 @@
     "cellWidth": 16,
     "cellHeight": 16
   }
-}
\ No newline at end of file
+}
diff --git a/src/assets/images/characters.json b/src/assets/images/characters.json
index 0e56db40..21302ba3 100644
--- a/src/assets/images/characters.json
+++ b/src/assets/images/characters.json
@@ -12,31 +12,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          2
-        ]
+        "frames": [0, 2]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          3,
-          5
-        ]
+        "frames": [3, 5]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          6,
-          8
-        ]
+        "frames": [6, 8]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          9,
-          11
-        ]
+        "frames": [9, 11]
       }
     }
   },
@@ -53,31 +41,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          2
-        ]
+        "frames": [0, 2]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          3,
-          5
-        ]
+        "frames": [3, 5]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          6,
-          8
-        ]
+        "frames": [6, 8]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          9,
-          11
-        ]
+        "frames": [9, 11]
       }
     }
   },
@@ -94,31 +70,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          2
-        ]
+        "frames": [0, 2]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          3,
-          5
-        ]
+        "frames": [3, 5]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          6,
-          8
-        ]
+        "frames": [6, 8]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          9,
-          11
-        ]
+        "frames": [9, 11]
       }
     }
   },
@@ -135,31 +99,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          2
-        ]
+        "frames": [0, 2]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          3,
-          5
-        ]
+        "frames": [3, 5]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          6,
-          8
-        ]
+        "frames": [6, 8]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          9,
-          11
-        ]
+        "frames": [9, 11]
       }
     }
   },
@@ -176,31 +128,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          2
-        ]
+        "frames": [0, 2]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          3,
-          5
-        ]
+        "frames": [3, 5]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          6,
-          8
-        ]
+        "frames": [6, 8]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          9,
-          11
-        ]
+        "frames": [9, 11]
       }
     }
   },
@@ -217,31 +157,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          2
-        ]
+        "frames": [0, 2]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          3,
-          5
-        ]
+        "frames": [3, 5]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          6,
-          8
-        ]
+        "frames": [6, 8]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          9,
-          11
-        ]
+        "frames": [9, 11]
       }
     }
   },
@@ -258,31 +186,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          2
-        ]
+        "frames": [0, 2]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          3,
-          5
-        ]
+        "frames": [3, 5]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          6,
-          8
-        ]
+        "frames": [6, 8]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          9,
-          11
-        ]
+        "frames": [9, 11]
       }
     }
   },
@@ -299,31 +215,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          2
-        ]
+        "frames": [0, 2]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          3,
-          5
-        ]
+        "frames": [3, 5]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          6,
-          8
-        ]
+        "frames": [6, 8]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          9,
-          11
-        ]
+        "frames": [9, 11]
       }
     }
   },
@@ -340,31 +244,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          2
-        ]
+        "frames": [0, 2]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          3,
-          5
-        ]
+        "frames": [3, 5]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          6,
-          8
-        ]
+        "frames": [6, 8]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          9,
-          11
-        ]
+        "frames": [9, 11]
       }
     }
   },
@@ -381,31 +273,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          2
-        ]
+        "frames": [0, 2]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          3,
-          5
-        ]
+        "frames": [3, 5]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          6,
-          8
-        ]
+        "frames": [6, 8]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          9,
-          11
-        ]
+        "frames": [9, 11]
       }
     }
   },
@@ -422,31 +302,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          2
-        ]
+        "frames": [0, 2]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          3,
-          5
-        ]
+        "frames": [3, 5]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          6,
-          8
-        ]
+        "frames": [6, 8]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          9,
-          11
-        ]
+        "frames": [9, 11]
       }
     }
   },
@@ -463,32 +331,20 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          2
-        ]
+        "frames": [0, 2]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          3,
-          5
-        ]
+        "frames": [3, 5]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          6,
-          8
-        ]
+        "frames": [6, 8]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          9,
-          11
-        ]
+        "frames": [9, 11]
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/assets/images/creatures.json b/src/assets/images/creatures.json
index 54f790d9..f3295c46 100644
--- a/src/assets/images/creatures.json
+++ b/src/assets/images/creatures.json
@@ -764,4 +764,4 @@
     "x": 144,
     "y": 48
   }
-}
\ No newline at end of file
+}
diff --git a/src/assets/images/environment.json b/src/assets/images/environment.json
index e2ef0242..39929e7d 100644
--- a/src/assets/images/environment.json
+++ b/src/assets/images/environment.json
@@ -611,4 +611,4 @@
     "x": 128,
     "y": 48
   }
-}
\ No newline at end of file
+}
diff --git a/src/assets/images/equipment.json b/src/assets/images/equipment.json
index 7aa019d5..2442de0d 100644
--- a/src/assets/images/equipment.json
+++ b/src/assets/images/equipment.json
@@ -890,4 +890,4 @@
     "x": 128,
     "y": 144
   }
-}
\ No newline at end of file
+}
diff --git a/src/assets/images/index.json b/src/assets/images/index.json
index b2bf5931..c2b803f1 100644
--- a/src/assets/images/index.json
+++ b/src/assets/images/index.json
@@ -9,4 +9,4 @@
   "assets/images/animation",
   "assets/images/equipment",
   "assets/images/items"
-]
\ No newline at end of file
+]
diff --git a/src/assets/images/items.json b/src/assets/images/items.json
index 803f4f26..6732fca0 100644
--- a/src/assets/images/items.json
+++ b/src/assets/images/items.json
@@ -179,4 +179,4 @@
     "x": 64,
     "y": 48
   }
-}
\ No newline at end of file
+}
diff --git a/src/assets/images/magic.json b/src/assets/images/magic.json
index c005d10d..485ab56c 100644
--- a/src/assets/images/magic.json
+++ b/src/assets/images/magic.json
@@ -12,43 +12,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3,
-          4
-        ]
+        "frames": [0, 1, 2, 3, 4]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          5,
-          6,
-          7,
-          8,
-          9
-        ]
+        "frames": [5, 6, 7, 8, 9]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          10,
-          11,
-          12,
-          13,
-          14
-        ]
+        "frames": [10, 11, 12, 13, 14]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          15,
-          16,
-          17,
-          18,
-          19
-        ]
+        "frames": [15, 16, 17, 18, 19]
       }
     }
   },
@@ -65,43 +41,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3,
-          4
-        ]
+        "frames": [0, 1, 2, 3, 4]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          5,
-          6,
-          7,
-          8,
-          9
-        ]
+        "frames": [5, 6, 7, 8, 9]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          10,
-          11,
-          12,
-          13,
-          14
-        ]
+        "frames": [10, 11, 12, 13, 14]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          15,
-          16,
-          17,
-          18,
-          19
-        ]
+        "frames": [15, 16, 17, 18, 19]
       }
     }
   },
@@ -118,43 +70,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3,
-          4
-        ]
+        "frames": [0, 1, 2, 3, 4]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          5,
-          6,
-          7,
-          8,
-          9
-        ]
+        "frames": [5, 6, 7, 8, 9]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          10,
-          11,
-          12,
-          13,
-          14
-        ]
+        "frames": [10, 11, 12, 13, 14]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          15,
-          16,
-          17,
-          18,
-          19
-        ]
+        "frames": [15, 16, 17, 18, 19]
       }
     }
   },
@@ -171,43 +99,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3,
-          4
-        ]
+        "frames": [0, 1, 2, 3, 4]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          5,
-          6,
-          7,
-          8,
-          9
-        ]
+        "frames": [5, 6, 7, 8, 9]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          10,
-          11,
-          12,
-          13,
-          14
-        ]
+        "frames": [10, 11, 12, 13, 14]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          15,
-          16,
-          17,
-          18,
-          19
-        ]
+        "frames": [15, 16, 17, 18, 19]
       }
     }
   },
@@ -224,43 +128,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3,
-          4
-        ]
+        "frames": [0, 1, 2, 3, 4]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          5,
-          6,
-          7,
-          8,
-          9
-        ]
+        "frames": [5, 6, 7, 8, 9]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          10,
-          11,
-          12,
-          13,
-          14
-        ]
+        "frames": [10, 11, 12, 13, 14]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          15,
-          16,
-          17,
-          18,
-          19
-        ]
+        "frames": [15, 16, 17, 18, 19]
       }
     }
   },
@@ -277,43 +157,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3,
-          4
-        ]
+        "frames": [0, 1, 2, 3, 4]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          5,
-          6,
-          7,
-          8,
-          9
-        ]
+        "frames": [5, 6, 7, 8, 9]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          10,
-          11,
-          12,
-          13,
-          14
-        ]
+        "frames": [10, 11, 12, 13, 14]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          15,
-          16,
-          17,
-          18,
-          19
-        ]
+        "frames": [15, 16, 17, 18, 19]
       }
     }
   },
@@ -330,43 +186,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3,
-          4
-        ]
+        "frames": [0, 1, 2, 3, 4]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          5,
-          6,
-          7,
-          8,
-          9
-        ]
+        "frames": [5, 6, 7, 8, 9]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          10,
-          11,
-          12,
-          13,
-          14
-        ]
+        "frames": [10, 11, 12, 13, 14]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          15,
-          16,
-          17,
-          18,
-          19
-        ]
+        "frames": [15, 16, 17, 18, 19]
       }
     }
   },
@@ -383,43 +215,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3,
-          4
-        ]
+        "frames": [0, 1, 2, 3, 4]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          5,
-          6,
-          7,
-          8,
-          9
-        ]
+        "frames": [5, 6, 7, 8, 9]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          10,
-          11,
-          12,
-          13,
-          14
-        ]
+        "frames": [10, 11, 12, 13, 14]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          15,
-          16,
-          17,
-          18,
-          19
-        ]
+        "frames": [15, 16, 17, 18, 19]
       }
     }
   },
@@ -436,43 +244,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3,
-          4
-        ]
+        "frames": [0, 1, 2, 3, 4]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          5,
-          6,
-          7,
-          8,
-          9
-        ]
+        "frames": [5, 6, 7, 8, 9]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          10,
-          11,
-          12,
-          13,
-          14
-        ]
+        "frames": [10, 11, 12, 13, 14]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          15,
-          16,
-          17,
-          18,
-          19
-        ]
+        "frames": [15, 16, 17, 18, 19]
       }
     }
   },
@@ -489,43 +273,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3,
-          4
-        ]
+        "frames": [0, 1, 2, 3, 4]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          5,
-          6,
-          7,
-          8,
-          9
-        ]
+        "frames": [5, 6, 7, 8, 9]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          10,
-          11,
-          12,
-          13,
-          14
-        ]
+        "frames": [10, 11, 12, 13, 14]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          15,
-          16,
-          17,
-          18,
-          19
-        ]
+        "frames": [15, 16, 17, 18, 19]
       }
     }
   },
@@ -542,43 +302,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3,
-          4
-        ]
+        "frames": [0, 1, 2, 3, 4]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          5,
-          6,
-          7,
-          8,
-          9
-        ]
+        "frames": [5, 6, 7, 8, 9]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          10,
-          11,
-          12,
-          13,
-          14
-        ]
+        "frames": [10, 11, 12, 13, 14]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          15,
-          16,
-          17,
-          18,
-          19
-        ]
+        "frames": [15, 16, 17, 18, 19]
       }
     }
   },
@@ -595,44 +331,20 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3,
-          4
-        ]
+        "frames": [0, 1, 2, 3, 4]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          5,
-          6,
-          7,
-          8,
-          9
-        ]
+        "frames": [5, 6, 7, 8, 9]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          10,
-          11,
-          12,
-          13,
-          14
-        ]
+        "frames": [10, 11, 12, 13, 14]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          15,
-          16,
-          17,
-          18,
-          19
-        ]
+        "frames": [15, 16, 17, 18, 19]
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/assets/images/objects.json b/src/assets/images/objects.json
index c458964e..5c72ee77 100644
--- a/src/assets/images/objects.json
+++ b/src/assets/images/objects.json
@@ -206,4 +206,4 @@
     "x": 32,
     "y": 64
   }
-}
\ No newline at end of file
+}
diff --git a/src/assets/images/punch.json b/src/assets/images/punch.json
index d218ff91..2b8c6631 100644
--- a/src/assets/images/punch.json
+++ b/src/assets/images/punch.json
@@ -12,39 +12,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3
-        ]
+        "frames": [0, 1, 2, 3]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          4,
-          5,
-          6,
-          7
-        ]
+        "frames": [4, 5, 6, 7]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          8,
-          9,
-          10,
-          11
-        ]
+        "frames": [8, 9, 10, 11]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          12,
-          13,
-          14,
-          15
-        ]
+        "frames": [12, 13, 14, 15]
       }
     }
   },
@@ -61,39 +41,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3
-        ]
+        "frames": [0, 1, 2, 3]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          4,
-          5,
-          6,
-          7
-        ]
+        "frames": [4, 5, 6, 7]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          8,
-          9,
-          10,
-          11
-        ]
+        "frames": [8, 9, 10, 11]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          12,
-          13,
-          14,
-          15
-        ]
+        "frames": [12, 13, 14, 15]
       }
     }
   },
@@ -110,39 +70,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3
-        ]
+        "frames": [0, 1, 2, 3]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          4,
-          5,
-          6,
-          7
-        ]
+        "frames": [4, 5, 6, 7]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          8,
-          9,
-          10,
-          11
-        ]
+        "frames": [8, 9, 10, 11]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          12,
-          13,
-          14,
-          15
-        ]
+        "frames": [12, 13, 14, 15]
       }
     }
   },
@@ -159,39 +99,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3
-        ]
+        "frames": [0, 1, 2, 3]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          4,
-          5,
-          6,
-          7
-        ]
+        "frames": [4, 5, 6, 7]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          8,
-          9,
-          10,
-          11
-        ]
+        "frames": [8, 9, 10, 11]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          12,
-          13,
-          14,
-          15
-        ]
+        "frames": [12, 13, 14, 15]
       }
     }
   },
@@ -208,39 +128,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3
-        ]
+        "frames": [0, 1, 2, 3]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          4,
-          5,
-          6,
-          7
-        ]
+        "frames": [4, 5, 6, 7]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          8,
-          9,
-          10,
-          11
-        ]
+        "frames": [8, 9, 10, 11]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          12,
-          13,
-          14,
-          15
-        ]
+        "frames": [12, 13, 14, 15]
       }
     }
   },
@@ -257,39 +157,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3
-        ]
+        "frames": [0, 1, 2, 3]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          4,
-          5,
-          6,
-          7
-        ]
+        "frames": [4, 5, 6, 7]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          8,
-          9,
-          10,
-          11
-        ]
+        "frames": [8, 9, 10, 11]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          12,
-          13,
-          14,
-          15
-        ]
+        "frames": [12, 13, 14, 15]
       }
     }
   },
@@ -306,39 +186,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3
-        ]
+        "frames": [0, 1, 2, 3]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          4,
-          5,
-          6,
-          7
-        ]
+        "frames": [4, 5, 6, 7]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          8,
-          9,
-          10,
-          11
-        ]
+        "frames": [8, 9, 10, 11]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          12,
-          13,
-          14,
-          15
-        ]
+        "frames": [12, 13, 14, 15]
       }
     }
   },
@@ -355,39 +215,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3
-        ]
+        "frames": [0, 1, 2, 3]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          4,
-          5,
-          6,
-          7
-        ]
+        "frames": [4, 5, 6, 7]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          8,
-          9,
-          10,
-          11
-        ]
+        "frames": [8, 9, 10, 11]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          12,
-          13,
-          14,
-          15
-        ]
+        "frames": [12, 13, 14, 15]
       }
     }
   },
@@ -404,39 +244,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3
-        ]
+        "frames": [0, 1, 2, 3]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          4,
-          5,
-          6,
-          7
-        ]
+        "frames": [4, 5, 6, 7]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          8,
-          9,
-          10,
-          11
-        ]
+        "frames": [8, 9, 10, 11]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          12,
-          13,
-          14,
-          15
-        ]
+        "frames": [12, 13, 14, 15]
       }
     }
   },
@@ -453,39 +273,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3
-        ]
+        "frames": [0, 1, 2, 3]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          4,
-          5,
-          6,
-          7
-        ]
+        "frames": [4, 5, 6, 7]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          8,
-          9,
-          10,
-          11
-        ]
+        "frames": [8, 9, 10, 11]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          12,
-          13,
-          14,
-          15
-        ]
+        "frames": [12, 13, 14, 15]
       }
     }
   },
@@ -502,39 +302,19 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3
-        ]
+        "frames": [0, 1, 2, 3]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          4,
-          5,
-          6,
-          7
-        ]
+        "frames": [4, 5, 6, 7]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          8,
-          9,
-          10,
-          11
-        ]
+        "frames": [8, 9, 10, 11]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          12,
-          13,
-          14,
-          15
-        ]
+        "frames": [12, 13, 14, 15]
       }
     }
   },
@@ -551,40 +331,20 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          0,
-          1,
-          2,
-          3
-        ]
+        "frames": [0, 1, 2, 3]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          4,
-          5,
-          6,
-          7
-        ]
+        "frames": [4, 5, 6, 7]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          8,
-          9,
-          10,
-          11
-        ]
+        "frames": [8, 9, 10, 11]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          12,
-          13,
-          14,
-          15
-        ]
+        "frames": [12, 13, 14, 15]
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/assets/images/vehicles.json b/src/assets/images/vehicles.json
index 97b9fb6a..a270b842 100644
--- a/src/assets/images/vehicles.json
+++ b/src/assets/images/vehicles.json
@@ -12,32 +12,20 @@
     "animations": {
       "up": {
         "duration": 500,
-        "frames": [
-          3,
-          7
-        ]
+        "frames": [3, 7]
       },
       "right": {
         "duration": 500,
-        "frames": [
-          1,
-          5
-        ]
+        "frames": [1, 5]
       },
       "down": {
         "duration": 500,
-        "frames": [
-          2,
-          6
-        ]
+        "frames": [2, 6]
       },
       "left": {
         "duration": 500,
-        "frames": [
-          0,
-          4
-        ]
+        "frames": [0, 4]
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/src/assets/maps/tiles/creatures.tsx b/src/assets/maps/tiles/creatures.tsx
index 717be432..a8d38f2f 100644
--- a/src/assets/maps/tiles/creatures.tsx
+++ b/src/assets/maps/tiles/creatures.tsx
@@ -1,259 +1,448 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<tileset version="1.9" tiledversion="1.9.2" name="../../images/creatures.png" tilewidth="16" tileheight="16" tilecount="85" columns="0" objectalignment="topleft">
- <grid orientation="orthogonal" width="1" height="1"/>
- <tile id="0">
-  <image width="16" height="16" source="../../../art/sprites/creatures/bugbear.png"/>
- </tile>
- <tile id="1">
-  <image width="16" height="16" source="../../../art/sprites/creatures/bugbear2.png"/>
- </tile>
- <tile id="2">
-  <image width="16" height="16" source="../../../art/sprites/creatures/cavePeeper.png"/>
- </tile>
- <tile id="3">
-  <image width="16" height="16" source="../../../art/sprites/creatures/clayGolem.png"/>
- </tile>
- <tile id="4">
-  <image width="16" height="16" source="../../../art/sprites/creatures/crab.png"/>
- </tile>
- <tile id="5">
-  <image width="16" height="16" source="../../../art/sprites/creatures/crawFighter.png"/>
- </tile>
- <tile id="6">
-  <image width="16" height="16" source="../../../art/sprites/creatures/cyclops.png"/>
- </tile>
- <tile id="7">
-  <image width="16" height="16" source="../../../art/sprites/creatures/drowElf.png"/>
- </tile>
- <tile id="8">
-  <image width="16" height="16" source="../../../art/sprites/creatures/dude.png"/>
- </tile>
- <tile id="9">
-  <image width="16" height="16" source="../../../art/sprites/creatures/dwarf2.png"/>
- </tile>
- <tile id="10">
-  <image width="16" height="16" source="../../../art/sprites/creatures/dwarfGuard.png"/>
- </tile>
- <tile id="11">
-  <image width="16" height="16" source="../../../art/sprites/creatures/dwarfKing.png"/>
- </tile>
- <tile id="12">
-  <image width="16" height="16" source="../../../art/sprites/creatures/emperor.png"/>
- </tile>
- <tile id="13">
-  <image width="16" height="16" source="../../../art/sprites/creatures/ghoul.png"/>
- </tile>
- <tile id="14">
-  <image width="16" height="16" source="../../../art/sprites/creatures/gnome.png"/>
- </tile>
- <tile id="15">
-  <image width="16" height="16" source="../../../art/sprites/creatures/gnome2.png"/>
- </tile>
- <tile id="16">
-  <image width="16" height="16" source="../../../art/sprites/creatures/gnome3.png"/>
- </tile>
- <tile id="17">
-  <image width="16" height="16" source="../../../art/sprites/creatures/gnomeKing.png"/>
- </tile>
- <tile id="18">
-  <image width="16" height="16" source="../../../art/sprites/creatures/goblin.png"/>
- </tile>
- <tile id="19">
-  <image width="16" height="16" source="../../../art/sprites/creatures/goblin4.png"/>
- </tile>
- <tile id="20">
-  <image width="16" height="16" source="../../../art/sprites/creatures/goblin6.png"/>
- </tile>
- <tile id="21">
-  <image width="16" height="16" source="../../../art/sprites/creatures/goblin7.png"/>
- </tile>
- <tile id="22">
-  <image width="16" height="16" source="../../../art/sprites/creatures/goblinArcher.png"/>
- </tile>
- <tile id="23">
-  <image width="16" height="16" source="../../../art/sprites/creatures/goblinKing.png"/>
- </tile>
- <tile id="24">
-  <image width="16" height="16" source="../../../art/sprites/creatures/goblinScout.png"/>
- </tile>
- <tile id="25">
-  <image width="16" height="16" source="../../../art/sprites/creatures/goblinWizard.png"/>
- </tile>
- <tile id="26">
-  <image width="16" height="16" source="../../../art/sprites/creatures/greensnake.png"/>
- </tile>
- <tile id="27">
-  <image width="16" height="16" source="../../../art/sprites/creatures/greenSpider.png"/>
- </tile>
- <tile id="28">
-  <image width="16" height="16" source="../../../art/sprites/creatures/guard2.png"/>
- </tile>
- <tile id="29">
-  <image width="16" height="16" source="../../../art/sprites/creatures/hugeSpider.png"/>
- </tile>
- <tile id="30">
-  <image width="16" height="16" source="../../../art/sprites/creatures/iceGolem.png"/>
- </tile>
- <tile id="31">
-  <image width="16" height="16" source="../../../art/sprites/creatures/iceMage.png"/>
- </tile>
- <tile id="32">
-  <image width="16" height="16" source="../../../art/sprites/creatures/iceTroll.png"/>
- </tile>
- <tile id="33">
-  <image width="16" height="16" source="../../../art/sprites/creatures/imp.png"/>
- </tile>
- <tile id="34">
-  <image width="16" height="16" source="../../../art/sprites/creatures/jellyfish.png"/>
- </tile>
- <tile id="35">
-  <image width="16" height="16" source="../../../art/sprites/creatures/kobold.png"/>
- </tile>
- <tile id="36">
-  <image width="16" height="16" source="../../../art/sprites/creatures/koboldShaman.png"/>
- </tile>
- <tile id="37">
-  <image width="16" height="16" source="../../../art/sprites/creatures/koboldSwordsman.png"/>
- </tile>
- <tile id="38">
-  <image width="16" height="16" source="../../../art/sprites/creatures/man.png"/>
- </tile>
- <tile id="39">
-  <image width="16" height="16" source="../../../art/sprites/creatures/man3.png"/>
- </tile>
- <tile id="40">
-  <image width="16" height="16" source="../../../art/sprites/creatures/merman.png"/>
- </tile>
- <tile id="41">
-  <image width="16" height="16" source="../../../art/sprites/creatures/mermanFighter.png"/>
- </tile>
- <tile id="42">
-  <image width="16" height="16" source="../../../art/sprites/creatures/mermanWizard.png"/>
- </tile>
- <tile id="43">
-  <image width="16" height="16" source="../../../art/sprites/creatures/mindFlayer.png"/>
- </tile>
- <tile id="44">
-  <image width="16" height="16" source="../../../art/sprites/creatures/minotaur.png"/>
- </tile>
- <tile id="45">
-  <image width="16" height="16" source="../../../art/sprites/creatures/mummy.png"/>
- </tile>
- <tile id="46">
-  <image width="16" height="16" source="../../../art/sprites/creatures/ogre.png"/>
- </tile>
- <tile id="47">
-  <image width="16" height="16" source="../../../art/sprites/creatures/ogre2.png"/>
- </tile>
- <tile id="48">
-  <image width="16" height="16" source="../../../art/sprites/creatures/oldMan.png"/>
- </tile>
- <tile id="49">
-  <image width="16" height="16" source="../../../art/sprites/creatures/oldMan2.png"/>
- </tile>
- <tile id="50">
-  <image width="16" height="16" source="../../../art/sprites/creatures/oliphant.png"/>
- </tile>
- <tile id="51">
-  <image width="16" height="16" source="../../../art/sprites/creatures/oliphant2.png"/>
- </tile>
- <tile id="52">
-  <image width="16" height="16" source="../../../art/sprites/creatures/oliphant3.png"/>
- </tile>
- <tile id="53">
-  <image width="16" height="16" source="../../../art/sprites/creatures/oliphant4.png"/>
- </tile>
- <tile id="54">
-  <image width="16" height="16" source="../../../art/sprites/creatures/oolanMaster.png"/>
- </tile>
- <tile id="55">
-  <image width="16" height="16" source="../../../art/sprites/creatures/phantom2.png"/>
- </tile>
- <tile id="56">
-  <image width="16" height="16" source="../../../art/sprites/creatures/pirate.png"/>
- </tile>
- <tile id="57">
-  <image width="16" height="16" source="../../../art/sprites/creatures/pirate2.png"/>
- </tile>
- <tile id="58">
-  <image width="16" height="16" source="../../../art/sprites/creatures/redSnake.png"/>
- </tile>
- <tile id="59">
-  <image width="16" height="16" source="../../../art/sprites/creatures/redSpider.png"/>
- </tile>
- <tile id="60">
-  <image width="16" height="16" source="../../../art/sprites/creatures/rockGolem.png"/>
- </tile>
- <tile id="61">
-  <image width="16" height="16" source="../../../art/sprites/creatures/skeleton.png"/>
- </tile>
- <tile id="62">
-  <image width="16" height="16" source="../../../art/sprites/creatures/skeletonGuard.png"/>
- </tile>
- <tile id="63">
-  <image width="16" height="16" source="../../../art/sprites/creatures/skeletonWizard.png"/>
- </tile>
- <tile id="64">
-  <image width="16" height="16" source="../../../art/sprites/creatures/snake.png"/>
- </tile>
- <tile id="65">
-  <image width="16" height="16" source="../../../art/sprites/creatures/snowman.png"/>
- </tile>
- <tile id="66">
-  <image width="16" height="16" source="../../../art/sprites/creatures/soldier.png"/>
- </tile>
- <tile id="67">
-  <image width="16" height="16" source="../../../art/sprites/creatures/spectre.png"/>
- </tile>
- <tile id="68">
-  <image width="16" height="16" source="../../../art/sprites/creatures/swordFish.png"/>
- </tile>
- <tile id="69">
-  <image width="16" height="16" source="../../../art/sprites/creatures/tarrMan2.png"/>
- </tile>
- <tile id="70">
-  <image width="16" height="16" source="../../../art/sprites/creatures/tarrSoldier.png"/>
- </tile>
- <tile id="71">
-  <image width="16" height="16" source="../../../art/sprites/creatures/treant.png"/>
- </tile>
- <tile id="72">
-  <image width="16" height="16" source="../../../art/sprites/creatures/treantElder.png"/>
- </tile>
- <tile id="73">
-  <image width="16" height="16" source="../../../art/sprites/creatures/troll.png"/>
- </tile>
- <tile id="74">
-  <image width="16" height="16" source="../../../art/sprites/creatures/twoHeadedTroll.png"/>
- </tile>
- <tile id="75">
-  <image width="16" height="16" source="../../../art/sprites/creatures/vezu.png"/>
- </tile>
- <tile id="76">
-  <image width="16" height="16" source="../../../art/sprites/creatures/wererat.png"/>
- </tile>
- <tile id="77">
-  <image width="16" height="16" source="../../../art/sprites/creatures/whiteSnake.png"/>
- </tile>
- <tile id="78">
-  <image width="16" height="16" source="../../../art/sprites/creatures/wraith2.png"/>
- </tile>
- <tile id="79">
-  <image width="16" height="16" source="../../../art/sprites/creatures/zombie3.png"/>
- </tile>
- <tile id="80">
-  <image width="16" height="16" source="../../../art/sprites/creatures/alienstaff.png"/>
- </tile>
- <tile id="81">
-  <image width="16" height="16" source="../../../art/sprites/creatures/bear.png"/>
- </tile>
- <tile id="82">
-  <image width="16" height="16" source="../../../art/sprites/creatures/blackSpider.png"/>
- </tile>
- <tile id="83">
-  <image width="16" height="16" source="../../../art/sprites/creatures/blueGoblin.png"/>
- </tile>
- <tile id="84">
-  <image width="16" height="16" source="../../../art/sprites/creatures/blueSnake.png"/>
- </tile>
+<tileset
+  version="1.9"
+  tiledversion="1.9.2"
+  name="../../images/creatures.png"
+  tilewidth="16"
+  tileheight="16"
+  tilecount="85"
+  columns="0"
+  objectalignment="topleft"
+>
+  <grid orientation="orthogonal" width="1" height="1" />
+  <tile id="0">
+    <image width="16" height="16" source="../../../art/sprites/creatures/bugbear.png" />
+  </tile>
+  <tile id="1">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/bugbear2.png"
+    />
+  </tile>
+  <tile id="2">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/cavePeeper.png"
+    />
+  </tile>
+  <tile id="3">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/clayGolem.png"
+    />
+  </tile>
+  <tile id="4">
+    <image width="16" height="16" source="../../../art/sprites/creatures/crab.png" />
+  </tile>
+  <tile id="5">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/crawFighter.png"
+    />
+  </tile>
+  <tile id="6">
+    <image width="16" height="16" source="../../../art/sprites/creatures/cyclops.png" />
+  </tile>
+  <tile id="7">
+    <image width="16" height="16" source="../../../art/sprites/creatures/drowElf.png" />
+  </tile>
+  <tile id="8">
+    <image width="16" height="16" source="../../../art/sprites/creatures/dude.png" />
+  </tile>
+  <tile id="9">
+    <image width="16" height="16" source="../../../art/sprites/creatures/dwarf2.png" />
+  </tile>
+  <tile id="10">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/dwarfGuard.png"
+    />
+  </tile>
+  <tile id="11">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/dwarfKing.png"
+    />
+  </tile>
+  <tile id="12">
+    <image width="16" height="16" source="../../../art/sprites/creatures/emperor.png" />
+  </tile>
+  <tile id="13">
+    <image width="16" height="16" source="../../../art/sprites/creatures/ghoul.png" />
+  </tile>
+  <tile id="14">
+    <image width="16" height="16" source="../../../art/sprites/creatures/gnome.png" />
+  </tile>
+  <tile id="15">
+    <image width="16" height="16" source="../../../art/sprites/creatures/gnome2.png" />
+  </tile>
+  <tile id="16">
+    <image width="16" height="16" source="../../../art/sprites/creatures/gnome3.png" />
+  </tile>
+  <tile id="17">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/gnomeKing.png"
+    />
+  </tile>
+  <tile id="18">
+    <image width="16" height="16" source="../../../art/sprites/creatures/goblin.png" />
+  </tile>
+  <tile id="19">
+    <image width="16" height="16" source="../../../art/sprites/creatures/goblin4.png" />
+  </tile>
+  <tile id="20">
+    <image width="16" height="16" source="../../../art/sprites/creatures/goblin6.png" />
+  </tile>
+  <tile id="21">
+    <image width="16" height="16" source="../../../art/sprites/creatures/goblin7.png" />
+  </tile>
+  <tile id="22">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/goblinArcher.png"
+    />
+  </tile>
+  <tile id="23">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/goblinKing.png"
+    />
+  </tile>
+  <tile id="24">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/goblinScout.png"
+    />
+  </tile>
+  <tile id="25">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/goblinWizard.png"
+    />
+  </tile>
+  <tile id="26">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/greensnake.png"
+    />
+  </tile>
+  <tile id="27">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/greenSpider.png"
+    />
+  </tile>
+  <tile id="28">
+    <image width="16" height="16" source="../../../art/sprites/creatures/guard2.png" />
+  </tile>
+  <tile id="29">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/hugeSpider.png"
+    />
+  </tile>
+  <tile id="30">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/iceGolem.png"
+    />
+  </tile>
+  <tile id="31">
+    <image width="16" height="16" source="../../../art/sprites/creatures/iceMage.png" />
+  </tile>
+  <tile id="32">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/iceTroll.png"
+    />
+  </tile>
+  <tile id="33">
+    <image width="16" height="16" source="../../../art/sprites/creatures/imp.png" />
+  </tile>
+  <tile id="34">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/jellyfish.png"
+    />
+  </tile>
+  <tile id="35">
+    <image width="16" height="16" source="../../../art/sprites/creatures/kobold.png" />
+  </tile>
+  <tile id="36">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/koboldShaman.png"
+    />
+  </tile>
+  <tile id="37">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/koboldSwordsman.png"
+    />
+  </tile>
+  <tile id="38">
+    <image width="16" height="16" source="../../../art/sprites/creatures/man.png" />
+  </tile>
+  <tile id="39">
+    <image width="16" height="16" source="../../../art/sprites/creatures/man3.png" />
+  </tile>
+  <tile id="40">
+    <image width="16" height="16" source="../../../art/sprites/creatures/merman.png" />
+  </tile>
+  <tile id="41">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/mermanFighter.png"
+    />
+  </tile>
+  <tile id="42">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/mermanWizard.png"
+    />
+  </tile>
+  <tile id="43">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/mindFlayer.png"
+    />
+  </tile>
+  <tile id="44">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/minotaur.png"
+    />
+  </tile>
+  <tile id="45">
+    <image width="16" height="16" source="../../../art/sprites/creatures/mummy.png" />
+  </tile>
+  <tile id="46">
+    <image width="16" height="16" source="../../../art/sprites/creatures/ogre.png" />
+  </tile>
+  <tile id="47">
+    <image width="16" height="16" source="../../../art/sprites/creatures/ogre2.png" />
+  </tile>
+  <tile id="48">
+    <image width="16" height="16" source="../../../art/sprites/creatures/oldMan.png" />
+  </tile>
+  <tile id="49">
+    <image width="16" height="16" source="../../../art/sprites/creatures/oldMan2.png" />
+  </tile>
+  <tile id="50">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/oliphant.png"
+    />
+  </tile>
+  <tile id="51">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/oliphant2.png"
+    />
+  </tile>
+  <tile id="52">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/oliphant3.png"
+    />
+  </tile>
+  <tile id="53">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/oliphant4.png"
+    />
+  </tile>
+  <tile id="54">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/oolanMaster.png"
+    />
+  </tile>
+  <tile id="55">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/phantom2.png"
+    />
+  </tile>
+  <tile id="56">
+    <image width="16" height="16" source="../../../art/sprites/creatures/pirate.png" />
+  </tile>
+  <tile id="57">
+    <image width="16" height="16" source="../../../art/sprites/creatures/pirate2.png" />
+  </tile>
+  <tile id="58">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/redSnake.png"
+    />
+  </tile>
+  <tile id="59">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/redSpider.png"
+    />
+  </tile>
+  <tile id="60">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/rockGolem.png"
+    />
+  </tile>
+  <tile id="61">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/skeleton.png"
+    />
+  </tile>
+  <tile id="62">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/skeletonGuard.png"
+    />
+  </tile>
+  <tile id="63">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/skeletonWizard.png"
+    />
+  </tile>
+  <tile id="64">
+    <image width="16" height="16" source="../../../art/sprites/creatures/snake.png" />
+  </tile>
+  <tile id="65">
+    <image width="16" height="16" source="../../../art/sprites/creatures/snowman.png" />
+  </tile>
+  <tile id="66">
+    <image width="16" height="16" source="../../../art/sprites/creatures/soldier.png" />
+  </tile>
+  <tile id="67">
+    <image width="16" height="16" source="../../../art/sprites/creatures/spectre.png" />
+  </tile>
+  <tile id="68">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/swordFish.png"
+    />
+  </tile>
+  <tile id="69">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/tarrMan2.png"
+    />
+  </tile>
+  <tile id="70">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/tarrSoldier.png"
+    />
+  </tile>
+  <tile id="71">
+    <image width="16" height="16" source="../../../art/sprites/creatures/treant.png" />
+  </tile>
+  <tile id="72">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/treantElder.png"
+    />
+  </tile>
+  <tile id="73">
+    <image width="16" height="16" source="../../../art/sprites/creatures/troll.png" />
+  </tile>
+  <tile id="74">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/twoHeadedTroll.png"
+    />
+  </tile>
+  <tile id="75">
+    <image width="16" height="16" source="../../../art/sprites/creatures/vezu.png" />
+  </tile>
+  <tile id="76">
+    <image width="16" height="16" source="../../../art/sprites/creatures/wererat.png" />
+  </tile>
+  <tile id="77">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/whiteSnake.png"
+    />
+  </tile>
+  <tile id="78">
+    <image width="16" height="16" source="../../../art/sprites/creatures/wraith2.png" />
+  </tile>
+  <tile id="79">
+    <image width="16" height="16" source="../../../art/sprites/creatures/zombie3.png" />
+  </tile>
+  <tile id="80">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/alienstaff.png"
+    />
+  </tile>
+  <tile id="81">
+    <image width="16" height="16" source="../../../art/sprites/creatures/bear.png" />
+  </tile>
+  <tile id="82">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/blackSpider.png"
+    />
+  </tile>
+  <tile id="83">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/blueGoblin.png"
+    />
+  </tile>
+  <tile id="84">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/creatures/blueSnake.png"
+    />
+  </tile>
 </tileset>
diff --git a/src/assets/maps/tiles/environment.tsx b/src/assets/maps/tiles/environment.tsx
index 1c9f7789..12946cd7 100644
--- a/src/assets/maps/tiles/environment.tsx
+++ b/src/assets/maps/tiles/environment.tsx
@@ -1,457 +1,610 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<tileset version="1.9" tiledversion="1.9.2" name="../../images/environment.png" tilewidth="16" tileheight="16" tilecount="51" columns="0" objectalignment="topleft">
- <tile id="2">
-  <properties>
-   <property name="color" value="#63390e"/>
-   <property name="icon" value="bridgeHorizontal.png"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/bridgeHorizontal.png"/>
- </tile>
- <tile id="3">
-  <properties>
-   <property name="color" value="#925e1a"/>
-   <property name="icon" value="caveFloor.png"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/caveFloor.png"/>
- </tile>
- <tile id="4">
-  <properties>
-   <property name="color" value="#8e6464"/>
-   <property name="icon" value="darkBridgeVertical.png"/>
-   <property name="isPath" value="true"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/darkBridgeVertical.png"/>
- </tile>
- <tile id="6">
-  <properties>
-   <property name="icon" value="iceGateCenter.png"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/iceGateCenter.png"/>
- </tile>
- <tile id="7">
-  <properties>
-   <property name="icon" value="plaque.png"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/plaque.png"/>
- </tile>
- <tile id="8">
-  <properties>
-   <property name="color" value="#585858"/>
-   <property name="icon" value="wall.png"/>
-   <property name="opaque" value="true"/>
-   <property name="passable" value="false"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/wall.png"/>
- </tile>
- <tile id="10">
-  <properties>
-   <property name="icon" value="blueBannerDoor.png"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/blueBannerDoor.png"/>
- </tile>
- <tile id="11">
-  <properties>
-   <property name="color" value="#63390e"/>
-   <property name="icon" value="bridgeVertical.png"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/bridgeVertical.png"/>
- </tile>
- <tile id="12">
-  <properties>
-   <property name="color" value="#5c3708"/>
-   <property name="icon" value="caveWall.png"/>
-   <property name="opaque" value="true"/>
-   <property name="passable" value="false"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/caveWall.png"/>
- </tile>
- <tile id="15">
-  <properties>
-   <property name="icon" value="iceGateLeft.png"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/iceGateLeft.png"/>
- </tile>
- <tile id="16">
-  <properties>
-   <property name="color" value="#0808D0"/>
-   <property name="icon" value="pool.png"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="false"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/pool.png"/>
- </tile>
- <tile id="17">
-  <properties>
-   <property name="color" value="#2828f0"/>
-   <property name="icon" value="water2.png"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="false"/>
-   <property name="shipPassable" value="true"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/water2.png"/>
- </tile>
- <tile id="18">
-  <properties>
-   <property name="icon" value="carpetN.png"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/carpetN.png"/>
- </tile>
- <tile id="19">
-  <properties>
-   <property name="icon" value="carpetNS.png"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/carpetNS.png"/>
- </tile>
- <tile id="20">
-  <properties>
-   <property name="icon" value="carpetS.png"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/carpetS.png"/>
- </tile>
- <tile id="22">
-  <properties>
-   <property name="color" value="#8e8e8e"/>
-   <property name="icon" value="darkFloor.png"/>
-   <property name="isPath" value="true"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/darkFloor.png"/>
- </tile>
- <tile id="24">
-  <properties>
-   <property name="color" value="#909090"/>
-   <property name="icon" value="iceMountain.png"/>
-   <property name="opaque" value="true"/>
-   <property name="passable" value="false"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/iceMountain.png"/>
- </tile>
- <tile id="25">
-  <properties>
-   <property name="icon" value="prism.png"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/prism.png"/>
- </tile>
- <tile id="26">
-  <properties>
-   <property name="color" value="#a01414"/>
-   <property name="icon" value="waterMountain.png"/>
-   <property name="opaque" value="true"/>
-   <property name="passable" value="false"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/waterMountain.png"/>
- </tile>
- <tile id="28">
-  <properties>
-   <property name="icon" value="column.png"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/column.png"/>
- </tile>
- <tile id="29">
-  <properties>
-   <property name="color" value="#222222"/>
-   <property name="icon" value="columnTile.png"/>
-   <property name="opaque" value="true"/>
-   <property name="passable" value="false"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/columnTile.png"/>
- </tile>
- <tile id="30">
-  <properties>
-   <property name="color" value="#8e6464"/>
-   <property name="icon" value="darkBridgeHorizontal.png"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/darkBridgeHorizontal.png"/>
- </tile>
- <tile id="31">
-  <properties>
-   <property name="color" value="#585858"/>
-   <property name="icon" value="darkWall.png"/>
-   <property name="opaque" value="true"/>
-   <property name="passable" value="false"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/darkWall.png"/>
- </tile>
- <tile id="32">
-  <properties>
-   <property name="color" value="#8e8e8e"/>
-   <property name="icon" value="floor.png"/>
-   <property name="isPath" value="true"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/floor.png"/>
- </tile>
- <tile id="33">
-  <properties>
-   <property name="color" value="#5b7497"/>
-   <property name="icon" value="iceWall.png"/>
-   <property name="opaque" value="true"/>
-   <property name="passable" value="false"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/iceWall.png"/>
- </tile>
- <tile id="34">
-  <properties>
-   <property name="color" value="#06796d"/>
-   <property name="icon" value="river.png"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="false"/>
-   <property name="shipPassable" value="true"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/river.png"/>
- </tile>
- <tile id="35">
-  <properties>
-   <property name="icon" value="well.png"/>
-   <property name="passable" type="bool" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/well.png"/>
- </tile>
- <tile id="36">
-  <properties>
-   <property name="color" value="#544d19"/>
-   <property name="icon" value="deadTree.png"/>
-   <property name="opaque" value="true"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/deadTree.png"/>
- </tile>
- <tile id="37">
-  <properties>
-   <property name="color" value="#925e1a"/>
-   <property name="icon" value="deck.png"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/deck.png"/>
- </tile>
- <tile id="38">
-  <properties>
-   <property name="color" value="#cd964e"/>
-   <property name="icon" value="desert.png"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/desert.png"/>
- </tile>
- <tile id="39">
-  <properties>
-   <property name="color" value="#a01414"/>
-   <property name="icon" value="desertMountain.png"/>
-   <property name="opaque" value="true"/>
-   <property name="passable" value="false"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/desertMountain.png"/>
- </tile>
- <tile id="40">
-  <properties>
-   <property name="icon" value="dome.png"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/dome.png"/>
- </tile>
- <tile id="42">
-  <properties>
-   <property name="color" value="#9eb8be"/>
-   <property name="icon" value="iceberg.png"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/iceberg.png"/>
- </tile>
- <tile id="43">
-  <properties>
-   <property name="color" value="#282828"/>
-   <property name="icon" value="rubble.png"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/rubble.png"/>
- </tile>
- <tile id="45">
-  <properties>
-   <property name="color" value="#28f028"/>
-   <property name="icon" value="grass.png"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/grass.png"/>
- </tile>
- <tile id="46">
-  <properties>
-   <property name="color" value="#5c3708"/>
-   <property name="icon" value="gunnelLeft.png"/>
-   <property name="opaque" value="true"/>
-   <property name="passable" value="false"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/gunnelLeft.png"/>
- </tile>
- <tile id="47">
-  <properties>
-   <property name="color" value="#5c3708"/>
-   <property name="icon" value="gunnelRight.png"/>
-   <property name="opaque" value="true"/>
-   <property name="passable" value="false"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/gunnelRight.png"/>
- </tile>
- <tile id="48">
-  <properties>
-   <property name="color" value="#ffffff"/>
-   <property name="icon" value="ice.png"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/ice.png"/>
- </tile>
- <tile id="49">
-  <properties>
-   <property name="color" value="#a8c4dd"/>
-   <property name="icon" value="iceFloor.png"/>
-   <property name="isPath" value="true"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/iceFloor.png"/>
- </tile>
- <tile id="54">
-  <properties>
-   <property name="color" value="#e13e29"/>
-   <property name="icon" value="lava.png"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="false"/>
-   <property name="shipPassable" value="true"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/lava.png"/>
- </tile>
- <tile id="50">
-  <properties>
-   <property name="icon" value="iceFloor.png"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/iceFloor.png"/>
- </tile>
- <tile id="56">
-  <properties>
-   <property name="color" value="#a01414"/>
-   <property name="icon" value="mountain.png"/>
-   <property name="opaque" value="true"/>
-   <property name="passable" value="false"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/mountain.png"/>
- </tile>
- <tile id="60">
-  <properties>
-   <property name="color" value="#a0ab40"/>
-   <property name="icon" value="palmTree.png"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/palmTree.png"/>
- </tile>
- <tile id="65">
-  <properties>
-   <property name="color" value="#544d19"/>
-   <property name="icon" value="stump.png"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/stump.png"/>
- </tile>
- <tile id="63">
-  <properties>
-   <property name="icon" value="sigil.png"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/sigil.png"/>
- </tile>
- <tile id="64">
-  <properties>
-   <property name="icon" value="skull.png"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/skull.png"/>
- </tile>
- <tile id="68">
-  <properties>
-   <property name="color" value="#008c00"/>
-   <property name="icon" value="treeAlt.png"/>
-   <property name="isDangerous" value="true"/>
-   <property name="opaque" value="true"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/treeAlt.png"/>
- </tile>
- <tile id="67">
-  <properties>
-   <property name="icon" value="tower.png"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/tower.png"/>
- </tile>
- <tile id="69">
-  <properties>
-   <property name="color" value="#525f47"/>
-   <property name="icon" value="tundra.png"/>
-   <property name="opaque" value="false"/>
-   <property name="passable" value="true"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/tundra.png"/>
- </tile>
- <tile id="70">
-  <properties>
-   <property name="color" value="#500000"/>
-   <property name="icon" value="volcano.png"/>
-   <property name="opaque" value="true"/>
-   <property name="passable" value="false"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/volcano.png"/>
- </tile>
- <tile id="44">
-  <properties>
-   <property name="icon" value="zTransparentMountain.png"/>
-   <property name="passable" value="false"/>
-   <property name="shipPassable" value="false"/>
-  </properties>
-  <image width="16" height="16" source="../../../art/sprites/environment/zTransparentMountain.png"/>
- </tile>
+<tileset
+  version="1.9"
+  tiledversion="1.9.2"
+  name="../../images/environment.png"
+  tilewidth="16"
+  tileheight="16"
+  tilecount="51"
+  columns="0"
+  objectalignment="topleft"
+>
+  <tile id="2">
+    <properties>
+      <property name="color" value="#63390e" />
+      <property name="icon" value="bridgeHorizontal.png" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/bridgeHorizontal.png"
+    />
+  </tile>
+  <tile id="3">
+    <properties>
+      <property name="color" value="#925e1a" />
+      <property name="icon" value="caveFloor.png" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/caveFloor.png"
+    />
+  </tile>
+  <tile id="4">
+    <properties>
+      <property name="color" value="#8e6464" />
+      <property name="icon" value="darkBridgeVertical.png" />
+      <property name="isPath" value="true" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/darkBridgeVertical.png"
+    />
+  </tile>
+  <tile id="6">
+    <properties>
+      <property name="icon" value="iceGateCenter.png" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/iceGateCenter.png"
+    />
+  </tile>
+  <tile id="7">
+    <properties>
+      <property name="icon" value="plaque.png" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/plaque.png"
+    />
+  </tile>
+  <tile id="8">
+    <properties>
+      <property name="color" value="#585858" />
+      <property name="icon" value="wall.png" />
+      <property name="opaque" value="true" />
+      <property name="passable" value="false" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image width="16" height="16" source="../../../art/sprites/environment/wall.png" />
+  </tile>
+  <tile id="10">
+    <properties>
+      <property name="icon" value="blueBannerDoor.png" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/blueBannerDoor.png"
+    />
+  </tile>
+  <tile id="11">
+    <properties>
+      <property name="color" value="#63390e" />
+      <property name="icon" value="bridgeVertical.png" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/bridgeVertical.png"
+    />
+  </tile>
+  <tile id="12">
+    <properties>
+      <property name="color" value="#5c3708" />
+      <property name="icon" value="caveWall.png" />
+      <property name="opaque" value="true" />
+      <property name="passable" value="false" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/caveWall.png"
+    />
+  </tile>
+  <tile id="15">
+    <properties>
+      <property name="icon" value="iceGateLeft.png" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/iceGateLeft.png"
+    />
+  </tile>
+  <tile id="16">
+    <properties>
+      <property name="color" value="#0808D0" />
+      <property name="icon" value="pool.png" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="false" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image width="16" height="16" source="../../../art/sprites/environment/pool.png" />
+  </tile>
+  <tile id="17">
+    <properties>
+      <property name="color" value="#2828f0" />
+      <property name="icon" value="water2.png" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="false" />
+      <property name="shipPassable" value="true" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/water2.png"
+    />
+  </tile>
+  <tile id="18">
+    <properties>
+      <property name="icon" value="carpetN.png" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/carpetN.png"
+    />
+  </tile>
+  <tile id="19">
+    <properties>
+      <property name="icon" value="carpetNS.png" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/carpetNS.png"
+    />
+  </tile>
+  <tile id="20">
+    <properties>
+      <property name="icon" value="carpetS.png" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/carpetS.png"
+    />
+  </tile>
+  <tile id="22">
+    <properties>
+      <property name="color" value="#8e8e8e" />
+      <property name="icon" value="darkFloor.png" />
+      <property name="isPath" value="true" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/darkFloor.png"
+    />
+  </tile>
+  <tile id="24">
+    <properties>
+      <property name="color" value="#909090" />
+      <property name="icon" value="iceMountain.png" />
+      <property name="opaque" value="true" />
+      <property name="passable" value="false" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/iceMountain.png"
+    />
+  </tile>
+  <tile id="25">
+    <properties>
+      <property name="icon" value="prism.png" />
+    </properties>
+    <image width="16" height="16" source="../../../art/sprites/environment/prism.png" />
+  </tile>
+  <tile id="26">
+    <properties>
+      <property name="color" value="#a01414" />
+      <property name="icon" value="waterMountain.png" />
+      <property name="opaque" value="true" />
+      <property name="passable" value="false" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/waterMountain.png"
+    />
+  </tile>
+  <tile id="28">
+    <properties>
+      <property name="icon" value="column.png" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/column.png"
+    />
+  </tile>
+  <tile id="29">
+    <properties>
+      <property name="color" value="#222222" />
+      <property name="icon" value="columnTile.png" />
+      <property name="opaque" value="true" />
+      <property name="passable" value="false" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/columnTile.png"
+    />
+  </tile>
+  <tile id="30">
+    <properties>
+      <property name="color" value="#8e6464" />
+      <property name="icon" value="darkBridgeHorizontal.png" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/darkBridgeHorizontal.png"
+    />
+  </tile>
+  <tile id="31">
+    <properties>
+      <property name="color" value="#585858" />
+      <property name="icon" value="darkWall.png" />
+      <property name="opaque" value="true" />
+      <property name="passable" value="false" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/darkWall.png"
+    />
+  </tile>
+  <tile id="32">
+    <properties>
+      <property name="color" value="#8e8e8e" />
+      <property name="icon" value="floor.png" />
+      <property name="isPath" value="true" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image width="16" height="16" source="../../../art/sprites/environment/floor.png" />
+  </tile>
+  <tile id="33">
+    <properties>
+      <property name="color" value="#5b7497" />
+      <property name="icon" value="iceWall.png" />
+      <property name="opaque" value="true" />
+      <property name="passable" value="false" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/iceWall.png"
+    />
+  </tile>
+  <tile id="34">
+    <properties>
+      <property name="color" value="#06796d" />
+      <property name="icon" value="river.png" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="false" />
+      <property name="shipPassable" value="true" />
+    </properties>
+    <image width="16" height="16" source="../../../art/sprites/environment/river.png" />
+  </tile>
+  <tile id="35">
+    <properties>
+      <property name="icon" value="well.png" />
+      <property name="passable" type="bool" value="false" />
+    </properties>
+    <image width="16" height="16" source="../../../art/sprites/environment/well.png" />
+  </tile>
+  <tile id="36">
+    <properties>
+      <property name="color" value="#544d19" />
+      <property name="icon" value="deadTree.png" />
+      <property name="opaque" value="true" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/deadTree.png"
+    />
+  </tile>
+  <tile id="37">
+    <properties>
+      <property name="color" value="#925e1a" />
+      <property name="icon" value="deck.png" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image width="16" height="16" source="../../../art/sprites/environment/deck.png" />
+  </tile>
+  <tile id="38">
+    <properties>
+      <property name="color" value="#cd964e" />
+      <property name="icon" value="desert.png" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/desert.png"
+    />
+  </tile>
+  <tile id="39">
+    <properties>
+      <property name="color" value="#a01414" />
+      <property name="icon" value="desertMountain.png" />
+      <property name="opaque" value="true" />
+      <property name="passable" value="false" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/desertMountain.png"
+    />
+  </tile>
+  <tile id="40">
+    <properties>
+      <property name="icon" value="dome.png" />
+    </properties>
+    <image width="16" height="16" source="../../../art/sprites/environment/dome.png" />
+  </tile>
+  <tile id="42">
+    <properties>
+      <property name="color" value="#9eb8be" />
+      <property name="icon" value="iceberg.png" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/iceberg.png"
+    />
+  </tile>
+  <tile id="43">
+    <properties>
+      <property name="color" value="#282828" />
+      <property name="icon" value="rubble.png" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/rubble.png"
+    />
+  </tile>
+  <tile id="45">
+    <properties>
+      <property name="color" value="#28f028" />
+      <property name="icon" value="grass.png" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image width="16" height="16" source="../../../art/sprites/environment/grass.png" />
+  </tile>
+  <tile id="46">
+    <properties>
+      <property name="color" value="#5c3708" />
+      <property name="icon" value="gunnelLeft.png" />
+      <property name="opaque" value="true" />
+      <property name="passable" value="false" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/gunnelLeft.png"
+    />
+  </tile>
+  <tile id="47">
+    <properties>
+      <property name="color" value="#5c3708" />
+      <property name="icon" value="gunnelRight.png" />
+      <property name="opaque" value="true" />
+      <property name="passable" value="false" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/gunnelRight.png"
+    />
+  </tile>
+  <tile id="48">
+    <properties>
+      <property name="color" value="#ffffff" />
+      <property name="icon" value="ice.png" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image width="16" height="16" source="../../../art/sprites/environment/ice.png" />
+  </tile>
+  <tile id="49">
+    <properties>
+      <property name="color" value="#a8c4dd" />
+      <property name="icon" value="iceFloor.png" />
+      <property name="isPath" value="true" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/iceFloor.png"
+    />
+  </tile>
+  <tile id="54">
+    <properties>
+      <property name="color" value="#e13e29" />
+      <property name="icon" value="lava.png" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="false" />
+      <property name="shipPassable" value="true" />
+    </properties>
+    <image width="16" height="16" source="../../../art/sprites/environment/lava.png" />
+  </tile>
+  <tile id="50">
+    <properties>
+      <property name="icon" value="iceFloor.png" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/iceFloor.png"
+    />
+  </tile>
+  <tile id="56">
+    <properties>
+      <property name="color" value="#a01414" />
+      <property name="icon" value="mountain.png" />
+      <property name="opaque" value="true" />
+      <property name="passable" value="false" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/mountain.png"
+    />
+  </tile>
+  <tile id="60">
+    <properties>
+      <property name="color" value="#a0ab40" />
+      <property name="icon" value="palmTree.png" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/palmTree.png"
+    />
+  </tile>
+  <tile id="65">
+    <properties>
+      <property name="color" value="#544d19" />
+      <property name="icon" value="stump.png" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image width="16" height="16" source="../../../art/sprites/environment/stump.png" />
+  </tile>
+  <tile id="63">
+    <properties>
+      <property name="icon" value="sigil.png" />
+    </properties>
+    <image width="16" height="16" source="../../../art/sprites/environment/sigil.png" />
+  </tile>
+  <tile id="64">
+    <properties>
+      <property name="icon" value="skull.png" />
+    </properties>
+    <image width="16" height="16" source="../../../art/sprites/environment/skull.png" />
+  </tile>
+  <tile id="68">
+    <properties>
+      <property name="color" value="#008c00" />
+      <property name="icon" value="treeAlt.png" />
+      <property name="isDangerous" value="true" />
+      <property name="opaque" value="true" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/treeAlt.png"
+    />
+  </tile>
+  <tile id="67">
+    <properties>
+      <property name="icon" value="tower.png" />
+    </properties>
+    <image width="16" height="16" source="../../../art/sprites/environment/tower.png" />
+  </tile>
+  <tile id="69">
+    <properties>
+      <property name="color" value="#525f47" />
+      <property name="icon" value="tundra.png" />
+      <property name="opaque" value="false" />
+      <property name="passable" value="true" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/tundra.png"
+    />
+  </tile>
+  <tile id="70">
+    <properties>
+      <property name="color" value="#500000" />
+      <property name="icon" value="volcano.png" />
+      <property name="opaque" value="true" />
+      <property name="passable" value="false" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/volcano.png"
+    />
+  </tile>
+  <tile id="44">
+    <properties>
+      <property name="icon" value="zTransparentMountain.png" />
+      <property name="passable" value="false" />
+      <property name="shipPassable" value="false" />
+    </properties>
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/environment/zTransparentMountain.png"
+    />
+  </tile>
 </tileset>
diff --git a/src/assets/maps/tiles/objects.tsx b/src/assets/maps/tiles/objects.tsx
index 60e0188d..8120d441 100644
--- a/src/assets/maps/tiles/objects.tsx
+++ b/src/assets/maps/tiles/objects.tsx
@@ -1,76 +1,129 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<tileset version="1.9" tiledversion="1.9.2" name="../../images/objects.png" tilewidth="16" tileheight="16" tilecount="24" columns="0" objectalignment="topleft">
- <grid orientation="orthogonal" width="1" height="1"/>
- <tile id="0">
-  <image width="16" height="16" source="../../../art/sprites/objects/bigCastleCenter.png"/>
- </tile>
- <tile id="1">
-  <image width="16" height="16" source="../../../art/sprites/objects/bigCastleLeft.png"/>
- </tile>
- <tile id="2">
-  <image width="16" height="16" source="../../../art/sprites/objects/bigCastleRight.png"/>
- </tile>
- <tile id="3">
-  <image width="16" height="16" source="../../../art/sprites/objects/chest.png"/>
- </tile>
- <tile id="4">
-  <image width="16" height="16" source="../../../art/sprites/objects/city.png"/>
- </tile>
- <tile id="5">
-  <image width="16" height="16" source="../../../art/sprites/objects/doorInWall.png"/>
- </tile>
- <tile id="6">
-  <image width="16" height="16" source="../../../art/sprites/objects/doorway.png"/>
- </tile>
- <tile id="7">
-  <image width="16" height="16" source="../../../art/sprites/objects/dungeonGate.png"/>
- </tile>
- <tile id="8">
-  <image width="16" height="16" source="../../../art/sprites/objects/keep.png"/>
- </tile>
- <tile id="9">
-  <image width="16" height="16" source="../../../art/sprites/objects/palaceCenter.png"/>
- </tile>
- <tile id="10">
-  <image width="16" height="16" source="../../../art/sprites/objects/palaceLeft.png"/>
- </tile>
- <tile id="11">
-  <image width="16" height="16" source="../../../art/sprites/objects/palaceRight.png"/>
- </tile>
- <tile id="12">
-  <image width="16" height="16" source="../../../art/sprites/objects/shop.png"/>
- </tile>
- <tile id="13">
-  <image width="16" height="16" source="../../../art/sprites/objects/temple.png"/>
- </tile>
- <tile id="14">
-  <image width="16" height="16" source="../../../art/sprites/objects/tower.png"/>
- </tile>
- <tile id="15">
-  <image width="16" height="16" source="../../../art/sprites/objects/staticShip.png"/>
- </tile>
- <tile id="16">
-  <image width="16" height="16" source="../../../art/sprites/environment/gold.png"/>
- </tile>
- <tile id="17">
-  <image width="16" height="16" source="../../../art/sprites/objects/invalid.png"/>
- </tile>
- <tile id="18">
-  <image width="16" height="16" source="../../../art/sprites/objects/woodenDoor.png"/>
- </tile>
- <tile id="20">
-  <image width="16" height="16" source="../../../art/sprites/objects/transparent.png"/>
- </tile>
- <tile id="21">
-  <image width="16" height="16" source="../../../art/sprites/objects/weapons.png"/>
- </tile>
- <tile id="23">
-  <image width="16" height="16" source="../../../art/sprites/objects/items.png"/>
- </tile>
- <tile id="24">
-  <image width="16" height="16" source="../../../art/sprites/objects/magics.png"/>
- </tile>
- <tile id="25">
-  <image width="16" height="16" source="../../../art/sprites/objects/armors.png"/>
- </tile>
+<tileset
+  version="1.9"
+  tiledversion="1.9.2"
+  name="../../images/objects.png"
+  tilewidth="16"
+  tileheight="16"
+  tilecount="24"
+  columns="0"
+  objectalignment="topleft"
+>
+  <grid orientation="orthogonal" width="1" height="1" />
+  <tile id="0">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/objects/bigCastleCenter.png"
+    />
+  </tile>
+  <tile id="1">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/objects/bigCastleLeft.png"
+    />
+  </tile>
+  <tile id="2">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/objects/bigCastleRight.png"
+    />
+  </tile>
+  <tile id="3">
+    <image width="16" height="16" source="../../../art/sprites/objects/chest.png" />
+  </tile>
+  <tile id="4">
+    <image width="16" height="16" source="../../../art/sprites/objects/city.png" />
+  </tile>
+  <tile id="5">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/objects/doorInWall.png"
+    />
+  </tile>
+  <tile id="6">
+    <image width="16" height="16" source="../../../art/sprites/objects/doorway.png" />
+  </tile>
+  <tile id="7">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/objects/dungeonGate.png"
+    />
+  </tile>
+  <tile id="8">
+    <image width="16" height="16" source="../../../art/sprites/objects/keep.png" />
+  </tile>
+  <tile id="9">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/objects/palaceCenter.png"
+    />
+  </tile>
+  <tile id="10">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/objects/palaceLeft.png"
+    />
+  </tile>
+  <tile id="11">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/objects/palaceRight.png"
+    />
+  </tile>
+  <tile id="12">
+    <image width="16" height="16" source="../../../art/sprites/objects/shop.png" />
+  </tile>
+  <tile id="13">
+    <image width="16" height="16" source="../../../art/sprites/objects/temple.png" />
+  </tile>
+  <tile id="14">
+    <image width="16" height="16" source="../../../art/sprites/objects/tower.png" />
+  </tile>
+  <tile id="15">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/objects/staticShip.png"
+    />
+  </tile>
+  <tile id="16">
+    <image width="16" height="16" source="../../../art/sprites/environment/gold.png" />
+  </tile>
+  <tile id="17">
+    <image width="16" height="16" source="../../../art/sprites/objects/invalid.png" />
+  </tile>
+  <tile id="18">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/objects/woodenDoor.png"
+    />
+  </tile>
+  <tile id="20">
+    <image
+      width="16"
+      height="16"
+      source="../../../art/sprites/objects/transparent.png"
+    />
+  </tile>
+  <tile id="21">
+    <image width="16" height="16" source="../../../art/sprites/objects/weapons.png" />
+  </tile>
+  <tile id="23">
+    <image width="16" height="16" source="../../../art/sprites/objects/items.png" />
+  </tile>
+  <tile id="24">
+    <image width="16" height="16" source="../../../art/sprites/objects/magics.png" />
+  </tile>
+  <tile id="25">
+    <image width="16" height="16" source="../../../art/sprites/objects/armors.png" />
+  </tile>
 </tileset>
diff --git a/src/index.html b/src/index.html
index e19c3b81..733a496a 100644
--- a/src/index.html
+++ b/src/index.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+<!doctype html>
 <html lang="en">
   <head>
     <meta charset="utf-8" />
@@ -80,7 +80,8 @@
       @font-face {
         font-family: "GraphicPixel";
         src: url("assets/fonts/graphicpixel-webfont.eot");
-        src: url("assets/fonts/graphicpixel-webfont.eot?#iefix")
+        src:
+          url("assets/fonts/graphicpixel-webfont.eot?#iefix")
             format("embedded-opentype"),
           url("assets/fonts/graphicpixel-webfont.woff") format("woff"),
           url("assets/fonts/graphicpixel-webfont.ttf") format("truetype"),
@@ -92,7 +93,8 @@
       @font-face {
         font-family: "Glyphicons";
         src: url("assets/fonts/glyphicons-halflings-regular.eot");
-        src: url("assets/fonts/glyphicons-halflings-regular.eot?#iefix")
+        src:
+          url("assets/fonts/glyphicons-halflings-regular.eot?#iefix")
             format("embedded-opentype"),
           url("assets/fonts/glyphicons-halflings-regular.woff") format("woff"),
           url("assets/fonts/glyphicons-halflings-regular.ttf") format("truetype"),
@@ -105,7 +107,9 @@
         font-style: normal;
         font-weight: 400;
         src: url(assets/fonts/iconfont/MaterialIcons-Regular.eot); /* For IE6-8 */
-        src: local("Material Icons"), local("MaterialIcons-Regular"),
+        src:
+          local("Material Icons"),
+          local("MaterialIcons-Regular"),
           url(assets/fonts/iconfont/MaterialIcons-Regular.woff2) format("woff2"),
           url(assets/fonts/iconfont/MaterialIcons-Regular.woff) format("woff"),
           url(assets/fonts/iconfont/MaterialIcons-Regular.ttf) format("truetype");
@@ -114,7 +118,8 @@
       @font-face {
         font-family: "AdvoCut";
         src: url("assets/fonts/advocut-webfont.eot");
-        src: url("assets/fonts/advocut-webfont.eot?#iefix") format("embedded-opentype"),
+        src:
+          url("assets/fonts/advocut-webfont.eot?#iefix") format("embedded-opentype"),
           url("assets/fonts/advocut-webfont.woff") format("woff"),
           url("assets/fonts/advocut-webfont.ttf") format("truetype"),
           url("assets/fonts/advocut-webfont.svg#AndinaRegular") format("svg");
@@ -168,15 +173,21 @@
       .hero-container > h1 a {
         text-decoration: none;
         color: inherit;
-        text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1), -8px 0 rgba(255, 255, 255, 0.2),
-          0px 0 rgba(0, 0, 0, 0.1), -4px 4px 0 rgba(255, 255, 255, 0.2);
+        text-shadow:
+          4px 4px 0 rgba(0, 0, 0, 0.1),
+          -8px 0 rgba(255, 255, 255, 0.2),
+          0px 0 rgba(0, 0, 0, 0.1),
+          -4px 4px 0 rgba(255, 255, 255, 0.2);
       }
 
       .hero-container p {
         padding: 15px;
         font-size: 1.2em;
-        text-shadow: -2px 0 rgba(255, 255, 255, 0.2), 1px 1px 0 rgba(0, 0, 0, 0.1),
-          -1px 1px 0 rgba(255, 255, 255, 0.2), 0px 0 rgba(0, 0, 0, 0.1);
+        text-shadow:
+          -2px 0 rgba(255, 255, 255, 0.2),
+          1px 1px 0 rgba(0, 0, 0, 0.1),
+          -1px 1px 0 rgba(255, 255, 255, 0.2),
+          0px 0 rgba(0, 0, 0, 0.1);
         color: #eeaa13;
       }
 
@@ -192,7 +203,10 @@
       }
 
       .hero-container.sad > h1 a {
-        text-shadow: -2px 0 #ff5252, 1px 1px 0 #f44336, -1px 1px 0 #ff5252,
+        text-shadow:
+          -2px 0 #ff5252,
+          1px 1px 0 #f44336,
+          -1px 1px 0 #ff5252,
           0px 0 #f44336;
       }
 
diff --git a/src/test.ts b/src/test.ts
index 43cc085d..e8259d81 100644
--- a/src/test.ts
+++ b/src/test.ts
@@ -9,7 +9,8 @@ import {
 // First, initialize the Angular testing environment.
 getTestBed().initTestEnvironment(
   BrowserDynamicTestingModule,
-  platformBrowserDynamicTesting(), {
-    teardown: { destroyAfterEach: false }
-}
+  platformBrowserDynamicTesting(),
+  {
+    teardown: { destroyAfterEach: false },
+  },
 );
diff --git a/src/tiled/follow-portal.js b/src/tiled/follow-portal.js
index 0d928575..e1183a02 100644
--- a/src/tiled/follow-portal.js
+++ b/src/tiled/follow-portal.js
@@ -9,7 +9,7 @@
 
 /* global tiled */
 
-const followWarp = tiled.registerAction('FollowPortal', function (/* action */) {
+const followWarp = tiled.registerAction("FollowPortal", function (/* action */) {
   /** @type TileMap */
   const map = tiled.activeAsset;
   if (!map.isTileMap) {
@@ -21,9 +21,9 @@ const followWarp = tiled.registerAction('FollowPortal', function (/* action */)
     return;
   }
 
-  const target = selectedObject.property('target');
-  const targetX = parseInt(selectedObject.property('targetX'), 10) * 16;
-  const targetY = parseInt(selectedObject.property('targetY'), 10) * 16;
+  const target = selectedObject.property("target");
+  const targetX = parseInt(selectedObject.property("targetX"), 10) * 16;
+  const targetY = parseInt(selectedObject.property("targetY"), 10) * 16;
   if (!target) {
     return;
   }
@@ -36,7 +36,7 @@ const followWarp = tiled.registerAction('FollowPortal', function (/* action */)
 
   tiled.mapEditor.currentMapView.centerOn(targetX, targetY);
 });
-followWarp.text = 'Follow Portal';
-followWarp.shortcut = 'Ctrl+F';
+followWarp.text = "Follow Portal";
+followWarp.shortcut = "Ctrl+F";
 
-tiled.extendMenu('Map', [{ separator: true }, { action: 'FollowPortal' }]);
+tiled.extendMenu("Map", [{ separator: true }, { action: "FollowPortal" }]);
diff --git a/src/tiled/portal-tool.ts b/src/tiled/portal-tool.ts
index c216e042..c2db8bdd 100644
--- a/src/tiled/portal-tool.ts
+++ b/src/tiled/portal-tool.ts
@@ -46,7 +46,7 @@ var tool = tiled.registerTool('CreateDialog', {
   getMaps: function (): string[] {
     const mapsPath = tiled.activeAsset.fileName.substr(
       0,
-      tiled.activeAsset.fileName.indexOf('maps/') + 5
+      tiled.activeAsset.fileName.indexOf('maps/') + 5,
     );
     const files: string[] = File.directoryEntries(mapsPath);
     return files.filter((val) => val.endsWith('.tmx'));
diff --git a/src/tiled/prune-tileset-tool.ts b/src/tiled/prune-tileset-tool.ts
index bfa6dbe4..7acd2672 100644
--- a/src/tiled/prune-tileset-tool.ts
+++ b/src/tiled/prune-tileset-tool.ts
@@ -53,7 +53,7 @@ var tool = tiled.registerTool('PruneTileset', {
         const tileIcon = tilePath.substring(tilePath.lastIndexOf('/') + 1);
         if (tileIcon === icon) {
           tiled.log(
-            `-- found gid ${tile.id} for icon ${icon} in tileset ${tileSet.name}`
+            `-- found gid ${tile.id} for icon ${icon} in tileset ${tileSet.name}`,
           );
           return tile;
         }
@@ -136,18 +136,18 @@ var tool = tiled.registerTool('PruneTileset', {
       .sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
     tiled.log(`Tiles: [${sorted.join(', ')}]`);
     const images = Object.keys(allImages).map((image) =>
-      image.substring(image.lastIndexOf('/') + 1)
+      image.substring(image.lastIndexOf('/') + 1),
     );
     tiled.log(`Images: [${images.join(', ')}]`);
     const tilesets = Object.keys(allTilesets).map((tileset) =>
-      tileset.substring(tileset.lastIndexOf('/') + 1)
+      tileset.substring(tileset.lastIndexOf('/') + 1),
     );
     tiled.log(`Tilesets: [${tilesets.join(', ')}]`);
   },
   getMaps: function (): string[] {
     const mapsPath = tiled.activeAsset.fileName.substr(
       0,
-      tiled.activeAsset.fileName.indexOf('maps/') + 5
+      tiled.activeAsset.fileName.indexOf('maps/') + 5,
     );
     const files: string[] = File.directoryEntries(mapsPath);
     return files
@@ -157,7 +157,7 @@ var tool = tiled.registerTool('PruneTileset', {
   getTilesetPaths: function (): string[] {
     const mapsPath = tiled.activeAsset.fileName.substr(
       0,
-      tiled.activeAsset.fileName.indexOf('maps/') + 5
+      tiled.activeAsset.fileName.indexOf('maps/') + 5,
     );
     const tileSetsPath = `${mapsPath}tiles/`;
     const files: string[] = File.directoryEntries(tileSetsPath);
diff --git a/src/tiled/tsconfig.tiled.json b/src/tiled/tsconfig.tiled.json
index 8655a73c..06a7cb07 100644
--- a/src/tiled/tsconfig.tiled.json
+++ b/src/tiled/tsconfig.tiled.json
@@ -3,16 +3,9 @@
     "target": "es5",
     "module": "commonjs",
     "sourceMap": false,
-    "types": [
-      "node"
-    ],
-    "lib": [],
+    "types": ["node"],
+    "lib": []
   },
-  "include": [
-    "*.ts",
-    "**/*.ts",
-  ],
-  "exclude": [
-    "node_modules"
-  ]
-}
\ No newline at end of file
+  "include": ["*.ts", "**/*.ts"],
+  "exclude": ["node_modules"]
+}
diff --git a/src/tsconfig.write-game-data.json b/src/tsconfig.write-game-data.json
index 6e36aeaf..29139467 100644
--- a/src/tsconfig.write-game-data.json
+++ b/src/tsconfig.write-game-data.json
@@ -3,7 +3,5 @@
     "module": "commonjs",
     "target": "ES2017"
   },
-  "files": [
-    "write-game-data.ts"
-  ]
-}
\ No newline at end of file
+  "files": ["write-game-data.ts"]
+}
diff --git a/src/typings.d.ts b/src/typings.d.ts
index ddfdabc6..b54684bf 100644
--- a/src/typings.d.ts
+++ b/src/typings.d.ts
@@ -1,3 +1,3 @@
 ///<reference path='../node_modules/immutable/dist/immutable.d.ts'/>
 
-declare module 'javascript-astar';
\ No newline at end of file
+declare module 'javascript-astar';
diff --git a/src/webpack/game-data-plugin/index.js b/src/webpack/game-data-plugin/index.js
index a33e2d95..1d137842 100644
--- a/src/webpack/game-data-plugin/index.js
+++ b/src/webpack/game-data-plugin/index.js
@@ -52,7 +52,7 @@ function shouldWriteData() {
         SEEN_HASHES[filename] = hash;
       });
       return should;
-    }
+    },
   );
 }
 
@@ -117,7 +117,7 @@ module.exports = class GameDataPlugin {
               callback();
             });
           });
-        }
+        },
       );
     });
   }
diff --git a/src/webpack/sprite-sheet-plugin/README.md b/src/webpack/sprite-sheet-plugin/README.md
index 92b1c215..4cd5dc54 100644
--- a/src/webpack/sprite-sheet-plugin/README.md
+++ b/src/webpack/sprite-sheet-plugin/README.md
@@ -4,4 +4,4 @@ This is a utility library written to take a set of input source sprites and outp
 
 # License
 
-MIT: See the `LICENSE` in the root of the project.
\ No newline at end of file
+MIT: See the `LICENSE` in the root of the project.
diff --git a/src/webpack/sprite-sheet-plugin/index.js b/src/webpack/sprite-sheet-plugin/index.js
index 4ccf3125..3727eb72 100644
--- a/src/webpack/sprite-sheet-plugin/index.js
+++ b/src/webpack/sprite-sheet-plugin/index.js
@@ -127,7 +127,7 @@ SpriteSheetPlugin.prototype.apply = function (compiler) {
         }
 
         processInput();
-      }
+      },
     );
   });
 };
diff --git a/src/webpack/sprite-sheet-plugin/sprite-packer.js b/src/webpack/sprite-sheet-plugin/sprite-packer.js
index da496803..190a4df7 100644
--- a/src/webpack/sprite-sheet-plugin/sprite-packer.js
+++ b/src/webpack/sprite-sheet-plugin/sprite-packer.js
@@ -1,17 +1,17 @@
 "use strict";
-var path = require('path');
-var Q = require('q');
-var _ = require('underscore');
-var fs = require('graceful-fs');
-var PNG = require('pngjs').PNG;
-var streams = require('memory-streams');
-var boxPacker = require('binpacking').GrowingPacker;
+var path = require("path");
+var Q = require("q");
+var _ = require("underscore");
+var fs = require("graceful-fs");
+var PNG = require("pngjs").PNG;
+var streams = require("memory-streams");
+var boxPacker = require("binpacking").GrowingPacker;
 function scalePng(png, scale) {
   scale = Math.floor(scale);
   var scaledPng = new PNG({
     width: png.width * scale,
     height: png.height * scale,
-    filterType: 0
+    filterType: 0,
   });
   for (var y = 0; y < scaledPng.height; y++) {
     for (var x = 0; x < scaledPng.width; x++) {
@@ -35,28 +35,30 @@ function readPngData(file, scale) {
   Q.all([
     readFile(file),
     readPngMetaData(path.join(path.dirname(file), defaultsFile), scale),
-    readPngMetaData(file, scale)
-  ]).spread(function (data, defaultMeta, meta) {
-    var stream = new PNG();
-    stream.on('parsed', function () {
-      var png = scale > 1 ? scalePng(this, scale) : this;
-      stream.end();
-      deferred.resolve({
-        png: png,
-        meta: _.extend({}, defaultMeta || {}, meta || {}),
-        file: file
+    readPngMetaData(file, scale),
+  ])
+    .spread(function (data, defaultMeta, meta) {
+      var stream = new PNG();
+      stream.on("parsed", function () {
+        var png = scale > 1 ? scalePng(this, scale) : this;
+        stream.end();
+        deferred.resolve({
+          png: png,
+          meta: _.extend({}, defaultMeta || {}, meta || {}),
+          file: file,
+        });
       });
+      stream.write(data);
+    })
+    .catch(function (err) {
+      deferred.reject(err);
     });
-    stream.write(data);
-  }).catch(function (err) {
-    deferred.reject(err);
-  });
   return deferred.promise;
 }
 function readPngMetaData(file, scale) {
   var deferred = Q.defer();
-  var file = file.replace(/\.[^\.]+$/, '.json');
-  fs.readFile(file, 'utf-8', function (err, data) {
+  var file = file.replace(/\.[^\.]+$/, ".json");
+  fs.readFile(file, "utf-8", function (err, data) {
     if (err) {
       deferred.resolve(null);
       return;
@@ -64,8 +66,7 @@ function readPngMetaData(file, scale) {
     try {
       var obj = JSON.parse(data.toString());
       deferred.resolve(obj);
-    }
-    catch (e) {
+    } catch (e) {
       deferred.reject(e);
     }
   });
@@ -84,21 +85,23 @@ function writePackedImage(name, cells, width, height, spriteSize, scale) {
   var deferred = Q.defer();
   var stream = new PNG({
     width: width,
-    height: height
+    height: height,
   });
   clearFillPng(stream);
   var baseName = path.basename(name);
-  var pngName = name + '.png';
+  var pngName = name + ".png";
   var writer = new streams.WritableStream();
   // var writer = fs.createWriteStream(pngName);
   _.each(cells, function (cell) {
     cell.png.bitblt(stream, 0, 0, cell.width, cell.height, cell.x, cell.y);
   });
-  stream.on('end', function () {
+  stream.on("end", function () {
     var metaData = {};
     _.each(cells, function (cell) {
       var fileName = cell.file.substr(cell.file.lastIndexOf("/") + 1);
-      var index = (cell.x / (spriteSize * scale)) + (cell.y / (spriteSize * scale)) * (width / spriteSize);
+      var index =
+        cell.x / (spriteSize * scale) +
+        (cell.y / (spriteSize * scale)) * (width / spriteSize);
       var width = cell.png.width * scale;
       var height = cell.png.height * scale;
       var metaObj = {
@@ -108,14 +111,16 @@ function writePackedImage(name, cells, width, height, spriteSize, scale) {
         source: baseName,
         index: index,
         x: cell.x,
-        y: cell.y
+        y: cell.y,
       };
       if (cell.meta) {
         _.extend(metaObj, cell.meta);
-        var hasWidth = typeof metaObj.cellWidth !== 'undefined';
-        var hasHeight = typeof metaObj.cellHeight !== 'undefined';
+        var hasWidth = typeof metaObj.cellWidth !== "undefined";
+        var hasHeight = typeof metaObj.cellHeight !== "undefined";
         if (hasWidth && hasHeight) {
-          metaObj.frames = (cell.png.width / metaObj.cellHeight) * (cell.png.height / metaObj.cellHeight);
+          metaObj.frames =
+            (cell.png.width / metaObj.cellHeight) *
+            (cell.png.height / metaObj.cellHeight);
         }
       }
       metaData[fileName] = metaObj;
@@ -125,23 +130,27 @@ function writePackedImage(name, cells, width, height, spriteSize, scale) {
     deferred.resolve({
       file: writer.toBuffer(),
       name: baseName,
-      meta: metaData
+      meta: metaData,
     });
   });
   stream.pack().pipe(writer);
   return deferred.promise;
 }
 module.exports = function (files, options) {
-  options = _.extend({}, {
-    outName: 'spriteSheet',
-    scale: 1
-  }, options || {});
+  options = _.extend(
+    {},
+    {
+      outName: "spriteSheet",
+      scale: 1,
+    },
+    options || {},
+  );
   var SOURCE_SPRITE_SIZE = 16;
-  if (path.extname(options.outName) !== '') {
-    options.outName = options.outName.substr(0, options.outName.lastIndexOf('.'));
+  if (path.extname(options.outName) !== "") {
+    options.outName = options.outName.substr(0, options.outName.lastIndexOf("."));
   }
   files = _.filter(files, function (file) {
-    return path.extname(file) == '.png';
+    return path.extname(file) == ".png";
   });
   var readFiles = _.map(files, function (file) {
     return readPngData(file, options.scale);
@@ -151,26 +160,32 @@ module.exports = function (files, options) {
       return {
         w: d.png.width,
         h: d.png.height,
-        data: d
+        data: d,
       };
     });
     var needSort = false;
     var blockW = -1;
     var blockH = -1;
     blocks.forEach(function (block) {
-      if ((blockW !== -1 && block.w !== blockW) || (block.h !== blockH && blockH !== -1)) {
+      if (
+        (blockW !== -1 && block.w !== blockW) ||
+        (block.h !== blockH && blockH !== -1)
+      ) {
         needSort = true;
       }
       blockW = block.w;
       blockH = block.h;
     });
     if (needSort) {
-      console.log("Sorting " + options.outName + " by size, because it contains sprites of varying sizes.");
+      console.log(
+        "Sorting " +
+          options.outName +
+          " by size, because it contains sprites of varying sizes.",
+      );
       blocks = blocks.sort(function (a, b) {
         return a.w - b.w;
       });
-    }
-    else {
+    } else {
       blocks = blocks.sort(function (a, b) {
         return path.basename(a.data.file).localeCompare(path.basename(b.data.file));
       });
@@ -185,9 +200,16 @@ module.exports = function (files, options) {
         y: b.fit.y,
         png: b.data.png,
         meta: b.data.meta,
-        file: b.data.file
+        file: b.data.file,
       };
     });
-    return writePackedImage(options.outName, cells, packer.root.w, packer.root.h, SOURCE_SPRITE_SIZE, options.scale);
+    return writePackedImage(
+      options.outName,
+      cells,
+      packer.root.w,
+      packer.root.h,
+      SOURCE_SPRITE_SIZE,
+      options.scale,
+    );
   });
 };
diff --git a/src/webpack/sprite-sheet-plugin/test/test.entry.js b/src/webpack/sprite-sheet-plugin/test/test.entry.js
index fe3f9e27..d6c3eefa 100644
--- a/src/webpack/sprite-sheet-plugin/test/test.entry.js
+++ b/src/webpack/sprite-sheet-plugin/test/test.entry.js
@@ -1,3 +1,3 @@
-'use strict';
+"use strict";
 
 console.log("The MODULE");
diff --git a/src/webpack/sprite-sheet-plugin/test/webpack.config.js b/src/webpack/sprite-sheet-plugin/test/webpack.config.js
index eef139c3..92963c15 100644
--- a/src/webpack/sprite-sheet-plugin/test/webpack.config.js
+++ b/src/webpack/sprite-sheet-plugin/test/webpack.config.js
@@ -1,26 +1,22 @@
-const webpack = require('webpack');
-const SpriteSheetPlugin = require('./../index');
+const webpack = require("webpack");
+const SpriteSheetPlugin = require("./../index");
 
 module.exports = function (options) {
   return {
-    entry: './test.entry.js',
+    entry: "./test.entry.js",
     module: {
       loaders: [
         {
           test: /\.(jpg|png|gif)$/,
-          loader: 'file'
-        }
-      ]
+          loader: "file",
+        },
+      ],
     },
 
-    plugins: [
-      new SpriteSheetPlugin([
-        {inputs: 'items/*.png', output: 'items'}
-      ])
-    ],
+    plugins: [new SpriteSheetPlugin([{ inputs: "items/*.png", output: "items" }])],
     output: {
-      path: 'dist',
-      filename: '[name].bundle.js'
-    }
-  }
+      path: "dist",
+      filename: "[name].bundle.js",
+    },
+  };
 };