diff --git a/multisrc/overrides/mangathemesia/lynxscans/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/mangathemesia/lynxscans/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..51faf999b
Binary files /dev/null and b/multisrc/overrides/mangathemesia/lynxscans/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/mangathemesia/lynxscans/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/mangathemesia/lynxscans/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..50a5fb1e2
Binary files /dev/null and b/multisrc/overrides/mangathemesia/lynxscans/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/mangathemesia/lynxscans/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/mangathemesia/lynxscans/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..6f0cf0b3c
Binary files /dev/null and b/multisrc/overrides/mangathemesia/lynxscans/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/mangathemesia/lynxscans/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/mangathemesia/lynxscans/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..ea55342e7
Binary files /dev/null and b/multisrc/overrides/mangathemesia/lynxscans/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/mangathemesia/lynxscans/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/mangathemesia/lynxscans/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..bab441b49
Binary files /dev/null and b/multisrc/overrides/mangathemesia/lynxscans/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/mangathemesia/lynxscans/res/web_hi_res_512.png b/multisrc/overrides/mangathemesia/lynxscans/res/web_hi_res_512.png
new file mode 100644
index 000000000..3a35efa06
Binary files /dev/null and b/multisrc/overrides/mangathemesia/lynxscans/res/web_hi_res_512.png differ
diff --git a/multisrc/overrides/mangathemesia/lynxscans/src/LynxScans.kt b/multisrc/overrides/mangathemesia/lynxscans/src/LynxScans.kt
new file mode 100644
index 000000000..9fb2156a6
--- /dev/null
+++ b/multisrc/overrides/mangathemesia/lynxscans/src/LynxScans.kt
@@ -0,0 +1,34 @@
+package eu.kanade.tachiyomi.extension.en.lynxscans
+
+import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
+import eu.kanade.tachiyomi.network.interceptor.rateLimit
+import okhttp3.Interceptor
+import okhttp3.Response
+
+class LynxScans : MangaThemesia("LynxScans", "https://lynxscans.com", "en", "/comics") {
+ override val versionId = 3
+ override val hasProjectPage = true
+
+ override val client = super.client.newBuilder()
+ .addNetworkInterceptor(::pageSpeedRedirectIntercept)
+ .rateLimit(2)
+ .build()
+
+ private fun pageSpeedRedirectIntercept(chain: Interceptor.Chain): Response {
+ val request = chain.request()
+
+ if (request.url.pathSegments.contains("wp-content") || request.method == "POST") {
+ return chain.proceed(request)
+ }
+
+ val newUrl = request.url.newBuilder()
+ .setQueryParameter("PageSpeed", "noscript")
+ .build()
+
+ val newRequest = request.newBuilder()
+ .url(newUrl)
+ .build()
+
+ return chain.proceed(newRequest)
+ }
+}
diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangathemesia/MangaThemesiaGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangathemesia/MangaThemesiaGenerator.kt
index cecb47aa4..216e6dd10 100644
--- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangathemesia/MangaThemesiaGenerator.kt
+++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangathemesia/MangaThemesiaGenerator.kt
@@ -61,6 +61,7 @@ class MangaThemesiaGenerator : ThemeSourceGenerator {
SingleLang("Legion Scan", "https://legionscans.com", "es", overrideVersionCode = 6),
SingleLang("LianScans", "https://www.lianscans.my.id", "id", isNsfw = true),
SingleLang("Lunar Scans", "https://lunarscan.org", "en", isNsfw = true),
+ SingleLang("LynxScans", "https://lynxscans.com", "en"),
SingleLang("Magus Manga", "https://magusmanga.com", "ar"),
SingleLang("Manga Indo.me", "https://mangaindo.me", "id", className = "MangaIndoMe"),
SingleLang("Manga Raw.org", "https://mangaraw.org", "ja", className = "MangaRawOrg", overrideVersionCode = 1),
diff --git a/src/en/lynxscans/AndroidManifest.xml b/src/en/lynxscans/AndroidManifest.xml
deleted file mode 100644
index 30deb7f79..000000000
--- a/src/en/lynxscans/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/src/en/lynxscans/build.gradle b/src/en/lynxscans/build.gradle
deleted file mode 100644
index 4b62f029f..000000000
--- a/src/en/lynxscans/build.gradle
+++ /dev/null
@@ -1,12 +0,0 @@
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-apply plugin: 'kotlinx-serialization'
-
-ext {
- extName = 'LynxScans'
- pkgNameSuffix = 'en.lynxscans'
- extClass = '.LynxScans'
- extVersionCode = 7
-}
-
-apply from: "$rootDir/common.gradle"
diff --git a/src/en/lynxscans/res/mipmap-hdpi/ic_launcher.png b/src/en/lynxscans/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index 1dd6cfde4..000000000
Binary files a/src/en/lynxscans/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/src/en/lynxscans/res/mipmap-mdpi/ic_launcher.png b/src/en/lynxscans/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 1c411bc85..000000000
Binary files a/src/en/lynxscans/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/src/en/lynxscans/res/mipmap-xhdpi/ic_launcher.png b/src/en/lynxscans/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index f9083e6c8..000000000
Binary files a/src/en/lynxscans/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/en/lynxscans/res/mipmap-xxhdpi/ic_launcher.png b/src/en/lynxscans/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 951a16c8f..000000000
Binary files a/src/en/lynxscans/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/en/lynxscans/res/mipmap-xxxhdpi/ic_launcher.png b/src/en/lynxscans/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index 5e87a4ede..000000000
Binary files a/src/en/lynxscans/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/en/lynxscans/res/web_hi_res_512.png b/src/en/lynxscans/res/web_hi_res_512.png
deleted file mode 100644
index 65950d349..000000000
Binary files a/src/en/lynxscans/res/web_hi_res_512.png and /dev/null differ
diff --git a/src/en/lynxscans/src/eu/kanade/tachiyomi/extension/en/lynxscans/LynxScans.kt b/src/en/lynxscans/src/eu/kanade/tachiyomi/extension/en/lynxscans/LynxScans.kt
deleted file mode 100644
index a151a0a20..000000000
--- a/src/en/lynxscans/src/eu/kanade/tachiyomi/extension/en/lynxscans/LynxScans.kt
+++ /dev/null
@@ -1,130 +0,0 @@
-package eu.kanade.tachiyomi.extension.en.lynxscans
-
-import eu.kanade.tachiyomi.network.GET
-import eu.kanade.tachiyomi.source.model.FilterList
-import eu.kanade.tachiyomi.source.model.MangasPage
-import eu.kanade.tachiyomi.source.model.Page
-import eu.kanade.tachiyomi.source.model.SChapter
-import eu.kanade.tachiyomi.source.model.SManga
-import eu.kanade.tachiyomi.source.online.HttpSource
-import kotlinx.serialization.decodeFromString
-import kotlinx.serialization.json.Json
-import okhttp3.Request
-import okhttp3.Response
-import uy.kohesive.injekt.injectLazy
-
-class LynxScans : HttpSource() {
- override val baseUrl: String = "https://lynxscans.com"
- private val apiUrl: String = "https://api.lynxscans.com/api"
-
- override val lang: String = "en"
- override val name: String = "LynxScans"
-
- override val versionId = 2
-
- override val supportsLatest: Boolean = true
-
- private val json: Json by injectLazy()
-
- // Popular
- override fun popularMangaRequest(page: Int): Request {
- return GET("$apiUrl/comics?page=$page", headers)
- }
-
- override fun popularMangaParse(response: Response): MangasPage {
- val data = json.decodeFromString(response.body.string())
-
- val titles = data.comics.data.map(PopularComicsData::toSManga)
-
- return MangasPage(titles, !data.comics.next_page_url.isNullOrEmpty())
- }
-
- // Latest
- override fun latestUpdatesRequest(page: Int): Request {
- return GET("$apiUrl/latest?page=$page", headers)
- }
-
- override fun latestUpdatesParse(response: Response): MangasPage {
- val data = json.decodeFromString(response.body.string())
-
- val titles = data.chapters.data.distinctBy { it.comic_titleSlug }.map(LatestChaptersData::toSManga)
-
- return MangasPage(titles, !data.chapters.next_page_url.isNullOrEmpty())
- }
-
- // Search
- override fun searchMangaParse(response: Response): MangasPage {
- throw UnsupportedOperationException("Not used")
- }
-
- override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
- throw Exception("Search is not supported")
- }
-
- // Details
- override fun mangaDetailsParse(response: Response): SManga {
- val data = json.decodeFromString(response.body.string())
-
- return data.comic.toSManga()
- }
-
- override fun mangaDetailsRequest(manga: SManga): Request {
- val titleId = manga.url.substringAfterLast("/")
-
- return GET("$apiUrl/comics/$titleId", headers)
- }
-
- override fun getMangaUrl(manga: SManga): String {
- val titleId = manga.url.substringAfterLast("/")
-
- return "$baseUrl/comics/$titleId"
- }
-
- // Chapters
- override fun chapterListRequest(manga: SManga): Request {
- return mangaDetailsRequest(manga)
- }
-
- override fun chapterListParse(response: Response): List {
- val data = json.decodeFromString(response.body.string())
-
- val chapters: MutableList = mutableListOf()
-
- data.comic.volumes.forEach { volume ->
- volume.chapters.forEach { chapter ->
- chapters.add(
- SChapter.create().apply {
- url = "/comics/${data.comic.titleSlug}/volume/${volume.number}/chapter/${chapter.number}"
- name = volume.name + " " + (if (!chapter.name.contains("chapter", true)) "Chapter ${chapter.number} " else "") + chapter.name
- },
- )
- }
- }
-
- return chapters
- }
-
- override fun getChapterUrl(chapter: SChapter): String {
- val chapterPath = chapter.url.substringAfter("/")
-
- return "$baseUrl/$chapterPath"
- }
-
- // Page
- override fun pageListRequest(chapter: SChapter): Request {
- val chapterPath = chapter.url.substringAfter("/")
-
- return GET("$apiUrl/$chapterPath", headers)
- }
-
- override fun pageListParse(response: Response): List {
- val data = json.decodeFromString(response.body.string())
-
- return data.pages.mapIndexed { idx, it ->
- Page(idx, imageUrl = it.thumb)
- }
- }
-
- // Unused
- override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException("Not Used")
-}
diff --git a/src/en/lynxscans/src/eu/kanade/tachiyomi/extension/en/lynxscans/LynxScansDto.kt b/src/en/lynxscans/src/eu/kanade/tachiyomi/extension/en/lynxscans/LynxScansDto.kt
deleted file mode 100644
index 81780f5c5..000000000
--- a/src/en/lynxscans/src/eu/kanade/tachiyomi/extension/en/lynxscans/LynxScansDto.kt
+++ /dev/null
@@ -1,110 +0,0 @@
-package eu.kanade.tachiyomi.extension.en.lynxscans
-
-import eu.kanade.tachiyomi.source.model.SManga
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class Latest(
- val chapters: LatestChapters,
-)
-
-@Serializable
-data class LatestChapters(
- val next_page_url: String?,
- val data: List,
-)
-
-@Serializable
-data class LatestChaptersData(
- val comic_title: String,
- val comic_thumb: String,
- val comic_titleSlug: String,
-) {
- fun toSManga(): SManga = SManga.create().apply {
- title = this@LatestChaptersData.comic_title
- thumbnail_url = this@LatestChaptersData.comic_thumb
- url = "/comics/" + this@LatestChaptersData.comic_titleSlug
- }
-}
-
-@Serializable
-data class Popular(
- val comics: PopularComics,
-)
-
-@Serializable
-data class PopularComics(
- val next_page_url: String?,
- val data: List,
-)
-
-@Serializable
-data class PopularComicsData(
- val title: String,
- val thumb: String,
- val titleSlug: String,
-) {
- fun toSManga(): SManga = SManga.create().apply {
- title = this@PopularComicsData.title
- thumbnail_url = this@PopularComicsData.thumb
- url = "/comics/" + this@PopularComicsData.titleSlug
- }
-}
-
-@Serializable
-data class MangaDetails(
- val comic: MangaDetailsComicData,
-)
-
-@Serializable
-data class MangaDetailsComicData(
- val title: String,
- val thumb: String,
- val titleSlug: String,
- val artist: String,
- val author: String,
- val description: String,
- val tags: List,
-
- val volumes: List,
-
-) {
- fun toSManga(): SManga = SManga.create().apply {
- title = this@MangaDetailsComicData.title
- thumbnail_url = this@MangaDetailsComicData.thumb
- url = "/comics/" + this@MangaDetailsComicData.titleSlug
- author = if (this@MangaDetailsComicData.author != "blank") this@MangaDetailsComicData.author else null
- artist = if (this@MangaDetailsComicData.artist != "blank") this@MangaDetailsComicData.artist else null
- description = this@MangaDetailsComicData.description
- genre = this@MangaDetailsComicData.tags.joinToString { it.name }
- status = SManga.UNKNOWN
- }
-}
-
-@Serializable
-data class MangaDetailsTag(
- val name: String,
-)
-
-@Serializable
-data class MangaDetailsVolume(
- val chapters: List,
- val name: String,
- val number: Int,
-)
-
-@Serializable
-data class MangaDetailsChapter(
- val name: String,
- val number: Int,
-)
-
-@Serializable
-data class PageList(
- val pages: List,
-)
-
-@Serializable
-data class Page(
- val thumb: String,
-)