home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 208_01 / eterm.c < prev    next >
Text File  |  1987-10-13  |  16KB  |  475 lines

  1. /*
  2. HEADER:        CUG208;
  3. TITLE:        'e' for CP/M68K
  4. VERSION:    1.48+
  5.  
  6. DESCRIPTION:    "a screen editor";
  7.  
  8. KEYWORDS:    editor;
  9. SYSTEM:        CP/M68K, V1.2;
  10. FILENAME:    e/eterm.c
  11. WARNINGS:    "the default value is for systems with 128K bytes
  12.          of memory or more";
  13. SEE-ALSO:    cpm68k.c, e68k.doc, CUG VOL 133;
  14. AUTHORS:    G.N.Gilbert('e'), J.W.Haefner(for DeSmet C on MSDOS and UNIX)
  15. CODER:        Yoshimasa Tsuji
  16. COMPILERS:    DRI C(Alcyon C) for CP/M68K;
  17. */
  18. /*
  19.     FUNCTIONS: terminit,terminal,gotoxy,deleteline,linedelete,delpage,
  20.            clear, insertline,standout,standend,keytranslate,help
  21.  
  22.     PURPOSE: terminal dependent functions
  23.     TERMINALS SUPPORTED:
  24.     adm31, kaypro, adds, vt52, haze, h19, adm3a, beehive, vt100
  25.     (televideo, ibm, ansi fall into somewhere)
  26. */
  27. #define adm31    1
  28. #define kaypro 0
  29. #define adds    0
  30. #define vt52    0
  31. #define haze    0
  32. #define h19    0
  33. #define adm3a    0
  34. #define beehive 0
  35. #define vt100    0
  36.  
  37. #include "e.h"
  38.  
  39. /*-------------------------OUTPUT TO SCREEN---------------------------*/
  40. char *Standout;
  41. char *Standend;
  42. char *csraddr;
  43. char *insline;
  44. char *delline;
  45. char *lindel;
  46. char *pagedel;
  47. char *Clear;        /* clear screen string */
  48. char *initstr = "";
  49. char *finistr = "";
  50. char *termname;
  51.  
  52. terminit()
  53. {
  54.             /* initialise tty, esc sequence, set raw */
  55. #if adm31
  56.  Standout = "\033)";
  57.  Standend = "\033(";
  58.  csraddr = "\033=";
  59.  insline = "\033E";
  60.  delline = "\033T";
  61.  lindel = "\033R";
  62.  pagedel = "\033Y";
  63.  Clear = "\033*";
  64.  termname = "|for ADM31";
  65. # endif
  66.  
  67. # if h19 | adm3a | beehive
  68. #    if beehive
  69.  Standout = "\033l";
  70.  Standent = "\033m";
  71. #     else
  72.  Standout = "\033p";
  73.  Standend = "\033q";
  74. #     endif
  75. #     if adm3a
  76.  csraddr = "\033=";
  77. #     else
  78.  csraddr = "\033Y";
  79. #     endif
  80.  insline = "\033L";
  81.  delline = "\033K";
  82.  lindel = "\033M";
  83.  pagedel = "\033J";
  84.  Clear = "\033E";
  85. #    if h19
  86.  termname = "|for H19";
  87. #    endif
  88. #    if adm3a
  89.  termname = "|for ADM-3A";
  90. #    endif
  91. #    if beehive
  92.  termname = "|for Beehive";
  93. #    endif
  94. # endif
  95. # if vt52 | adds
  96.  Standout = "\033U";
  97.  Standend = "\033T";
  98.  crsaddr = "\033Y";
  99.  insline = "\033L";
  100.  delline = "\033K";
  101.  lindel = "\033M";
  102.  pagedel = "\033k";
  103. #  if vt52
  104.  initstr = "\033\060@\033\071P";
  105.     /* set foreground to normal
  106.      * set background to reverse
  107.      */
  108.  finistr = "\033\071@";
  109.     /* set background back to normal*/
  110.  termname = "|for DEC VT52";
  111. #  endif
  112. #  if adds
  113.  initstr = "\033\071@\033\060P";
  114.  finistr = "\033\060@";
  115.  termname = "|for ADDS";
  116. #  endif
  117. # endif
  118.  
  119. # if vt100
  120.  Standout = "\033[1m";
  121.  Standend = "\033[0m";
  122.  crsaddr = "\033[";
  123.  insline = "\033[1L";
  124.  delline = "\033[K";
  125.  lindel = "\033[1M";
  126.  pagedel = "\033[J";
  127.  termname = "|for DEC VT100";
  128. # endif
  129.  
  130. # if kaypro
  131. /*
  132.     specific to the KayPro 10
  133.     THANKS to Don Colner for providing these codes and key assignments!
  134. */
  135.  Standout = "\033B1";
  136.  Standend = "\033C1";
  137.  crsaddr = "\033=";
  138.  insline = "\033E";
  139.  delline = "\030";
  140.  lindel = "\033R";    /* (0,y), ** , (0,y) */
  141.  pagedel = "\027";
  142.  termname = "|for Kaypro 10";
  143. # endif
  144. # if haze
  145. /*
  146.  specific to the HAZELTINE range of terminals.
  147.     NOTE ALSO that the terminal must be set to use TILDE as the lead -in
  148.     character, not Escape.
  149.  screen control characters for Hazeltine 1420 (and probably other
  150.     Hazeltines as well)
  151.  */
  152.  termname = "|for Hazeltine";
  153.  Standout = "\0134\031";
  154.  Standend = "\0134\037";
  155.  csraddr =  "\0134\021"; /* x, y */
  156.  insline = "\0134\033"; /* (0,y), ** */
  157.  delline = "\0134\017";
  158.  lindel = "\0134\023"; /* (0,y), ** */
  159.  pagedel = "\0134\030";
  160. #endif
  161.  
  162.  
  163.     raw();     /* set tty input in raw mode */
  164.     putstr(initstr);
  165. }
  166.  
  167. termfini()    /*restore terminal to 'normal' state.  Called once before
  168.           program exits */
  169. {
  170.     putstr(finistr);
  171.     noraw();    /* restore normal tty mode */
  172. }
  173.  
  174. terminal()    /*display name of terminal*/
  175. {
  176.     putstr(termname);
  177. }
  178.  
  179. gotoxy(x,y)    /*move cursor to column x, line y {top left is (0,0) */
  180. int x,y;
  181. {
  182.     putstr(csraddr);
  183. # if haze
  184.     putch(x), putch(y);
  185. # else
  186. #  if vt100
  187.     uspr(y+1);
  188.     putch(';');
  189.     uspr(x+1);
  190.     putch('H');
  191. #  else
  192.     putch(y+32);
  193.     putch(x+32);
  194. #  endif
  195. # endif
  196. }
  197.  
  198. clear()    /* clear stdscr */
  199. {
  200.     delpage(0);
  201. /*
  202.     putstr(Clear);
  203.  */
  204. }
  205.  
  206.  
  207. deleteline(x,y)    /*clear to spaces all characters on line y from column x
  208.             to the right edge of the screen, inclusive.
  209.             Leave cursor on left most blank */
  210. int x, y;
  211. {
  212.     gotoxy(x,y);
  213.     putstr(delline);
  214.     gotoxy(x,y);
  215.  
  216. }
  217.  
  218. linedelete(y)    /*delete the line y.  All following lines move up one.
  219.             Leave cursor at start of line y */
  220. int y;
  221. {
  222.     gotoxy(0,y);
  223.     putstr(lindel);
  224.     gotoxy(0,y);
  225. }
  226.  
  227. delpage(y)    /*clear to spaces line y and all following lines.  Leave
  228.             cursor at the start of line y */
  229. int y;
  230. {
  231.     gotoxy(0,y);
  232.     putstr(pagedel);
  233. }
  234.  
  235. insertline()    /*move all lines below line on which cursor is, down one,
  236.             losing last line.  New cursor line is blank, with
  237.             cursor at start of line */
  238. {
  239.     putstr(insline);
  240. }
  241.  
  242. standout()    /* stand out all subsequent characters */
  243. {
  244.     putstr(Standout);
  245. }
  246.  
  247. standend()    /* display all subsequent characters normally */
  248. {
  249.     putstr(Standend);
  250. }
  251.  
  252.  
  253. /*----------------------INPUT FROM KEYBOARD-----------------------------*/
  254.  
  255. # define ctrl(letter) ('letter' & 037)
  256. #define ESC     033
  257.  
  258.  
  259. keytranslate()    /*defines the terminal key codes which perform
  260.             the editor commands */
  261. {
  262.     /* each tran[xxxx]= should be set to the code emitted by the terminal
  263.     key which will perform the indicated action.  The recommended (control)
  264.     key assignments are shown in round brackets.
  265.         Some terminals precede their codes by a lead-in character
  266.     (eg the Hazeltine uses the tilde).  This char should be assigned to
  267.     tran[LEADIN].  If there is no lead-in character, set tran[LEADIN] to zero.
  268.         'e' will ignore the leadin character if tran[LEADIN] is non-zero,
  269.     but will set the parity bit on the next character. All other chars from the
  270.     keyboard will already have any parity bits removed as they are read in.  Thus
  271.     codes with lead-ins should be entered in the table below as code+0x80, or
  272.     more clearly, as code+PARBIT.
  273.         For example, suppose that one is coding the Hazeltine 1420, which
  274.     generates a tilde,^L (0x0d) sequence when the cursor up key is pressd.  To
  275.     recognise this sequence, set tran[LEADIN] to tilde (0x7e) and set
  276.     tran[UPKEY] to 0x0d+PARBIT.
  277.     */
  278. # if adm31 | h19 | adm3a | beehive | vt100
  279.     tran[LEADIN]=0;        /*lead-in character, 0 if not used*/
  280.     tran[DOWNKEY]= ctrl(J);    /*cursor down */
  281.     tran[UPKEY]= ctrl(K);    /*cursor up*/
  282.     tran[LEFTKEY]= ctrl(H);    /*cursor left*/
  283.     tran[RIGHTKEY]= ctrl(L);    /*cursor right*/
  284.     tran[RIGHTWKEY]= ctrl(D);    /*cursor right one word  */
  285.     tran[LEFTWKEY]= ctrl(S);    /*cursor left one word  */
  286.     tran[EOLKEY]= ctrl(E);    /*cursor to end of line  */
  287.     tran[BOLKEY]= ctrl(B);    /*cursor to beginning of line  */
  288.     tran[UPPAGE]= ctrl(W);    /*scroll up a page  */
  289.     tran[DOWNPAGE]= ctrl(Z);    /*scroll down a page  */
  290.     tran[BOFKEY]= ctrl(U);    /*cursor to beginning of file  */
  291.     tran[HOMEKEY]= ctrl(^);    /*cursor to end of file (HOME) */
  292.     tran[DELLEFT]= 0177;    /*delete char to left of cursor (DEL) */
  293.     tran[DELRIGHT]= ctrl(G);    /*delete char under cursor  */
  294.     tran[DELLNKEY]= ctrl(Y);    /*delete cursor line  */
  295.     tran[DELWDKEY]= ctrl(T);    /*delete word to right of cursor  */
  296.     tran[JUMPKEY]= ctrl(X);    /*jump to  */
  297.     tran[CRSTILL]= ctrl(N);    /*insert newline after cursor  */
  298.     tran[QUITKEY]= ctrl(Q);    /*quit  */
  299.     tran[ENVIRKEY]= ctrl(C);/*edit and file context */
  300.     tran[FINDKEY]= ctrl(F);    /*find  */
  301.     tran[ALTERKEY]= ctrl(A);    /*alter  */
  302.     tran[BLOCKKEY]= ctrl(O);    /*block operations  */
  303.     tran[RDFILEKEY]= ctrl(P);    /*read a file */
  304.     tran[REPKEY]= ctrl(R);    /*repeat last find/alter */
  305.     tran[HELPKEY]= ctrl(V);    /*display help menu */
  306.     tran[UNDOKEY]= ctrl(\\);    /*restore unedited line  */
  307.     tran[TAB]= ctrl(I);    /*tab  */
  308.     tran[RETRIEVE]= ctrl(R);    /*retrieve */
  309.     tran[CR]= ctrl(M);    /*return*/
  310.     tran[ESCKEY]=ESC;    /*escape, the magic key (ESC)*/
  311. }
  312. # endif
  313. /* of adm31 */
  314. # if vt52
  315.     tran[LEADIN]=ESC;    /*lead-in character, 0 if not used*/
  316.     tran[DOWNKEY]= 'B'+PARBIT;    /*cursor down */
  317.     tran[UPKEY]= 'A'+PARBIT;    /*cursor up*/
  318.     tran[LEFTKEY]= 'D'+PARBIT;    /*cursor left*/
  319.     tran[RIGHTKEY]= 'C'+PARBIT;    /*cursor right*/
  320.     tran[RIGHTWKEY]= ctrl(D);    /*cursor right one word  */
  321.     tran[LEFTWKEY]= ctrl(S);    /*cursor left one word  */
  322.     tran[EOLKEY]= ctrl(E);    /*cursor to end of line  */
  323.     tran[BOLKEY]= ctrl(B);    /*cursor to beginning of line  */
  324.     tran[UPPAGE]= ctrl(W);    /*scroll up a page  */
  325.     tran[DOWNPAGE]= ctrl(K);    /*scroll down a page (Z) */
  326.     tran[BOFKEY]= ctrl(H);    /*cursor to beginning of file (U) */
  327.     tran[HOMEKEY]= ctrl(A);    /*cursor to end of file (HOME) */
  328.     tran[DELLEFT]= 0177;    /*delete char to left of cursor (DEL) */
  329.     tran[DELRIGHT]= ctrl(G);    /*delete char under cursor (G) */
  330.     tran[DELLNKEY]= ctrl(Y);    /*delete cursor line (Y) */
  331.     tran[DELWDKEY]= ctrl(T);    /*delete word to right of cursor (T) */
  332.     tran[JUMPKEY]= ctrl(X);    /*jump to (X) */
  333.     tran[CRSTILL]= ctrl(N);    /*insert newline after cursor (N) */
  334.     tran[QUITKEY]= ctrl(Q);    /*quit (Q) */
  335.     tran[ENVIRKEY]= ctrl(C);    /*edit and file context (C) */
  336.     tran[FINDKEY]= ctrl(L);    /*find (F) */
  337.     tran[ALTERKEY]= ctrl(^);    /*alter (A) */
  338.     tran[BLOCKKEY]= ctrl(O);    /*block operations (O) */
  339.     tran[RDFILEKEY]= ctrl(P);    /*read a file (P) */
  340.     tran[REPKEY]= ctrl(R);    /*repeat last find/alter (R) */
  341.     tran[HELPKEY]= ctrl(V);    /*display help menu (V) */
  342.     tran[UNDOKEY]= ctrl(\\);    /*restore unedited line (\) */
  343.     tran[TAB]= ctrl(I);    /*tab (I) */
  344.     tran[RETRIEVE]= ctrl(R);    /*retrieve (R)*/
  345.     tran[CR]= ctrl(M);    /*return*/
  346.     tran[ESCKEY]=ESC;    /*escape, the magic key (ESC)*/
  347. }
  348. # endif
  349. /* of vt52 */
  350. # if adds
  351.     tran[LEADIN]=ESC;    /*lead-in character, 0 if not used*/
  352.     tran[DOWNKEY]= ctrl(J);    /*cursor down */
  353.     tran[UPKEY]= ctrl(Z);    /*cursor up*/
  354.     tran[LEFTKEY]= ctrl(U);    /*cursor left*/
  355.     tran[RIGHTKEY]= ctrl(F);    /*cursor right*/
  356.     tran[RIGHTWKEY]= ctrl(D);    /*cursor right one word  */
  357.     tran[LEFTWKEY]= ctrl(S);    /*cursor left one word  */
  358.     tran[EOLKEY]= ctrl(E);    /*cursor to end of line  */
  359.     tran[BOLKEY]= ctrl(B);    /*cursor to beginning of line  */
  360.     tran[UPPAGE]= ctrl(W);    /*scroll up a page  */
  361.     tran[DOWNPAGE]= ctrl(K);    /*scroll down a page (Z) */
  362.     tran[BOFKEY]= ctrl(H);    /*cursor to beginning of file (U) */
  363.     tran[HOMEKEY]= ctrl(A);    /*cursor to end of file (HOME) */
  364.     tran[DELLEFT]= 0177;    /*delete char to left of cursor (DEL) */
  365.     tran[DELRIGHT]= ctrl(G);    /*delete char under cursor (G) */
  366.     tran[DELLNKEY]= ctrl(Y);    /*delete cursor line (Y) */
  367.     tran[DELWDKEY]= ctrl(T);    /*delete word to right of cursor (T) */
  368.     tran[JUMPKEY]= ctrl(X);    /*jump to (X) */
  369.     tran[CRSTILL]= ctrl(N);    /*insert newline after cursor (N) */
  370.     tran[QUITKEY]= ctrl(Q);    /*quit (Q) */
  371.     tran[ENVIRKEY]= ctrl(C);    /*edit and file context (C) */
  372.     tran[FINDKEY]= ctrl(L);    /*find (F) */
  373.     tran[ALTERKEY]= ctrl(^);    /*alter (A) */
  374.     tran[BLOCKKEY]= ctrl(O);    /*block operations (O) */
  375.     tran[RDFILEKEY]= ctrl(P);    /*read a file (P) */
  376.     tran[REPKEY]= ctrl(R);    /*repeat last find/alter (R) */
  377.     tran[HELPKEY]= ctrl(V);    /*display help menu (V) */
  378.     tran[UNDOKEY]= ctrl(\\);    /*restore unedited line (\) */
  379.     tran[TAB]= ctrl(I);    /*tab (I) */
  380.     tran[RETRIEVE]= ctrl(R);    /*retrieve (R)*/
  381.     tran[CR]= ctrl(M);    /*return*/
  382.     tran[ESCKEY]=ESC;    /*escape, the magic key (ESC)*/
  383. }
  384. # endif
  385. /* of adds */
  386. # if kaypro
  387.     tran[LEADIN]=0;        /*lead-in character, 0 if not used*/
  388.     tran[DOWNKEY]= ctrl(X);    /*cursor down */
  389.     tran[UPKEY]= ctrl(E);    /*cursor up*/
  390.     tran[LEFTKEY]= ctrl(S);    /*cursor left*/
  391.     tran[RIGHTKEY]= ctrl(D);    /*cursor right*/
  392.     tran[RIGHTWKEY]= ctrl(P);    /*cursor right one word (D) */
  393.     tran[LEFTWKEY]= ctrl(O);    /*cursor left one word (S) */
  394.     tran[EOLKEY]= ctrl(J);    /*cursor to end of line (E) */
  395.     tran[BOLKEY]= ctrl(H);    /*cursor to beginning of line (B) */
  396.     tran[UPPAGE]= ctrl(W);    /*scroll up a page  */
  397.     tran[DOWNPAGE]= ctrl(Z);    /*scroll down a page (Z) */
  398.     tran[BOFKEY]= ctrl(T);    /*cursor to beginning of file (U) */
  399.     tran[HOMEKEY]= ctrl(B);    /*cursor to end of file (HOME) */
  400.     tran[DELLEFT]= 0177;    /*delete char to left of cursor (DEL) */
  401.     tran[DELRIGHT]= ctrl(G);    /*delete char under cursor (G) */
  402.     tran[DELLNKEY]= ctrl(Y);    /*delete cursor line (Y) */
  403.     tran[DELWDKEY]= ctrl(]);/*delete word to right of cursor (T) */
  404.     tran[JUMPKEY]= ctrl(L);    /*jump to (X) */
  405.     tran[CRSTILL]= ctrl(N);    /*insert newline after cursor (N) */
  406.     tran[QUITKEY]= ctrl(Q);    /*quit (Q) */
  407.     tran[ENVIRKEY]= ctrl(C);    /*edit and file context (C) */
  408.     tran[FINDKEY]= ctrl(F);    /*find (F) */
  409.     tran[ALTERKEY]= ctrl(A);    /*alter (A) */
  410.     tran[BLOCKKEY]= ctrl(K);    /*block operations (O) */
  411.     tran[RDFILEKEY]= ctrl(R);    /*read a file (P) */
  412.     tran[REPKEY]= ctrl(\\);    /*repeat last find/alter (R) */
  413.     tran[HELPKEY]= ctrl(V);    /*display help menu (V) */
  414.     tran[UNDOKEY]= ctrl(U);    /*restore unedited line (\) */
  415.     tran[TAB]= ctrl(I);    /*tab (I) */
  416.     tran[RETRIEVE]= ctrl(R);    /*retrieve (R)*/
  417.     tran[CR]= ctrl(M);    /*return*/
  418.     tran[ESCKEY]=ESC;    /*escape, the magic key (ESC)*/
  419. }
  420. # endif
  421. /* of kaypro */
  422. # if haze
  423.     tran[LEADIN]= 0176;        /* TILDE is the lead in character */
  424.     tran[DOWNKEY]= (ctrl(K))+PARBIT;    /*cursor down */
  425.     tran[UPKEY]= (ctrl(L))+PARBIT;        /*cursor up*/
  426.     tran[LEFTKEY]= ctrl(H);        /*cursor left*/
  427.     tran[RIGHTKEY]= ctrl(P);        /*cursor right*/
  428.     tran[RIGHTWKEY]= ctrl(D);        /*cursor right one word  */
  429.     tran[LEFTWKEY]= ctrl(S);        /*cursor left one word  */
  430.     tran[EOLKEY]= ctrl(E);        /*cursor to end of line  */
  431.     tran[BOLKEY]= ctrl(B);        /*cursor to beginning of line  */
  432.     tran[UPPAGE]= ctrl(W);        /*scroll up a page  */
  433.     tran[DOWNPAGE]= ctrl(Z);        /*scroll down a page (Z) */
  434.     tran[BOFKEY]= ctrl(U);        /*cursor to beginning of file (U) */
  435.     tran[HOMEKEY]= (ctrl(R))+PARBIT;    /*cursor to end of file (HOME) */
  436.     tran[DELLEFT]= 0177;        /*delete char to left of cursor (DEL) */
  437.     tran[DELRIGHT]= ctrl(G);        /*delete char under cursor (G) */
  438.     tran[DELLNKEY]= ctrl(Y);        /*delete cursor line (Y) */
  439.     tran[DELWDKEY]= ctrl(T);        /*delete word to right of cursor (T) */
  440.     tran[JUMPKEY]= ctrl(X);        /*jump to (X) */
  441.     tran[CRSTILL]= ctrl(N);        /*insert newline after cursor (N) */
  442.     tran[QUITKEY]= ctrl(Q);        /*quit (Q) */
  443.     tran[ENVIRKEY]= ctrl(C);        /*edit and file context (C) */
  444.     tran[FINDKEY]= ctrl(F);        /*find (F) */
  445.     tran[ALTERKEY]= ctrl(A);        /*alter (A) */
  446.     tran[BLOCKKEY]= ctrl(O);        /*block operations (O) */
  447.     tran[RDFILEKEY]= ctrl(K);        /*read a file (P) */
  448.     tran[REPKEY]= ctrl(R);        /*repeat last find/alter (R) */
  449.     tran[HELPKEY]= ctrl(V);        /*display help menu (V) */
  450.     tran[UNDOKEY]= ctrl(\\);        /*restore unedited line (\) */
  451.     tran[TAB]= ctrl(I);        /*tab (I) */
  452.     tran[RETRIEVE]= ctrl(R);        /*retrieve (R)*/
  453.     tran[CR]= ctrl(M);        /*return*/
  454.     tran[ESCKEY]=ESC;        /*escape, the magic key (ESC)*/
  455. }
  456. # endif
  457. /* of haze */
  458.  
  459. /*-------------------------------HELP MENU-------------------------------*/
  460. help()    /*display the help menu.  There must be (helplines-1)
  461.             lines of menu here (see terminal function,above) */
  462. {
  463.     putstr("CURSOR:  ^B|=beginning of line| ^E|=end of line|    ^S|=left word|  ^D|=right word\n");
  464.     putstr("MOVE:    ^W|=up a screen|       ^Z|=down a screen|  ^U|=top,     |HOME|=bottom of file\n");
  465.     putstr("DELETE: DEL|=char left|         ^G|=char right|     ^T|=word|       ^Y|=line|  ^\\|=undo\n");
  466.     putstr("         ^F|=find|              ^A|=alter|          ^R|=repeat|     ^V|=view menu\n");
  467.     putstr("   ^     ^N|=insert a new line| ^X|=jump to line|   ^P|=read file|  ^Q|=quit,save file\n");
  468.     putstr(" <- ->   ^C|=edit,file context| ^O|=write,print,shift,move,copy,or delete block\n");
  469.     putstr("---v------------------------------------------------------------------------");
  470. }
  471. /*---------------------------------END---------------------------------------*/
  472.  
  473.  
  474.  
  475.