diff --git a/src/pt/animesroll/AndroidManifest.xml b/src/pt/animesroll/AndroidManifest.xml
new file mode 100644
index 000000000..ab73d362f
--- /dev/null
+++ b/src/pt/animesroll/AndroidManifest.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pt/animesroll/build.gradle b/src/pt/animesroll/build.gradle
new file mode 100644
index 000000000..3641ba809
--- /dev/null
+++ b/src/pt/animesroll/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlinx-serialization'
+
+ext {
+ extName = 'AnimesROLL'
+ pkgNameSuffix = 'pt.animesroll'
+ extClass = '.AnimesROLL'
+ extVersionCode = 1
+ libVersion = '13'
+}
+
+apply from: "$rootDir/common.gradle"
diff --git a/src/pt/animesroll/res/mipmap-hdpi/ic_launcher.png b/src/pt/animesroll/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..8cb73ab4f
Binary files /dev/null and b/src/pt/animesroll/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/src/pt/animesroll/res/mipmap-mdpi/ic_launcher.png b/src/pt/animesroll/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..232aafba6
Binary files /dev/null and b/src/pt/animesroll/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/src/pt/animesroll/res/mipmap-xhdpi/ic_launcher.png b/src/pt/animesroll/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..076ca7ec5
Binary files /dev/null and b/src/pt/animesroll/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/src/pt/animesroll/res/mipmap-xxhdpi/ic_launcher.png b/src/pt/animesroll/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..e73cbc2f4
Binary files /dev/null and b/src/pt/animesroll/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/src/pt/animesroll/res/mipmap-xxxhdpi/ic_launcher.png b/src/pt/animesroll/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..2d8725b90
Binary files /dev/null and b/src/pt/animesroll/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/src/pt/animesroll/src/eu/kanade/tachiyomi/animeextension/pt/animesroll/AnimesROLL.kt b/src/pt/animesroll/src/eu/kanade/tachiyomi/animeextension/pt/animesroll/AnimesROLL.kt
new file mode 100644
index 000000000..e4ce53b9f
--- /dev/null
+++ b/src/pt/animesroll/src/eu/kanade/tachiyomi/animeextension/pt/animesroll/AnimesROLL.kt
@@ -0,0 +1,180 @@
+package eu.kanade.tachiyomi.animeextension.pt.animesroll
+
+import eu.kanade.tachiyomi.animeextension.pt.animesroll.dto.AnimeDataDto
+import eu.kanade.tachiyomi.animeextension.pt.animesroll.dto.AnimeInfoDto
+import eu.kanade.tachiyomi.animeextension.pt.animesroll.dto.EpisodeDto
+import eu.kanade.tachiyomi.animeextension.pt.animesroll.dto.LatestAnimeDto
+import eu.kanade.tachiyomi.animeextension.pt.animesroll.dto.PagePropDto
+import eu.kanade.tachiyomi.animeextension.pt.animesroll.dto.SearchResultsDto
+import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
+import eu.kanade.tachiyomi.animesource.model.AnimesPage
+import eu.kanade.tachiyomi.animesource.model.SAnime
+import eu.kanade.tachiyomi.animesource.model.SEpisode
+import eu.kanade.tachiyomi.animesource.model.Video
+import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
+import eu.kanade.tachiyomi.network.GET
+import eu.kanade.tachiyomi.network.asObservableSuccess
+import eu.kanade.tachiyomi.util.asJsoup
+import kotlinx.serialization.decodeFromString
+import kotlinx.serialization.json.Json
+import okhttp3.Headers
+import okhttp3.Request
+import okhttp3.Response
+import org.jsoup.nodes.Document
+import rx.Observable
+
+class AnimesROLL : AnimeHttpSource() {
+
+ override val name = "AnimesROLL"
+
+ override val baseUrl = "https://www.anroll.net"
+
+ override val lang = "pt-BR"
+
+ override val supportsLatest = true
+
+ override fun headersBuilder() = Headers.Builder().add("Referer", baseUrl)
+
+ private val json = Json {
+ ignoreUnknownKeys = true
+ isLenient = true
+ }
+
+ // ============================== Popular ===============================
+ // The site doesn't have a popular anime tab, so we use the home page instead (latest anime).
+ override fun popularAnimeRequest(page: Int) = GET(baseUrl)
+ override fun popularAnimeParse(response: Response) = latestUpdatesParse(response)
+
+ // ============================== Episodes ==============================
+ override fun episodeListParse(response: Response): List {
+ val originalUrl = response.request.url.toString()
+ return if ("/f/" in originalUrl) {
+ val od = response.asJsoup().parseAs().animeData.od
+ val episode = SEpisode.create().apply {
+ url = "$NEW_API_URL/od/$od/filme.mp4"
+ name = "Filme"
+ episode_number = 0F
+ }
+ listOf(episode)
+ } else {
+ val epdata = response.asJsoup().parseAs()
+ val urlStart = "https://cdn-01.animesroll.com/hls/animes/${epdata.anime.slug}"
+
+ (epdata.total_ep downTo 1).map {
+ SEpisode.create().apply {
+ episode_number = it.toFloat()
+ val fixedNum = it.toString().padStart(3, '0')
+ name = "Episódio #$fixedNum"
+ url = "$urlStart/$fixedNum.mp4/media-1/stream.m3u8"
+ }
+ }
+ }
+ }
+ // ============================ Video Links =============================
+
+ override fun fetchVideoList(episode: SEpisode): Observable> {
+ val epUrl = episode.url
+ return Observable.just(listOf(Video(epUrl, "default", epUrl)))
+ }
+
+ override fun videoListRequest(episode: SEpisode): Request {
+ TODO("Not yet implemented")
+ }
+
+ override fun videoListParse(response: Response): List