Full Code of Sovan22/Tokeii for AI

master 754b8503003b cached
185 files
528.8 KB
132.6k tokens
1 requests
Download .txt
Showing preview only (582K chars total). Download the full file or copy to clipboard to get everything.
Repository: Sovan22/Tokeii
Branch: master
Commit: 754b8503003b
Files: 185
Total size: 528.8 KB

Directory structure:
gitextract_qqda0tz5/

├── .gitignore
├── .idea/
│   ├── .gitignore
│   ├── compiler.xml
│   ├── gradle.xml
│   ├── kotlinc.xml
│   ├── misc.xml
│   └── vcs.xml
├── README.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── demomiru/
│       │               └── tokeiv2/
│       │                   └── ExampleInstrumentedTest.kt
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── demomiru/
│       │   │           └── tokeiv2/
│       │   │               ├── EpisodeAdapter.kt
│       │   │               ├── EpisodeAdapter2.kt
│       │   │               ├── MainActivity.kt
│       │   │               ├── Movie.kt
│       │   │               ├── MovieAdapter.kt
│       │   │               ├── MoviePlayActivity.kt
│       │   │               ├── MovieService.kt
│       │   │               ├── MoviesFragment.kt
│       │   │               ├── SearchFragment.kt
│       │   │               ├── TMDBService.kt
│       │   │               ├── TVShowAdapter.kt
│       │   │               ├── TVShowCardAdapter.kt
│       │   │               ├── TVShowDetails.kt
│       │   │               ├── TVShowFragment.kt
│       │   │               ├── TVshow.kt
│       │   │               ├── VideoPlayActivity.kt
│       │   │               ├── anime/
│       │   │               │   ├── AnimeAdapter.kt
│       │   │               │   ├── AnimeDetailsFragment.kt
│       │   │               │   ├── AnimeFragment.kt
│       │   │               │   └── AnimeInfo.kt
│       │   │               ├── extractors/
│       │   │               │   ├── CorrectTitleSelection.kt
│       │   │               │   ├── PrMovies.kt
│       │   │               │   └── Vidplay.kt
│       │   │               ├── history/
│       │   │               │   ├── QueryRepository.kt
│       │   │               │   ├── SearchApp.kt
│       │   │               │   ├── SearchDatabase.kt
│       │   │               │   ├── SearchHistory.kt
│       │   │               │   ├── SearchHistoryAdapter.kt
│       │   │               │   ├── SearchHistoryAdapter2.kt
│       │   │               │   └── SearchHistoryDao.kt
│       │   │               ├── subtitles/
│       │   │               │   ├── SubTrackAdapter.kt
│       │   │               │   └── Subtitles.kt
│       │   │               ├── tracks/
│       │   │               │   └── TrackAdapter.kt
│       │   │               ├── utils/
│       │   │               │   ├── DudeFilmsUtils.kt
│       │   │               │   ├── Extractor.kt
│       │   │               │   ├── GoMovies.kt
│       │   │               │   ├── GogoAnime.kt
│       │   │               │   ├── OpenSubtitle.kt
│       │   │               │   ├── SmashyStream.kt
│       │   │               │   ├── SuperstreamUtils.kt
│       │   │               │   ├── VidSrc.kt
│       │   │               │   ├── VidSrcUtils.kt
│       │   │               │   ├── ViewModelsTokei.kt
│       │   │               │   ├── colors.txt
│       │   │               │   └── retrofitBuilder.kt
│       │   │               └── watching/
│       │   │                   ├── ContinueWatching.kt
│       │   │                   ├── ContinueWatchingAdapter.kt
│       │   │                   ├── ContinueWatchingDao.kt
│       │   │                   ├── ContinueWatchingDatabase.kt
│       │   │                   └── ContinueWatchingRepository.kt
│       │   └── res/
│       │       ├── anim/
│       │       │   ├── enter_anim.xml
│       │       │   ├── enter_from_bottom.xml
│       │       │   ├── exit_anim.xml
│       │       │   ├── exit_to_top.xml
│       │       │   ├── go_left.xml
│       │       │   ├── go_right.xml
│       │       │   ├── layout_animation.xml
│       │       │   ├── nav_enter_anim.xml
│       │       │   ├── nav_exit_anim.xml
│       │       │   ├── nav_pop_enter.xml
│       │       │   ├── nav_pop_exit.xml
│       │       │   ├── pop_enter.xml
│       │       │   ├── pop_exit.xml
│       │       │   ├── rotate_around_center_point.xml
│       │       │   ├── rotate_left.xml
│       │       │   ├── rotate_right.xml
│       │       │   ├── slide_from_uo.xml
│       │       │   ├── slide_in.xml
│       │       │   ├── slide_in_right.xml
│       │       │   └── slide_out.xml
│       │       ├── drawable/
│       │       │   ├── anime_bottom_nav.xml
│       │       │   ├── background_search_history.xml
│       │       │   ├── background_text.xml
│       │       │   ├── baseline_cancel_24.xml
│       │       │   ├── baseline_double_arrow_24.xml
│       │       │   ├── baseline_history_24.xml
│       │       │   ├── baseline_keyboard_arrow_down_24.xml
│       │       │   ├── baseline_keyboard_arrow_up_24.xml
│       │       │   ├── baseline_lock_open_24.xml
│       │       │   ├── baseline_play_arrow_24.xml
│       │       │   ├── baseline_play_circle_24.xml
│       │       │   ├── baseline_search_24.xml
│       │       │   ├── baseline_zoom_out_map_24.xml
│       │       │   ├── custom_thumb.xml
│       │       │   ├── delete.xml
│       │       │   ├── down_arrow.xml
│       │       │   ├── edit.xml
│       │       │   ├── fill_screen.xml
│       │       │   ├── fit_screen.xml
│       │       │   ├── focus.xml
│       │       │   ├── focus_search.xml
│       │       │   ├── gradient_fill.xml
│       │       │   ├── gradient_fill_bottom.xml
│       │       │   ├── gradient_fill_text.xml
│       │       │   ├── ic_baseline_keyboard_backspace_24.xml
│       │       │   ├── ic_forward.xml
│       │       │   ├── ic_launcher_background.xml
│       │       │   ├── ic_menu.xml
│       │       │   ├── ic_rewind.xml
│       │       │   ├── ic_rotation.xml
│       │       │   ├── icon_play.xml
│       │       │   ├── image_view_round.xml
│       │       │   ├── more.xml
│       │       │   ├── netflix_audio_subtitles.xml
│       │       │   ├── netflix_brightness_four.xml
│       │       │   ├── netflix_brightness_one.xml
│       │       │   ├── netflix_brightness_three.xml
│       │       │   ├── netflix_brightness_two.xml
│       │       │   ├── netflix_lock_black.xml
│       │       │   ├── netflix_pause_button.xml
│       │       │   ├── netflix_speed.xml
│       │       │   ├── netflix_unlock.xml
│       │       │   ├── next_episode.xml
│       │       │   ├── play_ripple.xml
│       │       │   ├── player_controller_bg.xml
│       │       │   ├── properties.xml
│       │       │   ├── quality_24.xml
│       │       │   ├── radio_group_tab_bg.xml
│       │       │   ├── rectangle_box.xml
│       │       │   ├── rectangle_box_slim.xml
│       │       │   ├── selected_quality.xml
│       │       │   ├── selected_subtitle.xml
│       │       │   ├── share.xml
│       │       │   ├── share_link.xml
│       │       │   ├── tab_selector.xml
│       │       │   ├── tab_text_color_selector.xml
│       │       │   ├── volume_up_24.xml
│       │       │   └── white_round.xml
│       │       ├── drawable-v24/
│       │       │   └── ic_launcher_foreground.xml
│       │       ├── font/
│       │       │   ├── exo_2.xml
│       │       │   └── exo_2_thin.xml
│       │       ├── layout/
│       │       │   ├── activity_main.xml
│       │       │   ├── activity_movie_play.xml
│       │       │   ├── activity_video_play.xml
│       │       │   ├── card_view.xml
│       │       │   ├── custom_video_player2.xml
│       │       │   ├── dropdown_menu.xml
│       │       │   ├── episode_expanded_view.xml
│       │       │   ├── episode_item_viem.xml
│       │       │   ├── fragment_anime.xml
│       │       │   ├── fragment_anime_details.xml
│       │       │   ├── fragment_correct_title_selection.xml
│       │       │   ├── fragment_movies.xml
│       │       │   ├── fragment_search.xml
│       │       │   ├── fragment_tv_show.xml
│       │       │   ├── fragment_tv_show_details.xml
│       │       │   ├── item_view.xml
│       │       │   ├── search_item.xml
│       │       │   ├── sub_view.xml
│       │       │   ├── test.xml
│       │       │   └── track_item.xml
│       │       ├── menu/
│       │       │   └── bottom_nav.xml
│       │       ├── mipmap-anydpi-v26/
│       │       │   ├── ic_launcher.xml
│       │       │   └── ic_launcher_round.xml
│       │       ├── navigation/
│       │       │   └── nav_main.xml
│       │       ├── transition/
│       │       │   └── container_transform.xml
│       │       ├── values/
│       │       │   ├── colors.xml
│       │       │   ├── font_certs.xml
│       │       │   ├── preloaded_fonts.xml
│       │       │   ├── strings.xml
│       │       │   └── themes.xml
│       │       ├── values-night/
│       │       │   └── themes.xml
│       │       └── xml/
│       │           ├── backup_rules.xml
│       │           └── data_extraction_rules.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── demomiru/
│                       └── tokeiv2/
│                           └── ExampleUnitTest.kt
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties


================================================
FILE: .idea/.gitignore
================================================
# Default ignored files
/shelf/
/workspace.xml


================================================
FILE: .idea/compiler.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="CompilerConfiguration">
    <bytecodeTargetLevel target="17" />
  </component>
</project>

================================================
FILE: .idea/gradle.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="GradleMigrationSettings" migrationVersion="1" />
  <component name="GradleSettings">
    <option name="linkedExternalProjectsSettings">
      <GradleProjectSettings>
        <option name="testRunner" value="GRADLE" />
        <option name="distributionType" value="DEFAULT_WRAPPED" />
        <option name="externalProjectPath" value="$PROJECT_DIR$" />
        <option name="modules">
          <set>
            <option value="$PROJECT_DIR$" />
            <option value="$PROJECT_DIR$/app" />
          </set>
        </option>
      </GradleProjectSettings>
    </option>
  </component>
</project>

================================================
FILE: .idea/kotlinc.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="KotlinJpsPluginSettings">
    <option name="version" value="1.9.0" />
  </component>
</project>

================================================
FILE: .idea/misc.xml
================================================
<project version="4">
  <component name="ExternalStorageConfigurationManager" enabled="true" />
  <component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
    <output url="file://$PROJECT_DIR$/build/classes" />
  </component>
  <component name="ProjectType">
    <option name="id" value="Android" />
  </component>
  <component name="VisualizationToolProject">
    <option name="state">
      <ProjectState>
        <option name="scale" value="0.025" />
      </ProjectState>
    </option>
  </component>
</project>

================================================
FILE: .idea/vcs.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="VcsDirectoryMappings">
    <mapping directory="$PROJECT_DIR$" vcs="Git" />
  </component>
</project>

================================================
FILE: README.md
================================================
# Tokei    <img src="https://github.com/Sovan22/Tokeii/blob/master/app/tokei_logo.jpeg" width="40" height="40" alt="Image Description">
Movie and TV Streaming App 


## Download the app here:
# [tokei-release_v1.1.4](https://github.com/Sovan22/Tokeii/releases/download/v1.1.4-tokei/tokei-v1.1.4.apk)
Compatibility : Android 7+

## Features:
+ **AdFree**
+ No tracking/analytics
+ Lesser Loading Time
+ Good sources for Indian OTT Content

## App Demo

https://github.com/Sovan22/Tokeii/assets/12212201/b417be95-d728-4af8-9809-b2fcdfde1c5f



<img src="https://github.com/Sovan22/Tokeii/blob/master/app/movies.jpg" width="400" height="900" alt="Movies">  <img src="https://github.com/Sovan22/Tokeii/blob/master/app/search.jpg" width="400" height="900" alt="Search">

<img src="https://github.com/Sovan22/Tokeii/blob/master/app/player.jpg"  alt="Player">

## DISCLAIMER

+ Tokei only scrapes links from various websites and makes it easier for users to find tvShows and movies. 
+ Tokei doesn't host any of the contents found inside Tokei. Any and all images and movie/tv information found in the app are taken from various public APIs (TMDb). 
+ Furthermore, all of the movie/tv links found in Tokei are taken from various 3rd party hosting websites.
+ Tokei or it's owners aren't liable for any misuse of any of the contents found inside or outside of the app and cannot be held accountable for the distribution of any of the contents found inside the app. 
+ By using Tokei, you comply to the fact that the developer of the app is not responsible for any of the contents found in the app; nonetheless they may or may not be from their legitimate sources. 
+ If the internet infringement issues are involved, please contact the source website. The developer does not assume any legal responsibility.


================================================
FILE: app/.gitignore
================================================
/build

================================================
FILE: app/build.gradle
================================================


plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id("androidx.navigation.safeargs.kotlin")
    id("com.google.devtools.ksp")


}

def localProperties = new Properties()
localProperties.load(new FileInputStream(rootProject.file("local.properties")))

android {
    namespace 'com.demomiru.tokeiv2'
    compileSdk 34

    packagingOptions {
        pickFirst "META-INF/DEPENDENCIES"
        exclude 'mozilla/public-suffix-list.txt'
    }
    defaultConfig {
        applicationId "com.demomiru.tokeiv2"
        minSdk 26
        targetSdk 34
        versionCode 1
        versionName "1.1.4"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        buildConfigField("String", "OPEN_SUBTITLE_API_KEY", "\"${localProperties["OPEN_SUBTITLE_API_KEY"]}\"")
        buildConfigField("String", "TMDB_API_KEY", "\"${localProperties["TMDB_API_KEY"]}\"")
        buildConfigField("String", "TMDB_TOKEN", "\"${localProperties["TMDB_TOKEN"]}\"")
        buildConfigField("String", "SUPERSTREAM_API1", "\"${localProperties["SUPERSTREAM_API1"]}\"")
        buildConfigField("String", "SUPERSTREAM_API2", "\"${localProperties["SUPERSTREAM_API2"]}\"")
        buildConfigField("String", "PROXY_URL", "\"${localProperties["PROXY_URL"]}\"")
        buildConfigField("String", "MAL_API", "\"${localProperties["MAL_API"]}\"")
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    buildFeatures{
        viewBinding true
        buildConfig true
    }
}

dependencies {

    def paging_version = "3.2.1"

    implementation "androidx.paging:paging-runtime:$paging_version"
    implementation 'com.github.ismaeldivita:chip-navigation-bar:1.4.0'

    implementation 'androidx.core:core-ktx:1.9.0'
    implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.3.1"
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'at.blogc:expandabletextview:1.0.5'
    implementation "androidx.navigation:navigation-fragment-ktx:2.7.1"
    implementation "androidx.navigation:navigation-ui-ktx:2.7.1"
    implementation 'com.google.firebase:firebase-firestore-ktx:24.1.0'
    ksp("androidx.room:room-compiler:2.5.0")
    implementation "androidx.activity:activity-ktx:1.7.2"
    implementation 'androidx.appcompat:appcompat:1.6.1'
//    implementation("it.skrape:skrapeit:1.2.2")
//    implementation 'org.jsoup:jsoup:1.14.3'
//    implementation 'org.danilopianini:khttp:1.3.1'
    implementation 'com.github.Blatzar:NiceHttp:0.4.4'
    implementation 'com.fasterxml.jackson.module:jackson-module-kotlin:2.15.2'
    implementation("com.squareup.okhttp3:okhttp:4.10.0")
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2"
    implementation 'com.google.android.material:material:1.9.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    implementation("io.coil-kt:coil:2.4.0")
    // Room components
    implementation "androidx.room:room-runtime:2.5.0"
//    annotationProcessor "androidx.room:room-compiler:2.5.2"
    implementation "androidx.room:room-ktx:2.5.0"

    //ExoPlayer
    implementation "androidx.media3:media3-exoplayer:1.1.1"
    implementation "androidx.media3:media3-exoplayer-hls:1.1.1"
    implementation "androidx.media3:media3-exoplayer-dash:1.1.1"
    implementation "androidx.media3:media3-ui:1.1.1"


    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}


================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

================================================
FILE: app/src/androidTest/java/com/demomiru/tokeiv2/ExampleInstrumentedTest.kt
================================================
package com.demomiru.tokeiv2

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
 * Instrumented test, which will execute on an Android device.
 *
 * See [testing documentation](http://d.android.com/tools/testing).
 */
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
    @Test
    fun useAppContext() {
        // Context of the app under test.
        val appContext = InstrumentationRegistry.getInstrumentation().targetContext
        assertEquals("com.demomiru.tokeiv2", appContext.packageName)
    }
}

================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <application
        android:allowBackup="true"

        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        android:usesCleartextTraffic="true"
        tools:targetApi="31">
        <activity
            android:name=".VideoPlayActivity"
            android:screenOrientation="landscape"
            android:exported="false" />
        <activity
            android:name=".MoviePlayActivity"
            android:exported="false"
            android:screenOrientation="landscape" />
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:screenOrientation="fullSensor"
            tools:ignore="LockedOrientationActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <meta-data
            android:name="preloaded_fonts"
            android:resource="@array/preloaded_fonts" />
    </application>

</manifest>

================================================
FILE: app/src/main/java/com/demomiru/tokeiv2/EpisodeAdapter.kt
================================================
package com.demomiru.tokeiv2



import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class EpisodeAdapter(private val episodeNumber : List<Int>,
private val clickHandler : (Int) -> Unit
) : RecyclerView.Adapter<EpisodeAdapter.ViewHolder>() {

    class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView){
        val episodeText : TextView = itemView.findViewById(R.id.episode_no_text)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
       val view = LayoutInflater.from(parent.context).inflate(R.layout.episode_item_viem,parent,false)
        return ViewHolder(view)
    }

    @SuppressLint("SetTextI18n")
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val episodeN = episodeNumber[position]
        holder.episodeText.text = "Episode $episodeN"
        holder.itemView.setOnClickListener {
            clickHandler(episodeN)
        }
    }

    override fun getItemCount(): Int {
        return episodeNumber.size
    }
}

================================================
FILE: app/src/main/java/com/demomiru/tokeiv2/EpisodeAdapter2.kt
================================================
package com.demomiru.tokeiv2



import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.cardview.widget.CardView
import androidx.recyclerview.widget.RecyclerView
import at.blogc.android.views.ExpandableTextView
import coil.load


//class MyDiffUtilCallback : DiffUtil.ItemCallback<MyItem>() {
//    override fun areItemsTheSame(oldItem: MyItem, newItem: MyItem): Boolean {
//        // Return true if items are the same.
//        return oldItem.id == newItem.id
//    }
//
//    override fun areContentsTheSame(oldItem: MyItem, newItem: MyItem): Boolean {
//        // Return true if contents are the same.
//        return oldItem == newItem
//    }
//}


class EpisodeAdapter2(private val episodes : List<Episode>,
                      private val clickHandler : (Episode) -> Unit
) : RecyclerView.Adapter<EpisodeAdapter2.ViewHolder>() {

    class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView){
        val episodeText : TextView = itemView.findViewById(R.id.episode_no_text)
        val episodeImg : ImageView = itemView.findViewById(R.id.episode_img)
        val episodeOverview : ExpandableTextView = itemView.findViewById(R.id.episode_overview_text)
        val fl : FrameLayout = itemView.findViewById(R.id.expanded_episode_fl)
        val epCard: CardView = itemView.findViewById(R.id.episode_card)
        val expandText : ImageView = itemView.findViewById(R.id.expand_text)
        val expandableTextView : ExpandableTextView = itemView.findViewById(R.id.episode_overview_text)
        val episodeNumber : TextView = itemView.findViewById(R.id.episode_number)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
       val view = LayoutInflater.from(parent.context).inflate(R.layout.test,parent,false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val episode = episodes[position]
        holder.episodeText.text = episode.name
        holder.episodeNumber.text = episode.episode_number
        holder.episodeOverview.text = episode.overview
        holder.episodeImg.load("https://image.tmdb.org/t/p/w500${episode.still_path}")
        holder.fl.setOnClickListener {
            clickHandler(episode)
        }
        holder.epCard.setOnClickListener {
            holder.fl.performClick()
//            clickHandler(episode)
        }
        val etv = holder.expandableTextView
        etv.setAnimationDuration(750L)
        holder.expandText.setOnClickListener {
            if(etv.isExpanded){
                etv.collapse()
                holder.expandText.load(R.drawable.baseline_keyboard_arrow_down_24)
            }else{
                etv.expand()
                holder.expandText.load(R.drawable.baseline_keyboard_arrow_up_24)
            }
        }



    }

    override fun getItemCount(): Int {
        return episodes.size
    }
}

================================================
FILE: app/src/main/java/com/demomiru/tokeiv2/MainActivity.kt
================================================
package com.demomiru.tokeiv2

import android.annotation.SuppressLint
import android.app.AlertDialog
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.KeyEvent
import android.view.View
import android.widget.TextView
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.widget.NestedScrollView
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavOptions
import androidx.navigation.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.demomiru.tokeiv2.utils.ContinueWatchingViewModel2
import com.demomiru.tokeiv2.utils.ContinueWatchingViewModelFactory2
import com.demomiru.tokeiv2.utils.addRecyclerAnimation
import com.demomiru.tokeiv2.utils.passData
import com.demomiru.tokeiv2.watching.ContinueWatching
import com.demomiru.tokeiv2.watching.ContinueWatchingAdapter
import com.demomiru.tokeiv2.watching.ContinueWatchingDatabase
import com.demomiru.tokeiv2.watching.ContinueWatchingRepository
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.common.primitives.UnsignedBytes.toInt
import com.google.gson.Gson
import com.lagradost.nicehttp.Requests
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
import org.json.JSONArray
import org.jsoup.Jsoup


@Suppress("DEPRECATION")
class MainActivity : AppCompatActivity() {
    private val version = 114
    private val gson = Gson()
    private lateinit var watchHistoryRc : RecyclerView
    private val database by lazy { ContinueWatchingDatabase.getInstance(this) }
    private val watchHistoryDao by lazy { database.watchDao() }
    private val app = Requests()
    private lateinit var viewModelFactory: ContinueWatchingViewModelFactory2
    private val viewModel: ContinueWatchingViewModel2 by viewModels(
        factoryProducer = {
            viewModelFactory
        }
    )
    private var currentFragment = MutableLiveData(R.id.moviesFragment)
    private lateinit var continueText: TextView
    private lateinit var bottomNavigationView : BottomNavigationView

    private var nestedScrollView : NestedScrollView? = null
    private lateinit var adapter: ContinueWatchingAdapter
    private lateinit var continueWatchingRepository: ContinueWatchingRepository
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewModelFactory = ContinueWatchingViewModelFactory2(watchHistoryDao)
        val options = NavOptions.Builder()
            .setEnterAnim(R.anim.enter_from_bottom)
            .setExitAnim(R.anim.exit_to_top)
            .build()

        nestedScrollView = findViewById(R.id.nestedScrollView)
        val navController = findNavController(R.id.nav_host_fragment)
        bottomNavigationView = findViewById(R.id.bottom_nav_bar)
        continueWatchingRepository = ContinueWatchingRepository(watchHistoryDao)
        watchHistoryRc = findViewById(R.id.watch_history_rc)
        watchHistoryRc.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL,false)
        continueText = findViewById(R.id.continue_watching_text)






        adapter = ContinueWatchingAdapter{it,delete->
            if(delete){
                lifecycleScope.launch  (Dispatchers.IO) {
                    continueWatchingRepository.delete(it)
//                    continueWatchingRepository.loadData()
                }
            }
            else {
                startActivity(passData(it, this))
            }

        }


        watchHistoryRc.adapter = adapter
       bottomNavigationView.setOnNavigationItemSelectedListener { item ->
            when (item.itemId) {
                R.id.moviesFragment -> {
                    navController.navigate(R.id.moviesFragment, null, options)
                    if (viewModel.allWatchHistory.value?.size !=0){
                        watchHistoryRc.visibility = View.VISIBLE
                        continueText.visibility = View.VISIBLE
                        currentFragment.value = R.id.moviesFragment
                    }

                }
                R.id.searchFragment -> {
                    navController.navigate(R.id.searchFragment, null, options)
                    watchHistoryRc.visibility = View.GONE
                    continueText.visibility = View.GONE
                    currentFragment.value = R.id.searchFragment
                }
                R.id.TVShowFragment -> {
                    navController.navigate(R.id.TVShowFragment, null, options)
                    if (viewModel.allWatchHistory.value?.size !=0){
                        watchHistoryRc.visibility = View.VISIBLE
                        continueText.visibility = View.VISIBLE
                        currentFragment.value = R.id.TVShowFragment
                    }

                }
                R.id.animeFragment ->{
                    navController.navigate(R.id.animeFragment,null,options)
                    if (viewModel.allWatchHistory.value?.size !=0){
                        watchHistoryRc.visibility = View.VISIBLE
                        continueText.visibility = View.VISIBLE
                        currentFragment.value = R.id.animeFragment
                    }
                }
            }
            true
        }
        bottomNavigationView.setOnNavigationItemReselectedListener {
            return@setOnNavigationItemReselectedListener
        }
