about summary refs log tree commit diff stats
path: root/src/assets
diff options
context:
space:
mode:
authorHygna <hygna@proton.me>2022-10-04 19:00:06 +0100
committerHygna <hygna@proton.me>2022-10-04 19:00:06 +0100
commitaa408a4c9b3fd61d355328490e20048f77d0c647 (patch)
tree841ec358fbab402b625b860d83432b10e2a1d32a /src/assets
parentupdated instances (diff)
parentDisplay if server is not found, made images in settings clickable (diff)
downloadlibredirect-aa408a4c9b3fd61d355328490e20048f77d0c647.zip
Merge branch 'optimizations'
Diffstat (limited to 'src/assets')
-rw-r--r--src/assets/images/about-icon.svg3
-rw-r--r--src/assets/images/general-icon.svg3
-rw-r--r--src/assets/images/imdb-icon.svg (renamed from src/assets/images/imdb.svg)0
-rw-r--r--src/assets/images/imgur-icon.png (renamed from src/assets/images/imgur.png)bin26675 -> 26675 bytes
-rw-r--r--src/assets/images/maps-icon.svg3
-rw-r--r--src/assets/images/medium-icon.svg5
-rw-r--r--src/assets/images/quora-icon.png (renamed from src/assets/images/quora.png)bin5499 -> 5499 bytes
-rw-r--r--src/assets/images/reuters-icon.svg (renamed from src/assets/images/reuters.svg)0
-rw-r--r--src/assets/images/search-icon.svg3
-rw-r--r--src/assets/images/send-icon.svg51
-rw-r--r--src/assets/images/sendFiles-icon.svg3
-rw-r--r--src/assets/images/translate-icon.svg3
-rw-r--r--src/assets/images/youtubeMusic-icon.png (renamed from src/assets/images/youtube-music-icon.png)bin25903 -> 25903 bytes
-rw-r--r--src/assets/javascripts/general.js55
-rw-r--r--src/assets/javascripts/get-localstorage.js15
-rw-r--r--src/assets/javascripts/imdb.js221
-rw-r--r--src/assets/javascripts/imgur.js221
-rw-r--r--src/assets/javascripts/instagram.js249
-rw-r--r--src/assets/javascripts/lbry.js223
-rw-r--r--src/assets/javascripts/maps.js309
-rw-r--r--src/assets/javascripts/medium.js227
-rw-r--r--src/assets/javascripts/peertube.js209
-rw-r--r--src/assets/javascripts/quora.js205
-rw-r--r--src/assets/javascripts/reddit.js402
-rw-r--r--src/assets/javascripts/reuters.js155
-rw-r--r--src/assets/javascripts/search.js581
-rw-r--r--src/assets/javascripts/sendTargets.js200
-rw-r--r--src/assets/javascripts/services.js682
-rw-r--r--src/assets/javascripts/set-localstorage.js13
-rw-r--r--src/assets/javascripts/tiktok.js251
-rw-r--r--src/assets/javascripts/translate/get_lingva_preferences.js10
-rw-r--r--src/assets/javascripts/translate/set_lingva_preferences.js9
-rw-r--r--src/assets/javascripts/translate/translate.js377
-rw-r--r--src/assets/javascripts/twitter.js286
-rw-r--r--src/assets/javascripts/utils.js574
-rw-r--r--src/assets/javascripts/wikipedia.js247
-rw-r--r--src/assets/javascripts/youtube/get_pipedMaterial_preferences.js5
-rw-r--r--src/assets/javascripts/youtube/get_piped_preferences.js22
-rw-r--r--src/assets/javascripts/youtube/set_pipedMaterial_preferences.js7
-rw-r--r--src/assets/javascripts/youtube/set_piped_preferences.js45
-rw-r--r--src/assets/javascripts/youtube/youtube.js797
-rw-r--r--src/assets/javascripts/youtubeMusic.js332
42 files changed, 752 insertions, 6251 deletions
diff --git a/src/assets/images/about-icon.svg b/src/assets/images/about-icon.svg
new file mode 100644
index 00000000..551255e6
--- /dev/null
+++ b/src/assets/images/about-icon.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24" fill="currentColor">
+  <path d="M11 17h2v-6h-2Zm1-8q.425 0 .713-.288Q13 8.425 13 8t-.287-.713Q12.425 7 12 7t-.712.287Q11 7.575 11 8t.288.712Q11.575 9 12 9Zm0 13q-2.075 0-3.9-.788-1.825-.787-3.175-2.137-1.35-1.35-2.137-3.175Q2 14.075 2 12t.788-3.9q.787-1.825 2.137-3.175 1.35-1.35 3.175-2.138Q9.925 2 12 2t3.9.787q1.825.788 3.175 2.138 1.35 1.35 2.137 3.175Q22 9.925 22 12t-.788 3.9q-.787 1.825-2.137 3.175-1.35 1.35-3.175 2.137Q14.075 22 12 22Zm0-2q3.35 0 5.675-2.325Q20 15.35 20 12q0-3.35-2.325-5.675Q15.35 4 12 4 8.65 4 6.325 6.325 4 8.65 4 12q0 3a.35 2.325 5.675Q8.65 20 12 20Zm0-8Z"></path>
+</svg>
diff --git a/src/assets/images/general-icon.svg b/src/assets/images/general-icon.svg
new file mode 100644
index 00000000..55c5f8bc
--- /dev/null
+++ b/src/assets/images/general-icon.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="26px" viewBox="0 0 24 24" width="26px" fill="currentColor">
+  <path d="M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z"></path>
+</svg>
diff --git a/src/assets/images/imdb.svg b/src/assets/images/imdb-icon.svg
index a3f4103c..a3f4103c 100644
--- a/src/assets/images/imdb.svg
+++ b/src/assets/images/imdb-icon.svg
diff --git a/src/assets/images/imgur.png b/src/assets/images/imgur-icon.png
index c23a45b2..c23a45b2 100644
--- a/src/assets/images/imgur.png
+++ b/src/assets/images/imgur-icon.png
Binary files differdiff --git a/src/assets/images/maps-icon.svg b/src/assets/images/maps-icon.svg
new file mode 100644
index 00000000..c66a89d1
--- /dev/null
+++ b/src/assets/images/maps-icon.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor">
+  <path d="M20.5 3l-.16.03L15 5.1 9 3 3.36 4.9c-.21.07-.36.25-.36.48V20.5c0 .28.22.5.5.5l.16-.03L9 18.9l6 2.1 5.64-1.9c.21-.07.36-.25.36-.48V3.5c0-.28-.22-.5-.5-.5zM10 5.47l4 1.4v11.66l-4-1.4V5.47zm-5 .99l3-1.01v11.7l-3 1.16V6.46zm14 11.08l-3 1.01V6.86l3-1.16v11.84z"></path>
+</svg>
diff --git a/src/assets/images/medium-icon.svg b/src/assets/images/medium-icon.svg
new file mode 100644
index 00000000..72612486
--- /dev/null
+++ b/src/assets/images/medium-icon.svg
@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1770 1000" fill="currentColor">
+  <circle cx="500" cy="500" r="500"></circle>
+  <ellipse ry="475" rx="250" cy="501" cx="1296"></ellipse>
+  <ellipse cx="1682" cy="502" rx="88" ry="424"></ellipse>
+</svg>
diff --git a/src/assets/images/quora.png b/src/assets/images/quora-icon.png
index d2a06954..d2a06954 100644
--- a/src/assets/images/quora.png
+++ b/src/assets/images/quora-icon.png
Binary files differdiff --git a/src/assets/images/reuters.svg b/src/assets/images/reuters-icon.svg
index aab389c3..aab389c3 100644
--- a/src/assets/images/reuters.svg
+++ b/src/assets/images/reuters-icon.svg
diff --git a/src/assets/images/search-icon.svg b/src/assets/images/search-icon.svg
new file mode 100644
index 00000000..cb73ff15
--- /dev/null
+++ b/src/assets/images/search-icon.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
+  <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
+</svg>
diff --git a/src/assets/images/send-icon.svg b/src/assets/images/send-icon.svg
deleted file mode 100644
index 2ed80a06..00000000
--- a/src/assets/images/send-icon.svg
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   width="33.866665mm"
-   height="33.866665mm"
-   viewBox="0 0 33.866665 33.866665"
-   version="1.1"
-   id="svg898"
-   sodipodi:docname="send-icon.svg"
-   inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:svg="http://www.w3.org/2000/svg">
-  <defs
-     id="defs7" />
-  <sodipodi:namedview
-     id="namedview5"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageshadow="2"
-     inkscape:pageopacity="0.0"
-     inkscape:pagecheckerboard="0"
-     inkscape:document-units="mm"
-     showgrid="false"
-     inkscape:zoom="2.6623698"
-     inkscape:cx="46.950653"
-     inkscape:cy="88.079425"
-     inkscape:window-width="1888"
-     inkscape:window-height="1060"
-     inkscape:window-x="32"
-     inkscape:window-y="0"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="svg898" />
-  <circle
-     style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.17791"
-     id="path1168"
-     cx="16.933332"
-     cy="16.933332"
-     r="16.933332" />
-  <g
-     id="layer1"
-     transform="matrix(0.36395732,0,0,0.36395732,5.286709,5.2870656)">
-    <path
-       id="cloud-upload"
-       d="m 64,34.286 a 17.033,17.033 0 0 1 -4.406,11.428 14.857,14.857 0 0 1 -10.558,4.572 h -2.179 v -6.857 h 2.179 a 8.004,8.004 0 0 0 5.468,-2.31 10.184,10.184 0 0 0 2.639,-6.833 11.442,11.442 0 0 0 -11.429,-11.429 c -0.377,0 -2.312,0.242 -3.49,0.394 A 1.136,1.136 0 0 1 41.003,22.487 L 40.537,21.13 A 14.103,14.103 0 0 0 28.821,11.498 13.666,13.666 0 0 0 14.091,28.277 l 0.489,2.087 a 1.143,1.143 0 0 1 -0.783,1.355 l -2.054,0.62 a 6.794,6.794 0 0 0 -4.886,6.518 4.604,4.604 0 0 0 0.947,2.808 5.539,5.539 0 0 0 4.089,1.764 h 5.25 v 6.857 h -5.25 A 12.236,12.236 0 0 1 2.213,45.634 11.506,11.506 0 0 1 0,38.857 13.573,13.573 0 0 1 6.944,26.973 19.51,19.51 0 0 1 6.857,25.143 20.563,20.563 0 0 1 45.844,16 18.307,18.307 0 0 1 64,34.286 Z M 32.923,32.123 a 1.143,1.143 0 0 0 -1.846,0 l -8.592,11.775 a 1.143,1.143 0 0 0 0.923,1.816 h 5.163 v 12.572 a 1.143,1.143 0 0 0 1.143,1.143 h 4.572 a 1.143,1.143 0 0 0 1.143,-1.143 V 45.714 h 5.163 a 1.143,1.143 0 0 0 0.923,-1.816 z"
-       stroke-width="2.286"
-       fill="#45a1ff"
-       fill-opacity="1" />
-  </g>
-</svg>
diff --git a/src/assets/images/sendFiles-icon.svg b/src/assets/images/sendFiles-icon.svg
new file mode 100644
index 00000000..5557664e
--- /dev/null
+++ b/src/assets/images/sendFiles-icon.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor">
+  <path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l5-5 5 5h-3z"></path>
+</svg>
diff --git a/src/assets/images/translate-icon.svg b/src/assets/images/translate-icon.svg
new file mode 100644
index 00000000..30f9c1b7
--- /dev/null
+++ b/src/assets/images/translate-icon.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="currentColor">
+  <path d="M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"></path>
+</svg>
diff --git a/src/assets/images/youtube-music-icon.png b/src/assets/images/youtubeMusic-icon.png
index a33df696..a33df696 100644
--- a/src/assets/images/youtube-music-icon.png
+++ b/src/assets/images/youtubeMusic-icon.png
Binary files differdiff --git a/src/assets/javascripts/general.js b/src/assets/javascripts/general.js
index a8360bd5..6eb0a454 100644
--- a/src/assets/javascripts/general.js
+++ b/src/assets/javascripts/general.js
@@ -1,17 +1,20 @@
 "use strict"
 window.browser = window.browser || window.chrome
 
+let exceptions
+
 function isException(url) {
 	for (const item of exceptions.url) if (item == `${url.protocol}//${url.host}`) return true
 	for (const item of exceptions.regex) if (new RegExp(item).test(url.href)) return true
 	return false
 }
 
