diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e98441e9..56e5a334 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -12,9 +12,10 @@
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
+ android:usesCleartextTraffic="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
- android:theme="@style/AppTheme" android:fullBackupContent="@xml/backup_descriptor">
+ android:theme="@style/AppTheme" android:fullBackupContent="@xml/backup_descriptor" tools:targetApi="m">
diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt
index 94386124..a5b31950 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt
@@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.json.JsonMapper
import com.fasterxml.jackson.module.kotlin.KotlinModule
import com.lagradost.cloudstream3.animeproviders.ShiroProvider
+import com.lagradost.cloudstream3.movieproviders.MeloMovieProvider
import com.lagradost.cloudstream3.utils.ExtractorLink
import java.util.*
import kotlin.collections.ArrayList
@@ -20,8 +21,9 @@ object APIHolder {
private const val defProvider = 0
- val apis = arrayListOf(
- ShiroProvider()
+ val apis = arrayListOf(
+ ShiroProvider(),
+ MeloMovieProvider(),
)
fun getApiFromName(apiName: String?): MainAPI {
@@ -44,6 +46,7 @@ object APIHolder {
abstract class MainAPI {
open val name = "NONE"
open val mainUrl = "NONE"
+ open val instantLinkLoading = false // THIS IS IF THE LINK IS STORED IN THE "DATA"
open fun search(query: String): ArrayList? { // SearchResponse
return null
}
@@ -195,12 +198,14 @@ data class MovieLoadResponse(
val imdbId: Int?,
) : LoadResponse
+data class TvSeriesEpisode(val name: String?, val season : Int?, val episode: Int?, val data : String)
+
data class TvSeriesLoadResponse(
override val name: String,
override val url: String,
override val apiName: String,
override val type: TvType,
- val episodes: ArrayList,
+ val episodes: ArrayList,
override val posterUrl: String?,
override val year: Int?,
diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt
new file mode 100644
index 00000000..1c93ed26
--- /dev/null
+++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/MeloMovieProvider.kt
@@ -0,0 +1,155 @@
+package com.lagradost.cloudstream3.movieproviders
+
+import com.fasterxml.jackson.annotation.JsonProperty
+import com.fasterxml.jackson.module.kotlin.readValue
+import com.lagradost.cloudstream3.*
+import com.lagradost.cloudstream3.utils.ExtractorLink
+import com.lagradost.cloudstream3.utils.getQualityFromName
+import org.jsoup.Jsoup
+import org.jsoup.nodes.Element
+
+class MeloMovieProvider : MainAPI() {
+ override val name: String
+ get() = "MeloMovie"
+ override val mainUrl: String
+ get() = "https://melomovie.com"
+ override val instantLinkLoading: Boolean
+ get() = true
+
+ data class MeloMovieSearchResult(
+ @JsonProperty("id") val id: Int,
+ @JsonProperty("imdb_code") val imdbId: String,
+ @JsonProperty("title") val title: String,
+ @JsonProperty("type") val type: Int, // 1 = MOVIE, 2 = TV-SERIES
+ @JsonProperty("year") val year: Int?, // 1 = MOVIE, 2 = TV-SERIES
+ //"mppa" for tags
+ )
+
+ data class MeloMovieLink(val name: String, val link: String)
+
+ override fun search(query: String): ArrayList? {
+ val url = "$mainUrl/movie/search/?name=$query"
+ val returnValue: ArrayList = ArrayList()
+ val response = khttp.get(url)
+ val mapped = response.let { mapper.readValue>(it.text) }
+ if (mapped.isEmpty()) return returnValue
+
+ for (i in mapped) {
+ val currentUrl = "$mainUrl/movie/${i.id}"
+ val currentPoster = "$mainUrl/assets/images/poster/${i.imdbId}.jpg"
+ if (i.type == 2) { // TV-SERIES
+ returnValue.add(TvSeriesSearchResponse(i.title,
+ currentUrl,
+ currentUrl,
+ this.name,
+ TvType.TvSeries,
+ currentPoster,
+ i.year,
+ null))
+ } else if (i.type == 1) { // MOVIE
+ returnValue.add(MovieSearchResponse(i.title,
+ currentUrl,
+ currentUrl,
+ this.name,
+ TvType.Movie,
+ currentUrl,
+ i.year))
+ }
+ }
+ return returnValue
+ }
+
+ // http not https, the links are not https!
+ private fun fixUrl(url: String): String {
+ if(url.isEmpty()) return ""
+
+ if (url.startsWith("//")) {
+ return "http:$url"
+ }
+ if (!url.startsWith("http")) {
+ return "http://$url"
+ }
+ return url
+ }
+
+ private fun serializeData(element: Element): String {
+ val eps = element.select("> tbody > tr")
+ val parsed = eps.map {
+ try {
+ val tds = it.select("> td")
+ val name = tds[if (tds.size == 5) 1 else 0].text()
+ val url = fixUrl(tds.last().selectFirst("> a").attr("data-lnk").replace(" ", "%20"))
+ MeloMovieLink(name, url)
+ } catch (e: Exception) {
+ MeloMovieLink("", "")
+ }
+ }.filter { it.link != "" && it.name != "" }
+ return mapper.writeValueAsString(parsed)
+ }
+
+ override fun loadLinks(data: String, isCasting: Boolean, callback: (ExtractorLink) -> Unit): Boolean {
+ val links = mapper.readValue>(data)
+ for (link in links) {
+ callback.invoke(ExtractorLink(this.name, link.name, link.link, "", getQualityFromName(link.name), false))
+ }
+ return true
+ }
+
+ override fun load(slug: String): Any? {
+ val response = khttp.get(slug).text
+
+ //backdrop = imgurl
+ fun findUsingRegex(src: String): String? {
+ return src.toRegex().find(response)?.groups?.get(1)?.value ?: return null
+ }
+
+ val imdbId = findUsingRegex("var imdb = \"(tt[0-9]*)\"")?.toIntOrNull()
+ val document = Jsoup.parse(response)
+ val poster = document.selectFirst("img.img-fluid").attr("src")
+ val type = findUsingRegex("var posttype = ([0-9]*)")?.toInt() ?: return null
+ val titleInfo = document.selectFirst("div.movie_detail_title > div > div > h1")
+ val title = titleInfo.ownText()
+ val year = titleInfo.selectFirst("> a").text().replace("(", "").replace(")", "").toIntOrNull()
+ val plot = document.selectFirst("div.col-lg-12 > p").text()
+
+ if (type == 1) { // MOVIE
+ val serialize = document.selectFirst("table.accordion__list")
+ return MovieLoadResponse(title,
+ slug,
+ this.name,
+ TvType.Movie,
+ serializeData(serialize),
+ poster,
+ year,
+ plot,
+ imdbId)
+ } else if (type == 2) {
+ val episodes = ArrayList()
+ val seasons = document.select("div.accordion__card")
+ for (s in seasons) {
+ val season =
+ s.selectFirst("> div.card-header > button > span").text().replace("Season: ", "").toIntOrNull()
+ val localEpisodes = s.select("> div.collapse > div > div > div.accordion__card")
+ for (e in localEpisodes) {
+ val episode =
+ e.selectFirst("> div.card-header > button > span").text().replace("Episode: ", "").toIntOrNull()
+ val links = e.selectFirst("> div.collapse > div > table.accordion__list")
+ val data = serializeData(links)
+ episodes.add(TvSeriesEpisode(null, season, episode, data))
+ }
+ }
+ episodes.reverse()
+ return TvSeriesLoadResponse(title,
+ slug,
+ this.name,
+ TvType.TvSeries,
+ episodes,
+ poster,
+ year,
+ plot,
+ null,
+ imdbId)
+ }
+ return null
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt
index 80840815..824960da 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/ControllerActivity.kt
@@ -77,6 +77,7 @@ class SkipNextEpisodeController(val view: ImageView) : UIController() {
data class MetadataHolder(
val apiName: String,
+ val isMovie: Boolean,
val title: String?,
val poster: String?,
val currentEpisodeIndex: Int,
@@ -91,13 +92,13 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi
init {
view.setImageResource(R.drawable.ic_baseline_playlist_play_24)
view.setOnClickListener {
- // lateinit var dialog: AlertDialog
+ // lateinit var dialog: AlertDialog
val holder = getCurrentMetaData()
if (holder != null) {
val items = holder.currentLinks
if (items.isNotEmpty() && remoteMediaClient?.currentItem != null) {
- // val builder = AlertDialog.Builder(view.context, R.style.AlertDialogCustom)
+ // val builder = AlertDialog.Builder(view.context, R.style.AlertDialogCustom)
/*val builder = BottomSheetDialog(view.context, R.style.AlertDialogCustom)
builder.setTitle("Pick source")*/
val bottomSheetDialog = BottomSheetDialog(view.context)
@@ -212,7 +213,7 @@ class SelectSourceController(val view: ImageView, val activity: ControllerActivi
links.add(it)
}
}
-
+
if (res is Resource.Success) {
val sorted = sortUrls(links)
if (sorted.isNotEmpty()) {
@@ -295,9 +296,9 @@ class ControllerActivity : ExpandedControllerActivity() {
uiMediaController.bindViewToUIController(skipBackButton, SkipTimeController(skipBackButton, false))
uiMediaController.bindViewToUIController(skipForwardButton, SkipTimeController(skipForwardButton, true))
uiMediaController.bindViewToUIController(skipOpButton, SkipNextEpisodeController(skipOpButton))
- /* val progressBar: CastSeekBar? = findViewById(R.id.cast_seek_bar)
+ /* val progressBar: CastSeekBar? = findViewById(R.id.cast_seek_bar)
- progressBar?.backgroundTintList = (UIHelper.adjustAlpha(colorFromAttribute(R.attr.colorPrimary), 0.35f))
-*/
+ progressBar?.backgroundTintList = (UIHelper.adjustAlpha(colorFromAttribute(R.attr.colorPrimary), 0.35f))
+ */
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt
index 73052ab0..51588d58 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/PlayerFragment.kt
@@ -386,11 +386,12 @@ class PlayerFragment : Fragment() {
if (useSystemBrightness) {
// https://developer.android.com/reference/android/view/WindowManager.LayoutParams#screenBrightness
val lp = activity?.window?.attributes
- val currentBrightness = if (lp?.screenBrightness ?: -1.0f <= 0f) (android.provider.Settings.System.getInt(
- context?.contentResolver,
- android.provider.Settings.System.SCREEN_BRIGHTNESS
- ) * (1 / 255).toFloat())
- else lp?.screenBrightness!!
+ val currentBrightness =
+ if (lp?.screenBrightness ?: -1.0f <= 0f) (android.provider.Settings.System.getInt(
+ context?.contentResolver,
+ android.provider.Settings.System.SCREEN_BRIGHTNESS
+ ) * (1 / 255).toFloat())
+ else lp?.screenBrightness!!
val alpha = minOf(
maxOf(
@@ -403,8 +404,7 @@ class PlayerFragment : Fragment() {
progressBarRight?.max = 100 * 100
progressBarRight?.progress = (alpha * 100 * 100).toInt()
- }
- else {
+ } else {
val alpha = minOf(0.95f,
brightness_overlay.alpha + diffY.toFloat() * 0.5f) // 0.05f *if (diffY > 0) 1 else -1
brightness_overlay?.alpha = alpha
@@ -638,6 +638,7 @@ class PlayerFragment : Fragment() {
private var episodes: List = ArrayList()
var currentPoster: String? = null
var currentHeaderName: String? = null
+ var currentIsMovie: Boolean? = null
//region PIP MODE
private fun getPen(code: PlayerEventType): PendingIntent {
@@ -763,6 +764,7 @@ class PlayerFragment : Fragment() {
val index = links.indexOf(getCurrentUrl())
context?.startCast(
apiName,
+ currentIsMovie ?: return@addCastStateListener,
currentHeaderName,
currentPoster,
epData.index,
@@ -893,6 +895,7 @@ class PlayerFragment : Fragment() {
localData = d
currentPoster = d.posterUrl
currentHeaderName = d.name
+ currentIsMovie = !d.isEpisodeBased()
}
}
is Resource.Failure -> {
@@ -1209,8 +1212,8 @@ class PlayerFragment : Fragment() {
}
}
- private fun handlePauseEvent(pause : Boolean) {
- if(pause) {
+ private fun handlePauseEvent(pause: Boolean) {
+ if (pause) {
handlePlayerEvent(PlayerEventType.Pause)
}
}
@@ -1474,6 +1477,7 @@ class PlayerFragment : Fragment() {
}
override fun onPlayerError(error: ExoPlaybackException) {
+ println("CURRENT URL: " + currentUrl.url)
// Lets pray this doesn't spam Toasts :)
when (error.type) {
ExoPlaybackException.TYPE_SOURCE -> {
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt
index c79fe2ab..0667a4af 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt
@@ -29,6 +29,7 @@ import com.google.android.gms.cast.framework.CastContext
import com.google.android.gms.cast.framework.CastState
import com.google.android.material.button.MaterialButton
import com.lagradost.cloudstream3.*
+import com.lagradost.cloudstream3.APIHolder.getApiFromName
import com.lagradost.cloudstream3.UIHelper.colorFromAttribute
import com.lagradost.cloudstream3.UIHelper.fixPaddingStatusbar
import com.lagradost.cloudstream3.UIHelper.getStatusBarHeight
@@ -176,6 +177,7 @@ class ResultFragment : Fragment() {
}
private var currentPoster: String? = null
+ private var currentIsMovie: Boolean? = null
var url: String? = null
@@ -239,22 +241,33 @@ class ResultFragment : Fragment() {
currentLoadingCount++
when (episodeClick.action) {
ACTION_CHROME_CAST_EPISODE -> {
+
+ val skipLoading = if (apiName != null) {
+ getApiFromName(apiName).instantLinkLoading
+ } else false
+
+ var dialog : AlertDialog? = null
val currentLoad = currentLoadingCount
- val builder = AlertDialog.Builder(requireContext(), R.style.AlertDialogCustomTransparent)
- val customLayout = layoutInflater.inflate(R.layout.dialog_loading, null)
- builder.setView(customLayout)
- val dialog = builder.create()
+ if(!skipLoading) {
+ val builder = AlertDialog.Builder(requireContext(), R.style.AlertDialogCustomTransparent)
+ val customLayout = layoutInflater.inflate(R.layout.dialog_loading, null)
+ builder.setView(customLayout)
- dialog.show()
- dialog.setOnDismissListener {
- currentLoadingCount++
+ dialog = builder.create()
+
+ dialog.show()
+ dialog.setOnDismissListener {
+ currentLoadingCount++
+ }
}
+
// Toast.makeText(activity, "Loading links", Toast.LENGTH_SHORT).show()
viewModel.loadEpisode(episodeClick.data, true) { data ->
if (currentLoadingCount != currentLoad) return@loadEpisode
- dialog.dismiss()
+ dialog?.dismiss()
+
when (data) {
is Resource.Failure -> {
Toast.makeText(activity, "Failed to load links", Toast.LENGTH_SHORT).show()
@@ -263,6 +276,7 @@ class ResultFragment : Fragment() {
val eps = currentEpisodes ?: return@loadEpisode
context?.startCast(
apiName ?: return@loadEpisode,
+ currentIsMovie ?: return@loadEpisode,
currentHeaderName,
currentPoster,
episodeClick.data.index,
@@ -354,6 +368,7 @@ class ResultFragment : Fragment() {
currentHeaderName = d.name
currentPoster = d.posterUrl
+ currentIsMovie = !d.isEpisodeBased()
result_openinbrower.setOnClickListener {
val i = Intent(Intent.ACTION_VIEW)
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt
index 164bad76..52e38369 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultViewModel.kt
@@ -104,11 +104,12 @@ class ResultViewModel : ViewModel() {
val episodes = ArrayList()
for ((index, i) in d.episodes.withIndex()) {
episodes.add(context.buildResultEpisode(
- null, // TODO ADD NAMES
+ (i.name
+ ?: (if (i.season != null && i.episode != null) "S${i.season}:E${i.episode}" else null)), // TODO ADD NAMES
null,
- index + 1, //TODO MAKE ABLE TO NOT HAVE SOME EPISODE
- null, // TODO FIX SEASON
- i,
+ i.episode ?: (index + 1),
+ i.season,
+ i.data,
apiName,
(mainId + index + 1).hashCode(),
index,
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt
index 7a8e2b9d..0f2ba48d 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchFragment.kt
@@ -144,7 +144,9 @@ class SearchFragment : Fragment() {
}
}
}
- searchViewModel.search("overlord")
+ allApi.providersActive = requireActivity().getApiSettings()
+
+ searchViewModel.search("iron man")
// (activity as AppCompatActivity).loadResult("https://shiro.is/overlord-dubbed", "overlord-dubbed", "Shiro")
/*
(requireActivity() as AppCompatActivity).supportFragmentManager.beginTransaction()
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchViewModel.kt
index 1cd8abe1..d2dc1077 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchViewModel.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/search/SearchViewModel.kt
@@ -4,6 +4,7 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import com.lagradost.cloudstream3.APIHolder.allApi
import com.lagradost.cloudstream3.APIHolder.apis
import com.lagradost.cloudstream3.MainAPI
import com.lagradost.cloudstream3.mvvm.Resource
@@ -11,15 +12,13 @@ import com.lagradost.cloudstream3.mvvm.safeApiCall
import kotlinx.coroutines.launch
class SearchViewModel : ViewModel() {
- val api: MainAPI = apis[0] //TODO MULTI API
-
private val _searchResponse: MutableLiveData>> = MutableLiveData()
val searchResponse: LiveData>> get() = _searchResponse
fun search(query: String) = viewModelScope.launch {
_searchResponse.postValue(Resource.Loading())
val data = safeApiCall {
- api.search(query)
+ allApi.search(query)
}
_searchResponse.postValue(data as Resource>?)
diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/CastHelper.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/CastHelper.kt
index 6b4dba2a..29eb4fcd 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/utils/CastHelper.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/utils/CastHelper.kt
@@ -31,7 +31,10 @@ object CastHelper {
val link = holder.currentLinks[index]
val movieMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE)
movieMetadata.putString(MediaMetadata.KEY_SUBTITLE,
- (epData.name ?: "Episode ${epData.episode}") + " - ${link.name}")
+ if (holder.isMovie)
+ link.name
+ else
+ (epData.name ?: "Episode ${epData.episode}") + " - ${link.name}")
movieMetadata.putString(MediaMetadata.KEY_TITLE, holder.title)
@@ -58,7 +61,7 @@ object CastHelper {
println("FAILED AND LOAD NEXT")
}
else -> {
- println("FAILED::: " + res.status)
+ //IDK DO SMTH HERE
}
}
}
@@ -67,6 +70,7 @@ object CastHelper {
fun Context.startCast(
apiName: String,
+ isMovie: Boolean,
title: String?,
poster: String?,
currentEpisodeIndex: Int,
@@ -81,7 +85,7 @@ object CastHelper {
val epData = episodes[currentEpisodeIndex]
- val holder = MetadataHolder(apiName, title, poster, currentEpisodeIndex, episodes, currentLinks)
+ val holder = MetadataHolder(apiName, isMovie, title, poster, currentEpisodeIndex, episodes, currentLinks)
val index = startIndex ?: 0
val mediaItem =
@@ -96,7 +100,15 @@ object CastHelper {
startTime ?: 0,
)) {
if (currentLinks.size > index + 1)
- startCast(apiName, title, poster, currentEpisodeIndex, episodes, currentLinks, index + 1, startTime)
+ startCast(apiName,
+ isMovie,
+ title,
+ poster,
+ currentEpisodeIndex,
+ episodes,
+ currentLinks,
+ index + 1,
+ startTime)
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt
index 79be3f3e..e388c97e 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt
@@ -15,7 +15,7 @@ data class ExtractorLink(
val isM3u8: Boolean = false,
)
-fun ExtractorLink.getId() : Int {
+fun ExtractorLink.getId(): Int {
return url.hashCode()
}
@@ -27,6 +27,20 @@ enum class Qualities(var value: Int) {
UHD(3) // 4k
}
+fun getQualityFromName(qualityName: String): Int {
+ return when (qualityName.replace("p", "").replace("P", "")) {
+ "360" -> Qualities.SD
+ "480" -> Qualities.SD
+ "720" -> Qualities.HD
+ "1080" -> Qualities.FullHd
+ "1440" -> Qualities.UHD // I KNOW KINDA MISLEADING
+ "2160" -> Qualities.UHD
+ "4k" -> Qualities.UHD
+ "4K" -> Qualities.UHD
+ else -> Qualities.Unknown
+ }.value
+}
+
private val packedRegex = Regex("""eval\(function\(p,a,c,k,e,.*\)\)""")
fun getPacked(string: String): String? {
return packedRegex.find(string)?.value
diff --git a/app/src/main/res/layout/fragment_result.xml b/app/src/main/res/layout/fragment_result.xml
index 7b175717..be21ed4d 100644
--- a/app/src/main/res/layout/fragment_result.xml
+++ b/app/src/main/res/layout/fragment_result.xml
@@ -248,6 +248,7 @@