//        bottomNavigationView.selectedItemId = R.id.animeFragment

        lifecycleScope.launch (Dispatchers.IO){
//            val update = app.get("https://github.com/Sovan22/Tokeii/").document.select("article.markdown-body.entry-content.container-lg .anchor")[2].attr("href").substringAfter("v").toInt()
            val client = OkHttpClient()
            val request = Request.Builder()
                .url("https://api.github.com/repos/Sovan22/Tokeii/releases").build()
            val response = client.newCall(request).execute()
            if (response.isSuccessful) {
                val releases = JSONArray(response.body.string())
                val update = gson.fromJson(releases.getJSONObject(0).toString(),Release::class.java).tag_name.replace(".","").replace("v","").replace("-tokei","").toInt()
//                [2].attr("href").substringAfter("v").toInt()
                println(update)
                if (version < update)
                    withContext(Dispatchers.Main) {
                        showDialog()
                    }
            }
        }



    }

    data class Release(val tag_name:String)
    fun triggerSearchKeyPress() {
        val enterKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER)
        dispatchKeyEvent(enterKeyEvent)

    }


    @SuppressLint("SetTextI18n")
    override fun onResume() {
//        viewModel.currentFragment.observe(this){
//            if(it == R.id.searchFragment ){
//                watchHistoryRc.visibility = View.GONE
//                continueText.visibility = View.GONE
//            }
//            else{
//                watchHistoryRc.visibility = View.VISIBLE
//                continueText.visibility = View.VISIBLE
//            }
//        }

//        viewModel.showContinue.observe(this){
//            if(!it){
//                watchHistoryRc.visibility = View.GONE
//                continueText.visibility = View.GONE
//            }
//            else{
//                watchHistoryRc.visibility = View.VISIBLE
//                continueText.visibility = View.VISIBLE
//            }
//        }
            val viewStateObserver = Observer<List<ContinueWatching>> {watchFrom ->
            if(watchFrom.isNotEmpty()){
                watchHistoryRc.visibility = View.VISIBLE
                continueText.visibility = View.VISIBLE

                adapter.submitList(watchFrom)
                addRecyclerAnimation(watchHistoryRc,adapter)
                viewModel.currentFragment.observe(this){

                    if(it == R.id.searchFragment || it == R.id.TVShowDetails || it == R.id.animeDetailsFragment ){
                        watchHistoryRc.visibility = View.GONE
                        continueText.visibility = View.GONE
                    }
                    else{
                        watchHistoryRc.visibility = View.VISIBLE
                        continueText.visibility = View.VISIBLE
                    }
                }
//                if(currentFragment.value  == R.id.searchFragment){
//                    watchHistoryRc.visibility = View.GONE
//                    continueText.visibility = View.GONE
//                }else
//                {
//                    watchHistoryRc.visibility = View.VISIBLE
//                    continueText.visibility = View.VISIBLE
//                }
            }
            else{

                watchHistoryRc.visibility = View.GONE
                continueText.visibility = View.GONE
            }

        }
        viewModel.allWatchHistory.observe(this,viewStateObserver)
        viewModel.currentFragment.observe(this){
            bottomNavigationView.selectedItemId = it
        }
        super.onResume()
    }

    private fun showDialog(){
        val builder = AlertDialog.Builder(this)


        builder.setMessage("There is an update available to this app")
            .setTitle("Update Found")


        builder.setPositiveButton("Download"){ dialog, _ ->
            // User clicked OK button
            val url = "https://github.com/Sovan22/Tokeii/releases/"
            val intent = Intent(Intent.ACTION_VIEW)
            intent.data = Uri.parse(url)
            startActivity(intent)
            dialog.dismiss()
        }
        builder.setNegativeButton("Cancel"){ _, _ ->
            // User cancelled the dialog
        }

        val dialog = builder.create()
        dialog.show()
    }

    override fun onBackPressed() {
        if(viewModel.currentFragment.value == R.id.searchFragment && viewModel.searchOpen.value == true) {

            viewModel.searchOpen.value = false

        }
        else
            super.onBackPressed()
    }

}

================================================
FILE: app/src/main/java/com/demomiru/tokeiv2/Movie.kt
================================================
package com.demomiru.tokeiv2

import java.io.Serializable


data class Movie(
    val id : String,
    val original_language:String,
    val production_countries:List<Prod>,
    val title: String,
    val poster_path : String,
    val release_date : String
) : Serializable

data class Prod(
    val iso_3166_1 : String,
    val name: String
)
data class MovieArray(
    val movieFile : ArrayList<MovieFile>
)

data class MovieFile(
    val file: String, //episode file
    val title: String// language
)

data class MovieIMDB(
    val id: String,
    val imdb_id : String,
    val external_ids: ExternalIDs
)



data class Keys(
    val file: String,
    val key : String
)


================================================
FILE: app/src/main/java/com/demomiru/tokeiv2/MovieAdapter.kt
================================================
package com.demomiru.tokeiv2

import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView
import androidx.paging.PagingDataAdapter
import androidx.paging.PagingSource
import androidx.paging.PagingState
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import coil.load
import com.demomiru.tokeiv2.utils.retrofitBuilder
import com.demomiru.tokeiv2.utils.yearExtract

class MovieAdapter(private val clickHandler : (Movie) -> Unit) :
    ListAdapter<Movie,MovieAdapter.ViewHolder>(differCallback) {

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val imageView: ImageView = itemView.findViewById(R.id.image_view)
        val titleTextView: TextView = itemView.findViewById(R.id.title_text_view)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_view,parent,false)
        return ViewHolder(view)
    }

    companion object {
        val differCallback = object : DiffUtil.ItemCallback<Movie>() {
            override fun areItemsTheSame(oldItem: Movie, newItem: Movie): Boolean {
                return oldItem.id == newItem.id
            }

            override fun areContentsTheSame(oldItem: Movie, newItem: Movie): Boolean {
                return oldItem == newItem
            }
        }
    }



    @SuppressLint("SetTextI18n")
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val movie = getItem(position)
        holder.titleTextView.text = movie.title + " (${yearExtract(movie.release_date)})"
        holder.imageView.load("https://image.tmdb.org/t/p/w500${movie.poster_path}")
        holder.itemView.setOnClickListener {
            clickHandler(movie)
        }
    }

}

class MoviesPagingSource(private val list: Int): PagingSource<Int, Movie>() {
    private val retrofit = retrofitBuilder()
    private val movieService = retrofit.create(MovieService::class.java)
    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Movie> {
        return try {
            val currentPage = params.key ?: 1
            val response = when(list){
                1-> movieService.getPopularMovies(BuildConfig.TMDB_API_KEY,"en-US",currentPage)
                2-> movieService.getTrendingMovies(BuildConfig.TMDB_API_KEY, "en-US",currentPage)
                3-> movieService.getTopRatedMovies(BuildConfig.TMDB_API_KEY,"en-US",currentPage)
                else -> throw Exception("wrong list parameter input")
            }

            val data = response.body()!!.results
            val responseData = mutableListOf<Movie>()
            responseData.addAll(data)

            LoadResult.Page(
                data = responseData,
                prevKey = if (currentPage == 1) null else -1,
                nextKey = currentPage.plus(1)
            )
        } catch (e: Exception) {
            LoadResult.Error(e)
        }

    }


    override fun getRefreshKey(state: PagingState<Int, Movie>): Int? {
        return null
    }


}

class MovieAdapter2(
    private val clickHandler : (Movie) -> Unit
) :
    PagingDataAdapter<Movie,MovieAdapter2.ViewHolder>(differCallback) {

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val imageView: ImageView = itemView.findViewById(R.id.image_view)
        val titleTextView: TextView = itemView.findViewById(R.id.title_text_view)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_view,parent,false)
        return ViewHolder(view)
    }

    companion object {
        val differCallback = object : DiffUtil.ItemCallback<Movie>() {
            override fun areItemsTheSame(oldItem: Movie, newItem: Movie): Boolean {
                return oldItem.id == newItem.id
            }

            override fun areContentsTheSame(oldItem: Movie, newItem: Movie): Boolean {
                return oldItem == newItem
            }
        }
    }



    @SuppressLint("SetTextI18n")
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val movie = getItem(position)!!
        holder.titleTextView.text = movie.title + " (${yearExtract(movie.release_date)})"
        holder.imageView.load("https://image.tmdb.org/t/p/w500${movie.poster_path}")
        holder.itemView.setOnClickListener {
            clickHandler(movie)
        }
        holder.setIsRecyclable(false)
    }

}


================================================
FILE: app/src/main/java/com/demomiru/tokeiv2/MoviePlayActivity.kt
================================================
package com.demomiru.tokeiv2

import android.annotation.SuppressLint
import android.content.Context
import android.content.res.Resources
import android.net.Uri

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.MotionEvent

import android.view.View
import android.view.ViewGroup


import android.webkit.WebChromeClient

import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.FrameLayout

import android.widget.ProgressBar
import android.widget.Toast


import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.lifecycleScope


import androidx.media3.common.Player.*
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.demomiru.tokeiv2.extractors.PrMovies
import com.demomiru.tokeiv2.extractors.ResultsAdapter
import com.demomiru.tokeiv2.extractors.SearchResponse
import com.demomiru.tokeiv2.utils.Extractor
import com.demomiru.tokeiv2.utils.GoMovies
import com.demomiru.tokeiv2.utils.GogoAnime
import com.demomiru.tokeiv2.utils.SmashyStream
import com.demomiru.tokeiv2.utils.SuperstreamUtils

import com.demomiru.tokeiv2.utils.getMovieImdb
import com.demomiru.tokeiv2.utils.getMovieLink
import com.demomiru.tokeiv2.utils.getTvImdb
import com.demomiru.tokeiv2.utils.getTvLink


import com.demomiru.tokeiv2.utils.passVideoData


import com.demomiru.tokeiv2.watching.ContinueWatching

import com.demomiru.tokeiv2.watching.VideoData
import com.google.gson.Gson
import kotlinx.coroutines.Dispatchers

import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext


import kotlin.Exception


@Suppress("DEPRECATION")
class MoviePlayActivity : AppCompatActivity(){
    private val gson = Gson()
    private lateinit var webView : WebView
    private  var fullscreenContainer: FullscreenHolder? = null
    private var animeEp : List<GogoAnime.Episode> = listOf()
    private var isSuper = false
    private var superId: Int? = null
    private var IMDBid: String? = null
    private val superStream = SuperstreamUtils()
    private lateinit var loading:ProgressBar
    private lateinit var id:String
//    private var clickedMiddle = false
    private lateinit var resultRc : RecyclerView
    private var animeUrl = ""
    private var season: Int = 1
    private var episode: Int = 1
    private var origin : String = ""
    private var year : String = ""
    private var seekProgress : Int = 0
    private var imgLink : String? = null
    private lateinit var title:String
    private var type : String? = null
    private val videoUrl = MutableLiveData<String?>()
    private var subUrl : MutableList<String> = mutableListOf()
    private var source : String? = null

    private val COVER_SCREEN_PARAMS = FrameLayout.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
    private val prMovies = PrMovies()
    private lateinit var url : String

//    private val args : MoviePlayActivityArgs by navArgs()
    @SuppressLint("SetJavaScriptEnabled")


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_movie_play)
        Log.i("Start", "Time")
        resultRc = findViewById(R.id.results_rc)
        val bundle = intent.extras
        type = bundle?.getString("type")
        when (type) {
        "movie" -> {
            val data = bundle?.getSerializable("Data") as? Movie

            origin = data!!.original_language
            year = data.release_date.substringBefore("-")
            if(origin == "kn" || origin == "ml" || origin == "ta" || origin == "te")
                origin = "hi"
            id = data.id
            title = data.title
            imgLink = data.poster_path
        }
        "tvshow" -> {
            val data =  bundle?.getSerializable("Data") as? Episode

            id = bundle?.getString("id")!!
            title = bundle.getString("showTitle")!!
            imgLink = bundle.getString("poster")

            season = data!!.season_number.toInt()
            episode = data.episode_number.toInt()

        }
        "anime" ->{
            val data =  bundle?.getParcelable("Data") as? GogoAnime.AnimeDetails
            id = bundle?.getString("id")!!
            title = data?.title!!
            imgLink = data.poster
            season = 1
            episode = bundle.getInt("ep")
            animeEp = data.episodes!!
            animeUrl = data.episodes[episode].url
        }
        else -> {
            val data = bundle?.getParcelable("Data") as? ContinueWatching
            id = data!!.tmdbID.toString()
            title = data.title
            imgLink = data.imgLink
            seekProgress = data.progress
            type = data.type
            year = data.year ?: ""
            origin = data.origin ?: ""
            println(data)
            if (type != "movie"){
                season = data.season
                episode = data.episode
                if(type == "anime"){
                    animeEp = data.animeEp!!
                    animeUrl = data.animeEp[episode].url
                }
            }
        }
    }

        loading = findViewById(R.id.loading_content)


        webView = findViewById(R.id.web_view)
        loading.visibility = View.VISIBLE


        videoUrl.observe(this) { hlsUri ->
            if (!hlsUri.isNullOrEmpty()) {
                webView.visibility = View.GONE
                videoUrl.removeObservers(this)
               val intent =  passVideoData(VideoData(
                    seekProgress,
                    imgLink!!,
                    id.toInt(),
                    IMDBid,
                    title,
                    episode,
                    season,
                    type!!,
                    hlsUri,
                    superId,
                   subUrl,
                   animeEp,
                   origin,
                   year
                   ),this)
                intent.putExtra("origin", origin)
                intent.putExtra("superstream",isSuper)
                intent.putExtra("animeUrl",animeUrl)
//                println(source)
                intent.putExtra("source",source)
                startActivity(intent)
                finish()
            }
        }

//            if(type == "tvshow"){
//                lifecycleScope.launch {
//                    val imdbId = getTvImdb(id)
//                    if(imdbId.isNotBlank()){
//                        origin = "hi"
//                        IMDBid = imdbId
//                        val link = getTvLink(imdbId,season-1,episode-1)
//                        if(link.isNotBlank())
//                        videoUrl.value = link
//                        else{
//                            withContext(Dispatchers.Main){
//                                Toast.makeText(this@MoviePlayActivity,"No Links Available", Toast.LENGTH_SHORT).show()
//                                finish()
//                            }
//                        }
//                    }
//                    else{
//                        //Superstream add
//                        val mainData = superStream.search(title)
//                        superId = mainData.data.list[0].id
//                        if (superId != null) {
//                            isSuper = true
//                            val tvLinks = superStream.loadLinks(false, superId!!, season, episode)
//                            val urlMaps: MutableMap<String,String> = mutableMapOf()
//                            tvLinks.data?.list?.forEach {
//                                if(!it.path.isNullOrBlank()){
//                                    println("${it.quality} : ${it.path}")
//                                    urlMaps[it.quality!!] = it.path
//                                    if(it.quality == "720p") {
//                                        val subtitle = superStream.loadSubtile(false,it.fid!!,superId!!,season,episode).data
////
//                                        getSub(subtitle)
//
//                                        return@forEach
//                                    }
//                                }
//                            }
//                            if(urlMaps.isNotEmpty())
//                                videoUrl.value = gson.toJson(urlMaps)
//                            if(videoUrl.value.isNullOrBlank()){
////                                withContext(Dispatchers.Main){
////                                    Toast.makeText(this@MoviePlayActivity, "Not Available",Toast.LENGTH_SHORT).show()
////                                    finish()
////                                }
//                                isSuper = false
//                                getGoMovieLink(false)
////                                getSmashLink(false)
//                            }
//                        }
//                        else{
//                            isSuper = false
//                            getGoMovieLink(false)
////                            getSmashLink(false)
//                        }
//
//                    }
//                }
//            }
            if(type == "tvshow"){
                lifecycleScope.launch (Dispatchers.IO){
                    val imdbId = getTvImdb(id)
                    if (imdbId.isNotBlank()) {
                        origin = "hi"
                        IMDBid = imdbId
                    }
                    val links = Extractor(origin).loadExtractor(title,id,year,season,episode,false)
                    println(links)
                    val list = prMovies.getPrMovieLink(title)
                    withContext(Dispatchers.Main) {
                        if (!links.videoUrl.isNullOrBlank()) {
                            println("if run")
                            subUrl.addAll(links.subs)
                            isSuper = links.isSuper
                            source = links.source
                            videoUrl.value = links.videoUrl

                        } else {
                            println("else run")
                            loading.visibility = View.GONE
                            try {
                                val rcAdapter = ResultsAdapter {
                                    lifecycleScope.launch(Dispatchers.IO) {
                                        val src = prMovies.loadLinks(it.link!!)
                                        if (src.file.isNullOrBlank()) throw Exception("no video url found")
                                        withContext(Dispatchers.Main) {
                                            isSuper = false
                                            source = "prmovies"
                                            videoUrl.value = src.file
                                        }
                                    }
                                }
                                val width = Resources.getSystem().displayMetrics.widthPixels
                                val dpi = Resources.getSystem().displayMetrics.densityDpi
                                val grid = (width*160)/(165*dpi)
                                resultRc.apply {
                                    layoutManager = GridLayoutManager(this@MoviePlayActivity,grid)
                                    adapter = rcAdapter
                                }
                                if (list.isEmpty()) throw Exception("Empty search")

                                rcAdapter.submitList(list)
                            }catch (e:Exception){
                                Toast.makeText(
                                    this@MoviePlayActivity,
                                    "No available links",
                                    Toast.LENGTH_SHORT
                                ).show()
                                finish()
                            }
                        }
                    }
                }
            }
            else if(type == "movie"){
                println("Reached here")
//                if (origin != "hi") {
                    lifecycleScope.launch(Dispatchers.IO) {
//                        try {
//                            val mainData = superStream.search(title)
////                        println(mainData.data.list[0].year)
//                            val item = mainData.data.list[0]
//                            println(year + " ${item.year}")
//                            superId =
//                                if (item.title == title && item.year.toString() == year) item.id else null
//                            getMovieEn()
//                        }catch (e : Exception){
//                            getMovieEn()
//                        }
                        val links = Extractor(origin).loadExtractor(title,id,year, season,episode,true)
                        println(links)
                        val query = title.filter {
                            it.isLetterOrDigit() || it.isWhitespace()
                        }
                        val list = prMovies.getPrMovieLink(query)

                        withContext(Dispatchers.Main) {
                            if (!links.videoUrl.isNullOrBlank()) {
                                subUrl.addAll(links.subs)
                                isSuper = links.isSuper
                                source = links.source
                                videoUrl.value = links.videoUrl

                            } else {
                                println("else run")
                                println(list)
                                loading.visibility = View.GONE
                                try {
                                    if (list.isEmpty()) throw Exception("Empty search")
                                    val rcAdapter = ResultsAdapter {
                                        lifecycleScope.launch(Dispatchers.IO) {
                                            val src = prMovies.loadLinks(it.link!!)
                                            if (src.file.isNullOrBlank()) throw Exception("no video url found")
                                            withContext(Dispatchers.Main) {
                                                isSuper = false
                                                source = "prmovies"
                                                videoUrl.value = src.file
                                            }
                                        }
                                    }
                                    val width = Resources.getSystem().displayMetrics.widthPixels
                                    val dpi = Resources.getSystem().displayMetrics.densityDpi
                                    val grid = (width*160)/(165*dpi)
                                    resultRc.apply {
                                        layoutManager = GridLayoutManager(this@MoviePlayActivity,grid)
                                        adapter = rcAdapter
                                    }


                                    rcAdapter.submitList(list)
                                }catch (e:Exception){
                                    Toast.makeText(
                                        this@MoviePlayActivity,
                                        "No available links",
                                        Toast.LENGTH_SHORT
                                    ).show()
                                    finish()
                                }
//                                Toast.makeText(
//                                    this@MoviePlayActivity,
//                                    "No available links",
//                                    Toast.LENGTH_SHORT
//                                ).show()
//                                finish()

                            }
                        }
//                        webView.loadUrl(url)
                    }

//                }
//                else {
//                    lifecycleScope.launch {
//                        val imdbId = getMovieImdb(id)
//                        IMDBid = imdbId
//                        println(imdbId)
//                        lifecycleScope.launch {
//                            try {
//                                val mainData = superStream.search(title)
////                        println(mainData.data.list[0].year)
//                                val item = mainData.data.list[0]
//                                println(year + " ${item.year}")
//                                superId =
//                                    if (item.title == title && item.year.toString() == year) item.id else null
//                                getMovieHi(imdbId)
//                            } catch (e: Exception) {
//                                getMovieHi(imdbId)
//                            }
//                        }
// //                        videoUrl.value = getMovieLink(imdbId)
//
//
//                    }
//                }
            }
            else{
                lifecycleScope.launch (Dispatchers.IO){
                    val gogoSrc = GogoAnime()
                    val link = gogoSrc.extractVideos(animeUrl)
                    withContext(Dispatchers.Main){
                        videoUrl.value = link
                    }
                }
            }
    }

    private fun getPrMovie(list: List<SearchResponse>){

    }

    private suspend fun getGoMovieLink(isMovie: Boolean){
        val goMovie = GoMovies()
        val data = goMovie.search(season,episode,title,isMovie,year)
        val vidLink = data.first
        val subLinks = data.second
        if(vidLink.isNullOrBlank()){
//            Toast.makeText(this@MoviePlayActivity, "Not Available", Toast.LENGTH_SHORT).show()
//            finish()
            getSmashLink(isMovie)
        }
        else{
            if (!subLinks.isNullOrEmpty())subUrl.add(subLinks)
            videoUrl.value = vidLink
        }
    }

    private fun getSub(subtitle: SuperstreamUtils.PrivateSubtitleData?){
        subtitle?.list?.forEach { subList->
            if(subList.language == "English"){
                subList.subtitles.forEach { sub->

                        if (subUrl.size == 3) {
                        return
                        }
                        if (sub.lang == "en" && !sub.file_path.isNullOrBlank()) {
                            subUrl.add(sub.file_path)
//                            println("${sub.language} : ${sub.file_path}")
                        }


                }
                return
            }
        }
    }

    private fun getSub2(subtitle: SuperstreamUtils.PrivateSubtitleData?){
        subtitle?.list?.forEach { subList->
                subList.subtitles.forEach { sub->
                    if (!sub.file_path.isNullOrBlank()) {
                        subUrl.add("${subList.language} :${sub.file_path}")
                    }
            }
        }
    }

    private suspend fun getMovie()
    {
        if (superId != null) {
            isSuper = true
            val movieLinks = superStream.loadLinks(true, superId!!)
            movieLinks.data?.list?.forEach {
                if(!it.path.isNullOrBlank()){
                    println("${it.quality} : ${it.path}")
                    if(it.quality == "720p") {
                        val subtitle = superStream.loadSubtile(true,it.fid!!,superId!!).data
//
                        getSub(subtitle)
                        videoUrl.value = it.path
                        return
                    }
                }
            }
            if(videoUrl.value.isNullOrBlank()){
                withContext(Dispatchers.Main){
                    Toast.makeText(this@MoviePlayActivity, "Not Available",Toast.LENGTH_SHORT).show()
                    finish()
                }
            }
        }
        else{
            withContext(Dispatchers.Main){
                Toast.makeText(this@MoviePlayActivity, "Not Available",Toast.LENGTH_SHORT).show()
                finish()
            }
        }
    }

    private suspend fun getMovieHi(imdbId: String)
    {
        if (superId != null) {
            isSuper = true
            val movieLinks = superStream.loadLinks(true, superId!!)
            val urlMaps: MutableMap<String,String> = mutableMapOf()
            movieLinks.data?.list?.forEach {
                if(!it.path.isNullOrBlank()){
                    println("${it.quality} : ${it.path}")
                    urlMaps[it.quality!!] = it.path
                    if(it.quality == "720p") {
                        val subtitle = superStream.loadSubtile(true,it.fid!!,superId!!).data
//
                        getSub(subtitle)

                        return@forEach
                    }
                }

            }
            if(urlMaps.isNotEmpty())
                videoUrl.value = gson.toJson(urlMaps)
            if(videoUrl.value.isNullOrBlank()){
                withContext(Dispatchers.Main){
//                    webView.loadUrl(url)
//                    getSmashLink(true)
                    isSuper = false
                    val link = getMovieLink(imdbId)
                    if (link.isBlank()) {
                        getSmashLink(true,"hi")
                    }
                    else
                        videoUrl.value = link

                }
            }
        }
        else{
            withContext(Dispatchers.Main){
//                webView.loadUrl(url)
//                getSmashLink(true)
                isSuper = false
                val link = getMovieLink(imdbId)
                if (link.isBlank())
                    getSmashLink(true,"hi")
                else
                    videoUrl.value = link

            }
        }
    }

    private suspend fun getMovieEn()
    {
        if (superId != null) {
            isSuper = true
            val movieLinks = superStream.loadLinks(true, superId!!)
            val urlMaps: MutableMap<String,String> = mutableMapOf()
            movieLinks.data?.list?.forEach {
                if(!it.path.isNullOrBlank()){
                    println("${it.quality} : ${it.path}")
                    urlMaps[it.quality!!] = it.path
                    if(it.quality == "720p") {
                        val subtitle = superStream.loadSubtile(true,it.fid!!,superId!!).data
//
                        getSub(subtitle)

                        return@forEach
                    }
                }

            }
            if(urlMaps.isNotEmpty())
                videoUrl.value = gson.toJson(urlMaps)
            if(videoUrl.value.isNullOrBlank()){
                withContext(Dispatchers.Main){
//                    webView.loadUrl(url)
//                    getSmashLink(true)
                    isSuper = false
                    getGoMovieLink(true)

                }
            }
        }
        else{
            withContext(Dispatchers.Main){
//                webView.loadUrl(url)
//                getSmashLink(true)
                isSuper = false
                getGoMovieLink(true)

            }
        }
    }

    private fun getSmashLink(isMovie:Boolean,src: String = "en")
    {
        val smashSrc = SmashyStream()
        lifecycleScope.launch {
            val links = smashSrc.getLink(isMovie,id, season, episode,src)
            val vidLink = links.first
            val subLink = links.second
            if(vidLink.isNullOrBlank()){

                if (isMovie && origin == "hi"){
                    val mainData = superStream.search(title)
                    superId = mainData.data.list[0].id
                    getMovie()
                }
                else {
                    withContext(Dispatchers.Main) {
                        Toast.makeText(this@MoviePlayActivity, "Not Available", Toast.LENGTH_SHORT)
                            .show()
                        finish()
                    }
                }
            }
            else{
                if (!subLink.isNullOrBlank())subUrl.add(subLink)
                videoUrl.value = vidLink
            }
        }
    }


    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        webView.saveState(outState)
    }


    override fun onWindowFocusChanged(hasFocus: Boolean) {
        super.onWindowFocusChanged(hasFocus)
        if (hasFocus) {
            hideSystemUI()
        }
    }

    private fun hideSystemUI() {
        window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE
                // Set the content to appear under the system bars so that the
                // content doesn't resize when the system bars hide and show.
                or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                // Hide the nav bar and status bar
                or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_FULLSCREEN)
    }

}


