Repository: web-scrobbler/web-scrobbler
Pull request #4094 (2023-09-11 09:18:16)

Fix safari listenbrainz login
Safari is stripping crucial information from the listenbrainz request everywhere except background script.
Work around this by pushing login requests to background script.
Chrome login is still a little unstable (no domparser API in background script) but handling it probably means adding an entire dom parsing library or offscreen document jank. Don't think the time figuring that out is worth it when its a fairly minor issue compared to the inverse.


Patch:
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 5e1a17f6..118d002f 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -10,7 +10,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout the repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: Setup Node.js
         uses: actions/setup-node@v3
@@ -35,7 +35,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout the repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: Get Node.js version from .nvmrc
         id: get-node-version
@@ -64,7 +64,7 @@ jobs:
     runs-on: macos-latest
     steps:
       - name: Checkout the repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: Setup Node.js
         uses: actions/setup-node@v3
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index e209862a..fa0990e6 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -11,7 +11,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout the repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: Setup Node.js
         uses: actions/setup-node@v3
@@ -38,7 +38,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout the repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: Setup Node.js
         uses: actions/setup-node@v3
@@ -65,7 +65,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout the repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: Setup Node.js
         uses: actions/setup-node@v3
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 4f86951c..265d1740 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -10,7 +10,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout the repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: Setup Node.js
         uses: actions/setup-node@v3
diff --git a/.github/workflows/release-extension.yml b/.github/workflows/release-extension.yml
index 72cc4041..c3483f96 100644
--- a/.github/workflows/release-extension.yml
+++ b/.github/workflows/release-extension.yml
@@ -17,7 +17,7 @@ jobs:
     if: github.ref == 'refs/heads/master'
     steps:
       - name: Checkout the repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
         with:
           token: ${{ secrets.BOT_PAT }}
       - name: Setup git config
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 04cac65a..f022e932 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -9,7 +9,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout the repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: Get the extension version from ref
         run: echo "EXT_VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV
diff --git a/package-lock.json b/package-lock.json
index c513760e..48f4c001 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -22,15 +22,15 @@
         "@types/fs-extra": "11.0.1",
         "@types/imagemin": "8.0.1",
         "@types/imagemin-jpegtran": "5.0.1",
-        "@types/node": "20.5.6",
+        "@types/node": "20.6.0",
         "@types/react": "18.2.21",
         "@types/webextension-polyfill": "0.10.2",
         "@typescript-eslint/eslint-plugin": "6.6.0",
-        "archiver": "6.0.0",
+        "archiver": "6.0.1",
         "canvas": "2.11.2",
         "chokidar": "3.5.3",
         "esbuild": "0.19.2",
-        "eslint": "8.48.0",
+        "eslint": "8.49.0",
         "eslint-config-web-scrobbler": "2.1.1",
         "eslint-plugin-react": "7.33.2",
         "eslint-plugin-solid": "0.13.0",
@@ -48,12 +48,12 @@
         "sass": "1.66.1",
         "solid-js": "1.7.11",
         "stylelint-config-web-scrobbler": "0.2.0",
-        "tsx": "3.12.7",
+        "tsx": "3.12.8",
         "typescript": "5.2.2",
         "vite-plugin-conditional-compiler": "0.1.1",
         "vite-plugin-solid": "2.7.0",
         "vite-plugin-static-copy": "0.17.0",
