diff --git a/.forgejo/workflows/build+release.yml b/.forgejo/workflows/build+release.yml
deleted file mode 100644
index c473e32..0000000
--- a/.forgejo/workflows/build+release.yml
+++ /dev/null
@@ -1,91 +0,0 @@
-name: 'Build and Release Binary File'
-author: 'Neshura'
-
-on: 
-    push:
-        tags:
-            - '[0-9]+.[0-9]+.[0-9]+'
-            - '[0-9]+.[0-9]+.[0-9]+rc[0-9]+'
-jobs:
-    test:
-        runs-on: docker
-        steps:
-            -
-                name: Checking Out Repository Code
-                uses: https://code.forgejo.org/actions/checkout@v3
-            -
-                name: Placeholder
-                run: echo Placeholder Job
-            -
-                name: Check if Version in Cargo.toml matches Tag
-                run: |
-                    VERSION=$(cat Cargo.toml | grep -E "(^|\|)version =" | cut -f2- -d= | tr -d \" | tr -d " ")
-                    if test $VERSION != "${{  github.ref_name }}"; then 
-                        echo "Expected Version is: '${{  github.ref_name }}' actual Version is: '$VERSION'"; 
-                        exit 1
-                    else 
-                        echo "Version is: '$VERSION'"; 
-                    fi
-
-    build:
-        needs: test
-        if: success()
-        runs-on: docker
-        container: rust:latest
-        steps: 
-            -
-                name: Installing Node
-                run: apt update && apt install -y nodejs
-            -
-                name: Checking Out Repository Code
-                uses: https://code.forgejo.org/actions/checkout@v3
-            -
-                name: Preparing Environment
-                run: |
-                    echo DATABASE_URL=${{ secrets.DATABASE_URL }} >> .env
-                    echo MACHINE_GROUP_ID=${{ vars.MACHINE_GROUP_ID }} >> .env
-                    echo UPTIME_KUMA_URL= >> .env
-            -
-                name: Compiling To Linux Target
-                run: |
-                    cargo build -r
-                    mv target/release/chellaris-rust-api chellaris-rust-api-linux-amd64                    
-            -
-                name: Uploading Build Artifact
-                uses: actions/upload-artifact@v3
-                with:
-                    name: chellaris-rust-api-linux-amd64
-                    path: chellaris-rust-api-linux-amd64
-                    if-no-files-found: error
-
-    upload-release:
-        needs: build
-        if: success()
-        runs-on: docker
-        steps:
-            -
-                name: Downloading All Build Artifacts
-                uses: actions/download-artifact@v3
-            -
-                name: Rearrange Artifact Paths
-                run: |
-                    mkdir release
-                    mv chellaris-rust-api-linux-amd64/chellaris-rust-api-linux-amd64 release/chellaris-rust-api-linux-amd64                    
-            -
-                name: Upload Artifacts As Generic Packages
-                run: |
-                    echo 'curl -v --user ${{ secrets.FORGEJO_USERNAME }}:${{ secrets.FORGEJO_TOKEN }} \
-                    --upload-file release/chellaris-rust-api-linux-amd64 \
-                    https://forgejo.neshweb.net/api/packages/${{ secrets.FORGEJO_USERNAME }}/generic/${{ github.event.repository.name }}/${{  github.ref_name }}/chellaris-rust-api-linux-amd64'
-                    curl -v --user ${{ secrets.FORGEJO_USERNAME }}:${{ secrets.FORGEJO_TOKEN }} \
-                    --upload-file release/chellaris-rust-api-linux-amd64 \
-                    https://forgejo.neshweb.net/api/packages/${{ secrets.FORGEJO_USERNAME }}/generic/${{ github.event.repository.name }}/${{  github.ref_name }}/chellaris-rust-api-linux-amd64                    
-            -
-                name: Release New Version
-                uses: actions/forgejo-release@v1
-                with:
-                    direction: upload
-                    url: https://forgejo.neshweb.net
-                    release-dir: release
-                    token: ${{ secrets.FORGEJO_TOKEN }}
-                    tag: ${{  github.ref_name }}
diff --git a/.forgejo/workflows/test.yml b/.forgejo/workflows/test.yml
deleted file mode 100644
index 637f42a..0000000
--- a/.forgejo/workflows/test.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: 'Run Tests on Code'
-author: 'Neshura'
-
-on: 
-    push:
-        tags-ignore:
-            - '**'
-        branches:
-            - '**'
-jobs:
-    run-tests:
-        runs-on: docker
-        steps:
-            -
-                name: Placeholder
-                run: echo Placeholder Job
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 14602bb..ecdc5b9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,4 @@
 /target
-/.vscode
-/.idea
 
 config.toml
 
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..20c400c
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,68 @@
+image: 3.10.8-slim-buster
+
+variables:
+  PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/linux/$CI_COMMIT_TAG/"
+
+.deploy:
+  rules:
+    # Regex magic copied from Neshura/page-test, only deploys on x.y.z or higher (x.y) Tags
+    - if: $CI_COMMIT_TAG =~ /^((([\d])+\.){1,2}[\d]+)\s*$/ && $CI_COMMIT_TAG
+
+stages:          
+  - build
+  - upload
+  - release
+
+## Docker steps
+
+build:
+  image: rust:latest
+  stage: build
+
+  variables:
+    IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_BRANCH
+    CACHING: 
+  script:
+    - echo "Compiling the code..."
+    - cargo build -r
+    - echo "Compile complete."
+  after_script:
+    - echo JOB_ID=$CI_JOB_ID >> job.env
+    - mkdir ./artifacts
+    - cp /builds/Neshura/chellaris-rust-api/target/release/chellaris-rust-api ./artifacts/
+  artifacts:
+    paths:
+      - ./artifacts/
+    reports:
+      dotenv: job.env
+  rules:
+    - !reference [.deploy, rules]
+
+upload:
+  needs: 
+  - job: build
+    artifacts: true
+  image: curlimages/curl:latest
+  stage: upload
+  script:
+    - |
+      curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file artifacts/chellaris-rust-api "${PACKAGE_REGISTRY_URL}/chellaris-rust-api"
+  rules:
+    - !reference [.deploy, rules]
+
+
+Tag Release:
+  stage: release
+  image: registry.gitlab.com/gitlab-org/release-cli:latest
+  rules:
+    - !reference [.deploy, rules]  
+  script:
+    - apk add curl
+    - echo "running Release Job, attaching Artifact from Job $JOB_ID"
+  release:
+    tag_name: '$CI_COMMIT_TAG'
+    description: '$CI_COMMIT_TAG'
+    assets:
+      links:
+        - name: "chellaris-rust-api"
+          url: "${PACKAGE_REGISTRY_URL}/chellaris-rust-api"
diff --git a/Cargo.lock b/Cargo.lock
index ca617a4..93c78fa 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -21,17 +21,17 @@ dependencies = [
 
 [[package]]
 name = "actix-http"
-version = "3.4.0"
+version = "3.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a92ef85799cba03f76e4f7c10f533e66d87c9a7e7055f3391f09000ad8351bc9"
+checksum = "c2079246596c18b4a33e274ae10c0e50613f4d32a4198e09c7b93771013fed74"
 dependencies = [
  "actix-codec",
  "actix-rt",
  "actix-service",
  "actix-utils",
- "ahash",
+ "ahash 0.8.3",
  "base64",
- "bitflags 2.4.0",
+ "bitflags 1.3.2",
  "brotli",
  "bytes",
  "bytestring",
@@ -65,7 +65,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
 dependencies = [
  "quote",
- "syn 2.0.32",
+ "syn 2.0.29",
 ]
 
 [[package]]
@@ -132,9 +132,9 @@ dependencies = [
 
 [[package]]
 name = "actix-web"
-version = "4.4.0"
+version = "4.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e4a5b5e29603ca8c94a77c65cf874718ceb60292c5a5c3e5f4ace041af462b9"
+checksum = "cd3cb42f9566ab176e1ef0b8b3a896529062b4efc6be0123046095914c4c1c96"
 dependencies = [
  "actix-codec",
  "actix-http",
@@ -145,7 +145,7 @@ dependencies = [
  "actix-service",
  "actix-utils",
  "actix-web-codegen",
- "ahash",
+ "ahash 0.7.6",
  "bytes",
  "bytestring",
  "cfg-if",
@@ -154,6 +154,7 @@ dependencies = [
  "encoding_rs",
  "futures-core",
  "futures-util",
+ "http",
  "itoa",
  "language-tags",
  "log",
@@ -165,8 +166,8 @@ dependencies = [
  "serde_json",
  "serde_urlencoded",
  "smallvec",
- "socket2 0.5.5",
- "time",
+ "socket2 0.4.9",
+ "time 0.3.27",
  "url",
 ]
 
@@ -199,15 +200,25 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
 
 [[package]]
 name = "ahash"
-version = "0.8.6"
+version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a"
+checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
+dependencies = [
+ "getrandom",
+ "once_cell",
+ "version_check",
+]
+
+[[package]]
+name = "ahash"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
 dependencies = [
  "cfg-if",
  "getrandom",
  "once_cell",
  "version_check",
- "zerocopy",
 ]
 
 [[package]]
@@ -264,16 +275,6 @@ dependencies = [
  "num-traits",
 ]
 
-[[package]]
-name = "atomic-write-file"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edcdbedc2236483ab103a53415653d6b4442ea6141baf1ffa85df29635e88436"
-dependencies = [
- "nix",
- "rand",
-]
-
 [[package]]
 name = "autocfg"
 version = "1.1.0"
@@ -397,39 +398,37 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "chellaris-rust-api"
-version = "1.2.4"
+version = "0.1.0"
 dependencies = [
  "actix-web",
  "chrono",
  "ctrlc",
- "dotenvy",
- "dotenvy_macro",
+ "dotenv",
+ "dotenv_codegen",
  "env_logger",
- "rand",
- "reqwest",
  "schemars",
  "serde",
  "serde_json",
  "sqlx",
  "tokio",
  "toml",
- "url",
  "utoipa",
  "utoipa-swagger-ui",
 ]
 
 [[package]]
 name = "chrono"
-version = "0.4.31"
+version = "0.4.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
+checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5"
 dependencies = [
  "android-tzdata",
  "iana-time-zone",
  "js-sys",
  "num-traits",
+ "time 0.1.45",
  "wasm-bindgen",
- "windows-targets",
+ "winapi",
 ]
 
 [[package]]
@@ -451,20 +450,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb"
 dependencies = [
  "percent-encoding",
- "time",
+ "time 0.3.27",
  "version_check",
 ]
 
-[[package]]
-name = "core-foundation"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
 [[package]]
 name = "core-foundation-sys"
 version = "0.8.4"
@@ -535,9 +524,9 @@ dependencies = [
 
 [[package]]
 name = "ctrlc"
-version = "3.4.1"
+version = "3.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82e95fbd621905b854affdc67943b043a0fbb6ed7385fd5a25650d19a8a6cfdf"
+checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e"
 dependencies = [
  "nix",
  "windows-sys",
@@ -606,23 +595,40 @@ dependencies = [
 ]
 
 [[package]]
-name = "dotenvy"
-version = "0.15.7"
+name = "dotenv"
+version = "0.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
+checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
 
 [[package]]
-name = "dotenvy_macro"
-version = "0.15.7"
+name = "dotenv_codegen"
+version = "0.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb0235d912a8c749f4e0c9f18ca253b4c28cfefc1d2518096016d6e3230b6424"
+checksum = "56966279c10e4f8ee8c22123a15ed74e7c8150b658b26c619c53f4a56eb4a8aa"
 dependencies = [
- "dotenvy",
+ "dotenv_codegen_implementation",
+ "proc-macro-hack",
+]
+
+[[package]]
+name = "dotenv_codegen_implementation"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53e737a3522cd45f6adc19b644ce43ef53e1e9045f2d2de425c1f468abd4cf33"
+dependencies = [
+ "dotenv",
+ "proc-macro-hack",
  "proc-macro2",
  "quote",
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "dotenvy"
+version = "0.15.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
+
 [[package]]
 name = "dyn-clone"
 version = "1.0.13"
@@ -649,9 +655,9 @@ dependencies = [
 
 [[package]]
 name = "env_logger"
-version = "0.10.1"
+version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece"
+checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
 dependencies = [
  "humantime",
  "is-terminal",
@@ -722,12 +728,13 @@ dependencies = [
 
 [[package]]
 name = "flume"
-version = "0.11.0"
+version = "0.10.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"
+checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
 dependencies = [
  "futures-core",
  "futures-sink",
+ "pin-project",
  "spin 0.9.8",
 ]
 
@@ -737,26 +744,11 @@ version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
 
-[[package]]
-name = "foreign-types"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
-dependencies = [
- "foreign-types-shared",
-]
-
-[[package]]
-name = "foreign-types-shared"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
-
 [[package]]
 name = "form_urlencoded"
-version = "1.2.1"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
+checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
 dependencies = [
  "percent-encoding",
 ]
@@ -851,7 +843,7 @@ checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
 dependencies = [
  "cfg-if",
  "libc",
- "wasi",
+ "wasi 0.11.0+wasi-snapshot-preview1",
 ]
 
 [[package]]
@@ -891,7 +883,7 @@ version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
 dependencies = [
- "ahash",
+ "ahash 0.8.3",
  "allocator-api2",
 ]
 
@@ -963,17 +955,6 @@ dependencies = [
  "itoa",
 ]
 
-[[package]]
-name = "http-body"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
-dependencies = [
- "bytes",
- "http",
- "pin-project-lite",
-]
-
 [[package]]
 name = "httparse"
 version = "1.8.0"
@@ -992,43 +973,6 @@ version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
 
-[[package]]
-name = "hyper"
-version = "0.14.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
-dependencies = [
- "bytes",
- "futures-channel",
- "futures-core",
- "futures-util",
- "h2",
- "http",
- "http-body",
- "httparse",
- "httpdate",
- "itoa",
- "pin-project-lite",
- "socket2 0.4.9",
- "tokio",
- "tower-service",
- "tracing",
- "want",
-]
-
-[[package]]
-name = "hyper-tls"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
-dependencies = [
- "bytes",
- "hyper",
- "native-tls",
- "tokio",
- "tokio-native-tls",
-]
-
 [[package]]
 name = "iana-time-zone"
 version = "0.1.57"
@@ -1054,9 +998,9 @@ dependencies = [
 
 [[package]]
 name = "idna"
-version = "0.5.0"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
+checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
 dependencies = [
  "unicode-bidi",
  "unicode-normalization",
@@ -1083,12 +1027,6 @@ dependencies = [
  "serde",
 ]
 
-[[package]]
-name = "ipnet"
-version = "2.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
-
 [[package]]
 name = "is-terminal"
 version = "0.4.9"
@@ -1150,9 +1088,9 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.151"
+version = "0.2.147"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
+checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
 
 [[package]]
 name = "libm"
@@ -1162,9 +1100,9 @@ checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4"
 
 [[package]]
 name = "libsqlite3-sys"
-version = "0.27.0"
+version = "0.26.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716"
+checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326"
 dependencies = [
  "cc",
  "pkg-config",
@@ -1259,43 +1197,26 @@ dependencies = [
 
 [[package]]
 name = "mio"
-version = "0.8.10"
+version = "0.8.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09"
+checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
 dependencies = [
  "libc",
  "log",
- "wasi",
+ "wasi 0.11.0+wasi-snapshot-preview1",
  "windows-sys",
 ]
 
-[[package]]
-name = "native-tls"
-version = "0.2.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
-dependencies = [
- "lazy_static",
- "libc",
- "log",
- "openssl",
- "openssl-probe",
- "openssl-sys",
- "schannel",
- "security-framework",
- "security-framework-sys",
- "tempfile",
-]
-
 [[package]]
 name = "nix"
-version = "0.27.1"
+version = "0.26.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
+checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
 dependencies = [
- "bitflags 2.4.0",
+ "bitflags 1.3.2",
  "cfg-if",
  "libc",
+ "static_assertions",
 ]
 
 [[package]]
@@ -1381,50 +1302,6 @@ version = "1.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
 
-[[package]]
-name = "openssl"
-version = "0.10.57"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c"
-dependencies = [
- "bitflags 2.4.0",
- "cfg-if",
- "foreign-types",
- "libc",
- "once_cell",
- "openssl-macros",
- "openssl-sys",
-]
-
-[[package]]
-name = "openssl-macros"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.32",
-]
-
-[[package]]
-name = "openssl-probe"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
-
-[[package]]
-name = "openssl-sys"
-version = "0.9.93"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d"
-dependencies = [
- "cc",
- "libc",
- "pkg-config",
- "vcpkg",
-]
-
 [[package]]
 name = "parking_lot"
 version = "0.12.1"
@@ -1465,9 +1342,29 @@ dependencies = [
 
 [[package]]
 name = "percent-encoding"
-version = "2.3.1"
+version = "2.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
+checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
+
+[[package]]
+name = "pin-project"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422"
+dependencies = [
+ "pin-project-internal",
+]
+
+[[package]]
+name = "pin-project-internal"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.29",
+]
 
 [[package]]
 name = "pin-project-lite"
@@ -1538,6 +1435,12 @@ dependencies = [
  "version_check",
 ]
 
+[[package]]
+name = "proc-macro-hack"
+version = "0.5.20+deprecated"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
+
 [[package]]
 name = "proc-macro2"
 version = "1.0.66"
@@ -1644,44 +1547,6 @@ version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
 
-[[package]]
-name = "reqwest"
-version = "0.11.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b"
-dependencies = [
- "base64",
- "bytes",
- "encoding_rs",
- "futures-core",
- "futures-util",
- "h2",
- "http",
- "http-body",
- "hyper",
- "hyper-tls",
- "ipnet",
- "js-sys",
- "log",
- "mime",
- "native-tls",
- "once_cell",
- "percent-encoding",
- "pin-project-lite",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "system-configuration",
- "tokio",
- "tokio-native-tls",
- "tower-service",
- "url",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
- "winreg",
-]
-
 [[package]]
 name = "rsa"
 version = "0.9.2"
@@ -1706,9 +1571,9 @@ dependencies = [
 
 [[package]]
 name = "rust-embed"
-version = "8.1.0"
+version = "6.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "810294a8a4a0853d4118e3b94bb079905f2107c7fe979d8f0faae98765eb6378"
+checksum = "a36224c3276f8c4ebc8c20f158eca7ca4359c8db89991c4925132aaaf6702661"
 dependencies = [
  "rust-embed-impl",
  "rust-embed-utils",
@@ -1717,23 +1582,23 @@ dependencies = [
 
 [[package]]
 name = "rust-embed-impl"
-version = "8.1.0"
+version = "6.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfc144a1273124a67b8c1d7cd19f5695d1878b31569c0512f6086f0f4676604e"
+checksum = "49b94b81e5b2c284684141a2fb9e2a31be90638caf040bf9afbc5a0416afe1ac"
 dependencies = [
  "proc-macro2",
  "quote",
  "rust-embed-utils",
  "shellexpand",
- "syn 2.0.32",
+ "syn 2.0.29",
  "walkdir",
 ]
 
 [[package]]
 name = "rust-embed-utils"
-version = "8.1.0"
+version = "7.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "816ccd4875431253d6bb54b804bcff4369cbde9bae33defde25fdf6c2ef91d40"
+checksum = "9d38ff6bf570dc3bb7100fce9f7b60c33fa71d80e88da3f2580df4ff2bdded74"
 dependencies = [
  "sha2",
  "walkdir",
@@ -1782,20 +1647,11 @@ dependencies = [
  "winapi-util",
 ]
 
-[[package]]
-name = "schannel"
-version = "0.1.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88"
-dependencies = [
- "windows-sys",
-]
-
 [[package]]
 name = "schemars"
-version = "0.8.16"
+version = "0.8.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29"
+checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f"
 dependencies = [
  "dyn-clone",
  "schemars_derive",
@@ -1805,9 +1661,9 @@ dependencies = [
 
 [[package]]
 name = "schemars_derive"
-version = "0.8.16"
+version = "0.8.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967"
+checksum = "109da1e6b197438deb6db99952990c7f959572794b80ff93707d55a232545e7c"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1821,29 +1677,6 @@ version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
 
-[[package]]
-name = "security-framework"
-version = "2.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de"
-dependencies = [
- "bitflags 1.3.2",
- "core-foundation",
- "core-foundation-sys",
- "libc",
- "security-framework-sys",
-]
-
-[[package]]
-name = "security-framework-sys"
-version = "2.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
 [[package]]
 name = "semver"
 version = "1.0.18"
@@ -1852,22 +1685,22 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918"
 
 [[package]]
 name = "serde"
-version = "1.0.193"
+version = "1.0.185"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
+checksum = "be9b6f69f1dfd54c3b568ffa45c310d6973a5e5148fd40cf515acaf38cf5bc31"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.193"
+version = "1.0.185"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
+checksum = "dc59dfdcbad1437773485e0367fea4b090a2e0a16d9ffc46af47764536a298ec"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.32",
+ "syn 2.0.29",
 ]
 
 [[package]]
@@ -1883,9 +1716,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.108"
+version = "1.0.105"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
+checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360"
 dependencies = [
  "itoa",
  "ryu",
@@ -1894,9 +1727,9 @@ dependencies = [
 
 [[package]]
 name = "serde_spanned"
-version = "0.6.4"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80"
+checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186"
 dependencies = [
  "serde",
 ]
@@ -1937,9 +1770,9 @@ dependencies = [
 
 [[package]]
 name = "shellexpand"
-version = "3.1.0"
+version = "2.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b"
+checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4"
 dependencies = [
  "dirs",
 ]
@@ -1990,9 +1823,9 @@ dependencies = [
 
 [[package]]
 name = "socket2"
-version = "0.5.5"
+version = "0.5.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
+checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877"
 dependencies = [
  "libc",
  "windows-sys",
@@ -2036,9 +1869,9 @@ dependencies = [
 
 [[package]]
 name = "sqlx"
-version = "0.7.3"
+version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf"
+checksum = "8e58421b6bc416714d5115a2ca953718f6c621a51b68e4f4922aea5a4391a721"
 dependencies = [
  "sqlx-core",
  "sqlx-macros",
@@ -2049,11 +1882,11 @@ dependencies = [
 
 [[package]]
 name = "sqlx-core"
-version = "0.7.3"
+version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd"
+checksum = "dd4cef4251aabbae751a3710927945901ee1d97ee96d757f6880ebb9a79bfd53"
 dependencies = [
- "ahash",
+ "ahash 0.8.3",
  "atoi",
  "byteorder",
  "bytes",
@@ -2089,9 +1922,9 @@ dependencies = [
 
 [[package]]
 name = "sqlx-macros"
-version = "0.7.3"
+version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5"
+checksum = "208e3165167afd7f3881b16c1ef3f2af69fa75980897aac8874a0696516d12c2"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2102,11 +1935,10 @@ dependencies = [
 
 [[package]]
 name = "sqlx-macros-core"
-version = "0.7.3"
+version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841"
+checksum = "8a4a8336d278c62231d87f24e8a7a74898156e34c1c18942857be2acb29c7dfc"
 dependencies = [
- "atomic-write-file",
  "dotenvy",
  "either",
  "heck",
@@ -2129,9 +1961,9 @@ dependencies = [
 
 [[package]]
 name = "sqlx-mysql"
-version = "0.7.3"
+version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4"
+checksum = "8ca69bf415b93b60b80dc8fda3cb4ef52b2336614d8da2de5456cc942a110482"
 dependencies = [
  "atoi",
  "base64",
@@ -2171,9 +2003,9 @@ dependencies = [
 
 [[package]]
 name = "sqlx-postgres"
-version = "0.7.3"
+version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24"
+checksum = "a0db2df1b8731c3651e204629dd55e52adbae0462fa1bdcbed56a2302c18181e"
 dependencies = [
  "atoi",
  "base64",
@@ -2210,9 +2042,9 @@ dependencies = [
 
 [[package]]
 name = "sqlx-sqlite"
-version = "0.7.3"
+version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490"
+checksum = "be4c21bf34c7cae5b283efb3ac1bcc7670df7561124dc2f8bdc0b59be40f79a2"
 dependencies = [
  "atoi",
  "flume",
@@ -2228,9 +2060,14 @@ dependencies = [
  "sqlx-core",
  "tracing",
  "url",
- "urlencoding",
 ]
 
+[[package]]
+name = "static_assertions"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+
 [[package]]
 name = "stringprep"
 version = "0.1.3"
@@ -2260,36 +2097,15 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.32"
+version = "2.0.29"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2"
+checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a"
 dependencies = [
  "proc-macro2",
  "quote",
  "unicode-ident",
 ]
 
-[[package]]
-name = "system-configuration"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
-dependencies = [
- "bitflags 1.3.2",
- "core-foundation",
- "system-configuration-sys",
-]
-
-[[package]]
-name = "system-configuration-sys"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
 [[package]]
 name = "tempfile"
 version = "3.8.0"
@@ -2329,7 +2145,18 @@ checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.32",
+ "syn 2.0.29",
+]
+
+[[package]]
+name = "time"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
+dependencies = [
+ "libc",
+ "wasi 0.10.0+wasi-snapshot-preview1",
+ "winapi",
 ]
 
 [[package]]
@@ -2377,44 +2204,21 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
 
 [[package]]
 name = "tokio"
-version = "1.35.0"
+version = "1.32.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c"
+checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9"
 dependencies = [
  "backtrace",
  "bytes",
  "libc",
  "mio",
- "num_cpus",
  "parking_lot",
  "pin-project-lite",
  "signal-hook-registry",
- "socket2 0.5.5",
- "tokio-macros",
+ "socket2 0.5.3",
  "windows-sys",
 ]
 
-[[package]]
-name = "tokio-macros"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.32",
-]
-
-[[package]]
-name = "tokio-native-tls"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
-dependencies = [
- "native-tls",
- "tokio",
-]
-
 [[package]]
 name = "tokio-stream"
 version = "0.1.14"
@@ -2442,9 +2246,9 @@ dependencies = [
 
 [[package]]
 name = "toml"
-version = "0.8.8"
+version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35"
+checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542"
 dependencies = [
  "serde",
  "serde_spanned",
@@ -2454,18 +2258,18 @@ dependencies = [
 
 [[package]]
 name = "toml_datetime"
-version = "0.6.5"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
+checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
 dependencies = [
  "serde",
 ]
 
 [[package]]
 name = "toml_edit"
-version = "0.21.0"
+version = "0.19.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03"
+checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a"
 dependencies = [
  "indexmap 2.0.0",
  "serde",
@@ -2474,12 +2278,6 @@ dependencies = [
  "winnow",
 ]
 
-[[package]]
-name = "tower-service"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
-
 [[package]]
 name = "tracing"
 version = "0.1.37"
@@ -2501,7 +2299,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.32",
+ "syn 2.0.29",
 ]
 
 [[package]]
@@ -2513,12 +2311,6 @@ dependencies = [
  "once_cell",
 ]
 
-[[package]]
-name = "try-lock"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
-
 [[package]]
 name = "typenum"
 version = "1.16.0"
@@ -2569,26 +2361,20 @@ checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
 
 [[package]]
 name = "url"
-version = "2.5.0"
+version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
+checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
 dependencies = [
  "form_urlencoded",
  "idna",
  "percent-encoding",
 ]
 
-[[package]]
-name = "urlencoding"
-version = "2.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
-
 [[package]]
 name = "utoipa"
-version = "4.1.0"
+version = "3.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ff05e3bac2c9428f57ade702667753ca3f5cf085e2011fe697de5bfd49aa72d"
+checksum = "d82b1bc5417102a73e8464c686eef947bdfb99fcdfc0a4f228e81afa9526470a"
 dependencies = [
  "indexmap 2.0.0",
  "serde",
@@ -2598,22 +2384,22 @@ dependencies = [
 
 [[package]]
 name = "utoipa-gen"
-version = "4.1.0"
+version = "3.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f0b6f4667edd64be0e820d6631a60433a269710b6ee89ac39525b872b76d61d"
+checksum = "05d96dcd6fc96f3df9b3280ef480770af1b7c5d14bc55192baa9b067976d920c"
 dependencies = [
  "proc-macro-error",
  "proc-macro2",
  "quote",
  "regex",
- "syn 2.0.32",
+ "syn 2.0.29",
 ]
 
 [[package]]
 name = "utoipa-swagger-ui"
-version = "5.0.0"
+version = "3.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f839caa8e09dddc3ff1c3112a91ef7da0601075ba5025d9f33ae99c4cb9b6e51"
+checksum = "84614caa239fb25b2bb373a52859ffd94605ceb256eeb1d63436325cf81e3653"
 dependencies = [
  "actix-web",
  "mime_guess",
@@ -2648,13 +2434,10 @@ dependencies = [
 ]
 
 [[package]]
-name = "want"
-version = "0.3.1"
+name = "wasi"
+version = "0.10.0+wasi-snapshot-preview1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
-dependencies = [
- "try-lock",
-]
+checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
 
 [[package]]
 name = "wasi"
@@ -2683,22 +2466,10 @@ dependencies = [
  "once_cell",
  "proc-macro2",
  "quote",
- "syn 2.0.32",
+ "syn 2.0.29",
  "wasm-bindgen-shared",
 ]
 
-[[package]]
-name = "wasm-bindgen-futures"
-version = "0.4.37"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03"
-dependencies = [
- "cfg-if",
- "js-sys",
- "wasm-bindgen",
- "web-sys",
-]
-
 [[package]]
 name = "wasm-bindgen-macro"
 version = "0.2.87"
@@ -2717,7 +2488,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.32",
+ "syn 2.0.29",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
@@ -2728,16 +2499,6 @@ version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
 
-[[package]]
-name = "web-sys"
-version = "0.3.64"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
 [[package]]
 name = "whoami"
 version = "1.4.1"
@@ -2859,36 +2620,6 @@ dependencies = [
  "memchr",
 ]
 
-[[package]]
-name = "winreg"
-version = "0.50.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
-dependencies = [
- "cfg-if",
- "windows-sys",
-]
-
-[[package]]
-name = "zerocopy"
-version = "0.7.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "306dca4455518f1f31635ec308b6b3e4eb1b11758cefafc782827d0aa7acb5c7"
-dependencies = [
- "zerocopy-derive",
-]
-
-[[package]]
-name = "zerocopy-derive"
-version = "0.7.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be912bf68235a88fbefd1b73415cb218405958d1655b2ece9035a19920bdf6ba"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.32",
-]
-
 [[package]]
 name = "zeroize"
 version = "1.6.0"
diff --git a/Cargo.toml b/Cargo.toml
index f901372..4d071ee 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,25 +1,22 @@
 [package]
 name = "chellaris-rust-api"
-version = "1.2.4"
+version = "0.1.0"
 edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-actix-web = "4.4.0"
-chrono = "0.4.31"
-ctrlc = "3.4.1"
-dotenvy = "0.15.7"
-dotenvy_macro = "0.15.7"
-env_logger = "0.10.1"
-reqwest = "0.11.22"
-schemars = "0.8.16"
-serde = { version = "1.0.193", features = ["derive"] }
-serde_json = "1.0.108"
-sqlx = { version = "0.7.3", features = ["postgres", "runtime-tokio"] }
-tokio = { version = "1.35.0", features = ["rt", "rt-multi-thread", "macros", "time"] }
-toml = "0.8.8"
-utoipa = { version = "4.1.0", features = ["actix_extras", "non_strict_integers"] }
-utoipa-swagger-ui = { version = "5.0.0", features = ["actix-web"] }
-rand = "0.8.5"
-url = "2.5.0"
+actix-web = "4.3.1"
+chrono = "0.4.26"
+ctrlc = "3.4.0"
+dotenv = "0.15.0"
+dotenv_codegen = "0.15.0"
+env_logger = "0.10.0"
+schemars = "0.8.10"
+serde = { version = "1.0.185", features = ["derive"] }
+serde_json = "1.0.105"
+sqlx = { version = "0.7.1", features = ["postgres", "runtime-tokio"] }
+tokio = { version = "1.32.0", features = ["rt"] }
+toml = "0.7.6"
+utoipa = { version = "3.5.0", features = ["actix_extras", "non_strict_integers"] }
+utoipa-swagger-ui = { version = "3.1.5", features = ["actix-web"] }
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..2bb8783
--- /dev/null
+++ b/package.json
@@ -0,0 +1,5 @@
+{
+  "dependencies": {
+    "sqlx": "^4.3.2"
+  }
+}
diff --git a/src/db/mod.rs b/src/db/mod.rs
index 0f2302c..7c8e632 100644
--- a/src/db/mod.rs
+++ b/src/db/mod.rs
@@ -1 +1,5 @@
+use std::error::Error;
+
+use sqlx::{Postgres, postgres::PgConnectOptions, PgPool, Pool};
+
 pub(crate) mod schemas;
\ No newline at end of file
diff --git a/src/db/schemas.rs b/src/db/schemas.rs
index 9604b78..88525ad 100644
--- a/src/db/schemas.rs
+++ b/src/db/schemas.rs
@@ -33,7 +33,7 @@ pub struct GameGroup {
 pub struct Ethic {
     pub id: i32,
     pub name: String,
-    pub gestalt_ethic: bool,
+    pub machine_ethic: bool,
 }
 
 #[derive(Serialize, ToSchema, Debug, FromRow)]
@@ -42,15 +42,10 @@ pub struct Empire {
     pub group_id: i32,
     pub game_id: i32,
     pub name: String,
+    pub discord_user: Option<String>,
     pub gestalt: bool,
     pub portrait_id: i32,
     pub portrait_group_id: i32,
-    pub backstory: String,
-    pub goals: String,
-    pub interactions: String,
-    pub available: bool,
-    pub approval_status: Option<bool>,
-    pub users_id: i32,
 }
 
 #[derive(Serialize, ToSchema, Debug, FromRow)]
@@ -60,15 +55,3 @@ pub struct EmpireEthic {
     pub ethics_id: i32,
     pub fanatic: bool,
 }
-
-#[derive(Serialize, ToSchema, Debug, FromRow)]
-pub struct User {
-    pub id: i32,
-    pub token: String,
-    pub discord_id: Option<String>,
-    pub picture_url: Option<String>,
-    pub game_permissions: bool,
-    pub empire_permissions: bool,
-    pub data_permissions: bool,
-    pub user_permissions: bool,
-}
diff --git a/src/main.rs b/src/main.rs
index 6a3a574..d8da6f8 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,24 +1,21 @@
 #[macro_use]
-extern crate dotenvy_macro;
-extern crate dotenvy;
+extern crate dotenv_codegen;
+extern crate dotenv;
 
-use dotenvy::dotenv;
+use dotenv::dotenv;
 use tokio::time::sleep;
 
-use std::{env, fs, net::Ipv4Addr, net::Ipv6Addr, time::Duration, sync::{Arc, atomic::{AtomicBool, Ordering}}};
-use std::process::abort;
+use std::{env, error::Error, fs, net::Ipv4Addr, net::Ipv6Addr, thread, time::Duration, sync::{Mutex, Arc, atomic::{AtomicBool, Ordering}}};
 
 use chrono::Local;
 
-use actix_web::{middleware::Logger, web, App, HttpServer};
+use actix_web::{middleware::Logger, web, App, HttpServer, Result};
 use serde::{Deserialize, Serialize};
 use sqlx::{PgPool, Pool, Postgres, Connection};
-use tokio::signal::unix::SignalKind;
 use utoipa::{OpenApi, openapi::security::{SecurityScheme, ApiKey, ApiKeyValue}, Modify};
 use utoipa_swagger_ui::{Config, SwaggerUi, Url};
 
 mod db;
-mod v1;
 mod v2;
 mod v3;
 
@@ -28,33 +25,21 @@ macro_rules! api_base {
     };
 }
 
-macro_rules! api_base_1 {
-    () => {
-        "/api/v1"
-    };
-}
-
 macro_rules! api_base_2 {
     () => {
-        "/api/v2-l"
+        "/api/v2"
     };
 }
 
 macro_rules! api_base_3 {
     () => {
-        "/api/v3-l"
+        "/api/v3"
     };
 }
 
 #[derive(Serialize, Deserialize, Debug, Clone)]
 pub(crate) struct ConfigToml {
     auth: AuthenticationTokens,
-    port: PortConfig,
-}
-
-#[derive(Serialize, Deserialize, Debug, Clone)]
-pub(crate) struct PortConfig {
-    default: u16,
 }
 
 #[derive(Serialize, Deserialize, Debug, Clone)]
@@ -68,8 +53,11 @@ pub struct AppState {
     auth_tokens: AuthenticationTokens,
 }
 
-async fn postgres_watchdog(pool: PgPool, shutdown: Arc<AtomicBool>) {
-    while !shutdown.load(Ordering::Relaxed) {
+async fn postgres_watchdog(pool: PgPool, is_alive: Arc<AtomicBool>, shutdown: Arc<AtomicBool>) {
+    loop {
+        if shutdown.load(Ordering::Relaxed) {
+            break;
+        }
         let start = Local::now();
 
         let mut conn = match pool.acquire().await {
@@ -82,32 +70,27 @@ async fn postgres_watchdog(pool: PgPool, shutdown: Arc<AtomicBool>) {
             Err(_) => {println!("Error pinging Server"); break;},
         };
 
-        let url = dotenvy::var("UPTIME_KUMA_URL").unwrap_or("".to_string());
-        if url != "" {
-            match reqwest::get(
-                url,
-            ).await {
-                Ok(_) => {}
-                Err(err) => println!("{}", err),
-            };
-        }
-        else {
-            println!("No Uptime Kuma URL provided!");
-        }
+        let passed = (Local::now() - start).to_std().expect(&format!("Unable to get Time Difference for '{}' and '{}'", start, Local::now()));
         
-        while Local::now() - start < chrono::Duration::seconds(15) {
-            sleep(Duration::from_millis(100)).await;
-        }
+        sleep(Duration::from_secs(15) - passed).await;
     }
+    is_alive.store(false, Ordering::Relaxed);
 }
 
 #[actix_web::main]
-async fn main() {
+async fn main() -> Result<()> {
     env_logger::init();
     dotenv().ok();
 
     let shutdown: Arc<AtomicBool> = Arc::new(AtomicBool::new(false));
 
+    let shutdown_clone = Arc::clone(&shutdown);
+    ctrlc::set_handler(move || {
+        eprintln!("Ctrl-C received");
+        shutdown_clone.store(true, Ordering::Relaxed)
+    })
+    .expect("Error setting Ctrl-C handler");
+
     let toml_str = fs::read_to_string("config.toml").expect("Failed to read config.toml");
 
     let config: ConfigToml = toml::from_str(&toml_str).expect("Failed to parse config.toml");
@@ -165,9 +148,7 @@ async fn main() {
             v3::get_empire,
             v3::create_empire,
             v3::edit_empire,
-            v3::delete_empire,
-            v3::get_ethics,
-            v3::get_phenotypes
+            v3::delete_empire
         ), 
         components(schemas(
             v3::schemas::AuthReturn,
@@ -184,17 +165,15 @@ async fn main() {
             v3::schemas::DeleteEmpireParams,
             v3::schemas::FullViewData,
             v3::schemas::Ethic,
-            v3::schemas::ChellarisEthics,
             v3::schemas::EmpireEthic,
             v3::schemas::EmpireEthicLegacy,
             v3::schemas::ChellarisGameLegacy,
             v3::schemas::ChellarisGameFlat,
             v3::schemas::ChellarisGame,
-            v3::schemas::Phenotype,
-            v3::schemas::ChellarisPhenotypes,
+            v3::schemas::Species,
             v3::schemas::ChellarisGameGroupLegacy,
             v3::schemas::ChellarisGroupFlat,
-            v3::schemas::Species,
+            v3::schemas::Portrait,
             v3::schemas::ChellarisEmpireLegacy,
             v3::schemas::ChellarisEmpireFlat,
             v3::schemas::ChellarisEmpire
@@ -203,64 +182,27 @@ async fn main() {
     )]
     struct ApiDocV3;
 
-    #[derive(OpenApi)]
-    #[openapi(
-        paths(
-            v1::get_user,
-            v1::create_user,
-            v1::update_user,
-            v1::delete_user
-        ),
-        components(schemas(
-            v1::schemas::GetUserParams,
-            v1::schemas::UpdateUserParams,
-            v1::schemas::DeleteUserParams,
-            v1::schemas::User
-        ))
-    )]
-    struct ApiDocV1;
-
     let openapi_urls = vec![
-        Url::new("v1", concat!(api_base!(), "-docs/openapi1.json")),
-        Url::new("v2-L", concat!(api_base!(), "-docs/openapi2l.json")),
-        Url::new("v3-L", concat!(api_base!(), "-docs/openapi3l.json")),
+        Url::new("v2", concat!(api_base_2!(), "/openapi.json")),
+        Url::new("v3", concat!(api_base_3!(), "/openapi.json")),
     ];
 
+    let is_alive: Arc<AtomicBool> = Arc::new(AtomicBool::new(true));
+
     loop {
         let db_auth_tokens = config.auth.clone();
         let pool = PgPool::connect(dotenv!("DATABASE_URL")).await.unwrap();
-
         let pool_copy = pool.clone();
-        let shutdown_clone = shutdown.clone();
 
         let swagger_config = Config::new(openapi_urls.clone());
 
-        let mut openapi_v1 = ApiDocV1::openapi();
-        openapi_v1.info.title = "Chellaris Rust API v1".to_string();
+        let mut openapi_v2 = ApiDocV2::openapi();
+        openapi_v2.info.title = "Chellaris Rust API".to_string();
+    
+        let mut openapi_v3 = ApiDocV3::openapi();
+        openapi_v3.info.title = "Chellaris Rust API".to_string();
 
-        let mut openapi_v2_l = ApiDocV2::openapi();
-        openapi_v2_l.info.title = "Legacy Chellaris Rust API v2".to_string();
-
-        let mut openapi_v3_l = ApiDocV3::openapi();
-        openapi_v3_l.info.title = "Legacy Chellaris Rust API v3".to_string();
-
-        println!("Serving API on: ");
-        println!(" -> http://[{}]:{}", Ipv6Addr::UNSPECIFIED, 8080);
-        println!(" -> http://{}:{}", Ipv4Addr::UNSPECIFIED, 8080);
-
-        let watchdog_thread = tokio::spawn(async move { postgres_watchdog(pool_copy, shutdown_clone).await });
-        tokio::spawn(async move {
-            actix_web::rt::signal::unix::signal(SignalKind::terminate()).unwrap().recv().await;
-            println!("SIGTERM received, killing Server");
-            abort()
-        });
-        tokio::spawn(async move {
-            actix_web::rt::signal::unix::signal(SignalKind::interrupt()).unwrap().recv().await;
-            println!("SIGINT received, killing Server");
-            abort()
-        });
-
-        let _ = HttpServer::new(move || {
+        let server = HttpServer::new(move || {
             App::new()
                 .app_data(web::Data::new(AppState { db: pool.clone(), auth_tokens: db_auth_tokens.clone() }))
                 .wrap(Logger::default())
@@ -287,43 +229,56 @@ async fn main() {
                 .service(v3::create_empire)
                 .service(v3::edit_empire)
                 .service(v3::delete_empire)
-                .service(v3::get_ethics)
-                .service(v3::get_phenotypes)
-                // API v1 Endpoints
-                .service(v1::get_user)
-                .service(v1::create_user)
-                .service(v1::update_user)
-                .service(v1::delete_user)
                 // Swagger UI
                 .service(
                     SwaggerUi::new(concat!(api_base!(), "/swagger/{_:.*}"))
                         .urls(vec![
                             (
-                                Url::new("v1", concat!(api_base!(), "-docs/openapi1.json")),
-                                openapi_v1.clone(),
+                                Url::new("v2", concat!(api_base_2!(), "/openapi.json")),
+                                openapi_v2.clone(),
                             ),
                             (
-                                Url::new("v2-l", concat!(api_base!(), "-docs/openapi2l.json")),
-                                openapi_v2_l.clone(),
-                            ),
-                            (
-                                Url::new("v3-l", concat!(api_base!(), "-docs/openapi3l.json")),
-                                openapi_v3_l.clone(),
+                                Url::new("v3", concat!(api_base_3!(), "/openapi.json")),
+                                openapi_v3.clone(),
                             ),
                         ])
                         .config(swagger_config.clone()),
                 )
         })
-            .bind((Ipv6Addr::UNSPECIFIED, config.port.default)).expect("Port or IP already occupied")
-            .run()
-            .await;
+        .bind((Ipv6Addr::UNSPECIFIED, 8080)).expect("Port or IP already occupied")
+        .run();
 
-        watchdog_thread.abort();
+        let server_thread = tokio::spawn(async {
+            println!("Awaiting server");
+            let _ = server.await;
+            println!("Stopped awaiting server");
+        });
 
-        sleep(Duration::from_secs(10)).await;
+        println!("Started Serving API on: ");
+        println!(" -> http://[{}]:{}", Ipv6Addr::UNSPECIFIED, 8080);
+        println!(" -> http://{}:{}", Ipv4Addr::UNSPECIFIED, 8080);
 
-        println!("Service crashed due to unexpected Error, restarting thread after wait...");
+        let is_alive_clone = Arc::clone(&is_alive);
+        let shutdown_clone = Arc::clone(&shutdown);
+        let _ = tokio::spawn(async move { postgres_watchdog(pool_copy, is_alive_clone, shutdown_clone).await });
+        
+        //watchdog_thread.await;
 
-        sleep(Duration::from_secs(10)).await;
+        while is_alive.load(Ordering::Relaxed) {
+            let thread = tokio::spawn(async {
+                sleep(Duration::from_millis(100));
+            });
+
+            let _ = thread.await;
+        }
+
+        if shutdown.load(Ordering::Relaxed) {
+            break;
+        }
+
+        eprintln!("Connection died, restarting Server");
+        server_thread.abort();
     }
+
+    Ok(())
 }
diff --git a/src/v1/mod.rs b/src/v1/mod.rs
deleted file mode 100644
index 4c0fb1b..0000000
--- a/src/v1/mod.rs
+++ /dev/null
@@ -1,369 +0,0 @@
-use crate::{db, AppState};
-use actix_web::{delete, get, post, put, web, HttpRequest, HttpResponse, Responder};
-use std::collections::HashMap;
-use std::ops::Deref;
-use rand::distributions::Alphanumeric;
-use rand::{Rng, thread_rng};
-use sqlx::QueryBuilder;
-
-pub(crate) mod schemas;
-
-fn get_auth_header(req: &HttpRequest) -> Option<&str> {
-    req.headers().get("x-api-key")?.to_str().ok()
-}
-
-async fn verify_user_auth(data: &web::Data<AppState>, auth_token: &str, user_token: &str, table: schemas::TablePermission, permissions_only: bool) -> bool {
-    let user: db::schemas::User = match sqlx::query_as!(
-        db::schemas::User,
-        "SELECT * FROM public.users WHERE token = $1",
-        auth_token
-    )
-        .fetch_one(&data.db)
-        .await
-    {
-        Ok(data) => data,
-        Err(_) => return false,
-    };
-
-    if user.token == user_token && !permissions_only {
-        return true;
-    }
-    else {
-        match table {
-            schemas::TablePermission::Game => {
-                return user.data_permissions;
-            },
-            schemas::TablePermission::Empire => {
-                return user.empire_permissions;
-            },
-            schemas::TablePermission::Data => {
-                return user.data_permissions;
-            },
-            schemas::TablePermission::User => {
-                return user.user_permissions;
-            },
-        }
-    }
-}
-
-// User Endpoints
-#[utoipa::path(
-    request_body = GetUserParams,
-    responses(
-        (status = 200, description = "OK", body = User),
-        (status = 403, description = "Unauthorized"),
-        (status = 500, description = "Internal Server Error")
-    ),
-    security(
-        ("api_key" = [])
-    ),
-)]
-#[post("/api/v1/user")]
-pub(crate) async fn get_user(
-    data: web::Data<AppState>,
-    params: web::Json<schemas::GetUserParams>,
-    req: HttpRequest,
-) -> impl Responder {
-    let auth_header = get_auth_header(&req);
-    let params = params.into_inner();
-
-    let auth_token: String;
-
-    match auth_header {
-        Some(token) => auth_token = token.to_string(),
-        None => return HttpResponse::Unauthorized().finish(),
-    };
-
-    let auth = verify_user_auth(&data, &auth_token, &params.user_token, schemas::TablePermission::User, false).await;
-
-    if auth {
-        let user: db::schemas::User = match sqlx::query_as!(
-        db::schemas::User,
-        "SELECT * FROM public.users WHERE token = $1",
-        params.user_token
-    )
-            .fetch_one(&data.db)
-            .await
-        {
-            Ok(data) => data,
-            Err(_) => return HttpResponse::InternalServerError().finish(),
-        };
-
-        let mut user_permissions: HashMap<String, bool> = HashMap::new();
-
-        user_permissions.insert("game_permissions".to_string(), user.game_permissions);
-        user_permissions.insert("empire_permissions".to_string(), user.empire_permissions);
-        user_permissions.insert("data_permissions".to_string(), user.data_permissions);
-        user_permissions.insert("user_permissions".to_string(), user.user_permissions);
-
-        let return_data = schemas::User {
-            user_token: user.token,
-            discord_handle: user.discord_id,
-            profile_picture: user.picture_url,
-            permissions: user_permissions
-        };
-
-        return HttpResponse::Ok().json(return_data);
-    }
-    else {
-        return HttpResponse::Unauthorized().finish();
-    }
-}
-
-#[utoipa::path(
-    responses(
-        (status = 200, description = "OK", body = User),
-        (status = 500, description = "Internal Server Error")
-    ),
-)]
-#[post("/api/v1/user/create")]
-pub(crate) async fn create_user(
-    data: web::Data<AppState>,
-) -> impl Responder {
-    let user: db::schemas::User;
-
-    let mut rng = thread_rng();
-
-    let user_tokens = match sqlx::query_scalar!(
-        "SELECT token FROM public.users"
-    )
-        .fetch_all(&data.db)
-        .await
-    {
-        Ok(data) => data,
-        Err(_) => return HttpResponse::InternalServerError().finish(),
-    };
-
-    let new_token: String;
-
-    loop {
-        let mut chars: String = (0..6).map(|_| rng.sample(Alphanumeric) as char).collect();
-        chars = chars.to_uppercase();
-        if !user_tokens.contains(&chars) {
-            new_token = chars;
-            break;
-        }
-        else {
-            println!("looping");
-        }
-    }
-
-    user = match sqlx::query_as!(
-        db::schemas::User,
-        "INSERT INTO public.users(token, game_permissions, empire_permissions, data_permissions, user_permissions) VALUES ($1, $2, $3, $4, $5) RETURNING * ",
-        new_token,
-        false,
-        false,
-        false,
-        false
-
-    )
-        .fetch_one(&data.db)
-        .await
-    {
-        Ok(data) => data,
-        Err(_) => return HttpResponse::InternalServerError().finish(),
-    };
-
-    return HttpResponse::Ok().json(user)
-}
-
-#[utoipa::path(
-    request_body = UpdateUserParams,
-    responses(
-        (status = 200, description = "OK"),
-        (status = 403, description = "Unauthorized"),
-        (status = 500, description = "Internal Server Error")
-    ),
-    security(
-        ("api_key" = [])
-    ),
-)]
-#[put("/api/v1/user")]
-pub(crate) async fn update_user(
-    data: web::Data<AppState>,
-    params: web::Json<schemas::UpdateUserParams>,
-    req: HttpRequest,
-) -> impl Responder {
-    let auth_header = get_auth_header(&req);
-    let params = params.into_inner();
-
-    let auth_token: String;
-
-    match auth_header {
-        Some(token) => auth_token = token.to_string(),
-        None => return HttpResponse::Unauthorized().finish(),
-    };
-
-    let mut user_permissions: HashMap<String, bool> = HashMap::new();
-    match params.permissions {
-        Some(data) => {user_permissions = data.clone()},
-        None => {},
-    }
-
-    let mut elevated_auth = false;
-    if user_permissions.len() != 0 {
-        if user_permissions["game_permissions"] || user_permissions["empire_permissions"] || user_permissions["data_permissions"] || user_permissions["user_permissions"] {
-            elevated_auth = true;
-        }
-    }
-
-    let auth = verify_user_auth(&data, &auth_token, &params.user_token, schemas::TablePermission::User, elevated_auth).await;
-
-    // SQL Queries
-    // TODO: Optimize by utilizing some SQL magic, for now this has to do
-    if auth {
-        let user: db::schemas::User;
-
-        let mut user_query = QueryBuilder::<sqlx::Postgres>::new("UPDATE public.users SET ");
-        let mut user_query_separated = user_query.separated(", ");
-        let mut any_param_present = false;
-
-        if let Some(discord_handle) = params.discord_handle {
-            user_query_separated.push(" discord_id = ").push_bind_unseparated(discord_handle);
-            any_param_present = true;
-        }
-
-        if let Some(profile_picture) = params.profile_picture {
-            user_query_separated.push(" picture_url = ");
-            match any_param_present {
-                true => user_query_separated.push_bind(profile_picture),
-                false => user_query_separated.push_bind_unseparated(profile_picture)
-            };
-            any_param_present = true;
-        }
-
-        if user_permissions.len() != 0 {
-            for (entry, value) in user_permissions.iter() {
-                match entry.deref() {
-                    "game_permissions" => {
-                        user_query_separated.push( " game_permissions = ");
-                        match any_param_present {
-                            true => user_query_separated.push_bind(value),
-                            false => user_query_separated.push_bind_unseparated(value)
-                        };
-                        any_param_present = true;
-                    },
-                    "empire_permissions" => {
-                        user_query_separated.push( " empire_permissions = ");
-                        match any_param_present {
-                            true => user_query_separated.push_bind(value),
-                            false => user_query_separated.push_bind_unseparated(value)
-                        };
-                        any_param_present = true;
-                    },
-                    "data_permissions" => {
-                        user_query_separated.push( " data_permissions = ");
-                        match any_param_present {
-                            true => user_query_separated.push_bind(value),
-                            false => user_query_separated.push_bind_unseparated(value)
-                        };
-                        any_param_present = true;
-                    },
-                    "user_permissions" => {
-                        user_query_separated.push( " user_permissions = ");
-                        match any_param_present {
-                            true => user_query_separated.push_bind(value),
-                            false => user_query_separated.push_bind_unseparated(value)
-                        };
-                        any_param_present = true;
-                    },
-                    _ => {}
-                }
-            }
-        }
-
-        if any_param_present {
-            user_query_separated.push_unseparated(" WHERE token = ").push_bind_unseparated(params.user_token);
-            user_query_separated.push_unseparated(" RETURNING *");
-
-            user = match user_query
-                .build_query_as::<db::schemas::User>()
-                .fetch_one(&data.db)
-                .await
-            {
-                Ok(data) => data,
-                Err(_) => return HttpResponse::InternalServerError().finish(),
-            };
-        } else {
-            user = match sqlx::query_as!(
-                db::schemas::User,
-                "SELECT * FROM public.users WHERE token = $1",
-                params.user_token
-            )
-                .fetch_one(&data.db)
-                .await
-            {
-                Ok(data) => data,
-                Err(_) => return HttpResponse::InternalServerError().finish(),
-            };
-        }
-
-        let mut user_permissions: HashMap<String, bool> = HashMap::new();
-        user_permissions.insert("game_permissions".to_string(), user.game_permissions);
-        user_permissions.insert("empire_permissions".to_string(), user.empire_permissions);
-        user_permissions.insert("data_permissions".to_string(), user.data_permissions);
-        user_permissions.insert("user_permissions".to_string(), user.user_permissions);
-
-        let return_data = schemas::User {
-            user_token: user.token,
-            discord_handle: user.discord_id,
-            profile_picture: user.picture_url,
-            permissions: user_permissions
-        };
-        return HttpResponse::Ok().json(return_data);
-    } else {
-        return HttpResponse::Unauthorized().finish();
-    }
-}
-
-#[utoipa::path(
-    request_body = DeleteUserParams,
-    responses(
-        (status = 200, description = "OK"),
-        (status = 403, description = "Unauthorized"),
-        (status = 500, description = "Internal Server Error")
-    ),
-    security(
-        ("api_key" = [])
-    ),
-)]
-#[delete("/api/v1/user")]
-pub(crate) async fn delete_user(
-    data: web::Data<AppState>,
-    params: web::Query<schemas::DeleteUserParams>,
-    req: HttpRequest,
-) -> impl Responder {
-    let auth_header = get_auth_header(&req);
-    let params = params.into_inner();
-
-    let auth_token: String;
-
-    match auth_header {
-        Some(token) => auth_token = token.to_string(),
-        None => return HttpResponse::Unauthorized().finish(),
-    };
-
-    let auth = verify_user_auth(&data, &auth_token, &params.user_token, schemas::TablePermission::User, false).await;
-
-    // SQL Queries
-    // TODO: Optimize by utilizing some SQL magic, for now this has to do
-    if auth {
-        match sqlx::query!(
-            "DELETE FROM public.users WHERE token = $1",
-            params.user_token
-        )
-            .execute(&data.db)
-            .await
-        {
-            Ok(_) => {}
-            Err(_) => {
-                return HttpResponse::InternalServerError().finish();
-            }
-        };
-
-        return HttpResponse::Ok().into();
-    } else {
-        return HttpResponse::Unauthorized().finish();
-    }
-}
diff --git a/src/v1/schemas.rs b/src/v1/schemas.rs
deleted file mode 100644
index 81c23c3..0000000
--- a/src/v1/schemas.rs
+++ /dev/null
@@ -1,64 +0,0 @@
-use std::collections::HashMap;
-use serde::{Deserialize, Serialize};
-use utoipa::{IntoParams, ToSchema};
-
-// DB Permission Enums
-
-pub enum TablePermission {
-    Game,
-    Empire,
-    Data,
-    User
-}
-
-// User Structs
-
-#[derive(Serialize, ToSchema, Debug)]
-pub struct User {
-    #[schema(example = "abcdef")]
-    pub user_token: String,
-    #[schema(example = "discorduser")]
-    pub discord_handle: Option<String>,
-    #[schema(example = "/assets/avatars/124677612.png")]
-    pub profile_picture: Option<String>,
-    #[schema(example = "\
-    {\
-        [\"game_permissions\"]: true,
-        [\"empire_permissions\"]: true,
-        [\"data_permissions\"]: false,
-        [\"user_permissions\"]: false,
-    }\
-    ")]
-    pub permissions: HashMap<String, bool>,
-}
-
-#[derive(Serialize, Deserialize, ToSchema, Debug)]
-pub struct GetUserParams {
-    #[schema(example = "abcdef")]
-    pub user_token: String,
-}
-
-#[derive(Serialize, Deserialize, ToSchema, Debug)]
-pub struct UpdateUserParams {
-    #[schema(example = "abcdef")]
-    pub user_token: String,
-    #[schema(example = "discorduser")]
-    pub discord_handle: Option<String>,
-    #[schema(example = "/assets/avatars/124677612.png")]
-    pub profile_picture: Option<String>,
-    #[schema(example = "\
-    {\
-        [\"game_permissions\"]: true,
-        [\"empire_permissions\"]: true,
-        [\"data_permissions\"]: false,
-        [\"user_permissions\"]: false,
-    }\
-    ")]
-    pub permissions: Option<HashMap<String, bool>>,
-}
-
-#[derive(Serialize, Deserialize, ToSchema, Debug)]
-pub struct DeleteUserParams {
-    #[schema(example = "abcdef")]
-    pub user_token: String,
-}
\ No newline at end of file
diff --git a/src/v2/mod.rs b/src/v2/mod.rs
index 1f1f07a..9f37731 100644
--- a/src/v2/mod.rs
+++ b/src/v2/mod.rs
@@ -78,7 +78,7 @@ pub(crate) async fn empires(
 
         if let Some(auth_token) = params.token.clone() {
             if  auth_token == data.auth_tokens.admin || auth_token == data.auth_tokens.moderator {
-                new_data.discord_user = Some("deprecated".to_string());
+                new_data.discord_user = entry.discord_user.clone();
             }
         }
 
@@ -112,7 +112,7 @@ pub(crate) async fn ethics(
     db_data.iter().for_each(|entry| {
         let new_data = schemas::Ethic {
             id: entry.id,
-            gestalt_ethic: entry.gestalt_ethic,
+            machine_ethic: entry.machine_ethic,
             name: entry.name.clone()
         };
 
diff --git a/src/v2/schemas.rs b/src/v2/schemas.rs
index 69897e0..e575885 100644
--- a/src/v2/schemas.rs
+++ b/src/v2/schemas.rs
@@ -38,7 +38,7 @@ pub struct GameGroup {
 pub struct Ethic {
     pub id: i32,
     pub name: String,
-    pub gestalt_ethic: bool,
+    pub machine_ethic: bool,
 }
 
 #[derive(Serialize, ToSchema, Debug, FromRow)]
diff --git a/src/v3/mod.rs b/src/v3/mod.rs
index f1c414c..980e772 100644
--- a/src/v3/mod.rs
+++ b/src/v3/mod.rs
@@ -5,11 +5,12 @@ use actix_web::{
     web::{self, Json},
     HttpRequest, HttpResponse, Responder,
 };
-use sqlx::QueryBuilder;
+use sqlx::{Execute, QueryBuilder};
 
-use dotenvy;
-
-use crate::{db, AppState};
+use crate::{
+    db::{self, schemas::EmpireEthic},
+    AppState,
+};
 
 pub(crate) mod schemas;
 
@@ -31,7 +32,7 @@ fn verify_auth(token: Option<&str>, data: &AppState) -> schemas::AuthReturn {
     return auth_return;
 }
 
-fn get_auth_header(req: &HttpRequest) -> Option<&str> {
+fn get_auth_header<'a>(req: &'a HttpRequest) -> Option<&'a str> {
     req.headers().get("x-api-key")?.to_str().ok()
 }
 
@@ -109,37 +110,37 @@ pub(crate) async fn full_view_data(data: web::Data<AppState>) -> impl Responder
     let mut parsed_data: schemas::FullViewData = schemas::FullViewData {
         games: HashMap::new(),
         ethics: HashMap::new(),
-        phenotypes: HashMap::new(),
+        species: HashMap::new(),
     };
 
     // Data processing
     // Species Vector
     db_portrait_groups.iter().for_each(|species| {
-        let new_data = schemas::Phenotype {
+        let new_data = schemas::Species {
             id: species.id,
             display: species.name.clone(),
-            species: HashMap::new(),
+            portraits: HashMap::new(),
         };
 
         parsed_data
-            .phenotypes
+            .species
             .entry(species.id)
             .and_modify(|d| *d = new_data.clone())
             .or_insert(new_data);
     });
 
     db_portraits.iter().for_each(|portrait| {
-        let new_data = schemas::Species {
+        let new_data = schemas::Portrait {
             id: portrait.id,
             hires: portrait.hires.clone(),
-            lores: portrait.lores.clone(),
+            lores: Some(portrait.lores.clone()),
         };
 
         parsed_data
-            .phenotypes
+            .species
             .get_mut(&portrait.group_id)
             .unwrap()
-            .species
+            .portraits
             .entry(portrait.id)
             .and_modify(|d| *d = new_data.clone())
             .or_insert(new_data);
@@ -181,10 +182,10 @@ pub(crate) async fn full_view_data(data: web::Data<AppState>) -> impl Responder
         let new_data = schemas::ChellarisEmpireLegacy {
             id: empire.id,
             gestalt: empire.gestalt,
-            machine: empire.portrait_group_id.to_string() == dotenvy::var("MACHINE_GROUP_ID").unwrap_or("12".to_string()),
+            machine: false,
             group: empire.group_id,
-            portrait_id: empire.portrait_id,
-            portrait_group_id: empire.portrait_group_id,
+            empire_portrait: empire.portrait_id,
+            empire_portrait_group: empire.portrait_group_id,
             discord_user: None,
             ethics: HashMap::new(),
         };
@@ -204,7 +205,7 @@ pub(crate) async fn full_view_data(data: web::Data<AppState>) -> impl Responder
         let new_data = schemas::Ethic {
             id: ethic.id,
             display: ethic.name.clone(),
-            gestalt: ethic.gestalt_ethic,
+            machine: ethic.machine_ethic,
         };
 
         parsed_data
@@ -219,13 +220,13 @@ pub(crate) async fn full_view_data(data: web::Data<AppState>) -> impl Responder
         let id = empire_ethic.empire_id;
 
         let new_data = schemas::EmpireEthicLegacy {
-            ethic_id: empire_ethic.ethics_id,
+            id: empire_ethic.ethics_id,
             display: parsed_data.ethics[&empire_ethic.ethics_id].display.clone(),
-            gestalt: parsed_data.ethics[&empire_ethic.ethics_id].gestalt,
+            machine: parsed_data.ethics[&empire_ethic.ethics_id].machine,
             fanatic: empire_ethic.fanatic,
         };
 
-        if new_data.gestalt {
+        if new_data.machine {
             parsed_data
                 .games
                 .get_mut(&game_id)
@@ -233,7 +234,7 @@ pub(crate) async fn full_view_data(data: web::Data<AppState>) -> impl Responder
                 .empires
                 .get_mut(&id)
                 .unwrap()
-                .gestalt = true;
+                .machine = true;
         }
 
         parsed_data
@@ -367,7 +368,7 @@ pub(crate) async fn get_game_data(
                 "[REDACTED]".to_string()
             },
             discord_user: if user_auth.moderator || user_auth.admin {
-                Some("deprecated".to_string())
+                empire.discord_user.clone()
             } else {
                 None
             },
@@ -807,8 +808,7 @@ pub(crate) async fn get_empire(
             group: db_empire.group_id,
             game: db_empire.game_id,
             name: db_empire.name,
-            discord_user: Some("deprecated".to_string()),
-            machine: db_empire.portrait_group_id.to_string() == dotenvy::var("MACHINE_GROUP_ID").unwrap_or("12".to_string()),
+            discord_user: db_empire.discord_user,
             gestalt: db_empire.gestalt,
             portrait_id: db_empire.portrait_id,
             portrait_group_id: db_empire.portrait_group_id,
@@ -941,8 +941,7 @@ pub(crate) async fn create_empire(
                 group: db_empire.group_id,
                 game: db_empire.game_id,
                 name: db_empire.name,
-                discord_user: Some("deprecated".to_string()),
-                machine: db_empire.portrait_group_id.to_string() == dotenvy::var("MACHINE_GROUP_ID").unwrap_or("12".to_string()),
+                discord_user: db_empire.discord_user,
                 gestalt: db_empire.gestalt,
                 portrait_id: db_empire.portrait_id,
                 portrait_group_id: db_empire.portrait_group_id,
@@ -988,10 +987,12 @@ pub(crate) async fn edit_empire(
         let mut db_empire_query = QueryBuilder::<sqlx::Postgres>::new("UPDATE public.empires SET ");
         let mut db_empire_separated = db_empire_query.separated(", ");
 
-        // More often than not does nothing but is required to ensure data is handled properly
-        db_empire_separated
-            .push(" game_id = ")
-            .push_bind_unseparated(params.game_id);
+        if let Some(new_game) = params.game_id {
+            any_param_present = true;
+            db_empire_separated
+                .push(" game_id = ")
+                .push_bind_unseparated(new_game);
+        }
 
         if let Some(new_group) = params.group_id {
             any_param_present = true;
@@ -1037,12 +1038,6 @@ pub(crate) async fn edit_empire(
                     .push(" discord_user = ")
                     .push_bind_unseparated(new_discord_user);
             }
-            else {
-                any_param_present = true;
-                let val: Option<String> = None;
-                db_empire_separated
-                    .push(" discord_user = ").push_bind_unseparated(val);
-            }
         }
 
         let db_empire: db::schemas::Empire;
@@ -1051,6 +1046,9 @@ pub(crate) async fn edit_empire(
             db_empire_separated
                 .push_unseparated(" WHERE id = ")
                 .push_bind_unseparated(params.empire_id);
+            db_empire_separated
+                .push_unseparated(" AND group_id = ")
+                .push_bind_unseparated(params.group_id);
             db_empire_separated
                 .push_unseparated(" AND game_id = ")
                 .push_bind_unseparated(params.game_id);
@@ -1073,6 +1071,9 @@ pub(crate) async fn edit_empire(
             db_empire_separated
                 .push_unseparated(" WHERE id = ")
                 .push_bind_unseparated(params.empire_id);
+            db_empire_separated
+                .push_unseparated(" AND group_id = ")
+                .push_bind_unseparated(params.group_id);
             db_empire_separated
                 .push_unseparated(" AND game_id = ")
                 .push_bind_unseparated(params.game_id);
@@ -1174,8 +1175,7 @@ pub(crate) async fn edit_empire(
                 group: db_empire.group_id,
                 game: db_empire.game_id,
                 name: db_empire.name,
-                discord_user: Some("deprecated".to_string()),
-                machine: db_empire.portrait_group_id.to_string() == dotenvy::var("MACHINE_GROUP_ID").unwrap_or("12".to_string()),
+                discord_user: db_empire.discord_user,
                 gestalt: db_empire.gestalt,
                 portrait_id: db_empire.portrait_id,
                 portrait_group_id: db_empire.portrait_group_id,
@@ -1235,110 +1235,9 @@ pub(crate) async fn delete_empire(
     }
 }
 
-// Ethics Endpoints
-// Data Manipulation Admin Only
+// Data Manipulation Endpoints
 
-#[utoipa::path(
-    responses(
-        (status = 200, description = "OK", body = ChellarisEthics),
-    ),
-)]
-#[get("/api/v3/ethics")]
-pub(crate) async fn get_ethics(data: web::Data<AppState>) -> impl Responder {
-    // SQL Queries
-    // TODO: Optimize by utilizing some SQL magic, for now this has to do
-    let mut db_ethics: HashMap<i32, schemas::Ethic> = HashMap::new();
-
-    let mut db_ethic_query = QueryBuilder::<sqlx::Postgres>::new("SELECT * FROM public.ethics");
-
-    match db_ethic_query
-        .build_query_as::<db::schemas::Ethic>()
-        .fetch_all(&data.db)
-        .await
-    {
-        Ok(data) => {
-            for ethic in data {
-                db_ethics.insert(
-                    ethic.id,
-                    schemas::Ethic {
-                        id: ethic.id,
-                        gestalt: ethic.gestalt_ethic,
-                        display: ethic.name,
-                    },
-                );
-            }
-        }
-        Err(e) => return HttpResponse::UnprocessableEntity().body(format!("{:#?}", e.to_string())),
-    };
-
-    // Empire Ethic Creation
-    let parsed_data: schemas::ChellarisEthics = schemas::ChellarisEthics { ethics: db_ethics };
-
-    return HttpResponse::Ok().json(parsed_data);
-}
-
-// Species & Portrait Endpoints
-// Data Manipulation Admin Only
-
-#[utoipa::path(
-    responses(
-        (status = 200, description = "OK", body = ChellarisPhenotypes),
-    ),
-)]
-#[get("/api/v3/phenotypes")]
-pub(crate) async fn get_phenotypes(data: web::Data<AppState>) -> impl Responder {
-    // SQL Queries
-    // TODO: Optimize by utilizing some SQL magic, for now this has to do
-    let mut db_phenotypes: HashMap<i32, schemas::Phenotype> = HashMap::new();
-
-    let mut db_phenotype_query = QueryBuilder::<sqlx::Postgres>::new("SELECT * FROM public.portrait_groups");
-
-    match db_phenotype_query
-        .build_query_as::<db::schemas::PortraitGroup>()
-        .fetch_all(&data.db)
-        .await
-    {
-        Ok(data) => {
-            for phenotype in data {
-                db_phenotypes.insert(
-                    phenotype.id,
-                    schemas::Phenotype {
-                        id: phenotype.id,
-                        display: phenotype.name,
-                        species: HashMap::new(),
-                    },
-                );
-            }
-        }
-        Err(e) => return HttpResponse::UnprocessableEntity().body(format!("{:#?}", e.to_string())),
-    };
-
-    let mut db_species_query = QueryBuilder::<sqlx::Postgres>::new("SELECT * FROM public.portraits");
-
-    match db_species_query
-        .build_query_as::<db::schemas::Portrait>()
-        .fetch_all(&data.db)
-        .await
-    {
-        Ok(data) => {
-            for species in data {
-                if let Some(phenotype) = db_phenotypes.get_mut(&species.group_id) {
-                    phenotype.species.insert(
-                        species.id,
-                        schemas::Species {
-                            id: species.id,
-                            hires: species.hires,
-                            lores: species.lores
-                        }
-                    );
-                }
-            }
-        }
-        Err(e) => return HttpResponse::UnprocessableEntity().body(format!("{:#?}", e.to_string())),
-    };
-
-    // Empire Ethic Creation
-    let parsed_data: schemas::ChellarisPhenotypes = schemas::ChellarisPhenotypes { phenotypes: db_phenotypes };
-
-    return HttpResponse::Ok().json(parsed_data);
-}
+// Admin
+// Add/Update/Remove Portrait
+// Add/Update/Remove Species
+// Add/Update/Remove Ethics
diff --git a/src/v3/schemas.rs b/src/v3/schemas.rs
index 709a7b2..2a25b96 100644
--- a/src/v3/schemas.rs
+++ b/src/v3/schemas.rs
@@ -43,7 +43,7 @@ pub struct DeleteGameParam {
 pub struct FullViewData {
     pub games: HashMap<i32, ChellarisGameLegacy>,
     pub ethics: HashMap<i32, Ethic>,
-    pub phenotypes: HashMap<i32, Phenotype>,
+    pub species: HashMap<i32, Species>,
 }
 
 #[derive(Serialize, ToSchema, Debug, Clone)]
@@ -147,7 +147,7 @@ pub struct UpdateEmpireParams {
     #[schema(example = 1)]
     pub empire_id: i32,
     #[schema(example = 1)]
-    pub game_id: i32,
+    pub game_id: Option<i32>,
     #[schema(example = 1)]
     pub group_id: Option<i32>,
     #[schema(example = "Example Empire")]
@@ -195,7 +195,6 @@ pub struct ChellarisEmpire {
     pub game: i32,
     pub name: String,
     pub discord_user: Option<String>,
-    pub machine: bool,
     pub gestalt: bool,
     pub portrait_id: i32,
     pub portrait_group_id: i32,
@@ -208,19 +207,17 @@ pub struct ChellarisEmpireLegacy {
     pub group: i32,
     pub gestalt: bool,
     pub machine: bool,
-    pub portrait_id: i32,
-    pub portrait_group_id: i32,
+    pub empire_portrait: i32,
+    pub empire_portrait_group: i32,
     pub discord_user: Option<String>,
     pub ethics: HashMap<i32, EmpireEthicLegacy>,
 }
 
-// Ethics Structs
-
 #[derive(Serialize, ToSchema, Debug, Clone)]
 pub struct Ethic {
     pub id: i32,
     pub display: String,
-    pub gestalt: bool,
+    pub machine: bool,
 }
 
 #[derive(Serialize, Deserialize, ToSchema, Debug, Clone)]
@@ -233,35 +230,23 @@ pub struct EmpireEthic {
 
 #[derive(Serialize, ToSchema, Debug, Clone)]
 pub struct EmpireEthicLegacy {
-    pub ethic_id: i32,
-    pub display: String,
-    pub gestalt: bool,
-    pub fanatic: bool,
-}
-
-#[derive(Serialize, ToSchema, Debug, Clone)]
-pub struct ChellarisEthics {
-    pub ethics: HashMap<i32, Ethic>,
-}
-
-// Species Structs
-
-#[derive(Serialize, ToSchema, Debug, Clone)]
-pub struct Phenotype {
     pub id: i32,
     pub display: String,
-    pub species: HashMap<i32, Species>,
-}
-
-#[derive(Serialize, ToSchema, Debug, Clone)]
-pub struct ChellarisPhenotypes {
-    pub phenotypes: HashMap<i32, Phenotype>
+    pub machine: bool,
+    pub fanatic: bool,
 }
 
 #[derive(Serialize, ToSchema, Debug, Clone)]
 pub struct Species {
     pub id: i32,
-    pub hires: String,
-    pub lores: String,
+    pub display: String,
+    pub portraits: HashMap<i32, Portrait>,
+}
+
+#[derive(Serialize, ToSchema, Debug, Clone)]
+pub struct Portrait {
+    pub id: i32,
+    pub hires: String,
+    pub lores: Option<String>,
 }
 
diff --git a/yarn.lock b/yarn.lock
new file mode 100644
index 0000000..a2e0510
--- /dev/null
+++ b/yarn.lock
@@ -0,0 +1,314 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+ajv@^6.1.1:
+  version "6.12.6"
+  resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
+  integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
+  dependencies:
+    fast-deep-equal "^3.1.1"
+    fast-json-stable-stringify "^2.0.0"
+    json-schema-traverse "^0.4.1"
+    uri-js "^4.2.2"
+
+async@^2.0.1:
+  version "2.6.4"
+  resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
+  integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==
+  dependencies:
+    lodash "^4.17.14"
+
+bignumber.js@9.0.0:
+  version "9.0.0"
+  resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075"
+  integrity sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==
+
+bson@~1.0.4:
+  version "1.0.9"
+  resolved "https://registry.yarnpkg.com/bson/-/bson-1.0.9.tgz#12319f8323b1254739b7c6bef8d3e89ae05a2f57"
+  integrity sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg==
+
+buffer-shims@~1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51"
+  integrity sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g==
+
+core-util-is@~1.0.0:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
+  integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
+
+debug@*:
+  version "4.3.4"
+  resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
+  integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
+  dependencies:
+    ms "2.1.2"
+
+debug@^2.2.0:
+  version "2.6.9"
+  resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
+  integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
+  dependencies:
+    ms "2.0.0"
+
+double-ended-queue@^2.1.0-0:
+  version "2.1.0-0"
+  resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c"
+  integrity sha512-+BNfZ+deCo8hMNpDqDnvT+c0XpJ5cUa6mqYq89bho2Ifze4URTqRkcwR399hWoTrTkbZ/XJYDgP6rc7pRgffEQ==
+
+es6-promise@3.2.1:
+  version "3.2.1"
+  resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.2.1.tgz#ec56233868032909207170c39448e24449dd1fc4"
+  integrity sha512-oj4jOSXvWglTsc3wrw86iom3LDPOx1nbipQk+jaG3dy+sMRM6ReSgVr/VlmBuF6lXUrflN9DCcQHeSbAwGUl4g==
+
+fast-deep-equal@^3.1.1:
+  version "3.1.3"
+  resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
+  integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
+
+fast-json-stable-stringify@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
+  integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
+
+inherits@~2.0.1, inherits@~2.0.3:
+  version "2.0.4"
+  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
+  integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
+
+isarray@~1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
+  integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
+
+json-schema-traverse@^0.4.1:
+  version "0.4.1"
+  resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
+  integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
+
+lodash@^4.17.14, lodash@^4.17.4:
+  version "4.17.21"
+  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
+  integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
+
+mongo-sql@^2.7.5:
+  version "2.7.8"
+  resolved "https://registry.yarnpkg.com/mongo-sql/-/mongo-sql-2.7.8.tgz#f50184aaadc1be530db69e301ba35b01afd402d9"
+  integrity sha512-fJ4Tsn/G5QimXPRyoT0tnDhYdrPa/UJZY6FCJ4e9CYZgYH84w1qQrlednrpqgD9qK0oXtrLv78j1V+I5Yt/a6A==
+
+mongodb-core@2.1.20:
+  version "2.1.20"
+  resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-2.1.20.tgz#fece8dd76b59ee7d7f2d313b65322c160492d8f1"
+  integrity sha512-IN57CX5/Q1bhDq6ShAR6gIv4koFsZP7L8WOK1S0lR0pVDQaScffSMV5jxubLsmZ7J+UdqmykKw4r9hG3XQEGgQ==
+  dependencies:
+    bson "~1.0.4"
+    require_optional "~1.0.0"
+
+mongodb@^2.1.18:
+  version "2.2.36"
+  resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-2.2.36.tgz#1c573680b2849fb0f47acbba3dc5fa228de975f5"
+  integrity sha512-P2SBLQ8Z0PVx71ngoXwo12+FiSfbNfGOClAao03/bant5DgLNkOPAck5IaJcEk4gKlQhDEURzfR3xuBG1/B+IA==
+  dependencies:
+    es6-promise "3.2.1"
+    mongodb-core "2.1.20"
+    readable-stream "2.2.7"
+
+monk-middleware-cast-ids@^0.2.1:
+  version "0.2.1"
+  resolved "https://registry.yarnpkg.com/monk-middleware-cast-ids/-/monk-middleware-cast-ids-0.2.1.tgz#40c40e5a6cb33ccedc289220943275ee8861c529"
+  integrity sha512-Hp9gwjXo+inSPhXUlsV1u3DyZh2cXT3Osij/1gSNCJQCgacAF1lfmnTj6bKmlf1Et4dvLhwUL0PquxdZRIofkA==
+
+monk-middleware-fields@^0.2.0:
+  version "0.2.0"
+  resolved "https://registry.yarnpkg.com/monk-middleware-fields/-/monk-middleware-fields-0.2.0.tgz#ff637af35f5948879ccb2be15a91360911bea6c1"
+  integrity sha512-pp+k0JeBX+HkIKnCisrtsW/QM2WGkOVG1Bd1qKLSanuBCf1l5khpdHrEullfko0HO6tCjCJMp//MsR16gd5tAw==
+
+monk-middleware-handle-callback@^0.2.0:
+  version "0.2.2"
+  resolved "https://registry.yarnpkg.com/monk-middleware-handle-callback/-/monk-middleware-handle-callback-0.2.2.tgz#47de6cc1248726c72a2be0c81bc4e68310c32146"
+  integrity sha512-5hBynb7asZ2uw9XVze7C3XH0zXT51yFDvYydk/5HnWWzh2NLglDSiKDcX0yLKPHzFgiq+5Z4Laq5fFVnFsmm8w==
+
+monk-middleware-options@^0.2.1:
+  version "0.2.1"
+  resolved "https://registry.yarnpkg.com/monk-middleware-options/-/monk-middleware-options-0.2.1.tgz#58dae1c518d46636ebdff506fadfc773bb442886"
+  integrity sha512-ypE0wGC8n5ARvOq2tlERr1uyu1edckeDRkheQLaXPRm9LoW7kr9P7xMGEjW2vmBh7IxnkpONVc7555X8x+34hQ==
+
+monk-middleware-query@^0.2.0:
+  version "0.2.0"
+  resolved "https://registry.yarnpkg.com/monk-middleware-query/-/monk-middleware-query-0.2.0.tgz#a926c677d4a5620c62151b0a56d0c0c151675874"
+  integrity sha512-BApd5HBiczJl1eVy65c9/NBVLtygBePFxuoHgar/LeMWCjWP9odSJk3vsnbxTnsOT1CMJ+hFysbaosLzDsxvtA==
+
+monk-middleware-wait-for-connection@^0.2.0:
+  version "0.2.0"
+  resolved "https://registry.yarnpkg.com/monk-middleware-wait-for-connection/-/monk-middleware-wait-for-connection-0.2.0.tgz#312958d30e588b57d09754dd7c97b4843316835a"
+  integrity sha512-jSTz73B/+pGTTvhu5Ym8xsG6+QqaWab53UXnXdNNlTijTdLvcHABCLJXudQiJxob5N1Mzr5EOSx5ziwn2sihPQ==
+
+monk@^6.0.5:
+  version "6.0.6"
+  resolved "https://registry.yarnpkg.com/monk/-/monk-6.0.6.tgz#2ff1cd57f001bba0fea73d1eea3952a7d35450c5"
+  integrity sha512-bSuADQGwIxBcRzCzQaMoGmiGl30Dr+0iB1FQAQb3VwWwAKbtpDN2wkVHCjthzw/jXhPHWxTQFUtlSt/nSagojQ==
+  dependencies:
+    debug "*"
+    mongodb "^2.1.18"
+    monk-middleware-cast-ids "^0.2.1"
+    monk-middleware-fields "^0.2.0"
+    monk-middleware-handle-callback "^0.2.0"
+    monk-middleware-options "^0.2.1"
+    monk-middleware-query "^0.2.0"
+    monk-middleware-wait-for-connection "^0.2.0"
+    object-assign "^4.1.1"
+
+ms@2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
+  integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
+
+ms@2.1.2:
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
+  integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
+
+mysql@^2.11.1:
+  version "2.18.1"
+  resolved "https://registry.yarnpkg.com/mysql/-/mysql-2.18.1.tgz#2254143855c5a8c73825e4522baf2ea021766717"
+  integrity sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==
+  dependencies:
+    bignumber.js "9.0.0"
+    readable-stream "2.3.7"
+    safe-buffer "5.1.2"
+    sqlstring "2.3.1"
+
+object-assign@^4.1.1:
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
+  integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
+
+process-nextick-args@~1.0.6:
+  version "1.0.7"
+  resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
+  integrity sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==
+
+process-nextick-args@~2.0.0:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
+  integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
+
+punycode@^2.1.0:
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f"
+  integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==
+
+readable-stream@2.2.7:
+  version "2.2.7"
+  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.7.tgz#07057acbe2467b22042d36f98c5ad507054e95b1"
+  integrity sha512-a6ibcfWFhgihuTw/chl+u3fB5ykBZFmnvpyZHebY0MCQE4vvYcsCLpCeaQ1BkH7HdJYavNSqF0WDLeo4IPHQaQ==
+  dependencies:
+    buffer-shims "~1.0.0"
+    core-util-is "~1.0.0"
+    inherits "~2.0.1"
+    isarray "~1.0.0"
+    process-nextick-args "~1.0.6"
+    string_decoder "~1.0.0"
+    util-deprecate "~1.0.1"
+
+readable-stream@2.3.7:
+  version "2.3.7"
+  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
+  integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
+  dependencies:
+    core-util-is "~1.0.0"
+    inherits "~2.0.3"
+    isarray "~1.0.0"
+    process-nextick-args "~2.0.0"
+    safe-buffer "~5.1.1"
+    string_decoder "~1.1.1"
+    util-deprecate "~1.0.1"
+
+redis-commands@^1.2.0:
+  version "1.7.0"
+  resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.7.0.tgz#15a6fea2d58281e27b1cd1acfb4b293e278c3a89"
+  integrity sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==
+
+redis-parser@^2.6.0:
+  version "2.6.0"
+  resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-2.6.0.tgz#52ed09dacac108f1a631c07e9b69941e7a19504b"
+  integrity sha512-9Hdw19gwXFBJdN8ENUoNVJFRyMDFrE/ZBClPicKYDPwNPJ4ST1TedAHYNSiGKElwh2vrmRGMoJYbVdJd+WQXIw==
+
+redis@^2.8.0:
+  version "2.8.0"
+  resolved "https://registry.yarnpkg.com/redis/-/redis-2.8.0.tgz#202288e3f58c49f6079d97af7a10e1303ae14b02"
+  integrity sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==
+  dependencies:
+    double-ended-queue "^2.1.0-0"
+    redis-commands "^1.2.0"
+    redis-parser "^2.6.0"
+
+require_optional@~1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/require_optional/-/require_optional-1.0.1.tgz#4cf35a4247f64ca3df8c2ef208cc494b1ca8fc2e"
+  integrity sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==
+  dependencies:
+    resolve-from "^2.0.0"
+    semver "^5.1.0"
+
+resolve-from@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57"
+  integrity sha512-qpFcKaXsq8+oRoLilkwyc7zHGF5i9Q2/25NIgLQQ/+VVv9rU4qvr6nXVAw1DsnXJyQkZsR4Ytfbtg5ehfcUssQ==
+
+safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
+  version "5.1.2"
+  resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
+  integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
+
+semver@^5.1.0:
+  version "5.7.2"
+  resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8"
+  integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
+
+sqlstring@2.3.1:
+  version "2.3.1"
+  resolved "https://registry.yarnpkg.com/sqlstring/-/sqlstring-2.3.1.tgz#475393ff9e91479aea62dcaf0ca3d14983a7fb40"
+  integrity sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==
+
+sqlx@^4.3.2:
+  version "4.3.2"
+  resolved "https://registry.yarnpkg.com/sqlx/-/sqlx-4.3.2.tgz#e00e9c01543e776639b3622beee0b51f2e005b76"
+  integrity sha512-cKXn3T0fDhnX69F7556K0weGUYaBsmmtcIjTlj9OPQNxR56Lvil89pk5WntRR+h4IFFkrmKDg0yzl0YVsSDgbQ==
+  dependencies:
+    ajv "^6.1.1"
+    async "^2.0.1"
+    debug "^2.2.0"
+    lodash "^4.17.4"
+    mongo-sql "^2.7.5"
+    monk "^6.0.5"
+    mysql "^2.11.1"
+    redis "^2.8.0"
+
+string_decoder@~1.0.0:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
+  integrity sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==
+  dependencies:
+    safe-buffer "~5.1.0"
+
+string_decoder@~1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
+  integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
+  dependencies:
+    safe-buffer "~5.1.0"
+
+uri-js@^4.2.2:
+  version "4.4.1"
+  resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
+  integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
+  dependencies:
+    punycode "^2.1.0"
+
+util-deprecate@~1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
+  integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==