@Suppress("DEPRECATION")
class FullscreenHolder(ctx: Context) : FrameLayout(ctx) {
    init {
        setBackgroundColor(ctx.resources.getColor(android.R.color.black))
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(evt: MotionEvent): Boolean {
        return true
    }


}




================================================
FILE: app/src/main/java/com/demomiru/tokeiv2/MovieService.kt
================================================
package com.demomiru.tokeiv2

import retrofit2.Response
import retrofit2.http.GET


import retrofit2.http.Query

interface MovieService {
    @GET("movie/popular")
    suspend fun getPopularMovies(
        @Query("api_key") apiKey: String,
        @Query("language") language: String,
        @Query("page") page: Int
    ): Response<MovieResponse>

    @GET("trending/movie/day")
    suspend fun getTrendingMovies(
        @Query("api_key") apiKey: String,
        @Query("language") language: String,
        @Query("page") page: Int
    ): Response<MovieResponse>


    @GET("search/movie")
    suspend fun searchMovie(
        @Query("query") query: String,
        @Query("api_key") apiKey: String,
        @Query("language") language: String
    ) : Response<MovieResponse>

//    @GET("movie/{movie_id}")
//    suspend fun getImdbId(
//        @Path("movie_id") movie_id : String,
//        @Query("api_key") apiKey: String,
//        @Query("language") language: String
//    ) : Response<IdDB>

//    @GET("scrape") // Replace with the actual endpoint path
//    fun fetchDataFromServer(
//        @Header("ngrok-skip-browser-warning") value: String
//    ): Response<ServerResponse>

    @GET("movie/top_rated")
    suspend fun getTopRatedMovies(
        @Query("api_key") apiKey: String,
        @Query("language") language: String,
        @Query("page") page: Int
    ) : Response<MovieResponse>



}
//data class IdDB(
//    val id: String,
//    val imdb_id: String
//)

data class MovieResponse(
        val results: List<Movie>
        )
//data class ServerResponse(
//    val videoLink: String
//    )





================================================
FILE: app/src/main/java/com/demomiru/tokeiv2/MoviesFragment.kt
================================================
package com.demomiru.tokeiv2



import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ProgressBar
import android.widget.TextView
import android.widget.Toast
import androidx.core.view.isVisible
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.lifecycleScope
import androidx.paging.CombinedLoadStates
import androidx.paging.LoadState
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.cachedIn

import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.demomiru.tokeiv2.utils.ContinueWatchingViewModel2
import com.demomiru.tokeiv2.utils.addRecyclerAnimation
import com.demomiru.tokeiv2.utils.passData

import com.demomiru.tokeiv2.utils.retrofitBuilder
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

/**
 * A simple [Fragment] subclass.
 * Use the [MoviesFragment.newInstance] factory method to
 * create an instance of this fragment.
 */
class MoviesFragment : Fragment() {
    // TODO: Rename and change types of parameters
    private var param1: String? = null
    private val activityViewModel: ContinueWatchingViewModel2 by activityViewModels()
    private lateinit var popMovieRc: RecyclerView
    private lateinit var trenMovieRc : RecyclerView
    private lateinit var topMovieRc : RecyclerView
    private var loading = MutableLiveData(true)
    private val adapter = MovieAdapter2{
        println(it.release_date)
        startActivity(passData(it,requireContext()))
    }
    private var param2: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        lifecycleScope.launch (Dispatchers.IO){

        }
        super.onViewCreated(view, savedInstanceState)
    }

    @DelicateCoroutinesApi
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val view =  inflater.inflate(R.layout.fragment_movies, container, false)
        popMovieRc = view.findViewById(R.id.movie_recycler_view)
        trenMovieRc = view.findViewById(R.id.trending_movie_rc)
        topMovieRc = view.findViewById(R.id.topRatedMovie_recycler_view)


        topMovieRc.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL,false)
        trenMovieRc.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL,false)
        popMovieRc.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL,false)

        val retrofit = retrofitBuilder()
        val movieService = retrofit.create(MovieService::class.java)

        lifecycleScope.launch(Dispatchers.Main) {
            withContext(Dispatchers.IO){

//                val trmovies =   Pager(PagingConfig(1)){MoviesPagingSource(3)}.flow.cachedIn(lifecycleScope)
                val tradapter = MovieAdapter2{
//                    val action = MoviesFragmentDirections.actionMoviesFragmentToMoviePlayActivity(it.id, "movie")
//                    findNavController().navigate(play(it))
                    println(it.release_date)
                    startActivity(passData(it, requireContext()))

                }

//                val tmovies =  Pager(PagingConfig(1)){MoviesPagingSource(2)}.flow.cachedIn(lifecycleScope)
                val tadapter = MovieAdapter2 {
//                    findNavController().navigate(play(it))
                    println(it.release_date)
                    startActivity(passData(it, requireContext()))

                }

//                val movies = Pager(PagingConfig(1)){MoviesPagingSource(1)}.flow.cachedIn(lifecycleScope)
                val adapter = MovieAdapter2 {
                    println(it.release_date)
                    startActivity(passData(it, requireContext()))

                }
                withContext(Dispatchers.Main) {
                    addRecyclerAnimation(topMovieRc, tradapter)
                    addRecyclerAnimation(trenMovieRc, tadapter)
                    addRecyclerAnimation(popMovieRc, adapter)


                    lifecycleScope.launch {
                        activityViewModel.topMovies.collect {
                            tradapter.submitData(it)
                        }
                    }
                    lifecycleScope.launch {
                        activityViewModel.popMovies.collect{
                            adapter.submitData(it)
                        }
                    }
                    lifecycleScope.launch {
                        tadapter.addLoadStateListener {
                            val state = it.refresh
                            val visible = state is LoadState.Loading
                            if(visible){
                                view.findViewById<ProgressBar>(R.id.loading_movies).visibility = View.VISIBLE
                            }
                            else{
                                view.findViewById<TextView>(R.id.trending_text).visibility = View.VISIBLE
                                view.findViewById<TextView>(R.id.movies_text).visibility = View.VISIBLE
                                view.findViewById<TextView>(R.id.topmovies_text).visibility = View.VISIBLE
                                view.findViewById<ProgressBar>(R.id.loading_movies).visibility = View.GONE
                            }
                        }
//                        view.findViewById<ProgressBar>(R.id.loading_movies).visibility = View.GONE
//                        view.findViewById<TextView>(R.id.trending_text).visibility = View.VISIBLE
//                        view.findViewById<TextView>(R.id.movies_text).visibility = View.VISIBLE
//                        view.findViewById<TextView>(R.id.topmovies_text).visibility = View.VISIBLE
                        activityViewModel.trenMovies.collect {
                            tadapter.submitData(it)
                        }
                    }


                }
//

        }

//            withContext(Dispatchers.Main) {

//                view.findViewById<ProgressBar>(R.id.loading_movies).visibility = View.GONE
//                view.findViewById<TextView>(R.id.trending_text).visibility = View.VISIBLE
//                view.findViewById<TextView>(R.id.movies_text).visibility = View.VISIBLE
//                view.findViewById<TextView>(R.id.topmovies_text).visibility = View.VISIBLE
//            }
        }


        return view
    }

//    private inline fun CombinedLoadStates.decideOnState(
//        showLoading: (Boolean) -> Unit,
//        showEmptyState: (Boolean) -> Unit,
//        showError: (String) -> Unit
//    ) {
//        showLoading(refresh is LoadState.Loading)
//
//        showEmptyState(
//            source.append is LoadState.NotLoading
//                    && source.append.endOfPaginationReached
//                    && adapter.itemCount == 0
//        )
//
//        val errorState = source.append as? LoadState.Error
//            ?: source.prepend as? LoadState.Error
//            ?: source.refresh as? LoadState.Error
//            ?: append as? LoadState.Error
//            ?: prepend as? LoadState.Error
//            ?: refresh as? LoadState.Error
//
//        errorState?.let { showError(it.error.toString()) }
//    }

    override fun onResume() {
        activityViewModel.currentFragment.value = R.id.moviesFragment
        super.onResume()
    }
    companion object {
        /**
         * Use this factory method to create a new instance of
         * this fragment using the provided parameters.
         *
         * @param param1 Parameter 1.
         * @param param2 Parameter 2.
         * @return A new instance of fragment MoviesFragment.
         */
        // TODO: Rename and change types and number of parameters
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            MoviesFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }

}


================================================
FILE: app/src/main/java/com/demomiru/tokeiv2/SearchFragment.kt
================================================
@file:OptIn(DelicateCoroutinesApi::class)

package com.demomiru.tokeiv2


import android.content.Context
import android.content.res.Resources
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.ProgressBar
import android.widget.RadioButton
import android.widget.RadioGroup
import android.widget.SearchView
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.demomiru.tokeiv2.anime.AnimeAdapter
import com.demomiru.tokeiv2.history.QueryRepository
import com.demomiru.tokeiv2.history.SearchDatabase
import com.demomiru.tokeiv2.history.SearchHistory
import com.demomiru.tokeiv2.history.SearchHistoryAdapter2
import com.demomiru.tokeiv2.utils.ContinueWatchingViewModel2
import com.demomiru.tokeiv2.utils.SearchVMFactory
import com.demomiru.tokeiv2.utils.SearchViewModel
import com.demomiru.tokeiv2.utils.addRecyclerAnimation
import com.demomiru.tokeiv2.utils.passData
import kotlinx.coroutines.DelicateCoroutinesApi

class SearchFragment : Fragment() {
    //    private lateinit var searchHistoryList: List<String>
    private lateinit var searchHistoryRC: RecyclerView
    private lateinit var searchView : SearchView
    private val activityViewModel: ContinueWatchingViewModel2 by activityViewModels()
    private lateinit var searchHistoryFl : LinearLayout
    private lateinit var deleteAll : TextView
    private var isClicked = true
    private lateinit var adapter: SearchHistoryAdapter2
    private lateinit var searchResultsRc : RecyclerView
    private lateinit var searchEt: EditText
    private lateinit var movieChoice : RadioButton
    private lateinit var tvChoice : RadioButton
    private lateinit var animeChoice: RadioButton
    private lateinit var choice : RadioGroup
    private lateinit var searchLoading : ProgressBar
    private val database by lazy { SearchDatabase.getInstance(requireContext()) }
    private val searchHistoryDao by lazy { database.searchDao() }
    private lateinit var queryRepository:QueryRepository
    private lateinit var viewModelFactory: SearchVMFactory
    private lateinit var mAdapter : MovieAdapter
    private lateinit var tvAdapter : TVShowAdapter
    private lateinit var aAdapter: AnimeAdapter
    private val viewModel: SearchViewModel by viewModels(
        factoryProducer = {
            viewModelFactory
        }
    )



    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val view =  inflater.inflate(R.layout.fragment_search, container, false)
        searchHistoryFl = view.findViewById(R.id.search_history_ll)
        searchView = view.findViewById(R.id.searchView)
        queryRepository = QueryRepository(searchHistoryDao)
        viewModelFactory = SearchVMFactory(queryRepository)
        deleteAll = view.findViewById(R.id.delete_all_button)
        searchHistoryRC = view.findViewById(R.id.search_history_rc)
        searchResultsRc = view.findViewById(R.id.search_results_rc)
        searchLoading = view.findViewById(R.id.search_loading)
        movieChoice = view.findViewById(R.id.movies_search)
        tvChoice = view.findViewById(R.id.tvShows_search)
        animeChoice = view.findViewById(R.id.anime_search)
        choice = view.findViewById(R.id.choice)
        activityViewModel.currentFragment.value = R.id.searchFragment
//        println(activityViewModel.test)
        mAdapter = MovieAdapter{
//                    val action = SearchFragmentDirections.actionSearchFragmentToMoviePlayActivity(it.id,"movie",title = it.title)
//                    findNavController().navigate(action)
            startActivity(passData(it, requireContext()))
        }

        tvAdapter = TVShowAdapter{it, _ ->
            val action = SearchFragmentDirections.actionSearchFragmentToTVShowDetails(it.id, title = it.name)
            findNavController().navigate(action)
        }

        aAdapter = AnimeAdapter(requireContext()){

//                val action = SearchFragmentDirections.actionSearchFragmentToTVShowDetails(
//                    encodeStringToInt(it.name).toString(), title = "",animeUrl = it.url)
//                findNavController().navigate(action)
            val action =  SearchFragmentDirections.actionSearchFragmentToAnimeDetailsFragment(it.name,it.url)
            findNavController().navigate(action)

        }

//        var start = true
//        viewModel.queryText.observe(viewLifecycleOwner){
//            if(it.isNotBlank() && start)searchView.setQuery(it,false)
//        }

//        searchView.setQuery(viewModel.queryText.value,false)



        val width = Resources.getSystem().displayMetrics.widthPixels
        val dpi = Resources.getSystem().displayMetrics.densityDpi
        val grid = (width*160)/(165*dpi)
        println(grid)
        searchResultsRc.layoutManager = GridLayoutManager(requireContext(),grid)
        searchHistoryRC.layoutManager = LinearLayoutManager(requireContext())
//        start   = false
        adapter = SearchHistoryAdapter2{it,search->
            if (search){

                searchView.setQuery(it.query,true)
                viewModel.queryText.value = it.query
                viewModel.searchClicked.value = true
//                (activity as MainActivity).triggerSearchKeyPress()
            }
            else {
                viewModel.deleteRecord(it)
            }
        }
        searchHistoryRC.adapter = adapter
        searchHistoryRC.visibility = View.VISIBLE
//        GlobalScope.launch (Dispatchers.IO){
//            queryRepository.loadData()
//        }

        val searchHistoryObserver = Observer<List<SearchHistory>>{
            adapter.submitList(it)
            if (it.isEmpty()){
//                searchHistoryRC.visibility = View.GONE
//                deleteAll.visibility = View.GONE
                searchHistoryFl.visibility = View.GONE
                activityViewModel.searchOpen.value = false
                isClicked = true
            }

        }
        viewModel.searchClicked.observe(viewLifecycleOwner){
            if(it){
//                deleteAll.visibility = View.GONE
//                searchHistoryRC.visibility = View.GONE
                searchHistoryFl.visibility = View.GONE
                activityViewModel.searchOpen.value = false
            }
            else{
//                deleteAll.visibility = View.VISIBLE
//                searchHistoryRC.visibility = View.VISIBLE
                searchHistoryFl.visibility = View.VISIBLE
                activityViewModel.searchOpen.value = true
            }
        }

//        queryRepository.allQueries.observe(viewLifecycleOwner,searchHistoryObserver)
        viewModel.queries.observe(viewLifecycleOwner,searchHistoryObserver)


        deleteAll.setOnClickListener{
            viewModel.deleteAll()
        }

        searchEt = view.findViewById(R.id.search_et)
        searchEt.setOnClickListener{
            if(isClicked) {
                deleteAll.visibility = View.VISIBLE
                searchHistoryRC.visibility = View.VISIBLE
                isClicked = false
            }
            else{
                deleteAll.visibility = View.GONE
                searchHistoryRC.visibility = View.GONE
                isClicked = true
            }

        }
//        searchView.queryHint = "Search"

//        searchView.setOnCloseListener {
//            deleteAll.visibility = View.GONE
//            searchHistoryRC.visibility = View.GONE
//            false
//        }
        searchView.setOnClickListener {
            val imm =
                requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            imm.showSoftInput(it.findFocus(), 0)
        }

//        viewModel.queryText.observe(viewLifecycleOwner){
//            if(it.isNotBlank())searchView.setQuery(it,false)
//        }

        searchView.setOnQueryTextFocusChangeListener { view, hasFocus ->
            if(hasFocus) {
//                deleteAll.visibility = View.VISIBLE
//                searchHistoryRC.visibility = View.VISIBLE
                view.postDelayed({
                    val imm =
                        requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                    imm.showSoftInput(view.findFocus(), 0)
                }, 200)
                searchHistoryFl.visibility = View.VISIBLE
                activityViewModel.searchOpen.value = true

            }
//            else{
//
//                deleteAll.visibility = View.GONE
//                viewModel.searchClicked.value = true
//                searchHistoryRC.visibility = View.GONE
//
//            }
        }

        activityViewModel.searchOpen.observe(viewLifecycleOwner){
            if(it == false){
                searchHistoryFl.visibility = View.GONE
                searchView.clearFocus()
            }
        }

        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(query: String?): Boolean {
                // Logic for when search button is clicked
                if(query.isNullOrEmpty())return false
                viewModel.searchClicked.value = true
                if(movieChoice.isChecked)
                {
                    viewModel.choice.value = 1
                    performMovieSearch(query)
                }
                else if(tvChoice.isChecked){
                    viewModel.choice.value = 2
                    performShowSearch(query)
                }
                else{
                    viewModel.choice.value = 3
                    performAnimeSearch(query)
                }
//                searchView.isIconified = true
//                searchView.queryHint = query
                viewModel.queryText.value = query
                searchHistoryFl.visibility = View.GONE

                searchView.clearFocus()

                return false
            }

            override fun onQueryTextChange(newText: String?): Boolean {
                // Logic for when text in search view changes
                //add filter in searchHistory Rc
//                deleteAll.visibility = View.VISIBLE
//                searchHistoryRC.visibility = View.VISIBLE
                searchHistoryFl.visibility = View.VISIBLE
                viewModel.queryText.value = newText?:""
                return false
            }
        })

//        searchView.setOnClickListener {
//            searchView.isIconified = false
//        }

//        searchEt.setOnKeyListener { _, actionId, event ->
//            if(searchEt.text.toString().isEmpty()) return@setOnKeyListener true
//            if (actionId == KeyEvent.ACTION_DOWN || event.keyCode == KeyEvent.KEYCODE_ENTER) {
//                // The "Search" button on the keyboard was clicked
//                viewModel.searchClicked.value = true
//                if(movieChoice.isChecked)
//                {
//                    viewModel.choice.value = 1
//                    performMovieSearch()
//                }
//                else if(tvChoice.isChecked){
//                    viewModel.choice.value = 2
//                    performShowSearch()
//                }
//                else{
//                    viewModel.choice.value = 3
//                    performAnimeSearch()
//                }
//                return@setOnKeyListener true
//            }
//            false
//        }

        choice.setOnCheckedChangeListener { _, _: Int ->
            if(movieChoice.isChecked)
            {
                viewModel.choice.value = 1

            }
            else if(tvChoice.isChecked){
                viewModel.choice.value = 2

            }
            else{
                viewModel.choice.value = 3
            }
            searchResultsRc.visibility = View.GONE
//            searchHistoryRC.visibility = View.VISIBLE
            searchHistoryFl.visibility = View.VISIBLE
            viewModel.searchClicked.value = false
        }

        when(viewModel.choice.value){
            1 -> viewModel.movieList.observe(viewLifecycleOwner) { movies ->
                if (movies.isNotEmpty()) {
                    mAdapter.submitList(movies)
                    addRecyclerAnimation(searchResultsRc,mAdapter)
                    searchLoading.visibility = View.GONE
                    searchResultsRc.visibility = View.VISIBLE
                }
            }
            2 -> viewModel.tvList.observe(viewLifecycleOwner){shows->
                if(shows.isNotEmpty()){
                    tvAdapter.submitList(shows)
                    addRecyclerAnimation(searchResultsRc,tvAdapter)
                    searchLoading.visibility = View.GONE
                    searchResultsRc.visibility = View.VISIBLE
                }
            }
            3 -> viewModel.animeList.observe(viewLifecycleOwner){ anime->
                if(anime.isNotEmpty()){
                    aAdapter.submitList(anime)
                    addRecyclerAnimation(searchResultsRc,aAdapter)
                    searchLoading.visibility = View.GONE
                    searchResultsRc.visibility = View.VISIBLE
                }
            }
            else -> println(viewModel.choice.value)
        }

        viewModel.noMatches.observe(viewLifecycleOwner){
            if(it) {
                Toast.makeText(requireContext(), "No Matches", Toast.LENGTH_SHORT).show()
                viewModel.noMatches.value = false
            }
        }

        return view
    }


    private fun performAnimeSearch(query: String)
    {
        searchResultsRc.visibility = View.GONE
        searchHistoryFl.visibility = View.GONE
        isClicked = true
//        deleteAll.visibility = View.GONE
        searchLoading.visibility = View.VISIBLE
//        val gogoSrc = GogoAnime()

//        val query = searchEt.text.toString()
        val history = SearchHistory(query = query)
        viewModel.addToHistory(history)
        viewModel.searchAnime(query)
//        val adapter = AnimeAdapter(requireContext()){
//            lifecycleScope.launch {
//
////                val action = SearchFragmentDirections.actionSearchFragmentToTVShowDetails(
////                    encodeStringToInt(it.name).toString(), title = "",animeUrl = it.url)
////                findNavController().navigate(action)
//
//               val action =  SearchFragmentDirections.actionSearchFragmentToAnimeDetailsFragment(it.name,it.url)
//                findNavController().navigate(action)
//
//            }
//        }





        viewModel.animeList.observe(viewLifecycleOwner){anime->
            if(anime.isNotEmpty()){
                aAdapter.submitList(anime)
                addRecyclerAnimation(searchResultsRc, aAdapter)
                searchLoading.visibility = View.GONE
                searchResultsRc.visibility = View.VISIBLE
                searchResultsRc.requestFocus()
            }
            else{
//                Toast.makeText(requireContext(),"No Matches",Toast.LENGTH_SHORT).show()
                searchLoading.visibility = View.GONE
                searchResultsRc.visibility = View.GONE
            }
        }
//        addRecyclerAnimation(searchResultsRc, aAdapter)
//        lifecycleScope.launch(Dispatchers.IO) {
//            val history = SearchHistory(query = query)
//            queryRepository.insert(history)
//            queryRepository.loadData()
//            val animeList = gogoSrc.search(query)
//
//            withContext(Dispatchers.Main)
//            {
//                if (animeList.isEmpty()) Toast.makeText(requireContext(),"No Matches",Toast.LENGTH_LONG).show()
//                adapter.submitList(animeList)
//                searchLoading.visibility = View.GONE
//                searchResultsRc.visibility = View.VISIBLE
//            }
//        }

    }

    @OptIn(DelicateCoroutinesApi::class)
    private fun performMovieSearch(query:String)
    {
        searchResultsRc.visibility = View.GONE
//        searchHistoryRC.visibility = View.GONE
        isClicked = true
//        deleteAll.visibility = View.GONE
        searchHistoryFl.visibility = View.GONE
        searchLoading.visibility = View.VISIBLE

//        val query = searchEt.text.toString()

//        GlobalScope.launch(Dispatchers.IO) {
//
//            val history = SearchHistory(query = query)
//            queryRepository.insert(history)
//            queryRepository.loadData()
//        }
        val history = SearchHistory(query = query)
        viewModel.addToHistory(history)

//        val retrofit = retrofitBuilder()
//
//        val movieService = retrofit.create(MovieService::class.java)

        viewModel.searchMovie(query)
        viewModel.movieList.observe(viewLifecycleOwner){movies->
            if(movies.isNotEmpty()){
                mAdapter.submitList(movies)
                addRecyclerAnimation(searchResultsRc,mAdapter)
                searchLoading.visibility = View.GONE
                searchResultsRc.visibility = View.VISIBLE
                searchResultsRc.requestFocus()
            }
            else{
//                Toast.makeText(requireContext(),"No Matches",Toast.LENGTH_SHORT).show()
                searchLoading.visibility = View.GONE
                searchResultsRc.visibility = View.GONE
            }
        }

//        GlobalScope.launch (Dispatchers.Main){
//
//            val searchResults = movieService.searchMovie(
//                query,
//                BuildConfig.TMDB_API_KEY,
//                "en-US"
//            )
//
//            if (searchResults.isSuccessful)
//            {
//                val movies = searchResults.body()?.results ?: emptyList()
//                if (movies.isEmpty()) Toast.makeText(requireContext(),"No Matches",Toast.LENGTH_LONG).show()
//                val adapter = MovieAdapter(movies){
////                    val action = SearchFragmentDirections.actionSearchFragmentToMoviePlayActivity(it.id,"movie",title = it.title)
////                    findNavController().navigate(action)
//                    startActivity(passData(it,requireContext()))
//                }
//                addRecyclerAnimation(searchResultsRc,adapter)
//            }
//
//            withContext(Dispatchers.Main) {
//                searchLoading.visibility = View.GONE
//                searchResultsRc.visibility = View.VISIBLE
//            }
//        }

    }

    @OptIn(DelicateCoroutinesApi::class)
    private fun performShowSearch(query: String)
    {
        searchResultsRc.visibility = View.GONE
//        searchHistoryRC.visibility = View.GONE
        searchHistoryFl.visibility = View.GONE
        isClicked = true
        searchLoading.visibility = View.VISIBLE
//        deleteAll.visibility = View.GONE

//        val query = searchEt.text.toString()
//        GlobalScope.launch(Dispatchers.IO) {
////            searchHistoryDao.deleteAll()
//            val history = SearchHistory(query = query)
//            queryRepository.insert(history)
//            queryRepository.loadData()
//        }

        val history = SearchHistory(query = query)
        viewModel.addToHistory(history)

        viewModel.searchTv(query)
        viewModel.tvList.observe(viewLifecycleOwner){shows->
            if(shows.isNotEmpty()){
                tvAdapter.submitList(shows)
                addRecyclerAnimation(searchResultsRc,tvAdapter)
                searchLoading.visibility = View.GONE
                searchResultsRc.visibility = View.VISIBLE
                searchResultsRc.requestFocus()
            }
            else{
//                Toast.makeText(requireContext(),"No Matches",Toast.LENGTH_SHORT).show()
                searchLoading.visibility = View.GONE
                searchResultsRc.visibility = View.GONE
            }

        }

//        val retrofit = retrofitBuilder()
//
//        val tvService = retrofit.create(TMDBService::class.java)

//        GlobalScope.launch (Dispatchers.Main){
//
//            val searchResults = tvService.searchShow(
//                query,
//                BuildConfig.TMDB_API_KEY,
//                "en-US"
//            )
//
//            if (searchResults.isSuccessful)
//            {
//                val tvShows = searchResults.body()?.results ?: emptyList()
//                if (tvShows.isEmpty()) Toast.makeText(requireContext(),"No Matches",Toast.LENGTH_LONG).show()
//                val adapter = TVShowAdapter(tvShows){it, _ ->
//                    val action = SearchFragmentDirections.actionSearchFragmentToTVShowDetails(it.id, title = it.name)
//                    findNavController().navigate(action)
//                }
//                addRecyclerAnimation(searchResultsRc,adapter)
//            }
//            withContext(Dispatchers.Main) {
//                searchLoading.visibility = View.GONE
//                searchResultsRc.visibility = View.VISIBLE
//            }
//        }

    }



}

