diff --git a/multisrc/overrides/grouple/allhentai/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/grouple/allhentai/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..d7626a6f9
Binary files /dev/null and b/multisrc/overrides/grouple/allhentai/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/allhentai/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/grouple/allhentai/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..016fbc954
Binary files /dev/null and b/multisrc/overrides/grouple/allhentai/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/allhentai/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/grouple/allhentai/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..d2d35dd5b
Binary files /dev/null and b/multisrc/overrides/grouple/allhentai/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/allhentai/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/grouple/allhentai/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..ff4efdd56
Binary files /dev/null and b/multisrc/overrides/grouple/allhentai/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/allhentai/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/grouple/allhentai/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..541d18e42
Binary files /dev/null and b/multisrc/overrides/grouple/allhentai/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/allhentai/res/web_hi_res_512.png b/multisrc/overrides/grouple/allhentai/res/web_hi_res_512.png
new file mode 100644
index 000000000..f73d9a578
Binary files /dev/null and b/multisrc/overrides/grouple/allhentai/res/web_hi_res_512.png differ
diff --git a/multisrc/overrides/grouple/allhentai/src/AllHentai.kt b/multisrc/overrides/grouple/allhentai/src/AllHentai.kt
new file mode 100644
index 000000000..2217b9217
--- /dev/null
+++ b/multisrc/overrides/grouple/allhentai/src/AllHentai.kt
@@ -0,0 +1,259 @@
+package eu.kanade.tachiyomi.extension.ru.allhentai
+
+import eu.kanade.tachiyomi.multisrc.grouple.GroupLe
+import eu.kanade.tachiyomi.network.GET
+import eu.kanade.tachiyomi.source.model.Filter
+import eu.kanade.tachiyomi.source.model.FilterList
+import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
+import okhttp3.Request
+
+class AllHentai : GroupLe("AllHentai", "http://23.allhen.online", "ru"){
+
+    override val id: Long = 1809051393403180443
+
+    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
+        val url = "$baseUrl/search/advanced".toHttpUrlOrNull()!!.newBuilder()
+        (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
+            when (filter) {
+                is GenreList -> filter.state.forEach { genre ->
+                    if (genre.state != Filter.TriState.STATE_IGNORE) {
+                        url.addQueryParameter(genre.id, arrayOf("=", "=in", "=ex")[genre.state])
+                    }
+                }
+                is Category -> filter.state.forEach { category ->
+                    if (category.state != Filter.TriState.STATE_IGNORE) {
+                        url.addQueryParameter(category.id, arrayOf("=", "=in", "=ex")[category.state])
+                    }
+                }
+                is FilList -> filter.state.forEach { fils ->
+                    if (fils.state != Filter.TriState.STATE_IGNORE) {
+                        url.addQueryParameter(fils.id, arrayOf("=", "=in", "=ex")[fils.state])
+                    }
+                }
+                is OrderBy -> {
+                    if (filter.state > 0) {
+                        val ord = arrayOf("not", "year", "rate", "popularity", "votes", "created", "updated")[filter.state]
+                        val ordUrl = "$baseUrl/list?sortType=$ord&offset=${70 * (page - 1)}".toHttpUrlOrNull()!!.newBuilder()
+                        return GET(ordUrl.toString(), headers)
+                    }
+                }
+                is Tags -> {
+                    if (filter.state > 0) {
+                        val tagName = getTagsList()[filter.state].url
+                        val tagUrl = "$baseUrl/list/tag/$tagName?offset=${70 * (page - 1)}".toHttpUrlOrNull()!!.newBuilder()
+                        return GET(tagUrl.toString(), headers)
+                    }
+                }
+                else -> return@forEach
+            }
+        }
+        if (query.isNotEmpty()) {
+            url.addQueryParameter("q", query)
+        }
+        return if (url.toString().contains("?"))
+            GET(url.toString().replace("=%3D", "="), headers)
+        else  popularMangaRequest(page)
+    }
+
+    private class OrderBy : Filter.Select<String>(
+        "Сортировка (только)",
+        arrayOf("Без сортировки", "По году", "По популярности", "Популярно сейчас", "По рейтингу", "Новинки", "По дате обновления")
+    )
+
+    private class Genre(name: String, val id: String) : Filter.TriState(name)
+
+    private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Жанры", genres)
+    private class Category(categories: List<Genre>) : Filter.Group<Genre>("Категории", categories)
+    private class FilList(fils: List<Genre>) : Filter.Group<Genre>("Фильтры", fils)
+    private class Tags(tags: Array<String>) : Filter.Select<String>("Тэг (только)", tags)
+
+    private data class Tag(val name: String, val url: String)
+
+    override fun getFilterList() = FilterList(
+        OrderBy(),
+        Tags(tagsName),
+        GenreList(getGenreList()),
+        Category(getCategoryList()),
+        FilList(getFilList())
+    )
+
+    private fun getGenreList() = listOf(
+        Genre("ahegao", "el_855"),
+        Genre("анал", "el_828"),
+        Genre("бдсм", "el_78"),
+        Genre("без цензуры", "el_888"),
+        Genre("большая грудь", "el_837"),
+        Genre("большая попка", "el_3156"),
+        Genre("большой член", "el_884"),
+        Genre("бондаж", "el_5754"),
+        Genre("в первый раз", "el_811"),
+        Genre("в цвете", "el_290"),
+        Genre("гарем", "el_87"),
+        Genre("гендарная интрига", "el_89"),
+        Genre("групповой секс", "el_88"),
+        Genre("драма", "el_95"),
+        Genre("зрелые женщины", "el_5679"),
+        Genre("измена", "el_291"),
+        Genre("изнасилование", "el_124"),
+        Genre("инцест", "el_85"),
+        Genre("исторический", "el_93"),
+        Genre("комедия", "el_73"),
+        Genre("маленькая грудь", "el_870"),
+        Genre("научная фантастика", "el_76"),
+        Genre("нетораре", "el_303"),
+        Genre("оральный секс", "el_853"),
+        Genre("романтика", "el_74"),
+        Genre("тентакли", "el_69"),
+        Genre("трагедия", "el_1321"),
+        Genre("ужасы", "el_75"),
+        Genre("футанари", "el_77"),
+        Genre("фэнтези", "el_70"),
+        Genre("чикан", "el_1059"),
+        Genre("этти", "el_798"),
+        Genre("юри", "el_84"),
+        Genre("яой", "el_83")
+    )
+
+    private fun getCategoryList() = listOf(
+        Genre("3D", "el_626"),
+        Genre("Анимация", "el_5777"),
+        Genre("Без текста", "el_3157"),
+        Genre("Порно комикс", "el_1003"),
+        Genre("Порно манхва", "el_1104")
+    )
+
+    private fun getFilList() = listOf(
+        Genre("Высокий рейтинг", "s_high_rate"),
+        Genre("Сингл", "s_single"),
+        Genre("Для взрослых", "s_mature"),
+        Genre("Завершенная", "s_completed"),
+        Genre("Переведено", "s_translated"),
+        Genre("Длинная", "s_many_chapters"),
+        Genre("Ожидает загрузки", "s_wait_upload"),
+        Genre("Продается", "s_sale")
+    )
+
+    private fun getTagsList() = listOf(
+        Tag("Без тега", "not"),
+        Tag("handjob", "handjob"),
+        Tag("inseki", "inseki"),
+        Tag("алкоголь", "alcohol"),
+        Tag("андроид", "android"),
+        Tag("анилингус", "anilingus"),
+        Tag("бассейн", "pool"),
+        Tag("без трусиков", "without_panties"),
+        Tag("беременность", "pregnancy"),
+        Tag("бикини", "bikini"),
+        Tag("близнецы", "twins"),
+        Tag("боди-арт", "body_art"),
+        Tag("больница", "hospital"),
+        Tag("буккакэ", "bukkake"),
+        Tag("в ванной", "in_bathroom"),
+        Tag("в общественном месте", "in_public_place"),
+        Tag("в транспорте", "in_vehicle"),
+        Tag("вампиры", "vampires"),
+        Tag("вибратор", "vibrator"),
+        Tag("втянутые соски", "inverted_nipples"),
+        Tag("гипноз", "hypnosis"),
+        Tag("глубокий минет", "deepthroat"),
+        Tag("горничные", "maids"),
+        Tag("горячий источник", "hot_spring"),
+        Tag("гэнгбэнг", "gangbang"),
+        Tag("гяру", "gyaru"),
+        Tag("двойное проникновение", "double_penetration"),
+        Tag("Девочки волшебницы", "magical_girl"),
+        Tag("демоны", "demons"),
+        Tag("дефекация", "scat"),
+        Tag("дилдо", "dildo"),
+        Tag("додзинси", "doujinshi"),
+        Tag("домохозяйки", "housewives"),
+        Tag("дыра в стене", "hole_in_the_wall"),
+        Tag("жестокость", "cruelty"),
+        Tag("загар", "tan_lines"),
+        Tag("зомби", "zombie"),
+        Tag("инопланетяне", "aliens"),
+        Tag("исполнение желаний", "granting_wish"),
+        Tag("камера", "camera"),
+        Tag("косплей", "cosplay"),
+        Tag("кремпай", "creampie"),
+        Tag("куннилингус", "cunnilingus"),
+        Tag("купальник", "swimsuit"),
+        Tag("лактация", "lactation"),
+        Tag("латекс и кожа", "latex"),
+        Tag("Ломка Психики", "mind_break"),
+        Tag("магия", "magic"),
+        Tag("мастурбация", "masturbation"),
+        Tag("медсестра", "nurse"),
+        Tag("мерзкий дядька", "terrible_oyaji"),
+        Tag("много девушек", "many_girls"),
+        Tag("много спермы", "a_lot_of_sperm"),
+        Tag("монстрдевушки", "monstergirl"),
+        Tag("монстры", "monsters"),
+        Tag("мужчина крепкого телосложения", "muscle_man"),
+        Tag("на природе", "outside"),
+        Tag("не бритая киска", "hairy_pussy"),
+        Tag("не бритые подмышки", "hairy_armpits"),
+        Tag("нетори", "netori"),
+        Tag("нижнее бельё", "lingerie"),
+        Tag("обмен партнерами", "swinging"),
+        Tag("обмен телами", "body_swap"),
+        Tag("обычный секс", "normal_sex"),
+        Tag("огромная грудь", "super_big_boobs"),
+        Tag("орки", "orcs"),
+        Tag("очки", "megane"),
+        Tag("пайзури", "titsfuck"),
+        Tag("парень пассив", "passive_guy"),
+        Tag("пацанка", "tomboy"),
+        Tag("пеггинг", "pegging"),
+        Tag("переодевание", "disguise"),
+        Tag("пирсинг", "piercing"),
+        Tag("писают", "peeing"),
+        Tag("пляж", "beach"),
+        Tag("повседневность", "slice_of_life"),
+        Tag("повязка на глаза", "blindfold"),
+        Tag("подглядывание", "peeping"),
+        Tag("подчинение", "submission"),
+        Tag("похищение", "kidnapping"),
+        Tag("принуждение", "forced"),
+        Tag("прозрачная одежда", "transparent_clothes"),
+        Tag("проституция", "prostitution"),
+        Tag("психические отклонения", "mental_illness"),
+        Tag("публичный секс", "public_sex"),
+        Tag("пьяные", "drunk"),
+        Tag("рабы", "slaves"),
+        Tag("рентген зрение", "x_ray"),
+        Tag("сверхъестественное", "supernatural"),
+        Tag("секс втроем", "threesome"),
+        Tag("секс игрушки", "sex_toys"),
+        Tag("сексуально возбужденная", "horny"),
+        Tag("спортивная форма", "sports_uniform"),
+        Tag("спящие", "sleeping"),
+        Tag("страпон", "strapon"),
+        Tag("Суккуб", "succubus"),
+        Tag("темнокожие", "dark_skin"),
+        Tag("толстушки", "fatties"),
+        Tag("трап", "trap"),
+        Tag("униформа", "uniform"),
+        Tag("ушастые", "eared"),
+        Tag("фантазии", "dreams"),
+        Tag("фемдом", "femdom"),
+        Tag("фестиваль", "festival"),
+        Tag("фетиш", "fetish"),
+        Tag("фистинг", "fisting"),
+        Tag("фурри", "furry"),
+        Tag("футанари имеет парня", "futanari_on_boy"),
+        Tag("футджаб", "footfuck"),
+        Tag("цельный купальник", "full_swimsuit"),
+        Tag("цундэрэ", "tsundere"),
+        Tag("чулки", "hose"),
+        Tag("шалава", "slut"),
+        Tag("шантаж", "blackmail"),
+        Tag("эксгибиционизм", "exhibitionism"),
+        Tag("эльфы", "elves"),
+        Tag("яндере", "yandere")
+    )
+
+    private val tagsName = getTagsList().map {
+        it.name
+    }.toTypedArray()
+}
diff --git a/src/ru/mintmanga/AndroidManifest.xml b/multisrc/overrides/grouple/default/AndroidManifest.xml
similarity index 74%
rename from src/ru/mintmanga/AndroidManifest.xml
rename to multisrc/overrides/grouple/default/AndroidManifest.xml
index 79da42000..87f96afd9 100644
--- a/src/ru/mintmanga/AndroidManifest.xml
+++ b/multisrc/overrides/grouple/default/AndroidManifest.xml
@@ -4,7 +4,7 @@
 
     <application>
         <activity
-            android:name=".ru.mintmanga.MintmangaActivity"
+            android:name="eu.kanade.tachiyomi.multisrc.grouple.GroupLeUrlActivity"
             android:excludeFromRecents="true"
             android:exported="true"
             android:theme="@android:style/Theme.NoDisplay">
@@ -14,11 +14,11 @@
                 <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="android.intent.category.BROWSABLE" />
 
-                <!-- ReadmangaActivity sites can be added here. -->
+                <!-- GroupLeUrlActivity sites can be added here. -->
                 <data
-                    android:host="mintmanga.live"
+                    android:host="${SOURCEHOST}"
                     android:pathPattern="/..*/vol..*"
