diff --git a/src/zh/comico/AndroidManifest.xml b/src/zh/comico/AndroidManifest.xml
deleted file mode 100644
index 30deb7f79..000000000
--- a/src/zh/comico/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/src/zh/comico/build.gradle b/src/zh/comico/build.gradle
deleted file mode 100644
index 01c832b2c..000000000
--- a/src/zh/comico/build.gradle
+++ /dev/null
@@ -1,12 +0,0 @@
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-apply plugin: 'kotlinx-serialization'
-
-ext {
- extName = 'Comico'
- pkgNameSuffix = 'zh.comico'
- extClass = '.ComicoFactory'
- extVersionCode = 3
-}
-
-apply from: "$rootDir/common.gradle"
diff --git a/src/zh/comico/res/mipmap-hdpi/ic_launcher.png b/src/zh/comico/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index 032fb371e..000000000
Binary files a/src/zh/comico/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/src/zh/comico/res/mipmap-mdpi/ic_launcher.png b/src/zh/comico/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 3056e61ae..000000000
Binary files a/src/zh/comico/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/src/zh/comico/res/mipmap-xhdpi/ic_launcher.png b/src/zh/comico/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index 51dfe452b..000000000
Binary files a/src/zh/comico/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/zh/comico/res/mipmap-xxhdpi/ic_launcher.png b/src/zh/comico/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 2891cf9a0..000000000
Binary files a/src/zh/comico/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/zh/comico/res/mipmap-xxxhdpi/ic_launcher.png b/src/zh/comico/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index eeccd9050..000000000
Binary files a/src/zh/comico/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/zh/comico/res/web_hi_res_512.png b/src/zh/comico/res/web_hi_res_512.png
deleted file mode 100644
index 09b0f149e..000000000
Binary files a/src/zh/comico/res/web_hi_res_512.png and /dev/null differ
diff --git a/src/zh/comico/src/eu/kanade/tachiyomi/extension/zh/comico/Comico.kt b/src/zh/comico/src/eu/kanade/tachiyomi/extension/zh/comico/Comico.kt
deleted file mode 100644
index 58d117cf2..000000000
--- a/src/zh/comico/src/eu/kanade/tachiyomi/extension/zh/comico/Comico.kt
+++ /dev/null
@@ -1,176 +0,0 @@
-package eu.kanade.tachiyomi.extension.zh.comico
-
-import eu.kanade.tachiyomi.network.GET
-import eu.kanade.tachiyomi.network.POST
-import eu.kanade.tachiyomi.source.model.FilterList
-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.ParsedHttpSource
-import kotlinx.serialization.decodeFromString
-import kotlinx.serialization.json.Json
-import kotlinx.serialization.json.JsonObject
-import kotlinx.serialization.json.jsonArray
-import kotlinx.serialization.json.jsonObject
-import kotlinx.serialization.json.jsonPrimitive
-import okhttp3.FormBody
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import okhttp3.Response
-import org.jsoup.nodes.Document
-import org.jsoup.nodes.Element
-import uy.kohesive.injekt.injectLazy
-import java.text.SimpleDateFormat
-import java.util.Locale
-
-abstract class Comico(
- override val name: String,
- open val urlModifier: String,
- override val supportsLatest: Boolean
-) : ParsedHttpSource() {
-
- override val baseUrl = "https://www.comico.com.tw"
-
- override val lang = "zh"
-
- override val client: OkHttpClient = network.cloudflareClient
-
- val json: Json by injectLazy()
-
- // Popular
-
- override fun popularMangaRequest(page: Int): Request {
- return GET("$baseUrl$urlModifier/official/finish/?order=ALLSALES", headers)
- }
-
- override fun popularMangaSelector() = "ul.list-article02__list li.list-article02__item a"
-
- override fun popularMangaFromElement(element: Element): SManga {
- val manga = SManga.create()
-
- manga.url = element.attr("href").substringAfter(baseUrl + urlModifier)
- manga.title = element.attr("title")
- manga.thumbnail_url = element.select("img").first().attr("abs:src")
-
- return manga
- }
-
- override fun popularMangaNextPageSelector() = "No next page"
-
- // Latest
-
- override fun latestUpdatesRequest(page: Int): Request = throw UnsupportedOperationException("Not used")
-
- override fun latestUpdatesSelector() = throw UnsupportedOperationException("Not used")
-
- override fun latestUpdatesFromElement(element: Element): SManga = throw UnsupportedOperationException("Not used")
-
- override fun latestUpdatesNextPageSelector() = throw UnsupportedOperationException("Not used")
-
- // Search
-
- override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
- return GET("$baseUrl/search/index.nhn?searchWord=$query", headers)
- }
-
- override fun searchMangaSelector() = "div#officialList ul.list-article02__list li.list-article02__item a"
-
- override fun searchMangaFromElement(element: Element) = popularMangaFromElement(element)
-
- override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
-
- // Manga details
-
- override fun mangaDetailsRequest(manga: SManga): Request {
- return GET(baseUrl + urlModifier + manga.url, headers)
- }
-
- override fun mangaDetailsParse(document: Document): SManga {
- val infoElement = document.select("div.article-hero05")
-
- val manga = SManga.create()
- manga.title = infoElement.select("h1").text()
- manga.author = infoElement.select("p.article-hero05__author").text()
- manga.description = infoElement.select("p.article-hero05__sub-description").text()
- manga.genre = infoElement.select("div.article-hero05__meta a").text()
- manga.status = parseStatus(infoElement.select("div.article-hero05__meta p:not(:has(a))").first().text())
- manga.thumbnail_url = infoElement.select("img").attr("src")
-
- return manga
- }
-
- private fun parseStatus(status: String?) = when {
- status == null -> SManga.UNKNOWN
- status.contains("每") -> SManga.ONGOING
- status.contains("完結作品") -> SManga.COMPLETED
- else -> SManga.UNKNOWN
- }
-
- // Chapters
-
- override fun chapterListSelector() = throw UnsupportedOperationException("Not used")
-
- override fun chapterFromElement(element: Element): SChapter = throw UnsupportedOperationException("Not used")
-
- override fun chapterListRequest(manga: SManga): Request {
- val chapterListHeaders = headersBuilder()
- .add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
- .build()
-
- val body = FormBody.Builder()
- .add("titleNo", manga.url.replace("/", ""))
- .build()
-
- return POST("$baseUrl/api/getArticleList.nhn", chapterListHeaders, body)
- }
-
- fun chapterFromJson(jsonObject: JsonObject): SChapter {
- val chapter = SChapter.create()
-
- chapter.name = jsonObject["subtitle"]!!.jsonPrimitive.content
- chapter.setUrlWithoutDomain(jsonObject["articleDetailUrl"]!!.jsonPrimitive.content)
- chapter.date_upload = parseDate(jsonObject["date"]!!.jsonPrimitive.content)
-
- return chapter
- }
-
- override fun chapterListParse(response: Response): List {
- val chapters = mutableListOf()
-
- json.decodeFromString(response.body!!.string())["result"]!!
- .jsonObject["list"]!!
- .jsonArray
- .forEach {
- if (it.jsonObject["freeFlg"]!!.jsonPrimitive.content == "Y") {
- chapters.add(chapterFromJson(it.jsonObject))
- }
- }
-
- return chapters.reversed()
- }
-
- private fun parseDate(date: String): Long {
- return SimpleDateFormat("yyyy.MM.dd", Locale.getDefault()).parse(date)?.time ?: 0L
- }
-
- override fun pageListParse(document: Document): List {
- val pages = mutableListOf()
-
- // First image is in the body
- document.select("div.comic-image img")
- .map { pages.add(Page(pages.size, "", it.attr("abs:src"))) }
- // If there are more images, they're in a script
- document.select("script:containsData(imageData)").first().data().let {
- if (it.isNotEmpty()) {
- it.substringAfter("imageData:[").substringBefore("]").trim().split(",")
- .forEach { img -> pages.add(Page(pages.size, "", img.replace("\'", ""))) }
- }
- }
-
- return pages
- }
-
- override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
-
- override fun getFilterList() = FilterList()
-}
diff --git a/src/zh/comico/src/eu/kanade/tachiyomi/extension/zh/comico/ComicoFactory.kt b/src/zh/comico/src/eu/kanade/tachiyomi/extension/zh/comico/ComicoFactory.kt
deleted file mode 100644
index 61200d0d4..000000000
--- a/src/zh/comico/src/eu/kanade/tachiyomi/extension/zh/comico/ComicoFactory.kt
+++ /dev/null
@@ -1,109 +0,0 @@
-package eu.kanade.tachiyomi.extension.zh.comico
-
-import eu.kanade.tachiyomi.network.POST
-import eu.kanade.tachiyomi.source.Source
-import eu.kanade.tachiyomi.source.SourceFactory
-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 kotlinx.serialization.decodeFromString
-import kotlinx.serialization.json.JsonObject
-import kotlinx.serialization.json.jsonArray
-import kotlinx.serialization.json.jsonObject
-import kotlinx.serialization.json.jsonPrimitive
-import okhttp3.FormBody
-import okhttp3.Request
-import okhttp3.Response
-import org.jsoup.nodes.Document
-
-class ComicoFactory : SourceFactory {
- override fun createSources(): List = listOf(
- ComicoOfficial(),
- ComicoChallenge()
- )
-}
-
-class ComicoOfficial : Comico("Comico Official (Limited free chapters)", "", false)
-class ComicoChallenge : Comico("Comico Challenge", "/challenge", true) {
- override fun popularMangaRequest(page: Int): Request {
- val body = FormBody.Builder()
- .add("page", page.toString())
- .build()
-
- return POST("$baseUrl$urlModifier/updateList.nhn?order=new", headers, body)
- }
-
- override fun popularMangaParse(response: Response): MangasPage {
- val mangas = mutableListOf()
- val body = response.body!!.string()
-
- json.decodeFromString(body)["result"]!!
- .jsonObject["list"]!!
- .jsonArray
- .forEach {
- val manga = SManga.create()
-
- manga.thumbnail_url = it.jsonObject["img_url"]!!.jsonPrimitive.content
- manga.title = it.jsonObject["article_title"]!!.jsonPrimitive.content
- manga.author = it.jsonObject["author"]!!.jsonPrimitive.content
- manga.description = it.jsonObject["description"]!!.jsonPrimitive.content
- manga.url = it.jsonObject["article_url"]!!.jsonPrimitive.content.substringAfter(urlModifier)
- manga.status = if (it.jsonObject["is_end"]!!.jsonPrimitive.content == "false") SManga.ONGOING else SManga.COMPLETED
-
- mangas.add(manga)
- }
-
- val lastPage = json.decodeFromString(body)["result"]!!.jsonObject["totalPageCnt"]!!.jsonPrimitive.content
- val currentPage = json.decodeFromString(body)["result"]!!.jsonObject["currentPageNo"]!!.jsonPrimitive.content
-
- return MangasPage(mangas, currentPage < lastPage)
- }
-
- override fun latestUpdatesRequest(page: Int): Request {
- val body = FormBody.Builder()
- .add("page", page.toString())
- .build()
-
- return POST("$baseUrl$urlModifier/updateList.nhn?order=update", headers, body)
- }
-
- override fun latestUpdatesParse(response: Response) = popularMangaParse(response)
-
- override fun searchMangaSelector() = "div#challengeList ul.list-article02__list li.list-article02__item a"
-
- override fun mangaDetailsParse(document: Document): SManga {
- val infoElement = document.select("div.article-hero03__inner")
-
- val manga = SManga.create()
- manga.title = infoElement.select("h1").text()
- manga.author = infoElement.select("p.article-hero03__author").text()
- manga.description = infoElement.select("div.article-hero03__description p").text()
- manga.thumbnail_url = infoElement.select("img").attr("src")
-
- return manga
- }
-
- override fun chapterListParse(response: Response): List {
- val chapters = mutableListOf()
-
- json.decodeFromString(response.body!!.string())["result"]!!
- .jsonObject["list"]!!
- .jsonArray
- .forEach {
- chapters.add(chapterFromJson(it.jsonObject))
- }
-
- return chapters.reversed()
- }
-
- override fun pageListParse(document: Document): List {
- val pages = mutableListOf()
-
- document.select("img.comic-image__image").forEachIndexed { i, img ->
- pages.add(Page(i, "", img.attr("src")))
- }
-
- return pages
- }
-}