From 85b7bc695629926641c7cb752fd478adfdf374f3 Mon Sep 17 00:00:00 2001
From: Marius <mariausol@gmail.com>
Date: Sun, 4 Jul 2010 15:32:09 +0300
Subject: stable 2010-05-24 13:10

---
 tex/context/base/thrd-pic.tex | 3694 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 3694 insertions(+)
 create mode 100644 tex/context/base/thrd-pic.tex

(limited to 'tex/context/base/thrd-pic.tex')

diff --git a/tex/context/base/thrd-pic.tex b/tex/context/base/thrd-pic.tex
new file mode 100644
index 000000000..3c25d8a81
--- /dev/null
+++ b/tex/context/base/thrd-pic.tex
@@ -0,0 +1,3694 @@
+% Since this file is not available in every distribution, we
+% have copied the original in this file. The manuals to
+% Wichura's PiCTeX and TaBlE packages are not available on
+% line and are distributed by respectively the TeX Users Group
+% and Personal TeX Inc.
+
+% We've patched this file for catcode ! because in luatex we use
+% catcode tables and using unprotect/protect is cleaner.
+
+% This is PiCTeX, Version 1.1   9/21/87
+
+% CAVEAT: The PiCTeX manual often has a more lucid explanation
+%   of any given topic than you will find in the internal documentation
+%   of the macros.
+
+% PiCTeX's commands can be classified into two groups: (1) public (or
+%   external), and (2) private (or internal). The public macros are
+%   discussed at length in the manual. The only discussion of the private
+%   macros is the internal documentation. The private macros all have
+%   names beginning with an exclamation point (!) of category code 11.
+%   Since in normal usage "!" has category code 12, these macros can't
+%   be accessed or modified by the general user.
+
+% The macros are organized into thematically related groups. For example,
+%   the macros dealing with dots & dashes are all in the DASHPATTERN group.
+%   The table below shows which macros are in which groups. The table
+%   covers all public macros, and many (but not all) of PiCTeX's upper level
+%   private macros. Following the table, the various groups are listed
+%   in the order in which they appear in the table.
+
+% *********************** TABLE OF GROUPS OF MACROS **********************
+
+% HACKS:  Utility macros
+%    \PiC
+%    \PiCTeX
+%    \placevalueinpts
+%    \!!loop
+%    \!cfor
+%    \!copylist
+%    \!ecfor
+%    \!etfor
+%    \!getnext
+%    \!getnextvalueof
+%    \!ifempty
+%    \!ifnextchar
+%    \!leftappend
+%    \!listaddon
+%    \!loop
+%    \!lop
+%    \!mlap
+%    \!not
+%    \!removept
+%    \!rightappend
+%    \!tfor
+%    \!vmlap
+%    \!wlet
+
+% ALLOCATION:  Allocates registers
+
+% AREAS: Deals with plot areas
+%    \axis
+%    \grid
+%    \invisibleaxes
+%    \normalgraphs
+%    \plotheading
+%    \setplotarea
+%    \visibleaxes
+
+% ARROWS:  Draws arrows
+%    \arrow
+%    \betweenarrows
+
+% BARS:  Draws bars
+%    \putbar
+%    \setbars
+
+% BOXES:  Draws rectangles
+%    \frame
+%    \putrectangle
+%    \rectangle
+%    \shaderectangleson
+%    \shaderectanglesoff
+
+% CURVES:  Upper level plot commands
+%    \hshade
+%    \plot
+%    \sethistograms
+%    \setlinear
+%    \setquadratic
+%    \vshade
+
+% DASHPATTERNS:  Sets up dash patterns
+%    \findlength
+%    \setdashes
+%    \setdashesnear
+%    \setdashpattern
+%    \setdots
+%    \setdotsnear
+%    \setsolid
+%    \!dashingoff
+%    \!dashingon
+
+% DIVISION:  Does long division of dimension registers
+%    \Divide
+%    \!divide
+
+% ELLIPSES:  Draws ellipses and circles
+%    \circulararc
+%    \ellipticalarc
+
+% RULES:  Draws rules, i.e., horizontal & vertical lines
+%    \putrule
+%    \!putdashedhline
+%    \!putdashedvline
+%    \!puthline
+%    \!putsolidhline
+%    \!putsolidvline
+%    \!putvline
+
+% LINEAR ARC:  Draws straight lines -- solid and dashed
+%    \inboundscheckoff
+%    \inboundscheckon
+%    \!advancedashing
+%    \!drawlinearsegment
+%    \!initinboundscheck
+%    \!linearsolid
+%    \!lineardashed
+%    \!ljoin
+%    \!plotifinbounds
+%    \!start
+
+% LOGTEN:  Log_10 function
+%    \!logten
+
+% PICTURES:  Basic setups for PiCtures; \put commands
+%    \accountingoff
+%    \accountingon
+%    \beginpicture
+%    \endpicture
+%    \endpicturesave
+%    \lines
+%    \multiput
+%    \put
+%    \setcoordinatemode
+%    \setcoordinatesystem
+%    \setdimensionmode
+%    \stack
+%    \Lines
+%    \Xdistance
+%    \Ydistance
+%    \!dimenput
+%    \!ifcoordmode
+%    \!ifdimenmode
+%    \!setcoordmode
+%    \!setdimenmode
+%    \!setputobject
+
+% PLOTTING:  Things to do with plotting
+%    \dontsavelinesandcurves
+%    \replot
+%    \savelinesandcurves
+%    \setplotsymbol
+%    \writesavefile
+%    \!plot
+
+% PYTHAGORAS:  Euclidean distance function
+%    \placehypotenuse
+%    \!Pythag
+
+% QUADRATIC ARC:  Draws a quadratic arc
+%    \!qjoin
+
+% ROTATIONS:  Handles rotations
+%    \startrotation
+%    \stoprotation
+%    \!rotateaboutpivot
+%    \!rotateonly
+
+% SHADING:  Handles shading
+%    \setshadegrid
+%    \setshadesymbol
+%    \!lshade
+%    \!qshade
+%    \!starthshade
+%    \!startvshade
+
+% TICKS:  Draws ticks on graphs
+%    \gridlines
+%    \loggedticks
+%    \nogridlines
+%    \ticksin
+%    \ticksout
+%    \unloggesticks
+
+% ***************** END OF TABLE OF GROUPS OF MACROS ********************
+
+
+% \catcode`!=11 %  ***** THIS MUST NEVER BE OMITTED
+
+\unprotect
+
+% *******************************
+% *** HACKS  (Utility macros) ***
+% *******************************
+
+% ** User commands
+% **   \PiC{P\kern-.12em\lower.5ex\hbox{I}\kern-.075emC}
+% **   \PiCTeX{\PiC\kern-.11em\TeX}
+% **   \placevalueinpts of <DIMENSION REGISTER> in {CONTROL SEQUENCE}
+
+% ** Internal commands
+% **   \!ifnextchar{CHARACTER}{TRUE ACTION}{FALSE ACTION}
+% **   \!tfor NAME := LIST \do {BODY}
+% **   \!etfor NAME:= LIST \do {BODY}
+% **   \!cfor NAME := LIST \do {BODY}
+% **   \!ecfor NAME:= LIST \do {BODY}
+% **   \!ifempty{MACRO}{TRUE ACTION}{FALSE ACTION}
+% **   \!getnext\\ITEMfrom\LIST
+% **   \!getnextvalueof\DIMEN\from\LIST
+% **   \!copylist\LISTMACRO_A\to\LISTMACRO_B
+% **   \!wlet\CONTROL_SEQUENCE_A=\CONTROL_SEQUENCE_B
+% **   \!listaddon ITEM LIST
+% **   \!rightappendITEM\withCS\to\LISTMACRO
+% **   \!leftappendITEM\withCS\to\LISTMACRO
+% **   \!lop\LISTMACRO\to\ITEM
+% **   \!loop ... repeat
+% **   \!!loop ... repeat
+% **   \!removept{DIMENSION REGISTER}{CONTROL SEQUENCE}
+% **   \!mlap{...}
+% **   \!vmlap{...}
+% **   \!not{TEK if-CONDITION}
+
+% ** First, here are the the PiCTeX logo, and the syllable PiC:
+\def\PiC{P\kern-.12em\lower.5ex\hbox{I}\kern-.075emC}
+\def\PiCTeX{\PiC\kern-.11em\TeX}
+
+% ** The following macro expands to parameter #2 or parameter #3 according to
+% ** whether the next non-blank character following the macro is or is not #1.
+% ** Blanks following the macro are gobbled.
+\def\!ifnextchar#1#2#3{%
+  \let\!testchar=#1%
+  \def\!first{#2}%
+  \def\!second{#3}%
+  \futurelet\!nextchar\!testnext}
+\def\!testnext{%
+  \ifx \!nextchar \!spacetoken
+    \let\!next=\!skipspacetestagain
+  \else
+    \ifx \!nextchar \!testchar
+      \let\!next=\!first
+    \else
+      \let\!next=\!second
+    \fi
+  \fi
+  \!next}
+\def\\{\!skipspacetestagain}
+  \expandafter\def\\ {\futurelet\!nextchar\!testnext}
+\def\\{\let\!spacetoken= } \\  %  ** set \spacetoken to a space token
+
+
+% ** Borrow the "tfor" macro from Latex:
+% **   \!tfor NAME := LIST \do {BODY}
+% **   if, before expansion, LIST = T1 ... Tn,  where each  Ti  is a token
+% **   or  {...},  then executes  BODY  n  times, with  NAME = Ti  on the
+% **   i-th iteration.  Works for  n=0.
+\def\!tfor#1:=#2\do#3{%
+  \edef\!fortemp{#2}%
+  \ifx\!fortemp\!empty
+    \else
+    \!tforloop#2\!nil\!nil\!!#1{#3}%
+  \fi}
+\def\!tforloop#1#2\!!#3#4{%
+  \def#3{#1}%
+  \ifx #3\!nnil
+    \let\!nextwhile=\!fornoop
+  \else
+    #4\relax
+    \let\!nextwhile=\!tforloop
+  \fi
+  \!nextwhile#2\!!#3{#4}}
+
+
+% **   \!etfor NAME:= LIST\do {BODY}
+% **   This is like \!cfor, but LIST is any balanced token list whose complete
+% **     expansion has the form  T1 ... Tn
+\def\!etfor#1:=#2\do#3{%
+  \def\!!tfor{\!tfor#1:=}%
+  \edef\!!!tfor{#2}%
+  \expandafter\!!tfor\!!!tfor\do{#3}}
+
+
+% **   modify the Latex \tfor (token-for) loop to a \cfor (comma-for) loop.
+% **   \!cfor NAME := LIST \do {BODY}
+% **     if, before expansion, LIST = a1,a2,...an, then executes  BODY n times,
+% **     with  NAME = ai  on the i-th iteration.  Works for  n=0.
+\def\!cfor#1:=#2\do#3{%
+  \edef\!fortemp{#2}%
+  \ifx\!fortemp\!empty
+  \else
+    \!cforloop#2,\!nil,\!nil\!!#1{#3}%
+  \fi}
+\def\!cforloop#1,#2\!!#3#4{%
+  \def#3{#1}%
+  \ifx #3\!nnil
+    \let\!nextwhile=\!fornoop
+  \else
+    #4\relax
+    \let\!nextwhile=\!cforloop
+  \fi
+  \!nextwhile#2\!!#3{#4}}
+
+
+% **   \!ecfor NAME:= LIST\do {BODY}
+% **   This is like \!cfor, but LIST is any balanced token list whose complete
+% **     expansion has the form  a1,a2,...,an.
+\def\!ecfor#1:=#2\do#3{%
+  \def\!!cfor{\!cfor#1:=}%
+  \edef\!!!cfor{#2}%
+  \expandafter\!!cfor\!!!cfor\do{#3}}
+
+
+\def\!empty{}
+\def\!nnil{\!nil}
+\def\!fornoop#1\!!#2#3{}
+
+
+% **  \!ifempty{ARG}{TRUE ACTION}{FALSE ACTION}
+\def\!ifempty#1#2#3{%
+  \edef\!emptyarg{#1}%
+  \ifx\!emptyarg\!empty
+    #2%
+  \else
+    #3%
+  \fi}
+
+% **  \!getnext\\ITEMfrom\LIST
+% **    \LIST has the form \\{item1}\\{item2}\\{item3}...\\{itemk}
+% **    This routine sets \ITEM to item1, and cycles \LIST to
+% **    \\{item2}\\{item3}...\\{itemk}\\{item1}
+\def\!getnext#1\from#2{%
+  \expandafter\!gnext#2\!#1#2}%
+\def\!gnext\\#1#2\!#3#4{%
+  \def#3{#1}%
+  \def#4{#2\\{#1}}%
+  \ignorespaces}
+
+
+% ** \!getnextvalueof\DIMEN\from\LIST
+% **   Similar to !getnext.
+% **   \LIST has the form \\{dimen1}\\{dimen2}\\{dimen3} ...
+% **   \DIMEN is a dimension register
+% **   Works also for counts
+%
+\def\!getnextvalueof#1\from#2{%
+  \expandafter\!gnextv#2\!#1#2}%
+\def\!gnextv\\#1#2\!#3#4{%
+  #3=#1%
+  \def#4{#2\\{#1}}%
+  \ignorespaces}
+
+
+% ** \!copylist\LISTMACROA\to\LISTMACROB
+% **   makes the replacement text of LISTMACRO B identical to that of
+% **   list macro A.
+\def\!copylist#1\to#2{%
+  \expandafter\!!copylist#1\!#2}
+\def\!!copylist#1\!#2{%
+  \def#2{#1}\ignorespaces}
+
+
+% **  \!wlet\CSA=\CSB
+% **  lets control sequence \CSB = control sequence \CSA, and writes a
+% **    message to that effect in the log file using plain TEK's \wlog
+\def\!wlet#1=#2{%
+  \let#1=#2
+  \wlog{\string#1=\string#2}}
+
+% ** \!listaddon ITEM LIST
+% ** LIST <-- LIST \\ ITEM
+\def\!listaddon#1#2{%
+  \expandafter\!!listaddon#2\!{#1}#2}
+\def\!!listaddon#1\!#2#3{%
+  \def#3{#1\\#2}}
+
+% **  \!rightappendITEM\to\LISTMACRO
+% **    \LISTMACRO --> \LISTMACRO\\{ITEM}
+%\def\!rightappend#1\to#2{\expandafter\!!rightappend#2\!{#1}#2}
+%\def\!!rightappend#1\!#2#3{\def#3{#1\\{#2}}}
+
+
+% **  \!rightappendITEM\withCS\to\LISTMACRO
+% **    \LISTMACRO --> \LISTMACRO||CS||{ITEM}
+\def\!rightappend#1\withCS#2\to#3{\expandafter\!!rightappend#3\!#2{#1}#3}
+\def\!!rightappend#1\!#2#3#4{\def#4{#1#2{#3}}}
+
+
+% **  \!leftappendITEM\withCS\to\LISTMACRO
+% **    \LISTMACRO --> CS||{ITEM}||\LISTMACRO
+\def\!leftappend#1\withCS#2\to#3{\expandafter\!!leftappend#3\!#2{#1}#3}
+\def\!!leftappend#1\!#2#3#4{\def#4{#2{#3}#1}}
+
+
+% **  \!lop\LISTMACRO\to\ITEM
+% **    \\{item1}\\{item2}\\{item3} ... --> \\{item2}\\{item3} ...
+% **    item1 --> \ITEM
+\def\!lop#1\to#2{\expandafter\!!lop#1\!#1#2}
+\def\!!lop\\#1#2\!#3#4{\def#4{#1}\def#3{#2}}
+
+
+% **  \!placeNUMBER\of\LISTMACRO\in\ITEM
+% **    the NUMBERth item of \LISTMACRO --> replacement text of \ITEM
+%\def\!place#1\of#2\in#3{\def#3{\outofrange}%
+%{\count0=#1\def\\##1{\advance\count0-1 \ifnum\count0=0 \gdef#3{##1}\fi}#2}}
+
+
+% **  Following code converts a commalist to a list macro, with all items
+% **    fully expanded.
+%\!ecfor\item:=\commalist\do{\expandafter\!rightappend\item\to\list}
+
+
+% ** \!loop ... repeat
+% ** This is exactly like TEX's \loop ... repeat.  It can be used in nesting
+% ** two loops, without puting the inner one inside a group.
+\def\!loop#1\repeat{\def\!body{#1}\!iterate}
+\def\!iterate{\!body\let\!next=\!iterate\else\let\!next=\relax\fi\!next}
+
+% ** \!!loop ... repeat
+% ** This is exactly like TEX's \loop ... repeat.  It can be used in nesting
+% ** two loops, without puting the inner one inside a group.
+\def\!!loop#1\repeat{\def\!!body{#1}\!!iterate}
+\def\!!iterate{\!!body\let\!!next=\!!iterate\else\let\!!next=\relax\fi\!!next}
+%  (\multiput uses \!!loop)
+
+% ** \!removept{DIMENREG}{\CS}
+% ** Defines the control sequence CS to be the value (in points) in the
+% ** dimension register DIMENREG (but without the "pt" TEK usually adds)
+% ** E.g., after  \dimen0=12.3pt \!removept\dimen0\A, \A expands to 12.3
+\def\!removept#1#2{\edef#2{\expandafter\!!removePT\the#1}}
+{\catcode`p=12 \catcode`t=12 \gdef\!!removePT#1pt{#1}}
+
+% ** \pladevalueinpts of <DIMENSION REGISTER> in {CONTROL SEQUENCE}
+\def\placevalueinpts of <#1> in #2 {%
+  \!removept{#1}{#2}}
+
+% ** \!mlap{...}  \!vmlap{...}
+% ** Center  ...  in a box of width 0.
+\def\!mlap#1{\hbox to 0pt{\hss#1\hss}}
+\def\!vmlap#1{\vbox to 0pt{\vss#1\vss}}
+
+% ** \!not{TEK if-CONDITION}
+% ** By a TEK if-CONDITION is meant something like
+% **     \ifnum\N<0,   or   \ifdim\A>\B
+% ** \!not produces an if-condition which is false if the original condition
+% ** is true, and true if the original condition is false.
+\def\!not#1{%
+  #1\relax
+    \!switchfalse
+  \else
+    \!switchtrue
+  \fi
+  \if!switch
+  \ignorespaces}
+
+
+% *******************
+% *** ALLOCATIONS ***
+% *******************
+
+% This section allocates all the registers PiCTeX uses. Following
+% each allocation is a string of the form  ....N.D...L......... ;
+% the various letters show which sections of PiCTeX make explicit
+% reference to that register, according to the following code:
+
+%   H Hacks
+%   A Areas
+%   W arroWs
+%   B Bars
+%   X boXes
+%   C Curves
+%   D Dashpattterns
+%   V diVision
+%   E Ellipses
+%   U rUles
+%   L Linear arc
+%   G loGten
+%   P Pictures
+%   O plOtting
+%   Y pYthagoras
+%   Q Quadratic arc
+%   R Rotations
+%   S Shading
+%   T Ticks
+
+% Turn off messages from TeX's allocation macros
+\let\!!!wlog=\wlog              % "\wlog" is defined in plain TeX
+\def\wlog#1{}
+
+\newdimen\headingtoplotskip     %.A.................
+\newdimen\linethickness         %.A..X....U........T
+\newdimen\longticklength        %.A................T
+\newdimen\plotsymbolspacing     %......D...L....Q...
+\newdimen\shortticklength       %.A................T
+\newdimen\stackleading          %.A..........P......
+\newdimen\tickstovaluesleading  %.A................T
+\newdimen\totalarclength        %......D...L....Q...
+\newdimen\valuestolabelleading  %.A.................
+
+\newbox\!boxA                   %.AW...............T
+\newbox\!boxB                   %..W................
+\newbox\!picbox                 %............P......
+\newbox\!plotsymbol             %..........L..O.....
+\newbox\!putobject              %............PO...S.
+\newbox\!shadesymbol            %.................S.
+
+\newcount\!countA               %.A....D..UL....Q.ST
+\newcount\!countB               %......D..U.....Q.ST
+\newcount\!countC               %...............Q..T
+\newcount\!countD               %...................
+\newcount\!countE               %.............O....T
+\newcount\!countF               %.............O....T
+\newcount\!countG               %..................T
+\newcount\!fiftypt              %.........U.........
+\newcount\!intervalno           %..........L....Q...
+\newcount\!npoints              %..........L........
+\newcount\!nsegments            %.........U.........
+\newcount\!ntemp                %............P......
+\newcount\!parity               %.................S.
+\newcount\!scalefactor          %..................T
+\newcount\!tfs                  %.......V...........
+\newcount\!tickcase             %..................T
+
+\newdimen\!Xleft                %............P......
+\newdimen\!Xright               %............P......
+\newdimen\!Xsave                %.A................T
+\newdimen\!Ybot                 %............P......
+\newdimen\!Ysave                %.A................T
+\newdimen\!Ytop                 %............P......
+\newdimen\!angle                %........E..........
+\newdimen\!arclength            %..W......UL....Q...
+\newdimen\!areabloc             %.A........L........
+\newdimen\!arealloc             %.A........L........
+\newdimen\!arearloc             %.A........L........
+\newdimen\!areatloc             %.A........L........
+\newdimen\!bshrinkage           %.................S.
+\newdimen\!checkbot             %..........L........
+\newdimen\!checkleft            %..........L........
+\newdimen\!checkright           %..........L........
+\newdimen\!checktop             %..........L........
+\newdimen\!dimenA               %.AW.X.DVEUL..OYQRST
+\newdimen\!dimenB               %....X.DVEU...O.QRS.
+\newdimen\!dimenC               %..W.X.DVEU......RS.
+\newdimen\!dimenD               %..W.X.DVEU....Y.RS.
+\newdimen\!dimenE               %..W........G..YQ.S.
+\newdimen\!dimenF               %...........G..YQ.S.
+\newdimen\!dimenG               %...........G..YQ.S.
+\newdimen\!dimenH               %...........G..Y..S.
+\newdimen\!dimenI               %...BX.........Y....
+\newdimen\!distacross           %..........L....Q...
+\newdimen\!downlength           %..........L........
+\newdimen\!dp                   %.A..X.......P....S.
+\newdimen\!dshade               %.................S.
+\newdimen\!dxpos                %..W......U..P....S.
+\newdimen\!dxprime              %...............Q...
+\newdimen\!dypos                %..WB.....U..P......
+\newdimen\!dyprime              %...............Q...
+\newdimen\!ht                   %.A..X.......P....S.
+\newdimen\!leaderlength         %......D..U.........
+\newdimen\!lshrinkage           %.................S.
+\newdimen\!midarclength         %...............Q...
+\newdimen\!offset               %.A................T
+\newdimen\!plotheadingoffset    %.A.................
+\newdimen\!plotsymbolxshift     %..........L..O.....
+\newdimen\!plotsymbolyshift     %..........L..O.....
+\newdimen\!plotxorigin          %..........L..O.....
+\newdimen\!plotyorigin          %..........L..O.....
+\newdimen\!rootten              %...........G.......
+\newdimen\!rshrinkage           %.................S.
+\newdimen\!shadesymbolxshift    %.................S.
+\newdimen\!shadesymbolyshift    %.................S.
+\newdimen\!tenAa                %...........G.......
+\newdimen\!tenAc                %...........G.......
+\newdimen\!tenAe                %...........G.......
+\newdimen\!tshrinkage           %.................S.
+\newdimen\!uplength             %..........L........
+\newdimen\!wd                   %....X.......P....S.
+\newdimen\!wmax                 %...............Q...
+\newdimen\!wmin                 %...............Q...
+\newdimen\!xB                   %...............Q...
+\newdimen\!xC                   %...............Q...
+\newdimen\!xE                   %..W.....E.L....Q.S.
+\newdimen\!xM                   %..W.....E......Q.S.
+\newdimen\!xS                   %..W.....E.L....Q.S.
+\newdimen\!xaxislength          %.A................T
+\newdimen\!xdiff                %..........L........
+\newdimen\!xleft                %............P......
+\newdimen\!xloc                 %..WB.....U.......S.
+\newdimen\!xorigin              %.A........L.P....S.
+\newdimen\!xpivot               %................R..
+\newdimen\!xpos                 %..........L.P..Q.ST
+\newdimen\!xprime               %...............Q...
+\newdimen\!xright               %............P......
+\newdimen\!xshade               %.................S.
+\newdimen\!xshift               %..W.........PO...S.
+\newdimen\!xtemp                %............P......
+\newdimen\!xunit                %.AWBX...EUL.P..QRS.
+\newdimen\!xxE                  %........E..........
+\newdimen\!xxM                  %........E..........
+\newdimen\!xxS                  %........E..........
+\newdimen\!xxloc                %..WB....EU.........
+\newdimen\!yB                   %...............Q...
+\newdimen\!yC                   %...............Q...
+\newdimen\!yE                   %..W.....E.L....Q...
+\newdimen\!yM                   %..W.....E......Q...
+\newdimen\!yS                   %..W.....E.L....Q...
+\newdimen\!yaxislength          %.A................T
+\newdimen\!ybot                 %............P......
+\newdimen\!ydiff                %..........L........
+\newdimen\!yloc                 %..WB.....U.......S.
+\newdimen\!yorigin              %.A........L.P....S.
+\newdimen\!ypivot               %................R..
+\newdimen\!ypos                 %..........L.P..Q.ST
+\newdimen\!yprime               %...............Q...
+\newdimen\!yshade               %.................S.
+\newdimen\!yshift               %..W.........PO...S.
+\newdimen\!ytemp                %............P......
+\newdimen\!ytop                 %............P......
+\newdimen\!yunit                %.AWBX...EUL.P..QRS.
+\newdimen\!yyE                  %........E..........
+\newdimen\!yyM                  %........E..........
+\newdimen\!yyS                  %........E..........
+\newdimen\!yyloc                %..WB....EU.........
+\newdimen\!zpt                  %.AWBX.DVEULGP.YQ.ST
+
+\newif\if!axisvisible           %.A.................
+\newif\if!gridlinestoo          %..................T
+\newif\if!keepPO                %...................
+\newif\if!placeaxislabel        %.A.................
+\newif\if!switch                %H..................
+\newif\if!xswitch               %.A................T
+
+\newtoks\!axisLaBeL             %.A.................
+\newtoks\!keywordtoks           %.A.................
+
+\newwrite\!replotfile           %.............O.....
+
+\newhelp\!keywordhelp{The keyword mentioned in the error message in unknown.
+Replace NEW KEYWORD in the indicated response by the keyword that
+should have been specified.}    %.A.................
+
+% The following commands assign alternate names to some of the
+% above registers.  "\!wlet"  is defined in  Hacks.
+\!wlet\!!origin=\!xM                   %.A................T
+\!wlet\!!unit=\!uplength               %.A................T
+\!wlet\!Lresiduallength=\!dimenG       %.........U.........
+\!wlet\!Rresiduallength=\!dimenF       %.........U.........
+\!wlet\!axisLength=\!distacross        %.A................T
+\!wlet\!axisend=\!ydiff                %.A................T
+\!wlet\!axisstart=\!xdiff              %.A................T
+\!wlet\!axisxlevel=\!arclength         %.A................T
+\!wlet\!axisylevel=\!downlength        %.A................T
+\!wlet\!beta=\!dimenE                  %...............Q...
+\!wlet\!gamma=\!dimenF                 %...............Q...
+\!wlet\!shadexorigin=\!plotxorigin     %.................S.
+\!wlet\!shadeyorigin=\!plotyorigin     %.................S.
+\!wlet\!ticklength=\!xS                %..................T
+\!wlet\!ticklocation=\!xE              %..................T
+\!wlet\!ticklocationincr=\!yE          %..................T
+\!wlet\!tickwidth=\!yS                 %..................T
+\!wlet\!totalleaderlength=\!dimenE     %.........U.........
+\!wlet\!xone=\!xprime                  %....X..............
+\!wlet\!xtwo=\!dxprime                 %....X..............
+\!wlet\!ySsave=\!yM                    %...................
+\!wlet\!ybB=\!yB                       %.................S.
+\!wlet\!ybC=\!yC                       %.................S.
+\!wlet\!ybE=\!yE                       %.................S.
+\!wlet\!ybM=\!yM                       %.................S.
+\!wlet\!ybS=\!yS                       %.................S.
+\!wlet\!ybpos=\!yyloc                  %.................S.
+\!wlet\!yone=\!yprime                  %....X..............
+\!wlet\!ytB=\!xB                       %.................S.
+\!wlet\!ytC=\!xC                       %.................S.
+\!wlet\!ytE=\!downlength               %.................S.
+\!wlet\!ytM=\!arclength                %.................S.
+\!wlet\!ytS=\!distacross               %.................S.
+\!wlet\!ytpos=\!xxloc                  %.................S.
+\!wlet\!ytwo=\!dyprime                 %....X..............
+
+
+% Initial values for registers
+\!zpt=0pt                              % static
+\!xunit=1pt
+\!yunit=1pt
+\!arearloc=\!xunit
+\!areatloc=\!yunit
+\!dshade=5pt
+\!leaderlength=24in
+\!tfs=256                              % static
+\!wmax=5.3pt                           % static
+\!wmin=2.7pt                           % static
+\!xaxislength=\!xunit
+\!xpivot=\!zpt
+\!yaxislength=\!yunit
+\!ypivot=\!zpt
+\plotsymbolspacing=.4pt
+  \!dimenA=50pt \!fiftypt=\!dimenA     % static
+
+\!rootten=3.162278pt                   % static
+\!tenAa=8.690286pt                     % static  (A5)
+\!tenAc=2.773839pt                     % static  (A3)
+\!tenAe=2.543275pt                     % static  (A1)
+
+% Initial values for control sequences
+\def\!cosrotationangle{1}      %................R..
+\def\!sinrotationangle{0}      %................R..
+\def\!xpivotcoord{0}           %................R..
+\def\!xref{0}                  %............P......
+\def\!xshadesave{0}            %.................S.
+\def\!ypivotcoord{0}           %................R..
+\def\!yref{0}                  %............P......
+\def\!yshadesave{0}            %.................S.
+\def\!zero{0}                  %..................T
+
+% Reset TeX to report allocations
+\let\wlog=\!!!wlog
+%  *************************************
+%  ***  AREAS: Deals with plot areas ***
+%  *************************************
+%
+%  ** User commands
+%  **   \setplotarea x from LEFT XCOORD to RIGTH XCOORD, y from BOTTOM YCOORD
+%  **      to TOP YCOORD
+%  **   \axis BOTTOM-LEFT-TOP-RIGHT  [SHIFTEDTO xy=COORD] [VISIBLE-INVISIBLE]
+%  **      [LABEL {label}] [TICKS] /
+%  **   \visibleaxes
+%  **   \invisibleaxes
+%  **   \plotheading {HEADING}
+%  **   \grid {# of columns} {# of rows}
+%  **   \normalgraphs
+
+%  **  \normalgraphs
+%  **    Sets defaults for graph setup. See Subsection 3.4 of manual.
+\def\normalgraphs{%
+  \longticklength=.4\baselineskip
+  \shortticklength=.25\baselineskip
+  \tickstovaluesleading=.25\baselineskip
+  \valuestolabelleading=.8\baselineskip
+  \linethickness=.4pt
+  \stackleading=.17\baselineskip
+  \headingtoplotskip=1.5\baselineskip
+  \visibleaxes
+  \ticksout
+  \nogridlines
+  \unloggedticks}
+%
+% **  \setplotarea x from LEFT XCOORD to RIGTH XCOORD, y from BOTTOM YCOORD
+% **    to TOP YCOORD
+% **  Reserves space in PICBOX for a rectangular box with the indicated
+% **   coordinates.  Must be specified before calls to  \axis,
+% **   \grid, \plotheading.
+% **  See Subsection 3.1 of the manual.
+\def\setplotarea x from #1 to #2, y from #3 to #4 {%
+  \!arealloc=\!M{#1}\!xunit \advance \!arealloc -\!xorigin
+  \!areabloc=\!M{#3}\!yunit \advance \!areabloc -\!yorigin
+  \!arearloc=\!M{#2}\!xunit \advance \!arearloc -\!xorigin
+  \!areatloc=\!M{#4}\!yunit \advance \!areatloc -\!yorigin
+  \!initinboundscheck
+  \!xaxislength=\!arearloc  \advance\!xaxislength -\!arealloc
+  \!yaxislength=\!areatloc  \advance\!yaxislength -\!areabloc
+  \!plotheadingoffset=\!zpt
+  \!dimenput {{\setbox0=\hbox{}\wd0=\!xaxislength\ht0=\!yaxislength\box0}}
+     [bl] (\!arealloc,\!areabloc)}
+%
+% ** \visibleaxes, \invisibleaxes
+% ** Switches for setting visibility of subsequent axes.
+% ** See Subsection 3.2 of the manual.
+\def\visibleaxes{%
+  \def\!axisvisibility{\!axisvisibletrue}}
+\def\invisibleaxes{%
+  \def\!axisvisibility{\!axisvisiblefalse}}
+%
+% ** The next few macros enable the user to fix up an erroneous keyword
+% **   in the \axis command.
+%  \newhelp is in ALLOCATIONS
+%  \newhelp\!keywordhelp{The keyword mentioned in the error message in unknown.
+%  Replace NEW KEYWORD in the indicated response by the keyword that
+%  should have been specified.}
+
+\def\!fixkeyword#1{%
+  \errhelp=\!keywordhelp
+  \errmessage{Unrecognized keyword `#1': \the\!keywordtoks{NEW KEYWORD}'}}
+
+%  \newtoks\!keywordtoks    In ALLOCATIONS.
+\!keywordtoks={enter `i\fixkeyword}
+
+\def\fixkeyword#1{%
+  \!nextkeyword#1 }
+
+% ** \axis BOTTOM-LEFT-TOP-RIGHT  [SHIFTEDTO xy=COORD] [VISIBLE-INVISIBLE]
+% **   [LABEL {label}] [TICKS] /
+% ** Exactly one of the keywords BOTTOM, LEFT, TOP, RIGHT must be
+% ** specified. Axis is drawn along the indicated edge of the current
+% ** plot area, shifted if the SHIFTEDTO option is used, visible or
+% ** invisible according the selected option, with an optional LABEL,
+% ** and optional TICKS (see ticks.tex for the options avialabel with
+% ** TICKS). The TICKS option must be the last one specified. The \axis
+% ** MUST be terminated with a / followed by a space.
+% ** See Subsection 3.2 of the manual for more information.
+
+% ** The various options of the \axis command are processed by the
+% ** \!nextkeyword macro defined below. For example,
+% ** `\!nextkeyword shiftedto ' expands to `\!axisshiftedto'.
+\def\axis {%
+  \def\!nextkeyword##1 {%
+    \expandafter\ifx\csname !axis##1\endcsname \relax
+      \def\!next{\!fixkeyword{##1}}%
+    \else
+      \def\!next{\csname !axis##1\endcsname}%
+    \fi
+    \!next}%
+  \!offset=\!zpt
+  \!axisvisibility
+  \!placeaxislabelfalse
+  \!nextkeyword}
+
+% ** This and the various macros that follow handle the keyword
+% ** specifications on the \axis command
+% ** See Subsection 3.2 of the manual.
+\def\!axisbottom{%
+  \!axisylevel=\!areabloc
+  \def\!tickxsign{0}%
+  \def\!tickysign{-}%
+  \def\!axissetup{\!axisxsetup}%
+  \def\!axislabeltbrl{t}%
+  \!nextkeyword}
+
+\def\!axistop{%
+  \!axisylevel=\!areatloc
+  \def\!tickxsign{0}%
+  \def\!tickysign{+}%
+  \def\!axissetup{\!axisxsetup}%
+  \def\!axislabeltbrl{b}%
+  \!nextkeyword}
+
+\def\!axisleft{%
+  \!axisxlevel=\!arealloc
+  \def\!tickxsign{-}%
+  \def\!tickysign{0}%
+  \def\!axissetup{\!axisysetup}%
+  \def\!axislabeltbrl{r}%
+  \!nextkeyword}
+
+\def\!axisright{%
+  \!axisxlevel=\!arearloc
+  \def\!tickxsign{+}%
+  \def\!tickysign{0}%
+  \def\!axissetup{\!axisysetup}%
+  \def\!axislabeltbrl{l}%
+  \!nextkeyword}
+
+\def\!axisshiftedto#1=#2 {%
+  \if 0\!tickxsign
+    \!axisylevel=\!M{#2}\!yunit
+    \advance\!axisylevel -\!yorigin
+  \else
+    \!axisxlevel=\!M{#2}\!xunit
+    \advance\!axisxlevel -\!xorigin
+  \fi
+  \!nextkeyword}
+
+\def\!axisvisible{%
+  \!axisvisibletrue
+  \!nextkeyword}
+
+\def\!axisinvisible{%
+  \!axisvisiblefalse
+  \!nextkeyword}
+
+\def\!axislabel#1 {%
+  \!axisLaBeL={#1}%
+  \!placeaxislabeltrue
+  \!nextkeyword}
+
+\expandafter\def\csname !axis/\endcsname{%
+  \!axissetup % This could done already by "ticks"; if so, now \relax
+  \if!placeaxislabel
+    \!placeaxislabel
+  \fi
+  \if +\!tickysign %                 ** (A "top" axis)
+    \!dimenA=\!axisylevel
+    \advance\!dimenA \!offset %      ** dimA = top of the axis structure
+    \advance\!dimenA -\!areatloc %   ** dimA = excess over the plot area
+    \ifdim \!dimenA>\!plotheadingoffset
+      \!plotheadingoffset=\!dimenA % ** Greatest excess over the plot area
+    \fi
+  \fi}
+
+% ** \grid {c} {r}
+% ** Partitions the plot area into c columns and r rows; see Subsection 3.3
+% ** of the manual.
+% ** (Other grid patterns can be drawn with the TICKS option of the \axis
+% ** command.
+\def\grid #1 #2 {%
+  \!countA=#1\advance\!countA 1
+  \axis bottom invisible ticks length <\!zpt> andacross quantity {\!countA} /
+  \!countA=#2\advance\!countA 1
+  \axis left   invisible ticks length <\!zpt> andacross quantity {\!countA} / }
+
+% ** \plotheading{HEADING}
+% ** Places HEADING centered above the top of the plotarea (and above
+% ** any top axis ticks marks, tick labels, and axis label); see
+% ** Subsection 3.3 of the manual.
+\def\plotheading#1 {%
+  \advance\!plotheadingoffset \headingtoplotskip
+  \!dimenput {#1} [B] <.5\!xaxislength,\!plotheadingoffset>
+    (\!arealloc,\!areatloc)}
+
+% ** From here on, the routines are internal.
+\def\!axisxsetup{%
+  \!axisxlevel=\!arealloc
+  \!axisstart=\!arealloc
+  \!axisend=\!arearloc
+  \!axisLength=\!xaxislength
+  \!!origin=\!xorigin
+  \!!unit=\!xunit
+  \!xswitchtrue
+  \if!axisvisible
+    \!makeaxis
+  \fi}
+
+\def\!axisysetup{%
+  \!axisylevel=\!areabloc
+  \!axisstart=\!areabloc
+  \!axisend=\!areatloc
+  \!axisLength=\!yaxislength
+  \!!origin=\!yorigin
+  \!!unit=\!yunit
+  \!xswitchfalse
+  \if!axisvisible
+    \!makeaxis
+  \fi}
+
+\def\!makeaxis{%
+  \setbox\!boxA=\hbox{% (Make a pseudo-y[x] tick for an x[y]-axis)
+    \beginpicture
+      \!setdimenmode
+      \setcoordinatesystem point at {\!zpt} {\!zpt}
+      \putrule from {\!zpt} {\!zpt} to
+        {\!tickysign\!tickysign\!axisLength}
+        {\!tickxsign\!tickxsign\!axisLength}
+    \endpicturesave <\!Xsave,\!Ysave>}%
+    \wd\!boxA=\!zpt
+    \!placetick\!axisstart}
+
+\def\!placeaxislabel{%
+  \advance\!offset \valuestolabelleading
+  \if!xswitch
+    \!dimenput {\the\!axisLaBeL} [\!axislabeltbrl]
+      <.5\!axisLength,\!tickysign\!offset> (\!axisxlevel,\!axisylevel)
+    \advance\!offset \!dp  % ** advance offset by the "tallness"
+    \advance\!offset \!ht  % ** of the label
+  \else
+    \!dimenput {\the\!axisLaBeL} [\!axislabeltbrl]
+      <\!tickxsign\!offset,.5\!axisLength> (\!axisxlevel,\!axisylevel)
+  \fi
+  \!axisLaBeL={}}
+
+
+% *******************************
+% *** ARROWS  (Draws arrows)  ***
+% *******************************
+%
+% ** User commands
+% **  \arrow <ARROW HEAD LENGTH> [MID FRACTION, BASE FRACTION]
+% **    [<XSHIFT,YSHIFT>] from XFROM YFROM to XTO YTO
+% **  \betweenarrows {TEXT} [orientation & shift] from XFROM YFROM to XTO YTO
+
+% ** \arrow <ARROW HEAD LENGTH> [MID FRACTION, BASE FRACTION]
+% **    [<XSHIFT,YSHIFT>] from XFROM YFROM to XTO YTO
+% ** Draws an arrow from (XFROM,YFROM) to (XTO,YTO).  The arrow head
+% ** is constructed two quadratic arcs, which extend back a distance
+% ** ARROW HEAD LENGTH (a dimension) on both sides of the arrow shaft.
+% ** All the way back the arcs are a distance BASE FRACTION*ARROW HEAD
+% ** LENGTH apart, while half-way back they are a distance MID FRACTION*
+% ** ARROW HEAD LENGTH apart. <XSHIFT,YSHIFT> is optional, and has
+% ** its usual interpreation. See Subsection 5.4 of the manual.
+
+\def\arrow <#1> [#2,#3]{%
+  \!ifnextchar<{\!arrow{#1}{#2}{#3}}{\!arrow{#1}{#2}{#3}<\!zpt,\!zpt> }}
+
+\def\!arrow#1#2#3<#4,#5> from #6 #7 to #8 #9 {%
+%
+% ** convert to dimensions
+  \!xloc=\!M{#8}\!xunit
+  \!yloc=\!M{#9}\!yunit
+  \!dxpos=\!xloc  \!dimenA=\!M{#6}\!xunit  \advance \!dxpos -\!dimenA
+  \!dypos=\!yloc  \!dimenA=\!M{#7}\!yunit  \advance \!dypos -\!dimenA
+  \let\!MAH=\!M%                         ** save current c/d mode
+  \!setdimenmode%                        ** go into dimension mode
+%
+  \!xshift=#4\relax  \!yshift=#5\relax%  ** pick up shift
+  \!reverserotateonly\!xshift\!yshift%   ** back rotate shift
+  \advance\!xshift\!xloc  \advance\!yshift\!yloc
+%
+% **  draw shaft of arrow
+  \!xS=-\!dxpos  \advance\!xS\!xshift
+  \!yS=-\!dypos  \advance\!yS\!yshift
+  \!start (\!xS,\!yS)
+  \!ljoin (\!xshift,\!yshift)
+%
+% ** find 32*cosine and 32*sine of angle of rotation
+  \!Pythag\!dxpos\!dypos\!arclength
+  \!divide\!dxpos\!arclength\!dxpos
+  \!dxpos=32\!dxpos  \!removept\!dxpos\!!cos
+  \!divide\!dypos\!arclength\!dypos
+  \!dypos=32\!dypos  \!removept\!dypos\!!sin
+%
+% ** construct arrowhead
+  \!halfhead{#1}{#2}{#3}%                ** draw half of arrow head
+  \!halfhead{#1}{-#2}{-#3}%              ** draw other half
+%
+  \let\!M=\!MAH%                         ** restore old c/d mode
+  \ignorespaces}
+%
+% ** draw half of arrow head
+  \def\!halfhead#1#2#3{%
+    \!dimenC=-#1%
+    \divide \!dimenC 2 %                 ** half way back
+    \!dimenD=#2\!dimenC%                 ** half the mid width
+    \!rotate(\!dimenC,\!dimenD)by(\!!cos,\!!sin)to(\!xM,\!yM)
+    \!dimenC=-#1%                        ** all the way back
+    \!dimenD=#3\!dimenC
+    \!dimenD=.5\!dimenD%                 ** half the full width
+    \!rotate(\!dimenC,\!dimenD)by(\!!cos,\!!sin)to(\!xE,\!yE)
+    \!start (\!xshift,\!yshift)
+    \advance\!xM\!xshift  \advance\!yM\!yshift
+    \advance\!xE\!xshift  \advance\!yE\!yshift
+    \!qjoin (\!xM,\!yM) (\!xE,\!yE)
+    \ignorespaces}
+
+
+% ** \betweenarrows {TEXT} [orientation & shift] from XFROM YFROM to XTO YTO
+% **   Makes things like <--- text --->, using arrow heads from TeX's fonts.
+% **   See Subsection 5.4 of the manual.
+\def\betweenarrows #1#2 from #3 #4 to #5 #6 {%
+  \!xloc=\!M{#3}\!xunit  \!xxloc=\!M{#5}\!xunit%
+  \!yloc=\!M{#4}\!yunit  \!yyloc=\!M{#6}\!yunit%
+  \!dxpos=\!xxloc  \advance\!dxpos by -\!xloc
+  \!dypos=\!yyloc  \advance\!dypos by -\!yloc
+  \advance\!xloc .5\!dxpos
+  \advance\!yloc .5\!dypos
+%
+  \let\!MBA=\!M%           ** save current coord\dimen mode
+  \!setdimenmode%          ** express locations in dimens
+  \ifdim\!dypos=\!zpt
+    \ifdim\!dxpos<\!zpt \!dxpos=-\!dxpos \fi
+    \put {\!lrarrows{\!dxpos}{#1}}#2{} at {\!xloc} {\!yloc}
+  \else
+    \ifdim\!dxpos=\!zpt
+      \ifdim\!dypos<\!zpt \!dypos=-\!zpt \fi
+      \put {\!udarrows{\!dypos}{#1}}#2{} at {\!xloc} {\!yloc}
+    \fi
+  \fi
+  \let\!M=\!MBA%           ** restore previous c/d mode
+  \ignorespaces}
+
+% ** Subroutine for left-right between arrows
+\def\!lrarrows#1#2{% #1=width, #2=text
+  {\setbox\!boxA=\hbox{$\mkern-2mu\mathord-\mkern-2mu$}%
+   \setbox\!boxB=\hbox{$\leftarrow$}\!dimenE=\ht\!boxB
+   \setbox\!boxB=\hbox{}\ht\!boxB=2\!dimenE
+   \hbox to #1{$\mathord\leftarrow\mkern-6mu
+     \cleaders\copy\!boxA\hfil
+     \mkern-6mu\mathord-$%
+     \kern.4em $\vcenter{\box\!boxB}$$\vcenter{\hbox{#2}}$\kern.4em
+     $\mathord-\mkern-6mu
+     \cleaders\copy\!boxA\hfil
+     \mkern-6mu\mathord\rightarrow$}}}
+
+% ** Subroutine for up-down between arrows
+\def\!udarrows#1#2{% #1=width, #2=text
+  {\setbox\!boxB=\hbox{#2}%
+   \setbox\!boxA=\hbox to \wd\!boxB{\hss$\vert$\hss}%
+   \!dimenE=\ht\!boxA \advance\!dimenE \dp\!boxA \divide\!dimenE 2
+   \vbox to #1{\offinterlineskip
+      \vskip .05556\!dimenE
+      \hbox to \wd\!boxB{\hss$\mkern.4mu\uparrow$\hss}\vskip-\!dimenE
+      \cleaders\copy\!boxA\vfil
+      \vskip-\!dimenE\copy\!boxA
+      \vskip\!dimenE\copy\!boxB\vskip.4em
+      \copy\!boxA\vskip-\!dimenE
+      \cleaders\copy\!boxA\vfil
+      \vskip-\!dimenE \hbox to \wd\!boxB{\hss$\mkern.4mu\downarrow$\hss}
+      \vskip .05556\!dimenE}}}
+
+
+% ***************************
+% *** BARS  (Draws bars)  ***
+% ***************************
+%
+% ** User commands:
+% ** \putbar [<XSHIFT,YSHIFT>] breadth <BREADTH> from XSTART YSTART
+% **   to XEND YEND
+% ** \setbars [<XSHIFT,YSHIFT>] breadth <BREADTH> baseline at XY = COORD
+% **   [baselabels ([B_ORIENTATION_x,B_ORIENTATION_y] <B_XSHIFT,B_YSHIFT>)]
+% **   [endlabels  ([E_ORIENTATION_x,E_ORIENTATION_y] <E_XSHIFT,E_YSHIFT>)]
+
+
+% ** \putbar [<XSHIFT,YSHIFT>] breadth <BREADTH> from XSTART YSTART
+% **   to XEND YEND
+% ** Either XSTART=XEND or YSTART=YEND. Draws a rectangle between
+% **   (XSTART,YSTART) & (XEND,YEND). The "depth" of the rectangle
+% **   is determined by those two plot positions; its other
+% **   dimension "breadth" is specified by the dimension BREADTH.
+% ** See Subsection 4.2 of the manual.
+\def\putbar#1breadth <#2> from #3 #4 to #5 #6 {%
+  \!xloc=\!M{#3}\!xunit  \!xxloc=\!M{#5}\!xunit%
+  \!yloc=\!M{#4}\!yunit  \!yyloc=\!M{#6}\!yunit%
+  \!dypos=\!yyloc  \advance\!dypos by -\!yloc
+  \!dimenI=#2
+%
+  \ifdim \!dimenI=\!zpt %            ** If 0 breadth
+    \putrule#1from {#3} {#4} to {#5} {#6} % ** Then draw line
+  \else %                            ** Else, put in a rectangle
+    \let\!MBar=\!M%                  ** save current c/d mode
+    \!setdimenmode %                 ** go into dimension mode
+    \divide\!dimenI 2
+    \ifdim \!dypos=\!zpt
+      \advance \!yloc -\!dimenI %    ** Equal y coordinates
+      \advance \!yyloc \!dimenI
+    \else
+      \advance \!xloc -\!dimenI %    ** Equal x coordinates
+      \advance \!xxloc \!dimenI
+    \fi
+    \putrectangle#1corners at {\!xloc} {\!yloc} and {\!xxloc} {\!yyloc}
+    \let\!M=\!MBar %                 ** restore c/d mode
+  \fi
+  \ignorespaces}
+
+
+% ** \setbars [<XSHIFT,YSHIFT>] breadth <BREADTH> baseline at XY = COORD
+% **   [baselabels ([B_ORIENTATION_x,B_ORIENTATION_y] <B_XSHIFT,B_YSHIFT>)]
+% **   [endlabels  ([E_ORIENTATION_x,E_ORIENTATION_y] <E_XSHIFT,E_YSHIFT>)]
+% ** This command puts PiCTeX into the bar graph drawing mode described
+% **   in Subsection 4.4 of the manual.
+\def\setbars#1breadth <#2> baseline at #3 = #4 {%
+  \edef\!barshift{#1}%
+  \edef\!barbreadth{#2}%
+  \edef\!barorientation{#3}%
+  \edef\!barbaseline{#4}%
+  \def\!bardobaselabel{\!bardoendlabel}%
+  \def\!bardoendlabel{\!barfinish}%
+  \let\!drawcurve=\!barcurve
+  \!setbars}
+\def\!setbars{%
+  \futurelet\!nextchar\!!setbars}
+\def\!!setbars{%
+  \if b\!nextchar
+    \def\!!!setbars{\!setbarsbget}%
+  \else
+    \if e\!nextchar
+      \def\!!!setbars{\!setbarseget}%
+    \else
+      \def\!!!setbars{\relax}%
+    \fi
+  \fi
+  \!!!setbars}
+\def\!setbarsbget baselabels (#1) {%
+  \def\!barbaselabelorientation{#1}%
+  \def\!bardobaselabel{\!!bardobaselabel}%
+  \!setbars}
+\def\!setbarseget endlabels (#1) {%
+  \edef\!barendlabelorientation{#1}%
+  \def\!bardoendlabel{\!!bardoendlabel}%
+  \!setbars}
+
+% ** \!barcurve
+% ** Draws a bargraph with preset values of barshift, barbreadth,
+% ** barorientation (x or y) and barbaseline (coordinate)
+\def\!barcurve #1 #2 {%
+  \if y\!barorientation
+    \def\!basexarg{#1}%
+    \def\!baseyarg{\!barbaseline}%
+  \else
+    \def\!basexarg{\!barbaseline}%
+    \def\!baseyarg{#2}%
+  \fi
+  \expandafter\putbar\!barshift breadth <\!barbreadth> from {\!basexarg}
+    {\!baseyarg} to {#1} {#2}
+  \def\!endxarg{#1}%
+  \def\!endyarg{#2}%
+  \!bardobaselabel}
+
+\def\!!bardobaselabel "#1" {%
+  \put {#1}\!barbaselabelorientation{} at {\!basexarg} {\!baseyarg}
+  \!bardoendlabel}
+
+\def\!!bardoendlabel "#1" {%
+  \put {#1}\!barendlabelorientation{} at {\!endxarg} {\!endyarg}
+  \!barfinish}
+
+\def\!barfinish{%
+  \!ifnextchar/{\!finish}{\!barcurve}}
+
+
+% ********************************
+% *** BOXES (Draws rectangles) ***
+% ********************************
+%
+% ** User commands:
+% **   \putrectangle [<XSHIFT,YSHIFT>] corners at  XCOORD1 YCOORD1
+% **     and  XCOORD2 YCOORD2
+% **   \shaderectangleson
+% **   \shaderectanglesoff
+% **   \frame [<SEPARATION>] {TEXT}
+% **   \rectangle <WIDTH> <HEIGHT>
+%
+%
+% **  \putrectangle [<XSHIFT,YSHIFT>] corners at XCOORD1 YCOORD1
+% **    and  XCOORD2 YCOORD2
+% **  Draws a rectangle with corners at (X1,Y1), (X2,Y1), (X1,Y2), (X2,Y2)
+% **  Lines have thickness \linethickness, and overlap at the corners.
+% **  The optional field  <XSHIFT,YSHIFT>  functions as with a \put command.
+% **  See Subsection 4.2 of the manual.
+\def\putrectangle{%
+  \!ifnextchar<{\!putrectangle}{\!putrectangle<\!zpt,\!zpt> }}
+\def\!putrectangle<#1,#2> corners at #3 #4 and #5 #6 {%
+%
+% ** get locations
+  \!xone=\!M{#3}\!xunit  \!xtwo=\!M{#5}\!xunit%
+  \!yone=\!M{#4}\!yunit  \!ytwo=\!M{#6}\!yunit%
+  \ifdim \!xtwo<\!xone
+    \!dimenI=\!xone  \!xone=\!xtwo  \!xtwo=\!dimenI
+  \fi
+  \ifdim \!ytwo<\!yone
+    \!dimenI=\!yone  \!yone=\!ytwo  \!ytwo=\!dimenI
+  \fi
+  \!dimenI=#1\relax  \advance\!xone\!dimenI  \advance\!xtwo\!dimenI
+  \!dimenI=#2\relax  \advance\!yone\!dimenI  \advance\!ytwo\!dimenI
+  \let\!MRect=\!M%                  ** save current coord/dimen mode
+  \!setdimenmode
+%
+% ** shade rectangle if appropriate
+  \!shaderectangle
+%
+% ** draw horizontal edges
+  \!dimenI=.5\linethickness
+  \advance \!xone  -\!dimenI%       ** adjust x-location to overlap corners
+  \advance \!xtwo   \!dimenI%       ** ditto
+  \putrule from {\!xone} {\!yone} to {\!xtwo} {\!yone}
+  \putrule from {\!xone} {\!ytwo} to {\!xtwo} {\!ytwo}
+%
+% ** draw vertical edges
+  \advance \!xone   \!dimenI%       ** restore original x-values
+  \advance \!xtwo  -\!dimenI%
+  \advance \!yone  -\!dimenI%       ** adjust y-location to overlap corners
+  \advance \!ytwo   \!dimenI%       ** ditto
+  \putrule from {\!xone} {\!yone} to {\!xone} {\!ytwo}
+  \putrule from {\!xtwo} {\!yone} to {\!xtwo} {\!ytwo}
+%
+  \let\!M=\!MRect%                  ** restore coord/dimen mode
+  \ignorespaces}
+
+% ** \shaderectangleson
+% **   Subsequent rectangles will be shaded according to
+% **   the current shading pattern.  Affects \putrectangle, \putbar,
+% **   \frame, \sethistograms, and \setbars. See Subsection 7.5 of the manual.
+\def\shaderectangleson{%
+  \def\!shaderectangle{\!!shaderectangle}%
+  \ignorespaces}
+% ** \shaderectanglesoff
+% **    Suppresses  \shaderectangleson.  The default.
+\def\shaderectanglesoff{%
+  \def\!shaderectangle{}%
+  \ignorespaces}
+
+\shaderectanglesoff
+
+% ** The following internal routine shades the current rectangle, when
+% **   \!shaderectangle = \!!shaderectangle .
+\def\!!shaderectangle{%
+  \!dimenA=\!xtwo  \advance \!dimenA -\!xone
+  \!dimenB=\!ytwo  \advance \!dimenB -\!yone
+  \ifdim \!dimenA<\!dimenB
+    \!startvshade (\!xone,\!yone,\!ytwo)
+    \!lshade      (\!xtwo,\!yone,\!ytwo)
+  \else
+    \!starthshade (\!yone,\!xone,\!xtwo)
+    \!lshade      (\!ytwo,\!xone,\!xtwo)
+  \fi
+  \ignorespaces}
+
+% ** \frame [<SEPARATION>] {TEXT}
+% ** Draws a frame of thickness linethickness about the box enclosing
+% **   TEXT; the frame is separated from the box by a distance of
+% **   SEPARATION.  The result is an hbox with the same baseline as TEXT.
+% **   If <SEPARATION> is omitted, you get the effect of <0pt>.
+% ** See Subsection 4.2 of the manual.
+\def\frame{%
+  \!ifnextchar<{\!frame}{\!frame<\!zpt> }}
+\long\def\!frame<#1> #2{%
+  \beginpicture
+    \setcoordinatesystem units <1pt,1pt> point at 0 0
+    \put {#2} [Bl] at 0 0
+    \!dimenA=#1\relax
+    \!dimenB=\!wd \advance \!dimenB \!dimenA
+    \!dimenC=\!ht \advance \!dimenC \!dimenA
+    \!dimenD=\!dp \advance \!dimenD \!dimenA
+    \let\!MFr=\!M
+    \!setdimenmode
+    \putrectangle corners at {-\!dimenA} {-\!dimenD} and {\!dimenB} {\!dimenC}
+    \!setcoordmode
+    \let\!M=\!MFr
+  \endpicture
+  \ignorespaces}
+
+% ** \rectangle <WIDTH> <HEIGHT>
+% ** Constructs a rectangle of width WIDTH and heigth HEIGHT.
+% ** See Subsection 4.2 of the manual.
+\def\rectangle <#1> <#2> {%
+  \setbox0=\hbox{}\wd0=#1\ht0=#2\frame {\box0}}
+
+
+% *********************************************
+% ***  CURVES  (Upper level \plot commands) ***
+% *********************************************
+%
+% ** User commands
+% **   \plot  DATA  /
+% **   \plot  "FILE NAME"
+% **   \setquadratic
+% **   \setlinear
+% **   \sethistograms
+% **   \vshade  ...
+% **   \hshade  ...
+
+% \plot: multi-purpose command. Draws histograms, bar graphs, piecewise-linear
+% or piecewise quadratic curves, depending on the setting of \!drawcurve.
+% See Subsections 4.3-4.5, 5.1, 5.2 of the manual.
+\def\plot{%
+  \!ifnextchar"{\!plotfromfile}{\!drawcurve}}
+\def\!plotfromfile"#1"{%
+  \expandafter\!drawcurve \normalinput #1 /}
+
+% Command to set piecewise quadratic mode
+% See Subsections 5.1, 7.3, and 7.4 of the manual.
+\def\setquadratic{%
+  \let\!drawcurve=\!qcurve
+  \let\!!Shade=\!!qShade
+  \let\!!!Shade=\!!!qShade}
+
+% Command to set piecewise linear mode
+% See Subsections 5.1, 7.3, and 7.4 of the manual.
+\def\setlinear{%
+  \let\!drawcurve=\!lcurve
+  \let\!!Shade=\!!lShade
+  \let\!!!Shade=\!!!lShade}
+
+% Command to set histogram mode
+% See Subsection 4.3 of the manual.
+\def\sethistograms{%
+  \let\!drawcurve=\!hcurve}
+
+% Commands to cycle through list of coordinates in piecewise quadratic
+% interpolation mode
+\def\!qcurve #1 #2 {%
+  \!start (#1,#2)
+  \!Qjoin}
+\def\!Qjoin#1 #2 #3 #4 {%
+  \!qjoin (#1,#2) (#3,#4)             % \!qjoin  is defined in QUADRATIC
+  \!ifnextchar/{\!finish}{\!Qjoin}}
+
+% Commands to cycle through list of coordinates in piecewise linear
+% interpolation mode
+\def\!lcurve #1 #2 {%
+  \!start (#1,#2)
+  \!Ljoin}
+\def\!Ljoin#1 #2 {%
+  \!ljoin (#1,#2)                    % \!ljoin  is defined in LINEAR
+  \!ifnextchar/{\!finish}{\!Ljoin}}
+
+\def\!finish/{\ignorespaces}
+
+% Command to cycle through list of coordinates in histogram mode
+\def\!hcurve #1 #2 {%
+  \edef\!hxS{#1}%
+  \edef\!hyS{#2}%
+  \!hjoin}
+\def\!hjoin#1 #2 {%
+  \putrectangle corners at {\!hxS} {\!hyS} and {#1} {#2}
+  \edef\!hxS{#1}%
+  \!ifnextchar/{\!finish}{\!hjoin}}
+
+
+% \vshade: See Subsection 7.3 of the manual.
+\def\vshade #1 #2 #3 {%
+  \!startvshade (#1,#2,#3)
+  \!Shadewhat}
+
+% \hshade: See Subsection 7.4 of the manual.
+\def\hshade #1 #2 #3 {%
+  \!starthshade (#1,#2,#3)
+  \!Shadewhat}
+
+% Commands to cycle through coordinates and optional "edge effect"
+% fields while shading.
+\def\!Shadewhat{%
+  \futurelet\!nextchar\!Shade}
+\def\!Shade{%
+  \if <\!nextchar
+    \def\!nextShade{\!!Shade}%
+  \else
+    \if /\!nextchar
+      \def\!nextShade{\!finish}%
+    \else
+      \def\!nextShade{\!!!Shade}%
+    \fi
+  \fi
+  \!nextShade}
+\def\!!lShade<#1> #2 #3 #4 {%
+  \!lshade <#1> (#2,#3,#4)                 % \!lshade is defined in SHADING
+  \!Shadewhat}
+\def\!!!lShade#1 #2 #3 {%
+  \!lshade (#1,#2,#3)
+  \!Shadewhat}
+\def\!!qShade<#1> #2 #3 #4 #5 #6 #7 {%
+  \!qshade <#1> (#2,#3,#4) (#5,#6,#7)      % \!qshade is defined in SHADING
+  \!Shadewhat}
+\def\!!!qShade#1 #2 #3 #4 #5 #6 {%
+  \!qshade (#1,#2,#3) (#4,#5,#6)
+  \!Shadewhat}
+
+% ** Set default interpolation mode
+\setlinear
+
+
+%  ********************************************
+%  *** DASHPATTERNS (Sets up dash patterns) ***
+%  ********************************************
+
+%  **  User commands:
+%  **    \setdashpattern <DIMEN1,DIMEN2,DIMEN3,...>
+%  **    \setdots <INTRADOT_DISTANCE>
+%  **    \setdotsnear <INTRADOT_DISTANCE> for <ARC LENGTH>
+%  **    \setdashes <DASH/SKIP_DISTANCE>
+%  **    \setdashesnear <DASH/SKIP_DISTANCE> for <ARC LENGTH>
+%  **    \setsolid
+%  **    \findlength {CURVE CMDS}
+
+%  **  Internal commands:
+%  **    \!dashingon
+%  **    \!dashingoff
+
+%  **  Dash patterns are specified by a balanced token list whose complete
+%  **    expansion has the form: DIMEN1,DIMEN2,DIMEN3,DIMEN4,... ; this produces
+%  **    an arc of length DIMEN1, a skip of length DIMEN2, an arc of length
+%  **    DIMEN3, a skip of length DIMEN4, ... .  Any number of DIMEN values may
+%  **    be given. The pattern is repeated as many times (perhaps fractional)
+%  **    as necessary to draw the curve.
+%  **  A dash pattern remains in effect until it is overridden by a call to
+%  **    \setdashpattern, or to \setdots, \setdotsnear ... , \setdashes,
+%  **    \setdashesnear ... , or \setsolid.
+%  **  Solid lines are the default.
+
+
+%  **  \def\setdashpattern <DIMEN1,DIMEN2,DIMEN3,...>
+%  **  The following routine converts a balanced list of tokens whose
+%  **  complete expansion has the form  DIMEN1,DIMEN2, ... , DIMENk  into
+%  **  three list macros that are used in drawing dashed rules and curves:
+%  **    !Flist:   \!Rule{DIMEN1}\!Skip{DIMEN2}\!Rule{DIMEN3}\!Skip{DIMEN4} ...
+%  **    !Blist:   ...\!Skip{DIMEN4}\!Rule{DIMEN3}\!Skip{DIMEN2}\!Rule{DIMEN1}
+%  **    !UDlist:  \\{DIMEN1}\\{DIMEN2}\\{DIMEN3}\\{DIMEN4} ...;
+%  **  calculates \!leaderlength := DIMEN1 + ... + DIMENk; and
+%  **  sets the curve drawing routines to dash mode.
+%  **  Those lists are used by the curve drawing routines.
+%  **  Dimenj ... may be given as an explicit dimension (e.g., 5pt), or
+%  **  as an expression involving a dimension register (e.g., -2.5\dimen0).
+%  **  See Subsection 6.2 of the manual
+\def\setdashpattern <#1>{%
+  \def\!Flist{}\def\!Blist{}\def\!UDlist{}%
+  \!countA=0
+  \!ecfor\!item:=#1\do{%
+    \!dimenA=\!item\relax
+    \expandafter\!rightappend\the\!dimenA\withCS{\\}\to\!UDlist%
+    \advance\!countA  1
+    \ifodd\!countA
+      \expandafter\!rightappend\the\!dimenA\withCS{\!Rule}\to\!Flist%
+      \expandafter\!leftappend\the\!dimenA\withCS{\!Rule}\to\!Blist%
+    \else
+      \expandafter\!rightappend\the\!dimenA\withCS{\!Skip}\to\!Flist%
+      \expandafter\!leftappend\the\!dimenA\withCS{\!Skip}\to\!Blist%
+    \fi}%
+  \!leaderlength=\!zpt
+  \def\!Rule##1{\advance\!leaderlength  ##1}%
+  \def\!Skip##1{\advance\!leaderlength  ##1}%
+  \!Flist%
+  \ifdim\!leaderlength>\!zpt
+  \else
+    \def\!Flist{\!Skip{24in}}\def\!Blist{\!Skip{24in}}\ignorespaces
+    \def\!UDlist{\\{\!zpt}\\{24in}}\ignorespaces
+    \!leaderlength=24in
+  \fi
+  \!dashingon}
+
+
+%  **  \!dashingon  -- puts the curve drawing routines into dash mode
+%  **  \!dashingoff -- puts the curve drawing routines into solid mode
+%  **  These are internal commands, invoked by \setdashpattern and \setsolid
+\def\!dashingon{%
+  \def\!advancedashing{\!!advancedashing}%
+  \def\!drawlinearsegment{\!lineardashed}%
+  \def\!puthline{\!putdashedhline}%
+  \def\!putvline{\!putdashedvline}%
+%  \def\!putsline{\!putdashedsline}%
+  \ignorespaces}%
+\def\!dashingoff{%
+  \def\!advancedashing{\relax}%
+  \def\!drawlinearsegment{\!linearsolid}%
+  \def\!puthline{\!putsolidhline}%
+  \def\!putvline{\!putsolidvline}%
+%  \def\!putsline{\!putsolidsline}%
+  \ignorespaces}
+
+
+%  **  \setdots <LENGTH>  --  sets up a dot/skip pattern where dot (actually
+%  **    the current plotsymbol) is plunked down once for every LENGTH
+%  **    traveled along the curve.  LENGTH defaults to 5pt.
+%  **    See Subsection 6.1 of the manual.
+\def\setdots{%
+  \!ifnextchar<{\!setdots}{\!setdots<5pt>}}
+\def\!setdots<#1>{%
+  \!dimenB=#1\advance\!dimenB -\plotsymbolspacing
+  \ifdim\!dimenB<\!zpt
+    \!dimenB=\!zpt
+  \fi
+\setdashpattern <\plotsymbolspacing,\!dimenB>}
+
+% ** \setdotsnear <LENGTH> for <ARC LENGTH>
+% ** sets up a dot pattern where the dots are approximately LENGTH apart,
+% ** the total length of the pattern is ARC LENGTH, and the pattern
+% ** begins and ends with a dot. See Subsection 6.3 of the manual.
+\def\setdotsnear <#1> for <#2>{%
+  \!dimenB=#2\relax  \advance\!dimenB -.05pt
+  \!dimenC=#1\relax  \!countA=\!dimenC
+  \!dimenD=\!dimenB  \advance\!dimenD .5\!dimenC  \!countB=\!dimenD
+  \divide \!countB  \!countA
+  \ifnum 1>\!countB
+    \!countB=1
+  \fi
+  \divide\!dimenB  \!countB
+  \setdots <\!dimenB>}
+
+%  **  \setdashes <LENGTH>  --  sets up a dash/skip pattern where the dash
+%  **    and the skip are each of length LENGTH (the dash is formed by
+%  **    plunking down the current plotsymbol over an arc of length LENGTH
+%  **    and so may actually be longer than LENGTH.  LENGTH defaults to 5pt.
+%  **    See Subsection 6.1 of the manual.
+\def\setdashes{%
+  \!ifnextchar<{\!setdashes}{\!setdashes<5pt>}}
+\def\!setdashes<#1>{\setdashpattern <#1,#1>}
+
+% ** \setdashesnear ...
+% ** Like \setdotsnear; the pattern begins and ends with a dash.
+% ** See Subsection 6.3 of the manual.
+\def\setdashesnear <#1> for <#2>{%
+  \!dimenB=#2\relax
+  \!dimenC=#1\relax  \!countA=\!dimenC
+  \!dimenD=\!dimenB  \advance\!dimenD .5\!dimenC  \!countB=\!dimenD
+  \divide \!countB  \!countA
+  \ifodd \!countB
+  \else
+    \advance \!countB  1
+  \fi
+  \divide\!dimenB  \!countB
+  \setdashes <\!dimenB>}
+
+%  **  \setsolid  --  puts the curve drawing routines in "solid line" mode,
+%  **    the default mode.  See Subsection 6.1 of the manual.
+\def\setsolid{%
+  \def\!Flist{\!Rule{24in}}\def\!Blist{\!Rule{24in}}%
+  \def\!UDlist{\\{24in}\\{\!zpt}}%
+  \!dashingoff}
+\setsolid
+
+%  **  \findlength {CURVE CMDS}
+%  **  PiCTeX executes the \start, \ljoin, and \qjoin cmds comprising
+%  **  CURVE CMDS without plotting anything, but stashes the length
+%  **  of the phantom curve away in \totalarclength.
+%  **  See Subsection 6.3 of the manual.
+\def\findlength#1{%
+  \begingroup
+    \setdashpattern <0pt, \maxdimen>
+    \setplotsymbol ({})
+    \dontsavelinesandcurves
+    #1%
+  \endgroup
+  \ignorespaces}
+
+
+% *************************************************************
+% *** DIVISION  (Does long division of dimension registers) ***
+% *************************************************************
+
+% ** User command:
+% **   \Divide {DIVIDEND} by {DIVISOR} forming {RESULT}
+
+% ** Internal command
+% **   \!divide{DIVIDEND}{DIVISOR}{RESULT}
+
+% **  \!divide DIVIDEND [by] DIVISOR [to get] ANSWER
+% **  Divides the dimension DIVIDEND by the dimension DIVISOR, placing the
+% **  quotient in the dimension register ANSWER.  Values are understood to
+% **  be in points.  E.g.  12.5pt/1.4pt=8.92857pt.
+% **  Quotient is accurate to 1/65536pt=2**[-16]pt
+% **  |DIVISOR| should be < 2048pt (about 28 inches).
+\def\!divide#1#2#3{%
+  \!dimenB=#1%                      **  dimB  holds current remainder (r)
+  \!dimenC=#2%                      **  dimC  holds divisor (d)
+  \!dimenD=\!dimenB%                **  dimD  holds quotient q=r/d for this
+  \divide \!dimenD \!dimenC%        **    step, in units of scaled pts
+  \!dimenA=\!dimenD%                **  dimA  eventually holds answer (a)
+  \multiply\!dimenD \!dimenC%       **  r <-- r - dq
+  \advance\!dimenB -\!dimenD%       **  First step complete. Have integer part
+%                                   **  of a, and corresponding remainder.
+  \!dimenD=\!dimenC%                **  Temporarily use dimD to hold |d|
+    \ifdim\!dimenD<\!zpt \!dimenD=-\!dimenD
+  \fi
+  \ifdim\!dimenD<64pt%              **  Branch on the magnitude of |d|
+    \!divstep[\!tfs]\!divstep[\!tfs]%
+  \else
+    \!!divide
+  \fi
+  #3=\!dimenA\ignorespaces}
+
+% **  The following code handles divisors  d  with
+% **    (1)  .88in =  64pt <= d <  256pt =  3.54in
+% **    (2) 3.54in = 256pt <= d < 2048pt = 28.34in
+% **  Anything bigger than that may result in an overflow condition.
+% **  For our purposes, we should never even see case (2).
+\def\!!divide{%
+  \ifdim\!dimenD<256pt
+    \!divstep[64]\!divstep[32]\!divstep[32]%
+  \else
+    \!divstep[8]\!divstep[8]\!divstep[8]\!divstep[8]\!divstep[8]%
+    \!dimenA=2\!dimenA
+  \fi}
+
+
+% **  The following macro does the real long division work.
+\def\!divstep[#1]{%                 **  #1 = "B"
+  \!dimenB=#1\!dimenB%              **  r <-- B*r
+  \!dimenD=\!dimenB%                **  dimD  holds quotient q=r/d for this
+    \divide \!dimenD by \!dimenC%   **    step, in units of scaled pts
+  \!dimenA=#1\!dimenA%              **  a <-- B*a + q
+    \advance\!dimenA by \!dimenD%
+  \multiply\!dimenD by \!dimenC%    **  r <-- r - dq
+    \advance\!dimenB by -\!dimenD}
+
+% **  \Divide:  See Subsection 9.3 of the manual.
+\def\Divide <#1> by <#2> forming <#3> {%
+  \!divide{#1}{#2}{#3}}
+
+
+% *********************************************
+% *** ELLIPSES (Draws ellipses and circles) ***
+% *********************************************
+
+% ** User commands
+% **   \ellipticalarc  axes ratio A:B  DEGREES degrees from XSTART YSTART
+% **      center at XCENTER YCENTER
+% **   \circulararc DEGREES degrees from XSTART YSTART
+% **      center at XCENTER YCENTER
+
+% ** Internal command
+% **   \!sinandcos{32*ANGLE in radians}{32*SIN}{32*COS}
+
+
+% **   \ellipticalarc  axes ratio A:B  DEGREES degrees from XSTART YSTART
+% **      center at XCENTER YCENTER
+% **    Draws a elliptical arc starting at the coordinate point (XSTART,YSTART).
+% **    The center of the ellipse of which the arc is a segment is at
+% **      (XCENTER,YCENTER).
+% **    The arc extends through an angle of DEGREES degrees (may be + or -).
+% **    A:B is the ratio of the length of the xaxis to the length of
+% **      the yaxis of the ellipse
+% **    Sqrt{[(XSTART-XCENTER)/A]**2 + [(YSTART-YCENTER)/B]**2}
+% **      must be < 512pt (about 7in).
+% **    Doesn't modify the dimensions (ht, dp, wd) of the PiCture under
+% **      construction.
+
+% ** \circulararc  --  See Subsection 5.3 of the manual.
+\def\circulararc{%
+  \ellipticalarc axes ratio 1:1 }
+
+% ** \ellipticalarc  --  See Subsection 5.3 of the manual.
+\def\ellipticalarc axes ratio #1:#2 #3 degrees from #4 #5 center at #6 #7 {%
+  \!angle=#3pt\relax%                    ** get angle
+  \ifdim\!angle>\!zpt
+    \def\!sign{}%                        ** counterclockwise
+  \else
+    \def\!sign{-}\!angle=-\!angle%       ** clockwise
+  \fi
+  \!xxloc=\!M{#6}\!xunit%                ** convert CENTER to dimension
+  \!yyloc=\!M{#7}\!yunit
+  \!xxS=\!M{#4}\!xunit%                  ** get STARTing point on rim of ellipse
+  \!yyS=\!M{#5}\!yunit
+  \advance\!xxS -\!xxloc%                ** make center of ellipse (0,0)
+  \advance\!yyS -\!yyloc
+  \!divide\!xxS{#1pt}\!xxS %             ** scale point on ellipse to point on
+  \!divide\!yyS{#2pt}\!yyS %                 corresponding circle
+%
+  \let\!MC=\!M%                          ** save current c/d mode
+  \!setdimenmode%                        ** go into dimension mode
+%
+  \!xS=#1\!xxS  \advance\!xS\!xxloc
+  \!yS=#2\!yyS  \advance\!yS\!yyloc
+  \!start (\!xS,\!yS)%
+  \!loop\ifdim\!angle>14.9999pt%         ** draw in major portion of ellipse
+    \!rotate(\!xxS,\!yyS)by(\!cos,\!sign\!sin)to(\!xxM,\!yyM)
+    \!rotate(\!xxM,\!yyM)by(\!cos,\!sign\!sin)to(\!xxE,\!yyE)
+    \!xM=#1\!xxM  \advance\!xM\!xxloc  \!yM=#2\!yyM  \advance\!yM\!yyloc
+    \!xE=#1\!xxE  \advance\!xE\!xxloc  \!yE=#2\!yyE  \advance\!yE\!yyloc
+    \!qjoin (\!xM,\!yM) (\!xE,\!yE)
+    \!xxS=\!xxE  \!yyS=\!yyE
+    \advance \!angle -15pt
+  \repeat
+  \ifdim\!angle>\!zpt%                   ** complete remaining arc, if any
+    \!angle=100.53096\!angle%            ** convert angle to radians, divide
+    \divide \!angle 360 %                **   by 2, and multiply by 32
+    \!sinandcos\!angle\!!sin\!!cos%      ** get 32*sin & 32*cos
+    \!rotate(\!xxS,\!yyS)by(\!!cos,\!sign\!!sin)to(\!xxM,\!yyM)
+    \!rotate(\!xxM,\!yyM)by(\!!cos,\!sign\!!sin)to(\!xxE,\!yyE)
+    \!xM=#1\!xxM  \advance\!xM\!xxloc  \!yM=#2\!yyM  \advance\!yM\!yyloc
+    \!xE=#1\!xxE  \advance\!xE\!xxloc  \!yE=#2\!yyE  \advance\!yE\!yyloc
+    \!qjoin (\!xM,\!yM) (\!xE,\!yE)
+  \fi
+%
+  \let\!M=\!MC%                          ** restore c/d mode
+  \ignorespaces}%                        **   if appropriate
+
+
+%  ** \!rotate(XREG,YREG)by(32cos,32sin)to(XXREG,YYREG)
+%  ** rotates (XREG,YREG) by angle with specfied scaled cos & sin to
+%  ** (XXREG,YYREG).  Uses \!dimenA & \!dimenB as scratch registers.
+\def\!rotate(#1,#2)by(#3,#4)to(#5,#6){%
+  \!dimenA=#3#1\advance \!dimenA -#4#2%   ** Rcos(x+t)=Rcosx*cost - Rsinx*sint
+  \!dimenB=#3#2\advance \!dimenB  #4#1%   ** Rsin(x+t)=Rsinx*cost + Rcosx*sint
+  \divide \!dimenA 32  \divide \!dimenB 32
+  #5=\!dimenA  #6=\!dimenB
+  \ignorespaces}
+\def\!sin{4.17684}%                       ** 32*sin(pi/24) (pi/24=7.5deg)
+\def\!cos{31.72624}%                      ** 32*cos(pi/24)
+
+
+%  ** \!sinandcos{32*ANGLE in radians}{\SINCS}{\COSCS}
+%  **   Computes the 32*sine and 32*cosine of a small ANGLE expressed in
+%  **   radians/32 and puts these values in the replacement texts of
+%  **   \SINCS and \COSCS
+\def\!sinandcos#1#2#3{%
+ \!dimenD=#1%                **  angle is expressed in radians/32: 1pt = 1/32rad
+ \!dimenA=\!dimenD%          **  dimA will eventually contain 32sin(angle)in pts
+ \!dimenB=32pt%              **  dimB will eventually contain 32cos(angle)in pts
+ \!removept\!dimenD\!value%  **  get value of 32*angle, without "pt"
+ \!dimenC=\!dimenD%          **  holds 32*angle**i/i! in pts
+ \!dimenC=\!value\!dimenC \divide\!dimenC by 64 %   ** now 32*angle**2/2
+ \advance\!dimenB by -\!dimenC%                     ** 32-32*angle**2/2
+ \!dimenC=\!value\!dimenC \divide\!dimenC by 96 %   ** now 32*angle**3/3!
+ \advance\!dimenA by -\!dimenC%                     ** now 32*(angle-angle**3/6)
+ \!dimenC=\!value\!dimenC \divide\!dimenC by 128 %  ** now 32*angle**4/4!
+ \advance\!dimenB by \!dimenC%
+ \!removept\!dimenA#2%                              ** set 32*sin(angle)
+ \!removept\!dimenB#3%                              ** set 32*cos(angle)
+ \ignorespaces}
+
+
+% *****************************************************************
+% ***  RULES  (Draws rules, i.e., horizontal & vertical lines)  ***
+% *****************************************************************
+
+% **  User command:
+% **    \putrule [<XDIMEN,YDIMEN>] from  XCOORD1 YCOORD1
+% **      to  XCOORD2 YCOORD2
+
+% **  Internal commands:
+% **    \!puthline [<XDIMEN,YDIMEN>]    (h = horizontal)
+% **      Set by dashpat to either: \!putsolidhline  or \!putdashedhline
+% **    \!putvline [<XDIMEN,YDIMEN>]    (v = vertical)
+% **      Either:  \!putsolidvline  or  \!putdashedvline
+
+
+% **  \putrule [<XDIMEN,YDIMEN>] from XCOORD1 YCOORD1
+% **    to XCOORD2 YCOORD2
+% **  Draws a rule -- dashed or solid depending on the current dash pattern --
+% **    from (X1,Y1) to (X2,Y2).  Uses TEK's  \hrule & \vrule & \leaders
+% **    constructions to handle horizontal & vertical lines efficiently both
+% **    in terms of execution time and space in the DVI file.
+% **  See Subsection 4.1 of the manual.
+\def\putrule#1from #2 #3 to #4 #5 {%
+  \!xloc=\!M{#2}\!xunit  \!xxloc=\!M{#4}\!xunit%
+  \!yloc=\!M{#3}\!yunit  \!yyloc=\!M{#5}\!yunit%
+  \!dxpos=\!xxloc  \advance\!dxpos by -\!xloc
+  \!dypos=\!yyloc  \advance\!dypos by -\!yloc
+%
+  \ifdim\!dypos=\!zpt
+    \def\!!Line{\!puthline{#1}}\ignorespaces
+  \else
+    \ifdim\!dxpos=\!zpt
+      \def\!!Line{\!putvline{#1}}\ignorespaces
+    \else
+       \def\!!Line{}
+    \fi
+  \fi
+  \let\!ML=\!M%           ** save current coord\dimen mode
+  \!setdimenmode%         ** express locations in dimens
+  \!!Line%
+  \let\!M=\!ML%           ** restore previous c/d mode
+  \ignorespaces}
+
+
+% **  \!putsolidhline [<XDIMEN,YDIMEN>]
+% **  Place horizontal solid line
+\def\!putsolidhline#1{%
+  \ifdim\!dxpos>\!zpt
+    \put{\!hline\!dxpos}#1[l] at {\!xloc} {\!yloc}
+  \else
+    \put{\!hline{-\!dxpos}}#1[l] at {\!xxloc} {\!yyloc}
+  \fi
+  \ignorespaces}
+
+% **  \!putsolidvline [shifted <XDIMEN,YDIMEN>]
+% **  Place vertical solid line
+\def\!putsolidvline#1{%
+  \ifdim\!dypos>\!zpt
+    \put{\!vline\!dypos}#1[b] at {\!xloc} {\!yloc}
+  \else
+    \put{\!vline{-\!dypos}}#1[b] at {\!xxloc} {\!yyloc}
+  \fi
+  \ignorespaces}
+
+\def\!hline#1{\hbox to #1{\leaders \hrule height\linethickness\hfill}}
+\def\!vline#1{\vbox to #1{\leaders \vrule width\linethickness\vfill}}
+
+
+% **  \!putdashedhline [<XDIMEN,YDIMEN>]
+% **  Place dashed horizontal line
+\def\!putdashedhline#1{%
+  \ifdim\!dxpos>\!zpt
+    \!DLsetup\!Flist\!dxpos
+    \put{\hbox to \!totalleaderlength{\!hleaders}\!hpartialpattern\!Rtrunc}
+      #1[l] at {\!xloc} {\!yloc}
+  \else
+    \!DLsetup\!Blist{-\!dxpos}
+    \put{\!hpartialpattern\!Ltrunc\hbox to \!totalleaderlength{\!hleaders}}
+      #1[r] at {\!xloc} {\!yloc}
+  \fi
+  \ignorespaces}
+
+% **  \!putdashedhline [<XDIMEN,YDIMEN>]
+% **  Place dashed vertical line
+\def\!putdashedvline#1{%
+  \!dypos=-\!dypos%            ** vertical leaders go from top to bottom
+  \ifdim\!dypos>\!zpt
+    \!DLsetup\!Flist\!dypos
+    \put{\vbox{\vbox to \!totalleaderlength{\!vleaders}
+      \!vpartialpattern\!Rtrunc}}#1[t] at {\!xloc} {\!yloc}
+  \else
+    \!DLsetup\!Blist{-\!dypos}
+    \put{\vbox{\!vpartialpattern\!Ltrunc
+      \vbox to \!totalleaderlength{\!vleaders}}}#1[b] at {\!xloc} {\!yloc}
+  \fi
+  \ignorespaces}
+
+
+% **  The rest of the macros in this section are subroutines used by
+% **  \!putdashedhline and \!putdashedvline.
+\def\!DLsetup#1#2{%            ** Dashed-Line set up
+  \let\!RSlist=#1%             ** set !Rule-Skip list
+  \!countB=#2%                 ** convert rule length to integer (number of sps)
+  \!countA=\!leaderlength%     ** ditto, leaderlength
+  \divide\!countB by \!countA% ** number of complete leader units
+  \!totalleaderlength=\!countB\!leaderlength
+  \!Rresiduallength=#2%
+  \advance \!Rresiduallength by -\!totalleaderlength%  \** excess length
+  \!Lresiduallength=\!leaderlength
+  \advance \!Lresiduallength by -\!Rresiduallength
+  \ignorespaces}
+
+\def\!hleaders{%
+  \def\!Rule##1{\vrule height\linethickness width##1}%
+  \def\!Skip##1{\hskip##1}%
+  \leaders\hbox{\!RSlist}\hfill}
+
+\def\!hpartialpattern#1{%
+  \!dimenA=\!zpt \!dimenB=\!zpt
+  \def\!Rule##1{#1{##1}\vrule height\linethickness width\!dimenD}%
+  \def\!Skip##1{#1{##1}\hskip\!dimenD}%
+  \!RSlist}
+
+\def\!vleaders{%
+  \def\!Rule##1{\hrule width\linethickness height##1}%
+  \def\!Skip##1{\vskip##1}%
+  \leaders\vbox{\!RSlist}\vfill}
+
+\def\!vpartialpattern#1{%
+  \!dimenA=\!zpt \!dimenB=\!zpt
+  \def\!Rule##1{#1{##1}\hrule width\linethickness height\!dimenD}%
+  \def\!Skip##1{#1{##1}\vskip\!dimenD}%
+  \!RSlist}
+
+\def\!Rtrunc#1{\!trunc{#1}>\!Rresiduallength}
+\def\!Ltrunc#1{\!trunc{#1}<\!Lresiduallength}
+
+\def\!trunc#1#2#3{%
+  \!dimenA=\!dimenB
+  \advance\!dimenB by #1%
+  \!dimenD=\!dimenB  \ifdim\!dimenD#2#3\!dimenD=#3\fi
+  \!dimenC=\!dimenA  \ifdim\!dimenC#2#3\!dimenC=#3\fi
+  \advance \!dimenD by -\!dimenC}
+
+
+%  ****************************************************************
+%  ***  LINEAR ARC  (Draws straight lines -- solid and dashed)  ***
+%  ****************************************************************
+
+%  **  User commands
+%  **    \inboundscheckoff
+%  **    \inboundscheckon
+
+%  **  Internal commands
+%  **    \!start (XCOORD,YCOORD)
+%  **    \!ljoin (XCOORD,YCOORD)
+%  **    \!drawlinearsegment  --  set by \dashpat to either
+%  **      \!linearsolid  or  \!lineardashed
+%  **    \!advancedashing     --  set by \dashpat to either
+%  **       \relax  or  \!!advancedashing
+%  **    \!plotifinbounds     --  set by \inboundscheck off/on to either
+%  **       \!plot  or  \!!plotifinbounds
+%  **    \!initinboundscheck  --  set by \inboundscheck off/on to either
+%  **       \relax  or  \!!initinboundscheck
+
+
+%  \plotsymbolspacing  ** distance between consecutive plot positions
+%  \!xS                ** starting x
+%  \!yS                ** starting y
+%  \!xE                ** ending   x
+%  \!yE                ** ending   y
+%  \!xdiff             ** x_end - x_start
+%  \!ydiff             ** y_end - y_start
+%  \!distacross        ** how far along curve next point to be plotted is
+%  \!arclength         ** approximate length of arc for current interval
+%  \!downlength        ** remaining length for "pen" to be down
+%  \!uplength          ** length for "pen" to be down
+%  \!intervalno        ** counts segments to curve
+%  \totalarclength     ** cumulative distance along curve
+%  \!npoints           ** approximately  (arc length / plotsymbolspacing)
+
+%  **  Calls -- \!Pythag, \!divide, \!plot
+
+
+%  **  \!start (XCOORD,YCOORD)
+%  **  Sets initial point for linearly (or quadratically) interpolated curve
+\def\!start (#1,#2){%
+  \!plotxorigin=\!xorigin  \advance \!plotxorigin by \!plotsymbolxshift
+  \!plotyorigin=\!yorigin  \advance \!plotyorigin by \!plotsymbolyshift
+  \!xS=\!M{#1}\!xunit \!yS=\!M{#2}\!yunit
+  \!rotateaboutpivot\!xS\!yS
+  \!copylist\!UDlist\to\!!UDlist% **\!UDlist has the form \\{dimen1}\\{dimen2}..
+%                                 ** Routine will draw dashed line with pen
+%                                 ** down for dimen1, up for dimen2, ...
+  \!getnextvalueof\!downlength\from\!!UDlist
+  \!distacross=\!zpt%             ** 1st point goes at start of curve
+  \!intervalno=0 %                ** initialize interval counter
+  \global\totalarclength=\!zpt%   ** initialize distance traveled along curve
+  \ignorespaces}
+
+
+%  **  \!ljoin (XCOORD,YCOORD)
+%  **  Draws a straight line starting at the last point specified
+%  **    by the most recent \!start, \!ljoin, or \!qjoin, and
+%  **    ending at (XCOORD,YCOORD).
+\def\!ljoin (#1,#2){%
+  \advance\!intervalno by 1
+  \!xE=\!M{#1}\!xunit \!yE=\!M{#2}\!yunit
+  \!rotateaboutpivot\!xE\!yE
+  \!xdiff=\!xE \advance \!xdiff by -\!xS%**  xdiff = xE - xS
+  \!ydiff=\!yE \advance \!ydiff by -\!yS%**  ydiff = yE - yS
+  \!Pythag\!xdiff\!ydiff\!arclength%     **  arclength = sqrt(xdiff**2+ydiff**2)
+  \global\advance \totalarclength by \!arclength%
+  \!drawlinearsegment%   ** set by dashpat to \!linearsolid or \!lineardashed
+  \!xS=\!xE \!yS=\!yE%   ** shift ending points to starting points
+  \ignorespaces}
+
+
+% **  The following routine is used to draw a "solid" line between (xS,yS)
+% **  and (xE,yE).  Points are spaced nearly every  \plotsymbolspacing length
+% **  along the line.
+\def\!linearsolid{%
+  \!npoints=\!arclength
+  \!countA=\plotsymbolspacing
+  \divide\!npoints by \!countA%      ** now #pts =. arclength/plotsymbolspacing
+  \ifnum \!npoints<1
+    \!npoints=1
+  \fi
+  \divide\!xdiff by \!npoints
+  \divide\!ydiff by \!npoints
+  \!xpos=\!xS \!ypos=\!yS
+%
+  \loop\ifnum\!npoints>-1
+    \!plotifinbounds
+    \advance \!xpos by \!xdiff
+    \advance \!ypos by \!ydiff
+    \advance \!npoints by -1
+  \repeat
+  \ignorespaces}
+
+
+% ** The following routine is used to draw a dashed line between (xS,yS)
+% ** and (xE,yE). The dash pattern continues from the previous segment.
+\def\!lineardashed{%
+% **
+  \ifdim\!distacross>\!arclength
+    \advance \!distacross by -\!arclength  %nothing to plot in this interval
+%
+  \else
+%
+    \loop\ifdim\!distacross<\!arclength
+%     ** plot point, interpolating linearly in x and y
+      \!divide\!distacross\!arclength\!dimenA%  ** dimA = across/arclength
+      \!removept\!dimenA\!t%  ** \!t holds value in dimA, without the "pt"
+      \!xpos=\!t\!xdiff \advance \!xpos by \!xS
+      \!ypos=\!t\!ydiff \advance \!ypos by \!yS
+      \!plotifinbounds
+      \advance\!distacross by \plotsymbolspacing
+      \!advancedashing
+    \repeat
+%
+    \advance \!distacross by -\!arclength%    ** prepare for next interval
+  \fi
+  \ignorespaces}
+
+
+\def\!!advancedashing{%
+  \advance\!downlength by -\plotsymbolspacing
+  \ifdim \!downlength>\!zpt
+  \else
+    \advance\!distacross by \!downlength
+    \!getnextvalueof\!uplength\from\!!UDlist
+    \advance\!distacross by \!uplength
+    \!getnextvalueof\!downlength\from\!!UDlist
+  \fi}
+
+
+% ** \inboundscheckoff & \inboundscheckon: See Subsection 5.5 of the manual.
+\def\inboundscheckoff{%
+  \def\!plotifinbounds{\!plot(\!xpos,\!ypos)}%
+  \def\!initinboundscheck{\relax}\ignorespaces}
+\def\inboundscheckon{%
+  \def\!plotifinbounds{\!!plotifinbounds}%
+  \def\!initinboundscheck{\!!initinboundscheck}%
+  \!initinboundscheck\ignorespaces}
+\inboundscheckoff
+
+% ** The following code plots the current point only if it falls in the
+% ** current plotarea.  It doesn't matter if the coordinate system has
+% ** changed since the plotarea was set up.  However, shifts of the plot
+% ** are ignored (how the plotsymbol stands relative to its plot position is
+% ** unknown anyway).
+\def\!!plotifinbounds{%
+  \ifdim \!xpos<\!checkleft
+  \else
+    \ifdim \!xpos>\!checkright
+    \else
+      \ifdim \!ypos<\!checkbot
+      \else
+         \ifdim \!ypos>\!checktop
+         \else
+           \!plot(\!xpos,\!ypos)
+         \fi
+      \fi
+    \fi
+  \fi}
+
+
+\def\!!initinboundscheck{%
+  \!checkleft=\!arealloc     \advance\!checkleft by \!xorigin
+  \!checkright=\!arearloc    \advance\!checkright by \!xorigin
+  \!checkbot=\!areabloc      \advance\!checkbot by \!yorigin
+  \!checktop=\!areatloc      \advance\!checktop by \!yorigin}
+
+
+% *********************************
+% *** LOGTEN  (Log_10 function) ***
+% *********************************
+%
+% ** \!logten{X}
+% ** Calculates log_10 of X.  X and LOG10(X) are in fixed point notation.
+% **  X must be positive; it may have an optional `+' sign; any number
+% **  of digits may be specified for X.  The absolute error in LOG10(X) is
+% **  less than .0001 (probably < .00006).  That's about as good as you
+% **  hope for, since TEX only operates to 5 figures after the decimal
+% **  point anyway.
+
+%  \!rootten=3.162278pt       **** These are values are set in ALLOCATIONS
+%  \!tenAe=2.543275pt  (=A5)
+%  \!tenAc=2.773839pt  (=A3)
+%  \!tenAa=8.690286pt  (=A1)
+
+\def\!logten#1#2{%
+  \expandafter\!!logten#1\!nil
+  \!removept\!dimenF#2%
+  \ignorespaces}
+
+\def\!!logten#1#2\!nil{%
+  \if -#1%
+    \!dimenF=\!zpt
+    \def\!next{\ignorespaces}%
+  \else
+    \if +#1%
+      \def\!next{\!!logten#2\!nil}%
+    \else
+      \if .#1%
+        \def\!next{\!!logten0.#2\!nil}%
+      \else
+        \def\!next{\!!!logten#1#2..\!nil}%
+      \fi
+    \fi
+  \fi
+  \!next}
+
+\def\!!!logten#1#2.#3.#4\!nil{%
+  \!dimenF=1pt %                 ** DimF holds log10 original argument
+  \if 0#1%
+    \!!logshift#3pt %            ** Argument < 1
+  \else %                        ** Argument >= 1
+    \!logshift#2/%               ** Shift decimal pt as many places
+    \!dimenE=#1.#2#3pt %         **   as there are figures in #2
+  \fi %                          ** Now dimE holds revised X want log10 of
+  \ifdim \!dimenE<\!rootten%          ** Transform X to XX between sqrt(10)
+    \multiply \!dimenE 10 %           **   and 10*sqrt(10)
+    \advance  \!dimenF -1pt
+  \fi
+  \!dimenG=\!dimenE%                  ** dimG <- (XX + 10)
+    \advance\!dimenG 10pt
+  \advance\!dimenE -10pt %            ** dimE <- (XX - 10)
+  \multiply\!dimenE 10 %              ** dimE = 10*(XX-10)
+  \!divide\!dimenE\!dimenG\!dimenE%   ** Now dimE=10t==10*(XX-10)/(XX+10)
+  \!removept\!dimenE\!t%              ** !t=10t, with "pt" removed
+  \!dimenG=\!t\!dimenE%               ** dimG=100t**2
+  \!removept\!dimenG\!tt%             ** !tt=100t**2, with "pt" removed
+  \!dimenH=\!tt\!tenAe%               ** dimH=10*a5*(10t)**2 /100
+    \divide\!dimenH 100
+  \advance\!dimenH \!tenAc%           ** ditto + 10*a3
+  \!dimenH=\!tt\!dimenH%              ** ditto * (10t)**2 /100
+    \divide\!dimenH 100
+  \advance\!dimenH \!tenAa%           ** ditto + 10*a1
+  \!dimenH=\!t\!dimenH%               ** ditto * 10t / 100
+    \divide\!dimenH 100 %             ** Now dimH = log10(XX) - 1
+  \advance\!dimenF \!dimenH}%         ** dimF = log10(X)
+
+\def\!logshift#1{%
+  \if #1/%
+    \def\!next{\ignorespaces}%
+  \else
+    \advance\!dimenF 1pt
+    \def\!next{\!logshift}%
+  \fi
+  \!next}
+
+ \def\!!logshift#1{%
+   \advance\!dimenF -1pt
+   \if 0#1%
+     \def\!next{\!!logshift}%
+   \else
+     \if p#1%
+       \!dimenF=1pt
+       \def\!next{\!dimenE=1p}%
+     \else
+       \def\!next{\!dimenE=#1.}%
+     \fi
+   \fi
+   \!next}
+
+
+% ***********************************************************
+% *** PICTURES (Basic setups for PiCtures; \put commands) ***
+% ***********************************************************
+
+% **  User Commands:
+% **    \beginpicture
+% **    \endpicture
+% **    \endpicturesave <XREG,YREG>
+% **    \setcoordinatesystem units <XUNIT,YUNIT> point at XREF YREF
+% **    \put {OBJECT} [ORIENTATION] <XSHIFT,YSHIFT> at XCOORD YCOORD
+% **    \multiput {OJBECT} [ORIENTATION] <XSHIFT,YSHIFT>) at
+% **      XCOORD YCOORD
+% **      *NUMBER_OF_TIMES DXCOORD DYCOORD  /
+% **    \accountingon
+% **    \accountingoff
+% **    \stack [ORIENTATION] <LEADING> {LIST OF ITEMS}
+% **    \lines [ORIENTATION] {LINES}
+% **    \Lines [ORIENTATION] {LINES}
+% **    \setdimensionmode
+% **    \setcoordinatemode
+% **    \Xdistance
+% **    \Ydistance
+
+% **  Internal commands:
+% **    \!setputobject{OBJECT}{[ORIENTATION]<XSHIFT,YSHIFT>}
+% **    \!dimenput{OBJECT}[ORIENTATION]<XSHIFT,YSHIFT>(XDIMEN,YDIMEN)
+% **    \!setdimenmode
+% **    \!setcoordmode
+% **    \!ifdimenmode
+% **    \!ifcoordmode
+
+
+% **  \beginpicture
+% **  \endpicture
+% **  \endpicturesave <XREG,YREG>
+% **    \beginpicture ... \endpicture  creates an hbox.  Objects are
+% **    placed in this box using the \put command and the like (see below).
+% **    The location of an object is specified in terms of coordinate system(s)
+% **    established by \setcoordinatesystem.  Each coordinate system (there
+% **    might be just one) specifies the length of 1 horizontal unit, the length
+% **    of 1 vertical unit, and the coordinates of a "reference point".  The
+% **    reference points of various coordinate systems will be in the same
+% **    physical location.  The macros keep track of the size of the objects
+% **    and their locations. The resulting hbox is the smallest hbox which
+% **    encloses all the objects, and whose TEK reference point is the point
+% **    on the left edge of the box closest vertically to the PICTEX reference
+% **    point. Using \endpicturesave, you can (globally) save the distance TEK's
+% **    reference point is to the right (respectively, up from) PICTEX's
+% **    reference point in the dimension register \XREG (respectively \YREG).
+% **    You can then \put the picture OBJECT into a larger picture so that its
+% **    reference point is at (XCOORD,YCOORD) with the command
+% **      \put {picture OBJECT} [Bl] <\XREG, \YREG> at  XCOORD YCOORD
+
+% **  \beginpicture : See Subsection 1.1 of the manual.
+\def\beginpicture{%
+  \setbox\!picbox=\hbox\bgroup%
+  \!xleft=\maxdimen
+  \!xright=-\maxdimen
+  \!ybot=\maxdimen
+  \!ytop=-\maxdimen}
+
+% **  \endpicture : See Subsection 1.1 of the manual.
+\def\endpicture{%
+  \ifdim\!xleft=\maxdimen%  ** check if nothing was put in picbox
+    \!xleft=\!zpt \!xright=\!zpt \!ybot=\!zpt \!ytop=\!zpt
+  \fi
+  \global\!Xleft=\!xleft \global\!Xright=\!xright
+  \global\!Ybot=\!ybot \global\!Ytop=\!ytop
+  \egroup%
+  \ht\!picbox=\!Ytop  \dp\!picbox=-\!Ybot
+  \ifdim\!Ybot>\!zpt
+  \else
+    \ifdim\!Ytop<\!zpt
+      \!Ybot=\!Ytop
+    \else
+      \!Ybot=\!zpt
+    \fi
+  \fi
+  \hbox{\kern-\!Xleft\lower\!Ybot\box\!picbox\kern\!Xright}}
+
+% **  \endpicturesave : See Subsection 8.4 of the manual.
+\def\endpicturesave <#1,#2>{%
+  \endpicture \global #1=\!Xleft \global #2=\!Ybot \ignorespaces}
+
+
+% **   \setcoordinatesystem units <XUNIT,YUNIT>
+% **     point at XREF YREF
+% **   Each of `units <XUNIT,YUNIT>' and `point at XREF YREF'
+% **     are optional.
+% **   Unit lengths must be given in dimensions (e.g., <10pt,1in>).
+% **     Default unit lengths are 1pt, 1pt, or previous unit lengths.
+% **   Reference point is specified in current units (e.g., 3 5 ).
+% **     Default reference point is 0 0 , or previous reference point.
+% **   Unit lengths and reference points obey TEX's scoping rules.
+% **   See Subsection 1.2 of the manual.
+\def\setcoordinatesystem{%
+  \!ifnextchar{u}{\!getlengths }
+    {\!getlengths units <\!xunit,\!yunit>}}
+\def\!getlengths units <#1,#2>{%
+  \!xunit=#1\relax
+  \!yunit=#2\relax
+  \!ifcoordmode
+    \let\!SCnext=\!SCccheckforRP
+  \else
+    \let\!SCnext=\!SCdcheckforRP
+  \fi
+  \!SCnext}
+\def\!SCccheckforRP{%
+  \!ifnextchar{p}{\!cgetreference }
+    {\!cgetreference point at {\!xref} {\!yref} }}
+\def\!cgetreference point at #1 #2 {%
+  \edef\!xref{#1}\edef\!yref{#2}%
+  \!xorigin=\!xref\!xunit  \!yorigin=\!yref\!yunit
+  \!initinboundscheck % ** See linear.tex
+  \ignorespaces}
+\def\!SCdcheckforRP{%
+  \!ifnextchar{p}{\!dgetreference}%
+    {\ignorespaces}}
+\def\!dgetreference point at #1 #2 {%
+  \!xorigin=#1\relax  \!yorigin=#2\relax
+  \ignorespaces}
+
+
+%  ** \put {OBJECT} [XY] <XDIMEN,YDIMEN> at (XCOORD,YCOORD)
+%  **   `[XY]' and `<XDIMEN,YDIMEN>' are optional.
+%  **   First OBJECT is placed in an hbox (the "objectbox") and then a
+%  **     "reference point" is assigned to the objectbox as follows:
+%  **     [1] first, the reference point is taken to be the center of the box;
+%  **     [2] next, centering is overridden by the specifications
+%  **           X=l -- reference point along the left edge of the objectbox
+%  **           X=r -- reference point along the right edge of the objectbox
+%  **           Y=b -- reference point along the bottom edge of the objectbox
+%  **           Y=B -- reference point along the Baseline of the objectbox
+%  **           Y=t -- reference point along the top edge of the objectbox;
+%  **     [3] finally the reference point is shifted left by XDIMEN, down
+%  **           by YDIMEN  (both default to 0pt).
+%  **   The objectbox is placed within PICBOX with its reference point at
+%  **     (XCOORD,YCOORD).
+%  **   If OBJECT is a saved box, say  box0, you have to write
+%  **     \put{\box0}...   or  \put{\copy0}...
+%  **   The objectbox is void after the put.
+%  **   See Subsection 2.1 of the manual.
+\long\def\put#1#2 at #3 #4 {%
+  \!setputobject{#1}{#2}%
+  \!xpos=\!M{#3}\!xunit  \!ypos=\!M{#4}\!yunit
+  \!rotateaboutpivot\!xpos\!ypos%
+  \advance\!xpos -\!xorigin  \advance\!xpos -\!xshift
+  \advance\!ypos -\!yorigin  \advance\!ypos -\!yshift
+  \kern\!xpos\raise\!ypos\box\!putobject\kern-\!xpos%
+  \!doaccounting\ignorespaces}
+
+%  **   \multiput etc.  Like  \put.  The objectbox is not voided until the
+%  **     termininating /, and is placed repeatedly with:
+%  **     XCOORD YCOORD -- the objectbox is put down with its reference point
+%  **       at (XCOORD,YCOORD);
+%  **     *N DXCOORD DYCOORD -- each of N times the current
+%  **       (xcoord,ycoord) is incremented by (DXCOORD,DYCOORD), and the
+%  **       objectbox is put down with its reference point at (xcoord,ycoord)
+%  **       (This specification has to follow an XCOORD YCOORD pair)
+%  **     See Subsection 2.2 of the manual.
+\long\def\multiput #1#2 at {%
+  \!setputobject{#1}{#2}%
+  \!ifnextchar"{\!putfromfile}{\!multiput}}
+\def\!putfromfile"#1"{%
+  \expandafter\!multiput \normalinput #1 /}
+\def\!multiput{%
+  \futurelet\!nextchar\!!multiput}
+\def\!!multiput{%
+  \if *\!nextchar
+    \def\!nextput{\!alsoby}%
+  \else
+    \if /\!nextchar
+      \def\!nextput{\!finishmultiput}%
+    \else
+      \def\!nextput{\!alsoat}%
+    \fi
+  \fi
+  \!nextput}
+\def\!finishmultiput/{%
+  \setbox\!putobject=\hbox{}%
+  \ignorespaces}
+
+%  **   \!alsoat XCOORD YCOORD
+%  **     The objectbox is put down with reference point at XCOORD,YCOORD
+\def\!alsoat#1 #2 {%
+  \!xpos=\!M{#1}\!xunit  \!ypos=\!M{#2}\!yunit
+  \!rotateaboutpivot\!xpos\!ypos%
+  \advance\!xpos -\!xorigin  \advance\!xpos -\!xshift
+  \advance\!ypos -\!yorigin  \advance\!ypos -\!yshift
+  \kern\!xpos\raise\!ypos\copy\!putobject\kern-\!xpos%
+  \!doaccounting
+  \!multiput}
+
+% **   \!alsoby*N DXCOORD DYCOORD
+% **     N times, the current (XCOORD,YCOORD) is advanced by (DXCOORD,DYCOORD),
+% **     and the current (shifted, oriented) OBJECT is put down.
+\def\!alsoby*#1 #2 #3 {%
+  \!dxpos=\!M{#2}\!xunit \!dypos=\!M{#3}\!yunit
+  \!rotateonly\!dxpos\!dypos
+  \!ntemp=#1%
+  \!!loop\ifnum\!ntemp>0
+    \advance\!xpos by \!dxpos  \advance\!ypos by \!dypos
+    \kern\!xpos\raise\!ypos\copy\!putobject\kern-\!xpos%
+    \advance\!ntemp by -1
+  \repeat
+  \!doaccounting
+  \!multiput}
+
+% **  \accountingoff : Suspends PiCTeX's accounting of the aggregate
+% **    size of the picture box.
+% **  \accounting on : Reinstates accounting.
+% **  See Subsection 8.2 of the manual.
+\def\accountingon{\def\!doaccounting{\!!doaccounting}\ignorespaces}
+\def\accountingoff{\def\!doaccounting{}\ignorespaces}
+\accountingon
+\def\!!doaccounting{%
+  \!xtemp=\!xpos
+  \!ytemp=\!ypos
+  \ifdim\!xtemp<\!xleft
+     \!xleft=\!xtemp
+  \fi
+  \advance\!xtemp by  \!wd
+  \ifdim\!xright<\!xtemp
+    \!xright=\!xtemp
+  \fi
+  \advance\!ytemp by -\!dp
+  \ifdim\!ytemp<\!ybot
+    \!ybot=\!ytemp
+  \fi
+  \advance\!ytemp by  \!dp
+  \advance\!ytemp by  \!ht
+  \ifdim\!ytemp>\!ytop
+    \!ytop=\!ytemp
+  \fi}
+
+\long\def\!setputobject#1#2{%
+  \setbox\!putobject=\hbox{#1}%
+  \!ht=\ht\!putobject  \!dp=\dp\!putobject  \!wd=\wd\!putobject
+  \wd\!putobject=\!zpt
+  \!xshift=.5\!wd   \!yshift=.5\!ht   \advance\!yshift by -.5\!dp
+  \edef\!putorientation{#2}%
+  \expandafter\!SPOreadA\!putorientation[]\!nil%
+  \expandafter\!SPOreadB\!putorientation<\!zpt,\!zpt>\!nil\ignorespaces}
+
+\def\!SPOreadA#1[#2]#3\!nil{\!etfor\!orientation:=#2\do\!SPOreviseshift}
+
+\def\!SPOreadB#1<#2,#3>#4\!nil{\advance\!xshift by -#2\advance\!yshift by -#3}
+
+\def\!SPOreviseshift{%
+  \if l\!orientation
+    \!xshift=\!zpt
+  \else
+    \if r\!orientation
+      \!xshift=\!wd
+    \else
+      \if b\!orientation
+        \!yshift=-\!dp
+      \else
+        \if B\!orientation
+          \!yshift=\!zpt
+        \else
+          \if t\!orientation
+            \!yshift=\!ht
+          \fi
+        \fi
+      \fi
+    \fi
+  \fi}
+
+
+%  **  \!dimenput{OBJECT} <XDIMEN,YDIMEN> [XY] (XLOC,YLOC)
+%  **    This is an internal put routine, similar to \put, except that
+%  **    XLOC=distance right from reference point, YLOC=distance up from
+%  **    reference point. XLOC and YLOC are dimensions, so this routine
+%  **    is completely independent of the current coordinate system.
+%  **    This routine does NOT do ROTATIONS.
+\long\def\!dimenput#1#2(#3,#4){%
+  \!setputobject{#1}{#2}%
+  \!xpos=#3\advance\!xpos by -\!xshift
+  \!ypos=#4\advance\!ypos by -\!yshift
+  \kern\!xpos\raise\!ypos\box\!putobject\kern-\!xpos%
+  \!doaccounting\ignorespaces}
+
+
+%  ** The following macros permit the picture drawing routines to be used
+%  ** either in the default "coordinate mode", or in "dimension mode".
+%  **   In coordinate mode  \!M(1.5,\!xunit)    expands to  1.5\!xunit
+%  **   In dimension  mode  \!M(1.5pt,\!xunit)  expands to  1.5pt
+%  ** Dimension mode is useful in coding macros.
+%  ** Any special purpose picture macro that sets dimension mode should
+%  ** reset coordinate mode before completion.
+%  ** See Subsection 9.2 of the manual.
+\def\!setdimenmode{%
+  \let\!M=\!M!!\ignorespaces}
+\def\!setcoordmode{%
+  \let\!M=\!M!\ignorespaces}
+\def\!ifcoordmode{%
+  \ifx \!M \!M!}
+\def\!ifdimenmode{%
+  \ifx \!M \!M!!}
+\def\!M!#1#2{#1#2}
+\def\!M!!#1#2{#1}
+\!setcoordmode
+\let\setdimensionmode=\!setdimenmode
+\let\setcoordinatemode=\!setcoordmode
+
+%  ** \Xdistance{XCOORD}, \Ydistance{YCOORD}  are the horizontal and
+%  **   vertical distances from the origin (0,0) to the point
+%  **   (XCOORD,YCOORD)  in the current coordinate system.
+%  ** See Subsection 9.2 of the manual.
+\def\Xdistance#1{%
+  \!M{#1}\!xunit
+  \ignorespaces}
+\def\Ydistance#1{%
+  \!M{#1}\!yunit
+  \ignorespaces}
+
+% ** The following macros -- \stack, \line, and \Lines -- are useful for
+% **   annotating PiCtures. They can be used outside the \beginpicture ...
+% **   \endpicture environment.
+
+% ** \stack [POSITIONING] <LEADING> {VALUESLIST}
+% ** Builds a vertical stack of the values in VALUESLIST. Values in
+% ** VALUESLIST are separated by commas.  In the resulting stack, values are
+% ** centered by default, and positioned flush left (right) if
+% ** POSITIONING = l (r).  Values are separated vertically by LEADING,
+% ** which defaults to \stackleading.
+% ** See Subsection 2.3 of the manual.
+\def\stack{%
+  \!ifnextchar[{\!stack}{\!stack[c]}}
+\def\!stack[#1]{%
+  \let\!lglue=\hfill \let\!rglue=\hfill
+  \expandafter\let\csname !#1glue\endcsname=\relax
+  \!ifnextchar<{\!!stack}{\!!stack<\stackleading>}}
+\def\!!stack<#1>#2{%
+  \vbox{\def\!valueslist{}\!ecfor\!value:=#2\do{%
+    \expandafter\!rightappend\!value\withCS{\\}\to\!valueslist}%
+    \!lop\!valueslist\to\!value
+    \let\\=\cr\lineskiplimit=\maxdimen\lineskip=#1%
+    \baselineskip=-1000pt\halign{\!lglue##\!rglue\cr \!value\!valueslist\cr}}%
+  \ignorespaces}
+
+% ** \lines [POSITIONING] {LINES}
+% ** Builds a vertical array of the lines in LINES. Each line in LINES
+% ** is terminated by a \cr.  In the resulting array, lines are
+% ** centered by default, and positioned flush left (right) if
+% ** POSITIONING = l (r).  The lines in the array are subject to TeX's
+% ** usual spacing rules: in particular the baselines are ordinarily an equal
+% ** distance apart. The baseline of the array is the baseline of the
+% ** the bottom line.
+% ** See Subsection 2.3 of the manual.
+\def\lines{%
+  \!ifnextchar[{\!lines}{\!lines[c]}}
+\def\!lines[#1]#2{%
+  \let\!lglue=\hfill \let\!rglue=\hfill
+  \expandafter\let\csname !#1glue\endcsname=\relax
+  \vbox{\halign{\!lglue##\!rglue\cr #2\crcr}}%
+  \ignorespaces}
+
+% ** \Lines [POSITIONING] {LINES}
+% ** Like \lines, but the baseline of the array is the baseline of the
+% ** top line.  See Subsection 2.3 of the manual.
+\def\Lines{%
+  \!ifnextchar[{\!Lines}{\!Lines[c]}}
+\def\!Lines[#1]#2{%
+  \let\!lglue=\hfill \let\!rglue=\hfill
+  \expandafter\let\csname !#1glue\endcsname=\relax
+  \vtop{\halign{\!lglue##\!rglue\cr #2\crcr}}%
+  \ignorespaces}
+
+
+% *********************************************
+% *** PLOTTING (Things to do with plotting) ***
+% *********************************************
+
+% **  User commands
+% **    \setplotsymbol ({PLOTSYMBOL} [ORIENTATION] <XSHIFT,YSHIFT>)
+% **    \savelinesandcurves on "FILE_NAME"
+% **    \dontsavelinesandcurves
+% **    \writesavefile {MESSAGE}
+% **    \replot {FILE_NAME}
+
+% **  Internal command
+% **    \!plot(XDIMEN,YDIMEN)
+
+% **  \setplotsymbol ({PLOTSYMBOL} [ ] < , >)
+% **  Save PLOTSYMBOL away in an hbox for use with curve plotting routines
+% **  See Subsection 5.2 of the manual.
+\def\setplotsymbol(#1#2){%
+  \!setputobject{#1}{#2}
+  \setbox\!plotsymbol=\box\!putobject%
+  \!plotsymbolxshift=\!xshift
+  \!plotsymbolyshift=\!yshift
+  \ignorespaces}
+
+\setplotsymbol({\fiverm .})%       ** initialize plotsymbol
+
+
+% **  \!plot is either \!!plot (when no lines and curves are being saved) or
+% **                   \!!!plot (when   lines and curves are being saved)
+
+% **  \!!plot(XDIMEN,YDIMEN)
+% **  Places the current plotsymbol a horizontal distance=XDIMEN-xorigin
+% **    and a vertical distance=YDIMEN-yorigin from the current
+% **    reference point.
+\def\!!plot(#1,#2){%
+  \!dimenA=-\!plotxorigin \advance \!dimenA by #1%    ** over
+  \!dimenB=-\!plotyorigin \advance \!dimenB by #2%    ** up
+  \kern\!dimenA\raise\!dimenB\copy\!plotsymbol\kern-\!dimenA%
+  \ignorespaces}
+
+% **  \!!!plot(XDIMEN,YDIMEN)
+% **  Like \!!plot, but also saves the plot location in units of
+% **    scaled point, on file `replotfile'
+\def\!!!plot(#1,#2){%
+  \!dimenA=-\!plotxorigin \advance \!dimenA by #1%    ** over
+  \!dimenB=-\!plotyorigin \advance \!dimenB by #2%    ** up
+  \kern\!dimenA\raise\!dimenB\copy\!plotsymbol\kern-\!dimenA%
+  \!countE=\!dimenA
+  \!countF=\!dimenB
+  \immediate\write\!replotfile{\the\!countE,\the\!countF.}%
+  \ignorespaces}
+
+
+% ** \savelinesandcurves on "FILE_NAME"
+% **   Switch to save locations used for plotting lines and curves
+% **   (No advantage in saving locations for solid lines; however
+% **   replotting curve locations speeds things up by a factor of about 4.
+% ** \dontsavelinesandcurves
+% **   Terminates \savelinesandcurves. The default.
+% ** See Subsection 5.6 of the manual.
+\def\savelinesandcurves on "#1" {%
+  \immediate\closeout\!replotfile
+  \immediate\openout\!replotfile=#1%
+  \let\!plot=\!!!plot}
+
+\def\dontsavelinesandcurves {%
+  \let\!plot=\!!plot}
+\dontsavelinesandcurves
+
+% ** \writesavefile {MESSAGE}
+% ** The message is preceded by a "%", so that it won't interfere
+% ** with replotting.
+% ** See Subsection 5.6 of the manual.
+{\catcode`\%=11\xdef\!Commentsignal{%}}
+\def\writesavefile#1 {%
+  \immediate\write\!replotfile{\!Commentsignal #1}%
+  \ignorespaces}
+
+% ** \replot "FILE_NAME"
+% **   Replots the locations saved earlier under \savelinesandcurves
+% **   on "FILE_NAME"
+% ** See Subsection 5.6 of the manual.
+\def\replot"#1" {%
+  \expandafter\!replot\normalinput #1 /}
+\def\!replot#1,#2. {%
+  \!dimenA=#1sp
+  \kern\!dimenA\raise#2sp\copy\!plotsymbol\kern-\!dimenA
+  \futurelet\!nextchar\!!replot}
+\def\!!replot{%
+  \if /\!nextchar
+    \def\!next{\!finish}%
+  \else
+    \def\!next{\!replot}%
+  \fi
+  \!next}
+% **************************************************
+% ***  PYTHAGORAS  (Euclidean distance function) ***
+% **************************************************
+
+% ** User command:
+% **   \placehypotenuse for <dimension1> and <dimension2> in <register>
+
+% ** Internal command:
+% **   \!Pythag{X}{Y}{Z}
+% **     Input X,Y are dimensions, or dimension registers.
+% **     Output Z == sqrt(X**2+Y**2) must be a dimension register.
+% **     Assumes that |X|+|Y| < 2048pt (about 28in).
+
+% ** Without loss of generality, suppose  x>0, y>0.  Put s = x+y,
+% **   z = sqrt(x**2+y**2). Then  z = s*f,  where  f = sqrt(t**2 + (1-t)**2)
+% **   = sqrt((1+tau**2)/2), where  t = x/s  and  tau = 2(t-1/2) .
+
+% ** Uses the \!divide macro (which uses registers \!dimenA--\!dimenD.
+% ** Uses the \!removept macro   (e.g., 123.45pt --> 123.45)
+% ** Uses registers \!dimenE--\!dimenI.
+\def\!Pythag#1#2#3{%
+  \!dimenE=#1\relax
+  \ifdim\!dimenE<\!zpt
+    \!dimenE=-\!dimenE
+  \fi%                                            ** dimE = |x|
+  \!dimenF=#2\relax
+  \ifdim\!dimenF<\!zpt
+    \!dimenF=-\!dimenF
+  \fi%                                            ** dimF = |y|
+  \advance \!dimenF by \!dimenE%                  ** dimF = s = |x|+|y|
+  \ifdim\!dimenF=\!zpt
+    \!dimenG=\!zpt%                               ** dimG = z = sqrt(x**2+y**2)
+  \else
+    \!divide{8\!dimenE}\!dimenF\!dimenE%          ** now dimE = 8t = (8|x|)/s
+    \advance\!dimenE by -4pt%                     ** 8tau = (8t-4)*2
+      \!dimenE=2\!dimenE%                         **   (tau = 2*t - 1)
+    \!removept\!dimenE\!!t%                       ** 8tau, without "pt"
+    \!dimenE=\!!t\!dimenE%                        ** (8tau)**2, in pts
+    \advance\!dimenE by 64pt%                     ** u = [64 + (8tau)**2]/2
+    \divide \!dimenE by 2%                        **   [u = (8f)**2]
+    \!dimenH=7pt%                                 ** initial guess g at sqrt(u)
+    \!!Pythag\!!Pythag\!!Pythag%                  ** 3 iterations give sqrt(u)
+    \!removept\!dimenH\!!t%                       ** 8f=sqrt(u), without "pt"
+    \!dimenG=\!!t\!dimenF%                        ** z = (8f)*s/8
+    \divide\!dimenG by 8
+  \fi
+  #3=\!dimenG
+  \ignorespaces}
+
+\def\!!Pythag{%                                   ** Newton-Raphson for sqrt
+  \!divide\!dimenE\!dimenH\!dimenI%               ** v = u/g
+  \advance\!dimenH by \!dimenI%                   ** g <-- (g + u/g)/2
+    \divide\!dimenH by 2}
+
+% **  \placehypotenuse for <XI> and <ETA> in <ZETA>
+% **  See Subsection 9.3 of the manual.
+\def\placehypotenuse for <#1> and <#2> in <#3> {%
+  \!Pythag{#1}{#2}{#3}}
+
+
+% **********************************************
+% *** QUADRATIC ARC  (Draws a quadratic arc) ***
+% **********************************************
+
+% **  Internal command
+% **    \!qjoin (XCOORD1,YCOORD1) (XCOORD2,YCOORD2)
+
+% **  \!qjoin (XCOORD1,YCOORD1) (XCOORD2,YCOORD2)
+% **  Draws an arc starting at the (last) point specified by the most recent
+% **  \!qjoin, or \!ljoin, or \!start  and passing through (X_1,Y_1), (X_2,Y_2).
+% **  Uses quadratic interpolation in both  x  and  y:
+% **    x(t), 0 <= t <= 1, interpolates  x_0, x_1, x_2  at  t=0, .5, 1
+% **    y(t), 0 <= t <= 1, interpolates  y_0, y_1, y_2  at  t=0, .5, 1
+
+\def\!qjoin (#1,#2) (#3,#4){%
+  \advance\!intervalno by 1
+  \!ifcoordmode
+    \edef\!xmidpt{#1}\edef\!ymidpt{#2}%
+  \else
+    \!dimenA=#1\relax \edef\!xmidpt{\the\!dimenA}%
+    \!dimenA=#2\relax \edef\!xmidpt{\the\!dimenA}%
+  \fi
+  \!xM=\!M{#1}\!xunit  \!yM=\!M{#2}\!yunit   \!rotateaboutpivot\!xM\!yM
+  \!xE=\!M{#3}\!xunit  \!yE=\!M{#4}\!yunit   \!rotateaboutpivot\!xE\!yE
+%
+% ** Find coefficients for x(t)=a_x + b_x*t + c_x*t**2
+  \!dimenA=\!xM  \advance \!dimenA by -\!xS%   ** dimA = I = xM - xS
+  \!dimenB=\!xE  \advance \!dimenB by -\!xM%   ** dimB = II = xE-xM
+  \!xB=3\!dimenA \advance \!xB by -\!dimenB%   ** b=3I-II
+  \!xC=2\!dimenB \advance \!xC by -2\!dimenA%  ** c=2(II-I)
+%
+% ** Find coefficients for y(t)=y_x + b_y*t + c_y*t**2
+  \!dimenA=\!yM  \advance \!dimenA by -\!yS%
+  \!dimenB=\!yE  \advance \!dimenB by -\!yM%
+  \!yB=3\!dimenA \advance \!yB by -\!dimenB%
+  \!yC=2\!dimenB \advance \!yC by -2\!dimenA%
+%
+% ** Use Simpson's rule to calculate arc length over [0,1/2]:
+% **   arc length = 1/2[1/6 f(0) + 4/6 f(1/4) + 1/6 f(1/2)]
+% ** with f(t) = sqrt(x'(t)**2 + y'(t)**2).
+  \!xprime=\!xB  \!yprime=\!yB%          ** x'(t) = b + 2ct
+  \!dxprime=.5\!xC  \!dyprime=.5\!yC%    ** dt=1/4 ==> dx'(t) = c/2
+  \!getf \!midarclength=\!dimenA
+  \!getf \advance \!midarclength by 4\!dimenA
+  \!getf \advance \!midarclength by \!dimenA
+  \divide \!midarclength by 12
+%
+% ** Get arc length over [0,1].
+  \!arclength=\!dimenA
+  \!getf \advance \!arclength by 4\!dimenA
+  \!getf \advance \!arclength by \!dimenA
+  \divide \!arclength by 12%             ** Now have arc length over [1/2,1]
+  \advance \!arclength by \!midarclength
+  \global\advance \totalarclength by \!arclength
+%
+%
+% ** Check to see if there's anything to plot in this interval
+  \ifdim\!distacross>\!arclength
+    \advance \!distacross by -\!arclength%   ** nothing
+%
+  \else
+    \!initinverseinterp%  ** initialize for inverse interpolation on arc length
+    \loop\ifdim\!distacross<\!arclength%     ** loop over points on arc
+      \!inverseinterp%    ** find  t  such that arc length[0,t] = distacross,
+%                         **   using inverse quadratic interpolation
+%                         ** now evaluate x(t)=(c*t + b)*t + a
+      \!xpos=\!t\!xC \advance\!xpos by \!xB
+        \!xpos=\!t\!xpos \advance \!xpos by \!xS
+%                                             ** evaluate y(t)
+      \!ypos=\!t\!yC \advance\!ypos by \!yB
+        \!ypos=\!t\!ypos \advance \!ypos by \!yS
+      \!plotifinbounds%                       ** plot point if in bounds
+      \advance\!distacross \plotsymbolspacing%** advance arc length for next pt
+      \!advancedashing%                       ** see "linear"
+    \repeat
+%
+    \advance \!distacross by -\!arclength%    ** prepare for next interval
+  \fi
+%
+  \!xS=\!xE%              ** shift ending points to starting points
+  \!yS=\!yE
+  \ignorespaces}
+
+
+% ** \!getf -- Calculates sqrt(x'(t)**2 + y'(t)**2) and advances
+% **   x'(t) and y'(t)
+\def\!getf{\!Pythag\!xprime\!yprime\!dimenA%
+  \advance\!xprime by \!dxprime
+  \advance\!yprime by \!dyprime}
+
+
+% ** \!initinverseinterp -- initializes for inverse quadratic interpolation
+% ** of arc length provided  1/3 < midarclength/arclength < 2/3; otherwise
+% ** initializes for inverse linear interpolation.
+\def\!initinverseinterp{%
+  \ifdim\!arclength>\!zpt
+    \!divide{8\!midarclength}\!arclength\!dimenE% ** dimE=8w=8r/s, where  r
+%                                               **  = midarclength, s=arclength
+% **  Test for  w  out of range:  w<1/3  or w>2/3
+    \ifdim\!dimenE<\!wmin \!setinverselinear
+    \else
+      \ifdim\!dimenE>\!wmax \!setinverselinear
+      \else%                                    ** w  in range: initialize
+        \def\!inverseinterp{\!inversequad}\ignorespaces
+%
+% **     Calculate the coefficients  \!beta  and  \!gamma  of the quadratic
+% **                    t = \!beta*v + \!gamma*v**2
+% **     taking the values  t=0, 1/2, 1  at  v=0, w==r/s, 1  respectively:
+% **        \!beta = (1/2 - w**2)/[w(1-w)]
+% **        \!gamma = 1 - beta.
+%
+         \!removept\!dimenE\!Ew%           **  8w, without "pt"
+         \!dimenF=-\!Ew\!dimenE%           **  -(8w)**2
+         \advance\!dimenF by 32pt%         **  32 - (8w)**2
+         \!dimenG=8pt
+         \advance\!dimenG by -\!dimenE%    **  8 - 8w
+         \!dimenG=\!Ew\!dimenG%            **  (8w)*(8-8w)
+         \!divide\!dimenF\!dimenG\!beta%   **  beta = (32-(8w)**2)/(8w(8-8w))
+%                                          **       = (1/2 - w**2)/(w(1-w))
+         \!gamma=1pt
+         \advance \!gamma by -\!beta%      **  gamma = 1-beta
+      \fi%       ** end of the \ifdim\!dimenE>\!wmax
+    \fi%         ** end of the \ifdim\!dimenE<\!wmin
+  \fi%           ** end of the \ifdim\!arclength>\!zpt
+  \ignorespaces}
+
+
+% ** For 0 <= t <= 1, let AL(t) = arclength[0,t]/arclength[0,1]; note
+% ** AL(0)=0, AL(1/2)=midarclength/arclength, AL(1)=1.  This routine
+% ** calculates an approximation to AL^{-1}(distance across/arclength),
+% ** using the assumption that AL^{-1} is quadratic.  Specifically,
+% ** it finds  t  such that
+% **    AL^{-1}(v) =. t = v*(\!beta + \!gamma*v)
+% ** where  \!beta  and  \!gamma  are set by \!initinv, and where
+% ** v=distance across/arclength
+\def\!inversequad{%
+  \!divide\!distacross\!arclength\!dimenG%   ** dimG = v = distacross/arclength
+  \!removept\!dimenG\!v%                     ** v, without "pt"
+  \!dimenG=\!v\!gamma%                       ** gamma*v
+  \advance\!dimenG by \!beta%                ** beta + gamma*v
+  \!dimenG=\!v\!dimenG%                      ** t = v*(beta + gamma*v)
+  \!removept\!dimenG\!t}%                    ** t, without "pt"
+
+
+% ** When  w <= 1/3  or  w >= 2/3, the following routine writes (using
+% ** plain TEK's \wlog command) a warning message on the user's log file,
+% ** and initializes for inverse linear interpolation on arc length.
+\def\!setinverselinear{%
+  \def\!inverseinterp{\!inverselinear}%
+  \divide\!dimenE by 8 \!removept\!dimenE\!t
+  \!countC=\!intervalno \multiply \!countC 2
+  \!countB=\!countC     \advance \!countB -1
+  \!countA=\!countB     \advance \!countA -1
+  \wlog{\the\!countB th point (\!xmidpt,\!ymidpt) being plotted
+    doesn't lie in the}%
+  \wlog{ middle third of the arc between the \the\!countA th
+    and \the\!countC th points:}%
+  \wlog{ [arc length \the\!countA\space to \the\!countB]/[arc length
+    \the \!countA\space to \the\!countC]=\!t.}%
+  \ignorespaces}
+
+% **  Inverse linear interpolation
+\def\!inverselinear{%
+  \!divide\!distacross\!arclength\!dimenG
+  \!removept\!dimenG\!t}
+
+
+% **************************************
+% **  ROTATIONS  (Handles rotations) ***
+% **************************************
+
+% ** User commands
+% **   \startrotation [by COS_OF_ANGLE SIN_OF_ANGLE] [about XPIVOT YPIVOT]
+% **   \stoprotation
+
+% **   \startrotation [by COS_OF_ANGLE SIN_OF_ANGLE] [about XPIVOT YPIVOT]
+% ** Future (XCOORD,YCOORD)'s will be rotated about (XPIVOT,YPIVOT)
+% ** by the angle with the give COS and SIN. Both fields are optional.
+% ** [COS,SIN] defaults to previous value, or (1,0).
+% ** (XPIVOT,YPIVOT) defaults to previous value, or (0,0)
+% ** You can't change the coordinate system in the scope of a rotation.
+% ** See Subsection 9.1 of the manual.
+\def\startrotation{%
+  \let\!rotateaboutpivot=\!!rotateaboutpivot
+  \let\!rotateonly=\!!rotateonly
+  \!ifnextchar{b}{\!getsincos }%
+    {\!getsincos by {\!cosrotationangle} {\!sinrotationangle} }}
+\def\!getsincos by #1 #2 {%
+  \edef\!cosrotationangle{#1}%
+  \edef\!sinrotationangle{#2}%
+  \!ifcoordmode
+    \let\!ROnext=\!ccheckforpivot
+  \else
+    \let\!ROnext=\!dcheckforpivot
+  \fi
+  \!ROnext}
+\def\!ccheckforpivot{%
+  \!ifnextchar{a}{\!cgetpivot}%
+    {\!cgetpivot about {\!xpivotcoord} {\!ypivotcoord} }}
+\def\!cgetpivot about #1 #2 {%
+  \edef\!xpivotcoord{#1}%
+  \edef\!ypivotcoord{#2}%
+  \!xpivot=#1\!xunit  \!ypivot=#2\!yunit
+  \ignorespaces}
+\def\!dcheckforpivot{%
+  \!ifnextchar{a}{\!dgetpivot}{\ignorespaces}}
+\def\!dgetpivot about #1 #2 {%
+  \!xpivot=#1\relax  \!ypivot=#2\relax
+  \ignorespaces}
+
+
+% ** Following terminates rotation.
+% ** See Subsection 9.1 of the manual.
+\def\stoprotation{%
+  \let\!rotateaboutpivot=\!!!rotateaboutpivot
+  \let\!rotateonly=\!!!rotateonly
+  \ignorespaces}
+
+% ** !!rotateaboutpivot{XREG}{YREG}
+% ** XREG <-- xpvt + cos(angle)*(XREG-xpvt) - sin(angle)*(YREG-ypvt)
+% ** YREG <-- ypvt + cos(angle)*(YREG-ypvt) + sin(angle)*(XREG-xpvt)
+% ** XREG,YREG are dimension registers. Can't be \!dimenA to \!dimenD
+\def\!!rotateaboutpivot#1#2{%
+  \!dimenA=#1\relax  \advance\!dimenA -\!xpivot
+  \!dimenB=#2\relax  \advance\!dimenB -\!ypivot
+  \!dimenC=\!cosrotationangle\!dimenA
+    \advance \!dimenC -\!sinrotationangle\!dimenB
+  \!dimenD=\!cosrotationangle\!dimenB
+    \advance \!dimenD  \!sinrotationangle\!dimenA
+  \advance\!dimenC \!xpivot  \advance\!dimenD \!ypivot
+  #1=\!dimenC  #2=\!dimenD
+  \ignorespaces}
+
+% ** \!!rotateonly{XREG}{YREG}
+% ** Like \!!rotateaboutpivot, but with a pivot of  (0,0)
+\def\!!rotateonly#1#2{%
+  \!dimenA=#1\relax  \!dimenB=#2\relax
+  \!dimenC=\!cosrotationangle\!dimenA
+    \advance \!dimenC -\!rotsign\!sinrotationangle\!dimenB
+  \!dimenD=\!cosrotationangle\!dimenB
+    \advance \!dimenD  \!rotsign\!sinrotationangle\!dimenA
+  #1=\!dimenC  #2=\!dimenD
+  \ignorespaces}
+\def\!rotsign{}
+\def\!!!rotateaboutpivot#1#2{\relax}
+\def\!!!rotateonly#1#2{\relax}
+\stoprotation
+
+\def\!reverserotateonly#1#2{%
+  \def\!rotsign{-}%
+  \!rotateonly{#1}{#2}%
+  \def\!rotsign{}%
+  \ignorespaces}
+
+
+% **********************************
+% *** SHADING  (Handles shading) ***
+% **********************************
+
+% **  User commands
+% **    \setshadegrid [span <SPAN>] [point at XSHADE YSHADE]
+% **    \setshadesymbol [<LS, RS, BS, TS>] ({SHADESYMBOL}
+% **      <XDIMEN,YDIMEN> [ORIENTATION])
+
+% **  Internal commands:
+% **    \!startvshade  (xS,ybS,ytS)
+% **    \!starthshade  (yS,xlS,xrS)
+% **    \!lshade [<LS,RS,BS,TS>]
+% **       ** when shading vertically:
+% **       [the region from (xS,ybS,ytS) to] (xE,ybE,ytE)
+% **       ** when shading horizontally:
+% **       [the region from (yS,xlS,xrS) to] (yE,xlE,xrE)
+% **    \!qshade [<LS,RS,BS,TS>]
+% **       ** when shading vertically:
+% **       [the region from (xS,ybS,ytS) to] (xM,ybM,ytM)  (xE,ybE,ytE)
+% **       ** when shading horizontally:
+% **       [the region from (yS,xlS,xrS) to] (yM,xlM,xrM)  (yE,xlE,xrE)
+% **    \!lattice{ANCHOR}{SPAN}{LOCATION}{INDEX}{LATTICE LOCATION}
+% **    \!override{NOMINAL DIMEN}{REPLACEMENT DIMEN}{DIMEN}
+
+
+% **  The shading routine can operate either in a "vertical mode" or a
+% **  "horizontal mode".  In vertical mode, the region to be shaded is specified
+% **  in the form
+% **                 {(x,y): xl <= x <= xr  &  yb(x) <= y <= yt(x)}
+% **  where  yb  and  yt  are functions of  x.  In horizontal mode, the region
+% **  is specified in the form
+% **                 {(x,y): yb <= y <= yt  &  xl(y) <= x <= xr(y)}.
+% **  The functions  yb  and  yt  may be either both linear or both quadratic;
+% **  similarly for  xl  and  xr.  A region with say, piecewise quadratic bottom
+% **  and top boundaries, can be shaded by consecutive (vertical) \!qshades,
+% **  proceeding from left to right.  Similarly, a region with piecewise
+% **  quadratic left and right boundaries can be shaded by consecutive
+% **  (horizontal) \!qshades, proceeding from bottom to top.  More complex
+% **  regions can be shaded by partitioning them into appropriate subregions,
+% **  and shading those.
+
+% **  Shading is accomplished by placing a user-selected shading symbol at
+% **  those points of a regular grid which fall within the region to be
+% **  shaded.  This region can be "shrunk" so that a largish shading symbol
+% **  will not extend outside it.  Shrinking is accomplished by specifying
+% **  shrinkages for the left, right, bottom, and top boundaries, in a manner
+% **  discussed further below.
+
+% **  \shades and \!joins MUST NOT be intermingled.  Finish drawing a curve
+% **  before starting to shade a region, and finish shading a region before
+% **  starting to draw a curve.
+
+
+% **  \setshadegrid [span <SPAN>] [point at XSHADE YSHADE]
+% **  The shading symbol is placed down on the points of a grid centered
+% **  at the coordinate point (XSHADE,YSHADE).  The grid points are of the
+% **  form (j*SPAN,k*SPAN), with  j+k  even.  SPAN is specified
+% **  as a dimension.
+% **  (XSHADE,YSHADE) defaults to previous (XSHADE,YSHADE) (or (0,0) if none)
+% **  SPAN defaults to previous span (or 5pt if none)
+% **  See Subsection 7.2 of the manual.
+\def\setshadegrid{%
+  \!ifnextchar{s}{\!getspan }
+    {\!getspan span <\!dshade>}}
+\def\!getspan span <#1>{%
+  \!dshade=#1\relax
+  \!ifcoordmode
+    \let\!GRnext=\!GRccheckforAP
+  \else
+    \let\!GRnext=\!GRdcheckforAP
+  \fi
+  \!GRnext}
+\def\!GRccheckforAP{%
+  \!ifnextchar{p}{\!cgetanchor }
+    {\!cgetanchor point at {\!xshadesave} {\!yshadesave} }}
+\def\!cgetanchor point at #1 #2 {%
+  \edef\!xshadesave{#1}\edef\!yshadesave{#2}%
+  \!xshade=\!xshadesave\!xunit  \!yshade=\!yshadesave\!yunit
+  \ignorespaces}
+\def\!GRdcheckforAP{%
+  \!ifnextchar{p}{\!dgetanchor}%
+    {\ignorespaces}}
+\def\!dgetanchor point at #1 #2 {%
+  \!xshade=#1\relax  \!yshade=#2\relax
+  \ignorespaces}
+
+% **  \setshadesymbol  [<LS, RS, BS, TS>] ({SHADESYMBOL}
+% **    <XDIMEN,YDIMEN> [ORIENTATION])
+% **  Saves SHADESYMBOL away in an hbox for use with shading routines.
+% **  A shade symbol will not be plotted if its plot position comes within
+% **    distance LS of the left boundary,  RS of the right boundary,  TS of the
+% **    top boundary,  BS of the bottom boundary.  These parameters have
+% **    default values that should work in most cases (see below).
+% **    To override a default value, specify the replacement value
+% **    in the appropriate subfield of the shrinkages field.
+% **    0pt may be coded as  "z" (without the quotes).  To accept a
+% **    default value, leave the field empty.  Thus
+% **      [,z,,5pt]  sets  LS=default, RS=0pt, BS=default, TS=5pt .
+% **    Skipping the shrinkages field accepts all the defaults.
+% **  See Subsection 7.1 of the manual.
+\def\setshadesymbol{%
+  \!ifnextchar<{\!setshadesymbol}{\!setshadesymbol<,,,> }}
+
+\def\!setshadesymbol <#1,#2,#3,#4> (#5#6){%
+% **  set the shadesymbol
+  \!setputobject{#5}{#6}%
+  \setbox\!shadesymbol=\box\!putobject%
+  \!shadesymbolxshift=\!xshift \!shadesymbolyshift=\!yshift
+%
+% **  set the shrinkages
+  \!dimenA=\!xshift \advance\!dimenA \!smidge% ** default LS = xshift - smidge
+  \!override\!dimenA{#1}\!lshrinkage%
+  \!dimenA=\!wd \advance \!dimenA -\!xshift%   ** default RS = width - xshift
+    \advance\!dimenA \!smidge%                                  - smidge
+    \!override\!dimenA{#2}\!rshrinkage
+  \!dimenA=\!dp \advance \!dimenA \!yshift%    ** default BS = depth + yshift
+    \advance\!dimenA \!smidge%                                  - smidge
+    \!override\!dimenA{#3}\!bshrinkage
+  \!dimenA=\!ht \advance \!dimenA -\!yshift%   ** default TS = height - yshift
+    \advance\!dimenA \!smidge%                                  - smidge
+    \!override\!dimenA{#4}\!tshrinkage
+  \ignorespaces}
+\def\!smidge{-.2pt}%
+
+% ** \!override{NOMINAL DIMEN}{REPLACEMENT DIMEN}{DIMEN}
+% ** Overrides the NOMINAL DIMEN by the REPLACEMENT DIMEN to produce DIMEN,
+% ** according to the following rules:
+% **   REPLACEMENT DIMEN empty: DIMEN <-- NOMINAL DIMEN
+% **   REPLACEMENT DIMEN z:     DIMEN <-- 0pt
+% **   otherwise:               DIMEN <-- REPLACEMENT DIMEN
+% ** DIMEN must be a dimension register
+\def\!override#1#2#3{%
+  \edef\!!override{#2}%
+  \ifx \!!override\empty
+    #3=#1\relax
+  \else
+    \if z\!!override
+      #3=\!zpt
+    \else
+      \ifx \!!override\!blankz
+        #3=\!zpt
+      \else
+        #3=#2\relax
+      \fi
+    \fi
+  \fi
+  \ignorespaces}
+\def\!blankz{ z}
+
+\setshadesymbol ({\fiverm .})%       ** initialize plotsymbol
+%                                    ** \fivesy ^^B  is a small cross
+
+
+% ** \!startvshade [at] (xS,ybS,ytS)
+% ** Initiates vertical shading mode
+\def\!startvshade#1(#2,#3,#4){%
+  \let\!!xunit=\!xunit%
+  \let\!!yunit=\!yunit%
+  \let\!!xshade=\!xshade%
+  \let\!!yshade=\!yshade%
+  \def\!getshrinkages{\!vgetshrinkages}%
+  \let\!setshadelocation=\!vsetshadelocation%
+  \!xS=\!M{#2}\!!xunit
+  \!ybS=\!M{#3}\!!yunit
+  \!ytS=\!M{#4}\!!yunit
+  \!shadexorigin=\!xorigin  \advance \!shadexorigin \!shadesymbolxshift
+  \!shadeyorigin=\!yorigin  \advance \!shadeyorigin \!shadesymbolyshift
+  \ignorespaces}
+
+% ** \!starthshade [at] (yS,xlS,xrS)
+% ** Initiates horizontal shading mode
+\def\!starthshade#1(#2,#3,#4){%
+  \let\!!xunit=\!yunit%
+  \let\!!yunit=\!xunit%
+  \let\!!xshade=\!yshade%
+  \let\!!yshade=\!xshade%
+  \def\!getshrinkages{\!hgetshrinkages}%
+  \let\!setshadelocation=\!hsetshadelocation%
+  \!xS=\!M{#2}\!!xunit
+  \!ybS=\!M{#3}\!!yunit
+  \!ytS=\!M{#4}\!!yunit
+  \!shadexorigin=\!xorigin  \advance \!shadexorigin \!shadesymbolxshift
+  \!shadeyorigin=\!yorigin  \advance \!shadeyorigin \!shadesymbolyshift
+  \ignorespaces}
+
+
+% **  \!lattice{ANCHOR}{SPAN}{LOCATION}{INDEX}{LATTICE LOCATION}
+% **  Consider the lattice with points  ANCHOR + j*SPAN. This routine determines
+% **  the index  k  of the smallest lattice point >= LOCATION, and sets
+% **  LATTICE LOCATION = ANCHOR + k*SPAN.
+% **  INDEX is assumed to be a count register, LATTICE LOCATION a dimen reg.
+\def\!lattice#1#2#3#4#5{%
+  \!dimenA=#1%                        ** dimA = ANCHOR
+  \!dimenB=#2%                        ** dimB = SPAN  (assumed > 0pt)
+  \!countB=\!dimenB%                  ** ctB  = SPAN, as a count
+%
+% ** Determine index of smallest lattice point >= LOCATION
+  \!dimenC=#3%                        ** dimC = LOCATION
+  \advance\!dimenC -\!dimenA%         ** now dimC = LOCATION-ANCHOR
+  \!countA=\!dimenC%                  ** ctA = above, as a count
+  \divide\!countA \!countB%           ** now ctA = desired index, if dimC <= 0
+  \ifdim\!dimenC>\!zpt
+    \!dimenD=\!countA\!dimenB%        ** (tentative k)*span
+    \ifdim\!dimenD<\!dimenC%          ** if this is false, ctA = desired index
+      \advance\!countA 1 %            ** if true, have to add 1
+    \fi
+  \fi
+%
+  \!dimenC=\!countA\!dimenB%          ** lattice location = anchor + ctA*span
+    \advance\!dimenC \!dimenA
+  #4=\!countA%                        ** the desired index
+  #5=\!dimenC%                        ** corresponding lattice location
+  \ignorespaces}
+
+
+% ** \!qshade [with shrinkages] [[LS,RS,BS,TS]]
+% ***** during vertical shading:
+% **    [the region from (xS,ybS,ytS) to] (xM,ybM,ytM) [and] (xE,ybE,ytE)
+% ** Shades the region {(x,y): xS <= x <= xE, yb(x) <= y <= yt(x)}, where
+% **   yb is the quadratic thru (xS,ybS) & (xM,ybM) & (xE,ybE)
+% **   yt is the quadratic thru (xS,ytS) & (xM,ybM) & (xE,ytE)
+% ** xS,ybS,ytS are either given by \!startvshade or carried over
+% **   as the ending values of the immediately preceding \!qshade.
+% ** For the interpretation of LS, RS, BS, & TS, see \setshadesymbol. The
+% **   values set there can be overridden, for the course of this \!qshade
+% **   only, in the same manner as overrides are specified for
+% **   \setshadesymbol.
+% ***** during horizontal shading:
+% **    [the region from (yS,xlS,xrS) to] (yM,xlM,xrM) [and] (yE,xlE,xrE)
+\def\!qshade#1(#2,#3,#4)#5(#6,#7,#8){%
+  \!xM=\!M{#2}\!!xunit
+  \!ybM=\!M{#3}\!!yunit
+  \!ytM=\!M{#4}\!!yunit
+  \!xE=\!M{#6}\!!xunit
+  \!ybE=\!M{#7}\!!yunit
+  \!ytE=\!M{#8}\!!yunit
+  \!getcoeffs\!xS\!ybS\!xM\!ybM\!xE\!ybE\!ybB\!ybC%**Get coefficients B & C for
+  \!getcoeffs\!xS\!ytS\!xM\!ytM\!xE\!ytE\!ytB\!ytC%**y=y0 + B(x-X0) + C(x-X0)**2
+  \def\!getylimits{\!qgetylimits}%
+  \!shade{#1}\ignorespaces}
+
+% ** \!lshade ... (xE,ybE,ytE)
+% ** This is like \!qshade, but the top and bottom boundaries are linear,
+% ** rather than quadratic.
+\def\!lshade#1(#2,#3,#4){%
+  \!xE=\!M{#2}\!!xunit
+  \!ybE=\!M{#3}\!!yunit
+  \!ytE=\!M{#4}\!!yunit
+  \!dimenE=\!xE  \advance \!dimenE -\!xS%   ** xE-xS
+  \!dimenC=\!ytE \advance \!dimenC -\!ytS%  ** ytE-ytS
+  \!divide\!dimenC\!dimenE\!ytB%            ** ytB = (ytE-ytS)/(xE-xS)
+  \!dimenC=\!ybE \advance \!dimenC -\!ybS%  ** ybE-ybS
+  \!divide\!dimenC\!dimenE\!ybB%            ** ybB = (ybE-ybS)/(xE-xS)
+  \def\!getylimits{\!lgetylimits}%
+  \!shade{#1}\ignorespaces}
+
+% **  \!getcoeffs{X0}{Y0}{X1}{Y1}{X2}{Y2}{B}{C}
+% **  Finds  B  and  C  such that the quadratic  y = Y0 + B(x-X0) + C(x-X0)**2
+% **  passes through (X1,Y1) and (X2,Y2):  when X0=0=Y0, the formulas are:
+% **                   B = S1 - X1*C,   C = (S2-S1)/X2
+% **  with
+% **                 S1 = Y1/X1,   S2 = (Y2-Y1)/(X2-X1).
+\def\!getcoeffs#1#2#3#4#5#6#7#8{%
+  \!dimenC=#4\advance \!dimenC -#2%            ** dimC=Y1-Y0
+  \!dimenE=#3\advance \!dimenE -#1%            ** dimE=X1-X0
+  \!divide\!dimenC\!dimenE\!dimenF%            ** dimF=S1
+  \!dimenC=#6\advance \!dimenC -#4%            ** dimC=Y2-Y1
+  \!dimenH=#5\advance \!dimenH -#3%            ** dimH=X2-X1
+  \!divide\!dimenC\!dimenH\!dimenG%            ** dimG=S2
+  \advance\!dimenG -\!dimenF%                  ** dimG=S2-S1
+  \advance \!dimenH \!dimenE%                  ** dimH=X2-X0
+  \!divide\!dimenG\!dimenH#8%                  ** C=(S2-S1)/(X2-X0)
+  \!removept#8\!t%                             ** C, without "pt"
+  #7=-\!t\!dimenE%                             ** -C*(X1-X0)
+  \advance #7\!dimenF%                         ** B=S1-C*(X1-X0)
+  \ignorespaces}
+
+
+\def\!shade#1{%
+% ** Get LS,RS,BS,TS for this panel
+  \!getshrinkages#1<,,,>\!nil% %       ** now effective LS=dimE, RS=dimF,
+%                                      **   BS=dimG, TS=dimH
+  \advance \!dimenE \!xS%              ** now dimE=xS+LS
+  \!lattice\!!xshade\!dshade\!dimenE%  ** set parity=index of left-mst x-lattice
+    \!parity\!xpos%                    **   point >= xS+LS, xpos=its location
+  \!dimenF=-\!dimenF%                  ** set dimF=xE-RS
+    \advance\!dimenF \!xE
+%
+  \!loop\!not{\ifdim\!xpos>\!dimenF}%  ** loop over x-lattice points <= xE-RS
+    \!shadecolumn%
+    \advance\!xpos \!dshade%           ** move over to next column
+    \advance\!parity 1%                ** increase index of x-point
+  \repeat
+%
+  \!xS=\!xE%                           ** shift ending values to starting values
+  \!ybS=\!ybE
+  \!ytS=\!ytE
+  \ignorespaces}
+
+
+\def\!vgetshrinkages#1<#2,#3,#4,#5>#6\!nil{%
+  \!override\!lshrinkage{#2}\!dimenE
+  \!override\!rshrinkage{#3}\!dimenF
+  \!override\!bshrinkage{#4}\!dimenG
+  \!override\!tshrinkage{#5}\!dimenH
+  \ignorespaces}
+\def\!hgetshrinkages#1<#2,#3,#4,#5>#6\!nil{%
+  \!override\!lshrinkage{#2}\!dimenG
+  \!override\!rshrinkage{#3}\!dimenH
+  \!override\!bshrinkage{#4}\!dimenE
+  \!override\!tshrinkage{#5}\!dimenF
+  \ignorespaces}
+
+
+\def\!shadecolumn{%
+  \!dxpos=\!xpos
+  \advance\!dxpos -\!xS%            ** dx = x - xS
+  \!removept\!dxpos\!dx%            ** ditto, without "pt"
+  \!getylimits%                     ** get top and bottom y-values
+  \advance\!ytpos -\!dimenH%        ** less TS
+  \advance\!ybpos \!dimenG%         ** plus BS
+  \!yloc=\!!yshade%                 ** get anchor point for this column
+  \ifodd\!parity
+     \advance\!yloc \!dshade
+  \fi
+  \!lattice\!yloc{2\!dshade}\!ybpos%
+    \!countA\!ypos%                 ** ypos=smallest y point for this column
+  \!dimenA=-\!shadexorigin \advance \!dimenA \!xpos%      ** over
+  \loop\!not{\ifdim\!ypos>\!ytpos}% ** loop over ypos <= yt(t)
+    \!setshadelocation%             ** vmode: xloc=xpos, yloc=ypos
+%                                   ** hmode: xloc=ypos, yloc=xpos
+    \!rotateaboutpivot\!xloc\!yloc%
+    \!dimenA=-\!shadexorigin \advance \!dimenA \!xloc%    ** over
+    \!dimenB=-\!shadeyorigin \advance \!dimenB \!yloc%    ** up
+    \kern\!dimenA \raise\!dimenB\copy\!shadesymbol \kern-\!dimenA
+    \advance\!ypos 2\!dshade
+  \repeat
+  \ignorespaces}
+
+\def\!qgetylimits{%
+  \!dimenA=\!dx\!ytC
+  \advance\!dimenA \!ytB%         ** yt(t)=ytS + dx*(Bt + dx*Ct)
+  \!ytpos=\!dx\!dimenA
+  \advance\!ytpos \!ytS
+  \!dimenA=\!dx\!ybC
+  \advance\!dimenA \!ybB%         ** yb(t)=ybS + dx*(Bb + dx*Cb)
+  \!ybpos=\!dx\!dimenA
+  \advance\!ybpos \!ybS}
+
+\def\!lgetylimits{%
+  \!ytpos=\!dx\!ytB%              ** yt(t)=ytS + dx*Bt
+  \advance\!ytpos \!ytS
+  \!ybpos=\!dx\!ybB%              ** yb(t)=ybS + dx*Bb
+  \advance\!ybpos \!ybS}
+
+\def\!vsetshadelocation{%         ** vmode: xloc=xpos, yloc=ypos
+  \!xloc=\!xpos
+  \!yloc=\!ypos}
+\def\!hsetshadelocation{%         ** hmode: xloc=ypos, yloc=xpos
+  \!xloc=\!ypos
+  \!yloc=\!xpos}
+
+
+% **************************************
+% *** TICKS  (Draws ticks on graphs) ***
+% **************************************
+
+% ** User commands
+% **   \ticksout
+% **   \ticksin
+% **   \gridlines
+% **   \nogridlines
+% **   \loggedticks
+% **   \unloggesticks
+% ** See Subsection 3.4 of the manual
+
+% ** The following is an option of the \axis command
+% **   ticks
+% **     [in] [out]
+% **     [long] [short] [length <LENGTH>]
+% **     [width <WIDTH>]
+% **     [andacross] [butnotacross]
+% **     [logged] [unlogged]
+% **     [unlabeled] [numbered] [withvalues VALUE1 VALUE2 ... VALUEk / ]
+% **     [quantity Q] [at LOC1 LOC2 ... LOCk / ] [from LOC1 to LOC2 by
+% **       LOC_INCREMENT]
+% ** See Subsection 3.2 of the manual for the rules.
+
+% ** The various options of the  tick  field are processed by the
+% ** \!nextkeyword  command defined below.
+% ** For example, `\!nextkeyword short '  expands to  `\!ticksshort',
+% ** while `\!nextkeyword withvalues' expands to `\!tickswithvalues'.
+
+\def\!axisticks {%
+  \def\!nextkeyword##1 {%
+    \expandafter\ifx\csname !ticks##1\endcsname \relax
+      \def\!next{\!fixkeyword{##1}}%
+    \else
+      \def\!next{\csname !ticks##1\endcsname}%
+    \fi
+    \!next}%
+  \!axissetup
+    \def\!axissetup{\relax}%
+  \edef\!ticksinoutsign{\!ticksinoutSign}%
+  \!ticklength=\longticklength
+  \!tickwidth=\linethickness
+  \!gridlinestatus
+  \!setticktransform
+  \!maketick
+  \!tickcase=0
+  \def\!LTlist{}%
+  \!nextkeyword}
+
+\def\ticksout{%
+  \def\!ticksinoutSign{+}}
+\def\ticksin{%
+  \def\!ticksinoutSign{-}}
+\ticksout
+
+\def\gridlines{%
+  \def\!gridlinestatus{\!gridlinestootrue}}
+\def\nogridlines{%
+  \def\!gridlinestatus{\!gridlinestoofalse}}
+\nogridlines
+
+\def\loggedticks{%
+  \def\!setticktransform{\let\!ticktransform=\!logten}}
+\def\unloggedticks{%
+  \def\!setticktransform{\let\!ticktransform=\!donothing}}
+\def\!donothing#1#2{\def#2{#1}}
+\unloggedticks
+
+% ** \!ticks/ : terminates read of tick options
+\expandafter\def\csname !ticks/\endcsname{%
+  \!not {\ifx \!LTlist\empty}
+    \!placetickvalues
+  \fi
+  \def\!tickvalueslist{}%
+  \def\!LTlist{}%
+  \expandafter\csname !axis/\endcsname}
+
+\def\!maketick{%
+  \setbox\!boxA=\hbox{%
+    \beginpicture
+      \!setdimenmode
+      \setcoordinatesystem point at {\!zpt} {\!zpt}
+      \linethickness=\!tickwidth
+      \ifdim\!ticklength>\!zpt
+        \putrule from {\!zpt} {\!zpt} to
+          {\!ticksinoutsign\!tickxsign\!ticklength}
+          {\!ticksinoutsign\!tickysign\!ticklength}
+      \fi
+      \if!gridlinestoo
+        \putrule from {\!zpt} {\!zpt} to
+          {-\!tickxsign\!xaxislength} {-\!tickysign\!yaxislength}
+      \fi
+    \endpicturesave <\!Xsave,\!Ysave>}%
+    \wd\!boxA=\!zpt}
+
+\def\!ticksin{%
+  \def\!ticksinoutsign{-}%
+  \!maketick
+  \!nextkeyword}
+
+\def\!ticksout{%
+  \def\!ticksinoutsign{+}%
+  \!maketick
+  \!nextkeyword}
+
+\def\!tickslength<#1> {%
+  \!ticklength=#1\relax
+  \!maketick
+  \!nextkeyword}
+
+\def\!tickslong{%
+  \!tickslength<\longticklength> }
+
+\def\!ticksshort{%
+  \!tickslength<\shortticklength> }
+
+\def\!tickswidth<#1> {%
+  \!tickwidth=#1\relax
+  \!maketick
+  \!nextkeyword}
+
+\def\!ticksandacross{%
+  \!gridlinestootrue
+  \!maketick
+  \!nextkeyword}
+
+\def\!ticksbutnotacross{%
+  \!gridlinestoofalse
+  \!maketick
+  \!nextkeyword}
+
+\def\!tickslogged{%
+  \let\!ticktransform=\!logten
+  \!nextkeyword}
+
+\def\!ticksunlogged{%
+  \let\!ticktransform=\!donothing
+  \!nextkeyword}
+
+\def\!ticksunlabeled{%
+  \!tickcase=0
+  \!nextkeyword}
+
+\def\!ticksnumbered{%
+  \!tickcase=1
+  \!nextkeyword}
+
+\def\!tickswithvalues#1/ {%
+  \edef\!tickvalueslist{#1! /}%
+  \!tickcase=2
+  \!nextkeyword}
+
+\def\!ticksquantity#1 {%
+  \ifnum #1>1
+    \!updatetickoffset
+    \!countA=#1\relax
+    \advance \!countA -1
+    \!ticklocationincr=\!axisLength
+      \divide \!ticklocationincr \!countA
+    \!ticklocation=\!axisstart
+    \loop \!not{\ifdim \!ticklocation>\!axisend}
+      \!placetick\!ticklocation
+      \ifcase\!tickcase
+          \relax %  Case 0: no labels
+        \or
+          \relax %  Case 1: numbered -- not available here
+        \or
+          \expandafter\!gettickvaluefrom\!tickvalueslist
+          \edef\!tickfield{{\the\!ticklocation}{\!value}}%
+          \expandafter\!listaddon\expandafter{\!tickfield}\!LTlist%
+      \fi
+      \advance \!ticklocation \!ticklocationincr
+    \repeat
+  \fi
+  \!nextkeyword}
+
+\def\!ticksat#1 {%
+  \!updatetickoffset
+  \edef\!Loc{#1}%
+  \if /\!Loc
+    \def\next{\!nextkeyword}%
+  \else
+    \!ticksincommon
+    \def\next{\!ticksat}%
+  \fi
+  \next}
+
+\def\!ticksfrom#1 to #2 by #3 {%
+  \!updatetickoffset
+  \edef\!arg{#3}%
+  \expandafter\!separate\!arg\!nil
+  \!scalefactor=1
+  \expandafter\!countfigures\!arg/
+  \edef\!arg{#1}%
+  \!scaleup\!arg by\!scalefactor to\!countE
+  \edef\!arg{#2}%
+  \!scaleup\!arg by\!scalefactor to\!countF
+  \edef\!arg{#3}%
+  \!scaleup\!arg by\!scalefactor to\!countG
+  \loop \!not{\ifnum\!countE>\!countF}
+    \ifnum\!scalefactor=1
+      \edef\!Loc{\the\!countE}%
+    \else
+      \!scaledown\!countE by\!scalefactor to\!Loc
+    \fi
+    \!ticksincommon
+    \advance \!countE \!countG
+  \repeat
+  \!nextkeyword}
+
+\def\!updatetickoffset{%
+  \!dimenA=\!ticksinoutsign\!ticklength
+  \ifdim \!dimenA>\!offset
+    \!offset=\!dimenA
+  \fi}
+
+\def\!placetick#1{%
+  \if!xswitch
+    \!xpos=#1\relax
+    \!ypos=\!axisylevel
+  \else
+    \!xpos=\!axisxlevel
+    \!ypos=#1\relax
+  \fi
+  \advance\!xpos \!Xsave
+  \advance\!ypos \!Ysave
+  \kern\!xpos\raise\!ypos\copy\!boxA\kern-\!xpos
+  \ignorespaces}
+
+\def\!gettickvaluefrom#1 #2 /{%
+  \edef\!value{#1}%
+  \edef\!tickvalueslist{#2 /}%
+  \ifx \!tickvalueslist\!endtickvaluelist
+    \!tickcase=0
+  \fi}
+\def\!endtickvaluelist{! /}
+
+\def\!ticksincommon{%
+  \!ticktransform\!Loc\!t
+  \!ticklocation=\!t\!!unit
+  \advance\!ticklocation -\!!origin
+  \!placetick\!ticklocation
+  \ifcase\!tickcase
+    \relax % Case 0: no labels
+  \or %      Case 1: numbered
+    \ifdim\!ticklocation<-\!!origin
+      \edef\!Loc{$\!Loc$}%
+    \fi
+    \edef\!tickfield{{\the\!ticklocation}{\!Loc}}%
+    \expandafter\!listaddon\expandafter{\!tickfield}\!LTlist%
+  \or %      Case 2: labeled
+    \expandafter\!gettickvaluefrom\!tickvalueslist
+    \edef\!tickfield{{\the\!ticklocation}{\!value}}%
+    \expandafter\!listaddon\expandafter{\!tickfield}\!LTlist%
+  \fi}
+
+\def\!separate#1\!nil{%
+  \!ifnextchar{-}{\!!separate}{\!!!separate}#1\!nil}
+\def\!!separate-#1\!nil{%
+  \def\!sign{-}%
+  \!!!!separate#1..\!nil}
+\def\!!!separate#1\!nil{%
+  \def\!sign{+}%
+  \!!!!separate#1..\!nil}
+\def\!!!!separate#1.#2.#3\!nil{%
+  \def\!arg{#1}%
+  \ifx\!arg\!empty
+    \!countA=0
+  \else
+    \!countA=\!arg
+  \fi
+  \def\!arg{#2}%
+  \ifx\!arg\!empty
+    \!countB=0
+  \else
+    \!countB=\!arg
+  \fi}
+
+\def\!countfigures#1{%
+  \if #1/%
+    \def\!next{\ignorespaces}%
+  \else
+    \multiply\!scalefactor 10
+    \def\!next{\!countfigures}%
+  \fi
+  \!next}
+
+\def\!scaleup#1by#2to#3{%
+  \expandafter\!separate#1\!nil
+  \multiply\!countA #2\relax
+  \advance\!countA \!countB
+  \if -\!sign
+    \!countA=-\!countA
+  \fi
+  #3=\!countA
+  \ignorespaces}
+
+\def\!scaledown#1by#2to#3{%
+  \!countA=#1\relax%                          ** get original #
+  \ifnum \!countA<0 %                         ** take abs value,
+    \def\!sign{-}%                            **   remember sign
+    \!countA=-\!countA
+  \else
+    \def\!sign{}%
+  \fi
+  \!countB=\!countA%                          ** copy |#|
+  \divide\!countB #2\relax%                   ** integer part (|#|/sf)
+  \!countC=\!countB%                          ** get sf * (|#|/sf)
+    \multiply\!countC #2\relax
+  \advance \!countA -\!countC%                ** ctA is now remainder
+  \edef#3{\!sign\the\!countB.}%               ** +- integerpart.
+  \!countC=\!countA %                         ** Tack on proper number
+  \ifnum\!countC=0 %                          **   of zeros after .
+    \!countC=1
+  \fi
+  \multiply\!countC 10
+  \!loop \ifnum #2>\!countC
+    \edef#3{#3\!zero}%
+    \multiply\!countC 10
+  \repeat
+  \edef#3{#3\the\!countA}%                    ** Add on rest of remainder
+  \ignorespaces}
+
+\def\!placetickvalues{%
+  \advance\!offset \tickstovaluesleading
+  \if!xswitch
+    \setbox\!boxA=\hbox{%
+      \def\\##1##2{%
+        \!dimenput {##2} [B] (##1,\!axisylevel)}%
+      \beginpicture
+        \!LTlist
+      \endpicturesave <\!Xsave,\!Ysave>}%
+    \!dimenA=\!axisylevel
+      \advance\!dimenA -\!Ysave
+      \advance\!dimenA \!tickysign\!offset
+      \if -\!tickysign
+        \advance\!dimenA -\ht\!boxA
+      \else
+        \advance\!dimenA  \dp\!boxA
+      \fi
+    \advance\!offset \ht\!boxA
+      \advance\!offset \dp\!boxA
+    \!dimenput {\box\!boxA} [Bl] <\!Xsave,\!Ysave> (\!zpt,\!dimenA)
+  \else
+    \setbox\!boxA=\hbox{%
+      \def\\##1##2{%
+        \!dimenput {##2} [r] (\!axisxlevel,##1)}%
+      \beginpicture
+        \!LTlist
+      \endpicturesave <\!Xsave,\!Ysave>}%
+    \!dimenA=\!axisxlevel
+      \advance\!dimenA -\!Xsave
+      \advance\!dimenA \!tickxsign\!offset
+      \if -\!tickxsign
+        \advance\!dimenA -\wd\!boxA
+      \fi
+    \advance\!offset \wd\!boxA
+    \!dimenput {\box\!boxA} [Bl] <\!Xsave,\!Ysave> (\!dimenA,\!zpt)
+  \fi}
+
+
+\normalgraphs
+
+% \catcode`!=12 %  *****  THIS MUST NEVER BE OMITTED
+
+\protect \endinput
-- 
cgit v1.2.3

