diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 000000000..0642402e9
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,10 @@
+root = true
+[*]
+end_of_line = lf
+insert_final_newline = true
+charset = utf-8
+
+[*.ts]
+indent_style = space
+indent_size = 4
+trim_trailing_whitespace = true
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
new file mode 100644
index 000000000..47185e7c0
--- /dev/null
+++ b/.git-blame-ignore-revs
@@ -0,0 +1,2 @@
+# to be filled once final sha is known
+# Prettier init
diff --git a/.github/actions/setup-and-validate/action.yml b/.github/actions/setup-and-validate/action.yml
index 431cdc864..cc9ded1b7 100644
--- a/.github/actions/setup-and-validate/action.yml
+++ b/.github/actions/setup-and-validate/action.yml
@@ -4,9 +4,11 @@ runs:
   using: "composite"
   steps:
     - name: Set up Node.js
-      uses: actions/setup-node@v1.4.6
+      uses: actions/setup-node@v3
       with:
-        node-version: '16'
+        node-version: "16"
+        cache: "npm"
+        cache-dependency-path: package-lock.json
 
     - name: install deps
       run: npm ci
diff --git a/.github/workflows/validate-pr.yml b/.github/workflows/validate-pr.yml
index c1bbcbcf5..4e64746f8 100644
--- a/.github/workflows/validate-pr.yml
+++ b/.github/workflows/validate-pr.yml
@@ -6,7 +6,7 @@ jobs:
   build:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
 
       - name: Setup and validate themes
         uses: ./.github/actions/setup-and-validate
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 000000000..76f9aac83
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,13 @@
+node_modules
+.git
+langs/
+vendor/
+dist/
+.cache
+assets/generated/
+assets/themes/
+assets/layers/
+Docs/Tools/stats/
+Docs/Layers/
+Docs/Schemas/
+Docs/TagInfo/
\ No newline at end of file
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 000000000..7acf4f02d
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1,4 @@
+{
+  "semi": false,
+  "printWidth": 100
+}
diff --git a/Models/ThemeConfig/Conversion/AddContextToTranslations.ts b/Models/ThemeConfig/Conversion/AddContextToTranslations.ts
index af9961a89..335f3d761 100644
--- a/Models/ThemeConfig/Conversion/AddContextToTranslations.ts
+++ b/Models/ThemeConfig/Conversion/AddContextToTranslations.ts
@@ -44,7 +44,6 @@ export class AddContextToTranslations<T> extends DesugaringStep<T> {
      *   layers: [
      *       {
      *           tagRenderings:[
-     *               
      *               {id: "some-tr",
      *               question:{
      *                   en:"Question?"
@@ -59,7 +58,6 @@ export class AddContextToTranslations<T> extends DesugaringStep<T> {
      *   layers: [
      *       {
      *           tagRenderings:[
-     *               
      *               {id: "some-tr",
      *               question:{
      *                  _context: "prefix:context.layers.0.tagRenderings.some-tr.question"
diff --git a/UI/OpeningHours/OpeningHoursVisualization.ts b/UI/OpeningHours/OpeningHoursVisualization.ts
index f6f3a3c18..b0a8ee95c 100644
--- a/UI/OpeningHours/OpeningHoursVisualization.ts
+++ b/UI/OpeningHours/OpeningHoursVisualization.ts
@@ -1,15 +1,15 @@
-import {UIEventSource} from "../../Logic/UIEventSource";
+import { UIEventSource } from "../../Logic/UIEventSource";
 import Combine from "../Base/Combine";
-import {FixedUiElement} from "../Base/FixedUiElement";
-import {OH} from "./OpeningHours";
+import { FixedUiElement } from "../Base/FixedUiElement";
+import { OH } from "./OpeningHours";
 import Translations from "../i18n/Translations";
 import Constants from "../../Models/Constants";
 import BaseUIElement from "../BaseUIElement";
 import Toggle from "../Input/Toggle";
-import {VariableUiElement} from "../Base/VariableUIElement";
+import { VariableUiElement } from "../Base/VariableUIElement";
 import Table from "../Base/Table";
-import {Translation} from "../i18n/Translation";
-import {OsmConnection} from "../../Logic/Osm/OsmConnection";
+import { Translation } from "../i18n/Translation";
+import { OsmConnection } from "../../Logic/Osm/OsmConnection";
 
 export default class OpeningHoursVisualization extends Toggle {
     private static readonly weekdays: Translation[] = [
@@ -35,24 +35,24 @@ export default class OpeningHoursVisualization extends Toggle {
                 return value;
             }) // This mapping will absorb all other changes to tags in order to prevent regeneration
             .map(ohtext => {
-                    if (ohtext === undefined) {
-                        return new FixedUiElement("No opening hours defined with key " + key).SetClass("alert")
-                    }
-                    try {
-                        return OpeningHoursVisualization.CreateFullVisualisation(
-                            OH.CreateOhObject(tags.data, ohtext))
-                    } catch (e) {
-                        console.warn(e, e.stack);
-                        return new Combine([Translations.t.general.opening_hours.error_loading,
-                            new Toggle(
-                                new FixedUiElement(e).SetClass("subtle"),
-                                undefined,
-                                state?.osmConnection?.userDetails.map(userdetails => userdetails.csCount >= Constants.userJourney.tagsVisibleAndWikiLinked)
-                            )
-                        ]);
-                    }
-
+                if (ohtext === undefined) {
+                    return new FixedUiElement("No opening hours defined with key " + key).SetClass("alert")
                 }
+                try {
+                    return OpeningHoursVisualization.CreateFullVisualisation(
+                        OH.CreateOhObject(tags.data, ohtext))
+                } catch (e) {
+                    console.warn(e, e.stack);
+                    return new Combine([Translations.t.general.opening_hours.error_loading,
+                    new Toggle(
+                        new FixedUiElement(e).SetClass("subtle"),
+                        undefined,
+                        state?.osmConnection?.userDetails.map(userdetails => userdetails.csCount >= Constants.userJourney.tagsVisibleAndWikiLinked)
+                    )
+                    ]);
+                }
+
+            }
             ))
 
         super(
@@ -105,7 +105,7 @@ export default class OpeningHoursVisualization extends Toggle {
     }
 
     private static ConstructVizTable(oh: any, ranges: { isOpen: boolean; isSpecial: boolean; comment: string; startDate: Date; endDate: Date }[][],
-                                     rangeStart: Date): BaseUIElement {
+        rangeStart: Date): BaseUIElement {
 
 
         const isWeekstable: boolean = oh.isWeekStable();
@@ -158,7 +158,7 @@ export default class OpeningHoursVisualization extends Toggle {
         }
         return new Table(undefined,
             [["&nbsp", header], ...weekdays],
-            {contentStyle: [["width: 5%", `position: relative; height: ${headerHeight}`], ...weekdayStyles]}
+            { contentStyle: [["width: 5%", `position: relative; height: ${headerHeight}`], ...weekdayStyles] }
         ).SetClass("w-full")
             .SetStyle("border-collapse: collapse; word-break; word-break: normal; word-wrap: normal")
 
@@ -166,8 +166,8 @@ export default class OpeningHoursVisualization extends Toggle {
     }
 
     private static CreateRangeElem(availableArea: number, earliestOpen: number, latestclose: number,
-                                   range: { isOpen: boolean; isSpecial: boolean; comment: string; startDate: Date; endDate: Date },
-                                   isWeekstable: boolean): BaseUIElement {
+        range: { isOpen: boolean; isSpecial: boolean; comment: string; startDate: Date; endDate: Date },
+        isWeekstable: boolean): BaseUIElement {
 
         const textToShow = range.comment ?? (isWeekstable ? "" : range.startDate.toLocaleDateString());
 
@@ -179,6 +179,7 @@ export default class OpeningHoursVisualization extends Toggle {
         startOfDay.setHours(0, 0, 0, 0);
         // @ts-ignore
         const startpoint = (range.startDate - startOfDay) / 1000 - earliestOpen;
+        // prettier-ignore
         // @ts-ignore
         const width = (100 * (range.endDate - range.startDate) / 1000) / (latestclose - earliestOpen);
         const startPercentage = (100 * startpoint / availableArea);
@@ -270,8 +271,8 @@ export default class OpeningHoursVisualization extends Toggle {
             return Translations.t.general.opening_hours.closed_permanently.Clone()
         }
         const willOpenAt = `${opensAtDate.getDate()}/${opensAtDate.getMonth() + 1} ${OH.hhmm(opensAtDate.getHours(), opensAtDate.getMinutes())}`
-        return Translations.t.general.opening_hours.closed_until.Subs({date: willOpenAt})
+        return Translations.t.general.opening_hours.closed_until.Subs({ date: willOpenAt })
     }
 
-   
-}
\ No newline at end of file
+
+}
diff --git a/UI/Popup/TagRenderingQuestion.ts b/UI/Popup/TagRenderingQuestion.ts
index c3f22967e..a8f13bb88 100644
--- a/UI/Popup/TagRenderingQuestion.ts
+++ b/UI/Popup/TagRenderingQuestion.ts
@@ -1,38 +1,38 @@
-import {Store, Stores, UIEventSource} from "../../Logic/UIEventSource";
+import { Store, Stores, UIEventSource } from "../../Logic/UIEventSource";
 import Combine from "../Base/Combine";
-import {InputElement, ReadonlyInputElement} from "../Input/InputElement";
+import { InputElement, ReadonlyInputElement } from "../Input/InputElement";
 import ValidatedTextField from "../Input/ValidatedTextField";
-import {FixedInputElement} from "../Input/FixedInputElement";
-import {RadioButton} from "../Input/RadioButton";
-import {Utils} from "../../Utils";
+import { FixedInputElement } from "../Input/FixedInputElement";
+import { RadioButton } from "../Input/RadioButton";
+import { Utils } from "../../Utils";
 import CheckBoxes from "../Input/Checkboxes";
 import InputElementMap from "../Input/InputElementMap";
-import {SaveButton} from "./SaveButton";
-import {VariableUiElement} from "../Base/VariableUIElement";
+import { SaveButton } from "./SaveButton";
+import { VariableUiElement } from "../Base/VariableUIElement";
 import Translations from "../i18n/Translations";
-import {FixedUiElement} from "../Base/FixedUiElement";
-import {Translation} from "../i18n/Translation";
+import { FixedUiElement } from "../Base/FixedUiElement";
+import { Translation } from "../i18n/Translation";
 import Constants from "../../Models/Constants";
-import {SubstitutedTranslation} from "../SubstitutedTranslation";
-import {TagsFilter} from "../../Logic/Tags/TagsFilter";
-import {Tag} from "../../Logic/Tags/Tag";
-import {And} from "../../Logic/Tags/And";
-import {TagUtils, UploadableTag} from "../../Logic/Tags/TagUtils";
+import { SubstitutedTranslation } from "../SubstitutedTranslation";
+import { TagsFilter } from "../../Logic/Tags/TagsFilter";
+import { Tag } from "../../Logic/Tags/Tag";
+import { And } from "../../Logic/Tags/And";
+import { TagUtils, UploadableTag } from "../../Logic/Tags/TagUtils";
 import BaseUIElement from "../BaseUIElement";
-import {DropDown} from "../Input/DropDown";
+import { DropDown } from "../Input/DropDown";
 import InputElementWrapper from "../Input/InputElementWrapper";
 import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction";
-import TagRenderingConfig, {Mapping} from "../../Models/ThemeConfig/TagRenderingConfig";
-import {Unit} from "../../Models/Unit";
+import TagRenderingConfig, { Mapping } from "../../Models/ThemeConfig/TagRenderingConfig";
+import { Unit } from "../../Models/Unit";
 import VariableInputElement from "../Input/VariableInputElement";
 import Toggle from "../Input/Toggle";
 import Img from "../Base/Img";
 import FeaturePipelineState from "../../Logic/State/FeaturePipelineState";
 import Title from "../Base/Title";
-import {OsmConnection} from "../../Logic/Osm/OsmConnection";
-import {GeoOperations} from "../../Logic/GeoOperations";
-import {SearchablePillsSelector} from "../Input/SearchableMappingsSelector";
-import {OsmTags} from "../../Models/OsmFeature";
+import { OsmConnection } from "../../Logic/Osm/OsmConnection";
+import { GeoOperations } from "../../Logic/GeoOperations";
+import { SearchablePillsSelector } from "../Input/SearchableMappingsSelector";
+import { OsmTags } from "../../Models/OsmFeature";
 
 /**
  * Shows the question element.
@@ -41,15 +41,15 @@ import {OsmTags} from "../../Models/OsmFeature";
 export default class TagRenderingQuestion extends Combine {
 
     constructor(tags: UIEventSource<Record<string, string> & { id: string }>,
-                configuration: TagRenderingConfig,
-                state?: FeaturePipelineState,
-                options?: {
-                    units?: Unit[],
-                    afterSave?: () => void,
-                    cancelButton?: BaseUIElement,
-                    saveButtonConstr?: (src: Store<TagsFilter>) => BaseUIElement,
-                    bottomText?: (src: Store<TagsFilter>) => BaseUIElement
-                }
+        configuration: TagRenderingConfig,
+        state?: FeaturePipelineState,
+        options?: {
+            units?: Unit[],
+            afterSave?: () => void,
+            cancelButton?: BaseUIElement,
+            saveButtonConstr?: (src: Store<TagsFilter>) => BaseUIElement,
+            bottomText?: (src: Store<TagsFilter>) => BaseUIElement
+        }
     ) {
 
         const applicableMappingsSrc =
@@ -84,24 +84,24 @@ export default class TagRenderingQuestion extends Combine {
         const feedback = new UIEventSource<Translation>(undefined)
         const inputElement: ReadonlyInputElement<UploadableTag> =
             new VariableInputElement(applicableMappingsSrc.map(applicableMappings => {
-                    return TagRenderingQuestion.GenerateInputElement(state, configuration, applicableMappings, applicableUnit, tags, feedback)
-                }
+                return TagRenderingQuestion.GenerateInputElement(state, configuration, applicableMappings, applicableUnit, tags, feedback)
+            }
             ))
 
         const save = () => {
-            
-            
-            const selection = TagUtils.FlattenMultiAnswer(TagUtils.FlattenAnd( inputElement.GetValue().data, tags.data));
+
+
+            const selection = TagUtils.FlattenMultiAnswer(TagUtils.FlattenAnd(inputElement.GetValue().data, tags.data));
             if (selection) {
                 (state?.changes)
                     .applyAction(new ChangeTagAction(
                         tags.data.id, selection, tags.data, {
-                            theme: state?.layoutToUse?.id ?? "unkown",
-                            changeType: "answer",
-                        }
+                        theme: state?.layoutToUse?.id ?? "unkown",
+                        changeType: "answer",
+                    }
                     )).then(_ => {
-                    console.log("Tagchanges applied")
-                })
+                        console.log("Tagchanges applied")
+                    })
                 if (options.afterSave) {
                     options.afterSave();
                 }
@@ -229,7 +229,7 @@ export default class TagRenderingQuestion extends Combine {
         if (configuration.multiAnswer) {
             return TagRenderingQuestion.GenerateMultiAnswer(configuration, inputEls, ff, applicableMappings.map(mp => mp.ifnot))
         } else {
-            return new RadioButton(inputEls, {selectFirstAsDefault: false})
+            return new RadioButton(inputEls, { selectFirstAsDefault: false })
         }
 
     }
@@ -267,7 +267,6 @@ export default class TagRenderingQuestion extends Combine {
      *      freeform: {
      *          key:"key"
      *      },
-     *    
      *      mappings: [
      *          {
      *            if:"x=y",
@@ -298,7 +297,6 @@ export default class TagRenderingQuestion extends Combine {
      *      freeform: {
      *          key:"key"
      *      },
-     *    
      *      mappings: [
      *          {
      *            if:"x=y",
@@ -338,7 +336,7 @@ export default class TagRenderingQuestion extends Combine {
         const ff = configuration.freeform
         let onEmpty: BaseUIElement = undefined
         if (ff !== undefined) {
-            onEmpty = new VariableUiElement(searchValue.map(search => configuration.render.Subs({[ff.key]: search})))
+            onEmpty = new VariableUiElement(searchValue.map(search => configuration.render.Subs({ [ff.key]: search })))
         }
         const mode = configuration.multiAnswer ? "select-many" : "select-one";
 
@@ -357,7 +355,7 @@ export default class TagRenderingQuestion extends Combine {
                     return Translations.t.general.useSearch;
                 }
                 return new Combine([
-                    Translations.t.general.useSearchForMore.Subs({total: applicableMappings.length}),
+                    Translations.t.general.useSearchForMore.Subs({ total: applicableMappings.length }),
                     new SearchablePillsSelector(priority, {
                         selectedElements: tooMuchElementsValue,
                         hideSearchBar: true,
@@ -468,7 +466,7 @@ export default class TagRenderingQuestion extends Combine {
             },
             (tags: UploadableTag) => {
                 // {key --> values[]}
-                
+
                 const presentTags = TagUtils.SplitKeys([tags]);
                 const indices: number[] = []
                 // We also collect the values that have to be added to the freeform field
@@ -595,9 +593,9 @@ export default class TagRenderingQuestion extends Combine {
                     return tag;
                 }
                 return new And([
-                        tag,
-                        ...freeform.addExtraTags
-                    ]
+                    tag,
+                    ...freeform.addExtraTags
+                ]
                 );
             };
 
@@ -637,7 +635,7 @@ export default class TagRenderingQuestion extends Combine {
         // Add a length check
         input?.GetValue().addCallbackD((v: string | undefined) => {
             if (v?.length >= 255) {
-                feedback.setData(Translations.t.validation.tooLong.Subs({count: v.length}))
+                feedback.setData(Translations.t.validation.tooLong.Subs({ count: v.length }))
             }
         })
 
@@ -657,8 +655,8 @@ export default class TagRenderingQuestion extends Combine {
     }
 
     public static CreateTagExplanation(selectedValue: Store<TagsFilter>,
-                                       tags: Store<object>,
-                                       state?: { osmConnection?: OsmConnection }) {
+        tags: Store<object>,
+        state?: { osmConnection?: OsmConnection }) {
         return new VariableUiElement(
             selectedValue.map(
                 (tagsFilter: TagsFilter) => {
@@ -680,4 +678,4 @@ export default class TagRenderingQuestion extends Combine {
         ).SetClass("block break-all")
     }
 
-}
\ No newline at end of file
+}
diff --git a/customGenerator.html b/customGenerator.html
index ffa831d38..45cd309f5 100644
--- a/customGenerator.html
+++ b/customGenerator.html
@@ -1,15 +1,16 @@
 <html>
+  <body>
+    The custom generator has moved (temporarily), go to
+    <a href="https://pietervdvn.github.io/mc/legacy/070/customGenerator.html">
+      Redirecting you to the development version</a
+    >
 
-<body>
-
-The custom generator has moved (temporarily), go to <a
-        href='https://pietervdvn.github.io/mc/legacy/070/customGenerator.html'</a>
-Redirecting you to the development version
-
-<script>
-    window.location.replace("https://pietervdvn.github.io/mc/legacy/070/customGenerator.html" + window.location.search + window.location.hash);
-</script>
-
-</body>
-
+    <script>
+      window.location.replace(
+        "https://pietervdvn.github.io/mc/legacy/070/customGenerator.html" +
+          window.location.search +
+          window.location.hash
+      );
+    </script>
+  </body>
 </html>
diff --git a/package-lock.json b/package-lock.json
index b0c1b1239..8100ca3af 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,7 +9,6 @@
       "version": "0.0.5",
       "license": "GPL",
       "dependencies": {
-        "@parcel/service-worker": "^2.6.0",
         "@turf/boolean-intersects": "^6.5.0",
         "@turf/buffer": "^6.5.0",
         "@turf/collect": "^6.5.0",
@@ -49,6 +48,7 @@
       "devDependencies": {
         "@babel/polyfill": "^7.10.4",
         "@babel/preset-env": "7.13.8",
+        "@parcel/service-worker": "^2.6.0",
         "@types/chai": "^4.3.0",
         "@types/geojson": "^7946.0.10",
         "@types/leaflet-markercluster": "^1.0.3",
@@ -66,6 +66,7 @@
         "fs": "0.0.1-security",
         "mocha": "^9.2.2",
         "parcel": "^1.2.4",
+        "prettier": "2.7.1",
         "read-file": "^0.2.0",
         "sharp": "^0.30.5",
         "ts-node": "^10.9.1",
@@ -1542,6 +1543,7 @@
       "version": "2.6.0",
       "resolved": "https://registry.npmjs.org/@parcel/service-worker/-/service-worker-2.6.0.tgz",
       "integrity": "sha512-rOKRPoipOsg5XsYbag0mQ0WtVTscHjblL/zc0VA6O3ju5hgLAPVM4UmfdljuRVgRoMHSCV7wz1qAh9okvNqdjw==",
+      "dev": true,
       "engines": {
         "node": ">= 12.0.0",
         "parcel": "^2.6.0"
@@ -12630,6 +12632,21 @@
         "node": ">= 0.8.0"
       }
     },
+    "node_modules/prettier": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
+      "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
+      "dev": true,
+      "bin": {
+        "prettier": "bin-prettier.js"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      },
+      "funding": {
+        "url": "https://github.com/prettier/prettier?sponsor=1"
+      }
+    },
     "node_modules/process": {
       "version": "0.11.10",
       "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
@@ -17943,7 +17960,8 @@
     "@parcel/service-worker": {
       "version": "2.6.0",
       "resolved": "https://registry.npmjs.org/@parcel/service-worker/-/service-worker-2.6.0.tgz",
-      "integrity": "sha512-rOKRPoipOsg5XsYbag0mQ0WtVTscHjblL/zc0VA6O3ju5hgLAPVM4UmfdljuRVgRoMHSCV7wz1qAh9okvNqdjw=="
+      "integrity": "sha512-rOKRPoipOsg5XsYbag0mQ0WtVTscHjblL/zc0VA6O3ju5hgLAPVM4UmfdljuRVgRoMHSCV7wz1qAh9okvNqdjw==",
+      "dev": true
     },
     "@parcel/utils": {
       "version": "1.11.0",
@@ -26760,6 +26778,12 @@
       "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
       "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
     },
+    "prettier": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
+      "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
+      "dev": true
+    },
     "process": {
       "version": "0.11.10",
       "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
diff --git a/package.json b/package.json
index b3207bfbc..bd6ad2489 100644
--- a/package.json
+++ b/package.json
@@ -42,6 +42,7 @@
     "generate:charging-stations": "cd ./assets/layers/charging_station && ts-node csvToJson.ts && cd -",
     "prepare-deploy": "npm run generate:service-worker && ./scripts/build.sh",
     "gittag": "ts-node scripts/printVersion.ts | bash",
+    "format": "npx prettier --write '**/*.ts'",
     "lint": "tslint --project . -c tslint.json '**.ts' ",
     "clean:tests": "(find . -type f -name \"*.doctest.ts\" | xargs rm)",
     "clean": "rm -rf .cache/ && (find *.html | grep -v \"\\(404\\|index\\|land\\|test\\|preferences\\|customGenerator\\|professional\\|automaton\\|import_helper\\|import_viewer\\|theme\\).html\" | xargs rm) && (ls | grep \"^index_[a-zA-Z_-]\\+\\.ts$\" | xargs rm) && (ls | grep \".*.webmanifest$\" | grep -v \"manifest.webmanifest\" | xargs rm)",
@@ -51,7 +52,7 @@
     "weblate-add-upstream": "git remote add weblate-github git@github.com:weblate/MapComplete.git",
     "weblate-fix": "git remote update weblate-github; git merge weblate-github/weblate-mapcomplete-core; git merge weblate-github/weblate-mapcomplete-layers; git merge weblate-github/weblate-mapcomplete-layer-translations",
     "weblate-fix-heavy": "git remote rm weblate-layers; git remote add weblate-layers https://hosted.weblate.org/git/mapcomplete/layers/; git remote update weblate-layers; git merge weblate-layers/master",
-    "housekeeping": "npm run generate && npm run generate:docs && npm run generate:contributor-list && git add Docs/* && git commit assets/ langs/ Docs/ -m 'Housekeeping...'",
+    "housekeeping": "npm run generate && npm run generate:docs && npm run generate:contributor-list && npm run format && git add *.ts && git add Docs/* && git commit assets/ langs/ Docs/ -m 'Housekeeping...'",
     "parseSchools": "ts-node scripts/schools/amendSchoolData.ts",
     "steal": "ts-node scripts/thieves/stealLanguages.ts"
   },
@@ -68,7 +69,6 @@
     "not op_mini all"
   ],
   "dependencies": {
-    "@parcel/service-worker": "^2.6.0",
     "@turf/boolean-intersects": "^6.5.0",
     "@turf/buffer": "^6.5.0",
     "@turf/collect": "^6.5.0",
@@ -108,6 +108,7 @@
   "devDependencies": {
     "@babel/polyfill": "^7.10.4",
     "@babel/preset-env": "7.13.8",
+    "@parcel/service-worker": "^2.6.0",
     "@types/chai": "^4.3.0",
     "@types/geojson": "^7946.0.10",
     "@types/leaflet-markercluster": "^1.0.3",
@@ -125,6 +126,7 @@
     "fs": "0.0.1-security",
     "mocha": "^9.2.2",
     "parcel": "^1.2.4",
+    "prettier": "2.7.1",
     "read-file": "^0.2.0",
     "sharp": "^0.30.5",
     "ts-node": "^10.9.1",