8L2C)pJJJJ IH(ȱH:=IH[H`@HcH  $ +   I/H`JLNGȄBȄF aK  haaFF  mJm# KKJ UJ )J ۈ) ;J3ȱJFȱJGJKaȄM  aaNNJFLGJL LULTRAMACROSu#' #' '+DOT.GOODIES  wO".FOR.NEXT.LOOPSwC 'COMPARE 0~C -DOT.DB.AND.SS) sO,DOT.DEFAULTS4wO+DOT.EZ.MENU:$ c SYSUTIL.SYSTEM{c% c% UTIL.0~Qc, c, UTIL.1;yc c UTIL.2 c. c. MOVE15402KA' ULTRAMACROS# COPY.ME$33FASTCOPY.SYSTEM)VNZ [*LAUNCHER.SYSTEMG,b$ b1 PRODOSW#Bb  SETTINGSy >dMԡm#i㰼m#iЕOLԡȱfg hi !dLԡ憦  Ljmkm l y`2 Lԡ8(Je稽)ʈ@LLnSOS BOOT 1.1 SOS.KERNEL SOS KRNLI/O ERRORFILE 'SOS.KERNEL' NOT FOUND%INVALID KERNEL FILE: xةw,@  ȱlmi8#)!)? &PRODOS `DaElH$?EGvѶK+`L HHLy XP LM ŠϠĠӠS)*+,+`F)) (*=GJFjJJA QE'+ '== `@ STSP8QSS8 m P o R(8RbrO-DOT.MENUTOOLS?d-wxO6(DOT.IIGSW sO&.DOT.MENUTOOLS2_)wxO)DOT.STUFFuwM,TIPS.N.STUFF ~C 'A.NOTESC AO=====<====<====<====<====<====<====<====<====<====<====<====<====<====<====<===@O=====<====<====<====<====<====<====<====<====<====<====<====<====<====<====<===off.e 15, /92 5 - 21.09.92 6 - 21-09-92 7 - 92/09/21 8 - 92-09-21 9 - 92.09.2110 - 92092111 - Sep 21 9212 - 21 Sep 9213 - September 21, 199214 - 21 September 1992L// This all .findpo : $1 = .embedded : msg $1>!-----------------------------$1 = .fdate FormatEThis command returns today's date in a variety of possible formats: 1 - 09/21/92 2 - 09.21.92 3 - 09-21-92 4 - 21/09 + " DB and WP files">!------------------------$1 = .embeddedOMThe .embedded command returns the bottom line string from the Word Processer NL(Line 15, Column 12 or Boldface Begin, etc) even if the screen display is off.1::!------------------------.deskcoundefine any strings.<c:!-----------------------------%$1 = .choose "list,of,items",ChoiceLJThis command returns the specified item from a list of items separated by commas with.cachelist FirstStrOMThis command will return the names of the currently cached macro sets in the MKstrings starting with FirstStr. It sets Z equal to the number of currently PNcached files. If you set FirstStr to 0, it will just set Z and not aracter is left as is.?b:!//show result-----------------------------= .awpath : msg $1>!-------------------------* $1 = .case "case string","Work String"IGThis command lets you change the case of a string based on the case of LJanother string. If the case string character is not text, the work string ch.sort\sa-tDemonstrate .speed"\sa-uDemonstrate .substring \sa-wDemonstrate .weekdaystart-----------------------------$1 = .awpathCThis command returns the path where AppleWorks was launched from. a:!-----------------------------.x = .substring "hat","Where is my Hat",StartNLThis command searches for "hat" in "Where is my Hat" starting at the string LJposition specified by Start. Case does not matter. If fan be handy for demos or for debugging. It's NLactually a delay command, since higher numbers make Ultra run slower. Use 0 OMto return to full speed. You may press a key during long delays to hurry the macro along.>T:!----------------------------- .speed 1000NLThis command, written at the request of J.S. Rowe of England, allows you to JHslow down Ultra 4.0. This c.choose $50,x:x=x+1) 5 :1$8 = "Chronological order: " : sa-z :@.sort 1,5,1 : $8 = "Ascending sort order: " : sa-z :A.sort 1,5,0 : $8 = "Descending sort order: " : sa-z :msg "">!:!%:!-----------------------------.sort Start,End,DirectionNLThe sort command ------------------------------------.pop LMKPops return address from the subroutine stack. In English, this means that PNwhen a macro calls another macro (not a goto), the second macro can do a .pop &1 to avoid returning to the caller. 2pd. O:!+-----------------------------------------+Some Randy Brandt commands snuck in here:+-----". The search is a PN"contains" search, not an equal search. Also, start and end specify the range MKof string variables to search through. If a string is found, its number is Lreturned in X. X=0 means failure. You cannot search $0 using this comman.NewFile "New WP file",1 : // New WP file3.NewFile "New SS file",3 :// New SS file msg z>!----------------------------- x = .search "ishere",start,endNLThis command will search the string variables for "ishere? Well, it handles PNthe actions with or wit"hout display and ExpertMode leaving AppleWorks in the same state as you left it.LJWith a DB file, you still need to specify category names. Your macro will have to take care of that. N:!-----------------------------.NewFile "FileName",typeOMThis command creates a new file, giving it the name "FileName" as speficied. 2The type indicates which type of file to create: next a:.spacebar:restscr:>!-----------------------------$$1 = .fdate2 month,day,year,formatOMThis command works like .fdate except that you can specify a date. Note that Year needs to be 1992, not 92.AF:!-----------------------------x = .weekday month,day,yearIGReturns a value (1=Sun,2=Mon...7=Sat) indicating the day of week for a NLspecified date. Again, year has to be a full year (1992), not just the last two numbers."W: if R = 1GThe files don't have to have the same number of categories or the same ECcategory names, but there needs to be a one-to-one relationship in IGthat category one has to match category one, category two has to match category two, etc.FDThe purpo !"#$%&'oa-q find rtn .getrec 1,r(1),s(1),num #DB Record Compare by Randy BrandtCAThis macro will examine corresponding records from two files and FDdisplay six categories at a time, highlighting categories which are not identical.IAO=====<====<====<====<====<====<====<====<====<====<====<====<====<====<====<===@O=====<====<====<====<====<====<====<====<====<====<====<====<====<====<====<=== print i : spc : print j : spc// print variable valuesInext j : rtn// Return after inner loopFnext i>!// close the outer loopinner loop going down by 200's. It 9doesn't do much, but it does illustrate how this works.startf:else : if R = 6 then $7 = "Friday":{ Friday }@else : if R = 7 then $7 = "Saturday":{ Saturday }endif :'msg "Mark was born on a " + $7>! then $7 = "Sunday" : { Sunday }>else : if R = 2 then $7 = "Monday" : { Monday }?else : if R = 3 then $7 = "Tuesday" : { Tuesday }Aelse : if R = 4 then $7 = "Wednesday" : { Wednesday }@else : if Rse is to find out what changes have been made in the newer IGversion of the file, or perhaps to help you determine which record has Ethe newer data. That, and it was a fun little programming exercise.labels .comparedb#findfile=sa-f#getrec=sa-gstart3:!//back to normalBa: 42 then n(9) = 42 endif//no room for most DDD c(9) = peekword #dbrecs//how many recordsdisplay #on>!Bg:!f: 60 then y = 1 : endif :,ifnot y > num then k = y endthen goto sa-s endif//current record7T = 1 : if z = 139 then T = 0 - 1 : endif :=rec = rec + T : if rec = 0 then rec = 1 : endif :+if rec > c then rec = c endif :goto sa-c>!// z " + &J& + " or " +&K& +?// " for other categories; " + &M& + " for the next record ":/if z = 0 or Z = 209 or Z = 155 then3 oa-q display #on esc stop endif :/ifnot z = 13 or z = 139 or z = 138 =ame2.writestr 17,V,$(A) : V = V + 1 :2.writestr 17,V,$(B) : V = V + 2 :next i :2.msay "Other categories: " + &J K & +5 "Change records: " + &A-J A-K M & :&//.msay "Use>" : endif :(ifnot $(A) = $(B) then :$(A) = %J% + $(A) + %K%//invert:$(B) = %J% + $(B) + %K%//invertendif7.writestr 2,V,$3//category n str$ i : if i < 10 then $3 = " " + $3 :-$3 = $3 + "-" + .catname i :3$3 = left $3, 13 : $3 = $3 + ":" :=if $(A) = "" then $(A) = "" : endif :=if $(B) = "" then $(B) = " num then j = num : endif :&.titlebox 0,1,77,19,1,$6 :=.writestr 2,2,%J% + 'Record:' + str$ R(1) + %K% :for i = k to j :6A = S(1) + i - 1 : B = S(2) + i - 1 :=$3 =c : R(2) = Rec :$ display #off :#getrec :#F = 3 - F : $0 = $(F) :1oa-q find rtn : #getrec : display #onk = 1 : goto sa-d>!0D:!?c: n(9) then n = n(9) : endif//lesser of the twoEif c > c(9) then c = c(9) : endif////categories per page9Rec = 1//first record to read.writestr 0,0,%A% :>.writestr 255,0,"Record Compare by Randy Brandt" :D$0 = $1 : F = 1 : #findfile: n = n(9)//open fnd right :rtn : goto sa-b>!-----(b: to <' + $2 + '>':=P = 6ta*else .getrec 1,r(2),s(2),num>!(AO=====<====<====<====<====<====<====<====<====<====<====<====<====<====<====<===@O=====<====<====<====<====<====<====<====<====<====<====<====<====<====<====<=== .setcat cat,rec,"setcat data" : oa-1>! ---------Bg:! find category nameFh:! find number of a category name------------------------| Spreadsheet commaegory " + :str$ cat + "= <" + $1 + "> Press a key" :x = key :Acat = cat + 1 : if cat > T then msg "" :stop : else :2 rpt>! f:! ---------;e:">!5d:! redraw the screen to display the new name-----6c:! display the ------------>a:! get current HThis file demonstrates the commands from I.UM.DB.AND.SS (see page 51).ELoad the files "Sample DB" and "Sample SS" to try out the commands.labels\sa-a demo .getnames\sa-b demo .setnands |------------------------H// since this is simply a conversion routine, it can be used anywhere,F// not just inside of a spreadsheet (not that it's useful elsewhere)5i:! // an AW stringMKj:! the work promptO then msg $10 + " not found." : bell stop else// not thereL$11 = " block" : if Z > 1 then $11 = $11 + "s" : endif// grammaticalMmsg $10 + " is " + str$ z + $11>!// display sizeN--------------------------------msg $2>!D// online returns Z = to the file size in blocks, or 0 if it failsMh:! works with screen off>e:! load path of current file@f:! try from within a TimeOut applicationEg:!N----------------------------------------------------------------------------C// get the last entry in a file; make it easy to test for the endCc:!// sets Z to r35678 .eof : msg "The last row/record/line is " + KThese are the dot commands from I.UM.DEFAULTS. See page 50 of the manual.labels.dot.defaultsstart(a:! duration, pitch3b:!=n:!:o:!abel since chr$ 34 enters a quote,2// forcing label mode. Skip it to enter numbers.Bl:!.// place the cursor on any cell and try sa-m6m:! chr$ 10 and 11 turn inverse on/offH// plugs the date into a cell as a lber and press sa-k8// for example, move to a "Goal Pct" cell in Sample SSFk:!F// put the cursor in any cell with a formatted num// a little wp trick messing with a poke into the AW zero page (techie stuff)Ak:!@l:! set default data pathBm:!// easy path change9n:!4// try this one in each application- wp, db and ss@o:!>@ABCDEFGHIJKLMNOPQRSTU.addmenu 40,13,$9 : // anywhere we jolly w _________________$| File Card menus |_______________%| |%| by Randy Brandt |%| |%| Commands by Randy BraBO=====<====<====<===<=====<====<====<====<====<====<====<====<====<====<====<===@O=====<====<====<===<=====<====<====<====<====<====<====<====<====<====<====<===$0 = "You picked item " + str$ Z : endif.cls 1 : oa-q : msg $0>!ld hard-code the values to 4// save space in your file and in the macro table:D// .makemenu 24,10,51,3,2,1// same result as previous .makemenu#// result is always returned in Z9if z = 0 or z > 30 then $0 = "You Escaped." else :9inner box0.writestr 29,6,$50// display title0.line 22,7,30,#'_'// dividing line// create the menu itself@.makemenu Lefty,Top,FirstStr,Count,Spacing,Initial :E// of course, in a tested macro, you coupacing = 2// double space the menuAInitial = 1// initial menu item to highlight;.cls 1// clear most of the screen,.box 19,3,34,15,1// outer box,.box 21,4,30,13,1// efty = 24// left column (the word "left" is reserved)3Top = 10// top line of menu>FirstStr = 51// first string in menu is $519Count = 3// there are 3 menu items8Srt9a:.loadvar "test.variables",255 : // load eve $2,#'*',0 : //strip both ends#msg $1 : x = key : msg "">!8Q:.savevar "test.variables" : // save them in a file8clear 255 : // zap" :msg $2 : x = key :8$1 = .stripchar $2,#'*',2 : //strip end#msg $1 : x = key ::$1 = .stripchar $2,#'*',1 : //strip start#msg $1 : x = key :>$1 = .stripcharhis file is for demonstrating all of the dot commands foundC// in I.UM.MENUTOOLS, so we'll get a few out of the way here that?// have nothing to do with actual menus as far as we can tell>o:! just in case someone makes this into a task file4--- this is the startup message, full of MouseTextJ]:!A// ttem1.1=ba-1#item1.2=ba-2#item1.3=ba-3#mainmenu=sa-m#menu1.1=sa-x#menu2.1=sa-y#menu3.1=sa-ctrl-a#menu3.2=sa-ctrl-b#help2=sa-h#help3=ba-hstartE've got lots of labels to make our source easier to readlabels .dot.menus#setup=sa-s#doit=sa-f#lastkey=peek #key#item0.1=sa-1#item0.2=sa-2#item0.3=sa-3#item0.4=sa-4#ird not OMto worry about the Escape map at all. That way everything works the way it's OMsupposed to- the .popmap backs up, and then .filecard redraws the prior card Husing the prior heading. Do a find for **fc** to see this in the code.?// we title and return to OMthe prior one. If .filecard behaves normally though, it will add a new title NL(actually the same one) and the top will be "SAMPLE Escape: Sample" which OMis not what we want. By adding 128 to the card number, we tell .filecacard one is drawn with that title.MKThis is great except when we're backing up from a higher numbered card. If NLthe menu is on card 2 and the user presses Escape to get back to card 1, we PNhave to back up using a .popmap to get rid of the currentcards made MKfamous by AppleWorks. The routine which draws the card titles it using the NLEscape map heading at the top of the screen. When you use a command such as PN.filecard "Sample",1 the string SAMPLE is placed at the top of the screen and $rawn, and -then reset the poke after drawing the card:;Ex. poke $c3d,0 : .filecard "Lonely card",2 : poke $c3d,1A Quick Tutorial on .filecard-----------------------------OM.filecard is a special dot command making it easy to draw the fileorget that you can't use to run an macro; you have to use or to run them.NLTip: To draw a card from 2 thru 4 by itself, precede the ".FileCard" with a PNspecial poke to cancel the "edges" of the prior cards from getting d---------PNFirst print this file and then follow the macro logic as you step through the Lmenu choices on screen. This is the best way to learn how this mess works.NLI made most of the macros so they couldn't be run accidentally. Don't PNfrything4.writestr 255,11,"Z(8) = " + str$ Z(8) :3.writestr 255,13,"$69 = (" + $69 + ")":=.say "Press a key for the Main Menu" : oa-q esc>!-------------------------// MENU stuff starts here-------------------------#<#doit>::! ------------------------------- third choice on first card6<#item0.3>: 0 then sa-] : stop>! enter selected file and quit ---------------------------- second choice on first card#<#item0.2>::! ------------------------------#- third choice on the second card9<#item1.3>:! ----------------------------------------------------#- second choice on the third card&<#menu3.2>:! ------------------------------$- second choice on the second card"{ display a message on the card; all Mousetext characters }5.writestr 255,14,&A B C D E F G H I J K L M& :6.writestr 255, 16,&N O P Q R S T U V W X Y Z& :C.spacebar: .popmenu>! back up after user hits space bar --------if z = 1 then #menu3.1 rpt else+if z = 2 then #menu3.2 rpt else.popmenu>! ------------------------------G- this is the macro we run if item one from the third card was chosen%<#menu3.1>::! $1 from the previous menuH#menu1.1 :// make another menu on card 2)if z = 0 then z = #lastkey : endif;if z = #"Q" then oa-q stop else :// exit with OA-Q<if z = #"?" then #help2 rpt else :// u,12,"You want help?" .say "Dial 911">!-----------------------------G- this is the macro we run if item one from the first card was chosen<#item0.1>:!<#item0.4>:! x, y, first $, count, spacing, begin item ------------------------------5- this macro does the second card menu for item one<#menu1.1>:!C : .spacebar :us colorsckgr*Compile and press SA-Esc for macro menu.labels .iigs.cmds\sa-eDemonstrate .extkb!\sa-gDemonstrate .getcolor!\sa-sDemonstrate .setcolor!\sa-tDemonstrate .timei@O=====<====<====<====<====<====<====<====<====<====<====<====<====<====<====<===@O=====<====<====<====<====<====<====<====<====<====<====<====<====<====<====<===next ":4$69 = "":>! ":4$64 = " This is another ":4$65 = " help screen! ":4$66 = " ":4$67 = " ":4$68 = "":,$50 = " ":4$60 = "":4$61 = " ":4$62 = " ":4$63 = " $44 = " This is a neat ":,$45 = " help screen! ":,$46 = " ":,$47 = " ":,$48 = " ":,$49 = "=<#setup>:!wait for a key and return to main menu--------------6// define a bunch of strings here and use them laterheck again: " + $91 :.writestr 27,13,&LLL& :.spacebar .popmenu>! ------------------------------ - here's our third help screen9<#help3>:::!n less here" :=.addmenu 8,10,$7 : // .addmenu lets us put itemsC.addmenu 15,13,$8 : // anywhere we jolly well want to.addmenu 40,13,$9 :.domenu 1>! ------------------------------'- thigsstart-----------------------------.extkbPNThe .extkb command sets Z to true or false to indicate if the latest keypress OMwas a IIgs keypad or extended key. Ultra automatically calls BA macros when PNyou press a keypad or extend^`abcdefghijklmnopqrsif Num > Hi then msg "Escape" : else msg NumCompile, then press SA-Esc.labels .mtools2\sa-aDemonstrate .askyn\sa-bDemonstrate .box!\sa-cDemonstrate .titlebox\sa-fDemonstrate .fcard!\sa-gDemonstrBO=====<====<====<====<====<====<====<====<====<====<====<====<====<====<====<===@ O=====<====<====<====<====<====<====<====<====<====<====<====<====<====<====<===5ifnot x = 27 then//check for Escaperpt else :// clean things up again0display #off : oa-q : display #on : rtn :>poke $11ac,27>! restore Esc for stopping runaway macrosro"//top message beginJ$1 = .timegs 1 : $2 = .timegs 2//grab time with secondsH.writestr 255,0, $1 + & [ & + $2//display both formats:x = peek $c000//peek the key locationН-----------------------------$1 = .TimeIIgs 1The .timeiigs command=// Format- 1:time only; 2:AM/PM if Control Panel set for it@t:!lor command allows you to change the border, background and text colors on a IIgs.Cs:!-----------------------------.setcolor What,ColorMKThe .setcotop> so that F1 always goes to the Main Menu.-----------------------------X = .getcolor WhatKIThe .getcolor command allows you to read the border, background and text colors on a IIgs.0g:!HFYou can make the function keys go run another macro, so that they are OMcompletely independent of their keystroke equivalents. For example, we could Nhave this one do an !-This example requires an extended keyboard:J::else msg "Both-Apple-Return"//three keys ate .getinput"\sa-hDemonstrate .getstring!\sa-iDemonstrate .getvalue$\sa-kDemonstrate .list w/.box\sa-lDemonstrate .list!\sa-mDemonstrate .menuitem \sa-nDemonstrate .ongosub\sa-oDemonstrate .ongotorestscr: first:"if Z > 0 and Z < 155 then :4msg "If you didn't lie, your name is " + $1 :else msg Z>!-----------------------------+$1 = .GetString "Prompt","Default",MaxLenGEThis command is a mix between th this =command, you can set up your own input forms if you'd like.A// returns Z = 0:Esc, 155=OA-Esc, 209=OA-Q, or length of string G:!-----------------------------.ue :,.fCard 1,"Card #1",MText: .spacebar :,.fCard 2,"Card #2",MText: .spacebar :,.fCard 3,"Card #3",MText: .spacebar :!.fCard 4,"Card #4",MText: ,.Say "And back up without Mousetext":MText = #False :card example in HFthe Dot MenuTools file for more ideas. Two main differences: this one CAhas cards that look different, and it doesn't need to do an OA-Q )first, like the .filecard command does.F:!-------- screen>.titlebox 30,3,40,5,1,"This box has an inverse title" :4.writeStr 38,7,"Stuff something in the box" :.spacebar :<.titlebox 30,3,40,5,2,"This box has a normal title" :4.writeStr 38,7,"Stuff something in t-----------------------------.titlebox X,Y,W,L,T,titleFDThis command will draw a box starting at X,Y with a given Width and /number of Lines, using a title specifed by T. c:!nd DBnumber of Lines. If mTxt = 0, then a plain (non-mousetext) box is ,drawn, otherwise a mousetext box is drawn. b:!-----------------------------.Box X,Y,W,L,mTxtFDThis command will draw a box starting at X,Y with a given Width a\sa-pDemonstrate .pick\sa-tDemonstrate .therm#\sa-uDemonstrate .macronamesstart-----------------------------.askyn "prompt"HFThis returns consistent results no matter how a user may have patched their Ye.GetInput and the UltraMacros DBcommand. With it, you can specify the Prompt for the user and the GEDefault String as well as the maximum length. It is always displayed on the bottom of the screen.A// returns Z = 0:Esc, 155=OA-Esc, 209=OA-Q, or length of string H: 0 and Z < 155 then :7msg ' You came into this world on ' + $1 + ' ' :else msg Z>!IGWhen you're in theA-D.HFn:! comes back to msg-----------------------------.ongoto val,"ABCDEFGHIJK"IGThis command is identical to .ongosub except that it does not call the 9macrohat follows which contains a list of macro FDnames. Lower case represents SA macros, and upper case indicates BA Gmacros. Non-alphabetic macros are run by adding 128 to the character.DIf val = 4, then the command would call the macro SA-D, if 5 Bifnot x = 27 then print chr$ x// check for Escaperpt else msg "">!-----------------------------.ongosub val,"abcdDefghijk"GEThis command lets you call another macro based on a value. val is an DBindex into the string tm.M: Cursor through the menu; Esc to quit <--" : x = key : begin@$1 = .menuitem : msg $1// echo menu itemAx = key// get another keyB1,5,20,7,1,30,"30 Item List":2if z = 0 or z > 30 then msg str$ z : else :)msg "You picked Item #" + str$ z>!-----------------------------$1 = .MenuItemGThis command reads the current menu item from any numbered menu ite box or savescrrestscr2if z = 0 or z > 30 then msg str$ Z : else :)msg "You picked Item #" + str$ z>!L: Hi then msg str$ Z : else msg Num>!-----------------------------!.List X,Y,W,L,Start,End,"Title"IGThis command displays a scrollina default number and allow a IGnumber to be entered between 0 and 65534 as limited by min and max. If <the user exits via Escape, 65535 is returned and Z is set.A// returns Z = 0:Esc, 155=OA-Esc, 209=OA-Q, or length of string"I:oa-y : print $10 : rtn//plug it in:goto ba-h>!//repeat-----------------------------(X = .GetValue "Prompt",min,max,defaultFDThis command will prompt the user with Enter for 2a null category, and use OA-Q to stop the macro.@: command @>is used to define a category. Since .getstring, .getinput and F.getvalue all use the same , that can cause a few problems. HFHere's a macro by Jim Parker which works around that. Press as a subroutine, rather it does a goto MACRONAME.Bo:! msg won't be shown-----------------------------&$1 = .pick X,Y,W,L,Start,End,"Title"IGThis command displays a scrolling list with strings specified by Start HFand End. X,Y,W,L specify the X,Y position on the screen for the upper IGleft corner, the Width of the box (in char) and the # of Lines for the Astring display area). The title is drawn at the top of the box.0Limits: You can'pacebar : .dropdir :2oa-q>! drop down a step at a time------------------------.line Horiz,Vert,Length,Char=;The .line command draws a horizontal line at the specified IGcoordinates, using the specified character. If you se!\sa-wDemonstrate .menubar2start------------------------ .dropdirEThis command drops the last subdirectory from the current pathname./d:.spacebar : .dropdir : .snstrate .peekwordzp"\sa-rDemonstrate .rightmost\sa-sDemonstrate .setcol \ba-sDemonstrate .subchar \sa-tDemonstrate .toinmem \sa-uDemonstrate .uncache\sa-vDemonstrate .vline \sa-zDemonstrate .zapchartvwxyz{|}~lumn,Width---- main memory.zp except that it labels.stuff \sa-dDemonstrate .dropdir\sa-lDemonstrate .line\sa-mDemonstrate .msay \sa-nDemonstrate .peekvar \sa-oDemonstrate .pokevar#\sa-pDemoxAO=====<====<====<====<====<====<====<====<====<====<====<====<====<====<====<===@O=====<====<====<====<====<====<====<====<====<====<====<====<====<====<====<===.setcol Cohat macro. To use it yourself, it MUST FDbe followed by a goto command. The command will plug in the name of "the macro that the user selects.>U:!.therm 5,10,A,10 : next a :.spacebar : restscr>!-----------------------------.macronames : goto sa-aCAThis is the "live" SA-Esc command which displays a list of macro IGtitles. Choosing an entry runs tMax value. B@If Current <> 0, then the thermometer is updated to reflect the current position.T:!-----------------------------.Therm X,Y,Current,MaxGEThis command will draw a thermometer. If Current = 0, then an empty HFthermometer is drawn at X,Y and it is initialized with the 0 = .pick 41,5,20,7,1,30,"30 Item List":restscr:x = len $40:,if x = 0 then msg str$ Z :stop:endif:$2 = "You picked " :for i = 1 to z :$1 = mid $40,i,1: x = asc $1:  $2 =ing macro demonstrates how to use this command:G// returns Z = 0:Esc, 155=OA-Esc, 209=OA-Q, or number of picked items P:!------------------------.msay StringIG.msay is demo'd in the "Compare" file. It is like .say, except that it FDdoesn't save or restore the bottom line, making it useful inside of B@loops since the screen would flicker if .say was used, since it FDrestores the b : exit else : print chr$ a : rpt>!-----------------------------6.uncache "macroset"//uncache the named macro set>.uncache "*"//uncache all macro sets in the cache?.uncache "#"//uncache all sets EXCEPT ro value IGif the highlighted application has been loaded into memory or 0 if the application is still on disk.t:!//display the strings------------------------x = .toinmemHFThis command is used at the TimeOut menu. It returns a non-zeer. The ASCII values are used, but the compiler can convert Ftext characters for you so you don't have to know the number values.C:!------------------------2$1 = .subchar Text, FirstChar, LastChar, NewCharIGThe .subchar command replaces a range of characters with the specified IGnew charactr is ECscrambled, but slots always start at one and count up from left to right.>r:!// try in any application------------------------.setcol Column,WidthECThe .setcol command changes the width of the position on the current word processor IGline, or the last column on the screen in the data base. A column is a GE"slot" which is independent of the actual category contained in that GEslot. That is, you can rearrange the layout so the category ordestead of one. The values are stored in main memory..// no meaningful example yet; maybe some day------------------------x = .rightmostIGThis command returns the rightmost spreadsheet column containing data, DBthe last allowed character To ;peek main zero page bytes, just use plain old .&p:!------------------------.pokewordzp Address,ValueIG.pokewordzp works just like .pokezp except that it stores two bytes in >memory in2) = $abcd : e(2) = 9 :.pokevar $400,C(2),2,1>!------------------------x = .peekwordzp AddressFDThis command is used to peek a pair of bytes in auxiliary zero page ECmemory. If you don't know what that means, ignore this command.(2) >!------------------------#.pokevar Address,Start,Count,SizeCAThe .pokevar works just like .peekvar, except that it stores the ?=variable values in memory instead of reading memory into the variables.4o:! leaves message on bottom line------------------------#.peekvar Address,Start,Count,SizeB@The .peekvar command um4.0.systemHFUltra 4 caches macro sets whenever you use launch, call or link. This HFprovides maximum speed for switching, but ties up memory which may be GEbetter used for other things. The .uncache command removes the named HFmacro set from the cache, freeing up the memory. .uncache returns the number of files uncached in Z.<U:!------------------------ .vline Xpos, Ypos, Count, CharHFThe .vline command allows you to dreveral commands in GEthe macro at key places. That way you can examine the variables, and CAuse oa-v to examine the screen, so that you know exactly what is CAhappening as the macro progresses. When you press Escape to exit IGDebug, the macghtly different names. Your default set stored ECin UM4.0.SYSTEM should be named "um4.0.system" to avoid confusion, Esince that's what it will be called once it's saved as the default.Debug-----FDIf a macro is giving you trouble, place sefinition.FDUse the labels feature to name all of your macro sets. That way you FDwon't need to type the name when creating task files, and you won't GEhave to worry about making typing mistakes and creating two versions HFof a task file with slial is to write DBtrue TAPL (The Appleworks Programming Language) programs that are 3readable, commented and modifiable in the future.HFUnfortunately, you may not nest labels. That is, a user-defined label 2may not be used within another label dra series in NAUG's Forum. U4 Compiler -----------GEMake regular use of the new labels feature to make your source files =;readable. Ultra 4 is not designed for recording macros and ECdecompiling, although that does work. The primary go October 3, 1993To Learn More-------------IGWill Nelken taught an Ultra 4 course in the GEnie University. The same IGseries also ran in TimeOut-Central. Randy Brandt wrote a monthly Ult@O=====<====<====<====<====<====<====<====<====<====<====<====<====<====<====<===@O=====<====<====<====<====<====<====<====<====<====<====<====<====<====<====<===s identical to .menubar except that you specify 4the delimiter character following the two strings.Cw:!s is handy for stripping commas from numbers so the extended math commands work.Cz:!------------------------(.MenuBar2 "Prompt","Choices",DelimiterIGThe .menubar2 command iCol//next column8next Text//next character.spacebar : esc>!------------------------.ZapChar "Text", CharFDThe .zapchar command removes the specified character from a string. GEThiaw a vertical line anywhere on the screen using any character. v:s that are supposed @to match at the start like with the earlier versions of Ultra.----------GESpreadsheet find: The "live find" feature in the spreadsheet is even FDmore limited than the manual mentions. If two consecutive cells are DBidentical, will stop on the second one. To keep searching, *press the down arrow followTEM.FDThe task file will still work on other user's Apples if it's in the IGAppleWorks directory, since it checks the current directory first, and Fif that fails, looks where Ultra was when the task file was created.Find Change Page 18 -leWorks startup directory and ?=still find AppleWorks. For example, if your AppleWorks is in HF"/HD/APPLEWORKS" you could create a task file in "/HD/TASKS" and when ECit is launched from a program selector or Basic, it will still run APLWORKS.SYShis problem on ROM 3 IIgs's.======================Ultra 4.2 Manual Notes======================Task Files Page 8, 43 ----------@>A new Ultra 4 feature allows task files to be launched from a DBdirectory or disk other than the App is finished.ts, and use to  Mouse Fixer -----------DBSometimes the mouse will lock up in GSOS applications after 8-bit IGprograms such as Ultra 4 have used the mouse. See the file "MouseFixer 7Docs" for a solution to tH@O=====<====<====<====<====<====<====<====<====<====<====<====<====<====<====<===@O=====<====<====<====<====<====<====<====<====<====<====<====<====<====<====<===SuperFontsP(1) = 66//define variable with string numB oa-9//avoid overwriting other stuff/ (print $(P(1))) 3//hat trick!5 msg "The best hockey player in the world!">!ny Parentheses?---------------------HFTRIVIA: The highest number of consecutive legal parentheses in a TAPL @program is three, as in the third line of the following macro:start4a: poke $11ac,27>! restore Esc for stopping runaway macrose key location }>msg ' ' + $1 + str$ x + ' ' : { show last key pressed }%ifnot x = 27 then a = a + 1 :1oa-1 : print a : rpt : { keep going }Gelse{ Esc isn't aborting the macro, just passing control }1p Esc from aborting the macro }?insert : oa-e { strikeover cursor for our display }>$1 = 'Press any key (Escape to stop) Last key: ' :2a = 0 : { initialize a counter } begin2x = peek $c000 : { peek thating a counter while you press any HFkey you'd like. It will display the key value on the message line and HFkeep going until you press Escape, at which time it will clean up the display, beep and stop.start=a: because it does nothing until a key is pressed.FDThe answer is simple- just check for the key with a peek, accessing +the Apple II key input location directly.GEThe following macro will keep upd ECWhat do you do when you want a macro to keep running unless a user ECpresses a certain key? Or maybe you want the macro to do something GEdifferent when a key is pressed, but you don't want it wthe commas, you'd get false HFmatches on numbers like 1990 if you were just searching for 19 or 90. EBecause of this, search categories must begin and end with a comma.0Sample category entry: ,1960,1880,17,1776,196,IGOf course, if you just want a generic search macro, you can remove the >automatic comma addition code near the beginning of macro S.GECompile and press SA-A to try it out. Press Return or Escape to exit IGthe macro. Until then it will keep prompting you for another number"call" :$2 = "jsr" :#replace  DBThis Ultra program attempts to simplify the process of converting GEUltra 3.x files to the new format. Compile and press SA-C to convert ?=many of the commands. Read the rest of this file for ti@O=====<====<====<====<====<====<====<====<====<====<====<====<====<====<====<===@O=====<====<====<====<====<====<====<====<====<====<====<====<====<====<====<===$1 = r look for another number- #FirstStr + #FirstCat//where was it found?A$3 = .catname #FoundCat//grab the name0 msg ' Category "' + $3 + '" contains "' +1 $1 + '" in record ' + str$ R + ' ' :9goto sa-s>!// let usend. '//announce failure,Cbell : goto sa-s>!// then try againH----------------------------------------------------------------------(// found something, so tell user wheref: 0 then goto sa-F else//we found sumpinEnext S//try next categoryC next R //try next recordEmsg ' "' + $1 + '" was not fouith dataA for Rec = #FirstRec to #LastRec//range to scanA .getrec #FirstCat,Rec,#FirstStr,#Count//grab a record$for S = #FirstStr to #LastStrHPos = .substring $2,$(S),1//scan category fo + $1 + ","// commas avoid false finds for short stringsC#Count = #LastCat - #FirstCat + 1 //how many categories?@#LastRec = peekword #dbrecs //how many records?D#LastStr = #FirstStr + #Count - 1 //last string w----------------------------------------0s:!//get startedH------------------------------//found itGelse .setdisk "/extras/ultramacros"//failed, so try disk9esc rtn rtn//go to Add files=if z = 0 then bell stop else//should never happen exit@rptis first macro checks for the desired file on the desktop, and if #it's not found, gets it from disk2a: should be converted istsPts Goal PctWFVasquez, Benny @ @,@?VDBrandt, Randy @ @(@?XFEdmunston, Dave @ @(@b'vb'v?W FLametti, Gerry *@ $@7@! YB?V DBrandt, Randy @ *@4@ffffff? 1993 Summer League)PosGoalsAss$@?UD Polter, Marc @ @$@?1992-93 Hockey Stats)PosGoalsAssistsPts Goal PctZ FNeitenbach, Bryan .@ &@:@1991-92 Hockey Stats)PosGoalsAssistsPts Goal PctWFLametti, Gerry @ @$@?VDBrandt, Randy @ @ CM1 NJ  NJP nSindex"' :$2 = ".cls 1 oa-q" :#replace : >!1// subroutine to replace all $1 matches with $2;<#replace>:!9$1 = "cls" :$2 = ".cls 1" :#replace :9$1 = "call" :$2 = "jsr" :#replace :9$1 = "clear" :$2 = "clear 255" :#replace :9$1 = '& "space"' :$2 = ".spacebar" :#replace :9$1 = '& "o normalc::!//back thile a macro is 6running, see the file "Key Test Macro" on this disk.ECDue to formatting variations, we can't automate some commands, but this will help you do the job:1Replace:& "y/n" : & "Do you like Ultra 4.0" :3with:.menubar "The easiest way to convert your variables Gis to use the variable set number for your array number. For example:/Replace:b = 5 : putvar 1 : getvar 8 : c = 1with:b(1) = 5 : c(8) = 1ECFor an type method for checking for a key wusing the GE, , and commands, as menus are ?now completely different. See "Dot MenuTools" for an example.HFNow that Ultra has 260 numeric and 100 string variables, and HF have been dropped. ?DD/  FirsttNameLaststameStreetCitytyStateeZipZipPhoneeDD/      1 John SmithBob's Automotive1124th5th6th7th Susan Jones ABC Rentals145Bill DoeBob's Automotive158Jane Doe ABC Rentals220Koy RoeTy's Fishworks166   rbNamegory 1TeamAverageFourth  ;Y BFifthǀ Ӄ8{Sixth;|<| ߁SeventhLT`%Read anDD/     rb2 John SmithBill and Ted's Automotive1124567" Sue Jones ABC Rentals145howdyBill DoeBob's Automotive158@Jane Doe ABC Rentals215,1960,1972,1979,,1983,1985,1987,82,>Shad RoeTy's Fishworks178,1966,1976,1982,,1991,1993,19,Namegory 1TeamAverageFourth  ;Y BFifthǀ Ӄ8{Sixth;|<| ߁SeventhLT`%Read an:John L.Weigh 23 Elm St.KenoshaWI11111(100) 555-1001ASusanKnight18 Bluebell Way CharlestonWV22222(100) 555-1002@ByronBlack9 Airport Blvd. TeeterboroNJ33333(100) 555-1003@RobinSmith13 Fertile CrescentPuebloCO44444(100) 555- be placed in auxiliary memory.MKZ is set to the size of the block. It's up to you, the programmer, to make Esure the Ptr is valid and the Dest is a safe place to load a block.NLThis macro just replicates the command, but it shows how .gehis command allows you to grab the desktop memory block specified by Ptr. KIThe block is moved to the Dest address. Flag determines the memory banks OMinvolved. If Flag is 1, the block will be placed in main memory, and if Flag 5is 2, the block willcomparison bits are true.ABresult- - ------ 100 000 010 111;a:ShawnFarrell2498 Coyote CynTucsonAZ88888(100)tptr and .getblock can be used.1test line for getblock example -><- TabsKg: 53247 then//not text, maybe a carriage return:msg "Non-text line"// or a printer option,8stop endif// so stop right here<Adr = $BB00//IOall the way up to the maximum value. Multiplications and JHdivisions are limited because of the need to maintain two decimal place accuracy.PNHere are the ranges. (The second columns have commas to make the numbers more PNreadable, but you can' other math which is beyond the *range of Ultra's normal 0-65535 limits. LJOne limitation is that the result of a multiplication or division can not LJexceed 214,748.36, at least if you want an accurate answer. Additions and MKsubtractions work mmands allow 26 special Ultra 4 variables to handle MKnumbers ranging from negative 21 million to positive 21 million with up to JHtwo decimal places. This allows you to calculate financial transactions OMwithout needing the spreadsheet, or to do anyPtr is not a valid memory pointer.===========================Extended Math RoutinesCopyright 1992 by Mark Munz===========================G(Modified by Randy Brandt after Mark's retirement from the Apple II.)JHThe extended math cow. Adr specifies the auxiliary memory address Fwhere Ptr is stored. This command could also be called .pokeauxword.------------------------.relblock PtrNLThis command releases a memory block back to the desktop. Death will result 'if ointer value. If 0 is returned, there was insufficient $desktop memory to store the block.------------------------.putptr Adr, PtrIGUse this command to store a memory pointer in an open AppleWorks file, NLmodifying a line, record or rock. MKThe block starts at Adr and is Size bytes long. Flag determines the memory OMbanks involved. If Flag is 1, the block will be stored from main memory, and ?if Flag is 2, the block will be stored from auxiliary memory.NLZ is set to the new p 6 leaves a remainder of " + str$ x>!------------------------.putblock Ptr,Adr,Size,FlagKIThis command allows you to store a block on the desktop using the memory OMpointer specified by Ptr. Use 0 for Ptr if you want to allocate a new blo,Convert a two-byte number to a hex string:?:!------------------------x = .mod a,b.This command returns the remainder of A / B.L:!------------------------X = .HexStr "$A"NConvert a hex string into a variable. Works with or without the leading "$".A:!------------------------Ptr = .getptr AdrNLUse this command to grab a memory pointer from an open AppleWorks file. Adr JHspecifies an auxiliary memory address where the pointer is stored. This Gcommand cgrab the wp lineB// without this next line, would lock up trying to display0// the control characters which represent tabsB$2 = .subchar $1,0,31,#' ' //replace all codes with spacesBmsg $2//display th Buffer for work area<.getblock Ptr,Adr,1//1 means normal GetBlockKz = z - 2//length of text is block length minus 2:poke $bb01,z//set the string length5$1 = .peekstr $bb01//t use commas in your macros. You must write the numbers 5as they appear in the first columns of each group.)BExtended VariablesNormal Ultra 4B--------------------------------?Lowest: -21474836.47-21,474,836.4700DHighest:21474836.47 21,474,836.476553565,535MKTechnical trivia: Ultra variables are two bytes, hence the range from 0 to OM$FFFF. Extended variables are four bytes, w variableM.xIntegers #False//treat Ultra vars as hundredths=.xMath " `A = 1 + A(1) "//`A is now 1.99Amsg "1 + A(1) = " + .xstr A//display the result>.xIntegers #True>!ble<.xMath " `A = 1 + A(1) "//`A is now 100Amsg "1 + A(1) = " + .xstr A>!//display the result2// treat Ultra variables as hundredths (pennies)Mj:!//restore the default setting------------------------.xIntegers #FalseOMThe .xIntegers command detlt value is 2 until .xFixed is used.Of: #xB then msg "`A:" + $3 + " > `B:" + $4 : elseCif #xA < #xB then msg "`A:" + $3 + " < `B:" + $4 : else>if #xA = #xB then msg "`A:" + $3 + " = `B:" + $4>!-----------.xmath " `B = " + $4//define BA#xA = .xcompare A//get comparison string A0#xB = .xcompare B // and B8// compare the numbers and indicate their relationshipB// use a label to represent theor `A: ","1", 12//get AD// we allow 12 characters so even -21012345.67 can be enteredH$4 = .getstring "Enter value for `B: ","2", 12//get BB.xmath " `A = " + $3//define A as extended var2rts extended variables into strings which allow PNyou to compare extended numbers using or statements and have the Nresults work correctly even when negative numbers and decimals are involved.Hc:!//define a very small number"Debug 2.2 and Extended Variables"--------------------------------JHPress OA-X from the Debug main scrith one bit reserved for the sign 9(pos or neg), hence the range is -7FFFFFFF to 7FFFFFFF.MKTwo commands do the majority of the extended variable work: .xMath handles IGthe math operations, and .xStr makes results displayable. All extended Jvar//restore default------------------------.xmath " `A = B + C * 3.25 "MKThe .xMath command handles all extended variable definitions by evaluating HFthe expression contained in the string which follows the command. The PNexpression must start with a definition, such as "`A=", and then you may add, NLsubtract, divide or multiply extended variables, regular Ultra variables or Mliteral values. Only one definition may be entered for each .xMath command.Nm:QCB8 é=<?>CB 8 à ``hhߚHH`LL0H `hhhhH嬠謠嬠謠䮠򠳮à젠Π򮠠䮠گ뮠y Ultra variable by 2.5Gmsg "`Z = 2.5 * X = " + .xstr Z//convert and displayA.xFixed 2>!//restore default settingnes how many decimal places, if any, are shown.Os: command KIused with normal variables. It converts an extended variable to a string 4which can then be displayed with or .LThe .xFixed setting determi//define a regular Ultra variableL.xMath " `C = 10.3 * C(2) "//add 10.3 to an Ultra variableOmsg "10.3 * 12 = " + .xstr C>! //convert `C to string and display------------------------$1 = 8L2C)pJJJJ IH(ȱH:=IH[H`@HcH  $ +  QRzL7Q c QH ` UUUU UUwUU K  mL7Q=C8 ` 鼕SS S阝S` K mSSef`SJR Q8 QUQ 7H L7Q K  m  Q` KS S! m I/H`JLNGȄBȄF aK  haaFF  mJm# KKJ UJ )J ۈ) ;J3ȱJFȱJGJKaȄM  aaNNJFLGJL L? &PRODOS `DaElH$?EGvѶK+`L HHLy XP LM ŠϠĠӠS)*+,+`F)) (*=GJFjJJA QE'+ '== `@ STSP8QSS8 m P o R(8RLnSOS BOOT 1.1 SOS.KERNEL SOS KRNLI/O ERRORFILE 'SOS.KERNEL' NOT FOUND%INVA Lf Lf8 U{ U  LfUz魼U U 턐Lf g ÍUUUUUUUUUUUUUUUUU Lf U }LfLf  xLfUUU | LfU_ *n*  x\UUUUUUUUULfL`U /FUU  腐Lf > LfLfX8 Lf LfU 腐LfLf Lf2RλUULfLZd ޠLfU PLe  DLf 6 C Lf0UU ;U) Lf LfU) ÍUÍU lss f0U U gLfUU  Ɇ ۆUhg  mgLfL]dLdU D\UegfgggRwU  ㄐLf8  َ  LfG qq8Lf HLfU }LfLf ēLfULff0UUhg UL8cULfUUUUUUUUUUUUUUUUUUUUUUigUjgUkgUlgU U Lf #U SLfLf xLfUUUU LfUUUUUU LraLf DLf 6TUξUU SLfLf WLfcg R RUUU  LfLcU1UUU  Lf  ĜLfU LfLf1RU ,Lf2RL|a2RU 'L|aULbUg ؃Lf N@Lf LUU2RUUUUoLcUU#dUgUcgUUUU` aI꽌ɪVɭ&Y&&Y& 꽌ɪ\8`&&꽌ɪɖ'*&%&,E'зЮ꽌  ͭЅ?0ȱ Ѕ?iȱi lԠԠ͠ԠϠŠͮŠ SYSTEM.APPLE   L$J) (jJJ>L+ "?I>  N `  hi !dLԡ憦  Ljmkm l y`2 Lԡ8(Je稽)ʈ@LPRO`L i=L\Ʃx ? N'iLID KERNEL FILE: xةw,@  ȱlmi8#)!) >dLԡm#i㰼m#iЕOLԡȱfgU #? : 2UUigUjgUkgUlgU  λUU2L`& 0 pf Kf ! m` ?BSC8 íS0BTBTT/T8SmTATȢSTT`@`ÍUTU &N.) $ UUUU  ` r8` S ؃L1s hTUBU Ӏ T?]B C Ü s t H   sLq hrS s ƦRȢT TR1R Lp  ֎Lp8 ֎. Lp 瀐LpU ݀Lp 瀐Lp ֎LpT $LpTT 瀐 _lUUJUnUjUUUn tn# m lii n` 8``S[AASS l(lUUUU mU*U8UUUiegfgݠLjUUU UU*UU U8LjU8UUU*n 䇩ÍU` 8` _lUUUU m l lLdk qmU Km mLdk)"U +n Km mLdkU)DU m ]m mLdkUU l` 8`U8LCiU <Uii iUUnUUn mU tn n` 8`UU)UUUNUnUUUUU`U<8 5lU'U UU*UU8UUcg R RLj 8`ULjLjLj8iU 5UЖ UЏ lLg lLgU ULhU zm mLhU zmLhU zmLhLZiU zm mT TU)U UU  mcg R RU UU*UmUUiUUiUU!U8UUUUUU UUUO`U U vLvU9UUOUUUU ݀ E8Lvw  v`8` UUUUUU 瀐 E8,UUUUUUULwUUUO`y UTz){JJJ {{{U)Sz8{={8|U 43LmxyLx {Lmx |_$Twwm{{{ {{w8Lmx |+BUC {{,(LwLpxLpxP% LpxSS/SU yK\ LpxZSz\뎇UU x' x"3 2yU`UU  Lބ3`8`UU  C`H)12)ͼh`h8` UUUU Lބ8 ф` UUUU Lބ8 `UUUU Ly8 j`UTUčU nLT)TT/TTTTȽTTTTChhC`zUzU` UU  Lބ3` <8` UU  LބC`UUOUU ݀`8UUUUUUU*UU*U \>8 íU/T(T/!TL]S S/SLx`SDUSDUTDUTDUDUEU`DUDU DU`HH UTUCU nL8CT)BTBT/CTU #/BTSCTȽSCTSBTChhC`HH h`Hh``Hh`0` 8 ԂS`  ԂS`U 0`8`=?C( ` ``UUS KT K mH ZCB =< ?`   ``Hڐ)۰h`ɺɰ8``HUUh`H UUh`H#UUh`H h`Hh`TUBU`TUÍU`TUÍU` UU`UU``` ` U ݀`H c UH m {h(`UUULJULJUULJ ULJULJUUULJUUULJULJULJULJULJULJULJULJULJULJULJULJLJS K+  mSHU KU"U$ȱ% mU:U;ȱ<U)UUSmUUʱ ɠ S Shhh`UU S L3 ){ |_ z t9 DUUUU歊UU Ti?L~S= CB  K mH 9` K  mSU` K!  mUU ٩U`#UUU`HHLz} < K ! mU` /]6890U){ |_ zzz K8#6 8#9!z'z( m8k3c KU$U% mL~8L~UUL~SRS ؃RS Kz${% mL} : KU$Uzh _| {` Ȋ8j`h8``{ |` | |``8{  `{{ ϭ8`{{` ͚L ULX~ =7Y h 쁩UU x" ULX}U hh{{`BFG{C {{,(`l{Hh`{ {` | { { {`z){z)nzjz` {{zzzjz8iH{ zzz |zz |h _| {RH |z |z |z |` x |S ȽS)SȭȩÑȩ'ȩ ' z)zȊz{ {`{U 6 d0UU)/ UU`Sz>{JJJ{ {{{ |Hȱh `{+8 H|'z0ȩ4#ȩȩ yUx  y`D#ȑȩȑ|ȑ` xx𪬺xȭx κxxȭx `Tz{){QzRz{{12)͊{(8#2)Sz x Uz { {QzRz ၠ\DU  ~`cgg\gUcgLlH UUU h LUU!UUU L)U KU& mU- TL 9̭Ux eUпn K  mU` K:)@ " m 9!U eUU K !! K!  m`U K!  mU`΢U8i#i ! .cg .cg## 토iLՔ ᔰ U Li 4ii  LՔ  `i  L`"`8`O` `!```U UU7 >sU)U edUV` UU#cgUUUUUU ݀LcgUUUU UUU UUUO` <8` UUULLUUO# ` <8` .$  `UUU#`UU 瀐LK`UɅi8`UU ၠiUU 瀰UUUU` <8`+ , - . U  T T  U U U U ``!8"mUUiz8z !+mU-,mU .`UV 8` 8`z"z!& &BiߥiLȱ" ߈!ՠ!ȱ"ȱ#ȱ$Lґ`U U`8` ၭi iUUU ݀U UUU ` <8`izzjM bi ii8Li𐳥iL`UV7% / )#$%$U $U $U $UFLΉU ݀vFG8ΉU ݀XF) $C* $6' $)( $ $ $F`8`U U ݀` F 8i񩀍F` Rҭ RU8!U L荭U!O8 R R0. R R#O Rǭ R8``#` UFUU ݀L ၠ G$DU $LEU DULLGi̭F $LF UUDU  <8LyU8UzUU{` 䇭UUUUUU rpU/ mU T 䇀/fg Dgg 䇭fg Ɂcg UU UUUUUUUU ` <8`U RU RU Ɂ rU+ ŎUU !TȢTTT`U KU TCBB TCÅB mH  =< ?>8 íUT!T/TLBT BT/BTL`T=B CB  K mH `!BTDUCT)EUBT+CT/DULOTDUT)EUT T/DU`͟8퟊(RRRmcgcg8RR RmRiR` ` `` `O8#J` h 1L hS%BT/CTSmBTBTBTȢSCTBT` dT%T/TTmTTU ؋L_`U ɀ UUU LM8`RR UA U OH HhȩȩUh`ii8`8`UU mme`e` | UU ` LU_ULU"8%080UUU ݀L ၩeiUUUUU L K& mS L28 K! mU`΢UΤU UUUei`8`U UUUU UUUUUU `L8`UU `U  쁩UU x`r=?Cօ8  Q S K! m`H 1ȹ1)ךLNUU U)L>&U%UUL$UUU#U ΥUΦUL b L4UUUUU b LN L")U KU&:"!  m` K!  mU ͚` < ͚ K  m ͚ < K!  m`U` K!  mU`hhUHHHHH`hhhhhUHH` ee`  S S `8` U`  U '7J UTUCU nCT)BT%LNUL7SCTSBTCTBT RR1R L1R L RR)RR RLi EU 󈈌RLRi#оRЋ8˦hh˦R`HHRRRRRRRHRhURR1R 'L1R LRRRȱRLRUU/R0RR0 #/R0R Y8L/R0R R8m/R/R0Ri0Rhh`HH1R ܧhhܧ`HH1R hh` HH m  m  ͆U ͉U͊U x) + ') + &д_ +`FG8`0($ p,&" (0 8@ HPX !"#$`h%&px')*+,-./12345679:;<> 꽌ɪ\8`&&꽌ɪɵ'*&%&,E'зЮ꽌ɪФ`2JJJ'J&J>Ƚ3JJJJ&'J&&3>ȽfJJJJ&'J&&f>ȥ&)>ȥ')̻>JJJ >`*xY+&x'8*BIxix&&  *)f>)JJJ`80|'x&Hh & 󸩪 󸩭 󸘠Y'&Yxꪽ' 󸩪 󸽎`Hh` aI꽌ɪ򠚽ɭ&Y&&Y&<L淭  ؃L޷ L޷U )=U L޷U  1R # +L跬Rȱ)Lѷ R1R  &JJJȱ>'JJJ3ȱ>*JJJfȱ>J&*J&'J&&ȱ>J&*J&'J̻&*)')3݌`8`0($ p,&">֠LԮ@ ˵L+@ Kҥҭ?BC8 + +Hh@ <ԥBGKPUֶڶ ``8 δ( :: ȱ ELyi%{ "ٴ D  `             ` δ ȱ "{ E`Z " ȀzI뵩ꍫ H H m sh` S\nv /?amg     `ķ`L̷L̷ 'ȹ'{ȱ%ȱȱȱ.$50xLJJJJ`HHjf5 bh $50x` Hh݌(` 66 ľDULݾiDU   DU! ` `DU