-let exceptions
-
 function init() {
-	browser.storage.local.get("exceptions", r => {
-		exceptions = r.exceptions
+	return new Promise(resolve => {
+		browser.storage.local.get("options", r => {
+			if (r.options) exceptions = r.options.exceptions
+			resolve()
+		})
 	})
 }
 
@@ -22,46 +25,26 @@ async function initDefaults() {
 	return new Promise(resolve =>
 		browser.storage.local.set(
 			{
-				exceptions: {
-					url: [],
-					regex: [],
+				options: {
+					exceptions: {
+						url: [],
+						regex: [],
+					},
+					theme: "detect",
+					popupServices: ["youtube", "twitter", "instagram", "tiktok", "imgur", "reddit", "quora", "translate", "maps"],
+					autoRedirect: false,
+					firstPartyIsolate: false,
+					network: "clearnet",
+					networkFallback: true,
+					latencyThreshold: 1000,
 				},
-				theme: "DEFAULT",
-				popupFrontends: ["youtube", "twitter", "instagram", "tiktok", "imgur", "reddit", "quora", "translate", "maps"],
-				autoRedirect: false,
-				firstPartyIsolate: false,
-				protocol: "normal",
-				protocolFallback: true,
-				latencyThreshold: 1000,
 			},
 			() => resolve()
 		)
 	)
 }
 
-const allPopupFrontends = [
-	"youtube",
-	"youtubeMusic",
-	"twitter",
-	"instagram",
-	"tiktok",
-	"imgur",
-	"reddit",
-	"search",
-	"translate",
-	"maps",
-	"wikipedia",
-	"medium",
-	"quora",
-	"imdb",
-	"reuters",
-	"peertube",
-	"lbry",
-	"sendTargets",
-]
-
 export default {
 	isException,
 	initDefaults,
-	allPopupFrontends,
 }
diff --git a/src/assets/javascripts/get-localstorage.js b/src/assets/javascripts/get-localstorage.js
new file mode 100644
index 00000000..66740408
--- /dev/null
+++ b/src/assets/javascripts/get-localstorage.js
@@ -0,0 +1,15 @@
+window.browser = window.browser || window.chrome
+
+browser.storage.local.get(["localstorage", "tmp"], r => {
+	let localstorageJson = r.localstorage
+	const frontend = r.tmp[0]
+	const items = r.tmp[1]
+	localstorageJson[frontend] = {}
+
+	for (const item of items) {
+		let tmp = localStorage.getItem(item)
+		if (tmp) localstorageJson[frontend][item] = tmp
+	}
+
+	browser.storage.local.set({ localstorage: localstorageJson })
+})
diff --git a/src/assets/javascripts/imdb.js b/src/assets/javascripts/imdb.js
deleted file mode 100644
index 604e9a9e..00000000
--- a/src/assets/javascripts/imdb.js
+++ /dev/null
@@ -1,221 +0,0 @@
-window.browser = window.browser || window.chrome
-
-import utils from "./utils.js"
-
-const targets = [/^https?:\/{2}(?:www\.|)imdb\.com.*/]
-
-const frontends = new Array("libremdb")
-const protocols = new Array("normal", "tor", "i2p", "loki")
-
-let redirects = {}
-
-for (let i = 0; i < frontends.length; i++) {
-	redirects[frontends[i]] = {}
-	for (let x = 0; x < protocols.length; x++) {
-		redirects[frontends[i]][protocols[x]] = []
-	}
-}
-
-function setRedirects(val) {
-	return new Promise(resolve =>
-		browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
-			redirects.libremdb = val
-			libremdbNormalRedirectsChecks = [...redirects.libremdb.normal]
-			for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-				const a = libremdbNormalRedirectsChecks.indexOf(instance)
-				if (a > -1) libremdbNormalRedirectsChecks.splice(a, 1)
-			}
-			browser.storage.local.set(
-				{
-					imdbRedirects: redirects,
-					libremdbNormalRedirectsChecks,
-					libremdbTorRedirectsChecks: [...redirects.libremdb.tor],
-					libremdbI2pRedirectsChecks: [...redirects.libremdb.i2p],
-					libremdbLokiRedirectsChecks: [...redirects.libremdb.loki],
-				},
-				() => resolve()
-			)
-		})
-	)
-}
-
-let disableImdb,
-	protocol,
-	protocolFallback,
-	imdbRedirects,
-	libremdbNormalRedirectsChecks,
-	libremdbNormalCustomRedirects,
-	libremdbTorRedirectsChecks,
-	libremdbTorCustomRedirects,
-	libremdbI2pCustomRedirects,
-	libremdbLokiCustomRedirects
-
-function init() {
-	return new Promise(async resolve => {
-		browser.storage.local.get(
-			[
-				"disableImdb",
-				"protocol",
-				"protocolFallback",
-				"imdbRedirects",
-				"libremdbNormalRedirectsChecks",
-				"libremdbNormalCustomRedirects",
-				"libremdbTorRedirectsChecks",
-				"libremdbTorCustomRedirects",
-				"libremdbI2pCustomRedirects",
-				"libremdbLokiCustomRedirects",
-			],
-			r => {
-				disableImdb = r.disableImdb
-				protocol = r.protocol
-				protocolFallback = r.protocolFallback
-				imdbRedirects = r.imdbRedirects
-				libremdbNormalRedirectsChecks = r.libremdbNormalRedirectsChecks
-				libremdbNormalCustomRedirects = r.libremdbNormalCustomRedirects
-				libremdbTorRedirectsChecks = r.libremdbTorRedirectsChecks
-				libremdbTorCustomRedirects = r.libremdbTorCustomRedirects
-				libremdbI2pCustomRedirects = r.libremdbI2pCustomRedirects
-				libremdbLokiCustomRedirects = r.libremdbLokiCustomRedirects
-				resolve()
-			}
-		)
-	})
-}
-
-init()
-browser.storage.onChanged.addListener(init)
-
-function redirect(url, type, initiator, disableOverride) {
-	if (disableImdb && !disableOverride) return
-	if (url.pathname == "/") return
-	if (type != "main_frame") return
-	const all = [...imdbRedirects.libremdb.normal, ...libremdbNormalCustomRedirects]
-	if (initiator && (all.includes(initiator.origin) || targets.includes(initiator.host))) return
-	if (!targets.some(rx => rx.test(url.href))) return
-
-	let instancesList = []
-	if (protocol == "loki") instancesList = [...libremdbLokiCustomRedirects]
-	else if (protocol == "i2p") instancesList = [...libremdbI2pCustomRedirects]
-	else if (protocol == "tor") instancesList = [...libremdbTorRedirectsChecks, ...libremdbTorCustomRedirects]
-	if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-		instancesList = [...libremdbNormalRedirectsChecks, ...libremdbNormalCustomRedirects]
-	}
-	if (instancesList.length === 0) {
-		return
-	}
-
-	const randomInstance = utils.getRandomInstance(instancesList)
-	return `${randomInstance}${url.pathname}`
-}
-
-function reverse(url) {
-	return new Promise(async resolve => {
-		await init()
-		let protocolHost = utils.protocolHost(url)
-		const all = [
-			...imdbRedirects.libremdb.normal,
-			...imdbRedirects.libremdb.tor,
-			...libremdbNormalCustomRedirects,
-			...libremdbTorCustomRedirects,
-			...libremdbI2pCustomRedirects,
-			...libremdbLokiCustomRedirects,
-		]
-		if (!all.includes(protocolHost)) {
-			resolve()
-			return
-		}
-
-		resolve(`https://imdb.com${url.pathname}${url.search}`)
-	})
-}
-
-function switchInstance(url, disableOverride) {
-	return new Promise(async resolve => {
-		await init()
-		if (disableImdb && !disableOverride) {
-			resolve()
-			return
-		}
-		let protocolHost = utils.protocolHost(url)
-		const all = [
-			...imdbRedirects.libremdb.tor,
-			...imdbRedirects.libremdb.normal,
-
-			...libremdbNormalCustomRedirects,
-			...libremdbTorCustomRedirects,
-			...libremdbI2pCustomRedirects,
-			...libremdbLokiCustomRedirects,
-		]
-		if (!all.includes(protocolHost)) {
-			resolve()
-			return
-		}
-
-		let instancesList = []
-		if (protocol == "loki") instancesList = [...libremdbLokiCustomRedirects]
-		else if (protocol == "i2p") instancesList = [...libremdbI2pCustomRedirects]
-		else if (protocol == "tor") instancesList = [...libremdbTorRedirectsChecks, ...libremdbTorCustomRedirects]
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			instancesList = [...libremdbNormalRedirectsChecks, ...libremdbNormalCustomRedirects]
-		}
-
-		const i = instancesList.indexOf(protocolHost)
-		if (i > -1) instancesList.splice(i, 1)
-		if (instancesList.length === 0) {
-			resolve()
-			return
-		}
-
-		const randomInstance = utils.getRandomInstance(instancesList)
-		resolve(`${randomInstance}${url.pathname}${url.search}`)
-	})
-}
-
-function initDefaults() {
-	return new Promise(async resolve => {
-		fetch("/instances/data.json")
-			.then(response => response.text())
-			.then(async data => {
-				let dataJson = JSON.parse(data)
-				for (let i = 0; i < frontends.length; i++) {
-					redirects[frontends[i]] = dataJson[frontends[i]]
-				}
-				browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
-					libremdbNormalRedirectsChecks = [...redirects.libremdb.normal]
-					for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-						const a = libremdbNormalRedirectsChecks.indexOf(instance)
-						if (a > -1) libremdbNormalRedirectsChecks.splice(a, 1)
-					}
-					browser.storage.local.set(
-						{
-							disableImdb: true,
-							imdbRedirects: redirects,
-
-							libremdbNormalRedirectsChecks,
-							libremdbNormalCustomRedirects: [],
-
-							libremdbTorRedirectsChecks: [...redirects.libremdb.tor],
-							libremdbTorCustomRedirects: [],
-
-							libremdbI2pRedirectsChecks: [],
-							libremdbI2pCustomRedirects: [],
-
-							libremdbLokiRedirectsChecks: [],
-							libremdbLokiCustomRedirects: [],
-						},
-						() => resolve()
-					)
-				})
-			})
-	})
-}
-
-export default {
-	setRedirects,
-
-	redirect,
-	reverse,
-	switchInstance,
-
-	initDefaults,
-}
diff --git a/src/assets/javascripts/imgur.js b/src/assets/javascripts/imgur.js
deleted file mode 100644
index 24e8cb8d..00000000
--- a/src/assets/javascripts/imgur.js
+++ /dev/null
@@ -1,221 +0,0 @@
-window.browser = window.browser || window.chrome
-
-import utils from "./utils.js"
-
-const targets = /^https?:\/{2}([im]\.)?imgur\.(com|io)(\/|$)/
-
-const frontends = new Array("rimgo")
-const protocols = new Array("normal", "tor", "i2p", "loki")
-
-let redirects = {}
-
-for (let i = 0; i < frontends.length; i++) {
-	redirects[frontends[i]] = {}
-	for (let x = 0; x < protocols.length; x++) {
-		redirects[frontends[i]][protocols[x]] = []
-	}
-}
-
-function setRedirects(val) {
-	return new Promise(resolve =>
-		browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
-			redirects.rimgo = val
-			rimgoNormalRedirectsChecks = [...redirects.rimgo.normal]
-			for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-				const a = rimgoNormalRedirectsChecks.indexOf(instance)
-				if (a > -1) rimgoNormalRedirectsChecks.splice(a, 1)
-			}
-			browser.storage.local.set(
-				{
-					imgurRedirects: redirects,
-					rimgoNormalRedirectsChecks,
-					rimgoTorRedirectsChecks: [...redirects.rimgo.tor],
-					rimgoI2pRedirectsChecks: [...redirects.rimgo.i2p],
-					rimgoLokiRedirectsChecks: [...redirects.rimgo.loki],
-				},
-				() => resolve()
-			)
-		})
-	)
-}
-
-let disableImgur,
-	imgurRedirects,
-	protocol,
-	protocolFallback,
-	rimgoNormalRedirectsChecks,
-	rimgoNormalCustomRedirects,
-	rimgoTorRedirectsChecks,
-	rimgoTorCustomRedirects,
-	rimgoI2pRedirectsChecks,
-	rimgoI2pCustomRedirects,
-	rimgoLokiCustomRedirects
-
-function init() {
-	return new Promise(async resolve => {
-		browser.storage.local.get(
-			[
-				"disableImgur",
-				"imgurRedirects",
-				"protocol",
-				"protocolFallback",
-				"rimgoNormalRedirectsChecks",
-				"rimgoNormalCustomRedirects",
-				"rimgoTorRedirectsChecks",
-				"rimgoTorCustomRedirects",
-				"rimgoI2pRedirectsChecks",
-				"rimgoI2pCustomRedirects",
-				"rimgoLokiCustomRedirects",
-			],
-			r => {
-				disableImgur = r.disableImgur
-				imgurRedirects = r.imgurRedirects
-				protocol = r.protocol
-				protocolFallback = r.protocolFallback
-				rimgoNormalRedirectsChecks = r.rimgoNormalRedirectsChecks
-				rimgoNormalCustomRedirects = r.rimgoNormalCustomRedirects
-				rimgoTorRedirectsChecks = r.rimgoTorRedirectsChecks
-				rimgoTorCustomRedirects = r.rimgoTorCustomRedirects
-				rimgoI2pRedirectsChecks = r.rimgoI2pRedirectsChecks
-				rimgoI2pCustomRedirects = r.rimgoI2pCustomRedirects
-				rimgoLokiCustomRedirects = r.rimgoLokiCustomRedirects
-				resolve()
-			}
-		)
-	})
-}
-
-init()
-browser.storage.onChanged.addListener(init)
-
-// https://imgur.com/gallery/s4WXQmn
-// https://imgur.com/a/H8M4rcp
-// https://imgur.com/gallery/gYiQLWy
-// https://imgur.com/gallery/cTRwaJU
-// https://i.imgur.com/CFSQArP.jpeg
-
-function all() {
-	return [
-		...imgurRedirects.rimgo.normal,
-		...imgurRedirects.rimgo.tor,
-		...imgurRedirects.rimgo.i2p,
-		...rimgoNormalCustomRedirects,
-		...rimgoTorCustomRedirects,
-		...rimgoI2pCustomRedirects,
-		...rimgoLokiCustomRedirects,
-	]
-}
-
-function redirect(url, type, initiator, disableOverride) {
-	if (disableImgur && !disableOverride) return
-	if (url.pathname == "/" && !disableOverride) return
-	if (!["main_frame", "sub_frame", "xmlhttprequest", "other", "image", "media"].includes(type)) return
-	if (initiator && (all().includes(initiator.origin) || targets.test(initiator.host))) return
-	if (!targets.test(url.href)) return
-	if (url.pathname.includes("delete/")) return
-
-	let instancesList = []
-	if (protocol == "loki") instancesList = [...rimgoLokiCustomRedirects]
-	else if (protocol == "i2p") instancesList = [...rimgoI2pCustomRedirects, ...rimgoI2pRedirectsChecks]
-	else if (protocol == "tor") instancesList = [...rimgoTorRedirectsChecks, ...rimgoTorCustomRedirects]
-	if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-		instancesList = [...rimgoNormalRedirectsChecks, ...rimgoNormalCustomRedirects]
-	}
-	if (instancesList.length === 0) {
-		return
-	}
-
-	const randomInstance = utils.getRandomInstance(instancesList)
-	return `${randomInstance}${url.pathname}${url.search}`
-}
-
-function reverse(url) {
-	return new Promise(async resolve => {
-		await init()
-		const protocolHost = utils.protocolHost(url)
-		if (!all().includes(protocolHost)) {
-			resolve()
-			return
-		}
-		resolve(`https://imgur.com${url.pathname}${url.search}`)
-	})
-}
-
-function switchInstance(url, disableOverride) {
-	return new Promise(async resolve => {
-		await init()
-		if (disableImgur && !disableOverride) {
-			resolve()
-			return
-		}
-		let protocolHost = utils.protocolHost(url)
-		if (!all().includes(protocolHost)) {
-			resolve()
-			return
-		}
-		let instancesList = []
-		if (protocol == "loki") instancesList = [...rimgoLokiCustomRedirects]
-		else if (protocol == "i2p") instancesList = [...rimgoI2pCustomRedirects, ...rimgoI2pRedirectsChecks]
-		else if (protocol == "tor") instancesList = [...rimgoTorRedirectsChecks, ...rimgoTorCustomRedirects]
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			instancesList = [...rimgoNormalRedirectsChecks, ...rimgoNormalCustomRedirects]
-		}
-
-		const i = instancesList.indexOf(protocolHost)
-		if (i > -1) instancesList.splice(i, 1)
-		if (instancesList.length === 0) {
-			resolve()
-			return
-		}
-
-		const randomInstance = utils.getRandomInstance(instancesList)
-		resolve(`${randomInstance}${url.pathname}${url.search}`)
-	})
-}
-
-function initDefaults() {
-	return new Promise(resolve => {
-		fetch("/instances/data.json")
-			.then(response => response.text())
-			.then(async data => {
-				let dataJson = JSON.parse(data)
-				for (let i = 0; i < frontends.length; i++) {
-					redirects[frontends[i]] = dataJson[frontends[i]]
-				}
-				browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
-					rimgoNormalRedirectsChecks = [...redirects.rimgo.normal]
-					for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-						const a = rimgoNormalRedirectsChecks.indexOf(instance)
-						if (a > -1) rimgoNormalRedirectsChecks.splice(a, 1)
-					}
-					browser.storage.local.set(
-						{
-							disableImgur: false,
-							imgurRedirects: redirects,
-
-							rimgoNormalRedirectsChecks: rimgoNormalRedirectsChecks,
-							rimgoNormalCustomRedirects: [],
-
-							rimgoTorRedirectsChecks: [...redirects.rimgo.tor],
-							rimgoTorCustomRedirects: [],
-
-							rimgoI2pRedirectsChecks: [...redirects.rimgo.i2p],
-							rimgoI2pCustomRedirects: [],
-
-							rimgoLokiRedirectsChecks: [...redirects.rimgo.loki],
-							rimgoLokiCustomRedirects: [],
-						},
-						() => resolve()
-					)
-				})
-			})
-	})
-}
-
-export default {
-	setRedirects,
-	redirect,
-	reverse,
-	initDefaults,
-	switchInstance,
-}
diff --git a/src/assets/javascripts/instagram.js b/src/assets/javascripts/instagram.js
deleted file mode 100644
index bc580de7..00000000
--- a/src/assets/javascripts/instagram.js
+++ /dev/null
@@ -1,249 +0,0 @@
-window.browser = window.browser || window.chrome
-import utils from "./utils.js"
-
-const targets = ["instagram.com", "www.instagram.com"]
-
-const frontends = new Array("bibliogram")
-const protocols = new Array("normal", "tor", "i2p", "loki")
-
-let redirects = {}
-
-for (let i = 0; i < frontends.length; i++) {
-	redirects[frontends[i]] = {}
-	for (let x = 0; x < protocols.length; x++) {
-		redirects[frontends[i]][protocols[x]] = []
-	}
-}
-
-function setRedirects(val) {
-	return new Promise(resolve =>
-		browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
-			redirects.bibliogram = val
-			bibliogramNormalRedirectsChecks = [...redirects.bibliogram.normal]
-			for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-				const a = bibliogramNormalRedirectsChecks.indexOf(instance)
-				if (a > -1) bibliogramNormalRedirectsChecks.splice(a, 1)
-			}
-			browser.storage.local.set(
-				{
-					instagramRedirects: redirects,
-					bibliogramNormalRedirectsChecks,
-					bibliogramTorRedirectsChecks: [...redirects.bibliogram.tor],
-					bibliogramI2pRedirectsChecks: [...redirects.bibliogram.i2p],
-					bibliogramLokiRedirectsChecks: [...redirects.bibliogram.loki],
-				},
-				() => resolve()
-			)
-		})
-	)
-}
-
-let disableInstagram,
-	protocol,
-	protocolFallback,
-	instagramRedirects,
-	bibliogramNormalRedirectsChecks,
-	bibliogramTorRedirectsChecks,
-	bibliogramNormalCustomRedirects,
-	bibliogramTorCustomRedirects,
-	bibliogramI2pCustomRedirects,
-	bibliogramLokiCustomRedirects
-
-function init() {
-	return new Promise(async resolve => {
-		browser.storage.local.get(
-			[
-				"disableInstagram",
-				"protocol",
-				"protocolFallback",
-				"instagramRedirects",
-				"bibliogramNormalRedirectsChecks",
-				"bibliogramTorRedirectsChecks",
-				"bibliogramNormalCustomRedirects",
-				"bibliogramTorCustomRedirects",
-				"bibliogramI2pCustomRedirects",
-				"bibliogramLokiCustomRedirects",
-			],
-			r => {
-				disableInstagram = r.disableInstagram
-				protocol = r.protocol
-				protocolFallback = r.protocolFallback
-				instagramRedirects = r.instagramRedirects
-				bibliogramNormalRedirectsChecks = r.bibliogramNormalRedirectsChecks
-				bibliogramTorRedirectsChecks = r.bibliogramTorRedirectsChecks
-				bibliogramNormalCustomRedirects = r.bibliogramNormalCustomRedirects
-				bibliogramTorCustomRedirects = r.bibliogramTorCustomRedirects
-				bibliogramI2pCustomRedirects = r.bibliogramI2pCustomRedirects
-				bibliogramLokiCustomRedirects = r.bibliogramLokiCustomRedirects
-				resolve()
-			}
-		)
-	})
-}
-
-init()
-browser.storage.onChanged.addListener(init)
-
-function initBibliogramPreferences(test, from) {
-	return new Promise(async resolve => {
-		await init()
-		const protocolHost = utils.protocolHost(from)
-		if (
-			![
-				...bibliogramNormalRedirectsChecks,
-				...bibliogramTorRedirectsChecks,
-				...bibliogramNormalCustomRedirects,
-				...bibliogramTorCustomRedirects,
-				...bibliogramI2pCustomRedirects,
-				...bibliogramLokiCustomRedirects,
-			].includes(protocolHost)
-		) {
-			resolve()
-			return
-		}
-
-		if (!test) {
-			let checkedInstances = []
-			if (protocol == "loki") checkedInstances = [...bibliogramLokiCustomRedirects]
-			else if (protocol == "i2p") checkedInstances = [...bibliogramI2pCustomRedirects]
-			else if (protocol == "tor") checkedInstances = [...bibliogramTorRedirectsChecks, ...bibliogramTorCustomRedirects]
-			if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
-				checkedInstances = [...bibliogramNormalRedirectsChecks, ...bibliogramNormalCustomRedirects]
-			}
-			await utils.getPreferencesFromToken("bibliogram", from, checkedInstances, "settings", "settings.json")
-		}
-		resolve(true)
-	})
-}
-
-function all() {
-	return [
-		...bibliogramNormalRedirectsChecks,
-		...bibliogramTorRedirectsChecks,
-		...bibliogramNormalCustomRedirects,
-		...bibliogramTorCustomRedirects,
-		...bibliogramI2pCustomRedirects,
-		...bibliogramLokiCustomRedirects,
-	]
-}
-
-function redirect(url, type, initiator, disableOverride) {
-	if (disableInstagram && !disableOverride) return
-	if (!targets.includes(url.host)) return
-	if (initiator && all().includes(initiator.origin)) return "BYPASSTAB"
-	if (!["main_frame", "sub_frame", "xmlhttprequest", "other", "image", "media"].includes(type)) return
-
-	const bypassPaths = [/about/, /explore/, /support/, /press/, /api/, /privacy/, /safety/, /admin/, /\/(accounts\/|embeds?.js)/]
-	if (bypassPaths.some(rx => rx.test(url.pathname))) return
-
-	let instancesList = []
-	if (protocol == "loki") instancesList = [...bibliogramLokiCustomRedirects]
-	else if (protocol == "i2p") instancesList = [...bibliogramI2pCustomRedirects]
-	else if (protocol == "tor") instancesList = [...bibliogramTorRedirectsChecks, ...bibliogramTorCustomRedirects]
-	if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-		instancesList = [...bibliogramNormalRedirectsChecks, ...bibliogramNormalCustomRedirects]
-	}
-	if (instancesList.length === 0) {
-		return
-	}
-	let randomInstance = utils.getRandomInstance(instancesList)
-
-	const reservedPaths = ["u", "p", "privacy"]
-	if (url.pathname === "/" || reservedPaths.includes(url.pathname.split("/")[1])) return `${randomInstance}${url.pathname}${url.search}`
-	if (url.pathname.startsWith("/reel") || url.pathname.startsWith("/tv")) return `${randomInstance}/p${url.pathname.replace(/\/reel|\/tv/i, "")}${url.search}`
-	else return `${randomInstance}/u${url.pathname}${url.search}` // Likely a user profile, redirect to '/u/...'
-}
-
-function reverse(url) {
-	return new Promise(async resolve => {
-		await init()
-		const protocolHost = utils.protocolHost(url)
-		if (!all().includes(protocolHost)) {
-			resolve()
-			return
-		}
-
-		if (url.pathname.startsWith("/p")) resolve(`https://instagram.com${url.pathname.replace("/p", "")}${url.search}`)
-		if (url.pathname.startsWith("/u")) resolve(`https://instagram.com${url.pathname.replace("/u", "")}${url.search}`)
-		resolve(`https://instagram.com${url.pathname}${url.search}`)
-	})
-}
-
-function switchInstance(url, disableOverride) {
-	return new Promise(async resolve => {
-		await init()
-		if (disableInstagram && !disableOverride) {
-			resolve()
-			return
-		}
-		let protocolHost = utils.protocolHost(url)
-		if (!all().includes(protocolHost)) {
-			resolve()
-			return
-		}
-
-		let instancesList = []
-		if (protocol == "loki") instancesList = [...bibliogramLokiCustomRedirects]
-		else if (protocol == "i2p") instancesList = [...bibliogramI2pCustomRedirects]
-		else if (protocol == "tor") instancesList = [...bibliogramTorRedirectsChecks, ...bibliogramTorCustomRedirects]
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			instancesList = [...bibliogramNormalRedirectsChecks, ...bibliogramNormalCustomRedirects]
-		}
-
-		const i = instancesList.indexOf(protocolHost)
-		if (i > -1) instancesList.splice(i, 1)
-		if (instancesList.length === 0) {
-			resolve()
-			return
-		}
-
-		const randomInstance = utils.getRandomInstance(instancesList)
-		resolve(`${randomInstance}${url.pathname}${url.search}`)
-	})
-}
-
-function initDefaults() {
-	return new Promise(resolve => {
-		fetch("/instances/data.json")
-			.then(response => response.text())
-			.then(data => {
-				let dataJson = JSON.parse(data)
-				for (let i = 0; i < frontends.length; i++) {
-					redirects[frontends[i]] = dataJson[frontends[i]]
-				}
-				browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
-					bibliogramNormalRedirectsChecks = [...redirects.bibliogram.normal]
-					for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-						const a = bibliogramNormalRedirectsChecks.indexOf(instance)
-						if (a > -1) bibliogramNormalRedirectsChecks.splice(a, 1)
-					}
-					browser.storage.local.set({
-						disableInstagram: false,
-						instagramRedirects: redirects,
-
-						bibliogramNormalRedirectsChecks,
-						bibliogramNormalCustomRedirects: [],
-
-						bibliogramTorRedirectsChecks: [...redirects.bibliogram.tor],
-						bibliogramTorCustomRedirects: [],
-
-						bibliogramI2pRedirectsChecks: [...redirects.bibliogram.i2p],
-						bibliogramI2pCustomRedirects: [],
-
-						bibliogramLokiRedirectsChecks: [...redirects.bibliogram.loki],
-						bibliogramLokiCustomRedirects: [],
-					})
-					resolve()
-				})
-			})
-	})
-}
-
-export default {
-	setRedirects,
-	initBibliogramPreferences,
-	reverse,
-	redirect,
-	initDefaults,
-	switchInstance,
-}
diff --git a/src/assets/javascripts/lbry.js b/src/assets/javascripts/lbry.js
deleted file mode 100644
index 698517a9..00000000
--- a/src/assets/javascripts/lbry.js
+++ /dev/null
@@ -1,223 +0,0 @@
-window.browser = window.browser || window.chrome
-
-import utils from "./utils.js"
-
-const targets = [/^https?:\/{2}odysee\.com/]
-
-const frontends = new Array("librarian")
-const protocols = new Array("normal", "tor", "i2p", "loki")
-
-let redirects = {}
-
-for (let i = 0; i < frontends.length; i++) {
-	redirects[frontends[i]] = {}
-	for (let x = 0; x < protocols.length; x++) {
-		redirects[frontends[i]][protocols[x]] = []
-	}
-}
-
-function setRedirects(val) {
-	return new Promise(resolve =>
-		browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
-			redirects.librarian = val
-			librarianNormalRedirectsChecks = [...redirects.librarian.normal]
-			for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-				const a = librarianNormalRedirectsChecks.indexOf(instance)
-				if (a > -1) librarianNormalRedirectsChecks.splice(a, 1)
-			}
-			browser.storage.local.set(
-				{
-					lbryTargetsRedirects: redirects,
-					librarianNormalRedirectsChecks,
-					librarianTorRedirectsChecks: [...redirects.librarian.tor],
-					librarianI2pRedirectsChecks: [...redirects.librarian.i2p],
-					librarianLokiRedirectsChecks: [...redirects.librarian.loki],
-				},
-				() => resolve()
-			)
-		})
-	)
-}
-
-let disableLbryTargets,
-	lbryFrontend,
-	protocol,
-	protocolFallback,
-	lbryTargetsRedirects,
-	lbryRedirectType,
-	librarianNormalRedirectsChecks,
-	librarianNormalCustomRedirects,
-	librarianTorRedirectsChecks,
-	librarianTorCustomRedirects,
-	librarianI2pRedirectsChecks,
-	librarianI2pCustomRedirects,
-	librarianLokiCustomRedirects
-
-function init() {
-	return new Promise(resolve => {
-		browser.storage.local.get(
-			[
-				"disableLbryTargets",
-				"lbryFrontend",
-				"protocol",
-				"protocolFallback",
-				"lbryTargetsRedirects",
-				"lbryRedirectType",
-				"librarianNormalRedirectsChecks",
-				"librarianNormalCustomRedirects",
-				"librarianTorRedirectsChecks",
-				"librarianTorCustomRedirects",
-				"librarianI2pRedirectsChecks",
-				"librarianI2pCustomRedirects",
-				"librarianLokiCustomRedirects",
-			],
-			r => {
-				disableLbryTargets = r.disableLbryTargets
-				lbryFrontend = r.lbryFrontend
-				protocol = r.protocol
-				protocolFallback = r.protocolFallback
-				lbryTargetsRedirects = r.lbryTargetsRedirects
-				lbryRedirectType = r.lbryRedirectType
-				librarianNormalRedirectsChecks = r.librarianNormalRedirectsChecks
-				librarianNormalCustomRedirects = r.librarianNormalCustomRedirects
-				librarianTorRedirectsChecks = r.librarianTorRedirectsChecks
-				librarianTorCustomRedirects = r.librarianTorCustomRedirects
-				librarianI2pRedirectsChecks = r.librarianI2pRedirectsChecks
-				librarianI2pCustomRedirects = r.librarianI2pCustomRedirects
-				librarianLokiCustomRedirects = r.librarianLokiCustomRedirects
-				resolve()
-			}
-		)
-	})
-}
-init()
-browser.storage.onChanged.addListener(init)
-
-function all() {
-	return [...redirects.librarian.normal, ...redirects.librarian.tor, ...librarianNormalCustomRedirects, ...librarianTorCustomRedirects, ...librarianI2pCustomRedirects, ...librarianLokiCustomRedirects]
-}
-
-function getInstancesList() {
-	let tmpList = []
-	switch (protocol) {
-		case "loki":
-			tmpList = [...librarianLokiCustomRedirects]
-			break
-		case "i2p":
-			tmpList = [...librarianI2pRedirectsChecks, ...librarianI2pCustomRedirects]
-			break
-		case "tor":
-			tmpList = [...librarianTorRedirectsChecks, ...librarianTorCustomRedirects]
-	}
-	if ((tmpList.length === 0 && protocolFallback) || protocol == "normal") {
-		tmpList = [...librarianNormalRedirectsChecks, ...librarianNormalCustomRedirects]
-	}
-	return tmpList
-}
-
-function switchInstance(url, disableOverride) {
-	return new Promise(async resolve => {
-		await init()
-		if (disableLbryTargets && !disableOverride) {
-			resolve()
-			return
-		}
-		const protocolHost = utils.protocolHost(url)
-		if (!all().includes(protocolHost)) {
-			resolve()
-			return
-		}
-
-		let instancesList = []
-		if (protocol == "loki") instancesList = [...librarianLokiCustomRedirects]
-		else if (protocol == "i2p") instancesList = [...librarianI2pCustomRedirects]
-		else if (protocol == "tor") instancesList = [...librarianTorRedirectsChecks, ...librarianTorCustomRedirects]
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			instancesList = [...librarianNormalRedirectsChecks, ...librarianNormalCustomRedirects]
-		}
-
-		const i = instancesList.indexOf(protocolHost)
-		if (i > -1) instancesList.splice(i, 1)
-		if (instancesList.length === 0) {
-			resolve()
-			return
-		}
-
-		const randomInstance = utils.getRandomInstance(instancesList)
-		resolve(`${randomInstance}${url.pathname}${url.search}`)
-	})
-}
-
-function redirect(url, type, initiator, disableOverride) {
-	if (disableLbryTargets && !disableOverride) return
-	if (initiator && (all().includes(initiator.origin) || targets.includes(initiator.host))) return
-	if (!targets.some(rx => rx.test(url.href))) return
-	if (type == "sub_frame" && lbryRedirectType == "main_frame") return
-
-	const instancesList = getInstancesList()
-	switch (type) {
-		case "main_frame":
-			switch (lbryFrontend) {
-				case "librarian":
-					if (instancesList.length === 0) return
-					const randomInstance = utils.getRandomInstance(instancesList)
-					return `${randomInstance}${url.pathname}${url.search}`
-				case "lbryDesktop":
-					if (type == "main_frame") {
-						return url.href.replace(/^https?:\/{2}odysee\.com\//, "lbry://").replace(/:(?=[a-zA-Z0-9])/g, "#")
-					}
-			}
-		case "sub_frame":
-			if (instancesList.length === 0) return
-			const randomInstance = utils.getRandomInstance(instancesList)
-			return `${randomInstance}${url.pathname}${url.search}`.replace(/\/(?=[a-f0-9]{40})/, ":")
-	}
-}
-
-function initDefaults() {
-	return new Promise(async resolve => {
-		fetch("/instances/data.json")
-			.then(response => response.text())
-			.then(async data => {
-				let dataJson = JSON.parse(data)
-				for (let i = 0; i < frontends.length; i++) {
-					redirects[frontends[i]] = dataJson[frontends[i]]
-				}
-				browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
-					librarianNormalRedirectsChecks = [...redirects.librarian.normal]
-					for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-						const a = librarianNormalRedirectsChecks.indexOf(instance)
-						if (a > -1) librarianNormalRedirectsChecks.splice(a, 1)
-					}
-					browser.storage.local.set(
-						{
-							disableLbryTargets: true,
-							lbryFrontend: "librarian",
-							lbryTargetsRedirects: redirects,
-							lbryRedirectType: "both",
-
-							librarianNormalRedirectsChecks,
-							librarianNormalCustomRedirects: [],
-
-							librarianTorRedirectsChecks: [...redirects.librarian.tor],
-							librarianTorCustomRedirects: [],
-
-							librarianI2pRedirectsChecks: [...redirects.librarian.i2p],
-							librarianI2pCustomRedirects: [],
-
-							librarianLokiRedirectsChecks: [...redirects.librarian.loki],
-							librarianLokiCustomRedirects: [],
-						},
-						() => resolve()
-					)
-				})
-			})
-	})
-}
-
-export default {
-	setRedirects,
-	switchInstance,
-	redirect,
-	initDefaults,
-}
diff --git a/src/assets/javascripts/maps.js b/src/assets/javascripts/maps.js
deleted file mode 100644
index 6911c9ba..00000000
--- a/src/assets/javascripts/maps.js
+++ /dev/null
@@ -1,309 +0,0 @@
-"use strict"
-
-window.browser = window.browser || window.chrome
-import utils from "./utils.js"
-
-const targets = /^https?:\/{2}(((www|maps)\.)?(google\.).*(\/maps)|maps\.(google\.).*)/
-
-const frontends = new Array("facil")
-const protocols = new Array("normal", "tor", "i2p", "loki")
-
-let redirects = {}
-
-for (let i = 0; i < frontends.length; i++) {
-	redirects[frontends[i]] = {}
-	for (let x = 0; x < protocols.length; x++) {
-		redirects[frontends[i]][protocols[x]] = []
-	}
-}
-
-redirects.osm = {}
-redirects.osm.normal = ["https://www.openstreetmap.org"]
-
-function setRedirects(val) {
-	return new Promise(resolve =>
-		browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
-			redirects.facil = val
-			facilNormalRedirectsChecks = [...redirects.facil.normal]
-			for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-				const a = facilNormalRedirectsChecks.indexOf(instance)
-				if (a > -1) facilNormalRedirectsChecks.splice(a, 1)
-			}
-			browser.storage.local.set(
-				{
-					mapsRedirects: redirects,
-					facilNormalRedirectsChecks,
-					facilTorRedirectsChecks: [...redirects.facil.tor],
-					facilI2pRedirectsChecks: [...redirects.facil.i2p],
-					facilLokiRedirectsChecks: [...redirects.facil.loki],
-				},
-				() => resolve()
-			)
-		})
-	)
-}
-
-let disableMaps,
-	mapsFrontend,
-	protocol,
-	protocolFallback,
-	facilNormalRedirectsChecks,
-	facilNormalCustomRedirects,
-	facilTorRedirectsChecks,
-	facilTorCustomRedirects,
-	facilI2pRedirectsChecks,
-	facilI2pCustomRedirects,
-	facilLokiRedirectsChecks,
-	facilLokiCustomRedirects
-
-function init() {
-	browser.storage.local.get(
-		[
-			"disableMaps",
-			"mapsFrontend",
-			"protocol",
-			"protocolFallback",
-			"facilNormalRedirectsChecks",
-			"facilNormalCustomRedirects",
-			"facilTorRedirectsChecks",
-			"facilTorCustomRedirects",
-			"facilI2pRedirectsChecks",
-			"facilI2pCustomRedirects",
-			"facilLokiRedirectsChecks",
-			"facilLokiCustomRedirects",
-		],
-		r => {
-			disableMaps = r.disableMaps
-			mapsFrontend = r.mapsFrontend
-			protocol = r.protocol
-			protocolFallback = r.protocolFallback
-			facilNormalRedirectsChecks = r.facilNormalRedirectsChecks
-			facilNormalCustomRedirects = r.facilNormalCustomRedirects
-			facilTorRedirectsChecks = r.facilTorRedirectsChecks
-			facilTorCustomRedirects = r.facilTorCustomRedirects
-			facilI2pRedirectsChecks = r.facilI2pRedirectsChecks
-			facilI2pCustomRedirects = r.facilI2pCustomRedirects
-			facilLokiRedirectsChecks = r.facilLokiRedirectsChecks
-			facilLokiCustomRedirects = r.facilLokiCustomRedirects
-		}
-	)
-}
-
-init()
-browser.storage.onChanged.addListener(init)
-
-function redirect(url, initiator) {
-	if (disableMaps) return
-	if (initiator && initiator.host === "earth.google.com") return
-	if (!url.href.match(targets)) return
-	const mapCentreRegex = /@(-?\d[0-9.]*),(-?\d[0-9.]*),(\d{1,2})[.z]/
-	const dataLatLngRegex = /!3d(-?[0-9]{1,}.[0-9]{1,})!4d(-?[0-9]{1,}.[0-9]{1,})/
-	const placeRegex = /\/place\/(.*)\//
-	const travelModes = {
-		driving: "fossgis_osrm_car",
-		walking: "fossgis_osrm_foot",
-		bicycling: "fossgis_osrm_bike",
-		transit: "fossgis_osrm_car", // not implemented on OSM, default to car.
-	}
-	const travelModesFacil = {
-		driving: "car",
-		walking: "pedestrian",
-		bicycling: "bicycle",
-		transit: "car", // not implemented on Facil, default to car.
-	}
-	const osmLayers = {
-		none: "S",
-		transit: "T",
-		traffic: "S", // not implemented on OSM, default to standard.
-		bicycling: "C",
-	}
-	function addressToLatLng(address) {
-		const xmlhttp = new XMLHttpRequest()
-		xmlhttp.open("GET", `https://nominatim.openstreetmap.org/search/${address}?format=json&limit=1`, false)
-		xmlhttp.send()
-		if (xmlhttp.status === 200) {
-			const json = JSON.parse(xmlhttp.responseText)[0]
-			if (json) {
-				console.log("json", json)
-				return [`${json.lat},${json.lon}`, `${json.boundingbox[2]},${json.boundingbox[1]},${json.boundingbox[3]},${json.boundingbox[0]}`]
-			}
-		}
-		console.info("Error: Status is " + xmlhttp.status)
-	}
-
-	let instancesList
-	switch (mapsFrontend) {
-		case "osm":
-			instancesList = [...redirects.osm.normal]
-			break
-		case "facil":
-			switch (protocol) {
-				case "loki":
-					instancesList = [...facilLokiRedirectsChecks, ...facilLokiCustomRedirects]
-					break
-				case "i2p":
-					instancesList = [...facilI2pRedirectsChecks, ...facilI2pCustomRedirects]
-					break
-				case "tor":
-					instancesList = [...facilTorRedirectsChecks, ...facilTorCustomRedirects]
-			}
-			if ((instancesList == "" && protocolFallback) || protocol == "normal") {
-				instancesList = [...facilNormalRedirectsChecks, ...facilNormalCustomRedirects]
-			}
-	}
-	const randomInstance = utils.getRandomInstance(instancesList)
-
-	let mapCentre = "#"
-	let prefs = {}
-
-	if (url.pathname.match(mapCentreRegex)) {
-		// Set map centre if present
-		var [, lat, lon, zoom] = url.pathname.match(mapCentreRegex)
-	} else if (url.searchParams.has("center")) {
-		var [lat, lon] = url.searchParams.get("center").split(",")
-		var zoom = url.searchParams.get("zoom") ?? "17"
-	}
-
-	if (lat && lon && zoom) {
-		if (mapsFrontend == "osm") mapCentre = `#map=${zoom}/${lat}/${lon}`
-		if (mapsFrontend == "facil") mapCentre = `#${zoom}/${lat}/${lon}`
-	}
-
-	if (url.searchParams.get("layer")) prefs.layers = osmLayers[url.searchParams.get("layer")]
-
-	if (url.pathname.includes("/embed")) {
-		// Handle Google Maps Embed API
-		// https://www.google.com/maps/embed/v1/place?key=AIzaSyD4iE2xVSpkLLOXoyqT-RuPwURN3ddScAI&q=Eiffel+Tower,Paris+France
-		console.log("embed life")
-
-		let query = ""
-		if (url.searchParams.has("q")) query = url.searchParams.get("q")
-		else if (url.searchParams.has("query")) query = url.searchParams.has("query")
-		else if (url.searchParams.has("pb"))
-			try {
-				query = url.searchParams.get("pb").split(/!2s(.*?)!/)[1]
-			} catch (error) {
-				console.error(error)
-			} // Unable to find map marker in URL.
-
-		let [coords, boundingbox] = addressToLatLng(query)
-		prefs.bbox = boundingbox
-		prefs.marker = coords
-		prefs.layer = "mapnik"
-		let prefsEncoded = new URLSearchParams(prefs).toString()
-		if (mapsFrontend == "osm") return `${randomInstance}/export/embed.html?${prefsEncoded}`
-		if (mapsFrontend == "facil") return `${randomInstance}/#q=${query}`
-	} else if (url.pathname.includes("/dir")) {
-		// Handle Google Maps Directions
-		// https://www.google.com/maps/dir/?api=1&origin=Space+Needle+Seattle+WA&destination=Pike+Place+Market+Seattle+WA&travelmode=bicycling
-
-		let travMod = url.searchParams.get("travelmode")
-		if (url.searchParams.has("travelmode")) prefs.engine = travelModes[travMod]
-
-		let orgVal = url.searchParams.get("origin")
-		let destVal = url.searchParams.get("destination")
-
-		let org
-		addressToLatLng(orgVal, a => (org = a))
-		let dest
-		addressToLatLng(destVal, a => (dest = a))
-		prefs.route = `${org};${dest}`
-
-		let prefsEncoded = new URLSearchParams(prefs).toString()
-		if (mapsFrontend == "osm") return `${randomInstance}/directions?${prefsEncoded}${mapCentre}`
-		if (mapsFrontend == "facil") return `${randomInstance}/#q=${orgVal}%20to%20${destVal}%20by%20${travelModesFacil[travMod]}`
-	} else if (url.pathname.includes("data=") && url.pathname.match(dataLatLngRegex)) {
-		// Get marker from data attribute
-		// https://www.google.com/maps/place/41%C2%B001'58.2%22N+40%C2%B029'18.2%22E/@41.032833,40.4862063,17z/data=!3m1!4b1!4m6!3m5!1s0x0:0xf64286eaf72fc49d!7e2!8m2!3d41.0328329!4d40.4883948
-		console.log("data life")
-
-		let [, mlat, mlon] = url.pathname.match(dataLatLngRegex)
-
-		if (mapsFrontend == "osm") return `${randomInstance}/search?query=${mlat}%2C${mlon}`
-		if (mapsFrontend == "facil") return `${randomInstance}/#q=${mlat}%2C${mlon}`
-	} else if (url.searchParams.has("ll")) {
-		// Get marker from ll param
-		// https://maps.google.com/?ll=38.882147,-76.99017
-		console.log("ll life")
-
-		const [mlat, mlon] = url.searchParams.get("ll").split(",")
-
-		if (mapsFrontend == "osm") return `${randomInstance}/search?query=${mlat}%2C${mlon}`
-		if (mapsFrontend == "facil") return `${randomInstance}/#q=${mlat}%2C${mlon}`
-	} else if (url.searchParams.has("viewpoint")) {
-		// Get marker from viewpoint param.
-		// https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=48.857832,2.295226&heading=-45&pitch=38&fov=80
-		console.log("viewpoint life")
-
-		const [mlat, mlon] = url.searchParams.get("viewpoint").split(",")
-
-		if (mapsFrontend == "osm") return `${randomInstance}/search?query=${mlat}%2C${mlon}`
-		if (mapsFrontend == "facil") return `${randomInstance}/#q=${mlat}%2C${mlon}`
-	} else {
-		// Use query as search if present.
-		console.log("normal life")
-
-		let query
-		if (url.searchParams.has("q")) query = url.searchParams.get("q")
-		else if (url.searchParams.has("query")) query = url.searchParams.get("query")
-		else if (url.pathname.match(placeRegex)) query = url.pathname.match(placeRegex)[1]
-
-		let prefsEncoded = new URLSearchParams(prefs).toString()
-		if (query) {
-			if (mapsFrontend == "osm") return `${randomInstance}/search?query="${query}${mapCentre}&${prefsEncoded}`
-			if (mapsFrontend == "facil") return `${randomInstance}/${mapCentre}/Mpnk/${query}`
-		}
-	}
-
-	let prefsEncoded = new URLSearchParams(prefs).toString()
-	console.log("mapCentre", mapCentre)
-	console.log("prefs", prefs)
-	console.log("prefsEncoded", prefsEncoded)
-	if (mapsFrontend == "osm") return `${randomInstance}/${mapCentre}&${prefsEncoded}`
-	if (mapsFrontend == "facil") return `${randomInstance}/${mapCentre}/Mpnk`
-}
-
-function initDefaults() {
-	return new Promise(async resolve => {
-		fetch("/instances/data.json")
-			.then(response => response.text())
-			.then(async data => {
-				let dataJson = JSON.parse(data)
-				for (let i = 0; i < frontends.length; i++) {
-					redirects[frontends[i]] = dataJson[frontends[i]]
-				}
-				browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
-					facilNormalRedirectsChecks = [...redirects.facil.normal]
-					for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-						const a = facilNormalRedirectsChecks.indexOf(instance)
-						if (a > -1) facilNormalRedirectsChecks.splice(a, 1)
-					}
-					browser.storage.local.set(
-						{
-							disableMaps: false,
-							mapsFrontend: "osm",
-							mapsRedirects: redirects,
-							facilNormalRedirectsChecks,
-							facilNormalCustomRedirects: [],
-
-							facilTorRedirectsChecks: [...redirects.facil.tor],
-							facilTorCustomRedirects: [],
-
-							facilI2pRedirectsChecks: [...redirects.facil.i2p],
-							facilI2pCustomRedirects: [],
-
-							facilLokiRedirectsChecks: [...redirects.facil.loki],
-							facilLokiCustomRedirects: [],
-						},
-						() => resolve()
-					)
-				})
-			})
-	})
-}
-
-export default {
-	setRedirects,
-	redirect,
-	initDefaults,
-}
diff --git a/src/assets/javascripts/medium.js b/src/assets/javascripts/medium.js
deleted file mode 100644
index 386d234c..00000000
--- a/src/assets/javascripts/medium.js
+++ /dev/null
@@ -1,227 +0,0 @@
-window.browser = window.browser || window.chrome
-import utils from "./utils.js"
-
-const targets = [
-	// /(?:.*\.)*(?<!(link\.|cdn\-images\-\d+\.))medium\.com(\/.*)?$/,
-	/^medium\.com/,
-	/.*\.medium\.com/,
-	// // Other domains of medium blogs, source(s): https://findingtom.com/best-medium-blogs-to-follow/#1-forge
-
-	/^towardsdatascience\.com/,
-	/^uxdesign\.cc/,
-	/^uxplanet\.org/,
-	/^betterprogramming\.pub/,
-	/^aninjusticemag\.com/,
-	/^betterhumans\.pub/,
-	/^psiloveyou\.xyz/,
-	/^entrepreneurshandbook\.co/,
-	/^blog\.coinbase\.com/,
-
-	/^ levelup\.gitconnected\.com /,
-	/^javascript\.plainenglish\.io /,
-	/^blog\.bitsrc\.io /,
-	/^ itnext\.io /,
-	/^codeburst\.io /,
-	/^infosecwriteups\.com /,
-	/^ blog\.devgenius.io /,
-	/^ writingcooperative\.com /,
-]
-
-const frontends = new Array("scribe")
-const protocols = new Array("normal", "tor", "i2p", "loki")
-
-let redirects = {}
-
-for (let i = 0; i < frontends.length; i++) {
-	redirects[frontends[i]] = {}
-	for (let x = 0; x < protocols.length; x++) {
-		redirects[frontends[i]][protocols[x]] = []
-	}
-}
-
-function setRedirects(val) {
-	return new Promise(resolve =>
-		browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
-			redirects.scribe = val
-			scribeNormalRedirectsChecks = [...redirects.scribe.normal]
-			for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-				const a = scribeNormalRedirectsChecks.indexOf(instance)
-				if (a > -1) scribeNormalRedirectsChecks.splice(a, 1)
-			}
-			browser.storage.local.set(
-				{
-					mediumRedirects: redirects,
-					scribeNormalRedirectsChecks,
-					scribeTorRedirectsChecks: [...redirects.scribe.tor],
-					scribeI2pRedirectsChecks: [...redirects.scribe.i2p],
-					scribeLokiRedirectsChecks: [...redirects.scribe.loki],
-				},
-				() => resolve()
-			)
-		})
-	)
-}
-
-let disableMedium,
-	mediumRedirects,
-	scribeNormalRedirectsChecks,
-	scribeNormalCustomRedirects,
-	scribeTorRedirectsChecks,
-	scribeTorCustomRedirects,
-	scribeI2pCustomRedirects,
-	scribeLokiCustomRedirects,
-	protocol,
-	protocolFallback
-
-function init() {
-	return new Promise(resolve => {
-		browser.storage.local.get(
-			[
-				"disableMedium",
-				"mediumRedirects",
-				"scribeNormalRedirectsChecks",
-				"scribeNormalCustomRedirects",
-				"scribeTorRedirectsChecks",
-				"scribeTorCustomRedirects",
-				"scribeI2pCustomRedirects",
-				"scribeLokiCustomRedirects",
-				"protocol",
-				"protocolFallback",
-			],
-			r => {
-				disableMedium = r.disableMedium
-				mediumRedirects = r.mediumRedirects
-				scribeNormalRedirectsChecks = r.scribeNormalRedirectsChecks
-				scribeNormalCustomRedirects = r.scribeNormalCustomRedirects
-				scribeTorRedirectsChecks = r.scribeTorRedirectsChecks
-				scribeTorCustomRedirects = r.scribeTorCustomRedirects
-				scribeI2pCustomRedirects = r.scribeI2pCustomRedirects
-				scribeLokiCustomRedirects = r.scribeLokiCustomRedirects
-				protocol = r.protocol
-				protocolFallback = r.protocolFallback
-				resolve()
-			}
-		)
-	})
-}
-
-init()
-browser.storage.onChanged.addListener(init)
-
-function redirect(url, type, initiator, disableOverride) {
-	if (disableMedium && !disableOverride) return
-	if (url.pathname == "/" && !disableOverride) return
-	if (type != "main_frame" && "sub_frame" && "xmlhttprequest" && "other") return
-	if (
-		initiator &&
-		[...mediumRedirects.scribe.normal, ...mediumRedirects.scribe.tor, ...scribeNormalCustomRedirects, ...scribeTorCustomRedirects, ...scribeI2pCustomRedirects, ...scribeLokiCustomRedirects].includes(
-			initiator.origin
-		)
-	)
-		return
-
-	if (!targets.some(rx => rx.test(url.host))) return
-	if (/^\/(@[a-zA-Z.]{0,}(\/|)$)/.test(url.pathname)) return
-
-	let instancesList = []
-	if (protocol == "loki") instancesList = [...scribeLokiCustomRedirects]
-	else if (protocol == "i2p") instancesList = [...scribeI2pCustomRedirects]
-	else if (protocol == "tor") instancesList = [...scribeTorRedirectsChecks, ...scribeTorCustomRedirects]
-	if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-		instancesList = [...scribeNormalRedirectsChecks, ...scribeNormalCustomRedirects]
-	}
-	if (instancesList.length === 0) {
-		return
-	}
-
-	const randomInstance = utils.getRandomInstance(instancesList)
-	return `${randomInstance}${url.pathname}${url.search}`
-}
-
-function switchInstance(url, disableOverride) {
-	return new Promise(async resolve => {
-		await init()
-		if (disableMedium && !disableOverride) {
-			resolve()
-			return
-		}
-		let protocolHost = utils.protocolHost(url)
-		const all = [
-			...mediumRedirects.scribe.tor,
-			...mediumRedirects.scribe.normal,
-
-			...scribeNormalCustomRedirects,
-			...scribeTorCustomRedirects,
-			...scribeI2pCustomRedirects,
-			...scribeLokiCustomRedirects,
-		]
-		if (!all.includes(protocolHost)) {
-			resolve()
-			return
-		}
-
-		let instancesList = []
-		if (protocol == "loki") instancesList = [...scribeLokiCustomRedirects]
-		else if (protocol == "i2p") instancesList = [...scribeI2pCustomRedirects]
-		else if (protocol == "tor") instancesList = [...scribeTorRedirectsChecks, ...scribeTorCustomRedirects]
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			instancesList = [...scribeNormalRedirectsChecks, ...scribeNormalCustomRedirects]
-		}
-
-		const i = instancesList.indexOf(protocolHost)
-		if (i > -1) instancesList.splice(i, 1)
-		if (instancesList.length === 0) {
-			resolve()
-			return
-		}
-
-		const randomInstance = utils.getRandomInstance(instancesList)
-		resolve(`${randomInstance}${url.pathname}${url.search}`)
-	})
-}
-
-function initDefaults() {
-	return new Promise(resolve => {
-		fetch("/instances/data.json")
-			.then(response => response.text())
-			.then(data => {
-				let dataJson = JSON.parse(data)
-				for (let i = 0; i < frontends.length; i++) {
-					redirects[frontends[i]] = dataJson[frontends[i]]
-				}
-				browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
-					scribeNormalRedirectsChecks = [...redirects.scribe.normal]
-					for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-						const a = scribeNormalRedirectsChecks.indexOf(instance)
-						if (a > -1) scribeNormalRedirectsChecks.splice(a, 1)
-					}
-					browser.storage.local.set(
-						{
-							disableMedium: false,
-							mediumRedirects: redirects,
-
-							scribeNormalRedirectsChecks,
-							scribeNormalCustomRedirects: [],
-
-							scribeTorRedirectsChecks: [...redirects.scribe.tor],
-							scribeTorCustomRedirects: [],
-
-							scribeI2pRedirectsChecks: [...redirects.scribe.i2p],
-							scribeI2pCustomRedirects: [],
-
-							scribeLokiRedirectsChecks: [...redirects.scribe.loki],
-							scribeLokiCustomRedirects: [],
-						},
-						() => resolve()
-					)
-				})
-			})
-	})
-}
-
-export default {
-	setRedirects,
-	redirect,
-	switchInstance,
-	initDefaults,
-}
diff --git a/src/assets/javascripts/peertube.js b/src/assets/javascripts/peertube.js
deleted file mode 100644
index e1ff406f..00000000
--- a/src/assets/javascripts/peertube.js
+++ /dev/null
@@ -1,209 +0,0 @@
-window.browser = window.browser || window.chrome
-
-import utils from "./utils.js"
-
-const frontends = new Array("simpleertube")
-const protocols = new Array("normal", "tor", "i2p", "loki")
-
-let redirects = {}
-
-for (let i = 0; i < frontends.length; i++) {
-	redirects[frontends[i]] = {}
-	for (let x = 0; x < protocols.length; x++) {
-		redirects[frontends[i]][protocols[x]] = []
-	}
-}
-
-function setRedirects(val) {
-	return new Promise(resolve =>
-		browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
-			redirects.simpleertube = val
-			simpleertubeNormalRedirectsChecks = [...redirects.simpleertube.normal]
-			for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-				const a = simpleertubeNormalRedirectsChecks.indexOf(instance)
-				if (a > -1) simpleertubeNormalRedirectsChecks.splice(a, 1)
-			}
-			browser.storage.local.set(
-				{
-					peertubeRedirects: redirects,
-					simpleertubeNormalRedirectsChecks,
-					simpleertubeTorRedirectsChecks: [...redirects.simpleertube.tor],
-					simpleertubeI2pRedirectsChecks: [...redirects.simpleertube.i2p],
-					simpleertubeLokiRedirectsChecks: [...redirects.simpleertube.loki],
-				},
-				() => resolve()
-			)
-		})
-	)
-}
-
-let disablePeertubeTargets,
-	peertubeRedirects,
-	simpleertubeNormalRedirectsChecks,
-	simpleertubeNormalCustomRedirects,
-	simpleertubeTorRedirectsChecks,
-	simpleertubeTorCustomRedirects,
-	simpleertubeI2pRedirectsChecks,
-	simpleertubeI2pCustomRedirects,
-	simpleertubeLokiRedirectsChecks,
-	simpleertubeLokiCustomRedirects,
-	peerTubeTargets,
-	protocol,
-	protocolFallback
-
-function init() {
-	return new Promise(resolve => {
-		browser.storage.local.get(
-			[
-				"disablePeertubeTargets",
-				"peertubeRedirects",
-				"simpleertubeNormalRedirectsChecks",
-				"simpleertubeNormalCustomRedirects",
-				"simpleertubeTorRedirectsChecks",
-				"simpleertubeTorCustomRedirects",
-				"simpleertubeI2pRedirectsChecks",
-				"simpleertubeI2pCustomRedirects",
-				"simpleertubeLokiRedirectsChecks",
-				"simpleertubeLokiCustomRedirects",
-				"peerTubeTargets",
-				"protocol",
-				"protocolFallback",
-			],
-			r => {
-				disablePeertubeTargets = r.disablePeertubeTargets
-				peertubeRedirects = r.peertubeRedirects
-				simpleertubeNormalRedirectsChecks = r.simpleertubeNormalRedirectsChecks
-				simpleertubeNormalCustomRedirects = r.simpleertubeNormalCustomRedirects
-				simpleertubeTorRedirectsChecks = r.simpleertubeTorRedirectsChecks
-				simpleertubeTorCustomRedirects = r.simpleertubeTorCustomRedirects
-				simpleertubeI2pRedirectsChecks = r.simpleertubeI2pRedirectsChecks
-				simpleertubeI2pCustomRedirects = r.simpleertubeI2pCustomRedirects
-				simpleertubeLokiRedirectsChecks = r.simpleertubeLokiRedirectsChecks
-				simpleertubeLokiCustomRedirects = r.simpleertubeLokiCustomRedirects
-				peerTubeTargets = r.peerTubeTargets
-				protocol = r.protocol
-				protocolFallback = r.protocolFallback
-				resolve()
-			}
-		)
-	})
-}
-
-init()
-browser.storage.onChanged.addListener(init)
-
-function all() {
-	return [
-		...simpleertubeNormalRedirectsChecks,
-		...simpleertubeTorRedirectsChecks,
-		...simpleertubeI2pRedirectsChecks,
-		...simpleertubeLokiRedirectsChecks,
-		...simpleertubeNormalCustomRedirects,
-		...simpleertubeTorCustomRedirects,
-		...simpleertubeI2pCustomRedirects,
-		...simpleertubeLokiCustomRedirects,
-	]
-}
-
-function redirect(url, type, initiator, disableOverride) {
-	if (disablePeertubeTargets && !disableOverride) return
-	if (initiator && (all().includes(initiator.origin) || peerTubeTargets.includes(initiator.host))) return
-	let protocolHost = utils.protocolHost(url)
-	if (!peerTubeTargets.includes(protocolHost)) return
-	if (type != "main_frame") return
-
-	let instancesList = []
-	if (protocol == "loki") instancesList = [...simpleertubeLokiRedirectsChecks, ...simpleertubeLokiCustomRedirects]
-	else if (protocol == "i2p") instancesList = [...simpleertubeI2pRedirectsChecks, ...simpleertubeI2pCustomRedirects]
-	else if (protocol == "tor") instancesList = [...simpleertubeTorRedirectsChecks, ...simpleertubeTorCustomRedirects]
-	if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-		instancesList = [...simpleertubeNormalRedirectsChecks, ...simpleertubeNormalCustomRedirects]
-	}
-	if (instancesList.length === 0) {
-		return
-	}
-
-	const randomInstance = utils.getRandomInstance(instancesList)
-	if (url.host == "search.joinpeertube.org" || url.host == "sepiasearch.org") return randomInstance
-	return `${randomInstance}/${url.host}${url.pathname}${url.search}`
-}
-
-function switchInstance(url, disableOverride) {
-	return new Promise(async resolve => {
-		await init()
-		if (disablePeertubeTargets && !disableOverride) {
-			resolve()
-			return
-		}
-		const protocolHost = utils.protocolHost(url)
-		if (!all().includes(protocolHost)) {
-			resolve()
-			return
-		}
-
-		let instancesList = []
-		if (protocol == "loki") instancesList = [...simpleertubeLokiRedirectsChecks, ...simpleertubeLokiCustomRedirects]
-		else if (protocol == "i2p") instancesList = [...simpleertubeI2pRedirectsChecks, ...simpleertubeI2pCustomRedirects]
-		else if (protocol == "tor") instancesList = [...simpleertubeTorRedirectsChecks, ...simpleertubeTorCustomRedirects]
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			instancesList = [...simpleertubeNormalRedirectsChecks, ...simpleertubeNormalCustomRedirects]
-		}
-
-		const i = instancesList.indexOf(protocolHost)
-		if (i > -1) instancesList.splice(i, 1)
-		if (instancesList.length === 0) {
-			resolve()
-			return
-		}
-
-		const randomInstance = utils.getRandomInstance(instancesList)
-		resolve(`${randomInstance}${url.pathname}${url.search}`)
-	})
-}
-
-function initDefaults() {
-	return new Promise(resolve => {
-		fetch("/instances/data.json")
-			.then(response => response.text())
-			.then(data => {
-				let dataJson = JSON.parse(data)
-				for (let i = 0; i < frontends.length; i++) {
-					redirects[frontends[i]] = dataJson[frontends[i]]
-				}
-				browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
-					simpleertubeNormalRedirectsChecks = [...redirects.simpleertube.normal]
-					for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-						const a = simpleertubeNormalRedirectsChecks.indexOf(instance)
-						if (a > -1) simpleertubeNormalRedirectsChecks.splice(a, 1)
-					}
-					browser.storage.local.set(
-						{
-							peerTubeTargets: ["https://search.joinpeertube.org", ...dataJson.peertube],
-							disablePeertubeTargets: true,
-							peertubeRedirects: redirects,
-
-							simpleertubeNormalRedirectsChecks,
-							simpleertubeNormalCustomRedirects: [],
-
-							simpleertubeTorRedirectsChecks: [...redirects.simpleertube.tor],
-							simpleertubeTorCustomRedirects: [],
-
-							simpleertubeI2pRedirectsChecks: [...redirects.simpleertube.i2p],
-							simpleertubeI2pCustomRedirects: [],
-
-							simpleertubeLokiRedirectsChecks: [...redirects.simpleertube.loki],
-							simpleertubeLokiCustomRedirects: [],
-						},
-						() => resolve()
-					)
-				})
-			})
-	})
-}
-
-export default {
-	setRedirects,
-	switchInstance,
-	redirect,
-	initDefaults,
-}
diff --git a/src/assets/javascripts/quora.js b/src/assets/javascripts/quora.js
deleted file mode 100644
index 4473c3d7..00000000
--- a/src/assets/javascripts/quora.js
+++ /dev/null
@@ -1,205 +0,0 @@
-window.browser = window.browser || window.chrome
-
-import utils from "./utils.js"
-
-const targets = [/^https?:\/{2}(www\.|)quora\.com.*/]
-
-let redirects = {}
-
-const frontends = new Array("quetre")
-const protocols = new Array("normal", "tor", "i2p", "loki")
-
-for (let i = 0; i < frontends.length; i++) {
-	redirects[frontends[i]] = {}
-	for (let x = 0; x < protocols.length; x++) {
-		redirects[frontends[i]][protocols[x]] = []
-	}
-}
-
-function setRedirects(val) {
-	return new Promise(resolve =>
-		browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
-			redirects.quetre = val
-			quetreNormalRedirectsChecks = [...redirects.quetre.normal]
-			for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-				const a = quetreNormalRedirectsChecks.indexOf(instance)
-				if (a > -1) quetreNormalRedirectsChecks.splice(a, 1)
-			}
-			browser.storage.local.set(
-				{
-					quoraRedirects: redirects,
-					quetreNormalRedirectsChecks,
-					quetreTorRedirectsChecks: [...redirects.quetre.tor],
-					quetreI2pRedirectsChecks: [...redirects.quetre.i2p],
-					quetreLokiRedirectsChecks: [...redirects.quetre.loki],
-				},
-				() => resolve()
-			)
-		})
-	)
-}
-
-let disableQuora,
-	protocol,
-	protocolFallback,
-	quoraRedirects,
-	quetreNormalRedirectsChecks,
-	quetreNormalCustomRedirects,
-	quetreTorRedirectsChecks,
-	quetreTorCustomRedirects,
-	quetreI2pCustomRedirects,
-	quetreLokiCustomRedirects
-
-function init() {
-	return new Promise(async resolve => {
-		browser.storage.local.get(
-			[
-				"disableQuora",
-				"protocol",
-				"protocolFallback",
-				"quoraRedirects",
-				"quetreNormalRedirectsChecks",
-				"quetreNormalCustomRedirects",
-				"quetreTorRedirectsChecks",
-				"quetreTorCustomRedirects",
-				"quetreI2pCustomRedirects",
-				"quetreLokiCustomRedirects",
-			],
-			r => {
-				disableQuora = r.disableQuora
-				protocol = r.protocol
-				protocolFallback = r.protocolFallback
-				quoraRedirects = r.quoraRedirects
-				quetreNormalRedirectsChecks = r.quetreNormalRedirectsChecks
-				quetreNormalCustomRedirects = r.quetreNormalCustomRedirects
-				quetreTorRedirectsChecks = r.quetreTorRedirectsChecks
-				quetreTorCustomRedirects = r.quetreTorCustomRedirects
-				quetreI2pCustomRedirects = r.quetreI2pCustomRedirects
-				quetreLokiCustomRedirects = r.quetreLokiCustomRedirects
-				resolve()
-			}
-		)
-	})
-}
-
-init()
-browser.storage.onChanged.addListener(init)
-
-function redirect(url, type, initiator, disableOverride) {
-	if (disableQuora && !disableOverride) return
-	if (url.pathname == "/" && !disableOverride) return
-	if (type != "main_frame") return
-	const all = [...quoraRedirects.quetre.normal, ...quetreNormalCustomRedirects]
-	if (initiator && (all.includes(initiator.origin) || targets.includes(initiator.host))) return
-	if (!targets.some(rx => rx.test(url.href))) return
-
-	let instancesList = []
-	if (protocol == "loki") instancesList = [...quetreLokiCustomRedirects]
-	else if (protocol == "i2p") instancesList = [...quetreI2pCustomRedirects]
-	else if (protocol == "tor") instancesList = [...quetreTorRedirectsChecks, ...quetreTorCustomRedirects]
-	if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-		instancesList = [...quetreNormalRedirectsChecks, ...quetreNormalCustomRedirects]
-	}
-	if (instancesList.length === 0) return
-
-	const randomInstance = utils.getRandomInstance(instancesList)
-	return `${randomInstance}${url.pathname}`
-}
-
-function reverse(url) {
-	return new Promise(async resolve => {
-		await init()
-		let protocolHost = utils.protocolHost(url)
-		const all = [...quoraRedirects.quetre.normal, ...quoraRedirects.quetre.tor, ...quetreNormalCustomRedirects, ...quetreTorCustomRedirects, ...quetreI2pCustomRedirects, ...quetreLokiCustomRedirects]
-		if (!all.includes(protocolHost)) {
-			resolve()
-			return
-		}
-
-		resolve(`https://quora.com${url.pathname}${url.search}`)
-	})
-}
-
-function switchInstance(url, disableOverride) {
-	return new Promise(async resolve => {
-		await init()
-		if (disableQuora && !disableOverride) {
-			resolve()
-			return
-		}
-		let protocolHost = utils.protocolHost(url)
-		const all = [...quoraRedirects.quetre.tor, ...quoraRedirects.quetre.normal, ...quetreNormalCustomRedirects, ...quetreTorCustomRedirects, ...quetreI2pCustomRedirects, ...quetreLokiCustomRedirects]
-		if (!all.includes(protocolHost)) {
-			resolve()
-			return
-		}
-
-		let instancesList = []
-		if (protocol == "loki") instancesList = [...quetreLokiCustomRedirects]
-		else if (protocol == "i2p") instancesList = [...quetreI2pCustomRedirects]
-		else if (protocol == "tor") instancesList = [...quetreTorRedirectsChecks, ...quetreTorCustomRedirects]
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			instancesList = [...quetreNormalRedirectsChecks, ...quetreNormalCustomRedirects]
-		}
-
-		const i = instancesList.indexOf(protocolHost)
-		if (i > -1) instancesList.splice(i, 1)
-		if (instancesList.length === 0) {
-			resolve()
-			return
-		}
-
-		const randomInstance = utils.getRandomInstance(instancesList)
-		resolve(`${randomInstance}${url.pathname}${url.search}`)
-	})
-}
-
-function initDefaults() {
-	return new Promise(async resolve => {
-		fetch("/instances/data.json")
-			.then(response => response.text())
-			.then(async data => {
-				let dataJson = JSON.parse(data)
-				for (let i = 0; i < frontends.length; i++) {
-					redirects[frontends[i]] = dataJson[frontends[i]]
-				}
-				browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
-					quetreNormalRedirectsChecks = [...redirects.quetre.normal]
-					for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-						const a = quetreNormalRedirectsChecks.indexOf(instance)
-						if (a > -1) quetreNormalRedirectsChecks.splice(a, 1)
-					}
-					browser.storage.local.set(
-						{
-							disableQuora: false,
-
-							quoraRedirects: redirects,
-
-							quetreNormalRedirectsChecks,
-							quetreNormalCustomRedirects: [],
-
-							quetreTorRedirectsChecks: [...redirects.quetre.tor],
-							quetreTorCustomRedirects: [],
-
-							quetreI2pRedirectsChecks: [...redirects.quetre.i2p],
-							quetreI2pCustomRedirects: [],
-
-							quetreLokiRedirectsChecks: [...redirects.quetre.loki],
-							quetreLokiCustomRedirects: [],
-						},
-						() => resolve()
-					)
-				})
-			})
-	})
-}
-
-export default {
-	setRedirects,
-
-	redirect,
-	reverse,
-	switchInstance,
-
-	initDefaults,
-}
diff --git a/src/assets/javascripts/reddit.js b/src/assets/javascripts/reddit.js
deleted file mode 100644
index 209ee7e3..00000000
--- a/src/assets/javascripts/reddit.js
+++ /dev/null
@@ -1,402 +0,0 @@
-window.browser = window.browser || window.chrome
-
-import utils from "./utils.js"
-
-const targets = [/^https?:\/{2}(www\.|old\.|np\.|new\.|amp\.|)reddit\.com/, /^https?:\/{2}(i\.|preview\.)redd\.it/]
-let redirects = {}
-
-const frontends = new Array("libreddit", "teddit")
-const protocols = new Array("normal", "tor", "i2p", "loki")
-
-for (let i = 0; i < frontends.length; i++) {
-	redirects[frontends[i]] = {}
-	for (let x = 0; x < protocols.length; x++) {
-		redirects[frontends[i]][protocols[x]] = []
-	}
-}
-
-function setRedirects(val) {
-	return new Promise(resolve =>
-		browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
-			redirects = val
-			libredditNormalRedirectsChecks = [...redirects.libreddit.normal]
-			tedditNormalRedirectsChecks = [...redirects.teddit.normal]
-			for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-				const a = libredditNormalRedirectsChecks.indexOf(instance)
-				if (a > -1) libredditNormalRedirectsChecks.splice(a, 1)
-
-				const b = tedditNormalRedirectsChecks.indexOf(instance)
-				if (b > -1) tedditNormalRedirectsChecks.splice(b, 1)
-			}
-			browser.storage.local.set(
-				{
-					redditRedirects: redirects,
-					libredditNormalRedirectsChecks,
-					libredditTorRedirectsChecks: [...redirects.libreddit.tor],
-					libredditI2pRedirectsChecks: [...redirects.libreddit.i2p],
-					libredditLokiRedirectsChecks: [...redirects.libreddit.loki],
-					tedditNormalRedirectsChecks,
-					tedditTorRedirectsChecks: [...redirects.teddit.tor],
-					tedditI2pRedirectsChecks: [...redirects.teddit.i2p],
-					tedditLokiRedirectsChecks: [...redirects.teddit.loki],
-				},
-				() => resolve()
-			)
-		})
-	)
-}
-
-let disableReddit,
-	redditFrontend,
-	redditRedirects,
-	protocol,
-	protocolFallback,
-	libredditNormalRedirectsChecks,
-	libredditNormalCustomRedirects,
-	libredditTorRedirectsChecks,
-	libredditTorCustomRedirects,
-	libredditI2pCustomRedirects,
-	libredditLokiCustomRedirects,
-	tedditNormalRedirectsChecks,
-	tedditNormalCustomRedirects,
-	tedditTorRedirectsChecks,
-	tedditTorCustomRedirects,
-	tedditI2pCustomRedirects,
-	tedditLokiCustomRedirects
-
-function init() {
-	return new Promise(resolve => {
-		browser.storage.local.get(
-			[
-				"disableReddit",
-				"redditFrontend",
-				"redditRedirects",
-				"protocol",
-				"protocolFallback",
-				"libredditNormalRedirectsChecks",
-				"libredditNormalCustomRedirects",
-				"libredditTorRedirectsChecks",
-				"libredditTorCustomRedirects",
-				"libredditI2pCustomRedirects",
-				"libredditLokiCustomRedirects",
-				"tedditNormalRedirectsChecks",
-				"tedditNormalCustomRedirects",
-				"tedditTorRedirectsChecks",
-				"tedditTorCustomRedirects",
-				"tedditI2pCustomRedirects",
-				"tedditLokiCustomRedirects",
-			],
-			r => {
-				disableReddit = r.disableReddit
-				redditFrontend = r.redditFrontend
-				redditRedirects = r.redditRedirects
-				protocol = r.protocol
-				protocolFallback = r.protocolFallback
-				libredditNormalRedirectsChecks = r.libredditNormalRedirectsChecks
-				libredditNormalCustomRedirects = r.libredditNormalCustomRedirects
-				libredditTorRedirectsChecks = r.libredditTorRedirectsChecks
-				libredditTorCustomRedirects = r.libredditTorCustomRedirects
-				libredditI2pCustomRedirects = r.libredditI2pCustomRedirects
-				libredditLokiCustomRedirects = r.libredditLokiCustomRedirects
-				tedditNormalRedirectsChecks = r.tedditNormalRedirectsChecks
-				tedditNormalCustomRedirects = r.tedditNormalCustomRedirects
-				tedditTorRedirectsChecks = r.tedditTorRedirectsChecks
-				tedditTorCustomRedirects = r.tedditTorCustomRedirects
-				tedditI2pCustomRedirects = r.tedditI2pCustomRedirects
-				tedditLokiCustomRedirects = r.tedditLokiCustomRedirects
-				resolve()
-			}
-		)
-	})
-}
-
-init()
-browser.storage.onChanged.addListener(init)
-
-function initLibredditCookies(test, from) {
-	return new Promise(async resolve => {
-		await init()
-		const protocolHost = utils.protocolHost(from)
-		if (
-			![
-				...libredditNormalRedirectsChecks,
-				...libredditTorRedirectsChecks,
-				...libredditNormalCustomRedirects,
-				...libredditTorCustomRedirects,
-				...libredditI2pCustomRedirects,
-				...libredditLokiCustomRedirects,
-			].includes(protocolHost)
-		) {
-			resolve()
-			return
-		}
-
-		if (!test) {
-			let checkedInstances = []
-			if (protocol == "loki") checkedInstances = [...libredditLokiCustomRedirects]
-			else if (protocol == "i2p") checkedInstances = [...libredditI2pCustomRedirects]
-			else if (protocol == "tor") checkedInstances = [...libredditTorRedirectsChecks, ...libredditTorCustomRedirects]
-			if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
-				checkedInstances = [...libredditNormalRedirectsChecks, ...libredditNormalCustomRedirects]
-			}
-			await utils.copyCookie("libreddit", from, checkedInstances, "theme")
-			await utils.copyCookie("libreddit", from, checkedInstances, "front_page")
-			await utils.copyCookie("libreddit", from, checkedInstances, "layout")
-			await utils.copyCookie("libreddit", from, checkedInstances, "wide")
-			await utils.copyCookie("libreddit", from, checkedInstances, "post_sort")
-			await utils.copyCookie("libreddit", from, checkedInstances, "comment_sort")
-			await utils.copyCookie("libreddit", from, checkedInstances, "show_nsfw")
-			await utils.copyCookie("libreddit", from, checkedInstances, "autoplay_videos")
-			await utils.copyCookie("libreddit", from, checkedInstances, "use_hls")
-			await utils.copyCookie("libreddit", from, checkedInstances, "hide_hls_notification")
-			await utils.copyCookie("libreddit", from, checkedInstances, "subscriptions")
-			await utils.copyCookie("libreddit", from, checkedInstances, "filters")
-		}
-		resolve(true)
-	})
-}
-
-function initTedditCookies(test, from) {
-	return new Promise(async resolve => {
-		await init()
-		let protocolHost = utils.protocolHost(from)
-		if (
-			![...tedditNormalRedirectsChecks, ...tedditTorRedirectsChecks, ...tedditNormalCustomRedirects, ...tedditTorCustomRedirects, ...tedditI2pCustomRedirects, ...tedditI2pCustomRedirects].includes(
-				protocolHost
-			)
-		)
-			resolve()
-
-		if (!test) {
-			let checkedInstances = []
-			if (protocol == "loki") checkedInstances = [...tedditLokiCustomRedirects]
-			else if (protocol == "i2p") checkedInstances = [...tedditI2pCustomRedirects]
-			else if (protocol == "tor") checkedInstances = [...tedditTorRedirectsChecks, ...tedditTorCustomRedirects]
-			if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
-				checkedInstances = [...tedditNormalRedirectsChecks, ...tedditNormalCustomRedirects]
-			}
-			await utils.copyCookie("teddit", from, checkedInstances, "collapse_child_comments")
-			await utils.copyCookie("teddit", from, checkedInstances, "domain_instagram")
-			await utils.copyCookie("teddit", from, checkedInstances, "domain_twitter")
-			await utils.copyCookie("teddit", from, checkedInstances, "domain_youtube")
-			await utils.copyCookie("teddit", from, checkedInstances, "flairs")
-			await utils.copyCookie("teddit", from, checkedInstances, "highlight_controversial")
-			await utils.copyCookie("teddit", from, checkedInstances, "nsfw_enabled")
-			await utils.copyCookie("teddit", from, checkedInstances, "post_media_max_height")
-			await utils.copyCookie("teddit", from, checkedInstances, "show_upvoted_percentage")
-			await utils.copyCookie("teddit", from, checkedInstances, "show_upvotes")
-			await utils.copyCookie("teddit", from, checkedInstances, "theme")
-			await utils.copyCookie("teddit", from, checkedInstances, "videos_muted")
-		}
-		resolve(true)
-	})
-}
-
-function all() {
-	return [
-		...redditRedirects.libreddit.normal,
-		...redditRedirects.libreddit.tor,
-		...redditRedirects.teddit.normal,
-		...redditRedirects.teddit.tor,
-		...libredditNormalCustomRedirects,
-		...libredditTorCustomRedirects,
-		...libredditI2pCustomRedirects,
-		...libredditLokiCustomRedirects,
-		...tedditNormalCustomRedirects,
-		...tedditTorCustomRedirects,
-		...tedditI2pCustomRedirects,
-		...tedditLokiCustomRedirects,
-	]
-}
-
-// https://libreddit.exonip.de/vid/1mq8d0ma3yk81/720.mp4
-// https://libreddit.exonip.de/img/4v3t1vgvrzk81.png
-
-// https://teddit.net/vids/1mq8d0ma3yk81.mp4
-// https://teddit.net/pics/w:null_4v3t1vgvrzk81.png
-
-// redd.it/t5379n
-// https://v.redd.it/z08avb339n801/DASH_1_2_M
-// https://i.redd.it/bfkhs659tzk81.jpg
-function redirect(url, type, initiator, disableOverride) {
-	if (disableReddit && !disableOverride) return
-	if (!targets.some(rx => rx.test(url.href))) return
-	if (initiator && all().includes(initiator.origin)) return "BYPASSTAB"
-	if (!["main_frame", "xmlhttprequest", "other", "image", "media"].includes(type)) return
-	const bypassPaths = /\/(gallery\/poll\/rpan\/settings\/topics)/
-	if (url.pathname.match(bypassPaths)) return
-
-	let libredditInstancesList = []
-	let tedditInstancesList = []
-
-	if (protocol == "loki") {
-		libredditInstancesList = [...libredditLokiCustomRedirects]
-		tedditInstancesList = [...tedditLokiCustomRedirects]
-	} else if (protocol == "i2p") {
-		libredditInstancesList = [...libredditI2pCustomRedirects]
-		tedditInstancesList = [...tedditI2pCustomRedirects]
-	} else if (protocol == "tor") {
-		libredditInstancesList = [...libredditTorRedirectsChecks, ...libredditTorCustomRedirects]
-		tedditInstancesList = [...tedditTorRedirectsChecks, ...tedditTorCustomRedirects]
-	}
-	if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-		libredditInstancesList = [...libredditNormalRedirectsChecks, ...libredditNormalCustomRedirects]
-		tedditInstancesList = [...tedditNormalRedirectsChecks, ...tedditNormalCustomRedirects]
-	}
-
-	if (url.host === "i.redd.it") {
-		if (redditFrontend == "teddit") {
-			if (tedditInstancesList.length === 0) return
-			let tedditRandomInstance = utils.getRandomInstance(tedditInstancesList)
-			return `${tedditRandomInstance}/pics/w:null_${url.pathname.substring(1)}${url.search}`
-		}
-		if (redditFrontend == "libreddit") {
-			if (libredditInstancesList.length === 0) return
-			let libredditRandomInstance = utils.getRandomInstance(libredditInstancesList)
-			return `${libredditRandomInstance}/img${url.pathname}${url.search}`
-		}
-	} else if (url.host === "redd.it") {
-		if (redditFrontend == "libreddit" && !url.pathname.match(/^\/+[^\/]+\/+[^\/]/)) {
-			if (libredditInstancesList.length === 0) return
-			let libredditRandomInstance = utils.getRandomInstance(libredditInstancesList)
-			// https://redd.it/foo => https://libredd.it/comments/foo
-			return `${libredditRandomInstance}/comments${url.pathname}${url.search}`
-		}
-		if (redditFrontend == "teddit" && !url.pathname.match(/^\/+[^\/]+\/+[^\/]/)) {
-			if (tedditInstancesList.length === 0) return
-			let tedditRandomInstance = utils.getRandomInstance(tedditInstancesList)
-			// https://redd.it/foo => https://teddit.net/comments/foo
-			return `${tedditRandomInstance}/comments${url.pathname}${url.search}`
-		}
-	} else if (url.host === "preview.redd.it") {
-		if (redditFrontend == "teddit") return
-		if (redditFrontend == "libreddit") {
-			if (libredditInstancesList.length === 0) return
-			const libredditRandomInstance = utils.getRandomInstance(libredditInstancesList)
-			return `${libredditRandomInstance}/preview/pre${url.pathname}${url.search}`
-		}
-	}
-
-	let randomInstance
-	if (redditFrontend == "libreddit") {
-		if (libredditInstancesList.length === 0) return
-		randomInstance = utils.getRandomInstance(libredditInstancesList)
-	}
-	if (redditFrontend == "teddit") {
-		if (tedditInstancesList.length === 0) return
-		randomInstance = utils.getRandomInstance(tedditInstancesList)
-	}
-	return `${randomInstance}${url.pathname}${url.search}`
-}
-
-function switchInstance(url, disableOverride) {
-	return new Promise(async resolve => {
-		await init()
-		if (disableReddit && !disableOverride) {
-			resolve()
-			return
-		}
-		const protocolHost = utils.protocolHost(url)
-		if (!all().includes(protocolHost)) {
-			resolve()
-			return
-		}
-		let instancesList = []
-		if (redditFrontend == "libreddit") {
-			if (protocol == "loki") instancesList = [...libredditLokiCustomRedirects]
-			else if (protocol == "i2p") instancesList = [...libredditI2pCustomRedirects]
-			else if (protocol == "tor") instancesList = [...libredditTorRedirectsChecks, ...libredditTorCustomRedirects]
-			if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-				instancesList = [...libredditNormalRedirectsChecks, ...libredditNormalCustomRedirects]
-			}
-			if ([...redditRedirects.teddit.normal, ...redditRedirects.teddit.tor].includes(protocolHost)) {
-				url.pathname = url.pathname.replace("/pics/w:null_", "/img/")
-			}
-		} else if (redditFrontend == "teddit") {
-			if (protocol == "loki") instancesList = [...tedditLokiCustomRedirects]
-			else if (protocol == "i2p") instancesList = [...tedditI2pCustomRedirects]
-			else if (protocol == "tor") instancesList = [...tedditTorRedirectsChecks, ...tedditTorCustomRedirects]
-			if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-				instancesList = [...tedditNormalRedirectsChecks, ...tedditNormalCustomRedirects]
-			}
-			if ([...redditRedirects.libreddit.normal, ...redditRedirects.libreddit.tor].includes(protocolHost)) {
-				url.pathname = url.pathname.replace("/img/", "/pics/w:null_")
-			}
-		}
-
-		const i = instancesList.indexOf(protocolHost)
-		if (i > -1) instancesList.splice(i, 1)
-		if (instancesList.length === 0) {
-			resolve()
-			return
-		}
-
-		const randomInstance = utils.getRandomInstance(instancesList)
-		resolve(`${randomInstance}${url.pathname}${url.search}`)
-	})
-}
-
-function initDefaults() {
-	return new Promise(resolve => {
-		fetch("/instances/data.json")
-			.then(response => response.text())
-			.then(async data => {
-				let dataJson = JSON.parse(data)
-				for (const frontend of frontends) redirects[frontend] = dataJson[frontend]
-
-				browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
-					libredditNormalRedirectsChecks = [...redirects.libreddit.normal]
-					tedditNormalRedirectsChecks = [...redirects.teddit.normal]
-					for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-						const a = libredditNormalRedirectsChecks.indexOf(instance)
-						if (a > -1) libredditNormalRedirectsChecks.splice(a, 1)
-
-						const b = tedditNormalRedirectsChecks.indexOf(instance)
-						if (b > -1) tedditNormalRedirectsChecks.splice(b, 1)
-					}
-					browser.storage.local.set(
-						{
-							disableReddit: false,
-							redditFrontend: "libreddit",
-							redditRedirects: redirects,
-
-							libredditNormalRedirectsChecks,
-							libredditNormalCustomRedirects: [],
-
-							libredditTorRedirectsChecks: [...redirects.libreddit.tor],
-							libredditTorCustomRedirects: [],
-
-							libredditI2pRedirectsChecks: [...redirects.libreddit.i2p],
-							libredditI2pCustomRedirects: [],
-
-							libredditLokiRedirectsChecks: [...redirects.libreddit.loki],
-							libredditLokiCustomRedirects: [],
-
-							tedditNormalRedirectsChecks,
-							tedditNormalCustomRedirects: [],
-
-							tedditTorRedirectsChecks: [...redirects.teddit.tor],
-							tedditTorCustomRedirects: [],
-
-							tedditI2pRedirectsChecks: [...redirects.teddit.i2p],
-							tedditI2pCustomRedirects: [],
-
-							tedditLokiRedirectsChecks: [...redirects.teddit.loki],
-							tedditLokiCustomRedirects: [],
-						},
-						() => resolve()
-					)
-				})
-			})
-	})
-}
-
-export default {
-	setRedirects,
-	initLibredditCookies,
-	initTedditCookies,
-
-	redirect,
-	initDefaults,
-	switchInstance,
-}
diff --git a/src/assets/javascripts/reuters.js b/src/assets/javascripts/reuters.js
deleted file mode 100644
index 16459b4a..00000000
--- a/src/assets/javascripts/reuters.js
+++ /dev/null
@@ -1,155 +0,0 @@
-window.browser = window.browser || window.chrome
-
-import utils from "./utils.js"
-
-const targets = [/^https?:\/{2}(www\.|)reuters\.com.*/]
-
-const frontends = new Array("neuters")
-const protocols = new Array("normal", "tor", "i2p", "loki")
-
-let redirects = {}
-
-for (let i = 0; i < frontends.length; i++) {
-	redirects[frontends[i]] = {}
-	for (let x = 0; x < protocols.length; x++) {
-		redirects[frontends[i]][protocols[x]] = []
-	}
-}
-
-function setRedirects(val) {
-	return new Promise(resolve =>
-		browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
-			redirects.neuters = val
-			neutersNormalRedirectsChecks = [...redirects.neuters.normal]
-			for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-				const a = neutersNormalRedirectsChecks.indexOf(instance)
-				if (a > -1) neutersNormalRedirectsChecks.splice(a, 1)
-			}
-			browser.storage.local.set(
-				{
-					neutersRedirects: redirects,
-					neutersNormalRedirectsChecks,
-					neutersTorRedirectsChecks: [...redirects.neuters.tor],
-					neutersI2pRedirectsChecks: [...redirects.neuters.i2p],
-					neutersLokiRedirectsChecks: [...redirects.neuters.loki],
-				},
-				() => resolve()
-			)
-		})
-	)
-}
-
-let disableReuters,
-	protocol,
-	protocolFallback,
-	reutersRedirects,
-	neutersNormalRedirectsChecks,
-	neutersNormalCustomRedirects,
-	neutersTorRedirectsChecks,
-	neutersTorCustomRedirects,
-	neutersI2pCustomRedirects,
-	neutersLokiCustomRedirects
-
-function init() {
-	return new Promise(async resolve => {
-		browser.storage.local.get(
-			[
-				"disableReuters",
-				"protocol",
-				"protocolFallback",
-				"reutersRedirects",
-				"neutersNormalRedirectsChecks",
-				"neutersNormalCustomRedirects",
-				"neutersTorRedirectsChecks",
-				"neutersTorCustomRedirects",
-				"neutersI2pCustomRedirects",
-				"neutersLokiCustomRedirects",
-			],
-			r => {
-				disableReuters = r.disableReuters
-				protocol = r.protocol
-				protocolFallback = r.protocolFallback
-				reutersRedirects = r.reutersRedirects
-				neutersNormalRedirectsChecks = r.neutersNormalRedirectsChecks
-				neutersNormalCustomRedirects = r.neutersNormalCustomRedirects
-				neutersTorRedirectsChecks = r.neutersTorRedirectsChecks
-				neutersTorCustomRedirects = r.neutersTorCustomRedirects
-				neutersI2pCustomRedirects = r.neutersI2pCustomRedirects
-				neutersLokiCustomRedirects = r.neutersLokiCustomRedirects
-				resolve()
-			}
-		)
-	})
-}
-
-init()
-browser.storage.onChanged.addListener(init)
-
-function redirect(url, type, initiator, disableOverride) {
-	if (disableReuters && !disableOverride) return
-	if (type != "main_frame") return
-	const all = [...reutersRedirects.neuters.normal, ...neutersNormalCustomRedirects]
-	if (initiator && (all.includes(initiator.origin) || targets.includes(initiator.host))) return
-	if (!targets.some(rx => rx.test(url.href))) return
-
-	let instancesList = []
-	if (protocol == "loki") instancesList = [...neutersLokiCustomRedirects]
-	else if (protocol == "i2p") instancesList = [...neutersI2pCustomRedirects]
-	else if (protocol == "tor") instancesList = [...neutersTorRedirectsChecks, ...neutersTorCustomRedirects]
-	if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-		instancesList = [...neutersNormalRedirectsChecks, ...neutersNormalCustomRedirects]
-	}
-	if (instancesList.length === 0) return
-
-	const randomInstance = utils.getRandomInstance(instancesList)
-	// stolen from https://addons.mozilla.org/en-US/firefox/addon/reuters-redirect/
-	if (url.pathname.startsWith("/article/") || url.pathname.startsWith("/pf/") || url.pathname.startsWith("/arc/") || url.pathname.startsWith("/resizer/")) return null
-	else if (url.pathname.endsWith("/")) return `${randomInstance}${url.pathname}`
-	else return `${randomInstance}${url.pathname}/`
-}
-
-function initDefaults() {
-	return new Promise(async resolve => {
-		fetch("/instances/data.json")
-			.then(response => response.text())
-			.then(async data => {
-				let dataJson = JSON.parse(data)
-				for (let i = 0; i < frontends.length; i++) {
-					redirects[frontends[i]] = dataJson[frontends[i]]
-				}
-				browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
-					neutersNormalRedirectsChecks = [...redirects.neuters.normal]
-					for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-						const a = neutersNormalRedirectsChecks.indexOf(instance)
-						if (a > -1) neutersNormalRedirectsChecks.splice(a, 1)
-					}
-					browser.storage.local.set(
-						{
-							disableReuters: true,
-
-							reutersRedirects: redirects,
-
-							neutersNormalRedirectsChecks,
-							neutersNormalCustomRedirects: [],
-
-							neutersTorRedirectsChecks: [...redirects.neuters.tor],
-							neutersTorCustomRedirects: [],
-
-							neutersI2pRedirectsChecks: [...redirects.neuters.i2p],
-							neutersI2pCustomRedirects: [],
-
-							neutersLokiRedirectsChecks: [...redirects.neuters.loki],
-							neutersLokiCustomRedirects: [],
-						},
-						() => resolve()
-					)
-				})
-			})
-	})
-}
-
-export default {
-	setRedirects,
-	redirect,
-	initDefaults,
-}
diff --git a/src/assets/javascripts/search.js b/src/assets/javascripts/search.js
deleted file mode 100644
index 548e7629..00000000
--- a/src/assets/javascripts/search.js
+++ /dev/null
@@ -1,581 +0,0 @@
-window.browser = window.browser || window.chrome
-
-import utils from "./utils.js"
-
-const targets = [/^https?:\/{2}search\.libredirect\.invalid/]
-// Ill optimise all of assets/javascripts at a later date. For now, I'll just add librex and optimse options javascript
-const frontends = new Array("searx", "searxng", "whoogle", "librex")
-const protocols = new Array("normal", "tor", "i2p", "loki")
-
-let redirects = {}
-
-for (let i = 0; i < frontends.length; i++) {
-	redirects[frontends[i]] = {}
-	for (let x = 0; x < protocols.length; x++) {
-		redirects[frontends[i]][protocols[x]] = []
-	}
-}
-
-function setRedirects(val) {
-	return new Promise(resolve =>
-		browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
-			redirects = val
-			searxNormalRedirectsChecks = [...redirects.searx.normal]
-			searxngNormalRedirectsChecks = [...redirects.searxng.normal]
-			whoogleNormalRedirectsChecks = [...redirects.whoogle.normal]
-			librexNormalRedirectsChecks = [...redirects.librex.normal]
-			for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-				const a = searxNormalRedirectsChecks.indexOf(instance)
-				if (a > -1) searxNormalRedirectsChecks.splice(a, 1)
-
-				const b = searxngNormalRedirectsChecks.indexOf(instance)
-				if (b > -1) searxngNormalRedirectsChecks.splice(b, 1)
-
-				const c = whoogleNormalRedirectsChecks.indexOf(instance)
-				if (c > -1) whoogleNormalRedirectsChecks.splice(c, 1)
-
-				const d = librexNormalRedirectsChecks.indexOf(instance)
-				if (d > -1) librexNormalRedirectsChecks.splice(d, 1)
-			}
-			browser.storage.local.set(
-				{
-					searchRedirects: redirects,
-					searxNormalRedirectsChecks,
-					searxTorRedirectsChecks: [...redirects.searx.tor],
-					searxI2pRedirectsChecks: [...redirects.searx.i2p],
-					searxLokiRedirectsChecks: [...redirects.searx.loki],
-					searxngNormalRedirectsChecks,
-					searxngTorRedirectsChecks: [...redirects.searxng.tor],
-					searxngI2pRedirectsChecks: [...redirects.searxng.i2p],
-					searxngLokiRedirectsChecks: [...redirects.searxng.loki],
-					whoogleNormalRedirectsChecks,
-					whoogleTorRedirectsChecks: [...redirects.whoogle.tor],
-					whoogleI2pRedirectsChecks: [...redirects.whoogle.i2p],
-					whoogleLokiRedirectsChecks: [...redirects.whoogle.loki],
-					librexNormalRedirectsChecks,
-					librexTorRedirectsChecks: [...redirects.librex.tor],
-					librexI2pRedirectsChecks: [...redirects.librex.i2p],
-					librexLokiRedirectsChecks: [...redirects.librex.loki],
-				},
-				() => resolve()
-			)
-		})
-	)
-}
-
-let disableSearch,
-	searchFrontend,
-	searchRedirects,
-	protocol,
-	protocolFallback,
-	whoogleNormalRedirectsChecks,
-	whoogleNormalCustomRedirects,
-	whoogleTorRedirectsChecks,
-	whoogleTorCustomRedirects,
-	whoogleI2pRedirectsChecks,
-	whoogleI2pCustomRedirects,
-	whoogleLokiCustomRedirects,
-	searxNormalRedirectsChecks,
-	searxNormalCustomRedirects,
-	searxTorRedirectsChecks,
-	searxTorCustomRedirects,
-	searxI2pRedirectsChecks,
-	searxI2pCustomRedirects,
-	searxLokiCustomRedirects,
-	searxngNormalRedirectsChecks,
-	searxngNormalCustomRedirects,
-	searxngTorRedirectsChecks,
-	searxngTorCustomRedirects,
-	searxngI2pRedirectsChecks,
-	searxngI2pCustomRedirects,
-	searxngLokiCustomRedirects,
-	librexNormalRedirectsChecks,
-	librexNormalCustomRedirects,
-	librexTorRedirectsChecks,
-	librexTorCustomRedirects,
-	librexI2pRedirectsChecks,
-	librexI2pCustomRedirects,
-	librexLokiCustomRedirects
-
-function init() {
-	return new Promise(async resolve => {
-		browser.storage.local.get(
-			[
-				"disableSearch",
-				"searchFrontend",
-				"searchRedirects",
-				"protocol",
-				"protocolFallback",
-				"whoogleNormalRedirectsChecks",
-				"whoogleNormalCustomRedirects",
-				"whoogleTorRedirectsChecks",
-				"whoogleTorCustomRedirects",
-				"whoogleI2pRedirectsChecks",
-				"whoogleI2pCustomRedirects",
-				"whoogleLokiCustomRedirects",
-				"searxNormalRedirectsChecks",
-				"searxNormalCustomRedirects",
-				"searxTorRedirectsChecks",
-				"searxTorCustomRedirects",
-				"searxI2pRedirectsChecks",
-				"searxI2pCustomRedirects",
-				"searxLokiCustomRedirects",
-				"searxngNormalRedirectsChecks",
-				"searxngNormalCustomRedirects",
-				"searxngTorRedirectsChecks",
-				"searxngTorCustomRedirects",
-				"searxngI2pRedirectsChecks",
-				"searxngI2pCustomRedirects",
-				"searxngLokiCustomRedirects",
-				"librexNormalRedirectsChecks",
-				"librexNormalCustomRedirects",
-				"librexTorRedirectsChecks",
-				"librexTorCustomRedirects",
-				"librexI2pRedirectsChecks",
-				"librexI2pCustomRedirects",
-				"librexLokiCustomRedirects",
-			],
-			r => {
-				disableSearch = r.disableSearch
-				searchFrontend = r.searchFrontend
-				searchRedirects = r.searchRedirects
-				protocol = r.protocol
-				protocolFallback = r.protocolFallback
-				whoogleNormalRedirectsChecks = r.whoogleNormalRedirectsChecks
-				whoogleNormalCustomRedirects = r.whoogleNormalCustomRedirects
-				whoogleTorRedirectsChecks = r.whoogleTorRedirectsChecks
-				whoogleTorCustomRedirects = r.whoogleTorCustomRedirects
-				whoogleI2pRedirectsChecks = r.whoogleI2pRedirectsChecks
-				whoogleI2pCustomRedirects = r.whoogleI2pCustomRedirects
-				whoogleLokiCustomRedirects = r.whoogleLokiCustomRedirects
-				searxNormalRedirectsChecks = r.searxNormalRedirectsChecks
-				searxNormalCustomRedirects = r.searxNormalCustomRedirects
-				searxTorRedirectsChecks = r.searxTorRedirectsChecks
-				searxTorCustomRedirects = r.searxTorCustomRedirects
-				searxI2pRedirectsChecks = r.searxI2pRedirectsChecks
-				searxI2pCustomRedirects = r.searxI2pCustomRedirects
-				searxLokiCustomRedirects = r.searxLokiCustomRedirects
-				searxngNormalRedirectsChecks = r.searxngNormalRedirectsChecks
-				searxngNormalCustomRedirects = r.searxngNormalCustomRedirects
-				searxngTorRedirectsChecks = r.searxngTorRedirectsChecks
-				searxngTorCustomRedirects = r.searxngTorCustomRedirects
-				searxngI2pRedirectsChecks = r.searxngI2pRedirectsChecks
-				searxngI2pCustomRedirects = r.searxngI2pCustomRedirects
-				searxngLokiCustomRedirects = r.searxngLokiCustomRedirects
-				librexNormalRedirectsChecks = r.librexNormalRedirectsChecks
-				librexNormalCustomRedirects = r.librexNormalCustomRedirects
-				librexTorRedirectsChecks = r.librexTorRedirectsChecks
-				librexTorCustomRedirects = r.librexTorCustomRedirects
-				librexI2pRedirectsChecks = r.librexI2pRedirectsChecks
-				librexI2pCustomRedirects = r.librexI2pCustomRedirects
-				librexLokiCustomRedirects = r.librexLokiCustomRedirects
-				resolve()
-			}
-		)
-	})
-}
-
-init()
-browser.storage.onChanged.addListener(init)
-
-function initSearxCookies(test, from) {
-	return new Promise(async resolve => {
-		await init()
-		let protocolHost = utils.protocolHost(from)
-		if (
-			![
-				...searxNormalRedirectsChecks,
-				...searxNormalCustomRedirects,
-				...searxTorRedirectsChecks,
-				...searxTorCustomRedirects,
-				...searxI2pRedirectsChecks,
-				...searxI2pCustomRedirects,
-				...searxLokiCustomRedirects,
-			].includes(protocolHost)
-		) {
-			resolve()
-			return
-		}
-
-		if (!test) {
-			let checkedInstances = []
-			if (protocol == "loki") checkedInstances = [...searxLokiCustomRedirects]
-			else if (protocol == "i2p") checkedInstances = [...searxI2pCustomRedirects, ...searxI2pRedirectsChecks]
-			else if (protocol == "tor") checkedInstances = [...searxTorRedirectsChecks, ...searxTorCustomRedirects]
-			if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
-				checkedInstances = [...searxNormalRedirectsChecks, ...searxNormalCustomRedirects]
-			}
-			await utils.copyCookie("searx", from, checkedInstances, "advanced_search")
-			await utils.copyCookie("searx", from, checkedInstances, "autocomplete")
-			await utils.copyCookie("searx", from, checkedInstances, "categories")
-			await utils.copyCookie("searx", from, checkedInstances, "disabled_engines")
-			await utils.copyCookie("searx", from, checkedInstances, "disabled_plugins")
-			await utils.copyCookie("searx", from, checkedInstances, "doi_resolver")
-			await utils.copyCookie("searx", from, checkedInstances, "enabled_engines")
-			await utils.copyCookie("searx", from, checkedInstances, "enabled_plugins")
-			await utils.copyCookie("searx", from, checkedInstances, "image_proxy")
-			await utils.copyCookie("searx", from, checkedInstances, "language")
-			await utils.copyCookie("searx", from, checkedInstances, "locale")
-			await utils.copyCookie("searx", from, checkedInstances, "method")
-			await utils.copyCookie("searx", from, checkedInstances, "oscar-style")
-			await utils.copyCookie("searx", from, checkedInstances, "results_on_new_tab")
-			await utils.copyCookie("searx", from, checkedInstances, "safesearch")
-			await utils.copyCookie("searx", from, checkedInstances, "theme")
-			await utils.copyCookie("searx", from, checkedInstances, "tokens")
-		}
-		resolve(true)
-	})
-}
-
-function initSearxngCookies(test, from) {
-	return new Promise(async resolve => {
-		await init()
-		let protocolHost = utils.protocolHost(from)
-		if (
-			![
-				...searxngNormalRedirectsChecks,
-				...searxngNormalCustomRedirects,
-				...searxngTorRedirectsChecks,
-				...searxngTorCustomRedirects,
-				...searxngI2pRedirectsChecks,
-				...searxngI2pCustomRedirects,
-				...searxngLokiCustomRedirects,
-			].includes(protocolHost)
-		) {
-			resolve()
-			return
-		}
-
-		if (!test) {
-			let checkedInstances = []
-			if (protocol == "loki") checkedInstances = [...searxngLokiCustomRedirects]
-			else if (protocol == "i2p") checkedInstances = [...searxngI2pCustomRedirects, ...searxngI2pRedirectsChecks]
-			else if (protocol == "tor") checkedInstances = [...searxngTorRedirectsChecks, ...searxngTorCustomRedirects]
-			if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
-				checkedInstances = [...searxngNormalRedirectsChecks, ...searxngNormalCustomRedirects]
-			}
-			await utils.copyCookie("searxng", from, checkedInstances, "autocomplete")
-			await utils.copyCookie("searxng", from, checkedInstances, "categories")
-			await utils.copyCookie("searxng", from, checkedInstances, "disabled_engines")
-			await utils.copyCookie("searxng", from, checkedInstances, "disabled_plugins")
-			await utils.copyCookie("searxng", from, checkedInstances, "doi_resolver")
-			await utils.copyCookie("searxng", from, checkedInstances, "enabled_plugins")
-			await utils.copyCookie("searxng", from, checkedInstances, "enabled_engines")
-			await utils.copyCookie("searxng", from, checkedInstances, "image_proxy")
-			await utils.copyCookie("searxng", from, checkedInstances, "infinite_scroll")
-			await utils.copyCookie("searxng", from, checkedInstances, "language")
-			await utils.copyCookie("searxng", from, checkedInstances, "locale")
-			await utils.copyCookie("searxng", from, checkedInstances, "maintab")
-			await utils.copyCookie("searxng", from, checkedInstances, "method")
-			await utils.copyCookie("searxng", from, checkedInstances, "query_in_title")
-			await utils.copyCookie("searxng", from, checkedInstances, "results_on_new_tab")
-			await utils.copyCookie("searxng", from, checkedInstances, "safesearch")
-			await utils.copyCookie("searxng", from, checkedInstances, "simple_style")
-			await utils.copyCookie("searxng", from, checkedInstances, "theme")
-			await utils.copyCookie("searxng", from, checkedInstances, "tokens")
-		}
-		resolve(true)
-	})
-}
-
-function initLibrexCookies(test, from) {
-	return new Promise(async resolve => {
-		await init()
-		let protocolHost = utils.protocolHost(from)
-		if (
-			![
-				...librexNormalRedirectsChecks,
-				...librexNormalCustomRedirects,
-				...librexTorRedirectsChecks,
-				...librexTorCustomRedirects,
-				...librexI2pRedirectsChecks,
-				...librexI2pCustomRedirects,
-				...librexLokiCustomRedirects,
-			].includes(protocolHost)
-		) {
-			resolve()
-			return
-		}
-
-		if (!test) {
-			let checkedInstances = []
-			if (protocol == "loki") checkedInstances = [...librexLokiCustomRedirects]
-			else if (protocol == "i2p") checkedInstances = [...librexI2pCustomRedirects, ...librexI2pRedirectsChecks]
-			else if (protocol == "tor") checkedInstances = [...librexTorRedirectsChecks, ...librexTorCustomRedirects]
-			if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
-				checkedInstances = [...librexNormalRedirectsChecks, ...librexNormalCustomRedirects]
-			}
-			await utils.copyCookie("librex", from, checkedInstances, "bibliogram")
-			await utils.copyCookie("librex", from, checkedInstances, "disable_special")
-			await utils.copyCookie("librex", from, checkedInstances, "invidious")
-			await utils.copyCookie("librex", from, checkedInstances, "libreddit")
-			await utils.copyCookie("librex", from, checkedInstances, "nitter")
-			await utils.copyCookie("librex", from, checkedInstances, "proxitok")
-			await utils.copyCookie("librex", from, checkedInstances, "theme")
-			await utils.copyCookie("librex", from, checkedInstances, "wikiless")
-		}
-		resolve(true)
-	})
-}
-
-function redirect(url, disableOverride) {
-	if (disableSearch && !disableOverride) return
-	if (!targets.some(rx => rx.test(url.href))) return
-	if (url.searchParams.has("tbm")) return
-	if (url.hostname.includes("google") && !url.searchParams.has("q") && url.pathname != "/") return
-	let randomInstance
-	let path
-	if (searchFrontend == "searx") {
-		let instancesList = []
-		if (protocol == "loki") instancesList = [...searxLokiCustomRedirects]
-		else if (protocol == "i2p") instancesList = [...searxI2pCustomRedirects, ...searxI2pRedirectsChecks]
-		else if (protocol == "tor") instancesList = [...searxTorRedirectsChecks, ...searxTorCustomRedirects]
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			instancesList = [...searxNormalRedirectsChecks, ...searxNormalCustomRedirects]
-		}
-		if (instancesList.length === 0) {
-			return
-		}
-
-		randomInstance = utils.getRandomInstance(instancesList)
-		path = "/"
-	} else if (searchFrontend == "searxng") {
-		let instancesList = []
-		if (protocol == "loki") instancesList = [...searxngLokiCustomRedirects]
-		else if (protocol == "i2p") instancesList = [...searxngI2pCustomRedirects, ...searxngI2pRedirectsChecks]
-		else if (protocol == "tor") instancesList = [...searxngTorRedirectsChecks, ...searxngTorCustomRedirects]
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			instancesList = [...searxngNormalRedirectsChecks, ...searxngNormalCustomRedirects]
-		}
-		if (instancesList.length === 0) {
-			return
-		}
-
-		randomInstance = utils.getRandomInstance(instancesList)
-		path = "/"
-	} else if (searchFrontend == "whoogle") {
-		let instancesList = []
-		if (protocol == "loki") instancesList = [...whoogleLokiCustomRedirects]
-		else if (protocol == "i2p") instancesList = [...whoogleI2pCustomRedirects, ...whoogleI2pRedirectsChecks]
-		else if (protocol == "tor") instancesList = [...whoogleTorRedirectsChecks, ...whoogleTorCustomRedirects]
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			instancesList = [...whoogleNormalRedirectsChecks, ...whoogleNormalCustomRedirects]
-		}
-		if (instancesList.length === 0) {
-			return
-		}
-
-		randomInstance = utils.getRandomInstance(instancesList)
-		path = "/search"
-	} else if (searchFrontend == "librex") {
-		let instancesList = []
-		if (protocol == "loki") instancesList = [...librexLokiCustomRedirects]
-		else if (protocol == "i2p") instancesList = [...librexI2pCustomRedirects, ...librexI2pRedirectsChecks]
-		else if (protocol == "tor") instancesList = [...librexTorRedirectsChecks, ...librexTorCustomRedirects]
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			instancesList = [...librexNormalRedirectsChecks, ...librexNormalCustomRedirects]
-		}
-		if (instancesList.length === 0) {
-			return
-		}
-
-		randomInstance = utils.getRandomInstance(instancesList)
-		path = "/search.php"
-	}
-
-	if (((url.hostname.includes("google") || url.hostname.includes("bing")) && !url.searchParams.has("q")) || (url.hostname.includes("yandex") && !url.searchParams.has("text"))) path = "/"
-
-	let searchQuery = ""
-	if ((url.hostname.includes("google") || url.hostname.includes("bing") || url.hostname.includes("search.libredirect.invalid")) && url.searchParams.has("q"))
-		searchQuery = `?q=${encodeURIComponent(url.searchParams.get("q"))}`
-	if (url.hostname.includes("yandex") && url.searchParams.has("text")) searchQuery = `?q=${url.searchParams.get("text")}`
-
-	return `${randomInstance}${path}${searchQuery}`
-}
-
-function switchInstance(url, disableOverride) {
-	return new Promise(async resolve => {
-		await init()
-		if (disableSearch && !disableOverride) {
-			resolve()
-			return
-		}
-		let protocolHost = utils.protocolHost(url)
-		if (
-			![
-				...searchRedirects.searx.normal,
-				...searchRedirects.searx.tor,
-				...searchRedirects.searx.i2p,
-
-				...searchRedirects.searxng.normal,
-				...searchRedirects.searxng.tor,
-				...searchRedirects.searxng.i2p,
-
-				...searchRedirects.whoogle.normal,
-				...searchRedirects.whoogle.tor,
-				...searchRedirects.whoogle.i2p,
-
-				...searchRedirects.librex.normal,
-				...searchRedirects.librex.tor,
-				...searchRedirects.librex.i2p,
-
-				...searxNormalCustomRedirects,
-				...searxTorCustomRedirects,
-				...searxI2pCustomRedirects,
-				...searxLokiCustomRedirects,
-
-				...searxngNormalCustomRedirects,
-				...searxngTorCustomRedirects,
-				...searxngI2pCustomRedirects,
-				...searxngLokiCustomRedirects,
-
-				...whoogleNormalCustomRedirects,
-				...whoogleTorCustomRedirects,
-				...whoogleI2pCustomRedirects,
-				...whoogleLokiCustomRedirects,
-
-				...librexNormalCustomRedirects,
-				...librexTorCustomRedirects,
-				...librexI2pCustomRedirects,
-				...librexLokiCustomRedirects,
-			].includes(protocolHost)
-		) {
-			resolve()
-			return
-		}
-
-		let instancesList = []
-
-		if (protocol == "loki") {
-			if (searchFrontend == "searx") instancesList = [...searxLokiCustomRedirects]
-			else if (searchFrontend == "searxng") instancesList = [...searxngLokiCustomRedirects]
-			else if (searchFrontend == "whoogle") instancesList = [...whoogleLokiCustomRedirects]
-			else if (searchFrontend == "librex") instancesList = [...librexLokiCustomRedirects]
-		} else if (protocol == "tor") {
-			if (searchFrontend == "searx") instancesList = [...searxTorRedirectsChecks, ...searxTorCustomRedirects]
-			else if (searchFrontend == "searxng") instancesList = [...searxngTorRedirectsChecks, ...searxngTorCustomRedirects]
-			else if (searchFrontend == "whoogle") instancesList = [...whoogleTorRedirectsChecks, ...whoogleTorCustomRedirects]
-			else if (searchFrontend == "librex") instancesList = [...librexTorRedirectsChecks, ...librexTorCustomRedirects]
-		} else if (protocol == "i2p") {
-			if (searchFrontend == "searx") instancesList = [...searxI2pRedirectsChecks, ...searxI2pCustomRedirects]
-			else if (searchFrontend == "searxng") instancesList = [...searxngI2pRedirectsChecks, ...searxngI2pCustomRedirects]
-			else if (searchFrontend == "whoogle") instancesList = [...whoogleI2pRedirectsChecks, ...whoogleI2pCustomRedirects]
-			else if (searchFrontend == "librex") instancesList = [...librexI2pRedirectsChecks, ...librexI2pCustomRedirects]
-		}
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			if (searchFrontend == "searx") instancesList = [...searxNormalRedirectsChecks, ...searxNormalCustomRedirects]
-			else if (searchFrontend == "searxng") instancesList = [...searxngNormalRedirectsChecks, ...searxngNormalCustomRedirects]
-			else if (searchFrontend == "whoogle") instancesList = [...whoogleNormalRedirectsChecks, ...whoogleNormalCustomRedirects]
-			else if (searchFrontend == "librex") instancesList = [...librexNormalRedirectsChecks, ...librexNormalCustomRedirects]
-		}
-		const i = instancesList.indexOf(protocolHost)
-		if (i > -1) instancesList.splice(i, 1)
-		if (instancesList.length === 0) {
-			resolve()
-			return
-		}
-
-		const randomInstance = utils.getRandomInstance(instancesList)
-		resolve(`${randomInstance}${url.pathname}${url.search}`)
-	})
-}
-
-function initDefaults() {
-	return new Promise(async resolve => {
-		fetch("/instances/data.json")
-			.then(response => response.text())
-			.then(async data => {
-				let dataJson = JSON.parse(data)
-				for (let i = 0; i < frontends.length; i++) {
-					redirects[frontends[i]] = dataJson[frontends[i]]
-				}
-
-				browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
-					searxNormalRedirectsChecks = [...redirects.searx.normal]
-					searxngNormalRedirectsChecks = [...redirects.searxng.normal]
-					whoogleNormalRedirectsChecks = [...redirects.whoogle.normal]
-					librexNormalRedirectsChecks = [...redirects.librex.normal]
-					for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-						const a = searxNormalRedirectsChecks.indexOf(instance)
-						if (a > -1) searxNormalRedirectsChecks.splice(a, 1)
-
-						const b = searxngNormalRedirectsChecks.indexOf(instance)
-						if (b > -1) searxngNormalRedirectsChecks.splice(b, 1)
-
-						const c = whoogleNormalRedirectsChecks.indexOf(instance)
-						if (c > -1) whoogleNormalRedirectsChecks.splice(c, 1)
-
-						const d = librexNormalRedirectsChecks.indexOf(instance)
-						if (d > -1) librexNormalRedirectsChecks.splice(d, 1)
-					}
-					browser.storage.local.set(
-						{
-							disableSearch: false,
-							searchFrontend: "searxng",
-							searchRedirects: redirects,
-							searxngCustomSettings: false,
-
-							whoogleNormalRedirectsChecks,
-							whoogleNormalCustomRedirects: [],
-
-							whoogleTorRedirectsChecks: [...redirects.whoogle.tor],
-							whoogleTorCustomRedirects: [],
-
-							whoogleI2pRedirectsChecks: [...redirects.whoogle.i2p],
-							whoogleI2pCustomRedirects: [],
-
-							whoogleLokiRedirectsChecks: [...redirects.whoogle.loki],
-							whoogleLokiCustomRedirects: [],
-
-							searxNormalRedirectsChecks,
-							searxNormalCustomRedirects: [],
-
-							searxTorRedirectsChecks: [...redirects.searx.tor],
-							searxTorCustomRedirects: [],
-
-							searxI2pRedirectsChecks: [...redirects.searx.i2p],
-							searxI2pCustomRedirects: [],
-
-							searxLokiRedirectsChecks: [...redirects.searx.loki],
-							searxLokiCustomRedirects: [],
-
-							searxngNormalRedirectsChecks,
-							searxngNormalCustomRedirects: [],
-
-							searxngTorRedirectsChecks: [...redirects.searxng.tor],
-							searxngTorCustomRedirects: [],
-
-							searxngI2pRedirectsChecks: [...redirects.searxng.i2p],
-							searxngI2pCustomRedirects: [],
-
-							searxngLokiRedirectsChecks: [...redirects.searxng.loki],
-							searxngLokiCustomRedirects: [],
-
-							librexNormalRedirectsChecks,
-							librexNormalCustomRedirects: [],
-
-							librexTorRedirectsChecks: [...redirects.librex.tor],
-							librexTorCustomRedirects: [],
-
-							librexI2pRedirectsChecks: [...redirects.librex.i2p],
-							librexI2pCustomRedirects: [],
-
-							librexLokiRedirectsChecks: [...redirects.librex.loki],
-							librexLokiCustomRedirects: [],
-						},
-						() => resolve()
-					)
-				})
-			})
-	})
-}
-
-export default {
-	setRedirects,
-	initSearxCookies,
-	initSearxngCookies,
-	initLibrexCookies,
-	redirect,
-	initDefaults,
-	switchInstance,
-}
diff --git a/src/assets/javascripts/sendTargets.js b/src/assets/javascripts/sendTargets.js
deleted file mode 100644
index a7b5f20b..00000000
--- a/src/assets/javascripts/sendTargets.js
+++ /dev/null
@@ -1,200 +0,0 @@
-window.browser = window.browser || window.chrome
-
-import utils from "./utils.js"
-
-const targets = [/^https?:\/{2}send\.libredirect\.invalid\/$/, /^ https ?: \/\/send\.firefox\.com\/$/, /^https?:\/{2}sendfiles\.online\/$/]
-
-const frontends = new Array("send")
-const protocols = new Array("normal", "tor", "i2p", "loki")
-
-let redirects = {}
-
-for (let i = 0; i < frontends.length; i++) {
-	redirects[frontends[i]] = {}
-	for (let x = 0; x < protocols.length; x++) {
-		redirects[frontends[i]][protocols[x]] = []
-	}
-}
-
-function setRedirects(val) {
-	return new Promise(resolve =>
-		browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
-			redirects.send = val
-			sendNormalRedirectsChecks = [...redirects.send.normal]
-			for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-				const a = sendNormalRedirectsChecks.indexOf(instance)
-				if (a > -1) sendNormalRedirectsChecks.splice(a, 1)
-			}
-			browser.storage.local.set(
-				{
-					sendTargetsRedirects: redirects,
-					sendNormalRedirectsChecks,
-					sendTorRedirectsChecks: [...redirects.send.tor],
-					sendI2pRedirectsChecks: [...redirects.send.i2p],
-					sendLokiRedirectsChecks: [...redirects.send.loki],
-				},
-				() => resolve()
-			)
-		})
-	)
-}
-
-let disableSendTarget,
-	sendTargetsRedirects,
-	sendNormalRedirectsChecks,
-	sendNormalCustomRedirects,
-	sendTorRedirectsChecks,
-	sendTorCustomRedirects,
-	sendI2pCustomRedirects,
-	sendLokiCustomRedirects,
-	protocol,
-	protocolFallback
-
-function init() {
-	return new Promise(resolve => {
-		browser.storage.local.get(
-			[
-				"disableSendTarget",
-				"sendTargetsRedirects",
-				"protocol",
-				"protocolFallback",
-				"sendNormalRedirectsChecks",
-				"sendNormalCustomRedirects",
-				"sendTorRedirectsChecks",
-				"sendTorCustomRedirects",
-				"sendI2pCustomRedirects",
-				"sendLokiCustomRedirects",
-			],
-			r => {
-				disableSendTarget = r.disableSendTarget
-				sendTargetsRedirects = r.sendTargetsRedirects
-				sendNormalRedirectsChecks = r.sendNormalRedirectsChecks
-				sendNormalCustomRedirects = r.sendNormalCustomRedirects
-				sendTorRedirectsChecks = r.sendTorRedirectsChecks
-				sendTorCustomRedirects = r.sendTorCustomRedirects
-				sendI2pCustomRedirects = r.sendI2pCustomRedirects
-				sendLokiCustomRedirects = r.sendLokiCustomRedirects
-				protocol = r.protocol
-				protocolFallback = r.protocolFallback
-				resolve()
-			}
-		)
-	})
-}
-
-init()
-browser.storage.onChanged.addListener(init)
-
-function all() {
-	return [
-		...sendTargetsRedirects.send.normal,
-		...sendTargetsRedirects.send.tor,
-		...sendNormalCustomRedirects,
-		...sendTorRedirectsChecks,
-		...sendTorCustomRedirects,
-		...sendI2pCustomRedirects,
-		...sendLokiCustomRedirects,
-	]
-}
-
-function switchInstance(url, disableOverride) {
-	return new Promise(async resolve => {
-		await init()
-		if (disableSendTarget && !disableOverride) {
-			resolve()
-			return
-		}
-		const protocolHost = utils.protocolHost(url)
-		if (!all().includes(protocolHost)) {
-			resolve()
-			return
-		}
-		if (url.pathname != "/") {
-			resolve()
-			return
-		}
-
-		let instancesList = []
-		if (protocol == "loki") instancesList = [...sendLokiCustomRedirects]
-		else if (protocol == "i2p") instancesList = [...sendI2pCustomRedirects]
-		else if (protocol == "tor") instancesList = [...sendTorRedirectsChecks, ...sendTorCustomRedirects]
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			instancesList = [...sendNormalRedirectsChecks, ...sendNormalCustomRedirects]
-		}
-
-		const i = instancesList.indexOf(protocolHost)
-		if (i > -1) instancesList.splice(i, 1)
-		if (instancesList.length === 0) {
-			resolve()
-			return
-		}
-
-		const randomInstance = utils.getRandomInstance(instancesList)
-		resolve(`${randomInstance}${url.pathname}${url.search}`)
-	})
-}
-
-function redirect(url, type, initiator, disableOverride) {
-	if (disableSendTarget && !disableOverride) return
-	if (type != "main_frame") return
-	if (initiator && (all().includes(initiator.origin) || targets.includes(initiator.host))) return
-	if (!targets.some(rx => rx.test(url.href))) return
-
-	let instancesList = []
-	if (protocol == "loki") instancesList = [...sendLokiCustomRedirects]
-	else if (protocol == "i2p") instancesList = [...sendI2pCustomRedirects]
-	else if (protocol == "tor") instancesList = [...sendTorRedirectsChecks, ...sendTorCustomRedirects]
-	if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-		instancesList = [...sendNormalRedirectsChecks, ...sendNormalCustomRedirects]
-	}
-	if (instancesList.length === 0) return
-
-	const randomInstance = utils.getRandomInstance(instancesList)
-	return randomInstance
-}
-
-function initDefaults() {
-	return new Promise(resolve => {
-		fetch("/instances/data.json")
-			.then(response => response.text())
-			.then(async data => {
-				let dataJson = JSON.parse(data)
-				for (let i = 0; i < frontends.length; i++) {
-					redirects[frontends[i]] = dataJson[frontends[i]]
-				}
-				browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
-					sendNormalRedirectsChecks = [...redirects.send.normal]
-					for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-						const a = sendNormalRedirectsChecks.indexOf(instance)
-						if (a > -1) sendNormalRedirectsChecks.splice(a, 1)
-					}
-					browser.storage.local.set(
-						{
-							disableSendTarget: false,
-							sendTargetsRedirects: redirects,
-
-							sendNormalRedirectsChecks,
-							sendNormalCustomRedirects: [],
-
-							sendTorRedirectsChecks: [...redirects.send.tor],
-							sendTorCustomRedirects: [],
-
-							sendI2pRedirectsChecks: [...redirects.send.i2p],
-							sendI2pCustomRedirects: [],
-
-							sendLokiRedirectsChecks: [...redirects.send.loki],
-							sendLokiCustomRedirects: [],
-						},
-						() => resolve()
-					)
-				})
-			})
-	})
-}
-
-export default {
-	setRedirects,
-	redirect,
-	switchInstance,
-	initDefaults,
-}
diff --git a/src/assets/javascripts/services.js b/src/assets/javascripts/services.js
new file mode 100644
index 00000000..afd7906f
--- /dev/null
+++ b/src/assets/javascripts/services.js
@@ -0,0 +1,682 @@
+window.browser = window.browser || window.chrome