-        "vitest": "0.34.3"
+        "vitest": "0.34.4"
       },
       "engines": {
         "node": ">=18.0.0"
@@ -664,19 +664,19 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.1.0.tgz",
-      "integrity": "sha512-Uuk8RpCg/7fdHSceR1M6XbSZFSuMrxcePFuGgyvsBn+u339dk5OeL4jv2EojwTN2st/unJGsVm4qHWjWNmJ/tw==",
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.2.2.tgz",
+      "integrity": "sha512-Ub6LaRaAgF80dTSzUdXpFLM1pVDdmEVB9qb5iAzSpyDlX/mfJTFGOnZ516O05p5uWWteNviMKi4PAyEuRxI5gA==",
       "dev": true,
       "dependencies": {
-        "esbuild": "~0.17.6",
+        "esbuild": "~0.18.20",
         "source-map-support": "^0.5.21"
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz",
-      "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
+      "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
       "cpu": [
         "arm"
       ],
@@ -690,9 +690,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz",
-      "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
+      "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
       "cpu": [
         "arm64"
       ],
@@ -706,9 +706,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz",
-      "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
+      "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
       "cpu": [
         "x64"
       ],
@@ -722,9 +722,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-arm64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz",
-      "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
+      "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
       "cpu": [
         "arm64"
       ],
@@ -738,9 +738,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz",
-      "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
+      "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
       "cpu": [
         "x64"
       ],
@@ -754,9 +754,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz",
-      "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
+      "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
       "cpu": [
         "arm64"
       ],
@@ -770,9 +770,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz",
-      "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
+      "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
       "cpu": [
         "x64"
       ],
@@ -786,9 +786,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz",
-      "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
+      "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
       "cpu": [
         "arm"
       ],
@@ -802,9 +802,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz",
-      "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
+      "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
       "cpu": [
         "arm64"
       ],
@@ -818,9 +818,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ia32": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz",
-      "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
+      "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
       "cpu": [
         "ia32"
       ],
@@ -834,9 +834,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-loong64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz",
-      "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
+      "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
       "cpu": [
         "loong64"
       ],
@@ -850,9 +850,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-mips64el": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz",
-      "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
+      "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
       "cpu": [
         "mips64el"
       ],
@@ -866,9 +866,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ppc64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz",
-      "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
+      "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
       "cpu": [
         "ppc64"
       ],
@@ -882,9 +882,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-riscv64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz",
-      "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
+      "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
       "cpu": [
         "riscv64"
       ],
@@ -898,9 +898,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-s390x": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz",
-      "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
+      "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
       "cpu": [
         "s390x"
       ],
@@ -914,9 +914,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz",
-      "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
+      "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
       "cpu": [
         "x64"
       ],
@@ -930,9 +930,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/netbsd-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz",
-      "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
+      "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
       "cpu": [
         "x64"
       ],
@@ -946,9 +946,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/openbsd-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz",
-      "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
+      "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
       "cpu": [
         "x64"
       ],
@@ -962,9 +962,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/sunos-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz",
-      "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
+      "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
       "cpu": [
         "x64"
       ],
@@ -978,9 +978,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-arm64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz",
-      "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
+      "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
       "cpu": [
         "arm64"
       ],
@@ -994,9 +994,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-ia32": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz",
-      "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
+      "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
       "cpu": [
         "ia32"
       ],
@@ -1010,9 +1010,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-x64": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz",
-      "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
+      "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
       "cpu": [
         "x64"
       ],
@@ -1026,9 +1026,9 @@
       }
     },
     "node_modules/@esbuild-kit/core-utils/node_modules/esbuild": {
-      "version": "0.17.19",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz",
-      "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==",
+      "version": "0.18.20",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
+      "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
       "dev": true,
       "hasInstallScript": true,
       "bin": {
@@ -1038,28 +1038,28 @@
         "node": ">=12"
       },
       "optionalDependencies": {
-        "@esbuild/android-arm": "0.17.19",
-        "@esbuild/android-arm64": "0.17.19",
-        "@esbuild/android-x64": "0.17.19",
-        "@esbuild/darwin-arm64": "0.17.19",
-        "@esbuild/darwin-x64": "0.17.19",
-        "@esbuild/freebsd-arm64": "0.17.19",
-        "@esbuild/freebsd-x64": "0.17.19",
-        "@esbuild/linux-arm": "0.17.19",
-        "@esbuild/linux-arm64": "0.17.19",
-        "@esbuild/linux-ia32": "0.17.19",
-        "@esbuild/linux-loong64": "0.17.19",
-        "@esbuild/linux-mips64el": "0.17.19",
-        "@esbuild/linux-ppc64": "0.17.19",
-        "@esbuild/linux-riscv64": "0.17.19",
-        "@esbuild/linux-s390x": "0.17.19",
-        "@esbuild/linux-x64": "0.17.19",
-        "@esbuild/netbsd-x64": "0.17.19",
-        "@esbuild/openbsd-x64": "0.17.19",
-        "@esbuild/sunos-x64": "0.17.19",
-        "@esbuild/win32-arm64": "0.17.19",
-        "@esbuild/win32-ia32": "0.17.19",
-        "@esbuild/win32-x64": "0.17.19"
+        "@esbuild/android-arm": "0.18.20",
+        "@esbuild/android-arm64": "0.18.20",
+        "@esbuild/android-x64": "0.18.20",
+        "@esbuild/darwin-arm64": "0.18.20",
+        "@esbuild/darwin-x64": "0.18.20",
+        "@esbuild/freebsd-arm64": "0.18.20",
+        "@esbuild/freebsd-x64": "0.18.20",
+        "@esbuild/linux-arm": "0.18.20",
+        "@esbuild/linux-arm64": "0.18.20",
+        "@esbuild/linux-ia32": "0.18.20",
+        "@esbuild/linux-loong64": "0.18.20",
+        "@esbuild/linux-mips64el": "0.18.20",
+        "@esbuild/linux-ppc64": "0.18.20",
+        "@esbuild/linux-riscv64": "0.18.20",
+        "@esbuild/linux-s390x": "0.18.20",
+        "@esbuild/linux-x64": "0.18.20",
+        "@esbuild/netbsd-x64": "0.18.20",
+        "@esbuild/openbsd-x64": "0.18.20",
+        "@esbuild/sunos-x64": "0.18.20",
+        "@esbuild/win32-arm64": "0.18.20",
+        "@esbuild/win32-ia32": "0.18.20",
+        "@esbuild/win32-x64": "0.18.20"
       }
     },
     "node_modules/@esbuild-kit/esm-loader": {
@@ -1472,18 +1472,18 @@
       }
     },
     "node_modules/@eslint/js": {
-      "version": "8.48.0",
-      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz",
-      "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==",
+      "version": "8.49.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz",
+      "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==",
       "dev": true,
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
       }
     },
     "node_modules/@humanwhocodes/config-array": {
-      "version": "0.11.10",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
-      "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==",
+      "version": "0.11.11",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
+      "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==",
       "dev": true,
       "dependencies": {
         "@humanwhocodes/object-schema": "^1.2.1",
@@ -2347,9 +2347,9 @@
       "dev": true
     },
     "node_modules/@types/node": {
-      "version": "20.5.6",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.6.tgz",
-      "integrity": "sha512-Gi5wRGPbbyOTX+4Y2iULQ27oUPrefaB0PxGQJnfyWN3kvEDGM3mIB5M/gQLmitZf7A9FmLeaqxD3L1CXpm3VKQ==",
+      "version": "20.6.0",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz",
+      "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==",
       "devOptional": true
     },
     "node_modules/@types/normalize-package-data": {
@@ -2776,13 +2776,13 @@
       }
     },
     "node_modules/@vitest/expect": {
-      "version": "0.34.3",
-      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.3.tgz",
-      "integrity": "sha512-F8MTXZUYRBVsYL1uoIft1HHWhwDbSzwAU9Zgh8S6WFC3YgVb4AnFV2GXO3P5Em8FjEYaZtTnQYoNwwBrlOMXgg==",
+      "version": "0.34.4",
+      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.4.tgz",
+      "integrity": "sha512-XlMKX8HyYUqB8dsY8Xxrc64J2Qs9pKMt2Z8vFTL4mBWXJsg4yoALHzJfDWi8h5nkO4Zua4zjqtapQ/IluVkSnA==",
       "dev": true,
       "dependencies": {
-        "@vitest/spy": "0.34.3",
-        "@vitest/utils": "0.34.3",
+        "@vitest/spy": "0.34.4",
+        "@vitest/utils": "0.34.4",
         "chai": "^4.3.7"
       },
       "funding": {
@@ -2790,12 +2790,12 @@
       }
     },
     "node_modules/@vitest/runner": {
-      "version": "0.34.3",
-      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.3.tgz",
-      "integrity": "sha512-lYNq7N3vR57VMKMPLVvmJoiN4bqwzZ1euTW+XXYH5kzr3W/+xQG3b41xJn9ChJ3AhYOSoweu974S1V3qDcFESA==",
+      "version": "0.34.4",
+      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.4.tgz",
+      "integrity": "sha512-hwwdB1StERqUls8oV8YcpmTIpVeJMe4WgYuDongVzixl5hlYLT2G8afhcdADeDeqCaAmZcSgLTLtqkjPQF7x+w==",
       "dev": true,
       "dependencies": {
-        "@vitest/utils": "0.34.3",
+        "@vitest/utils": "0.34.4",
         "p-limit": "^4.0.0",
         "pathe": "^1.1.1"
       },
@@ -2831,9 +2831,9 @@
       }
     },
     "node_modules/@vitest/snapshot": {
-      "version": "0.34.3",
-      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.3.tgz",
-      "integrity": "sha512-QyPaE15DQwbnIBp/yNJ8lbvXTZxS00kRly0kfFgAD5EYmCbYcA+1EEyRalc93M0gosL/xHeg3lKAClIXYpmUiQ==",
+      "version": "0.34.4",
+      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.4.tgz",
+      "integrity": "sha512-GCsh4coc3YUSL/o+BPUo7lHQbzpdttTxL6f4q0jRx2qVGoYz/cyTRDJHbnwks6TILi6560bVWoBpYC10PuTLHw==",
       "dev": true,
       "dependencies": {
         "magic-string": "^0.30.1",
@@ -2845,9 +2845,9 @@
       }
     },
     "node_modules/@vitest/spy": {
-      "version": "0.34.3",
-      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.3.tgz",
-      "integrity": "sha512-N1V0RFQ6AI7CPgzBq9kzjRdPIgThC340DGjdKdPSE8r86aUSmeliTUgkTqLSgtEwWWsGfBQ+UetZWhK0BgJmkQ==",
+      "version": "0.34.4",
+      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.4.tgz",
+      "integrity": "sha512-PNU+fd7DUPgA3Ya924b1qKuQkonAW6hL7YUjkON3wmBwSTIlhOSpy04SJ0NrRsEbrXgMMj6Morh04BMf8k+w0g==",
       "dev": true,
       "dependencies": {
         "tinyspy": "^2.1.1"
@@ -2857,9 +2857,9 @@
       }
     },
     "node_modules/@vitest/utils": {
-      "version": "0.34.3",
-      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.3.tgz",
-      "integrity": "sha512-kiSnzLG6m/tiT0XEl4U2H8JDBjFtwVlaE8I3QfGiMFR0QvnRDfYfdP3YvTBWM/6iJDAyaPY6yVQiCTUc7ZzTHA==",
+      "version": "0.34.4",
+      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.4.tgz",
+      "integrity": "sha512-yR2+5CHhp/K4ySY0Qtd+CAL9f5Yh1aXrKfAT42bq6CtlGPh92jIDDDSg7ydlRow1CP+dys4TrOrbELOyNInHSg==",
       "dev": true,
       "dependencies": {
         "diff-sequences": "^29.4.3",
@@ -3028,133 +3028,78 @@
       }
     },
     "node_modules/archiver": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/archiver/-/archiver-6.0.0.tgz",
