From f0fdd1ecc2c99a07990f70fb498175d5ee431334 Mon Sep 17 00:00:00 2001 From: Marcelo Lv Cabral Date: Thu, 24 Oct 2019 01:52:36 -0700 Subject: [PATCH] Added support to SD Display Mode and removed usage of roKeyboardScreen #96 --- assets/fonts/Gotham-Medium.otf | Bin 0 -> 60488 bytes images/dialog-back.png | Bin 0 -> 8083 bytes images/dialog-bar.png | Bin 0 -> 1892 bytes images/dialog-bottom.png | Bin 0 -> 1711 bytes images/dialog-bullet.png | Bin 0 -> 580 bytes images/dialog-top.png | Bin 0 -> 3117 bytes images/dialog.png | Bin 0 -> 1728 bytes images/keyboard-back.png | Bin 0 -> 25928 bytes images/keyboard-backspace.png | Bin 0 -> 3258 bytes images/keyboard-bullet-on.png | Bin 0 -> 2054 bytes images/keyboard-bullet-sel-on.png | Bin 0 -> 2287 bytes images/keyboard-caps.png | Bin 0 -> 2887 bytes images/keyboard-check.png | Bin 0 -> 583 bytes images/keyboard-clear.png | Bin 0 -> 2655 bytes images/keyboard-cursor.png | Bin 0 -> 132 bytes images/keyboard-field.png | Bin 0 -> 2952 bytes images/keyboard-key.png | Bin 0 -> 1200 bytes images/keyboard-long.png | Bin 0 -> 3463 bytes images/keyboard-shift.png | Bin 0 -> 1990 bytes images/keyboard-space.png | Bin 0 -> 1879 bytes images/paragraph-bar.png | Bin 0 -> 1818 bytes images/paragraph-bullet.png | Bin 0 -> 438 bytes source/gameMain.brs | 16 +- source/gameMenu.brs | 207 +++++++------- source/gameMods.brs | 5 +- source/gameSound.brs | 1 + source/gameUtil.brs | 82 +++--- source/libCanvas.brs | 3 + source/libKeyboardScreen.brs | 444 ++++++++++++++++++++++++++++++ source/libListScreen.brs | 62 ++++- source/libMessageDialog.brs | 142 ++++++++++ source/libScreens.brs | 26 +- 32 files changed, 827 insertions(+), 161 deletions(-) create mode 100644 assets/fonts/Gotham-Medium.otf create mode 100644 images/dialog-back.png create mode 100644 images/dialog-bar.png create mode 100644 images/dialog-bottom.png create mode 100644 images/dialog-bullet.png create mode 100644 images/dialog-top.png create mode 100644 images/dialog.png create mode 100644 images/keyboard-back.png create mode 100644 images/keyboard-backspace.png create mode 100644 images/keyboard-bullet-on.png create mode 100644 images/keyboard-bullet-sel-on.png create mode 100644 images/keyboard-caps.png create mode 100644 images/keyboard-check.png create mode 100644 images/keyboard-clear.png create mode 100644 images/keyboard-cursor.png create mode 100644 images/keyboard-field.png create mode 100644 images/keyboard-key.png create mode 100644 images/keyboard-long.png create mode 100644 images/keyboard-shift.png create mode 100644 images/keyboard-space.png create mode 100644 images/paragraph-bar.png create mode 100644 images/paragraph-bullet.png create mode 100644 source/libKeyboardScreen.brs create mode 100644 source/libMessageDialog.brs diff --git a/assets/fonts/Gotham-Medium.otf b/assets/fonts/Gotham-Medium.otf new file mode 100644 index 0000000000000000000000000000000000000000..144fd8e9ee1db5b39a321a05735886c3bf163a25 GIT binary patch literal 60488 zcmce;2S5}_^C&*Eaa?3o#^F4}vSQ9TqoSBaLx$1Dw&9wF;S2o+Z85B08lNkN4UZc+QW{bf@vq@H{i@*sBcu7(p7@Dxju%~I z!0?dcy(g8x=N0%pCps!N?(0OZA=1yjn>ik@sz!~bg|r^xU&7@hXQzIKZ@6P`w4K@g zMvr5^f35iCm1c?hEj|jIioL}@*iLQ!+MGM7Is3KZ*NU1Y3MA_{YlVj#=gIM}@jG)iv3Ad8tl3Y1%K>oWfRXcUVvYBeExYQXOqhc}pt}3ZY zNBYe;D_Db{Sb)DPH^)}yan?TD$|_FJm$8-AoC)c{9^fAhXU{LRm9<zl(d!Yx$)W>wz83{rPJ8TB{`k0jjdb? z%U;+IUW4<>&BFiIGS8Le?%K*K&d3Y4vYK<@S-)9*4Of;QYb$FxXMVk{ti$(rY-K%n zM5VWt1+J#Lj;&k_%Tczn9amYs!&WYi zjf>)meqj*f5JO9@9{x>K{?^4eqwrl6VvOMeuoQ;Rb-5sXGo0hxqM}E| zgolR3nX9|iFgL7Uzd>zwZEo%o6*43uB*t9T+$km`CZtZcsK}7my5_LBxagMk>Ln&7 z){Pq#9TgfA5FIwEZcr40>WmQM5PAT@HFG_Xs$lGAJj2pCDlRNwxVcA2aCkgE_Qr3a z_$31C#^7T}XnaHf7P?^nI$@t$V*7uG#=bVh9#}`rj7um6F>`Dsv^0N%sinDLUF?k6 zGX}pG1z6{w$g7i2o-dLYgF_mQU?cw-nQur;YX4Vid4m1}Sgiu)g(q zC{7S#)L3O2gRq5lJQ%CxPiT0oIlvqj6A&CSJRoM6Icms1vrTPtVpw=kn0a`>D05(l zIVL1DJT?xQD%czzX$}gBi3`B{(D<0}*x>M>I2_klMDgFVKKGBj`u_sLf3<}EX)XMZ z8@5ws!YU^6XP+%9HhUd$o`P}F`{0~d#eqA{37fY_<&BwZr!4Xid^22m%LGgu@({Z+ zo?x6dMB!@oC060CIOG?$3>k(XEHPfNato^&ui#{qMB;K~oWbe^AiV#HxT%LY<52`L zaTJ3v>LE0%7^sW%#Ua%ZjJw*IgHS9nc8UuNF?Wm%uHzGnqR2fwC?qmA#M~}4CM0Bd zNMxKjE(&WP6Ap>OhuEkgaftyjA?BcfNXBMEqT(Zi%~6pN;gKQcfVh7bUG-w)qobo@ z;_8K<7^)i9w`oFw&$K;h=2;Y_G zH2e&_59VA^zc6z@bDMZQUyiTDSK}M-&G;_-06v8OnV-dfRsE>yr#hj!qpoUfYx>pn z-mEq2%?5L6b6K;=?2J1>eRE552XnM}lzEDIrFotC5A$a8j*352G*@)4=;!P}HDA9X zCNsB!+sYew6JM3D$v5R&@b0`HKNK;1R+T{v$5q)1hGf$_vkEa3GmGXj=JIB;-_ZyAAN0K6?!N2&w)dOeZ+ySe{f77J-LHDzbYIGOk@Ga?e$MHf<2ji*$8s`q z2IP3<^v-d<7o{6-(>Jgi|DXNQsSFG@ul)PJ!os7jsYd-q%jq~hYM#Y7182t-N1e{d zmEcNpr8oypoIpI82wMXrx0}7^2xV?7ay5ip5 zopVPP_27EqzT69UdN0l!1(q+@hwIDrZRu8@Wx~AKYec3%8Bi!ENVua=W=*Tq>8s?c>t;-YAX&QD}wo z-Y7hlG6BW2O*9N)|H93~EAIRFhv`R!e}-}+@nH?Omm7QM?bXlb^Y9 z+-#oXdA=Lpo$tweBLDW__F$a@yqWLENArF7zWfCK7v77D=RNpdyf0cller{r3OA7> z+%#@FHIXsI)}1>8bzKKGQZHEuZHh;Pg{;S%`fxGvDbP*yG8zD_`G<{$p>oCdXF zo;O<6ntTm~S0VQ_lS^{B75Q9eRcJZbbcm3mtV}U zq(i zO;Al%O;;^atygVT?NMc@&Zw@b?yH`vUa3IMtL@a1y1crQx~{r~x}&<6+E*Q*4p9$N zk5DJ7$Eqi)e^<{{FIKNoZ&atMkE<`LZ>k@v|5U$MQ;kYvrzx!|uc@r5rD>>XrE$}A z*Yws5&;)BDG$S+#no*i0%>>OP%?!YQ~o zbq#bab#A)uIv<^%E>st%`$acTw_LYQw_A5mcUpHzcSCny_eN*Y>-DAd<@MF|&Gc>c zUG%;61N5Q#DE&|RN%|T3+4@EL<@)vdt@?fX4E-tnMg0wZj{dp+o&K|+5{e0>g>ph= zp|;RiXeD$IdI&y(pAae}3dzE6!hB(cuu<4091_k7SBh0AR#d^#4GF-Oos~AB%C&Pr{m_C^XEa)d2UsZ#EmH0h7!VVN|GQcV2)Ew4DsaM;Yga3> zaO0LvICojB@Q=1a3@`a&HBCjB@o-YQ`#8 zuOPJNA|e7}ZFlb?ZQ_cQy_J@6%GJk8T)g$>qfi>zz7~BSX;!hz#{9N??4^2OsN@ z$6IfGg2H2h;)kP|Ix?}a*sriSs<7B!q4+1|+P`4Nekv%nV~CZn0R^RY9jz}ylv~eO z>}i-%j4CX873pW}H|4OzfFjR<0by}{&{|FiNmQAr;dPsPJ zvbJNxN3zFQT+)%O5W>6xtPqKMGrKDd!y{404ylVbCL-8P5fNBW;ITV{hj#{#-4u9O zu)@PaB!kE9ND=a4bVx`dT6$q2BSIoN#>YfOhr~uj#|K7)%fVl98;1Kq~I)Ydzw1?U2-u_JLh6O|n zVNX~@3nwPnRvr-_5QCPp?Mdmnt*ms~R#t{Q%=W;h(BBG)jXo# zDKlEM!0IZ~i!YVw#XFl`c2lMo3)bnyf-=2$M|KR43TAZ__O})yq9U!WhKC15*&Yxr z6Ljdl#SRrTWE%!^4Jg&wiem*7$Lxmo9Qs{?qGA-XgQHOPDDRmw0j<1HR)?_?yN^O{ z#v232?ve4s1DVezRCya65EFp&8m$124N-g!tX6OcGc8#Ody(ICM0`|SNN`{Td##jX z5mkh>Rz!R(dp$fn(pm@(PYB1^#aAIXRZ5fL@ey(1(GjEA%ZQLzr9NT_VAF`Nq7g(v zb7i5jw;n$3VMB(-M#P7P*Tq3nCJej4CamzrriaZPzOl|77L@5?ceWbw&Zdjql*40PcwA2hzPg2sXZn%x;_yfe`3rhvwR6*LwU(0Eq_KI1|w_Xpv4 z7ukmD;?&KbxO}#>PB;KEHrp$S*>( zV+p^MU&b%zSD*p1ieJsI;n(u(`1Sk-ek1<}zlqls;F}2 zUHNu=d)|#(r>cY|W2CCGs*0+rs+y`g8gn&OwN$lLbyRiHtgEkTplYaUq-u-?UQ<;w zRdZDfRZCSXl?$4CZB%VluBvvb_9{132Q>aVsXD8=sJg1Usk*D&RXtQ5s-7xOGzojF zyj0#QAC<4FkE$=akov0zs0N~;=%?~m4ORuH0?}j)R)wgBs6tg?Xgm&84O2y^hN~h~ zQD{hxP{pWXRdK3#RRS87BUPhRKdDBm#-MrmvnolItQw~pkA~(is$W$TRg=)*oT8el zBC2WpYi22TM_H6!& z=pFU5^qci3^nVH^(E6HHEV9^S17|30Xkh4U7;czs*kd?ur?D$-SH;fXF4k_A-Ob_y zijOWnyZE}|2Z}$m*V?<<_qGqVpJ2b#{-FIcdyBDzv5_&!ILo-(c*XdvgkyWwrFxf&E48T9p;EaH_6{b8i4IFdPV^ML#H7-y(tS$j zNKGU!#|n-u9hd%4^M_tPT>RldnQCQ%%EXr;WtNqB@T2iZ^N+25^!Rc0k7vso%DR*t zUG`?#&*jRMYg=w;xdr9Y%e^e$yL?RfS>?Bve^j1UC{>|Wg|G@!E9|Iny+WR;s>#Ph zOc^HX^rKTVr@l@Tot8PhG7m6MHt#V%tXQU^Z^c;^?>e`14tD;{Io0`HCA&)1D|M(e zqSE`yPLRRD&?y5sxqd^hALO8R;=2l>ZGdMs$Q!4wVHD^k7^sLH>lpd zdRXkaYYwluu;%MpqiZdzb+XpW+RnAR*Z!sU zw%T9oc-C1|XIGuGbsp8R)NNjOLfs{Gx70mf_pf@z>s6}Psov;%^Xu)ZcdMSIev|sa z^~cxWQvXT=b%V+cdNvr@U}=NQ2G1InZs^)@X`?QUA{#Ahbf$61#w{BUZ9KX0#wN9z ztZtIo8| z#mW{3THJ2&x#f_S^IJY{<kC2g0tUDbA9+Y4M z+iBX>Zs*l*Z@UxivfKUHUfaH0`-bg3+WWPi*?w#LlkIP{f90lfb9AfY*43?_+cdY0 z9l|?2>o~GgwN4{DSvvc5-rl8Sm&sjHy1eaLx$C^Hr@NKu=F@Fnx98nmy3g$XpnI-+ z8TZld3wt>9Xx-!Y9w|MZd;I9p-D8HwVUKq`+x48-^Q324&q&X8y(;&b(%Y_gWbgI8 z|MIHiwZ&WQEqYh-9_hWp`;AX`pTjucB7sc*-=;eD6&J<|6^-*^3V z{mS;+)4z28#r^*p5I5lVK+V9kfppLxgN_cm>u2v*+0WN+tlv(*Ykt(fnSV?F)&Xe& zcLJ*fHVf<)I52QT;Jm;sLFIyK1x*inA8Z#~Hn>`F)8MYbk--y!mj-VQz86eGj3Le; zEkis)28YCk{2H<>WLwDDkem<;?Lh|~_*~`yPY%eH52)!tjXe4D7|UecrG658CbYAq ztdmODEAo z(rMeX3861qkpNBJLYKGDAd%mht5WA`V5wA z+Tpal8B34wbCXZ_wFxvUEZQNq7qCTwRwROUp{)?v;1vn-pU|jRqQf;XJblpo=4&vB zd*x%fDoMQQwY%q9w>iRz#(FWWm!6hNZrYxhg(-S*FQMA=K2SA8p#AjS=J{;wohEdz zrxnw(eC~uj7$;PF@JbKj{QFl3@WOPxc#VAOc7oR4A%M4j-?)8oDZ_*z^rfV zbpJ(wZu;!FmC?jspzGkKG)+%ZHf=sLQ=lF7ZB~z5NA?ItXg(o(Kmx4ICfP7JdqSea z{zp*z(KB`t7iT~iypt*#V2dVo(;zRWDSDr%K?D7Ur5-a)*B@TLFU#lfh3w)Nx@@)Y~|-1Qn&o5XBds%?upNCfG-)PGlB zL3~y#(6<|DfFnokU%9{!rhDY#))PkstmzIfrQp3|*OIN+K7Gs91N$})8)(9&{X&Mi zjSxoB`;z#qbN{`^ou=za>iWHB*9%aeHqr)#_{R+(g3;1A*E5kn0Zr8>kgd+x*vJWI zmQJP>b6@hO!Cno|XhkXGww5}-=<<$04g8n&9-N;GzWAjo{l-3(j@2DiK-(|8=QMooi#e*}1(F`Ao=CLl@aW zx=6-?@lE?}C#miL=njOQtk!-Z7(0@M)L89Gs0Zl!QC&anHjg(~w8p-00A0MW0CZ|t z@KFLCc!4*lsWz#LG%da^t{kb6@BOg}B(9+TeBKQ5=&>075XA-F8sfhU)h#-TghP)&R+`$Myva!S ztVqc9N#vmu7}e0p5sbM$O?9+a&$ZRSVXM~YMu3x(LB-20kbrbY`8VL`eH~N=6hS55 zW}YCRLgs){b?(s$CR&Pg_3ctuc-TpsaWQ4<8FGfC2a!(1Jt`S_76Pf-;ff0c=mP`EQ%evbW;lv7PX{e;bBt(Toeu7VeA~TGKqpgc z;57 zn4jKC@Dpq#bfebTBMCGx0SBfs@cermqLFMAjv-C;K0Jp?Y~-p_?lLWJ8b~503{4W| zL321qP;gk9kwp6E)&AOTOZF~2K!ltVejSjw_TB@UnYt0rO13yIO9fgitLU{4-wA2 z(0Ziz*ifGcw0{-aiVkI~msZ@=KEpR{;Hl{QM40?ZYTWDaB?Odp2mKMH%`CIR3nxtp4c87Rq_~J$YtHCWLbE0olxZ+&c(=1^(|G_Je&*9JJrSPz#ES z@8JA63F?6E29#p6bGQG2Hd_VpkA?_f6*21n0m>iO(HhTqPd-gEcv znSk#2t(W(}dL|q;oSv%hVD3l$IFx|BYzZ8BBlRQ$SNf(1UFv9$_dg%@k_gZX)KDMd z8I@ofn%(zMzx3W~8sT`=tB4yQ4i_!=x-rx+T_%Uu?@XIo*N>K_C5f;Krb~^z4qd@^ zmk(t=cy!FGJ>u@{+pD3;XsL;yU?x=Hui%2dBA1h@7%XcvxL*J1OF~{#w&43_%V~U; z9HW-^WJ?4D`WYI-XJ|w~Z;7EJaKxD~X^XuwAuC*$6V%t`7LuF*8cTwXe$m)URyeX3 zO1Q__k{kmga1~nEjS7%U8`E4AvPN2&?ehKz2p4bJvy7*LaF@SL=HAkRdfAg>1RRv5 zS^EYxnzcKX_>UX(C+S8_YH%(zRD06(WT% z9pIJX{{WWV2bUcV8M~nVJD79_hU^mWCCig&Q|Udqw>~>f7`0K`*556zI*#`^+8R2- z2#Cf`c7a6v+nTmV`BcH9bBF$s>-Rd5Inx*awp2)g88sIr_0*2oHF%2~wiBqDa@5&L zJd{lJx7)ojT_ow7w`~^?)2bn9LvIk_-ILqk0zuRZdeJHP*M|iu|sh=en3&t8g16LiTuXg zNcBd?s)lZswo)~NaXT(;@O}>-z&kt!d&qzi&7g$%;jtrR>#+Y>)}`>GcUp_}f+!za zw?CEK!$Br#qjyC75wy#FWh?AWmQHR#2TI+2BV0_>1%Y+c-AoDhb`n4Ar2A2^aPK>` znTZa@J*1EBWm=f0lQAO+bn>sDMLw6*a-$@vy21F8fJTnS>3s|(yXqWiUo!$95ohd0AWGOI$WP;3H`0NAQxJk*bh}l!MNKB&Dxo|24h#&{~U!7>_|O>5xVEsu$Mipl-bLZbr3~w|4xwU?h?yX zC_xBP`2(Th^d1d|dsx)631@`jjLI6es2uAfv=&9iT#jVp?vf-mFiZ!X)X-r32}dFx z#mWrpP(m7%vJPiFIO(7+INX5-C^w*Dm1nfMiEhwA2@5A-^-B7u#|O7ydqJ;0bxr?( zCU7j!%<0<;SjIW{#IFDK*l zK2PLtV$F|OQ?^f*ni-5|7b_~n#@tS7xH?e+p1|H*ANnJqLo8cqsJxYy$2pMQlxiyz z9kzYmAZ~}v6Q$+`@j?rOxV+!latLxd&Z6yM7Og^H5`9T$QW+`| zRDhO454s$x5IPHm>tuMLHU433iW(Nun(pXgFfPHBjN+8%&&rq7XB}H3cm6~jU*wj4 z!9N5+{g66JaPkH9&MghzFX%~Kz8aQ{YM9(Z(Zeh@J*=Q1{EjV;D=l*`(UY~oJFhfF z#gF!o$3bx0>kdcdGUAG(@;K=U>h6R8f-+ih#b30{GeT=Ya1$JarnK>Mev157J%u)w z#V62h+uuV3!$^Q7kVK;8bzoOZb4kMGLwgz#Gt6|GS zshz<%Hu*#Q1i8}(hwCV(j-ZfAWzzwrp!jQWV;s@}^?6#-)P#8Z2YU;!m)h&ak$I7T zx70iO?fsAVKO{or2dO;{jV|dUJpIV0F@5|>lH^tdd^+lzN5Ni9g|uX;gFzhG(Xioz z)X89Mne-aU-a-zR-u;4*7sz!WrC4x*5dVa&t!G%kGA`a6)o77`q{Wb|~Li562*g>yB7BsJoM%e)00| zfh|ll1D_x3!Pw~*wKKIK{RfBl7hoF#F3gYcste46F6(GPN5>u}` z_A-dsx7pXIf=Pv|NE6&jl6o7af0Vq~JUAsljSukb15QLf1HHVCOo@a{)Y+KhUztg~ z{SXnr8cQdsh1>bJPH08He0%x)ojVu0R6$u(sdKmHrf+c+Otu`UAkm4pbCE%@oi{Sf zOvX=i4GvdbC_PT0NZhUr(jc99!3RYIT29y_>OSsIfIo4URD&z1)i8IQ*mbyQXk}p~I2{0&U<+B1*1JxjV%L;6F(kU=YIw8pOVX4B`eq zgVEW_2OH%jYG^I5k!TqL9&|n`DJuc>KnZthN9qY>2=#?ks1MAe5<#1-qt@7vHv3Dy zZ=)g;%1i#(ol@jA+6^(4 za%0H$E-TNi*s+7$AS^9V|JE=m(Ob;SI39W|@ZEhM-Z>{d` z#$m0U$WK#($QV*NwL5ehiYD?W#S(>LFV#>CMc~WN4Qrx&vSN2f?3WaKdvod;@{TN; zvWqMcZfx9i*R=NO2wn5xn{POgCDV72MdUBPGqf8bZ>5FeLl;Mo_9Su2P?A7eZy%Bs z-!&m5gtR6J(}$8o(tdOVEzU6ah6#Uqy>K`#+lwn88zx96$%d4bw}mdtwPVAR#zd0Q zBw=>kTtOThGdFTxB=I1T{_(AZtOV`CE%O&|AdAV0@vFuQYmzr4Z@`7AIKgmIPC$i1 zCs>Yr0+o0%XJVeG1kPJ^LuAh`B*fyWHC9@baQ_2*N}T!O=SL*b;SkE(Cvw+ZU#Stw z@oQt+PC&b{Au6dQX)VR}vb$3C!w?~{%0sgF{w$(>P0sB(bX@3oQ5zECAMHI=5MP{z z8`{<5R*ha2CtSIq4c`&G)^DLer_)6eu9a)#$?2;(zX{#xb#0$@!;X;)f-#VMg0}Br zDBE$Jaf?3fD6joQZ=fDM{XL!jNJsX}-@IbwvZbr$ZX!p>mgsGRgy+|^15dlBQ#ElT zz2k#}f`Z~bNPD54OQoB%gWe?;y>-hHj@^{?H~S@?Np!e*Q~n`ayql|n%Mv-BcqBYk zc>Bidc%{l(@rmCb-pf3RAl~&P-Xr~n3C{1mJ>OQ<4)sg)A)dr@h1V8;p>pLTo}WHy zQzDLx$|RZO@Y2+c!bj($$1DG(-I}`M2st6pHMECRvB|x+PU4fl?%(_P@lmrXRU0;| zXfjSC;MMTal}GR<(E+yO@TNY2B@+0wr#?DyWJB=5J*f&9aD)0wDLF3|KXAPgIr#E1n(N^zPMhqB{T4J?F>E>6fQbLt zv?|rKifo*C@aLR_O^FJyh+%Pl=%eW&KSejv6DV<+sb@P;M+h*`KGY6xMyQgs4a%K| zIp?9&Ha=qql)o-_*`byjCP{&YZJHp%3@9gEB74{F+9M1|(?&!_jq)Qx=YE+NkerJL zj-5B{BAZ8U7$Kw`)`o5kSlt0Tt8LlPjGd+2ohG0{{QF^R=IMivQjeT)$beOJ`2`TO z#81#jt|sjv8y2rvErg#3S3TK2Zd1bYgq6eQ`ICWU`1tVA!ZIK2`gyBo|3QS*HSxht z6ZP>k<7W&bLdSj)JrINE{)i(cQLaesC0Lb7SLqOHNz}iG$1h%sVU>C{%^9Ey3$B8LF+;zrC>HJxl7@_1pR44 z)UEyTZ)4Q0`=cyFi3|Stw=uMU{-zK|^fjAlHT1u`ql2*uGD;UPqhqEA>X}Zo3hiQ| z^=?Sld!;rq(bg86fgf(_p3)!glPXY2duY+N9pseIZjv-4DsG^u4itZ`OIx21?8N5m z-9!EsJX7D2-$@}T!-vYH&VkQ4{=#MGby*F`aw+M-&1(;^n-5&BHg4q7t}*VMjc>X> zG@a9U2c;gw4+nRp967wpzb}618|3F>GWI3!VAV&alJjc$m|RREpJ=bC(@-5&k!jck z&uQo~^CVNzbE_g#!CeczEXAaEmQj`UM!CfqSdqoU;_K=o=yVujFv|7L9ZbA;PGB(_1`|*WuP(+NPqvW-9t?M<|JAS|c4! zi@GTq{>W`Lpk!-kZbAdq(iq00*+>*^3Eg@40o>Ivj<%F;K=%fu4mF`0 z#3HwlO+3`ZL5;zVg=1~Tu%}Kz=Tm&jMQD0a4ZdA~6acX3efx@R?R+^utS9MtA# zy4*L>O0>8HyEEx-9Zr8qX+Zey{a9`Prd|8@ZwVZL)doZa^|vuzhCEX(|F}njb`VKs zQ@l3ygHp5;ErpvoZRsx!Mb+gv}Ei&Tl>9Iu7>FjzbKVVm)vnLmWKPiZ7!L zv>GW5DfpoAIS>xNJm-LuDOWou{+yexpgf2ue@2uC8A^bo(g*`RtQl^AG#bkg z(#qq}&K`{8jc&;^P*x42aGyjsPz7`YrR8Dxi6hriGtUXGx3mNL_K9*QLWjXSkKz!K zbH{drI765*BN3XmB;#6Ysd{7sFG5A;{44dmHJDBR?rZ5N|18BA{{1^`jTK^xR=5e} zzVp}61M*K&T+uprU!WF&P95=Op;t%z5Q?DU4dTm$Z>pj}jGo|9w~-+WD>JN#1{#QN zmXU?ESMKLw!x4}UW6e>9K^6&}Mbu8NBmIQqZ$V$oap0F*y)oub4)SO;$9B(m1QFGT z52Fp@?lFj*YAh|Ku?Azt;sp6^zN<%%ynGJoX~8h#+P({y1(#deo?hPJO;8G#t%+K0 z1srFn@CrfyXu3sCgdOc8+B3V-epSSBiuhUI`J7TsT1ES6o}8zjKNoLX({w-Vq{cnQdX9e{sxM$yi>b=jyFfIG^_v(-fMW*|%}dCmS2`%&yG*1oLF&}HW78iFkf zxEz{)DOpHOU(m`i{0-*Bjs>lhosE*W8Q_16A2y>carbQ5rVZeom9M$7Z)hcD$bkm4^Aal9PAiF zO5PmiTl(JR1b6UjtfBjtDn-6#Vi zR;|~7RxzQMv$*`5{>Huo=T7bl>4iHK>DGU6_XwedUVQc>`E-a?G40%YNX^MY5nmFx zB^J1o4%*yFKik|%$?~Fa9Z&ze%A>I|ss)8!suNJ{Um;U7*8b(2+Aq9c6jV>K5t3*l zL`3&9Hu%*brcC^%5!kUdv5FGx%N%0K`5v+4f~MSgY+9%r7ZRA63T0DS`(^1+Hhmm6 zKjdm_p5&U}{6O+1d4V*^kgA!CYi)Vb>l%-s(k&nK!qtAQ&^sQA!5Xj=LzCf`Wa$yP zvg>%dAg)iIVh|T6Pc^_gI4co@Wfg9$UVa|0po7)0^-8VI7D=J=K-uxn-yMmfWp;{r#AF$>xhD&)9 z|GB1}17eR;rY9Doho9hSQ9DJDHUChlEsgN`&@279R**W0;8w>U^EOG;#zait<>pVYJnfb;Zyhg)``8?4*R$MJF zMj;z}j_SgKH`C@syD?!y+=f`8*@)F$z<#?nb?|n-)q#N<0#={`M1P<>RnclpZEc7V zcOx_cH*`V$2rV(EgFpp0457XhaK}%P>U6pOgiY&-D=%MWwX27#wVr#snkWUZCyI0M zC|eFT7pJ&Y@!wrz{yVss#g@U==~il=ezeXTqxKtTp1(YWjhofm_f4J6%GmYBxy|?c zSu0tm)dr}(GKNQRTEDBr$g&QOz4)?-^Y9kpL%MDk&~+4zQ>-{mnfvKToXiy+b7+VY zpAWn5Ehzo;{WB1G3^Svy`J4PJ(=|oZHQ@rymfl+?R?=fWOf-92ngt@GlK!gw2tK^4 z^#naLY3L2Vg{${BdA|IIBo6t_AkO>UK+`Rr(hLJ_4(-{lvTkM(_a8D?fd??%<^ddo z9>Dbeh8bv?;lLGm3cstW3|^(YdCX^MYf)GiIj{)WvdS3F&inOW>e{io{>u0SpeHg7 z7*~t?FpOfS6Vq^~P^@_o6>#=qAKND7?&j{|b-E?>PvLwmbo1L5x>^`&6Afr=m0< zcHssmvTV-s)vJX+2tA20DjnYPe87QR#(?lWa*4KHNVG8{#*84t$$))f_ovPw^QO(8 zCRirO9xOgw10lb7=#>B@KQ`m{lx;?Lj;}E{r-Fykp1?&lN7D8R`8~ zuMxtg+S>igQx+V@l#zWwu1-Je0~Z9$LDw6V8hTM33Ka29#fQCLn{JaMTej^Lx*|W{ zor?%;gwVzCD~ta8L%`T8cLh^cY_S}hAW*|{g^&B95WuKTelwd!h)ENr)$kH^rFn)+ zs03CoXl`56_rSpx5b7+ym*y7*ps1?0ST(f$TuoX~q%qqzP!5dA{YhGA=xce;aOcOf zZPvv1A#Hd8nG8mLT;$=Q_#vr9}pdHt!D>gBp_`gZj_BZB*jI;=ru*bb%FZK#IHnQCj9*>2(&;F*_oB`9V)_D0 zHj7piwSX=>R?H)C&7F&^-y-h~Gj|F$(X5AsduY)B8O_8FBl8!9bo8DT()--W$n0s;f#Juzb7vH$1$f?P(2>v0~LCqV6{P=>nD zT4v^!$88lY69XpV)iEt1OQ$cG9zP-}mW&_+Q^W61or|k@-ZViWZi^FHy=dL8ZL5|q zTC{wX@ZFeM4PANd=TgXv^pe$9E;3++`j8y0Fn1s_cVW!4NNNSn6|>Nkf@^yX`^sY4u`Z_-fx?J{VQ(FXb{^D&6rNIt!H{h+ZfUn{L{uVsS zaR&bruFNXg(v3mvp_f*l-`>zQ^(Q z{7$74JQz@k5#J=sHFHy>7L)u#NeiI~7~cBmC+}Rf^1v*i@|T7z%!|oGN}Tsiay|jZ zXJ}xhf%aogQ|RgN8h1fVJP}{6muE|tEVJ=34bxB3&{m&)`GFfo4*#MhFmPCfKF}AG zJLtiedZ9xM)w+tdz$mCrT`7niLmsaAE3`RV$DP_=u)IRG@1Xuagp%uGAlaJa^5}7) zAEMX=w!zu-)K?D+^jE67!Pc{_#dZ8$0o;h0W8&0Nwu9Lk5cF8a?fR>*6py-t)T-o~(aKG`==Y~<5DB@?AaKHUXW z8+X&?$SAjLDK#aYVzwn5pv#dx=l~cgVd_q0x&~|Hun0Vx0My#h;Z4`D8nrS0f|2r~ z$vt3a^*mKX&r>}sJ_Xs!+{L(|QHL+JC5)zbRbZYe$O$^hfG)EFbwQv?OB-GXG!D9+ z5#L_N&v$-L*+%XN_o<;On#YHAzXiv|_xlBH>qXdz!DVSi&d}Q`cvIzBxX;j`7$UTh zBHxFK3OTSq*@I}Wyyf}rAOIKO601jG5T=gG4dJ4M`4V>2sH54Kt&cG1C1mc)II2j~ z#gA$<5-&@bkX2Dfy)14FP^c}>3Ecq*p_=T75#wUCNqd5!79(b9-f$gCXt8UX37sb= zVeYBMqQ&bV^n5?XYy-^jMag+e7FoVw+hEqHI5xV6MJin1N$57fXL$LyBq(^Lcv39t zFJ+lStH2yV#i76&Nrxqh_CQn7{KC9~+e%)+hi~TJ9zAXb48bs)#L5JtkO>&Xd?qMJ zfjA0=Ohph)u})hPoB@OiR;WsRfVpz=)3oG^pGz_+{Ke{WE1(d~mqH5VQHmI*sg|dO z6c#wjvK|*W)L?4va$L92>5I0|*=4ndlpWe;4mDK5HPAZGx4>p8fMyfvO0HOIMWjzf zkzSB8W(B6~(SI}2rplApS}y=qKvvPDGg<{r&?Sb`v)0rVOtTqPHs>%9}xE)_`tkeZjLhGmRkb1;5)bl-@z@|fY0xAG#Ycw>d<~nm-C;mp_&QvoTJfc3Q4c4e+2Osl=)cwwPF)yA+s`1NFrQK!epl# zDf_b0I^7I-O8z7lb{;$-h$$UTYuU!#leEE&du)-7n^-sQR-`d$KiI#k-?_GX8=wZ( z0P`VADdBa@hBIOsTWu3;!9*f4ifIJb$SsoUF{ia)Nu@zjy{_3$nR6xa@yQ!6o}Oz{ z7kB^q9&Kxz{!_AB1G$ExA{S(uFq4n%TB+b>WpsaJbR2C=JIVIJC^fEROgq^@8>6@@ znni~;D6%}u2rNjXqg)<`0uIwy^7+0XmxZExU&QR1HIn#Zu|fPW8~I*A0_Lk1KAL7h zX?|>3%(P zmnkD-O|XG>iO8U~9Gd`TWcuXIWvMoPixTAbMUw?j(3VmbG}MB_f}Cpv?3niw1yKgA zzKxdKG;B3FjBobs*?!q{hMbN$Jy1CJOxxjD%Rj2%oI6!(PKzT85-Q#EhZ>>aIDCCH z>4(vyJ_ADAV&+=s&0R8uc8#<4-Dyx98rb?Z>XHAycuk2|)c^g<;o45So z;{tCw3_#VA3C+A*<{&R{mArab#QR}QtFpOBs8P;iT96Ia`FjPhWMghJ>OoU+g%t&b zI&gl5)_4Ay{qkETGi{I#r$Mna2J9G%!(}q@rlg-v%N;8%H>7D+6d~`j;_gMTQ<=MW z8oFHeb8uYFwmEmvcRTY{!dAir3oRX@WYD?A4Zh-<3Q+2aj8Q`T7 ziYuBMmxI!WrN=FSc_=S_G0?VoKeIHs2uzb3h-q@0{qo~0Y>O{U)TIK(SmKJfo~nK0 z;JT2-Vh7g13`TJrz=y^BN+z(FpOWY+et3rf3PL%5&-;Z*x%Cv$X3eUDZiz}_9sFz+ z_&bpuF~x3)EnS#d&9INz%=@f1^T@o<5=$Pow$5Unu_$zku)I8ICC_1oQ(@b3O181Q z$-3nJ!X;Oy}{j2boK4w$Sqn$7y zZe#!%OOmFIoi2zYtLv9cS~QiVtLD4e{xO=}9_^zS1b(;m(WXY!uYDFe;WE0x~PA*x~N0ZMLqv- zF6#9&4S0g{9?KI)^Hxt)>A1lt_V=;EZ2U`LKyimjt~S#>jsMI$hmTfdGlkr&DEhzh%--n8tlA65})rFd*Q*ghY!X-+SlLHns z5iDhNQWa$49uM};6cYaCa6WvNy#nx^lnF5kwGUX+`ybo zmX=nHzX7k*HEtY*1N>EgF^Gm7&Cp%)cP;F%106;TouR-=2T#B53M?M$Ch3 z^t6s|MSmeA&r^$$tp+5C8g7&MVAzTCS>sI>h)(3WPimVDg7_tKbw(&S*RS>A9jUG!d5K8Fd=s>Ob8QkAVq?>!yt-tp8 zgw5f^SD@Q1l_aD|A4>!OcA!FjkE;mtJI3Vw{{6v4$wLrVLAM%=i~#Lng!4xF!D#7hY-+Tm8!exVv;j;b+=(q>Tkkx$#3Tr zsc*vieX)L$QXfw+()IF;Q{ae+Yi-YWJuO~9Wo5i{nM{E7U_YK*(uz52@URXT=b$1! z8;um{6kN2{?|L3RE;6_|-Xh5uyDP5L{y^==&xU3bFiXVRT*l@fz<$mI+H5wakl4>5 z9kkfWp273Q?QR<$!`-HasSqkg*8$6vac5sy!;W_>41P?LZ zE+(FTJ+F*%w=EWUo(yIrGjre*bl-fftDW|1P24n813;bEwpoTVb zGifucn+e9FpgZnx=t8gaU^?%45l{CH#1>o7F5PMn-)+M?ywhyQB5kAD!J3@AkqMPg z^T#ei^=zaw_oTGbFb$3GUD!?MZ@NI83%Wopv`j%VCM}~RW0on*JH^NX5-ygFFy7193r8BW>)=nCVf|1aZT>n>|Q!GcBzdgE<1F@c_Fp z9!=aDSyc6=kB~rXpCn5_(ysYs?WA>6h0(OwDY6(((_fr-aC7=Tq312_u;IhwLX(Bl zav$xY`Lsm~*IYH=b89fz$V1q>e z9y1ruDZnUcHrnB(4&S}KLGZA6Xb0_zI*UI8VT2mEXop;d@>e%QJG5b-9G>=k1Um6` z?j9H-Wmf^mzwi=>*(QP1Lyzgzfp~h4(7>vMw0VmK$Na(&5YVqU1iT5JZ5e|0KMcY2 zZHq5@K!3yEaKK*Ks5d>CeBdlIh|-a7@cZARZ#+S7xsMc*Pq zUPGYL9%S=&Q=r`K>uqm=kbM;@PGN_9w&L-`J)c*x1Bj(bKRid;9>ryqplA)jM3yapky(8IbBk71$)-U?hvCXK)(UafffI7C1Xa>DkwFB2bK3AsgU zkw2K%7K`{3AC@*(rJ1buCAu1au0l(z(gsp@*a*(V4S%9Q?&Ro(4;6_!`@Mo*^(8(rpxsNPP-tw|W$6Yt;4L8rBf$9Pgnb#7C%lYOsaz|%QfR0?sJa$)TbXGgaBPgs3#_D?S zkGd&9#C@8io4SB3APezS(4y%J1^79K4%4l_b|mc*xkz>o+v_P9@t7b4fB1B@r0@#@bYR+-Doh@xQ7ER&?IEZc5ihMYnCcwNC=%( zbM;AGy!0HkvG^=trmdu$k?3<3YF&dmMUP3)(kN~* z59pHa-ldfLY~Sg9pn-|j(Oso|B#^G?_iv03L>3DfK4O5$xLkJJ4;>%*A8<%L2GX(f z$Dr>~@gT@}3gwtiyh|YJ1+6xdyg|`0E*d!Ni+*rH(v5`qVQYk8LE7!Z4vkDl^KM3N*~2{8ABQGL&M`GSXVgHHt_Uf|tfbT}ASIff zl#au!7l-L|pBFe%=5go35}++gXE>9efgX27Ovx=i4yClE9$b|o4dUp*^bF>%W9qrB zdd^wjb1*Aw914_~*JZCO;-2K(KI5dl260PriXpEiHcK^#vB^-zVo(~I$7O{kKsVgi z3h=-_w!w)h$+>ppP|REE+HfU@6d<#~}GBAc4b%_zH&twd;3mT(OmGA?xDFP!gUH z+dojCCgy6y?pZM&J?EG8T*mn}TqoK}^iB{K0V1WOq!hFKm;YH6s&TZ%<4_ zj|_}C2Pq1j8*|{GY?AgH2cvb>O{MY;uw}H%xI$ork@r6K7<^$c%fSzPPx7&c8v;jSt z4|JkC4h0*#!mf`!?||wQj3@w@=4u1DFBt)*xgx-Q$yR^|U9BD8j)M6Rp1g29PER4N z__H7BnDc*Lo~V{jL%IZ7%S5Wx8?!JAu;7d|%w|b5v3OA0QrzMq;d$ve<#V<7w?SY3 zodX`D#sdr1)69F`;bCam1xz~e+#71%pg*#D%|1LVwPNDx3FsY)o*g+efb=23W25lT z7=O}B2=1a6_f*Z&gN(2}aH_0vUn>gRDQ*0f0P9I@r4j}w;p5*ZKq3pMxR#9MTIoO{ zbYfQWe?s5VV`0GS4K}1CM)@2i>-feQ6%?cs||M1noF$#!$J%!yiq0e=?&o`R`%RJWBUofzZ@)~qm+lyD__xYK0TWpzh>#TVSSG^75o<``%zJ`wM ztNHnG+hHC{$1231qxk-jgu~30v;;wJbH%Oju_SKGV7c8#3z0Ebh z*9Gp*kG~{B6D41KIRlc6p%w%(QuzUf;jTy7u67Iso@=J{w-|7@3zt_($NwW4spv3$ zLO@g;rXCg(qlvk>{)aSeVJ_J5MO?7km<#p?=7Rk%seHg3W%<+fzuJ2bxG0YIe|+YS zyIVLw6fwq_J8SI560snPM#YBRU@5$sU`d)yQidskw`f>E(6c8!X?V>HGVTVgcM znI*a3duDIBL&a!f^2zJ}|L(qKXLjl{&ph+Yvs0d3<{-mRAZ3{YC%%af)$P8^Fo70? zLmn*bF>A&2Icyb~cOfh>++kdWSD8CFp~|K8YoBbXy%d`(_AT4GP5yy*I#S{i&MYXB zT&q>%KFI(R|U z*PUm#hWr?4JdMN3IIwBLfz7TcwmUz;>1~_IH6s-Nsm>ra@t0dS%KfxE<0IuMzLdUV zCf`lh_-Bgkm*0PeCOD(-`D<*9DY5;w@Cy*Z$k~ zs$w*;G3gEbf*T)wY@H4^ckS`PW5odOVV;$u@%ZU{Lh;NAy-+TwgrqAUf4ic(I4XYht7lm|)RHKghMmUZduE9~m2plzB z!;czv#Nz!y5B475)lMxYM|!Z0>Z!vF(dyWdPc#v*)@k;m5R%rXXi)e93J6JwT&NqE zl0Mx5g+s16c%-8y79s7oLabSz!o`{^2lu9>HA${*?I`yjIdG_i9KK3T+Oi$ebwW(S zU}^0>L+>ShW`}|hNaG5MAKG88yr|={2q|Ge(x)3`DV;$2Jje^h@lG!5`U0r=aB;Cn zlMSvN>7mI*C_gnrJXk+TgZ~}C5BVsO3p4AvFq7yIX4X4|nSqni`N2=%)>ipj%Ie_| z>k}MeJ%pKy+}b;4P4Mm?`@}ZwF~ybyzVkxQc0t)oi6{7e?{A%HV*LuTJW2_rWFh4} zCDJm|q(nYa@?Z~z?GLxKz5YrSY&2G?G_Mp8(EKV3u*@*AfIZ(`ws`wvGUI0`pIMA~ zZ`*-fKPxqDKUXvCY`%wC>mSNYa&1;UzN9FBZfw49nM3TZ;=$m7%$=qS!~cUXSl zgMFa5om6sL+RHsg_l%WhKpDw#e8$oA@^ZBD)7iF$HFJ_@@0Fz+yW7X(f@f~)4)|K%?yAEI6UC;M-s_CAZzz8!8BE^l9G$DhMZ-paPWyun#N`-72)+dKh^e+rRPR zg##VyA$CaXb`_wTkfpi>x7y5g6YkrdeDdVB@a8ZF(z6TZ#E7Png~H7{w{*&#LJ3Q*JJ9?(44`V~mIc%PG>q;&nJ z@zNlm(vrWZQqT&h3jY$w%$6lKo!_~=Evi;))x2``&|Q}=?%H?J3e_btD+tX2`Sh1_ zK@&kih}ABBhcScyXzE^d#@`#73kvQrebuTTpTQTg@>IxVa(e6^<)DTW@kPkb51_;~r{9C$$`v!dR6Cac zXZLK=?$T3FndQo6M)bC#m~X8l#|3hoEbkSsu6SGJ!iQV1_qs~`u`1SbX6xl)Yo(SS z8B#hO>3wQA=2v~blV>sMOH763`{@GnvC0n{98&TmNeQg2;hUJGA#0t6Vm&REpj!14To313KAJf-ovaabIqPvg zZar6r)D6mopmrLmWVs@`{Om!u@3CJ7&$&19E;!~vFw9%FrqHQ-q6U1t=lz?(E97>f&kb3sVyok~c;fsC=LTIEv~(Dz#rpIc)Zz1J zdFWR`3#u)Q#8kYza@oRUKCH04r`X(6^v(q~6YE5~pkRWz-MfX6&#lxg=ooe@QHDQ% zEW_NaU!3x*-eUjRvnl(}U)bHWMvc&>)i6YiIo^2?+mITU%7&!k;P~>B4^AF~;fk}1 zJ`44$)wXs%>nKycZFNqa+II4(CEoP3?a5je-(@LmpYlWv9*yAI2tK6-pQvRS%^vsx z#kUMxt#&izk7F_#^fqh8em5Xv<&VaGE9Q5rZ5?i^J*0czzC+fYw9Gc0oS(G90!dNi zyJCL#7lPNWz?fj;y3!xp{Pj5C3SH?Q%4(=cKa8b5Ki!#82R_Ri}!g_*9X< z^XTLVespq#%hAaL;^<@)dR~yr(Mf++3j#m@rsiXUO<{_HEi{YGD%P9h^Z)LS>A zYv6E`FaEMZu+kIc=Zk-&kl9tYUNZVhqu^44;E)IzeyLqmxKboC+{l)H={MUn>9eU5 zCd<MtYW%$hYVCT3(@>WOk}PeeJ* z!u@3O$nEBdH0BNYka-7RE?c&4fRfEJ-lTXR3%F^)R)DQ* z+f=lUHC5=*wq4tv+pk$Bo35?iwiSA~(w}{TZ#ALl2$KO^_0N$b>?*v(XQP-OfY(vB zz@g>|KARC~x2hP(q2&q1W0}Hc;foV|0eIXo-z4lf;A;|m$AMUWIN?}**qzF9VBH{N z>jBd8x$!-RS-u0k2eWsNwyv4#1cJTl!=(6{rjbD{UO{-Ks6n?^*EH9q9Xx@bSUBlaA<5|S)=mk>u zW`@N6Nkez>`JaQ=)Nk0dfgAfRk6zquPDfe#TVrWzG`-E^qSbgre~WFHDd#t76>(;*hSn3LDNNo31a^`dq-%I5=A<8 zt=kIad{)CRW`^zS>8!#GqvDS*T~80@=J9Z*rzi6=pWHda(E zJL{hKlh$V>9)BTwhF>2Sp+jga{wB5_fBmxQ^5U;m?R2|z$90O{U7t%|06&VVtM8(Z z&=1lljB$-I z*|-}&0shhW)TA?cm;z0qrf~f9cdco!>0A8Vx0+N>YAyAX21#*Jyp$lVk~T|E+=;t~ z`+M%?-CMbLaPQ$h)qSb^R`;Xs=iO}{?|1}wwDTC|G2LUC$1aZ>9?a}+4l)lkk2cRW zrH#mmdf>Q&aOzE>x&0baws zW_l%g9q^XCYkP-!_x2v*J;{5XcarzsY$RKbY?ZS$$kr;`gls9lsH!9 zfyMkVRrRlzRxFc0|A!0W^MAPTKf544|Fet5oOz4gE__FeEp}#<^FA-fRo?*1rD-BC zm@zH03KLeV;Ce^CyzR{Szpf5UX^&G~RX0oB>gHEyQ&;j9$KEX~hY`oVN*f_oPrxUg(v;0J z++TL$1f*QPqHt)?u5RnXHq}|e|21(GV8yUt)2-c|f>6&|&D)np`Xawvbj)hL?L$#l zgMRLYsYkR6^t4AYWBO6W$f5v51LpCBb+x|YD2WozqyntI#r&(xf^0D9@>7nu@lc5Y z&BOuea|~wuSZW^rpc9ln5AFcl94;83ES6|wEAe}S{4%s@9#%pbW~5}cGQBDq=oBU; z%NcFuY!l>L>H9IaM{R}V^s?y_4CY&MK`30%wK13-iY?6bFr#+N^j9=w2>lr5reVvu zj?6tr0c zLpuWR2G{|>m;a5gvHXu!ck^BO?BZ?PHf>sbOuiwRtC~7(Z?T~qh&P+!{-IKach3)* zgh_tOb$QSFP5Y!yruVqKoq5<$#fuFrK@JA43hrUM{6CJBCezy%oMON*O8J>Z0?4t^_tk zPs~*p=M1NWf*y*0ANebu{PZY*KvS8~R23}dQgy{C(c6d5-@luxo)HbH zUJTTcb(3kW`@*?QGt+&)hv`w|+dEu%EcCm`b3o)4dDXNPbESu-=$PoSk+Re&dj3`` zo52b^Rtn&I#7ik$w_vKW(xgb=cDZ3OUy-*buihbHBP*p|s$xlP;JA9vbv#llh$ z{f0@&b|L`t%Vucq#A?y+P>b<9mH>d|8qjZ!U42CP1AW@vM$o_A(}}^HpZ$UV;lQt$ zEibg5v&i%%hQVQjhWC`CH>T5S-8dQP{13^+cg;T$4(u* z!Mt6AG1(0@y%zJe%~0oG2NY1pKUt|El>VC8ogb7tAfL<&qcUF>#jI+lKUo$vU)#6y zoK-&Aa&_=ziAld=U*}v|u7};4iXs1u_8Vox_BDgM_2@mIyS08 z$}H!7MYqjh{z<;D|3cG8m~O?oEgwn`$}2W6x+n!h3w!UFPq`NM!SMs*C3C;&eP;B9 z6864fg95n{_SvgcCF~1EFB&B+i(MJJLJUm!?~D&x1^PFkeDejdXXCSyh9&doE|XVF zhg)oF(4a*)zSnxrjaV{7GI#C2ByrV}uh*?x8r7?JWdE*K^N%=+Fa={uplu?i)N!aC z;IYi-+Ao^SnDIKk0I`lEFe|}F*%GAa&H)}BwEfg$7SoGz5DPJy+lCsNCDmEP*T5Wq zX5n9~AFlG>*FY+!;6E||VCzo9zHTQ6;r~P~LWg|2*R`fcq=)z?pSg`3HmiGr#Ln4> zVMT|zp>i{6BL2Qs6mz2a&_SWu)eTy5x67MGBt=WgIdsN|jl)vpeG*#bLh8l3_xN;K z5ycHir2p9_Wfi{hlOHO)IRH19YL z@K?sfa{V41TS(^KdqY-y2>n(qGW1(*NK?}aOmsMZ&mOHbO~87kflJ+ zk2a9)*}Uq4WwX3~)XLZ|`%dXUEvkKoPoj|Om6g-#*0YG#+e=|6ZzKjOi0Kq_x~y zj+!5{60h+UPPDy;8r+kQr^MfuDjH+DM@6-gTgg#h$E=kq8K-=B{1YDTszeEy=0sn~ z$@>bJXAYyeh+M5%wSD*jj+cU+`lv}MIk0ZE)DnEgwFu*6u|wX=8p~gng40FS$!?QF z&k5&GzW4K^bN?V1RsQY5<;6_gb!5+`!-v$q*C=F9_z^4bc&ieZEJ4TX-@BLSc&?xL1>ei1XDxpJMj0+y{_y70R(VV0iZ1gd zGv=z6V6N)0n5$|B-q%6QRhb=ARkaRvsN?Mh$#bV~uQ?3WBUdmzwJbV8Oi!7^ zBbIGSPF&9CraFkZDKk!GOvI*4{QPht%OgXt;$p+q6$g)F7bWH_ttGBN(o!aYNIzqK zrtfxlse(1_YAwSc+G;}*A4rkQn~kK;?bOZ~z5isJ_6sd+X|E*6X%2#nb|FZJ7A-Oe(v_yHVm8!;sDf3ZI&a|LB4Y3Ct0db@+}_IB zy(QBZm}DNfC}M86sf*{&UWRiv+E8JUBc?|!7~F15*O6U^fnxtmd7=7gwsytJq_r#i zbnn)uZ+8nHW~}BTMcLIBCM9>P1&!{m!H>HXD$5NF=5HO|tyS-M?%fdHGDLjGFNn2$bf&>3*g zqz{nRP2_}!$lHS~q@NRAK3v4RPsaffq>6|^>~@k}#L*EwF%Tm$;b->l!~-yR5-;LS zvSDQ)JKkxFW)1R@a^!VW@OU{ga&~(~-Z?sU>@$EwbcyKKmkjC_)v+@f-lu2xj$}-q zex3V}i4g<)Mv+O8u*mdi9&>JV&xmd$DLT4LS(1!rIkFwk@?;O5ACW_NRv@W(`ja!! z13N{NOVI-(qsg@aJcnC=Naw%_MQ!;ThmB)NFP>_sNw_`mlpI*dj@tN=oWxIrV7&_| zyu{O6JhO=>7IxsTVpOfYyYS(SOo7qdz+e?plhj8`x4}}*1Tu-tBn!!Ml0-I>6mp21 zAQ#9ra)QksyXbM4!fbl9_Fye zIP3`y`x_NX>6+u+roOxLX