================================================
FILE: app/src/main/java/com/demomiru/tokeiv2/TMDBService.kt
================================================
package com.demomiru.tokeiv2

import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Path
import retrofit2.http.Query
import java.io.Serializable


interface TMDBService {

    @GET("tv/popular")
    suspend fun getPopularTVShows(
        @Query("api_key") apiKey: String,
        @Query("language") language: String,
        @Query("page") page: Int
    ): Response<TVShowResponse>

    @GET("trending/tv/day")
    suspend fun getTrendingTVShows(
        @Query("api_key") apiKey: String,
        @Query("language") language: String,
        @Query("page") page: Int
    ): Response<TVShowResponse>

    @GET("tv/{series_id}")
    suspend fun getTVShowDetails(
        @Path("series_id") seriesID: String,
        @Query("api_key") apiKey: String,
        @Query("language") language: String
    ): Response<TVShowDetailsResponse>

    @GET("tv/{series_id}/season/{season_number}")
    suspend fun getEpisodeDetails(
        @Path("series_id") seriesID: String,
        @Path("season_number") season: String,
        @Query("api_key") apiKey: String,
        @Query("language") language: String
    ) : Response<TVShowEpisodeDetailsResponse>

    @GET("search/tv")
    suspend fun searchShow(
        @Query("query") query: String,
        @Query("api_key") apiKey: String,
        @Query("language") language: String
    ) : Response<TVShowResponse>

    @GET("tv/top_rated")
    suspend fun getTopRatedTVShows(
        @Query("api_key") apiKey: String,
        @Query("language") language: String,
        @Query("page") page: Int
    ) : Response<TVShowResponse>



}

data class TVShowResponse(
    val results: List<TVshow>
)

data class TVShowDetailsResponse(
    val backdrop_path : String,
    val overview : String,
    val original_name : String,
    val number_of_seasons: String,
    val poster_path : String,
    val number_of_episodes : Int,
    val tagline : String
)

data class TVShowEpisodeDetailsResponse(
    val episodes : List<Episode>
)
data class Episode(
    val air_date: String?,
    val season_number: String,
    val episode_number: String,
    val overview: String?,
    val name: String?,
    val still_path: String?,
) : Serializable

data class Season(
    val id : String,
    val title:String,
    val folder: List<Folder>
)
data class Folder(
    val episode: String,
    val folder: List<EpisodeID>
)
data class EpisodeID(
    val file: String, //episode file
    val title: String// language
)

data class TvIMDB(
    val languages: List<String>,
    val external_ids : ExternalIDs,
    val number_of_seasons: String,
    val origin_country: List<String>
)
data class ExternalIDs(
    val imdb_id : String
)

data class ImdbEpisode(
    val episodes : List<EP>
)
data class EP(
    val episode_number: String
)



================================================
FILE: app/src/main/java/com/demomiru/tokeiv2/TVShowAdapter.kt
================================================
package com.demomiru.tokeiv2

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.view.ViewCompat
import androidx.paging.PagingDataAdapter
import androidx.paging.PagingSource
import androidx.paging.PagingState
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import coil.load
import com.demomiru.tokeiv2.MovieAdapter2.Companion.differCallback
import com.demomiru.tokeiv2.utils.retrofitBuilder

class TVShowAdapter(
private val clickHandler : (TVshow,Int) -> Unit
) :
    ListAdapter<TVshow,TVShowAdapter.ViewHolder>(differCallback) {

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val imageView: ImageView = itemView.findViewById(R.id.image_view)
        val titleTextView: TextView = itemView.findViewById(R.id.title_text_view)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_view, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val tvShow = getItem(position)
        holder.titleTextView.text = tvShow.name
        holder.imageView
            .load("https://image.tmdb.org/t/p/w500${tvShow.poster_path}")
        ViewCompat.setTransitionName(holder.imageView, "image_$position")

        holder.itemView.setOnClickListener {
            clickHandler(tvShow,position)
        }
    }
    companion object {
        val differCallback = object : DiffUtil.ItemCallback<TVshow>() {
            override fun areItemsTheSame(oldItem: TVshow, newItem: TVshow): Boolean {
                return oldItem.id == newItem.id
            }

            override fun areContentsTheSame(oldItem: TVshow, newItem: TVshow): Boolean {
                return oldItem == newItem
            }
        }
    }

}

class TvShowPagingSource(private val list: Int): PagingSource<Int, TVshow>() {
    private val retrofit = retrofitBuilder()
    private val tvService = retrofit.create(TMDBService::class.java)
    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, TVshow> {
        return try {
            val currentPage = params.key ?: 1
            val response = when(list){
                1-> tvService.getPopularTVShows(BuildConfig.TMDB_API_KEY,"en-US",currentPage)
                2-> tvService.getTrendingTVShows(BuildConfig.TMDB_API_KEY, "en-US",currentPage)
                3-> tvService.getTopRatedTVShows(BuildConfig.TMDB_API_KEY,"en-US",currentPage)
                else -> throw Exception("wrong list parameter input")
            }

            val data = response.body()!!.results
            val responseData = mutableListOf<TVshow>()
            responseData.addAll(data)

            LoadResult.Page(
                data = responseData,
                prevKey = if (currentPage == 1) null else -1,
                nextKey = currentPage.plus(1)
            )
        } catch (e: Exception) {
            LoadResult.Error(e)
        }

    }


    override fun getRefreshKey(state: PagingState<Int, TVshow>): Int? {
        return null
    }

}

class TVShowAdapter2(private val clickHandler : (TVshow,Int) -> Unit) :
    PagingDataAdapter<TVshow,TVShowAdapter2.ViewHolder>(differCallback) {

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val imageView: ImageView = itemView.findViewById(R.id.image_view)
        val titleTextView: TextView = itemView.findViewById(R.id.title_text_view)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_view, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val tvShow = getItem(position)!!
        holder.titleTextView.text = tvShow.name
        holder.imageView
            .load("https://image.tmdb.org/t/p/w500${tvShow.poster_path}")
        ViewCompat.setTransitionName(holder.imageView, "image_$position")

        holder.itemView.setOnClickListener {
            clickHandler(tvShow,position)
        }
        holder.setIsRecyclable(false)
    }
    companion object {
        val differCallback = object : DiffUtil.ItemCallback<TVshow>() {
            override fun areItemsTheSame(oldItem: TVshow, newItem: TVshow): Boolean {
                return oldItem.id == newItem.id
            }

            override fun areContentsTheSame(oldItem: TVshow, newItem: TVshow): Boolean {
                return oldItem == newItem
            }
        }
    }
}

================================================
FILE: app/src/main/java/com/demomiru/tokeiv2/TVShowCardAdapter.kt
================================================
package com.demomiru.tokeiv2


import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import coil.load


class TVShowCardAdapter(private val tvShows: List<List<TVshow>>): RecyclerView.Adapter<TVShowCardAdapter.ViewHolder>() {

    class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView){
        val verticalImage: ImageView = itemView.findViewById(R.id.vertical_container)
        val horizontalImage1: ImageView = itemView.findViewById(R.id.horizontal_container1)
        val horizontalImage2: ImageView = itemView.findViewById(R.id.horizontal_container2)
    }

    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.card_view,parent,false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val tvShow = tvShows[position  % tvShows.size]
        holder.verticalImage.load("https://image.tmdb.org/t/p/w500${tvShow[0].poster_path}")
        holder.horizontalImage1.load("https://image.tmdb.org/t/p/original${tvShow[1].backdrop_path}")
        holder.horizontalImage2.load("https://image.tmdb.org/t/p/original${tvShow[2].backdrop_path}")
    }

    override fun getItemCount(): Int {
       return Int.MAX_VALUE
    }
}

================================================
FILE: app/src/main/java/com/demomiru/tokeiv2/TVShowDetails.kt
================================================
package com.demomiru.tokeiv2

import android.annotation.SuppressLint
import android.content.res.Configuration

import android.os.Bundle

import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import android.widget.AdapterView
import android.widget.ArrayAdapter

import android.widget.Button
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.ProgressBar
import android.widget.Spinner
import android.widget.TextView
import android.widget.Toast
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope

import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import coil.load
import com.demomiru.tokeiv2.anime.AnimeEpisodeAdapter
import com.demomiru.tokeiv2.utils.ContinueWatchingViewModel
import com.demomiru.tokeiv2.utils.ContinueWatchingViewModel2
import com.demomiru.tokeiv2.utils.ContinueWatchingViewModelFactory
import com.demomiru.tokeiv2.utils.GogoAnime
import com.demomiru.tokeiv2.utils.dateToUnixTime
import com.demomiru.tokeiv2.utils.dropDownMenu
import com.demomiru.tokeiv2.utils.passData
import com.demomiru.tokeiv2.utils.retrofitBuilder
import com.demomiru.tokeiv2.watching.ContinueWatching
import com.demomiru.tokeiv2.watching.ContinueWatchingDatabase

import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope

import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext


class TVShowDetails : Fragment() {
    private val args : TVShowDetailsArgs by navArgs()
    private val activityViewModel: ContinueWatchingViewModel2 by activityViewModels()
    private lateinit var id: String
    private lateinit var title: String
    private var isAnime: Boolean = false
    private var animeDetails = MutableLiveData<GogoAnime.AnimeDetails>(null)
    private lateinit var viewModelFactory: ContinueWatchingViewModelFactory
    private val viewModel: ContinueWatchingViewModel by viewModels(
        factoryProducer = {
            viewModelFactory
        }
    )
    private var lastPlayedSeason = 1
    private lateinit var episodeProgress : ContinueWatching
    private val database by lazy { ContinueWatchingDatabase.getInstance(requireContext()) }
    private val watchHistoryDao by lazy { database.watchDao() }
    private lateinit var episodesRc: RecyclerView
    private lateinit var progressBar: ProgressBar
    private lateinit var dropDownSpinner: Spinner


    @SuppressLint("SetTextI18n")
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val viewStateObserver = Observer<ContinueWatching?> {watchFrom ->
            val continueButton =  view.findViewById<Button>(R.id.continue_button)
            if (watchFrom != null) {
                episodeProgress = watchFrom
                continueButton.visibility = View.VISIBLE
               continueButton.text =
                    "Continue Watching \t S${watchFrom.season} E${watchFrom.episode}"
                lastPlayedSeason = watchFrom.season
            }

            continueButton.setOnClickListener {
                startActivity(passData(watchFrom!!, requireContext()))
            }
        }
        viewModel.watchFrom.observe(viewLifecycleOwner,viewStateObserver)
    }

    @SuppressLint("NotifyDataSetChanged", "SetTextI18n")
    @OptIn(DelicateCoroutinesApi::class)
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
//        postponeEnterTransition()
        // Inflate the layout for this fragment
        activityViewModel.currentFragment.value = R.id.TVShowDetails
        val view = inflater.inflate(R.layout.fragment_tv_show_details, container, false)
//        val animeDetails = arguments?.getSerializable("anime-details") as? GogoAnime.AnimeDetails
//        if (animeDetails!= null) isAnime = true

        val animeUrl: String = args.animeUrl
        println(animeUrl)
        isAnime = animeUrl.length > 5

        if (!isAnime) {
            id = args.tmdbID
            viewModelFactory = ContinueWatchingViewModelFactory(watchHistoryDao, id.toInt())
            title = args.title
            val position = args.position
        }
        else
        {
            id=args.tmdbID
            viewModelFactory = ContinueWatchingViewModelFactory(watchHistoryDao, id.toInt())
            title = args.title
            val gogoSrc = GogoAnime()
            lifecycleScope.launch {
                val details  = gogoSrc.load(animeUrl)
                withContext(Dispatchers.Main){
                    animeDetails.value = details
                    if (animeDetails!=null){
                        title = details.title!!
                    }
                    else{
                        Toast.makeText(requireContext(),"Error Loading", Toast.LENGTH_SHORT).show()
                    }
                }
            }
        }
//        val continueButton  = view.findViewById<Button>(R.id.continue_button)



//        hintTil = view.findViewById(R.id.dropdown_menu)
        progressBar = view.findViewById(R.id.progress_circular)
        episodesRc = view.findViewById(R.id.episode_display_rc)
        val orientation = this.resources.configuration.orientation
        if(orientation == Configuration.ORIENTATION_LANDSCAPE)
            episodesRc.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
        else
        episodesRc.layoutManager = LinearLayoutManager(requireContext())

        val expandView = view.findViewById<ConstraintLayout>(R.id.expand_tvshow_view)
        val titleTv = view.findViewById<TextView>(R.id.title_show)
        val backdropImg: ImageView = view.findViewById(R.id.show_backdrop)
        val posterImg: ImageView = view.findViewById(R.id.show_poster)
        val overview: TextView = view.findViewById(R.id.overview)
        val retrofit = retrofitBuilder()
        dropDownSpinner = view.findViewById(R.id.dropdown_spinner)
//        viewModel.season.observe(viewLifecycleOwner){
//            dropDownSpinner.setSelection(it)
//        }
//        expandView.transitionName = "image_$position"


        if (!isAnime){
            println(" NOt anime")
        val tvService = retrofit.create(TMDBService::class.java)
        lifecycleScope.launch(Dispatchers.IO) {
            val tvDetailsResponse = tvService.getTVShowDetails(
                id,
                BuildConfig.TMDB_API_KEY,
                "en-US"
            )

            if (tvDetailsResponse.isSuccessful) {
                val tvShows = tvDetailsResponse.body()

                withContext(Dispatchers.Main){
                    posterImg.load("https://image.tmdb.org/t/p/w500${tvShows?.poster_path}")
                    backdropImg.load("https://image.tmdb.org/t/p/original${tvShows?.backdrop_path}")
                    overview.text = tvShows?.overview
                    titleTv.text = title
                }


                val seasons = dropDownMenu(tvShows!!.number_of_seasons.toInt()) // Fetch the data
                val arrayAdapter = ArrayAdapter(
                    requireContext(),
                    android.R.layout.simple_dropdown_item_1line,
                    seasons
                ) // Create an ArrayAdapter
//                dropdownMenu = view.findViewById(R.id.autoCompleteTextView)
//                dropdownMenu.setAdapter(arrayAdapter) // Set the adapter

                withContext(Dispatchers.Main){
                    dropDownSpinner.adapter = arrayAdapter
                    dropDownSpinner.setSelection(lastPlayedSeason-1)

                }

                var seasonNumber: String
                dropDownSpinner.onItemSelectedListener =
                    object : AdapterView.OnItemSelectedListener {
                        override fun onItemSelected(
                            parent: AdapterView<*>?,
                            p1: View?,
                            position: Int,
                            p3: Long
                        ) {
                            val selectedItem = parent?.getItemAtPosition(position) as String
                            seasonNumber = selectedItem.substringAfter(" ")
                            Log.i("Season Number", seasonNumber)
                            viewModel.season.value = position

                            lifecycleScope.launch(Dispatchers.IO) {
                                val episodeResponse = tvService.getEpisodeDetails(
                                    id, seasonNumber,
                                    BuildConfig.TMDB_API_KEY,
                                    "en-US"
                                )

                                if (episodeResponse.isSuccessful) {
                                    var episodes = episodeResponse.body()?.episodes ?: emptyList()

                                    if(episodes.isNotEmpty()){
                                        val condition: (Episode) -> Boolean = { episode ->
                                            if (episode.air_date == null) true
                                            else
                                            dateToUnixTime(episode.air_date) > System.currentTimeMillis()
                                        }
                                        val repisodes =  episodes.toMutableList()
                                        repisodes.removeIf(condition)
                                        episodes = repisodes
                                    }

                                    val adapter = EpisodeAdapter2(episodes) {
                                        startActivity(
                                            passData(
                                                it,
                                                requireContext(),
                                                title,
                                                tvShows.poster_path,
                                                id
                                            )
                                        )

                                    }

                                    val context = episodesRc.context
                                    val controller = AnimationUtils.loadLayoutAnimation(
                                        context,
                                        R.anim.layout_animation
                                    )
                                    withContext(Dispatchers.Main) {
                                        episodesRc.adapter = adapter
                                        episodesRc.layoutAnimation = controller
                                        adapter.notifyDataSetChanged()
                                        episodesRc.scheduleLayoutAnimation()
                                        view.findViewById<TextView>(R.id.episodes_text).visibility =
                                            View.VISIBLE
                                    }

                                }
                            }
                        }

                        override fun onNothingSelected(p0: AdapterView<*>?) {

                        }

                    }

                withContext(Dispatchers.Main) {

                    view.findViewById<LinearLayout>(R.id.progress_layout).visibility = View.GONE
//                    view.findViewById<TextView>(R.id.episodes_text).visibility = View.VISIBLE
                }

            }
        }
    }else
        {
        dropDownSpinner.visibility = View.GONE
        animeDetails.observe(viewLifecycleOwner) {animeDetails->
            if(animeDetails!=null){

                view.findViewById<LinearLayout>(R.id.progress_layout).visibility = View.GONE
                posterImg.load(animeDetails.poster)
                backdropImg.load(animeDetails.poster)
                overview.text = animeDetails.description
                titleTv.text = animeDetails.title

                val episodes = animeDetails.episodes
                val adapter = AnimeEpisodeAdapter() { _, epPos->
                    startActivity(
                        passData(
                            animeDetails,
                            requireContext(),
                            "0",
                            epPos,
                            animeDetails.title?:""
                        )
                    )
                }
                episodesRc.adapter = adapter
                adapter.submitList(episodes)
                val context = episodesRc.context
                val controller = AnimationUtils.loadLayoutAnimation(
                    context,
                    R.anim.layout_animation
                )
                episodesRc.layoutAnimation = controller
                adapter.notifyDataSetChanged()
                episodesRc.scheduleLayoutAnimation()
                view.findViewById<TextView>(R.id.episodes_text).visibility =
                    View.VISIBLE
                }
            }
        }
        return view
    }
}

================================================
FILE: app/src/main/java/com/demomiru/tokeiv2/TVShowFragment.kt
================================================
package com.demomiru.tokeiv2

import android.os.Bundle

import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import androidx.navigation.fragment.findNavController
import android.view.ViewGroup
import android.widget.ProgressBar
import android.widget.TextView
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.paging.LoadState
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.cachedIn

import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.demomiru.tokeiv2.utils.ContinueWatchingViewModel2

import com.demomiru.tokeiv2.utils.addRecyclerAnimation
import com.demomiru.tokeiv2.utils.playShow
import com.demomiru.tokeiv2.utils.retrofitBuilder

import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class TVShowFragment : Fragment() {

    private val activityViewModel : ContinueWatchingViewModel2 by activityViewModels()
    private lateinit var popTvRc: RecyclerView
    private lateinit var trenTvRc: RecyclerView
    private lateinit var topTvRc : RecyclerView




    @OptIn(DelicateCoroutinesApi::class)
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val view =  inflater.inflate(R.layout.fragment_tv_show, container, false)
        popTvRc = view.findViewById(R.id.popular_tvshow_rc)
        trenTvRc = view.findViewById(R.id.trending_tvshow_rc)
        topTvRc = view.findViewById(R.id.toprated_tvshow_rc)


        val retrofit = retrofitBuilder()
        topTvRc.layoutManager = LinearLayoutManager(requireContext(),LinearLayoutManager.HORIZONTAL,false)
        popTvRc.layoutManager = LinearLayoutManager(requireContext(),LinearLayoutManager.HORIZONTAL,false)
        trenTvRc.layoutManager = LinearLayoutManager(requireContext(),LinearLayoutManager.HORIZONTAL,false)

        val tvService = retrofit.create(TMDBService::class.java)

        lifecycleScope.launch(Dispatchers.IO) {
//            val tvPopularShows = Pager(PagingConfig(1)){TvShowPagingSource(1)}.flow.cachedIn(lifecycleScope)
//
//
//            val tvTrendingShows = Pager(PagingConfig(1)){TvShowPagingSource(2)}.flow.cachedIn(lifecycleScope)
//
//            val tvTopShows = Pager(PagingConfig(1)){TvShowPagingSource(3)}.flow.cachedIn(lifecycleScope)

            val topAdapter = TVShowAdapter2{ it, position->
//                    val action = TVShowFragmentDirections.actionTVShowFragmentToTVShowDetails(it.id)
                    findNavController().navigate(playShow(it,position,it.name))
            }



            val trenAdapter = TVShowAdapter2{it, position->
//                    val action = TVShowFragmentDirections.actionTVShowFragmentToTVShowDetails(it.id)
                    findNavController().navigate(playShow(it,position,it.name))
                }



            val popAdapter = TVShowAdapter2{it, position->
//                    val action = TVShowFragmentDirections.actionTVShowFragmentToTVShowDetails(it.id)
                    findNavController().navigate(playShow(it,position,it.name))
            }



            withContext(Dispatchers.Main){
                addRecyclerAnimation(popTvRc,popAdapter)
                addRecyclerAnimation(trenTvRc,trenAdapter)
                addRecyclerAnimation(topTvRc,topAdapter)
                lifecycleScope.launch {
                    activityViewModel.tvTrendingShows.collect{
                        trenAdapter.submitData(it)
                    }
                }

                lifecycleScope.launch {
                    activityViewModel.tvPopularShows.collect{
                        popAdapter.submitData(it)
                    }
                }

                lifecycleScope.launch {
                    topAdapter.addLoadStateListener {
                        val state = it.refresh
                        val visible = state is LoadState.Loading
                        if(visible)
                        {
                            view.findViewById<ProgressBar>(R.id.loading_tvshow).visibility = View.VISIBLE
                        }else{
                            view.findViewById<ProgressBar>(R.id.loading_tvshow).visibility = View.GONE
                            view.findViewById<TextView>(R.id.trending_text).visibility = View.VISIBLE
                            view.findViewById<TextView>(R.id.popular_text).visibility = View.VISIBLE
                            view.findViewById<TextView>(R.id.topShows_text).visibility = View.VISIBLE
                        }
                    }
                    activityViewModel.tvTopShows.collect{
                        topAdapter.submitData(it)
                    }
                }

            }
        }
        return view
    }

    override fun onResume() {
        activityViewModel.currentFragment.value = R.id.TVShowFragment
        super.onResume()
    }
}

