From e837d84105076f829a00a2f7ea059a6ac1f45d97 Mon Sep 17 00:00:00 2001 From: JPyke3 Date: Mon, 1 Feb 2021 11:10:53 +0100 Subject: [PATCH] Add Support for iOS "Add to Homescreen" * Adds basic Manifest.json * Adds Meta Tags for iOS * Adds Meta Tags for Android * Adds Logo for Manifest.json * Adds iOS Logo for homescreen --- src/main.rs | 20 +++++++++++++++++++- static/logo.png | Bin 0 -> 10553 bytes static/manifest.json | 15 +++++++++++++++ static/touch-icon-iphone.png | Bin 0 -> 13835 bytes templates/base.html | 13 +++++++++++++ 5 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 static/logo.png create mode 100644 static/manifest.json create mode 100644 static/touch-icon-iphone.png diff --git a/src/main.rs b/src/main.rs index b67445a..30b479a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,6 +19,21 @@ async fn style() -> HttpResponse { HttpResponse::Ok().content_type("text/css").body(include_str!("../static/style.css")) } +// Required for creating a PWA +async fn manifest() -> HttpResponse { + HttpResponse::Ok().content_type("application/json").body(include_str!("../static/manifest.json")) +} + +// Required for the manifest to be valid +async fn pwa_logo() -> HttpResponse { + HttpResponse::Ok().content_type("image/png").body(include_bytes!("../static/logo.png").as_ref()) +} + +// Required for iOS App Icons +async fn iphone_logo() -> HttpResponse { + HttpResponse::Ok().content_type("image/png").body(include_bytes!("../static/touch-icon-iphone.png").as_ref()) +} + async fn robots() -> HttpResponse { HttpResponse::Ok() .header("Cache-Control", "public, max-age=1209600, s-maxage=86400") @@ -75,7 +90,7 @@ async fn main() -> std::io::Result<()> { .header("X-Frame-Options", "DENY") .header( "Content-Security-Policy", - "default-src 'none'; media-src 'self'; style-src 'self' 'unsafe-inline'; base-uri 'none'; img-src 'self' data:; form-action 'self'; frame-ancestors 'none';", + "default-src 'none'; manifest-src 'self'; media-src 'self'; style-src 'self' 'unsafe-inline'; base-uri 'none'; img-src 'self' data:; form-action 'self'; frame-ancestors 'none';", ), ) // Default service in case no routes match @@ -84,6 +99,9 @@ async fn main() -> std::io::Result<()> { .route("/style.css/", web::get().to(style)) .route("/favicon.ico/", web::get().to(favicon)) .route("/robots.txt/", web::get().to(robots)) + .route("/manifest.json/", web::get().to(manifest)) + .route("/logo.png/", web::get().to(pwa_logo)) + .route("/touch-icon-iphone.png/", web::get().to(iphone_logo)) // Proxy media through Libreddit .route("/proxy/{url:.*}/", web::get().to(proxy::handler)) // Browse user profile diff --git a/static/logo.png b/static/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..bd005fc2404d4b203eba752f6695e802b4f9b0b9 GIT binary patch literal 10553 zcmZ9y2{_bW^f-KH#u$dNWJzRclPuX~Nd{@*OA=#@Z3x+wELmc*7AYmNq^M+>!Pv89 z(3FJiYbq6GPqL)&ztivcf1me#=XpFn_uPBWJ?GqW&OP_sbHm*1Bn~Tz1pweqpE_;< z0Fuc1<6wu77jEhA;Xlrcr)(|*z$L)?Lx9W&A`pnUY;n>6lyvQ$h7Gn0`lk8-l-=g~ z>x2eCrt9=^eakC|`Eiq*b|WE@Kl-c`F1RpTrIFtdOJ_&Xqt`34ViBntQJ<4!7+fLh zyA|2O)OR!R4L>h7+(3$mbankOFkBGCQ#8f)4Zc#R?5sFY3t!&s^0#-Gu&^-9(zJeqL*mfv zbV%ut$-CA7?d+@GTYYJp7EY>PxcttPzy9y9ZpX2RprD|;joU|-)|A2|N-JL9fAK5t zjV2ao4RZnO>lq%xapm1=ZOFbM3t~dE3!g(wE|bw8aEOvr;e~ZPITH9lSGs9yrIZ)N z5Mq-j6GF6gbsGg*`{sYB93AIWY!xUqLCB+vLpc7p(vo$B7?k6Ts9VoP9+%G^J$|Pt zWIa^0{6|$&Q=~|Jatf$?NI@&4kV4C{gAWpNU+_x?TR!%@K={3*A!nRT-kmP^%-PB_ zz3A+cGPkUSX_~Bq$E#TnZu=)9b+6(Ua%&*6hN&~yTBwN*&cjxt@aeK)6rmm{z z3bj+Gp1lx@IplEanw(YriKTb1&!JY#&me{SUs^Y94Crh|Y-f$U?;j_-C9K?RP3%rZ z4qZU*?2o3Pg-#0<4X^(89b7Qsy_RtFsqkkR_L76LcIM&;F5|nnryotNWQAmn@3DV7 zxul&i(DRPF%TS9=UZy)q>`2^_(R>z{m23gY^I(K9HUG@5+qX|5WMU|2EsMOzPHqFm z>+5P;8RE5u{6F`Rn{QbZBn(i3ol|AeMNX6{W2f0WguQcSj3@;c)Xbv$W{-1){%?`$ zV?x#B%Sd6`>4L|tJQeL}bhOtF`X{W-pGDnVY*!wA#axWPM4H@;b}J(LxK)4JffRP> zHI9vF+Sb2v>D8n9Z8GYRdtN<%z zB2mmUds;3wh}#AvP>e3P3>4KX6B`9AsX70p%z3}Oot<>bnuA!G=_%CTMJrmF8>x7W zApOU9oGLshmtGtdszNoQauO@sTe2ywK+T}Yo#}U7LMJ>^gP-o+@Eh@VNoPXMR-GGv zF0W`1HE%eIXFM*eMC4Yz8mYc=a=Dv`6i(Vl)DL#?lIZa0(S)r##Wv6H7ux{sO^%F;60X`$J}VX_M33(I@Zm!} zDZW3JVl>GnC#C3CS-^!zZ0CNw&is)gMMP)`R2F1XjHb(V36d^hG=SabepU#P*h}QY zS{@K@7Kk1^ub)`{3w2K_j=J`F=ktTgc2^I+_q$P>Frkg9i_e;>?wV z@yn8s~^V=bOCE({hVU_KlgT=OzY}zJhYP9!xj7*Zk4{=v^>Urnt z(1Y1~L|7ohQRL!(tvnXZGaR!!L6K{=VGRdSoSZD4qruGxj@h%8_LhBQ`!I(!2vm}! z44JxX3DMHpNl}u_#d`~A;CYa}_+**u`inFt9ZsUcz3~GDo@nz(Qk+7b(Xh&heN>Pw zLd|d^Zv7i6ZvMQfVdBfC97*O|-Y;L00RCJ9Kb83LQioZ+JAXBPaL0eaoF6!WS_bo} z!XC2v10ilutlDKT=#*2|K~_(%U_+4J*b%tWn>`D>Kg{TZoYW3i^(NTH(;^Vn=+rJ8cmGgWiW{r#iEOQAuQWDxy~@>~GiP>*feK z%3+f~1t;+Uq(5aHvvnH< z?n%9vY7jRZl!~LBLFMt&jqk-$!w|q&&@pU*!)9^^-FUAZ!u-G+o#Ss#5M?M7 zD~ejT1SD<7FTK(2j%qOfRL6J}P`gpjmAHpIdFnYb=SB?eFDFs!^y`nq-8}enu6y2= zX>0M*{gZiodAfwzawf{p2kz#}Mj^aT9~cXM!QX-S68kMJ@q z^A9{Y)*HbGayF$$?r6tftKuYzU7zqwj)jhcvLJF{kJoNuBBe?iu5(METtkXnyvL1- zia&zFYjzk6?!R~-Ubl2loE!@fu5eUG=Z_5it~yT6#dcKu8VXGOJteMFPT-@LknhNV zhQqeUMO6pie7ly{LAGxxkps^&#cl2j(9_x$ME-`*XR)BUyMK zlepQJm0z!tmS>mOiGLrsuHL@wSiAZ~U3c3e{OPx*l|;vw4?7*%NX(2_eFnD1@1t3& z-0M%^`1blrX?)~$Ct3S*1)1>$d-Eu%QH0QjrQhGaH7B0XIjXH4Di=V^N2Qt02g__{;1bm*I%C(sdi5rmTlOn6MNebGat{>K2;*YCiCKu~knVKn8 z^+o6SE-oK}f57B=Tq3zPYqc&-jILug%STBXn6vmlwl((SE9l+)mcjr(Ok zE%HLDW+FFxBspJLI=z_I9k0Jf+dt1(sYLeZG zM;)pjH-OKbP5nEbD#X?Jj(g5?oRLGNJ-JA!Ym?*7Bc}%0>SxW(&tL5y9KaQG6A3CH zu*{2LtfyD(c&b?6{YiC+ue&{?ofI7n%u)4hw2x#*9Z`9#i+aV<(0V?UqOlw zYVfF?&2HnJPX}<*>PIV2c_9h1imQJ%2_NqOwRakrV_epy74DUry8TFN!Sx0OO(c|fo}<#25GD|JMITN$>Y1+fg7DMX(Oy~a za7M2v+l=@4o;ApJZBz!K5-SF!U~slrKc{Puljwni#;I79Yc>3x;+iXC9!y0Nw9hH| zcwig`ei59`qtap@;{|9~;`A+j%#l`$LaX87Uf+GFvq8x znjFV2W4(6KX|B-aDHY6)#*L!oy>UML#OIcsMR zy7?F?Ak$`qKyvh`ykxNv!=e!hes(Xec_}Aah5T#zTPDg9CJ|J#O$(6od&Znuq()|b z9#C?KLjWngRO>QX9I-5P^3-l16>J4tT*M-4KzriXBQsW5nP6q}4@rWhs}S`rCDn%{ z4q5(eNnjT3Cy#`o!M)rfS;92p?FTuKb3E0u%$S!o9iI`}=rA3dZGmFZW?r4HyTIh| z=QFnS{D-ZGPql5+{BiF;%E!J(E*VkmncP1eGOTF5NWy=&f>FTR{S0HTB*v9cX3RxA zqy-mExM#zZJwP6Z2cts+Hxl3jEre$4bJ_CPXbz>{h`T|K|MaaE^QaaSA*f(k3INN} zd(0=X7#cC5ekTB)k8ggtylQx@*E4Q9z*8NC?_7DY?!3C*s~DkNzaT03uEfL0K=0U@ z)rwi!cYg0RBO@|(xAU*)hAnrFoZnjdRmOZ5y93up|8wQ&!s0QnB)r}(|EOAD)nm#D?y(*DAtm^<``6_^tMiWR%hq4z zBVO|p&-~?4u$*YyenQHKFZ{?lQHCBiS|tDH%>UiX$f^uWCEIiY^P~`}BDyGYE9DV~ zCH=j=#=$Km!5lipiuq;$*r&-_83@r73DDQkrr2o1Y0p)&&EgRhgFLB~NqNggev~l% z&PaRQmoHz=w%P1K$l-47^2NxQVF^vkPb6cHd@-!TR`1mDou++-{R?6AUZ2}GZ*UZ3 z_yGd-#YR}uP9BM4f+ggW$`uXgUjB}$wWgb$IkWgmjo7ZA0POF&(JTsju`zZ+DsvCR z7%K01l1nY~>V%`MJTb`Ma?ZoLL&6iEn7!FfKx(Il$G4`9t+iM=8N$Lhfhj1#sa1eK z+?#!EdulB*vU<0m3}KFeGrZ*w74qe3Ct!5-(gvE=`}EXb@*KFaYpOB%$@_mErO)S9 zG+>yOY%?7@+)5}G;$KIkI~2&wufazEJ;kz0#ScC3eeI8A%!98x=)D)iM)&c9VG`Eb zV*y*xk=+pF48ujp29#5AUWVKRR`$rp8&wr{$h2{5FlI8*-XYX)=#bwtx0^oq0y*qJ zYL>FoFXmo$7g*R$uf!m#Q_`+)E$~M0Q9^I{wES^8se_>nOLPSKvEi+swp(Fs@Qq)~ zhA!t*QmZhFY(V2@>Z89e&2{>Rl-_FEj#Wjut_d;XECyy6?}hqDOM(R!1nJNE3hOZl zjbA!?8+Qh!`rnuMv=pP#R;3tI7WDE$aZ#syjfulT^7Hx>oXs21S!R-Tah4)97F{d< z8TmcIvQcH2=O2(tajlhMOug7^r{Cw@7!dHU4Z6`|)toh0VwVIPs3VV6a30|y+7x=j z%+#nKRb%26!X%6je7~E1RpY}0`Xxp}p2{qASY5+YzAZk;!7hvx5~wjXn0ZM^!kj)& z-vIyuUN^H66rbQXgwQ&fh_o5674O0HSZrp z)E5J^{l-(RywK3rYX(mD0-&I3_bp{GyIB;vhFiA5(pOy>?NgEUem--Vz)pj9uZsc*L#|OGH%D1uL zQy{g={e=oyE0Pa>EAO+ni6IHm2|Sk&Ai%Wal=We!Cg?;5oky?c8F7Fgb^2+kX>~~b&g04mrji2zsxMk8dwMY1(=OnU0Nk$) z=-w>H4nmhjZ|_yjy3a0;S^$8`?D$pXy67lM=YEa?G}q^I*`yc%Z0l$;DT@0nPZqh?Gw>?+$q2Oub5sqMjsSY94TUY4l*izQ=*KV}bL5ZDv_ z?7aC!FJi!OH*;_5E_py1#|eMb>kK>;vUrxEGQ&IP0}WyHW^zOJlK$>`q#LJ)EIZf^Eyn}?Zb zc^ycS|B?zBJpeh)){Wc>PcEsT1crucLk{L#{QUfqOB$I+02p@Yu>2n$pGr;%$(x)& zfS@C`8bwiPkep)eMvtPvk9hr!+?sWmvei-k$^()sb|Sp^U>?^0PPtVPxzGUtzMf(r zLEBmF!}-CXp|Vh@UtJ<2w==QA0DsGQX(qJv<02Q#`)Zy3#=qLt)x`#B{kz+p9|^vi zuqKXFIRGGK-3WhU2taADvu_Ec6l5jeULRSgRfEn+|vk)jjzM z%n4>W{MBa>^9JUP&+JY`LFne@)svF|eD&@XI|=!=d+M!TO3rA7N--{fj>YBgUHOus ziGENmQ|=2vYYY{HJ9fIm^5Aq43+52p1^SZ42;=mlc_%3rELF~nKtIt$E9rYR8gqsDh}aa zQYo%h(Bn)ATdVE=U${mM%v*;r+6n5KD)3@^HAN)%u%!RHo6s0$LyJ-CBu1Skninu8 z(_Hh1kc849)p#_ZzgS`h%X{%-p%lI9u3((@LT#A)^jSRSjTg(3B{2XHv>ISXZ~a^f zL}gt!m)@L*@bdFptN?%^Ym#VTf=b(W84lCY(GgP!+wP?dEUw*;Pys-3esS^k{l-WS zhRSyyK=0Lr4ne(9F5<3!Frb*&1#WcaA>QWb07mLzg%gEvVeg4@#M*JV`@=2exP{Bm zUqwTIb)Qt%e08A+OA!6Q68DdU^gAVUzlyQMQK(Zpe}y*oq)Il;L<`?S0{N9+MZ6BX z=;f0(Q2Q8m38%(tI0P<3<`nI#$N|2tj0D{i|C&jJt1a!6sxCz&=oX@~zrXOPVn(1` z;)xdA==2+ePR9e#k>7>e^ZogBK;58Crx#itqlW?=qtSZyv&$`^524E;e9%v)3DM`E zDiRyFJ$=WqX;+B=pU;$6BduLN!byAr&y2IPv!b;!VDu><=+x3Me}udm@P@iCZW;-aRC3?J6wAC72<6j zJIFCSVY52Y_6i|4GB(CifJ%psqqkdxtFgo$7O@dxHJFrQWSYhv(2aOvT3w?!S{wUFu`kX~`uQVGV9jeAi#*5Dh z(xX^t4C*T}7xeVz@L7DoJvVza`b~+DypI9Mv2v~s5ecfi%t#2@G6kT&t&9028Qu&owa?}Y z2)X%}nP&Mgg^2HDcKqBw_AP_DX-=s;xpyn>BNsl;U*Zs@9iBA6=z2z8GLFNjk^@(d z0;b7vV_aG{o+VRKMS?J3hIV~owYCLGP@3Zb{nn!$=EEIVoM1eCbA$yr`yp#gQMNoP z^(Z$0>M3het3wf+<~eiKui-uy+#oiF-h;5jgc5QdqTE1WFJMT+lLPy4$mR;8yc_`v z?!f%sl8hkj2PO5TY+C06z)w0$hwvGj8#59fvdM`7il>G{SAsuYLp~BvKIyW;g_h^@~+mZ}0Pm?XOK0S?)yA;j?%;R9ABGR{jA}b8cqs|Hq zP@lpJV1Y9N7{S-NVtFr1VY(%hGcu`Nv;VhBDw=j2t}kPd3J3O5@*r7)IlVJh79I>^ z*07^Y?0J^V?I{oIzFIqD z(P-=`K)3jO^Ud-X=)`litxE5XveEWSzr!r4Z~`D!aBfAm(29}Je0hg$EJVi`bzYfi zWetP(=#EyFd}tSTQ>||sboL)6yIRS6L1CskyInD_fz-Xm60kOf3F=VQ?wgFvTq?*V zvD03TvV%{ug`q;8Mett#^DOv;Ju^dsgox4arvLYm7y7e)-F^MqWTs1~I}{_mz}Lj+ zej!Xw$-^Xp@Xgt3%Yckg%)gat>q=ao7px-W-VAEogkH?G%Kq)ev-^;Q$B?jb;R;5L zfuWi-Ij;)G{sEDbm8mrRq5$SNlz;Gm?EdS`t42v!BC97XQw8>%{ofw{;d`tuF5>AR zvs}U+P-z$5x$WSdbAp{_DSdOh8P|ZqCqjGU%^DPa;N`+-e@d9p1i(ivVs&mLy4ySn zM;u}NsfQMoEj`~rdiF+0zP=2mp?kf;&e=v^PU0b+t`>vA1VuySLg{?c;5sGGiUZ8w zap>#w3Uhz{3PU?i;1LX2z0BPI?9A*3__!iqqVN<&22(ALr8fi zYL}Oakh`(n)N2z9y|JvOD(|$1bpxLa`USY-d)gSGH?R4LTEd zYZlYuqVn5ssMJyK#+fDoKq+>4d;Ad_8?9EP{8&@a{OHPh{Fiwc%?-i9Z{(H3`&qkRn&s}Z8${!%x?-{odF(i0Cfm|r1v{(%t zsVdz|F6J{F{61Rc<(TN&t%CqpcC-#WVk>cB_rf(gyvv9Me2!dw@2$uOg854h)mJFZ zw~4ZW?+*h|!!_Jhr6(Dqlw>siB&W654!XuYaqet`G;tdc(7d0^`h=?nncd59nm3&V zF{++5em+-=>{#W|1AZ7s}ghYSNVvUM9*e;-h!acw5)RCG zwE5F`KwjIern1~d7bF4QTc*u(oju2Wq`9+8mCC z{`urq5r03vU=d_MuS~>zq{(wnVIf*v0+WU*%Upposy+|>zTKx3mUD@__K2m%--sO! zyGv2{w=S)7yvU@dQ3Drm4I$jcUw^2iPzI1AKfe`sfgT#S;iy&gf zCP5)DYQVoNJy37!z!p4rcNQL4cj~a>MHL?)2U61Z;C+bA-Tb5&aeBAPUrk_sE8BSBQomAog_x4n=eZ1W~b2dknjmA@+E|{Y>oii1TD-XU+8E_I#K?)wE zl6JW)${?s;xEZLgT~az4wZY^2wV_h4!$;af-Y_b&HHn^UbXerAVmsUX*-qXK_ho1N znJ75kI(a&n|@vvuWV_-#L3<0((d zPU0kbGc)4wn5RVp@zrG&IKu^RSCx$24owl8eIn&0uNCn{Hh8Lw;oL`6FJ`qReK=#! zl^mlJHUpl5WDHWcwnu|a^go?sI}iT5Vm^jBH!4wwqOiiTZKH9L%=};!UN}=iZj&txCAKlJAEUEb+uAGx-d7>MM{dz?VrlZel>2tN+G0N?aq8RzO zP{ogNx>Zs-ISKu+^kx3#1NDvt&E4!2Dg@kx12{>r-bv2Wl<|1A!yUoJCMT-Tc&yB( z@V$iC8PPwxBEdyagQX^4I7r>QJoLZ6UfSrEkjp#)3tTL^6Yke9>5Q#K?Yoj=3MZan zJQjKo$Wfd;MU`OA=0^#c9whh3PIt8qA8W|J%8}%JF?$de%;d#t75lMUDHQDU!IR*+ zE9I+BMeaD1d6i{x=#J9cXt_~XdZX&xT_->#t$o?Kw)pA@FVZ~i^k3<3mr94i9^+WW zIssr$;rnQS1N3o0gHkSd15KB-a#ju+6-^_a@(#&(T!?43`u^*BGyLFwRH$9I6uSs?Qw3v7^Jw1H^ z)?wW+NB`!h=io;s`j+XgzKPoDHCuCqQAkdr`P~pXW%iQX8Q}vKc~MvnqWPTw4d*Lo z2aH>Pwtfmf{__rUK*pi(%Q@7HIS#?)xtGhXusoH0s&84JG9W!d-f#*J7hdjn0osG$oSTpxd#hd5Bw%ReC^Kbp08lYG9ll2WhN_m`+(=)43{W1&H{h-HwK-#eI<#d_vo{lFXUUimi!7{ka*3zOy5^(s}#y>FQjL z%6#u{&A$p+xA;w3XxJgNot4dTma!MXMf8whz-%{0*_^v~IhHR?BD(vblm@J_>$@WH z@N?6j(@h^G^Vjlkdrc#(`RSDRE{1E%u##;=pZma&^Ql@1hnRA&>E&{#zqP-=Ij*j1 zzq;S3822=Uj6Ecu_ibryDN9}{JHBw_jClys|K~QMtg9qC_UM8gfWOm5X2(km$Wi|X DUqzu; literal 0 HcmV?d00001 diff --git a/static/manifest.json b/static/manifest.json new file mode 100644 index 0000000..4f02724 --- /dev/null +++ b/static/manifest.json @@ -0,0 +1,15 @@ +{ + "name": "Libreddit", + "short_name": "Libreddit", + "display": "standalone", + "background_color": "#2A3443", + "description": "An alternative private front-end to Reddit", + "theme_color": "#2A3443", + "icons": [ + { + "src": "./logo.png", + "sizes": "512x512", + "type": "image/png" + } + ] + } \ No newline at end of file diff --git a/static/touch-icon-iphone.png b/static/touch-icon-iphone.png new file mode 100644 index 0000000000000000000000000000000000000000..1b9b4d54a76748cd40673db1c1d956586362f2c9 GIT binary patch literal 13835 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ΞHd-piM`i-G4ZbJ=g$lkd7Oy+uiT`n3Q3QYiG`Wb(o4$07}Eya4ieCFah~ z$5`Ux4)KDW!M#~(T3Q5vb6j;Q9DwlC$W~gm(c*Vw^O^wNo)QdpldC)BWMzgi&CL?H zRx4REGiG;-K2DKwv$0_SR;}peB|M=|KV)QKF>HD|P-X>6%Fd2|`I1w65u`v}sDB3^ z6RqYR1j&?PMH-E6-ry_`hqFzXWI-X+Res+#qCN*6@=oc$v%bE%tgDx!&o|_(c3YIO zL}X^+v6DvYT3ROT&Ndp1^x_m16;0LJ5h+P!xeX3QXCj*DRTCM*%_@p#Vm$yM(bCZ| zJst9El5tb5ah+`-06vC~`L%)6>vbD}TPQF)AMjqq0&6|5r(1mZfP5_Z*)!UpP#)oq z{={3G6=!VBc(4Qp$-alw-LI^ytEqu>sy~6DfJYRD4P?|n0<8FY5}A`uYzP4jynEM` zuNZk-lv42~_iApYH8nMDUDROhL30qI6%rOcY&d!XC3S-eJ{T<=-yZw)2|ZqgWdIo! z&IxI=Br5n2H7au+H~uxE8ww;`Y;()UFc_@0yim;Vi1paN&7Du(BSMOoOoQyAAGmEx)g*&MZ2va zNhne<2=&<9TwGUISLxgX@(Qd;dm$i!D=jSrgf3Gz<(3)b#X) zOV`&p8(dsmAAmz>v%Hn+*PB7^j05CvS66{`jg1@&m_8&mbva+h@)h;86npBeKoB4u zteuWSZoX$*WB1|8Z*9Hk_}Ua^f=C?;MUev&2X`;a`S^%7H#gr@0s7qaX7Ldbn4cym z6)TLtwVOa3(9Nx(P?ScuMHM?c4j}R`BbrhaxQq0o0Zm@r`cN>{;6nHDrm^zQ34wbaeFQqJfDQ1C6pI6R3@V(2tcm7`Cvm z5SH=^&^jX{qp2D=-X}*d!;*(7`c;#wwcFbcadB~Zjg3@~9zF7S{yFI`YiU`T{Qdh3 zpDWBGcXoE(Jord{8p=b0kGcHq3`hYz&W_-7Z#>YnO9UNfb=!G>in2%_I$3$Y^ySM? z?UKiaoa>%=Y@~5m)9mc*K;?7u)J`89EO%!lYwG-n(Yx6cq9WAHcG*xv3RhYE{%JEJuRY6@HIgq6(1Jx(s>}>>SfI^kb@?{}~v!Cdf({mDRbYg7u zr4#>U?-t(Z(C+fG!ao5(@<@0sHKvLY) z)C82(z|ZSRgEoM?h+}(!H_r5BvX#;&5 + + + + + + + + + + + + + {% endblock %}