% Input: normalized model records and global semantic style policy.
% Output: styles, metrics, geometry services, diagnostics, and versioned events.
% Owned state: semantic themes, measurements, and the event writer.
% Invariants: drawing never parses picture syntax or mutates validated topology.
% Next stage: dialect front ends translate their syntax into shared services.
% SPDX-License-Identifier: Apache-2.0
% Copyright the TNLean project; see LICENSE for the full terms.
%
% Metric doctrine: ONE base pitch; every repeated distance is a named ratio
% of it.  Profiles (compact, inline) are a scale factor applied at the base,
% so no literal can bypass them.  Each ratio's motivation is printed in the
% manual's geometry appendix; the source states it once here.
%
% Label doctrine: labels never overlap ink by construction.  Every label
% site (in-glyph, leg tip, bond midpoint, free quadrant of a bead) is a
% reserved band derived from the metric system; automatic placement picks a
% free quadrant (a bead's label takes the first face without ink in the
% order s, n, e, w, and south when every face carries ink -- any wire
% endpoint or policy leg standing on a face reserves it, a bead on a wire
% reserves the two faces its carrier runs through, and an even span reserves
% the stations that land in the lanes either side of its dot), and every label
% accepts `label pos` / `label shift` for manual override.
%
% Glyph doctrine: an unadorned tensor (\tn{A}) renders as the theme's
% default skin -- a filled bead with its label placed OUTSIDE in a free
% quadrant (the CPSV school); an inscribed-label glyph is an explicit
% skin (box, pill, mpo, tri).  The kernel's skin= key owns the choice per
% atom, and the event stream records the RESOLVED skin.

% Triangle skins (tri=l / tri=r) borrow the isosceles-triangle node shape;
% the library itself loads with the rest of tikz-tensor-networks.sty's tikz libraries.

% ---------- semantic hues (a theme may rebind colours, nothing else) ----------
\colorlet{tenkzInk}{black!92}
\colorlet{tenkzPaper}{white}
\colorlet{tenkzPassive}{black!55}
\colorlet{tenkzAction}{red!65!black}
\colorlet{tenkzMarked}{blue!65!black}
\colorlet{tenkzExtra}{violet!65!black}
\colorlet{tenkzOperator}{red!80!black}% wire hue of an operator (MPO) layer

% ---------- metric system ----------
\newdimen\tenkz@pitch          \tenkz@pitch=11mm
\newdimen\tenkz@basepitch      \tenkz@basepitch=11mm
% ratios (of pitch unless stated)
\def\tenkz@r@layersep{0.80}    % layers read as layers, not as two chains
\def\tenkz@r@physleg{0.38}     % a labelled leg clears the bond-label band
\def\tenkz@r@stub{0.45}        % open index: longer than a leg, shorter than a bond;
                               % also the reach of an inter-layer cup: the bend
                               % protrudes exactly as far as the stubs it replaces,
                               % so open and cup-closed ends share one silhouette
\def\tenkz@r@daylight{0.15}    % PURE daylight: the one gap between a row's
                               % outermost ink (its silhouette, see the grid's
                               % resolver) and any closure or annotation ink
                               % placed beyond it -- racetrack returns, span
                               % braces.  It separates, never clears: WHAT must
                               % be cleared is the silhouette's business, and
                               % is measured, not budgeted.  0.15 pitch is
                               % ~1.7mm at the default 11mm pitch (~8.5x the
                               % 0.55pt wire width, so wire-weight ink never
                               % fuses with the return at print size) and
                               % still ~1mm (~5.3 wire widths) inline
\def\tenkz@r@labelclear{0.12}  % ONE clearance for every label band
\def\tenkz@r@dotlabelband{0.30}% ONE label band for every external label:
                               % clearance + one line of script-size text.
                               % Bead labels and leg-tip labels are the same
                               % object (a name hung off ink), so both kinds
                               % share this metric DELIBERATELY -- the
                               % silhouette resolver budgets each with it
\def\tenkz@r@inlinephysleg{0.26}   % inline: legs shrink faster than the pitch
\def\tenkz@r@inlinelabelclear{0.05}% inline: labels hug the ink to spare line height
\def\tenkz@r@dotdia{0.16}      % bead diameter
\def\tenkz@r@tallover{0.34}    % vertical overshoot of a wires=k glyph beyond its
                               % outer wire rows: the gate box must visibly COVER
                               % the wires it terminates (quantikz \gate[k])
\def\tenkz@r@phtracereach{0.24}% physical-trace clearance: the flat per-site
                               % loop clears the glyph above, below and east; it
                               % must clear the glyph yet stay inside the bond
                               % span to the next site
\def\tenkz@r@pairtracereach{0.40}% pair-trace reach (traced columns): how far east
                               % of the leg axis the per-column Tr_s racetrack
                               % swings; < 1/2 so the east straight clears the
                               % neighbouring column's glyph and label bands at
                               % the default pitch, and wide enough that the
                               % stadium caps (radius = reach/2) read as smooth
                               % turnarounds rather than kinks
\def\tenkz@r@corner{0.14}      % rounded-corner radius of traces and hulls
\def\tenkz@r@glyphbox{0.22}    % the flat-skin height floor: a pill and an
                               % on-wire capsule stay flatter than the square
                               % a box takes; also the span decorations'
                               % lateral overhang beyond their first and last
                               % column
\def\tenkz@r@glyphref{0.50}    % the size-class reference EXTENT: the one
                               % extent every inscribed-label glyph reaches
                               % before its label starts to move it, so a box
                               % beside a pill beside an on-wire capsule read
                               % as one family and no author states a width.
                               % A box takes it as its side and a labelled
                               % circle as its diameter, so an unlabelled
                               % site is square rather than a flat mark.
                               % Half the pitch is the pill's own long-
                               % standing width, shared out rather than
                               % reinvented: glyph and bond then alternate in
                               % equal measure, and the contracted index
                               % between two glyphs keeps as much ink as the
                               % glyphs it joins.  A standalone label wider
                               % than the reference moves to the station
                               % rule; only an equation's shared class
                               % measure may grow the glyph
\def\tenkz@r@wireglyph{0.30}   % on-wire glyph minimum: on-wire matrix size,
                               % canonical-tensor height -- taller than the
                               % box floor because these glyphs sit ON a
                               % wire and must read over it
\def\tenkz@r@wireglyphcap{0.15}% = wireglyph/2: the corner radius that closes
                               % the minimal on-wire rectangle into a stadium.
                               % A named literal, not 0.5\tenkz@dim{...}: pgf's
                               % dimension parser detaches a leading factor
                               % from a \dimexpr and misreads the radius
                               % (lens-shaped, self-intersecting capsules)
\def\tenkz@r@fusionwidth{0.075}% fusion-bar stroke: a wedge, not a wire, so
                               % it scales with the pitch like a glyph
\def\tenkz@r@fuseover{0.10}    % the fusion bar's overhang beyond its outer
                               % wire rows: the wedge must visibly CLASP the
                               % wires it fuses (as tallover makes a gate
                               % cover its wires); also the bar's silhouette
                               % contribution, so drawing and clearance read
                               % one number
\def\tenkz@r@crossgap{0.10}    % the calibrated crossing break: the paper a
                               % strand shows through the strand that passes
                               % over it, whether the break is cut into the
                               % under path or laid by the over path's halo
% absolute floors and ink hierarchy: the metric registry owns the values
% (tenkz-metric.code.tex); these spellings resolve through it lazily so
% the styles below keep reading \tenkz@wirewidth et al. unchanged.

\def\tenkz@dim#1{\dimexpr#1\tenkz@pitch\relax}

% Label mathematics is script-size by default: glyphs are compact marks, not
% text boxes, and the surrounding equation stays visually dominant.
\let\tenkz@labelsize\scriptstyle

% Math-style sensing needs one fact TeX will not answer for: whether the
% mathematics a picture stands in is a line of running mathematics or a
% display.  No test distinguishes them after the fact -- a fenced or braced
% sub-formula of a display is inner mathematics exactly as an inline line is
% -- but the two are entered by different primitives, and each carries a
% token list TeX inserts on entry.  A display sets the display flag, which is
% local to the display's own math list and so survives into every sub-formula,
% fence and alignment cell inside it; a math shift raises the inline flag only
% where no display has claimed the context.  Reading these two answers the
% question the density profile turns on, and answers it for exactly the case
% it is about: a picture in a line of running mathematics.
\newif\iftenkz@mathinline
\newif\iftenkz@mathdisplay
\everymath\expandafter{\the\everymath
  \iftenkz@mathdisplay\else\tenkz@mathinlinetrue\fi}
\everydisplay\expandafter{\the\everydisplay \tenkz@mathdisplaytrue}

