' JJJJ ?\>',=l>  JJJJ!xHH<>BC=?L,L=LLLW LL* L_ L L L Lc`\_ [ {}~|`{}~|ح! )i ɶLhh捠 W LiHH`,` a $(H (G h$(IL]  8` a ƀ餁L]   思 L  G L G L  L L  L4  :L Lʩ L a y LDFG` )  L 6  H ɓ, h H h %2$($` $L| L  $` "%$L"LX  y $)` I L5H  Ih5`a{)`#`$` I $  o  8` ` & `  慥) 8` I _ 0 膆8` I H h톉ߥ N `  8`  `   ) `  ` NHh  L~ N s w  N 8`` s  w H hi`8`i`HJJh )`N`ɄNHNh` c SCRAMBLED DIRECTORYLe o ɄԝN`8``  iL   iL H  h s O c CANNOT READL H  h s * $ c BAD OR UNFORMATTEDL l !` c WRITE-PROTECTED c DISK; cESC TO ABORT SPACE TO IGNORE, RETURN TO RE-TRY:   L c ` m ) !) `)P)@ xLA `BU,>J>VJ>V`8'x0|&HhHh VY)'&Y)xꪽ)' `Hh`V0^*^*>&` cI꽌ɪVɭ&Y&&Y& 꽌ɪ\8`&&꽌ɪɖ'*&%&,E'зЮ꽌ɪФ`+*xS&x'8*3Ixix&& 8  '  & x)*++`FG8`0($ p,&"  !"#$%&'()*+,-./0123456789:;<=>?80^݌Hh ü ü݌ ռ ռ ռA ļD ļ? ļAEDE?HJ>h Լ ռ ռ ռ`HJ>݌h Hh݌`HIHHHHhHH݌hHhHh݌H6 VDP (ED _ $0x8x D- ڸDD# H8`?E Vk (f???0xE Hh D#-EEE8` D ڸx D - ڸx8`-0ݩ?ʥD EEE`   D#-EEE8` D ڸx D - l `CAT^REN-DELSAV^TYP:RUN LOA׳MOVpGETޱPUTINIFORMONeIN#QPR#W8$6 Y  # 8` p *  p _  `L h& s " c UNABLE TO FORMAT DISK` h 8` )N )i TOO LONG`  pHCOM ܳhH bh  pL p *  _  W ɓ8`` ` b   :D)  *.%  0  ,.8` 08` `  $H    h m mDISPLAY MUSEDIT DIS+SAVEPROG DIS'CURSOR EDI)CONFIG EDI*DISKCOPY COMEDIT SYSح"_" / LI cAPPLE ][ ADIOS-81 Version 01/29/82 ^ l ! 0 W ) W  !  񭰵:Q1J7F)!Le&HH   lK ( :Lk$ ,+L c !hiУ`L W  W ` pH hHH phh 8` pU P Y մIH hBHH hh8Lv p# L h cINSUFFICIENT DISK SPACE` ó챊 ` p/ * * Y _ n拥ɰ cFILE  !"#(,-. &8` )N )i &8`   6,+ 0 s w l l ! 0 cFREE ON : 8 * c K-BYTES8`HNH+, l hAN9m *hH  +8`h`0:)8``  ` L 178`dH W h H W hLMd R R 0LW 8mH Mh`! 0 cERASE ALL FILES ON DRIVE 1 (Y/N):   Y N W ` W 8` h H W hLMd R R 0LW 8mH Mh`! 0 cERASE ALL FIL% File: DISPLAY.MUS (C) 27-Nov-81 The Soft Warehouse % % Revised 23-Oct-1981 by T.B. Robinson % % LINELEN should be set to 1 less than the maximum screen width % LINELEN: LINELENGTH()-1$ % An atom with no characters in its print name % % PROPERTY PRTMATH, AND, FUNCTION (), PRTSPACE: TRUE, FALSE, ENDFUN$ % Ditto NOT % PROPERTY PRTMATH, NOT, FUNCTION (), PRTSPACE: TRUE, FALSE, ENDFUN$ % Ditto EQ % PROPERTY PRTMATH, EQ, FUNCTION (), PRT FUNCTION (LEX1), PRINT (FIRST (LEX1)), TRUE, ENDFUN$ % Deal with FUNCTION body % PROPERTY PRTMATH, FUNCTION, FUNCTION (LEX1), UNPARSEFUN (LEX1, 'FUNCTION, 'ENDFUN), ENDFUN$ % Deal with SUBROUTINE body % PROPERTY PRTMHEN EMPTY (FIRST (LEX1)), PRINT (LPAR), PRINT (RPAR) EXIT, PRINT (FIRST (LEX1)) EXIT, PRTLIST (FALSE, FIRST (FIRST (LEX1)), REST (FIRST (LEX1))), ENDBLOCK, UNPARSE (CURIND+INDENT, TRUE, REST (LEX1)), PRINTLINE (COMMA) PRINT (LPAR), UNPARSE (SPACES (), FALSE, LEX1), PRINT (RPAR), TRUE, ENDFUN$ % This redefines PRTLIST. It uses UNPARSE on each element and will suppress LOP1 if FALSE % FUNCTION PRTLIST (LOP1, EX1, LEX1), BLOCK WHEp level display function. With one argument it displays a function definition, with two, a property definition. % FUNCTION DISPLAY ("*FUN*", EX1, LINELENGTH), MOVD ('PRINT, '"PRINT$"), MOVD ('"QPRINT$", 'PRINT), NEWLINE (2), BLOCK 1, EX2)), UNPARSE (INDENT, FALSE, LIST (GETD (LEX1))) EXIT, UNPARSE (INDENT, FALSE, LIST (GET (EX1, EX2))), ENDFUN$ % Ensure spaces around OR % PROPERTY PRTMATH, OR, FUNCTION (), PRTSPACE: TRUE, FALSE, ENDFUN$ % Ditto AND (LEX1), PRINT (''), PRINTLIST (FIRST (LEX1)), TRUE, ENDFUN$ % This is redefined in the optional section below % FUNCTION PRINTLIST (EX1), PRINT (EX1), ENDFUN$ % Suppress IDENTITY after WHEN % PROPERTY PRTMATH, IDENTITY,AMBDA' type functions % FUNCTION UNPARSEFUN (LEX1, EX1, EX2), PRINT (EX1), SPACES (1), BLOCK WHEN "*FUN*", PRINT ("*FUN*"), "*FUN*": FALSE, SPACES (1) EXIT, ENDBLOCK, BLOCK WHEN ATOM (FIRST (LEX1)), W FALSE, LEX1), PRINTLINE (COMMA), ENDBLOCK, SPACES (CURIND), PRINT ('ENDLOOP), TRUE, ENDFUN$ % Just for completeness make a COND pretty % PROPERTY PRTMATH, COND, FUNCTION (), PRINT ('COND), SPACES (1), NULL: ""$ % The depth by which successive levels are indented % INDENT: 2$ % Setting CURIND and *FUN* globally allows GETD and GET to pretty print their results, although without quotes % CURIND: 3$ "*FUN*": FALSE$ % The to1: GET (EX1, EX2), WHEN EMPTY (LEX1), PRINT (LEX1) EXIT, PRINT ('PROPERTY), SPACES (1), PRINT (EX1), PRINT (COMMA), SPACES (1), PRINT (EX2), PRINTLINE (COMMA), SPACES (INDENT), WHEN ATOM (LEX1) AND LEX1=COMPRESS (LIST (EXSPACE: TRUE, FALSE, ENDFUN$ % No space before : % PROPERTY PRTMATH, :, FUNCTION (LEX1), PRINT (FIRST (LEX1)), PRINT (':), SPACES (1), UNPARSE (CURIND, FALSE, REST (LEX1)), ENDFUN$ PROPERTY PRTMATH, ', FUNCTION ATH, SUBROUTINE, FUNCTION (LEX1), UNPARSEFUN (LEX1, 'SUBROUTINE, 'ENDSUB), ENDFUN$ % Common routine for both FUNCTION and SUBROUTINE. *FUN* set if this is a named function. It is FALSE for functions on property lists, or other 'L, SPACES (CURIND), PRINT (EX2), TRUE, ENDFUN$ % Deal with LOOP % PROPERTY PRTMATH, LOOP, FUNCTION (LEX1), PRINTLINE ('LOOP), BLOCK WHEN EMPTY (LEX1) EXIT, SPACES (CURIND + INDENT), UNPARSE (CURIND + INDENT, WHEN EX1, DISPPROP ("*FUN*", EX1) EXIT, UNPARSE (0, FALSE, LIST (GETD ("*FUN*"))), ENDBLOCK, MOVD ('"PRINT$", 'PRINT), NULL, ENDFUN$ % Display a property definition % FUNCTION DISPPROP (EX1, EX2, "*FUN*", LEX1), LEXN LOP1, PRINT (LOP1), SPACES (1) EXIT, ENDBLOCK, PRINT (LPAR), LOOP UNPARSE (CURIND, FALSE, LIST (EX1)), WHEN ATOM (LEX1) EXIT, PRINT (COMMA), SPACES (1), EX1: POP (LEX1), ENDLOOP, PRINT (RPAR), ENDFUN quotes if required. This function puts the first quote at the start of the name instead of just before the first delimiter character. % FUNCTION "QPRINT$" (EX1, PRINT, LENGTH), LENGTH: LENGTH (EX1), BLOCK WHEN LENGTH+SPACES() > LINELETLIST (LEX1), WHEN ATOM (LEX1), PRINT (LEX1) EXIT, PRINT (LPAR), LOOP PRINTLIST (POP (LEX1)), WHEN EMPTY (LEX1) EXIT, SPACES (1), WHEN ATOM (LEX1), PRINT ('.), SPACES (1), PRINT (LEX1) EXIT, ENDLOOP% File: EDIT.DIS (C) 01/04/82 The Soft Warehouse % % Screen oriented editing package for muSIMP-80 % % Revised 23-Oct-1981 by T. B. Robinson % % * * * Control variables and miscellaneous items * * * % % Character to exit from th LOOP WHEN EMPTY (RREST (LIST)), TOKEN: SECOND (LIST), REPLACER (LIST), TOKEN EXIT, POP (LIST), ENDLOOP, ENDFUN$ % Return the last item of LIST % FUNCTION LAST (LIST), LOOP WHEN EMPTY (REST (LIST)), WHEN ATOM (LEX2), PRINT (LEX2) EXIT, WHEN ATOM (FIRST (LEX2)), PRTMATH (LEX2, 0, 0, TRUE) EXIT, WHEN ATOM (FIRST (FIRST (LEX2))), UNPARSEWHEN (CURIND, LEX2) EXIT, UNPARSEBLOCK (CURIND, LEX2), ENDBLOCK$ % * * * O P T I O N A L Q U O T I N G P R I N T E R * * * % % These functions must be loaded in order to use the screen editor, otherwise names including break characters will not be read back correctly after editing % % Print with "PRINT$" (EX1) EXIT, ENDBLOCK, EX1, ENDFUN$ % Deal with quoted lists. Although PRINT will deal with lists it is necessary to ensure that PRINT is never given more than an atom, so that the output redirection will work % FUNCTION PRIN. It generates NUL for control-SPACE! % % WHEN CHAR = NULL, ACCEPTCHAR (SPACE, 'INSERTDEL) EXIT, % BLOCK WHEN SPACES()+1 < LINELEN EXIT, ILINE (), DLINET (), ENDBLOCK, PRINT (CHAR), WHEN EMPTY (REST ("*COL*")), "*% % Append LIST2 to LIST1 without REPLACER % FUNCTION APPEND (LIST1, LIST2), WHEN EMPTY (LIST1), LIST2 EXIT, ADJOIN (POP (LIST1), APPEND (LIST1, LIST2)), ENDFUN$ % Remove the last item from LIST % FUNCTION CHOP (LIST, TOKEN), $ % The main unparser % FUNCTION UNPARSE (CURIND, EOL, LEX1, LEX2), LOOP WHEN EMPTY (LEX1) EXIT, LEX2: POP (LEX1), BLOCK WHEN EOL, PRINTLINE (COMMA), SPACES (CURIND) EXIT, ENDBLOCK, BLOCK PARSEBLOCK (CURIND, LEX1), PRINTLINE ('BLOCK), SPACES (CURIND+INDENT), UNPARSE (CURIND+INDENT, FALSE, LEX1), PRINTLINE (COMMA), SPACES (CURIND), PRINT ('ENDBLOCK), ENDFUN$ % In case QPRINT$ is not loaded % MOVD ('PRINT, '"QPRINT$")N, NEWLINE (), SPACES (CURIND + 2*INDENT) EXIT, ENDBLOCK, PRINT: TRUE, BLOCK WHEN LENGTH = LENGTH (EX1), "PRINT$" (EX1) EXIT, "PRINT$" ('""""), "PRINT$" (EX1), "PRINT$" ('""""), WHEN EX1 = '"""", , PRINT (RPAR), ENDFUN$ RDS ()$ l not work if *FUN* is a globally defined function % FUNCTION ACCEPTCHAR (CHAR, "*FUN*"), % This is a kludge for the VT100e editor % EDTERM: ASCII (11)$ % % % Number of spaces at each level of indent. % INDENT: 2$ SPACE: " "$ NULL: ""$ CR: ASCII (13)$ % % ESC: ASCII (27)$ % % % * * * U t i l i t y R o u t i n e s * * * , EOL: TRUE, ENDLOOP, ENDFUN$ % Deal with WHEN % FUNCTION UNPARSEWHEN (CURIND, LEX1), PRINT ('WHEN), SPACES (1), UNPARSE (CURIND+INDENT, FALSE, LEX1), SPACES (1), PRINT ('EXIT), ENDFUN$ % Deal with a BLOCK % FUNCTION UNFIRST (LIST) EXIT, POP (LIST), ENDLOOP, ENDFUN$ % Split LIST after NUM items, return the tail % FUNCTION SPLIT (LIST, NUM, TOKEN), LOOP WHEN ATOM (LIST), FALSE EXIT, NUM: DIFFERENCE (NUM, 1), WHEN ZERO (NUM), TRL-J> Move down a line % 11 EDTERM % Exit editor (dummy) % 12 SEARCHN % Search for next % 13 NLINE % Insert a carriage return % 14 ILINE % Insert newline % 15 SEARCHF % Search for first % 16 DELB % 28 TRUE % Dummy % 29 TRUE % Dummy % 30 DISPTEXT % Redisplay text % 31 TRUE % Dummy % 127 DELB % Delete a character backwards % ), '(FUNCTION (CHAR FUNNAME) (PUT (ASCII CHAR) ('EDFUN) FUNNAME)))$ OT INTEGER (NUM), FALSE EXIT, ENDLOOP, ENDFUN$ % Convert digit to number % FUNCTION DIGNUM (NUM), WHEN INTEGER (NUM), NUM EXIT, NUM: ASSOC (NUM, DIGNUM), WHEN NUM, REST (NUM) EXIT ENDFUN$ DIGNUM: '(("0" . 0) M), NUM: 0, LOOP WHEN EMPTY (COL), NUM EXIT, NUM: PLUS (NUM, TOKLEN(POP(COL))), ENDLOOP, ENDFUN$ % Make sure he meant it! This function is also defined in FILESYS.GRI % FUNCTION CONFIRM (EX1, READCHAR), LOOP NEWLINE LOOP WHEN EMPTY (LIST), FALSE EXIT, "*FUN*" (POP (LIST)), ENDLOOP, ENDFUN$ % Apply *FUN* to pairs of items from LIST N. B. this will not work if *FUN* is a globally defined function % FUNCTION MAP2 (LIST, "*FUN*"), LO 5 ULINET % Move up following indentation % 6 RTOK % Move right a word % 7 DELF % Delete character forward % 8 LCHAR % Move left a character % 9 GLINE % Insert previously deleted line % 10 DLINE % Toggle insert switch % 23 BTEXT % Move to start of text % 24 DLINET % Move down following indent % 25 KELINE % Kill current line % 26 ETEXT % Move to end of text % 27 TRUE % Dummy % ACK (TOKEN) EXIT, ADJOIN (COMPRESS (TOKEN)), ENDFUN$ % Possibly construct an integer % FUNCTION INTPACK (LIST, NUM), NUM: 0, LOOP WHEN EMPTY (LIST), ADJOIN (NUM) EXIT, NUM: PLUS (10*NUM, DIGNUM(POP(LIST))), WHEN NHEN INTEGER (TOKEN), TOKEN EXIT, WHEN ATOM (TOKEN), 1 EXIT, WHEN EMPTY (REST (TOKEN)), LENGTH (FIRST (TOKEN)) EXIT, LENGTH (TOKEN), ENDFUN$ % Return printing length of a line or part of a line % FUNCTION LINELEN (COL, NU TOKEN: REST (LIST), REPLACER (LIST), TOKEN EXIT, POP (LIST), ENDLOOP, ENDFUN$ % Apply *FUN* to each item in LIST. N. B. this will not work if *FUN* is a globally defined function % FUNCTION MAPC (LIST, "*FUN*"), TION (CHAR) (PUT CHAR ('PRTCHAR) TRUE)))$ MAP2 ('( 0 TRUE % Dummy % 1 LTOK % Move left a word % 2 ELINE % Move to end of line and down% 3 DPAGE % Move down a page % 4 RCHAR % Move right a charcter % Delete a character backwards % 17 ULINE % Move up a line % 18 UPAGE % Move up a page % 19 LCHAR % Move left a character % 20 DELW % Delete word to right % 21 KLINE % Kill to end of line % 22 % Unpack a token % FUNCTION "UNPACK$" (TOKEN), WHEN REST (TOKEN) OR LENGTH (FIRST (TOKEN)) EQ 1, TOKEN EXIT, EXPLODE (FIRST (TOKEN)) ENDFUN$ % Pack a token % FUNCTION "PACK$" (TOKEN), WHEN ATOM (TOKEN), TOKEN EXIT, WHEN INTP ("1" . 1) ("2" . 2) ("3" . 3) ("4" . 4) ("5" . 5) ("6" . 6) ("7" . 7) ("8" . 8) ("9" . 9))$ % Return printing length of a token % FUNCTION TOKLEN (TOKEN), WOP WHEN EMPTY (LIST), FALSE EXIT, "*FUN*" (POP (LIST), POP (LIST)), ENDLOOP, ENDFUN$ MAPC ('(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z #), '(FUNC (), PRINT ("Hit RETURN to "), PRINT (EX1), PRINT (", ESC to abort:"), READCHAR (), WHEN SCAN EQ ESC OR SCAN EQ CR EXIT, ENDLOOP, NEWLINE (2), SCAN EQ CR, ENDFUN$ % Read a word for searching % FUNCTION "READWORD$" (, WHEN EMPTY (RREST ("*TEXT*")) AND EMPTY (REST (SECOND ("*TEXT*"))), EX1: FALSE EXIT, ERR: FALSE, EX1: EDPARSE (), WHEN NOT ERR EXIT, ENDLOOP, EX1, ENDFUN$ % Accept a character N. B. this will not work if *FUN* is a < LINELEN EXIT, ILINE (TRUE), ENDFUN$ % Toggle insert switch % FUNCTION INSRT (), "*INSERT*": NOT "*INSERT*", ENDFUN$ % * * * C u r s o r c o n t r o l * * * % % Move right by one character % FUNCTION RCHAR ( TOKEN), T WHEN DLINET (), ELINE () EXIT EXIT, CR (), DISPLINE (SECOND ("*ROW*")), "SPLICE$" ("*COL*"), "*COL*": GETTEXT (SECOND ("*ROW*")), ENDFUN$ % Move down a line % FUNCTION DLINE (), WHEN MOVEDOWNLINE (TRUE), NEWLINE (), XIT, ENDLOOP, CR (), ENDFUN$ % Move to end of text % FUNCTION ETEXT (UPDATE), "SPLICE$" ("*COL*"), LOOP WHEN NOT DOWNPAGE() EXIT, UPDATE: TRUE, ENDLOOP, "*ROW*": GETTEXT ("*TEXT*", ADJOIN (LAST ("*TEXT*"))), "*COL*": GNDFUN$ % ****************** M a i n F u n c t i o n s ******************** % % The top level edit function % FUNCTION EDIT ("*FUN*", EX1, READCHAR, "*INSERT*", "*TEXT*", "*ROW*", "*COL*", "*PRETEXT*", "*POSTTEXT*", "*DELETED*", "*SEARCHN), APPLY (GET (SCAN, 'EDFUN)) EXIT, ACCEPTCHAR (SCAN, 'INSERTDEL), ENDBLOCK, ENDLOOP, NEWLINE (LENGTH ("*ROW*")), "SPLICE$" ("*COL*"), LOOP WHEN EMPTY ("*PRETEXT*") EXIT, UPPAGE (), ENDLOOPELEN EXIT, ILINE (), DLINET (), ENDBLOCK, PRINT (CHAR), WHEN EMPTY (REST ("*COL*")), "*FUN*" (CHAR) EXIT, WHEN NOT "*INSERT*", DELCHAR (), "*FUN*" (CHAR) EXIT, "*FUN*" (CHAR), WHEN "PRTREST$" ("*ROW*", "*COL*", 0) LOOP WHEN NOT ATOM (NEXTRIGHT ()) EXIT, TOKEN: MOVERIGHTTOK (), DISPTOKEN (TOKEN), WHEN EMPTY (TOKEN) EXIT, ENDLOOP, ENDFUN$ % Move to end of line % FUNCTION ELINE (EX1), WHEN EMPTY (REST ("*COL*")), WHEN EX1 EXIT,SE, ENDFUN$ % Move down a page % FUNCTION DPAGE ( NUM), NUM: PAGELEN, LOOP WHEN NOT MOVEDOWNLINE (TRUE) EXIT, NEWLINE (), NUM: DIFFERENCE (NUM, 1), WHEN NOT NUM>0 EXIT, ENDLOOP, LOOP WHEN NOT MOVELEFTTOK() EREADCHAR, WORD), READCHAR: TRUE, LOOP WHEN READCHAR() EQ CR EXIT, PUSH (SCAN, WORD), ENDLOOP, WHEN EMPTY (WORD), NULL EXIT, WORD: REVERSE (WORD), WHEN INTPACK (WORD), FIRST (INTPACK (WORD)) EXIT, COMPRESS (WORD), ETEXT*", SCREENLEN), LOOP RECLAIM (), DISPTEXT (), LOOP WHEN READCHAR() EQ EDTERM EXIT, BLOCK WHEN GET (SCAN, 'PRTCHAR) OR INTEGER (SCAN), ACCEPTCHAR (SCAN, 'INSERTPRT) EXIT, WHEN GET (SCAN, 'EDFU globally defined function % FUNCTION ACCEPTCHAR (CHAR, "*FUN*"), % This is a kludge for the VT100. It generates NUL for control-SPACE! % % WHEN CHAR EQ NULL, ACCEPTCHAR (SPACE, 'INSERTDEL) EXIT, % BLOCK WHEN PLUS(SPACES(),1) < LINOKEN: MOVERIGHTCHAR (), WHEN EMPTY (TOKEN), DLINE () EXIT, DISPTOKEN (TOKEN), ENDFUN$ % Move right by one token % FUNCTION RTOK ( TOKEN), TOKEN: MOVERIGHTTOK (), DISPTOKEN (TOKEN), WHEN EMPTY (TOKEN) AND NOT DLINET() EXIT, LOOP WHEN NOT MOVELEFTTOK() EXIT, ENDLOOP EXIT, ELINE (), ENDFUN$ % Move down a line, following indentation % FUNCTION DLINET (), WHEN MOVEDOWNLINE (TRUE), NEWLINE (), SPACES (FIRST ("*COL*")), TRUE EXIT, FAL*", PRINT), READCHAR: TRUE, LOOP WHEN READCHAR() EQ CR EXIT, ENDLOOP, READCHAR: FALSE, PRINT: TRUE, "*INSERT*": TRUE, "*TEXT*": EDDISP ("*FUN*", EX1), "*ROW*": "*TEXT*", "*COL*": SECOND ("*TEXT*"), "*POSTTEXT*": SPLIT ("*ETTEXT (SECOND ("*ROW*")), WHEN UPDATE, DISPTEXT () EXIT, SETCURSOR ("*TEXT*", "*ROW*", "*COL*"), ENDFUN$ % Move left one character % FUNCTION LCHAR ( TOKEN), TOKEN: MOVELEFTCHAR (), WHEN EMPTY (TOKEN), WHEN ULINE (), OVELEFTTOK() EXIT, ENDLOOP, CR (), ENDFUN$ % Move to start of text % FUNCTION BTEXT (UPDATE), "SPLICE$" ("*COL*"), LOOP WHEN NOT UPPAGE () EXIT, UPDATE: TRUE, ENDLOOP, "*ROW*": "*TEXT*", "*COL*": SECOND ("*ROW*"), WWHEN ATOM (FIRST ("*COL*")), WHEN EMPTY (TOKEN), POP ("*COL*"), CHAR EXIT, REPLACER ("*COL*", ADJOIN (CHAR, REST ("*COL*"))), POP ("*COL*"), REPLACEF (REST ("*COL*"), TOKEN), CHAR EXIT, REPLACEF ("*COL*", APPEND (F TOKEN EXIT, TOKEN ENDFUN$ % Move down one line % FUNCTION MOVEDOWNLINE (EX1, EX2), "SPLICE$" ("*COL*"), WHEN EMPTY (RREST ("*ROW*")), EX2: DOWNPAGE (), WHEN NOT EX2, FALSE EXIT, WHEN EX1, WHEN EX2 EQ 1,STTEXT*"), LOOP PUSH (SECOND ("*TEXT*"), "*PRETEXT*"), REPLACER ("*TEXT*", RREST ("*TEXT*")), NUM: DIFFERENCE (NUM, 1), WHEN ZERO (NUM) EXIT, ENDLOOP, "*POSTTEXT*": SPLIT ("*TEXT*", SCREENLEN), NUM0, ENDFUN$ % Move one cELINE (TRUE) EXIT, BS (TOKLEN (TOKEN)), ENDBLOCK, LOOP TOKEN: MOVELEFTTOK (TRUE), WHEN EMPTY (TOKEN) EXIT, BS (TOKLEN (TOKEN)), WHEN NOT ATOM (SECOND ("*COL*")) EXIT, ENDLOOP, ENDFUN$ % Move up a line to beginning % TRUE EXIT, FALSE, ENDFUN$ % Move up a page % FUNCTION UPAGE ( NUM), NUM: PAGELEN, LOOP WHEN NOT MOVEUPLINE (TRUE) EXIT, UP (), NUM: DIFFERENCE (NUM, 1), WHEN NOT NUM>0 EXIT, ENDLOOP, LOOP WHEN NOT MRST ("*COL*")) AND TOKEN EQ SPACE, REPLACEF ("*COL*", PLUS (FIRST("*COL*"),1)), REPLACER ("*COL*", RREST ("*COL*")), TOKEN EXIT, WHEN ATOM (TOKEN), MOVERIGHTTOK () EXIT, TOKEN: "UNPACK$" (TOKEN), CHAR: ADJOIN (POP (TOKEN)), ), WHEN EMPTY (TOKEN), FALSE EXIT, WHEN INTEGER (FIRST ("*COL*")) AND TOKEN EQ SPACE, REPLACEF ("*COL*", PLUS (FIRST("*COL*"),1)), REPLACER ("*COL*", RREST ("*COL*")), TOKEN EXIT, WHEN "SPLICE$" ("*COL*"), POP ("*COL*"), % Move down a page % FUNCTION DOWNPAGE ( NUM, NUM0), WHEN EMPTY ("*POSTTEXT*"), FALSE EXIT, NUM: LENGTH ("*POSTTEXT*"), BLOCK WHEN NUM > PAGELEN, NUM: PAGELEN EXIT, ENDBLOCK, NUM0: NUM, CONCATEN ("*TEXT*", "*PO ELINE (TRUE), TRUE EXIT, FALSE EXIT, BS (1), TRUE, ENDFUN$ % Move left one token % FUNCTION LTOK ( TOKEN), TOKEN: MOVELEFTTOK (TRUE), WHEN EMPTY (TOKEN) AND NOT ULINET() EXIT, BLOCK WHEN EMPTY (TOKEN), , FALSE, ENDFUN$ % Move up a line, following indentation % FUNCTION ULINET (), WHEN BEGINLINE (TRUE), CR (), SPACES (FIRST ("*COL*")), FALSE EXIT, WHEN MOVEUPLINE (TRUE), UP (), CR (), SPACES (FIRST ("*COL*")),HEN UPDATE, DISPTEXT () EXIT, SETCURSOR ("*TEXT*", "*ROW*", "*COL*"), ENDFUN$ % Move one character to the right % FUNCTION MOVERIGHTCHAR ( CHAR, TOKEN), TOKEN: NEXTRIGHT (), WHEN EMPTY (TOKEN), FALSE EXIT, WHEN INTEGER (FIIRST ("*COL*"), CHAR)), WHEN EMPTY (TOKEN), REPLACER ("*COL*", RREST ("*COL*")), CHAR EXIT, REPLACEF (REST ("*COL*"), TOKEN), CHAR, ENDFUN$ % Move one token to the right % FUNCTION MOVERIGHTTOK ( TOKEN), TOKEN: NEXTRIGHT ( NEWLINE (2), UP (), DISPLINE (THIRD ("*ROW*")), UP (), MOVEDOWNLINE () EXIT, DISPTEXT (), MOVEDOWNLINE () EXIT, MOVEDOWNLINE () EXIT, POP ("*ROW*"), "*COL*": SECOND ("*ROW*"), ENDFUN$ FUNCTION ULINE (), WHEN BEGINLINE (), LOOP WHEN NOT MOVELEFTTOK() EXIT, ENDLOOP, CR (), FALSE EXIT, WHEN MOVEUPLINE (TRUE), UP (), LOOP WHEN NOT MOVELEFTTOK() EXIT, ENDLOOP, CR (), TRUE EXITharacter to the left % FUNCTION MOVELEFTCHAR ( TOKEN), TOKEN: FIRST ("*COL*"), WHEN ATOM (TOKEN), MOVELEFTTOK () EXIT, TOKEN: "UNPACK$" (TOKEN), WHEN EMPTY (REST (TOKEN)), WHEN EMPTY (REST ("*COL*")) OR ATOM (SECOND ("*COL*"))("*COL*"), WHEN EMPTY (FIRST ("*ROW*")), WHEN UPPAGE (), BLOCK WHEN EX1, DISPTEXT () EXIT, ENDBLOCK, MOVEUPLINE () EXIT, FALSE EXIT, "*COL*": FIRST ("*ROW*"), "*ROW*": GETTEXT ("*TEXT*", "*ROW*"),irst occurrence of a name % FUNCTION SEARCHF (), HOME (), SPACES (LINELEN (SECOND ("*TEXT*"))), CR (), PRINT ("Search for: "), "*SEARCH*": "READWORD$" (), HOME (), SPACES (LINELEN), HOME (), DISPLINE (SECOND ("*TEXT*")), WH", "*ROW*", "*COL*"), ENDFUN$ % * * * T e x t M o d i f i e r s * * * % % Delete a character forwards % FUNCTION DELF (), WHEN EMPTY (DELCHAR ()), KLINE (TRUE) EXIT, "PRTREST$" ("*ROW*", "*COL*", 1), ENDFUN$ % Delete a characEN ()), LOOP TOKEN: NEXTRIGHT (), WHEN EMPTY (TOKEN) EXIT, WHEN NOT ATOM (TOKEN) EXIT, NUM: PLUS (NUM, 1), DELTOKEN (), ENDLOOP, ENDBLOCK, WHEN ZERO (NUM) EXIT, "PRTREST$" ("*ROW*", "*COL*", NUM), ENDFIT, CHAR: ADJOIN (CHOP (TOKEN)), REPLACEF ("*COL*", TOKEN), WHEN EMPTY (REST ("*COL*")) OR ATOM (SECOND ("*COL*")), REPLACER ("*COL*", ADJOIN (CHAR, REST ("*COL*"))), TOKEN EXIT, REPLACEF (REST ("*COL*"), CONCATEN (CHAR, SECOND ("*COL (EX1), WHEN ZERO (FIRST ("*COL*")), FALSE EXIT, WHEN EX1 AND INTEGER (FIRST ("*COL*")), FALSE EXIT, "SPLICE$" ("*COL*"), "*COL*": SECOND ("*ROW*"), TRUE, ENDFUN$ % Move up one line % FUNCTION MOVEUPLINE (EX1), "SPLICE$" ("*PRETEXT*", NUM), "*TEXT*": ADJOIN (FALSE, CONCATEN (REVERSE (LEX1), CONCATEN (REST ("*TEXT*" ), "*POSTTEXT*"))), "*ROW*": GETTEXT ("*TEXT*", REST ("*ROW*")), "*POSTTEXT*": SPLIT ("*TEXT*", SCREENLEN), TRUE, ENDFUN$ % Search for f(TOKEN) AND NOT MOVEDOWNLINE (TRUE) EXIT, BLOCK WHEN EMPTY (TOKEN), TOKEN: NULL EXIT, WHEN NOT ATOM (TOKEN), TOKEN: FIRST (TOKEN) EXIT, ENDBLOCK, WHEN TOKEN = "*SEARCH*" EXIT, ENDLOOP, SETCURSOR ("*TEXT*NUM: TOKLEN (DELTOKEN ()) EXIT, NUM: 0, LOOP TOKEN: NEXTRIGHT (), WHEN EMPTY (TOKEN) EXIT, WHEN NOT ATOM (TOKEN) EXIT, NUM: PLUS (NUM, 1), DELTOKEN (), ENDLOOP EXIT, NUM: TOKLEN (DELTOK, "*COL*": GETTEXT (SECOND ("*ROW*"), "*COL*"), TOKEN EXIT, REPLACEF (REST ("*COL*"), "PACK$" (APPEND (TOKEN, SECOND ("*COL*")))), "*COL*": GETTEXT (SECOND ("*ROW*"), "*COL*"), REPLACER ("*COL*", RREST ("*COL*")), TOKEN EXDIFFERENCE(TOKEN ,1)), REPLACER ("*COL*", ADJOIN (SPACE, REST ("*COL*"))), SPACE EXIT, "SPLICE$" ("*COL*"), "*COL*": GETTEXT (SECOND ("*ROW*"), "*COL*"), TOKEN, ENDFUN$ % Move to the start of the currrent line % FUNCTION BEGINLINE ENDFUN$ % Move up a page % FUNCTION UPPAGE ( NUM), WHEN EMPTY ("*PRETEXT*"), FALSE EXIT, NUM: LENGTH ("*PRETEXT*"), BLOCK WHEN NUM > PAGELEN, NUM: PAGELEN EXIT, ENDBLOCK, LEX1: "*PRETEXT*", "*PRETEXT*": SPLITEN "*SEARCH*" EQ NULL, SETCURSOR ("*TEXT*", "*ROW*", "*COL*") EXIT, SEARCHN (), ENDFUN$ % Search for next occurrence of a name % FUNCTION SEARCHN (TOKEN), WHEN "*SEARCH*" EQ NULL EXIT, LOOP TOKEN: MOVERIGHTTOK (), WHEN EMPTY ter backwards % FUNCTION DELB ( TOKEN), WHEN LCHAR (), DELF () EXIT ENDFUN$ % Delete word backwards % FUNCTION DELW ( TOKEN, NUM), BLOCK WHEN NOT ATOM (FIRST ("*COL*")), WHEN NOT ATOM (SECOND ("*COL*")), *"))), TOKEN, ENDFUN$ % Move one token to the left % FUNCTION MOVELEFTTOK (EX1, TOKEN), TOKEN: FIRST ("*COL*"), WHEN INTEGER (TOKEN), WHEN EX1, FALSE EXIT, WHEN ZERO (TOKEN), FALSE EXIT, REPLACEF ("*COL*", UN$ % Insert a text character % FUNCTION INSERTPRT (CHAR), WHEN ATOM (FIRST ("*COL*")), REPLACER ("*COL*", ADJOIN (ADJOIN (CHAR), REST ("*COL*"))), POP ("*COL*") EXIT, REPLACEF ("*COL*", CONCATEN ("UNPACK$" (FIRST ("*COL*")), ADJOIN (*": REST ("*COL*"), WHEN NOT EX1 OR EMPTY (RREST ("*ROW*")) AND EMPTY ("*POSTTEXT*") OR PLUS (SPACES (), LINELEN(THIRD("*ROW*"))) > LINELEN, NUM: LINELEN (REST ("*COL*")), REPLACER ("*COL*", FALSE), "PRTREST$" ("*ROW*", "*urn next token to the right % FUNCTION NEXTRIGHT (), WHEN EMPTY (REST ("*COL*")), FALSE EXIT, SECOND ("*COL*"), ENDFUN$ % Insert carriage return % FUNCTION NLINE (), WHEN NOT "*INSERT*" AND DLINET() EXIT, ILINE (), DLINET (), NGTH ("*TEXT*") > SCREENLEN, PUSH (CHOP ("*TEXT*"), "*POSTTEXT*"), SCROLLDOWN (REST ("*ROW*"), LINELEN (FIRST ("*POSTTEXT*"))), SETCURSOR ("*TEXT*", "*ROW*", "*COL*") EXIT, SCROLLDOWN (REST ("*ROW*"), 0), SETCURSOR ("*TEXT*", "*ROW*", COL), LOOP WHEN NOT POP (LIST) EQ SPACE EXIT, REPLACEF (COL, PLUS(FIRST(COL),1)), REPLACER (COL, LIST), ENDLOOP EXIT, WHEN ATOM (FIRST (COL)), REPLACEF (REST (COL), "PACK$" (SECOND (COL))) EXIT, WHEN EMPTY (REST (C$" ("*COL*"), POP ("*COL*"), ENDFUN$ % Delete next character to the right % FUNCTION DELCHAR ( TOKEN), TOKEN: NEXTRIGHT (), WHEN ATOM (TOKEN), DELTOKEN () EXIT, TOKEN: "UNPACK$" (TOKEN), WHEN EMPTY (REST (TOKEN)), REPN$ % Kill current line including carriage-return % FUNCTION KELINE (), WHEN FIRST ("*COL*") EQ 0, KLINE (TRUE) EXIT, ULINE (), KLINE (TRUE), ENDFUN$ % Kill to end of line % FUNCTION KLINE (EX1, NUM, NUM0, LEX1), "*DELETED NUM0>0 EXIT, PUSH (SPACE, LEX1), NUM0: DIFFERENCE (NUM0, 1), ENDLOOP, REPLACER ("*COL*", LEX1), REPLACER (REST ("*ROW*"), RRREST ("*ROW*")), SCROLLUP (REST ("*ROW*"), NUM), SETCURSOR ("*TEXT*", "*ROW*", "*COL*"), ENDFUN$ % RetEST ("*COL*")), RREST ("*ROW*" ))), SPACES (LINELEN (THIRD ("*ROW*"))), REPLACER ("*COL*", FALSE), "SPLICE$" (THIRD ("*ROW*")), BLOCK WHEN EX1 EXIT, REPLACEF (THIRD ("*ROW*"), INDENT (SECOND ("*ROW*"))), ENDBLOCK, WHEN LE REPLACER ("*COL*", APPEND ("*DELETED*")), "PRTREST$" ("*ROW*", "*COL*", 0), ENDFUN$ % Reconstruct a token % FUNCTION "SPLICE$" (COL, LIST), WHEN INTEGER (FIRST (COL)) REPLACEF (REST (COL), "PACK$" (SECOND (COL))), LIST: REST (CHAR))) ENDFUN$ % Insert a delimeter character % FUNCTION INSERTDEL (CHAR), WHEN CHAR EQ SPACE AND INTEGER (FIRST ("*COL*")), REPLACEF ("*COL*", PLUS (FIRST("*COL*"), 1)) EXIT, REPLACER ("*COL*", ADJOIN (CHAR, REST ("*COL*"))), "SPLICEFALSE EXIT, REPLACER ("*COL*", RREST ("*COL*")), WHEN ATOM (FIRST ("*COL*")) OR ATOM (SECOND ("*COL*")), TOKEN EXIT, REPLACEF ("*COL*", "UNPACK$" (FIRST ("*COL*"))), REPLACEF (REST ("*COL*"), "UNPACK$" (SECOND ("*COL*"))), TOKEN, ENDFUCOL*", NUM) EXIT, BLOCK WHEN EMPTY ("*POSTTEXT*") EXIT, CONCATEN ("*TEXT*", ADJOIN (POP ("*POSTTEXT*"))), ENDBLOCK, NUM: LINELEN (SECOND ("*ROW*")), LEX1: REST (THIRD ("*ROW*")), NUM0: FIRST (THIRD ("*ROW*")), LOOP WHEN NOT ENDFUN$ % Insert a new line % FUNCTION ILINE (EX1), BLOCK WHEN EMPTY (REST ("*COL*")) OR ATOM (SECOND ("*COL*")) EXIT, REPLACEF (REST ("*COL*"), "PACK$" (SECOND ("*COL*"))), ENDBLOCK, REPLACER (REST ("*ROW*"), ADJOIN (ADJOIN (0, R"*COL*"), ENDFUN$ % Insert previously deleted line % FUNCTION GLINE (), BLOCK WHEN REST ("*COL*"), ILINE (TRUE) EXIT, ENDBLOCK, BLOCK WHEN PLUS(SPACES(),LINELEN("*DELETED*")) > LINELEN, DLINET () EXIT, ENDBLOCK, LACER ("*COL*", RREST ("*COL*")), FIRST (TOKEN) EXIT, REPLACEF (REST ("*COL*"), REST (TOKEN)), FIRST (TOKEN), ENDFUN$ % Delete next token to the right % FUNCTION DELTOKEN ( TOKEN), TOKEN: NEXTRIGHT (), WHEN EMPTY (TOKEN), OL)) OR ATOM (SECOND (COL)), REPLACEF (COL, "PACK$" (FIRST (COL))), TRUE EXIT, REPLACEF (COL, "PACK$" (APPEND (FIRST (COL), SECOND (COL)))), REPLACER (COL, RREST (COL)), FALSE, ENDFUN$ % Find sublist % FUNCTION GETTEXT (LIST, TAILACES (POP (ROW)), LOOP WHEN ROW = REST (COL), PLUS (NUM0, 1) EXIT, DISPTOKEN (POP (ROW)), ENDLOOP, ENDFUN$ % Replace a line of text % FUNCTION REPLLINE (COL, LENGTH, NUM), CR (), DISPLINE (COL), NUM: SPACES (),UM0), ROW: REVERSE (ROW), LOOP NUM: REPLLINE (POP (ROW), NUM), UP (), WHEN EMPTY (REST (ROW)) EXIT, ENDLOOP, CR (), ENDFUN$ % Compute indentation % MATCHOPEN: LIST (LPAR, 'WHEN, 'LOOP, 'BLOCK, 'FUNCTION, 'SUBROUTINE)$ MNCE (NUM, INDENT) EXIT, ENDBLOCK, ENDLOOP, ENDFUN$ % * * * R e d i r e c t G R I N D o u t p u t * * * % % Add a newline to the text data structure. Suppress newlines at the start of the text. % FUNCTION "NEWLINE$" (N), WHEN NT (SPACE), PLUS ("SPACES$", 1) EXIT, WHEN LENGTH ("*ROW*") EQ 1, "*ROW*": ADJOIN (N), "SPACES$": PLUS(N,1) EXIT, ENDFUN$ % Pass TOKEN to the text data structure inserting a newline if needed. % FUNCTION LPRINT (TOKEN, PRINT, LENN (ROW) (DISPLINE ROW) (NEWLINE))), SETCURSOR ("*TEXT*", "*ROW*", "*COL*"), ENDFUN$ % Display a line of text % FUNCTION DISPLINE (ROW), SPACES (POP (ROW)), MAPC (ROW, 'DISPTOKEN), ENDFUN$ % Display one token % FUNCTION DISPTOKEN (TOKCOL, NUM, NUM0), NUM0: SPACES (), MAPC (REST (COL), 'DISPTOKEN), NUM: DIFFERENCE (SPACES(NUM), NUM0), WHEN NUM < NUM0, NUM0: SPACES (), BS (NUM), PLUS (NUM0, 1) EXIT, NUM0: SPACES (), CR (), ROW: SECOND (ROW), SPUM: REPLLINE (POP (ROW), NUM), NEWLINE (), ENDLOOP, SPACES (NUM), UP (LENGTH), ENDFUN$ % Scroll down part of screen % FUNCTION SCROLLDOWN (ROW, NUM, NUM0), NUM0: DIFFERENCE (LENGTH(ROW), 1), WHEN NUM0 < 0 EXIT, NEWLINE (NP (COL), BLOCK WHEN NOT ATOM (HEAD), HEAD: FIRST ("PACK$" (HEAD)) EXIT, ENDBLOCK, BLOCK WHEN MEMBER (HEAD, MATCHOPEN), NUM: PLUS (NUM, INDENT) EXIT, WHEN MEMBER (HEAD, MATCHCLOSE), NUM: DIFFERENE % FUNCTION "PRINTLINE$" (TOKEN), PRINT (TOKEN), NEWLINE (), ENDFUN$ % Deal with spaces. Multiple spaces only occur at the start of a line. % FUNCTION "SPACES$" (N), WHEN NOT INTEGER (N), "SPACES$" EXIT, WHEN N EQ 1, LPRI), LOOP WHEN REST (LIST) = TAIL, LIST EXIT, POP (LIST), ENDLOOP, ENDFUN$ % * * * T e x t P r i n t i n g * * * % % Display a screen of text % FUNCTION DISPTEXT () CLEARSCREEN (), MAPC (REST ("*TEXT*"), '(FUNCTIO EXIT, NEWLINE (), ENDLOOP, ROW: SECOND (ROW), SPACES (POP (ROW)), LOOP WHEN ROW = REST (COL) EXIT, DISPTOKEN (POP (ROW)), ENDLOOP, ENDFUN$ % Print from cursor to end of line, restore cursor % FUNCTION "PRTREST$" (ROW, SPACES (DIFFERENCE (LENGTH, NUM)), NUM, ENDFUN$ % Scroll up part of screen % FUNCTION SCROLLUP (ROW, NUM, LENGTH), WHEN EMPTY (ROW), SPACES (NUM) EXIT, LENGTH: DIFFERENCE (LENGTH(ROW), 1), LOOP WHEN EMPTY (ROW) EXIT, NATCHCLOSE: LIST (RPAR, 'EXIT, 'ENDLOOP, 'ENDBLOCK)$ FUNCTION INDENT (COL, NUM, HEAD), WHEN EMPTY (COL), 0 EXIT, NUM: POP (COL), LOOP WHEN EMPTY (COL), WHEN NUM<0 OR NUM>LINELEN/2, 0 EXIT, NUM EXIT, HEAD: POLENGTH ("*ROW*") EQ 1 EXIT, LOOP WHEN ZERO (N) EXIT, PUSH (REVERSE ("*ROW*"), "*TEXT*"), "*ROW*": ADJOIN (0), N: DIFFERENCE (N, 1), WHEN NOT N>0 EXIT, ENDLOOP, "SPACES$": 1, ENDFUN$ % Make PRINTLINE use PRINT and NEWLIEN), WHEN EMPTY (TOKEN) EXIT, WHEN ATOM (TOKEN), PRINT (TOKEN) EXIT, MAPC (TOKEN, 'PRINT), ENDFUN$ % Set cursor to current position % FUNCTION SETCURSOR (TEXT, ROW, COL), HOME (), LOOP POP (TEXT), WHEN TEXT = REST (ROW)GTH), PRINT: TRUE, LENGTH: LENGTH (TOKEN), "SPACES$": PLUS ("SPACES$", LENGTH), BLOCK WHEN INTEGER (TOKEN) OR GET (TOKEN, 'PRTCHAR), PUSH (ADJOIN (TOKEN), "*ROW*") EXIT, WHEN LENGTH EQ 1, PUSH (TOKEN, "*ROW*") EXIT, "*TEXT*", "*COL*": SECOND ("*TEXT*"), "SCAN$": GETD ('SCAN), MOVD ('READCHAR, '"READCHAR$"), MOVD ('"SCAN$", 'SCAN), MOVD ('SREADCHAR, 'READCHAR), TERM: LIST (';, RPAR), TERM: CONCATEN (TERM, TERM), ERR: FALSE, EX1: PARSE (SCAN AN), WHEN MOVEDOWNLINE (), WHEN EX1, SCAN: CR EXIT, SCAN () EXIT, WHEN DOWNPAGE (), SCAN (EX1) EXIT, WHEN EX1, SCAN: EX1 EXIT, SCAN: POP (TERM) EXIT, WHEN ATOM (SCAN), WHEN EX1, SCAN EH (SCAN, LEX1), ENDLOOP, ENDFUN$ % To satisfy SYNTAX if an error occurs % FUNCTION SREADCHAR (), SCAN: '$, ENDFUN$ % Flag end of symbols for FILESYS % OBLIST: LENGTH (OBLIST ())$ RDS ('CURSOR, 'EDI)$ INTLINE, NEWLINE, SPACES, "*TEXT*", "*ROW*", "SPACES$"), "SPACES$": 1, "*TEXT*": ADJOIN (FALSE), "*ROW*": ADJOIN (0), WHEN EMPTY (EX1), LIST (FALSE, "*ROW*") EXIT, BLOCK WHEN EMPTY (EX2) AND EMPTY (GETD (EX1)), MOVD ('OIN (0), "*TEXT*"), REVERSE ("*TEXT*"), ENDFUN$ FUNCTION NULLFUN (), ENDFUN$ % * * * R e d i r e c t P A R S E I n p u t * * * % % Parse ther text data structure % FUNCTION EDPARSE ("SCAN$", "READCHAR$", EX1, EX2, TERM), "*ROW*":Take items from the text data structure. The cursor is advanced so that, in the event of an error, editing can be resumed at the point at which the error was detected % FUNCTION "SCAN$" (EX1, LEX1), SCAN: MOVERIGHTTOK (), WHEN EMPTY (SC""" WHEN NEXTRIGHT () EQ '"""", SCAN: COMPRESS (CONCATEN (REVERSE (PUSH (MOVERIGHTTOK (), LEX1)), LIST (QSCAN ()))) EXIT, WHEN EMPTY (LEX1), SCAN: NULL EXIT, SCAN: COMPRESS (REVERSE (LEX1)) EXIT, PUS PUSH (ADJOIN (TOKEN), "*ROW*"), ENDBLOCK, WHEN TOKEN EQ COMMA AND "SPACES$" > DIFFERENCE(LINELEN,12), NEWLINE (), SPACES (PLUS(CURIND,2*INDENT)) EXIT, ENDFUN$ % Display into text data structure % FUNCTION EDDISP (EX1, EX2, PRINT, PRINTLINE$", 'PRINTLINE), MOVD ('"NEWLINE$", 'NEWLINE), MOVD ('"SPACES$", 'SPACES), DISPLAY (EX1, EX2), PRINTLINE ('$), PUTD ('PRINT, PRINT), PUTD ('PRINTLINE, PRINTLINE), PUTD ('NEWLINE, NEWLINE), PUTD ('SPACES, SPACES), PUSH (ADJ(), 0), BLOCK WHEN NOT TERMINATOR() OR MOVERIGHTTOK(), SYNTAX () EXIT, ENDBLOCK, PUTD ('SCAN, "SCAN$"), MOVD ('"READCHAR$", 'READCHAR), WHEN ERR, NEWLINE (), ERR: CONFIRM ('"re-edit") EXIT, EVAL (EX1), ENDFUN$ % XIT, WHEN SCAN EQ SPACE, SCAN () EXIT, WHEN SCAN EQ '"""", QSCAN () EXIT, SCAN EXIT, SCAN: FIRST (SCAN), ENDFUN$ % Deal with double quotes % FUNCTION QSCAN ( LEX1), LOOP SCAN ('""""), WHEN SCAN EQ '"NULLFUN, EX1) EXIT, WHEN EMPTY (GET (EX1, EX2)), PUT (EX1, EX2, 'TRUE) EXIT, ENDBLOCK, PRINT: GETD ('PRINT), PRINTLINE: GETD ('PRINTLINE), NEWLINE: GETD ('NEWLINE), SPACES: GETD ('SPACES), MOVD ('LPRINT, 'PRINT), MOVD ('"PR;)$)hSZ8Z[["}$}GG1'GG1/GGr[6GGX[A GGN(GGV0GG ]8GG&f@GG,nHGG2vPGGbXGG2`GGZGpGGxGGGGGG;GGGGGMGGYGGiGG~GGGGGG1LGiLG1LG1L1LG1LG1MG1M1MG8gMG1 MG1(MG\g0MG18MGg@MGgHMGgPMGhXM1`M1hM1 pM1 xMx1 ӀMp1ӈMh1ӐM`1ӘMX1ӠMP1ӨMH1ӰM@1ӸM81M01M(HlOG@vOG1OG1O1%O1'OȰ1)Pа1+Pذ1-P఍1/P11 P13(P150P178P 19@P(1;HP01=PP81?XP@1A`PH1ChPP1EpPX1GxP`1IԀPh1KԈPp1MԐPx1OԘP1QԠP1SԨP1U԰P1WԸP1YP1[PG% File: CURSOR.EDI (C) 11/27/81 The Soft Warehouse % % * * A P P L E S c r e e n * * % % * * P r i m i t i v e s * * % CR: ASCII (13)$ % % SPACE: " "$ % Maximum length of lines. Set to one less then the screenwidth LINE (HOME), PRINT (HOME) ENDFUN$ % Clear screen, then HOME cursor. % CLEARSCREEN: ASCII (26)$ % % FUNCTION CLEARSCREEN (), PRINTLINE (CLEARSCREEN), PRINT (HOME) ENDFUN$ % Move up N lines % UP#: ASCII (11)$ % %(GG[ GG+HG+HG+"ZG+*HG,4IG-,=IGI,JIG/RIG/Y IG.d(IGC/k0IGa/t8IG}2{@IGHIGPIG2XIG'3`IG_hIGGG/xIGE0IGIGIG5IG5IG\ШIG1иIG1 иIG1IG1IG1KG1KG1KGVcKGxc0ZGhLG1L1ZG xрZG1GG1 LG1(LGf0LGc8LGe@LGHdHLGPdPLGXdXLG`d`LGhdhLG g&pLGd0xLGd9ҀLGdI҈LGdTҐLGddҘLGDevҠLGxeҨLG1ҰLG1ҸLGHfLGnfLG1aN1cN1eN1gN1iN1kN1mOG1oOG1tOGl|OGk OG l(OGBk0OGVm8OGbk@OGrHOGlPOGHuXOGk`OGqhOGtpOGtxOGrqӀOGrӈOGmӐOG~mӘOG,rӠOGsӨOG6kӰOGmӸOGkOGsOGr/QGr9QGzuCQGqKQG{RQG.sZQGvbRGmkRG~vyRGnRGt RGdv(RG&v0RGn8RGLp ZG1HRG1PRG.oXRGv`RGohRG}pRGpxRGpրRG| ֈRG1ְPG|֘RG1֠RGds%֨RGw.ְRGw7ָRG1B֘PG|GRGyond the top or bottom of the screen % PAGELEN: 2*SCREENLEN/3$ % Number of spaces to use for each level of indentation. % INDENT: 1$ % HOME cursor at top left of screen. % HOME: ASCII (30)$ % % FUNCTION HOME (), PRINTGG GGGGGG#GG,GG5HGY?HG4EHG5KHGP HGd5Y(HG]0HGe8HGuk@HG qHHGS xPHGv XHGk"`HG"hHG"pHG!#xHGK#HGm#HG#HG'$HG$HG%HG%GG'`JG/(HG'GG1JT1JG1JG]JG1JGj^JG1 KG^KG^KG^%KG1/ KG14(KG1:GG1B8KG1F@K谍1HGG1JPKG1L`KG|[`K1^hKG`pKGbxKGm#dрKGv`fшKG'$hѐKG`jјKG1lѠKG`nѨKG`wѰKG1ѸKGeGG1KG1!M 1#M1%M1'Mı1)M1+M1-N1/N11N13Nȯ15 NЯ17(Nد190N்1;8N词1=@N1?HN1APN1CXN1E`N1GhN1IpN 1KxN(1MӀN01OӈN81QӐN@1SӘNH1UӠNP1WӨNX1YӰN`1[ӸNh1]Np1_Nxh]PGDhePGdhkGhsPG1zPG1|PG1~QG1QG1QG1QG1 QG1(QG10QG18QGh@QG1HQG&iPQG1XQG1`QGXihQG1pQG1xQG1ԀQG1ԈQG1ԐQG1ԘQG1ԠQG1ըQG1 հQGy(ZG1QGj$QG to avoid trouble with wraparound. % LINELEN: LINELENGTH()-1$ % Number of lines on the screen. % SCREENLEN: 24$ % Number of lines moved by the move page commands. This also determines the amount of hysteresis when the cursor goes be1IG1IG1GG1 IDa%IG[-G14`JG18JG1<JG1AJG[R JG1ZеG&\^0JG1h8JG1m@JG1uHJG1~PJG1XJG\`JG1hJG1pJG1xJG:\ЀJG1ЈJG`АJG1ИJ1РJG1ШJL1аJG\иJ̲1JG1JG FUNCTION UP (N), WHEN N EQ 0 EXIT, LOOP PRINT (UP#), N: DIFFERENCE(N,1), WHEN NOT POSITIVE(N) EXIT, ENDLOOP, ENDFUN$ % Move to start of line % FUNCTION CR (), PRINT (CR), ENDFUN$ % Back space N places % BS#: ASC"), ENDBLOCK, READCHAR: FALSE, ENDLOOP, "", ENDFUN$ RDS ()$ DRIVE REQUEST:  L LX ?L IрI(恩Ł襁& INSUFFICIENT GOOD RAM FOR COPY!Lyf kngw =kgi)gff#)׭yfwx   i kngx =kgi)gfyf#% File: SAVEPROG.DIS (C) 11/27/81 The Soft Warehouse % % Revised 23-Oct-1981 by T.B. Robinson % % When SAVE is true, modified functions and properties are flagged for saving % SAVE: FALSE$ CR: ASCII (13)$ % % SPACE: " "$ % WHEN NOT EX2, EX2: TRUE EXIT, ENDBLOCK, WHEN MEMBER (EX2, GET ('SAVE, EX1)), EX1 EXIT, PUT ('SAVE, EX1, ADJOIN (EX2, GET ('SAVE ,EX1))), EX1, ENDFUN$ % Replace the PARSE.MUS definition of MAKDEF % FUNCTION MAKDEF (EX1X2, EX3) EXIT EXIT, PUTP (EX1, EX2, EX3), ENDSUB $ % Make sure he meant it! Also defined in EDIT.GRI. % FUNCTION CONFIRM (EX1, READCHAR), LOOP NEWLINE (), PRINT ("Hit RETURN to "), PRINT (EX1), PRINT (", ESC to abort:ACE, NEWLINE (2) EXIT, NEWLINE (), BLOCK WHEN GET (SCAN, 'EDFUN), PRINT ("Function name? "), READCHAR: TRUE, PUT (SCAN, 'EDFUN, SCAN ()), READCHAR () EXIT, PRINTLINE ("Must be a control key  ADIOS DISK COPY UTILITY, 05/11/81  TYPE TO ABORT COPY, OTHERWISE ENTER  SOURCE DRIVE NUMBER: Lw  TARGET DRIVE NUMBER: Lx  wx   TYPE TO BEGIN; TO ABORT COPY; OR A TO CHANGE DISK IN DRIVE 1 ` ? 17H h)8H h(`)d`)P)@cbxL5s `RT $I$I$UUU$$A$ PUTD (PUT (EX1, EX2, COMPRESS (LIST (EX1, EX2))), EX3) EXIT, PUT (EX1, EX2, EX3), ENDBLOCK, WHEN SAVE, FLAGSAVE (EX1, EX2) EXIT, EX1, ENDFUN$ % Add to the list of items to be saved % FUNCTION FLAGSAVE (EX1, EX2), BLOCK II (8)$ % % FUNCTION BS (N), WHEN N EQ 0 EXIT, LOOP PRINT (BS#), N: DIFFERENCE(N,1), WHEN NOT POSITIVE(N) EXIT, ENDLOOP, ENDFUN$ SAVE: TRUE$ OBLIST: LENGTH (OBLIST())$ RDS ()$ % File: CONFIG.EDI 16-July-81 The Soft Warehouse % % Revised 23-Sep-1981 by T.B. Robinson % % Configure an EDIT control function % FUNCTION CONFIGURE ( READCHAR), NEWLINE (2), LOOP PRINT ("Which key? "), WHEN READCHAR () = SP)ԭwx   iL  DISK COPY COMPLETE; MORE (Y/N)? Y N ?L@  L L ? RETURN TO CONTINUE, ESC TO ABORT;    DISK COPY ABORTED; MORE (Y/N)? L@  `  INSERT DISK IN DRIVE 1 `  INSERT Store a definition and flag it % FUNCTION PUTDEF (EX1, LEX1), PUTD (EX1, LEX1), WHEN SAVE, FLAGSAVE (EX1) EXIT, EX1, ENDFUN$ % Store a property and flag it % FUNCTION PUTP (EX1, EX2, EX3), BLOCK WHEN FIRST (EX3) = 'FUNCTION,"), READCHAR (), WHEN SCAN=ESC OR SCAN=CR EXIT, ENDLOOP, NEWLINE (2), SCAN = CR, ENDFUN$ % The top level function to save the flagged functions and properties % FUNCTION SAVEPROG (FILE, EXT, DRIVE, LEX1, EX1, LEX2, PRI, EX2, LEX1), WHEN GETD (EX1) = ADJOIN (EX2, LEX1), EX1 EXIT, WHEN GETD (EX1) AND NOT RDS, WHEN CONFIRM ('redefine), PUTDEF (EX1, ADJOIN (EX2, LEX1)) EXIT EXIT, PUTDEF (EX1, ADJOIN (EX2, LEX1)), ENDFUN$ % Replace the PARSE.MUS, ENDBLOCK, POP (LEX2), ENDLOOP, ENDLOOP, PRINTVALUES (), NEWLINE (2), PRINT: TRUE, PRINTLINE ('"RDS ()$"), WRS (), FILE, ENDFUN$ % Display the value of a variable, if non-trivial % FUNCTION PRINTVAL (EX1), PRINT$", 'PRINT), LINELENGTH (LINELENGTH), ENDFUN$ % Mark end of symbols % OBLIST: LENGTH (OBLIST ())$ SAVE: TRUE$ RDS()$ 1SRG`wWG1`G1jRG1uRGxzRGySGySGfySG{SG{ SG1(SG10SG|8SG1@SG@|HSG1PSG1LG1PG1ZG ZG(ZG0ZG8ZG@ZGHZGPZGXZG`ZGhZGpZGxZGRENLOP1PRTLISTPOINTNUMBERDENNUMPRTDIGDISPLAYLINELENNULLINDENTCURIND*FUN*PRINT$QPRINT$DISPPROPUNPARSEPRTMATHORPRTMATHANDPRTMATHNOTPRTMATHEQPRTMATH:PRINTLISTPRTMATH'PRTMATHIDENTITYUNPARSEFUNPRTMATHFUNCTIONPRTMATHSUBROUTINEPRTMATX2, EX3) EXIT EXIT, PUTP (EX1, EX2, EX3), ENDSUB $ % Make sure he meant it! Also defined in EDIT.GRI. % FUNCTION CONFIRM (EX1, READCHAR), LOOP NEWLINE (), PRINT ("Hit RETURN to "), PRINT (EX1), PRINT (", ESC to abort:EN GETD (EX1), DISPLAY (EX1), PRINTLINE ('$) EXIT EXIT, ENDBLOCK, LOOP WHEN EMPTY (LEX2) EXIT, BLOCK WHEN GET (EX1, FIRST (LEX2)), DISPLAY (EX1, FIRST (LEX2)), PRINTLINE ('$) EXIT, MOVD ('PRINT, '"PRINT$"), MOVD ('"QPRINT$", 'PRINT), LINELENGTH: LINELENGTH (LINELEN + 2), LEX1: OBLIST (), EX1: LENGTH (LEX1), LOOP WHEN NOT EX1 > OBLIST EXIT, PRINTVAL (POP (LEX1)), EX1: EX1 - 1, ENDLOOP, MOVD ('"KENDFUNENDSUBTERMINATOR;$&MATCHDELIMSYNTAXNOT FOUNDINFIXOPERATORLBPMATCHNOPPREFIXBADASSIGNMENTRBPUSED ASREADLIST.PUTPARSEPROPERTYDEFFUNIDENTITYWHENPARSEWHENBLOCKWITHOUTERR?@SYNTAX ERROR! CR <>+-*/^PRTSPACEPRTPA definition of PUTPROP % SUBROUTINE PUTPROP (EX1, EX2, EX3), WHEN GET (EX1, EX2) = EX3 OR GETD (GET (EX1, EX2)) = EX3, EX1 EXIT, WHEN GET (EX1, EX2) AND NOT (SCAN = '$) AND NOT RDS, WHEN CONFIRM ('redefine, READCHAR), PUTP (EX1, ENT), WHEN NOT WRS (FILE, EXT, DRIVE), FALSE EXIT, LEX1: REVERSE (REST ('SAVE)), LOOP WHEN EMPTY (LEX1) EXIT, EX1: FIRST (FIRST (LEX1)), LEX2: REVERSE (REST (POP (LEX1))), BLOCK WHEN MEMBER ('TRUE, LEX2), WH WHEN EX1 = EVAL (EX1) EXIT, NEWLINE (), PRINT (EX1), PRINT (':), SPACES (1), PRINT (''), PRINTLIST (EVAL (EX1)), PRINTLINE ('$), ENDFUN$ % Display the values of all variables % FUNCTION PRINTVALUES ( LEX1, EX1, LINELENGTH)ZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGZGPARSEMUSRPAR)LPAR(COMMA,BELLPRTMATHMAKDEFEX1EX2LEX1 *** REDEFINED: PUTPROPEX3DELIMITEREXITENDLOOPENDBLOC"), READCHAR (), WHEN SCAN=ESC OR SCAN=CR EXIT, ENDLOOP, NEWLINE (2), SCAN = CR, ENDFUN$ % The top level function to save the flagged functions and properties % FUNCTION SAVEPROG (FILE, EXT, DRIVE, LEX1, EX1, LEX2, PRIHLOOPPRTMATHCONDEOLLEX2UNPARSEWHENUNPARSEBLOCK"EDITDISEDTERM SPACE ESCAPPENDLIST1LIST2CHOPTOKENLASTSPLITMAPCMAP2ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#CHARPRTCHARJI\JIHZ\\JJJ)Ju\P\p\\e\P\JJG\\\JJHJJu\P\IIJG]]]J]\YID],]P\\]\\!HI\YGJI ]\!HI\YGJI\IH\1H]J9IJ1H]J']]!HI]AI]1H"]J9IJ1H"]J1]IH4]GJ:]1H@]J9IJ!HJH]r]P]m]T]!HIZ]YGI`]IJf]1H]I1H]I]v]J_9I HH_9IHK___?[_H!HHKr_GJ_9IhJ___JJJH0K_H8\_?[@_!HI_IP\Z_?[_h____H_9I@K H [IH_9I8K!H0K!HHGH_``HHIGJp`j`_f`P`_"``_!HHGYI@`,`*`H/`H8\4` H:` [GHXKI`D`HHK` HHHYI``X`h_H\`IJc`GJHPK!H0KGs`AI0KGbKLb!H JbH JZ!HIbHbJHbb I1GIbGbbG J!H JKHb9IJHLb!HIbHIJbbbbb!HIbKIHb9IKbbb6a!HKGqKJZGI!HKG!HI cKI!HJcKI H.c cH*c&cGKGKKI _8c[Ac6a[a HbbIJJKJ JKJGh^jc^cHbc1GfcaHIoc[GtcZqHIGGeh_6aeaG9LeGJHHe9IPIG>ae6aeaYIee(ah_e!HI\`c`9LLGeYGIee:ah_ KKG@feYI>f8f,fee!HLG!ffeeLLLfeLLLGf!G f!GLffILZZGG f)f$fHLGL/f5fdd KL!HL\`7dLLJLGjfbfh_Zfh_VfH^9LdGJHff9IKLJGjffff123456789TOKLENCOLCONFIRMHit RETURN to , ESC to abort:READWORD$WORD*INSERT**TEXT**ROW**COL**PRETEXT**POSTTEXT**DELETED**SEARCH*EDDISPSCREENLENACCEPTCHARINSERTPRTINSERTDELSPLICE$UPPAGEEDPARSEDELCHARPRTREST$MOVERIGHTCHARDISIn[[f[9IGG\[[[[I9HIJ J[[IIH[ J9HIJ[YH[YGIJG[[!G J[[4[[[[HJHZHI H[>[1HIJ[IH[[G[ JAH[G[ JIJ JGG \H \\\GHpJGHhJGH`JGG,\H8\2\GH(JYJG\\B\YI\\z\j\R\P\Ha\V\JJHIJHd\GHIu\P\p\aGJGHG^IJ\9IJYI^P\^Hd\ H^^GJGIIJG\^^QGJ^QGI^yJ J^^QGJ^QGI^QG^^ H^IGh^IGh^^^QGI^yJ^9I0J _^QG_^yJ^YG_I9IKGIG^___D__YI__^_D]_.___~_v_l_h_H_D_@_HHHZQ_L_HHK__T_IHKZZGGJd_9I`JHZ!HHKr_AIIHzaZ1H]KYIa&a:a&aaaIIaa1H@]K1H]Kc`!HI\`IIZa1H@]KKI Haa1H@]K1H]Kc`aaa\aaa&a:apaIIZa1H@]K1H@]Kb:a&abpaII bZ1H]K1H]K!HI\`c`:a&a6aa)bII2b.bYGJ1H8bK9II!HJBb)GI!HKLb!GIccccbbbbbnbfbkba KKYIbbb~bzGf[Hz_Hn[ JGdddGiLn[Hd9I8IGh^[GddGHn[GddLJ[d9IHJGddLJj[d9IPJG>e[h_&edddd"dGHL9LdGf[yKLLedKG ee)Gn[!Gn[#eeeHn[e6aaGn[Gn[)e;e6e0eh_!HLGHL KL JIJGdpeZedReGHVe9I8Joejebed9LdGJHd7dHte9IXILTOKELINEDPAGERCHARULINETRTOKDELFLCHARGLINEDLINESEARCHNNLINEILINESEARCHFDELBULINEUPAGEDELWKLINEINSRTBTEXTDLINETKELINEETEXTDISPTEXTFUNNAMEEDFUN UNPACK$PACK$INTPACKDIGNUM0WLINE$SPACES$PRINTLINE$LPRINTNULLFUNSCAN$READCHAR$TERMSREADCHARre-editQSCANCURSOREDIUP#BS#'  'xd2[HAHII[IGN[J)G@[IJJGJ^[In[j[f[)GJ9IG!GJGJx[IJJJ1H@]I]]!HI]AI]1H]I9IJ1H]I!HJP\\]JIJGIJJGh^P^F^6^&^ ^^]YI^^]]]]]J]P\IGHI!HI]GI]JP\GHJ]P\I!HI^GI^YG^JH!HI]P\GYI*^-^H0^GP\I=^P\IH@^GIIK^]GIIYI\^V^!HIP\_^Hb^GIIIG^r^]^^x^Y^`~`HIJ``yHIGJG^`HIJGG`h_`HKGh^````[`iKJ`1H@]K1H@]K`````[`iKJ`1H@]K1H@]K`[qKJ`1H]K1H]KG>a:a&a6aaaHIYI.a,a(a&a a!HI\`KHIc`IIZZHIHKKIJGFc2cPbFbh!H0MRnahk!H0MlGppfpjZp0M!HQ`p)RkQhpp~prpLyGQxpQrrhrYIrrrrRr!HKZrrH`hWk!H0Mkrr!HKr9QRrHrGlHrGl1MKGrrrqGQrGrrQGOPlrr$nyGQrQGrkGlOGrssj$nyGQsQGOkssqGQsHlZ H(s$sGlGOLGBh^sZsTsDs>s&hqGk>hQsJs&hyGQnG>h!H0MRnahRr!H0MkGBhsssssvs0MqGjG"vuuuuuGyG@Qu9G@QqG@QuPuMuu1G@Q!G@QuuGqG@QuPuHuuGuGu)G@QuuqGuuPuGuvvvuYIvuuyG@QXGqG@QuHuZvHvGhgL!HXGuqGuvPuGuAQXGGhahZh0MG0MG"ihiYIii!HK iHKi9QiI@QiKG@QAQKGTi0iD_:`YI_Pi[Li*`>iAiHFi:`GHMHXQHPQIHGi_iixilihiYHhQuipi!GtiPhQ!k!H0MkRkHkGkRk HVkkH k!H0MkGh^kkkjk!HQk)Rk1GQ!RkYKkkk!kkOcGkGGkkk_kYIkkHk9R1RGGGkGk_lGHl!GQGhBl llkYIllHkYIr6rQQQKgyrnrFrYIhrfr`rTrRrR!HKZrHKZcrH`hWk!H0Mk!HKtr9QRr`|t HtoG*o!HQkIKRJGGtltGGkGGt"k kt Hk kGh^*uuuPt utttXlR,qZtttXlR,qtKt!GQItQ)MxQqKtQqHxQ uuqGou LkcQoHuKoyG,quQG$u*oQGZk9u.uqGk4uPl;uHDu@uGlGkGGtu^uTujyGQZuMQaueu kqKjuKHepuKQwukH0M~g1GXGGg9GXGYG0MGggYIghggg!GXGGg)GXGYGGggYIggghgggtg0M!H0MgGK!HKgHKZgGGXGYGK0MGhgYIggLhggGGXGYGLGh hYIhhLhghggGGBh*h"haH&h!G0M/h0MH>h4hG:hZqH&h)G0M1MGBh\hVhNhQGRhYH0MYhP0Mah0MG0MGhhlhYIhhthyhG`LOiI!HQjAMxQQ!HQi!HQxQ!HxQjQLI!HpQG!HHGYIjjG*`XKLIHpQxQQQQQQQHG2kkk kjjjjqOGjiKjKQQQZLOkkjQHpQkjGk)GQHO%k"k kOqO'kiK,kKHeZOLGGmGljmjmmXlel|j!HQkYImlmHjGnnnZnVnLn>nnnmmOqGk0MWkmOyGQn9GQqGQ nMlO;n4n(n$nnOqGk0MIQyGQ.nQGOkWk$nOGl!HODnQGHnI0M!H0MRnP0Mahkunhnbn0MyGQnqGQnnHlZ HnzGLkqGQpH0MZpGG0McG!H0MlI0MGh^ppjpG!HQkpG HIpGlpGGlGh^jppp!HQp)RxQQ!HQp!GQqpGjppyRpc|jGpGhnqdq^qXqLq0q qqG!HQj!HQ&q)RxQ,q)GQ!HxQ6qQGGtQGBtIQoatVtPt6ryGQG!HK\tKkHvtftqKltKHertKoHHhQ~iaGhQiKGhQYIiiIHhQiG*`XKHhQGj_jjfjjjjjiIYI~j|j$jjj jiiiiiH0K!HIiQ!H0KGii!HIG HjiGi)Gi1GxQGj9GxQYIjjQjGQQQH jqHQYItj*jSj:j0jQH6j9IQMj>jIIBj1HHHj9IO1HHHjajVjQH\j9IQHjjfjGH1HHpj9IOwjG*vIRGBhvvvIM0McahvH0MWkGvqvvvvYIvv RzvvGRuHzv!HRv1GRYIvv_vGIv)GRIIIR@QGXwRwLw{&{r_;{_,{!H0K2{IQ6{9I8S K0KQHH{D{9IH9I SIHR{S9IHY{]{]Hb{kH8\!HIl{IP\Z!H(Sx{OGDGOGLGOGTGOG\GOGdGOGlGOGtGOG|GOGGOGGOGGOGGOGȱGOGGOGGOGGOGGOGįGOG̯GOGԯGOGܯGOGGOGGOGGOGGOGGOG GOGGOGGOG$GOG,GOG4GD8IpL@L H`LHTGXLP\HPLXdHHL`lH@LhGKG8IpJGGtxxHJGXGGJGGGIJZG|JG HPIKIJȲKZxJXIG8I8Iܲ8JGPGزGԲGXI̳ KGGZ<G GKG G8I(K4$ KG88I,HZI@HJG<GPIpGPIGLlPG\IhxJdIG`GXGTJxJ|JGtGGIHGIZGGKJHGԵ8IGGIGIPJHJ@Jĵ8Jȵ0J̵8IܵPJGصGG䵜\@HKZIGpIyH~yHLf HyyqKRyHK8ZG0MIyyyIyQQG0MyyI0MQGpHZyyIyQHhy1H0Mpj!HRyHRpH!HpHh1MHpHGzxzzzzzzzxznzdzZzPzJzFz@z6z,z"zzzaGxQIxxQIH(zH9IHIH2zH9IHIH