home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / QBAS / PROGEN71.ZIP / PROGEN71.DOC < prev    next >
Text File  |  1991-10-09  |  21KB  |  598 lines

  1.  
  2.               PROGEN71
  3.  
  4.       (PRO)GRAM (GEN)ERATOR FOR MICROSOFT ISAM FILES
  5.         By:
  6.                Raymond E Dixon
  7.                11660 VC Johnson Rd.
  8.             Jacksonville, Fl 32218
  9.                (904) 765-4048
  10.  
  11.     FILES created BY PROGEN71:
  12.  
  13.     CREATE.BAT ' compile and link the last generated program
  14.     EDIT.BAT   ' load prolib71.qlb and last generated program
  15.  
  16.     YOUR PROGRAM NAME.BAS 'source code error free!
  17.  
  18.     'if you change your code who knows.
  19.     'remember PROGEN71 erases your old database if you use the same
  20.     'name to recreate your database because ISAM can't handle changes
  21.     'in type structures so if you add or delete fields ISAM can't read
  22.     'old file.
  23.     'you can create or delete key fields within your program as long
  24.     'as you use existing fields.
  25.  
  26.  
  27.     YOUR PROGRAM NAME.FLD 'field data
  28.     YOUR PROGRAM NAME.F1  'database field index
  29.     YOUR PROGRAM NAME.F2  'database field index
  30.  
  31.      FILES used by SAMPLE '  sample program field data
  32.  
  33.     SAMPLE.FLD 'field data
  34.     SAMPLE.F1  'database field index
  35.     SAMPLE.F2  'database field index
  36.  
  37.      FILES included with PROGEN71
  38.  
  39.      PROGEN71.EXE 'the source generator with source code
  40.      PROSCN71.EXE 'screen generator with source code
  41.  
  42.      PROSRC71.ZIP 'source code for progrn71 and proscrn71 
  43.      
  44.      PROLIB71.BAT 'creates LIB and QLB fiiles with asm function
  45.      PROLIB71.BAS 'bas function and subs needed by source
  46.  
  47.      PROASM71.BAT 'creates obj and lib files to link with PROLIB71
  48.      PROASM71.ASM 'asm function and subs needed by source
  49.  
  50.      EDA.BAT      'loads user program and asm lib function
  51.      EDP.BAT      'loads user program and PROLIB71.QLB with
  52.           'all function and subs.
  53.  
  54. ---------------------------------------------------------------
  55.             (a few words from me)
  56.  
  57.       This program came about when I got tired of search
  58.     and replace every time I needed a new database for
  59.     myself or a friend. I feel like most programmers tend
  60.     to modify existing code rather than start from scratch
  61.     so I decided why not let the computer do all the work
  62.     for me. I know there are plenty of programs out there
  63.     that will write data bases for you but most were copyrighted
  64.     (and or) carried a lots of excess baggage that I never
  65.     needed. PROGEN writes complete ready to run programs
  66.     that need no editing.
  67.     
  68.       All the subs and function or included with the
  69.     source code. You can edit or change any part of your
  70.     program to suite your needs. You can use PROGEN to
  71.     wright a program to write your on programs with, the
  72.     bulk code that's in PROGEN71 was written with PROGEN
  73.     it's self. Just write a module to read all common code
  74.     in and add the new code where needed and write to file.
  75.     
  76.       Remember all programs created with PROGEN can be
  77.     recreated in seconds unless deleted from database,
  78.     progen writes all batch files needed to compile and
  79.     link the programs written by PROGEN. Even though
  80.     this version has some limitation such as max 10
  81.     fields, it can write almost any database needed for
  82.     most, you can easily add fields to the source code and
  83.     change screens and edits to reflect the changes.
  84.     
  85.       The version I use allows 250 fields and 20 screens
  86.     for data. I will release a my personel version soon if
  87.     there's any interest from the users out there !. I may
  88.     charge a small fee for my services to cover updates
  89.     and shipping (unless you send me some good code.
  90.       
  91.       There seems to be a shortage of free code for users 
  92.     anymore so lets see if we can swap some ideas around 
  93.     like the good old days of CP/M and TRSDOS.
  94.  
  95.       I know it's hard to write basic subs because there are
  96.     so mamy on the market that are (c) copyrighted !! if you
  97.     wright more than a one line program somebody claims it 
  98.     was in their lib but I find 90% of their code in some
  99.     book somewhere, I even found code from a popular tool.box
  100.     in a 15 year old book a few days ago. I not sure it's
  101.     possible to copyright a sub routine , maybe sub programs
  102.     that do something in a special way that used a special
  103.     interface that no one could easly come up with.
  104.     
  105.       Don't get me wrong I beleve everone should be able to
  106.     protect there work with a copyright if it's a program
  107.     that does something usefull. But if you release the code
  108.     to the public copyrighting seems to be a little silly to
  109.     me. If you really won't to protect your code why release
  110.     it. Microsoft don't give out the code for QuickBasic or
  111.     any of their programs that they won't protected.     
  112.  
  113.     
  114.       I would release the source for PROGEN but every one seems
  115.     to want to make a buck now days on anything and everything
  116.     but I may release this  version later on if any one seems
  117.     to want it . The source code generated by PROGEN is free
  118.     to use, sell or GIVEAWAY!. Some ASM code was modified for
  119.     QBX FAR STRING support and all code supports FAR AND NEAR
  120.     and is not compatible with QB4.5 which. ISAM is only available
  121.     with PDS,QBX and BC 7.0 and above.
  122.       
  123.       I have a PROGEN45 keyindex for QB4.5 if anyone wants it just
  124.     write me or give me a call and I'll send it to you for the cost
  125.     of shipping and handling plus disk. From the user's standpoint
  126.     there's no difference. The main difference is the number of
  127.     records (max 32k) and all the code is written in Quickbasic.
  128.  
  129.         PROGEN45 was used to create PROGEN71.
  130.  
  131.       If anyone out there makes improvements please send me a
  132.        copy or has any suggestions let me know and I will see if I
  133.        can improve in the meantime I just write for the fun of it
  134.        and have for over 10 years. My first computer was a TRS80
  135.        MODEL III which I still own and use.
  136.  
  137.       I use to write in FORTRAN until Quickbasic came along,
  138.        "C" never made any sense to me, you have to tell it everything
  139.        the computer should already know and MICROSOFT'S PDS is just
  140.        as fast and assembly is just as easy to wright as "C" with a
  141.        few libraries unless you intend to write for different computers.
  142.        
  143.      With 70 million MSDOS PC out there why. 
  144.  
  145.  I hope this program will help you in some way!
  146.  
  147.             Thanks for trying PROGEN71.
  148.  
  149.                     Raymond E Dixon
  150.                     11660 VC Johnson Rd.
  151.                     Jacksonville, FL 32218
  152.                     (904) 765-4048
  153. PS. source code included.
  154.     send me some good code. asm or bas
  155. ---------------------------------------------------------------
  156.       
  157.     There is some help for sub and function used in the
  158.      code generated by PROGEN but most is easy to use without
  159.      any or very little explanation. The PROASM71.ASM code is
  160.      compatible with UIASM.ASM with my code added.
  161.       
  162.       ISAM manager code is all in BASIC.
  163.  
  164.   SUB ISM (cmd$, IndexNum, Retcode) STATIC
  165.  
  166.   This subprogram is designed to facilitate the quick
  167.   look up of data in a large file through the use of keys
  168.   in a ISAM database file. The format of the calling
  169.   subprogram is:
  170.   
  171.  CREATEINDEX INDEXNUMBER,"FIELDNAME" [,"FIELDNAME2","ETC."]
  172.  
  173.  SETINDEX INDEXNUMBER,"FIELDNAME" ' field name must have been created
  174.  
  175.  DELETEINDEX INDEXNUMBER,"FIELDNAME"
  176.  
  177.   PROGEN creates all indexs needed. 
  178.  
  179.  'remember you can create and delete indexes on the fly with ISAM
  180.  such as temporary for reports as long as the fields are predefined
  181.  in the open database with the type statement.
  182.  
  183.  CMD$ = "F" Index Find First
  184.     "L" Index Find Last
  185.     "EQ" Index Search EXACT MATCH
  186.     "GE" Index Search EXACT MATCH or NEXT GREATER
  187.     "A" Index Add
  188.     "D" Index Delete ' deletes one record not index
  189.     "N" Index Next
  190.     "P" Index Previous
  191.   
  192.   IndexNum = ISAM file number
  193.  
  194.   RetCode  = 0 if no records exist
  195.          1 if at least 1 record in index
  196.  
  197.   CALL ISM (cmd$, IndexNum, Retcode) STATIC
  198.  
  199.   USE:
  200.       KEY$ = "raymond" ' in PROGEN key$ is COMMOND SHARED for ease of use
  201.     
  202.     CALL  "EQ",indexnumber,retcode
  203.     if retcode = 1 then
  204.     
  205.     retrieve indexnumber
  206.     lprint RecField.lastname
  207.     
  208.     else
  209.     
  210.     exit (sub) or (function) or (do) or (for) ' just don't print
  211.     
  212.     end if
  213.      
  214. ---------------------------------------------------------------
  215.         *** END SUB or FUNCTION ***
  216. ---------------------------------------------------------------
  217.  
  218.   SUB DialogBox (Ques$(), Before, After, LENGTH, Ffgd, Fbgd, Gfgd, Gbgd, sect, Answer$, Ek)
  219.  
  220.   Before   -  Textlines for question before input
  221.   After    -  Textlines for question after input
  222.   Length   -  Length of input
  223.   Ffgd     -  Frame foreground
  224.   Fbgd     -  Frame background
  225.   Gfgd     -  General Foreground
  226.   Gbgd     -  General background
  227.   Sect     -  Section of the screen to display on
  228.           0=Top,1=Center,2=Bottom
  229.   Answer$  -  Answer string
  230.  
  231.   Ek       -  Exit Key
  232.           5=Return, 7=ESC
  233.  
  234.   SUB DialogBox (Ques$(), Before, After, LENGTH, Ffgd, Fbgd, Gfgd, Gbgd, sect, Answer$, Ek)
  235.  
  236. ---------------------------------------------------------------
  237.         *** END SUB or FUNCTION ***
  238. ---------------------------------------------------------------
  239.  
  240.  function:   userNformat(number$,format$)
  241.  
  242.        numeric formats allow higest
  243.        value of format position.
  244.  
  245.       format$ = "99999.99" decimal   ( any decimal position)
  246.       format$ = "99" numbers only  < (99 max) each digit = to max value
  247.       format$ = "19" (19) is max value
  248.  
  249.  to print:
  250.  
  251.       number$ = userNformat(number$,format$)
  252.       print number$;
  253.  or:
  254.       print userNformat(number$,"9999.99");
  255.  
  256.       may use basic print using "####.##";VAL(number$) for decimal numbers
  257.       and integer. decimal  pos and length optional
  258.  
  259.  
  260.        USE LOCATE ROW,COLUMN
  261.  
  262.        maybe passed by parameters if you like to add to parms
  263.  
  264.        column = Column pos to start printing
  265.        Row = Row to start printing
  266.  
  267. FUNCTION FEN$ (savescreen%,EFG, EBG, work$, format$, ExitCode, UPflag, PGUPflag, DNflag, PGDNflag, RETflag, TABflag, ESCflag, F10flag)
  268.  
  269.        ExitCode = VALUE EXIT  1 TO 7
  270.  
  271.        set flags to enable  to exit on key
  272.  
  273.        UPflag     = True  ,exitcode =  1
  274.        PGUPflag   = True  ,exitcode =  2
  275.        DNflag     = True  ,exitcode =  3
  276.        PGDNflag   = True  ,exitcode =  4
  277.        RETflag    = True  ,exitcode =  5
  278.        TABflag    = True  ,exitcode =  6
  279.        ESCflag    = True  ,exitcode =  7
  280.  
  281.        ESC key restores field if True or False
  282.  
  283.    sample how to handle exitcode after input routine (see program).
  284.  
  285.    SELECT CASE ExitCode
  286.  
  287.        CASE 1 'what to do if uparrow key exit
  288.            could be
  289.            GOTO previous entry
  290.  
  291.        CASE 2 'what to do if pageup key exit
  292.  
  293.        CASE 3 'what to do if downarrow key exit
  294.            could be
  295.            GOTO next entry
  296.        CASE 4 'what to do if pagedown key exit
  297.  
  298.        CASE 5 'what to do if enter key exit
  299.         could be accept entry
  300.        CASE 6 'what to do if tab key exit
  301.            'could be return to menu
  302.  
  303.    END SELECT
  304.  
  305. ---------------------------------------------------------------
  306.  
  307. ---------------------------------------------------------------
  308.  
  309.  
  310. FUNCTION FES$ (savescreen%,EFG, EBG, work$, format$, caseflag, ExitCode, UPflag, PGUPflag, DNflag, PGDNflag, RETflag, TABflag, ESCflag, F10flag)
  311.  
  312.   IF ANYONE MAKES ANY INPROVEMENTS I WOULD LIKE YOU TO RENAME THIS SUB
  313.   TO A NEW NAME. AND IF YOU WOULD SEND ME A COPY.
  314.  
  315.        formated input routine with user format
  316.  
  317.        assign values before calling routine
  318.  
  319.        work$ =""  or string to edit
  320.  
  321.        numeric formats allow higest
  322.        value of format position.
  323.  
  324.       format$ = "99" numbers only  < (99 max) each digit = to max value
  325.       format$ = "19" (19) is max value
  326.       format$ = "999-99-9999" SS number
  327.       format$ = "999-9999"       7  digit phone
  328.       format$ = "(999) 999-9999" 10 digit phone
  329.       format$ = "19/39/99"  date format
  330.       format$ = "########" alphanumeric set for 8 characters (maybe more or less)
  331.       format$ = "@@@@@@@@" alpha only   same as above
  332.       format$ = "Y/N:*"    force YN answer.
  333.       format$ = "M/F:|"    force MF answer.
  334.       format$ = "~"       'force enter key for prompts or other exit key.
  335.       format$ = may be any format you can create in a basic string
  336.         even you can include the Prompt if you like.
  337.  
  338.       format$ = "Test Data: 99" 'this format will print
  339.          Test Data: your value passed
  340.                 in the the length of 2
  341.                 Seting numbers 1 to 99.
  342.  
  343.        USE LOCATE ROW,COLUMN
  344.  
  345.        maybe passed by parameters if you like to add to parms
  346.  
  347.        column = Column pos to start printing
  348.        Row = Row to start printing
  349.  
  350.        locate 12,24
  351.  
  352.  work$ = FES$ (savescreen%,EFG, EBG, work$, format$, caseflag, ExitCode, UPflag, PGUPflag, DNflag, PGDNflag, RETflag, TABflag, ESCflag, F10flag)
  353.  
  354.        ExitCode = VALUE EXIT  1 TO 7
  355.  
  356.        set flags to enable  to exit on key
  357.  
  358.        UPflag     = True  ,exitcode =  1
  359.        PGUPflag   = True  ,exitcode =  2
  360.        DNflag     = True  ,exitcode =  3
  361.        PGDNflag   = True  ,exitcode =  4
  362.        RETflag    = True  ,exitcode =  5
  363.        TABflag    = True  ,exitcode =  6
  364.        ESCflag    = True  ,exitcode =  7
  365.  
  366.        ESC key restores field if True or False
  367.  
  368.     force case if set.
  369.             caseflag = 0 any case
  370.                  = 1 for upper only
  371.                  = 2 for lower only
  372.     
  373.     savescreen = 1 background restored on exit
  374.     savescreen = 0 no background saved
  375.  
  376.    FUNCTION FES$ (savescreen%,EFG, EBG, work$, format$, caseflag, ExitCode, UPflag, PGUPflag, DNflag, PGDNflag, RETflag, TABflag, ESCflag, F10flag)
  377.  
  378.    sample how to handle exitcode after input routine (see program).
  379.  
  380.    SELECT CASE ExitCode
  381.  
  382.        CASE 1 'what to do if uparrow key exit
  383.            could be
  384.            GOTO previous entry
  385.  
  386.        CASE 2 'what to do if pageup key exit
  387.  
  388.        CASE 3 'what to do if downarrow key exit
  389.            could be
  390.            GOTO next entry
  391.        CASE 4 'what to do if pagedown key exit
  392.  
  393.        CASE 5 'what to do if enter key exit
  394.         could be accept entry
  395.        CASE 6 'what to do if tab key exit
  396.            'could be return to menu
  397.  
  398.  
  399.     END SELECT
  400.  
  401. ---------------------------------------------------------------
  402.         *** END SUB or FUNCTION ***
  403. ---------------------------------------------------------------
  404.  
  405.  FUNCTION MenuWindow (ROW, col, MenuStr$, title$, MenuFore, MenuBack, Reversed)
  406.     menuwindow saves and restores screen
  407.  
  408.  Title$ = "Title",  maybe null ""
  409.  
  410.      if row  <= 1 then menu is centered on screen vert
  411.      if column <= 1 then menu is centered on screen horiz
  412.      if col is to large to fit then is adjusted
  413.      if row is to large to fit then is adjusted
  414.      if row and col = 0 then menu is centered on screen
  415.  
  416.  
  417.    select = MenuWindow (ROW, col, MenuStr$, title$, MenuFore, MenuBack, Reversed)
  418.  
  419.  Menu$ = "A - menu1\B - menu2\C - menu3\D - Menu4\"
  420.  or:
  421.        menu$="1 - Option\"
  422.  menu$=menu$+"2 - Option\"
  423.  menu$=menu$+"3 - Option\"
  424.  menu$=menu$+"4 - Option\"
  425.  
  426.       first letter must be different and Caps or Num
  427.       to allow for single key selection.
  428.  
  429.  MENUSEL = MenuBar(24, 3, BO$, BLACK, WHITE, RED, IRV)
  430.   |                |   |  |     |       |     |     |_ bar color
  431.   |                |   |  |     |       |     |_ highlite color
  432.   |                |   |  |     |       |_ background color
  433.   |                |   |  |     |_ foreground color
  434.   |                |   |  |_ menu string
  435.   |                |   |_ start column
  436.   |                |_ row posisition
  437.   |_ pos return value
  438.  
  439.    SELECT CASE menusel
  440.  
  441.        CASE 1 'what to do if menu number 1
  442.  
  443.        CASE 2 'what to do if menu number 2
  444.  
  445.        CASE 3 'what to do if menu number 3
  446.  
  447.        CASE 4 'what to do if menu number 4
  448.  
  449.     END SELECT
  450.  
  451. ---------------------------------------------------------------
  452.         *** END SUB or FUNCTION ***
  453. ---------------------------------------------------------------
  454.  
  455.  
  456.    SUB Message (Text$(), lines, Border, Bf, Bb, GF, gb)
  457.  
  458.   Text1$   -  Text to display
  459.   lines   -  Text ITEMS to display
  460.   Border  -  Border type
  461.   Bf      -  Border foreground color
  462.   Bb      -  Border backgroynd color
  463.   Gf      -  Global foreground
  464.   Gb      -  Global background
  465.  
  466. ---------------------------------------------------------------
  467.         *** END SUB or FUNCTION ***
  468. ---------------------------------------------------------------
  469.  
  470.  
  471.  FUNCTION SelBox (List$(), numele, lenview, diswide, fg, bg, rev) STATIC
  472.  
  473. ---------------------------------------------------------------
  474.         *** END SUB or FUNCTION ***
  475. ---------------------------------------------------------------
  476.  
  477. SUB AskQuestion (Text$(), numlines, Border, Bf, Bb, GF, gb, Ques$, ans$)
  478.  
  479.    text$(1) = "YES, go ahead and delete   " + cust.Firstname
  480.    text$(2) = "NO, I don't want to delete " + cust.Firstname
  481.  
  482.      Ques$ = "(Y/N)"
  483.      answ$ = "YyNn"
  484.  
  485.     AskQuestion text$(), 2, 1, BLACK, WHITE, BLACK, WHITE, Ques$, answ$
  486.  
  487.     IF UCASE$(answ$) = "Y" THEN
  488.     ELSE
  489.     END IF
  490.  
  491. ---------------------------------------------------------------
  492.         *** END SUB or FUNCTION ***
  493. ---------------------------------------------------------------
  494.  
  495. sub: message
  496.  
  497.      text$(1) = "There are no RECORDS"
  498.      text$(2) = "in the database to Edit, Update!"
  499.      text$(3) = ""   'BLANK LINE
  500.      text$(4) = "Press any key to continue"
  501.  
  502.      Message text$(), 4, 3, BLACK, WHITE, BLACK, WHITE '  DIsplay Message
  503.  
  504. ---------------------------------------------------------------
  505.         *** END SUB or FUNCTION ***
  506. ---------------------------------------------------------------
  507.  
  508. function:  menubar
  509.  
  510.      BO$ = "    Next    Previous     Search    Edit   Dial" + CHR$(255) + "phone1  Dial" + CHR$(255) + "phone2   Menu "
  511.  BRV = MenuBar(24, 3, BO$, BLACK, WHITE, RED, IRV)
  512.   |            |   |  |     |       |     |     |_ bar color         
  513.   |            |   |  |     |       |     |_ highlite color
  514.   |            |   |  |     |       |_ background color
  515.   |            |   |  |     |_ foreground color
  516.   |            |   |  |_ menu string
  517.   |            |   |_ start column
  518.   |            |_ row posisition
  519.   |_ pos return value
  520.  
  521.  end of menubar
  522.  
  523. ---------------------------------------------------------------
  524.         *** END SUB or FUNCTION ***
  525. ---------------------------------------------------------------
  526.  
  527. drawbox 'a basic sub uses drawwind in asm lib
  528.  
  529.    SUB DrawBox (toprow, LeftCol, Width, height, FrameType, FrmFgd, FrmBgd, Fill, FillFgd, FillBgd,shadow)
  530.     
  531.     frametype = 0 'clears frame
  532.             1 'single line
  533.             2 'double line
  534.             3 '
  535.             4 'wide bar top and bottom ,open sides
  536.        
  537.        fill  =   0 'draws frame only
  538.                  1 'clear inside window  
  539.  
  540.       shadow  =  0 'no shadow
  541.                  1 'draws shadow
  542.  
  543.  ---------------------------------------------------------------
  544.         *** END SUB or FUNCTION ***
  545. ---------------------------------------------------------------
  546. code below written in asm.
  547.  
  548. ;--------------------------------------------------------------
  549. ;
  550. ;  prolib71.asm
  551. ;
  552. ;  Copyright (C) 1989 Microsoft Corporation, All Rights Reserved
  553. ;
  554. ;  GetCopyBox   : Gets screen box info and places into string variable
  555. ;  PutCopyBox   : Puts screen box info from string variable onto screen
  556. ;
  557. ;DECLARE SUB getcopybox (row1%, col1%, row2%, col2%, buffer$)
  558. ;DECLARE SUB putcopybox (row%, col%, buffer$)
  559. ;DECLARE SUB attrbox (row1%, col1%, row2%, col2%, attr%)
  560. ;
  561. ;  Copyright (C) 1991 Raymond E Dixon
  562. ;                       (see windemo.bas for examples)
  563. ;  Colorwind    : Changes the color attributes of all characters within a box
  564. ;               : Fill with character within a box, space clears window
  565. ;
  566. ;  PNC          : print in color
  567. ;  PNC string$,row,column,foreground,background
  568. ;
  569. ;  Drawwind     : draw a window with or without border and clear window
  570. ;
  571. ;  Captal       : converts first char to U/case and others to l/case
  572. ;               : needed for proper name format
  573. ;       From    :"rAyMoNd e DIXON"
  574. ;       To      :"Raymond E Dixon"
  575. ;
  576. ;  ClrKeyBuf    : clears keyboard buffer
  577. ;
  578. ;       "all sub work with far or near strings"
  579. ;
  580. ;DECLARE SUB Colorwind (row1%, col1%, row2%, col2%,char%,fillflag%, foreground%, background%)
  581. ;DECLARE SUB drawwind (row1%, col1%, row2%, col2%, frame%,clear%)
  582. ;DECLARE SUB pnc (a$, row%, col%, foreground%, background%)
  583. ;DECLARE SUB captal (a$)         'CONVERT FIRST LETTER TO UPPER CASE
  584.  
  585. ; flag function and subs from PC mag. (not used in my programs)
  586.  
  587. ;DECLARE SUB setflag(flag%)      'SET FLAG
  588. ;DECLARE FUNCTION getflag(flag%) 'GET STATE OF FLAG
  589. ;DECLARE SUB resetflag(flag%)    'RESET FLAG
  590. ;DECLARE SUB clearall            'CLEAR ALL FLAGS
  591.  
  592.  
  593. ;DECLARE FUNCTION CPUcheck% 1 = 8086/88, 2 = 80286, 3 = 386/486
  594.  
  595. ;-----------------------------------------------------------------------------
  596.  
  597.  
  598.