-      "integrity": "sha512-EPGa+bYaxaMiCT8DCbEDqFz8IjeBSExrJzyUOJx2FBkFJ/OZzJuso3lMSk901M50gMqXxTQcumlGajOFlXhVhw==",
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/archiver/-/archiver-6.0.1.tgz",
+      "integrity": "sha512-CXGy4poOLBKptiZH//VlWdFuUC1RESbdZjGjILwBuZ73P7WkAUN0htfSfBq/7k6FRFlpu7bg4JOkj1vU9G6jcQ==",
       "dev": true,
       "dependencies": {
-        "archiver-utils": "^3.0.0",
+        "archiver-utils": "^4.0.1",
         "async": "^3.2.4",
         "buffer-crc32": "^0.2.1",
         "readable-stream": "^3.6.0",
         "readdir-glob": "^1.1.2",
-        "tar-stream": "^2.2.0",
-        "zip-stream": "^4.1.0"
+        "tar-stream": "^3.0.0",
+        "zip-stream": "^5.0.1"
       },
       "engines": {
         "node": ">= 12.0.0"
       }
     },
     "node_modules/archiver-utils": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz",
-      "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-4.0.1.tgz",
+      "integrity": "sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg==",
       "dev": true,
       "dependencies": {
-        "glob": "^7.1.4",
+        "glob": "^8.0.0",
         "graceful-fs": "^4.2.0",
         "lazystream": "^1.0.0",
-        "lodash.defaults": "^4.2.0",
-        "lodash.difference": "^4.5.0",
-        "lodash.flatten": "^4.4.0",
-        "lodash.isplainobject": "^4.0.6",
-        "lodash.union": "^4.6.0",
+        "lodash": "^4.17.15",
         "normalize-path": "^3.0.0",
-        "readable-stream": "^2.0.0"
+        "readable-stream": "^3.6.0"
       },
       "engines": {
-        "node": ">= 6"
+        "node": ">= 12.0.0"
+      }
+    },
+    "node_modules/archiver-utils/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0"
       }
     },
     "node_modules/archiver-utils/node_modules/glob": {
-      "version": "7.2.3",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
-      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+      "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
       "dev": true,
       "dependencies": {
         "fs.realpath": "^1.0.0",
         "inflight": "^1.0.4",
         "inherits": "2",
-        "minimatch": "^3.1.1",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
+        "minimatch": "^5.0.1",
+        "once": "^1.3.0"
       },
       "engines": {
-        "node": "*"
+        "node": ">=12"
       },
       "funding": {
         "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/archiver-utils/node_modules/readable-stream": {
-      "version": "2.3.8",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
-      "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
-      "dev": true,
-      "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"
-      }
-    },
-    "node_modules/archiver-utils/node_modules/safe-buffer": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-      "dev": true
-    },
-    "node_modules/archiver-utils/node_modules/string_decoder": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "~5.1.0"
-      }
-    },
-    "node_modules/archiver/node_modules/archiver-utils": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.3.tgz",
-      "integrity": "sha512-fXzpEZTKgBJMWy0eUT0/332CAQnJ27OJd7sGcvNZzxS2Yzg7iITivMhXOm+zUTO4vT8ZqlPCqiaLPmB8qWhWRA==",
-      "dev": true,
-      "dependencies": {
-        "glob": "^7.1.4",
-        "graceful-fs": "^4.2.0",
-        "lazystream": "^1.0.0",
-        "lodash.defaults": "^4.2.0",
-        "lodash.difference": "^4.5.0",
-        "lodash.flatten": "^4.4.0",
-        "lodash.isplainobject": "^4.0.6",
-        "lodash.union": "^4.6.0",
-        "normalize-path": "^3.0.0",
-        "readable-stream": "^3.6.0"
-      },
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/archiver/node_modules/glob": {
-      "version": "7.2.3",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
-      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+    "node_modules/archiver-utils/node_modules/minimatch": {
+      "version": "5.1.6",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+      "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
       "dev": true,
       "dependencies": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.1.1",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
+        "brace-expansion": "^2.0.1"
       },
       "engines": {
-        "node": "*"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
+        "node": ">=10"
       }
     },
     "node_modules/are-we-there-yet": {
@@ -3349,6 +3294,12 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/b4a": {
+      "version": "1.6.4",
+      "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz",
+      "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==",
+      "dev": true
+    },
     "node_modules/babel-plugin-jsx-dom-expressions": {
       "version": "0.36.10",
       "resolved": "https://registry.npmjs.org/babel-plugin-jsx-dom-expressions/-/babel-plugin-jsx-dom-expressions-0.36.10.tgz",
@@ -3753,17 +3704,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/bl": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
-      "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
-      "dev": true,
-      "dependencies": {
-        "buffer": "^5.5.0",
-        "inherits": "^2.0.4",
-        "readable-stream": "^3.4.0"
-      }
-    },
     "node_modules/blueimp-md5": {
       "version": "2.19.0",
       "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz",
@@ -4195,18 +4135,18 @@
       }
     },
     "node_modules/compress-commons": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz",
