diff --git a/src/en/hwtmanga/AndroidManifest.xml b/src/en/hwtmanga/AndroidManifest.xml
deleted file mode 100644
index 30deb7f79..000000000
--- a/src/en/hwtmanga/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/src/en/hwtmanga/build.gradle b/src/en/hwtmanga/build.gradle
deleted file mode 100644
index 0b4be9ab9..000000000
--- a/src/en/hwtmanga/build.gradle
+++ /dev/null
@@ -1,13 +0,0 @@
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-apply plugin: 'kotlinx-serialization'
-
-ext {
- extName = 'Hardworking Translations'
- pkgNameSuffix = 'en.hwtmanga'
- extClass = '.HWTManga'
- extVersionCode = 2
- isNsfw = true
-}
-
-apply from: "$rootDir/common.gradle"
diff --git a/src/en/hwtmanga/res/mipmap-hdpi/ic_launcher.png b/src/en/hwtmanga/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index ffa8b5936..000000000
Binary files a/src/en/hwtmanga/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/src/en/hwtmanga/res/mipmap-mdpi/ic_launcher.png b/src/en/hwtmanga/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 19b101bf3..000000000
Binary files a/src/en/hwtmanga/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/src/en/hwtmanga/res/mipmap-xhdpi/ic_launcher.png b/src/en/hwtmanga/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index 5f59c4226..000000000
Binary files a/src/en/hwtmanga/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/en/hwtmanga/res/mipmap-xxhdpi/ic_launcher.png b/src/en/hwtmanga/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 60e2a388a..000000000
Binary files a/src/en/hwtmanga/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/en/hwtmanga/res/mipmap-xxxhdpi/ic_launcher.png b/src/en/hwtmanga/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index 206d666a5..000000000
Binary files a/src/en/hwtmanga/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/en/hwtmanga/res/web_hi_res_512.png b/src/en/hwtmanga/res/web_hi_res_512.png
deleted file mode 100644
index 84ccc0db5..000000000
Binary files a/src/en/hwtmanga/res/web_hi_res_512.png and /dev/null differ
diff --git a/src/en/hwtmanga/src/eu/kanade/tachiyomi/extension/en/hwtmanga/HWTFilters.kt b/src/en/hwtmanga/src/eu/kanade/tachiyomi/extension/en/hwtmanga/HWTFilters.kt
deleted file mode 100644
index 3b051e673..000000000
--- a/src/en/hwtmanga/src/eu/kanade/tachiyomi/extension/en/hwtmanga/HWTFilters.kt
+++ /dev/null
@@ -1,132 +0,0 @@
-package eu.kanade.tachiyomi.extension.en.hwtmanga
-
-import eu.kanade.tachiyomi.source.model.Filter
-
-class Tag(name: String, private val id: String) : Filter.CheckBox(name) {
- override fun toString() = id
-}
-
-private val tags: List
- get() = listOf(
- Tag("Action", "action"),
- Tag("Adventure", "adventure"),
- Tag("Comedy", "comedy"),
- Tag("Cooking", "cooking"),
- Tag("Drama", "drama"),
- Tag("Fantasy", "fantasy"),
- Tag("Horror", "horror"),
- Tag("Mystery", "mystery"),
- Tag("Martial Arts", "martialarts"),
- Tag("Romance", "romance"),
- Tag("School Life", "school"),
- Tag("Shoujo", "shoujo"),
- Tag("Shounen", "shounen"),
- Tag("Supernatural", "supernatural"),
- Tag("Sci-fi", "sci-fi"),
- Tag("Slice of Life", "slice of life"),
- Tag("Adult", "adult"),
- Tag("Ancient era", "ancient era"),
- Tag("Arranged Marriage", "arranged_marriage"),
- Tag("Age gap", "age_gap"),
- Tag("Betrayal", "betrayal"),
- Tag("Clan", "clan"),
- Tag("Childhood Friends", "childhood_friends"),
- Tag("Couple", "couple"),
- Tag("Crime", "crime"),
- Tag("Cultivation", "cultivation"),
- Tag("Comic", "comic"),
- Tag("Delinquent", "delinquent"),
- Tag("Doujinshi", "doujinshi"),
- Tag("Ecchi", "ecchi"),
- Tag("Family", "family"),
- Tag("Fetishes", "fetish"),
- Tag("Gender Bender", "gender_bender"),
- Tag("Gyaru", "gyaru"),
- Tag("Harem", "harem"),
- Tag("Historical", "historical"),
- Tag("Isekai", "isekai"),
- Tag("Josei", "josei"),
- Tag("Lolicon", "lolicon"),
- Tag("Leader or Politician", "leader_politician"),
- Tag("Mature", "mature"),
- Tag("Magic", "magic"),
- Tag("Mangaka", "mangaka"),
- Tag("Masochist", "masochist"),
- Tag("Monsters", "monsters"),
- Tag("Mecha", "mecha"),
- Tag("Music", "music"),
- Tag("Medical", "medical"),
- Tag("Misunderstands", "misunderstands"),
- Tag("OneShot", "oneshot"),
- Tag("Public figure", "public figure"),
- Tag("Psychological", "psychological"),
- Tag("Powerful Lead Character", "powerful"),
- Tag("Rushed ending", "rushed end"),
- Tag("Revenge", "revenge"),
- Tag("Reverse Harem", "reverse_harem"),
- Tag("Sadist", "sadist"),
- Tag("Seinen", "seinen"),
- Tag("Shotacon", "shotacon"),
- Tag("Secret Crush", "secret_crush"),
- Tag("Secret Relationship", "secret_relationship"),
- Tag("Smart MC", "smart_mc"),
- Tag("Sports", "sports"),
- Tag("Smut", "smut"),
- Tag("Tragedy", "tragedy"),
- Tag("Tomboy", "tomboy"),
- Tag("Triangles", "triangles"),
- Tag("Unusual Pupils", "unusual_pupils"),
- Tag("Vampires", "vampires"),
- Tag("Webtoon", "webtoon"),
- Tag("Work", "work"),
- Tag("Zombies", "zombies"),
- Tag("4-Koma", "4koma"),
- Tag("Manga", "manga"),
- Tag("Manhwa", "manhwa"),
- Tag("Manhua", "manhua"),
- )
-
-class TagFilter(
- values: List = tags,
-) : Filter.Group("Tag Match", values) {
- override fun toString() =
- state.filter { it.state }.joinToString(";").ifEmpty { "all;" }
-}
-
-private val states: Array
- get() = arrayOf("ALL", "Completed", "Ongoing")
-
-class StateFilter(
- values: Array = states,
-) : Filter.Select("State", values) {
- private val ids = arrayOf("all", "complete", "ongoing")
-
- override fun toString() = ids[state]
-}
-
-private val orders: Array
- get() = arrayOf(
- "A~Z",
- "Z~A",
- "Newest",
- "Oldest",
- "Most Liked",
- "Most Viewed",
- "Most Favourite",
- )
-
-class OrderFilter(
- values: Array = orders,
-) : Filter.Select("Order By", values) {
- private val ids = arrayOf(
- "az",
- "za",
- "newest",
- "oldest",
- "liked",
- "viewed",
- "fav",
- )
-
- override fun toString() = ids[state]
-}
diff --git a/src/en/hwtmanga/src/eu/kanade/tachiyomi/extension/en/hwtmanga/HWTManga.kt b/src/en/hwtmanga/src/eu/kanade/tachiyomi/extension/en/hwtmanga/HWTManga.kt
deleted file mode 100644
index 5708b227d..000000000
--- a/src/en/hwtmanga/src/eu/kanade/tachiyomi/extension/en/hwtmanga/HWTManga.kt
+++ /dev/null
@@ -1,214 +0,0 @@
-package eu.kanade.tachiyomi.extension.en.hwtmanga
-
-import eu.kanade.tachiyomi.network.POST
-import eu.kanade.tachiyomi.network.asObservableSuccess
-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.json.Json
-import kotlinx.serialization.json.decodeFromJsonElement
-import kotlinx.serialization.json.jsonObject
-import okhttp3.Cookie
-import okhttp3.CookieJar
-import okhttp3.FormBody
-import okhttp3.HttpUrl
-import okhttp3.Request
-import okhttp3.Response
-import uy.kohesive.injekt.injectLazy
-import java.text.SimpleDateFormat
-import java.util.Locale
-
-class HWTManga : HttpSource() {
- override val name = "Hardworking Translations"
-
- override val baseUrl = "https://www.hwtmanga.com/hwt/"
-
- override val lang = "en"
-
- override val supportsLatest = true
-
- override val client = network.client.newBuilder().cookieJar(
- object : CookieJar {
- override fun saveFromResponse(url: HttpUrl, cookies: List) {}
-
- override fun loadForRequest(url: HttpUrl) =
- listOf(
- Cookie.Builder()
- .domain("www.hwtmanga.com")
- .path("/hwt")
- .name("PHPSESSID")
- .value(sessionID)
- .build(),
- Cookie.Builder()
- .domain("www.hwtmanga.com")
- .path("/")
- .name("manga_security_id")
- .value(postID)
- .build(),
- )
- },
- ).build()
-
- private var postID = ""
-
- private var sessionID = ""
-
- private val json by injectLazy()
-
- override fun latestUpdatesRequest(page: Int) =
- FormBody.Builder().search(order = "newest", pid = page)
-
- override fun latestUpdatesParse(response: Response) =
- searchMangaParse(response)
-
- override fun popularMangaRequest(page: Int) =
- FormBody.Builder().search(order = "viewed", pid = page)
-
- override fun popularMangaParse(response: Response) =
- searchMangaParse(response)
-
- override fun searchMangaRequest(page: Int, query: String, filters: FilterList) =
- FormBody.Builder().search(
- query = query,
- pid = page,
- tags = filters.get("all;"),
- state = filters.get("all"),
- order = filters.get("az"),
- )
-
- override fun searchMangaParse(response: Response) =
- response.parse>("query").map {
- SManga.create().apply {
- title = it.title
- thumbnail_url = it.cimage
- url = "?page=manga&vid=${it.postID}"
- }
- }.let { MangasPage(it, false) }
-
- override fun fetchMangaDetails(manga: SManga) =
- FormBody.Builder().post("GET_MANGA_INFO") {
- add("scom", "0")
- add("pageid", "1")
- add("pid", manga.id)
- }.let(client::newCall).asObservableSuccess().map { res ->
- // Session cookie is required to view pages
- if (sessionID == "") {
- val request = Request.Builder()
- .url(baseUrl)
- .headers(headers)
- .head().build()
- client.newCall(request).execute().header("Set-Cookie")?.let {
- sessionID = Cookie.parse(request.url, it)?.value ?: ""
- }
- }
-
- val info = res.parse("mangaInfo")
- info.tags[0].value = info.mtag.value
- manga.title = info.title
- manga.thumbnail_url = info.cover
- manga.description = info.desc + "\n\n\n" +
- info.onames.replace(",", " | ")
- manga.genre = info.tags.joinToString { it.value!! }
- manga.status = when (info.statue) {
- 1 -> SManga.ONGOING
- else -> SManga.UNKNOWN
- }
- manga.initialized = true
- return@map manga
- }!!
-
- override fun chapterListRequest(manga: SManga) =
- FormBody.Builder().post("GET_CHAPTER_LIST") {
- add("pageid", "1")
- add("pid", manga.id)
- }
-
- override fun chapterListParse(response: Response) =
- response.parse("all_data").mapIndexed { idx, ch ->
- SChapter.create().apply {
- chapter_number = idx + 1f
- url = "?page=watch_manga&cid=${ch.fid}&pid=${ch.pid}"
- date_upload = dateFormat.parse(ch.cdate)?.time ?: 0L
- name = buildString {
- append("Chapter %.0f".format(chapter_number))
- if (ch.name != "-") append(" | ${ch.name}")
- if (ch.is_locked != "false") append(LOCK)
- }
- }
- }
-
- override fun pageListRequest(chapter: SChapter) =
- FormBody.Builder().post("GET_CHA_DATA", "manga_viewer") {
- val tokens = chapter.tokens
- postID = tokens[5]
- add("pageid", "1")
- add("cid", tokens[3])
- add("pid", postID)
- }
-
- override fun pageListParse(response: Response) =
- response.parse>("clist")
- .mapIndexed { idx, page -> Page(idx, "", page.image) }
-
- override fun getFilterList() =
- FilterList(TagFilter(), StateFilter(), OrderFilter())
-
- override fun mangaDetailsParse(response: Response) =
- throw UnsupportedOperationException("Not used")
-
- override fun imageUrlParse(response: Response) =
- throw UnsupportedOperationException("Not used")
-
- private inline val SManga.id: String
- get() = url.substringAfterLast('=')
-
- private inline val SChapter.tokens: List
- get() = url.split('&', '=')
-
- private inline val HWTPage.image: String
- get() = if (base.startsWith("http")) base else baseUrl + base
-
- private fun FormBody.Builder.post(
- subpage: String,
- page: String = "mangaData",
- block: FormBody.Builder.() -> FormBody.Builder,
- ) = add("page", page).add("subpage", subpage).run {
- POST(baseUrl + "callback.php", headers, block().build())
- }
-
- private fun FormBody.Builder.search(
- query: String = "",
- tags: String = "all;",
- state: String = "all",
- order: String = "az",
- pid: Int = 1,
- ) = post("MANGASEARCH") {
- add("searchbox", query)
- add("byg", tags)
- add("bys", state)
- add("byo", order)
- add("pid", pid.toString())
- }
-
- private inline fun Response.parse(key: String) =
- body.string().let { body ->
- if ("success" !in body) error(body)
- json.decodeFromJsonElement(
- json.parseToJsonElement(body).jsonObject[key]!!,
- )
- }
-
- private inline fun FilterList.get(default: String) =
- find { it is T }?.toString() ?: default
-
- companion object {
- private const val LOCK = " \uD83D\uDD12"
-
- private val dateFormat by lazy {
- SimpleDateFormat("MMM dd, yyyy", Locale.ROOT)
- }
- }
-}
diff --git a/src/en/hwtmanga/src/eu/kanade/tachiyomi/extension/en/hwtmanga/HWTModels.kt b/src/en/hwtmanga/src/eu/kanade/tachiyomi/extension/en/hwtmanga/HWTModels.kt
deleted file mode 100644
index b2570a016..000000000
--- a/src/en/hwtmanga/src/eu/kanade/tachiyomi/extension/en/hwtmanga/HWTModels.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-package eu.kanade.tachiyomi.extension.en.hwtmanga
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class HWTQuery(
- val cimage: String,
- val postID: String,
- val title: String,
-)
-
-@Serializable
-data class HWTMangaInfo(
- val cover: String,
- val desc: String,
- val mtag: HWTTag,
- val onames: String,
- val statue: Int,
- val postID: Int,
- val tags: List,
- val title: String,
-)
-
-@Serializable
-data class HWTTag(var value: String?)
-
-@Serializable
-data class HWTChapterList(
- private val chapterList: List,
-) : List by chapterList
-
-@Serializable
-data class HWTChapter(
- val fid: String,
- val pid: String,
- val name: String,
- val cdate: String,
- val is_locked: String,
-)
-
-@Serializable
-data class HWTPage(val base: String)