% corasdiagram package runtime.
% - The shipped package version is mirrored from corasdiagram-version.tex.
% - The \ProvidesPackage date must match the current CHANGELOG.md release date;
%   tools/check_release_tag.py enforces that before tagged releases.
% - Canonical icon sources live in assets/icons-src/ and generated runtime
%   assets live in icons/.
% - Contributor workflow, release procedure, and local verification commands
%   are documented in CONTRIBUTING.md at the repository root.
\NeedsTeXFormat{LaTeX2e}
\def\corasdiagramversion{0.0.0}
\InputIfFileExists{corasdiagram-version.tex}{}{}
\ProvidesPackage{corasdiagram}[2026/03/28 v\corasdiagramversion CORAS diagram package]

\RequirePackage{graphicx}
\RequirePackage{array}
\RequirePackage{longtable}
\RequirePackage{pgfkeys}
\RequirePackage{tikz}
\RequirePackage{xparse}
\usetikzlibrary{arrows.meta,calc,decorations.markings,fit,positioning,shapes.geometric}
\pgfdeclarelayer{corasbackground}
\pgfsetlayers{corasbackground,main}

\makeatletter

\def\corasdiagram@iconsdirname{icons}
\def\corasdiagram@iconfileprefix{corasdiagram-}
\edef\corasdiagram@iconspath{\@currpath\corasdiagram@iconsdirname}
\def\corasdiagram@iconsuffix{}

