
###############################################################################
#                                                                             #
#  Lout @Diag package for drawing diagrams                                    #
#  Version 1.0 (July 1996)                                                    #
#  Jeffrey H. Kingston                                                        #
#                                                                             #
#  Based on Version 2.0 of the @Fig package (Jeffrey H. Kingston, Dec 1992).  #
#                                                                             #
###############################################################################

@SysPrependGraphic { diag.lpg }
@SysInclude { diag.etc }

export @Diag
def @DiagramPrint
    named save		             	{ no	           	}
    named maxlabels             	{ 200           	}

    import @Geometry named outline
	named margin {}
	named shadow {}
	named sides {}
	named angle {}
					{ box			}
    named margin			{ 0.6f          	}
    import @Geometry named shadow	{ 0.4f          	}
    import @Geometry named sides	{ 3			}
    import @Geometry named angle	{ "dup 180 exch div"	}
    named translate			{			}
    named outlinestyle
	named solid   { "/ldiagsolid"   }
	named dashed  { "/ldiagdashed"  }
	named cdashed { "/ldiagcdashed" }
	named dotted  { "/ldiagdotted"  }
	named noline  { "/ldiagnoline"  }
					{ solid         	}
    import @Geometry named outlinedashlength	{ 0.2f		}
    import @Geometry named outlinewidth
	named thin   { 0.04 ft }
	named medium { 0.08 ft }
	named thick  { 0.12 ft }
					{ thin	         	}
    named paint                 	{ nopaint       	}
    named font				{			}
    named break				{			}
    named format right @Body    	{ @Body         	}

    named valign			{ ctr           	}
    named vsize                 	{               	}
    named vindent			{ ctr           	}
    named vstrut
	named no  { 0.0f }
	named yes { 1.0f }
					{ no            	}
    named vmargin               	{               	}
    named topmargin             	{               	}
    named footmargin            	{               	}

    named halign			{ ctr           	}
    named hsize                 	{               	}
    named hindent			{ ctr           	}
    named hstrut
	named no  { 0.0f }
	named yes { 1.0f }
					{ no            	}
    named hmargin               	{               	}
    named leftmargin            	{               	}
    named rightmargin           	{               	}

    named nodelabel			{			}
    named nodelabelmargin		{ 0.2f			}
    named nodelabelfont			{ -2p			}
    named nodelabelbreak		{ ragged nohyphen	}
    named nodelabelformat right @Body	{ @Body			}
    import @Geometry named nodelabelpos	{ 			}
    named nodelabelprox			{ outside		}
    import @Geometry named nodelabelangle  { horizontal		}
    named nodelabelctr			{ no			}
    import @Geometry named nodelabeladjust { 0 0		}

    named alabel			{			}
    named alabelmargin			{ 			}
    named alabelfont			{ 			}
    named alabelbreak			{ 			}
    named alabelformat right @Body	{ 			}
    import @Geometry named alabelpos	{ NE			}
    named alabelprox			{ 			}
    import @Geometry named alabelangle	{ 			}
    named alabelctr			{ 			}
    import @Geometry named alabeladjust	{ 			}

    named blabel			{			}
    named blabelmargin			{ 			}
    named blabelfont			{ 			}
    named blabelbreak			{ 			}
    named blabelformat right @Body	{ 			}
    import @Geometry named blabelpos	{ NW			}
    named blabelprox			{ 			}
    import @Geometry named blabelangle	{ 			}
    named blabelctr			{ 			}
    import @Geometry named blabeladjust	{ 			}

    named clabel			{			}
    named clabelmargin			{ 			}
    named clabelfont			{ 			}
    named clabelbreak			{ 			}
    named clabelformat right @Body	{ 			}
    import @Geometry named clabelpos	{ SW			}
    named clabelprox			{ 			}
    import @Geometry named clabelangle	{ 			}
    named clabelctr			{ 			}
    import @Geometry named clabeladjust	{ 			}

    named dlabel			{			}
    named dlabelmargin			{ 			}
    named dlabelfont			{ 			}
    named dlabelbreak			{ 			}
    named dlabelformat right @Body	{ 			}
    import @Geometry named dlabelpos	{ SE			}
    named dlabelprox			{ 			}
    import @Geometry named dlabelangle	{ 			}
    named dlabelctr			{ 			}
    import @Geometry named dlabeladjust	{ 			}

    import @Geometry named path
	named from {}
	named to {}
	named bias {}
	named fbias {}
	named tbias {}
	named radius {}
	named xindent {}
	named zindent {}
	named frompt {}
	named topt {}
	named arrow {}
	named arrowlength {}
					{ line			}
    import @Geometry named from		{ 0,0			}
    import @Geometry named to		{ 1,1			}
    import @Geometry named bias		{ 2.0f			}
    import @Geometry named fbias	{ 2.0f			}
    import @Geometry named tbias	{ 2.0f			}
    import @Geometry named radius	{ 1.0f			}
    import @Geometry named xindent	{ 0.8f			}
    import @Geometry named zindent	{ 0.8f			}
    import @Geometry named frompt	{ 0 0			}
    import @Geometry named topt		{ 0 0			}
    named pathstyle
	named solid   { "/ldiagsolid"   }
	named dashed  { "/ldiagdashed"  }
	named cdashed { "/ldiagcdashed" }
	named dotted  { "/ldiagdotted"  }
	named noline  { "/ldiagnoline"  }
					{ solid         	}
    import @Geometry named pathdashlength { 0.2f		}
    import @Geometry named pathwidth
	named thin   { 0.04 ft }
	named medium { 0.08 ft }
	named thick  { 0.12 ft }
					{ thin	         	}
    named arrow                 	{ no			}
    named arrowstyle             	{ solid			}
    named arrowwidth             	{ 0.3f			}
    named arrowlength            	{ 0.5f			}

    named linklabel			{			}
    named linklabelmargin		{ 0.2f			}
    named linklabelfont			{ -2p			}
    named linklabelbreak		{ ragged nohyphen	}
    named linklabelformat right @Body	{ @Body			}
    import @Geometry named linklabelpos	{ 			}
    named linklabelprox			{ above			}
    import @Geometry named linklabelangle  { horizontal		}
    named linklabelctr			{ no			}
    import @Geometry named linklabeladjust { 0 0		}

    named xlabel			{			}
    named xlabelmargin			{ 			}
    named xlabelfont			{ 			}
    named xlabelbreak			{ 			}
    named xlabelformat right @Body	{ 			}
    import @Geometry named xlabelpos	{ LFROM			}
    named xlabelprox			{ 			}
    import @Geometry named xlabelangle	{ 			}
    named xlabelctr			{			}
    import @Geometry named xlabeladjust	{ 			}

    named ylabel			{			}
    named ylabelmargin			{ 			}
    named ylabelfont			{ 			}
    named ylabelbreak			{ 			}
    named ylabelformat right @Body	{ 			}
    import @Geometry named ylabelpos	{ LMID			}
    named ylabelprox			{ 			}
    import @Geometry named ylabelangle	{ 			}
    named ylabelctr			{ yes			}
    import @Geometry named ylabeladjust	{ 			}

    named zlabel			{			}
    named zlabelmargin			{ 			}
    named zlabelfont			{ 			}
    named zlabelbreak			{ 			}
    named zlabelformat right @Body	{ 			}
    import @Geometry named zlabelpos	{ LTO			}
    named zlabelprox			{ 			}
    import @Geometry named zlabelangle	{ 			}
    named zlabelctr			{			}
    import @Geometry named zlabeladjust	{ 			}

    named fromlabel			{			}
    named fromlabelmargin		{ 0f			}
    named fromlabelfont			{			}
    named fromlabelbreak		{ ragged nohyphen	}
    named fromlabelformat right @Body	{ @Body			}
    import @Geometry named fromlabelpos	{ FROM			}
    named fromlabelprox			{ W			}
    import @Geometry named fromlabelangle  { antiparallel	}
    named fromlabelctr			{ no			}
    import @Geometry named fromlabeladjust { 0 0		}

    named tolabel			{			}
    named tolabelmargin			{ 0f			}
    named tolabelfont			{			}
    named tolabelbreak			{ ragged nohyphen	}
    named tolabelformat right @Body	{ @Body			}
    import @Geometry named tolabelpos	{ TO			}
    named tolabelprox			{ W			}
    import @Geometry named tolabelangle	{ parallel		}
    named tolabelctr			{ no			}
    import @Geometry named tolabeladjust { 0 0			}

    named treehsep			{ 0.5f			}
    named treevsep			{ 0.5f			}
    named treehindent
	named left  { 0.0rt }
	named ctr   { 0.5rt }
	named right { 1.0rt }
					{ ctr			}
    named treevindent
	named top   { 0.0rt }
	named ctr   { 0.5rt }
	named foot  { 1.0rt }
					{ ctr			}

