%% -*-TeX-*-
 % ###################################################################
 % 
 %  FILE: "pgfmore.sty"
 %                                    created: 2004-02-27 10:20:11 
 %                                last update: 2004-03-17 17:14:49 
 %  Author: Frédéric Boulanger
 %  E-mail: Frederic.Boulanger@supelec.fr
 %    mail: Supélec - Service Informatique
 %          3 rue Joliot-Curie, 91192 Gif-sur-Yvette cedex, France
 %     www: http://wwwsi.supelec.fr/fb/
 %  
 %  Description: 
 % 
 %  History
 % 
 %  modified   by  rev reason
 %  ---------- --- --- -----------
 %  2004-02-27 FBO 1.0 original
 % ###################################################################
 %%
\ProvidesPackage{pgfmore}[2004/02/27 Frederic.Boulanger@supelec.fr]
\RequirePackage{pgf}
\RequirePackage{pgfnodes}

%%
%% Macros definition tools
%%

%
% Redefine a command \cmd : let \cmd@orig hold its original
% definition, then define \cmd again.
%  
\newcommand{\redef}[1]{%
  \ifx #1\undefined
    \PackageError{pgfmore}%
                 {\string#1 is not defined and cannot be redefined}%
                 {\string\redef\space can only be used with already defined 
                  commands, but \string#1 is not defined.}%
  \fi
  {%
    \escapechar=-1% \string won't put a '\' in front of the cs name
    \global\expandafter\let\csname\string#1@orig\endcsname#1%
  }%
  \def#1%
}

% Define a new command, check for existing definition
\newcommand{\chkdef}[1]{%
  \ifx #1\undefined
  \else
    \PackageError{pgfmore}%
                 {\string#1 is already defined and cannot be redefined}%
                 {\string\chkdef\space can only define new commands, 
                  but \string#1 is already defined.}%
  \fi
  {%
    \escapechar=-1% \string won't put a '\' in front of the cs name
    \global\expandafter\let\csname\string#1@orig\endcsname#1%
  }%
  \def#1%
}

% Change the definition of an existing command
\newcommand{\chgdef}[1]{%
  \ifx #1\undefined
    \PackageError{pgfmore}%
                 {\string#1 is not defined}%
                 {\string\chgdef\space can only change the definition 
                  of defined commands, but \string#1 is not defined.}%
  \fi
  {%
    \escapechar=-1% \string won't put a '\' in front of the cs name
    \global\expandafter\let\csname\string#1@orig\endcsname#1%
  }%
  \def#1%
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Separate fill and stroke color handling %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% The token register \pgf@current@path contains the commands
% that build the current path.
\newtoks\pgf@current@path

% Reset current path to the empty path
\newcommand{\pgfresetpath}{\pgf@current@path={}}

% Append something to the token register
\newcommand{\pgf@append@path}[1]{%
  \expandafter\pgf@current@path\expandafter{\the\pgf@current@path#1}%
}

% Append a path-building command to the current graphic path.
% The command itself must not be expanded while its arguments
% must be fully expanded to known numerical values.
\newcommand{\pgf@appendtopath}[1]{%
  \pgf@append@pathcmd#1\end@args
}
% First, add the unexpanded path-building command
\chkdef\pgf@append@pathcmd#1{%
  \pgf@append@path{#1}%
  \pgf@parse@pathargs
}
% then, add the expanded parameters
\chkdef{\pgf@tmp@arg}{}
\chkdef\pgf@parse@pathargs#1{%
  \ifx #1\end@args
    \let\next=\relax
  \else
    \let\next=\pgf@parse@pathargs
    \edef\pgf@tmp@arg{#1}%
    \expandafter\pgf@append@path\expandafter{\expandafter{\pgf@tmp@arg}}%
  \fi
  \next
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Redefine the path building commands to add to pgf's 
% path instead being expanded to \special
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\redef\pgfsys@moveto#1#2{%
  \pgf@appendtopath{\pgfsys@moveto@orig{#1}{#2}}%
}
\redef\pgfsys@lineto#1#2{%
  \pgf@appendtopath{\pgfsys@lineto@orig{#1}{#2}}%
}
\redef\pgfsys@closepath{%
  \pgf@appendtopath{\pgfsys@closepath@orig}%
}
\redef\pgfsys@bezier#1#2#3#4#5#6{%
  \pgf@appendtopath{\pgfsys@bezier@orig{#1}{#2}{#3}{#4}{#5}{#6}}%
}
\redef\pgfsys@rect#1#2#3#4{%
  \pgf@appendtopath{\pgfsys@rect@orig{#1}{#2}{#3}{#4}}%
}
%%%
% Update path stroking/filling commands so that they use pgf's
% path and colors.
%%%
% \pgfstroke must be redefined because the stroke hook is not
% expanded inside the group where the stroke color is set in
% \pgfsys@stroke, so arrows wouldn't have the right color.
\redef\pgfstroke{%
  {\expandafter\color\pgf@strokecolor\pgfstroke@orig}\pgfresetpath
}
\redef\pgfsys@stroke{%
  {\expandafter\color\pgf@strokecolor\the\pgf@current@path\pgfsys@stroke@orig}%
  \pgfresetpath
}
\redef\pgfsys@fill{%
  {\expandafter\color\pgf@fillcolor\the\pgf@current@path\pgfsys@fill@orig}%
  \pgfresetpath
}
\redef\pgfsys@fillstroke{%
  {\expandafter\color\pgf@fillcolor\the\pgf@current@path\pgfsys@fill@orig
   \expandafter\color\pgf@strokecolor\the\pgf@current@path\pgfsys@stroke@orig}%
  \pgfresetpath
}
% Same thing for clipping commands
\redef\pgfsys@clip{%
  \pgfsys@clip@orig\pgfresetpath
}
\redef\pgfsys@eoclip{%
  \the\pgf@current@path\pgfsys@eoclip@orig\pgfresetpath
}
\redef\pgfsys@strokeclip{%
  {\expandafter\color\pgf@strokecolor
   \the\pgf@current@path\pgfsys@strokeclip@orig}%
  \pgfresetpath
}
\redef\pgfsys@closestrokeclip{%
  {\expandafter\color\pgf@strokecolor
   \the\pgf@current@path\pgfsys@closestrokeclip@orig}%
  \pgfresetpath
}
\redef\pgfsys@fillclip{%
  {\expandafter\color\pgf@fillcolor\the\pgf@current@path\pgfsys@fillclip@orig}%
  \pgfresetpath
}
\redef\pgfsys@fillstrokeclip{%
  {\expandafter\color\pgf@fillcolor\the\pgf@current@path\pgfsys@fill@orig
   \expandafter\color\pgf@strokecolor
   \the\pgf@current@path\pgfsys@strokeclip@orig}%
  \pgfresetpath
}
\redef\pgfsys@discardpath{%
  \pgfsys@discardpath@orig\pgfresetpath
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Many arguments in pgf are enclosed in square %
% brackets but are not optional.               %
% Make them really optional.                   %
% + add support for pgf's text color           %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Make the mode parameter of drawing commands default to "stroke"
% 
\redef\pgfrect{%
  \@ifnextchar[{%
    \pgfrect@orig%
  }{%
    \pgfrect@orig[stroke]%
  }%
}
%
\redef\pgfcircle{%
  \@ifnextchar[{%
    \pgfcircle@orig%
  }{%
    \pgfcircle@orig[stroke]%
  }%
}
%
\redef\pgfellipse{%
  \@ifnextchar[{%
    \pgfellipse@orig%
  }{%
    \pgfellipse@orig[stroke]%
  }%
}

%
% Make the mode parameter of node commands default to "stroke"
% 
\redef\pgfnodecircle#1{%
  \@ifnextchar[{%
    \pgfnodecircle@orig{#1}%
  }{%
    \pgfnodecircle@orig{#1}[stroke]%
  }%
}
\redef\pgfnoderect#1{%
  \@ifnextchar[{%
    \pgfnoderect@orig{#1}%
  }{%
    \pgfnoderect@orig{#1}[stroke]%
  }%
}
% fix missing global def of nodes
\newcommand{\pgfmakeglobal}[1]{%
  \expandafter\pgf@makeglobal\csname#1\endcsname
}
\newcommand{\pgf@makeglobal}[1]{%
  \global\let#1=#1%
}
\redef\pgfnodecircle@orig#1[#2]#3#4{%
  \pgfnodecircle@orig@orig{#1}[#2]{#3}{#4}%
  \pgfmakeglobal{pgfno@#1}%
  \pgfmakeglobal{pgfnob@#1}%
  \pgfmakeglobal{pgfnom@#1}%
  \ignorespaces
}
\redef\pgfnoderect@orig#1[#2]#3#4{%
  \pgfnoderect@orig@orig{#1}[#2]{#3}{#4}%
  \pgfmakeglobal{pgfno@#1}%
  \pgfmakeglobal{pgfnob@#1}%
  \pgfmakeglobal{pgfnom@#1}%
  \ignorespaces
}
%
\redef\pgfnodebox#1{%
  \@ifnextchar[{%
    \pgf@nodebox{#1}%
  }{%
    \pgf@nodebox{#1}[stroke]%
  }%
}
% Can't reuse \pgfnodebox@orig since it draws the noderect *after*
% drawing the text box, so the text is obscured if the mode is fill!
% 
% \chkdef\pgf@nodebox#1[#2]#3#4#5#6{%
%   \pgfnodebox@orig{#1}[#2]{#3}{\expandafter\color\pgf@textcolor#4}{#5}{#6}%
% }
\chkdef\pgf@nodebox#1[#2]#3#4#5#6{%
  \setbox\pgf@hbox=\hbox{\expandafter\color\pgf@textcolor#4}%
  \pgf@x=\wd\pgf@hbox%
  \pgf@y=\ht\pgf@hbox%
  \advance\pgf@x by #5\relax%
  \advance\pgf@x by #5\relax%
  \advance\pgf@y by #6\relax%
  \advance\pgf@y by #6\relax%
  \edef\pgf@boxsize{\noexpand\pgf@x=\the\pgf@x\noexpand\pgf@y=\the\pgf@y}%
  \pgfnoderect{#1}[#2]{#3}{\pgf@boxsize}%
  \csname pgf@haligncenter\endcsname%
  \csname pgf@valigncenter\endcsname%
  \wd\pgf@hbox=0pt%
  \pgfputat{#3}{%
  \pgfsys@starthbox%
  \box\pgf@hbox%
  \pgfsys@endhbox}%
  \ignorespaces
}

%
% Make the text alignement default to left,base for \pgfbox
% 
\redef\pgfbox{%
  \@ifnextchar[{%
    \pgf@box%
  }{%
    \pgf@box[left,base]%
  }%
}
% + add last optional argument to have opaque text
\chkdef\pgf@box[#1,#2]#3{%
  \@ifnextchar[{%
    \pgf@@box[#1,#2]{#3}%
  }{%
    \pgf@@box[#1,#2]{#3}[]%
  }%
}
\chkdef\pgf@@box[#1,#2]#3[#4]{%
  \if |#4|%
  \else
    \pgfbox@orig[#1,#2]{%
      \kern-\fboxsep
      \expandafter\colorbox\pgf@backcolor{\expandafter\color\pgf@backcolor#3}%
     }%
  \fi
  \pgfbox@orig[#1,#2]{\expandafter\color\pgf@textcolor#3}%
}

%
% Put labels halfway by default
% 
\redef\pgfnodelabel#1#2{%
  \@ifnextchar[{%
    \pgf@nodelabel{#1}{#2}%
  }{%
    \pgf@nodelabel{#1}{#2}[0.5]%
  }%
}
% with a default vertical offset of 0pt
\chkdef\pgf@nodelabel#1#2[#3]{%
  \@ifnextchar[{%
    \pgf@@nodelabel{#1}{#2}[#3]%
  }{%
    \pgf@@nodelabel{#1}{#2}[#3][0pt]%
  }%
}
\chkdef\pgf@@nodelabel#1#2[#3][#4]#5{%
  \pgfnodelabel@orig{#1}{#2}[#3][#4]{\expandafter\color\pgf@textcolor#5}%
}
%
% Same thing for rotated labels
% 
\redef\pgfnodelabelrotated#1#2{%
  \@ifnextchar[{%
    \pgf@nodelabelrotated{#1}{#2}%
  }{%
    \pgf@nodelabelrotated{#1}{#2}[0.5]%
  }%
}
\chkdef\pgf@nodelabelrotated#1#2[#3]{%
  \@ifnextchar[{%
    \pgf@@nodelabelrotated{#1}{#2}[#3]%
  }{%
    \pgf@@nodelabelrotated{#1}{#2}[#3][0pt]%
  }%
}
\chkdef\pgf@@nodelabelrotated#1#2[#3][#4]#5{%
  \pgfnodelabelrotated@orig{#1}{#2}[#3][#4]{\expandafter\color\pgf@textcolor#5}%
}

%%%%%%%%%%%%%%
% PGF colors
%%%%%%%%%%%%%%
%
% Set one of the pgf colors
% 
% \pgfsetcolor{pgfcolor}<color spec>
% 
% <color spec> is a color specification as defined by the color package. 
% It may be a color name or a [model]{spec} color specification.
% 
% pgfcolor is one of:
%   fill   : to define the fill color
%   stroke : to define the stroke color
%   text   : to define the color of text
%   back   : to define the background color for opaque text
% 
% The default values are:
%   fill   = black
%   stroke = black
%   text   = black
%   back   = white
% what yields the same behavior as pgf without the pgfmore package.
% 
\newcommand{\pgfsetcolor}[1]{%
  \@ifnextchar[{%
    \pgf@setmodelcolor{#1}%
  }{%
    \pgf@setnamedcolor{#1}%
  }
}
\newcommand{\pgf@setnamedcolor}[2]{%
  \expandafter\chgdef\csname pgf@#1color\endcsname{{#2}}%
  \ignorespaces
}
\chkdef\pgf@setmodelcolor#1[#2]#3{%
  \expandafter\chgdef\csname pgf@#1color\endcsname{[#2]{#3}}%
  \ignorespaces
}

\pgfsetcolor{fill}{black}
\pgfsetcolor{stroke}{black}
\pgfsetcolor{text}{black}
\pgfsetcolor{back}{white}


%%%%%%%%%%%%%%%%
% New commands %
%%%%%%%%%%%%%%%%

%
% Command to set picture units easily
%
\newcommand{\pgfsetxunit}[1]{%
  \pgfsetxvec{\pgfpoint{#1}{0pt}}%
}
\newcommand{\pgfsetyunit}[1]{%
  \pgfsetyvec{\pgfpoint{0pt}{#1}}%
}
\newcommand{\pgfsetunit}[1]{%
  \pgfsetxunit{#1}%
  \pgfsetyunit{#1}%
}

% Some temporaries
\chkdef{\pgf@temppointa}{}
\chkdef{\pgf@temppointb}{}
\chkdef{\pgf@testa}{}
\chkdef{\pgf@testb}{}
\chkdef{\pgf@transform}{}
\chkdef{\pgf@cmda}{}
\chkdef{\pgf@cmdb}{}
\chkdef{\pgf@cmdc}{}
\chkdef{\pgf@cmdd}{}

%
% Set a point for later reuse.
% 
% \pgfsetpoint[global]{command}{point}
% 
% If the optional "global" argument is present, the point
% will be defined globally.
% 
\newcommand{\pgfsetpoint}[3][]{%
  \let\next\edef
  \if |#1|%
  \else
    \let\next\xdef
  \fi
  #3%
  \expandafter\next\expandafter#2\expandafter{%
    \noexpand\pgf@x=\the\pgf@x\relax\noexpand\pgf@y=\the\pgf@y\relax
  }\ignorespaces
}

%
% Compute a vector which is perpendicular to and of same length
% as the vector from point A to point B.
% 
% \pgfdiff and \pgfperp form an orthonormal direct referential.
% 
% \pgfperp{point A}{point B}
% 
\newcommand{\pgfperp}[2]{%
  \pgf@process{#1}%
  \pgf@xa=\pgf@y%
  \pgf@ya=-\pgf@x%
  \pgf@process{#2}%
  \advance\pgf@xa by-\pgf@y\relax%
  \advance\pgf@ya by\pgf@x\relax%
  \pgf@x=\pgf@xa\pgf@y=\pgf@ya\relax\ignorespaces
}

%
% Compute the tangent of an angle in degrees
% 
% \pgftan{angle}
% 
% x  : sin
% y  : cos
% xa : tan
% 
\newcommand{\pgftan}[1]{%
  \pgfsincos{#1}%
  % casting a dimen to a number yields 65536 times the value 
  % of the dimen in pt. 65536 = 4*16384
  \pgf@xa=16384\pgf@x\relax % 16384 sin
  \pgf@ya=0.25\pgf@y\relax  % cos/4
  \divide\pgf@xa by \pgf@ya % 16384 sin / 65536(cos/4) = sin/cos
}

%
% Find options and execute code for each option found
% 
% #1 = option description
%      list of pairs <option,action>
% #2 = effective options
% 
% \pgfgetopt{{o\pgf@opaque@labeltrue}{r\pgf@rotated@labeltrue}}{op}
% will execute \pgf@opaque@labeltrue since 'o' is present in the
% second argument. It won't execute \pgf@rotated@labeltrue since
% 'r' is not in the second argument. The 'p' in the second argument
% will be ignored since no command is associated to it.
% 
\newcommand{\pgfgetopt}[2]{%
  \pgf@parseopts{#1}#2\end
}
% Handle each option in turn
\chkdef\pgf@parseopts#1#2{%
  \ifx #2\end
    \let\next=\@gobble
  \else
    \pgf@lookup@opt{#2}#1\end
    \let\next=\pgf@parseopts
  \fi
  \next{#1}%
}
% look up the action associated to an option
\chkdef\pgf@lookup@opt#1#2{%
  \ifx #2\end
    \let\next=\@gobble
  \else
    \pgf@checkopt{#1}#2\end%
    \let\next=\pgf@lookup@opt
  \fi
  \next{#1}%
}
\chkdef\pgf@checkopt#1#2#3\end{%
  \edef\pgf@testa{#1}%
  \edef\pgf@testb{#2}%
  \ifx\pgf@testa\pgf@testb
    #3% execute the action
  \fi
}

%
% Stroke or fill a polyline
% 
% \pgfxypolyline[mode]{(x1,y1)...(xi,yi)...(xn,yn)}
% 
% mode defaults to "stroke".
% 
% "virtual" mode may be used to insert a polyline into the current path
% 
\newcommand{\pgfxypolyline}[2][stroke]{%
  \pgf@xypolyline[#1]{#2}%
}
\chkdef\pgf@xypolyline[#1]#2{%
  \pgf@xypolyline@core[#1]#2\end
}
\chkdef\pgf@xypolyline@core[#1](#2,#3){%
  \pgfmoveto{\pgfxy(#2,#3)}%
  \pgf@buildpath{#1}% handle remaining points
}
\newcommand{\pgf@buildpath}[2]{
  \ifx #2\end
    \let\next\pgf@drawpath
  \else
    \let\next\pgf@addpoint
  \fi
  \next{#1}%
}
\chkdef\pgf@addpoint#1#2,#3){%
  \pgflineto{\pgfxy(#2,#3)}%
  \pgf@buildpath{#1}%
}
\newcommand{\pgf@drawpath}[1]{%
  \edef\pgf@testa{virtual}%
  \edef\pgf@testb{#1}%
  \ifx\pgf@testa\pgf@testb
  \else
    \csname pgf#1\endcsname
  \fi
  \ignorespaces
}
%
% Associate text to a node
% 
% \pgfnodetext[xoff,yoff]{node}{text}[opaque]
% 
% The optional "xoff,yoff" argument gives the offset of the text
% from the center of the node. It defaults to 0pt,0pt.
% 
% If the optional "opaque" argument is present, the text will
% be opaque.
% 
\newcommand{\pgfnodetext}[3][0pt,0pt]{%
  \@ifnextchar[{%
    \pgf@nodetext{#1}{#2}{#3}%
  }{%
    \pgf@nodetext{#1}{#2}{#3}[]%
  }%
}
\chkdef\pgf@nodetext#1#2#3[#4]{%
  \pgf@parsepoint[#1]%
  \pgfputat{\pgfrelative{\pgfnodecenter{#2}}{\pgf@temppointa}}{%
    \if |#4|%
    \else
      \pgfbox[center,center]{%
        \expandafter\colorbox\pgf@backcolor{\expandafter\color\pgf@backcolor#3}%
      }%
    \fi
    \pgfbox[center,center]{\expandafter\color\pgf@textcolor#3}%
  }\ignorespaces
}
\chkdef\pgf@parsepoint[#1,#2]{%
  \pgfsetpoint{\pgf@temppointa}{\pgfpoint{#1}{#2}}%
}

%
% Put text at the border of a node.
% 
% \pgfbordernodetext[offset]{node}{direction}[options]{text}
% 
% Direction is one of n,ne,e,se,s,sw,w,nw
% The optional offset parameter allows to offset the text
% from the border of the node. It defaults to 0pt.
% The optional options parameter may contain:
%   o  to get an opaque label
%   r  to get a rotated label (perpendicular to "direction")
% The default is to have transparent horizontal labels.
\newif\ifpgf@rotated@label
\newif\ifpgf@opaque@label
\newcommand{\pgfbordernodetext}[3][0pt]{%
  \@ifnextchar[{%
    \pgf@bordernodetext{#1}{#2}{#3}%
  }{%
    \pgf@bordernodetext{#1}{#2}{#3}[]%
  }%
}
\chkdef\pgf@bordernodetext#1#2#3[#4]#5{%
  \pgf@opaque@labelfalse  % default settings
  \pgf@rotated@labelfalse
  \pgfgetopt{{o\pgf@opaque@labeltrue}{r\pgf@rotated@labeltrue}}{#4}%
  \ifpgf@rotated@label % compute the parameters of the rotation
    \pgfsincos{\pgfdirection{#3}}%
    \pgf@xa=\pgf@x\pgf@ya=-\pgf@y\relax
    \pgf@xb=\pgf@y\pgf@yb=\pgf@x\relax
    \edef\pgf@cmda{\pgfget{xa}}%
    \edef\pgf@cmdb{\pgfget{ya}}%
    \edef\pgf@cmdc{\pgfget{xb}}%
    \edef\pgf@cmdd{\pgfget{yb}}%
    \def\pgf@transform{%
      \pgfsys@transform{\pgf@cmda}{\pgf@cmdb}%
                       {\pgf@cmdc}{\pgf@cmdd}{0}{0}%
    }%
  \else
    \let\pgf@transform\relax % no rotation
    \def\pgf@cmda{0}%
  \fi
  \ifpgf@opaque@label
    \pgfputat{\pgfnodeborder{#2}{\pgfdirection{#3}}{#1}}{%
      \pgf@transform
      \pgfbox[center,center]{% background for the label
        \kern-\pgf@cmda\fboxsep
        \expandafter\colorbox\pgf@backcolor{\expandafter\color\pgf@backcolor#5}%
      }%
    }%
  \fi
  \pgfputat{\pgfnodeborder{#2}{\pgfdirection{#3}}{#1}}{%
    \pgf@transform
    \pgfbox[center,center]{\expandafter\color\pgf@textcolor#5}% label
  }%
}

%
% Put an (opaque) label on an edge between two nodes
% 
% \pgfedgelabel[options]{node1}[fraction of way]{node2}[offset]{text}
% 
% "options" my contain the following characters:
%    o for an opaque label: the bouding box of the
%      text will be filled with the background color 
%      (useful when the label is over the edge or another node)
% 
%    r for a rotated label (baseline aligned with the edge)
% The default is a transparent horizontal label.
% 
% If "fraction of way" is omitted, it will default to 0.5 (halfway).
% 
% The optional "offset" parameter is a length that will be used to offset 
% the label from the edge. It defaults to 0pt.
% 
\newcommand{\pgfedgelabel}[2][]{%
  \@ifnextchar[{%
    \pgf@edgelabel[#1]{#2}%
  }{%
    \pgf@edgelabel[#1]{#2}[0.5]%
  }
}
\chkdef\pgf@edgelabel[#1]#2[#3]#4{%
  \@ifnextchar[{%
    \pgf@@edgelabel[#1]{#2}[#3]{#4}%
  }{%
    \pgf@@edgelabel[#1]{#2}[#3]{#4}[0pt]%
  }%
}
\chkdef\pgf@@edgelabel[#1]#2[#3]#4[#5]#6{%
  \pgf@opaque@labelfalse  % default settings
  \pgf@rotated@labelfalse
  \pgfgetopt{{o\pgf@opaque@labeltrue}{r\pgf@rotated@labeltrue}}{#1}%
  \pgfnormalise{\pgfperp{\pgfnodecenter{#2}}{\pgfnodecenter{#4}}}%
  \pgfsetpoint{\pgf@temppointb}{% perpendical offset from edge
    \pgf@xa=#5\relax
    \pgf@x=\pgfget x\pgf@xa\relax\pgf@y=\pgfget y\pgf@xa\relax
  }
  \pgfsetpoint{\pgf@temppointa}{% compute position of label
    \pgfrelative{%
      \pgfpartway{#3}{%
         \pgfnodeconnstart[\pgf@nodesepstart]{#2}{#4}%
       }{%
         \pgfnodeconnstart[\pgf@nodesepend]{#4}{#2}%
       }%
     }{\pgf@temppointb}%
  }%
  \ifpgf@rotated@label  % compute rotation parameters
    \pgfnormalise{%
      \pgfdiff{\pgfnodeconnstart[\pgf@nodesepstart]{#2}{#4}}%
              {\pgfnodeconnstart[\pgf@nodesepend]{#4}{#2}}%
      }%
      \edef\pgf@cmda{\pgfget y}%
      \edef\pgf@cmdb{\pgfget x}%
      \pgf@x=-\pgf@x\relax
      \edef\pgf@cmdc{\pgfget x}%
      \edef\pgf@cmdd{\pgfget y}%
      \def\pgf@transform{%
        \pgfsys@transform{\pgf@cmda}{\pgf@cmdb}%
                         {\pgf@cmdc}{\pgf@cmdd}{0}{0}%
      }%
  \else
    \let\pgf@transform\relax % no rotation
    \def\pgf@cmda{0}%
  \fi
  \ifpgf@opaque@label
    \pgfputat{\pgf@temppointa}{%
      \pgf@transform
      \pgfbox[center,center]{% label opaque background
        \kern-\pgf@cmda\fboxsep
        \expandafter\colorbox\pgf@backcolor{\expandafter\color\pgf@backcolor#6}%
      }%
    }%
  \fi
  \pgfputat{\pgf@temppointa}{%
    \pgf@transform
    \pgfbox[center,center]{\expandafter\color\pgf@textcolor#6}% label
  }%
}

%
% Draw a bow between node1 and node2. The bow is a bezier curve with
% control points that are frac1 and frac2 partway between the nodes
% and deviation sideway from the node1->node2 axis. If deviation is 
% positive, the bow deviates to the left of the axis. It deviates to 
% the right if deviation is negative.
% 
% The first argument is optional and defaults to 0.4,0.6
% 
% \pgfnodebow[frac1,frac2]{node1}{node2}{deviation}
% 
\newcommand{\pgfnodebow}[4][0.4,0.6]{%
  \pgf@computebow{#1}{#2}{#3}{#4}%
  \pgfmoveto{%
    \csname pgfno@#2\endcsname[\pgf@nodesepstart]%
      {\pgfnodecenter{#2}}%
      {\pgf@temppointa}%
  }%
  \pgfcurveto{\pgf@temppointa}{\pgf@temppointb}%
             {\csname pgfno@#3\endcsname[\pgf@nodesepend]%
               {\pgfnodecenter{#3}}%
               {\pgf@temppointb}%
             }%
  \pgfstroke\ignorespaces
}
\newcommand{\pgf@computebow}[4]{%
  \pgf@parsewayfracs#1\end
  \begin{pgfscope}% new referential with xvec=node1node2
    \pgfsetxvec{\pgfdiff{\pgfnodecenter{#2}}{\pgfnodecenter{#3}}}%
    \pgfsetyvec{\pgfperp{\pgfnodecenter{#2}}{\pgfnodecenter{#3}}}%
    \pgfsetpoint[global]{\pgf@temppointa}{%
      \pgfrelative{\pgfnodecenter{#2}}{\pgfxy(\pgf@cmda,#4)}%
    }%
    \pgfsetpoint[global]{\pgf@temppointb}{%
      \pgfrelative{\pgfnodecenter{#2}}{\pgfxy(\pgf@cmdb,#4)}%
    }%
  \end{pgfscope}%
}
\chkdef\pgf@parsewayfracs#1,#2\end{%
  \chgdef\pgf@cmda{#1}%
  \chgdef\pgf@cmdb{#2}%
}

%
% Put a label on a bow between nodes
% 
% \pgfnodebowlabel[frac1,frac2]{node1}{node2}{deviation}[options]{text}
% 
% The optional options may contain:
%   o  for an opaque label
%   r  for a rotated label
% 
\newcommand{\pgfnodebowlabel}[4][0.4,0.6]{%
  \@ifnextchar[{\pgf@nodebowlabel{#1}{#2}{#3}{#4}}%
               {\pgf@nodebowlabel{#1}{#2}{#3}{#4}[]}
}
\chkdef\pgf@nodebowlabel#1#2#3#4[#5]#6{%
  \pgf@opaque@labelfalse
  \pgf@rotated@labelfalse
  \pgfgetopt{{o\pgf@opaque@labeltrue}{r\pgf@rotated@labeltrue}}{#5}%
  \pgf@computebow{#1}{#2}{#3}{#4}%
  \ifpgf@rotated@label
    \pgfnormalise{\pgfdiff{\pgf@temppointa}{\pgf@temppointb}}%
    \edef\pgf@cmda{\pgfget x}%
    \edef\pgf@cmdb{\pgfget y}%
    \pgf@y=-\pgf@y\relax
    \edef\pgf@cmdc{\pgfget y}%
    \edef\pgf@cmdd{\pgfget x}%
    \def\pgf@transform{%
      \pgfsys@transform{\pgf@cmda}{\pgf@cmdb}%
                       {\pgf@cmdc}{\pgf@cmdd}{0}{0}%
    }%
  \else
    \let\pgf@transform\relax
    \def\pgf@cmda{0}%
  \fi
  \pgfsetpoint{\pgf@temppointa}{%
    \pgfpartway{0.5}{\pgf@temppointa}{\pgf@temppointb}%
  }%
  \ifpgf@opaque@label
    \pgfputat{\pgf@temppointa}{%
      \pgf@transform
      \pgfbox[center,center]{%
        \kern-\pgf@cmda\fboxsep
        \expandafter\colorbox\pgf@backcolor{\expandafter\color\pgf@backcolor#6}%
      }%
    }%
  \fi
  \pgfputat{\pgf@temppointa}{%
    \pgf@transform
    \pgfbox[center,center]{\expandafter\color\pgf@textcolor#6}%
  }%
}

%
% Connect a node to itself with a loop
% 
% \pgfnodeconnloop{node}{half loop angle}(looptopx,looptopy)
% 
% The loop will be directed toward the relative point (looptopx,looptopy),
% and the control points of the bezier curve will be "half top angle" apart
% on each side of the node->looptop axis.
% 
\chkdef\pgfnodeconnloop#1#2(#3,#4){%
  \ifnum#2>80\relax % avoid arithmetic overflow when computing tangent
    \PackageWarning{pgfmore}{%
      Half-loop angle #2 is too large. \MessageBreak Using 80 degrees instead
    }%
    \pgf@computenodeloop{#1}{80}{#3}{#4}%
  \else
    \pgf@computenodeloop{#1}{#2}{#3}{#4}%
  \fi
  \pgfmoveto{%
    \csname pgfno@#1\endcsname[\pgf@nodesepstart]%
      {\pgfnodecenter{#1}}{\pgf@temppointa}%
  }%
  \pgfcurveto{\pgf@temppointa}{\pgf@temppointb}%
             {\csname pgfno@#1\endcsname[\pgf@nodesepend]%
               {\pgfnodecenter{#1}}{\pgf@temppointb}%
             }%
  \pgfstroke
  \ignorespaces
}

\newcommand{\pgf@computenodeloop}[4]{%
  \begin{pgfscope}
    \pgfsetpoint{\pgf@temppointa}{%
      \pgfrelative{\pgfnodecenter{#1}}{\pgfxy(#3,#4)}%
    }%
    \pgfsetxvec{\pgfdiff{\pgfnodecenter{#1}}{\pgf@temppointa}}%
    \pgfsetyvec{\pgfperp{\pgfnodecenter{#1}}{\pgf@temppointa}}%
    \pgftan{#2}%
    \edef\pgf@cmda{\pgfget{xa}}%
    \pgfsetpoint[global]{\pgf@temppointa}{%
      \pgfrelative{\pgfnodecenter{#1}}{\pgfxy(1,-\pgf@cmda)}%
    }%
    \pgfsetpoint[global]{\pgf@temppointb}{%
      \pgfrelative{\pgfnodecenter{#1}}{\pgfxy(1,\pgf@cmda)}%
    }%
  \end{pgfscope}%
}

%
% Put a label on a node loop.
% 
% \pgfnodelooplabel{node}[fraction](looptopx,looptopy)[options]{text}
% 
% (looptopx,looptopy) is the direction into which the loop goes.
% 
% The optional "fraction" argument gives the fraction of the distance 
% from the center of the node to (looptopx, looptopy) at which the 
% label will be put. It defaults to 1.
% 
% The optional "options" may contain:
%   o  to get an opaque label
%   r  to get a rotated label (default)
%   n  to get a "normal" (not rotated) label
% 
\newcommand{\pgfnodelooplabel}[1]{%
  \@ifnextchar[{%
    \pgf@nodelooplabel{#1}%
  }{%
    \pgf@nodelooplabel{#1}[1]%
  }%
}
\chkdef\pgf@nodelooplabel#1[#2](#3,#4){%
  \@ifnextchar[{%
    \pgf@@nodelooplabel{#1}[#2](#3,#4)%
  }{%
    \pgf@@nodelooplabel{#1}[#2](#3,#4)[]%
  }%
}
\chkdef\pgf@@nodelooplabel#1[#2](#3,#4)[#5]#6{%
  \pgf@opaque@labelfalse
  \pgf@rotated@labeltrue
  \pgfgetopt{%
    {o\pgf@opaque@labeltrue}%
    {r\pgf@rotated@labeltrue}%
    {n\pgf@rotated@labelfalse}%
  }{#5}%
  \ifpgf@rotated@label
    \pgfnormalise{\pgfxy(#3,#4)}%
    \edef\pgf@cmda{\pgfget y}%
    \edef\pgf@cmdc{\pgfget x}%
    \edef\pgf@cmdd{\pgfget y}%
    \pgf@x=-\pgf@x\relax
    \edef\pgf@cmdb{\pgfget x}%
    \def\pgf@transform{%
      \pgfsys@transform{\pgf@cmda}{\pgf@cmdb}%
                       {\pgf@cmdc}{\pgf@cmdd}{0}{0}%
    }%
  \else
    \let\pgf@transform\relax
    \def\pgf@cmda{0}%
  \fi
  \ifpgf@opaque@label
    \pgfputat{%
      \pgfpartway{#2}{\pgfnodecenter{#1}}%
                     {\pgfrelative{\pgfnodecenter{#1}}{\pgfxy(#3,#4)}}%
    }{%
      \pgf@transform
      \makebox[0pt][c]{%
        \kern-\pgf@cmda\fboxsep
        \expandafter\colorbox\pgf@backcolor{\expandafter\color\pgf@backcolor#6}%
      }%
    }%
  \fi
  \pgfputat{%
    \pgfpartway{#2}{\pgfnodecenter{#1}}%
                   {\pgfrelative{\pgfnodecenter{#1}}{\pgfxy(#3,#4)}}%
  }{%
    \pgf@transform
    \makebox[0pt][c]{\expandafter\color\pgf@textcolor#6}%
  }%
  \ignorespaces
}

\endinput