-      "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-5.0.1.tgz",
+      "integrity": "sha512-MPh//1cERdLtqwO3pOFLeXtpuai0Y2WCd5AhtKxznqM7WtaMYaOEMSgn45d9D10sIHSfIKE603HlOp8OPGrvag==",
       "dev": true,
       "dependencies": {
-        "buffer-crc32": "^0.2.13",
-        "crc32-stream": "^4.0.2",
+        "crc-32": "^1.2.0",
+        "crc32-stream": "^5.0.0",
         "normalize-path": "^3.0.0",
         "readable-stream": "^3.6.0"
       },
       "engines": {
-        "node": ">= 10"
+        "node": ">= 12.0.0"
       }
     },
     "node_modules/concat-map": {
@@ -4324,16 +4264,16 @@
       }
     },
     "node_modules/crc32-stream": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz",
-      "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-5.0.0.tgz",
+      "integrity": "sha512-B0EPa1UK+qnpBZpG+7FgPCu0J2ETLpXq09o9BkLkEAhdB6Z61Qo4pJ3JYu0c+Qi+/SAL7QThqnzS06pmSSyZaw==",
       "dev": true,
       "dependencies": {
         "crc-32": "^1.2.0",
         "readable-stream": "^3.4.0"
       },
       "engines": {
-        "node": ">= 10"
+        "node": ">= 12.0.0"
       }
     },
     "node_modules/cross-spawn": {
@@ -5051,16 +4991,16 @@
       }
     },
     "node_modules/eslint": {
-      "version": "8.48.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz",
-      "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==",
+      "version": "8.49.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz",
+      "integrity": "sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==",
       "dev": true,
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.2.0",
         "@eslint-community/regexpp": "^4.6.1",
         "@eslint/eslintrc": "^2.1.2",
-        "@eslint/js": "8.48.0",
-        "@humanwhocodes/config-array": "^0.11.10",
+        "@eslint/js": "8.49.0",
+        "@humanwhocodes/config-array": "^0.11.11",
         "@humanwhocodes/module-importer": "^1.0.1",
         "@nodelib/fs.walk": "^1.2.8",
         "ajv": "^6.12.4",
@@ -5538,6 +5478,12 @@
       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
       "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
     },
