From ca27731aa8a24e84eac8a032b310eb0fe90a5dec Mon Sep 17 00:00:00 2001 From: Alessandro Jean Date: Wed, 9 Jun 2021 18:46:25 -0300 Subject: [PATCH] Fix broken search and chapter images at MP. (#7580) --- src/all/mangapark/build.gradle | 2 +- .../extension/all/mangapark/MangaPark.kt | 376 +++++++++--------- .../all/mangapark/MangaParkFactory.kt | 14 +- 3 files changed, 186 insertions(+), 206 deletions(-) diff --git a/src/all/mangapark/build.gradle b/src/all/mangapark/build.gradle index 83b727bc9..70fc832be 100644 --- a/src/all/mangapark/build.gradle +++ b/src/all/mangapark/build.gradle @@ -6,7 +6,7 @@ ext { extName = 'MangaPark v3' pkgNameSuffix = 'all.mangapark' extClass = '.MangaParkFactory' - extVersionCode = 5 + extVersionCode = 6 libVersion = '1.2' containsNsfw = true } diff --git a/src/all/mangapark/src/eu/kanade/tachiyomi/extension/all/mangapark/MangaPark.kt b/src/all/mangapark/src/eu/kanade/tachiyomi/extension/all/mangapark/MangaPark.kt index 0409569a6..b949f1501 100644 --- a/src/all/mangapark/src/eu/kanade/tachiyomi/extension/all/mangapark/MangaPark.kt +++ b/src/all/mangapark/src/eu/kanade/tachiyomi/extension/all/mangapark/MangaPark.kt @@ -14,50 +14,50 @@ import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.util.asJsoup import kotlinx.serialization.json.Json import kotlinx.serialization.json.buildJsonObject -import kotlinx.serialization.json.jsonArray +import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive import kotlinx.serialization.json.put import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient -import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.Request +import okhttp3.RequestBody.Companion.toRequestBody +import okhttp3.Response import org.jsoup.Jsoup import org.jsoup.nodes.Document import org.jsoup.nodes.Element -import java.util.Calendar -import java.util.concurrent.TimeUnit -import okhttp3.Response import rx.Observable import uy.kohesive.injekt.injectLazy +import java.util.Calendar +import java.util.concurrent.TimeUnit open class MangaPark( override val lang: String, private val siteLang: String ) : ParsedHttpSource() { - - override val name : String = "MangaPark v3" - - override val baseUrl : String = "https://mangapark.net" - - override val supportsLatest = true - - private val json : Json by injectLazy() - - override val client : OkHttpClient = network.cloudflareClient.newBuilder() + + override val name: String = "MangaPark v3" + + override val baseUrl: String = "https://mangapark.net" + + override val supportsLatest = true + + private val json: Json by injectLazy() + + override val client: OkHttpClient = network.cloudflareClient.newBuilder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .build() - + override fun latestUpdatesRequest(page: Int): Request { return GET("$baseUrl/browse?sort=update&page=$page") } - + override fun latestUpdatesSelector(): String { return "div#subject-list div.col" } - + override fun latestUpdatesFromElement(element: Element): SManga { return SManga.create().apply { setUrlWithoutDomain(element.select("a.fw-bold").attr("href")) @@ -65,19 +65,19 @@ open class MangaPark( thumbnail_url = element.select("a.position-relative img").attr("abs:src") } } - + override fun latestUpdatesNextPageSelector() = "div#mainer nav.d-none .pagination .page-item:last-of-type:not(.disabled)" - + override fun popularMangaRequest(page: Int): Request { return GET("$baseUrl/browse?sort=d007&page=$page") } - + override fun popularMangaSelector() = latestUpdatesSelector() - + override fun popularMangaFromElement(element: Element) = latestUpdatesFromElement(element) - + override fun popularMangaNextPageSelector() = latestUpdatesNextPageSelector() - + override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable { return when { query.startsWith(PREFIX_ID_SEARCH) -> { @@ -87,15 +87,15 @@ open class MangaPark( mangaFromID(response, id) } } - + query.isNotBlank() -> { val url = "$baseUrl/search?word=$query&page=$page" client.newCall(GET(url, headers)).asObservableSuccess() .map { response -> - searchParse(response) + searchMangaParse(response) } } - + else -> { val sortFilter = filters.findInstance()!! val reverseSortFilter = filters.findInstance()!! @@ -105,21 +105,22 @@ open class MangaPark( val maxChapterFilter = filters.findInstance()!! val url = "$baseUrl/browse".toHttpUrlOrNull()!!.newBuilder() url.addQueryParameter("page", page.toString()) - - with (sortFilter) { + + with(sortFilter) { if (reverseSortFilter.state) { - url.addQueryParameter("sort","${this.selected}.az") + url.addQueryParameter("sort", "${this.selected}.az") } else { - url.addQueryParameter("sort","${this.selected}.za") + url.addQueryParameter("sort", "${this.selected}.za") } } - - with (genreFilter) { - url.addQueryParameter("genres", included.joinToString(",") + "|" + excluded.joinToString(",") + + with(genreFilter) { + url.addQueryParameter( + "genres", included.joinToString(",") + "|" + excluded.joinToString(",") ) } - with (statusFilter) { + with(statusFilter) { url.addQueryParameter("release", this.selected) } @@ -129,12 +130,12 @@ open class MangaPark( client.newCall(GET(url.build().toString(), headers)).asObservableSuccess() .map { response -> - searchParse(response) + searchMangaParse(response) } } } } - + private fun mangaFromID(response: Response, id: String): MangasPage { val infoElement = response.asJsoup().select("div#mainer div.container-fluid") val manga = SManga.create().apply { @@ -146,41 +147,30 @@ open class MangaPark( return MangasPage(listOf(manga), false) } - private fun searchParse(response: Response): MangasPage { - val mangas = mutableListOf() - - response.asJsoup().select("div#search-list div.col").forEach { element -> - mangas.add(latestUpdatesFromElement(element)) - } - - val nextPage = response.asJsoup().select(latestUpdatesNextPageSelector()).first() != null - - return MangasPage(mangas, nextPage) - } - override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = throw UnsupportedOperationException("Not used") - override fun searchMangaSelector() = throw UnsupportedOperationException("Not used") - override fun searchMangaFromElement(element: Element) = throw UnsupportedOperationException("Not used") - override fun searchMangaNextPageSelector() = throw UnsupportedOperationException("Not used") + + override fun searchMangaSelector() = "div#search-list div.col" + + override fun searchMangaFromElement(element: Element) = latestUpdatesFromElement(element) + + override fun searchMangaNextPageSelector() = latestUpdatesNextPageSelector() override fun mangaDetailsParse(document: Document): SManga { - val infoElement = document.select("div#mainer div.container-fluid") - val genreList = mutableListOf() val statusStr = infoElement.select("div.attr-item:contains(status) span").text() - infoElement.select("div.attr-item:contains(genres) span span").forEach { element -> - genreList.add(element.text()) - } - + return SManga.create().apply { title = infoElement.select("h3.item-title").text() - description = infoElement.select("div.limit-height-body").select("h5.text-muted, div.limit-html").joinToString("\n\n") { it.text() } - author = infoElement.select("div.attr-item:contains(author)").text().split("/").joinToString(", ") { it.trim() } + description = infoElement.select("div.limit-height-body") + .select("h5.text-muted, div.limit-html") + .joinToString("\n\n") { it.text() } + author = infoElement.select("div.attr-item:contains(author) a") + .joinToString { it.text().trim() } status = parseStatus(statusStr) thumbnail_url = infoElement.select("div.detail-set div.attr-cover img").attr("abs:src") - genre = genreList.joinToString(", ") { it.trim() } + genre = infoElement.select("div.attr-item:contains(genres) span span") + .joinToString { it.text().trim() } } - } private fun parseStatus(status: String?) = when { @@ -200,7 +190,7 @@ open class MangaPark( put("lang", siteLang) put("sid", sid) } - + val requestBody = jsonPayload.toString().toRequestBody("application/json;charset=UTF-8".toMediaType()) val refererUrl = "$baseUrl/$url".toHttpUrlOrNull()!!.newBuilder() @@ -217,20 +207,20 @@ open class MangaPark( body = requestBody ) } - + override fun chapterListParse(response: Response): List { val resToJson = json.parseToJsonElement(response.body!!.string()).jsonObject val document = Jsoup.parse(resToJson["html"]!!.jsonPrimitive.content) return document.select(chapterListSelector()).map { chapterFromElement(it) } } - + override fun chapterListSelector() = "div.episode-item" override fun chapterFromElement(element: Element): SChapter { - + val urlElement = element.select("a.chapt") val time = element.select("div.extra > i.ps-2").text() - + return SChapter.create().apply { name = urlElement.text() chapter_number = urlElement.attr("href").substringAfterLast("/").toFloat() @@ -238,7 +228,7 @@ open class MangaPark( setUrlWithoutDomain(urlElement.attr("href")) } } - + private fun parseChapterDate(date: String): Long { val value = date.split(' ')[0].toInt() val timeStr = date.split(' ')[1].removeSuffix("s") @@ -272,32 +262,25 @@ open class MangaPark( } override fun pageListParse(document: Document): List { - - val pages = mutableListOf() - val duktape = Duktape.create() val script = document.select("script").html() - val imgCdnHost = script.substringAfter("const imgCdnHost = ").substringBefore(";") + val imgCdnHost = script.substringAfter("const imgCdnHost = \"").substringBefore("\";") val imgPathLisRaw = script.substringAfter("const imgPathLis = ").substringBefore(";") val imgPathLis = json.parseToJsonElement(imgPathLisRaw).jsonArray - val amPass = duktape.evaluate(script.substringAfter("const amPass = ").substringBefore(";")).toString() + val amPass = script.substringAfter("const amPass = ").substringBefore(";") val amWord = script.substringAfter("const amWord = ").substringBefore(";") - - val decryptScript = cryptoJS + "CryptoJS.AES.decrypt($amWord, \"$amPass\").toString(CryptoJS.enc.Utf8);" - + + val decryptScript = cryptoJS + "CryptoJS.AES.decrypt($amWord, $amPass).toString(CryptoJS.enc.Utf8);" + val imgWordLisRaw = duktape.evaluate(decryptScript).toString() val imgWordLis = json.parseToJsonElement(imgWordLisRaw).jsonArray - - imgPathLis.mapIndexed { i, imgPathE -> - val imgPath = imgPathE.jsonPrimitive.content - val imgWordE = imgWordLis.elementAt(i) - val imgWord = imgWordE.jsonPrimitive.content - - val page = "$imgCdnHost$imgPath?$imgWord" - pages.add(Page(i, "", "$page")) - } - return pages + return imgWordLis.mapIndexed { i, imgWordE -> + val imgPath = imgPathLis[i].jsonPrimitive.content + val imgWord = imgWordE.jsonPrimitive.content + + Page(i, "", "$imgCdnHost$imgPath?$imgWord") + } } private val cryptoJS by lazy { @@ -311,9 +294,8 @@ open class MangaPark( override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used") - override fun getFilterList() = FilterList( - //LetterFilter(), + // LetterFilter(), Filter.Header("NOTE: Ignored if using text search!"), Filter.Separator(), SortFilter(getSortFilter(), 10), @@ -381,124 +363,122 @@ open class MangaPark( ) private fun getGenreFilter() = listOf( - TriStateFilterOption("artbook","Artbook"), - TriStateFilterOption("cartoon","Cartoon"), - TriStateFilterOption("comic","Comic"), - TriStateFilterOption("doujinshi","Doujinshi"), - TriStateFilterOption("imageset","Imageset"), - TriStateFilterOption("manga","Manga"), - TriStateFilterOption("manhua","Manhua"), - TriStateFilterOption("manhwa","Manhwa"), - TriStateFilterOption("webtoon","Webtoon"), - TriStateFilterOption("western","Western"), - TriStateFilterOption("josei","Josei"), - TriStateFilterOption("seinen","Seinen"), - TriStateFilterOption("shoujo","Shoujo"), - TriStateFilterOption("shoujo_ai","Shoujo ai"), - TriStateFilterOption("shounen","Shounen"), - TriStateFilterOption("shounen_ai","Shounen ai"), - TriStateFilterOption("yaoi","Yaoi"), - TriStateFilterOption("yuri","Yuri"), - TriStateFilterOption("ecchi","Ecchi"), - TriStateFilterOption("mature","Mature"), - TriStateFilterOption("adult","Adult"), - TriStateFilterOption("gore","Gore"), - TriStateFilterOption("violence","Violence"), - TriStateFilterOption("smut","Smut"), - TriStateFilterOption("hentai","Hentai"), - TriStateFilterOption("_4_koma","4-Koma"), - TriStateFilterOption("action","Action"), - TriStateFilterOption("adaptation","Adaptation"), - TriStateFilterOption("adventure","Adventure"), - TriStateFilterOption("aliens","Aliens"), - TriStateFilterOption("animals","Animals"), - TriStateFilterOption("anthology","Anthology"), - TriStateFilterOption("cars","cars"), - TriStateFilterOption("comedy","Comedy"), - TriStateFilterOption("cooking","Cooking"), - TriStateFilterOption("crime","crime"), - TriStateFilterOption("crossdressing","Crossdressing"), - TriStateFilterOption("delinquents","Delinquents"), - TriStateFilterOption("dementia","Dementia"), - TriStateFilterOption("demons","Demons"), - TriStateFilterOption("drama","Drama"), - TriStateFilterOption("fantasy","Fantasy"), - TriStateFilterOption("fan_colored","Fan-Colored"), - TriStateFilterOption("full_color","Full Color"), - TriStateFilterOption("game","Game"), - TriStateFilterOption("gender_bender","Gender Bender"), - TriStateFilterOption("genderswap","Genderswap"), - TriStateFilterOption("ghosts","Ghosts"), - TriStateFilterOption("gyaru","Gyaru"), - TriStateFilterOption("harem","Harem"), - TriStateFilterOption("harlequin","Harlequin"), - TriStateFilterOption("historical","Historical"), - TriStateFilterOption("horror","Horror"), - TriStateFilterOption("incest","Incest"), - TriStateFilterOption("isekai","Isekai"), - TriStateFilterOption("kids","Kids"), - TriStateFilterOption("loli","Loli"), - TriStateFilterOption("lolicon","lolicon"), - TriStateFilterOption("magic","Magic"), - TriStateFilterOption("magical_girls","Magical Girls"), - TriStateFilterOption("martial_arts","Martial Arts"), - TriStateFilterOption("mecha","Mecha"), - TriStateFilterOption("medical","Medical"), - TriStateFilterOption("military","Military"), - TriStateFilterOption("monster_girls","Monster Girls"), - TriStateFilterOption("monsters","Monsters"), - TriStateFilterOption("music","Music"), - TriStateFilterOption("mystery","Mystery"), - TriStateFilterOption("netorare","Netorare/NTR"), - TriStateFilterOption("ninja","Ninja"), - TriStateFilterOption("office_workers","Office Workers"), - TriStateFilterOption("oneshot","Oneshot"), - TriStateFilterOption("parody","parody"), - TriStateFilterOption("philosophical","Philosophical"), - TriStateFilterOption("police","Police"), - TriStateFilterOption("post_apocalyptic","Post-Apocalyptic"), - TriStateFilterOption("psychological","Psychological"), - TriStateFilterOption("reincarnation","Reincarnation"), - TriStateFilterOption("reverse_harem","Reverse Harem"), - TriStateFilterOption("romance","Romance"), - TriStateFilterOption("samurai","Samurai"), - TriStateFilterOption("school_life","School Life"), - TriStateFilterOption("sci_fi","Sci-Fi"), - TriStateFilterOption("shota","Shota"), - TriStateFilterOption("shotacon","shotacon"), - TriStateFilterOption("slice_of_life","Slice of Life"), - TriStateFilterOption("sm_bdsm","SM/BDSM"), - TriStateFilterOption("space","Space"), - TriStateFilterOption("sports","Sports"), - TriStateFilterOption("super_power","Super Power"), - TriStateFilterOption("superhero","Superhero"), - TriStateFilterOption("supernatural","Supernatural"), - TriStateFilterOption("survival","Survival"), - TriStateFilterOption("thriller","Thriller"), - TriStateFilterOption("time_travel","Time Travel"), - TriStateFilterOption("traditional_games","Traditional Games"), - TriStateFilterOption("tragedy","Tragedy"), - TriStateFilterOption("vampires","Vampires"), - TriStateFilterOption("video_games","Video Games"), - TriStateFilterOption("virtual_reality","Virtual Reality"), - TriStateFilterOption("wuxia","Wuxia"), - TriStateFilterOption("xianxia","Xianxia"), - TriStateFilterOption("xuanhuan","Xuanhuan"), - TriStateFilterOption("zombies","Zombies"), + TriStateFilterOption("artbook", "Artbook"), + TriStateFilterOption("cartoon", "Cartoon"), + TriStateFilterOption("comic", "Comic"), + TriStateFilterOption("doujinshi", "Doujinshi"), + TriStateFilterOption("imageset", "Imageset"), + TriStateFilterOption("manga", "Manga"), + TriStateFilterOption("manhua", "Manhua"), + TriStateFilterOption("manhwa", "Manhwa"), + TriStateFilterOption("webtoon", "Webtoon"), + TriStateFilterOption("western", "Western"), + TriStateFilterOption("josei", "Josei"), + TriStateFilterOption("seinen", "Seinen"), + TriStateFilterOption("shoujo", "Shoujo"), + TriStateFilterOption("shoujo_ai", "Shoujo ai"), + TriStateFilterOption("shounen", "Shounen"), + TriStateFilterOption("shounen_ai", "Shounen ai"), + TriStateFilterOption("yaoi", "Yaoi"), + TriStateFilterOption("yuri", "Yuri"), + TriStateFilterOption("ecchi", "Ecchi"), + TriStateFilterOption("mature", "Mature"), + TriStateFilterOption("adult", "Adult"), + TriStateFilterOption("gore", "Gore"), + TriStateFilterOption("violence", "Violence"), + TriStateFilterOption("smut", "Smut"), + TriStateFilterOption("hentai", "Hentai"), + TriStateFilterOption("_4_koma", "4-Koma"), + TriStateFilterOption("action", "Action"), + TriStateFilterOption("adaptation", "Adaptation"), + TriStateFilterOption("adventure", "Adventure"), + TriStateFilterOption("aliens", "Aliens"), + TriStateFilterOption("animals", "Animals"), + TriStateFilterOption("anthology", "Anthology"), + TriStateFilterOption("cars", "cars"), + TriStateFilterOption("comedy", "Comedy"), + TriStateFilterOption("cooking", "Cooking"), + TriStateFilterOption("crime", "crime"), + TriStateFilterOption("crossdressing", "Crossdressing"), + TriStateFilterOption("delinquents", "Delinquents"), + TriStateFilterOption("dementia", "Dementia"), + TriStateFilterOption("demons", "Demons"), + TriStateFilterOption("drama", "Drama"), + TriStateFilterOption("fantasy", "Fantasy"), + TriStateFilterOption("fan_colored", "Fan-Colored"), + TriStateFilterOption("full_color", "Full Color"), + TriStateFilterOption("game", "Game"), + TriStateFilterOption("gender_bender", "Gender Bender"), + TriStateFilterOption("genderswap", "Genderswap"), + TriStateFilterOption("ghosts", "Ghosts"), + TriStateFilterOption("gyaru", "Gyaru"), + TriStateFilterOption("harem", "Harem"), + TriStateFilterOption("harlequin", "Harlequin"), + TriStateFilterOption("historical", "Historical"), + TriStateFilterOption("horror", "Horror"), + TriStateFilterOption("incest", "Incest"), + TriStateFilterOption("isekai", "Isekai"), + TriStateFilterOption("kids", "Kids"), + TriStateFilterOption("loli", "Loli"), + TriStateFilterOption("lolicon", "lolicon"), + TriStateFilterOption("magic", "Magic"), + TriStateFilterOption("magical_girls", "Magical Girls"), + TriStateFilterOption("martial_arts", "Martial Arts"), + TriStateFilterOption("mecha", "Mecha"), + TriStateFilterOption("medical", "Medical"), + TriStateFilterOption("military", "Military"), + TriStateFilterOption("monster_girls", "Monster Girls"), + TriStateFilterOption("monsters", "Monsters"), + TriStateFilterOption("music", "Music"), + TriStateFilterOption("mystery", "Mystery"), + TriStateFilterOption("netorare", "Netorare/NTR"), + TriStateFilterOption("ninja", "Ninja"), + TriStateFilterOption("office_workers", "Office Workers"), + TriStateFilterOption("oneshot", "Oneshot"), + TriStateFilterOption("parody", "parody"), + TriStateFilterOption("philosophical", "Philosophical"), + TriStateFilterOption("police", "Police"), + TriStateFilterOption("post_apocalyptic", "Post-Apocalyptic"), + TriStateFilterOption("psychological", "Psychological"), + TriStateFilterOption("reincarnation", "Reincarnation"), + TriStateFilterOption("reverse_harem", "Reverse Harem"), + TriStateFilterOption("romance", "Romance"), + TriStateFilterOption("samurai", "Samurai"), + TriStateFilterOption("school_life", "School Life"), + TriStateFilterOption("sci_fi", "Sci-Fi"), + TriStateFilterOption("shota", "Shota"), + TriStateFilterOption("shotacon", "shotacon"), + TriStateFilterOption("slice_of_life", "Slice of Life"), + TriStateFilterOption("sm_bdsm", "SM/BDSM"), + TriStateFilterOption("space", "Space"), + TriStateFilterOption("sports", "Sports"), + TriStateFilterOption("super_power", "Super Power"), + TriStateFilterOption("superhero", "Superhero"), + TriStateFilterOption("supernatural", "Supernatural"), + TriStateFilterOption("survival", "Survival"), + TriStateFilterOption("thriller", "Thriller"), + TriStateFilterOption("time_travel", "Time Travel"), + TriStateFilterOption("traditional_games", "Traditional Games"), + TriStateFilterOption("tragedy", "Tragedy"), + TriStateFilterOption("vampires", "Vampires"), + TriStateFilterOption("video_games", "Video Games"), + TriStateFilterOption("virtual_reality", "Virtual Reality"), + TriStateFilterOption("wuxia", "Wuxia"), + TriStateFilterOption("xianxia", "Xianxia"), + TriStateFilterOption("xuanhuan", "Xuanhuan"), + TriStateFilterOption("zombies", "Zombies"), // Hidden Genres TriStateFilterOption("award_winning", "Award Winning"), TriStateFilterOption("youkai", "Youkai"), TriStateFilterOption("uncategorized", "Uncategorized") ) - + private inline fun Iterable<*>.findInstance() = find { it is T } as? T - + companion object { - + const val PREFIX_ID_SEARCH = "id:" - + const val CryptoJSUrl = "https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js" - } - } diff --git a/src/all/mangapark/src/eu/kanade/tachiyomi/extension/all/mangapark/MangaParkFactory.kt b/src/all/mangapark/src/eu/kanade/tachiyomi/extension/all/mangapark/MangaParkFactory.kt index f5021ef11..2a82627fd 100644 --- a/src/all/mangapark/src/eu/kanade/tachiyomi/extension/all/mangapark/MangaParkFactory.kt +++ b/src/all/mangapark/src/eu/kanade/tachiyomi/extension/all/mangapark/MangaParkFactory.kt @@ -11,7 +11,7 @@ class MangaParkFactory : SourceFactory { class LanguageOption(val lang: String, val siteLang: String = lang) private val languages = listOf( - //LanguageOption("",""), + // LanguageOption("",""), LanguageOption("en"), LanguageOption("ar"), LanguageOption("bg"), @@ -34,11 +34,11 @@ private val languages = listOf( LanguageOption("ms"), LanguageOption("pl"), LanguageOption("pt"), - LanguageOption("pt-BR","pt_br"), + LanguageOption("pt-BR", "pt_br"), LanguageOption("ro"), LanguageOption("ru"), LanguageOption("es"), - LanguageOption("es-419","es_419"), + LanguageOption("es-419", "es_419"), LanguageOption("sv"), LanguageOption("th"), LanguageOption("tr"), @@ -56,10 +56,10 @@ private val languages = listOf( LanguageOption("km"), LanguageOption("ca"), LanguageOption("ceb"), - LanguageOption("zh-rHK","zh_hk"), - LanguageOption("zh-rTW","zh_tw"), + LanguageOption("zh-rHK", "zh_hk"), + LanguageOption("zh-rTW", "zh_tw"), LanguageOption("hr"), - LanguageOption("en-US","en_us"), + LanguageOption("en-US", "en_us"), LanguageOption("eo"), LanguageOption("et"), LanguageOption("fo"), @@ -116,5 +116,5 @@ private val languages = listOf( LanguageOption("zu"), LanguageOption("other", "_t"), LanguageOption("eu"), - LanguageOption("pt-PT","pt_pt") + LanguageOption("pt-PT", "pt_pt") )