-                    android:scheme="https" />
+                    android:scheme="${SOURCESCHEME}" />
             </intent-filter>
         </activity>
     </application>
diff --git a/multisrc/overrides/grouple/mintmanga/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/grouple/mintmanga/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..cbc0d3927
Binary files /dev/null and b/multisrc/overrides/grouple/mintmanga/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/mintmanga/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/grouple/mintmanga/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..b7a7d167e
Binary files /dev/null and b/multisrc/overrides/grouple/mintmanga/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/mintmanga/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/grouple/mintmanga/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..cdc090f10
Binary files /dev/null and b/multisrc/overrides/grouple/mintmanga/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/mintmanga/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/grouple/mintmanga/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..626bfc7d1
Binary files /dev/null and b/multisrc/overrides/grouple/mintmanga/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/mintmanga/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/grouple/mintmanga/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..56bc00e18
Binary files /dev/null and b/multisrc/overrides/grouple/mintmanga/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/mintmanga/res/web_hi_res_512.png b/multisrc/overrides/grouple/mintmanga/res/web_hi_res_512.png
new file mode 100644
index 000000000..659735502
Binary files /dev/null and b/multisrc/overrides/grouple/mintmanga/res/web_hi_res_512.png differ
diff --git a/multisrc/overrides/grouple/mintmanga/src/MintManga.kt b/multisrc/overrides/grouple/mintmanga/src/MintManga.kt
new file mode 100644
index 000000000..56f492561
--- /dev/null
+++ b/multisrc/overrides/grouple/mintmanga/src/MintManga.kt
@@ -0,0 +1,157 @@
+package eu.kanade.tachiyomi.extension.ru.mintmanga
+
+import eu.kanade.tachiyomi.multisrc.grouple.GroupLe
+import eu.kanade.tachiyomi.network.GET
+import eu.kanade.tachiyomi.source.model.Filter
+import eu.kanade.tachiyomi.source.model.FilterList
+import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
+import okhttp3.Request
+
+class MintManga : GroupLe("MintManga", "https://mintmanga.live", "ru"){
+
+    override val id: Long = 6
+
+    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
+        val url = "$baseUrl/search/advanced".toHttpUrlOrNull()!!.newBuilder()
+        (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
+            when (filter) {
+                is GenreList -> filter.state.forEach { genre ->
+                    if (genre.state != Filter.TriState.STATE_IGNORE) {
+                        url.addQueryParameter(genre.id, arrayOf("=", "=in", "=ex")[genre.state])
+                    }
+                }
+                is Category -> filter.state.forEach { category ->
+                    if (category.state != Filter.TriState.STATE_IGNORE) {
+                        url.addQueryParameter(category.id, arrayOf("=", "=in", "=ex")[category.state])
+                    }
+                }
+                is AgeList -> filter.state.forEach { age ->
+                    if (age.state != Filter.TriState.STATE_IGNORE) {
+                        url.addQueryParameter(age.id, arrayOf("=", "=in", "=ex")[age.state])
+                    }
+                }
+                is More -> filter.state.forEach { more ->
+                    if (more.state != Filter.TriState.STATE_IGNORE) {
+                        url.addQueryParameter(more.id, arrayOf("=", "=in", "=ex")[more.state])
+                    }
+                }
+                is FilList -> filter.state.forEach { fils ->
+                    if (fils.state != Filter.TriState.STATE_IGNORE) {
+                        url.addQueryParameter(fils.id, arrayOf("=", "=in", "=ex")[fils.state])
+                    }
+                }
+                is OrderBy -> {
+                    if (filter.state > 0) {
+                        val ord = arrayOf("not", "year", "rate", "popularity", "votes", "created", "updated")[filter.state]
+                        val ordUrl = "$baseUrl/list?sortType=$ord&offset=${70 * (page - 1)}".toHttpUrlOrNull()!!.newBuilder()
+                        return GET(ordUrl.toString(), headers)
+                    }
+                }
+                else -> return@forEach
+            }
+        }
+        if (query.isNotEmpty()) {
+            url.addQueryParameter("q", query)
+        }
+        return if (url.toString().contains("?"))
+            GET(url.toString().replace("=%3D", "="), headers)
+        else  popularMangaRequest(page)
+    }
+
+    private class OrderBy : Filter.Select<String>(
+        "Сортировка (только)",
+        arrayOf("Без сортировки", "По году", "По популярности", "Популярно сейчас", "По рейтингу", "Новинки", "По дате обновления")
+    )
+
+    private class Genre(name: String, val id: String) : Filter.TriState(name)
+
+    private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Жанры", genres)
+    private class Category(categories: List<Genre>) : Filter.Group<Genre>("Категории", categories)
+    private class AgeList(ages: List<Genre>) : Filter.Group<Genre>("Возрастная рекомендация", ages)
+    private class More(moren: List<Genre>) : Filter.Group<Genre>("Прочее", moren)
+    private class FilList(fils: List<Genre>) : Filter.Group<Genre>("Фильтры", fils)
+
+    override fun getFilterList() = FilterList(
+        OrderBy(),
+        Category(getCategoryList()),
+        GenreList(getGenreList()),
+        AgeList(getAgeList()),
+        More(getMore()),
+        FilList(getFilList())
+    )
+    private fun getFilList() = listOf(
+        Genre("Высокий рейтинг", "s_high_rate"),
+        Genre("Сингл", "s_single"),
+        Genre("Для взрослых", "s_mature"),
+        Genre("Завершенная", "s_completed"),
+        Genre("Переведено", "s_translated"),
+        Genre("Длинная", "s_many_chapters"),
+        Genre("Ожидает загрузки", "s_wait_upload"),
+    )
+    private fun getMore() = listOf(
+        Genre("В цвете", "el_4614"),
+        Genre("Веб", "el_1355"),
+        Genre("Выпуск приостановлен", "el_5232"),
+        Genre("Не Яой", "el_1874"),
+        Genre("Сборник", "el_1348")
+    )
+
+    private fun getAgeList() = listOf(
+        Genre("R(16+)", "el_3968"),
+        Genre("NC-17(18+)", "el_3969"),
+        Genre("R18+(18+)", "el_3990")
+    )
+
+    private fun getCategoryList() = listOf(
+        Genre("Ёнкома", "el_2741"),
+        Genre("Комикс западный", "el_1903"),
+        Genre("Комикс русский", "el_2173"),
+        Genre("Манхва", "el_1873"),
+        Genre("Маньхуа", "el_1875"),
+        Genre("Ранобэ", "el_5688"),
+    )
+
+    private fun getGenreList() = listOf(
+        Genre("арт", "el_2220"),
+        Genre("бара", "el_1353"),
+        Genre("боевик", "el_1346"),
+        Genre("боевые искусства", "el_1334"),
+        Genre("вампиры", "el_1339"),
+        Genre("гарем", "el_1333"),
+        Genre("гендерная интрига", "el_1347"),
+        Genre("героическое фэнтези", "el_1337"),
+        Genre("детектив", "el_1343"),
+        Genre("дзёсэй", "el_1349"),
+        Genre("додзинси", "el_1332"),
+        Genre("драма", "el_1310"),
+        Genre("игра", "el_5229"),
+        Genre("история", "el_1311"),
+        Genre("киберпанк", "el_1351"),
+        Genre("комедия", "el_1328"),
+        Genre("меха", "el_1318"),
+        Genre("научная фантастика", "el_1325"),
+        Genre("омегаверс", "el_5676"),
+        Genre("повседневность", "el_1327"),
+        Genre("постапокалиптика", "el_1342"),
+        Genre("приключения", "el_1322"),
+        Genre("психология", "el_1335"),
+        Genre("романтика", "el_1313"),
+        Genre("самурайский боевик", "el_1316"),
+        Genre("сверхъестественное", "el_1350"),
+        Genre("сёдзё", "el_1314"),
+        Genre("сёдзё-ай", "el_1320"),
+        Genre("сёнэн", "el_1326"),
+        Genre("сёнэн-ай", "el_1330"),
+        Genre("спорт", "el_1321"),
+        Genre("сэйнэн", "el_1329"),
+        Genre("трагедия", "el_1344"),
+        Genre("триллер", "el_1341"),
+        Genre("ужасы", "el_1317"),
+        Genre("фэнтези", "el_1323"),
+        Genre("школа", "el_1319"),
+        Genre("эротика", "el_1340"),
+        Genre("этти", "el_1354"),
+        Genre("юри", "el_1315"),
+        Genre("яой", "el_1336")
+    )
+}
diff --git a/multisrc/overrides/grouple/readmanga/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/grouple/readmanga/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..3a287acfc
Binary files /dev/null and b/multisrc/overrides/grouple/readmanga/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/readmanga/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/grouple/readmanga/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..8ebcb6940
Binary files /dev/null and b/multisrc/overrides/grouple/readmanga/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/readmanga/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/grouple/readmanga/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..51af633ab
Binary files /dev/null and b/multisrc/overrides/grouple/readmanga/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/readmanga/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/grouple/readmanga/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..37d39ba2e
Binary files /dev/null and b/multisrc/overrides/grouple/readmanga/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/readmanga/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/grouple/readmanga/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..88764f0bb
Binary files /dev/null and b/multisrc/overrides/grouple/readmanga/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/readmanga/res/web_hi_res_512.png b/multisrc/overrides/grouple/readmanga/res/web_hi_res_512.png
new file mode 100644
index 000000000..a2cba1ddc
Binary files /dev/null and b/multisrc/overrides/grouple/readmanga/res/web_hi_res_512.png differ
diff --git a/multisrc/overrides/grouple/readmanga/src/ReadManga.kt b/multisrc/overrides/grouple/readmanga/src/ReadManga.kt
new file mode 100644
index 000000000..0e622a559
--- /dev/null
+++ b/multisrc/overrides/grouple/readmanga/src/ReadManga.kt
@@ -0,0 +1,156 @@
+package eu.kanade.tachiyomi.extension.ru.readmanga
+
+import android.widget.Toast
+import eu.kanade.tachiyomi.multisrc.grouple.GroupLe
+import eu.kanade.tachiyomi.network.GET
+import eu.kanade.tachiyomi.source.model.Filter
+import eu.kanade.tachiyomi.source.model.FilterList
+import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
+import okhttp3.Request
+
+class ReadManga : GroupLe("ReadManga", "https://readmanga.io", "ru"){
+
+    override val id: Long = 5
+
+    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
+        val url = "$baseUrl/search/advanced".toHttpUrlOrNull()!!.newBuilder()
+        (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
+            when (filter) {
+                is GenreList -> filter.state.forEach { genre ->
+                    if (genre.state != Filter.TriState.STATE_IGNORE) {
+                        url.addQueryParameter(genre.id, arrayOf("=", "=in", "=ex")[genre.state])
+                    }
+                }
+                is Category -> filter.state.forEach { category ->
+                    if (category.state != Filter.TriState.STATE_IGNORE) {
+                        url.addQueryParameter(category.id, arrayOf("=", "=in", "=ex")[category.state])
+                    }
+                }
+                is AgeList -> filter.state.forEach { age ->
+                    if (age.state != Filter.TriState.STATE_IGNORE) {
+                        url.addQueryParameter(age.id, arrayOf("=", "=in", "=ex")[age.state])
+                    }
+                }
+                is More -> filter.state.forEach { more ->
+                    if (more.state != Filter.TriState.STATE_IGNORE) {
+                        url.addQueryParameter(more.id, arrayOf("=", "=in", "=ex")[more.state])
+                    }
+                }
+                is FilList -> filter.state.forEach { fils ->
+                    if (fils.state != Filter.TriState.STATE_IGNORE) {
+                        url.addQueryParameter(fils.id, arrayOf("=", "=in", "=ex")[fils.state])
+                    }
+                }
+                is OrderBy -> {
+                    if (filter.state > 0) {
+                        val ord = arrayOf("not", "year", "rate", "popularity", "votes", "created", "updated")[filter.state]
+                        val ordUrl = "$baseUrl/list?sortType=$ord&offset=${70 * (page - 1)}".toHttpUrlOrNull()!!.newBuilder()
+                        return GET(ordUrl.toString(), headers)
+                    }
+                }
+                else -> return@forEach
+            }
+        }
+        if (query.isNotEmpty()) {
+            url.addQueryParameter("q", query)
+        }
+        return if (url.toString().contains("?"))
+            GET(url.toString().replace("=%3D", "="), headers)
+        else  popularMangaRequest(page)
+    }
+
+    private class OrderBy : Filter.Select<String>(
+        "Сортировка (только)",
+        arrayOf("Без сортировки", "По году", "По популярности", "Популярно сейчас", "По рейтингу", "Новинки", "По дате обновления")
+    )
+
+    private class Genre(name: String, val id: String) : Filter.TriState(name)
+
+    private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Жанры", genres)
+    private class Category(categories: List<Genre>) : Filter.Group<Genre>("Категории", categories)
+    private class AgeList(ages: List<Genre>) : Filter.Group<Genre>("Возрастная рекомендация", ages)
+    private class More(moren: List<Genre>) : Filter.Group<Genre>("Прочее", moren)
+    private class FilList(fils: List<Genre>) : Filter.Group<Genre>("Фильтры", fils)
+
+    override fun getFilterList() = FilterList(
+        OrderBy(),
+        Category(getCategoryList()),
+        GenreList(getGenreList()),
+        AgeList(getAgeList()),
+        More(getMore()),
+        FilList(getFilList())
+    )
+
+    private fun getFilList() = listOf(
+        Genre("Высокий рейтинг", "s_high_rate"),
+        Genre("Сингл", "s_single"),
+        Genre("Для взрослых", "s_mature"),
+        Genre("Завершенная", "s_completed"),
+        Genre("Переведено", "s_translated"),
+        Genre("Длинная", "s_many_chapters"),
+        Genre("Ожидает загрузки", "s_wait_upload"),
+        Genre("Продается", "s_sale")
+    )
+    private fun getMore() = listOf(
+        Genre("В цвете", "el_7290"),
+        Genre("Веб", "el_2160"),
+        Genre("Выпуск приостановлен", "el_8033"),
+        Genre("Сборник", "el_2157")
+    )
+
+    private fun getAgeList() = listOf(
+        Genre("G(0+)", "el_6180"),
+        Genre("PG-13(12+)", "el_6181"),
+        Genre("PG(16+)", "el_6179")
+    )
+
+    private fun getCategoryList() = listOf(
+        Genre("Ёнкома", "el_2161"),
+        Genre("Комикс западный", "el_3515"),
+        Genre("Манхва", "el_3001"),
+        Genre("Маньхуа", "el_3002"),
+        Genre("Ранобэ", "el_8575"),
+    )
+
+    private fun getGenreList() = listOf(
+        Genre("арт", "el_5685"),
+        Genre("боевик", "el_2155"),
+        Genre("боевые искусства", "el_2143"),
+        Genre("вампиры", "el_2148"),
+        Genre("гарем", "el_2142"),
+        Genre("гендерная интрига", "el_2156"),
+        Genre("героическое фэнтези", "el_2146"),
+        Genre("детектив", "el_2152"),
+        Genre("дзёсэй", "el_2158"),
+        Genre("додзинси", "el_2141"),
+        Genre("драма", "el_2118"),
+        Genre("игра", "el_2154"),
+        Genre("история", "el_2119"),
+        Genre("киберпанк", "el_8032"),
+        Genre("кодомо", "el_2137"),
+        Genre("комедия", "el_2136"),
+        Genre("махо-сёдзё", "el_2147"),
+        Genre("меха", "el_2126"),
+        Genre("научная фантастика", "el_2133"),
+        Genre("повседневность", "el_2135"),
+        Genre("постапокалиптика", "el_2151"),
+        Genre("приключения", "el_2130"),
+        Genre("психология", "el_2144"),
+        Genre("романтика", "el_2121"),
+        Genre("самурайский боевик", "el_2124"),
+        Genre("сверхъестественное", "el_2159"),
+        Genre("сёдзё", "el_2122"),
+        Genre("сёдзё-ай", "el_2128"),
+        Genre("сёнэн", "el_2134"),
+        Genre("сёнэн-ай", "el_2139"),
+        Genre("спорт", "el_2129"),
+        Genre("сэйнэн", "el_2138"),
+        Genre("трагедия", "el_2153"),
+        Genre("триллер", "el_2150"),
+        Genre("ужасы", "el_2125"),
+        Genre("фэнтези", "el_2131"),
+        Genre("школа", "el_2127"),
+        Genre("этти", "el_2149"),
+        Genre("юри", "el_2123")
+    )
+}
diff --git a/multisrc/overrides/grouple/rumix/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/grouple/rumix/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..26dea9c1c
Binary files /dev/null and b/multisrc/overrides/grouple/rumix/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/rumix/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/grouple/rumix/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..1b214efa4
Binary files /dev/null and b/multisrc/overrides/grouple/rumix/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/rumix/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/grouple/rumix/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..73a45df39
Binary files /dev/null and b/multisrc/overrides/grouple/rumix/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/rumix/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/grouple/rumix/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..dc8aaaf40
Binary files /dev/null and b/multisrc/overrides/grouple/rumix/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/rumix/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/grouple/rumix/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..2d263c880
Binary files /dev/null and b/multisrc/overrides/grouple/rumix/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/rumix/res/web_hi_res_512.png b/multisrc/overrides/grouple/rumix/res/web_hi_res_512.png
new file mode 100644
index 000000000..87cb89581
Binary files /dev/null and b/multisrc/overrides/grouple/rumix/res/web_hi_res_512.png differ
diff --git a/multisrc/overrides/grouple/rumix/src/RuMIX.kt b/multisrc/overrides/grouple/rumix/src/RuMIX.kt
new file mode 100644
index 000000000..26b7e355f
--- /dev/null
+++ b/multisrc/overrides/grouple/rumix/src/RuMIX.kt
@@ -0,0 +1,23 @@
+package eu.kanade.tachiyomi.extension.ru.rumix
+
+import android.widget.Toast
+import eu.kanade.tachiyomi.multisrc.grouple.GroupLe
+import eu.kanade.tachiyomi.network.GET
+import eu.kanade.tachiyomi.source.model.Filter
+import eu.kanade.tachiyomi.source.model.FilterList
+import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
+import okhttp3.Request
+
+class RuMIX : GroupLe("RuMIX", "https://rumix.me", "ru"){
+
+    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
+        val url = "$baseUrl/search/advanced".toHttpUrlOrNull()!!.newBuilder()
+        if (query.isNotEmpty()) {
+            url.addQueryParameter("q", query)
+        }
+        return if (url.toString().contains("?"))
+            GET(url.toString().replace("=%3D", "="), headers)
+        else  popularMangaRequest(page)
+    }
+
+}
diff --git a/multisrc/overrides/grouple/selfmanga/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/grouple/selfmanga/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..43778af35
Binary files /dev/null and b/multisrc/overrides/grouple/selfmanga/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/selfmanga/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/grouple/selfmanga/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..7d991c0ad
Binary files /dev/null and b/multisrc/overrides/grouple/selfmanga/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/selfmanga/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/grouple/selfmanga/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..b4ea98529
Binary files /dev/null and b/multisrc/overrides/grouple/selfmanga/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/selfmanga/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/grouple/selfmanga/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..54fea1b05
Binary files /dev/null and b/multisrc/overrides/grouple/selfmanga/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/selfmanga/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/grouple/selfmanga/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..a7f0a9e56
Binary files /dev/null and b/multisrc/overrides/grouple/selfmanga/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/grouple/selfmanga/res/web_hi_res_512.png b/multisrc/overrides/grouple/selfmanga/res/web_hi_res_512.png
new file mode 100644
index 000000000..85a865456
Binary files /dev/null and b/multisrc/overrides/grouple/selfmanga/res/web_hi_res_512.png differ
diff --git a/multisrc/overrides/grouple/selfmanga/src/SelfManga.kt b/multisrc/overrides/grouple/selfmanga/src/SelfManga.kt
new file mode 100644
index 000000000..86bc21516
--- /dev/null
+++ b/multisrc/overrides/grouple/selfmanga/src/SelfManga.kt
@@ -0,0 +1,93 @@
+package eu.kanade.tachiyomi.extension.ru.selfmanga
+
+import eu.kanade.tachiyomi.multisrc.grouple.GroupLe
+import eu.kanade.tachiyomi.network.GET
+import eu.kanade.tachiyomi.source.model.Filter
+import eu.kanade.tachiyomi.source.model.FilterList
+import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
+import okhttp3.Request
+
+class SelfManga : GroupLe("SelfManga", "https://selfmanga.live", "ru") {
+
+    override val id: Long = 5227602742162454547
+
+    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
+        val url = "$baseUrl/search/advanced".toHttpUrlOrNull()!!.newBuilder()
+        (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
+            when (filter) {
+                is GenreList -> filter.state.forEach { genre ->
+                    if (genre.state != Filter.TriState.STATE_IGNORE) {
+                        url.addQueryParameter(genre.id, arrayOf("=", "=in", "=ex")[genre.state])
+                    }
+                }
+                is Category -> filter.state.forEach { category ->
+                    if (category.state != Filter.TriState.STATE_IGNORE) {
+                        url.addQueryParameter(category.id, arrayOf("=", "=in", "=ex")[category.state])
+                    }
+                }
+                else -> return@forEach
+            }
+        }
+        if (query.isNotEmpty()) {
+            url.addQueryParameter("q", query)
+        }
+        return if (url.toString().contains("?"))
+            GET(url.toString().replace("=%3D", "="), headers)
+        else  popularMangaRequest(page)
+    }
+
+    private class Genre(name: String, val id: String) : Filter.TriState(name)
+    private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Genres", genres)
+    private class Category(categories: List<Genre>) : Filter.Group<Genre>("Category", categories)
+
+    override fun getFilterList() = FilterList(
+        Category(getCategoryList()),
+        GenreList(getGenreList())
+    )
+
+    private fun getCategoryList() = listOf(
+        Genre("Артбук", "el_5894"),
+        Genre("Веб", "el_2160"),
+        Genre("Журнал", "el_4983"),
+        Genre("Ранобэ", "el_5215"),
+        Genre("Сборник", "el_2157")
+    )
+
+    private fun getGenreList() = listOf(
+        Genre("боевик", "el_2155"),
+        Genre("боевые искусства", "el_2143"),
+        Genre("вампиры", "el_2148"),
+        Genre("гарем", "el_2142"),
+        Genre("гендерная интрига", "el_2156"),
+        Genre("героическое фэнтези", "el_2146"),
+        Genre("детектив", "el_2152"),
+        Genre("дзёсэй", "el_2158"),
+        Genre("додзинси", "el_2141"),
+        Genre("драма", "el_2118"),
+        Genre("ёнкома", "el_2161"),
+        Genre("история", "el_2119"),
+        Genre("комедия", "el_2136"),
+        Genre("махо-сёдзё", "el_2147"),
+        Genre("мистика", "el_2132"),
+        Genre("научная фантастика", "el_2133"),
+        Genre("повседневность", "el_2135"),
+        Genre("постапокалиптика", "el_2151"),
+        Genre("приключения", "el_2130"),
+        Genre("психология", "el_2144"),
+        Genre("романтика", "el_2121"),
+        Genre("сверхъестественное", "el_2159"),
+        Genre("сёдзё", "el_2122"),
+        Genre("сёдзё-ай", "el_2128"),
+        Genre("сёнэн", "el_2134"),
+        Genre("сёнэн-ай", "el_2139"),
+        Genre("спорт", "el_2129"),
+        Genre("сэйнэн", "el_5838"),
+        Genre("трагедия", "el_2153"),
+        Genre("триллер", "el_2150"),
+        Genre("ужасы", "el_2125"),
+        Genre("фантастика", "el_2140"),
+        Genre("фэнтези", "el_2131"),
+        Genre("школа", "el_2127"),
+        Genre("этти", "el_4982")
+    )
+}
diff --git a/src/ru/readmanga/src/eu/kanade/tachiyomi/extension/ru/readmanga/Readmanga.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/grouple/GroupLe.kt
similarity index 67%
rename from src/ru/readmanga/src/eu/kanade/tachiyomi/extension/ru/readmanga/Readmanga.kt
rename to multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/grouple/GroupLe.kt
index 6212ad4e2..b4680d840 100644
--- a/src/ru/readmanga/src/eu/kanade/tachiyomi/extension/ru/readmanga/Readmanga.kt
+++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/grouple/GroupLe.kt
@@ -1,4 +1,4 @@
-package eu.kanade.tachiyomi.extension.ru.readmanga
+package eu.kanade.tachiyomi.multisrc.grouple
 
 import android.app.Application
 import android.content.SharedPreferences