% ---------- style table (complete Phase-0 subset of the spec table) ----------
\tikzset{
  tenkz every picture/.style={line cap=round, line join=round},
  % glyph skins
  tensor/.style={tenkz audited glyph={circle}{0pt},
      draw=tenkzInk, fill=tenkzInk,
      circle, inner sep=0pt,
      minimum size=\tenkz@dim{\tenkz@r@dotdia}, line width=\tenkz@wirewidth},
  % The three labelled skins share ONE reference extent (\tenkz@r@glyphref):
  % a box beside a pill, and an operator beside its inverse, read as the
  % same kind of object because the class fixes the extent, not the label.
  % The box takes the reference on BOTH axes, so a site with one index on
  % each face is the square its sources draw whether or not it carries a
  % label; a pill and an on-wire capsule are deliberately flatter and keep
  % their own height floor.
  box tensor/.style={tenkz audited glyph={rect}{0pt},
      draw=tenkzInk, fill=tenkzPaper,
      rectangle,
      inner sep=\tenkz@boxinset,
      minimum size=\tenkz@dim{\tenkz@r@glyphref},
      line width=\tenkz@wirewidth, text=tenkzInk},
  mpo tensor/.style={box tensor},
  % A glyphless junction draws no outline at all; its silhouette exists only
  % to give declared ports a boundary to stand on.  It keeps the flat floor
  % rather than the class reference, because the reference says how a glyph
  % reads and there is no glyph here -- and because a port standing on an
  % invisible boundary moves when that boundary grows.
  junction silhouette/.style={box tensor,
      minimum size=\tenkz@dim{\tenkz@r@glyphbox},
      minimum width=\tenkz@dim{\tenkz@r@glyphref}},
  pill tensor/.style={tenkz audited glyph={roundrect}{\tenkz@pillcap},
      draw=tenkzInk, fill=tenkzPaper,
      rectangle,
      rounded corners=\tenkz@pillcap,
      inner xsep=\tenkz@pillxinset, inner ysep=\tenkz@pillyinset,
      minimum height=\tenkz@dim{\tenkz@r@glyphbox},
      minimum width=\tenkz@dim{\tenkz@r@glyphref},
      line width=\tenkz@wirewidth, text=tenkzInk},
  % capsule, not circle: the height is pinned by `minimum size`, and a wide
  % label (an inverse, a product) grows the glyph only sideways, so every
  % on-wire matrix on a chain reads at the same height.  The corner radius
  % \tenkz@r@wireglyphcap is HALF the minimum size -- exactly the radius
  % that closes the minimal rectangle into a stadium -- which is why it is
  % not \tenkz@r@corner (the trace/hull radius, a different object).
  on-wire matrix/.style={
      tenkz audited glyph={roundrect}{\tenkz@dim{\tenkz@r@wireglyphcap}},
      draw=tenkzAction,
      fill=tenkzPaper, rectangle,
      rounded corners=\tenkz@dim{\tenkz@r@wireglyphcap},
      inner xsep=\tenkz@wireglyphxinset,
      inner ysep=\tenkz@wireglyphyinset,
      minimum size=\tenkz@dim{\tenkz@r@wireglyph},
      minimum width=\tenkz@dim{\tenkz@r@glyphref},
      line width=\tenkz@wirewidth, text=tenkzInk},
  % the style's public 0.6 name; \tnX is the documented alias
  ring tensor/.style={on-wire matrix},
  % canonical-form isometries (kernel skins tri and triwest, legacy tri=l and
  % tri=r): an isoceles triangle whose FLAT side receives the isometry's
  % domain and whose APEX emits its codomain -- the A_L / A_R glyphs of
  % canonical-form MPS (sum_s A_L^s{}^dagger A_L^s = 1).
  % Wires meet the flat side's midpoint and the apex, both on the wire axis.
  % triangleinset is tight: a triangle must CIRCUMSCRIBE its text box,
  % so every point of padding costs ~triple in glyph height, and two
  % triangle rows would otherwise collide across the default layer gap
  % apex angle 55: the flat-side height grows like 2 tan(apex/2) * text
  % width, so a narrower apex trades a slightly longer glyph for the
  % vertical clearance the sandwich genre needs across the layer gap
  canonical tensor/.style={tenkz audited glyph={triangle}{0pt},
      draw=tenkzInk,
      fill=tenkzPaper,
      isosceles triangle, isosceles triangle apex angle=55,
      isosceles triangle stretches, inner sep=\tenkz@triangleinset,
      minimum width=\tenkz@dim{\tenkz@r@canonicalwidth},
      minimum height=\tenkz@dim{\tenkz@r@wireglyph},
      line width=\tenkz@wirewidth, text=tenkzInk},
  left canonical tensor/.style={canonical tensor, shape border rotate=0},
  right canonical tensor/.style={canonical tensor, shape border rotate=180},
  fusion map/.style={draw=tenkzInk, fill=tenkzInk, line cap=round,
      line width=\tenkz@dim{\tenkz@r@fusionwidth}},
  tree junction/.style={tenkz audited glyph={circle}{0pt}, draw=tenkzInk,
      fill=tenkzInk,
      circle, inner sep=0pt,
      minimum size=\tenkz@junctionfloor},
  % A ribbon tree is a filled surface with two boundary curves, not a
  % doubled wire.  The cd renderer draws the strip fills and their two
  % boundaries separately, then joins three strips through a nonsingular
  % vertex patch.  This style supplies only the semantic boundary/fill colours.
  tree ribbon/.style={draw=tenkzInk, line width=\tenkz@wirewidth},
  tree ribbon fill/.style={draw=tenkzPaper, fill=tenkzPaper},
  % wires
  bond/.style={draw=tenkzInk, line width=\tenkz@wirewidth},
  fused bond/.style={bond, double=tenkzPaper,
      double distance=\tenkz@fusedwiregap},
  physical leg/.style={bond},
  operator bond/.style={bond, draw=tenkzOperator},
  % A trace closure identifies two ends of the picture and asserts nothing
  % about the wires its return passes.  Drawn as a plain junction it would
  % assert the opposite -- in a tensor diagram a crossing without a break
  % reads as a contraction -- so the return carries the calibrated crossing
  % break as a paper halo, the same break the string tier cuts into an under
  % path.  The halo is butt-capped: a return leaves and re-enters its glyph
  % on the glyph's own border, and a round cap would eat into that outline.
  % A closure is always a single stroke -- it carries no strand weight --
  % which is what makes the halo admissible: paper laid under a multi-strand
  % stroke mottles it, and that shortcut is refused everywhere it would.
  trace/.style={bond, rounded corners=\tenkz@dim{\tenkz@r@corner},
      preaction={draw=tenkzPaper, line cap=butt,
        line width=\dimexpr\tenkz@wirewidth
          + \tenkz@dim{\tenkz@r@crossgap}\relax}},
  % ---------- semantic roles (the 0.6 hue contract) ----------
  % Resolution is pure style indirection: role words map to ONE derived
  % style per role x glyph family — bond (wires, joins), tensor (filled
  % beads), outline (inscribed-label glyphs: box, pill, mpo, tri, ring)
  % — all bound to the core hue slots, so a theme that rebinds
  % tenkzOperator etc. recolours every role-hued atom, wire and join at
  % one point.  No raw colour is ever accepted at a call site, in any
  % tier.
  marked bond/.style={bond, draw=tenkzMarked},
  extra bond/.style={bond, draw=tenkzExtra},
  passive bond/.style={bond, draw=tenkzPassive},
  operator ribbon/.style={tree ribbon, draw=tenkzOperator,
      fill=tenkzOperator!12!tenkzPaper},
  operator ribbon fill/.style={draw=tenkzOperator!12!tenkzPaper,
      fill=tenkzOperator!12!tenkzPaper},
  marked ribbon/.style={tree ribbon, draw=tenkzMarked,
      fill=tenkzMarked!12!tenkzPaper},
  marked ribbon fill/.style={draw=tenkzMarked!12!tenkzPaper,
      fill=tenkzMarked!12!tenkzPaper},
  extra ribbon/.style={tree ribbon, draw=tenkzExtra,
      fill=tenkzExtra!12!tenkzPaper},
  extra ribbon fill/.style={draw=tenkzExtra!12!tenkzPaper,
      fill=tenkzExtra!12!tenkzPaper},
  passive ribbon/.style={tree ribbon, draw=tenkzPassive,
      fill=tenkzPassive!12!tenkzPaper},
  passive ribbon fill/.style={draw=tenkzPassive!12!tenkzPaper,
      fill=tenkzPassive!12!tenkzPaper},
  operator tensor/.style={draw=tenkzOperator, fill=tenkzOperator},
  marked tensor/.style={draw=tenkzMarked, fill=tenkzMarked},
  extra tensor/.style={draw=tenkzExtra, fill=tenkzExtra},
  passive tensor/.style={draw=tenkzPassive, fill=tenkzPassive},
  operator tree junction/.style={tree junction, operator tensor},
  marked tree junction/.style={tree junction, marked tensor},
  extra tree junction/.style={tree junction, extra tensor},
  passive tree junction/.style={tree junction, passive tensor},
  operator outline/.style={draw=tenkzOperator, text=tenkzOperator},
  marked outline/.style={draw=tenkzMarked, text=tenkzMarked},
  extra outline/.style={draw=tenkzExtra, text=tenkzExtra},
  passive outline/.style={draw=tenkzPassive, text=tenkzPassive},
  % Canonical atoms use the class reference on both axes.
  tenkz canonical size s/.style={
      minimum width=\dimexpr
        \tenkz@r@glyphref\tenkz@pitch * 3 / 4\relax,
      minimum height=\dimexpr
        \tenkz@r@glyphref\tenkz@pitch * 3 / 4\relax},
  tenkz canonical size m/.style={
      minimum width=\tenkz@dim{\tenkz@r@glyphref},
      minimum height=\tenkz@dim{\tenkz@r@glyphref}},
  tenkz canonical size l/.style={
      minimum width=\dimexpr
        \tenkz@r@glyphref\tenkz@pitch * 5 / 4\relax,
      minimum height=\dimexpr
        \tenkz@r@glyphref\tenkz@pitch * 5 / 4\relax},
  % A pill scales BOTH of its named floors by the class factor, so every
  % size keeps the pill's flat proportion; the canonical square styles
  % above would swallow it into a box.
  tenkz pill size s/.style={
      minimum width=\dimexpr
        \tenkz@r@glyphref\tenkz@pitch * 3 / 4\relax,
      minimum height=\dimexpr
        \tenkz@r@glyphbox\tenkz@pitch * 3 / 4\relax},
  tenkz pill size m/.style={
      minimum width=\tenkz@dim{\tenkz@r@glyphref},
      minimum height=\tenkz@dim{\tenkz@r@glyphbox}},
  tenkz pill size l/.style={
      minimum width=\dimexpr
        \tenkz@r@glyphref\tenkz@pitch * 5 / 4\relax,
      minimum height=\dimexpr
        \tenkz@r@glyphbox\tenkz@pitch * 5 / 4\relax},
  tenkz dot size s/.style={
      minimum size=\tenkz@dim{\tenkz@r@clusterdot}},
  tenkz dot size m/.style={
      minimum size=\tenkz@dim{\tenkz@r@dotdia}},
  tenkz dot size l/.style={
      minimum size=\tenkz@dim{\tenkz@r@glyphbox}},
  % directionality marks (design brief): an OUTGOING arrow is the vector space
  % V, an INCOMING one its dual V*; contraction joins out-to-in, and REVERSING
  % a barb is the dual/inverse representation -- so `reversed` variants flip
  % the barb, never the wire.  The barb rides mid-wire and inherits the wire's
  % colour; the `fused` variants size the barb to span the doubled wire.  The
  % station is an argument because a leg that leaves a glyph must count it
  % along the daylight beyond the silhouette, not along the whole leg; the
  % default is the named station a wire between two glyphs keeps.
  dir marks/.style={decoration={markings,
      mark=at position #1 with
      {\arrow{Straight Barb[length=\tenkz@barblen]}}}, postaction=decorate},
  dir marks/.default=\tenkz@r@dirmarkstation,
  dir marks reversed/.style={decoration={markings,
      mark=at position #1 with
      {\arrow{Straight Barb[length=\tenkz@barblen, reversed]}}},
      postaction=decorate},
  dir marks reversed/.default=\tenkz@r@dirmarkstation,
  % a declared wire stroke.  A dashed rail carries an index the picture draws
  % but does not contract; a dotted one carries a lattice lying under the
  % sheet.  Both keep the wire's weight and colour: only the paper changes.
  tenkz wire dashed/.style={
      dash pattern=on \tenkz@wiredash off \tenkz@wiredash},
  tenkz wire dotted/.style={
      dash pattern=on \tenkz@wirewidth off \tenkz@wiredotgap},
  fused dir marks/.style={decoration={markings,
      mark=at position \tenkz@r@dirmarkstation with
      {\arrow{Straight Barb[length=\tenkz@fusedbarblen]}}},
      postaction=decorate},
  fused dir marks reversed/.style={decoration={markings,
      mark=at position \tenkz@r@dirmarkstation with
      {\arrow{Straight Barb[length=\tenkz@fusedbarblen, reversed]}}},
      postaction=decorate},
  % annotation ink (never confusable with 0.55pt wires)
  cut/.style={draw=tenkzPassive, dashed, line width=\tenkz@annwidth},
  brace/.style={draw=tenkzInk, line width=\tenkz@annwidth,
      decoration={brace, amplitude=\tenkz@braceamp}, decorate},
  % One presentation for one meaning: these outlines delimit members of a
  % blocked/grouped object; they are not contraction wires.  K1 grid spans
  % consume this style and the measured-box renderer below.
  group region/.style={draw=tenkzPassive, fill=none, densely dashed,
      rounded corners=\tenkz@groupcorner, line width=\tenkz@annwidth},
  % the package's label skin.  Named `tn label`, NOT `label`: a bare
  % `label/.style` would clobber TikZ's built-in /tikz/label key
  % document-wide, silently swallowing `label=above:$x$` on every node of
  % every picture that merely loads tenkz.
  tn label/.style={tenkz audited label, shape=rectangle, rounded corners=0pt,
      text=tenkzInk, inner sep=\tenkz@labelinset, font=\scriptsize},
}

