Fix sources and add Asura Scans TR for wpmangastream (#8983)
* Phoenix Fansub: Fix manga urls and chapter dates * Mihentai: Fix extension * AsuraScans: Convert to multilang, adding TR source
This commit is contained in:
parent
4598685c2c
commit
0924c076d9
|
@ -1,28 +0,0 @@
|
||||||
package eu.kanade.tachiyomi.extension.en.asurascans
|
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
|
|
||||||
import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream
|
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import org.jsoup.nodes.Document
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
class AsuraScans : WPMangaStream("AsuraScans", "https://www.asurascans.com", "en") {
|
|
||||||
|
|
||||||
private val rateLimitInterceptor = RateLimitInterceptor(1, 3, TimeUnit.SECONDS)
|
|
||||||
|
|
||||||
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
|
|
||||||
.connectTimeout(10, TimeUnit.SECONDS)
|
|
||||||
.readTimeout(30, TimeUnit.SECONDS)
|
|
||||||
.addNetworkInterceptor(rateLimitInterceptor)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
override val pageSelector = "div.rdminimal img[loading*=lazy]"
|
|
||||||
|
|
||||||
// Skip scriptPages
|
|
||||||
override fun pageListParse(document: Document): List<Page> {
|
|
||||||
return document.select(pageSelector)
|
|
||||||
.filterNot { it.attr("abs:src").isNullOrEmpty() }
|
|
||||||
.mapIndexed { i, img -> Page(i, "", img.attr("abs:src")) }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
package eu.kanade.tachiyomi.extension.all.asurascans
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
|
||||||
|
import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream
|
||||||
|
import eu.kanade.tachiyomi.source.SourceFactory
|
||||||
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import org.jsoup.nodes.Document
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Locale
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
class AsuraScansFactory : SourceFactory {
|
||||||
|
override fun createSources() = listOf(
|
||||||
|
AsuraScansEn(),
|
||||||
|
AsuraScansTr()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class AsuraScans(
|
||||||
|
override val baseUrl: String,
|
||||||
|
override val lang: String,
|
||||||
|
dateFormat: SimpleDateFormat
|
||||||
|
) : WPMangaStream("Asura Scans", baseUrl, lang, dateFormat) {
|
||||||
|
private val rateLimitInterceptor = RateLimitInterceptor(1, 3, TimeUnit.SECONDS)
|
||||||
|
|
||||||
|
override val client: OkHttpClient = network.cloudflareClient.newBuilder()
|
||||||
|
.connectTimeout(10, TimeUnit.SECONDS)
|
||||||
|
.readTimeout(30, TimeUnit.SECONDS)
|
||||||
|
.addNetworkInterceptor(rateLimitInterceptor)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
class AsuraScansEn : AsuraScans("https://asurascans.com/", "en", SimpleDateFormat("MMM d, yyyy", Locale.US)) {
|
||||||
|
override val pageSelector = "div.rdminimal img[loading*=lazy]"
|
||||||
|
|
||||||
|
// Skip scriptPages
|
||||||
|
override fun pageListParse(document: Document): List<Page> {
|
||||||
|
return document.select(pageSelector)
|
||||||
|
.filterNot { it.attr("abs:src").isNullOrEmpty() }
|
||||||
|
.mapIndexed { i, img -> Page(i, "", img.attr("abs:src")) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AsuraScansTr : AsuraScans("https://tr.asurascans.com/", "tr", SimpleDateFormat("MMM d, yyyy", Locale("tr"))) {
|
||||||
|
override fun mangaDetailsParse(document: Document): SManga {
|
||||||
|
return SManga.create().apply {
|
||||||
|
document.select("div.bigcontent").firstOrNull()?.let { infoElement ->
|
||||||
|
status = parseStatus(infoElement.select(".imptdt:contains(Durum) i").firstOrNull()?.ownText())
|
||||||
|
infoElement.select(".fmed b:contains(Yazar)+span").firstOrNull()?.ownText().let {
|
||||||
|
if (it.isNullOrBlank().not() && it != "N/A" && it != "-") {
|
||||||
|
author = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
infoElement.select(".fmed b:contains(Çizer)+span").firstOrNull()?.ownText().let {
|
||||||
|
if (it.isNullOrBlank().not() && it != "N/A" && it != "-") {
|
||||||
|
artist = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
description = infoElement.select("div.desc p, div.entry-content p").joinToString("\n") { it.text() }
|
||||||
|
thumbnail_url = infoElement.select("div.thumb img").imgAttr()
|
||||||
|
|
||||||
|
val genres = infoElement.select(".mgen a")
|
||||||
|
.map { element -> element.text().toLowerCase(Locale.ROOT) }
|
||||||
|
.toMutableSet()
|
||||||
|
|
||||||
|
// add series type(manga/manhwa/manhua/other) thinggy to genre
|
||||||
|
document.select(seriesTypeSelector).firstOrNull()?.ownText()?.let {
|
||||||
|
if (it.isEmpty().not() && genres.contains(it).not()) {
|
||||||
|
genres.add(it.toLowerCase(Locale.ROOT))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
genre = genres.toList().map { it.capitalize(Locale.ROOT) }.joinToString(", ")
|
||||||
|
|
||||||
|
// add alternative name to manga description
|
||||||
|
document.select(altNameSelector).firstOrNull()?.ownText()?.let {
|
||||||
|
if (it.isBlank().not() && it != "N/A" && it != "-") {
|
||||||
|
description = when {
|
||||||
|
description.isNullOrBlank() -> altName + it
|
||||||
|
else -> description + "\n\n$altName" + it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override val seriesTypeSelector = ".imptdt:contains(Tür) a"
|
||||||
|
override val altName: String = "Alternatif isim: "
|
||||||
|
|
||||||
|
override fun parseStatus(element: String?): Int = when {
|
||||||
|
element == null -> SManga.UNKNOWN
|
||||||
|
listOf("Devam Ediyor").any { it.contains(element, ignoreCase = true) } -> SManga.ONGOING
|
||||||
|
listOf("Tamamlandı").any { it.contains(element, ignoreCase = true) } -> SManga.COMPLETED
|
||||||
|
else -> SManga.UNKNOWN
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,180 @@ package eu.kanade.tachiyomi.extension.en.mihentai
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.annotations.Nsfw
|
import eu.kanade.tachiyomi.annotations.Nsfw
|
||||||
import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream
|
import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream
|
||||||
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
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.SManga
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.jsonArray
|
||||||
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
|
import okhttp3.Request
|
||||||
|
import org.jsoup.nodes.Document
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
@Nsfw
|
@Nsfw
|
||||||
class Mihentai : WPMangaStream("Mihentai", "https://mihentai.com", "en")
|
class Mihentai : WPMangaStream("Mihentai", "https://mihentai.com", "en") {
|
||||||
|
override fun popularMangaRequest(page: Int): Request {
|
||||||
|
return GET("$baseUrl/manga/page/$page/?order=popular", headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun latestUpdatesRequest(page: Int): Request {
|
||||||
|
return GET("$baseUrl/manga/page/$page/?order=update", headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
|
val url = "$baseUrl/manga/page/$page/".toHttpUrlOrNull()!!.newBuilder()
|
||||||
|
url.addQueryParameter("title", query)
|
||||||
|
filters.forEach { filter ->
|
||||||
|
when (filter) {
|
||||||
|
is StatusFilter -> url.addQueryParameter("status", filter.toUriPart())
|
||||||
|
is TypeFilter -> url.addQueryParameter("type", filter.toUriPart())
|
||||||
|
is SortByFilter -> url.addQueryParameter("order", filter.toUriPart())
|
||||||
|
is GenreListFilter -> {
|
||||||
|
filter.state
|
||||||
|
.filter { it.state != Filter.TriState.STATE_IGNORE }
|
||||||
|
.forEach { url.addQueryParameter("genre[]", it.id) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return GET(url.build().toString(), headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mangaDetailsParse(document: Document): SManga {
|
||||||
|
return SManga.create().apply {
|
||||||
|
document.select("div.bigcontent, div.animefull, div.main-info").firstOrNull()?.let { infoElement ->
|
||||||
|
status = parseStatus(infoElement.select("span:contains(Status:), .imptdt:contains(Status) i").firstOrNull()?.ownText())
|
||||||
|
thumbnail_url = infoElement.select("div.thumb img").imgAttr()
|
||||||
|
|
||||||
|
val genres = infoElement.select("span:contains(Tag) a")
|
||||||
|
.map { element -> element.text().toLowerCase(Locale.ROOT) }
|
||||||
|
.toMutableSet()
|
||||||
|
|
||||||
|
// add series type(manga/manhwa/manhua/other) thinggy to genre
|
||||||
|
document.select("span:contains(Type)").firstOrNull()?.ownText()?.let {
|
||||||
|
if (it.isEmpty().not() && genres.contains(it).not()) {
|
||||||
|
genres.add(it.toLowerCase(Locale.ROOT))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
genre = genres.toList().joinToString(", ") { it.capitalize(Locale.ROOT) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun parseStatus(element: String?): Int = when {
|
||||||
|
element == null -> SManga.UNKNOWN
|
||||||
|
listOf("ongoing", "publishing").any { it.contains(element, ignoreCase = true) } -> SManga.ONGOING
|
||||||
|
listOf("finished").any { it.contains(element, ignoreCase = true) } -> SManga.COMPLETED
|
||||||
|
else -> SManga.UNKNOWN
|
||||||
|
}
|
||||||
|
|
||||||
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
|
override fun pageListParse(document: Document): List<Page> {
|
||||||
|
val htmlPages = document.select(pageSelector)
|
||||||
|
.filterNot { it.attr("abs:src").isNullOrEmpty() }
|
||||||
|
.mapIndexed { i, img ->
|
||||||
|
val pageUrl = img.attr("abs:src").substringAfter(baseUrl).prependIndent(baseUrl)
|
||||||
|
Page(i, "", pageUrl)
|
||||||
|
}
|
||||||
|
.toMutableList()
|
||||||
|
|
||||||
|
val docString = document.toString()
|
||||||
|
val imageListRegex = Regex("\\\"images.*?:.*?(\\[.*?\\])")
|
||||||
|
val imageListJson = imageListRegex.find(docString)?.destructured?.toList()?.get(0)
|
||||||
|
if (imageListJson != null) {
|
||||||
|
val imageList = json.parseToJsonElement(imageListJson).jsonArray
|
||||||
|
val baseResolver = baseUrl.toHttpUrl()
|
||||||
|
|
||||||
|
val scriptPages = imageList.mapIndexed { i, jsonEl ->
|
||||||
|
val imageUrl = jsonEl.jsonPrimitive.content
|
||||||
|
Page(i, "", baseResolver.resolve(imageUrl).toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (htmlPages.size < scriptPages.size) {
|
||||||
|
htmlPages += scriptPages
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
countViews(document)
|
||||||
|
|
||||||
|
return htmlPages.distinctBy { it.imageUrl }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class StatusFilter : UriPartFilter(
|
||||||
|
"Status",
|
||||||
|
arrayOf(
|
||||||
|
Pair("All", ""),
|
||||||
|
Pair("Publishing", "publishing"),
|
||||||
|
Pair("Finished", "finished"),
|
||||||
|
Pair("Dropped", "drop")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
private class TypeFilter : UriPartFilter(
|
||||||
|
"Type",
|
||||||
|
arrayOf(
|
||||||
|
Pair("Default", ""),
|
||||||
|
Pair("Manga", "Manga"),
|
||||||
|
Pair("Manhwa", "Manhwa"),
|
||||||
|
Pair("Manhua", "Manhua"),
|
||||||
|
Pair("Webtoon", "webtoon"),
|
||||||
|
Pair("One-Shot", "One-Shot"),
|
||||||
|
Pair("Doujin", "doujin")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun getFilterList(): FilterList = FilterList(
|
||||||
|
listOf(
|
||||||
|
StatusFilter(),
|
||||||
|
TypeFilter(),
|
||||||
|
SortByFilter(),
|
||||||
|
GenreListFilter(getGenreList())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun getGenreList(): List<Genre> = listOf(
|
||||||
|
Genre("Adventure", "adventure"),
|
||||||
|
Genre("Ahego", "ahego"),
|
||||||
|
Genre("Anal", "anal"),
|
||||||
|
Genre("Battle", "battle"),
|
||||||
|
Genre("Big Breasts", "big-breasts"),
|
||||||
|
Genre("Blowjob", "blowjob"),
|
||||||
|
Genre("Comic 3D", "comic-3d"),
|
||||||
|
Genre("Doujin", "doujin"),
|
||||||
|
Genre("Dragon ball", "dragon-ball"),
|
||||||
|
Genre("Fingering", "fingering"),
|
||||||
|
Genre("Full color", "full-color"),
|
||||||
|
Genre("Futanari", "futanari"),
|
||||||
|
Genre("Girlfriend", "girlfriend"),
|
||||||
|
Genre("Grouped", "grouped"),
|
||||||
|
Genre("Handjob", "handjob"),
|
||||||
|
Genre("Hijab", "hijab"),
|
||||||
|
Genre("Incest", "incest"),
|
||||||
|
Genre("Kissing", "kissing"),
|
||||||
|
Genre("Mama", "mama"),
|
||||||
|
Genre("Manga", "manga"),
|
||||||
|
Genre("Masturbation", "masturbation"),
|
||||||
|
Genre("Milf", "milf"),
|
||||||
|
Genre("Mom & Son", "mom-son"),
|
||||||
|
Genre("Naruto", "naruto"),
|
||||||
|
Genre("One Piece", "one-piece"),
|
||||||
|
Genre("Pregnancy", "pregnancy"),
|
||||||
|
Genre("Rape", "rape"),
|
||||||
|
Genre("Romance", "romance"),
|
||||||
|
Genre("School", "school"),
|
||||||
|
Genre("Scooby-Doo", "scooby-doo"),
|
||||||
|
Genre("Sister", "sister"),
|
||||||
|
Genre("Stocking", "stocking"),
|
||||||
|
Genre("Sub Indo", "sub-indo"),
|
||||||
|
Genre("Threesome", "threesome"),
|
||||||
|
Genre("Uncensored", "uncensored"),
|
||||||
|
Genre("Western", "western"),
|
||||||
|
Genre("Yuri", "yuri")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package eu.kanade.tachiyomi.extension.es.phoenixfansub
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream
|
||||||
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
import org.jsoup.nodes.Element
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
class PhoenixFansub : WPMangaStream(
|
||||||
|
"Phoenix Fansub",
|
||||||
|
"https://phoenixfansub.com",
|
||||||
|
"es",
|
||||||
|
SimpleDateFormat("MMM d, yyyy", Locale("es"))
|
||||||
|
) {
|
||||||
|
override fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {
|
||||||
|
thumbnail_url = element.select("div.limit img").imgAttr()
|
||||||
|
element.select("div.bsx > a").first().let {
|
||||||
|
url = "/manga/${it.attr("href")}"
|
||||||
|
title = it.attr("title")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override val altName: String = "Nombre alternativo: "
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package eu.kanade.tachiyomi.multisrc.wpmangastream
|
package eu.kanade.tachiyomi.multisrc.wpmangastream
|
||||||
|
|
||||||
|
import generator.ThemeSourceData.MultiLang
|
||||||
import generator.ThemeSourceData.SingleLang
|
import generator.ThemeSourceData.SingleLang
|
||||||
import generator.ThemeSourceGenerator
|
import generator.ThemeSourceGenerator
|
||||||
|
|
||||||
|
@ -12,7 +13,7 @@ class WPMangaStreamGenerator : ThemeSourceGenerator {
|
||||||
override val baseVersionCode: Int = 11
|
override val baseVersionCode: Int = 11
|
||||||
|
|
||||||
override val sources = listOf(
|
override val sources = listOf(
|
||||||
SingleLang("Asura Scans", "https://www.asurascans.com", "en", overrideVersionCode = 5),
|
MultiLang("Asura Scans", "https://www.asurascans.com", listOf("en", "tr"), className = "AsuraScansFactory", pkgName = "asurascans", overrideVersionCode = 6),
|
||||||
SingleLang("KlanKomik", "https://klankomik.com", "id", overrideVersionCode = 1),
|
SingleLang("KlanKomik", "https://klankomik.com", "id", overrideVersionCode = 1),
|
||||||
SingleLang("MasterKomik", "https://masterkomik.com", "id", overrideVersionCode = 1),
|
SingleLang("MasterKomik", "https://masterkomik.com", "id", overrideVersionCode = 1),
|
||||||
SingleLang("Kaisar Komik", "https://kaisarkomik.com", "id", overrideVersionCode = 1),
|
SingleLang("Kaisar Komik", "https://kaisarkomik.com", "id", overrideVersionCode = 1),
|
||||||
|
@ -35,7 +36,7 @@ class WPMangaStreamGenerator : ThemeSourceGenerator {
|
||||||
SingleLang("MangaSwat", "https://mangaswat.com", "ar", overrideVersionCode = 3),
|
SingleLang("MangaSwat", "https://mangaswat.com", "ar", overrideVersionCode = 3),
|
||||||
SingleLang("Manga Raw.org", "https://mangaraw.org", "ja", className = "MangaRawOrg", overrideVersionCode = 1),
|
SingleLang("Manga Raw.org", "https://mangaraw.org", "ja", className = "MangaRawOrg", overrideVersionCode = 1),
|
||||||
SingleLang("Manga Pro Z", "https://mangaproz.com", "ar"),
|
SingleLang("Manga Pro Z", "https://mangaproz.com", "ar"),
|
||||||
SingleLang("Mihentai", "https://mihentai.com", "en", isNsfw = true),
|
SingleLang("Mihentai", "https://mihentai.com", "en", isNsfw = true, overrideVersionCode = 1),
|
||||||
SingleLang("Kuma Scans (Kuma Translation)", "https://kumascans.com", "en", className = "KumaScans", overrideVersionCode = 1),
|
SingleLang("Kuma Scans (Kuma Translation)", "https://kumascans.com", "en", className = "KumaScans", overrideVersionCode = 1),
|
||||||
SingleLang("Tempest Manga", "https://manga.tempestfansub.com", "tr"),
|
SingleLang("Tempest Manga", "https://manga.tempestfansub.com", "tr"),
|
||||||
SingleLang("xCaliBR Scans", "https://xcalibrscans.com", "en", overrideVersionCode = 2),
|
SingleLang("xCaliBR Scans", "https://xcalibrscans.com", "en", overrideVersionCode = 2),
|
||||||
|
@ -44,7 +45,7 @@ class WPMangaStreamGenerator : ThemeSourceGenerator {
|
||||||
SingleLang("The Apollo Team", "https://theapollo.team", "en"),
|
SingleLang("The Apollo Team", "https://theapollo.team", "en"),
|
||||||
SingleLang("Sekte Doujin", "https://sektedoujin.xyz", "id", isNsfw = true, overrideVersionCode = 2),
|
SingleLang("Sekte Doujin", "https://sektedoujin.xyz", "id", isNsfw = true, overrideVersionCode = 2),
|
||||||
SingleLang("Lemon Juice Scan", "https://lemonjuicescan.com", "pt-BR", isNsfw = true, overrideVersionCode = 1),
|
SingleLang("Lemon Juice Scan", "https://lemonjuicescan.com", "pt-BR", isNsfw = true, overrideVersionCode = 1),
|
||||||
SingleLang("Phoenix Fansub", "https://phoenixfansub.com", "es"),
|
SingleLang("Phoenix Fansub", "https://phoenixfansub.com", "es", overrideVersionCode = 1),
|
||||||
SingleLang("Geass Scanlator", "https://geassscan.xyz", "pt-BR", overrideVersionCode = 2),
|
SingleLang("Geass Scanlator", "https://geassscan.xyz", "pt-BR", overrideVersionCode = 2),
|
||||||
SingleLang("Imagine Scan", "https://imaginescan.com.br", "pt-BR", isNsfw = true),
|
SingleLang("Imagine Scan", "https://imaginescan.com.br", "pt-BR", isNsfw = true),
|
||||||
SingleLang("Vapo Scan", "https://vaposcans.com", "pt-BR", overrideVersionCode = 2),
|
SingleLang("Vapo Scan", "https://vaposcans.com", "pt-BR", overrideVersionCode = 2),
|
||||||
|
|
Loading…
Reference in New Issue