@@ -32,17 +32,15 @@ import java.text.SimpleDateFormat
 import java.util.Locale
 import java.util.regex.Pattern
 
-class Readmanga : ConfigurableSource, ParsedHttpSource() {
+abstract class GroupLe(
+    override val name: String,
+    override val baseUrl: String,
+    final override val lang: String
+) : ConfigurableSource, ParsedHttpSource() {
 
-    override val id: Long = 5
     private val preferences: SharedPreferences by lazy {
         Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
     }
-    override val name = "Readmanga"
-
-    override val baseUrl = "https://readmanga.io"
-
-    override val lang = "ru"
 
     override val supportsLatest = true
 
@@ -90,50 +88,6 @@ class Readmanga : ConfigurableSource, ParsedHttpSource() {
 
     override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
 
-    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
-        val url = "$baseUrl/search/advanced".toHttpUrlOrNull()!!.newBuilder()
-        (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
-            when (filter) {
-                is GenreList -> filter.state.forEach { genre ->
-                    if (genre.state != Filter.TriState.STATE_IGNORE) {
-                        url.addQueryParameter(genre.id, arrayOf("=", "=in", "=ex")[genre.state])
-                    }
-                }
-                is Category -> filter.state.forEach { category ->
-                    if (category.state != Filter.TriState.STATE_IGNORE) {
-                        url.addQueryParameter(category.id, arrayOf("=", "=in", "=ex")[category.state])
-                    }
-                }
-                is AgeList -> filter.state.forEach { age ->
-                    if (age.state != Filter.TriState.STATE_IGNORE) {
-                        url.addQueryParameter(age.id, arrayOf("=", "=in", "=ex")[age.state])
-                    }
-                }
-                is More -> filter.state.forEach { more ->
-                    if (more.state != Filter.TriState.STATE_IGNORE) {
-                        url.addQueryParameter(more.id, arrayOf("=", "=in", "=ex")[more.state])
-                    }
-                }
-                is FilList -> filter.state.forEach { fils ->
-                    if (fils.state != Filter.TriState.STATE_IGNORE) {
-                        url.addQueryParameter(fils.id, arrayOf("=", "=in", "=ex")[fils.state])
-                    }
-                }
-                is OrderBy -> {
-                    if (filter.state > 0) {
-                        val ord = arrayOf("not", "year", "rate", "popularity", "votes", "created", "updated")[filter.state]
-                        val ordUrl = "$baseUrl/list?sortType=$ord&offset=${70 * (page - 1)}".toHttpUrlOrNull()!!.newBuilder()
-                        return GET(ordUrl.toString(), headers)
-                    }
-                }
-            }
-        }
-        if (query.isNotEmpty()) {
-            url.addQueryParameter("q", query)
-        }
-        return GET(url.toString().replace("=%3D", "="), headers)
-    }
-
     override fun searchMangaSelector() = popularMangaSelector()
 
     override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element)
@@ -344,101 +298,6 @@ class Readmanga : ConfigurableSource, ParsedHttpSource() {
         }
     }
 