{

    export "::" @ShowPoints @ShowTags @ShowDirections @CatchTags @Transform

	   @Tree @HTree

           @Node
           @Box @CurveBox @ShadowBox @Square @Diamond @Polygon
	   @Isosceles @Ellipse @Circle
	   @ArrowHead @SolidArrowHead @OpenArrowHead @HalfOpenArrowHead
	   @SolidCurvedArrowHead @OpenCurvedArrowHead @HalfOpenCurvedArrowHead
	   @CircleArrowHead @BoxArrowHead

	   @Link
	   @Line @Arrow @Curve @CurveArrow
	   @ACurve @ACurveArrow @CCurve @CCurveArrow
	   @Bezier @BezierArrow
	   @HVLine @HVArrow @VHLine @VHArrow
	   @HVCurve @HVCurveArrow @VHCurve @VHCurveArrow
	   @LVRLine @LVRArrow @RVLLine @RVLArrow
	   @LVRCurve @LVRCurveArrow @RVLCurve @RVLCurveArrow
	   @DWrapLine @DWrapArrow @UWrapLine @UWrapArrow
	   @DWrapCurve @DWrapCurveArrow @UWrapCurve @UWrapCurveArrow

    def @Diag
	named save		             	{ save	           	}
        named maxlabels             		{ maxlabels     	}

	import @Geometry named outline
	    named margin {}
	    named shadow {}
	    named sides {}
	    named angle {}
						{ outline
						    margin { margin }
						    shadow { shadow }
						    sides  { sides  }
						    angle  { angle  }
						}
        named margin                		{ margin        	}
	import @Geometry named shadow		{ shadow		}
	import @Geometry named sides		{ sides			}
	import @Geometry named angle		{ angle			}
	named translate				{ translate		}
	named nodetag				{			}
        named outlinestyle
	    named solid   { "/ldiagsolid"   }
	    named dashed  { "/ldiagdashed"  }
	    named cdashed { "/ldiagcdashed" }
	    named dotted  { "/ldiagdotted"  }
	    named noline  { "/ldiagnoline"  }
						{ outlinestyle     	}
        import @Geometry named outlinedashlength{ outlinedashlength    	}
        import @Geometry named outlinewidth
	    named thin   { 0.04 ft }
	    named medium { 0.08 ft }
	    named thick  { 0.12 ft }
						{ outlinewidth     	}
        named paint                 		{ paint         	}
	named font				{ font			}
	named break				{ break			}
        named format right @Body    		{ format @Body  	}
        named valign				{ valign        	}
        named vsize                 		{ vsize         	}
        named vindent				{ vindent       	}
        named vstrut
		named no  { 0.0f }
		named yes { 1.0f }
						{ vstrut	 	}
        named vmargin               		{ vmargin       	}
        named topmargin             		{ topmargin     	}
        named footmargin            		{ footmargin    	}
        named halign				{ halign        	}
        named hsize                 		{ hsize         	}
        named hindent				{ hindent       	}
        named hstrut
		named no  { 0.0f }
		named yes { 1.0f }
						{ hstrut	 	}
        named hmargin               		{ hmargin       	}
        named leftmargin            		{ leftmargin    	}
        named rightmargin           		{ rightmargin   	}

	import @Geometry named path
	    named from {}
	    named to {}
	    named bias {}
	    named fbias {}
	    named tbias {}
	    named radius {}
	    named xindent {}
	    named zindent {}
	    named frompt {}
	    named topt {}
	    named arrow {}
	    named arrowlength {}
						{ path
						    from	{ from }
						    to		{ to   }
						    bias	{ bias }
						    fbias	{ fbias }
						    tbias	{ tbias }
						    radius	{ radius }
						    xindent	{ xindent }
						    zindent	{ zindent }
						    frompt	{ frompt }
						    topt	{ topt }
						    arrow	{ arrow }
						    arrowlength	{ arrowlength }
						}
	import @Geometry named from		{ from			}
	import @Geometry named to		{ to			}
	import @Geometry named bias		{ bias			}
	import @Geometry named fbias		{ fbias			}
	import @Geometry named tbias		{ tbias			}
	import @Geometry named radius		{ radius		}
	import @Geometry named xindent		{ xindent		}
	import @Geometry named zindent		{ zindent		}
	import @Geometry named frompt		{ frompt		}
	import @Geometry named topt		{ topt			}
        named pathstyle
	    named solid   { "/ldiagsolid"   }
	    named dashed  { "/ldiagdashed"  }
	    named cdashed { "/ldiagcdashed" }
	    named dotted  { "/ldiagdotted"  }
	    named noline  { "/ldiagnoline"  }
						{ pathstyle     	}
        import @Geometry named pathdashlength	{ pathdashlength    	}
        import @Geometry named pathwidth
	    named thin   { 0.04 ft }
	    named medium { 0.08 ft }
	    named thick  { 0.12 ft }
						{ pathwidth     	}
	named arrow				{ arrow			}
	named arrowstyle			{ arrowstyle		}
	named arrowwidth			{ arrowwidth		}
	named arrowlength			{ arrowlength		}

	named nodelabel				{ nodelabel		}
	named nodelabelmargin			{ nodelabelmargin	}
	named nodelabelfont			{ nodelabelfont		}
	named nodelabelbreak			{ nodelabelbreak	}
	named nodelabelformat right @Body	{ nodelabelformat @Body	}
	import @Geometry named nodelabelpos	{ nodelabelpos		}
	named nodelabelprox			{ nodelabelprox		}
	import @Geometry named nodelabelangle	{ nodelabelangle	}
	named nodelabelctr			{ nodelabelctr		}
	import @Geometry named nodelabeladjust	{ nodelabeladjust	}

        named alabel				{ alabel		}
        named alabelmargin			{ alabelmargin		}
        named alabelfont			{ alabelfont		}
        named alabelbreak			{ alabelbreak		}
	named alabelformat right @Body		{ alabelformat @Body	}
        import @Geometry named alabelpos	{ alabelpos		}
        named alabelprox			{ alabelprox		}
        import @Geometry named alabelangle	{ alabelangle		}
	named alabelctr				{ alabelctr		}
        import @Geometry named alabeladjust	{ alabeladjust		}

        named blabel				{ blabel		}
        named blabelmargin			{ blabelmargin		}
        named blabelfont			{ blabelfont		}
        named blabelbreak			{ blabelbreak		}
	named blabelformat right @Body		{ blabelformat @Body	}
        import @Geometry named blabelpos	{ blabelpos		}
        named blabelprox			{ blabelprox		}
        import @Geometry named blabelangle	{ blabelangle		}
	named blabelctr				{ blabelctr		}
        import @Geometry named blabeladjust	{ blabeladjust		}

        named clabel				{ clabel		}
        named clabelmargin			{ clabelmargin		}
        named clabelfont			{ clabelfont		}
        named clabelbreak			{ clabelbreak		}
	named clabelformat right @Body		{ clabelformat @Body	}
        import @Geometry named clabelpos	{ clabelpos		}
        named clabelprox			{ clabelprox		}
        import @Geometry named clabelangle	{ clabelangle		}
	named clabelctr				{ clabelctr		}
        import @Geometry named clabeladjust	{ clabeladjust		}

        named dlabel				{ dlabel		}
        named dlabelmargin			{ dlabelmargin		}
        named dlabelfont			{ dlabelfont		}
        named dlabelbreak			{ dlabelbreak		}
	named dlabelformat right @Body		{ dlabelformat @Body	}
        import @Geometry named dlabelpos	{ dlabelpos		}
        named dlabelprox			{ dlabelprox		}
        import @Geometry named dlabelangle	{ dlabelangle		}
	named dlabelctr				{ dlabelctr		}
        import @Geometry named dlabeladjust	{ dlabeladjust		}

        named fromlabel				{ fromlabel		}
        named fromlabelmargin			{ fromlabelmargin	}
        named fromlabelfont			{ fromlabelfont		}
        named fromlabelbreak			{ fromlabelbreak	}
	named fromlabelformat right @Body	{ fromlabelformat @Body	}
        import @Geometry named fromlabelpos	{ fromlabelpos		}
        named fromlabelprox			{ fromlabelprox		}
        import @Geometry named fromlabelangle	{ fromlabelangle	}
	named fromlabelctr			{ fromlabelctr		}
        import @Geometry named fromlabeladjust	{ fromlabeladjust	}

	named linklabel				{ linklabel		}
	named linklabelmargin			{ linklabelmargin	}
	named linklabelfont			{ linklabelfont		}
	named linklabelbreak			{ linklabelbreak	}
	named linklabelformat right @Body	{ linklabelformat @Body	}
	import @Geometry named linklabelpos	{ linklabelpos		}
	named linklabelprox			{ linklabelprox		}
	import @Geometry named linklabelangle	{ linklabelangle	}
	named linklabelctr			{ linklabelctr		}
	import @Geometry named linklabeladjust	{ linklabeladjust	}

        named xlabel				{ xlabel		}
        named xlabelmargin			{ xlabelmargin		}
        named xlabelfont			{ xlabelfont		}
        named xlabelbreak			{ xlabelbreak		}
	named xlabelformat right @Body		{ xlabelformat @Body	}
        import @Geometry named xlabelpos	{ xlabelpos		}
        named xlabelprox			{ xlabelprox		}
        import @Geometry named xlabelangle	{ xlabelangle		}
	named xlabelctr				{ xlabelctr		}
        import @Geometry named xlabeladjust	{ xlabeladjust		}

        named ylabel				{ ylabel		}
        named ylabelmargin			{ ylabelmargin		}
        named ylabelfont			{ ylabelfont		}
        named ylabelbreak			{ ylabelbreak		}
	named ylabelformat right @Body		{ ylabelformat @Body	}
        import @Geometry named ylabelpos	{ ylabelpos		}
        named ylabelprox			{ ylabelprox		}
        import @Geometry named ylabelangle	{ ylabelangle		}
	named ylabelctr				{ ylabelctr		}
        import @Geometry named ylabeladjust	{ ylabeladjust		}

        named zlabel				{ zlabel		}
        named zlabelmargin			{ zlabelmargin		}
        named zlabelfont			{ zlabelfont		}
        named zlabelbreak			{ zlabelbreak		}
	named zlabelformat right @Body		{ zlabelformat @Body	}
        import @Geometry named zlabelpos	{ zlabelpos		}
        named zlabelprox			{ zlabelprox		}
        import @Geometry named zlabelangle	{ zlabelangle		}
	named zlabelctr				{ zlabelctr		}
        import @Geometry named zlabeladjust	{ zlabeladjust		}

        named tolabel				{ tolabel		}
        named tolabelmargin			{ tolabelmargin		}
        named tolabelfont			{ tolabelfont		}
        named tolabelbreak			{ tolabelbreak		}
	named tolabelformat right @Body		{ tolabelformat @Body	}
        import @Geometry named tolabelpos	{ tolabelpos		}
        named tolabelprox			{ tolabelprox		}
        import @Geometry named tolabelangle	{ tolabelangle		}
	named tolabelctr			{ tolabelctr		}
        import @Geometry named tolabeladjust	{ tolabeladjust		}

	named treehsep				{ treehsep		}
	named treevsep				{ treevsep		}
	named treehindent
	    named left  { 0.0rt }
	    named ctr   { 0.5rt }
	    named right { 1.0rt }
						{ treehindent		}
	named treevindent
	    named top   { 0.0rt }
	    named ctr   { 0.5rt }
	    named foot  { 1.0rt }
						{ treevindent		}
        body @Body
    @Begin

        # Like @Graphic, but affects the graphics state of right parameter
        def @InnerGraphic
            left ps
            right x
        {
          @BackEnd @Case {
            PostScript @Yield {
              { ps gsave // grestore } @Graphic x
            }
            PDF @Yield {
              { ps q // Q } @Graphic x
            }
          }
        }

	def @BoxLabels right x
	{
          @BackEnd @Case {
            PostScript @Yield {
	        "[ ldiagbox ] pop" @Graphic x
	      }
	      PDF @Yield {}
	    }
	}

	def @IfNonEmpty
	    left x
	    right y
	{
	    x @Case {
		""   @Yield @Null
		else @Yield y
	    }
	}

	def @Else
	    precedence 20
	    associativity right
	    left x
	    right y
	{
	    x @Case {
		""   @Yield y
		else @Yield x
	    }
	}

        def @ShowTags
	    right x
        {
          @BackEnd @Case {
            PostScript @Yield {
            {
	      "() ldiagpushtagdict"
              // "ldiagshowtags ldiagpopuptagdict"
	      } @Graphic x
	      }
	      PDF @Yield {}
	    }
        }

        def @ShowPoints
	    right x
        {
          @BackEnd @Case {
            PostScript @Yield {
            {
	      "() ldiagpushtagdict"
              // "ldiagshowpoints ldiagpopuptagdict"
	      } @Graphic x
	      }
	      PDF @Yield {}
	    }
        }

        def @ShowDirections
	    right x
        {
          @BackEnd @Case {
            PostScript @Yield {
            { "() ldiagpushtagdict"
              // "ldiagshowangles ldiagpopuptagdict" } @Graphic x
	      }
	      PDF @Yield {}
	    }
        }

        def "::"
            precedence 33
	    associativity right
            left name
            right x
        {
          @BackEnd @Case {
            PostScript @Yield {
            { "("name") ldiagpushtagdict"
              // "ldiagpopuptagdict" } @Graphic x
	      }
	      PDF @Yield {}
	    }
        }

        def @CatchTags
            precedence 33
	    associativity right
            right x
        {
          @BackEnd @Case {
            PostScript @Yield {
            {
	       "() ldiagpushtagdict"
               // "ldiagpoptagdict"
	      }
	      @Graphic x
	      }
	      PDF @Yield {}
	    }
        }

        def @ZeroWidth right x
        {
	    @HContract @VContract {
            ^|0io @HContract @VContract x |0io
	    }
        }

        def @ZeroSize right x
        {
	    @HContract @VContract {
            ^/0io ^|0io @HContract @VContract x |0io /0io
	    }
        }

	def @FromArrowLength
	    left arrow
	    right arrowlength
	{
        @BackEnd @Case {
          PostScript @Yield {
	    arrow @Case {
		{ no yes forward }   @Yield 0
		{ back both }	     @Yield {"("arrowlength") ldiagdecodelength"}
	    }
	    }
	    PDF @Yield {}
	  }
	}

	def @ToArrowLength
	    left arrow
	    right arrowlength
	{
        @BackEnd @Case {
          PostScript @Yield {
	    arrow @Case {
		{ no back }	     @Yield 0
		{ yes forward both } @Yield {"("arrowlength") ldiagdecodelength"}
	    }
	    }
	    PDF @Yield {}
	  }
	}

	def @AddMargins
	    named mtop {}
	    named mfoot {}
	    named mleft {}
	    named mright {}
	    right x
	{

	    @HContract @VContract {
			 ^|mleft    |mright
		^/mtop    |      x  |
		 /mfoot   |         |
	    }
	}

        def @Transform
            precedence 32
            import @Geometry named translate
#               named to precedence 10 left x right y { x y "ldiagpsub" }
                named to precedence 10 left x right y {
                  @BackEnd @Case {
                    PostScript @Yield { x y "ldiagpsub" }
                    PDF @Yield {""}
                  }
                }
            {}
            import @Geometry named rotate { 0d }
            named scale    { 1 1 }
            right x
        {
          @BackEnd @Case {

            PostScript @Yield {
            { rotate "rotate" scale "scale newpath clip" }
            @InnerGraphic
            {
                @ZeroSize x
            }
            //
            # { rotate "rotate" scale "scale" translate "translate" }
            { translate "translate" rotate "rotate" scale "scale" }
            @InnerGraphic
            {
                @ZeroSize x
            }
	      }

	      PDF @Yield { # presume that "rotate", "scale" and "translate" are not matrices
            { "__cos("rotate") __sin("rotate") __sub(0, __sin("rotate")) __cos("rotate") 0 0 cm"
              "__pick(1, "scale") 0 0 __pick(2, "scale") 0 0 cm n W" }
            @InnerGraphic
            {
                @ZeroSize x
            }
            //
            # { rotate "rotate" scale "scale" translate "translate" }
            { "1 0 0 1 "translate" cm"
              "__cos("rotate") __sin("rotate") __sub(0, __sin("rotate")) __cos("rotate") 0 0 cm"
              "__pick(1, "scale") 0 0 __pick(2, "scale") 0 0 cm" }
            @InnerGraphic
            {
                @ZeroSize x
            }
	      }

	    }
        }

	def @DoLabel
	    named which				{}
	    named labeltag			{ LABEL }
	    named label				{}
	    named labelmargin			{}
	    named labelfont			{}
	    named labelbreak			{}
	    named labelformat right @Body	{}
	    named labelpos			{}
	    named labelprox			{}
	    named labelangle			{}
	    named labelctr			{}
	    named labeladjust			{}
	{

	    import @Geometry
            def alignedangle
            {
		labelpos??"ANGLE" quadcase 
			0	{ labelpos??"ANGLE"		}
			0-90	{ labelpos??"ANGLE"		}
			90	{ labelpos??"ANGLE"		}
			90-180	{ labelpos??"ANGLE" + 180d	}
			180	{ labelpos??"ANGLE" + 180d	}
			180-270	{ labelpos??"ANGLE" + 180d	}
			270	{ labelpos??"ANGLE" + 180d	}
			270-360	{ labelpos??"ANGLE"		}
	    }

	    import @Geometry
            def perpalignedangle
            {
		labelpos??"ANGLE" quadcase 
			0	{ labelpos??"ANGLE" - 90d	}
			0-90	{ labelpos??"ANGLE" - 90d	}
			90	{ labelpos??"ANGLE" - 90d	}
			90-180	{ labelpos??"ANGLE" - 90d	}
			180	{ labelpos??"ANGLE" + 90d	}
			180-270	{ labelpos??"ANGLE" + 90d	}
			270	{ labelpos??"ANGLE" + 90d	}
			270-360	{ labelpos??"ANGLE" + 90d	}
		    
	    }

	    import @Geometry
            def finalangle
            {
                labelangle @Case {

		    "horizontal"	@Yield { 0d				}
                    "aligned"		@Yield { alignedangle			}
                    "perpendicular"	@Yield { perpalignedangle		}
                    "parallel"		@Yield { labelpos??"ANGLE"		}
                    "antiparallel"	@Yield { labelpos??"ANGLE" + 180d	}
                    else		@Yield labelangle
                }
            }

	    import @Geometry
	    def @AlignedAboveProximity
	    {
		which @Case {
		  { x f } @Yield { labelpos??ANGLE quadcase
				0	{ (SW) }
				0-90	{ (SW) }
				90	{ (SW) }
				90-180	{ (SE) }
				180	{ (SE) }
				180-270	{ (SE) }
				270	{ (SE) }
				270-360	{ (SW) }
			  }
		  { z t } @Yield { labelpos??ANGLE quadcase
				0	{ (SE) }
				0-90	{ (SE) }
				90	{ (SE) }
				90-180	{ (SW) }
				180	{ (SW) }
				180-270	{ (SW) }
				270	{ (SW) }
				270-360	{ (SE) }
			  }
		  else @Yield (S)
		}
	    }

	    import @Geometry
	    def @AlignedBelowProximity
	    {
		which @Case {
		  { x f } @Yield { labelpos??ANGLE quadcase
				0	{ (NW) }
				0-90	{ (NW) }
				90	{ (NW) }
				90-180	{ (NE) }
				180	{ (NE) }
				180-270	{ (NE) }
				270	{ (NE) }
				270-360	{ (NW) }
			  }
		  { z t } @Yield { labelpos??ANGLE quadcase
				0	{ (NE) }
				0-90	{ (NE) }
				90	{ (NE) }
				90-180	{ (NW) }
				180	{ (NW) }
				180-270	{ (NW) }
				270	{ (NW) }
				270-360	{ (NE) }
			  }
		  else @Yield (N)
		}
	    }

	    import @Geometry
	    def @AlignedLeftProximity
	    {
		which @Case {
		  { x f } @Yield { labelpos??ANGLE quadcase
				0	{ (SW) }
				0-90	{ (SW) }
				90	{ (SW) }
				90-180	{ (NE) }
				180	{ (SE) }
				180-270	{ (SE) }
				270	{ (SE) }
				270-360	{ (NW) }
			  }
		  { z t } @Yield { labelpos??ANGLE quadcase
				0	{ (SE) }
				0-90	{ (SE) }
				90	{ (SE) }
				90-180	{ (NW) }
				180	{ (SW) }
				180-270	{ (SW) }
				270	{ (SW) }
				270-360	{ (NE) }
			  }
		  else @Yield { labelpos??ANGLE quadcase
				0	{ (S) }
				0-90	{ (S) }
				90	{ (S) }
				90-180	{ (N) }
				180	{ (S) }
				180-270	{ (S) }
				270	{ (S) }
				270-360	{ (N) }
			  }
		}
	    }

	    import @Geometry
	    def @AlignedRightProximity
	    {
		which @Case {
		  { x f } @Yield { labelpos??ANGLE quadcase
				0	{ (SW) }
				0-90	{ (NW) }
				90	{ (NW) }
				90-180	{ (SE) }
				180	{ (SE) }
				180-270	{ (NE) }
				270	{ (NE) }
				270-360	{ (SW) }
			  }
		  { z t } @Yield { labelpos??ANGLE quadcase
				0	{ (SE) }
				0-90	{ (NE) }
				90	{ (NE) }
				90-180	{ (SW) }
				180	{ (SW) }
				180-270	{ (NW) }
				270	{ (NW) }
				270-360	{ (SE) }
			  }
		  else @Yield { labelpos??ANGLE quadcase
				0	{ (S) }
				0-90	{ (N) }
				90	{ (N) }
				90-180	{ (S) }
				180	{ (S) }
				180-270	{ (N) }
				270	{ (N) }
				270-360	{ (S) }
			  }
		}
	    }

	    import @Geometry
	    def @AlignedInsideProximity
	    {
		which @Case {
		  { x f } @Yield { labelpos??ANGLE quadcase
				0	{ (SW) }
				0-90	{ (SW) }
				90	{ (SW) }
				90-180	{ (NE) }
				180	{ (NE) }
				180-270	{ (NE) }
				270	{ (NE) }
				270-360	{ (SW) }
			  }
		  { z t } @Yield { labelpos??ANGLE quadcase
				0	{ (SE) }
				0-90	{ (SE) }
				90	{ (SE) }
				90-180	{ (NW) }
				180	{ (NW) }
				180-270	{ (NW) }
				270	{ (NW) }
				270-360	{ (SE) }
			  }
		  else @Yield { labelpos??ANGLE quadcase
				0	{ (S) }
				0-90	{ (S) }
				90	{ (S) }
				90-180	{ (N) }
				180	{ (N) }
				180-270	{ (N) }
				270	{ (N) }
				270-360	{ (S) }
			  }
		}
	    }

	    import @Geometry
	    def @AlignedOutsideProximity
	    {
		which @Case {
		  { x f } @Yield { labelpos??ANGLE quadcase
				0	{ (NW) }
				0-90	{ (NW) }
				90	{ (NW) }
				90-180	{ (SE) }
				180	{ (SE) }
				180-270	{ (SE) }
				270	{ (SE) }
				270-360	{ (NW) }
			  }
		  { z t } @Yield { labelpos??ANGLE quadcase
				0	{ (NE) }
				0-90	{ (NE) }
				90	{ (NE) }
				90-180	{ (SW) }
				180	{ (SW) }
				180-270	{ (SW) }
				270	{ (SW) }
				270-360	{ (NE) }
			  }
		  else @Yield { labelpos??ANGLE quadcase
				0	{ (N) }
				0-90	{ (N) }
				90	{ (N) }
				90-180	{ (S) }
				180	{ (S) }
				180-270	{ (S) }
				270	{ (S) }
				270-360	{ (N) }
			  }
		}
	    }


	    import @Geometry
	    def @PerpendicularAboveProximity
	    {
		which @Case {
		  { x f } @Yield { labelpos??ANGLE quadcase
				0	{ (SE) }
				0-90	{ (SE) }
				90	{ (SE) }
				90-180	{ (SW) }
				180	{ (NE) }
				180-270	{ (NE) }
				270	{ (NE) }
				270-360	{ (NW) }
			  }
		  { z t } @Yield { labelpos??ANGLE quadcase
				0	{ (NE) }
				0-90	{ (NE) }
				90	{ (NE) }
				90-180	{ (NW) }
				180	{ (SE) }
				180-270	{ (SE) }
				270	{ (SE) }
				270-360	{ (SW) }
			  }
		  else @Yield { labelpos??ANGLE quadcase
				0	{ (E) }
				0-90	{ (E) }
				90	{ (E) }
				90-180	{ (W) }
				180	{ (E) }
				180-270	{ (E) }
				270	{ (E) }
				270-360	{ (W) }
			  }
		}
	    }

	    import @Geometry
	    def @PerpendicularBelowProximity
	    {
		which @Case {
		  { x f } @Yield { labelpos??ANGLE quadcase
				0	{ (SW) }
				0-90	{ (SW) }
				90	{ (SW) }
				90-180	{ (SE) }
				180	{ (NW) }
				180-270	{ (NW) }
				270	{ (NW) }
				270-360	{ (NE) }
			  }
		  { z t } @Yield { labelpos??ANGLE quadcase
				0	{ (NW) }
				0-90	{ (NW) }
				90	{ (NW) }
				90-180	{ (NE) }
				180	{ (SW) }
				180-270	{ (SW) }
				270	{ (SW) }
				270-360	{ (SE) }
			  }
		  else @Yield { labelpos??ANGLE quadcase
				0	{ (W) }
				0-90	{ (W) }
				90	{ (W) }
				90-180	{ (E) }
				180	{ (W) }
				180-270	{ (W) }
				270	{ (W) }
				270-360	{ (E) }
			  }
		}
	    }

	    import @Geometry
	    def @PerpendicularLeftProximity
	    {
		which @Case {
		  { x f } @Yield { labelpos??ANGLE quadcase
				0	{ (SE) }
				0-90	{ (SE) }
				90	{ (SE) }
				90-180	{ (SE) }
				180	{ (NE) }
				180-270	{ (NE) }
				270	{ (NE) }
				270-360	{ (NE) }
			  }
		  { z t } @Yield { labelpos??ANGLE quadcase
				0	{ (NE) }
				0-90	{ (NE) }
				90	{ (NE) }
				90-180	{ (NE) }
				180	{ (SE) }
				180-270	{ (SE) }
				270	{ (SE) }
				270-360	{ (SE) }
			  }
		  else @Yield (E)
		}
	    }

	    import @Geometry
	    def @PerpendicularRightProximity
	    {
		which @Case {
		  { x f } @Yield { labelpos??ANGLE quadcase
				0	{ (SW) }
				0-90	{ (SW) }
				90	{ (SW) }
				90-180	{ (SW) }
				180	{ (NW) }
				180-270	{ (NW) }
				270	{ (NW) }
				270-360	{ (NW) }
			  }
		  { z t } @Yield { labelpos??ANGLE quadcase
				0	{ (NW) }
				0-90	{ (NW) }
				90	{ (NW) }
				90-180	{ (NW) }
				180	{ (SW) }
				180-270	{ (SW) }
				270	{ (SW) }
				270-360	{ (SW) }
			  }
		  else @Yield (W)
		}
	    }

	    import @Geometry
	    def @PerpendicularInsideProximity
	    {
		which @Case {
		  { x f } @Yield { labelpos??ANGLE quadcase
				0	{ (SE) }
				0-90	{ (SE) }
				90	{ (SE) }
				90-180	{ (SE) }
				180	{ (NW) }
				180-270	{ (NW) }
				270	{ (NW) }
				270-360	{ (NW) }
			  }
		  { z t } @Yield { labelpos??ANGLE quadcase
				0	{ (NE) }
				0-90	{ (NE) }
				90	{ (NE) }
				90-180	{ (NE) }
				180	{ (SW) }
				180-270	{ (SW) }
				270	{ (SW) }
				270-360	{ (SW) }
			  }
		  else @Yield { labelpos??ANGLE quadcase
				0	{ (E) }
				0-90	{ (E) }
				90	{ (E) }
				90-180	{ (E) }
				180	{ (W) }
				180-270	{ (W) }
				270	{ (W) }
				270-360	{ (W) }
			  }
		}
	    }

	    import @Geometry
	    def @PerpendicularOutsideProximity
	    {
		which @Case {
		  { x f } @Yield { labelpos??ANGLE quadcase
				0	{ (SW) }
				0-90	{ (SW) }
				90	{ (SW) }
				90-180	{ (SW) }
				180	{ (NE) }
				180-270	{ (NE) }
				270	{ (NE) }
				270-360	{ (NE) }
			  }
		  { z t } @Yield { labelpos??ANGLE quadcase
				0	{ (NW) }
				0-90	{ (NW) }
				90	{ (NW) }
				90-180	{ (NW) }
				180	{ (SE) }
				180-270	{ (SE) }
				270	{ (SE) }
				270-360	{ (SE) }
			  }
		  else @Yield { labelpos??ANGLE quadcase
				0	{ (W) }
				0-90	{ (W) }
				90	{ (W) }
				90-180	{ (W) }
				180	{ (E) }
				180-270	{ (E) }
				270	{ (E) }
				270-360	{ (E) }
			  }
		}
	    }


	    import @Geometry
	    def @OtherAboveProximity
	    {
		which @Case {
		  { x f } @Yield { labelpos??ANGLE quadcase
				0	{ (SW) }
				0-90	{ (SE) }
				90	{ (SW) }
				90-180	{ (SW) }
				180	{ (SE) }
				180-270	{ (SE) }
				270	{ (NW) }
				270-360	{ (SW) }
			  }
		  { z t } @Yield { labelpos??ANGLE quadcase
				0	{ (SE) }
				0-90	{ (SE) }
				90	{ (NW) }
				90-180	{ (SW) }
				180	{ (SW) }
				180-270	{ (SE) }
				270	{ (SW) }
				270-360	{ (SW) }
			  }
		  else @Yield { labelpos??ANGLE quadcase
				0	{ (S) }
				0-90	{ (SE) }
				90	{ (W) }
				90-180	{ (SW) }
				180	{ (S) }
				180-270	{ (SE) }
				270	{ (W) }
				270-360	{ (SW) }
			  }
		}
	    }

	    import @Geometry
	    def @OtherBelowProximity
	    {
		which @Case {
		  { x f } @Yield { labelpos??ANGLE quadcase
				0	{ (NW) }
				0-90	{ (NW) }
				90	{ (SW) }
				90-180	{ (NE) }
				180	{ (NE) }
				180-270	{ (NW) }
				270	{ (NW) }
				270-360	{ (NE) }
			  }
		  { z t } @Yield { labelpos??ANGLE quadcase
				0	{ (NE) }
				0-90	{ (NW) }
				90	{ (NW) }
				90-180	{ (NE) }
				180	{ (NW) }
				180-270	{ (NW) }
				270	{ (SW) }
				270-360	{ (NE) }
			  }
		  else @Yield { labelpos??ANGLE quadcase
				0	{ (N) }
				0-90	{ (NW) }
				90	{ (W) }
				90-180	{ (NE) }
				180	{ (N) }
				180-270	{ (NW) }
				270	{ (W) }
				270-360	{ (NE) }
			  }
		}
	    }

	    import @Geometry
	    def @OtherLeftProximity
	    {
		which @Case {
		  { x f } @Yield { labelpos??ANGLE quadcase
				0	{ (SW) }
				0-90	{ (SE) }
				90	{ (SE) }
				90-180	{ (NE) }
				180	{ (SE) }
				180-270	{ (SE) }
				270	{ (NE) }
				270-360	{ (NE) }
			  }
		  { z t } @Yield { labelpos??ANGLE quadcase
				0	{ (SE) }
				0-90	{ (SE) }
				90	{ (NE) }
				90-180	{ (NE) }
				180	{ (SW) }
				180-270	{ (SE) }
				270	{ (SE) }
				270-360	{ (NE) }
			  }
		  else @Yield { labelpos??ANGLE quadcase
				0	{ (S) }
				0-90	{ (SE) }
				90	{ (E) }
				90-180	{ (NE) }
				180	{ (S) }
				180-270	{ (SE) }
				270	{ (E) }
				270-360	{ (NE) }
			  }
		}
	    }

	    import @Geometry
	    def @OtherRightProximity
	    {
		which @Case {
		  { x f } @Yield { labelpos??ANGLE quadcase
				0	{ (SW) }
				0-90	{ (NW) }
				90	{ (SW) }
				90-180	{ (SW) }
				180	{ (SE) }
				180-270	{ (NW) }
				270	{ (NW) }
				270-360	{ (SW) }
			  }
		  { z t } @Yield { labelpos??ANGLE quadcase
				0	{ (SE) }
				0-90	{ (NW) }
				90	{ (NW) }
				90-180	{ (SW) }
				180	{ (SW) }
				180-270	{ (NW) }
				270	{ (SW) }
				270-360	{ (SW) }
			  }
		  else @Yield { labelpos??ANGLE quadcase
				0	{ (S) }
				0-90	{ (NW) }
				90	{ (W) }
				90-180	{ (SW) }
				180	{ (S) }
				180-270	{ (NW) }
				270	{ (W) }
				270-360	{ (SW) }
			  }
		}
	    }

	    import @Geometry
	    def @OtherInsideProximity
	    {
		which @Case {
		  { x f } @Yield { labelpos??ANGLE quadcase
				0	{ (SW) }
				0-90	{ (SE) }
				90	{ (SE) }
				90-180	{ (NE) }
				180	{ (NE) }
				180-270	{ (NW) }
				270	{ (NW) }
				270-360	{ (SW) }
			  }
		  { z t } @Yield { labelpos??ANGLE quadcase
				0	{ (SE) }
				0-90	{ (SE) }
				90	{ (NE) }
				90-180	{ (NE) }
				180	{ (NW) }
				180-270	{ (NW) }
				270	{ (SW) }
				270-360	{ (SW) }
			  }
		  else @Yield { labelpos??ANGLE quadcase
				0	{ (S) }
				0-90	{ (SE) }
				90	{ (E) }
				90-180	{ (NE) }
				180	{ (N) }
				180-270	{ (NW) }
				270	{ (W) }
				270-360	{ (SW) }
			  }
		}
	    }

	    import @Geometry
	    def @OtherOutsideProximity
	    {
		which @Case {
		  { x f } @Yield { labelpos??ANGLE quadcase
				0	{ (NW) }
				0-90	{ (NW) }
				90	{ (SW) }
				90-180	{ (SW) }
				180	{ (SE) }
				180-270	{ (SE) }
				270	{ (NE) }
				270-360	{ (NE) }
			  }
		  { z t } @Yield { labelpos??ANGLE quadcase
				0	{ (NE) }
				0-90	{ (NW) }
				90	{ (NW) }
				90-180	{ (SW) }
				180	{ (SW) }
				180-270	{ (SE) }
				270	{ (SE) }
				270-360	{ (NE) }
			  }
		  else @Yield { labelpos??ANGLE quadcase
				0	{ (N) }
				0-90	{ (NW) }
				90	{ (W) }
				90-180	{ (SW) }
				180	{ (S) }
				180-270	{ (SE) }
				270	{ (E) }
				270-360	{ (NE) }
			  }
		}
	    }


	    import @Geometry
	    def @AboveProximity
	    {
                labelangle @Case {
                    "aligned"		@Yield @AlignedAboveProximity
		    "perpendicular"	@Yield @PerpendicularAboveProximity
                    else		@Yield @OtherAboveProximity
                }
	    }

	    import @Geometry
	    def @BelowProximity
	    {
                labelangle @Case {
                    "aligned"		@Yield @AlignedBelowProximity
		    "perpendicular"	@Yield @PerpendicularBelowProximity
                    else		@Yield @OtherBelowProximity
                }
	    }

	    import @Geometry
	    def @LeftProximity
	    {
                labelangle @Case {
                    "aligned"		@Yield @AlignedLeftProximity
		    "perpendicular"	@Yield @PerpendicularLeftProximity
                    else		@Yield @OtherLeftProximity
                }
	    }

	    import @Geometry
	    def @RightProximity
	    {
                labelangle @Case {
                    "aligned"		@Yield @AlignedRightProximity
		    "perpendicular"	@Yield @PerpendicularRightProximity
                    else		@Yield @OtherRightProximity
                }
	    }

	    import @Geometry
	    def @InsideProximity
	    {
                labelangle @Case {
                    "aligned"		@Yield @AlignedInsideProximity
		    "perpendicular"	@Yield @PerpendicularInsideProximity
                    else		@Yield @OtherInsideProximity
                }
	    }

	    import @Geometry
	    def @OutsideProximity
	    {
                labelangle @Case {
                    "aligned"		@Yield @AlignedOutsideProximity
		    "perpendicular"	@Yield @PerpendicularOutsideProximity
                    else		@Yield @OtherOutsideProximity
                }
	    }

	    import @Geometry
            def proximity
            {
                labelprox @Case {
                    above   @Yield @AboveProximity
                    below   @Yield @BelowProximity
                    left    @Yield @LeftProximity
                    right   @Yield @RightProximity
                    inside  @Yield @InsideProximity
                    outside @Yield @OutsideProximity
		    else    @Yield { "("labelprox")" }
                }
            }

	    import @Geometry
	    def dorotate
		left point
		right angle
	    {
		{ {0 0} distance point } atangle { {0 0} angleto point + angle }
	    }

	    import @Geometry
	    def translation
	    {
		labelctr @Case {
		    { no No } @Yield {
			labelpos -- labeltag?!?proximity
		    }
		    { yes Yes } @Yield {
			#P0	:= labelpos
			#P1	:= labeltag?!?proximity -- P0
			#P2	:= labeltag??CTR -- P0
			#TH	:= labelpos??ANGLE
			#P1A	:= P1 dorotate { 0 - TH }
			#P2A	:= P2 dorotate { 0 - TH }
			#PRA	:= { 0 - xcoord P2A 0 - ycoord P1A }
			#PRA dorotate TH ++ P0
			XP1	:= labeltag?!?proximity
			XP2	:= labeltag??CTR
			XANG	:= labelpos??ANGLE
			XTH	:= XANG - 90d - { XP1 angleto XP2 }
			XDIST	:= { XP1 distance XP2 } * sin XTH
			labelpos -- XP1 ++ XDIST atangle XANG
		    }
		}
	    }

	    @CatchTags @ZeroSize @Transform
		translate { translation ++ labeladjust }
		rotate { finalangle }
		scale { 1 1 }
	    labeltag:: @BoxLabels @CatchTags @AddMargins
		mtop { labelmargin }
		mfoot { labelmargin }
		mleft { labelmargin }
		mright { labelmargin }
	    labelfont @Font labelbreak @Break labelformat label
	}


        def @Node
            import @Geometry named translate
#               named to precedence 10 left x right y { x y "ldiagpsub" }
                named to precedence 10 left x right y {
                  @BackEnd @Case {
                    PostScript @Yield { x y "ldiagpsub" }
                    PDF @Yield {""}
                  }
                }
            {}
            import @Geometry named rotate	{ 0d			}
	    import @Geometry named outline
		named margin {}
		named shadow {}
		named sides {}
		named angle {}
						{ outline
						    margin { margin }
						    shadow { shadow }
						    sides  { sides  }
						    angle  { angle  }
						}
	    named margin               		{ margin        	}
	    import @Geometry named shadow	{ shadow		}
	    import @Geometry named sides	{ sides			}
	    import @Geometry named angle	{ angle			}
	    named nodetag			{ nodetag		}
            named outlinestyle
		named solid   { "/ldiagsolid"   }
		named dashed  { "/ldiagdashed"  }
		named cdashed { "/ldiagcdashed" }
		named dotted  { "/ldiagdotted"  }
		named noline  { "/ldiagnoline"  }
						{ outlinestyle     	}
            import @Geometry named outlinedashlength { outlinedashlength}
            import @Geometry named outlinewidth
		named thin   { 0.04 ft }
		named medium { 0.08 ft }
		named thick  { 0.12 ft }
						{ outlinewidth     	}
            named paint				{ paint         	}
	    named font				{ font			}
	    named break				{ break			}
            named format right @Body		{ format @Body  	}
            named valign			{ valign        	}
            named vsize				{ vsize         	}
            named vindent			{ vindent       	}
	    named vstrut
		named no  { 0.0f }
		named yes { 1.0f }
						{ vstrut	 	}
            named vmargin			{ vmargin       	}
            named topmargin			{ topmargin     	}
            named footmargin			{ footmargin    	}

            named halign			{ halign        	}
            named hsize				{ hsize         	}
            named hindent			{ hindent       	}
	    named hstrut
		named no  { 0.0f }
		named yes { 1.0f }
						{ hstrut	 	}
            named hmargin			{ hmargin       	}
            named leftmargin			{ leftmargin    	}
            named rightmargin			{ rightmargin   	}

	    named nodelabel			{ nodelabel		}
	    named nodelabelmargin		{ nodelabelmargin	}
	    named nodelabelfont			{ nodelabelfont		}
	    named nodelabelbreak		{ nodelabelbreak	}
	    named nodelabelformat right @Body	{ nodelabelformat @Body	}
	    import @Geometry named nodelabelpos	{ nodelabelpos		}
	    named nodelabelprox			{ nodelabelprox		}
	    import @Geometry named nodelabelangle  { nodelabelangle	}
	    named nodelabelctr			{ nodelabelctr		}
	    import @Geometry named nodelabeladjust { nodelabeladjust	}

            named alabel			{ alabel		}
            named alabelmargin			{ alabelmargin		}
            named alabelfont			{ alabelfont		}
            named alabelbreak			{ alabelbreak		}
	    named alabelformat right @Body	{ alabelformat @Body	}
            import @Geometry named alabelpos	{ alabelpos		}
            named alabelprox			{ alabelprox		}
            import @Geometry named alabelangle	{ alabelangle		}
	    named alabelctr			{ alabelctr		}
            import @Geometry named alabeladjust	{ alabeladjust		}

            named blabel			{ blabel		}
            named blabelmargin			{ blabelmargin		}
            named blabelfont			{ blabelfont		}
            named blabelbreak			{ blabelbreak		}
	    named blabelformat right @Body	{ blabelformat @Body	}
            import @Geometry named blabelpos	{ blabelpos		}
            named blabelprox			{ blabelprox		}
            import @Geometry named blabelangle	{ blabelangle		}
	    named blabelctr			{ blabelctr		}
            import @Geometry named blabeladjust	{ blabeladjust		}

            named clabel			{ clabel		}
            named clabelmargin			{ clabelmargin		}
            named clabelfont			{ clabelfont		}
            named clabelbreak			{ clabelbreak		}
	    named clabelformat right @Body	{ clabelformat @Body	}
            import @Geometry named clabelpos	{ clabelpos		}
            named clabelprox			{ clabelprox		}
            import @Geometry named clabelangle	{ clabelangle		}
	    named clabelctr			{ clabelctr		}
            import @Geometry named clabeladjust	{ clabeladjust		}

            named dlabel			{ dlabel		}
            named dlabelmargin			{ dlabelmargin		}
            named dlabelfont			{ dlabelfont		}
            named dlabelbreak			{ dlabelbreak		}
	    named dlabelformat right @Body	{ dlabelformat @Body	}
            import @Geometry named dlabelpos	{ dlabelpos		}
            named dlabelprox			{ dlabelprox		}
            import @Geometry named dlabelangle	{ dlabelangle		}
	    named dlabelctr			{ dlabelctr		}
            import @Geometry named dlabeladjust	{ dlabeladjust		}

            right @Body
        {

            def @LabelPos
		left x
		right y
            {
		nodelabelpos @Case {
		    x    @Yield y
		    else @Yield ""
		}
            }

            def @If
		left cond
		right x
            {
		cond @Case {
		    { yes Yes } @Yield x
		    else        @Yield ""
		}
            }


            def @Strut right x
            {
		def vs { 0.5w @VShift { vstrut @High } }
		def hs {                hstrut @Wide   }

		@HContract @VContract {
		    @HContract @VContract x | vs / hs |
		}
            }

	    def @Indent right x
	    {
		x @Case {
		    { top left   } @Yield 0.0rt
		    { ctr        } @Yield 0.5rt
		    { foot right } @Yield 1.0rt
		    { mctr	     } @Yield 0.5bx
		    else           @Yield x
		}
	    }

            def @VSize right x
            {
		vsize @Case {
		    ""   @Yield x
		    else @Yield { vsize @High { /{@Indent vindent} x / } }
		}
            }

            def @HSize right x
            {
		hsize @Case {
		    ""   @Yield x
		    else @Yield { hsize @Wide { |{@Indent hindent} x | } }
		}
            }

	    def @Align right x
	    {
		x @Case {
		    { top left   } @Yield 0.0w
		    { ctr        } @Yield 0.5w
		    { foot right } @Yield 1.0w
		    { mark       } @Yield "+0i"
		    else           @Yield x
		}
	    }

	    def @ALabel
	    {
		@DoLabel
		    which	{ "a"						}
		    label	{ alabel	     @Else nodelabel		}
		    labelmargin	{ alabelmargin	     @Else nodelabelmargin	}
		    labelfont	{ alabelfont	     @Else nodelabelfont	}
		    labelbreak	{ alabelbreak	     @Else nodelabelbreak	}
		    labelformat { alabelformat @Body @Else nodelabelformat @Body}
		    labelpos	{ alabelpos	     @Else nodelabelpos		}
		    labelprox	{ alabelprox	     @Else nodelabelprox	}
		    labelangle	{ alabelangle	     @Else nodelabelangle	}
		    labelctr	{ alabelctr	     @Else nodelabelctr		}
		    labeladjust	{ alabeladjust	     @Else nodelabeladjust	}
	    }

	    def @BLabel
	    {
		@DoLabel
		    which	{ "b"						}
		    label	{ blabel	     @Else nodelabel		}
		    labelmargin	{ blabelmargin	     @Else nodelabelmargin	}
		    labelfont	{ blabelfont	     @Else nodelabelfont	}
		    labelbreak	{ blabelbreak	     @Else nodelabelbreak	}
		    labelformat { blabelformat @Body @Else nodelabelformat @Body}
		    labelpos	{ blabelpos	     @Else nodelabelpos		}
		    labelprox	{ blabelprox	     @Else nodelabelprox	}
		    labelangle	{ blabelangle	     @Else nodelabelangle	}
		    labelctr	{ blabelctr	     @Else nodelabelctr		}
		    labeladjust	{ blabeladjust	     @Else nodelabeladjust	}
	    }

	    def @CLabel
	    {
		@DoLabel
		    which	{ "c"						}
		    label	{ clabel	     @Else nodelabel		}
		    labelmargin	{ clabelmargin	     @Else nodelabelmargin	}
		    labelfont	{ clabelfont	     @Else nodelabelfont	}
		    labelbreak	{ clabelbreak	     @Else nodelabelbreak	}
		    labelformat { clabelformat @Body @Else nodelabelformat @Body}
		    labelpos	{ clabelpos	     @Else nodelabelpos		}
		    labelprox	{ clabelprox	     @Else nodelabelprox	}
		    labelangle	{ clabelangle	     @Else nodelabelangle	}
		    labelctr	{ clabelctr	     @Else nodelabelctr		}
		    labeladjust	{ clabeladjust	     @Else nodelabeladjust	}
	    }

	    def @DLabel
	    {
		@DoLabel
		    which	{ "d"						}
		    label	{ dlabel	     @Else nodelabel		}
		    labelmargin	{ dlabelmargin	     @Else nodelabelmargin	}
		    labelfont	{ dlabelfont	     @Else nodelabelfont	}
		    labelbreak	{ dlabelbreak	     @Else nodelabelbreak	}
		    labelformat { dlabelformat @Body @Else nodelabelformat @Body}
		    labelpos	{ dlabelpos	     @Else nodelabelpos		}
		    labelprox	{ dlabelprox	     @Else nodelabelprox	}
		    labelangle	{ dlabelangle	     @Else nodelabelangle	}
		    labelctr	{ dlabelctr	     @Else nodelabelctr		}
		    labeladjust	{ dlabeladjust	     @Else nodelabeladjust	}
	    }

	    import @Geometry
	    def @OutLine
	    {
	      @BackEnd @Case {
	        PostScript @Yield {
		outline @Case {
		    box		@Yield { "ldiagbox"			}
		    curvebox	@Yield { "("margin") ldiagcurvebox"	}
		    shadowbox	@Yield { shadow "ldiagshadow ldiagbox"	}
		    square	@Yield { "ldiagsquare"			}
		    diamond	@Yield { "ldiagdiamond"			}
		    polygon	@Yield { sides angle "ldiagpolygon"	}
		    isosceles	@Yield { "ldiagisosceles"		}
		    ellipse	@Yield { "ldiagellipse"			}
		    circle	@Yield { "ldiagcircle"			}
		    else	    @Yield {
				    outline
					margin { "("margin") ldiagdecodelength" }
					shadow { shadow }
					sides  { sides  }
					angle  { angle  }
		    }
		}
		  }
		  PDF @Yield {}
		}
	    }

	    def @Value
            {
              @BackEnd @Case {
                PostScript @Yield {
		@HContract @VContract
		{
		    {
			"ldiagnodebegin [" @OutLine "]"
			outlinedashlength "[" outlinestyle "]"
			outlinewidth "/ldiag"paint "ldiagnodeend"
			"(IN) ldiagpushtagdict"
			//
			"ldiagpopuptagdict"
		    }
		    @Graphic
		    {
			{@Align valign} @VShift {@Align halign} @HShift
			@AddMargins
			    mtop   { topmargin   @Else vmargin @Else margin }
			    mfoot  { footmargin  @Else vmargin @Else margin }
			    mleft  { leftmargin  @Else hmargin @Else margin }
			    mright { rightmargin @Else hmargin @Else margin }
			    @HSize @VSize @HContract @VContract
			    font @Font break @Break format @Strut @Body
		    }
		    / {alabel @Else nodelabel} @IfNonEmpty @ALabel
		    / {blabel @Else nodelabel} @IfNonEmpty @BLabel
		    / {clabel @Else nodelabel} @IfNonEmpty @CLabel
		    / {dlabel @Else nodelabel} @IfNonEmpty @DLabel
		}
                }
                PDF @Yield {}
              }
            }

	    def @TValue
	    {
		nodetag @Case {
		    ""   @Yield @Value
		    else @Yield { nodetag:: @Value }
		}
	    }

            translate @Case {
                  "" @Yield @TValue
                  else @Yield {
		    @Null & # so that preceding space gets chewed up
                    @Transform translate { translate } rotate { rotate } @TValue
                  }
            }
        }

	macro @@Node	 { @Node			  }
        macro @Box	 { @Node outline { box		} }
        macro @CurveBox	 { @Node outline { curvebox	} }
	macro @ShadowBox { @Node outline { shadowbox	} }
        macro @Square	 { @Node outline { square	} }
        macro @Diamond	 { @Node outline { diamond	} }
        macro @Polygon	 { @Node outline { polygon	} }
        macro @Isosceles { @Node outline { isosceles	} }
        macro @Ellipse	 { @Node outline { ellipse	} }
        macro @Circle	 { @Node outline { circle	} }


	macro @InsulatedNode {
	    @Node
		topmargin { 0i }
		footmargin { 0i }
		leftmargin { 0i }
		rightmargin { 0i }
		alabel {}
		blabel {}
		clabel {}
		dlabel {}
		hsize {}
		vsize {}
		vstrut { no }
		hstrut { no }
	}

	def @SolidArrowHead
	    named width { arrowwidth }
	    named length { arrowlength }
	    named pathwidth { pathwidth }
	{
	    @InsulatedNode
		paint { nochange }
		outlinestyle { noline }
		outlinewidth { pathwidth }
		outline {
		  @BackEnd @Case {
		    PostScript @Yield {
		    "ldiagsolidarrowhead"
		    # 0 0 xsize ysize * 0.5 0 ysize
		    }
		    PDF @Yield {}
		  }
		}
	    {
		length @Wide width @High
	    }
	}

	def @OpenArrowHead
	    named width { arrowwidth }
	    named length { arrowlength }
	    named pathwidth { pathwidth }
	{
	    @InsulatedNode
		outlinewidth { pathwidth }
		outlinestyle { noline }
		paint { nochange }
		outline {
		  @BackEnd @Case {
		    PostScript @Yield {
		    pathwidth "ldiagopenarrowhead"

		    # PSW := { 0 0 }
		    # PNW := { 0 ysize }
		    # PE  := { xsize ysize*0.5 }
		    # REL := pathwidth atangle { PE angleto PNW + 90d }
		    # PNA := { 0 ysize*0.5 + pathwidth*0.5 }
		    # PSA := { 0 ysize*0.5 - pathwidth*0.5 }
		    # PNI := {
		    #   PNA PNA ++ { xsize 0 }
		    #   PNW ++ REL PE ++ REL ldiaglineintersect
		    # }
		    # PSI := PNI -- { 0 pathwidth }
		    #
		    # PSW PE PNW PNI PNA PSA PSI PSW
		    }
		    PDF @Yield {}
		  }
		}
	    {
		length @Wide width @High
	    }
	}

	def @HalfOpenArrowHead
	    named width { arrowwidth }
	    named length { arrowlength }
	    named pathwidth { pathwidth }
	{
	    @InsulatedNode
		paint { nochange }
		outlinestyle { noline }
		outlinewidth { pathwidth }
		outline {
		  @BackEnd @Case {
		    PostScript @Yield {
		    pathwidth "ldiaghalfopenarrowhead"

		    # 0 0
		    # xsize ysize * 0.5
		    # 0 ysize
		    # xsize*0.3 ysize*0.5 + pathwidth*0.5
		    # 0         ysize*0.5 + pathwidth*0.5
		    # 0         ysize*0.5 - pathwidth*0.5
		    # xsize*0.3 ysize*0.5 - pathwidth*0.5
		    # 0 0
		    }
		    PDF @Yield {}
		  }
		}
	    {
		length @Wide width @High
	    }
	}

	def @SolidCurvedArrowHead
	    named width { arrowwidth }
	    named length { arrowlength }
	    named pathwidth { pathwidth }
	{
	    @InsulatedNode
		outlinestyle { noline }
		paint { nochange }
		outlinewidth { pathwidth }
		outline {
		  @BackEnd @Case {
		    PostScript @Yield {
		    "ldiagsolidcurvedarrowhead"
		    # 0 0
		    # [0 0 xsize ysize * 0.5 "ldiaglinebetween"
		    #  xsize 0 xsize ysize "ldiaglineintersect" clockwise]
		    # xsize ysize * 0.5
		    # [xsize ysize * 0.5 0 ysize "ldiaglinebetween"
		    #  xsize 0 xsize ysize "ldiaglineintersect" clockwise]
		    # 0 ysize
		    }
		    PDF @Yield {}
		  }
		}
	    {
		length @Wide width @High
	    }
	}

	def @OpenCurvedArrowHead
	    named width { arrowwidth }
	    named length { arrowlength }
	    named pathwidth { pathwidth }
	{
	    @InsulatedNode
		outlinestyle { noline }
		paint { nochange }
		outlinewidth { pathwidth }
		outline {
		  @BackEnd @Case {
		    PostScript @Yield {
		    pathwidth "ldiagopencurvedarrowhead"
		    # LR:= { 0 0 xsize ysize * 0.5 "ldiaglinebetween"
		    #    xsize 0 xsize ysize "ldiaglineintersect" }
		    # UR:= { xsize ysize * 0.5 0 ysize "ldiaglinebetween"
		    #      xsize 0 xsize ysize "ldiaglineintersect" }
		    # PW2  := pathwidth * 0.5
		    # UMID := {
		    # 0 ysize * 0.5 + PW2  xsize ysize * 0.5 + PW2
		    # {0 ysize} ++ 1f atangle { UR angleto {0 ysize} + 90d }
		    # { 0 ysize } ldiaglineintersect
		    # }
		    # LMID := UMID -- { 0 pathwidth }
		    # 0 0
		    # [LR clockwise]
		    # xsize ysize * 0.5
		    # [UR clockwise]
		    # 0 ysize
		    # UMID
		    # 0 ysize * 0.5 + PW2
		    # 0 ysize * 0.5 - PW2
		    # LMID
		    # 0 0
		    }
		    PDF @Yield {}
		  }
		}
	    {
		length @Wide width @High
	    }
	}

	def @HalfOpenCurvedArrowHead
	    named width { arrowwidth }
	    named length { arrowlength }
	    named pathwidth { pathwidth }
	{
	    @InsulatedNode
		outlinestyle { noline }
		paint { nochange }
		outlinewidth { pathwidth }
		outline {
		  @BackEnd @Case {
		    PostScript @Yield {
		    pathwidth "ldiaghalfopencurvedarrowhead"
		    # LR:= { 0 0 xsize ysize * 0.5 "ldiaglinebetween"
		    #      xsize 0 xsize ysize "ldiaglineintersect" }
		    # UR:= { xsize ysize * 0.5 0 ysize "ldiaglinebetween"
		    #      xsize 0 xsize ysize "ldiaglineintersect" }
		    # BR:= { 0 0 LR 0 ysize UR "ldiaglineintersect" }
		    # BRAD := { 0 0 } distance BR
		    # PW2  := pathwidth * 0.5
		    # XDIST := sqrt { BRAD*BRAD - PW2*PW2 }
		    # UMID := BR ++ { XDIST PW2 }
		    # LMID := BR ++ { XDIST 0 - PW2 }
		    # 0 0
		    # [LR clockwise]
		    # xsize ysize * 0.5
		    # [UR clockwise]
		    # 0 ysize
		    # [BR clockwise ]
		    # UMID
		    # 0 ysize * 0.5 + PW2
		    # 0 ysize * 0.5 - PW2
		    # LMID
		    # [BR clockwise ]
		    # 0 0
		    }
		    PDF @Yield {}
		  }
		}
	    {
		length @Wide width @High
	    }
	}

	def @CircleArrowHead
	    named width { arrowwidth }
	    named length { arrowlength }
	    named pathwidth { pathwidth }
	{
	    @InsulatedNode
		outlinestyle { noline }
		paint { nochange }
		outlinewidth { pathwidth }
		outline { circle }
	    { length @Wide length @High }
	}

	def @BoxArrowHead
	    named width { arrowwidth }
	    named length { arrowlength }
	    named pathwidth { pathwidth }
	{
	    @InsulatedNode
		outlinestyle { noline }
		paint { nochange }
		outlinewidth { pathwidth }
		outline { box }
	    { length @Wide width @High }
	}

	def @ArrowHead
	    named style { arrowstyle }
	    named width { arrowwidth }
	    named length { arrowlength }
	    named pathwidth { pathwidth }
	{
	    style @Case {
		solid          @Yield @SolidArrowHead
				  width { width } length { length }
				  pathwidth { pathwidth }
		halfopen       @Yield @HalfOpenArrowHead
				  width { width } length { length }
				  pathwidth { pathwidth }
		open           @Yield @OpenArrowHead
				  width { width } length { length }
				  pathwidth { pathwidth }
		curvedsolid    @Yield @SolidCurvedArrowHead
				  width { width } length { length }
				  pathwidth { pathwidth }
		curvedhalfopen @Yield @HalfOpenCurvedArrowHead
				  width { width } length { length }
				  pathwidth { pathwidth }
		curvedopen     @Yield @OpenCurvedArrowHead
				  width { width } length { length }
				  pathwidth { pathwidth }
		circle         @Yield @CircleArrowHead
				  width { width } length { length }
				  pathwidth { pathwidth }
		box            @Yield @BoxArrowHead
				  width { width } length { length }
				  pathwidth { pathwidth }
	    }
	}

        def @Link
            import @Geometry named path
                named from {}
                named to {}
                named bias {}
                named fbias {}
                named tbias {}
                named radius {}
                named xindent {}
                named zindent {}
                named frompt {}
                named topt {}
                named arrow {}
                named arrowlength {}
            					{ path
						    from { from }
						    to { to }
						    bias { bias }
						    fbias { fbias }
						    tbias { tbias }
						    radius { radius }
						    xindent { xindent }
						    zindent { zindent }
						    frompt { frompt }
						    topt { topt }
						    arrow { arrow }
						    arrowlength { arrowlength }
						}
            import @Geometry named from		{ from			}
            import @Geometry named to		{ to			}
            import @Geometry named bias		{ bias			}
            import @Geometry named fbias	{ fbias			}
            import @Geometry named tbias	{ tbias			}
            import @Geometry named radius	{ radius		}
            import @Geometry named xindent	{ xindent		}
            import @Geometry named zindent	{ zindent		}
            import @Geometry named frompt	{ frompt		}
            import @Geometry named topt		{ topt		}
            named pathstyle
		named solid   { "/ldiagsolid"   }
		named dashed  { "/ldiagdashed"  }
		named cdashed { "/ldiagcdashed" }
		named dotted  { "/ldiagdotted"  }
		named noline  { "/ldiagnoline"  }
						{ pathstyle		}
            import @Geometry named pathdashlength { pathdashlength	}
            import @Geometry named pathwidth
		named thin   { 0.04 ft }
		named medium { 0.08 ft }
		named thick  { 0.12 ft }
						{ pathwidth		}

            named arrow				{ arrow			}
            named arrowstyle			{ arrowstyle		}
            named arrowwidth			{ arrowwidth		}
            named arrowlength			{ arrowlength		}

	    named linklabel			{ linklabel		}
	    named linklabelmargin		{ linklabelmargin	}
	    named linklabelfont			{ linklabelfont		}
	    named linklabelbreak		{ linklabelbreak	}
	    named linklabelformat right @Body	{ linklabelformat @Body	}
	    import @Geometry named linklabelpos	{ linklabelpos		}
	    named linklabelprox			{ linklabelprox		}
	    import @Geometry named linklabelangle  { linklabelangle	}
	    named linklabelctr			{ linklabelctr		}
	    import @Geometry named linklabeladjust { linklabeladjust	}

            named xlabel			{ xlabel		}
            named xlabelmargin	        	{ xlabelmargin		}
            named xlabelfont			{ xlabelfont		}
            named xlabelbreak			{ xlabelbreak		}
	    named xlabelformat right @Body	{ xlabelformat @Body	}
            import @Geometry named xlabelpos	{ xlabelpos		}
            named xlabelprox			{ xlabelprox		}
            import @Geometry named xlabelangle	{ xlabelangle		}
	    named xlabelctr			{ xlabelctr		}
            import @Geometry named xlabeladjust	{ xlabeladjust		}

            named ylabel			{ ylabel		}
            named ylabelmargin			{ ylabelmargin		}
            named ylabelfont			{ ylabelfont		}
            named ylabelbreak			{ ylabelbreak		}
	    named ylabelformat right @Body	{ ylabelformat @Body	}
            import @Geometry named ylabelpos	{ ylabelpos		}
            named ylabelprox			{ ylabelprox		}
            import @Geometry named ylabelangle	{ ylabelangle		}
	    named ylabelctr			{ ylabelctr		}
            import @Geometry named ylabeladjust	{ ylabeladjust		}

            named zlabel			{ zlabel		}
            named zlabelmargin			{ zlabelmargin		}
            named zlabelfont			{ zlabelfont		}
            named zlabelbreak			{ zlabelbreak		}
	    named zlabelformat right @Body	{ zlabelformat @Body	}
            import @Geometry named zlabelpos	{ zlabelpos		}
            named zlabelprox			{ zlabelprox		}
            import @Geometry named zlabelangle	{ zlabelangle		}
	    named zlabelctr			{ zlabelctr		}
            import @Geometry named zlabeladjust	{ zlabeladjust		}

            named fromlabel			{ fromlabel		}
            named fromlabelmargin		{ fromlabelmargin	}
            named fromlabelfont			{ fromlabelfont		}
            named fromlabelbreak		{ fromlabelbreak	}
	    named fromlabelformat right @Body	{ fromlabelformat @Body	}
            import @Geometry named fromlabelpos	{ fromlabelpos		}
            named fromlabelprox			{ fromlabelprox		}
            import @Geometry named fromlabelangle  { fromlabelangle	}
	    named fromlabelctr			{ fromlabelctr		}
            import @Geometry named fromlabeladjust { fromlabeladjust	}

            named tolabel			{ tolabel		}
            named tolabelmargin			{ tolabelmargin		}
            named tolabelfont			{ tolabelfont		}
            named tolabelbreak			{ tolabelbreak		}
	    named tolabelformat right @Body	{ tolabelformat @Body	}
            import @Geometry named tolabelpos	{ tolabelpos		}
            named tolabelprox			{ tolabelprox		}
            import @Geometry named tolabelangle	{ tolabelangle		}
	    named tolabelctr			{ tolabelctr		}
            import @Geometry named tolabeladjust{ tolabeladjust		}

        {
	    def @XLabel
	    {
		@DoLabel
		    which	{ "x"						}
		    label	{ xlabel	     @Else linklabel		}
		    labelmargin	{ xlabelmargin	     @Else linklabelmargin	}
		    labelfont	{ xlabelfont	     @Else linklabelfont	}
		    labelbreak	{ xlabelbreak	     @Else linklabelbreak	}
		    labelformat { xlabelformat @Body @Else linklabelformat @Body}
		    labelpos	{ xlabelpos	     @Else linklabelpos		}
		    labelprox	{ xlabelprox	     @Else linklabelprox	}
		    labelangle	{ xlabelangle	     @Else linklabelangle	}
		    labelctr	{ xlabelctr	     @Else linklabelctr		}
		    labeladjust	{ xlabeladjust	     @Else linklabeladjust	}
	    }

	    def @YLabel
	    {
		@DoLabel
		    which	{ "y"						}
		    label	{ ylabel	     @Else linklabel		}
		    labelmargin	{ ylabelmargin	     @Else linklabelmargin	}
		    labelfont	{ ylabelfont	     @Else linklabelfont	}
		    labelbreak	{ ylabelbreak	     @Else linklabelbreak	}
		    labelformat { ylabelformat @Body @Else linklabelformat @Body}
		    labelpos	{ ylabelpos	     @Else linklabelpos		}
		    labelprox	{ ylabelprox	     @Else linklabelprox	}
		    labelangle	{ ylabelangle	     @Else linklabelangle	}
		    labelctr	{ ylabelctr	     @Else linklabelctr		}
		    labeladjust	{ ylabeladjust	     @Else linklabeladjust	}
	    }

	    def @ZLabel
	    {
		@DoLabel
		    which	{ "z"						}
		    label	{ zlabel	     @Else linklabel		}
		    labelmargin	{ zlabelmargin	     @Else linklabelmargin	}
		    labelfont	{ zlabelfont	     @Else linklabelfont	}
		    labelbreak	{ zlabelbreak	     @Else linklabelbreak	}
		    labelformat { zlabelformat @Body @Else linklabelformat @Body}
		    labelpos	{ zlabelpos	     @Else linklabelpos		}
		    labelprox	{ zlabelprox	     @Else linklabelprox	}
		    labelangle	{ zlabelangle	     @Else linklabelangle	}
		    labelctr	{ zlabelctr	     @Else linklabelctr		}
		    labeladjust	{ zlabeladjust	     @Else linklabeladjust	}
	    }

	    def @FromArrow
	    {
		arrow @Case {
		    { back both } @Yield {
			@ArrowHead
			    style { arrowstyle }
			    width { arrowwidth }
			    length { arrowlength }
			    pathwidth { pathwidth }
		    }
		    else @Yield ""
		}
	    }

	    def @ToArrow
	    {
		arrow @Case {
		    { yes forward both } @Yield {
			@ArrowHead
			    style { arrowstyle }
			    width { arrowwidth }
			    length { arrowlength }
			    pathwidth { pathwidth }
		    }
		    else @Yield ""
		}
	    }

	    import @Geometry
	    def @LinePath
	    {
		@BackEnd @Case {
		  PostScript @Yield {
	       {arrow @FromArrowLength arrowlength}
	       {arrow @ToArrowLength arrowlength}
	       "{" from "}" "{" to "}"
	       xindent zindent "ldiaglinepath"
               # FROM	:< {from??CTR angleto to??CTR}
               # FROM	:: from boundaryatangle FROM@ANGLE
               # 	++ {arrow @FromArrowLength arrowlength}atangle FROM@ANGLE
               # TO  	:< FROM@ANGLE
               # TO  	:: to boundaryatangle { TO@ANGLE - 180d }
               # ++ {arrow @ToArrowLength arrowlength} atangle {TO@ANGLE - 180d}
               # 		
               # LMID	:: FROM ** 0.5 ++ TO ** 0.5
               # LMID	:< FROM@ANGLE
               # XINDENT	:= xindent min { FROM distance LMID }
               # LFROM	:: FROM ++ XINDENT atangle FROM@ANGLE
               # LFROM	:< FROM@ANGLE
               # ZINDENT	:= zindent min { TO distance LMID }
               # LTO 	:: TO -- ZINDENT atangle FROM@ANGLE
               # LTO 	:< FROM@ANGLE
	       #
               # if cond { direct }
               # then { FROM TO }
               # else { FROM LFROM LMID LTO TO }
		  }
		  PDF @Yield {}
		}
	    }

	    import @Geometry
	    def @ACurvePath
	    {
		@BackEnd @Case {
		  PostScript @Yield {
	       {arrow @FromArrowLength arrowlength}
	       {arrow @ToArrowLength arrowlength}
	       "{" from "}" "{" to "}"
	       xindent zindent bias "ldiagacurvepath"
               #  #B1	:= bias max 0.02f
               #  #B2	:= { from??CTR distance to??CTR } * 0.5
               #  #BIAS    := B1 min B2
	       #  BIAS  := bias max 0.02f
               #  XMID	:= from??CTR ** 0.5 ++ to??CTR ** 0.5
               #  XTOP	:= XMID ++ BIAS atangle {from??CTR angleto to??CTR - 90d}
               #  CTR  	:= { from??CTR XTOP ldiaglinebetween
               #  	     to??CTR   XTOP ldiaglinebetween ldiaglineintersect }
               #  FROM	:: aabout
               #  		circum { from }
               #  		extra  { arrow @FromArrowLength arrowlength }
               #  		centre { CTR }
	       #  FROM 	:< if cond { from??CTR distance FROM > 0 }
               #  	      then { from??CTR angleto FROM }
	       #  	      else { CTR angleto FROM + 90d }
               #  TO	:: cabout
               #  		circum { to }
               #  		extra  { arrow @ToArrowLength arrowlength }
               #  		centre { CTR }
               #  TO   	:< if cond { TO distance to??CTR > 0 }
               #  	      then { TO angleto to??CTR }
               #  	      else { CTR angleto TO + 90d }
               # 
               #  RADIUS	:= CTR distance FROM
               #  LMID 	:: CTR ++ RADIUS atangle {
               #   CTR angleto FROM +
	       #   { {360d + {CTR angleto TO} - {CTR angleto FROM}} mod 360 } / 2
	       #   }
               #  LMID 	:< CTR angleto LMID  + 90d
               #
               #  XINDENT	:= xindent min { FROM distance LMID }
               #  LFROM	:: CTR ++ RADIUS atangle {
               #  	   CTR angleto { FROM ++ XINDENT atangle FROM@ANGLE } }
               #  LFROM	:< CTR angleto LFROM + 90d
               #  ZINDENT	:= zindent min { TO distance LMID }
               #  LTO  	:: CTR ++ RADIUS atangle {
               #  	   CTR angleto { TO ++ ZINDENT atangle {TO@ANGLE+180d}}}
               #  LTO  	:< CTR angleto LTO   + 90d
               #
               #  if cond { direct }
	       #  then { FROM [CTR] TO }
               #  else { FROM [CTR] LFROM [CTR] LMID [CTR] LTO [CTR] TO }
		  }
		  PDF @Yield {}
		}
	    }

	    import @Geometry
	    def @CCurvePath
	    {
		@BackEnd @Case {
		  PostScript @Yield {
	       {arrow @FromArrowLength arrowlength}
	       {arrow @ToArrowLength arrowlength}
	       "{" from "}" "{" to "}"
	       xindent zindent bias "ldiagccurvepath"
              #  #B1     := bias max 0.02f
              #  #B2     := { from??CTR distance to??CTR } * 0.5
              #  #BIAS   := B1 min B2
              #  BIAS   := bias max 0.02f
              #  XMID   := from??CTR ** 0.5 ++ to??CTR ** 0.5
              #  XTOP   := XMID ++ BIAS atangle {from??CTR angleto to??CTR + 90d}
              #  CTR    := { from??CTR XTOP ldiaglinebetween
              #              to??CTR   XTOP ldiaglinebetween ldiaglineintersect }
              #  FROM   :: cabout
              #                  circum { from }
              #                  extra  { arrow @FromArrowLength arrowlength }
              #                  centre { CTR }
              #  FROM   :< if cond { from??CTR distance FROM > 0 }
              #               then { from??CTR angleto FROM }
              #               else { CTR angleto FROM - 90d }
              #  TO     :: aabout
              #                 circum { to }
              #                 extra  { arrow @ToArrowLength arrowlength }
              #                 centre { CTR }
              #  TO     :< if cond { TO distance to??CTR > 0 }
              #               then { TO angleto to??CTR }
              #               else { CTR angleto TO - 90d }
              #
              #  RADIUS  := CTR distance FROM
              #  LMID    :: CTR ++ RADIUS atangle {
              #   CTR angleto TO +
              #   { {360d + {CTR angleto FROM} - {CTR angleto TO} } mod 360 } / 2
              #   }
              #  LMID    :< CTR angleto LMID  - 90d
              #
              #  XINDENT := xindent min { FROM distance LMID }
              #  LFROM   :: CTR ++ RADIUS atangle {
              #             CTR angleto { FROM ++ XINDENT atangle FROM@ANGLE } }
              #  LFROM   :< CTR angleto LFROM - 90d
              #  ZINDENT := zindent min { TO distance LMID }
              #  LTO     :: CTR ++ RADIUS atangle {
              #             CTR angleto { TO ++ ZINDENT atangle {TO@ANGLE+180d}}}
              #  LTO     :< CTR angleto LTO   - 90d
              #
              #  if cond { direct }
              #  then { FROM [CTR clockwise] TO }
              #  else { FROM [CTR clockwise] LFROM [CTR clockwise]
              #         LMID [CTR clockwise] LTO   [CTR clockwise] TO }
		  }
		  PDF @Yield {}
		}
          }

	    import @Geometry
	    def @BezierPath
	    {
		@BackEnd @Case {
		  PostScript @Yield {
	       {arrow @FromArrowLength arrowlength}
	       {arrow @ToArrowLength arrowlength}
	       "{" from "}" "{" to "}"
	       xindent zindent [ frompt ] [ topt ] "ldiagbezierpath"
              # FROM      :< from??CTR angleto frompt
              # FROM      :: from boundaryatangle FROM@ANGLE
              # ++ {arrow @FromArrowLength arrowlength} atangle FROM@ANGLE
              # TO        :< topt angleto to??CTR
              # TO        :: to boundaryatangle { TO@ANGLE + 180d }
              # ++ {arrow @ToArrowLength arrowlength} atangle { TO@ANGLE + 180d }
              # LFROM     :: FROM ++ { xindent atangle FROM@ANGLE }
              # LFROM     :< FROM@ANGLE
              # LTO       :: TO ++ zindent atangle { TO@ANGLE + 180d }
              # LTO       :< TO@ANGLE
              # LMID       :: { FROM ++ TO ++ frompt ++ topt } ** 0.25
              # FROM [frompt topt] TO
		  }
		  PDF @Yield {}
		}
	    }

	    import @Geometry
	    def @VHLinePath
	    {
		@BackEnd @Case {
		  PostScript @Yield {
	      {arrow @FromArrowLength arrowlength}
	      {arrow @ToArrowLength arrowlength}
	      "{" from "}" "{" to "}"
	      xindent zindent "ldiagvhlinepath"
              # CTR     := { {xcoord from??CTR} {ycoord to??CTR} }
              # FANG    := from??CTR angleto CTR
              # TANG    := to??CTR angleto CTR
              # FROM    :: from boundaryatangle FANG
              # ++ {arrow @FromArrowLength arrowlength} atangle FANG
              # FROM    :< FANG
              # TO      :: to boundaryatangle TANG
              # ++ {arrow @ToArrowLength arrowlength} atangle TANG
              # TO      :< TANG + 180d
              # FDIST   := FROM distance CTR
              # TDIST   := TO distance CTR
              # XINDENT := xindent min FDIST
              # ZINDENT := zindent min TDIST
              # LFROM   :: FROM ++ XINDENT atangle FANG
              # LFROM   :< FROM@ANGLE
              # LTO     :: TO ++ ZINDENT atangle TANG
              # LTO     :< TO@ANGLE
              # LMID    :: CTR 
              # LMID    :< {1f atangle {FANG + 180d}} angleto
              #            {1f atangle {TANG + 180d}}
              # FROM LFROM LMID LTO TO
		  }
		  PDF @Yield {}
		}
	    }

	    import @Geometry
	    def @VHCurvePath
	    {
		@BackEnd @Case {
		  PostScript @Yield {
	      {arrow @FromArrowLength arrowlength}
	      {arrow @ToArrowLength arrowlength}
	      "{" from "}" "{" to "}"
	      xindent zindent radius "ldiagvhcurvepath"
              # CTR     := { {xcoord from??CTR} {ycoord to??CTR} }
              # FANG    := from??CTR angleto CTR
              # TANG    := to??CTR angleto CTR
              # FROM    :: from boundaryatangle FANG
              # ++ {arrow @FromArrowLength arrowlength} atangle FANG
              # FROM    :< FANG
              # TO      :: to boundaryatangle TANG
              # ++ {arrow @ToArrowLength arrowlength} atangle TANG
              # TO      :< TANG + 180d
              # FDIST   := FROM distance CTR
              # TDIST   := TO distance CTR
              # RADIUS  := radius min FDIST min TDIST 
              # XINDENT := xindent min { FDIST - RADIUS }
              # ZINDENT := zindent min { TDIST - RADIUS }
              # LFROM   :: FROM ++ XINDENT atangle FANG
              # LFROM   :< FROM@ANGLE
              # LTO     :: TO ++ ZINDENT atangle TANG
              # LTO     :< TO@ANGLE
              # FCTR    := CTR ++ RADIUS atangle { FROM@ANGLE + 180d }
              # TCTR    := CTR ++ RADIUS atangle { TO@ANGLE          }
              # XCTR    := CTR ++ RADIUS atangle { FROM@ANGLE + 180d }
              #                ++ RADIUS atangle { TO@ANGLE }
              # LMID    :: XCTR ++ RADIUS atangle { XCTR angleto CTR }
              # LMID    :< FCTR angleto TCTR
              # FROM LFROM FCTR
              #     { FCTR angleto TCTR } quadcase
              #       0        {   }
              #       0-90     { [XCTR clockwise] }
              #       90       {   }
              #       90-180   { [XCTR] }
              #       180      {   }
              #       180-270  { [XCTR clockwise] }
              #       270      {   }
              #       270-360  { [XCTR] }
              # TCTR LTO TO
		  }
		  PDF @Yield {}
		}
	    }

	    import @Geometry
	    def @HVLinePath
	    {
		@BackEnd @Case {
		  PostScript @Yield {
	      {arrow @FromArrowLength arrowlength}
	      {arrow @ToArrowLength arrowlength}
	      "{" from "}" "{" to "}"
	      xindent zindent "ldiaghvlinepath"
              # CTR     := { {xcoord to??CTR} {ycoord from??CTR} }
              # FANG    := from??CTR angleto CTR
              # TANG    := to??CTR angleto CTR
              # FROM    :: from boundaryatangle FANG
              # ++ {arrow @FromArrowLength arrowlength} atangle FANG
              # FROM    :< FANG
              # TO      :: to boundaryatangle TANG
              # ++ {arrow @ToArrowLength arrowlength} atangle TANG
              # TO      :< TANG + 180d
              # FDIST   := FROM distance CTR
              # TDIST   := TO distance CTR
              # XINDENT := xindent min FDIST
              # ZINDENT := zindent min TDIST
              # LFROM   :: FROM ++ XINDENT atangle FANG
              # LFROM   :< FROM@ANGLE
              # LTO     :: TO ++ ZINDENT atangle TANG
              # LTO     :< TO@ANGLE
              # LMID    :: CTR 
              # LMID    :< {1f atangle {FANG + 180d}} angleto
              #            {1f atangle {TANG + 180d}}
              # FROM LFROM LMID LTO TO
		  }
		  PDF @Yield {}
		}
	    }

	    import @Geometry
	    def @HVCurvePath
	    {
		@BackEnd @Case {
		  PostScript @Yield {
	      {arrow @FromArrowLength arrowlength}
	      {arrow @ToArrowLength arrowlength}
	      "{" from "}" "{" to "}"
	      xindent zindent radius "ldiaghvcurvepath"
              # CTR     := { {xcoord to??CTR} {ycoord from??CTR} }
              # FANG    := from??CTR angleto CTR
              # TANG    := to??CTR angleto CTR
              # FROM    :: from boundaryatangle FANG
              # ++ {arrow @FromArrowLength arrowlength} atangle FANG
              # FROM    :< FANG
              # TO      :: to boundaryatangle TANG
              # ++ {arrow @ToArrowLength arrowlength} atangle TANG
              # TO      :< TANG + 180d
              # FDIST   := FROM distance CTR
              # TDIST   := TO distance CTR
              # RADIUS  := radius min FDIST min TDIST 
              # XINDENT := xindent min { FDIST - RADIUS }
              # ZINDENT := zindent min { TDIST - RADIUS }
              # LFROM   :: FROM ++ XINDENT atangle FANG
              # LFROM   :< FROM@ANGLE
              # LTO     :: TO ++ ZINDENT atangle TANG
              # LTO     :< TO@ANGLE
              # FCTR    := CTR ++ RADIUS atangle { FROM@ANGLE + 180d }
              # TCTR    := CTR ++ RADIUS atangle { TO@ANGLE          }
              # XCTR    := CTR ++ RADIUS atangle { FROM@ANGLE + 180d }
              #                ++ RADIUS atangle { TO@ANGLE }
              # LMID    :: XCTR ++ RADIUS atangle { XCTR angleto CTR }
              # LMID    :< FCTR angleto TCTR
              # FROM LFROM FCTR
              #     { FCTR angleto TCTR } quadcase
              #       0        {   }
              #       0-90     { [XCTR] }
              #       90       {   }
              #       90-180   { [XCTR clockwise] }
              #       180      {   }
              #       180-270  { [XCTR] }
              #       270      {   }
              #       270-360  { [XCTR clockwise] }
              # TCTR LTO TO
		  }
		  PDF @Yield {}
		}
	    }

	    import @Geometry
	    def @LVRLinePath
	    {
		@BackEnd @Case {
		  PostScript @Yield {
	      {arrow @FromArrowLength arrowlength}
	      {arrow @ToArrowLength arrowlength}
	      "{" from "}" "{" to "}"
	      xindent zindent bias "ldiaglvrlinepath"
              # FROM    :: from boundaryatangle 180d
              # ++ {arrow @FromArrowLength arrowlength} atangle 180d
              # FROM    :< 180d
              # TO      :: to boundaryatangle 180d
              # ++ {arrow @ToArrowLength arrowlength} atangle 180d
              # TO      :< 0d
              # XLEFT   := {{xcoord FROM} min {xcoord TO}} - bias
              # P1      :: { XLEFT ycoord FROM }
              # P2      :: { XLEFT ycoord TO   }
              # VERT    := P1 angleto P2
              # P1      :< P1 angleto {P1++{1f atangle 180d}++{1f atangle VERT}}
              # P2      :< P2 angleto {P2++{1f atangle 0d}  ++{1f atangle VERT}}
              # LMID    :: P1 ** 0.5 ++ P2 ** 0.5
              # LMID    :< VERT
              # XINDENT := xindent min {FROM distance P1}
              # ZINDENT := zindent min {P2   distance TO}
              # LFROM   :: FROM -- { XINDENT 0 }
              # LFROM   :< 180d
              # LTO     :: TO -- { ZINDENT 0 }
              # LTO     :< 0d
              # FROM LFROM P1 LMID P2 LTO TO
		  }
		  PDF @Yield {}
		}
	    }

	    import @Geometry
	    def @LVRCurvePath
	    {
		@BackEnd @Case {
		  PostScript @Yield {
	      {arrow @FromArrowLength arrowlength}
	      {arrow @ToArrowLength arrowlength}
	      "{" from "}" "{" to "}"
	      xindent zindent bias radius "ldiaglvrcurvepath"
              # FROM    :: from boundaryatangle 180d
              # ++ {arrow @FromArrowLength arrowlength} atangle 180d
              # FROM    :< 180d
              # TO      :: to boundaryatangle 180d
              # ++ {arrow @ToArrowLength arrowlength} atangle 180d
              # TO      :< 0d
              # XLEFT   := {{xcoord FROM} min {xcoord TO}} - bias
              # XP1     := { XLEFT ycoord FROM }
              # XP2     := { XLEFT ycoord TO   }
              # VERT    := XP1 angleto XP2
              # LMID    :: XP1 ** 0.5 ++ XP2 ** 0.5
              # LMID    :< VERT
              # XINDENT := xindent min {FROM distance XP1}
              # ZINDENT := zindent min {XP2   distance TO}
              # LFROM   :: FROM -- { XINDENT 0 }
              # LFROM   :< 180d
              # LTO     :: TO -- { ZINDENT 0 }
              # LTO     :< 0d
              # RADIUS  := radius min { { XP1 distance XP2 } / 2 }
              # XP1PRE  := XP1 ++ { RADIUS atangle 0d }
              # XP1POST := XP1 ++ { RADIUS atangle VERT }
              # XP1CTR  := XP1PRE ++ { RADIUS atangle VERT }
              # P1      :: XP1CTR ++ { RADIUS atangle { XP1CTR angleto XP1 } }
              # P1      :< XP1PRE angleto XP1POST
              # XP2PRE  := XP2 -- { RADIUS atangle VERT }
              # XP2POST := XP2 ++ { RADIUS atangle 0d }
              # XP2CTR  := XP2PRE ++ { RADIUS atangle 0d }
              # P2      :: XP2CTR ++ { RADIUS atangle { XP2CTR angleto XP2 } }
              # P2      :< XP2PRE angleto XP2POST
              # FROM LFROM XP1PRE
              #   {round VERT} quadcase
              #     90 { [XP1CTR clockwise] P1 [XP1CTR clockwise] }
              #     270 { [XP1CTR] P1 [XP1CTR] }
              # XP1POST LMID XP2PRE
              #   {round VERT} quadcase
              #     90 { [XP2CTR clockwise] P2 [XP2CTR clockwise] }
              #     270 { [XP2CTR] P2 [XP2CTR] }
              # XP2POST LTO TO
		  }
		  PDF @Yield {}
		}
	    }

	    import @Geometry
	    def @RVLLinePath
	    {
		@BackEnd @Case {
		  PostScript @Yield {
	      {arrow @FromArrowLength arrowlength}
	      {arrow @ToArrowLength arrowlength}
	      "{" from "}" "{" to "}"
	      xindent zindent bias "ldiagrvllinepath"
              # FROM    :: from boundaryatangle 0d
              # ++ {arrow @FromArrowLength arrowlength} atangle 0d
              # FROM    :< 0d
              # TO      :: to boundaryatangle 0d
              # ++ {arrow @ToArrowLength arrowlength} atangle 0d
              # TO      :< 180d
              # XRIGHT  := {{xcoord FROM} max {xcoord TO}} + bias
              # P1      :: { XRIGHT ycoord FROM }
              # P2      :: { XRIGHT ycoord TO   }
              # VERT    := P1 angleto P2
              # P1      :< P1 angleto {P1++{1f atangle 0d}  ++{1f atangle VERT}}
              # P2      :< P2 angleto {P2++{1f atangle 180d}++{1f atangle VERT}}
              # LMID    :: P1 ** 0.5 ++ P2 ** 0.5
              # LMID    :< VERT
              # XINDENT := xindent min {FROM distance P1}
              # ZINDENT := zindent min {P2   distance TO}
              # LFROM   :: FROM ++ { XINDENT 0 }
              # LFROM   :< 0d
              # LTO     :: TO ++ { ZINDENT 0 }
              # LTO     :< 180d
              # FROM LFROM P1 LMID P2 LTO TO
		  }
		  PDF @Yield {}
		}
	    }

	    import @Geometry
	    def @RVLCurvePath
	    {
		@BackEnd @Case {
		  PostScript @Yield {
	      {arrow @FromArrowLength arrowlength}
	      {arrow @ToArrowLength arrowlength}
	      "{" from "}" "{" to "}"
	      xindent zindent bias radius "ldiagrvlcurvepath"
              # FROM    :: from boundaryatangle 0d
              # ++ {arrow @FromArrowLength arrowlength} atangle 0d
              # FROM    :< 0d
              # TO      :: to boundaryatangle 0d
              # ++ {arrow @ToArrowLength arrowlength} atangle 0d
              # TO      :< 180d
              # XRIGHT  := {{xcoord FROM} max {xcoord TO}} + bias
              # XP1     := { XRIGHT ycoord FROM }
              # XP2     := { XRIGHT ycoord TO   }
              # VERT    := XP1 angleto XP2
              # LMID    :: XP1 ** 0.5 ++ XP2 ** 0.5
              # LMID    :< VERT
              # XINDENT := xindent min {FROM distance XP1}
              # ZINDENT := zindent min {XP2   distance TO}
              # LFROM   :: FROM ++ { XINDENT 0 }
              # LFROM   :< 0d
              # LTO     :: TO ++ { ZINDENT 0 }
              # LTO     :< 180d
              # RADIUS  := radius min { { XP1 distance XP2 } * 0.5 }
              # XP1PRE  := XP1 ++ { RADIUS atangle 180d }
              # XP1POST := XP1 ++ { RADIUS atangle VERT }
              # XP1CTR  := XP1PRE ++ { RADIUS atangle VERT }
              # P1      :: XP1CTR ++ { RADIUS atangle { XP1CTR angleto XP1 } }
              # P1      :< XP1PRE angleto XP1POST
              # XP2PRE  := XP2 -- { RADIUS atangle VERT }
              # XP2POST := XP2 ++ { RADIUS atangle 180d }
              # XP2CTR  := XP2PRE ++ { RADIUS atangle 180d }
              # P2      :: XP2CTR ++ { RADIUS atangle { XP2CTR angleto XP2 } }
              # P2      :< XP2PRE angleto XP2POST
              # FROM LFROM XP1PRE
              #   {round VERT} quadcase
              #     90 { [XP1CTR] P1 [XP1CTR] }
              #     270 { [XP1CTR clockwise] P1 [XP1CTR clockwise] }
              # XP1POST LMID XP2PRE
              #   {round VERT} quadcase
              #     90 { [XP2CTR] P2 [XP2CTR] }
              #     270 { [XP2CTR clockwise] P2 [XP2CTR clockwise] }
              # XP2POST LTO TO
		  }
		  PDF @Yield {}
		}
	    }

	    import @Geometry
	    def @DWrapLinePath
	    {
		@BackEnd @Case {
		  PostScript @Yield {
	      {arrow @FromArrowLength arrowlength}
	      {arrow @ToArrowLength arrowlength}
	      "{" from "}" "{" to "}"
	      xindent zindent bias fbias tbias "ldiagdwraplinepath"
              # DIRN	:= if cond { xcoord from??CTR < xcoord to??CTR }
              # 	      then { 180d } else { 0d }
              # FROM	:: from boundaryatangle DIRN
              # ++ {arrow @FromArrowLength arrowlength} atangle DIRN
              # FROM	:< DIRN
              # TO	:: to boundaryatangle { DIRN + 180d }
              # ++ {arrow @ToArrowLength arrowlength} atangle { DIRN + 180d }
              # TO	:< DIRN
              # P1	:: FROM ++ {fbias max 0} atangle DIRN
              # P1	:< if cond { DIRN = 180d } then { 225d } else { -45d }
              # P4	:: TO ++ {tbias max 0} atangle { DIRN + 180d }
              # P4	:< if cond { DIRN = 180d } then { 135d } else { 45d }
              # YC	:= ycoord { from boundaryatangle 270d } min
              # 	   ycoord { to   boundaryatangle 270d }
              # 	   - { bias max 0 }
              # P2	:: { xcoord P1 YC }
              # P2	:< P4@ANGLE - 180d
              # P3	:: { xcoord P4 YC }
              # P3	:< P1@ANGLE - 180d
              # XINDENT	:= xindent min { FROM distance P1 }
              # LFROM	:: FROM ++ XINDENT atangle DIRN
              # LFROM	:< FROM@ANGLE
              # ZINDENT	:= zindent min { TO distance P4 }
              # LTO	:: TO ++ ZINDENT atangle { DIRN + 180d }
              # LTO	:< TO@ANGLE
              # LMID	:: P2 ** 0.5 ++ P3 ** 0.5
              # LMID	:< DIRN - 180d
              # FROM P1 P2 P3 P4 TO
		  }
		  PDF @Yield {}
		}
	    }

	    import @Geometry
	    def @DWrapCurvePath
	    {
		@BackEnd @Case {
		  PostScript @Yield {
	      {arrow @FromArrowLength arrowlength}
	      {arrow @ToArrowLength arrowlength}
	      "{" from "}" "{" to "}"
	      xindent zindent bias fbias tbias radius "ldiagdwrapcurvepath"
              # DIRN	:= if cond { xcoord from??CTR < xcoord to??CTR }
              # 	      then { 180d } else { 0d }
              # CLOCK	:= if cond { xcoord from??CTR < xcoord to??CTR }
              # 	      then { anticlockwise } else { clockwise }
              # FROM	:: from boundaryatangle DIRN
              # ++ {arrow @FromArrowLength arrowlength} atangle DIRN
              # FROM	:< DIRN
              # TO	:: to boundaryatangle { DIRN + 180d }
              # ++ {arrow @ToArrowLength arrowlength} atangle { DIRN + 180d }
              # TO	:< DIRN
              #
              # XP1	:= FROM ++ {fbias max 0} atangle DIRN
              # XP4	:= TO ++ {tbias max 0} atangle { DIRN + 180d }
              # YC	:= ycoord { from boundaryatangle 270d } min
              # 	   ycoord { to   boundaryatangle 270d }
              # 	   - { bias max 0 }
              # XP2	:= { xcoord XP1 YC }
              # XP3	:= { xcoord XP4 YC }
              #
              # RP1	:= radius min { XP1 distance FROM } min
              # 	   { { XP1 distance XP2 } / 2 }
              # XP1PRE	:= XP1 ++ RP1 atangle { XP1 angleto FROM }
              # XP1POST := XP1 ++ RP1 atangle { XP1 angleto XP2  }
              # XP1CTR  := XP1PRE ++ RP1 atangle { XP1 angleto XP2  }
              # P1	:: XP1CTR ++ RP1 atangle { XP1CTR angleto XP1 }
              # P1	:< XP1CTR angleto P1 + DIRN - 90d
              #
              # RP2	:= radius min { { XP1 distance XP2 } / 2 }
              # 	     min { { XP2 distance XP3 } / 2 }
              # XP2PRE	:= XP2 ++ RP2 atangle { XP2 angleto XP1 }
              # XP2POST	:= XP2 ++ RP2 atangle { XP2 angleto XP3 }
              # XP2CTR	:= XP2PRE ++ RP2 atangle { XP2 angleto XP3 }
              # P2	:: XP2CTR ++ RP2 atangle { XP2CTR angleto XP2 }
              # P2	:< XP2CTR angleto P2 + DIRN - 90d
              #
              # RP3	:= radius min { { XP2 distance XP3 } / 2 }
              # 	     min { { XP3 distance XP4 } / 2 }
              # XP3PRE	:= XP3 ++ RP3 atangle { XP3 angleto XP2 }
              # XP3POST	:= XP3 ++ RP3 atangle { XP3 angleto XP4 }
              # XP3CTR	:= XP3PRE ++ RP3 atangle { XP3 angleto XP4 }
              # P3	:: XP3CTR ++ RP3 atangle { XP3CTR angleto XP3 }
              # P3	:< XP3CTR angleto P3 + DIRN - 90d
              #
              # RP4	:= radius min { { XP4 distance XP3 } / 2 }
              # 	     min { XP4 distance TO }
              # XP4PRE	:= XP4 ++ RP4 atangle { XP4 angleto XP3 }
              # XP4POST := XP4 ++ RP4 atangle { XP4 angleto TO  }
              # XP4CTR  := XP4PRE ++ RP4 atangle { XP4 angleto TO  }
              # P4	:: XP4CTR ++ RP4 atangle { XP4CTR angleto XP4 }
              # P4	:< XP4CTR angleto P4 + DIRN - 90d
              #
              # XINDENT	:= xindent min { FROM distance XP1PRE }
              # LFROM	:: FROM ++ XINDENT atangle DIRN
              # LFROM	:< FROM@ANGLE
              #
              # LMID	:: XP2 ** 0.5 ++ XP3 ** 0.5
              # LMID	:< DIRN - 180d
              #
              # ZINDENT	:= zindent min { TO distance XP4POST }
              # LTO	:: TO ++ ZINDENT atangle { DIRN + 180d }
              # LTO	:< TO@ANGLE
              #
              # FROM LFROM
              # XP1PRE [XP1CTR CLOCK] XP1POST
              # XP2PRE [XP2CTR CLOCK] XP2POST
              # LMID
              # XP3PRE [XP3CTR CLOCK] XP3POST
              # XP4PRE [XP4CTR CLOCK] XP4POST
              # LTO TO
		  }
		  PDF @Yield {}
		}
	    }

	    import @Geometry
	    def @UWrapLinePath
	    {
		@BackEnd @Case {
		  PostScript @Yield {
	      {arrow @FromArrowLength arrowlength}
	      {arrow @ToArrowLength arrowlength}
	      "{" from "}" "{" to "}"
	      xindent zindent bias fbias tbias "ldiaguwraplinepath"
              # DIRN	:= if cond { xcoord from??CTR < xcoord to??CTR }
              # 	      then { 180d } else { 0d }
              # FROM	:: from boundaryatangle DIRN
              # ++ {arrow @FromArrowLength arrowlength} atangle DIRN
              # FROM	:< DIRN
              # TO	:: to boundaryatangle { DIRN + 180d }
              # ++ {arrow @ToArrowLength arrowlength} atangle { DIRN + 180d }
              # TO	:< DIRN
              # P1	:: FROM ++ {fbias max 0} atangle DIRN
              # P1	:< if cond { DIRN = 180d } then { 135d } else { 45d }
              # P4	:: TO ++ {tbias max 0} atangle { DIRN + 180d }
              # P4	:< if cond { DIRN = 180d } then { 225d } else { -45d }
              # YC	:= ycoord { from boundaryatangle 90d } max
              # 	   ycoord { to   boundaryatangle 90d }
              # 	   + { bias max 0 }
              # P2	:: { xcoord P1 YC }
              # P2	:< P4@ANGLE - 180d
              # P3	:: { xcoord P4 YC }
              # P3	:< P1@ANGLE - 180d
              # XINDENT	:= xindent min { FROM distance P1 }
              # LFROM	:: FROM ++ XINDENT atangle DIRN
              # LFROM	:< FROM@ANGLE
              # ZINDENT	:= zindent min { TO distance P4 }
              # LTO	:: TO ++ ZINDENT atangle { DIRN + 180d }
              # LTO	:< TO@ANGLE
              # LMID	:: P2 ** 0.5 ++ P3 ** 0.5
              # LMID	:< DIRN - 180d
              # FROM P1 P2 P3 P4 TO
		  }
		  PDF @Yield {}
		}
	    }

	    import @Geometry
	    def @UWrapCurvePath
	    {
		@BackEnd @Case {
		  PostScript @Yield {
	      {arrow @FromArrowLength arrowlength}
	      {arrow @ToArrowLength arrowlength}
	      "{" from "}" "{" to "}"
	      xindent zindent bias fbias tbias radius "ldiaguwrapcurvepath"
              # DIRN	:= if cond { xcoord from??CTR < xcoord to??CTR }
              # 	      then { 180d } else { 0d }
              # CLOCK	:= if cond { xcoord from??CTR < xcoord to??CTR }
              # 	      then { clockwise } else { anticlockwise }
              # FROM	:: from boundaryatangle DIRN
              # ++ {arrow @FromArrowLength arrowlength} atangle DIRN
              # FROM	:< DIRN
              # TO	:: to boundaryatangle { DIRN + 180d }
              # ++ {arrow @ToArrowLength arrowlength} atangle { DIRN + 180d }
              # TO	:< DIRN
              #
              # XP1	:= FROM ++ {fbias max 0} atangle DIRN
              # XP4	:= TO ++ {tbias max 0} atangle { DIRN + 180d }
              # YC	:= ycoord { from boundaryatangle 90d } max
              # 	   ycoord { to   boundaryatangle 90d }
              # 	   + { bias max 0 }
              # XP2	:= { xcoord XP1 YC }
              # XP3	:= { xcoord XP4 YC }
              #
              # RP1	:= radius min { XP1 distance FROM } min
              # 	   { { XP1 distance XP2 } / 2 }
              # XP1PRE	:= XP1 ++ RP1 atangle { XP1 angleto FROM }
              # XP1POST := XP1 ++ RP1 atangle { XP1 angleto XP2  }
              # XP1CTR  := XP1PRE ++ RP1 atangle { XP1 angleto XP2  }
              # P1	:: XP1CTR ++ RP1 atangle { XP1CTR angleto XP1 }
              # P1	:< XP1CTR angleto P1 + DIRN + 90d
              #
              # RP2	:= radius min { { XP1 distance XP2 } / 2 }
              # 	     min { { XP2 distance XP3 } / 2 }
              # XP2PRE	:= XP2 ++ RP2 atangle { XP2 angleto XP1 }
              # XP2POST	:= XP2 ++ RP2 atangle { XP2 angleto XP3 }
              # XP2CTR	:= XP2PRE ++ RP2 atangle { XP2 angleto XP3 }
              # P2	:: XP2CTR ++ RP2 atangle { XP2CTR angleto XP2 }
              # P2	:< XP2CTR angleto P2 + DIRN + 90d
              #
              # RP3	:= radius min { { XP2 distance XP3 } / 2 }
              # 	     min { { XP3 distance XP4 } / 2 }
              # XP3PRE	:= XP3 ++ RP3 atangle { XP3 angleto XP2 }
              # XP3POST	:= XP3 ++ RP3 atangle { XP3 angleto XP4 }
              # XP3CTR	:= XP3PRE ++ RP3 atangle { XP3 angleto XP4 }
              # P3	:: XP3CTR ++ RP3 atangle { XP3CTR angleto XP3 }
              # P3	:< XP3CTR angleto P3 + DIRN + 90d
              #
              # RP4	:= radius min { { XP4 distance XP3 } / 2 }
              # 	     min { XP4 distance TO }
              # XP4PRE	:= XP4 ++ RP4 atangle { XP4 angleto XP3 }
              # XP4POST := XP4 ++ RP4 atangle { XP4 angleto TO  }
              # XP4CTR  := XP4PRE ++ RP4 atangle { XP4 angleto TO  }
              # P4	:: XP4CTR ++ RP4 atangle { XP4CTR angleto XP4 }
              # P4	:< XP4CTR angleto P4 + DIRN + 90d
              #
              # XINDENT	:= xindent min { FROM distance XP1PRE }
              # LFROM	:: FROM ++ XINDENT atangle DIRN
              # LFROM	:< FROM@ANGLE
              #
              # LMID	:: XP2 ** 0.5 ++ XP3 ** 0.5
              # LMID	:< DIRN - 180d
              #
              # ZINDENT	:= zindent min { TO distance XP4POST }
              # LTO	:: TO ++ ZINDENT atangle { DIRN + 180d }
              # LTO	:< TO@ANGLE
              #
              # FROM LFROM
              # XP1PRE [XP1CTR CLOCK] XP1POST
              # XP2PRE [XP2CTR CLOCK] XP2POST
              # LMID
              # XP3PRE [XP3CTR CLOCK] XP3POST
              # XP4PRE [XP4CTR CLOCK] XP4POST
              # LTO TO
		  }
		  PDF @Yield {}
		}
	    }

	    import @Geometry
	    def @Path
	    {
		path @Case {
		    line			@Yield @LinePath
		    { acurve curve }		@Yield @ACurvePath
		    ccurve			@Yield @CCurvePath
		    bezier			@Yield @BezierPath
		    vhline			@Yield @VHLinePath
		    vhcurve			@Yield @VHCurvePath
		    hvline			@Yield @HVLinePath
		    hvcurve			@Yield @HVCurvePath
		    lvrline			@Yield @LVRLinePath
		    lvrcurve			@Yield @LVRCurvePath
		    rvlline			@Yield @RVLLinePath
		    rvlcurve			@Yield @RVLCurvePath
		    dwrapline			@Yield @DWrapLinePath
		    dwrapcurve			@Yield @DWrapCurvePath
		    uwrapline			@Yield @UWrapLinePath
		    uwrapcurve			@Yield @UWrapCurvePath
		    else			@Yield {
			path
			    from { from }
			    to { to }
			    bias { bias }
			    fbias { fbias }
			    tbias { tbias }
			    radius { radius }
			    xindent { xindent }
			    zindent { zindent }
			    frompt { frompt }
			    topt { topt }
			    arrow { arrow }
			    arrowlength { arrowlength }
		    }
		}
	    }

	    def @FromLabel
	    {
		@DoLabel
		    which	{ "f"				}
		    label	{ fromlabel @Else @FromArrow	}
		    labelmargin	{ fromlabelmargin		}
		    labelfont	{ fromlabelfont			}
		    labelbreak	{ fromlabelbreak		}
		    labelformat { fromlabelformat @Body		}
		    labelpos	{ fromlabelpos			}
		    labelprox	{ fromlabelprox			}
		    labelangle	{ fromlabelangle		}
		    labelctr	{ fromlabelctr			}
		    labeladjust	{ fromlabeladjust		}
	    }

	    def @ToLabel
	    {
		@DoLabel
		    which	{ "t"				}
		    label	{ tolabel @Else @ToArrow	}
		    labelmargin	{ tolabelmargin			}
		    labelfont	{ tolabelfont			}
		    labelbreak	{ tolabelbreak			}
		    labelformat { tolabelformat @Body		}
		    labelpos	{ tolabelpos			}
		    labelprox	{ tolabelprox			}
		    labelangle	{ tolabelangle			}
		    labelctr	{ tolabelctr			}
		    labeladjust	{ tolabeladjust			}
	    }

	    def @Direct
	    {
		pathstyle @Case {
		    { "/ldiagsolid" "/ldiagdashed" "/ldiagcdashed"
		      "/ldiagdotted" "/ldiagnoline" } @Yield 1
		    else @Yield 0
		}
	    }

	  @BackEnd @Case {
	    PostScript @Yield {

	    @Null & # so that preceding space gets chewed up
            {
	      @Direct "ldiaglinkbegin [" @Path "]" pathdashlength
	      "[" pathstyle "]" pathwidth "ldiaglinkend"
            }
            @Graphic
            {
		/ { fromlabel @Else @FromArrow}	@IfNonEmpty @FromLabel
		/ { xlabel @Else linklabel }	@IfNonEmpty @XLabel
		/ { ylabel @Else linklabel }	@IfNonEmpty @YLabel
		/ { zlabel @Else linklabel }	@IfNonEmpty @ZLabel
		/ { tolabel @Else @ToArrow }	@IfNonEmpty @ToLabel
	    }

	    }
	    PDF @Yield {}
	  }
	}


        def @ObjectLink
	    precedence 90
	    associativity left
	    left x
	    named treehsep { treehsep }
	    named treevsep { treevsep }
	    named format
		named x {}
		named y {}
		named insinuatelink {}
		named treehsep {}
		named treevsep {}
	    { x | y | insinuatelink }
            import @Geometry named path
                named from {}
                named to {}
                named bias {}
                named fbias {}
                named tbias {}
                named radius {}
                named xindent {}
                named zindent {}
                named frompt {}
                named topt {}
                named arrow {}
                named arrowlength {}
            					{ path
						    from { from }
						    to { to }
						    bias { bias }
						    fbias { fbias }
						    tbias { tbias }
						    radius { radius }
						    xindent { xindent }
						    zindent { zindent }
						    frompt { frompt }
						    topt { topt }
						    arrow { arrow }
						    arrowlength { arrowlength }
						}
            import @Geometry named basefrom	{ 			}
            import @Geometry named baseto	{ 			}
            import @Geometry named from		{ 			}
            import @Geometry named to		{ 			}
            import @Geometry named bias		{ bias			}
            import @Geometry named fbias	{ fbias			}
            import @Geometry named tbias	{ tbias			}
            import @Geometry named radius	{ radius		}
            import @Geometry named xindent	{ xindent		}
            import @Geometry named zindent	{ zindent		}
            import @Geometry named frompt	{ frompt		}
            import @Geometry named topt		{ topt			}
            named pathstyle
		named solid   { "/ldiagsolid"   }
		named dashed  { "/ldiagdashed"  }
		named cdashed { "/ldiagcdashed" }
		named dotted  { "/ldiagdotted"  }
		named noline  { "/ldiagnoline"  }
						{ pathstyle		}
            import @Geometry named pathdashlength { pathdashlength	}
            import @Geometry named pathwidth
		named thin   { 0.04 ft }
		named medium { 0.08 ft }
		named thick  { 0.12 ft }
						{ pathwidth		}

            named arrow				{ arrow			}
            named arrowstyle			{ arrowstyle		}
            named arrowwidth			{ arrowwidth		}
            named arrowlength			{ arrowlength		}

	    named linklabel			{ linklabel		}
	    named linklabelmargin		{ linklabelmargin	}
	    named linklabelfont			{ linklabelfont		}
	    named linklabelbreak		{ linklabelbreak	}
	    named linklabelformat right @Body	{ linklabelformat @Body	}
	    import @Geometry named linklabelpos	{ linklabelpos		}
	    named linklabelprox			{ linklabelprox		}
	    import @Geometry named linklabelangle  { linklabelangle	}
	    named linklabelctr			{ linklabelctr		}
	    import @Geometry named linklabeladjust { linklabeladjust	}

            named xlabel			{ xlabel		}
            named xlabelmargin	        	{ xlabelmargin		}
            named xlabelfont			{ xlabelfont		}
            named xlabelbreak			{ xlabelbreak		}
	    named xlabelformat right @Body	{ xlabelformat @Body	}
            import @Geometry named xlabelpos	{ xlabelpos		}
            named xlabelprox			{ xlabelprox		}
            import @Geometry named xlabelangle	{ xlabelangle		}
	    named xlabelctr			{ xlabelctr		}
            import @Geometry named xlabeladjust	{ xlabeladjust		}

            named ylabel			{ ylabel		}
            named ylabelmargin			{ ylabelmargin		}
            named ylabelfont			{ ylabelfont		}
            named ylabelbreak			{ ylabelbreak		}
	    named ylabelformat right @Body	{ ylabelformat @Body	}
            import @Geometry named ylabelpos	{ ylabelpos		}
            named ylabelprox			{ ylabelprox		}
            import @Geometry named ylabelangle	{ ylabelangle		}
	    named ylabelctr			{ ylabelctr		}
            import @Geometry named ylabeladjust	{ ylabeladjust		}

            named zlabel			{ zlabel		}
            named zlabelmargin			{ zlabelmargin		}
            named zlabelfont			{ zlabelfont		}
            named zlabelbreak			{ zlabelbreak		}
	    named zlabelformat right @Body	{ zlabelformat @Body	}
            import @Geometry named zlabelpos	{ zlabelpos		}
            named zlabelprox			{ zlabelprox		}
            import @Geometry named zlabelangle	{ zlabelangle		}
	    named zlabelctr			{ zlabelctr		}
            import @Geometry named zlabeladjust	{ zlabeladjust		}

            named fromlabel			{ fromlabel		}
            named fromlabelmargin		{ fromlabelmargin	}
            named fromlabelfont			{ fromlabelfont		}
            named fromlabelbreak		{ fromlabelbreak	}
	    named fromlabelformat right @Body	{ fromlabelformat @Body	}
            import @Geometry named fromlabelpos	{ fromlabelpos		}
            named fromlabelprox			{ fromlabelprox		}
            import @Geometry named fromlabelangle  { fromlabelangle	}
	    named fromlabelctr			{ fromlabelctr		}
            import @Geometry named fromlabeladjust { fromlabeladjust	}

            named tolabel			{ tolabel		}
            named tolabelmargin			{ tolabelmargin		}
            named tolabelfont			{ tolabelfont		}
            named tolabelbreak			{ tolabelbreak		}
	    named tolabelformat right @Body	{ tolabelformat @Body	}
            import @Geometry named tolabelpos	{ tolabelpos		}
            named tolabelprox			{ tolabelprox		}
            import @Geometry named tolabelangle	{ tolabelangle		}
	    named tolabelctr			{ tolabelctr		}
            import @Geometry named tolabeladjust{ tolabeladjust		}
	    right y

        {
	    def @From
	    {
		from @Case {
		    ""   @Yield basefrom
		    else @Yield { basefrom"@"from }
		}
	    }

	    def @To
	    {
		to @Case {
		    ""   @Yield baseto
		    else @Yield { baseto"@"to }
		}
	    }

	    format
		x { x }
		y { y }
		treehsep { treehsep }
		treevsep { treevsep }
		insinuatelink {
		    @Link
			from		{ @From			}
			to		{ @To			}
			bias		{ bias			}
			fbias		{ fbias			}
			tbias		{ tbias			}
			radius		{ radius		}
			xindent		{ xindent		}
			zindent		{ zindent		}
			frompt		{ frompt		}
			topt		{ topt			}
			path		{ path
						from { @From }
						to { @To }
						bias { bias }
						fbias { fbias }
						tbias { tbias }
						radius { radius }
						xindent { xindent }
						zindent { zindent }
						frompt { frompt }
						topt { topt }
						arrow { arrow }
						arrowlength { arrowlength }
					}
			pathstyle	{ pathstyle		}
			pathdashlength	{ pathdashlength	}
			pathwidth	{ pathwidth		}
			arrow		{ arrow			}
			arrowstyle	{ arrowstyle		}
			arrowwidth	{ arrowwidth		}
			arrowlength	{ arrowlength		}

			linklabel	{ linklabel		}
			linklabelmargin	{ linklabelmargin	}
			linklabelfont	{ linklabelfont		}
			linklabelbreak	{ linklabelbreak	}
			linklabelformat	{ linklabelformat @Body	}
			linklabelpos	{ linklabelpos		}
			linklabelprox	{ linklabelprox		}
			linklabelangle	{ linklabelangle	}
			linklabelctr	{ linklabelctr		}
			linklabeladjust	{ linklabeladjust	}

			xlabel		{ xlabel		}
			xlabelmargin	{ xlabelmargin		}
			xlabelfont	{ xlabelfont		}
			xlabelbreak	{ xlabelbreak		}
			xlabelformat	{ xlabelformat @Body	}
			xlabelpos	{ xlabelpos		}
			xlabelprox	{ xlabelprox		}
			xlabelangle	{ xlabelangle		}
			xlabelctr	{ xlabelctr		}
			xlabeladjust	{ xlabeladjust		}

			ylabel		{ ylabel		}
			ylabelmargin	{ ylabelmargin		}
			ylabelfont	{ ylabelfont		}
			ylabelbreak	{ ylabelbreak		}
			ylabelformat	{ ylabelformat @Body	}
			ylabelpos	{ ylabelpos		}
			ylabelprox	{ ylabelprox		}
			ylabelangle	{ ylabelangle		}
			ylabelctr	{ ylabelctr		}
			ylabeladjust	{ ylabeladjust		}

			zlabel		{ zlabel		}
			zlabelmargin	{ zlabelmargin		}
			zlabelfont	{ zlabelfont		}
			zlabelbreak	{ zlabelbreak		}
			zlabelformat	{ zlabelformat @Body	}
			zlabelpos	{ zlabelpos		}
			zlabelprox	{ zlabelprox		}
			zlabelangle	{ zlabelangle		}
			zlabelctr	{ zlabelctr		}
			zlabeladjust	{ zlabeladjust		}

			fromlabel	{ fromlabel		}
			fromlabelmargin	{ fromlabelmargin	}
			fromlabelfont	{ fromlabelfont		}
			fromlabelbreak	{ fromlabelbreak	}
			fromlabelformat	{ fromlabelformat @Body	}
			fromlabelpos	{ fromlabelpos		}
			fromlabelprox	{ fromlabelprox		}
			fromlabelangle	{ fromlabelangle	}
			fromlabelctr	{ fromlabelctr		}
			fromlabeladjust	{ fromlabeladjust	}

			tolabel		{ tolabel		}
			tolabelmargin	{ tolabelmargin		}
			tolabelfont	{ tolabelfont		}
			tolabelbreak	{ tolabelbreak		}
			tolabelformat	{ tolabelformat @Body	}
			tolabelpos	{ tolabelpos		}
			tolabelprox	{ tolabelprox		}
			tolabelangle	{ tolabelangle		}
			tolabelctr	{ tolabelctr		}
			tolabeladjust	{ tolabeladjust		}
	    }
        }

	macro @Line		{ @Link path { line     }		}
	macro @Arrow		{ @Link path { line     } arrow { yes }	}
	macro @Curve		{ @Link path { curve	}		}
	macro @CurveArrow	{ @Link path { curve	} arrow { yes }	}
	macro @ACurve		{ @Link path { acurve	}		}
	macro @ACurveArrow	{ @Link path { acurve	} arrow { yes }	}
	macro @CCurve		{ @Link path { ccurve	}		}
	macro @CCurveArrow	{ @Link path { ccurve	} arrow { yes }	}

	macro @Bezier		{ @Link path { bezier	}		}
	macro @BezierArrow	{ @Link path { bezier	} arrow { yes }	}

	macro @HVLine		{ @Link path { hvline   }		}
	macro @HVArrow		{ @Link path { hvline   } arrow { yes }	}
	macro @VHLine		{ @Link path { vhline   }		}
	macro @VHArrow		{ @Link path { vhline   } arrow { yes }	}
	macro @HVCurve		{ @Link path { hvcurve  }		}
	macro @HVCurveArrow	{ @Link path { hvcurve  } arrow { yes }	}
	macro @VHCurve		{ @Link path { vhcurve  }		}
	macro @VHCurveArrow	{ @Link path { vhcurve  } arrow { yes }	}

	macro @LVRLine		{ @Link path { lvrline  }		}
	macro @LVRArrow		{ @Link path { lvrline  } arrow { yes }	}
	macro @RVLLine		{ @Link path { rvlline  }		}
	macro @RVLArrow		{ @Link path { rvlline  } arrow { yes }	}
	macro @LVRCurve		{ @Link path { lvrcurve }		}
	macro @LVRCurveArrow	{ @Link path { lvrcurve } arrow { yes }	}
	macro @RVLCurve		{ @Link path { rvlcurve }		}
	macro @RVLCurveArrow	{ @Link path { rvlcurve } arrow { yes }	}

	macro @DWrapLine	{ @Link path { dwrapline}		}
	macro @DWrapArrow	{ @Link path { dwrapline} arrow { yes }	}
	macro @UWrapLine	{ @Link path { uwrapline}		}
	macro @UWrapArrow	{ @Link path { uwrapline} arrow { yes }	}
	macro @DWrapCurve	{ @Link path {dwrapcurve}		}
	macro @DWrapCurveArrow	{ @Link path {dwrapcurve} arrow { yes }	}
	macro @UWrapCurve	{ @Link path {uwrapcurve}		}
	macro @UWrapCurveArrow	{ @Link path {uwrapcurve} arrow { yes }	}

	export

	    @Node @Box @CurveBox @ShadowBox @Square @Diamond
	    @Polygon @Isosceles @Ellipse @Circle
	    @LeftSub @ZeroWidthLeftSub @RightSub @ZeroWidthRightSub
	    @FirstSub @NextSub @StubSub

	def @Tree
	    named treehindent
		named left  { 0.0rt }
		named ctr   { 0.5rt }
		named right { 1.0rt }
						{ treehindent		}
	    body x
	{

	    macro @TNode	{ @@Node nodetag { T 		} }
            macro @Node		{ @TNode                          }
            macro @Box		{ @TNode outline { box		} }
            macro @CurveBox	{ @TNode outline { curvebox	} }
	    macro @ShadowBox	{ @TNode outline { shadowbox	} }
            macro @Square	{ @TNode outline { square	} }
            macro @Diamond	{ @TNode outline { diamond	} }
            macro @Polygon	{ @TNode outline { polygon	} }
            macro @Isosceles	{ @TNode outline { isosceles	} }
            macro @Ellipse	{ @TNode outline { ellipse	} }
            macro @Circle	{ @TNode outline { circle	} }

	    def fixroot
		precedence 90
		left root
	    {
		|treehindent root
	    }

	    macro @LeftSub
	    {
		@ObjectLink
		    basefrom { T }
		    baseto { L@T }
		    format { { /treevsep {L::y} } |treehsep x | insinuatelink }
	    }

	    macro @ZeroWidthLeftSub
	    {
		@ObjectLink
		    basefrom { T }
		    baseto { L@T }
		    format { { /treevsep @ZeroWidth { {L::y} ^|treehsep } } |
			x | insinuatelink }
	    }

	    macro @FirstSub
	    {
		fixroot //
		@ObjectLink
		    basefrom { T }
		    baseto { S@T }
		    format { //treevsep {S::y} | insinuatelink | }
	    }

	    macro @NextSub
	    {
		@ObjectLink
		    basefrom { T }
		    baseto { S@T }
		    format { x |treehsep { / {S::y} | insinuatelink | } }
	    }

	    macro @RightSub
	    {
		@ObjectLink
		    basefrom { T }
		    baseto { R@T }
		    format { x |treehsep  { /treevsep {R::y} } | insinuatelink }
	    }

	    macro @ZeroWidthRightSub
	    {
		@ObjectLink
		    basefrom { T }
		    baseto { R@T }
		    format { x | { /treevsep @ZeroWidth { |treehsep {R::y} } }
			| insinuatelink }
	    }

	    macro @StubSub
	    {
		@ObjectLink
		    basefrom { T }
		    baseto { T }
		    format { @VContract { |0.5rt x | // |0.5rt
		      S:: @BoxLabels @CatchTags y | } | insinuatelink }
		    # path { from S@T@SW S@T@SE to }
		    path {
			P1::	S@SW
			P2::	S@SE
			FROM::	from boundaryatangle { from??CTR angleto P1 }
			TO::	to   boundaryatangle { to??CTR   angleto P2 }
			FROM P1 P2 TO
		    }
	    }

	    @HContract @VContract x
	}

	export

	    @Node @Box @CurveBox @ShadowBox @Square @Diamond
	    @Polygon @Isosceles @Ellipse @Circle
	    @LeftSub @ZeroWidthLeftSub @RightSub @ZeroWidthRightSub
	    @FirstSub @NextSub @StubSub

	def @HTree
	    named treevindent
		named top   { 0.0rt }
		named ctr   { 0.5rt }
		named foot  { 1.0rt }
						{ treevindent		}
	    body x
	{

	    macro @TNode	{ @@Node nodetag { T 		} }
	    macro @Node		{ @TNode                          }
            macro @Box		{ @TNode outline { box		} }
            macro @CurveBox	{ @TNode outline { curvebox	} }
	    macro @ShadowBox	{ @TNode outline { shadowbox	} }
            macro @Square	{ @TNode outline { square	} }
            macro @Diamond	{ @TNode outline { diamond	} }
            macro @Polygon	{ @TNode outline { polygon	} }
            macro @Isosceles	{ @TNode outline { isosceles	} }
            macro @Ellipse	{ @TNode outline { ellipse	} }
            macro @Circle	{ @TNode outline { circle	} }

	    def fixroot
		precedence 90
		left root
	    {
		/treevindent root
	    }

	    macro @LeftSub
	    {
		@ObjectLink
		    basefrom { T }
		    baseto { L@T }
		    format { { |treehsep {L::y} } /treevsep x / insinuatelink }
	    }

	    macro @ZeroWidthLeftSub
	    {
		@ObjectLink
		    basefrom { T }
		    baseto { L@T }
		    format { { |treehsep @ZeroWidth { {L::y} ^/treevsep } } /
			x / insinuatelink }
	    }

	    macro @FirstSub
	    {
		fixroot ||
		@ObjectLink
		    basefrom { T }
		    baseto { S@T }
		    format { ||treehsep { {S::y} / insinuatelink / } }
	    }

	    macro @NextSub
	    {
		@ObjectLink
		    basefrom { T }
		    baseto { S@T }
		    format { x /treevsep { | {S::y} { / insinuatelink / } } }
	    }

	    macro @RightSub
	    {
		@ObjectLink
		    basefrom { T }
		    baseto { R@T }
		    format { x /treevsep  { |treehsep {R::y} } / insinuatelink }
	    }

	    macro @ZeroWidthRightSub
	    {
		@ObjectLink
		    basefrom { T }
		    baseto { R@T }
		    format { x / { |treehsep @ZeroWidth { /treevsep {R::y} } }
			/ insinuatelink }
	    }

	    macro @StubSub
	    {
		@ObjectLink
		    basefrom { T }
		    baseto { T }
		    format { @VContract { { /0.5rt x / } || { /0.5rt
		      S:: @BoxLabels @CatchTags y / } } / insinuatelink }
		    # path { from S@T@SW S@T@SE to }
		    path {
			P1::	S@NE
			P2::	S@SE
			FROM::	from boundaryatangle { from??CTR angleto P1 }
			TO::	to   boundaryatangle { to??CTR   angleto P2 }
			FROM P1 P2 TO
		    }
	    }

	    @HContract @VContract x
	}

	@BackEnd @Case {
	  PostScript @Yield {
        {
	  save @Case { { yes Yes } @Yield "grestore save gsave" else @Yield {} }
	  maxlabels "ldiagbegin"
          //
	  "ldiagend"
	  save @Case { { yes Yes } @Yield "restore" else @Yield {} }
        } @Graphic @Body
	  }
	  PDF @Yield {}
	}

    @End @Diag
}