\pgfkeys{
  /corasdiagram/package/.is family,
  /corasdiagram/package,
  iconset/.code={%
    \def\corasdiagram@optionvalue{#1}%
    \def\corasdiagram@optioncolor{color}%
    \def\corasdiagram@optionbw{bw}%
    \ifx\corasdiagram@optionvalue\corasdiagram@optioncolor
      \def\corasdiagram@iconsuffix{}%
    \else\ifx\corasdiagram@optionvalue\corasdiagram@optionbw
      \def\corasdiagram@iconsuffix{_bw}%
    \else
      \PackageError{corasdiagram}{Unknown iconset `#1'}{Use `iconset=color` or `iconset=bw`.}%
    \fi\fi
  },
  icons-path/.store in=\corasdiagram@iconspath,
}

\def\corasdiagram@parsepackageoption#1=#2\@nil{%
  \def\corasdiagram@optionkey{#1}%
  \def\corasdiagram@optionvalue{#2}%
}

\DeclareOption*{%
  \edef\corasdiagram@packageoption{\CurrentOption}%
  \expandafter\corasdiagram@parsepackageoption\corasdiagram@packageoption\@nil
  \def\corasdiagram@keyiconset{iconset}%
  \def\corasdiagram@keyiconspath{icons-path}%
  \ifx\corasdiagram@optionkey\corasdiagram@keyiconset
    \def\corasdiagram@optioncolor{color}%
    \def\corasdiagram@optionbw{bw}%
    \ifx\corasdiagram@optionvalue\corasdiagram@optioncolor
      \def\corasdiagram@iconsuffix{}%
    \else\ifx\corasdiagram@optionvalue\corasdiagram@optionbw
      \def\corasdiagram@iconsuffix{_bw}%
    \else
      \PackageError{corasdiagram}{Unknown iconset `\corasdiagram@optionvalue'}{Use `iconset=color` or `iconset=bw`.}%
    \fi\fi
  \else\ifx\corasdiagram@optionkey\corasdiagram@keyiconspath
    \edef\corasdiagram@iconspath{\corasdiagram@optionvalue}%
  \else
    \PackageError{corasdiagram}{Unknown package option `\CurrentOption'}{Supported options are `iconset=<color|bw>` and `icons-path=<path>`.}%
  \fi\fi
}
\ProcessOptions\relax

\tikzset{
  corasdiagram/.style={
    font=\sffamily\footnotesize,
    every node/.style={font=\sffamily\footnotesize,align=center},
    >=Latex,
    min edge gap=8mm
  },
  layout/.code={\def\corasdiagram@layoutmode{#1}},
  min edge gap/.code={\def\corasdiagram@layoutmingap{#1}},
  coras/asset diagram/.style={},
  coras/threat diagram/.style={},
  coras/risk diagram/.style={},
  coras/treatment diagram/.style={},
  coras/treatment overview diagram/.style={},
  coras/base node/.style={
    draw=none,
    inner sep=0pt,
    outer sep=0pt,
    align=center
  },
  coras/invisible anchor/.style={
    draw=none,
    fill=none,
    inner sep=0pt,
    outer sep=0pt
  },
  coras/anchor ellipse/.style={
    coras/invisible anchor,
    ellipse
  },
  coras/anchor rectangle/.style={
    coras/invisible anchor,
    rectangle
  },
  coras/box/.style={
    draw,
    rectangle,
    fill=white,
    line width=0.45pt,
    inner xsep=4pt,
    inner ysep=3pt,
    outer sep=1pt,
    align=center
  },
  coras/ellipse/.style={
    draw,
    ellipse,
    fill=white,
    line width=0.45pt,
    inner xsep=5pt,
    inner ysep=3pt,
    outer sep=1pt,
    align=center
  },
  coras/incident body/.style={
    coras/box,
    minimum height=8mm
  },
  coras/risk body/.style={
    coras/box,
    minimum height=11mm
  },
  coras/treatment body/.style={
    coras/ellipse,
    fill=white,
    minimum height=9mm
  },
  coras/junction/.style={
    circle,
    draw,
    fill=white,
    line width=0.45pt,
    minimum size=3.3mm,
    inner sep=0pt,
    outer sep=1pt
  },
  coras/scope base/.style={
    draw,
    rectangle,
    fill=black!2,
    line width=0.45pt,
    inner sep=7mm,
    outer sep=0pt
  },
  coras/scope system/.style={coras/scope base},
  coras/scope asset-scope/.style={
    coras/scope base,
    fill=white,
    rounded corners=4mm
  },
  coras/scope analysis/.style={coras/scope base},
  coras/scope risk-group/.style={coras/scope base},
  coras/scope treatment-scope/.style={coras/scope base},
  coras/scope title/.style={
    anchor=south west,
    inner sep=0pt,
    outer sep=0pt,
    font=\sffamily\footnotesize\bfseries
  },
  coras/open arrow/.style={
    postaction={decorate},
    decoration={
      markings,
      mark=at position 1 with {
        \draw[solid,line width=\pgflinewidth,line cap=round]
          (0,0) -- (-2.4mm,0.95mm);
        \draw[solid,line width=\pgflinewidth,line cap=round]
          (0,0) -- (-2.4mm,-0.95mm);
      }
    }
  },
  coras/risk ref box/.style={
    coras/box,
    minimum height=5mm,
    inner xsep=2.5pt,
    inner ysep=1.2pt,
    font=\sffamily\scriptsize
  },
  coras/causal/.style={
    draw,
    line width=0.45pt,
    coras/open arrow
  },
  coras/relation/.style={
    draw,
    line width=0.45pt,
    coras/open arrow
  },
  coras/concern/.style={
    draw,
    dashed,
    line width=0.45pt,
    coras/open arrow
  },
  coras/association/.style={
    draw,
    dashed,
    line width=0.45pt,
    coras/open arrow
  },
  coras/treatment/.style={
    draw,
    dashed,
    line width=0.45pt,
    coras/open arrow
  },
  coras/overview/.style={
    coras/treatment
  },
  coras/asset anchor/.style={
    coras/invisible anchor,
    shape=corasassetanchorshape
  },
  coras/indirect asset anchor/.style={
    coras/invisible anchor,
    shape=corasindirectassetanchorshape
  },
  coras/stakeholder anchor/.style={
    coras/invisible anchor,
    shape=corasstakeholderanchorshape
  },
  coras/threat accidental anchor/.style={
    coras/invisible anchor,
    shape=corasthreataccidentalanchorshape
  },
  coras/threat deliberate anchor/.style={
    coras/invisible anchor,
    shape=corasthreatdeliberateanchorshape
  },
  coras/threat nonhuman anchor/.style={
    coras/invisible anchor,
    shape=corasthreatnonhumananchorshape
  },
  coras/vulnerability anchor/.style={
    coras/invisible anchor,
    shape=corasvulnerabilityanchorshape
  },
}

\newcommand{\corasdiagram@setsymbolmetric}[3]{%
  \expandafter\def\csname corasdiagram@anchordata@#1@#2\endcsname{#3}%
}

\newcommand{\corasdiagram@setsymbolanchor}[4]{%
  \expandafter\def\csname corasdiagram@anchordata@#1@#2x\endcsname{#3}%
  \expandafter\def\csname corasdiagram@anchordata@#1@#2y\endcsname{#4}%
}

\newcommand{\corasdiagram@setsymboloutline}[2]{%
  \expandafter\def\csname corasdiagram@anchordata@#1@outline\endcsname{#2}%
}

\newcommand{\corasdiagram@getsymbolmetric}[3]{%
  \expandafter\ifcsname corasdiagram@anchordata@#1@#2\endcsname
    \edef#3{\csname corasdiagram@anchordata@#1@#2\endcsname}%
  \else
    \let#3\@empty
  \fi
}

\newcommand{\corasdiagram@setsymbolpoint}[2]{%
  \expandafter\ifcsname corasdiagram@anchordata@#1@#2x\endcsname
    \pgf@x=\dimexpr\csname corasdiagram@anchordata@#1@#2x\endcsname\relax
    \pgf@y=\dimexpr\csname corasdiagram@anchordata@#1@#2y\endcsname\relax
  \else
    \pgf@x=0pt\relax
    \pgf@y=0pt\relax
  \fi
}

\newcommand{\corasdiagram@symbolpoint}[2]{%
  \pgfqpoint{%
    \csname corasdiagram@anchordata@#1@#2x\endcsname
  }{%
    \csname corasdiagram@anchordata@#1@#2y\endcsname
  }%
}

\newcommand{\corasdiagram@symbolbodycenter}[1]{%
  \pgf@x=0pt\relax
  \pgf@y=0pt\relax
}

\newcommand{\corasdiagram@symboltextanchor}[1]{%
  \pgf@x=0pt\relax
  \pgf@y=0pt\relax
}

\newcommand{\corasdiagram@symbolbaseanchor}[1]{%
  \pgf@x=0pt\relax
  \pgf@y=\dimexpr\csname corasdiagram@anchordata@#1@basey\endcsname\relax
}

\newcommand{\corasdiagram@symbolmidanchor}[1]{%
  \pgf@x=0pt\relax
  \pgf@y=\dimexpr\csname corasdiagram@anchordata@#1@midy\endcsname\relax
}

\newcommand{\corasdiagram@symbolbaseeastanchor}[1]{%
  \pgf@x=\dimexpr\csname corasdiagram@anchordata@#1@bodyhalfx\endcsname\relax
  \pgf@y=\dimexpr\csname corasdiagram@anchordata@#1@basey\endcsname\relax
}

\newcommand{\corasdiagram@symbolbasewestanchor}[1]{%
  \pgf@x=-\dimexpr\csname corasdiagram@anchordata@#1@bodyhalfx\endcsname\relax
  \pgf@y=\dimexpr\csname corasdiagram@anchordata@#1@basey\endcsname\relax
}

\newcommand{\corasdiagram@symbolmideastanchor}[1]{%
  \pgf@x=\dimexpr\csname corasdiagram@anchordata@#1@bodyhalfx\endcsname\relax
  \pgf@y=\dimexpr\csname corasdiagram@anchordata@#1@midy\endcsname\relax
}

\newcommand{\corasdiagram@symbolmidwestanchor}[1]{%
  \pgf@x=-\dimexpr\csname corasdiagram@anchordata@#1@bodyhalfx\endcsname\relax
  \pgf@y=\dimexpr\csname corasdiagram@anchordata@#1@midy\endcsname\relax
}

\newcommand{\corasdiagram@symboloutlinepath}[1]{%
  \pgfpathmoveto{\corasdiagram@symbolpoint{#1}{north}}%
  \pgfpathlineto{\corasdiagram@symbolpoint{#1}{northeast}}%
  \pgfpathlineto{\corasdiagram@symbolpoint{#1}{east}}%
  \pgfpathlineto{\corasdiagram@symbolpoint{#1}{southeast}}%
  \pgfpathlineto{\corasdiagram@symbolpoint{#1}{south}}%
  \pgfpathlineto{\corasdiagram@symbolpoint{#1}{southwest}}%
  \pgfpathlineto{\corasdiagram@symbolpoint{#1}{west}}%
  \pgfpathlineto{\corasdiagram@symbolpoint{#1}{northwest}}%
  \pgfpathclose%
}

\newcommand{\corasdiagram@symbolborderintersection}[1]{%
  \pgf@xa=\pgf@x%
  \pgf@ya=\pgf@y%
  \pgfmathsetmacro{\corasdiagram@dx}{\the\pgf@xa}%
  \pgfmathsetmacro{\corasdiagram@dy}{\the\pgf@ya}%
  \corasdiagram@setsnappeddirectionalanchor
  \expandafter\corasdiagram@setsymbolpoint\expandafter{#1}{\corasdiagram@snappeddirectionalanchor}%
}

\newcommand{\corasdiagram@declareiconsymbolshape}[2]{%
  \pgfdeclareshape{#1}{%
    \savedanchor\centerpoint{\corasdiagram@symbolbodycenter{#2}}%
    \anchor{center}{\corasdiagram@symbolbodycenter{#2}}%
    \anchor{text}{\corasdiagram@symboltextanchor{#2}}%
    \anchor{base}{\corasdiagram@symbolbaseanchor{#2}}%
    \anchor{mid}{\corasdiagram@symbolmidanchor{#2}}%
    \anchor{base east}{\corasdiagram@symbolbaseeastanchor{#2}}%
    \anchor{base west}{\corasdiagram@symbolbasewestanchor{#2}}%
    \anchor{mid east}{\corasdiagram@symbolmideastanchor{#2}}%
    \anchor{mid west}{\corasdiagram@symbolmidwestanchor{#2}}%
    \anchor{north}{\corasdiagram@setsymbolpoint{#2}{north}}%
    \anchor{north east}{\corasdiagram@setsymbolpoint{#2}{northeast}}%
    \anchor{east}{\corasdiagram@setsymbolpoint{#2}{east}}%
    \anchor{south east}{\corasdiagram@setsymbolpoint{#2}{southeast}}%
    \anchor{south}{\corasdiagram@setsymbolpoint{#2}{south}}%
    \anchor{south west}{\corasdiagram@setsymbolpoint{#2}{southwest}}%
    \anchor{west}{\corasdiagram@setsymbolpoint{#2}{west}}%
    \anchor{north west}{\corasdiagram@setsymbolpoint{#2}{northwest}}%
    \anchorborder{\corasdiagram@symbolborderintersection{#2}}%
    \backgroundpath{\corasdiagram@symboloutlinepath{#2}}%
  }%
}

\newcommand{\corasdiagram@defineanchors@stakeholder}{%
  \corasdiagram@setsymbolmetric{stakeholder}{bodyhalfx}{1.9mm}%
  \corasdiagram@setsymbolmetric{stakeholder}{bodyhalfy}{4.4mm}%
  \corasdiagram@setsymbolmetric{stakeholder}{basey}{-3.7mm}%
  \corasdiagram@setsymbolmetric{stakeholder}{midy}{0.5mm}%
  \corasdiagram@setsymbolanchor{stakeholder}{north}{0.1mm}{7.6mm}%
  \corasdiagram@setsymbolanchor{stakeholder}{northeast}{3.25mm}{4.35mm}%
  \corasdiagram@setsymbolanchor{stakeholder}{east}{3.8mm}{0.1mm}%
  \corasdiagram@setsymbolanchor{stakeholder}{southeast}{3.15mm}{-4.85mm}%
  \corasdiagram@setsymbolanchor{stakeholder}{south}{-0.1mm}{-7.8mm}%
  \corasdiagram@setsymbolanchor{stakeholder}{southwest}{-1.75mm}{-4.8mm}%
  \corasdiagram@setsymbolanchor{stakeholder}{west}{-3.8mm}{-0.05mm}%
  \corasdiagram@setsymbolanchor{stakeholder}{northwest}{-2.95mm}{4.2mm}%
  \corasdiagram@setsymboloutline{stakeholder}{north,northeast,east,southeast,south,southwest,west,northwest}%
}

\newcommand{\corasdiagram@defineanchors@asset}{%
  \corasdiagram@setsymbolmetric{asset}{bodyhalfx}{4.15mm}%
  \corasdiagram@setsymbolmetric{asset}{bodyhalfy}{4.85mm}%
  \corasdiagram@setsymbolmetric{asset}{basey}{-3.9mm}%
  \corasdiagram@setsymbolmetric{asset}{midy}{0.35mm}%
  \corasdiagram@setsymbolanchor{asset}{north}{0mm}{5.9mm}%
  \corasdiagram@setsymbolanchor{asset}{northeast}{3.15mm}{1.15mm}%
  \corasdiagram@setsymbolanchor{asset}{east}{5.25mm}{-1.45mm}%
  \corasdiagram@setsymbolanchor{asset}{southeast}{3.9mm}{-4.05mm}%
  \corasdiagram@setsymbolanchor{asset}{south}{0mm}{-5.8mm}%
  \corasdiagram@setsymbolanchor{asset}{southwest}{-4.45mm}{-3.75mm}%
  \corasdiagram@setsymbolanchor{asset}{west}{-4.8mm}{-1.25mm}%
  \corasdiagram@setsymbolanchor{asset}{northwest}{-2.3mm}{1.25mm}%
  \corasdiagram@setsymboloutline{asset}{north,northeast,east,southeast,south,southwest,west,northwest}%
}

\newcommand{\corasdiagram@defineanchors@indirectasset}{%
  \corasdiagram@setsymbolmetric{indirectasset}{bodyhalfx}{4.15mm}%
  \corasdiagram@setsymbolmetric{indirectasset}{bodyhalfy}{4.85mm}%
  \corasdiagram@setsymbolmetric{indirectasset}{basey}{-3.9mm}%
  \corasdiagram@setsymbolmetric{indirectasset}{midy}{0.35mm}%
  \corasdiagram@setsymbolanchor{indirectasset}{north}{0mm}{5.9mm}%
  \corasdiagram@setsymbolanchor{indirectasset}{northeast}{3.15mm}{1.15mm}%
  \corasdiagram@setsymbolanchor{indirectasset}{east}{5.25mm}{-1.45mm}%
  \corasdiagram@setsymbolanchor{indirectasset}{southeast}{3.9mm}{-4.05mm}%
  \corasdiagram@setsymbolanchor{indirectasset}{south}{0mm}{-5.8mm}%
  \corasdiagram@setsymbolanchor{indirectasset}{southwest}{-4.45mm}{-3.75mm}%
  \corasdiagram@setsymbolanchor{indirectasset}{west}{-4.8mm}{-1.25mm}%
  \corasdiagram@setsymbolanchor{indirectasset}{northwest}{-2.3mm}{1.25mm}%
  \corasdiagram@setsymboloutline{indirectasset}{north,northeast,east,southeast,south,southwest,west,northwest}%
}

\newcommand{\corasdiagram@defineanchors@threataccidental}{%
  \corasdiagram@setsymbolmetric{threataccidental}{bodyhalfx}{2.8mm}%
  \corasdiagram@setsymbolmetric{threataccidental}{bodyhalfy}{5.4mm}%
  \corasdiagram@setsymbolmetric{threataccidental}{basey}{-4.4mm}%
  \corasdiagram@setsymbolmetric{threataccidental}{midy}{0.5mm}%
  \corasdiagram@setsymbolanchor{threataccidental}{north}{-1.75mm}{6.6mm}%
  \corasdiagram@setsymbolanchor{threataccidental}{northeast}{2.05mm}{4.1mm}%
  \corasdiagram@setsymbolanchor{threataccidental}{east}{4.6mm}{0.35mm}%
  \corasdiagram@setsymbolanchor{threataccidental}{southeast}{0.1mm}{-3.4mm}%
  \corasdiagram@setsymbolanchor{threataccidental}{south}{-1.65mm}{-6.9mm}%
  \corasdiagram@setsymbolanchor{threataccidental}{southwest}{-3.6mm}{-3.5mm}%
  \corasdiagram@setsymbolanchor{threataccidental}{west}{-4.45mm}{0.15mm}%
  \corasdiagram@setsymbolanchor{threataccidental}{northwest}{-4.25mm}{3.8mm}%
  \corasdiagram@setsymboloutline{threataccidental}{north,northeast,east,southeast,south,southwest,west,northwest}%
}

\newcommand{\corasdiagram@defineanchors@threatdeliberate}{%
  \corasdiagram@setsymbolmetric{threatdeliberate}{bodyhalfx}{3.0mm}%
  \corasdiagram@setsymbolmetric{threatdeliberate}{bodyhalfy}{5.7mm}%
  \corasdiagram@setsymbolmetric{threatdeliberate}{basey}{-4.6mm}%
  \corasdiagram@setsymbolmetric{threatdeliberate}{midy}{0.6mm}%
  \corasdiagram@setsymbolanchor{threatdeliberate}{north}{-1.65mm}{6.85mm}%
  \corasdiagram@setsymbolanchor{threatdeliberate}{northeast}{1.1mm}{5mm}%
  \corasdiagram@setsymbolanchor{threatdeliberate}{east}{5mm}{-0.25mm}%
  \corasdiagram@setsymbolanchor{threatdeliberate}{southeast}{0.45mm}{-5.05mm}%
  \corasdiagram@setsymbolanchor{threatdeliberate}{south}{-1.75mm}{-7.35mm}%
  \corasdiagram@setsymbolanchor{threatdeliberate}{southwest}{-3.8mm}{-3.95mm}%
  \corasdiagram@setsymbolanchor{threatdeliberate}{west}{-5mm}{0.1mm}%
  \corasdiagram@setsymbolanchor{threatdeliberate}{northwest}{-4.05mm}{5.25mm}%
  \corasdiagram@setsymboloutline{threatdeliberate}{north,northeast,east,southeast,south,southwest,west,northwest}%
}

\newcommand{\corasdiagram@defineanchors@threatnonhuman}{%
  \corasdiagram@setsymbolmetric{threatnonhuman}{bodyhalfx}{4.1mm}%
  \corasdiagram@setsymbolmetric{threatnonhuman}{bodyhalfy}{4.3mm}%
  \corasdiagram@setsymbolmetric{threatnonhuman}{basey}{-3.1mm}%
  \corasdiagram@setsymbolmetric{threatnonhuman}{midy}{0.4mm}%
  \corasdiagram@setsymbolanchor{threatnonhuman}{north}{0mm}{4.7mm}%
  \corasdiagram@setsymbolanchor{threatnonhuman}{northeast}{5.65mm}{6.7mm}%
  \corasdiagram@setsymbolanchor{threatnonhuman}{east}{6.2mm}{0.05mm}%
  \corasdiagram@setsymbolanchor{threatnonhuman}{southeast}{6.2mm}{-6.05mm}%
  \corasdiagram@setsymbolanchor{threatnonhuman}{south}{-0.1mm}{-4.45mm}%
  \corasdiagram@setsymbolanchor{threatnonhuman}{southwest}{-6.3mm}{-3.55mm}%
  \corasdiagram@setsymbolanchor{threatnonhuman}{west}{-6.3mm}{0.05mm}%
  \corasdiagram@setsymbolanchor{threatnonhuman}{northwest}{-6.3mm}{4.95mm}%
  \corasdiagram@setsymboloutline{threatnonhuman}{north,northeast,east,southeast,south,southwest,west,northwest}%
}

\newcommand{\corasdiagram@defineanchors@vulnerability}{%
  \corasdiagram@setsymbolmetric{vulnerability}{bodyhalfx}{2.4mm}%
  \corasdiagram@setsymbolmetric{vulnerability}{bodyhalfy}{4.1mm}%
  \corasdiagram@setsymbolmetric{vulnerability}{basey}{-3.1mm}%
  \corasdiagram@setsymbolmetric{vulnerability}{midy}{0.4mm}%
  \corasdiagram@setsymbolanchor{vulnerability}{north}{-0.35mm}{5.2mm}%
  \corasdiagram@setsymbolanchor{vulnerability}{northeast}{2.3mm}{3.15mm}%
  \corasdiagram@setsymbolanchor{vulnerability}{east}{3.7mm}{-0.15mm}%
  \corasdiagram@setsymbolanchor{vulnerability}{southeast}{3.4mm}{-2.55mm}%
  \corasdiagram@setsymbolanchor{vulnerability}{south}{0mm}{-5.25mm}%
  \corasdiagram@setsymbolanchor{vulnerability}{southwest}{-3.4mm}{-3.1mm}%
  \corasdiagram@setsymbolanchor{vulnerability}{west}{-3.25mm}{-0.15mm}%
  \corasdiagram@setsymbolanchor{vulnerability}{northwest}{-3.25mm}{3.8mm}%
  \corasdiagram@setsymboloutline{vulnerability}{north,northeast,east,southeast,south,southwest,west,northwest}%
}

\corasdiagram@defineanchors@asset
\corasdiagram@defineanchors@indirectasset
\corasdiagram@defineanchors@stakeholder
\corasdiagram@defineanchors@threataccidental
\corasdiagram@defineanchors@threatdeliberate
\corasdiagram@defineanchors@threatnonhuman
\corasdiagram@defineanchors@vulnerability

\corasdiagram@declareiconsymbolshape{corasassetanchorshape}{asset}
\corasdiagram@declareiconsymbolshape{corasindirectassetanchorshape}{indirectasset}
\corasdiagram@declareiconsymbolshape{corasstakeholderanchorshape}{stakeholder}
\corasdiagram@declareiconsymbolshape{corasthreataccidentalanchorshape}{threataccidental}
\corasdiagram@declareiconsymbolshape{corasthreatdeliberateanchorshape}{threatdeliberate}
\corasdiagram@declareiconsymbolshape{corasthreatnonhumananchorshape}{threatnonhuman}
\corasdiagram@declareiconsymbolshape{corasvulnerabilityanchorshape}{vulnerability}

\newcount\corasdiagram@autonode
\newcount\corasdiagram@diagramseq
\newcount\corasdiagram@edgecoordseq
\newcount\corasdiagram@placedcount
\newcount\corasdiagram@placedindex
\newdimen\corasdiagram@tmpdimen
\newdimen\corasdiagram@compartmentwidth
\newdimen\corasdiagram@compartmentheight
\newdimen\corasdiagram@compartmentside
\newdimen\corasdiagram@halfcompartmentside
\newdimen\corasdiagram@scopewidth
\newdimen\corasdiagram@scopeheight
\newdimen\corasdiagram@finalscopewidth
\newdimen\corasdiagram@finalscopeheight
\newdimen\corasdiagram@labelwidth
\newdimen\corasdiagram@labelheight
\newdimen\corasdiagram@estimatedwidth
\newdimen\corasdiagram@estimatedheight
\newdimen\corasdiagram@currentx
\newdimen\corasdiagram@currenty
\newdimen\corasdiagram@previousx
\newdimen\corasdiagram@previousy
\newdimen\corasdiagram@currenthalfwidth
\newdimen\corasdiagram@currenthalfheight
\newdimen\corasdiagram@previoushalfwidth
\newdimen\corasdiagram@previoushalfheight
\newdimen\corasdiagram@overlapx
\newdimen\corasdiagram@requiredy
\newdimen\corasdiagram@overlapmarginx
\newdimen\corasdiagram@overlapmarginy
\newdimen\corasdiagram@minimumedgegap
\newdimen\corasdiagram@minimumedgegapslack
\newdimen\corasdiagram@requestedgap
\newdimen\corasdiagram@neighborcenterdimen
\newdimen\corasdiagram@neighborhalfdimen

\def\corasdiagram@knownroles{stakeholder,asset,threatsource,vulnerability,scenario,incident,risk,treatment,junction,scope}
\def\corasdiagram@currentfamily{}
\def\corasdiagram@layoutmode{auto}
\def\corasdiagram@layoutmingap{8mm}
\def\corasdiagram@currentdiagramid{}
\corasdiagram@minimumedgegapslack=0.6mm\relax

\newcommand{\corasdiagram@ensurename}[1]{%
  \ifx#1\@empty
    \global\advance\corasdiagram@autonode by 1\relax
    \edef#1{coras-auto-\the\corasdiagram@autonode}%
  \fi
}

\newcommand{\corasdiagram@setdefault}[2]{%
  \ifx#1\@empty
    \def#1{#2}%
  \fi
}

\newcommand{\corasdiagram@normalize}[1]{%
  \edef#1{#1}%
}

\newcommand{\corasdiagram@iconfile}[1]{%
  \corasdiagram@iconspath/\corasdiagram@iconfileprefix#1\corasdiagram@iconsuffix.pdf%
}

\newcommand{\corasdiagram@resolveiconperspectivesuffix}[1]{%
  \def\corasdiagram@resolvedperspectivesuffix{}%
  \def\corasdiagram@perspectivebefore{before}%
  \def\corasdiagram@perspectivebeforeafter{before-after}%
  \def\corasdiagram@perspectiveafter{after}%
  \ifx#1\@empty
  \else\ifx#1\corasdiagram@perspectivebefore
  \else\ifx#1\corasdiagram@perspectivebeforeafter
    \def\corasdiagram@resolvedperspectivesuffix{_outlined}%
  \else\ifx#1\corasdiagram@perspectiveafter
    \def\corasdiagram@resolvedperspectivesuffix{_shaded}%
  \else
    \PackageError{corasdiagram}{Unknown perspective `#1'}{%
      Use `perspective=before`, `perspective=before-after`, or `perspective=after`.%
    }%
  \fi\fi\fi\fi
}

\newcommand{\corasdiagram@resolveiconstem}[3]{%
  \corasdiagram@resolveiconperspectivesuffix{#2}%
  \edef#3{#1\corasdiagram@resolvedperspectivesuffix}%
}

\newcommand{\corasdiagram@includeicon}[2]{%
  \includegraphics[width=#1]{\corasdiagram@iconfile{#2}}%
}

\newcommand{\corasdiagram@highlevelcauseicons}{%
  \begin{tikzpicture}[baseline=(current bounding box.center),x=1mm,y=1mm,scale=\corashlatable@iconscale,transform shape]
    \node[inner sep=0pt,outer sep=0pt] (deliberate) at (0,0)
      {\corasdiagram@includeicon{7.4mm}{threat-human-deliberate}};
    \node[inner sep=0pt,outer sep=0pt] (accidental) at (10.5,0)
      {\corasdiagram@includeicon{7.4mm}{threat-human-accidental}};
    \node[inner sep=0pt,outer sep=0pt] (nonhuman) at (23.5,0)
      {\corasdiagram@includeicon{10.8mm}{threat-non-human}};
  \end{tikzpicture}%
}

\newcommand{\corasdiagram@highleveleventicons}{%
  \begin{tikzpicture}[baseline=(current bounding box.center),x=1mm,y=1mm,scale=\corashlatable@iconscale,transform shape]
    \node[coras/ellipse,minimum width=19mm,minimum height=8.5mm,inner sep=0pt] (scenario) at (0,0) {};
    \node[coras/base node,anchor=center] at (scenario.north)
      {\corasdiagram@includeicon{5.1mm}{risk}};
    \node[coras/incident body,minimum width=18.5mm,minimum height=8.5mm,inner sep=0pt] (incident) at (26,0) {};
    \node[coras/base node,anchor=center] at ([xshift=-1.5mm]incident.north east)
      {\corasdiagram@includeicon{5.1mm}{unwanted-incident}};
    \node[coras/base node,inner sep=0pt,outer sep=0pt] at (48,0)
      {\corasdiagram@includeicon{8.2mm}{asset}};
  \end{tikzpicture}%
}

\newcommand{\corasdiagram@highlevelpossibilityicons}{%
  \begin{tikzpicture}[baseline=(current bounding box.center),scale=\corashlatable@iconscale,transform shape]
    \node[coras/base node,inner sep=0pt,outer sep=0pt]
      {\corasdiagram@includeicon{8.0mm}{vulnerability}};
  \end{tikzpicture}%
}

\newcommand{\corasdiagram@ifincsv}[4]{%
  \edef\corasdiagram@membertest{#1}%
  \def\corasdiagram@ismember{0}%
  \@for\corasdiagram@candidate:=#2\do{%
    \edef\corasdiagram@candidatevalue{\corasdiagram@candidate}%
    \ifx\corasdiagram@candidatevalue\corasdiagram@membertest
      \def\corasdiagram@ismember{1}%
    \fi
  }%
  \ifnum\corasdiagram@ismember=1\relax
    #3%
  \else
    #4%
  \fi
}

\newcommand{\corasdiagram@setnodeprop}[3]{%
  \expandafter\edef\csname corasdiagram@node@#1@#2\endcsname{#3}%
}

\newcommand{\corasdiagram@getnodeprop}[3]{%
  \expandafter\ifcsname corasdiagram@node@#1@#2\endcsname
    \edef#3{\csname corasdiagram@node@#1@#2\endcsname}%
  \else
    \let#3\@empty
  \fi
}

\newcommand{\corasdiagram@getbordernode}[2]{%
  \corasdiagram@getnodeprop{bordernode}{#2}{#1}%
  \ifx#1\@empty
    \expandafter\ifcsname pgf@sh@ns@#2-anchor\endcsname
      \edef#1{#2-anchor}%
    \else
      \expandafter\ifcsname pgf@sh@ns@#2\endcsname
        \edef#1{#2}%
      \fi
    \fi
  \fi
}

\newcommand{\corasdiagram@getanchorlegendcoord}[5]{%
  \corasdiagram@getnodeprop{anchorsymbol}{#1}{\corasdiagram@anchorsymbol}%
  \ifx\corasdiagram@anchorsymbol\@empty
    \corasdiagram@getbordernode{\corasdiagram@legendbordernode}{#1}%
    \pgfextractx{\corasdiagram@tmpdimen}{%
      \pgfpointdiff{\pgfpointanchor{\corasdiagram@legendbordernode}{center}}%
        {\pgfpointanchor{\corasdiagram@legendbordernode}{#3}}%
    }%
    \edef#4{\the\corasdiagram@tmpdimen}%
    \pgfextracty{\corasdiagram@tmpdimen}{%
      \pgfpointdiff{\pgfpointanchor{\corasdiagram@legendbordernode}{center}}%
        {\pgfpointanchor{\corasdiagram@legendbordernode}{#3}}%
    }%
    \edef#5{\the\corasdiagram@tmpdimen}%
  \else
    \def\corasdiagram@legendid{#2}%
    \def\corasdiagram@legendcenter{center}%
    \def\corasdiagram@legendtext{text}%
    \def\corasdiagram@legendbase{base}%
    \def\corasdiagram@legendmid{mid}%
    \def\corasdiagram@legendbaseeast{baseeast}%
    \def\corasdiagram@legendbasewest{basewest}%
    \def\corasdiagram@legendmideast{mideast}%
    \def\corasdiagram@legendmidwest{midwest}%
    \ifx\corasdiagram@legendid\corasdiagram@legendcenter
      \edef#4{0pt}%
      \edef#5{0pt}%
    \else\ifx\corasdiagram@legendid\corasdiagram@legendtext
      \edef#4{0pt}%
      \edef#5{0pt}%
    \else\ifx\corasdiagram@legendid\corasdiagram@legendbase
      \edef#4{0pt}%
      \edef#5{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @basey\endcsname}%
    \else\ifx\corasdiagram@legendid\corasdiagram@legendmid
      \edef#4{0pt}%
      \edef#5{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @midy\endcsname}%
    \else\ifx\corasdiagram@legendid\corasdiagram@legendbaseeast
      \edef#4{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @bodyhalfx\endcsname}%
      \edef#5{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @basey\endcsname}%
    \else\ifx\corasdiagram@legendid\corasdiagram@legendbasewest
      \edef#4{-\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @bodyhalfx\endcsname}%
      \edef#5{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @basey\endcsname}%
    \else\ifx\corasdiagram@legendid\corasdiagram@legendmideast
      \edef#4{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @bodyhalfx\endcsname}%
      \edef#5{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @midy\endcsname}%
    \else\ifx\corasdiagram@legendid\corasdiagram@legendmidwest
      \edef#4{-\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @bodyhalfx\endcsname}%
      \edef#5{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @midy\endcsname}%
    \else
      \edef#4{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @#2x\endcsname}%
      \edef#5{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @#2y\endcsname}%
    \fi\fi\fi\fi\fi\fi\fi\fi
  \fi
}

\newcommand{\corasdiagram@setscopefit}[2]{%
  \expandafter\edef\csname corasdiagram@scopefit@#1\endcsname{#2}%
}

\newcommand{\corasdiagram@setroleordernode}[3]{%
  \expandafter\xdef\csname corasdiagram@roleindex@\corasdiagram@currentdiagramid @#1@#2\endcsname{#3}%
}

\newcommand{\corasdiagram@getroleordernode}[3]{%
  \expandafter\ifcsname corasdiagram@roleindex@\corasdiagram@currentdiagramid @#2@#3\endcsname
    \edef#1{\csname corasdiagram@roleindex@\corasdiagram@currentdiagramid @#2@#3\endcsname}%
  \else
    \let#1\@empty
  \fi
}

\newcommand{\corasdiagram@getscopefit}[2]{%
  \expandafter\ifcsname corasdiagram@scopefit@#2\endcsname
    \edef#1{\csname corasdiagram@scopefit@#2\endcsname}%
  \else
    \let#1\@empty
  \fi
}

\newcommand{\corasdiagram@scopekey}[1]{%
  \corasdiagram@currentdiagramid::#1%
}

\newcommand{\corasdiagram@registerscopemember}[2]{%
  \ifx#1\@empty
  \else
    \edef\corasdiagram@scopenodename{#2}%
    \edef\corasdiagram@currscopekey{\corasdiagram@scopekey{#1}}%
    \corasdiagram@getscopefit{\corasdiagram@scopefitlist}{\corasdiagram@currscopekey}%
    \ifx\corasdiagram@scopefitlist\@empty
      \corasdiagram@setscopefit{\corasdiagram@currscopekey}{(\corasdiagram@scopenodename)}%
    \else
      \expandafter\edef\csname corasdiagram@scopefit@\corasdiagram@currscopekey\endcsname{%
        \corasdiagram@scopefitlist\space (\corasdiagram@scopenodename)%
      }%
    \fi
  \fi
}

\expandafter\def\csname corasdiagram@allowednodes@asset\endcsname{stakeholder,asset,scope}
\expandafter\def\csname corasdiagram@allowednodes@threat\endcsname{threatsource,vulnerability,scenario,incident,asset}
\expandafter\def\csname corasdiagram@allowednodes@risk\endcsname{threatsource,risk,asset}
\expandafter\def\csname corasdiagram@allowednodes@treatment\endcsname{treatment,threatsource,vulnerability,scenario,incident,asset}
\expandafter\def\csname corasdiagram@allowednodes@treatmentoverview\endcsname{treatment,risk,asset,junction}

\newcommand{\corasdiagram@getallowedroles}[1]{%
  \expandafter\ifcsname corasdiagram@allowednodes@#1\endcsname
    \edef\corasdiagram@allowedroles{\csname corasdiagram@allowednodes@#1\endcsname}%
  \else
    \let\corasdiagram@allowedroles\@empty
  \fi
}

\newcommand{\corasdiagram@familynamelabel}[1]{%
  \ifcsname corasdiagram@familylabel@#1\endcsname
    \csname corasdiagram@familylabel@#1\endcsname
  \else
    #1%
  \fi
}
\expandafter\def\csname corasdiagram@familylabel@asset\endcsname{asset diagram}
\expandafter\def\csname corasdiagram@familylabel@threat\endcsname{threat diagram}
\expandafter\def\csname corasdiagram@familylabel@risk\endcsname{risk diagram}
\expandafter\def\csname corasdiagram@familylabel@treatment\endcsname{treatment diagram}
\expandafter\def\csname corasdiagram@familylabel@treatmentoverview\endcsname{treatment overview diagram}

\newcommand{\corasdiagram@rolelabel}[1]{%
  \ifcsname corasdiagram@rolelabel@#1\endcsname
    \csname corasdiagram@rolelabel@#1\endcsname
  \else
    #1%
  \fi
}
\expandafter\def\csname corasdiagram@rolelabel@stakeholder\endcsname{stakeholder}
\expandafter\def\csname corasdiagram@rolelabel@asset\endcsname{asset}
\expandafter\def\csname corasdiagram@rolelabel@threatsource\endcsname{threat source}
\expandafter\def\csname corasdiagram@rolelabel@vulnerability\endcsname{vulnerability}
\expandafter\def\csname corasdiagram@rolelabel@scenario\endcsname{threat scenario}
\expandafter\def\csname corasdiagram@rolelabel@incident\endcsname{unwanted incident}
\expandafter\def\csname corasdiagram@rolelabel@risk\endcsname{risk}
\expandafter\def\csname corasdiagram@rolelabel@treatment\endcsname{treatment}
\expandafter\def\csname corasdiagram@rolelabel@junction\endcsname{junction}
\expandafter\def\csname corasdiagram@rolelabel@scope\endcsname{scope}

\newcommand{\corasdiagram@semanticlabel}[1]{%
  \ifcsname corasdiagram@semanticlabel@#1\endcsname
    \csname corasdiagram@semanticlabel@#1\endcsname
  \else
    #1%
  \fi
}
\expandafter\def\csname corasdiagram@semanticlabel@causal\endcsname{causal}
\expandafter\def\csname corasdiagram@semanticlabel@relation\endcsname{relation}
\expandafter\def\csname corasdiagram@semanticlabel@concern\endcsname{concern}
\expandafter\def\csname corasdiagram@semanticlabel@association\endcsname{association}
\expandafter\def\csname corasdiagram@semanticlabel@treatment\endcsname{treatment}

\newcommand{\corasdiagram@maptyperole}[1]{%
  \def\corasdiagram@mappedrole{#1}%
  \def\corasdiagram@typeindirectasset{indirectasset}%
  \ifx#1\corasdiagram@typeindirectasset
    \def\corasdiagram@mappedrole{asset}%
  \fi
  \corasdiagram@ifincsv{#1}{threataccidental,threatdeliberate,threatnonhuman}{%
    \def\corasdiagram@mappedrole{threatsource}%
  }{}%
}

\newcommand{\corasdiagram@validatecurrentrole}[2]{%
  \ifx\corasdiagram@currentfamily\@empty
  \else
    \corasdiagram@getallowedroles{\corasdiagram@currentfamily}%
    \corasdiagram@ifincsv{#2}{\corasdiagram@allowedroles}{}{%
      \PackageError{corasdiagram}{Node type `#1' is not allowed in the \corasdiagram@familynamelabel{\corasdiagram@currentfamily}}{%
        Allowed roles here are \corasdiagram@allowedroles.%
      }%
    }%
  \fi
}

\newcommand{\corasdiagram@validateedgepair}[4]{%
  \def\corasdiagram@edgepairvalid{0}%
  \def\corasdiagram@fromrole{#3}%
  \def\corasdiagram@torole{#4}%
  \expandafter\ifx\csname corasdiagram@edgecheck@#1@#2\endcsname\relax
  \else
    \csname corasdiagram@edgecheck@#1@#2\endcsname
  \fi
}

\def\corasdiagram@markedgevalid{\def\corasdiagram@edgepairvalid{1}}

\expandafter\def\csname corasdiagram@edgecheck@asset@relation\endcsname{%
  \corasdiagram@ifincsv{\corasdiagram@fromrole}{asset}%
    {\corasdiagram@ifincsv{\corasdiagram@torole}{asset}{\corasdiagram@markedgevalid}{}}{}%
}
\expandafter\def\csname corasdiagram@edgecheck@asset@concern\endcsname{%
  \corasdiagram@ifincsv{\corasdiagram@fromrole}{stakeholder}%
    {\corasdiagram@ifincsv{\corasdiagram@torole}{asset}{\corasdiagram@markedgevalid}{}}{}%
}

\expandafter\def\csname corasdiagram@edgecheck@threat@causal\endcsname{%
  \corasdiagram@ifincsv{\corasdiagram@fromrole}{threatsource,vulnerability,scenario}%
    {\corasdiagram@ifincsv{\corasdiagram@torole}{vulnerability,scenario,incident}{\corasdiagram@markedgevalid}{}}{}%
}
\expandafter\def\csname corasdiagram@edgecheck@threat@relation\endcsname{%
  \corasdiagram@ifincsv{\corasdiagram@fromrole}{incident}%
    {\corasdiagram@ifincsv{\corasdiagram@torole}{asset}{\corasdiagram@markedgevalid}{}}{}%
}
\expandafter\def\csname corasdiagram@edgecheck@threat@association\endcsname{%
  \corasdiagram@ifincsv{\corasdiagram@fromrole}{scenario,incident}%
    {\corasdiagram@ifincsv{\corasdiagram@torole}{asset,incident,scenario}{\corasdiagram@markedgevalid}{}}{}%
}

\expandafter\def\csname corasdiagram@edgecheck@risk@causal\endcsname{%
  \corasdiagram@ifincsv{\corasdiagram@fromrole}{threatsource}%
    {\corasdiagram@ifincsv{\corasdiagram@torole}{risk}{\corasdiagram@markedgevalid}{}}{}%
}
\expandafter\def\csname corasdiagram@edgecheck@risk@relation\endcsname{%
  \corasdiagram@ifincsv{\corasdiagram@fromrole}{risk}%
    {\corasdiagram@ifincsv{\corasdiagram@torole}{asset}{\corasdiagram@markedgevalid}{}}{}%
}

\expandafter\def\csname corasdiagram@edgecheck@treatment@causal\endcsname{%
  \corasdiagram@ifincsv{\corasdiagram@fromrole}{threatsource,vulnerability,scenario}%
    {\corasdiagram@ifincsv{\corasdiagram@torole}{vulnerability,scenario,incident}{\corasdiagram@markedgevalid}{}}{}%
}
\expandafter\def\csname corasdiagram@edgecheck@treatment@relation\endcsname{%
  \corasdiagram@ifincsv{\corasdiagram@fromrole}{incident}%
    {\corasdiagram@ifincsv{\corasdiagram@torole}{asset}{\corasdiagram@markedgevalid}{}}{}%
}
\expandafter\def\csname corasdiagram@edgecheck@treatment@treatment\endcsname{%
  \corasdiagram@ifincsv{\corasdiagram@fromrole}{treatment}%
    {\corasdiagram@ifincsv{\corasdiagram@torole}{threatsource,vulnerability,scenario,incident,asset,risk,junction}{\corasdiagram@markedgevalid}{}}{}%
}

\expandafter\def\csname corasdiagram@edgecheck@treatmentoverview@relation\endcsname{%
  \corasdiagram@ifincsv{\corasdiagram@fromrole}{risk}%
    {\corasdiagram@ifincsv{\corasdiagram@torole}{asset}{\corasdiagram@markedgevalid}{}}{}%
}
\expandafter\def\csname corasdiagram@edgecheck@treatmentoverview@treatment\endcsname{%
  \corasdiagram@ifincsv{\corasdiagram@fromrole}{treatment,junction}%
    {\corasdiagram@ifincsv{\corasdiagram@torole}{junction,risk}{\corasdiagram@markedgevalid}{}}{}%
}

\newcommand{\corasdiagram@validateedge}[3]{%
  \ifx\corasdiagram@currentfamily\@empty
  \else
    \corasdiagram@validateedgepair{\corasdiagram@currentfamily}{#1}{#2}{#3}%
    \ifx\corasdiagram@edgepairvalid\@empty
    \fi
    \ifnum\corasdiagram@edgepairvalid=1\relax
    \else
      \PackageError{corasdiagram}{\corasdiagram@semanticlabel{#1} edge from \corasdiagram@rolelabel{#2} to \corasdiagram@rolelabel{#3} is not allowed in the \corasdiagram@familynamelabel{\corasdiagram@currentfamily}}{%
        Use the canonical CORAS node roles and semantic edge commands for this diagram family.%
      }%
    \fi
  \fi
}

\newcommand{\corasdiagram@begindiagram}[1]{%
  \global\advance\corasdiagram@diagramseq by 1\relax
  \edef\corasdiagram@currentdiagramid{diagram-\the\corasdiagram@diagramseq}%
  \def\corasdiagram@currentfamily{#1}%
  \def\corasdiagram@layoutmode{auto}%
  \global\corasdiagram@placedcount=0\relax
  \@for\corasdiagram@role:=\corasdiagram@knownroles\do{%
    \expandafter\def\csname corasdiagram@lane@#1@\corasdiagram@role\endcsname{0}%
  }%
}

\newcommand{\corasdiagram@nextlaneindex}[2]{%
  \expandafter\ifx\csname corasdiagram@lane@#1@#2\endcsname\relax
    \expandafter\def\csname corasdiagram@lane@#1@#2\endcsname{0}%
  \fi
  \edef\corasdiagram@currindex{\csname corasdiagram@lane@#1@#2\endcsname}%
  \pgfmathtruncatemacro{\corasdiagram@nextindex}{\corasdiagram@currindex + 1}%
  \expandafter\xdef\csname corasdiagram@lane@#1@#2\endcsname{\corasdiagram@nextindex}%
  \edef\corasdiagram@laneindex{\corasdiagram@nextindex}%
}

\newcommand{\corasdiagram@setautocoord}[2]{%
  \edef\corasnode@at{(#1,#2)}%
}

\newcommand{\corasdiagram@measurelabelcontent}{%
  \ifx\corasnode@textwidth\@empty
    \setbox\z@=\hbox{{\sffamily\footnotesize\let\\\space\corasnode@title}}%
    \corasdiagram@labelwidth=\wd\z@
    \corasdiagram@labelheight=3.8ex\relax
    \edef\corasdiagram@measuretitle{\corasnode@title}%
    \in@{\\}{\corasdiagram@measuretitle}%
    \ifin@
      \advance\corasdiagram@labelheight by 3.8ex\relax
    \fi
    \ifx\corasnode@meta\@empty
    \else
      \advance\corasdiagram@labelheight by 2.6ex\relax
    \fi
    \ifx\corasnode@level\@empty
    \else
      \advance\corasdiagram@labelheight by 2.6ex\relax
    \fi
  \else
    \setbox\z@=\hbox{{\sffamily\footnotesize\corasdiagram@composecontent{\corasnode@textwidth}}}%
    \corasdiagram@labelwidth=\wd\z@
    \corasdiagram@labelheight=\dimexpr\ht\z@+\dp\z@\relax
  \fi
}

\newcommand{\corasdiagram@measureiconlabelsize}[2]{%
  \corasdiagram@measurelabelcontent
  \corasdiagram@estimatedwidth=#1\relax
  \ifdim\corasdiagram@labelwidth>\corasdiagram@estimatedwidth
    \corasdiagram@estimatedwidth=\corasdiagram@labelwidth
  \fi
  \corasdiagram@estimatedheight=\dimexpr#2+\corasdiagram@labelheight\relax
  \corasdiagram@tmpdimen=\corasnode@labelgap\relax
  \ifdim\corasdiagram@tmpdimen<0pt
    \corasdiagram@tmpdimen=-\corasdiagram@tmpdimen
  \fi
  \advance\corasdiagram@estimatedheight by \corasdiagram@tmpdimen
}

\newcommand{\corasdiagram@measurebodynodesize}[4]{%
  \corasdiagram@measurelabelcontent
  \corasdiagram@estimatedwidth=\dimexpr#1+#2\relax
  \corasdiagram@estimatedheight=\dimexpr\corasdiagram@labelheight+#3\relax
  \ifdim\corasdiagram@estimatedheight<#4\relax
    \corasdiagram@estimatedheight=#4\relax
  \fi
  \advance\corasdiagram@estimatedheight by \corasnode@iconwidth\relax
}

\newcommand{\corasdiagram@measureautonodesize}{%
  \def\corasdiagram@typeasset{asset}%
  \def\corasdiagram@typeindirectasset{indirectasset}%
  \def\corasdiagram@typestakeholder{stakeholder}%
  \def\corasdiagram@typethreataccidental{threataccidental}%
  \def\corasdiagram@typethreatdeliberate{threatdeliberate}%
  \def\corasdiagram@typethreatnonhuman{threatnonhuman}%
  \def\corasdiagram@typevulnerability{vulnerability}%
  \def\corasdiagram@typescenario{scenario}%
  \def\corasdiagram@typeincident{incident}%
  \def\corasdiagram@typerisk{risk}%
  \def\corasdiagram@typetreatment{treatment}%
  \def\corasdiagram@typejunction{junction}%
  \ifx\corasnode@type\corasdiagram@typeasset
    \corasdiagram@setdefault\corasnode@textwidth{26mm}%
    \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}%
    \corasdiagram@measureiconlabelsize{10mm}{10.2mm}%
  \else\ifx\corasnode@type\corasdiagram@typeindirectasset
    \corasdiagram@setdefault\corasnode@textwidth{26mm}%
    \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}%
    \corasdiagram@measureiconlabelsize{10mm}{10.2mm}%
  \else\ifx\corasnode@type\corasdiagram@typestakeholder
    \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}%
    \corasdiagram@measureiconlabelsize{7mm}{9.9mm}%
  \else\ifx\corasnode@type\corasdiagram@typethreataccidental
    \corasdiagram@setdefault\corasnode@textwidth{23mm}%
    \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}%
    \corasdiagram@measureiconlabelsize{10mm}{13.0mm}%
  \else\ifx\corasnode@type\corasdiagram@typethreatdeliberate
    \corasdiagram@setdefault\corasnode@textwidth{23mm}%
    \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}%
    \corasdiagram@measureiconlabelsize{10mm}{13.6mm}%
  \else\ifx\corasnode@type\corasdiagram@typethreatnonhuman
    \corasdiagram@setdefault\corasnode@textwidth{26mm}%
    \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}%
    \corasdiagram@measureiconlabelsize{13mm}{10.8mm}%
  \else\ifx\corasnode@type\corasdiagram@typevulnerability
    \corasdiagram@setdefault\corasnode@textwidth{22mm}%
    \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}%
    \corasdiagram@measureiconlabelsize{8mm}{9.0mm}%
  \else\ifx\corasnode@type\corasdiagram@typescenario
    \corasdiagram@setdefault\corasnode@textwidth{28mm}%
    \corasdiagram@setdefault\corasnode@iconwidth{6.2mm}%
    \corasdiagram@measurebodynodesize{\corasnode@textwidth}{10pt}{6pt}{10mm}%
  \else\ifx\corasnode@type\corasdiagram@typeincident
    \corasdiagram@setdefault\corasnode@textwidth{25mm}%
    \corasdiagram@setdefault\corasnode@iconwidth{5.6mm}%
    \corasdiagram@measurebodynodesize{\corasnode@textwidth}{8pt}{6pt}{8mm}%
  \else\ifx\corasnode@type\corasdiagram@typerisk
    \corasdiagram@setdefault\corasnode@textwidth{27mm}%
    \corasdiagram@setdefault\corasnode@iconwidth{6.5mm}%
    \corasdiagram@measurebodynodesize{\corasnode@textwidth}{8pt}{6pt}{11mm}%
  \else\ifx\corasnode@type\corasdiagram@typetreatment
    \corasdiagram@setdefault\corasnode@textwidth{24mm}%
    \corasdiagram@setdefault\corasnode@iconwidth{7mm}%
    \corasdiagram@measurebodynodesize{\corasnode@textwidth}{10pt}{6pt}{9mm}%
  \else\ifx\corasnode@type\corasdiagram@typejunction
    \corasdiagram@estimatedwidth=3.3mm\relax
    \corasdiagram@estimatedheight=3.3mm\relax
  \else
    \corasdiagram@estimatedwidth=15mm\relax
    \corasdiagram@estimatedheight=10mm\relax
  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
}

\newcommand{\corasdiagram@resolveeffectivegap}{%
  \ifx\corasnode@minedgegap\@empty
    \corasdiagram@minimumedgegap=\corasdiagram@layoutmingap\relax
  \else
    \corasdiagram@minimumedgegap=\corasnode@minedgegap\relax
  \fi
}

\newcommand{\corasdiagram@preparecurrentplacementmetrics}{%
  \corasdiagram@measureautonodesize
  \corasdiagram@resolveeffectivegap
  \corasdiagram@currenthalfwidth=\dimexpr\corasdiagram@estimatedwidth/2\relax
  \corasdiagram@currenthalfheight=\dimexpr\corasdiagram@estimatedheight/2\relax
}

\newcommand{\corasdiagram@enforcehorizontalrelativegap}[1]{%
  \corasdiagram@requestedgap=#1\relax
  \corasdiagram@tmpdimen=\dimexpr
    \corasdiagram@currenthalfwidth+\corasdiagram@minimumedgegap+\corasdiagram@minimumedgegapslack\relax
  \ifdim\corasdiagram@requestedgap<\corasdiagram@tmpdimen
    \corasdiagram@requestedgap=\corasdiagram@tmpdimen
  \fi
}

\newcommand{\corasdiagram@enforceverticalrelativegap}[1]{%
  \corasdiagram@requestedgap=#1\relax
  \corasdiagram@tmpdimen=\dimexpr
    \corasdiagram@currenthalfheight+\corasdiagram@minimumedgegap+\corasdiagram@minimumedgegapslack\relax
  \ifdim\corasdiagram@requestedgap<\corasdiagram@tmpdimen
    \corasdiagram@requestedgap=\corasdiagram@tmpdimen
  \fi
}

\newcommand{\corasdiagram@registerplacednode}[1]{%
  \global\advance\corasdiagram@placedcount by 1\relax
  \expandafter\xdef\csname corasdiagram@placed@\corasdiagram@currentdiagramid @\the\corasdiagram@placedcount\endcsname{#1}%
}

\newcommand{\corasdiagram@getplacednode}[2]{%
  \expandafter\ifcsname corasdiagram@placed@\corasdiagram@currentdiagramid @#2\endcsname
    \edef#1{\csname corasdiagram@placed@\corasdiagram@currentdiagramid @#2\endcsname}%
  \else
    \let#1\@empty
  \fi
}

\def\corasdiagram@splitautocoord(#1,#2){%
  \def\corasdiagram@rawautox{#1}%
  \def\corasdiagram@rawautoy{#2}%
}

\newcommand{\corasdiagram@avoidautolayoutoverlap}{%
  \corasdiagram@measureautonodesize
  \corasdiagram@currenthalfwidth=\dimexpr\corasdiagram@estimatedwidth/2\relax
  \corasdiagram@currenthalfheight=\dimexpr\corasdiagram@estimatedheight/2\relax
  \corasdiagram@overlapmarginx=1.5mm\relax
  \corasdiagram@overlapmarginy=1.8mm\relax
  \corasdiagram@placedindex=1\relax
  \loop
    \ifnum\corasdiagram@placedindex<\numexpr\corasdiagram@placedcount+1\relax
      \corasdiagram@getplacednode{\corasdiagram@previousnode}{\the\corasdiagram@placedindex}%
      \ifx\corasdiagram@previousnode\@empty
      \else
        \corasdiagram@getnodeprop{publicwidth}{\corasdiagram@previousnode}{\corasdiagram@previouswidth}%
        \corasdiagram@getnodeprop{publicheight}{\corasdiagram@previousnode}{\corasdiagram@previousheight}%
        \corasdiagram@getnodeprop{centerx}{\corasdiagram@previousnode}{\corasdiagram@previouscenterx}%
        \corasdiagram@getnodeprop{centery}{\corasdiagram@previousnode}{\corasdiagram@previouscentery}%
        \ifx\corasdiagram@previouswidth\@empty
        \else
          \corasdiagram@previoushalfwidth=\dimexpr\corasdiagram@previouswidth/2\relax
          \corasdiagram@previoushalfheight=\dimexpr\corasdiagram@previousheight/2\relax
          \corasdiagram@previousx=\corasdiagram@previouscenterx\relax
          \corasdiagram@previousy=\corasdiagram@previouscentery\relax
          \corasdiagram@overlapx=\dimexpr\corasdiagram@currentx-\corasdiagram@previousx\relax
          \ifdim\corasdiagram@overlapx<0pt
            \corasdiagram@overlapx=-\corasdiagram@overlapx
          \fi
          \ifdim\corasdiagram@overlapx<\dimexpr\corasdiagram@currenthalfwidth+\corasdiagram@previoushalfwidth+\corasdiagram@overlapmarginx\relax
            \corasdiagram@requiredy=\dimexpr
              \corasdiagram@previousy-\corasdiagram@previoushalfheight-\corasdiagram@currenthalfheight-\corasdiagram@overlapmarginy\relax
            \ifdim\corasdiagram@currenty>\corasdiagram@requiredy
              \corasdiagram@currenty=\corasdiagram@requiredy
            \fi
          \fi
        \fi
      \fi
      \advance\corasdiagram@placedindex by 1\relax
  \repeat
  \corasdiagram@makenodecoordfromdimens
}

\newcommand{\corasdiagram@usespecifiedorder}{%
  \ifx\corasnode@order\@empty
    \corasdiagram@nextlaneindex{\corasdiagram@currentfamily}{\corasnode@role}%
    \edef\corasnode@resolvedorder{\corasdiagram@laneindex}%
  \else
    \edef\corasdiagram@laneindex{\corasnode@order}%
    \edef\corasnode@resolvedorder{\corasnode@order}%
  \fi
}

\newcommand{\corasdiagram@makenodecoordfromdimens}{%
  \edef\corasnode@at{(\the\corasdiagram@currentx,\the\corasdiagram@currenty)}%
}

\newcommand{\corasdiagram@enforcerightofnode}[1]{%
  \ifx#1\@empty
  \else
    \corasdiagram@getnodeprop{publicwidth}{#1}{\corasdiagram@neighborwidth}%
    \corasdiagram@getnodeprop{centerx}{#1}{\corasdiagram@neighborcenter}%
    \ifx\corasdiagram@neighborwidth\@empty
    \else
      \corasdiagram@neighborhalfdimen=\dimexpr\corasdiagram@neighborwidth/2\relax
      \corasdiagram@neighborcenterdimen=\corasdiagram@neighborcenter\relax
      \corasdiagram@tmpdimen=\dimexpr
        \corasdiagram@neighborcenterdimen+\corasdiagram@neighborhalfdimen+\corasdiagram@currenthalfwidth+\corasdiagram@minimumedgegap+\corasdiagram@minimumedgegapslack\relax
      \ifdim\corasdiagram@currentx<\corasdiagram@tmpdimen
        \corasdiagram@currentx=\corasdiagram@tmpdimen
      \fi
    \fi
  \fi
}

\newcommand{\corasdiagram@enforceleftofnode}[1]{%
  \ifx#1\@empty
  \else
    \corasdiagram@getnodeprop{publicwidth}{#1}{\corasdiagram@neighborwidth}%
    \corasdiagram@getnodeprop{centerx}{#1}{\corasdiagram@neighborcenter}%
    \ifx\corasdiagram@neighborwidth\@empty
    \else
      \corasdiagram@neighborhalfdimen=\dimexpr\corasdiagram@neighborwidth/2\relax
      \corasdiagram@neighborcenterdimen=\corasdiagram@neighborcenter\relax
      \corasdiagram@tmpdimen=\dimexpr
        \corasdiagram@neighborcenterdimen-\corasdiagram@neighborhalfdimen-\corasdiagram@currenthalfwidth-\corasdiagram@minimumedgegap-\corasdiagram@minimumedgegapslack\relax
      \ifdim\corasdiagram@currentx>\corasdiagram@tmpdimen
        \corasdiagram@currentx=\corasdiagram@tmpdimen
      \fi
    \fi
  \fi
}

\newcommand{\corasdiagram@enforceabovenode}[1]{%
  \ifx#1\@empty
  \else
    \corasdiagram@getnodeprop{publicheight}{#1}{\corasdiagram@neighborheight}%
    \corasdiagram@getnodeprop{centery}{#1}{\corasdiagram@neighborcenter}%
    \ifx\corasdiagram@neighborheight\@empty
    \else
      \corasdiagram@neighborhalfdimen=\dimexpr\corasdiagram@neighborheight/2\relax
      \corasdiagram@neighborcenterdimen=\corasdiagram@neighborcenter\relax
      \corasdiagram@tmpdimen=\dimexpr
        \corasdiagram@neighborcenterdimen+\corasdiagram@neighborhalfdimen+\corasdiagram@currenthalfheight+\corasdiagram@minimumedgegap+\corasdiagram@minimumedgegapslack\relax
      \ifdim\corasdiagram@currenty<\corasdiagram@tmpdimen
        \corasdiagram@currenty=\corasdiagram@tmpdimen
      \fi
    \fi
  \fi
}

\newcommand{\corasdiagram@enforcebelownode}[1]{%
  \ifx#1\@empty
  \else
    \corasdiagram@getnodeprop{publicheight}{#1}{\corasdiagram@neighborheight}%
    \corasdiagram@getnodeprop{centery}{#1}{\corasdiagram@neighborcenter}%
    \ifx\corasdiagram@neighborheight\@empty
    \else
      \corasdiagram@neighborhalfdimen=\dimexpr\corasdiagram@neighborheight/2\relax
      \corasdiagram@neighborcenterdimen=\corasdiagram@neighborcenter\relax
      \corasdiagram@tmpdimen=\dimexpr
        \corasdiagram@neighborcenterdimen-\corasdiagram@neighborhalfdimen-\corasdiagram@currenthalfheight-\corasdiagram@minimumedgegap-\corasdiagram@minimumedgegapslack\relax
      \ifdim\corasdiagram@currenty>\corasdiagram@tmpdimen
        \corasdiagram@currenty=\corasdiagram@tmpdimen
      \fi
    \fi
  \fi
}

\newcommand{\corasdiagram@enforcerightofrole}[1]{%
  \ifx\corasnode@resolvedorder\@empty
  \else
    \corasdiagram@getroleordernode{\corasdiagram@adjacentnode}{#1}{\corasnode@resolvedorder}%
    \corasdiagram@enforcerightofnode{\corasdiagram@adjacentnode}%
  \fi
}

\newcommand{\corasdiagram@enforceleftofrole}[1]{%
  \ifx\corasnode@resolvedorder\@empty
  \else
    \corasdiagram@getroleordernode{\corasdiagram@adjacentnode}{#1}{\corasnode@resolvedorder}%
    \corasdiagram@enforceleftofnode{\corasdiagram@adjacentnode}%
  \fi
}

\newcommand{\corasdiagram@enforceaboverole}[1]{%
  \ifx\corasnode@resolvedorder\@empty
  \else
    \corasdiagram@getroleordernode{\corasdiagram@adjacentnode}{#1}{\corasnode@resolvedorder}%
    \corasdiagram@enforceabovenode{\corasdiagram@adjacentnode}%
  \fi
}

\newcommand{\corasdiagram@enforcebelowsamerole}[1]{%
  \ifx\corasnode@resolvedorder\@empty
  \else
    \pgfmathtruncatemacro{\corasdiagram@previousorder}{\corasnode@resolvedorder - 1}%
    \ifnum\corasdiagram@previousorder>0\relax
      \corasdiagram@getroleordernode{\corasdiagram@adjacentnode}{#1}{\corasdiagram@previousorder}%
      \corasdiagram@enforcebelownode{\corasdiagram@adjacentnode}%
    \fi
  \fi
}

\newcommand{\corasdiagram@enforcebelowallplacedrole}[1]{%
  \corasdiagram@placedindex=1\relax
  \loop
    \ifnum\corasdiagram@placedindex<\numexpr\corasdiagram@placedcount+1\relax
      \corasdiagram@getplacednode{\corasdiagram@previousnode}{\the\corasdiagram@placedindex}%
      \ifx\corasdiagram@previousnode\@empty
      \else
        \corasdiagram@getnodeprop{role}{\corasdiagram@previousnode}{\corasdiagram@previousrole}%
        \def\corasdiagram@targetrole{#1}%
        \ifx\corasdiagram@previousrole\corasdiagram@targetrole
          \corasdiagram@enforcebelownode{\corasdiagram@previousnode}%
        \fi
      \fi
      \advance\corasdiagram@placedindex by 1\relax
  \repeat
}

\newcommand{\corasdiagram@enforcerightofsamerole}[1]{%
  \ifx\corasnode@resolvedorder\@empty
  \else
    \pgfmathtruncatemacro{\corasdiagram@previousorder}{\corasnode@resolvedorder - 1}%
    \ifnum\corasdiagram@previousorder>0\relax
      \corasdiagram@getroleordernode{\corasdiagram@adjacentnode}{#1}{\corasdiagram@previousorder}%
      \corasdiagram@enforcerightofnode{\corasdiagram@adjacentnode}%
    \fi
  \fi
}

\newcommand{\corasdiagram@applyautominedgegap}{%
  \expandafter\ifx\csname corasdiagram@autogap@\corasdiagram@currentfamily @\corasnode@role\endcsname\relax
  \else
    \csname corasdiagram@autogap@\corasdiagram@currentfamily @\corasnode@role\endcsname
  \fi
}

\newcommand{\corasdiagram@setroleplacement}[1]{%
  \corasdiagram@usespecifiedorder
  \corasdiagram@preparecurrentplacementmetrics
  \def\corasdiagram@x{0}%
  \def\corasdiagram@y{0}%
  \def\corasdiagram@family{#1}%
  \ifx\corasdiagram@family\@empty
  \else
    \ifx\corasdiagram@family\@empty\else\fi
  \fi
  \ifx\corasdiagram@family\@empty
  \else
    \expandafter\ifx\csname corasdiagram@autoplace@#1@\corasnode@role\endcsname\relax
      \edef\corasnode@at{(0,0)}%
    \else
      \csname corasdiagram@autoplace@#1@\corasnode@role\endcsname
      \corasdiagram@currentx=\dimexpr\corasdiagram@x cm\relax
      \corasdiagram@currenty=\dimexpr\corasdiagram@y cm\relax
      \corasdiagram@applyautominedgegap
      \corasdiagram@makenodecoordfromdimens
      \corasdiagram@avoidautolayoutoverlap
    \fi
  \fi
}

\newcommand{\corasdiagram@tryrelativeplacement}{%
  \ifx\corasnode@rightof\@empty
    \ifx\corasnode@belowof\@empty
      \ifx\corasnode@incidentof\@empty
        \ifx\corasnode@harms\@empty
          \ifx\corasnode@treats\@empty
          \else
            \corasdiagram@preparecurrentplacementmetrics
          \fi
        \else
          \corasdiagram@preparecurrentplacementmetrics
        \fi
      \else
        \corasdiagram@preparecurrentplacementmetrics
      \fi
    \else
      \corasdiagram@preparecurrentplacementmetrics
    \fi
  \else
    \corasdiagram@preparecurrentplacementmetrics
  \fi
  \ifx\corasnode@rightof\@empty
  \else
    \corasdiagram@enforcehorizontalrelativegap{\corasnode@horizontalgap}%
    \edef\corasnode@at{([xshift=\the\corasdiagram@requestedgap]\corasnode@rightof.east)}%
  \fi
  \ifx\corasnode@at\@empty
    \ifx\corasnode@belowof\@empty
    \else
      \corasdiagram@enforceverticalrelativegap{\corasnode@verticalgap}%
      \edef\corasnode@at{([yshift=-\the\corasdiagram@requestedgap]\corasnode@belowof.south)}%
    \fi
  \fi
  \ifx\corasnode@at\@empty
    \ifx\corasnode@incidentof\@empty
    \else
      \corasdiagram@enforcehorizontalrelativegap{\corasnode@horizontalgap}%
      \edef\corasnode@at{([xshift=\the\corasdiagram@requestedgap]\corasnode@incidentof.east)}%
    \fi
  \fi
  \ifx\corasnode@at\@empty
    \ifx\corasnode@harms\@empty
    \else
      \corasdiagram@enforcehorizontalrelativegap{\corasnode@horizontalgap}%
      \edef\corasnode@at{([xshift=-\the\corasdiagram@requestedgap]\corasnode@harms.west)}%
    \fi
  \fi
  \ifx\corasnode@at\@empty
    \ifx\corasnode@treats\@empty
    \else
      \corasdiagram@enforceverticalrelativegap{\corasnode@verticalgap}%
      \edef\corasnode@at{([yshift=\the\corasdiagram@requestedgap]\corasnode@treats.north)}%
    \fi
  \fi
}

\newcommand{\corasdiagram@resolveplacement}{%
  \ifx\corasnode@at\@empty
    \corasdiagram@tryrelativeplacement
  \fi
  \ifx\corasnode@at\@empty
    \edef\corasdiagram@layoutchoice{\corasnode@layout}%
    \ifx\corasdiagram@layoutchoice\@empty
      \edef\corasdiagram@layoutchoice{\corasdiagram@layoutmode}%
    \fi
    \def\corasdiagram@manual{manual}%
    \ifx\corasdiagram@layoutchoice\corasdiagram@manual
      \edef\corasnode@at{(0,0)}%
    \else
      \corasdiagram@setroleplacement{\corasdiagram@currentfamily}%
    \fi
  \fi
}

\expandafter\def\csname corasdiagram@autoplace@asset@stakeholder\endcsname{%
  \pgfmathtruncatemacro{\corasdiagram@lanegroup}{int((\corasdiagram@laneindex - 1)/2)}%
  \pgfmathtruncatemacro{\corasdiagram@isright}{mod(\corasdiagram@laneindex,2)}%
  \ifnum\corasdiagram@isright=1\relax
    \def\corasdiagram@x{0}%
  \else
    \def\corasdiagram@x{10}%
  \fi
  \pgfmathsetmacro{\corasdiagram@y}{3.1 - 3.4*\corasdiagram@lanegroup}%
}
\expandafter\def\csname corasdiagram@autoplace@asset@asset\endcsname{%
  \pgfmathtruncatemacro{\corasdiagram@lanegroup}{int((\corasdiagram@laneindex - 1)/2)}%
  \pgfmathtruncatemacro{\corasdiagram@isright}{mod(\corasdiagram@laneindex,2)}%
  \ifnum\corasdiagram@isright=1\relax
    \def\corasdiagram@x{3.8}%
    \pgfmathsetmacro{\corasdiagram@y}{1.4 - 2.6*\corasdiagram@lanegroup}%
  \else
    \def\corasdiagram@x{7.2}%
    \pgfmathsetmacro{\corasdiagram@y}{2.8 - 2.6*\corasdiagram@lanegroup}%
  \fi
}

\expandafter\def\csname corasdiagram@autoplace@threat@threatsource\endcsname{%
  \def\corasdiagram@x{0}%
  \pgfmathsetmacro{\corasdiagram@y}{2.8 - 3.1*(\corasdiagram@laneindex - 1)}%
}
\expandafter\def\csname corasdiagram@autoplace@threat@vulnerability\endcsname{%
  \def\corasdiagram@x{3.3}%
  \pgfmathsetmacro{\corasdiagram@y}{2.4 - 3.1*(\corasdiagram@laneindex - 1)}%
}
\expandafter\def\csname corasdiagram@autoplace@threat@scenario\endcsname{%
  \def\corasdiagram@x{6.6}%
  \pgfmathsetmacro{\corasdiagram@y}{3.8 - 2.4*(\corasdiagram@laneindex - 1)}%
}
\expandafter\def\csname corasdiagram@autoplace@threat@incident\endcsname{%
  \def\corasdiagram@x{10.2}%
  \pgfmathsetmacro{\corasdiagram@y}{2.8 - 3.1*(\corasdiagram@laneindex - 1)}%
}
\expandafter\def\csname corasdiagram@autoplace@threat@asset\endcsname{%
  \def\corasdiagram@x{13.3}%
  \pgfmathsetmacro{\corasdiagram@y}{2.6 - 3.1*(\corasdiagram@laneindex - 1)}%
}

\expandafter\def\csname corasdiagram@autoplace@risk@threatsource\endcsname{%
  \def\corasdiagram@x{0}%
  \pgfmathsetmacro{\corasdiagram@y}{1.8 - 3.1*(\corasdiagram@laneindex - 1)}%
}
\expandafter\def\csname corasdiagram@autoplace@risk@risk\endcsname{%
  \def\corasdiagram@x{4.2}%
  \pgfmathsetmacro{\corasdiagram@y}{2.8 - 2.4*(\corasdiagram@laneindex - 1)}%
}
\expandafter\def\csname corasdiagram@autoplace@risk@asset\endcsname{%
  \def\corasdiagram@x{8.1}%
  \pgfmathsetmacro{\corasdiagram@y}{2.4 - 3.1*(\corasdiagram@laneindex - 1)}%
}

\expandafter\def\csname corasdiagram@autoplace@treatment@treatment\endcsname{%
  \pgfmathsetmacro{\corasdiagram@x}{1.6 + 4.2*(\corasdiagram@laneindex - 1)}%
  \def\corasdiagram@y{5.2}%
}
\expandafter\def\csname corasdiagram@autoplace@treatment@threatsource\endcsname{%
  \def\corasdiagram@x{0}%
  \pgfmathsetmacro{\corasdiagram@y}{2.4 - 3.1*(\corasdiagram@laneindex - 1)}%
}
\expandafter\def\csname corasdiagram@autoplace@treatment@vulnerability\endcsname{%
  \def\corasdiagram@x{3.3}%
  \pgfmathsetmacro{\corasdiagram@y}{2.1 - 3.1*(\corasdiagram@laneindex - 1)}%
}
\expandafter\def\csname corasdiagram@autoplace@treatment@scenario\endcsname{%
  \def\corasdiagram@x{6.6}%
  \pgfmathsetmacro{\corasdiagram@y}{3.3 - 2.4*(\corasdiagram@laneindex - 1)}%
}
\expandafter\def\csname corasdiagram@autoplace@treatment@incident\endcsname{%
  \def\corasdiagram@x{10.3}%
  \pgfmathsetmacro{\corasdiagram@y}{2.6 - 3.1*(\corasdiagram@laneindex - 1)}%
}
\expandafter\def\csname corasdiagram@autoplace@treatment@asset\endcsname{%
  \def\corasdiagram@x{13.4}%
  \pgfmathsetmacro{\corasdiagram@y}{2.2 - 3.1*(\corasdiagram@laneindex - 1)}%
}

\expandafter\def\csname corasdiagram@autoplace@treatmentoverview@risk\endcsname{%
  \def\corasdiagram@x{4.2}%
  \pgfmathsetmacro{\corasdiagram@y}{2.4 - 3.0*(\corasdiagram@laneindex - 1)}%
}
\expandafter\def\csname corasdiagram@autoplace@treatmentoverview@asset\endcsname{%
  \def\corasdiagram@x{7.7}%
  \pgfmathsetmacro{\corasdiagram@y}{2.0 - 3.0*(\corasdiagram@laneindex - 1)}%
}
\expandafter\def\csname corasdiagram@autoplace@treatmentoverview@junction\endcsname{%
  \def\corasdiagram@x{5.0}%
  \def\corasdiagram@y{-3.2}%
}
\expandafter\def\csname corasdiagram@autoplace@treatmentoverview@treatment\endcsname{%
  \pgfmathsetmacro{\corasdiagram@x}{2.0 + 3.4*(\corasdiagram@laneindex - 1)}%
  \def\corasdiagram@y{-5.1}%
}

\expandafter\def\csname corasdiagram@autogap@threat@threatsource\endcsname{%
  \corasdiagram@enforceleftofrole{vulnerability}%
}
\expandafter\def\csname corasdiagram@autogap@threat@vulnerability\endcsname{%
  \corasdiagram@enforcerightofrole{threatsource}%
  \corasdiagram@enforceleftofrole{scenario}%
}
\expandafter\def\csname corasdiagram@autogap@threat@scenario\endcsname{%
  \corasdiagram@enforcerightofrole{vulnerability}%
  \corasdiagram@enforceleftofrole{incident}%
  \corasdiagram@enforcebelowsamerole{scenario}%
}
\expandafter\def\csname corasdiagram@autogap@threat@incident\endcsname{%
  \corasdiagram@enforcerightofrole{scenario}%
  \corasdiagram@enforceleftofrole{asset}%
  \corasdiagram@enforcebelowsamerole{incident}%
}
\expandafter\def\csname corasdiagram@autogap@threat@asset\endcsname{%
  \corasdiagram@enforcerightofrole{incident}%
  \corasdiagram@enforcebelowsamerole{asset}%
}

\expandafter\def\csname corasdiagram@autogap@risk@threatsource\endcsname{%
  \corasdiagram@enforceleftofrole{risk}%
}
\expandafter\def\csname corasdiagram@autogap@risk@risk\endcsname{%
  \corasdiagram@enforcerightofrole{threatsource}%
  \corasdiagram@enforceleftofrole{asset}%
  \corasdiagram@enforcebelowsamerole{risk}%
}
\expandafter\def\csname corasdiagram@autogap@risk@asset\endcsname{%
  \corasdiagram@enforcerightofrole{risk}%
  \corasdiagram@enforcebelowsamerole{asset}%
}

\expandafter\def\csname corasdiagram@autogap@treatment@threatsource\endcsname{%
  \corasdiagram@enforceleftofrole{vulnerability}%
}
\expandafter\def\csname corasdiagram@autogap@treatment@vulnerability\endcsname{%
  \corasdiagram@enforcerightofrole{threatsource}%
  \corasdiagram@enforceleftofrole{scenario}%
}
\expandafter\def\csname corasdiagram@autogap@treatment@scenario\endcsname{%
  \corasdiagram@enforcerightofrole{vulnerability}%
  \corasdiagram@enforceleftofrole{incident}%
  \corasdiagram@enforcebelowsamerole{scenario}%
}
\expandafter\def\csname corasdiagram@autogap@treatment@incident\endcsname{%
  \corasdiagram@enforcerightofrole{scenario}%
  \corasdiagram@enforceleftofrole{asset}%
}
\expandafter\def\csname corasdiagram@autogap@treatment@asset\endcsname{%
  \corasdiagram@enforcerightofrole{incident}%
}
\expandafter\def\csname corasdiagram@autogap@treatment@treatment\endcsname{%
  \corasdiagram@enforcerightofsamerole{treatment}%
  \corasdiagram@enforceaboverole{threatsource}%
  \corasdiagram@enforceaboverole{vulnerability}%
  \corasdiagram@enforceaboverole{scenario}%
  \corasdiagram@enforceaboverole{incident}%
  \corasdiagram@enforceaboverole{asset}%
}

\expandafter\def\csname corasdiagram@autogap@treatmentoverview@risk\endcsname{%
  \corasdiagram@enforcebelowsamerole{risk}%
}
\expandafter\def\csname corasdiagram@autogap@treatmentoverview@asset\endcsname{%
  \corasdiagram@enforcerightofrole{risk}%
  \corasdiagram@enforcebelowsamerole{asset}%
}
\expandafter\def\csname corasdiagram@autogap@treatmentoverview@junction\endcsname{%
  \corasdiagram@enforcebelowallplacedrole{risk}%
}
\expandafter\def\csname corasdiagram@autogap@treatmentoverview@treatment\endcsname{%
  \corasdiagram@enforcerightofsamerole{treatment}%
  \corasdiagram@enforcebelowallplacedrole{junction}%
}

\newcommand{\corasdiagram@secondarytext}[1]{%
  {\scriptsize\itshape\color{black!65}#1}%
}

\newcommand{\corasdiagram@composecontent}[1]{%
  \parbox{#1}{%
    \centering
    \strut\corasnode@title\strut
    \ifx\corasnode@meta\@empty
    \else
      \\[-0.1ex]\corasdiagram@secondarytext{\corasnode@meta}%
    \fi
    \ifx\corasnode@level\@empty
    \else
      \\[-0.1ex]\corasdiagram@secondarytext{[\corasnode@level]}%
    \fi
  }%
}

\newcommand{\corasdiagram@composeautocontent}{%
  \begin{tabular}{@{}c@{}}
    \strut\corasnode@title\strut
    \ifx\corasnode@meta\@empty
    \else
      \\[-0.1ex]\corasdiagram@secondarytext{\corasnode@meta}%
    \fi
    \ifx\corasnode@level\@empty
    \else
      \\[-0.1ex]\corasdiagram@secondarytext{[\corasnode@level]}%
    \fi
  \end{tabular}%
}

\newcommand{\corasdiagram@placenode}[3]{%
  \edef\corasdiagram@nodeoptions{#1,\corasnode@tikz}%
  \expandafter\node\expandafter[\corasdiagram@nodeoptions] (#2) at \corasnode@at {#3};
}

\newcommand{\corasdiagram@placeauxnode}[4]{%
  \edef\corasdiagram@auxnodeoptions{#1,#4}%
  \expandafter\node\expandafter[\corasdiagram@auxnodeoptions] (#2) {#3};
}

\newcommand{\corasdiagram@fitpublicnode}[2]{%
  \node[inner sep=0pt,outer sep=0pt,fit=#2] (#1) {};
}

\newcommand{\corasdiagram@storepublicnodesize}[1]{%
  \pgfextractx{\corasdiagram@tmpdimen}{%
    \pgfpointdiff{\pgfpointanchor{#1}{west}}{\pgfpointanchor{#1}{east}}%
  }%
  \corasdiagram@compartmentwidth=\corasdiagram@tmpdimen\relax
  \ifdim\corasdiagram@compartmentwidth<0pt
    \corasdiagram@compartmentwidth=-\corasdiagram@compartmentwidth
  \fi
  \pgfextracty{\corasdiagram@tmpdimen}{%
    \pgfpointdiff{\pgfpointanchor{#1}{south}}{\pgfpointanchor{#1}{north}}%
  }%
  \corasdiagram@compartmentheight=\corasdiagram@tmpdimen\relax
  \ifdim\corasdiagram@compartmentheight<0pt
    \corasdiagram@compartmentheight=-\corasdiagram@compartmentheight
  \fi
  \corasdiagram@setnodeprop{publicwidth}{#1}{\the\corasdiagram@compartmentwidth}%
  \corasdiagram@setnodeprop{publicheight}{#1}{\the\corasdiagram@compartmentheight}%
  \pgfextractx{\corasdiagram@tmpdimen}{\pgfpointanchor{#1}{center}}%
  \corasdiagram@setnodeprop{centerx}{#1}{\the\corasdiagram@tmpdimen}%
  \pgfextracty{\corasdiagram@tmpdimen}{\pgfpointanchor{#1}{center}}%
  \corasdiagram@setnodeprop{centery}{#1}{\the\corasdiagram@tmpdimen}%
}

\newcommand{\corasdiagram@fitanchor}[3]{%
  \node[#1,fit=(#3),inner sep=0pt,outer sep=0pt] (#2-anchor) {};
}

\newcommand{\corasdiagram@resolveendpoint}[1]{%
  \edef\corasdiagram@rawendpoint{#1}%
  \in@{(}{\corasdiagram@rawendpoint}%
  \ifin@
    \edef\corasdiagram@resolvedendpoint{\corasdiagram@rawendpoint}%
  \else
    \in@{.}{\corasdiagram@rawendpoint}%
    \ifin@
      \expandafter\corasdiagram@splitendpoint\corasdiagram@rawendpoint\@nil
    \else
      \def\corasdiagram@endpointbase{\corasdiagram@rawendpoint}%
      \let\corasdiagram@endpointsuffix\@empty
    \fi
    \expandafter\ifcsname pgf@sh@ns@\corasdiagram@endpointbase-anchor\endcsname
      \ifx\corasdiagram@endpointsuffix\@empty
        \edef\corasdiagram@resolvedendpoint{\corasdiagram@endpointbase-anchor}%
      \else
        \edef\corasdiagram@resolvedendpoint{\corasdiagram@endpointbase-anchor.\corasdiagram@endpointsuffix}%
      \fi
    \else
      \edef\corasdiagram@resolvedendpoint{\corasdiagram@rawendpoint}%
    \fi
  \fi
}

\def\corasdiagram@splitendpoint#1.#2\@nil{%
  \def\corasdiagram@endpointbase{#1}%
  \def\corasdiagram@endpointsuffix{#2}%
}

\newcommand{\corasdiagram@endpointbasename}[2]{%
  \edef\corasdiagram@rawendpoint{#2}%
  \in@{(}{\corasdiagram@rawendpoint}%
  \ifin@
    \let#1\@empty
  \else
    \in@{.}{\corasdiagram@rawendpoint}%
    \ifin@
      \expandafter\corasdiagram@splitendpoint\corasdiagram@rawendpoint\@nil
      \edef#1{\corasdiagram@endpointbase}%
    \else
      \edef#1{\corasdiagram@rawendpoint}%
    \fi
  \fi
}

\newcommand{\corasdiagram@lookupendpointrole}[2]{%
  \corasdiagram@endpointbasename{\corasdiagram@basename}{#2}%
  \ifx\corasdiagram@basename\@empty
    \let#1\@empty
  \else
    \corasdiagram@getnodeprop{role}{\corasdiagram@basename}{#1}%
  \fi
}

\newcommand{\corasdiagram@registernode}[1]{%
  \corasdiagram@validatecurrentrole{\corasnode@type}{\corasnode@role}%
  \corasdiagram@setnodeprop{role}{#1}{\corasnode@role}%
  \corasdiagram@setnodeprop{type}{#1}{\corasnode@type}%
  \corasdiagram@setnodeprop{scope}{#1}{\corasnode@scope}%
  \corasdiagram@setnodeprop{orderindex}{#1}{\corasnode@resolvedorder}%
  \ifx\corasnode@resolvedorder\@empty
  \else
    \corasdiagram@setroleordernode{\corasnode@role}{\corasnode@resolvedorder}{#1}%
  \fi
  \corasdiagram@registerscopemember{\corasnode@scope}{#1}%
  \corasdiagram@registerplacednode{#1}%
}

\newcommand{\corasdiagram@rendericonlabelnode}[1]{%
  \def\corasdiagram@iconanchoroptions{\corasnode@anchorstyle,coras/invisible anchor}%
  \ifx\corasnode@anchorwidth\@empty
  \else
    \edef\corasdiagram@iconanchoroptions{\corasdiagram@iconanchoroptions,minimum width=\corasnode@anchorwidth}%
  \fi
  \ifx\corasnode@anchorheight\@empty
  \else
    \edef\corasdiagram@iconanchoroptions{\corasdiagram@iconanchoroptions,minimum height=\corasnode@anchorheight}%
  \fi
  \corasdiagram@placenode{\corasdiagram@iconanchoroptions}{\corasnode@name-anchor}{}%
  \node[coras/base node] (\corasnode@name-graphic) at \corasnode@at {%
    \corasdiagram@includeicon{\corasnode@iconwidth}{#1}%
  };
  \def\corasdiagram@labelnodeoptions{coras/base node,anchor=north}%
  \ifx\corasnode@textwidth\@empty
    \def\corasdiagram@labelcontent{\corasdiagram@composeautocontent}%
  \else
    \edef\corasdiagram@labelnodeoptions{\corasdiagram@labelnodeoptions,text width=\corasnode@textwidth}%
    \def\corasdiagram@labelcontent{\corasdiagram@composecontent{\corasnode@textwidth}}%
  \fi
  \corasdiagram@placeauxnode{\corasdiagram@labelnodeoptions}{\corasnode@name-label}{%
    \corasdiagram@labelcontent
  }{at={([yshift=\corasnode@labelgap]\corasnode@name-graphic.south)}}%
  \corasdiagram@fitpublicnode{\corasnode@name}{(\corasnode@name-graphic) (\corasnode@name-label)}%
  \corasdiagram@storepublicnodesize{\corasnode@name}%
  \corasdiagram@setnodeprop{bordernode}{\corasnode@name}{\corasnode@name-anchor}%
  \ifx\corasnode@anchorsymbol\@empty
  \else
    \corasdiagram@setnodeprop{anchorsymbol}{\corasnode@name}{\corasnode@anchorsymbol}%
  \fi
}

\newcommand{\corasdiagram@render@asset}{%
  \corasdiagram@setdefault\corasnode@textwidth{26mm}%
  \corasdiagram@setdefault\corasnode@iconwidth{10mm}%
  \corasdiagram@setdefault\corasnode@anchorstyle{coras/asset anchor}%
  \corasdiagram@setdefault\corasnode@anchorwidth{0pt}%
  \corasdiagram@setdefault\corasnode@anchorheight{0pt}%
  \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}%
  \corasdiagram@setdefault\corasnode@perspective{before}%
  \def\corasnode@anchorsymbol{asset}%
  \corasdiagram@resolveiconstem{asset}{\corasnode@perspective}{\corasdiagram@resolvediconstem}%
  \corasdiagram@rendericonlabelnode{\corasdiagram@resolvediconstem}%
}

\newcommand{\corasdiagram@render@indirectasset}{%
  \corasdiagram@setdefault\corasnode@textwidth{26mm}%
  \corasdiagram@setdefault\corasnode@iconwidth{10mm}%
  \corasdiagram@setdefault\corasnode@anchorstyle{coras/indirect asset anchor}%
  \corasdiagram@setdefault\corasnode@anchorwidth{0pt}%
  \corasdiagram@setdefault\corasnode@anchorheight{0pt}%
  \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}%
  \corasdiagram@setdefault\corasnode@perspective{before}%
  \def\corasnode@anchorsymbol{indirectasset}%
  \corasdiagram@resolveiconstem{indirect-asset}{\corasnode@perspective}{\corasdiagram@resolvediconstem}%
  \corasdiagram@rendericonlabelnode{\corasdiagram@resolvediconstem}%
}

\newcommand{\corasdiagram@render@stakeholder}{%
  \corasdiagram@setdefault\corasnode@iconwidth{7mm}%
  \corasdiagram@setdefault\corasnode@anchorstyle{coras/stakeholder anchor}%
  \corasdiagram@setdefault\corasnode@anchorwidth{0pt}%
  \corasdiagram@setdefault\corasnode@anchorheight{0pt}%
  \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}%
  \corasdiagram@setdefault\corasnode@perspective{before}%
  \def\corasnode@anchorsymbol{stakeholder}%
  \corasdiagram@resolveiconstem{stakeholder}{\corasnode@perspective}{\corasdiagram@resolvediconstem}%
  \corasdiagram@rendericonlabelnode{\corasdiagram@resolvediconstem}%
}

\newcommand{\corasdiagram@render@threataccidental}{%
  \corasdiagram@setdefault\corasnode@textwidth{23mm}%
  \corasdiagram@setdefault\corasnode@iconwidth{10mm}%
  \corasdiagram@setdefault\corasnode@anchorstyle{coras/threat accidental anchor}%
  \corasdiagram@setdefault\corasnode@anchorwidth{0pt}%
  \corasdiagram@setdefault\corasnode@anchorheight{0pt}%
  \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}%
  \corasdiagram@setdefault\corasnode@perspective{before}%
  \def\corasnode@anchorsymbol{threataccidental}%
  \corasdiagram@resolveiconstem{threat-human-accidental}{\corasnode@perspective}{\corasdiagram@resolvediconstem}%
  \corasdiagram@rendericonlabelnode{\corasdiagram@resolvediconstem}%
}

\newcommand{\corasdiagram@render@threatdeliberate}{%
  \corasdiagram@setdefault\corasnode@textwidth{23mm}%
  \corasdiagram@setdefault\corasnode@iconwidth{10mm}%
  \corasdiagram@setdefault\corasnode@anchorstyle{coras/threat deliberate anchor}%
  \corasdiagram@setdefault\corasnode@anchorwidth{0pt}%
  \corasdiagram@setdefault\corasnode@anchorheight{0pt}%
  \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}%
  \corasdiagram@setdefault\corasnode@perspective{before}%
  \def\corasnode@anchorsymbol{threatdeliberate}%
  \corasdiagram@resolveiconstem{threat-human-deliberate}{\corasnode@perspective}{\corasdiagram@resolvediconstem}%
  \corasdiagram@rendericonlabelnode{\corasdiagram@resolvediconstem}%
}

\newcommand{\corasdiagram@render@threatnonhuman}{%
  \corasdiagram@setdefault\corasnode@textwidth{26mm}%
  \corasdiagram@setdefault\corasnode@iconwidth{13mm}%
  \corasdiagram@setdefault\corasnode@anchorstyle{coras/threat nonhuman anchor}%
  \corasdiagram@setdefault\corasnode@anchorwidth{0pt}%
  \corasdiagram@setdefault\corasnode@anchorheight{0pt}%
  \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}%
  \corasdiagram@setdefault\corasnode@perspective{before}%
  \def\corasnode@anchorsymbol{threatnonhuman}%
  \corasdiagram@resolveiconstem{threat-non-human}{\corasnode@perspective}{\corasdiagram@resolvediconstem}%
  \corasdiagram@rendericonlabelnode{\corasdiagram@resolvediconstem}%
}

\newcommand{\corasdiagram@render@vulnerability}{%
  \corasdiagram@setdefault\corasnode@textwidth{22mm}%
  \corasdiagram@setdefault\corasnode@iconwidth{8mm}%
  \corasdiagram@setdefault\corasnode@anchorstyle{coras/vulnerability anchor}%
  \corasdiagram@setdefault\corasnode@anchorwidth{0pt}%
  \corasdiagram@setdefault\corasnode@anchorheight{0pt}%
  \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}%
  \corasdiagram@setdefault\corasnode@perspective{before}%
  \def\corasnode@anchorsymbol{vulnerability}%
  \corasdiagram@resolveiconstem{vulnerability}{\corasnode@perspective}{\corasdiagram@resolvediconstem}%
  \corasdiagram@rendericonlabelnode{\corasdiagram@resolvediconstem}%
}

\newcommand{\corasdiagram@render@scenario}{%
  \corasdiagram@setdefault\corasnode@textwidth{28mm}%
  \corasdiagram@setdefault\corasnode@iconwidth{6.2mm}%
  \corasdiagram@setdefault\corasnode@perspective{before}%
  \corasdiagram@placenode{%
    coras/ellipse,
    text width=\corasnode@textwidth
  }{\corasnode@name-body}{\corasdiagram@composecontent{\corasnode@textwidth}}%
  \corasdiagram@resolveiconstem{risk}{\corasnode@perspective}{\corasdiagram@resolvediconstem}%
  \node[coras/base node,anchor=center] (\corasnode@name-icon)
    at (\corasnode@name-body.north)
    {\corasdiagram@includeicon{\corasnode@iconwidth}{\corasdiagram@resolvediconstem}};
  \corasdiagram@fitanchor{coras/anchor ellipse}{\corasnode@name}{\corasnode@name-body}%
  \corasdiagram@fitpublicnode{\corasnode@name}{(\corasnode@name-body) (\corasnode@name-icon)}%
  \corasdiagram@storepublicnodesize{\corasnode@name}%
  \corasdiagram@setnodeprop{bordernode}{\corasnode@name}{\corasnode@name-body}%
}

\newcommand{\corasdiagram@render@incident}{%
  \corasdiagram@setdefault\corasnode@textwidth{25mm}%
  \corasdiagram@setdefault\corasnode@iconwidth{5.6mm}%
  \corasdiagram@setdefault\corasnode@perspective{before}%
  \corasdiagram@placenode{%
    coras/incident body,
    text width=\corasnode@textwidth
  }{\corasnode@name-body}{\corasdiagram@composecontent{\corasnode@textwidth}}%
  \corasdiagram@resolveiconstem{unwanted-incident}{\corasnode@perspective}{\corasdiagram@resolvediconstem}%
  \node[coras/base node,anchor=center] (\corasnode@name-icon)
    at ([xshift=-1.6mm]\corasnode@name-body.north east)
    {\corasdiagram@includeicon{\corasnode@iconwidth}{\corasdiagram@resolvediconstem}};
  \corasdiagram@fitanchor{coras/anchor rectangle}{\corasnode@name}{\corasnode@name-body}%
  \corasdiagram@fitpublicnode{\corasnode@name}{(\corasnode@name-body) (\corasnode@name-icon)}%
  \corasdiagram@storepublicnodesize{\corasnode@name}%
  \corasdiagram@setnodeprop{bordernode}{\corasnode@name}{\corasnode@name-body}%
}

\newcommand{\corasdiagram@render@risk}{%
  \corasdiagram@setdefault\corasnode@textwidth{27mm}%
  \corasdiagram@setdefault\corasnode@iconwidth{6.5mm}%
  \corasdiagram@setdefault\corasnode@perspective{before}%
  \corasdiagram@placenode{%
    coras/risk body,
    text width=\corasnode@textwidth
  }{\corasnode@name-body}{\corasdiagram@composecontent{\corasnode@textwidth}}%
  \corasdiagram@resolveiconstem{risk}{\corasnode@perspective}{\corasdiagram@resolvediconstem}%
  \node[coras/base node,anchor=south] (\corasnode@name-icon)
    at ([yshift=0.5mm]\corasnode@name-body.north)
    {\corasdiagram@includeicon{\corasnode@iconwidth}{\corasdiagram@resolvediconstem}};
  \corasdiagram@fitanchor{coras/anchor rectangle}{\corasnode@name}{\corasnode@name-body}%
  \corasdiagram@fitpublicnode{\corasnode@name}{(\corasnode@name-body) (\corasnode@name-icon)}%
  \corasdiagram@storepublicnodesize{\corasnode@name}%
  \corasdiagram@setnodeprop{bordernode}{\corasnode@name}{\corasnode@name-body}%
}

\newcommand{\corasdiagram@render@treatment}{%
  \corasdiagram@setdefault\corasnode@textwidth{24mm}%
  \corasdiagram@setdefault\corasnode@iconwidth{7mm}%
  \corasdiagram@setdefault\corasnode@perspective{before}%
  \corasdiagram@placenode{%
    coras/treatment body,
    text width=\corasnode@textwidth
  }{\corasnode@name-body}{\corasdiagram@composecontent{\corasnode@textwidth}}%
  \corasdiagram@resolveiconstem{treatment}{\corasnode@perspective}{\corasdiagram@resolvediconstem}%
  \node[coras/base node,anchor=center] (\corasnode@name-icon)
    at (\corasnode@name-body.north)
    {\corasdiagram@includeicon{\corasnode@iconwidth}{\corasdiagram@resolvediconstem}};
  \corasdiagram@fitanchor{coras/anchor ellipse}{\corasnode@name}{\corasnode@name-body}%
  \corasdiagram@fitpublicnode{\corasnode@name}{(\corasnode@name-body) (\corasnode@name-icon)}%
  \corasdiagram@storepublicnodesize{\corasnode@name}%
  \corasdiagram@setnodeprop{bordernode}{\corasnode@name}{\corasnode@name-body}%
}

\newcommand{\corasdiagram@render@junction}{%
  \corasdiagram@placenode{coras/junction}{\corasnode@name}{}%
  \corasdiagram@fitanchor{coras/anchor ellipse}{\corasnode@name}{\corasnode@name}%
  \corasdiagram@storepublicnodesize{\corasnode@name}%
  \corasdiagram@setnodeprop{bordernode}{\corasnode@name}{\corasnode@name}%
}

\pgfkeys{
  /coras/node/.is family,
  /coras/node,
  type/.store in=\corasnode@type,
  name/.store in=\corasnode@name,
  title/.store in=\corasnode@title,
  label/.store in=\corasnode@label,
  meta/.store in=\corasnode@meta,
  level/.store in=\corasnode@level,
  value/.store in=\corasnode@value,
  perspective/.store in=\corasnode@perspective,
  at/.store in=\corasnode@at,
  scope/.store in=\corasnode@scope,
  order/.store in=\corasnode@order,
  text width/.store in=\corasnode@textwidth,
  icon width/.store in=\corasnode@iconwidth,
  anchor style/.store in=\corasnode@anchorstyle,
  anchor width/.store in=\corasnode@anchorwidth,
  anchor height/.store in=\corasnode@anchorheight,
  label gap/.store in=\corasnode@labelgap,
  layout/.store in=\corasnode@layout,
  min edge gap/.store in=\corasnode@minedgegap,
  right of/.store in=\corasnode@rightof,
  below of/.store in=\corasnode@belowof,
  incident of/.store in=\corasnode@incidentof,
  treats/.store in=\corasnode@treats,
  harms/.store in=\corasnode@harms,
  horizontal gap/.store in=\corasnode@horizontalgap,
  vertical gap/.store in=\corasnode@verticalgap,
  tikz/.store in=\corasnode@tikz,
}

\NewDocumentCommand{\corasnode}{O{}}{%
  \pgfkeys{/coras/node/.cd,%
    type=asset,%
    name=,%
    title=,%
    label=,%
    meta=,%
    level=,%
    value=,%
    perspective=before,%
    at=,%
    scope=,%
    order=,%
    text width=,%
    icon width=,%
    anchor style=,%
    anchor width=,%
    anchor height=,%
    label gap=,%
    layout=,%
    min edge gap=,%
    right of=,%
    below of=,%
    incident of=,%
    treats=,%
    harms=,%
    horizontal gap=12mm,%
    vertical gap=14mm,%
    tikz=,%
    #1%
  }%
  \let\corasnode@resolvedorder\@empty
  \corasdiagram@ensurename\corasnode@name
  \ifx\corasnode@title\@empty
    \edef\corasnode@title{\corasnode@label}%
  \fi
  \corasdiagram@maptyperole{\corasnode@type}%
  \edef\corasnode@role{\corasdiagram@mappedrole}%
  \ifx\corasnode@level\@empty
    \ifx\corasnode@value\@empty
    \else
      \edef\corasnode@level{\corasnode@value}%
    \fi
  \fi
  \corasdiagram@resolveplacement
  \corasdiagram@normalize\corasnode@tikz
  \let\corasnode@anchorsymbol\@empty
  \@ifundefined{corasdiagram@render@\corasnode@type}{%
    \PackageError{corasdiagram}{Unknown node type `\corasnode@type'}{%
      Valid node types are asset, stakeholder, threataccidental,
      threatdeliberate, threatnonhuman, vulnerability, indirectasset, scenario,
      incident, risk, treatment, and junction.%
    }%
  }{%
    \csname corasdiagram@render@\corasnode@type\endcsname
    \corasdiagram@registernode{\corasnode@name}%
  }%
}

\pgfkeys{
  /coras/edge/.is family,
  /coras/edge,
  from/.store in=\corasedge@from,
  to/.store in=\corasedge@to,
  type/.store in=\corasedge@type,
  semantic/.store in=\corasedge@semantic,
  label/.store in=\corasedge@label,
  pos/.store in=\corasedge@pos,
  path/.store in=\corasedge@path,
  route/.store in=\corasedge@route,
  tikz/.store in=\corasedge@tikz,
  label options/.store in=\corasedge@labeloptions,
}

\newcommand{\corasdiagram@resolvedgesemantic}{%
  \ifx\corasedge@semantic\@empty
    \edef\corasedge@semantic{\corasedge@type}%
    \def\corasdiagram@overview{overview}%
    \ifx\corasedge@semantic\corasdiagram@overview
      \def\corasedge@semantic{treatment}%
    \fi
  \fi
}

\newcommand{\corasdiagram@defaultpathforroute}{%
  \def\corasdiagram@edgepath{--}%
  \def\corasdiagram@routeauto{auto}%
  \def\corasdiagram@routestraight{straight}%
  \def\corasdiagram@routehv{hv}%
  \def\corasdiagram@routevh{vh}%
  \ifx\corasedge@route\corasdiagram@routehv
    \def\corasdiagram@edgepath{-|}%
  \else\ifx\corasedge@route\corasdiagram@routevh
    \def\corasdiagram@edgepath{|-}%
  \else\ifx\corasedge@route\corasdiagram@routestraight
    \def\corasdiagram@edgepath{--}%
  \else
    \def\corasdiagram@edgepath{--}%
    \def\corasdiagram@concern{concern}%
    \def\corasdiagram@treatmentsemantic{treatment}%
    \ifx\corasedge@semantic\corasdiagram@concern
      \def\corasdiagram@edgepath{-|}%
    \else\ifx\corasedge@semantic\corasdiagram@treatmentsemantic
      \def\corasdiagram@edgepath{--}%
    \fi\fi
  \fi\fi\fi
}

\newcommand{\corasdiagram@setcurveanchorsfromdelta}{%
  \pgfmathtruncatemacro{\corasdiagram@verticaldominant}{abs(\corasdiagram@dy) > abs(\corasdiagram@dx) ? 1 : 0}%
  \ifnum\corasdiagram@verticaldominant=1\relax
    \pgfmathtruncatemacro{\corasdiagram@targetabove}{\corasdiagram@dy > 0 ? 1 : 0}%
    \ifnum\corasdiagram@targetabove=1\relax
      \xdef\corasdiagram@fromanchorsuffix{north}%
      \xdef\corasdiagram@toanchorsuffix{south}%
      \xdef\corasdiagram@curveout{90}%
      \xdef\corasdiagram@curvein{-90}%
    \else
      \xdef\corasdiagram@fromanchorsuffix{south}%
      \xdef\corasdiagram@toanchorsuffix{north}%
      \xdef\corasdiagram@curveout{-90}%
      \xdef\corasdiagram@curvein{90}%
    \fi
  \else
    \pgfmathtruncatemacro{\corasdiagram@targetright}{\corasdiagram@dx > 0 ? 1 : 0}%
    \ifnum\corasdiagram@targetright=1\relax
      \xdef\corasdiagram@fromanchorsuffix{east}%
      \xdef\corasdiagram@toanchorsuffix{west}%
      \xdef\corasdiagram@curveout{0}%
      \xdef\corasdiagram@curvein{180}%
    \else
      \xdef\corasdiagram@fromanchorsuffix{west}%
      \xdef\corasdiagram@toanchorsuffix{east}%
      \xdef\corasdiagram@curveout{180}%
      \xdef\corasdiagram@curvein{0}%
    \fi
  \fi
}

\newcommand{\corasdiagram@newedgecoordname}[1]{%
  \global\advance\corasdiagram@edgecoordseq by 1\relax
  \edef#1{coras-edge-\the\corasdiagram@edgecoordseq}%
}

\newcommand{\corasdiagram@markbordereligible}[3]{%
  \corasdiagram@endpointbasename{#2}{#1}%
  \def#3{0}%
  \ifx#2\@empty
  \else
    \edef\corasdiagram@rawplain{#1}%
    \edef\corasdiagram@baseplain{#2}%
    \ifx\corasdiagram@rawplain\corasdiagram@baseplain
      \corasdiagram@getbordernode{\corasdiagram@lookupbordernode}{#2}%
      \ifx\corasdiagram@lookupbordernode\@empty
      \else
        \def#3{1}%
      \fi
    \fi
  \fi
}

\newcommand{\corasdiagram@makeedgecoord}[2]{%
  \path coordinate (#1) at #2;
}

\newcommand{\corasdiagram@setsnappeddirectionalanchor}{%
  \pgfmathtruncatemacro{\corasdiagram@zerodelta}{abs(\corasdiagram@dx) < 0.02 && abs(\corasdiagram@dy) < 0.02 ? 1 : 0}%
  \ifnum\corasdiagram@zerodelta=1\relax
    \xdef\corasdiagram@snappeddirectionalanchor{north}%
  \else
    \pgfmathsetmacro{\corasdiagram@borderangle}{atan2(\corasdiagram@dy,\corasdiagram@dx)}%
    \ifdim\corasdiagram@borderangle pt>157.5pt\relax
      \xdef\corasdiagram@snappeddirectionalanchor{west}%
    \else\ifdim\corasdiagram@borderangle pt>112.5pt\relax
      \xdef\corasdiagram@snappeddirectionalanchor{northwest}%
    \else\ifdim\corasdiagram@borderangle pt>67.5pt\relax
      \xdef\corasdiagram@snappeddirectionalanchor{north}%
    \else\ifdim\corasdiagram@borderangle pt>22.5pt\relax
      \xdef\corasdiagram@snappeddirectionalanchor{northeast}%
    \else\ifdim\corasdiagram@borderangle pt>-22.5pt\relax
      \xdef\corasdiagram@snappeddirectionalanchor{east}%
    \else\ifdim\corasdiagram@borderangle pt>-67.5pt\relax
      \xdef\corasdiagram@snappeddirectionalanchor{southeast}%
    \else\ifdim\corasdiagram@borderangle pt>-112.5pt\relax
      \xdef\corasdiagram@snappeddirectionalanchor{south}%
    \else
      \ifdim\corasdiagram@borderangle pt>-157.5pt\relax
        \xdef\corasdiagram@snappeddirectionalanchor{southwest}%
      \else
        \xdef\corasdiagram@snappeddirectionalanchor{west}%
      \fi
    \fi\fi\fi\fi\fi\fi\fi
  \fi
}

\newcommand{\corasdiagram@getnodeanchorname}[2]{%
  \expandafter\ifx\csname corasdiagram@nodeanchorname@#2\endcsname\relax
    \edef#1{west}%
  \else
    \edef#1{\csname corasdiagram@nodeanchorname@#2\endcsname}%
  \fi
}
\expandafter\def\csname corasdiagram@nodeanchorname@north\endcsname{north}
\expandafter\def\csname corasdiagram@nodeanchorname@northeast\endcsname{north east}
\expandafter\def\csname corasdiagram@nodeanchorname@east\endcsname{east}
\expandafter\def\csname corasdiagram@nodeanchorname@southeast\endcsname{south east}
\expandafter\def\csname corasdiagram@nodeanchorname@south\endcsname{south}
\expandafter\def\csname corasdiagram@nodeanchorname@southwest\endcsname{south west}
\expandafter\def\csname corasdiagram@nodeanchorname@west\endcsname{west}
\expandafter\def\csname corasdiagram@nodeanchorname@northwest\endcsname{north west}

\newcommand{\corasdiagram@makeiconbordercoord}[3]{%
  \corasdiagram@getbordernode{\corasdiagram@bordernodename}{#1}%
  \path let \p1=(\corasdiagram@bordernodename.center), \p2=(#2.center) in \pgfextra{%
    \pgfmathsetmacro{\corasdiagram@dx}{\x2-\x1}%
    \pgfmathsetmacro{\corasdiagram@dy}{\y2-\y1}%
    \corasdiagram@setsnappeddirectionalanchor
  };%
  \corasdiagram@getnodeanchorname{\corasdiagram@nodeanchorname}{\corasdiagram@snappeddirectionalanchor}%
  \pgf@process{\pgfpointanchor{\corasdiagram@bordernodename}{\corasdiagram@nodeanchorname}}%
  \edef\corasdiagram@borderx{\the\pgf@x}%
  \edef\corasdiagram@bordery{\the\pgf@y}%
  \path coordinate (#3) at (\corasdiagram@borderx,\corasdiagram@bordery);
}

\newcommand{\corasdiagram@makebordercoord}[3]{%
  \corasdiagram@getnodeprop{anchorsymbol}{#1}{\corasdiagram@bordersymbol}%
  \ifx\corasdiagram@bordersymbol\@empty
    \corasdiagram@getbordernode{\corasdiagram@bordernodename}{#1}%
    \edef\corasdiagram@borderrefname{#2}%
    \pgf@process{%
      \expandafter\pgfpointshapeborder\expandafter{\corasdiagram@bordernodename}{%
        \expandafter\pgfpointanchor\expandafter{\corasdiagram@borderrefname}{center}%
      }%
    }%
    \edef\corasdiagram@borderx{\the\pgf@x}%
    \edef\corasdiagram@bordery{\the\pgf@y}%
    \path coordinate (#3) at (\corasdiagram@borderx,\corasdiagram@bordery);
  \else
    \corasdiagram@makeiconbordercoord{#1}{#2}{#3}%
  \fi
}

\newcommand{\corasdiagram@applyexactborderanchors}{%
  \ifx\corasedge@path\@empty
    \corasdiagram@markbordereligible{\corasedge@rawfrom}{\corasdiagram@linefrombase}{\corasdiagram@applyfrom}%
    \corasdiagram@markbordereligible{\corasedge@rawto}{\corasdiagram@linetobase}{\corasdiagram@applyto}%
    \ifnum\corasdiagram@applyfrom=1\relax
      \def\corasdiagram@applyanchors{1}%
    \else\ifnum\corasdiagram@applyto=1\relax
      \def\corasdiagram@applyanchors{1}%
    \else
      \def\corasdiagram@applyanchors{0}%
    \fi\fi
    \ifnum\corasdiagram@applyanchors=1\relax
      \corasdiagram@newedgecoordname{\corasdiagram@actualfromcoord}%
      \corasdiagram@newedgecoordname{\corasdiagram@actualtocoord}%
      \corasdiagram@makeedgecoord{\corasdiagram@actualfromcoord}{(\corasedge@from)}%
      \corasdiagram@makeedgecoord{\corasdiagram@actualtocoord}{(\corasedge@to)}%
      \edef\corasdiagram@fromrefcoord{\corasdiagram@actualtocoord}%
      \edef\corasdiagram@torefcoord{\corasdiagram@actualfromcoord}%
      \def\corasdiagram@edgepathhv{-|}%
      \def\corasdiagram@edgepathvh{|-}%
      \ifx\corasdiagram@edgepath\corasdiagram@edgepathhv
        \corasdiagram@newedgecoordname{\corasdiagram@elbowcoord}%
        \corasdiagram@makeedgecoord{\corasdiagram@elbowcoord}{(\corasedge@from -| \corasedge@to)}%
        \edef\corasdiagram@fromrefcoord{\corasdiagram@elbowcoord}%
        \edef\corasdiagram@torefcoord{\corasdiagram@elbowcoord}%
      \else\ifx\corasdiagram@edgepath\corasdiagram@edgepathvh
        \corasdiagram@newedgecoordname{\corasdiagram@elbowcoord}%
        \corasdiagram@makeedgecoord{\corasdiagram@elbowcoord}{(\corasedge@from |- \corasedge@to)}%
        \edef\corasdiagram@fromrefcoord{\corasdiagram@elbowcoord}%
        \edef\corasdiagram@torefcoord{\corasdiagram@elbowcoord}%
      \fi\fi
      \ifnum\corasdiagram@applyfrom=1\relax
        \corasdiagram@newedgecoordname{\corasdiagram@frombordercoord}%
        \corasdiagram@makebordercoord{\corasdiagram@linefrombase}{\corasdiagram@fromrefcoord}{\corasdiagram@frombordercoord}%
        \edef\corasedge@from{\corasdiagram@frombordercoord}%
      \fi
      \ifnum\corasdiagram@applyto=1\relax
        \corasdiagram@newedgecoordname{\corasdiagram@tobordercoord}%
        \corasdiagram@makebordercoord{\corasdiagram@linetobase}{\corasdiagram@torefcoord}{\corasdiagram@tobordercoord}%
        \edef\corasedge@to{\corasdiagram@tobordercoord}%
      \fi
    \fi
  \fi
}

\newcommand{\corasdiagram@drawcurvededge}{%
  \corasdiagram@markbordereligible{\corasedge@rawfrom}{\corasdiagram@curvefrombase}{\corasdiagram@applycurvefrom}%
  \corasdiagram@markbordereligible{\corasedge@rawto}{\corasdiagram@curvetobase}{\corasdiagram@applycurveto}%
  \ifx\corasdiagram@curvefrombase\@empty
    \def\corasdiagram@curveavailable{0}%
  \else\ifx\corasdiagram@curvetobase\@empty
    \def\corasdiagram@curveavailable{0}%
  \else
    \def\corasdiagram@curveavailable{1}%
  \fi\fi
  \ifnum\corasdiagram@curveavailable=1\relax
    \corasdiagram@newedgecoordname{\corasdiagram@curvefromcenter}%
    \corasdiagram@newedgecoordname{\corasdiagram@curvetocenter}%
    \corasdiagram@makeedgecoord{\corasdiagram@curvefromcenter}{(\corasedge@from)}%
    \corasdiagram@makeedgecoord{\corasdiagram@curvetocenter}{(\corasedge@to)}%
    \path let \p1=(\corasdiagram@curvefromcenter), \p2=(\corasdiagram@curvetocenter) in \pgfextra{%
      \pgfmathsetmacro{\corasdiagram@dx}{\x2-\x1}%
      \pgfmathsetmacro{\corasdiagram@dy}{\y2-\y1}%
      \corasdiagram@setcurveanchorsfromdelta
    };
    \corasdiagram@newedgecoordname{\corasdiagram@curvefirstcontrol}%
    \corasdiagram@newedgecoordname{\corasdiagram@curvesecondcontrol}%
    \corasdiagram@newedgecoordname{\corasdiagram@curvefirstborderref}%
    \corasdiagram@newedgecoordname{\corasdiagram@curvesecondborderref}%
    \corasdiagram@makeedgecoord{\corasdiagram@curvefirstcontrol}{($(\corasdiagram@curvefromcenter)+(\corasdiagram@curveout:8mm)$)}%
    \corasdiagram@makeedgecoord{\corasdiagram@curvesecondcontrol}{($(\corasdiagram@curvetocenter)+(\corasdiagram@curvein:8mm)$)}%
    \corasdiagram@makeedgecoord{\corasdiagram@curvefirstborderref}{($(\corasdiagram@curvefromcenter)+(\corasdiagram@curveout:40mm)$)}%
    \corasdiagram@makeedgecoord{\corasdiagram@curvesecondborderref}{($(\corasdiagram@curvetocenter)+(\corasdiagram@curvein:40mm)$)}%
    \edef\corasdiagram@curvefrom{\corasedge@from}%
    \edef\corasdiagram@curveto{\corasedge@to}%
    \ifnum\corasdiagram@applycurvefrom=1\relax
      \corasdiagram@newedgecoordname{\corasdiagram@curvefromborder}%
      \corasdiagram@makebordercoord{\corasdiagram@curvefrombase}{\corasdiagram@curvefirstborderref}{\corasdiagram@curvefromborder}%
      \edef\corasdiagram@curvefrom{\corasdiagram@curvefromborder}%
    \fi
    \ifnum\corasdiagram@applycurveto=1\relax
      \corasdiagram@newedgecoordname{\corasdiagram@curvetoborder}%
      \corasdiagram@makebordercoord{\corasdiagram@curvetobase}{\corasdiagram@curvesecondborderref}{\corasdiagram@curvetoborder}%
      \edef\corasdiagram@curveto{\corasdiagram@curvetoborder}%
    \fi
    \ifx\corasedge@label\@empty
      \expandafter\draw\expandafter[\corasdiagram@edgeoptions]
        (\corasdiagram@curvefrom)
        .. controls (\corasdiagram@curvefirstcontrol) and (\corasdiagram@curvesecondcontrol) ..
        (\corasdiagram@curveto);
    \else
      \edef\corasdiagram@edgelabelfragment{%
        node[\corasdiagram@edgelabeloptions]{%
          \unexpanded\expandafter{\corasedge@label}%
        }%
      }%
      \expandafter\draw\expandafter[\corasdiagram@edgeoptions]
        (\corasdiagram@curvefrom)
        .. controls (\corasdiagram@curvefirstcontrol) and (\corasdiagram@curvesecondcontrol) ..
        \corasdiagram@edgelabelfragment
        (\corasdiagram@curveto);
    \fi
  \else
    \ifx\corasedge@label\@empty
      \expandafter\draw\expandafter[\corasdiagram@edgeoptions]
        (\corasedge@from) \corasdiagram@edgepath (\corasedge@to);
    \else
      \edef\corasdiagram@edgelabelfragment{%
        node[\corasdiagram@edgelabeloptions]{%
          \unexpanded\expandafter{\corasedge@label}%
        }%
      }%
      \expandafter\draw\expandafter[\corasdiagram@edgeoptions]
        (\corasedge@from) \corasdiagram@edgepath (\corasedge@to)
        \corasdiagram@edgelabelfragment;
    \fi
  \fi
}

\NewDocumentCommand{\corasedge}{O{}}{%
  \pgfkeys{/coras/edge/.cd,%
    from=,%
    to=,%
    type=causal,%
    semantic=,%
    label=,%
    pos=.5,%
    path=,%
    route=auto,%
    tikz=,%
    label options={fill=white,inner sep=1pt},%
    #1%
  }%
  \corasdiagram@normalize\corasedge@tikz
  \corasdiagram@normalize\corasedge@labeloptions
  \ifx\corasedge@from\@empty
    \PackageError{corasdiagram}{Missing `from` key for \string\corasedge}{%
      Use \string\corasedge[from=<node>,to=<node>,type=<style>].%
    }%
  \else\ifx\corasedge@to\@empty
    \PackageError{corasdiagram}{Missing `to` key for \string\corasedge}{%
      Use \string\corasedge[from=<node>,to=<node>,type=<style>].%
    }%
  \else
    \corasdiagram@resolvedgesemantic
    \edef\corasedge@rawfrom{\corasedge@from}%
    \edef\corasedge@rawto{\corasedge@to}%
    \corasdiagram@lookupendpointrole{\corasedge@fromrole}{\corasedge@from}%
    \corasdiagram@lookupendpointrole{\corasedge@torole}{\corasedge@to}%
    \ifx\corasedge@fromrole\@empty
    \else\ifx\corasedge@torole\@empty
    \else
      \corasdiagram@validateedge{\corasedge@semantic}{\corasedge@fromrole}{\corasedge@torole}%
    \fi\fi
    \corasdiagram@resolveendpoint{\corasedge@from}%
    \edef\corasedge@from{\corasdiagram@resolvedendpoint}%
    \corasdiagram@resolveendpoint{\corasedge@to}%
    \edef\corasedge@to{\corasdiagram@resolvedendpoint}%
    \ifx\corasedge@path\@empty
      \corasdiagram@defaultpathforroute
    \else
      \edef\corasdiagram@edgepath{\corasedge@path}%
    \fi
    \corasdiagram@applyexactborderanchors
    \edef\corasdiagram@edgeoptions{coras/\corasedge@type,\corasedge@tikz}%
    \edef\corasdiagram@edgelabeloptions{pos=\corasedge@pos,\corasedge@labeloptions}%
    \def\corasdiagram@treatmentsemantic{treatment}%
    \ifx\corasedge@semantic\corasdiagram@treatmentsemantic
      \ifx\corasedge@path\@empty
        \corasdiagram@drawcurvededge
      \else
        \ifx\corasedge@label\@empty
          \expandafter\draw\expandafter[\corasdiagram@edgeoptions]
            (\corasedge@from) \corasdiagram@edgepath (\corasedge@to);
        \else
          \edef\corasdiagram@edgelabelfragment{%
            node[\corasdiagram@edgelabeloptions]{%
              \unexpanded\expandafter{\corasedge@label}%
            }%
          }%
          \expandafter\draw\expandafter[\corasdiagram@edgeoptions]
            (\corasedge@from) \corasdiagram@edgepath (\corasedge@to)
            \corasdiagram@edgelabelfragment;
        \fi
      \fi
    \else
      \ifx\corasedge@label\@empty
        \expandafter\draw\expandafter[\corasdiagram@edgeoptions]
          (\corasedge@from) \corasdiagram@edgepath (\corasedge@to);
      \else
        \edef\corasdiagram@edgelabelfragment{%
          node[\corasdiagram@edgelabeloptions]{%
            \unexpanded\expandafter{\corasedge@label}%
          }%
        }%
        \expandafter\draw\expandafter[\corasdiagram@edgeoptions]
          (\corasedge@from) \corasdiagram@edgepath (\corasedge@to)
          \corasdiagram@edgelabelfragment;
      \fi
    \fi
  \fi\fi
}

\pgfkeys{
  /coras/scope/.is family,
  /coras/scope,
  name/.store in=\corasscope@name,
  title/.store in=\corasscope@title,
  label/.store in=\corasscope@label,
  kind/.store in=\corasscope@kind,
  scope/.store in=\corasscope@scope,
  fit/.store in=\corasscope@fit,
  padding/.store in=\corasscope@padding,
  stakeholder/.store in=\corasscope@stakeholder,
  stakeholder corner/.store in=\corasscope@stakeholdercorner,
  stakeholder xsep/.store in=\corasscope@stakeholderxsep,
  stakeholder ysep/.store in=\corasscope@stakeholderysep,
  stakeholder tikz/.store in=\corasscope@stakeholdertikz,
  tikz/.store in=\corasscope@tikz,
  title tikz/.store in=\corasscope@titletikz,
}

\newcommand{\corasdiagram@drawstakeholdercompartment}{%
  \ifx\corasscope@stakeholder\@empty
  \else
    \corasdiagram@normalize\corasscope@stakeholdertikz
    \edef\corasdiagram@compartmentoptions{draw,line width=0.45pt,\corasscope@stakeholdertikz}%
    \edef\corasdiagram@stakeholderzoneside{\the\corasdiagram@compartmentside}%
    \def\corasdiagram@cornerright{right}%
    \ifx\corasscope@stakeholdercorner\corasdiagram@cornerright
      \coordinate (\corasscope@name-stakeholder-top)
        at ([xshift=-\corasdiagram@stakeholderzoneside]\corasscope@name.north east);
      \expandafter\draw\expandafter[\corasdiagram@compartmentoptions]
        (\corasscope@name-stakeholder-top)
        -- ([yshift=-\corasdiagram@stakeholderzoneside]\corasscope@name-stakeholder-top)
        -- ([yshift=-\corasdiagram@stakeholderzoneside]\corasscope@name.north east);
    \else
      \coordinate (\corasscope@name-stakeholder-top)
        at ([xshift=\corasdiagram@stakeholderzoneside]\corasscope@name.north west);
      \expandafter\draw\expandafter[\corasdiagram@compartmentoptions]
        (\corasscope@name-stakeholder-top)
        -- ([yshift=-\corasdiagram@stakeholderzoneside]\corasscope@name-stakeholder-top)
        -- ([yshift=-\corasdiagram@stakeholderzoneside]\corasscope@name.north west);
    \fi
  \fi
}

\newcommand{\corasdiagram@prepareassetscope}{%
  \ifx\corasscope@stakeholderxsep\@empty
    \def\corasscope@stakeholderxsep{0.25mm}%
  \fi
  \ifx\corasscope@stakeholderysep\@empty
    \def\corasscope@stakeholderysep{0.25mm}%
  \fi
  \ifx\corasscope@stakeholder\@empty
    \corasdiagram@compartmentside=0pt\relax
    \corasdiagram@halfcompartmentside=0pt\relax
  \else
    \corasdiagram@getnodeprop{publicwidth}{\corasscope@stakeholder}{\corasdiagram@storedstakeholderwidth}%
    \corasdiagram@getnodeprop{publicheight}{\corasscope@stakeholder}{\corasdiagram@storedstakeholderheight}%
    \ifx\corasdiagram@storedstakeholderwidth\@empty
      \corasdiagram@compartmentwidth=0pt\relax
    \else
      \corasdiagram@compartmentwidth=\corasdiagram@storedstakeholderwidth\relax
    \fi
    \corasdiagram@compartmentwidth=\dimexpr
      \corasdiagram@compartmentwidth+\corasscope@stakeholderxsep+\corasscope@stakeholderxsep\relax
    \ifx\corasdiagram@storedstakeholderheight\@empty
      \corasdiagram@compartmentheight=0pt\relax
    \else
      \corasdiagram@compartmentheight=\corasdiagram@storedstakeholderheight\relax
    \fi
    \corasdiagram@compartmentheight=\dimexpr
      \corasdiagram@compartmentheight+\corasscope@stakeholderysep+\corasscope@stakeholderysep\relax
    \corasdiagram@compartmentside=\corasdiagram@compartmentwidth\relax
    \ifdim\corasdiagram@compartmentheight>\corasdiagram@compartmentside
      \corasdiagram@compartmentside=\corasdiagram@compartmentheight
    \fi
    \corasdiagram@halfcompartmentside=\dimexpr\corasdiagram@compartmentside/2\relax
  \fi
}

\NewDocumentCommand{\corasscope}{O{}}{%
  \pgfkeys{/coras/scope/.cd,%
    name=,%
    title=,%
    label=,%
    kind=system,%
    scope=,%
    fit=,%
    padding=,%
    stakeholder=,%
    stakeholder corner=left,%
    stakeholder xsep=,%
    stakeholder ysep=,%
    stakeholder tikz=,%
    tikz=,%
    title tikz=,%
    #1%
  }%
  \corasdiagram@ensurename\corasscope@name
  \ifx\corasscope@padding\@empty
    \def\corasdiagram@assetscopekind{asset-scope}%
    \ifx\corasscope@kind\corasdiagram@assetscopekind
      \def\corasscope@padding{1.0mm}%
    \else
      \def\corasscope@padding{5mm}%
    \fi
  \fi
  \corasdiagram@prepareassetscope
  \ifx\corasscope@title\@empty
    \edef\corasscope@title{\corasscope@label}%
  \fi
  \ifx\corasscope@fit\@empty
    \ifx\corasscope@scope\@empty
    \else
      \edef\corasdiagram@currscopekey{\corasdiagram@scopekey{\corasscope@scope}}%
      \corasdiagram@getscopefit{\corasscope@fit}{\corasdiagram@currscopekey}%
    \fi
  \fi
  \corasdiagram@validatecurrentrole{scope}{scope}%
  \ifx\corasscope@fit\@empty
    \PackageError{corasdiagram}{Missing `fit` or `scope` key for \string\corasscope}{%
      Provide `fit={(a) (b)}` or `scope=<group>` after assigning nodes to that scope.%
    }%
  \else
    \corasdiagram@normalize\corasscope@tikz
    \corasdiagram@normalize\corasscope@titletikz
    \def\corasdiagram@assetscopekind{asset-scope}%
    \begin{pgfonlayer}{corasbackground}%
      \ifx\corasscope@kind\corasdiagram@assetscopekind
        \node[draw=none,fit=\corasscope@fit,inner sep=0pt,outer sep=0pt]
          (\corasscope@name-fit) {};
        \def\corasdiagram@cornerright{right}%
        \ifx\corasscope@stakeholdercorner\corasdiagram@cornerright
          \coordinate (\corasscope@name-cell-ne)
            at ([xshift=\the\corasdiagram@halfcompartmentside,yshift=\the\corasdiagram@halfcompartmentside]\corasscope@stakeholder.center);
          \pgfextractx{\corasdiagram@tmpdimen}{%
            \pgfpointdiff{\pgfpointanchor{\corasscope@name-fit}{west}}{\pgfpointanchor{\corasscope@name-cell-ne}{center}}%
          }%
          \corasdiagram@scopewidth=\corasdiagram@tmpdimen\relax
          \ifdim\corasdiagram@scopewidth<0pt
            \corasdiagram@scopewidth=-\corasdiagram@scopewidth
          \fi
          \corasdiagram@scopewidth=\dimexpr\corasdiagram@scopewidth+\corasscope@padding\relax
          \pgfextracty{\corasdiagram@tmpdimen}{%
            \pgfpointdiff{\pgfpointanchor{\corasscope@name-fit}{south}}{\pgfpointanchor{\corasscope@name-cell-ne}{center}}%
          }%
          \corasdiagram@scopeheight=\corasdiagram@tmpdimen\relax
          \ifdim\corasdiagram@scopeheight<0pt
            \corasdiagram@scopeheight=-\corasdiagram@scopeheight
          \fi
          \corasdiagram@scopeheight=\dimexpr\corasdiagram@scopeheight+\corasscope@padding\relax
          \corasdiagram@finalscopewidth=\corasdiagram@scopewidth\relax
          \ifdim\corasdiagram@finalscopewidth<\dimexpr2\corasdiagram@compartmentside\relax
            \corasdiagram@finalscopewidth=\dimexpr2\corasdiagram@compartmentside\relax
          \fi
          \corasdiagram@finalscopeheight=\corasdiagram@scopeheight\relax
          \ifdim\corasdiagram@finalscopeheight<\dimexpr2\corasdiagram@compartmentside\relax
            \corasdiagram@finalscopeheight=\dimexpr2\corasdiagram@compartmentside\relax
          \fi
          \coordinate (\corasscope@name-nw)
            at ([xshift=-\the\corasdiagram@finalscopewidth]\corasscope@name-cell-ne);
          \coordinate (\corasscope@name-se)
            at ([yshift=-\the\corasdiagram@finalscopeheight]\corasscope@name-cell-ne);
        \else
          \coordinate (\corasscope@name-cell-nw)
            at ([xshift=-\the\corasdiagram@halfcompartmentside,yshift=\the\corasdiagram@halfcompartmentside]\corasscope@stakeholder.center);
          \pgfextractx{\corasdiagram@tmpdimen}{%
            \pgfpointdiff{\pgfpointanchor{\corasscope@name-cell-nw}{center}}{\pgfpointanchor{\corasscope@name-fit}{east}}%
          }%
          \corasdiagram@scopewidth=\corasdiagram@tmpdimen\relax
          \ifdim\corasdiagram@scopewidth<0pt
            \corasdiagram@scopewidth=-\corasdiagram@scopewidth
          \fi
          \corasdiagram@scopewidth=\dimexpr\corasdiagram@scopewidth+\corasscope@padding\relax
          \pgfextracty{\corasdiagram@tmpdimen}{%
            \pgfpointdiff{\pgfpointanchor{\corasscope@name-fit}{south}}{\pgfpointanchor{\corasscope@name-cell-nw}{center}}%
          }%
          \corasdiagram@scopeheight=\corasdiagram@tmpdimen\relax
          \ifdim\corasdiagram@scopeheight<0pt
            \corasdiagram@scopeheight=-\corasdiagram@scopeheight
          \fi
          \corasdiagram@scopeheight=\dimexpr\corasdiagram@scopeheight+\corasscope@padding\relax
          \corasdiagram@finalscopewidth=\corasdiagram@scopewidth\relax
          \ifdim\corasdiagram@finalscopewidth<\dimexpr2\corasdiagram@compartmentside\relax
            \corasdiagram@finalscopewidth=\dimexpr2\corasdiagram@compartmentside\relax
          \fi
          \corasdiagram@finalscopeheight=\corasdiagram@scopeheight\relax
          \ifdim\corasdiagram@finalscopeheight<\dimexpr2\corasdiagram@compartmentside\relax
            \corasdiagram@finalscopeheight=\dimexpr2\corasdiagram@compartmentside\relax
          \fi
          \coordinate (\corasscope@name-nw) at (\corasscope@name-cell-nw);
          \coordinate (\corasscope@name-se)
            at ([xshift=\the\corasdiagram@finalscopewidth,yshift=-\the\corasdiagram@finalscopeheight]\corasscope@name-cell-nw);
        \fi
        \expandafter\node\expandafter[
          coras/scope \corasscope@kind,
          fit=(\corasscope@name-nw) (\corasscope@name-se),
          inner sep=0pt,
          outer sep=0pt,
          \corasscope@tikz
        ] (\corasscope@name) {};
      \else
        \edef\corasdiagram@scopeoptions{coras/scope \corasscope@kind,fit=\corasscope@fit,inner sep=\corasscope@padding,\corasscope@tikz}%
        \expandafter\node\expandafter[\corasdiagram@scopeoptions] (\corasscope@name) {};
      \fi
    \end{pgfonlayer}%
    \corasdiagram@setnodeprop{role}{\corasscope@name}{scope}%
    \corasdiagram@setnodeprop{type}{\corasscope@name}{scope}%
    \ifx\corasscope@title\@empty
    \else
      \edef\corasdiagram@scopetitleoptions{coras/scope title,\corasscope@titletikz}%
      \expandafter\node\expandafter[\corasdiagram@scopetitleoptions]
        (\corasscope@name-title)
        at ([xshift=2mm,yshift=1.5mm]\corasscope@name.north west)
        {\corasscope@title};
    \fi
    \corasdiagram@drawstakeholdercompartment
  \fi
}

\NewDocumentCommand{\corascontainer}{O{}}{%
  \corasscope[#1]%
}

\pgfkeys{
  /coras/riskref/.is family,
  /coras/riskref,
  name/.store in=\corasriskref@name,
  label/.store in=\corasriskref@label,
  from/.store in=\corasriskref@from,
  to/.store in=\corasriskref@to,
  pos/.store in=\corasriskref@pos,
  at/.store in=\corasriskref@at,
  perspective/.store in=\corasriskref@perspective,
  tikz/.store in=\corasriskref@tikz,
  icon width/.store in=\corasriskref@iconwidth,
}

\NewDocumentCommand{\corasriskref}{O{}}{%
  \pgfkeys{/coras/riskref/.cd,%
    name=,%
    label=,%
    from=,%
    to=,%
    pos=.5,%
    at=,%
    perspective=before,%
    tikz=,%
    icon width=5mm,%
    #1%
  }%
  \ifx\corasdiagram@currentfamily\@empty
  \else
    \corasdiagram@ifincsv{\corasdiagram@currentfamily}{treatment,treatmentoverview}{}{%
      \PackageError{corasdiagram}{\string\corasriskref\space is only allowed in treatment-oriented diagrams}{%
        Use it in `corastreatmentdiagram` or `corastreatmentoverviewdiagram`.%
      }%
    }%
  \fi
  \corasdiagram@ensurename\corasriskref@name
  \corasdiagram@normalize\corasriskref@tikz
  \corasdiagram@resolveiconstem{risk}{\corasriskref@perspective}{\corasdiagram@resolvediconstem}%
  \edef\corasdiagram@riskrefoptions{coras/risk ref box,\corasriskref@tikz}%
  \ifx\corasriskref@at\@empty
    \ifx\corasriskref@from\@empty
      \PackageError{corasdiagram}{Missing placement for \string\corasriskref}{%
        Provide either `at=<coordinate>` or `from=<node>,to=<node>`.%
      }%
    \else\ifx\corasriskref@to\@empty
      \PackageError{corasdiagram}{Missing `to` key for \string\corasriskref}{%
        Provide either `at=<coordinate>` or `from=<node>,to=<node>`.%
      }%
    \else
      \corasdiagram@resolveendpoint{\corasriskref@from}%
      \edef\corasriskref@from{\corasdiagram@resolvedendpoint}%
      \corasdiagram@resolveendpoint{\corasriskref@to}%
      \edef\corasriskref@to{\corasdiagram@resolvedendpoint}%
      \expandafter\node\expandafter[\corasdiagram@riskrefoptions] (\corasriskref@name-body)
        at ($(\corasriskref@from)!\corasriskref@pos!(\corasriskref@to)$)
        {\corasriskref@label};
    \fi\fi
  \else
    \expandafter\node\expandafter[\corasdiagram@riskrefoptions] (\corasriskref@name-body)
      at \corasriskref@at
      {\corasriskref@label};
  \fi
  \node[coras/base node,anchor=east] (\corasriskref@name-icon)
    at ([xshift=-0.7mm]\corasriskref@name-body.west)
    {\corasdiagram@includeicon{\corasriskref@iconwidth}{\corasdiagram@resolvediconstem}};
  \corasdiagram@fitpublicnode{\corasriskref@name}{(\corasriskref@name-body) (\corasriskref@name-icon)}%
}

\NewDocumentCommand{\corasasset}{O{}g}{%
  \IfNoValueTF{#2}{%
    \corasnode[type=asset,#1]%
  }{%
    \corasnode[type=asset,title={#2},#1]%
  }%
}

\NewDocumentCommand{\corasindirectasset}{O{}g}{%
  \IfNoValueTF{#2}{%
    \corasnode[type=indirectasset,#1]%
  }{%
    \corasnode[type=indirectasset,title={#2},#1]%
  }%
}

\NewDocumentCommand{\corasstakeholder}{O{}g}{%
  \IfNoValueTF{#2}{%
    \corasnode[type=stakeholder,#1]%
  }{%
    \corasnode[type=stakeholder,title={#2},#1]%
  }%
}

\NewDocumentCommand{\corasthreataccidental}{O{}g}{%
  \IfNoValueTF{#2}{%
    \corasnode[type=threataccidental,#1]%
  }{%
    \corasnode[type=threataccidental,title={#2},#1]%
  }%
}

\NewDocumentCommand{\corasthreatdeliberate}{O{}g}{%
  \IfNoValueTF{#2}{%
    \corasnode[type=threatdeliberate,#1]%
  }{%
    \corasnode[type=threatdeliberate,title={#2},#1]%
  }%
}

\NewDocumentCommand{\corasthreatnonhuman}{O{}g}{%
  \IfNoValueTF{#2}{%
    \corasnode[type=threatnonhuman,#1]%
  }{%
    \corasnode[type=threatnonhuman,title={#2},#1]%
  }%
}

\NewDocumentCommand{\corasthreatsource}{O{}g}{%
  \IfNoValueTF{#2}{%
    \corasnode[type=threataccidental,#1]%
  }{%
    \corasnode[type=threataccidental,title={#2},#1]%
  }%
}

\NewDocumentCommand{\corasvulnerability}{O{}g}{%
  \IfNoValueTF{#2}{%
    \corasnode[type=vulnerability,#1]%
  }{%
    \corasnode[type=vulnerability,title={#2},#1]%
  }%
}

\NewDocumentCommand{\corasscenario}{O{}g}{%
  \IfNoValueTF{#2}{%
    \corasnode[type=scenario,#1]%
  }{%
    \corasnode[type=scenario,title={#2},#1]%
  }%
}

\NewDocumentCommand{\corasincident}{O{}g}{%
  \IfNoValueTF{#2}{%
    \corasnode[type=incident,#1]%
  }{%
    \corasnode[type=incident,title={#2},#1]%
  }%
}

\NewDocumentCommand{\corasunwantedincident}{O{}g}{%
  \IfNoValueTF{#2}{%
    \corasnode[type=incident,#1]%
  }{%
    \corasnode[type=incident,title={#2},#1]%
  }%
}

\NewDocumentCommand{\corasrisk}{O{}gg}{%
  \IfNoValueTF{#2}{%
    \IfNoValueTF{#3}{%
      \corasnode[type=risk,#1]%
    }{%
      \corasnode[type=risk,level={#3},#1]%
    }%
  }{%
    \IfNoValueTF{#3}{%
      \corasnode[type=risk,title={#2},#1]%
    }{%
      \corasnode[type=risk,title={#2},level={#3},#1]%
    }%
  }%
}

\NewDocumentCommand{\corastreatment}{O{}g}{%
  \IfNoValueTF{#2}{%
    \corasnode[type=treatment,#1]%
  }{%
    \corasnode[type=treatment,title={#2},#1]%
  }%
}

\NewDocumentCommand{\corasjunction}{O{}}{%
  \corasnode[type=junction,#1]%
}

\NewDocumentCommand{\corascauses}{O{}}{%
  \corasedge[semantic=causal,type=causal,#1]%
}

\NewDocumentCommand{\corasrelates}{O{}}{%
  \corasedge[semantic=relation,type=relation,#1]%
}

\NewDocumentCommand{\corasconcerns}{O{}}{%
  \corasedge[semantic=concern,type=concern,#1]%
}

\NewDocumentCommand{\corasassociates}{O{}}{%
  \corasedge[semantic=association,type=association,#1]%
}

\NewDocumentCommand{\corastreats}{O{}}{%
  \corasedge[semantic=treatment,type=treatment,#1]%
}

\pgfkeys{
  /coras/high-level-table/.is family,
  /coras/high-level-table,
  caption/.store in=\corashlatable@caption,
  label/.store in=\corashlatable@label,
  cause heading/.store in=\corashlatable@causeheading,
  event heading/.store in=\corashlatable@eventheading,
  possibility heading/.store in=\corashlatable@possibilityheading,
  cause width/.store in=\corashlatable@causewidth,
  event width/.store in=\corashlatable@eventwidth,
  possibility width/.store in=\corashlatable@possibilitywidth,
  column sep/.store in=\corashlatable@columnsep,
  row sep/.store in=\corashlatable@rowsep,
  icon scale/.store in=\corashlatable@iconscale,
  cause icons/.store in=\corashlatable@causeicons,
  event icons/.store in=\corashlatable@eventicons,
  possibility icons/.store in=\corashlatable@possibilityicons,
}

\newcommand{\corasdiagram@preparehighleveltabledefaults}{%
  \def\corashlatable@caption{}%
  \def\corashlatable@label{}%
  \def\corashlatable@causeheading{Who/what causes it?}%
  \def\corashlatable@eventheading{How? What is the scenario or incident? What is harmed?}%
  \def\corashlatable@possibilityheading{What makes it possible?}%
  \def\corashlatable@causewidth{\dimexpr6\textwidth/25\relax}%
  \def\corashlatable@eventwidth{\dimexpr2\textwidth/5\relax}%
  \def\corashlatable@possibilitywidth{\dimexpr3\textwidth/10\relax}%
  \def\corashlatable@columnsep{10pt}%
  \def\corashlatable@rowsep{0.8ex}%
  \def\corashlatable@iconscale{1}%
  \def\corashlatable@causeicons{\corasdiagram@highlevelcauseicons}%
  \def\corashlatable@eventicons{\corasdiagram@highleveleventicons}%
  \def\corashlatable@possibilityicons{\corasdiagram@highlevelpossibilityicons}%
}

\newcommand{\corasdiagram@highleveltableheader}{%
  {\centering\corashlatable@causeicons\par} &
  {\centering\corashlatable@eventicons\par} &
  {\centering\corashlatable@possibilityicons\par}\tabularnewline[0.8ex]%
  \corashlatable@causeheading &
  \corashlatable@eventheading &
  \corashlatable@possibilityheading\tabularnewline[0.9ex]%
  \hline
}

\newcommand{\corasdiagram@beginhighleveltable}[1]{%
  \par\begingroup
  \corasdiagram@preparehighleveltabledefaults
  \pgfkeys{/coras/high-level-table/.cd,#1}%
  \setlength{\LTleft}{0pt}%
  \setlength{\LTright}{0pt}%
  \setlength{\LTpre}{0pt}%
  \setlength{\LTpost}{0pt}%
  \setlength{\tabcolsep}{0pt}%
  \setlength{\arrayrulewidth}{0.5pt}%
  \renewcommand{\arraystretch}{1.08}%
  \begin{longtable}{@{}>{\raggedright\arraybackslash}p{\corashlatable@causewidth}@{\hspace{\corashlatable@columnsep}}>{\raggedright\arraybackslash}p{\corashlatable@eventwidth}@{\hspace{\corashlatable@columnsep}}>{\raggedright\arraybackslash}p{\corashlatable@possibilitywidth}@{}}%
    \ifx\corashlatable@caption\@empty
    \else
      \caption{\corashlatable@caption}%
      \ifx\corashlatable@label\@empty
      \else
        \label{\corashlatable@label}%
      \fi
      \tabularnewline
    \fi
    \hline
    \corasdiagram@highleveltableheader
    \endfirsthead
    \multicolumn{3}{@{}l@{}}{\footnotesize\itshape Continued from previous page}\tabularnewline[0.4ex]%
    \hline
    \corasdiagram@highleveltableheader
    \endhead
    \hline
    \multicolumn{3}{@{}r@{}}{\footnotesize\itshape Continued on next page}\tabularnewline
    \endfoot
    \hline
    \endlastfoot
}

\newcommand{\corasdiagram@endhighleveltable}{%
  \end{longtable}%
  \endgroup
}

\NewDocumentCommand{\corashighlevelanalysisrow}{m m m}{%
  #1 & #2 & #3\tabularnewline[\corashlatable@rowsep]%
}

\NewDocumentCommand{\corashighlevelriskrow}{m m m}{%
  \corashighlevelanalysisrow{#1}{#2}{#3}%
}

\NewDocumentEnvironment{corashighlevelanalysistable}{O{}}{%
  \corasdiagram@beginhighleveltable{#1}%
}{%
  \corasdiagram@endhighleveltable
}

\NewDocumentEnvironment{corashighlevelrisktable}{O{}}{%
  \corasdiagram@beginhighleveltable{#1}%
}{%
  \corasdiagram@endhighleveltable
}

\NewDocumentEnvironment{corasassetdiagram}{O{}}{%
  \corasdiagram@begindiagram{asset}%
  \begin{tikzpicture}[corasdiagram,layout=auto,coras/asset diagram,#1]%
}{%
  \end{tikzpicture}%
}

\NewDocumentEnvironment{corasthreatdiagram}{O{}}{%
  \corasdiagram@begindiagram{threat}%
  \begin{tikzpicture}[corasdiagram,layout=auto,coras/threat diagram,#1]%
}{%
  \end{tikzpicture}%
}

\NewDocumentEnvironment{corasriskdiagram}{O{}}{%
  \corasdiagram@begindiagram{risk}%
  \begin{tikzpicture}[corasdiagram,layout=auto,coras/risk diagram,#1]%
}{%
  \end{tikzpicture}%
}

\NewDocumentEnvironment{corastreatmentdiagram}{O{}}{%
  \corasdiagram@begindiagram{treatment}%
  \begin{tikzpicture}[corasdiagram,layout=auto,coras/treatment diagram,#1]%
}{%
  \end{tikzpicture}%
}

\NewDocumentEnvironment{corastreatmentoverviewdiagram}{O{}}{%
  \corasdiagram@begindiagram{treatmentoverview}%
  \begin{tikzpicture}[corasdiagram,layout=auto,coras/treatment overview diagram,#1]%
}{%
  \end{tikzpicture}%
}

\makeatother