-    private class OrderBy : Filter.Select<String>(
-        "Сортировка (только)",
-        arrayOf("Без сортировки", "По году", "По популярности", "Популярно сейчас", "По рейтингу", "Новинки", "По дате обновления")
-    )
-
-    private class Genre(name: String, val id: String) : Filter.TriState(name)
-
-    private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Жанры", genres)
-    private class Category(categories: List<Genre>) : Filter.Group<Genre>("Категории", categories)
-    private class AgeList(ages: List<Genre>) : Filter.Group<Genre>("Возрастная рекомендация", ages)
-    private class More(moren: List<Genre>) : Filter.Group<Genre>("Прочее", moren)
-    private class FilList(fils: List<Genre>) : Filter.Group<Genre>("Фильтры", fils)
-
-    override fun getFilterList() = FilterList(
-        OrderBy(),
-        Category(getCategoryList()),
-        GenreList(getGenreList()),
-        AgeList(getAgeList()),
-        More(getMore()),
-        FilList(getFilList())
-    )
-
-    private fun getFilList() = listOf(
-        Genre("Высокий рейтинг", "s_high_rate"),
-        Genre("Сингл", "s_single"),
-        Genre("Для взрослых", "s_mature"),
-        Genre("Завершенная", "s_completed"),
-        Genre("Переведено", "s_translated"),
-        Genre("Длинная", "s_many_chapters"),
-        Genre("Ожидает загрузки", "s_wait_upload"),
-        Genre("Продается", "s_sale")
-    )
-    private fun getMore() = listOf(
-        Genre("В цвете", "el_7290"),
-        Genre("Веб", "el_2160"),
-        Genre("Выпуск приостановлен", "el_8033"),
-        Genre("Сборник", "el_2157")
-    )
-
-    private fun getAgeList() = listOf(
-        Genre("G(0+)", "el_6180"),
-        Genre("PG-13(12+)", "el_6181"),
-        Genre("PG(16+)", "el_6179")
-    )
-
-    private fun getCategoryList() = listOf(
-        Genre("Ёнкома", "el_2161"),
-        Genre("Комикс западный", "el_3515"),
-        Genre("Манхва", "el_3001"),
-        Genre("Маньхуа", "el_3002"),
-        Genre("Ранобэ", "el_8575"),
-    )
-
-    private fun getGenreList() = listOf(
-        Genre("арт", "el_5685"),
-        Genre("боевик", "el_2155"),
-        Genre("боевые искусства", "el_2143"),
-        Genre("вампиры", "el_2148"),
-        Genre("гарем", "el_2142"),
-        Genre("гендерная интрига", "el_2156"),
-        Genre("героическое фэнтези", "el_2146"),
-        Genre("детектив", "el_2152"),
-        Genre("дзёсэй", "el_2158"),
-        Genre("додзинси", "el_2141"),
-        Genre("драма", "el_2118"),
-        Genre("игра", "el_2154"),
-        Genre("история", "el_2119"),
-        Genre("киберпанк", "el_8032"),
-        Genre("кодомо", "el_2137"),
-        Genre("комедия", "el_2136"),
-        Genre("махо-сёдзё", "el_2147"),
-        Genre("меха", "el_2126"),
-        Genre("научная фантастика", "el_2133"),
-        Genre("повседневность", "el_2135"),
-        Genre("постапокалиптика", "el_2151"),
-        Genre("приключения", "el_2130"),
-        Genre("психология", "el_2144"),
-        Genre("романтика", "el_2121"),
-        Genre("самурайский боевик", "el_2124"),
-        Genre("сверхъестественное", "el_2159"),
-        Genre("сёдзё", "el_2122"),
-        Genre("сёдзё-ай", "el_2128"),
-        Genre("сёнэн", "el_2134"),
-        Genre("сёнэн-ай", "el_2139"),
-        Genre("спорт", "el_2129"),
-        Genre("сэйнэн", "el_2138"),
-        Genre("трагедия", "el_2153"),
-        Genre("триллер", "el_2150"),
-        Genre("ужасы", "el_2125"),
-        Genre("фэнтези", "el_2131"),
-        Genre("школа", "el_2127"),
-        Genre("этти", "el_2149"),
-        Genre("юри", "el_2123")
-    )
-
     override fun setupPreferenceScreen(screen: androidx.preference.PreferenceScreen) {
         screen.addPreference(screen.editTextPreference(UAGENT_TITLE, UAGENT_DEFAULT, uagent))
     }
diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/grouple/GroupLeGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/grouple/GroupLeGenerator.kt
new file mode 100644
index 000000000..d2d95d680
--- /dev/null
+++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/grouple/GroupLeGenerator.kt
@@ -0,0 +1,28 @@
+package eu.kanade.tachiyomi.multisrc.grouple
+
+import generator.ThemeSourceData.SingleLang
+import generator.ThemeSourceGenerator
+
+class GroupLeGenerator: ThemeSourceGenerator {
+
+    override val themePkg = "grouple"
+
+    override val themeClass = "GroupLe"
+
+    override val baseVersionCode: Int = 1
+
+    override val sources = listOf(
+        SingleLang("ReadManga", "https://readmanga.io", "ru", overrideVersionCode = 45),
+        SingleLang("MintManga", "https://mintmanga.live", "ru", overrideVersionCode = 46),
+        SingleLang("AllHentai", "http://23.allhen.online", "ru",isNsfw = true, overrideVersionCode = 22),
+        SingleLang("SelfManga", "https://selfmanga.live", "ru", overrideVersionCode = 22),
+        SingleLang("RuMIX", "https://rumix.me", "ru", overrideVersionCode = 1)
+    )
+
+    companion object {
+        @JvmStatic
+        fun main(args: Array<String>) {
+            GroupLeGenerator().createAll()
+        }
+    }
+}
diff --git a/src/ru/readmanga/src/eu/kanade/tachiyomi/extension/ru/readmanga/ReadmangaActivity.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/grouple/GroupLeUrlActivity.kt
similarity index 77%
rename from src/ru/readmanga/src/eu/kanade/tachiyomi/extension/ru/readmanga/ReadmangaActivity.kt
rename to multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/grouple/GroupLeUrlActivity.kt
index 860ff0fd3..c69adf47b 100644
--- a/src/ru/readmanga/src/eu/kanade/tachiyomi/extension/ru/readmanga/ReadmangaActivity.kt
+++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/grouple/GroupLeUrlActivity.kt
@@ -1,4 +1,4 @@
-package eu.kanade.tachiyomi.extension.ru.readmanga
+package eu.kanade.tachiyomi.multisrc.grouple
 
 import android.app.Activity
 import android.content.ActivityNotFoundException
@@ -12,7 +12,7 @@ import kotlin.system.exitProcess
  * you have this extension installed, but still let the main tachiyomi app control
  * things.
  */
