From 2b22ac7ecad986e94de0b8a8c5a381c9209e4d1d Mon Sep 17 00:00:00 2001 From: Bobbi Webber-Manners Date: Sun, 18 Oct 2026 00:53:32 -0400 Subject: [PATCH] Improved shortcuts using Open Apple. --- softcard65.asm | 8 ++- softcard80.asm | 143 +++++++++++++++++++++++++++++-------------------- zapple2.po | Bin 819200 -> 819200 bytes 3 files changed, 92 insertions(+), 59 deletions(-) diff --git a/softcard65.asm b/softcard65.asm index f28bb44..7bc7cce 100644 --- a/softcard65.asm +++ b/softcard65.asm @@ -325,7 +325,9 @@ HANDLR LDA #0 LDA #0 ; If no chars, return 0 in AREG JMP :C3DONE ; ... :C3YES LDA $C000 ; Expose keycode without consuming the key - STA YREG ; AREG remains the original boolean interface + STA YREG + LDA $C061 ; Open Apple pushbutton (bit 7 = pressed) + STA XREG ; modifier accompanying the peeked character LDA #1 :C3DONE STA AREG ; Store the value for the Z80 JMP RWRETURN ; Restore transient bank @@ -813,10 +815,13 @@ VGET JSR VPEEK :VGWAIT LDA $C000 ; keyboard latch; bit 7 means key ready BPL :VGWAIT PHA + LDA $C061 ; sample Open Apple BEFORE strobe is cleared + STA VKMOD BIT $C010 ; clear keyboard strobe LDA VUNDER JSR VDRAW ; restore original character PLA + LDX VKMOD ; HANDLR returns X in XREG alongside AREG keycode RTS VBELL BIT $C030 ; click speaker @@ -898,6 +903,7 @@ VSTATE DB 0 ; 0 idle, 1 ESC, 2 coord1, 3 coord2 VCOORD DB 0 VCRP DB 0 ; Suppress second half of CR/LF pair VATTR DB 0 ; Soroc ESC '(' inverse on, ESC ')' normal +VKMOD DB 0 ; last blocking key's Open Apple state (outside saved video) * Loader diagnostics without ROM I/O. CROUT LDA #$0D diff --git a/softcard80.asm b/softcard80.asm index 7d1c285..1192ea2 100644 --- a/softcard80.asm +++ b/softcard80.asm @@ -177,7 +177,7 @@ RWD_DONE LD A,B RET RWTOTAL DEFB 1 TABCOUNT DEFB 1 -TABREQ DEFB 0FFH ; ^] followed by 0..9/A..F, FF = none +TABREQ DEFB 0FFH ; Open Apple + 0..9/A..F/arrows; FF = none RWREPORT LD DE,RWMSG1 CALL C_WRITESTR LD A,(RWTOTAL) @@ -232,18 +232,17 @@ RWD_TEND POP AF JP C_WRITE ORG 00300H -CR_SELCMD CALL BIOSCONIN ; selector after Ctrl-] at CCP - CALL TABDECODE - JP C,CRSL1 ; bad key: continue editing - LD (TABREQ),A - XOR A - LD (IX+1),A ; discard partial command line +; A queued Open Apple hotkey returns immediately, with no key passed +; to an application. CCP discards the current unfinished command line. +CR_SELCMD XOR A + LD (IX+1),A RET -; Fullscreen CP/M programs commonly poll BDOS 11 or BIOS CONST before -; reading a keystroke. Detect ^] here rather than waiting for a read call. -; CMD=3 returns 0/1 in AREG and an unconsumed keycode in YREG. -; Return FF/00 as usual; F3 is a private deferred-status marker on suspend. +; Fullscreen applications poll BDOS 11 or BIOS CONST before reading a +; character. CMD=3 peeks at $C000 and samples Open Apple ($C061) in XREG. +; Valid shortcuts consume the keyboard strobe directly, without drawing +; a cursor or waiting for another character. Ordinary keys are untouched. +; F3 is the private deferred-status marker on suspension. TSKSTAT LD A,3 LD (CMD),A LD (SOFTCARD),A @@ -252,12 +251,10 @@ TSKSTAT LD A,3 JR Z,TSSTEMPTY LD A,(YREG) AND 07FH - CP 01DH - JR NZ,TSSTREADY - CALL BIOSCONIN ; consume ^] only, leave other keys alone - CALL TSKKEY ; get selector and queue tab switch - JR NC,TSKSTAT ; invalid selector: resume status polling - LD A,0F3H ; deferred status poll on resume + CALL TSKKEY + JR NC,TSSTREADY + LD A,(0E010H) ; Apple II $C010: clear just this key + LD A,0F3H ; resume the pending status poll LD L,A RET TSSTREADY LD A,0FFH @@ -267,11 +264,10 @@ TSSTEMPTY XOR A LD L,A RET -; Cold-start BANKS report also tells the user how to switch sessions. -; Ctrl-] is ASCII $1D; Ctrl-[ is ESC and is NOT our switch key. +; Advertise the modifier and arrows as one-keystroke shortcuts. RWMSG3 DEFM ' sessions (0-9,A-F)' DEFB 13 - DEFM 'Switch: ^] (Ctrl-]) then 0-9/A-F' + DEFM 'Switch: Open Apple+0-9/A-F, left/right arrows' DEFB 13,'$' ; Print the current logical session and drive: [0]A:> ... [F]P:> @@ -299,8 +295,8 @@ CCPPRNT LD E,'[' ; Phase 3A: two independent CCP contexts. TAB 0 / TAB 1 switches ; shell state (drive/user, IOBYTE, login/R/O vectors, terminal type). ; The transient for a context uses its corresponding RamWorks bank. -; Phase 3B: Ctrl-] at supported input calls parks one transient in each -; bank. TAB n resumes a parked transient, rather than reloading it. +; Phase 3B: Open Apple shortcuts park a transient without reloading it. +; TAB n resumes a parked transient, rather than reloading it. ; Phase 3C: full text-screen/terminal-state snapshots in reserved bank 2. ; Still cooperative: no switching from a CPU-bound loop. CCPTAB LD A,(FILEBUF) @@ -392,7 +388,7 @@ CCPPRPTR LD A,(TABMODE) TABMODE DEFB 0 TB_PREFIX DEFM 'TAB ' DEFB '$' -TB_SUFFIX DEFM ' (Ctrl-] then 0-9/A-F)' +TB_SUFFIX DEFM ' (OA+0-9/A-F OA+arrows)' DEFB 13,'$' ; Session descriptors are only seven bytes each, stored in MAIN memory. @@ -536,25 +532,20 @@ B_DRV_RESET EQU 25H ; Selectively reset disk drives ; ================================================================ ; RamWorks Phase 3B: two parked AUX transients, cooperative switching. ; Resident MAIN-memory code below $1000 is outside both AUX TPAs. -; ^] is intercepted at BDOS 1, BIOS CONIN, and BDOS 6 input, and at -; the start of a buffered BDOS 10 input line. No interrupt preemption. +; Open Apple is sampled alongside each keystroke or status peek. +; It cooperatively parks applications; no interrupt preemption. ; ================================================================ ORG 00800H ; BDOS 10 may suspend only at an empty line. A successful hotkey ; parks the read itself; resume restarts it, without submitting CR. -AXLSKEY LD A,C - OR A - JP NZ,AXLNEXT - CALL TSKKEY - JP NC,AXLNEXT ; invalid selector, keep waiting - LD A,0FAH ; deferred BDOS 10 input +AXLSKEY LD A,0FAH ; deferred BDOS 10 input LD L,A RET -; BDOS function 1 cooked input, with suspend hotkey and Ctrl-C. +; Blocked BDOS 1 and BIOS CONIN sample Open Apple at key-read time. TSKCIN CALL BIOSCONIN - CP 01DH - JR Z,TSKCIKEY + CALL TSKKEY + JR C,TSKCIKEY CP 3 JR NZ,TSKECHO LD A,1 @@ -568,20 +559,16 @@ TSKECHO PUSH AF POP AF LD L,A RET -TSKCIKEY CALL TSKKEY - JR NC,TSKCIN ; no switch, consume nothing - LD A,0F1H ; deferred cooked input +TSKCIKEY LD A,0F1H ; deferred cooked input LD L,A RET TSKBIRD CALL BIOSCONIN - CP 01DH - JR Z,TSKBIKEY + CALL TSKKEY + JR C,TSKBIKEY LD L,A RET -TSKBIKEY CALL TSKKEY - JR NC,TSKBIRD - LD A,0F2H ; deferred BIOS character input +TSKBIKEY LD A,0F2H ; deferred BIOS character input LD L,A RET @@ -605,17 +592,50 @@ TSKACTIVE CALL TSKFLPTR LD A,(HL) RET -; ^] is a prefix. Carry=1 when a valid selector queued a switch; -; carry=0 if invalid (caller retries its original keyboard operation). -TSKKEY CALL BIOSCONIN +; A=ASCII key, XREG=Open Apple state sampled by the 6502 at key read. +; Carry=1 if a shortcut was queued, else carry=0 and A is unchanged. +; Arrow keys wrap around TABCOUNT; numeric/hex keys select directly. +; Preserve BC (TABDECODE uses C, and AXLINE holds its count there). +TSKKEY PUSH BC + PUSH AF + LD A,(XREG) + BIT 7,A + JR Z,TSKIGNORE + POP AF + PUSH AF + CP 08H ; Apple IIe left-arrow + JR Z,TSKPREV + CP 15H ; Apple IIe right-arrow + JR Z,TSKNEXT CALL TABDECODE JR C,TSKIGNORE - LD (TABREQ),A + JR TSKQUEUE +TSKPREV LD A,(TABMODE) + OR A + JR NZ,TSKPREVB + LD A,(TABCOUNT) +TSKPREVB DEC A + JR TSKQUEUE +TSKNEXT LD A,(TABMODE) + INC A + LD B,A + LD A,(TABCOUNT) + CP B + JR Z,TSKWRAP + JR C,TSKWRAP + LD A,B + JR TSKQUEUE +TSKWRAP XOR A +TSKQUEUE LD (TABREQ),A LD A,3 LD (AXQUIT),A + POP BC ; discard the original character/flags + POP BC ; restore caller's BC SCF RET -TSKIGNORE OR A ; clear carry +TSKIGNORE POP AF ; ordinary key: return it unchanged + POP BC + OR A ; clear carry RET TSKSET PUSH AF @@ -750,7 +770,7 @@ TSKRFIN XOR A LD (AXDMAP),HL RET -TSKMSG DEFM 'Suspended (Ctrl-] then 0-9/A-F to switch)' +TSKMSG DEFM 'Suspended (Open Apple+0-9/A-F/arrows)' DEFB 13,'$' TSKBUSY DEFM 'Session suspended: select it first' DEFB 13,'$' @@ -1191,7 +1211,7 @@ AXAUXWR XOR A ; no punch/list device attached ; Direct BIOS console calls use private C codes $F1..$F3 from the LC ; jump-table shims. Caller registers are preserved by those shims. -AXBICON JP TSKSTAT ; catch ^] while BIOS CONST polls +AXBICON JP TSKSTAT ; catch Open Apple while BIOS CONST polls AXBIREAD JP TSKBIRD ; handler moved under $0800 AXBIOUT CALL C_RAWPUT XOR A @@ -1261,9 +1281,18 @@ AXLNEXT PUSH BC POP HL POP BC AND 07FH - CP 01DH ; only suspend at start of a new line - JP Z,AXLSKEY - CP 13 + ; For BDOS 10, park only at the beginning of a line. + ; Once characters have been entered, don't discard the line. + PUSH AF + LD A,C + OR A + JR NZ,AXLNOKEY + POP AF + CALL TSKKEY + JP C,AXLSKEY + JR AXLKEY +AXLNOKEY POP AF +AXLKEY CP 13 JR Z,AXLDONE CP 3 JR Z,AXLCAN @@ -2384,15 +2413,13 @@ AUXBDOS6 LD A,E CP 0FFH JR NZ,AB6OUT ; control-character output is not input AB6IN CALL C_RAWIO - CP 01DH - RET NZ CALL TSKKEY - JR NC,AB6IN ; invalid selector, poll again + RET NC ; no shortcut: return raw character/0 LD A,0F6H ; deferred BDOS 6 poll LD L,A RET AB6OUT JP C_RAWIO -ABDSTAT JP TSKSTAT ; catch ^] while BDOS 11 polls +ABDSTAT JP TSKSTAT ; catch Open Apple while BDOS 11 polls AUXBDOS9 PUSH BC PUSH DE PUSH HL @@ -2782,10 +2809,10 @@ C_READSTR LD H,D ; HL will be the working pointer CRSL1 PUSH HL CALL BIOSCONIN ; Raw key, no premature echo POP HL + CALL TSKKEY ; includes Open Apple+arrows + JP C,CR_SELCMD CP 3 ; Preserve CP/M Ctrl-C abort JP Z,BDOSWARM - CP 01DH - JP Z,CR_SELCMD CP 13 JR Z,CRSEND CP 10 diff --git a/zapple2.po b/zapple2.po index 5d2bcded374c3c8971efd825d45772f98721e4f5..8ef9a853382818313373f9530093ad806ecdac06 100644 GIT binary patch delta 6255 zcmZuV3v?6Jwln#(Nt)86g*g3CW|9hN3bc-VY90i+6+sOY5nWyp3Erm`FHmTerXWe6 zKM4(OIaAQ3Xr&dbSW;lQLQ4kIMtn?gdJA5BkGqW0dvB|j7F)RG^@v3b0Q9H)+XaU=yh$5?m&CN2cIdrZ`hhu6*0|i6|p39n!Jg+w8^HMtgU&$FOaaj z4a?IaPxB+cpdfAH+fRQ1!j+10rJ|r>(E7JFPSUL)1)Km&yHjUkfgE`=W(~EqV1Wu{ z%lbftq8S&-DxXkIku`gVN)JEL+s>IUr?UY4^M#Ww#+$(qt!S|DLsRs%`}+ z9%8NQ{ni8RnNChM6uV5s6db?K4oR)E&v2rZOaoSZT{M=+5v^Z*^aC4M+4{MspRE?6 zTG`qmV2IXs2(r3=ockki?LO{7&~9d(+~TOQKfnYrnOg!Nxc2an)JmNZ zyfb#kfG@+KHxnRCgcbsm@eF5z3F6F(POD)8$v+Osxu=G38^{9p_bhlN1T!RT;rBwO zTZUNY(0Vb;ww8Xj8@F`xdBN*DQ!9|Q#*D_e1!Xz6-C3)&$)qJHZ}fx4`@LF9BsS!;(2Jc5ya zc9}pVi~JKpaiR{uSnK@)Q-Ki1@qU(VV?Dio&ka9&k@fWXJvaRz`RE58JOFbh-YuK? zWWY9ab-=caJmoKV6O(yX2RvB72CFtqwhSn+Dp+kJulqd%Y>paAOQv*ntCfLn1=OFd zRg$>~T!e$7xxEZdisuG9Qxj+zU;$Zh{03{AnG=Y{2M&Q%P)I(_f>H8m^o;IaW4Q>! z7&UtsW7}EJdn|j2^&A$RZ(;?{-$zGvPiA4w@lf{59)&+rdbS`lfm78=i4BnM9Kg5y z9S-FnY~J^WSsTJ77fuo~sf4RRyQYmHY1(c)3st7=B)#DhoU=&jm?0Ybr#W`WXPjbI z4)r}~j?YM6!+*Nl{GNmcDN7N`>$9uj2SiGCq8`!%hQPA?GnQ5z7PR zQ%udjtmL$ZW&G4KQM5*TR2CHBbvlgdPDtjk)rPF`OA0ykklx^2qHu8M zM$C$#3r?eXcqF1Q#zm$WlXyy&n?+0ouY9D`{E}oLp#^xsQUFgI<+)NjfqUr!2_*02 z_KuGE+;E4F8{wBIhD$i$E1Zt4U7eYk`OxxAWpZ+|))k-34dzKygHOm*VSS8hOs`N~ z8O&3u2Axl+Rr*P)D~gdGy+)-lwQScXs!Xlh^^;X59j4c*Oqg9ysLbB&bc)KlU4fG?IxW{uft4)N{`viDJt5#-IS`* zci9IY1KVrVD%1U7+oVzTDuxwd6F6p4s0JScN7u+yoUljdyC{5?wa zg5kmB|6dl_V=UH}M3F=Zh)qrdQ++S81_P98-w6Q7?y%?46!4QtBg>!%(k(!xRKQj4tj? zO8x7Iz0EjjxWu4dcdi%ewx@&W7$(k^`i$-9&R!kfh;-F@h~a_i8TU`A2s(=RxUHS% zw@@qWu+@TJt12e^0*`#1ZxsP;a1Cb1UEmQy)zjm;gxtVj40WMTt23PcTO>pvikoG2 z$nVl($gi~+^80u(l^s5Enx@}8 z_tk~;+*gS!+Km|BhIZ{sqT0%N@>N13BFcSaY&2|68?J*ML=0=cJN5Ct)wou&f61!F zB#9r}ziP<}m@lK0+UEHK48N_Kf8(&PQ(8g|ApTF)K617>w!~+?g^aSkg@oi*Cw&W9 zV(FWRk~2Ubv8Vw4vDSruhj!E%@Rv`$Tj!R*MbX4e!`n|i%B17+Gd07(GiX!&!JJw3 z)U0~g1)eJRb?&e8(ht1)%cDnOxc>D9YR-GWqMcRGtI?bT>oWj=pn7+D;d}<)tP==7 zuN$Ik)OKJ8RLtCiGvbAcGz!(J5o%$>!BpIjDh|%X-$W-5dbM$U?{28ZZp$qw`rh3^ z`KfJhcqAyGmLcg|p7^gBa7pOmkIH!(9eQgS&Y`}y{`?<@%04VRQO1}3RMu8LrD9cu zt3qA5vr<}BS=Ci_sp@~K!c{tVuKUoo1@1ie2KN>BfxUC8t<~<`?%h{V_1h=n!~-CW zNJAg)LQ4-B@&7_w4*gN~AY>5nhvqo%=KZ3t^W$a|9!&ninzPY~+qHiHd6RmRt_^z{__MsIuHC66CA(581yFW$|Z zkDNq(DHLpEMMzQNGfD)rm-#6b;MD_BvpzCM>%ztpDHJ(L-W4HZ;YDgGArgF~`eIay z40#DqG9t>Nv3K<|A7^Na2|LK}!)ktB4fTka^yQ(=m65zqaV4bRUI{LXd!k2=H9R^W z1af{yU_cOn0qeXqA#fi<8AW|7LbuW94U6ZAaZy1rB8=2QoAI3=Id?f<`+OCgWB%=$ ziygz97^{eVB#K3O?>(cB777Fi)pV{Z3@7gSKf_^Au3ig=o4N`r(I@Xw&VN=>*eK_v zTNr-kp3a0llmyfFGkk^sn`NVYLy@7*_&sLBXk>;kXN*STVK!xs>YJF?J`Tn2(Kj#` z7F?JrJkj+LCQE;S+1VGn)Z)sw`$~=S3yb8$2>l^rIxxX1u)}*I*{T14F&$yFO3XL7 zDo09TnEn`JnlTzx)z1vBX<~qKDSnSYI?R|F1gn32J?bF1j$@MNbc$XPZ=9Y5-t_FK zT9>2jH63OQAkZ^~{JSB}euBJW>IXzW6Rdu{hroE<9$>hzz!~-Yq2=}y=S{~z_xUWr zfe#q-hfMa75*RNmBBd5r7Pt?t#u5K*i3qvU?cu=qygOQa6u%P-7Zd6m@uYF)uNf#i zFJ$yvhB_|d0%mN~7b@Mel)^_Hk?c;H+aRBW*?l3I+u@948{^ca5zQq5OI#}zuymM# zLi~y$WL_Al(@`y9$~79J2|F->r7t0Ldr!XkD=;?Q9A?@&Z|^x5?!A~qNk$i^^nH`> z==-LPR3sTRH#&l`?v5akOFxs+*eLigFWVrnE>0;iB%!YwCuIdi1Ek8_#Y7TFX$KMC zq19mFWO?V_J(e*JO!f^yIN;OQXiAew1~pTM@|toV7S96zL`{y|5)*7_oHz_2H`MlD z+)&$pbx#}yhQ}HrR%6=uIU%QpH&fvk^?WVrXv%RyyIRZ8;#nDQTAdYpe^zaNnW0uO z2Mo}%-Z4P;dM8I`TE*y}W6Y}=+Qv{%iXni=gbzFRf*}|%K;HFX;(X;9QzOg373f+~ zFC^eb(fgS);nbja-`730;coBj%&rdpv^Uyrv#WpAYkffbO{*P=w!@{v0uAmY!0<9t z*ymgaj=yByh~kdS#VgR_BkS>RQR9(*zLiu^hw5PiC)el`(drN8JLR5>J-wItwfipiKyT(ui8cI=eIwAX z!wz+1QD^@?^Aw?#O9&k#uXn6x%%O%ZJyxQI)|?T-l=HW1i68ieTB6@V!n8etlM)>k zo`+#@^(x|esX+#^*prTN27@DFCQ;3Yq;p!`4jL-%wc6fum+cYUsEkOBDzHu{pj{Kv zs6)alzp8c;#>19%^Z*-~V9BHB)m!rE`Sq6NbZ)(jvyj1Qb@oV%G1b9Oue19|iHwWj z=N-I&l^CTFSwO})fG1png$pJRrF{#qfN(B)8K zl=H19owx>Dk^~UkX~bB$@stR6oG@x>Nppr8ZLtGQK`3_GkEF0V+6d)qN}oD1dhE6M^Ouz)wRcbUZb-56ohi0&Vr? zoyzupp-T1A(;0dOLnVuC7wXFzFwcN1rQSRprMG7&p&PZ83wJNHD<$_-S^N9=i~+{6 zU}?(PfFViqZ!Z+5QD!cz=ggbyIa<~@LUlCq-o|10+Q|23rQN+%`T}NIBVXI3$L;$hzNp7;NK z&pGd$*}_7uu#l@u&_piDP!C6i1Y${$f`l z3L({yqJrSJey6BVKymI}dMNg9f2R23pD51%gW?N+rf3OEin$$XD2C_4?gW23hRi>h zTKy-c_EAk?OHPDOilm0&w74uPh_}R5JzmjZ8*H?h1RK|2%WbfIS#P7x*xKrCVP|ag znHuD7uXpGA7)=9HbE*a%Li?Zo@cWLDt%J;x`aYVuA~2^;+18w@T~Y6Tp`LkGq2YD9 zM5-OXrb|z#Xvlu&BW>$ddrf3G6rfZD~Rc<^D>zi=5=lYygI+DyQss@dR6D!y)jq|DWnW z-1VB#?tSXxUkSq62KQdIu)e|lx?0F-aKELtS25AYQiN2e7}H9FX>fO0u#1tcT4iEe z-e{|60B&SoM5aQ?KHeepscosJ#nFAaBI7Jq+a72HdA04@X|SQTT{$gkVHnjY(lD@% zVgw8(0lc?P7NY@&a1&wZI4!31O&5~^jcOFf!ay~OV_;a@C`PsFZN+3zh(rlQQefyf zZHFRsz!Ink?4X=|Gp1i*I#jI@?oQz+AXTB#4#nAUQD67Td!2%Baoq)XyHHBfT3pve zDEhhv$g;Hkmh^iN+P&gKU>-u79db4Y21sEp49gqEd421|`G7)b5BI5U$)`zlrq=Kp z%IW?F?4|;W6l^9)8BdF57{J)1(6AH+P<^H^Onj=3vV$^6Ult%LlFip-NiPfFr}k^1 z?>VK)unUA%%6<_fYA*|77A)^ikO1I>8p2W|9*NL9S5xkwP{S|}G+qn}t=H_wzY+Rq z(OwskI?MJ*BVEXR(FmHv$l^N6u6X*XT>$e?9>sy}S;Eb%srsE{d4IN>IB6F$36ELZ zIHVJ$m;j2cyb*+)LN-a`c)K9HE4Vuv-Mx*1UvPIex_@c})rIf4DIbifRI4WKNuND! zsn4Ft9B<72C(^i=`rOE8hgm(+WC90f*>>hiqx(xCJz8YSHFRNXH0^8E!v3?@sZwV_ zgm7r$e$7ma^VNPSz%+ZbJuTfAN(JQ*|gnrhC?P2Of-4utx#FUNX) zy$Es3V@xAtHKVms+=+b8dU0SS#Mlok$fv_f5Jg56qFlxI8jQ}TwFQI>rI{WHm4Tw1 z$e$*9#R2JQZGWB!k*=SBRxC|TO`Z2xDxH{^s4I*~6np1()4fl8PX`S@&^HV}(x3Ov z{Rs$twBaiKxptt_@C&Uq*XA3p(dN2*!ys)=K!)qI895BU(H2iWC)4JO4#Q2_>ZGJC zTDF^(inKj2P@_?Aod^@%E!=#KHq_>u2WdlHzWF+BNI>S_XajOsWSaBjn{U#Fi;mt$ z!S}L0+6=zUztCOUer?bUahZRldmn{3mwiu*WC>b4;ER-gxJp7QsqR(j|FpQ+_|TZp z3g1<4X5)G$H*fXEzh>hvjVr=qwR*jDAD%sKM3PPojv*S$iF{do;a^%9z0J?(`xoV7 z-RQcL>ha0Xhi@#9qXId2yzAa&dpF4afw?*I)xg6!^3Q=sa^$2ya*nJEST@MR1FJU3 zu>lZ?BOsoD5d@4RAc25U1h51c2rv>bjsR0&FMi)Om-6EQ7w5cC1j{Y8l>nIIS}*!z zwf^`bzrM(tv|a>`U#IrprhDL~6>9a3Ep7v``Ob-+Jch)99M z93jqwE*<)ribaw?mqkB&6zTR79U7#NR-p}gMEv%y2@B;h0i=~1@oTb6qJ~prtSb5Dd7rm?UmDAkv61&I&%TIz`Qaltagz0Ur*Z{oVWynDlLYR1e>4d1Wq+kF{fwTBx z={RTa29lPdZqYcP=rePn=yP(R=nHb8=(b!a`jT8I`ct`3^kunnO2D2Am47}L4E-Y) z3;{3(*5^X`H|B;a+8QgMlXl(hd9 z{WHU*Y?nSp`pl)*N|n3xYU#exp&Zz72wvr&SVTf&r>m)Pq}obqXL1Q`MBrVBrTI+m zP$lkU8*o2>A4-bE>fJLb6`sA@oUmm_lb0DA_k$(l<(XW@%lglCYmjsbZ`~cwp4u)k zFYDtJ!genc5h{wPYp;N=r0>^#ck+YXODP?-Xa3`}8HPHx=kfWAVEiAPR9-W!hnHS1 zm0myOZC2;8Jy=>*>SZQdBJ#YJ0c_HA&(y1~HFE>l8o^z~tcC~vfHe~E>*a;icX)G! zky?H7K!r<1QP|9nrT%qtA)i8pHI()H8}Qo7ed%eHY+5C(k;H6=HLdV)54`;Q)5;>s z@LCmn|3MJZrBzB%`2M}mjRORd>Uz}!N80~-1!3Ho9|+BH{oc*6pECAMj3JxYL^gCB z*(s~{jiyfH;(ck<>-fYz&&XJ*YnwdANBZS}^%|U&u5EtZ$qlc&RapIoJ0{3ONTjbn z5+=>Z``^f$f9T2jzCM>p9Eu01lQ~pGuhbRC*%>zRU={!48v9~C2 z9ZOZSrz&}|%}PdyNq`>YZ5cRsDNFZU2^?eTjk30;eo@I)p=O4tc;3Ok7(yEb5`^7! zwj>A#ZqkU~6vW0`;alryaM7m=G z*LP-FE`zfPmUh0r`TEXt!LGJ=Ry8;~sr##}g6^;C8Ew2V?rM`i+|}d<_NI^292$fe zrcN;u(b-9P#&{g89yY02alk}cBwmhX)J^)BCS4o~CWbY;c3N+U;Ig|9(t((QIN`8a z1AC?%&pSNbrkn-o@v`(VYq-Cvdgw5SF4)@_U9h)5aSa^?UP4u}&6IrWoG@d8>)7B6 z2C1wpn8yTP!fUF`PH0-oc}_Vow^~>8_FZ=zSXT4w5`M1{8rNG!=wWZACzzM;h84W! z37%WYvrCmkKxHVB{9WJ<00QFeNQO??T+?Vd69R(X6^cbAmEqhYsTy*2aMh87r?PK% z(B{dd{$F>6n(pM%yE?8Hczl2M@0?SQ*wAvPUNp+?~aM>%R9&Ij0zYmXYJ zGTaKVAOC#xo{XHzaLu_c^0I`M8nvSnE(PPE$0f%7z`k7R;o{3IIh6}68!GDd!KupcbuPfeirux4;#@a ztI|^!1Pj=#ZYq`w$ps4xFd>3~5j|!01TLzX1Xqqt@Y!~AoWuBS6^YI!xypm4MZ*2<(a#uUhmDNMRvuK!=@K)L=0D+5EmOfjki6r73>+`l%6UF?rM)T=WE ziAH0AY+-QuF~*rvv6+J%x4FFQ+$D!hnP|9HM}l{~7MiwR9SVrN_;-{KLlP`mQzwWq zvDUdMHR+pjZa;YR^%3ou~_rGKClfQz|5j( zI2#&Aec&&+K%NP^@~Y!MDwx2^#t%0nD?FeMI{u>pY2#jVGRpG;KeUpBbi0J1ngU-b zsAUb}mLqlrk_z*@%^<%Puon~*q720k7kuaw8qxnsUMQ%aLkSP@e=P$3co4QG<&oT? z;MLBANgk~4fyIgk1nxXa6~tS`B6py6e7rWH)T?TJlu)!{nGjv~7#Mf1F>npjJD!F|8-^RtE zuK$=Yg<|llLLxQtG=#MbVSyp+!Vq?G2y4BC6)_)|FdtL! dsNhk