From 29881aa442df2750694823b382a3ebd9b580208d Mon Sep 17 00:00:00 2001 From: "kihong.kim" Date: Sat, 24 Jan 2026 21:44:13 +0900 Subject: [PATCH] Add admin management tabs and TV/mobile fixes --- .../android/app/src/main/AndroidManifest.xml | 8 +- flutter_app/assets/fonts/Mulish-Regular.ttf | Bin 0 -> 103340 bytes flutter_app/assets/fonts/Outfit-Bold.ttf | Bin 0 -> 48316 bytes flutter_app/assets/fonts/Outfit-Medium.ttf | Bin 0 -> 47776 bytes flutter_app/assets/fonts/Outfit-SemiBold.ttf | Bin 0 -> 48432 bytes flutter_app/lib/main.dart | 26 +- .../lib/screens/admin/admin_screen.dart | 352 +++++++++++++++++- .../lib/screens/tv/tv_dashboard_screen.dart | 147 ++++---- flutter_app/lib/widgets/calendar_widget.dart | 81 ++-- flutter_app/pubspec.yaml | 13 + 10 files changed, 522 insertions(+), 105 deletions(-) create mode 100644 flutter_app/assets/fonts/Mulish-Regular.ttf create mode 100644 flutter_app/assets/fonts/Outfit-Bold.ttf create mode 100644 flutter_app/assets/fonts/Outfit-Medium.ttf create mode 100644 flutter_app/assets/fonts/Outfit-SemiBold.ttf diff --git a/flutter_app/android/app/src/main/AndroidManifest.xml b/flutter_app/android/app/src/main/AndroidManifest.xml index 0b0fc45..a4f82cd 100644 --- a/flutter_app/android/app/src/main/AndroidManifest.xml +++ b/flutter_app/android/app/src/main/AndroidManifest.xml @@ -1,8 +1,13 @@ + + + android:icon="@mipmap/ic_launcher" + android:usesCleartextTraffic="true"> + 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 literal 0 HcmV?d00001 diff --git a/flutter_app/assets/fonts/Outfit-Medium.ttf b/flutter_app/assets/fonts/Outfit-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..90d88f845eef20e57daa4394c125b1912794e8a4 GIT binary patch literal 47776 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%0A7Mxco|+H?W=H*>(_X#gFnIR@CI|rA z3HurB#Thj744Qcc%{+r&Rg3sVQ_k0dt*qgAsNAb)3SkFjw+W-r= zfGb$R4cx&4Ji!aRp(m}pRJ+o#%vY-cs^_QKAH}9TicNWxS-6E+xP@7`g;}_TS-6E+ zxP@7`g;}_TS-6E+xCPtuCbs7=cIPqd&STh}$FMt(VRs%wbK23Ib~L9Q&1pw-+R>bL zG^ZWSX-9L~(VTWPryb2{M|0ZIoOU#)9nEP+bK23Ib~L9Q&1pw-+R>bLG^ZWSX-9L~ z(VTWPryb2{M|0ZIns&6N9j$3cYucGBGSQB9w4)vEXh%ER(T;YsqaE#NM?2clj&`)8 z9j$1mN7|VMr_pcM!E{(ipOwQhtod?S0V|;r@K#8@(Ec1L>iH`MO=x7kY{LFL!<>1R zIrAL$=WXW8qcVg!G?1P?OHZGrr#X2Iu3!Z>a0d_Y1TXN0beM*uuY>8ZjK7z|3Rnr1 z;6-`gVDBzq?=Dboi=*7L%++7YUiMd{A7t8XGK+cJjnplU)GgFb&F1aA+r+y~%r7mS z?>3W{@^u?Y)kPCaJ9Fy6D0?|Ev_M(VSqY$nem=o#wvg&if4hI!~!*m9LFo!nt0;uk0U_ zqKW&OxUZ4>8nKIOkV7@Bg>|qVHo!*M1UJBquoz} z`~m(5&%l22c^007=ivo-5e~phPzx`^E2MoD4s!h(uXXSzcpXf?`2rHWfCMjKmz%X8 z*MPo!%=IZa4UO;#oIzL5k?vDyg3s(1&?9rC^tQK3e+WaLqS41#v@l*<2j)_w--`5G zk$x-EZ$S}Rg(MQW``tre-Y zBDGee)rxdly3KAU@R>d&-t?)yKssL_oiC8i7f46>Q{84QByo}Byq|k;G+K@sUQfNa8 zZAhUFDYPMlHl)yo6xxtN8&XiCs|^XXA%Qj|p!80Sur_q34JouCg*K$nh7{V6LK{+O zLkew3LFtUrkv8=06Wjnd!e-b4 zH=(mzdEExv;bzzYJKAK;Jh4D2VLXW=<`9$tVK;Q+h@weT{$LfTj1AlI+)S_glE z*WnG?=SPdwjtNUuedA-}qzMsC`FGKBh^wTk!to9cnhyKoGoU0X) zg}Hn({nt$YHUAIn?f;FfZM@9ZcJ$kmwC^eSJvJ9oebb07ZN!!~{)jyY(-&^wIn0&);YMt3BR01Yo7>oJFQOOTg&(lrMc>rZCrx_2 zuTCj^$XHiv|7^S+W$Qm=EI07}8G0#*)Bhp#VJP=1uOwRJ%UI6z$Fn*zNcA1DO^i|V zo>uN5o$luk@td#&`Y#W5u?0Jkf=|y0_9BJe0XfI(r@-?W_S^+$`+uwl=Zg*K1%A*Q z{2>yeAR1yIo%#*sbr=kXVi*A>FcL;VDU`ujm`3{RU^*;>a-^YlVV3dUa##T?p%V1^ zpV3wgYhfL%hYhe1Ho*;WBW#8(uobq!cDNaKz)rXocEN418*Ya?;7+&;?uL8dUf2Wo z!Ctr@9)SJuEIbF#!wc{t9DtXg7G8#fa0u$*9XJ8XYJbe@DL4&{@ClrQPoW7uLv#4P z1^W9e+H;nbdb)izJ0`ENqG>}?jYz5iNu5AaCy>l}Y~e|4;Roo{21J%s@|P!cSlp%!WBI7v{lySO5#@sdDN9Y2kT)2 zY=lj41KbFkVGG>EJzII*2HW9g*a17?R@eo%!EU%6?tnYtF1Q=+fqP*O>%IGU-3#}_ z1E6Ns@1Iedu-Z*n?Ix^t6IQzktKEdvZem=VU|gJFT%2HBoM2p>U|gJFT%2HBoM2p> zU|gJFMs31sH!(g=FrzkMwVSZoO<3(FG`NW|Q_q;GXUx=NwHw*NXk-VYksXXib}$;* z!DwU$qmdnqMs_e7*}-UJY^j~&!)X3V#@FS$$7jg*9Ql0;>Jycp!Flfc9KK-I3}dyH zj31N=IrbBblnd-8w@S4dxf$(0gZ7_6`_G{LXVCsLXz>}e_zYTn1})~(T0Bc1%Ih!~ z4#hA6N?;_6f>J1hu`r2}r=c0wfw@LM>(G?5Xv*d5bW>Am(Ue*=r4~)8MN?|glv*^U z7EP%|Q)hoOKQ=Q zTC}7VEvZFIYSEGgw4@d-sYOd_(UMyHsyeiw4lSrd3+m8 z!wc{t9DtXg7G8!|Nc$=r)=oDI=sPd#39P9hj-vGJ^L;kf%o7jybs6VukZmJ zhZESh4;g6fXoOGT44QF{{62*y_zcc--{PBl)|n6+S7pcG@v~VXio#$ z(}4Cgpgj#}&knSw0qto(dm7LlK9dC{FcL;VDU`ujn1l_Q#_M%39TwuPn0BTC?PnMUkP6LzKs?WsX~YS5kc(4HE!rv~k*L3?V@o*J~L2JNXq zduq_08nmYd?WsX~YS5kc(4HE!rv~k*L3?V@o*J~L2JJb9_SB#~HE2%_ z+Eat}96);xpgjlBo&#vl0kr1;+H(Nyc@XWXL3?V@o*J~L2JNXqduq_08nmYd?WsX~ z4xl{;(4HE!=K$Js0PQ(|_8dTaI9Elv_3#cHMx)+^Bk&#^h4Y zhmW~F1*f4AK7lj#7to$#XwNaU=NQ^^4DG2yd+N}hI<)6GwC6dr=XJE_btmmPi1yTI z?cvk3dM^LSX=eC<-f5uLyD9xaO5Z_A4>EV-Lke%^?xR?z1N!cj=-zpB?>xG99^E^S z?(x}ha07Sn08j7&Z{Qn{cy^;cv0~-fjruI2m1j3rp50h^c4K9?&q|F>^6bXSvl}Zr z16H2hSb271<=KsuXE#=!-B@{cW98Y6m1j3rbgvoRJA>|>LHEwEf9TEUb-g+L=FKy5 zZ@!sAea6w7HHWvD2lHV8EW|4>XN6h8e7cM>m%|EJ36-!0Keigy!a7(F8(<@Bf*asQ z*bG}>D{O=9a5L+zxlZop2Z24fnvka3Ac2`{4oD56{AL@I1T#FTw$M z32NbGI0z@~U(#c0#jIB0U!pHxqAy>fFJGcBU*eB@)9>6*ul=|uZl=d|xySuK_qe)y z>R0D+o%>&STvxXW=<>ME_uz4zLd%Y#Wk=Dnqd#Id|0G&=4lPrbupTX|N6YHbvU;?v zp0RcgP5b|1C83@N{m)kt=3ayIvz<1qS{qia4Xf6MRcphlwPDrTuxf2swKlAp+AC6f z4PT(8>bZJPPad1GYTb6quxf2swKl9;TQ|?hv73NapY8OHig>~(Sfi-Vj`4+_5Cp-{ z7y3a6^api5ZvccrI7C1!sPn#wkOb;natfqE8VrOCVBd}>hk})};K?E1NeX$84})MZ zsB_E(PzXgZ8pgml7!MO*B22?>UkB5n9Q##4OPAppEQb}a5-RZrS?^-c&$Dms&q}-x z{^42tLt4)Mp;~j^z__l%8rNZs>#)XkSmQdZaUIsU4r^S8HLk-N*I|w8u*Q7vC+q(J z=mUWe1i{c3`auZvhfo**VGs@x5DW2;2uY9(DUb?jFc8x1w=iZeuu8hXD(M2NqzkN) zF0e|vz$)nitE3C8k}j}Hy1**w0;{A8tdcIUO1i-6=K`yr3yi}Htb8u8^0~mu=K|7d zMq15CORZ*<^*)8P&LORHNb4NZI)}74$%sUL?4JJr#U9h8d-+$pcck{;*->VmRZnN0 zqNkr?u04#ttNpaT?5Fib&zsQm3+$)$W&TP>FVx&;uIZHC{Eb%g)PQ#z*jW!Hbr@$B zITa$~(Wx8J55DsdEZ_pJU=QmHo?<J)UAco?< zJ+)BhP3rL!>+uxp@f7Rv6zlO6>+uxp@f7Rv6zlO6>+uxp9qWuI=)))I!zZw#O{`p- zSh+T_a&2Pe+QiDWiIr;;E7vAgu1&05)sBpMB6yI#euTb$guZ@+zJ7$heuRE*VWw_j zrfy-TZegZwVWw_jrfy-TZegZwVWw_jrfy-TZegZwVWw_jrfy-TZegZwVWw_jrfy-T zZegZwVWw_jrfy-TZegZwVWw_jrfy-TZegZw!IM0N{cK^jZeg}=VYXKLge}b0EzH&} z%+@W;)-BA|d@BOH1hw!o9E3yMUk~rV3G~&piC>vi;c9af?l zE76RVXvRwL9Zt{}`auZvhfo**VGs@x5Xrq!5DhWFQy;8GGghM+tI>?rXvS(ZV>Ozw z8qHXZW;9Bjo@>TxG-EZIu^P=-jb^MyGghM+tI>?rXvS(ZV>Ozw8qHXZW~@dtnplS> z)}e`YXks0jScfLop^0^9VjY@ThbGoxU7E2j&1hsD7N!{s(~N~_#==dI&8&gq9vcOAn!? zhZvj6r~Loo9eKY><1fmT0(RzHDOKY>;sMXQgZ)ko3lqs;P0ndOf%%O6F<&$4c5W8KomGyVp& z`~X_su^++-5A{?5tH9}MX3a^=3+&Wl@mhG!FbNyTIeg|xb*e|wGX_||1zf=jZr~0c z;0a#f4ZfVH?gf6(8~h;>q97V#ARXUjD6hj{I26MOD1nhM3QD02#)7I*_q~;KXi776 zK8L0pM^lcYDaX;2<7mop?EeYr2eEkU$+RRDGFks;fqE9Wj8?r#tKOtlZ_=taY1Nyw z>P=epCarptR=r89-lSD;(yBKZ)9sAucE)r&W4fI&-Oku-XKc1JHrpAS?X;?j@zc)u zX=nVjGk)3`Kkba4cE(RTYDz)x9&p0{HI5|&in$Yofbo~GQ6QcJ~ z=3clT9)SJuEIbF#!wc{t9DtYL($k?QkgECILhXmQp{s4^Y8$%RhOV};0#>Iw+v%CZ z^vq#2?F2gc1y4mn>7@{!ii9vr`!P%VVSSrf9k(${`*AKL9gUtu4(g1FI!oH1o|BLw zmRZ_|cTYOB!`Z7*>r$oB=eg_hy%VK>r?m7JqF2j0o~iRaT#lOPe3czjv*teXIZ3~$ zr;`^P-jTt1!EOP; zZt-J{ezuu1%l2+?`iTtJjMEv$D;G=F$P*7{oXC*gnWu4#)wdT5<1unkd5A2T#fKoX zEO|MRfqiAfBpG&NW73&Ea*evv$h&yx*79<`FI3-SIbp={M2ZiL%eg!mXy}Z8v@^b( zGn1SZb)-M6%fQ=rF2xe;79F1#9N(?9A(^|b-Ie+17^hM#BQqag#E3w5;mw$AuP;w3zn zj`+Jf;}`R-lAMZFt+qUgWL^2BiVyZFP_1aPWMp8pmTxdJj_jS)+rq0fe zbhP72UjzjO_OZI<=@)CXD(>M!IfFwoqYoWO&CN|c@N(&#w89}C#ba`ojJ5r1O?h$h zfXuM+wA9qJ^6be2^QMHv^j}b%JCm=my;#E11z(`uxW{-4D=S>1(u|z!A|op^DA;x`(>D zC=6-&8fKRqC|g-rw6gTT%j34s&&{2;eXOl*O-0eF(PfoI6*+Tn8arm|+#It9%(3(y zd0NPmm2dz`6rg&%$DI4hEw=4H?J0YC&s^JkS1Lo-8#$|b^SRn9*IYWJ{BVy&1UZD; zQ!$pqrc`MMKgN-+7WLNS;Yux%f3VqmENtMMIkxwEDhW%e+M_=N z7;U?38{}f!L-J-N>57WZfrdWn`?Wr*y$NOScuvZ=HscR>=F7WT3^C`NJM3Gx63U(I zTUSYPqeCQ}B`TX`mbieOP-UCU5|yTz@w51T_MYNr^ZDSe_^y2B@Oi?ncxC&{e3tN? zxjG&VFVVKoj9<>T{9wj(xqh7z)UE8WTdHN{wx7$j+B~Juo_NfY!&aQaRo^n->Q_C>o<3#!zTE%xp_0p|UyJ9U` zC)FMpI%)rpis#vmka-r><7WH<)|M(BpFyVU)|&CNc+#PyGm^Xi;uJsI{<)6F8xW07 z`OL9v8|=tugVuRrQPzi6#>gqQr&h1AY?%4o8PzWG4Y8*Q{ws~69#*-$Rp~@9ewmsR zd$Y|K6&KIMq;-HS(14?ba|c}0J3BloJ!DPZ0?&-ZF(IL$*)j60Eq2thAr5NB?sdHBq~PZn8pu2=1O%V{i>u-zj|mXs~to&^1H?l_mZa>Kc7!>C~2y)oZ~CdK{bBZ_cJCs z%0jXMv4O6^G+J4TLfO~WG*uNV$L(9X@2sP6tq}%VVtRJ?Ws>y0gDrRuy~jXF!DR2q-Sh3VcFy@f z+-dE)m(w`~IOIlck*8T+1>aEFRS)G`nemGqKHWI%lv8@~YrcH|5sL&y%a_=kfbLeu zoNVLuESY9RM=A3YX2`q7ZeM`K**13UHvKxTba`R)u}B>*&H)|7T=K8Q~Ei4+EdBfOn+Xt zCsFNecUjV&+hoC+4u&6STh54q*UyI^YNPRJ-}iC|9rfZrhhg1Z=?9*6xpvN; zIoWBhIoY|no$D}V+g$OeWUp(h(`_qwcMRX3&28JC(ctZaDTpebpUlW&zjJ2c=A!)?Fx_q!*8 ze*zPikRR^qTI}wXJ$q=$(!oY!pZrT!nCS*v^{z0UaM ze4~PAXZnA2#xGKy0%KkEbq&&{rz2%nKy*MB{;utxn?FuDeS_^ESg%9u$LT#8o{?K# zAtiksY0)WFYW&133ts_y{qMtmH|cj_zrX(6q$k3j;J$wv{WT><$i;JdT&VkXf0Ud3 zA*bsa>wNVJz>HrYdppG|xtsB`q^ncB>L)XPjx5u1S1sA6TcURHE#`Hd;h5I8P))^Y)x{Wtwyy`->KWU%%O9y>N=b8s?KKo z0zMtCddrMgZ8YO&@!A#Nm3|KYokrQ}*dozzd&PT#F-x5`nwd&pJUBXZRvS^4mcyYBgRjOa`9k8}*} z?&Wk0@UHSy>&)_I^O<(lif~4_o8+WEJ4u}|i49}aInK3Q4aBNgzVnShbbm8v;0xCU=uOC%<{fL2+vv;$fxODQcJwZo(I%~P0Oi9>`-QO8ItDq~krL(1Tuw-5FKkrPvq{xg-GZN(a&eY2#CsjJ~ zw)F0dU&LvF&UoY5&RiB}J7O)H>C<>|o7|3kty;>gNa^cXzRg#CdY>HuZ4Di6gr4JK z8CGt=fq5M}i;g~*MS0UQGN#I z+HG^p9ydef$Aqy9aGW}ISmAEoOUKTT-bD^6T~l1VrZj(kR9WDV=)|GX(L)oXhXj^I z&G#&>LbHmK6Gr#z7dtFDX?SeEexnnTk&n(@>(f?;KJDPuaKyJzs@{=e2D@Upoo>pN z%P;BFl^*M1eAB5RVfHlDTKYxR$10cIp!&tErP2@;>n3NbUhEiyx?dtX`{j}`*liHH zMl%X~XLVQW#KNek!h}RM3S}^Tbm=&B?hrK){SHqoKo@6i4@p6V#M%$I*>H{Bff z(}}lmRxC!H_0nrI<%e92bX?`Nwx^xV)MXMfB9|_`c)a_-??Frs?fn+*?XE@oK}%## zq+7@Sg7zM@5{H(p8Bu)w$Pr71SS+@6@|r{=EH5FcC@Q8nId*8!sOWOf;Z>#Ra?y&B z-u-&bj7ceoh#8)mS`r)5uQXAuyp^tet2O#IEt9$YkF^es{+4e#jWu@$oMgd6pC0Sd zsn|bQr(qrX{e5-orsb-R%C@OGTIGTv9a{dap|sqLoi*_CSf%@$v;{NU*^!5voWuWz z=}NEcqnXQ+3^O)g(hrVUH@Tc|RN)&XIc+86pN*4PHcl00Dc{^_X`~;w-IQ_Npp>Hi zrQZC@%;ZmGl@XpdB|R*()Y~^X;bNn_u^b1+g4ELtgMJP`-}Jsg$9`pwIq#_n@rU$J zx{j-gE*mf=d-ym;;jpSn!1msu7QGh*<%Wy`nO zvPUi%+%UAVq-4d=v}g&%Gj^23T6=p2$0tXGrF!{}`7y0B_T1#@?H3;wo|YQn z6WxDTS1XnFs8%XHxmD}EIz`!rE$~-z3t6-@QAQ+NRGAkV8yh+xCPp^eB8>dF(9k#q_J!7oC;8S?>Za~0tW+tm z0v^Pl(pKOhuB>wIC&-9Ts|XpZ$DJ9w;2{-TPi&YTcV_IYyHxDg+;_w&?VR_C<;+%^ z-jk2x8|siUXA;lzYB=)vIrU%-(y`N@t9JU=R2n~@dGVm5URHMc59^hUx}TkXzI@ZL zZz1+iv|fD^kkekjUNu^+0ZyXu$r{d33=8TXUpa8xD2G&zMTD37^@@xzJTHEgH#Xkl z*(o5-)2O_kM?!u**Q|Zn(=#KdeAwG}84gvZZLghR4H#fQd%Qm9&zn|MK z47Gix6$JSd+V-eB(85QRd{__P&#R-K^o-=_Cv`(dKWT6NF`a&{{S&=*P$jP-eH`D! zq-QqAIyT0(N4%-?SMgR^@m)tfr|R61e#i3y^I1X1g94?%^bYx260uWCgA+}i!RlQ) zCc2{ZBm1C06zlzhl(2yek;z$ElhgTQKzeAAYwpyn>?xV5Z)I3|PTy2U%%s$mN%^+= zOaFFAvyHONV1zKz*F;#+hXod3SUc<-FqE*US$YNk0ac9-vsTKhR`FK3I8N7zF{9e;$Mf;{?shgyt(5XE?*Of2 z9k)BXCevSc>}` zQ0Ft9a)4VO_Dx zN}I8>^tz*aS~Zui=N=a`4~zO%xbRNdb@^~Tw4rlH=1OfD-my1x#Wu;qT~9I0dMRJR ztnHFq)t^50e;D!dB3A+G#6xgAPcfY5_8#grwM-r>v$bA9zytKV!>?GSPH8I5GHbFp z#UV}0E%dJ$>&B|>cI2kkYxzd3*0`S6Yi#KUx&`+R_+PBo4jPZM7O=f8S?u_iF@N= zbh(m+m2uZhjv3sq%qJo+tw7sLuYjLiA2MK!ulL{%%kfJ+ieA&BWp0V;M^+8;msm5E zYrmfI?J#8B^MA6#iYdF?RgU~^*O?LK5lMZ~C$l^?k4R2~xAWin&a0V$C+?jtY<8MU z_vJ4S4P3BXClkgL1&``CJTW#dX3)?cm~FYjv6o^C@`pR zZ~ySzxuVayASFD=zm(U94e5`LAYm08{fv%%hj#F4s)4tQs;4ZWSe8Syg_X5o3zF8l&S7)YPG+W8mh2R@xt9r}a zvA3N5`=;NPJ-+tu*pZF$R$BzA-09l$q*AK~Qn>|WsqJ#TuYc%IRokO(8g^6E_NqS( z+a9x>yM8U@91g(9+1LjTjv{+~zn1-n4%wg6vNz+El+E}BJS|skFyob+&G=br)zul_ zm3|K2P_1O`O)J!Y#BrQHj*MrMC^$GEk|CRiUoBVe?o+$-hJZu1{;v<){@CyhH@)L8 zE&F@h{vmxP9y~qaS*5vNcD05#^AN!fS*XLyAHBQrj_AFcPXG1(q8YC8pPVl%xAlKR zX03jM8tJ=q%RY9r%+x9~Ue#2^A z*0!x&M%!+eHt2ei?y~o0zN%ejX|ty}dd2t@3#HB*$0=*j;T}foB|)Ix0I^)UD{@ojPlgnXjh>Xs z&nL!SyYmK#;W2ndcGk>6Y1vsR7yqNIiET&s9TU|`Z+1)iId)xQm38kZ**qMKMN|g{ zSps)#NHC$|RRuUL1aC?nmlZdtUzulcuL0qo$PYF;JIf`Gg`ts^J~pLaaGASD)PReJ zRc$Wr@4i+v8oJhs)C)E1s8?Tha;{J>YU8{-zqBetJD2O1mv7slCV#_eg{sGf(FGy=0{<}JyKyLjFqT(z+CP@b}fA9*NGIh#+b z7Vt^bYxsox{2%uFd$fB2$X^|jxU6IJjN#M|0VKKN%E2gcw)^v43%-50^10;knVlW? zTxDMW=;;1%wDQW!jAcETS$T_AE%ijYdnYULy2plu#40XcP?H*RMLxczPVyPuDW64r zFZ0h?uVG?-Xob|Hq|~#I9;KxAoMSJMluCL@DLwDKMmjGj)FScHy>#_F?dnA@^DmYA zck8WlzH93g{&SV`H$SxVEZ@FtQ{3s{-4$0aJ@uZaK7w#r$0?P*qkG?}gx|a6{X@I( zYTv_0^}o;QEB620{9o?>KlOedJ==W&ag{^t|D>Po-4-i9Zdm>wcC6>6%Othl7M#vC zeOFG#YFnfx3dDs6YpnaEvcrdE)=>kWd9;_jPZk@mV*^6e*=^>Kjva*Hz>cTXYzcG3 z-0_I|;e?^Fu|pHm3Js$mEG#Y#;%EE#Oq2H|lq9E=B;>}ekIkEy7!i?>7#@*0dP3=_ zG8@iHHye1(cB0eEJB0=S=&YmykB-hpL;*6en^Mvu+Cr;Wve*Cs;vd1MSkI%{)pOiG- zbH={P%3n>N{;O4$`=+nRUp;lo>b$&FQ>U)ZS7or9Era#`bLXlcEAX-FFaAdzeKV#m zSwb3oWcd~K=&PQ^=E)*H(W4sV7T&MjZxlmLcAGx3*)Os@t)u zoV+}@csk#$ebn{w6M8&H_3+EP-)NT4EcDFEm=JOK!6`Yvit;#gGcI2mQ0 z%D@lE!+X}JGTczE(66`KZ_JR*f4%-2`MRxW)TqcM&&hh5-VF+*))%=i%-o@JKB?Yu z7|gMWiWRpgr#wDBGVrU>RaAO>dP=c+?wK$&%;J}nA2()E_K0!+_p(J_VU>1&6+{M#Wd z!3iCUa#h^6*sH#7kjFEObr*M|G@~MsYb^4y8-HQ!WvKnpj@d7dXP=!9RUxW6W=`?CU%q+!yRGuI@*f`fdKG8zfjMO2 zuKfRQQUV16-~$NaNATfK00am;5d7-L zk3@=pQT)piMbeTf+tSqfq_Hfiwq#3DWT_LoiS0JBr%9YioXB<(H+5yjt*eaOk*aBv zG>JR$c*dWxt9+c=laBb6D)WT+^j>n98I3VZk&S0%{Z;lzW?Mk}cfB*GE=d?xTdYx6bo^SUzwVAD>hX#I} z3lSC=8n9Q^-@ow2Ijx~sXEd5pLRE`sk6DJIiOPOh2N_Ohlpau=^s+^5IaV=^yr%-i zC5Rl{w|9QdLQ0P9S{b^u`lFBHaclp^n>SUMdsfiw%L+s%Y!?A!aH4u|mJ%5*qR>Hh z$p#%fAOj=^oPg-@A&bwN@atpbBrZ~wdp+M$RITH!j*4QwFj!Hp@g;f>^z7|>`gZ5` zETVC*^v)P*^%Cot^i~Dmytb4#7|PXLqHt9*B5ry%F+SeXAGhYB4oM3hv#&9J14)Z& z&vd*dFcf4*n$lF(!nY7)Nh6iaK6^ABD-Peel?MtE7U?H`z&10kMP=c%fkl?&R-n;W zK93fp|Fe6|WGeJx1M4f}t$FmW%+m2@c4!I9Lh(!dUJ~Sc$WjmyWFLsf9X^QMK3{Rb z?(q8^b}UqCVc!co9sO-36)%c~h1jJt6*QVAIGC&}$vBw&h3qrps8M`IK;>p+wYW*H z02ZGQE!VtrN`XwF=V3tNSzI_|u-U8nIoc|tdB;}3Cf9f+DwqZB%=JaDw7djEay8RF z?1dfRrpThI@{m&YdwY0??U7n8Ve>^_66nh{wj%Idgg>_?hZsYp2TKDAl=sQ|lIahb zrs3s)U)jFF&aP0Chvhi8_uZvKr75N6HS(I&%Goki0TsDM$PMV#7Ampl#1G}G1sYM4 zi_On0&RPpjDgqk~y|(*1TkcAPw>LzJBWVP$nrm#fpeY>MuzquNB$XIUmef9;i*Zo) zlEm78)smhJQAtwNfW65IRyhJisW)A2M;02V65-)gqJ_*Yy-JiBA+(Y(|hwLpthAU8HaI$It#D3{9u0%@U!!d3RmF8~k z*l~-#6X<_*-4reUf}G~?yE>pAyw8h>X;ymQt6p>Gk4v5w;3;uR@6QsG{Fr*OT*qlw zjMfzaw}}i~pPQp=5i98<63X6x;pXHdyMIe#CwvrQu*OT)L`AUFnbP93D8~ zatt}EjtvYC3;uikDfb$8v5@i~@C(C$>HyRl1u9F#LBS3d6$#$Eut|4%dl+VNkmhP~*zZNqH=G zAOJVgU8r+BeC5iOo$AP)o5RE0e+>^)9!{}bvvT?GjeoSHJl2WAlet3t(k?ycz<2U3 z@GT7qsMahXyOAnDULj9#$n8$Gs}&pw3zqv7URQht6^2QQ^1pLG%J&C!=6?muTAb88 z4Y^K+xqPn>mfu>)XVTKA`QORE=IZpa8~_0!x<95 zvfZur^U*<{9jZR^D!GW<6BuWD%BJCC?0R}`ZvXuJ2)p)uUHPMXh#fWlF;heI#CVO9 zUEiIb-#<4eU1x9EDwxAKW%z{EP$0-{vm$h5p+(jID$iL<_G}XrViS3T%qz1?MX+nJ zNF=TKuvx+j4~wNw=!>?6vZ|L^S(P3ow`U6AnO@bVUc-F>vZzV`Kh?k`hZKI?_Fja% z+%BcsK5qMfkayc92nq$rPj`v?A(uduuZZkk?KEF!HcC}KgZD7wmh2WM$E{H&l;gom zLtNwt7kS6wv3#g=Jq>X=xcTsCG&X*;ZSu=~I{jp6Sy6nZbL;+w`n~PZUVCHk-T`;3 z$J6SLG^7G{L9oNdc<$A=OG>&Yqa%mg+EID%uXhI8ZEAfm?&!K(Y~0_yb-ux3X>xmi z;MwT&Z}irL?+b;t`W#L#l}I+XwRN>^YLoC=X~?bj33n0J7M^A`b&`y&Q%SqS_$X0q zFbZFlH%l$Yl}axOLfvR8*ddnnl*a^jU8R{ElD^cjuVM4XnBa9bdSV-O9mWm4WS?(K zO?)V74Oh0=+%;8IL8~-TEZ)`JGHu^zXsD@Gou!Zza{jQlr5(oK?G4Sl9PK<*;{dx+ zH`2D`2J#%G3lE*?bJ}fHM!veaF4pCXgxehshsEOHP44DsWV0aMsSV}c!qUyDu+BVcEq%pqgm?5_4Kxr$fq=QVq4G2Df+%CHIYb6 zrh?llTh|3EY*aR}Sp(YE%AVx-*`A)W<6~#H^_-!3jk>x{>`KtQDqSaciGLd(tFIr6 zJ00uwWtLipqt;^7t#?!%96Ud=1Sl}x4)Gx z{YicKvieVS=2erkWSaGy#+fhebB^WmpTiwKUq@KJS_Q$17dh)|58?~}Cjr5B->|RJ z?(x_w;d(`ok@7*+6*UK3+5S8>eM0?Lcm9$>%sv69V|~E>JvKc(P0nDcK8hoETv5(M zQuv+nORx>37-rd7zjFLHPMq?{aM7RQJ*8f|)m3JzcG=48bq-fT=P7j>E39R3M7Nf0 z*po}7l+Eff@+PCMT)RfgyDYXKZ!vmwI-`D_L0htp7b?SIK_2<=+sCS6@*Z~?T)~NT zo24GlGKA&NaP*P{KQq2-ws(5v2(MB36o}@WKggAHootR$FI;Lb$c4#fDP(beX$%|7 zkAeH_J&>9b#mR;Sdc9pgQ9oo2n9TueWzb{_-k7YPkWNk1PrL)atBZ+oteiv~*YSiS zIa%+kfJ#$iuBfqELluuq)K8MtC|ZwyI;s)yNFA7&pK|T2CGj((_34=ev2@)Z>b7nZ zb0YSe_f~b=T3pFSp|QQAQF!=xFXG|5{dLh$Ud(=Xl{*l~#_W%>$pw#a>>c04Y|i-F zF3H)JHzKeZYYOlp-|v2Kyta1y!S0@e$i&p2+_Xnb&UT1>$lP{RGLg5fQX~11H8*Ek zwWsyK)~yFxz17IzMlOzyz5s;)bG;d)NCJL3`(3`@33ZcGY}HSuW?DPPEnCa$g5XL2 zMn05`IK z64M6{f2a97CqLYI@G1L`$(_sI$H3aYD?JJ4oqp*LEXUqEqodNNGRmK?M{&qedN;WZ zIfHrHF^3AuX2>hj?`LL+6-(AE#pr5}6Dzq*j?>jnOQ8gPO6Ntr>H+d0=apL!;b*Ky z_Kf2lWN$~W^jrrSe}H~O8lUkF={ZWlxM~&BaOX;1O3n4-Ee(<3Vx6$WuI}cHnw`diq_Ui+-r40X;=!FnzoLWdx%Fhvd)}L0N)S+_AYMRj(}v)cHZd(1JJ0$uh1OabOvtYkssQ?F6v&|A^8mhkdipKt z+h-a4TC$FOOuorR82JV>N0YWpp1~PwpxRZ=`^pf{70CHa)@k)xgQ3Oeli$5CsnTA* zfL_0t?X`!>c;uBC3}4Umbl>mMn;P;{@)gLW=ri%eG>E0wlZN|3_m7?Lc%1z7%{Pfg zVmrmy;s&z7e8u1+Np&s}<02a94zBn}j_rS7a5&!R_0{i>4E+=L%)+jh_Vt_UqtSX| zl-{Zzt;1ZV*>m<{h0v35J7#u+Y=c+ixrE|DnkSep+lg~_r6{>NFSU?H&w97J)$65K zpV{s(nQS)c@EV0FoJ>yHdme)=jKT50{%Fa&T@nq~*mIYpgdGo`aPMQC0s$^|m~ zFdJ-~aE3f4vrXGzO?jLlFJEC>i;tXO;>*e!oF3l9-sHA6kiX-eVj~8{%}WkTrxDl3 zpcJUCA&wNIu!1e;8mtsKL7wVWODr?M5)p0J7B92<%SRE1l(|NH>B5p>qhpSs3~#q6}*wJbM~6N&0U?h%5?R`YqiBCy4emJ7x#MVXkQR3 zhcmuajlodLuddYkZuw&VwhDtGYS$TyS2e9(N9|qd)mBKx znf)uhW(pCJN}s3KMIoY`Ajyd3gO&9 zn&(E2>6WrMc;On-?k1OMW5(u;UGdo5Z+Jh5_wfY_@)zYgFYyw><8dLJhRw=fOkTnp zeg@ZB^He*>Fn>n;fJvOo5;CVz{uXcdh;`Dit}@*r>Bth5asDU#};xOQWt_v8sDuJmswO zdeZVeZ>?N!{y7=ROGz2{>I)fMQ)aS0m8FI3mMwO?_*_7@_+oJg9kBA(A8_%v7q2p=ImpBB=CqZ`t4sS(mThK?!|(h|oNkKX8tHeI=5Ggq7u z(zO>?JkAvtxndYsJWX9XiXiIaEj-EbeLm0T^XK_IgwG#z)Fs(*Om!Sn9LHJII+$}0 z@DiN}!$lNfjOa#~EHVkR#X!PgVl3f!F`aORm`ylW+(o!XY#`h$9wOW>b`btfJVjWF zWTe)J_~0pAeoBUl4vNz9CdHGh`3hgZlQ7eF&ALEl7GEBT~?=9UP^T z8|Tl;0LQsRraw8(4eDO&IJby2@w(&OsZ|h_@0y#c}Q>GDNK7T*4>|M8SptgkE*3(?tRu1^+8yn2wwOmZ&L zHCZffBd#m`*Hxs@leb@!awd7?lfK7qls1~uX3?Vgq%OWDZP+hrmP@&d#0t_i$tH}F zlOUOTjzt=U99y?8OpGFR5xP`}WJ>rnM@w%uajK1B^o^2nYZ=aRNOlRj*p;h_kiL>! zi`3^3cWq1;6= z#Em6A_JCN%7GutW9SY#nTFO4g`-d5&hsoQm)w{!t;&(*dFXA?mOGmEuMrPlV+tcDa z;Z9LQ_&Y|gL2jxZ4`U4vb7t03wbGr>B-Zqbj%$v$|ES~trDiGeZi-JNHh^oWHKWWT zJBmxhcnPa?*6%J#t0PwR&iCR6!lr9gNkPiKa;(v{e3*Kwn*FX-DkUA$rawjO6WEv5 zwNd#UQPlb1@X+N3^tiudX-QuGpo#W<|jCh-V5t8D7u#R;QfL{@nST^F?cx zHP5=y`jGXsi>FJv%TkxWxV-H0oy$+I>8?4hTU>Xz?sRQ*b9ak(%W#|IHq))x?Jl=1 zZadr#yM5wT?RLT4a1VFy;-2l^-~AT%rS99^|K$F>`y1{D-A}vMd$jk6_Q>~G;IZ7} zfX7jflOCr%E_ht=boTW2?C3ekbF=58o*#Kude*e*+-6RjC2jV#x#T6h26~P5y4`Dz z*AlNaUiW*w~y8-Ryw_D!s`F3x#d#|0{C)uZ$&mf;MK2v@EBCN^!`g)P51ZgN8TU#e&qQmm#DC)?5M#}w?-93t&Z9rEu)7-uZsS%bC1ps zc7C(-H=QrWSYsx}Y>lam?G!sTc1!Hu*!N?heafxw#;zq~KjJrGTnYcIOK8S0G z9}-^}zb5|4_}Ai3#MdS`Cv-~4OPG`}J7HPChkxC zGVz`eK=5MH}pVHh#!%=^}k)2N@}2WP(hUnXM2P4yX%Xr`T z(&A)swRl>5EU}>*k?Rj(eqq63p%%0e;dpQ zf|A0R$+|QC{wCdJfDDzLWxVVvGi0{RkwfGtIYrK3WPe};>5>i^pIU^)YH_Ee&Y^24 z>0+2~SWs9;T~cgVBs%o#|zRvhM`SWn+^IDcOiC9NlB4mX;CmZCyM(xEk(;pAlii8oiA?V}P;H zQ0o=`j77#uW1Vr2J|{F-lNei#hxLc80^=Uz{+740jr5Z#^h`fF23e(2TBHn?1En_- zY%4p;cG8D_8Y+h&({$?91`F*g0+DvOh{g|1!goj&S@d!rtl&_*qfvOFw=(a~zz>)! zis*+Bdi@p|E*CPp-;GDQk(umaywS(BHQ&Wd@H|%Y73R@0X1IgQQpdzee9%ff(9<$X z_L9+Zr1X;h%%pkrW`DFNOU{?sqMjZeg`Hh0domllA*~`g8tn>_%cQILr|c$~ozT5N z=63^)^w6`Or)Vcan2&-*2hjz8BVHt+xxGX#TAPD6-A@k2ADJR1iOG0n^TZJG54@%l zu}rLH#<>%HUN0VGU2(s7K>SfWDSj{hAnp+_;n%*(3T>ZwO%4%nijTwx;zMyld?nr% zRm|-x86!)Wy;rfCTgzOvff;+9@E7+oLv6z2-Nr1w6(9d0(O%rgn&c5?v>nVYkFr8} z98c=cjHRdWR-Ry7{RyA#FL)i#;2r-}q>E?qAD=_}Ul2XTi};Lx6TQXDqCYcHo_K@# zaX+iZ1NdO?i4o#maSQX)7;#997XKqAh$CW}D90B)j=%Pam?}QTldQl`{S2S-Ykapw z;tamtH{uR)mf3YFzRUZpsE*3T%x)!exm+R_F}9{Mcg~cv7-P3Hmln!tvH&aa1%BhF z_@|%a+f~a%*+s@ODidU!oFvD}@p2*-V4R#FZ#AA51C67??`E-7l6ILGWc*D;|AIQ= z?IO_NXu(1mlX(AI^dqgih;EJX5!ZdhbRWcVvlzrNSO(cE;1uV%;Kq3+$F_zPzQ#+W zQzTx;Owrvknz&Op#u6r?{sR%}GpF?;%9zddU`eCRYdCLBw(vKu=QGkQ5dqEY6@84G z;a%ZpsS*L#V;n^0&j_DiFkXZitr;dd8aIjMPdaUP`5m&o4xLAq2(`2)%|r+h!M}wp z74AkZ=~|N_x*I9jyq_2~jf|2;Mq#7O_pRi9aQk!Bdznsk(}i0%$La}1Vm39suh29su^@RnDBBX#R? zQ+No&g0Fu)hKF!9ync!NSOm4kIF3ALz$}<9+}*~DV6O`3K^tD8E;Fg?B+B8|O>Y}qI}%5%(9yBNolL=Ra@-uH_b z`q8R6PCq2mr_;EWy&;)IJCZ141nagDB1GOQ`a_t`zn=U~iO$d!XQwm!4qdsXBXnRj z)Db$!H<<~46j_!O>_MG~HJ+tCABseytw^#kQyQ@%%lLqHY!TryQjAv^uZtkVowO6F z%V-hL=kCTGqKEMi`BP71m+By`)p=8#I>xGac@&urCci(?#)ldECIPL^Rh)j0r8JGgx)Th;NzWU1>=nW&A@N zk?zb-9@10K?LXn;c!>nrRwPPqJc|#Q>HZ}?RGtm9e^)f78$OUf+HzWXGcpkGp}m+X zgQ?XCX7O2~9RH{z^YV+#@u{rX(?mKxO{nZ7GGrLD;=l22B19&hQZ6uaV5O<`7*WqWKMv1tgdB;M zj$;1*S>A%*HUa-?4D+yqlQ*H3^eDFrS@hD$q*Uv+E;>%6L zBkGIa^FMfKui>e^A^wWTr2I{1_H&luXSv~p-Gk?){JQn{K{awYKHA&DMXtbO-62;B zFY!;&fKR1--%j|i`B;@4xk|XoJLPItF?X{sv{tT@>*WTyQQjl(m7C;dxkcV5@0SnA zt@1&+O+F+amfP|3D)BZSz`y!bRO2OmiMRDRo??}Jgu4SfBWUh3tg5hoRgHC zo9B|VAitovXrW6^(X66{h4b8VXB3s>7ZemOEV1Sl zRZ4P>b(|JQn{n4(u873VK4^tiR_CDnaaa}uZ7O7?T+y3BDTozp65N@}J<+L_k*ru62w$R#;7*SgS*UDzr% zEyGes9~509sv=nS-2lKN#kjwy~~sye15Wu_Uqqs^$CBpsERY<`rSlH}BX zNpX>mOi4~R6ZK1X$uBN0TDD}7j!(|cbl2~TRjH1sEH@oBqiESeM@+UEGrw?VQ<@B& zU22jZF-fUOnQmH?1w{*{yJ=~vGe??!9?FcQCgpa`pRcdy+-wGMjx`@M#K$3AwO8OBNMy*smmH}UQ|{s~solDXQG*Lcbr!d%>&IXsKGKM@Zjj5$e) zyDjR9bH-l@FBxwV{?(%PsjG}nb!aC%XK>$7Jc-Z8T{Yw1gu9Hl3IA!7k+<;t7>>aq zH~{-#Pb>b$`LnPSeow8hy`Slz)=T?I@d#Za3&hiBFavAmXe_VoyL`Nb;6 zxmd+G7poY{SrtP_jODC~VSP*tAu+~y6@y1h3?VV%ePRr)ZOwg%=gcSam{HE>Pv}%n z=yPZ8@6>W1=sP@7-OuW-lKWD($-?4Ri!K~;8{(Gd*4r&hhbcNtY!!Ca=V3Yw)}fi+ zPoI0~(AAA`e^jBH8PlL+YN?HIRjm`QU+Iu%6*&Lc^_c4+*8@7-*DBnj&;O>w zXLYz!hi3ZUyYArHZ8|j1xm!WZ2G_e>m%A3b&Uc;ZI!&KX(&1Pgj?m#C9rn|qPS15c zbzKNuGhC6OYmyGlb2E&0jUqnOHHgqhhn_k#W31|2=fN`@t~*@*<#I`f^*XH4;b|RK z>hPor9Vt)fm?JKK7s91XhkJEs#=PRfSaf+>hkw?g8DoY|xIDtATXkrjZ*p1Zawm6k zRJcfob9FdFhf{PoQHP^-Xr>>g&j+~lCAaQ6Ow(ak9meV~!lfgh2I$aRhweIbQlV8p z;bHwr$-sJ1hu`V&oVCjOxwS%v$94FRR^fa4{4E{6u0u2ZOZxmd9qzLJkvt#Q;lnyK zWA4}I_qgn~uCcDvVM(iSp+29j!|6JltV1*XIV+>edR&L2bT~wX#N}Cg>$_sTttt9E zQHPy%7^Xr;n&4LFepWB5EAeXH(4q6s);yl%`B8`FxfwP%GY*{3Ix_;CKh@#KIy7UB zwK_lKe8731^Bx`kO^46waHkG`ufrWW+@`}Vx~vU4yi12>%yMO8oagJ1`+uC9F=jZ; znbo{=>u{{|2Y@208nXo2L$~Iut5&`j-wbIn{Gs zqr=lWtkmI29i9lO;L{^I{JRdzbhy{)725-??Y~uhOj5Y1ZmAYjv8nI?Y;DB5O01#!b!R zgfHq)<>{u=yXo|9YECCcPml&da1{tEu4bkO>=z50eazk{vAu2t)$g0E;U1Es7w!OZ#y-w3!*GkmRJs1nW)z8cC1d*pwl$yGz~gUgHEHKFO#xCrG&MomK@!R9Gxadwx)-CogF##1m1Wtm%X&xgn9z6h@G>C@V(U&c&qiZBWv{&cw6+- zA`f%Va3A;d)Dw7r=I-Yw>`kdB@LtzX;O*DX-u+!ad-p%=cnLgtL9POSRgk9;3qkc~ z6Vo|Y8mMN$QPh11e!*L~Fd*8Z=iQ~M9< z%znD*eaq2)iTI29(+|~|{eKA0shsU6?Dh7~IX2ioxBtcdw*5u>AMC$VY3=uc&fCn_ z%+0R7+LoMKpV`kl(x@k;gevo9|Li=8?D%6Iv8xfnpZ$~$535?(zqVKZGEcKjI&lD> z;$t+WQS!1g`x4gLFPWbp`(OOoU;IUsBf`GOUSr>BKMa4cbI-&6zWp=%Q|d!x^_+c& zKBIqH|CxQIKWT2geG^yw!G6mANBdtmyMn~4?Atl}OoZ59;Qm@D=SbD8E!PHdu4-@Q zjYUKr0|{S-FYTx8C+%u|rurtxUZc)h{v3V$byJMJ+J4Z^y;=JX`wPu+s_(z&lSb9U z{CTPxT>EE7OUysJ8Uup8XEobi^VdrD&GF4`5UNx(T|MvT$(a}0?TLlx#BQ{D#xt0m z=RxdaD?1Ra?LZ24U?FzmF6=;0{p3R~Pd+@(9r@?kT^`AJKTO)AJn>M#(|YHy6}7w; zvAVm!4u4zjSrl{kpo=Kc_Xw8DbnXwV%S$wmbI<3Zn?L5Y$ZCF#<^8oU_W&n< zoBvOKD@k|#OI_Q~Z@$kypO<|8$ZJEpt=^m3x_c!CxU2VGK3<+)Mw?4*jzu3mT$w2WCPi1u!4|D%9RBV?Kk|%|DMk-1? z%KgU9+^15u;xVmHPclj}#2@r1`4dlg^%sBEV`UfjtM26aAuHtwaS_}0BgaPjcRV2> zD4B^{T(Vb*ABkz?(<{Kvrw-Nom-tS~v%&xiIDs=*!3A8w4cx&4JfV&KYvE;oU9<&n zXa_#vOS~WWLjVLq5VVJ2=l~rd1VW(`gh4phMnEJ)K{RnO5C`#)0Ey5AxA&hVIYg-~QaCKl66 zC9njR!ZKJ6D_|w8f;(X~+y!f3Ev$p}umLv0y|4*3!xp#??uQ3pD?A9>;30U}{)O1i z@ez0wcEBs}D(r#R;B|Nd_QIR65B5VD9E8KAR&v~eUZ=sg-b?}|NLAJ4fF4OJbN%~Z-q(3}F5}wK^ypexcdJ!|wX=6oVg6 zV*0Tj^24J0;obP*-T3i5fFIV~k2S6z&jt8#55yN-uIElwxiM9BW z<5%!CR6#YIM*Gf@<~-EEx9~mw=tbK7gVI_1etbhe@eI9ph~7Iy?;WD|4$*su=)FVq z-XVJL5WRPZ-aAC^9isOR;XC@EXSL{XEjnC_4%ec?wRn;~u4}Pu>VfOUF_w+&cYtj8$biWqe=b0jrK4`})%)dU|dGlcg=J_p1hYZMsEXaoL&;xoxFX#<@D5EdrKtITZJm?PtU?2>F z!K57mLpdMDaX5^Ck+9fafgP>Dj#gktE3l&#*wG5?Xa#n(0y|oP9j(BQR$xafu%i{& z(F*Kn1$MLoJ6eGqt-y{}U`H#kqZQcE3hZbFcC-RJT7ey{z>Zd6M=P+S6==>6*wG5? zXa#n(0y|nEp2xoJh8N&(@FKhfFT*Q*{wnN&*Wh({1NOq3un+dbTcmv($~b?A;{kXV z-h+dzJ`Ypw5jYCRSZjR%$KgXb0UyD~P!1LF37lm8eF|8qp_!-A%+qM*X*3fr20L<& zyv{=nd<(T)QwQJKYp}f)cc`%(XvB(}?yoqCJghPb1pX zi1sw1J&kBjBihr5_B5hBjc89J+S7>kG@?C?Xip>B(}?yoqCJghPb1pXi1sw1J&kBj zBihr5_B5hBjc89Jn$w8pG@?0;Xig*ZMLHVNh=w$xA&qEABO20(hBTrfjc7 zh2TMXKV$R$h0XgH=i&rxusF;ykIpC*Kp~ zdxF(xqx~G$)=`%_*3;jU^F`8KVq9F-=|3TT9Vx0wQO$LSxlVl#un}*iEhEMoy*GGQ zFGFb=cS2~3Rj8e=M$$WS=DKRGtHwV5|Dk^mBd65!|Z!)=lBRb3OnF2@>ctZJ7E{+ ze}Sjr8F&`{3eUmwup3^0zrl;}61)trkk6~I2VR5M;SJaeZ^Ay<4{wq7Z7AdX9gYX! zU3d=;qI-v_-w`+pCwZ^@xk~tw^RM7*sDf%Z&77xpM$bbHe9M#XZS8NNX>ZAP_KVU7 zLhWZ|B;RO=M)EQCACZ0?p4wuxwgi^IQdkDdVFj#&Rd6S)hPz-5tc7*39yY*6xED6T zX4nGv!Ts<6Y=sA58$1LLGyb-7d;}ha9qRtd zg_Df-Q}kG+{T$Ny4(WV{biPA6-yxmvkj(c;=6fXbJ(BqzNt|!8AxPl|JdMSS+Y(p; zOJNx-hZV3AR>7UH8t#HMuol+Ade{IP;a=DTn_&yw2lvARuoWJJZSW9mhezO1*a5$z z-(KPPD(r#R;B|Nd_QIR65B5VD97In}B8gM2`lJl?NYp8;1IIZ>I40>>ezCYWl z)t9k22f6ALsVb3?N*QXeRT{z$!9l(!Txq{TtkRo{?8Bw-St=#XM^@Fysv22UBdcm; zRgJ8wkySOaszz4T$f_DyRU@lv#_L(+RgJu=kykbHszzSb$g3K8RU@xz1#|zpEa)zW{p^j|G~S4-d3(s#A=T`hfAOW)PfceV6gEqzx@-__E0we(#reOF80)zWvh z^j$4|S4-cWLEmfXyIT6LmcFZX^qcCN2KuIfzG6=>mrk1{` zrEhBKn_Bv&mcFT_Z))kATKcAezG`lf-tX`pW!9DQ>JYjFl^aR#6GX8YzF z`sO@+Q%&D|!`S+UvGomO>l?<_H;fI{H)pUcXRs`1uqYW=q+k(AG!FK=!yOToigq-83?sus>FzRmMy#LyZ zyU|MW`W0ak+I+LCHnmzCPx=Wk5ei@imQC%(%;mFrFdr7cLMTG&i|LgTSOQC787zkt zuo70mov<42f;F%f*1>w%02|?6*aVwl3)~0y!vnAt9)xZ15Iju1wsU+09)%t73cLz? z;5B$1-hjREChUX#PzHy&{sMGvo_Q*V*m z%h(3>T^Xr%y1)WX;0#u90atJXcklpDXoDs4V)v~rctbnz0bk<%z#jr25Q3mR1Vabt z2qB@g=_I%fCd2J8 z1*XC@$cO1rz;!d|-#PY=b#Kk%+WD{m7D5qe7ISyC1eU;3SO&{s1+0Wsa3`#WyWnoF zS;KKHtb_Hi0XD+Dun9K97Pt@YhX-IQJP6z1A$XW|-FA+Tz@xAO)Xe&yXVe<3b`4g$ z2CH3z)vm#6*I>147#E*0EM#b=C*&lneP7-L5mV@DWcM;K#Au-aA3s8!6URg8|K zGJ$c|Mel5U#z^^zo#l&i1@BkV|LYk6XBh!!83AV*0cRNjXVK)dX!2P!`7D~O*1C_O zZD-N8vuN8{wCya~b{1_ri?*Fb+s>kGXVJE^XxUk`>NHw)9<4f$R-H#%&N{T^EZXwR z^}4AoWoSzo+ERwLl%XwUXiFK|Qiisap)F--OBvcyhPITUDP?F%8Jbdtrj(&6WoSwn zno@?Ql%XkQXi6EHQii6Kp($l(N*S6`hNhIEDP?F%C7M!(rj(&6WoSwn^Y;NX;Q*R& z08Kc6CLBN$4xkAK(1bEHp$ttZLler-gfcXt3{5CQ6UxwpGBlwKO*nui96%HJ))vPD z@GiUu2km>%gi17_5>2Q?6R=%y96p2-@DY3rKzZ&*KlgC%yueku()fi*5e zGtRP8EbY6np}Vl5yRf0Vu%WxKp}Vl5yRf0Vu%WxKp}Vl5yRf0V(4H!^rwZ+B6zwTRdrHxs zQnaTO?I}fjO3|KDw5Js9*^l<@M|(=qp8aUgeza#l+Or?+;i)UiJpxDJ7#j5f9ET6# z1bhS^LpfByCvXx@VH+x`! z=w8b%?53_J?2XM2lV9!^yLTi;0S zl3l=(UBHrEz>;0Sl3l=(U1;TXUATeQRfU#)f`$783-<|LR|8&G1724HURMKNR|8&G z1724HURMKNR|8&G16uYaT2_OWeT|kK#}XdL5+27A9>)?M*FN)N)^a7V1eU@wSPm;- zC9HxwVKv+ZYhW#`gY~chHp0EI2{ywPxDW1!2Vg5a2;1Nxc$iVMo#P|$DC~e&;8oZI zufgl^2JD45VIS;=GBEcW>al9|Shaer+GVWTWvtp|tlDL)+GVWTWvtp|tlDL)+GVWT zWwf*oE&V52`ZZRq4lS)iOY6|mI<&M7Tchqm)??M`v1;{LwR)`DWvtp|tlDL4&*5h8 zD226ZDx@l9Kk+1xS6D$^VeDRE z#dL)g(-l@sS6DG!Va0TX71I?~OjlSjUBRN?$Jpg}P#_i3ARRIw6S5#1x3B8~< z42B^v42Hu97zyLC-V<9$KP zxr>0tS8^||BUgm-dn!CFB4e2El#cwDGdJEvTkwW<-~-_h0g(^|N$e^0;n){)pdaKy z9`uI+Fc1d8P*BgjjOWRU2`~|ErN1V@Z7>;bhbb@>ra?YT2lFoBd-V5C`gK@>-ha2(QqNl9AiaK&UOz~$AEeh0Vkzpe6!ln&dMrgfmZBa@QIDml z$5PZ|DeAEl^;n8}EJZz*q8>|8kG32{TMnWv2ho;;SdMxuM?IFK9?MaW<*3JU)MGj7 zu^jbSj(Rle9G0UV%TbTzsK;{DV>#-v9Q9a^dMpROngiXT2lRwq&>Q+tMqkK*evk`! z&>sfCKo|srNjn6Faz2dXa2Nq2VU)cb4LyK{9za76prKW0XcZb-g@#t4p;c&T6&hNF zhE}1WRcL4x8u}0H_~(qn12?kcjLpx{)N(Yn98E1pQ_IoRax}FZO)W=L%hA+wG_@Q} zEk{$!(bRG@wH!??M^nqu)N(Yn98E1pQ_IoRax}FZO)W=L%hA+wG_@Q}Ek{$!(bRG@ zwH!??M^nqu)N(Yn98E1pQ_IoRax}FZO)W=L%hA+wG_@Q}Ek{$!(bRG*(^qI~Ioeu| zww5#NpJ3KM!K{CRS^osHKEG)LA454*z$b8$oxoG9cq{QHzvTQY_!_F98qSf|d8mPJ zp_Xgv;5$|uYUhxr-dMw2Ldz@B^0%8kfOMV(puf>@wKr1Fo^%p>kE5_d?A~JazGprh zg&nNqTJK`!J$e;5D*VGs-jRikV7TGWnn19h%JTRz36eTq%{6r1)bHtkd9fs@i3qFH|> z*sn6auQI+*GrmvL@~b=t{NFy2<;9HI7QCSy_&_*BKqN##l6@ItsF5+$$QWv53^g)_ z8W}^4jG;!xP$OfgkulWB*lDCy4YaD3u~N%esnxA1B7QOPC9njR!ZKJ6D_|w8f;(X~ z+y!f3Ev$p}umLv0y|4*3!xp#??uQ3pD?A9>;33!!kHDj_173kwVGq0pufrR#7v6+@ zupi1m-3>X3RW|Qss6Fya=<6l)^%DAe34Oh!yj1k^M|$QsJ#!pQJBeP_%Se7IncAvU%fRkCc67g6{Q|gI`jO^RrmIq#nL*vc-*`4YH8uX(y#uBu4IW?}F)nk?P+Qf#MLpv>cI~h* zK0YD7D0NJ7&k6pC0fhszZp&0ft8WcP+kZ43Gmcyt#BR#FRk(v?^=t8*>UWUJ4 zC~q?|1FcrMb@+yY^z?%DBgU>to*XhZEBTh5VPQRQN$xQ&WODL4_soI~!-j2`o|Tz2 zIV>u?&xEw}@qHqq!Y3zZAW>b4)-UyoCQ84~AW_2+uS$>mt@6=-tyjNMk4`BMjDH~I zwWmns8Gk#!=cVeadgy(6D3H~x*+VT|6pFOG z4BaJvc{OilcK4aNukRhPu^=;Z`o`h5?>4Q-o;|Sttn3wOQ`Za|wsvZo*#l~wEQ~M6 zQ>~CY3E_(p`KlhjVa|b)f77w^M%l~9=i4fNtqfgn%Mo4g$p2Jx>5%dbTOhq1!o5*3 zmLsNAX$ODCmn|)7r^myuwMdrPuI_0O*L1|SVYsbsvy5A?z;^0JC1EL5d(^kATUpA~ zc9D*8r^eo(O;K{AZIzsE`=eZ=B)xoj^FX72_4QgGk-pZ)XXsyNNBoiIeEBq$A=WzQ zCi`|x355>9Tw9V{uSL>ap3*b3yy@(UD$8WnL+P0rKbha^yHWh@{JLICys~^|`YAk} z-V(1YpBX=k-B=xuevj0a&y1fZDUsHxayvE4Pq(qjYN>W9sV!D*kzp%V$QX>1!&1~@ zDWY#MQms~hzkmSU#evbv^kFX^7`nb7Gi$~@BPKkYG&y{FkK9?^vkUt6o04*??E^V; z(jVM2XRIGKoHRK-CMR_5F=xPlc|DV-_U~m`>U-B;$2E<@T8o-}uuk;S48E(RS`}?u zXHb*o_&I#DswKUWrkVbBzImu-E7jV~*S1y}PE${0@+Ou_M5#P_E+H1y7wwqd#%he}a#ox|4 zR>{qc_zM=LJ!bkT_}k{rw2-|l>$TPki?TnoGfL*${xpA+W&O;b&p2w{)}AQpwKl2i zt#aOZr5C>VWd~_bJ0SuiI>#_IX+0ndw4kDIe%NH6)J~ncwcp%ho_liq#NZCWDN*tZ zTbCh4eA`p^%^$g1{r?JnL=|@>U1|}3Z~IWjJ!gAOj=%ccCVn<@lx=$-TTzn?(EzTZ zCCOS+bHo9TW^O)O<}NKGS7|h}?$w+XE0mTfZSc`j)=v~O7j4(l(eXM@Gd|zp0}Y}q z@}w*?eh%M=Rb!|-`3!TEg{S2k?e82&qm`}bF2ih9gDJL9j(cY5GhaIj*E(Tw=Nj$X z;h9O&w+po3KeQV(O@?I3j??Z9J~a7I2jd-Emi!0mc+%DOp6u;vQ#+%ohUym=)PEmA zqq9z$PVi{I<;S6c6g659$5t&hYiExn7&Fu*4;hl4ot&M=`nXe`o!K5s(!jWEu}sV zDXHfoo8r|NG~=f`Y>}B>jX^VhGQYXnl3tB9Gk%KrMoZgF|GjQc9DCfYysjI!$$~Q- z2*1&`yg_}J=fiKc(byJowEL^j+$J?^n01_mW-EIcVgKH+@mtZ#H^DFCd#W)lzTu5) zX*@IG>Z%E{=s(KeI6mR(%86rdx)+p|m^GWpuktGo9O*gTsyJbdE} zHFAaz-=L4*+sa1ET-(B2##YbKDZetr;$*)uwztP$H_%L5wg5S)|2}~)ttG{3r)7;} zjZ|`C|7g*9Zfcjf%%b$kJ$v7lYWrL@O(wO<55Y!aVwH1bsF6xy-!q+fdhL)^`4(Ms3dw) zr<}NM8D`8D_wL;%#dV2~4vXy=7}{lEM&C(E83~gj!lEKVqJo1$lZIwaU!>%tOV;uk z<&e)~$j5NRs~Yi*o13Up^P=n~>Xy*7GP{X7I+kd61AX?U;(WKtk%+2OG>Db?4Q)tqU{CqF~XOV z_AGt$(b4HS0e(XhVtRx}^h)%J_39av9FQ>~rQfo(NmGY+jp;imHz;#N{Q6N_XCYT-~MxZ7*)RQ{U*A2dbq^p#@do(&ER=GkTt&q zV=#eYWgWhXvQ0m3wmoJHHeR|q${2vVqVA-U3XN5%Os_%vtxdXVrZ=Z!wpSe2$qmgb z+yLZ6DadcU?&&!^kDzp~54y)D5OzxSbLVu%T9XH_PVwJwAG3DIrkMWm3H@R=54qcY z@S0oXi?-q2@}i^jy2?GaQMcSZnEuiEXid7+p-J!Q`Ol13zPlMegL`0VUNqxXf12^r zuZdUls2M+*r(Igot9jInpTci;s5#2a=X-5u`OTLbx1o9NytXYz9dqRk+hp-_Opr>; z%u>`0X_h{VZy}qt%23j4j-SWx#=AGCZ)lD$xT>h^dx;oxSI;U7jv{y6bcId{g*L;?rDq z#t6~m7#**krF?z0?u{8{Z}6)ls=j8tlDZi`U3#~QS5i0QCrjBXUP;}IpTe(AH0}Gn zsN13UC&Mjxu(Tyy23mY$d{YhYBYw8}rw;qcc2^6f%Z!g2XZ+&{{$wH zQ8^-4c2#ql55W#cP6D@I%fy1}$p~A+AIc|{KWV$Lcr!nj@sjOnImtH4_Pv~Fdsg*{ zzEZbwu0!MA)O9xFRU6It>3nlswcU(YZ8YO2^IvRQ;#C{X_$mC~9o5D#YL-gPET)&8 z$&$n+J=1g@T*BlXJ8ci{oGJfebC8o|^iX64uMy^hd zcr}id@6M>ZHs7Z4d|mz>9X9jYa$5Ek%+gfb%+hY>o9?O&9U0v|{3i=6e)G70EfB$vv z{fY+;D()9QwAu>|&n8*@=lafQnr?op-bQ`XE{&r;&9$69sHIJ6tgALz z<>c-yu|GDqbPB&g&=UVlbLv_B%-BRDNnU79Jx}6SH_6N5*BoCc*0jVM`lpZsxG=ltVEGxl2MKv1J%l2Niil}@8jwTE}Bv066l}Vw590ibvYnyY>Hu| zj!n&-+pE`H+so?%{7Y1KXGQ7IJ#kpK-Q9-9_bVPWu(+SQQEvNP$W*q;| zFI#0F7%(n29{K3pwLT#iy-%l({1;tSDw-2wt_qpIezn|Y7vALLlg{z^TJpPFaW zV0)r!E&ZbEVU=?it9~(SqclXty2#s^C6q5>>XYi1u%>=-)U#<6UNa1xBN>P7Ql(Y( z$DF*hF{y@;GBz|?jld`sX36&J`~%jvjKtmDh9#~rJ0zle(@>PNRN0~E1iJ`WnrL%x zy;(*9fiX-hS~JY`bJI#GAixq69VkNvEzavTyLU`dC(o2mo;;Y7yLeE9szO9WR#;f( z_Aog=+`ZqT{<*Vy_(TMH$#~njDYxep<*cMTqq4%o2(!cG(lPgpcIbBvn%S9O;ZTyv zm*26&ZjStk#H%|=Q9SX5AC7@le#o_>|3>n$F&+HvH$-G~TDI)!spgUYt8&u%Ygo}= zy{p+$zPiccoF47cw6~zWN3F);!y2M@XvVHsEaSp9EtXiu#YpG1-w@VyaO}wg$ z-WRxu+B7ToZ`LZONyq{7TsF)w*IwP?At!ZH$$9j0iL|r{67cItg^Aw^z-f(AD^hM|NzCrVv%bWo5 zdSiY=2c^^SrIBMg_D}9LFu;FZ?$R+ivwQTIos%&pi79hThp6<>(DbONjL^`GlbI=F z!XtZUu9!RbZd=Bnc|FhcS(ukMzfb(&7~tH#gt!&PeE(*giFBTxRCDBwN;c>7S4hlo%46JuWF}Y^LqFQGQiDJE}5N zd8suNJL_uy-uG8>ye;awEVccpzG24HGKH)U8Sj&`V?}0(P=*Vo#B6lm&@U`LJ}f*g zPM)!a7|97?oe~o}g(WaovSTdX=9gBf8#^2Ay02F$kcJ!a7qmTif-|d}TFq$S=_nyn z_4qSmr$4D;4-w0qFC=HiPJTee{={{adYqZDQ%(@eQ(W=#F!k)ruh}7GMw3cs@LZ6P ziTvL`z4C0@?@w3z{YC4IXJ%e~$E=tAXZHKQ;C`ohJ^TF?>gv1f@#150_2y~bRy+QB z1!=Xi)@~MsZ(9G3V>~7MErL@l=h<`yWWi z`$jpp&h5HfnsmpD{xZ^?)F?WFI_|31~T9KSEARv5vy zb>gJXU&UMH9K^46T#nSavl?u=YtUW#+v*0dm*bvV`qbCDe)JCcT2irBN`vD}ox%ED zKPFnD94;SPY4?7lrb?QV|fGjy4;d& zJK}in(|ugGE@QjfjyH`&%D$PAm^>jfee883F@0RJ?YKj~X$K=wtqOLVa^qJLl|44& z>vb9Yw(GBq_vSgyG47j7JKeMc*E0T_OLaK)Y80qmHni_;mOh7jraE5NO8M9--YRF} z0w`ZPUZq9@BON|lv%O7KyG1d->;SD~!&_^oG|fqKO`Ej!(BIMclda53bA6Gxnkzfu ziL_Nu0kmET>0+;U-a`g2>7TcB(2ym0c}s>wXLkzAijKlR%W}_MJaFJ0xw&@?9Jn}l zB@499-NVDXcgCkyZPsPzo_NL46RabeQo8tTlK z9uh)^PVCH>GhIYHf(d-Ej5B&c44(U_0OI6~M8286xyq3O1kr3`HNmqesltJk^(-b!OvjNOJNo$e1+?|; zl$qEyuXB9-$PPh1-adY9eIv3G2aZuTK$ojqkC&o6mf=dKW-L#btGn_yQ=cYj{C2(4 z90IzD`WaW6_H(>gts@;|X4Z16{ zBEZ{I?w(7gc|%kVPs|ML?%p9VIKF*IN~g52_A&l}aUByf)@9G?pO>HBE5k?|78lWL zth=9YfvZPQ*G{2HAqxW&LOR3+r6yjzVmS4j-aYfSj2`2C_(&T7L=Z<=XBPtza$Hd-B-uzl@0x&QXREqqJM{J3+rtDBkEWcPg}Vf38;8HkUpxV zUD!Q2jhDr0>e_vChYu%R`xazv@Qdvb*L8hnfqTZZJ~GHw7n%@|(gioArth?LB}bi$ z)`4TX%&F=>7c|GKm5hpKuP?SGR?RSG?DST#YKAdmCkMBrRWpnkJLPsYwsd*SFMfQ- z2G8?`HE*6$u4%z*gZeI;4mWCvkh*|EeNV7H>N?MLs7dek#7gc-xW_{G& zote6DnvyM3jp2rDRd1R5_m)$iZ2R57C+@3Ya2Lz1Y?MlTRAKy^RE}MK7vEI1eXe); z_rJDbY3z!rD`J;!*fVuy^h&OJO3G=rKTA0k&uxV570TAvYuWP*5dA%s-<(!;HRF|( z&G_j&jnERWPpP_f|8oqe@-~FV=%f7a1>38e?&n7bM@!un`?N&z~BG4fV^%(QVN4DOR zbl-!g&TJnw(Mg`S-7iaQ?GMS!I}TAJeU)z6myVX1I|gRFYMF}1Ly1xKH)B=1%-G36 zEwQRqX6zLHeTMojqL8mspBwJ$2TAcqyZGa5nPgij@1HYN4!6BJbZAVmyrX!iE=gal z>vdX}Kb1V4%skn#`ITM$Ci`|>?%lL8+cWjrQsn9;yJeQ8T4k1XJ2RF=?SdF~c0ts0 z$DNfeXj&D!=p})_`P}jKyCW-8r}phTCaxeME-v8*;{{uN>zxwA=rtuX#NddeZOBV-?mN7$cB4Msb)XKA`N$*+Vg2D(?!h-$~3E6 zSSwTWb7gG853)RKz2TiXC3{6u#MKK9>8i~MR{VIYZUe|gdHZR6hqWi)PrZfj&NCPN zmhXQ<%cnO`Df<^)qvwoP&G#jV{56l;7~HoYbG?6zw*1qlInVfa(S~Qbj?0S53LfI_ z-=;&y-5dIa#>R%i(G9=8)L40gDMPN*%EhF0T{kNMyT*rv#>It(#9#eMO>0ON`FK6q zN|$vHv{6`ryyi&9Z-HgDm~6jc9pDFAZ|jn{On9hN>HS?BYM}ANXH(pS$XpU-q0* z>c_9`JeBY__P}qnG2e18QO;tBw9y)n_NyB3p!%;z*Y%9``uiC-94Y_r^nWIud+ie9 zCI{L7m9GBR26MR*aEoWCe|*}1H!}aPcCEWIn6i1P#5TJ{d8fvo9X_o3P7N+{`6SdkKO5?84|9*lZ5-*tz5G^%JpuqW_=P zt^~Nv>RRjkimk+JY;Be-$=ZJ{wk&J4&N6rRM`LaceY78cav()5ptSu-Qrc<6&d3nkcavpJnSG&y?m)mT1 z_x7~4wF|#zdP+W>q#i&j6#dX<;mn+nF|RZc(9;ziK3{tv(C+tjQ~-hr5a^_*)nA_S zdRof;E#9>*v&HE$n_)@f;H&rnw;SGFS7*;z-gm6G=jf{bqdh%G`h%@J-xjRIwKZqx z@yW@@hKA1UoIEplD7L+~cY8Ftt#`%t7=xjQPQ#173i9rN$*@O{3GWfkXyDM^v41~G z8BsJFn3S+n+BnrA%13m9l6JgeKMOhL;$WmDCdbl5MWC&0*muLqmhozBmH!7%T}uag zNNcI|>&ipHNN-z5Y^1^8+T#CFPmgCm#!7>pa=^k23n`yzxt)=KbKI?>@wke`2&g`4 z+wU3DboxE8P}TX>@UJpdX=7`{O;eA3= zetLh82ha`ZU9;@3k%#_4j~4wkRG4Ol_wN7TM2J3o?bwHOK}f7v!B3r~^FjlgVMV}t zG3r?)OCR>DvidTM_3RnClBwrBZ_|FEmr%Y&hGJ8>bjpcS`Rs! zv~-JvHDoOxGpV&}G=}{8ZS^e^wbar;DdCw{Fen(6%oAE!l8Ly_0-Z0;$khIs=7#4_ z|2mXg7IN2bsY_kk=7?FXF^7X4(B?GmN)2xyqwt#oy}h_*yt!p}lXxndu-b5@p8y+4 zGv;qHwG{B(Q8G?c9r*jP_x?h!g}L3APhisYvV0si&?g78hW##H?X0Yg<4knsl$Ke~ zR6N@Ni!3=qIPusY2CFpZkgjX8*4-9Vda6zFP4)F7aZ}u@tZH>H+u3Q0n9UKJJ#4Xr z?R+T2^Wkt#WJ68Wig>OqC)DCftO*9!BwQ__99wRDMODp)$W&?2QdU`7T8S-mDJ4R@ z2h}_w);r8^&Ip{@sW*BTM?BUXhE^%(+tCjFrYf&2$k&ZCVuHMl&u2SuEGLn)ntX+N zM{&*8=G301rk$zbjlx^B+L~~0_pZ2k`SQ=MtY~t& znkvehoX%$O`NU4}`C~hGF5q*PzXU%DE{>WM)yXsoj2nA>d=%j{F5$oF{0zrmen#Ya za3W{98m{MQsl{2etTNDL-Qd5ezjbR;7cRf>)obZ68O*KcFw?AVuTx}XwIP$Z(xI)Z0o_MvMOp)J> z&@Og~M}_xBC>f!m5m;t2OEasAi}`)0Yl%8hSgXeI{G8PpqLr=9VJ#UWzm?h*XvfoM z51z1cThxR-?m-bcbci-mhme?7xLeI zHvw?bdX%NK?fdWP{C1At5V~`EIv7r zACJ(Tk>^K*Qg^eyd5L4G)?_i{>a&9-hQ*%Ps(s7%bU*Reo=sbKZJ#tz!Oi283DBf=ky`sTbsEiB$jE}4~89jtD7G&wMk7)X?5qK=i5h7>P|9E8zU%i}eOp`f7| zN@F!B!M7@ClUk;Aee!6U7Y^Uhvvl&x0|i+}eK@f{2VI9rEv606m|7%F?g})z@6%{O zeV^QGrW+a1iwvD=4!sStbo}M)&=T@he1I6I(=6)%bg8rxzd*0X8~`4Ln+SC z0qZq-5wM^EXF|&~^xVN9XS{NPc4si?v+-{bJ}R%H;QUvq~hB=_NO^qOFwPLq)X6=RBv;u#id>S069?0t)7Ow%gY ze38B_v~xvitN<0hiS#md*QHEjkMm;4rW_lQu`N)=RhiiQVv)n_FVXwVo(A=xWzTXL zi-P^tl}q9>9o|2$^%#wAZH2d|zAd^gS=}GYjomJ!Q3hOo+E1?nXCt#=V&ueKU0f9p z>!nQ=3m#>Dc9~tdT(>D6TvHv&nNZsOQN73Lt=9nj8X4-Z!-L6qUp%*J^uZu+Yj z|D%{5$d^EM^aJi9_N59nui{}1XURE`n?wIQ<&EJJ2YT0q#s*Fo-&a9(4-Jfl*YzH_ zC;VCEuE71UqcV-`8d-u!c6I3AY%7!{>*3V2cVdrlfHMm=d^isE4V$=^HgA53z0*UR zH!}>fk)7-?_h)b^L=wD3Nwr`2s8U&a>5ucCX5lI23m@$#mGqc-w!A?15zCUNU>QM@ zH1xvM6xvKGenNjImQhc>|Gl3~BHJkLzo@hk%eW`q=l=BKc4WW7*}){ei)=Z#uSGlb z?#UfH7uhXmYdjRZ{mj7NncIV@y62|$KUc?U zYEUy@u89c<+0Tn7YuVYu9gVH6jUDkGzrW`YYV4nSt}cZZ1_#dE&T8tWAE5yF2h_!U zipOJe#tfc!$HHMPrj=f=!#*Wy;Z&+@9d5nf-@iClsWIVCqs(30-=FmROv)vT3abKv zs=`G}xKf{gWMJ(LHuGkS_28PpQKx&GFX_&6=eUx-3EnXVsAfQo$xy`v9SmG7t_^T$ z40JL$8H0fu5sI=f7zhLl0nY66*8r0|rIul$1txtXV-9}8mvrR-Skkx6?HnCkbI@wp zY_{F7b^z3F0n~&jE5v<(6mJ~XDzPZGOvKNfJ2#>XU;6pj826u}qfCxlQC@T9@@FUB zpI07yBFkl*+rVZceW&k1cB#m($h-Us_}5KO&{w$MLs~-P5L?G$KzSd*>LWy zS0K*Sxki5w!Hp2-R4R&hqn`;;eCNI`$@dxQ>74r&FavZieU1Bx1d|r77p{f3C~K~y z7T#+0VNIDu;+eyF1x5b!qT-tSmCY;kRPl<~(<}9JUZ>`F0`-A4yyqC!&;u5%ae+_A zhe>F~a{47bh^!P?QQ4`RN*@-lhsVcnoS5hnugjm5|JX`WiW)DcYe1;$RW|YZ=ZT3M z$H#@QiEp!2NQ6OR4H<&ewpfJGfVHTQpNlP(&NjgyCg@qD*I+)D(1{3Zmklq{8jl)< zca6tN@zfyviM`NPH9f2NzF1bFMybBindf+>Rx~TE-0iFt7bL0*PCAtPVc**^`g*@m z-TXn{+eClr7a(-A6rSk^xgT!wu~l?_E`-*;c5|iH^0lPcBPtZ3*_2HCOEEcQ<-G zjqYGF;WOE6CX?NM=lQpDb60N(t-G$R{ouNA|EW!Z4hyFa#I0RhqRENn9Xk?6V~Y2D zhfjI^DQ|hzXM*K@ZWFT=n%q4-J>6|BZNmS6o^0p!D0VS=WIjctSlZ?(C*%<&DM@=q zag~&_Zp8Hk9G5M8+vSW7FRSc~7Y%8HR(qgCOP>`Ew(qEEN!8dLrik62EE>=>te~yl zu8QbD#2hg8n{6J8i8ly+In|r$8n#&bmqvL@g~4eWDex3FxwBZaSUfYVD+E55 z46#TPAqSF#5xi9-zUbJlCKk@zME3~$ZOo)&+v=K}{P)R8%94VbcNs%=N0m|VC>@tB zDjjSN1*dPN*T5$ZmjB8nj>;#vuP~(`t@p}h^vpCXI=5uw7nWT09~`Qy-)>u> z$9~7n*R|B~(c$ifZT1yx1LWds#Tzv!EItbk-8p0~EiKdNT=mgNkH0Fo(pqLJF_?6E zSAA8mjTb%+RpOReFW;(a<>yoYmBJXeY4kx2TUle~e3YZ*XNWeFSxHz4iEKRF+k0dr5*az1su`)S-n6Wu+uT*)E-Ceul=z`#<#$#<=1Sfs~=0&jMdd|N$!5*jZx*6E_kfs z47jQ<678@0ioK{HzZg7X!O+!BoLmR4! z>GO34rK{0yH{wON`r9i49e#gDprYNs*<~;}ohAd8MM7S_8x=oSW&u|PTcg)Z-J-np z(sc~t>=Vd3u@B<&sVTaHt`ly({8u_C97DMhN+QF_8bg=2C01#p$pVTVr--vbdtqrq!1go1IQ`am#onk&C&)aBLi_W%`ka%OI&I7^v#DYF}7!W8Ez^l|D?C` zDC>>J>YO#Ltu>C?9jT_>u0cz^vr3NUzy0owi02>lR+W3^#Pbi@ojAiv$MX*z^DR2A6)?PKraepUw0k$1;gCPGz`5$b{)f!kb9gr`x-ictPa#FzM(+ zx{dKVD}@s5DdY8sViGM>NiD?Td8|ZUjbp25@2YjeL#t@>B>O1bPn%Z>4>1WBR;)pJ zma|+si)8)Eumxmpi2>ygve$}LerHf0_Lr6U*-Lm7SLP_=2OeR?!@%&8ga^YBBhT;@ zYJltK_U?TL=n_f|(??vR)Y~kSaiPqQG5j0pg&SU2|H2J-h31xWxlkl4nnfR>(2wDu zHZm*~yG!iL0Q%A-!i4_Hpt?Xml?)j){4#)V+_UEm;j8zH@I92rEuycBXPVIGuxnC@ zmIzBa1L1Z{xznL5@v7UbodNb)U*f~(F3Ky^6l%3?<>h$S={A67h#UOzY6YaTit zdVMX1uWQeqbswQOJYAqO&`B}E#D`Ugv{zHjuE_3fr&gV!3opGydBXdwtu@mPT(0Ol zhEoS7(P1-)#x-mOmwhJJ9NDvaZB5kf3>^urInSNBJp8SRetoFCJVZL-)x=;JbD3oo zJcQMT`J$IWet~0Heok4RW4k74war*}7Ocb>&#LJg*9*%j>S^NnMz5D$eL9m_t1T@R zUgw+L?k117*^QfeW2sJSG%_PX4lCKf^9^2aBfrt4!`4%)Gf^Lpvf^zthTA$5d$FFk zE6TV|?kI3x0vcfiU4#r>L3sG(Ho(Cscl)NSJ<-UBp@|k>jjSuEp{PDP3_} z5k1o{+`F3YBH`3Nn&8y<)*qtnv`@H?!O|&Ka@VJ8X%QUE@_|9~&upFUnwk=xXFwVB z`LJ9niYr}ehtH zou%Z9Y`68(uGMnmbiPkGDbey;fPzhw^U~wc)J2>}W;>6|ac#48P}aklz_%Y@q+t(>>;LONR^QE;uHAB)X+a*&hG+kn zc{UU}(a+iHPH$m7^l(Mk(+haUq^rC>@0J5TxT2XH9B8E%zFwEWd)P-~7aX5wEIyf< zV=Vsa+>N}1g@qn~Wl4gAJu$Bzk|T#W3v;==30qv?lP)!r1CzGQ6#I+hhR;gr(bmsI ze`}n1i<_aaC9r$+9{00QUohAgvX*NcTCu-+@+vj5WS`ZQ7I6Gm z+)2AV>2f9P_Jp(8U?|oa44mGM1AMqiAhmRMn=273pA8hg}Rd z6>jm}CE(8c_xnP-0?e8eQ{e|k@djR-p;iZPofQo zx;lSVTvW3pFMmmH;nsE=MZF&6Cx<{651a*|b6aE^!7TC&V*= ztK6$b?Y!)F3PW~>2d@M)a&V|M{*_GThLkPHQ$By84-{%79P)P z3~4r5E^NXq%-ml<)%x@u23y_L*oS`VE@LD9K4GU(bBbH?7}LTswfWFh>GNsOSEbW4 R9Ii&MuX})d=SvF3{{f> main() async { WidgetsFlutterBinding.ensureInitialized(); // Hide status bar for TV immersive experience SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky); + GoogleFonts.config.allowRuntimeFetching = false; await initializeDateFormatting(); @@ -120,9 +121,8 @@ class MyApp extends StatelessWidget { ), ), ), - initialRoute: '/', + home: const AdaptiveHome(), routes: { - '/': (context) => const TvDashboardScreen(), '/mobile': (context) => const MobileHomeScreen(), '/admin': (context) => const AdminScreen(), }, @@ -130,3 +130,25 @@ class MyApp extends StatelessWidget { ); } } + +class AdaptiveHome extends StatelessWidget { + const AdaptiveHome({super.key}); + + @override + Widget build(BuildContext context) { + const forceTv = String.fromEnvironment('FORCE_TV', defaultValue: 'false'); + if (forceTv.toLowerCase() == 'true') { + return const TvDashboardScreen(); + } + + final size = MediaQuery.of(context).size; + final shortestSide = size.shortestSide; + final isMobile = shortestSide < 600; + + if (isMobile) { + return const MobileHomeScreen(); + } + + return const TvDashboardScreen(); + } +} diff --git a/flutter_app/lib/screens/admin/admin_screen.dart b/flutter_app/lib/screens/admin/admin_screen.dart index b5c045f..9a4c5a0 100644 --- a/flutter_app/lib/screens/admin/admin_screen.dart +++ b/flutter_app/lib/screens/admin/admin_screen.dart @@ -3,9 +3,13 @@ import 'package:provider/provider.dart'; import '../../models/bible_verse.dart'; import '../../models/family_member.dart'; import '../../models/photo.dart'; +import '../../models/announcement.dart'; +import '../../models/schedule_item.dart'; import '../../services/bible_verse_service.dart'; import '../../services/family_service.dart'; import '../../services/photo_service.dart'; +import '../../services/announcement_service.dart'; +import '../../services/schedule_service.dart'; class AdminScreen extends StatefulWidget { const AdminScreen({super.key}); @@ -18,15 +22,18 @@ class _AdminScreenState extends State { @override Widget build(BuildContext context) { return DefaultTabController( - length: 3, + length: 5, child: Scaffold( appBar: AppBar( title: const Text('Admin Settings'), bottom: const TabBar( + isScrollable: true, tabs: [ Tab(text: 'Family Members'), Tab(text: 'Photos'), Tab(text: 'Bible Verses'), + Tab(text: 'Announcements'), + Tab(text: 'Schedules'), ], ), ), @@ -35,6 +42,8 @@ class _AdminScreenState extends State { FamilyManagerTab(), PhotoManagerTab(), BibleVerseManagerTab(), + AnnouncementManagerTab(), + ScheduleManagerTab(), ], ), ), @@ -448,3 +457,344 @@ class _BibleVerseManagerTabState extends State { ); } } + +class AnnouncementManagerTab extends StatefulWidget { + const AnnouncementManagerTab({super.key}); + + @override + State createState() => _AnnouncementManagerTabState(); +} + +class _AnnouncementManagerTabState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + floatingActionButton: FloatingActionButton( + onPressed: () => _showAddAnnouncementDialog(context), + child: const Icon(Icons.campaign), + ), + body: FutureBuilder>( + future: Provider.of(context).fetchAnnouncements(), + builder: (context, snapshot) { + if (!snapshot.hasData) { + return const Center(child: CircularProgressIndicator()); + } + final announcements = snapshot.data!; + if (announcements.isEmpty) { + return const Center( + child: Text( + 'No announcements added yet', + style: TextStyle(color: Colors.grey), + ), + ); + } + return ListView.builder( + itemCount: announcements.length, + itemBuilder: (context, index) { + final announcement = announcements[index]; + return ListTile( + title: Text(announcement.title), + subtitle: Text( + announcement.content, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (announcement.priority > 0) + Container( + padding: const EdgeInsets.symmetric( + horizontal: 6, vertical: 2), + decoration: BoxDecoration( + color: Colors.orangeAccent, + borderRadius: BorderRadius.circular(4), + ), + child: Text( + 'P${announcement.priority}', + style: const TextStyle( + color: Colors.white, fontSize: 10), + ), + ), + const SizedBox(width: 8), + Icon( + announcement.active ? Icons.check_circle : Icons.cancel, + color: announcement.active ? Colors.green : Colors.grey, + size: 16, + ), + IconButton( + icon: const Icon(Icons.delete, color: Colors.red), + onPressed: () async { + await Provider.of( + context, + listen: false, + ).deleteAnnouncement(announcement.id); + setState(() {}); + }, + ), + ], + ), + ); + }, + ); + }, + ), + ); + } + + void _showAddAnnouncementDialog(BuildContext context) { + final titleController = TextEditingController(); + final contentController = TextEditingController(); + final priorityController = TextEditingController(text: '0'); + bool isActive = true; + + showDialog( + context: context, + builder: (context) => StatefulBuilder( + builder: (context, setDialogState) => AlertDialog( + title: const Text('Add Announcement'), + content: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextField( + controller: titleController, + decoration: const InputDecoration(labelText: 'Title'), + ), + TextField( + controller: contentController, + decoration: const InputDecoration(labelText: 'Content'), + maxLines: 3, + ), + TextField( + controller: priorityController, + decoration: + const InputDecoration(labelText: 'Priority (0-10)'), + keyboardType: TextInputType.number, + ), + SwitchListTile( + title: const Text('Active'), + value: isActive, + onChanged: (value) { + setDialogState(() { + isActive = value; + }); + }, + ), + ], + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text('Cancel'), + ), + TextButton( + onPressed: () async { + if (titleController.text.isNotEmpty) { + await Provider.of( + context, + listen: false, + ).createAnnouncement( + Announcement( + id: '', + title: titleController.text, + content: contentController.text, + priority: int.tryParse(priorityController.text) ?? 0, + active: isActive, + ), + ); + if (mounted) { + Navigator.pop(context); + setState(() {}); + } + } + }, + child: const Text('Add'), + ), + ], + ), + ), + ); + } +} + +class ScheduleManagerTab extends StatefulWidget { + const ScheduleManagerTab({super.key}); + + @override + State createState() => _ScheduleManagerTabState(); +} + +class _ScheduleManagerTabState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + floatingActionButton: FloatingActionButton( + onPressed: () => _showAddScheduleDialog(context), + child: const Icon(Icons.calendar_today), + ), + body: FutureBuilder>( + future: Provider.of(context).fetchSchedules(), + builder: (context, snapshot) { + if (!snapshot.hasData) { + return const Center(child: CircularProgressIndicator()); + } + final schedules = snapshot.data!; + if (schedules.isEmpty) { + return const Center( + child: Text( + 'No schedules added yet', + style: TextStyle(color: Colors.grey), + ), + ); + } + return ListView.builder( + itemCount: schedules.length, + itemBuilder: (context, index) { + final schedule = schedules[index]; + return ListTile( + title: Text(schedule.title), + subtitle: Text( + '${schedule.description}\n${schedule.startDate.toIso8601String().split('T')[0]} ~ ${schedule.endDate.toIso8601String().split('T')[0]}', + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + isThreeLine: true, + trailing: IconButton( + icon: const Icon(Icons.delete, color: Colors.red), + onPressed: () async { + await Provider.of( + context, + listen: false, + ).deleteSchedule(schedule.id); + setState(() {}); + }, + ), + ); + }, + ); + }, + ), + ); + } + + void _showAddScheduleDialog(BuildContext context) { + final titleController = TextEditingController(); + final descriptionController = TextEditingController(); + final startController = TextEditingController( + text: DateTime.now().toIso8601String().split('T')[0], + ); + final endController = TextEditingController( + text: DateTime.now().toIso8601String().split('T')[0], + ); + bool isAllDay = true; + String? selectedFamilyMemberId; + + showDialog( + context: context, + builder: (context) => StatefulBuilder( + builder: (context, setDialogState) => AlertDialog( + title: const Text('Add Schedule'), + content: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextField( + controller: titleController, + decoration: const InputDecoration(labelText: 'Title'), + ), + TextField( + controller: descriptionController, + decoration: const InputDecoration(labelText: 'Description'), + ), + TextField( + controller: startController, + decoration: const InputDecoration( + labelText: 'Start Date (YYYY-MM-DD)', + ), + ), + TextField( + controller: endController, + decoration: const InputDecoration( + labelText: 'End Date (YYYY-MM-DD)', + ), + ), + SwitchListTile( + title: const Text('All Day'), + value: isAllDay, + onChanged: (value) { + setDialogState(() { + isAllDay = value; + }); + }, + ), + FutureBuilder>( + future: Provider.of(context, listen: false) + .fetchFamilyMembers(), + builder: (context, snapshot) { + if (!snapshot.hasData) return const SizedBox(); + final members = snapshot.data!; + return DropdownButtonFormField( + value: selectedFamilyMemberId, + decoration: const InputDecoration( + labelText: 'Family Member', + ), + items: members.map((member) { + return DropdownMenuItem( + value: member.id, + child: Text(member.name), + ); + }).toList(), + onChanged: (value) { + setDialogState(() { + selectedFamilyMemberId = value; + }); + }, + ); + }, + ), + ], + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text('Cancel'), + ), + TextButton( + onPressed: () async { + if (titleController.text.isNotEmpty) { + final startDate = + DateTime.tryParse(startController.text) ?? DateTime.now(); + final endDate = + DateTime.tryParse(endController.text) ?? DateTime.now(); + + await Provider.of( + context, + listen: false, + ).createSchedule( + ScheduleItem( + id: '', + title: titleController.text, + description: descriptionController.text, + startDate: startDate, + endDate: endDate, + familyMemberId: selectedFamilyMemberId ?? '', + isAllDay: isAllDay, + ), + ); + if (mounted) { + Navigator.pop(context); + setState(() {}); + } + } + }, + child: const Text('Add'), + ), + ], + ), + ), + ); + } +} diff --git a/flutter_app/lib/screens/tv/tv_dashboard_screen.dart b/flutter_app/lib/screens/tv/tv_dashboard_screen.dart index 588a7d7..6fb2364 100644 --- a/flutter_app/lib/screens/tv/tv_dashboard_screen.dart +++ b/flutter_app/lib/screens/tv/tv_dashboard_screen.dart @@ -1,4 +1,5 @@ import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -47,84 +48,102 @@ class _TvDashboardScreenState extends State { Widget build(BuildContext context) { // 1920x1080 reference return Scaffold( - body: SafeArea( - child: Padding( - padding: const EdgeInsets.all(32.0), // Outer margin safe zone - child: Column( - children: [ - // Header: Time and Weather - SizedBox( - height: 100, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [const DigitalClockWidget(), const WeatherWidget()], - ), - ), - const SizedBox(height: 24), - // Main Content Grid - Expanded( - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, + body: Center( + child: AspectRatio( + aspectRatio: 16 / 9, + child: FittedBox( + fit: BoxFit.contain, + child: SizedBox( + width: 1920, + height: 1080, + child: Padding( + padding: const EdgeInsets.all(32.0), // Outer margin safe zone + child: Column( children: [ - // Left Column: Calendar, Schedule, Announcement - Expanded( - flex: 3, - child: Column( + // Header: Time and Weather + SizedBox( + height: 100, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - const Expanded(flex: 4, child: CalendarWidget()), - const SizedBox(height: 16), - const Expanded(flex: 4, child: ScheduleListWidget()), - const SizedBox(height: 16), - const Expanded(flex: 2, child: AnnouncementWidget()), + const DigitalClockWidget(), + const WeatherWidget() ], ), ), - const SizedBox(width: 24), - // Center Column: Photo Slideshow + const SizedBox(height: 24), + // Main Content Grid Expanded( - flex: 4, - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(16), - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.5), - blurRadius: 20, - offset: const Offset(0, 10), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Left Column: Calendar, Schedule, Announcement + Expanded( + flex: 3, + child: Column( + children: [ + const Expanded( + flex: 4, child: CalendarWidget()), + const SizedBox(height: 16), + const Expanded( + flex: 4, child: ScheduleListWidget()), + const SizedBox(height: 16), + const Expanded( + flex: 2, child: AnnouncementWidget()), + ], ), - ], - ), - clipBehavior: Clip.antiAlias, - child: const PhotoSlideshowWidget(), + ), + const SizedBox(width: 24), + // Center Column: Photo Slideshow + Expanded( + flex: 4, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.5), + blurRadius: 20, + offset: const Offset(0, 10), + ), + ], + ), + clipBehavior: Clip.antiAlias, + child: const PhotoSlideshowWidget(), + ), + ), + const SizedBox(width: 24), + // Right Column: Todos, Bible Verse + Expanded( + flex: 3, + child: Column( + children: [ + const Expanded( + flex: 6, child: TodoListWidget()), + const SizedBox(height: 16), + const Expanded( + flex: 3, child: BibleVerseWidget()), + ], + ), + ), + ], ), ), - const SizedBox(width: 24), - // Right Column: Todos, Bible Verse - Expanded( - flex: 3, - child: Column( - children: [ - const Expanded(flex: 6, child: TodoListWidget()), - const SizedBox(height: 16), - const Expanded(flex: 3, child: BibleVerseWidget()), - ], + // Hidden trigger for admin/mobile view (e.g. long press corner) + GestureDetector( + onLongPress: () { + Navigator.of(context).pushNamed('/admin'); + }, + child: Container( + width: 50, + height: 50, + color: Colors.transparent, ), ), ], ), ), - // Hidden trigger for admin/mobile view (e.g. long press corner) - GestureDetector( - onLongPress: () { - Navigator.of(context).pushNamed('/admin'); - }, - child: Container( - width: 50, - height: 50, - color: Colors.transparent, - ), - ), - ], + ), ), ), ), diff --git a/flutter_app/lib/widgets/calendar_widget.dart b/flutter_app/lib/widgets/calendar_widget.dart index 192326d..d561afe 100644 --- a/flutter_app/lib/widgets/calendar_widget.dart +++ b/flutter_app/lib/widgets/calendar_widget.dart @@ -20,8 +20,7 @@ class CalendarWidget extends StatelessWidget { // If we want Sun start: Sun=0, Mon=1... // Let's adjust so Sunday is first. - int offset = - startingWeekday % + int offset = startingWeekday % 7; // If startingWeekday is 7 (Sun), offset is 0. If 1 (Mon), offset is 1. return Container( @@ -39,9 +38,9 @@ class CalendarWidget extends StatelessWidget { Text( DateFormat('MMMM yyyy').format(now), style: Theme.of(context).textTheme.titleLarge?.copyWith( - fontWeight: FontWeight.bold, - color: Colors.white, - ), + fontWeight: FontWeight.bold, + color: Colors.white, + ), ), const Icon(Icons.calendar_today, color: Colors.white54), ], @@ -67,42 +66,50 @@ class CalendarWidget extends StatelessWidget { const SizedBox(height: 8), // Days Grid Expanded( - child: GridView.builder( - physics: const NeverScrollableScrollPhysics(), - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 7, - childAspectRatio: 1.0, - ), - itemCount: 42, // 6 rows max to be safe - itemBuilder: (context, index) { - final dayNumber = index - offset + 1; - if (dayNumber < 1 || dayNumber > daysInMonth) { - return const SizedBox.shrink(); - } + child: Column( + children: List.generate(6, (row) { + return Expanded( + child: Row( + children: List.generate(7, (col) { + final index = row * 7 + col; + final dayNumber = index - offset + 1; - final isToday = dayNumber == now.day; + if (dayNumber < 1 || dayNumber > daysInMonth) { + return const Expanded(child: SizedBox.shrink()); + } - return Container( - margin: const EdgeInsets.all(4), - decoration: isToday - ? BoxDecoration( - color: Theme.of(context).colorScheme.primary, - shape: BoxShape.circle, - ) - : null, - child: Center( - child: Text( - '$dayNumber', - style: TextStyle( - color: isToday ? Colors.black : Colors.white, - fontWeight: isToday - ? FontWeight.bold - : FontWeight.normal, - ), - ), + final isToday = dayNumber == now.day; + + return Expanded( + child: Container( + margin: const EdgeInsets.all(2), + decoration: isToday + ? BoxDecoration( + color: Theme.of(context).colorScheme.primary, + shape: BoxShape.circle, + ) + : null, + child: Center( + child: FittedBox( + fit: BoxFit.scaleDown, + child: Text( + '$dayNumber', + style: TextStyle( + color: isToday ? Colors.black : Colors.white, + fontWeight: isToday + ? FontWeight.bold + : FontWeight.normal, + fontSize: 12, + ), + ), + ), + ), + ), + ); + }), ), ); - }, + }), ), ), ], diff --git a/flutter_app/pubspec.yaml b/flutter_app/pubspec.yaml index 646bdbe..497266f 100644 --- a/flutter_app/pubspec.yaml +++ b/flutter_app/pubspec.yaml @@ -21,3 +21,16 @@ dev_dependencies: flutter: uses-material-design: true + fonts: + - family: Outfit + fonts: + - asset: assets/fonts/Outfit-Medium.ttf + weight: 500 + - asset: assets/fonts/Outfit-SemiBold.ttf + weight: 600 + - asset: assets/fonts/Outfit-Bold.ttf + weight: 700 + - family: Mulish + fonts: + - asset: assets/fonts/Mulish-Regular.ttf + weight: 400