+    "node_modules/fast-fifo": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
+      "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
+      "dev": true
+    },
     "node_modules/fast-glob": {
       "version": "3.2.12",
       "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
@@ -7628,30 +7574,6 @@
       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
       "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
     },
-    "node_modules/lodash.defaults": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
-      "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==",
-      "dev": true
-    },
-    "node_modules/lodash.difference": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
-      "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==",
-      "dev": true
-    },
-    "node_modules/lodash.flatten": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
-      "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==",
-      "dev": true
-    },
-    "node_modules/lodash.isplainobject": {
-      "version": "4.0.6",
-      "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
-      "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
-      "dev": true
-    },
     "node_modules/lodash.merge": {
       "version": "4.6.2",
       "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -7663,12 +7585,6 @@
       "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
       "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw=="
     },
-    "node_modules/lodash.union": {
-      "version": "4.6.0",
-      "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
-      "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==",
-      "dev": true
-    },
     "node_modules/log-symbols": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
@@ -8569,9 +8485,9 @@
       }
     },
     "node_modules/mlly": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.1.tgz",
-      "integrity": "sha512-SCDs78Q2o09jiZiE2WziwVBEqXQ02XkGdUy45cbJf+BpYRIjArXRJ1Wbowxkb+NaM9DWvS3UC9GiO/6eqvQ/pg==",
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.2.tgz",
+      "integrity": "sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==",
       "dev": true,
       "dependencies": {
         "acorn": "^8.10.0",
@@ -9729,6 +9645,12 @@
         }
       ]
     },
+    "node_modules/queue-tick": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
+      "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==",
+      "dev": true
+    },
     "node_modules/quick-lru": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz",
@@ -10969,6 +10891,16 @@
       "integrity": "sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==",
       "dev": true
     },
+    "node_modules/streamx": {
+      "version": "2.15.1",
+      "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz",
+      "integrity": "sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==",
+      "dev": true,
+      "dependencies": {
+        "fast-fifo": "^1.1.0",
+        "queue-tick": "^1.0.1"
+      }
+    },
     "node_modules/strict-uri-encode": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
@@ -11714,19 +11646,14 @@
       }
     },
     "node_modules/tar-stream": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
-      "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+      "version": "3.1.6",
+      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz",
+      "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==",
       "dev": true,
       "dependencies": {
-        "bl": "^4.0.3",
-        "end-of-stream": "^1.4.1",
-        "fs-constants": "^1.0.0",
-        "inherits": "^2.0.3",
-        "readable-stream": "^3.1.1"
-      },
-      "engines": {
-        "node": ">=6"
+        "b4a": "^1.6.4",
+        "fast-fifo": "^1.2.0",
+        "streamx": "^2.15.0"
       }
     },
     "node_modules/temp-dir": {
@@ -11911,13 +11838,13 @@
       }
     },
     "node_modules/tsx": {
-      "version": "3.12.7",
-      "resolved": "https://registry.npmjs.org/tsx/-/tsx-3.12.7.tgz",
-      "integrity": "sha512-C2Ip+jPmqKd1GWVQDvz/Eyc6QJbGfE7NrR3fx5BpEHMZsEHoIxHL1j+lKdGobr8ovEyqeNkPLSKp6SCSOt7gmw==",
+      "version": "3.12.8",
+      "resolved": "https://registry.npmjs.org/tsx/-/tsx-3.12.8.tgz",
+      "integrity": "sha512-Lt9KYaRGF023tlLInPj8rgHwsZU8qWLBj4iRXNWxTfjIkU7canGL806AqKear1j722plHuiYNcL2ZCo6uS9UJA==",
       "dev": true,
       "dependencies": {
         "@esbuild-kit/cjs-loader": "^2.4.2",
-        "@esbuild-kit/core-utils": "^3.0.0",
+        "@esbuild-kit/core-utils": "^3.2.2",
         "@esbuild-kit/esm-loader": "^2.5.5"
       },
       "bin": {
@@ -12810,9 +12737,9 @@
       }
     },
     "node_modules/vite-node": {
-      "version": "0.34.3",
-      "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.3.tgz",
-      "integrity": "sha512-+0TzJf1g0tYXj6tR2vEyiA42OPq68QkRZCu/ERSo2PtsDJfBpDyEfuKbRvLmZqi/CgC7SCBtyC+WjTGNMRIaig==",
+      "version": "0.34.4",
+      "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.4.tgz",
+      "integrity": "sha512-ho8HtiLc+nsmbwZMw8SlghESEE3KxJNp04F/jPUCLVvaURwt0d+r9LxEqCX5hvrrOQ0GSyxbYr5ZfRYhQ0yVKQ==",
       "dev": true,
       "dependencies": {
         "cac": "^6.7.14",
@@ -13303,19 +13230,19 @@
       }
     },
     "node_modules/vitest": {
-      "version": "0.34.3",
-      "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.3.tgz",
-      "integrity": "sha512-7+VA5Iw4S3USYk+qwPxHl8plCMhA5rtfwMjgoQXMT7rO5ldWcdsdo3U1QD289JgglGK4WeOzgoLTsGFu6VISyQ==",
+      "version": "0.34.4",
+      "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.4.tgz",
+      "integrity": "sha512-SE/laOsB6995QlbSE6BtkpXDeVNLJc1u2LHRG/OpnN4RsRzM3GQm4nm3PQCK5OBtrsUqnhzLdnT7se3aeNGdlw==",
       "dev": true,
       "dependencies": {
         "@types/chai": "^4.3.5",
         "@types/chai-subset": "^1.3.3",
         "@types/node": "*",
-        "@vitest/expect": "0.34.3",
-        "@vitest/runner": "0.34.3",
-        "@vitest/snapshot": "0.34.3",
-        "@vitest/spy": "0.34.3",
-        "@vitest/utils": "0.34.3",
+        "@vitest/expect": "0.34.4",
+        "@vitest/runner": "0.34.4",
+        "@vitest/snapshot": "0.34.4",
+        "@vitest/spy": "0.34.4",
+        "@vitest/utils": "0.34.4",
         "acorn": "^8.9.0",
         "acorn-walk": "^8.2.0",
         "cac": "^6.7.14",
@@ -13329,8 +13256,8 @@
         "strip-literal": "^1.0.1",
         "tinybench": "^2.5.0",
         "tinypool": "^0.7.0",
-        "vite": "^3.0.0 || ^4.0.0",
-        "vite-node": "0.34.3",
+        "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0",
+        "vite-node": "0.34.4",
         "why-is-node-running": "^2.2.2"
       },
       "bin": {
@@ -13669,17 +13596,17 @@
       }
     },
     "node_modules/zip-stream": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz",