+

+import utils from "./utils.js"

+

+let config, options, redirects

+

+function init() {

+	return new Promise(async resolve => {

+		browser.storage.local.get(["options", "redirects"], r => {

+			options = r.options

+			redirects = r.redirects

+			fetch("/config/config.json")

+				.then(response => response.text())

+				.then(configData => {

+					config = JSON.parse(configData)

+					resolve()

+				})

+		})

+	})

+}

+

+init()

+browser.storage.onChanged.addListener(init)

+

+function fetchFrontendInstanceList(service, frontend, redirects, options, config) {

+	let tmp = []

+	if (config.services[service].frontends[frontend].instanceList) {

+		for (const network in config.networks) {

+			tmp.push(...redirects[network], ...options[frontend][network].custom)

+		}

+	} else if (config.services[service].frontends[frontend].singleInstance) tmp = config.services[service].frontends[frontend].singleInstance

+	return tmp

+}

+

+function all(service, frontend, options, config, redirects) {

+	let instances = []

+	if (!frontend) {

+		for (const frontend in config.services[service].frontends) {

+			instances.push(...fetchFrontendInstanceList(service, frontend, redirects[frontend], options, config))

+		}

+	} else {

+		instances.push(...fetchFrontendInstanceList(service, frontend, redirects[frontend], options, config))

+	}

+	return instances

+}

