diff --git a/src/all/onepace/AndroidManifest.xml b/src/all/onepace/AndroidManifest.xml
new file mode 100644
index 000000000..acb4de356
--- /dev/null
+++ b/src/all/onepace/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/src/all/onepace/build.gradle b/src/all/onepace/build.gradle
new file mode 100644
index 000000000..6be4cb1ec
--- /dev/null
+++ b/src/all/onepace/build.gradle
@@ -0,0 +1,13 @@
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+
+ext {
+ extName = 'Onepace'
+ pkgNameSuffix = 'all.onepace'
+ extClass = '.OnepaceFactory'
+ extVersionCode = 1
+ libVersion = '12'
+ containsNsfw = false
+}
+
+apply from: "$rootDir/common.gradle"
diff --git a/src/all/onepace/res/mipmap-hdpi/ic_launcher.png b/src/all/onepace/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..0a05668e4
Binary files /dev/null and b/src/all/onepace/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/src/all/onepace/res/mipmap-mdpi/ic_launcher.png b/src/all/onepace/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..0a05668e4
Binary files /dev/null and b/src/all/onepace/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/src/all/onepace/res/mipmap-xhdpi/ic_launcher.png b/src/all/onepace/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..0a05668e4
Binary files /dev/null and b/src/all/onepace/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/src/all/onepace/res/mipmap-xxhdpi/ic_launcher.png b/src/all/onepace/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..0a05668e4
Binary files /dev/null and b/src/all/onepace/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/src/all/onepace/res/mipmap-xxxhdpi/ic_launcher.png b/src/all/onepace/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..0a05668e4
Binary files /dev/null and b/src/all/onepace/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/src/all/onepace/src/eu/kanade/tachiyomi/animeextension/all/onepace/Onepace.kt b/src/all/onepace/src/eu/kanade/tachiyomi/animeextension/all/onepace/Onepace.kt
new file mode 100644
index 000000000..db149a59d
--- /dev/null
+++ b/src/all/onepace/src/eu/kanade/tachiyomi/animeextension/all/onepace/Onepace.kt
@@ -0,0 +1,156 @@
+package eu.kanade.tachiyomi.animeextension.all.onepace
+
+import androidx.preference.PreferenceScreen
+import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
+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.ParsedAnimeHttpSource
+import eu.kanade.tachiyomi.network.GET
+import eu.kanade.tachiyomi.util.asJsoup
+import kotlinx.serialization.decodeFromString
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.json.JsonObject
+import kotlinx.serialization.json.jsonArray
+import kotlinx.serialization.json.jsonObject
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import org.jsoup.nodes.Document
+import org.jsoup.nodes.Element
+import uy.kohesive.injekt.api.get
+import uy.kohesive.injekt.injectLazy
+import java.lang.Exception
+import java.net.URLEncoder
+
+open class Onepace(override val lang: String, override val name: String) : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
+
+ override val baseUrl = "https://www.zippyshare.com/rest/public/getTree?user=onepace&ident=kbvatgfc&id=%23"
+
+ override val supportsLatest = false
+
+ override val client: OkHttpClient = network.cloudflareClient
+
+ private val json: Json by injectLazy()
+
+ override fun popularAnimeParse(response: Response): AnimesPage {
+ val animes = mutableListOf()
+ val document = client.newCall(GET(baseUrl)).execute().asJsoup()
+ val responseJson = json.decodeFromString(document.select("body").text().dropLast(1).drop(1))
+ val childrenJson = responseJson["children"]?.jsonArray
+ // 0 = eng, 1 = sp, 2 = fr
+ val langId = when (lang) {
+ "es" -> 1
+ "en" -> 0
+ "fr" -> 2
+ else -> 0
+ }
+ val langAnJson = childrenJson!![langId].jsonObject["children"]!!.jsonArray
+ langAnJson.forEach {
+ val anName = it.jsonObject["text"].toString().replace("\"", "")
+ val anId = it.jsonObject["li_attr"]!!.jsonObject["ident"].toString().replace("\"", "")
+ val anStatus = if (anName.contains("Completo")) SAnime.COMPLETED else SAnime.ONGOING
+ val thumUrl = thumAnimeParser(anName)
+ animes.add(
+ SAnime.create().apply {
+ title = anName
+ status = anStatus
+ url = "https://www.zippyshare.com/onepace/$anId/dir.html"
+ thumbnail_url = thumUrl
+ }
+ )
+ }
+
+ return AnimesPage(animes, false)
+ }
+
+ private fun thumAnimeParser(animeName: String): String {
+ val document = client.newCall(GET("https://onepace.net/_next/data/BM0nGdjN96o4xOSQR37x8/es/watch.json")).execute().asJsoup()
+ val jsonResponse = json.decodeFromString(document.body().text())["pageProps"]!!
+ val arcsJson = jsonResponse.jsonObject["arcs"]!!.jsonArray
+ arcsJson.forEach {
+ val thumId = it.jsonObject["images"]!!.jsonArray[0].jsonObject["src"].toString().replace("\"", "")
+ val langTitle = it.jsonObject["translations"]!!.jsonArray
+ langTitle.forEach { j ->
+ val langCode = j.jsonObject["language"]!!.jsonObject["code"]
+ if (langCode.toString().replace("\"", "") == lang) {
+ val title = j.jsonObject["title"].toString().replace("\"", "")
+ if (animeName.lowercase().contains(title.lowercase())) return "https://onepace.net/_next/image?url=%2Fimages%2Farcs%2F$thumId&w=828&q=75"
+ }
+ }
+ }
+ return ""
+ }
+
+ override fun popularAnimeRequest(page: Int): Request = GET(baseUrl)
+
+ override fun popularAnimeNextPageSelector() = throw Exception("not used")
+
+ override fun popularAnimeSelector() = throw Exception("not used")
+
+ override fun popularAnimeFromElement(element: Element) = throw Exception("not used")
+
+ override fun episodeListParse(response: Response): List {
+ val episodes = mutableListOf()
+ val Realurl = response.request.url.toString().substringAfter("%23")
+ val jsoup = client.newCall(GET(Realurl)).execute().asJsoup()
+ jsoup.select("table.listingplikow tbody tr.filerow.even").forEach {
+ val epName = it.select("td.cien a.name").text().replace(".mp4", "")
+ val epNum = epName.substringAfter("][").substringBefore("]").replace("-", ".").replace(",", ".").toFloat()
+ val epUrl = it.select("td.cien a.name").attr("href")
+ episodes.add(
+ SEpisode.create().apply {
+ name = epName
+ url = epUrl
+ episode_number = epNum
+ }
+ )
+ }
+
+ return episodes
+ }
+
+ override fun episodeListSelector() = throw Exception("not used")
+
+ override fun episodeFromElement(element: Element) = throw Exception("not used")
+
+ override fun videoListParse(response: Response): List