================================================
FILE: app/src/main/java/com/demomiru/tokeiv2/TVshow.kt
================================================
package com.demomiru.tokeiv2

data class TVshow(
    val id: String,
    val name: String,
    val poster_path: String,
    val backdrop_path: String
)


================================================
FILE: app/src/main/java/com/demomiru/tokeiv2/VideoPlayActivity.kt
================================================
@file:Suppress("DEPRECATION")
@file:OptIn(DelicateCoroutinesApi::class)

package com.demomiru.tokeiv2

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.demomiru.tokeiv2.watching.VideoData
import android.annotation.SuppressLint
import android.content.Context
import android.content.res.Resources
import android.health.connect.datatypes.units.Length
import android.media.AudioManager
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.os.PowerManager
import android.provider.Settings
import android.util.Log
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Button
import android.widget.FrameLayout
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.ProgressBar

import android.widget.SeekBar
import android.widget.Spinner
import android.widget.TextView
import android.widget.Toast
import androidx.activity.viewModels

import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContentProviderCompat.requireContext


import androidx.core.view.GestureDetectorCompat
import androidx.core.view.isVisible
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.lifecycleScope
import androidx.media3.common.C
import androidx.media3.common.MediaItem
import androidx.media3.common.MimeTypes
import androidx.media3.common.PlaybackException
import androidx.media3.common.Player
import androidx.media3.common.Timeline
import androidx.media3.common.TrackSelectionOverride
import androidx.media3.common.Tracks
import androidx.media3.common.text.CueGroup
import androidx.media3.datasource.DefaultDataSourceFactory
import androidx.media3.datasource.DefaultHttpDataSource
import androidx.media3.exoplayer.ExoPlayer

import androidx.media3.exoplayer.hls.HlsMediaSource
import androidx.media3.exoplayer.source.BaseMediaSource
import androidx.media3.exoplayer.source.MediaSource
import androidx.media3.exoplayer.source.MergingMediaSource
import androidx.media3.exoplayer.source.ProgressiveMediaSource
import androidx.media3.exoplayer.source.SingleSampleMediaSource
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector
import androidx.media3.exoplayer.upstream.DefaultBandwidthMeter
import androidx.media3.ui.AspectRatioFrameLayout

import androidx.media3.ui.PlayerView
import androidx.media3.ui.SubtitleView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.demomiru.tokeiv2.subtitles.SubTrackAdapter
import com.demomiru.tokeiv2.subtitles.Subtitle
import com.demomiru.tokeiv2.subtitles.SubtitleConfig
import com.demomiru.tokeiv2.tracks.SourceAdapter
import com.demomiru.tokeiv2.tracks.Track
import com.demomiru.tokeiv2.tracks.TrackAdapter
import com.demomiru.tokeiv2.utils.ExtractedData
import com.demomiru.tokeiv2.utils.Extractor
import com.demomiru.tokeiv2.utils.GoMovies
import com.demomiru.tokeiv2.utils.GogoAnime
import com.demomiru.tokeiv2.utils.OpenSubtitle
import com.demomiru.tokeiv2.utils.SmashyStream
import com.demomiru.tokeiv2.utils.SubAdapter
import com.demomiru.tokeiv2.utils.SuperstreamUtils
import com.demomiru.tokeiv2.utils.VideoViewModel
import com.demomiru.tokeiv2.utils.encodeStringToInt

import com.demomiru.tokeiv2.utils.getHiTvSeasons
import com.demomiru.tokeiv2.utils.getMovieImdb
import com.demomiru.tokeiv2.utils.getSeasonEpisodes
import com.demomiru.tokeiv2.utils.getTvIMDB
import com.demomiru.tokeiv2.utils.getTvImdb
import com.demomiru.tokeiv2.utils.getTvLink
import com.demomiru.tokeiv2.utils.getTvSeasons
import com.demomiru.tokeiv2.utils.setSeekBarTime
import com.demomiru.tokeiv2.watching.ContinueWatching
import com.demomiru.tokeiv2.watching.ContinueWatchingDatabase
import com.google.android.material.progressindicator.CircularProgressIndicator
import com.google.android.material.switchmaterial.SwitchMaterial
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.File
import java.lang.reflect.Type
import kotlin.Exception
import kotlin.math.abs


class VideoPlayActivity : AppCompatActivity(),AudioManager.OnAudioFocusChangeListener, GestureDetector.OnGestureListener {

    private val gson = Gson()
    private val superStream = SuperstreamUtils()
    private var trackUpdate = 0L
    private val fileList: MutableList<String> = mutableListOf()
    private val fileLinks: MutableList<String> = mutableListOf()
    private var bfapplyUrl = ""
    private var setTrackAdapter = 1
    private val openSubtitleAPI = BuildConfig.OPEN_SUBTITLE_API_KEY
    private var subUpdateProgress = 0L
    private var isShowFinished = false
    private var animeEpList : List<GogoAnime.Episode>? = null
    private lateinit var subSelectBg : ConstraintLayout
    private lateinit var sourceSelectRc: RecyclerView
    private lateinit var qualitySelectBg: ConstraintLayout
    private lateinit var videoLoading: FrameLayout
    private lateinit var showSubs: SwitchMaterial
    private var totalSeasons = 1
    private var totalEpisode = 0
    private var superId: Int? = null
    private var isNextEpisode = MutableLiveData(false)
//    private var isControllerVisible = true
    private lateinit var id:String
    private var season: Int = 1
    private var episode: Int = 1
    private var progress : Int = 0
    private var imgLink : String? = null
    private var year : String = ""
    private lateinit var title:String
    private var type : String? = null
    private var imdbId : String? = null
    private var urlMaps: MutableMap<String,String> = mutableMapOf()
    private lateinit var unlockIv : ImageView
    private var isLocked = false
    private lateinit var lockLL : LinearLayout
    private val database by lazy { ContinueWatchingDatabase.getInstance(this) }
    private val watchHistoryDao by lazy { database.watchDao() }
    private lateinit var gestureDetectorCompat : GestureDetectorCompat
    private var subList = MutableLiveData<List<String>>()
    private lateinit var player : ExoPlayer
    private lateinit var goBack : ImageView
    private lateinit var videoUri: Uri
    private var newVideoUrl  = MutableLiveData<String>("")
    private var isTrackChanged = false
    private var maxVolume: Int = 0
    private var brightness: Int = 0
    private lateinit var brightnessLL: LinearLayout
    private var animeUrl = ""
    private lateinit var brightnessSeek : SeekBar
    private lateinit var volumeLL: LinearLayout
    private lateinit var mainPlayer:FrameLayout
    private lateinit var volumeSeek : SeekBar
    private var audioManager: AudioManager? = null
    private lateinit var seekBar:SeekBar
    private var q = ""
    private var subUrl : List<String> = listOf()
    private var newSubUrl: MutableList<String> = mutableListOf()
    private lateinit var mediaSource: MediaSource
    private lateinit var videoMediaSource: BaseMediaSource
    private lateinit var playPause: ImageButton
    private lateinit var titleTv : TextView
    private lateinit var screenScale: LinearLayout
    private var volume : Int = 0
    private var minSwipeY: Float = 0f
    private var fit = 1
    private var mOrigin: String? = null
    private var selectedUrl : String = ""
    private var sourcesList = listOf<ExtractedData>()
    private var source: String? = ""
    private lateinit var powerManager: PowerManager
    private lateinit var wakeLock: PowerManager.WakeLock
    private lateinit var openSubll : LinearLayout
    private val oS = OpenSubtitle(this)



    private val handler = Handler(Looper.getMainLooper())
    private val updateSeekBarRunnable = object : Runnable {
        override fun run() {
            seekBar.progress = player.currentPosition.toInt()
            subUpdateProgress = player.currentPosition
            //TODO get link for next episode after progress > 95
            handler.postDelayed(this, 1000)
        }
    }

    @SuppressLint("UnsafeOptInUsageError", "ClickableViewAccessibility", "SetTextI18n",
        "SetJavaScriptEnabled"
    )

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_video_play)
        powerManager = getSystemService(POWER_SERVICE) as PowerManager
        wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "VideoPlayerActivity:wakelock")
        showSubs = findViewById(R.id.switchcompat)


