mirror of
				https://github.com/recloudstream/cloudstream-extensions.git
				synced 2024-08-15 03:03:54 +00:00 
			
		
		
		
	Fixed WatchCartoonOnline
This commit is contained in:
		
							parent
							
								
									b1a9851fc0
								
							
						
					
					
						commit
						b9d86b5be2
					
				
					 6 changed files with 140 additions and 127 deletions
				
			
		|  | @ -5,7 +5,6 @@ import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
| import com.lagradost.cloudstream3.utils.loadExtractor | import com.lagradost.cloudstream3.utils.loadExtractor | ||||||
| 
 | 
 | ||||||
| class KimCartoonProvider : MainAPI() { | class KimCartoonProvider : MainAPI() { | ||||||
| 
 |  | ||||||
|     override var mainUrl = "https://kimcartoon.li" |     override var mainUrl = "https://kimcartoon.li" | ||||||
|     override var name = "Kim Cartoon" |     override var name = "Kim Cartoon" | ||||||
|     override val hasQuickSearch = true |     override val hasQuickSearch = true | ||||||
|  | @ -73,7 +72,7 @@ class KimCartoonProvider : MainAPI() { | ||||||
|                 AnimeSearchResponse( |                 AnimeSearchResponse( | ||||||
|                     it.select("span").text(), |                     it.select("span").text(), | ||||||
|                     mainUrl + it.attr("href"), |                     mainUrl + it.attr("href"), | ||||||
|                     mainUrl, |                     name, | ||||||
|                     TvType.Cartoon, |                     TvType.Cartoon, | ||||||
|                     fixUrl(it.select("img").attr("src")) |                     fixUrl(it.select("img").attr("src")) | ||||||
|                 ) |                 ) | ||||||
|  |  | ||||||
|  | @ -16,7 +16,7 @@ cloudstream { | ||||||
|      * 2: Slow |      * 2: Slow | ||||||
|      * 3: Beta only |      * 3: Beta only | ||||||
|      * */ |      * */ | ||||||
|     status = 1 // will be 3 if unspecified |     status = 0 // will be 3 if unspecified | ||||||
|     tvTypes = listOf( |     tvTypes = listOf( | ||||||
|         "TvSeries", |         "TvSeries", | ||||||
|         "Movie", |         "Movie", | ||||||
|  |  | ||||||
|  | @ -21,5 +21,5 @@ class AsianLoadProvider : VidstreamProviderTemplate() { | ||||||
|     override val secretKey = "93422192433952489752342908585752" |     override val secretKey = "93422192433952489752342908585752" | ||||||
|     override val secretDecryptKey = secretKey |     override val secretDecryptKey = secretKey | ||||||
| 
 | 
 | ||||||
|     override val supportedTypes = setOf(TvType.AsianDrama) |     override val supportedTypes = setOf(TvType.AsianDrama, TvType.TvSeries) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| // use an integer for version numbers | // use an integer for version numbers | ||||||
| version = 1 | version = 2 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| cloudstream { | cloudstream { | ||||||
|  |  | ||||||
|  | @ -2,10 +2,9 @@ package com.lagradost | ||||||
| 
 | 
 | ||||||
| import com.fasterxml.jackson.annotation.JsonProperty | import com.fasterxml.jackson.annotation.JsonProperty | ||||||
| import com.lagradost.cloudstream3.* | import com.lagradost.cloudstream3.* | ||||||
| import com.lagradost.cloudstream3.utils.AppUtils.parseJson | import com.lagradost.cloudstream3.utils.Coroutines.mainWork | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorLink | import com.lagradost.cloudstream3.utils.ExtractorLink | ||||||
| import com.lagradost.cloudstream3.utils.Qualities | import com.lagradost.cloudstream3.utils.Qualities | ||||||
| import org.jsoup.Jsoup |  | ||||||
| import org.mozilla.javascript.Context | import org.mozilla.javascript.Context | ||||||
| import org.mozilla.javascript.Scriptable | import org.mozilla.javascript.Scriptable | ||||||
| import java.util.* | import java.util.* | ||||||
|  | @ -13,7 +12,8 @@ import java.util.* | ||||||
| 
 | 
 | ||||||
| class WatchCartoonOnlineProvider : MainAPI() { | class WatchCartoonOnlineProvider : MainAPI() { | ||||||
|     override var name = "WatchCartoonOnline" |     override var name = "WatchCartoonOnline" | ||||||
|     override var mainUrl = "https://www.wcostream.com" |     override var mainUrl = "https://www.wcostream.net" | ||||||
|  |     override val hasMainPage = true | ||||||
| 
 | 
 | ||||||
|     override val supportedTypes = setOf( |     override val supportedTypes = setOf( | ||||||
|         TvType.Cartoon, |         TvType.Cartoon, | ||||||
|  | @ -22,34 +22,57 @@ class WatchCartoonOnlineProvider : MainAPI() { | ||||||
|         TvType.TvSeries |         TvType.TvSeries | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     override suspend fun search(query: String): List<SearchResponse> { |     override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse? { | ||||||
|         val url = "https://www.wcostream.com/search" |         val doc = app.get(mainUrl).document | ||||||
|  |         val rows = doc.select("div.recent-release").mapNotNull { | ||||||
|  |             val rowName = it.text() | ||||||
|  |             val parent = it.parent() ?: return@mapNotNull null | ||||||
|  |             val list = parent.select("ul.items > li").map { item -> | ||||||
|  |                 val link = item.select("a").attr("href") | ||||||
|  |                 val name = item.text() | ||||||
|  |                 newTvSeriesSearchResponse( | ||||||
|  |                     name, link | ||||||
|  |                 ) { | ||||||
|  |                     this.posterUrl = fixUrl(item.select("img").attr("src")) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             HomePageList(rowName, list) | ||||||
|  |         } | ||||||
|  |         return HomePageResponse(rows, false) | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|         var response = | 
 | ||||||
|  |     override suspend fun search(query: String): List<SearchResponse> { | ||||||
|  |         val url = "$mainUrl/search" | ||||||
|  | 
 | ||||||
|  |         val seriesDocument = | ||||||
|             app.post( |             app.post( | ||||||
|                 url, |                 url, | ||||||
|                 headers = mapOf("Referer" to url), |                 headers = mapOf("Referer" to url), | ||||||
|                 data = mapOf("catara" to query, "konuara" to "series") |                 data = mapOf("catara" to query, "konuara" to "series") | ||||||
|             ).text |             ).document | ||||||
|         var document = Jsoup.parse(response) |  | ||||||
|         var items = document.select("div#blog > div.cerceve").toList() |  | ||||||
| 
 | 
 | ||||||
|         val returnValue = ArrayList<SearchResponse>() |         val series = seriesDocument.select("div#blog > div.cerceve").toList().mapNotNull { item -> | ||||||
| 
 |             val header = item.selectFirst("> div.iccerceve") ?: return@mapNotNull null | ||||||
|         for (item in items) { |             val titleHeader = header.selectFirst("> div.aramadabaslik > a") | ||||||
|             val header = item.selectFirst("> div.iccerceve") |  | ||||||
|             val titleHeader = header!!.selectFirst("> div.aramadabaslik > a") |  | ||||||
|             val title = titleHeader!!.text() |             val title = titleHeader!!.text() | ||||||
|             val href = fixUrl(titleHeader.attr("href")) |             val href = fixUrl(titleHeader.attr("href")) | ||||||
|             val poster = fixUrl(header.selectFirst("> a > img")!!.attr("src")) |             val poster = fixUrl(header.selectFirst("> a > img")!!.attr("src")) | ||||||
|             val genreText = item.selectFirst("div.cerceve-tur-ve-genre")!!.ownText() |             val genreText = item.selectFirst("div.cerceve-tur-ve-genre")!!.ownText() | ||||||
|             if (genreText.contains("cartoon")) { |             if (genreText.contains("cartoon")) { | ||||||
|                 returnValue.add(TvSeriesSearchResponse(title, href, this.name, TvType.Cartoon, poster, null, null)) |                 TvSeriesSearchResponse( | ||||||
|  |                     title, | ||||||
|  |                     href, | ||||||
|  |                     this.name, | ||||||
|  |                     TvType.Cartoon, | ||||||
|  |                     poster, | ||||||
|  |                     null, | ||||||
|  |                     null | ||||||
|  |                 ) | ||||||
|             } else { |             } else { | ||||||
|                 val isDubbed = genreText.contains("dubbed") |                 val isDubbed = genreText.contains("dubbed") | ||||||
|                 val set: EnumSet<DubStatus> = |                 val set: EnumSet<DubStatus> = | ||||||
|                     EnumSet.of(if (isDubbed) DubStatus.Dubbed else DubStatus.Subbed) |                     EnumSet.of(if (isDubbed) DubStatus.Dubbed else DubStatus.Subbed) | ||||||
|                 returnValue.add( |  | ||||||
|                 AnimeSearchResponse( |                 AnimeSearchResponse( | ||||||
|                     title, |                     title, | ||||||
|                     href, |                     href, | ||||||
|  | @ -59,30 +82,30 @@ class WatchCartoonOnlineProvider : MainAPI() { | ||||||
|                     null, |                     null, | ||||||
|                     set, |                     set, | ||||||
|                 ) |                 ) | ||||||
|                 ) |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // "episodes-search", is used for finding movies, anime episodes should be filtered out |         // "episodes-search", is used for finding movies, anime episodes should be filtered out | ||||||
|         response = |         val episodesDocument = | ||||||
|             app.post( |             app.post( | ||||||
|                 url, |                 url, | ||||||
|                 headers = mapOf("Referer" to url), |                 headers = mapOf("Referer" to url), | ||||||
|                 data = mapOf("catara" to query, "konuara" to "episodes") |                 data = mapOf("catara" to query, "konuara" to "episodes") | ||||||
|             ).text |             ).document | ||||||
|         document = Jsoup.parse(response) |         val items = episodesDocument.select("#catlist-listview2 > ul > li") | ||||||
|         items = document.select("#catlist-listview2 > ul > li") |             // Filter away episodes and blanks | ||||||
|             .filter { it -> it?.text() != null && !it.text().toString().contains("Episode") } |             .filterNot { element -> | ||||||
|  |                 element.text().contains("Episode") || element.text().isNullOrBlank() | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|         for (item in items) { |         val episodes = items.mapNotNull { item -> | ||||||
|             val titleHeader = item.selectFirst("a") |             val titleHeader = item.selectFirst("a") ?: return@mapNotNull null | ||||||
|             val title = titleHeader!!.text() |             val title = titleHeader.text() | ||||||
|             val href = fixUrl(titleHeader.attr("href")) |             val href = fixUrl(titleHeader.attr("href")) | ||||||
|             //val isDubbed = title.contains("dubbed") |             //val isDubbed = title.contains("dubbed") | ||||||
|             //val set: EnumSet<DubStatus> = |             //val set: EnumSet<DubStatus> = | ||||||
|             //   EnumSet.of(if (isDubbed) DubStatus.Dubbed else DubStatus.Subbed) |             //   EnumSet.of(if (isDubbed) DubStatus.Dubbed else DubStatus.Subbed) | ||||||
|             returnValue.add( |             MovieSearchResponse( | ||||||
|                 TvSeriesSearchResponse( |  | ||||||
|                 title, |                 title, | ||||||
|                 href, |                 href, | ||||||
|                 this.name, |                 this.name, | ||||||
|  | @ -91,25 +114,24 @@ class WatchCartoonOnlineProvider : MainAPI() { | ||||||
|                 null, |                 null, | ||||||
|                 null, |                 null, | ||||||
|             ) |             ) | ||||||
|             ) |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return returnValue |         return series + episodes | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override suspend fun load(url: String): LoadResponse { |     override suspend fun load(url: String): LoadResponse { | ||||||
|         val isMovie = !url.contains("/anime/") |         val isSeries = url.contains("/anime/") | ||||||
|         val response = app.get(url).text |         val document = app.get(url).document | ||||||
|         val document = Jsoup.parse(response) |  | ||||||
| 
 | 
 | ||||||
|         return if (!isMovie) { |         return if (isSeries) { | ||||||
|             val title = document.selectFirst("td.vsbaslik > h2")!!.text() |             val title = document.selectFirst("td.vsbaslik > h2")!!.text() | ||||||
|             val poster = fixUrlNull(document.selectFirst("div#cat-img-desc > div > img")?.attr("src")) |             val poster = | ||||||
|  |                 fixUrlNull(document.selectFirst("div#cat-img-desc > div > img")?.attr("src")) | ||||||
|             val plot = document.selectFirst("div.iltext")!!.text() |             val plot = document.selectFirst("div.iltext")!!.text() | ||||||
|             val genres = document.select("div#cat-genre > div.wcobtn > a").map { it.text() } |             val genres = document.select("div#cat-genre > div.wcobtn > a").map { it.text() } | ||||||
|             val episodes = document.select("div#catlist-listview > ul > li > a").reversed().map { |             val episodes = document.select("div#catlist-listview > ul > li > a").reversed().map { | ||||||
|                 val text = it.text() |                 val text = it.text() | ||||||
|                 val match = Regex("Season ([0-9]*) Episode ([0-9]*).*? (.*)").find(text) |                 val match = Regex("""Season (\d*) Episode (\d*).*? (.*)""").find(text) | ||||||
|                 val href = it.attr("href") |                 val href = it.attr("href") | ||||||
|                 if (match != null) { |                 if (match != null) { | ||||||
|                     val last = match.groupValues[3] |                     val last = match.groupValues[3] | ||||||
|  | @ -120,7 +142,7 @@ class WatchCartoonOnlineProvider : MainAPI() { | ||||||
|                         match.groupValues[2].toIntOrNull(), |                         match.groupValues[2].toIntOrNull(), | ||||||
|                     ) |                     ) | ||||||
|                 } |                 } | ||||||
|                 val match2 = Regex("Episode ([0-9]*).*? (.*)").find(text) |                 val match2 = Regex("""Episode (\d*).*? (.*)""").find(text) | ||||||
|                 if (match2 != null) { |                 if (match2 != null) { | ||||||
|                     val last = match2.groupValues[2] |                     val last = match2.groupValues[2] | ||||||
|                     return@map Episode( |                     return@map Episode( | ||||||
|  | @ -149,36 +171,28 @@ class WatchCartoonOnlineProvider : MainAPI() { | ||||||
|                 tags = genres |                 tags = genres | ||||||
|             ) |             ) | ||||||
|         } else { |         } else { | ||||||
|             val title = document.selectFirst(".iltext .Apple-style-span")?.text().toString() |             val title = document.selectFirst("td.ilxbaslik8")?.text().toString() | ||||||
|             val b = document.select(".iltext b") |  | ||||||
|             val description = if (b.isNotEmpty()) { |  | ||||||
|                 b.last()!!.html().split("<br>")[0] |  | ||||||
|             } else null |  | ||||||
| 
 | 
 | ||||||
|             TvSeriesLoadResponse( |             newMovieLoadResponse( | ||||||
|                 title, |                 title, | ||||||
|                 url, |                 url, | ||||||
|                 this.name, |                 TvType.AnimeMovie, | ||||||
|                 TvType.TvSeries, |                 url | ||||||
|                 listOf(Episode(url,title)), |             ) { | ||||||
|                 null, |                 plot = document.select("div.iltext").text() | ||||||
|                 null, |                     .substringAfter("Episode Description:") | ||||||
|                 description, |                     .substringBefore("Share:") | ||||||
|                 null, |             } | ||||||
|                 null |  | ||||||
|             ) |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     data class LinkResponse( |     data class LinkResponse( | ||||||
|         //  @JsonProperty("cdn") |         //  @JsonProperty("cdn") | ||||||
|         //  val cdn: String, |         //  val cdn: String, | ||||||
|         @JsonProperty("enc") |         @JsonProperty("enc") val enc: String, | ||||||
|         val enc: String, |         @JsonProperty("hd") val hd: String, | ||||||
|         @JsonProperty("hd") |         @JsonProperty("fhd") val fhd: String, | ||||||
|         val hd: String, |         @JsonProperty("server") val server: String, | ||||||
|         @JsonProperty("server") |  | ||||||
|         val server: String, |  | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     override suspend fun loadLinks( |     override suspend fun loadLinks( | ||||||
|  | @ -187,18 +201,20 @@ class WatchCartoonOnlineProvider : MainAPI() { | ||||||
|         subtitleCallback: (SubtitleFile) -> Unit, |         subtitleCallback: (SubtitleFile) -> Unit, | ||||||
|         callback: (ExtractorLink) -> Unit |         callback: (ExtractorLink) -> Unit | ||||||
|     ): Boolean { |     ): Boolean { | ||||||
|         val response = app.get(data).text |         val document = app.get(data).document | ||||||
|         /*val embedUrl = fixUrl( |         val foundJS = document.select("div.iltext > script").html() | ||||||
|             Regex("itemprop=\"embedURL\" content=\"(.*?)\"").find(response.text)?.groupValues?.get(1) ?: return false |  | ||||||
|         )*/ |  | ||||||
|         val start = response.indexOf("itemprop=\"embedURL") |  | ||||||
|         val foundJS = Regex("<script>(.*?)</script>").find(response, start)?.groupValues?.get(1) |  | ||||||
|             ?.replace("document.write", "var returnValue = ") |  | ||||||
| 
 | 
 | ||||||
|  |         // Find the variable name, eg: var HAi = ""; | ||||||
|  |         val varRegex = Regex("""var (\S*)""") | ||||||
|  | 
 | ||||||
|  |         val varName = varRegex.find(foundJS)?.groupValues?.get(1) | ||||||
|  |             ?: throw RuntimeException("Cannot find var name!") | ||||||
|  | 
 | ||||||
|  |         val src = document.select("iframe#frameNewAnimeuploads0").attr("src") ?: mainWork { | ||||||
|  |             // Rhino needs to be on main | ||||||
|             val rhino = Context.enter() |             val rhino = Context.enter() | ||||||
|         rhino.initStandardObjects() |  | ||||||
|             rhino.optimizationLevel = -1 |             rhino.optimizationLevel = -1 | ||||||
|         val scope: Scriptable = rhino.initStandardObjects() |             val scope: Scriptable = rhino.initSafeStandardObjects() | ||||||
| 
 | 
 | ||||||
|             val decodeBase64 = "atob = function(s) {\n" + |             val decodeBase64 = "atob = function(s) {\n" + | ||||||
|                     "    var e={},i,b=0,c,x,l=0,a,r='',w=String.fromCharCode,L=s.length;\n" + |                     "    var e={},i,b=0,c,x,l=0,a,r='',w=String.fromCharCode,L=s.length;\n" + | ||||||
|  | @ -210,20 +226,29 @@ class WatchCartoonOnlineProvider : MainAPI() { | ||||||
|                     "    }\n" + |                     "    }\n" + | ||||||
|                     "    return r;\n" + |                     "    return r;\n" + | ||||||
|                     "};" |                     "};" | ||||||
|  |             val documentJs = """ | ||||||
|  |                 document = { write: function () {} }; | ||||||
|  |             """.trimIndent() | ||||||
|  |             rhino.evaluateString(scope, documentJs + decodeBase64 + foundJS, "JavaScript", 1, null) | ||||||
| 
 | 
 | ||||||
|         rhino.evaluateString(scope, decodeBase64 + foundJS, "JavaScript", 1, null) |             val jsEval = scope.get(varName, scope)?.toString() | ||||||
|         val jsEval = scope.get("returnValue", scope) ?: return false |                 ?: throw RuntimeException("Cannot get the Rhino scope variable") | ||||||
|         val src = fixUrl(Regex("src=\"(.*?)\"").find(jsEval as String)?.groupValues?.get(1) ?: return false) |             val url = | ||||||
|  |                 Regex("src=\"(.*?)\"").find(jsEval)?.groupValues?.get(1) ?: return@mainWork null | ||||||
|  |             fixUrl(url) | ||||||
|  |         } ?: return false | ||||||
| 
 | 
 | ||||||
|         val embedResponse = app.get( |         val embedResponse = app.get( | ||||||
|             (src), |             src, | ||||||
|             headers = mapOf("Referer" to data) |             headers = mapOf("Referer" to src) | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|         val getVidLink = fixUrl( |         val getVidLink = fixUrl( | ||||||
|             Regex("get\\(\"(.*?)\"").find(embedResponse.text)?.groupValues?.get(1) ?: return false |             Regex("getJSON\\(\"(.*?)\"").find(embedResponse.text)?.groupValues?.get(1) | ||||||
|  |                 ?: return false | ||||||
|         ) |         ) | ||||||
|         val linkResponse = app.get( | 
 | ||||||
|  |         val link = app.get( | ||||||
|             getVidLink, headers = mapOf( |             getVidLink, headers = mapOf( | ||||||
|                 "sec-ch-ua" to "\"Chromium\";v=\"91\", \" Not;A Brand\";v=\"99\"", |                 "sec-ch-ua" to "\"Chromium\";v=\"91\", \" Not;A Brand\";v=\"99\"", | ||||||
|                 "sec-ch-ua-mobile" to "?0", |                 "sec-ch-ua-mobile" to "?0", | ||||||
|  | @ -236,34 +261,24 @@ class WatchCartoonOnlineProvider : MainAPI() { | ||||||
|                 "user-agent" to "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36", |                 "user-agent" to "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36", | ||||||
|                 "cookie" to "countrytabs=0" |                 "cookie" to "countrytabs=0" | ||||||
|             ) |             ) | ||||||
|         ) |         ).parsed<LinkResponse>() | ||||||
| 
 | 
 | ||||||
|         val link = parseJson<LinkResponse>(linkResponse.text) |         fun loadLink(server: String, link: String?, quality: Qualities) { | ||||||
| 
 |             if (link.isNullOrBlank()) return | ||||||
|         val hdLink = "${link.server}/getvid?evid=${link.hd}" |  | ||||||
|         val sdLink = "${link.server}/getvid?evid=${link.enc}" |  | ||||||
| 
 |  | ||||||
|         if (link.hd.isNotBlank()) |  | ||||||
|             callback.invoke( |             callback.invoke( | ||||||
|                 ExtractorLink( |                 ExtractorLink( | ||||||
|                     this.name, |                     this.name, | ||||||
|                     this.name + " HD", |  | ||||||
|                     hdLink, |  | ||||||
|                     "", |  | ||||||
|                     Qualities.P720.value |  | ||||||
|                 ) |  | ||||||
|             ) |  | ||||||
| 
 |  | ||||||
|         if (link.enc.isNotBlank()) |  | ||||||
|             callback.invoke( |  | ||||||
|                 ExtractorLink( |  | ||||||
|                     this.name, |                     this.name, | ||||||
|                     this.name + " SD", |                     "${server}/getvid?evid=${link}", | ||||||
|                     sdLink, |  | ||||||
|                     "", |                     "", | ||||||
|                     Qualities.P480.value |                     quality.value | ||||||
|                 ) |                 ) | ||||||
|             ) |             ) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         loadLink(link.server, link.hd, Qualities.P720) | ||||||
|  |         loadLink(link.server, link.enc, Qualities.P480) | ||||||
|  |         loadLink(link.server, link.fhd, Qualities.P1080) | ||||||
| 
 | 
 | ||||||
|         return true |         return true | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| 
 |  | ||||||
| package com.lagradost | package com.lagradost | ||||||
| 
 | 
 | ||||||
| import com.lagradost.cloudstream3.plugins.CloudstreamPlugin | import com.lagradost.cloudstream3.plugins.CloudstreamPlugin | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 no-commit
						no-commit