diff --git a/src/en/animedao/AndroidManifest.xml b/src/en/animedao/AndroidManifest.xml
deleted file mode 100644
index 568741e54..000000000
--- a/src/en/animedao/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file
diff --git a/src/en/animedao/build.gradle b/src/en/animedao/build.gradle
deleted file mode 100644
index d0894af82..000000000
--- a/src/en/animedao/build.gradle
+++ /dev/null
@@ -1,22 +0,0 @@
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-apply plugin: 'kotlinx-serialization'
-
-ext {
- extName = 'AnimeDao'
- pkgNameSuffix = 'en.animedao'
- extClass = '.AnimeDao'
- extVersionCode = 13
- libVersion = '13'
-}
-
-dependencies {
- implementation(project(':lib-mixdrop-extractor'))
- implementation(project(':lib-mp4upload-extractor'))
- implementation(project(':lib-streamtape-extractor'))
- implementation(project(':lib-streamsb-extractor'))
- implementation(project(':lib-dood-extractor'))
-}
-
-
-apply from: "$rootDir/common.gradle"
diff --git a/src/en/animedao/res/mipmap-hdpi/ic_launcher.png b/src/en/animedao/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index 8984de5f5..000000000
Binary files a/src/en/animedao/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/src/en/animedao/res/mipmap-mdpi/ic_launcher.png b/src/en/animedao/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 17e3f9ee7..000000000
Binary files a/src/en/animedao/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/src/en/animedao/res/mipmap-xhdpi/ic_launcher.png b/src/en/animedao/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index e792a6905..000000000
Binary files a/src/en/animedao/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/en/animedao/res/mipmap-xxhdpi/ic_launcher.png b/src/en/animedao/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 09869e437..000000000
Binary files a/src/en/animedao/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/en/animedao/res/mipmap-xxxhdpi/ic_launcher.png b/src/en/animedao/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index 5a747f19e..000000000
Binary files a/src/en/animedao/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/en/animedao/res/web_hi_res_512.png b/src/en/animedao/res/web_hi_res_512.png
deleted file mode 100644
index 082b0b122..000000000
Binary files a/src/en/animedao/res/web_hi_res_512.png and /dev/null differ
diff --git a/src/en/animedao/src/eu/kanade/tachiyomi/animeextension/en/animedao/AnimeDao.kt b/src/en/animedao/src/eu/kanade/tachiyomi/animeextension/en/animedao/AnimeDao.kt
deleted file mode 100644
index 27d629393..000000000
--- a/src/en/animedao/src/eu/kanade/tachiyomi/animeextension/en/animedao/AnimeDao.kt
+++ /dev/null
@@ -1,404 +0,0 @@
-package eu.kanade.tachiyomi.animeextension.en.animedao
-
-import android.app.Application
-import android.content.SharedPreferences
-import androidx.preference.ListPreference
-import androidx.preference.PreferenceScreen
-import androidx.preference.SwitchPreferenceCompat
-import eu.kanade.tachiyomi.animeextension.en.animedao.extractors.VidstreamingExtractor
-import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
-import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
-import eu.kanade.tachiyomi.animesource.model.AnimesPage
-import eu.kanade.tachiyomi.animesource.model.SAnime
-import eu.kanade.tachiyomi.animesource.model.SEpisode
-import eu.kanade.tachiyomi.animesource.model.Video
-import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
-import eu.kanade.tachiyomi.lib.doodextractor.DoodExtractor
-import eu.kanade.tachiyomi.lib.mixdropextractor.MixDropExtractor
-import eu.kanade.tachiyomi.lib.mp4uploadextractor.Mp4uploadExtractor
-import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor
-import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
-import eu.kanade.tachiyomi.network.GET
-import eu.kanade.tachiyomi.network.asObservableSuccess
-import eu.kanade.tachiyomi.util.asJsoup
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.async
-import kotlinx.coroutines.awaitAll
-import kotlinx.coroutines.runBlocking
-import kotlinx.serialization.json.Json
-import okhttp3.HttpUrl.Companion.toHttpUrl
-import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import okhttp3.Response
-import org.jsoup.nodes.Document
-import org.jsoup.nodes.Element
-import rx.Observable
-import uy.kohesive.injekt.Injekt
-import uy.kohesive.injekt.api.get
-import uy.kohesive.injekt.injectLazy
-import java.text.SimpleDateFormat
-import java.util.Locale
-
-class AnimeDao : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
-
- override val name = "AnimeDao"
-
- override val baseUrl = "https://animedao.to"
-
- override val lang = "en"
-
- override val supportsLatest = true
-
- override val client: OkHttpClient = network.cloudflareClient
-
- private val json: Json by injectLazy()
-
- private val preferences: SharedPreferences by lazy {
- Injekt.get().getSharedPreferences("source_$id", 0x0000)
- }
-
- // ============================== Popular ===============================
-
- override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/animelist/popular")
-
- override fun popularAnimeSelector(): String = "div.container > div.row > div.col-md-6"
-
- override fun popularAnimeFromElement(element: Element): SAnime {
- val thumbnailUrl = element.selectFirst("img")!!.attr("data-src")
-
- return SAnime.create().apply {
- setUrlWithoutDomain(element.selectFirst("a")!!.attr("href"))
- thumbnail_url = if (thumbnailUrl.contains(baseUrl.toHttpUrl().host)) {
- thumbnailUrl
- } else {
- baseUrl + thumbnailUrl
- }
- title = element.selectFirst("span.animename")!!.text()
- }
- }
-
- override fun popularAnimeNextPageSelector(): String? = null
-
- // =============================== Latest ===============================
-
- override fun latestUpdatesRequest(page: Int): Request = GET(baseUrl)
-
- override fun latestUpdatesSelector(): String = "div#latest-tab-pane > div.row > div.col-md-6"
-
- override fun latestUpdatesFromElement(element: Element): SAnime {
- val thumbnailUrl = element.selectFirst("img")!!.attr("data-src")
-
- return SAnime.create().apply {
- setUrlWithoutDomain(element.selectFirst("a.animeparent")!!.attr("href"))
- thumbnail_url = if (thumbnailUrl.contains(baseUrl.toHttpUrl().host)) {
- thumbnailUrl
- } else {
- baseUrl + thumbnailUrl
- }
- title = element.selectFirst("span.animename")!!.text()
- }
- }
-
- override fun latestUpdatesNextPageSelector(): String? = popularAnimeNextPageSelector()
-
- // =============================== Search ===============================
-
- override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request = throw Exception("Not used")
-
- override fun fetchSearchAnime(page: Int, query: String, filters: AnimeFilterList): Observable {
- val params = AnimeDaoFilters.getSearchParameters(filters)
- return client.newCall(searchAnimeRequest(page, query, params))
- .asObservableSuccess()
- .map { response ->
- searchAnimeParse(response)
- }
- }
-
- private fun searchAnimeRequest(page: Int, query: String, filters: AnimeDaoFilters.FilterSearchParams): Request {
- return if (query.isNotBlank()) {
- val cleanQuery = query.replace(" ", "+")
- GET("$baseUrl/search/?search=$cleanQuery", headers = headers)
- } else {
- var url = "$baseUrl/animelist/".toHttpUrlOrNull()!!.newBuilder()
- .addQueryParameter("status[]=", filters.status)
- .addQueryParameter("order[]=", filters.order)
- .build().toString()
-
- if (filters.genre.isNotBlank()) url += "&${filters.genre}"
- if (filters.rating.isNotBlank()) url += "&${filters.rating}"
- if (filters.letter.isNotBlank()) url += "&${filters.letter}"
- if (filters.year.isNotBlank()) url += "&${filters.year}"
- if (filters.score.isNotBlank()) url += "&${filters.score}"
- url += "&page=$page"
-
- GET(url, headers = headers)
- }
- }
-
- override fun searchAnimeParse(response: Response): AnimesPage {
- val document = response.asJsoup()
- val selector = if (response.request.url.encodedPath.startsWith("/animelist/")) {
- searchAnimeSelectorFilter()
- } else {
- searchAnimeSelector()
- }
-
- val animes = document.select(selector).map { element ->
- searchAnimeFromElement(element)
- }
-
- val hasNextPage = searchAnimeNextPageSelector().let { selector ->
- document.select(selector).first()
- } != null
-
- return AnimesPage(animes, hasNextPage)
- }
-
- override fun searchAnimeSelector(): String = popularAnimeSelector()
-
- override fun searchAnimeFromElement(element: Element): SAnime = popularAnimeFromElement(element)
-
- private fun searchAnimeSelectorFilter(): String = "div.container div.col-12 > div.row > div.col-md-6"
-
- override fun searchAnimeNextPageSelector(): String = "ul.pagination > li.page-item:has(i.fa-arrow-right):not(.disabled)"
-
- // ============================== FILTERS ===============================
-
- override fun getFilterList(): AnimeFilterList = AnimeDaoFilters.FILTER_LIST
-
- // =========================== Anime Details ============================
-
- override fun animeDetailsParse(document: Document): SAnime {
- val thumbnailUrl = document.selectFirst("div.card-body img")!!.attr("data-src")
- val moreInfo = document.select("div.card-body table > tbody > tr").joinToString("\n") { it.text() }
-
- return SAnime.create().apply {
- title = document.selectFirst("div.card-body h2")!!.text()
- thumbnail_url = if (thumbnailUrl.contains(baseUrl.toHttpUrl().host)) {
- thumbnailUrl
- } else {
- baseUrl + thumbnailUrl
- }
- status = document.selectFirst("div.card-body table > tbody > tr:has(>td:contains(Status)) td:not(:contains(Status))")?.let {
- parseStatus(it.text())
- } ?: SAnime.UNKNOWN
- description = (document.selectFirst("div.card-body div:has(>b:contains(Description))")?.ownText() ?: "") + "\n\n$moreInfo"
- genre = document.select("div.card-body table > tbody > tr:has(>td:contains(Genres)) td > a").joinToString(", ") { it.text() }
- }
- }
-
- // ============================== Episodes ==============================
-
- override fun episodeListParse(response: Response): List {
- return if (preferences.getBoolean(PREF_EPISODE_SORT_KEY, PREF_EPISODE_SORT_DEFAULT)) {
- super.episodeListParse(response).sortedWith(
- compareBy(
- { it.episode_number },
- { it.name },
- ),
- ).reversed()
- } else {
- super.episodeListParse(response)
- }
- }
-
- override fun episodeListSelector(): String = "div#episodes-tab-pane > div.row > div > div.card"
-
- override fun episodeFromElement(element: Element): SEpisode {
- val episodeName = element.selectFirst("span.animename")!!.text()
- val episodeTitle = element.selectFirst("div.animetitle")?.text() ?: ""
-
- return SEpisode.create().apply {
- name = "$episodeName $episodeTitle"
- episode_number = if (episodeName.contains("Episode ", true)) {
- episodeName.substringAfter("Episode ").substringBefore(" ").toFloatOrNull() ?: 0F
- } else { 0F }
- if (element.selectFirst("span.filler") != null && preferences.getBoolean(PREF_MARK_FILLERS_KEY, PREF_MARK_FILLERS_DEFAULT)) {
- scanlator = "Filler Episode"
- }
- date_upload = element.selectFirst("span.date")?.let { parseDate(it.text()) } ?: 0L
- setUrlWithoutDomain(element.selectFirst("a[href]")!!.attr("href"))
- }
- }
-
- // ============================ Video Links =============================
-
- override fun videoListParse(response: Response): List