//        val sub =PlayerControlView.findViewById<SubtitleView>(R.id.exo_subtitles)
        val videoNext = findViewById<LinearLayout>(R.id.videoView_next_ep)
        val buffer = findViewById<ProgressBar>(R.id.buffering)
        val bundle = intent.extras
        val origin = intent.getStringExtra("origin")

        var isSuper = intent.getBooleanExtra("superstream",false)
        source = intent.getStringExtra("source")

        val data = bundle?.getParcelable("VidData") as? VideoData

        type = data!!.type
        mOrigin = data.origin
        year = data.year?: ""
        if(type == "anime") {
            animeEpList = data.animeEpisode
            totalEpisode = animeEpList!!.size
        }
        id = data.tmdbID.toString()
        println("Video Url:" + data.videoUrl)

        videoUri =  if(isSuper){
            q = "720p"
            urlMaps = gson.fromJson(data.videoUrl,object : TypeToken<Map<String, String>>() {}.type)
            selectedUrl = if(urlMaps["720p"].isNullOrEmpty()) {
                q = urlMaps.keys.first()
                urlMaps[q]!!
            } else
                urlMaps["720p"]!!

            Uri.parse(selectedUrl)

        } else Uri.parse(data.videoUrl)

        bfapplyUrl = selectedUrl


        progress = data.progress
        title = data.title
        imgLink = data.imgLink
        superId = data.superId
        subUrl = data.superSub
        imdbId = data.imdbId

        println("SuperID: $superId")

        if (type != "movie"){
            season = data.season
            episode = data.episode
        }

        val videoQuality = findViewById<TextView>(R.id.videoView_quality)
        videoQuality.text = if (isSuper) q else "Auto"
        val sourceLoading = findViewById<ProgressBar>(R.id.source_loading)

        val sourceAdapter = SourceAdapter{
            newSubUrl.clear()
            newSubUrl.addAll(it.subs)
            if(fileLinks.isNotEmpty()){
                val l = fileLinks.size
                val fl = fileList.size
                var j = 1
                val map  = mutableMapOf<String,String>()
                for (i in (fl-l) until fl ){
                    val lang = fileList[i].substringAfter("lang-").substringBefore("N").replace("%20","")
                    map["$j OS - $lang"] = fileList[i]
                }
                val mapString = gson.toJson(map)
                val prevSubs = newSubUrl
                newSubUrl = (prevSubs + mapString).toMutableList()
            }
            source = it.source
            isSuper = it.isSuper
            isTrackChanged = true
            setTrackAdapter = 1
            newVideoUrl.value = if(!it.isSuper)it.videoUrl else{
                urlMaps = gson.fromJson(it.videoUrl,object : TypeToken<Map<String, String>>() {}.type)
                selectedUrl = urlMaps["720p"]!!
                bfapplyUrl = selectedUrl
                selectedUrl
            }
            subSelectBg.visibility = View.GONE
            videoQuality.text = if (isSuper) q else "Auto"
        }
        sourceSelectRc = findViewById(R.id.source_change_rc)
        sourceSelectRc.apply {
            layoutManager = LinearLayoutManager(this@VideoPlayActivity)
            adapter = sourceAdapter
        }

        if(type!="anime") {
            lifecycleScope.launch(Dispatchers.IO) {
                sourcesList = sourcesList + ExtractedData(data.videoUrl, subUrl, source!!, isSuper)
                sourcesList = sourcesList + Extractor(mOrigin!!).loadSourceChange(
                    title,
                    id,
                    season,
                    episode,
                    year,
                    type == "movie",
                    source
                )
                withContext(Dispatchers.Main) {
                    sourceLoading.visibility = View.GONE
                    sourceAdapter.submitList(sourcesList)
                }
            }
        }




        window.decorView.apply {
            systemUiVisibility = (
                    View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
                            View.SYSTEM_UI_FLAG_IMMERSIVE or
                            View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
                            View.SYSTEM_UI_FLAG_FULLSCREEN
                    )
        }
        gestureDetectorCompat = GestureDetectorCompat(this,this)

        var play = true

        videoLoading = findViewById(R.id.video_loading_fl)
        val webView = findViewById<WebView>(R.id.web_view2)

        webView.settings.javaScriptEnabled = true
        webView.settings.domStorageEnabled = true
        println("Superstream : $isSuper")
        webView.webViewClient = object : WebViewClient() {

            override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
                return request?.url.toString() != view?.url
            }

            override fun shouldInterceptRequest(
                view: WebView?,
                request: WebResourceRequest?
            ): WebResourceResponse? {
                if (request?.url.toString().endsWith("m3u8")){
//                    Log.i("Video Link","Found")
                    lifecycleScope.launch {
                        newVideoUrl.value = request?.url.toString()
                    }
                }
                return super.shouldInterceptRequest(view, request)
            }
        }




        openSubll = findViewById<LinearLayout>(R.id.open_sub_ll)
        val addOpenSub = findViewById<Button>(R.id.add_open_sub)
        val spinner = findViewById<Spinner>(R.id.spinner)
        val search = findViewById<Button>(R.id.search)
        val apply = findViewById<Button>(R.id.apply)
        val subRv = findViewById<RecyclerView>(R.id.sub_rc)
        var langMap : Map<String,String> = mapOf()
        var spinList :List<String>
        var selectedItem = "English"
        var fileLink = ""
        var lI = 0

        var openSubAdapter = SubAdapter{
            fileLink = it
        }

        subRv.apply {
            layoutManager = LinearLayoutManager(this@VideoPlayActivity)
            adapter = openSubAdapter
        }


        lifecycleScope.launch(Dispatchers.IO) {
           langMap =  oS.getLang()
            spinList = langMap.map{
                it.key
            }
            val eI = spinList.indexOfFirst {
                it == "English"
            }

            withContext(Dispatchers.Main){
                val arrayAdapter = ArrayAdapter(
                    this@VideoPlayActivity,
                    android.R.layout.simple_dropdown_item_1line,
                    spinList
                )
                spinner.adapter = arrayAdapter
                spinner.setSelection(eI)
            }
        }


        spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(
                parent: AdapterView<*>?,
                p1: View?,
                position: Int,
                p3: Long
            ) {
                val lang = parent?.getItemAtPosition(position) as String
                if(selectedItem != lang){
                    openSubAdapter = SubAdapter{
                        fileLink = it
                    }
                    subRv.adapter = openSubAdapter
                }
                selectedItem = lang

            }

            override fun onNothingSelected(p0: AdapterView<*>?) {
                selectedItem = "English"
            }

        }

        search.setOnClickListener {
            if (langMap.isEmpty())return@setOnClickListener
            val langCode = langMap[selectedItem]!!
            lifecycleScope.launch(Dispatchers.IO) {
                val sid = if(type=="movie") getMovieImdb(id) else getTvIMDB(id)
                val subRes = oS.searchSubs(sid,langCode,season,episode,type=="movie" )

                withContext(Dispatchers.Main){
                    if (subRes.isEmpty()) Toast.makeText(this@VideoPlayActivity,"No Subs for this Language",Toast.LENGTH_SHORT).show()
                    openSubAdapter.submitList(subRes)
                }
            }
        }


        apply.setOnClickListener{
            if(fileLink.isBlank()) return@setOnClickListener
            if(fileLink in fileLinks) {
                Toast.makeText(this@VideoPlayActivity,"Already added", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }
            lifecycleScope.launch(Dispatchers.IO) {
                val fileName = "$title-S$season-E$episode-lang-$selectedItem N$lI"
                oS.getSub2(fileLink, selectedItem, fileName)
                fileLinks.add(fileLink)
                trackUpdate = subUpdateProgress
                isTrackChanged = true
                withContext(Dispatchers.Main) {
                    val map: MutableMap<String, String> = mutableMapOf()
                    lI++
                    val link = oS.getSRT(fileName).toString()
                    map["$lI OS - $selectedItem"] = link
                    if(link !in fileList) {
                        val mapString = gson.toJson(map)
                        val prevSubs = subList.value
                        subList.value = if (prevSubs != null)
                            prevSubs + mapString
                        else
                            listOf(mapString)
                        fileList.add(link)
                    }
                }
            }
        }




        val remTimeTv = findViewById<TextView>(R.id.videoView_endtime)
        val seekForward: ImageButton = findViewById(R.id.videoView_forward)
        val seekBack : ImageButton = findViewById(R.id.videoView_rewind)
        val subTracks : LinearLayout = findViewById(R.id.videoView_track)
        val vidTracks : LinearLayout = findViewById(R.id.videoView_resolution)
//        if (isSuper) vidTracks.visibility = View.GONE

        if(type == "anime") subTracks.visibility = View.GONE


        val skipOp : LinearLayout = findViewById(R.id.videoView_skip_op)
        if(type != "tvshow") skipOp.visibility = View.VISIBLE
        val skipOpText = findViewById<TextView>(R.id.skip_op_text)
        skipOpText.text = if(type == "movie") "Skip CAM Ads" else "Skip OP"


        val subSelectionView: RecyclerView = findViewById(R.id.sub_tracks_rc)

        subSelectBg = findViewById(R.id.subtitle_select)
        qualitySelectBg = findViewById(R.id.quality_select)

        val applySub : Button = findViewById(R.id.apply_sub)
        val applyQuality : Button = findViewById(R.id.apply_quality)
        val screenResizeTv : TextView = findViewById(R.id.screen_resize_text)
        val screenResizeIv : ImageView = findViewById(R.id.screen_resize_img)
        mainPlayer = findViewById(R.id.main_player)
        goBack = findViewById(R.id.videoView_go_back)
        screenScale = findViewById(R.id.videoView_screen_size)
        lockLL  = findViewById(R.id.videoView_lock_screen)
        unlockIv = findViewById(R.id.unlock_controls)





        brightnessLL = findViewById(R.id.videoView_two_layout)
        brightnessSeek = findViewById(R.id.videoView_brightness)
        val contentResolver = contentResolver
        val currbrightness = Settings.System.getInt(contentResolver, Settings.System.SCREEN_BRIGHTNESS)*3

        brightnessSeek.max = 30
        brightness = currbrightness / 10

        if(audioManager == null) audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
        maxVolume = audioManager!!.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
        Log.i("maxVolume",maxVolume.toString())
        volumeLL = findViewById(R.id.volume_ll)
        volumeSeek = findViewById(R.id.volume_seek)
        volumeSeek.max = maxVolume
        volume = maxVolume/2

        subSelectionView.layoutManager = LinearLayoutManager(this)

        val subtitleView = findViewById<SubtitleView>(R.id.custom_subtitles)
        val playerView = findViewById<PlayerView>(R.id.video_view)

        if(type!="anime")
        playerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM
        else {
            playerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT
            fit = 3
            screenResizeTv.text = "Fit"
            screenResizeIv.setImageResource(R.drawable.fit_screen)
        }
        playerView.subtitleView?.visibility = View.GONE

        subtitleView.setFractionalTextSize(0.05f)
        subtitleView.setApplyEmbeddedStyles(false)

        val trackSelector = DefaultTrackSelector(this)
        player = ExoPlayer.Builder(this).setTrackSelector(trackSelector).build()
        val tracksRv = findViewById<RecyclerView>(R.id.tracks_rc)
        tracksRv.layoutManager = LinearLayoutManager(this)


        showSubs.setOnClickListener {
            if (showSubs.isChecked) subtitleView.visibility = View.VISIBLE
            else subtitleView.visibility = View.GONE
        }


       val a = PlayerView.ControllerVisibilityListener { visibility ->
           if(visibility == View.VISIBLE || !showSubs.isChecked) subtitleView.visibility = View.GONE
           else subtitleView.visibility = View.VISIBLE
       }
        playerView.setControllerVisibilityListener(a)

        try {


            val gestureDetectorDouble =
                GestureDetectorCompat(this, object : GestureDetector.SimpleOnGestureListener() {
                    override fun onDoubleTap(e: MotionEvent): Boolean {

                        if (e.x > playerView.width / 2) {
                            // Double tapped on the right side - forward seek
                            player.seekTo(player.currentPosition + 10000)
                            seekBar.progress = player.currentPosition.toInt()
                        } else {
                            // Double tapped on the left side - backward seek
                            player.seekTo(player.currentPosition - 10000)
                            seekBar.progress = player.currentPosition.toInt()
                        }

                        return super.onDoubleTap(e)
                    }


//            override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
//                // Handle single tap event if needed
//                if (isControllerVisible) {
//                    playerView.hideController()
//                    isControllerVisible = false
//                } else {
//                    playerView.showController()
//                    isControllerVisible = true
//                }
//                return super.onSingleTapConfirmed(e)
//            }

                })

            val dataSourceFactory = DefaultHttpDataSource.Factory()
                .setAllowCrossProtocolRedirects(true)
                .setConnectTimeoutMs(50000)
                .setReadTimeoutMs(50000)
                .setTransferListener(DefaultBandwidthMeter.Builder(this).build())


            playPause = findViewById(R.id.videoView_play_pause_btn)
            seekBar = findViewById(R.id.videoView_seekbar)
            titleTv = findViewById(R.id.videoView_title)




            val listener = object : Player.Listener {


                override fun onTracksChanged(tracks: Tracks) {
                    if (qualitySelectBg.isVisible || subSelectBg.isVisible) return
//                    if (isSuper && setTrackAdapter == 1) {
//                        println("Called adapter")
//                        val trackData = superUrlSelector()
//                        val ta = TrackAdapter(trackData) {
//                            isTrackChanged = true
//                            newSubUrl = subUrl.toMutableList()
//                            selectedUrl = urlMaps[it.resolution.second]!!
//                            videoQuality.text = "${it.resolution.second}"
//                        }
//                        tracksRv.adapter = ta
//                        setTrackAdapter--
//                    }
                    if (setTrackAdapter == 0) return
                    else if(player.duration == C.TIME_UNSET) return
                    else {
                        val trackGroup = tracks.groups[0]
                        val trackRv: MutableList<Track> = mutableListOf()
                        for (i in 0 until trackGroup.length) {
                            val trackDetails = trackGroup.getTrackFormat(i)
//                    val selected = trackGroup.isTrackSelected(i)
                            trackRv.add(
                                Track(
                                    trackDetails.id!!.toInt(),
                                    trackDetails.label.toString(),
                                    Pair(
                                        trackDetails.width.toString(),
                                        trackDetails.height.toString()
                                    ),
                                    selected = false
                                )
                            )
                        }
                        trackRv.add(
                            Track(
                                trackGroup.length,
                                "Auto",
                                Pair("", ""),
                                selected = true
                            )
                        )
                        trackRv.reverse()
                        val trackAdapter = TrackAdapter(trackRv) { track ->
//                    val trackSelectionOverride = TrackSelectionOverride(0, track.id)
//                    track.selected = true
                            player.trackSelectionParameters = if (track.format != "Auto") {
                                videoQuality.text = "${track.resolution.second}p"
                                player.trackSelectionParameters
                                    .buildUpon()
                                    .setOverrideForType(
                                        TrackSelectionOverride(trackGroup.mediaTrackGroup, track.id)
                                    )
                                    .build()

                            } else {
                                videoQuality.text = "Auto"
                                player.trackSelectionParameters
                                    .buildUpon()
                                    .setOverrideForType(
                                        TrackSelectionOverride(
                                            trackGroup.mediaTrackGroup,
                                            MutableList(track.id) { it })
                                    )
                                    .build()


                            }
//                    for( i in 0 until ) println(player.currentTracks.groups[0].isTrackSelected(i))
//                    player.prepare()
                        }
                        for (track in trackRv) {
                            println(track)
                        }
                        tracksRv.adapter = trackAdapter
                    }
                    super.onTracksChanged(tracks)
                }

                //            override fun onVideoSizeChanged(videoSize: VideoSize) {
//               if(videoSize.width !=0 && videoSize.height!=0 ){
//                   videoQuality.text = "${videoSize.height}p"
//               }
//                super.onVideoSizeChanged(videoSize)
//            }
                override fun onPlayerError(error: PlaybackException) {
                    Toast.makeText(
                        this@VideoPlayActivity,
                        "Quality not available or Network Issue",
                        Toast.LENGTH_SHORT
                    ).show()
                    super.onPlayerError(error)
                }

                @SuppressLint("UnsafeOptInUsageError")
                override fun onTimelineChanged(timeline: Timeline, reason: Int) {

                        if (isSuper && setTrackAdapter == 1) {
                            println("Called adapter")
                            val trackData = superUrlSelector()
                            val ta = TrackAdapter(trackData) {
                                isTrackChanged = true
                                newSubUrl = subList.value?.toMutableList() ?: mutableListOf()
                                selectedUrl = urlMaps[it.resolution.second]!!
                                videoQuality.text = "${it.resolution.second}"
                            }
                            tracksRv.adapter = ta
                            setTrackAdapter--
                        }


                    if (player.duration != C.TIME_UNSET) {
                        // Duration is available
                        seekBar.max = player.duration.toInt()

                        subUpdateProgress = trackUpdate
                        trackUpdate = 0L
                        isTrackChanged = false

//                    val seek = player.duration / 100 * progress
//                    println(subUpdateProgress)
                        val seek =
                            if (subUpdateProgress > 0) subUpdateProgress else player.duration / 100 * progress
                        player.seekTo(seek)
                        seekBar.progress = seek.toInt()
                        playerView.setOnTouchListener { _, motionEvent ->
                            if (!isLocked) {
                                gestureDetectorDouble.onTouchEvent(motionEvent)
                                gestureDetectorCompat.onTouchEvent(motionEvent)
                                if (motionEvent.action == MotionEvent.ACTION_UP) {
                                    if (brightnessLL.visibility == View.VISIBLE || volumeLL.visibility == View.VISIBLE) {
                                        playerView.useController = false
                                        brightnessLL.visibility = View.GONE
                                        volumeLL.visibility = View.GONE

                                    }
                                }
                                Handler(Looper.getMainLooper()).postDelayed({
                                    playerView.useController = true
                                }, 1000)
                            } else {

                                if (unlockIv.visibility == View.VISIBLE) {
                                    unlockIv.visibility = View.GONE
                                } else {
                                    unlockIv.visibility = View.VISIBLE
                                    Handler(Looper.getMainLooper()).postDelayed({
                                        unlockIv.visibility = View.GONE
                                    }, 5000)
                                }

                            }
                            return@setOnTouchListener false
                        }
                    }
                    super.onTimelineChanged(timeline, reason)
                }

                override fun onPlaybackStateChanged(playbackState: Int) {
                    if (playbackState == Player.STATE_ENDED) {
                        if (type == "tvshow") {
                            if (isShowFinished || (season == totalSeasons && episode == totalEpisode)) finish()
                            isNextEpisode.value = true
                        } else finish()

                    }
                else if(playbackState == Player.STATE_BUFFERING) {
                        buffer.visibility = View.VISIBLE
                        playPause.visibility = View.GONE
                    }
                    else {
                        playPause.visibility = View.VISIBLE
                        buffer.visibility = View.GONE
                    }
                    super.onPlaybackStateChanged(playbackState)
                }

                override fun onCues(cueGroup: CueGroup) {
                    subtitleView.setCues(cueGroup.cues)
                    super.onCues(cueGroup)
                }
            }
            player.addListener(listener)






            if (subUrl.isEmpty() && imdbId!=null) {
                println("empty")
//                lifecycleScope.launch(Dispatchers.IO) {
//                   val subs = oS.searchSubs(imdbId!!,"eng",season,episode,type=="movie")
//                    val fileName = "$title-$season-$episode-English"
//                    oS.getSub2(subs[0].SubDownloadLink,"English",fileName)
//                    subList.postValue(subUrl + listOf(oS.getSRT(fileName).toString()))
//                }
                subList.postValue(subUrl)

            } else {
                subList.postValue(subUrl)
            }

            isNextEpisode.observe(this) { isNext ->
                if (isNext) {
                    setTrackAdapter = 1
                    if (type == "anime") {
                        getNextAnimeEp()
                        return@observe
                    }
                    println("Source: $source")
                    episodeNext()
                    fileLinks.clear()
                    openSubAdapter = SubAdapter {
                        fileLink = it
                    }
                    subRv.adapter = openSubAdapter
                    sourceLoading.visibility = View.VISIBLE
                    lifecycleScope.launch (Dispatchers.IO){

                        val vidData = Extractor(origin!!).loadExtractorNext(title,id,season,episode,source!!)
                        withContext(Dispatchers.Main){
                            if(vidData.videoUrl!=null){
                                newSubUrl.clear()
                                newSubUrl.addAll(vidData.subs)
                                newVideoUrl.value = if(!vidData.isSuper)vidData.videoUrl ?: "" else{
                                    urlMaps = gson.fromJson(vidData.videoUrl,object : TypeToken<Map<String, String>>() {}.type)
                                    selectedUrl = if(urlMaps[q].isNullOrEmpty()){
                                        q = urlMaps.keys.first()
                                        urlMaps[q]!!
                                    }
                                    else urlMaps[q]!!
                                    selectedUrl
                                }
                            }
                            else
                            {
                                Toast.makeText(this@VideoPlayActivity,"Link not available", Toast.LENGTH_SHORT).show()
                                finish()
                            }
                        }

                        val sourceAdapter2 = SourceAdapter{
                            newSubUrl.clear()
                            newSubUrl.addAll(it.subs)
                            if(fileLinks.isNotEmpty()){
                                val l = fileLinks.size
                                val fl = fileList.size
                                var j = 1
                                val map  = mutableMapOf<String,String>()
                                for (i in (fl-l) until fl ){
                                    val lang = fileList[i].substringAfter("lang-").substringBefore(" ")
                                    map["$j OS - $lang"] = fileList[i]
                                }
                                val mapString = gson.toJson(map)
                                val prevSubs = newSubUrl
                                newSubUrl = (prevSubs + mapString).toMutableList()
                            }
                            source = it.source
                            isSuper = it.isSuper
                            isTrackChanged = true
                            setTrackAdapter = 1
                            newVideoUrl.value = if(!it.isSuper)it.videoUrl else{
                                urlMaps = gson.fromJson(it.videoUrl,object : TypeToken<Map<String, String>>() {}.type)
                                selectedUrl = if(urlMaps[q].isNullOrEmpty()){
                                    q = urlMaps.keys.first()
                                    urlMaps[q]!!
                                }
                                else urlMaps[q]!!
                                bfapplyUrl = selectedUrl
                                selectedUrl
                            }
                            subSelectBg.visibility = View.GONE
                            videoQuality.text = if (isSuper) q else "Auto"
                        }
                        sourceSelectRc.adapter = sourceAdapter2
                        sourcesList = listOf(ExtractedData(newVideoUrl.value,newSubUrl,source!!,isSuper))
                        sourcesList = sourcesList + Extractor(mOrigin!!).loadSourceChange(title,id,season,episode,year,type == "movie",source)
                        withContext(Dispatchers.Main){
                            sourceLoading.visibility = View.GONE
                            sourceAdapter2.submitList(sourcesList)
                        }
                    }

//                    if (origin == "hi") {
//                        episodeNext()
//                        if (!isShowFinished)
//                            lifecycleScope.launch(Dispatchers.IO) {
//                                val res =
//                                    imdbId?.let { getTvLink(it, season - 1, episode - 1) } ?: ""
//
//                                if (res.isNotBlank()) newVideoUrl.postValue(res)
//                                else {
//                                    withContext(Dispatchers.Main) {
//                                        Toast.makeText(
//                                            this@VideoPlayActivity,
//                                            "Not Available",
//                                            Toast.LENGTH_SHORT
//                                        ).show()
//                                        finish()
//                                    }
//                                }
//                            }
//                    } else {
//                        episodeNext()
//                        var isVideo = false
//                        if (!isShowFinished) {
//                            lifecycleScope.launch(Dispatchers.IO) {
//                                if (superId != null && isSuper) {
//                                    val tvLinks =
//                                        superStream.loadLinks(false, superId!!, season, episode)
//                                    tvLinks.data?.list?.forEach {
//                                        if (!it.path.isNullOrBlank()) {
//                                            println("${it.quality} : ${it.path}")
//                                            if (it.quality == "720p") {
//                                                val subtitle = superStream.loadSubtile(
//                                                    false,
//                                                    it.fid!!,
//                                                    superId!!,
//                                                    season,
//                                                    episode
//                                                ).data
//                                                getSub(subtitle)
//                                                if (it.path.isNullOrBlank()) isVideo = true
//                                                newVideoUrl.postValue(it.path!!)
//                                            }
//                                        }
//                                    }
//                                    if (isVideo) {
////                                    withContext(Dispatchers.Main){
////                                        Toast.makeText(this@VideoPlayActivity, "Not Available",Toast.LENGTH_SHORT).show()
////                                        finish()
////                                    }
//                                        getGoMovieLink()
////                                    getSmashLink()
//                                    }
//                                } else {
////                                withContext(Dispatchers.Main){
////                                    Toast.makeText(this@VideoPlayActivity, "Not Available",Toast.LENGTH_SHORT).show()
////                                    finish()
////                                }
//                                    getGoMovieLink()
////                                getSmashLink()
//                                }
//                            }
//                        }
//                    }
                    isNextEpisode.value = false
                }
            }

            // When Subtitles are available
            subList.observe(this) {
                fileLink = ""
                val subtitleConfig: MutableList<SubtitleConfig> = mutableListOf()
                var s = 0
//                videoQuality.text = if (isSuper) "720p" else "Auto"
                if (!it.isNullOrEmpty()) {
                    val map = it[0]
                    var subMap : MutableMap<String,String> = mutableMapOf()
                    if(!map.isNullOrBlank()) subMap = gson.fromJson(map, object : TypeToken<Map<String, String>>() {}.type)
                    for( key in subMap.keys){
                        val subs = subMap[key]!!.split(",")
                        var i = 1
                        for (element in subs) {
                            val subtitleMediaSource = if (element.contains("vtt")) {
                                SingleSampleMediaSource.Factory(dataSourceFactory).createMediaSource(
                                    MediaItem.SubtitleConfiguration.Builder(Uri.parse(element))
                                        .setMimeType(MimeTypes.TEXT_VTT)
                                        .setLanguage("en")
                                        .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
                                        .build(),
                                    C.TIME_UNSET
                                )
                            }else if (element.contains("file://")) {
                                SingleSampleMediaSource.Factory(DefaultDataSourceFactory(this@VideoPlayActivity,"user-agent")).createMediaSource(
                                    MediaItem.SubtitleConfiguration.Builder(Uri.parse(element))
                                        .setMimeType(MimeTypes.APPLICATION_SUBRIP)
                                        .setLanguage("en")
                                        .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
                                        .build(),
                                    C.TIME_UNSET
                                )
                            }
                            else {
                                SingleSampleMediaSource.Factory(dataSourceFactory).createMediaSource(
                                    MediaItem.SubtitleConfiguration.Builder(Uri.parse(element))
                                        .setMimeType(MimeTypes.APPLICATION_SUBRIP)
                                        .setLanguage("en")
                                        .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
                                        .build(),
                                    C.TIME_UNSET
                                )

                            }
                            subtitleConfig.add(SubtitleConfig(subtitleMediaSource, language = "$key $i"))
                            if(i==6)break
                            i++
                        }
                    }

                    s = subtitleConfig.indexOfFirst {subConfig ->
                        subConfig.language.contains("English")
                    }
                    if(it.size > 1){
                        for( i in 1 until it.size){
                            val map = it[i]
                            var subMap : MutableMap<String,String> = mutableMapOf()
                            if(!map.isNullOrBlank()) subMap = gson.fromJson(map, object : TypeToken<Map<String, String>>() {}.type)
                            for( key in subMap.keys){
                                val subtitleMediaSource =
                                    SingleSampleMediaSource.Factory(DefaultDataSourceFactory(this@VideoPlayActivity,"user-agent")).createMediaSource(
                                        MediaItem.SubtitleConfiguration.Builder(Uri.parse(subMap[key]))
                                            .setMimeType(MimeTypes.APPLICATION_SUBRIP)
                                            .setLanguage("en")
                                            .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
                                            .build(),
                                        C.TIME_UNSET
                                    )
                                subtitleConfig.add(0,SubtitleConfig(subtitleMediaSource, language = "$key"))
                                s = 0
                            }
                        }
                    }


                    // change from here
//                    for (element in it) {
//                        println(element)
//                        val subtitleMediaSource = if (element.contains("vtt")) {
//                            SingleSampleMediaSource.Factory(dataSourceFactory).createMediaSource(
//                                MediaItem.SubtitleConfiguration.Builder(Uri.parse(element))
//                                    .setMimeType(MimeTypes.TEXT_VTT)
//                                    .setLanguage("en")
//                                    .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
//                                    .build(),
//                                C.TIME_UNSET
//                            )
//                        } else {
//                            SingleSampleMediaSource.Factory(dataSourceFactory).createMediaSource(
//                                MediaItem.SubtitleConfiguration.Builder(Uri.parse(element))
//                                    .setMimeType(MimeTypes.APPLICATION_SUBRIP)
//                                    .setLanguage("en")
//                                    .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
//                                    .build(),
//                                C.TIME_UNSET
//                            )
//
//                        }
//                        subtitleConfig.add(SubtitleConfig(subtitleMediaSource))
//                    }

//                    val
                            videoMediaSource = if (isSuper || source == "nowtv") {
                                if(source == "nowtv"){
                                    val dsF = DefaultHttpDataSource.Factory()
                                        .setDefaultRequestProperties(mapOf("Referer" to "https://bflix.gs/",
                                        "Connection" to "keep-alive"
                                            ))
                                        .setAllowCrossProtocolRedirects(true)
                                        .setConnectTimeoutMs(50000)
                                        .setReadTimeoutMs(50000)
                                        .setTransferListener(DefaultBandwidthMeter.Builder(this).build())
                                    println("NowTV insiide videomedia")
                                    ProgressiveMediaSource.Factory(dsF)
                                        .createMediaSource(MediaItem.fromUri(videoUri))

                                }else
                                ProgressiveMediaSource.Factory(dataSourceFactory)
                            .createMediaSource(MediaItem.fromUri(videoUri))
                    } else {
                        HlsMediaSource.Factory(dataSourceFactory)
                            .createMediaSource(MediaItem.fromUri(videoUri))
                    }

//                player.setMediaItem(mediaItem)

                    subSelectionView.adapter = SubTrackAdapter(subtitleConfig, s){ sub ->
                        val newMediaSource = MergingMediaSource(videoMediaSource, sub.subConfig)
                        subUpdateProgress = player.currentPosition
                        trackUpdate = subUpdateProgress
                        player.setMediaSource(newMediaSource)
                        player.prepare()
//                    player.seekTo(subUpdateProgress)
//                    seekBar.progress = subUpdateProgress.toInt()
                    }
                    mediaSource = MergingMediaSource(videoMediaSource, subtitleConfig[s].subConfig)
                } else {
                    subSelectionView.adapter = SubTrackAdapter(subtitleConfig, s) {}
                    mediaSource = if (isSuper) {
                        ProgressiveMediaSource.Factory(dataSourceFactory)
                            .createMediaSource(MediaItem.fromUri(videoUri))
                    } else {
                        HlsMediaSource.Factory(dataSourceFactory)
                            .createMediaSource(MediaItem.fromUri(videoUri))
                    }
                }

                player.setMediaSource(mediaSource)
                if (type == "movie")
                    titleTv.text = title
                else {
                    videoNext.visibility = View.VISIBLE
                    titleTv.text =
                        if (type == "tvshow") "$title S$season E$episode" else "$title E${episode + 1}"
                }

                mainPlayer.visibility = View.VISIBLE
                playerView.player = player
                videoLoading.visibility = View.GONE

                player.prepare()
                player.playWhenReady = true

                println("${player.videoSize.width} x ${player.videoSize.height}")

                playerPlay()

                subTracks.setOnClickListener {
                    playerPause()
                    mainPlayer.visibility = View.GONE
                    subSelectBg.visibility = View.VISIBLE

                }

                addOpenSub.setOnClickListener {
                    openSubll.visibility = View.VISIBLE
                    subSelectBg.visibility = View.GONE
                }

                vidTracks.setOnClickListener {
                    playerPause()
                    mainPlayer.visibility = View.GONE
                    qualitySelectBg.visibility = View.VISIBLE
                }

                applyQuality.setOnClickListener {
                    qualitySelectBg.visibility = View.GONE
                    mainPlayer.visibility = View.VISIBLE
                    if(isSuper) {
                        if (bfapplyUrl != selectedUrl)
                            newVideoUrl.value = selectedUrl
                    }

                    player.seekTo(subUpdateProgress)
                    seekBar.progress = subUpdateProgress.toInt()

                    playerPlay()
                    bfapplyUrl = selectedUrl
                }

                applySub.setOnClickListener {
                    subSelectBg.visibility = View.GONE
                    mainPlayer.visibility = View.VISIBLE
                    player.seekTo(subUpdateProgress)
                    seekBar.progress = subUpdateProgress.toInt()
                    playerPlay()
                }


                playPause.setOnClickListener {
                    play = if (play) {
                        player.pause()
                        playPause.setImageResource(R.drawable.icon_play)
                        false
                    } else {
                        player.play()
                        playPause.setImageResource(R.drawable.netflix_pause_button)
                        true
                    }
                }

                seekForward.setOnClickListener {
                    val progress = (player.currentPosition + 10000)
                    player.seekTo(progress)
                    seekBar.progress = progress.toInt()
                    seekForward.rotation = 90f
                    Handler(Looper.getMainLooper()).postDelayed({
                        seekForward.rotation = 0f
                    }, 1000)
                }

                seekBack.setOnClickListener {
                    val progress = (player.currentPosition - 10000)
                    player.seekTo(progress)
                    seekBar.progress = progress.toInt()
                    seekBack.rotation = -90f
                    Handler(Looper.getMainLooper()).postDelayed({
                        seekBack.rotation = 0f
                    }, 1000)  // Delay of 1 second

                }

                screenScale.setOnClickListener {
                    when (fit) {
                        1 -> {
                            playerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL
                            screenResizeTv.text = "Fill"
                            screenResizeIv.setImageResource(R.drawable.fill_screen)
                            fit = 2
                        }

                        2 -> {
                            playerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT
                            screenResizeTv.text = "Fit"
                            screenResizeIv.setImageResource(R.drawable.fit_screen)
                            fit = 3
                        }

                        else -> {
                            playerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM
                            screenResizeTv.text = "Zoom"
                            screenResizeIv.setImageResource(R.drawable.baseline_zoom_out_map_24)
                            fit = 1
                        }
                    }
                }

                lockLL.setOnClickListener {
                    isLocked = true
                    playerView.useController = false
//                    unlockIv.visibility = View.VISIBLE
                }


                goBack.setOnClickListener {
                    finish()
                }

                unlockIv.setOnClickListener {
                    isLocked = false
                    playerView.useController = true
                    unlockIv.visibility = View.GONE
                }

                videoNext.setOnClickListener {
                    isNextEpisode.value = true
                }

                skipOp.setOnClickListener {
                    val progress = (player.currentPosition + 90000)
                    player.seekTo(progress)
                    seekBar.progress = progress.toInt()
                }

            }

            newVideoUrl.observe(this) { newUrl ->
                if (!newUrl.isNullOrEmpty()) {
                    videoUri = Uri.parse(newUrl)
                    if (!isTrackChanged) {
                        if(isSuper) videoQuality.text = "720p" else videoQuality.text = "Auto"
                        progress = 0
                        subUpdateProgress = 0
                    } else {
//                        newSubUrl = subUrl.toMutableList()
                        trackUpdate = subUpdateProgress
                    }
                    isTrackChanged = false

                    subList.value = newSubUrl.toList()

//                    if (newSubUrl.isEmpty() && type != "anime") {
//                        println("empty")
//                        lifecycleScope.launch(Dispatchers.IO) {
//                            val fileID: List<String> = if (type == "movie") {
//                                getSubtitles(id)
//                            } else {
//                                getSubtitles(id, season, episode)
//                            }
//
//                            subList.postValue(getAuthToken(fileID))
//                        }
//                    } else {
//                        subList.postValue(newSubUrl.toList())
//                    }
                }
            }

            if (type == "tvshow") {
                lifecycleScope.launch(Dispatchers.IO) {
                    totalSeasons =
                        if (origin != "hi") getTvSeasons(id) else getHiTvSeasons(imdbId!!)
                    totalEpisode = getSeasonEpisodes(id, season)
                }

            }


//        if (seekBar.progress == seekBar.max)isNextEpisode.value = true


            seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
                override fun onProgressChanged(
                    seekBar: SeekBar?,
                    progress: Int,
                    fromUser: Boolean
                ) {
                    if (player.duration != C.TIME_UNSET) {
                        val rem = player.duration - progress.toLong()
                        if (fromUser) {
                            player.seekTo(progress.toLong())
                            subUpdateProgress = player.currentPosition
                            remTimeTv.text = setSeekBarTime(rem)
                        }
                        remTimeTv.text = setSeekBarTime(rem)
                        subUpdateProgress = player.currentPosition
                    }
                }

                override fun onStartTrackingTouch(seekBar: SeekBar?) {
                    // Optional: stop updating the SeekBar while the user is dragging it
                    handler.removeCallbacks(updateSeekBarRunnable)
                }

                override fun onStopTrackingTouch(seekBar: SeekBar?) {
                    // Optional: resume updating the SeekBar after the user finished dragging it
                    handler.post(updateSeekBarRunnable)
                }
            })


            // Start updating the SeekBar
            handler.post(updateSeekBarRunnable)
        }catch (e :Exception){e.printStackTrace()}

    }

//    private suspend fun getGoMovieLink(){
//        val goMovie = GoMovies()
//        newSubUrl.clear()
//        lifecycleScope.launch(Dispatchers.IO) {
//            val data = goMovie.search(season, episode, title,false,year)
//            val vidLink = data.first
//            val subLinks = data.second
//            if(vidLink.isNullOrBlank()){
////                withContext(Dispatchers.Main){
////                    Toast.makeText(this@VideoPlayActivity, "Not Available",Toast.LENGTH_SHORT).show()
////                    finish()
////                }
//                getSmashLink()
//            }
//            else{
//                if (!subLinks.isNullOrEmpty())newSubUrl.addAll(subLinks)
//                newVideoUrl.postValue(vidLink!!)
//            }
//        }
//    }

