`5;Ish-y+T3jdRcBQHU~0ho
zUzV>gi}gR&4oY|bi`)MSeEbK@wWKvUKQq{%f(_IA
zJBFb&ctoT7`*y)BD}bEOrCMkqfszqfMP;4Uh(w*eCgJ|1o7Be-VNuJFm77TCRh^fNF+Jeq5Gl5q
zX$s2735dQibsGAXuMdrKuwBzO+F^Tj2p(-p#
z=>y45<9UL=Cc9bB1;MbPrRpyhUI}4g8n4G=7lUb4#p=t!rvS5r6g)|c=h%*U2H`|(
zh2znBOzt37w*EM6i1;^yms|bUe@G*{giHV$(~rDorwCXTOv^0*E>z4CUD(cME}znh
zJ|HF%W=jY}=x|T_?FzcOy83(3QnvY^w{u9|=YuT3WsVh}r>|B|d3P{p_aj8;K`A@f
zBmC@`QShj$stU&Te0|K6sYZuVSo&Q2{Zi%g`XaBIsG*s@6wY{E{{)1mvYTNodCg@^
zq19N^il?4eJx_POu-u*XMkCJ>qnzMlwd$h`^NQ;M2NaXHevk{R;cyFf!0kN&=ZR$@s^LdpK&b>*zPA2`*ftL5HL2PKRh(Fwo>UsUhsvz
z!D1eFPC+PWkjTTs@N$Q#>c^aQ_)GFMf%N+brZqKzX4&XA&|ptCRBMkiX^wYm8{-y5
zD4dAJU!A*RhKdS3(lkgZSJ?|2a8Pg0a{?q%3Wqvryq?en#qjA1TL
zRO9`yln?mv_L!Y9?B~-(Q8caxEp{dCF^>wXsVuwaai&LhOUojga{eq>&9l24cbxx`
zQKu<}M~d;IukzTpPhZiv`(d5?={Ic}0J|8v_sW=bnhHw32@D!tQ#9c+8S5lPEj~}1
zSzWR3q{wzU8s7cHs^ltw*U^bU1|leW6^e7Ho9>Iug>2UV{MT2N3q547zl))R5^}=V
zLP!5Ik@|r|;K@TW;Ncol5Cq}YE-^?hCkH2nGAr4LGx1yeA|8j8l)~HqP_mL4~
zTPuU-hqU=cz;2-iYuANTR9z3gqP71oT1BlA!yIim^2#w;FUtjd*u}|N{87FNMkK8<
z@93p1OIOuy%B_PvoW%0ZPc4aS$tHT&7PC;~$yNB}YKfbjs>>$JY$%KLd#b5nvU
zX#_9FVC_R~mf#)xXP=igHDE-upO$s`aTrOtY?aYHTS1e^k%B}j41V{SOyGg!J8+6Q
zj;Ax{Zi{>Q#C<0cJTd7ES!tW`Gwrj-{}2&!>b(o^(52J^>S>405p10Is!h!szmw(X
z+#khgf{LZU0!xJHeRXZqUELn8NL-JqBW-`zt6Koso@y32sM_Qr!3h<{#Z^&*3|&p<
z_+AozM@ad-pA(wZM{)ajKUKUm`dlK3$qRIt*hm?+4c^@E>Ki;BW76Q5#eKEdMoqDz
zj_}-Bq5-pd4LBx$YNyfFbVmuo*-?`SIt%8DMG+7nT5IflCa0?zP*x
zQ?T6L(n&A2Us-;G+NPK)-%{05MJM6kg7U2hHJUhNusYI^7I@o!Bf#k(LS)d_{{12P
zA{fL^U90?gu0j(D0Ta(mfOK~KX$yJ_Ed;!aeA(k|>9UN!tbjAOH^k3um15kwIr6$Y
z4Lp&UmPVha-<~#(y4FhnZ2+VvS?7thFl!w#`syRt7Ze(UmZDR&(>^r(wU@`v{re8Z
zFv+$YOqK%PyYoM`N43Vb#fskC*pV+O1ctK(R`uUBikdph@w}OLZgA*K6V#cB`eC|P
zf8331fKSwI87XSLci;RAIzYU5P@pLqw-^#QVBVOMBR*<|9e57JO(k}Z}>%go(S!DyEI{0su
zq}PaK#9c(lq{vt?LMpTy6PNHrCbNyZZM|(TX6QfLJt14dJ2Emzsvg&%i*NTAsIzu*
z1paO;7u}imz-|^L?USu#+VWY!{_OJAtKAvjrv=G?Of#`!GE8lLL-Es`eZH*QM!+IQOs9Svu
z?;0*2ctVVgyUAj-l)?6fkgWnmY6_WAvj)|=>BW83%(i_hFn-NB&5ICdUN>o*!?-%*<##J@;@tsN$05>a!L62XKW(^<`%M
zeBrCH!&|1xu=@>tcLAZ4^eY*(JrA{S#oRPg4*%=f
zW5M&|ZdwnnuW-;k8zA*q+ndbm*-GhXrfNNHpl_tV`}(k~F!awljZs|olScpW{|PE(
z8oSa+&0|#V_{sZtqqjfimYzR59jG7(on$ULeS@;=Sk~Gn|shCX$
z25AM(i_f=x)?^_Y3O=R}dP&llH6uxXI*W01|C3o7XA^e*&0!~8*+>s8l(Q@0i5$-V;-K44+kHj@rji@!!tmGIIGx3r8tR3
z>18^L@8zgPJtK>onut>iIeIltJHp%1%h)HDA`Ty(cn>jJ9I%$0{Z5f>+|K*2fJBFh
zC;|Ah4{EK70nKC#p?gXz-vGM6DFX8$vl)p=%a*d%QKh@nwo3-v`|ata7(!P)-IpAO
zIOb$Cs9kv_rhWNB*_3eS!nkL
zO}N2+9F6ZT>QSP+C9QmxK9t%5tJ>?2!hDMpLpq-e#ndifitTiCcW#~5wA!^rJ212j
zWI(K@k+$r-g1s2d9Mhufp%z*{h!bzaCXMypaB+LuU?u4VRjWWTB<#YTW!YAD09$d@
z?N-}rMZY3HjT|K&*S#L7zSiRqi48Ov0hmKQ)#CIWvUfg4R`HS{O9R~CqhpNKACPa3Kpr@-r*BSzTxvX
zC7eV~`nfL_rU_nB@$(2jIIvjIMEd6-1!XH?qyVGVn4=3u+?MJKym`G8>NLZD6330c
z-5mfaan#a>Z6u^3dQ}3+rKpn^$X=S0owG{_2`~(bcE#KE#qHw5*WC^e4-AH8=#@Bg
z!@i`_DvStv7awwaoRlizz(!uq6)8-jZ_dB?O4>ImQ*nF6(~E2oWLJOJF_{A%36@>r
zDZM#ox8L+UAyiB;jqm09sc`yPTG&gM$suxpBf^g+JW1Ht7>Rz`89k>pqlH^O{+Tt=Fd>`F1M3Ozh4WpZW6g<<-R
zrY}FySBjML3?_TP6Eic&qobpKl`OV>FIUrw>q0PZ`rqwB{l5lo;YH2C!g?Y*(Qa=k%DX*XW);u4s+J7qfkl)wBoC0v4v1NxP@VR^_V%W0}-9*mDjBozE;OskYjo}I#Ip<
zLEs>t%ZdN4zN;U3smTNjpRj?$BwY^kH$WPz3dVH2t{Yd9xsdgfYt!Kv-*4t1BHo6M
zhmUPnQ$D5P1uB*qT`4HDL3JZ7qFUGULT4t6jVGPh1JSV4R5kTSnCBUa>%+djn1_^9
z_76}CVb2#SBSYYlqjZ7>?OXBtTTj4IsDSg*x4R+o##;DV8+G9~ES8StHdFSiTT*kT
zMpycsSGe8kB%6su+}TbT@<;|B3YXyrE8fOC?igzcmBpHqv9eiTz(4!Ei;(x#SF@iqG7pl^tA_LSg+7@w}2K1cksg%3E*=S@gu?3e$j%
z(6!;1XQU@nX=dpK2axhUqil?VG*U8
z;w6%jqUt2Qs4V5her@ssn)~+R8SmeRm+I9JDUs!}*
z&>UTEzm)@i6-D3;2KL>hncNoL$3-R-KqH6+LDn5^F19`3-}i@#(28<@k~I!JuPF(UJIRaml&kn-k!7;BJ`mA&}Q|P
z3f$>$kBBlslU!@`wLdCb39UQ6lZSID`_qb<^I?Wyd4UuKn|}(x`!2MfDbe8$k#{$r
z#u3*II6cFHw;iqj#3lvbRe*gBBlEy>IG2R>3WM+0_)rQI8rX5D
zDMm7`Wjdc3mNpJ4mu0fEn?+ZZH`JTo^<`2D2Gjzd8)uh#R*&GF0+7NG2?L$~%LO2h
zLwzmNWH;=;FlDt~`fRnTy>l6UWxzZ2(6hrNNjG~T+V*4+F&4(!Pg}V!HUM&!a_9VU
z%<^fY+Uh``J>F?e)V(mXnZ?yG1>5sJw1<-@=Ok!4X#7`d9+JDO>G5)7b
zX<=b8wbh&>(@*dlzfwkop-Zop7V0~PFAmp>r$lhm|H$Icf%+h
zwDlm7JhGLA=x_yB!p7Ym@ZQ0Z|5$~>-tlozO^tm~aYb-ys)aM0?BxvI^;iHcjJa%g
zx!ofL6p9`6`4|i-v0~YaHbr1RHuM-j!ph|_=0Zu!cJ|s27`4w2=tMdwKjtb7Z#`Pb
z4Tk{xgw96)|ueTiV|eF-V$O_DZv?L5a-
z2E6l-R!(`^@J^bZxty<9hhU9EGS}My*n++x6z;?i50CK>%2`~;N2pf~BL4154j$;5
z1I|R`(qb;4hAE(mkvqxCB>@q(|
z&!35Mv#~+l(2b$*+kNj#Zn%7R
z!nU4M76h5h5D#NORp;JCQgEK!ef?)ln$y|}FXPPvw0QXT5I8s;yA=XDyxfW2QRRN;
zs(CBx7j86c-ITdJQ_wOvEAcC{HrVe;8Y5G;>#{Q>x-OOUjBU+G+=s0*L?XbfppOc|
z;VvKW#|dCVcgiIjXV|gD^ZxRT_hWa`?s&j9!hq7o&^bDZT9=f;>B0p%6`tG1t*opp
z)83ps{`s*K8U6S6ifPijkNv5}%@F8+wn_i>M^4g)o7$D@Bsf*zQTAKA1%aA|hUzFd
zu0o>rPoi!4dLi};MiiN#QJ_1xE-6S*fD7Nf`v30P#=yO1Sc$X>4sTePaugXKZkkBh
z#T+2aX}kopt2GpFN#Fi9^IGm(mUvjA?(|Z~33y6IIeq2#dcfenTN}^bWYqJBt3nl;
z^5dQ$xteH|Yd`xu$o5GI;A5!7GI9};zA&B_#wS&6t&`Eu-sEb>WSxg~u^H`bCVO`B
zdb|4SE07uq|HRglW#_d-=7UkQs&_bqxQsZN=Bu5l*4ua5?KvJV@ZmQeaBOlv(YX_q
zLyu2N$S3{1aq<;C&kV1<@3y~5fWm&^e_T4eG0SSC7F|fpyKZ8i$z^57Ko7j|qZtvN
z&<-F+CMG`6(XiUs7nQsPj{ZtB?DhwbP`lnEFJs5P!LZs`F!98|#%@~siv7d(55;x0
z;QP~jp=QQkE)X2Tjc~zQE|6TjuqOfDq0EO!vD42o6!4k8iVrC~4h1T2mL48Tc%n*x
znK16TA#i&UL#Mlfp)Vu-h7-BGfinks*b`~lR0{?B>_%l&*}Qu19UQQUH59DD
z1G6;7T|C~9XHUFe)o4KIRng?aA)v!u9*VW-Pkc>sduetW^mhcE4P^Dglwi~o?Q%DM
zw}C;(SyDze7R9_lMJWHvOYI82OF+b|7Z??V6@0S1+q&RC+Z`?Rrfn9d@-z1Zypbb0
zNg&O`ePizu?ndYaCKiw+2Sf0{^!XR7iGF7n?rPsjN`1q>o1>jM4YoYEH_UamwWYU{
zM0mU^Q+@pSae-TC$vT~=2~|K~*|xe7F;Ww1ds2jr_-(_Dv$>6p84KTrsgBMbPh>-o
z&i*k}a>cb-VB?#V9wGrjsb`;7fUM8O6@PeLgnuUHD*RmYcJnOBu&R;Rj^2MG4zKH3
zvR|T~@kWnrr0Eyxbd~;{Py`(N>b6&y?e9wlnRJh^J*7ZO{pmlM@EVDNayZEa@ZOjm
z1yvi^lga*>szb+a)Z;a1*!mx&0?V(2DG^jYUD|B)W40||@p1=ydq9FrzD7&5
zMELMAIxg4hK>ZFzAdLKfpqaQ*m%t-=CsY4<^Vmjgj;@&-E-|(S9WTsp@gfYu{fi+i?w{6^s
z!h#pZ2Sz1bF9t#&BG0qE!{JF2Ds{#!+Tl5>W@?v8J<*ph6=Suk007LW6&279n21&^
zPGN|t5Q{QNgZy{i-ssxNy+Rq};WZ4*o;rR%j}CGt@5)}h(2mxoSqodMU$vu?g5;)9
zT|ktC>>Z0*MS8Y*QL-pYoKyHzkeC3j{6-rDXEv2GYcq>?S8$>D+A;Md^J95>`Z|nNK^qu(^lk0
z-i@YtjB5&YZn)lQARPd}(~lMJmw_4}9T~f_6xM(8M%~MvoWR~B)A+7K89^lcR;sIPxVL_|O&Ac`qjfxySn^L=j2g6Cjx=zZb9~oUv_`tAyYlMc5Ey)
zj}Zd8%&crd2+*#7+bhFb0k}lLrkmB8l39e-pW8R#Au0#}8UdQ`i%MGlGnV;VRjR9u
zr?kV0OdHDEKC_-LFKmfX_Ex2f0}=mSzx+^C92ZJH!Hx#xAf&a6bJ^tbEyP#W7t*zy
zJ+!#E81z?dV|~MD2Gb|2Ti8?R5M4wQ$8KybIv_wJ70Nt{@!>(A3boShB8Q&9ciU6gKY2B4Y8Ka`M|8l*S(jsR&$+GWK2^S+=BJ!U
zq4}J-Jkb}Ik-cE5C5tO>l;q}al-kpXi@d8VMBfG-SWbAM`7^4-kg@$%DZY&fM)Zko
z__-D_MJ9(>bY1dulpy_xr#sPCN=9FEa8z5pi8^CpS8hThB!#-
zMeo?ir1jG*2F{d|asMHjkp(Tk^aiaqp2Fh6I0>PxqMm|XM1xIho7^v73IP1M(3DAf
z96Vl>CXg+37vhVqeb<`+=ydA~Ieoe!xX1M%gdT*^jm45HXQH?2-W?NW8-PWV8V5Nj
zC4aagqkvOivtt|>x)S_eBX@DjLn@=d`2aRK$`iw1r$quk^iH}v@D)r{g~d^Q2l6wFlG!$h`pNJcU|~xOYWuG$=EVOi5$iC`kdR_Qp_E)=>XaN9
cSWhe(nP0h|gZY*aIo<#n2?g;AQ3L<~2O{ggDgXcg
literal 0
HcmV?d00001
diff --git a/src/all/subsplease/src/eu/kanade/tachiyomi/animeextension/all/subsplease/Subsplease.kt b/src/all/subsplease/src/eu/kanade/tachiyomi/animeextension/all/subsplease/Subsplease.kt
new file mode 100644
index 00000000..250e0045
--- /dev/null
+++ b/src/all/subsplease/src/eu/kanade/tachiyomi/animeextension/all/subsplease/Subsplease.kt
@@ -0,0 +1,208 @@
+package eu.kanade.tachiyomi.animeextension.all.subsplease
+
+import android.app.Application
+import android.content.SharedPreferences
+import androidx.preference.ListPreference
+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.AnimeHttpSource
+import eu.kanade.tachiyomi.network.GET
+import eu.kanade.tachiyomi.util.asJsoup
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.json.JsonObject
+import kotlinx.serialization.json.jsonArray
+import kotlinx.serialization.json.jsonObject
+import kotlinx.serialization.json.jsonPrimitive
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import uy.kohesive.injekt.Injekt
+import uy.kohesive.injekt.api.get
+import kotlin.Exception
+
+class Subsplease : ConfigurableAnimeSource, AnimeHttpSource() {
+
+ override val name = "Subsplease"
+
+ override val baseUrl = "https://subsplease.org"
+
+ override val lang = "all"
+
+ override val supportsLatest = false
+
+ override val client: OkHttpClient = network.cloudflareClient
+
+ private val preferences: SharedPreferences by lazy {
+ Injekt.get().getSharedPreferences("source_$id", 0x0000)
+ }
+
+ private val json = Json {
+ isLenient = true
+ ignoreUnknownKeys = true
+ }
+
+ override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/api/?f=schedule&tz=Europe/Berlin")
+
+ override fun popularAnimeParse(response: Response): AnimesPage {
+ val responseString = response.body.string()
+ return parsePopularAnimeJson(responseString)
+ }
+
+ private fun parsePopularAnimeJson(jsonLine: String?): AnimesPage {
+ val jsonData = jsonLine ?: return AnimesPage(emptyList(), false)
+ val jObject = json.decodeFromString(jsonData)
+ val jOe = jObject.jsonObject["schedule"]!!.jsonObject.entries
+ val animeList = mutableListOf()
+ jOe.forEach {
+ val itJ = it.value.jsonArray
+ for (item in itJ) {
+ val anime = SAnime.create()
+ anime.title = item.jsonObject["title"]!!.jsonPrimitive.content
+ anime.setUrlWithoutDomain("$baseUrl/shows/${item.jsonObject["page"]!!.jsonPrimitive.content}")
+ anime.thumbnail_url = baseUrl + item.jsonObject["image_url"]?.jsonPrimitive?.content
+ animeList.add(anime)
+ }
+ }
+ return AnimesPage(animeList, hasNextPage = false)
+ }
+
+ // episodes
+
+ override fun episodeListParse(response: Response): List {
+ val document = response.asJsoup()
+ val sId = document.select("#show-release-table").attr("sid")
+ val responseString = client.newCall(GET("$baseUrl/api/?f=show&tz=Europe/Berlin&sid=$sId")).execute().body.string()
+ val url = "$baseUrl/api/?f=show&tz=Europe/Berlin&sid=$sId"
+ return parseEpisodeAnimeJson(responseString, url)
+ }
+
+ private fun parseEpisodeAnimeJson(jsonLine: String?, url: String): List {
+ val jsonData = jsonLine ?: return emptyList()
+ val jObject = json.decodeFromString(jsonData)
+ val episodeList = mutableListOf()
+ val epE = jObject["episode"]!!.jsonObject.entries
+ epE.forEach {
+ val itJ = it.value.jsonObject
+ val episode = SEpisode.create()
+ val num = itJ["episode"]!!.jsonPrimitive.content
+ episode.episode_number = num.toFloat()
+ episode.name = "Episode $num"
+ episode.setUrlWithoutDomain("$url&num=$num")
+ episodeList.add(episode)
+ }
+ return episodeList
+ }
+
+ // Video Extractor
+
+ override fun videoListParse(response: Response): List