% ---------- event stream (v2, minimal Phase-0 writer) ----------
\newwrite\tenkz@log
\newif\iftenkz@logopen
% One writer, one emitting context.  The picture surface owns its own
% identity and hands it to the shared renderer as \tenkz@auditpictureid,
% assigned LOCALLY inside the picture's group so that closing the group
% RESTORES the enclosing picture's id -- a nested picture inside another
% picture's cell must not steal the parent's later events.  Back in running
% prose \tenkz@pictureid is the identity of no picture, which is how a bare
% \tntree logs picture=0.
\newcount\tenkz@pictureid
\newif\iftenkz@auditpicture
\tenkz@auditpicturefalse
\def\tenkz@auditpictureid{\the\tenkz@pictureid}
\AtBeginDocument{\immediate\openout\tenkz@log=\jobname.tnlog\tenkz@logopentrue}
\AtEndDocument{\iftenkz@logopen\immediate\closeout\tenkz@log\fi}
\def\tenkz@event#1{\iftenkz@logopen
  \immediate\write\tenkz@log{#1}\fi}

% Measured audit geometry.  Coordinates are written as integer scaled points,
% so the event stream is independent of locale and TeX's decimal formatting.
% Labels use visible live rectangles or sharp round-stroked rectangles.  Core
% glyph nodes retain their visible filled shape after outer-separation removal:
% circles use live cardinal
% anchors, rounded rectangles carry the final stroke-expanded corner radius,
% and triangles use live centerline corners plus an explicit half-stroke.
% Typed-map wire geometry is the endpoint-anchor rectangle, expanded by the
% stroke's vertical half-width, minus the exact opaque label support.  Both
% caps terminate under opaque nodes, so longitudinal cap ink is not visible.
\newcount\tenkz@bboxuid
\newcount\tenkz@inkuid
\newcount\tenkz@inkowner
\newcount\tenkz@glyphsnapuid
\newdimen\tenkz@glyphradius
\newdimen\tenkz@labelradius
\newdimen\tenkz@glyphradiusx
\newdimen\tenkz@glyphradiusy
\newdimen\tenkz@glyphouterxsep
\newdimen\tenkz@glyphouterysep
\newdimen\tenkz@glyphhalfstroke
\newdimen\tenkz@glyphwidth
\newdimen\tenkz@glyphheight
\newdimen\tenkz@glyphdiameter
\newdimen\tenkz@glyphxone
\newdimen\tenkz@glyphyone
\newdimen\tenkz@glyphxtwo
\newdimen\tenkz@glyphytwo
\newdimen\tenkz@glyphxthree
\newdimen\tenkz@glyphythree
\newdimen\tenkz@bboxxmin
\newdimen\tenkz@bboxxmax
\newdimen\tenkz@bboxymin
\newdimen\tenkz@bboxymax
\newdimen\tenkz@bboxxa
\newdimen\tenkz@bboxya
\newif\iftenkz@bboxcapture
\newif\iftenkz@identitylinear
\newif\iftenkz@frameglyphrotated
\newif\iftenkz@frameglyphaffine
\newif\iftenkz@labelrectangle
\newif\iftenkz@auditownermatch
\tenkz@bboxcapturetrue
\let\tenkz@labelgeometrykey\relax
\let\tenkz@auditinstallowner\relax
% Station provenance rides the label whose placement the kernel chose.  The
% claim is ARMED immediately before the one node it describes and consumed
% by that node's own audit installation: the install binds the armed claim
% to the node's snapshot token and disarms it, and the capture reads the
% claim back off the token it is capturing.  The first audited label to
% install therefore owns the claim, and every label installing after it --
% in particular a nested label created by an execute-at-end-node hook
% during the audited node's own construction -- starts unclaimed.  Every
% other label site stays unclaimed rather than mislabeled: an absent field
% is the stream's word for a placement the model has not classified.  The
% station is the chooser's face word, before compass conversion; an
% explicit placement claims no station.
\let\tenkz@labelstation\relax
\let\tenkz@labelprovenance\relax
\let\tenkz@armedlabelstation\relax
\let\tenkz@armedlabelprovenance\relax
% A label whose site is deliberately on the ink it stands in -- the elision
% glyph, whose row the wires it elides pass straight through -- says so, so a
% reader need not guess it from an unclaimed site.  It rides the same
% per-node token as the claim above.
\let\tenkz@labelrole\relax
\let\tenkz@armedlabelrole\relax
\def\tenkz@labelroleclaim#1{\def\tenkz@armedlabelrole{#1}}
\def\tenkz@labelclaim#1#2{%
  \def\tenkz@armedlabelprovenance{#1}%
  \if\relax\detokenize{#2}\relax
    \let\tenkz@armedlabelstation\relax
  \else
    \def\tenkz@armedlabelstation{#2}%
  \fi}
\def\tenkz@labelrelease{%
  \let\tenkz@labelstation\relax
  \let\tenkz@labelprovenance\relax
  \let\tenkz@armedlabelstation\relax
  \let\tenkz@armedlabelprovenance\relax
  \let\tenkz@labelrole\relax
  \let\tenkz@armedlabelrole\relax}
% Mirror the actual backend graphic state without changing any PGF arguments.
% Assignments remain local to the same TeX groups as the driver mutations, so
% inherited scopes and final node options are observed at the real path use.
\def\tenkz@empty{}
\def\tenkz@livejoin{miter}
\def\tenkz@livecap{butt}
\def\tenkz@livedash{}
\def\tenkz@livestrokeopacity{1}
\def\tenkz@livefillopacity{1}
\def\tenkz@liveblendmode{normal}
\let\tenkz@sys@miterjoin\pgfsys@miterjoin
\let\tenkz@sys@roundjoin\pgfsys@roundjoin
\let\tenkz@sys@beveljoin\pgfsys@beveljoin
\let\tenkz@sys@buttcap\pgfsys@buttcap
\let\tenkz@sys@roundcap\pgfsys@roundcap
\let\tenkz@sys@rectcap\pgfsys@rectcap
\let\tenkz@sys@setdash\pgfsys@setdash
\let\tenkz@sys@strokeopacity\pgfsys@stroke@opacity
\let\tenkz@sys@fillopacity\pgfsys@fill@opacity
\let\tenkz@sys@blendmode\pgfsys@blend@mode
\def\pgfsys@miterjoin{\def\tenkz@livejoin{miter}\tenkz@sys@miterjoin}
\def\pgfsys@roundjoin{\def\tenkz@livejoin{round}\tenkz@sys@roundjoin}
\def\pgfsys@beveljoin{\def\tenkz@livejoin{bevel}\tenkz@sys@beveljoin}
\def\pgfsys@buttcap{\def\tenkz@livecap{butt}\tenkz@sys@buttcap}
\def\pgfsys@roundcap{\def\tenkz@livecap{round}\tenkz@sys@roundcap}
\def\pgfsys@rectcap{\def\tenkz@livecap{rect}\tenkz@sys@rectcap}
\def\pgfsys@setdash#1#2{%
  \edef\tenkz@livedash{#1}%
  \tenkz@sys@setdash{#1}{#2}}
\def\pgfsys@stroke@opacity#1{%
  \edef\tenkz@livestrokeopacity{#1}%
  \tenkz@sys@strokeopacity{#1}}
\def\pgfsys@fill@opacity#1{%
  \edef\tenkz@livefillopacity{#1}%
  \tenkz@sys@fillopacity{#1}}
\def\pgfsys@blend@mode#1{%
  \edef\tenkz@liveblendmode{#1}%
  \tenkz@sys@blendmode{#1}}
% Node options can be inherited by nested pictures.  Reset the local claimant
% at the start of every node; an audited installer below then claims only that
% node, and the surrounding claimant is restored when the node group closes.
\let\tenkz@node@reset@hook\tikz@node@reset@hook
\def\tikz@node@reset@hook{%
  \tenkz@node@reset@hook
  \let\tenkz@auditinstallowner\relax
  \let\tenkz@frameglyphangle\relax}
\def\tenkz@begininkuse#1{%
  \global\advance\tenkz@inkuid by 1\relax
  \tenkz@inkowner=\tenkz@inkuid
  \tenkz@event{ink-use|picture=\tenkz@auditpictureid|class=#1|%
    id=\the\tenkz@inkowner}}
\def\tenkz@bboxlabeluse{%
  \iftenkz@bboxcapture
    \iftenkz@auditpicture
      \tenkz@inkowner=0\relax
      \tenkz@event{label-use|picture=\tenkz@auditpictureid}%
    \fi
  \fi}
\def\tenkz@writelabelbbox{%
  \global\advance\tenkz@bboxuid by 1\relax
  \tenkz@event{bbox|picture=\tenkz@auditpictureid|class=label|%
    id=\the\tenkz@bboxuid|owner=\the\tenkz@inkowner|%
    xmin=\number\tenkz@bboxxmin|xmax=\number\tenkz@bboxxmax|%
    ymin=\number\tenkz@bboxymin|ymax=\number\tenkz@bboxymax|%
    shape=\tenkz@labelshape|radius=\number\tenkz@labelradius%
    \ifx\tenkz@labelstation\relax\else|station=\tenkz@labelstation\fi%
    \ifx\tenkz@labelprovenance\relax\else|provenance=\tenkz@labelprovenance\fi%
    \ifx\tenkz@labelrole\relax\else|role=\tenkz@labelrole\fi}}
\def\tenkz@checklinear#1#2#3#4#5#6{%
  \tenkz@identitylineartrue
  \pgf@xa=#1pt\relax
  \ifdim\pgf@xa=1pt\else\tenkz@identitylinearfalse\fi
  \pgf@xa=#2pt\relax
  \ifdim\pgf@xa=0pt\else\tenkz@identitylinearfalse\fi
  \pgf@xa=#3pt\relax
  \ifdim\pgf@xa=0pt\else\tenkz@identitylinearfalse\fi
  \pgf@xa=#4pt\relax
  \ifdim\pgf@xa=1pt\else\tenkz@identitylinearfalse\fi}
\def\tenkz@requireidentitylinear#1#2{%
  \edef\tenkz@nodematrix{\csname pgf@sh@nt@#1\endcsname}%
  \expandafter\tenkz@checklinear\tenkz@nodematrix
  \iftenkz@identitylinear\else
    \PackageError{tenkz}{Audited #2 node '#1' has unsupported affine transform}%
      {Remove transform shape, or use an untransformed audited node.}%
  \fi}
\def\tenkz@requirelabelrectangle#1{%
  \tenkz@labelrectangletrue
  \edef\tenkz@livelabelshape{\csname pgf@sh@ns@#1\endcsname}%
  \def\tenkz@pgfrectangle{rectangle}%
  \ifx\tenkz@livelabelshape\tenkz@pgfrectangle\else
    \tenkz@labelrectanglefalse
    \PackageError{tenkz}{Audited label node '#1' has unsupported live shape
      '\tenkz@livelabelshape'}{Use the rectangular tn label shape.}%
  \fi}
\def\tenkz@storelabelgeometry{%
  \ifx\tenkz@labelgeometrykey\relax\else
    \pgfextractx{\tenkz@bboxxa}{\pgfpointanchor{\tikzlastnode}{center}}%
    \pgfextracty{\tenkz@bboxya}{\pgfpointanchor{\tikzlastnode}{center}}%
    \pgf@x=\tenkz@bboxxmin \advance\pgf@x by -\tenkz@bboxxa
    \expandafter\xdef\csname tenkz@labelxmin@\tenkz@labelgeometrykey
      \endcsname{\the\pgf@x}%
    \pgf@x=\tenkz@bboxxmax \advance\pgf@x by -\tenkz@bboxxa
    \expandafter\xdef\csname tenkz@labelxmax@\tenkz@labelgeometrykey
      \endcsname{\the\pgf@x}%
    \pgf@y=\tenkz@bboxymin \advance\pgf@y by -\tenkz@bboxya
    \expandafter\xdef\csname tenkz@labelymin@\tenkz@labelgeometrykey
      \endcsname{\the\pgf@y}%
    \pgf@y=\tenkz@bboxymax \advance\pgf@y by -\tenkz@bboxya
    \expandafter\xdef\csname tenkz@labelymax@\tenkz@labelgeometrykey
      \endcsname{\the\pgf@y}%
    \expandafter\xdef\csname tenkz@labelshape@\tenkz@labelgeometrykey
      \endcsname{\tenkz@labelshape}%
    \expandafter\xdef\csname tenkz@labelradius@\tenkz@labelgeometrykey
      \endcsname{\the\tenkz@labelradius}%
    \expandafter\xdef\csname tenkz@labelopaque@\tenkz@labelgeometrykey
      \endcsname{\tenkz@labelopaque}%
    \ifx\tenkz@labelstation\relax\else
      \expandafter\xdef\csname tenkz@labelstation@\tenkz@labelgeometrykey
        \endcsname{\tenkz@labelstation}%
    \fi
    \ifx\tenkz@labelprovenance\relax\else
      \expandafter\xdef\csname tenkz@labelprovenance@\tenkz@labelgeometrykey
        \endcsname{\tenkz@labelprovenance}%
    \fi
  \fi}
\def\tenkz@cleanupstoredlabelgeometry#1{%
  \global\expandafter\let\csname tenkz@labelxmin@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@labelxmax@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@labelymin@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@labelymax@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@labelshape@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@labelradius@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@labelopaque@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@labelstation@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@labelprovenance@#1\endcsname\relax}
\def\tenkz@emitstoredlabelbbox#1#2{%
  \begingroup
  \tenkz@requireidentitylinear{#1}{label}%
  \tenkz@requirelabelrectangle{#1}%
  \iftenkz@identitylinear
  \iftenkz@labelrectangle
    \pgfextractx{\tenkz@bboxxa}{\pgfpointanchor{#1}{center}}%
    \pgfextracty{\tenkz@bboxya}{\pgfpointanchor{#1}{center}}%
    \tenkz@bboxxmin=\csname tenkz@labelxmin@#2\endcsname\relax
    \tenkz@bboxxmax=\csname tenkz@labelxmax@#2\endcsname\relax
    \tenkz@bboxymin=\csname tenkz@labelymin@#2\endcsname\relax
    \tenkz@bboxymax=\csname tenkz@labelymax@#2\endcsname\relax
    \advance\tenkz@bboxxmin by \tenkz@bboxxa
    \advance\tenkz@bboxxmax by \tenkz@bboxxa
    \advance\tenkz@bboxymin by \tenkz@bboxya
    \advance\tenkz@bboxymax by \tenkz@bboxya
    \edef\tenkz@labelshape{\csname tenkz@labelshape@#2\endcsname}%
    \tenkz@labelradius=\csname tenkz@labelradius@#2\endcsname\relax
    \expandafter\let\expandafter\tenkz@labelstation
      \csname tenkz@labelstation@#2\endcsname
    \expandafter\let\expandafter\tenkz@labelprovenance
      \csname tenkz@labelprovenance@#2\endcsname
    \tenkz@writelabelbbox
  \fi
  \fi
  \endgroup}
\def\tenkz@cleanupvisiblesnapshot#1{%
  \global\expandafter\let\csname tenkz@pathxmin@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@pathxmax@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@pathymin@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@pathymax@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@outerx@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@outery@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@stroke@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@draw@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@fill@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@double@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@shade@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@fade@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@pathpicture@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@clip@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@join@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@dash@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@strokeopacity@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@fillopacity@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@textopacity@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@textwidth@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@textheight@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@textdepth@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@invalid@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@outercount@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@modecount@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@usecount@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@auditowner@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@snapshotdone@#1\endcsname\relax}
% Convert the effective outer separation to numeric lengths.  This is called
% only from the real \pgf@outer@adjust@hook invocation in \pgfmultipartnode.
\def\tenkz@snapshotoutersep#1{%
  \tenkz@incrementtokenslot{outercount}{#1}%
  \pgfmathsetlength{\pgf@x}{\pgfkeysvalueof{/pgf/outer xsep}}%
  \expandafter\xdef\csname tenkz@outerx@#1\endcsname{\the\pgf@x}%
  \pgfmathsetlength{\pgf@y}{\pgfkeysvalueof{/pgf/outer ysep}}%
  \expandafter\xdef\csname tenkz@outery@#1\endcsname{\the\pgf@y}}
\def\tenkz@checkcurrentauditowner#1{%
  \tenkz@auditownermatchfalse
  \edef\tenkz@currentauditowner{\tenkz@auditinstallowner}%
  \edef\tenkz@intendedauditowner{#1}%
  \ifx\tenkz@currentauditowner\tenkz@intendedauditowner
    \tenkz@auditownermatchtrue
  \fi}
\def\tenkz@checklastauditowner#1{%
  \tenkz@auditownermatchfalse
  \expandafter\ifx\csname tenkz@auditowner@#1\endcsname\relax
  \else
    \edef\tenkz@currentauditowner{\tikzlastnode}%
    \edef\tenkz@intendedauditowner{%
      \csname tenkz@auditowner@#1\endcsname}%
    \ifx\tenkz@currentauditowner\tenkz@intendedauditowner
      \tenkz@auditownermatchtrue
    \fi
  \fi}
\def\tenkz@checkrequiredlastauditowner#1{%
  \tenkz@checklastauditowner{#1}%
  \iftenkz@auditownermatch\else
    \tenkz@checkcurrentauditowner{#1}%
  \fi}
\def\tenkz@incrementtokenslot#1#2{%
  \count@=\csname tenkz@#1@#2\endcsname\relax
  \advance\count@ by 1\relax
  \expandafter\xdef\csname tenkz@#1@#2\endcsname{\the\count@}}
\def\tenkz@capturepathmode#1{%
  \tenkz@incrementtokenslot{modecount}{#1}%
  \csname tenkz@savedmode@#1\endcsname
  \iftikz@mode@shade
    \expandafter\gdef\csname tenkz@shade@#1\endcsname{1}%
  \else
    \expandafter\gdef\csname tenkz@shade@#1\endcsname{0}%
  \fi
  \iftikz@mode@fade@path
    \expandafter\gdef\csname tenkz@fade@#1\endcsname{1}%
  \else\iftikz@mode@fade@scope
    \expandafter\gdef\csname tenkz@fade@#1\endcsname{1}%
  \else
    \expandafter\gdef\csname tenkz@fade@#1\endcsname{0}%
  \fi\fi
  \ifx\tikz@path@picture\pgfutil@empty
    \expandafter\gdef\csname tenkz@pathpicture@#1\endcsname{0}%
  \else
    \expandafter\gdef\csname tenkz@pathpicture@#1\endcsname{1}%
  \fi}
\def\tenkz@captureactualpath#1#2{%
  \tenkz@incrementtokenslot{usecount}{#1}%
  \def\tenkz@affine{affine}%
  \ifx\tenkz@frameglyphangle\tenkz@affine
    % PGF has already materialized the node's transformed visible path here.
    % Preserve its page-space hull before the backend consumes and clears it.
    \expandafter\xdef\csname tenkz@pathxmin@#1\endcsname{\the\pgf@pathminx}%
    \expandafter\xdef\csname tenkz@pathxmax@#1\endcsname{\the\pgf@pathmaxx}%
    \expandafter\xdef\csname tenkz@pathymin@#1\endcsname{\the\pgf@pathminy}%
    \expandafter\xdef\csname tenkz@pathymax@#1\endcsname{\the\pgf@pathmaxy}%
  \fi
  \pgfutil@in@{draw}{#2}%
  \ifpgfutil@in@
    \expandafter\gdef\csname tenkz@draw@#1\endcsname{1}%
    \pgf@x=.5\pgflinewidth
    \expandafter\xdef\csname tenkz@stroke@#1\endcsname{\the\pgf@x}%
  \else
    \expandafter\gdef\csname tenkz@draw@#1\endcsname{0}%
    \expandafter\gdef\csname tenkz@stroke@#1\endcsname{0pt}%
  \fi
  \pgfutil@in@{fill}{#2}%
  \ifpgfutil@in@
    \expandafter\gdef\csname tenkz@fill@#1\endcsname{1}%
  \else
    \expandafter\gdef\csname tenkz@fill@#1\endcsname{0}%
  \fi
  \pgfutil@in@{clip}{#2}%
  \ifpgfutil@in@
    \expandafter\gdef\csname tenkz@clip@#1\endcsname{1}%
  \else
    \expandafter\gdef\csname tenkz@clip@#1\endcsname{0}%
  \fi
  \iftikz@mode@double
    \expandafter\gdef\csname tenkz@double@#1\endcsname{1}%
  \else
    \expandafter\gdef\csname tenkz@double@#1\endcsname{0}%
  \fi
  \expandafter\xdef\csname tenkz@join@#1\endcsname{\tenkz@livejoin}%
  \ifx\tenkz@livedash\tenkz@empty
    \expandafter\gdef\csname tenkz@dash@#1\endcsname{0}%
  \else
    \expandafter\gdef\csname tenkz@dash@#1\endcsname{1}%
  \fi
  \expandafter\xdef\csname tenkz@strokeopacity@#1\endcsname{%
    \tenkz@livestrokeopacity}%
  \expandafter\xdef\csname tenkz@fillopacity@#1\endcsname{%
    \tenkz@livefillopacity}}
\def\tenkz@setinvalid#1#2{%
  \edef\tenkz@invalidcode{\csname tenkz@invalid@#1\endcsname}%
  \ifnum\tenkz@invalidcode=0\relax
    \expandafter\gdef\csname tenkz@invalid@#1\endcsname{#2}%
  \fi}
\def\tenkz@validateactualpath#1{%
  \expandafter\gdef\csname tenkz@invalid@#1\endcsname{0}%
  % Prefer the semantic reason for a rejected path over the lower-level
  % single-pass guard: path pictures and similar effects can themselves add
  % mode evaluations or path uses.
  \ifnum\csname tenkz@double@#1\endcsname=1\relax
    \tenkz@setinvalid{#1}{5}%
  \fi
  \ifnum\csname tenkz@shade@#1\endcsname=1\relax
    \tenkz@setinvalid{#1}{6}%
  \fi
  \ifnum\csname tenkz@fade@#1\endcsname=1\relax
    \tenkz@setinvalid{#1}{7}%
  \fi
  \ifnum\csname tenkz@pathpicture@#1\endcsname=1\relax
    \tenkz@setinvalid{#1}{10}%
  \fi
  \ifnum\csname tenkz@clip@#1\endcsname=1\relax
    \tenkz@setinvalid{#1}{9}%
  \fi
  \ifnum\csname tenkz@draw@#1\endcsname=1\relax
    \edef\tenkz@actualjoin{\csname tenkz@join@#1\endcsname}%
    \def\tenkz@roundjoin{round}%
    \ifx\tenkz@actualjoin\tenkz@roundjoin\else
      \tenkz@setinvalid{#1}{1}%
    \fi
    \ifnum\csname tenkz@dash@#1\endcsname=1\relax
      \tenkz@setinvalid{#1}{2}%
    \fi
    \pgf@xa=\csname tenkz@strokeopacity@#1\endcsname pt\relax
    \ifdim\pgf@xa>0pt\else\tenkz@setinvalid{#1}{3}\fi
  \fi
  \ifnum\csname tenkz@fill@#1\endcsname=1\relax
    \pgf@xa=\csname tenkz@fillopacity@#1\endcsname pt\relax
    \ifdim\pgf@xa>0pt\else\tenkz@setinvalid{#1}{4}\fi
  \fi
  \ifnum\csname tenkz@usecount@#1\endcsname=1\relax
  \else\tenkz@setinvalid{#1}{8}\fi
  \ifnum\csname tenkz@outercount@#1\endcsname=1\relax
  \else\tenkz@setinvalid{#1}{12}\fi
  \ifnum\csname tenkz@modecount@#1\endcsname=1\relax
  \else\tenkz@setinvalid{#1}{11}\fi}
\def\tenkz@runouterhook#1{%
  \expandafter\ifx\csname tenkz@outeractive@#1\endcsname\relax
    \csname tenkz@savedouter@#1\endcsname
  \else
    \expandafter\let\csname tenkz@outeractive@#1\endcsname\relax
    \csname tenkz@savedouter@#1\endcsname
    \tenkz@snapshotoutersep{#1}%
  \fi}
\def\tenkz@runactualusage#1{%
  \expandafter\let\csname tenkz@savedusepath@#1\endcsname\pgfusepath
  \expandafter\let\csname tenkz@savedmode@#1\endcsname\tikz@mode
  \def\pgfusepath##1{%
    \tenkz@captureactualpath{#1}{##1}%
    \csname tenkz@savedusepath@#1\endcsname{##1}}%
  \def\tikz@mode{\tenkz@capturepathmode{#1}}%
  \csname tenkz@savedusage@#1\endcsname
  \expandafter\let\csname tenkz@savedusepath@#1\endcsname\relax
  \expandafter\let\csname tenkz@savedmode@#1\endcsname\relax
  \tenkz@validateactualpath{#1}}
% The unclaimed branch is the original four-argument call.  The per-node local
% claimant binds its token to PGF's final node name here: nested pictures can
% inherit outer hooks, so construction order alone cannot identify ownership.
\let\tenkz@multipartnode\pgfmultipartnode
\def\pgfmultipartnode#1#2#3#4{%
  \ifx\tenkz@auditinstallowner\relax\else
    \expandafter\xdef\csname tenkz@auditowner@%
      \tenkz@auditinstallowner\endcsname{#3}%
    \expandafter\ifx\csname tenkz@snapshotdone@%
      \tenkz@auditinstallowner\endcsname\relax
    \else
      \expandafter\xdef\csname tenkz@audittoken@#3\endcsname{%
        \tenkz@auditinstallowner}%
    \fi
  \fi
  \expandafter\ifx\csname tenkz@audittoken@#3\endcsname\relax
    \tenkz@multipartnode{#1}{#2}{#3}{#4}%
  \else
    \edef\tenkz@token{\csname tenkz@audittoken@#3\endcsname}%
    \global\expandafter\let\csname tenkz@audittoken@#3\endcsname\relax
    % TikZ closes the materialized text hbox immediately before this PGF
    % call.  Save it now; after placement the `text' anchor is its
    % baseline-left origin.
    \expandafter\xdef\csname tenkz@textwidth@\tenkz@token\endcsname{%
      \the\wd\pgfnodeparttextbox}%
    \expandafter\xdef\csname tenkz@textheight@\tenkz@token\endcsname{%
      \the\ht\pgfnodeparttextbox}%
    \expandafter\xdef\csname tenkz@textdepth@\tenkz@token\endcsname{%
      \the\dp\pgfnodeparttextbox}%
    \expandafter\let\csname tenkz@savedouter@\tenkz@token\endcsname
      \pgf@outer@adjust@hook
    \expandafter\def\csname tenkz@outeractive@\tenkz@token\endcsname{1}%
    \expandafter\def\csname tenkz@savedusage@\tenkz@token\endcsname{#4}%
    \expandafter\gdef\csname tenkz@outercount@\tenkz@token\endcsname{0}%
    \expandafter\gdef\csname tenkz@modecount@\tenkz@token\endcsname{0}%
    \expandafter\gdef\csname tenkz@usecount@\tenkz@token\endcsname{0}%
    \expandafter\gdef\csname tenkz@draw@\tenkz@token\endcsname{0}%
    \expandafter\gdef\csname tenkz@fill@\tenkz@token\endcsname{0}%
    \expandafter\gdef\csname tenkz@stroke@\tenkz@token\endcsname{0pt}%
    \expandafter\gdef\csname tenkz@double@\tenkz@token\endcsname{0}%
    \expandafter\gdef\csname tenkz@shade@\tenkz@token\endcsname{0}%
    \expandafter\gdef\csname tenkz@fade@\tenkz@token\endcsname{0}%
    \expandafter\gdef\csname tenkz@pathpicture@\tenkz@token\endcsname{0}%
    \expandafter\gdef\csname tenkz@clip@\tenkz@token\endcsname{0}%
    \expandafter\gdef\csname tenkz@join@\tenkz@token\endcsname{unknown}%
    \expandafter\gdef\csname tenkz@dash@\tenkz@token\endcsname{0}%
    \expandafter\gdef\csname tenkz@strokeopacity@\tenkz@token\endcsname{1}%
    \expandafter\gdef\csname tenkz@fillopacity@\tenkz@token\endcsname{1}%
    \edef\pgf@outer@adjust@hook{%
      \noexpand\tenkz@runouterhook{\tenkz@token}}%
    \edef\tenkz@wrappedusage{%
      \noexpand\tenkz@runactualusage{\tenkz@token}}%
    \tenkz@multipartnode{#1}{#2}{#3}{\tenkz@wrappedusage}%
    \expandafter\let\expandafter\pgf@outer@adjust@hook
      \csname tenkz@savedouter@\tenkz@token\endcsname
    \expandafter\let\csname tenkz@savedouter@\tenkz@token\endcsname\relax
    \expandafter\let\csname tenkz@outeractive@\tenkz@token\endcsname\relax
    \expandafter\let\csname tenkz@savedusage@\tenkz@token\endcsname\relax
  \fi}
\def\tenkz@visiblestateerror#1#2#3{%
  \ifcase#1\relax
  \or\PackageError{tenkz}{Audited #2 node '#3' has a non-round line join}%
      {Use line join=round for audited visible geometry.}%
  \or\PackageError{tenkz}{Audited #2 node '#3' has a dashed stroke}%
      {Use a solid stroke for audited visible geometry.}%
  \or\PackageError{tenkz}{Audited #2 node '#3' has zero draw opacity}%
      {Use positive draw opacity or draw=none.}%
  \or\PackageError{tenkz}{Audited #2 node '#3' has zero fill opacity}%
      {Use positive fill opacity or fill=none.}%
  \or\PackageError{tenkz}{Audited #2 node '#3' has a double stroke}%
      {Double strokes are not representable by the audit geometry.}%
  \or\PackageError{tenkz}{Audited #2 node '#3' uses shading}%
      {Shaded paths are not representable by the audit geometry.}%
  \or\PackageError{tenkz}{Audited #2 node '#3' uses fading}%
      {Faded paths are not representable by the audit geometry.}%
  \or\PackageError{tenkz}{Audited #2 node '#3' has multiple path uses}%
      {Use one ordinary fill/draw path for audited visible geometry.}%
  \or\PackageError{tenkz}{Audited #2 node '#3' uses clipping}%
      {Clipped nodes are not representable by the audit geometry.}%
  \or\PackageError{tenkz}{Audited #2 node '#3' uses a path picture}%
      {Path pictures are not representable by the audit geometry.}%
  \or\PackageError{tenkz}{Audited #2 node '#3' has multiple mode evaluations}%
      {Use an ordinary single-pass TikZ node.}%
  \or\PackageError{tenkz}{Audited #2 node '#3' has multiple outer adjustments}%
      {Use an ordinary single-pass PGF node.}%
  \or\PackageError{tenkz}{Audited #2 node '#3' has an outline without a fill}%
      {Use a filled rectangle or a transparent text-only audited label.}%
  \or\PackageError{tenkz}{Audited #2 node '#3' has zero text opacity}%
      {Use positive text opacity for audited labels.}%
  \or\PackageError{tenkz}{Audited #2 node '#3' has a negative live half-stroke}%
      {Use a nonnegative line width for audited labels.}%
  \else\PackageError{tenkz}{Audited #2 node '#3' has invalid visible state}%
      {Use an ordinary filled, optionally round-stroked audited node.}%
  \fi}
% shared by the label and glyph capture entry points below: neither ran
% its owned PGF path callback (the node's audit style was never actually
% applied), so there is no invalid-code register to read at all.  #2 is
% the node to DISPLAY (not necessarily \tikzlastnode -- a deferred glyph
% capture reports a saved node reference instead), #3 the invalid-code
% lookup key to clean up
\def\tenkz@nocapturedpathstate#1#2#3{%
  \tenkz@cleanupglyphsnapshot{#3}%
  \PackageError{tenkz}{Audited #1 node '#2' has no captured path state}%
    {The node did not run its owned PGF path callback.}}
\def\tenkz@capturelabelbbox#1{%
  \tenkz@checkrequiredlastauditowner{#1}%
  \iftenkz@auditownermatch
    \expandafter\ifx\csname tenkz@labelowner@#1\endcsname\relax
    \else
      \tenkz@inkowner=\csname tenkz@labelowner@#1\endcsname\relax
    \fi
    \expandafter\ifx\csname tenkz@invalid@#1\endcsname\relax
      \tenkz@nocapturedpathstate{label}{\tikzlastnode}{#1}%
    \else
      \tenkz@capturelabelbboxstate{#1}%
    \fi
  \fi}
\def\tenkz@capturelabelbboxstate#1{%
  \edef\tenkz@visibleinvalid{\csname tenkz@invalid@#1\endcsname}%
  % A fill supplies solid rectangular support.  With neither fill nor stroke,
  % the exact auditable support is PGF's materialized text box.  A draw-only
  % rectangle is an outline ring, which this geometry schema cannot represent.
  \ifnum\tenkz@visibleinvalid=0\relax
    \ifnum\csname tenkz@fill@#1\endcsname=1\relax
    \else
      \ifnum\csname tenkz@draw@#1\endcsname=1\relax
        \tenkz@setinvalid{#1}{13}%
        \edef\tenkz@visibleinvalid{13}%
      \fi
    \fi
  \fi
  \ifnum\tenkz@visibleinvalid=0\relax
    \pgf@xa=\csname tenkz@textopacity@#1\endcsname pt\relax
    \ifdim\pgf@xa>0pt\else
      \tenkz@setinvalid{#1}{14}%
      \edef\tenkz@visibleinvalid{14}%
    \fi
  \fi
  \ifnum\tenkz@visibleinvalid=0\relax
    \ifnum\csname tenkz@draw@#1\endcsname=1\relax
      \pgf@xa=\csname tenkz@stroke@#1\endcsname\relax
      \ifdim\pgf@xa<0pt
        \tenkz@setinvalid{#1}{15}%
        \edef\tenkz@visibleinvalid{15}%
      \fi
    \fi
  \fi
  \ifnum\tenkz@visibleinvalid=0\relax
    \iftenkz@auditpicture
      \begingroup
      % The claim, if this node's install consumed one, rides the same
      % token as the rest of its snapshot state.
      \expandafter\let\expandafter\tenkz@labelprovenance
        \csname tenkz@labelclaimprov@#1\endcsname
      \expandafter\let\expandafter\tenkz@labelstation
        \csname tenkz@labelclaimstat@#1\endcsname
      \expandafter\let\expandafter\tenkz@labelrole
        \csname tenkz@labelclaimrole@#1\endcsname
      \tenkz@requireidentitylinear{\tikzlastnode}{label}%
      \tenkz@requirelabelrectangle{\tikzlastnode}%
      \iftenkz@identitylinear
      \iftenkz@labelrectangle
        \ifnum\csname tenkz@fill@#1\endcsname=1\relax
          \tenkz@readlabelcorners{#1}%
          \iftenkz@labelrectangle
            \tenkz@glyphouterxsep=\csname tenkz@outerx@#1\endcsname\relax
            \tenkz@glyphouterysep=\csname tenkz@outery@#1\endcsname\relax
            \tenkz@glyphhalfstroke=\csname tenkz@stroke@#1\endcsname\relax
            \pgfextractx{\tenkz@bboxxmin}{%
              \pgfpointanchor{\tikzlastnode}{west}}%
            \pgfextractx{\tenkz@bboxxmax}{%
              \pgfpointanchor{\tikzlastnode}{east}}%
            \pgfextracty{\tenkz@bboxymin}{%
              \pgfpointanchor{\tikzlastnode}{south}}%
            \pgfextracty{\tenkz@bboxymax}{%
              \pgfpointanchor{\tikzlastnode}{north}}%
            \advance\tenkz@bboxxmin by \tenkz@glyphouterxsep
            \advance\tenkz@bboxxmax by -\tenkz@glyphouterxsep
            \advance\tenkz@bboxymin by \tenkz@glyphouterysep
            \advance\tenkz@bboxymax by -\tenkz@glyphouterysep
            \advance\tenkz@bboxxmin by -\tenkz@glyphhalfstroke
            \advance\tenkz@bboxxmax by \tenkz@glyphhalfstroke
            \advance\tenkz@bboxymin by -\tenkz@glyphhalfstroke
            \advance\tenkz@bboxymax by \tenkz@glyphhalfstroke
            \ifdim\tenkz@glyphhalfstroke>0pt
              \def\tenkz@labelshape{roundrect}%
              \tenkz@labelradius=\tenkz@glyphhalfstroke
            \else
              \def\tenkz@labelshape{rect}%
              \tenkz@labelradius=0pt
            \fi
            \pgf@xa=\csname tenkz@fillopacity@#1\endcsname pt\relax
            \ifdim\pgf@xa=1pt
              \def\tenkz@labelopaque{1}%
            \else
              \def\tenkz@labelopaque{0}%
            \fi
          \fi
        \else
          \pgfextractx{\tenkz@bboxxmin}{%
            \pgfpointanchor{\tikzlastnode}{text}}%
          \pgfextracty{\tenkz@bboxya}{%
            \pgfpointanchor{\tikzlastnode}{text}}%
          \tenkz@bboxxmax=\tenkz@bboxxmin
          \advance\tenkz@bboxxmax by
            \csname tenkz@textwidth@#1\endcsname\relax
          \tenkz@bboxymin=\tenkz@bboxya
          \advance\tenkz@bboxymin by
            -\csname tenkz@textdepth@#1\endcsname\relax
          \tenkz@bboxymax=\tenkz@bboxya
          \advance\tenkz@bboxymax by
            \csname tenkz@textheight@#1\endcsname\relax
          \def\tenkz@labelshape{rect}%
          \tenkz@labelradius=0pt
          \def\tenkz@labelopaque{0}%
        \fi
        \iftenkz@labelrectangle
          \tenkz@storelabelgeometry
          \iftenkz@bboxcapture
            \tenkz@writelabelbbox
          \fi
        \fi
      \fi
      \fi
      \endgroup
    \fi
    \tenkz@cleanupglyphsnapshot{#1}%
  \else
    \tenkz@cleanupglyphsnapshot{#1}%
    \tenkz@visiblestateerror{\tenkz@visibleinvalid}{label}{\tikzlastnode}%
  \fi}
\def\tenkz@snapshotvisible#1{%
  \tenkz@checkcurrentauditowner{#1}%
  \iftenkz@auditownermatch
    \expandafter\ifx\csname tenkz@snapshotdone@#1\endcsname\relax
      % PGF calls the multipart usage argument only for shapes with a
      % background or foreground path.  Do not arm pathless coordinate nodes
      % that inherit a matrix's `every node' style.
      \pgfutil@ifundefined{pgf@sh@bg@\tikz@shape}{%
        \pgfutil@ifundefined{pgf@sh@fg@\tikz@shape}{}{%
          \tenkz@snapshotvisiblepath{#1}}%
      }{\tenkz@snapshotvisiblepath{#1}}%
    \fi
  \fi
}
\def\tenkz@snapshotvisiblepath#1{%
  \expandafter\gdef\csname tenkz@snapshotdone@#1\endcsname{1}%
  \ifx\tikz@textopacity\pgfutil@empty
    \expandafter\gdef\csname tenkz@textopacity@#1\endcsname{1}%
  \else
    \expandafter\xdef\csname tenkz@textopacity@#1\endcsname{\tikz@textopacity}%
  \fi}
% Capture the final corner state while TikZ is still constructing the node.
% `append after command' runs too late: PGF has restored the path-local
% \ifpgf@arccorners and \pgf@corner@arc state by then.  Each audited node gets a
% globally unique token, and `execute at end node' snapshots the state under
% that token for the matching append-after callback to consume.
\def\tenkz@snapshotglyphstate#1{%
  \tenkz@checkcurrentauditowner{#1}%
  \iftenkz@auditownermatch
    \expandafter\ifx\csname tenkz@snapshotdone@#1\endcsname\relax
      \ifpgf@arccorners
        \expandafter\gdef\csname tenkz@glypharcflag@#1\endcsname{1}%
        \expandafter\xdef\csname tenkz@glypharc@#1\endcsname{\pgf@corner@arc}%
      \else
        \expandafter\gdef\csname tenkz@glypharcflag@#1\endcsname{0}%
        \expandafter\gdef\csname tenkz@glypharc@#1\endcsname{{0pt}{0pt}}%
      \fi
      \ifx\tenkz@frameglyphangle\relax\else
        \expandafter\xdef\csname tenkz@frameglyph@#1\endcsname
          {\tenkz@frameglyphangle}%
      \fi
      \tenkz@snapshotvisible{#1}%
    \fi
  \fi}
\def\tenkz@setglypharcaux#1#2{%
  \tenkz@glyphradiusx=#1\relax
  \tenkz@glyphradiusy=#2\relax}
\def\tenkz@readglyphcorners#1{%
  \edef\tenkz@glypharcflag{\csname tenkz@glypharcflag@#1\endcsname}%
  \ifnum\tenkz@glypharcflag=1\relax
    \edef\tenkz@glypharcs{\csname tenkz@glypharc@#1\endcsname}%
    \expandafter\tenkz@setglypharcaux\tenkz@glypharcs
    \ifdim\tenkz@glyphradiusx<0pt
      \PackageError{tenkz}{Audited rounded rectangle has a negative x radius}%
        {Use an isotropic, nonnegative corner radius.}%
    \fi
    \ifdim\tenkz@glyphradiusy<0pt
      \PackageError{tenkz}{Audited rounded rectangle has a negative y radius}%
        {Use an isotropic, nonnegative corner radius.}%
    \fi
    \ifdim\tenkz@glyphradiusx=\tenkz@glyphradiusy\relax
    \else
      \PackageError{tenkz}{Audited rounded rectangle has unequal corner radii}%
        {Use the same nonnegative radius in both axes.}%
    \fi
    \tenkz@glyphradius=\tenkz@glyphradiusx
  \else
    \tenkz@glyphradius=0pt
  \fi}
\def\tenkz@readlabelcorners#1{%
  \edef\tenkz@glypharcflag{\csname tenkz@glypharcflag@#1\endcsname}%
  \ifnum\tenkz@glypharcflag=1\relax
    \edef\tenkz@glypharcs{\csname tenkz@glypharc@#1\endcsname}%
    \expandafter\tenkz@setglypharcaux\tenkz@glypharcs
    \ifdim\tenkz@glyphradiusx=0pt\relax
      \ifdim\tenkz@glyphradiusy=0pt\relax\else
        \tenkz@rejectlabelcorners
      \fi
    \else
      \tenkz@rejectlabelcorners
    \fi
  \fi}
\def\tenkz@rejectlabelcorners{%
  \tenkz@labelrectanglefalse
  \PackageError{tenkz}{Audited label node '\tikzlastnode' has rounded corners}%
    {Use a sharp rectangular fill; a round line join may round only its stroke.}}

% PGF's public triangle corner anchors include `outer sep'.  These private
% audit anchors use the shape's saved, pre-separation vertices instead; the
% normal node transform is still applied by \pgfpointanchor.
\expandafter\def\csname pgf@anchor@isosceles triangle@tenkz apex\endcsname{%
  \trianglepoints
  \pgfpointadd{\centerpoint}{%
    \pgfmathrotatepointaround{\apex}{\pgfpointorigin}{\rotate}}}
\expandafter\def\csname pgf@anchor@isosceles triangle@tenkz left corner\endcsname{%
  \trianglepoints
  \pgfpointadd{\centerpoint}{%
    \pgfmathrotatepointaround{\lowerleft}{\pgfpointorigin}{\rotate}}}
\expandafter\def\csname pgf@anchor@isosceles triangle@tenkz right corner\endcsname{%
  \trianglepoints
  \lowerleft
  \pgf@xa=\pgf@x
  \pgf@ya=-\pgf@y
  \pgfpointadd{\centerpoint}{%
    \pgfmathrotatepointaround{\pgfqpoint{\pgf@xa}{\pgf@ya}}%
      {\pgfpointorigin}{\rotate}}}

% Resolve the node's final PGF shape identity after every style addition has
% run.  A semantic skin may be restyled from (say) circle to rectangle, or its
% rounded corners may be enabled/disabled; the event describes that live node,
% not the base style's starting shape or declared radius.
\def\tenkz@resolveglyphshape#1#2{%
  \edef\tenkz@livepgfshape{\csname pgf@sh@ns@#1\endcsname}%
  \tenkz@glyphouterxsep=\csname tenkz@outerx@#2\endcsname\relax
  \tenkz@glyphouterysep=\csname tenkz@outery@#2\endcsname\relax
  \tenkz@glyphhalfstroke=\csname tenkz@stroke@#2\endcsname\relax
  \def\tenkz@pgfcircle{circle}%
  \def\tenkz@pgfrectangle{rectangle}%
  \def\tenkz@pgftriangle{isosceles triangle}%
  \ifx\tenkz@livepgfshape\tenkz@pgfcircle
    \def\tenkz@glyphshape{circle}%
    \tenkz@glyphradius=0pt
  \else\ifx\tenkz@livepgfshape\tenkz@pgfrectangle
    \tenkz@readglyphcorners{#2}%
    \ifdim\tenkz@glyphradius>0pt
      \def\tenkz@glyphshape{roundrect}%
    \else\ifdim\tenkz@glyphhalfstroke>0pt
      \def\tenkz@glyphshape{roundrect}%
    \else
      \def\tenkz@glyphshape{rect}%
    \fi\fi
  \else\ifx\tenkz@livepgfshape\tenkz@pgftriangle
    \tenkz@readglyphcorners{#2}%
    \ifdim\tenkz@glyphradius>0pt
      \PackageError{tenkz}{Audited triangle '#1' has rounded corners}%
        {Rounded triangles are not representable by the audit geometry.}%
    \fi
    \def\tenkz@glyphshape{triangle}%
    \tenkz@glyphradius=0pt
  \else
    \def\tenkz@glyphshape{unsupported}%
    \tenkz@glyphradius=0pt
    \PackageError{tenkz}{Audited glyph node '#1' has unsupported live shape
      '\tenkz@livepgfshape'}{Use a circle, rectangle, rounded rectangle, or
      isosceles triangle for a library-owned glyph.}%
  \fi\fi\fi}
\def\tenkz@emitglyphinkuse{%
  \tenkz@event{ink-use|picture=\tenkz@auditpictureid|class=glyph|%
    id=\the\tenkz@inkowner|shape=\tenkz@glyphshape}}
\def\tenkz@captureglyphgeometry#1#2#3{%
  \tenkz@checkrequiredlastauditowner{#3}%
  \iftenkz@auditownermatch
    \tenkz@captureglyphgeometrynode{\tikzlastnode}{#1}{#2}{#3}%
  \fi}
\def\tenkz@cleanupglyphsnapshot#1{%
  \global\expandafter\let\csname tenkz@glypharcflag@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@glypharc@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@frameglyph@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@labelowner@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@labelclaimprov@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@labelclaimstat@#1\endcsname\relax
  \global\expandafter\let\csname tenkz@labelclaimrole@#1\endcsname\relax
  \tenkz@cleanupvisiblesnapshot{#1}}
\def\tenkz@captureglyphgeometrynode#1#2#3#4{%
  \expandafter\ifx\csname tenkz@invalid@#4\endcsname\relax
    \tenkz@nocapturedpathstate{glyph}{#1}{#4}%
  \else
    \edef\tenkz@visibleinvalid{\csname tenkz@invalid@#4\endcsname}%
    \ifnum\tenkz@visibleinvalid=0\relax
    \iftenkz@bboxcapture
      \iftenkz@auditpicture
      \global\advance\tenkz@inkuid by 1\relax
      \tenkz@inkowner=\tenkz@inkuid
      \tenkz@resolveglyphshape{#1}{#4}%
      \edef\tenkz@glyphfill{\csname tenkz@fill@#4\endcsname}%
      \ifnum\tenkz@glyphfill=1\relax\else
        \def\tenkz@glyphshape{unsupported}%
        \PackageError{tenkz}{Audited glyph node '#1' has no filled shape}%
          {Give every audited glyph a live fill, not only a drawn outline.}%
      \fi
      \tenkz@frameglyphrotatedfalse
      \tenkz@frameglyphaffinefalse
      \expandafter\ifx\csname tenkz@frameglyph@#4\endcsname\relax
        \tenkz@requireidentitylinear{#1}{glyph}%
        \iftenkz@identitylinear\else\def\tenkz@glyphshape{unsupported}\fi
      \else
        % Only the private frame and basis keys sanction transformed glyphs.
        % Arbitrary transform-shape customization remains identity-only.
        \edef\tenkz@nodematrix{\csname pgf@sh@nt@#1\endcsname}%
        \expandafter\tenkz@checklinear\tenkz@nodematrix
        \iftenkz@identitylinear\else\tenkz@frameglyphrotatedtrue\fi
        \edef\tenkz@frameglyphkind{\csname tenkz@frameglyph@#4\endcsname}%
        \def\tenkz@affine{affine}%
        \ifx\tenkz@frameglyphkind\tenkz@affine
          \tenkz@frameglyphaffinetrue
          % The current audit schema has no ellipse or general curved-path
          % primitive.  Publish the conservative captured path hull instead.
          \def\tenkz@glyphshape{rect}%
          \tenkz@glyphradius=0pt
        \fi
      \fi
      \iftenkz@frameglyphrotated
        % A rotated rounded rectangle is not an axis-aligned rounded
        % rectangle.  Audit its conservative sharp axis-aligned hull.
        \def\tenkz@roundrect{roundrect}%
        \ifx\tenkz@glyphshape\tenkz@roundrect
          \def\tenkz@glyphshape{rect}%
          \tenkz@glyphradius=0pt
        \fi
      \fi
      \tenkz@emitglyphinkuse
      \tenkz@emitglyphgeometry{#1}{#4}%
      \fi
    \fi
    \tenkz@cleanupglyphsnapshot{#4}%
    \else
      \tenkz@cleanupglyphsnapshot{#4}%
      \tenkz@visiblestateerror{\tenkz@visibleinvalid}{glyph}{#1}%
    \fi
  \fi}
\def\tenkz@bboxincludeanchor#1#2{%
  \pgfextractx{\tenkz@bboxxa}{\pgfpointanchor{#1}{#2}}%
  \pgfextracty{\tenkz@bboxya}{\pgfpointanchor{#1}{#2}}%
  \ifdim\tenkz@bboxxa<\tenkz@bboxxmin \tenkz@bboxxmin=\tenkz@bboxxa\fi
  \ifdim\tenkz@bboxxa>\tenkz@bboxxmax \tenkz@bboxxmax=\tenkz@bboxxa\fi
  \ifdim\tenkz@bboxya<\tenkz@bboxymin \tenkz@bboxymin=\tenkz@bboxya\fi
  \ifdim\tenkz@bboxya>\tenkz@bboxymax \tenkz@bboxymax=\tenkz@bboxya\fi}
\def\tenkz@emitglyphgeometry#1#2{%
  \begingroup
  \def\tenkz@circle{circle}%
  \iftenkz@frameglyphaffine
    \tenkz@bboxxmin=\csname tenkz@pathxmin@#2\endcsname\relax
    \tenkz@bboxxmax=\csname tenkz@pathxmax@#2\endcsname\relax
    \tenkz@bboxymin=\csname tenkz@pathymin@#2\endcsname\relax
    \tenkz@bboxymax=\csname tenkz@pathymax@#2\endcsname\relax
  \else\ifx\tenkz@glyphshape\tenkz@circle
    % A circle's rotated corner anchors are not its axis extrema.  Recover
    % its invariant radius from the transformed centre-to-east vector.
    \pgfextractx{\tenkz@bboxxmin}{\pgfpointanchor{#1}{center}}%
    \pgfextracty{\tenkz@bboxymin}{\pgfpointanchor{#1}{center}}%
    \pgfextractx{\tenkz@bboxxa}{\pgfpointanchor{#1}{east}}%
    \pgfextracty{\tenkz@bboxya}{\pgfpointanchor{#1}{east}}%
    \advance\tenkz@bboxxa by -\tenkz@bboxxmin
    \advance\tenkz@bboxya by -\tenkz@bboxymin
    \pgfmathparse
      {veclen(\strip@pt\tenkz@bboxxa,\strip@pt\tenkz@bboxya)}%
    \tenkz@bboxxa=\pgfmathresult pt
    \tenkz@bboxxmax=\tenkz@bboxxmin
    \advance\tenkz@bboxxmin by -\tenkz@bboxxa
    \advance\tenkz@bboxxmax by \tenkz@bboxxa
    \tenkz@bboxymax=\tenkz@bboxymin
    \advance\tenkz@bboxymin by -\tenkz@bboxxa
    \advance\tenkz@bboxymax by \tenkz@bboxxa
  \else
    \iftenkz@frameglyphrotated
      \pgfextractx{\tenkz@bboxxmin}{\pgfpointanchor{#1}{north east}}%
      \pgfextracty{\tenkz@bboxymin}{\pgfpointanchor{#1}{north east}}%
      \tenkz@bboxxmax=\tenkz@bboxxmin
      \tenkz@bboxymax=\tenkz@bboxymin
      \tenkz@bboxincludeanchor{#1}{north west}%
      \tenkz@bboxincludeanchor{#1}{south east}%
      \tenkz@bboxincludeanchor{#1}{south west}%
    \else
      \pgfextractx{\tenkz@bboxxmin}{\pgfpointanchor{#1}{west}}%
      \pgfextractx{\tenkz@bboxxmax}{\pgfpointanchor{#1}{east}}%
      \pgfextracty{\tenkz@bboxymin}{\pgfpointanchor{#1}{south}}%
      \pgfextracty{\tenkz@bboxymax}{\pgfpointanchor{#1}{north}}%
    \fi
  \fi\fi
  \iftenkz@frameglyphaffine
  \else\ifx\tenkz@glyphshape\tenkz@circle
    \ifdim\tenkz@glyphouterxsep<\tenkz@glyphouterysep
      \tenkz@glyphouterxsep=\tenkz@glyphouterysep
    \fi
    \advance\tenkz@bboxxmin by \tenkz@glyphouterxsep
    \advance\tenkz@bboxxmax by -\tenkz@glyphouterxsep
    \advance\tenkz@bboxymin by \tenkz@glyphouterxsep
    \advance\tenkz@bboxymax by -\tenkz@glyphouterxsep
  \else
    \advance\tenkz@bboxxmin by \tenkz@glyphouterxsep
    \advance\tenkz@bboxxmax by -\tenkz@glyphouterxsep
    \advance\tenkz@bboxymin by \tenkz@glyphouterysep
    \advance\tenkz@bboxymax by -\tenkz@glyphouterysep
  \fi\fi
  \advance\tenkz@bboxxmin by -\tenkz@glyphhalfstroke
  \advance\tenkz@bboxxmax by \tenkz@glyphhalfstroke
  \advance\tenkz@bboxymin by -\tenkz@glyphhalfstroke
  \advance\tenkz@bboxymax by \tenkz@glyphhalfstroke
  \def\tenkz@roundrect{roundrect}%
  \ifx\tenkz@glyphshape\tenkz@roundrect
    \advance\tenkz@glyphradius by \tenkz@glyphhalfstroke
    \tenkz@glyphwidth=\tenkz@bboxxmax
    \advance\tenkz@glyphwidth by -\tenkz@bboxxmin
    \tenkz@glyphheight=\tenkz@bboxymax
    \advance\tenkz@glyphheight by -\tenkz@bboxymin
    \tenkz@glyphdiameter=\tenkz@glyphradius
    \advance\tenkz@glyphdiameter by \tenkz@glyphradius
    \ifdim\tenkz@glyphdiameter>\tenkz@glyphwidth
      \PackageError{tenkz}{Audited rounded rectangle radius exceeds half its width}%
        {Reduce the corner radius or enlarge the node.}%
    \fi
    \ifdim\tenkz@glyphdiameter>\tenkz@glyphheight
      \PackageError{tenkz}{Audited rounded rectangle radius exceeds half its height}%
        {Reduce the corner radius or enlarge the node.}%
    \fi
  \fi
  \def\tenkz@triangle{triangle}%
  \ifx\tenkz@glyphshape\tenkz@triangle
    \pgfextractx{\tenkz@glyphxone}{\pgfpointanchor{#1}{tenkz apex}}%
    \pgfextracty{\tenkz@glyphyone}{\pgfpointanchor{#1}{tenkz apex}}%
    \pgfextractx{\tenkz@glyphxtwo}{\pgfpointanchor{#1}{tenkz left corner}}%
    \pgfextracty{\tenkz@glyphytwo}{\pgfpointanchor{#1}{tenkz left corner}}%
    \pgfextractx{\tenkz@glyphxthree}{\pgfpointanchor{#1}{tenkz right corner}}%
    \pgfextracty{\tenkz@glyphythree}{\pgfpointanchor{#1}{tenkz right corner}}%
    \tenkz@bboxxmin=\tenkz@glyphxone \tenkz@bboxxmax=\tenkz@glyphxone
    \tenkz@bboxymin=\tenkz@glyphyone \tenkz@bboxymax=\tenkz@glyphyone
    \ifdim\tenkz@glyphxtwo<\tenkz@bboxxmin \tenkz@bboxxmin=\tenkz@glyphxtwo\fi
    \ifdim\tenkz@glyphxtwo>\tenkz@bboxxmax \tenkz@bboxxmax=\tenkz@glyphxtwo\fi
    \ifdim\tenkz@glyphxthree<\tenkz@bboxxmin \tenkz@bboxxmin=\tenkz@glyphxthree\fi
    \ifdim\tenkz@glyphxthree>\tenkz@bboxxmax \tenkz@bboxxmax=\tenkz@glyphxthree\fi
    \ifdim\tenkz@glyphytwo<\tenkz@bboxymin \tenkz@bboxymin=\tenkz@glyphytwo\fi
    \ifdim\tenkz@glyphytwo>\tenkz@bboxymax \tenkz@bboxymax=\tenkz@glyphytwo\fi
    \ifdim\tenkz@glyphythree<\tenkz@bboxymin \tenkz@bboxymin=\tenkz@glyphythree\fi
    \ifdim\tenkz@glyphythree>\tenkz@bboxymax \tenkz@bboxymax=\tenkz@glyphythree\fi
    \advance\tenkz@bboxxmin by -\tenkz@glyphhalfstroke
    \advance\tenkz@bboxxmax by \tenkz@glyphhalfstroke
    \advance\tenkz@bboxymin by -\tenkz@glyphhalfstroke
    \advance\tenkz@bboxymax by \tenkz@glyphhalfstroke
  \else
    \tenkz@glyphxone=0pt \tenkz@glyphyone=0pt
    \tenkz@glyphxtwo=0pt \tenkz@glyphytwo=0pt
    \tenkz@glyphxthree=0pt \tenkz@glyphythree=0pt
  \fi
  \tenkz@event{glyph-geometry|picture=\tenkz@auditpictureid|%
    owner=\the\tenkz@inkowner|shape=\tenkz@glyphshape|%
    xmin=\number\tenkz@bboxxmin|xmax=\number\tenkz@bboxxmax|%
    ymin=\number\tenkz@bboxymin|ymax=\number\tenkz@bboxymax|%
    radius=\number\tenkz@glyphradius|stroke=\number\tenkz@glyphhalfstroke|%
    x1=\number\tenkz@glyphxone|y1=\number\tenkz@glyphyone|%
    x2=\number\tenkz@glyphxtwo|y2=\number\tenkz@glyphytwo|%
    x3=\number\tenkz@glyphxthree|y3=\number\tenkz@glyphythree}%
  \endgroup}
\tikzset{
  tenkz glyph frame/.style={
    transform shape,
    rotate=#1,
    /utils/exec={\def\tenkz@frameglyphangle{#1}}},
  tenkz glyph basis/.style args={#1,#2,#3,#4}{
    transform shape,
    cm={#1,#2,#3,#4,(0pt,0pt)},
    /utils/exec={\def\tenkz@frameglyphangle{affine}}},
  tenkz audited label/.style={
    /utils/exec=\tenkz@installlabelaudit},
  tenkz audited label owner/.code={%
    \iftenkz@bboxcapture
      \iftenkz@auditpicture
        \global\expandafter\edef
          \csname tenkz@labelowner@\tenkz@glyphsnaptoken\endcsname{#1}%
      \fi
    \fi},
  tenkz audited glyph/.style 2 args={
    /utils/exec={\tenkz@installglyphaudit{#1}{#2}}},
}
\def\tenkz@installlabelaudit{%
  \tenkz@bboxlabeluse
  \iftenkz@auditpicture
    \global\advance\tenkz@glyphsnapuid by 1\relax
    \edef\tenkz@glyphsnaptoken{\the\tenkz@glyphsnapuid}%
    \edef\tenkz@auditinstallowner{\tenkz@glyphsnaptoken}%
    \ifx\tenkz@armedlabelprovenance\relax\else
      \global\expandafter\let
        \csname tenkz@labelclaimprov@\tenkz@glyphsnaptoken\endcsname
        \tenkz@armedlabelprovenance
      \global\expandafter\let
        \csname tenkz@labelclaimstat@\tenkz@glyphsnaptoken\endcsname
        \tenkz@armedlabelstation
      \global\let\tenkz@armedlabelprovenance\relax
      \global\let\tenkz@armedlabelstation\relax
    \fi
    \ifx\tenkz@armedlabelrole\relax\else
      \global\expandafter\let
        \csname tenkz@labelclaimrole@\tenkz@glyphsnaptoken\endcsname
        \tenkz@armedlabelrole
      \global\let\tenkz@armedlabelrole\relax
    \fi
    \edef\tenkz@installlabelsnapshot{%
      \noexpand\tikzset{%
        execute at end node={%
          \noexpand\tenkz@snapshotglyphstate{\tenkz@glyphsnaptoken}},%
        append after command={\noexpand\pgfextra{%
          \noexpand\tenkz@capturelabelbbox{\tenkz@glyphsnaptoken}}}}}%
    \tenkz@installlabelsnapshot
  \fi}
\def\tenkz@installglyphaudit#1#2{%
  \iftenkz@bboxcapture
    \iftenkz@auditpicture
      \global\advance\tenkz@glyphsnapuid by 1\relax
      \edef\tenkz@glyphsnaptoken{\the\tenkz@glyphsnapuid}%
      \edef\tenkz@auditinstallowner{\tenkz@glyphsnaptoken}%
      \edef\tenkz@installglyphsnapshot{%
        \noexpand\tikzset{%
          execute at end node={%
            \noexpand\tenkz@snapshotglyphstate{\tenkz@glyphsnaptoken}},%
          append after command={\noexpand\pgfextra{%
            \noexpand\tenkz@captureglyphgeometry{#1}{#2}%
              {\tenkz@glyphsnaptoken}}}}}%
      \tenkz@installglyphsnapshot
    \fi
  \fi}

\ExplSyntaxOn

% ---------- shared syntax predicates ----------
% This predicate recognizes a nonempty string of decimal digits.  Callers
% retain their own range checks and diagnostics.
\prg_new_conditional:Npnn \tenkz_token_if_decimal_digits:n #1 { T, F, TF }
  {
    \regex_match:nnTF { \A [0-9]+ \Z } {#1}
      { \prg_return_true: }
      { \prg_return_false: }
  }
\prg_generate_conditional_variant:Nnn \tenkz_token_if_decimal_digits:n
  { V } { T, F, TF }

% ---------- species (the 0.6 hue contract, clause 2) ----------
% Species declare NAMES, never colors: \tndeclare{species}{name}{}
% assigns each new name the next hue of the theme's semantic cycle and
% derives one style per glyph
% family — `species <name> bond', `species <name> tensor', `species
% <name> outline' — through the same indirection as the role styles, so
% a theme rebinding the core hue slots recolours every species at one
% point.  A name keeps its index (hence its hue) across redeclarations,
% so a document-global declaration holds one hue per species over every
% figure of a paper.  An undeclared species at a call site is an error.
% Scope: the index registry is global (a hue, once assigned, is never
% reassigned), but the derived styles are ordinary tikz styles, LOCAL to
% the declaring group -- a picture-scope declaration ends with its
% picture.  The call-site check therefore tests the derived style, not
% the registry, so an out-of-scope species is reported by the curated
% message instead of a raw pgfkeys error; re-declaring the name
% re-derives the styles with the same hue.
\prop_new:N \g__tenkz_species_prop     % name -> 1-based declaration index
\int_new:N  \g__tenkz_species_int
% the semantic cycle: hue slots, in assignment order
\clist_const:Nn \c__tenkz_speccycle_clist
  { tenkzMarked , tenkzAction , tenkzExtra , tenkzOperator }
\msg_new:nnn { tenkz } { unknown-species }
  {
    Undeclared~species~'#1'.~Declare~names~first~--~
    \token_to_str:N \tndeclare{species}{name}{}~(recommended~in~the~
    preamble:~a~species~keeps~one~hue~across~every~figure)~before~the~
    option~list.~A~declaration~inside~a~group~or~picture~ends~with~
    that~group.
  }
\prg_new_protected_conditional:Npnn \tenkz_species_if_declared:n #1
  { T, F, TF }
  {
    \pgfkeysifdefined { /tikz/species~#1~bond/.@cmd }
      { \prg_return_true: }
      { \prg_return_false: }
  }
\cs_new_protected:Npn \tenkz_species_check:n #1
  {
    \tenkz_species_if_declared:nF {#1}
      { \msg_error:nnn { tenkz } { unknown-species } {#1} }
  }
\cs_generate_variant:Nn \tenkz_species_check:n { e, V }
\cs_new_protected:Npn \tenkz_species_one:n #1
  {
    % first declaration fixes the index; a redeclaration re-derives the
    % styles (idempotent) without moving any later species' hue
    \prop_if_in:NnF \g__tenkz_species_prop {#1}
      {
        \int_gincr:N \g__tenkz_species_int
        \prop_gput:Nne \g__tenkz_species_prop {#1}
          { \int_use:N \g__tenkz_species_int }
      }
    \prop_get:NnN \g__tenkz_species_prop {#1} \l_tmpa_tl
    \tl_set:Ne \l_tmpb_tl
      { \clist_item:Nn \c__tenkz_speccycle_clist
          { 1 + \int_mod:nn { \l_tmpa_tl - 1 }
              { \clist_count:N \c__tenkz_speccycle_clist } } }
    \exp_args:NnV \tenkz_species_one_hued:nn {#1} \l_tmpb_tl
  }
% The style family of one species from an explicit hue.  A declared hue is
% authoritative for every record class, so the kernel's declaration door
% mints the tree styles from the same color its own records resolve.
\cs_new_protected:Npn \tenkz_species_one_hued:nn #1#2
  {
    \tl_set:Ne \l_tmpa_tl
      {
        species~#1~bond/.style={bond, draw=#2},
        species~#1~tensor/.style={draw=#2, fill=#2},
        species~#1~tree~junction/.style={tree~junction,
          species~#1~tensor},
        species~#1~outline/.style={draw=#2, text=#2},
        species~#1~ribbon/.style={tree~ribbon, draw=#2,
          fill=#2!12!tenkzPaper},
        species~#1~ribbon~fill/.style={
          draw=#2!12!tenkzPaper,
          fill=#2!12!tenkzPaper}
      }
    \exp_args:NV \tikzset \l_tmpa_tl
  }
\cs_generate_variant:Nn \tenkz_species_one_hued:nn { nV }
% ---------- the cell-set algebra ----------
% One addressing algebra serves the contraction keys: terms `(r,c)` |
% `(r1-r2,c1-c2)`, optionally with a trailing third coordinate, or a
% registered name; terms combine with `+` (union) / `-` (difference),
% left to right.  \tenkz_cs_openscan:n pre-scans a braced option value
% and rewrites its TOP-LEVEL commas to unions (parenthesis depth decides
% which commas separate terms); \tenkz_cs_resolve:nN turns the rewritten
% expression into a membership prop whose keys read "r-c" on the default
% third coordinate and "r-c-h" otherwise.  The third slot means
% INTERFACE in the contraction keys (open=/trace=); each caller sets
% the state below around its resolve.
%
% The machinery lives HERE, in core, under shared single-underscore
% names, outside the grid tier's private namespace.  Caller-set state:
%   \l_tenkz_cs_defsheet_int  default third coordinate of a 2-slot term
%                             (mask to -1 so an explicit third
%                             coordinate never collapses to a bare key)
%   \l_tenkz_cs_sheets_int    stack height priced by the range guard
%   \l_tenkz_cs_guard_bool    range-guard switch; callers whose third
%                             slot is NOT a sheet turn it off and guard
%                             in their own alphabet
%   \l_tenkz_cs_names_prop    registered name -> comma list of keys
\prop_new:N \l_tenkz_cs_result_prop
\prop_new:N \l_tenkz_cs_term_prop
\prop_new:N \l_tenkz_cs_names_prop
\tl_new:N \l_tenkz_cs_expr_tl
\tl_new:N \l_tenkz_cs_acc_tl
\tl_new:N \l_tenkz_cs_op_tl
\tl_new:N \l_tenkz_cs_scan_tl
\tl_new:N \l_tenkz_cs_body_tl
\seq_new:N \l_tenkz_cs_parts_seq
\seq_new:N \l_tenkz_cs_range_parts_seq
\int_new:N \l_tenkz_cs_depth_int
\int_new:N \l_tenkz_cs_rlo_int
\int_new:N \l_tenkz_cs_rhi_int
\int_new:N \l_tenkz_cs_clo_int
\int_new:N \l_tenkz_cs_chi_int
\int_new:N \l_tenkz_cs_hsel_int
\int_new:N \l_tenkz_cs_defsheet_int
\int_new:N \l_tenkz_cs_sheets_int
\bool_new:N \l_tenkz_cs_guard_bool
\bool_new:N \l_tenkz_cs_valid_bool
\bool_set_true:N \l_tenkz_cs_guard_bool
\msg_new:nnn { tenkz } { unknown-name }
  { Unknown~cell-set~name~'#1'~in~a~cell-set~expression. }
\msg_new:nnn { tenkz } { sheet-range }
  { A~cell~addresses~sheet~#1,~but~this~picture~stacks~sheets~0..#2:~
    the~cell~renders~on~no~sheet. }

% option-value pre-scan: top-level commas become unions
\cs_new_protected:Npn \tenkz_cs_openscan:n #1
  {
    \str_case:nnF {#1}
      {
        {(} { \int_incr:N \l_tenkz_cs_depth_int
              \tl_put_right:Nn \l_tenkz_cs_scan_tl {(} }
        {)} { \int_decr:N \l_tenkz_cs_depth_int
              \tl_put_right:Nn \l_tenkz_cs_scan_tl {)} }
      }
      {
        \bool_lazy_and:nnTF
          { \int_compare_p:nNn { \l_tenkz_cs_depth_int } = {0} }
          { \str_if_eq_p:nn {#1} {,} }
          { \tl_put_right:Nn \l_tenkz_cs_scan_tl {+} }
          { \tl_put_right:Nn \l_tenkz_cs_scan_tl {#1} }
      }
  }

% expression -> membership prop
\cs_new_protected:Npn \tenkz_cs_resolve:nN #1#2
  {
    \bool_set_true:N \l_tenkz_cs_valid_bool
    \prop_clear:N \l_tenkz_cs_result_prop
    \tl_set:Nn \l_tenkz_cs_expr_tl {#1}
    \tl_remove_all:Nn \l_tenkz_cs_expr_tl { ~ }
    \int_zero:N \l_tenkz_cs_depth_int
    \tl_clear:N \l_tenkz_cs_acc_tl
    \tl_set:Nn \l_tenkz_cs_op_tl {+}
    \tl_map_inline:Nn \l_tenkz_cs_expr_tl { \tenkz_cs_scan:n {##1} }
    \tenkz_cs_flush:
    \prop_set_eq:NN #2 \l_tenkz_cs_result_prop
  }
\cs_generate_variant:Nn \tenkz_cs_resolve:nN { VN }

\cs_new_protected:Npn \tenkz_cs_scan:n #1
  {
    \str_case:nnF {#1}
      {
        {(} { \int_incr:N \l_tenkz_cs_depth_int
              \tl_put_right:Nn \l_tenkz_cs_acc_tl {(} }
        {)} { \int_decr:N \l_tenkz_cs_depth_int
              \tl_put_right:Nn \l_tenkz_cs_acc_tl {)} }
      }
      {
        \bool_lazy_and:nnTF
          { \int_compare_p:nNn { \l_tenkz_cs_depth_int } = {0} }
          { \bool_lazy_or_p:nn
              { \str_if_eq_p:nn {#1} {+} }
              { \str_if_eq_p:nn {#1} {-} } }
          { \tenkz_cs_flush: \tl_set:Nn \l_tenkz_cs_op_tl {#1} }
          { \tl_put_right:Nn \l_tenkz_cs_acc_tl {#1} }
      }
  }

% resolve the pending term (in \l_tenkz_cs_acc_tl) and combine into result
\cs_new_protected:Npn \tenkz_cs_flush:
  {
    \tl_if_empty:NF \l_tenkz_cs_acc_tl
      {
        \tenkz_cs_term:VN \l_tenkz_cs_acc_tl \l_tenkz_cs_term_prop
        \str_if_eq:VnTF \l_tenkz_cs_op_tl {-}
          { \prop_map_inline:Nn \l_tenkz_cs_term_prop
              { \prop_remove:Nn \l_tenkz_cs_result_prop {##1} } }
          { \prop_map_inline:Nn \l_tenkz_cs_term_prop
              { \prop_put:Nnn \l_tenkz_cs_result_prop {##1} {1} } }
      }
    \tl_clear:N \l_tenkz_cs_acc_tl
  }

% a term -> membership prop
\cs_new_protected:Npn \tenkz_cs_term:nN #1#2
  {
    \prop_clear:N #2
    \tl_if_in:nnTF {#1} {(}
      { \tenkz_cs_rect:nN {#1} #2 }
      {
        \prop_get:NnNTF \l_tenkz_cs_names_prop {#1} \l_tenkz_cs_body_tl
          {
            \clist_map_inline:Vn \l_tenkz_cs_body_tl
              { \prop_put:Nnn #2 {##1} {1} }
          }
          {
            \msg_error:nnn { tenkz } { unknown-name } {#1}
            \bool_set_false:N \l_tenkz_cs_valid_bool
          }
      }
  }
\cs_generate_variant:Nn \tenkz_cs_term:nN { VN }
\cs_generate_variant:Nn \clist_map_inline:nn { Vn }

% normalized cell key: "r-c" on the DEFAULT third coordinate (the
% sheetless format, so single-sheet pictures and their event stream are
% untouched), "r-c-h" otherwise; expandable
\cs_new:Npn \tenkz_cs_cellkey:nnn #1#2#3
  {
    \int_compare:nNnTF {#3} = { \l_tenkz_cs_defsheet_int }
      { #1 - #2 }
      { #1 - #2 - #3 }
  }

% warn when a sheet coordinate falls outside 0 .. sheets-1 (the cell
% would render on no sheet); guarded, not clamped
\cs_new_protected:Npn \tenkz_cs_guard_sheet:n #1
  {
    \bool_if:NT \l_tenkz_cs_guard_bool
      {
        \bool_lazy_and:nnF
          { \int_compare_p:nNn {#1} > {-1} }
          { \int_compare_p:nNn {#1} < { \l_tenkz_cs_sheets_int } }
          {
            \msg_warning:nnee { tenkz } { sheet-range }
              { \int_eval:n {#1} }
              { \int_eval:n { \l_tenkz_cs_sheets_int - 1 } }
            \tenkz@event{warning|picture=\the\tenkz@pictureid|%
              code=sheet-range|sheet=\int_eval:n {#1}}
          }
      }
  }

% (rlo-rhi,clo-chi) or (r,c), optionally with a trailing third
% coordinate -> membership prop; a two-slot term lives on the default
\cs_new_protected:Npn \tenkz_cs_rect:nN #1#2
  {
    \tl_set:Nn \l_tenkz_cs_body_tl {#1}
    \tl_remove_once:Nn \l_tenkz_cs_body_tl {(}
    \tl_remove_once:Nn \l_tenkz_cs_body_tl {)}
    \seq_set_split:NnV \l_tenkz_cs_parts_seq {,} \l_tenkz_cs_body_tl
    \tenkz_cs_range:eNN { \seq_item:Nn \l_tenkz_cs_parts_seq {1} }
      \l_tenkz_cs_rlo_int \l_tenkz_cs_rhi_int
    \bool_if:NT \l_tenkz_cs_valid_bool
      {
        \tenkz_cs_range:eNN { \seq_item:Nn \l_tenkz_cs_parts_seq {2} }
          \l_tenkz_cs_clo_int \l_tenkz_cs_chi_int
        \bool_if:NT \l_tenkz_cs_valid_bool
          {
            \int_compare:nNnTF { \seq_count:N \l_tenkz_cs_parts_seq } > {2}
              {
                \int_set:Nn \l_tenkz_cs_hsel_int
                  { \seq_item:Nn \l_tenkz_cs_parts_seq {3} }
                \tenkz_cs_guard_sheet:n { \l_tenkz_cs_hsel_int }
              }
              { \int_set_eq:NN \l_tenkz_cs_hsel_int \l_tenkz_cs_defsheet_int }
            \int_step_inline:nnn { \l_tenkz_cs_rlo_int } { \l_tenkz_cs_rhi_int }
              {
                \int_step_inline:nnn { \l_tenkz_cs_clo_int } { \l_tenkz_cs_chi_int }
                  {
                    \prop_put:Nen #2
                      { \tenkz_cs_cellkey:nnn {##1} {####1}
                          { \int_use:N \l_tenkz_cs_hsel_int } } {1}
                  }
              }
          }
      }
  }
\cs_generate_variant:Nn \prop_put:Nnn { Nen }
\cs_generate_variant:Nn \seq_set_split:Nnn { NnV }

% "a" or a rising "a-b" -> lo, hi.  A hyphen is range syntax here, so
% it must have exactly two nonblank operands; it is never a loose integer
% expression whose tail can quietly turn a bad selector into an empty one.
\cs_new_protected:Npn \tenkz_cs_range:nNN #1#2#3
  {
    \tl_if_in:nnTF {#1} {-}
      {
        \seq_set_split:Nnn \l_tenkz_cs_range_parts_seq {-} {#1}
        \int_compare:nNnTF { \seq_count:N \l_tenkz_cs_range_parts_seq } = {2}
          {
            \tl_set:Ne \l_tmpa_tl
              { \seq_item:Nn \l_tenkz_cs_range_parts_seq {1} }
            \tl_set:Ne \l_tmpb_tl
              { \seq_item:Nn \l_tenkz_cs_range_parts_seq {2} }
            \bool_lazy_or:nnTF
              { \tl_if_blank_p:V \l_tmpa_tl }
              { \tl_if_blank_p:V \l_tmpb_tl }
              { \bool_set_false:N \l_tenkz_cs_valid_bool }
              {
                \int_set:Nn #2 { \l_tmpa_tl }
                \int_set:Nn #3 { \l_tmpb_tl }
                \int_compare:nNnT {#2} > {#3}
                  { \bool_set_false:N \l_tenkz_cs_valid_bool }
              }
          }
          { \bool_set_false:N \l_tenkz_cs_valid_bool }
      }
      { \int_set:Nn #2 {#1} \int_set:Nn #3 {#1} }
  }
\cs_generate_variant:Nn \tenkz_cs_range:nNN { eNN }
\ExplSyntaxOff

\endinput