//    private fun getSmashLink()
//    {
//        newSubUrl.clear()
//        val smashSrc = SmashyStream()
//        lifecycleScope.launch(Dispatchers.IO) {
//            val links = smashSrc.getLink(false,id, season, episode)
//            val vidLink = links.first
//            val subLink = links.second
//            if(vidLink.isNullOrBlank()){
//                withContext(Dispatchers.Main){
//                    Toast.makeText(this@VideoPlayActivity, "Not Available",Toast.LENGTH_SHORT).show()
//                    finish()
//                }
//            }
//            else{
//                if (!subLink.isNullOrBlank())newSubUrl.add(subLink)
//                newVideoUrl.postValue(vidLink!!)
//            }
//        }
//    }
//
//    private fun getSub(subtitle: SuperstreamUtils.PrivateSubtitleData?){
//        newSubUrl.clear()
//        subtitle?.list?.forEach { subList->
//            if(subList.language == "English"){
//                subList.subtitles.forEach { sub->
//
//                    if (newSubUrl.size == 3) {
//                        return
//                    }
//                    if (sub.lang == "en" && !sub.file_path.isNullOrBlank()) {
//                        newSubUrl.add(sub.file_path)
//                        println("${sub.language} : ${sub.file_path}")
//                    }
//
//
//                }
//                return
//            }
//        }
//    }


    private fun getNextAnimeEp()
    {
        val gogoSrc = GogoAnime()
        episode+=1
        if (episode == totalEpisode) {
            Toast.makeText(this, "No further episodes", Toast.LENGTH_SHORT).show()
            isShowFinished = true
            episode = totalEpisode-1
            return
        }
        animeUrl = animeEpList?.get(episode)?.url ?: ""
        mainPlayer.visibility = View.GONE
        playerPause()
        videoLoading.visibility = View.VISIBLE

        lifecycleScope.launch {
            newVideoUrl.postValue(gogoSrc.extractVideos(animeUrl))
        }
    }


    private fun getAuthToken(fileId: List<String>): List<String>{
        val client = OkHttpClient()

        val mediaType = "application/json".toMediaTypeOrNull()
        val body =
            "{\n  \"username\": \"bokaboy_20\",\n  \"password\": \"d.omh.err.y61.7@gmail.com\"\n}".toRequestBody(mediaType)
        try {


            val request = Request.Builder()
                .url("https://api.opensubtitles.com/api/v1/login")
                .post(body)
                .addHeader("Content-Type", "application/json")
                .addHeader("User-Agent", "")
                .addHeader("Accept", "application/json")
                .addHeader("Api-Key", openSubtitleAPI)
                .build()
            val response = client.newCall(request).execute()



            if (response.isSuccessful) {
                val gson = Gson()

                val responseBody = response.body

                val type: Type = object : TypeToken<Map<String?, Any?>?>() {}.type
                val map: Map<String, Any> = gson.fromJson(responseBody.string(), type)
                val token = map["token"].toString()
                Log.i("response", token)

                responseBody.close()
                val downloadUrlList = mutableListOf<String>()
                for (element in fileId) {
                    downloadUrlList.add(getSubtitleURl(token, element))
                }

                return downloadUrlList.toList()
            } else
                Log.i("response", "unsuccessful")
        }catch (e :Exception){
            e.printStackTrace()
            return listOf()
        }
        return listOf()
    }

    private fun getSubtitleURl(token:String, fileId: String):String{
        val client = OkHttpClient()

        val mediaType = "application/json".toMediaTypeOrNull()
        val body = "{\n  \"file_id\": $fileId\n}".toRequestBody(mediaType)
        try{
            val request = Request.Builder()
                .url("https://api.opensubtitles.com/api/v1/download")
                .post(body)
                .addHeader("User-Agent", "")
                .addHeader("Content-Type", "application/json")
                .addHeader("Accept", "application/json")
                .addHeader("Api-Key", openSubtitleAPI)
                .addHeader("Authorization", token)
                .build()

            val response = client.newCall(request).execute()
            if (response.isSuccessful){
                val gson = Gson()

                val responseBody = response.body

                val type: Type = object : TypeToken<Map<String?, Any?>?>() {}.type
                val map: Map<String, Any> = gson.fromJson(responseBody.string(), type)
                responseBody.close()
                return map["link"].toString()

            }
        }catch (e :Exception){
            e.printStackTrace()
            return ""
        }
        return ""
    }

    private fun getSubtitles(tmdbId:String, season:Int = 0, episode:Int = 0) : List<String>{
        val client = OkHttpClient()

        try{
            val request : Request
            if(type == "movie") {
                request = Request.Builder()
                    .url("https://api.opensubtitles.com/api/v1/subtitles?tmdb_id=$tmdbId&type=movie&languages=en&order_by=ratings&page=1")
                    .get()
                    .addHeader("User-Agent", "")
                    .addHeader("Api-Key", openSubtitleAPI)
                    .build()
            }
            else{
                request = Request.Builder()
                    .url("https://api.opensubtitles.com/api/v1/subtitles?languages=en&order_by=ratings&parent_tmdb_id=$tmdbId&season_number=$season&episode_number=$episode&page=1")
                    .get()
                    .addHeader("User-Agent", "")
                    .addHeader("Api-Key", openSubtitleAPI)
                    .build()
            }

            val response = client.newCall(request).execute()
            if (response.isSuccessful){
                val gson = Gson()
                val responseBody = response.body
                val subtitle: Subtitle = gson.fromJson(responseBody.string(), Subtitle::class.java)
                responseBody.close()
                val fileIDs = mutableListOf<String>()
                val count = if(subtitle.data.size> 3) 3
                else subtitle.data.size

                for (i in 0 until count){
                    fileIDs.add(subtitle.data[i].attributes.files[0].file_id)
                }
                return fileIDs.toList()
            }
        }catch (e :Exception){
            e.printStackTrace()
            return listOf()
        }
        return listOf()
    }


    private fun playerPause(){
        player.pause()
        playPause.setImageResource(R.drawable.icon_play)
    }
    private fun playerPlay(){
        player.play()
        playPause.setImageResource(R.drawable.netflix_pause_button)
    }

    override fun onPause(){
        wakeLock.release()
        player.pause()
        playPause.setImageResource(R.drawable.icon_play)
        super.onPause()

    }

    override fun onDestroy() {
        handler.removeCallbacks(updateSeekBarRunnable)
        val currentPosition = player.currentPosition
        val duration = player.duration
        val progress = (currentPosition * 100 / duration).toInt()


        GlobalScope.launch(Dispatchers.IO) {
                if (type == "movie") {
                    if (progress in 3..96){
                        watchHistoryDao.insert(
                            ContinueWatching(
                                progress = progress,
                                imgLink = imgLink!!,
                                tmdbID = id.toInt(),
                                title = title,
                                type = type!!,
                                origin = mOrigin,
                                year = year
                            )
                        )
                    }
                } else if (type == "tvshow") {
                    watchHistoryDao.insert(
                        ContinueWatching(
                            progress = progress,
                            imgLink = imgLink!!,
                            tmdbID = id.toInt(),
                            title = title,
                            season = season,
                            episode = episode,
                            type = type!!
                        )
                    )
                }
                else {
                    watchHistoryDao.insert(
                        ContinueWatching(
                            progress = progress,
                            imgLink = imgLink!!,
                            tmdbID = encodeStringToInt(title),
                            title = title,
                            season = season,
                            episode = episode,
                            type = type!!,
                            animeEp = animeEpList
                        )
                    )
                }

            }

        Log.i("Progress", progress.toString())
        player.playWhenReady = false
        player.stop()
        player.seekTo(0)

        player.release() // or pause, depending on your requirements

        lifecycleScope.launch (Dispatchers.IO) {
            for (s in fileList) {
                val path = Uri.parse(s).path
                path?.let {
                    File(path).delete()
                }
            }
        }

        Log.i("Finish", "Called finish() go back pressed")
        super.onDestroy()
    }

    override fun onDown(p0: MotionEvent): Boolean = false

    override fun onShowPress(p0: MotionEvent) = Unit

    override fun onSingleTapUp(p0: MotionEvent): Boolean = false
    override fun onScroll(event: MotionEvent?, event1: MotionEvent, dX: Float, dY: Float): Boolean {
        minSwipeY += dY

        val sWidth = Resources.getSystem().displayMetrics.widthPixels

        if(abs(dX)< abs(dY) && abs(minSwipeY) > 50){
            if(event!!.x < sWidth/2){
                brightnessLL.visibility = View.VISIBLE
                volumeLL.visibility = View.GONE
                val increase = dY > 0
                val newValue = if(increase) brightness + 1 else brightness - 1

                if(newValue in 0..30) brightness = newValue
                brightnessSeek.progress = brightness
                setScreenBrightness(brightness)
            }
            else{
                brightnessLL.visibility = View.GONE
                volumeLL.visibility = View.VISIBLE

                val increase = dY > 0
                val newValue = if(increase) volume + 5 else volume - 5
                if(newValue in 0..maxVolume) volume = newValue
                volumeSeek.progress = volume
                audioManager!!.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0)
            }
            minSwipeY = 0f
        }
        return true
    }

    private fun setScreenBrightness(value: Int){
        val d = 1.0f/30
        val lp = this.window.attributes
        lp.screenBrightness = d * value
        this.window.attributes = lp
    }

    private fun episodeNext(){
        if (episode < totalEpisode) {
            mainPlayer.visibility = View.GONE
            playerPause()
            videoLoading.visibility = View.VISIBLE
            episode += 1
        } else {
            if (season < totalSeasons) {
                season += 1
                playerPause()
                lifecycleScope.launch(Dispatchers.IO) {
                    totalEpisode = getSeasonEpisodes(id, season)
                }
                mainPlayer.visibility = View.GONE

                videoLoading.visibility = View.VISIBLE
                episode = 1
            } else {
                Toast.makeText(
                    this@VideoPlayActivity,
                    "ShowFinished",
                    Toast.LENGTH_SHORT
                ).show()
                isShowFinished = true
            }
        }
    }



    private fun superUrlSelector() : List<Track>
    {
        var id = 0
        var selectPos = 0
        var tracks = urlMaps.map {
            val selected = it.key == q

            val resolution = Pair("",it.key)

            if(selected)selectPos = id
            Track(id++,"super",resolution,selected)
        }
        val selectedQ = tracks.get(selectPos)
        tracks = tracks - selectedQ
        tracks = tracks + selectedQ
        tracks = tracks.reversed()
        println(tracks)
        return tracks
    }


    @SuppressLint("WakelockTimeout")
    override fun onResume() {
        super.onResume()
            wakeLock.acquire()
        if(audioManager == null) audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
        audioManager!!.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN)
        if(brightness != 0) setScreenBrightness(brightness)
    }



    @Deprecated("Deprecated in Java")
    override fun onBackPressed() {
        if(subSelectBg.visibility != View.VISIBLE && !qualitySelectBg.isVisible && !openSubll.isVisible)
        super.onBackPressed()
        else if (openSubll.isVisible){
            openSubll.visibility = View.GONE
            subSelectBg.visibility = View.VISIBLE
        }
        else{
            subSelectBg.visibility = View.GONE
            qualitySelectBg.visibility = View.GONE
            mainPlayer.visibility = View.VISIBLE
            playerPlay()
        }
    }

    override fun onLongPress(p0: MotionEvent) = Unit
    override fun onFling(p0: MotionEvent?, p1: MotionEvent, p2: Float, p3: Float): Boolean  = false
    override fun onAudioFocusChange(focusChange: Int) {
        if(focusChange <= 0) playerPause()
    }
}

================================================
FILE: app/src/main/java/com/demomiru/tokeiv2/anime/AnimeAdapter.kt
================================================
package com.demomiru.tokeiv2.anime

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import coil.ImageLoader
import coil.disk.DiskCache
import coil.load
import coil.memory.MemoryCache
import com.demomiru.tokeiv2.R
import com.demomiru.tokeiv2.utils.GogoAnime

class AnimeAdapter(context: Context, private val onClick: (GogoAnime.AnimeSearchResponse) -> Unit): ListAdapter<GogoAnime.AnimeSearchResponse, AnimeAdapter.ViewHolder>(
    DiffCallBack
) {

    private val imageLoader = ImageLoader.Builder(context)
        .memoryCache { MemoryCache.Builder(context).maxSizePercent(0.25).build() }
        .build()

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view){
        val imageView : ImageView = view.findViewById(R.id.image_view)
        val title : TextView = view.findViewById(R.id.title_text_view)
        val dub: TextView = view.findViewById(R.id.tv_show_detail_tv)
    }

    object DiffCallBack: DiffUtil.ItemCallback<GogoAnime.AnimeSearchResponse>(){
        override fun areItemsTheSame(
            oldItem: GogoAnime.AnimeSearchResponse,
            newItem: GogoAnime.AnimeSearchResponse
        ): Boolean {
            return oldItem === newItem
        }

        override fun areContentsTheSame(
            oldItem: GogoAnime.AnimeSearchResponse,
            newItem: GogoAnime.AnimeSearchResponse
        ): Boolean {
            return oldItem == newItem
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_view, parent,false)
        return ViewHolder(view)

    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val anime = getItem(position)
        holder.imageView.load(anime.posterUrl,imageLoader)
        holder.title.text = anime.name
        if(anime.dub!=null){
            holder.dub.visibility = if(anime.dub) View.VISIBLE else View.GONE
        }
        holder.itemView.setOnClickListener {
            onClick(anime)
        }
    }
}

class AnimeEpisodeAdapter(private val onClick: (GogoAnime.Episode,Int) -> Unit) : ListAdapter<GogoAnime.Episode, AnimeEpisodeAdapter.ViewHolder>(
    DiffCallBack
){

    class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView){
        val episodeText : TextView = itemView.findViewById(R.id.episode_no_text)
    }

    object DiffCallBack : DiffUtil.ItemCallback<GogoAnime.Episode>() {
        override fun areItemsTheSame(
            oldItem: GogoAnime.Episode,
            newItem: GogoAnime.Episode
        ): Boolean {
            return oldItem === newItem
        }

        override fun areContentsTheSame(
            oldItem: GogoAnime.Episode,
            newItem: GogoAnime.Episode
        ): Boolean {
            return oldItem == newItem
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.episode_item_viem,parent,false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val episode = getItem(position)
        holder.episodeText.text = episode.name
        holder.itemView.setOnClickListener {
            onClick(episode,position)
        }
    }


}

================================================
FILE: app/src/main/java/com/demomiru/tokeiv2/anime/AnimeDetailsFragment.kt
================================================
package com.demomiru.tokeiv2.anime

import android.annotation.SuppressLint
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import android.widget.Button
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import coil.load
import com.demomiru.tokeiv2.R
import com.demomiru.tokeiv2.TVShowDetailsArgs

import com.demomiru.tokeiv2.databinding.FragmentAnimeDetailsBinding
import com.demomiru.tokeiv2.utils.ContinueWatchingViewModel
import com.demomiru.tokeiv2.utils.ContinueWatchingViewModel2
import com.demomiru.tokeiv2.utils.ContinueWatchingViewModelFactory
import com.demomiru.tokeiv2.utils.GogoAnime
import com.demomiru.tokeiv2.utils.encodeStringToInt
import com.demomiru.tokeiv2.utils.passData
import com.demomiru.tokeiv2.watching.ContinueWatchi
Download .txt
gitextract_qqda0tz5/

