diff --git a/settings.gradle b/settings.gradle
index a677f30b..e7b4def4 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,2 +1 @@
include ':app'
-include ':tv'
diff --git a/tv/.gitignore b/tv/.gitignore
deleted file mode 100644
index 42afabfd..00000000
--- a/tv/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build
\ No newline at end of file
diff --git a/tv/build.gradle b/tv/build.gradle
deleted file mode 100644
index 7df71998..00000000
--- a/tv/build.gradle
+++ /dev/null
@@ -1,34 +0,0 @@
-plugins {
- id 'com.android.application'
- id 'kotlin-android'
-}
-
-android {
- compileSdk 32
-
- defaultConfig {
- applicationId "com.metabrainz.android"
- minSdk 21
- targetSdk 32
- versionCode 1
- versionName "1.0"
- }
-
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
- }
- }
-
- lintOptions{
- abortOnError false
- }
-}
-
-dependencies {
- implementation 'androidx.core:core-ktx:1.7.0'
- implementation 'androidx.leanback:leanback:1.0.0'
- implementation 'androidx.appcompat:appcompat:1.4.0'
- implementation 'com.github.bumptech.glide:glide:4.12.0'
-}
\ No newline at end of file
diff --git a/tv/proguard-rules.pro b/tv/proguard-rules.pro
deleted file mode 100644
index 481bb434..00000000
--- a/tv/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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
\ No newline at end of file
diff --git a/tv/src/main/AndroidManifest.xml b/tv/src/main/AndroidManifest.xml
deleted file mode 100644
index ac8fc37e..00000000
--- a/tv/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/tv/src/main/ic_launcher-playstore.png b/tv/src/main/ic_launcher-playstore.png
deleted file mode 100644
index f9a6a9c0..00000000
Binary files a/tv/src/main/ic_launcher-playstore.png and /dev/null differ
diff --git a/tv/src/main/java/com/metabrainz/android/BrowseErrorActivity.kt b/tv/src/main/java/com/metabrainz/android/BrowseErrorActivity.kt
deleted file mode 100644
index d6caf868..00000000
--- a/tv/src/main/java/com/metabrainz/android/BrowseErrorActivity.kt
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.metabrainz.android
-
-import android.os.Bundle
-import android.os.Handler
-import android.view.Gravity
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.FrameLayout
-import android.widget.ProgressBar
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentActivity
-
-/**
- * BrowseErrorActivity shows how to use ErrorFragment.
- */
-class BrowseErrorActivity : FragmentActivity() {
-
- private lateinit var mErrorFragment: ErrorFragment
- private lateinit var mSpinnerFragment: SpinnerFragment
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- if (savedInstanceState == null) {
- getSupportFragmentManager().beginTransaction()
- .replace(R.id.main_browse_fragment, MainFragment())
- .commitNow()
- }
- testError()
- }
-
- private fun testError() {
- mErrorFragment = ErrorFragment()
- supportFragmentManager
- .beginTransaction()
- .add(R.id.main_browse_fragment, mErrorFragment)
- .commit()
-
- mSpinnerFragment = SpinnerFragment()
- supportFragmentManager
- .beginTransaction()
- .add(R.id.main_browse_fragment, mSpinnerFragment)
- .commit()
-
- val handler = Handler()
- handler.postDelayed({
- supportFragmentManager
- .beginTransaction()
- .remove(mSpinnerFragment)
- .commit()
- mErrorFragment.setErrorContent()
- }, TIMER_DELAY)
- }
-
- class SpinnerFragment : Fragment() {
- override fun onCreateView(
- inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?,
- ): View? {
- val progressBar = ProgressBar(container?.context)
- if (container is FrameLayout) {
- val layoutParams =
- FrameLayout.LayoutParams(SPINNER_WIDTH, SPINNER_HEIGHT, Gravity.CENTER)
- progressBar.layoutParams = layoutParams
- }
- return progressBar
- }
- }
-
- companion object {
- private val TIMER_DELAY = 3000L
- private val SPINNER_WIDTH = 100
- private val SPINNER_HEIGHT = 100
- }
-}
\ No newline at end of file
diff --git a/tv/src/main/java/com/metabrainz/android/CardPresenter.kt b/tv/src/main/java/com/metabrainz/android/CardPresenter.kt
deleted file mode 100644
index 212c4651..00000000
--- a/tv/src/main/java/com/metabrainz/android/CardPresenter.kt
+++ /dev/null
@@ -1,82 +0,0 @@
-package com.metabrainz.android
-
-import android.graphics.drawable.Drawable
-import androidx.leanback.widget.ImageCardView
-import androidx.leanback.widget.Presenter
-import androidx.core.content.ContextCompat
-import android.util.Log
-import android.view.ViewGroup
-
-import com.bumptech.glide.Glide
-import kotlin.properties.Delegates
-
-/**
- * A CardPresenter is used to generate Views and bind Objects to them on demand.
- * It contains an ImageCardView.
- */
-class CardPresenter : Presenter() {
- private var mDefaultCardImage: Drawable? = null
- private var sSelectedBackgroundColor: Int by Delegates.notNull()
- private var sDefaultBackgroundColor: Int by Delegates.notNull()
-
- override fun onCreateViewHolder(parent: ViewGroup): Presenter.ViewHolder {
- Log.d(TAG, "onCreateViewHolder")
-
- sDefaultBackgroundColor = ContextCompat.getColor(parent.context, R.color.default_background)
- sSelectedBackgroundColor =
- ContextCompat.getColor(parent.context, R.color.selected_background)
- mDefaultCardImage = ContextCompat.getDrawable(parent.context, R.drawable.movie)
-
- val cardView = object : ImageCardView(parent.context) {
- override fun setSelected(selected: Boolean) {
- updateCardBackgroundColor(this, selected)
- super.setSelected(selected)
- }
- }
-
- cardView.isFocusable = true
- cardView.isFocusableInTouchMode = true
- updateCardBackgroundColor(cardView, false)
- return Presenter.ViewHolder(cardView)
- }
-
- override fun onBindViewHolder(viewHolder: Presenter.ViewHolder, item: Any) {
- val movie = item as Movie
- val cardView = viewHolder.view as ImageCardView
-
- Log.d(TAG, "onBindViewHolder")
- if (movie.cardImageUrl != null) {
- cardView.titleText = movie.title
- cardView.contentText = movie.studio
- cardView.setMainImageDimensions(CARD_WIDTH, CARD_HEIGHT)
- Glide.with(viewHolder.view.context)
- .load(movie.cardImageUrl)
- .centerCrop()
- .error(mDefaultCardImage)
- .into(cardView.mainImageView)
- }
- }
-
- override fun onUnbindViewHolder(viewHolder: Presenter.ViewHolder) {
- Log.d(TAG, "onUnbindViewHolder")
- val cardView = viewHolder.view as ImageCardView
- // Remove references to images so that the garbage collector can free up memory
- cardView.badgeImage = null
- cardView.mainImage = null
- }
-
- private fun updateCardBackgroundColor(view: ImageCardView, selected: Boolean) {
- val color = if (selected) sSelectedBackgroundColor else sDefaultBackgroundColor
- // Both background colors should be set because the view"s background is temporarily visible
- // during animations.
- view.setBackgroundColor(color)
- view.setInfoAreaBackgroundColor(color)
- }
-
- companion object {
- private val TAG = "CardPresenter"
-
- private val CARD_WIDTH = 313
- private val CARD_HEIGHT = 176
- }
-}
\ No newline at end of file
diff --git a/tv/src/main/java/com/metabrainz/android/DetailsActivity.kt b/tv/src/main/java/com/metabrainz/android/DetailsActivity.kt
deleted file mode 100644
index ea0e2b64..00000000
--- a/tv/src/main/java/com/metabrainz/android/DetailsActivity.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.metabrainz.android
-
-import android.os.Bundle
-import androidx.fragment.app.FragmentActivity
-
-/**
- * Details activity class that loads [VideoDetailsFragment] class.
- */
-class DetailsActivity : FragmentActivity() {
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_details)
- if (savedInstanceState == null) {
- supportFragmentManager.beginTransaction()
- .replace(R.id.details_fragment, VideoDetailsFragment())
- .commitNow()
- }
- }
-
- companion object {
- const val SHARED_ELEMENT_NAME = "hero"
- const val MOVIE = "Movie"
- }
-}
\ No newline at end of file
diff --git a/tv/src/main/java/com/metabrainz/android/DetailsDescriptionPresenter.kt b/tv/src/main/java/com/metabrainz/android/DetailsDescriptionPresenter.kt
deleted file mode 100644
index 721a122b..00000000
--- a/tv/src/main/java/com/metabrainz/android/DetailsDescriptionPresenter.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.metabrainz.android
-
-import androidx.leanback.widget.AbstractDetailsDescriptionPresenter
-
-class DetailsDescriptionPresenter : AbstractDetailsDescriptionPresenter() {
-
- override fun onBindDescription(
- viewHolder: AbstractDetailsDescriptionPresenter.ViewHolder,
- item: Any,
- ) {
- val movie = item as Movie
-
- viewHolder.title.text = movie.title
- viewHolder.subtitle.text = movie.studio
- viewHolder.body.text = movie.description
- }
-}
\ No newline at end of file
diff --git a/tv/src/main/java/com/metabrainz/android/ErrorFragment.kt b/tv/src/main/java/com/metabrainz/android/ErrorFragment.kt
deleted file mode 100644
index 0e3a478a..00000000
--- a/tv/src/main/java/com/metabrainz/android/ErrorFragment.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.metabrainz.android
-
-import android.os.Bundle
-import android.view.View
-
-import androidx.core.content.ContextCompat
-import androidx.leanback.app.ErrorSupportFragment
-
-/**
- * This class demonstrates how to extend [ErrorSupportFragment].
- */
-class ErrorFragment : ErrorSupportFragment() {
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- title = resources.getString(R.string.app_name)
- }
-
- internal fun setErrorContent() {
- imageDrawable =
- ContextCompat.getDrawable(requireActivity(), androidx.leanback.R.drawable.lb_ic_sad_cloud)
- message = resources.getString(R.string.error_fragment_message)
- setDefaultBackground(TRANSLUCENT)
-
- buttonText = resources.getString(R.string.dismiss_error)
- buttonClickListener = View.OnClickListener {
- requireFragmentManager().beginTransaction().remove(this@ErrorFragment).commit()
- }
- }
-
- companion object {
- private val TRANSLUCENT = true
- }
-}
\ No newline at end of file
diff --git a/tv/src/main/java/com/metabrainz/android/MainActivity.kt b/tv/src/main/java/com/metabrainz/android/MainActivity.kt
deleted file mode 100644
index 6735ba6c..00000000
--- a/tv/src/main/java/com/metabrainz/android/MainActivity.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.metabrainz.android
-
-import android.os.Bundle
-import androidx.fragment.app.FragmentActivity
-
-/**
- * Loads [MainFragment].
- */
-class MainActivity : FragmentActivity() {
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- if (savedInstanceState == null) {
- supportFragmentManager.beginTransaction()
- .replace(R.id.main_browse_fragment, MainFragment())
- .commitNow()
- }
- }
-}
\ No newline at end of file
diff --git a/tv/src/main/java/com/metabrainz/android/MainFragment.kt b/tv/src/main/java/com/metabrainz/android/MainFragment.kt
deleted file mode 100644
index f71cb92e..00000000
--- a/tv/src/main/java/com/metabrainz/android/MainFragment.kt
+++ /dev/null
@@ -1,231 +0,0 @@
-package com.metabrainz.android
-
-import java.util.Collections
-import java.util.Timer
-import java.util.TimerTask
-
-import android.content.Intent
-import android.graphics.Color
-import android.graphics.drawable.Drawable
-import android.os.Bundle
-import android.os.Handler
-import androidx.leanback.app.BackgroundManager
-import androidx.leanback.app.BrowseSupportFragment
-import androidx.leanback.widget.ArrayObjectAdapter
-import androidx.leanback.widget.HeaderItem
-import androidx.leanback.widget.ImageCardView
-import androidx.leanback.widget.ListRow
-import androidx.leanback.widget.ListRowPresenter
-import androidx.leanback.widget.OnItemViewClickedListener
-import androidx.leanback.widget.OnItemViewSelectedListener
-import androidx.leanback.widget.Presenter
-import androidx.leanback.widget.Row
-import androidx.leanback.widget.RowPresenter
-import androidx.core.app.ActivityOptionsCompat
-import androidx.core.content.ContextCompat
-import android.util.DisplayMetrics
-import android.util.Log
-import android.view.Gravity
-import android.view.ViewGroup
-import android.widget.TextView
-import android.widget.Toast
-
-import com.bumptech.glide.Glide
-import com.bumptech.glide.request.target.SimpleTarget
-import com.bumptech.glide.request.transition.Transition
-
-/**
- * Loads a grid of cards with movies to browse.
- */
-class MainFragment : BrowseSupportFragment() {
-
- private val mHandler = Handler()
- private lateinit var mBackgroundManager: BackgroundManager
- private var mDefaultBackground: Drawable? = null
- private lateinit var mMetrics: DisplayMetrics
- private var mBackgroundTimer: Timer? = null
- private var mBackgroundUri: String? = null
-
- override fun onActivityCreated(savedInstanceState: Bundle?) {
- Log.i(TAG, "onCreate")
- super.onActivityCreated(savedInstanceState)
-
- prepareBackgroundManager()
-
- setupUIElements()
-
- loadRows()
-
- setupEventListeners()
- }
-
- override fun onDestroy() {
- super.onDestroy()
- Log.d(TAG, "onDestroy: " + mBackgroundTimer?.toString())
- mBackgroundTimer?.cancel()
- }
-
- private fun prepareBackgroundManager() {
-
- mBackgroundManager = BackgroundManager.getInstance(activity)
- mBackgroundManager.attach(requireActivity().window)
- mDefaultBackground = ContextCompat.getDrawable(requireActivity(), R.drawable.default_background)
- mMetrics = DisplayMetrics()
- requireActivity().windowManager.defaultDisplay.getMetrics(mMetrics)
- }
-
- private fun setupUIElements() {
- title = getString(R.string.browse_title)
- // over title
- headersState = BrowseSupportFragment.HEADERS_ENABLED
- isHeadersTransitionOnBackEnabled = true
-
- // set fastLane (or headers) background color
- brandColor = ContextCompat.getColor(requireActivity(), R.color.fastlane_background)
- // set search icon color
- searchAffordanceColor = ContextCompat.getColor(requireActivity(), R.color.search_opaque)
- }
-
- private fun loadRows() {
- val list = MovieList.list
-
- val rowsAdapter = ArrayObjectAdapter(ListRowPresenter())
- val cardPresenter = CardPresenter()
-
- for (i in 0 until NUM_ROWS) {
- if (i != 0) {
- Collections.shuffle(list)
- }
- val listRowAdapter = ArrayObjectAdapter(cardPresenter)
- for (j in 0 until NUM_COLS) {
- listRowAdapter.add(list[j % 5])
- }
- val header = HeaderItem(i.toLong(), MovieList.MOVIE_CATEGORY[i])
- rowsAdapter.add(ListRow(header, listRowAdapter))
- }
-
- val gridHeader = HeaderItem(NUM_ROWS.toLong(), "PREFERENCES")
-
- val mGridPresenter = GridItemPresenter()
- val gridRowAdapter = ArrayObjectAdapter(mGridPresenter)
- gridRowAdapter.add(resources.getString(R.string.grid_view))
- gridRowAdapter.add(getString(R.string.error_fragment))
- gridRowAdapter.add(resources.getString(R.string.personal_settings))
- rowsAdapter.add(ListRow(gridHeader, gridRowAdapter))
-
- adapter = rowsAdapter
- }
-
- private fun setupEventListeners() {
- setOnSearchClickedListener {
- Toast.makeText(requireActivity(), "Implement your own in-app search", Toast.LENGTH_LONG)
- .show()
- }
-
- onItemViewClickedListener = ItemViewClickedListener()
- onItemViewSelectedListener = ItemViewSelectedListener()
- }
-
- private inner class ItemViewClickedListener : OnItemViewClickedListener {
- override fun onItemClicked(
- itemViewHolder: Presenter.ViewHolder,
- item: Any,
- rowViewHolder: RowPresenter.ViewHolder,
- row: Row,
- ) {
-
- if (item is Movie) {
- Log.d(TAG, "Item: " + item.toString())
- val intent = Intent(requireActivity(), DetailsActivity::class.java)
- intent.putExtra(DetailsActivity.MOVIE, item)
-
- val bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
- requireActivity(),
- (itemViewHolder.view as ImageCardView).mainImageView,
- DetailsActivity.SHARED_ELEMENT_NAME)
- .toBundle()
- startActivity(intent, bundle)
- } else if (item is String) {
- if (item.contains(getString(R.string.error_fragment))) {
- val intent = Intent(requireActivity(), BrowseErrorActivity::class.java)
- startActivity(intent)
- } else {
- Toast.makeText(requireActivity(), item, Toast.LENGTH_SHORT).show()
- }
- }
- }
- }
-
- private inner class ItemViewSelectedListener : OnItemViewSelectedListener {
- override fun onItemSelected(
- itemViewHolder: Presenter.ViewHolder?, item: Any?,
- rowViewHolder: RowPresenter.ViewHolder, row: Row,
- ) {
- if (item is Movie) {
- mBackgroundUri = item.backgroundImageUrl
- startBackgroundTimer()
- }
- }
- }
-
- private fun updateBackground(uri: String?) {
- val width = mMetrics.widthPixels
- val height = mMetrics.heightPixels
- Glide.with(requireActivity())
- .load(uri)
- .centerCrop()
- .error(mDefaultBackground)
- .into>(
- object : SimpleTarget(width, height) {
- override fun onResourceReady(
- drawable: Drawable,
- transition: Transition?,
- ) {
- mBackgroundManager.drawable = drawable
- }
- })
- mBackgroundTimer?.cancel()
- }
-
- private fun startBackgroundTimer() {
- mBackgroundTimer?.cancel()
- mBackgroundTimer = Timer()
- mBackgroundTimer?.schedule(UpdateBackgroundTask(), BACKGROUND_UPDATE_DELAY.toLong())
- }
-
- private inner class UpdateBackgroundTask : TimerTask() {
-
- override fun run() {
- mHandler.post { updateBackground(mBackgroundUri) }
- }
- }
-
- private inner class GridItemPresenter : Presenter() {
- override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {
- val view = TextView(parent.context)
- view.layoutParams = ViewGroup.LayoutParams(GRID_ITEM_WIDTH, GRID_ITEM_HEIGHT)
- view.isFocusable = true
- view.isFocusableInTouchMode = true
- view.setBackgroundColor(ContextCompat.getColor(requireActivity(), R.color.default_background))
- view.setTextColor(Color.WHITE)
- view.gravity = Gravity.CENTER
- return ViewHolder(view)
- }
-
- override fun onBindViewHolder(viewHolder: ViewHolder, item: Any) {
- (viewHolder.view as TextView).text = item as String
- }
-
- override fun onUnbindViewHolder(viewHolder: ViewHolder) {}
- }
-
- companion object {
- private val TAG = "MainFragment"
-
- private val BACKGROUND_UPDATE_DELAY = 300
- private val GRID_ITEM_WIDTH = 200
- private val GRID_ITEM_HEIGHT = 200
- private val NUM_ROWS = 6
- private val NUM_COLS = 15
- }
-}
\ No newline at end of file
diff --git a/tv/src/main/java/com/metabrainz/android/Movie.kt b/tv/src/main/java/com/metabrainz/android/Movie.kt
deleted file mode 100644
index b1490e06..00000000
--- a/tv/src/main/java/com/metabrainz/android/Movie.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.metabrainz.android
-
-import java.io.Serializable
-
-/**
- * Movie class represents video entity with title, description, image thumbs and video url.
- */
-data class Movie(
- var id: Long = 0,
- var title: String? = null,
- var description: String? = null,
- var backgroundImageUrl: String? = null,
- var cardImageUrl: String? = null,
- var videoUrl: String? = null,
- var studio: String? = null,
-) : Serializable {
-
- override fun toString(): String {
- return "Movie{" +
- "id=" + id +
- ", title='" + title + '\'' +
- ", videoUrl='" + videoUrl + '\'' +
- ", backgroundImageUrl='" + backgroundImageUrl + '\'' +
- ", cardImageUrl='" + cardImageUrl + '\'' +
- '}'
- }
-
- companion object {
- internal const val serialVersionUID = 727566175075960653L
- }
-}
\ No newline at end of file
diff --git a/tv/src/main/java/com/metabrainz/android/MovieList.kt b/tv/src/main/java/com/metabrainz/android/MovieList.kt
deleted file mode 100644
index 8c2fdf40..00000000
--- a/tv/src/main/java/com/metabrainz/android/MovieList.kt
+++ /dev/null
@@ -1,87 +0,0 @@
-package com.metabrainz.android
-
-object MovieList {
- val MOVIE_CATEGORY = arrayOf(
- "Category Zero",
- "Category One",
- "Category Two",
- "Category Three",
- "Category Four",
- "Category Five")
-
- val list: List by lazy {
- setupMovies()
- }
- private var count: Long = 0
-
- private fun setupMovies(): List {
- val title = arrayOf(
- "Zeitgeist 2010_ Year in Review",
- "Google Demo Slam_ 20ft Search",
- "Introducing Gmail Blue",
- "Introducing Google Fiber to the Pole",
- "Introducing Google Nose")
-
- val description = "Fusce id nisi turpis. Praesent viverra bibendum semper. " +
- "Donec tristique, orci sed semper lacinia, quam erat rhoncus massa, non congue tellus est " +
- "quis tellus. Sed mollis orci venenatis quam scelerisque accumsan. Curabitur a massa sit " +
- "amet mi accumsan mollis sed et magna. Vivamus sed aliquam risus. Nulla eget dolor in elit " +
- "facilisis mattis. Ut aliquet luctus lacus. Phasellus nec commodo erat. Praesent tempus id " +
- "lectus ac scelerisque. Maecenas pretium cursus lectus id volutpat."
- val studio = arrayOf(
- "Studio Zero",
- "Studio One",
- "Studio Two",
- "Studio Three",
- "Studio Four")
- val videoUrl = arrayOf(
- "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/Zeitgeist/Zeitgeist%202010_%20Year%20in%20Review.mp4",
- "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/Demo%20Slam/Google%20Demo%20Slam_%2020ft%20Search.mp4",
- "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Gmail%20Blue.mp4",
- "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Fiber%20to%20the%20Pole.mp4",
- "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Nose.mp4")
- val bgImageUrl = arrayOf(
- "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/Zeitgeist/Zeitgeist%202010_%20Year%20in%20Review/bg.jpg",
- "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/Demo%20Slam/Google%20Demo%20Slam_%2020ft%20Search/bg.jpg",
- "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Gmail%20Blue/bg.jpg",
- "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Fiber%20to%20the%20Pole/bg.jpg",
- "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Nose/bg.jpg")
- val cardImageUrl = arrayOf(
- "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/Zeitgeist/Zeitgeist%202010_%20Year%20in%20Review/card.jpg",
- "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/Demo%20Slam/Google%20Demo%20Slam_%2020ft%20Search/card.jpg",
- "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Gmail%20Blue/card.jpg",
- "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Fiber%20to%20the%20Pole/card.jpg",
- "https://commondatastorage.googleapis.com/android-tv/Sample%20videos/April%20Fool's%202013/Introducing%20Google%20Nose/card.jpg")
-
- val list = title.indices.map {
- buildMovieInfo(
- title[it],
- description,
- studio[it],
- videoUrl[it],
- cardImageUrl[it],
- bgImageUrl[it])
- }
-
- return list
- }
-
- private fun buildMovieInfo(
- title: String,
- description: String,
- studio: String,
- videoUrl: String,
- cardImageUrl: String,
- backgroundImageUrl: String,
- ): Movie {
- val movie = Movie()
- movie.id = count++
- movie.title = title
- movie.description = description
- movie.studio = studio
- movie.cardImageUrl = cardImageUrl
- movie.backgroundImageUrl = backgroundImageUrl
- movie.videoUrl = videoUrl
- return movie
- }
-}
\ No newline at end of file
diff --git a/tv/src/main/java/com/metabrainz/android/PlaybackActivity.kt b/tv/src/main/java/com/metabrainz/android/PlaybackActivity.kt
deleted file mode 100644
index 1f61dd98..00000000
--- a/tv/src/main/java/com/metabrainz/android/PlaybackActivity.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.metabrainz.android
-
-import android.os.Bundle
-import androidx.fragment.app.FragmentActivity
-
-/** Loads [PlaybackVideoFragment]. */
-class PlaybackActivity : FragmentActivity() {
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- if (savedInstanceState == null) {
- supportFragmentManager.beginTransaction()
- .replace(android.R.id.content, PlaybackVideoFragment())
- .commit()
- }
- }
-}
\ No newline at end of file
diff --git a/tv/src/main/java/com/metabrainz/android/PlaybackVideoFragment.kt b/tv/src/main/java/com/metabrainz/android/PlaybackVideoFragment.kt
deleted file mode 100644
index fac6287d..00000000
--- a/tv/src/main/java/com/metabrainz/android/PlaybackVideoFragment.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.metabrainz.android
-
-import android.net.Uri
-import android.os.Bundle
-import androidx.leanback.app.VideoSupportFragment
-import androidx.leanback.app.VideoSupportFragmentGlueHost
-import androidx.leanback.media.MediaPlayerAdapter
-import androidx.leanback.media.PlaybackTransportControlGlue
-import androidx.leanback.widget.PlaybackControlsRow
-
-/** Handles video playback with media controls. */
-class PlaybackVideoFragment : VideoSupportFragment() {
-
- private lateinit var mTransportControlGlue: PlaybackTransportControlGlue
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
-
- val (_, title, description, _, _, videoUrl) =
- activity?.intent?.getSerializableExtra(DetailsActivity.MOVIE) as Movie
-
- val glueHost = VideoSupportFragmentGlueHost(this@PlaybackVideoFragment)
- val playerAdapter = MediaPlayerAdapter(activity)
- playerAdapter.setRepeatAction(PlaybackControlsRow.RepeatAction.INDEX_NONE)
-
- mTransportControlGlue = PlaybackTransportControlGlue(getActivity(), playerAdapter)
- mTransportControlGlue.host = glueHost
- mTransportControlGlue.title = title
- mTransportControlGlue.subtitle = description
- mTransportControlGlue.playWhenPrepared()
-
- playerAdapter.setDataSource(Uri.parse(videoUrl))
- }
-
- override fun onPause() {
- super.onPause()
- mTransportControlGlue.pause()
- }
-}
\ No newline at end of file
diff --git a/tv/src/main/java/com/metabrainz/android/VideoDetailsFragment.kt b/tv/src/main/java/com/metabrainz/android/VideoDetailsFragment.kt
deleted file mode 100644
index e0450c6f..00000000
--- a/tv/src/main/java/com/metabrainz/android/VideoDetailsFragment.kt
+++ /dev/null
@@ -1,211 +0,0 @@
-package com.metabrainz.android
-
-import android.content.Context
-import android.content.Intent
-import android.graphics.Bitmap
-import android.os.Bundle
-import android.graphics.drawable.Drawable
-import androidx.leanback.app.DetailsSupportFragment
-import androidx.leanback.app.DetailsSupportFragmentBackgroundController
-import androidx.leanback.widget.Action
-import androidx.leanback.widget.ArrayObjectAdapter
-import androidx.leanback.widget.ClassPresenterSelector
-import androidx.leanback.widget.DetailsOverviewRow
-import androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter
-import androidx.leanback.widget.FullWidthDetailsOverviewSharedElementHelper
-import androidx.leanback.widget.HeaderItem
-import androidx.leanback.widget.ImageCardView
-import androidx.leanback.widget.ListRow
-import androidx.leanback.widget.ListRowPresenter
-import androidx.leanback.widget.OnActionClickedListener
-import androidx.leanback.widget.OnItemViewClickedListener
-import androidx.leanback.widget.Presenter
-import androidx.leanback.widget.Row
-import androidx.leanback.widget.RowPresenter
-import androidx.core.app.ActivityOptionsCompat
-import androidx.core.content.ContextCompat
-import android.util.Log
-import android.widget.Toast
-
-import com.bumptech.glide.Glide
-import com.bumptech.glide.request.target.SimpleTarget
-import com.bumptech.glide.request.transition.Transition
-
-import java.util.Collections
-
-/**
- * A wrapper fragment for leanback details screens.
- * It shows a detailed view of video and its metadata plus related videos.
- */
-class VideoDetailsFragment : DetailsSupportFragment() {
-
- private var mSelectedMovie: Movie? = null
-
- private lateinit var mDetailsBackground: DetailsSupportFragmentBackgroundController
- private lateinit var mPresenterSelector: ClassPresenterSelector
- private lateinit var mAdapter: ArrayObjectAdapter
-
- override fun onCreate(savedInstanceState: Bundle?) {
- Log.d(TAG, "onCreate DetailsFragment")
- super.onCreate(savedInstanceState)
-
- mDetailsBackground = DetailsSupportFragmentBackgroundController(this)
-
- mSelectedMovie = requireActivity().intent.getSerializableExtra(DetailsActivity.MOVIE) as Movie
- if (mSelectedMovie != null) {
- mPresenterSelector = ClassPresenterSelector()
- mAdapter = ArrayObjectAdapter(mPresenterSelector)
- setupDetailsOverviewRow()
- setupDetailsOverviewRowPresenter()
- setupRelatedMovieListRow()
- adapter = mAdapter
- initializeBackground(mSelectedMovie)
- onItemViewClickedListener = ItemViewClickedListener()
- } else {
- val intent = Intent(requireActivity(), MainActivity::class.java)
- startActivity(intent)
- }
- }
-
- private fun initializeBackground(movie: Movie?) {
- mDetailsBackground.enableParallax()
- Glide.with(requireActivity())
- .asBitmap()
- .centerCrop()
- .error(R.drawable.default_background)
- .load(movie?.backgroundImageUrl)
- .into>(object : SimpleTarget() {
- override fun onResourceReady(
- bitmap: Bitmap,
- transition: Transition?,
- ) {
- mDetailsBackground.coverBitmap = bitmap
- mAdapter.notifyArrayItemRangeChanged(0, mAdapter.size())
- }
- })
- }
-
- private fun setupDetailsOverviewRow() {
- Log.d(TAG, "doInBackground: " + mSelectedMovie?.toString())
- val row = DetailsOverviewRow(mSelectedMovie)
- row.imageDrawable = ContextCompat.getDrawable(requireActivity(), R.drawable.default_background)
- val width = convertDpToPixel(requireActivity(), DETAIL_THUMB_WIDTH)
- val height = convertDpToPixel(requireActivity(), DETAIL_THUMB_HEIGHT)
- Glide.with(requireActivity())
- .load(mSelectedMovie?.cardImageUrl)
- .centerCrop()
- .error(R.drawable.default_background)
- .into>(object : SimpleTarget(width, height) {
- override fun onResourceReady(
- drawable: Drawable,
- transition: Transition?,
- ) {
- Log.d(TAG, "details overview card image url ready: " + drawable)
- row.imageDrawable = drawable
- mAdapter.notifyArrayItemRangeChanged(0, mAdapter.size())
- }
- })
-
- val actionAdapter = ArrayObjectAdapter()
-
- actionAdapter.add(
- Action(
- ACTION_WATCH_TRAILER,
- resources.getString(R.string.watch_trailer_1),
- resources.getString(R.string.watch_trailer_2)))
- actionAdapter.add(
- Action(
- ACTION_RENT,
- resources.getString(R.string.rent_1),
- resources.getString(R.string.rent_2)))
- actionAdapter.add(
- Action(
- ACTION_BUY,
- resources.getString(R.string.buy_1),
- resources.getString(R.string.buy_2)))
- row.actionsAdapter = actionAdapter
-
- mAdapter.add(row)
- }
-
- private fun setupDetailsOverviewRowPresenter() {
- // Set detail background.
- val detailsPresenter = FullWidthDetailsOverviewRowPresenter(DetailsDescriptionPresenter())
- detailsPresenter.backgroundColor =
- ContextCompat.getColor(requireActivity(), R.color.selected_background)
-
- // Hook up transition element.
- val sharedElementHelper = FullWidthDetailsOverviewSharedElementHelper()
- sharedElementHelper.setSharedElementEnterTransition(
- activity, DetailsActivity.SHARED_ELEMENT_NAME)
- detailsPresenter.setListener(sharedElementHelper)
- detailsPresenter.isParticipatingEntranceTransition = true
-
- detailsPresenter.onActionClickedListener = OnActionClickedListener { action ->
- if (action.id == ACTION_WATCH_TRAILER) {
- val intent = Intent(requireActivity(), PlaybackActivity::class.java)
- intent.putExtra(DetailsActivity.MOVIE, mSelectedMovie)
- startActivity(intent)
- } else {
- Toast.makeText(requireActivity(), action.toString(), Toast.LENGTH_SHORT).show()
- }
- }
- mPresenterSelector.addClassPresenter(DetailsOverviewRow::class.java, detailsPresenter)
- }
-
- private fun setupRelatedMovieListRow() {
- val subcategories = arrayOf(getString(R.string.related_movies))
- val list = MovieList.list
-
- Collections.shuffle(list)
- val listRowAdapter = ArrayObjectAdapter(CardPresenter())
- for (j in 0 until NUM_COLS) {
- listRowAdapter.add(list[j % 5])
- }
-
- val header = HeaderItem(0, subcategories[0])
- mAdapter.add(ListRow(header, listRowAdapter))
- mPresenterSelector.addClassPresenter(ListRow::class.java, ListRowPresenter())
- }
-
- private fun convertDpToPixel(context: Context, dp: Int): Int {
- val density = context.applicationContext.resources.displayMetrics.density
- return Math.round(dp.toFloat() * density)
- }
-
- private inner class ItemViewClickedListener : OnItemViewClickedListener {
- override fun onItemClicked(
- itemViewHolder: Presenter.ViewHolder?,
- item: Any?,
- rowViewHolder: RowPresenter.ViewHolder,
- row: Row,
- ) {
- if (item is Movie) {
- Log.d(TAG, "Item: " + item.toString())
- val intent = Intent(requireActivity(), DetailsActivity::class.java)
- intent.putExtra(resources.getString(R.string.movie), mSelectedMovie)
-
- val bundle =
- ActivityOptionsCompat.makeSceneTransitionAnimation(
- requireActivity(),
- (itemViewHolder?.view as ImageCardView).mainImageView,
- DetailsActivity.SHARED_ELEMENT_NAME)
- .toBundle()
- startActivity(intent, bundle)
- }
- }
- }
-
- companion object {
- private val TAG = "VideoDetailsFragment"
-
- private val ACTION_WATCH_TRAILER = 1L
- private val ACTION_RENT = 2L
- private val ACTION_BUY = 3L
-
- private val DETAIL_THUMB_WIDTH = 274
- private val DETAIL_THUMB_HEIGHT = 274
-
- private val NUM_COLS = 10
- }
-}
\ No newline at end of file
diff --git a/tv/src/main/res/drawable/default_background.xml b/tv/src/main/res/drawable/default_background.xml
deleted file mode 100644
index 82e51a2b..00000000
--- a/tv/src/main/res/drawable/default_background.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/tv/src/main/res/drawable/ic_banner_foreground.xml b/tv/src/main/res/drawable/ic_banner_foreground.xml
deleted file mode 100644
index 6b3ecc8c..00000000
--- a/tv/src/main/res/drawable/ic_banner_foreground.xml
+++ /dev/null
@@ -1,112 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/tv/src/main/res/drawable/movie.png b/tv/src/main/res/drawable/movie.png
deleted file mode 100644
index cb5cb6d3..00000000
Binary files a/tv/src/main/res/drawable/movie.png and /dev/null differ
diff --git a/tv/src/main/res/layout/activity_details.xml b/tv/src/main/res/layout/activity_details.xml
deleted file mode 100644
index 2aa3d828..00000000
--- a/tv/src/main/res/layout/activity_details.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
\ No newline at end of file
diff --git a/tv/src/main/res/layout/activity_main.xml b/tv/src/main/res/layout/activity_main.xml
deleted file mode 100644
index 86bbdaec..00000000
--- a/tv/src/main/res/layout/activity_main.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
\ No newline at end of file
diff --git a/tv/src/main/res/mipmap-anydpi-v26/ic_banner.xml b/tv/src/main/res/mipmap-anydpi-v26/ic_banner.xml
deleted file mode 100644
index a0a0dece..00000000
--- a/tv/src/main/res/mipmap-anydpi-v26/ic_banner.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/tv/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/tv/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
deleted file mode 100644
index 036d09bc..00000000
--- a/tv/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/tv/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/tv/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
deleted file mode 100644
index 036d09bc..00000000
--- a/tv/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/tv/src/main/res/mipmap-hdpi/ic_launcher.png b/tv/src/main/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index 572c5fb1..00000000
Binary files a/tv/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/tv/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/tv/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
deleted file mode 100644
index f925e897..00000000
Binary files a/tv/src/main/res/mipmap-hdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/tv/src/main/res/mipmap-hdpi/ic_launcher_round.png b/tv/src/main/res/mipmap-hdpi/ic_launcher_round.png
deleted file mode 100644
index 41f9948d..00000000
Binary files a/tv/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ
diff --git a/tv/src/main/res/mipmap-mdpi/ic_launcher.png b/tv/src/main/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 3471366b..00000000
Binary files a/tv/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/tv/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/tv/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
deleted file mode 100644
index 409beb44..00000000
Binary files a/tv/src/main/res/mipmap-mdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/tv/src/main/res/mipmap-mdpi/ic_launcher_round.png b/tv/src/main/res/mipmap-mdpi/ic_launcher_round.png
deleted file mode 100644
index c781cb4e..00000000
Binary files a/tv/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ
diff --git a/tv/src/main/res/mipmap-xhdpi/ic_banner.png b/tv/src/main/res/mipmap-xhdpi/ic_banner.png
deleted file mode 100644
index 722dd4cb..00000000
Binary files a/tv/src/main/res/mipmap-xhdpi/ic_banner.png and /dev/null differ
diff --git a/tv/src/main/res/mipmap-xhdpi/ic_launcher.png b/tv/src/main/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index 729f470a..00000000
Binary files a/tv/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/tv/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/tv/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
deleted file mode 100644
index b816dbf3..00000000
Binary files a/tv/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/tv/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/tv/src/main/res/mipmap-xhdpi/ic_launcher_round.png
deleted file mode 100644
index fd138788..00000000
Binary files a/tv/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/tv/src/main/res/mipmap-xxhdpi/ic_launcher.png b/tv/src/main/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index 66503faa..00000000
Binary files a/tv/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/tv/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/tv/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
deleted file mode 100644
index a2058453..00000000
Binary files a/tv/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/tv/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/tv/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
deleted file mode 100644
index 0aafdc78..00000000
Binary files a/tv/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/tv/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/tv/src/main/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index 643eb604..00000000
Binary files a/tv/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/tv/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/tv/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
deleted file mode 100644
index 229daa00..00000000
Binary files a/tv/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png and /dev/null differ
diff --git a/tv/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/tv/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
deleted file mode 100644
index d6af4cc7..00000000
Binary files a/tv/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ
diff --git a/tv/src/main/res/values/colors.xml b/tv/src/main/res/values/colors.xml
deleted file mode 100644
index 733f3f53..00000000
--- a/tv/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
- #000000
- #DDDDDD
- #0096a6
- #ffaa3f
- #ffaa3f
- #3d3d3d
-
\ No newline at end of file
diff --git a/tv/src/main/res/values/ic_banner_background.xml b/tv/src/main/res/values/ic_banner_background.xml
deleted file mode 100644
index d217ae9d..00000000
--- a/tv/src/main/res/values/ic_banner_background.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
- #263238
-
\ No newline at end of file
diff --git a/tv/src/main/res/values/ic_launcher_background.xml b/tv/src/main/res/values/ic_launcher_background.xml
deleted file mode 100644
index 801e235a..00000000
--- a/tv/src/main/res/values/ic_launcher_background.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
- #263238
-
\ No newline at end of file
diff --git a/tv/src/main/res/values/strings.xml b/tv/src/main/res/values/strings.xml
deleted file mode 100644
index baaa6b79..00000000
--- a/tv/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
- MusicBrainz
- Videos by Your Company
- Related Videos
- Grid View
- Error Fragment
- Personal Settings
- Watch trailer
- FREE
- Rent By Day
- From $1.99
- Buy and Own
- AT $9.99
- Movie
-
-
- An error occurred
- Dismiss
-
\ No newline at end of file
diff --git a/tv/src/main/res/values/themes.xml b/tv/src/main/res/values/themes.xml
deleted file mode 100644
index fba78f8b..00000000
--- a/tv/src/main/res/values/themes.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file