%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
%   This is 'catoptions' package, version 0.2.7i, 2023/10/29.             %
%                                                                         %
%   The catoptions package changes LaTeX package loading internals        %
%   so that all subsequently loaded packages can rely on having           %
%   normal catcodes in effect. The package also contains some useful      %
%   facilities unconnected with catcodes. In particular, it contains      %
%   options processing facilities that have the familiar and simple       %
%   syntax of LaTeX's legacy options parsing mechanism, but with          %
%   improved robustness in terms of option value default, preservation    %
%   of braces in option values, and parsing of expandable package         %
%   and class option values. Also, the package contains some API.         %
%                                                                         %
%   The catcode facilities of the package are an extension of the         %
%   'pcatcode' package by Michael J. Downes and David M. Jones.           %
%                                                                         %
%   This package and accompanying files may be distributed and/or         %
%   modified under the conditions of the LaTeX Project Public License,    %
%   either version 1.3 of this license or any later version.              %
%                                                                         %
%   The LPPL maintenance status of this software is 'author-maintained'.  %
%                                                                         %
%   Copyright (c) 2010-2012 Ahmed Musa (amusa22@gmail.com).               %
%   Copyright (c) 2023      Ahmed Musa (amusa22@gmail.com), David Carlisle%
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%

\begingroup
\chardef\%\catcode37\catcode37 14\relax\expandafter\iffalse\string\
\fi\let\e\endlinechar\chardef\E\e\e13\chardef\n\catcode\e\catcode\e5%
\chardef\s\catcode32 \catcode32\string=10
\chardef\=\catcode61 \catcode61\string=12
\chardef\l=\catcode123 \catcode123=1
\chardef\r=\catcode125 \catcode125=2
\chardef\[=\catcode91 \catcode91=12
\chardef\]=\catcode93 \catcode93=12
\chardef\^=\catcode94 \catcode94=7
\chardef\.=\catcode46 \catcode46=12
\chardef\/=\catcode47 \catcode47=12
\chardef\~=\catcode126 \catcode126=13
\chardef\&=\catcode38 \catcode38=4
\chardef\$=\catcode36 \catcode36=3
\chardef\_=\catcode95 \catcode95=8
\chardef\+=\catcode43 \catcode43=12
\chardef\!=\catcode33 \catcode33=12
\chardef\'=\catcode39 \catcode39=12
\chardef\(=\catcode40 \catcode40=12
\chardef\)=\catcode41 \catcode41=12
\chardef\*=\catcode42 \catcode42=12
\chardef\,=\catcode44 \catcode44=12
\chardef\-=\catcode45 \catcode45=12
\chardef\:=\catcode58 \catcode58=12
\chardef\<=\catcode60 \catcode60=12
\chardef\>=\catcode62 \catcode62=12
\chardef\`=\catcode96 \catcode96=12
\edef\x{%
  \endgroup
  \def\noexpand\cptrestorecatcodes{%
    \endlinechar=\number\E \catcode\number\e=\number\n
    \catcode32=\number\s \catcode123=\number\l
    \catcode125=\number\r \catcode37=\number\%
    \catcode61=\number\= \catcode91=\number\[
    \catcode93=\number\] \catcode94=\number\^
    \catcode46=\number\. \catcode47=\number\/
    \catcode126=\number\~ \catcode38=\number\&
    \catcode36=\number\$ \catcode95=\number\_
    \catcode43=\number\+ \catcode33=\number\!
    \catcode39=\number\' \catcode40=\number\(
    \catcode41=\number\) \catcode42=\number\*
    \catcode44=\number\, \catcode45=\number\-
    \catcode58=\number\: \catcode60=\number\<
    \catcode62=\number\> \catcode96=\number\`
  }%
}
\x
\catcode37 14\relax\expandafter\iffalse\string\
\fi\endlinechar13\catcode13 5%
\catcode61\string=12
\catcode32=10
\catcode123=1
\catcode125=2
\catcode91=12
\catcode93=12
\catcode46=12
\catcode47=12
\catcode94=7
\catcode126=13

\AtEndOfPackage{%
  \newletcsset{%
    \csvloop=\csv@@loop,
    \csvparse=\csv@@parse,
    \kvloop=\kv@@loop,
    \kvparse=\kv@@parse,
    \kvprocess=\kv@@process,
    \tsvloop=\tsv@@loop,
    \tsvparse=\tsv@@parse,
    \sisoloop=\siso@@loop,
    \dofunclist=\cptdofunclist,
    \docommalist=\cptdocommalist,
    \dosisolist=\cptdosisolist,
    \newvariables=\cptnewvariables,
    \stripallouterbraces=\cptstripallouterbraces,
    \stripouterbraces=\cptstripNouterbraces,
    \stripallouterbracesincs=\cptstripallouterbracesincs,
    \gobble@to@relax=\cptgobbletorelax,
    \cpt@gobbletorelax=\cptgobbletorelax,
    \cpt@gobbletorelax@fi@endgroup=\cptbgobbletorelax,
    \ifcasse=\cptifcasse,
    \docasse=\cptdocasse,
    \csvnormalize=\csv@@normalize,
    \kvnormalize=\kv@@normalize
  }%
}
\edef\cpt@hashchar{\string#}
\begingroup
\catcode`#=13
\gdef\cpt@activehash{#}
\endgroup
\m@ne=-1 \z@=0pt \p@=1pt
\@ifdefinable\m@one{\newcount\m@one\m@one\m@ne}
\@ifdefinable\z@pt{\newdimen\z@pt\z@pt\z@}
\chardef\active=13
\NeedsTeXFormat{LaTeX2e}[2011/06/27]
%% DPC
\ProvidesPackage{catoptions}
  [2023/10/29 v0.2.7i Securing catcodes and parsing options (AM)]
%% END CHANGE
\ifcase%
  \ifx\eTeXversion\cpt@undefined\z@pt\else
    \ifnum\eTeXversion<\tw@\z@pt\else\@ne\fi\fi
  \PackageError{catoptions}{eTeX not loaded or old version}
    {This package requires eTeX version 2 or higher.}%
  \expandafter\endinput
\fi
%% DPC
%%% New latex option handler is definined
\ifx\ProcessKeyOptions\@undefined\else
\PackageWarningNoLine{catoptions}
   {\MessageBreak catoptions modifies package option handling and is%
    \MessageBreak incompatible with many other packages.%
    \MessageBreak For new documents it is recommended to use%
    \MessageBreak The built in option processor:%
    \MessageBreak \string\ProcessKeyOptions, see clsguide}
\fi
%% END CHANGE
\protected\def\cptloggingall{%
  \tracinggroups\@ne\tracingifs\@ne\tracingall\tracingassigns\@ne
}
\let\cpttracingall\cptloggingall
% \ifcsdefinable, \cpt@starorlong, \cpt@testopt, \cptcommanormalize, etc,
% change later on:
\@ifdefinable\ifcsdefinable{\let\ifcsdefinable\@ifdefinable}
\@ifdefinable\cptnewlet\relax
% Don't put '=' after \let#1, in case the caller uses '=':
\protected\def\cptnewlet#1{\ifcsdefinable#1\relax\let#1}
\cptnewlet\cpt@nil\relax
\newcommand*\cpt@nnil{\cpt@nil}
\let\@iden\@firstofone
\def\cptiofii#1#2{#1}
\def\cptiiofii#1#2{#2}
\@ifdefinable\ifforbreak{\newif\ifforbreak}
\cptnewlet\cpt@starorlong\@star@or@long
\cptnewlet\cpt@testopt\@testopt
\cptnewlet\cptcommanormalize\unexpanded
\protected\def\ifnotnilTF#1#2{%
  \begingroup
  \edef\reserved@a{\cpttrimspace{#1}}%
  \def\reserved@b{#2}%
  \expandafter\endgroup
  \ifx\reserved@a\reserved@b\expandafter\@gobble
    \else\expandafter\@iden\fi
}
\newcommand*\defifxTF[2]{%
  \begingroup
  \edef\reserved@a{\cpttrimspace{#1}}%
  \expandafter\endgroup\ifx#2\reserved@a
  \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
}
\newcommand*\cpt@for@nil{\cpt@for@nil}
% Simple, 1-dimensional comma loop. \forbreak can be used to break
% out of the loop. \do may appear in #1; so we can't use \do as the delimiter:
\protected\def\cptfor#1\dofor#2{%
  \def\cpt@fordo##1,{\cpt@for@a,\cpt@fordo{##1}{#2}}%
  \edef\reserved@a{\cptcommanormalize{#1}}%
  \forbreakfalse
  \expandafter\cpt@fordo\reserved@a,\cpt@for@nil,%
}
% Simple, 1-dimensional tsv loop:
\protected\def\cpttfor#1\dofor#2{%
  \def\cpt@tfordo##1{\cpt@for@a{}\cpt@tfordo{##1}{#2}}%
  \forbreakfalse\cpt@tfordo#1\cpt@for@nil
}
\protected\def\cpt@for@a#1#2#3#4{%
  \edef\reserved@a{\unexpanded{#3}}%
  \ifx\reserved@a\cpt@for@nil\expandafter\@gobble\else
  \expandafter\@iden\fi{%
    \ifforbreak\expandafter\cptiofii\else\expandafter\cptiiofii\fi
    {\def\reserved@a##1\cpt@for@nil#1{}\reserved@a}{#4#2}%
  }%
}
% \foreachmeer{<list>}<processor>
% Expandable comma loop. The \noexpand before #1 is required when #1
% begins with a command. <processor> must be pre-defined by the user:
\newcommand*\foreachmeer[2]{%
  \expandafter\cpt@foreachmeer@a\romannumeral
  -`\q\cptcommanormalize{\noexpand#1},\cpt@nnil,\meer@nil{#2}%
}
\def\cpt@foreachmeer@a#1,#2\meer@nil#3{%
  \expandafter\ifx\cpt@car#1\car@nil\cpt@nnil
  \expandafter\cptiofii\else\expandafter\cptiiofii\fi
  {}{#3{#1}\cpt@foreachmeer@a#2\meer@nil{#3}}%
}
% Unique \chardef'd token:
\ifcsdefinable\cptchardef{%
  \protected\def\cptchardef#1#2 {%
    \ifcsdefinable#1{%
      \def\reserved@a##1=##2\@nil{##2 }%
      \chardef#1\reserved@a=#2\@nil
    }%
  }%
}
\newcommand\cptswap[2]{#2#1}
\newcommand\cptswapbracefirst[2]{#2{#1}}
\newcommand\cptswapbracesecond[2]{{#2}#1}
\newcommand\cptswapbraceboth[2]{{#2}{#1}}
\cptswap{ }{\let\cptsptoken= }
\def\@space{ }
\@namedef{cptgobblespace} {}
\@ifdefinable\@gobblespace{\let\@gobblespace\cptgobblespace}
% \cptnewbools[<pref>]{a,b}
\newcommand*\cptnewbools[2][]{%
  \cptfor#2\dofor{%
    \expandafter\ifcsdefinable\csname if#1##1\endcsname
    {\expandafter\newif\csname if#1##1\endcsname}%
  }%
}
\cptnewbools[cpt@]{st,pl,pm,cl,verbose}
% \cptnewcounts[<pref>]{a,b}
\newcommand*\cptnewcounts[2][]{%
  \cptfor#2\dofor{%
    \expandafter\ifcsdefinable\csname#1##1\endcsname
    {\expandafter\newcount\csname#1##1\endcsname}%
  }%
}
% \cptnewcounters[<pref>]{a,b}[<master>]
\newcommand*\cptnewcounters{\cpt@testopt\cpt@newcounters{}}
\def\cpt@newcounters[#1]#2{%
  \cpt@testopt{\cpt@newc@unters{#1}{#2}}{}%
}
\def\cpt@newc@unters#1#2[#3]{%
  \cptfor#2\dofor{%
    \ifcat&\detokenize{#3}&\relax
      \newcounter{#1##1}%
    \else
      \newcounter{#1##1}[#3]%
    \fi
  }%
}
\newcommand*\cptnewdimens[2][]{%
  \cptfor#2\dofor{%
    \expandafter\ifcsdefinable\csname#1##1\endcsname
    {\expandafter\newdimen\csname#1##1\endcsname}%
  }%
}
\newcommand*\cpt@quark{\@gobble\cpt@quark}
\newcommand\ifxTF[2]{%
  \ifblankTF{#1}{%
    \ifblankTF{#2}\cptiofii\cptiiofii
  }{%
    \ifblankTF{#2}\cptiiofii{%
      \expandafter\ifblankTF\expandafter{\@gobble#1}{%
        \expandafter\ifblankTF\expandafter{\@gobble#2}{%
          \ifx#1#2\expandafter\cptiofii\else\expandafter\cptiiofii\fi
        }{%
          \cpt@notonetokenerr{#2}%
        }%
      }{%
        \cpt@notonetokenerr{#1}%
      }%
    }%
  }%
}
\newcommand\ifxFT[2]{\ifxTF{#1}{#2}\cptiiofii\cptiofii}
\def\cpt@ifcseq@#1#2\cpt@ifcseq@nil{\expandafter#1}
\newcommand\ifcseqTF[2]{%
  \csname @\expandafter\expandafter\expandafter
  \ifx\cpt@ifcseq@#1\batchmode\cpt@ifcseq@nil\cpt@car#2\noboundary\car@nil
  first\else second\fi oftwo\endcsname
}
\newcommand\ifcseqFT[2]{\ifcseqTF{#1}{#2}\cptiiofii\cptiofii}
\newcommand*\ifxcseqTF[2]{%
  \ifcseqTF{#1}{#2}{%
    \cptiofii
  }{%
    \expandafter\cptswapbracefirst\expandafter{#1}%
    {\expandafter\ifstrcmpTF\expandafter{#2}}%
    \cptiofii\cptiiofii
  }%
}
\newcommand\ifnullTF[1]{%
  \ifcat$\detokenize{#1}$\expandafter\@firstoftwo
    \else\expandafter\@secondoftwo\fi
}
\newcommand\ifnullFT[1]{\ifnullTF{#1}\cptiiofii\cptiofii}
\newcommand\ifblankTF[1]{%
  \expandafter\ifnullTF\expandafter{\@gobble#1.}%
}
\newcommand\ifblankFT[1]{\ifblankTF{#1}\cptiiofii\cptiofii}
\let\then\iffalse
\let\dolacus\iffalse
\@ifdefinable\iflacus\relax
\long\def\iflacus#1\dolacus{%
  \ifcat$\detokenize\expandafter{\@gobble#1.}$%
}
\newcommand\ifbracedTF[3]{%
  \romannumeral\expandafter\@secondoftwo\expandafter{\expandafter
  {\string#1.}\expandafter\cptiofii\expandafter{\iffalse}\fi
  0 #2}{0 #3}%
}
\newcommand\ifbracedFT[1]{\ifbracedTF{#1}\cptiiofii\cptiofii}
\newcommand\ifleadspaceTF[3]{%
  \romannumeral\csname
  @\ifnullTF{#1}{second}{\iffalse{\fi\cpt@ifleadspace.#1 }}%
  oftwo\endcsname{0 #2}{0 #3}%
}
\long\def\cpt@ifleadspace#1 {%
  \expandafter\ifnullTF\expandafter{\@gobble#1}{first}{second}%
  \expandafter\@gobble\expandafter{\iffalse}\fi
}
\newcommand\iftrailspaceTF[1]{%
  \romannumeral-`\q
  \csname @\expandafter\@firstofone\expandafter{%
    \romannumeral\expandafter
    \cpt@iftrailspace\expandafter{\cpt@removetospace.#1 }%
  }%
}
\newcommand\cpt@iftrailspace[1]{%
  \ifnullTF{#1}{%
    \expandafter\cptiiofii\cptiofii
  }{%
    \ifleadspaceTF{#1}{%
      \expandafter\ifnullTF\expandafter{\@gobblespace#1}{%
        \expandafter\@firstoftwo\@firstoftwo
      }{%
        \@secondoftwo
      }%
    }{%
      \@secondoftwo
    }%
  }{%
    {0 first}{0 second}oftwo\endcsname
  }{%
    \expandafter\cpt@iftrailspace\expandafter{\cpt@removetospace.#1}%
  }%
}

\ifxTF\pdfstrcmp\cpt@undefined{%
  \RequirePackage{pdftexcmds}%
  \ifxTF\pdf@strcmp\cpt@undefined{%
    \cpt@err{Neither \string\pdfstrcmp nor \string\pdf@strcmp exists}\@ehc
  }{%
    \let\cpt@pdfstrcmp\pdf@strcmp
  }%
}{%
  \let\cpt@pdfstrcmp\pdfstrcmp
}
\long\def\cptifstreq#1#2\then{%
  \ifnum\cpt@pdfstrcmp{\detokenize{#1}}{\detokenize{#2}}=\z@pt
}
\newcommand\ifstrcmpTF[2]{%
  \usename{@\ifnum\cpt@pdfstrcmp{\detokenize{#1}}%
    {\detokenize{#2}}=0first\else second\fi oftwo}%
}
\newcommand\ifstrcmpFT[2]{\ifstrcmpTF{#1}{#2}\cptiiofii\cptiofii}
\newcommand*\cpt@def@[3]{%
  \ifcsdefinable#3\relax
  \ifcat$\detokenize{#2}$\else\protected\fi
  \l@ngrel@x\csname#1def\endcsname#3%
}
\ifcsdefinable\robust@def{%
  \protected\def\robust@def{\cpt@starorlong{\cpt@def@{}{p}}}%
}
\robust@def*\new@def{\cpt@starorlong{\cpt@def@{}{}}}
\robust@def*\new@gdef{\cpt@starorlong{\cpt@def@{g}{}}}
\robust@def*\robust@gdef{\cpt@starorlong{\cpt@def@{g}{p}}}
\robust@def*\new@edef{\cpt@starorlong{\cpt@def@{e}{}}}
\robust@def*\robust@edef{\cpt@starorlong{\cpt@def@{e}{p}}}
\robust@def*\new@xdef{\cpt@starorlong{\cpt@def@{x}{}}}
\robust@def*\robust@xdef{\cpt@starorlong{\cpt@def@{x}{p}}}
\robust@def*\renew@def{\cpt@starorlong{\cpt@redef@{}}}
\robust@def*\robust@redef{\cpt@starorlong{\cpt@redef@{p}}}
\robust@def*\cpt@redef@#1#2{%
  \@ifundefined{\expandafter\@gobble\string#2}{}{%
    \ifcpt@verbose
      \@latex@info{Command '\string#2' redefined}%
    \fi
  }%
  \ifcat$\detokenize{#1}$\else\protected\fi
  \l@ngrel@x\def#2%
}
\new@def*\cpt@checkoptprefix{\@iden}
\robust@def*\provide@def{%
  \cpt@testst{\cpt@testcl{\cpt@providedef\relax}}%
}
\robust@def*\providerobust@def{%
  \cpt@testst{\cpt@testcl{\cpt@providedef\protected}}%
}
\robust@def*\cpt@providedef#1#2{%
  \ifescapedTF{#2}{}{\cpt@notescapederr{#2}}%
  \ifdefTF#2{%
    \ifcpt@verbose
      \cpt@info{Command '\string#2' already defined:
        \MsgBrk not redefined}%
    \fi
    \def\reserved@a{\undefcs\reserved@b}%
  }{%
    \def\reserved@a{%
      \ifcpt@cl\global\fi\let#2\reserved@b
      \undefcs\reserved@b
    }%
  }%
  \afterassignment\reserved@a
  \ifcpt@st\else\long\fi
  #1\def\reserved@b
}
\new@def*\MsgBrk{\MessageBreak}
\new@def*\commentBegin{%
  \begingroup
  \catcode`\{=12
  \catcode`\}=12
  \catcode`\#=12
  \cpt@commentblock
}
\new@def\cpt@commentblock#1\commentEnd{\endgroup}
\robust@def*\cptnormalcatcodes{%
  \endlinechar13
  \catcode33=12\catcode34=12\catcode35=6\catcode36=3\catcode37=14
  \catcode38=4\catcode39=12\catcode40=12\catcode41=12\catcode42=12
  \catcode43=12\catcode44=12\catcode45=12\catcode46=12\catcode47=12
  \catcode58=12\catcode59=12\catcode60=12\catcode61=12\catcode62=12
  \catcode63=12\catcode91=12\catcode92=0\catcode93=12\catcode94=7
  \catcode95=8\catcode96=12\catcode123=1\catcode124=12\catcode125=2
  \catcode126=13\catcode32=10\catcode13=5\catcode9=10\catcode10=12
}

\begingroup
\let\s\string
\escapechar\m@one
\new@xdef*\cpt@oth@rchars{%
  \s\!\s\"\s\$\s\&\s\'\s\(\s\)\s\*\s+\s\,\s\-\s\.\s\/\s\:%
  \s\;\s\<\s\=\s\>\s\?\s\[\s\]\s\^\s\_\s\`\s\|\s\~%
  %% left out: \s\\\s\%\s\{\s\}\s\#
}
\new@xdef*\cpt@otherchars{%
  \cpt@oth@rchars\s\\\s\%\s\{\s\}\s\#%
}
\endgroup

\new@def*\cpt@spcatcodestack{}
\robust@def*\cpt@sppushcatcodes{%
  \edef\cpt@spcatcodestack{%
    \catcode\number`\ =\the\catcode`\ %
    \catcode\number`\^^I=\the\catcode`\^^I
    \catcode\number\endlinechar=\the\catcode`\
    \endlinechar=\the\endlinechar
    {\cpt@spcatcodestack}%
  }%
}
\robust@def*\BeginOverlookWhiteSpace{%
  \cptpushnumber\cpt@overlooknr
  \ifnum\cpt@overlooknr>\@ne
    \cpt@err{There is an unclosed
      \string\BeginOverlookWhiteSpace}\@ehc
  \fi
  \cpt@sppushcatcodes
  \catcode`\ =9\relax
  \catcode`\^^I=9\relax
  \endlinechar\m@one
}
\robust@def*\EndOverlookWhiteSpace{%
  \def\reserved@a##1##{##1\xdef\cpt@spcatcodestack}%
  \expandafter\reserved@a\cpt@spcatcodestack
  \undefcs\cpt@overlooknr
}
\robust@def*\BeginOverlookEndline{%
  \cptpushnumber\cpt@overlookendlinenr
  \ifnum\cpt@overlookendlinenr>\@ne
    \cpt@err{There is an unclosed
      \string\BeginOverlookEndline}\@ehc
  \fi
  \cptchardef\cpt@savendlinechar=\number\endlinechar
  \endlinechar\m@one
}
\robust@def*\EndOverlookEndline{%
  \endlinechar\cpt@savendlinechar
  \undefcs\cpt@overlookendlinenr
}
\new@def*\cpt@catcodestack{}
\robust@def*\cptpushcatcodes{%
  \begingroup
  \def\x##1{%
    \ifx##1\@nnil\else
      \catcode\number`##1=\the\catcode`##1\relax
      \expandafter\x
    \fi
  }%
  \xdef\cpt@catcodestack{%
    \expandafter\x\cpt@otherchars\ \
    \^^I\^^J\@nnil{\cpt@catcodestack}%
  }%
  \endgroup
}
\cptpushcatcodes
\cptnormalcatcodes
\robust@def*\cptpopcatcodes{%
  \begingroup
  \def\x##1##{\endgroup##1\xdef\cpt@catcodestack}%
  \expandafter\x\cpt@catcodestack
}
\@ifdefinable\currentcatcodesubset\relax
\robust@def*\GetCurrentCatcodeSubset{%
  \begingroup
  \def\x##1{%
    \ifx##1\@nnil\else
      \@space(\string##1\@firstofone{:\number\catcode`##1})%
      \expandafter\x
    \fi
  }%
  \edef\x{%
    \def\noexpand\currentcatcodesubset{%
      \x\^^I\^^J\^^L\^^M\ \!\"\#\$\%\&%
      \'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\}\|\~\@nnil
    }%
  }%
  \expandafter\endgroup\x
}
\new@def*\cpt@lq{`}
\robust@def*\cpt@setupsafeactivesedef{%
  \let\cpt@setupsafeactivesedef\relax
  \begingroup
  \cpttfor!"$&'()*+,-./:;<=>?[]^_`|~\dofor{%
    \catcode\cpt@lq##1\string=\active
  }%
  \everyeof{\noexpand}%
  \xdef\cpt@safeactives{\unexpanded\expandafter{\cpt@activehash}%
    \scantokens{\unexpanded{!"$&'()*+,-./:;<=>?[]^_`|~}}}%
  \gdef\cptsafeactivesedef##1##2{%
    \begingroup
    \expandafter\cpttfor\cpt@safeactives\dofor{%
      \ifnum\catcode\cpt@lq####1\string=\active
        \edef####1{\string####1}%
      \fi
    }%
    \cptexpandsecond\endgroup
      {\edef\noexpand##1{\noexpand\unexpanded{##2}}}%
  }%
  \endgroup
}
\newcommand*\neededfutureletchars{}
\newcommand*\declarefutureletset[2][fl@]{%
  \xdef\cpt@fletprefix{\cpttrimspaces{#1}}%
  \cptexpandargonce{\cptfiltermergecsv[,]\cpt@fletprefixes}
    \cpt@fletprefix\nofilter
  \ifblankTF{#2}{%
    \def\neededfutureletchars{}%
  }{%
    \def\neededfutureletchars{#2}%
    \cpt@sttrue\cpt@csvnormalize[,]\neededfutureletchars
    \oifstrcmpFT\neededfutureletchars{all}{}{%
      \def\neededfutureletchars{}%
      \def\cpt@tempa##1\@##2\@{%
        \ifx##1\end\else
          \cptguaddtolist\neededfutureletchars{##1}%
          \expandafter\cpt@tempa
        \fi
      }%
      \expandafter\cpt@tempa\cpt@futureletchars\end\@\@
    }%
  }%
  \globalize\neededfutureletchars
  \globalize\cpt@fletprefixes
}

\begingroup
\cptrestorecatcodes
\begingroup
\catcode`\3="3 \catcode`\4="4 \catcode`\7="7 \catcode`\8="8
\catcode`\A="A \catcode`\B="B \catcode`\C="C \catcode`\D="D
\robust@gdef*\cpt@flet@a#1#2{%
  \begingroup
  \edef\cpt@tempa{\noexpandcsn{\cpt@fletprefix#1}}%
  \edef\cpt@tempb{\noexpandcsn{if\cpt@fletprefix#1}}%
  \oifinset@sp@TF,\cpt@tempa\cptfutureletmacros{}{%
    \xdef\cptfutureletmacros{%
      \ifcsnullTF\cptfutureletmacros{}%
        {\expandcsonce\cptfutureletmacros,}%
      \expandcsonce\cpt@tempa,\expandcsonce\cpt@tempb
    }%
  }%
  \def\siso@do##1{\lccode`##1=`#2}%
  \siso@@loop{034678BCD}%
  \ifnum\catcode`#2=\active
    \def\do##1{\noexpand\do\noexpand##1\noexpand}%
    \lowercase{%
      \xdef\cpt@activecharacters{%
        \cpt@activecharacters
        \do#2D%
      }%
    }%
  \fi
  \xdef\cpt@tempa{%
    \let\noexpand\cpt@tempa\noexpand\cpt@undefined
    \gletcs\expandcsonce\cpt@tempa= %
  }%
  \aftergroup\cpt@tempa
  \lowercase{%
    \expandafter\endgroup
    \ifcase\numexpr\catcode`#2\relax
      0\or \bgroup\or \egroup\or 3\or 4\or 5\or 6\or 7\or
      8\or 9\or \@sptoken\or B\or C\else D\fi
  }%
}
\endgroup
\robust@gdef*\cpt@futureletchars{%
  space\@\ \@ exclam\@\!\@ dblquote\@\"\@ hash\@\#\@ dollar\@\$\@
  ampersand\@\&\@ rquote\@\'\@ lparen\@\(\@ rparen\@\)\@ star\@\*\@
  plus\@\+\@ comma\@\,\@ hyphen\@\-\@ period\@\.\@ slash\@\/\@
  colon\@\:\@ semicolon\@\;\@ less\@\<\@ equal\@\=\@ greater\@\>\@
  question\@\?\@ lbracket\@\[\@ rbracket\@\]\@ hat\@\^\@
  underscore\@\_\@ lquote\@\`\@ lbrace\@\{\@ vert\@\|\@ rbrace\@\}\@
  tilde\@\~\@ bslash\@\\\@
}
\robust@gdef*\cptfutureletsetup{%
  \gdef\cpt@activecharacters{}%
  \gdef\cptfutureletmacros{}%
  \def\cpt@flet@b##1\@##2\@{%
    \expandafter\ifxTF\cpt@car##1\car@nil\end{}{%
      \oifinset@sp@FT,{##1}\neededfutureletchars{}{%
        \cpt@flet@a{##1}{##2}%
      }%
      \cpt@flet@b
    }%
  }%
  \def\csv@do##1{%
    \gundefcsn{##1\curropt}%
    \gundefcsn{if##1\curropt}%
  }%
  \def\cpt@fletundef##1\@##2\@{%
    \ifxTF##1\end{}{%
      \def\curropt{##1}%
      \csv@@parse*[,]\cpt@fletprefixes
      \cpt@fletundef
    }%
  }%
  \def\cpt@fletdef##1\@##2\@{%
    \expandafter\ifxTF\cpt@car##1\car@nil\end{}{%
      \oifinset@sp@FT,{##1}\neededfutureletchars{}{%
        \csn@xdef{if\cpt@fletprefix##1}####1{%
          \noexpand\usename{@\noexpand\ifx
            \noexpandcsn{\cpt@fletprefix##1}%
            ####1\unexpanded{\@empty first\else second\fi oftwo}%
          }%
        }%
      }%
      \cpt@fletdef
    }%
  }%
  \expandafter\cpt@fletundef\cpt@futureletchars\end\@\@
  \expandafter\cpt@fletdef\cpt@futureletchars\end\@\@
  \expandafter\cpt@flet@b\cpt@futureletchars\end\@\@
}

% We can't use \AtBeginDocument here in place of \BeforeStartOfDocument.
% See <http://tex.stackexchange.com/questions/146391/catoptions
% -destroys-french-active-characters-and>.
\AtEndOfPackage{\BeforeStartOfDocument{\cptrestorecatcodes}}

\robust@gdef*\futureletresetactives{%
  \begingroup
  \defpass\cpt@tempa##1{\endgroup
    \def\do####1####2{\let####1=##1####2}%
  }{ }%
  \cpt@activecharacters
  \let\do\relax
}
\endgroup

\robust@def*\UseNormalCatcodes{%
  \ifdocstartedTF{%
    \cpt@err
      {\noexpand\UseNormalCatcodes is a preamble command}
      {Preamble command in document body.}%
  }{}%
  \RecoverAtRequirePackage\UseNormalCatcodes
  \let\UseNormalCatcodes\relax
  \cptpushcatcodes
  \cptnormalcatcodes
  \ifcseqTF\@currname\@empty{%
    \BeforeStartOfDocument{\cptpopcatcodes}%
  }{%
    \AfterEndOfStyleFile{\cptpopcatcodes}%
  }%
}
\new@def*\cptgetcatcode#1{%
  \number
  \ifcat\noexpand#1\bgroup1\else
  \ifcat\noexpand#1\egroup2\else
  \ifcat\noexpand#1$3\else %$
  \ifcat\noexpand#1&4\else
  \ifcat\noexpand#1##6\else
  \ifcat\noexpand#1^7\else
  \ifcat\noexpand#1_8\else
  \ifcat\noexpand#1\@sptoken10\else
  \ifcat\noexpand#1a11\else
  \ifcat\noexpand#1!12\else
  \ifcat\noexpand#1\noexpand~13\else
  -1\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
}

\robust@def\cpt@ifnextchar#1#2#3{%
  \begingroup
  \let\reserved@a=#1%
  \toks@{\endgroup#2}%
  \toks1{\endgroup#3}%
  \global\futurelet\@let@token\cpt@ifnext
}
\robust@def*\cpt@ifnext{%
  \ifx\@let@token\@sptoken
    \toks2{\cpt@ifn@xt}%
  \else
    \ifx\@let@token\reserved@a
      \toks2\expandafter{\the\toks@}%
    \else
      \toks2\expandafter{\the\toks1}%
    \fi
  \fi
  \the\toks2
}
\@namedef{cpt@ifn@xt} {\global\futurelet\@let@token\cpt@ifnext}
\newcommand\ifnextcharTF[3]{%
  \begingroup
  \cpt@ifnextchar\relax
    {\cpt@ifnextcharacter{#1}{#2}{#3}}%
    {\cpt@ifnextcharacter{#1}{#2}{#3}}%
}
\new@def\cpt@ifnextcharacter#1#2#3{%
  \ifcase
     \ifcat\noexpand\@let@token\bgroup 1\fi
     \ifcat\noexpand\@let@token\egroup 1\fi
     0\let\next\cpt@ifn@xtcharacter
  \else
     \def\next{\endgroup\cpt@ifnextchar}%
  \fi
  \next{#1}{#2}{#3}%
}
\new@def\cpt@ifn@xtcharacter#1#2#3#4{%
  \escapechar92\relax
  \edef\x{\cpt@ifn@xtch@racter{#1}\cpt@ifn@xtch@racter{#4}}%
  \expandafter\endgroup\csname @\expandafter
    \ifx\x first\else second\fi oftwo\endcsname
  {#2}{#3}#4%
}
% Must be expandable:
\new@def\cpt@ifn@xtch@racter#1{%
  \expandafter\cpt@ifn@xtch@r@cter\string#1\relax\noboundary{#1}%
}
\new@def\cpt@ifn@xtch@r@cter#1#2\noboundary#3{%
  \ifx\relax#2#1\else\noexpand#3\fi
}
\robust@redef\cpt@ifstar#1{\ifnextcharTF*{\@firstoftwo{#1}}}
\robust@redef*\cpt@starorlong#1{%
  \cpt@ifstar{\let\l@ngrel@x\relax#1}{\let\l@ngrel@x\long#1}%
}
\new@def*\ifsecondisnnilTF#1{%
  \expandafter\expandafter\expandafter\cpt@ifsecondisnnil
  \expandafter\string\noexpand#1\cpt@nnil\cpt@nil
}
\new@def*\cpt@ifsecondisnnil#1#2\cpt@nil{%
  \expandafter\ifcseqTF\cpt@car#2\car@nil\cpt@nnil
}
\new@def\aftercsname#1#2{%
  \expandafter\cptswap\expandafter{\csname#2\endcsname}{#1}%
}
\new@def\xaftercsname#1#2{%
  \expandafter\expandafter\expandafter
  \cptswap\expandafter\expandafter
  \expandafter{\csname#2\endcsname}{#1}%
}
\new@def\xaftercsnamebrace#1#2{%
  \expandafter\expandafter\expandafter
  \cptswapbracefirst\expandafter
  \expandafter\expandafter{\csname#2\endcsname}{#1}%
}
%% For internal use; #1 must be one token:
\new@def*\simpleexpandarg#1#2{\expandafter#1\expandafter{#2}}
\cptnewlet\s@expandarg\simpleexpandarg
%%--

\new@def*\cptexpandnext#1#2{%
  \expandafter\cptswap\expandafter{#2}{#1}%
}
\new@def*\cptbexpandnext#1#2{%
  \expandafter\expandafter\expandafter\cptswap
  \expandafter\expandafter\expandafter{#2}{#1}%
}
\new@def*\cptexpandbracenext#1#2{%
  \expandafter\cptswapbracefirst\expandafter{#2}{#1}%
}
\cptnewlet\cptexpandbrnext\cptexpandbracenext
\new@def*\cptexpandsome#1\expandthis#2#3\expandstop{%
  \cptexpandnext{#1}{#2}#3%
}
\new@def*\cptexpandbracesome#1\expandthis#2#3\expandstop{%
  \cptexpandbracenext{#1}{#2}#3%
}
\new@def\cptremovescape#1{%
  \ifblankTF{#1}{}{\expandafter\@gobble\string#1}%
}
\new@def\cptgobblescape#1{%
  \ifblankTF{#1}{}{%
    \ifnum\escapechar>\@cclv\else
      \ifnum\escapechar<\z@pt\else
        \expandafter\expandafter
        \csname @gobble\ifnum\escapechar=\@xxxii @space\fi
        \cptthreexp\endcsname
      \fi
    \fi
    \string#1%
  }%
}
\robust@def*\defpass#1#2#{\afterassignment#1\long\def#1#2}
\robust@def*\edefpass#1#2#{\afterassignment#1\long\edef#1#2}
\new@def\uselivecs#1{%
  \ifdefTF{#1}{#1}{\cpt@notdeferr{#1}}%
}
\new@def*\usecsifdef#1{\ifdefTF#1{#1}{}}
\new@def*\expandonceifmacroelsenil#1{%
  \ifmacroTF{#1}{%
    \ifexpandableTF{#1}{%
      \expandcsonce{#1}%
    }{%
      \unexpanded{#1}%
    }%
  }{}%
}
\new@def\usename#1{\csname#1\endcsname}% long!
\new@def\usecsn#1{%
  \ifcsname#1\endcsname\expandafter\@iden\else
    \expandafter\@gobble\fi{\usename{#1}}%
}
% \usecsnifdef is stronger than \usecsn:
\new@def*\usecsnifdef#1{\ifcsndefTF{#1}{\usename{#1}}{}}
\new@def\uselivecsn#1{%
  \ifcsndefTF{#1}{%
    \usename{#1}%
  }{%
    \cpt@err{Command '\@backslashchar#1' undefined}\@ehc
  }%
}
\new@def\ifcondTF#1\fi{\csname @#1first\else second\fi oftwo\endcsname}
\new@def\ifcondFT#1\fi{\ifcondTF#1\fi}
\new@def*\ifcsnameTF#1{%
  \ifblankTF{#1}\@secondoftwo{%
    \usename{@\ifcsname#1\endcsname first\else second\fi oftwo}%
  }%
}
\new@def*\ifcsnameFT#1{\ifcsnameTF{#1}\cptiiofii\cptiofii}
\new@def*\ifnamedefTF#1{%
  \ifcsnameTF{#1}{%
    \usename{@\expandafter\ifx\csname#1\endcsname\relax
      second\else first\fi oftwo}%
  }{%
    \@secondoftwo
  }%
}
\robust@def*\cpt@notdefinable{%
  \@latex@error
    {Command '\@backslashchar\undefinablecs' already exists}%
    {Command '\@backslashchar\undefinablecs' already defined,
    \MsgBrk or name '\@backslashchar\@qend\undefinablecs' illegal.}
}
\robust@def*\ifchoicefoundTF\endgroup{%
  \expandafter\endgroup\ifcpt@choicefd
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
\robust@def*\cpt@oneoftwo#1\endgroup{%
  \let\@firstoftwo\relax
  \let\@secondoftwo\relax
  \cptpassexpanded{%
    \endgroup
    \ifcase#1\relax
      \ifdefboolTF{cpt@choicefd}\cptiofii\cptiiofii
    \or
      \ifdefboolTF{cpt@choicefd}\cptiiofii\cptiofii
    \else
      \cpt@err{Invalid number '#1'}\noexpand\@ehc
    \fi
  }%
}
\robust@def*\cpt@ifseeparameter#1#{%
  \xifinsetTF
    {\detokenize{macro parameter character}}
    {\meaning\@let@token}%
}
% \cptcommanormalize is cheap but is restricted to comma lists only.
% Also, it isn't meant for parsing keyval lists. See \kv@@normalize
% and \kv@@parse:
\begingroup
\uccode`\~=`\,%
\uppercase{\endgroup
  \def\cptcommanormalize#1{%
    \unexpanded\expandafter{\romannumeral-`\q
      \cpt@activecomma,#1,~\cpt@nil}%
  }%
  \def\cpt@activecomma#1~#2\cpt@nil{%
    \ifblankTF{#2}
      {\cpt@spacecomma#1 ,\cpt@nil}{\cpt@activecomma#1,#2\cpt@nil}%
  }%
}
\def\cpt@spacecomma#1 ,#2\cpt@nil{%
  \ifblankTF{#2}
    {\cpt@commaspace#1, \cpt@nil}{\cpt@spacecomma#1,#2\cpt@nil}%
}
\def\cpt@commaspace#1, #2\cpt@nil{%
  \ifblankTF{#2}
    {\cpt@doublecomma#1,,\cpt@nil}{\cpt@commaspace#1,#2\cpt@nil}%
}
\def\cpt@doublecomma#1,,#2\cpt@nil{%
  \ifblankTF{#2}
    {\ifblankTF{#1}{}{\expandafter\noexpand\@gobble#1}}
    {\cpt@doublecomma#1,#2\cpt@nil}%
}
\cptnewcounts{cpt@csvdepth}
\cptnewbools{loopbreak}
\ifcsdefinable\loopbreak{\let\loopbreak\loopbreaktrue}
\robust@def*\cpt@notdeferr#1{%
  \@latex@error{Command '\detokenize{#1}' isn't defined}
    {I expected '\detokenize{#1}' to be defined.}%
}
\robust@def*\cpt@isdeferr#1{%
  \@latex@error{Command '\detokenize{#1}' is already defined}
    {I expected '\detokenize{#1}' to be undefined.}%
}
\robust@def*\cpt@notcserr#1{%
  \@latex@error{Token '\detokenize{#1}' not a macro
    \MsgBrk or is currently undefined}
    {I expected '\detokenize{#1}' to be defined.}%
}
\robust@def*\cpt@iscserr#1{%
  \@latex@error{Token '\detokenize{#1}' is a macro:
    \MsgBrk not currently undefined}
    {I didn't expect '\detokenize{#1}' to be defined.}%
}
\robust@def*\cpt@notescapederr#1{%
  \@latex@error{Token '\detokenize{#1}' not escaped
    \MsgBrk or is an active character}{I expected
    the first token of\MsgBrk'\detokenize{#1}' to be
    escape character.}%
}
\robust@def*\cpt@isescapederr#1{%
  \@latex@error{Token '\detokenize{#1}' is escaped}{%
    I didn't expect the first character of '\detokenize{#1}'
      \MsgBrk to be the escape character.}%
}
\robust@def*\cpt@notbracederr#1{%
  \@latex@error{Token '\detokenize{#1}' isn't braced}
    {I expected '\detokenize{#1}' to be braced.}%
}
\robust@def*\cpt@isbracederr#1{%
  \@latex@error{Token '\detokenize{#1}' is braced}
    {I didn't expect '\detokenize{#1}' to be braced.}%
}
\robust@def*\cpt@notonetokenerr#1{%
  \@latex@error{'\detokenize{#1}' is not one token}
    {I expected '\detokenize{#1}' to be one token.}%
}
\robust@def*\cpt@isonetokenerr#1{%
  \@latex@error{'\detokenize{#1}' is one token}
    {I didn't expect '\detokenize{#1}' to be one token.}%
}
\robust@def*\cpt@notblankerr#1{%
  \@latex@error{'\detokenize{#1}' is not blank or empty}
    {I expected '\detokenize{#1}' to be blank.}%
}
\robust@def*\cpt@isblankerr#1{%
  \@latex@error
    {Blank/empty token for command '\detokenize{#1}'}
    {I didn't expect a blank argument/token here.}%
}
\robust@def*\cpt@notexpandableerr#1{%
  \@latex@error{'\detokenize{#1}' is not expandable
    \MsgBrk or is undefined}
    {I expected '\detokenize{#1}' to be expandable.}%
}
\robust@def*\cpt@toodeep#1#2{%
  \@latex@error{Command '\detokenize{#1}' nested too deeply}
    {Command '\detokenize{#1}' nested beyond level '#2'.}%
}

\begingroup
\catcode`\&=7
\robust@gdef*\cpt@getmacroprefix#1{%
  \begingroup
  \edef\cpt@tempa##1{\def##1####1\detokenize{macro}:####2&}%
  \cpt@tempa\@ifmacro{%
    \def\macroprefix{##1}%
    \usename{@\ifblankTF{##2}{second}{first}oftwo}%
  }%
  \edef\cpt@tempb##1{##1\detokenize{macro}:&}%
  \cpt@tempb{\expandafter\@ifmacro\meaning#1}{%
    \@testtrue
  }{%
    \@testfalse\def\macroprefix{}%
  }%
  \cpteveryscan
  \cptpassexpanded{%
    \endgroup
    \ifcsemptyTF\macroprefix\@iden{\noexpand\scantokens}%
    {\def\noexpand\macroprefix{\macroprefix}\relax}%
  }%
}
\new@gdef*\cpt@getprefix#1>#2&{#1}
\robust@gdef*\ifprotectedTF#1{%
  \begingroup
  \edef\cpt@tempa##1{\def##1####1\string\protected####2&}%
  \cpt@tempa\cpt@tempa{%
    \aftercsname\endgroup{@\ifblankTF{##2}{second}{first}oftwo}%
  }%
  \edef\cpt@tempb##1{%
    ##1\expandafter\cpt@getprefix\meaning#1&\string\protected&%
  }%
  \cpt@tempb\cpt@tempa
}
\endgroup

% We need the equivalent of '\protected\let' and we want to be able to
% do \shelllet\x=\y:
\robust@def*\shelllet#1{\cpt@ifeql{\cpt@shelllet{#1}}{\cpt@shelllet{#1}}}
\robust@def*\cpt@shelllet#1#2{%
  \ifblankTF{#2}{%
    \cpt@isblankerr\shelllet
  }{%
    \expandafter\ifblankTF\expandafter{\@gobble#2}{%
      \ifcsdefinable#1{%
        % Here we must use \let and not \def (for immediate inheritance):
        \ifprotectedTF#2{\let#1=#2}{%
          \ifcsndefinable{shell@\cptremovescape#1}{%
            \letcsntocs{shell@\cptremovescape#1}=#2%
            \protected\edef#1{\cptmakecs{shell@\cptremovescape#1}}%
          }%
        }%
      }%
    }{%
      \cpt@notonetokenerr{#2}%
    }%
  }%
}
\robust@def\showruntime#1\runtime{%
  \pdfresettimer#1%
  \message{Run time: \the\pdfelapsedtime}%
}
\new@def*\ifdocstartedTF{\ifdefTF\cpt@docstarted\cptiofii\cptiiofii}

\long\def\@gobblethree#1#2#3{}
\long\def\@firstofthree#1#2#3{#1}
\long\def\@secondofthree#1#2#3{#2}
\long\def\@thirdofthree#1#2#3{#3}
\new@def\cptalloftwo#1#2{#1#2}
\new@def*\cptrmstop{0 }
\ifcsdefinable\cptrm{\let\cptrm\romannumeral}
\new@def\cpt@car#1#2\car@nil{#1}
\new@def\cpt@cdr#1#2\cdr@nil{#2}
\ifcsdefinable\cpt@relax{\let\cpt@relax\relax}
% This is needed to define phantom environments:
\newcommand*\phantom@env{\relax}
\new@def\cptgobbletorelax#1\cpt@relax{}
\new@def\cptbgobbletorelax\fi#1\cpt@relax{\fi\endgroup}
\new@def\cpt@removetonnil#1\cpt@nnil{}
\new@def\cpt@catchtonnil#1\cpt@nnil{#1}
\new@def\cpt@removetodot#1.{}
\new@def\cpt@catchtodot#1.{#1}
\new@def\cpt@removetospace#1 {}
\ifcsdefinable\csvbreak{\let\csvbreak\relax}
\new@def*\cpt@csvbreak{\csvbreak}
\ifcsdefinable\csvpause{\let\csvpause\relax}
\new@def*\cpt@csvpause{\csvpause}
\ifcsdefinable\tsvbreak{\let\tsvbreak\relax}
\new@def*\cpt@tsvbreak{\tsvbreak}
\new@def*\ifcsvbreakTF#1{%
  \edef\reserved@a{\unexpanded{#1}}%
  \ifcseqTF\reserved@a\cpt@csvbreak
}
\ifcsdefinable\cptdoremainder{\let\cptdoremainder\@gobble}
% #1: sentinel; #2: parser
\robust@def*\gobble@to@sentinel#1#2{%
  \defpass\reserved@a##1#1#2{\cptdoremainder{##1}}%
}
\new@def*\cptthreexp{\expandafter\expandafter\expandafter}
\new@def*\cptsevenxp{%
  \expandafter\expandafter\expandafter
  \expandafter\expandafter\expandafter\expandafter
}
\robust@def\cptlocalxp#1{\begingroup\cptthreexp\endgroup#1}
\new@def*\cptzapspaces#1{%
  \def\cptzapspaces##1{\romannumeral\cpt@zapspaces.##1#1\zap@nil}%
}
\cptzapspaces{ }
\long\def\cpt@zapspaces#1 #2\zap@nil{%
  \ifblankTF{#2}{%
    \expandafter\cptrmstop\@gobble#1%
  }{%
    \expandafter\cpt@zapspaces\expandafter.\@gobble#1#2\zap@nil
  }%
}
\new@def*\cptdotimes#1{%
  \ifblankTF{#1}{%
    \ifdefboolTF{cpt@useempty}{\cpt@dotimes{m}}\@gobble
  }{%
    \expandafter\cpt@dotimes\expandafter
      {\romannumeral\number#1000}%
  }%
}
\new@def*\cpt@dotimes#1#2{%
  \ifnullTF{#1}{}{%
    #2\relax
    \expandafter\ifnullTF\expandafter{\@gobble#1}{}{%
      \expandafter\cpt@dotimes\expandafter{\@gobble#1}{#2}%
    }%
  }%
}
\new@def*\cptexpandtimes#1{%
  \expandafter\cpt@expandtimes\expandafter
    {\romannumeral\number#1000}%
}
\new@def*\cpt@expandtimes#1#2{%
  \ifnullTF{#1}{%
    \unexpanded{#2}%
  }{%
    \expandafter\ifnullTF\expandafter{\@gobble#1}{%
      \unexpanded\expandafter{#2}%
    }{%
      \expandafter\cptswapbracefirst\expandafter{#2}%
      {\expandafter\cpt@expandtimes\expandafter{\@gobble#1}}%
    }%
  }%
}
\new@def*\normal@reverse#1{\cpt@normalreverse{}#1\@nnil}
\long\def\cpt@normalreverse#1#2{%
  \expandafter\ifxTF\cpt@car#2\car@nil\@nnil{%
    \ifdefboolTF{@test}\@iden\unexpanded{#1}%
  }{%
    \cpt@normalreverse{#2#1}%
  }%
}
\new@def*\robust@reverse@testbrace#1{%
  \ifnum\cpt@pdfstrcmp{\detokenize\expandafter{\@gobble#1.}}{}=\z@pt
    \expandafter\@secondoftwo\else\expandafter\@firstoftwo\fi
  {%
    \ifnum\cpt@pdfstrcmp{\expandafter\@car\detokenize{#1}\@nil}%
      \cpt@leftbracechar=\z@pt
      \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
  }{%
    \@secondoftwo
  }%
}
\new@def*\robust@reverse#1{\cpt@robustreverse{}.#1\@nnil}
\long\def\cpt@robustreverse#1#2\@nnil{%
  \cpt@r@bustreverse{#1}%
    {\expandafter\robust@reverse@testbrace\expandafter{\@gobble#2}}#2\@nnil
}
\long\def\cpt@r@bustreverse#1#2.#3{%
  \expandafter\ifxTF\cpt@car#3\car@nil\@nnil{%
    \ifdefboolTF{@test}\@iden\unexpanded{#1}%
  }{%
    #2{\cpt@robustreverse{{#3}#1}}{\cpt@robustreverse{#3#1}}.%
  }%
}
\robust@def*\ifcommandsdefinable#1{%
  \@testopt{\cpt@ifcmdsdefinable#1}\relax
}
\def\cpt@ifcmdsdefinable#1[#2]{%
  \edef\reserved@e{\unexpanded{#2}}%
  \begingroup
  \@tempswafalse
  \cptfor #1\dofor{%
    \if\expandafter\@car\string##1x\@nil\@backslashchar
      \@tempswafalse
      \ifcsdefinable##1\@tempswatrue
    \else
      \cpt@notescapederr{##1}%
    \fi
    \if@tempswa\else\loopbreak\fi
  }%
  \if@tempswa
    \aftergroup\reserved@e
  \fi
  \endgroup
}
\ifcommandsdefinable{\cpttrimspace,\cpttrimspaces}\relax
\long\def\cpttrimspaces#1{\cpt@trimspaces@a\relax{#1}}
\begingroup
\catcode`\&=7\catcode`\$=7
\long\gdef\cpt@trimspaces@a#1#2{\cpt@trimspaces@b.#1$.#2& &}
\long\gdef\cpt@trimspaces@b#1$#2 &{\cpt@trimspaces@c#1$#2&}
\long\gdef\cpt@trimspaces@c#1$#2&#3{%
  \cpt@trimspaces@d\ifstrcmpTF{#2}{#1}{%
    \unexpanded\expandafter{\@gobble#1}%
  }{%
    \cpt@trimspaces@d\cpt@trimspaces@a{#2}{#2}%
  }%
}
\long\gdef\cpt@trimspaces@d#1#2{%
  \expandafter\cpt@trimspaces@e\expandafter#1\expandafter{%
    \unexpanded\expandafter
    {\romannumeral-`\q\expandafter\noexpand\@gobble#2}%
  }%
}
\long\gdef\cpt@trimspaces@e#1#2#3{%
  \expandafter#1\expandafter{\@gobble#3}{#2}%
}
\long\gdef\cpttrimspace#1{\cpt@trimspace@a.#1& &}
\long\gdef\cpt@trimspace@a#1 &{\cpt@trimspace@b#1&}
\long\gdef\cpt@trimspace@b#1&#2{%
  \unexpanded\expandafter{%
    \romannumeral0%
    \expandafter\ifleadspaceTF\expandafter{\@gobble#1}{%
      \@gobble#1%
    }{%
      \expandafter\@space\@gobble#1%
    }%
  }%
}
\endgroup
\robust@def\trim@@spaces#1#2{\edef#2{\cpttrimspaces{#1}}}
\robust@def\trim@@space#1#2{\edef#2{\cpttrimspace{#1}}}
\robust@def*\despacecontent#1{%
  \edef#1{\simpleexpandarg\cpttrimspace{#1}}%
}
\robust@def\cptusesimpletrimspaces{%
  \let\cptcurrtrimspaces\cpttrimspace
}
\cptusesimpletrimspaces
\let\cptusesimpletrimspace\cptusesimpletrimspaces
\robust@def\cptusehardtrimspaces{%
  \let\cptcurrtrimspaces\cpttrimspaces
}
\let\cptusehardtrimspace\cptusehardtrimspaces
% It is more efficient to use \csv@@normalize in place
% of \cptdespacecsvlist. Also, \csv@@normalize allows parsers
% to be made innocent. But the following is needed in some
% instances (eg, where we don't want to sanitize the parser):
\robust@def*\cptdespacecsvlist{\cpt@teststopt\cpt@despacecsvlist,}
% #1: arbitrary parser
% * -> #2 is a <listcmd>, otherwise a <list>
\robust@def*\cpt@despacecsvlist[#1]#2{%
  \cpt@stchoose{cpt@st}{#2}\cpt@tempa\cpt@despacecsvlist
  \ifcsnullTF\cpt@tempa{}{%
    \def\cpt@rsvda{}%
    \UseEmptyEntry
    \def\csv@do##1{%
      \edef\cpt@tempa{\cpttrimspaces{##1}}%
      \cptoaddtolist[#1]\cpt@rsvda\cpt@tempa
    }%
    \csv@@loop*[#1]\cpt@tempa
    \ifdefboolFT{cpt@st}{}{\let#2=\cpt@rsvda}%
  }%
}
% \cptnewvariables{<type>}[<prf>]{<variables>}[<state/value>]
% If <type> is 'toks', <state/value> is the content of the
% new token register.
% Valid <types> are 'if, toks, dimen, count, tog, switch'.
% Boxes can't be initialized by this command.
\robust@def*\cptnewvariables#1{\cpt@testopt{\cpt@newvariables{#1}}{}}
\robust@def*\cpt@newvariables#1[#2]#3{%
  \edef\reserved@a{\noexpand\cpt@testopt{%
    \cpt@newv@riables{\cpttrimspace{#1}}{\cpttrimspace{#2}}{#3}%
  }{}}%
  \reserved@a
}
\robust@def*\cpt@newv@riables#1#2#3[#4]{%
  \def\cpt@rsvda##1{%
    \ifblankTF{#4}{\def\cpt@tempc{##1}}{\def\cpt@tempc{#4}}%
  }%
  \edef\cpt@tempb{\ifstrcmpTF{#1}{if}{if}{}}%
  \cptfor#3\dofor{%
    \ifblankTF{##1}\cptgobbletorelax\relax
    \ifnamedefTF{\cpt@tempb#2##1}{%
      \edef\undefinablecs{\cpt@tempb#2##1}%
      \ifstrcmpTF{#1}{tog}{}{\cpt@notdefinable}%
    }{%
      \ifstrcmpTF{#1}{tog}{%
        \@tempswatrue
        \ifnamedefTF{cpt@tog@#2##1}{%
          \cpt@err{Toggle '#2##1' already defined}\@ehc
        }{%
          \lowercase{%
            \ifstrcmpTF{#4}{true}{%
              \let\cpt@togstate\@firstoftwo
            }{%
              \ifstrcmpTF{#4}{false}{%
                \let\cpt@togstate\@secondoftwo
              }{%
                \ifblankTF{#4}{%
                  \let\cpt@togstate\@secondoftwo
                }{%
                  \@latex@error{Invalid toggle value '#4'}\@ehc
                }%
              }%
            }%
          }%
          \expandafter\let\csname
            cpt@tog@#2##1\endcsname\cpt@togstate
        }%
      }{%
        \@tempswatrue
        % Declare the new switch:
        \ifstrcmpTF{#1}{switch}{%
          \lowercase{%
            \ifstrcmpTF{#4}{true}{%
              \def\reserved@a{00}%
            }{%
              \ifstrcmpTF{#4}{false}{%
                \def\reserved@a{01}%
              }{%
                \ifblankTF{#4}{%
                  \def\reserved@a{01}%
                }{%
                  \@latex@error{Invalid switch value '#4'}\@ehc
                }%
              }%
            }%
          }%
          \expandafter\let\csname#2##1\endcsname\reserved@a
        }{%
          \@tempswafalse
          % Declare the new variable:
          \csname new#1\expandafter\endcsname\csname
            \cpt@tempb#2##1\endcsname
          % Initialize the new variable:
          \ifstrcmpTF{#1}{if}{%
            \cpt@rsvda{false}%
            \csname#2##1\cpt@tempc\endcsname
          }{%
            \ifstrcmpTF{#1}{toks}{%
              \cpt@rsvda{}%
              \csname#2##1\endcsname\expandafter{\cpt@tempc}%
            }{%
              % It is dangerous to initialize boxes here:
              % horizontal and vertical boxes are incompatible.
              \ifstrcmpTF{#1}{box}{}{%
                \ifstrcmpTF{#1}{count}{%
                  \cpt@rsvda\z@pt
                  \csname#2##1\endcsname=\cpt@tempc\relax
                }{%
                  \ifstrcmpTF{#1}{dimen}{%
                    \cpt@rsvda\z@pt
                    \csname#2##1\endcsname=\cpt@tempc\relax
                  }{%
                    \ifstrcmpTF{#1}{skip}{%
                      \cpt@rsvda{\z@pt plus \z@pt minus \z@pt}%
                      \csname#2##1\endcsname=\cpt@tempc\relax
                    }{%
                      \ifstrcmpTF{#1}{write}{}{%
                        \ifstrcmpTF{#1}{read}{}{%
                          \cpt@unknownnewvar{#1}%
                        }%
                      }%
                    }%
                  }%
                }%
              }%
            }%
          }%
        }%
      }%
    }%
    \cpt@relax
  }%
}
\def\cpt@unknownnewvar#1{%
  \if@tempswa\else
    \begingroup
    \def\x##1{Maybe you meant '##1'.}%
    \cpt@err{Unknown variable type '#1'}{%
      \ifstrcmpTF{#1}{dim}{\x{dimen}}{%
        \ifstrcmpTF{#1}{token}{\x{toks}}{%
          \ifstrcmpTF{#1}{tok}{\x{toks}}{%
            \ifstrcmpTF{#1}{toggle}{\x{tog}}{%
              \ifstrcmpTF{#1}{sw}{\x{switch}}{%
                No variable of type '#1'.
              }%
            }%
          }%
        }%
      }%
    }%
    \endgroup
  \fi
}

\cptnewvariables{if}[cpt@]{usepox,optfd,noval,igopt,inpox,olddx,
  in,check,choicefd,useempty,swa}[false]

% st                -> I saw star
% pl                -> I saw plus
% pm                -> I saw prime
% cl                -> I saw exclamation mark
% verbose           -> log information (package option)
% usepox            -> use \XDeclareOption and \XProcessOptions for
%                      \DeclareOption and \ProcessOptions (package option)
% igopt             -> ignore option
% optfd             -> option found
% inpox             -> we're in \XProcessOptions
% olddx             -> we're in \DeclareOption and not in \XDeclareOption
% in                -> for use in \cpt@in
% check,sw          -> generic booleans ('check' for short intervals;
%                      'sw' for longer intervals)
% choicefd          -> generic (choice found)
% loopbreak         -> terminate loop
% useempty          -> use empty entry (in loops)
%
\cptnewvariables{tog}{biboolopts}[false]
\cptnewvariables{count}[cpt@]{optdepth,cnta}[\z@pt]
\new@def*\UseEmptyEntry{\global\cpt@useemptytrue}
\new@def*\DiscardEmptyEntry{\global\cpt@useemptyfalse}
\new@def\oifnullTF#1{\expandafter\ifnullTF\expandafter{#1}}
\new@def\oifnullFT#1{\expandafter\ifnullFT\expandafter{#1}}
\new@def\xifnullTF#1{\cptexpandarg\ifnullTF{#1}}
\new@def\xifnullFT#1{\cptexpandarg\ifnullFT{#1}}
\new@def\oifblankTF#1{\expandafter\ifblankTF\expandafter{#1}}
\new@def\oifblankFT#1{\expandafter\ifblankFT\expandafter{#1}}
\new@def\xifblankTF#1{\cptexpandarg\ifblankTF{#1}}
\new@def\xifblankFT#1{\xifblankTF{#1}\cptiiofii\cptiofii}
\new@def*\ifdefTF#1{%
  \ifblankTF{#1}\@secondoftwo{%
    \usename{@\ifx#1\cpt@undefined second\else
    \ifx#1\relax second\else first\fi\fi oftwo}%
  }%
}
\new@def*\ifdefFT#1{\ifdefTF{#1}\cptiiofii\cptiofii}
\new@def*\oifdefTF#1{\expandafter\ifdefTF\expandafter{#1}}
\new@def*\oifdefFT#1{\expandafter\ifdefFT\expandafter{#1}}
\new@def*\xifdefTF#1{\cptexpandarg\ifdefTF{#1}}
\new@def*\xifdefFT#1{\cptexpandarg\ifdefFT{#1}}
\new@def*\ifcsndefTF#1{%
  \ifblankTF{#1}{%
    \expandafter\@secondoftwo\@gobble
  }{%
    \ifcsname#1\endcsname
      \expandafter\@firstofone
    \else
      \cptthreexp\@secondoftwo\expandafter\@gobble
    \fi
  }{%
    \aftercsname\ifdefTF{#1}%
  }%
}
\new@def*\ifcsndefFT#1{\ifcsndefTF{#1}\cptiiofii\cptiofii}
\new@def*\oifcsndefTF#1{\expandafter\ifcsndefTF\expandafter{#1}}
\new@def*\oifcsndefFT#1{\expandafter\ifcsndefFT\expandafter{#1}}
\new@def*\xifcsndefTF#1{\cptexpandarg\ifcsndefTF{#1}}
\new@def*\xifcsndefFT#1{\cptexpandarg\ifcsndefFT{#1}}
\robust@redef*\ifcsdefinable#1#2{%
  \ifblankTF{#1}{%
    \cpt@isblankerr\ifcsdefinable
  }{%
    \edef\undefinablecs{\cptgobblescape#1}%
    \ifdefTF{#1}\cpt@notdefinable{%
      \ifcsndefTF{end\undefinablecs}\cpt@notdefinable{#2}%
    }%
  }%
}
\ifcsdefinable\@ifcsdefinable{\let\@ifcsdefinable\ifcsdefinable}
\robust@def\rc@ifcsdefinable#1#2{\let\ifcsdefinable\@ifcsdefinable#2}
\robust@def*\ifcsndefinable#1{\cptlocalxp\aftercsname\ifcsdefinable{#1}}
\robust@def*\ifdefinableTF#1{%
  \ifblankTF{#1}{%
    \cpt@isblankerr\ifdefinableTF
    \@secondoftwo
  }{%
    \ifdefTF{#1}\@secondoftwo{%
      \ifcsndefTF{end\cptgobblescape#1}\cptiiofii\cptiofii
    }%
  }%
}
\robust@def*\ltxmsg@warn{\@latex@warning@no@line}
\robust@def*\ltxmsg@info{\@latex@info@no@line}
\robust@def*\ltxmsg@err{\@latex@error}
\robust@redef\cpt@testopt#1#2{\ifnextcharTF[{#1}{#1[{#2}]}}

% Eg, \def\csa{\cpt@testcharopt\csb<{default}>}
%     \def\csb<#1>{...}
\robust@def*\cpt@testcharopt#1#2#3#4{\ifnextcharTF#2{#1}{#1#2{#3}#4}}

% Expandable \@testopt:
% Eg, \def\macroa#1{\cpt@xtestopt{#1}\macrob{Mr.}}
%     \def\macrob[#1]#2{#1 #2}
%     \edef\testa{\macroa{John Johnson}}
%     \edef\testb{\macroa[Dr.]{Haiki Heiki}}
\new@def*\cpt@xtestopt#1#2#3{%
  \cpt@xifbrack#1\\[\\{#2#1}{#2[{#3}]{#1}}%
}
\new@def*\cpt@xifbrack#1[#2\\#3#{\ifblankTF{#1#2}}
% Eg, \def\macroa{\cpt@newxtestopt\macrob{Mr.}}
%     \def\macrob[#1]#2{#1 #2}
%     \edef\testa{\expandafter\macroa\activespace{John Johnson}}
%     \edef\testb{\macroa[Dr.]{Haiki Heiki}}
\new@def*\cpt@newxtestopt#1#2#3{%
  % #3 will be a space only if that space is active. But
  % \ifstrcmpTF will detokenize that space before comparison.
  \ifstrcmpTF{ }{#3}{%
    \cpt@newxtestopt#1{#2}%
  }{%
    \ifstrcmpTF{#3}{[}{%
      #1[%
    }{%
      \ifntypeTF{#3}{%
        #1[#2]#3%
      }{%
        #1[#2]{#3}%
      }%
    }%
  }%
}
\robust@def*\cpt@ifbrack#1#2{\ifnextcharTF[{#1}{#2}}
\robust@def\cpt@testpnopt#1#2{\ifnextcharTF({#1}{#1({#2})}}
\robust@def\cpt@testltopt#1#2{\ifnextcharTF<{#1}{#1<{#2}>}}
\robust@def\cpt@ifplus#1{\ifnextcharTF+{\@firstoftwo{#1}}}
\robust@def\cpt@ifclam#1{\ifnextcharTF!{\@firstoftwo{#1}}}
\robust@def\cpt@ifprime#1{\ifnextcharTF'{\@firstoftwo{#1}}}
\robust@def\cpt@ifeql#1{\ifnextcharTF={\@firstoftwo{#1}}}
\robust@def\cpt@testst#1{\cpt@ifstar{\cpt@sttrue#1}{\cpt@stfalse#1}}
\robust@def\cpt@testpl#1{\cpt@ifplus{\cpt@pltrue#1}{\cpt@plfalse#1}}
\robust@def\cpt@testpm#1{\cpt@ifprime{\cpt@pmtrue#1}{\cpt@pmfalse#1}}
\robust@def\cpt@testcl#1{\cpt@ifclam{\cpt@cltrue#1}{\cpt@clfalse#1}}
\robust@def\cpt@teststpl#1{\cpt@testst{\cpt@testpl{#1}}}
\robust@def\cpt@teststpm#1{\cpt@testst{\cpt@testpm{#1}}}
\robust@def\cpt@teststopt#1#2{\cpt@testst{\cpt@testopt{#1}{#2}}}
\robust@def*\newletcs#1{%
  \begingroup
  \def\cpt@tempa{\relax}%
  \cpt@ifeql{\cpt@newletcs{#1}}{\cpt@newletcs{#1}}%
}
\robust@def*\gnewletcs#1{%
  \begingroup
  \def\cpt@tempa{\global}%
  \cpt@ifeql{\cpt@newletcs{#1}}{\cpt@newletcs{#1}}%
}
\robust@def*\cpt@newletcs#1{%
  \ifcsdefinable{#1}{%
    \expandafter\endgroup\cpt@tempa\let#1= %
  }%
}
\robust@def*\gletcs{\global\let}
\robust@def*\fulllet{\@testtrue\cpt@fulllet}
\robust@def*\fullnewlet{\@testfalse\cpt@fulllet}
\robust@def*\cpt@fulllet#1#2{%
  \trim@@space{#1}\cpt@tempa
  \trim@@space{#2}\cpt@tempb
  \cpt@fullleterr\cpt@tempa\cpt@tempb
  \csname\if@test let\else newletcs\fi
    \cptthreexp\endcsname\expandafter\cpt@tempa\cpt@tempb
  \oifdefFT\cpt@tempb{}{%
    \ifcsndefTF{\expandafter\string\cpt@tempb}{%
      \letcsntocsn{\expandafter\string\cpt@tempa}
        {\expandafter\string\cpt@tempb}%
    }{%
      \ifcsndefFT{\expandafter\cptgobblescape\cpt@tempb\@space}{}{%
        \letcsntocsn{\expandafter\cptgobblescape\cpt@tempa\@space}
          {\expandafter\cptgobblescape\cpt@tempb\@space}%
        \ifcsndefFT{\expandafter\string\cpt@tempb\@space}{}{%
          \letcsntocsn{\expandafter\string\cpt@tempa\@space}
            {\expandafter\string\cpt@tempb\@space}%
        }%
      }%
    }%
  }%
}
\new@def*\cpt@fullleterr#1#2{%
  \simpleexpandarg\ifntypeTF{#1}{%
    \simpleexpandarg\ifntypeTF{#2}{}{%
      \cpt@notonetokenerr{#2}%
    }%
  }{%
    \cpt@notonetokenerr{#1}%
  }%
}
\robust@def*\letcsset{%
  \@tempswafalse
  \cpt@ifstar
    {\let\dolet\ltsfulllet\cpt@newletcsset}%
    {\let\dolet\let\cpt@newletcsset}%
}
% Eg, \newletcsset{\a\b,\x\y}
\robust@def*\newletcsset{%
  \@tempswatrue
  \cpt@ifstar
    {\let\dolet\ltsfulllet\cpt@newletcsset}%
    {\let\dolet\let\cpt@newletcsset}%
}
\robust@def*\cpt@newletcsset#1{%
  \def\cpt@tempa##1##2\cpt@nil{%
    \cpt@tempb##1=##2\cpt@nil
  }%
  \def\cpt@tempb##1=##2\cpt@nil{%
    \ifblankFT{##2}{}{%
      \cpt@err{The partner of command '\string##1' is void}\@ehc
    }%
    \if@tempswa
      \ifdefTF{##1}{%
        \ifx##1##2\else\cpt@isdeferr{##1}\fi
      }{%
        \dolet##1=##2%
      }%
    \else
      \dolet##1=##2%
    \fi
  }%
  \cptfor#1\dofor{%
    \ifinsetTF{=}{##1}{%
      \cpt@tempb##1\cpt@nil
    }{%
      \cpt@tempa##1\cpt@nil
    }%
  }%
  \undefcs\dolet
}
\robust@def*\cptletmanytocs#1#2{\cptfor#1\dofor{\let##1= #2}}
\robust@def*\fullletmanytocs#1#2{\cptfor#1\dofor{\fulllet{##1}{#2}}}
\robust@def*\begintoksgroup{\begingroup\toks@{}}
\robust@def*\endtoksgroup{\expandafter\endgroup\the\toks@}

\begingroup
\catcode`\&=7
\new@gdef*\ifcounterTF#1{%
  \ifcseqTF#1\count{%
    \@secondoftwo
  }{%
    \expandafter\cpt@ifcounter@a\meaning#1:&%
  }%
}
\edef\cpt@ifcounter@a#1#2{%
  \gdef#1##1:##2&{#2##1\string\count&}%
  \gdef#2##1\string\count##2&{\noexpand\ifblankTF{##1}}%
}
\cpt@ifcounter@a\cpt@ifcounter@a\cpt@ifcounter@b
% Similar to \ifcounterTF. Don't call this \ifdimTF:
\new@gdef*\ifdimenTF#1{%
  \ifcseqTF#1\dimen{%
    \@secondoftwo
  }{%
    \expandafter\cpt@ifdimen@a\meaning#1:&%
  }%
}
\edef\cpt@ifdimen@a#1#2{%
  \gdef#1##1:##2&{#2##1\string\dimen&}%
  \gdef#2##1\string\dimen##2&{\noexpand\ifblankTF{##1}}%
}
\cpt@ifdimen@a\cpt@ifdimen@a\cpt@ifdimen@b
\endgroup

% Argument #1 can be an arbitrary number (\countdef'd or otherwise).
% Pushing is done globally.
\robust@def*\cptpushnumber#1{%
  \ifntypeTF{#1}{%
    \ifdefTF{#1}{%
      \ifcounterTF#1{%
        \global\advance#1\@ne
      }{%
        \xdef#1{\the\numexpr#1+1}%
      }%
    }{%
      \gdef#1{\@ne}%
    }%
  }{%
    \cpt@notonetokenerr{#1}%
  }%
}
\robust@def*\cptpopnumber#1{%
  \ifntypeTF{#1}{%
    \ifdefTF{#1}{%
      \ifnumcmpTF#1=\z@pt{%
        \cpt@err{Counter or number '\string#1' is already 0}\@ehc
      }{%
        \ifcounterTF#1{%
          \global\advance#1\m@one
        }{%
          \xdef#1{\the\numexpr#1-1}%
        }%
      }%
    }{%
      \cpt@err{Counter or number '\string#1' is undefined}\@ehc
    }%
  }{%
    \cpt@notonetokenerr{#1}%
  }%
}
% #1: calling/base function to push
% #2: comma-separated state list (subsidiary functions) to push
% #3: arbitrary number
\robust@def*\cptpushfunctions#1#2#3{%
  \begingroup
  \def\reserved@a##1##2\push@nil{%
    \ifx\cptpushfunctions##2%
      \cptpushnumber#3%
    \else
      \cpt@notonetokenerr{#3}%
    \fi
  }%
  \reserved@a#3\cptpushfunctions\push@nil
  \toks@{}\@temptokena{}\escapechar-1\relax
  \let\xp\expandcsonce
  \edef\cpt@stack{\string#1@cpt@stack}%
  \ifcsndefTF\cpt@stack{}{\csn@def\cpt@stack{}}%
  % #2 comes with \\ behind each macro to be pushed.
  \def\\##1{%
    \edef\cpt@tempa{\noexpandcsn{\string##1@cpt@\cptrm#3}}%
    \cptexpanded{%
      \toks@{\the\toks@\let\xp\cpt@tempa\noexpand##1}%
      \@temptokena{\the\@temptokena\let\noexpand##1\xp\cpt@tempa
        \undefcs\xp\cpt@tempa}%
    }%
  }%
  #2%
  \csn@xdef\cpt@stack{%
    \the\@temptokena\noexpand\cpt@nil{\expandcsnonce\cpt@stack}%
  }%
  \expandafter\endgroup\the\toks@
}

% #1: calling/base function to pop
% #2: depth counter
\robust@def*\cptpopfunctions#1#2{%
  \ifdefTF{#2}{%
    \ifnum#2=\z@pt
      \cpt@err{Number '\string#2' is currently '0'}\@ehc
    \fi
  }{%
    \cpt@err{Can't pop functions with unknown
      \MsgBrk number \string#2}\@ehc
  }%
  \edef\cpt@stack{\cptremovescape{#1}@cpt@stack}%
  \ifcsndefTF\cpt@stack{%
    \edef\reserved@a{\expandcsnonce\cpt@stack}%
    \def\reserved@b##1\cpt@nil{##1\csn@gdef\cpt@stack}%
    \expandafter\reserved@b\reserved@a
  }{%
    \cpt@err{Unknown stack for function \string#1}\@ehc
    \@gobble
  }%
  \cptpopnumber{#2}%
}
\cptchardef\cpt@optionstacklimit=4\relax
% #1: calling (base) function
% #2: state list (a macro)
% #3: state counter
\robust@def*\cpt@pushstate#1#2#3{%
  \ifnum#3>\cpt@optionstacklimit\relax
    \@latex@error{Current option/key state is being pushed
      \MsgBrk beyond level '\cpt@optionstacklimit'. I suspect infinite
      \MsgBrk re-entrance. If this isn't the case, please
      \MsgBrk set package option 'option-stack-limit' or
      'key-stack-limit' to the required value in
      \MsgBrk\noexpand\documentclass
    }\@ehc
  \fi
  \cptexpandargonce{\cptpushfunctions#1}{#2}{#3}%
}
% #1: calling/base function
% #2: state counter
\robust@def*\cpt@popstate#1#2{\cptpopfunctions{#1}{#2}}
\robust@def*\cpt@stchoose#1#2#3#4{%
  \ifdefboolTF{#1}{%
    \ifmacroTF{#2}{%
      \let#3=#2%
    }{%
      \cpt@err{Bad arguments to macro '\detokenize{#4}'.
        \MsgBrk Token '\detokenize{#2}' not a macro
        \MsgBrk but '\@backslashchar if#1' is true}\@ehc
    }%
  }{%
    \edef#3{\unexpanded{#2}}%
  }%
}
\robust@def*\cptdelimitcs#1#2{%
  \begingroup
  \def\cpt@tempb##1{%
    \edef\cpt@tempa####1{%
      \def####1########1\detokenize{macro:}########2%
        ->########3\cpt@nil{%
        ########1\def\string\cpt@tempa########2%
        \ifblankTF{##1}{}{\string##1}{########3}%
      }%
      \edef####1{####1\meaning#1\cpt@nil}%
    }%
    \cpt@tempa\cpt@tempa
  }%
  \cpt@tempb{}%
  \cpteveryscan
  \scantokens\expandafter{\cpt@tempa}\relax
  \ifcseqTF#1\cpt@tempa{%
    \cpt@tempb{#2}%
    \scantokens\expandafter{\cpt@tempa}\relax
  }{%
    \cpt@err{Your command \noexpand#1 isn't scannable.
      \MsgBrk I needed to delimit its last parameter text}\@ehc
  }%
  % Because of parameters, \postgroupdef can't be used here:
  \gletcs#1\cpt@tempa
  \endgroup
}
% First provide \def\do<params>{<defn>}
% \cptdofunclist[<parser>]{<list>}
% \cptdofunclist*[<parser>]{<listcmd>}
% The command expects \do, which can be multi-parametered.
% Parameters of \do are delimited internally, relieving the user
% of this need. Calling \cptdofunclist is equivalent to defining
% a multi-parametered \do within \csv@do:
\robust@def*\cptdofunclist{%
  \cptpushnumber\dofunclistdepth
  \begingroup
  \edef\sav@do{\cptmakecs{sav@do@\cptrm\dofunclistdepth}}%
  \expandafter\let\sav@do\do
  \expandafter\cptdelimitcs\sav@do\cpt@nil
  \toks@{\def\csv@do##1}%
  \toks1\expandafter{\expandafter\expandafter\sav@do
    \cptrm\ifbracedTF{##1}{0{##1}}{0 ##1}\cpt@nil}%
  \expandafter\expandafter\expandafter\endgroup\expandafter
    \the\expandafter\toks@\expandafter{\the\toks1}%
  \csv@@parse
}
\robust@def*\cptdocommalist{\cpt@testst\cpt@docommalist}
\robust@def*\cpt@docommalist#1#2{%
  \def\csv@do##1{#2}%
  \cptexpanded{\csv@@parse\ifcpt@st*\fi}{#1}%
}
\robust@def*\csv@@loop{\cpt@listparse{01}{01}}
\robust@def*\csv@@parse{\cpt@listparse{00}{01}}
\robust@def*\kv@@loop{\cpt@listparse{01}{00}}
\robust@def*\kv@@parse{\cpt@listparse{00}{00}}
\new@def*\cpt@listparse#1#2{%
  \def\cpt@nmlz{#1}\def\cpt@inkv{#2}%
  \cpt@teststopt\cpt@listp@rse,%
}
\newletcs\cpt@csvnil\relax
\new@def*\cpt@csvnnil{\cpt@csvnil}
\newcommand*\cpt@listp@rse[2][,]{%
  \cpt@stchoose{cpt@st}{#2}\cpt@csvarg\cpt@listparse
  % \cpt@nmlz and \cpt@inkv are used before the commencement
  % of the loop: no need to include them in the state list.
  % \cpt@loopcbk is meant for callbacks with hash characters.
  % It can be defined outside \csv@do or \kv@do and called within
  % \csv@do or \kv@do.
  \cptpushfunctions\cpt@listparse{%
    \\\cpt@listdo\\\curr@do\\\cpt@loopcbk
    \\\ifcpt@useempty\\\ifloopbreak\\\cptdoremainder
  }\cpt@csvdepth
  \letcstocsn\curr@do{\if\cpt@inkv kv\else csv\fi @do}%
  \ifdefTF\curr@do{}{%
    \cpt@err{'\string\csv@do' or '\string\kv@do' is undefined}\@ehc
  }%
  \def\cpt@listdo##1#1{%
    \edef\cpt@csvarg{\expandcsonce{\@gobble##1}}%
    \ifcseqTF\cpt@csvarg\cpt@csvnnil{}{%
      \ifcseqTF\cpt@csvarg\cpt@csvbreak{%
        \loopbreaktrue
      }{%
        \ifcsemptyTF\cpt@csvarg{%
          \ifboolFT{cpt@useempty}{}{\curr@do{}\relax}%
        }{%
          \s@expandarg\curr@do\cpt@csvarg\relax
        }%
      }%
      \ifdefboolTF{loopbreak}
        {\gobble@to@sentinel\cpt@csvnil#1}{\cpt@listdo.}%
    }%
  }%
  \ifswitchFT{cpt@nmlz}{}{%
    \ifcsemptyTF\cpt@csvarg{}{%
      \cpt@sttrue
      \usename{cpt@\ifswitchTF{cpt@inkv}{kv}{csv}normalize}%
      [#1]\cpt@csvarg
    }%
  }%
  \loopbreakfalse
  \expandafter\cpt@listdo\expandafter.\cpt@csvarg#1\cpt@csvnil#1%
  \cptpopfunctions\cpt@listparse\cpt@csvdepth
  \ifnum\cpt@csvdepth=\z@pt
    % So that these functions are defined before the loop is called:
    \undefcs\csv@do\undefcs\kv@do\undefcs\dofunclistdepth
  \fi
}
% #1=keyval list, #2=processor
\robust@def*\kv@@process#1#2{%
  \cptpushfunctions\kv@@process{\\\kv@do\\\ifloopbreak\\#2}\cpt@csvdepth
  \def\kv@do##1,{%
    \defifxTF{##1}\cpt@nnil{}{%
      \def\reserved@a####1={%
        \edef\key@name{\unexpanded{####1}}%
        \def\reserved@a########1=########2\cpt@nil{%
          \edef\key@value{\expandcsonce{\@gobble########1}}%
          \ifx\key@value\cpt@rej
            \cpt@novaltrue\def\key@value{}%
          \else
            \cpt@novalfalse
          \fi
          \cptexpandtwoargsonce{#2}\key@name\key@value
        }%
        \reserved@a.%
      }%
      \reserved@a##1=^?^=\cpt@nil
      \ifloopbreak
        \def\kv@do####1\cpt@nil,{}%
      \fi
      \kv@do
    }%
  }%
  \kv@@normalize{#1}%
  \expandafter\kv@do\normalized@list,\cpt@nil,%
  \cptpopfunctions\kv@@process\cpt@csvdepth
}
\robust@def*\cpt@setupuserdo#1{%
  \ifntypeTF{#1}{%
    \ifmacroTF{#1}{\let\user@do#1}{\cpt@notcserr{#1}}%
  }{%
    \cpt@notonetokenerr{#1}%
  }%
}
\robust@def*\cpt@setupnextindris#1{%
  \def\getnextindris##1#1##2\indris@nil{%
    \if\cpt@incsv
      \edef\nextindris{\expandcsonce{\@gobble##1}}%
    \else
      \edef\nextindris{\s@expandarg\cpttrimspace{\@gobble##1}}%
    \fi
    \letcsntocs{nextindris@\cptrm\indrisdepth}\nextindris
  }%
}
\cptnewvariables{if}{lastindris}[false]
\cptnewvariables{count}{indrisdepth}[\z@pt]
\robust@def*\indrisloop{\cpt@teststopt\cpt@indrisloop,}
% #1: parser
% #2: list
% #3: a one-parameter recurrent macro (eg, \def\do#1{*#1*})
\robust@def*\cpt@indrisloop[#1]#2#3{%
  \cptpushfunctions\indrisloop{%
    \\\indris@do\\\indrisnr\\\iflastindris\\\ifloopbreak
    \\\user@do\\\getnextindris\\\cptdoremainder
  }\cpt@csvdepth
  \advance\indrisdepth\@ne
  \cpt@stchoose{cpt@st}{#2}\cpt@rsvda\indrisloop
  \cpt@sttrue\cpt@csvnormalize[#1]\cpt@rsvda
  \lastindrisfalse\loopbreakfalse
  \chardef\indrisnr\z@pt
  \cpt@setupuserdo{#3}%
  \cpt@setupnextindris{#1}%
  \let\cpt@incsv\cptswtrue
  \def\indris@do##1#1##2\indris@nil{%
    \s@expandarg\ifcsvbreakTF{\@gobble##1}\loopbreak\relax
    \ifdefboolTF{loopbreak}{%
      \cptdoremainder{##2}%
    }{%
      \edef\currindris{\expandcsonce{\@gobble##1}}%
      \letcsntocs{currindris@\cptrm\indrisdepth}\currindris
      \edef\indrisnr{\the\numexpr\indrisnr+1}%
      \getnextindris.##2\indris@nil
      \ifcseqTF\nextindris\cpt@nnil{%
        \lastindristrue\def\nextindris{}%
        \csn@def{nextindris@\cptrm\indrisdepth}{}%
        \s@expandarg\user@do\currindris\relax
      }{%
        \s@expandarg\user@do\currindris\relax
        \indris@do.##2\indris@nil
      }%
    }%
  }%
  \expandafter\indris@do\expandafter.\cpt@rsvda#1\cpt@nil#1\indris@nil
  \cptpopfunctions\indrisloop\cpt@csvdepth
  \advance\indrisdepth\m@one
}

% #1=list, #2=operator/format
% Eg,
% \def\pkg{%
%   \ifnextcharTF'%
%    {\@firstoftwo{\def\pkgsw{00}\@pkg}}
%    {\def\pkgsw{01}\@pkg}%
% }
% \def\@pkg#1{%
%  \def\do##1{\textcolor{ForestGreen}{\texttt{##1}}}%
%  \cptprintcommalist{#1}\do
%  \if\pkgsw\@space package\ifnum\maxindrisnr>\@ne s\fi\fi
% }
\robust@def*\cptprintcommalist{\cpt@testst\cpt@printcommalist}
\robust@def*\cpt@printcommalist#1#2{%
  \cpt@stchoose{cpt@st}{#1}\cpt@tempa\cptprintcommalist
  \def\print@do##1{%
    \ifnum\indrisnr>\@ne
      \iflastindris
        \edef\maxindrisnr{\number\indrisnr}%
        \@space and\@space
      \else
        ,\@space
      \fi
    \fi
    #2{##1}%
  }%
  \expandafter\indrisloop\expandafter{\cpt@tempa}\print@do
}
%% Robust, multi-level, general-purpose tsv processor:
\robust@def*\tsv@@loop{%
  \let\tsv@inparse\cptswfalse
  \cpt@testst\cpt@tsvparse@a
}
\robust@def*\tsv@@parse{%
  \let\tsv@inparse\cptswtrue
  \cpt@testst\cpt@tsvparse@a
}
\new@def*\cpt@tsvnil{\cpt@tsvnil}
\robust@def\cpt@tsvparse@a#1{%
  \cpt@stchoose{cpt@st}{#1}\cpt@tsvarg\cpt@tsvparse@a
  % Use \cpt@csvdepth here also, to avoid premature undefining
  % of pushed counterparts of \ifcpt@useempty, \ifloopbreak and
  % \cptdoremainder by \cptpopfunctions:
  \cptpushfunctions\tsv@@parse{%
    \\\sav@tsv@do\\\ifcpt@useempty\\\ifloopbreak\\\cptdoremainder
    \\\tsv@inparse
  }\cpt@csvdepth
  \ifdefTF\tsv@do{}{%
    \cpt@err{'\string\tsv@do' is undefined}\@ehc
  }%
  \let\sav@tsv@do\tsv@do
  \loopbreakfalse
  \expandafter\cpt@tsvparse@b\cpt@tsvarg\cpt@tsvnil
  \cptpopfunctions\tsv@@parse\cpt@csvdepth
  \ifnum\cpt@csvdepth=\z@pt
    \undefcs\tsv@do
  \fi
}
\robust@def*\cpt@tsvparse@b{%
  \ifdefboolTF{loopbreak}{%
    \gobble@to@sentinel\cpt@tsvnil{}%
  }{%
    \begingroup
    \let\bgr@up\bgroup
    \let\bgroup\cpt@undefined
    % Don't use \ifnextcharTF here:
    \cpt@ifnextchar\bgr@up\cpt@tsvparse@c\cpt@tsvparse@c
  }%
}
\robust@def\cpt@tsvparse@c#1{%
  \ifcseqTF\@let@token\bgr@up{%
    \endgroup
    \edef\cpt@tsvarg{{\unexpanded{#1}}}%
  }{%
    \endgroup
    \edef\cpt@tsvarg{\usename{cpttrimspace\if\tsv@inparse s\fi}{#1}}%
  }%
  \ifcseqTF\cpt@tsvarg\cpt@tsvnil{}{%
    \ifcseqTF\cpt@tsvarg\cpt@tsvbreak{%
      \loopbreak
    }{%
      \ifcsemptyTF\cpt@tsvarg{%
        \ifcpt@useempty\sav@tsv@do{}\relax\fi
      }{%
        \expandafter\sav@tsv@do\expandafter{\cpt@tsvarg}\relax
      }%
    }%
    \cpt@tsvparse@b
  }%
}
% \tsv@@parse does preserve outer braces but sometimes this
% isn't required, necessitating a call to a brace stripper.
% \siso@@loop strips outer braces in its arguments and
% doesn't trim leading and trailing spaces, but can
% be nested to any level:
\newletcs\cpt@sisonil\relax
\new@def*\cpt@sisonnil{\cpt@sisonil}
\robust@def*\siso@@loop{\cpt@testst\cpt@sisoloop}
\robust@def*\cpt@sisoloop#1{%
  \cpt@stchoose{cpt@st}{#1}\siso@arg\siso@@loop
  % Use \cpt@csvdepth here also, to avoid premature un-defining
  % of pushed counterparts of \ifloopbreak:
  \cptpushfunctions\siso@@loop{\\\sav@siso@do\\\ifloopbreak}\cpt@csvdepth
  \ifdefTF\siso@do{}{\cpt@notdeferr\siso@do}%
  \let\sav@siso@do\siso@do
  \loopbreakfalse
  \expandafter\cpt@sisoloop@a\siso@arg\cpt@sisonil
  \cptpopfunctions\siso@@loop\cpt@csvdepth
  \ifnum\cpt@csvdepth=\z@pt\undefcs\siso@do\fi
}
\robust@def*\cpt@sisoloop@a#1{%
  \edef\siso@arg{\unexpanded{#1}}%
  \ifcseqTF\siso@arg\cpt@sisonnil{}{%
    \ifdefboolTF{loopbreak}{%
      \gobble@to@sentinel\cpt@sisonil{}%
    }{%
      \sav@siso@do{#1}\relax\cpt@sisoloop@a
    }%
  }%
}
\robust@def*\cptdosisolist{\cpt@testst\cpt@dosisolist}
\robust@def*\cpt@dosisolist#1#2{%
  \def\siso@do##1{#2}%
  \cptexpanded{\siso@@loop\ifcpt@st*\fi}{#1}%
}
%
% 1. Any type of parser, argument and delimiter are allowed in \cptforeach.
% 2. It is permissible to use #1, #2, #3, etc, to refer to the elements of
%    list in the callback.
% 3. Control sequences can't be used as delimiters in #2.
% 4. Star (*) suffix implies that <list> is a command.
% 6. This can't be used to fill/complete the list before processing.
%    See keyreader-for package for that feature.
%
% Example:
%
% \newcount\nr
% \cptforeach[;] \xa/\ya/\za \in a1/b1/c1; a2/b2/c2; a3/b3/c3 \do{%
%   \nr\z@pt
%   \cptforeach[,] \xs|\ys|\zs \in s1|t1|u1, s2|t2|u2, s3|t3|u3 \do{%
%     \advance\nr\@ne
%     \ifnum\nr>\@ne\loopbreak\fi
%     \edef\cmda####1{#1#2#3*####1*##1##2##3}%
%     \edef\cmdb####1{\xa\ya\za*####1*\xs\ys\zs}%
%   }%
% }
%
\cptnewcounts[cpt@]{foreachdepth}
\robust@def*\cptforeach{\cpt@teststopt\cpt@foreach,}
\robust@def*\cpt@foreach[#1]#2\in#3\do#4{%
  \begingroup
  \let\if@foreach@st\ifcpt@st
  \global\advance\cpt@foreachdepth\@ne
  \@tempcnta\z@pt\def\cpt@tempc{}%
  \def\cpt@cmds{}\def\cpt@params{}%
  \cpttfor#2\dofor{%
    \ifescapedTF{##1}{%
      \advance\@tempcnta\@ne
      \edef\cpt@cmds{%
        \expandcsonce\cpt@cmds
        \edef\unexpanded{##1}{%
          \noexpand\unexpanded{########\number\@tempcnta}%
        }%
      }%
      \edef\cpt@params{\expandcsonce\cpt@params########\number\@tempcnta}%
      \edef\cpt@tempc{\expandcsonce\cpt@tempc\unexpanded{\\##1}}%
    }{%
      \ifnum\@tempcnta=\z@pt
        \cpt@err{First item of \noexpand\cptforeach can't
          \MsgBrk be a delimiter}\@ehc
      \else
        \ifnum\@tempcnta=\@ne
          \edef\cpt@subparser{\cpttrimspace{##1}}%
        \fi
        \edef\cpt@params{\expandcsonce\cpt@params\unexpanded{##1}}%
      \fi
    }%
  }%
  \edef\cpt@tempb{\unexpanded{#3}}%
  \expandafter\cpt@sttrue\expandafter\cpt@csvnormalize
    \expandafter[\cpt@subparser]\cpt@tempb
  % Add one extra parameter:
  \edef\cpt@params{%
    \expandcsonce\cpt@params
    \cpt@subparser####\the\numexpr\@tempcnta+1\relax
  }%
  % Generate extra subparser list for padding:
  \@tempcnta\z@pt\def\cpt@tempa{}%
  \cptloop
    \edef\cpt@tempa{\cpt@tempa\cpt@subparser}%
    \advance\@tempcnta\@ne
    \ifnum\@tempcnta<8\relax
  \cptrepeat
  \edef\elt{\noexpandcsn{cpt@foreach@do@\romannumeral\cpt@foreachdepth}}%
  \let\cpt@foreach@nil\relax
  \cptexpanded{%
    \endgroup
    \cptpushfunctions\cptforeach{\expandcsonce\cpt@tempc}\cpt@csvdepth
    \def\expandcsonce\elt\expandcsonce\cpt@params\cpt@foreach@nil{%
      \expandcsonce\cpt@cmds\unexpanded{#4}%
    }%
    \def\noexpand\csv@do####1{%
      \expandcsonce\elt####1\cpt@tempa\cpt@foreach@nil
    }%
    \csv@@parse\if@foreach@st*\fi[#1]{\expandcsonce\cpt@tempb}%
  }%
  \cptpopfunctions\cptforeach\cpt@csvdepth
  \global\advance\cpt@foreachdepth\m@ne
}

\robust@def*\cpt@oncurrlevel#1#2{%
  \ifdefTF\curr@level{%
    \ifnum\curr@level=\z@pt
      \cpt@err{'\string\curr@level' is zero}{%
        I can't do anything on zero current level.}%
    \fi
  }{%
    \cpt@err{'\string\curr@level' undefined}\@ehc
  }%
  \cptexpandsecond{#1}
    {\noexpandcsn{\cptgobblescape#2@\romannumeral\curr@level}}%
}
% #1: parser
% #2: token list
\new@def*\csliststack#1#2{%
  \iflacus#2\dolacus\else
    \expandafter\ifnullTF\expandafter{\cptiiofii#2{}}{%
      \ifdefTF{#2}{%
        \ifx#2\@empty\else\expandcsonce{#2}#1\fi
      }{}%
    }{%
      \unexpanded{#2}#1%
    }%
  \fi
}
\newletcs\cptliststack\csliststack
\new@def*\csnliststack#1#2{%
  \ifblankTF{#1}{%
    \expandafter\csliststack\expandafter
      {\expandafter}\csname#2\endcsname
  }{%
    \expandafter\csliststack\expandafter#1\csname#2\endcsname
  }%
}
\robust@def*\cptemptify#1{%
  \ifblankTF{#1}{}{\let#1\@empty}%
}
\robust@def*\cptgemptify#1{%
   \ifblankTF{#1}{}{\global\let#1\@empty}%
}
\robust@def*\genemptify{\cpt@teststcl\cpt@genemptify}
\def\cpt@genemptify#1{%
  \ifblankTF{#1}{}{%
    \ifcpt@cl\global\fi\ifcpt@st\else\long\fi\def#1{}%
  }%
}
\robust@def*\cptemptifycsn{\aftercsname\cptemptify}
\robust@def*\cptgemptifycsn{\global\aftercsname\cptemptify}
\robust@def*\cptemptifycsset{%
  \cpt@testst{\cpt@testcl\cpt@emptifycsset}%
}
\robust@def*\cpt@emptifycsset#1{%
  \cptfor#1\dofor{%
    \ifntypeTF{##1}{%
      \ifescapedTF{##1}{%
        \ifcpt@cl\global\fi\def##1{}%
      }{%
        \cpt@notescapederr{##1}%
      }%
    }{%
      \cpt@notonetokenerr{##1}%
    }%
  }%
}
\robust@def*\cptemptifycsnset{\cpt@testopt\cpt@emptifycsnset{}}
\robust@def*\cpt@emptifycsnset[#1]#2{%
  \cptfor#2\dofor{\csn@def{#1##1}{}}%
}
\AtEndOfPackage{%
  \AfterStartOfDocument{%
    \def\do#1{%
      \ifdefTF#1{%
        \gdef#1{%
          \@latex@error{'\string#1' is a preamble command}
          {Move command '\string#1' to document preamble.}%
        }%
      }{%
        \ifx\relax#1\else
          \cpt@warn{Undefined command '\unexpanded{#1}':
            \MsgBrk appeared in \string\cptonlypreamble}%
        \fi
      }%
    }%
    \cpt@preamblecmdhook
    \gundefcs\cpt@preamblecmdhook
    \gletcs\do\noexpand
  }%
}
\new@def*\cpt@preamblecmdhook{}
\robust@def*\cptonlypreamble#1{%
  \begingroup
  \def\csv@do##1{%
    \ifescapedFT{##1}{%
      \cpt@notescapederr{##1}%
    }{%
      \ifntypeTF{##1}{%
        \xifinsetTF{\detokenize{\do##1}}%
          {\cptoxdetok\cpt@preamblecmdhook}{%
          \cpt@warn{Command '\unexpanded{##1}' multiply
            \MsgBrk submitted to \string\cptonlypreamble:
            ignored}%
        }{%
          \xdef\cpt@preamblecmdhook{\csliststack{}%
            \cpt@preamblecmdhook\unexpanded{\do##1}%
          }%
        }%
      }{%
        \cpt@notonetokenerr{##1}%
      }%
    }%
  }%
  \csv@@parse[,]{#1}%
  \endgroup
}
\new@def*\cpt@newlinespaces{^^J\@spaces\@spaces}
\robust@def*\cptelementcount{\cpt@teststopt\cpt@elemcount,}
\robust@def*\cpt@elemcount[#1]#2{%
  \begingroup
  \def\cptelemnr{0}%
  \edef\reserved@a{\ifcpt@st*\fi}%
  \def\csv@do##1{%
    \edef\cptelemnr{\the\numexpr\cptelemnr+1}%
  }%
  \expandafter\csv@@loop\reserved@a[#1]{#2}%
  \postgroupdef\cptelemnr\endgroup
}
% Eg, \ifelemcountTF[;](>)[2]{a;b;c}{T}{F};
% * -> #4 is a macro
\robust@def*\ifelemcountTF{\cpt@teststopt\cpt@ifelemcount@a,}
\robust@def*\cpt@ifelemcount@a[#1]{%
  \cpt@testpnopt{\cpt@ifelemcount@b{#1}}=%
}
\robust@def*\cpt@ifelemcount@b#1(#2){%
  \cpt@testopt{\cpt@ifelemcount@c{#1}{#2}}1%
}
\robust@def*\cpt@ifelemcount@c#1#2[#3]#4{%
  \begingroup
  \@tempcnta\z@pt
  \edef\reserved@a{\ifcpt@st*\fi}%
  \def\csv@do##1{%
    \advance\@tempcnta\@ne
  }%
  \expandafter\csv@@loop\reserved@a[#1]{#4}%
  \aftercsname\endgroup{@\ifnum\@tempcnta#2#3 %
    first\else second\fi oftwo}%
}
\robust@def*\cptfindduplicates{\cpt@teststopt\cpt@findduplicates,}
\robust@def*\cpt@findduplicates[#1]#2{%
  \begingroup
  \edef\reserved@a{\ifcpt@st*\fi}%
  \edef\parser{\detokenize{#1}}%
  \def\cpt@currstack{}\gdef\duplicates{}%
  \def\csv@do##1{%
    \xifinsetTF{\detokenize{#1##1#1}}
      {\parser\cptoxdetok\cpt@currstack\parser}{%
      \xdef\duplicates{\csliststack#1\duplicates\unexpanded{##1}}%
    }{%
      \edef\cpt@currstack{\csliststack#1\cpt@currstack\unexpanded{##1}}%
    }%
  }%
  \expandafter\csv@@parse\reserved@a[#1]{#2}%
  \ifcsemptyTF\duplicates
    {\endgroup\@firstoftwo}{\endgroup\@secondoftwo}%
}
\new@def*\ifcsnullTF#1{%
  \ifblankTF{#1}\@secondoftwo{%
    \oifblankTF{\@gobble#1}{%
      \ifcseqTF#1\@empty
    }{%
      \@secondoftwo
    }%
  }%
}
\new@def*\ifcsnullFT#1{\ifcsnullTF{#1}\cptiiofii\cptiofii}
\new@def*\oifcsnullTF#1{\expandafter\ifcsnullTF\expandafter{#1}}
\new@def*\oifcsnullFT#1{\expandafter\ifcsnullFT\expandafter{#1}}
\new@def\ifcsemptyTF#1{%
  \expandafter\ifcseqTF\cpt@car#1\@undefined\car@nil\@empty
}
\new@def*\ifcsnnullTF#1{%
  \ifblankTF{#1}{%
    \@secondoftwo
  }{%
    \ifcsndefTF{#1}{%
      \expandafter\ifx\csname#1\endcsname\@empty
        \expandafter\@firstoftwo
      \else
        \expandafter\@secondoftwo
      \fi
    }{%
      \@secondoftwo
    }%
  }%
}
\new@def*\ifcsnnullFT#1{\ifcsnnullTF{#1}\cptiiofii\cptiofii}
\new@def*\ifdefnotnullTF#1{%
  \ifdefTF{#1}{%
    \ifcsnullTF{#1}\cptiiofii\cptiofii
  }{%
    \@secondoftwo
  }%
}
\new@def*\ifcsndefnotnullTF#1{%
  \ifcsndefTF{#1}{%
    \ifcsnnullTF{#1}\cptiiofii\cptiofii
  }{%
    \@secondoftwo
  }%
}
\new@def*\expandcsonce#1{\unexpanded\expandafter{#1}}
\new@def*\expandcsnonce#1{\aftercsname\expandcsonce{#1}}
\new@def*\expandcstwice#1{\unexpanded\cptthreexp{#1}}
\new@def*\expandcsntwice#1{\aftercsname\expandcstwice{#1}}
\new@def*\noexpandcsn#1{\expandcsonce{\csname#1\endcsname}}
\newletcs\cptmakecs=\noexpandcsn
\new@def*\cptoxdetok#1{\detokenize\expandafter{#1}}
\new@def*\cpttxdetok#1{\detokenize\cptthreexp{#1}}
\new@def*\cptsxdetok#1{\detokenize\cptsevenxp{#1}}
\robust@def\cptpassexpanded#1{%
  \begingroup\protected@edef\x{\endgroup#1}\x
}
\newletcs\cptexpanded=\cptpassexpanded
\robust@def\cptpassunexpanded#1{\begingroup\long\def\x{\endgroup#1}\x}
\robust@def*\cptexpandarg#1#2{\cptpassexpanded{\unexpanded{#1}{#2}}}
\robust@def*\cptexpandargonce#1#2{%
  \cptpassexpanded{\unexpanded{#1}{\expandcsonce{#2}}}%
}
\robust@def*\cptexpandsecond#1#2{\cptpassexpanded{\unexpanded{#1}#2}}
\robust@def*\cptexpandsecondonce#1#2{%
  \cptpassexpanded{\unexpanded{#1}\expandcsonce{#2}}%
}
\robust@def*\cptexpandsecondarg#1#2#3{%
  \cptpassexpanded{\unexpanded{#1#2}{#3}}%
}
\robust@def*\cptexpandsecondargonce#1#2#3{%
  \cptpassexpanded{\unexpanded{#1#2}{\expandcsonce{#3}}}%
}
\robust@def*\cptexpandtwoargs#1#2#3{%
  \cptpassexpanded{\unexpanded{#1}{#2}{#3}}%
}
\robust@def*\cptexpandtwoargsonce#1#2#3{%
  \cptpassexpanded
  {\unexpanded{#1}{\expandcsonce{#2}}{\expandcsonce{#3}}}%
}
\robust@def*\StyleFileRCSInfo$#1 #2 #3 #4 #5 #6 #7 #8 ${%
  \def\cpt@filedate{#4}%
  \def\cpt@fileversion{v#3}%
  \def\cpt@filetime{#5}%
  \def\cpt@fileauthor{#6\@space#7}%
}
\new@def*\cpt@filedesc{}
\defpass\reserved@a#1{%
  \robust@def*\StyleFilePurpose##1{%
    \gdef\cpt@filedesc{##1#1(\cpt@fileauthor)}%
  }%
}{ }
\new@def*\StyleFileInfo{%
  \cpt@filedate\@space\cpt@fileversion\@space\cpt@filedesc
}
\robust@def*\SetStyleFileMessages{%
  \begingroup
  \catcode`\ =9\catcode`\^^I=9\relax
  \edef\cpt@tempa{\expandafter\@carcube\@currname\@nil @}%
  \def\cpt@tempb{\@testopt{\expandafter\endgroup
    \cpt@SetStyleFileMessages}}%
  \expandafter\cpt@tempb\expandafter{\cpt@tempa}%
}
\robust@def*\cpt@SetStyleFileMessages[#1]#2#3#4{%
  \begingroup
  \def\cpt@tempa##1{\noexpandcsn{##1}}%
  \protected\def\cpt@tempb{\global\protected\@namedef}%
  \edef\cpt@tempc{\ifx\@currext\@pkgextension Package\else Class\fi}%
  \@tempswafalse
  \cptfor#2,#3,#4\dofor{%
    \ifcsname#1##1\endcsname
      \edef\undefinablecs{#1##1}\@tempswatrue\forbreaktrue
    \fi
  }%
  \if@tempswa
    \cpt@notdefinable
  \else
    \cptpassexpanded{%
      \cpt@tempb{#1#2}####1{\cpt@tempa{\cpt@tempc Info}%
        {\@currname}{####1\noexpand\@gobble}}%
      \cpt@tempb{#1#3}####1{\cpt@tempa{\cpt@tempc WarningNoLine}%
        {\@currname}{####1}}%
      \cpt@tempb{#1#4}####1####2{\cpt@tempa{\cpt@tempc Error}%
        {\@currname}{####1}{####2}}%
    }%
  \fi
  \endgroup
}
\SetStyleFileMessages[cpt@]{info}{warn}{err}
\new@def*\ifboolTF#1{%
  \ifblankTF{#1}{%
    \cpt@err{Empty boolean}\@ehc
  }{%
    \ifcsndefTF{if#1}{%
      \ifdefboolTF{#1}%
    }{%
      \cpt@err{Boolean '\@backslashchar#1' undefined}\@ehc
    }%
  }%
}
\new@def*\ifdefboolFT#1{\ifdefboolTF{#1}\cptiiofii\cptiofii}
\new@def*\ifdefboolTF#1{%
  \usename{@\usename{if#1}first\else second\fi oftwo}%
}
\new@def*\ifboolFT#1{\ifboolTF{#1}\cptiiofii\cptiofii}
\new@def*\ifgroupboolTF#1{%
  \ifboolTF{#1}{\endgroup\cptiofii}{\endgroup\cptiiofii}%
}
\new@def*\ifbooleanTF#1#{%
  \ifntypeTF{#1}{%
    \ifescapedTF{#1}{%
      \ifboolTF{\cptremovescape#1}\cptiofii\cptiiofii
    }{%
      \cpt@notescapederr
    }%
  }{%
    \cpt@notonetokenerr{#1}%
  }%
}
\new@def\cptiterate#1\cptrepeat{\cpt@iterate\@gobble{#1}}
\newletcs\cptloop=\cptiterate
\newletcs\cptrepeat\fi
\new@def\cpt@iterate\@gobble#1{%
  #1\relax\expandafter\cpt@iterate\fi\@gobble{#1}%
}
\new@def\cptwhileexpr#1\do#2{%
  #1 \cptswap{#2\cptwhileexpr{#1}\do{#2}}\fi
}
\new@def*\cpt@numlt#1<{#1<\numexpr}
\new@def*\cpt@numgt#1>{#1>\numexpr}
\new@def*\cpt@numeq#1={#1=\numexpr}
\new@def*\cpt@dimlt#1<{#1<\dimexpr}
\new@def*\cpt@dimgt#1>{#1>\dimexpr}
\new@def*\cpt@dimeq#1={#1=\dimexpr}
% Don't put \numexpr in the arg #2 when calling \cptwhilenum:
\new@def*\cptwhilenum#1\do#2{%
	\ifnum\numexpr\cpt@numlt\cpt@numgt\cpt@numeq#1%
  \cpt@removetonnil<=>\cpt@nnil\relax
  \cptswap{#2\cptwhilenum{#1}\do{#2}}\fi
}
% Don't put \dimexpr in the arg #2 when calling \cptwhiledim:
\new@def*\cptwhiledim#1\do#2{%
	\ifdim\dimexpr\cpt@dimlt\cpt@dimgt\cpt@dimeq#1%
  \cpt@removetonnil<=>\cpt@nnil\relax
  \cptswap{#2\cptwhiledim{#1}\do{#2}}\fi
}
\new@def*\ifnumcmpTF#1#{%
  \usename{@\ifnum\numexpr\cpt@numlt\cpt@numgt\cpt@numeq#1%
  \cpt@removetonnil<=>\cpt@nnil first\else second\fi oftwo}%
}
\new@def*\ifnumcmpFT#1#{\usename{@\ifnumcmpTF#1{second}{first}oftwo}}
\new@def*\ifdimcmpTF#1#{%
  \usename{@\ifdim\dimexpr\cpt@dimlt\cpt@dimgt\cpt@dimeq#1%
  \cpt@removetonnil<=>\cpt@nnil first\else second\fi oftwo}%
}
\new@def*\ifdimcmpFT#1#{\usename{@\ifdimcmpTF#1{second}{first}oftwo}}
% Define control sequences to check for a token (eg, dash):
% \cpt@defcheck<cs><testtoken>\cpt@nil
\robust@def*\cpt@defcheck#1#2\cpt@nil{%
  \new@def*#1##1\cpt@nil{%
    \begingroup
    \def\cpt@tempa####1#2####2\cpt@nil{\endgroup
      \usename{@\ifblankTF{####2}{second}{first}oftwo}%
    }%
    \cpt@tempa##1#2\cpt@nil
  }%
}
\cpt@defcheck\cpt@checkeq=\cpt@nil
%%--
% Define control sequences to split tokens (eg, at a dash):
% \cpt@defsplit@at<cs><splitter/testtoken>\cpt@nil
\robust@def*\cpt@defsplit@at#1#2\cpt@nil{%
  \def#1##1\cpt@nil{%
    \begingroup
    \def\cpt@tempa####1#2####2\cpt@nil{\endgroup
      \def\lpt{####1}\def\rpt{####2}%
    }%
    \ifinsetTF{#2}{##1}{%
      \cpt@tempa##1#2\cpt@nil
    }{%
      \def\lpt{##1}\def\rpt{}%
    }%
  }%
}
\cpt@defsplit@at\cpt@split@ateq=\cpt@nil

% Define a control sequence to check for the presence
% of a suffix in/for another control sequence:
\robust@def\DefSuffixChecker#1#2#3#4{%
  \long\gdef#1##1##2##3##4{%
    \begintoksgroup
    \def\cpt@tempa{%
      \ifstrcmpTF{##4}{#2}{%
        \ifstrcmpTF{##2##3}{#3#4}{%
          \toks@{##1##4##2##3}%
        }{%
          \ifstrcmpTF{##2##3}{#4#3}{%
            \toks@{##1##4##3##2}%
          }{%
            \ifntypeTF{##2}{%
              \ifntypeTF{##3}{%
                \toks@{##1##2##3##4}%
              }{%
                \toks@{##1##2{##3}##4}%
              }%
            }{%
              \ifntypeTF{##3}{%
                \toks@{##1{##2}##3##4}%
              }{%
                \toks@{##1{##2}{##3}##4}%
              }%
            }%
          }%
        }%
      }{%
        \cpt@tempb
      }%
    }%
    \def\cpt@tempb{%
      \ifstrcmpTF{##4}{#3}{%
        \ifstrcmpTF{##2##3}{#2#4}{%
          \toks@{##1##2##4##3}%
        }{%
          \ifstrcmpTF{##2##3}{#4#2}{%
            \toks@{##1##3##4##2}%
          }{%
            \toks@{##1##2##3##4}%
          }%
        }%
      }{%
        \cpt@tempc
      }%
    }%
    \def\cpt@tempc{%
      \ifstrcmpTF{##4}{#4}{%
        \ifstrcmpTF{##2##3}{#2#3}{%
          \toks@{##1##2##3##4}%
        }{%
          \ifstrcmpTF{##2##3}{#3#2}{%
            \toks@{##1##3##2##4}%
          }{%
            \toks@{##1##2##3##4}%
          }%
        }%
      }{%
        \cpt@tempd
      }%
    }%
    \def\cpt@tempd{%
      \ifstrcmpTF{##3}{#2}{%
        \ifstrcmpTF{##2}{#3}{%
          \ifntypeTF{##4}{%
            \toks@{##1##3##2##4}%
          }{%
            \toks@{##1##3##2{##4}}%
          }%
        }{%
          \cpt@tempi
        }%
      }{%
        \cpt@tempe
      }%
    }%
    \def\cpt@tempe{%
      \ifstrcmpTF{##3}{#3}{%
        \ifstrcmpTF{##2}{#2}{%
          \ifntypeTF{##4}{%
            \toks@{##1##2##3##4}%
          }{%
            \toks@{##1##2##3{##4}}%
          }%
        }{%
          \cpt@tempi
        }%
      }{%
        \cpt@tempf
      }%
    }%
    \def\cpt@tempf{%
      \ifntypeTF{##4}{\toks1{##4}}{\toks1{{##4}}}%
      \cpt@tempg
    }%
    \def\cpt@tempg{%
      \ifntypeTF{##3}{%
        \ifntypeTF{##2}{%
          \cpt@temph{##1##2##3}%
        }{%
          \cpt@temph{##1{##2}##3}%
        }%
      }{%
        \ifntypeTF{##2}{%
          \cpt@temph{##1##2{##3}}%
        }{%
          \cpt@temph{##1{##2}{##3}}%
        }%
      }%
    }%
    \def\cpt@temph####1{%
      \cptexpanded{\toks@{\unexpanded{####1}\the\toks1}}%
    }%
    \def\cpt@tempi{%
      \ifstrcmpTF{##2}{#4}{%
        \ifntypeTF{##4}{%
          \toks@{##1##3##2##4}%
        }{%
          \toks@{##1##3##2{##4}}%
        }%
      }{%
        \ifntypeTF{##4}{%
          \toks@{##1##2##3##4}%
        }{%
          \toks@{##1##2##3{##4}}%
        }%
      }%
    }%
    \cpt@tempa
    \endtoksgroup
  }%
}
\DefSuffixChecker\cpt@checkoptprefix{*}{+}{!}
\new@def*\ifnumoddTF#1#{%
  \usename{@\ifodd#1\@empty first\else second\fi oftwo}%
}
\new@def*\ifnumoddFT#1#{%
  \usename{@\ifnumoddTF#1{second}{first}oftwo}%
}
\newletcs\ifnumevenTF\ifnumoddFT
\robust@def*\cptnumexpr{\cpt@testcl{\cpt@numexpr{num}}}
\robust@def*\cptdimexpr{\cpt@testcl{\cpt@numexpr{dim}}}
\robust@def*\cptglueexpr{\cpt@testcl{\cpt@numexpr{glue}}}
\robust@def*\cptmuexpr{\cpt@testcl{\cpt@numexpr{mu}}}
\new@def*\cpt@numexpr#1#2#3{%
  \ifntypeTF{#2}{}{\cpt@notonetokenerr{#2}}%
  \ifescapedTF{#2}{}{\cpt@notescapederr{#2}}%
  \ifdefTF{#2}{%
    \ifcpt@cl\global\fi#2=\usename{#1expr}#3\relax\relax
  }{%
    \def\reserved@a##1#1##2##3\@nil{%
      \usename{new##2}#2\relax
    }%
    \reserved@a num{count}dim{dimen}glue{skip}mu{muskip}\@nil
    \ifcpt@cl\global\fi#2=\usename{#1expr}#3\relax\relax
  }%
}
\robust@def*\cptnumdef{\cpt@testcl{\cpt@numdef{num}}}
\robust@def*\cptdimdef{\cpt@testcl{\cpt@numdef{dim}}}
\robust@def*\cptgluedef{\cpt@testcl{\cpt@numdef{glue}}}
\robust@def*\cptmudef{\cpt@testcl{\cpt@numdef{mu}}}
\new@def*\cpt@numdef#1#2#3{%
  \ifntypeTF{#2}{}{\cpt@notonetokenerr{#2}}%
  \ifescapedTF{#2}{}{\cpt@notescapederr{#2}}%
  \ifcpt@cl\global\fi\edef#2{\the\usename{#1expr}#3}%
}
\robust@def*\cptnumadd{\cpt@testcl{\cpt@numadd{num}}}
\robust@def*\cptdimadd{\cpt@testcl{\cpt@numadd{dim}}}
\robust@def*\cptglueadd{\cpt@testcl{\cpt@numadd{glue}}}
\robust@def*\cptmuadd{\cpt@testcl{\cpt@numadd{mu}}}
\new@def*\cpt@numadd#1#2#3{%
  \ifntypeTF{#2}{}{\cpt@notonetokenerr{#2}}%
  \ifescapedTF{#2}{}{\cpt@notescapederr{#2}}%
  \ifdefTF{#2}{%
    \ifcpt@cl\global\fi\edef#2{\the\usename{#1expr}#2+#3}%
  }{%
    \ifcpt@cl\global\fi\edef#2{\the\usename{#1expr}#3}%
  }%
}
\robust@def*\csnnumdef{\cpt@testcl{\aftercsname{\cpt@numdef{num}}}}
\robust@def*\csndimdef{\cpt@testcl{\aftercsname{\cpt@numdef{dim}}}}
\robust@def*\csnnumadd{\cpt@testcl{\aftercsname{\cpt@numadd{num}}}}
\robust@def*\csndimadd{\cpt@testcl{\aftercsname{\cpt@numadd{dim}}}}
\new@edef*\cpt@leftbracechar{%
  \expandafter\@car\string{\@nil\iffalse}\fi
}
\new@edef*\cpt@rightbracechar{%
  \iffalse{\fi\expandafter\@car\string}\@nil
}
\newcommand\xifstrcmpTF[2]{%
  \usename{@\ifnum\cpt@pdfstrcmp{#1}{#2}=0first\else
    second\fi oftwo}%
}
\new@def\xifstrcmpFT#1#2{\xifstrcmpTF{#1}{#2}\cptiiofii\cptiofii}
\new@def\oifstrcmpTF#1#2{%
  \expandafter\cptswapbracefirst\expandafter{#1}
  {\expandafter\ifstrcmpTF\expandafter{#2}}%
}
\robust@def\oifstrcmp@sp@TF#1#2{%
  \ifntypeTF{#1}{%
    \ifexpandableTF{#1}{%
      \ifntypeTF{#2}{%
        \ifexpandableTF{#2}{%
          \oifstrcmpTF{#1}{#2}%
        }{%
          \cpt@notexpandableerr{#2}%
          \@secondoftwo
        }%
      }{%
        \cpt@notonetokenerr{#2}%
        \@secondoftwo
      }%
    }{%
      \cpt@notexpandableerr{#1}%
      \@secondoftwo
    }%
  }{%
    \cpt@notonetokenerr{#1}%
    \@secondoftwo
  }%
}
\robust@def\oifstrcmpFT#1#2{%
  \oifstrcmpTF{#1}{#2}\cptiiofii\cptiofii
}
% Expandable:
\new@def\ifstreqTF#1#2{%
  \expandafter\cptswap\expandafter
  {\expandafter{\romannumeral-`\q\cpttrimspaces{#1}}}
  {\expandafter\ifstrcmpTF\expandafter
  {\romannumeral-`\q\cpttrimspaces{#2}}}%
}
\robust@def\ifstreqFT#1#2{\ifstreqTF{#1}{#2}\cptiiofii\cptiofii}
\robust@def\oifstreqTF#1#2{\cptexpandtwoargsonce\ifstreqTF{#1}{#2}}
\robust@def\oifstreqFT#1#2{\cptexpandtwoargsonce\ifstreqFT{#1}{#2}}
\robust@def\xifstreqTF#1#2{\cptexpandtwoargs\ifstreqTF{#1}{#2}}
\robust@def\xifstreqFT#1#2{\cptexpandtwoargs\ifstreqFT{#1}{#2}}
\new@def*\ifleftbracedTF#1{%
  \ifblankTF{#1}{%
    \@secondoftwo
  }{%
    \usename{@\if\expandafter\cpt@car\detokenize{#1}\car@nil
      \expandafter\cpt@car\string{\car@nil\ifnum0=`}\fi
      first\else second\fi oftwo}%
  }%
}
\new@def*\ifdefeqTF#1#2{%
  \ifdefTF{#1}{%
    \ifdefTF{#2}{%
      \usename{@\ifx#1#2first\else second\fi of oftwo}%
    }\@secondoftwo
  }\@secondoftwo
}
\new@def\ifdefeqFT#1#2{\ifdefeqTF{#1}{#2}\cptiiofii\cptiofii}
\new@def\ifcateqTF#1#{\usename{@\ifcat#1first\else second\fi oftwo}}
% Expand and detokenize before comparison:
\new@def\ifcharcmpTF#1#2{%
  \ifntypeTF{#1}{%
    \ifntypeTF{#2}{%
      \usename{@\if\detokenize\expandafter{\romannumeral\expandafter
        \cptswap\expandafter{\romannumeral-`\q#2}{-`\q#1}}%
        first\else second\fi oftwo}%
    }{%
      \cpt@notonetokenerr{#2}\@secondoftwo
    }%
  }{%
    \cpt@notonetokenerr{#1}\@secondoftwo
  }%
}
\new@def\ifexpandableTF#1#2#3{%
  \romannumeral\ifleftbracedTF{#1}\@secondoftwo{%
  \ifblankTF{#1}\@secondoftwo{\expandafter\ifx\noexpand#1#1%
  \expandafter\@secondoftwo\else\expandafter\@firstoftwo\fi}}%
  {0 #2}{0 #3}%
}

% Test if #1 is a single, non-space and non-braced token:
\new@def\ifntypeTF#1{%
  \if0\cpt@pdfstrcmp{\detokenize\expandafter{\cptalloftwo#1{}{}}}%
    {\detokenize{#1{}}}%
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
\new@def\ifsingletokenTF#1#2#3{%
  \romannumeral\ifblankTF{#1}\@secondoftwo{%
    \ifbracedTF{#1}\@secondoftwo{%
      \ifleadspaceTF{#1}{%
        \expandafter\ifblankTF\expandafter{\@gobblespace#1}%
      }{%
        \expandafter\ifblankTF\expandafter{\@gobble#1}%
      }%
      \cptiofii\cptiiofii
    }%
  }{0 #2}{0 #3}%
}
\new@def\ifsingletokenFT#1{\ifntypeTF{#1}\cptiiofii\cptiofii}
% Don't test for \ifleadspaceTF:
\new@def\ifsingleindrisTF#1{%
  \romannumeral
  \ifblankTF{#1}{%
    0 \cptiiofii
  }{%
    % Eat one token and take the rest to \cpt@ifsingleindris:
    \expandafter
    \cpt@ifsingleindris\cpt@cdr#1\cdr@nil\single@nil{#1}%
  }%
}
\new@def\cpt@ifsingleindris#1\single@nil#2{%
  \ifblankTF{#1}{%
    \xifstrcmpTF{\expandafter\cpt@car
    \detokenize{#2}x\car@nil}\cpt@leftbracechar
      {0 \cptiiofii}{0 \cptiofii}%
  }{0 \cptiiofii}%
}
\robust@def*\ifsingledigitTF#1{%
  \begingroup
  \let\@@nil\relax
  \edef\cpt@tempa##1{\def##1####1\detokenize{#1}####2####3\@@nil}%
  \cpt@tempa\cpt@tempa{%
    \endgroup
    \csname @\ifx##20first\else second\fi oftwo\endcsname
  }%
  \edef\cpt@tempb{00 01 02 03 04 05 06 07 08 09 0\detokenize{#1}}%
  \expandafter\cpt@tempa\cpt@tempb\relax\@@nil
}
\new@def*\cpt@parserlist{,;:/|*><=-+"'}
\robust@def*\cpt@checklistparser#1#2{%
  \ifmacroTF{#1}{%
    \ifcpt@verbose
      \cpt@info{Parser '\detokenize{#1}' is a macro}\@ehc
    \fi
  }{%
    \ifntypeTF{#1}{%
      \xifinsetTF{\detokenize{#1}}\cpt@parserlist{%
        #2% Don't put \relax here!
      }{%
        \cpt@listparsererr{#1}%
      }%
    }{%
      \cpt@listparsererr{#1}%
    }%
  }%
}
\robust@def*\cpt@ch@cklistparser#1{%
  \ifblankTF{#1}{%
    \cpt@listparsererr{#1}%
  }{%
    % if #1 is a single token:
    \ifsecondisnnilTF{#1}{%
      \xifinsetTF{\detokenize{#1}}\cpt@parserlist{}{%
        \cpt@listparsererr{#1}%
      }%
    }{%
      \cpt@listparsererr{#1}%
    }%
  }%
}
\robust@def*\cpt@listparsererr#1{%
  \cpt@err{Invalid list parser '\detokenize{#1}'}\@ehc
}
\robust@def*\postgroupdef#1\endgroup{%
  \cptpassexpanded{\endgroup\cpt@csexit{#1}}%
}
\robust@def*\postgroupcsndef#1\endgroup{%
  \aftercsname\postgroupdef{#1}\endgroup
}
% #1: macro;
% #2: arbitrary token (eg, \endgroup):
\robust@def*\cptpassacross#1#2{%
  \cptpassexpanded{\unexpanded{#2}\cpt@csexit#1}%
}
\new@def*\cpt@csexit#1{\edef\noexpand#1{\ox@unexpanded{#1}}}
\new@def*\ox@unexpanded#1{\noexpand\unexpanded{\expandcsonce{#1}}}
\robust@def*\cptaftergroup#1{%
  \advance\@tempcnta\@ne
  \csn@xdef{cpt@aftergroup@\romannumeral\@tempcnta}{%
    \gundefcsn{cpt@aftergroup@\romannumeral\@tempcnta}%
    \unexpanded\ifblankTF{#1}{}\expandafter{#1}%
  }%
  \aftercsname\aftergroup{cpt@aftergroup@\romannumeral\@tempcnta}%
}
\robust@def\cptafterassignment#1{%
  \begingroup
  \advance\@tempcnta\@ne
  \csn@xdef{cpt@afterassignment@\romannumeral\@tempcnta}{%
    \gundefcsn{cpt@afterassignment@\romannumeral\@tempcnta}%
    \unexpanded\ifblankTF{#1}{}\expandafter{#1}%
  }%
  \aftercsname{\endgroup\afterassignment}
    {cpt@afterassignment@\romannumeral\@tempcnta}%
}
\robust@def*\cptexpandmacro#1#2{%
  \ifntypeTF{#1}{%
    \ifmacroTF{#1}{%
      \ifexpandableTF{#1}{%
        \simpleexpandarg\cptexpandmacro{#1}#2%
      }{%
        \edef#2{\unexpanded{#1}}%
      }%
    }{%
      \edef#2{\unexpanded{#1}}%
    }%
  }{%
    \edef#2{\unexpanded{#1}}%
  }%
}
% Expandable:
\new@def*\cptexpandcs#1{%
  \ifntypeTF{#1}{%
    \ifmacroTF{#1}{%
      \ifexpandableTF{#1}{%
        \simpleexpandarg\cptexpandcs{#1}%
      }{%
        \noexpand#1%
      }%
    }{%
      \noexpand#1%
    }%
  }{%
    \unexpanded{#1}%
  }%
}
% Expandable full expand; strips braces and leading
% spaces, but not trailing spaces:
\begingroup
\catcode`\&=7
\new@gdef*\cptfullexpand#1{%
	\romannumeral\cpt@fullexpand{#1}{}%
}
\new@gdef*\cpt@fullexpand#1{%
	\expandafter\cpt@f@llexp@nd\romannumeral\cpt@f@llexpand#1&%
}
\new@gdef*\cpt@f@llexpand#1{%
  \ifmacroTF{#1}{%
    \ifexpandableTF{#1}{%
      \expandafter\cpt@f@llexpand\expandafter{#1}%
    }{%
      0 #1%
    }%
  }{%
    0 #1%
  }%
}
\new@gdef*\cpt@f@llexp@nd#1#2&#3{%
	\ifblankTF{#2}{0 #3#1}{\cpt@fullexpand{#2}{#3#1}}%
}
\endgroup

% [<fallback>]{<teststr>}{<{str1}{act1}{str2}{act2}...>}
% Expandable:
\new@def*\cptifstreqcase#1{\cpt@xtestopt{#1}\cpt@ifstreqcase{}}
\new@def\cpt@ifstreqcase[#1]#2#3{%
  \expandafter\cptswapbracefirst\expandafter{#2}%
    {\cpt@ifstreqc@se#3\cpt@mil\cpt@mil\cpt@nil}{#1}%
}
\new@def\cpt@ifstreqc@se#1#2#3\cpt@nil#4#5{%
  \ifblankTF{#3}{#5}{%
    \ifstrcmpTF{#1}{#4}{#2}{%
      \cpt@ifstreqc@se#3\cpt@nil{#4}{#5}%
    }%
  }%
}
% #1: test string (choice)
% #2: nominations and callbacks, eg, {{a}1,{b}2,{ x }3}
% #3: no-match fallback
% Expandable:
\new@def\cptcheckchoice#1#2#3{%
  \expandafter\cptswapbracefirst\expandafter
  {\romannumeral-`\q\cpttrimspace{#1}}
  {\cpt@checkchoice#2,\cpt@mil\cpt@mil,\cpt@nil}{#3}%
}
\new@def\cpt@checkchoice#1#2,#3\cpt@nil#4#5{%
  \ifblankTF{#3}{\unexpanded{#5}}{%
    \xifstrcmpTF{\cpttrimspace{#1}}{\unexpanded{#4}}{%
      \unexpanded{#2}%
    }{%
      \cpt@checkchoice#3\cpt@nil{#4}{#5}%
    }%
  }%
}
% Test if <str1>, etc, is in <teststr>
% [<default act>]{<teststr>}{<{str1}{act1}{str2}{act2}...>}
\new@def*\cptifstrpresentcase#1{\cpt@xtestopt{#1}\cpt@ifstrincase{}}
\new@def\cpt@ifstrincase[#1]#2#3{%
  \expandafter\cptswapbracefirst\expandafter{#2}%
    {\cpt@ifstrinc@se#3\cpt@mil\cpt@mil\cpt@nil}{#1}%
}
\new@def\cpt@ifstrinc@se#1#2#3\cpt@nil#4#5{%
  \ifblankTF{#3}{#5}{%
    \ifinsetTF{#1}{#4}{#2}{%
      \cpt@ifstrinc@se#3\cpt@nil{#4}{#5}%
    }%
  }%
}
\new@def\do@else@part\do#1#2\endif{\unexpanded{#1}}
\new@def\all@to@endif#1\endif{\unexpanded{#1}}
\new@def\first@to@endif#1#2\endif{\unexpanded{#1}}
\new@def\gobble@to@endif#1\endif{}
\new@def*\ifcassedimcmpTF#1#2#3{\ifdimcmpTF#1#2{#3}}
\new@def*\ifcassenumcmpTF#1#2#3{\ifnumcmpTF#1#2{#3}}
% Eg,
% \edef\x{%
%   \cptifcasse\ifstrcmpTF{teststr}
%     {str1}{case1 callback}
%     {str2}{case2 callback}
%   \ifnone
%     no match
%   \endif
% }
% \edef\x{%
%   \cptifcasse\ifcassenumcmpTF{testnum}
%     {=2}{equal to 2}
%     {<3}{less than 3}
%     {>4}{greater than 4}
%   \ifnone
%     no match
%   \endif
% }
% The comparator command is any test command that yields
% <iofii> or <iiofii> but \ifnumcmpTF can't be used directly.
% Use \ifcassenumcmpTF instead. The user can also define his own
% logical test command and pass it to \cptifcasse, eg,
% \def\test#1#2{\ifinsetTF{#2}{#1}}
\new@def*\cptifcasse#1#2{%
  \ifstrcmpTF{#1}\ifnone{%
    \all@to@endif
  }{%
    \ifstrcmpTF{#1}\endif{}{%
      \ifstrcmpTF{#2}\ifnone{%
        \all@to@endif
      }{%
        \ifstrcmpTF{#2}\endif{}{\cpt@ifcasse{#1}{#2}}%
      }%
    }%
  }%
}
\new@def*\cpt@ifcasse#1#2#3{%
  \ifstrcmpTF{#3}\ifnone{%
    \all@to@endif
  }{%
    \ifstrcmpTF{#3}\endif{}{%
      #1{#2}{#3}\first@to@endif{\cpt@ifcasse@i{#1}{#2}}%
    }%
  }%
}
\new@def*\cpt@ifcasse@i#1#2#3{\cpt@ifcasse{#1}{#2}}

% Eg,
% \edef\x{%
%   \cptdocasse\ifcassedimcmpTF{1pt+2pt+3pt}
%     {=2pt}\do{equal to 2pt}
%   \elseif
%     {<3pt}\do{less than 3pt}
%   \elseif
%     \do{no match}
%   \endif
% }
% \edef\x{%
%   \cptdocasse\ifcassenumcmpTF{1+2+3}
%     {=2}\do{equal to 2}
%   \elseif
%     {<3}\do{less than 3}
%   \elseif
%     \do{no match}
%   \endif
% }
% \edef\x{%
%   \cptdocasse\ifcassenumcmpTF{5}
%     {=2}\do{equal to 2}
%   \elseif
%     {<3}\do{less than 3}
%   \elseif
%     {>4}\do{greater than 4}
%   \elseif
%     \do{no match}
%   \endif
% }
% \edef\x{%
%  \cptdocasse\ifstrcmpTF{x}
%    a\do{\def\y{a}}
%  \elseif
%    b\do{\def\y{b}}
%  \elseif
%  \endif
% }
\new@def*\cptdocasse#1#2{%
  \ifstrcmpTF{#1}\elseif{%
    \gobble@to@endif
  }{%
    \ifstrcmpTF{#1}\endif{}{%
      \ifstrcmpTF{#2}\elseif{%
        \gobble@to@endif
      }{%
        \ifstrcmpTF{#2}\endif{}{\cptdocasse@i{#1}{#2}}%
      }%
    }%
  }%
}
\new@def*\cptdocasse@i#1#2#3{%
  \ifstrcmpTF{#3}\elseif{%
    \cptdocasse@i{#1}{#2}%
  }{%
    \ifstrcmpTF{#3}\endif{}{%
      \ifstrcmpTF{#3}\do{%
        \do@else@part\do
      }{%
        \cptdocasse@ii{#1}{#2}{#3}%
      }%
    }%
  }%
}
\new@def*\cptdocasse@ii#1#2#3\do#4{%
  \ifstrcmpTF{#4}\elseif{%
    \cptdocasse@ii{#1}{#2}%
  }{%
    \ifstrcmpTF{#4}\endif{}{%
      #1{#2}{#3}{%
        \unexpanded{#4}%
        \gobble@to@endif
      }{%
        \cptdocasse@i{#1}{#2}%
      }%
    }%
  }%
}

\robust@def\cpt@in#1#2{%
  \long\def\in@@##1#1##2\in@@{%
    \edef\in@@{\unexpanded{##2}}%
    \ifx\in@@\@empty\cpt@infalse\else\cpt@intrue\fi
  }%
  \in@@#2{\in@@}#1\in@@
}
\robust@def\cptiffound#1\in#2\then{%
  \cptexpandtwoargs\cpt@in{\cpttrimspace{#1}}{\cpttrimspace{#2}}%
  \ifcpt@in
}
\robust@def\ifinsetTF#1#2{%
  \cpt@in{#1}{#2}%
  \usename{@\ifcpt@in first\else second\fi oftwo}%
}
\robust@def\ifinsetFT#1#2{\ifinsetTF{#1}{#2}\cptiiofii\cptiofii}
\robust@def\oifinsetTF#1#2{\cptexpandtwoargsonce\ifinsetTF{#1}{#2}}
\robust@def\oifinsetFT#1#2{\oifinsetTF{#1}{#2}\cptiiofii\cptiofii}
\robust@def\xifinsetTF#1#2{\cptexpandtwoargs\ifinsetTF{#1}{#2}}
\robust@def\xifinsetFT#1#2{\xifinsetTF{#1}{#2}\cptiiofii\cptiofii}
\robust@def\oifinset@sp@TF#1#2#3{%
  \begingroup
  \edef\parser{\detokenize{#1}}%
  \edef\x{{\parser\cptoxdetok{#2}\parser}%
    {\parser\ifdefTF{#3}{\cptoxdetok{#3}}{}\parser}}%
  \expandafter\endgroup\expandafter\ifinsetTF\x
}
\robust@def\oifinset@sp@FT#1#2#3{%
  \oifinset@sp@TF{#1}{#2}{#3}\cptiiofii\cptiofii
}
\robust@def*\cptifpattern#1\in#2{%
  \ifntypeTF{#2}{%
    \ifdefTF{#2}{%
      \ifblankTF{#1}{%
        \@secondoftwo
      }{%
        \xifinsetTF{\detokenize{#1}}{\meaning#2}%
      }%
    }{%
      \@secondoftwo
    }%
  }{%
    \cpt@notonetokenerr{#2}%
  }%
}
% \cptaddtolist[<parser>]<\cs>{<newitem>}
% *     -> use \protected@(e)xdef.
% uadd  -> don't expand <newitem> at all.
% oadd  -> expand <newitem> once.
% xadd  -> fully expand <newitem>.
% gadd  -> add globally.
\robust@def*\cptuaddtolist{\cpt@teststopt{\cpt@addtolist\unexpanded{e}},}
\robust@def*\cptguaddtolist{\cpt@teststopt{\cpt@addtolist\unexpanded{x}},}
\robust@def*\cptoaddtolist{\cpt@teststopt{\cpt@addtolist\expandcsonce{e}},}
\robust@def*\cptgoaddtolist{\cpt@teststopt{\cpt@addtolist\expandcsonce{x}},}
\robust@def*\cptxaddtolist{\cpt@teststopt{\cpt@addtolist\@firstofone{e}},}
\robust@def*\cptgxaddtolist{\cpt@teststopt{\cpt@addtolist\@firstofone{x}},}
\newletcs\cptaddtolist\cptuaddtolist
\newletcs\cptgaddtolist\cptguaddtolist
\robust@def\cpt@addtolist#1#2[#3]#4#5{%
  \ifcpt@check\cpt@checklistparser{#3}\relax\fi
  \begingroup
  \toks@{\endgroup
    \ifdefTF#4{%
      \ifdefboolTF{cpt@st}{%
        \usename{protected@#2def}#4{\csliststack#3#4#1{#5}}%
      }{%
        \usename{#2def}#4{\csliststack#3#4#1{#5}}%
      }%
    }{%
      \ifdefboolTF{cpt@st}{%
        \usename{protected@#2def}#4{#1{#5}}%
      }{%
        \usename{#2def}#4{#1{#5}}%
      }%
    }%
  }%
  \ifblankTF{#5}{%
    \ifcpt@useempty\the\toks@\else\endgroup\fi
  }{%
    \the\toks@
  }%
}
\robust@def*\cptapptomacro{\cpt@testst{\cpt@hooktomacro>}}
\robust@def*\cptpreptomacro{\cpt@testst{\cpt@hooktomacro<}}
\robust@def\cpt@hooktomacro#1#2#3{%
  \cpt@getmacroprefix{#2}%
  \ifcpt@st\let\reserved@a\expandcsonce\else\let\reserved@a\unexpanded\fi
  \ifdefTF{#2}{%
    \ifx#1>%
      \macroprefix\edef#2{\expandcsonce{#2}\reserved@a{#3}}%
    \else
      \macroprefix\edef#2{\reserved@a{#3}\expandcsonce{#2}}%
    \fi
  }{%
    \macroprefix\edef#2{\reserved@a{#3}}%
  }%
}
% #1 : optional list parser
% #2 : control sequence of main list
% #3 : sublist to remove (not cs)
% #4 : filter/wrapper
\robust@def*\cptfilterremovecsv{%
  \begingroup
  \let\cpt@inkv\cptswfalse
  \let\temp@parse\csv@@parse
  \cpt@testopt\cpt@filterremoveelements{,}%
}
\robust@def*\cptfilterremovekv{%
  \begingroup
  \let\cpt@inkv\cptswtrue
  \let\temp@parse\kv@@parse
  \cpt@testopt\cpt@filterremoveelements{,}%
}
\robust@def*\cpt@filterremoveelements[#1]#2#3#4{%
  \edef\temp@do
    {\cptmakecs{\ifxTF\temp@parse\csv@@parse{csv}{kv}@do}}%
  \cptdeclarefilter{#4}%
  \ifdefTF{#2}{}{\def#2{}}%
  \edef\cpt@delete{\unexpanded{#3}}%
  \ifcsnullTF\cpt@delete{}{%
    \cpt@sttrue
    \usename{cpt@\if\cpt@inkv k\else cs\fi vnormalize}[#1]\cpt@delete
  }%
  \edef\cpt@tempd##1{%
    {\detokenize{#1}\noexpand\cptoxdetok{##1}\detokenize{#1}}%
    {\detokenize{#1}\cptoxdetok\cpt@delete\detokenize{#1}}%
  }%
  \def\cpt@tempc{}%
  \expandafter\def\temp@do##1{%
    \edef\cpt@tempa{\unexpanded{##1}}%
    \cpt@usefilter\cpt@tempa\cpt@tempb
    % no \oifinset@sp@TF here (see detokenization above):
    \expandafter\xifinsetTF\cpt@tempd\cpt@tempb{}{%
      \cptuaddtolist[#1]\cpt@tempc{##1}%
    }%
  }%
  \ifcsnullTF#2{}{%
    \ifcsnullTF\cpt@delete{}{%
      \temp@parse*[#1]#2%
    }%
  }%
  \let#2\cpt@tempc
  \postgroupdef#2\endgroup
}
\robust@def*\cptdeclarefilter#1{%
  \edef\cpt@usefilter##1##2{%
    \ifblankTF{#1}{\let##2=##1}{%
      \ifcseqTF#1\relax{\let##2=##1}{%
        \ifstrcmpTF{#1}\nofilter{\let##2=##1}{%
          \unexpanded{#1}{##1}{##2}%
        }%
      }%
    }%
  }%
}
% #1 : parser
% #2 : old list (a control sequence) of parser-separated list
% #3 : new update (a non-command list)
% #4 : element-wise filter/wrapper
\newletcs\everymergeitem=\@iden
\robust@def*\cptfiltermergecsv{%
  \begingroup
  \let\temp@parse\csv@@parse
  \cpt@testopt\cpt@filtermergelists{,}%
}
\robust@def*\cptfiltermergekv{%
  \begingroup
  \let\temp@parse\kv@@parse
  \cpt@testopt\cpt@filtermergelists{,}%
}
\robust@def*\cpt@filtermergelists[#1]#2#3#4{%
  \edef\temp@do{%
    \cptmakecs{\ifcseqTF\temp@parse\csv@@parse{csv}{kv}@do}%
  }%
  \cptdeclarefilter{#4}%
  \ifdefTF{#2}{}{\def#2{}}%
  \ifblankTF{#3}{%
    \def\cpt@update{}%
  }{%
    \edef\cpt@update{\unexpanded{#3}}%
  }%
  \def\cpt@add##1{%
    \edef#2{\csliststack#1#2\everymergeitem{\expandcsonce{##1}}}%
  }%
  \expandafter\def\temp@do##1{%
    \cpt@choicefdfalse
    \edef\cpt@merge@a{\unexpanded{##1}}%
    \cpt@usefilter\cpt@merge@a\cpt@merge@b
    \expandafter\def\temp@do####1{%
      \edef\cpt@merge@c{\unexpanded{####1}}%
      \cpt@usefilter\cpt@merge@c\cpt@merge@d
      \cptscancs\cpt@merge@b
      \cptscancs\cpt@merge@d
      \ifx\cpt@merge@b\cpt@merge@d
        \cpt@choicefdtrue\cpt@add\cpt@merge@a
      \else
        \cpt@add\cpt@merge@c
      \fi
    }%
    \cptexpandargonce{\def#2{}\temp@parse[#1]}#2%
    \ifdefboolTF{cpt@choicefd}{}{\cpt@add\cpt@merge@a}%
  }%
  \ifcsnullTF#2{%
    \edef#2{\expandcsonce\cpt@update}%
  }{%
    \ifcsnullTF\cpt@update{}{%
      \temp@parse*[#1]\cpt@update
    }%
  }%
  \postgroupdef#2\endgroup
  \let\everymergeitem\@firstofone
  % No need to undefine \temp@parse, \temp@do, etc:
  % they have been defined in a local group.
}
\cptnewvariables{switch}[cpt@]{fromrepl,fromrem}[false]

% See also \cptfilterremovecsv:
% #1 : optional list parser
% #2 : listcmd
% #3 : single element to remove
% * -> remove all occurrences of #3
\robust@def*\cptremoveoneelement{\cpt@teststopt\cpt@removeoneelement,}
\robust@def\cpt@removeoneelement[#1]#2#3{%
  \begingroup
  \let\ifremovest\ifcpt@st
  \edef\pser{\detokenize{#1}}%
  \def\cpt@remove@a##1{%
    \def\cpt@remove@b####1#1##1#1####2\remove@nil{%
      \edef#2{\unexpanded{####1#1####2}}%
      \cpt@trimparsers[#1]#2%
    }%
    \xifinsetTF{\detokenize{#1##1#1}}{\pser\cptoxdetok{#2}\pser}{%
      \expandafter\cpt@remove@b\expandafter#1#2#1\remove@nil
      % If removing all occurrences:
      \ifdefboolTF{removest}{%
        \expandafter\cpt@remove@a\expandafter{\cpt@remove@c}%
      }{}%
    }{}%
  }%
  \ifdefswitchTF{cpt@fromrem}{%
    % We're coming from \cptremoveelements, #3 has been
    % trimmed and #2 has already been normalized:
    \edef\cpt@remove@c{\unexpanded{#3}}%
  }{%
    \cpt@sttrue\cpt@csvnormalize[#1]#2%
    \edef\cpt@remove@c{\cpttrimspaces{#3}}%
  }%
  \let\cpt@remove@d#2%
  \expandafter\cpt@remove@a\expandafter{\cpt@remove@c}%
  \ifdefswitchTF{cpt@fromrem}{}{%
    \ifx\cpt@remove@d#2\ifcpt@verbose
      \cpt@warn{The list in \noexpand#2 not updated:
        \MsgBrk perhaps something was wrong}%
    \fi\fi
  }%
  \postgroupdef#2\endgroup
}
% #1 : optional list parser
% #2 : control sequence of list
% #3 : sublist to remove
\robust@def*\cptremoveelements{\cpt@teststopt\cpt@removeelements,}
\robust@def\cpt@removeelements[#1]#2#3{%
  \begingroup
  \edef\cpt@resa{\ifcpt@st*\fi}%
  \let\cpt@fromrem\cptswtrue
  \cpt@sttrue\cpt@csvnormalize[#1]#2%
  \long\def\csv@do##1{%
    \expandafter\cptremoveoneelement\cpt@resa[#1]#2{##1}%
  }%
  \csv@@parse[#1]{#3}%
  \postgroupdef#2\endgroup
}
% \cptreplaceoneelement[<parser>]{<cs>}{<search>}{<replace>}
% #1: optional list parser
% #2: control sequence of list
% #3: single item to replace
% #4: item to substitute
% * -> replace all occurrences
\robust@def*\cptreplaceoneelement{\cpt@teststopt\cpt@replaceoneelement,}
\robust@def\cpt@replaceoneelement[#1]#2#3#4{%
  \begingroup
  \let\ifreplst\ifcpt@st
  \edef\pser{\detokenize{#1}}%
  \def\cpt@replace@a##1{%
    \def\cpt@replace@b####1#1##1#1####2\rep@nil{%
      \edef#2{\unexpanded{####1#1#4#1####2}}%
      \cpt@trimparsers[#1]#2%
    }%
    \xifinsetTF{\detokenize{#1##1#1}}{\pser\cptoxdetok#2\pser}{%
      \expandafter\cpt@replace@b\expandafter#1#2#1\rep@nil
      % If replacing all occurrences of #3 in #2:
      \ifdefboolTF{replst}{%
        \expandafter\cpt@replace@a\expandafter{\cpt@replace@c}%
      }{}%
    }{}%
  }%
  \ifdefswitchTF{cpt@fromrepl}{%
    % We're coming from \cptreplaceelements, #3 has been
    % trimmed and #2 has already been normalized:
    \edef\cpt@replace@c{\unexpanded{#3}}%
  }{%
    \cpt@sttrue\cpt@csvnormalize[#1]#2%
    \edef\cpt@replace@c{\cpttrimspaces{#3}}%
  }%
  \let\cpt@replace@d#2%
  \expandafter\cpt@replace@a\expandafter{\cpt@replace@c}%
  \ifdefswitchTF{cpt@fromrepl}{}{%
    \ifx\cpt@replace@d#2%
      \ifcpt@verbose
        \cpt@warn{The list in \noexpand#2 not updated:
          \MsgBrk something was wrong}%
      \fi
    \fi
  }%
  \postgroupdef#2\endgroup
}
% #1: optional list parser
% #2: listcmd
% #3: items to replace
% #4: items to substitute
% * -> replace all occurrences
\robust@def*\cptreplaceelements{\cpt@teststopt\cpt@replaceelements,}
\robust@def\cpt@replaceelements[#1]#2#3#4{%
  \begingroup
  \edef\cpt@replace@a{\unexpanded{#3}}%
  \edef\cpt@replace@b{\unexpanded{#4}}%
  \edef\cpt@replace@c{\ifcpt@st*\fi}%
  \cptfor#2,\cpt@replace@a,\cpt@replace@b\dofor{%
    \cpt@sttrue\cpt@csvnormalize[#1]##1%
  }%
  \def\cpt@replace@d##1#1##2\noboundary##3#1##4\noboundary{%
    \expandafter\cptreplaceoneelement\cpt@replace@c[#1]#2{##1}{##3}%
    \ifblankTF{##2}{}{%
      \ifblankTF{##4}{}{%
        \cpt@replace@d##2\noboundary##4\noboundary
      }%
    }%
  }%
  \let\cpt@fromrepl\cptswtrue
  \cptexpandsecond\cpt@replace@d{%
    \expandcsonce\cpt@replace@a#1\noboundary
    \expandcsonce\cpt@replace@b#1\noboundary
  }%
  \postgroupdef#2\endgroup
}
\robust@def*\csnnewif#1{%
  \ifstrcmpTF{#1}{x}{%
    \cpt@err{Redefining '\cptmakecs{ifx}'?}\@ehc
  }{%
    \usename{newif\cptthreexp}\usename{if#1}%
  }%
}
\robust@def*\csn@def{\aftercsname\def}
\robust@def*\csn@gdef{\aftercsname\gdef}
\robust@def*\csn@edef{\aftercsname\edef}
\robust@def*\csn@xdef{\aftercsname\xdef}
\robust@def*\csndef{\cpt@starorlong{\cpt@csndef{}{}{}}}
\robust@def*\csnpdef{\cpt@starorlong{\cpt@csndef{}{p}{}}}
\robust@def*\csngdef{\cpt@starorlong{\cpt@csndef{}{}{g}}}
\robust@def*\csnpgdef{\cpt@starorlong{\cpt@csndef{}{p}{g}}}
\robust@def*\csnedef{\cpt@starorlong{\cpt@csndef{}{}{e}}}
\robust@def*\csnpedef{\cpt@starorlong{\cpt@csndef{}{p}{e}}}
\robust@def*\csnxdef{\cpt@starorlong{\cpt@csndef{}{}{x}}}
\robust@def*\csnpxdef{\cpt@starorlong{\cpt@csndef{}{p}{x}}}
\robust@def*\newcsndef{\cpt@starorlong{\cpt@csndef{n}{}{}}}
\robust@def*\newcsnpdef{\cpt@starorlong{\cpt@csndef{n}{p}{}}}
\robust@def*\newcsngdef{\cpt@starorlong{\cpt@csndef{n}{}{g}}}
\robust@def*\newcsnpgdef{\cpt@starorlong{\cpt@csndef{n}{p}{g}}}
\robust@def*\newcsnedef{\cpt@starorlong{\cpt@csndef{n}{}{e}}}
\robust@def*\newcsnpedef{\cpt@starorlong{\cpt@csndef{n}{p}{e}}}
\robust@def*\newcsnxdef{\cpt@starorlong{\cpt@csndef{n}{}{x}}}
\robust@def*\newcsnpxdef{\cpt@starorlong{\cpt@csndef{n}{p}{x}}}
\new@def*\cpt@csndef#1#2#3#4{%
  \if#1n\relax
    \ifcsndefTF{#4}{%
      \def\undefinablecs{#4}\cpt@notdefinable
    }{}%
  \fi
  \if#2p\relax\let\reserved@a\protected\else
    \let\reserved@a\relax\fi
  \reserved@a\l@ngrel@x\aftercsname\aftercsname{#3def}{#4}%
}
\robust@def*\letcsntocs#1{\cptthreexp\let\usename{#1}}
\robust@def*\gletcsntocs#1{\global\cptthreexp\let\usename{#1}}
\robust@def*\letcstocsn#1#2{%
  \begingroup\expandafter\endgroup\expandafter
  \let\expandafter#1\csname#2\endcsname
}
\robust@def*\gletcstocsn#1#2{%
  \begingroup\expandafter\endgroup\expandafter\global
  \expandafter\let\expandafter#1\csname#2\endcsname
}
\robust@def*\letcsntocsn#1#2{%
  \begingroup\expandafter\endgroup
  \expandafter\let\csname#1\expandafter
  \endcsname\csname#2\endcsname
}
\robust@def*\gletcsntocsn#1#2{%
  \begingroup\expandafter\endgroup\expandafter
  \global\expandafter\let\csname#1\expandafter
  \endcsname\csname#2\endcsname
}
\robust@def*\globalize#1{\gletcs#1#1}
\robust@def*\globalizecsn#1{%
  \begingroup\expandafter\endgroup\expandafter
  \global\expandafter\let\csname#1\expandafter\endcsname
  \csname#1\endcsname
}
\robust@def*\undefcs#1{\let#1\cpt@undefined}
\robust@def*\gundefcs{\global\undefcs}
\robust@def*\undefcsn#1{\aftercsname\undefcs{#1}}
\robust@def*\gundefcsn{\global\undefcsn}
\robust@def*\undefcsset{\cpt@testst{\cpt@testcl\cpt@undefcsset}}
\robust@def*\cpt@undefcsset#1{%
  \cpt@stchoose{cpt@st}{#1}\cpt@rsvda\undefcsset
  \expandafter\cptfor\cpt@rsvda\dofor{%
    \ifntypeTF{##1}{%
      \ifescapedTF{##1}{%
        \ifcpt@cl\global\fi\undefcs##1%
      }{%
        \cpt@notescapederr{##1}%
      }%
    }{%
      \cpt@notonetokenerr{##1}%
    }%
  }%
}
% #1: parser, #2: listcmd
% This is one way to preserve braces in #2:
\robust@def*\cpttrimleadparsers#1#2{%
  \ifblankTF{#1}{%
    \cpt@err{Empty parser in \string\cpttrimleadparsers}\@ehc
  }{}%
  \begingroup
  \ifcat$\detokenize\expandafter\expandafter\expandafter
    {\expandafter\@gobble#2.}$\cptbgobbletorelax\fi
  \def\reserved@e##1#1{%
    \edef\reserved@a{\unexpanded\expandafter{\@gobble##1}}%
    \ifx\reserved@a\@empty
      \def\next{\reserved@e.}%
    \else
      \def\@next####1#1\noboundary
        {\edef#2{\unexpanded\expandafter{\@gobble####1}}}%
      \edef\next{\unexpanded{\@next##1#1}}%
    \fi
    \next
  }%
  \expandafter\reserved@e\expandafter.#2#1\noboundary
  \postgroupdef#2\endgroup\cpt@relax
}
% #1: parser, #2: list command
\robust@def\cpttrimtrailparsers#1#2{%
  \begingroup
  \def\cpt@trima{%
    \xifinsetTF{\detokenize{#1}\noboundary}
      {\cptoxdetok{#2}\noboundary}{%
      \def\reserved@a####1#1\noboundary{%
        \edef#2{\expandcsonce{\@gobble####1}}%
        \cpt@trima
      }%
      \expandafter\reserved@a\expandafter.#2\noboundary
    }{}%
  }%
  \cpt@trima
  \postgroupdef#2\endgroup
}
\robust@def*\cpttrimparsers{\cpt@testopt\cpt@trimparsers,}
\robust@def*\cpt@trimparsers[#1]#2{%
  \ifntypeTF{#1}{%
    \cpttrimleadparsers{#1}#2%
    \cpttrimtrailparsers{#1}#2%
  }{%
    \cpt@notonetokenerr{#1}%
  }%
}
% #1: token on command, #2: test token:
\robust@def\cpt@stripsuffix#1#2{%
  \ifblankTF{#2}{%
    \cpt@err{Blank test token for \string\cpt@stripsuffix}\@ehc
  }{%
    \edef\reserved@a{%
      \ifblankTF{#1}{}{\ifstrcmpTF{#1}{#2}{}{\unexpanded{#1}}}%
    }%
  }%
}
% Strip #1 number of outer braces in #2; return result in #3:
\robust@def*\cptstripNouterbraces{\cpt@testopt\cpt@stripouterbraces\@ne}
\newletcs\cptstripnbr\cptstripNouterbraces
\robust@def*\cpt@stripouterbraces[#1]{%
  \begingroup
  \def\end@def##1##2##3{\postgroupdef##3\endgroup}%
  \@tempcnta\z@pt
  \catcode`\{=1
  \catcode`\}=2
  \catcode`\#=6
  \cpt@str@pouterbraces{#1}%
}
\robust@def\cpt@str@pouterbraces#1#2#3{%
  \advance\@tempcnta\@ne
  \edef#3{\unexpanded{#2}}%
  \cpt@str@pouterbr@ces#2\strip@nil{#3}{#1}%
}
\robust@def\cpt@str@pouterbr@ces#1\strip@nil#2#3{%
  \defifxTF{#1}#2{%
    \end@def
  }{%
    \ifnum\@tempcnta>#3\relax
      \expandafter\end@def
    \else
      \expandafter\cpt@str@pouterbraces
    \fi
  }%
  {#3}{#1}{#2}%
}
\robust@def\cptstripallouterbraces#1#2{%
  \edef#2{\unexpanded\cptthreexp{\cpt@stripallouterbraces#1\strip@nil}}%
}
\newletcs\cptstripallbr\cptstripallouterbraces
\robust@def\cptstripallouterbracesincs#1{%
  \expandafter\cptstripallouterbraces\expandafter{#1}#1%
}
\newletcs\cptstripallbrincs\cptstripallouterbracesincs
\robust@def\cpt@stripallouterbraces#1\strip@nil{%
  \romannumeral\ifbracedTF{#1}{%
    \expandafter\ifnullTF\expandafter{\@gobble#1}{%
      \expandafter\@gobble\cpt@stripallouterbraces#1\strip@nil
    }{0 #1}%
  }{0 #1}%
}
\robust@def\cpt@starafter#1#2{%
  \begingroup
  \def\cpt@tempa{#1}%
  \def\cpt@tempb##1{#1{#2}}%
  \def\cpt@tempc{\futurelet\next\cpt@staract}%
  \cpt@tempc
}
\new@def*\cpt@staract{%
  \ifcseqTF\@sptoken\next{%
    \afterassignment\cpt@tempc\let\next= %
  }{%
    \cptexpandsecond\endgroup{%
      \ifcseqTF*\next{\expandcsonce\cpt@tempb}%
        {\expandcsonce\cpt@tempa}%
    }%
  }%
}
\robust@def*\cptbracearg{\cpt@testopt\cpt@bracearg\@ne}
\robust@def\cpt@bracearg[#1]#2#3{%
  \begingroup
  \@tempcnta\z@pt
  \loop
    \edef#3{\unexpanded{{#2}}}%
    \advance\@tempcnta\@ne
    \ifnum\@tempcnta<#1\relax
  \repeat
  \postgroupdef#3\endgroup
}
% Expandable:
\edef\ifmacroTF#1{%
  \noexpand\ifblankTF{#1}{%
    \noexpand\@secondoftwo
  }{%
    \noexpand\ifleftbracedTF{#1}{%
      \noexpand\@secondoftwo
    }{%
      \unexpanded{\expandafter\cpt@ifmacro\meaning}%
      #1\detokenize{macro}:\cpt@nil
    }%
  }%
}
\new@def*\ifmacroFT#1{\ifmacroTF{#1}\cptiiofii\cptiofii}
\new@def*\oifmacroTF#1{\simpleexpandarg\ifmacroTF{#1}}
\new@def*\ifcsnmacroTF{\aftercsname\ifmacroTF}
\edef\cpt@ifmacro{%
  \def\noexpand\cpt@ifmacro##1\detokenize{macro}:##2\cpt@nil
}
\cpt@ifmacro{\usename{@\ifblankTF{#2}{second}{first}oftwo}}

\new@def*\csnmeaning#1{\aftercsname\meaning{#1}}
\robust@def*\ifescapedTF#1{%
  \begingroup
  \escapechar92\relax
  \edef\x{\expandafter\cpt@car\string#1x\car@nil}%
  \aftercsname\endgroup
  {@\ifx\x\@backslashchar first\else second\fi oftwo}%
}
\robust@def*\ifescapedFT#1{\ifescapedTF{#1}\cptiiofii\cptiofii}
% \robustaliascount counts the number of 'robustified' commands.
% It may be used to set a threshold for the no. of allowable
% aliases. \cptrobustify avoids \scantokens, because some commands
% aren't scannable:
\cptchardef\maxrobustalias50
\robust@def*\cptrobustify#1{%
  \def\csv@do##1{%
    \ifescapedTF{##1}{%
      \ifdefTF{##1}{%
        \cptpushnumber\robustaliascount
        \ifnum\robustaliascount<\maxrobustalias\relax
          \ifcsndefTF{robbase@\cptgobblescape##1}{%
            \cpt@warn{Command '\string##1' is already robust:
              \MsgBrk not made robust again}%
          }{%
            \letcsntocs{robbase@\cptgobblescape##1}##1%
            \protected\edef##1{\cptmakecs{robbase@\cptgobblescape##1}}%
          }%
        \else
          \cpt@err{Maximum number '\number\maxrobustalias' of
            robust command aliases exceeded:\MsgBrk
            You can set \noexpand\maxrobustalias higher}\@ehc
        \fi
      }{%
        \cpt@notdeferr{##1}%
      }%
    }{%
      \cpt@notescapederr{##1}%
    }%
  }%
  \csv@@parse[,]{#1}%
}
\robust@def*\leftaddtocs{%
  \let\cpt@def\edef\let\swap\cptswap\cpt@addtocs
}
\robust@def*\gleftaddtocs{%
  \let\cpt@def\xdef\let\swap\cptswap\cpt@addtocs
}
\robust@def*\rightaddtocs{%
  \let\cpt@def\edef\let\swap\cptalloftwo\cpt@addtocs
}
\robust@def*\grightaddtocs{%
  \let\cpt@def\xdef\let\swap\cptalloftwo\cpt@addtocs
}
\robust@def*\rightaddtocsn{\aftercsname\rightaddtocs}
\robust@def*\grightaddtocsn{\aftercsname\grightaddtocs}
\robust@def*\leftaddtocsn{\aftercsname\leftaddtocs}
\robust@def*\gleftaddtocsn{\aftercsname\gleftaddtocs}
\robust@def\cpt@addtocs#1#2{%
  \ifntypeTF{#1}{%
    \ifescapedTF{#1}{%
      \ifdefTF#1{%
        \cpt@getmacroprefix{#1}%
        \macroprefix\cpt@def
          #1{\swap{\expandcsonce{#1}}{\unexpanded{#2}}}%
      }{%
        \cpt@def#1{\unexpanded{#2}}%
      }%
    }{%
      \cpt@notescapederr{#1}%
    }%
  }{%
    \cpt@notonetokenerr{#1}%
  }%
  \undefcs\cpt@def\undefcs\swap
}
\robust@def*\cpteveryscan{%
  \everyeof{\noexpand}%
  \endlinechar\m@one
  \makeatletter
  \catcode`\ =10
  \catcode`\\\z@pt
  \catcode`\{\@ne
  \catcode`\}\tw@
}
% #1 must be a non-parametered macro:
\robust@def*\cptscancs#1{%
  \begingroup
  \edef#1{\long\def\string#1{\cptoxdetok{#1}}}%
  \cpteveryscan
  \scantokens\expandafter{#1}\relax
  \postgroupdef#1\endgroup
}
\newletcs\cptscantokens\cptscancs
\begingroup
  \lccode`\A =`\@ %
  \lccode`\B =`\@ %
  \catcode`\A = 8 %
  \catcode`\B = 3 %
\lowercase{\endgroup\def\cpt@rescan@marker{AB}}
\robust@def*\cptrescan{\cpt@rescan@a\def}
\robust@def*\cptgrescan{\cpt@rescan@a\gdef}
% #1 = \def or \gdef
% #2 = command to receive the re-scanned stuff
% #3 = arbitrary code to execute before \scantokens
% #4 = stuff to rescan
\robust@def*\cpt@rescan@a#1#2#3#4{%
  \begingroup
  \everyeof\expandafter{\cpt@rescan@marker\noexpand}%
  \endlinechar\m@one\newlinechar\m@one
  #3%
  \cptexpanded{\endgroup
    #1\noexpand#2{%
      \expandafter\cpt@rescan@b\expandafter\@empty
      \scantokens\expandafter{#4}%
    }%
  }%
}
\edefpass\reserved@a{%
  % The \expandafter here is to get rid of \@empty:
  \def\noexpand\cpt@rescan@b##1\cpt@rescan@marker{%
    \noexpand\unexpanded\noexpand\expandafter{##1}%
  }%
}
\robust@def*\cpt@lowercasecs#1{%
  \ifmacroTF{#1}{%
    \cptexpandarg\lowercase{\def\noexpand#1{#1}}%
  }{%
    \cpt@notcserr{#1}%
  }%
}
\robust@def*\cptprovidecount#1{%
  \ifescapedTF{#1}{%
    \ifdefTF{#1}{%
      \ifcounterTF{#1}{}{%
        \cpt@warn{Command '\noexpand#1' is already
          \MsgBrk defined but not a counter}%
      }%
    }{%
      \newcount#1%
    }%
  }{%
    \cpt@notescapederr{#1}%
  }%
}
\robust@def*\cptprovidedimen#1{%
  \ifescapedTF{#1}{%
    \ifdefTF{#1}{%
      \ifdimenTF{#1}{}{%
        \cpt@warn{Command '\noexpand#1' is already
          \MsgBrk defined but not a dimension}%
      }%
    }{%
      \newdimen#1%
    }%
  }{%
    \cpt@notescapederr{#1}%
  }%
}
\robust@def*\newtog#1{\cpt@testopt{\cpt@newtog{#1}}{false}}
\new@def*\cpt@newtog#1[#2]{%
  \ifinsetTF{,}{#1}{%
    \cpt@err{Command \noexpand\newtog doesn't accept list}
      {Please submit only one toggle to \noexpand\newtog.
      \MsgBrk You can use \noexpand\cptnewvariables
      for multiple toggles.}%
  }{}%
  \ifcsndefTF{cpt@tog@#1}{%
    \cpt@err{Toggle '#1' already defined}%
      {Please provide a new toggle.}%
  }{}%
  \cpt@gettogstate{#2}%
  \letcsntocs{cpt@tog@#1}\cpt@togstate
}
\robust@def*\providetog#1{%
  \ifcsndefTF{cpt@tog@#1}{}{%
    \letcsntocs{cpt@tog@#1}\@secondoftwo
  }%
}
\robust@def*\cpt@gettogstate#1{%
  \lowercase{%
    \xifstrcmpTF{#1}{true}{%
      \let\cpt@togstate\@firstoftwo
    }{%
      \xifstrcmpTF{#1}{false}{%
        \let\cpt@togstate\@secondoftwo
      }{%
        \cpt@err{Invalid toggle value '#1'}%
          {Valid toggle values are 'true' and 'false'.}%
      }%
    }%
  }%
}
\robust@def*\cpt@notogerr#1{%
  \cpt@err{Toggle switch '#1' is undefined}\@ehc
}
\robust@def*\settogtrue#1{%
  \ifcsndefTF{cpt@tog@#1}{%
    \letcsntocs{cpt@tog@#1}\@firstoftwo
  }{%
    \cpt@notogerr{#1}%
  }%
}
\newletcs\togtrue=\settogtrue
\robust@def*\settogfalse#1{%
  \ifcsndefTF{cpt@tog@#1}{%
    \letcsntocs{cpt@tog@#1}\@secondoftwo
  }{%
    \cpt@notogerr{#1}%
  }%
}
\newletcs\togfalse=\settogfalse
\robust@def*\settog#1#2{%
  \ifcsndefTF{cpt@tog@#1}{%
    \cpt@gettogstate{#2}%
    \letcsntocs{cpt@tog@#1}\cpt@togstate
  }{%
    \cpt@notogerr{#1}%
  }%
}
\robust@def*\undeftog#1{%
  \ifcsndefTF{cpt@tog@#1}{%
    \letcsntocs{cpt@tog@#1}\cpt@undefined
  }{%
    \cpt@info{Null instruction to undefine unknown toggle '#1'}%
  }%
}
\new@def*\iftogTF#1{%
  \ifcsndefTF{cpt@tog@#1}{%
    \usename{cpt@tog@#1}%
  }{%
    \cpt@notogerr{#1}\@gobbletwo
  }%
}
\new@def*\iftogFT#1{\iftogTF{#1}\cptiiofii\cptiofii}
\new@def*\cptswtrue{00}
\new@def*\cptswfalse{01}
\def\reserved@a#1{%
  \new@def*\negatesw##1{%
    0\ifcase##11#1\or\expandafter1\else\expandafter0\fi
  }%
  \new@def*\bothswtrue##1##2{%
    0\ifcase##1##2#1\expandafter0\else\expandafter1\fi
  }%
  \new@def*\oneswtrue##1##2{%
    0\ifnum##1##2<101#1\expandafter0\else\expandafter1\fi
  }%
}
\reserved@a{ }
% Convert bool value (true or false) to switch value (00 or 01):
\robust@def*\booltoswitch#1#2{%
  \begingroup
  \def\reserved@a##1#1##2##3\@nil{%
    \def#2{##2}%
    \ifx#2\@nnil
      \cpt@err{Bad boolean value '#1' can't be
        \MsgBrk converted to switch value}\@ehc
    \fi
  }%
  \reserved@a true{00}false{01}#1{\@nil}\@nil
  \postgroupdef#2\endgroup
}
% Expandable:
\new@def*\bbooltoswitch#1{%
  \expandafter\ifstrcmpTF\expandafter
  {\romannumeral-`\q\expandafter\cpttrimspace
  \expandafter{\romannumeral-`\q#1}}{true}{00}{01}%
}

\robust@def*\cptnewswitch#1{\cpt@testopt{\cpt@newswitch#1}{false}}
\robust@def*\cpt@newswitch#1[#2]{%
  \ifinsetTF{,}{#1}{%
    \cpt@err{Command \noexpand\cptnewswitch doesn't accept list}
      {Please submit only one switch to \string\cptnewswitch.}%
  }{}%
  \xifinsetTF{,#1,}{,if,x,switch,tog,togg,bool,test,}{%
    \cpt@err{Invalid switch name '#1'}\@ehc
  }{}%
  \ifcsndefinable{#1}\relax
  \cpt@getswitchstate{#2}%
  \letcsntocsn{#1}{cptsw\cpt@switchstate}%
}
\robust@def*\cpt@getswitchstate#1{%
  \lowercase{\edef\cpt@tempa{\cpttrimspaces{#1}}}%
  \xifinsetTF{,\cpt@tempa,}{,true,false,}{%
    \let\cpt@switchstate\cpt@tempa
  }{%
    \cpt@err{Invalid switch value '#1'}
      {Valid switch values are 'true' and 'false'.}%
  }%
}
\robust@def*\cpt@noswitcherr#1{%
  \cpt@err{Switch '\string#1' is undefined}\@ehc
}
\robust@def*\cptsetswitch#1#2{%
  \ifcsndefTF{#1}{%
    \cpt@getswitchstate{#2}%
    \letcsntocsn{#1}{cptsw\cpt@switchstate}%
  }{%
    \cpt@noswitcherr{#1}%
  }%
}
\robust@def*\cptsetswitchtrue#1{%
  \ifcsndefTF{#1}{%
    \letcsntocs{#1}\cptswtrue
  }{%
    \cpt@noswitcherr{#1}%
  }%
}
\newletcs\cptswitchtrue\cptsetswitchtrue
\robust@def*\cptsetswitchfalse#1{%
  \ifcsndefTF{#1}{%
    \letcsntocs{#1}\cptswfalse
  }{%
    \cpt@noswitcherr{#1}%
  }%
}
\newletcs\cptswitchfalse\cptsetswitchfalse
\new@def*\ifdefswitchTF#1{%
  \ifcsndefFT{#1}{%
    \cpt@err{Switch '#1' is not defined}\@ehc
    \@gobbletwo
  }{%
    \if\usename{#1}\expandafter\cptiofii\else\expandafter\cptiiofii\fi
  }%
}
\new@def*\ifdefswitchFT#1{\ifdefswitchTF{#1}\cptiiofii\cptiofii}
\new@def*\ifswitchTF#1{%
  \if\usename{#1}\expandafter\cptiofii\else\expandafter\cptiiofii\fi
}
\new@def*\ifswitchFT#1{\ifswitchTF{#1}\cptiiofii\cptiofii}
\new@def*\thebool@normal#1{\ifboolTF{#1}{true}{false}}
\new@def*\thebool@reverse#1{\ifboolTF{#1}{false}{true}}
\cptnewcounts[cpt@]{exprcnt}
\robust@def*\ifexprTF#1{%
  \begingroup
  \let\cpt@expr@neg\cptswfalse
  \cpt@exprcnt\z@pt
  \cpt@expr@beg
  \cpt@expr@bgroup#1(\expr@nil
  \cpt@expr@end
  \cpt@expr@eval
}
\robust@def*\cpt@expr@beg{%
  \begingroup
  \let\cpt@expr@neg\cptswfalse
  \cpt@exprcnt\z@pt
}
\robust@def*\cpt@expr@end{%
  \cpt@expr@eval\cpt@expr@true\cpt@expr@false
}
\robust@def*\cpt@expr@eval{%
  \aftercsname\endgroup
  {@\ifnum\cpt@exprcnt<\z@pt second\else first\fi oftwo}%
}
\robust@def*\cpt@expr@true{%
  \advance\cpt@exprcnt\if\cpt@expr@neg\m@one\else\z@pt\fi
  \let\cpt@expr@neg\cptswfalse
}
\robust@def*\cpt@expr@false{%
  \advance\cpt@exprcnt\if\cpt@expr@neg\z@pt\else\m@one\fi
  \let\cpt@expr@neg\cptswfalse
}
\robust@def\cpt@expr@bgroup#1(#2\expr@nil{%
  \cpt@expr@egroup#1)\expr@nil
  \ifblankTF{#2}{}{%
    \cpt@expr@beg
    \cpt@expr@bgroup#2\expr@nil
  }%
}
\robust@def\cpt@expr@egroup#1)#2\expr@nil{%
  \cpt@expr@and#1and\expr@nil
  \ifblankTF{#2}{}{%
    \cpt@expr@end
    \cpt@expr@egroup#2\expr@nil
  }%
}
\robust@def\cpt@expr@and#1and#2\expr@nil{%
  \cpt@expr@or#1or\expr@nil
  \ifblankTF{#2}{}{%
    \cpt@exprcnt\ifnum\cpt@exprcnt<\z@pt\m@one\else\z@pt\fi
    \cpt@expr@and#2\expr@nil
  }%
}
\robust@def\cpt@expr@or#1or#2\expr@nil{%
  \cpt@expr@not#1not\expr@nil
  \ifblankTF{#2}{}{%
    \cpt@exprcnt\ifnum\cpt@exprcnt<\z@pt\z@pt\else\@ne\fi
    \cpt@expr@or#2\expr@nil
  }%
}
\robust@def\cpt@expr@not#1not#2\expr@nil{%
  \cpt@expr@tog#1tog\expr@nil
  \ifblankTF{#2}{}{%
    \let\cpt@expr@neg\cptswtrue
    \cpt@expr@not#2\expr@nil
  }%
}
\robust@def\cpt@expr@tog#1tog#2\expr@nil{%
  \cpt@expr@bool#1bool\expr@nil
  \ifblankTF{#2}{}{\cpt@expr@tog@a#2\expr@nil}%
}
\robust@def\cpt@expr@tog@a#1#2\expr@nil{%
  \edef\reserved@a{\cpttrimspaces{#1}}%
  \ifcsndefTF{cpt@tog@\reserved@a}{%
    \usename{cpt@tog@\reserved@a}\cpt@expr@true\cpt@expr@false
  }{%
    \cpt@err{Invalid test expression:
      \MsgBrk toggle '\reserved@a' is undefined}\@ehc
    \cpt@expr@false
  }%
  \cpt@expr@tog#2\expr@nil
}
\robust@def\cpt@expr@bool#1bool#2\expr@nil{%
  \cpt@expr@switch#1switch\expr@nil
  \ifblankTF{#2}{}{\cpt@expr@bool@a#2\expr@nil}%
}
\robust@def\cpt@expr@bool@a#1#2\expr@nil{%
  \edef\reserved@a{\cpttrimspaces{#1}}%
  \ifcsndefTF{if\reserved@a}{%
    \ifdefboolTF\reserved@a\cpt@expr@true\cpt@expr@false
  }{%
    \cpt@err{Invalid test expression:
      \MsgBrk boolean '\reserved@a' is undefined}\@ehc
    \cpt@expr@false
  }%
  \cpt@expr@bool#2\expr@nil
}
\robust@def\cpt@expr@switch#1switch#2\expr@nil{%
  \cpt@expr@test#1test\expr@nil
  \ifblankTF{#2}{}{\cpt@expr@switch@a#2\expr@nil}%
}
\robust@def\cpt@expr@switch@a#1#2\expr@nil{%
  \edef\reserved@a{\cpttrimspaces{#1}}%
  \ifcsndefTF\reserved@a{%
    \ifswitchTF\reserved@a\cpt@expr@true\cpt@expr@false
  }{%
    \cpt@err{Invalid test expression:
      \MsgBrk switch '\reserved@a' is undefined}\@ehc
    \cpt@expr@false
  }%
  \cpt@expr@switch#2\expr@nil
}
\robust@def\cpt@expr@test#1test#2\expr@nil{%
  \ifblankTF{#1}{}{%
    \cpt@err{Invalid piece in test expression:
      \MsgBrk'\detokenize{#1}'}\@ehc
  }%
  \ifblankTF{#2}{}{%
    \cpt@expr@test@a#2\expr@nil
  }%
}
\robust@def\cpt@expr@test@a#1#2\expr@nil{%
  \ignorespaces#1\cpt@expr@true\cpt@expr@false
  \cpt@expr@test#2\expr@nil
}

\robust@def*\cptifonepresentTF#1#2{%
  \begingroup
  \cpt@choicefdfalse
  \def\siso@do##1{%
    \ifinsetTF{##1}{#2}{%
      \cpt@choicefdtrue\loopbreak
    }{}%
  }%
  \siso@@loop{#1}%
  \expandafter\endgroup\ifcpt@choicefd
    \expandafter\cptiofii\else\expandafter\cptiiofii\fi
}
% #1: listcmd
% #2: comparator: < (ascending) or > (descending)
% Eg, \def\x{13251{8/2}} \cptnumbersort\x>
\robust@def*\cptnumbersort#1#2{%
  \begingroup
  \let\numcmp\ifnumcmpTF
  \cpt@sortlist{#1}{#2}%
}
% Eg, \def\x{13251{4456789201.12}} \cptbignumbersort\x>
\robust@def*\cptbignumbersort#1#2{%
  \begingroup
  \ifcsndefTF{ver@fp.sty}{%
    \def\reserved@a##1#2##2##3\cpt@nil{%
      \def\numcmp####1#2####2####{%
        \usename{FPif##2}{####1}{####2}%
        \expandafter\cptiofii\else\expandafter\cptiiofii\fi
      }%
    }%
    \reserved@a={eq}>{gt}<{lt}\cpt@nil
  }{%
    \cpt@err{'fp' package not loaded}
      {You need to first load 'fp' package before
      \MsgBrk calling \string\cptbignumbersort.}%
  }%
  % If #1 contains expressions, evaluate them first before
  % sorting the results:
  \cptexpandarg{\cptifonepresentTF{/*-+}}{\cptoxdetok{#1}}{%
    \def\siso@do##1{%
      \FPeval\resulta{clip(##1)}%
      \edef#1{#1{\resulta}}%
    }%
    \cptexpandarg{\def#1{}\siso@@loop}{#1}%
  }{}%
  \cpt@sortlist{#1}{#2}%
}
% Eg, \def\x{ab{west}cdea{east}} \cptalphasort\x<
\robust@def*\cptalphasort#1#2{%
  \begingroup
  \def\numcmp##1#2##2##{%
    \ifnum\cpt@pdfstrcmp{##1}{##2}#2\z@pt
    \expandafter\cptiofii\else\expandafter\cptiiofii\fi
  }%
  \cpt@sortlist{#1}{#2}%
}
\robust@def*\cpt@sortlist#1#2{%
  \def\sortedlist{}%
  \cpt@sortlist@a{#1}{#2}%
  \edefpass#1{\endgroup\def\noexpand#1{\sortedlist}}%
}
\new@def*\cpt@sortwrapper#1{{#1}}
\robust@def*\cpt@sortlist@a#1#2{%
  % Get the largest/smallest number and return:
  \def\do##1{%
    \def\smaller@bigger{}%
    \defpass\do####1{%
      \defifxTF{####1}\@nnil{%
        % Store the largest/smallest number:
        \edef\sortedlist{\sortedlist\cpt@sortwrapper{##1}}%
        \ifcsemptyTF\smaller@bigger{}{%
          \let#1=\smaller@bigger
          \cpt@sortlist@a#1#2%
        }%
      }{%
        \numcmp####1#2##1{%
          \cpt@sortlist@b{#1}{#2}{{####1}{##1}}.%
        }{%
          \edef\smaller@bigger{\smaller@bigger{####1}}%
          \do
        }%
      }%
    }%
  }%
  \expandafter\do#1\@nil
}
\robust@def*\cpt@sortlist@b#1#2#3#4\@nil{%
  % \@gobble is for gobbling the dot:
  \edef#1{#3\smaller@bigger\@gobble#4}%
  \cpt@sortlist@a{#1}{#2}%
}
\robust@def*\BeforeProcessOptions{%
  \ifcsndefTF{\@currname @\@currext @beginprocessopt}{%
    \cpt@warn{\noexpand\BeforeProcessOptions wrongly located}%
    \@gobble
  }{%
    \aftercsname\grightaddtocs{\@currname @\@currext
      @beforeprocessopt}%
  }%
}
\robust@def*\AfterProcessOptions{%
  \ifcsndefTF{\@currname @\@currext @endprocessopt}{%
    \@firstofone
  }{%
    \aftercsname\grightaddtocs{\@currname @\@currext
      @afterprocessopt}%
  }%
}
\robust@def*\BeforeStartOfDocument{\grightaddtocs\cpt@beforestartdoc}
\new@def*\cpt@beforestartdoc{}
%% DPC
%% since hooks were added \document does not need grouping adjustment
\ifx \UseOneTimeHook \@undefined
\gleftaddtocs\document{%
  \endgroup
  \let\BeforeStartOfDocument\@firstofone
  \cpt@beforestartdoc
  \let\BeforeStartOfDocument\@notprerr
  \gundefcs\cpt@beforestartdoc
  \gdef\cpt@docstarted{}%
  \begingroup
}
\else
\gleftaddtocs\document{%
%  \endgroup
  \let\BeforeStartOfDocument\@firstofone
  \cpt@beforestartdoc
  \let\BeforeStartOfDocument\@notprerr
  \gundefcs\cpt@beforestartdoc
  \gdef\cpt@docstarted{}%
%  \begingroup
}
\fi
%% END CHANGE
\robust@def*\AfterStartOfDocument{\grightaddtocs\cpt@afterstartdoc}
\new@def*\cpt@afterstartdoc{}
\robust@def*\AfterAfterStartOfDocument#1{%
  \AtBeginDocument{%
    \grightaddtocs\cpt@afterafterstartdoc{#1}%
  }%
}
\new@def*\cpt@afterafterstartdoc{}
\grightaddtocs\document{%
  \let\AfterStartOfDocument\@firstofone
  \cpt@afterstartdoc
  \let\AfterStartOfDocument\@notprerr
  \gundefcs\cpt@afterstartdoc
  \cpt@afterafterstartdoc
  \let\AfterAfterStartOfDocument\@notprerr
  \gundefcs\cpt@afterafterstartdoc
  \ignorespaces
}
\gleftaddtocs\@popfilename{%
  \ifcsnameFT{\@currname.\@currext-cpt@hook}{}{%
    \usename{\@currname.\@currext-cpt@hook}%
    \gundefcsn{\@currname.\@currext-cpt@hook}%
  }%
}
% \loadifnotloaded{<package>}[<date>]
\robust@def*\loadifnotloaded#1{%
  \cpt@testopt{\cpt@ifpkgnotloaded{#1}}{}%
}
\robust@def*\cpt@ifpkgnotloaded#1[#2]{%
  \@ifpackageloaded{#1}{%
    \@ifpackagelater{#1}{#2}{}{%
      \ltxmsg@err{Loaded version of #1 package is not current}\@ehc
    }%
  }{%
    \RequirePackage{#1}[#2]%
  }%
}
% If package has been loaded with <options>.
% \ifpackagewithoptionsTF{<package>}{<options>}{<true>}{<false>}
\robust@def*\ifpackagewithoptionsTF{\cpt@ifoptions\@pkgextension}
\robust@def*\ifclasswithoptionsTF{\cpt@ifoptions\@clsextension}
\robust@def*\cpt@ifoptions#1#2{%
  \cptexpandarg\cpt@ifopti@ns{\cpt@optionlist{#2.#1}}%
}
\robust@def*\cpt@ifopti@ns#1#2{%
  \begingroup
  \edef\temp@optlist{\unexpanded{#1}}%
  \cpt@sttrue\cpt@kvnormalize[,]\temp@optlist
  \cpt@choicefdtrue
  \def\checkopts{%
    \def\kv@do####1{%
      \oifinset@sp@TF,{####1}\temp@optlist
        {}{\cpt@choicefdfalse\loopbreak}%
    }%
    \kv@@parse{#2}%
  }%
  \ifblankTF{#2}{%
    \ifcsemptyTF\temp@optlist{}{%
      \cpt@choicefdfalse
    }%
  }{%
    \ifcsemptyTF\temp@optlist{%
      \cpt@choicefdfalse
    }{%
      \checkopts
    }%
  }%
  \ifdefboolTF{cpt@choicefd}
    {\endgroup\@firstoftwo}{\endgroup\@secondoftwo}%
}
% #1=package, #2=options
\robust@def*\cptcheckoptionclash#1#2{%
  \begingroup
  \edef\cpt@rsvda{\detokenize\expandafter
    {\romannumeral-`\q\cpt@optionlist{#1.\@pkgextension}}}%
  \@tempswafalse
  \ifblankTF{#2}{%
    \ifcsnullTF\cpt@rsvda{}\@tempswatrue
  }{%
    \ifcsnullTF\cpt@rsvda{%
      \@tempswatrue
    }{%
      \def\kv@do####1{%
        \xifinsetTF{,\detokenize{####1},}{,\cpt@rsvda,}{}{%
          \@tempswatrue\loopbreak
        }%
      }%
      \kv@@parse[,]{#2}%
    }%
  }%
  \expandafter\endgroup
  \if@tempswa
    \cpt@err{Option clash for package ##1.\@pkgextension}\@ehc
    \expandafter\@gobble
  \fi
}
% If package was later loaded (before begin-document).
% \ifpackageloadedlaterTF{<package>}{<true>}{<false>}
\robust@def*\ifpackageloadedlaterTF{\cpt@ifpkgloadedlater\@pkgextension}
\robust@def*\ifclassloadedlaterTF{\cpt@ifpkgloadedlater\@clsextension}
\robust@def*\cpt@ifpkgloadedlater#1#2#3#4{%
  \begingroup
  \edef\elt{\ifx#1\@pkgextension package\else class\fi}%
  \usename{@if\elt loaded}{#2}{%
    \endgroup
    \ifcpt@verbose
      \cpt@info{\@cls@pkg\@space '#2' has been loaded}%
    \fi
  }{%
    \def\elt##1##2{%
      \ifcpt@verbose
        \cpt@info{\@cls@pkg\@space '#2' was##1 loaded afterwards}%
      \fi
      \unexpanded{##2}\relax
    }%
    \cptexpanded{\endgroup
      \AfterStartOfDocument{%
        \noexpand\ifcsndefTF{ver@#2.#1}{\elt{}{#3}}{\elt{n't}{#4}}%
      }%
    }%
  }%
}
% \cptloadpackages[<inner-parser><outer-parser>]{%
%   pkga<inner>options<inner>date<outer>
%   pkgb<inner>options<inner>date<outer>
% }
\robust@def*\cptloadpackages{%
  \begingroup
  \endlinechar=-1
  \cpt@testopt{\expandafter\endgroup\cpt@loadpackages}{|;}%
}
\robust@def\cpt@loadpackages[#1]#2{%
  \begingroup
  \toks@{}%
  % ##1: inner parser; ##2 outer parser:
  \def\cpt@tempa##1##2\cpt@nil{%
    \ifblankTF{##2}{%
      \cpt@err{No outer parser or something wrong
        \MsgBrk while in \string\cptloadpackages}\@ehc
      \@gobble
    }{%
      \ifinsetFT{,}{##1##2}{}{%
        \cpt@err{Parser can't be comma (,) in
          \string\cptloadpackages}\@ehc
        \expandafter\@gobble
      }%
    }%
    % \cpt@lo@dpackages can't be taken outside \cpt@loadpackages:
    \def\cpt@lo@dpackages####1##1####2##1####3##1####4\cpt@nil{%
      \ifblankTF{####1}{%
        \cpt@err{No package name while in \string\cptloadpackages}\@ehc
        \@gobble
      }{}%
      \ifblankTF{####2}{%
        \def\cpt@rsvda{}%
      }{%
        \cptstripallouterbraces{####2}\cpt@rsvda
      }%
      \@ifpackageloaded{####1}{%
        % Check if package was previously loaded with options:
        \edef\cpt@rsvdb{\detokenize\expandafter
          {\romannumeral-`\q\cpt@optionlist{####1.\@pkgextension}}}%
        \@tempswafalse
        \ifcsnullTF\cpt@rsvda{%
          \ifcsnullTF\cpt@rsvdb{}\@tempswatrue
        }{%
          \ifcsnullTF\cpt@rsvdb{%
            \@tempswatrue
          }{%
            \def\kv@do########1{%
              \xifinsetTF{,\detokenize{########1},}{,\cpt@rsvdb,}{}{%
                \@tempswatrue\loopbreak
              }%
            }%
            \kv@@parse*[,]\cpt@rsvda
          }%
        }%
        \if@tempswa
          \cpt@err{Option clash for package ####1.\@pkgextension}\@ehc
          \expandafter\@gobble
        \fi
      }{%
        \cptexpanded{%
          \toks@{\the\toks@
            \ifcseqTF\documentclass\@twoclasseserror
              {\noexpand\usepackage}{\noexpand\RequirePackage}%
            [\expandcsonce\cpt@rsvda]{####1}[####3]%
          }%
        }%
      }%
    }%
    \def\csv@do####1{%
      \cpt@lo@dpackages####1##1##1##1##1\cpt@nil
    }%
    \cpt@useemptyfalse
    \csv@@parse[##2]{#2}%
  }%
  \cpt@tempa#1\cpt@nil
  \expandafter\endgroup\the\toks@
}
% Eg,
% \cptrequirepackages{%
%   pkga|options|date; pkgb|options|date; etc.
% }
\robust@def*\cptrequirepackages#1{%
  \begintoksgroup
  \let\RequirePackage\relax
  \def\cpt@requirepackage##1|##2|##3|##4\@nil{%
    \edef\cpt@tempa{\cpttrimspaces{##1}}%
    \edef\cpt@tempb{\cpttrimspaces{##2}}%
    \edef\cpt@tempc{\cpttrimspaces{##3}}%
    \@ifpackageloaded{\cpt@tempa}{%
      \xifstrcmpTF\cpt@tempc{^?^}{}{%
        \@ifpackagelater\cpt@tempa\cpt@tempc{%
          \cptexpandbracenext\cptstripallouterbraces\cpt@tempb\cpt@tempb
          \cptexpandsecond\cptcheckoptionclash
            {{\expandcsonce\cpt@tempa}{\expandcsonce\cpt@tempb}}%
        }{%
          \addto@hook\toks@{\@latex@error{Loaded version of
            '\cpt@tempa' package is not current}\@ehc}%
        }%
      }%
    }{%
      \xifstrcmpTF\cpt@tempb{^?^}{%
        \xifstrcmpTF\cpt@tempc{^?^}{%
          \addto@hook\toks@{\RequirePackage{\cpt@tempa}}%
        }{%
          \addto@hook\toks@{\RequirePackage{\cpt@tempa}[\cpt@tempc]}%
        }%
      }{%
        \xifstrcmpTF\cpt@tempc{^?^}{%
          \addto@hook\toks@{\RequirePackage[\cpt@tempb]{\cpt@tempa}}%
        }{%
          \addto@hook\toks@
            {\RequirePackage[\cpt@tempb]{\cpt@tempa}[\cpt@tempc]}%
        }%
      }%
    }%
  }%
  \def\csv@do##1{%
    \cpt@requirepackage##1|^?^|^?^|\@nil
  }%
  \csv@@parse[;]{#1}%
  \endtoksgroup
}
% #1=base, #2=modules to be load
\robust@def*\cptloadmodules#1#2{%
  \begintoksgroup
  \def\clash@list{}%
  \def\do##1##2{%
    \ifcpt@noval
      \def\curr@optlist{}%
    \else
      \cptstripallouterbraces{##2}\curr@optlist
    \fi
    \@ifpackageloaded{##1}{%
      % Check option clash:
      \cptexpandarg{\cpt@ifoptions{sty}{##1}}{\expandcsonce\curr@optlist}{}{%
        \ifx\curr@optlist\@empty
          \cptuaddtolist\clash@list{##1}%
        \else
          \cptuaddtolist\clash@list{##1=##2}%
        \fi
      }%
    }{%
      \cptexpanded{\toks@{\the\toks@
        \noexpand\RequirePackage[\expandcsonce\curr@optlist]{%
          \ifblankTF{#1}{}{#1-}##1%
        }}%
      }%
    }%
  }%
  \kv@@process{#2}\do
  \ifx\clash@list\@empty
    \expandafter\endtoksgroup
  \else
    \cptexpanded{\endgroup
      \cpt@err{Option clash for module(s):
      \noexpand\unexpanded{\expandcsonce\clash@list}}}\@ehc
  \fi
}
\robust@def*\AfterEndOfStyleFile{%
  \begingroup
  \def\cpt@tempa{\endgroup
    \expandafter\grightaddtocs
    \csname\@currname.\@currext-cpt@hook\endcsname
  }%
  \ifcsnullTF\@currname{%
    \endgroup\@gobble
  }{%
    \cpt@tempa
  }%
}
\robust@def*\ifinstylefileTF{\ifcsemptyTF\@currname\cptiiofii\cptiofii}
\robust@def*\cpt@pushhash{%
  \begingroup
  \@makeother{\#}%
  \endlinechar\m@one
  \cpt@push@hash
}
\robust@def\cpt@push@hash#1#2{%
  \xifinsetTF\cpt@hashchar{\detokenize{#1}}{%
    \edef\x##1{##1\detokenize{#1}\cpt@hashchar\cpt@nil}%
    \edef\y##1{\def##1####1\cpt@hashchar####2\cpt@nil}%
    \y\y{%
      \ifblankTF{##2}{%
        \toks@\expandafter{\the\toks@##1}%
      }{%
        \cptpassexpanded
          {\toks@{\the\toks@##1\cpt@hashchar\cpt@hashchar}}%
        \y##2\cpt@nil
      }%
    }%
    \x{\toks@{}\y}%
  }{%
    \toks@\expandafter{\detokenize{#1}}%
  }%
  \edef#2{\the\toks@}%
  \postgroupdef#2\endgroup
}
\robust@def*\cpt@pophash{%
  \begingroup
  \@makeother{\#}%
  \endlinechar\m@one
  \cpt@pop@hash
}
\robust@def\cpt@pop@hash#1#2{%
  \xifinsetTF{\detokenize{##}}{\detokenize{#1}}{%
    \edef\x##1{##1\detokenize{#1##}\cpt@nil}%
    \edef\y##1{\def##1####1\detokenize{##}####2\cpt@nil}%
    \y\y{%
      \ifblankTF{##2}{%
        \toks@\expandafter{\the\toks@##1}%
      }{%
        \cptexpanded{\toks@{\the\toks@##1\cpt@hashchar}}%
        \y##2\cpt@nil
      }%
    }%
    \x{\toks@{}\y}%
  }{%
    \toks@\expandafter{\detokenize{#1}}%
  }%
  \edef#2{\the\toks@}%
  \postgroupdef#2\endgroup
}
% * -> #2 is a listcmd, else it is a list:
\robust@def*\csv@@normalize{\cpt@teststopt\cpt@csvnormalize,}
\robust@def\cpt@csvnormalize[#1]#2{%
  \let\cpt@inkv\cptswfalse
  \cpt@normalizelist{#1}{#2}%
}
\robust@def*\kv@@normalize{\cpt@teststopt\cpt@kvnormalize,}
\robust@def\cpt@kvnormalize[#1]#2{%
  \let\cpt@inkv\cptswtrue
  \cpt@normalizelist{#1}{#2}%
}
\ifcsdefinable\normalized@list\relax

\begingroup
\catcode`\^=3
\robust@gdef\cpt@normalizelist#1#2{%
  \begingroup
  \let\if@nmlzst\ifcpt@st
  \cpt@stchoose{cpt@st}{#2}\reserved@e\cpt@normalizelist
  \ifx\reserved@e\@empty
    \def\normalized@list{}%
    \cptbgobbletorelax
  \fi
  % It is absolutely necessary to check parser here, since this
  % normalizer doesn't take multiple parsers at once:
  \cpt@ch@cklistparser{#1}%
  \expandafter\SetupParserNormalizer\string#1%
  \toks@\expandafter{\expandafter#1\reserved@e#1}%
  \nmlz@activeparser
  \expandafter\nmlz@spaceletter\string#1%
  \expandafter\nmlz@letterspace\string#1%
  \expandafter\nmlz@doubleletter\string#1%
  \ifswitchFT{cpt@inkv}{}{%
    \nmlz@activeequal
    \nmlz@spaceletter=%
    \nmlz@letterspace=%
    % We put '^?' at the end of #1 to preserve any trailing '='.
    % This can happen if a key has an empty value.
    \toks@\expandafter{\the\toks@^?}%
    \nmlz@doubleletter=%
    \cpt@commaequalerr
    \def\reserved@a##1^?##2\nmlz@nil{\toks@{##1##2}}%
    \expandafter\reserved@a\the\toks@\nmlz@nil
  }%
  \edef\normalized@list{\the\toks@}%
  \cpttrimleadparsers#1\normalized@list
  \cptexpanded{\endgroup
    \ifdefboolTF{@nmlzst}{%
      \edef\noexpand#2{\ox@unexpanded\normalized@list}%
    }{%
      \cpt@csexit\normalized@list
    }%
  }%
  \cpt@relax
}
\endgroup

\new@def*\SetupParserNormalizer#1{%
  \begingroup
  \uccode`\~=`#1%
  \uppercase{\endgroup
    \def\nmlz@activeparser{%
      \def\cpt@tempa####1~####2\nmlz@nil{%
        \ifblankTF{####2}{%
          \toks@{####1}%
        }{%
          \cpt@tempa####1#1####2\nmlz@nil
        }%
      }%
      \toks@\expandafter{\expandafter}\expandafter
      \cpt@tempa\the\toks@~\nmlz@nil
    }%
  }%
}
\begingroup
\catcode`\==12
\uccode`\~=`\=%
\uppercase{\endgroup
  \def\nmlz@activeequal{%
    \def\cpt@tempa##1~##2\nmlz@nil{%
      \ifblankTF{##2}
        {\toks@{##1}}{\cpt@tempa##1=##2\nmlz@nil}%
    }%
    \toks@\expandafter{\expandafter}\expandafter
    \cpt@tempa\the\toks@~\nmlz@nil
  }%
}
\def\nmlz@doubleletter#1{%
  \def\cpt@tempa##1#1#1##2\nmlz@nil{%
    \ifblankTF{##2}
      {\toks@{##1}}{\cpt@tempa##1#1##2\nmlz@nil}%
  }%
  \expandafter\cpt@tempa\the\toks@#1#1\nmlz@nil
}
\defpass\cpt@tempa#1{%
  \def\nmlz@spaceletter##1{%
    \def\cpt@tempa####1#1##1####2\nmlz@nil{%
      \ifblankTF{####2}
        {\toks@{####1}}{\cpt@tempa####1##1####2\nmlz@nil}%
    }%
    \expandafter\cpt@tempa\the\toks@#1##1\nmlz@nil
  }%
  \def\nmlz@letterspace##1{%
    \def\cpt@tempa####1##1#1####2\nmlz@nil{%
      \ifblankTF{####2}
        {\toks@{####1}}{\cpt@tempa####1##1####2\nmlz@nil}%
    }%
    \expandafter\cpt@tempa\the\toks@##1#1\nmlz@nil
  }%
}{ }
\robust@def*\cpt@commaequalerr{%
  \def\cpt@tempa##1,=##2\nmlz@nil{%
    \ifblankTF{##2}{}{%
      \cpt@err{There is 'comma' next to 'equal' (,=) in
        \MsgBrk your key-value list}\@ehc
    }%
  }%
  \expandafter\cpt@tempa\the\toks@,=\nmlz@nil
}
% Double parser normalizer. This is for normalizing lists
% like {x|| y|||| z}, where the parser is double bar ||:
\new@def*\SetupDoubleParserNormalizer#1{%
  \begingroup
  \uccode`\~=`#1%
  \uppercase{\endgroup
    \def\cptnormalizedoubleparser##1{%
      \unexpanded\expandafter{\romannumeral-`\q
        \nmlz@activedoubleparser#1#1##1#1#1~~\nmlz@nil}%
    }%
    \def\nmlz@activedoubleparser##1~~##2\nmlz@nil{%
      \ifblankTF{##2}
        {\nmlz@spacedoubleparser##1 #1#1\nmlz@nil}
        {\nmlz@activedoubleparser##1#1#1##2\nmlz@nil}%
    }%
  }%
  \def\nmlz@spacedoubleparser##1 #1#1##2\nmlz@nil{%
    \ifblankTF{##2}
      {\nmlz@doubleparserspace##1#1#1 \nmlz@nil}
      {\nmlz@spacedoubleparser##1#1#1##2\nmlz@nil}%
  }%
  \def\nmlz@doubleparserspace##1#1#1 ##2\nmlz@nil{%
    \ifblankTF{##2}
      {\nmlz@fourparser##1#1#1#1#1\nmlz@nil}
      {\nmlz@doubleparserspace##1#1#1##2\nmlz@nil}%
  }%
  \def\nmlz@fourparser##1#1#1#1#1##2\nmlz@nil{%
    \ifblankTF{##2}
      {\ifblankTF{##1}{}{\@gobbletwo##1}}
      {\nmlz@fourparser##1#1#1##2\nmlz@nil}%
  }%
}
% This is for normalizing lists like {x\\ y\\\\ z}, where \\ is
% a control sequence:
\robust@def*\SetupSpecialParserNormalizer#1{%
  \def\cptspecialnormalize##1{%
    \unexpanded\expandafter{\romannumeral-`\q
      \spnmlz@spaceparser##1 #1\nmlz@nil}%
  }%
  \def\spnmlz@spaceparser##1 #1##2\nmlz@nil{%
    \ifblankTF{##2}
      {\spnmlz@parserspace##1#1 \nmlz@nil}
      {\spnmlz@spaceparser##1#1##2\nmlz@nil}%
  }%
  \def\spnmlz@parserspace##1#1 ##2\nmlz@nil{%
    \ifblankTF{##2}
      {\spnmlz@doubleparser##1#1#1\nmlz@nil}
      {\spnmlz@parserspace##1#1##2\nmlz@nil}%
  }%
  \def\spnmlz@doubleparser##1#1#1##2\nmlz@nil{%
    \ifblankTF{##2}{##1}
      {\spnmlz@doubleparser##1#1##2\nmlz@nil}%
  }%
}
% See file 'commands-with-different-meaning-in-environment' for examples:
\robust@def*\AtBeginColony#1{\grightaddtocsn{atbegin@#1@colonyhook}}
\robust@def*\AtEndColony#1{\grightaddtocsn{atend@#1@colonyhook}}
\new@def*\colonyarg#1{\@nameuse{colony@arg@\romannumeral#1}}
\robust@def*\newcolony{\cpt@starorlong\new@colony}
\def\new@colony#1{\cpt@testopt{\newcolony@a#1}0}
\def\newcolony@a#1[#2]{%
  \cpt@ifbrack{\newcolony@b{#1}{#2}}{\newcolony@c{#1}{[#2]}}%
}
\def\newcolony@b#1#2[#3]{\newcolony@c{#1}{[#2][{#3}]}}
\robust@def*\renewcolony{\cpt@starorlong\renew@colony}
\def\renew@colony#1{%
  \ifcsndefTF{#1}{}{\cpt@err{Environment '#1' is undefined}\@ehc}%
  \expandafter\let\csname#1\endcsname\relax
  \expandafter\let\csname end#1\endcsname\relax
  \new@colony{#1}%
}
\long\def\newcolony@c#1#2#3#4{%
  \ifcsndefTF{#1}{}{\letcsntocsn{#1}{end#1}}%
  \def\reserved@a[##1]##2\@nil{%
    \chardef\@tempa\z@pt
    \loop\ifnum\@tempa<##1\relax
      \edef\@tempa{\the\numexpr\@tempa+1}%
      \cptexpandarg{\rightaddtocs\@tempb}{%
        \csn@edef{colony@arg@\romannumeral\@tempa}%
        {\noexpand\unexpanded{################\number\@tempa}}%
      }%
    \repeat
  }%
  \reserved@a#2\@nil
  \cptexpandbracenext{\aftercsname\new@command{#1}#2}{%
    \@tempb
    \@nameuse{atbegin@#1@colonyhook}%
    \@nameuse{#1@env@defs}#3%
  }%
  \l@ngrel@x\csn@def{end#1}{%
    #4\@nameuse{atend@#1@colonyhook}%
  }%
}
% #1 = environment name; #2 = command
\robust@def*\newcolonycmd{\cpt@testst\new@colonycmd}
\robust@def\new@colonycmd#1#2{%
  \aftercsname\rightaddtocs{#1@env@defs}{\colonyletcs{#1}{#2}}%
  \cptexpanded{\noexpand\newcommand\ifcpt@st*\fi
    \noexpandcsn{#1@\cptgobblescape#2}}%
}
\def\colonyletcs#1#2{\letcstocsn{#2}{#1@\cptgobblescape#2}}

\robust@def*\cptcheckbool#1#2#3{%
  \lowercase{%
    \edef\cpt@resa{\s@expandarg\cpttrimspaces{\cptrm-`\q#1}}%
  }%
  \xifinsetTF{,\cpt@resa,}{,true,false,}{%
    #3\relax
  }{%
    \@latex@error{Invalid value '#1' for '#2'}\@ehc
  }%
}
\robust@def*\cptcheckswitch#1#2{%
  \edef\cpt@resa{\s@expandarg\cpttrimspaces{\cptrm-`\q#1}}%
  \xifinsetTF{,\cpt@resa,}{,00,01,}{%
    #2\relax
  }{%
    \@latex@error{Invalid switch value '#1'}\@ehc
  }%
}
\robust@def*\RecoverAtRequirePackage#1{%
  \ifblankFT{#1}{}{%
    \cpt@isblankerr\RecoverAtRequirePackage
  }%
  \begingroup
  \cptfor#1\dofor{%
    \ifescapedTF{##1}{%
      \ifdefTF{##1}{}{%
        % If the argument was undefined, then it couldn't be
        % executed later:
        \cpt@notdeferr{##1}%
        \@gobble
      }%
    }{%
      \cpt@notescapederr{##1}%
      \@gobble
    }%
    \ifcsndefTF{cpt@atpush@\cptremovescape##1}{}{%
      \gletcsntocs{cpt@atpush@\cptremovescape##1}##1%
      \edef\cpt@tempa{%
        \gletcs\unexpanded{##1}=%
          \noexpandcsn{cpt@atpush@\cptremovescape##1}%
      }%
      \xifinsetTF{\cptoxdetok\cpt@tempa}{\cptoxdetok\@pushfilename}{}{%
        \xdef\@pushfilename{%
          \expandcsonce\cpt@tempa\expandcsonce\@pushfilename
        }%
      }%
    }%
  }%
  \endgroup
}
\let\cpt@documentclass\cpt@undefined
\robust@def*\cpt@getdocumentclass{%
  \def\csv@do##1{%
    \filename@parse{##1}%
    \ifx\filename@ext\@clsextension
      \ifcsndefFT{opt@\filename@area\filename@base.%
        \filename@ext}{}{%
        \xdef\cpt@documentclass{%
          \filename@area\filename@base.\filename@ext
        }%
      }%
    \fi
    \ifx\cpt@documentclass\cpt@undefined\else\loopbreak\fi
  }%
  \csv@@parse*\@filelist
  \ifdefTF\cpt@documentclass{}{%
    \ifcpt@verbose
      \@latex@info@no@line{'catoptions' package loaded before
        \string\documentclass: \MsgBrk no problem}%
    \fi
  }%
}
\cptpassunexpanded{%
  \ifxTF\@filelist\relax{}{%
    \ifxTF\@filelist\@gobble{}{%
      \ifxTF\@filelist\@empty\relax\cpt@getdocumentclass
    }%
  }%
  \ifxTF\cpt@documentclass\cpt@undefined{%
    \let\cpt@classoptionslist\@empty
  }{%
    \ifxTF\@classoptionslist\relax{}{%
      \ifxTF\@classoptionslist\@empty{}{%
        \cpt@sttrue\cpt@kvnormalize[,]\@classoptionslist
      }%
    }%
    \let\cpt@classoptionslist\@classoptionslist
    \def\@fileswith@ptions##1[##2]##3{%
      \edef\cpt@tempa{\cptcommanormalize{##3}}%
      \cptfor xkeyval,kvoptions,ltxkeys\dofor{%
        \xifinsetFT{,####1,}{,\cpt@tempa,}{}{%
          \let\@classoptionslist\cpt@classoptionslist
          \forbreaktrue
        }%
      }%
      \cpt@ifbrack{\@fileswith@pti@ns##1[##2]##3}%
        {\@fileswith@pti@ns##1[##2]##3[]}%
    }%
    \def\csv@do##1{%
      \ifinsetTF{=}{##1}{}{%
        \cptguaddtolist\@classoptionslist{##1}%
      }%
    }%
    \expandafter\def\expandafter\@classoptionslist\expandafter
      {\expandafter}\expandafter\csv@@loop\expandafter
      {\@classoptionslist}%
  }%
}
\robust@def*\cpt@testfam#1{%
  \ifnextcharTF<{#1}{#1<\@currname.\@currext>}%
}
\robust@def*\cpt@badoptionerr#1{%
  \expandafter\ifescapedTF\expandafter{#1}{%
    \cpt@isescapederr{#1}%
  }{%
    \expandafter\ifmacroFT\expandafter{#1}{}{%
      \cpt@err{Macro as option name '\expandcsonce{#1}'}\@ehc
    }%
  }%
}
\robust@def*\XDeclareOption{%
  \let\@fileswith@pti@ns\@badrequireerror
  \cpt@ifstar
    {\cpt@testfam\cpt@define@default@ds}%
    {\cpt@testfam\cpt@declareoption}%
}
\robust@def*\XDeclareDefaultCallback{\XDeclareOption*}
\robust@def*\cpt@declareoption<#1>#2{%
  \trim@@space{#1}\cpt@currfam
  \trim@@space{#2}\cpt@curropt
  \cpt@badoptionerr\cpt@curropt
  \cptexpandarg\cpt@testopt
    {\cpt@d@clareoption{\cpt@currfam}{\cpt@curropt}}{}%
}
\robust@def\cpt@d@clareoption#1#2[#3]#4{%
  \cpt@d@cl@reoption{#1}{#2}{#3}%
  \ifdefboolTF{cpt@olddx}{%
    % xcolor.sty uses a unique definition of callback:
    \xifstrcmpTF{\@currname.\@currext}{xcolor.sty}{%
      \csn@xdef{#1@ds@#2}{%
        \unexpanded{\edef\XC@@opt{\XC@@opt#2,}#4}%
      }%
    }{%
      \csn@xdef{#1@ds@#2}{\unexpanded{#4}}%
    }%
  }{%
    \begingroup
    \long\def\cpt@tempa##1{\endgroup
      \csn@gdef{#1@ds@#2}####1{##1}%
    }%
    \cpt@tempa{#4}%
  }%
  \cpt@olddxfalse
}
\robust@def*\XDeclareOptions{%
  \let\@fileswith@pti@ns\@badrequireerror
  \cpt@ifstar{%
    \cpt@err{Command \noexpand\XDeclareOptions has no
      star form}\@ehc
  }{%
    \cpt@testfam\cpt@declareoptions
  }%
}
\robust@def*\cpt@declareoptions<#1>#2{%
  \cpt@testopt{\cpt@d@clareoptions{#1}{#2}}{}%
}
\robust@def\cpt@d@clareoptions#1#2[#3]#4{%
  \trim@@space{#1}\cpt@currfam
  \def\csv@do##1{%
    \cpt@badoptionerr{##1}%
    \s@expandarg\cpt@d@clareoption\cpt@currfam{##1}[#3]{#4}%
  }%
  \csv@@parse[,]{#2}%
}

\robust@def*\XInvalidOptionHandler{%
  \cpt@testfam\cpt@invalidoptionhandler
}
\robust@def*\cpt@invalidoptionhandler<#1>#2{%
  \def\cpt@currfams{#1}%
  \def\csv@do##1{%
    \ifcsndefTF{##1@invalidoptionerr}{%
      \cpt@err{Invalid option handler already defined
        \MsgBrk for family '##1'}{%
        Second invalid option handler for family '##1'?
      }%
    }{%
      % The error message will replace key macro, hence
      % it needs a parameter:
      \csn@gdef{##1@invalidoptionerr}####1{#2####1}%
    }%
  }%
  \csv@@parse*[,]\cpt@currfams
}
\robust@def*\XDeclareInvalidOptions{%
  \let\@fileswith@pti@ns\@badrequireerror
  \cpt@ifstar{%
    \cpt@err{Invalid star suffix for command
      \MsgBrk\string\XDeclareInvalidOption}\@ehc
  }{%
    \cpt@testfam\cpt@declarenulloptions
  }%
}
\newletcs\XDeclareInvalidOption\XDeclareInvalidOptions
\robust@def*\cpt@declarenulloptions<#1>#2{%
  \def\cpt@currfams{#1}%
  \def\cpt@curropts{#2}%
  \def\csv@do##1{\cpt@d@clarenulloptions{##1}}%
  \csv@@parse*[,]\cpt@currfams
  \cpt@olddxfalse
}
\robust@def*\cpt@d@clarenulloptions#1{%
  \def\csv@do##1{%
    \ifcsndefTF{#1@ds@##1}{%
      \cpt@err{Option '##1' of family '#1'
        \MsgBrk is already defined}\@ehc
    }{%
      \cpt@badoptionerr{##1}%
      \cpt@d@cl@reoption{#1}{##1}{}%
      \ifcsndefTF{#1@invalidoptionerr}{%
        \gletcsntocsn{#1@ds@##1}{#1@invalidoptionerr}%
      }{%
        \begingroup
        \def\cpt@temp@err{%
          \cpt@err{Option '##1' of family '#1'
            \MsgBrk is invalid or null}{%
            Invalid option '##1' of family '#1'.}%
        }%
        \ifdefboolTF{cpt@olddx}{%
          \csn@xdef{#1@ds@##1}{\cpt@temp@err}%
        }{%
          \csn@xdef{#1@ds@##1}####1{\cpt@temp@err}%
        }%
        \endgroup
      }%
    }%
  }%
  \csv@@parse*[,]\cpt@curropts
}
\robust@def*\XDeclareCommandOption{%
  \let\@fileswith@pti@ns\@badrequireerror
  \let\cmdoption\cptswtrue
  \cpt@testfam\cpt@declarecmdoption
}
\robust@def*\XDeclareCommandOptions{%
  \let\@fileswith@pti@ns\@badrequireerror
  \let\cmdoption\cptswtrue
  \cpt@testfam\cpt@declarecmdoptions
}
\robust@def*\XDeclareBooleanOption{%
  \let\@fileswith@pti@ns\@badrequireerror
  \let\cmdoption\cptswfalse
  \cpt@testfam\cpt@declarecmdoption
}
\robust@def*\XDeclareBooleanOptions{%
  \let\@fileswith@pti@ns\@badrequireerror
  \let\cmdoption\cptswfalse
  \cpt@testfam\cpt@declarecmdoptions
}
\robust@def*\cpt@declarecmdoption<#1>#2{%
  \trim@@space{#1}\cpt@currfam
  \trim@@space{#2}\cpt@curropt
  \cpt@badoptionerr\cpt@curropt
  \cptexpandarg\cpt@testopt
    {\cpt@d@clarecmdoption{\cpt@currfam}{\cpt@curropt}}{}%
}
\robust@def\cpt@d@clarecmdoption#1#2[#3]{%
  \cptexpandarg{\cpt@testpnopt{\cpt@d@cl@recmdoption
    {#1}{#2}{#3}}}{\if\cmdoption cmd\fi\@currname @}%
}
\robust@def\cpt@d@cl@recmdoption#1#2#3(#4)#5{%
  \cpt@d@cl@reoption{#1}{#2}{#3}%
  \if\cmdoption
    \def\cpt@rsvda{\csn@def{#4#2}{####1}}%
  \else
    \csnnewif{#4#2}%
    \def\cpt@rsvda{%
      \cptcheckbool{####1}{option #2}{\usename{#4#2\cpt@resa}}%
    }%
  \fi
  \long\def\cpt@rsvdb##1{%
    \csn@gdef{#1@ds@#2}####1{##1\relax}%
  }%
  \expandafter\cpt@rsvdb\expandafter{\cpt@rsvda#5}%
}
\robust@def*\cpt@declarecmdoptions<#1>#2{%
  \cpt@testopt{\cpt@d@clarecmdoptions{#1}{#2}}{}%
}
\robust@def\cpt@d@clarecmdoptions#1#2[#3]{%
  \cptexpandarg{\cpt@testpnopt{\cpt@d@cl@recmdoptions
    {#1}{#2}{#3}}}{\if\cmdoption cmd\fi\@currname @}%
}
\robust@def\cpt@d@cl@recmdoptions#1#2#3(#4)#5{%
  \trim@@spaces{#1}\cpt@currfam
  \begintoksgroup
  \toks1{{#3}(#4){#5}}%
  \def\csv@do##1{%
    \cpt@badoptionerr{##1}%
    \cptexpanded{%
      \toks@{\the\toks@\relax
        \cpt@d@cl@recmdoption{\cpt@currfam}{##1}\the\toks1
      }%
    }%
  }%
  \csv@@parse[,]{#2}%
  \endtoksgroup
}
\robust@def*\XDeclareBiBooleanOptions{%
  \let\@fileswith@pti@ns\@badrequireerror
  \let\cmdoption\cptswfalse
  \cpt@testfam\cpt@declarebibooloptions
}
\cptnewlet\XDeclareBibooleanOptions\XDeclareBiBooleanOptions
\robust@def*\cpt@declarebibooloptions<#1>#2{%
  \begingroup
  \@tempcnta\z@pt
  \def\csv@do##1{%
    \advance\@tempcnta\@ne
  }%
  \csv@@loop[,]{#2}%
  \ifnum\@tempcnta>\tw@
    \cpt@err{Biboolean options '#2' more than 2}\@ehc
    \aftergroup\@gobble
  \else
    \ifnum\@tempcnta<\tw@
      \cpt@err{Biboolean options '#2' less than 2}\@ehc
      \aftergroup\@gobble
    \fi
  \fi
  \endgroup
  \cpt@testopt{\cpt@d@clarebibooloptions{#1}{#2}}{}%
}
\robust@def\cpt@d@clarebibooloptions#1#2[#3]{%
  \cptexpandarg{\cpt@testpnopt{\cpt@d@cl@rebibooloptions
    {#1}{#2}{#3}}}{\@currname @}%
}
\robust@def\cpt@d@cl@rebibooloptions#1#2#3(#4)#5#6{%
  \edef\cpt@currfam{\cpttrimspaces{#1}}%
  \def\cpt@curropts{#2}%
  \cpt@sttrue\cpt@csvnormalize[,]\cpt@curropts
  \def\cpt@tempa##1,##2\cpt@nil##3{%
    \cpt@newv@riables{tog}{##3@}{##1,##2}[false]%
    \def\cpt@tempa####1####2{%
      \cpt@d@cl@rebib@oloptions{##1}{##2}{#3}{#4}{##3}{####1}%
      \cpt@d@cl@rebib@oloptions{##2}{##1}{#3}{#4}{##3}{####2}%
    }%
  }%
  \cptexpandsecond\cpt@tempa{\cpt@curropts\cpt@nil{\cpt@currfam}}%
  \cpt@tempa{#5}{#6}%
}
% #1: primary option name
% #2: secondary option name
% #3: default value
% #4: macro prefix
% #5: current family
% #6: callback for primary option
\robust@def\cpt@d@cl@rebib@oloptions#1#2#3#4#5#6{%
  \cpt@d@cl@recmdoption{#5}{#1}{#3}(#4){%
    #6\relax
    % If called by sister, don't call back:
    \iftogTF{#5@#1}{}{%
      \settogtrue{#5@#2}%
      \settogtrue{biboolopts}%
      \cptexpandarg{\XExecuteOptions<#5>}{#2=\thebool@reverse{#4#1}}%
      \settogfalse{biboolopts}%
      \settogfalse{#5@#2}%
    }%
  }%
}
\robust@def*\XDeclareSwitchOption{%
  \let\@fileswith@pti@ns\@badrequireerror
  \cpt@testfam\cpt@declareswoption
}
\robust@def*\XDeclareSwitchOptions{%
  \let\@fileswith@pti@ns\@badrequireerror
  \cpt@testfam\cpt@declareswoptions
}
\robust@def*\cpt@declareswoption<#1>#2{%
  \trim@@space{#1}\cpt@currfam
  \trim@@space{#2}\cpt@curropt
  \cpt@badoptionerr\cpt@curropt
  \cptexpandarg\cpt@testopt
    {\cpt@d@clareswoption{\cpt@currfam}{\cpt@curropt}}{}%
}
\robust@def*\cpt@d@clareswoption#1#2[#3]{%
  \cptexpandarg{\cpt@testpnopt{\cpt@d@cl@reswoption
    {#1}{#2}{#3}}}{\@currname @}%
}
\robust@def*\cpt@d@cl@reswoption#1#2#3(#4)#5{%
  \cpt@d@cl@reoption{#1}{#2}{#3}%
  \def\cpt@rsvda{%
    \cptcheckbool{####1}{#2}{%
      \letcsntocsn{#4#2}{cptsw\cpt@resa}%
    }%
  }%
  \long\def\cpt@rsvdb##1{%
    \csn@gdef{#1@ds@#2}####1{##1\relax}%
  }%
  \expandafter\cpt@rsvdb\expandafter{\cpt@rsvda#5}%
}
\robust@def*\cpt@declareswoptions<#1>#2{%
  \cpt@testopt{\cpt@d@clareswoptions{#1}{#2}}{}%
}
\robust@def\cpt@d@clareswoptions#1#2[#3]{%
  \cptexpandarg{\cpt@testpnopt{\cpt@d@cl@reswoptions
    {#1}{#2}{#3}}}{\@currname @}%
}
\robust@def\cpt@d@cl@reswoptions#1#2#3(#4)#5{%
  \trim@@spaces{#1}\cpt@currfam
  \begingroup
  \toks@{{#3}(#4){#5}}%
  \toks1{}%
  \def\csv@do##1{%
    \cpt@badoptionerr{##1}%
    \cptexpanded{%
      \toks1{\the\toks1\relax
        \cpt@d@cl@reswoption{\cpt@currfam}{##1}\the\toks@
      }%
    }%
  }%
  \csv@@parse[,]{#2}%
  \expandafter\endgroup\the\toks1
}
\robust@def\cpt@d@cl@reoption#1#2#3{%
  \ifcsndefTF{#1@declaredoptions}{%
    \xifinsetTF{,\cptoxdetok{#2},}{,\cpt@getdeclaredoptions{#1},}{%
      \cpt@warn{Option '#2' multiply defined\MsgBrk in
        family '#1'\MsgBrk (in \@cls@pkg\@space'\@currname')%
      }%
    }{%
      \aftercsname{\cptoaddtolist*}{#1@declaredoptions}{#2}%
    }%
  }{%
    \csn@xdef{#1@declaredoptions}{\expandcsonce{#2}}%
  }%
  \csn@xdef{#1@ds@#2@default}{%
    \noexpandcsn{#1@ds@#2}{\unexpanded{#3}}%
  }%
}
\robust@def*\XDisableOptions{%
  \cpt@testst{%
    \let\ifcpt@swa\ifcpt@st
    \cpt@testfam\cpt@disableoption
  }%
}
\robust@def*\XDisableOptionsAtBeginDocument{\XDisableOptions*}
\robust@def*\cpt@disableoption<#1>#2{%
  \def\cpt@currfams{#1}%
  \def\cpt@curropts{#2}%
  \def\csv@do##1{%
    \cpt@dis@bleoption{##1}%
  }%
  \csv@@parse*[,]\cpt@currfams
}
\robust@def*\cpt@dis@bleoption#1{%
  \def\csv@do##1{%
    \ifcsndefFT{#1@ds@##1}{%
      \cpt@info{Option '##1' of family '#1'\MsgBrk
        is undeclared: not disabled}
    }{%
      \cptpassexpanded{%
        \ifcpt@swa\noexpand\AtBeginDocument{\fi
          \cptfiltermergekv[,]%
            \noexpandcsn{#1@disabledoptions}{##1}%
            \noexpand\nofilter
          \noexpand\undefcsn{#1@ds@##1@default}%
          \csn@gdef{#1@ds@##1}{%
            \noexpand\@latex@error{%
              Key '##1' of families '#1' is disabled
            }{%
              Key '##1' of family '#1'\MsgBrk
              has been disabled. You can't set or reset\MsgBrk
              it at this late stage. Perhaps you should\MsgBrk
              have set it earlier in \string\documentclass\MsgBrk
              or \string\usepackage
            }%
          }%
        \ifcpt@swa}\fi
      }%
    }%
  }%
  \csv@@parse*[,]\cpt@curropts
}
\robust@def*\XLogDisabledOptions{%
  \ifnextcharTF<\cpt@disabledoptionlist
    \cpt@dis@bledoptionlist
}
\robust@def*\cpt@disabledoptionlist<#1>{%
  \cpt@dis@bledoptionlist{#1}%
}
\robust@def*\cpt@dis@bledoptionlist#1{%
  \def\cpt@disable@a##1{%
    \ifcsndefTF{##1@disabledoptions}{%
      \cpt@info{Disabled options of family '##1':
        ^^J\expandcsnonce{##1@disabledoptions}}%
    }{%
      \cpt@info{No disabled options in family '##1'
        \MsgBrk at this point\ifcsnullTF\@currname{}
        {:\@space You can try the command
        \MsgBrk\noexpand\XLogDisabledOptions again, after
        \MsgBrk begin document}}%
    }%
  }%
  \def\cpt@disable@b##1##2{%
    \cpt@err{Command \noexpand\XLogDisabledOptions issued
      \MsgBrk in document but family name contains
      \MsgBrk ##1 extension \string##2,
      \MsgBrk a preamble command}\@ehc
  }%
  \def\csv@do##1{%
    \ifcsnullFT\@currname{%
      \cpt@disable@a{##1}%
    }{%
      \ifinsetTF\@pkgextension{##1}{%
        \cpt@disable@b{package}\@pkgextension
      }{%
        \ifinsetTF\@clsextension{##1}{%
          \cpt@disable@b{class}\@clsextension
        }{%
          \cpt@disable@a{##1}%
        }%
      }%
    }%
  }%
  \ifblankTF{#1}{}{\csv@@parse{#1}}%
  \undefcs\cpt@disable@a\undefcs\cpt@disable@b
}
\robust@def*\ifoptdisabledTF{%
  \cpt@swatrue\cpt@testfam\cpt@ifoptdisabled
}
\robust@def*\ifoptdisabledFT{%
  \cpt@swafalse\cpt@testfam\cpt@ifoptdisabled
}
\robust@def*\cpt@ifoptdisabled<#1>#2{%
  \def\cpt@currfams{#1}%
  \cpt@choicefdfalse
  \def\csv@do##1{%
    \cpt@ifoptdis@bled{##1}{#2}%
  }%
  \csv@@parse*[,]\cpt@currfams
  \ifdefboolTF{cpt@swa}\ifdefboolTF\ifdefboolFT{cpt@choicefd}%
}
\robust@def*\cpt@ifoptdis@bled#1#2{%
  \ifcsndefFT{#1@disabledoptions}{}{%
    \xifinsetFT{,#2,}{,\expandcsnonce{#1@disabledoptions},}{}{%
      \loopbreak\cpt@choicefdtrue
    }%
  }%
}
\robust@def*\ifoptdefTF{%
  \cpt@swatrue\cpt@testfam\cpt@ifoptdef
}
\robust@def*\ifoptdefFT{%
  \cpt@swafalse\cpt@testfam\cpt@ifoptdef
}
\robust@def*\cpt@ifoptdef<#1>#2{%
  \def\cpt@currfams{#1}%
  \cpt@choicefdfalse
  % may break out of loop:
  \def\csv@do##1{%
    \cpt@ifoptd@f{##1}{#2}%
  }%
  \csv@@parse*[,]\cpt@currfams
  \ifdefboolTF{cpt@swa}\ifdefboolTF\ifdefboolFT{cpt@choicefd}%
}
\robust@def*\cpt@ifoptd@f#1#2{%
  \ifcsndefFT{#1@ds@#2}{}{%
    \cpt@choicefdtrue\loopbreak
  }%
}
\new@def*\cpt@getdeclaredoptions#1{%
  \ifcsndefFT{#1@declaredoptions}{}{%
    \ifcsnnullTF{#1@declaredoptions}{}{%
      \detokenize\cptsevenxp{\usename{#1@declaredoptions}}%
    }%
  }%
}
\robust@def*\XUnknownOptionHandler{%
  \cpt@testfam\cpt@unknownoptionhandler
}
\robust@def*\cpt@unknownoptionhandler<#1>{%
  \cpt@testopt{\cpt@unkn@wnoptionhandler#1}{}%
}
\robust@def*\cpt@unkn@wnoptionhandler#1[#2]#3{%
  \def\cpt@currfams{#1}%
  \edef\reserved@e##1{%
    \csn@def{##1@default@ds}####1####2####3{\unexpanded{#3}}%
  }%
  \def\csv@do##1{%
    \ifcsndefFT{##1@default@ds}{}{%
      \ifcpt@verbose
        \cpt@warn{Unknown option handler for family
          \MsgBrk '##1' replaced}%
      \fi
    }%
    \reserved@e{##1}%
    \csn@def{##1@default@na}{#2}%
  }%
  \csv@@parse*[,]\cpt@currfams
}
\robust@def*\cpt@define@default@ds<#1>#2{%
  \csn@def{#1@default@ds}##1##2##3{#2}%
  \AtEndOfPackage{%
    \let\cpt@define@default@ds\rsv@cpt@define@default@ds
  }%
  \protected\def\cpt@define@default@ds<##1>##2{%
    \cpt@err{'\string\XDeclareOption*' multiply defined in
      \MsgBrk\@cls@pkg\space'\@currname'}{Multiple star
      variant of \noexpand\XDeclareOption in
      \@cls@pkg\@space'\@currname'.}%
  }%
}
\newletcs\rsv@cpt@define@default@ds\cpt@define@default@ds
% In case a \RequirePackage comes up before end of package:
\RecoverAtRequirePackage\cpt@define@default@ds

\new@def*\cpt@optionlist#1{%
  \ifcsndefFT{opt@#1}{}{\unexpanded\cptsevenxp{\usename{opt@#1}}}%
}
% Use \kv@@parse and \csv@@parse for all options processing
% because there might be the need to break out of the loop
% prematurely.
\newletcs\cpt@processedoptions\@empty

\robust@def*\XProcessOptions{%
  \csn@def{\@currname @\@currext @beginprocessopt}{}%
  \letcstocsn\reserved@a{\@currname @\@currext @beforeprocessopt}%
  \letcsntocs{\@currname @\@currext @beforeprocessopt}\relax
  \ifdefTF\reserved@a\reserved@a\relax
  \cpt@inpoxtrue
  \let\@fileswith@pti@ns\@badrequireerror
  \edef\cpt@testname{\@currname.\@currext}%
  \ifx\cpt@testname\cpt@documentclass
    \let\@unusedoptionlist\cpt@classoptionslist
  \fi
  \edef\cpt@classoptions{%
    \ifx\cpt@testname\cpt@documentclass\else
      \expandcsonce\cpt@classoptionslist\fi
  }%
  \edef\@curroptions{\cpt@optionlist{\@currname.\@currext}}%
  \ifcsnullTF\@curroptions{}
    {\cpt@sttrue\cpt@kvnormalize[,]\@curroptions}%
  \cpt@testst{\cpt@testfam\cpt@processoptions}%
}
\robust@def*\cpt@processoptions<#1>{%
  \ifdefboolTF{cpt@st}{%
    \cpt@testopt{\cpt@xprocessoptions#1}{}%
  }{%
    \cpt@testopt{\cpt@yprocessoptions#1}{}%
  }%
}
\robust@def*\cpt@yprocessoptions#1[#2]{%
  \ifblankTF{#2}{%
    \def\cpt@currna{}%
  }{%
    \edef\cpt@currna{\cptcommanormalize{#2}}%
  }%
  \def\csv@do##1{%
    \cpt@ypr@cessoptions{##1}%
  }%
  \csv@@parse{#1}%
  \cpt@pr@cessoptions{#1}%
  \cpt@pr@cessopti@ns
}
\robust@def*\cpt@ypr@cessoptions#1{%
  \def\cpt@currfam{#1}%
  \def\kv@do##1{%
    \edef\CurrentOption{\unexpanded{##1}}%
    \ifcsnullTF\CurrentOption{}{%
      \cpt@findoption@a
      \ifdefboolFT{cpt@optfd}{}{%
        \ifcsndefFT{#1@ds@\cpt@curropt}{}{%
          \ifcsnullTF\cpt@currna{%
            \cpt@igoptfalse
          }{%
            \oifinset@sp@TF,\cpt@curropt\cpt@currna{%
              \cpt@igopttrue
            }{%
              \cpt@igoptfalse
            }%
          }%
          \cpt@useoption
        }%
      }%
    }%
  }%
  \ifxTF\cpt@classoptions\@empty{}{%
    \ifcsndefFT{#1@declaredoptions}{}{%
      \ifcsnnullTF{#1@declaredoptions}{}{%
        \aftercsname{\kv@@parse*}{#1@declaredoptions}%
      }%
    }%
  }%
}
\robust@def*\cpt@xprocessoptions#1[#2]{%
  \ifblankTF{#2}{%
    \def\cpt@currna{}%
  }{%
    \edef\cpt@currna{\cptcommanormalize{#2}}%
  }%
  \def\csv@do##1{%
    \cpt@xpr@cessoptions{##1}%
  }%
  \csv@@parse{#1}%
  \cpt@pr@cessoptions{#1}%
  \cpt@pr@cessopti@ns
}
\robust@def*\cpt@xpr@cessoptions#1{%
  \def\cpt@currfam{#1}%
  \edef\DeclaredOptions{\cpt@getdeclaredoptions\cpt@currfam}%
  \def\kv@do##1{%
    \edef\CurrentOption{\unexpanded{##1}}%
    \ifcsnullTF\CurrentOption{}{%
      \cpt@findoption@b
      \oifinset@sp@FT,\cpt@curropt\DeclaredOptions{}{%
        \ifcsndefFT{#1@ds@\cpt@curropt}{}{%
          \ifcsnullTF\cpt@currna{%
            \cpt@igoptfalse
          }{%
            \oifinset@sp@TF,\cpt@curropt\cpt@currna{%
              \cpt@igopttrue
            }{%
              \cpt@igoptfalse
            }%
          }%
          \cpt@useoption
        }%
      }%
    }%
  }%
  \ifcsnullTF\cpt@classoptions{}
    {\kv@@parse*[,]\cpt@classoptions}%
}
\robust@def*\cpt@pr@cessoptions#1{%
  \def\kv@do##1{%
    \edef\CurrentOption{\unexpanded{##1}}%
    \ifcsnullTF\CurrentOption{}{%
      \cpt@findoption@b
      \def\csv@do####1{%
        \def\cpt@currfam{####1}%
        \ifcsndefTF{\cpt@currfam @ds@\cpt@curropt}{%
          \ifcsnullTF\cpt@currna{%
            \cpt@igoptfalse
          }{%
            \oifinset@sp@TF,\cpt@curropt\cpt@currna{%
              \cpt@igopttrue
            }{%
              \cpt@igoptfalse
            }%
          }%
          \cpt@useoption
        }{%
          \oifinset@sp@TF,\cpt@curropt\XExternalOptions{%
            \ifindefaultdsTF{\PassOptionsToClass}{%
              \cpt@use@default@ds
            }{%
              \ifindefaultdsFT{\PassOptionsToPackage}{}{%
                \cpt@use@default@ds
              }%
            }%
          }{%
            \cpt@addto@undef@opts
            \cpt@use@default@ds
          }%
        }%
      }%
      \csv@@loop[,]{#1}%
    }%
  }%
  \ifcsnullTF\@curroptions{}{\kv@@parse*[,]\@curroptions}%
}
\robust@def*\cpt@pr@cessopti@ns{%
  \let\CurrentOption\@empty
  \undefcs\cpt@classoptions
  \let\@fileswith@pti@ns\@@fileswith@pti@ns
  \cpt@olddxfalse
  \AtEndOfPackage{\let\@unprocessedoptions\relax}%
  \letcstocsn\reserved@a{\@currname @\@currext @afterprocessopt}%
  \letcsntocs{\@currname @\@currext @afterprocessopt}\relax
  \ifdefTF\reserved@a\reserved@a\relax
  \csn@def{\@currname @\@currext @endprocessopt}{}%
}
\robust@def*\ifindefaultdsTF{%
  \begingroup
  \def\reserved@e{\cptiofii\cptiiofii}%
  \cpt@ifin@default@ds
}
\robust@def*\ifindefaultdsFT{%
  \begingroup
  \def\reserved@e{\cptiiofii\cptiofii}%
  \cpt@ifin@default@ds
}
\robust@def*\cpt@ifin@default@ds#1{%
  \let\xp\expandcsonce
  \edef\cpt@ds@a{%
    {\xp\cpt@currfam}{\xp\cpt@curropt}{\xp\cpt@currval}%
  }%
  \edef\cpt@ds@b{\cptmakecs{\cpt@currfam @default@ds}}%
  \edef\cpt@ds@c{%
    \unexpanded\cptsevenxp{\expandafter\cpt@ds@b\cpt@ds@a}%
  }%
  \cptexpanded{%
    \endgroup
    \cpt@csexit\cpt@ds@a\cpt@csexit\cpt@ds@b\cpt@csexit\cpt@ds@c
    \ifinsetTF{\detokenize{#1}}{\cptoxdetok\cpt@ds@c}%
    \xp\reserved@e
  }%
}
\robust@def*\cpt@use@default@ds{%
  \begingroup
  \let\xp\expandcsonce
  \ifcsndefTF{\cpt@currfam @default@na}{}{%
    \csn@def{\cpt@currfam @default@na}{}%
  }%
  \toks@{\default@ds}%
  \ifcsndefFT{\cpt@currfam @default@ds}{}{%
    \edef\cpt@tempa{\expandcsnonce{\cpt@currfam @default@na}}%
    \oifinset@sp@TF,\cpt@curropt\cpt@tempa{}{%
      \ifindefaultdsFT{define/.code=}{%
        \toks@\expandafter{\cpt@ds@c}%
      }{%
        \ifindefaultdsFT{/.end}{%
          \cpt@err{I can't find '/.end' in^^J'\cptoxdetok\cpt@ds@c}\@ehc
        }{%
          \cptexpandmacro\cpt@currval\curr@val
          \despacecontent\curr@val
          \def\cpt@tempb{\XDeclareBooleanOption}%
          \let\cmd\@empty
          \oifstrcmpTF{true}\curr@val{}{%
            \oifstrcmpTF{false}\curr@val{}{%
              \def\cpt@tempb{\XDeclareCommandOption}%
              \def\cmd{cmd}%
            }%
          }%
          \def\cpt@tempa##1define/.code=##2/.end##3\cpt@nil{%
            \cptexpanded{\toks@{%
              \unexpanded{##1##3}%
              \cpt@tempb<\cpt@currfam>{\cpt@curropt}[\xp\curr@val]%
                (\cmd\@currname @){\unexpanded{##2}}%
              \XExecuteOptions<\cpt@currfam>{\cpt@curropt=\xp\curr@val}%
            }}%
          }%
          \expandafter\cpt@tempa\cpt@ds@c\cpt@nil
        }%
      }%
    }%
  }%
  \expandafter\endgroup\the\toks@
}
\robust@def*\XExecuteOptions{%
  \cpt@inpoxfalse
  \cpt@testfam\cpt@executeoptions
}
\robust@def*\cpt@executeoptions<#1>#2{%
  \cpt@testopt{\cpt@ex@cuteoptions{#1}{#2}}{}%
}
\robust@def*\cpt@ex@cuteoptions#1#2[#3]{%
  \def\cpt@currna{#3}%
  \ifcsnullTF\cpt@currna{}{%
    \cpt@sttrue\cpt@csvnormalize[,]\cpt@currna
  }%
  \edef\cpt@curroptvals{\unexpanded{#2}}%
  \ifcsnullTF\cpt@curroptvals{}{%
    \cpt@sttrue\cpt@kvnormalize[,]\cpt@curroptvals
  }%
  \def\csv@do##1{%
    \cpt@ex@cuteopti@ns{##1}%
  }%
  \csv@@parse[,]{#1}%
  \cpt@olddxfalse
  \undefcs\ExecutedOptions
  \undefcs\cpt@execwarnlist
}
\robust@def*\cpt@ex@cuteopti@ns#1{%
  \def\cpt@currfam{#1}%
  \ifnum\cpt@optdepth=\z@pt
    \csn@def{\cpt@currfam @executedoptions}{}%
    \csn@def{\cpt@currfam @exec@warnlist}{}%
  \fi
  \edef\DeclaredOptions{\cpt@getdeclaredoptions\cpt@currfam}%
  \def\kv@do##1{%
    \edef\CurrentOption{\unexpanded{##1}}%
    \ifcsnullTF\CurrentOption{}{%
      \cpt@findoption@b
      \edef\ExecutedOptions{%
        \expandcsnonce{\cpt@currfam @executedoptions}%
      }%
      \edef\cpt@execwarnlist{%
        \expandcsnonce{\cpt@currfam @exec@warnlist}%
      }%
      \oifinset@sp@TF,\cpt@curropt\cpt@currna{}{%
        \cpt@igoptfalse
        \oifinset@sp@TF,\cpt@curropt\DeclaredOptions{%
          \oifinset@sp@TF,\cpt@curropt\ExecutedOptions{%
            \oifinset@sp@TF,\cpt@curropt\cpt@execwarnlist{}{%
              \iftogTF{biboolopts}{}{%
                \ifcpt@verbose
                  \cpt@info{Option '\cpt@curropt' of family
                    '\cpt@currfam'\MsgBrk multiply submitted to
                    \string\XExecuteOptions:\MsgBrk re-executed}%
                \fi
              }%
              \aftercsname{\cptgoaddtolist}
                {\cpt@currfam @exec@warnlist}\cpt@curropt
            }%
          }{%
            \aftercsname{\cptgoaddtolist}
              {\cpt@currfam @executedoptions}\cpt@curropt
          }%
          \cpt@useoption
        }{%
          \cpt@addto@undecl@opts
        }%
      }%
    }%
  }%
  \kv@@loop*[,]\cpt@curroptvals
}
% Alias keys must always come from the parent's family:
\robust@def*\XExecuteAliasOption#1{%
  \cpt@testopt{\cpt@executealiasoption#1}{}%
}
\robust@def*\cpt@executealiasoption#1[#2]{%
  \edef\reserved@a{\ifblankTF{#2}
    {\expandcsonce\cpt@currval}{\unexpanded{#2}}}%
  \cpt@inpoxfalse
  \cptexpandsecond\cpt@executeoptions
    {<\cpt@currfam>{#1=\expandcsonce\reserved@a}}\relax
}
% \OptionFound is always the option with its current value,
% while \CurrentOption may have no value (as in
% \cpt@ypr@cessoptions, the only function calling
% \cpt@findoption@a):
\robust@def\cpt@findoption@a{%
  \cpt@optfdfalse
  \def\kv@do##1{%
    \ifblankTF{##1}{}{%
      \xifinsetTF{=}{\detokenize{##1}}{%
        \cpt@splitoption##1=\opt@split@nil
      }{%
        \edef\cpt@curropt{\unexpanded{##1}}%
        \let\cpt@currval\@empty
      }%
      \ifx\cpt@curropt\CurrentOption
        \cpt@optfdtrue\loopbreak
        \edef\OptionFound{\unexpanded{##1}}%
      \else
        \let\cpt@curropt\@empty
        \let\OptionFound\@empty
      \fi
    }%
  }%
  % This loop may break prematurely:
  \kv@@loop*[,]\cpt@classoptions
}
\robust@def\cpt@findoption@b{%
  % Here \CurrentOption may have a value:
  \let\OptionFound\CurrentOption
  \xifinsetTF{=}{\cptoxdetok\CurrentOption}{%
    \expandafter\cpt@splitoption\CurrentOption=\opt@split@nil
    \let\CurrentOption\cpt@curropt
  }{%
    \let\cpt@curropt\CurrentOption
    \let\cpt@currval\@empty
  }%
}
\robust@def\cpt@splitoption#1=#2\opt@split@nil{%
  \def\cpt@curropt{#1}%
  \ifinsetTF{=\opt@split@nil}{#2\opt@split@nil}{%
    \begingroup
    \defpass\cpt@tempa##1=##2\opt@split@nil{\endgroup
      \edef\cpt@currval{\unexpanded\expandafter{\@gobble##1}}%
    }%
    .#2\opt@split@nil
  }{%
    \edef\cpt@currval{\unexpanded{#2}}%
  }%
}
\robust@def*\cpt@useoption{%
  \ifdefboolFT{cpt@inpox}{}{%
    \oifinset@sp@TF,\OptionFound\cpt@processedoptions{}{%
      \cptgoaddtolist\cpt@processedoptions\OptionFound
    }%
    \oifinset@sp@TF,\CurrentOption\cpt@processedoptions{}{%
      \cptgoaddtolist\cpt@processedoptions\CurrentOption
    }%
    \ifcsnullTF\OptionFound{}{\cpt@removecurroption\OptionFound}%
    \ifcseqTF\OptionFound\CurrentOption{}{%
      \cpt@removecurroption\CurrentOption
    }%
  }%
  \ifdefboolTF{cpt@igopt}{}{%
    % Don't attempt to catch undefined options here:
    \ifcsndefFT{\cpt@currfam @ds@\cpt@curropt}{}{%
      \ifdefboolTF{cpt@olddx}{%
        \usename{\cpt@currfam @ds@\cpt@curropt}%
      }{%
        \ifcsnullTF\cpt@currval{%
          \cptthreexp\cpt@usedefault
          \csname\cpt@currfam @ds@\cpt@curropt
            @default\endcsname\cpt@nil
        }{%
          \cpt@useoption@a
        }%
      }%
    }%
  }%
}
\robust@def*\cpt@useoption@a{%
  \cpt@pushstate\XExecuteOptions\cpt@optionstate\cpt@optdepth
  \cptexpandargonce{\usename{\cpt@currfam @ds@\cpt@curropt}}%
    \cpt@currval\relax
  \cpt@popstate\XExecuteOptions\cpt@optdepth
}
% Only 'article', 'report', 'memoir' options have been added
% to \XExternalOptions. Other external options (eg, those of
% script and KOMA-Script classes) haven't been added.
\new@def*\XExternalOptions{%
  10pt,11pt,12pt,14pt,17pt,20pt,25pt,30pt,36pt,48pt,60pt,%
  a0paper,a1paper,a2paper,a3paper,a4paper,a6paper,%
  b0paper,b1paper,b2paper,b3paper,b4paper,b5paper,b6paper,%
  letterpaper,legalpaper,executivepaper,landscape,oneside,%
  twoside,draft,final,titlepage,notitlepage,onecolumn,%
  twocolumn,leqno,fleqn,openbib,openright,openleft,openany,%
  article,ms,showtrims,oldfontcommands,extrafontsizes,noetex%
}
\robust@def*\AddToExternalOptions#1{%
  \cptfiltermergecsv[,]\XExternalOptions{#1}\nofilter
}
\robust@def*\RemoveFromExternalOptions#1{%
  \cptfilterremovecsv[,]\XExternalOptions{#1}\nofilter
}
\robust@def*\cpt@addto@undecl@opts{%
  \edef\everymergeitem##1{\@space##1}%
  \cptexpandarg{\cptfiltermergekv[;]\cpt@undeclaredopts}%
    {\cpt@currfam,\cpt@curropt,\expandcsonce\cpt@currval}\nofilter
}
\robust@def*\cpt@addto@undef@opts{%
  \edef\everymergeitem##1{\@space##1}%
  \oifinset@sp@TF,\cpt@curropt\XExternalOptions{}{%
    \cptexpandarg{\cptfiltermergekv[;]\cpt@undefinedopts}%
      {\cpt@currfam,\cpt@curropt,\expandcsonce\cpt@currval}\nofilter
  }%
}
\AfterStartOfDocument{\AtEndDocument{%
  % \cpt@undeclaredopts from \XExecuteOptions:
  \ifdefFT\cpt@undeclaredopts{}{%
    \ifcsnullTF\cpt@undeclaredopts{}{%
      \despacecontent\cpt@undeclaredopts
      \cpt@warn{%
        Undeclared options found in \string\XExecuteOptions
        \MsgBrk (family,option,value):
        ^^J\expandcsonce\cpt@undeclaredopts
      }%
    }%
  }%
  % \cpt@undefinedopts from \XProcessOptions:
  \ifdefFT\cpt@undefinedopts{}{%
    \ifcsnullTF\cpt@undefinedopts{}{%
      \despacecontent\cpt@undefinedopts
      \cpt@warn{%
        Undefined options
        \MsgBrk[Family, Option, Value]:
        \MsgBrk\expandcsonce\cpt@undefinedopts.
        \MsgBrk Default action already taken in each case
      }%
    }%
  }%
}}
\robust@def*\cpt@usedefault#1#2\cpt@nil{%
  \ifmacroTF{#1}{%
    \edef\cpt@tempa{\cptremovescape#1}%
  }{%
    \cpt@notcserr{#1}%
  }%
  \edef\cpt@tempb{\cpt@currfam @ds@\cpt@curropt}%
  \@onelevel@sanitize\cpt@tempb
  \ifcseqTF\cpt@tempa\cpt@tempb{%
    \begingroup
    \csn@def{\cpt@currfam @ds@\cpt@curropt}##1{%
      \toks@{\def\cpt@currval{##1}}%
    }%
    \usename{\cpt@currfam @ds@\cpt@curropt @default}%
    \expandafter\endgroup\the\toks@
    \cpt@useoption@a
  }{%
    \cpt@warn{Non-standard default function for option
      '\expandcsonce\cpt@curropt':\MsgBrk Executed anyway}%
    \cpt@pushstate\XExecuteOptions\cpt@optionstate\cpt@optdepth
    \usename{\cpt@currfam @ds@\cpt@curropt @default}\relax
    \cpt@popstate\XExecuteOptions\cpt@optdepth
  }%
}
\robust@def*\cpt@optionstate{%
  \\\cpt@currfams\\\cpt@curroptvals\\\cpt@currfam\\\cpt@currna
  \\\cpt@curropt\\\cpt@currval\\\CurrentOption\\\OptionFound
  \\\ifcpt@inpox\\\ifcpt@optfd\\\ifcpt@igopt\\\DeclaredOptions
  \\\ExecutedOptions
}
\robust@def*\cpt@removecurroption#1{%
  \cptexpandargonce{\cptfilterremovekv[,]%
    \@unusedoptionlist}{#1}\nofilter
}
% Remove processed options from \@unusedoptionlist:
\robust@def*\cpt@optioncleanup#1{%
  \ifmacroTF{#1}{}{\cpt@notcserr{#1}}%
  \BeforeStartOfDocument{%
    \ifdefFT#1{}{%
      \ifcsnullTF#1{}{%
        \ifcsnullTF\@unusedoptionlist{}{%
          \def\csv@do##1{%
            \xifinsetTF{,\detokenize{##1},}%
              {,\cptoxdetok\@unusedoptionlist,}{%
              \cpt@removecurroption{##1}%
            }%
          }%
          \csv@@parse*[,]#1%
        }%
      }%
    }%
    \globalize\@unusedoptionlist
    \def#1{}%
  }%
}
\BeforeStartOfDocument{%
  \cpt@optioncleanup\cpt@processedoptions
}
\robust@redef*\@fileswith@pti@ns#1[#2]#3[#4]{%
  \begingroup
  \edef\fileopts{\unexpanded{#2}}%
  \ifcsnullTF\fileopts{}{\cpt@sttrue\cpt@kvnormalize[,]\fileopts}%
  \def\fileswithopts##1##2{%
    \noexpand\@onefilewithoptions{##1}%
    [\expandcsonce\fileopts]\unexpanded{[#4]##2}%
  }%
  \def\file@withopts##1{\cptpassexpanded{\toks@{##1}}}%
  \toks@{}%
  \ifcseqTF#1\@clsextension{%
    \ifx\@classoptionslist\relax
      \xdef\@classoptionslist{\expandcsonce\fileopts}%
      \file@withopts{\fileswithopts{#3}{#1\@documentclasshook}}%
    \else
      \file@withopts{\fileswithopts{#3}{#1}}%
    \fi
  }{%
    \edef\cpt@tempa{\cptzapspaces{#3}}%
    \DiscardEmptyEntry
    \def\csv@do##1{%
      \file@withopts{\the\toks@\fileswithopts{##1}\@pkgextension}%
    }%
    \csv@@loop*\cpt@tempa
  }%
  \expandafter\endgroup\the\toks@
}
\robust@redef*\@onefilewithoptions#1[#2][#3]#4{%
  \@pushfilename
  \xdef\@currname{#1}%
  \global\let\@currext#4%
  \letcsntocs{\@currname.\@currext-h@@k}\@empty
  \let\CurrentOption\@empty
  \@reset@ptions
  \makeatletter
  \defpass\reserved@a{%
    \@ifl@aded\@currext{#1}{%
      \cpt@ifoptions\@currext{#1}{#2}{}{%
        \edef\reserved@e{\cpt@optionlist{#1.\@currext}}%
        \@onelevel@sanitize\reserved@e
        \despacecontent\reserved@e
        \ltxmsg@err{Option clash for \@cls@pkg\@space #1}{%
          The package '#1' has already been loaded
          with \ifx\reserved@e\@empty no options.\MsgBrk\else
          options:\MsgBrk\@space\@space[\reserved@e].\fi\MsgBrk
          There has now been an attempt to load it with
          \iflacus#2\dolacus no options\else options
          \MsgBrk\@space\@space[\unexpanded{#2}]\fi.
          \MsgBrk Adding the global options:\MsgBrk
          \@space\@space'\ifx\reserved@e\@empty\else
          \reserved@e\ifblankTF{#2}{}{,}\fi\unexpanded{#2}'\MsgBrk
          to your \noexpand\documentclass declaration may fix this.
        }%
      }%
    }{%
      \@pass@ptions\@currext{#2}{#1}%
      \gletcsntocs{ver@\@currname.\@currext}\@empty
      \InputIfFileExists{\@currname.\@currext}{}{%
        \@missingfileerror\@currname\@currext
      }%
      \let\@unprocessedoptions\@@unprocessedoptions
      \usename{\@currname.\@currext-h@@k}%
      \undefcsn{\@currname.\@currext-h@@k}%
      \@unprocessedoptions
    }%
    \def\cpt@tempa####1 v####2 ####3\@nil####4{%
      \edef####4{'####1\ifblankTF{####2}{}{ v####2}'}%
    }%
    \cpt@tempa#3 v \@nil\cpt@tempb
    \cptthreexp\cpt@tempa\csname ver@#1.\@currext
      \expandafter\endcsname\@space v \@nil\cpt@tempc
    \@ifl@ter\@currext{#1}{#3}{}{%
      \cptexpandarg\AtEndDocument{%
        \ltxmsg@warn{%
          You requested,\on@line, version\MsgBrk
          \cpt@tempb\@space of \@cls@pkg\@space #1,\MsgBrk
          but only version \cpt@tempc\MsgBrk is available
        }%
      }%
    }%
    \ifx\@currext
      \@clsextension\let\LoadClass\@twoloadclasserror
    \fi
    \@popfilename
    \@reset@ptions
  }%
}
\robust@def*\cpt@removevalues#1{%
  \cptdocommalist{#1}{\cpt@rem@vevalues{##1}}%
}
\robust@def*\cpt@rem@vevalues#1{%
  \ifcseqTF#1\@empty\cptgobbletorelax\relax
  \xifinsetTF{=}{\cptoxdetok{#1}}{}\cptgobbletorelax
  \begingroup
  \def\cpt@resa{}%
  \def\cpt@resb##1=##2\cpt@nil{%
    \edef\cpt@resa{\csliststack,\cpt@resa\unexpanded{##1}}%
  }%
  \def\kv@do##1{\cpt@resb##1=\cpt@nil}%
  \kv@@parse*{#1}%
  \let#1\cpt@resa
  \postgroupdef#1\endgroup
  \cpt@relax
}
\robust@redef*\ExecuteOptions#1{%
  \cptpushfunctions\ExecuteOptions{\\\CurrentOption}\cpt@optdepth
  \edef\CurrentOption{\unexpanded{#1}}%
  \cpt@sttrue\cpt@kvnormalize[,]\CurrentOption
  \cpt@removevalues\CurrentOption
  \def\csv@do##1{%
    \def\CurrentOption{##1}%
    \csname ds@##1\endcsname
  }%
  \csv@@parse*\CurrentOption
  \cptpopfunctions\ExecuteOptions\cpt@optdepth
}
\robust@redef\@pass@ptions#1#2#3{%
  \begingroup
  \ifntypeTF{#2}{%
    \ifmacroTF{#2}{%
      \let\@expand\expandcsonce
    }{%
      \let\@expand\unexpanded
    }%
  }{%
    \let\@expand\unexpanded
  }%
  \ifcsndefTF{opt@#3.#1}{%
    \ifblankTF{#2}{}{%
      \cptexpandarg{\cptexpandsecond{\cptfiltermergekv[,]}%
        {\cptmakecs{opt@#3.#1}}}{\@expand{#2}}{}%
    }%
  }{%
    \csn@edef{opt@#3.#1}{\@expand{#2}}%
  }%
  \globalizecsn{opt@#3.#1}%
  \endgroup
}
\robust@redef*\OptionNotUsed{%
  \ifxTF\@currext\@clsextension{%
    \cptexpandargonce{\cptfiltermergekv[,]%
      \@unusedoptionlist}\CurrentOption\nofilter
  }{}%
}
\robust@redef*\@use@ption{%
  \oifinset@sp@FT,\CurrentOption\@unusedoptionlist{}{%
    \cptexpandargonce{\cptfilterremovekv[,]%
      \@unusedoptionlist}\CurrentOption\nofilter
  }%
  \csname ds@\CurrentOption\endcsname
}
\let\@@fileswith@pti@ns\@fileswith@pti@ns
\robust@redef*\ProcessOptions{%
  \cptpushfunctions\ProcessOptions{\\\CurrentOption}\cpt@optdepth
  \cpt@sttrue\cpt@csvnormalize[,]\@declaredoptions
  \cpt@sttrue\cpt@kvnormalize[,]\@classoptionslist
  \edef\@curroptions{\cpt@optionlist{\@currname.\@currext}}%
  \cpt@sttrue\cpt@kvnormalize[,]\@curroptions
  \cpt@removevalues{\@classoptionslist,\@curroptions}%
  \let\ds@\@empty
  \cpt@ifstar\@xprocess@ptions\@process@ptions
}
\robust@redef*\@process@ptions{%
  \edef\@curr@ptions{%
    \ifx\@currext\@clsextension\else\expandcsonce
    \@classoptionslist,\fi\expandcsonce\@curroptions
  }%
  \def\csv@do##1{%
    \def\CurrentOption{##1}%
    \oifinset@sp@TF,\CurrentOption\@curr@ptions{%
      \@use@ption
      \letcsntocs{ds@##1}\@empty
    }{}%
  }%
  \csv@@parse*\@declaredoptions
  \@process@pti@ns
}
\robust@redef*\@xprocess@ptions{%
  \ifcseqTF\@currext\@clsextension{}{%
    \def\csv@do##1{%
      \def\CurrentOption{##1}%
      \oifinset@sp@TF,\CurrentOption\@declaredoptions{%
        \@use@ption
        \letcsntocs{ds@##1}\@empty
      }{}%
    }%
    \csv@@parse*\@classoptionslist
  }%
  \@process@pti@ns
}
\robust@redef*\@process@pti@ns{%
  \def\csv@do##1{%
    \def\CurrentOption{##1}%
    \ifcsndefTF{ds@##1}\@use@ption{\@use@ption\default@ds}%
  }%
  \csv@@parse*\@curroptions
  \expandafter\cptfor\@declaredoptions\dofor{%
    \letcsntocs{ds@##1}\relax
  }%
  \cptpopfunctions\ProcessOptions\cpt@optdepth
  \let\@fileswith@pti@ns\@@fileswith@pti@ns
  \AtEndOfPackage{\let\@unprocessedoptions\relax}%
}
% If catoptions is loaded before \documentclass, it will
% automatically use \XDeclareOption, etc. At \documentclass,
% if usepox is false, the package will revert to \DeclareOption,
% etc:
\cptpassunexpanded{%
  \begingroup
  \def\cpt@tempa{\endgroup
    \gnewletcs\cpt@kernelDeclareOption\DeclareOption
    \gnewletcs\cpt@kernelProcessOptions\ProcessOptions
    \gnewletcs\cpt@kernelExecuteOptions\ExecuteOptions
    \gdef\DeclareOption{\cpt@olddxtrue\XDeclareOption}%
    \gdef\ProcessOptions{\cpt@olddxtrue\XProcessOptions}%
    \gdef\ExecuteOptions{\cpt@olddxtrue\XExecuteOptions}%
    \AtEndOfPackage{%
      \ifcpt@usepox\else
        \def\documentclass{%
          \let\documentclass\@twoclasseserror
          \if@compatibility\else
            \def\usepackage{%
              \gletcs\DeclareOption\cpt@kernelDeclareOption
              \gletcs\ProcessOptions\cpt@kernelProcessOptions
              \gletcs\ExecuteOptions\cpt@kernelExecuteOptions
              \cpt@olddxfalse
              \RequirePackage
            }%
          \fi
          \@fileswithoptions\@clsextension
        }%
      \fi
    }%
  }%
  \ifdefTF\cpt@documentclass\endgroup\cpt@tempa
}

\cptonlypreamble{%
  \cptonlypreamble,\cpt@getdocumentclass,\cptloadpackages,
  \ifpackagewithoptionsTF,\ifclasswithoptionsTF,\cpt@ifoptions,
  \cptpushcatcodes,\cptpopcatcodes,\UseNormalCatcodes,
  \StyleFilePurpose,\StyleFileInfo,
  \AfterEndOfStyleFile,\StyleFileRCSInfo,\SetStyleFileMessages,
  \XDeclareOption,\XDeclareOptions,\XDeclareCommandOption,
  \XDeclareCommandOptions,\XDeclareBooleanOption,
  \XDeclareBooleanOptions,\XDeclareBiBooleanOptions,
  \XDeclareSwitchOption,\XDeclareSwitchOptions,
  \XProcessOptions,\XExecuteOptions,\XExecuteAliasOption,
  \cpt@processedoptions,\cpt@optionlist,\cpt@findoption@a,
  \cpt@findoption@b,\cpt@processoptions,\cpt@xprocessoptions,
  \cpt@yprocessoptions,\cpt@pr@cessoptions,\BeforeStartOfDocument,
  \AfterStartOfDocument,\XInvalidOptionHandler,\XDeclareInvalidOption,
  \XDeclareInvalidOptions,\XUnknownOptionHandler,\XExternalOptions,
  \AfterProcessOptions,\BeforeProcessOptions,\loadifnotloaded
}
\XDeclareBiBooleanOptions{verbose,silent}[true](cpt@){}{}
\XDeclareBiBooleanOptions{draft,final}[true](cpt@){}{}
\XDeclareCommandOptions{%
  option-stack-limit,optionstacklimit,key-stack-limit,%
  keystacklimit,key-depth-limit,keydepthlimit%
}[4](cpt@){%
  \xdef\cpt@optionstacklimit{\number#1}%
}
\XDeclareBooleanOption{usepox}[true](cpt@){%
  \ifcpt@usepox
    \AtEndOfPackage{%
      \gdef\DeclareOption{\cpt@olddxtrue\XDeclareOption}%
      \gdef\ProcessOptions{\cpt@olddxtrue\XProcessOptions}%
      \gdef\ExecuteOptions{\cpt@olddxtrue\XExecuteOptions}%
    }%
  \fi
}
\XDisableOptions*{draft,final}
\XDeclareOption*{\cpt@warn{Unknown option '\CurrentOption' ignored}}
\XExecuteOptions{%
  verbose=false,usepox=true,optionstacklimit=4%
}\relax
\XProcessOptions*\relax

\cptpopcatcodes
\cptrestorecatcodes
\declarefutureletset[fl@]{lbracket,star,rquote}

\endinput

%% End of file catoptions.sty %%