├── .gitignore
├── .idea/
│   ├── .gitignore
│   ├── compiler.xml
│   ├── gradle.xml
│   ├── kotlinc.xml
│   ├── misc.xml
│   └── vcs.xml
├── README.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── demomiru/
│       │               └── tokeiv2/
│       │                   └── ExampleInstrumentedTest.kt
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── demomiru/
│       │   │           └── tokeiv2/
│       │   │               ├── EpisodeAdapter.kt
│       │   │               ├── EpisodeAdapter2.kt
│       │   │               ├── MainActivity.kt
│       │   │               ├── Movie.kt
│       │   │               ├── MovieAdapter.kt
│       │   │               ├── MoviePlayActivity.kt
│       │   │               ├── MovieService.kt
│       │   │               ├── MoviesFragment.kt
│       │   │               ├── SearchFragment.kt
│       │   │               ├── TMDBService.kt
│       │   │               ├── TVShowAdapter.kt
│       │   │               ├── TVShowCardAdapter.kt
│       │   │               ├── TVShowDetails.kt
│       │   │               ├── TVShowFragment.kt
│       │   │               ├── TVshow.kt
│       │   │               ├── VideoPlayActivity.kt
│       │   │               ├── anime/
│       │   │               │   ├── AnimeAdapter.kt
│       │   │               │   ├── AnimeDetailsFragment.kt
│       │   │               │   ├── AnimeFragment.kt
│       │   │               │   └── AnimeInfo.kt
│       │   │               ├── extractors/
│       │   │               │   ├── CorrectTitleSelection.kt
│       │   │               │   ├── PrMovies.kt
│       │   │               │   └── Vidplay.kt
│       │   │               ├── history/
│       │   │               │   ├── QueryRepository.kt
│       │   │               │   ├── SearchApp.kt
│       │   │               │   ├── SearchDatabase.kt
│       │   │               │   ├── SearchHistory.kt
│       │   │               │   ├── SearchHistoryAdapter.kt
│       │   │               │   ├── SearchHistoryAdapter2.kt
│       │   │               │   └── SearchHistoryDao.kt
│       │   │               ├── subtitles/
│       │   │               │   ├── SubTrackAdapter.kt
│       │   │               │   └── Subtitles.kt
│       │   │               ├── tracks/
│       │   │               │   └── TrackAdapter.kt
│       │   │               ├── utils/
│       │   │               │   ├── DudeFilmsUtils.kt
│       │   │               │   ├── Extractor.kt
│       │   │               │   ├── GoMovies.kt
│       │   │               │   ├── GogoAnime.kt
│       │   │               │   ├── OpenSubtitle.kt
│       │   │               │   ├── SmashyStream.kt
│       │   │               │   ├── SuperstreamUtils.kt
│       │   │               │   ├── VidSrc.kt
│       │   │               │   ├── VidSrcUtils.kt
│       │   │               │   ├── ViewModelsTokei.kt
│       │   │               │   ├── colors.txt
│       │   │               │   └── retrofitBuilder.kt
│       │   │               └── watching/
│       │   │                   ├── ContinueWatching.kt
│       │   │                   ├── ContinueWatchingAdapter.kt
│       │   │                   ├── ContinueWatchingDao.kt
│       │   │                   ├── ContinueWatchingDatabase.kt
│       │   │                   └── ContinueWatchingRepository.kt
│       │   └── res/
│       │       ├── anim/
│       │       │   ├── enter_anim.xml
│       │       │   ├── enter_from_bottom.xml
│       │       │   ├── exit_anim.xml
│       │       │   ├── exit_to_top.xml
│       │       │   ├── go_left.xml
│       │       │   ├── go_right.xml
│       │       │   ├── layout_animation.xml
│       │       │   ├── nav_enter_anim.xml
│       │       │   ├── nav_exit_anim.xml
│       │       │   ├── nav_pop_enter.xml
│       │       │   ├── nav_pop_exit.xml
│       │       │   ├── pop_enter.xml
│       │       │   ├── pop_exit.xml
│       │       │   ├── rotate_around_center_point.xml
│       │       │   ├── rotate_left.xml
│       │       │   ├── rotate_right.xml
│       │       │   ├── slide_from_uo.xml
│       │       │   ├── slide_in.xml
│       │       │   ├── slide_in_right.xml
│       │       │   └── slide_out.xml
│       │       ├── drawable/
│       │       │   ├── anime_bottom_nav.xml
│       │       │   ├── background_search_history.xml
│       │       │   ├── background_text.xml
│       │       │   ├── baseline_cancel_24.xml
│       │       │   ├── baseline_double_arrow_24.xml
│       │       │   ├── baseline_history_24.xml
│       │       │   ├── baseline_keyboard_arrow_down_24.xml
│       │       │   ├── baseline_keyboard_arrow_up_24.xml
│       │       │   ├── baseline_lock_open_24.xml
│       │       │   ├── baseline_play_arrow_24.xml
│       │       │   ├── baseline_play_circle_24.xml
│       │       │   ├── baseline_search_24.xml
│       │       │   ├── baseline_zoom_out_map_24.xml
│       │       │   ├── custom_thumb.xml
│       │       │   ├── delete.xml
│       │       │   ├── down_arrow.xml
│       │       │   ├── edit.xml
│       │       │   ├── fill_screen.xml
│       │       │   ├── fit_screen.xml
│       │       │   ├── focus.xml
│       │       │   ├── focus_search.xml
│       │       │   ├── gradient_fill.xml
│       │       │   ├── gradient_fill_bottom.xml
│       │       │   ├── gradient_fill_text.xml
│       │       │   ├── ic_baseline_keyboard_backspace_24.xml
│       │       │   ├── ic_forward.xml
│       │       │   ├── ic_launcher_background.xml
│       │       │   ├── ic_menu.xml
│       │       │   ├── ic_rewind.xml
│       │       │   ├── ic_rotation.xml
│       │       │   ├── icon_play.xml
│       │       │   ├── image_view_round.xml
│       │       │   ├── more.xml
│       │       │   ├── netflix_audio_subtitles.xml
│       │       │   ├── netflix_brightness_four.xml
│       │       │   ├── netflix_brightness_one.xml
│       │       │   ├── netflix_brightness_three.xml
│       │       │   ├── netflix_brightness_two.xml
│       │       │   ├── netflix_lock_black.xml
│       │       │   ├── netflix_pause_button.xml
│       │       │   ├── netflix_speed.xml
│       │       │   ├── netflix_unlock.xml
│       │       │   ├── next_episode.xml
│       │       │   ├── play_ripple.xml
│       │       │   ├── player_controller_bg.xml
│       │       │   ├── properties.xml
│       │       │   ├── quality_24.xml
│       │       │   ├── radio_group_tab_bg.xml
│       │       │   ├── rectangle_box.xml
│       │       │   ├── rectangle_box_slim.xml
│       │       │   ├── selected_quality.xml
│       │       │   ├── selected_subtitle.xml
│       │       │   ├── share.xml
│       │       │   ├── share_link.xml
│       │       │   ├── tab_selector.xml
│       │       │   ├── tab_text_color_selector.xml
│       │       │   ├── volume_up_24.xml
│       │       │   └── white_round.xml
│       │       ├── drawable-v24/
│       │       │   └── ic_launcher_foreground.xml
│       │       ├── font/
│       │       │   ├── exo_2.xml
│       │       │   └── exo_2_thin.xml
│       │       ├── layout/
│       │       │   ├── activity_main.xml
│       │       │   ├── activity_movie_play.xml
│       │       │   ├── activity_video_play.xml
│       │       │   ├── card_view.xml
│       │       │   ├── custom_video_player2.xml
│       │       │   ├── dropdown_menu.xml
│       │       │   ├── episode_expanded_view.xml
│       │       │   ├── episode_item_viem.xml
│       │       │   ├── fragment_anime.xml
│       │       │   ├── fragment_anime_details.xml
│       │       │   ├── fragment_correct_title_selection.xml
│       │       │   ├── fragment_movies.xml
│       │       │   ├── fragment_search.xml
│       │       │   ├── fragment_tv_show.xml
│       │       │   ├── fragment_tv_show_details.xml
│       │       │   ├── item_view.xml
│       │       │   ├── search_item.xml
│       │       │   ├── sub_view.xml
│       │       │   ├── test.xml
│       │       │   └── track_item.xml
│       │       ├── menu/
│       │       │   └── bottom_nav.xml
│       │       ├── mipmap-anydpi-v26/
│       │       │   ├── ic_launcher.xml
│       │       │   └── ic_launcher_round.xml
│       │       ├── navigation/
│       │       │   └── nav_main.xml
│       │       ├── transition/
│       │       │   └── container_transform.xml
│       │       ├── values/
│       │       │   ├── colors.xml
│       │       │   ├── font_certs.xml
│       │       │   ├── preloaded_fonts.xml
│       │       │   ├── strings.xml
│       │       │   └── themes.xml
│       │       ├── values-night/
│       │       │   └── themes.xml
│       │       └── xml/
│       │           ├── backup_rules.xml
│       │           └── data_extraction_rules.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── demomiru/
│                       └── tokeiv2/
│                           └── ExampleUnitTest.kt
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
Condensed preview — 185 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (579K chars).
[
  {
    "path": ".gitignore",
    "chars": 225,
    "preview": "*.iml\n.gradle\n/local.properties\n/.idea/caches\n/.idea/libraries\n/.idea/modules.xml\n/.idea/workspace.xml\n/.idea/navEditor."
  },
  {
    "path": ".idea/.gitignore",
    "chars": 47,
    "preview": "# Default ignored files\n/shelf/\n/workspace.xml\n"
  },
  {
    "path": ".idea/compiler.xml",
    "chars": 169,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"CompilerConfiguration\">\n    <bytecodeTar"
  },
  {
    "path": ".idea/gradle.xml",
    "chars": 680,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"GradleMigrationSettings\" migrationVersio"
  },
  {
    "path": ".idea/kotlinc.xml",
    "chars": 175,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"KotlinJpsPluginSettings\">\n    <option na"
  },
  {
    "path": ".idea/misc.xml",
    "chars": 584,
    "preview": "<project version=\"4\">\n  <component name=\"ExternalStorageConfigurationManager\" enabled=\"true\" />\n  <component name=\"Proje"
  },
  {
    "path": ".idea/vcs.xml",
    "chars": 180,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping dire"
  },
  {
    "path": "README.md",
    "chars": 1800,
    "preview": "# Tokei    <img src=\"https://github.com/Sovan22/Tokeii/blob/master/app/tokei_logo.jpeg\" width=\"40\" height=\"40\" alt=\"Imag"
  },
  {
    "path": "app/.gitignore",
    "chars": 6,
    "preview": "/build"
  },
  {
    "path": "app/build.gradle",
    "chars": 4025,
    "preview": "\n\nplugins {\n    id 'com.android.application'\n    id 'org.jetbrains.kotlin.android'\n    id(\"androidx.navigation.safeargs."
  },
  {
    "path": "app/proguard-rules.pro",
    "chars": 750,
    "preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
  },
  {
    "path": "app/src/androidTest/java/com/demomiru/tokeiv2/ExampleInstrumentedTest.kt",
    "chars": 667,
    "preview": "package com.demomiru.tokeiv2\n\nimport androidx.test.platform.app.InstrumentationRegistry\nimport androidx.test.ext.junit.r"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "chars": 1713,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:to"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/EpisodeAdapter.kt",
    "chars": 1171,
    "preview": "package com.demomiru.tokeiv2\n\n\n\nimport android.annotation.SuppressLint\nimport android.view.LayoutInflater\nimport android"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/EpisodeAdapter2.kt",
    "chars": 3041,
    "preview": "package com.demomiru.tokeiv2\n\n\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGrou"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/MainActivity.kt",
    "chars": 10402,
    "preview": "package com.demomiru.tokeiv2\n\nimport android.annotation.SuppressLint\nimport android.app.AlertDialog\nimport android.conte"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/Movie.kt",
    "chars": 675,
    "preview": "package com.demomiru.tokeiv2\n\nimport java.io.Serializable\n\n\ndata class Movie(\n    val id : String,\n    val original_lang"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/MovieAdapter.kt",
    "chars": 4762,
    "preview": "package com.demomiru.tokeiv2\n\nimport android.annotation.SuppressLint\nimport android.view.LayoutInflater\nimport android.v"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/MoviePlayActivity.kt",
    "chars": 25617,
    "preview": "package com.demomiru.tokeiv2\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.conte"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/MovieService.kt",
    "chars": 1623,
    "preview": "package com.demomiru.tokeiv2\n\nimport retrofit2.Response\nimport retrofit2.http.GET\n\n\nimport retrofit2.http.Query\n\ninterfa"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/MoviesFragment.kt",
    "chars": 8931,
    "preview": "package com.demomiru.tokeiv2\n\n\n\nimport android.os.Bundle\nimport androidx.fragment.app.Fragment\nimport android.view.Layou"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/SearchFragment.kt",
    "chars": 21556,
    "preview": "@file:OptIn(DelicateCoroutinesApi::class)\n\npackage com.demomiru.tokeiv2\n\n\nimport android.content.Context\nimport android."
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/TMDBService.kt",
    "chars": 2770,
    "preview": "package com.demomiru.tokeiv2\n\nimport retrofit2.Response\nimport retrofit2.http.GET\nimport retrofit2.http.Path\nimport retr"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/TVShowAdapter.kt",
    "chars": 4834,
    "preview": "package com.demomiru.tokeiv2\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/TVShowCardAdapter.kt",
    "chars": 1440,
    "preview": "package com.demomiru.tokeiv2\n\n\nimport androidx.recyclerview.widget.RecyclerView\nimport android.view.LayoutInflater\nimpor"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/TVShowDetails.kt",
    "chars": 13553,
    "preview": "package com.demomiru.tokeiv2\n\nimport android.annotation.SuppressLint\nimport android.content.res.Configuration\n\nimport an"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/TVShowFragment.kt",
    "chars": 5199,
    "preview": "package com.demomiru.tokeiv2\n\nimport android.os.Bundle\n\nimport androidx.fragment.app.Fragment\nimport android.view.Layout"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/TVshow.kt",
    "chars": 152,
    "preview": "package com.demomiru.tokeiv2\n\ndata class TVshow(\n    val id: String,\n    val name: String,\n    val poster_path: String,\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/VideoPlayActivity.kt",
    "chars": 73703,
    "preview": "@file:Suppress(\"DEPRECATION\")\n@file:OptIn(DelicateCoroutinesApi::class)\n\npackage com.demomiru.tokeiv2\n\nimport androidx.a"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/anime/AnimeAdapter.kt",
    "chars": 3593,
    "preview": "package com.demomiru.tokeiv2.anime\n\nimport android.content.Context\nimport android.view.LayoutInflater\nimport android.vie"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/anime/AnimeDetailsFragment.kt",
    "chars": 8415,
    "preview": "package com.demomiru.tokeiv2.anime\n\nimport android.annotation.SuppressLint\nimport android.os.Bundle\nimport android.util."
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/anime/AnimeFragment.kt",
    "chars": 4976,
    "preview": "package com.demomiru.tokeiv2.anime\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/anime/AnimeInfo.kt",
    "chars": 6571,
    "preview": "package com.demomiru.tokeiv2.anime\n\nimport android.content.Context\nimport com.demomiru.tokeiv2.BuildConfig\nimport com.de"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/extractors/CorrectTitleSelection.kt",
    "chars": 5446,
    "preview": "package com.demomiru.tokeiv2.extractors\n\nimport android.annotation.SuppressLint\nimport android.app.Dialog\nimport android"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/extractors/PrMovies.kt",
    "chars": 2244,
    "preview": "package com.demomiru.tokeiv2.extractors\n\nimport android.os.Bundle\nimport androidx.appcompat.app.AppCompatActivity\nimport"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/extractors/Vidplay.kt",
    "chars": 7128,
    "preview": "package com.demomiru.tokeiv2.extractors\n\nimport androidx.lifecycle.lifecycleScope\nimport com.demomiru.tokeiv2.utils.Vide"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/history/QueryRepository.kt",
    "chars": 3402,
    "preview": "package com.demomiru.tokeiv2.history\n\nimport android.view.View\nimport android.widget.Toast\nimport androidx.annotation.Wo"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/history/SearchApp.kt",
    "chars": 173,
    "preview": "package com.demomiru.tokeiv2.history\n\nimport android.app.Application\n\nclass SearchApp : Application() {\n    val db by la"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/history/SearchDatabase.kt",
    "chars": 976,
    "preview": "package com.demomiru.tokeiv2.history\n\nimport android.content.Context\nimport androidx.room.Database\nimport androidx.room."
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/history/SearchHistory.kt",
    "chars": 393,
    "preview": "package com.demomiru.tokeiv2.history\n\nimport androidx.room.ColumnInfo\nimport androidx.room.Entity\nimport androidx.room.I"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/history/SearchHistoryAdapter.kt",
    "chars": 1457,
    "preview": "package com.demomiru.tokeiv2.history\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.Vi"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/history/SearchHistoryAdapter2.kt",
    "chars": 1824,
    "preview": "package com.demomiru.tokeiv2.history\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.Vi"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/history/SearchHistoryDao.kt",
    "chars": 778,
    "preview": "package com.demomiru.tokeiv2.history\n\nimport androidx.room.Dao\nimport androidx.room.Delete\nimport androidx.room.Insert\ni"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/subtitles/SubTrackAdapter.kt",
    "chars": 1822,
    "preview": "package com.demomiru.tokeiv2.subtitles\n\n\nimport android.annotation.SuppressLint\nimport android.view.LayoutInflater\nimpor"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/subtitles/Subtitles.kt",
    "chars": 303,
    "preview": "package com.demomiru.tokeiv2.subtitles\n\n\n\ndata class Subtitle(\n    val data: List<Sub>\n)\n\ndata class Sub(\n    val id : S"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/tracks/TrackAdapter.kt",
    "chars": 3651,
    "preview": "package com.demomiru.tokeiv2.tracks\n\nimport android.annotation.SuppressLint\nimport android.view.LayoutInflater\nimport an"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/DudeFilmsUtils.kt",
    "chars": 11389,
    "preview": "package com.demomiru.tokeiv2.utils\n\nimport android.util.Log\nimport com.demomiru.tokeiv2.BuildConfig\nimport com.demomiru."
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/Extractor.kt",
    "chars": 16094,
    "preview": "package com.demomiru.tokeiv2.utils\n\nimport JsUnpacker\nimport android.net.Uri\nimport androidx.media3.common.MimeTypes\nimp"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/GoMovies.kt",
    "chars": 10550,
    "preview": "package com.demomiru.tokeiv2.utils\n\nimport android.util.Base64\nimport com.demomiru.tokeiv2.BuildConfig\nimport com.google"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/GogoAnime.kt",
    "chars": 17553,
    "preview": "package com.demomiru.tokeiv2.utils\n\nimport android.annotation.SuppressLint\nimport android.os.Parcel\nimport android.os.Pa"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/OpenSubtitle.kt",
    "chars": 7914,
    "preview": "package com.demomiru.tokeiv2.utils\n\nimport android.content.Context\nimport android.net.Uri\nimport android.view.LayoutInfl"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/SmashyStream.kt",
    "chars": 3220,
    "preview": "package com.demomiru.tokeiv2.utils\n\n\nimport android.icu.text.CaseMap.Title\nimport com.demomiru.tokeiv2.BuildConfig\nimpor"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/SuperstreamUtils.kt",
    "chars": 24509,
    "preview": "package com.demomiru.tokeiv2.utils\n\n\nimport android.util.Base64\n\nimport com.demomiru.tokeiv2.utils.SuperstreamUtils.Ciph"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/VidSrc.kt",
    "chars": 3526,
    "preview": "package com.demomiru.tokeiv2.utils\n\nimport com.google.gson.Gson\nimport com.lagradost.nicehttp.Requests\nimport org.checke"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/VidSrcUtils.kt",
    "chars": 5884,
    "preview": "package com.demomiru.tokeiv2.utils\n\nimport android.os.Handler\nimport android.os.Looper\nimport android.os.SystemClock\nimp"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/ViewModelsTokei.kt",
    "chars": 8705,
    "preview": "@file:Suppress(\"UNCHECKED_CAST\")\n\npackage com.demomiru.tokeiv2.utils\n\nimport android.content.Context\nimport android.net."
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/colors.txt",
    "chars": 936,
    "preview": "All hex value from 100% to 0% alpha\n\n100% — FF\n99% — FC\n98% — FA\n97% — F7\n96% — F5\n95% — F2\n94% — F0\n93% — ED\n92% — EB\n9"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/retrofitBuilder.kt",
    "chars": 9155,
    "preview": "package com.demomiru.tokeiv2.utils\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/watching/ContinueWatching.kt",
    "chars": 5188,
    "preview": "package com.demomiru.tokeiv2.watching\n\nimport android.net.Uri\nimport android.os.Parcel\nimport android.os.Parcelable\nimpo"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/watching/ContinueWatchingAdapter.kt",
    "chars": 3353,
    "preview": "package com.demomiru.tokeiv2.watching\n\nimport android.annotation.SuppressLint\n\nimport android.os.Handler\nimport android."
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/watching/ContinueWatchingDao.kt",
    "chars": 943,
    "preview": "package com.demomiru.tokeiv2.watching\n\nimport androidx.lifecycle.LiveData\nimport androidx.room.Dao\nimport androidx.room."
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/watching/ContinueWatchingDatabase.kt",
    "chars": 1680,
    "preview": "package com.demomiru.tokeiv2.watching\n\nimport android.content.Context\nimport androidx.room.Database\nimport androidx.room"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/watching/ContinueWatchingRepository.kt",
    "chars": 1069,
    "preview": "package com.demomiru.tokeiv2.watching\n\nimport androidx.annotation.WorkerThread\nimport androidx.lifecycle.LiveData\nimport"
  },
  {
    "path": "app/src/main/res/anim/enter_anim.xml",
    "chars": 689,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <scale\n     "
  },
  {
    "path": "app/src/main/res/anim/enter_from_bottom.xml",
    "chars": 224,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <translate\n "
  },
  {
    "path": "app/src/main/res/anim/exit_anim.xml",
    "chars": 689,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <scale\n     "
  },
  {
    "path": "app/src/main/res/anim/exit_to_top.xml",
    "chars": 224,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <translate\n "
  },
  {
    "path": "app/src/main/res/anim/go_left.xml",
    "chars": 322,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n     android:inte"
  },
  {
    "path": "app/src/main/res/anim/go_right.xml",
    "chars": 321,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n     android:inte"
  },
  {
    "path": "app/src/main/res/anim/layout_animation.xml",
    "chars": 226,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layoutAnimation\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n "
  },
  {
    "path": "app/src/main/res/anim/nav_enter_anim.xml",
    "chars": 321,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <alpha\n     "
  },
  {
    "path": "app/src/main/res/anim/nav_exit_anim.xml",
    "chars": 321,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <alpha\n     "
  },
  {
    "path": "app/src/main/res/anim/nav_pop_enter.xml",
    "chars": 321,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <alpha\n     "
  },
  {
    "path": "app/src/main/res/anim/nav_pop_exit.xml",
    "chars": 321,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <alpha\n     "
  },
  {
    "path": "app/src/main/res/anim/pop_enter.xml",
    "chars": 689,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <scale\n     "
  },
  {
    "path": "app/src/main/res/anim/pop_exit.xml",
    "chars": 689,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <scale\n     "
  },
  {
    "path": "app/src/main/res/anim/rotate_around_center_point.xml",
    "chars": 428,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:share"
  },
  {
    "path": "app/src/main/res/anim/rotate_left.xml",
    "chars": 1015,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set\n        xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        a"
  },
  {
    "path": "app/src/main/res/anim/rotate_right.xml",
    "chars": 1015,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set\n        xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        a"
  },
  {
    "path": "app/src/main/res/anim/slide_from_uo.xml",
    "chars": 223,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <translate\n "
  },
  {
    "path": "app/src/main/res/anim/slide_in.xml",
    "chars": 223,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <translate\n "
  },
  {
    "path": "app/src/main/res/anim/slide_in_right.xml",
    "chars": 222,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <translate\n "
  },
  {
    "path": "app/src/main/res/anim/slide_out.xml",
    "chars": 224,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <translate\n"
  },
  {
    "path": "app/src/main/res/drawable/anime_bottom_nav.xml",
    "chars": 623,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\" android:height"
  },
  {
    "path": "app/src/main/res/drawable/background_search_history.xml",
    "chars": 228,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:sha"
  },
  {
    "path": "app/src/main/res/drawable/background_text.xml",
    "chars": 191,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:sha"
  },
  {
    "path": "app/src/main/res/drawable/baseline_cancel_24.xml",
    "chars": 458,
    "preview": "<vector android:height=\"24dp\" android:tint=\"#D51616\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    andr"
  },
  {
    "path": "app/src/main/res/drawable/baseline_double_arrow_24.xml",
    "chars": 422,
    "preview": "<vector android:height=\"24dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    andr"
  },
  {
    "path": "app/src/main/res/drawable/baseline_history_24.xml",
    "chars": 543,
    "preview": "<vector android:height=\"24dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    andr"
  },
  {
    "path": "app/src/main/res/drawable/baseline_keyboard_arrow_down_24.xml",
    "chars": 344,
    "preview": "<vector android:height=\"24dp\" android:tint=\"@color/white\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n   "
  },
  {
    "path": "app/src/main/res/drawable/baseline_keyboard_arrow_up_24.xml",
    "chars": 333,
    "preview": "<vector android:height=\"24dp\" android:tint=\"@color/white\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n   "
  },
  {
    "path": "app/src/main/res/drawable/baseline_lock_open_24.xml",
    "chars": 559,
    "preview": "<vector android:height=\"48dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    andr"
  },
  {
    "path": "app/src/main/res/drawable/baseline_play_arrow_24.xml",
    "chars": 294,
    "preview": "<vector android:height=\"40dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    andr"
  },
  {
    "path": "app/src/main/res/drawable/baseline_play_circle_24.xml",
    "chars": 353,
    "preview": "<vector android:height=\"24dp\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:"
  },
  {
    "path": "app/src/main/res/drawable/baseline_search_24.xml",
    "chars": 528,
    "preview": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    andr"
  },
  {
    "path": "app/src/main/res/drawable/baseline_zoom_out_map_24.xml",
    "chars": 502,
    "preview": "<vector android:height=\"24dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    andr"
  },
  {
    "path": "app/src/main/res/drawable/custom_thumb.xml",
    "chars": 346,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <ite"
  },
  {
    "path": "app/src/main/res/drawable/delete.xml",
    "chars": 1280,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/down_arrow.xml",
    "chars": 339,
    "preview": "<vector android:height=\"48dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    andr"
  },
  {
    "path": "app/src/main/res/drawable/edit.xml",
    "chars": 1348,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/fill_screen.xml",
    "chars": 447,
    "preview": "<vector android:alpha=\"0.9\" android:height=\"40dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewpor"
  },
  {
    "path": "app/src/main/res/drawable/fit_screen.xml",
    "chars": 487,
    "preview": "<vector android:alpha=\"0.9\" android:height=\"40dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewpor"
  },
  {
    "path": "app/src/main/res/drawable/focus.xml",
    "chars": 451,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item a"
  },
  {
    "path": "app/src/main/res/drawable/focus_search.xml",
    "chars": 438,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item a"
  },
  {
    "path": "app/src/main/res/drawable/gradient_fill.xml",
    "chars": 338,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\" android:shape=\""
  },
  {
    "path": "app/src/main/res/drawable/gradient_fill_bottom.xml",
    "chars": 338,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\" android:shape=\""
  },
  {
    "path": "app/src/main/res/drawable/gradient_fill_text.xml",
    "chars": 340,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\" android:shape=\""
  },
  {
    "path": "app/src/main/res/drawable/ic_baseline_keyboard_backspace_24.xml",
    "chars": 338,
    "preview": "<vector android:height=\"24dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    andr"
  },
  {
    "path": "app/src/main/res/drawable/ic_forward.xml",
    "chars": 954,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"90dp\"\n    android:height=\"90dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_launcher_background.xml",
    "chars": 5606,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:wi"
  },
  {
    "path": "app/src/main/res/drawable/ic_menu.xml",
    "chars": 337,
    "preview": "<vector android:height=\"24dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    andr"
  },
  {
    "path": "app/src/main/res/drawable/ic_rewind.xml",
    "chars": 989,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"90dp\"\n    android:height=\"90dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_rotation.xml",
    "chars": 751,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"30dp\"\n    android:height=\"30dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/icon_play.xml",
    "chars": 314,
    "preview": "<vector android:alpha=\"0.9\" android:height=\"40dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewpor"
  },
  {
    "path": "app/src/main/res/drawable/image_view_round.xml",
    "chars": 276,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:sha"
  },
  {
    "path": "app/src/main/res/drawable/more.xml",
    "chars": 493,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/netflix_audio_subtitles.xml",
    "chars": 374,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"35dp\"\n    android:height=\"35dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/netflix_brightness_four.xml",
    "chars": 1827,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"30dp\"\n    android:height=\"30dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/netflix_brightness_one.xml",
    "chars": 2145,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"30dp\"\n    android:height=\"30dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/netflix_brightness_three.xml",
    "chars": 1422,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"30dp\"\n    android:height=\"30dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/netflix_brightness_two.xml",
    "chars": 1042,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"30dp\"\n    android:height=\"30dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/netflix_lock_black.xml",
    "chars": 985,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"20dp\"\n    android:height=\"20dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/netflix_pause_button.xml",
    "chars": 311,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"40dp\"\n    android:height=\"40dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/netflix_speed.xml",
    "chars": 1984,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"30dp\"\n    android:height=\"30dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/netflix_unlock.xml",
    "chars": 1157,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"30dp\"\n    android:height=\"30dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/next_episode.xml",
    "chars": 316,
    "preview": "<vector android:height=\"40dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    andr"
  },
  {
    "path": "app/src/main/res/drawable/play_ripple.xml",
    "chars": 540,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n        <i"
  },
  {
    "path": "app/src/main/res/drawable/player_controller_bg.xml",
    "chars": 803,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item"
  },
  {
    "path": "app/src/main/res/drawable/properties.xml",
    "chars": 413,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/quality_24.xml",
    "chars": 578,
    "preview": "<vector android:height=\"24dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    andr"
  },
  {
    "path": "app/src/main/res/drawable/radio_group_tab_bg.xml",
    "chars": 310,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:sha"
  },
  {
    "path": "app/src/main/res/drawable/rectangle_box.xml",
    "chars": 304,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\" android:shape=\""
  },
  {
    "path": "app/src/main/res/drawable/rectangle_box_slim.xml",
    "chars": 303,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\" android:shape=\""
  },
  {
    "path": "app/src/main/res/drawable/selected_quality.xml",
    "chars": 293,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:sha"
  },
  {
    "path": "app/src/main/res/drawable/selected_subtitle.xml",
    "chars": 350,
    "preview": "<vector android:alpha=\"0.9\" android:height=\"24dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewpor"
  },
  {
    "path": "app/src/main/res/drawable/share.xml",
    "chars": 740,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/share_link.xml",
    "chars": 552,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"48dp\"\n    android:height=\"48dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/tab_selector.xml",
    "chars": 1001,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item a"
  },
  {
    "path": "app/src/main/res/drawable/tab_text_color_selector.xml",
    "chars": 257,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item "
  },
  {
    "path": "app/src/main/res/drawable/volume_up_24.xml",
    "chars": 544,
    "preview": "<vector android:alpha=\"0.9\" android:autoMirrored=\"true\"\n    android:height=\"24dp\" android:tint=\"#FFFFFF\"\n    android:vie"
  },
  {
    "path": "app/src/main/res/drawable/white_round.xml",
    "chars": 195,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <solid an"
  },
  {
    "path": "app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "chars": 1702,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    "
  },
  {
    "path": "app/src/main/res/font/exo_2.xml",
    "chars": 354,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<font-family xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n        app:font"
  },
  {
    "path": "app/src/main/res/font/exo_2_thin.xml",
    "chars": 374,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<font-family xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n        app:font"
  },
  {
    "path": "app/src/main/res/layout/activity_main.xml",
    "chars": 6362,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<androidx.coordinatorlayout.widget.CoordinatorLayout\n    xmlns:android=\"http://s"
  },
  {
    "path": "app/src/main/res/layout/activity_movie_play.xml",
    "chars": 1390,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    an"
  },
  {
    "path": "app/src/main/res/layout/activity_video_play.xml",
    "chars": 11709,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "app/src/main/res/layout/card_view.xml",
    "chars": 2250,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.cardview.widget.CardView xmlns:android=\"http://schemas.android.com/apk/"
  },
  {
    "path": "app/src/main/res/layout/custom_video_player2.xml",
    "chars": 18083,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout\n    xmlns:android=\"http://sche"
  },
  {
    "path": "app/src/main/res/layout/dropdown_menu.xml",
    "chars": 766,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "app/src/main/res/layout/episode_expanded_view.xml",
    "chars": 4350,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout\n    android:layout_height=\"wrap_content\"\n    android:layout_width=\"m"
  },
  {
    "path": "app/src/main/res/layout/episode_item_viem.xml",
    "chars": 1306,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "app/src/main/res/layout/fragment_anime.xml",
    "chars": 4319,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
  },
  {
    "path": "app/src/main/res/layout/fragment_anime_details.xml",
    "chars": 7437,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout\n    xmlns:android=\"http://sche"
  },
  {
    "path": "app/src/main/res/layout/fragment_correct_title_selection.xml",
    "chars": 315,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns"
  },
  {
    "path": "app/src/main/res/layout/fragment_movies.xml",
    "chars": 3518,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout\n    xmlns:android=\"http://sche"
  },
  {
    "path": "app/src/main/res/layout/fragment_search.xml",
    "chars": 5916,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "app/src/main/res/layout/fragment_tv_show.xml",
    "chars": 3538,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas."
  },
  {
    "path": "app/src/main/res/layout/fragment_tv_show_details.xml",
    "chars": 6547,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout\n    xmlns:android=\"http://sche"
  },
  {
    "path": "app/src/main/res/layout/item_view.xml",
    "chars": 3035,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    x"
  },
  {
    "path": "app/src/main/res/layout/search_item.xml",
    "chars": 1638,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "app/src/main/res/layout/sub_view.xml",
    "chars": 811,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "app/src/main/res/layout/test.xml",
    "chars": 4943,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout\n    android:layout_height=\"wra"
  },
  {
    "path": "app/src/main/res/layout/track_item.xml",
    "chars": 716,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "app/src/main/res/menu/bottom_nav.xml",
    "chars": 628,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n\n    <item and"
  },
  {
    "path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "chars": 328,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <bac"
  },
  {
    "path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "chars": 343,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <b"
  },
  {
    "path": "app/src/main/res/navigation/nav_main.xml",
    "chars": 5643,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<navigation xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:"
  },
  {
    "path": "app/src/main/res/transition/container_transform.xml",
    "chars": 333,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<transitionSet xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    and"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "chars": 316,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"black\">#FF000000</color>\n    <color name=\"white\">#FF"
  },
  {
    "path": "app/src/main/res/values/font_certs.xml",
    "chars": 3581,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <array name=\"com_google_android_gms_fonts_certs\">\n        <item>@"
  },
  {
    "path": "app/src/main/res/values/preloaded_fonts.xml",
    "chars": 204,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <array name=\"preloaded_fonts\" translatable=\"false\">\n        <item"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "chars": 863,
    "preview": "<resources>\n    <string name=\"app_name\">Tokei</string>\n    <string name=\"movies\">Movies</string>\n    <string name=\"trend"
  },
  {
    "path": "app/src/main/res/values/themes.xml",
    "chars": 927,
    "preview": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <!-- Base application theme. -->\n    <style name=\"Base.Th"
  },
  {
    "path": "app/src/main/res/values-night/themes.xml",
    "chars": 327,
    "preview": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <!-- Base application theme. -->\n    <style name=\"Base.Th"
  },
  {
    "path": "app/src/main/res/xml/backup_rules.xml",
    "chars": 478,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n   Sample backup rules file; uncomment and customize as necessary.\n   See htt"
  },
  {
    "path": "app/src/main/res/xml/data_extraction_rules.xml",
    "chars": 551,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n   Sample data extraction rules file; uncomment and customize as necessary.\n "
  },
  {
    "path": "app/src/test/java/com/demomiru/tokeiv2/ExampleUnitTest.kt",
    "chars": 344,
    "preview": "package com.demomiru.tokeiv2\n\nimport org.junit.Test\n\nimport org.junit.Assert.*\n\n/**\n * Example local unit test, which wi"
  },
  {
    "path": "build.gradle",
    "chars": 534,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\n\nbuildscript {\n    "
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 230,
    "preview": "#Sat Aug 26 21:19:31 IST 2023\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://"
  },
  {
    "path": "gradle.properties",
    "chars": 1358,
    "preview": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will ov"
  },
  {
    "path": "gradlew",
    "chars": 5766,
    "preview": "#!/usr/bin/env sh\n\n#\n# Copyright 2015 the original author or authors.\n#\n# Licensed under the Apache License, Version 2.0"
  },
  {
    "path": "gradlew.bat",
    "chars": 2674,
    "preview": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "settings.gradle",
    "chars": 386,
    "preview": "pluginManagement {\n    repositories {\n        google()\n        mavenCentral()\n        gradlePluginPortal()\n    }\n}\ndepen"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the Sovan22/Tokeii GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 185 files (528.8 KB), approximately 132.6k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!