-      "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-5.0.1.tgz",
+      "integrity": "sha512-UfZ0oa0C8LI58wJ+moL46BDIMgCQbnsb+2PoiJYtonhBsMh2bq1eRBVkvjfVsqbEHd9/EgKPUuL9saSSsec8OA==",
       "dev": true,
       "dependencies": {
-        "archiver-utils": "^2.1.0",
-        "compress-commons": "^4.1.0",
+        "archiver-utils": "^4.0.1",
+        "compress-commons": "^5.0.1",
         "readable-stream": "^3.6.0"
       },
       "engines": {
-        "node": ">= 10"
+        "node": ">= 12.0.0"
       }
     },
     "node_modules/zwitch": {
diff --git a/package.json b/package.json
index 04b082c3..a8b6308c 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,7 @@
     "dist": "npm run build dist",
     "dev": "npm run build dev",
     "build": "tsx build.ts",
-    "buildts": "tsc --project tsconfig.connectors.json",
+    "checkts": "tsc --noEmit && tsc --noEmit --project tsconfig.connectors.json",
     "test": "vitest",
     "lint": "eslint . && stylelint \"**/*.scss\" && remark .",
     "translations": "tx pull -m onlytranslated && tsx scripts/translations-prepare.ts"
@@ -39,15 +39,15 @@
     "@types/fs-extra": "11.0.1",
     "@types/imagemin": "8.0.1",
     "@types/imagemin-jpegtran": "5.0.1",
-    "@types/node": "20.5.6",
+    "@types/node": "20.6.0",
     "@types/react": "18.2.21",
     "@types/webextension-polyfill": "0.10.2",
     "@typescript-eslint/eslint-plugin": "6.6.0",
-    "archiver": "6.0.0",
+    "archiver": "6.0.1",
     "canvas": "2.11.2",
     "chokidar": "3.5.3",
     "esbuild": "0.19.2",
-    "eslint": "8.48.0",
+    "eslint": "8.49.0",
     "eslint-config-web-scrobbler": "2.1.1",
     "eslint-plugin-react": "7.33.2",
     "eslint-plugin-solid": "0.13.0",
@@ -65,12 +65,12 @@
     "sass": "1.66.1",
     "solid-js": "1.7.11",
     "stylelint-config-web-scrobbler": "0.2.0",
-    "tsx": "3.12.7",
+    "tsx": "3.12.8",
     "typescript": "5.2.2",
     "vite-plugin-conditional-compiler": "0.1.1",
     "vite-plugin-solid": "2.7.0",
     "vite-plugin-static-copy": "0.17.0",
-    "vitest": "0.34.3"
+    "vitest": "0.34.4"
   },
   "engines": {
     "node": ">=18.0.0"
diff --git a/scripts/log.ts b/scripts/log.ts
index 672086ec..92dd2be5 100644
--- a/scripts/log.ts
+++ b/scripts/log.ts
@@ -1,6 +1,6 @@
 type ColorType = 'success' | 'info' | 'error' | 'warning' | keyof typeof COLORS;
 
-export default function colorLog(message: string, type?: ColorType): void {
+export default function colorLog(message: unknown, type?: ColorType): void {
 	let color: string = type || COLORS.FgBlack;
 
 	switch (type) {
diff --git a/scripts/translations-prepare.ts b/scripts/translations-prepare.ts
index a467ca8b..5dc34fdf 100644
--- a/scripts/translations-prepare.ts
+++ b/scripts/translations-prepare.ts
@@ -2,23 +2,27 @@ import { glob } from 'glob';
 import { readFile, writeFile } from 'fs/promises';
 import colorLog from 'scripts/log';
 
-const translationFiles = await glob('src/_locales/**/messages.json');
+async function main() {
+	const translationFiles = await glob('src/_locales/**/messages.json');
 
-for (const index in translationFiles) {
-	const filePath = translationFiles[index];
+	for (const index in translationFiles) {
+		const filePath = translationFiles[index];
 
-	const json = JSON.parse(await readFile(filePath));
+		const json = JSON.parse(await readFile(filePath, 'utf-8'));
 
-	let modified = false;
-	Object.keys(json).forEach((key) => {
-		if (json[key]['message'] === '') {
-			delete json[key];
-			modified = true;
-		}
-	});
+		let modified = false;
+		Object.keys(json).forEach((key) => {
+			if (json[key]['message'] === '') {
+				delete json[key];
+				modified = true;
+			}
+		});
 
-	if (modified) {
-		colorLog(`Updating ${filePath}`, 'info');
-		await writeFile(filePath, JSON.stringify(json, null, 4) + '\n');
+		if (modified) {
+			colorLog(`Updating ${filePath}`, 'info');
+			await writeFile(filePath, JSON.stringify(json, null, 4) + '\n');
+		}
 	}
 }
+
+main();
diff --git a/src/connectors/turntable.fm.ts b/src/connectors/deepcut.fm.ts
similarity index 100%
rename from src/connectors/turntable.fm.ts
rename to src/connectors/deepcut.fm.ts
diff --git a/src/core/background/main.ts b/src/core/background/main.ts
index ff8a8f1b..13bfacbc 100644
--- a/src/core/background/main.ts
+++ b/src/core/background/main.ts
@@ -45,6 +45,7 @@ import {
 	toggleLove,
 } from './scrobble';
 import scrobbleService from '../object/scrobble-service';
+import { fetchListenBrainzProfile } from '@/util/util';
 
 const disabledTabs = BrowserStorage.getStorage(BrowserStorage.DISABLED_TABS);
 
@@ -393,6 +394,15 @@ setupBackgroundListeners(
 		},
 	}),
 
+	/**
+	 * Listener called by a content script to attempt signing into musicbrainz.
+	 * This has to be done in background script, as safari blocks sending necessary cookies in other scripts.
+	 */
+	backgroundListener({
+		type: 'sendListenBrainzRequest',
+		fn: async (payload) => fetchListenBrainzProfile(payload.url),
+	}),
+
 	/**
 	 * Listener called by a controller to trigger clearing now playing notification.
 	 */
diff --git a/src/core/connectors.ts b/src/core/connectors.ts
index 60db57c1..23e32e3c 100644
--- a/src/core/connectors.ts
+++ b/src/core/connectors.ts
@@ -1661,10 +1661,13 @@ export default <ConnectorMeta[]>[
 		id: 'navidrome',
 	},
 	{
-		label: 'turntable.fm',
-		matches: ['*://turntable.fm/*'],
-		js: 'turntable.fm.js',
-		id: 'turntable.fm',
+		label: 'deepcut.fm',
+		matches: [
+			'*://deepcut.fm/*',
+			'*://turntable.fm/*',
+			],
+		js: 'deepcut.fm.js',
+		id: 'deepcut.fm',
 	},
 	{
 		label: 'Burntable',
diff --git a/src/core/scrobbler/listenbrainz/listenbrainz-scrobbler.ts b/src/core/scrobbler/listenbrainz/listenbrainz-scrobbler.ts
index 7c3afe6f..aa4d9767 100644
--- a/src/core/scrobbler/listenbrainz/listenbrainz-scrobbler.ts
+++ b/src/core/scrobbler/listenbrainz/listenbrainz-scrobbler.ts
@@ -10,6 +10,7 @@ import {
 	ListenBrainzTrackMeta,
 	MetadataLookup,
 } from './listenbrainz.types';
+import { sendContentMessage } from '@/util/communication';
 
 /**
  * Module for all communication with LB
@@ -340,21 +341,25 @@ export default class ListenBrainzScrobbler extends BaseScrobbler<'ListenBrainz'>
 
 	private async fetchSession(url: string) {
 		this.debugLog(`Use ${url}`);
-		// NOTE: Use 'same-origin' credentials to fix login on Firefox ESR 60.
-		const promise = fetch(url, {
-			method: 'GET',
-			// #v-ifdef VITE_FIREFOX
-			credentials: 'same-origin',
-			// #v-endif
-		});
+
+		// safari does not send cookies in content requests. Use background script to send.
+		// however, if already in background script, send directly as messaging will fail.
+		const promise = Util.isBackgroundScript()
+			? Util.fetchListenBrainzProfile(url)
+			: sendContentMessage({
+					type: 'sendListenBrainzRequest',
+					payload: {
+						url,
+					},
+			  });
 		const timeout = this.REQUEST_TIMEOUT;
 
-		const response = await Util.timeoutPromise(timeout, promise);
+		// @ts-expect-error typescript is confused by the combination of ternary and promise wrapped promise. It's a skill issue on typescript's part.
+		const rawHtml = await Util.timeoutPromise(timeout, promise);
 
-		if (response.ok) {
+		if (rawHtml !== null) {
 			const parser = new DOMParser();
 
-			const rawHtml = await response.text();
 			const doc = parser.parseFromString(rawHtml, 'text/html');
 
 			let sessionName = null;
diff --git a/src/util/communication.ts b/src/util/communication.ts
index bff7445d..4dc311f1 100644
--- a/src/util/communication.ts
+++ b/src/util/communication.ts
@@ -92,6 +92,12 @@ interface ContentCommunications {
 		};
 		response: Promise<(ServiceCallResult | Record<string, never>)[]>;
 	};
+	sendListenBrainzRequest: {
+		payload: {
+			url: string;
+		};
+		response: Promise<string | null>;
+	};
 }
 
 interface BackgroundCommunications {
diff --git a/src/util/util.ts b/src/util/util.ts
index 7e6458f4..0d1bc6ab 100644
--- a/src/util/util.ts
+++ b/src/util/util.ts
@@ -275,3 +275,43 @@ export function createTrackLibraryURL(
 		track,
 	)}`;
 }
+
+/**
+ * Check if script is currently running in a background script.
+ *
+ * @returns true if running in background script, false if running in any other context including popup.
+ */
+export function isBackgroundScript(): boolean {
+	// on chromium, no window in background script.
+	if (!self.window) {
+		return true;
+	}
+	// on firefox and safari, check for being in the generated background script
+	if (
+		(location.href.startsWith('safari-web-extension') ||
+			location.href.startsWith('moz-extension')) &&
+		location.href.endsWith('generated_background_page.html')
+	) {
+		return true;
+	}
+	return false;
+}
+
+/**
+ * Attempt to fetch listenbrainz profile HTML.
+ *
+ * @param url - URL of listenbrainz instance
+ * @returns html of profile, null if response error
+ */
+export async function fetchListenBrainzProfile(url: string) {
+	const res = await fetch(url, {
+		method: 'GET',
+		// #v-ifdef VITE_FIREFOX
+		credentials: 'same-origin',
+		// #v-endif
+	});
+	if (!res.ok) {
+		return null;
+	}
+	return res.text();
+}
diff --git a/tsconfig.json b/tsconfig.json
index ca9c3f17..e33bb468 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -4,6 +4,7 @@
     "baseUrl": ".",
     "module": "ES2020",
     "moduleResolution": "Node",
+    "isolatedModules": true,
     "outDir": "build",
     "jsx": "preserve",
     "jsxImportSource": "solid-js",


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 265d199b..b1f3ee24 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -10,7 +10,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout the repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: Setup Node.js
         uses: actions/setup-node@v3
@@ -20,5 +20,26 @@ jobs:
       - name: Install dependencies
         run: npm ci
 
+      - name: Check for typescript errors
+        run: npm run checkts
+
       - name: Run tests
         run: npm run test
+
+  test_typescript:
+    name: Run tests
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout the repository
+        uses: actions/checkout@v4
+
+      - name: Setup Node.js
+        uses: actions/setup-node@v3
+        with:
+          node-version-file: '.nvmrc'
+
+      - name: Install dependencies
+        run: npm ci
+
+      - name: Check for typescript errors
+        run: npm run checkts
diff --git a/tests/background/song.test.ts b/tests/background/song.test.ts
index 9808c3a2..9a10b71b 100644
--- a/tests/background/song.test.ts
+++ b/tests/background/song.test.ts
@@ -378,10 +378,12 @@ function testEquals() {
 	});
 
 	it('should not equal null value', () => {
+		// @ts-expect-error we are explicitly testing bad format here
 		expect(songWithUniqueId.equals(null)).to.be.false;
 	});
 
 	it('should not equal non-song object', () => {
+		// @ts-expect-error we are explicitly testing bad format here
 		expect(songWithUniqueId.equals(23)).to.be.false;
 	});
 }
diff --git a/tests/background/util.test.ts b/tests/background/util.test.ts
index 059830d9..711b39d0 100644
--- a/tests/background/util.test.ts
+++ b/tests/background/util.test.ts
@@ -215,6 +215,8 @@ function runTests() {
 		const description = func.name;
 
 		describe(description, () => {
+			// TODO: type gymnastics
+			// @ts-ignore type gymnastics required on this one. It works.
 			testFunction(func, data);
 		});
 	}
@@ -226,6 +228,7 @@ function runTests() {
 function testDebugLog() {
 	it('should throw an error if type is invalid', () => {
 		function callInvalidDebugLog() {
+			// @ts-expect-error we are explicitly testing bad format here
 			Util.debugLog('Test', 'invalid_type123');
 		}
 
diff --git a/tests/content/util.test.ts b/tests/content/util.test.ts
index 3ce7f645..0a2f76c6 100644
--- a/tests/content/util.test.ts
+++ b/tests/content/util.test.ts
@@ -2,7 +2,7 @@ import { TestData } from '#/types/types';
 import { expect, it, describe } from 'vitest';
 
 // trick webextension polyfill into thinking this is running in the browser
-(globalThis as { chrome: unknown }).chrome = {
+(globalThis as unknown as { chrome: unknown }).chrome = {
 	runtime: {
 		id: 'mock',
 	},
@@ -1126,6 +1126,8 @@ function runTests() {
 		const description = func.name;
 
 		describe(description, () => {
+			// TODO: type gymnastics
+			// @ts-ignore type gymnastics required on this one. It works.
 			testFunction(func, data);
 		});
 	}
diff --git a/tests/mocks/webextension-polyfill.ts b/tests/mocks/webextension-polyfill.ts
index 76d09c68..77651c8f 100644
--- a/tests/mocks/webextension-polyfill.ts
+++ b/tests/mocks/webextension-polyfill.ts
@@ -1,3 +1,4 @@
+import type { CloneableSong } from '@/core/object/song';
 import { vi } from 'vitest';
 
 /**