+

+function regexArray(service, url, config) {

+	let targets

+	if (config.services[service].targets == "datajson") {

+		browser.storage.local.get("targets", r => {

+			targets = r.targets[service]

+		})

+	} else {

+		targets = config.services[service].targets

+	}

+	for (const targetString in targets) {

+		const target = new RegExp(targets[targetString])

+		if (target.test(url.href)) return true

+	}

+	return false

+}

+

+function redirect(url, type, initiator) {

+	let randomInstance

+	let frontend

+	for (const service in config.services) {

+		if (!options[service].enabled) continue

+		if (config.services[service].embeddable && type != options[service].redirectType && options[service].redirectType != "both") continue

+		if (!config.services[service].embeddable && type != "main_frame") continue

+		let targets = new RegExp(config.services[service].targets.join("|"), "i")

+

+		if (!regexArray(service, url, config)) continue

+		if (initiator) {

+			if (targets.test(initiator.host)) continue

+			if (all(service, null, options, config, redirects).includes(initiator.origin)) return "BYPASSTAB"

+		}

+

+		if (Object.keys(config.services[service].frontends).length > 1) {

+			if (type == "sub_frame" && config.services[service].embeddable && !config.services[service].frontends[options[service].frontend].embeddable) frontend = options[service].embedFrontend

+			else frontend = options[service].frontend

+		} else frontend = Object.keys(config.services[service].frontends)[0]

+

+		if (config.services[service].frontends[frontend].instanceList) {

+			let instanceList = [...options[frontend][options.network].enabled, ...options[frontend][options.network].custom]

+			if (instanceList.length === 0 && options.networkFallback) instanceList = [...options[frontend].clearnet.enabled, ...options[frontend].clearnet.custom]

+			if (instanceList.length === 0) return

+			randomInstance = utils.getRandomInstance(instanceList)

+		} else if (config.services[service].frontends[frontend].singleInstance) randomInstance = config.services[service].frontends[frontend].singleInstance

+		break

+	}

+	if (!frontend) return

+

+	// Here is a (temperory) space for defining constants required in 2 or more switch cases.

+	// When possible, try have the two switch cases share all their code as done with searx and searxng.

+	// Do not do that when they do not share 100% of their code.

+

+	const mapCentreRegex = /@(-?\d[0-9.]*),(-?\d[0-9.]*),(\d{1,2})[.z]/

+	const dataLatLngRegex = /!3d(-?[0-9]{1,}.[0-9]{1,})!4d(-?[0-9]{1,}.[0-9]{1,})/

+	const placeRegex = /\/place\/(.*)\//

+	function convertMapCentre() {

+		let [lat, lon, zoom] = [null, null, null]

+		if (url.pathname.match(mapCentreRegex)) {

+			// Set map centre if present

+			;[lat, lon, zoom] = url.pathname.match(mapCentreRegex)

+		} else if (url.searchParams.has("center")) {

+			;[lat, lon] = url.searchParams.get("center").split(",")

+			zoom = url.searchParams.get("zoom") ?? "17"

+		}

+		return [zoom, lon, lat]

+	}

+

+	switch (frontend) {

+		// This is where all instance-specific code must be ran to convert the service url to one that can be understood by the frontend.

+		case "beatbump":

+			return `${randomInstance}${url.pathname}${url.search}`

+				.replace("/watch?v=", "/listen?id=")

+				.replace("/channel/", "/artist/")

+				.replace("/playlist?list=", "/playlist/VL")

+				.replace(/\/search\?q=.*/, searchQuery => searchQuery.replace("?q=", "/") + "?filter=all")

+		case "hyperpipe":

+			return `${randomInstance}${url.pathname}${url.search}`.replace(/\/search\?q=.*/, searchQuery => searchQuery.replace("?q=", "/"))

+		case "bibliogram":

+			const reservedPaths = ["u", "p", "privacy"]

+			if (url.pathname === "/" || reservedPaths.includes(url.pathname.split("/")[1])) return `${randomInstance}${url.pathname}${url.search}`

+			if (url.pathname.startsWith("/reel") || url.pathname.startsWith("/tv")) return `${randomInstance}/p${url.pathname.replace(/\/reel|\/tv/i, "")}${url.search}`

+			else return `${randomInstance}/u${url.pathname}${url.search}` // Likely a user profile, redirect to '/u/...'

+		case "lbryDesktop":

+			return url.href.replace(/^https?:\/{2}odysee\.com\//, "lbry://").replace(/:(?=[a-zA-Z0-9])/g, "#")

+		case "neuters":

+			if (url.pathname.startsWith("/article/") || url.pathname.startsWith("/pf/") || url.pathname.startsWith("/arc/") || url.pathname.startsWith("/resizer/")) return null

+			else if (url.pathname.endsWith("/")) return `${randomInstance}${url.pathname}`

+			else return `${randomInstance}${url.pathname}/`

+		case "searx":

+		case "searxng":

+			return `${randomInstance}/?q=${encodeURIComponent(url.searchParams.get("q"))}`

+		case "whoogle":

+			return `${randomInstance}/search${encodeURIComponent(url.searchParams.get("q"))}`

+		case "librex":

+			return `${randomInstance}/search.php?q=${encodeURIComponent(url.searchParams.get("q"))}`

+		case "send":

+			return randomInstance

+		case "nitter":

+			if (url.host.split(".")[0] === "pbs" || url.host.split(".")[0] === "video") {

+				const [, id, format, extra] = url.search.match(/(.*)\?format=(.*)&(.*)/)

+				const query = encodeURIComponent(`${id}.${format}?${extra}`)

+				return `${randomInstance}/pic${url.pathname}${query}`

+			} else if (url.pathname.split("/").includes("tweets")) return `${randomInstance}${url.pathname.replace("/tweets", "")}${url.search}`

+			else if (url.host == "t.co") return `${randomInstance}/t.co${url.pathname}`

+			else return `${randomInstance}${url.pathname}${url.search}`

+		case "yattee":

+			return url.href.replace(/^https?:\/{2}/, "yattee://")

+		case "freetube":

+			return `freetube://https://youtu.be${url.pathname}${url.search}`.replace(/watch\?v=/, "")

+		case "simplyTranslate":

+			return `${randomInstance}/${url.search}`

+		case "osm": {

+			if (initiator && initiator.host === "earth.google.com") return

+			const travelModes = {

+				driving: "fossgis_osrm_car",

+				walking: "fossgis_osrm_foot",

+				bicycling: "fossgis_osrm_bike",

+				transit: "fossgis_osrm_car", // not implemented on OSM, default to car.

+			}

+

+			function addressToLatLng(address) {

+				const xmlhttp = new XMLHttpRequest()

+				xmlhttp.open("GET", `https://nominatim.openstreetmap.org/search/${address}?format=json&limit=1`, false)

+				xmlhttp.send()

+				if (xmlhttp.status === 200) {

+					const json = JSON.parse(xmlhttp.responseText)[0]

+					if (json) {

+						console.log("json", json)

+						return [`${json.lat},${json.lon}`, `${json.boundingbox[2]},${json.boundingbox[1]},${json.boundingbox[3]},${json.boundingbox[0]}`]

+					}

+				}

+				console.info("Error: Status is " + xmlhttp.status)

+			}

+

+			let mapCentre = "#"

+			let prefs = {}

+

+			const mapCentreData = convertMapCentre()

+			if (mapCentreData[0] && mapCentreData[1] && mapCentreData[2]) mapCentre = `#map=${mapCentreData[0]}/${mapCentreData[1]}/${mapCentreData[2]}`

+			if (url.searchParams.get("layer")) prefs.layers = osmLayers[url.searchParams.get("layer")]

+

+			if (url.pathname.includes("/embed")) {

+				// Handle Google Maps Embed API

+				// https://www.google.com/maps/embed/v1/place?key=AIzaSyD4iE2xVSpkLLOXoyqT-RuPwURN3ddScAI&q=Eiffel+Tower,Paris+France

+				//console.log("embed life")

+

+				let query = ""

+				if (url.searchParams.has("q")) query = url.searchParams.get("q")

+				else if (url.searchParams.has("query")) query = url.searchParams.has("query")

+				else if (url.searchParams.has("pb"))

+					try {

+						query = url.searchParams.get("pb").split(/!2s(.*?)!/)[1]

+					} catch (error) {

+						console.error(error)

+					} // Unable to find map marker in URL.

+

+				let [coords, boundingbox] = addressToLatLng(query)

+				prefs.bbox = boundingbox

+				prefs.marker = coords

+				prefs.layer = "mapnik"

+				let prefsEncoded = new URLSearchParams(prefs).toString()

+				return `${randomInstance}/export/embed.html?${prefsEncoded}`

+			} else if (url.pathname.includes("/dir")) {

+				// Handle Google Maps Directions

+				// https://www.google.com/maps/dir/?api=1&origin=Space+Needle+Seattle+WA&destination=Pike+Place+Market+Seattle+WA&travelmode=bicycling

+

+				let travMod = url.searchParams.get("travelmode")

+				if (url.searchParams.has("travelmode")) prefs.engine = travelModes[travMod]

+

+				let orgVal = url.searchParams.get("origin")

+				let destVal = url.searchParams.get("destination")

+

+				let org = addressToLatLng(orgVal)

+				let dest = addressToLatLng(destVal)

+				prefs.route = `${org};${dest}`

+

+				let prefsEncoded = new URLSearchParams(prefs).toString()

+				return `${randomInstance}/directions?${prefsEncoded}${mapCentre}`

+			} else if (url.pathname.includes("data=") && url.pathname.match(dataLatLngRegex)) {

+				// Get marker from data attribute

+				// https://www.google.com/maps/place/41%C2%B001'58.2%22N+40%C2%B029'18.2%22E/@41.032833,40.4862063,17z/data=!3m1!4b1!4m6!3m5!1s0x0:0xf64286eaf72fc49d!7e2!8m2!3d41.0328329!4d40.4883948

+				//console.log("data life")

+

+				let [, mlat, mlon] = url.pathname.match(dataLatLngRegex)

+

+				return `${randomInstance}/search?query=${mlat}%2C${mlon}`

+			} else if (url.searchParams.has("ll")) {

+				// Get marker from ll param

+				// https://maps.google.com/?ll=38.882147,-76.99017

+				//console.log("ll life")

+

+				const [mlat, mlon] = url.searchParams.get("ll").split(",")

+

+				return `${randomInstance}/search?query=${mlat}%2C${mlon}`

+			} else if (url.searchParams.has("viewpoint")) {

+				// Get marker from viewpoint param.

+				// https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=48.857832,2.295226&heading=-45&pitch=38&fov=80

+				//console.log("viewpoint life")

+

+				const [mlat, mlon] = url.searchParams.get("viewpoint").split(",")

+

+				return `${randomInstance}/search?query=${mlat}%2C${mlon}`

+			} else {

+				// Use query as search if present.

+				//console.log("normal life")

+

+				let query

+				if (url.searchParams.has("q")) query = url.searchParams.get("q")

+				else if (url.searchParams.has("query")) query = url.searchParams.get("query")

+				else if (url.pathname.match(placeRegex)) query = url.pathname.match(placeRegex)[1]

+

+				let prefsEncoded = new URLSearchParams(prefs).toString()

+				if (query) return `${randomInstance}/search?query="${query}${mapCentre}&${prefsEncoded}`

+			}

+

+			let prefsEncoded = new URLSearchParams(prefs).toString()

+			console.log("mapCentre", mapCentre)

+			console.log("prefs", prefs)

+			console.log("prefsEncoded", prefsEncoded)

+			return `${randomInstance}/${mapCentre}&${prefsEncoded}`

+		}

+		case "facil": {

+			if (initiator && initiator.host === "earth.google.com") return

+			const travelModes = {

+				driving: "car",

+				walking: "pedestrian",

+				bicycling: "bicycle",

+				transit: "car", // not implemented on Facil, default to car.

+			}

+			const mapCentreData = convertMapCentre()

+			let mapCentre = "#"

+			if (mapCentreData[0] && mapCentreData[1] && mapCentreData[2]) mapCentre = `#${mapCentreData[0]}/${mapCentreData[1]}/${mapCentreData[2]}`

+

+			if (url.pathname.includes("/embed")) {

+				// Handle Google Maps Embed API

+				// https://www.google.com/maps/embed/v1/place?key=AIzaSyD4iE2xVSpkLLOXoyqT-RuPwURN3ddScAI&q=Eiffel+Tower,Paris+France

+				//console.log("embed life")

+

+				let query = ""

+				if (url.searchParams.has("q")) query = url.searchParams.get("q")

+				else if (url.searchParams.has("query")) query = url.searchParams.has("query")

+				else if (url.searchParams.has("pb"))

+					try {

+						query = url.searchParams.get("pb").split(/!2s(.*?)!/)[1]

+					} catch (error) {

+						console.error(error)

+					} // Unable to find map marker in URL.

+

+				return `${randomInstance}/#q=${query}`

+			} else if (url.pathname.includes("/dir")) {

+				// Handle Google Maps Directions

+				// https://www.google.com/maps/dir/?api=1&origin=Space+Needle+Seattle+WA&destination=Pike+Place+Market+Seattle+WA&travelmode=bicycling

+

+				let travMod = url.searchParams.get("travelmode")

+

+				let orgVal = url.searchParams.get("origin")

+				let destVal = url.searchParams.get("destination")

+

+				return `${randomInstance}/#q=${orgVal}%20to%20${destVal}%20by%20${travelModes[travMod]}`

+			} else if (url.pathname.includes("data=") && url.pathname.match(dataLatLngRegex)) {

+				// Get marker from data attribute

+				// https://www.google.com/maps/place/41%C2%B001'58.2%22N+40%C2%B029'18.2%22E/@41.032833,40.4862063,17z/data=!3m1!4b1!4m6!3m5!1s0x0:0xf64286eaf72fc49d!7e2!8m2!3d41.0328329!4d40.4883948

+				//console.log("data life")

+

+				let [, mlat, mlon] = url.pathname.match(dataLatLngRegex)

+

+				return `${randomInstance}/#q=${mlat}%2C${mlon}`

+			} else if (url.searchParams.has("ll")) {

+				// Get marker from ll param

+				// https://maps.google.com/?ll=38.882147,-76.99017

+				//console.log("ll life")

+

+				const [mlat, mlon] = url.searchParams.get("ll").split(",")

+

+				return `${randomInstance}/#q=${mlat}%2C${mlon}`

+			} else if (url.searchParams.has("viewpoint")) {

+				// Get marker from viewpoint param.

+				// https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=48.857832,2.295226&heading=-45&pitch=38&fov=80

+				//console.log("viewpoint life")

+

+				const [mlat, mlon] = url.searchParams.get("viewpoint").split(",")

+

+				return `${randomInstance}/#q=${mlat}%2C${mlon}`

+			} else {

+				// Use query as search if present.

+				//console.log("normal life")

+

+				let query

+				if (url.searchParams.has("q")) query = url.searchParams.get("q")

+				else if (url.searchParams.has("query")) query = url.searchParams.get("query")

+				else if (url.pathname.match(placeRegex)) query = url.pathname.match(placeRegex)[1]

+

+				if (query) return `${randomInstance}/${mapCentre}/Mpnk/${query}`

+			}

+		}

+		case "wikiless":

+			let GETArguments = []

+			if (url.search.length > 0) {

+				let search = url.search.substring(1) //get rid of '?'

+				let argstrings = search.split("&")

+				for (let i = 0; i < argstrings.length; i++) {

+					let args = argstrings[i].split("=")

+					GETArguments.push([args[0], args[1]])

+				}

+			}

+

+			let link = `${randomInstance}${url.pathname}`

+			let urlSplit = url.host.split(".")

+			if (urlSplit[0] != "wikipedia" && urlSplit[0] != "www") {

+				if (urlSplit[0] == "m") GETArguments.push(["mobileaction", "toggle_view_mobile"])

+				else GETArguments.push(["lang", urlSplit[0]])

+				if (urlSplit[1] == "m") GETArguments.push(["mobileaction", "toggle_view_mobile"])

+				// wikiless doesn't have mobile view support yet

+			}

+			for (let i = 0; i < GETArguments.length; i++) link += (i == 0 ? "?" : "&") + GETArguments[i][0] + "=" + GETArguments[i][1]

+			return link

+

+		case "lingva":

+			let params_arr = url.search.split("&")

+			params_arr[0] = params_arr[0].substring(1)

+			let params = {}

+			for (let i = 0; i < params_arr.length; i++) {

+				let pair = params_arr[i].split("=")

+				params[pair[0]] = pair[1]

+			}

+			if (params.sl && params.tl && params.text) {

+				return `${randomInstance}/${params.sl}/${params.tl}/${params.text}`

+			}

+			return randomInstance

+		default:

+			return `${randomInstance}${url.pathname}${url.search}`

+	}

+}

+

+function computeService(url, returnFrontend) {

+	return new Promise(resolve => {

+		fetch("/config/config.json")

+			.then(response => response.text())

+			.then(configData => {

+				const config = JSON.parse(configData)

+				browser.storage.local.get(["redirects", "options"], r => {

+					const redirects = r.redirects

+					const options = r.options

+					for (const service in config.services) {

+						if (regexArray(service, url, config)) {

+							if (returnFrontend) {

+								resolve([service, null])

+							} else {

+								resolve(service)

+							}

+							return

+						} else {

+							for (const frontend in config.services[service].frontends) {

+								if (all(service, frontend, options, config, redirects).includes(utils.protocolHost(url))) {

+									if (returnFrontend) {

+										resolve([service, frontend])

+									} else {

+										resolve(service)

+									}

+									return

+								}

+							}

+						}

+					}

+					resolve()

+				})

+			})

+	})

+}

+

+function switchInstance(url) {

+	return new Promise(async resolve => {

+		await init()

+		const protocolHost = utils.protocolHost(url)

+		for (const service in config.services) {

+			if (!all(service, null, options, config, redirects).includes(protocolHost)) continue

+

+			let instancesList = [...options[options[service].frontend][options.network].enabled, ...options[options[service].frontend][options.network].custom]

+			if (instancesList.length === 0 && options.networkFallback) instancesList = [...options[options[service].frontend].clearnet.enabled, ...options[options[service].frontend].clearnet.custom]

+

+			let oldInstance

+			const i = instancesList.indexOf(protocolHost)

+			if (i > -1) {

+				oldInstance = instancesList[i]

+				instancesList.splice(i, 1)

+			}

+			if (instancesList.length === 0) {

+				resolve()

+				return

+			}

+			const randomInstance = utils.getRandomInstance(instancesList)

+			const oldUrl = `${oldInstance}${url.pathname}${url.search}`

+			// This is to make instance switching work when the instance depends on the pathname, eg https://darmarit.org/searx

+			// Doesn't work because of .includes array method, not a top priotiry atm

+			resolve(oldUrl.replace(oldInstance, randomInstance))

+			return

+		}

+		resolve()

+	})

+}

+

+function reverse(url) {

+	return new Promise(async resolve => {

+		await init()

+		let protocolHost = utils.protocolHost(url)

+		for (const service in config.services) {

+			if (!all(service, null, options, config, redirects).includes(protocolHost)) continue

+

+			switch (service) {

+				case "instagram":

+					if (url.pathname.startsWith("/p")) resolve(`https://instagram.com${url.pathname.replace("/p", "")}${url.search}`)

+					if (url.pathname.startsWith("/u")) resolve(`https://instagram.com${url.pathname.replace("/u", "")}${url.search}`)

+					resolve(config.services[service].url + url.pathname + url.search)

+					return

+				case "youtube":

+				case "imdb":

+				case "imgur":

+				case "tiktok":

+				case "twitter":

+				case "reddit":

+					resolve(config.services[service].url + url.pathname + url.search)

+					return

+				default:

+					resolve()

+					return

+			}

+		}

+		resolve()

+	})

+}

+

+function unifyPreferences(url, tabId) {

+	return new Promise(async resolve => {

+		await init()

+		const protocolHost = utils.protocolHost(url)

+		for (const service in config.services) {

+			for (const frontend in config.services[service].frontends) {

+				if (all(service, frontend, options, config, redirects).includes(protocolHost)) {

+					let instancesList = [...options[frontend][options.network].enabled, ...options[frontend][options.network].custom]

+					if (options.networkFallback && options.network != "clearnet") instancesList.push(...options[frontend].clearnet.enabled, ...options[frontend].clearnet.custom)

+

+					const frontendObject = config.services[service].frontends[frontend]

+					if ("cookies" in frontendObject.preferences) {

+						for (const cookie of frontendObject.preferences.cookies) {

+							utils.copyCookie(frontendObject, url, instancesList, cookie)

+						}

+					}

+					if ("localstorage" in frontendObject.preferences) {

+						browser.storage.local.set({ tmp: [frontend, frontendObject.preferences.localstorage] })

+						browser.tabs.executeScript(tabId, {

+							file: "/assets/javascripts/get-localstorage.js",

+							runAt: "document_start",

+						})

+						for (const instance of instancesList)

+							browser.tabs.create({ url: instance }, tab =>

+								browser.tabs.executeScript(tab.id, {

+									file: "/assets/javascripts/set-localstorage.js",

+									runAt: "document_start",

+								})

+							)

+					}

+					/*

+					if ("indexeddb" in frontendObject.preferences) {

+					}

+					if ("token" in frontendObject.preferences) {

+					}

+					*/

+					resolve(true)

+					return

+				}

+			}

+		}

+	})

+}

+

+async function setRedirects(redirects) {

+	fetch("/config/config.json")

+		.then(response => response.text())

+		.then(configData => {

+			//browser.storage.local.get(["options", "blacklists"], async r => {

+			//const options = r.options

+			const config = JSON.parse(configData)

+			let targets = {}

+			for (const service in config.services) {

+				if (config.services[service].targets == "datajson") {

+					targets[service] = redirects[service]

+				}

+				/*

+					for (const frontend in config.services[service].frontends) {

+						if (config.services[service].frontends[frontend].instanceList) {

+							for (const network in config.networks) {

+								options[frontend][network].enabled = redirects[frontend][network]

+							}

+							for (const blacklist in r.blacklists) {

+								for (const instance of blacklist) {

+									let i = options[frontend].clearnet.enabled.indexOf(instance)

+									if (i > -1) options[frontend].clearnet.enabled.splice(i, 1)

+								}

+							}

+						}

+					}

+					*/

+				// The above will be implemented with https://github.com/libredirect/libredirect/issues/334

+			}

+			browser.storage.local.set({ redirects, targets /*, options*/ })

+			//})

+		})

+}

+

+function initDefaults() {

+	return new Promise(resolve => {

+		fetch("/instances/data.json")

+			.then(response => response.text())

+			.then(data => {

+				fetch("/config/config.json")

+					.then(response => response.text())

+					.then(configData => {

+						browser.storage.local.get(["options", "blacklists"], r => {

+							let redirects = JSON.parse(data)

+							let options = r.options

+							let targets = {}

+							let config = JSON.parse(configData)

+							const localstorage = {}

+							const latency = {}

+							for (const service in config.services) {

+								options[service] = {}

+								if (config.services[service].targets == "datajson") {

+									targets[service] = redirects[service]

+								}

+								for (const defaultOption in config.services[service].options) {

+									options[service][defaultOption] = config.services[service].options[defaultOption]

+								}

+								for (const frontend in config.services[service].frontends) {

+									if (config.services[service].frontends[frontend].instanceList) {

+										options[frontend] = {}

+										for (const network in config.networks) {

+											options[frontend][network] = {}

+											options[frontend][network].enabled = JSON.parse(data)[frontend][network]

+											options[frontend][network].custom = []

+										}

+										for (const blacklist in r.blacklists) {

+											for (const instance of r.blacklists[blacklist]) {

+												let i = options[frontend].clearnet.enabled.indexOf(instance)

+												if (i > -1) options[frontend].clearnet.enabled.splice(i, 1)

+											}

+										}

+									}

+								}

+							}

+							browser.storage.local.set({ redirects, options, targets, latency, localstorage })

+							resolve()

+						})

+					})

+			})

+	})

+}

+

+function upgradeOptions() {

+	return new Promise(resolve => {

+		fetch("/config/config.json")

+			.then(response => response.text())

+			.then(configData => {

+				browser.storage.local.get(null, r => {

+					let options = r.options

+					let latency = {}

+					const config = JSON.parse(configData)

+					options.exceptions = r.exceptions

+					if (r.theme != "DEFAULT") options.theme = r.theme

+					options.popupServices = r.popupFrontends

+					let tmp = options.popupServices.indexOf("tikTok")

+					if (tmp > -1) {

+						options.popupServices.splice(tmp, 1)

+						options.popupServices.push("tiktok")

+					}

+					tmp = options.popupServices.indexOf("sendTarget")

+					if (tmp > -1) {

+						options.popupServices.splice(tmp, 1)

+						options.popupServices.push("sendFiles")

+					}

+					options.firstPartyIsolate = r.firstPartyIsolate

+					options.autoRedirect = r.autoRedirect

+					switch (r.onlyEmbeddedVideo) {

+						case "onlyNotEmbedded":

+							options.youtube.redirectType = "main_frame"

+						case "onlyEmbedded":

+							options.youtube.redirectType = "sub_frame"

+						case "both":

+							options.youtube.redirectType = "both"

+					}

+					for (const service in config.services) {

+						let oldService

+						switch (service) {

+							case "tiktok":

+								oldService = "tikTok"

+								break

+							case "sendFiles":

+								oldService = "sendTarget"

+								break

+							default:

+								oldService = service

+						}

+						options[service].enabled = !r["disable" + utils.camelCase(oldService)]

+						if (r[oldService + "Frontend"]) {

+							if (r[oldService + "Frontend"] == "yatte") options[service].frontend = "yattee"

+							else options[service].frontend = r[oldService + "Frontend"]

+						}

+						if (r[oldService + "RedirectType"]) options[service].redirectType = r[oldService + "RedirectType"]

+						if (r[oldService + "EmbedFrontend"] && (service != "youtube" || r[oldService + "EmbedFrontend"] == "invidious" || r[oldService + "EmbedFrontend"] == "piped"))

+							options[service].embedFrontend = r[oldService + "EmbedFrontend"]

+						for (const frontend in config.services[service].frontends) {

+							if (r[frontend + "Latency"]) latency[frontend] = r[frontend + "Latency"]

+							for (const network in config.networks) {

+								let protocol

+								if (network == "clearnet") protocol = "normal"

+								else protocol = network

+								if (r[frontend + utils.camelCase(protocol) + "RedirectsChecks"]) {

+									options[frontend][network].enabled = r[frontend + utils.camelCase(protocol) + "RedirectsChecks"]

+									options[frontend][network].custom = r[frontend + utils.camelCase(protocol) + "CustomRedirects"]

+								}

+							}

+						}

+					}

+					browser.storage.local.set({ options, latency }, () => resolve())

+				})

+			})

+	})

+}

+

+export default {

+	redirect,

+	computeService,

+	switchInstance,

+	reverse,

+	unifyPreferences,

+	setRedirects,

+	initDefaults,

+	upgradeOptions,

+}

diff --git a/src/assets/javascripts/set-localstorage.js b/src/assets/javascripts/set-localstorage.js
new file mode 100644
index 00000000..8dbfcad7
--- /dev/null
+++ b/src/assets/javascripts/set-localstorage.js
@@ -0,0 +1,13 @@
+window.browser = window.browser || window.chrome
+
+browser.storage.local.get(["localstorage", "tmp"], r => {
+	const localstorageJson = r.localstorage
+	const frontend = r.tmp[0]
+	const items = localstorageJson[frontend]
+
+	for (const item in items) {
+		localStorage.setItem(item, items[item])
+	}
+
+	window.close()
+})
diff --git a/src/assets/javascripts/tiktok.js b/src/assets/javascripts/tiktok.js
deleted file mode 100644
index 78106a15..00000000
--- a/src/assets/javascripts/tiktok.js
+++ /dev/null
@@ -1,251 +0,0 @@
-window.browser = window.browser || window.chrome
-
-import utils from "./utils.js"
-
-const targets = [/^https?:\/{2}(www\.|)tiktok\.com.*/]
-
-const frontends = new Array("proxiTok")
-const protocols = new Array("normal", "tor", "i2p", "loki")
-
-let redirects = {}
-
-for (let i = 0; i < frontends.length; i++) {
-	redirects[frontends[i]] = {}
-	for (let x = 0; x < protocols.length; x++) {
-		redirects[frontends[i]][protocols[x]] = []
-	}
-}
-
-function setRedirects(val) {
-	return new Promise(resolve =>
-		browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
-			redirects.proxiTok = val
-			proxiTokNormalRedirectsChecks = [...redirects.proxiTok.normal]
-			for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-				const a = proxiTokNormalRedirectsChecks.indexOf(instance)
-				if (a > -1) proxiTokNormalRedirectsChecks.splice(a, 1)
-			}
-			browser.storage.local.set(
-				{
-					tiktokRedirects: redirects,
-					proxiTokNormalRedirectsChecks,
-					proxiTokTorRedirectsChecks: [...redirects.proxiTok.tor],
-					proxiTokI2pRedirectsChecks: [...redirects.proxiTok.i2p],
-					proxiTokLokiRedirectsChecks: [...redirects.proxiTok.loki],
-				},
-				() => resolve()
-			)
-		})
-	)
-}
-
-function initProxiTokCookies(test, from) {
-	return new Promise(async resolve => {
-		await init()
-		let protocolHost = utils.protocolHost(from)
-		if (
-			![
-				...proxiTokNormalRedirectsChecks,
-				...proxiTokNormalCustomRedirects,
-				...proxiTokTorRedirectsChecks,
-				...proxiTokTorCustomRedirects,
-				...proxiTokI2pCustomRedirects,
-				...proxiTokLokiCustomRedirects,
-			].includes(protocolHost)
-		)
-			resolve()
-
-		if (!test) {
-			let checkedInstances = []
-			if (protocol == "loki") checkedInstances = [...proxiTokI2pCustomRedirects]
-			else if (protocol == "i2p") checkedInstances = [...proxiTokLokiCustomRedirects]
-			else if (protocol == "tor") checkedInstances = [...proxiTokTorRedirectsChecks, ...proxiTokTorCustomRedirects]
-			if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
-				checkedInstances = [...proxiTokNormalRedirectsChecks, ...proxiTokNormalCustomRedirects]
-			}
-			await utils.copyCookie("proxitok", from, checkedInstances, "theme")
-			await utils.copyCookie("proxitok", from, checkedInstances, "api-legacy")
-		}
-		resolve(true)
-	})
-}
-
-let disableTiktok,
-	protocol,
-	protocolFallback,
-	tiktokRedirects,
-	proxiTokNormalRedirectsChecks,
-	proxiTokNormalCustomRedirects,
-	proxiTokTorRedirectsChecks,
-	proxiTokTorCustomRedirects,
-	proxiTokI2pCustomRedirects,
-	proxiTokLokiCustomRedirects
-
-function init() {
-	return new Promise(async resolve => {
-		browser.storage.local.get(
-			[
-				"disableTiktok",
-				"protocol",
-				"protocolFallback",
-				"tiktokRedirects",
-				"proxiTokNormalRedirectsChecks",
-				"proxiTokNormalCustomRedirects",
-				"proxiTokTorRedirectsChecks",
-				"proxiTokTorCustomRedirects",
-				"proxiTokI2pCustomRedirects",
-				"proxiTokLokiCustomRedirects",
-			],
-			r => {
-				disableTiktok = r.disableTiktok
-				protocol = r.protocol
-				protocolFallback = r.protocolFallback
-				tiktokRedirects = r.tiktokRedirects
-				proxiTokNormalRedirectsChecks = r.proxiTokNormalRedirectsChecks
-				proxiTokNormalCustomRedirects = r.proxiTokNormalCustomRedirects
-				proxiTokTorRedirectsChecks = r.proxiTokTorRedirectsChecks
-				proxiTokTorCustomRedirects = r.proxiTokTorCustomRedirects
-				proxiTokI2pCustomRedirects = r.proxiTokI2pCustomRedirects
-				proxiTokLokiCustomRedirects = r.proxiTokLokiCustomRedirects
-				resolve()
-			}
-		)
-	})
-}
-
-init()
-browser.storage.onChanged.addListener(init)
-
-// https://www.tiktok.com/@keysikaspol/video/7061265241887345946
-// https://www.tiktok.com/@keysikaspol
-function redirect(url, type, initiator, disableOverride) {
-	if (disableTiktok && !disableOverride) return
-	if (type != "main_frame") return
-	const all = [...tiktokRedirects.proxiTok.normal, ...proxiTokNormalCustomRedirects]
-	if (initiator && (all.includes(initiator.origin) || targets.includes(initiator.host))) return
-	if (!targets.some(rx => rx.test(url.href))) return
-
-	let instancesList = []
-	if (protocol == "loki") instancesList = [...proxiTokI2pCustomRedirects]
-	else if (protocol == "i2p") instancesList = [...proxiTokLokiCustomRedirects]
-	else if (protocol == "tor") instancesList = [...proxiTokTorRedirectsChecks, ...proxiTokTorCustomRedirects]
-	if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-		instancesList = [...proxiTokNormalRedirectsChecks, ...proxiTokNormalCustomRedirects]
-	}
-	if (instancesList.length === 0) return
-
-	const randomInstance = utils.getRandomInstance(instancesList)
-	return `${randomInstance}${url.pathname}`
-}
-
-function reverse(url) {
-	return new Promise(async resolve => {
-		await init()
-		let protocolHost = utils.protocolHost(url)
-		const all = [
-			...tiktokRedirects.proxiTok.normal,
-			...tiktokRedirects.proxiTok.tor,
-			...proxiTokNormalCustomRedirects,
-			...proxiTokTorCustomRedirects,
-			...proxiTokI2pCustomRedirects,
-			...proxiTokLokiCustomRedirects,
-		]
-		if (!all.includes(protocolHost)) {
-			resolve()
-			return
-		}
-
-		resolve(`https://tiktok.com${url.pathname}${url.search}`)
-	})
-}
-
-function switchInstance(url, disableOverride) {
-	return new Promise(async resolve => {
-		await init()
-		if (disableTiktok && !disableOverride) {
-			resolve()
-			return
-		}
-		let protocolHost = utils.protocolHost(url)
-		const all = [
-			...tiktokRedirects.proxiTok.tor,
-			...tiktokRedirects.proxiTok.normal,
-
-			...proxiTokNormalCustomRedirects,
-			...proxiTokTorCustomRedirects,
-			...proxiTokI2pCustomRedirects,
-			...proxiTokLokiCustomRedirects,
-		]
-		if (!all.includes(protocolHost)) {
-			resolve()
-			return
-		}
-
-		let instancesList = []
-		if (protocol == "loki") instancesList = [...proxiTokI2pCustomRedirects]
-		else if (protocol == "i2p") instancesList = [...proxiTokLokiCustomRedirects]
-		else if (protocol == "tor") instancesList = [...proxiTokTorRedirectsChecks, ...proxiTokTorCustomRedirects]
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			instancesList = [...proxiTokNormalRedirectsChecks, ...proxiTokNormalCustomRedirects]
-		}
-
-		const i = instancesList.indexOf(protocolHost)
-		if (i > -1) instancesList.splice(i, 1)
-		if (instancesList.length === 0) {
-			resolve()
-			return
-		}
-
-		const randomInstance = utils.getRandomInstance(instancesList)
-		resolve(`${randomInstance}${url.pathname}${url.search}`)
-	})
-}
-
-function initDefaults() {
-	return new Promise(async resolve => {
-		fetch("/instances/data.json")
-			.then(response => response.text())
-			.then(async data => {
-				let dataJson = JSON.parse(data)
-				for (let i = 0; i < frontends.length; i++) {
-					redirects[frontends[i]] = dataJson[frontends[i]]
-				}
-				browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
-					proxiTokNormalRedirectsChecks = [...redirects.proxiTok.normal]
-					for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-						const a = proxiTokNormalRedirectsChecks.indexOf(instance)
-						if (a > -1) proxiTokNormalRedirectsChecks.splice(a, 1)
-					}
-					browser.storage.local.set(
-						{
-							disableTiktok: false,
-
-							tiktokRedirects: redirects,
-
-							proxiTokNormalRedirectsChecks,
-							proxiTokNormalCustomRedirects: [],
-
-							proxiTokTorRedirectsChecks: [...redirects.proxiTok.tor],
-							proxiTokTorCustomRedirects: [],
-
-							proxiTokI2pRedirectsChecks: [...redirects.proxiTok.i2p],
-							proxiTokI2pCustomRedirects: [],
-
-							proxiTokLokiRedirectsChecks: [...redirects.proxiTok.loki],
-							proxiTokLokiCustomRedirects: [],
-						},
-						() => resolve()
-					)
-				})
-			})
-	})
-}
-
-export default {
-	setRedirects,
-	redirect,
-	reverse,
-	switchInstance,
-	initProxiTokCookies,
-	initDefaults,
-}
diff --git a/src/assets/javascripts/translate/get_lingva_preferences.js b/src/assets/javascripts/translate/get_lingva_preferences.js
deleted file mode 100644
index 0d6ff6ec..00000000
--- a/src/assets/javascripts/translate/get_lingva_preferences.js
+++ /dev/null
@@ -1,10 +0,0 @@
-window.browser = window.browser || window.chrome
-
-browser.storage.local.set({
-	["lingva_chakra-ui-color-mode"]: localStorage.getItem("chakra-ui-color-mode"),
-	lingva_isauto: localStorage.getItem("isauto"),
-	lingva_source: localStorage.getItem("source"),
-	lingva_target: localStorage.getItem("target"),
-})
-
-console.log(localStorage.getItem("target"))
diff --git a/src/assets/javascripts/translate/set_lingva_preferences.js b/src/assets/javascripts/translate/set_lingva_preferences.js
deleted file mode 100644
index 04a36e1b..00000000
--- a/src/assets/javascripts/translate/set_lingva_preferences.js
+++ /dev/null
@@ -1,9 +0,0 @@
-window.browser = window.browser || window.chrome
-
-browser.storage.local.get(["lingva_chakra-ui-color-mode", "lingva_isauto", "lingva_source", "lingva_target"], r => {
-	if (r["lingva_chakra-ui-color-mode"] !== undefined) localStorage.setItem("chakra-ui-color-mode", r["lingva_chakra-ui-color-mode"])
-	if (r.lingva_isauto !== undefined) localStorage.setItem("isauto", r.lingva_isauto)
-	if (r.lingva_source !== undefined) localStorage.setItem("source", r.lingva_source)
-	if (r.lingva_target !== undefined) localStorage.setItem("target", r.lingva_target)
-	window.close()
-})
diff --git a/src/assets/javascripts/translate/translate.js b/src/assets/javascripts/translate/translate.js
deleted file mode 100644
index fa103169..00000000
--- a/src/assets/javascripts/translate/translate.js
+++ /dev/null
@@ -1,377 +0,0 @@
-window.browser = window.browser || window.chrome
-
-import utils from "../utils.js"
-
-const targets = [/^https?:\/{2}translate\.google(\.[a-z]{2,3}){1,2}\//]
-
-const frontends = new Array("simplyTranslate", "lingva")
-const protocols = new Array("normal", "tor", "i2p", "loki")
-
-let redirects = {}
-
-for (let i = 0; i < frontends.length; i++) {
-	redirects[frontends[i]] = {}
-	for (let x = 0; x < protocols.length; x++) {
-		redirects[frontends[i]][protocols[x]] = []
-	}
-}
-
-let translateDisable,
-	translateFrontend,
-	protocol,
-	protocolFallback,
-	translateRedirects,
-	simplyTranslateNormalRedirectsChecks,
-	simplyTranslateNormalCustomRedirects,
-	simplyTranslateTorRedirectsChecks,
-	simplyTranslateTorCustomRedirects,
-	simplyTranslateI2pRedirectsChecks,
-	simplyTranslateI2pCustomRedirects,
-	simplyTranslateLokiRedirectsChecks,
-	simplyTranslateLokiCustomRedirects,
-	lingvaNormalRedirectsChecks,
-	lingvaNormalCustomRedirects,
-	lingvaTorRedirectsChecks,
-	lingvaTorCustomRedirects,
-	lingvaI2pCustomRedirects,
-	lingvaLokiCustomRedirects
-
-function init() {
-	return new Promise(resolve => {
-		browser.storage.local.get(
-			[
-				"translateDisable",
-				"translateFrontend",
-				"protocol",
-				"protocolFallback",
-				"translateRedirects",
-				"simplyTranslateNormalRedirectsChecks",
-				"simplyTranslateNormalCustomRedirects",
-				"simplyTranslateTorRedirectsChecks",
-				"simplyTranslateTorCustomRedirects",
-				"simplyTranslateI2pRedirectsChecks",
-				"simplyTranslateI2pCustomRedirects",
-				"simplyTranslateLokiRedirectsChecks",
-				"simplyTranslateLokiCustomRedirects",
-
-				"lingvaNormalRedirectsChecks",
-				"lingvaNormalCustomRedirects",
-				"lingvaTorRedirectsChecks",
-				"lingvaTorCustomRedirects",
-				"lingvaI2pCustomRedirects",
-				"lingvaLokiCustomRedirects",
-			],
-			r => {
-				translateDisable = r.translateDisable
-				translateFrontend = r.translateFrontend
-				protocol = r.protocol
-				protocolFallback = r.protocolFallback
-				translateRedirects = r.translateRedirects
-				simplyTranslateNormalRedirectsChecks = r.simplyTranslateNormalRedirectsChecks
-				simplyTranslateNormalCustomRedirects = r.simplyTranslateNormalCustomRedirects
-				simplyTranslateTorRedirectsChecks = r.simplyTranslateTorRedirectsChecks
-				simplyTranslateTorCustomRedirects = r.simplyTranslateTorCustomRedirects
-				simplyTranslateI2pRedirectsChecks = r.simplyTranslateI2pRedirectsChecks
-				simplyTranslateI2pCustomRedirects = r.simplyTranslateI2pCustomRedirects
-				simplyTranslateLokiRedirectsChecks = r.simplyTranslateLokiRedirectsChecks
-				simplyTranslateLokiCustomRedirects = r.simplyTranslateLokiCustomRedirects
-				lingvaNormalRedirectsChecks = r.lingvaNormalRedirectsChecks
-				lingvaNormalCustomRedirects = r.lingvaNormalCustomRedirects
-				lingvaTorRedirectsChecks = r.lingvaTorRedirectsChecks
-				lingvaTorCustomRedirects = r.lingvaTorCustomRedirects
-				lingvaI2pCustomRedirects = r.lingvaI2pCustomRedirects
-				lingvaLokiCustomRedirects = r.lingvaLokiCustomRedirects
-				resolve()
-			}
-		)
-	})
-}
-
-init()
-browser.storage.onChanged.addListener(init)
-
-function setRedirects(val) {
-	return new Promise(resolve =>
-		browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
-			redirects = val
-			simplyTranslateNormalRedirectsChecks = [...redirects.simplyTranslate.normal]
-			lingvaNormalRedirectsChecks = [...redirects.lingva.normal]
-			for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-				const a = simplyTranslateNormalCustomRedirects.indexOf(instance)
-				if (a > -1) simplyTranslateNormalCustomRedirects.splice(a, 1)
-
-				const b = lingvaNormalRedirectsChecks.indexOf(instance)
-				if (b > -1) lingvaNormalRedirectsChecks.splice(b, 1)
-			}
-			browser.storage.local.set(
-				{
-					translateRedirects: redirects,
-					simplyTranslateNormalRedirectsChecks,
-					simplyTranslateTorRedirectsChecks: [...redirects.simplyTranslate.tor],
-					simplyTranslateI2pRedirectsChecks: [...redirects.simplyTranslate.i2p],
-					simplyTranslateLokiRedirectsChecks: [...redirects.simplyTranslate.loki],
-					lingvaNormalRedirectsChecks,
-					lingvaTorRedirectsChecks: [...redirects.lingva.tor],
-					lingvaI2pRedirectsChecks: [...redirects.lingva.i2p],
-					lingvaLokiRedirectsChecks: [...redirects.lingva.loki],
-				},
-				() => resolve()
-			)
-		})
-	)
-}
-
-function copyPasteLingvaLocalStorage(test, url, tabId) {
-	return new Promise(async resolve => {
-		await init()
-		if (translateDisable || translateFrontend != "lingva") {
-			resolve()
-			return
-		}
-		const protocolHost = utils.protocolHost(url)
-		if (
-			![...lingvaNormalRedirectsChecks, ...lingvaNormalCustomRedirects, ...lingvaTorRedirectsChecks, ...lingvaTorCustomRedirects, ...lingvaI2pCustomRedirects, ...lingvaLokiCustomRedirects].includes(
-				protocolHost
-			)
-		) {
-			resolve()
-			return
-		}
-
-		if (!test) {
-			browser.tabs.executeScript(tabId, {
-				file: "/assets/javascripts/translate/get_lingva_preferences.js",
-				runAt: "document_start",
-			})
-
-			let checkedInstances = []
-			if (protocol == "loki") checkedInstances = [...lingvaLokiCustomRedirects]
-			//...lingvaLokiRedirectsChecks,
-			else if (protocol == "i2p") checkedInstances = [...lingvaI2pCustomRedirects]
-			//...lingvaI2pRedirectsChecks,
-			else if (protocol == "tor") checkedInstances = [...lingvaTorRedirectsChecks, ...lingvaTorCustomRedirects]
-			if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
-				checkedInstances = [...lingvaNormalRedirectsChecks, ...lingvaNormalCustomRedirects]
-			}
-			const i = checkedInstances.indexOf(protocolHost)
-			if (i !== -1) checkedInstances.splice(i, 1)
-			if (checkedInstances.length === 0) {
-				resolve()
-				return
-			}
-			for (const to of checkedInstances)
-				browser.tabs.create({ url: to }, tab =>
-					browser.tabs.executeScript(tab.id, {
-						file: "/assets/javascripts/translate/set_lingva_preferences.js",
-						runAt: "document_start",
-					})
-				)
-		}
-		resolve(true)
-	})
-}
-
-function copyPasteSimplyTranslateCookies(test, from) {
-	return new Promise(async resolve => {
-		await init()
-		const protocolHost = utils.protocolHost(from)
-		if (
-			![
-				...simplyTranslateNormalRedirectsChecks,
-				...simplyTranslateNormalCustomRedirects,
-				...simplyTranslateTorRedirectsChecks,
-				...simplyTranslateTorCustomRedirects,
-				...simplyTranslateI2pRedirectsChecks,
-				...simplyTranslateI2pCustomRedirects,
-				...simplyTranslateLokiRedirectsChecks,
-				...simplyTranslateLokiCustomRedirects,
-			].includes(protocolHost)
-		) {
-			resolve()
-			return
-		}
-		if (!test) {
-			let checkedInstances = []
-			if (protocol == "loki") checkedInstances = [...simplyTranslateLokiRedirectsChecks, ...simplyTranslateLokiCustomRedirects]
-			else if (protocol == "i2p") checkedInstances = [...simplyTranslateI2pCustomRedirects, ...simplyTranslateI2pRedirectsChecks]
-			else if (protocol == "tor") checkedInstances = [...simplyTranslateTorRedirectsChecks, ...simplyTranslateTorCustomRedirects]
-			if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
-				checkedInstances = [...simplyTranslateNormalRedirectsChecks, ...simplyTranslateNormalCustomRedirects]
-			}
-			await utils.copyCookie("simplyTranslate", from, checkedInstances, "from_lang")
-			await utils.copyCookie("simplyTranslate", from, checkedInstances, "to_lang")
-			await utils.copyCookie("simplyTranslate", from, checkedInstances, "tts_enabled")
-			await utils.copyCookie("simplyTranslate", from, checkedInstances, "use_text_fields")
-		}
-		resolve(true)
-	})
-}
-
-function redirect(url, disableOverride) {
-	if (translateDisable && !disableOverride) return
-	if (!targets.some(rx => rx.test(url.href))) return
-
-	if (translateFrontend == "simplyTranslate") {
-		let instancesList = []
-		if (protocol == "loki") instancesList = [...simplyTranslateLokiRedirectsChecks, ...simplyTranslateLokiCustomRedirects]
-		else if (protocol == "i2p") instancesList = [...simplyTranslateI2pRedirectsChecks, ...simplyTranslateI2pCustomRedirects]
-		else if (protocol == "tor") instancesList = [...simplyTranslateTorRedirectsChecks, ...simplyTranslateTorCustomRedirects]
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			instancesList = [...simplyTranslateNormalRedirectsChecks, ...simplyTranslateNormalCustomRedirects]
-		}
-		if (instancesList.length === 0) return
-
-		const randomInstance = utils.getRandomInstance(instancesList)
-		return `${randomInstance}/${url.search}`
-	} else if (translateFrontend == "lingva") {
-		let params_arr = url.search.split("&")
-		params_arr[0] = params_arr[0].substring(1)
-		let params = {}
-		for (let i = 0; i < params_arr.length; i++) {
-			let pair = params_arr[i].split("=")
-			params[pair[0]] = pair[1]
-		}
-		let instancesList = []
-		if (protocol == "loki") instancesList = [...lingvaLokiCustomRedirects]
-		//...lingvaLokiRedirectsChecks,
-		else if (protocol == "i2p") instancesList = [...lingvaI2pCustomRedirects] //...lingvaI2pRedirectsChecks,
-		if (protocol == "tor") instancesList = [...lingvaTorRedirectsChecks, ...lingvaTorCustomRedirects]
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			instancesList = [...lingvaNormalRedirectsChecks, ...lingvaNormalCustomRedirects]
-		}
-		if (instancesList.length === 0) return
-
-		const randomInstance = utils.getRandomInstance(instancesList)
-		if (params.sl && params.tl && params.text) {
-			return `${randomInstance}/${params.sl}/${params.tl}/${params.text}`
-		}
-		return randomInstance
-	}
-}
-
-function switchInstance(url, disableOverride) {
-	return new Promise(async resolve => {
-		await init()
-		if (translateDisable && !disableOverride) {
-			resolve()
-			return
-		}
-		const protocolHost = utils.protocolHost(url)
-		if (
-			![
-				...translateRedirects.simplyTranslate.normal,
-				...translateRedirects.simplyTranslate.tor,
-				...translateRedirects.simplyTranslate.i2p,
-				...translateRedirects.simplyTranslate.loki,
-
-				...simplyTranslateNormalCustomRedirects,
-				...simplyTranslateTorCustomRedirects,
-				...simplyTranslateI2pCustomRedirects,
-				...simplyTranslateLokiCustomRedirects,
-
-				...translateRedirects.lingva.normal,
-				...translateRedirects.lingva.tor,
-
-				...lingvaNormalCustomRedirects,
-				...lingvaTorCustomRedirects,
-				...lingvaI2pCustomRedirects,
-				...lingvaLokiCustomRedirects,
-			].includes(protocolHost)
-		) {
-			resolve()
-			return
-		}
-
-		let instancesList = []
-
-		if (protocol == "loki") {
-			if (translateFrontend == "simplyTranslate") instancesList = [...simplyTranslateLokiRedirectsChecks, ...simplyTranslateLokiCustomRedirects]
-			else if (translateFrontend == "lingva") instancesList = [...lingvaLokiCustomRedirects] //...lingvaLokiRedirectsChecks,
-		} else if (protocol == "i2p") {
-			if (translateFrontend == "simplyTranslate") instancesList = [...simplyTranslateI2pRedirectsChecks, ...simplyTranslateI2pCustomRedirects]
-			else if (translateFrontend == "lingva") instancesList = [...lingvaI2pCustomRedirects] //...lingvaI2pRedirectsChecks,
-		} else if (protocol == "tor") {
-			if (translateFrontend == "simplyTranslate") instancesList = [...simplyTranslateTorRedirectsChecks, ...simplyTranslateTorCustomRedirects]
-			else if (translateFrontend == "lingva") instancesList = [...lingvaTorRedirectsChecks, ...lingvaTorCustomRedirects]
-		}
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			if (translateFrontend == "simplyTranslate") instancesList = [...simplyTranslateNormalRedirectsChecks, ...simplyTranslateNormalCustomRedirects]
-			else if (translateFrontend == "lingva") instancesList = [...lingvaNormalRedirectsChecks, ...lingvaNormalCustomRedirects]
-		}
-
-		const i = instancesList.indexOf(protocolHost)
-		if (i > -1) instancesList.splice(i, 1)
-		if (instancesList.length === 0) {
-			resolve()
-			return
-		}
-
-		const randomInstance = utils.getRandomInstance(instancesList)
-		resolve(`${randomInstance}${url.pathname}${url.search}`)
-	})
-}
-
-function initDefaults() {
-	return new Promise(async resolve => {
-		fetch("/instances/data.json")
-			.then(response => response.text())
-			.then(async data => {
-				let dataJson = JSON.parse(data)
-				for (let i = 0; i < frontends.length; i++) {
-					redirects[frontends[i]] = dataJson[frontends[i]]
-				}
-				browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
-					simplyTranslateNormalRedirectsChecks = [...redirects.simplyTranslate.normal]
-					lingvaNormalRedirectsChecks = [...redirects.lingva.normal]
-					for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-						const a = simplyTranslateNormalRedirectsChecks.indexOf(instance)
-						if (a > -1) simplyTranslateNormalRedirectsChecks.splice(a, 1)
-
-						const b = lingvaNormalRedirectsChecks.indexOf(instance)
-						if (b > -1) lingvaNormalRedirectsChecks.splice(b, 1)
-					}
-					browser.storage.local.set(
-						{
-							translateDisable: false,
-							translateFrontend: "simplyTranslate",
-							translateRedirects: redirects,
-
-							simplyTranslateNormalRedirectsChecks,
-							simplyTranslateNormalCustomRedirects: [],
-
-							simplyTranslateTorRedirectsChecks: [...redirects.simplyTranslate.tor],
-							simplyTranslateTorCustomRedirects: [],
-
-							simplyTranslateI2pRedirectsChecks: [...redirects.simplyTranslate.i2p],
-							simplyTranslateI2pCustomRedirects: [],
-
-							simplyTranslateLokiRedirectsChecks: [...redirects.simplyTranslate.loki],
-							simplyTranslateLokiCustomRedirects: [],
-
-							lingvaNormalRedirectsChecks,
-							lingvaNormalCustomRedirects: [],
-
-							lingvaTorRedirectsChecks: [...redirects.lingva.tor],
-							lingvaTorCustomRedirects: [],
-
-							lingvaI2pRedirectsChecks: [...redirects.lingva.i2p],
-							lingvaI2pCustomRedirects: [],
-
-							lingvaLokiRedirectsChecks: [...redirects.lingva.loki],
-							lingvaLokiCustomRedirects: [],
-						},
-						() => resolve()
-					)
-				})
-			})
-	})
-}
-
-export default {
-	copyPasteSimplyTranslateCookies,
-	copyPasteLingvaLocalStorage,
-	setRedirects,
-	redirect,
-	initDefaults,
-	switchInstance,
-}
diff --git a/src/assets/javascripts/twitter.js b/src/assets/javascripts/twitter.js
deleted file mode 100644
index eca8219f..00000000
--- a/src/assets/javascripts/twitter.js
+++ /dev/null
@@ -1,286 +0,0 @@
-window.browser = window.browser || window.chrome
-
-import utils from "./utils.js"
-
-const targets = [/^https?:\/{2}(www\.|mobile\.|)twitter\.com/, /^https?:\/{2}(pbs\.|video\.|)twimg\.com/, /^https?:\/{2}platform\.twitter\.com\/embed/, /^https?:\/{2}t\.co/]
-
-const frontends = new Array("nitter")
-const protocols = new Array("normal", "tor", "i2p", "loki")
-
-let redirects = {}
-
-for (let i = 0; i < frontends.length; i++) {
-	redirects[frontends[i]] = {}
-	for (let x = 0; x < protocols.length; x++) {
-		redirects[frontends[i]][protocols[x]] = []
-	}
-}
-
-function setRedirects(val) {
-	return new Promise(resolve =>
-		browser.storage.local.get(["cloudflareBlackList", "authenticateBlackList", "offlineBlackList"], r => {
-			redirects.nitter = val
-			nitterNormalRedirectsChecks = [...redirects.nitter.normal]
-			for (const instance of [...r.cloudflareBlackList, ...r.authenticateBlackList, ...r.offlineBlackList]) {
-				let i = nitterNormalRedirectsChecks.indexOf(instance)
-				if (i > -1) nitterNormalRedirectsChecks.splice(i, 1)
-			}
-			browser.storage.local.set(
-				{
-					twitterRedirects: redirects,
-					nitterNormalRedirectsChecks,
-					nitterTorRedirectsChecks: [...redirects.nitter.tor],
-					nitterI2pRedirectsChecks: [...redirects.nitter.i2p],
-					nitterLokiRedirectsChecks: [...redirects.nitter.loki],
-				},
-				() => resolve()
-			)
-		})
-	)
-}
-
-let disableTwitter,
-	protocol,
-	protocolFallback,
-	twitterRedirects,
-	twitterRedirectType,
-	nitterNormalRedirectsChecks,
-	nitterNormalCustomRedirects,
-	nitterTorRedirectsChecks,
-	nitterTorCustomRedirects,
-	nitterI2pCustomRedirects,
-	nitterLokiCustomRedirects
-
-function init() {
-	return new Promise(async resolve => {
-		browser.storage.local.get(
-			[
-				"disableTwitter",
-				"protocol",
-				"protocolFallback",
-				"twitterRedirects",
-				"twitterRedirectType",
-				"nitterNormalRedirectsChecks",
-				"nitterNormalCustomRedirects",
-				"nitterTorRedirectsChecks",
-				"nitterTorCustomRedirects",
-				"nitterI2pCustomRedirects",
-				"nitterLokiCustomRedirects",
-			],
-			r => {
-				disableTwitter = r.disableTwitter
-				protocol = r.protocol
-				protocolFallback = r.protocolFallback
-				twitterRedirects = r.twitterRedirects
-				twitterRedirectType = r.twitterRedirectType
-				nitterNormalRedirectsChecks = r.nitterNormalRedirectsChecks
-				nitterNormalCustomRedirects = r.nitterNormalCustomRedirects
-				nitterTorRedirectsChecks = r.nitterTorRedirectsChecks
-				nitterTorCustomRedirects = r.nitterTorCustomRedirects
-				nitterI2pCustomRedirects = r.nitterI2pCustomRedirects
-				nitterLokiCustomRedirects = r.nitterLokiCustomRedirects
-				resolve()
-			}
-		)
-	})
-}
-
-init()
-browser.storage.onChanged.addListener(init)
-
-function all() {
-	return [...nitterNormalRedirectsChecks, ...nitterTorRedirectsChecks, ...nitterNormalCustomRedirects, ...nitterTorCustomRedirects, ...nitterI2pCustomRedirects, ...nitterLokiCustomRedirects]
-}
-
-function redirect(url, type, initiator, disableOverride) {
-	if (disableTwitter && !disableOverride) return
-	if (!targets.some(rx => rx.test(url.href))) return
-	if (url.pathname.split("/").includes("home")) return
-	if (initiator && all().includes(initiator.origin)) return "BYPASSTAB"
-	if (twitterRedirectType == "main_frame" && type != "main_frame") return
-
-	let instancesList = []
-	if (protocol == "loki") instancesList = [...nitterI2pCustomRedirects]
-	else if (protocol == "i2p") instancesList = [...nitterLokiCustomRedirects]
-	else if (protocol == "tor") instancesList = [...nitterTorRedirectsChecks, ...nitterTorCustomRedirects]
-	if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-		instancesList = [...nitterNormalRedirectsChecks, ...nitterNormalCustomRedirects]
-	}
-	if (instancesList.length === 0) return
-
-	const randomInstance = utils.getRandomInstance(instancesList)
-	// https://pbs.twimg.com/profile_images/648888480974508032/66_cUYfj_400x400.jpg
-
-	let search = new URLSearchParams(url.search)
-
-	search.delete("ref_src")
-	search.delete("ref_url")
-
-	search = search.toString()
-	if (search !== "") search = `?${search}`
-
-	if (url.host.split(".")[0] === "pbs" || url.host.split(".")[0] === "video") {
-		const [, id, format, extra] = search.match(/(.*)\?format=(.*)&(.*)/)
-		const query = encodeURIComponent(`${id}.${format}?${extra}`)
-		return `${randomInstance}/pic${search}${query}`
-	}
-	if (url.pathname.split("/").includes("tweets")) {
-		return `${randomInstance}${url.pathname.replace("/tweets", "")}${search}`
-	}
-	if (url.host == "t.co") {
-		return `${randomInstance}/t.co${url.pathname}`
-	}
-	return `${randomInstance}${url.pathname}${search}`
-}
-
-function reverse(url) {
-	return new Promise(async resolve => {
-		await init()
-		const protocolHost = utils.protocolHost(url)
-		if (!all().includes(protocolHost)) {
-			resolve()
-			return
-		}
-		resolve(`https://twitter.com${url.pathname}${url.search}`)
-	})
-}
-
-function switchInstance(url, disableOverride) {
-	return new Promise(async resolve => {
-		await init()
-		if (disableTwitter && !disableOverride) {
-			resolve()
-			return
-		}
-		const protocolHost = utils.protocolHost(url)
-		if (!all().includes(protocolHost)) {
-			resolve()
-			return
-		}
-		let instancesList = []
-		if (protocol == "loki") instancesList = [...nitterI2pCustomRedirects]
-		else if (protocol == "i2p") instancesList = [...nitterLokiCustomRedirects]
-		else if (protocol == "tor") instancesList = [...nitterTorRedirectsChecks, ...nitterTorCustomRedirects]
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			instancesList = [...nitterNormalRedirectsChecks, ...nitterNormalCustomRedirects]
-		}
-
-		let index = instancesList.indexOf(protocolHost)
-		if (index > -1) instancesList.splice(index, 1)
-		if (instancesList.length === 0) {
-			resolve()
-			return
-		}
-
-		const randomInstance = utils.getRandomInstance(instancesList)
-		resolve(`${randomInstance}${url.pathname}${url.search}`)
-	})
-}
-
-function removeXFrameOptions(e) {
-	if (e.type != "sub_frame") return
-	let url = new URL(e.url)
-	let protocolHost = utils.protocolHost(url)
-	if (!all().includes(protocolHost)) return
-	let isChanged = false
-	for (const i in e.responseHeaders) {
-		if (e.responseHeaders[i].name == "x-frame-options") {
-			e.responseHeaders.splice(i, 1)
-			isChanged = true
-		} else if (e.responseHeaders[i].name == "content-security-policy") {
-			e.responseHeaders.splice(i, 1)
-			isChanged = true
-		}
-	}
-	if (isChanged) return { responseHeaders: e.responseHeaders }
-}
-
-function initNitterCookies(test, from) {
-	return new Promise(async resolve => {
-		await init()
-		const protocolHost = utils.protocolHost(from)
-		if (!all().includes(protocolHost)) {
-			resolve()
-			return
-		}
-		if (!test) {
-			let checkedInstances = []
-			if (protocol == "loki") checkedInstances = [...nitterI2pCustomRedirects]
-			else if (protocol == "i2p") checkedInstances = [...nitterLokiCustomRedirects]
-			else if (protocol == "tor") checkedInstances = [...nitterTorRedirectsChecks, ...nitterTorCustomRedirects]
-			if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
-				checkedInstances = [...nitterNormalRedirectsChecks, ...nitterNormalCustomRedirects]
-			}
-			await utils.copyCookie("nitter", from, checkedInstances, "theme")
-			await utils.copyCookie("nitter", from, checkedInstances, "infiniteScroll")
-			await utils.copyCookie("nitter", from, checkedInstances, "stickyProfile")
-			await utils.copyCookie("nitter", from, checkedInstances, "bidiSupport")
-			await utils.copyCookie("nitter", from, checkedInstances, "hideTweetStats")
-			await utils.copyCookie("nitter", from, checkedInstances, "hideBanner")
-			await utils.copyCookie("nitter", from, checkedInstances, "hidePins")
-			await utils.copyCookie("nitter", from, checkedInstances, "hideReplies")
-			await utils.copyCookie("nitter", from, checkedInstances, "squareAvatars")
-			await utils.copyCookie("nitter", from, checkedInstances, "mp4Playback")
-			await utils.copyCookie("nitter", from, checkedInstances, "hlsPlayback")
-			await utils.copyCookie("nitter", from, checkedInstances, "proxyVideos")
-			await utils.copyCookie("nitter", from, checkedInstances, "muteVideos")
-			await utils.copyCookie("nitter", from, checkedInstances, "autoplayGifs")
-
-			await utils.copyCookie("nitter", from, checkedInstances, "replaceInstagram")
-			await utils.copyCookie("nitter", from, checkedInstances, "replaceReddit")
-			await utils.copyCookie("nitter", from, checkedInstances, "replaceTwitter")
-			await utils.copyCookie("nitter", from, checkedInstances, "replaceYouTube")
-		}
-		resolve(true)
-	})
-}
-
-function initDefaults() {
-	return new Promise(resolve => {
-		fetch("/instances/data.json")
-			.then(response => response.text())
-			.then(data => {
-				let dataJson = JSON.parse(data)
-				for (let i = 0; i < frontends.length; i++) {
-					redirects[frontends[i]] = dataJson[frontends[i]]
-				}
-				browser.storage.local.get(["cloudflareBlackList", "authenticateBlackList", "offlineBlackList"], async r => {
-					nitterNormalRedirectsChecks = [...redirects.nitter.normal]
-					for (const instance of [...r.cloudflareBlackList, ...r.authenticateBlackList, ...r.offlineBlackList]) {
-						let i = nitterNormalRedirectsChecks.indexOf(instance)
-						if (i > -1) nitterNormalRedirectsChecks.splice(i, 1)
-					}
-					browser.storage.local.set(
-						{
-							disableTwitter: false,
-							twitterRedirects: redirects,
-							twitterRedirectType: "both",
-
-							nitterNormalRedirectsChecks,
-							nitterNormalCustomRedirects: [],
-
-							nitterTorRedirectsChecks: [...redirects.nitter.tor],
-							nitterTorCustomRedirects: [],
-
-							nitterI2pRedirectsChecks: [...redirects.nitter.i2p],
-							nitterI2pCustomRedirects: [],
-
-							nitterLokiRedirectsChecks: [...redirects.nitter.loki],
-							nitterLokiCustomRedirects: [],
-						},
-						() => resolve()
-					)
-				})
-			})
-	})
-}
-
-export default {
-	setRedirects,
-	redirect,
-	switchInstance,
-	reverse,
-	removeXFrameOptions,
-	initNitterCookies,
-	initDefaults,
-}
diff --git a/src/assets/javascripts/utils.js b/src/assets/javascripts/utils.js
deleted file mode 100644
index 5ca5c30b..00000000
--- a/src/assets/javascripts/utils.js
+++ /dev/null
@@ -1,574 +0,0 @@
-window.browser = window.browser || window.chrome
-import twitterHelper from "./twitter.js"
-import youtubeHelper from "./youtube/youtube.js"
-import instagramHelper from "./instagram.js"
-import mediumHelper from "./medium.js"
-import redditHelper from "./reddit.js"
-import searchHelper from "./search.js"
-import translateHelper from "./translate/translate.js"
-import wikipediaHelper from "./wikipedia.js"
-import peertubeHelper from "./peertube.js"
-import lbryHelper from "./lbry.js"
-import sendTargetsHelper from "./sendTargets.js"
-import tiktokHelper from "./tiktok.js"
-import quoraHelper from "./quora.js"
-import libremdbHelper from "./imdb.js"
-import imgurHelper from "./imgur.js"
-import reutersHelper from "./reuters.js"
-import youtubeMusicHelper from "./youtubeMusic.js"
-import mapsHelper from "./maps.js"
-import localise from "./localise.js"
-
-function getRandomInstance(instances) {
-	return instances[~~(instances.length * Math.random())]
-}
-
-let cloudflareBlackList = []
-let authenticateBlackList = []
-let offlineBlackList = []
-async function initBlackList() {
-	return new Promise(resolve => {
-		browser.storage.local.get(["cloudflareBlackList", "authenticateBlackList", "offlineBlackList"], r => {
-			cloudflareBlackList = r.cloudflareBlackList
-			authenticateBlackList = r.authenticateBlackList
-			offlineBlackList = r.offlineBlackList
-		})
-		if (cloudflareBlackList.length == 0) {
-			fetch("/instances/blacklist.json")
-				.then(response => response.text())
-				.then(data => {
-					cloudflareBlackList = JSON.parse(data).cloudflare
-					authenticateBlackList = JSON.parse(data).authenticate
-					offlineBlackList = JSON.parse(data).offline
-				})
-		}
-		resolve()
-	})
-}
-
-function updateBlackList() {
-	return new Promise(async resolve => {
-		let http = new XMLHttpRequest()
-		let fallback = new XMLHttpRequest()
-		http.open("GET", "https://codeberg.org/LibRedirect/libredirect/raw/branch/master/src/instances/blacklist.json", false)
-		http.send(null)
-		if (http.status != 200) {
-			fallback.open("GET", "https://raw.githubusercontent.com/libredirect/libredirect/master/src/instances/blacklist.json", false)
-			fallback.send(null)
-			if (fallback.status === 200) {
-				http = fallback
-			} else {
-				resolve()
-				return
-			}
-		}
-		const blackList = JSON.parse(http.responseText)
-		browser.storage.local.set({
-			cloudflareBlackList: blackList.cloudflare,
-			authenticateBlackList: blackList.authenticate,
-			offlineBlackList: blackList.offline,
-		})
-		;(cloudflareBlackList = blackList.cloudflare), (authenticateBlackList = blackList.authenticate), (offlineBlackList = blackList.offline)
-		resolve()
-	})
-}
-
-function updateInstances() {
-	return new Promise(async resolve => {
-		let http = new XMLHttpRequest()
-		let fallback = new XMLHttpRequest()
-		http.open("GET", "https://raw.githubusercontent.com/libredirect/libredirect/master/src/instances/data.json", false)
-		http.send(null)
-		if (http.status != 200) {
-			fallback.open("GET", "https://codeberg.org/LibRedirect/libredirect/raw/branch/master/src/instances/data.json", false)
-			fallback.send(null)
-			if (fallback.status === 200) {
-				http = fallback
-			} else {
-				resolve()
-				return
-			}
-		}
-		await updateBlackList()
-		const instances = JSON.parse(http.responseText)
-
-		await youtubeHelper.setRedirects({
-			invidious: instances.invidious,
-			piped: instances.piped,
-			pipedMaterial: instances.pipedMaterial,
-			cloudtube: instances.cloudtube,
-		})
-		await twitterHelper.setRedirects(instances.nitter)
-		await instagramHelper.setRedirects(instances.bibliogram)
-		await redditHelper.setRedirects({
-			libreddit: instances.libreddit,
-			teddit: instances.teddit,
-		})
-		await translateHelper.setRedirects({
-			simplyTranslate: instances.simplyTranslate,
-			lingva: instances.lingva,
-		})
-		await searchHelper.setRedirects({
-			searx: instances.searx,
-			searxng: instances.searxng,
-			whoogle: instances.whoogle,
-			librex: instances.librex,
-		})
-		await wikipediaHelper.setRedirects(instances.wikiless)
-		await mediumHelper.setRedirects(instances.scribe)
-		await quoraHelper.setRedirects(instances.quetre)
-		await libremdbHelper.setRedirects(instances.libremdb)
-		await sendTargetsHelper.setRedirects(instances.send)
-		await tiktokHelper.setRedirects(instances.proxiTok)
-		await lbryHelper.setRedirects(instances.librarian)
-		await reutersHelper.setRedirects(instances.neuters)
-		await youtubeMusicHelper.setRedirects({
-			beatbump: instances.beatbump,
-			hyperpipe: instances.hyperpipe,
-		})
-		await mapsHelper.setRedirects(instances.facil)
-		await peertubeHelper.setRedirects(instances.simpleertube)
-
-		console.info("Successfully updated Instances")
-		resolve(true)
-		return
-	})
-}
-
-function protocolHost(url) {
-	if (url.username && url.password) return `${url.protocol}//${url.username}:${url.password}@${url.host}`
-	return `${url.protocol}//${url.host}`
-}
-
-async function processDefaultCustomInstances(target, name, protocol, document) {
-	function camelCase(str) {
-		return str.charAt(0).toUpperCase() + str.slice(1)
-	}
-	let latencyKey = `${name}Latency`
-	let instancesLatency
-	let nameProtocolElement = document.getElementById(name).getElementsByClassName(protocol)[0]
-
-	let nameCustomInstances = []
-	let nameCheckListElement = nameProtocolElement.getElementsByClassName("checklist")[0]
-
-	await initBlackList()
-
-	let nameDefaultRedirects
-
-	let redirectsChecks = `${name}${camelCase(protocol)}RedirectsChecks`
-	let customRedirects = `${name}${camelCase(protocol)}CustomRedirects`
-	let redirectsKey = `${target}Redirects`
-
-	let redirects
-
-	async function getFromStorage() {
-		return new Promise(async resolve =>
-			browser.storage.local.get([redirectsChecks, customRedirects, redirectsKey, latencyKey], r => {
-				nameDefaultRedirects = r[redirectsChecks]
-				nameCustomInstances = r[customRedirects]
-				instancesLatency = r[latencyKey] ?? []
-				redirects = r[redirectsKey]
-				resolve()
-			})
-		)
-	}
-
-	await getFromStorage()
-	if (nameCustomInstances === undefined) console.log(customRedirects)
-
-	function calcNameCheckBoxes() {
-		let isTrue = true
-		for (const item of redirects[name][protocol]) {
-			if (nameDefaultRedirects === undefined) console.log(name + protocol + " is undefined")
-			if (!nameDefaultRedirects.includes(item)) {
-				isTrue = false
-				break
-			}
-		}
-		for (const element of nameCheckListElement.getElementsByTagName("input")) {
-			element.checked = nameDefaultRedirects.includes(element.className)
-		}
-		if (nameDefaultRedirects.length == 0) isTrue = false
-		nameProtocolElement.getElementsByClassName("toggle-all")[0].checked = isTrue
-	}
-	nameCheckListElement.innerHTML = [
-		`<div>
-        <x data-localise="__MSG_toggleAll__">Toggle All</x>
-        <input type="checkbox" class="toggle-all"/>
-      </div>`,
-		...redirects[name][protocol].map(x => {
-			const cloudflare = cloudflareBlackList.includes(x) ? ' <span style="color:red;">cloudflare</span>' : ""
-			const authenticate = authenticateBlackList.includes(x) ? ' <span style="color:orange;">authenticate</span>' : ""
-			const offline = offlineBlackList.includes(x) ? ' <span style="color:grey;">offline</span>' : ""
-
-			let ms = instancesLatency[x]
-			let latencyColor = ms <= 1000 ? "green" : ms <= 2000 ? "orange" : "red"
-			let latencyLimit
-			if (ms == 5000) latencyLimit = "5000ms+"
-			else if (ms > 5000) latencyLimit = `ERROR: ${ms - 5000}`
-			else latencyLimit = ms + "ms"
-
-			const latency = x in instancesLatency ? '<span style="color:' + latencyColor + ';">' + latencyLimit + "</span>" : ""
-
-			let warnings = [cloudflare, authenticate, offline, latency].join(" ")
-			return `<div>
-                    <x><a href="${x}" target="_blank">${x}</a>${warnings}</x>
-                    <input type="checkbox" class="${x}"/>
-                  </div>`
-		}),
-	].join("\n<hr>\n")
-
-	localise.localisePage()
-
-	calcNameCheckBoxes()
-	nameProtocolElement.getElementsByClassName("toggle-all")[0].addEventListener("change", async event => {
-		if (event.target.checked) nameDefaultRedirects = [...redirects[name][protocol]]
-		else nameDefaultRedirects = []
-
-		browser.storage.local.set({ [redirectsChecks]: nameDefaultRedirects })
-		calcNameCheckBoxes()
-	})
-
-	for (let element of nameCheckListElement.getElementsByTagName("input")) {
-		if (element.className != "toggle-all")
-			nameProtocolElement.getElementsByClassName(element.className)[0].addEventListener("change", async event => {
-				if (event.target.checked) nameDefaultRedirects.push(element.className)
-				else {
-					let index = nameDefaultRedirects.indexOf(element.className)
-					if (index > -1) nameDefaultRedirects.splice(index, 1)
-				}
-				browser.storage.local.set({
-					[redirectsChecks]: nameDefaultRedirects,
-				})
-				calcNameCheckBoxes()
-			})
-	}
-
-	function calcNameCustomInstances() {
-		nameProtocolElement.getElementsByClassName("custom-checklist")[0].innerHTML = nameCustomInstances
-			.map(
-				x => `<div>
-                ${x}
-                <button class="add clear-${x}">
-                  <svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 0 24 24" width="20px" fill="currentColor">
-                    <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
-                  </svg>
-                </button>
-              </div>
-              <hr>`
-			)
-			.join("\n")
-
-		for (const item of nameCustomInstances) {
-			nameProtocolElement.getElementsByClassName(`clear-${item}`)[0].addEventListener("click", async () => {
-				let index = nameCustomInstances.indexOf(item)
-				if (index > -1) nameCustomInstances.splice(index, 1)
-				browser.storage.local.set({ [customRedirects]: nameCustomInstances })
-				calcNameCustomInstances()
-			})
-		}
-	}
-	calcNameCustomInstances()
-	nameProtocolElement.getElementsByClassName("custom-instance-form")[0].addEventListener("submit", async event => {
-		event.preventDefault()
-		let nameCustomInstanceInput = nameProtocolElement.getElementsByClassName("custom-instance")[0]
-		let url = new URL(nameCustomInstanceInput.value)
-		let protocolHostVar = protocolHost(url)
-		if (nameCustomInstanceInput.validity.valid && !redirects[name][protocol].includes(protocolHostVar)) {
-			if (!nameCustomInstances.includes(protocolHostVar)) {
-				nameCustomInstances.push(protocolHostVar)
-				browser.storage.local.set({ [customRedirects]: nameCustomInstances })
-				nameCustomInstanceInput.value = ""
-			}
-			calcNameCustomInstances()
-		}
-	})
-}
-
-function ping(href) {
-	return new Promise(async resolve => {
-		let average = 0
-		let time
-		for (let i = 0; i < 3; i++) {
-			time = await pingOnce(href)
-			if (i == 0) continue
-			if (time >= 5000) {
-				resolve(time)
-				return
-			}
-			average += time
-		}
-		average = parseInt(average / 3)
-		resolve(average)
-	})
-}
-
-function pingOnce(href) {
-	return new Promise(async resolve => {
-		let started
-		let http = new XMLHttpRequest()
-		http.timeout = 5000
-		http.ontimeout = () => resolve(5000)
-		http.onerror = () => resolve()
-		http.onreadystatechange = () => {
-			if (http.readyState == 2) {
-				if (http.status == 200) {
-					let ended = new Date().getTime()
-					http.abort()
-					resolve(ended - started)
-				} else {
-					resolve(5000 + http.status)
-				}
-			}
-		}
-		http.open("GET", `${href}?_=${new Date().getTime()}`, true)
-		started = new Date().getTime()
-		http.send(null)
-	})
-}
-
-async function testLatency(element, instances, frontend) {
-	return new Promise(async resolve => {
-		let myList = {}
-		let latencyThreshold
-		let redirectsChecks = []
-		browser.storage.local.get(["latencyThreshold", `${frontend}NormalRedirectsChecks`], r => {
-			latencyThreshold = r.latencyThreshold
-			redirectsChecks = r[`${frontend}NormalRedirectsChecks`]
-		})
-		for (const href of instances)
-			await ping(href).then(time => {
-				if (time) {
-					myList[href] = time
-					let color
-					if (time <= 1000) color = "green"
-					else if (time <= 2000) color = "orange"
-					else color = "red"
-
-					if (time > latencyThreshold) {
-						redirectsChecks.splice(redirectsChecks.indexOf(href), 1)
-					}
-
-					browser.storage.local.set({ [`${frontend}NormalRedirectsChecks`]: redirectsChecks })
-
-					let text
-					if (time == 5000) text = "5000ms+"
-					else if (time > 5000) text = `ERROR: ${time - 5000}`
-					else text = `${time}ms`
-					element.innerHTML = `${href}:&nbsp;<span style="color:${color};">${text}</span>`
-				}
-			})
-		resolve(myList)
-	})
-}
-
-function copyCookie(frontend, targetUrl, urls, name) {
-	return new Promise(resolve => {
-		browser.storage.local.get("firstPartyIsolate", r => {
-			let query
-			if (!r.firstPartyIsolate)
-				query = {
-					url: protocolHost(targetUrl),
-					name: name,
-				}
-			else
-				query = {
-					url: protocolHost(targetUrl),
-					name: name,
-					firstPartyDomain: null,
-				}
-			browser.cookies.getAll(query, async cookies => {
-				for (const cookie of cookies)
-					if (cookie.name == name) {
-						for (const url of urls) {
-							const setQuery = r.firstPartyIsolate
-								? {
-										url: url,
-										name: name,
-										value: cookie.value,
-										secure: true,
-										firstPartyDomain: new URL(url).hostname,
-								  }
-								: {
-										url: url,
-										name: name,
-										value: cookie.value,
-										secure: true,
-										expirationDate: cookie.expirationDate,
-								  }
-							browser.cookies.set(setQuery)
-						}
-						break
-					}
-				resolve()
-			})
-		})
-	})
-}
-
-function getPreferencesFromToken(frontend, targetUrl, urls, name, endpoint) {
-	return new Promise(resolve => {
-		browser.storage.local.get("firstPartyIsolate", r => {
-			const http = new XMLHttpRequest()
-			const url = `${targetUrl}${endpoint}`
-			http.open("GET", url, false)
-			http.setRequestHeader("Cookie", `${name}=${cookie.value}`)
-			http.send(null)
-			const preferences = JSON.parse(http.responseText)
-			let formdata = new FormData()
-			for (var key in preferences) formdata.append(key, preferences[key])
-			for (const url of urls) {
-				const http = new XMLHttpRequest()
-				http.open("POST", `${url}/settings/stay`, false)
-				http.send(null)
-			}
-			resolve()
-			return
-		})
-	})
-}
-
-function copyRaw(test, copyRawElement) {
-	return new Promise(resolve => {
-		browser.tabs.query({ active: true, currentWindow: true }, async tabs => {
-			let currTab = tabs[0]
-			if (currTab) {
-				let url
-				try {
-					url = new URL(currTab.url)
-				} catch {
-					resolve()
-					return
-				}
-
-				let newUrl = await youtubeHelper.reverse(url)
-				if (!newUrl) newUrl = await twitterHelper.reverse(url)
-				if (!newUrl) newUrl = await instagramHelper.reverse(url)
-				if (!newUrl) newUrl = await tiktokHelper.reverse(url)
-				if (!newUrl) newUrl = await quoraHelper.reverse(url)
-				if (!newUrl) newUrl = await libremdbHelper.reverse(url)
-				if (!newUrl) newUrl = await imgurHelper.reverse(url)
-
-				if (newUrl) {
-					resolve(newUrl)
-					if (test) return
-					navigator.clipboard.writeText(newUrl)
-					if (copyRawElement) {
-						const textElement = copyRawElement.getElementsByTagName("h4")[0]
-						const oldHtml = textElement.innerHTML
-						textElement.innerHTML = browser.i18n.getMessage("copied")
-						setTimeout(() => (textElement.innerHTML = oldHtml), 1000)
-					}
-				}
-			}
-			resolve()
-		})
-	})
-}
-
-function unify(test) {
-	return new Promise(resolve => {
-		browser.tabs.query({ active: true, currentWindow: true }, async tabs => {
-			let currTab = tabs[0]
-			if (currTab) {
-				let url
-				try {
-					url = new URL(currTab.url)
-				} catch {
-					resolve()
-					return
-				}
-
-				let result = await youtubeHelper.copyPasteInvidiousCookies(test, url)
-				if (!result) result = await youtubeHelper.copyPastePipedLocalStorage(test, url, currTab.id)
-				if (!result) result = await youtubeHelper.copyPastePipedMaterialLocalStorage(test, url, currTab.id)
-
-				if (!result) result = await twitterHelper.initNitterCookies(test, url)
-				if (!result) result = await redditHelper.initLibredditCookies(test, url)
-				if (!result) result = await redditHelper.initTedditCookies(test, url)
-				if (!result) result = await searchHelper.initSearxCookies(test, url)
-				if (!result) result = await searchHelper.initSearxngCookies(test, url)
-				if (!result) result = await searchHelper.initLibrexCookies(test, url)
-				if (!result) result = await tiktokHelper.initProxiTokCookies(test, url)
-				if (!result) result = await wikipediaHelper.initWikilessCookies(test, url)
-				if (!result) result = await translateHelper.copyPasteSimplyTranslateCookies(test, url)
-				if (!result) result = await translateHelper.copyPasteLingvaLocalStorage(test, url)
-				if (!result) result = await instagramHelper.initBibliogramPreferences(test, url)
-
-				resolve(result)
-			}
-		})
-	})
-}
-
-function switchInstance(test) {
-	return new Promise(resolve => {
-		browser.tabs.query({ active: true, currentWindow: true }, async tabs => {
-			let currTab = tabs[0]
-			if (currTab) {
-				let url
-				try {
-					url = new URL(currTab.url)
-				} catch {
-					resolve()
-					return
-				}
-				let newUrl = await youtubeHelper.switchInstance(url, true)
-				if (!newUrl) newUrl = await twitterHelper.switchInstance(url, true)
-				if (!newUrl) newUrl = await instagramHelper.switchInstance(url, true)
-				if (!newUrl) newUrl = await redditHelper.switchInstance(url, true)
-				if (!newUrl) newUrl = await searchHelper.switchInstance(url, true)
-				if (!newUrl) newUrl = await translateHelper.switchInstance(url, true)
-				if (!newUrl) newUrl = await mediumHelper.switchInstance(url, true)
-				if (!newUrl) newUrl = await quoraHelper.switchInstance(url, true)
-				if (!newUrl) newUrl = await libremdbHelper.switchInstance(url, true)
-				if (!newUrl) newUrl = await tiktokHelper.switchInstance(url, true)
-				if (!newUrl) newUrl = await sendTargetsHelper.switchInstance(url, true)
-				if (!newUrl) newUrl = await peertubeHelper.switchInstance(url, true)
-				if (!newUrl) newUrl = await lbryHelper.switchInstance(url, true)
-				if (!newUrl) newUrl = await imgurHelper.switchInstance(url, true)
-				if (!newUrl) newUrl = await wikipediaHelper.switchInstance(url, true)
-				if (!newUrl) newUrl = await youtubeMusicHelper.switchInstance(url, true)
-
-				if (newUrl) {
-					if (!test) browser.tabs.update({ url: newUrl })
-					resolve(true)
-				} else resolve()
-			}
-		})
-	})
-}
-
-function latency(name, frontend, document, location) {
-	let latencyElement = document.getElementById(`latency-${frontend}`)
-	let latencyLabel = document.getElementById(`latency-${frontend}-label`)
-	latencyElement.addEventListener("click", async () => {
-		let reloadWindow = () => location.reload()
-		latencyElement.addEventListener("click", reloadWindow)
-		let key = `${name}Redirects`
-		browser.storage.local.get(key, r => {
-			let redirects = r[key]
-			const oldHtml = latencyLabel.innerHTML
-			latencyLabel.innerHTML = "..."
-			testLatency(latencyLabel, redirects[frontend].normal, frontend).then(r => {
-				browser.storage.local.set({ [`${frontend}Latency`]: r })
-				latencyLabel.innerHTML = oldHtml
-				processDefaultCustomInstances(name, frontend, "normal", document)
-				latencyElement.removeEventListener("click", reloadWindow)
-			})
-		})
-	})
-}
-
-export default {
-	getRandomInstance,
-	updateInstances,
-	protocolHost,
-	processDefaultCustomInstances,
-	latency,
-	copyCookie,
-	getPreferencesFromToken,
-	switchInstance,
-	copyRaw,
-	unify,
-}
diff --git a/src/assets/javascripts/wikipedia.js b/src/assets/javascripts/wikipedia.js
deleted file mode 100644
index 1e06ed44..00000000
--- a/src/assets/javascripts/wikipedia.js
+++ /dev/null
@@ -1,247 +0,0 @@
-window.browser = window.browser || window.chrome
-
-import utils from "./utils.js"
-
-const targets = /^https?:\/{2}([a-z]+\.)*wikipedia\.org/
-
-const frontends = new Array("wikiless")
-const protocols = new Array("normal", "tor", "i2p", "loki")
-
-let redirects = {}
-
-for (let i = 0; i < frontends.length; i++) {
-	redirects[frontends[i]] = {}
-	for (let x = 0; x < protocols.length; x++) {
-		redirects[frontends[i]][protocols[x]] = []
-	}
-}
-
-function setRedirects(val) {
-	return new Promise(resolve =>
-		browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
-			redirects.wikiless = val
-			wikilessNormalRedirectsChecks = [...redirects.wikiless.normal]
-			for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-				const a = wikilessNormalRedirectsChecks.indexOf(instance)
-				if (a > -1) wikilessNormalRedirectsChecks.splice(a, 1)
-			}
-			browser.storage.local.set(
-				{
-					wikipediaRedirects: redirects,
-					wikilessNormalRedirectsChecks,
-					wikilessTorRedirectsChecks: [...redirects.wikiless.tor],
-					wikilessI2pRedirectsChecks: [...redirects.wikiless.i2p],
-					wikilessLokiRedirectsChecks: [...redirects.wikiless.loki],
-				},
-				() => resolve()
-			)
-		})
-	)
-}
-
-let disableWikipedia,
-	wikipediaRedirects,
-	protocol,
-	protocolFallback,
-	wikilessNormalRedirectsChecks,
-	wikilessTorRedirectsChecks,
-	wikilessI2pRedirectsChecks,
-	wikilessNormalCustomRedirects,
-	wikilessTorCustomRedirects,
-	wikilessI2pCustomRedirects,
-	wikilessLokiCustomRedirects
-
-function init() {
-	return new Promise(async resolve => {
-		browser.storage.local.get(
-			[
-				"disableWikipedia",
-				"wikipediaRedirects",
-				"protocol",
-				"protocolFallback",
-				"wikilessNormalRedirectsChecks",
-				"wikilessTorRedirectsChecks",
-				"wikilessI2pRedirectsChecks",
-				"wikilessNormalCustomRedirects",
-				"wikilessTorCustomRedirects",
-				"wikilessI2pCustomRedirects",
-				"wikilessLokiCustomRedirects",
-			],
-			r => {
-				disableWikipedia = r.disableWikipedia
-				wikipediaRedirects = r.wikipediaRedirects
-				protocol = r.protocol
-				protocolFallback = r.protocolFallback
-				wikilessNormalRedirectsChecks = r.wikilessNormalRedirectsChecks
-				wikilessTorRedirectsChecks = r.wikilessTorRedirectsChecks
-				wikilessI2pRedirectsChecks = r.wikilessI2pRedirectsChecks
-				wikilessNormalCustomRedirects = r.wikilessNormalCustomRedirects
-				wikilessTorCustomRedirects = r.wikilessTorCustomRedirects
-				wikilessI2pCustomRedirects = r.wikilessI2pCustomRedirects
-				wikilessLokiCustomRedirects = r.wikilessLokiCustomRedirects
-				resolve()
-			}
-		)
-	})
-}
-
-init()
-browser.storage.onChanged.addListener(init)
-
-function initWikilessCookies(test, from) {
-	return new Promise(async resolve => {
-		await init()
-		const protocolHost = utils.protocolHost(from)
-		const all = [
-			...wikilessNormalRedirectsChecks,
-			...wikilessNormalCustomRedirects,
-			...wikilessTorRedirectsChecks,
-			...wikilessTorCustomRedirects,
-			...wikilessI2pRedirectsChecks,
-			...wikilessI2pCustomRedirects,
-			...wikilessLokiCustomRedirects,
-		]
-		if (!all.includes(protocolHost)) {
-			resolve()
-			return
-		}
-
-		if (!test) {
-			let checkedInstances = []
-			if (protocol == "loki") checkedInstances = [...wikilessLokiCustomRedirects]
-			else if (protocol == "i2p") checkedInstances = [...wikilessI2pCustomRedirects, ...wikilessI2pRedirectsChecks]
-			else if (protocol == "tor") checkedInstances = [...wikilessTorRedirectsChecks, ...wikilessTorCustomRedirects]
-			if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
-				checkedInstances = [...wikilessNormalRedirectsChecks, ...wikilessNormalCustomRedirects]
-			}
-			await utils.copyCookie("wikiless", from, checkedInstances, "theme")
-			await utils.copyCookie("wikiless", from, checkedInstances, "default_lang")
-		}
-		resolve(true)
-	})
-}
-
-function redirect(url, disableOverride) {
-	if (disableWikipedia && !disableOverride) return
-	if (!targets.test(url.href)) return
-
-	let GETArguments = []
-	if (url.search.length > 0) {
-		let search = url.search.substring(1) //get rid of '?'
-		let argstrings = search.split("&")
-		for (let i = 0; i < argstrings.length; i++) {
-			let args = argstrings[i].split("=")
-			GETArguments.push([args[0], args[1]])
-		}
-	}
-	let instancesList = []
-	if (protocol == "loki") instancesList = [...wikilessLokiCustomRedirects]
-	else if (protocol == "i2p") instancesList = [...wikilessI2pCustomRedirects, ...wikilessI2pRedirectsChecks]
-	else if (protocol == "tor") instancesList = [...wikilessTorRedirectsChecks, ...wikilessTorCustomRedirects]
-	if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-		instancesList = [...wikilessNormalRedirectsChecks, ...wikilessNormalCustomRedirects]
-	}
-	if (instancesList.length === 0) return
-	const randomInstance = utils.getRandomInstance(instancesList)
-
-	let link = `${randomInstance}${url.pathname}`
-	let urlSplit = url.host.split(".")
-	if (urlSplit[0] != "wikipedia" && urlSplit[0] != "www") {
-		if (urlSplit[0] == "m") GETArguments.push(["mobileaction", "toggle_view_mobile"])
-		else GETArguments.push(["lang", urlSplit[0]])
-		if (urlSplit[1] == "m") GETArguments.push(["mobileaction", "toggle_view_mobile"])
-		// wikiless doesn't have mobile view support yet
-	}
-	for (let i = 0; i < GETArguments.length; i++) link += (i == 0 ? "?" : "&") + GETArguments[i][0] + "=" + GETArguments[i][1]
-	return link
-}
-
-function switchInstance(url, disableOverride) {
-	return new Promise(async resolve => {
-		await init()
-		if (disableWikipedia && !disableOverride) {
-			resolve()
-			return
-		}
-		const protocolHost = utils.protocolHost(url)
-		const wikipediaList = [
-			...wikipediaRedirects.wikiless.normal,
-			...wikipediaRedirects.wikiless.tor,
-			...wikipediaRedirects.wikiless.i2p,
-
-			...wikilessNormalCustomRedirects,
-			...wikilessTorCustomRedirects,
-			...wikilessI2pCustomRedirects,
-			...wikilessLokiCustomRedirects,
-		]
-		if (!wikipediaList.includes(protocolHost)) {
-			resolve()
-			return
-		}
-
-		let instancesList = []
-		if (protocol == "loki") instancesList = [...wikilessLokiCustomRedirects]
-		else if (protocol == "i2p") instancesList = [...wikilessI2pCustomRedirects, ...wikilessI2pRedirectsChecks]
-		else if (protocol == "tor") instancesList = [...wikilessTorRedirectsChecks, ...wikilessTorCustomRedirects]
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			instancesList = [...wikilessNormalRedirectsChecks, ...wikilessNormalCustomRedirects]
-		}
-
-		let index = instancesList.indexOf(protocolHost)
-		if (index > -1) instancesList.splice(index, 1)
-		if (instancesList.length === 0) {
-			resolve()
-			return
-		}
-
-		const randomInstance = utils.getRandomInstance(instancesList)
-		resolve(`${randomInstance}${url.pathname}${url.search}`)
-	})
-}
-
-function initDefaults() {
-	return new Promise(resolve => {
-		fetch("/instances/data.json")
-			.then(response => response.text())
-			.then(async data => {
-				let dataJson = JSON.parse(data)
-				for (let i = 0; i < frontends.length; i++) {
-					redirects[frontends[i]] = dataJson[frontends[i]]
-				}
-				browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
-					wikilessNormalRedirectsChecks = [...redirects.wikiless.normal]
-					for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-						const a = wikilessNormalRedirectsChecks.indexOf(instance)
-						if (a > -1) wikilessNormalRedirectsChecks.splice(a, 1)
-					}
-					browser.storage.local.set(
-						{
-							disableWikipedia: true,
-							wikipediaRedirects: redirects,
-
-							wikilessNormalRedirectsChecks,
-							wikilessNormalCustomRedirects: [],
-
-							wikilessTorRedirectsChecks: [...redirects.wikiless.tor],
-							wikilessTorCustomRedirects: [],
-
-							wikilessI2pRedirectsChecks: [...redirects.wikiless.i2p],
-							wikilessI2pCustomRedirects: [],
-
-							wikilessLokiRedirectsChecks: [...redirects.wikiless.loki],
-							wikilessLokiCustomRedirects: [],
-						},
-						() => resolve()
-					)
-				})
-			})
-	})
-}
-
-export default {
-	setRedirects,
-	initWikilessCookies,
-	redirect,
-	initDefaults,
-	switchInstance,
-}
diff --git a/src/assets/javascripts/youtube/get_pipedMaterial_preferences.js b/src/assets/javascripts/youtube/get_pipedMaterial_preferences.js
deleted file mode 100644
index df79e13c..00000000
--- a/src/assets/javascripts/youtube/get_pipedMaterial_preferences.js
+++ /dev/null
@@ -1,5 +0,0 @@
-window.browser = window.browser || window.chrome
-
-browser.storage.local.set({
-	pipedMaterial_PREFERENCES: localStorage.getItem("PREFERENCES"),
-})
diff --git a/src/assets/javascripts/youtube/get_piped_preferences.js b/src/assets/javascripts/youtube/get_piped_preferences.js
deleted file mode 100644
index 388ecd19..00000000
--- a/src/assets/javascripts/youtube/get_piped_preferences.js
+++ /dev/null
@@ -1,22 +0,0 @@
-window.browser = window.browser || window.chrome
-
-browser.storage.local.set({
-	piped_bufferGoal: localStorage.getItem("bufferGoal"),
-	piped_comments: localStorage.getItem("comments"),
-	piped_disableLBRY: localStorage.getItem("disableLBRY"),
-	piped_enabledCodecs: localStorage.getItem("enabledCodecs"),
-	piped_hl: localStorage.getItem("hl"),
-	piped_homepage: localStorage.getItem("homepage"),
-	piped_instance: localStorage.getItem("instance"),
-	piped_listen: localStorage.getItem("listen"),
-	piped_minimizeDescription: localStorage.getItem("minimizeDescription"),
-	piped_playerAutoPlay: localStorage.getItem("playerAutoPlay"),
-	piped_proxyLBRY: localStorage.getItem("proxyLBRY"),
-	piped_quality: localStorage.getItem("quality"),
-	piped_region: localStorage.getItem("region"),
-	piped_selectedSkip: localStorage.getItem("selectedSkip"),
-	piped_sponsorblock: localStorage.getItem("sponsorblock"),
-	piped_theme: localStorage.getItem("theme"),
-	piped_volume: localStorage.getItem("volume"),
-	piped_watchHistory: localStorage.getItem("watchHistory"),
-})
diff --git a/src/assets/javascripts/youtube/set_pipedMaterial_preferences.js b/src/assets/javascripts/youtube/set_pipedMaterial_preferences.js
deleted file mode 100644
index 59d6dcc4..00000000
--- a/src/assets/javascripts/youtube/set_pipedMaterial_preferences.js
+++ /dev/null
@@ -1,7 +0,0 @@
-window.browser = window.browser || window.chrome
-
-browser.storage.local.get("pipedMaterial_PREFERENCES", r => {
-	if (r.pipedMaterial_PREFERENCES !== undefined) localStorage.setItem("PREFERENCES", r.pipedMaterial_PREFERENCES)
-
-	window.close()
-})
diff --git a/src/assets/javascripts/youtube/set_piped_preferences.js b/src/assets/javascripts/youtube/set_piped_preferences.js
deleted file mode 100644
index 374f2d61..00000000
--- a/src/assets/javascripts/youtube/set_piped_preferences.js
+++ /dev/null
@@ -1,45 +0,0 @@
-window.browser = window.browser || window.chrome
-
-browser.storage.local.get(
-	[
-		"piped_bufferGoal",
-		"piped_comments",
-		"piped_disableLBRY",
-		"piped_enabledCodecs",
-		"piped_homepage",
-		"piped_instance",
-		"piped_listen",
-		"piped_minimizeDescription",
-		"piped_playerAutoPlay",
-		"piped_proxyLBRY",
-		"piped_quality",
-		"piped_region",
-		"piped_selectedSkip",
-		"piped_sponsorblock",
-		"piped_theme",
-		"piped_volume",
-		"piped_watchHistory",
-	],
-	r => {
-		if (r.piped_bufferGoal !== undefined) localStorage.setItem("bufferGoal", r.piped_bufferGoal)
-		if (r.piped_comments !== undefined) localStorage.setItem("comments", r.piped_comments)
-		if (r.piped_disableLBRY !== undefined) localStorage.setItem("disableLBRY", r.piped_disableLBRY)
-		if (r.piped_hl !== undefined) localStorage.setItem("hl", r.piped_hl)
-		if (r.piped_enabledCodecs !== undefined) localStorage.setItem("enabledCodecs", r.piped_enabledCodecs)
-		if (r.piped_homepage !== undefined) localStorage.setItem("homepage", r.piped_homepage)
-		if (r.piped_instance !== undefined) localStorage.setItem("instance", r.piped_instance)
-		if (r.piped_listen !== undefined) localStorage.setItem("listen", r.piped_listen)
-		if (r.piped_minimizeDescription !== undefined) localStorage.setItem("minimizeDescription", r.piped_minimizeDescription)
-		if (r.piped_playerAutoPlay !== undefined) localStorage.setItem("playerAutoPlay", r.piped_playerAutoPlay)
-		if (r.piped_proxyLBRY !== undefined) localStorage.setItem("proxyLBRY", r.piped_proxyLBRY)
-		if (r.piped_quality !== undefined) localStorage.setItem("quality", r.piped_quality)
-		if (r.piped_region !== undefined) localStorage.setItem("region", r.piped_region)
-		if (r.piped_selectedSkip !== undefined) localStorage.setItem("selectedSkip", r.piped_selectedSkip)
-		if (r.piped_sponsorblock !== undefined) localStorage.setItem("sponsorblock", r.piped_sponsorblock)
-		if (r.piped_theme !== undefined) localStorage.setItem("theme", r.piped_theme)
-		if (r.piped_volume !== undefined) localStorage.setItem("volume", r.piped_volume)
-		if (r.piped_watchHistory !== undefined) localStorage.setItem("watchHistory", r.piped_watchHistory)
-
-		window.close()
-	}
-)
diff --git a/src/assets/javascripts/youtube/youtube.js b/src/assets/javascripts/youtube/youtube.js
deleted file mode 100644
index 7b215704..00000000
--- a/src/assets/javascripts/youtube/youtube.js
+++ /dev/null
@@ -1,797 +0,0 @@
-"use strict"
-
-window.browser = window.browser || window.chrome
-
-import utils from "../utils.js"
-
-const targets = [
-	/^https?:\/{2}(www\.|music\.|m\.|)youtube\.com(\/.*|$)/,
-
-	/^https?:\/{2}img\.youtube\.com\/vi\/.*\/..*/, // https://stackoverflow.com/questions/2068344/how-do-i-get-a-youtube-video-thumbnail-from-the-youtube-api
-	/^https?:\/{2}(i|s)\.ytimg\.com\/vi\/.*\/..*/,
-
-	/^https?:\/{2}(www\.|music\.|)youtube\.com\/watch\?v\=..*/,
-
-	/^https?:\/{2}youtu\.be\/..*/,
-
-	/^https?:\/{2}(www\.|)(youtube|youtube-nocookie)\.com\/embed\/..*/,
-]
-
-const frontends = new Array("invidious", "piped", "pipedMaterial", "cloudtube")
-const protocols = new Array("normal", "tor", "i2p", "loki")
-
-let redirects = {}
-
-for (let i = 0; i < frontends.length; i++) {
-	redirects[frontends[i]] = {}
-	for (let x = 0; x < protocols.length; x++) {
-		redirects[frontends[i]][protocols[x]] = []
-	}
-}
-
-function setRedirects(val) {
-	return new Promise(resolve =>
-		browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
-			redirects = val
-			invidiousNormalRedirectsChecks = [...redirects.invidious.normal]
-			pipedNormalRedirectsChecks = [...redirects.piped.normal]
-			pipedMaterialNormalRedirectsChecks = [...redirects.pipedMaterial.normal]
-			cloudtubeNormalRedirectsChecks = [...redirects.cloudtube.normal]
-			for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-				const a = invidiousNormalRedirectsChecks.indexOf(instance)
-				if (a > -1) invidiousNormalRedirectsChecks.splice(a, 1)
-
-				const b = pipedNormalRedirectsChecks.indexOf(instance)
-				if (b > -1) pipedNormalRedirectsChecks.splice(b, 1)
-
-				const c = pipedMaterialNormalRedirectsChecks.indexOf(instance)
-				if (c > -1) pipedMaterialNormalRedirectsChecks.splice(c, 1)
-
-				const d = cloudtubeNormalRedirectsChecks.indexOf(instance)
-				if (c > -1) cloudtubeNormalRedirectsChecks.splice(d, 1)
-			}
-			browser.storage.local.set(
-				{
-					youtubeRedirects: redirects,
-					invidiousNormalRedirectsChecks,
-					invidiousTorRedirectsChecks: [...redirects.invidious.tor],
-					invidiousI2pRedirectsChecks: [...redirects.invidious.i2p],
-					invidiousLokiRedirectsChecks: [...redirects.invidious.loki],
-					pipedNormalRedirectsChecks,
-					pipedTorRedirectsChecks: [...redirects.piped.tor],
-					pipedI2pRedirectsChecks: [...redirects.piped.i2p],
-					pipedLokiRedirectsChecks: [...redirects.piped.loki],
-					pipedMaterialNormalRedirectsChecks,
-					pipedMaterialTorRedirectsChecks: [...redirects.pipedMaterial.tor],
-					pipedMaterialI2pRedirectsChecks: [...redirects.pipedMaterial.i2p],
-					pipedMaterialLokiRedirectsChecks: [...redirects.pipedMaterial.loki],
-					cloudtubeNormalRedirectsChecks,
-					cloudtubeTorRedirectsChecks: [...redirects.cloudtube.tor],
-					cloudtubeI2pRedirectsChecks: [...redirects.cloudtube.i2p],
-					cloudtubeLokiRedirectsChecks: [...redirects.cloudtube.loki],
-				},
-				() => resolve()
-			)
-		})
-	)
-}
-
-let disableYoutube,
-	onlyEmbeddedVideo,
-	youtubeFrontend,
-	protocol,
-	protocolFallback,
-	youtubeEmbedFrontend,
-	youtubeRedirects,
-	invidiousNormalRedirectsChecks,
-	invidiousNormalCustomRedirects,
-	invidiousTorRedirectsChecks,
-	invidiousTorCustomRedirects,
-	invidiousI2pRedirectsChecks,
-	invidiousI2pCustomRedirects,
-	invidiousLokiRedirectsChecks,
-	invidiousLokiCustomRedirects,
-	pipedNormalRedirectsChecks,
-	pipedNormalCustomRedirects,
-	pipedTorRedirectsChecks,
-	pipedTorCustomRedirects,
-	pipedI2pRedirectsChecks,
-	pipedI2pCustomRedirects,
-	pipedLokiRedirectsChecks,
-	pipedLokiCustomRedirects,
-	pipedMaterialNormalRedirectsChecks,
-	pipedMaterialNormalCustomRedirects,
-	pipedMaterialTorRedirectsChecks,
-	pipedMaterialTorCustomRedirects,
-	pipedMaterialI2pRedirectsChecks,
-	pipedMaterialI2pCustomRedirects,
-	pipedMaterialLokiRedirectsChecks,
-	pipedMaterialLokiCustomRedirects,
-	cloudtubeNormalRedirectsChecks,
-	cloudtubeNormalCustomRedirects,
-	cloudtubeTorRedirectsChecks,
-	cloudtubeTorCustomRedirects,
-	cloudtubeI2pRedirectsChecks,
-	cloudtubeI2pCustomRedirects,
-	cloudtubeLokiRedirectsChecks,
-	cloudtubeLokiCustomRedirects
-
-function init() {
-	return new Promise(resolve => {
-		browser.storage.local.get(
-			[
-				"disableYoutube",
-				"onlyEmbeddedVideo",
-				"youtubeFrontend",
-				"protocol",
-				"protocolFallback",
-				"youtubeEmbedFrontend",
-				"youtubeRedirects",
-				"invidiousNormalRedirectsChecks",
-				"invidiousNormalCustomRedirects",
-				"invidiousTorRedirectsChecks",
-				"invidiousTorCustomRedirects",
-				"invidiousI2pRedirectsChecks",
-				"invidiousI2pCustomRedirects",
-				"invidiousLokiRedirectsChecks",
-				"invidiousLokiCustomRedirects",
-				"pipedNormalRedirectsChecks",
-				"pipedNormalCustomRedirects",
-				"pipedTorRedirectsChecks",
-				"pipedTorCustomRedirects",
-				"pipedI2pRedirectsChecks",
-				"pipedI2pCustomRedirects",
-				"pipedLokiRedirectsChecks",
-				"pipedLokiCustomRedirects",
-				"pipedMaterialNormalRedirectsChecks",
-				"pipedMaterialNormalCustomRedirects",
-				"pipedMaterialTorRedirectsChecks",
-				"pipedMaterialTorCustomRedirects",
-				"pipedMaterialI2pRedirectsChecks",
-				"pipedMaterialI2pCustomRedirects",
-				"pipedMaterialLokiRedirectsChecks",
-				"pipedMaterialLokiCustomRedirects",
-				"cloudtubeNormalRedirectsChecks",
-				"cloudtubeNormalCustomRedirects",
-				"cloudtubeTorRedirectsChecks",
-				"cloudtubeTorCustomRedirects",
-				"cloudtubeI2pRedirectsChecks",
-				"cloudtubeI2pCustomRedirects",
-				"cloudtubeLokiRedirectsChecks",
-				"cloudtubeLokiCustomRedirects",
-			],
-			r => {
-				disableYoutube = r.disableYoutube
-				onlyEmbeddedVideo = r.onlyEmbeddedVideo
-				youtubeFrontend = r.youtubeFrontend
-				protocol = r.protocol
-				protocolFallback = r.protocolFallback
-				youtubeEmbedFrontend = r.youtubeEmbedFrontend
-				youtubeRedirects = r.youtubeRedirects
-				invidiousNormalRedirectsChecks = r.invidiousNormalRedirectsChecks
-				invidiousNormalCustomRedirects = r.invidiousNormalCustomRedirects
-				invidiousTorRedirectsChecks = r.invidiousTorRedirectsChecks
-				invidiousTorCustomRedirects = r.invidiousTorCustomRedirects
-				invidiousI2pRedirectsChecks = r.invidiousI2pRedirectsChecks
-				invidiousI2pCustomRedirects = r.invidiousI2pCustomRedirects
-				invidiousLokiRedirectsChecks = r.invidiousLokiRedirectsChecks
-				invidiousLokiCustomRedirects = r.invidiousLokiCustomRedirects
-				pipedNormalRedirectsChecks = r.pipedNormalRedirectsChecks
-				pipedNormalCustomRedirects = r.pipedNormalCustomRedirects
-				pipedTorRedirectsChecks = r.pipedTorRedirectsChecks
-				pipedTorCustomRedirects = r.pipedTorCustomRedirects
-				pipedI2pRedirectsChecks = r.pipedI2pRedirectsChecks
-				pipedI2pCustomRedirects = r.pipedI2pCustomRedirects
-				pipedLokiRedirectsChecks = r.pipedLokiRedirectsChecks
-				pipedLokiCustomRedirects = r.pipedLokiCustomRedirects
-				pipedMaterialNormalRedirectsChecks = r.pipedMaterialNormalRedirectsChecks
-				pipedMaterialNormalCustomRedirects = r.pipedMaterialNormalCustomRedirects
-				pipedMaterialTorRedirectsChecks = r.pipedMaterialTorRedirectsChecks
-				pipedMaterialTorCustomRedirects = r.pipedMaterialTorCustomRedirects
-				pipedMaterialI2pRedirectsChecks = r.pipedMaterialI2pRedirectsChecks
-				pipedMaterialI2pCustomRedirects = r.pipedMaterialI2pCustomRedirects
-				pipedMaterialLokiRedirectsChecks = r.pipedMaterialLokiRedirectsChecks
-				pipedMaterialLokiCustomRedirects = r.pipedMaterialLokiCustomRedirects
-				cloudtubeNormalRedirectsChecks = r.cloudtubeNormalRedirectsChecks
-				cloudtubeNormalCustomRedirects = r.cloudtubeNormalCustomRedirects
-				cloudtubeTorRedirectsChecks = r.cloudtubeTorRedirectsChecks
-				cloudtubeTorCustomRedirects = r.cloudtubeTorCustomRedirects
-				cloudtubeI2pRedirectsChecks = r.cloudtubeI2pRedirectsChecks
-				cloudtubeI2pCustomRedirects = r.cloudtubeI2pCustomRedirects
-				cloudtubeLokiRedirectsChecks = r.cloudtubeLokiRedirectsChecks
-				cloudtubeLokiCustomRedirects = r.cloudtubeLokiCustomRedirects
-				resolve()
-			}
-		)
-	})
-}
-
-init()
-browser.storage.onChanged.addListener(init)
-
-function all() {
-	return [
-		...youtubeRedirects.invidious.normal,
-		...youtubeRedirects.invidious.tor,
-		...youtubeRedirects.invidious.i2p,
-		...youtubeRedirects.invidious.loki,
-
-		...youtubeRedirects.piped.normal,
-		...youtubeRedirects.piped.tor,
-		...youtubeRedirects.piped.i2p,
-		...youtubeRedirects.piped.loki,
-
-		...youtubeRedirects.pipedMaterial.normal,
-		...youtubeRedirects.pipedMaterial.tor,
-		...youtubeRedirects.pipedMaterial.i2p,
-		...youtubeRedirects.pipedMaterial.loki,
-
-		...youtubeRedirects.cloudtube.normal,
-		...youtubeRedirects.cloudtube.tor,
-		...youtubeRedirects.cloudtube.i2p,
-		...youtubeRedirects.cloudtube.loki,
-
-		...invidiousNormalCustomRedirects,
-		...invidiousTorCustomRedirects,
-		...invidiousI2pCustomRedirects,
-		...invidiousLokiCustomRedirects,
-
-		...pipedNormalCustomRedirects,
-		...pipedTorCustomRedirects,
-		...pipedI2pCustomRedirects,
-		...pipedLokiCustomRedirects,
-
-		...pipedMaterialNormalCustomRedirects,
-		...pipedMaterialTorCustomRedirects,
-		...pipedMaterialI2pCustomRedirects,
-		...pipedMaterialLokiCustomRedirects,
-
-		...cloudtubeNormalCustomRedirects,
-		...cloudtubeTorCustomRedirects,
-		...cloudtubeI2pCustomRedirects,
-		...cloudtubeLokiCustomRedirects,
-	]
-}
-
-function calculateFrontend(type) {
-	switch (type) {
-		case "main_frame":
-			return youtubeFrontend
-		case "sub_frame":
-			return youtubeEmbedFrontend
-	}
-}
-
-function getInstanceList(type) {
-	let instancesList = []
-	switch (calculateFrontend(type)) {
-		case "invidious":
-			switch (protocol) {
-				case "loki":
-					instancesList = [...invidiousLokiRedirectsChecks, ...invidiousLokiCustomRedirects]
-					break
-				case "i2p":
-					instancesList = [...invidiousI2pRedirectsChecks, ...invidiousI2pCustomRedirects]
-					break
-				case "tor":
-					instancesList = [...invidiousTorRedirectsChecks, ...invidiousTorCustomRedirects]
-			}
-			if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-				instancesList = [...invidiousNormalRedirectsChecks, ...invidiousNormalCustomRedirects]
-			}
-			break
-		case "piped":
-			switch (protocol) {
-				case "loki":
-					instancesList = [...pipedLokiRedirectsChecks, ...pipedLokiCustomRedirects]
-					break
-				case "i2p":
-					instancesList = [...pipedI2pRedirectsChecks, ...pipedI2pCustomRedirects]
-					break
-				case "tor":
-					instancesList = [...pipedTorRedirectsChecks, ...pipedTorCustomRedirects]
-			}
-			if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-				instancesList = [...pipedNormalRedirectsChecks, ...pipedNormalCustomRedirects]
-			}
-			break
-		case "pipedMaterial":
-			switch (protocol) {
-				case "loki":
-					instancesList = [...pipedMaterialLokiRedirectsChecks, ...pipedMaterialLokiCustomRedirects]
-					break
-				case "i2p":
-					instancesList = [...pipedMaterialI2pRedirectsChecks, ...pipedMaterialI2pCustomRedirects]
-					break
-				case "tor":
-					instancesList = [...pipedMaterialTorRedirectsChecks, ...pipedMaterialTorCustomRedirects]
-			}
-			if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-				instancesList = [...pipedMaterialNormalRedirectsChecks, ...pipedMaterialNormalCustomRedirects]
-			}
-		case "cloudtube":
-			switch (protocol) {
-				case "loki":
-					instancesList = [...cloudtubeLokiRedirectsChecks, ...cloudtubeLokiCustomRedirects]
-					break
-				case "i2p":
-					instancesList = [...cloudtubeI2pRedirectsChecks, ...cloudtubeI2pCustomRedirects]
-					break
-				case "tor":
-					instancesList = [...cloudtubeTorRedirectsChecks, ...cloudtubeTorCustomRedirects]
-			}
-			if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-				instancesList = [...cloudtubeNormalRedirectsChecks, ...cloudtubeNormalCustomRedirects]
-			}
-	}
-	return instancesList
-}
-
-function redirect(url, type, tabId, initiator, disableOverride) {
-	if (disableYoutube && !disableOverride) return
-	if (!targets.some(rx => rx.test(url.href))) return
-	if (initiator && all().includes(initiator.origin)) return "BYPASSTAB"
-
-	if (type != ("main_frame" || "sub_frame")) return
-	if (url.pathname.match(/iframe_api/) || url.pathname.match(/www-widgetapi/)) return // Don't redirect YouTube Player API.
-	if (onlyEmbeddedVideo == "onlyNotEmbedded" && type == "sub_frame") return
-
-	if (type == "main_frame") {
-		switch (youtubeFrontend) {
-			case "yatte":
-				return url.href.replace(/^https?:\/{2}/, "yattee://")
-			case "freetube":
-				if (url.host === "youtu.be") return `freetube://https://youtube.com/watch?v=${url.pathname.slice(1)}&${url.search.slice(1)}`
-				return `freetube://https://youtube.com${url.pathname}${url.search}`
-		}
-	}
-
-	const instanceList = getInstanceList(type)
-	try {
-		if (instanceList.length >= 1) {
-			const randomInstance = utils.getRandomInstance(instanceList)
-			return `${randomInstance}${url.pathname}${url.search}`
-		}
-	} catch {
-		return
-	}
-}
-
-function reverse(url) {
-	return new Promise(async resolve => {
-		await init()
-		const protocolHost = utils.protocolHost(url)
-		if (!all().includes(protocolHost)) {
-			resolve()
-			return
-		}
-		resolve(`https://youtube.com${url.pathname}${url.search}`)
-	})
-}
-
-function switchInstance(url, disableOverride) {
-	return new Promise(async resolve => {
-		await init()
-		if (disableYoutube && !disableOverride) {
-			resolve()
-			return
-		}
-		const protocolHost = utils.protocolHost(url)
-		if (!all().includes(protocolHost)) {
-			resolve()
-			return
-		}
-
-		let instancesList = []
-		switch (protocol) {
-			case "loki":
-				switch (youtubeFrontend) {
-					case "invidious":
-						instancesList = [...invidiousLokiRedirectsChecks, ...invidiousLokiCustomRedirects]
-						break
-					case "piped":
-						instancesList = [...pipedLokiRedirectsChecks, ...pipedLokiCustomRedirects]
-						break
-					case "pipedMaterial":
-						instancesList = [...pipedMaterialLokiRedirectsChecks, ...pipedMaterialLokiCustomRedirects]
-						break
-					case "cloudtube":
-						instancesList = [...cloudtubeLokiRedirectsChecks, ...cloudtubeLokiCustomRedirects]
-				}
-				break
-			case "i2p":
-				switch (youtubeFrontend) {
-					case "invidious":
-						instancesList = [...invidiousI2pRedirectsChecks, ...invidiousI2pCustomRedirects]
-						break
-					case "piped":
-						instancesList = [...pipedI2pRedirectsChecks, ...pipedI2pCustomRedirects]
-						break
-					case "pipedMaterial":
-						instancesList = [...pipedMaterialI2pRedirectsChecks, ...pipedMaterialI2pCustomRedirects]
-						break
-					case "cloudtube":
-						instancesList = [...cloudtubeI2pRedirectsChecks, ...cloudtubeI2pCustomRedirects]
-				}
-				break
-			case "tor":
-				switch (youtubeFrontend) {
-					case "invidious":
-						instancesList = [...invidiousTorRedirectsChecks, ...invidiousTorCustomRedirects]
-						break
-					case "piped":
-						instancesList = [...pipedTorRedirectsChecks, ...pipedTorCustomRedirects]
-						break
-					case "pipedMaterial":
-						instancesList = [...pipedMaterialTorRedirectsChecks, ...pipedMaterialTorCustomRedirects]
-						break
-					case "cloudtube":
-						instancesList = [...cloudtubeTorRedirectsChecks, ...cloudtubeTorCustomRedirects]
-				}
-		}
-		if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-			switch (youtubeFrontend) {
-				case "invidious":
-					instancesList = [...invidiousNormalRedirectsChecks, ...invidiousNormalCustomRedirects]
-					break
-				case "piped":
-					instancesList = [...pipedNormalRedirectsChecks, ...pipedNormalCustomRedirects]
-					break
-				case "pipedMaterial":
-					instancesList = [...pipedMaterialNormalRedirectsChecks, ...pipedMaterialNormalCustomRedirects]
-					break
-				case "cloudtube":
-					instancesList = [...cloudtubeNormalRedirectsChecks, ...cloudtubeNormalCustomRedirects]
-			}
-		}
-
-		const i = instancesList.indexOf(protocolHost)
-		if (i > -1) instancesList.splice(i, 1)
-		if (instancesList.length == 0) {
-			resolve()
-			return
-		}
-
-		const randomInstance = utils.getRandomInstance(instancesList)
-		resolve(`${randomInstance}${url.pathname}${url.search}`)
-	})
-}
-
-function initDefaults() {
-	return new Promise(async resolve => {
-		fetch("/instances/data.json")
-			.then(response => response.text())
-			.then(async data => {
-				let dataJson = JSON.parse(data)
-				for (let i = 0; i < frontends.length; i++) {
-					redirects[frontends[i]] = dataJson[frontends[i]]
-				}
-				browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
-					invidiousNormalRedirectsChecks = [...redirects.invidious.normal]
-					pipedNormalRedirectsChecks = [...redirects.piped.normal]
-					pipedMaterialNormalRedirectsChecks = [...redirects.pipedMaterial.normal]
-					cloudtubeNormalRedirectsChecks = [...redirects.cloudtube.normal]
-					for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-						const a = invidiousNormalRedirectsChecks.indexOf(instance)
-						if (a > -1) invidiousNormalRedirectsChecks.splice(a, 1)
-
-						const b = pipedNormalRedirectsChecks.indexOf(instance)
-						if (b > -1) pipedNormalRedirectsChecks.splice(b, 1)
-
-						const c = pipedMaterialNormalRedirectsChecks.indexOf(instance)
-						if (c > -1) pipedMaterialNormalRedirectsChecks.splice(c, 1)
-
-						const d = cloudtubeNormalRedirectsChecks.indexOf(instance)
-						if (c > -1) cloudtubeNormalRedirectsChecks.splice(d, 1)
-					}
-					browser.storage.local.set(
-						{
-							disableYoutube: false,
-							enableYoutubeCustomSettings: false,
-							onlyEmbeddedVideo: "both",
-							youtubeRedirects: redirects,
-							youtubeFrontend: "invidious",
-
-							invidiousNormalRedirectsChecks,
-							invidiousNormalCustomRedirects: [],
-
-							invidiousTorRedirectsChecks: [...redirects.invidious.tor],
-							invidiousTorCustomRedirects: [],
-
-							invidiousI2pRedirectsChecks: [...redirects.invidious.i2p],
-							invidiousI2pCustomRedirects: [],
-
-							invidiousLokiRedirectsChecks: [...redirects.invidious.loki],
-							invidiousLokiCustomRedirects: [],
-
-							pipedNormalRedirectsChecks,
-							pipedNormalCustomRedirects: [],
-
-							pipedTorRedirectsChecks: [...redirects.piped.tor],
-							pipedTorCustomRedirects: [],
-
-							pipedI2pRedirectsChecks: [...redirects.piped.i2p],
-							pipedI2pCustomRedirects: [],
-
-							pipedLokiRedirectsChecks: [...redirects.piped.loki],
-							pipedLokiCustomRedirects: [],
-
-							pipedMaterialNormalRedirectsChecks: pipedMaterialNormalRedirectsChecks,
-							pipedMaterialNormalCustomRedirects: [],
-
-							pipedMaterialTorRedirectsChecks: [...redirects.pipedMaterial.tor],
-							pipedMaterialTorCustomRedirects: [],
-
-							pipedMaterialI2pRedirectsChecks: [...redirects.pipedMaterial.i2p],
-							pipedMaterialI2pCustomRedirects: [],
-
-							pipedMaterialLokiRedirectsChecks: [...redirects.pipedMaterial.loki],
-							pipedMaterialLokiCustomRedirects: [],
-
-							cloudtubeNormalRedirectsChecks: cloudtubeNormalRedirectsChecks,
-							cloudtubeNormalCustomRedirects: [],
-
-							cloudtubeTorRedirectsChecks: [...redirects.cloudtube.tor],
-							cloudtubeTorCustomRedirects: [],
-
-							cloudtubeI2pRedirectsChecks: [...redirects.cloudtube.i2p],
-							cloudtubeI2pCustomRedirects: [],
-
-							cloudtubeLokiRedirectsChecks: [...redirects.cloudtube.loki],
-							cloudtubeLokiCustomRedirects: [],
-
-							youtubeEmbedFrontend: "invidious",
-						},
-						() => resolve()
-					)
-				})
-			})
-	})
-}
-
-function copyPasteInvidiousCookies(test, from) {
-	return new Promise(async resolve => {
-		await init()
-		if (disableYoutube || youtubeFrontend != "invidious") {
-			resolve()
-			return
-		}
-		const protocolHost = utils.protocolHost(from)
-		if (
-			![
-				...invidiousNormalRedirectsChecks,
-				...invidiousTorRedirectsChecks,
-				...invidiousNormalCustomRedirects,
-				...invidiousTorCustomRedirects,
-				...invidiousI2pCustomRedirects,
-				...invidiousLokiCustomRedirects,
-			].includes(protocolHost)
-		) {
-			resolve()
-			return
-		}
-		if (!test) {
-			let checkedInstances = []
-
-			if (protocol == "loki") checkedInstances = [...invidiousLokiCustomRedirects]
-			else if (protocol == "i2p") checkedInstances = [...invidiousI2pCustomRedirects]
-			else if (protocol == "tor") checkedInstances = [...invidiousTorRedirectsChecks, ...invidiousTorCustomRedirects]
-			if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
-				checkedInstances = [...invidiousNormalRedirectsChecks, ...invidiousNormalCustomRedirects]
-			}
-			const i = checkedInstances.indexOf(protocolHost)
-			if (i !== -1) checkedInstances.splice(i, 1)
-			await utils.copyCookie("invidious", from, checkedInstances, "PREFS")
-		}
-		resolve(true)
-	})
-}
-
-function copyPastePipedLocalStorage(test, url, tabId) {
-	return new Promise(async resolve => {
-		await init()
-		if (disableYoutube || youtubeFrontend != "piped") {
-			resolve()
-			return
-		}
-		const protocolHost = utils.protocolHost(url)
-		if (
-			![...pipedNormalCustomRedirects, ...pipedNormalRedirectsChecks, ...pipedTorRedirectsChecks, ...pipedTorCustomRedirects, ...pipedI2pCustomRedirects, ...pipedLokiCustomRedirects].includes(
-				protocolHost
-			)
-		) {
-			resolve()
-			return
-		}
-
-		if (!test) {
-			browser.tabs.executeScript(tabId, {
-				file: "/assets/javascripts/youtube/get_piped_preferences.js",
-				runAt: "document_start",
-			})
-
-			let checkedInstances = []
-			if (protocol == "loki") checkedInstances = [...pipedLokiCustomRedirects]
-			else if (protocol == "i2p") checkedInstances = [...pipedI2pCustomRedirects]
-			else if (protocol == "tor") checkedInstances = [...pipedTorRedirectsChecks, ...pipedTorCustomRedirects]
-			if ((checkedInstances.length === 0 && protocolFallback) || protocol == "normal") {
-				checkedInstances = [...pipedNormalCustomRedirects, ...pipedNormalRedirectsChecks]
-			}
-			const i = checkedInstances.indexOf(protocolHost)
-			if (i !== -1) checkedInstances.splice(i, 1)
-			for (const to of checkedInstances) {
-				browser.tabs.create({ url: to }, tab =>
-					browser.tabs.executeScript(tab.id, {
-						file: "/assets/javascripts/youtube/set_piped_preferences.js",
-						runAt: "document_start",
-					})
-				)
-			}
-		}
-		resolve(true)
-	})
-}
-
-function copyPastePipedMaterialLocalStorage(test, url, tabId) {
-	return new Promise(async resolve => {
-		await init()
-		if (disableYoutube || youtubeFrontend != "pipedMaterial") {
-			resolve()
-			return
-		}
-		const protocolHost = utils.protocolHost(url)
-		if (
-			![
-				...pipedMaterialNormalRedirectsChecks,
-				...pipedMaterialNormalCustomRedirects,
-				//...pipedMaterialTorRedirectsChecks,
-				...pipedMaterialTorCustomRedirects,
-				...pipedMaterialI2pCustomRedirects,
-				...pipedMaterialLokiCustomRedirects,
-			].includes(protocolHost)
-		) {
-			resolve()
-			return
-		}
-
-		if (!test) {
-			browser.tabs.executeScript(tabId, {
-				file: "/assets/javascripts/youtube/get_pipedMaterial_preferences.js",
-				runAt: "document_start",
-			})
-
-			let checkedInstances = []
-			if (protocol == "loki") checkedInstances = [...pipedMaterialLokiCustomRedirects]
-			else if (protocol == "i2p") checkedInstances = [...pipedMaterialI2pCustomRedirects]
-			else if (protocol == "tor") checkedInstances = [...pipedMaterialTorCustomRedirects] //...pipedMaterialTorRedirectsChecks,
-			if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-				checkedInstances = [...pipedMaterialNormalRedirectsChecks, ...pipedMaterialNormalCustomRedirects]
-			}
-			const i = checkedInstances.indexOf(protocolHost)
-			if (i !== -1) checkedInstances.splice(i, 1)
-			for (const to of checkedInstances)
-				browser.tabs.create({ url: to }, tab =>
-					browser.tabs.executeScript(tab.id, {
-						file: "/assets/javascripts/youtube/set_pipedMaterial_preferences.js",
-						runAt: "document_start",
-					})
-				)
-		}
-		resolve(true)
-	})
-}
-
-function removeXFrameOptions(e) {
-	let isChanged = false
-
-	if (e.type == "main_frame") {
-		for (const i in e.responseHeaders) {
-			if (e.responseHeaders[i].name == "content-security-policy") {
-				let instancesList = []
-				switch (protocol) {
-					case "loki":
-						switch (youtubeFrontend) {
-							case "invidious":
-								instancesList = [...invidiousLokiRedirectsChecks, ...invidiousLokiCustomRedirects]
-								break
-							case "piped":
-								instancesList = [...pipedLokiRedirectsChecks, ...pipedLokiCustomRedirects]
-								break
-							case "pipedMaterial":
-								instancesList = [...pipedMaterialLokiRedirectsChecks, ...pipedMaterialLokiCustomRedirects]
-								break
-							case "cloudtube":
-								instancesList = [...cloudtubeLokiRedirectsChecks, ...cloudtubeLokiCustomRedirects]
-						}
-						break
-					case "i2p":
-						switch (youtubeFrontend) {
-							case "invidious":
-								instancesList = [...invidiousI2pRedirectsChecks, ...invidiousI2pCustomRedirects]
-								break
-							case "piped":
-								instancesList = [...pipedI2pRedirectsChecks, ...pipedI2pCustomRedirects]
-								break
-							case "pipedMaterial":
-								instancesList = [...pipedMaterialI2pRedirectsChecks, ...pipedMaterialI2pCustomRedirects]
-								break
-							case "cloudtube":
-								instancesList = [...cloudtubeI2pRedirectsChecks, ...cloudtubeI2pCustomRedirects]
-						}
-						break
-					case "tor":
-						switch (youtubeFrontend) {
-							case "invidious":
-								instancesList = [...invidiousTorRedirectsChecks, ...invidiousTorCustomRedirects]
-								break
-							case "piped":
-								instancesList = [...pipedTorRedirectsChecks, ...pipedTorCustomRedirects]
-								break
-							case "pipedMaterial":
-								instancesList = [...pipedMaterialTorRedirectsChecks, ...pipedMaterialTorCustomRedirects]
-								break
-							case "cloudtube":
-								instancesList = [...cloudtubeTorRedirectsChecks, ...cloudtubeTorCustomRedirects]
-						}
-				}
-				if ((instancesList.length === 0 && protocolFallback) || protocol == "normal") {
-					switch (youtubeFrontend) {
-						case "invidious":
-							instancesList = [...invidiousNormalRedirectsChecks, ...invidiousNormalCustomRedirects]
-							break
-						case "piped":
-							instancesList = [...pipedNormalRedirectsChecks, ...pipedNormalCustomRedirects]
-							break
-						case "pipedMaterial":
-							instancesList = [...pipedMaterialNormalRedirectsChecks, ...pipedMaterialNormalCustomRedirects]
-							break
-						case "cloudtube":
-							instancesList = [...cloudtubeNormalRedirectsChecks, ...cloudtubeNormalCustomRedirects]
-					}
-				}
-				let securityPolicyList = e.responseHeaders[i].value.split(";")
-				for (const i in securityPolicyList) securityPolicyList[i] = securityPolicyList[i].trim()
-
-				let newSecurity = ""
-				for (const item of securityPolicyList) {
-					if (item.trim() == "") continue
-					let regex = item.match(/([a-z-]{0,}) (.*)/)
-					if (regex == null) continue
-					let [, key, vals] = regex
-					if (key == "frame-src") vals = vals + " " + instancesList.join(" ")
-					newSecurity += key + " " + vals + "; "
-				}
-
-				e.responseHeaders[i].value = newSecurity
-				isChanged = true
-			}
-		}
-	} else if (e.type == "sub_frame") {
-		const url = new URL(e.url)
-		const protocolHost = utils.protocolHost(url)
-		if (all().includes(protocolHost)) {
-			for (const i in e.responseHeaders) {
-				if (e.responseHeaders[i].name == "x-frame-options") {
-					e.responseHeaders.splice(i, 1)
-					isChanged = true
-				} else if (e.responseHeaders[i].name == "content-security-policy") {
-					e.responseHeaders.splice(i, 1)
-					isChanged = true
-				}
-			}
-		}
-	}
-	if (isChanged) return { responseHeaders: e.responseHeaders }
-}
-
-export default {
-	setRedirects,
-	copyPastePipedLocalStorage,
-	copyPastePipedMaterialLocalStorage,
-	copyPasteInvidiousCookies,
-	redirect,
-	reverse,
-	switchInstance,
-	initDefaults,
-	removeXFrameOptions,
-}
diff --git a/src/assets/javascripts/youtubeMusic.js b/src/assets/javascripts/youtubeMusic.js
deleted file mode 100644
index 757378f4..00000000
--- a/src/assets/javascripts/youtubeMusic.js
+++ /dev/null
@@ -1,332 +0,0 @@
-"use strict"
-
-import utils from "./utils.js"
-
-window.browser = window.browser || window.chrome
-
-const targets = [/^https?:\/{2}music\.youtube\.com(\/.*|$)/]
-
-const frontends = new Array("beatbump", "hyperpipe")
-const protocols = new Array("normal", "tor", "i2p", "loki")
-
-let redirects = {}
-
-for (let i = 0; i < frontends.length; i++) {
-	redirects[frontends[i]] = {}
-	for (let x = 0; x < protocols.length; x++) {
-		redirects[frontends[i]][protocols[x]] = []
-	}
-}
-
-function setRedirects(val) {
-	return new Promise(resolve =>
-		browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], r => {
-			redirects = val
-			beatbumpNormalRedirectsChecks = [...redirects.beatbump.normal]
-			hyperpipeNormalRedirectsChecks = [...redirects.hyperpipe.normal]
-			for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-				const a = beatbumpNormalRedirectsChecks.indexOf(instance)
-				if (a > -1) beatbumpNormalRedirectsChecks.splice(a, 1)
-
-				const b = hyperpipeNormalRedirectsChecks.indexOf(instance)
-				if (b > -1) hyperpipeNormalRedirectsChecks.splice(b, 1)
-			}
-			browser.storage.local.set(
-				{
-					youtubeMusicRedirects: redirects,
-					beatbumpNormalRedirectsChecks,
-					beatbumpTorRedirectsChecks: [...redirects.beatbump.tor],
-					beatbumpI2pRedirectsChecks: [...redirects.beatbump.i2p],
-					beatbumpLokiRedirectsChecks: [...redirects.beatbump.loki],
-					hyperpipeNormalRedirectsChecks,
-					hyperpipeTorRedirectsChecks: [...redirects.hyperpipe.tor],
-					hyperpipeI2pRedirectsChecks: [...redirects.hyperpipe.i2p],
-					hyperpipeLokiRedirectsChecks: [...redirects.hyperpipe.loki],
-				},
-				() => resolve()
-			)
-		})
-	)
-}
-
-let disableYoutubeMusic,
-	youtubeMusicFrontend,
-	youtubeMusicRedirects,
-	protocol,
-	protocolFallback,
-	beatbumpNormalRedirectsChecks,
-	beatbumpNormalCustomRedirects,
-	beatbumpTorRedirectsChecks,
-	beatbumpTorCustomRedirects,
-	beatbumpI2pRedirectsChecks,
-	beatbumpI2pCustomRedirects,
-	beatbumpLokiRedirectsChecks,
-	beatbumpLokiCustomRedirects,
-	hyperpipeNormalRedirectsChecks,
-	hyperpipeNormalCustomRedirects,
-	hyperpipeTorRedirectsChecks,
-	hyperpipeTorCustomRedirects,
-	hyperpipeI2pRedirectsChecks,
-	hyperpipeI2pCustomRedirects,
-	hyperpipeLokiRedirectsChecks,
-	hyperpipeLokiCustomRedirects
-
-function init() {
-	return new Promise(async resolve => {
-		browser.storage.local.get(
-			[
-				"disableYoutubeMusic",
-				"youtubeMusicFrontend",
-				"youtubeMusicRedirects",
-				"protocol",
-				"protocolFallback",
-				"beatbumpNormalRedirectsChecks",
-				"beatbumpNormalCustomRedirects",
-				"beatbumpTorRedirectsChecks",
-				"beatbumpTorCustomRedirects",
-				"beatbumpI2pRedirectsChecks",
-				"beatbumpI2pCustomRedirects",
-				"beatbumpLokiRedirectsChecks",
-				"beatbumpLokiCustomRedirects",
-				"hyperpipeNormalRedirectsChecks",
-				"hyperpipeNormalCustomRedirects",
-				"hyperpipeTorRedirectsChecks",
-				"hyperpipeTorCustomRedirects",
-				"hyperpipeI2pRedirectsChecks",
-				"hyperpipeI2pCustomRedirects",
-				"hyperpipeLokiRedirectsChecks",
-				"hyperpipeLokiCustomRedirects",
-			],
-			r => {
-				disableYoutubeMusic = r.disableYoutubeMusic
-				youtubeMusicFrontend = r.youtubeMusicFrontend
-				youtubeMusicRedirects = r.youtubeMusicRedirects
-				protocol = r.protocol
-				protocolFallback = r.protocolFallback
-				beatbumpNormalRedirectsChecks = r.beatbumpNormalRedirectsChecks
-				beatbumpNormalCustomRedirects = r.beatbumpNormalCustomRedirects
-				beatbumpTorRedirectsChecks = r.beatbumpTorRedirectsChecks
-				beatbumpTorCustomRedirects = r.beatbumpTorCustomRedirects
-				beatbumpI2pRedirectsChecks = r.beatbumpI2pRedirectsChecks
-				beatbumpI2pCustomRedirects = r.beatbumpI2pCustomRedirects
-				beatbumpLokiRedirectsChecks = r.beatbumpLokiRedirectsChecks
-				beatbumpLokiCustomRedirects = r.beatbumpLokiCustomRedirects
-				hyperpipeNormalRedirectsChecks = r.hyperpipeNormalRedirectsChecks
-				hyperpipeNormalCustomRedirects = r.hyperpipeNormalCustomRedirects
-				hyperpipeTorRedirectsChecks = r.hyperpipeTorRedirectsChecks
-				hyperpipeTorCustomRedirects = r.hyperpipeTorCustomRedirects
-				hyperpipeI2pRedirectsChecks = r.hyperpipeI2pRedirectsChecks
-				hyperpipeI2pCustomRedirects = r.hyperpipeI2pCustomRedirects
-				hyperpipeLokiRedirectsChecks = r.hyperpipeLokiRedirectsChecks
-				hyperpipeLokiCustomRedirects = r.hyperpipeLokiCustomRedirects
-				resolve()
-			}
-		)
-	})
-}
-
-init()
-browser.storage.onChanged.addListener(init)
-
-function all() {
-	return [
-		...beatbumpNormalRedirectsChecks,
-		...beatbumpNormalCustomRedirects,
-		...beatbumpTorRedirectsChecks,
-		...beatbumpTorCustomRedirects,
-		...beatbumpI2pRedirectsChecks,
-		...beatbumpI2pCustomRedirects,
-		...beatbumpLokiRedirectsChecks,
-		...beatbumpLokiCustomRedirects,
-		...hyperpipeNormalRedirectsChecks,
-		...hyperpipeNormalCustomRedirects,
-		...hyperpipeTorRedirectsChecks,
-		...hyperpipeTorCustomRedirects,
-		...hyperpipeI2pRedirectsChecks,
-		...hyperpipeI2pCustomRedirects,
-		...hyperpipeLokiRedirectsChecks,
-		...hyperpipeLokiCustomRedirects,
-	]
-}
-
-function getInstanceList() {
-	let tmpList = []
-	switch (youtubeMusicFrontend) {
-		case "beatbump":
-			switch (protocol) {
-				case "loki":
-					tmpList = [...beatbumpLokiRedirectsChecks, ...beatbumpLokiCustomRedirects]
-					break
-				case "i2p":
-					tmpList = [...beatbumpI2pRedirectsChecks, ...beatbumpI2pCustomRedirects]
-					break
-				case "tor":
-					tmpList = [...beatbumpTorRedirectsChecks, ...beatbumpTorCustomRedirects]
-			}
-			if ((tmpList.length === 0 && protocolFallback) || protocol == "normal") {
-				tmpList = [...beatbumpNormalRedirectsChecks, ...beatbumpNormalCustomRedirects]
-			}
-			break
-		case "hyperpipe":
-			switch (protocol) {
-				case "loki":
-					tmpList = [...hyperpipeLokiRedirectsChecks, ...hyperpipeLokiCustomRedirects]
-					break
-				case "i2p":
-					tmpList = [...hyperpipeI2pRedirectsChecks, ...hyperpipeI2pCustomRedirects]
-					break
-				case "tor":
-					tmpList = [...hyperpipeTorRedirectsChecks, ...hyperpipeTorCustomRedirects]
-			}
-			if ((tmpList.length === 0 && protocolFallback) || protocol == "normal") {
-				tmpList = [...hyperpipeNormalRedirectsChecks, ...hyperpipeNormalCustomRedirects]
-			}
-	}
-	return tmpList
-}
-
-function getUrl(randomInstance, url) {
-	switch (youtubeMusicFrontend) {
-		case "beatbump":
-			return `${randomInstance}${url.pathname}${url.search}`
-				.replace("/watch?v=", "/listen?id=")
-				.replace("/channel/", "/artist/")
-				.replace("/playlist?list=", "/playlist/VL")
-				.replace(/\/search\?q=.*/, searchQuery => searchQuery.replace("?q=", "/") + "?filter=song")
-		case "hyperpipe":
-			return `${randomInstance}${url.pathname}${url.search}`.replace(/\/search\?q=.*/, searchQuery => searchQuery.replace("?q=", "/"))
-	}
-}
-
-/* 
-Video
-https://music.youtube.com/watch?v=_PkGiKBW-DA&list=RDAMVM_PkGiKBW-DA
-https://beatbump.ml/listen?id=_PkGiKBW-DA&list=RDAMVM_PkGiKBW-DA
-
-Playlist
-https://music.youtube.com/playlist?list=PLqxd0OMLeWy64zlwhjouj92ISc38FbOns
-https://music.youtube.com/playlist?list=PLqxd0OMLeWy7lrJSzt9LnOJjbC1IaruPM
-https://music.youtube.com/playlist?list=PLQod4DlD72ZMJmOrSNbmEmK_iZ1oXPzKd
-https://beatbump.ml/playlist/VLPLqxd0OMLeWy64zlwhjouj92ISc38FbOns
-
-Channel
-https://music.youtube.com/channel/UCfgmMDI7T5tOQqjnOBRe_wg
-https://beatbump.ml/artist/UCfgmMDI7T5tOQqjnOBRe_wg
-
-Albums
-https://music.youtube.com/playlist?list=OLAK5uy_n-9HVh3cryV2gREZM9Sc0JwEKYjjfi0dU
-https://music.youtube.com/playlist?list=OLAK5uy_lcr5O1zS8f6WIFI_yxqVp2RK9Dyy2bbw0
-https://beatbump.ml/release?id=MPREb_3DURc4yEUtD
-https://beatbump.ml/release?id=MPREb_evaZrV1WNdS
-
-https://music.youtube.com/playlist?list=OLAK5uy_n6OHVllUZUCnlIY1m-gUaH8uqkN3Y-Ca8
-https://music.youtube.com/playlist?list=OLAK5uy_nBOTxAc3_RGB82-Z54jdARGxGaCYlpngY
-https://beatbump.ml/release?id=MPREb_QygdC0wEoLe
-
-https://music.youtube.com/watch?v=R6gSMSYKhKU&list=OLAK5uy_n-9HVh3cryV2gREZM9Sc0JwEKYjjfi0dU
-
-Search
-https://music.youtube.com/search?q=test
-https://beatbump.ml/search/test?filter=EgWKAQIIAWoKEAMQBBAKEAkQBQ%3D%3D
-
-*/
-function redirect(url, type, initiator, disableOverride) {
-	if (disableYoutubeMusic && !disableOverride) return
-	if (!targets.some(rx => rx.test(url.href))) return
-
-	let instancesList = getInstanceList()
-
-	if (instancesList.length === 0) return
-	const randomInstance = utils.getRandomInstance(instancesList)
-	return getUrl(randomInstance, url)
-}
-
-function switchInstance(url, disableOverride) {
-	return new Promise(async resolve => {
-		await init()
-		if (disableYoutubeMusic && !disableOverride) {
-			resolve()
-			return
-		}
-		const protocolHost = utils.protocolHost(url)
-		if (!all().includes(protocolHost)) {
-			resolve()
-			return
-		}
-
-		let instancesList = getInstanceList()
-
-		const i = instancesList.indexOf(protocolHost)
-		if (i > -1) instancesList.splice(i, 1)
-		if (instancesList.length === 0) {
-			resolve()
-			return
-		}
-
-		const randomInstance = utils.getRandomInstance(instancesList)
-		return getUrl(randomInstance, url)
-	})
-}
-
-function initDefaults() {
-	return new Promise(resolve => {
-		fetch("/instances/data.json")
-			.then(response => response.text())
-			.then(async data => {
-				let dataJson = JSON.parse(data)
-				for (let i = 0; i < frontends.length; i++) {
-					redirects[frontends[i]] = dataJson[frontends[i]]
-				}
-				browser.storage.local.get(["cloudflareBlackList", "offlineBlackList"], async r => {
-					beatbumpNormalRedirectsChecks = [...redirects.beatbump.normal]
-					hyperpipeNormalRedirectsChecks = [...redirects.hyperpipe.normal]
-					for (const instance of [...r.cloudflareBlackList, ...r.offlineBlackList]) {
-						const a = beatbumpNormalRedirectsChecks.indexOf(instance)
-						if (a > -1) beatbumpNormalRedirectsChecks.splice(a, 1)
-
-						const b = hyperpipeNormalRedirectsChecks.indexOf(instance)
-						if (b > -1) hyperpipeNormalRedirectsChecks.splice(b, 1)
-					}
-					browser.storage.local.set(
-						{
-							disableYoutubeMusic: false,
-							youtubeMusicFrontend: "hyperpipe",
-							youtubeMusicRedirects: redirects,
-
-							beatbumpNormalRedirectsChecks,
-							beatbumpNormalCustomRedirects: [],
-
-							beatbumpTorRedirectsChecks: [...redirects.beatbump.tor],
-							beatbumpTorCustomRedirects: [],
-
-							beatbumpI2pRedirectsChecks: [...redirects.beatbump.i2p],
-							beatbumpI2pCustomRedirects: [],
-
-							beatbumpLokiRedirectsChecks: [...redirects.beatbump.loki],
-							beatbumpLokiCustomRedirects: [],
-
-							hyperpipeNormalRedirectsChecks,
-							hyperpipeNormalCustomRedirects: [],
-
-							hyperpipeTorRedirectsChecks: [...redirects.hyperpipe.tor],
-							hyperpipeTorCustomRedirects: [],
-
-							hyperpipeI2pRedirectsChecks: [...redirects.hyperpipe.i2p],
-							hyperpipeI2pCustomRedirects: [],
-
-							hyperpipeLokiRedirectsChecks: [...redirects.hyperpipe.loki],
-							hyperpipeLokiCustomRedirects: [],
-						},
-						() => resolve()
-					)
-				})
-			})
-	})
-}
-
-export default {
-	setRedirects,
-	switchInstance,
-	redirect,
-	initDefaults,
-}