-class ReadmangaActivity : Activity() {
+class GroupLeUrlActivity : Activity() {
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -21,17 +21,17 @@ class ReadmangaActivity : Activity() {
             val titleid = pathSegments[0]
             val mainIntent = Intent().apply {
                 action = "eu.kanade.tachiyomi.SEARCH"
-                putExtra("query", "${Readmanga.PREFIX_SLUG_SEARCH}$titleid")
+                putExtra("query", "${GroupLe.PREFIX_SLUG_SEARCH}$titleid")
                 putExtra("filter", packageName)
             }
 
             try {
                 startActivity(mainIntent)
             } catch (e: ActivityNotFoundException) {
-                Log.e("ReadmangaActivity", e.toString())
+                Log.e("GroupLeUrlActivity", e.toString())
             }
         } else {
-            Log.e("ReadmangaActivity", "could not parse uri from intent $intent")
+            Log.e("GroupLeUrlActivity", "could not parse uri from intent $intent")
         }
 
         finish()
diff --git a/src/ru/allhentai/AndroidManifest.xml b/src/ru/allhentai/AndroidManifest.xml
deleted file mode 100644
index 30deb7f79..000000000
--- a/src/ru/allhentai/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest package="eu.kanade.tachiyomi.extension" />
diff --git a/src/ru/allhentai/build.gradle b/src/ru/allhentai/build.gradle
deleted file mode 100644
index 362abd013..000000000
--- a/src/ru/allhentai/build.gradle
+++ /dev/null
@@ -1,12 +0,0 @@
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-
-ext {
-    extName = 'AllHentai'
-    pkgNameSuffix = 'ru.allhentai'
-    extClass = '.AllHentai'
-    extVersionCode = 22
-    isNsfw = true
-}
-
-apply from: "$rootDir/common.gradle"
diff --git a/src/ru/allhentai/res/mipmap-hdpi/ic_launcher.png b/src/ru/allhentai/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index 359610927..000000000
Binary files a/src/ru/allhentai/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/allhentai/res/mipmap-mdpi/ic_launcher.png b/src/ru/allhentai/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index c23a8e98d..000000000
Binary files a/src/ru/allhentai/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/allhentai/res/mipmap-xhdpi/ic_launcher.png b/src/ru/allhentai/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index 6b6ce16c8..000000000
Binary files a/src/ru/allhentai/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/allhentai/res/mipmap-xxhdpi/ic_launcher.png b/src/ru/allhentai/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index ecbb34fd2..000000000
Binary files a/src/ru/allhentai/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/allhentai/res/mipmap-xxxhdpi/ic_launcher.png b/src/ru/allhentai/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index d45ddd771..000000000
Binary files a/src/ru/allhentai/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/allhentai/res/web_hi_res_512.png b/src/ru/allhentai/res/web_hi_res_512.png
deleted file mode 100644
index 2bb4c600f..000000000
Binary files a/src/ru/allhentai/res/web_hi_res_512.png and /dev/null differ
diff --git a/src/ru/allhentai/src/eu/kanade/tachiyomi/extension/ru/allhentai/AllHentai.kt b/src/ru/allhentai/src/eu/kanade/tachiyomi/extension/ru/allhentai/AllHentai.kt
deleted file mode 100644
index 101f78eb1..000000000
--- a/src/ru/allhentai/src/eu/kanade/tachiyomi/extension/ru/allhentai/AllHentai.kt
+++ /dev/null
@@ -1,565 +0,0 @@
-package eu.kanade.tachiyomi.extension.ru.allhentai
-
-import android.app.Application
-import android.content.SharedPreferences
-import android.widget.Toast
-import eu.kanade.tachiyomi.network.GET
-import eu.kanade.tachiyomi.network.asObservableSuccess
-import eu.kanade.tachiyomi.network.interceptor.rateLimit
-import eu.kanade.tachiyomi.source.ConfigurableSource
-import eu.kanade.tachiyomi.source.model.Filter
-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 eu.kanade.tachiyomi.util.asJsoup
-import okhttp3.Headers
-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 java.io.IOException
-import java.text.DecimalFormat
-import java.text.ParseException
-import java.text.SimpleDateFormat
-import java.util.Locale
-import java.util.regex.Pattern
-
-class AllHentai : ConfigurableSource, ParsedHttpSource() {
-
-    private val preferences: SharedPreferences by lazy {
-        Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
-    }
-
-    override val name = "AllHentai"
-
-    private var domain: String = preferences.getString(DOMAIN_TITLE, DOMAIN_DEFAULT)!!
-    override val baseUrl: String = domain
-
-    override val lang = "ru"
-
-    override val supportsLatest = true
-
-    override val client: OkHttpClient = network.client.newBuilder()
-        .rateLimit(2)
-        .addNetworkInterceptor { chain ->
-            val originalRequest = chain.request()
-            val response = chain.proceed(originalRequest)
-            if (originalRequest.url.toString().contains(baseUrl) and (originalRequest.url.toString().contains("internal/redirect") or (response.code == 301)))
-                throw IOException("Манга переехала на другой адрес/ссылку!")
-            response
-        }
-        .build()
-
-    override fun popularMangaSelector() = "div.tile"
-
-    override fun latestUpdatesSelector() = popularMangaSelector()
-
-    override fun popularMangaRequest(page: Int): Request =
-        GET("$baseUrl/list?sortType=rate&offset=${70 * (page - 1)}", headers)
-
-    override fun latestUpdatesRequest(page: Int): Request =
-        GET("$baseUrl/list?sortType=updated&offset=${70 * (page - 1)}", headers)
-
-    override fun popularMangaFromElement(element: Element): SManga {
-        val manga = SManga.create()
-        manga.thumbnail_url = element.select("img.lazy").first()?.attr("data-original")?.replace("_p.", ".")
-        element.select("h3 > a").first().let {
-            manga.setUrlWithoutDomain(it.attr("href"))
-            manga.title = it.attr("title")
-        }
-        return manga
-    }
-
-    override fun latestUpdatesFromElement(element: Element): SManga =
-        popularMangaFromElement(element)
-
-    override fun popularMangaNextPageSelector() = "a.nextLink"
-
-    override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
-
-    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
-        val url = "$baseUrl/search/advanced".toHttpUrlOrNull()!!.newBuilder()
-        (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
-            when (filter) {
-                is GenreList -> filter.state.forEach { genre ->
-                    if (genre.state != Filter.TriState.STATE_IGNORE) {
-                        url.addQueryParameter(genre.id, arrayOf("=", "=in", "=ex")[genre.state])
-                    }
-                }
-                is Category -> filter.state.forEach { category ->
-                    if (category.state != Filter.TriState.STATE_IGNORE) {
-                        url.addQueryParameter(category.id, arrayOf("=", "=in", "=ex")[category.state])
-                    }
-                }
-                is FilList -> filter.state.forEach { fils ->
-                    if (fils.state != Filter.TriState.STATE_IGNORE) {
-                        url.addQueryParameter(fils.id, arrayOf("=", "=in", "=ex")[fils.state])
-                    }
-                }
-                is OrderBy -> {
-                    if (filter.state > 0) {
-                        val ord = arrayOf("not", "year", "rate", "popularity", "votes", "created", "updated")[filter.state]
-                        val ordUrl = "$baseUrl/list?sortType=$ord&offset=${70 * (page - 1)}".toHttpUrlOrNull()!!.newBuilder()
-                        return GET(ordUrl.toString(), headers)
-                    }
-                }
-                is Tags -> {
-                    if (filter.state > 0) {
-                        val tagName = getTagsList()[filter.state].url
-                        val tagUrl = "$baseUrl/list/tag/$tagName?offset=${70 * (page - 1)}".toHttpUrlOrNull()!!.newBuilder()
-                        return GET(tagUrl.toString(), headers)
-                    }
-                }
-                else -> return@forEach
-            }
-        }
-        if (query.isNotEmpty()) {
-            url.addQueryParameter("q", query)
-        }
-        return GET(url.toString().replace("=%3D", "="), headers)
-    }
-
-    override fun searchMangaSelector() = popularMangaSelector()
-
-    override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element)
-
-    // max 200 results (exception OrderBy,Tags)
-    override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
-
-    override fun mangaDetailsParse(document: Document): SManga {
-        val infoElement = document.select(".expandable").first()
-        val rawCategory = infoElement.select("span.elem_category").text()
-        val category = if (rawCategory.isNotEmpty()) {
-            rawCategory.lowercase()
-        } else {
-            "манга"
-        }
-
-        val manga = SManga.create()
-        var authorElement = infoElement.select("span.elem_author").first()?.text()
-        if (authorElement == null) {
-            authorElement = infoElement.select("span.elem_screenwriter").first()?.text()
-        }
-        manga.title = document.select("h1.names .name").text()
-        manga.author = authorElement
-        manga.artist = infoElement.select("span.elem_illustrator").first()?.text()
-        manga.genre = category + ", " + infoElement.select("span.elem_genre").text().split(",").joinToString { it.trim() }
-        manga.description = document.select("div#tab-description  .manga-description").text()
-        manga.status = parseStatus(infoElement.html())
-        manga.thumbnail_url = infoElement.select("img").attr("data-full")
-        return manga
-    }
-
-    private fun parseStatus(element: String): Int = when {
-        element.contains("Запрещена публикация произведения по копирайту") || element.contains("ЗАПРЕЩЕНА К ПУБЛИКАЦИИ НА ТЕРРИТОРИИ РФ!") -> SManga.LICENSED
-        element.contains("<b>Перевод:</b> продолжается") -> SManga.ONGOING
-        element.contains("<b>Сингл</b>") || element.contains("<b>Перевод:</b> завер") -> SManga.COMPLETED
-        else -> SManga.UNKNOWN
-    }
-
-    override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
-        return if (manga.status != SManga.LICENSED) {
-            client.newCall(chapterListRequest(manga))
-                .asObservableSuccess()
-                .map { response ->
-                    chapterListParse(response, manga)
-                }
-        } else {
-            Observable.error(java.lang.Exception("Licensed - No chapters to show"))
-        }
-    }
-
-    private fun chapterListParse(response: Response, manga: SManga): List<SChapter> {
-        val document = response.asJsoup()
-        return document.select(chapterListSelector()).map { chapterFromElement(it, manga) }
-    }
-
-    override fun chapterListSelector() = "div.chapters-link > table > tbody > tr:has(td > a):has(td.date:not(.text-info))"
-
-    private fun chapterFromElement(element: Element, manga: SManga): SChapter {
-        val urlElement = element.select("a").first()
-        val chapterInf = element.select("td.item-title").first()
-        val urlText = urlElement.text()
-
-        val chapter = SChapter.create()
-        chapter.setUrlWithoutDomain(urlElement.attr("href") + "?mtr=true") // mtr is 18+ skip
-
-        var translators = ""
-        val translatorElement = urlElement.attr("title")
-        if (!translatorElement.isNullOrBlank()) {
-            translators = translatorElement
-                .replace("(Переводчик),", "&")
-                .removeSuffix(" (Переводчик)")
-        }
-        chapter.scanlator = translators
-
-        chapter.name = urlText.removeSuffix(" новое").trim()
-        if (manga.title.length > 25) {
-            for (word in manga.title.split(' ')) {
-                chapter.name = chapter.name.removePrefix(word).trim()
-            }
-        }
-        val dots = chapter.name.indexOf("…")
-        val numbers = chapter.name.findAnyOf(IntRange(0, 9).map { it.toString() })?.first ?: 0
-
-        if (dots in 0 until numbers) {
-            chapter.name = chapter.name.substringAfter("…").trim()
-        }
-
-        chapter.chapter_number = chapterInf.attr("data-num").toFloat() / 10
-
-        chapter.date_upload = element.select("td.d-none").last()?.text()?.let {
-            try {
-                SimpleDateFormat("dd.MM.yy", Locale.US).parse(it)?.time ?: 0L
-            } catch (e: ParseException) {
-                SimpleDateFormat("dd/MM/yy", Locale.US).parse(it)?.time ?: 0L
-            }
-        } ?: 0
-        return chapter
-    }
-
-    override fun chapterFromElement(element: Element): SChapter {
-        throw Exception("Not used")
-    }
-
-    override fun prepareNewChapter(chapter: SChapter, manga: SManga) {
-        val extra = Regex("""\s*([0-9]+\sЭкстра)\s*""")
-        val single = Regex("""\s*Сингл\s*""")
-        when {
-            extra.containsMatchIn(chapter.name) -> {
-                if (chapter.name.substringAfter("Экстра").trim().isEmpty())
-                    chapter.name = chapter.name.replaceFirst(" ", " - " + DecimalFormat("#,###.##").format(chapter.chapter_number).replace(",", ".") + " ")
-            }
-
-            single.containsMatchIn(chapter.name) -> {
-                if (chapter.name.substringAfter("Сингл").trim().isEmpty())
-                    chapter.name = DecimalFormat("#,###.##").format(chapter.chapter_number).replace(",", ".") + " " + chapter.name
-            }
-        }
-    }
-
-    override fun pageListParse(response: Response): List<Page> {
-        val html = response.body!!.string()
-        val trimmedHtml = html.substringAfter("rm_h.initReader(").substringBefore(");")
-
-        val p = Pattern.compile("'.*?','.*?',\".*?\"")
-        val m = p.matcher(trimmedHtml)
-
-        val pages = mutableListOf<Page>()
-
-        var i = 0
-        while (m.find()) {
-            val urlParts = m.group().replace("[\"\']+".toRegex(), "").split(',')
-            val url = when {
-                (urlParts[1].isEmpty() && urlParts[2].startsWith("/static/")) -> {
-                    baseUrl + urlParts[2]
-                }
-                urlParts[1].endsWith("/manga/") -> {
-                    urlParts[0] + urlParts[2]
-                }
-                urlParts[1].isEmpty() -> {
-                    val imageUrl = urlParts[2].split('?')
-                    "https:" + urlParts[0] + imageUrl[0]
-                }
-                else -> {
-                    urlParts[1] + urlParts[0] + urlParts[2]
-                }
-            }
-
-            pages.add(Page(i++, "", url))
-        }
-        return pages
-    }
-
-    override fun pageListParse(document: Document): List<Page> {
-        throw Exception("Not used")
-    }
-
-    override fun imageUrlParse(document: Document) = ""
-
-    override fun imageRequest(page: Page): Request {
-        val imgHeader = Headers.Builder().apply {
-            add("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64)")
-            add("Referer", baseUrl)
-        }.build()
-        return GET(page.imageUrl!!, imgHeader)
-    }
-
-    private class OrderBy : Filter.Select<String>(
-        "Сортировка (только)",
-        arrayOf("Без сортировки", "По году", "По популярности", "Популярно сейчас", "По рейтингу", "Новинки", "По дате обновления")
-    )
-
-    private class Genre(name: String, val id: String) : Filter.TriState(name)
-
-    private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Жанры", genres)
-    private class Category(categories: List<Genre>) : Filter.Group<Genre>("Категории", categories)
-    private class FilList(fils: List<Genre>) : Filter.Group<Genre>("Фильтры", fils)
-    private class Tags(tags: Array<String>) : Filter.Select<String>("Тэг (только)", tags)
-
-    private data class Tag(val name: String, val url: String)
-
-    override fun getFilterList() = FilterList(
-        OrderBy(),
-        Tags(tagsName),
-        GenreList(getGenreList()),
-        Category(getCategoryList()),
-        FilList(getFilList())
-    )
-
-    /*
-    * [...document.querySelectorAll('.search-form > .form-group')[1].querySelectorAll('span.js-link')]
-    *   .map((el) =>
-    *      `Genre("${el.textContent.trim()}", "${el
-    *          .getAttribute('onclick')
-    *          .match(/el_\d+/)}")`
-    *  )
-    *  .join(',\n');
-    *  on allhen.live/search/advanced
-    */
-    private fun getGenreList() = listOf(
-        Genre("ahegao", "el_855"),
-        Genre("анал", "el_828"),
-        Genre("бдсм", "el_78"),
-        Genre("без цензуры", "el_888"),
-        Genre("большая грудь", "el_837"),
-        Genre("большая попка", "el_3156"),
-        Genre("большой член", "el_884"),
-        Genre("бондаж", "el_5754"),
-        Genre("в первый раз", "el_811"),
-        Genre("в цвете", "el_290"),
-        Genre("гарем", "el_87"),
-        Genre("гендарная интрига", "el_89"),
-        Genre("групповой секс", "el_88"),
-        Genre("драма", "el_95"),
-        Genre("зрелые женщины", "el_5679"),
-        Genre("измена", "el_291"),
-        Genre("изнасилование", "el_124"),
-        Genre("инцест", "el_85"),
-        Genre("исторический", "el_93"),
-        Genre("комедия", "el_73"),
-        Genre("маленькая грудь", "el_870"),
-        Genre("научная фантастика", "el_76"),
-        Genre("нетораре", "el_303"),
-        Genre("оральный секс", "el_853"),
-        Genre("романтика", "el_74"),
-        Genre("тентакли", "el_69"),
-        Genre("трагедия", "el_1321"),
-        Genre("ужасы", "el_75"),
-        Genre("футанари", "el_77"),
-        Genre("фэнтези", "el_70"),
-        Genre("чикан", "el_1059"),
-        Genre("этти", "el_798"),
-        Genre("юри", "el_84"),
-        Genre("яой", "el_83")
-    )
-
-    /*
-    * [...document.querySelectorAll('.search-form > .form-group')[2].querySelectorAll('span.js-link')]
-    *   .map((el) =>
-    *      `Genre("${el.textContent.trim()}", "${el
-    *          .getAttribute('onclick')
-    *          .match(/el_\d+/)}")`
-    *  )
-    *  .join(',\n');
-    *  on allhen.live/search/advanced
-    */
-    private fun getCategoryList() = listOf(
-        Genre("3D", "el_626"),
-        Genre("Анимация", "el_5777"),
-        Genre("Без текста", "el_3157"),
-        Genre("Порно комикс", "el_1003"),
-        Genre("Порно манхва", "el_1104")
-    )
-
-    /*
-    * [...document.querySelectorAll('.search-form > .form-group')[1].querySelectorAll('span.js-link')]
-    *   .map((el) =>
-    *      `Genre("${el.textContent.trim()}", "${el
-    *          .getAttribute('onclick')
-    *          .match(/s_\w+/)}")`
-    *  )
-    *  .join(',\n');
-    *  on allhen.live/search/advanced
-    */
-    private fun getFilList() = listOf(
-        Genre("Высокий рейтинг", "s_high_rate"),
-        Genre("Сингл", "s_single"),
-        Genre("Для взрослых", "s_mature"),
-        Genre("Завершенная", "s_completed"),
-        Genre("Переведено", "s_translated"),
-        Genre("Длинная", "s_many_chapters"),
-        Genre("Ожидает загрузки", "s_wait_upload"),
-        Genre("Продается", "s_sale")
-    )
-
-    /**
-     * [...document.querySelectorAll('tbody .element-link')]
-     *   .map((it) =>
-     *      `Tag("${it.textContent.trim()}", "${it
-     *          .getAttribute('href')
-     *          .split('tag/')
-     *          .pop()}")`
-     *  )
-     *  .join(',\n');
-     *  on allhen.live/list/tags/sort_NAME
-     */
-    private fun getTagsList() = listOf(
-        Tag("Без тега", "not"),
-        Tag("handjob", "handjob"),
-        Tag("inseki", "inseki"),
-        Tag("алкоголь", "alcohol"),
-        Tag("андроид", "android"),
-        Tag("анилингус", "anilingus"),
-        Tag("бассейн", "pool"),
-        Tag("без трусиков", "without_panties"),
-        Tag("беременность", "pregnancy"),
-        Tag("бикини", "bikini"),
-        Tag("близнецы", "twins"),
-        Tag("боди-арт", "body_art"),
-        Tag("больница", "hospital"),
-        Tag("буккакэ", "bukkake"),
-        Tag("в ванной", "in_bathroom"),
-        Tag("в общественном месте", "in_public_place"),
-        Tag("в транспорте", "in_vehicle"),
-        Tag("вампиры", "vampires"),
-        Tag("вибратор", "vibrator"),
-        Tag("втянутые соски", "inverted_nipples"),
-        Tag("гипноз", "hypnosis"),
-        Tag("глубокий минет", "deepthroat"),
-        Tag("горничные", "maids"),
-        Tag("горячий источник", "hot_spring"),
-        Tag("гэнгбэнг", "gangbang"),
-        Tag("гяру", "gyaru"),
-        Tag("двойное проникновение", "double_penetration"),
-        Tag("Девочки волшебницы", "magical_girl"),
-        Tag("демоны", "demons"),
-        Tag("дефекация", "scat"),
-        Tag("дилдо", "dildo"),
-        Tag("додзинси", "doujinshi"),
-        Tag("домохозяйки", "housewives"),
-        Tag("дыра в стене", "hole_in_the_wall"),
-        Tag("жестокость", "cruelty"),
-        Tag("загар", "tan_lines"),
-        Tag("зомби", "zombie"),
-        Tag("инопланетяне", "aliens"),
-        Tag("исполнение желаний", "granting_wish"),
-        Tag("камера", "camera"),
-        Tag("косплей", "cosplay"),
-        Tag("кремпай", "creampie"),
-        Tag("куннилингус", "cunnilingus"),
-        Tag("купальник", "swimsuit"),
-        Tag("лактация", "lactation"),
-        Tag("латекс и кожа", "latex"),
-        Tag("Ломка Психики", "mind_break"),
-        Tag("магия", "magic"),
-        Tag("мастурбация", "masturbation"),
-        Tag("медсестра", "nurse"),
-        Tag("мерзкий дядька", "terrible_oyaji"),
-        Tag("много девушек", "many_girls"),
-        Tag("много спермы", "a_lot_of_sperm"),
-        Tag("монстрдевушки", "monstergirl"),
-        Tag("монстры", "monsters"),
-        Tag("мужчина крепкого телосложения", "muscle_man"),
-        Tag("на природе", "outside"),
-        Tag("не бритая киска", "hairy_pussy"),
-        Tag("не бритые подмышки", "hairy_armpits"),
-        Tag("нетори", "netori"),
-        Tag("нижнее бельё", "lingerie"),
-        Tag("обмен партнерами", "swinging"),
-        Tag("обмен телами", "body_swap"),
-        Tag("обычный секс", "normal_sex"),
-        Tag("огромная грудь", "super_big_boobs"),
-        Tag("орки", "orcs"),
-        Tag("очки", "megane"),
-        Tag("пайзури", "titsfuck"),
-        Tag("парень пассив", "passive_guy"),
-        Tag("пацанка", "tomboy"),
-        Tag("пеггинг", "pegging"),
-        Tag("переодевание", "disguise"),
-        Tag("пирсинг", "piercing"),
-        Tag("писают", "peeing"),
-        Tag("пляж", "beach"),
-        Tag("повседневность", "slice_of_life"),
-        Tag("повязка на глаза", "blindfold"),
-        Tag("подглядывание", "peeping"),
-        Tag("подчинение", "submission"),
-        Tag("похищение", "kidnapping"),
-        Tag("принуждение", "forced"),
-        Tag("прозрачная одежда", "transparent_clothes"),
-        Tag("проституция", "prostitution"),
-        Tag("психические отклонения", "mental_illness"),
-        Tag("публичный секс", "public_sex"),
-        Tag("пьяные", "drunk"),
-        Tag("рабы", "slaves"),
-        Tag("рентген зрение", "x_ray"),
-        Tag("сверхъестественное", "supernatural"),
-        Tag("секс втроем", "threesome"),
-        Tag("секс игрушки", "sex_toys"),
-        Tag("сексуально возбужденная", "horny"),
-        Tag("спортивная форма", "sports_uniform"),
-        Tag("спящие", "sleeping"),
-        Tag("страпон", "strapon"),
-        Tag("Суккуб", "succubus"),
-        Tag("темнокожие", "dark_skin"),
-        Tag("толстушки", "fatties"),
-        Tag("трап", "trap"),
-        Tag("униформа", "uniform"),
-        Tag("ушастые", "eared"),
-        Tag("фантазии", "dreams"),
-        Tag("фемдом", "femdom"),
-        Tag("фестиваль", "festival"),
-        Tag("фетиш", "fetish"),
-        Tag("фистинг", "fisting"),
-        Tag("фурри", "furry"),
-        Tag("футанари имеет парня", "futanari_on_boy"),
-        Tag("футджаб", "footfuck"),
-        Tag("цельный купальник", "full_swimsuit"),
-        Tag("цундэрэ", "tsundere"),
-        Tag("чулки", "hose"),
-        Tag("шалава", "slut"),
-        Tag("шантаж", "blackmail"),
-        Tag("эксгибиционизм", "exhibitionism"),
-        Tag("эльфы", "elves"),
-        Tag("яндере", "yandere")
-    )
-
-    private val tagsName = getTagsList().map {
-        it.name
-    }.toTypedArray()
-
-    override fun setupPreferenceScreen(screen: androidx.preference.PreferenceScreen) {
-        screen.addPreference(screen.editTextPreference(DOMAIN_TITLE, DOMAIN_DEFAULT, domain))
-    }
-
-    private fun androidx.preference.PreferenceScreen.editTextPreference(title: String, default: String, value: String): androidx.preference.EditTextPreference {
-        return androidx.preference.EditTextPreference(context).apply {
-            key = title
-            this.title = title
-            summary = value
-            this.setDefaultValue(default)
-            dialogTitle = title
-            setOnPreferenceChangeListener { _, newValue ->
-                try {
-                    val res = preferences.edit().putString(title, newValue as String).commit()
-                    Toast.makeText(context, "Для смены домена необходимо перезапустить приложение с полной остановкой.", Toast.LENGTH_LONG).show()
-                    res
-                } catch (e: Exception) {
-                    e.printStackTrace()
-                    false
-                }
-            }
-        }
-    }
-    companion object {
-        private const val DOMAIN_TITLE = "Домен"
-        private const val DOMAIN_DEFAULT = "http://23.allhen.online"
-    }
-}
diff --git a/src/ru/mintmanga/build.gradle b/src/ru/mintmanga/build.gradle
deleted file mode 100644
index eefc6de02..000000000
--- a/src/ru/mintmanga/build.gradle
+++ /dev/null
@@ -1,11 +0,0 @@
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-
-ext {
-    extName = 'Mintmanga'
-    pkgNameSuffix = 'ru.mintmanga'
-    extClass = '.Mintmanga'
-    extVersionCode = 46
-}
-
-apply from: "$rootDir/common.gradle"
diff --git a/src/ru/mintmanga/res/mipmap-hdpi/ic_launcher.png b/src/ru/mintmanga/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index 78bc7512c..000000000
Binary files a/src/ru/mintmanga/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/mintmanga/res/mipmap-mdpi/ic_launcher.png b/src/ru/mintmanga/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index ff183f248..000000000
Binary files a/src/ru/mintmanga/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/mintmanga/res/mipmap-xhdpi/ic_launcher.png b/src/ru/mintmanga/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index 6a6ef9e52..000000000
Binary files a/src/ru/mintmanga/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/mintmanga/res/mipmap-xxhdpi/ic_launcher.png b/src/ru/mintmanga/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 8b12a60a8..000000000
Binary files a/src/ru/mintmanga/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/mintmanga/res/mipmap-xxxhdpi/ic_launcher.png b/src/ru/mintmanga/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index c555bd882..000000000
Binary files a/src/ru/mintmanga/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/mintmanga/src/eu/kanade/tachiyomi/extension/ru/mintmanga/Mintmanga.kt b/src/ru/mintmanga/src/eu/kanade/tachiyomi/extension/ru/mintmanga/Mintmanga.kt
deleted file mode 100644
index 6d7aec6f6..000000000
--- a/src/ru/mintmanga/src/eu/kanade/tachiyomi/extension/ru/mintmanga/Mintmanga.kt
+++ /dev/null
@@ -1,469 +0,0 @@
-package eu.kanade.tachiyomi.extension.ru.mintmanga
-
-import android.app.Application
-import android.content.SharedPreferences
-import android.widget.Toast
-import eu.kanade.tachiyomi.network.GET
-import eu.kanade.tachiyomi.network.asObservableSuccess
-import eu.kanade.tachiyomi.network.interceptor.rateLimit
-import eu.kanade.tachiyomi.source.ConfigurableSource
-import eu.kanade.tachiyomi.source.model.Filter
-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.ParsedHttpSource
-import eu.kanade.tachiyomi.util.asJsoup
-import okhttp3.Headers
-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 java.io.IOException
-import java.text.DecimalFormat
-import java.text.ParseException
-import java.text.SimpleDateFormat
-import java.util.Locale
-import java.util.regex.Pattern
-
-class Mintmanga : ConfigurableSource, ParsedHttpSource() {
-
-    override val id: Long = 6
-    private val preferences: SharedPreferences by lazy {
-        Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
-    }
-    override val name = "Mintmanga"
-
-    override val baseUrl = "https://mintmanga.live"
-
-    override val lang = "ru"
-
-    override val supportsLatest = true
-
-    override val client: OkHttpClient = network.client.newBuilder()
-        .rateLimit(2)
-        .addNetworkInterceptor { chain ->
-            val originalRequest = chain.request()
-            val response = chain.proceed(originalRequest)
-            if (originalRequest.url.toString().contains(baseUrl) and (originalRequest.url.toString().contains("internal/redirect") or (response.code == 301)))
-                throw IOException("Манга переехала на другой адрес/ссылку!")
-            response
-        }
-        .build()
-
-    private var uagent: String = preferences.getString(UAGENT_TITLE, UAGENT_DEFAULT)!!
-    override fun headersBuilder() = Headers.Builder().apply {
-        add("User-Agent", uagent)
-        add("Referer", baseUrl)
-    }
-
-    override fun popularMangaRequest(page: Int): Request =
-        GET("$baseUrl/list?sortType=rate&offset=${70 * (page - 1)}", headers)
-
-    override fun latestUpdatesRequest(page: Int): Request =
-        GET("$baseUrl/list?sortType=updated&offset=${70 * (page - 1)}", headers)
-
-    override fun popularMangaSelector() = "div.tile"
-
-    override fun latestUpdatesSelector() = popularMangaSelector()
-
-    override fun popularMangaFromElement(element: Element): SManga {
-        val manga = SManga.create()
-        manga.thumbnail_url = element.select("img.lazy").first()?.attr("data-original")?.replace("_p.", ".")
-        element.select("h3 > a").first().let {
-            manga.setUrlWithoutDomain(it.attr("href"))
-            manga.title = it.attr("title")
-        }
-        return manga
-    }
-
-    override fun latestUpdatesFromElement(element: Element): SManga =
-        popularMangaFromElement(element)
-
-    override fun popularMangaNextPageSelector() = "a.nextLink"
-
-    override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
-
-    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
-        val url = "$baseUrl/search/advanced".toHttpUrlOrNull()!!.newBuilder()
-        (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
-            when (filter) {
-                is GenreList -> filter.state.forEach { genre ->
-                    if (genre.state != Filter.TriState.STATE_IGNORE) {
-                        url.addQueryParameter(genre.id, arrayOf("=", "=in", "=ex")[genre.state])
-                    }
-                }
-                is Category -> filter.state.forEach { category ->
-                    if (category.state != Filter.TriState.STATE_IGNORE) {
-                        url.addQueryParameter(category.id, arrayOf("=", "=in", "=ex")[category.state])
-                    }
-                }
-                is AgeList -> filter.state.forEach { age ->
-                    if (age.state != Filter.TriState.STATE_IGNORE) {
-                        url.addQueryParameter(age.id, arrayOf("=", "=in", "=ex")[age.state])
-                    }
-                }
-                is More -> filter.state.forEach { more ->
-                    if (more.state != Filter.TriState.STATE_IGNORE) {
-                        url.addQueryParameter(more.id, arrayOf("=", "=in", "=ex")[more.state])
-                    }
-                }
-                is FilList -> filter.state.forEach { fils ->
-                    if (fils.state != Filter.TriState.STATE_IGNORE) {
-                        url.addQueryParameter(fils.id, arrayOf("=", "=in", "=ex")[fils.state])
-                    }
-                }
-                is OrderBy -> {
-                    if (filter.state > 0) {
-                        val ord = arrayOf("not", "year", "rate", "popularity", "votes", "created", "updated")[filter.state]
-                        val ordUrl = "$baseUrl/list?sortType=$ord&offset=${70 * (page - 1)}".toHttpUrlOrNull()!!.newBuilder()
-                        return GET(ordUrl.toString(), headers)
-                    }
-                }
-            }
-        }
-        if (query.isNotEmpty()) {
-            url.addQueryParameter("q", query)
-        }
-        return GET(url.toString().replace("=%3D", "="), headers)
-    }
-
-    override fun searchMangaSelector() = popularMangaSelector()
-
-    override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element)
-
-    // max 200 results (exception OrderBy)
-    override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
-
-    override fun mangaDetailsParse(document: Document): SManga {
-        val infoElement = document.select(".expandable").first()
-        val rawCategory = infoElement.select("span.elem_category").text()
-        val category = if (rawCategory.isNotEmpty()) {
-            rawCategory.lowercase()
-        } else {
-            "манга"
-        }
-        val ratingValue = infoElement.select(".col-sm-7 .rating-block").attr("data-score").toFloat() * 2
-        val ratingValueOver = infoElement.select(".info-icon").attr("data-content").substringBeforeLast("/5</b><br/>").substringAfterLast(": <b>").replace(",", ".").toFloat() * 2
-        val ratingVotes = infoElement.select(".col-sm-7 .user-rating meta[itemprop=\"ratingCount\"]").attr("content")
-        val ratingStar = when {
-            ratingValue > 9.5 -> "★★★★★"
-            ratingValue > 8.5 -> "★★★★✬"
-            ratingValue > 7.5 -> "★★★★☆"
-            ratingValue > 6.5 -> "★★★✬☆"
-            ratingValue > 5.5 -> "★★★☆☆"
-            ratingValue > 4.5 -> "★★✬☆☆"
-            ratingValue > 3.5 -> "★★☆☆☆"
-            ratingValue > 2.5 -> "★✬☆☆☆"
-            ratingValue > 1.5 -> "★☆☆☆☆"
-            ratingValue > 0.5 -> "✬☆☆☆☆"
-            else -> "☆☆☆☆☆"
-        }
-        val rawAgeValue = infoElement.select(".elem_limitation .element-link").first()?.text()
-        val rawAgeStop = when (rawAgeValue) {
-            "NC-17" -> "18+"
-            "R18+" -> "18+"
-            else -> "16+"
-        }
-        val manga = SManga.create()
-        var authorElement = infoElement.select("span.elem_author").first()?.text()
-        if (authorElement == null) {
-            authorElement = infoElement.select("span.elem_screenwriter").first()?.text()
-        }
-        manga.title = document.select("h1.names .name").text()
-        manga.author = authorElement
-        manga.artist = infoElement.select("span.elem_illustrator").first()?.text()
-        manga.genre = category + ", " + rawAgeStop + ", " + infoElement.select("span.elem_genre").text().split(",").joinToString { it.trim() }
-        var altName = ""
-        if (infoElement.select(".another-names").isNotEmpty()) {
-            altName = "Альтернативные названия:\n" + infoElement.select(".another-names").text() + "\n\n"
-        }
-        manga.description = ratingStar + " " + ratingValue + "[ⓘ" + ratingValueOver + "]" + " (голосов: " + ratingVotes + ")\n" + altName + document.select("div#tab-description  .manga-description").text()
-        manga.status = parseStatus(infoElement.html())
-        manga.thumbnail_url = infoElement.select("img").attr("data-full")
-        return manga
-    }
-
-    private fun parseStatus(element: String): Int = when {
-        element.contains("Запрещена публикация произведения по копирайту") || element.contains("ЗАПРЕЩЕНА К ПУБЛИКАЦИИ НА ТЕРРИТОРИИ РФ!") -> SManga.LICENSED
-        element.contains("<b>Перевод:</b> продолжается") -> SManga.ONGOING
-        element.contains("<b>Сингл</b>") || element.contains("<b>Перевод:</b> завер") -> SManga.COMPLETED
-        else -> SManga.UNKNOWN
-    }
-
-    override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
-        return if (manga.status != SManga.LICENSED) {
-            client.newCall(chapterListRequest(manga))
-                .asObservableSuccess()
-                .map { response ->
-                    chapterListParse(response, manga)
-                }
-        } else {
-            Observable.error(java.lang.Exception("Licensed - No chapters to show"))
-        }
-    }
-
-    private fun chapterListParse(response: Response, manga: SManga): List<SChapter> {
-        val document = response.asJsoup()
-        return document.select(chapterListSelector()).map { chapterFromElement(it, manga) }
-    }
-
-    override fun chapterListSelector() = "div.chapters-link > table > tbody > tr:has(td > a):has(td.date:not(.text-info))"
-
-    private fun chapterFromElement(element: Element, manga: SManga): SChapter {
-        val urlElement = element.select("a").first()
-        val chapterInf = element.select("td.item-title").first()
-        val urlText = urlElement.text()
-
-        val chapter = SChapter.create()
-        chapter.setUrlWithoutDomain(urlElement.attr("href") + "?mtr=true") // mtr is 18+ skip
-
-        var translators = ""
-        val translatorElement = urlElement.attr("title")
-        if (!translatorElement.isNullOrBlank()) {
-            translators = translatorElement
-                .replace("(Переводчик),", "&")
-                .removeSuffix(" (Переводчик)")
-        }
-        chapter.scanlator = translators
-
-        chapter.name = urlText.removeSuffix(" новое").trim()
-        if (manga.title.length > 25) {
-            for (word in manga.title.split(' ')) {
-                chapter.name = chapter.name.removePrefix(word).trim()
-            }
-        }
-        val dots = chapter.name.indexOf("…")
-        val numbers = chapter.name.findAnyOf(IntRange(0, 9).map { it.toString() })?.first ?: 0
-
-        if (dots in 0 until numbers) {
-            chapter.name = chapter.name.substringAfter("…").trim()
-        }
-
-        chapter.chapter_number = chapterInf.attr("data-num").toFloat() / 10
-
-        chapter.date_upload = element.select("td.d-none").last()?.text()?.let {
-            try {
-                SimpleDateFormat("dd.MM.yy", Locale.US).parse(it)?.time ?: 0L
-            } catch (e: ParseException) {
-                SimpleDateFormat("dd/MM/yy", Locale.US).parse(it)?.time ?: 0L
-            }
-        } ?: 0
-        return chapter
-    }
-
-    override fun chapterFromElement(element: Element): SChapter {
-        throw Exception("Not used")
-    }
-
-    override fun prepareNewChapter(chapter: SChapter, manga: SManga) {
-        val extra = Regex("""\s*([0-9]+\sЭкстра)\s*""")
-        val single = Regex("""\s*Сингл\s*""")
-        when {
-            extra.containsMatchIn(chapter.name) -> {
-                if (chapter.name.substringAfter("Экстра").trim().isEmpty())
-                    chapter.name = chapter.name.replaceFirst(" ", " - " + DecimalFormat("#,###.##").format(chapter.chapter_number).replace(",", ".") + " ")
-            }
-
-            single.containsMatchIn(chapter.name) -> {
-                if (chapter.name.substringAfter("Сингл").trim().isEmpty())
-                    chapter.name = DecimalFormat("#,###.##").format(chapter.chapter_number).replace(",", ".") + " " + chapter.name
-            }
-        }
-    }
-
-    override fun pageListParse(response: Response): List<Page> {
-        val html = response.body!!.string()
-        val beginIndex = html.indexOf("rm_h.initReader( [")
-        val endIndex = html.indexOf(");", beginIndex)
-        val trimmedHtml = html.substring(beginIndex, endIndex)
-
-        val p = Pattern.compile("'.*?','.*?',\".*?\"")
-        val m = p.matcher(trimmedHtml)
-
-        val pages = mutableListOf<Page>()
-
-        var i = 0
-        while (m.find()) {
-            val urlParts = m.group().replace("[\"\']+".toRegex(), "").split(',')
-            val url = if (urlParts[1].isEmpty() && urlParts[2].startsWith("/static/")) {
-                baseUrl + urlParts[2]
-            } else {
-                if (urlParts[1].endsWith("/manga/")) {
-                    urlParts[0] + urlParts[2]
-                } else {
-                    urlParts[1] + urlParts[0] + urlParts[2]
-                }
-            }
-            pages.add(Page(i++, "", url))
-        }
-        return pages
-    }
-
-    override fun pageListParse(document: Document): List<Page> {
-        throw Exception("Not used")
-    }
-
-    override fun imageUrlParse(document: Document) = ""
-
-    override fun imageRequest(page: Page): Request {
-        val imgHeader = Headers.Builder().apply {
-            add("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64)")
-            add("Referer", baseUrl)
-        }.build()
-        return GET(page.imageUrl!!, imgHeader)
-    }
-    private fun searchMangaByIdRequest(id: String): Request {
-        return GET("$baseUrl/$id", headers)
-    }
-
-    override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
-        return if (query.startsWith(PREFIX_SLUG_SEARCH)) {
-            val realQuery = query.removePrefix(PREFIX_SLUG_SEARCH)
-            client.newCall(searchMangaByIdRequest(realQuery))
-                .asObservableSuccess()
-                .map { response ->
-                    val details = mangaDetailsParse(response)
-                    details.url = "/$realQuery"
-                    MangasPage(listOf(details), false)
-                }
-        } else {
-            client.newCall(searchMangaRequest(page, query, filters))
-                .asObservableSuccess()
-                .map { response ->
-                    searchMangaParse(response)
-                }
-        }
-    }
-
-    private class OrderBy : Filter.Select<String>(
-        "Сортировка (только)",
-        arrayOf("Без сортировки", "По году", "По популярности", "Популярно сейчас", "По рейтингу", "Новинки", "По дате обновления")
-    )
-
-    private class Genre(name: String, val id: String) : Filter.TriState(name)
-
-    private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Жанры", genres)
-    private class Category(categories: List<Genre>) : Filter.Group<Genre>("Категории", categories)
-    private class AgeList(ages: List<Genre>) : Filter.Group<Genre>("Возрастная рекомендация", ages)
-    private class More(moren: List<Genre>) : Filter.Group<Genre>("Прочее", moren)
-    private class FilList(fils: List<Genre>) : Filter.Group<Genre>("Фильтры", fils)
-
-    override fun getFilterList() = FilterList(
-        OrderBy(),
-        Category(getCategoryList()),
-        GenreList(getGenreList()),
-        AgeList(getAgeList()),
-        More(getMore()),
-        FilList(getFilList())
-    )
-    private fun getFilList() = listOf(
-        Genre("Высокий рейтинг", "s_high_rate"),
-        Genre("Сингл", "s_single"),
-        Genre("Для взрослых", "s_mature"),
-        Genre("Завершенная", "s_completed"),
-        Genre("Переведено", "s_translated"),
-        Genre("Длинная", "s_many_chapters"),
-        Genre("Ожидает загрузки", "s_wait_upload"),
-    )
-    private fun getMore() = listOf(
-        Genre("В цвете", "el_4614"),
-        Genre("Веб", "el_1355"),
-        Genre("Выпуск приостановлен", "el_5232"),
-        Genre("Не Яой", "el_1874"),
-        Genre("Сборник", "el_1348")
-    )
-
-    private fun getAgeList() = listOf(
-        Genre("R(16+)", "el_3968"),
-        Genre("NC-17(18+)", "el_3969"),
-        Genre("R18+(18+)", "el_3990")
-    )
-
-    private fun getCategoryList() = listOf(
-        Genre("Ёнкома", "el_2741"),
-        Genre("Комикс западный", "el_1903"),
-        Genre("Комикс русский", "el_2173"),
-        Genre("Манхва", "el_1873"),
-        Genre("Маньхуа", "el_1875"),
-        Genre("Ранобэ", "el_5688"),
-    )
-
-    private fun getGenreList() = listOf(
-        Genre("арт", "el_2220"),
-        Genre("бара", "el_1353"),
-        Genre("боевик", "el_1346"),
-        Genre("боевые искусства", "el_1334"),
-        Genre("вампиры", "el_1339"),
-        Genre("гарем", "el_1333"),
-        Genre("гендерная интрига", "el_1347"),
-        Genre("героическое фэнтези", "el_1337"),
-        Genre("детектив", "el_1343"),
-        Genre("дзёсэй", "el_1349"),
-        Genre("додзинси", "el_1332"),
-        Genre("драма", "el_1310"),
-        Genre("игра", "el_5229"),
-        Genre("история", "el_1311"),
-        Genre("киберпанк", "el_1351"),
-        Genre("комедия", "el_1328"),
-        Genre("меха", "el_1318"),
-        Genre("научная фантастика", "el_1325"),
-        Genre("омегаверс", "el_5676"),
-        Genre("повседневность", "el_1327"),
-        Genre("постапокалиптика", "el_1342"),
-        Genre("приключения", "el_1322"),
-        Genre("психология", "el_1335"),
-        Genre("романтика", "el_1313"),
-        Genre("самурайский боевик", "el_1316"),
-        Genre("сверхъестественное", "el_1350"),
-        Genre("сёдзё", "el_1314"),
-        Genre("сёдзё-ай", "el_1320"),
-        Genre("сёнэн", "el_1326"),
-        Genre("сёнэн-ай", "el_1330"),
-        Genre("спорт", "el_1321"),
-        Genre("сэйнэн", "el_1329"),
-        Genre("трагедия", "el_1344"),
-        Genre("триллер", "el_1341"),
-        Genre("ужасы", "el_1317"),
-        Genre("фэнтези", "el_1323"),
-        Genre("школа", "el_1319"),
-        Genre("эротика", "el_1340"),
-        Genre("этти", "el_1354"),
-        Genre("юри", "el_1315"),
-        Genre("яой", "el_1336")
-    )
-    override fun setupPreferenceScreen(screen: androidx.preference.PreferenceScreen) {
-        screen.addPreference(screen.editTextPreference(UAGENT_TITLE, UAGENT_DEFAULT, uagent))
-    }
-
-    private fun androidx.preference.PreferenceScreen.editTextPreference(title: String, default: String, value: String): androidx.preference.EditTextPreference {
-        return androidx.preference.EditTextPreference(context).apply {
-            key = title
-            this.title = title
-            summary = value
-            this.setDefaultValue(default)
-            dialogTitle = title
-            setOnPreferenceChangeListener { _, newValue ->
-                try {
-                    val res = preferences.edit().putString(title, newValue as String).commit()
-                    Toast.makeText(context, "Для смены User-Agent необходимо перезапустить приложение с полной остановкой.", Toast.LENGTH_LONG).show()
-                    res
-                } catch (e: Exception) {
-                    e.printStackTrace()
-                    false
-                }
-            }
-        }
-    }
-    companion object {
-        private const val UAGENT_TITLE = "User-Agent(для некоторых стран)"
-        private const val UAGENT_DEFAULT = "arora"
-        const val PREFIX_SLUG_SEARCH = "slug:"
-    }
-}
diff --git a/src/ru/mintmanga/src/eu/kanade/tachiyomi/extension/ru/mintmanga/MintmangaActivity.kt b/src/ru/mintmanga/src/eu/kanade/tachiyomi/extension/ru/mintmanga/MintmangaActivity.kt
deleted file mode 100644
index 34432a5eb..000000000
--- a/src/ru/mintmanga/src/eu/kanade/tachiyomi/extension/ru/mintmanga/MintmangaActivity.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-package eu.kanade.tachiyomi.extension.ru.mintmanga
-
-import android.app.Activity
-import android.content.ActivityNotFoundException
-import android.content.Intent
-import android.os.Bundle
-import android.util.Log
-import kotlin.system.exitProcess
-/**
- * Springboard that accepts https://mintmanga.live/xxx intents and redirects them to
- * the main tachiyomi process. The idea is to not install the intent filter unless
- * you have this extension installed, but still let the main tachiyomi app control
- * things.
- */
-class MintmangaActivity : Activity() {
-
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-        val pathSegments = intent?.data?.pathSegments
-        if (pathSegments != null && pathSegments.size > 0) {
-            val titleid = pathSegments[0]
-            val mainIntent = Intent().apply {
-                action = "eu.kanade.tachiyomi.SEARCH"
-                putExtra("query", "${Mintmanga.PREFIX_SLUG_SEARCH}$titleid")
-                putExtra("filter", packageName)
-            }
-
-            try {
-                startActivity(mainIntent)
-            } catch (e: ActivityNotFoundException) {
-                Log.e("MintmangaActivity", e.toString())
-            }
-        } else {
-            Log.e("MintmangaaActivity", "could not parse uri from intent $intent")
-        }
-
-        finish()
-        exitProcess(0)
-    }
-}
diff --git a/src/ru/readmanga/AndroidManifest.xml b/src/ru/readmanga/AndroidManifest.xml
deleted file mode 100644
index 711a7fa3e..000000000
--- a/src/ru/readmanga/AndroidManifest.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="eu.kanade.tachiyomi.extension">
-
-    <application>
-        <activity
-            android:name=".ru.readmanga.ReadmangaActivity"
-            android:excludeFromRecents="true"
-            android:exported="true"
-            android:theme="@android:style/Theme.NoDisplay">
-            <intent-filter>
-                <action android:name="android.intent.action.VIEW" />
-
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.BROWSABLE" />
-
-                <!-- ReadmangaActivity sites can be added here. -->
-                <data
-                    android:host="readmanga.io"
-                    android:pathPattern="/..*/vol..*"
-                    android:scheme="https" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/src/ru/readmanga/build.gradle b/src/ru/readmanga/build.gradle
deleted file mode 100644
index ac07bf6a2..000000000
--- a/src/ru/readmanga/build.gradle
+++ /dev/null
@@ -1,11 +0,0 @@
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-
-ext {
-    extName = 'Readmanga'
-    pkgNameSuffix = 'ru.readmanga'
-    extClass = '.Readmanga'
-    extVersionCode = 45
-}
-
-apply from: "$rootDir/common.gradle"
diff --git a/src/ru/readmanga/res/mipmap-hdpi/ic_launcher.png b/src/ru/readmanga/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index 3e550725e..000000000
Binary files a/src/ru/readmanga/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/readmanga/res/mipmap-mdpi/ic_launcher.png b/src/ru/readmanga/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index b3df119e7..000000000
Binary files a/src/ru/readmanga/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/readmanga/res/mipmap-xhdpi/ic_launcher.png b/src/ru/readmanga/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index b3158fb26..000000000
Binary files a/src/ru/readmanga/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/readmanga/res/mipmap-xxhdpi/ic_launcher.png b/src/ru/readmanga/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 35ef8d93a..000000000
Binary files a/src/ru/readmanga/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/readmanga/res/mipmap-xxxhdpi/ic_launcher.png b/src/ru/readmanga/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index e63084ad6..000000000
Binary files a/src/ru/readmanga/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/selfmanga/AndroidManifest.xml b/src/ru/selfmanga/AndroidManifest.xml
deleted file mode 100644
index 30deb7f79..000000000
--- a/src/ru/selfmanga/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest package="eu.kanade.tachiyomi.extension" />
diff --git a/src/ru/selfmanga/build.gradle b/src/ru/selfmanga/build.gradle
deleted file mode 100644
index 4f036c3b7..000000000
--- a/src/ru/selfmanga/build.gradle
+++ /dev/null
@@ -1,11 +0,0 @@
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-
-ext {
-    extName = 'Selfmanga'
-    pkgNameSuffix = 'ru.selfmanga'
-    extClass = '.Selfmanga'
-    extVersionCode = 22
-}
-
-apply from: "$rootDir/common.gradle"
diff --git a/src/ru/selfmanga/res/mipmap-hdpi/ic_launcher.png b/src/ru/selfmanga/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index b66a27888..000000000
Binary files a/src/ru/selfmanga/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/selfmanga/res/mipmap-mdpi/ic_launcher.png b/src/ru/selfmanga/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 4feafbdc7..000000000
Binary files a/src/ru/selfmanga/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/selfmanga/res/mipmap-xhdpi/ic_launcher.png b/src/ru/selfmanga/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index 9677de7dd..000000000
Binary files a/src/ru/selfmanga/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/selfmanga/res/mipmap-xxhdpi/ic_launcher.png b/src/ru/selfmanga/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 1c86beed1..000000000
Binary files a/src/ru/selfmanga/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/selfmanga/res/mipmap-xxxhdpi/ic_launcher.png b/src/ru/selfmanga/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index 58d7f343c..000000000
Binary files a/src/ru/selfmanga/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/src/ru/selfmanga/res/web_hi_res_512.png b/src/ru/selfmanga/res/web_hi_res_512.png
deleted file mode 100644
index 52aa54712..000000000
Binary files a/src/ru/selfmanga/res/web_hi_res_512.png and /dev/null differ
diff --git a/src/ru/selfmanga/src/eu/kanade/tachiyomi/extension/ru/selfmanga/Selfmanga.kt b/src/ru/selfmanga/src/eu/kanade/tachiyomi/extension/ru/selfmanga/Selfmanga.kt
deleted file mode 100644
index 3641440b4..000000000
--- a/src/ru/selfmanga/src/eu/kanade/tachiyomi/extension/ru/selfmanga/Selfmanga.kt
+++ /dev/null
@@ -1,266 +0,0 @@
-package eu.kanade.tachiyomi.extension.ru.selfmanga
-
-import eu.kanade.tachiyomi.network.GET
-import eu.kanade.tachiyomi.network.interceptor.rateLimit
-import eu.kanade.tachiyomi.source.model.Filter
-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 okhttp3.Headers
-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 java.io.IOException
-import java.text.DecimalFormat
-import java.text.ParseException
-import java.text.SimpleDateFormat
-import java.util.Locale
-import java.util.regex.Pattern
-
-class Selfmanga : ParsedHttpSource() {
-
-    override val name = "Selfmanga"
-
-    override val baseUrl = "https://selfmanga.live"
-
-    override val lang = "ru"
-
-    override val supportsLatest = true
-
-    override val client: OkHttpClient = network.client.newBuilder()
-        .rateLimit(2)
-        .addNetworkInterceptor { chain ->
-            val originalRequest = chain.request()
-            val response = chain.proceed(originalRequest)
-            if (originalRequest.url.toString().contains(baseUrl) and (originalRequest.url.toString().contains("internal/redirect") or (response.code == 301)))
-                throw IOException("Манга переехала на другой адрес/ссылку!")
-            response
-        }
-        .build()
-
-    override fun popularMangaSelector() = "div.tile"
-
-    override fun latestUpdatesSelector() = popularMangaSelector()
-
-    override fun popularMangaRequest(page: Int): Request =
-        GET("$baseUrl/list?sortType=rate&offset=${70 * (page - 1)}", headers)
-
-    override fun latestUpdatesRequest(page: Int): Request =
-        GET("$baseUrl/list?sortType=updated&offset=${70 * (page - 1)}", headers)
-
-    override fun popularMangaFromElement(element: Element): SManga {
-        val manga = SManga.create()
-        manga.thumbnail_url = element.select("img.lazy").first()?.attr("data-original")?.replace("_p.", ".")
-        element.select("h3 > a").first().let {
-            manga.setUrlWithoutDomain(it.attr("href"))
-            manga.title = it.attr("title")
-        }
-        return manga
-    }
-
-    override fun latestUpdatesFromElement(element: Element): SManga =
-        popularMangaFromElement(element)
-
-    override fun popularMangaNextPageSelector() = "a.nextLink"
-
-    override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector()
-
-    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
-        val url = "$baseUrl/search/advanced".toHttpUrlOrNull()!!.newBuilder()
-        (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
-            when (filter) {
-                is GenreList -> filter.state.forEach { genre ->
-                    if (genre.state != Filter.TriState.STATE_IGNORE) {
-                        url.addQueryParameter(genre.id, arrayOf("=", "=in", "=ex")[genre.state])
-                    }
-                }
-                is Category -> filter.state.forEach { category ->
-                    if (category.state != Filter.TriState.STATE_IGNORE) {
-                        url.addQueryParameter(category.id, arrayOf("=", "=in", "=ex")[category.state])
-                    }
-                }
-            }
-        }
-        if (query.isNotEmpty()) {
-            url.addQueryParameter("q", query)
-        }
-        return GET(url.toString().replace("=%3D", "="), headers)
-    }
-
-    override fun searchMangaSelector() = popularMangaSelector()
-
-    override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element)
-
-    // max 200 results
-    override fun searchMangaNextPageSelector(): Nothing? = null
-
-    override fun mangaDetailsParse(document: Document): SManga {
-        val infoElement = document.select(".expandable").first()
-
-        val manga = SManga.create()
-        manga.title = document.select("h1.names .name").text()
-        manga.author = infoElement.select("span.elem_author").first()?.text()
-        manga.genre = infoElement.select("span.elem_genre").text().split(",").joinToString { it.trim() }
-        manga.description = document.select("div#tab-description  .manga-description").text()
-        manga.status = parseStatus(infoElement.html())
-        manga.thumbnail_url = infoElement.select("img").attr("data-full")
-        return manga
-    }
-
-    private fun parseStatus(element: String): Int = when {
-        element.contains("Запрещена публикация произведения по копирайту") || element.contains("ЗАПРЕЩЕНА К ПУБЛИКАЦИИ НА ТЕРРИТОРИИ РФ!") -> SManga.LICENSED
-        element.contains("<b>Перевод:</b> продолжается") -> SManga.ONGOING
-        element.contains("<b>Сингл</b>") || element.contains(", завер") -> SManga.COMPLETED
-        else -> SManga.UNKNOWN
-    }
-
-    override fun chapterListSelector() = "div.chapters-link > table > tbody > tr:has(td > a):has(td.date:not(.text-info))"
-
-    override fun chapterFromElement(element: Element): SChapter {
-        val urlElement = element.select("a").first()
-        val chapterInf = element.select("td.item-title").first()
-        val urlText = urlElement.text()
-
-        val chapter = SChapter.create()
-        chapter.setUrlWithoutDomain(urlElement.attr("href") + "?mtr=true") // mtr is 18+ skip
-        if (urlText.endsWith(" новое")) {
-            chapter.name = urlText.dropLast(6)
-        } else {
-            chapter.name = urlText
-        }
-
-        chapter.chapter_number = chapterInf.attr("data-num").toFloat() / 10
-
-        chapter.date_upload = element.select("td.d-none").last()?.text()?.let {
-            try {
-                SimpleDateFormat("dd/MM/yy", Locale.US).parse(it)?.time ?: 0L
-            } catch (e: ParseException) {
-                SimpleDateFormat("dd.MM.yy", Locale.US).parse(it)?.time ?: 0L
-            }
-        } ?: 0
-        return chapter
-    }
-
-    override fun prepareNewChapter(chapter: SChapter, manga: SManga) {
-        val extra = Regex("""\s*([0-9]+\sЭкстра)\s*""")
-        val single = Regex("""\s*Сингл\s*""")
-        when {
-            extra.containsMatchIn(chapter.name) -> {
-                if (chapter.name.substringAfter("Экстра").trim().isEmpty())
-                    chapter.name = chapter.name.replaceFirst(" ", " - " + DecimalFormat("#,###.##").format(chapter.chapter_number).replace(",", ".") + " ")
-            }
-
-            single.containsMatchIn(chapter.name) -> {
-                if (chapter.name.substringAfter("Сингл").trim().isEmpty())
-                    chapter.name = DecimalFormat("#,###.##").format(chapter.chapter_number).replace(",", ".") + " " + chapter.name
-            }
-        }
-    }
-
-    override fun pageListParse(response: Response): List<Page> {
-        val html = response.body!!.string()
-        val beginIndex = html.indexOf("rm_h.initReader( [")
-        val endIndex = html.indexOf(");", beginIndex)
-        val trimmedHtml = html.substring(beginIndex, endIndex)
-
-        val p = Pattern.compile("'.*?','.*?',\".*?\"")
-        val m = p.matcher(trimmedHtml)
-
-        val pages = mutableListOf<Page>()
-
-        var i = 0
-        while (m.find()) {
-            val urlParts = m.group().replace("[\"\']+".toRegex(), "").split(',')
-            val url = if (urlParts[1].isEmpty() && urlParts[2].startsWith("/static/")) {
-                baseUrl + urlParts[2]
-            } else {
-                if (urlParts[1].endsWith("/manga/")) {
-                    urlParts[0] + urlParts[2]
-                } else {
-                    urlParts[1] + urlParts[0] + urlParts[2]
-                }
-            }
-            pages.add(Page(i++, "", url))
-        }
-        return pages
-    }
-
-    override fun pageListParse(document: Document): List<Page> {
-        throw Exception("Not used")
-    }
-
-    override fun imageUrlParse(document: Document) = ""
-
-    override fun imageRequest(page: Page): Request {
-        val imgHeader = Headers.Builder().apply {
-            add("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64)")
-            add("Referer", baseUrl)
-        }.build()
-        return GET(page.imageUrl!!, imgHeader)
-    }
-
-    private class Genre(name: String, val id: String) : Filter.TriState(name)
-    private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Genres", genres)
-    private class Category(categories: List<Genre>) : Filter.Group<Genre>("Category", categories)
-
-    /* [...document.querySelectorAll("tr.advanced_option:nth-child(1) > td:nth-child(3) span.js-link")]
-    *  .map(el => `Genre("${el.textContent.trim()}", $"{el.getAttribute('onclick')
-    *  .substr(31,el.getAttribute('onclick').length-33)"})`).join(',\n')
-    *  on https://selfmanga.ru/search/advanced
-    */
-    override fun getFilterList() = FilterList(
-        Category(getCategoryList()),
-        GenreList(getGenreList())
-    )
-
-    private fun getCategoryList() = listOf(
-        Genre("Артбук", "el_5894"),
-        Genre("Веб", "el_2160"),
-        Genre("Журнал", "el_4983"),
-        Genre("Ранобэ", "el_5215"),
-        Genre("Сборник", "el_2157")
-    )
-
-    private fun getGenreList() = listOf(
-        Genre("боевик", "el_2155"),
-        Genre("боевые искусства", "el_2143"),
-        Genre("вампиры", "el_2148"),
-        Genre("гарем", "el_2142"),
-        Genre("гендерная интрига", "el_2156"),
-        Genre("героическое фэнтези", "el_2146"),
-        Genre("детектив", "el_2152"),
-        Genre("дзёсэй", "el_2158"),
-        Genre("додзинси", "el_2141"),
-        Genre("драма", "el_2118"),
-        Genre("ёнкома", "el_2161"),
-        Genre("история", "el_2119"),
-        Genre("комедия", "el_2136"),
-        Genre("махо-сёдзё", "el_2147"),
-        Genre("мистика", "el_2132"),
-        Genre("научная фантастика", "el_2133"),
-        Genre("повседневность", "el_2135"),
-        Genre("постапокалиптика", "el_2151"),
-        Genre("приключения", "el_2130"),
-        Genre("психология", "el_2144"),
-        Genre("романтика", "el_2121"),
-        Genre("сверхъестественное", "el_2159"),
-        Genre("сёдзё", "el_2122"),
-        Genre("сёдзё-ай", "el_2128"),
-        Genre("сёнэн", "el_2134"),
-        Genre("сёнэн-ай", "el_2139"),
-        Genre("спорт", "el_2129"),
-        Genre("сэйнэн", "el_5838"),
-        Genre("трагедия", "el_2153"),
-        Genre("триллер", "el_2150"),
-        Genre("ужасы", "el_2125"),
-        Genre("фантастика", "el_2140"),
-        Genre("фэнтези", "el_2131"),
-        Genre("школа", "el_2127"),
-        Genre("этти", "el_4982")
-    )
-}