#z7yELM*7l2bSK?HH_#n)7fqq7Xd+!r*U=!v^8Bolj$rvht8$*=x*{U9Y}^j;rXX@1Q|>_f!4jqdn7MyNd}Vk zSXVQU&NPyAC7l5G0MeaA0Lyw%geQ95Mq(k;$os@f`l08Yre&}YkMz86Atg%4#>+rT3(}TDDK!K=v_~nOQC4@-gY-eF2;>`uQU{X3-~*qc ztodXCC}j~@jIwu;-DEEUQ9Nr)YuQz~5frb3gEZ5Uq2R9>=u%NqUN&rf29`dJc8F zNN=Ow66#VF@HYZAcLTJsI566oMAF5?h_Wx!E~GzApwkd?5_s-P+tMX)p903a z(ROqx+^2#2?zBB!2KO1XLJt~7m&1J)?a`Bl(-m-^L(BA{9q3AwKZ#Dpa|(^e^R{TK z>}abTFutJ6ob+qB{9tmyyaSUP=3SUP9CmO;9iUAG4vrzVg!eq4=>*(nT8tJ0jg+J1 zh!mPcaG}0(8qJ5U*^d)3i!O?H~wFj39ryX1%7m&VWOk4+EvWPAQ7hFP@VkvYvT|rm6jFjtLMo2z3x{i!{ z!1XhYeSqpB@LLY%`O%5Xdz!4{#ENsw3Ia~Fv5JpUu4B|jj6<16A&wE=HZAew<>??x z>gY7VT{)LcfKOiVr3o&h_aw*YJq0Pu7+strUxH)gE9S^&GPpN|I{_S*mr@*0it$sW z7*#G~DKTb}4TzhAG{JZ|j!c2%XM~iU3(~*`q%`q| zB%();IZHnk_Gvm;*r(8!xc^B=EZjZ;iGbV3MakZDh#HFya)fdz#Rp@}Nb!D_4pqbP zJt1-d6mC?_@suNn7)MMs#%U2FR`rA1=rX!+eqaPfp6~a36!E}FR*SfPXXFtwAO9Lq z!`1HyNY)M?+PiC11fW&93IA^45;*Xt18vf~BK7;ovpz63ip(WTAt!$eY2puBl2)ND z(29L9A`ZjmfN_xfrl9A|hn%wt63ijU12<4=Zu?U_8vw(e#K+!{WVc@d{ym7V{XWTw zFhBbuk_+y4;Lqc}Ykx%Y*zeP6a2t^VvF!?CKNYca+ixP|5g_zKn%s6S)A}GR7vki$ z-$hDA_}oV-9)1-*YCiWJdGL7Gc|7E!h!UP6?qf&p4|#kMVn)6L04;J7&^|(p`zSRL zW!(m}_W|is#C{|o)gxE_=FIhW2FxmKT09d{`q;N(M@C@x4>ONJpE8>{^X&#;no8#d=H^6xsZo}v_bl9Fgxt0sTHOs+@=dwTLH_Cl%zi)p8oC{c9H-7>5eWbjO zmimjA{Wxxy8!254(Xd-_NJ&8zwZFfmzmolR6O4_@7Is7(gBbE zSL*Ou@D8 zNnY>zt2J`Xo#V*)?#$6aXA11=Dks6yHKv2#In!o#*^j92FZSBZ@m}_3f53f3Yff?W z&r293XWGBSJs;!I0hnc4O3`a~+3$+@PwkuSY2d#<*mq@w?^j*+XPS@W-K92}L;may zm~i2juZqpN$E(6Khe3K3*Yi?H=2$O(Q`<)1U?Oj z$b_$e7cK#VHk#XiRZG!$zkN#PQeWrI0nHRhg(K}7`S=4&J+;rk`&``nAoc7M9G2tj z7hvfoaCw1CiT2+S9}*<+woxkyQo6V@AbW$B*Ye2PwqF+Qrt(jYDHrNhF$3tYJ8JZb z)VCUOKIPg_oGf+2IXAkZ_^pi=Q$|&*zlTkmN_NfETo`#<|Gz;kN?dJIq=+6 zj-NsI&%-NXWQ1lEX(6RD+}z>id~;e4*dfDa_-UbFYRqv;_RPj&6nfswOaGdar0sdNHs~2dmiyGVf$|aQ(Piczcn*S8!x8) z-}*SdoigP8e-9dbv;6~Kb#DWHA-_(5go@+efbpsL3gF)Xe9qv4%Xa|pv6u&fAD4VD zh#oA)$F~8+U&+J1$9~X$(!Tp`&N{sw90F&VXAcC&c)isBRxJCCf2*X|El1<1Vw@A4 zLU4~4c&!%ib@ToE@w5^JWL%aNQUbR#=l%S9=FtDzn{!X!ZYPZY z8#?>nl;A7gNr7|A#XtE?(F5AI6!Op?uwX{G0KdGY$V{sjpMk zf4DVYoEdtZ3jGUl{{M#QsA$uFS{x9| z#Om91VP6+tQxyB=-fqrsnwvJC2WZ4D1hE(B3SSN95WZ<{e|PRW0kR;;18?4ieQ<4c*L{j(hY$#B;-X{|N2^01?e)7k$_qEPuh zheq^OJ__*_iK3`3LR&t=cA@8}RcIcwEbILgVWD&%0j(vOj?wr&>(( zGARUDtH2b7amPs~cT$bi&IEr|ypn0B%JfkEzV@- zMjdi%$zgN&wVS}DT~^e}ikDm&rVi3;hL_7tF!FldaQtdU!xg+TE(0*fF|QdOptc0Z zt7^=EL^C}9Ccv*|Jb`J=cme0!cq8TWCL2ycWk((O`OD@RhL@I0z|8aK`8ey$!?cU1 z)(p=j^Cf}uJV;|upZZioxps;Wv>ri=y59B3i+ASy)VE4FnOBBPA~?M zVk8iOoa)r8faY+qwKh_{%0uCA1)PqpNInD<^<3h)I-zw}^brnob=QE`cI$Cw?Zvw; zdD*S@UA@TLh@MQ)yQ;#NaQgXuylMEgh!_DGl+S65_w?ezU$dS4lKXR02|cDZYVD7@ zR|NL>We`sSELH+0~U4!`QaR88Q$46s%OJ+Hh-sqzU&CYh{2 z(2sgGz&SeS#oa|fZ`nYt1p&A7E|gINXKc=&if7#1UE6V26p=~;a_3zNu&Q?r)PUa{ zcFm9P1uTUcsCPNMl|$*JGfZ)WYKHTLhA=$E^QJibHG@E0HCzmTul5qd{W%S(Mk`0N zHGghb0;V zhT;@zIno<^<#xTg^O_5`ZY zpV1s-D$PlAk~K6J%|+JI+%z{yqIqZ@vX17ZACPZoQCf!VpaHZdIY8^vrX&?7^jng1 zG?ca?=b?9{7r7{OGu(wHsZr!9PSlPkj82Ab6dR4l>H23lQN4it2JJCxsgCP!peAU0 z_?}9@F6WBm%)6n28}IwcAb8BhkbPg#CkRA;rKL#|oO!RR+fIt;Mv=1mrlgE+Gbuv7 zNL9LpREH@;*N`f@VWbxP3ecIP66{(!cl&MK8B!TKtMcf&lCrv9q=arIDWvO1KGaPj zm318vXAtt5L;~nLq#jHWwS*vi|{lxUK;yrdt4*0s!{{)T15w5NGuZ33ngTkXlG1YO&jN zb%eXQJ{fW0ubV95H{|i?JcRv9^3yq_0K)3%nv*>G_9UOK7V6dl_$fm^0**hT4ah*) z<>*gV}XifUT{*8mRy+GZl1Uq@-{^L0g?CwSm6| zbP}luQws4G1Mh8hrJ#`p?Sl8wv^FV^bS06lg1#~-C(Ia93OFy$@%=L62Dyc|fxtg+ z1Bao3_Q$*pU_XHQO^-28!#{5WR|B{j;k~?Q1Ktjr;cc)8d2+mQe80r#H^ZN|0r2l? zfcqcO2F+pr0Q0lJyM}+>2CfD)iuZh?4R||fhPMH4W7xdzy!_{FQFmTG$AOD2XcBGA z>n&)4?r-a&Jm=Eb{e z*UI$X5Ai+&4YVPJd7E(jzF_ly0vw6{;$pkiCjt1$&4)Vl9ZtUvyOzWLi1#N>(=XWQ zV}i~#o3}B?^PkwfKZ-uVX@R$gqhIpA!TV<>JDan8I9+nu5Ol@cR)eb@DGge0n4 zZ-W^JlME9GQype4`c?z2?B{I(17JZsqQ3)P$iJU{!$(Lf*kfTJd+B^gCH*MD^QxnN zalTjpc&QFk1f~F;jj%POCcQ^`=yQ`=Zb!i{JCTww6-XC*e)Q224pSO-8JHR{AHh_H zDIxl*)|b_|FT~SzL!YZj3ZTszxwRn$b{y4|4ZZ$R6;ucM!5*kedR zyythk7joF#uMkWP^w(OtpTX;Sk~ca|0XnaAryig0+`)`1U< zA%QP5sB=wjfa6jy!7ycE3d0nEdCy^&ht1=ZhA9JH*#xE>OjB;duQ~Sv5C08zSI*1f z$J1Aa$q(ZRQx(Pn!}H>4+QYmL(*tRExq&Vw1nyceK`<@3KjMf>myB}x7~pIx4!_EK fvuLk3iu;5df&5X43=!WrA&^pnA;WAXqY3$c@X-lI literal 0 HcmV?d00001 diff --git a/images/dialog-back.png b/images/dialog-back.png new file mode 100644 index 0000000000000000000000000000000000000000..50e1314b989c515e5f56ef660682a2ff9d467eb4 GIT binary patch literal 8083 zcmb_hdpK3=y4M~xEH#R?h#{A$U0ZHpn1v8lC94vWg-WL843&Gtlv|_RLbSGoFp*s< zg_5pfhG~X`Zf;>BooVf-4w ziB;fl5wBm4_y`HDD<}S~;CkLU32sXJn%Mas_H_33KXKMc$m_&u4_|c;Ctrna>YD0W z*to*!L?Iyxv~SPP)=Y=tw$q{3eJQ-o#a-iYS-Eym=v!wWCgX{k@)RSH&z(I zZK_WBOh>4wkdT3pj>nfD8uO0V^o>7!_|R*N_j>HjrueXoB|%^3n+BHGX^)24g# z-<~>?lpoGwwTtQV{1AZxh?*m}RSAyk#R{x-KJ@u4oXJL$ucYFky_Z4-Hy;W9#ylH~ zAEtvC-Ec2Qb^ZR_fn4jGyC?R>{#Xny9)LVfr1N%3LZM6J8Ap^)(w=>9bFazm2v228ZoKetPc^BIuGTRpPLF)Zl9BLW==y(I2_k1S{~J(=HHrvn%w>!a^#tE?vZDMipiS+Yp~pw@2d(^D~iIorN!p<%lC$X{kwRFerlcGoq;a9@;SiFOaCcmNc%q_%KqHxM1)UHhdhGBCT zjCYGc1jGa@@a!lVYjMqYT8hI8&dy*3kJEy?Z=JDyBu*f08|@Hcu*mQ3oNAdH0motj+^+NQ{&W%Uy>}%<4GF5J=SMZz9L%g$5 zJC#`6^$23WHh5wD^ezHkH%@n>$?t%trAC<{c^VvcSsV9)Y0RHMD&1wF!?VsjL(Xy# zKkUUcF=-9)qmPK7wVf(QlarA($KvtkA(^FDzFyu%l|`DNx6V_&CchmbOgd;O4UO-F zOfW#qx#uB8lL4_fV|yxYg-B#b(CjUrON$Xnlr>4k`R^ZAqe?gWvzebPieK}a9&Eg|f2?&b;|!OK;Y-E5mLCQB$7yr&xYLtSgL* zT^x798)%9jTm4&{iI@(VW12b?hQhnaDW710o4SLdukTj4>qD3}<#(54IBcdQl+>40 zC|$zL)8MijDlyBziv(JSBvRvX5U-tZoYZkeYim&g>IH|l#o)aro4-E5f6!N;d1sldToY z89jUm8ESnxs;&dM>WFo`n3^$wyLdEJ7D=Jnr_Hs-4fYg{Y5eClD?cuY0TfOa;(Lpe>CG^P0rgBKqvU}$F>{l;Opp3sWHpFigm6lim8pUXipYw5h| zfw{}gQruG0ahd5fSrVuxuP}J&Md-7$fpPiParl8|HyR4rN`9t0dfctZ(>=-;af6-RAh}p>k2XrK@gS?xEQKmWZ9W{~R7!a_-%)+7(ltdKT zJ`vP>9!XP*!e@H~f6e@670$d!;i&sw5F7Oe|xAwXfA? z0tU0%>!GCmnB`)jV8#mh=mygf`_^5^-v_rm43GS*IA3fABBbOhAi|^b*s_W~|^vtt)@%e}yQdop(CIVg$KK)+w zdWbXoc9-JfD>nz=6MJ1j3L3T1^2VU5%Nz>Zmc0#M%gEGTxj#d0v|pT%qmzl4roKLi zQhUh!u;va-PQ7;`s6m5&p!H(Pnxq&yZ(a?)K47kN87o+X>7?i0ePGFgTWE5X4&?1_ zsrRtuZTPGjY_GTygvD>L_d(D)+VLZxY0wCrtvQMmiz_O+l(}iYl&YP)r5lA=`lr;J z*}d{B>}t7rW_)Fm$O=$`+v0FH`BJaWT_%X^Tc9K(gM~qYz#h<;B&UmZ1o>=^!MV{4 zg^)`}dr;;;l^v|x8raaSaJw>x?WSE`_pxrW!B#=VhR8H%iw%I~hi7qnLXI7j0isNNvcdW;g~h>C&c~*Q#oktXJvSuyaB3M_}s8vT=S6bhkOpZB76W%PD@)IQ`7h; zK|SK(kmIZ7F?UI*Cn=7wStnXOLZvO&p$Uo39;(@1+J;edD|Ffq|y?7`y>F2AeEIxgfLCPfNq6r>B9o%S3It z{RD-?6Ars#SLNQqOLGZCC3D>J>@Z^1i`DD?u$SvnCPfPtmk;yv+D>#Hy^5yl3Sn4sWpzpyHZLHA!g>`v#P2meBHFuC@Fb5dh1ITd+qqmb^EdU z#zvwBW{P;Uy-1|xQ8ZdL+L4pc(l@hC`;1Ul?Q~>`K^ljhJ(!Bms^$i4P185})vL=| zS5QR4O4Spt#>PN*|H%z@F2qaySQ^S)b|1~UlKu5$@-e$A(Mt4=4pBrLg`1S%>Qr2p zKtoSmF2nJr1l0HFlFPe;lF2``(I}t<&JGz3+=;`FkubbgjV7n2<~Ac{kq^h;Yw%-w z=L(zqT7? zIwDf>%l(>qhUses;^EX_!CykHrJ$ry6zU0t^>&4ZmXZLz6N`t>hPPs4BQHlIs_ym+ z8nR3#f+Ti3^4(4#Y7gYp3=a|VFaf%~@!&s!((Lc7Cad@HS3<;zeTIBfWAI9!1xs&4 ztrrs$l~it{5@)~66z!MNpk*61gkLmzDiDoVz3i`8L4lYd=y6*yG0IjwE$zg$3mj_j z4%l!(kb4$+96mmNSD=-}^zvdpzDk(atI9P_1pm6PSQkR~ya~ZSU=J&H))N z+qTV=l+lAW(vWSQ{oQ!{w<=9*%{tQ_lwYg~zl)9haB0(2#9j}su_^b%5d`^aM0Rb$ zxqj5Ksx2AT9QN~xgjpUymFPOBpRdZPM&XUO%@Vwt`E&~yls@Q>UFcAX-fv_+CFf&;1;21UF71;=OsbS^`;p? zpyk=r3Z(3nRfDLokkA*SL~N|tCBt10zRA4*XLvfI;bE2Lc4~)Lx@9!(Ily4s5Gwi% zg~k=TI2=wi%0Da#q@gCPOVEBQFFy2h1$&P?^zf(i^N~~+t)9{(*|{!Pg0cF>-pDm= zsN97+ftQ}WuA#c>wb!_FrXk#wam&*>8t)^4+}z8^G^k5jJRXfxJG0|O!y_qqEy&wM zdgiE^Zu7CNAt3jca)c)+#zX+dJPjzkLp-0}?C4F)@v`dfsQBnG5!2Q1t9yNk1c7Lg@`$ zwi&8Ny|JWK3Oe%RT4b|g0%);mww`9t$VGK!3|;(PaU3DtTWbwyo#gRFdQ z-%Qu@MY9l%*TR$#N%`}4fO6ed?-LF*M?URn&?i=MjEvG)x&lswk0sX0=~=Ib#+W|L2N^LG zY`FFHmWxmnC^yWp0UZb&H{^+IJ#g(t(b~wxE>N!YHBm$UF%u+>A}!jTkn}xub)3A> z@jhnVX)>=B&h$)X9>q-z5|@&xG`=5YVWba4b%L~7?OoS6hoP#fdISkNv>wWVWdO$q zM^#|M9|@>#`U19D!#ILeTr!PY`*Fv4!8L+Ea&&OJN_c6nPjK-n-h!y1h|%o6T4%>@ zH0pPCar2gppFt{6epgHjs;fZ+^(km-ZES5v4WY7MJ~|DO|w*jj@nYvH?1WSx)W-iI|}|Awg50Yy*(u zh3VItdXfyDn|34jb*bO&c%P6u$Gn<#Vefq&VXrmsg4iP}lfy?)oq;+qsL zCpsLQkXvUpX2H;4iW*#wJ_}B%Z@|Zfe_K=;CyS{5?n6lNY;S4+GMS;5D!Nca4L)LE zBMWiO*Jlv2?r3^hbmDF-uG7v`P16TcIAf3ipWrVW2)LX&k%)=8Og7R&scHJQarj(H z2|)~g%{(QBc>F8CS&OS@SfLA7yVy+W-PCx~bvmy#dx40F-_;hBzmS_B*-6dL8g=l5 zNsHCMCj+^qqPxpCxnc$2XnT&R92+{UZG8Vqz#`pgC;Z~OOcX7kCs9+^S3L%&9_v6z zW8_FPT!qqJkAP9laIwT)9OaA^v-QE zoqsA0)rEC-c9v0o036U9pz}(*oOx#7hGpIfFYfhuMQki7#o)CRxq>m}Q~$6ehx5v5 z8wfcmm~Wda`7_*7exS65&YK*&bQ!0F@U!@le*zL2RgE&oIa1~9yIEdV1TjZ|SP8F_ z{b6Atrw~O6%`a#L!->U(`Q1xoo!U%z@(W3TJ&6q7-JF))E`7Kf43GLFf_Sgqx6%ag z4oWgIa}N-O;A}OJFL4#Fv1e$|<5S(w$uo_*r3@6j;7#?Sb&#dmaSJH=QVva&xjFO5 zgjed~e-gTI+=BT0CK2<^u#=HInhpu&ylU0R{J?OV@-w4iM{pmmH(sF#FvHDM+*0;2_5(%s~(nQUt z*Ak>?8YWG=rv>jP4#GUGjo{t_D5^UNLstGXL++qZTU%RJb~f1u?Ek0k{=o|a@)hiM zHMo+jT*-lAkoytDjARnl8jVLjLQlE2O6?^Uc$@}=YqzM;Pm4|+C0oD{L2na?dS*BY zR_jv4rja3|;!#b}LkC!YG$SNWfzy zuCNQ+; zAAj&~-?a`#5HMW^zow`XCaoetxO#YaIID2N_!|X9UImwfTKVKj@QITrgSNuv+YQJ; z{5vZ-Xnr?s38>Hf^iI%R?Lno}MNG*s$5x}yasy#9sJGp@#>ZO0+!u|(cr4)Wsr9XK z_^ZIyvRMQ83(?#>IN6F7xWp4q*$_>G!l9Wl)(Qe5#FMK=2TxfOEY5u{OpHu1@_}Nd zvA@4R0QR$&=-4&@u2ToWs!Zr1F-v^Ra_3&C2?O42ch`r3j53hecVx;p5|aGWIZ?Xf z@J@)hK3cu=nTtZZvB3yw8U_~G88{s_v57%Gjr}(wZM_2~d5}YVbFzZuatsb-<%bg8 zit*~zj7(2EaK-ij@;E|Flf%etF3aE_kkSZJ^9sA24TmsLC z9PS}(scH5DGte23F*)*w68Z=@Tap37W_Vgz%UxdP@0v9`K^kjwSQ<)C_x}-M5d)qF zcV!`f5m!u;s5c6$F!;rb7oX`ofS5P*OhR?pdA1}#N{NhY&eDP%m|4_Gj|CR~>IlND z12-Sv7yvNI5h()tK>SWre+En>0G8zUF0&DEwVlMrFNDoE!9#cVdGcJe^&9KU^6y4d zV4hft^Yg&ybXyi#HMVZ9WOtTF?lv{$wmB$1p5B&4j^!WxtyucmAQ($7pV`iW)t>4= zWRbXj7T_U+6xKB@ATZ5`OK>7l#;Rl?xC876e1xLpoQzJG_J^h9f4^{#3{+O3?C(Fc zy+Wbm$B*AazZr?k1c(w3(U&&|QdiP$RNiCr;6?ElYYp4?1@;KEa4m5(SkOAOQ zSSH^;#^`!RreJxlD54AwwWg7TJJ%g literal 0 HcmV?d00001 diff --git a/images/dialog-bar.png b/images/dialog-bar.png new file mode 100644 index 0000000000000000000000000000000000000000..6b5d231a6d590a486dad84be5c1280c69a3b33c6 GIT binary patch literal 1892 zcmW+%X*gT?9!^cEMwKp@DXKc7qgtWEpvv^I)f!{yu?w{%h=hrVHMmqeQ@0GIwn4Ng ziCvROtesK&SVJrcuA5q-Vrv9N@5%jemj8K|=l%UYyytf(M{8N=6(|G(k+rq4bcR4A z7~uPLX({mT<@Zh%e4L7Owl;^<4XdnyhtnuCxETb}m??AgND@4sjj-{Egh0;!Exu0m zhF1lGAHTs{x#L~Jk@)CGxFATxqYx|}h7H1B(}(H8ez>!JEhHBLkz(0enmvp`Y;f1? zb1;{Cw-0X3a>mQJ9Mo+#632E($5l&vUHdLLD`ns+=CwrDb>aoHR|>odI~fH`PNC4P z7?sG@eHkTM#7IFGl+>CE7%PQ&_s_2wfA5EMVKSLD6&3G8(db$-Sv*`mJ2W&jtT#iI z@M(3-{mO2~i z3YVN4A9toyRYg>{&}hSaK1fYIu#TlRHH{Ap40x|<_vth&FUO3^s@zZH*xB1@Ka_6@ z*5_Xh4xaY+qJeD4Zr%?R%}(rm+st2O4H!<#nDM=P+N7&exiOPul0Ij2R7|?9$#ik` z^h6#U9KaxFSPex*Md&dbR{KG~*{?y^U7CfYgklpB9hlj-{SsL=-8;BlZ?!u1S0LEs zFeD_x6#P)0k0)1HrOKU;UBgakaNF8U@)9T%$|*3hM>UyT5}L&AAhuFzw3#}e)-aKP zdnZ0&8iT=XRId5L;c!^Ds~h_WH$S4KrRCF_a)|Tk`=`JE4uH>11T7$6mLkz~EH^Y> zB%lWLW_UzL(~IvX&BG9F!AdaitqMAw?O1Fa^i)nQLvr4LQeQ7JiZqt}#c7-H_Y+w~ zO&uNj$B$tXo#bT+&@55I(^pQ#$j{W&bc)SJvFm;5%7)nKuCCdd$Bv^ zU|6R7Mie3C8I6fvHm_TL78Df3IPlN1xeU5&!E;%AdxU%OdumF~;ap~rg@uKIiHU!- zfU}K>iJ3M{+FgdPZ*J1Rwa#!42zX7IiYwO9n$_YdDk}C^2o8nowJj}1iughCd<(2g zlqm@y-1@y4C{Huq+#%^iOhZR~BRwea~~jAtJMIdhtIb)iZ&PKK;g#3o1a~NN;)~} zyjc2q>p!XO#LrWb3*gFT7Z*wELZDA*?3;s{EL$|Mo7zVrk<2fb6%@qbI&Sj#P1CQf zGrf%fCsj2yx{hzhG>=zKEI#6=mrU$J`|AHy-X`JkAXD>RocuqvQ;R70U z>G(if@oU*=L#M9d{QTdZ&eb=L8r#Pu`X~GaL~U|gQD@|?>PM+-4#gcmiD(&B2+u|P z^!ce(i!gS-F+P;_)m17nSLtKDBNbe8KWnjI!oU zSR+7jWw0naFi^CZ=jjLZ6ORw6XuU0HO>24f}LbhFzVxU?BIF>B!GcbpSAv=3OrbVi3IwjdSg$N%U+=kUW_eS6r&Afcp_^rc>2j zR9Gl3mHo}!-Cb$$O)3SUR zxcBqzM8ofMIpGT(jEak%>+!3j>W0^EYkUwD0I{wNf@dGx(UDeO{v9atb7kqwaX4W_ zB5{w`f647%@UWkD?VAbItNQ|OD`BboES=_7FuBe-{lNpk`}9o`q$?2ZjrcXN`XOC; zL4z;v4!nRe!D0arR26fKRO(l$dIq|>i=RZIxdJ^DC(Qf#X_qeepZ^8-zF9q9R9vho z!;n>dlOrXucz zwD?bxA3u=aEZmLOMzrncu@lQtIq2qQe|36G%QW}5-NWnRk;Nwd&35Douh}?xg1C38BfVRs9)pfP>p(J*0W=(2&FW>S{xBf#elsWiH%^ zYcugw45wWit0bu?pOdO(GH)n`YcHA$)+XM-F*3~GE2kt40}bzf1Jd$EtXCx4^8f%$ zO->3;c{e`J(MR}vK8N;fX9ouo{17hK+Un{?)A&7iumfdUkc#_qt+qDEUa4(85Qo@W LIa=14`=$I3TmhCL literal 0 HcmV?d00001 diff --git a/images/dialog-bottom.png b/images/dialog-bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..727f8f58fcb8dc79aad3a009dd98417dfe8e5602 GIT binary patch literal 1711 zcmaJ>`#;nBAOFlyxy3o?ft})95Zbh9Au`3c9J$S9lxA|KuVSuKx?!D;uQ^eV8sW61 z+9tQTMW(SX?3gx9q?ryKom^%jmxYb*Xa0cm!~6Yuzb?<$>-~CPp83InM-25W^#A}c z^gHT<1pp`%Tw8C|1?Rvo4{bpKNyi>J1k{OPQ=p=K+B?7-02+$)Rk1ptzAfcwR5}0{ zz0eGZAi44v&}fn28<`QB9G`J6HjN0R#3qn3;3Q&(wF}%Cj@&zMoj?Ns-Cce@-eKqQ zijlR@Fd|Hlx_+ak^tryJgI21^%S793Oi0r)JI??9bf=+++bG?p30C<|`ub@>HwMl; z9ZkL$t!5we9EENvCX!*Vw3O->XT`Jh%bDT@*+e>hArX7w0vC>7^)FfH)*bb4wJdi( z{aZ%JG&5}q$!2JRnx9o!G_NIEf5r`lrlQ=!&!Co%J`#+Nc`s=Oi_R{U(Z9<|7W6)k$uIY{(EPn$$H*z z`&?ZovsM=$ook3E5HM=B8iW9_UO{(X@6{jys+p$UJAn5~u{h9TtU5=uj^r3xp&jk) zaJ99y`1Je^`0rYkEipe(&yA` zO3z~29+cM=)%ix)*Zo7arZ4M^UphjQI1dc8&ssH;6hT&e z?`@=Z?zbubBS5vRka4pXSfr6B74jjDChs;;T0Wg$m8(+mJJtItppIfrI;-Coxktwb3_On5a@x8)nx@?cZ^_wmS_Q3tG@|x9WS| zJxruTXeajLIQT)DBQ9g*3lS`09UBGj$W)Z!wmLbUu&K98NTl&2wyFjpod)Nx5i;Ic zNRmo8{#2zSS-R%_<$cIqdE32~<(-H{LElo76ZB>=JpArgzfy~+tyx=Ym44%C5L?UNu^?tQ_jz{;2 z#1h1_H`8t#Y;g;{pnOVHBg|>=CNG&Jt*P{XvP1NL3Me-<%HzE~x?*_^I z^)5+~{)*N2iO3c#;Z{@HSkow23HatZBTqf|*~{|d=N89Ey$F;6;Yp^_yF!`DtkiuRm5b5N#u|Aavw z-B2LMnhw1ls0%(^JuP;Tw{o{?ARB*9am^700?{G`RnL zNke&Kw3of(h=eMGKVS&xqtEQBHfA{Qa&}+G=BK~2P-75TQCX?--tAwq+Yj3>`4V?V zK3TEpOm>#xf^nlYye?*)u6>Uq^qLhl>>~H(CQm$l_B`Obs`b5`+wIXui$=9t5yUBY#bkw_gKZrBfsKqDEjNjA=$ zeQqW)yD=)}wOQ^}W{d+0C3DnzBg~0XN-offFEfSX``ojpf2VZ*W>!OJ~Ta8tXFR9byCve}mAS#9Q*?q&Zx05ZOJ>n1&M6D zO<&KwH5K*PLGzOMFxsb@NIL5$|KhegUMOYXSL@;XzWyV8=Fh2DcOU|9@?xH(>;(gJ iviR%v_UQ4TkbW<|{Y;!IH$VlN0YBeBpSnW?%Krfn_ZS5L literal 0 HcmV?d00001 diff --git a/images/dialog-bullet.png b/images/dialog-bullet.png new file mode 100644 index 0000000000000000000000000000000000000000..0f431e6a5370679543e0f16926952e67026303bd GIT binary patch literal 580 zcmeAS@N?(olHy`uVBq!ia0vp^N+8U^1|+TAxeoy;#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DjSL74G){)!Z!pk#?_L`iUdT1k0gQ7S`0VrE{6US4X6f{C7i zo{`~4h0LiyQ@41!IEF;Hzn%6xuh~JMS2Y=qXLUR9Pf9>=y4prFy}n`rfQLiN}iKguD=%DeV4EMDAVJQ z63qu04nMpQvp?BHD$#0g(%!h)j77#^qvm96jaqpB{o=cMi*M#Ex|lJg>HD@Q-4ZL= z&pj^=3;Paq$DEenm5R^+AF&7bZ1ta6@4oE+cb z+|x_bzH2DC9{O(^ZhCfu1n<)oZDxD=pYOW6?&gIv+PmEaH79BG_?#=)Sg2U&d?_Td zNx@*Ji*OG&+lsr3J4877-2zj>jCnUI9A3|J`l(P4$1;QYEX-SqUKnosDeLI$IcJ7P zeVawsex4aoq4vyiy&|y+uHqgSS%XR%;mjJ_6}1c!CmT+F@VoUE7|9Htu6{1-oD!M< DnS1vd literal 0 HcmV?d00001 diff --git a/images/dialog-top.png b/images/dialog-top.png new file mode 100644 index 0000000000000000000000000000000000000000..83f52651c91ce3921ef70d942f98d49d2f39b509 GIT binary patch literal 3117 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 q@DyRQ^g&#g^WXlO~WkRL%C%1xE0NT z3ItRv*hLh5eSNhIEw#0^6%>`Uw6rudG*nbnWMpK33g8w=c~u%^Es%A~H&5x;jcAtk zESGS~POO|**wCL+SZ5cKQ(9IT79JjxoE;n-Y+&Kw>+9#}=qRC}$-*PbC2PpcDIh5= z!^|ZBG?Rr#818tbnCT1LSAjg4SQ6wH+`w>o)2*e`w;Ws6)Y{#Zb#wW@qy4(S@9m!Q z@Zp&gYZfi6a##9v=h}$_8&)lz_3zu)kFQ@meE8t@jmsC#pFMeG-@a{Imd{8s{`>pu z$9Heuyn6BY(f#{(Zr{3b>C~ws2X}7Uwsj4&(OV8rpbMUQx;TbZ+^&P*oWfq?<_PfybzI^jH=9)KKeU41_U#88< z{Ud0_lF2_ij&p0z+vMP|^2hoOvm&`$6mI{Kyw)SyF+n8l^oCbr9KN-J*EX#__w?)C z!&(oH2XC*Q`0-Rw1g~{@)zw#_?vF(eO#hg1!~XY{O92t`uG;L|_a^F2?~pn$JtFB= z-Q8K!Lqj4yx`waKvUU&UP?DPcPWJ5SuKM=SYl|}1c>A_gDw<^+CqT`W)opOj`XQz3OxKf4V(yola*NdbNhW=*I zZ4FxX{=dLmd+G0Ar;`&JxL78KxSsW0^wBS3g`4s3fWXeoOdEeE=8y%m!FiH>lYzZT4bb#zQh`_T+yq>Wh*K(cr>_ES??bE>1)focH=}l`{l>l zvO9vBHq4vn?x&Q!=I!h4vTHY0nJ>{55iw)Gx#`;!`9u3cBZ8;jjtzVH>lcGaVeInL zw^E-MUAEDYb-z^nz;n9~{Wjjx3t+AJ74_TJ{d4o!kgR7GEv1e&Ix*>~gTe~DWM4f D`@*Fu literal 0 HcmV?d00001 diff --git a/images/keyboard-back.png b/images/keyboard-back.png new file mode 100644 index 0000000000000000000000000000000000000000..482694274e133bad44d9848028d749ff50147227 GIT binary patch literal 25928 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 Q`^jHY67sK0U+Me(Kiqa&hX4Qo literal 0 HcmV?d00001 diff --git a/images/keyboard-backspace.png b/images/keyboard-backspace.png new file mode 100644 index 0000000000000000000000000000000000000000..c62a1cdc594c83df42e5182b9a348b348c6ac75f GIT binary patch literal 3258 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 literal 0 HcmV?d00001 diff --git a/images/keyboard-bullet-sel-on.png b/images/keyboard-bullet-sel-on.png new file mode 100644 index 0000000000000000000000000000000000000000..c5f8b21db4dc53c61575fe338458aa379f4cc5bc GIT binary patch literal 2287 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D2!u&QK~z{reOJkD z9M=^+HFQ_?z-|sEsgR}&!7wa4ijV}c1!*H^;RMJcT4x(TOX(Zr{|S(92!bHUDlsf* zh)G2gr*00-9&3I%=Qb%ww%{i{)zGi*aPGN-y!-d>L#xOOOlMP!$74(;x{i?NxxKHd z3YDvL%mIO&e|Pb?mFvyB_b%T#X9`ACc6N4#)6-LoMnj}&in1&z%5z>2xFD!G z->>m8eDC(Xn(e@^yO3wYAau1_4L`Mgd3E9ObUH#L;u@ z%K7J8{_!0ZYkRf>c>Lb?Lq{2s^WN=C;b=56#c7&BNcg_T9k{9rP&x{x5?6Vs2t-ll z$cyx?&F4JhHREq33OZ9bj|PP_IxqtQq7VcDez^VFY-UPxi*3n|d{;Tom8FN0VOFSx zgnlc}6=gi1CMjk_EKL%mSz_-C8c@=>iXZBmQijlAM`IYj9}&R2bLWmht{C$JSK2|J zf+{Me017J0f(jFIBSVsr3zV2si7fLxLunqzFhVU-JbC5wg@>U}iQII9+Z5RHzW(}m zgnVM2%SL$hc}z6MXQ)RJu6%Y4YoGoKoz-=OjV9tz z4@vJ8wx2!2i=FQ=8V=3tcDsY9(Lx-ziHJ~87@4}+l=2HIrvuloUnj$J7u91#af=?+ z=yAa?B#h|<9u^bfyP5+~1?8&R`Ei#@)PU zsuI;X$OC_k8IZmTvzED{JfKVVcg!8)g9I3Tly(46uyxRa9hENDGOIrH4LJ8YzcA z`Q?|$uH3{SnyC0Z=9w|M8MF4(h|>jieUk4aE731QJnjAhTVMQ^XvUaKMtJOqz;|dPLB^;!{ejXrU7Py*+l&Lc#g>@xp2puaU z2|CIv?4}{kHom~(;xe;=vXuL-pmHX?(vHV%r7)%9LR+dpGvG$4p zql}?YuGaYvt!z{oB9g66p)5;Cncw=IK|@jt@Updm*4mcx>n+%s$%Lv_uk)PBnNnMI zn5i(wP}NCRR)npIk|9xIz_a{(v!<*E34vE3ZPM$4cM3wlI~HN0!jjzXS`C-txpIn8 z&a2|k0r|oLz?{?Oy^OioLL>7dl>ER7iw=laWo) zyuXlXaPxrf{erO-$@E?|c;1oJCg}rz%k$EzlNWky6}(rm=V9G9!A3-3DLYxoYgteM z(<$%rNi2~UT&pYN<2YPtOCJVE9pk1~jm{yN}+JZ*ghHa!FW4tW|op zRt~XPOh)+&GX9xTmkJnXLN8DU%JTeya!+kg z7Fu-mmk{aT$x$E6vpyQ^RB613VXe(ns*~k4`&Qp_nu+6^AOLUZCm4LQE|J~L35#Fo(DuUnI-t&^Y0msQ_qp{ z-sa{edc7Vksoe7N3bxplWT^fcsjFbM}tKihgN(V4WTqoM-g_)aeGE%IkTbB zY_p#)SiI{|Y++Q44-fWmaPV4O5=Y@(y?PZdU%sTZiM(?^+uUMVT{D<8i)o-x2TCY7 z)7+MfOrd5pEh`p`r`Q~mq*2^7;}vVk2o3HENBth#>@HCpnPM&P_U+r)-rmOH;h}jO zH(G9GWff~|iAoXmWYv3hCFN(9%}lu!CT<}g&|7gu%8Xnz(?A&@Lpcu^#5(uG7{9xK{{ukkUiL=^g8%>k002ov JPDHLkV1m5sOz!{y literal 0 HcmV?d00001 diff --git a/images/keyboard-caps.png b/images/keyboard-caps.png new file mode 100644 index 0000000000000000000000000000000000000000..94998001aec956b9568c811e1d08706ca73b4385 GIT binary patch literal 2887 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 Vo_`*8uC)LF002ovPDHLkV1h5R0fhhn literal 0 HcmV?d00001 diff --git a/images/keyboard-clear.png b/images/keyboard-clear.png new file mode 100644 index 0000000000000000000000000000000000000000..f80bc21fad5228e0e8def9815251cc7e229bfd9c GIT binary patch literal 2655 zcmV-l3ZV6gP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D3G_)sK~!i%?VEdW z73CSmpWSnECkcUY2^g>>Lap3HovDniO4S66QV;^IV9`PgRXcXZ4jo$y{LzlKooc5} zsT8HwLGaQ}DOBpzDhjAG?Gy?Kg;Gn3LCE#wdUCGY_jz~sa1u`7q|HgrG(O>FFWyg-pi1ffvK z3IqaHFxVv#w4%|lLKfUZDl99aJQ!VFT@I6=C47`eBCu3K=kg%=Ad4Ty1HE1^JRXlz zI!R1wu1NDlqk{qN^-2*?Cog&DBtjLL=$w(j@p8jf%y5t`A1%*;$9{tj2Tti=3Eu&!gdwDarv2U|L+sdy%u z3a4Pw2d}`CTXdl0I+t=EY|is3mLj;M6fO&yqzTh4U?LBPZMgh^bke!8v+z{y>1>B=W6~n7A{<9b#!#Zk~86^qZ&(Z!u!`f zs;Qu?>o_L8@i0Q2t@yBPAx_SGPyvsweH)*AZ-bWX!0VQy7nOjTzq;D%J+R2#vqtP+^Wy4 z?Cea5T*IiUsqC7{KJlyqlYwi@dxXi98sUm6cXoTN~Qj+ts=0 zqK+#nPz<28g1)O(c zH-_)HABJ>OQz;kj$dMyaR8$0`qN2h&ckUc~KHs3j4SlK#O`qRrgKaqk?{i;3S8J0~ z+IRV9El11T#}shx@mG=mn>7MB=#=)q*xn`F(W6HzV1-*-TZ<-N6S_JF4{mtsooKsj zlcs`kzQ4iPya@jP0j#UQb@!s<_8-tz$UU|b+1pk)CH*ftH$OigB_$;&E-tnQ%h~*j zNSBw(!3a7w9;~%#Av$~w3G4PXya%?y+wgZi`OuV#gmwBWI7Sne+|K6~L!DbwQ-g+v z25pWFw5;h1;9t5$zAd=R0Z-PtdWRb}KNaNo-aPr4CCIDqV}%V8dU)hX=rs~aT-Gxvc7fSa;DgO{^8>{S?sh5zGZrAU>{kkQY|{aFADaQ=-DmVW zgl>BjR;5IO*QOo3|TU`?XLG0S-G%Q?LhR3IqF#Bm({S2 z{XTKsBqJ2!6gt28rNyQgN5ov`c1sK46px6R1bfd5nq$W{{uS*{R-)6_C}$yGj92`9 z0bDpv0b6A^!jzN4@jY7Z%yRc0-aKH{Z*8!WV~s6KfWx~I*X=`iJanV1Cm|Q^h!Gh7^?~Pb7D1d?6cz7BRk`3 zT=*kyOy-Ahqe)K8B!t`8*a(h{agr?+@(9?-mtK$+7i>j0ur%oT5W5`P4WqzuaQRK} zdgS7q+#_FJmOVpKf%(&39T~AsB{GtHfw@Ei+fEBE?3MR+p*uy)u&R~iRnF>4}`z1Yv>ox6n!BPP@vhfb& z{d=!aHW6O(G`u&gbV`yG$6;Um8nAbxy(xf=?;NqgN{%(2S(FxFDe|*9+AK}Z`!ET! zXOR-P{x)>}v?X(Hyvi`mB2sU8kJwzRb908Xl8 zIPMot2pB49VKCS*-z0Rkl60j+NbLV{vp{zn@PwHjX z9)$lbyJM29n09;Xp}BdMGrfd5e*AdtnF(x3>Qe5${7jI1A&(Q4XU?91ugRxfVvaWu zaH=4urG%)dBR95s!qt|5)S+VubIh1AI%h`r>I-;MPI;zIovJI`A+erU!ZhqxBHi)b zcscd{zr#M$Sh!;ZTr%8N0f!bjj=&u2Gzc^uxQaQKB1i)D`~4Q@)97O6Uyhgs8h_RNeio}ut=fuEgRY24J_3St}CVj3I0hCQ-uvz*4c`1=ZJ=ycqh}b z48nDTZgo2iJ(UoyD?%2KmIGUdBnft?!FAIGA=;fT{>_M|SE#mt{{W@I(&L&o=PLjJ N002ovPDHLkV1o465{>`> literal 0 HcmV?d00001 diff --git a/images/keyboard-cursor.png b/images/keyboard-cursor.png new file mode 100644 index 0000000000000000000000000000000000000000..c880a1b71c36a09fbe0e6437823cfc5268c9e8f5 GIT binary patch literal 132 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 literal 0 HcmV?d00001 diff --git a/images/keyboard-shift.png b/images/keyboard-shift.png new file mode 100644 index 0000000000000000000000000000000000000000..35866f06c22ef5f89e16776e2591355872e63bc4 GIT binary patch literal 1990 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 RQ5^sP002ovPDHLkV1gP@jurp_ literal 0 HcmV?d00001 diff --git a/images/paragraph-bar.png b/images/paragraph-bar.png new file mode 100644 index 0000000000000000000000000000000000000000..347cc5e9509805a6b8d66f743881b4d53d1baffc GIT binary patch literal 1818 zcmX9KS*S4`Q%UYae%eMZ=U|F0F^M^@lgs2%S|c3z0AL3Je8(aY;63$mD;Ipgm?u0)fZ&DUNALiTBKi;kpy}$)^)O}d{9U5wDJB5y z>Vhst{x8_?fFr;CO4?%c>#&Iab7W)&zUNk zYB~9w*UkHUoW9lY#5L&mxm2aGkjsWlwq8u94hNhI(JSO~haV?QTKN0>%QK>* z>jEe`iu|~x^IoO^JMMdE{ec;t?X$!-2 zI-SuwFmQZ4B0b%~J|b|imYlP(_N>NH3c!cHW`JSxPsZEaS= zBO~+!G`k~5E*tue+Q-8qV+4(EaBIsQ|Pb{&a>ATOzU-aV%L<*M+Tq-%bz6d z(1v{wUBjK@4}Mgsmil}THY5fWQOLOXIx1 zzOJlbfu?$0UENrg_5z@pAS(kO!Ssj?$)$~7`f7BXxjM3vp$%|iMp z6bdV43rU>=GkfP+(sqh2Nwp@|vh%uSb4!cP&VMn^p6y;+LW~R=mQYr2FRYKZGWpKw zG9xZC6mb(Fj^_r5`};k1xFy&6#`4NQg})Fjdkc$6idUbO!w=|pT=|;REN)dJXh5;`P3SIb z{jCotUO=U+YWPzdSzkUJr*#E5BHlMIivTy~vjhhnc3rU=0pc!kdlCpv3g#%wd~9qi z31qPXOwU?d^CKF)4u?J|oN~1(i$_IQSp!Y|zaRN^kV3xWQlBujNbKNC87f<7%gCTUg#G+eBUr)^#!=13q>RE%A<}xr zoOafRQ>RK8$3D;R6&0wJXUJ!c!Hsw&Fiw;v+u_9#f-OOlEtN`Rvo&BGgxNt8C{JJ8 zcvgH1zadpwKf85bNf%RmyEvJKTyFislV)64#wN)jqVu`+ib zDC^+Yn?}dP>{mi%;rOGP&41uw`ET1VX+zO}aPBq6Ujh~FYsp6~f}J-Dk}z0WMg21~ z;qX24H~lBl-319xucsA*gQIFF)-dKAZY+oVvwzv$ere0)QI3|RB2%wUefCCFKX2LK zP9!jc?kKp(mG?!nt#gwaPx(LsUKy=6@H8+k&sYeIq|%<*)7R&ngPE@aRhJ~8PpzOh zc{o$k&1q7pW^Z>=);6JgBcGnz^Pg(^CZ7*7Fva06&2Lm_dAv4`uv&dfkva1)>Zobl zL9<;yfcPg2kbC3e;xyfa`f%;Vo;&brq-9ZiX^nKc>q^tFFfkcB={G;iM20wD_(0xk z4pF*6G&7d5KbQCqplxmSM5b3tvhprizK%krqBG3xy0jed<8!HWRYScWA^cm&Lpjxq zs7m8pcIVoXdt`ZN?k&UCTDy^E<&njWK1V~o^3OmSetWd-HJt)wY+y*uQpoO-PZouW zrn=4y>`?N{+w({W#(rK3p1JCG{}+@+lT6H8%t6w++uluPD3Iji^9w&Gyq-qB%OS8wK)GmUBg0ChW1Qb}B$-c9S7 zqRqdzSy~$a#A0z(EV~ka9Wsn)d928iH1T?J@-Vn02VNwq>DdwBH^#NjL?&6Iv>cqGG7p12#}zv-5vLLjiE3Y>ji;`ys4Sfl{S$B}U&!QpW;nv68W| zf*iIDL-4#u~W{BI{GNvIX^TM=pjz5eptT>M`=3=D}A)k)t~gRraHwr{2V_jCie gt~LXe1Z9hRFfP?w7iGd-;QtKpI_B#pAf3tn2YN6-qW}N^ literal 0 HcmV?d00001 diff --git a/images/paragraph-bullet.png b/images/paragraph-bullet.png new file mode 100644 index 0000000000000000000000000000000000000000..0fff2d33f1ee566ac1895048aa5ffa7b272a974e GIT binary patch literal 438 zcmV;n0ZIOeP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0ZU0lK~z{r?Urk6 zgD@0^k6OH6TJ-<_Lj52W@t*k}bZnU>8(X(B@<2$XX?&t5Z)yo4=ozrL{?9QYGDbwk zh{!yR$fpA>j$^Sb%XW3lJkMlV7TLB1W>Fj(8yO0*)r?~7G}f*|0g0us9b+BlBX zwk@~5@0CJIku1wZnx>Q_352+*a2$sP@Z>NrdPvlDP51j9{i%$yM#3_5iuRCkL6Y<(ZZ;k5LLl2R!0!51Xe*DmTOB6-xQ1w{c95N628}M70?JHwM gWQ>T65qS^M3xJKxxtZVV6951J07*qoM6N<$f{Jvx3;+NC literal 0 HcmV?d00001 diff --git a/source/gameMain.brs b/source/gameMain.brs index 841c4ba..3ce9d29 100644 --- a/source/gameMain.brs +++ b/source/gameMain.brs @@ -31,24 +31,28 @@ Sub Main() m.files = CreateObject("roFileSystem") m.fonts = {reg:CreateObject("roFontRegistry")} m.fonts.reg.Register("pkg:/assets/fonts/PoP.ttf") + m.fonts.reg.Register("pkg:/assets/fonts/Gotham-Medium.otf") + m.fonts.KeysFont = m.fonts.reg.getFont("Gotham Medium", 30, false, false) m.bitmapFont = LoadBitmapFont() m.prandom = CreatePseudoRandom() m.manifest = GetManifestArray() m.status = [] 'Check Roku model for performance alert if not IsOpenGL() - m.mainScreen = CreateObject("roScreen") - m.mainScreen.SetMessagePort(m.port) - MessageDialog("Prince of Persia", "Warning: Your Roku device doesn't support accelerated graphics, this game will not perform well.") + m.mainScreen = CreateObject("roScreen", true, 1280, 720) + canvas = CreateCanvas() + MessageDialog(m.port, "Prince of Persia", "Warning: Your Roku device doesn't support accelerated" + chr(10) + "graphics, this game will not perform well.") else if IsRokuStick() - m.mainScreen = CreateObject("roScreen") - m.mainScreen.SetMessagePort(m.port) - MessageDialog("Prince of Persia", "Warning: Your Roku Stick device has limited memory, this game only works properly on the 4 rooms mode.") + m.mainScreen = CreateObject("roScreen", true, 1280, 720) + canvas = CreateCanvas() + MessageDialog(m.port, "Prince of Persia", "Warning: Your Roku Stick device has limited memory," + chr(10) + "this game only works properly on the 4 rooms mode.") end if 'Initialize Screen if isHD() + print "HD Mode" m.mainScreen = CreateObject("roScreen", true, 854, 480) else + print "SD Mode" m.mainScreen = CreateObject("roScreen", true, 640, 480) end if m.mainScreen.SetMessagePort(m.port) diff --git a/source/gameMenu.brs b/source/gameMenu.brs index f099ff9..c58cfd5 100644 --- a/source/gameMenu.brs +++ b/source/gameMenu.brs @@ -12,28 +12,27 @@ ' ******************************************************************************************************** ' ******************************************************************************************************** -Function StartMenu() as integer - screen = m.mainScreen - screen.Clear(0) - scale = Int(GetScale(screen, 640, 432)) - centerX = Cint((screen.GetWidth()-(640*scale))/2) - centerY = Cint((screen.GetHeight()-(432*scale))/2) +function StartMenu() as integer + m.mainScreen.Clear(0) + scale = Int(GetScale(m.mainScreen, 640, 432)) + centerX = Cint((m.mainScreen.GetWidth() - (640 * scale)) / 2) + centerY = Cint((m.mainScreen.GetHeight() - (432 * scale)) / 2) backImage = ScaleBitmap(CreateObject("roBitmap", "pkg:/images/start_menu.jpg"), scale) - CrossFade(screen, centerX, centerY, GetPaintedBitmap(m.colors.black, 640 * scale, 432 * scale, true), backImage, 4) + CrossFade(m.mainScreen, centerX, centerY, GetPaintedBitmap(m.colors.black, 640 * scale, 432 * scale, true), backImage, 4) menuFont = m.fonts.reg.getFont("Prince of Persia Game Font", 26, false, false) button = -1 selected = 0 while true if button <> selected - screen.Clear(0) - screen.DrawObject(centerX, centerY, backImage) - faceColors = [ m.colors.white, m.colors.white, m.colors.white, m.colors.white ] + m.mainScreen.Clear(0) + m.mainScreen.DrawObject(centerX, centerY, backImage) + faceColors = [m.colors.white, m.colors.white, m.colors.white, m.colors.white] faceColors[selected] = &hFF0000FF - screen.DrawText("Play Classic Mode", centerX + 225, centerY + 162, faceColors[0], menuFont) - screen.DrawText("Play 4 Rooms Mode", centerX + 215, centerY + 215, faceColors[1], menuFont) - screen.DrawText("Play 9 Rooms Mode", centerX + 215, centerY + 267, faceColors[2], menuFont) - screen.DrawText("Game Settings", centerX + 240, centerY + 319, faceColors[3], menuFont) - screen.SwapBuffers() + m.mainScreen.DrawText("Play Classic Mode", centerX + 225, centerY + 162, faceColors[0], menuFont) + m.mainScreen.DrawText("Play 4 Rooms Mode", centerX + 215, centerY + 215, faceColors[1], menuFont) + m.mainScreen.DrawText("Play 9 Rooms Mode", centerX + 215, centerY + 267, faceColors[2], menuFont) + m.mainScreen.DrawText("Game Settings", centerX + 240, centerY + 319, faceColors[3], menuFont) + m.mainScreen.SwapBuffers() button = selected end if key = wait(0, m.port) @@ -60,36 +59,36 @@ Function StartMenu() as integer if button < 3 return button + 1 else - SettingsMenu(screen) + SettingsMenu() button = -1 end if end if end if end while -End Function +end function -Sub SettingsMenu(screen as object) - scale = Int(GetScale(screen, 640, 432)) - centerX = Cint((screen.GetWidth()-(640*scale))/2) - centerY = Cint((screen.GetHeight()-(432*scale))/2) +sub SettingsMenu() + scale = Int(GetScale(m.mainScreen, 640, 432)) + centerX = Cint((m.mainScreen.GetWidth() - (640 * scale)) / 2) + centerY = Cint((m.mainScreen.GetHeight() - (432 * scale)) / 2) menuFont = m.fonts.reg.getFont("Prince of Persia Game Font", 30, false, false) colorWhite = &hFFFFFFFF colorRed = &hFF0000FF button = -1 selected = m.settings.controlMode - backImage = ScaleBitmap(CreateObject("roBitmap", "pkg:/images/settings_menu.jpg"),scale) + backImage = ScaleBitmap(CreateObject("roBitmap", "pkg:/images/settings_menu.jpg"), scale) while true if button <> selected - screen.Clear(0) - screen.DrawObject(centerX, centerY, backImage) - faceColors = [ m.colors.white, m.colors.white, m.colors.white, m.colors.white, m.colors.white ] + m.mainScreen.Clear(0) + m.mainScreen.DrawObject(centerX, centerY, backImage) + faceColors = [m.colors.white, m.colors.white, m.colors.white, m.colors.white, m.colors.white] faceColors[selected] = &hFF0000FF - screen.DrawText("Control Mode", centerX + 93, centerY + 108, faceColors[0], menuFont) - screen.DrawText("Graphics Mode", centerX + 93, centerY + 161, faceColors[1], menuFont) - screen.DrawText("Mods & Cheats", centerX + 93, centerY + 213, faceColors[2], menuFont) - screen.DrawText("High Scores", centerX + 93, centerY + 265, faceColors[3], menuFont) - screen.DrawText("Game Credits", centerX + 93, centerY + 318, faceColors[4], menuFont) - screen.SwapBuffers() + m.mainScreen.DrawText("Control Mode", centerX + 93, centerY + 108, faceColors[0], menuFont) + m.mainScreen.DrawText("Graphics Mode", centerX + 93, centerY + 161, faceColors[1], menuFont) + m.mainScreen.DrawText("Mods & Cheats", centerX + 93, centerY + 213, faceColors[2], menuFont) + m.mainScreen.DrawText("High Scores", centerX + 93, centerY + 265, faceColors[3], menuFont) + m.mainScreen.DrawText("Game Credits", centerX + 93, centerY + 318, faceColors[4], menuFont) + m.mainScreen.SwapBuffers() button = selected end if key = wait(0, m.port) @@ -117,13 +116,13 @@ Sub SettingsMenu(screen as object) else if key = m.code.BUTTON_SELECT_PRESSED m.sounds.select.Trigger(50) if selected = 0 - option = OptionsMenu(screen, [{text: "Vertical Control", image:"control_vertical"},{text:"Horizontal Control", image:"control_horizontal"}], m.settings.controlMode) + option = OptionsMenu([{ text: "Vertical Control", image: "control_vertical" }, { text: "Horizontal Control", image: "control_horizontal" }], m.settings.controlMode) if option >= 0 and option <> m.settings.controlMode m.settings.controlMode = option SaveSettings(m.settings) end if else if selected = 1 - option = OptionsMenu(screen, [{text: "IBM-PC MS-DOS", image:"graphics_dos"},{text:"Macintosh Classic", image:"graphics_mac"}], m.settings.spriteMode) + option = OptionsMenu([{ text: "IBM-PC MS-DOS", image: "graphics_dos" }, { text: "Macintosh Classic", image: "graphics_mac" }], m.settings.spriteMode) if option >= 0 and option <> m.settings.spriteMode m.settings.spriteMode = option m.settings.modId = invalid @@ -131,41 +130,47 @@ Sub SettingsMenu(screen as object) end if else if selected = 2 ModsAndCheatsScreen() - m.mainScreen.SwapBuffers() + if isHD() + m.mainScreen = CreateObject("roScreen", true, 854, 480) + else + m.mainScreen = CreateObject("roScreen", true, 640, 480) + end if + m.mainScreen.SetMessagePort(m.port) + m.mainScreen.SetAlphaEnable(true) else if selected = 3 - HighscoresScreen(screen) + HighscoresScreen() else if selected = 4 - CreditsScreen(screen) + CreditsScreen() end if button = -1 end if end if end while -End Sub +end sub -Function OptionsMenu(screen as object, options as object, default as integer) as integer - scale = Int(GetScale(screen, 640, 432)) - centerX = Cint((screen.GetWidth()-(640*scale))/2) - centerY = Cint((screen.GetHeight()-(432*scale))/2) +function OptionsMenu(options as object, default as integer) as integer + scale = Int(GetScale(m.mainScreen, 640, 432)) + centerX = Cint((m.mainScreen.GetWidth() - (640 * scale)) / 2) + centerY = Cint((m.mainScreen.GetHeight() - (432 * scale)) / 2) menuFont = m.fonts.reg.getFont("Prince of Persia Game Font", 26, false, false) colorWhite = &hFFFFFFFF colorRed = &hFF0000FF button = -1 if default <= 1 then selected = default else selected = 0 - backImage = ScaleBitmap(CreateObject("roBitmap", "pkg:/images/options_menu.jpg"),scale) + backImage = ScaleBitmap(CreateObject("roBitmap", "pkg:/images/options_menu.jpg"), scale) while true if button <> selected - screen.Clear(0) - screen.DrawObject(centerX, centerY, backImage) + m.mainScreen.Clear(0) + m.mainScreen.DrawObject(centerX, centerY, backImage) if selected = 0 - screen.DrawText(options[0].text, centerX + 88, centerY + 57, colorRed, menuFont) - screen.DrawText(options[1].text, centerX + 80, centerY + 109, colorWhite, menuFont) + m.mainScreen.DrawText(options[0].text, centerX + 88, centerY + 57, colorRed, menuFont) + m.mainScreen.DrawText(options[1].text, centerX + 80, centerY + 109, colorWhite, menuFont) else - screen.DrawText(options[0].text, centerX + 88, centerY + 57, colorWhite, menuFont) - screen.DrawText(options[1].text, centerX + 80, centerY + 109, colorRed, menuFont) + m.mainScreen.DrawText(options[0].text, centerX + 88, centerY + 57, colorWhite, menuFont) + m.mainScreen.DrawText(options[1].text, centerX + 80, centerY + 109, colorRed, menuFont) end if - screen.DrawObject(centerX, centerY, ScaleBitmap(CreateObject("roBitmap", "pkg:/images/" + options[selected].image + ".png"),scale)) - screen.SwapBuffers() + m.mainScreen.DrawObject(centerX, centerY, ScaleBitmap(CreateObject("roBitmap", "pkg:/images/" + options[selected].image + ".png"), scale)) + m.mainScreen.SwapBuffers() button = selected end if key = wait(0, m.port) @@ -191,59 +196,59 @@ Function OptionsMenu(screen as object, options as object, default as integer) as end if end while return selected -End Function +end function -Sub HighScoresScreen(screen as object) - scale = Int(GetScale(screen, 640, 432)) - centerX = Cint((screen.GetWidth()-(640*scale))/2) - centerY = Cint((screen.GetHeight()-(432*scale))/2) +sub HighScoresScreen() + scale = Int(GetScale(m.mainScreen, 640, 432)) + centerX = Cint((m.mainScreen.GetWidth() - (640 * scale)) / 2) + centerY = Cint((m.mainScreen.GetHeight() - (432 * scale)) / 2) backImage = ScaleBitmap(CreateObject("roBitmap", "pkg:/images/highscores_back.jpg"), scale) - while true - screen.Clear(0) - screen.DrawObject(centerX, centerY, backImage) - xn = centerX + 72 * 2 - xt = centerX + 217 * 2 - ys = centerY + 85 * 2 - c = 0 - for each score in m.highScores - m.bitmapFont.write(screen, score.name, xn, ys, 2.0) - m.bitmapFont.write(screen, FormatTime(score.time), xt, ys, 2.0) - ys += (12 * 2) - c++ - if c = 7 then exit for - next + while true + m.mainScreen.Clear(0) + m.mainScreen.DrawObject(centerX, centerY, backImage) + xn = centerX + 72 * 2 + xt = centerX + 217 * 2 + ys = centerY + 85 * 2 + c = 0 + for each score in m.highScores + m.bitmapFont.write(m.mainScreen, score.name, xn, ys, 2.0) + m.bitmapFont.write(m.mainScreen, FormatTime(score.time), xt, ys, 2.0) + ys += (12 * 2) + c++ + if c = 7 then exit for + next if m.highScores.Count() > 0 - m.bitmapFont.write(screen, "[ Press * to reset the High Scores ]", xn - 52, 370, 2.0) + m.bitmapFont.write(m.mainScreen, "[ Press * to reset the High Scores ]", xn - 52, 370, 2.0) else - m.bitmapFont.write(screen, "< No High Scores are recorded yet >", xn - 52, ys + 8, 2.0) + m.bitmapFont.write(m.mainScreen, "< No High Scores are recorded yet >", xn - 52, ys + 8, 2.0) end if - screen.SwapBuffers() - key = wait(0, m.port) - if key <> invalid + m.mainScreen.SwapBuffers() + key = wait(0, m.port) + if key <> invalid if type(key) = "roUniversalControlEvent" key = key.getInt() end if - if key = m.code.BUTTON_INFO_PRESSED and m.highScores.Count() > 0 - m.sounds.select.Trigger(50) - saveOpt = MessageBox(screen, 230, 100, "Reset Scores?", 2) + if key = m.code.BUTTON_INFO_PRESSED and m.highScores.Count() > 0 + m.sounds.select.Trigger(50) + saveOpt = MessageBox(m.mainScreen, 230, 100, "Reset Scores?", 2) if saveOpt = m.const.BUTTON_YES m.highScores = [] SaveHighScores(m.highScores) end if - else if key < 100 - m.sounds.navSingle.Trigger(50) - exit while - end if - end if - end while -End Sub + else if key < 100 + m.sounds.navSingle.Trigger(50) + exit while + end if + end if + end while +end sub -Sub CreditsScreen(screen as object) - scale = Int(GetScale(screen, 640, 432)) - centerX = Cint((screen.GetWidth()-(640*scale))/2) - centerY = Cint((screen.GetHeight()-(432*scale))/2) - screen.Clear(0) - screen.DrawObject(centerX, centerY, ScaleBitmap(CreateObject("roBitmap", "pkg:/images/game_credits.jpg"), scale)) +sub CreditsScreen() + scale = Int(GetScale(m.mainScreen, 640, 432)) + centerX = Cint((m.mainScreen.GetWidth() - (640 * scale)) / 2) + centerY = Cint((m.mainScreen.GetHeight() - (432 * scale)) / 2) + m.mainScreen.Clear(0) + m.mainScreen.DrawObject(centerX, centerY, ScaleBitmap(CreateObject("roBitmap", "pkg:/images/game_credits.jpg"), scale)) m.mainScreen.SwapBuffers() while true key = wait(0, m.port) @@ -252,11 +257,11 @@ Sub CreditsScreen(screen as object) end if if key <> invalid and key < 100 then exit while end while -End Sub +end sub -Function MessageBox(screen as object, width as integer, height as integer, text as string, options = 3 as integer) as integer - leftX = Cint((screen.GetWidth()-width)/2) - topY = Cint((screen.GetHeight()-height)/2) +function MessageBox(screen as object, width as integer, height as integer, text as string, options = 3 as integer) as integer + leftX = Cint((screen.GetWidth() - width) / 2) + topY = Cint((screen.GetHeight() - height) / 2) xt = leftX + int(width / 2) - ((Len(text) + 1) * 14) / 2 xb = leftX + int(width / 2) - (13 * 14) / 2 yt = topY + height / 2 - 25 @@ -268,8 +273,8 @@ Function MessageBox(screen as object, width as integer, height as integer, text screen.DrawRect(leftX, topY, width, height, m.colors.black) m.bitmapFont.write(screen, text, xt, yt, 2.0) DrawBorder(screen, width, height, m.colors.white, 0) - boff = [0,60,100] - line = [42,28,84] + boff = [0, 60, 100] + line = [42, 28, 84] m.bitmapFont.write(screen, "Yes", xb + boff[0], yt + 30, 2.0) m.bitmapFont.write(screen, "No", xb + boff[1], yt + 30, 2.0) if options = 3 @@ -307,11 +312,11 @@ Function MessageBox(screen as object, width as integer, height as integer, text end if end if end while -End Function +end function -Sub TextBox(screen as object, width as integer, height as integer, text as string, border = false as boolean) - leftX = Cint((screen.GetWidth()-width)/2) - topY = Cint((screen.GetHeight()-height)/2) +sub TextBox(screen as object, width as integer, height as integer, text as string, border = false as boolean) + leftX = Cint((screen.GetWidth() - width) / 2) + topY = Cint((screen.GetHeight() - height) / 2) xt = leftX + int(width / 2) - (Len(text) * 13) / 2 yt = topY + height / 2 - 15 m.mainScreen.SwapBuffers() @@ -319,4 +324,4 @@ Sub TextBox(screen as object, width as integer, height as integer, text as strin m.bitmapFont.write(screen, text, xt, yt, 2.0) if border then DrawBorder(screen, width, height, m.colors.white, 0) m.mainScreen.SwapBuffers() -End Sub +end sub diff --git a/source/gameMods.brs b/source/gameMods.brs index cdfb86a..f2e501a 100644 --- a/source/gameMods.brs +++ b/source/gameMods.brs @@ -119,12 +119,14 @@ Function GetModImage(modId as dynamic) as string End Function Sub ModsAndCheatsScreen() + m.mainScreen = CreateObject("roScreen", true, 1280, 720) + m.mainScreen.SetMessagePort(m.port) this = { screen: CreateListScreen() port: m.port } this.screen.SetMessagePort(this.port) - this.screen.SetHeader("Mods and Cheats") + this.screen.SetHeader("Mods an d Cheats") this.modArray = [{name: "(none)", author:"", levels: false, sprites: false, sounds: false}] this.modIndex = 0 for each modId in m.mods.Keys() @@ -300,7 +302,6 @@ Sub ModsAndCheatsScreen() end if end if end while - return End Sub Function GetMenuItems(menu as object) diff --git a/source/gameSound.brs b/source/gameSound.brs index 966a942..b14640a 100644 --- a/source/gameSound.brs +++ b/source/gameSound.brs @@ -18,6 +18,7 @@ Function LoadSounds(enable as boolean) as object wav: {clip:"", priority:0, cycles:0}, metadata : ParseJson(ReadAsciiFile("pkg:/assets/sounds/sounds.json")), navSingle : CreateObject("roAudioResource", "navsingle"), + roll : CreateObject("roAudioResource", "navmulti"), deadend : CreateObject("roAudioResource", "deadend"), select : CreateObject("roAudioResource", "select") } diff --git a/source/gameUtil.brs b/source/gameUtil.brs index 304955a..6c7eeb7 100644 --- a/source/gameUtil.brs +++ b/source/gameUtil.brs @@ -371,12 +371,12 @@ End Function Function IsHD() di = CreateObject("roDeviceInfo") - return (di.GetUIResolution().name <> "sd") + return (di.GetUIResolution().height >= 720) End Function Function IsfHD() di = CreateObject("roDeviceInfo") - return(di.GetUIResolution() = "fhd") + return(di.GetUIResolution().name.lcase() = "fhd") End Function Function ConvertX(x) @@ -488,16 +488,16 @@ Function FormatTime(seconds as integer) as string end if ' Hours if seconds >= 3600 - textTime = textTime + (seconds / 3600).toStr() + ":" + textTime = textTime + int(seconds / 3600).toStr() + ":" hasHours = true seconds = seconds Mod 3600 end if ' Minutes if seconds >= 60 if hasHours - textTime = textTime + ZeroPad((seconds / 60).toStr()) + ":" + textTime = textTime + ZeroPad(int(seconds / 60).toStr()) + ":" else - textTime = textTime + (seconds / 60).toStr() + ":" + textTime = textTime + int(seconds / 60).toStr() + ":" end if seconds = seconds Mod 60 else @@ -592,31 +592,44 @@ Function seq_prandom(seed as integer, n as integer, p as integer, max as integer return r1 End Function -'------- Roku Screens Functions ---- -Sub MessageDialog(title, text, port = invalid) As Integer - if port = invalid then port = CreateObject("roMessagePort") - d = CreateObject("roMessageDialog") - d.SetTitle(title) - d.SetText(text) - d.SetMessagePort(port) - d.AddButton(1, "Okay") - d.Show() +Function MessageDialog(port, title, text, buttons = ["OK"], default = 0, overlay = false) As Integer + if port = invalid + if m.port = invalid + port = CreateObject("roMessagePort") + else + port = m.port + end if + end if + s = CreateMessageDialog() + s.SetTitle(title) + s.SetText(text) + s.SetMessagePort(port) + s.EnableOverlay(overlay) + for b = 0 to buttons.Count()-1 + s.AddButton(b, buttons[b]) + next + s.SetFocusedMenuItem(default) + s.Show() + result = 99 'nothing pressed while true - msg = wait(0, port) - if msg.isScreenClosed() - exit while - else if msg.isButtonPressed() + msg = s.wait(port) + if msg.isButtonPressed() result = msg.GetIndex() exit while + else if msg.isScreenClosed() + exit while end if end while -End Sub + return result +End Function Function KeyboardScreen(title = "", prompt = "", text = "", button1 = "Okay", button2= "Cancel", secure = false, port = invalid) as string + m.mainScreen = CreateObject("roScreen", true, 1280, 720) + m.mainScreen.SetMessagePort(m.port) + m.mainScreen.SetAlphaEnable(true) if port = invalid then port = CreateObject("roMessagePort") result = "" - port = CreateObject("roMessagePort") - screen = CreateObject("roKeyboardScreen") + screen = CreateKeyBoardScreen() screen.SetMessagePort(port) screen.SetTitle(title) screen.SetDisplayText(prompt) @@ -626,22 +639,27 @@ Function KeyboardScreen(title = "", prompt = "", text = "", button1 = "Okay", bu screen.SetSecureText(secure) screen.Show() while true - msg = wait(0, port) - if type(msg) = "roKeyboardScreenEvent" - if msg.isScreenClosed() + msg = screen.wait(port) + if msg.isScreenClosed() + exit while + else if msg.isButtonPressed() + if msg.GetIndex() = 1 and screen.GetText().Trim() <> "" 'Ok + result = screen.GetText() + exit while + else if msg.GetIndex() = 2 'Cancel + result = "" exit while - else if msg.isButtonPressed() - if msg.GetIndex() = 1 and screen.GetText().Trim() <> "" 'Ok - result = screen.GetText() - exit while - else if msg.GetIndex() = 2 'Cancel - result = "" - exit while - end if end if end if end while screen.Close() + if isHD() + m.mainScreen = CreateObject("roScreen", true, 854, 480) + else + m.mainScreen = CreateObject("roScreen", true, 640, 480) + end if + m.mainScreen.SetMessagePort(m.port) + m.mainScreen.SetAlphaEnable(true) return result End function diff --git a/source/libCanvas.brs b/source/libCanvas.brs index 35a13a9..0cb66b9 100644 --- a/source/libCanvas.brs +++ b/source/libCanvas.brs @@ -37,6 +37,9 @@ Function CreateCanvas() as object m.fonts.AddReplace("big", m.fonts.reg.GetDefaultFont(40 * this.scale, false, false)) m.fonts.AddReplace("huge", m.fonts.reg.GetDefaultFont(46 * this.scale, false, false)) end if + ' Initialize Cache + InitCache() + this.stackId = m.stack.Count() m.stack.Push(this) return this diff --git a/source/libKeyboardScreen.brs b/source/libKeyboardScreen.brs new file mode 100644 index 0000000..5282964 --- /dev/null +++ b/source/libKeyboardScreen.brs @@ -0,0 +1,444 @@ +' ******************************************************************************************************** +' ******************************************************************************************************** +' ** Roku Prince of Persia Channel - http://github.com/lvcabral/Prince-of-Persia-Roku +' ** +' ** libKeyboardScreen.brs - Library to implement a Keyboard Screen +' ** Created: October 2019 +' ** Updated: October 2019 +' ** +' ** Copyright (C) Marcelo Lv Cabral < https://lvcabral.com > +' ******************************************************************************************************** +' ******************************************************************************************************** + +Function CreateKeyBoardScreen() as object + ' Objects + this = {buttons:[], canvas: CreateCanvas(), focused: {r:0,c:1}} + this.screen = this.canvas.screen + this.codes = m.code + this.sounds = m.sounds + this.theme = m.theme + this.fonts = m.fonts + this.textFont = m.fonts.reg.GetDefaultFont(25, false, false) + this.modes = [] + this.currentMode = 0 + this.capsLock = false + this.shift = false + ' Properties + this.title = "" + this.text = "" + this.displayText = "" + this.blinkCursor = false + this.maxLength = 20 + this.secure = false + this.focus = -1 + this.visible = false + ' Methods + this.SetMessagePort = set_msg_port + this.SetTitle = set_title + this.SetText = set_text + this.SetDisplayText = set_display_text + this.SetMaxLength = set_max_length + this.SetSecureText = set_secure_text + this.GetText = get_text + this.AddButton = add_button + ' this.ClearButtons ' Not Implemented + this.Show = show_keyboard_screen + this.Wait = wait_keyboard_screen + this.Close = close_screen + this.SetModes = set_keyboard_modes + + ' Initialize Canvas + this.SetModes() + this.canvas.SetLayer(0, GetOverhang()) + + return this +End Function + +Sub show_keyboard_screen() + txtArray = [] + imgArray = [] + keybPos = {x: 255, y: 280} + cursorPos = { x: keybPos.x + 770, y: keybPos.y - 96 } + txtArray.Push({ Text: m.title + TextAttrs: {color: m.theme.BreadcrumbTextLeft, font: "Large", HAlign: "Right"} + TargetRect: {x: 578, y: 72, w:650, h:36}}) + imgArray.Push({ url: "pkg:/images/keyboard-field.png" + CompositionMode: "Source" + TargetRect: {x:keybPos.x, y:keybPos.y-110}}) + imgArray.Push({ url: "pkg:/images/keyboard-back.png" + CompositionMode: "Source" + TargetRect: {x:keybPos.x, y:keybPos.y}}) + if m.secure then text = String(Len(m.text), "*") else text = m.text + txtArray.Push({ + Text: text + TextAttrs: {color: "#A7A7A7FF", font: "Medium", HAlign: "Right", elipsis: true} + TargetRect: {x:keybPos.x+20, y:keybPos.y-90, w:747, h:36}}) + if m.blinkCursor + m.canvas.SetLayer(3, { url: "pkg:/images/keyboard-cursor.png", TargetRect: cursorPos }) + else + m.canvas.ClearLayer(3) + end if + m.blinkCursor = not m.blinkCursor + txtArray.Push({ + Text: m.displayText + TextAttrs: {color: "#666D70FF", font: "Medium", HAlign: "Right"} + TargetRect: {x:keybPos.x+15, y:keybPos.y-36, w:770, h:36}}) + ' Setup Keyboard + m.keys = [[],[],[],[]] + for c = 0 to 11 + for r = 0 to 3 + char = m.modes[m.currentMode].Mid(c+12*r,1) + if c > 0 and c < 11 + if c <= 7 + xc = c-1 + x = keybPos.x+199 + (46*xc) + y = keybPos.y+21 + (46*r) + else + xc = c-8 + x = keybPos.x+537 + (46*xc) + y = keybPos.y+21 + (46*r) + end if + if char <> m.K_SKIP + if c = m.focused.c and r = m.focused.r + color = "#0094FFFF" + imgArray.Push({ url: "pkg:/images/keyboard-key.png" + CompositionMode: "Source" + TargetRect: {x:x, y:y-7}}) + else + color = "#A7A7A7FF" + end if + txtArray.Push({ + Text: char + TextAttrs: {color: color, font: m.fonts.KeysFont, HAlign: "Center"} + TargetRect: {x:x, y:y, w:42, h:32}}) + else + txtArray.Push({ color: "#585858FF" + TargetRect: {x:x, y:y-6, w:42, h:42}}) + end if + else if c = 0 + x = keybPos.x+13 + y = keybPos.y+14 + (46*r) + if c = m.focused.c and r = m.focused.r + if r = 0 + img = "pkg:/images/keyboard-caps.png" + else + img = "pkg:/images/keyboard-long.png" + end if + color = "#0094FFFF" + imgArray.Push({ url: img + CompositionMode: "Source" + TargetRect: {x:x, y:y}}) + else + color = "#3C3C3CFF" + end if + if r > 0 + if r = 1 + caption = "abc123" + else if r = 2 + caption = "&%#?" + else if r = 3 + caption = "åÅñÑ" + end if + txtArray.Push({ + Text: caption + TextAttrs: {color: color, font: m.fonts.KeysFont, HAlign: "Center"} + TargetRect: {x:x + 40, y:y + 6, w:106, h:32}}) + end if + else if c > 10 + if c = m.focused.c and r = m.focused.r + x = keybPos.x+692 + y = keybPos.y+15 + (46*r) + color = "#0094FFFF" + if r = 0 + img = "pkg:/images/keyboard-shift.png" + else if r = 1 + img = "pkg:/images/keyboard-space.png" + else if r = 2 + img = "pkg:/images/keyboard-clear.png" + else if r = 3 + img = "pkg:/images/keyboard-backspace.png" + end if + imgArray.Push({ url: img + CompositionMode: "Source" + TargetRect: {x:x, y:y}}) + end if + end if + m.keys[r].Push(char) + next + next + ' Setup Left Keys + if m.capsLock + imgArray.Push({ url: "pkg:/images/keyboard-check.png" + TargetRect: {x:keybPos.x+24, y:keybPos.y+25}}) + end if + img = "pkg:/images/keyboard-bullet-on.png" + if m.currentMode < 2 + modePos = {x:keybPos.x+17, y:keybPos.y+66} + if m.focused.c = 0 and m.focused.r = 1 + img = "pkg:/images/keyboard-bullet-sel-on.png" + end if + else if m.currentMode < 4 + modePos = {x:keybPos.x+17, y:keybPos.y+112} + if m.focused.c = 0 and m.focused.r = 2 + img = "pkg:/images/keyboard-bullet-sel-on.png" + end if + else + modePos = {x:keybPos.x+17, y:keybPos.y+158} + if m.focused.c = 0 and m.focused.r = 3 + img = "pkg:/images/keyboard-bullet-sel-on.png" + end if + end if + + imgArray.Push({ url: img + TargetRect: modePos}) + + ' Setup Buttons + if m.buttons.Count() > 0 + menuPos = {x: 224, y: m.screen.GetHeight() - 70 - (36 * m.buttons.Count())} + for i = 0 to m.buttons.Count() - 1 + if i = m.focus + imgArray.Push({ url: "pkg:/images/paragraph-bar.png" + TargetRect: {x:menuPos.x , y:menuPos.y}}) + txtColor = m.theme.ListItemHighlightText + if txtColor = invalid + txtColor = "#FFFFFFFF" + end if + else + imgArray.Push({ url: "pkg:/images/paragraph-bullet.png" + TargetRect: {x:1016 , y:menuPos.y}}) + txtColor = "#666D70FF" + end if + txtArray.Push({ + Text: m.buttons[i].text + TextAttrs: {color: txtColor, font: m.textFont, HAlign: "Right"} + TargetRect: {x:menuPos.x + 28, y:menuPos.y + 2, w:750, h:30}}) + menuPos.y = menuPos.y + 36 + next + end if + m.canvas.SetLayer(1, imgArray) + m.canvas.SetLayer(2, txtArray) + m.canvas.Show() + m.visible = true +End Sub + +Function wait_keyboard_screen(port) as object + if port = invalid then port = m.canvas.screen.port + while true + event = wait(500, port) + if type(event) = "roUniversalControlEvent" and event.IsPress() + index = event.GetInt() + char = event.GetChar() + if index = m.codes.BUTTON_LEFT_PRESSED and m.focused.r < 4 + cols = m.keys[m.focused.r].Count()-1 + m.focused.c-- + if m.focused.c < 0 then m.focused.c = cols + key = m.keys[m.focused.r][m.focused.c] + while key = m.K_SKIP + m.focused.c-- + if m.focused.c < 0 then m.focused.c = cols + key = m.keys[m.focused.r][m.focused.c] + end while + m.sounds.navSingle.Trigger(50) + else if index = m.codes.BUTTON_RIGHT_PRESSED and m.focused.r < 4 + cols = m.keys[m.focused.r].Count()-1 + m.focused.c++ + if m.focused.c > cols then m.focused.c = 0 + key = m.keys[m.focused.r][m.focused.c] + while key = m.K_SKIP + m.focused.c++ + if m.focused.c > cols then m.focused.c = 0 + key = m.keys[m.focused.r][m.focused.c] + end while + m.sounds.navSingle.Trigger(50) + else if index = m.codes.BUTTON_UP_PRESSED + m.focused.r-- + if m.focused.r < 0 + m.focused.r = 3 + m.buttons.Count() + else if m.focused.r < 4 + key = m.keys[m.focused.r][m.focused.c] + while key = m.K_SKIP + m.focused.r-- + key = m.keys[m.focused.r][m.focused.c] + end while + end if + m.focus = m.focused.r - 4 + m.sounds.navSingle.Trigger(50) + else if index = m.codes.BUTTON_DOWN_PRESSED + m.focused.r++ + if m.focused.r > 3 + m.buttons.Count() + m.focused.r = 0 + else if m.focused.r < 4 + key = m.keys[m.focused.r][m.focused.c] + if key = m.K_SKIP then m.focused.r = 4 + end if + m.focus = m.focused.r - 4 + m.sounds.navSingle.Trigger(50) + else if index = m.codes.BUTTON_BACK_PRESSED + m.sounds.navSingle.Trigger(50) + m.Close() + msg = GetScreenMessage(m.focus, "closed") + exit while + else if index = m.codes.BUTTON_REWIND_PRESSED or index = 11 + if Len(m.text) > 0 + m.sounds.roll.Trigger(50) + m.text = Left(m.text, Len(m.text)-1) + else + m.sounds.deadend.Trigger(50) + end if + else if index = m.codes.BUTTON_SELECT_PRESSED + if m.focus >= 0 + m.sounds.select.Trigger(50) + msg = GetScreenMessage(m.buttons[m.focus].id, "button") + exit while + else + key = m.keys[m.focused.r][m.focused.c] + if key = m.K_CAPS ' Caps Lock + m.shift = false + m.capsLock = not m.capsLock + if m.currentMode = 0 and m.capsLock + m.currentMode = 1 + else if m.currentMode = 1 and not m.capsLock + m.currentMode = 0 + else if m.currentMode = 2 and m.capsLock + m.currentMode = 3 + else if m.currentMode = 3 and not m.capsLock + m.currentMode = 2 + else if m.currentMode = 4 and m.capsLock + m.currentMode = 5 + else if m.currentMode = 5 and not m.capsLock + m.currentMode = 4 + end if + m.sounds.select.Trigger(50) + else if key = m.K_SHFT ' Shift + if m.currentMode = 0 + m.currentMode = 1 + else if m.currentMode = 2 + m.currentMode = 3 + else if m.currentMode = 4 + m.currentMode = 5 + end if + m.shift = true + m.sounds.select.Trigger(50) + else if key = m.K_ABC1 ' Letters and Numbers + if m.capsLock or m.shift + m.currentMode = 1 + else + m.currentMode = 0 + end if + m.sounds.select.Trigger(50) + else if key = m.K_SYMB ' Symbols + if m.capsLock or m.shift + m.currentMode = 3 + else + m.currentMode = 2 + end if + m.sounds.select.Trigger(50) + else if key = m.K_ACNT ' Accents + if m.capsLock or m.shift + m.currentMode = 5 + else + m.currentMode = 4 + end if + m.sounds.select.Trigger(50) + else if key = m.K_WIPE ' Clear + if Len(m.text) > 0 + m.sounds.roll.Trigger(50) + m.text = "" + else + m.sounds.deadend.Trigger(50) + end if + else if key = m.K_BKSP ' Backspace + if Len(m.text) > 0 + m.sounds.roll.Trigger(50) + m.text = Left(m.text, Len(m.text)-1) + else + m.sounds.deadend.Trigger(50) + end if + else if key >= m.K_SPAC ' Printable character + if Len(m.text) < m.maxLength + m.sounds.select.Trigger(50) + m.text += key + else + m.sounds.deadend.Trigger(50) + end if + if m.shift and not m.capsLock + if m.currentMode = 1 + m.currentMode = 0 + else if m.currentMode = 3 + m.currentMode = 2 + else if m.currentMode = 5 + m.currentMode = 4 + end if + end if + m.shift = false + end if + end if + else if char >= 32 and char <= 126 ' Basic printable ASCII characters + m.sounds.select.Trigger(50) + m.text += Chr(char) + else if char >= 128 and char <= 255 ' Extended printable ASCII characters + m.sounds.select.Trigger(50) + m.text += Chr(char) + end if + end if + m.Show() + end while + return msg +End Function + +Sub set_keyboard_modes() + 'Constants + m.K_CAPS = Chr(14) + m.K_SHFT = Chr(15) + m.K_ABC1 = Chr(1) + m.K_SYMB = Chr(2) + m.K_ACNT = Chr(3) + m.K_SPAC = Chr(32) + m.K_WIPE = Chr(4) + m.K_SKIP = Chr(9) + m.K_BKSP = Chr(127) + m.K_DBQT = Chr(34) + ' Keyboard Modes + lowerCase = m.K_CAPS + "abcdefg123" + m.K_SHFT + lowerCase += m.K_ABC1 + "hijklmn456" + m.K_SPAC + lowerCase += m.K_SYMB + "opqrstu789" + m.K_WIPE + lowerCase += m.K_ACNT + "vwxyz-_@0." + m.K_BKSP + m.modes.Push(lowerCase) + upperCase = m.K_CAPS + "ABCDEFG123" + m.K_SHFT + upperCase += m.K_ABC1 + "HIJKLMN456" + m.K_SPAC + upperCase += m.K_SYMB + "OPQRSTU789" + m.K_WIPE + upperCase += m.K_ACNT + "VWXYZ-_@0." + m.K_BKSP + m.modes.Push(upperCase) + lowerSymb = m.K_CAPS + "!?*#$%^´ˆ˜" + m.K_SHFT + lowerSymb += m.K_ABC1 + "&,:;`'" + m.K_DBQT + "¨¯¸ " + lowerSymb += m.K_SYMB + "(){}[]~=+×" + m.K_WIPE + lowerSymb += m.K_ACNT + "¡¿<>|\/÷±‰" + m.K_BKSP + m.modes.Push(lowerSymb) + upperSymb = m.K_CAPS + "•·¢£¤¥€¼½¾" + m.K_SHFT + upperSymb += m.K_ABC1 + "®©™«»‹›“”„" + m.K_SPAC + upperSymb += m.K_SYMB + "¦†‡§ƒµ¶‘’‚" + m.K_WIPE + upperSymb += m.K_ACNT + "¹²³º°ª…–—" + m.K_SKIP + m.K_BKSP + m.modes.Push(upperSymb) + lowerAcnt = m.K_CAPS + "àáâãäåæýÿš" + m.K_SHFT + lowerAcnt += m.K_ABC1 + "èéêëìíîžðþ" + m.K_SPAC + lowerAcnt += m.K_SYMB + "ïòóôõöøß" + m.K_SKIP + m.K_SKIP + m.K_WIPE + lowerAcnt += m.K_ACNT + "œùúûüçñ" + m.K_SKIP + m.K_SKIP + m.K_SKIP + m.K_BKSP + m.modes.Push(lowerAcnt) + upperAcnt = m.K_CAPS + "ÀÁÂÃÄÅÆÝŸŠ" + m.K_SHFT + upperAcnt += m.K_ABC1 + "ÈÉÊËÌÍÎŽÐÞ" + m.K_SPAC + upperAcnt += m.K_SYMB + "ÏÒÓÔÕÖØ" + m.K_SKIP + m.K_SKIP + m.K_SKIP + m.K_WIPE + upperAcnt += m.K_ACNT + "ŒÙÚÛÜÇÑ" + m.K_SKIP + m.K_SKIP + m.K_SKIP + m.K_BKSP + m.modes.Push(upperAcnt) +End Sub + +Sub set_display_text(text as string) + m.displayText = text +End Sub + +Sub set_max_length(length as integer) + m.maxLength = length +End Sub + +Sub set_secure_text(secure as boolean) + m.secure = secure +End Sub \ No newline at end of file diff --git a/source/libListScreen.brs b/source/libListScreen.brs index 4193223..dd1e171 100644 --- a/source/libListScreen.brs +++ b/source/libListScreen.brs @@ -4,7 +4,7 @@ ' ** ' ** libListScreen.brs - Library to implement generic List Screen ' ** Created: June 2018 -' ** Updated: September 2019 +' ** Updated: October 2019 ' ** ' ** Copyright (C) Marcelo Lv Cabral < https://lvcabral.com > ' ******************************************************************************************************** @@ -33,14 +33,12 @@ Function CreateListScreen(ignoreBackKey = false as boolean) as object this.SetHeader = set_list_header this.SetContent = set_list_content this.SetItem = set_content_item - this.SetFocusedListItem = set_focused_item + this.SetFocusedListItem = set_focused_list_item + ' this.SetTitle ' Not Implemented this.Show = show_list_screen this.Wait = wait_list_screen this.Close = close_screen - ' Initialize Cache - InitCache() - ' Initialize Canvas this.canvas.SetLayer(0, GetOverhang()) @@ -48,6 +46,7 @@ Function CreateListScreen(ignoreBackKey = false as boolean) as object End Function Sub show_list_screen() + print "Show List:"; m.headerText txtArray = [] imgArray = [] txtArray.Append(m.breadCrumb) @@ -55,7 +54,10 @@ Sub show_list_screen() Text: m.headerText TextAttrs: {color: m.theme.ListScreenHeaderText, font: "Large", HAlign: "Left"} TargetRect: {x:170, y:156, w:524, h:32}}) - if m.content.Count() > 0 + if m.content.Count() > 0 + if m.focus >= m.content.Count() + m.focus = 0 + end if imgArray.Push({ url: m.content[m.focus].HDPosterUrl 'CachedFile(m.content[m.focus].HDPosterUrl + "250x250") TargetRect: {x: 782, y: 200}}) @@ -73,6 +75,14 @@ Sub show_list_screen() url: "pkg:/images/arrow-up.png" TargetRect: {x: 380, y: menuPos.y-40}}) end if + if m.first < 0 or m.last >= m.content.Count() + m.first = 0 + if m.content.Count() > 9 + m.last = 7 + else + m.last = m.content.Count() - 1 + end if + end if for i = m.first to m.last if i = m.focus if m.theme.ListItemHighlightHD <> invalid and m.theme.ListItemHighlightHD <> "" @@ -86,13 +96,20 @@ Sub show_list_screen() else textColor = m.theme.ListItemText end if - txtArray.Push({ - Text: m.content[i].Title - TextAttrs: {color: textColor, font: "Medium", HAlign: "Left"} - TargetRect: {x:menuPos.x, y:menuPos.y, w:420, h:30}}) - imgArray.Push({ - url: m.content[i].HDSmallIconUrl - TargetRect: {x: 654, y: menuPos.y}}) + if m.content[i].HDSmallIconUrl <> invalid + txtArray.Push({ + Text: m.content[i].Title + TextAttrs: {color: textColor, font: "Medium", HAlign: "Left", elipsis: true} + TargetRect: {x:menuPos.x, y:menuPos.y, w:420, h:30}}) + imgArray.Push({ + url: m.content[i].HDSmallIconUrl + TargetRect: {x: 654, y: menuPos.y}}) + else + txtArray.Push({ + Text: m.content[i].Title + TextAttrs: {color: textColor, font: "Medium", HAlign: "Left", elipsis: true} + TargetRect: {x:menuPos.x, y:menuPos.y, w:470, h:30}}) + end if menuPos.y = menuPos.y + 54 next if m.last < m.content.Count() - 1 @@ -107,7 +124,7 @@ Sub show_list_screen() m.visible = true End Sub -Sub set_list_content(list as object) +Sub set_list_content(list as object, refresh = true as boolean) m.content = list for i = 0 to m.content.Count() - 1 m.content[i].HDPosterUrl = CenterImage(m.content[i].HDPosterUrl, 300, 300) @@ -119,7 +136,7 @@ Sub set_list_content(list as object) else m.last = m.content.Count() - 1 end if - if m.visible then m.Show() + if m.visible and refresh then m.Show() End Sub Sub set_content_item(index as integer, item as object, refresh = true as boolean) @@ -128,6 +145,21 @@ Sub set_content_item(index as integer, item as object, refresh = true as boolean if m.visible and refresh then m.Show() End Sub +Sub set_focused_list_item(index as integer) + m.focus = index + if m.content.Count() < 8 + m.first = 0 + m.last = m.content.Count() - 1 + else if index + 8 < m.content.Count() + m.first = index + m.last = index + 7 + else if index - m.content.Count() < 8 + m.first = m.content.Count() - 8 + m.last = m.content.Count() - 1 + end if + if m.visible then m.Show() +End Sub + Function wait_list_screen(port) as object if port = invalid then port = m.canvas.screen.port while true diff --git a/source/libMessageDialog.brs b/source/libMessageDialog.brs new file mode 100644 index 0000000..7770d58 --- /dev/null +++ b/source/libMessageDialog.brs @@ -0,0 +1,142 @@ +' ******************************************************************************************************** +' ******************************************************************************************************** +' ** Roku Prince of Persia Channel - http://github.com/lvcabral/Prince-of-Persia-Roku +' ** +' ** libListScreen.brs - Library to implement generic List Screen +' ** Created: September 2019 +' ** Updated: October 2019 +' ** +' ** Copyright (C) Marcelo Lv Cabral < https://lvcabral.com > +' ******************************************************************************************************** +' ******************************************************************************************************** + +Function CreateMessageDialog() as object + ' Objects + this = {buttons:[], canvas: GetTopCanvas()} + this.screen = this.canvas.screen + this.codes = m.code + this.sounds = m.sounds + this.theme = m.theme + this.titleFont = this.canvas.fonts.reg.GetDefaultFont(32, true, false) + this.textFont = this.canvas.fonts.reg.GetDefaultFont(25, false, false) + + this.title = "" + this.text = "" + this.focus = 0 + this.overlay = false + this.visible = false + this.backCache = false + this.lineHeight = this.textFont.GetOneLineHeight() + + ' Methods + this.SetMessagePort = set_msg_port + this.SetTitle = set_title + this.SetText = set_text + this.AddButton = add_button + this.EnableOverlay = enable_overlay + this.SetFocusedMenuItem = set_focused_item + this.Show = show_msg_dialog + this.Wait = wait_msg_dialog + + return this +End Function + +Sub show_msg_dialog() + print "Show Dialog" + txtArray = [] + imgArray = [] + imgArray.Push({ url: "pkg:/images/dialog-top.png" + TargetRect: {x:254, y:171}}) + imgArray.Push({ url: "tmp:/dialog-back.png" + TargetRect: {x:254, y:203}}) + txtArray.Push({ + Text: m.title + TextAttrs: {color: "#4F5962FF", font: m.titleFont, HAlign: "Center"} + TargetRect: {x:275, y:208, w:730, h:32}}) + lines = m.text.Split(Chr(10)) + textHeight = m.lineHeight * lines.Count() + for l = 0 to lines.Count() - 1 + txtArray.Push({ + Text: lines[l] + TextAttrs: {color: "#666D70FF", font: m.textFont, HAlign: "Left"} + TargetRect: {x:294, y:260 + (l * m.lineHeight), w:680, h:m.lineHeight}}) + next + menuPos = {x: 290, y: 280 + (l * m.lineHeight)} + if m.buttons.Count() > 0 + for i = 0 to m.buttons.Count() - 1 + if i = m.focus + imgArray.Push({ url: "pkg:/images/dialog-bar.png" + TargetRect: {x:menuPos.x , y:menuPos.y}}) + textColor = m.theme.ListItemHighlightText + else + imgArray.Push({ url: "pkg:/images/dialog-bullet.png" + TargetRect: {x:948 , y:menuPos.y}}) + textColor = "#666D70FF" + end if + txtArray.Push({ + Text: m.buttons[i].text + TextAttrs: {color: textColor, font: m.textFont, HAlign: "Right"} + TargetRect: {x:menuPos.x + 28, y:menuPos.y + 2, w:622, h:30}}) + menuPos.y = menuPos.y + 36 + next + end if + if not m.backCache + bmp = ScaleToSize(CreateObject("roBitmap", "pkg:/images/dialog-back.png"), 771, menuPos.y-203, false) + png = bmp.GetPng(0, 0, bmp.GetWidth(), bmp.GetHeight()) + png.WriteFile("tmp:/dialog-back.png") + m.backCache = true + end if + imgArray.Push({ url: "pkg:/images/dialog-bottom.png" + TargetRect: {x:254, y:menuPos.y}}) + m.canvas.SetLayer(91, imgArray) + m.canvas.SetLayer(92, txtArray) + m.canvas.Show() + m.visible = true +End Sub + +Function wait_msg_dialog(port) as object + if port = invalid then port = m.canvas.screen.port + while true + event = wait(0, port) + if type(event) = "roUniversalControlEvent" + index = event.GetInt() + if index = m.codes.BUTTON_UP_PRESSED + if m.buttons.Count() > 0 + if m.focus = 0 + m.sounds.dead.Trigger(50) + else + m.focus-- + m.sounds.navi.Trigger(50) + m.Show() + end if + end if + else if index = m.codes.BUTTON_DOWN_PRESSED + if m.buttons.Count() > 0 + if m.focus = m.buttons.Count() - 1 + m.sounds.dead.Trigger(50) + else + m.focus++ + m.sounds.navi.Trigger(50) + m.Show() + end if + end if + else if index = m.codes.BUTTON_BACK_PRESSED + m.sounds.navi.Trigger(50) + msg = GetScreenMessage(m.focus, "closed") + exit while + else if index = m.codes.BUTTON_SELECT_PRESSED + m.sounds.select.Trigger(50) + msg = GetScreenMessage(m.buttons[m.focus].id, "button") + exit while + end if + end if + end while + m.canvas.ClearLayer(91) + m.canvas.ClearLayer(92) + m.canvas.Show() + return msg +End Function + +Sub enable_overlay(enable as boolean) + m.overlay = enable +End Sub diff --git a/source/libScreens.brs b/source/libScreens.brs index 699c96c..acdbcd2 100644 --- a/source/libScreens.brs +++ b/source/libScreens.brs @@ -4,7 +4,7 @@ ' ** ' ** libCanvas.brs - Library with generic methods for Screen objects ' ** Created: June 2018 -' ** Updated: September 2019 +' ** Updated: October 2019 ' ** ' ** Copyright (C) Marcelo Lv Cabral < https://lvcabral.com > ' ******************************************************************************************************** @@ -36,13 +36,21 @@ Sub set_breadcrumb_text(leftText as string, rightText as string) m.breadCrumb = [] m.breadCrumb.Push({ Text: leftText TextAttrs: {color: m.theme.BreadcrumbTextLeft, font: font, HAlign: "Left"} - TargetRect: {x:xl, y:72, w:wl, h:24}}) + TargetRect: {x:xl, y:72, w:wl, h:30}}) m.breadCrumb.Push({ Text: "•" TextAttrs: {color: m.theme.BreadcrumbDelimiter, font: font, HAlign: "Left"} - TargetRect: {x:xb, y:72, w:20, h:24}}) + TargetRect: {x:xb, y:72, w:20, h:30}}) m.breadCrumb.Push({ Text: rightText TextAttrs: {color: m.theme.BreadcrumbTextRight, font: font, HAlign: "Left"} - TargetRect: {x:xr, y:72, w:wr, h:24}}) + TargetRect: {x:xr, y:72, w:wr, h:30}}) +End Sub + +Sub set_title(title as string) + m.title = title +End Sub + +Sub set_text(text as string) + m.text = text End Sub Sub set_focused_item(index as integer) @@ -50,10 +58,18 @@ Sub set_focused_item(index as integer) if m.visible then m.Show() End Sub +Function get_text() as string + return m.text +End Function + Function get_content_list() as object return m.content End Function +Sub add_button(id as integer, text as string) + m.buttons.Push({id: id, text: text}) +End Sub + '------ ' Generic Functions @@ -117,7 +133,7 @@ End Function Function CachedFile(fileName as string) as string g = GetGlobalAA() tmpFile = g.cache.Lookup(fileName) - if tmpFile = invalid then tmpFile = fileName + if tmpFile = invalid then tmpFile = "" return tmpFile End Function