% \iffalse
%<*driver>
\documentclass{l3doc}
\OnlyDescription
\begin{document}
\DocInput{gradbars.dtx}
\end{document}
%</driver>
% \fi
% \title{\textsf{gradbars}: documented source}
% \author{SuFan (Tape5try)}
% \date{v1.1.0 / 2026/10/25}
% \maketitle
% \input{docs/source-guide.tex}
% \StopEventually{}
% \section{\texttt{gradbars-accessible.sty}}
%    \begin{macrocode}
%<accessible>% Author: SuFan; MIT License. Opt-in color roles; existing defaults unchanged.
%<accessible>\ProvidesPackage{gradbars-accessible}[2026/10/25 v1.1.0 Accessible color roles]
%<accessible>% Okabe--Ito Color Universal Design palette; see docs/accessibility.md.
%<accessible>\definecolor{gradbarsCudBlue}{HTML}{0072B2}
%<accessible>\definecolor{gradbarsCudOrange}{HTML}{E69F00}
%<accessible>\definecolor{gradbarsCudTeal}{HTML}{009E73}
%<accessible>\definecolor{gradbarsCudSky}{HTML}{56B4E9}
%<accessible>\definecolor{gradbarsCudVermillion}{HTML}{D55E00}
%<accessible>\definecolor{gradbarsCudPurple}{HTML}{CC79A7}
%<accessible>\definecolor{gradbarsCudYellow}{HTML}{F0E442}
%<accessible>\pgfkeys{/gradbars,
%<accessible> .accessible heat roles/.code={\pgfkeysifdefined{/gradbars/heat low color/.@cmd}
%<accessible>   {\pgfkeysalso{/gradbars/heat low color=white,/gradbars/heat high color=gradbarsCudBlue}}{}},
%<accessible> theme/accessible/.style={fill=solid,left color=gradbarsCudBlue,right color=gradbarsCudBlue,
%<accessible>   track color=black!6,text color=auto,negative color=gradbarsCudVermillion},
%<accessible> palette/accessible/.style={theme=accessible,
%<accessible>   stack colors={gradbarsCudBlue,gradbarsCudOrange,gradbarsCudTeal,gradbarsCudPurple,gradbarsCudSky,gradbarsCudVermillion,gradbarsCudYellow},
%<accessible>   stack patterns={none,diagonal,dots,crosshatch,none,diagonal,dots},
%<accessible>   threshold colors={gradbarsCudVermillion,black!15,gradbarsCudBlue},
%<accessible>   compare color=gradbarsCudOrange,spark high color=gradbarsCudBlue,spark low color=gradbarsCudVermillion,
%<accessible>   spark win color=gradbarsCudBlue,spark loss color=gradbarsCudVermillion,spark zero color=black,
%<accessible>   heat center color=white,.accessible heat roles},
%<accessible> heat palette/accessible-sequential/.style={heat palette=sequential,
%<accessible>   heat low color=white,heat high color=gradbarsCudBlue,heat text color=auto},
%<accessible> heat palette/accessible-diverging/.style={heat palette=diverging,
%<accessible>   heat low color=gradbarsCudVermillion,heat high color=gradbarsCudBlue,
%<accessible>   heat center color=white,heat text color=auto}}
%<accessible>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-api.sty}}
%    \begin{macrocode}
%<api>% Author: SuFan; MIT License. Stable version-1 public extension entry points.
%<api>\ProvidesPackage{gradbars-api}[2026/10/25 v1.1.0 gradbars public interfaces]
%<api>\ExplSyntaxOn
%<api>\prop_new:N\g__gradbars_library_files_prop
%<api>\prop_new:N\g__gradbars_library_dependencies_prop
%<api>\prop_new:N\g__gradbars_library_state_prop
%<api>\seq_new:N\g__gradbars_library_stack_seq
%<api>\tl_new:N\l__gradbars_library_file_tl
%<api>\tl_new:N\l__gradbars_library_dependencies_tl
%<api>\bool_new:N\g__gradbars_loader_valid_bool
%<api>\prop_new:N\g__gradbars_type_names_prop
%<api>\prop_new:N\g__gradbars_formatter_names_prop
%<api>\tl_new:N\l__gradbars_public_value_tl
%<api>\seq_new:N\l__gradbars_module_version_seq
%<api>\tl_new:N\g__gradbars_release_version_tl
%<api>\tl_set:Nx\l_tmpa_tl{\use:c{ver@gradbars.sty}}
%<api>\regex_extract_once:nVNTF{v([0-9]+\.[0-9]+\.[0-9]+)}\l_tmpa_tl\l__gradbars_module_version_seq
%<api>  {\tl_gset:Nx\g__gradbars_release_version_tl{\seq_item:Nn\l__gradbars_module_version_seq{2}}}
%<api>  {\PackageError{gradbars}{Load~the~gradbars~entry~package}{Do~not~load~internal~modules~directly.}}
%<api>\cs_generate_variant:Nn\clist_map_inline:nn{Vn}
%<api>\cs_new_protected:Npn\__gradbars_public_error:n #1
%<api>  {\PackageError{gradbars}{#1}{Check~the~public~interface~and~library~requirements.}}
%<api>\cs_new_protected:Npn\__gradbars_check_module:n #1
%<api>  {\tl_set:Nx\l_tmpa_tl{\use:c{ver@#1.sty}}
%<api>   \regex_extract_once:nVNTF{v([0-9]+\.[0-9]+\.[0-9]+)}\l_tmpa_tl\l__gradbars_module_version_seq
%<api>     {\str_if_eq:eeF{\seq_item:Nn\l__gradbars_module_version_seq{2}}{\g__gradbars_release_version_tl}
%<api>        {\bool_gset_false:N\g__gradbars_loader_valid_bool
%<api>         \__gradbars_public_error:n{Mixed~module~versions:~#1~requires~v\g__gradbars_release_version_tl}}}
%<api>     {\bool_gset_false:N\g__gradbars_loader_valid_bool
%<api>      \__gradbars_public_error:n{Missing~module~version:~#1}}}
%<api>\prg_new_protected_conditional:Npnn\__gradbars_name_valid:n #1{TF}
%<api>  {\regex_match:nnTF{\A[a-z][a-z0-9-]*\Z}{#1}{\prg_return_true:}{\prg_return_false:}}
%<api>
%<api>\NewExpandableDocumentCommand\gradbarsversion{}{\tl_use:N\g__gradbars_release_version_tl}
%<api>\seq_new:N\l__gradbars_required_version_seq
%<api>\seq_new:N\l__gradbars_current_version_seq
%<api>\int_new:N\l__gradbars_version_order_int
%<api>\NewDocumentCommand\gradbarsrequireversion{m}
%<api> {\regex_match:nnTF{\A(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\Z}{#1}
%<api>   {\seq_set_split:Nnn\l__gradbars_required_version_seq{.}{#1}
%<api>    \exp_args:NNnV\seq_set_split:Nnn\l__gradbars_current_version_seq{.}\g__gradbars_release_version_tl
%<api>    \int_zero:N\l__gradbars_version_order_int
%<api>    \int_step_inline:nn{3}
%<api>     {\int_compare:nNnT{\l__gradbars_version_order_int}={0}
%<api>       {\int_compare:nNnT{\seq_item:Nn\l__gradbars_current_version_seq{##1}}>
%<api>         {\seq_item:Nn\l__gradbars_required_version_seq{##1}}{\int_set:Nn\l__gradbars_version_order_int{1}}
%<api>        \int_compare:nNnT{\seq_item:Nn\l__gradbars_current_version_seq{##1}}<
%<api>         {\seq_item:Nn\l__gradbars_required_version_seq{##1}}{\int_set:Nn\l__gradbars_version_order_int{-1}}}}
%<api>    \int_compare:nNnT{\l__gradbars_version_order_int}<{0}
%<api>     {\__gradbars_public_error:n{Library~requires~gradbars~#1~or~newer;~installed~\gradbarsversion}}}
%<api>   {\__gradbars_public_error:n{Invalid~required~version:~#1}}}
%<api>
%<api>\NewDocumentCommand\gradbarsdeclarelibrary{m m m}
%<api>  {\__gradbars_name_valid:nTF{#1}
%<api>     {\prop_if_in:NnTF\g__gradbars_library_files_prop{#1}
%<api>        {\__gradbars_public_error:n{Library~already~registered:~#1}}
%<api>        {\prop_gput:Nnn\g__gradbars_library_files_prop{#1}{#3}
%<api>         \prop_gput:Nnn\g__gradbars_library_dependencies_prop{#1}{#2}}}
%<api>     {\__gradbars_public_error:n{Invalid~library~name:~#1}}}
%<api>\cs_new_protected:Npn\__gradbars_load_library:n #1
%<api>  {\prop_get:NnNTF\g__gradbars_library_files_prop{#1}\l__gradbars_library_file_tl
%<api>     {\str_case_e:nnF{\prop_item:Nn\g__gradbars_library_state_prop{#1}}
%<api>        {{loaded}{}{loading}{\bool_gset_false:N\g__gradbars_loader_valid_bool
%<api>           \__gradbars_public_error:n{Circular~library~dependency:~\seq_use:Nn\g__gradbars_library_stack_seq{~->~}~->~#1}}}
%<api>        {\prop_gput:Nnn\g__gradbars_library_state_prop{#1}{loading}
%<api>         \seq_gput_right:Nn\g__gradbars_library_stack_seq{#1}
%<api>         \prop_get:NnN\g__gradbars_library_dependencies_prop{#1}\l__gradbars_library_dependencies_tl
%<api>         \clist_map_inline:Vn\l__gradbars_library_dependencies_tl
%<api>           {\bool_if:NT\g__gradbars_loader_valid_bool{\__gradbars_load_library:n{##1}}}
%<api>         \bool_if:NT\g__gradbars_loader_valid_bool
%<api>           {\prop_get:NnN\g__gradbars_library_files_prop{#1}\l__gradbars_library_file_tl
%<api>            \file_if_exist:VTF\l__gradbars_library_file_tl
%<api>              {\regex_replace_once:nnN{\.sty\Z}{}\l__gradbars_library_file_tl
%<api>               \exp_args:NV\RequirePackage\l__gradbars_library_file_tl
%<api>               \regex_match:nVT{\Agradbars-lib-}\l__gradbars_library_file_tl
%<api>                 {\exp_args:NV\__gradbars_check_module:n\l__gradbars_library_file_tl}
%<api>               \bool_if:NT\g__gradbars_loader_valid_bool
%<api>                 {\prop_gput:Nnn\g__gradbars_library_state_prop{#1}{loaded}}}
%<api>              {\bool_gset_false:N\g__gradbars_loader_valid_bool
%<api>               \__gradbars_public_error:n{Library~file~not~found:~\l__gradbars_library_file_tl}}}
%<api>         \seq_gpop_right:NN\g__gradbars_library_stack_seq\l_tmpa_tl
%<api>         \bool_if:NF\g__gradbars_loader_valid_bool{\prop_gremove:Nn\g__gradbars_library_state_prop{#1}}}}
%<api>     {\bool_gset_false:N\g__gradbars_loader_valid_bool\__gradbars_public_error:n{Unknown~library:~#1}}}
%<api>\NewDocumentCommand\usegradbarslibrary{m}
%<api>  {\bool_gset_true:N\g__gradbars_loader_valid_bool
%<api>   \clist_map_inline:nn{#1}{\bool_if:NT\g__gradbars_loader_valid_bool{\__gradbars_load_library:n{##1}}}}
%<api>\NewDocumentCommand\gradbarsiflibraryloaded{m m m}
%<api>  {\str_if_eq:eeTF{\prop_item:Nn\g__gradbars_library_state_prop{#1}}{loaded}{#2}{#3}}
%<api>\NewDocumentCommand\gradbarsset{m}{\gradbarssetup{#1}}
%<api>\cs_new_protected:Npn\gradbarsCheckFormatter #1
%<api>  {\prop_if_in:NnF\g__gradbars_formatter_names_prop{#1}{\__gradbars_public_error:n{Unknown~formatter:~#1}}}
%<api>\pgfkeys{/gradbars/formatter/.code={\gradbarsCheckFormatter{#1}\def\gradbars@formatter{#1}}}
%<api>\prop_gput:Nnn\g__gradbars_formatter_names_prop{builtin}{builtin}
%<api>\prop_gput:Nnn\g__gradbars_formatter_names_prop{siunitx}{builtin}
%<api>\cs_new_protected:Npn\__gradbars_format_builtin:nnn #1#2#3
%<api>  {\str_if_eq:nnTF{#3}{scientific}
%<api>     {\pgfmathprintnumber[sci,sci~zerofill,precision=#2]{#1}}
%<api>     {\str_if_eq:nnTF{#3}{grouped}
%<api>        {\pgfmathprintnumber[fixed,fixed~zerofill,precision=#2,1000~sep={\mathord{,}}]{#1}}
%<api>        {\pgfmathprintnumber[fixed,fixed~zerofill,precision=#2,1000~sep={\,}]{#1}}}}
%<api>\NewDocumentCommand\gradbarsformatnumber{O{} m}
%<api>  {\group_begin:\pgfkeys{/gradbars,formatter=builtin,precision=1,number~format=fixed,#1}
%<api>   \gradbars@validtrue\gradbarsCheckNumber{#2}{formatter~value}
%<api>   \tl_set:Nx\l_tmpa_tl{\gradbars@precision}
%<api>   \regex_match:nVF{\A[0-6]\Z}\l_tmpa_tl
%<api>     {\gradbarsFail{Precision~must~be~an~integer~from~0~to~6}}
%<api>   \ifgradbars@valid
%<api>     \str_if_eq:eeTF{\gradbars@formatter}{builtin}
%<api>       {\use:x{\exp_not:N\__gradbars_format_builtin:nnn{\fp_eval:n{#2}}{\gradbars@precision}{\gradbars@numberformat}}}
%<api>       {\str_if_eq:eeTF{\gradbars@formatter}{siunitx}
%<api>          {\gradbarsValidateFormatter\gradbarsSIOptions\num{#2}}
%<api>          {\__gradbars_public_error:n{Number~helper~supports~builtin~or~siunitx}}}
%<api>   \fi\group_end:}
%<api>\NewDocumentCommand\gradbarsdeclareformatter{m +m}
%<api>  {\__gradbars_name_valid:nTF{#1}
%<api>     {\prop_if_in:NnTF\g__gradbars_formatter_names_prop{#1}
%<api>        {\__gradbars_public_error:n{Formatter~already~registered:~#1}}
%<api>        {\cs_gset_protected:cpn{__gradbars_formatter_#1:nnn}##1##2##3{#2}
%<api>         \prop_gput:Nnn\g__gradbars_formatter_names_prop{#1}{custom}}}
%<api>     {\__gradbars_public_error:n{Invalid~formatter~name:~#1}}}
%<api>\cs_new_eq:NN\__gradbars_single_label_before_api:\gradbarsSingleLabel
%<api>\cs_set_protected:Npn\gradbarsSingleLabel
%<api>  {\str_if_eq:eeTF{\prop_item:Ne\g__gradbars_formatter_names_prop{\gradbars@formatter}}{custom}
%<api>     {\tl_if_empty:oTF{\gradbars@text}
%<api>        {\ifgradbars@missing\gradbars@missingtext\else
%<api>         \bool_if:NTF\l__gradbars_decimal_active_bool
%<api>           {\__gradbars_public_error:n{Custom~formatters~do~not~support~decimal~alignment}}
%<api>           {\use:x{\exp_not:c{__gradbars_formatter_\gradbars@formatter :nnn}
%<api>                 {\gradbars@number}{\gradbars@precision}{\gradbars@numberformat}}\gradbarsNumericSuffix}\fi}
%<api>        {\gradbars@text}}
%<api>     {\__gradbars_single_label_before_api:}}
%<api>\NewDocumentCommand\gradbarsdeclaretype{m +m}
%<api>  {\__gradbars_name_valid:nTF{#1}
%<api>     {\prop_if_in:NnTF\g__gradbars_type_names_prop{#1}
%<api>        {\__gradbars_public_error:n{Graphic~type~already~registered:~#1}}
%<api>        {\cs_gset_protected:cpn{__gradbars_type_#1:n}##1{#2}
%<api>         \prop_gput:Nnn\g__gradbars_type_names_prop{#1}{custom}}}
%<api>     {\__gradbars_public_error:n{Invalid~graphic~type~name:~#1}}}
%<api>\gradbarsdeclaretype{bar}{\gradbar{#1}}
%<api>\gradbarsdeclaretype{heat}{\gradheat{#1}}
%<api>\NewDocumentCommand\gradgraphic{O{} m m}
%<api>  {\group_begin:\gradbarssetup{#1}
%<api>   \prop_if_in:NnTF\g__gradbars_type_names_prop{#2}
%<api>     {\tl_set:Nn\l__gradbars_public_value_tl{#3}\tl_trim_spaces:N\l__gradbars_public_value_tl
%<api>      \str_if_eq:VnTF\l__gradbars_public_value_tl{NA}
%<api>        {\use:c{__gradbars_type_#2:n}{NA}}
%<api>        {\gradbars@validtrue\gradbarsCheckNumber{#3}{graphic~value}
%<api>         \ifgradbars@valid
%<api>           \use:x{\exp_not:c{__gradbars_type_#2:n}{\fp_eval:n{#3}}}\fi}}
%<api>     {\__gradbars_public_error:n{Unknown~graphic~type:~#2}}
%<api>   \group_end:}
%<api>\cs_new_protected:Npn\__gradbars_unloaded:n #1
%<api>  {\__gradbars_public_error:n{Library~#1~not~loaded;~use~usegradbarslibrary~in~the~preamble}}
%<api>\ProvideDocumentCommand\gradstack{O{} m}{\__gradbars_unloaded:n{stack}}
%<api>\ProvideDocumentCommand\gradspark{O{} m}{\__gradbars_unloaded:n{spark}}
%<api>\ProvideDocumentCommand\gradheat{O{} m}{\__gradbars_unloaded:n{heat}}
%<api>\ProvideDocumentCommand\gradbarscolumn{s m m}{\__gradbars_unloaded:n{csv}}
%<api>\ProvideDocumentCommand\gradbarshead{m}{\__gradbars_unloaded:n{csv}}
%<api>\ProvideDocumentCommand\gradbarsloadcsv{O{} m m}{\__gradbars_unloaded:n{csv}}
%<api>\ProvideDocumentCommand\gradbarcsv{O{} m m m}{\__gradbars_unloaded:n{csv}}
%<api>\ProvideDocumentCommand\gradbarscsvcell{m m m}{\__gradbars_unloaded:n{csv}}
%<api>\ProvideDocumentCommand\gradbarscsvstyle{m m m}{\__gradbars_unloaded:n{csv}}
%<api>\ProvideDocumentCommand\gradbarscsvtable{O{} m m m}{\__gradbars_unloaded:n{csv}}
%<api>\ProvideDocumentEnvironment{gradtable}{O{} +b}{\__gradbars_unloaded:n{table}}{}
%<api>\ProvideDocumentCommand\gradcolumn{O{} m m}{\__gradbars_unloaded:n{table}}
%<api>\ProvideDocumentCommand\gradrow{m}{\__gradbars_unloaded:n{table}}
%<api>\ProvideDocumentCommand\gradsummary{O{} m}{\__gradbars_unloaded:n{table}}
%<api>\ProvideDocumentCommand\gradgroup{m}{\__gradbars_unloaded:n{table}}
%<api>\ProvideDocumentCommand\gradheader{+m}{\__gradbars_unloaded:n{table}}
%<api>\ProvideDocumentCommand\gradspan{m m}{\__gradbars_unloaded:n{table}}
%<api>\ProvideDocumentCommand\gradtablestyle{m m}{\__gradbars_unloaded:n{table}}
%<api>\ProvideDocumentCommand\gradtableschema{m +m}{\__gradbars_unloaded:n{table}}
%<api>\ProvideDocumentCommand\graduseschema{m}{\__gradbars_unloaded:n{table}}
%<api>\cs_new_protected:Npn\__gradbars_tblr_unloaded:
%<api>  {\__gradbars_public_error:n{Load~the~tabularray~gradbars~library~with~UseTblrLibrary}}
%<api>\ProvideDocumentCommand\gradtblrsetup{m}{\__gradbars_tblr_unloaded:}
%<api>\ProvideDocumentCommand\gradtblrcell{O{} m m}{\__gradbars_tblr_unloaded:}
%<api>\ProvideDocumentCommand\gradbarTblr{O{} m}{\__gradbars_tblr_unloaded:}
%<api>\ProvideDocumentCommand\gradheatTblr{O{} m}{\__gradbars_tblr_unloaded:}
%<api>\ProvideDocumentCommand\gradnumberTblr{O{} m}{\__gradbars_tblr_unloaded:}
%<api>\ProvideDocumentCommand\gradcompareTblr{O{} m}{\__gradbars_tblr_unloaded:}
%<api>\ProvideDocumentCommand\gradcorrelation{O{} m}{\__gradbars_unloaded:n{reports}}
%<api>\ProvideDocumentCommand\gradablation{O{} m m}{\__gradbars_unloaded:n{reports}}
%<api>\ProvideDocumentCommand\gradmetric{O{} m}{\__gradbars_unloaded:n{reports}}
%<api>\ProvideDocumentCommand\gradcorrelationcolumn{O{} m m}{\__gradbars_unloaded:n{reports}}
%<api>\ProvideDocumentCommand\gradablationcolumn{O{} m m}{\__gradbars_unloaded:n{reports}}
%<api>\ProvideDocumentCommand\gradmetriccolumn{O{} m m}{\__gradbars_unloaded:n{reports}}
%<api>\ProvideDocumentCommand\gradboxplot{O{} m}{\__gradbars_unloaded:n{distribution}}
%<api>\ProvideDocumentCommand\gradboxsummary{O{} m}{\__gradbars_unloaded:n{distribution}}
%<api>\ProvideDocumentCommand\gradcomputesummary{m +m}{\__gradbars_unloaded:n{distribution}}
%<api>\ProvideDocumentCommand\gradsummarytext{O{} m}{\__gradbars_unloaded:n{distribution}}
%<api>\ProvideDocumentCommand\gradheatlegend{O{}}{\__gradbars_unloaded:n{legend}}
%<api>\ProvideDocumentCommand\gradreferencelegend{O{} m}{\__gradbars_unloaded:n{legend}}
%<api>\ProvideDocumentCommand\gradlegenddefine{m m}{\__gradbars_unloaded:n{legend}}
%<api>\ProvideDocumentCommand\gradlegenduse{O{} m}{\__gradbars_unloaded:n{legend}}
%<api>\ProvideDocumentCommand\gradtblrtagging{m}{\__gradbars_tblr_unloaded:}
%<api>\@onlypreamble\usegradbarslibrary
%<api>\@onlypreamble\gradbarsdeclarelibrary
%<api>\ExplSyntaxOff
%<api>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-backend.sty}}
%    \begin{macrocode}
%<backend>% Author: SuFan; MIT License. Versioned public scalar backend contract.
%<backend>\ProvidesPackage{gradbars-backend}[2026/10/25 v1.1.0 Public backend contract]
%<backend>\ExplSyntaxOn
%<backend>\cs_generate_variant:Nn\clist_if_in:nnTF{Vn}
%<backend>\cs_generate_variant:Nn\clist_if_in:nnF{Vn}
%<backend>\prop_new:N\g__gradbars_backends_prop
%<backend>\prop_new:N\l__gradbars_backend_record_prop
%<backend>\clist_const:Nn\c__gradbars_backend_features_clist
%<backend>  {bar,heat,missing,signed,gradient,print,labels,units,clip,decorations,embedded,tagging,artifact}
%<backend>\clist_const:Nn\c__gradbars_backend_kinds_clist
%<backend>  {bar,heat,stack,spark,compare,dumbbell,range,bullet,boxplot,heat-legend,reference-legend,category-legend}
%<backend>\tl_new:N\l__gradbars_backend_tl
%<backend>\tl_new:N\l__gradbars_backend_fallback_tl
%<backend>\tl_new:N\l__gradbars_backend_native_tl
%<backend>\clist_new:N\l__gradbars_backend_caps_clist
%<backend>\clist_new:N\l__gradbars_backend_required_clist
%<backend>\clist_new:N\l__gradbars_backend_missing_clist
%<backend>\tl_new:N\l__gradbars_backend_kind_tl
%<backend>\bool_new:N\l__gradbars_backend_active_bool
%<backend>\bool_new:N\l__gradbars_backend_default_bool
%<backend>\bool_new:N\l__gradbars_backend_valid_bool
%<backend>\tl_set:Nn\l__gradbars_backend_tl{tikz}
%<backend>\tl_set:Nn\l__gradbars_backend_fallback_tl{error}
%<backend>\prop_gput:Nnn\g__gradbars_backends_prop{tikz}
%<backend> {bar,heat,stack,spark,compare,dumbbell,range,bullet,boxplot,heat-legend,reference-legend,category-legend,missing,signed,gradient,print,labels,units,clip,decorations,embedded,tagging,artifact}
%<backend>\pgfkeys{/gradbars,
%<backend> backend/.code={\prop_if_in:NnTF\g__gradbars_backends_prop{#1}
%<backend>   {\tl_set:Nn\l__gradbars_backend_tl{#1}}
%<backend>   {\__gradbars_public_error:n{Unknown~backend:~#1}}},
%<backend> backend~fallback/.is~choice,
%<backend> backend~fallback/error/.code={\tl_set:Nn\l__gradbars_backend_fallback_tl{error}},
%<backend> backend~fallback/tikz/.code={\tl_set:Nn\l__gradbars_backend_fallback_tl{tikz}}}
%<backend>\NewExpandableDocumentCommand\gradbarsbackendversion{}{1}
%<backend>\NewDocumentCommand\gradbarsdeclarebackend{m m +m}
%<backend> {\bool_set_true:N\l__gradbars_backend_valid_bool
%<backend>  \__gradbars_name_valid:nTF{#1}{}
%<backend>   {\bool_set_false:N\l__gradbars_backend_valid_bool
%<backend>    \__gradbars_public_error:n{Invalid~backend~name:~#1}}
%<backend>  \prop_if_in:NnT\g__gradbars_backends_prop{#1}
%<backend>   {\bool_set_false:N\l__gradbars_backend_valid_bool
%<backend>    \__gradbars_public_error:n{Backend~already~registered:~#1}}
%<backend>  \clist_set:Nn\l__gradbars_backend_caps_clist{#2}
%<backend>  \clist_remove_duplicates:N\l__gradbars_backend_caps_clist
%<backend>  \clist_map_inline:Nn\l__gradbars_backend_caps_clist
%<backend>   {\clist_if_in:NnF\c__gradbars_backend_features_clist{##1}
%<backend>     {\bool_set_false:N\l__gradbars_backend_valid_bool
%<backend>      \__gradbars_public_error:n{Unknown~backend~capability:~##1}}}
%<backend>  \clist_if_in:NnF\l__gradbars_backend_caps_clist{bar}
%<backend>   {\clist_if_in:NnF\l__gradbars_backend_caps_clist{heat}
%<backend>     {\bool_set_false:N\l__gradbars_backend_valid_bool
%<backend>      \__gradbars_public_error:n{Backend~must~support~bar~or~heat}}}
%<backend>  \bool_if:NT\l__gradbars_backend_valid_bool
%<backend>   {\prop_gput:NnV\g__gradbars_backends_prop{#1}\l__gradbars_backend_caps_clist
%<backend>    \cs_gset_protected:cpn{__gradbars_backend_#1:n}##1{#3}}}
%<backend>\NewDocumentCommand\gradbarsifbackendcapable{m m m m}
%<backend> {\prop_get:NnNTF\g__gradbars_backends_prop{#1}\l_tmpa_tl
%<backend>   {\clist_if_in:VnTF\l_tmpa_tl{#2}{#3}{#4}}{#4}}
%<backend>\msg_new:nnn{gradbars}{backend-field}{Backend~record~field~unavailable:~#1.}
%<backend>\NewExpandableDocumentCommand\gradbarsbackendvalue{m}
%<backend> {\bool_if:NTF\l__gradbars_backend_active_bool
%<backend>   {\prop_if_in:NnTF\l__gradbars_backend_record_prop{#1}
%<backend>     {\prop_item:Nn\l__gradbars_backend_record_prop{#1}}
%<backend>     {\msg_expandable_error:nnn{gradbars}{backend-field}{#1}}}
%<backend>   {\msg_expandable_error:nnn{gradbars}{backend-field}{#1}}}
%<backend>\NewDocumentCommand\gradbarsbackendlabel{}
%<backend> {\bool_if:NTF\l__gradbars_backend_active_bool
%<backend>   {{\gradbars@font\gradbarsSingleLabel}}
%<backend>   {\__gradbars_public_error:n{Backend~label~requires~an~active~callback}}}
%<backend>\NewDocumentCommand\gradbarsbackenddefault{}
%<backend> {\bool_if:NTF\l__gradbars_backend_active_bool
%<backend>   {\bool_if:NTF\l__gradbars_backend_default_bool
%<backend>     {\__gradbars_public_error:n{Backend~default~may~be~drawn~only~once}}
%<backend>     {\bool_set_true:N\l__gradbars_backend_default_bool
%<backend>      \tl_use:N\l__gradbars_backend_native_tl}}
%<backend>   {\__gradbars_public_error:n{Backend~default~requires~an~active~callback}}}
%<backend>\cs_new_protected:Npn\__gradbars_backend_record:n #1
%<backend> {\prop_clear:N\l__gradbars_backend_record_prop
%<backend>  \prop_put:Nnn\l__gradbars_backend_record_prop{version}{1}
%<backend>  \prop_put:Nnn\l__gradbars_backend_record_prop{kind}{#1}
%<backend>  \clist_map_inline:nn{min,max,shape,baseline,precision,numberformat,format,better,overflow,label,labelalign,accessibility,
%<backend>    left,right,negativecolor,track,textcolor,text,rounded,pattern,patterncolor,overflowmark,change,changecolor,markershape,markerfill,markersize,target,targetcolor,band,bandcolor,bandopacity,
%<backend>    references,errorminus,errorplus,errorcolor,thresholds,thresholdcolors,unit,unitcode,unittext,missingtext,gap,labelwidth,
%<backend>    baselineshift,heatpalette,heatcenter,heatcentercolor,heatlow,heathigh,heatmissing}
%<backend>   {\cs_if_exist:cT{gradbars@##1}
%<backend>     {\prop_put:Nnx\l__gradbars_backend_record_prop{##1}{\exp_not:v{gradbars@##1}}}}
%<backend>  \prop_put:Nnx\l__gradbars_backend_record_prop{raw-value}{\exp_not:o{\gradbars@value}}
%<backend>  \prop_put:Nnx\l__gradbars_backend_record_prop{width}{\dim_eval:n{\gradbars@width}}
%<backend>  \prop_put:Nnx\l__gradbars_backend_record_prop{height}{\dim_eval:n{\gradbars@height}}
%<backend>  \prop_put:Nnn\l__gradbars_backend_record_prop{missing}{false}
%<backend>  \prop_put:Nnn\l__gradbars_backend_record_prop{print}{false}
%<backend>  \prop_put:Nnn\l__gradbars_backend_record_prop{gradient}{false}
%<backend>  \prop_put:Nnn\l__gradbars_backend_record_prop{tagging}{false}
%<backend>  \prop_put:Nnn\l__gradbars_backend_record_prop{embedded}{false}
%<backend>  \ifpgfpicture\prop_put:Nnn\l__gradbars_backend_record_prop{embedded}{true}\fi
%<backend>  \cs_if_exist:NT\tag_if_active:T{\tag_if_active:T{\prop_put:Nnn\l__gradbars_backend_record_prop{tagging}{true}}}
%<backend>  \ifgradbars@print\prop_put:Nnn\l__gradbars_backend_record_prop{print}{true}\fi
%<backend>  \ifgradbars@gradient\prop_put:Nnn\l__gradbars_backend_record_prop{gradient}{true}\fi
%<backend>  \ifgradbars@missing
%<backend>   \prop_put:Nnn\l__gradbars_backend_record_prop{missing}{true}
%<backend>   \prop_put:Nnn\l__gradbars_backend_record_prop{value}{NA}
%<backend>   \prop_put:Nnn\l__gradbars_backend_record_prop{display-value}{NA}
%<backend>   \prop_put:Nnn\l__gradbars_backend_record_prop{position}{NA}
%<backend>  \else
%<backend>   \prop_put:Nnx\l__gradbars_backend_record_prop{value}{\fp_eval:n{\gradbars@value}}
%<backend>   \prop_put:Nnx\l__gradbars_backend_record_prop{display-value}{\gradbars@number}
%<backend>   \prop_put:Nnx\l__gradbars_backend_record_prop{position}
%<backend>    {\fp_eval:n{max(0,min(1,(\gradbars@value-\gradbars@min)/(\gradbars@max-\gradbars@min)))}}
%<backend>  \fi
%<backend>  \prop_put:Nnx\l__gradbars_backend_record_prop{zero}
%<backend>   {\fp_eval:n{max(0,min(1,-\gradbars@min/(\gradbars@max-\gradbars@min)))}}
%<backend>  \str_if_eq:nnTF{#1}{bar}
%<backend>   {\gradbarsBuildAlt
%<backend>    \clist_map_inline:nn{start,stop,end}
%<backend>     {\prop_put:Nnx\l__gradbars_backend_record_prop{##1}{\use:c{gradbars@##1}}}}
%<backend>   {\convertcolorspec{named}{gradbarsHeatCell}{rgb}\gradbars@rgb
%<backend>    \prop_put:Nno\l__gradbars_backend_record_prop{heat-rgb}{\gradbars@rgb}}
%<backend>  \tl_if_empty:oF{\gradbars@alt}{\tl_set:No\l__gradbars_alt_tl{\gradbars@alt}}
%<backend>  \prop_put:NnV\l__gradbars_backend_record_prop{alt}\l__gradbars_alt_tl
%<backend>  \prop_put:Nnx\l__gradbars_backend_record_prop{percentbase}{\gradbarsPercentBase}}
%<backend>\cs_new_protected:Npn\__gradbars_backend_requirements:n #1
%<backend> {\clist_set:Nn\l__gradbars_backend_required_clist{#1}
%<backend>  \ifgradbars@missing\clist_put_right:Nn\l__gradbars_backend_required_clist{missing}\fi
%<backend>  \fp_compare:nNnT{\gradbars@min}<{0}{\clist_put_right:Nn\l__gradbars_backend_required_clist{signed}}
%<backend>  \str_if_eq:nnT{#1}{bar}
%<backend>   {\ifgradbars@gradient\clist_put_right:Nn\l__gradbars_backend_required_clist{gradient}\fi}
%<backend>  \ifgradbars@print\clist_put_right:Nn\l__gradbars_backend_required_clist{print}\fi
%<backend>  \str_if_eq:eeF{\gradbars@label}{none}{\clist_put_right:Nn\l__gradbars_backend_required_clist{labels}}
%<backend>  \tl_if_empty:oF{\gradbars@unit}{\clist_put_right:Nn\l__gradbars_backend_required_clist{units}}
%<backend>  \tl_if_empty:oF{\gradbars@unitcode}{\clist_put_right:Nn\l__gradbars_backend_required_clist{units}}
%<backend>  \ifgradbars@missing\else
%<backend>   \fp_compare:nT{\gradbars@value<\gradbars@min || \gradbars@value>\gradbars@max}
%<backend>    {\clist_put_right:Nn\l__gradbars_backend_required_clist{clip}}\fi
%<backend>  \dim_compare:nNnT{\gradbars@rounded}>{0pt}{\clist_put_right:Nn\l__gradbars_backend_required_clist{decorations}}
%<backend>  \str_if_eq:nnT{#1}{bar}
%<backend>   {
%<backend>  \str_if_eq:eeF{\gradbars@pattern}{none}{\clist_put_right:Nn\l__gradbars_backend_required_clist{decorations}}
%<backend>  \str_if_eq:eeF{\gradbars@shape}{bar}{\str_if_eq:nnT{#1}{bar}{\clist_put_right:Nn\l__gradbars_backend_required_clist{decorations}}}
%<backend>  \clist_map_inline:nn{target,band,references,errorminus,errorplus,thresholds}
%<backend>   {\tl_set:Nv\l_tmpb_tl{gradbars@##1}
%<backend>    \tl_if_empty:NF\l_tmpb_tl{\clist_put_right:Nn\l__gradbars_backend_required_clist{decorations}}}
%<backend>  \ifgradbars@outline\clist_put_right:Nn\l__gradbars_backend_required_clist{decorations}\fi
%<backend>  \str_if_eq:eeF{\gradbars@overflowmark}{none}{\clist_put_right:Nn\l__gradbars_backend_required_clist{decorations}}
%<backend>  \str_if_eq:eeF{\gradbars@change}{none}{\clist_put_right:Nn\l__gradbars_backend_required_clist{decorations}}
%<backend>   }
%<backend>  \ifpgfpicture\clist_put_right:Nn\l__gradbars_backend_required_clist{embedded}\fi
%<backend>  \cs_if_exist:NT\tag_if_active:T
%<backend>   {\tag_if_active:T
%<backend>     {\str_case_e:nn{\gradbars@accessibility}
%<backend>       {{auto}{\clist_put_right:Nn\l__gradbars_backend_required_clist{tagging}}
%<backend>        {artifact}{\clist_put_right:Nn\l__gradbars_backend_required_clist{artifact}}}}}}
%<backend>\cs_new_protected:Npn\__gradbars_backend_draw:nn #1#2
%<backend> {\str_if_eq:VnTF\l__gradbars_backend_tl{tikz}{#2}
%<backend>   {\group_begin:
%<backend>    \bool_if:NTF\l__gradbars_backend_active_bool
%<backend>     {\__gradbars_public_error:n{Recursive~backend~callback}}
%<backend>     {\clist_set:Nn\l__gradbars_backend_required_clist{#1}
%<backend>      \str_case:nn{#1}{{bar}{\__gradbars_backend_requirements:n{bar}}{heat}{\__gradbars_backend_requirements:n{heat}}}
%<backend>      \prop_get:NVN\g__gradbars_backends_prop\l__gradbars_backend_tl\l_tmpa_tl
%<backend>      \bool_set_true:N\l__gradbars_backend_valid_bool
%<backend>      \clist_clear:N\l__gradbars_backend_missing_clist
%<backend>      \clist_map_inline:Nn\l__gradbars_backend_required_clist
%<backend>       {\clist_if_in:VnF\l_tmpa_tl{##1}{\bool_set_false:N\l__gradbars_backend_valid_bool\clist_put_right:Nn\l__gradbars_backend_missing_clist{##1}}}
%<backend>      \clist_remove_duplicates:N\l__gradbars_backend_missing_clist
%<backend>      \bool_if:NTF\l__gradbars_backend_valid_bool
%<backend>       {\__gradbars_backend_record:n{#1}
%<backend>        \tl_set:Nn\l__gradbars_backend_native_tl{#2}
%<backend>        \bool_set_true:N\l__gradbars_backend_active_bool
%<backend>        \bool_set_false:N\l__gradbars_backend_default_bool
%<backend>        \use:c{__gradbars_backend_\l__gradbars_backend_tl :n}{#1}}
%<backend>       {\str_if_eq:VnTF\l__gradbars_backend_fallback_tl{tikz}{#2}
%<backend>         {\__gradbars_public_error:n{Backend~\l__gradbars_backend_tl~lacks~required~capabilities~for~#1:~\clist_use:Nn\l__gradbars_backend_missing_clist{,~}}}}}
%<backend>    \group_end:}}
%<backend>\cs_new_protected:Npn\__gradbars_backend_core:
%<backend> {\tl_set:Nn\l__gradbars_backend_kind_tl{bar}
%<backend>  \ifgradbars@stack\tl_set:Nn\l__gradbars_backend_kind_tl{stack}\fi
%<backend>  \ifgradbars@spark\tl_set:Nn\l__gradbars_backend_kind_tl{spark}\fi
%<backend>  \ifgradbars@compare\tl_set:Nn\l__gradbars_backend_kind_tl{compare}
%<backend>    \str_if_eq:eeT{\gradbars@shape}{dumbbell}{\tl_set:Nn\l__gradbars_backend_kind_tl{dumbbell}}\fi
%<backend>  \ifgradbars@rangemode\tl_set:Nn\l__gradbars_backend_kind_tl{range}\fi
%<backend>  \ifgradbars@bullet\tl_set:Nn\l__gradbars_backend_kind_tl{bullet}\fi
%<backend>  \exp_args:NV\__gradbars_backend_draw:nn\l__gradbars_backend_kind_tl{\__gradbars_render_tikz:}}
%<backend>\@onlypreamble\gradbarsdeclarebackend
%<backend>\ExplSyntaxOff
%<backend>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-core.sty}}
%    \begin{macrocode}
%<core>% Author: SuFan; MIT License. Internal implementation unless documented.
%<core>\ProvidesPackage{gradbars-core}[2026/10/25 v1.1.0 gradbars core]
%<core>\RequirePackage{tikz}
%<core>\RequirePackage{xparse}
%<core>\RequirePackage{expl3}
%<core>\usetikzlibrary{shadings,patterns}
%<core>\ExplSyntaxOn
%<core>\cs_generate_variant:Nn\prop_put:Nnn{Nxn,Nxx,NVx}
%<core>\ExplSyntaxOff
%<core>\definecolor{gradbarsBlue}{HTML}{2563EB}
%<core>\definecolor{gradbarsBlueLight}{HTML}{93C5FD}
%<core>\definecolor{gradbarsTeal}{HTML}{0F766E}
%<core>\definecolor{gradbarsTealLight}{HTML}{5EEAD4}
%<core>\definecolor{gradbarsViolet}{HTML}{7C3AED}
%<core>\definecolor{gradbarsVioletLight}{HTML}{C4B5FD}
%<core>\definecolor{gradbarsWarmOrange}{HTML}{EA580C}
%<core>\definecolor{gradbarsWarmOrangeLight}{HTML}{FDBA74}
%<core>\definecolor{gradbarsForest}{HTML}{166534}
%<core>\definecolor{gradbarsForestLight}{HTML}{86EFAC}
%<core>\definecolor{gradbarsInk}{HTML}{243247}
%<core>\definecolor{gradbarsTrack}{HTML}{EDF2F7}
%<core>% Public built-in palette.
%<core>\definecolor{lightgreen}{RGB}{144,238,144}
%<core>\definecolor{lightyellow}{RGB}{255,255,224}
%<core>\definecolor{lightblue}{RGB}{173,216,230}
%<core>\definecolor{lightred}{RGB}{255,160,122}
%<core>\definecolor{rose}{RGB}{255,102,204}
%<core>\definecolor{skyblue}{RGB}{135,206,235}
%<core>\definecolor{gold}{RGB}{255,215,0}
%<core>\definecolor{lavender}{RGB}{230,230,250}
%<core>\definecolor{peach}{RGB}{255,218,185}
%<core>\newif\ifgradbars@valid
%<core>\newif\ifgradbars@gradient
%<core>\def\gradbars@width{24mm}
%<core>\def\gradbars@height{1.5ex}
%<core>\def\gradbars@max{100}
%<core>\def\gradbars@min{0}
%<core>\def\gradbars@scalegroup{}
%<core>\def\gradbars@percentbase{}
%<core>\def\gradbars@rounded{0pt}
%<core>\def\gradbars@target{}
%<core>\def\gradbars@targetcolor{gradbarsInk}
%<core>\def\gradbars@negativecolor{lightred}
%<core>\def\gradbars@negativeleft{}
%<core>\def\gradbars@negativeright{}
%<core>\newif\ifgradbars@negativegradient
%<core>\gradbars@negativegradientfalse
%<core>\def\gradbars@thresholds{}
%<core>\def\gradbars@thresholdcolors{lightred,gold,lightgreen}
%<core>\def\gradbars@errorminus{}
%<core>\def\gradbars@errorplus{}
%<core>\def\gradbars@errorcolor{gradbarsInk}
%<core>\newif\ifgradbars@error
%<core>\newsavebox\gradbars@labelbox
%<core>\def\gradbars@precision{1}
%<core>\def\gradbars@unit{}
%<core>\def\gradbars@text{}
%<core>\def\gradbars@alt{}
%<core>\def\gradbars@accessibility{auto}
%<core>\newif\ifgradbars@capturealt
%<core>\def\gradbars@label{outside}
%<core>\def\gradbars@baseline{auto}
%<core>\def\gradbars@baselineshift{0pt}
%<core>\def\gradbars@format{value}
%<core>\def\gradbars@overflow{clip}
%<core>\def\gradbars@gap{.6em}
%<core>\def\gradbars@labelwidth{4.5em}
%<core>\def\gradbars@labelalign{graphic}
%<core>\def\gradbars@font{\relax}
%<core>\newif\ifgradbars@missing
%<core>\newif\ifgradbars@stack
%<core>\newcount\gradbars@styledepth
%<core>\def\gradbars@missingtext{--}
%<core>\def\gradbars@numberformat{fixed}
%<core>\def\gradbars@band{}
%<core>\def\gradbars@bandcolor{gold}
%<core>\def\gradbars@bandopacity{0.3}
%<core>\def\gradbars@stackcolors{gradbarsBlue,gradbarsTeal,gold}
%<core>\RequirePackage{gradbars-keys}
%<core>\pgfkeys{/gradbars,theme=blue}
%<core>\DeclareDocumentCommand\gradbarssetup{m}{\pgfkeys{/gradbars,#1}}
%<core>% Style definitions follow ordinary TeX grouping, like setup.
%<core>\DeclareDocumentCommand\gradbarsstyle{m m}{%
%<core>  \expandafter\def\csname gradbars@style@#1\endcsname{#2}}
%<core>\def\gradbarsUseStyle#1{%
%<core>  \ifcsname gradbars@style@#1\endcsname
%<core>    \ifnum\gradbars@styledepth<32
%<core>      \advance\gradbars@styledepth by 1
%<core>      \expandafter\let\expandafter\gradbars@styleoptions\csname gradbars@style@#1\endcsname
%<core>      \expandafter\pgfkeysalso\expandafter{\gradbars@styleoptions}%
%<core>      \advance\gradbars@styledepth by -1
%<core>    \else\PackageError{gradbars}{Style nesting exceeds 32 levels}{Check for recursive styles.}\fi
%<core>  \else\PackageError{gradbars}{Unknown style: #1}{Define it with gradbarsstyle first.}\fi
%<core>}
%<core>
%<core>% Validate before drawing; floating point arithmetic also supports large counts.
%<core>\ExplSyntaxOn
%<core>
%<core>
%<core>\cs_new_protected:Npn \gradbarsFail #1
%<core>  {\gradbars@validfalse \PackageError{gradbars}{#1}{Check~the~gradbars~options~and~data.}}
%<core>\cs_new_protected:Npn \gradbarsRange #1#2
%<core>  {
%<core>    \fp_compare:nT {#2 < \gradbars@min || #2 > \gradbars@max}
%<core>      {
%<core>        \str_if_eq:eeTF {\gradbars@overflow}{error}
%<core>          {\gradbarsFail{#1~exceeds~range}}
%<core>          {\PackageWarning{gradbars}{#1~exceeds~range;~bar~clipped,~label~unchanged}}
%<core>      }
%<core>  }
%<core>\cs_new:Npn \gradbarsPosition #1
%<core>  {\fp_eval:n {(max(\gradbars@min,min(\gradbars@max,#1))-\gradbars@min)/
%<core>    (\gradbars@max-\gradbars@min)}}
%<core>\clist_new:N \l__gradbars_thresholds_clist
%<core>\clist_new:N \l__gradbars_colors_clist
%<core>\cs_new_protected:Npn \gradbarsValidate
%<core>  {
%<core>    \gradbars@missingfalse
%<core>    \tl_set:Nx \l_tmpa_tl {\gradbars@value}
%<core>    \tl_trim_spaces:N \l_tmpa_tl
%<core>    \tl_if_empty:NT \l_tmpa_tl {\gradbars@missingtrue}
%<core>    \str_if_eq:VnT \l_tmpa_tl {NA} {\gradbars@missingtrue}
%<core>    \ifgradbars@missing \def\gradbars@value{0}\fi
%<core>    \gradbarsCheckNumber{\gradbars@value}{value}
%<core>    \gradbarsCheckNumber{\gradbars@min}{min}
%<core>    \gradbarsCheckNumber{\gradbars@max}{max}
%<core>    \tl_set:Nx \l_tmpa_tl {\gradbars@precision}
%<core>    \regex_match:nVTF {\A [0-6] \Z} \l_tmpa_tl { }
%<core>      {\gradbarsFail{Precision~must~be~an~integer~from~0~to~6}}
%<core>    \ifgradbars@valid
%<core>      \fp_compare:nNnF {\gradbars@max} > {\gradbars@min}
%<core>        {\gradbarsFail{Max~must~be~greater~than~min}}
%<core>      \fp_compare:nNnT {\gradbars@min} = {0}
%<core>        {\fp_compare:nNnT {\gradbars@value} < {0}
%<core>          {\gradbarsFail{Negative~values~require~a~negative~min}}}
%<core>      \str_if_eq:eeT {\gradbars@format}{percent}
%<core>        {\fp_compare:nNnF {\gradbars@min} = {0}
%<core>          {\gradbarsFail{Percent~format~requires~min=0}}\gradbarsValidatePercentBase}
%<core>    \fi
%<core>    \tl_if_empty:oF {\gradbars@target}
%<core>      {\gradbarsCheckNumber{\gradbars@target}{target}}
%<core>    \gradbars@errorfalse
%<core>    \tl_if_empty:oF {\gradbars@errorminus}{\gradbars@errortrue}
%<core>    \tl_if_empty:oF {\gradbars@errorplus}{\gradbars@errortrue}
%<core>    \ifgradbars@error
%<core>      \tl_if_empty:oT {\gradbars@errorminus}{\def\gradbars@errorminus{0}}
%<core>      \tl_if_empty:oT {\gradbars@errorplus}{\def\gradbars@errorplus{0}}
%<core>      \gradbarsCheckNumber{\gradbars@errorminus}{error~minus}
%<core>      \gradbarsCheckNumber{\gradbars@errorplus}{error~plus}
%<core>    \fi
%<core>    \clist_set:Nx \l__gradbars_thresholds_clist {\gradbars@thresholds}
%<core>    \clist_set:Nx \l__gradbars_colors_clist {\gradbars@thresholdcolors}
%<core>    \clist_if_empty:NF \l__gradbars_thresholds_clist
%<core>      {
%<core>        \int_compare:nNnF {\clist_count:N \l__gradbars_thresholds_clist} = {2}
%<core>          {\gradbarsFail{Thresholds~must~contain~two~values}}
%<core>        \int_compare:nNnF {\clist_count:N \l__gradbars_colors_clist} = {3}
%<core>          {\gradbarsFail{Threshold~colors~must~contain~three~colors}}
%<core>        \clist_map_inline:Nn \l__gradbars_thresholds_clist
%<core>          {\gradbarsCheckNumber{##1}{threshold}}
%<core>      }
%<core>    \ifgradbars@valid
%<core>      \ifgradbars@missing\else\gradbarsRange{Value}{\gradbars@value}\fi
%<core>      \tl_if_empty:oF {\gradbars@target}
%<core>        {
%<core>          \fp_compare:nT {\gradbars@target < \gradbars@min || \gradbars@target > \gradbars@max}
%<core>            {\gradbarsFail{Target~must~lie~within~range}}
%<core>          \cs_set:Npx \gradbars@targetpos {\gradbarsPosition{\gradbars@target}}
%<core>        }
%<core>      \ifgradbars@error
%<core>        \fp_compare:nT {\gradbars@errorminus<0 || \gradbars@errorplus<0}
%<core>          {\gradbarsFail{Error~magnitudes~must~be~nonnegative}}
%<core>        \ifgradbars@missing\else
%<core>        \gradbarsRange{Error~lower~endpoint}{\gradbars@value-\gradbars@errorminus}
%<core>        \gradbarsRange{Error~upper~endpoint}{\gradbars@value+\gradbars@errorplus}
%<core>        \cs_set:Npx \gradbars@errorlo
%<core>          {\gradbarsPosition{\gradbars@value-\gradbars@errorminus}}
%<core>        \cs_set:Npx \gradbars@errorhi
%<core>          {\gradbarsPosition{\gradbars@value+\gradbars@errorplus}}
%<core>        \fi
%<core>      \fi
%<core>      \cs_set:Npx \gradbars@zero {\gradbarsPosition{0}}
%<core>      \cs_set:Npx \gradbars@end {\gradbarsPosition{\gradbars@value}}
%<core>      \cs_set:Npx \gradbars@start {\fp_eval:n {min(\gradbars@zero,\gradbars@end)}}
%<core>      \cs_set:Npx \gradbars@stop {\fp_eval:n {max(\gradbars@zero,\gradbars@end)}}
%<core>      \fp_compare:nNnT {\gradbars@value} < {0}
%<core>        {\ifgradbars@negativegradient
%<core>           \gradbars@gradienttrue
%<core>           \ifx\gradbars@negativeleft\@empty
%<core>             \let\gradbars@left\gradbars@negativecolor
%<core>           \else
%<core>             \let\gradbars@left\gradbars@negativeleft
%<core>           \fi
%<core>           \ifx\gradbars@negativeright\@empty
%<core>             \let\gradbars@right\gradbars@negativecolor
%<core>           \else
%<core>             \let\gradbars@right\gradbars@negativeright
%<core>           \fi
%<core>         \else
%<core>           \gradbars@gradientfalse \let\gradbars@left\gradbars@negativecolor
%<core>         \fi}
%<core>      \clist_if_empty:NF \l__gradbars_thresholds_clist
%<core>        {
%<core>          \fp_compare:nNnF {\clist_item:Nn \l__gradbars_thresholds_clist {1}}
%<core>            < {\clist_item:Nn \l__gradbars_thresholds_clist {2}}
%<core>            {\gradbarsFail{Thresholds~must~be~strictly~increasing}}
%<core>          \int_set:Nn \l_tmpa_int {1}
%<core>          \fp_compare:nNnF {\gradbars@value}
%<core>            < {\clist_item:Nn \l__gradbars_thresholds_clist {1}}
%<core>            {\int_set:Nn \l_tmpa_int {2}}
%<core>          \fp_compare:nNnF {\gradbars@value}
%<core>            < {\clist_item:Nn \l__gradbars_thresholds_clist {2}}
%<core>            {\int_set:Nn \l_tmpa_int {3}}
%<core>          \cs_set:Npx \gradbars@left
%<core>            {\clist_item:Nn \l__gradbars_colors_clist
%<core>              {\str_if_eq:eeTF {\gradbars@better}{lower}{4-\l_tmpa_int}{\l_tmpa_int}}}
%<core>          \gradbars@gradientfalse
%<core>        }
%<core>      \str_if_eq:eeTF {\gradbars@format}{percent}
%<core>        {\cs_set:Npx \gradbars@number
%<core>          {\fp_eval:n {100*\gradbars@value/\gradbarsPercentBase}}}
%<core>        {\cs_set:Npx \gradbars@number
%<core>          {\fp_eval:n {\gradbars@value}}}
%<core>    \fi
%<core>  }
%<core>\clist_new:N \l__gradbars_band_clist
%<core>\clist_new:N \l__gradbars_stack_clist
%<core>\clist_new:N \l__gradbars_stackcolors_clist
%<core>\fp_new:N \l__gradbars_sum_fp
%<core>\fp_new:N \l__gradbars_before_fp
%<core>\cs_new_protected:Npn \gradbarsValidateExtras
%<core>  {
%<core>    \clist_set:Nx \l__gradbars_band_clist {\gradbars@band}
%<core>    \clist_if_empty:NF \l__gradbars_band_clist
%<core>      {
%<core>        \tl_set:Nx \l_tmpa_tl {\gradbars@band}
%<core>        \regex_match:nVT {\A\s*,|,\s*,|,\s*\Z} \l_tmpa_tl
%<core>          {\gradbarsFail{Band~must~contain~two~endpoints}}
%<core>        \int_compare:nNnF {\clist_count:N \l__gradbars_band_clist} = {2}
%<core>          {\gradbarsFail{Band~must~contain~two~endpoints}}
%<core>        \clist_map_inline:Nn \l__gradbars_band_clist
%<core>          {\gradbarsCheckNumber{##1}{band~endpoint}}
%<core>        \gradbarsCheckNumber{\gradbars@bandopacity}{band~opacity}
%<core>        \ifgradbars@valid
%<core>          \cs_set:Npx \gradbars@bandlo {\clist_item:Nn \l__gradbars_band_clist {1}}
%<core>          \cs_set:Npx \gradbars@bandhi {\clist_item:Nn \l__gradbars_band_clist {2}}
%<core>          \fp_compare:nF {\gradbars@min <= \gradbars@bandlo < \gradbars@bandhi <= \gradbars@max}
%<core>            {\gradbarsFail{Band~must~be~increasing~and~within~range}}
%<core>          \fp_compare:nF {0 <= \gradbars@bandopacity <= 1}
%<core>            {\gradbarsFail{Band~opacity~must~be~between~zero~and~one}}
%<core>        \fi
%<core>      }
%<core>    \ifgradbars@stack
%<core>      \ifgradbars@valid
%<core>        \gradbarsRange{Positive~stack~total}{\gradbars@positive}
%<core>        \gradbarsRange{Negative~stack~total}{\gradbars@negative}
%<core>        \fp_compare:nNnT {\gradbars@negative} < {0}
%<core>          {\fp_compare:nNnT {\gradbars@min} = {0}
%<core>             {\gradbarsFail{Negative~stack~requires~a~negative~min}}}
%<core>        \cs_set:Npx \gradbars@start {\gradbarsPosition{\gradbars@negative}}
%<core>        \cs_set:Npx \gradbars@stop {\gradbarsPosition{\gradbars@positive}}
%<core>      \fi
%<core>      \tl_if_empty:oF {\gradbars@thresholds}
%<core>        {\gradbarsFail{Stacked~bars~do~not~support~thresholds}}
%<core>      \ifgradbars@error \gradbarsFail{Stacked~bars~do~not~support~error~whiskers}\fi
%<core>      \clist_set:Nx \l__gradbars_stackcolors_clist {\gradbars@stackcolors}
%<core>      \clist_if_empty:NT \l__gradbars_stackcolors_clist
%<core>        {\gradbarsFail{Stack~colors~must~not~be~empty}}
%<core>    \fi
%<core>  }
%<core>\ExplSyntaxOn
%<core>
%<core>
%<core>\ExplSyntaxOff
%<core>
%<core>\RequirePackage{gradbars-model}
%<core>\RequirePackage{gradbars-render-tikz}
%<core>\ExplSyntaxOff
%<core>\DeclareDocumentCommand\gradbar{O{} m}{%
%<core>  \leavevmode\begingroup
%<core>    \gradbarsCaptureTikzAlt
%<core>    \gradbars@capturealttrue
%<core>    \pgfkeys{/gradbars,#1}%
%<core>    \gradbars@capturealtfalse
%<core>    % Resolve font-relative dimensions in the surrounding text font.
%<core>    \ifpgfpicture
%<core>      \pgfinterruptpicture
%<core>      \font@name
%<core>      \edef\gradbars@resolved{%
%<core>        \noexpand\endpgfinterruptpicture
%<core>        \def\noexpand\gradbars@width{\the\dimexpr\gradbars@width\relax}%
%<core>        \def\noexpand\gradbars@height{\the\dimexpr\gradbars@height\relax}%
%<core>        \def\noexpand\gradbars@rounded{\the\dimexpr\gradbars@rounded\relax}%
%<core>        \def\noexpand\gradbars@gap{\the\dimexpr\gradbars@gap\relax}%
%<core>        \def\noexpand\gradbars@labelwidth{\the\dimexpr\gradbars@labelwidth\relax}%
%<core>      }%
%<core>      \gradbars@resolved
%<core>    \fi
%<core>    \def\gradbars@value{#2}%
%<core>    \gradbars@render
%<core>  \endgroup
%<core>}
%<core>
%<core>
%<core>% v0.0.2: labels, legends and collected table columns.
%<core>\def\gradbars@stacknames{}
%<core>\def\gradbars@segmentlabels{none}
%<core>\def\gradbars@segmentfont{\scriptsize}
%<core>\def\gradbars@segmenttextcolor{auto}
%<core>\def\gradbars@labeloverflow{auto}
%<core>\newif\ifgradbars@legend
%<core>\newif\ifgradbars@inside
%<core>\newif\ifgradbars@fit
%<core>\newsavebox\gradbars@segmentbox
%<core>\pgfkeys{/gradbars,
%<core>  stack names/.store in=\gradbars@stacknames,
%<core>  legend/.is if=gradbars@legend,legend/.default=true,
%<core>  segment font/.store in=\gradbars@segmentfont,
%<core>  segment text color/.store in=\gradbars@segmenttextcolor,
%<core>  segment labels/.is choice,
%<core>  segment labels/none/.code=\def\gradbars@segmentlabels{none},
%<core>  segment labels/value/.code=\def\gradbars@segmentlabels{value},
%<core>  segment labels/percent/.code=\def\gradbars@segmentlabels{percent},
%<core>  segment labels/name/.code=\def\gradbars@segmentlabels{name},
%<core>  segment labels/name value/.code=\def\gradbars@segmentlabels{name value},
%<core>  segment labels/name percent/.code=\def\gradbars@segmentlabels{name percent},
%<core>  label overflow/.is choice,
%<core>  label overflow/auto/.code=\def\gradbars@labeloverflow{auto},
%<core>  label overflow/allow/.code=\def\gradbars@labeloverflow{allow}
%<core>}
%<core>\def\gradbarsMeasure#1#2#3{%
%<core>  \sbox#1{\pgfinterruptpicture\font@name #2#3\endpgfinterruptpicture}}
%<core>
%<core>\ExplSyntaxOn
%<core>\clist_new:N \l__gradbars_names_clist
%<core>\seq_new:N \l__gradbars_occupied_seq
%<core>\dim_new:N \l__gradbars_top_dim
%<core>\dim_new:N \l__gradbars_labelbottom_dim
%<core>\dim_new:N \l__gradbars_labelleft_dim
%<core>\dim_new:N \l__gradbars_labelright_dim
%<core>\dim_new:N \l__gradbars_leaderx_dim
%<core>\dim_new:N \l__gradbars_leaderleft_dim
%<core>\dim_new:N \l__gradbars_leaderright_dim
%<core>\fp_new:N \l__gradbars_luminance_fp
%<core>\int_new:N \l__gradbars_index_int
%<core>
%<core>\let\gradbarsValidatePrevious\gradbarsValidateExtras
%<core>\cs_set_protected:Npn \gradbarsValidateExtras
%<core>  {
%<core>    \gradbarsValidatePrevious
%<core>    \clist_set:No \l__gradbars_names_clist {\gradbars@stacknames}
%<core>    \ifgradbars@stack
%<core>      \clist_if_empty:NF \l__gradbars_names_clist
%<core>        {\int_compare:nNnF {\clist_count:N \l__gradbars_names_clist}
%<core>          = {\clist_count:N \l__gradbars_stack_clist}
%<core>          {\gradbarsFail{Stack~names~must~match~the~segment~count}}}
%<core>      \bool_set_false:N \l_tmpa_bool
%<core>      \ifgradbars@legend \bool_set_true:N \l_tmpa_bool \fi
%<core>      \str_case_e:nn {\gradbars@segmentlabels}
%<core>        {{name}{\bool_set_true:N \l_tmpa_bool}
%<core>         {name~value}{\bool_set_true:N \l_tmpa_bool}
%<core>         {name~percent}{\bool_set_true:N \l_tmpa_bool}}
%<core>      \bool_if:NT \l_tmpa_bool
%<core>        {\clist_if_empty:NT \l__gradbars_names_clist
%<core>          {\gradbarsFail{Stack~names~are~required~for~names~or~legend}}}
%<core>      \ifgradbars@legend
%<core>        \ifdim\gradbars@width>14pt\relax\else
%<core>          \gradbarsFail{Legend~width~must~exceed~14pt}\fi
%<core>      \fi
%<core>    \else
%<core>      \ifgradbars@legend \gradbarsFail{Automatic~legend~requires~gradstack}\fi
%<core>    \fi
%<core>  }
%<core>\cs_new_protected:Npn \gradbarsResetLabels
%<core>  {\seq_clear:N \l__gradbars_occupied_seq
%<core>   \dim_set:Nn \l__gradbars_top_dim {\gradbars@height+4pt}}
%<core>\cs_new_protected:Npn \gradbarsCheckOverlap #1#2#3
%<core>  {
%<core>    \dim_compare:nNnT {\l__gradbars_labelleft_dim} < {#2+3pt}
%<core>      {\dim_compare:nNnT {\l__gradbars_labelright_dim} > {#1-3pt}
%<core>        {\dim_set:Nn \l__gradbars_labelbottom_dim
%<core>          {\dim_max:nn {\l__gradbars_labelbottom_dim}{#3+3pt}}}}
%<core>  }
%<core>\cs_new_protected:Npn \gradbarsLeaderBounds #1#2#3
%<core>  {
%<core>    \dim_set:Nn \l__gradbars_leaderleft_dim
%<core>      {\dim_min:nn {\l__gradbars_leaderleft_dim}{#1-4pt}}
%<core>    \dim_set:Nn \l__gradbars_leaderright_dim
%<core>      {\dim_max:nn {\l__gradbars_leaderright_dim}{#2+4pt}}
%<core>  }
%<core>\cs_new_protected:Npn \gradbarsPlaceSegment
%<core>  {
%<core>    \pgfmathsetlengthmacro\gradbars@segmentmid{.5*(\gradbars@segmentlo+\gradbars@segmenthi)}
%<core>    \gradbars@fittrue
%<core>    \ifgradbars@outline\gradbars@fitfalse\fi
%<core>    \ifdim\dimexpr\wd\gradbars@segmentbox+4pt\relax>\dimexpr\gradbars@segmenthi-\gradbars@segmentlo\relax
%<core>      \gradbars@fitfalse\fi
%<core>    \ifdim\dimexpr\ht\gradbars@segmentbox+\dp\gradbars@segmentbox+2pt\relax>\gradbars@height\relax
%<core>      \gradbars@fitfalse\fi
%<core>    \ifx\gradbars@target\@empty\else
%<core>      \pgfmathsetlengthmacro\gradbars@distance{abs(\gradbars@xtarget-\gradbars@segmentmid)}
%<core>      \ifdim\gradbars@distance<\dimexpr.5\wd\gradbars@segmentbox+2pt\relax
%<core>        \gradbars@fitfalse\fi
%<core>    \fi
%<core>    \ifgradbars@fit
%<core>      \let\gradbars@labelcolor\gradbars@segmenttextcolor
%<core>      \str_if_eq:eeT {\gradbars@segmenttextcolor}{auto}{\gradbarsContrast{\gradbars@segmentcolor}}
%<core>      \gradbarsMeasure\gradbars@segmentbox\gradbars@segmentfont{\color{\gradbars@labelcolor}\gradbars@segmentcontent}
%<core>      \node[inner~sep=0pt,outer~sep=0pt,text=\gradbars@labelcolor]
%<core>        [gradbars~label~background]
%<core>        at (\gradbars@segmentmid,.5*\gradbars@height){\usebox\gradbars@segmentbox};
%<core>    \else
%<core>      \pgfmathsetlengthmacro\gradbars@labelx
%<core>        {max(.5*\wd\gradbars@segmentbox,min(\gradbars@segmentmid,\gradbars@width-.5*\wd\gradbars@segmentbox))}
%<core>      \dim_set:Nn \l__gradbars_labelleft_dim {\gradbars@labelx-.5\wd\gradbars@segmentbox}
%<core>      \dim_set:Nn \l__gradbars_labelright_dim {\gradbars@labelx+.5\wd\gradbars@segmentbox}
%<core>      \dim_set:Nn \l__gradbars_labelbottom_dim {\gradbars@height+4pt}
%<core>      \seq_map_inline:Nn \l__gradbars_occupied_seq {\gradbarsCheckOverlap ##1}
%<core>      % Route elevated leaders around earlier label boxes, not through text.
%<core>      \dim_set:Nn \l__gradbars_leaderx_dim {\gradbars@segmentmid}
%<core>      \dim_compare:nNnT {\l__gradbars_labelbottom_dim} > {\gradbars@height+4pt}
%<core>        {
%<core>          \dim_set:Nn \l__gradbars_leaderleft_dim {\gradbars@segmentmid}
%<core>          \dim_set:Nn \l__gradbars_leaderright_dim {\gradbars@segmentmid}
%<core>          \seq_map_inline:Nn \l__gradbars_occupied_seq {\gradbarsLeaderBounds ##1}
%<core>          \dim_compare:nNnTF
%<core>            {\gradbars@segmentmid-\l__gradbars_leaderleft_dim} <
%<core>            {\l__gradbars_leaderright_dim-\gradbars@segmentmid}
%<core>            {\dim_set_eq:NN \l__gradbars_leaderx_dim \l__gradbars_leaderleft_dim}
%<core>            {\dim_set_eq:NN \l__gradbars_leaderx_dim \l__gradbars_leaderright_dim}
%<core>        }
%<core>      \seq_put_right:Nx \l__gradbars_occupied_seq
%<core>        {{\dim_use:N \l__gradbars_labelleft_dim}{\dim_use:N \l__gradbars_labelright_dim}
%<core>          {\dim_eval:n {\l__gradbars_labelbottom_dim+\ht\gradbars@segmentbox+\dp\gradbars@segmentbox}}}
%<core>      \dim_set:Nn \l__gradbars_top_dim {\dim_max:nn {\l__gradbars_top_dim}
%<core>        {\l__gradbars_labelbottom_dim+\ht\gradbars@segmentbox+\dp\gradbars@segmentbox+3pt}}
%<core>      \draw[gradbarsInk!55,line~width=.3pt]
%<core>        (\gradbars@segmentmid,\gradbars@height)--
%<core>        (\gradbars@segmentmid,\dim_eval:n {\gradbars@height+1pt})--
%<core>        (\dim_use:N \l__gradbars_leaderx_dim,\dim_eval:n {\gradbars@height+1pt})--
%<core>        (\dim_use:N \l__gradbars_leaderx_dim,\dim_eval:n {\l__gradbars_labelbottom_dim-2pt})--
%<core>        (\gradbars@labelx,\dim_eval:n {\l__gradbars_labelbottom_dim-2pt});
%<core>      \let\gradbars@labelcolor\gradbars@segmenttextcolor
%<core>      \str_if_eq:eeT {\gradbars@segmenttextcolor}{auto}{\def\gradbars@labelcolor{black}}
%<core>      \gradbarsMeasure\gradbars@segmentbox\gradbars@segmentfont{\color{\gradbars@labelcolor}\gradbars@segmentcontent}
%<core>      \node[anchor=south,inner~sep=0pt,outer~sep=0pt,text=\gradbars@labelcolor]
%<core>        at (\gradbars@labelx,\dim_use:N \l__gradbars_labelbottom_dim){\usebox\gradbars@segmentbox};
%<core>    \fi
%<core>  }
%<core>
%<core>
%<core>\cs_new_protected:Npn \gradbarsMainBackground
%<core>  {
%<core>    \def\gradbars@labelcolor{black}
%<core>    \ifgradbars@inside
%<core>      \let\gradbars@background\gradbars@track
%<core>      \clist_if_empty:NF \l__gradbars_band_clist
%<core>        {\dim_compare:nNnT {\gradbars@labelx} > {\gradbars@bandxlo}
%<core>          {\dim_compare:nNnT {\gradbars@labelx} < {\gradbars@bandxhi}
%<core>            {\edef\gradbars@background{\gradbars@bandcolor!
%<core>               \fp_eval:n {100*\gradbars@bandopacity}!\gradbars@track}}}}
%<core>      \ifdim\gradbars@labelx>\gradbars@xstart\relax
%<core>        \ifdim\gradbars@labelx<\gradbars@xstop\relax
%<core>          \let\gradbars@background\gradbars@left
%<core>          \ifgradbars@gradient
%<core>            \pgfmathparse{100*(\gradbars@labelx-\gradbars@xstart)/(\gradbars@xstop-\gradbars@xstart)}
%<core>            \edef\gradbars@background{\gradbars@right!\pgfmathresult!\gradbars@left}
%<core>          \fi
%<core>          \ifgradbars@stack
%<core>            \fp_zero:N \l__gradbars_sum_fp
%<core>            \int_zero:N \l__gradbars_index_int
%<core>            \clist_map_inline:Nn \l__gradbars_stack_clist
%<core>              {\fp_add:Nn \l__gradbars_sum_fp {##1}\int_incr:N \l__gradbars_index_int
%<core>               \pgfmathsetlengthmacro\gradbars@segmenthi{\gradbarsPosition{\l__gradbars_sum_fp}*(\gradbars@width)}
%<core>               \dim_compare:nNnT {\gradbars@labelx} < {\gradbars@segmenthi}
%<core>               {
%<core>                 \gradbarsCategoryColor{\l__gradbars_index_int}
%<core>                 \let\gradbars@background\gradbars@segmentcolor
%<core>                 \clist_map_break:
%<core>               }}
%<core>          \fi
%<core>        \fi
%<core>      \fi
%<core>      \gradbarsContrast{\gradbars@background}
%<core>    \fi
%<core>  }
%<core>
%<core>\ExplSyntaxOff
%<core>\DeclareDocumentCommand\gradbarslegend{O{} m}{%
%<core>  \begingroup\gradbarsCaptureTikzAlt\gradbars@capturealttrue
%<core>  \pgfkeys{/gradbars,#1,stack names={#2}}\gradbars@capturealtfalse%
%<core>  \begingroup\font@name
%<core>    \edef\gradbars@next{\endgroup
%<core>      \def\noexpand\gradbars@width{\the\dimexpr\gradbars@width\relax}}%
%<core>  \gradbars@next
%<core>  \gradbarsResolveShapeLengths
%<core>  \gradbarsStandaloneLegend
%<core>  \endgroup}
%<core>\ExplSyntaxOn
%<core>\cs_new_protected:Npn \gradbarsStandaloneLegend
%<core>  {
%<core>    \gradbars@validtrue
%<core>    \clist_set:No \l__gradbars_names_clist {\gradbars@stacknames}
%<core>    \clist_set:No \l__gradbars_stackcolors_clist {\gradbars@stackcolors}
%<core>    \clist_if_empty:NT \l__gradbars_names_clist {\gradbarsFail{Legend~names~must~not~be~empty}}
%<core>    \clist_if_empty:NT \l__gradbars_stackcolors_clist {\gradbarsFail{Stack~colors~must~not~be~empty}}
%<core>    \gradbarsValidatePatterns
%<core>    \ifdim\gradbars@width>14pt\else\gradbarsFail{Legend~width~must~exceed~14pt}\fi
%<core>    \ifgradbars@valid
%<core>      \__gradbars_backend_draw:nn{category-legend}
%<core>       {\ifpgfpicture \gradbarsDrawLegend
%<core>      \else\gradbarsPrepareLegendAlt\tikz[baseline=0pt]{\gradbarsDrawLegend}\fi}
%<core>    \fi
%<core>  }
%<core>\ExplSyntaxOff
%<core>\ExplSyntaxOff
%<core>% Data import, print patterns and metric direction (v0.0.2).
%<core>\def\gradbars@better{higher}
%<core>\def\gradbars@pattern{none}
%<core>\def\gradbars@patterncolor{black}
%<core>\def\gradbars@stackpatterns{none}
%<core>\newif\ifgradbars@print
%<core>\pgfkeys{/gradbars,
%<core>  print labels/.is if=gradbars@print,
%<core>  better/.is choice,
%<core>  better/higher/.code=\def\gradbars@better{higher},
%<core>  better/lower/.code=\def\gradbars@better{lower},
%<core>  pattern/.store in=\gradbars@pattern,
%<core>  pattern color/.store in=\gradbars@patterncolor,
%<core>  stack patterns/.store in=\gradbars@stackpatterns,
%<core>  print/.style={outline=false,print labels=true,theme=gray,color=white,track color=black!8,
%<core>    negative color=white,negative fill=solid,text color=black,segment text color=black,
%<core>    pattern=diagonal,pattern color=black,
%<core>    stack colors={white},stack patterns={diagonal,dots,crosshatch},
%<core>    threshold colors={black!10,black!25,black!45}}
%<core>}
%<core>\ExplSyntaxOn
%<core>\prop_const_from_keyval:Nn \c__gradbars_patterns_prop
%<core>  {none=none,diagonal=north~east~lines,reverse=north~west~lines,
%<core>   dots=dots,crosshatch=crosshatch,horizontal=horizontal~lines,vertical=vertical~lines}
%<core>\clist_new:N \l__gradbars_patterns_clist
%<core>\tl_new:N \l__gradbars_pattern_tl
%<core>\cs_new_protected:Npn \gradbarsPatternRect #1#2#3#4#5
%<core>  {
%<core>    \int_compare:nNnTF {#1} = {0}
%<core>      {\tl_set:No \l__gradbars_pattern_tl {\gradbars@pattern}}
%<core>      {\clist_set:No \l__gradbars_patterns_clist {\gradbars@stackpatterns}
%<core>       \tl_set:Nx \l__gradbars_pattern_tl
%<core>         {\clist_item:Nn \l__gradbars_patterns_clist
%<core>           {1+\int_mod:nn {#1-1}{\clist_count:N \l__gradbars_patterns_clist}}}}
%<core>    \gradbarsCategoryPattern{#1}
%<core>    \prop_get:NVNTF \c__gradbars_patterns_prop \l__gradbars_pattern_tl \l__gradbars_pattern_tl
%<core>      {\tl_if_eq:NnF \l__gradbars_pattern_tl {none}
%<core>        {\path[pattern=\l__gradbars_pattern_tl,pattern~color=\gradbars@patterncolor,draw=none]
%<core>          (#2,#3) rectangle (#4,#5);}}
%<core>      {\gradbarsFail{Unknown~pattern}}
%<core>  }
%<core>\cs_new_eq:NN \gradbarsValidateBeforePatterns \gradbarsValidateExtras
%<core>\cs_set_protected:Npn \gradbarsValidateExtras
%<core>  {
%<core>    \gradbarsValidateBeforePatterns
%<core>    \gradbarsValidatePatterns
%<core>  }
%<core>\cs_new_protected:Npn \gradbarsValidatePatterns
%<core>  {
%<core>    \clist_set:No \l__gradbars_patterns_clist {\gradbars@stackpatterns}
%<core>    \clist_if_empty:NT \l__gradbars_patterns_clist {\gradbarsFail{Stack~patterns~must~not~be~empty}}
%<core>    \clist_put_left:No \l__gradbars_patterns_clist {\gradbars@pattern}
%<core>    \clist_map_inline:Nn \l__gradbars_patterns_clist
%<core>      {\prop_if_in:NnF \c__gradbars_patterns_prop {##1}{\gradbarsFail{Unknown~pattern:~##1}}}
%<core>  }
%<core>
%<core>\ExplSyntaxOff
%<core>% Compact comparison shapes and reusable visual presets, v0.0.2.
%<core>\newif\ifgradbars@compare
%<core>\newif\ifgradbars@rangemode
%<core>\newif\ifgradbars@referencemissing
%<core>\newif\ifgradbars@rangemissing
%<core>\newif\ifgradbars@outline
%<core>\def\gradbars@shape{bar}
%<core>\def\gradbars@reference{0}
%<core>\def\gradbars@comparecolor{black!20}
%<core>\def\gradbars@compareratio{.45}
%<core>\def\gradbars@rangelo{0}
%<core>\def\gradbars@rangehi{0}
%<core>\def\gradbars@rangepoint{}
%<core>\def\gradbars@markersize{2pt}
%<core>\def\gradbars@stemwidth{.6pt}
%<core>\def\gradbars@outlinewidth{.4pt}
%<core>\def\gradbars@rowpadding{0pt}
%<core>\pgfkeys{/gradbars,
%<core>  shape/.is choice,
%<core>  shape/bar/.code=\def\gradbars@shape{bar},
%<core>  shape/lollipop/.code=\def\gradbars@shape{lollipop},
%<core>  compare color/.store in=\gradbars@comparecolor,
%<core>  compare ratio/.store in=\gradbars@compareratio,
%<core>  range point/.store in=\gradbars@rangepoint,
%<core>  marker size/.store in=\gradbars@markersize,
%<core>  stem width/.store in=\gradbars@stemwidth,
%<core>  outline/.is if=gradbars@outline,outline/.default=true,
%<core>  outline width/.store in=\gradbars@outlinewidth,
%<core>  row padding/.store in=\gradbars@rowpadding,
%<core>  preset/.is choice,
%<core>  preset/paper/.style={theme=solid,shape=bar,outline=false,
%<core>    height=5pt,rounded=0pt,track color=black!4,label=outside,
%<core>    font=\small,label gap=.35em,row padding=.5pt,pattern=none,stack patterns={none},print labels=false},
%<core>  preset/report/.style={theme=solid,shape=bar,outline=false,
%<core>    height=12pt,rounded=3pt,track color=black!6,label=outside,
%<core>    font=\normalsize,label gap=.6em,row padding=2pt,target color=gradbarsInk,
%<core>    threshold colors={lightred,gold,lightgreen},pattern=none,stack patterns={none},print labels=false},
%<core>  preset/presentation/.style={theme=solid,shape=bar,outline=false,
%<core>    height=18pt,rounded=2pt,label=auto,text color=auto,
%<core>    font=\large,label gap=.7em,row padding=4pt,track color=black!10,
%<core>    pattern=none,stack patterns={none},print labels=false},
%<core>  preset/outline/.style={theme=gray,shape=bar,outline=true,
%<core>    height=7pt,rounded=0pt,track color=white,left color=black!80,
%<core>    compare color=black!35,label=outside,font=\small,
%<core>    outline width=.35pt,stem width=.4pt,label gap=.4em,row padding=1pt,
%<core>    pattern=none,stack patterns={none},print labels=false}
%<core>}
%<core>\def\gradbarsResolveShapeLengths{%
%<core>  \begingroup\font@name
%<core>  \edef\gradbars@next{\endgroup
%<core>    \def\noexpand\gradbars@markersize{\the\dimexpr\gradbars@markersize\relax}%
%<core>    \def\noexpand\gradbars@stemwidth{\the\dimexpr\gradbars@stemwidth\relax}%
%<core>    \def\noexpand\gradbars@outlinewidth{\the\dimexpr\gradbars@outlinewidth\relax}%
%<core>    \def\noexpand\gradbars@leftlabelwidth{\the\dimexpr\gradbars@labelwidth\relax}%
%<core>    \def\noexpand\gradbars@baselineoffset{\the\dimexpr.5ex\relax}%
%<core>    \def\noexpand\gradbars@baselineshift{\the\dimexpr\gradbars@baselineshift\relax}%
%<core>    \def\noexpand\gradbars@rowpadding{\the\dimexpr\gradbars@rowpadding\relax}}%
%<core>  \gradbars@next}
%<core>\DeclareDocumentCommand\gradcompare{O{} m m}{%
%<core>  \begingroup\gradbars@comparetrue
%<core>    \def\gradbars@reference{#2}%
%<core>    \gradbar[shape=bar,#1]{#3}%
%<core>  \endgroup}
%<core>\DeclareDocumentCommand\gradrange{O{} m m}{%
%<core>  \begingroup\gradbars@rangemodetrue
%<core>    \def\gradbars@rangelo{#2}\def\gradbars@rangehi{#3}%
%<core>    \gradbar[shape=bar,#1]{#3}%
%<core>  \endgroup}
%<core>\ExplSyntaxOn
%<core>\cs_new_eq:NN \gradbarsValidateBeforeShapes \gradbarsValidateExtras
%<core>\cs_set_protected:Npn \gradbarsValidateExtras
%<core>  {
%<core>    \gradbarsValidateBeforeShapes
%<core>    \clist_map_inline:nn {markersize,stemwidth,outlinewidth}
%<core>      {\dim_compare:nNnF {\use:c {gradbars@##1}} > {0pt}
%<core>        {\gradbarsFail{Marker~and~line~sizes~must~be~positive}}}
%<core>    \dim_compare:nNnT {\gradbars@rowpadding} < {0pt}
%<core>      {\gradbarsFail{Row~padding~must~be~nonnegative}}
%<core>    \ifgradbars@stack
%<core>      \str_if_eq:eeF {\gradbars@shape}{bar}{\gradbarsFail{Stacked~bars~require~shape=bar}}
%<core>    \fi
%<core>    \ifgradbars@compare
%<core>      \str_case_e:nnF {\gradbars@shape}{{bar}{}{dumbbell}{}}
%<core>        {\gradbarsFail{Comparison~requires~shape=bar~or~dumbbell}}
%<core>      \gradbarsCheckNumber{\gradbars@compareratio}{compare~ratio}
%<core>      \gradbars@referencemissingfalse
%<core>      \tl_set:Nx \l_tmpa_tl {\gradbars@reference}\tl_trim_spaces:N \l_tmpa_tl
%<core>      \tl_if_empty:NT \l_tmpa_tl {\gradbars@referencemissingtrue}
%<core>      \str_if_eq:VnT \l_tmpa_tl {NA}{\gradbars@referencemissingtrue}
%<core>      \ifgradbars@referencemissing\else\gradbarsCheckNumber{\gradbars@reference}{reference}\fi
%<core>      \ifgradbars@valid
%<core>        \fp_compare:nF {0<\gradbars@compareratio<1}{\gradbarsFail{Compare~ratio~must~lie~strictly~between~0~and~1}}
%<core>        \ifgradbars@referencemissing\else
%<core>          \fp_compare:nNnT {\gradbars@min} = {0}
%<core>            {\fp_compare:nNnT {\gradbars@reference} < {0}
%<core>              {\gradbarsFail{Negative~reference~requires~a~negative~min}}}
%<core>          \gradbarsRange{Reference}{\gradbars@reference}
%<core>        \fi
%<core>      \fi
%<core>    \fi
%<core>    \ifgradbars@rangemode
%<core>      \str_if_eq:eeF {\gradbars@shape}{bar}{\gradbarsFail{Range~requires~shape=bar}}
%<core>      \ifgradbars@error\gradbarsFail{Range~bars~do~not~accept~error~whiskers}\fi
%<core>      \clist_if_empty:NF \l__gradbars_thresholds_clist
%<core>        {\gradbarsFail{Range~bars~do~not~accept~thresholds}}
%<core>      \gradbars@rangemissingfalse
%<core>      \tl_set:Nx \l_tmpa_tl {\gradbars@rangelo}\tl_trim_spaces:N \l_tmpa_tl
%<core>      \tl_if_empty:NT \l_tmpa_tl {\gradbars@rangemissingtrue}
%<core>      \str_if_eq:VnT \l_tmpa_tl {NA}{\gradbars@rangemissingtrue}
%<core>      \ifgradbars@rangemissing
%<core>        \ifgradbars@missing\else\gradbarsFail{Both~range~endpoints~must~be~present~or~missing}\fi
%<core>      \else
%<core>        \ifgradbars@missing\gradbarsFail{Both~range~endpoints~must~be~present~or~missing}\fi
%<core>        \gradbarsCheckNumber{\gradbars@rangelo}{range~lower~endpoint}
%<core>      \fi
%<core>      \tl_if_empty:oF {\gradbars@rangepoint}{\gradbarsCheckNumber{\gradbars@rangepoint}{range~point}}
%<core>      \ifgradbars@valid
%<core>        \ifgradbars@missing
%<core>          \tl_if_empty:oF {\gradbars@rangepoint}{\gradbarsFail{Missing~range~cannot~have~a~point}}
%<core>        \else
%<core>          \fp_compare:nNnT {\gradbars@rangelo} > {\gradbars@rangehi}
%<core>            {\gradbarsFail{Range~lower~endpoint~must~not~exceed~upper}}
%<core>          \fp_compare:nNnT {\gradbars@min} = {0}
%<core>            {\fp_compare:nNnT {\gradbars@rangelo} < {0}
%<core>              {\gradbarsFail{Negative~range~requires~a~negative~min}}}
%<core>          \gradbarsRange{Range~lower~endpoint}{\gradbars@rangelo}
%<core>          \tl_if_empty:oF {\gradbars@rangepoint}
%<core>            {\fp_compare:nF {\gradbars@rangelo<=\gradbars@rangepoint<=\gradbars@rangehi}
%<core>              {\gradbarsFail{Range~point~must~lie~between~endpoints}}}
%<core>          \cs_set:Npx \gradbars@start {\gradbarsPosition{\gradbars@rangelo}}
%<core>          \cs_set:Npx \gradbars@stop {\gradbarsPosition{\gradbars@rangehi}}
%<core>        \fi
%<core>      \fi
%<core>    \else
%<core>      \tl_if_empty:oF {\gradbars@rangepoint}{\gradbarsFail{Range~point~requires~gradrange}}
%<core>    \fi
%<core>  }
%<core>% Format each endpoint independently using the ordinary number formatter.
%<core>\cs_new_eq:NN \gradbarsSingleLabel \gradbars@labelcontent
%<core>\cs_new_protected:Npn \gradbarsFormatEndpoint #1
%<core>  {\group_begin:\gradbars@missingfalse\def\gradbars@text{}
%<core>   \cs_set:Npx \gradbars@number {\fp_eval:n {#1}}
%<core>   \str_if_eq:eeT {\gradbars@format}{percent}
%<core>     {\cs_set:Npx \gradbars@number {\fp_eval:n {100*(#1)/\gradbarsPercentBase}}}
%<core>   \gradbarsSingleLabel\group_end:}
%<core>\cs_set_protected:Npn \gradbars@labelcontent
%<core>  {
%<core>    \tl_if_empty:oTF {\gradbars@text}
%<core>      {\ifgradbars@compare
%<core>         \gradbarsSingleLabel\,/\,
%<core>         \ifgradbars@referencemissing\gradbars@missingtext
%<core>         \else\gradbarsFormatEndpoint{\gradbars@reference}\fi
%<core>       \else\ifgradbars@rangemode
%<core>         \ifgradbars@missing\gradbars@missingtext
%<core>         \else[\gradbarsFormatEndpoint{\gradbars@rangelo},\,
%<core>               \gradbarsFormatEndpoint{\gradbars@rangehi}]\fi
%<core>       \else\gradbarsSingleLabel\fi\fi}
%<core>      {\gradbars@text}
%<core>  }
%<core>
%<core>
%<core>
%<core>\ExplSyntaxOff
%<core>
%<core>
%<core>% v0.0.3: comparison, signed compositions, series and semantic palettes.
%<core>\definecolor{gradbarsOrange}{HTML}{D55E00}
%<core>\definecolor{gradbarsPurple}{HTML}{AA4499}
%<core>\definecolor{gradbarsCyan}{HTML}{56B4E9}
%<core>\definecolor{gradbarsGreen}{HTML}{009E73}
%<core>\def\gradbars@comparelabel{values}
%<core>\def\gradbars@stacktotals{net}
%<core>\def\gradbars@qualitytarget{}
%<core>\def\gradbars@qualityrange{}
%<core>\def\gradbars@sparkrange{auto}
%<core>\def\gradbars@sparkpoints{extrema}
%<core>\def\gradbars@sparkhigh{gradbarsTeal}
%<core>\def\gradbars@sparklow{gradbarsOrange}
%<core>\newif\ifgradbars@spark
%<core>\pgfkeys{/gradbars,
%<core>  shape/dumbbell/.code=\def\gradbars@shape{dumbbell},
%<core>  shape/sparkline/.code=\def\gradbars@shape{sparkline},
%<core>  compare label/.is choice,
%<core>  compare label/values/.code=\def\gradbars@comparelabel{values},
%<core>  compare label/delta/.code=\def\gradbars@comparelabel{delta},
%<core>  stack totals/.is choice,
%<core>  stack totals/net/.code=\def\gradbars@stacktotals{net},
%<core>  stack totals/separate/.code=\def\gradbars@stacktotals{separate},
%<core>  better/target/.code=\def\gradbars@better{target},
%<core>  better/interval/.code=\def\gradbars@better{interval},
%<core>  quality target/.store in=\gradbars@qualitytarget,
%<core>  quality range/.store in=\gradbars@qualityrange,
%<core>  spark range/.is choice,
%<core>  spark range/auto/.code=\def\gradbars@sparkrange{auto},
%<core>  spark range/fixed/.code=\def\gradbars@sparkrange{fixed},
%<core>  spark points/.is choice,
%<core>  spark points/extrema/.code=\def\gradbars@sparkpoints{extrema},
%<core>  spark points/all/.code=\def\gradbars@sparkpoints{all},
%<core>  spark points/last/.code=\def\gradbars@sparkpoints{last},
%<core>  spark points/none/.code=\def\gradbars@sparkpoints{none},
%<core>  spark high color/.store in=\gradbars@sparkhigh,
%<core>  spark low color/.store in=\gradbars@sparklow,
%<core>  palette/.is choice,
%<core>  palette/categorical/.style={stack colors={gradbarsBlue,gradbarsOrange,gradbarsGreen,gradbarsPurple,gradbarsCyan,gold},
%<core>    stack patterns={none},compare color=gradbarsOrange,negative color=gradbarsOrange},
%<core>  palette/sequential/.style={stack colors={gradbarsBlue!20,gradbarsBlue!40,gradbarsBlue!60,gradbarsBlue!80,gradbarsBlue},
%<core>    stack patterns={none}},
%<core>  palette/diverging/.style={stack colors={gradbarsOrange!85,gradbarsOrange!40,black!12,gradbarsTeal!40,gradbarsTeal!85},
%<core>    threshold colors={gradbarsOrange,gold,gradbarsTeal},negative color=gradbarsOrange,
%<core>    compare color=gradbarsOrange,left color=gradbarsTeal,right color=gradbarsTeal!35,stack patterns={none}},
%<core>  palette/mono/.style={print,stack colors={white,black!10,black!20},
%<core>    stack patterns={diagonal,dots,crosshatch},compare color=black!45,
%<core>    spark high color=black,spark low color=black},
%<core>}
%<core>\DeclareDocumentCommand\graddumbbell{O{} m m}{%
%<core>  \gradcompare[#1,shape=dumbbell]{#2}{#3}}
%<core>\ExplSyntaxOn
%<core>\ExplSyntaxOn
%<core>% Category identity is scoped and keyed by literal names, independent of order.
%<core>\prop_new:N \l__gradbars_category_colors_prop
%<core>\prop_new:N \l__gradbars_category_patterns_prop
%<core>\DeclareDocumentCommand\gradbarscategory{m m m}
%<core>  {
%<core>    \tl_if_blank:nTF {#1}{\gradbarsFail{Category~name~must~not~be~empty}}
%<core>      {\prop_if_in:NnTF \c__gradbars_patterns_prop {#3}
%<core>        {\prop_put:Nnn \l__gradbars_category_colors_prop {#1}{#2}
%<core>         \prop_put:Nnn \l__gradbars_category_patterns_prop {#1}{#3}}
%<core>        {\gradbarsFail{Unknown~category~pattern}}}
%<core>  }
%<core>\cs_new_protected:Npn \gradbarsCategoryColor #1
%<core>  {
%<core>    \cs_set:Npx \gradbars@segmentcolor
%<core>      {\clist_item:Nn \l__gradbars_stackcolors_clist
%<core>        {1+\int_mod:nn {#1-1}{\clist_count:N \l__gradbars_stackcolors_clist}}}
%<core>    \tl_set:Nx \l_tmpa_tl {\clist_item:Nn \l__gradbars_names_clist {#1}}
%<core>    \ifgradbars@print\else
%<core>      \prop_get:NVNT \l__gradbars_category_colors_prop \l_tmpa_tl \l_tmpb_tl
%<core>        {\cs_set:Npx \gradbars@segmentcolor {\exp_not:V \l_tmpb_tl}}
%<core>    \fi
%<core>  }
%<core>\cs_new_protected:Npn \gradbarsCategoryPattern #1
%<core>  {
%<core>    \int_compare:nNnT {#1} > {0}
%<core>      {\tl_set:Nx \l_tmpa_tl {\clist_item:Nn \l__gradbars_names_clist {#1}}
%<core>       \prop_get:NVNT \l__gradbars_category_patterns_prop \l_tmpa_tl \l_tmpb_tl
%<core>         {\tl_set_eq:NN \l__gradbars_pattern_tl \l_tmpb_tl}}
%<core>  }
%<core>\fp_new:N \l__gradbars_distance_fp
%<core>\clist_new:N \l__gradbars_quality_clist
%<core>\cs_new_protected:Npn \gradbarsQuality
%<core>  {
%<core>    \str_case_e:nn {\gradbars@better}
%<core>      {{target}{\gradbarsCheckNumber{\gradbars@qualitytarget}{quality~target}}
%<core>       {interval}{\clist_set:Nx \l__gradbars_quality_clist {\gradbars@qualityrange}
%<core>         \tl_set:Nx \l_tmpa_tl {\gradbars@qualityrange}
%<core>         \regex_match:nVT {\A\s*,|,\s*,|,\s*\Z} \l_tmpa_tl
%<core>           {\gradbarsFail{Quality~range~requires~two~endpoints}}
%<core>         \int_compare:nNnF {\clist_count:N \l__gradbars_quality_clist} = {2}
%<core>           {\gradbarsFail{Quality~range~requires~two~endpoints}}
%<core>         \clist_map_inline:Nn \l__gradbars_quality_clist
%<core>           {\gradbarsCheckNumber{##1}{quality~endpoint}}}}
%<core>    \clist_if_empty:NT \l__gradbars_thresholds_clist
%<core>      {\gradbarsFail{Target~and~interval~quality~require~distance~thresholds}}
%<core>    \ifgradbars@stack\gradbarsFail{Stack~does~not~support~quality~evaluation}\fi
%<core>    \ifgradbars@rangemode\gradbarsFail{Range~does~not~support~quality~evaluation}\fi
%<core>    \ifgradbars@valid
%<core>      \fp_compare:nNnT {\clist_item:Nn \l__gradbars_thresholds_clist {1}} < {0}
%<core>        {\gradbarsFail{Distance~thresholds~must~be~nonnegative}}
%<core>      \str_if_eq:eeTF {\gradbars@better}{target}
%<core>        {\fp_set:Nn \l__gradbars_distance_fp {abs(\gradbars@value-\gradbars@qualitytarget)}}
%<core>        {\fp_compare:nNnT {\clist_item:Nn \l__gradbars_quality_clist {1}}
%<core>           > {\clist_item:Nn \l__gradbars_quality_clist {2}}
%<core>           {\gradbarsFail{Quality~range~must~be~ordered}}
%<core>         \fp_set:Nn \l__gradbars_distance_fp
%<core>           {max(0,\clist_item:Nn \l__gradbars_quality_clist {1}-\gradbars@value,
%<core>             \gradbars@value-\clist_item:Nn \l__gradbars_quality_clist {2})}}
%<core>      \int_set:Nn \l_tmpa_int {1}
%<core>      \fp_compare:nT {\l__gradbars_distance_fp <= \clist_item:Nn \l__gradbars_thresholds_clist {2}}
%<core>        {\int_set:Nn \l_tmpa_int {2}}
%<core>      \fp_compare:nT {\l__gradbars_distance_fp <= \clist_item:Nn \l__gradbars_thresholds_clist {1}}
%<core>        {\int_set:Nn \l_tmpa_int {3}}
%<core>      \cs_set:Npx \gradbars@left {\clist_item:Nn \l__gradbars_colors_clist {\l_tmpa_int}}
%<core>      \gradbars@gradientfalse
%<core>    \fi
%<core>  }
%<core>\cs_new_eq:NN \gradbarsValidateBeforeThree \gradbarsValidateExtras
%<core>\cs_set_protected:Npn \gradbarsValidateExtras
%<core>  {
%<core>    \gradbarsValidateBeforeThree
%<core>    \str_case_e:nn {\gradbars@better}{{target}{\gradbarsQuality}{interval}{\gradbarsQuality}}
%<core>    \str_if_eq:eeT {\gradbars@shape}{dumbbell}
%<core>      {\ifgradbars@compare\else\gradbarsFail{Dumbbell~requires~graddumbbell}\fi}
%<core>    \str_if_eq:eeT {\gradbars@shape}{sparkline}
%<core>      {\ifgradbars@spark\else\gradbarsFail{Sparkline~requires~gradspark}\fi}
%<core>    \ifgradbars@spark
%<core>      \str_if_eq:eeF {\gradbars@shape}{sparkline}{\gradbarsFail{Spark~requires~shape=sparkline}}
%<core>      \ifgradbars@error\gradbarsFail{Spark~does~not~support~error~whiskers}\fi
%<core>      \tl_if_empty:oF {\gradbars@target}{\gradbarsFail{Spark~does~not~support~bar~targets}}
%<core>      \tl_if_empty:oF {\gradbars@band}{\gradbarsFail{Spark~does~not~support~bar~bands}}
%<core>      \tl_if_empty:oF {\gradbars@thresholds}{\gradbarsFail{Spark~does~not~support~thresholds}}
%<core>      \gradbarsValidateSpark
%<core>    \fi
%<core>  }
%<core>\cs_new_eq:NN \gradbarsLabelBeforeThree \gradbars@labelcontent
%<core>\cs_set_protected:Npn \gradbars@labelcontent
%<core>  {
%<core>    \tl_if_empty:oTF {\gradbars@text}
%<core>      {\ifgradbars@compare
%<core>        \str_if_eq:eeTF {\gradbars@comparelabel}{delta}
%<core>          {\ifgradbars@missing\gradbars@missingtext\else
%<core>             \ifgradbars@referencemissing\gradbars@missingtext\else
%<core>               $\Delta$\,\gradbarsFormatEndpoint{\gradbars@value-\gradbars@reference}\fi\fi}
%<core>          {\gradbarsLabelBeforeThree}
%<core>       \else\ifgradbars@stack
%<core>         \str_if_eq:eeTF {\gradbars@stacktotals}{separate}
%<core>           {+\gradbarsFormatEndpoint{\gradbars@positive}\,/\,\gradbarsFormatEndpoint{\gradbars@negative}}
%<core>           {\gradbarsLabelBeforeThree}
%<core>       \else\gradbarsLabelBeforeThree\fi\fi}
%<core>      {\gradbars@text}
%<core>  }
%<core>
%<core>
%<core>\ExplSyntaxOn
%<core>% Auto series scaling applies to the y axis; it must not inherit bar clipping.
%<core>\cs_new_eq:NN \gradbarsValidateBeforeSpark \gradbarsValidate
%<core>\cs_set_protected:Npn \gradbarsValidate
%<core>  {
%<core>    \ifgradbars@spark
%<core>      \str_if_eq:eeT{\gradbars@sparktype}{winloss}
%<core>        {\cs_set:Npx\gradbars@min{\fp_eval:n{min(0,\l__gradbars_series_min_fp)}}
%<core>         \cs_set:Npx\gradbars@max{\fp_eval:n{max(1,\l__gradbars_series_max_fp)}}
%<core>         \str_if_eq:eeT{\gradbars@format}{percent}
%<core>           {\gradbarsFail{Win-loss~does~not~support~percent~format}}}
%<core>      \str_if_eq:eeT {\gradbars@sparkrange}{auto}
%<core>        {\cs_set:Npx \gradbars@min {\fp_eval:n {min(0,\l__gradbars_series_min_fp)}}
%<core>         \cs_set:Npx \gradbars@max {\fp_eval:n {max(1,\l__gradbars_series_max_fp)}}
%<core>         \str_if_eq:eeT {\gradbars@format}{percent}
%<core>           {\gradbarsFail{Auto~spark~range~does~not~support~percent~format}}}
%<core>      \str_if_eq:eeF {\gradbars@label}{none}{\def\gradbars@label{outside}}
%<core>    \fi
%<core>    \let\gradbars@sparkbasecolor\gradbars@left
%<core>    \gradbarsValidateBeforeSpark
%<core>    \ifgradbars@spark\let\gradbars@left\gradbars@sparkbasecolor\fi
%<core>  }
%<core>
%<core>
%<core>\ExplSyntaxOff
%<core>% Reference records: {value/color/line style/name}, names may be empty.
%<core>\def\gradbars@references{}
%<core>\def\gradbars@bulletbands{}
%<core>\newif\ifgradbars@bullet
%<core>\pgfkeys{/gradbars/.cd,
%<core>  references/.store in=\gradbars@references,
%<core>  bullet bands/.store in=\gradbars@bulletbands}
%<core>\DeclareDocumentCommand\gradbullet{O{} m}{%
%<core>  \begingroup\gradbars@bullettrue
%<core>  \gradbar[height=12pt,fill=solid,label=outside,#1,shape=bar]{#2}%
%<core>  \endgroup}
%<core>\ExplSyntaxOn
%<core>\seq_new:N \l__gradbars_record_seq
%<core>\clist_new:N \l__gradbars_refs_clist
%<core>\clist_new:N \l__gradbars_bands_clist
%<core>\fp_new:N \l__gradbars_band_start_fp
%<core>\tl_new:N \l__gradbars_record_color_tl
%<core>\tl_new:N \l__gradbars_record_style_tl
%<core>\tl_new:N \l__gradbars_record_name_tl
%<core>\cs_new_protected:Npn \gradbarsRecord #1#2
%<core>  {\seq_set_split:Nnn \l__gradbars_record_seq {/}{#1}
%<core>   \int_compare:nNnF {\seq_count:N \l__gradbars_record_seq} = {#2}
%<core>     {\gradbarsFail{Wrong~number~of~fields~in~reference,~band~or~interval~record}}}
%<core>\cs_new_eq:NN \gradbarsValidateBeforeReferences \gradbarsValidateExtras
%<core>\cs_set_protected:Npn \gradbarsValidateExtras
%<core>  {
%<core>    \gradbarsValidateBeforeReferences
%<core>    \clist_set:No \l__gradbars_refs_clist {\gradbars@references}
%<core>    \clist_set:No \l__gradbars_bands_clist {\gradbars@bulletbands}
%<core>    \ifgradbars@spark
%<core>      \clist_if_empty:NF \l__gradbars_refs_clist
%<core>        {\gradbarsFail{Spark~does~not~support~references}}
%<core>    \fi
%<core>    \clist_map_inline:Nn \l__gradbars_refs_clist
%<core>      {\gradbarsRecord{##1}{4}
%<core>       \ifgradbars@valid
%<core>         \gradbarsCheckNumber{\seq_item:Nn \l__gradbars_record_seq {1}}{reference}
%<core>         \ifgradbars@valid
%<core>           \fp_compare:nT
%<core>             {\seq_item:Nn \l__gradbars_record_seq {1}<\gradbars@min ||
%<core>              \seq_item:Nn \l__gradbars_record_seq {1}>\gradbars@max}
%<core>             {\gradbarsFail{Reference~must~lie~within~range}}
%<core>           \tl_set:Nx \l_tmpa_tl {\seq_item:Nn \l__gradbars_record_seq {3}}
%<core>           \exp_args:NnV \clist_if_in:nnF {solid,dashed,dotted} \l_tmpa_tl
%<core>             {\gradbarsFail{Reference~line~style~must~be~solid,~dashed~or~dotted}}
%<core>         \fi
%<core>       \fi}
%<core>    \ifgradbars@bullet
%<core>      \clist_if_empty:NT \l__gradbars_bands_clist
%<core>        {\gradbarsFail{Bullet~requires~explicit~bullet~bands}}
%<core>    \else
%<core>      \clist_if_empty:NF \l__gradbars_bands_clist
%<core>        {\gradbarsFail{Bullet~bands~require~gradbullet}}
%<core>    \fi
%<core>    \ifgradbars@valid
%<core>      \fp_set:Nn \l__gradbars_band_start_fp {\gradbars@min}
%<core>      \clist_map_inline:Nn \l__gradbars_bands_clist
%<core>        {\gradbarsRecord{##1}{2}
%<core>         \ifgradbars@valid
%<core>           \gradbarsCheckNumber{\seq_item:Nn \l__gradbars_record_seq {1}}{band~endpoint}
%<core>           \ifgradbars@valid
%<core>             \fp_compare:nT
%<core>               {\seq_item:Nn \l__gradbars_record_seq {1}<=\l__gradbars_band_start_fp ||
%<core>                \seq_item:Nn \l__gradbars_record_seq {1}>\gradbars@max}
%<core>               {\gradbarsFail{Bullet~endpoints~must~increase~within~range}}
%<core>             \fp_set:Nn \l__gradbars_band_start_fp {\seq_item:Nn \l__gradbars_record_seq {1}}
%<core>           \fi
%<core>         \fi}
%<core>      \ifgradbars@bullet\ifgradbars@valid
%<core>        \fp_compare:nNnF {\l__gradbars_band_start_fp} = {\gradbars@max}
%<core>          {\gradbarsFail{Last~bullet~endpoint~must~equal~max}}
%<core>      \fi\fi
%<core>    \fi
%<core>  }
%<core>
%<core>
%<core>
%<core>% Each interval record has name / lower / point (or NA) / upper / color.
%<core>\tl_new:N \l__gradbars_interval_rows_tl
%<core>\cs_new_protected:Npn \gradbarsIntervalRow #1#2#3#4#5
%<core>  {#1 & \gradrange[color=#5,range~point=#3]{#2}{#4}\\}
%<core>\DeclareDocumentCommand\gradintervals{O{} m}
%<core>  {\group_begin:
%<core>   \pgfkeys{/gradbars,#1}
%<core>   \gradbars@validtrue
%<core>   \tl_clear:N \l__gradbars_interval_rows_tl
%<core>   \clist_if_empty:nT {#2}{\gradbarsFail{Interval~comparison~requires~records}}
%<core>   \clist_map_inline:nn {#2}
%<core>     {\gradbarsRecord{##1}{5}
%<core>      \ifgradbars@valid
%<core>        \tl_set:Nx \l__gradbars_record_name_tl {\seq_item:Nn \l__gradbars_record_seq {1}}
%<core>        \tl_set:Nx \l_tmpa_tl {\seq_item:Nn \l__gradbars_record_seq {3}}
%<core>        \str_if_eq:VnT \l_tmpa_tl {NA}{\tl_clear:N \l_tmpa_tl}
%<core>        \tl_put_right:Nx \l__gradbars_interval_rows_tl
%<core>          {\exp_not:N \gradbarsIntervalRow
%<core>            {\exp_not:V \l__gradbars_record_name_tl}
%<core>            {\seq_item:Nn \l__gradbars_record_seq {2}}
%<core>            {\exp_not:V \l_tmpa_tl}
%<core>            {\seq_item:Nn \l__gradbars_record_seq {4}}
%<core>            {\seq_item:Nn \l__gradbars_record_seq {5}}}
%<core>      \fi}
%<core>   \ifgradbars@valid
%<core>     \begin{tabular}{@{}l@{\hspace{.7em}}l@{}}
%<core>       \l__gradbars_interval_rows_tl
%<core>     \end{tabular}
%<core>   \fi\group_end:}
%<core>\ExplSyntaxOff
%<core>% v0.0.4: overflow indicators, comparison annotations and marker shapes.
%<core>\def\gradbars@overflowmark{none}
%<core>\def\gradbars@markershape{circle}
%<core>\def\gradbars@markerfill{solid}
%<core>\def\gradbars@change{none}
%<core>\pgfkeys{/gradbars/.cd,
%<core> overflow mark/.is choice,
%<core> overflow mark/none/.code=\def\gradbars@overflowmark{none},
%<core> overflow mark/arrow/.code=\def\gradbars@overflowmark{arrow},
%<core> overflow mark/slash/.code=\def\gradbars@overflowmark{slash},
%<core> marker shape/.is choice,
%<core> marker shape/circle/.code=\def\gradbars@markershape{circle},
%<core> marker shape/square/.code=\def\gradbars@markershape{square},
%<core> marker shape/diamond/.code=\def\gradbars@markershape{diamond},
%<core> marker shape/triangle/.code=\def\gradbars@markershape{triangle},
%<core> marker fill/.is choice,
%<core> marker fill/solid/.code=\def\gradbars@markerfill{solid},
%<core> marker fill/hollow/.code=\def\gradbars@markerfill{hollow},
%<core> compare annotation/.is choice,
%<core> compare annotation/none/.code=\def\gradbars@change{none},
%<core> compare annotation/arrow/.code=\def\gradbars@change{arrow},
%<core> compare annotation/bracket/.code=\def\gradbars@change{bracket},
%<core> compare label/percent/.code=\def\gradbars@comparelabel{percent}}
%<core>\ExplSyntaxOn
%<core>
%<core>
%<core>\fp_new:N \l__gradbars_raw_low_fp
%<core>\fp_new:N \l__gradbars_raw_high_fp
%<core>\bool_new:N \l__gradbars_overflow_known_bool
%<core>\cs_new_protected:Npn \gradbarsOverflowSide #1#2
%<core>  {\begin{scope}[shift={(#1,.5*\gradbars@height)},xscale=#2]
%<core>    \str_if_eq:eeTF {\gradbars@overflowmark}{arrow}
%<core>      {\draw[draw=gradbarsInk,line~width=.7pt](-2pt,-2pt)--(1pt,0)--(-2pt,2pt);}
%<core>      {\draw[draw=gradbarsInk,line~width=.7pt](-2pt,-2pt)--(0,2pt) (0,-2pt)--(2pt,2pt);}
%<core>   \end{scope}}
%<core>
%<core>\cs_new_protected:Npn \gradbarsChangeLabel
%<core>  {\group_begin:
%<core>   \ifgradbars@missing\gradbars@missingtext\else
%<core>   \ifgradbars@referencemissing\gradbars@missingtext\else
%<core>    \str_if_eq:eeTF {\gradbars@comparelabel}{percent}
%<core>      {\fp_compare:nNnTF {\gradbars@reference} = {0}
%<core>        {\gradbars@missingtext}
%<core>        {\def\gradbars@format{value}\def\gradbars@unit{\%}\def\gradbars@unitcode{}\def\gradbars@unittext{}
%<core>         \fp_compare:nNnT {\gradbars@value-\gradbars@reference} > {0}{+}
%<core>         \gradbarsFormatEndpoint{100*(\gradbars@value-\gradbars@reference)/abs(\gradbars@reference)}}}
%<core>      {$\Delta$\,\def\gradbars@format{value}
%<core>       \fp_compare:nNnT {\gradbars@value-\gradbars@reference} > {0}{+}
%<core>       \gradbarsFormatEndpoint{\gradbars@value-\gradbars@reference}}
%<core>   \fi\fi\group_end:}
%<core>\cs_new_eq:NN \gradbarsLabelBeforeFour \gradbars@labelcontent
%<core>\cs_set_protected:Npn \gradbars@labelcontent
%<core>  {\ifgradbars@compare
%<core>     \tl_if_empty:oTF {\gradbars@text}
%<core>       {\str_if_eq:eeTF {\gradbars@comparelabel}{percent}
%<core>          {\gradbarsChangeLabel}{\gradbarsLabelBeforeFour}}
%<core>       {\gradbarsLabelBeforeFour}
%<core>   \else\gradbarsLabelBeforeFour\fi}
%<core>
%<core>\ExplSyntaxOff
%<core>\ExplSyntaxOff
%<core>\RequirePackage{gradbars-tagging}
%<core>\ExplSyntaxOff
%<core>\ExplSyntaxOff
%<core>\ExplSyntaxOff
%<core>% v0.0.5: CSV selection, diverging heat and discrete spark observations.
%<core>\def\gradbars@heatpalette{sequential}
%<core>\def\gradbars@heatcenter{0}
%<core>\def\gradbars@heatcentercolor{white}
%<core>\def\gradbars@sparktype{line}
%<core>\def\gradbars@sparkbarwidth{.7}
%<core>\def\gradbars@sparkwincolor{gradbarsTeal}
%<core>\def\gradbars@sparklosscolor{gradbarsOrange}
%<core>\def\gradbars@sparkzerocolor{black!45}
%<core>\pgfkeys{/gradbars,
%<core>  heat palette/.is choice,
%<core>  heat palette/sequential/.style={heat low color=gradbarsBlueLight!15,heat high color=gradbarsBlue,
%<core>    /gradbars/heat palette value=sequential},
%<core>  heat palette/diverging/.style={heat low color=gradbarsOrange,heat high color=gradbarsTeal,
%<core>    heat center color=white,/gradbars/heat palette value=diverging},
%<core>  heat palette value/.store in=\gradbars@heatpalette,
%<core>  heat center/.store in=\gradbars@heatcenter,
%<core>  heat center color/.store in=\gradbars@heatcentercolor,
%<core>  spark type/.is choice,
%<core>  spark type/line/.code=\def\gradbars@sparktype{line},
%<core>  spark type/bar/.code=\def\gradbars@sparktype{bar},
%<core>  spark type/winloss/.code=\def\gradbars@sparktype{winloss},
%<core>  spark bar width/.store in=\gradbars@sparkbarwidth,
%<core>  spark win color/.store in=\gradbars@sparkwincolor,
%<core>  spark loss color/.store in=\gradbars@sparklosscolor,
%<core>  spark zero color/.store in=\gradbars@sparkzerocolor}
%<core>\ExplSyntaxOn
%<core>\ExplSyntaxOn
%<core>\ExplSyntaxOn
%<core>\cs_new_eq:NN\gradbarsBuildAltBeforeSix\gradbarsBuildAlt
%<core>\cs_set_protected:Npn\gradbarsBuildAlt
%<core>  {\gradbarsBuildAltBeforeSix
%<core>   \ifgradbars@spark
%<core>     \tl_put_left:Nx\l__gradbars_alt_tl{Spark~type:~\gradbars@sparktype.~}
%<core>     \str_if_eq:eeT{\gradbars@sparktype}{winloss}
%<core>       {\tl_put_right:Nn\l__gradbars_alt_tl{~Positive:~win;~negative:~loss;~zero:~tie.}}
%<core>   \fi}
%<core>\ExplSyntaxOff
%<core>% v0.0.6: reusable scales, numeric summaries and table presentation.
%<core>\ExplSyntaxOn
%<core>\prop_new:N\l__gradbars_scale_groups_prop
%<core>\tl_new:N\l__gradbars_scale_min_tl
%<core>\tl_new:N\l__gradbars_scale_max_tl
%<core>\keys_define:nn{gradbars/scale}
%<core>  {min .tl_set:N=\l__gradbars_scale_min_tl,max .tl_set:N=\l__gradbars_scale_max_tl}
%<core>\DeclareDocumentCommand\gradscale{m m}
%<core>  {\gradbars@validtrue
%<core>   \tl_clear:N\l__gradbars_scale_min_tl\tl_clear:N\l__gradbars_scale_max_tl
%<core>   \keys_set:nn{gradbars/scale}{#2}
%<core>   \tl_if_blank:nT{#1}{\gradbarsFail{Scale~name~must~not~be~empty}}
%<core>   \gradbarsCheckNumber{\l__gradbars_scale_min_tl}{scale~min}
%<core>   \gradbarsCheckNumber{\l__gradbars_scale_max_tl}{scale~max}
%<core>   \ifgradbars@valid
%<core>     \fp_compare:nNnTF{\l__gradbars_scale_max_tl}>{\l__gradbars_scale_min_tl}
%<core>       {\prop_put:Nnx\l__gradbars_scale_groups_prop{#1}
%<core>          {min=\l__gradbars_scale_min_tl,max=\l__gradbars_scale_max_tl}}
%<core>       {\gradbarsFail{Scale~max~must~be~greater~than~min}}
%<core>   \fi}
%<core>\cs_new_protected:Npn\gradbarsResolveScaleGroup
%<core>  {\tl_if_empty:oF{\gradbars@scalegroup}
%<core>     {\tl_set:No\l_tmpb_tl{\gradbars@scalegroup}
%<core>      \prop_get:NVNTF\l__gradbars_scale_groups_prop\l_tmpb_tl\l_tmpa_tl
%<core>        {\exp_args:NV\gradbarssetup\l_tmpa_tl
%<core>         \ifgradbars@spark\pgfkeys{/gradbars,spark~range=fixed}\fi}
%<core>        {\gradbarsFail{Unknown~scale~group:~\gradbars@scalegroup}}}}
%<core>\cs_new:Npn\gradbarsPercentBase
%<core>  {\tl_if_empty:oTF{\gradbars@percentbase}{\gradbars@max}{\gradbars@percentbase}}
%<core>\cs_new_protected:Npn\gradbarsValidatePercentBase
%<core>  {\gradbarsCheckNumber{\gradbarsPercentBase}{percent~base}
%<core>   \ifgradbars@valid\fp_compare:nNnF{\gradbarsPercentBase}>{0}
%<core>     {\gradbarsFail{Percent~base~must~be~positive}}\fi}
%<core>\cs_new_eq:NN\gradbarsBuildAltBeforeSummary\gradbarsBuildAlt
%<core>\cs_set_protected:Npn\gradbarsBuildAlt
%<core>  {\gradbarsBuildAltBeforeSummary
%<core>   \str_if_eq:eeT{\gradbars@format}{percent}
%<core>     {\tl_put_right:Nx\l__gradbars_alt_tl{~Percent~base:~\gradbarsPercentBase.}}}
%<core>\ExplSyntaxOff
%<core>\ExplSyntaxOff
%<core>\RequirePackage{gradbars-numbers}
%<core>\ExplSyntaxOn
%<core>\ExplSyntaxOff
%<core>
%<core>
%<core>\ExplSyntaxOff
%<core>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-keys.sty}}
%    \begin{macrocode}
%<keys>% Author: SuFan; MIT License. Basic public pgfkeys family.
%<keys>\ProvidesPackage{gradbars-keys}[2026/10/25 v1.1.0 gradbars keys]
%<keys>\pgfkeys{/gradbars/.is family,/gradbars,
%<keys>  style/.code={\gradbarsUseStyle{#1}},
%<keys>  missing text/.store in=\gradbars@missingtext,
%<keys>  number format/.is choice,
%<keys>  number format/fixed/.code=\def\gradbars@numberformat{fixed},
%<keys>  number format/grouped/.code=\def\gradbars@numberformat{grouped},
%<keys>  number format/scientific/.code=\def\gradbars@numberformat{scientific},
%<keys>  band/.store in=\gradbars@band,
%<keys>  band color/.store in=\gradbars@bandcolor,
%<keys>  band opacity/.store in=\gradbars@bandopacity,
%<keys>  stack colors/.store in=\gradbars@stackcolors,
%<keys>  width/.store in=\gradbars@width,
%<keys>  height/.store in=\gradbars@height,
%<keys>  max/.store in=\gradbars@max,
%<keys>  min/.store in=\gradbars@min,
%<keys>  scale group/.store in=\gradbars@scalegroup,
%<keys>  percent base/.store in=\gradbars@percentbase,
%<keys>  rounded/.store in=\gradbars@rounded,
%<keys>  target/.store in=\gradbars@target,
%<keys>  target color/.store in=\gradbars@targetcolor,
%<keys>  negative color/.store in=\gradbars@negativecolor,
%<keys>  negative fill/.is choice,
%<keys>  negative fill/solid/.code=\gradbars@negativegradientfalse,
%<keys>  negative fill/gradient/.code=\gradbars@negativegradienttrue,
%<keys>  negative left color/.code={\def\gradbars@negativeleft{#1}\gradbars@negativegradienttrue},
%<keys>  negative right color/.code={\def\gradbars@negativeright{#1}\gradbars@negativegradienttrue},
%<keys>  thresholds/.store in=\gradbars@thresholds,
%<keys>  threshold colors/.store in=\gradbars@thresholdcolors,
%<keys>  error/.style={error minus=#1,error plus=#1},
%<keys>  error minus/.store in=\gradbars@errorminus,
%<keys>  error plus/.store in=\gradbars@errorplus,
%<keys>  error color/.store in=\gradbars@errorcolor,
%<keys>  precision/.store in=\gradbars@precision,
%<keys>  unit/.store in=\gradbars@unit,
%<keys>  text/.store in=\gradbars@text,
%<keys>  alt/.store in=\gradbars@alt,
%<keys>  accessibility/.is choice,
%<keys>  accessibility/auto/.code=\def\gradbars@accessibility{auto},
%<keys>  accessibility/artifact/.code=\def\gradbars@accessibility{artifact},
%<keys>  accessibility/off/.code=\def\gradbars@accessibility{off},
%<keys>  label gap/.store in=\gradbars@gap,
%<keys>  label width/.store in=\gradbars@labelwidth,
%<keys>  label align/.is choice,
%<keys>  label align/graphic/.code=\def\gradbars@labelalign{graphic},
%<keys>  label align/cell/.code=\def\gradbars@labelalign{cell},
%<keys>  font/.store in=\gradbars@font,
%<keys>  left color/.store in=\gradbars@left,
%<keys>  right color/.store in=\gradbars@right,
%<keys>  track color/.store in=\gradbars@track,
%<keys>  text color/.store in=\gradbars@textcolor,
%<keys>  color/.style={fill=solid,left color=#1},
%<keys>  fill/.is choice,
%<keys>  fill/gradient/.code=\gradbars@gradienttrue,
%<keys>  fill/solid/.code=\gradbars@gradientfalse,
%<keys>  label/.is choice,
%<keys>  label/outside/.code=\def\gradbars@label{outside},
%<keys>  label/inside/.code=\def\gradbars@label{inside},
%<keys>  label/none/.code=\def\gradbars@label{none},
%<keys>  label/end/.code=\def\gradbars@label{end},
%<keys>  label/auto/.code=\def\gradbars@label{auto},
%<keys>  label/left/.code=\def\gradbars@label{left},
%<keys>  baseline/.is choice,
%<keys>  baseline/auto/.code=\def\gradbars@baseline{auto},
%<keys>  baseline/text/.code=\def\gradbars@baseline{text},
%<keys>  baseline/center/.code=\def\gradbars@baseline{center},
%<keys>  baseline/bottom/.code=\def\gradbars@baseline{bottom},
%<keys>  baseline shift/.store in=\gradbars@baselineshift,
%<keys>  value format/.is choice,
%<keys>  value format/value/.code=\def\gradbars@format{value},
%<keys>  value format/percent/.code=\def\gradbars@format{percent},
%<keys>  overflow/.is choice,
%<keys>  overflow/clip/.code=\def\gradbars@overflow{clip},
%<keys>  overflow/error/.code=\def\gradbars@overflow{error},
%<keys>  theme/.is choice,
%<keys>  theme/blue/.style={fill=gradient,left color=gradbarsBlue,
%<keys>    right color=gradbarsBlueLight,track color=gradbarsTrack,text color=gradbarsInk},
%<keys>  theme/teal/.style={fill=gradient,left color=gradbarsTeal,
%<keys>    right color=gradbarsTealLight,track color=gradbarsTrack,text color=gradbarsInk},
%<keys>  theme/solid/.style={fill=solid,left color=gradbarsBlue,
%<keys>    right color=gradbarsBlue,track color=gradbarsTrack,text color=gradbarsInk},
%<keys>  theme/gray/.style={fill=solid,left color=black!65,
%<keys>    right color=black!65,track color=black!8,text color=black},
%<keys>  theme/lbyellow/.style={fill=gradient,left color=lightblue!90,
%<keys>    right color=lightyellow!60,track color=gradbarsTrack,text color=gradbarsInk},
%<keys>  theme/viblue/.style={fill=gradient,left color=violet!20,
%<keys>    right color=lightblue!70,track color=gradbarsTrack,text color=gradbarsInk},
%<keys>  theme/cyblu/.style={fill=gradient,left color=cyan,
%<keys>    right color=blue!20,track color=gradbarsTrack,text color=gradbarsInk},
%<keys>  theme/violet/.style={fill=gradient,left color=gradbarsViolet,
%<keys>    right color=gradbarsVioletLight,track color=gradbarsViolet!6,text color=gradbarsInk},
%<keys>  theme/orange/.style={fill=gradient,left color=gradbarsWarmOrange,
%<keys>    right color=gradbarsWarmOrangeLight,track color=gradbarsWarmOrange!6,text color=gradbarsInk},
%<keys>  theme/forest/.style={fill=gradient,left color=gradbarsForest,
%<keys>    right color=gradbarsForestLight,track color=gradbarsForest!6,text color=gradbarsInk},
%<keys>}
%<keys>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-lib-csv.sty}}
%    \begin{macrocode}
%<lib-csv>% Author: SuFan; MIT License. Internal implementation unless documented.
%<lib-csv>\ProvidesPackage{gradbars-lib-csv}[2026/10/25 v1.1.0 gradbars lib-csv]
%<lib-csv>\RequirePackage{collcell}
%<lib-csv>\ExplSyntaxOff
%<lib-csv>\DeclareDocumentCommand\gradbarscolumn{s m m}{%
%<lib-csv>  \IfBooleanTF{#1}{\gradbarsDefineCompactColumn{#2}{#3}}{%
%<lib-csv>    \gradbarsDefineColumn{#2}{#3}}}
%<lib-csv>\ExplSyntaxOn
%<lib-csv>\cs_new_protected:Npn \gradbarsDefineColumn #1#2
%<lib-csv>  {
%<lib-csv>    \regex_match:nnTF {\A[A-Za-z]\Z} {#1}
%<lib-csv>      {\expandafter\newcolumntype\expandafter{#1}
%<lib-csv>        {>{\collectcell{\gradbar[#2]}}l<{\endcollectcell}}}
%<lib-csv>      {\PackageError{gradbars}{Column~name~must~be~one~ASCII~letter}
%<lib-csv>        {Choose~a~single~unused~letter,~for~example~G.}}
%<lib-csv>  }
%<lib-csv>
%<lib-csv>% Expand directly to \multicolumn: alignment must see \omit before any setup.
%<lib-csv>\cs_set:Npn \gradbarshead #1 {\multicolumn{1}{c}{#1}}
%<lib-csv>\dim_new:N \l__gradbars_column_blank_dim
%<lib-csv>\cs_new_protected:Npn \__gradbars_compact_cell:nn #1#2
%<lib-csv>  {\tl_if_blank:nTF {#2}
%<lib-csv>     {\group_begin:
%<lib-csv>      \gradbarssetup{#1}
%<lib-csv>      \dim_set:Nn\l__gradbars_column_blank_dim{\gradbars@width}
%<lib-csv>      \dim_compare:nNnTF{\l__gradbars_column_blank_dim}>{0pt}
%<lib-csv>        {\hbox_to_wd:nn{\l__gradbars_column_blank_dim}{\hfil}}
%<lib-csv>        {\gradbarsFail{Width~must~be~positive}}
%<lib-csv>      \group_end:}
%<lib-csv>     {\gradbar[baseline=text,label=inside,label~align=cell,#1]{#2}}}
%<lib-csv>\cs_new_protected:Npn \gradbarsDefineCompactColumn #1#2
%<lib-csv>  {\regex_match:nnTF {\A[A-Za-z]\Z}{#1}
%<lib-csv>     {\clist_if_in:nnTF{c,l,r,p,m,b,w,W}{#1}
%<lib-csv>        {\__gradbars_public_error:n{Column~already~defined~or~reserved:~#1}}
%<lib-csv>        {\cs_if_exist:cTF{NC@find@#1}
%<lib-csv>          {\__gradbars_public_error:n{Column~already~defined~or~reserved:~#1}}
%<lib-csv>          {\newcolumntype{#1}
%<lib-csv>            {>{\collectcell{\__gradbars_compact_cell:nn{#2}}}c<{\endcollectcell}}}}}
%<lib-csv>     {\__gradbars_public_error:n{Column~name~must~be~one~ASCII~letter}}}
%<lib-csv>
%<lib-csv>\ExplSyntaxOff
%<lib-csv>\ExplSyntaxOn
%<lib-csv>% CSV is read as character data; fields are never executed as TeX.
%<lib-csv>\ior_new:N \l__gradbars_csv_ior
%<lib-csv>\prop_new:N \l__gradbars_csv_prop
%<lib-csv>\seq_new:N \l__gradbars_csv_fields_seq
%<lib-csv>\tl_new:N \l__gradbars_csv_field_tl
%<lib-csv>\tl_new:N \l__gradbars_csv_line_tl
%<lib-csv>\tl_new:N \l__gradbars_csv_value_tl
%<lib-csv>\tl_new:N \l__gradbars_csv_table_tl
%<lib-csv>\clist_new:N \l__gradbars_csv_missing_clist
%<lib-csv>\int_new:N \l__gradbars_csv_state_int
%<lib-csv>\int_new:N \l__gradbars_csv_row_int
%<lib-csv>\int_new:N \l__gradbars_csv_col_int
%<lib-csv>\int_new:N \l__gradbars_csv_width_int
%<lib-csv>\fp_new:N \l__gradbars_csv_min_fp
%<lib-csv>\fp_new:N \l__gradbars_csv_max_fp
%<lib-csv>\keys_define:nn {gradbars/csv}
%<lib-csv>  {missing .clist_set:N=\l__gradbars_csv_missing_clist}
%<lib-csv>\cs_generate_variant:Nn \prop_put:Nnn {Nxn,Nxx,NVx}
%<lib-csv>\cs_generate_variant:Nn \prop_get:NnN {cxN}
%<lib-csv>\cs_generate_variant:Nn \prop_if_in:NnTF {cxTF}
%<lib-csv>\cs_new_protected:Npn \gradbarsCSVField
%<lib-csv>  {\tl_trim_spaces:N \l__gradbars_csv_field_tl
%<lib-csv>   \seq_put_right:NV \l__gradbars_csv_fields_seq \l__gradbars_csv_field_tl
%<lib-csv>   \tl_clear:N \l__gradbars_csv_field_tl
%<lib-csv>   \int_zero:N \l__gradbars_csv_state_int}
%<lib-csv>\cs_new_protected:Npn \gradbarsCSVParse #1
%<lib-csv>  {
%<lib-csv>    \seq_clear:N \l__gradbars_csv_fields_seq
%<lib-csv>    \tl_clear:N \l__gradbars_csv_field_tl
%<lib-csv>    \int_zero:N \l__gradbars_csv_state_int
%<lib-csv>    % states: 0=unquoted, 1=quoted, 2=closing quote, 3=trailing space.
%<lib-csv>    \str_map_inline:nn {#1}
%<lib-csv>      {
%<lib-csv>        \int_case:nn {\l__gradbars_csv_state_int}
%<lib-csv>          {
%<lib-csv>            {0}{\str_case:nnF {##1}
%<lib-csv>              {{,}{\gradbarsCSVField}
%<lib-csv>               {"}{\tl_if_blank:VTF \l__gradbars_csv_field_tl
%<lib-csv>                    {\tl_clear:N \l__gradbars_csv_field_tl\int_set:Nn \l__gradbars_csv_state_int {1}}
%<lib-csv>                    {\gradbarsFail{Quote~inside~unquoted~CSV~field}}}}
%<lib-csv>              {\tl_put_right:Nn \l__gradbars_csv_field_tl {##1}}}
%<lib-csv>            {1}{\str_if_eq:nnTF {##1}{"}
%<lib-csv>              {\int_set:Nn \l__gradbars_csv_state_int {2}}
%<lib-csv>              {\tl_put_right:Nn \l__gradbars_csv_field_tl {##1}}}
%<lib-csv>            {2}{\str_case:nnF {##1}
%<lib-csv>              {{"}{\tl_put_right:Nn \l__gradbars_csv_field_tl {"}\int_set:Nn \l__gradbars_csv_state_int {1}}
%<lib-csv>               {,}{\gradbarsCSVField}}
%<lib-csv>              {\str_if_eq:nnTF {##1}{~}
%<lib-csv>                {\int_set:Nn \l__gradbars_csv_state_int {3}}
%<lib-csv>                {\gradbarsFail{Unexpected~text~after~CSV~quote}}}}
%<lib-csv>            {3}{\str_if_eq:nnTF {##1}{,}{\gradbarsCSVField}
%<lib-csv>              {\str_if_eq:nnF {##1}{~}{\gradbarsFail{Unexpected~text~after~CSV~quote}}}}
%<lib-csv>          }
%<lib-csv>      }
%<lib-csv>    \int_compare:nNnT {\l__gradbars_csv_state_int} = {1}
%<lib-csv>      {\gradbarsFail{Unclosed~CSV~quote;~multiline~fields~are~not~supported}}
%<lib-csv>    \gradbarsCSVField
%<lib-csv>  }
%<lib-csv>\cs_new_protected:Npn \gradbarsCSVLine #1
%<lib-csv>  {
%<lib-csv>    \tl_set:Nn \l__gradbars_csv_line_tl {#1}
%<lib-csv>    % pdfTeX reads UTF-8 as bytes; Unicode engines read a single BOM character.
%<lib-csv>    \sys_if_engine_pdftex:TF
%<lib-csv>      {\regex_replace_once:nnN {\A\x{EF}\x{BB}\x{BF}} {} \l__gradbars_csv_line_tl}
%<lib-csv>      {\regex_replace_once:nnN {\A\x{FEFF}} {} \l__gradbars_csv_line_tl}
%<lib-csv>    \tl_if_blank:VF \l__gradbars_csv_line_tl
%<lib-csv>      {
%<lib-csv>        \exp_args:NV \gradbarsCSVParse \l__gradbars_csv_line_tl
%<lib-csv>        \int_compare:nNnTF {\l__gradbars_csv_row_int} = {0}
%<lib-csv>          {
%<lib-csv>            \int_set:Nn \l__gradbars_csv_width_int {\seq_count:N \l__gradbars_csv_fields_seq}
%<lib-csv>            \int_zero:N \l__gradbars_csv_col_int
%<lib-csv>            \seq_map_inline:Nn \l__gradbars_csv_fields_seq
%<lib-csv>              {\int_incr:N \l__gradbars_csv_col_int
%<lib-csv>               \tl_if_blank:nT {##1}{\gradbarsFail{CSV~header~must~not~be~empty}}
%<lib-csv>               \prop_if_in:NnT \l__gradbars_csv_prop {col/##1}{\gradbarsFail{Duplicate~CSV~header:~##1}}
%<lib-csv>               \prop_put:Nnx \l__gradbars_csv_prop {col/##1}{\int_use:N \l__gradbars_csv_col_int}}
%<lib-csv>          }
%<lib-csv>          {
%<lib-csv>            \int_compare:nNnF {\seq_count:N \l__gradbars_csv_fields_seq} = {\l__gradbars_csv_width_int}
%<lib-csv>              {\gradbarsFail{CSV~row~has~wrong~field~count}}
%<lib-csv>            \int_zero:N \l__gradbars_csv_col_int
%<lib-csv>            \seq_map_inline:Nn \l__gradbars_csv_fields_seq
%<lib-csv>              {\int_incr:N \l__gradbars_csv_col_int
%<lib-csv>               \prop_put:Nxn \l__gradbars_csv_prop
%<lib-csv>                 {row/\int_use:N \l__gradbars_csv_row_int/\int_use:N \l__gradbars_csv_col_int}{##1}}
%<lib-csv>          }
%<lib-csv>        \int_incr:N \l__gradbars_csv_row_int
%<lib-csv>      }
%<lib-csv>  }
%<lib-csv>\DeclareDocumentCommand\gradbarsloadcsv{O{} m m}
%<lib-csv>  {
%<lib-csv>    \gradbars@validtrue
%<lib-csv>    \regex_match:nnF {\A[A-Za-z][A-Za-z0-9_\-]*\Z}{#2}
%<lib-csv>      {\gradbarsFail{CSV~dataset~name~must~start~with~an~ASCII~letter}}
%<lib-csv>    \clist_set:Nn \l__gradbars_csv_missing_clist {NA,N/A,null}
%<lib-csv>    \keys_set:nn {gradbars/csv}{#1}
%<lib-csv>    \prop_clear:N \l__gradbars_csv_prop
%<lib-csv>    \int_zero:N \l__gradbars_csv_row_int
%<lib-csv>    \file_if_exist:nTF {#3}
%<lib-csv>      {\ior_open:Nn \l__gradbars_csv_ior {#3}
%<lib-csv>       \ior_str_map_inline:Nn \l__gradbars_csv_ior {\gradbarsCSVLine{##1}}
%<lib-csv>       \ior_close:N \l__gradbars_csv_ior}
%<lib-csv>      {\gradbarsFail{CSV~file~not~found:~#3}}
%<lib-csv>    \int_compare:nNnF {\l__gradbars_csv_row_int} > {0}{\gradbarsFail{CSV~requires~a~header}}
%<lib-csv>    \ifgradbars@valid
%<lib-csv>      \prop_put:Nnx \l__gradbars_csv_prop {rows}{\int_eval:n {\l__gradbars_csv_row_int-1}}
%<lib-csv>      \prop_put:NnV \l__gradbars_csv_prop {missing}\l__gradbars_csv_missing_clist
%<lib-csv>      \prop_if_exist:cF {l__gradbars_csv_#2_prop}{\prop_new:c {l__gradbars_csv_#2_prop}}
%<lib-csv>      \prop_set_eq:cN {l__gradbars_csv_#2_prop}\l__gradbars_csv_prop
%<lib-csv>    \fi
%<lib-csv>  }
%<lib-csv>\cs_new_protected:Npn \gradbarsCSVColumn #1#2
%<lib-csv>  {
%<lib-csv>    \gradbars@validtrue
%<lib-csv>    \prop_if_exist:cTF {l__gradbars_csv_#1_prop}
%<lib-csv>      {\prop_if_in:cxTF {l__gradbars_csv_#1_prop}{col/\tl_to_str:n {#2}}
%<lib-csv>        {\prop_get:cxN {l__gradbars_csv_#1_prop}{col/\tl_to_str:n {#2}}\l_tmpa_tl
%<lib-csv>         \int_set:Nn \l__gradbars_csv_col_int {\l_tmpa_tl}}
%<lib-csv>        {\gradbarsFail{Unknown~CSV~column:~#2}}}
%<lib-csv>      {\gradbarsFail{Unknown~CSV~dataset:~#1}}
%<lib-csv>  }
%<lib-csv>\cs_new_protected:Npn \gradbarsCSVGet #1#2#3
%<lib-csv>  {
%<lib-csv>    \gradbarsCSVColumn{#1}{#3}
%<lib-csv>    \regex_match:nnF {\A[1-9][0-9]*\Z}{#2}{\gradbarsFail{CSV~row~must~be~a~positive~integer}}
%<lib-csv>    \ifgradbars@valid
%<lib-csv>      \prop_if_in:cxTF {l__gradbars_csv_#1_prop}{row/#2/\int_use:N \l__gradbars_csv_col_int}
%<lib-csv>        {\prop_get:cxN {l__gradbars_csv_#1_prop}{row/#2/\int_use:N \l__gradbars_csv_col_int}\l__gradbars_csv_value_tl}
%<lib-csv>        {\gradbarsFail{CSV~row~out~of~range}}
%<lib-csv>    \fi
%<lib-csv>  }
%<lib-csv>\cs_new_protected:Npn \gradbarsCSVNumber #1
%<lib-csv>  {
%<lib-csv>    \prop_get:cnN {l__gradbars_csv_#1_prop}{missing}\l_tmpa_tl
%<lib-csv>    \clist_set:NV \l__gradbars_csv_missing_clist \l_tmpa_tl
%<lib-csv>    \bool_set_false:N \l_tmpa_bool
%<lib-csv>    \tl_if_blank:VT \l__gradbars_csv_value_tl {\bool_set_true:N \l_tmpa_bool}
%<lib-csv>    \clist_map_inline:Nn \l__gradbars_csv_missing_clist
%<lib-csv>      {\str_if_eq:eeT {\l__gradbars_csv_value_tl}{\tl_to_str:n {##1}}{\bool_set_true:N \l_tmpa_bool}}
%<lib-csv>    \bool_if:NTF \l_tmpa_bool
%<lib-csv>      {\tl_set:Nn \l__gradbars_csv_value_tl {NA}}
%<lib-csv>      {\gradbarsCheckNumber{\l__gradbars_csv_value_tl}{CSV~numeric~cell}}
%<lib-csv>  }
%<lib-csv>\DeclareDocumentCommand\gradbarscsvcell{m m m}
%<lib-csv>  {\group_begin:\gradbarsCSVGet{#1}{#2}{#3}
%<lib-csv>   \ifgradbars@valid\tl_use:N \l__gradbars_csv_value_tl\fi\group_end:}
%<lib-csv>\DeclareDocumentCommand\gradbarcsv{O{} m m m}
%<lib-csv>  {\group_begin:\gradbarsCSVGet{#2}{#3}{#4}
%<lib-csv>   \ifgradbars@valid\gradbarsCSVNumber{#2}
%<lib-csv>     \ifgradbars@valid\gradbar[#1]{\l__gradbars_csv_value_tl}\fi\fi\group_end:}
%<lib-csv>\cs_new_protected:Npn \gradbarsCSVRange #1#2
%<lib-csv>  {
%<lib-csv>    \gradbarsCSVColumn{#1}{#2}
%<lib-csv>    \fp_zero:N \l__gradbars_csv_min_fp
%<lib-csv>    \fp_zero:N \l__gradbars_csv_max_fp
%<lib-csv>    \ifgradbars@valid
%<lib-csv>      \int_step_inline:nn {\prop_item:cn {l__gradbars_csv_#1_prop}{rows}}
%<lib-csv>        {\prop_get:cxN {l__gradbars_csv_#1_prop}{row/##1/\int_use:N \l__gradbars_csv_col_int}\l__gradbars_csv_value_tl
%<lib-csv>         \gradbarsCSVNumber{#1}
%<lib-csv>         \ifgradbars@valid
%<lib-csv>           \str_if_eq:VnF \l__gradbars_csv_value_tl {NA}
%<lib-csv>             {\fp_set:Nn \l__gradbars_csv_min_fp {min(\l__gradbars_csv_min_fp,\l__gradbars_csv_value_tl)}
%<lib-csv>              \fp_set:Nn \l__gradbars_csv_max_fp {max(\l__gradbars_csv_max_fp,\l__gradbars_csv_value_tl)}}
%<lib-csv>         \fi}
%<lib-csv>      % Keep a positive upper limit even for all-zero/all-missing/negative columns.
%<lib-csv>      \fp_compare:nNnT {\l__gradbars_csv_max_fp} = {0}{\fp_set:Nn \l__gradbars_csv_max_fp {1}}
%<lib-csv>    \fi
%<lib-csv>  }
%<lib-csv>\DeclareDocumentCommand\gradbarscsvstyle{m m m}
%<lib-csv>  {\gradbarsCSVRange{#2}{#3}
%<lib-csv>   \ifgradbars@valid
%<lib-csv>     \cs_set:cpx {gradbars@style@#1}
%<lib-csv>       {min=\fp_to_decimal:N \l__gradbars_csv_min_fp,max=\fp_to_decimal:N \l__gradbars_csv_max_fp}
%<lib-csv>   \fi}
%<lib-csv>\DeclareDocumentCommand\gradbarscsvtable{O{} m m m}
%<lib-csv>  {
%<lib-csv>    \group_begin:
%<lib-csv>    \gradbarsCSVRange{#2}{#4}
%<lib-csv>    \ifgradbars@valid
%<lib-csv>      \tl_set:Nx \l__gradbars_csv_table_tl
%<lib-csv>        {\exp_not:N \gradbarssetup{min=\fp_to_decimal:N \l__gradbars_csv_min_fp,
%<lib-csv>          max=\fp_to_decimal:N \l__gradbars_csv_max_fp}
%<lib-csv>         \exp_not:N \begin{tabular}{@{}ll@{}}\exp_not:N \hline
%<lib-csv>         \tl_to_str:n {#3}&\tl_to_str:n {#4}\exp_not:N \\\exp_not:N \hline}
%<lib-csv>      \int_step_inline:nn {\prop_item:cn {l__gradbars_csv_#2_prop}{rows}}
%<lib-csv>        {\gradbarsCSVGet{#2}{##1}{#3}
%<lib-csv>         \ifgradbars@valid
%<lib-csv>           \tl_put_right:Nx \l__gradbars_csv_table_tl
%<lib-csv>             {\exp_not:V \l__gradbars_csv_value_tl &
%<lib-csv>              \exp_not:N \gradbarcsv[\exp_not:n {#1}]{#2}{##1}{\exp_not:n {#4}}\exp_not:N \\}
%<lib-csv>         \fi}
%<lib-csv>      \tl_put_right:Nn \l__gradbars_csv_table_tl {\hline\end{tabular}}
%<lib-csv>      \ifgradbars@valid\tl_use:N \l__gradbars_csv_table_tl\fi
%<lib-csv>    \fi
%<lib-csv>    \group_end:
%<lib-csv>  }
%<lib-csv>\ExplSyntaxOff
%<lib-csv>
%<lib-csv>
%<lib-csv>\ExplSyntaxOff
%<lib-csv>
%<lib-csv>\ExplSyntaxOff
%<lib-csv>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-lib-distribution.sty}}
%    \begin{macrocode}
%<lib-distribution>% Author: SuFan; MIT License. Distribution statistics and inline box plots.
%<lib-distribution>\ProvidesPackage{gradbars-lib-distribution}[2026/10/25 v1.1.0 Distribution graphics]
%<lib-distribution>\ExplSyntaxOn
%<lib-distribution>\prop_new:N \l__gradbars_stats_prop
%<lib-distribution>\seq_new:N \l__gradbars_samples_seq
%<lib-distribution>\seq_new:N \l__gradbars_outliers_seq
%<lib-distribution>\int_new:N \l__gradbars_sample_missing_int
%<lib-distribution>\fp_new:N \l__gradbars_sample_sum_fp
%<lib-distribution>\fp_new:N \l__gradbars_quantile_h_fp
%<lib-distribution>\int_new:N \l__gradbars_quantile_j_int
%<lib-distribution>\tl_new:N \l__gradbars_quantile_tl
%<lib-distribution>\fp_new:N\l__gradbars_box_low_fp
%<lib-distribution>\fp_new:N\l__gradbars_box_high_fp
%<lib-distribution>\tl_new:N \l__gradbars_distribution_range_tl
%<lib-distribution>\tl_set:Nn \l__gradbars_distribution_range_tl {auto}
%<lib-distribution>\pgfkeys{/gradbars/box~range/.is~choice,
%<lib-distribution> /gradbars/box~range/auto/.code={\tl_set:Nn\l__gradbars_distribution_range_tl{auto}},
%<lib-distribution> /gradbars/box~range/fixed/.code={\tl_set:Nn\l__gradbars_distribution_range_tl{fixed}}}
%<lib-distribution>\cs_new:Npn \gradstat #1 {\prop_item:Nn\l__gradbars_stats_prop{#1}}
%<lib-distribution>\cs_new_protected:Npn \__gradbars_quantile:nN #1#2
%<lib-distribution>  {\fp_set:Nn\l__gradbars_quantile_h_fp{1+(\seq_count:N\l__gradbars_samples_seq-1)*(#1)}
%<lib-distribution>   \int_set:Nn\l__gradbars_quantile_j_int{\fp_eval:n{floor(\l__gradbars_quantile_h_fp)}}
%<lib-distribution>   \tl_set:Nx#2{\seq_item:Nn\l__gradbars_samples_seq{\l__gradbars_quantile_j_int}}
%<lib-distribution>   \int_compare:nNnT{\l__gradbars_quantile_j_int}<{\seq_count:N\l__gradbars_samples_seq}
%<lib-distribution>     {\tl_set:Nx#2{\fp_eval:n{#2+(\l__gradbars_quantile_h_fp-\l__gradbars_quantile_j_int)*
%<lib-distribution>       (\seq_item:Nn\l__gradbars_samples_seq{\l__gradbars_quantile_j_int+1}-#2)}}}}
%<lib-distribution>\cs_new_protected:Npn \__gradbars_distribution_parse:n #1
%<lib-distribution>  {\prop_clear:N\l__gradbars_stats_prop
%<lib-distribution>   \seq_clear:N\l__gradbars_samples_seq\seq_clear:N\l__gradbars_outliers_seq
%<lib-distribution>   \int_zero:N\l__gradbars_sample_missing_int\fp_zero:N\l__gradbars_sample_sum_fp
%<lib-distribution>   \tl_if_blank:nF{#1}
%<lib-distribution>     {\seq_set_split:Nnn\l_tmpa_seq{,}{#1}
%<lib-distribution>      \seq_map_inline:Nn\l_tmpa_seq
%<lib-distribution>        {\tl_set:Nn\l_tmpa_tl{##1}\tl_trim_spaces:N\l_tmpa_tl
%<lib-distribution>         \bool_lazy_or:nnTF{\tl_if_empty_p:N\l_tmpa_tl}{\str_if_eq_p:Vn\l_tmpa_tl{NA}}
%<lib-distribution>           {\int_incr:N\l__gradbars_sample_missing_int}
%<lib-distribution>           {\gradbarsCheckNumber{\l_tmpa_tl}{distribution~sample}
%<lib-distribution>            \ifgradbars@valid
%<lib-distribution>              \seq_put_right:Nx\l__gradbars_samples_seq{\fp_eval:n{\l_tmpa_tl}}
%<lib-distribution>              \fp_add:Nn\l__gradbars_sample_sum_fp{\l_tmpa_tl}
%<lib-distribution>            \fi}}}
%<lib-distribution>   \seq_sort:Nn\l__gradbars_samples_seq
%<lib-distribution>     {\fp_compare:nNnTF{##1}>{##2}{\sort_return_swapped:}{\sort_return_same:}}
%<lib-distribution>   \prop_put:Nnx\l__gradbars_stats_prop{n}{\seq_count:N\l__gradbars_samples_seq}
%<lib-distribution>   \prop_put:Nnx\l__gradbars_stats_prop{missing}{\int_use:N\l__gradbars_sample_missing_int}
%<lib-distribution>   \prop_put:Nnn\l__gradbars_stats_prop{method}{type-7;~1.5~IQR~observed~whiskers}
%<lib-distribution>   \seq_if_empty:NTF\l__gradbars_samples_seq
%<lib-distribution>     {\clist_map_inline:nn{min,max,q1,median,q3,iqr,low,high,mean}
%<lib-distribution>        {\prop_put:Nnn\l__gradbars_stats_prop{##1}{NA}}}
%<lib-distribution>     {\clist_map_inline:nn{q1/.25,median/.5,q3/.75}
%<lib-distribution>        {\seq_set_split:Nnn\l_tmpb_seq{/}{##1}
%<lib-distribution>         \__gradbars_quantile:nN{\seq_item:Nn\l_tmpb_seq{2}}\l__gradbars_quantile_tl
%<lib-distribution>         \prop_put:Nxx\l__gradbars_stats_prop{\seq_item:Nn\l_tmpb_seq{1}}{\l__gradbars_quantile_tl}}
%<lib-distribution>      \prop_put:Nnx\l__gradbars_stats_prop{min}{\seq_item:Nn\l__gradbars_samples_seq{1}}
%<lib-distribution>      \prop_put:Nnx\l__gradbars_stats_prop{max}{\seq_item:Nn\l__gradbars_samples_seq{-1}}
%<lib-distribution>      \prop_put:Nnx\l__gradbars_stats_prop{mean}{\fp_eval:n{\l__gradbars_sample_sum_fp/\gradstat{n}}}
%<lib-distribution>      \prop_put:Nnx\l__gradbars_stats_prop{iqr}{\fp_eval:n{\gradstat{q3}-\gradstat{q1}}}
%<lib-distribution>      \prop_put:Nnn\l__gradbars_stats_prop{low}{}
%<lib-distribution>      \seq_map_inline:Nn\l__gradbars_samples_seq
%<lib-distribution>        {\fp_compare:nTF{##1<\gradstat{q1}-1.5*\gradstat{iqr} || ##1>\gradstat{q3}+1.5*\gradstat{iqr}}
%<lib-distribution>           {\seq_put_right:Nn\l__gradbars_outliers_seq{##1}}
%<lib-distribution>           {\tl_if_empty:eT{\gradstat{low}}{\prop_put:Nnn\l__gradbars_stats_prop{low}{##1}}
%<lib-distribution>            \prop_put:Nnn\l__gradbars_stats_prop{high}{##1}}}}
%<lib-distribution>   \prop_put:Nnx\l__gradbars_stats_prop{outliers}{\seq_use:Nn\l__gradbars_outliers_seq{,}}
%<lib-distribution>   \prop_put:Nnx\l__gradbars_stats_prop{outlier~count}{\seq_count:N\l__gradbars_outliers_seq}}
%<lib-distribution>\DeclareDocumentCommand\gradcomputesummary{m +m}
%<lib-distribution>  {\group_begin:\gradbars@validtrue\__gradbars_distribution_parse:n{#1}
%<lib-distribution>   \ifgradbars@valid#2\fi\group_end:}
%<lib-distribution>\DeclareDocumentCommand\gradsummarytext{O{} m}
%<lib-distribution>  {\group_begin:\gradbarssetup{#1}\gradbars@validtrue\gradbarsValidateFormatter
%<lib-distribution>   \tl_set:Nx\l_tmpa_tl{\gradbars@precision}
%<lib-distribution>   \regex_match:nVF{\A[0-6]\Z}\l_tmpa_tl{\gradbarsFail{Precision~must~be~an~integer~from~0~to~6}}
%<lib-distribution>   \str_if_eq:eeF{\gradbars@format}{value}{\gradbarsFail{Distribution~summaries~require~value~format=value}}
%<lib-distribution>   \ifgradbars@valid\gradcomputesummary{#2}
%<lib-distribution>    {n=\gradstat{n};~missing=\gradstat{missing};~
%<lib-distribution>     \int_compare:nNnTF{\gradstat{n}}={0}{\gradbars@missingtext}
%<lib-distribution>       {Q1=\gradbarsFormatEndpoint{\gradstat{q1}};~
%<lib-distribution>        median=\gradbarsFormatEndpoint{\gradstat{median}};~
%<lib-distribution>        Q3=\gradbarsFormatEndpoint{\gradstat{q3}};~
%<lib-distribution>        IQR=\gradbarsFormatEndpoint{\gradstat{iqr}};~
%<lib-distribution>        whiskers=\gradbarsFormatEndpoint{\gradstat{low}}--\gradbarsFormatEndpoint{\gradstat{high}};~
%<lib-distribution>        outliers=\gradstat{outlier~count}}}\fi\group_end:}
%<lib-distribution>\keys_define:nn{gradbars/distribution/summary}
%<lib-distribution>  {n .code:n=\prop_put:Nnn\l__gradbars_stats_prop{n}{#1},
%<lib-distribution>   missing .code:n=\prop_put:Nnn\l__gradbars_stats_prop{missing}{#1},
%<lib-distribution>   q1 .code:n=\prop_put:Nnn\l__gradbars_stats_prop{q1}{#1},
%<lib-distribution>   median .code:n=\prop_put:Nnn\l__gradbars_stats_prop{median}{#1},
%<lib-distribution>   q3 .code:n=\prop_put:Nnn\l__gradbars_stats_prop{q3}{#1},
%<lib-distribution>   low .code:n=\prop_put:Nnn\l__gradbars_stats_prop{low}{#1},
%<lib-distribution>   high .code:n=\prop_put:Nnn\l__gradbars_stats_prop{high}{#1},
%<lib-distribution>   min .code:n=\prop_put:Nnn\l__gradbars_stats_prop{min}{#1},
%<lib-distribution>   max .code:n=\prop_put:Nnn\l__gradbars_stats_prop{max}{#1},
%<lib-distribution>   mean .code:n=\prop_put:Nnn\l__gradbars_stats_prop{mean}{#1},
%<lib-distribution>   outliers .code:n={\seq_set_from_clist:Nn\l__gradbars_outliers_seq{#1}
%<lib-distribution>     \prop_put:Nnn\l__gradbars_stats_prop{outliers}{#1}
%<lib-distribution>     \prop_put:Nnx\l__gradbars_stats_prop{outlier~count}{\seq_count:N\l__gradbars_outliers_seq}}}
%<lib-distribution>\cs_new_protected:Npn\__gradbars_distribution_record:n #1
%<lib-distribution>  {\prop_clear:N\l__gradbars_stats_prop\seq_clear:N\l__gradbars_outliers_seq
%<lib-distribution>   \prop_put:Nnn\l__gradbars_stats_prop{missing}{unknown}
%<lib-distribution>   \prop_put:Nnn\l__gradbars_stats_prop{outlier~count}{unknown}
%<lib-distribution>   \prop_put:Nnn\l__gradbars_stats_prop{outliers}{not~supplied}
%<lib-distribution>   \prop_put:Nnn\l__gradbars_stats_prop{method}{precomputed;~algorithm~not~verified}
%<lib-distribution>   \keys_set:nn{gradbars/distribution/summary}{#1}
%<lib-distribution>   \clist_map_inline:nn{n,q1,median,q3,low,high}
%<lib-distribution>     {\prop_if_in:NnF\l__gradbars_stats_prop{##1}{\gradbarsFail{Missing~summary~field:~##1}}}
%<lib-distribution>   \ifgradbars@valid
%<lib-distribution>     \tl_set:Nx\l_tmpa_tl{\gradstat{n}}
%<lib-distribution>     \regex_match:nVF{\A[1-9][0-9]*\Z}\l_tmpa_tl{\gradbarsFail{Summary~n~must~be~a~positive~integer}}
%<lib-distribution>     \clist_map_inline:nn{q1,median,q3,low,high,min,max,mean}
%<lib-distribution>       {\prop_if_in:NnT\l__gradbars_stats_prop{##1}{\gradbarsCheckNumber{\gradstat{##1}}{summary~##1}}}
%<lib-distribution>   \fi
%<lib-distribution>   \ifgradbars@valid
%<lib-distribution>     \fp_compare:nF{\gradstat{low}<=\gradstat{q1}<=\gradstat{median}<=\gradstat{q3}<=\gradstat{high}}
%<lib-distribution>       {\gradbarsFail{Summary~requires~low<=q1<=median<=q3<=high}}
%<lib-distribution>     \prop_put:Nnx\l__gradbars_stats_prop{iqr}{\fp_eval:n{\gradstat{q3}-\gradstat{q1}}}
%<lib-distribution>     \tl_set:Nx\l_tmpa_tl{\gradstat{missing}}
%<lib-distribution>     \str_if_eq:VnF\l_tmpa_tl{unknown}
%<lib-distribution>       {\regex_match:nVF{\A[0-9]+\Z}\l_tmpa_tl{\gradbarsFail{Summary~missing~must~be~a~nonnegative~integer}}}
%<lib-distribution>     \int_set:Nn\l_tmpa_int{1}
%<lib-distribution>     \fp_compare:nNnF{\gradstat{low}}={\gradstat{high}}{\int_set:Nn\l_tmpa_int{2}}
%<lib-distribution>     \int_compare:nNnT{\seq_count:N\l__gradbars_outliers_seq+\l_tmpa_int}>{\gradstat{n}}
%<lib-distribution>       {\gradbarsFail{Summary~n~cannot~contain~the~outliers~and~observed~whiskers}}
%<lib-distribution>     \prop_if_in:NnT\l__gradbars_stats_prop{min}
%<lib-distribution>       {\fp_compare:nNnT{\gradstat{min}}>{\gradstat{low}}{\gradbarsFail{Summary~minimum~exceeds~lower~whisker}}}
%<lib-distribution>     \prop_if_in:NnT\l__gradbars_stats_prop{max}
%<lib-distribution>       {\fp_compare:nNnT{\gradstat{max}}<{\gradstat{high}}{\gradbarsFail{Summary~maximum~below~upper~whisker}}}
%<lib-distribution>     \int_compare:nNnT{\gradstat{n}}={1}
%<lib-distribution>       {\fp_compare:nNnF{\gradstat{low}}={\gradstat{high}}{\gradbarsFail{Single~sample~summary~must~be~constant}}}
%<lib-distribution>
%<lib-distribution>     \seq_map_inline:Nn\l__gradbars_outliers_seq
%<lib-distribution>       {\gradbarsCheckNumber{##1}{summary~outlier}
%<lib-distribution>        \ifgradbars@valid
%<lib-distribution>          \prop_if_in:NnT\l__gradbars_stats_prop{min}
%<lib-distribution>            {\fp_compare:nNnT{##1}<{\gradstat{min}}{\gradbarsFail{Summary~outlier~below~declared~minimum}}}
%<lib-distribution>          \prop_if_in:NnT\l__gradbars_stats_prop{max}
%<lib-distribution>            {\fp_compare:nNnT{##1}>{\gradstat{max}}{\gradbarsFail{Summary~outlier~above~declared~maximum}}}
%<lib-distribution>        \fi
%<lib-distribution>        \ifgradbars@valid\fp_compare:nF{##1<\gradstat{low} || ##1>\gradstat{high}}
%<lib-distribution>          {\gradbarsFail{Summary~outlier~must~lie~outside~whiskers}}\fi}
%<lib-distribution>     \clist_map_inline:nn{min,max}
%<lib-distribution>       {\prop_if_in:NnF\l__gradbars_stats_prop{##1}
%<lib-distribution>          {\prop_put:Nnx\l__gradbars_stats_prop{##1}{\str_if_eq:nnTF{##1}{min}{\gradstat{low}}{\gradstat{high}}}}}
%<lib-distribution>     \seq_map_inline:Nn\l__gradbars_outliers_seq
%<lib-distribution>       {\prop_put:Nnx\l__gradbars_stats_prop{min}{\fp_eval:n{min(##1,\gradstat{min})}}
%<lib-distribution>        \prop_put:Nnx\l__gradbars_stats_prop{max}{\fp_eval:n{max(##1,\gradstat{max})}}}
%<lib-distribution>     \prop_if_in:NnT\l__gradbars_stats_prop{mean}
%<lib-distribution>       {\fp_compare:nF{\gradstat{min}<=\gradstat{mean}<=\gradstat{max}}
%<lib-distribution>          {\gradbarsFail{Summary~mean~must~lie~within~extrema}}}
%<lib-distribution>   \fi}
%<lib-distribution>\cs_new:Npn\__gradbars_box_x:n #1{\fp_eval:n{max(0,min(1,((#1)-\gradbars@min)/(\gradbars@max-\gradbars@min)))}}
%<lib-distribution>\cs_new_protected:Npn\__gradbars_distribution_draw:
%<lib-distribution>  {\gradbarsResolveScaleGroup\gradbarsValidateFormatter
%<lib-distribution>   \tl_set:Nx\l_tmpa_tl{\gradbars@precision}
%<lib-distribution>   \regex_match:nVF{\A[0-6]\Z}\l_tmpa_tl{\gradbarsFail{Precision~must~be~an~integer~from~0~to~6}}
%<lib-distribution>   \str_if_eq:eeF{\gradbars@format}{value}{\gradbarsFail{Box~plots~require~value~format=value}}
%<lib-distribution>   \int_compare:nNnT{\gradstat{n}}>{0}
%<lib-distribution>     {\tl_if_empty:oT{\gradbars@scalegroup}
%<lib-distribution>        {\str_if_eq:VnT\l__gradbars_distribution_range_tl{auto}
%<lib-distribution>          {\cs_set:Npx\gradbars@min{\gradstat{min}}\cs_set:Npx\gradbars@max{\gradstat{max}}
%<lib-distribution>           \fp_compare:nNnT{\gradbars@min}={\gradbars@max}
%<lib-distribution>             {\fp_set:Nn\l__gradbars_box_low_fp{\gradstat{min}}
%<lib-distribution>              \fp_set_eq:NN\l__gradbars_box_high_fp\l__gradbars_box_low_fp
%<lib-distribution>              \__gradbars_constant_range:NN\l__gradbars_box_low_fp\l__gradbars_box_high_fp
%<lib-distribution>              \cs_set:Npx\gradbars@min{\fp_use:N\l__gradbars_box_low_fp}
%<lib-distribution>              \cs_set:Npx\gradbars@max{\fp_use:N\l__gradbars_box_high_fp}}}}}
%<lib-distribution>   \gradbarsCheckNumber{\gradbars@min}{min}\gradbarsCheckNumber{\gradbars@max}{max}
%<lib-distribution>   \ifgradbars@valid
%<lib-distribution>     \fp_compare:nNnF{\gradbars@max}>{\gradbars@min}{\gradbarsFail{Max~must~be~greater~than~min}}
%<lib-distribution>     \dim_compare:nNnF{\gradbars@width}>{0pt}{\gradbarsFail{Width~must~be~positive}}
%<lib-distribution>     \dim_compare:nNnF{\gradbars@height}>{0pt}{\gradbarsFail{Height~must~be~positive}}
%<lib-distribution>   \fi
%<lib-distribution>   \ifgradbars@valid
%<lib-distribution>     \int_compare:nNnT{\gradstat{n}}>{0}
%<lib-distribution>       {\gradbarsRange{Box~minimum}{\gradstat{min}}\gradbarsRange{Box~maximum}{\gradstat{max}}}
%<lib-distribution>     \tl_set:Nx\l__gradbars_alt_tl{Box~plot:~n=\gradstat{n};~missing=\gradstat{missing};~
%<lib-distribution>       Q1=\gradstat{q1};~median=\gradstat{median};~Q3=\gradstat{q3};~IQR=\gradstat{iqr};~
%<lib-distribution>       whiskers=\gradstat{low}~to~\gradstat{high};~outlier~count=\gradstat{outlier~count};~
%<lib-distribution>       outliers=\tl_if_empty:eTF{\gradstat{outliers}}{none}{\gradstat{outliers}}.~Method:~\gradstat{method}.~Scale:~\gradbars@min\c_space_tl to~\gradbars@max.}
%<lib-distribution>     \tl_if_empty:oF{\gradbars@unit}{\tl_put_right:Nx\l__gradbars_alt_tl{~Unit:~\exp_not:o{\gradbars@unit}.}}
%<lib-distribution>     \ifgradbars@print\def\gradbars@left{black}\fi
%<lib-distribution>     \str_if_eq:eeT{\gradbars@textcolor}{auto}{\def\gradbars@textcolor{black}}
%<lib-distribution>     \__gradbars_backend_draw:nn{boxplot}
%<lib-distribution>      {\gradbarsApplyAlt
%<lib-distribution>     \leavevmode\tikz[baseline=-.5ex,x=\gradbars@width,y=\gradbars@height]
%<lib-distribution>       {\path[use~as~bounding~box](0,0)rectangle(1,1);
%<lib-distribution>        \int_compare:nNnTF{\gradstat{n}}={0}
%<lib-distribution>          {\node[font=\gradbars@font]at(.5,.5){\gradbars@missingtext};}
%<lib-distribution>          {\draw[draw=\gradbars@left,line~width=.5pt]
%<lib-distribution>             (\__gradbars_box_x:n{\gradstat{low}},.5)--(\__gradbars_box_x:n{\gradstat{high}},.5);
%<lib-distribution>           \draw[draw=\gradbars@left,fill=\gradbars@left!15,line~width=.5pt]
%<lib-distribution>             (\__gradbars_box_x:n{\gradstat{q1}},.2)rectangle(\__gradbars_box_x:n{\gradstat{q3}},.8);
%<lib-distribution>           \draw[draw=\gradbars@textcolor,line~width=.8pt]
%<lib-distribution>             (\__gradbars_box_x:n{\gradstat{median}},.2)--(\__gradbars_box_x:n{\gradstat{median}},.8);
%<lib-distribution>           \clist_map_inline:nn{low,high}
%<lib-distribution>             {\draw[draw=\gradbars@left,line~width=.5pt]
%<lib-distribution>               (\__gradbars_box_x:n{\gradstat{##1}},.3)--(\__gradbars_box_x:n{\gradstat{##1}},.7);}
%<lib-distribution>           \seq_map_inline:Nn\l__gradbars_outliers_seq
%<lib-distribution>             {\draw[draw=\gradbars@left,fill=white](\__gradbars_box_x:n{##1},.5)circle[radius=1.2pt];}
%<lib-distribution>           \str_if_eq:eeF{\gradbars@label}{none}
%<lib-distribution>             {\node[anchor=west,font=\gradbars@font,inner~sep=0pt]
%<lib-distribution>               at([xshift=\gradbars@gap]1,.5){\gradbarsFormatEndpoint{\gradstat{median}}};}}}
%<lib-distribution>      }
%<lib-distribution>   \fi}
%<lib-distribution>\DeclareDocumentCommand\gradboxplot{O{} m}
%<lib-distribution>  {\group_begin:\gradbars@validtrue\gradbarsCaptureTikzAlt\gradbars@capturealttrue
%<lib-distribution>   \gradbarssetup{height=3ex,label=none,#1}\gradbars@capturealtfalse
%<lib-distribution>   \__gradbars_distribution_parse:n{#2}\ifgradbars@valid\__gradbars_distribution_draw:\fi\group_end:}
%<lib-distribution>\DeclareDocumentCommand\gradboxsummary{O{} m}
%<lib-distribution>  {\group_begin:\gradbars@validtrue\gradbarsCaptureTikzAlt\gradbars@capturealttrue
%<lib-distribution>   \gradbarssetup{height=3ex,label=none,#1}\gradbars@capturealtfalse
%<lib-distribution>   \__gradbars_distribution_record:n{#2}\ifgradbars@valid\__gradbars_distribution_draw:\fi\group_end:}
%<lib-distribution>\ExplSyntaxOff
%<lib-distribution>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-lib-heat.sty}}
%    \begin{macrocode}
%<lib-heat>% Author: SuFan; MIT License. Internal implementation unless documented.
%<lib-heat>\ProvidesPackage{gradbars-lib-heat}[2026/10/25 v1.1.0 gradbars lib-heat]
%<lib-heat>\ExplSyntaxOff
%<lib-heat>\def\gradbars@heatlow{gradbarsBlueLight!15}
%<lib-heat>\def\gradbars@heathigh{gradbarsBlue}
%<lib-heat>\def\gradbars@heattext{auto}
%<lib-heat>\def\gradbars@heatmissing{gradbarsTrack}
%<lib-heat>% Named palettes select both interpolation mode and color roles.
%<lib-heat>\definecolor{gradbarsHeatRed}{HTML}{B91C1C}
%<lib-heat>\definecolor{gradbarsHeatBrown}{HTML}{92400E}
%<lib-heat>\pgfkeys{/gradbars,
%<lib-heat>  heat palette/blue/.style={heat palette=sequential,heat low color=white,heat center color=white,heat high color=gradbarsBlue,heat text color=auto},
%<lib-heat>  heat palette/teal/.style={heat palette=sequential,heat low color=white,heat center color=white,heat high color=gradbarsTeal,heat text color=auto},
%<lib-heat>  heat palette/purple/.style={heat palette=sequential,heat low color=white,heat center color=white,heat high color=gradbarsPurple,heat text color=auto},
%<lib-heat>  heat palette/orange/.style={heat palette=sequential,heat low color=white,heat center color=white,heat high color=gradbarsWarmOrange,heat text color=auto},
%<lib-heat>  heat palette/purple-teal/.style={heat palette=diverging,heat low color=gradbarsPurple,heat center color=white,heat high color=gradbarsTeal,heat text color=auto},
%<lib-heat>  heat palette/blue-red/.style={heat palette=diverging,heat low color=gradbarsBlue,heat center color=white,heat high color=gradbarsHeatRed,heat text color=auto},
%<lib-heat>  heat palette/orange-blue/.style={heat palette=diverging,heat low color=gradbarsWarmOrange,heat center color=white,heat high color=gradbarsBlue,heat text color=auto},
%<lib-heat>  heat palette/brown-teal/.style={heat palette=diverging,heat low color=gradbarsHeatBrown,heat center color=white,heat high color=gradbarsTeal,heat text color=auto},
%<lib-heat>  heat low color/.store in=\gradbars@heatlow,
%<lib-heat>  heat high color/.store in=\gradbars@heathigh,
%<lib-heat>  heat text color/.store in=\gradbars@heattext,
%<lib-heat>  heat missing color/.store in=\gradbars@heatmissing,
%<lib-heat>  print/.append style={heat low color=white,heat high color=black!75}}
%<lib-heat>\ExplSyntaxOn
%<lib-heat>\DeclareDocumentCommand\gradheat{O{} m}
%<lib-heat>  {\gradbarsHeatCell{height=3ex,#1}{#2}}
%<lib-heat>\cs_new_protected:Npn\gradbarsHeatCell #1#2
%<lib-heat>  {\leavevmode\group_begin:
%<lib-heat>   \gradbarsCaptureTikzAlt\gradbars@capturealttrue
%<lib-heat>   \pgfkeys{/gradbars,#1}\gradbars@capturealtfalse
%<lib-heat>   \gradbars@stackfalse\gradbars@sparkfalse\gradbars@comparefalse\gradbars@rangemodefalse
%<lib-heat>   \ifpgfpicture
%<lib-heat>     \pgfinterruptpicture\font@name
%<lib-heat>     \edef\gradbars@resolved{\noexpand\endpgfinterruptpicture
%<lib-heat>       \def\noexpand\gradbars@width{\the\dimexpr\gradbars@width\relax}
%<lib-heat>       \def\noexpand\gradbars@height{\the\dimexpr\gradbars@height\relax}
%<lib-heat>       \def\noexpand\gradbars@rounded{\the\dimexpr\gradbars@rounded\relax}}
%<lib-heat>     \gradbars@resolved
%<lib-heat>   \fi
%<lib-heat>   \gradbars@validtrue\gradbars@missingfalse
%<lib-heat>   \gradbarsValidateFormatter
%<lib-heat>   \gradbarsResolveScaleGroup
%<lib-heat>   \tl_set:Nx\l_tmpa_tl{#2}\tl_trim_spaces:N\l_tmpa_tl
%<lib-heat>   \tl_if_empty:NT\l_tmpa_tl{\gradbars@missingtrue}
%<lib-heat>   \str_if_eq:VnT\l_tmpa_tl{NA}{\gradbars@missingtrue}
%<lib-heat>   \def\gradbars@value{#2}
%<lib-heat>   \gradbarsCheckNumber{\gradbars@min}{min}\gradbarsCheckNumber{\gradbars@max}{max}
%<lib-heat>   \ifgradbars@missing\else\gradbarsCheckNumber{#2}{heat~value}\fi
%<lib-heat>   \tl_set:Nx\l_tmpa_tl{\gradbars@precision}
%<lib-heat>   \regex_match:nVF{\A[0-6]\Z}\l_tmpa_tl
%<lib-heat>     {\gradbarsFail{Precision~must~be~an~integer~from~0~to~6}}
%<lib-heat>   \ifgradbars@valid
%<lib-heat>     \fp_compare:nNnF{\gradbars@max}>{\gradbars@min}{\gradbarsFail{Max~must~be~greater~than~min}}
%<lib-heat>     \str_if_eq:eeT{\gradbars@format}{percent}
%<lib-heat>       {\fp_compare:nNnF{\gradbars@min}={0}{\gradbarsFail{Percent~format~requires~min=0}}
%<lib-heat>        \fp_compare:nNnF{\gradbars@max}>{0}{\gradbarsFail{Percent~format~requires~positive~max}}
%<lib-heat>        \gradbarsValidatePercentBase}
%<lib-heat>     \dim_compare:nNnF{\gradbars@width}>{0pt}{\gradbarsFail{Width~must~be~positive}}
%<lib-heat>     \dim_compare:nNnF{\gradbars@height}>{0pt}{\gradbarsFail{Height~must~be~positive}}
%<lib-heat>     \str_if_eq:eeT{\gradbars@heatpalette}{diverging}
%<lib-heat>       {\gradbarsCheckNumber{\gradbars@heatcenter}{heat~center}
%<lib-heat>        \ifgradbars@valid\fp_compare:nF{\gradbars@min<=\gradbars@heatcenter<=\gradbars@max}
%<lib-heat>          {\gradbarsFail{Heat~center~must~lie~within~range}}\fi}
%<lib-heat>   \fi
%<lib-heat>   \ifgradbars@valid
%<lib-heat>     \ifgradbars@missing
%<lib-heat>       \colorlet{gradbarsHeatCell}{\gradbars@heatmissing}
%<lib-heat>     \else
%<lib-heat>       \gradbarsRange{Heat~value}{#2}
%<lib-heat>       \cs_set:Npx\gradbars@number{\fp_eval:n{\str_if_eq:eeTF{\gradbars@format}{percent}{100*(#2)/\gradbarsPercentBase}{#2}}}
%<lib-heat>       \gradbarsHeatColor{#2}
%<lib-heat>     \fi
%<lib-heat>     \str_if_eq:eeTF{\gradbars@heattext}{auto}
%<lib-heat>       {\gradbarsContrast{gradbarsHeatCell}}{\let\gradbars@labelcolor\gradbars@heattext}
%<lib-heat>     \tl_set:Nn\l__gradbars_alt_tl{Heat~cell:~}
%<lib-heat>     \ifgradbars@missing\tl_put_right:Nn\l__gradbars_alt_tl{missing.}
%<lib-heat>     \else\tl_put_right:Nx\l__gradbars_alt_tl
%<lib-heat>       {\fp_eval:n{#2}~\gradbars@unit.~Color~scale:~\gradbars@min\c_space_tl to~\gradbars@max.}\fi
%<lib-heat>     \str_if_eq:eeT{\gradbars@heatpalette}{diverging}
%<lib-heat>       {\tl_put_right:Nx\l__gradbars_alt_tl{~Diverging~center:~\gradbars@heatcenter.}}
%<lib-heat>     \str_if_eq:eeT{\gradbars@format}{percent}{\tl_put_right:Nx\l__gradbars_alt_tl{~Percent~base:~\gradbarsPercentBase.}}
%<lib-heat>     \tl_put_right:Nx\l__gradbars_alt_tl{~Direction:~\gradbars@better.}
%<lib-heat>     \ifgradbars@valid
%<lib-heat>       \__gradbars_backend_draw:nn{heat}
%<lib-heat>        {\ifpgfpicture\begin{scope}\gradbarsHeatDraw\end{scope}
%<lib-heat>       \else\gradbarsApplyAlt\tikz[baseline=(gradbarsheat.base)]{\gradbarsHeatDraw}\fi}
%<lib-heat>     \fi
%<lib-heat>   \fi\group_end:}
%<lib-heat>\cs_new_protected:Npn\gradbarsHeatDraw
%<lib-heat>  {\node[fill=gradbarsHeatCell,text=\gradbars@labelcolor,inner~sep=2pt,
%<lib-heat>     minimum~width=\gradbars@width,minimum~height=\gradbars@height,
%<lib-heat>     font=\gradbars@font,rounded~corners=\gradbars@rounded](gradbarsheat)
%<lib-heat>     {\str_if_eq:eeF{\gradbars@label}{none}{\gradbars@labelcontent}};}
%<lib-heat>\ExplSyntaxOff
%<lib-heat>
%<lib-heat>\ExplSyntaxOff
%<lib-heat>\ExplSyntaxOn
%<lib-heat>\fp_new:N\l__gradbars_heat_value_fp
%<lib-heat>\cs_new_protected:Npn\gradbarsHeatColor #1
%<lib-heat>  {\colorlet{gradbarsHeatLow}{\gradbars@heatlow}
%<lib-heat>   \colorlet{gradbarsHeatHigh}{\gradbars@heathigh}
%<lib-heat>   \colorlet{gradbarsHeatCenter}{\gradbars@heatcentercolor}
%<lib-heat>   \ifgradbars@print
%<lib-heat>     \colorlet{gradbarsHeatLow}{white}\colorlet{gradbarsHeatHigh}{black!75}
%<lib-heat>     \str_if_eq:eeT{\gradbars@heatpalette}{diverging}
%<lib-heat>       {\colorlet{gradbarsHeatLow}{black!75}\colorlet{gradbarsHeatCenter}{white}}
%<lib-heat>   \fi
%<lib-heat>   \str_if_eq:eeTF{\gradbars@heatpalette}{diverging}
%<lib-heat>     {\str_if_eq:eeT{\gradbars@better}{lower}
%<lib-heat>        {\colorlet{gradbarsHeatSwap}{gradbarsHeatLow}
%<lib-heat>         \colorlet{gradbarsHeatLow}{gradbarsHeatHigh}\colorlet{gradbarsHeatHigh}{gradbarsHeatSwap}}
%<lib-heat>      \fp_set:Nn\l__gradbars_heat_value_fp{max(\gradbars@min,min(\gradbars@max,#1))}
%<lib-heat>      \fp_compare:nNnTF{\l__gradbars_heat_value_fp}={\gradbars@heatcenter}
%<lib-heat>        {\colorlet{gradbarsHeatCell}{gradbarsHeatCenter}}
%<lib-heat>        {\fp_compare:nNnTF{\l__gradbars_heat_value_fp}<{\gradbars@heatcenter}
%<lib-heat>           {\colorlet{gradbarsHeatCell}{gradbarsHeatLow!\fp_eval:n{
%<lib-heat>             100*(\gradbars@heatcenter-\l__gradbars_heat_value_fp)/(\gradbars@heatcenter-\gradbars@min)}!gradbarsHeatCenter}}
%<lib-heat>           {\colorlet{gradbarsHeatCell}{gradbarsHeatHigh!\fp_eval:n{
%<lib-heat>             100*(\l__gradbars_heat_value_fp-\gradbars@heatcenter)/(\gradbars@max-\gradbars@heatcenter)}!gradbarsHeatCenter}}}}
%<lib-heat>     {\colorlet{gradbarsHeatCell}{gradbarsHeatHigh!\fp_eval:n{
%<lib-heat>        100*\str_if_eq:eeTF{\gradbars@better}{lower}{(1-\gradbarsPosition{#1})}{\gradbarsPosition{#1}}}!gradbarsHeatLow}}}
%<lib-heat>
%<lib-heat>\ExplSyntaxOff
%<lib-heat>
%<lib-heat>\ExplSyntaxOff
%<lib-heat>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-lib-legend.sty}}
%    \begin{macrocode}
%<lib-legend>% Author: SuFan; MIT License. Continuous and shared semantic legends.
%<lib-legend>\ProvidesPackage{gradbars-lib-legend}[2026/10/25 v1.1.0 Shared legends]
%<lib-legend>\ExplSyntaxOn
%<lib-legend>\cs_generate_variant:Nn\seq_set_from_clist:Nn{NV}
%<lib-legend>\cs_generate_variant:Nn\prop_to_keyval:N{c}
%<lib-legend>\tl_new:N\l__gradbars_legend_title_tl
%<lib-legend>\tl_new:N\l__gradbars_legend_ticks_tl
%<lib-legend>\tl_new:N\l__gradbars_legend_names_tl
%<lib-legend>\tl_new:N\l__gradbars_legend_orientation_tl
%<lib-legend>\tl_new:N\l__gradbars_legend_missing_tl
%<lib-legend>\tl_new:N\l__gradbars_legend_kind_tl
%<lib-legend>\tl_new:N\l__gradbars_legend_group_tl
%<lib-legend>\tl_new:N\l__gradbars_legend_snapshot_tl
%<lib-legend>\tl_new:N\l__gradbars_legend_signature_tl
%<lib-legend>\prop_new:N\l__gradbars_legends_prop
%<lib-legend>\prop_new:N\l__gradbars_legend_signatures_prop
%<lib-legend>\int_new:N\g__gradbars_legend_scale_int
%<lib-legend>\tl_new:N\l__gradbars_legend_scale_name_tl
%<lib-legend>\cs_new_protected:Npn\__gradbars_legend_scale_name:
%<lib-legend>  {\int_gincr:N\g__gradbars_legend_scale_int
%<lib-legend>   \tl_set:Nx\l__gradbars_legend_scale_name_tl{gradbars-internal-legend-\int_use:N\g__gradbars_legend_scale_int}
%<lib-legend>   \prop_if_in:NVTF\l__gradbars_scale_groups_prop\l__gradbars_legend_scale_name_tl
%<lib-legend>     {\__gradbars_legend_scale_name:}{}}
%<lib-legend>
%<lib-legend>\seq_new:N\l__gradbars_legend_ticks_seq
%<lib-legend>\fp_new:N\l__gradbars_legend_previous_fp
%<lib-legend>\fp_new:N\l__gradbars_legend_value_fp
%<lib-legend>\seq_new:N\l__gradbars_legend_tick_rows_seq
%<lib-legend>\box_new:N\l__gradbars_legend_tick_box
%<lib-legend>\dim_new:N\l__gradbars_legend_tick_left_dim
%<lib-legend>\dim_new:N\l__gradbars_legend_tick_right_dim
%<lib-legend>\dim_new:N\l__gradbars_legend_lane_a_dim
%<lib-legend>\dim_new:N\l__gradbars_legend_lane_b_dim
%<lib-legend>\cs_new_protected:Npn\__gradbars_legend_tick_layout:
%<lib-legend>  {\seq_clear:N\l__gradbars_legend_tick_rows_seq
%<lib-legend>   \dim_set:Nn\l__gradbars_legend_lane_a_dim{-10000pt}
%<lib-legend>   \dim_set:Nn\l__gradbars_legend_lane_b_dim{-10000pt}
%<lib-legend>   \seq_map_inline:Nn\l__gradbars_legend_ticks_seq
%<lib-legend>     {\gradbarsSuspendMeasurementTagging
%<lib-legend>      \hbox_set:Nn\l__gradbars_legend_tick_box{\gradbars@font\gradbarsFormatEndpoint{##1}}
%<lib-legend>      \gradbarsResumeMeasurementTagging
%<lib-legend>      \dim_set:Nn\l__gradbars_legend_tick_left_dim
%<lib-legend>        {\fp_to_dim:n{\gradbarsPosition{##1}*\dim_to_fp:n{\gradbars@width}}-\box_wd:N\l__gradbars_legend_tick_box/2}
%<lib-legend>      \dim_set:Nn\l__gradbars_legend_tick_right_dim
%<lib-legend>        {\l__gradbars_legend_tick_left_dim+\box_wd:N\l__gradbars_legend_tick_box+2pt}
%<lib-legend>      \dim_compare:nNnTF{\l__gradbars_legend_tick_left_dim}>{\l__gradbars_legend_lane_a_dim}
%<lib-legend>        {\seq_put_right:Nn\l__gradbars_legend_tick_rows_seq{0}
%<lib-legend>         \dim_set_eq:NN\l__gradbars_legend_lane_a_dim\l__gradbars_legend_tick_right_dim}
%<lib-legend>        {\dim_compare:nNnTF{\l__gradbars_legend_tick_left_dim}>{\l__gradbars_legend_lane_b_dim}
%<lib-legend>          {\seq_put_right:Nn\l__gradbars_legend_tick_rows_seq{1}
%<lib-legend>           \dim_set_eq:NN\l__gradbars_legend_lane_b_dim\l__gradbars_legend_tick_right_dim}
%<lib-legend>          {\gradbarsFail{Legend~tick~labels~overlap;~increase~width~or~reduce~ticks}}}}}
%<lib-legend>\tl_set:Nn\l__gradbars_legend_orientation_tl{horizontal}
%<lib-legend>\tl_set:Nn\l__gradbars_legend_missing_tl{true}
%<lib-legend>\tl_set:Nn\l__gradbars_legend_kind_tl{heat}
%<lib-legend>\pgfkeys{/gradbars,
%<lib-legend> legend~title/.store~in=\l__gradbars_legend_title_tl,
%<lib-legend> legend~ticks/.store~in=\l__gradbars_legend_ticks_tl,
%<lib-legend> legend~names/.store~in=\l__gradbars_legend_names_tl,
%<lib-legend> legend~orientation/.is~choice,
%<lib-legend> legend~orientation/horizontal/.code={\tl_set:Nn\l__gradbars_legend_orientation_tl{horizontal}},
%<lib-legend> legend~orientation/vertical/.code={\tl_set:Nn\l__gradbars_legend_orientation_tl{vertical}},
%<lib-legend> legend~missing/.is~choice,
%<lib-legend> legend~missing/true/.code={\tl_set:Nn\l__gradbars_legend_missing_tl{true}},
%<lib-legend> legend~missing/false/.code={\tl_set:Nn\l__gradbars_legend_missing_tl{false}},
%<lib-legend> legend~missing/.default=true,
%<lib-legend> legend~kind/.is~choice,
%<lib-legend> legend~kind/heat/.code={\tl_set:Nn\l__gradbars_legend_kind_tl{heat}},
%<lib-legend> legend~kind/categorical/.code={\tl_set:Nn\l__gradbars_legend_kind_tl{categorical}},
%<lib-legend> legend~kind/reference/.code={\tl_set:Nn\l__gradbars_legend_kind_tl{reference}},
%<lib-legend> legend~group/.code={\__gradbars_legend_apply:n{#1}}}
%<lib-legend>\cs_new_protected:Npn\__gradbars_legend_signature:
%<lib-legend>  {\tl_set:Nx\l__gradbars_legend_signature_tl
%<lib-legend>    {\gradbars@min/\gradbars@max/\gradbars@heatlow/\gradbars@heathigh/
%<lib-legend>     \gradbars@heatpalette/\gradbars@heatcenter/\gradbars@heatcentercolor/\gradbars@better/
%<lib-legend>     \exp_not:o{\gradbars@unit}/\exp_not:o{\gradbars@unitcode}/\exp_not:o{\gradbars@unittext}/\gradbars@left/\gradbars@right/\gradbars@negativecolor/
%<lib-legend>     \gradbars@comparecolor/\gradbars@stackcolors/\gradbars@stackpatterns/
%<lib-legend>     \ifgradbars@print true\else false\fi}
%<lib-legend>   \clist_map_inline:nn{heatmissing,targetcolor,bandcolor,bandopacity,errorcolor,thresholdcolors,target,band,references,errorminus,errorplus,thresholds,bulletbands,format,percentbase,sparkhigh,sparklow,sparkwincolor,sparklosscolor,sparkzerocolor}
%<lib-legend>     {\tl_put_right:Nx\l__gradbars_legend_signature_tl{##1={\exp_not:v{gradbars@##1}}}}}
%<lib-legend>\cs_new_protected:Npn\__gradbars_legend_check:
%<lib-legend>  {\tl_if_empty:NF\l__gradbars_legend_group_tl
%<lib-legend>     {\__gradbars_legend_signature:
%<lib-legend>      \str_if_eq:eeF{\l__gradbars_legend_signature_tl}
%<lib-legend>        {\prop_item:NV\l__gradbars_legend_signatures_prop\l__gradbars_legend_group_tl}
%<lib-legend>        {\gradbarsFail{Conflicting~scale,~unit~or~palette~for~shared~legend}}}}
%<lib-legend>\cs_new_eq:NN\__gradbars_resolve_before_legend:\gradbarsResolveScaleGroup
%<lib-legend>\cs_set_protected:Npn\gradbarsResolveScaleGroup
%<lib-legend>  {\__gradbars_legend_check:\__gradbars_resolve_before_legend:\__gradbars_legend_check:
%<lib-legend>   \tl_if_empty:NF\l__gradbars_legend_group_tl
%<lib-legend>     {\ifgradbars@spark
%<lib-legend>       \str_if_eq:eeT{\gradbars@sparktype}{winloss}
%<lib-legend>         {\fp_compare:nF{\gradbars@min=-1 && \gradbars@max=1}
%<lib-legend>           {\gradbarsFail{Shared~win-loss~legend~requires~min=-1,max=1}}}
%<lib-legend>      \fi}}
%<lib-legend>\cs_new_protected:Npn\__gradbars_legend_validate:
%<lib-legend>  {\gradbarsResolveScaleGroup\gradbarsValidateFormatter
%<lib-legend>   \tl_set:Nx\l_tmpa_tl{\gradbars@precision}
%<lib-legend>   \regex_match:nVF{\A[0-6]\Z}\l_tmpa_tl{\gradbarsFail{Precision~must~be~an~integer~from~0~to~6}}
%<lib-legend>   \gradbarsCheckNumber{\gradbars@min}{min}\gradbarsCheckNumber{\gradbars@max}{max}
%<lib-legend>   \ifgradbars@valid
%<lib-legend>     \str_if_eq:eeT{\gradbars@format}{percent}
%<lib-legend>       {\fp_compare:nNnF{\gradbars@min}={0}{\gradbarsFail{Percent~legend~requires~min=0}}
%<lib-legend>        \gradbarsValidatePercentBase}
%<lib-legend>     \fp_compare:nNnF{\gradbars@max}>{\gradbars@min}{\gradbarsFail{Max~must~be~greater~than~min}}
%<lib-legend>     \dim_compare:nNnF{\gradbars@width}>{0pt}{\gradbarsFail{Width~must~be~positive}}
%<lib-legend>     \dim_compare:nNnF{\gradbars@height}>{0pt}{\gradbarsFail{Height~must~be~positive}}
%<lib-legend>     \str_if_eq:eeT{\gradbars@heatpalette}{diverging}
%<lib-legend>       {\gradbarsCheckNumber{\gradbars@heatcenter}{heat~center}
%<lib-legend>        \ifgradbars@valid\fp_compare:nF{\gradbars@min<=\gradbars@heatcenter<=\gradbars@max}
%<lib-legend>          {\gradbarsFail{Heat~center~must~lie~within~range}}\fi}
%<lib-legend>   \fi}
%<lib-legend>\DeclareDocumentCommand\gradlegenddefine{m m}
%<lib-legend>  {\prop_if_in:NnTF\l__gradbars_legends_prop{#1}
%<lib-legend>     {\__gradbars_public_error:n{Legend~already~defined:~#1}}
%<lib-legend>     {\__gradbars_name_valid:nTF{#1}
%<lib-legend>       {\group_begin:\gradbars@validtrue
%<lib-legend>        \tl_if_empty:NF\l__gradbars_legend_group_tl{\def\gradbars@scalegroup{}}
%<lib-legend>        \tl_clear:N\l__gradbars_legend_group_tl
%<lib-legend>        \gradbarssetup{#2}\__gradbars_legend_validate:
%<lib-legend>        \__gradbars_legend_scale_name:
%<lib-legend>        \tl_clear:N\l__gradbars_legend_snapshot_tl
%<lib-legend>        \clist_map_inline:nn{min,max,heatlow,heathigh,heatpalette,heatcenter,heatcentercolor,
%<lib-legend>          better,unit,unitcode,unittext,left,right,negativecolor,comparecolor,stackcolors,stackpatterns,
%<lib-legend>          targetcolor,bandcolor,bandopacity,errorcolor,heatmissing,thresholdcolors,
%<lib-legend>          target,band,references,errorminus,errorplus,thresholds,bulletbands,formatter,numberformat,format,percentbase,
%<lib-legend>          sparkhigh,sparklow,sparkwincolor,sparklosscolor,sparkzerocolor}
%<lib-legend>          {\tl_put_right:Nx\l__gradbars_legend_snapshot_tl
%<lib-legend>             {\exp_not:N\def\exp_not:c{gradbars@##1}{\exp_not:v{gradbars@##1}}}}
%<lib-legend>        \tl_put_right:Nx\l__gradbars_legend_snapshot_tl
%<lib-legend>          {\ifgradbars@print\exp_not:N\gradbars@printtrue\else\exp_not:N\gradbars@printfalse\fi}
%<lib-legend>        \clist_map_inline:nn{kind,names,title,ticks,orientation,missing}
%<lib-legend>          {\tl_put_right:Nx\l__gradbars_legend_snapshot_tl
%<lib-legend>            {\exp_not:N\tl_set:Nn\exp_not:c{l__gradbars_legend_##1_tl}
%<lib-legend>              {\exp_not:v{l__gradbars_legend_##1_tl}}}}
%<lib-legend>        \clist_map_inline:nn{colors,patterns}
%<lib-legend>          {\tl_put_right:Nx\l__gradbars_legend_snapshot_tl
%<lib-legend>             {\exp_not:N\prop_set_from_keyval:Nn\exp_not:c{l__gradbars_category_##1_prop}
%<lib-legend>               {\exp_not:e{\prop_to_keyval:c{l__gradbars_category_##1_prop}}}}}
%<lib-legend>        \__gradbars_legend_signature:
%<lib-legend>        \ifgradbars@valid
%<lib-legend>          \use:x{\group_end:
%<lib-legend>            \prop_put:Nnn\exp_not:N\l__gradbars_scale_groups_prop{\l__gradbars_legend_scale_name_tl}
%<lib-legend>              {min=\gradbars@min,max=\gradbars@max}
%<lib-legend>            \prop_put:Nnn\exp_not:N\l__gradbars_legends_prop{#1}
%<lib-legend>              {\exp_not:N\def\exp_not:N\gradbars@scalegroup{\l__gradbars_legend_scale_name_tl}
%<lib-legend>               \exp_not:V\l__gradbars_legend_snapshot_tl}
%<lib-legend>            \prop_put:Nnn\exp_not:N\l__gradbars_legend_signatures_prop{#1}
%<lib-legend>              {\exp_not:V\l__gradbars_legend_signature_tl}}
%<lib-legend>        \else\group_end:\fi}
%<lib-legend>       {\__gradbars_public_error:n{Invalid~legend~name:~#1}}}}
%<lib-legend>% Snapshots are executable assignments, not key lists.
%<lib-legend>\cs_new_protected:Npn\__gradbars_legend_apply:n #1
%<lib-legend>  {\tl_if_blank:nTF{#1}
%<lib-legend>     {\tl_clear:N\l__gradbars_legend_group_tl\def\gradbars@scalegroup{}}
%<lib-legend>     {\prop_get:NnNTF\l__gradbars_legends_prop{#1}\l__gradbars_legend_snapshot_tl
%<lib-legend>       {\tl_use:N\l__gradbars_legend_snapshot_tl\tl_set:Nn\l__gradbars_legend_group_tl{#1}}
%<lib-legend>       {\gradbarsFail{Unknown~legend~group:~#1}}}}
%<lib-legend>\keys_define:nn{gradbars/legend/layout}
%<lib-legend>  {width .code:n=\gradbarssetup{width=#1},height .code:n=\gradbarssetup{height=#1},
%<lib-legend>   legend~missing .code:n=\gradbarssetup{legend~missing=#1},
%<lib-legend>   legend~missing .default:n=true,
%<lib-legend>   title .tl_set:N=\l__gradbars_legend_title_tl,
%<lib-legend>   ticks .tl_set:N=\l__gradbars_legend_ticks_tl,
%<lib-legend>   orientation .choices:nn={horizontal,vertical}
%<lib-legend>     {\tl_set_eq:NN\l__gradbars_legend_orientation_tl\l_keys_choice_tl},
%<lib-legend>   precision .code:n=\gradbarssetup{precision=#1},
%<lib-legend>   number~format .code:n=\gradbarssetup{number~format=#1},
%<lib-legend>   font .code:n=\gradbarssetup{font={#1}},
%<lib-legend>   accessibility .code:n=\gradbarssetup{accessibility=#1},alt .code:n=\gradbarssetup{alt={#1}}}
%<lib-legend>\DeclareDocumentCommand\gradlegenduse{O{} m}
%<lib-legend>  {\group_begin:\gradbars@validtrue\gradbarssetup{width=50mm,height=3mm}
%<lib-legend>   \__gradbars_legend_apply:n{#2}\keys_set:nn{gradbars/legend/layout}{#1}
%<lib-legend>   \ifgradbars@valid
%<lib-legend>     \str_case:Vn\l__gradbars_legend_kind_tl
%<lib-legend>       {{heat}{\gradheatlegend}
%<lib-legend>        {categorical}{\exp_args:NV\gradbarslegend\l__gradbars_legend_names_tl}
%<lib-legend>        {reference}{\exp_args:NV\gradreferencelegend\l__gradbars_legend_names_tl}}
%<lib-legend>   \fi\group_end:}
%<lib-legend>\DeclareDocumentCommand\gradheatlegend{O{}}
%<lib-legend>  {\group_begin:\gradbars@validtrue\gradbarssetup{#1}\__gradbars_legend_validate:
%<lib-legend>   \ifgradbars@valid
%<lib-legend>     \tl_if_empty:NTF\l__gradbars_legend_ticks_tl
%<lib-legend>       {\seq_clear:N\l__gradbars_legend_ticks_seq
%<lib-legend>        \seq_put_right:Nx\l__gradbars_legend_ticks_seq{\gradbars@min}
%<lib-legend>        \str_if_eq:eeT{\gradbars@heatpalette}{diverging}
%<lib-legend>          {\fp_compare:nT{\gradbars@min<\gradbars@heatcenter<\gradbars@max}
%<lib-legend>            {\seq_put_right:Nx\l__gradbars_legend_ticks_seq{\gradbars@heatcenter}}}
%<lib-legend>        \seq_put_right:Nx\l__gradbars_legend_ticks_seq{\gradbars@max}}
%<lib-legend>       {\seq_set_from_clist:NV\l__gradbars_legend_ticks_seq\l__gradbars_legend_ticks_tl}
%<lib-legend>     \fp_set:Nn\l__gradbars_legend_previous_fp{-inf}
%<lib-legend>     \seq_map_inline:Nn\l__gradbars_legend_ticks_seq
%<lib-legend>       {\gradbarsCheckNumber{##1}{legend~tick}
%<lib-legend>        \ifgradbars@valid\fp_compare:nF{\l__gradbars_legend_previous_fp<##1 && \gradbars@min<=##1<=\gradbars@max}
%<lib-legend>          {\gradbarsFail{Legend~ticks~must~increase~within~range}}\fp_set:Nn\l__gradbars_legend_previous_fp{##1}\fi}
%<lib-legend>     \str_if_eq:VnT\l__gradbars_legend_orientation_tl{horizontal}{\ifgradbars@valid\__gradbars_legend_tick_layout:\fi}
%<lib-legend>     \tl_set:Nx\l__gradbars_alt_tl{Continuous~\gradbars@heatpalette\c_space_tl color~legend.~
%<lib-legend>       Scale:~\gradbars@min\c_space_tl to~\gradbars@max.~Direction:~\gradbars@better.}
%<lib-legend>     \str_if_eq:VnT\l__gradbars_legend_missing_tl{true}
%<lib-legend>       {\tl_put_right:Nx\l__gradbars_alt_tl{~Missing:~\gradbars@missingtext.}}
%<lib-legend>     \tl_if_empty:oF{\gradbars@unit}{\tl_put_right:Nx\l__gradbars_alt_tl{~Unit:~\exp_not:o{\gradbars@unit}.}}
%<lib-legend>     \str_if_eq:eeT{\gradbars@format}{percent}{\tl_put_right:Nx\l__gradbars_alt_tl{~Percent~base:~\gradbarsPercentBase.}}
%<lib-legend>     \str_if_eq:eeT{\gradbars@heatpalette}{diverging}
%<lib-legend>       {\tl_put_right:Nx\l__gradbars_alt_tl{~Neutral~center:~\gradbars@heatcenter.}}
%<lib-legend>     \tl_if_empty:NF\l__gradbars_legend_title_tl
%<lib-legend>       {\tl_put_left:Nx\l__gradbars_alt_tl{\exp_not:V\l__gradbars_legend_title_tl.~}}
%<lib-legend>     \ifgradbars@valid\__gradbars_backend_draw:nn{heat-legend}{\gradbarsApplyAlt
%<lib-legend>       \leavevmode\tikz[baseline=0pt]
%<lib-legend>        {\str_if_eq:VnTF\l__gradbars_legend_orientation_tl{horizontal}
%<lib-legend>          {\begin{scope}[x=\gradbars@width,y=\gradbars@height]
%<lib-legend>           \int_step_inline:nn{256}
%<lib-legend>             {\gradbarsHeatColor{\fp_eval:n{\gradbars@min+(##1-.5)/256*(\gradbars@max-\gradbars@min)}}
%<lib-legend>              \path[fill=gradbarsHeatCell,draw=none](\fp_eval:n{(##1-1)/256},0)rectangle(\fp_eval:n{##1/256},1);}
%<lib-legend>           \draw[draw=black!65,line~width=.3pt](0,0)rectangle(1,1);
%<lib-legend>           \seq_map_indexed_inline:Nn\l__gradbars_legend_ticks_seq
%<lib-legend>             {\draw(\gradbarsPosition{##2},0)--++(0,-.25);
%<lib-legend>              \node[anchor=north,font=\gradbars@font,inner~sep=2pt,
%<lib-legend>                yshift={-\int_eval:n{5*\seq_item:Nn\l__gradbars_legend_tick_rows_seq{##1}}mm}]
%<lib-legend>                at(\gradbarsPosition{##2},-.25){\gradbarsFormatEndpoint{##2}};}
%<lib-legend>           \node[anchor=south,font=\gradbars@font,text~width=\gradbars@width,align=center]at(.5,1){\l__gradbars_legend_title_tl};
%<lib-legend>           \end{scope}}
%<lib-legend>          {\begin{scope}[x=\gradbars@height,y=\gradbars@width]
%<lib-legend>           \int_step_inline:nn{256}
%<lib-legend>             {\gradbarsHeatColor{\fp_eval:n{\gradbars@min+(##1-.5)/256*(\gradbars@max-\gradbars@min)}}
%<lib-legend>              \path[fill=gradbarsHeatCell,draw=none](0,\fp_eval:n{(##1-1)/256})rectangle(1,\fp_eval:n{##1/256});}
%<lib-legend>           \draw[draw=black!65,line~width=.3pt](0,0)rectangle(1,1);
%<lib-legend>           \seq_map_inline:Nn\l__gradbars_legend_ticks_seq
%<lib-legend>             {\node[anchor=west,font=\gradbars@font]at(1,\gradbarsPosition{##1}){\gradbarsFormatEndpoint{##1}};}
%<lib-legend>           \node[anchor=south,font=\gradbars@font,text~width=\gradbars@width,align=center]at(.5,1){\l__gradbars_legend_title_tl};\end{scope}}
%<lib-legend>         \str_if_eq:VnT\l__gradbars_legend_missing_tl{true}
%<lib-legend>          {\path[fill=\gradbars@heatmissing,draw=black!50](0,-16mm)rectangle(4mm,-13mm);
%<lib-legend>         \node[anchor=west,font=\gradbars@font]at(5mm,-14.5mm){\gradbars@missingtext :~missing};}}
%<lib-legend>     }\fi
%<lib-legend>   \fi\group_end:}
%<lib-legend>\DeclareDocumentCommand\gradreferencelegend{O{} m}
%<lib-legend>  {\group_begin:\gradbarssetup{#1}\gradbars@validtrue
%<lib-legend>   \tl_set:Nn\l__gradbars_alt_tl{Reference~symbols:~#2.}
%<lib-legend>   \__gradbars_backend_draw:nn{reference-legend}{\gradbarsApplyAlt\leavevmode\tikz[baseline=0pt]
%<lib-legend>    {\int_zero:N\l_tmpa_int
%<lib-legend>     \clist_map_inline:nn{#2}
%<lib-legend>       {\seq_set_split:Nnn\l_tmpa_seq{/}{##1}
%<lib-legend>        \int_compare:nNnTF{\seq_count:N\l_tmpa_seq}={2}
%<lib-legend>          {\begin{scope}[yshift=-\int_eval:n{\l_tmpa_int}*5mm]
%<lib-legend>           \str_case_e:nnF{\seq_item:Nn\l_tmpa_seq{1}}
%<lib-legend>             {{target}{\draw[draw=\gradbars@targetcolor,line~width=1pt](3mm,-1.5mm)--(3mm,1.5mm);}
%<lib-legend>              {reference}{\draw[dashed,draw=\gradbars@targetcolor](3mm,-1.5mm)--(3mm,1.5mm);}
%<lib-legend>              {band}{\fill[\gradbars@bandcolor,opacity=\gradbars@bandopacity](0,-1.5mm)rectangle(6mm,1.5mm);}
%<lib-legend>              {error}{\draw[draw=\gradbars@errorcolor](0,0)--(6mm,0)(0,-1mm)--(0,1mm)(6mm,-1mm)--(6mm,1mm);}
%<lib-legend>              {box}{\draw(0,0)--(6mm,0)(1.5mm,-1mm)rectangle(4.5mm,1mm)(3mm,-1mm)--(3mm,1mm);}}
%<lib-legend>             {\gradbarsFail{Unknown~reference~legend~symbol}}
%<lib-legend>           \node[anchor=west,font=\gradbars@font]at(8mm,0){\seq_item:Nn\l_tmpa_seq{2}};\end{scope}
%<lib-legend>           \int_incr:N\l_tmpa_int}
%<lib-legend>          {\gradbarsFail{Reference~legend~requires~type/description}}}}
%<lib-legend>   }\group_end:}
%<lib-legend>\ExplSyntaxOff
%<lib-legend>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-lib-reports.sty}}
%    \begin{macrocode}
%<lib-reports>% Author: SuFan; MIT License. Opt-in domain recipes, not statistical inference.
%<lib-reports>\ProvidesPackage{gradbars-lib-reports}[2026/10/25 v1.1.0 Domain report presets]
%<lib-reports>\gradbarsstyle{report-correlation}{min=-1,max=1,heat palette=purple-teal,
%<lib-reports> heat center=0,precision=2,width=14mm,height=3ex,overflow=error,value format=value}
%<lib-reports>\gradbarsstyle{report-ablation}{min=0,max=100,width=40mm,height=3ex,
%<lib-reports> compare label=delta,precision=2,compare color=gradbarsCudOrange,color=gradbarsCudBlue}
%<lib-reports>\gradbarsstyle{report-metric}{min=0,max=100,width=35mm,height=3ex,
%<lib-reports> precision=2,theme=accessible,label=inside,label align=cell}
%<lib-reports>\gradtablestyle{correlation}{style=matrix,rules=booktabs,graphic width=14mm,
%<lib-reports> min graphic width=8mm,column sep=4pt,row padding=2pt,theme=none}
%<lib-reports>\gradtablestyle{ablation}{style=academic,graphic width=40mm,
%<lib-reports> row stretch=1.4,row padding=2pt,theme=teal}
%<lib-reports>\gradtablestyle{metrics}{style=research,graphic width=35mm,
%<lib-reports> row stretch=1.4,row padding=2pt,theme=accessible}
%<lib-reports>\DeclareDocumentCommand\gradcorrelation{O{} m}
%<lib-reports> {\gradheat[style=report-correlation,#1,min=-1,max=1,scale group={},overflow=error]{#2}}
%<lib-reports>\DeclareDocumentCommand\gradablation{O{} m m}
%<lib-reports> {\graddumbbell[style=report-ablation,#1]{#2}{#3}}
%<lib-reports>\DeclareDocumentCommand\gradmetric{O{} m}
%<lib-reports> {\gradbar[style=report-metric,#1]{#2}}
%<lib-reports>\DeclareDocumentCommand\gradcorrelationcolumn{O{} m m}
%<lib-reports> {\gradcolumn[type=heat,scale=fixed,
%<lib-reports>   options={style=report-correlation},#1]{#2}{#3}}
%<lib-reports>\DeclareDocumentCommand\gradablationcolumn{O{} m m}
%<lib-reports> {\gradcolumn[type=dumbbell,
%<lib-reports>   options={style=report-ablation},#1]{#2}{#3}}
%<lib-reports>\DeclareDocumentCommand\gradmetriccolumn{O{} m m}
%<lib-reports> {\gradcolumn[type=bar,scale=column,include zero=true,mark=both,
%<lib-reports>   options={style=report-metric},#1]{#2}{#3}}
%<lib-reports>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-lib-spark.sty}}
%    \begin{macrocode}
%<lib-spark>% Author: SuFan; MIT License. Internal implementation unless documented.
%<lib-spark>\ProvidesPackage{gradbars-lib-spark}[2026/10/25 v1.1.0 gradbars lib-spark]
%<lib-spark>\ExplSyntaxOn
%<lib-spark>\seq_new:N \l__gradbars_series_seq
%<lib-spark>\seq_new:N \l__gradbars_series_clean_seq
%<lib-spark>\fp_new:N \l__gradbars_series_min_fp
%<lib-spark>\fp_new:N \l__gradbars_series_max_fp
%<lib-spark>\fp_new:N \l__gradbars_series_low_fp
%<lib-spark>\fp_new:N \l__gradbars_series_high_fp
%<lib-spark>\bool_new:N \l__gradbars_series_any_bool
%<lib-spark>\bool_new:N \l__gradbars_series_prev_bool
%<lib-spark>\bool_new:N \l__gradbars_series_mark_bool
%<lib-spark>\int_new:N \l__gradbars_series_index_int
%<lib-spark>\cs_new_protected:Npn \gradbarsParseSpark #1
%<lib-spark>  {
%<lib-spark>    \fp_zero:N \l__gradbars_series_min_fp
%<lib-spark>    \fp_zero:N \l__gradbars_series_max_fp
%<lib-spark>    \seq_set_split:Nnn \l__gradbars_series_seq {,}{#1}
%<lib-spark>    \seq_clear:N \l__gradbars_series_clean_seq
%<lib-spark>    \bool_set_false:N \l__gradbars_series_any_bool
%<lib-spark>    \seq_map_inline:Nn \l__gradbars_series_seq
%<lib-spark>      {\tl_set:Nx \l_tmpa_tl {##1}\tl_trim_spaces:N \l_tmpa_tl
%<lib-spark>       \tl_if_empty:NT \l_tmpa_tl {\tl_set:Nn \l_tmpa_tl {NA}}
%<lib-spark>       \str_if_eq:VnF \l_tmpa_tl {NA}
%<lib-spark>         {\gradbarsCheckNumber{\l_tmpa_tl}{spark~observation}
%<lib-spark>          \ifgradbars@valid
%<lib-spark>            \bool_if:NTF \l__gradbars_series_any_bool
%<lib-spark>              {\fp_set:Nn \l__gradbars_series_min_fp {min(\l__gradbars_series_min_fp,\l_tmpa_tl)}
%<lib-spark>               \fp_set:Nn \l__gradbars_series_max_fp {max(\l__gradbars_series_max_fp,\l_tmpa_tl)}}
%<lib-spark>              {\fp_set:Nn \l__gradbars_series_min_fp {\l_tmpa_tl}
%<lib-spark>               \fp_set:Nn \l__gradbars_series_max_fp {\l_tmpa_tl}
%<lib-spark>               \bool_set_true:N \l__gradbars_series_any_bool}
%<lib-spark>          \fi}
%<lib-spark>       \seq_put_right:NV \l__gradbars_series_clean_seq \l_tmpa_tl}
%<lib-spark>    \seq_set_eq:NN \l__gradbars_series_seq \l__gradbars_series_clean_seq
%<lib-spark>    \cs_set:Npx \gradbars@sparklast {\seq_item:Nn \l__gradbars_series_seq {-1}}
%<lib-spark>  }
%<lib-spark>\DeclareDocumentCommand\gradspark{O{} m}
%<lib-spark>  {\group_begin:\gradbars@validtrue\gradbarsParseSpark{#2}
%<lib-spark>   \ifgradbars@valid
%<lib-spark>     \gradbars@sparktrue
%<lib-spark>     \gradbar[height=4ex,#1,shape=sparkline]{\gradbars@sparklast}
%<lib-spark>   \fi\group_end:}
%<lib-spark>\cs_new_protected:Npn \gradbarsValidateSpark
%<lib-spark>  {
%<lib-spark>    \str_if_eq:eeTF {\gradbars@sparktype}{winloss}
%<lib-spark>      {\fp_set:Nn\l__gradbars_series_low_fp{-1}\fp_set:Nn\l__gradbars_series_high_fp{1}}
%<lib-spark>      {\str_if_eq:eeTF {\gradbars@sparkrange}{fixed}
%<lib-spark>      {\fp_set:Nn \l__gradbars_series_low_fp {\gradbars@min}
%<lib-spark>       \fp_set:Nn \l__gradbars_series_high_fp {\gradbars@max}
%<lib-spark>       \seq_map_inline:Nn \l__gradbars_series_seq
%<lib-spark>         {\str_if_eq:nnF {##1}{NA}{\gradbarsRange{Spark~observation}{##1}}}}
%<lib-spark>      {\fp_set_eq:NN \l__gradbars_series_low_fp \l__gradbars_series_min_fp
%<lib-spark>       \fp_set_eq:NN \l__gradbars_series_high_fp \l__gradbars_series_max_fp
%<lib-spark>       \str_if_eq:eeT{\gradbars@sparktype}{bar}
%<lib-spark>         {\fp_set:Nn\l__gradbars_series_low_fp{min(0,\l__gradbars_series_min_fp)}
%<lib-spark>          \fp_set:Nn\l__gradbars_series_high_fp{max(0,\l__gradbars_series_max_fp)}
%<lib-spark>          \fp_compare:nNnT{\l__gradbars_series_low_fp}={\l__gradbars_series_high_fp}
%<lib-spark>            {\fp_set:Nn\l__gradbars_series_high_fp{1}}}}}
%<lib-spark>    \str_if_eq:eeF{\gradbars@sparktype}{line}
%<lib-spark>      {\gradbarsCheckNumber{\gradbars@sparkbarwidth}{spark~bar~width}
%<lib-spark>       \ifgradbars@valid\fp_compare:nF{0<\gradbars@sparkbarwidth<=1}
%<lib-spark>         {\gradbarsFail{Spark~bar~width~must~be~in~(0,1]}}\fi}
%<lib-spark>  }
%<lib-spark>\cs_new_protected:Npn \gradbarsDrawSpark
%<lib-spark>  {
%<lib-spark>    \gradbarsMarkerBounds
%<lib-spark>    \bool_set_false:N \l__gradbars_series_prev_bool
%<lib-spark>    \int_zero:N \l__gradbars_series_index_int
%<lib-spark>    \seq_map_inline:Nn \l__gradbars_series_seq
%<lib-spark>      {\int_incr:N \l__gradbars_series_index_int
%<lib-spark>       \str_if_eq:nnTF {##1}{NA}
%<lib-spark>         {\bool_set_false:N \l__gradbars_series_prev_bool}
%<lib-spark>         {\pgfmathsetlengthmacro\gradbars@sparkx
%<lib-spark>            {\fp_eval:n {\seq_count:N \l__gradbars_series_seq=1 ? .5 :
%<lib-spark>              (\l__gradbars_series_index_int-1)/max(1,\seq_count:N \l__gradbars_series_seq-1)}*\gradbars@width}
%<lib-spark>          \fp_compare:nNnTF {\l__gradbars_series_low_fp} = {\l__gradbars_series_high_fp}
%<lib-spark>            {\pgfmathsetlengthmacro\gradbars@sparky{.5*\gradbars@height}}
%<lib-spark>            {\pgfmathsetlengthmacro\gradbars@sparky
%<lib-spark>              {\fp_eval:n {max(0,min(1,(##1-\l__gradbars_series_low_fp)/
%<lib-spark>                (\l__gradbars_series_high_fp-\l__gradbars_series_low_fp)))}*\gradbars@height}}
%<lib-spark>          \bool_if:NT \l__gradbars_series_prev_bool
%<lib-spark>            {\draw[draw=\gradbars@left,line~width=\gradbars@stemwidth]
%<lib-spark>              (\gradbars@sparkprevx,\gradbars@sparkprevy)--(\gradbars@sparkx,\gradbars@sparky);}
%<lib-spark>          \bool_set_false:N \l__gradbars_series_mark_bool
%<lib-spark>          \let\gradbars@pointcolor\gradbars@left
%<lib-spark>          \str_case_e:nn {\gradbars@sparkpoints}
%<lib-spark>            {{all}{\bool_set_true:N \l__gradbars_series_mark_bool}
%<lib-spark>             {extrema}{\fp_compare:nNnT {##1} = {\l__gradbars_series_min_fp}
%<lib-spark>                {\bool_set_true:N \l__gradbars_series_mark_bool\let\gradbars@pointcolor\gradbars@sparklow}
%<lib-spark>               \fp_compare:nNnT {##1} = {\l__gradbars_series_max_fp}
%<lib-spark>                {\bool_set_true:N \l__gradbars_series_mark_bool\let\gradbars@pointcolor\gradbars@sparkhigh}}}
%<lib-spark>          \str_if_eq:eeF {\gradbars@sparkpoints}{none}
%<lib-spark>            {\int_compare:nNnT {\l__gradbars_series_index_int} = {\seq_count:N \l__gradbars_series_seq}
%<lib-spark>               {\bool_set_true:N \l__gradbars_series_mark_bool}}
%<lib-spark>          \bool_if:NT \l__gradbars_series_mark_bool
%<lib-spark>            {\gradbarsDrawMarker{\gradbars@sparkx}{\gradbars@sparky}
%<lib-spark>               {\gradbars@pointcolor}{\gradbars@markerfill}}
%<lib-spark>          \let\gradbars@sparkprevx\gradbars@sparkx\let\gradbars@sparkprevy\gradbars@sparky
%<lib-spark>          \bool_set_true:N \l__gradbars_series_prev_bool}}
%<lib-spark>  }
%<lib-spark>
%<lib-spark>\ExplSyntaxOff
%<lib-spark>\ExplSyntaxOn
%<lib-spark>\cs_new_eq:NN\gradbarsDrawSparkLine\gradbarsDrawSpark
%<lib-spark>\cs_set_protected:Npn\gradbarsDrawSpark
%<lib-spark>  {\str_if_eq:eeTF{\gradbars@sparktype}{line}{\gradbarsDrawSparkLine}{\gradbarsDrawSparkBars}}
%<lib-spark>\cs_new_protected:Npn\gradbarsDrawSparkBars
%<lib-spark>  {\int_zero:N\l__gradbars_series_index_int
%<lib-spark>   \pgfmathsetlengthmacro\gradbars@sparkhalf
%<lib-spark>     {\gradbars@sparkbarwidth/(2*\seq_count:N\l__gradbars_series_seq)*\gradbars@width}
%<lib-spark>   \pgfmathsetlengthmacro\gradbars@sparkbase
%<lib-spark>     {\fp_eval:n{max(0,min(1,-\l__gradbars_series_low_fp/
%<lib-spark>       (\l__gradbars_series_high_fp-\l__gradbars_series_low_fp)))}*\gradbars@height}
%<lib-spark>   \draw[draw=\gradbars@sparkzerocolor,line~width=.3pt]
%<lib-spark>     (0,\gradbars@sparkbase)--(\gradbars@width,\gradbars@sparkbase);
%<lib-spark>   \seq_map_inline:Nn\l__gradbars_series_seq
%<lib-spark>     {\int_incr:N\l__gradbars_series_index_int
%<lib-spark>      \str_if_eq:nnF{##1}{NA}
%<lib-spark>        {\pgfmathsetlengthmacro\gradbars@sparkx
%<lib-spark>           {(\l__gradbars_series_index_int-.5)/\seq_count:N\l__gradbars_series_seq*\gradbars@width}
%<lib-spark>         \str_if_eq:eeTF{\gradbars@sparktype}{winloss}
%<lib-spark>           {\pgfmathsetlengthmacro\gradbars@sparky{\fp_eval:n{(sign(##1)+1)/2}*\gradbars@height}
%<lib-spark>            \let\gradbars@sparkfill\gradbars@sparkwincolor
%<lib-spark>            \fp_compare:nNnT{##1}<{0}{\let\gradbars@sparkfill\gradbars@sparklosscolor}}
%<lib-spark>           {\pgfmathsetlengthmacro\gradbars@sparky
%<lib-spark>              {\fp_eval:n{max(0,min(1,(##1-\l__gradbars_series_low_fp)/
%<lib-spark>                (\l__gradbars_series_high_fp-\l__gradbars_series_low_fp)))}*\gradbars@height}
%<lib-spark>            \let\gradbars@sparkfill\gradbars@left
%<lib-spark>            \fp_compare:nNnT{##1}<{0}{\let\gradbars@sparkfill\gradbars@negativecolor}}
%<lib-spark>         \ifgradbars@print\def\gradbars@sparkfill{black!65}
%<lib-spark>           \fp_compare:nNnT{##1}<{0}{\def\gradbars@sparkfill{black!35}}\fi
%<lib-spark>         \dim_compare:nNnTF{\gradbars@sparky}={\gradbars@sparkbase}
%<lib-spark>           {\draw[draw=\gradbars@sparkzerocolor,line~width=.8pt]
%<lib-spark>              ([xshift=-\gradbars@sparkhalf]\gradbars@sparkx,\gradbars@sparkbase)--
%<lib-spark>              ([xshift=\gradbars@sparkhalf]\gradbars@sparkx,\gradbars@sparkbase);}
%<lib-spark>           {\path[fill=\gradbars@sparkfill,draw=none]
%<lib-spark>              ([xshift=-\gradbars@sparkhalf]\gradbars@sparkx,\gradbars@sparkbase) rectangle
%<lib-spark>              ([xshift=\gradbars@sparkhalf]\gradbars@sparkx,\gradbars@sparky);}}}}
%<lib-spark>
%<lib-spark>\ExplSyntaxOff
%<lib-spark>
%<lib-spark>\ExplSyntaxOff
%<lib-spark>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-lib-stack.sty}}
%    \begin{macrocode}
%<lib-stack>% Author: SuFan; MIT License. Internal implementation unless documented.
%<lib-stack>\ProvidesPackage{gradbars-lib-stack}[2026/10/25 v1.1.0 gradbars lib-stack]
%<lib-stack>\ExplSyntaxOn
%<lib-stack>\cs_new_protected:Npn \gradbarsParseStack #1
%<lib-stack>  {
%<lib-stack>    \tl_set:Nx \l_tmpa_tl {#1}
%<lib-stack>    % Empty elements are invalid, not silently dropped by clist normalization.
%<lib-stack>    \regex_match:nVTF {\A\s*\Z|\A\s*,|,\s*,|,\s*\Z} \l_tmpa_tl
%<lib-stack>      {\gradbarsFail{Stack~requires~a~nonempty~list~of~numbers}} { }
%<lib-stack>    \clist_set:Nx \l__gradbars_stack_clist {#1}
%<lib-stack>    \fp_zero:N \l__gradbars_sum_fp
%<lib-stack>    \fp_zero:N \l__gradbars_positive_fp
%<lib-stack>    \fp_zero:N \l__gradbars_negative_fp
%<lib-stack>    \clist_map_inline:Nn \l__gradbars_stack_clist
%<lib-stack>      {
%<lib-stack>        \gradbarsCheckNumber{##1}{stack~segment}
%<lib-stack>        \ifgradbars@valid
%<lib-stack>          \fp_add:Nn \l__gradbars_sum_fp {##1}
%<lib-stack>          \fp_compare:nNnTF {##1} < {0}
%<lib-stack>            {\fp_add:Nn \l__gradbars_negative_fp {##1}}
%<lib-stack>            {\fp_add:Nn \l__gradbars_positive_fp {##1}}
%<lib-stack>        \fi
%<lib-stack>      }
%<lib-stack>    \cs_set:Npx \gradbars@total {\fp_to_decimal:N \l__gradbars_sum_fp}
%<lib-stack>    \cs_set:Npx \gradbars@positive {\fp_to_decimal:N \l__gradbars_positive_fp}
%<lib-stack>    \cs_set:Npx \gradbars@negative {\fp_to_decimal:N \l__gradbars_negative_fp}
%<lib-stack>    \cs_set:Npx \gradbars@gross {\fp_eval:n {\gradbars@positive-\gradbars@negative}}
%<lib-stack>  }
%<lib-stack>\ExplSyntaxOff
%<lib-stack>\ExplSyntaxOn
%<lib-stack>\cs_new_protected:Npn \gradbarsDrawStack
%<lib-stack>  {
%<lib-stack>    \gradbarsStackReset
%<lib-stack>    \int_zero:N \l_tmpa_int
%<lib-stack>    \clist_map_inline:Nn \l__gradbars_stack_clist
%<lib-stack>      {
%<lib-stack>        \gradbarsStackStep{##1}
%<lib-stack>        \int_incr:N \l_tmpa_int
%<lib-stack>        \gradbarsCategoryColor{\l_tmpa_int}
%<lib-stack>        \pgfmathsetlengthmacro\gradbars@segmentlo
%<lib-stack>          {\gradbarsPosition{\l__gradbars_before_fp}*(\gradbars@width)}
%<lib-stack>        \pgfmathsetlengthmacro\gradbars@segmenthi
%<lib-stack>          {\gradbarsPosition{\l__gradbars_sum_fp}*(\gradbars@width)}
%<lib-stack>        \ifdim\gradbars@segmenthi>\gradbars@segmentlo\relax
%<lib-stack>          \ifgradbars@outline
%<lib-stack>            \draw[draw=\gradbars@segmentcolor,line~width=\gradbars@outlinewidth]
%<lib-stack>              (\gradbars@segmentlo,0) rectangle (\gradbars@segmenthi,\gradbars@height);
%<lib-stack>          \else
%<lib-stack>            \path[fill=\gradbars@segmentcolor,draw=none]
%<lib-stack>              (\gradbars@segmentlo,0) rectangle (\gradbars@segmenthi,\gradbars@height);
%<lib-stack>            \gradbarsPatternRect{\l_tmpa_int}{\gradbars@segmentlo}{0}{\gradbars@segmenthi}{\gradbars@height}
%<lib-stack>          \fi
%<lib-stack>        \fi
%<lib-stack>      }
%<lib-stack>  }
%<lib-stack>\ExplSyntaxOff
%<lib-stack>\ExplSyntaxOff
%<lib-stack>\DeclareDocumentCommand\gradstack{O{} m}{%
%<lib-stack>  \leavevmode\begingroup
%<lib-stack>    \gradbars@validtrue
%<lib-stack>    \gradbarsParseStack{#2}%
%<lib-stack>    \ifgradbars@valid
%<lib-stack>      \gradbars@stacktrue
%<lib-stack>      \gradbar[#1]{\gradbars@total}%
%<lib-stack>    \fi
%<lib-stack>  \endgroup
%<lib-stack>}
%<lib-stack>\ExplSyntaxOff
%<lib-stack>\ExplSyntaxOn
%<lib-stack>\fp_new:N \l__gradbars_positive_fp
%<lib-stack>\fp_new:N \l__gradbars_negative_fp
%<lib-stack>\cs_new_protected:Npn \gradbarsStackReset
%<lib-stack>  {\fp_zero:N \l__gradbars_positive_fp\fp_zero:N \l__gradbars_negative_fp}
%<lib-stack>\cs_new_protected:Npn \gradbarsStackStep #1
%<lib-stack>  {
%<lib-stack>    \fp_compare:nNnTF {#1} < {0}
%<lib-stack>      {\fp_set_eq:NN \l__gradbars_sum_fp \l__gradbars_negative_fp
%<lib-stack>       \fp_add:Nn \l__gradbars_negative_fp {#1}
%<lib-stack>       \fp_set_eq:NN \l__gradbars_before_fp \l__gradbars_negative_fp}
%<lib-stack>      {\fp_set_eq:NN \l__gradbars_before_fp \l__gradbars_positive_fp
%<lib-stack>       \fp_add:Nn \l__gradbars_positive_fp {#1}
%<lib-stack>       \fp_set_eq:NN \l__gradbars_sum_fp \l__gradbars_positive_fp}
%<lib-stack>  }
%<lib-stack>
%<lib-stack>\ExplSyntaxOff
%<lib-stack>
%<lib-stack>\ExplSyntaxOff
%<lib-stack>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-lib-table.sty}}
%    \begin{macrocode}
%<lib-table>% Author: SuFan; MIT License. Internal implementation unless documented.
%<lib-table>\ProvidesPackage{gradbars-lib-table}[2026/10/25 v1.1.0 gradbars lib-table]
%<lib-table>\RequirePackage{booktabs}
%<lib-table>\RequirePackage{colortbl}
%<lib-table>\RequirePackage{longtable}
%<lib-table>\ExplSyntaxOff
%<lib-table>% gradtable buffers declarations and rows; no alignment tokens in user data.
%<lib-table>\ExplSyntaxOn
%<lib-table>\seq_new:N \l__gradtable_columns_seq
%<lib-table>\seq_new:N \l__gradtable_rows_seq
%<lib-table>\prop_new:N \l__gradtable_titles_prop
%<lib-table>\prop_new:N \l__gradtable_types_prop
%<lib-table>\prop_new:N \l__gradtable_options_prop
%<lib-table>\prop_new:N \l__gradtable_widths_prop
%<lib-table>\prop_new:N \l__gradtable_align_prop
%<lib-table>\prop_new:N \l__gradtable_headalign_prop
%<lib-table>\prop_new:N \l__gradtable_valign_prop
%<lib-table>\prop_new:N \l__gradtable_colwidth_prop
%<lib-table>\tl_new:N \l__gradtable_align_tl
%<lib-table>\tl_new:N \l__gradtable_headalign_tl
%<lib-table>\tl_new:N \l__gradtable_valign_tl
%<lib-table>\tl_new:N \l__gradtable_default_align_tl
%<lib-table>\tl_new:N \l__gradtable_default_headalign_tl
%<lib-table>\tl_new:N \l__gradtable_default_valign_tl
%<lib-table>\tl_new:N \l__gradtable_rules_tl
%<lib-table>\tl_new:N \l__gradtable_stretch_tl
%<lib-table>\tl_new:N \l__gradtable_header_spec_tl
%<lib-table>\tl_new:N \l__gradtable_header_color_tl
%<lib-table>\tl_new:N \l__gradtable_rule_color_tl
%<lib-table>\dim_new:N \l__gradtable_colwidth_dim
%<lib-table>\dim_new:N \l__gradtable_sep_dim
%<lib-table>\dim_new:N \l__gradtable_padding_dim
%<lib-table>\tl_new:N \l__gradtable_preset_tl
%<lib-table>\tl_new:N \l__gradtable_type_tl
%<lib-table>\tl_new:N \l__gradtable_options_tl
%<lib-table>\tl_new:N \l__gradtable_id_tl
%<lib-table>\tl_new:N \l__gradtable_preamble_tl
%<lib-table>\tl_new:N \l__gradtable_body_tl
%<lib-table>\clist_new:N \l__gradtable_cells_clist
%<lib-table>\seq_new:N \l__gradtable_interval_seq
%<lib-table>\dim_new:N \l__gradtable_graphic_dim
%<lib-table>\dim_new:N \l__gradtable_text_dim
%<lib-table>\dim_new:N \l__gradtable_label_dim
%<lib-table>\dim_new:N \g__gradtable_measured_dim
%<lib-table>\box_new:N \l__gradtable_measure_box
%<lib-table>\int_new:N \l__gradtable_row_int
%<lib-table>\int_new:N \l__gradtable_col_int
%<lib-table>\bool_new:N \l__gradtable_valid_bool
%<lib-table>\bool_new:N \l__gradtable_started_bool
%<lib-table>\keys_define:nn {gradbars/table}
%<lib-table>  {preset .choice:,
%<lib-table>   preset / paper .code:n = \tl_set:Nn \l__gradtable_preset_tl {paper},
%<lib-table>   preset / report .code:n = \tl_set:Nn \l__gradtable_preset_tl {report},
%<lib-table>   preset / mono .code:n = \tl_set:Nn \l__gradtable_preset_tl {mono},
%<lib-table>   graphic~width .dim_set:N = \l__gradtable_graphic_dim,
%<lib-table>   label~width .dim_set:N = \l__gradtable_label_dim,
%<lib-table>   text~width .dim_set:N = \l__gradtable_text_dim,
%<lib-table>   align .choices:nn = {auto,l,c,r}{\tl_set_eq:NN\l__gradtable_default_align_tl\l_keys_choice_tl},
%<lib-table>   header~align .choices:nn = {auto,l,c,r}{\tl_set_eq:NN\l__gradtable_default_headalign_tl\l_keys_choice_tl},
%<lib-table>   valign .choices:nn = {t,c,b}{\tl_set_eq:NN\l__gradtable_default_valign_tl\l_keys_choice_tl},
%<lib-table>   rules .choices:nn = {booktabs,rows,grid,none}{\tl_set_eq:NN\l__gradtable_rules_tl\l_keys_choice_tl},
%<lib-table>   row~stretch .tl_set:N = \l__gradtable_stretch_tl,
%<lib-table>   column~sep .dim_set:N = \l__gradtable_sep_dim,
%<lib-table>   row~padding .dim_set:N = \l__gradtable_padding_dim,
%<lib-table>   header~color .tl_set:N = \l__gradtable_header_color_tl,
%<lib-table>   rule~color .tl_set:N = \l__gradtable_rule_color_tl}
%<lib-table>\keys_define:nn {gradbars/table/column}
%<lib-table>  {type .choices:nn = {text,number,bar,bullet,interval,compare,dumbbell,stack,spark,heat,boxplot}
%<lib-table>     {\tl_set_eq:NN \l__gradtable_type_tl \l_keys_choice_tl},
%<lib-table>   options .tl_set:N = \l__gradtable_options_tl,
%<lib-table>   align .choices:nn = {auto,l,c,r}{\tl_set_eq:NN\l__gradtable_align_tl\l_keys_choice_tl},
%<lib-table>   header~align .choices:nn = {auto,l,c,r}{\tl_set_eq:NN\l__gradtable_headalign_tl\l_keys_choice_tl},
%<lib-table>   valign .choices:nn = {t,c,b}{\tl_set_eq:NN\l__gradtable_valign_tl\l_keys_choice_tl},
%<lib-table>   width .dim_set:N = \l__gradtable_colwidth_dim}
%<lib-table>\cs_new_protected:Npn \gradtableError #1
%<lib-table>  {\bool_set_false:N \l__gradtable_valid_bool
%<lib-table>   \PackageError{gradbars}{Table~row~\int_use:N\l__gradtable_row_int,
%<lib-table>      ~column~\tl_use:N\l__gradtable_id_tl :~#1}
%<lib-table>     {Check~column~declarations~and~comma-separated~row~data.}}
%<lib-table>\DeclareDocumentCommand\gradcolumn{O{} m m}
%<lib-table>  {\PackageError{gradbars}{gradcolumn~requires~gradtable}{Place~column~declarations~inside~gradtable.}}
%<lib-table>\DeclareDocumentCommand\gradrow{m}
%<lib-table>  {\PackageError{gradbars}{gradrow~requires~gradtable}{Place~rows~inside~gradtable.}}
%<lib-table>\cs_new_protected:Npn \gradtableColumn #1#2#3
%<lib-table>  {\bool_if:NT \l__gradtable_started_bool {\gradtableError{Declare~columns~before~rows}}
%<lib-table>   \seq_if_empty:NF\l__gradtable_headers_seq{\gradtableError{Declare~columns~before~headers}}
%<lib-table>   \tl_set:Nn \l__gradtable_id_tl {#2}
%<lib-table>   \tl_if_blank:nT {#2}{\gradtableError{Column~identifier~must~not~be~empty}}
%<lib-table>   \prop_if_in:NnT \l__gradtable_types_prop {#2}{\gradtableError{Duplicate~column~identifier}}
%<lib-table>   \tl_set:Nn \l__gradtable_type_tl {text}
%<lib-table>   \tl_clear:N \l__gradtable_options_tl
%<lib-table>   \tl_set_eq:NN\l__gradtable_align_tl\l__gradtable_default_align_tl
%<lib-table>   \tl_set_eq:NN\l__gradtable_headalign_tl\l__gradtable_default_headalign_tl
%<lib-table>   \tl_set_eq:NN\l__gradtable_valign_tl\l__gradtable_default_valign_tl
%<lib-table>   \dim_zero:N\l__gradtable_colwidth_dim
%<lib-table>   \fp_set:Nn\l__gradtable_weight_fp{1}
%<lib-table>   \tl_set:Nn\l__gradtable_mark_tl{none}
%<lib-table>   \tl_set:Nn\l__gradtable_source_tl{#2}
%<lib-table>   \tl_set_eq:NN\l__gradtable_scale_tl\l__gradtable_default_scale_tl
%<lib-table>   \bool_set_eq:NN\l__gradtable_zero_bool\l__gradtable_default_zero_bool
%<lib-table>   \tl_set_eq:NN\l__gradtable_formatter_tl\l__gradtable_default_formatter_tl
%<lib-table>   \tl_set_eq:NN\l__gradtable_number_align_tl\l__gradtable_default_number_align_tl
%<lib-table>   \bool_set_false:N\l__gradtable_number_align_explicit_bool
%<lib-table>   \tl_set:Nn\l__gradtable_aggregate_tl{none}
%<lib-table>   \tl_set_eq:NN\l__gradtable_scale_group_tl\l__gradtable_default_scale_group_tl
%<lib-table>   \fp_set_eq:NN\l__gradtable_scale_padding_fp\l__gradtable_default_scale_padding_fp
%<lib-table>   \bool_set_eq:NN\l__gradtable_scale_nice_bool\l__gradtable_default_scale_nice_bool
%<lib-table>   \keys_set:nn {gradbars/table/column}{#1}
%<lib-table>   \str_if_eq:VnT\l__gradtable_type_tl{boxplot}{\gradbarsiflibraryloaded{distribution}{}{\gradtableError{Load~distribution~library~before~boxplot~columns}}}
%<lib-table>   \gradtableStoreNumericFormat{#2}
%<lib-table>   \dim_compare:nNnT{\l__gradtable_colwidth_dim}<{0pt}{\gradtableError{Column~width~must~be~nonnegative}}
%<lib-table>   \prop_put:Nnx\l__gradtable_fixed_prop{#2}{\dim_use:N\l__gradtable_colwidth_dim}
%<lib-table>   \prop_put:Nnx\l__gradtable_weights_prop{#2}{\fp_use:N\l__gradtable_weight_fp}
%<lib-table>   \str_if_eq:VnT\l__gradtable_align_tl{auto}
%<lib-table>     {\tl_set:Nn\l__gradtable_align_tl{l}
%<lib-table>      \str_if_eq:VnT\l__gradtable_type_tl{number}{\tl_set:Nn\l__gradtable_align_tl{r}}}
%<lib-table>   \str_if_eq:VnT\l__gradtable_headalign_tl{auto}{\tl_set_eq:NN\l__gradtable_headalign_tl\l__gradtable_align_tl}
%<lib-table>   \str_if_eq:VnT\l__gradtable_type_tl{text}
%<lib-table>     {\dim_compare:nNnT{\l__gradtable_colwidth_dim}={0pt}{\dim_set_eq:NN\l__gradtable_colwidth_dim\l__gradtable_text_dim}}
%<lib-table>   \prop_put:NnV\l__gradtable_marks_prop{#2}\l__gradtable_mark_tl
%<lib-table>   \str_if_eq:VnF\l__gradtable_mark_tl{none}
%<lib-table>     {\str_case:VnF\l__gradtable_type_tl{{number}{}{bar}{}{bullet}{}{heat}{}}
%<lib-table>       {\gradtableError{Mark~requires~number,~bar,~bullet~or~heat~column}}}
%<lib-table>   \prop_put:NnV\l__gradtable_sources_prop{#2}\l__gradtable_source_tl
%<lib-table>   \prop_put:NnV\l__gradtable_scales_prop{#2}\l__gradtable_scale_tl
%<lib-table>   \prop_put:NnV\l__gradtable_aggregates_prop{#2}\l__gradtable_aggregate_tl
%<lib-table>   \prop_put:NnV\l__gradtable_scale_groups_prop{#2}\l__gradtable_scale_group_tl
%<lib-table>   \prop_put:Nnx\l__gradtable_scale_padding_prop{#2}{\fp_to_decimal:N\l__gradtable_scale_padding_fp}
%<lib-table>   \prop_put:Nnx\l__gradtable_scale_nice_prop{#2}{\bool_if:NTF\l__gradtable_scale_nice_bool{true}{false}}
%<lib-table>   \str_if_eq:VnF\l__gradtable_aggregate_tl{none}
%<lib-table>     {\str_case:VnF\l__gradtable_type_tl{{number}{}{bar}{}{bullet}{}{heat}{}}
%<lib-table>        {\gradtableError{Aggregate~requires~a~scalar~numeric~column}}}
%<lib-table>   \tl_if_empty:NF\l__gradtable_scale_group_tl
%<lib-table>     {\str_if_eq:VnT\l__gradtable_scale_tl{column}
%<lib-table>        {\gradtableError{Scale~group~requires~scale=fixed}}}
%<lib-table>   \prop_put:Nnx\l__gradtable_zero_prop{#2}{\bool_if:NTF\l__gradtable_zero_bool{true}{false}}
%<lib-table>   \seq_put_right:Nn \l__gradtable_columns_seq {#2}
%<lib-table>   \prop_put:Nnn \l__gradtable_titles_prop {#2}{#3}
%<lib-table>   \prop_put:NnV \l__gradtable_types_prop {#2}\l__gradtable_type_tl
%<lib-table>   \prop_put:NnV \l__gradtable_options_prop {#2}\l__gradtable_options_tl
%<lib-table>   \prop_put:NnV\l__gradtable_align_prop{#2}\l__gradtable_align_tl
%<lib-table>   \prop_put:NnV\l__gradtable_headalign_prop{#2}\l__gradtable_headalign_tl
%<lib-table>   \prop_put:NnV\l__gradtable_valign_prop{#2}\l__gradtable_valign_tl
%<lib-table>   \prop_put:Nnx\l__gradtable_colwidth_prop{#2}{\dim_use:N\l__gradtable_colwidth_dim}
%<lib-table>   \prop_put:Nnx \l__gradtable_widths_prop {#2}{\dim_use:N\l__gradtable_label_dim}}
%<lib-table>\cs_new_protected:Npn \gradtableRow #1
%<lib-table>  {\bool_set_true:N \l__gradtable_started_bool
%<lib-table>   \int_incr:N \l__gradtable_row_int
%<lib-table>   \clist_set:Nn \l__gradtable_cells_clist {#1}
%<lib-table>   \int_compare:nNnTF {\clist_count:N\l__gradtable_cells_clist} = {\seq_count:N\l__gradtable_columns_seq}
%<lib-table>     {\seq_put_right:Nn \l__gradtable_rows_seq {#1}}
%<lib-table>     {\gradtableError{Wrong~number~of~cells;~use~NA~for~missing~data}}}
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>\DeclareDocumentEnvironment{gradtable}{O{} +b}
%<lib-table>  {\group_begin:
%<lib-table>   \prop_clear:N\l__gradtable_fixed_prop
%<lib-table>   \prop_clear:N\l__gradtable_weights_prop
%<lib-table>   \prop_clear:N\l__gradtable_plots_prop
%<lib-table>   \prop_clear:N\l__gradtable_sources_prop
%<lib-table>   \prop_clear:N\l__gradtable_scales_prop
%<lib-table>   \prop_clear:N\l__gradtable_zero_prop
%<lib-table>   \prop_clear:N\l__gradtable_ranges_prop
%<lib-table>   \prop_clear:N\l__gradtable_aggregates_prop
%<lib-table>   \prop_clear:N\l__gradtable_formatters_prop
%<lib-table>   \prop_clear:N\l__gradtable_number_align_prop
%<lib-table>   \prop_clear:N\l__gradtable_decimal_left_prop
%<lib-table>   \prop_clear:N\l__gradtable_decimal_right_prop
%<lib-table>   \prop_clear:N\l__gradtable_scale_groups_prop
%<lib-table>   \prop_clear:N\l__gradtable_scale_padding_prop
%<lib-table>   \prop_clear:N\l__gradtable_scale_nice_prop
%<lib-table>   \prop_clear:N\l__gradtable_percent_bases_prop
%<lib-table>   \bool_set_false:N\l__gradtable_summary_bool
%<lib-table>   \seq_clear:N\l__gradtable_headers_seq
%<lib-table>   \prop_clear:N\l__gradtable_groups_prop
%<lib-table>   \prop_clear:N\l__gradtable_marks_prop
%<lib-table>   \seq_clear:N\l__gradtable_style_stack_seq
%<lib-table>   \seq_clear:N\l__gradtable_schema_stack_seq
%<lib-table>   \cs_set_eq:NN\gradtableSavedRuleColor\CT@arc@
%<lib-table>   \seq_clear:N\l__gradtable_columns_seq\seq_clear:N\l__gradtable_rows_seq
%<lib-table>   \prop_clear:N\l__gradtable_titles_prop\prop_clear:N\l__gradtable_types_prop
%<lib-table>   \prop_clear:N\l__gradtable_options_prop\prop_clear:N\l__gradtable_widths_prop
%<lib-table>   \prop_clear:N\l__gradtable_align_prop\prop_clear:N\l__gradtable_headalign_prop
%<lib-table>   \prop_clear:N\l__gradtable_valign_prop\prop_clear:N\l__gradtable_colwidth_prop
%<lib-table>   \int_zero:N\l__gradtable_row_int\tl_clear:N\l__gradtable_id_tl
%<lib-table>   \bool_set_true:N\l__gradtable_valid_bool\bool_set_false:N\l__gradtable_started_bool
%<lib-table>   \keys_set:nn{gradbars/table}{preset=paper,graphic~width=32mm,text~width=22mm,label~width=18mm,
%<lib-table>      align=auto,header~align=auto,valign=t,rules=booktabs,row~stretch=auto,
%<lib-table>      column~sep=6pt,row~padding=0pt,header~color=auto,rule~color=black,group~color=gradbarsTrack,group~sep=4pt,width=0pt,min~text~width=12mm,min~graphic~width=12mm,
%<lib-table>      long=false,caption={},label={},continued~text={(continued)},data={},scale=fixed,include~zero=true,
%<lib-table>      sort={},sort~keys={},order=ascending,filter={},limit=0,scale~scope=data,
%<lib-table>      group~by={},rank~scope=table,group~summary=false,group~summary~scope=visible,
%<lib-table>      group~summary~label={Summary},group~missing~label={(ungrouped)},
%<lib-table>      scale~group={},scale~padding=0,scale~nice=false,theme=none,font={},
%<lib-table>      summary~color=auto,summary~font={\bfseries\boldmath},
%<lib-table>      formatter=builtin,number~align=none,#1}
%<lib-table>   \str_if_eq:VnT\l__gradtable_stretch_tl{auto}
%<lib-table>     {\tl_set:Nn\l__gradtable_stretch_tl{1.2}
%<lib-table>      \str_if_eq:VnT\l__gradtable_preset_tl{report}{\tl_set:Nn\l__gradtable_stretch_tl{1.5}}}
%<lib-table>   \regex_match:nVTF{\A\d+(\.\d+)?\Z}\l__gradtable_stretch_tl
%<lib-table>     {\fp_compare:nNnF{\l__gradtable_stretch_tl}>{0}{\gradtableError{Row~stretch~must~be~positive}}}
%<lib-table>     {\gradtableError{Row~stretch~must~be~a~positive~decimal}}
%<lib-table>   \dim_compare:nNnT{\l__gradtable_sep_dim}<{0pt}{\gradtableError{Column~sep~must~be~nonnegative}}
%<lib-table>   \dim_compare:nNnT{\l__gradtable_padding_dim}<{0pt}{\gradtableError{Row~padding~must~be~nonnegative}}
%<lib-table>   \bool_set_false:N\l__gradtable_header_auto_bool
%<lib-table>   \str_if_eq:VnT\l__gradtable_header_color_tl{auto}
%<lib-table>     {\bool_set_true:N\l__gradtable_header_auto_bool\tl_clear:N\l__gradtable_header_color_tl
%<lib-table>      \str_if_eq:VnT\l__gradtable_theme_tl{none}
%<lib-table>        {\str_if_eq:VnT\l__gradtable_preset_tl{report}{\tl_set:Nn\l__gradtable_header_color_tl{gradbarsTrack}}}}
%<lib-table>   \gradtableResolveThemeColors
%<lib-table>   \dim_compare:nNnF{\l__gradtable_graphic_dim}>{0pt}{\gradtableError{Graphic~width~must~be~positive}}
%<lib-table>   \dim_compare:nNnF{\l__gradtable_text_dim}>{0pt}{\gradtableError{Text~width~must~be~positive}}
%<lib-table>   \dim_compare:nNnT{\l__gradtable_label_dim}<{0pt}{\gradtableError{Label~width~must~be~nonnegative}}
%<lib-table>   \gradtableValidateLayout
%<lib-table>   \RenewDocumentCommand\gradheader{+m}{\gradtableAddHeader{##1}}
%<lib-table>   \RenewDocumentCommand\gradcolumn{O{} m m}{\gradtableColumn{##1}{##2}{##3}}
%<lib-table>   \RenewDocumentCommand\gradrow{m}{\gradtableRow{##1}}
%<lib-table>   \RenewDocumentCommand\gradgroup{m}{\gradtableGroup{##1}}
%<lib-table>   \RenewDocumentCommand\graduseschema{m}{\gradtableUseSchema{##1}}
%<lib-table>   \RenewDocumentCommand\gradsummary{O{} m}{\gradtableSummaryDeclare{##1}{##2}}
%<lib-table>   #2
%<lib-table>   \tl_if_empty:NF\l__gradtable_data_tl{\gradtableImportCSV}
%<lib-table>   \prop_if_in:NxT\l__gradtable_groups_prop{\int_eval:n{\l__gradtable_row_int+1}}
%<lib-table>     {\gradtableError{Group~requires~at~least~one~data~row}}
%<lib-table>   \seq_if_empty:NT\l__gradtable_columns_seq{\gradtableError{Table~requires~columns}}
%<lib-table>   \gradtableValidateSelection
%<lib-table>   \bool_if:NT\l__gradtable_valid_bool{\gradtableRender}
%<lib-table>   \cs_gset_eq:NN\CT@arc@\gradtableSavedRuleColor
%<lib-table>   \group_end:}{}
%<lib-table>\ExplSyntaxOff
%<lib-table>
%<lib-table>% Reusable table definitions, group headings and column extrema.
%<lib-table>\ExplSyntaxOn
%<lib-table>\prop_new:N\g__gradtable_styles_prop
%<lib-table>\prop_new:N\g__gradtable_schemas_prop
%<lib-table>\prop_new:N\l__gradtable_groups_prop
%<lib-table>\prop_new:N\l__gradtable_marks_prop
%<lib-table>\prop_new:N\l__gradtable_best_prop
%<lib-table>\prop_new:N\l__gradtable_second_prop
%<lib-table>\seq_new:N\l__gradtable_style_stack_seq
%<lib-table>\seq_new:N\l__gradtable_schema_stack_seq
%<lib-table>\seq_new:N\l__gradtable_rank_seq
%<lib-table>\tl_new:N\l__gradtable_mark_tl
%<lib-table>\tl_new:N\l__gradtable_group_color_tl
%<lib-table>\tl_new:N\g__gradtable_rank_direction_tl
%<lib-table>\tl_new:N\l__gradtable_rank_direction_tl
%<lib-table>\tl_new:N\l__gradtable_rank_value_tl
%<lib-table>\dim_new:N\l__gradtable_group_sep_dim
%<lib-table>\int_new:N\l__gradtable_rank_col_int
%<lib-table>\cs_generate_variant:Nn\prop_if_in:NnT{NxT}
%<lib-table>\cs_generate_variant:Nn\prop_get:NnNT{NxNT}
%<lib-table>\keys_define:nn{gradbars/table}
%<lib-table>  {style .code:n=\gradtableUseStyle{#1},
%<lib-table>   group~color .tl_set:N=\l__gradtable_group_color_tl,
%<lib-table>   group~sep .code:n={\dim_set:Nn\l__gradtable_group_sep_dim{#1}
%<lib-table>     \dim_compare:nNnT{\l__gradtable_group_sep_dim}<{0pt}
%<lib-table>       {\gradtableError{Group~sep~must~be~nonnegative}}}}
%<lib-table>\keys_define:nn{gradbars/table/column}
%<lib-table>  {mark .choices:nn={none,best,both}{\tl_set_eq:NN\l__gradtable_mark_tl\l_keys_choice_tl}}
%<lib-table>\DeclareDocumentCommand\gradtablestyle{m m}
%<lib-table>  {\tl_if_blank:nTF{#1}{\PackageError{gradbars}{Empty~table~style~name}{Supply~a~name.}}
%<lib-table>     {\prop_gput:Nnn\g__gradtable_styles_prop{#1}{#2}}}
%<lib-table>\DeclareDocumentCommand\gradtableschema{m +m}
%<lib-table>  {\tl_if_blank:nTF{#1}{\PackageError{gradbars}{Empty~table~schema~name}{Supply~a~name.}}
%<lib-table>     {\prop_gput:Nnn\g__gradtable_schemas_prop{#1}{#2}}}
%<lib-table>\cs_new_protected:Npn\gradtableUseStyle #1
%<lib-table>  {\seq_if_in:NnTF\l__gradtable_style_stack_seq{#1}
%<lib-table>     {\gradtableError{Recursive~table~style~#1}}
%<lib-table>     {\prop_get:NnNTF\g__gradtable_styles_prop{#1}\l_tmpa_tl
%<lib-table>       {\seq_put_right:Nn\l__gradtable_style_stack_seq{#1}
%<lib-table>        \exp_args:NnV\keys_set:nn{gradbars/table}\l_tmpa_tl
%<lib-table>        \seq_pop_right:NN\l__gradtable_style_stack_seq\l_tmpa_tl}
%<lib-table>       {\gradtableError{Unknown~table~style~#1}}}}
%<lib-table>\DeclareDocumentCommand\graduseschema{m}
%<lib-table>  {\PackageError{gradbars}{graduseschema~requires~gradtable}{Use~inside~gradtable.}}
%<lib-table>\cs_new_protected:Npn\gradtableUseSchema #1
%<lib-table>  {\seq_if_in:NnTF\l__gradtable_schema_stack_seq{#1}
%<lib-table>     {\gradtableError{Recursive~table~schema~#1}}
%<lib-table>     {\prop_get:NnNTF\g__gradtable_schemas_prop{#1}\l_tmpa_tl
%<lib-table>       {\seq_put_right:Nn\l__gradtable_schema_stack_seq{#1}
%<lib-table>        \tl_use:N\l_tmpa_tl
%<lib-table>        \seq_pop_right:NN\l__gradtable_schema_stack_seq\l_tmpa_tl}
%<lib-table>       {\gradtableError{Unknown~table~schema~#1}}}}
%<lib-table>\DeclareDocumentCommand\gradgroup{m}
%<lib-table>  {\PackageError{gradbars}{gradgroup~requires~gradtable}{Use~inside~gradtable.}}
%<lib-table>\cs_new_protected:Npn\gradtableGroup #1
%<lib-table>  {\bool_set_true:N\l__gradtable_started_bool
%<lib-table>   \seq_if_empty:NT\l__gradtable_columns_seq{\gradtableError{Declare~columns~before~groups}}
%<lib-table>   \tl_if_blank:nT{#1}{\gradtableError{Group~title~must~not~be~empty}}
%<lib-table>   \prop_if_in:NxT\l__gradtable_groups_prop{\int_eval:n{\l__gradtable_row_int+1}}
%<lib-table>     {\gradtableError{Group~requires~at~least~one~data~row}}
%<lib-table>   \prop_put:Nxn\l__gradtable_groups_prop{\int_eval:n{\l__gradtable_row_int+1}}{#1}}
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>\ExplSyntaxOff
%<lib-table>% v0.0.4: column-spanning headers, constrained widths and long tables.
%<lib-table>\ExplSyntaxOn
%<lib-table>\seq_new:N\l__gradtable_headers_seq
%<lib-table>\tl_new:N\l__gradtable_head_tl
%<lib-table>\tl_new:N\l__gradtable_caption_tl
%<lib-table>\tl_new:N\l__gradtable_label_tl
%<lib-table>\tl_new:N\l__gradtable_continued_tl
%<lib-table>\tl_new:N\l__gradtable_span_id_tl
%<lib-table>\bool_new:N\l__gradtable_long_bool
%<lib-table>\dim_new:N\l__gradtable_total_dim
%<lib-table>\dim_new:N\l__gradtable_min_text_dim
%<lib-table>\dim_new:N\l__gradtable_min_graphic_dim
%<lib-table>\dim_new:N\l__gradtable_remaining_dim
%<lib-table>\dim_new:N\l__gradtable_base_dim
%<lib-table>\dim_new:N\l__gradtable_span_dim
%<lib-table>\dim_new:N\g__gradtable_extent_dim
%<lib-table>\fp_new:N\l__gradtable_weight_fp
%<lib-table>\fp_new:N\l__gradtable_weight_sum_fp
%<lib-table>\prop_new:N\l__gradtable_fixed_prop
%<lib-table>\prop_new:N\l__gradtable_weights_prop
%<lib-table>\prop_new:N\l__gradtable_flex_prop
%<lib-table>\prop_new:N\l__gradtable_plots_prop
%<lib-table>\prop_new:N\l__gradtable_overheads_prop
%<lib-table>\int_new:N\l__gradtable_span_start_int
%<lib-table>\int_new:N\l__gradtable_span_count_int
%<lib-table>\keys_define:nn{gradbars/table}
%<lib-table>  {width .dim_set:N=\l__gradtable_total_dim,
%<lib-table>   min~text~width .dim_set:N=\l__gradtable_min_text_dim,
%<lib-table>   min~graphic~width .dim_set:N=\l__gradtable_min_graphic_dim,
%<lib-table>   long .bool_set:N=\l__gradtable_long_bool,
%<lib-table>   caption .tl_set:N=\l__gradtable_caption_tl,
%<lib-table>   label .tl_set:N=\l__gradtable_label_tl,
%<lib-table>   continued~text .tl_set:N=\l__gradtable_continued_tl}
%<lib-table>\keys_define:nn{gradbars/table/column}
%<lib-table>  {weight .code:n={\regex_match:nnTF{\A\d+(\.\d+)?\Z}{#1}
%<lib-table>     {\fp_set:Nn\l__gradtable_weight_fp{#1}
%<lib-table>      \fp_compare:nNnF{#1}>{0}{\gradtableError{Column~weight~must~be~positive}}}
%<lib-table>     {\gradtableError{Column~weight~must~be~a~positive~decimal}}}}
%<lib-table>
%<lib-table>\DeclareDocumentCommand\gradheader{+m}
%<lib-table>  {\PackageError{gradbars}{gradheader~requires~gradtable}{Declare~headers~inside~gradtable.}}
%<lib-table>\DeclareDocumentCommand\gradspan{m m}
%<lib-table>  {\PackageError{gradbars}{gradspan~requires~gradheader}{Place~spans~inside~gradheader.}}
%<lib-table>\cs_new_protected:Npn\gradtableAddHeader #1
%<lib-table>  {\bool_if:NT\l__gradtable_started_bool{\gradtableError{Declare~headers~before~rows}}
%<lib-table>   \int_zero:N\l__gradtable_span_count_int
%<lib-table>   \cs_set_eq:NN\gradtableSavedSpan\gradspan
%<lib-table>   \RenewDocumentCommand\gradspan{m m}
%<lib-table>     {\regex_match:nnTF{\A[1-9]\d*\Z}{##1}
%<lib-table>       {\int_add:Nn\l__gradtable_span_count_int{##1}}
%<lib-table>       {\gradtableError{Header~span~must~be~a~positive~integer}}}
%<lib-table>   #1
%<lib-table>   \cs_set_eq:NN\gradspan\gradtableSavedSpan
%<lib-table>   \int_compare:nNnF{\l__gradtable_span_count_int}={\seq_count:N\l__gradtable_columns_seq}
%<lib-table>     {\gradtableError{Header~spans~must~cover~all~columns~exactly}}
%<lib-table>   \seq_put_right:Nn\l__gradtable_headers_seq{#1}}
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>\ExplSyntaxOff
%<lib-table>
%<lib-table>
%<lib-table>\ExplSyntaxOff
%<lib-table>\ExplSyntaxOff
%<lib-table>% v0.0.5: native CSV tables, column scales and scalar heat cells.
%<lib-table>\ExplSyntaxOn
%<lib-table>\tl_new:N\l__gradtable_data_tl
%<lib-table>\seq_new:N\l__gradtable_data_rows_seq
%<lib-table>\seq_new:N\l__gradtable_range_rows_seq
%<lib-table>\tl_new:N\l__gradtable_source_tl
%<lib-table>\tl_new:N\l__gradtable_scale_tl
%<lib-table>\tl_new:N\l__gradtable_default_scale_tl
%<lib-table>\bool_new:N\l__gradtable_zero_bool
%<lib-table>\bool_new:N\l__gradtable_default_zero_bool
%<lib-table>\prop_new:N\l__gradtable_sources_prop
%<lib-table>\prop_new:N\l__gradtable_scales_prop
%<lib-table>\prop_new:N\l__gradtable_zero_prop
%<lib-table>\prop_new:N\l__gradtable_ranges_prop
%<lib-table>\tl_new:N\l__gradtable_import_row_tl
%<lib-table>\tl_new:N\l__gradtable_import_source_tl
%<lib-table>\int_new:N\l__gradtable_import_row_int
%<lib-table>\int_new:N\l__gradtable_scale_col_int
%<lib-table>\seq_new:N\l__gradtable_scale_values_seq
%<lib-table>\fp_new:N\l__gradtable_min_fp
%<lib-table>\fp_new:N\l__gradtable_max_fp
%<lib-table>\fp_new:N\l__gradtable_positive_fp
%<lib-table>\fp_new:N\l__gradtable_negative_fp
%<lib-table>\bool_new:N\l__gradtable_seen_bool
%<lib-table>\keys_define:nn{gradbars/table}
%<lib-table>  {data .tl_set:N=\l__gradtable_data_tl,
%<lib-table>   scale .choices:nn={fixed,column}{\tl_set_eq:NN\l__gradtable_default_scale_tl\l_keys_choice_tl},
%<lib-table>   include~zero .bool_set:N=\l__gradtable_default_zero_bool}
%<lib-table>\keys_define:nn{gradbars/table/column}
%<lib-table>  {source .tl_set:N=\l__gradtable_source_tl,
%<lib-table>   scale .choices:nn={fixed,column}{\tl_set_eq:NN\l__gradtable_scale_tl\l_keys_choice_tl},
%<lib-table>   include~zero .bool_set:N=\l__gradtable_zero_bool}
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>\ExplSyntaxOff
%<lib-table>
%<lib-table>\ExplSyntaxOff
%<lib-table>\ExplSyntaxOn
%<lib-table>\tl_new:N\l__gradtable_sort_tl
%<lib-table>\tl_new:N\l__gradtable_order_tl
%<lib-table>\tl_new:N\l__gradtable_filter_tl
%<lib-table>\tl_new:N\l__gradtable_scale_scope_tl
%<lib-table>\int_new:N\l__gradtable_limit_int
%<lib-table>\int_new:N\l__gradtable_sort_col_int
%<lib-table>\int_new:N\l__gradtable_selection_col_int
%<lib-table>\seq_new:N\l__gradtable_selected_seq
%<lib-table>\seq_new:N\l__gradtable_filters_seq
%<lib-table>\seq_new:N\l__gradtable_filter_parts_seq
%<lib-table>\clist_new:N\l__gradtable_selection_cells_clist
%<lib-table>\prop_new:N\l__gradtable_selection_rows_prop
%<lib-table>\prop_new:N\l__gradtable_sort_values_prop
%<lib-table>\prop_new:N\l__gradtable_sort_missing_prop
%<lib-table>\tl_new:N\l__gradtable_selection_value_tl
%<lib-table>\tl_new:N\l__gradtable_selection_type_tl
%<lib-table>\tl_new:N\l__gradtable_filter_id_tl
%<lib-table>\tl_new:N\l__gradtable_filter_op_tl
%<lib-table>\tl_new:N\l__gradtable_filter_target_tl
%<lib-table>\bool_new:N\l__gradtable_selected_bool
%<lib-table>\cs_generate_variant:Nn\clist_map_inline:nn{Vn}
%<lib-table>\cs_generate_variant:Nn\regex_extract_once:nnNTF{nVNTF}
%<lib-table>\keys_define:nn{gradbars/table}
%<lib-table>  {sort .tl_set:N=\l__gradtable_sort_tl,
%<lib-table>   order .choices:nn={ascending,descending}{\tl_set_eq:NN\l__gradtable_order_tl\l_keys_choice_tl},
%<lib-table>   filter .tl_set:N=\l__gradtable_filter_tl,
%<lib-table>   limit .code:n={\regex_match:nnTF{\A\d+\Z}{#1}
%<lib-table>     {\int_set:Nn\l__gradtable_limit_int{#1}}{\gradtableError{Limit~must~be~a~nonnegative~integer}}},
%<lib-table>   scale~scope .choices:nn={data,visible}{\tl_set_eq:NN\l__gradtable_scale_scope_tl\l_keys_choice_tl}}
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>\ExplSyntaxOff
%<lib-table>
%<lib-table>\ExplSyntaxOff
%<lib-table>\ExplSyntaxOn
%<lib-table>\tl_new:N\l__gradtable_aggregate_tl
%<lib-table>\prop_new:N\l__gradtable_aggregates_prop
%<lib-table>\tl_new:N\l__gradtable_scale_group_tl
%<lib-table>\tl_new:N\l__gradtable_default_scale_group_tl
%<lib-table>\prop_new:N\l__gradtable_scale_groups_prop
%<lib-table>\fp_new:N\l__gradtable_scale_padding_fp
%<lib-table>\fp_new:N\l__gradtable_default_scale_padding_fp
%<lib-table>\bool_new:N\l__gradtable_scale_nice_bool
%<lib-table>\bool_new:N\l__gradtable_default_scale_nice_bool
%<lib-table>\prop_new:N\l__gradtable_scale_padding_prop
%<lib-table>\prop_new:N\l__gradtable_scale_nice_prop
%<lib-table>\prop_new:N\l__gradtable_percent_bases_prop
%<lib-table>\fp_new:N\l__gradtable_padding_amount_fp
%<lib-table>\fp_new:N\l__gradtable_nice_step_fp
%<lib-table>\fp_new:N\l__gradtable_nice_power_fp
%<lib-table>\tl_new:N\l__gradtable_theme_tl
%<lib-table>\tl_new:N\l__gradtable_theme_color_tl
%<lib-table>\tl_new:N\l__gradtable_font_tl
%<lib-table>\tl_new:N\l__gradtable_summary_color_tl
%<lib-table>\tl_new:N\l__gradtable_summary_font_tl
%<lib-table>\bool_new:N\l__gradtable_header_auto_bool
%<lib-table>\bool_new:N\l__gradtable_summary_bool
%<lib-table>\tl_new:N\l__gradtable_summary_label_tl
%<lib-table>\tl_new:N\l__gradtable_summary_scope_tl
%<lib-table>\tl_new:N\l__gradtable_summary_label_id_tl
%<lib-table>\prop_new:N\l__gradtable_summary_values_prop
%<lib-table>\seq_new:N\l__gradtable_summary_rows_seq
%<lib-table>\int_new:N\l__gradtable_summary_col_int
%<lib-table>\int_new:N\l__gradtable_summary_count_int
%<lib-table>\fp_new:N\l__gradtable_summary_sum_fp
%<lib-table>\fp_new:N\l__gradtable_summary_min_fp
%<lib-table>\fp_new:N\l__gradtable_summary_max_fp
%<lib-table>\tl_new:N\l__gradtable_summary_value_tl
%<lib-table>\keys_define:nn{gradbars/table}
%<lib-table>  {scale~group .tl_set:N=\l__gradtable_default_scale_group_tl,
%<lib-table>   scale~padding .code:n=\gradtableSetPadding\l__gradtable_default_scale_padding_fp{#1},
%<lib-table>   scale~nice .bool_set:N=\l__gradtable_default_scale_nice_bool,
%<lib-table>   theme .choices:nn={none,blue,teal,violet,orange,forest,mono,accessible}
%<lib-table>     {\tl_set_eq:NN\l__gradtable_theme_tl\l_keys_choice_tl},
%<lib-table>   font .tl_set:N=\l__gradtable_font_tl,
%<lib-table>   summary~color .tl_set:N=\l__gradtable_summary_color_tl,
%<lib-table>   summary~font .tl_set:N=\l__gradtable_summary_font_tl}
%<lib-table>\keys_define:nn{gradbars/table/column}
%<lib-table>  {aggregate .choices:nn={none,count,sum,mean,min,max}
%<lib-table>     {\tl_set_eq:NN\l__gradtable_aggregate_tl\l_keys_choice_tl},
%<lib-table>   scale~group .tl_set:N=\l__gradtable_scale_group_tl,
%<lib-table>   scale~padding .code:n=\gradtableSetPadding\l__gradtable_scale_padding_fp{#1},
%<lib-table>   scale~nice .bool_set:N=\l__gradtable_scale_nice_bool}
%<lib-table>\keys_define:nn{gradbars/table/summary}
%<lib-table>  {scope .choices:nn={visible,data}{\tl_set_eq:NN\l__gradtable_summary_scope_tl\l_keys_choice_tl}}
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>\DeclareDocumentCommand\gradsummary{O{} m}
%<lib-table>  {\PackageError{gradbars}{gradsummary~requires~gradtable}{Place~it~inside~gradtable.}}
%<lib-table>\cs_new_protected:Npn\gradtableSummaryDeclare #1#2
%<lib-table>  {\bool_if:NT\l__gradtable_summary_bool{\gradtableError{Only~one~summary~row~is~supported}}
%<lib-table>   \bool_set_true:N\l__gradtable_summary_bool
%<lib-table>   \tl_set:Nn\l__gradtable_summary_label_tl{#2}
%<lib-table>   \tl_set:Nn\l__gradtable_summary_scope_tl{visible}
%<lib-table>   \keys_set:nn{gradbars/table/summary}{#1}}
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>\gradtablestyle{academic}{preset=paper,rules=booktabs,header~align=c,row~stretch=1.2,column~sep=6pt}
%<lib-table>\gradtablestyle{reference}{preset=paper,rules=booktabs,header~align=c,
%<lib-table>  row~stretch=1.25,column~sep=6pt,number~align=decimal}
%<lib-table>\gradtablestyle{distribution}{preset=paper,rules=booktabs,header~align=c,row~stretch=1.6,column~sep=8pt,row~padding=3pt,graphic~width=45mm}
%<lib-table>\gradtablestyle{accessible}{preset=paper,rules=rows,header~align=c,row~stretch=1.4,column~sep=7pt,row~padding=2pt,theme=accessible}
%<lib-table>\gradtablestyle{matrix}{preset=paper,rules=rows,align=c,header~align=c,
%<lib-table>  row~stretch=1.35,column~sep=6pt,row~padding=1pt}
%<lib-table>\gradtablestyle{compact}{preset=paper,rules=booktabs,header~align=c,row~stretch=1.05,column~sep=4pt,
%<lib-table>  graphic~width=24mm,label~width=12mm,text~width=18mm,font={\small}}
%<lib-table>\gradtablestyle{dashboard}{preset=report,rules=rows,header~align=c,row~stretch=1.5,column~sep=8pt,
%<lib-table>  row~padding=2pt,theme=blue}
%<lib-table>\ExplSyntaxOff
%<lib-table>
%<lib-table>\ExplSyntaxOff
%<lib-table>\ExplSyntaxOff
%<lib-table>% v0.0.7: stable lexicographic selection, automatic groups and group statistics.
%<lib-table>\ExplSyntaxOn
%<lib-table>\tl_new:N\l__gradtable_sort_keys_tl
%<lib-table>\seq_new:N\l__gradtable_sort_keys_seq
%<lib-table>\seq_new:N\l__gradtable_sort_parts_seq
%<lib-table>\tl_new:N\l__gradtable_sort_id_tl
%<lib-table>\tl_new:N\l__gradtable_sort_direction_tl
%<lib-table>\clist_new:N\l__gradtable_sort_left_clist
%<lib-table>\clist_new:N\l__gradtable_sort_right_clist
%<lib-table>\tl_new:N\l__gradtable_sort_left_tl
%<lib-table>\tl_new:N\l__gradtable_sort_right_tl
%<lib-table>\bool_new:N\l__gradtable_sort_left_missing_bool
%<lib-table>\bool_new:N\l__gradtable_sort_right_missing_bool
%<lib-table>\int_new:N\l__gradtable_compare_int
%<lib-table>\tl_new:N\l__gradtable_group_by_tl
%<lib-table>\tl_new:N\l__gradtable_rank_scope_tl
%<lib-table>\bool_new:N\l__gradtable_group_summary_bool
%<lib-table>\tl_new:N\l__gradtable_group_summary_scope_tl
%<lib-table>\tl_new:N\l__gradtable_group_summary_label_tl
%<lib-table>\tl_new:N\l__gradtable_group_missing_label_tl
%<lib-table>\prop_new:N\l__gradtable_group_ids_prop
%<lib-table>\prop_new:N\l__gradtable_group_labels_prop
%<lib-table>\prop_new:N\l__gradtable_row_groups_prop
%<lib-table>\prop_new:N\l__gradtable_group_ends_prop
%<lib-table>\prop_new:N\l__gradtable_group_best_prop
%<lib-table>\prop_new:N\l__gradtable_group_second_prop
%<lib-table>\prop_new:N\l__gradtable_group_summary_values_prop
%<lib-table>\prop_new:N\g__gradtable_group_result_prop
%<lib-table>\prop_new:N\g__gradtable_group_widths_prop
%<lib-table>\int_new:N\l__gradtable_group_count_int
%<lib-table>\int_new:N\l__gradtable_group_col_int
%<lib-table>\int_new:N\l__gradtable_current_group_int
%<lib-table>\tl_new:N\l__gradtable_group_key_tl
%<lib-table>\tl_new:N\l__gradtable_group_id_tl
%<lib-table>\seq_new:N\l__gradtable_group_input_seq
%<lib-table>\cs_generate_variant:Nn\prop_put:Nnn{NVV,NxV}
%<lib-table>\cs_generate_variant:Nn\prop_remove:Nn{Nx}
%<lib-table>\keys_define:nn{gradbars/table}
%<lib-table>  {sort~keys .tl_set:N=\l__gradtable_sort_keys_tl,
%<lib-table>   group~by .tl_set:N=\l__gradtable_group_by_tl,
%<lib-table>   rank~scope .choices:nn={table,group}{\tl_set_eq:NN\l__gradtable_rank_scope_tl\l_keys_choice_tl},
%<lib-table>   group~summary .bool_set:N=\l__gradtable_group_summary_bool,
%<lib-table>   group~summary~scope .choices:nn={visible,data}{\tl_set_eq:NN\l__gradtable_group_summary_scope_tl\l_keys_choice_tl},
%<lib-table>   group~summary~label .tl_set:N=\l__gradtable_group_summary_label_tl,
%<lib-table>   group~missing~label .tl_set:N=\l__gradtable_group_missing_label_tl}
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>\ExplSyntaxOff
%<lib-table>
%<lib-table>
%<lib-table>\ExplSyntaxOff
%<lib-table>\ExplSyntaxOn
%<lib-table>\tl_new:N\l__gradtable_default_formatter_tl
%<lib-table>\tl_new:N\l__gradtable_formatter_tl
%<lib-table>\tl_new:N\l__gradtable_default_number_align_tl
%<lib-table>\tl_new:N\l__gradtable_number_align_tl
%<lib-table>\bool_new:N\l__gradtable_number_align_explicit_bool
%<lib-table>\prop_new:N\l__gradtable_formatters_prop
%<lib-table>\prop_new:N\l__gradtable_number_align_prop
%<lib-table>\prop_new:N\l__gradtable_decimal_left_prop
%<lib-table>\prop_new:N\l__gradtable_decimal_right_prop
%<lib-table>\dim_new:N\g__gradbars_decimal_left_dim
%<lib-table>\dim_new:N\g__gradbars_decimal_right_dim
%<lib-table>\dim_new:N\g__gradbars_decimal_full_dim
%<lib-table>\box_new:N\l__gradbars_decimal_left_box
%<lib-table>\box_new:N\l__gradbars_decimal_right_box
%<lib-table>\tl_new:N\l__gradbars_decimal_integer_tl
%<lib-table>\tl_new:N\l__gradbars_decimal_fraction_tl
%<lib-table>\tl_new:N\l__gradbars_decimal_sign_tl
%<lib-table>\seq_new:N\l__gradbars_decimal_parts_seq
%<lib-table>\fp_new:N\l__gradbars_decimal_value_fp
%<lib-table>\int_new:N\l__gradbars_decimal_exponent_int
%<lib-table>\keys_define:nn{gradbars/table}
%<lib-table>  {formatter .code:n={\gradbarsCheckFormatter{#1}\tl_set:Nn\l__gradtable_default_formatter_tl{#1}},
%<lib-table>   number~align .choices:nn={none,decimal}{\tl_set_eq:NN\l__gradtable_default_number_align_tl\l_keys_choice_tl}}
%<lib-table>\keys_define:nn{gradbars/table/column}
%<lib-table>  {formatter .code:n={\gradbarsCheckFormatter{#1}\tl_set:Nn\l__gradtable_formatter_tl{#1}},
%<lib-table>   number~align .choices:nn={none,decimal}
%<lib-table>     {\tl_set_eq:NN\l__gradtable_number_align_tl\l_keys_choice_tl\bool_set_true:N\l__gradtable_number_align_explicit_bool}}
%<lib-table>\cs_new_protected:Npn\gradtableStoreNumericFormat #1
%<lib-table>  {\str_if_eq:VnF\l__gradtable_type_tl{number}
%<lib-table>     {\bool_if:nT{\l__gradtable_number_align_explicit_bool && \str_if_eq_p:Vn\l__gradtable_number_align_tl{decimal}}
%<lib-table>        {\gradtableError{Decimal~alignment~requires~a~number~column}}
%<lib-table>      \tl_set:Nn\l__gradtable_number_align_tl{none}}
%<lib-table>   \prop_put:NnV\l__gradtable_formatters_prop{#1}\l__gradtable_formatter_tl
%<lib-table>   \prop_put:NnV\l__gradtable_number_align_prop{#1}\l__gradtable_number_align_tl}
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>
%<lib-table>\int_new:N\l__gradtable_decimal_col_int
%<lib-table>
%<lib-table>
%<lib-table>\gradtablestyle{research}{preset=paper,rules=booktabs,header~align=c,row~stretch=1.3,
%<lib-table>  column~sep=5pt,row~padding=1pt,group~sep=5pt,number~align=decimal,
%<lib-table>  summary~font={\bfseries\boldmath}}
%<lib-table>\ExplSyntaxOff
%<lib-table>
%<lib-table>
%<lib-table>\ExplSyntaxOff
%<lib-table>
%<lib-table>\ExplSyntaxOff
%<lib-table>\RequirePackage{gradbars-table-data}
%<lib-table>\RequirePackage{gradbars-table-layout}
%<lib-table>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-model.sty}}
%    \begin{macrocode}
%<model>% Author: SuFan; MIT License. Private validated model and layout preparation.
%<model>\ProvidesPackage{gradbars-model}[2026/10/25 v1.1.0 gradbars model]
%<model>\ExplSyntaxOn
%<model>\prop_new:N \l__gradbars_model_prop
%<model>\fp_new:N\l__gradbars_constant_value_fp
%<model>% Preserve the established +/-0.5 rule; use a bounded relative span only when
%<model>% that increment disappears at the numeric engine's significant-digit limit.
%<model>\cs_new_protected:Npn\__gradbars_constant_range:NN #1#2
%<model>  {\fp_set_eq:NN\l__gradbars_constant_value_fp#1
%<model>   \fp_sub:Nn#1{.5}\fp_add:Nn#2{.5}
%<model>   \fp_compare:nNnF{#2}>{#1}
%<model>     {\fp_set:Nn#1{max(-1e100,\l__gradbars_constant_value_fp-abs(\l__gradbars_constant_value_fp)*.05)}
%<model>      \fp_set:Nn#2{min(1e100,\l__gradbars_constant_value_fp+abs(\l__gradbars_constant_value_fp)*.05)}}}
%<model>
%<model>\cs_new_protected:Npn \__gradbars_prepare_model:
%<model>  {
%<model>    \gradbars@validtrue
%<model>    \gradbarsResolveScaleGroup
%<model>    \gradbarsResolveShapeLengths
%<model>    \gradbarsValidate
%<model>    \gradbarsValidateExtras
%<model>    \dim_compare:nNnT {\gradbars@rounded} < {0pt}
%<model>      {\gradbarsFail{Rounded~radius~must~be~nonnegative}}
%<model>    \dim_compare:nNnF {\gradbars@width} > {0pt}
%<model>      {\gradbarsFail{Width~must~be~positive}}
%<model>    \dim_compare:nNnF {\gradbars@height} > {0pt}
%<model>      {\gradbarsFail{Height~must~be~positive}}
%<model>    \prop_clear:N \l__gradbars_model_prop
%<model>    \ifgradbars@valid
%<model>      \prop_put:Nno \l__gradbars_model_prop {raw-value}{\gradbars@value}
%<model>      \clist_map_inline:nn {min,max,zero,start,stop,end,shape}
%<model>        {\prop_put:Nnx \l__gradbars_model_prop {##1}{\use:c{gradbars@##1}}}
%<model>      \prop_put:Nnn \l__gradbars_model_prop {missing}{false}
%<model>      \ifgradbars@missing
%<model>        \prop_put:Nnn \l__gradbars_model_prop {missing}{true}
%<model>      \fi
%<model>    \fi
%<model>  }
%<model>% Projection runs in the drawing font/coordinate context, preserving em/ex sizes.
%<model>\cs_new_protected:Npn \__gradbars_project_layout:
%<model>  {
%<model>    \pgfmathsetlengthmacro\gradbars@xzero{\gradbars@zero*(\gradbars@width)}
%<model>    \pgfmathsetlengthmacro\gradbars@xend{\gradbars@end*(\gradbars@width)}
%<model>    \pgfmathsetlengthmacro\gradbars@xstart{\gradbars@start*(\gradbars@width)}
%<model>    \pgfmathsetlengthmacro\gradbars@xstop{\gradbars@stop*(\gradbars@width)}
%<model>    \pgfmathsetlengthmacro\gradbars@radius
%<model>      {min(\gradbars@rounded,.5*(\gradbars@height),.5*(\gradbars@width))}
%<model>  }
%<model>\cs_new_protected:Npn \__gradbars_render:
%<model>  {
%<model>    \__gradbars_prepare_model:
%<model>    \ifgradbars@valid \__gradbars_backend_core: \fi
%<model>  }
%<model>\cs_new_eq:NN \gradbarsPrepareLayout \__gradbars_project_layout:
%<model>\cs_new_eq:NN \gradbars@render \__gradbars_render:
%<model>\ExplSyntaxOff
%<model>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-numbers.sty}}
%    \begin{macrocode}
%<numbers>% Author: SuFan; MIT License. Internal implementation unless documented.
%<numbers>\ProvidesPackage{gradbars-numbers}[2026/10/25 v1.1.0 gradbars numbers]
%<numbers>\ExplSyntaxOff
%<numbers>% v0.0.8: bounded scientific input, optional SI formatting and decimal anchors.
%<numbers>\ExplSyntaxOn
%<numbers>\def\gradbars@formatter{builtin}
%<numbers>\def\gradbars@unitcode{}
%<numbers>\def\gradbars@unittext{}
%<numbers>\pgfkeys{/gradbars,
%<numbers>  formatter/.is~choice,
%<numbers>  formatter/builtin/.code=\def\gradbars@formatter{builtin},
%<numbers>  formatter/siunitx/.code=\def\gradbars@formatter{siunitx},
%<numbers>  unit~code/.store~in=\gradbars@unitcode,
%<numbers>  unit~text/.store~in=\gradbars@unittext}
%<numbers>\ExplSyntaxOn
%<numbers>\tl_new:N\l__gradbars_input_tl
%<numbers>\prg_new_protected_conditional:Npnn\gradbarsIfNumber:n #1{T,F,TF}
%<numbers>  {\tl_set:Nx\l__gradbars_input_tl{#1}\tl_trim_spaces:N\l__gradbars_input_tl
%<numbers>   \regex_match:nVTF{\A[+\-]?(\d{1,101}(\.\d{0,101})?|\.\d{1,101})([eE][+\-]?\d{1,3})?\Z}\l__gradbars_input_tl
%<numbers>     {\fp_compare:nNnTF{abs(\l__gradbars_input_tl)}>{1e100}
%<numbers>        {\prg_return_false:}
%<numbers>        {\fp_compare:nNnTF{\l__gradbars_input_tl}={0}{\prg_return_true:}
%<numbers>           {\fp_compare:nNnTF{abs(\l__gradbars_input_tl)}<{1e-100}
%<numbers>              {\prg_return_false:}{\prg_return_true:}}}}
%<numbers>     {\prg_return_false:}}
%<numbers>\prg_generate_conditional_variant:Nnn\gradbarsIfNumber:n{V}{T,F,TF}
%<numbers>\cs_set_protected:Npn\gradbarsCheckNumber #1#2
%<numbers>  {\gradbarsIfNumber:nF{#1}
%<numbers>     {\gradbars@validfalse
%<numbers>      \PackageError{gradbars}{Invalid~#2:~expected~a~decimal~or~scientific~number}
%<numbers>        {Use~86.5~or~1.2e-3.~Nonzero~magnitudes~must~be~between~1e-100~and~1e100;~expressions,~NaN~and~infinity~are~not~accepted.}}}
%<numbers>\cs_new_protected:Npn\gradbarsValidateFormatter
%<numbers>  {\str_if_eq:eeT{\gradbars@formatter}{siunitx}
%<numbers>     {\@ifpackageloaded{siunitx}
%<numbers>        {\cs_if_exist:NF\unit{\gradbarsFail{Formatter~siunitx~requires~siunitx~v3}}}
%<numbers>        {\gradbarsFail{Formatter~siunitx~requires~loading~siunitx~v3~before~use}}}
%<numbers>   \tl_if_empty:oF{\gradbars@unitcode}
%<numbers>     {\str_if_eq:eeF{\gradbars@formatter}{siunitx}{\gradbarsFail{Unit~code~requires~formatter=siunitx}}
%<numbers>      \tl_if_empty:oT{\gradbars@unittext}{\gradbarsFail{Unit~code~requires~readable~unit~text}}
%<numbers>      \tl_if_empty:oF{\gradbars@unit}{\gradbarsFail{Use~unit~or~unit~code,~not~both}}
%<numbers>      \str_if_eq:eeT{\gradbars@format}{percent}{\gradbarsFail{Percent~labels~cannot~use~unit~code}}}}
%<numbers>\cs_new_eq:NN\gradbarsValidateBeforeEight\gradbarsValidate
%<numbers>\cs_set_protected:Npn\gradbarsValidate{\gradbarsValidateFormatter\gradbarsValidateBeforeEight}
%<numbers>\cs_new_protected:Npn\gradbarsNumericSuffix
%<numbers>  {\str_if_eq:eeTF{\gradbars@format}{percent}{\%}
%<numbers>     {\tl_if_empty:oTF{\gradbars@unitcode}{\gradbars@unit}
%<numbers>        {\,\exp_args:No\unit{\gradbars@unitcode}}}}
%<numbers>\cs_new_protected:Npn\gradbarsSIOptions
%<numbers>  {\sisetup{mode=math,reset-math-version=false,propagate-math-font=true,
%<numbers>      output-decimal-marker={.},round-mode=places,round-precision=\gradbars@precision,
%<numbers>      round-pad=true,round-half=up,group-minimum-digits=4,group-separator={\,},exponent-mode=fixed,fixed-exponent=0}
%<numbers>   \str_if_eq:eeT{\gradbars@numberformat}{scientific}{\sisetup{exponent-mode=scientific}}
%<numbers>   \str_if_eq:eeT{\gradbars@numberformat}{grouped}{\sisetup{group-separator={,}}}}
%<numbers>\bool_new:N\l__gradbars_decimal_active_bool
%<numbers>\bool_new:N\l__gradbars_decimal_measure_bool
%<numbers>\cs_new_eq:NN\gradbarsSingleLabelBeforeEight\gradbarsSingleLabel
%<numbers>\cs_set_protected:Npn\gradbarsSingleLabel
%<numbers>  {\gradbarsValidateFormatter
%<numbers>   \bool_if:NTF\l__gradbars_decimal_active_bool
%<numbers>     {\gradbarsDecimalPrint{\gradbars@number}}
%<numbers>     {\str_if_eq:eeTF{\gradbars@formatter}{siunitx}
%<numbers>        {\tl_if_empty:oTF{\gradbars@text}
%<numbers>           {\ifgradbars@missing\gradbars@missingtext\else
%<numbers>            \group_begin:\gradbarsSIOptions\exp_args:No\num{\gradbars@number}\gradbarsNumericSuffix\group_end:\fi}
%<numbers>           {\gradbars@text}}
%<numbers>        {\gradbarsSingleLabelBeforeEight}}}
%<numbers>\cs_new_eq:NN\gradbarsApplyAltBeforeEight\gradbarsApplyAlt
%<numbers>\cs_set_protected:Npn\gradbarsApplyAlt
%<numbers>  {\tl_if_empty:oF{\gradbars@unitcode}
%<numbers>     {\tl_put_right:Nx\l__gradbars_alt_tl{~Unit:~\exp_not:o{\gradbars@unittext}.}}
%<numbers>   \gradbarsApplyAltBeforeEight}
%<numbers>
%<numbers>\ExplSyntaxOff
%<numbers>
%<numbers>\ExplSyntaxOff
%<numbers>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-render-tikz.sty}}
%    \begin{macrocode}
%<render-tikz>% Author: SuFan; MIT License. Internal implementation unless documented.
%<render-tikz>\ProvidesPackage{gradbars-render-tikz}[2026/10/25 v1.1.0 gradbars render-tikz]
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_new_protected:Npn \gradbarsDrawBand
%<render-tikz>  {
%<render-tikz>    \clist_if_empty:NF \l__gradbars_band_clist
%<render-tikz>      {
%<render-tikz>        \pgfmathsetlengthmacro\gradbars@bandxlo{\gradbarsPosition{\gradbars@bandlo}*(\gradbars@width)}
%<render-tikz>        \pgfmathsetlengthmacro\gradbars@bandxhi{\gradbarsPosition{\gradbars@bandhi}*(\gradbars@width)}
%<render-tikz>        \path[fill=\gradbars@bandcolor,fill~opacity=\gradbars@bandopacity,draw=none]
%<render-tikz>          (\gradbars@bandxlo,-2pt) rectangle ([yshift=2pt]\gradbars@bandxhi,\gradbars@height);
%<render-tikz>      }
%<render-tikz>  }
%<render-tikz>
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\def\gradbars@labelcontent{%
%<render-tikz>  \ifx\gradbars@text\@empty
%<render-tikz>    \ifgradbars@missing\gradbars@missingtext\else
%<render-tikz>      \begingroup
%<render-tikz>      \def\gradbars@temp{scientific}%
%<render-tikz>      \ifx\gradbars@numberformat\gradbars@temp
%<render-tikz>        \pgfmathprintnumber[sci,sci zerofill,precision=\gradbars@precision]{\gradbars@number}%
%<render-tikz>      \else
%<render-tikz>        \def\gradbars@temp{grouped}%
%<render-tikz>        \ifx\gradbars@numberformat\gradbars@temp
%<render-tikz>          \pgfmathprintnumber[fixed,fixed zerofill,precision=\gradbars@precision,1000 sep={\mathord{,}}]{\gradbars@number}%
%<render-tikz>        \else
%<render-tikz>          \pgfmathprintnumber[fixed,fixed zerofill,precision=\gradbars@precision,1000 sep={\,}]{\gradbars@number}%
%<render-tikz>        \fi
%<render-tikz>      \fi
%<render-tikz>      \def\gradbars@temp{percent}%
%<render-tikz>      \ifx\gradbars@format\gradbars@temp\%\else\gradbars@unit\fi
%<render-tikz>      \endgroup
%<render-tikz>    \fi
%<render-tikz>  \else\gradbars@text\fi
%<render-tikz>}
%<render-tikz>
%<render-tikz>\def\gradbars@draw{%
%<render-tikz>  \tikzset{gradbars label background/.style={}}%
%<render-tikz>  \ifgradbars@print
%<render-tikz>    \tikzset{gradbars label background/.style={fill=white,inner sep=1pt}}%
%<render-tikz>  \fi
%<render-tikz>  \gradbarsPrepareLayout
%<render-tikz>  \gradbarsDrawTrack
%<render-tikz>  \gradbarsDrawBand
%<render-tikz>  \gradbarsDrawShape
%<render-tikz>  \ifgradbars@spark\else\ifdim\gradbars@xzero>0pt
%<render-tikz>    \draw[gradbarsInk!65,line width=.35pt]
%<render-tikz>      (\gradbars@xzero,0)--(\gradbars@xzero,\gradbars@height);
%<render-tikz>  \fi\fi
%<render-tikz>  \ifx\gradbars@target\@empty\else
%<render-tikz>    \pgfmathsetlengthmacro\gradbars@xtarget{\gradbars@targetpos*(\gradbars@width)}%
%<render-tikz>    \draw[draw=\gradbars@targetcolor,line width=.6pt]
%<render-tikz>      ([yshift=-1pt]\gradbars@xtarget,0)--
%<render-tikz>      ([yshift=1pt]\gradbars@xtarget,\gradbars@height);
%<render-tikz>  \fi
%<render-tikz>  \ifgradbars@missing\else\ifgradbars@error
%<render-tikz>    \pgfmathsetlengthmacro\gradbars@xlo{\gradbars@errorlo*(\gradbars@width)}%
%<render-tikz>    \pgfmathsetlengthmacro\gradbars@xhi{\gradbars@errorhi*(\gradbars@width)}%
%<render-tikz>    \draw[draw=\gradbars@errorcolor,line width=.5pt]
%<render-tikz>      ([yshift=.5*\gradbars@height]\gradbars@xlo,0)--
%<render-tikz>      ([yshift=.5*\gradbars@height]\gradbars@xhi,0);
%<render-tikz>    \foreach \gradbars@cap in {\gradbars@xlo,\gradbars@xhi}{
%<render-tikz>      \draw[draw=\gradbars@errorcolor,line width=.5pt]
%<render-tikz>        ([yshift=.2*\gradbars@height]\gradbars@cap,0)--
%<render-tikz>        ([yshift=.8*\gradbars@height]\gradbars@cap,0);
%<render-tikz>    }
%<render-tikz>  \fi\fi
%<render-tikz>  \gradbarsDrawReferences
%<render-tikz>  \gradbarsDrawOverflow
%<render-tikz>  \gradbarsDrawChange
%<render-tikz>  \gradbarsResetLabels
%<render-tikz>  \ifgradbars@stack
%<render-tikz>    \gradbarsDrawSegmentLabels
%<render-tikz>    \ifgradbars@legend\gradbarsDrawLegend\fi
%<render-tikz>  \fi
%<render-tikz>  \gradbarsDrawMainLabel
%<render-tikz>  \gradbarsResolveBaseline
%<render-tikz>  \coordinate (gradbarsbaseline) at (0,\gradbars@baseliney);
%<render-tikz>  \path[use as bounding box] (0,-\gradbars@rowpadding)
%<render-tikz>    rectangle (\gradbars@width,{\gradbars@height+\gradbars@rowpadding});
%<render-tikz>}
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_new_protected:Npn \__gradbars_render_tikz: {
%<render-tikz>    \ifpgfpicture
%<render-tikz>      \begin{scope}\gradbars@draw\end{scope}%
%<render-tikz>    \else
%<render-tikz>      \gradbarsPrepareAlt
%<render-tikz>      \tikz[baseline=(gradbarsbaseline)]{\gradbars@draw}%
%<render-tikz>    \fi
%<render-tikz>}
%<render-tikz>
%<render-tikz>\ExplSyntaxOff
%<render-tikz>
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_new_protected:Npn \gradbarsContrast #1
%<render-tikz>  {
%<render-tikz>    \convertcolorspec{named}{#1}{rgb}\gradbars@rgb
%<render-tikz>    \clist_set:Nx \l_tmpa_clist {\gradbars@rgb}
%<render-tikz>    \fp_zero:N \l__gradbars_luminance_fp
%<render-tikz>    \int_step_inline:nn {3}
%<render-tikz>      {
%<render-tikz>        \fp_set:Nn \l_tmpa_fp {\clist_item:Nn \l_tmpa_clist {##1}}
%<render-tikz>        \fp_compare:nNnTF {\l_tmpa_fp} > {0.04045}
%<render-tikz>          {\fp_set:Nn \l_tmpa_fp {((\l_tmpa_fp+0.055)/1.055)^2.4}}
%<render-tikz>          {\fp_set:Nn \l_tmpa_fp {\l_tmpa_fp/12.92}}
%<render-tikz>        \fp_add:Nn \l__gradbars_luminance_fp
%<render-tikz>          {\l_tmpa_fp*\clist_item:nn {0.2126,0.7152,0.0722}{##1}}
%<render-tikz>      }
%<render-tikz>    \fp_compare:nNnTF {\l__gradbars_luminance_fp} > {0.179}
%<render-tikz>      {\def\gradbars@labelcolor{black}}{\def\gradbars@labelcolor{white}}
%<render-tikz>  }
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_new_protected:Npn \gradbarsDrawSegmentLabels
%<render-tikz>  {
%<render-tikz>    \str_if_eq:eeF {\gradbars@segmentlabels}{none}
%<render-tikz>      {
%<render-tikz>        \gradbarsStackReset
%<render-tikz>        \int_zero:N \l__gradbars_index_int
%<render-tikz>        \clist_map_inline:Nn \l__gradbars_stack_clist
%<render-tikz>          {
%<render-tikz>            \int_incr:N \l__gradbars_index_int
%<render-tikz>            \gradbarsStackStep{##1}
%<render-tikz>            \pgfmathsetlengthmacro\gradbars@segmentlo{\gradbarsPosition{\l__gradbars_before_fp}*(\gradbars@width)}
%<render-tikz>            \pgfmathsetlengthmacro\gradbars@segmenthi{\gradbarsPosition{\l__gradbars_sum_fp}*(\gradbars@width)}
%<render-tikz>            \ifdim\gradbars@segmenthi>\gradbars@segmentlo\relax
%<render-tikz>              \gradbarsCategoryColor{\l__gradbars_index_int}
%<render-tikz>              \def\gradbars@segmentcontent
%<render-tikz>              {\def\gradbars@text{}\def\gradbars@unit{}\def\gradbars@unitcode{}\def\gradbars@unittext{}\def\gradbars@format{value}
%<render-tikz>                \cs_set:Npx \gradbars@number {\fp_eval:n {##1}}
%<render-tikz>                \str_case_e:nn {\gradbars@segmentlabels}
%<render-tikz>                  {{percent}{\def\gradbars@format{percent}}
%<render-tikz>                   {name~percent}{\def\gradbars@format{percent}}}
%<render-tikz>                \str_if_eq:eeT {\gradbars@format}{percent}
%<render-tikz>                  {\cs_set:Npx \gradbars@number {\fp_eval:n {100*abs(##1)/\gradbars@gross}}}
%<render-tikz>                \tl_clear:N \l_tmpb_tl
%<render-tikz>                \str_case_e:nn {\gradbars@segmentlabels}
%<render-tikz>                  {{name}{\tl_set:Nn \l_tmpb_tl {name}}
%<render-tikz>                   {name~value}{\tl_set:Nn \l_tmpb_tl {both}}
%<render-tikz>                   {name~percent}{\tl_set:Nn \l_tmpb_tl {both}}}
%<render-tikz>                \tl_if_empty:NF \l_tmpb_tl
%<render-tikz>                    {\clist_item:Nn \l__gradbars_names_clist {\l__gradbars_index_int}}
%<render-tikz>                   \str_if_eq:VnT \l_tmpb_tl {both}{:\space}
%<render-tikz>                   \str_if_eq:VnF \l_tmpb_tl {name}{\gradbarsSingleLabel}}
%<render-tikz>              \gradbarsMeasure\gradbars@segmentbox\gradbars@segmentfont{\gradbars@segmentcontent}
%<render-tikz>              \gradbarsPlaceSegment
%<render-tikz>            \fi
%<render-tikz>          }
%<render-tikz>      }
%<render-tikz>  }
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_new_protected:Npn \gradbarsDrawLegend
%<render-tikz>  {
%<render-tikz>    \dim_set:Nn \l_tmpa_dim {6pt}
%<render-tikz>    \int_zero:N \l__gradbars_index_int
%<render-tikz>    \clist_map_inline:Nn \l__gradbars_names_clist
%<render-tikz>      {
%<render-tikz>        \int_incr:N \l__gradbars_index_int
%<render-tikz>        \gradbarsCategoryColor{\l__gradbars_index_int}
%<render-tikz>        \gradbarsMeasure\gradbars@segmentbox\gradbars@font
%<render-tikz>          {\parbox[t]{\dimexpr\gradbars@width-14pt\relax}{\raggedright\strut ##1\strut}}
%<render-tikz>        \ifgradbars@outline
%<render-tikz>          \draw[draw=\gradbars@segmentcolor,line~width=\gradbars@outlinewidth]
%<render-tikz>            (0,-\dim_use:N \l_tmpa_dim) rectangle (8pt,-\dim_eval:n {\l_tmpa_dim+6pt});
%<render-tikz>        \else
%<render-tikz>          \path[fill=\gradbars@segmentcolor,draw=none]
%<render-tikz>            (0,-\dim_use:N \l_tmpa_dim) rectangle (8pt,-\dim_eval:n {\l_tmpa_dim+6pt});
%<render-tikz>          \gradbarsPatternRect{\l__gradbars_index_int}{0}{-\dim_use:N \l_tmpa_dim}
%<render-tikz>            {8pt}{-\dim_eval:n {\l_tmpa_dim+6pt}}
%<render-tikz>        \fi
%<render-tikz>        \node[anchor=north~west,inner~sep=0pt,outer~sep=0pt,text=gradbarsInk]
%<render-tikz>          at (14pt,-\dim_use:N \l_tmpa_dim){\usebox\gradbars@segmentbox};
%<render-tikz>        \dim_add:Nn \l_tmpa_dim {\ht\gradbars@segmentbox+\dp\gradbars@segmentbox+4pt}
%<render-tikz>      }
%<render-tikz>  }
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\dim_new:N \l__gradbars_labelslot_dim
%<render-tikz>\cs_new_protected:Npn \__gradbars_draw_graphic_label:
%<render-tikz>  {
%<render-tikz>    \str_if_eq:eeF {\gradbars@label}{none}
%<render-tikz>      {
%<render-tikz>        \gradbarsMeasure\gradbars@labelbox\gradbars@font{\gradbars@labelcontent}
%<render-tikz>        \let\gradbars@placement\gradbars@label
%<render-tikz>        \gradbars@insidefalse
%<render-tikz>        \str_if_eq:eeT {\gradbars@placement}{auto}
%<render-tikz>          {\def\gradbars@placement{outside}
%<render-tikz>           \ifdim\dimexpr\wd\gradbars@labelbox+4pt\relax<\dimexpr\gradbars@xstop-\gradbars@xstart\relax
%<render-tikz>             \def\gradbars@placement{center}\fi}
%<render-tikz>        \str_if_eq:eeF {\gradbars@labeloverflow}{allow}
%<render-tikz>          {\str_if_eq:eeT {\gradbars@placement}{inside}
%<render-tikz>             {\ifdim\dimexpr\wd\gradbars@labelbox+4pt\relax>\gradbars@width\relax
%<render-tikz>                \def\gradbars@placement{outside}\fi}
%<render-tikz>           \str_if_eq:eeT {\gradbars@placement}{end}
%<render-tikz>             {\ifdim\wd\gradbars@labelbox>\gradbars@width\relax
%<render-tikz>                \def\gradbars@placement{outside}\fi}}
%<render-tikz>        \str_case_e:nn {\gradbars@placement}
%<render-tikz>          {{inside}{\gradbars@insidetrue}{center}{\gradbars@insidetrue}}
%<render-tikz>        \ifgradbars@inside
%<render-tikz>          \str_if_eq:eeF {\gradbars@shape}{bar}
%<render-tikz>            {\def\gradbars@placement{outside}\gradbars@insidefalse}
%<render-tikz>          \ifgradbars@stack
%<render-tikz>            \fp_compare:nNnT {\gradbars@negative} < {0}
%<render-tikz>              {\def\gradbars@placement{outside}\gradbars@insidefalse}
%<render-tikz>          \fi
%<render-tikz>          \ifgradbars@compare \def\gradbars@placement{outside}\gradbars@insidefalse\fi
%<render-tikz>          \ifgradbars@outline \def\gradbars@placement{outside}\gradbars@insidefalse\fi
%<render-tikz>          \ifgradbars@rangemode
%<render-tikz>            \tl_if_empty:oF {\gradbars@rangepoint}
%<render-tikz>              {\def\gradbars@placement{outside}\gradbars@insidefalse}
%<render-tikz>          \fi
%<render-tikz>        \fi
%<render-tikz>        \ifgradbars@inside
%<render-tikz>          \str_if_eq:eeF {\gradbars@labeloverflow}{allow}
%<render-tikz>            {\ifdim\dimexpr\ht\gradbars@labelbox+\dp\gradbars@labelbox+2pt\relax>\gradbars@height\relax
%<render-tikz>               \def\gradbars@placement{outside}\gradbars@insidefalse\fi}
%<render-tikz>          \ifgradbars@stack
%<render-tikz>            \str_if_eq:eeF {\gradbars@segmentlabels}{none}
%<render-tikz>              {\def\gradbars@placement{outside}\gradbars@insidefalse}
%<render-tikz>          \fi
%<render-tikz>          \ifgradbars@error \def\gradbars@placement{outside}\gradbars@insidefalse\fi
%<render-tikz>          \ifgradbars@inside
%<render-tikz>            \str_if_eq:eeTF {\gradbars@placement}{center}
%<render-tikz>              {\pgfmathsetlengthmacro\gradbars@labelx{.5*(\gradbars@xstart+\gradbars@xstop)}}
%<render-tikz>              {\pgfmathsetlengthmacro\gradbars@labelx{\gradbars@width-2pt-.5*\wd\gradbars@labelbox}}
%<render-tikz>            \ifx\gradbars@target\@empty\else
%<render-tikz>              \pgfmathsetlengthmacro\gradbars@distance{abs(\gradbars@xtarget-\gradbars@labelx)}
%<render-tikz>              \ifdim\gradbars@distance<\dimexpr.5\wd\gradbars@labelbox+2pt\relax
%<render-tikz>                \def\gradbars@placement{outside}\gradbars@insidefalse\fi
%<render-tikz>            \fi
%<render-tikz>          \fi
%<render-tikz>        \fi
%<render-tikz>        \let\gradbars@labelcolor\gradbars@textcolor
%<render-tikz>        \str_if_eq:eeT {\gradbars@textcolor}{auto}{\gradbarsMainBackground}
%<render-tikz>        \gradbarsMeasure\gradbars@labelbox\gradbars@font{\color{\gradbars@labelcolor}\gradbars@labelcontent}
%<render-tikz>        \ifgradbars@inside
%<render-tikz>          \node[inner~sep=0pt,outer~sep=0pt,text=\gradbars@labelcolor]
%<render-tikz>            [gradbars~label~background]
%<render-tikz>            at (\gradbars@labelx,.5*\gradbars@height){\usebox\gradbars@labelbox};
%<render-tikz>        \else
%<render-tikz>          \str_if_eq:eeTF {\gradbars@placement}{left}
%<render-tikz>            {\dim_set:Nn \l__gradbars_labelslot_dim {\gradbars@leftlabelwidth}
%<render-tikz>             \str_if_eq:eeF {\gradbars@labeloverflow}{allow}
%<render-tikz>               {\dim_set:Nn \l__gradbars_labelslot_dim
%<render-tikz>                  {\dim_max:nn {\l__gradbars_labelslot_dim}{\wd\gradbars@labelbox}}}
%<render-tikz>             \node[anchor=east,inner~sep=0pt,outer~sep=0pt,text=\gradbars@labelcolor]
%<render-tikz>               at (-\gradbars@gap,.5*\gradbars@height)
%<render-tikz>               {\makebox[\dim_use:N \l__gradbars_labelslot_dim][r]{\usebox\gradbars@labelbox}};}
%<render-tikz>            {\str_if_eq:eeTF {\gradbars@placement}{end}
%<render-tikz>            {\pgfmathsetlengthmacro\gradbars@labelx
%<render-tikz>              {max(.5*\wd\gradbars@labelbox,min(\gradbars@xend,\gradbars@width-.5*\wd\gradbars@labelbox))}
%<render-tikz>             \node[anchor=south,inner~sep=0pt,outer~sep=0pt,text=\gradbars@labelcolor]
%<render-tikz>               at (\gradbars@labelx,\dim_use:N \l__gradbars_top_dim){\usebox\gradbars@labelbox};}
%<render-tikz>            {\dim_set:Nn \l__gradbars_labelslot_dim {\gradbars@labelwidth}
%<render-tikz>             \str_if_eq:eeF {\gradbars@labeloverflow}{allow}
%<render-tikz>               {\dim_set:Nn \l__gradbars_labelslot_dim
%<render-tikz>                  {\dim_max:nn {\l__gradbars_labelslot_dim}{\wd\gradbars@labelbox}}}
%<render-tikz>             \node[anchor=west,inner~sep=0pt,outer~sep=0pt,text=\gradbars@labelcolor]
%<render-tikz>               at ([xshift=\gradbars@gap,yshift=.5*\gradbars@height]\gradbars@width,0)
%<render-tikz>               {\makebox[\dim_use:N \l__gradbars_labelslot_dim][r]{\usebox\gradbars@labelbox}};}}
%<render-tikz>        \fi
%<render-tikz>      }
%<render-tikz>  }
%<render-tikz>\cs_new_protected:Npn \gradbarsDrawMainLabel
%<render-tikz>  {\bool_lazy_and:nnTF
%<render-tikz>     {\str_if_eq_p:ee{\gradbars@labelalign}{cell}}
%<render-tikz>     {\str_if_eq_p:ee{\gradbars@label}{inside} || \str_if_eq_p:ee{\gradbars@label}{auto}}
%<render-tikz>     {\def\gradbars@placement{center}\gradbars@insidetrue
%<render-tikz>      \pgfmathsetlengthmacro\gradbars@labelx{.5*\gradbars@width}
%<render-tikz>      \let\gradbars@labelcolor\gradbars@textcolor
%<render-tikz>      \str_if_eq:eeT{\gradbars@textcolor}{auto}{\gradbarsMainBackground}
%<render-tikz>      \gradbarsMeasure\gradbars@labelbox\gradbars@font
%<render-tikz>        {\color{\gradbars@labelcolor}\gradbars@labelcontent}
%<render-tikz>      \node[inner~sep=0pt,outer~sep=0pt,text=\gradbars@labelcolor]
%<render-tikz>        [gradbars~label~background] at (\gradbars@labelx,.5*\gradbars@height)
%<render-tikz>        {\usebox\gradbars@labelbox};}
%<render-tikz>     {\__gradbars_draw_graphic_label:}}
%<render-tikz>\cs_new_protected:Npn \gradbarsResolveBaseline
%<render-tikz>  {
%<render-tikz>    \pgfmathsetlengthmacro\gradbars@baseliney{.5*\gradbars@height-\gradbars@baselineoffset}
%<render-tikz>    \str_case_e:nn {\gradbars@baseline}
%<render-tikz>      {
%<render-tikz>        {center}{\pgfmathsetlengthmacro\gradbars@baseliney{.5*\gradbars@height}}
%<render-tikz>        {bottom}{\def\gradbars@baseliney{0pt}}
%<render-tikz>        {text}
%<render-tikz>          {\str_if_eq:eeT {\gradbars@label}{none}
%<render-tikz>             {\gradbarsMeasure\gradbars@labelbox\gradbars@font{\strut}}
%<render-tikz>           \pgfmathsetlengthmacro\gradbars@baseliney
%<render-tikz>             {.5*\gradbars@height-.5*(\ht\gradbars@labelbox-\dp\gradbars@labelbox)}
%<render-tikz>           \str_if_eq:eeF {\gradbars@label}{none}
%<render-tikz>             {\str_if_eq:eeT {\gradbars@placement}{end}
%<render-tikz>                {\pgfmathsetlengthmacro\gradbars@baseliney
%<render-tikz>                   {\dim_use:N \l__gradbars_top_dim+\dp\gradbars@labelbox}}}}
%<render-tikz>      }
%<render-tikz>    \pgfmathsetlengthmacro\gradbars@baseliney{\gradbars@baseliney-\gradbars@baselineshift}
%<render-tikz>  }
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_new_protected:Npn \gradbarsDrawTrack
%<render-tikz>  {
%<render-tikz>    \str_if_eq:eeTF {\gradbars@shape}{lollipop}
%<render-tikz>      {\draw[draw=\gradbars@track,line~width=\gradbars@stemwidth]
%<render-tikz>        (0,.5*\gradbars@height)--(\gradbars@width,.5*\gradbars@height);}
%<render-tikz>      {\ifgradbars@outline
%<render-tikz>        \path[rounded~corners=\gradbars@radius,fill=\gradbars@track,
%<render-tikz>          draw=gradbarsInk!35,line~width=\gradbars@outlinewidth]
%<render-tikz>          (0,0) rectangle (\gradbars@width,\gradbars@height);
%<render-tikz>       \else
%<render-tikz>        \path[rounded~corners=\gradbars@radius,fill=\gradbars@track,draw=none]
%<render-tikz>          (0,0) rectangle (\gradbars@width,\gradbars@height);
%<render-tikz>       \fi}
%<render-tikz>  }
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_new_protected:Npn \gradbarsDrawDot #1
%<render-tikz>  {
%<render-tikz>    \pgfmathsetlengthmacro\gradbars@dotradius{min(\gradbars@markersize,.5*\gradbars@height)}
%<render-tikz>    \ifgradbars@outline
%<render-tikz>      \path[fill=white,draw=\gradbars@left,line~width=\gradbars@stemwidth]
%<render-tikz>        (#1,.5*\gradbars@height) circle[radius=\gradbars@dotradius];
%<render-tikz>    \else
%<render-tikz>      \path[fill=\gradbars@left,draw=none]
%<render-tikz>        (#1,.5*\gradbars@height) circle[radius=\gradbars@dotradius];
%<render-tikz>    \fi
%<render-tikz>  }
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_new_protected:Npn \gradbarsDrawShape
%<render-tikz>  {
%<render-tikz>    \str_if_eq:eeTF {\gradbars@shape}{lollipop}
%<render-tikz>      {\ifgradbars@missing\else
%<render-tikz>         \draw[draw=\gradbars@left,line~width=\gradbars@stemwidth]
%<render-tikz>           (\gradbars@xzero,.5*\gradbars@height)--(\gradbars@xend,.5*\gradbars@height);
%<render-tikz>         \gradbarsDrawDot{\gradbars@xend}
%<render-tikz>       \fi}
%<render-tikz>      {
%<render-tikz>        \ifgradbars@compare
%<render-tikz>          \ifgradbars@referencemissing\else
%<render-tikz>            \pgfmathsetlengthmacro\gradbars@xref{\gradbarsPosition{\gradbars@reference}*(\gradbars@width)}
%<render-tikz>            \ifgradbars@outline
%<render-tikz>              \draw[draw=\gradbars@comparecolor,line~width=\gradbars@outlinewidth]
%<render-tikz>                (\gradbars@xzero,0) rectangle (\gradbars@xref,\gradbars@height);
%<render-tikz>            \else
%<render-tikz>              \path[rounded~corners=\gradbars@radius,fill=\gradbars@comparecolor,draw=none]
%<render-tikz>                (\gradbars@xzero,0) rectangle (\gradbars@xref,\gradbars@height);
%<render-tikz>            \fi
%<render-tikz>          \fi
%<render-tikz>          \begin{scope}[yshift={.5*(1-\gradbars@compareratio)*\gradbars@height}]
%<render-tikz>            \pgfmathsetlengthmacro\gradbars@height{\gradbars@compareratio*\gradbars@height}
%<render-tikz>            \pgfmathsetlengthmacro\gradbars@radius{min(\gradbars@radius,.5*\gradbars@height)}
%<render-tikz>            \gradbarsDrawBarBody
%<render-tikz>          \end{scope}
%<render-tikz>        \else
%<render-tikz>          \gradbarsDrawBarBody
%<render-tikz>          \ifgradbars@rangemode\ifgradbars@missing\else
%<render-tikz>            \draw[draw=\gradbars@left,line~width=\gradbars@stemwidth]
%<render-tikz>              (\gradbars@xstart,0)--(\gradbars@xstart,\gradbars@height)
%<render-tikz>              (\gradbars@xstop,0)--(\gradbars@xstop,\gradbars@height);
%<render-tikz>            \tl_if_empty:oF {\gradbars@rangepoint}
%<render-tikz>              {\pgfmathsetlengthmacro\gradbars@xpoint{\gradbarsPosition{\gradbars@rangepoint}*(\gradbars@width)}
%<render-tikz>               \pgfmathsetlengthmacro\gradbars@dotradius{min(\gradbars@markersize,.5*\gradbars@height)}
%<render-tikz>               \gradbarsDrawMarker{\gradbars@xpoint}{.5*\gradbars@height}{gradbarsInk}{hollow}}
%<render-tikz>          \fi\fi
%<render-tikz>        \fi
%<render-tikz>      }
%<render-tikz>  }
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\def\gradbarsDrawBarBody{%
%<render-tikz>  \ifdim\gradbars@xstop>\gradbars@xstart\relax
%<render-tikz>    \pgfmathsetlengthmacro\gradbars@fillradius{min(\gradbars@radius,.5*(\gradbars@xstop-\gradbars@xstart))}%
%<render-tikz>    \begin{scope}
%<render-tikz>      \clip[rounded corners=\gradbars@radius]
%<render-tikz>        (0,0) rectangle (\gradbars@width,\gradbars@height);
%<render-tikz>      \ifgradbars@stack
%<render-tikz>        \clip[rounded corners=\gradbars@fillradius]
%<render-tikz>          (\gradbars@xstart,0) rectangle (\gradbars@xstop,\gradbars@height);
%<render-tikz>        \gradbarsDrawStack
%<render-tikz>      \else\ifgradbars@outline
%<render-tikz>        \draw[rounded corners=\gradbars@fillradius,draw=\gradbars@left,line width=\gradbars@outlinewidth]
%<render-tikz>          (\gradbars@xstart,0) rectangle (\gradbars@xstop,\gradbars@height);
%<render-tikz>      \else\ifgradbars@gradient
%<render-tikz>        \path[rounded corners=\gradbars@fillradius,shade,
%<render-tikz>          left color=\gradbars@left,right color=\gradbars@right]
%<render-tikz>          (\gradbars@xstart,0) rectangle (\gradbars@xstop,\gradbars@height);
%<render-tikz>      \else
%<render-tikz>        \path[rounded corners=\gradbars@fillradius,fill=\gradbars@left,draw=none]
%<render-tikz>          (\gradbars@xstart,0) rectangle (\gradbars@xstop,\gradbars@height);
%<render-tikz>      \fi\fi\fi
%<render-tikz>      \ifgradbars@stack\else\ifgradbars@outline\else
%<render-tikz>        \clip[rounded corners=\gradbars@fillradius]
%<render-tikz>          (\gradbars@xstart,0) rectangle (\gradbars@xstop,\gradbars@height);
%<render-tikz>        \gradbarsPatternRect{0}{\gradbars@xstart}{0}{\gradbars@xstop}{\gradbars@height}
%<render-tikz>      \fi
%<render-tikz>      \fi
%<render-tikz>    \end{scope}
%<render-tikz>  \fi
%<render-tikz>}
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_new_eq:NN \gradbarsShapeBeforeThree \gradbarsDrawShape
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_set_protected:Npn \gradbarsDrawShape
%<render-tikz>  {
%<render-tikz>    \str_case_e:nnF {\gradbars@shape}
%<render-tikz>      {{dumbbell}{\gradbarsDrawDumbbell}{sparkline}{\gradbarsDrawSpark}}
%<render-tikz>      {\gradbarsShapeBeforeThree}
%<render-tikz>  }
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_new_protected:Npn \gradbarsDrawDumbbell
%<render-tikz>  {
%<render-tikz>    \gradbarsMarkerBounds
%<render-tikz>    \ifgradbars@referencemissing\else
%<render-tikz>      \pgfmathsetlengthmacro\gradbars@xref{\gradbarsPosition{\gradbars@reference}*\gradbars@width}
%<render-tikz>      \ifgradbars@missing\else
%<render-tikz>        \draw[draw=\gradbars@left,line~width=\gradbars@stemwidth]
%<render-tikz>          (\gradbars@xref,.5*\gradbars@height)--(\gradbars@xend,.5*\gradbars@height);
%<render-tikz>      \fi
%<render-tikz>      \group_begin:\let\gradbars@left\gradbars@comparecolor
%<render-tikz>        \gradbars@outlinetrue\gradbarsDrawDot{\gradbars@xref}\group_end:
%<render-tikz>    \fi
%<render-tikz>    \ifgradbars@missing\else\gradbarsDrawDot{\gradbars@xend}\fi
%<render-tikz>  }
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_new_protected:Npn \gradbarsMarkerBounds
%<render-tikz>  {\path
%<render-tikz>     (-\gradbars@markersize,-\gradbars@markersize) rectangle
%<render-tikz>     ([xshift=\gradbars@markersize,yshift=\gradbars@markersize]\gradbars@width,\gradbars@height);}
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_new_eq:NN \gradbarsTrackBeforeThree \gradbarsDrawTrack
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_set_protected:Npn \gradbarsDrawTrack
%<render-tikz>  {\group_begin:
%<render-tikz>   \str_if_eq:eeT {\gradbars@shape}{dumbbell}{\def\gradbars@shape{lollipop}}
%<render-tikz>   \gradbarsTrackBeforeThree\group_end:}
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_new_protected:Npn \gradbarsDrawReferences
%<render-tikz>  {\int_zero:N \l_tmpa_int
%<render-tikz>   \clist_map_inline:Nn \l__gradbars_refs_clist
%<render-tikz>     {\seq_set_split:Nnn \l__gradbars_record_seq {/}{##1}
%<render-tikz>      \tl_set:Nx \l__gradbars_record_color_tl {\seq_item:Nn \l__gradbars_record_seq {2}}
%<render-tikz>      \tl_set:Nx \l__gradbars_record_style_tl {\seq_item:Nn \l__gradbars_record_seq {3}}
%<render-tikz>      \tl_set:Nx \l__gradbars_record_name_tl {\seq_item:Nn \l__gradbars_record_seq {4}}
%<render-tikz>      \pgfmathsetlengthmacro\gradbars@rx
%<render-tikz>        {\gradbarsPosition{\seq_item:Nn \l__gradbars_record_seq {1}}*(\gradbars@width)}
%<render-tikz>      \draw[draw=\l__gradbars_record_color_tl,line~width=.6pt,
%<render-tikz>        \l__gradbars_record_style_tl]
%<render-tikz>        (\gradbars@rx,-1pt)--(\gradbars@rx,{\gradbars@height+1pt});
%<render-tikz>      \tl_if_blank:VF \l__gradbars_record_name_tl
%<render-tikz>        {\node[anchor=south,inner~sep=1pt,font=\scriptsize,
%<render-tikz>           text=\l__gradbars_record_color_tl]
%<render-tikz>           at (\gradbars@rx,{\gradbars@height+2pt+10pt*\int_mod:nn{\l_tmpa_int}{2}})
%<render-tikz>           {\l__gradbars_record_name_tl};}
%<render-tikz>      \int_incr:N \l_tmpa_int}}
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_new_eq:NN \gradbarsBandBeforeBullet \gradbarsDrawBand
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_set_protected:Npn \gradbarsDrawBand
%<render-tikz>  {\ifgradbars@bullet
%<render-tikz>     \fp_set:Nn \l__gradbars_band_start_fp {\gradbars@min}
%<render-tikz>     \clist_map_inline:Nn \l__gradbars_bands_clist
%<render-tikz>       {\seq_set_split:Nnn \l__gradbars_record_seq {/}{##1}
%<render-tikz>        \tl_set:Nx \l__gradbars_record_color_tl {\seq_item:Nn \l__gradbars_record_seq {2}}
%<render-tikz>        \pgfmathsetlengthmacro\gradbars@bx
%<render-tikz>          {\gradbarsPosition{\l__gradbars_band_start_fp}*(\gradbars@width)}
%<render-tikz>        \pgfmathsetlengthmacro\gradbars@ex
%<render-tikz>          {\gradbarsPosition{\seq_item:Nn \l__gradbars_record_seq {1}}*(\gradbars@width)}
%<render-tikz>        \path[fill=\l__gradbars_record_color_tl,draw=none]
%<render-tikz>          (\gradbars@bx,0) rectangle (\gradbars@ex,\gradbars@height);
%<render-tikz>        \fp_set:Nn \l__gradbars_band_start_fp {\seq_item:Nn \l__gradbars_record_seq {1}}}
%<render-tikz>   \fi\gradbarsBandBeforeBullet}
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_new_eq:NN \gradbarsShapeBeforeBullet \gradbarsDrawShape
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_set_protected:Npn \gradbarsDrawShape
%<render-tikz>  {\ifgradbars@bullet
%<render-tikz>     \begin{scope}[yshift=.3*\gradbars@height,yscale=.4]
%<render-tikz>       \gradbarsShapeBeforeBullet
%<render-tikz>     \end{scope}
%<render-tikz>   \else\gradbarsShapeBeforeBullet\fi}
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_new_protected:Npn \gradbarsDrawMarker #1#2#3#4
%<render-tikz>  {\group_begin:
%<render-tikz>   \tl_set:Nn \l_tmpa_tl {#3}
%<render-tikz>   \str_if_eq:eeT {#4}{hollow}{\tl_set:Nn \l_tmpa_tl {white}}
%<render-tikz>   \begin{scope}[shift={(#1,#2)}]
%<render-tikz>   \tikzset{gradbars~mark/.style={draw=#3,fill=\l_tmpa_tl,line~width=\gradbars@stemwidth}}
%<render-tikz>   \str_case_e:nn {\gradbars@markershape}
%<render-tikz>     {{circle}{\path[gradbars~mark] (0,0) circle[radius=\gradbars@markersize];}
%<render-tikz>      {square}{\path[gradbars~mark] (-\gradbars@markersize,-\gradbars@markersize)
%<render-tikz>        rectangle (\gradbars@markersize,\gradbars@markersize);}
%<render-tikz>      {diamond}{\path[gradbars~mark] (0,\gradbars@markersize)--(\gradbars@markersize,0)
%<render-tikz>        --(0,-\gradbars@markersize)--(-\gradbars@markersize,0)--cycle;}
%<render-tikz>      {triangle}{\path[gradbars~mark] (0,\gradbars@markersize)
%<render-tikz>        --(\gradbars@markersize,-\gradbars@markersize)--(-\gradbars@markersize,-\gradbars@markersize)--cycle;}}
%<render-tikz>   \end{scope}\group_end:}
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_set_protected:Npn \gradbarsDrawDot #1
%<render-tikz>  {\ifgradbars@outline
%<render-tikz>     \gradbarsDrawMarker{#1}{.5*\gradbars@height}{\gradbars@left}{hollow}
%<render-tikz>   \else\gradbarsDrawMarker{#1}{.5*\gradbars@height}{\gradbars@left}{\gradbars@markerfill}\fi}
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_new_protected:Npn \gradbarsDrawOverflow
%<render-tikz>  {\str_if_eq:eeF {\gradbars@overflowmark}{none}
%<render-tikz>    {\bool_set_true:N \l__gradbars_overflow_known_bool
%<render-tikz>     \ifgradbars@missing\bool_set_false:N \l__gradbars_overflow_known_bool\fi
%<render-tikz>     \ifgradbars@compare\ifgradbars@referencemissing\else
%<render-tikz>       \bool_set_true:N \l__gradbars_overflow_known_bool\fi\fi
%<render-tikz>     \ifgradbars@spark\bool_set_eq:NN \l__gradbars_overflow_known_bool \l__gradbars_series_any_bool\fi
%<render-tikz>     \bool_if:NT \l__gradbars_overflow_known_bool {
%<render-tikz>      \fp_set:Nn \l__gradbars_raw_low_fp {\gradbars@value}
%<render-tikz>      \fp_set_eq:NN \l__gradbars_raw_high_fp \l__gradbars_raw_low_fp
%<render-tikz>      \ifgradbars@stack
%<render-tikz>        \fp_set:Nn \l__gradbars_raw_low_fp {\gradbars@negative}
%<render-tikz>        \fp_set:Nn \l__gradbars_raw_high_fp {\gradbars@positive}
%<render-tikz>      \fi
%<render-tikz>      \ifgradbars@rangemode
%<render-tikz>        \fp_set:Nn \l__gradbars_raw_low_fp {\gradbars@rangelo}
%<render-tikz>        \fp_set:Nn \l__gradbars_raw_high_fp {\gradbars@rangehi}
%<render-tikz>      \fi
%<render-tikz>      \ifgradbars@compare\ifgradbars@referencemissing\else
%<render-tikz>        \fp_set:Nn \l__gradbars_raw_low_fp {min(\gradbars@value,\gradbars@reference)}
%<render-tikz>        \fp_set:Nn \l__gradbars_raw_high_fp {max(\gradbars@value,\gradbars@reference)}
%<render-tikz>        \ifgradbars@missing
%<render-tikz>          \fp_set:Nn \l__gradbars_raw_low_fp {\gradbars@reference}
%<render-tikz>          \fp_set_eq:NN \l__gradbars_raw_high_fp \l__gradbars_raw_low_fp
%<render-tikz>        \fi
%<render-tikz>      \fi\fi
%<render-tikz>      \ifgradbars@error
%<render-tikz>        \fp_set:Nn \l__gradbars_raw_low_fp {min(\l__gradbars_raw_low_fp,\gradbars@value-\gradbars@errorminus)}
%<render-tikz>        \fp_set:Nn \l__gradbars_raw_high_fp {max(\l__gradbars_raw_high_fp,\gradbars@value+\gradbars@errorplus)}
%<render-tikz>      \fi
%<render-tikz>      \ifgradbars@spark
%<render-tikz>        \fp_set_eq:NN \l__gradbars_raw_low_fp \l__gradbars_series_min_fp
%<render-tikz>        \fp_set_eq:NN \l__gradbars_raw_high_fp \l__gradbars_series_max_fp
%<render-tikz>      \fi
%<render-tikz>      \fp_compare:nNnT {\l__gradbars_raw_low_fp} < {\gradbars@min}{\gradbarsOverflowSide{0pt}{-1}}
%<render-tikz>      \fp_compare:nNnT {\l__gradbars_raw_high_fp} > {\gradbars@max}{\gradbarsOverflowSide{\gradbars@width}{1}}
%<render-tikz>    }}}
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\ExplSyntaxOn
%<render-tikz>\cs_new_protected:Npn \gradbarsDrawChange
%<render-tikz>  {\ifgradbars@compare\ifgradbars@missing\else\ifgradbars@referencemissing\else
%<render-tikz>   \str_if_eq:eeF {\gradbars@change}{none}
%<render-tikz>    {\pgfmathsetlengthmacro\gradbars@cx{\gradbarsPosition{\gradbars@reference}*\gradbars@width}
%<render-tikz>     \begin{scope}[yshift={\gradbars@height+5pt}]
%<render-tikz>       \str_if_eq:eeTF {\gradbars@change}{arrow}
%<render-tikz>         {\dim_compare:nNnF {\gradbars@xend} = {\gradbars@cx}
%<render-tikz>            {\draw[->,draw=gradbarsInk,line~width=.5pt](\gradbars@cx,0)--(\gradbars@xend,0);}}
%<render-tikz>         {\draw[draw=gradbarsInk,line~width=.5pt]
%<render-tikz>           (\gradbars@cx,-2pt)--(\gradbars@cx,0)--(\gradbars@xend,0)--(\gradbars@xend,-2pt);}
%<render-tikz>       \node[anchor=south,inner~sep=1pt,font=\scriptsize,text=gradbarsInk]
%<render-tikz>         at ({.5*(\gradbars@cx+\gradbars@xend)},1pt){\gradbarsChangeLabel};
%<render-tikz>     \end{scope}}
%<render-tikz>   \fi\fi\fi}
%<render-tikz>\ExplSyntaxOff
%<render-tikz>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-table-data.sty}}
%    \begin{macrocode}
%<table-data>% Author: SuFan; MIT License. Private table data layer.
%<table-data>\ProvidesPackage{gradbars-table-data}[2026/10/25 v1.1.0 gradbars table data]
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableRank
%<table-data>  {\prop_clear:N\l__gradtable_best_prop\prop_clear:N\l__gradtable_second_prop
%<table-data>   \int_zero:N\l__gradtable_rank_col_int
%<table-data>   \seq_map_inline:Nn\l__gradtable_columns_seq
%<table-data>     {\int_incr:N\l__gradtable_rank_col_int
%<table-data>      \str_if_eq:eeF{\prop_item:Nn\l__gradtable_marks_prop{##1}}{none}
%<table-data>        {\group_begin:\gradtableConfigure{##1}
%<table-data>         \tl_gset:Nx\g__gradtable_rank_direction_tl{\gradbars@better}\group_end:
%<table-data>         \tl_set_eq:NN\l__gradtable_rank_direction_tl\g__gradtable_rank_direction_tl
%<table-data>         \str_case:VnF\l__gradtable_rank_direction_tl{{higher}{}{lower}{}}
%<table-data>           {\gradtableError{Mark~requires~better=higher~or~lower}}
%<table-data>         \seq_clear:N\l__gradtable_rank_seq
%<table-data>         \seq_map_inline:Nn\l__gradtable_rows_seq
%<table-data>           {\clist_set:Nn\l__gradtable_cells_clist{####1}
%<table-data>            \tl_set:Nx\l__gradtable_rank_value_tl
%<table-data>              {\clist_item:Nn\l__gradtable_cells_clist{\l__gradtable_rank_col_int}}
%<table-data>            \tl_trim_spaces:N\l__gradtable_rank_value_tl
%<table-data>            \gradbarsIfNumber:VT\l__gradtable_rank_value_tl
%<table-data>              {\seq_put_right:Nx\l__gradtable_rank_seq{\fp_eval:n{\l__gradtable_rank_value_tl}}}}
%<table-data>         \seq_remove_duplicates:N\l__gradtable_rank_seq
%<table-data>         \seq_sort:Nn\l__gradtable_rank_seq
%<table-data>           {\str_if_eq:VnTF\l__gradtable_rank_direction_tl{higher}
%<table-data>              {\fp_compare:nNnTF{####1}<{####2}{\sort_return_swapped:}{\sort_return_same:}}
%<table-data>              {\fp_compare:nNnTF{####1}>{####2}{\sort_return_swapped:}{\sort_return_same:}}}
%<table-data>         \seq_if_empty:NF\l__gradtable_rank_seq
%<table-data>           {\prop_put:Nnx\l__gradtable_best_prop{##1}{\seq_item:Nn\l__gradtable_rank_seq{1}}}
%<table-data>         \int_compare:nNnT{\seq_count:N\l__gradtable_rank_seq}>{1}
%<table-data>           {\prop_put:Nnx\l__gradtable_second_prop{##1}{\seq_item:Nn\l__gradtable_rank_seq{2}}}}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableImportCSV
%<table-data>  {\seq_if_empty:NF\l__gradtable_rows_seq
%<table-data>     {\gradtableError{Data~tables~cannot~also~contain~manual~rows}}
%<table-data>   \prop_if_exist:cTF{l__gradbars_csv_\l__gradtable_data_tl _prop}
%<table-data>     {\seq_map_inline:Nn\l__gradtable_columns_seq
%<table-data>        {\tl_set:Nn\l__gradtable_id_tl{##1}
%<table-data>         \prop_get:NnN\l__gradtable_sources_prop{##1}\l__gradtable_import_source_tl
%<table-data>         \exp_args:NVV\gradbarsCSVColumn\l__gradtable_data_tl\l__gradtable_import_source_tl
%<table-data>         \ifgradbars@valid\else\bool_set_false:N\l__gradtable_valid_bool\fi}
%<table-data>      \bool_if:NT\l__gradtable_valid_bool
%<table-data>        {\int_step_inline:nn{\prop_item:cn{l__gradbars_csv_\l__gradtable_data_tl _prop}{rows}}
%<table-data>           {\int_set:Nn\l__gradtable_import_row_int{##1}
%<table-data>            \tl_clear:N\l__gradtable_import_row_tl
%<table-data>            \seq_map_inline:Nn\l__gradtable_columns_seq
%<table-data>              {\tl_set:Nn\l__gradtable_id_tl{####1}
%<table-data>               \prop_get:NnN\l__gradtable_sources_prop{####1}\l__gradtable_import_source_tl
%<table-data>               \use:x{\exp_not:N\gradbarsCSVGet{\l__gradtable_data_tl}{##1}{\l__gradtable_import_source_tl}}
%<table-data>               \str_if_eq:eeF{\prop_item:Nn\l__gradtable_types_prop{####1}}{text}
%<table-data>                 {\gradtableMapCSVMissing}
%<table-data>               \tl_if_empty:NF\l__gradtable_import_row_tl{\tl_put_right:Nn\l__gradtable_import_row_tl{,}}
%<table-data>               \tl_put_right:Nx\l__gradtable_import_row_tl{{\exp_not:V\l__gradbars_csv_value_tl}}}
%<table-data>            \exp_args:NV\gradtableRow\l__gradtable_import_row_tl}
%<table-data>         \seq_set_eq:NN\l__gradtable_data_rows_seq\l__gradtable_rows_seq
%<table-data>         \gradtableSelectRows}}
%<table-data>     {\gradtableError{Unknown~CSV~dataset:~\l__gradtable_data_tl}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableMapCSVMissing
%<table-data>  {\prop_get:cnN{l__gradbars_csv_\l__gradtable_data_tl _prop}{missing}\l_tmpa_tl
%<table-data>   \clist_set:NV\l__gradbars_csv_missing_clist\l_tmpa_tl
%<table-data>   \bool_set_false:N\l_tmpa_bool
%<table-data>   \tl_if_blank:VT\l__gradbars_csv_value_tl{\bool_set_true:N\l_tmpa_bool}
%<table-data>   \clist_map_inline:Nn\l__gradbars_csv_missing_clist
%<table-data>     {\str_if_eq:eeT{\l__gradbars_csv_value_tl}{\tl_to_str:n{##1}}{\bool_set_true:N\l_tmpa_bool}}
%<table-data>   \bool_if:NT\l_tmpa_bool{\tl_set:Nn\l__gradbars_csv_value_tl{NA}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableScaleValue #1
%<table-data>  {\tl_set:Nn\l_tmpb_tl{#1}\tl_trim_spaces:N\l_tmpb_tl
%<table-data>   \tl_if_empty:NF\l_tmpb_tl
%<table-data>     {\str_if_eq:VnF\l_tmpb_tl{NA}
%<table-data>       {\gradbarsIfNumber:VTF\l_tmpb_tl
%<table-data>         {\bool_if:NTF\l__gradtable_seen_bool
%<table-data>           {\fp_set:Nn\l__gradtable_min_fp{min(\l__gradtable_min_fp,\l_tmpb_tl)}
%<table-data>            \fp_set:Nn\l__gradtable_max_fp{max(\l__gradtable_max_fp,\l_tmpb_tl)}}
%<table-data>           {\fp_set:Nn\l__gradtable_min_fp{\l_tmpb_tl}
%<table-data>            \fp_set:Nn\l__gradtable_max_fp{\l_tmpb_tl}
%<table-data>            \bool_set_true:N\l__gradtable_seen_bool}}
%<table-data>         {\gradtableError{Auto~scale~requires~decimal~or~scientific~numbers~or~NA}}}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableScaleCell #1
%<table-data>  {\str_case:VnF\l__gradtable_type_tl
%<table-data>     {{compare}{\seq_set_split:Nnn\l__gradtable_scale_values_seq{/}{#1}}
%<table-data>      {dumbbell}{\seq_set_split:Nnn\l__gradtable_scale_values_seq{/}{#1}}
%<table-data>      {interval}{\seq_set_split:Nnn\l__gradtable_scale_values_seq{/}{#1}}
%<table-data>      {boxplot}{\seq_set_split:Nnn\l__gradtable_scale_values_seq{,}{#1}}
%<table-data>      {spark}{\seq_set_split:Nnn\l__gradtable_scale_values_seq{,}{#1}}
%<table-data>      {stack}{\seq_set_split:Nnn\l__gradtable_scale_values_seq{,}{#1}}}
%<table-data>     {\seq_set_from_clist:Nn\l__gradtable_scale_values_seq{{#1}}}
%<table-data>   \str_if_eq:VnTF\l__gradtable_type_tl{stack}
%<table-data>     {\fp_zero:N\l__gradtable_positive_fp\fp_zero:N\l__gradtable_negative_fp
%<table-data>      \str_if_eq:nnF{#1}{NA}
%<table-data>        {\seq_map_inline:Nn\l__gradtable_scale_values_seq
%<table-data>           {\gradbars@validtrue\gradbarsCheckNumber{##1}{stack~segment}
%<table-data>            \ifgradbars@valid
%<table-data>              \fp_compare:nNnTF{##1}<{0}
%<table-data>                {\fp_add:Nn\l__gradtable_negative_fp{##1}}
%<table-data>                {\fp_add:Nn\l__gradtable_positive_fp{##1}}
%<table-data>            \else\bool_set_false:N\l__gradtable_valid_bool\fi}
%<table-data>         \exp_args:Ne\gradtableScaleValue{\fp_to_decimal:N\l__gradtable_positive_fp}
%<table-data>         \exp_args:Ne\gradtableScaleValue{\fp_to_decimal:N\l__gradtable_negative_fp}}}
%<table-data>     {\seq_map_inline:Nn\l__gradtable_scale_values_seq{\gradtableScaleValue{##1}}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableAutoRanges
%<table-data>  {\seq_set_eq:NN\l__gradtable_range_rows_seq\l__gradtable_rows_seq
%<table-data>   \tl_if_empty:NF\l__gradtable_data_tl
%<table-data>     {\str_if_eq:VnT\l__gradtable_scale_scope_tl{data}
%<table-data>        {\seq_set_eq:NN\l__gradtable_range_rows_seq\l__gradtable_data_rows_seq}}
%<table-data>   \int_zero:N\l__gradtable_scale_col_int
%<table-data>   \seq_map_inline:Nn\l__gradtable_columns_seq
%<table-data>     {\int_incr:N\l__gradtable_scale_col_int
%<table-data>      \tl_set:Nn\l__gradtable_id_tl{##1}
%<table-data>      \prop_get:NnN\l__gradtable_types_prop{##1}\l__gradtable_type_tl
%<table-data>      \str_if_eq:VnF\l__gradtable_type_tl{text}
%<table-data>        {\str_if_eq:eeT{\prop_item:Nn\l__gradtable_scales_prop{##1}}{column}
%<table-data>          {\bool_set_false:N\l__gradtable_seen_bool
%<table-data>           \int_zero:N\l__gradtable_row_int
%<table-data>           \seq_map_inline:Nn\l__gradtable_range_rows_seq
%<table-data>             {\int_incr:N\l__gradtable_row_int
%<table-data>              \clist_set:Nn\l__gradtable_cells_clist{####1}
%<table-data>              \exp_args:Ne\gradtableScaleCell
%<table-data>                {\clist_item:Nn\l__gradtable_cells_clist{\l__gradtable_scale_col_int}}}
%<table-data>           \bool_if:NTF\l__gradtable_seen_bool
%<table-data>             {\str_if_eq:eeT{\prop_item:Nn\l__gradtable_zero_prop{##1}}{true}
%<table-data>                {\fp_set:Nn\l__gradtable_min_fp{min(0,\l__gradtable_min_fp)}
%<table-data>                 \fp_set:Nn\l__gradtable_max_fp{max(0,\l__gradtable_max_fp)}}
%<table-data>              \fp_compare:nNnT{\l__gradtable_min_fp}={\l__gradtable_max_fp}
%<table-data>                {\str_if_eq:eeTF{\prop_item:Nn\l__gradtable_zero_prop{##1}}{true}
%<table-data>                   {\fp_set:Nn\l__gradtable_max_fp{1}}
%<table-data>                   {\__gradbars_constant_range:NN\l__gradtable_min_fp\l__gradtable_max_fp}}}
%<table-data>             {\fp_zero:N\l__gradtable_min_fp\fp_set:Nn\l__gradtable_max_fp{1}}
%<table-data>           \gradtableAdjustRange{##1}
%<table-data>           \prop_put:Nnx\l__gradtable_ranges_prop{##1}
%<table-data>             {min=\fp_to_decimal:N\l__gradtable_min_fp,max=\fp_to_decimal:N\l__gradtable_max_fp
%<table-data>              \str_if_eq:VnT\l__gradtable_type_tl{spark}{,spark~range=fixed}}}}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableValidateSelection
%<table-data>  {\tl_if_empty:NT\l__gradtable_data_tl
%<table-data>     {\bool_if:nT{!\tl_if_empty_p:N\l__gradtable_sort_tl ||
%<table-data>        !\tl_if_empty_p:N\l__gradtable_filter_tl || \int_compare_p:nNn{\l__gradtable_limit_int}>{0}}
%<table-data>        {\gradtableError{Sort,~filter~and~limit~require~a~CSV~data~source}}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableSelectionType #1
%<table-data>  {\prop_get:NnNTF\l__gradtable_types_prop{#1}\l__gradtable_selection_type_tl
%<table-data>     {\str_case:VnF\l__gradtable_selection_type_tl{{text}{}{number}{}{bar}{}{bullet}{}{heat}{}}
%<table-data>       {\gradtableError{Sort~and~filter~require~a~scalar~or~text~column}}}
%<table-data>     {\gradtableError{Unknown~selection~column:~#1}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableSelectionValue #1
%<table-data>  {\tl_set:Nx\l__gradtable_selection_value_tl
%<table-data>     {\clist_item:Nn\l__gradtable_selection_cells_clist{#1}}
%<table-data>   \tl_trim_spaces:N\l__gradtable_selection_value_tl}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableColumnIndex #1
%<table-data>  {\int_zero:N\l__gradtable_selection_col_int
%<table-data>   \seq_map_inline:Nn\l__gradtable_columns_seq
%<table-data>     {\int_incr:N\l__gradtable_selection_col_int
%<table-data>      \str_if_eq:nnT{##1}{#1}{\seq_map_break:}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtablePrepareFilters
%<table-data>  {\seq_clear:N\l__gradtable_filters_seq
%<table-data>   \clist_map_inline:Vn\l__gradtable_filter_tl
%<table-data>     {\tl_set:Nn\l_tmpa_tl{##1}
%<table-data>      \regex_extract_once:nVNTF{\A\s*([^<>=!]+?)\s*(>=|<=|!=|=|>|<)\s*(.*?)\s*\Z}
%<table-data>        \l_tmpa_tl\l__gradtable_filter_parts_seq
%<table-data>        {\tl_set:Nx\l__gradtable_filter_id_tl{\seq_item:Nn\l__gradtable_filter_parts_seq{2}}
%<table-data>         \tl_trim_spaces:N\l__gradtable_filter_id_tl
%<table-data>         \tl_set:Nx\l__gradtable_filter_op_tl{\seq_item:Nn\l__gradtable_filter_parts_seq{3}}
%<table-data>         \tl_set:Nx\l__gradtable_filter_target_tl{\seq_item:Nn\l__gradtable_filter_parts_seq{4}}
%<table-data>         \tl_trim_spaces:N\l__gradtable_filter_target_tl
%<table-data>         \exp_args:NV\gradtableSelectionType\l__gradtable_filter_id_tl
%<table-data>         \str_if_eq:VnTF\l__gradtable_selection_type_tl{text}
%<table-data>           {\str_case:VnF\l__gradtable_filter_op_tl{{=}{}{!=}{}}
%<table-data>              {\gradtableError{Text~filters~support~only~=~and~!=}}}
%<table-data>           {\str_if_eq:VnTF\l__gradtable_filter_target_tl{NA}
%<table-data>              {\str_case:VnF\l__gradtable_filter_op_tl{{=}{}{!=}{}}
%<table-data>                 {\gradtableError{Missing~filters~support~only~=NA~and~!=NA}}}
%<table-data>              {\gradbars@validtrue\gradbarsCheckNumber{\l__gradtable_filter_target_tl}{filter~value}
%<table-data>               \ifgradbars@valid\else\bool_set_false:N\l__gradtable_valid_bool\fi}}
%<table-data>         \bool_if:NT\l__gradtable_valid_bool
%<table-data>           {\exp_args:NV\gradtableColumnIndex\l__gradtable_filter_id_tl
%<table-data>            \seq_put_right:Nx\l__gradtable_filters_seq
%<table-data>              {{\int_use:N\l__gradtable_selection_col_int}
%<table-data>               {\exp_not:V\l__gradtable_selection_type_tl}{\exp_not:V\l__gradtable_filter_op_tl}
%<table-data>               {\exp_not:V\l__gradtable_filter_target_tl}}}}
%<table-data>        {\gradtableError{Filter~requires~column~operator~value}}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableApplyFilter #1#2#3#4
%<table-data>  {\gradtableSelectionValue{#1}
%<table-data>   \str_if_eq:nnTF{#2}{text}
%<table-data>     {\str_if_eq:eeTF{\tl_to_str:V\l__gradtable_selection_value_tl}{\tl_to_str:n{#4}}
%<table-data>        {\str_if_eq:nnT{#3}{!=}{\bool_set_false:N\l__gradtable_selected_bool}}
%<table-data>        {\str_if_eq:nnT{#3}{=}{\bool_set_false:N\l__gradtable_selected_bool}}}
%<table-data>     {\str_if_eq:nnTF{#4}{NA}
%<table-data>        {\str_if_eq:VnTF\l__gradtable_selection_value_tl{NA}
%<table-data>           {\str_if_eq:nnT{#3}{!=}{\bool_set_false:N\l__gradtable_selected_bool}}
%<table-data>           {\str_if_eq:nnT{#3}{=}{\bool_set_false:N\l__gradtable_selected_bool}}}
%<table-data>        {\str_if_eq:VnTF\l__gradtable_selection_value_tl{NA}
%<table-data>           {\bool_set_false:N\l__gradtable_selected_bool}
%<table-data>           {\gradbars@validtrue\gradbarsCheckNumber{\l__gradtable_selection_value_tl}{filter~cell}
%<table-data>            \ifgradbars@valid
%<table-data>              \str_case:nn{#3}
%<table-data>                {{=}{\fp_compare:nNnF{\l__gradtable_selection_value_tl}={#4}{\bool_set_false:N\l__gradtable_selected_bool}}
%<table-data>                 {!=}{\fp_compare:nNnT{\l__gradtable_selection_value_tl}={#4}{\bool_set_false:N\l__gradtable_selected_bool}}
%<table-data>                 {>}{\fp_compare:nNnF{\l__gradtable_selection_value_tl}>{#4}{\bool_set_false:N\l__gradtable_selected_bool}}
%<table-data>                 {<}{\fp_compare:nNnF{\l__gradtable_selection_value_tl}<{#4}{\bool_set_false:N\l__gradtable_selected_bool}}
%<table-data>                 {>=}{\fp_compare:nNnT{\l__gradtable_selection_value_tl}<{#4}{\bool_set_false:N\l__gradtable_selected_bool}}
%<table-data>                 {<=}{\fp_compare:nNnT{\l__gradtable_selection_value_tl}>{#4}{\bool_set_false:N\l__gradtable_selected_bool}}}
%<table-data>            \else\bool_set_false:N\l__gradtable_valid_bool\bool_set_false:N\l__gradtable_selected_bool\fi}}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableSortTie #1#2
%<table-data>  {\int_compare:nNnTF{#1}>{#2}{\sort_return_swapped:}{\sort_return_same:}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableSortCompare #1#2
%<table-data>  {\str_if_eq:eeTF{\prop_item:Nn\l__gradtable_sort_missing_prop{#1}}{true}
%<table-data>     {\str_if_eq:eeTF{\prop_item:Nn\l__gradtable_sort_missing_prop{#2}}{true}
%<table-data>        {\gradtableSortTie{#1}{#2}}{\sort_return_swapped:}}
%<table-data>     {\str_if_eq:eeTF{\prop_item:Nn\l__gradtable_sort_missing_prop{#2}}{true}
%<table-data>        {\sort_return_same:}
%<table-data>        {\tl_set:Nx\l_tmpa_tl{\prop_item:Nn\l__gradtable_sort_values_prop{#1}}
%<table-data>         \tl_set:Nx\l_tmpb_tl{\prop_item:Nn\l__gradtable_sort_values_prop{#2}}
%<table-data>         \str_if_eq:VnTF\l__gradtable_selection_type_tl{text}
%<table-data>           {\str_if_eq:VVTF\l_tmpa_tl\l_tmpb_tl{\gradtableSortTie{#1}{#2}}
%<table-data>              {\str_if_eq:VnTF\l__gradtable_order_tl{ascending}
%<table-data>                 {\str_compare:eNeTF{\l_tmpa_tl}>{\l_tmpb_tl}{\sort_return_swapped:}{\sort_return_same:}}
%<table-data>                 {\str_compare:eNeTF{\l_tmpa_tl}<{\l_tmpb_tl}{\sort_return_swapped:}{\sort_return_same:}}}}
%<table-data>           {\fp_compare:nNnTF{\l_tmpa_tl}={\l_tmpb_tl}{\gradtableSortTie{#1}{#2}}
%<table-data>              {\str_if_eq:VnTF\l__gradtable_order_tl{ascending}
%<table-data>                 {\fp_compare:nNnTF{\l_tmpa_tl}>{\l_tmpb_tl}{\sort_return_swapped:}{\sort_return_same:}}
%<table-data>                 {\fp_compare:nNnTF{\l_tmpa_tl}<{\l_tmpb_tl}{\sort_return_swapped:}{\sort_return_same:}}}}}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableSelectRows
%<table-data>  {\gradtablePrepareFilters
%<table-data>   \seq_clear:N\l__gradtable_selected_seq
%<table-data>   \prop_clear:N\l__gradtable_selection_rows_prop
%<table-data>   \prop_clear:N\l__gradtable_sort_values_prop\prop_clear:N\l__gradtable_sort_missing_prop
%<table-data>   \int_zero:N\l__gradtable_import_row_int
%<table-data>   \seq_map_inline:Nn\l__gradtable_data_rows_seq
%<table-data>     {\int_incr:N\l__gradtable_import_row_int
%<table-data>      \clist_set:Nn\l__gradtable_selection_cells_clist{##1}
%<table-data>      \bool_set_true:N\l__gradtable_selected_bool
%<table-data>      \seq_map_inline:Nn\l__gradtable_filters_seq
%<table-data>        {\bool_if:NT\l__gradtable_selected_bool{\gradtableApplyFilter####1}}
%<table-data>      \bool_if:NT\l__gradtable_selected_bool
%<table-data>        {\seq_put_right:Nx\l__gradtable_selected_seq{\int_use:N\l__gradtable_import_row_int}
%<table-data>         \prop_put:Nxn\l__gradtable_selection_rows_prop{\int_use:N\l__gradtable_import_row_int}{##1}}}
%<table-data>   \gradtablePrepareSortKeys
%<table-data>   \bool_if:NT\l__gradtable_valid_bool
%<table-data>     {\seq_if_empty:NF\l__gradtable_sort_keys_seq
%<table-data>        {\seq_sort:Nn\l__gradtable_selected_seq{\gradtableMultiCompare{##1}{##2}}}}
%<table-data>   \seq_clear:N\l__gradtable_rows_seq
%<table-data>   \int_zero:N\l__gradtable_row_int
%<table-data>   \seq_map_inline:Nn\l__gradtable_selected_seq
%<table-data>     {\bool_if:nT{\int_compare_p:nNn{\l__gradtable_limit_int}={0} ||
%<table-data>        \int_compare_p:nNn{\l__gradtable_row_int}<{\l__gradtable_limit_int}}
%<table-data>        {\prop_get:NnN\l__gradtable_selection_rows_prop{##1}\l_tmpa_tl
%<table-data>         \seq_put_right:NV\l__gradtable_rows_seq\l_tmpa_tl
%<table-data>         \int_incr:N\l__gradtable_row_int}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableSetPadding #1#2
%<table-data>  {\gradbars@validtrue\gradbarsCheckNumber{#2}{scale~padding}
%<table-data>   \ifgradbars@valid
%<table-data>     \fp_compare:nNnTF{#2}<{0}{\gradtableError{Scale~padding~must~be~nonnegative}}
%<table-data>       {\fp_set:Nn#1{#2}}
%<table-data>   \else\bool_set_false:N\l__gradtable_valid_bool\fi}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableAdjustRange #1
%<table-data>  {\fp_set:Nn\l__gradtable_padding_amount_fp
%<table-data>     {(\l__gradtable_max_fp-\l__gradtable_min_fp)*\prop_item:Nn\l__gradtable_scale_padding_prop{#1}/100}
%<table-data>   \bool_if:nT{\fp_compare_p:nNn{\l__gradtable_padding_amount_fp}>{0} ||
%<table-data>     \str_if_eq_p:ee{\prop_item:Nn\l__gradtable_scale_nice_prop{#1}}{true}}
%<table-data>     {\prop_put:Nnx\l__gradtable_percent_bases_prop{#1}{\fp_to_decimal:N\l__gradtable_max_fp}}
%<table-data>   \fp_compare:nNnF{\l__gradtable_min_fp}={0}
%<table-data>     {\fp_sub:Nn\l__gradtable_min_fp{\l__gradtable_padding_amount_fp}}
%<table-data>   \fp_compare:nNnF{\l__gradtable_max_fp}={0}
%<table-data>     {\fp_add:Nn\l__gradtable_max_fp{\l__gradtable_padding_amount_fp}}
%<table-data>   \str_if_eq:eeT{\prop_item:Nn\l__gradtable_scale_nice_prop{#1}}{true}
%<table-data>     {\fp_set:Nn\l__gradtable_nice_step_fp{(\l__gradtable_max_fp-\l__gradtable_min_fp)/5}
%<table-data>      \fp_set:Nn\l__gradtable_nice_power_fp{10^floor(ln(\l__gradtable_nice_step_fp)/ln(10))}
%<table-data>      \fp_set:Nn\l__gradtable_nice_step_fp{\l__gradtable_nice_step_fp/\l__gradtable_nice_power_fp}
%<table-data>      \fp_set:Nn\l__gradtable_nice_step_fp
%<table-data>        {(\l__gradtable_nice_step_fp<=1?1:(\l__gradtable_nice_step_fp<=2?2:
%<table-data>          (\l__gradtable_nice_step_fp<=5?5:10)))*\l__gradtable_nice_power_fp}
%<table-data>      \fp_set:Nn\l__gradtable_min_fp
%<table-data>        {floor(\l__gradtable_min_fp/\l__gradtable_nice_step_fp)*\l__gradtable_nice_step_fp}
%<table-data>      \fp_set:Nn\l__gradtable_max_fp
%<table-data>        {ceil(\l__gradtable_max_fp/\l__gradtable_nice_step_fp)*\l__gradtable_nice_step_fp}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableBuildSummary
%<table-data>  {\prop_clear:N\l__gradtable_summary_values_prop
%<table-data>   \tl_clear:N\l__gradtable_summary_label_id_tl
%<table-data>   \bool_if:NT\l__gradtable_summary_bool
%<table-data>     {\seq_set_eq:NN\l__gradtable_summary_rows_seq\l__gradtable_rows_seq
%<table-data>      \tl_if_empty:NF\l__gradtable_data_tl
%<table-data>        {\str_if_eq:VnT\l__gradtable_summary_scope_tl{data}
%<table-data>           {\seq_set_eq:NN\l__gradtable_summary_rows_seq\l__gradtable_data_rows_seq}}
%<table-data>      \int_zero:N\l__gradtable_summary_col_int
%<table-data>      \seq_map_inline:Nn\l__gradtable_columns_seq
%<table-data>        {\int_incr:N\l__gradtable_summary_col_int
%<table-data>         \tl_set:Nn\l__gradtable_id_tl{##1}
%<table-data>         \str_if_eq:eeT{\prop_item:Nn\l__gradtable_types_prop{##1}}{text}
%<table-data>           {\tl_if_empty:NT\l__gradtable_summary_label_id_tl
%<table-data>              {\tl_set:Nn\l__gradtable_summary_label_id_tl{##1}}}
%<table-data>         \prop_get:NnN\l__gradtable_aggregates_prop{##1}\l__gradtable_aggregate_tl
%<table-data>         \str_if_eq:VnF\l__gradtable_aggregate_tl{none}{\gradtableAggregateColumn{##1}}}
%<table-data>      \tl_if_empty:NF\l__gradtable_summary_label_tl
%<table-data>        {\tl_if_empty:NT\l__gradtable_summary_label_id_tl
%<table-data>           {\gradtableError{A~summary~label~requires~a~text~column}}}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableAggregateColumn #1
%<table-data>  {\int_zero:N\l__gradtable_summary_count_int\fp_zero:N\l__gradtable_summary_sum_fp
%<table-data>   \seq_map_inline:Nn\l__gradtable_summary_rows_seq
%<table-data>     {\clist_set:Nn\l__gradtable_cells_clist{##1}
%<table-data>      \tl_set:Nx\l__gradtable_summary_value_tl
%<table-data>        {\clist_item:Nn\l__gradtable_cells_clist{\l__gradtable_summary_col_int}}
%<table-data>      \tl_trim_spaces:N\l__gradtable_summary_value_tl
%<table-data>      \tl_if_empty:NF\l__gradtable_summary_value_tl
%<table-data>        {\str_if_eq:VnF\l__gradtable_summary_value_tl{NA}
%<table-data>           {\gradbars@validtrue\gradbarsCheckNumber{\l__gradtable_summary_value_tl}{aggregate~value}
%<table-data>            \ifgradbars@valid
%<table-data>              \int_incr:N\l__gradtable_summary_count_int
%<table-data>              \fp_add:Nn\l__gradtable_summary_sum_fp{\l__gradtable_summary_value_tl}
%<table-data>              \int_compare:nNnTF{\l__gradtable_summary_count_int}={1}
%<table-data>                {\fp_set:Nn\l__gradtable_summary_min_fp{\l__gradtable_summary_value_tl}
%<table-data>                 \fp_set_eq:NN\l__gradtable_summary_max_fp\l__gradtable_summary_min_fp}
%<table-data>                {\fp_set:Nn\l__gradtable_summary_min_fp{min(\l__gradtable_summary_min_fp,\l__gradtable_summary_value_tl)}
%<table-data>                 \fp_set:Nn\l__gradtable_summary_max_fp{max(\l__gradtable_summary_max_fp,\l__gradtable_summary_value_tl)}}
%<table-data>            \else\bool_set_false:N\l__gradtable_valid_bool\fi}}}
%<table-data>   \tl_set:Nn\l__gradtable_summary_value_tl{NA}
%<table-data>   \str_case:Vn\l__gradtable_aggregate_tl
%<table-data>     {{count}{\tl_set:Nx\l__gradtable_summary_value_tl{\int_use:N\l__gradtable_summary_count_int}}
%<table-data>      {sum}{\tl_set:Nx\l__gradtable_summary_value_tl{\fp_to_decimal:N\l__gradtable_summary_sum_fp}}}
%<table-data>   \int_compare:nNnT{\l__gradtable_summary_count_int}>{0}
%<table-data>     {\str_case:Vn\l__gradtable_aggregate_tl
%<table-data>        {{mean}{\tl_set:Nx\l__gradtable_summary_value_tl
%<table-data>           {\fp_eval:n{\l__gradtable_summary_sum_fp/\l__gradtable_summary_count_int}}}
%<table-data>         {min}{\tl_set:Nx\l__gradtable_summary_value_tl{\fp_to_decimal:N\l__gradtable_summary_min_fp}}
%<table-data>         {max}{\tl_set:Nx\l__gradtable_summary_value_tl{\fp_to_decimal:N\l__gradtable_summary_max_fp}}}}
%<table-data>   \prop_put:NnV\l__gradtable_summary_values_prop{#1}\l__gradtable_summary_value_tl}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_eq:NN\gradtableValidateSelectionBeforeSeven\gradtableValidateSelection
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_set_protected:Npn\gradtableValidateSelection
%<table-data>  {\gradtableValidateSelectionBeforeSeven
%<table-data>   \tl_if_empty:NT\l__gradtable_data_tl
%<table-data>     {\bool_if:nT{!\tl_if_empty_p:N\l__gradtable_sort_keys_tl || !\tl_if_empty_p:N\l__gradtable_group_by_tl}
%<table-data>        {\gradtableError{Sort~keys~and~group~by~require~a~CSV~data~source}}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtablePrepareSortKeys
%<table-data>  {\seq_clear:N\l__gradtable_sort_keys_seq
%<table-data>   \tl_if_empty:NTF\l__gradtable_sort_keys_tl
%<table-data>     {\tl_if_empty:NF\l__gradtable_sort_tl
%<table-data>        {\tl_set_eq:NN\l__gradtable_sort_id_tl\l__gradtable_sort_tl
%<table-data>         \tl_set_eq:NN\l__gradtable_sort_direction_tl\l__gradtable_order_tl
%<table-data>         \gradtableAddSortKey}}
%<table-data>     {\tl_if_empty:NF\l__gradtable_sort_tl{\gradtableError{Use~sort~or~sort~keys,~not~both}}
%<table-data>      \clist_map_inline:Vn\l__gradtable_sort_keys_tl
%<table-data>        {\seq_set_split:Nnn\l__gradtable_sort_parts_seq{/}{##1}
%<table-data>         \int_compare:nNnTF{\seq_count:N\l__gradtable_sort_parts_seq}={2}
%<table-data>           {\tl_set:Nx\l__gradtable_sort_id_tl{\seq_item:Nn\l__gradtable_sort_parts_seq{1}}
%<table-data>            \tl_set:Nx\l__gradtable_sort_direction_tl{\seq_item:Nn\l__gradtable_sort_parts_seq{2}}
%<table-data>            \tl_trim_spaces:N\l__gradtable_sort_id_tl\tl_trim_spaces:N\l__gradtable_sort_direction_tl
%<table-data>            \str_case:VnF\l__gradtable_sort_direction_tl{{ascending}{}{descending}{}}
%<table-data>              {\gradtableError{Sort~key~direction~must~be~ascending~or~descending}}
%<table-data>            \gradtableAddSortKey}
%<table-data>           {\gradtableError{Sort~keys~require~column/direction}}}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableAddSortKey
%<table-data>  {\exp_args:NV\gradtableSelectionType\l__gradtable_sort_id_tl
%<table-data>   \exp_args:NV\gradtableColumnIndex\l__gradtable_sort_id_tl
%<table-data>   \bool_if:NT\l__gradtable_valid_bool
%<table-data>     {\seq_put_right:Nx\l__gradtable_sort_keys_seq
%<table-data>        {{\int_use:N\l__gradtable_selection_col_int}{\exp_not:V\l__gradtable_selection_type_tl}
%<table-data>         {\exp_not:V\l__gradtable_sort_direction_tl}}
%<table-data>      \seq_map_inline:Nn\l__gradtable_selected_seq
%<table-data>        {\clist_set:Nx\l__gradtable_selection_cells_clist{\prop_item:Nn\l__gradtable_selection_rows_prop{##1}}
%<table-data>         \gradtableSelectionValue{\l__gradtable_selection_col_int}
%<table-data>         \str_if_eq:VnF\l__gradtable_selection_type_tl{text}
%<table-data>           {\bool_if:nF{\tl_if_empty_p:N\l__gradtable_selection_value_tl || \str_if_eq_p:Vn\l__gradtable_selection_value_tl{NA}}
%<table-data>              {\gradbars@validtrue\gradbarsCheckNumber{\l__gradtable_selection_value_tl}{sort~cell}
%<table-data>               \ifgradbars@valid\else\bool_set_false:N\l__gradtable_valid_bool\fi}}}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableMultiCompare #1#2
%<table-data>  {\clist_set:Nx\l__gradtable_sort_left_clist{\prop_item:Nn\l__gradtable_selection_rows_prop{#1}}
%<table-data>   \clist_set:Nx\l__gradtable_sort_right_clist{\prop_item:Nn\l__gradtable_selection_rows_prop{#2}}
%<table-data>   \int_zero:N\l__gradtable_compare_int
%<table-data>   \seq_map_inline:Nn\l__gradtable_sort_keys_seq
%<table-data>     {\gradtableCompareKey##1
%<table-data>      \int_compare:nNnF{\l__gradtable_compare_int}={0}{\seq_map_break:}}
%<table-data>   \int_compare:nNnTF{\l__gradtable_compare_int}={0}{\gradtableSortTie{#1}{#2}}
%<table-data>     {\int_compare:nNnTF{\l__gradtable_compare_int}>{0}{\sort_return_swapped:}{\sort_return_same:}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableCompareKey #1#2#3
%<table-data>  {\tl_set:Nx\l__gradtable_sort_left_tl{\clist_item:Nn\l__gradtable_sort_left_clist{#1}}
%<table-data>   \tl_set:Nx\l__gradtable_sort_right_tl{\clist_item:Nn\l__gradtable_sort_right_clist{#1}}
%<table-data>   \tl_trim_spaces:N\l__gradtable_sort_left_tl\tl_trim_spaces:N\l__gradtable_sort_right_tl
%<table-data>   \bool_set:Nn\l__gradtable_sort_left_missing_bool{\tl_if_empty_p:N\l__gradtable_sort_left_tl}
%<table-data>   \bool_set:Nn\l__gradtable_sort_right_missing_bool{\tl_if_empty_p:N\l__gradtable_sort_right_tl}
%<table-data>   \str_if_eq:nnF{#2}{text}
%<table-data>     {\str_if_eq:VnT\l__gradtable_sort_left_tl{NA}{\bool_set_true:N\l__gradtable_sort_left_missing_bool}
%<table-data>      \str_if_eq:VnT\l__gradtable_sort_right_tl{NA}{\bool_set_true:N\l__gradtable_sort_right_missing_bool}}
%<table-data>   \bool_if:NTF\l__gradtable_sort_left_missing_bool
%<table-data>     {\bool_if:NF\l__gradtable_sort_right_missing_bool{\int_set:Nn\l__gradtable_compare_int{1}}}
%<table-data>     {\bool_if:NTF\l__gradtable_sort_right_missing_bool{\int_set:Nn\l__gradtable_compare_int{-1}}
%<table-data>        {\str_if_eq:nnTF{#2}{text}
%<table-data>           {\str_if_eq:VVF\l__gradtable_sort_left_tl\l__gradtable_sort_right_tl
%<table-data>              {\str_compare:eNeTF{\l__gradtable_sort_left_tl}>{\l__gradtable_sort_right_tl}
%<table-data>                 {\int_set:Nn\l__gradtable_compare_int{1}}{\int_set:Nn\l__gradtable_compare_int{-1}}}}
%<table-data>           {\fp_compare:nNnF{\l__gradtable_sort_left_tl}={\l__gradtable_sort_right_tl}
%<table-data>              {\fp_compare:nNnTF{\l__gradtable_sort_left_tl}>{\l__gradtable_sort_right_tl}
%<table-data>                 {\int_set:Nn\l__gradtable_compare_int{1}}{\int_set:Nn\l__gradtable_compare_int{-1}}}}
%<table-data>         \str_if_eq:nnT{#3}{descending}{\int_set:Nn\l__gradtable_compare_int{-\l__gradtable_compare_int}}}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableNewDataGroup
%<table-data>  {\int_incr:N\l__gradtable_group_count_int
%<table-data>   \tl_set:Nx\l__gradtable_group_id_tl{\int_use:N\l__gradtable_group_count_int}
%<table-data>   \prop_put:NVV\l__gradtable_group_ids_prop\l__gradtable_group_key_tl\l__gradtable_group_id_tl
%<table-data>   \tl_if_empty:NTF\l__gradtable_group_key_tl
%<table-data>     {\prop_put:NVV\l__gradtable_group_labels_prop\l__gradtable_group_id_tl\l__gradtable_group_missing_label_tl}
%<table-data>     {\prop_put:NVV\l__gradtable_group_labels_prop\l__gradtable_group_id_tl\l__gradtable_group_key_tl}
%<table-data>   \seq_clear_new:c{l__gradtable_group_\l__gradtable_group_id_tl _seq}
%<table-data>   \seq_clear_new:c{l__gradtable_group_data_\l__gradtable_group_id_tl _seq}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableReadGroupKey #1
%<table-data>  {\clist_set:Nn\l__gradtable_cells_clist{#1}
%<table-data>   \tl_set:Nx\l__gradtable_group_key_tl{\clist_item:Nn\l__gradtable_cells_clist{\l__gradtable_group_col_int}}
%<table-data>   \tl_trim_spaces:N\l__gradtable_group_key_tl}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_protected:Npn\gradtableBuildGroups
%<table-data>  {\prop_clear:N\l__gradtable_group_ids_prop\prop_clear:N\l__gradtable_group_labels_prop
%<table-data>   \prop_clear:N\l__gradtable_row_groups_prop\prop_clear:N\l__gradtable_group_ends_prop
%<table-data>   \int_zero:N\l__gradtable_group_count_int
%<table-data>   \tl_if_empty:NTF\l__gradtable_group_by_tl
%<table-data>     {\bool_if:nT{\l__gradtable_group_summary_bool || \str_if_eq_p:Vn\l__gradtable_rank_scope_tl{group}}
%<table-data>        {\prop_if_empty:NT\l__gradtable_groups_prop{\gradtableError{Group~statistics~require~group~by~or~gradgroup}}
%<table-data>         \seq_set_eq:NN\l__gradtable_group_input_seq\l__gradtable_rows_seq
%<table-data>         \int_zero:N\l__gradtable_row_int
%<table-data>         \seq_map_inline:Nn\l__gradtable_group_input_seq
%<table-data>           {\int_incr:N\l__gradtable_row_int
%<table-data>            \prop_get:NxNTF\l__gradtable_groups_prop{\int_use:N\l__gradtable_row_int}\l__gradtable_group_key_tl
%<table-data>              {\gradtableNewDataGroup}
%<table-data>              {\int_compare:nNnT{\l__gradtable_group_count_int}={0}
%<table-data>                 {\tl_clear:N\l__gradtable_group_key_tl\gradtableNewDataGroup
%<table-data>                  \prop_put:NxV\l__gradtable_groups_prop{1}\l__gradtable_group_missing_label_tl}}
%<table-data>            \seq_put_right:cn{l__gradtable_group_\l__gradtable_group_id_tl _seq}{##1}
%<table-data>            \seq_put_right:cn{l__gradtable_group_data_\l__gradtable_group_id_tl _seq}{##1}
%<table-data>            \prop_put:NxV\l__gradtable_row_groups_prop{\int_use:N\l__gradtable_row_int}\l__gradtable_group_id_tl
%<table-data>            \prop_put:Nxx\l__gradtable_group_ends_prop{\int_use:N\l__gradtable_row_int}{\l__gradtable_group_id_tl}
%<table-data>            \prop_remove:Nx\l__gradtable_group_ends_prop{\int_eval:n{\l__gradtable_row_int-1}}
%<table-data>            \prop_if_in:NxT\l__gradtable_groups_prop{\int_use:N\l__gradtable_row_int}
%<table-data>              {\int_compare:nNnT{\l__gradtable_row_int}>{1}
%<table-data>                 {\prop_put:Nxx\l__gradtable_group_ends_prop{\int_eval:n{\l__gradtable_row_int-1}}{\int_eval:n{\l__gradtable_group_count_int-1}}}}}}}
%<table-data>     {\prop_if_empty:NF\l__gradtable_groups_prop{\gradtableError{Do~not~combine~group~by~with~gradgroup}}
%<table-data>      \exp_args:NV\gradtableSelectionType\l__gradtable_group_by_tl
%<table-data>      \str_if_eq:VnF\l__gradtable_selection_type_tl{text}{\gradtableError{Group~by~requires~a~text~column}}
%<table-data>      \exp_args:NV\gradtableColumnIndex\l__gradtable_group_by_tl
%<table-data>      \int_set_eq:NN\l__gradtable_group_col_int\l__gradtable_selection_col_int
%<table-data>      \bool_if:NT\l__gradtable_valid_bool
%<table-data>        {\seq_map_inline:Nn\l__gradtable_data_rows_seq
%<table-data>           {\gradtableReadGroupKey{##1}
%<table-data>            \prop_get:NVNTF\l__gradtable_group_ids_prop\l__gradtable_group_key_tl\l__gradtable_group_id_tl
%<table-data>              {}{\gradtableNewDataGroup}
%<table-data>            \seq_put_right:cn{l__gradtable_group_data_\l__gradtable_group_id_tl _seq}{##1}}
%<table-data>         \seq_map_inline:Nn\l__gradtable_rows_seq
%<table-data>           {\gradtableReadGroupKey{##1}
%<table-data>            \prop_get:NVN\l__gradtable_group_ids_prop\l__gradtable_group_key_tl\l__gradtable_group_id_tl
%<table-data>            \seq_put_right:cn{l__gradtable_group_\l__gradtable_group_id_tl _seq}{##1}}
%<table-data>         \seq_clear:N\l__gradtable_rows_seq\prop_clear:N\l__gradtable_groups_prop
%<table-data>         \int_zero:N\l__gradtable_row_int
%<table-data>         \int_step_inline:nn{\l__gradtable_group_count_int}
%<table-data>           {\seq_if_empty:cF{l__gradtable_group_##1_seq}
%<table-data>              {\prop_get:NnN\l__gradtable_group_labels_prop{##1}\l__gradtable_group_key_tl
%<table-data>               \prop_put:NxV\l__gradtable_groups_prop{\int_eval:n{\l__gradtable_row_int+1}}\l__gradtable_group_key_tl
%<table-data>               \seq_map_inline:cn{l__gradtable_group_##1_seq}
%<table-data>                 {\seq_put_right:Nn\l__gradtable_rows_seq{####1}\int_incr:N\l__gradtable_row_int
%<table-data>                  \prop_put:Nxn\l__gradtable_row_groups_prop{\int_use:N\l__gradtable_row_int}{##1}}
%<table-data>               \prop_put:Nxn\l__gradtable_group_ends_prop{\int_use:N\l__gradtable_row_int}{##1}}}}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_eq:NN\gradtableRankBeforeSeven\gradtableRank
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_set_protected:Npn\gradtableRank
%<table-data>  {\gradtableRankBeforeSeven
%<table-data>   \prop_clear:N\l__gradtable_group_best_prop\prop_clear:N\l__gradtable_group_second_prop
%<table-data>   \str_if_eq:VnT\l__gradtable_rank_scope_tl{group}
%<table-data>     {\int_step_inline:nn{\l__gradtable_group_count_int}
%<table-data>        {\group_begin:\seq_set_eq:Nc\l__gradtable_rows_seq{l__gradtable_group_##1_seq}
%<table-data>         \gradtableRankBeforeSeven\prop_gset_eq:NN\g__gradtable_group_result_prop\l__gradtable_best_prop
%<table-data>         \group_end:
%<table-data>         \prop_map_inline:Nn\g__gradtable_group_result_prop
%<table-data>           {\prop_put:Nnn\l__gradtable_group_best_prop{##1/####1}{####2}}
%<table-data>         \group_begin:\seq_set_eq:Nc\l__gradtable_rows_seq{l__gradtable_group_##1_seq}
%<table-data>         \gradtableRankBeforeSeven\prop_gset_eq:NN\g__gradtable_group_result_prop\l__gradtable_second_prop
%<table-data>         \group_end:
%<table-data>         \prop_map_inline:Nn\g__gradtable_group_result_prop
%<table-data>           {\prop_put:Nnn\l__gradtable_group_second_prop{##1/####1}{####2}}}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_new_eq:NN\gradtableBuildSummaryBeforeSeven\gradtableBuildSummary
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOn
%<table-data>\cs_set_protected:Npn\gradtableBuildSummary
%<table-data>  {\gradtableBuildSummaryBeforeSeven
%<table-data>   \prop_clear:N\l__gradtable_group_summary_values_prop
%<table-data>   \bool_if:NT\l__gradtable_group_summary_bool
%<table-data>     {\int_step_inline:nn{\l__gradtable_group_count_int}
%<table-data>        {\seq_if_empty:cF{l__gradtable_group_##1_seq}
%<table-data>           {\group_begin:\bool_set_true:N\l__gradtable_summary_bool
%<table-data>            \tl_set_eq:NN\l__gradtable_summary_label_tl\l__gradtable_group_summary_label_tl
%<table-data>            \tl_set_eq:NN\l__gradtable_summary_scope_tl\l__gradtable_group_summary_scope_tl
%<table-data>            \seq_set_eq:Nc\l__gradtable_rows_seq{l__gradtable_group_##1_seq}
%<table-data>            \seq_set_eq:Nc\l__gradtable_data_rows_seq{l__gradtable_group_data_##1_seq}
%<table-data>            \gradtableBuildSummaryBeforeSeven
%<table-data>            \prop_gset_eq:NN\g__gradtable_group_result_prop\l__gradtable_summary_values_prop
%<table-data>            \group_end:
%<table-data>            \prop_map_inline:Nn\g__gradtable_group_result_prop
%<table-data>              {\prop_put:Nnn\l__gradtable_group_summary_values_prop{##1/####1}{####2}}}}}}
%<table-data>\ExplSyntaxOff
%<table-data>\ExplSyntaxOff
%<table-data>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-table-layout.sty}}
%    \begin{macrocode}
%<table-layout>% Author: SuFan; MIT License. Private table layout layer.
%<table-layout>\ProvidesPackage{gradbars-table-layout}[2026/10/25 v1.1.0 gradbars table layout]
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn \gradtableConfigure #1
%<table-layout>  {\prop_get:NnN \l__gradtable_types_prop {#1}\l__gradtable_type_tl
%<table-layout>   \prop_get:NnN \l__gradtable_options_prop {#1}\l__gradtable_options_tl
%<table-layout>   \pgfkeys{/gradbars,scale~group={},preset=paper,fill=solid,precision=1,overflow~mark=arrow}
%<table-layout>   \str_case:Vn \l__gradtable_preset_tl
%<table-layout>     {{report}{\pgfkeys{/gradbars,preset=report}}
%<table-layout>      {mono}{\pgfkeys{/gradbars,theme=gray,print}}}
%<table-layout>   \gradtableConfigureTheme
%<table-layout>   \pgfkeys{/gradbars,width=\l__gradtable_graphic_dim}
%<table-layout>   \str_if_eq:VnT\l__gradtable_type_tl{heat}{\pgfkeys{/gradbars,height=3ex}}
%<table-layout>   \prop_get:NnN\l__gradtable_formatters_prop{#1}\l_tmpa_tl
%<table-layout>   \pgfkeys{/gradbars,unit~code={},unit~text={},formatter/.expand~once=\l_tmpa_tl}
%<table-layout>   \prop_get:NnN\l__gradtable_number_align_prop{#1}\l__gradtable_number_align_tl
%<table-layout>   \exp_args:NV \gradbarssetup \l__gradtable_options_tl
%<table-layout>   \gradbarsValidateFormatter
%<table-layout>   \prop_get:NnN\l__gradtable_scale_groups_prop{#1}\l_tmpa_tl
%<table-layout>   \tl_if_empty:NF\l_tmpa_tl{\pgfkeys{/gradbars/scale~group/.expand~once=\l_tmpa_tl}}
%<table-layout>   \tl_if_empty:oF{\gradbars@scalegroup}
%<table-layout>     {\str_if_eq:eeT{\prop_item:Nn\l__gradtable_scales_prop{#1}}{column}
%<table-layout>        {\gradtableError{Scale~group~requires~scale=fixed}}}
%<table-layout>   \prop_get:NnNT\l__gradtable_ranges_prop{#1}\l_tmpa_tl
%<table-layout>     {\exp_args:NV\gradbarssetup\l_tmpa_tl}
%<table-layout>   \tl_if_empty:oT{\gradbars@percentbase}
%<table-layout>     {\prop_get:NnNT\l__gradtable_percent_bases_prop{#1}\l_tmpa_tl
%<table-layout>        {\pgfkeys{/gradbars/percent~base/.expand~once=\l_tmpa_tl}}}
%<table-layout>   \gradbarsResolveScaleGroup
%<table-layout>   \prop_get:NnNT\l__gradtable_plots_prop{#1}\l_tmpa_tl
%<table-layout>     {\pgfkeys{/gradbars/width/.expand~once=\l_tmpa_tl}}
%<table-layout>   \pgfkeys{/gradbars,label=outside,label~width=\prop_item:Nn\l__gradtable_widths_prop{#1}}
%<table-layout>   \str_if_eq:VnT\l__gradtable_type_tl{heat}
%<table-layout>     {\dim_compare:nNnT{\prop_item:Nn\l__gradtable_colwidth_prop{#1}}>{0pt}
%<table-layout>        {\pgfkeys{/gradbars,width=\prop_item:Nn\l__gradtable_colwidth_prop{#1}}}
%<table-layout>      \pgfkeys{/gradbars,label=inside}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn \gradtableNumber #1
%<table-layout>  {\tl_set:Nn \l_tmpa_tl {#1}\tl_trim_spaces:N \l_tmpa_tl
%<table-layout>   \str_if_eq:VnTF \l_tmpa_tl {NA}
%<table-layout>     {\gradbars@missingtext}
%<table-layout>     {\gradbars@validtrue\gradbarsCheckNumber{#1}{table~number}
%<table-layout>      \tl_set:Nx \l_tmpa_tl {\gradbars@precision}
%<table-layout>      \regex_match:nVTF {\A [0-6] \Z} \l_tmpa_tl {}
%<table-layout>        {\gradbarsFail{Precision~must~be~an~integer~from~0~to~6}}
%<table-layout>      \str_if_eq:eeT {\gradbars@format}{percent}
%<table-layout>        {\gradbarsCheckNumber{\gradbars@max}{max}
%<table-layout>         \ifgradbars@valid\fp_compare:nNnF {\gradbars@max}>{0}
%<table-layout>           {\gradbarsFail{Percent~format~requires~positive~max}}\fi\gradbarsValidatePercentBase}
%<table-layout>      \ifgradbars@valid
%<table-layout>        \gradbars@missingfalse\def\gradbars@value{#1}
%<table-layout>        \gradbarsFormatEndpoint{#1}
%<table-layout>      \fi}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn \gradtableContent #1
%<table-layout>  {\str_case:Vn \l__gradtable_type_tl
%<table-layout>    {{text}{#1}
%<table-layout>     {number}{\gradtableNumber{#1}}
%<table-layout>     {bar}{\gradbar{#1}}
%<table-layout>     {bullet}{\gradbullet{#1}}
%<table-layout>     {heat}{\gradbarsHeatCell{}{#1}}
%<table-layout>     {compare}{\gradtablePair{\gradcompare}{#1}}
%<table-layout>     {dumbbell}{\gradtablePair{\graddumbbell}{#1}}
%<table-layout>     {stack}{\str_if_eq:nnTF{#1}{NA}{\gradbar{NA}}{\gradstack{#1}}}
%<table-layout>     {boxplot}{\gradboxplot[box~range=fixed]{#1}}
%<table-layout>     {spark}{\gradspark{#1}}
%<table-layout>     {interval}{\str_if_eq:nnTF {#1}{NA}
%<table-layout>       {\gradrange{NA}{NA}}
%<table-layout>       {\seq_set_split:Nnn \l__gradtable_interval_seq {/}{#1}
%<table-layout>        \int_compare:nNnTF {\seq_count:N\l__gradtable_interval_seq} = {3}
%<table-layout>          {\tl_set:Nx \l_tmpa_tl {\seq_item:Nn\l__gradtable_interval_seq{2}}
%<table-layout>           \str_if_eq:VnT \l_tmpa_tl {NA}{\tl_clear:N\l_tmpa_tl}
%<table-layout>           \pgfkeys{/gradbars/range~point/.expand~once=\l_tmpa_tl}
%<table-layout>           \exp_args:Nee \gradrange
%<table-layout>             {\seq_item:Nn\l__gradtable_interval_seq{1}}
%<table-layout>             {\seq_item:Nn\l__gradtable_interval_seq{3}}}
%<table-layout>          {\gradbarsFail{Interval~requires~lower/point/upper}}}}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn \gradtableMeasure #1#2
%<table-layout>  {\group_begin:
%<table-layout>   \gradbarsSuspendMeasurementTagging
%<table-layout>   \tl_set:Nn \l__gradtable_id_tl {#1}
%<table-layout>   \gradtableConfigure{#1}
%<table-layout>   \gradtableHighlight{#1}{#2}
%<table-layout>   \cs_set_eq:NN \gradtableSavedPackageError \PackageError
%<table-layout>   \cs_set_protected:Npn \PackageError ##1##2##3
%<table-layout>     {\gradtableSavedPackageError{##1}
%<table-layout>       {Table~row~\int_use:N\l__gradtable_row_int,~column~#1:~##2}{##3}}
%<table-layout>   \dim_gset:Nn \g__gradtable_measured_dim {\prop_item:Nn\l__gradtable_widths_prop{#1}}
%<table-layout>   \cs_set_eq:NN \gradtableSavedLabel \gradbarsDrawMainLabel
%<table-layout>   \cs_set_protected:Npn \gradbarsDrawMainLabel
%<table-layout>     {\gradbarsMeasure\gradbars@labelbox\gradbars@font{\gradbars@labelcontent}
%<table-layout>      \dim_gset:Nn \g__gradtable_measured_dim
%<table-layout>        {\dim_max:nn{\g__gradtable_measured_dim}{\wd\gradbars@labelbox}}
%<table-layout>      \gradtableSavedLabel}
%<table-layout>   \hbox_set:Nn \l__gradtable_measure_box {\gradtableContent{#2}}
%<table-layout>   \str_if_eq:VnT \l__gradtable_type_tl {number}
%<table-layout>     {\dim_gset:Nn \g__gradtable_measured_dim
%<table-layout>       {\dim_max:nn{\g__gradtable_measured_dim}{\box_wd:N\l__gradtable_measure_box}}}
%<table-layout>   \gradbarsResumeMeasurementTagging
%<table-layout>   \group_end:
%<table-layout>   \prop_put:Nnx \l__gradtable_widths_prop {#1}{\dim_use:N\g__gradtable_measured_dim}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn \gradtableCell #1#2
%<table-layout>  {\group_begin:\tl_set:Nn\l__gradtable_id_tl{#1}\gradtableConfigure{#1}
%<table-layout>   \gradtableHighlight{#1}{#2}
%<table-layout>   \str_if_eq:VnTF \l__gradtable_type_tl {number}
%<table-layout>     {\makebox[\dim_max:nn{\prop_item:Nn\l__gradtable_widths_prop{#1}}{\prop_item:Nn\l__gradtable_colwidth_prop{#1}}]
%<table-layout>       [\prop_item:Nn\l__gradtable_align_prop{#1}]{\gradtableContent{#2}}}
%<table-layout>     {\str_if_eq:VnTF\l__gradtable_type_tl{text}{\gradtableContent{#2}}
%<table-layout>        {\hbox_set:Nn\l__gradtable_measure_box{\gradtableContent{#2}}
%<table-layout>         \dim_compare:nNnT{\l__gradtable_total_dim}>{0pt}
%<table-layout>           {\dim_compare:nNnT{\box_wd:N\l__gradtable_measure_box}
%<table-layout>              >{\prop_item:Nn\l__gradtable_colwidth_prop{#1}+.2pt}
%<table-layout>              {\gradtableError{Graphic~exceeds~allocated~column;~increase~width~or~simplify~labels}}}
%<table-layout>         \makebox[\dim_max:nn{\box_wd:N\l__gradtable_measure_box}{\prop_item:Nn\l__gradtable_colwidth_prop{#1}}]
%<table-layout>           [\prop_item:Nn\l__gradtable_align_prop{#1}]{\box_use:N\l__gradtable_measure_box}}}
%<table-layout>   \group_end:}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new:Npn\gradtableAlignCode #1
%<table-layout>  {\str_case:nn{#1}{{l}{\raggedright}{c}{\centering}{r}{\raggedleft}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new:Npn\gradtableVerticalCode #1
%<table-layout>  {\str_case:nn{#1}{{t}{p}{c}{m}{b}{b}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn \gradtableRender
%<table-layout>  {\gradtableBuildGroups
%<table-layout>   \gradtableAutoRanges
%<table-layout>   \tl_use:N\l__gradtable_font_tl
%<table-layout>   \gradtableBuildSummary
%<table-layout>   \gradtableRank
%<table-layout>   \gradtableScan
%<table-layout>   \gradtableMeasureSummary
%<table-layout>   \dim_compare:nNnT{\l__gradtable_total_dim}>{0pt}{\gradtableAllocate}
%<table-layout>   \tl_set:Nn\l__gradtable_preamble_tl{@{}}
%<table-layout>   \tl_clear:N\l__gradtable_body_tl
%<table-layout>   \str_case:Vn\l__gradtable_rules_tl
%<table-layout>     {{booktabs}{\tl_set:Nn\l__gradtable_body_tl{\toprule}}
%<table-layout>      {rows}{\tl_set:Nn\l__gradtable_body_tl{\toprule}}
%<table-layout>      {grid}{\tl_set:Nn\l__gradtable_body_tl{\hline}\tl_set:Nn\l__gradtable_preamble_tl{|}}}
%<table-layout>   \gradtableBuildHeaders
%<table-layout>   \int_zero:N\l__gradtable_col_int
%<table-layout>   \seq_map_inline:Nn \l__gradtable_columns_seq
%<table-layout>     {\int_incr:N\l__gradtable_col_int
%<table-layout>      \int_compare:nNnT{\l__gradtable_col_int}>{1}{\tl_put_right:Nn\l__gradtable_body_tl{&}}
%<table-layout>      \bool_if:nTF{\dim_compare_p:nNn{\l__gradtable_total_dim}>{0pt} ||
%<table-layout>        \str_if_eq_p:ee{\prop_item:Nn\l__gradtable_types_prop{##1}}{text}}
%<table-layout>        {\tl_put_right:Nx\l__gradtable_preamble_tl
%<table-layout>          {>{\exp_not:N\gradtableAlignCode{\prop_item:Nn\l__gradtable_align_prop{##1}}\exp_not:N\arraybackslash}
%<table-layout>           \str_if_eq:eeTF{\prop_item:Nn\l__gradtable_types_prop{##1}}{text}
%<table-layout>             {\exp_args:Ne\gradtableVerticalCode{\prop_item:Nn\l__gradtable_valign_prop{##1}}}{p}
%<table-layout>           {\prop_item:Nn\l__gradtable_colwidth_prop{##1}}}}
%<table-layout>        {\tl_put_right:Nx\l__gradtable_preamble_tl{\prop_item:Nn\l__gradtable_align_prop{##1}}}
%<table-layout>      \str_if_eq:VnT\l__gradtable_rules_tl{grid}{\tl_put_right:Nn\l__gradtable_preamble_tl{|}}
%<table-layout>      \tl_clear:N\l__gradtable_header_spec_tl
%<table-layout>      \str_if_eq:VnTF\l__gradtable_rules_tl{grid}
%<table-layout>        {\int_compare:nNnT{\l__gradtable_col_int}={1}{\tl_put_right:Nn\l__gradtable_header_spec_tl{|}}}
%<table-layout>        {\int_compare:nNnT{\l__gradtable_col_int}={1}{\tl_put_right:Nn\l__gradtable_header_spec_tl{@{}}}}
%<table-layout>      \tl_if_empty:NF\l__gradtable_header_color_tl
%<table-layout>        {\dim_set_eq:NN\l_tmpa_dim\l__gradtable_sep_dim
%<table-layout>         \dim_set_eq:NN\l_tmpb_dim\l__gradtable_sep_dim
%<table-layout>         \str_if_eq:VnTF\l__gradtable_rules_tl{grid}
%<table-layout>           {\dim_set:Nn\l_tmpa_dim{\dim_max:nn{0pt}{\l_tmpa_dim-\arrayrulewidth}}
%<table-layout>            \dim_set_eq:NN\l_tmpb_dim\l_tmpa_dim}
%<table-layout>           {\int_compare:nNnT{\l__gradtable_col_int}={1}{\dim_zero:N\l_tmpa_dim}
%<table-layout>            \int_compare:nNnT{\l__gradtable_col_int}={\seq_count:N\l__gradtable_columns_seq}{\dim_zero:N\l_tmpb_dim}}
%<table-layout>         \tl_put_right:Nx\l__gradtable_header_spec_tl
%<table-layout>           {>{\exp_not:N\columncolor{\exp_not:V\l__gradtable_header_color_tl}
%<table-layout>             [\dim_use:N\l_tmpa_dim][\dim_use:N\l_tmpb_dim]}}}
%<table-layout>      \bool_if:nTF{\dim_compare_p:nNn{\l__gradtable_total_dim}>{0pt} ||
%<table-layout>        \str_if_eq_p:ee{\prop_item:Nn\l__gradtable_types_prop{##1}}{text}}
%<table-layout>        {\tl_put_right:Nx\l__gradtable_header_spec_tl
%<table-layout>          {>{\exp_not:N\gradtableAlignCode{\prop_item:Nn\l__gradtable_headalign_prop{##1}}\exp_not:N\arraybackslash}
%<table-layout>           p{\prop_item:Nn\l__gradtable_colwidth_prop{##1}}}}
%<table-layout>        {\tl_put_right:Nx\l__gradtable_header_spec_tl{\prop_item:Nn\l__gradtable_headalign_prop{##1}}}
%<table-layout>      \str_if_eq:VnTF\l__gradtable_rules_tl{grid}
%<table-layout>        {\tl_put_right:Nn\l__gradtable_header_spec_tl{|}}
%<table-layout>        {\int_compare:nNnT{\l__gradtable_col_int}={\seq_count:N\l__gradtable_columns_seq}
%<table-layout>          {\tl_put_right:Nn\l__gradtable_header_spec_tl{@{}}}}
%<table-layout>      \tl_put_right:Nx\l__gradtable_body_tl
%<table-layout>        {\exp_not:N\multicolumn{1}{\exp_not:V\l__gradtable_header_spec_tl}
%<table-layout>          {\exp_not:N\gradtableHeader{##1}}}}
%<table-layout>   \str_if_eq:VnF\l__gradtable_rules_tl{grid}{\tl_put_right:Nn\l__gradtable_preamble_tl{@{}}}
%<table-layout>   \tl_put_right:Nn\l__gradtable_body_tl{\\}
%<table-layout>   \str_case:Vn\l__gradtable_rules_tl
%<table-layout>     {{booktabs}{\tl_put_right:Nn\l__gradtable_body_tl{\midrule}}
%<table-layout>      {rows}{\tl_put_right:Nn\l__gradtable_body_tl{\midrule}}
%<table-layout>      {grid}{\tl_put_right:Nn\l__gradtable_body_tl{\hline}}}
%<table-layout>   \tl_set_eq:NN\l__gradtable_head_tl\l__gradtable_body_tl
%<table-layout>   \tl_clear:N\l__gradtable_body_tl
%<table-layout>   \int_zero:N\l__gradtable_row_int
%<table-layout>   \seq_map_inline:Nn\l__gradtable_rows_seq
%<table-layout>     {\int_incr:N\l__gradtable_row_int
%<table-layout>      \gradtableInsertGroup
%<table-layout>      \clist_set:Nn\l__gradtable_cells_clist{##1}
%<table-layout>      \int_zero:N\l__gradtable_col_int
%<table-layout>      \clist_map_inline:Nn\l__gradtable_cells_clist
%<table-layout>        {\int_incr:N\l__gradtable_col_int
%<table-layout>         \tl_set:Nx\l__gradtable_id_tl{\seq_item:Nn\l__gradtable_columns_seq{\l__gradtable_col_int}}
%<table-layout>         \int_compare:nNnT{\l__gradtable_col_int}>{1}{\tl_put_right:Nn\l__gradtable_body_tl{&}}
%<table-layout>         \tl_put_right:Nx\l__gradtable_body_tl
%<table-layout>           {\exp_not:N\gradtableGroupedCell{\int_use:N\l__gradtable_row_int}{\exp_not:V\l__gradtable_id_tl}{\exp_not:n{####1}}}}
%<table-layout>      \bool_set_false:N\l_tmpa_bool
%<table-layout>      \prop_if_in:NxT\l__gradtable_group_ends_prop{\int_use:N\l__gradtable_row_int}
%<table-layout>        {\bool_set_true:N\l_tmpa_bool}
%<table-layout>      \bool_if:nTF{(\l__gradtable_summary_bool &&
%<table-layout>        \int_compare_p:nNn{\l__gradtable_row_int}={\seq_count:N\l__gradtable_rows_seq}) ||
%<table-layout>        (\l__gradtable_group_summary_bool && \l_tmpa_bool)}
%<table-layout>        {\tl_put_right:Nn\l__gradtable_body_tl{\\*}}
%<table-layout>        {\tl_put_right:Nn\l__gradtable_body_tl{\\}}
%<table-layout>      \str_if_eq:VnT\l__gradtable_rules_tl{grid}{\tl_put_right:Nn\l__gradtable_body_tl{\hline}}
%<table-layout>      \gradtableAppendGroupSummary
%<table-layout>      \str_if_eq:VnT\l__gradtable_rules_tl{rows}
%<table-layout>        {\int_compare:nNnT{\l__gradtable_row_int}<{\seq_count:N\l__gradtable_rows_seq}
%<table-layout>          {\tl_put_right:Nn\l__gradtable_body_tl{\midrule}}}}
%<table-layout>   \gradtableAppendSummary
%<table-layout>   \cs_set:Npx\arraystretch{\l__gradtable_stretch_tl}
%<table-layout>   \setlength\tabcolsep{\l__gradtable_sep_dim}
%<table-layout>   \setlength\extrarowheight{\l__gradtable_padding_dim}
%<table-layout>   \exp_args:NV\arrayrulecolor\l__gradtable_rule_color_tl
%<table-layout>   \bool_if:NTF\l__gradtable_long_bool{\gradtableLong}
%<table-layout>     {\exp_args:NV\tabular\l__gradtable_preamble_tl
%<table-layout>        \l__gradtable_head_tl\l__gradtable_body_tl\gradtableBottom
%<table-layout>      \endtabular}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableHeader #1
%<table-layout>  {\textbf{\prop_item:Nn\l__gradtable_titles_prop{#1}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableInsertGroup
%<table-layout>  {\prop_get:NxNT\l__gradtable_groups_prop{\int_use:N\l__gradtable_row_int}\l_tmpa_tl
%<table-layout>    {\str_if_eq:VnF\l__gradtable_rules_tl{grid}
%<table-layout>       {\tl_put_right:Nx\l__gradtable_body_tl
%<table-layout>          {\exp_not:N\noalign{\exp_not:N\vskip\dim_use:N\l__gradtable_group_sep_dim}}}
%<table-layout>     \tl_set:Nn\l_tmpb_tl{@{}}
%<table-layout>     \dim_zero:N\l_tmpa_dim
%<table-layout>     \str_if_eq:VnT\l__gradtable_rules_tl{grid}
%<table-layout>       {\tl_set:Nn\l_tmpb_tl{|}
%<table-layout>        \dim_set:Nn\l_tmpa_dim{\dim_max:nn{0pt}{\l__gradtable_sep_dim-\arrayrulewidth}}}
%<table-layout>     \tl_if_empty:NF\l__gradtable_group_color_tl
%<table-layout>       {\tl_put_right:Nx\l_tmpb_tl
%<table-layout>         {>{\exp_not:N\columncolor{\exp_not:V\l__gradtable_group_color_tl}
%<table-layout>           [\dim_use:N\l_tmpa_dim][\dim_use:N\l_tmpa_dim]}}}
%<table-layout>     \dim_compare:nNnTF{\l__gradtable_total_dim}>{0pt}
%<table-layout>       {\dim_set_eq:NN\l__gradtable_span_dim\l__gradtable_total_dim
%<table-layout>        \str_if_eq:VnT\l__gradtable_rules_tl{grid}
%<table-layout>          {\dim_sub:Nn\l__gradtable_span_dim{2\l__gradtable_sep_dim+2\arrayrulewidth}}
%<table-layout>        \tl_put_right:Nx\l_tmpb_tl
%<table-layout>          {>{\exp_not:N\raggedright\exp_not:N\arraybackslash}p{\dim_use:N\l__gradtable_span_dim}}}
%<table-layout>       {\tl_put_right:Nn\l_tmpb_tl{l}}
%<table-layout>     \str_if_eq:VnTF\l__gradtable_rules_tl{grid}
%<table-layout>       {\tl_put_right:Nn\l_tmpb_tl{|}}{\tl_put_right:Nn\l_tmpb_tl{@{}}}
%<table-layout>     \tl_put_right:Nx\l__gradtable_body_tl
%<table-layout>       {\exp_not:N\multicolumn{\seq_count:N\l__gradtable_columns_seq}{\exp_not:V\l_tmpb_tl}
%<table-layout>         {\exp_not:N\gradtableGroupTitle{\exp_not:V\l_tmpa_tl}}\exp_not:N\\*}
%<table-layout>     \str_if_eq:VnT\l__gradtable_rules_tl{grid}
%<table-layout>       {\tl_put_right:Nn\l__gradtable_body_tl{\gradtableGroupRule}}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new:Npn\gradtableGroupRule
%<table-layout>  {\noalign{\nobreak{\CT@arc@\hrule height\arrayrulewidth}\nobreak}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableGroupTitle #1
%<table-layout>  {\rule{0pt}{\dim_eval:n{\ht\strutbox+\l__gradtable_group_sep_dim}}\textbf{#1}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtablePair #1#2
%<table-layout>  {\str_if_eq:nnTF{#2}{NA}{#1{NA}{NA}}
%<table-layout>    {\seq_set_split:Nnn\l__gradtable_interval_seq{/}{#2}
%<table-layout>     \int_compare:nNnTF{\seq_count:N\l__gradtable_interval_seq}={2}
%<table-layout>       {\exp_args:Nee#1{\seq_item:Nn\l__gradtable_interval_seq{1}}
%<table-layout>         {\seq_item:Nn\l__gradtable_interval_seq{2}}}
%<table-layout>       {\gradbarsFail{Comparison~requires~reference/current}}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableBest #1{{\bfseries\boldmath #1}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableHighlight #1#2
%<table-layout>  {\cs_set_eq:NN\gradtableEmphasis\use:n
%<table-layout>   \tl_set:Nn\l_tmpa_tl{#2}\tl_trim_spaces:N\l_tmpa_tl
%<table-layout>   \gradbarsIfNumber:VT\l_tmpa_tl
%<table-layout>     {\prop_get:NnNT\l__gradtable_best_prop{#1}\l_tmpb_tl
%<table-layout>        {\fp_compare:nNnT{#2}={\l_tmpb_tl}{\cs_set_eq:NN\gradtableEmphasis\gradtableBest}}
%<table-layout>      \str_if_eq:eeT{\prop_item:Nn\l__gradtable_marks_prop{#1}}{both}
%<table-layout>        {\prop_get:NnNT\l__gradtable_second_prop{#1}\l_tmpb_tl
%<table-layout>          {\fp_compare:nNnT{#2}={\l_tmpb_tl}{\cs_set_eq:NN\gradtableEmphasis\underline}}}}
%<table-layout>   \str_if_eq:VnTF\l__gradtable_type_tl{number}
%<table-layout>     {\cs_set_eq:NN\gradtableOriginalNumber\gradtableNumber
%<table-layout>      \cs_set_protected:Npn\gradtableNumber##1{\gradtableEmphasis{\gradtableOriginalNumber{##1}}}}
%<table-layout>     {\cs_set_eq:NN\gradtableOriginalLabel\gradbars@labelcontent
%<table-layout>      \cs_set_protected:Npn\gradbars@labelcontent{\gradtableEmphasis{\gradtableOriginalLabel}}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableValidateLayout
%<table-layout>  {\dim_compare:nNnT{\l__gradtable_total_dim}<{0pt}{\gradtableError{Table~width~must~be~nonnegative}}
%<table-layout>   \dim_compare:nNnF{\l__gradtable_min_text_dim}>{0pt}{\gradtableError{Min~text~width~must~be~positive}}
%<table-layout>   \dim_compare:nNnF{\l__gradtable_min_graphic_dim}>{0pt}{\gradtableError{Min~graphic~width~must~be~positive}}
%<table-layout>   \bool_if:NTF\l__gradtable_long_bool
%<table-layout>     {\ifinner\gradtableError{Long~table~requires~outer~paragraph~mode}\fi
%<table-layout>      \if@twocolumn\gradtableError{Long~table~requires~one-column~mode}\fi
%<table-layout>      \tl_if_empty:NF\l__gradtable_label_tl
%<table-layout>        {\tl_if_empty:NT\l__gradtable_caption_tl{\gradtableError{Table~label~requires~caption}}}}
%<table-layout>     {\tl_if_empty:NF\l__gradtable_caption_tl{\gradtableError{Caption~option~requires~long=true}}
%<table-layout>      \tl_if_empty:NF\l__gradtable_label_tl{\gradtableError{Label~option~requires~long=true}}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableBuildHeaders
%<table-layout>  {\seq_map_inline:Nn\l__gradtable_headers_seq
%<table-layout>    {\int_set:Nn\l__gradtable_span_start_int{1}
%<table-layout>     \cs_set_eq:NN\gradtableSavedSpan\gradspan
%<table-layout>     \RenewDocumentCommand\gradspan{m m}{\gradtableBuildSpan{####1}{####2}}
%<table-layout>     ##1
%<table-layout>     \cs_set_eq:NN\gradspan\gradtableSavedSpan
%<table-layout>     \tl_put_right:Nn\l__gradtable_body_tl{\\}
%<table-layout>     \str_case:Vn\l__gradtable_rules_tl
%<table-layout>       {{grid}{\tl_put_right:Nn\l__gradtable_body_tl{\hline}}
%<table-layout>        {booktabs}{\tl_put_right:Nn\l__gradtable_body_tl{\midrule}}
%<table-layout>        {rows}{\tl_put_right:Nn\l__gradtable_body_tl{\midrule}}}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableBuildSpan #1#2
%<table-layout>  {\int_compare:nNnT{\l__gradtable_span_start_int}>{1}{\tl_put_right:Nn\l__gradtable_body_tl{&}}
%<table-layout>   \tl_clear:N\l__gradtable_header_spec_tl
%<table-layout>   \str_if_eq:VnTF\l__gradtable_rules_tl{grid}
%<table-layout>     {\int_compare:nNnT{\l__gradtable_span_start_int}={1}{\tl_put_right:Nn\l__gradtable_header_spec_tl{|}}}
%<table-layout>     {\int_compare:nNnT{\l__gradtable_span_start_int}={1}{\tl_put_right:Nn\l__gradtable_header_spec_tl{@{}}}}
%<table-layout>   \tl_if_empty:NF\l__gradtable_header_color_tl
%<table-layout>     {\dim_set_eq:NN\l_tmpa_dim\l__gradtable_sep_dim
%<table-layout>      \dim_set_eq:NN\l_tmpb_dim\l__gradtable_sep_dim
%<table-layout>      \str_if_eq:VnTF\l__gradtable_rules_tl{grid}
%<table-layout>        {\dim_set:Nn\l_tmpa_dim{\dim_max:nn{0pt}{\l_tmpa_dim-\arrayrulewidth}}
%<table-layout>         \dim_set_eq:NN\l_tmpb_dim\l_tmpa_dim}
%<table-layout>        {\int_compare:nNnT{\l__gradtable_span_start_int}={1}{\dim_zero:N\l_tmpa_dim}
%<table-layout>         \int_compare:nNnT{\l__gradtable_span_start_int+#1-1}={\seq_count:N\l__gradtable_columns_seq}
%<table-layout>           {\dim_zero:N\l_tmpb_dim}}
%<table-layout>      \tl_put_right:Nx\l__gradtable_header_spec_tl
%<table-layout>        {>{\exp_not:N\columncolor{\exp_not:V\l__gradtable_header_color_tl}
%<table-layout>          [\dim_use:N\l_tmpa_dim][\dim_use:N\l_tmpb_dim]}}}
%<table-layout>   \dim_compare:nNnTF{\l__gradtable_total_dim}>{0pt}
%<table-layout>     {\dim_set:Nn\l__gradtable_span_dim{2\l__gradtable_sep_dim*(#1-1)}
%<table-layout>      \str_if_eq:VnT\l__gradtable_rules_tl{grid}
%<table-layout>        {\dim_add:Nn\l__gradtable_span_dim{\arrayrulewidth*(#1-1)}}
%<table-layout>      \int_step_inline:nnnn{\l__gradtable_span_start_int}{1}{\l__gradtable_span_start_int+#1-1}
%<table-layout>        {\tl_set:Nx\l__gradtable_span_id_tl{\seq_item:Nn\l__gradtable_columns_seq{##1}}
%<table-layout>         \dim_add:Nn\l__gradtable_span_dim{\prop_item:NV\l__gradtable_colwidth_prop\l__gradtable_span_id_tl}}
%<table-layout>      \tl_put_right:Nx\l__gradtable_header_spec_tl
%<table-layout>        {>{\exp_not:N\centering\exp_not:N\arraybackslash}p{\dim_use:N\l__gradtable_span_dim}}}
%<table-layout>     {\tl_put_right:Nn\l__gradtable_header_spec_tl{c}}
%<table-layout>   \str_if_eq:VnTF\l__gradtable_rules_tl{grid}
%<table-layout>     {\tl_put_right:Nn\l__gradtable_header_spec_tl{|}}
%<table-layout>     {\int_compare:nNnT{\l__gradtable_span_start_int+#1-1}={\seq_count:N\l__gradtable_columns_seq}
%<table-layout>        {\tl_put_right:Nn\l__gradtable_header_spec_tl{@{}}}}
%<table-layout>   \tl_put_right:Nx\l__gradtable_body_tl
%<table-layout>     {\exp_not:N\multicolumn{#1}{\exp_not:V\l__gradtable_header_spec_tl}{\exp_not:N\textbf{\exp_not:n{#2}}}}
%<table-layout>   \int_add:Nn\l__gradtable_span_start_int{#1}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableScan
%<table-layout>  {\int_zero:N\l__gradtable_row_int
%<table-layout>   \seq_map_inline:Nn\l__gradtable_rows_seq
%<table-layout>     {\int_incr:N\l__gradtable_row_int
%<table-layout>      \clist_set:Nn\l__gradtable_cells_clist{##1}
%<table-layout>      \int_zero:N\l__gradtable_col_int
%<table-layout>      \clist_map_inline:Nn\l__gradtable_cells_clist
%<table-layout>        {\int_incr:N\l__gradtable_col_int
%<table-layout>         \tl_set:Nx\l__gradtable_id_tl{\seq_item:Nn\l__gradtable_columns_seq{\l__gradtable_col_int}}
%<table-layout>         \exp_args:NV\gradtableMeasure\l__gradtable_id_tl{####1}}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableExtent #1#2
%<table-layout>  {\group_begin:\gradtableConfigure{#1}\gradtableHighlight{#1}{#2}
%<table-layout>   \gradbarsSuspendMeasurementTagging
%<table-layout>   \dim_gset:Nn\g__gradtable_extent_dim{\prop_item:Nn\l__gradtable_overheads_prop{#1}}
%<table-layout>   \str_case:VnF\l__gradtable_type_tl{{text}{}{number}{}}
%<table-layout>     {\hbox_set:Nn\l__gradtable_measure_box{\gradtableContent{#2}}
%<table-layout>      \dim_gset:Nn\g__gradtable_extent_dim
%<table-layout>        {\dim_max:nn{\prop_item:Nn\l__gradtable_overheads_prop{#1}}
%<table-layout>          {\box_wd:N\l__gradtable_measure_box-\gradbars@width}}}
%<table-layout>   \gradbarsResumeMeasurementTagging
%<table-layout>   \group_end:
%<table-layout>   \prop_put:Nnx\l__gradtable_overheads_prop{#1}{\dim_use:N\g__gradtable_extent_dim}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableAllocate
%<table-layout>  {\prop_clear:N\l__gradtable_overheads_prop\prop_clear:N\l__gradtable_flex_prop
%<table-layout>   \seq_map_inline:Nn\l__gradtable_columns_seq
%<table-layout>     {\group_begin:\gradtableConfigure{##1}
%<table-layout>      \dim_gset:Nn\g__gradtable_extent_dim
%<table-layout>        {\prop_item:Nn\l__gradtable_widths_prop{##1}+\gradbars@gap+2pt}
%<table-layout>      \str_if_eq:VnT\l__gradtable_type_tl{heat}{\dim_gzero:N\g__gradtable_extent_dim}
%<table-layout>      \group_end:
%<table-layout>      \prop_put:Nnx\l__gradtable_overheads_prop{##1}{\dim_use:N\g__gradtable_extent_dim}}
%<table-layout>   \int_zero:N\l__gradtable_row_int
%<table-layout>   \seq_map_inline:Nn\l__gradtable_rows_seq
%<table-layout>     {\int_incr:N\l__gradtable_row_int\clist_set:Nn\l__gradtable_cells_clist{##1}\int_zero:N\l__gradtable_col_int
%<table-layout>      \clist_map_inline:Nn\l__gradtable_cells_clist
%<table-layout>        {\int_incr:N\l__gradtable_col_int
%<table-layout>         \tl_set:Nx\l__gradtable_id_tl{\seq_item:Nn\l__gradtable_columns_seq{\l__gradtable_col_int}}
%<table-layout>         \exp_args:NV\gradtableExtent\l__gradtable_id_tl{####1}}}
%<table-layout>   \dim_set:Nn\l__gradtable_remaining_dim
%<table-layout>     {\l__gradtable_total_dim-2\l__gradtable_sep_dim*(\seq_count:N\l__gradtable_columns_seq-1)}
%<table-layout>   \str_if_eq:VnT\l__gradtable_rules_tl{grid}
%<table-layout>     {\dim_sub:Nn\l__gradtable_remaining_dim
%<table-layout>        {2\l__gradtable_sep_dim+\arrayrulewidth*(\seq_count:N\l__gradtable_columns_seq+1)}}
%<table-layout>   \fp_zero:N\l__gradtable_weight_sum_fp
%<table-layout>   \seq_map_inline:Nn\l__gradtable_columns_seq
%<table-layout>     {\tl_set:Nn\l__gradtable_id_tl{##1}
%<table-layout>      \tl_set:Nx\l__gradtable_type_tl{\prop_item:Nn\l__gradtable_types_prop{##1}}
%<table-layout>      \dim_set:Nn\l__gradtable_base_dim{\prop_item:Nn\l__gradtable_fixed_prop{##1}}
%<table-layout>      \fp_zero:N\l__gradtable_weight_fp
%<table-layout>      \str_if_eq:VnTF\l__gradtable_type_tl{number}
%<table-layout>        {\dim_set:Nn\l__gradtable_base_dim
%<table-layout>           {\dim_max:nn{\l__gradtable_base_dim}{\prop_item:Nn\l__gradtable_widths_prop{##1}}}}
%<table-layout>        {\dim_compare:nNnTF{\l__gradtable_base_dim}>{0pt}
%<table-layout>           {\str_if_eq:VnF\l__gradtable_type_tl{text}
%<table-layout>              {\dim_compare:nNnT{\l__gradtable_base_dim}
%<table-layout>                <{\prop_item:Nn\l__gradtable_overheads_prop{##1}+\l__gradtable_min_graphic_dim}
%<table-layout>                {\gradtableError{Fixed~column~too~narrow~for~labels~and~graphic}}}}
%<table-layout>           {\fp_set:Nn\l__gradtable_weight_fp{\prop_item:Nn\l__gradtable_weights_prop{##1}}
%<table-layout>            \str_if_eq:VnTF\l__gradtable_type_tl{text}
%<table-layout>              {\dim_set_eq:NN\l__gradtable_base_dim\l__gradtable_min_text_dim}
%<table-layout>              {\dim_set:Nn\l__gradtable_base_dim
%<table-layout>                {\prop_item:Nn\l__gradtable_overheads_prop{##1}+\l__gradtable_min_graphic_dim}}}}
%<table-layout>      \bool_if:nT{(\l__gradtable_summary_bool || \l__gradtable_group_summary_bool) && \str_if_eq_p:Vn\l__gradtable_type_tl{heat}}
%<table-layout>        {\dim_compare:nNnTF{\prop_item:Nn\l__gradtable_fixed_prop{##1}}>{0pt}
%<table-layout>           {\dim_compare:nNnT{\l__gradtable_base_dim}<{\prop_item:Nn\l__gradtable_widths_prop{##1}+4pt}
%<table-layout>              {\gradtableError{Heat~column~too~narrow~for~its~label~or~summary}}}
%<table-layout>           {\dim_set:Nn\l__gradtable_base_dim
%<table-layout>              {\dim_max:nn{\l__gradtable_base_dim}{\prop_item:Nn\l__gradtable_widths_prop{##1}+4pt}}}}
%<table-layout>      \prop_put:Nnx\l__gradtable_colwidth_prop{##1}{\dim_use:N\l__gradtable_base_dim}
%<table-layout>      \prop_put:Nnx\l__gradtable_flex_prop{##1}{\fp_use:N\l__gradtable_weight_fp}
%<table-layout>      \fp_add:Nn\l__gradtable_weight_sum_fp{\l__gradtable_weight_fp}
%<table-layout>      \dim_sub:Nn\l__gradtable_remaining_dim{\l__gradtable_base_dim}}
%<table-layout>   \dim_compare:nNnT{\l__gradtable_remaining_dim}<{0pt}
%<table-layout>     {\gradtableError{Table~width~too~small;~increase~width~or~reduce~minimum~widths~and~spacing}}
%<table-layout>   \fp_compare:nNnT{\l__gradtable_weight_sum_fp}={0}
%<table-layout>     {\dim_compare:nNnT{\l__gradtable_remaining_dim}>{.1pt}
%<table-layout>        {\gradtableError{Table~width~requires~a~flexible~text~or~graphic~column}}}
%<table-layout>   \seq_map_inline:Nn\l__gradtable_columns_seq
%<table-layout>     {\fp_set:Nn\l__gradtable_weight_fp{\prop_item:Nn\l__gradtable_flex_prop{##1}}
%<table-layout>      \fp_compare:nNnT{\l__gradtable_weight_fp}>{0}
%<table-layout>        {\dim_set:Nn\l_tmpa_dim{\fp_to_dim:n
%<table-layout>           {\dim_to_fp:n{\l__gradtable_remaining_dim}*\l__gradtable_weight_fp/\l__gradtable_weight_sum_fp}}
%<table-layout>         \prop_put:Nnx\l__gradtable_colwidth_prop{##1}
%<table-layout>           {\dim_eval:n{\prop_item:Nn\l__gradtable_colwidth_prop{##1}+\l_tmpa_dim}}
%<table-layout>         \dim_sub:Nn\l__gradtable_remaining_dim{\l_tmpa_dim}
%<table-layout>         \fp_sub:Nn\l__gradtable_weight_sum_fp{\l__gradtable_weight_fp}}
%<table-layout>      \str_case_e:nnF{\prop_item:Nn\l__gradtable_types_prop{##1}}{{text}{}{number}{}}
%<table-layout>        {\prop_put:Nnx\l__gradtable_plots_prop{##1}
%<table-layout>          {\dim_eval:n{\prop_item:Nn\l__gradtable_colwidth_prop{##1}-\prop_item:Nn\l__gradtable_overheads_prop{##1}}}}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new:Npn\gradtableBottom
%<table-layout>  {\str_case:Vn\l__gradtable_rules_tl{{booktabs}{\bottomrule}{rows}{\bottomrule}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableLong
%<table-layout>  {\par\setlength\LTleft{0pt}\setlength\LTright{\fill}
%<table-layout>   \dim_compare:nNnT{\l__gradtable_total_dim}>{0pt}{\setlength\LTcapwidth{\l__gradtable_total_dim}}
%<table-layout>   \exp_args:NV\longtable\l__gradtable_preamble_tl
%<table-layout>     \tl_if_empty:NF\l__gradtable_caption_tl
%<table-layout>       {\caption{\l__gradtable_caption_tl}
%<table-layout>        \tl_if_empty:NF\l__gradtable_label_tl{\exp_args:NV\label\l__gradtable_label_tl}\\}
%<table-layout>     \l__gradtable_head_tl\endfirsthead
%<table-layout>     \tl_if_empty:NTF\l__gradtable_caption_tl
%<table-layout>       {\tl_if_empty:NF\l__gradtable_continued_tl
%<table-layout>         {\multicolumn{\seq_count:N\l__gradtable_columns_seq}{c}{\l__gradtable_continued_tl}\\}}
%<table-layout>       {\caption[]{\l__gradtable_caption_tl\space\l__gradtable_continued_tl}\\}
%<table-layout>     \l__gradtable_head_tl\endhead
%<table-layout>     \gradtableBottom
%<table-layout>     \tl_if_empty:NF\l__gradtable_continued_tl
%<table-layout>       {\multicolumn{\seq_count:N\l__gradtable_columns_seq}{r}{\footnotesize\l__gradtable_continued_tl}\\}
%<table-layout>     \endfoot
%<table-layout>     \gradtableBottom\endlastfoot
%<table-layout>     \l__gradtable_body_tl
%<table-layout>   \endlongtable}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableConfigureTheme
%<table-layout>  {\str_case:Vn\l__gradtable_theme_tl
%<table-layout>     {{accessible}{\pgfkeys{/gradbars,palette=accessible,heat~palette=accessible-sequential}}
%<table-layout>      {blue}{\pgfkeys{/gradbars,theme=blue,heat~low~color=gradbarsBlue!8,heat~high~color=gradbarsBlue}}
%<table-layout>      {teal}{\pgfkeys{/gradbars,theme=teal,heat~low~color=gradbarsTeal!8,heat~high~color=gradbarsTeal}}
%<table-layout>      {violet}{\pgfkeys{/gradbars,theme=violet,heat~low~color=gradbarsViolet!8,heat~high~color=gradbarsViolet}}
%<table-layout>      {orange}{\pgfkeys{/gradbars,theme=orange,heat~low~color=gradbarsWarmOrange!8,heat~high~color=gradbarsWarmOrange}}
%<table-layout>      {forest}{\pgfkeys{/gradbars,theme=forest,heat~low~color=gradbarsForest!8,heat~high~color=gradbarsForest}}
%<table-layout>      {mono}{\pgfkeys{/gradbars,theme=gray,print}}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableResolveThemeColors
%<table-layout>  {\tl_set:Nn\l__gradtable_theme_color_tl{gradbarsBlue}
%<table-layout>   \str_case:Vn\l__gradtable_theme_tl
%<table-layout>     {{accessible}{\tl_set:Nn\l__gradtable_theme_color_tl{gradbarsCudBlue}}
%<table-layout>      {teal}{\tl_set:Nn\l__gradtable_theme_color_tl{gradbarsTeal}}
%<table-layout>      {violet}{\tl_set:Nn\l__gradtable_theme_color_tl{gradbarsViolet}}
%<table-layout>      {orange}{\tl_set:Nn\l__gradtable_theme_color_tl{gradbarsWarmOrange}}
%<table-layout>      {forest}{\tl_set:Nn\l__gradtable_theme_color_tl{gradbarsForest}}
%<table-layout>      {mono}{\tl_set:Nn\l__gradtable_theme_color_tl{black}}}
%<table-layout>   \str_if_eq:VnF\l__gradtable_theme_tl{none}
%<table-layout>     {\bool_if:NT\l__gradtable_header_auto_bool
%<table-layout>        {\tl_set:Nx\l__gradtable_header_color_tl{\l__gradtable_theme_color_tl !8}}}
%<table-layout>   \str_if_eq:VnT\l__gradtable_summary_color_tl{auto}
%<table-layout>     {\tl_clear:N\l__gradtable_summary_color_tl
%<table-layout>      \str_if_eq:VnF\l__gradtable_theme_tl{none}
%<table-layout>        {\tl_set:Nx\l__gradtable_summary_color_tl{\l__gradtable_theme_color_tl !8}}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableSummaryContent #1
%<table-layout>  {\tl_use:N\l__gradtable_summary_font_tl
%<table-layout>   \str_if_eq:eeTF{#1}{\l__gradtable_summary_label_id_tl}
%<table-layout>     {\tl_use:N\l__gradtable_summary_label_tl}
%<table-layout>     {\prop_get:NnNT\l__gradtable_summary_values_prop{#1}\l__gradtable_summary_value_tl
%<table-layout>        {\str_if_eq:eeT{\prop_item:Nn\l__gradtable_aggregates_prop{#1}}{count}
%<table-layout>           {\def\gradbars@precision{0}\def\gradbars@unit{}\def\gradbars@unitcode{}\def\gradbars@unittext{}\def\gradbars@format{value}}
%<table-layout>         \exp_args:NV\gradtableNumber\l__gradtable_summary_value_tl}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableMeasureSummary
%<table-layout>  {\bool_if:NT\l__gradtable_summary_bool
%<table-layout>     {\seq_map_inline:Nn\l__gradtable_columns_seq
%<table-layout>        {\group_begin:\gradtableConfigure{##1}\gradbarsSuspendMeasurementTagging
%<table-layout>         \hbox_set:Nn\l__gradtable_measure_box{\gradtableSummaryContent{##1}}
%<table-layout>         \dim_gset:Nn\g__gradtable_measured_dim{\box_wd:N\l__gradtable_measure_box}
%<table-layout>         \gradbarsResumeMeasurementTagging\group_end:
%<table-layout>         \prop_put:Nnx\l__gradtable_widths_prop{##1}
%<table-layout>           {\dim_max:nn{\prop_item:Nn\l__gradtable_widths_prop{##1}}{\g__gradtable_measured_dim}}
%<table-layout>         \str_if_eq:eeT{\prop_item:Nn\l__gradtable_types_prop{##1}}{text}
%<table-layout>           {\dim_compare:nNnT{\g__gradtable_measured_dim}>{\prop_item:Nn\l__gradtable_colwidth_prop{##1}}
%<table-layout>              {\dim_compare:nNnT{\l__gradtable_total_dim}={0pt}
%<table-layout>                 {\prop_put:Nnx\l__gradtable_colwidth_prop{##1}{\dim_use:N\g__gradtable_measured_dim}}}}}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableSummaryCell #1
%<table-layout>  {\group_begin:\gradtableConfigure{#1}
%<table-layout>   \str_if_eq:VnTF\l__gradtable_type_tl{text}{\gradtableSummaryContent{#1}}
%<table-layout>     {\makebox[\dim_max:nn{\prop_item:Nn\l__gradtable_widths_prop{#1}}
%<table-layout>      {\prop_item:Nn\l__gradtable_colwidth_prop{#1}}]
%<table-layout>       [\str_case:VnF\l__gradtable_type_tl
%<table-layout>          {{number}{\prop_item:Nn\l__gradtable_align_prop{#1}}{heat}{c}}{r}]
%<table-layout>       {\gradtableSummaryContent{#1}}}\group_end:}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableAppendSummary
%<table-layout>  {\bool_if:NT\l__gradtable_summary_bool
%<table-layout>     {\str_case:Vn\l__gradtable_rules_tl
%<table-layout>        {{booktabs}{\tl_put_right:Nn\l__gradtable_body_tl{\midrule}}
%<table-layout>         {rows}{\tl_put_right:Nn\l__gradtable_body_tl{\midrule}}}
%<table-layout>      \tl_if_empty:NF\l__gradtable_summary_color_tl
%<table-layout>        {\tl_put_right:Nx\l__gradtable_body_tl{\exp_not:N\rowcolor{\exp_not:V\l__gradtable_summary_color_tl}}}
%<table-layout>      \int_zero:N\l__gradtable_summary_col_int
%<table-layout>      \seq_map_inline:Nn\l__gradtable_columns_seq
%<table-layout>        {\int_incr:N\l__gradtable_summary_col_int
%<table-layout>         \int_compare:nNnT{\l__gradtable_summary_col_int}>{1}{\tl_put_right:Nn\l__gradtable_body_tl{&}}
%<table-layout>         \tl_put_right:Nn\l__gradtable_body_tl{\gradtableSummaryCell{##1}}}
%<table-layout>      \tl_put_right:Nn\l__gradtable_body_tl{\\}
%<table-layout>      \str_if_eq:VnT\l__gradtable_rules_tl{grid}{\tl_put_right:Nn\l__gradtable_body_tl{\hline}}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_eq:NN\gradtableHighlightBeforeSeven\gradtableHighlight
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_set_protected:Npn\gradtableHighlight #1#2
%<table-layout>  {\str_if_eq:VnT\l__gradtable_rank_scope_tl{group}
%<table-layout>     {\prop_clear:N\l__gradtable_best_prop\prop_clear:N\l__gradtable_second_prop
%<table-layout>      \prop_get:NxN\l__gradtable_row_groups_prop{\int_use:N\l__gradtable_row_int}\l__gradtable_group_id_tl
%<table-layout>      \prop_get:NxNT\l__gradtable_group_best_prop{\l__gradtable_group_id_tl/#1}\l_tmpa_tl
%<table-layout>        {\prop_put:NnV\l__gradtable_best_prop{#1}\l_tmpa_tl}
%<table-layout>      \prop_get:NxNT\l__gradtable_group_second_prop{\l__gradtable_group_id_tl/#1}\l_tmpa_tl
%<table-layout>        {\prop_put:NnV\l__gradtable_second_prop{#1}\l_tmpa_tl}}
%<table-layout>   \gradtableHighlightBeforeSeven{#1}{#2}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableGroupedCell #1#2#3
%<table-layout>  {\group_begin:\int_set:Nn\l__gradtable_row_int{#1}\gradtableCell{#2}{#3}\group_end:}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableUseGroupSummary #1
%<table-layout>  {\bool_set_true:N\l__gradtable_summary_bool
%<table-layout>   \tl_set_eq:NN\l__gradtable_summary_label_tl\l__gradtable_group_summary_label_tl
%<table-layout>   \prop_clear:N\l__gradtable_summary_values_prop\tl_clear:N\l__gradtable_summary_label_id_tl
%<table-layout>   \seq_map_inline:Nn\l__gradtable_columns_seq
%<table-layout>     {\str_if_eq:eeT{\prop_item:Nn\l__gradtable_types_prop{##1}}{text}
%<table-layout>        {\tl_if_empty:NT\l__gradtable_summary_label_id_tl{\tl_set:Nn\l__gradtable_summary_label_id_tl{##1}}}
%<table-layout>      \prop_get:NnNT\l__gradtable_group_summary_values_prop{#1/##1}\l_tmpa_tl
%<table-layout>        {\prop_put:NnV\l__gradtable_summary_values_prop{##1}\l_tmpa_tl}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_eq:NN\gradtableMeasureSummaryBeforeSeven\gradtableMeasureSummary
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_set_protected:Npn\gradtableMeasureSummary
%<table-layout>  {\gradtableMeasureSummaryBeforeSeven
%<table-layout>   \bool_if:NT\l__gradtable_group_summary_bool
%<table-layout>     {\int_step_inline:nn{\l__gradtable_group_count_int}
%<table-layout>        {\seq_if_empty:cF{l__gradtable_group_##1_seq}
%<table-layout>           {\group_begin:\gradtableUseGroupSummary{##1}\gradtableMeasureSummaryBeforeSeven
%<table-layout>            \prop_gset_eq:NN\g__gradtable_group_widths_prop\l__gradtable_widths_prop
%<table-layout>            \prop_gset_eq:NN\g__gradtable_group_result_prop\l__gradtable_colwidth_prop\group_end:
%<table-layout>            \prop_set_eq:NN\l__gradtable_widths_prop\g__gradtable_group_widths_prop
%<table-layout>            \prop_set_eq:NN\l__gradtable_colwidth_prop\g__gradtable_group_result_prop}}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableGroupSummaryCell #1#2
%<table-layout>  {\group_begin:\gradtableUseGroupSummary{#1}\gradtableSummaryCell{#2}\group_end:}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableAppendGroupSummary
%<table-layout>  {\bool_if:NT\l__gradtable_group_summary_bool
%<table-layout>     {\prop_get:NxNT\l__gradtable_group_ends_prop{\int_use:N\l__gradtable_row_int}\l__gradtable_group_id_tl
%<table-layout>        {\str_case:Vn\l__gradtable_rules_tl
%<table-layout>           {{booktabs}{\tl_put_right:Nn\l__gradtable_body_tl{\midrule}}}
%<table-layout>         \tl_if_empty:NF\l__gradtable_summary_color_tl
%<table-layout>           {\tl_put_right:Nx\l__gradtable_body_tl{\exp_not:N\rowcolor{\exp_not:V\l__gradtable_summary_color_tl}}}
%<table-layout>         \int_zero:N\l__gradtable_summary_col_int
%<table-layout>         \seq_map_inline:Nn\l__gradtable_columns_seq
%<table-layout>           {\int_incr:N\l__gradtable_summary_col_int
%<table-layout>            \int_compare:nNnT{\l__gradtable_summary_col_int}>{1}{\tl_put_right:Nn\l__gradtable_body_tl{&}}
%<table-layout>            \tl_put_right:Nx\l__gradtable_body_tl
%<table-layout>              {\exp_not:N\gradtableGroupSummaryCell{\l__gradtable_group_id_tl}{\exp_not:n{##1}}}}
%<table-layout>         \bool_if:nTF{\l__gradtable_summary_bool && \int_compare_p:nNn{\l__gradtable_row_int}={\seq_count:N\l__gradtable_rows_seq}}
%<table-layout>           {\tl_put_right:Nn\l__gradtable_body_tl{\\*}}{\tl_put_right:Nn\l__gradtable_body_tl{\\}}
%<table-layout>         \str_if_eq:VnT\l__gradtable_rules_tl{grid}{\tl_put_right:Nn\l__gradtable_body_tl{\hline}}}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_eq:NN\gradtableConfigureBeforeEight\gradtableConfigure
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_set_protected:Npn\gradtableConfigure #1
%<table-layout>  {\tl_set:Nn\l__gradtable_id_tl{#1}\gradtableConfigureBeforeEight{#1}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradbarsDecimalParts #1
%<table-layout>  {\fp_set:Nn\l__gradbars_decimal_value_fp{#1}
%<table-layout>   \int_zero:N\l__gradbars_decimal_exponent_int
%<table-layout>   \str_if_eq:eeT{\gradbars@numberformat}{scientific}
%<table-layout>     {\fp_compare:nNnF{\l__gradbars_decimal_value_fp}={0}
%<table-layout>        {\int_set:Nn\l__gradbars_decimal_exponent_int{\fp_eval:n{floor(ln(abs(\l__gradbars_decimal_value_fp))/ln(10))}}
%<table-layout>         \fp_set:Nn\l__gradbars_decimal_value_fp
%<table-layout>           {\l__gradbars_decimal_value_fp/10^\l__gradbars_decimal_exponent_int}}}
%<table-layout>   \fp_compare:nNnTF{\l__gradbars_decimal_value_fp}<{0}
%<table-layout>     {\fp_set:Nn\l__gradbars_decimal_value_fp{-round(abs(\l__gradbars_decimal_value_fp),\gradbars@precision,1)}}
%<table-layout>     {\fp_set:Nn\l__gradbars_decimal_value_fp{round(\l__gradbars_decimal_value_fp,\gradbars@precision,1)}}
%<table-layout>   \str_if_eq:eeT{\gradbars@numberformat}{scientific}
%<table-layout>     {\fp_compare:nT{abs(\l__gradbars_decimal_value_fp)>=10}
%<table-layout>        {\fp_set:Nn\l__gradbars_decimal_value_fp{\l__gradbars_decimal_value_fp/10}
%<table-layout>         \int_incr:N\l__gradbars_decimal_exponent_int}}
%<table-layout>   \tl_clear:N\l__gradbars_decimal_sign_tl
%<table-layout>   \fp_compare:nNnT{\l__gradbars_decimal_value_fp}<{0}{\tl_set:Nn\l__gradbars_decimal_sign_tl{\ensuremath{-}}}
%<table-layout>   \seq_set_split:Nnx\l__gradbars_decimal_parts_seq{.}{\fp_to_decimal:n{abs(\l__gradbars_decimal_value_fp)}}
%<table-layout>   \tl_set:Nx\l__gradbars_decimal_integer_tl{\seq_item:Nn\l__gradbars_decimal_parts_seq{1}}
%<table-layout>   \tl_clear:N\l__gradbars_decimal_fraction_tl
%<table-layout>   \int_compare:nNnT{\seq_count:N\l__gradbars_decimal_parts_seq}>{1}
%<table-layout>     {\tl_set:Nx\l__gradbars_decimal_fraction_tl{\seq_item:Nn\l__gradbars_decimal_parts_seq{2}}}
%<table-layout>   \int_while_do:nn{\tl_count:N\l__gradbars_decimal_fraction_tl<\gradbars@precision}
%<table-layout>     {\tl_put_right:Nn\l__gradbars_decimal_fraction_tl{0}}
%<table-layout>   \hbox_set:Nn\l__gradbars_decimal_left_box
%<table-layout>     {\l__gradbars_decimal_sign_tl
%<table-layout>      \str_if_eq:eeTF{\gradbars@formatter}{siunitx}
%<table-layout>        {\group_begin:\gradbarsSIOptions\sisetup{round-mode=none,exponent-mode=fixed,fixed-exponent=0}
%<table-layout>         \exp_args:NV\num\l__gradbars_decimal_integer_tl\group_end:}
%<table-layout>        {\str_if_eq:eeTF{\gradbars@numberformat}{grouped}
%<table-layout>           {\pgfmathprintnumber[fixed,precision=0,1000~sep={\mathord{,}}]{\l__gradbars_decimal_integer_tl}}
%<table-layout>           {\pgfmathprintnumber[fixed,precision=0,1000~sep={\,}]{\l__gradbars_decimal_integer_tl}}}}
%<table-layout>   \hbox_set:Nn\l__gradbars_decimal_right_box
%<table-layout>     {\int_compare:nNnT{\gradbars@precision}>{0}{\ensuremath{.\l__gradbars_decimal_fraction_tl}}
%<table-layout>      \str_if_eq:eeT{\gradbars@numberformat}{scientific}
%<table-layout>        {\ensuremath{{}\times10^{\int_use:N\l__gradbars_decimal_exponent_int}}}
%<table-layout>      \gradbarsNumericSuffix}
%<table-layout>   \dim_gset:Nn\g__gradbars_decimal_left_dim{\box_wd:N\l__gradbars_decimal_left_box}
%<table-layout>   \dim_gset:Nn\g__gradbars_decimal_right_dim{\box_wd:N\l__gradbars_decimal_right_box}
%<table-layout>   \dim_gset:Nn\g__gradbars_decimal_full_dim{\g__gradbars_decimal_left_dim+\g__gradbars_decimal_right_dim}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradbarsDecimalPrint #1
%<table-layout>  {\gradbarsDecimalParts{#1}
%<table-layout>   \bool_if:NTF\l__gradbars_decimal_measure_bool
%<table-layout>     {\box_use:N\l__gradbars_decimal_left_box\box_use:N\l__gradbars_decimal_right_box}
%<table-layout>     {\prop_if_in:NVTF\l__gradtable_decimal_left_prop\l__gradtable_id_tl
%<table-layout>        {\makebox[\prop_item:NV\l__gradtable_decimal_left_prop\l__gradtable_id_tl][r]{\box_use:N\l__gradbars_decimal_left_box}
%<table-layout>         \makebox[\prop_item:NV\l__gradtable_decimal_right_prop\l__gradtable_id_tl][l]{\box_use:N\l__gradbars_decimal_right_box}}
%<table-layout>        {\box_use:N\l__gradbars_decimal_left_box\box_use:N\l__gradbars_decimal_right_box}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_eq:NN\gradtableNumberBeforeEight\gradtableNumber
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_set_protected:Npn\gradtableNumber #1
%<table-layout>  {\str_if_eq:VnTF\l__gradtable_number_align_tl{decimal}
%<table-layout>     {\bool_set_true:N\l__gradbars_decimal_active_bool
%<table-layout>      \str_if_eq:nnTF{#1}{NA}
%<table-layout>        {\bool_if:NTF\l__gradbars_decimal_measure_bool
%<table-layout>           {\gradbars@missingtext}
%<table-layout>           {\prop_if_in:NVTF\l__gradtable_decimal_left_prop\l__gradtable_id_tl
%<table-layout>              {\makebox[\dim_eval:n{\prop_item:NV\l__gradtable_decimal_left_prop\l__gradtable_id_tl+
%<table-layout>                    \prop_item:NV\l__gradtable_decimal_right_prop\l__gradtable_id_tl}][c]{\gradbars@missingtext}}
%<table-layout>              {\gradbars@missingtext}}}
%<table-layout>        {\gradtableNumberBeforeEight{#1}}}
%<table-layout>     {\gradtableNumberBeforeEight{#1}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableMeasureDecimalValue #1#2#3
%<table-layout>  {\group_begin:\gradbarsSuspendMeasurementTagging\gradtableConfigure{#1}
%<table-layout>   \str_if_eq:nnTF{#3}{summary}
%<table-layout>     {\tl_use:N\l__gradtable_summary_font_tl
%<table-layout>      \str_if_eq:eeT{\prop_item:Nn\l__gradtable_aggregates_prop{#1}}{count}
%<table-layout>        {\def\gradbars@precision{0}\def\gradbars@unit{}\def\gradbars@unitcode{}\def\gradbars@unittext{}\def\gradbars@format{value}}}
%<table-layout>     {\gradtableHighlight{#1}{#2}}
%<table-layout>   \bool_set_true:N\l__gradbars_decimal_measure_bool
%<table-layout>   \dim_gzero:N\g__gradbars_decimal_left_dim\dim_gzero:N\g__gradbars_decimal_right_dim
%<table-layout>   \hbox_set:Nn\l__gradtable_measure_box{\gradtableNumber{#2}}
%<table-layout>   \dim_gset:Nn\g__gradbars_decimal_full_dim{\box_wd:N\l__gradtable_measure_box}
%<table-layout>   \gradbarsResumeMeasurementTagging\group_end:
%<table-layout>   \prop_put:Nnx\l__gradtable_decimal_left_prop{#1}
%<table-layout>     {\dim_max:nn{\prop_item:Nn\l__gradtable_decimal_left_prop{#1}}{\g__gradbars_decimal_left_dim}}
%<table-layout>   \prop_put:Nnx\l__gradtable_decimal_right_prop{#1}
%<table-layout>     {\dim_max:nn{\prop_item:Nn\l__gradtable_decimal_right_prop{#1}}{\g__gradbars_decimal_right_dim}}
%<table-layout>   \prop_put:Nnx\l__gradtable_widths_prop{#1}
%<table-layout>     {\dim_max:nn{\prop_item:Nn\l__gradtable_widths_prop{#1}}{\g__gradbars_decimal_full_dim}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_protected:Npn\gradtableMeasureDecimals
%<table-layout>  {\prop_clear:N\l__gradtable_decimal_left_prop\prop_clear:N\l__gradtable_decimal_right_prop
%<table-layout>   \int_zero:N\l__gradtable_decimal_col_int
%<table-layout>   \seq_map_inline:Nn\l__gradtable_columns_seq
%<table-layout>     {\int_incr:N\l__gradtable_decimal_col_int
%<table-layout>      \str_if_eq:eeT{\prop_item:Nn\l__gradtable_number_align_prop{##1}}{decimal}
%<table-layout>        {\prop_put:Nnn\l__gradtable_decimal_left_prop{##1}{0pt}
%<table-layout>         \prop_put:Nnn\l__gradtable_decimal_right_prop{##1}{0pt}
%<table-layout>         \int_zero:N\l__gradtable_row_int
%<table-layout>         \seq_map_inline:Nn\l__gradtable_rows_seq
%<table-layout>           {\int_incr:N\l__gradtable_row_int\clist_set:Nn\l__gradtable_cells_clist{####1}
%<table-layout>            \exp_args:Nne\gradtableMeasureDecimalValue{##1}
%<table-layout>              {\clist_item:Nn\l__gradtable_cells_clist{\l__gradtable_decimal_col_int}}{data}}
%<table-layout>         \bool_if:NT\l__gradtable_summary_bool
%<table-layout>           {\prop_get:NnNT\l__gradtable_summary_values_prop{##1}\l_tmpa_tl
%<table-layout>              {\exp_args:NnV\gradtableMeasureDecimalValue{##1}\l_tmpa_tl{summary}}}
%<table-layout>         \bool_if:NT\l__gradtable_group_summary_bool
%<table-layout>           {\int_step_inline:nn{\l__gradtable_group_count_int}
%<table-layout>              {\prop_get:NnNT\l__gradtable_group_summary_values_prop{####1/##1}\l_tmpa_tl
%<table-layout>                 {\exp_args:NnV\gradtableMeasureDecimalValue{##1}\l_tmpa_tl{summary}}}}
%<table-layout>         \dim_set:Nn\l_tmpa_dim{\prop_item:Nn\l__gradtable_decimal_left_prop{##1}+
%<table-layout>                               \prop_item:Nn\l__gradtable_decimal_right_prop{##1}}
%<table-layout>         \dim_set:Nn\l_tmpb_dim{\prop_item:Nn\l__gradtable_widths_prop{##1}}
%<table-layout>         \dim_compare:nNnT{\l_tmpb_dim}>{\l_tmpa_dim}
%<table-layout>           {\prop_put:Nnx\l__gradtable_decimal_right_prop{##1}
%<table-layout>              {\dim_eval:n{\l_tmpb_dim-\prop_item:Nn\l__gradtable_decimal_left_prop{##1}}}}
%<table-layout>         \prop_put:Nnx\l__gradtable_widths_prop{##1}
%<table-layout>           {\dim_max:nn{\l_tmpb_dim}{\l_tmpa_dim}}
%<table-layout>         \dim_compare:nNnT{\prop_item:Nn\l__gradtable_fixed_prop{##1}}>{0pt}
%<table-layout>           {\dim_compare:nNnT{\prop_item:Nn\l__gradtable_widths_prop{##1}}>{\prop_item:Nn\l__gradtable_fixed_prop{##1}}
%<table-layout>              {\tl_set:Nn\l__gradtable_id_tl{##1}\gradtableError{Decimal~column~width~too~narrow;~increase~width}}}}}}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_new_eq:NN\gradtableMeasureSummaryBeforeEight\gradtableMeasureSummary
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOn
%<table-layout>\cs_set_protected:Npn\gradtableMeasureSummary
%<table-layout>  {\gradtableMeasureSummaryBeforeEight\gradtableMeasureDecimals}
%<table-layout>\ExplSyntaxOff
%<table-layout>\ExplSyntaxOff
%<table-layout>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-tagging.sty}}
%    \begin{macrocode}
%<tagging>% Author: SuFan; MIT License. Internal implementation unless documented.
%<tagging>\ProvidesPackage{gradbars-tagging}[2026/10/25 v1.1.0 gradbars tagging]
%<tagging>\ExplSyntaxOff
%<tagging>% Accessible descriptions use the supported TikZ tagging interface.  No tagging
%<tagging>% is activated by this package; ordinary documents keep their existing output.
%<tagging>\def\gradbarsCaptureTikzAlt{%
%<tagging>  % Capture explicit /tikz/alt options locally, without changing the global key.
%<tagging>  \pgfkeysifdefined{/tikz/alt/.@cmd}{%
%<tagging>    \pgfkeys{/tikz/alt/.append code={\ifgradbars@capturealt\def\gradbars@alt{##1}\fi}}%
%<tagging>  }{\pgfkeys{/tikz/alt/.code={\def\gradbars@alt{##1}}}}%
%<tagging>}
%<tagging>\ExplSyntaxOn
%<tagging>\tl_new:N \l__gradbars_alt_tl
%<tagging>\seq_new:N \l__gradbars_alt_fields_seq
%<tagging>\int_new:N \l__gradbars_alt_index_int
%<tagging>\cs_new_protected:Npn \gradbarsAltValue #1
%<tagging>  {
%<tagging>    \tl_set:Nx \l_tmpa_tl {#1}
%<tagging>    \tl_trim_spaces:N \l_tmpa_tl
%<tagging>    \tl_if_empty:NTF \l_tmpa_tl
%<tagging>      {\tl_put_right:Nn \l__gradbars_alt_tl {missing}}
%<tagging>      {\str_if_eq:VnTF \l_tmpa_tl {NA}
%<tagging>        {\tl_put_right:Nn \l__gradbars_alt_tl {missing}}
%<tagging>        {\tl_put_right:Nx \l__gradbars_alt_tl {\fp_eval:n {\l_tmpa_tl}}}}
%<tagging>  }
%<tagging>\cs_new_protected:Npn \gradbarsBuildAlt
%<tagging>  {
%<tagging>    \tl_clear:N \l__gradbars_alt_tl
%<tagging>    \ifgradbars@spark
%<tagging>      \tl_put_right:Nn \l__gradbars_alt_tl {Equally~spaced~series:~}
%<tagging>      \int_zero:N \l__gradbars_alt_index_int
%<tagging>      \seq_map_inline:Nn \l__gradbars_series_seq
%<tagging>        {\int_incr:N \l__gradbars_alt_index_int
%<tagging>         \int_compare:nNnT {\l__gradbars_alt_index_int}>{1}
%<tagging>           {\tl_put_right:Nn \l__gradbars_alt_tl {;~}}
%<tagging>         \tl_put_right:Nx \l__gradbars_alt_tl
%<tagging>           {observation~\int_use:N\l__gradbars_alt_index_int :~}
%<tagging>         \gradbarsAltValue{##1}}
%<tagging>      \tl_put_right:Nn \l__gradbars_alt_tl {.~Final~observation:~}
%<tagging>      \gradbarsAltValue{\gradbars@sparklast}
%<tagging>      \tl_put_right:Nx \l__gradbars_alt_tl
%<tagging>        {.~Vertical~range:~\fp_use:N\l__gradbars_series_low_fp\c_space_tl to~\fp_use:N\l__gradbars_series_high_fp.}
%<tagging>    \else\ifgradbars@stack
%<tagging>      \tl_put_right:Nn \l__gradbars_alt_tl {Stacked~contributions:~}
%<tagging>      \int_zero:N \l__gradbars_alt_index_int
%<tagging>      \clist_map_inline:Nn \l__gradbars_stack_clist
%<tagging>        {\int_incr:N \l__gradbars_alt_index_int
%<tagging>         \int_compare:nNnT {\l__gradbars_alt_index_int}>{1}
%<tagging>           {\tl_put_right:Nn \l__gradbars_alt_tl {;~}}
%<tagging>         \clist_if_empty:NTF \l__gradbars_names_clist
%<tagging>           {\tl_put_right:Nx \l__gradbars_alt_tl
%<tagging>             {segment~\int_use:N\l__gradbars_alt_index_int}}
%<tagging>           {\tl_put_right:Nx \l__gradbars_alt_tl
%<tagging>             {\clist_item:Nn\l__gradbars_names_clist{\l__gradbars_alt_index_int}}}
%<tagging>         \tl_put_right:Nn \l__gradbars_alt_tl {:~}\gradbarsAltValue{##1}}
%<tagging>      \tl_put_right:Nx \l__gradbars_alt_tl
%<tagging>        {.~Net:~\gradbars@total.~Positive~subtotal:~\gradbars@positive.\c_space_tl
%<tagging>         Negative~subtotal:~\gradbars@negative.}
%<tagging>    \else\ifgradbars@compare
%<tagging>      \tl_put_right:Nn \l__gradbars_alt_tl {Reference:~}
%<tagging>      \ifgradbars@referencemissing
%<tagging>        \tl_put_right:Nn \l__gradbars_alt_tl {missing}
%<tagging>      \else\gradbarsAltValue{\gradbars@reference}\fi
%<tagging>      \tl_put_right:Nn \l__gradbars_alt_tl {.~Current:~}
%<tagging>      \ifgradbars@missing\tl_put_right:Nn \l__gradbars_alt_tl {missing}
%<tagging>      \else\gradbarsAltValue{\gradbars@value}\fi
%<tagging>      \tl_put_right:Nn \l__gradbars_alt_tl {.~Change:~}
%<tagging>      \ifgradbars@missing\tl_put_right:Nn \l__gradbars_alt_tl {missing}
%<tagging>      \else\ifgradbars@referencemissing\tl_put_right:Nn \l__gradbars_alt_tl {missing}
%<tagging>      \else\gradbarsAltValue{\gradbars@value-\gradbars@reference}\fi\fi
%<tagging>      \str_if_eq:eeT {\gradbars@comparelabel}{percent}
%<tagging>        {\tl_put_right:Nn \l__gradbars_alt_tl {.~Relative~change:~}
%<tagging>         \ifgradbars@missing\tl_put_right:Nn \l__gradbars_alt_tl {missing}
%<tagging>         \else\ifgradbars@referencemissing\tl_put_right:Nn \l__gradbars_alt_tl {missing}
%<tagging>         \else\fp_compare:nNnTF {\gradbars@reference}={0}
%<tagging>           {\tl_put_right:Nn \l__gradbars_alt_tl {undefined~for~a~zero~reference}}
%<tagging>           {\gradbarsAltValue{100*(\gradbars@value-\gradbars@reference)/abs(\gradbars@reference)}
%<tagging>            \tl_put_right:Nn \l__gradbars_alt_tl {~percent}}\fi\fi}
%<tagging>      \tl_put_right:Nn \l__gradbars_alt_tl {.}
%<tagging>    \else\ifgradbars@rangemode
%<tagging>      \tl_put_right:Nn \l__gradbars_alt_tl {Interval:~}
%<tagging>      \ifgradbars@rangemissing\tl_put_right:Nn \l__gradbars_alt_tl {missing.}
%<tagging>      \else
%<tagging>        \gradbarsAltValue{\gradbars@rangelo}
%<tagging>        \tl_put_right:Nn \l__gradbars_alt_tl {~to~}\gradbarsAltValue{\gradbars@rangehi}
%<tagging>        \tl_put_right:Nn \l__gradbars_alt_tl {.}
%<tagging>        \tl_if_empty:oF {\gradbars@rangepoint}
%<tagging>          {\tl_put_right:Nn \l__gradbars_alt_tl {~Point~estimate:~}
%<tagging>           \gradbarsAltValue{\gradbars@rangepoint}\tl_put_right:Nn \l__gradbars_alt_tl {.}}
%<tagging>      \fi
%<tagging>    \else
%<tagging>      \tl_put_right:Nn \l__gradbars_alt_tl {Value:~}
%<tagging>      \ifgradbars@missing\tl_put_right:Nn \l__gradbars_alt_tl {missing.}
%<tagging>      \else\gradbarsAltValue{\gradbars@value}\tl_put_right:Nn \l__gradbars_alt_tl {.}\fi
%<tagging>    \fi\fi\fi\fi
%<tagging>    \tl_if_empty:oF {\gradbars@unit}
%<tagging>      {\tl_put_right:Nx \l__gradbars_alt_tl {~Unit:~\exp_not:o{\gradbars@unit}.}}
%<tagging>    \ifgradbars@spark\else
%<tagging>      \tl_put_right:Nx \l__gradbars_alt_tl
%<tagging>        {~Scale:~\fp_eval:n{\gradbars@min}~to~\fp_eval:n{\gradbars@max}.}
%<tagging>      \ifgradbars@error
%<tagging>        \tl_put_right:Nx \l__gradbars_alt_tl
%<tagging>          {~Error~distances:~minus~\gradbars@errorminus,~plus~\gradbars@errorplus.}
%<tagging>      \fi
%<tagging>      \tl_if_empty:oF {\gradbars@target}
%<tagging>        {\tl_put_right:Nx \l__gradbars_alt_tl {~Target:~\gradbars@target.}}
%<tagging>      \clist_map_inline:Nn \l__gradbars_refs_clist
%<tagging>        {\seq_set_split:Nnn\l__gradbars_alt_fields_seq{/}{##1}
%<tagging>         \tl_put_right:Nx\l__gradbars_alt_tl
%<tagging>           {~Reference~\seq_item:Nn\l__gradbars_alt_fields_seq{4}:\c_space_tl
%<tagging>            \seq_item:Nn\l__gradbars_alt_fields_seq{1}.}}
%<tagging>      \tl_if_empty:oF {\gradbars@band}
%<tagging>        {\tl_put_right:Nx\l__gradbars_alt_tl {~Reference~band:~\gradbars@band.}}
%<tagging>      \ifgradbars@bullet
%<tagging>        \tl_put_right:Nn\l__gradbars_alt_tl {~Background~grade~upper~bounds:~}
%<tagging>        \clist_map_inline:Nn\l__gradbars_bands_clist
%<tagging>          {\seq_set_split:Nnn\l__gradbars_alt_fields_seq{/}{##1}
%<tagging>           \tl_put_right:Nx\l__gradbars_alt_tl
%<tagging>             {\seq_item:Nn\l__gradbars_alt_fields_seq{1};~}}
%<tagging>      \fi
%<tagging>    \fi
%<tagging>  }
%<tagging>\cs_new_protected:Npn \gradbarsApplyAlt
%<tagging>  {
%<tagging>    \cs_if_exist:NT \tag_if_active:T
%<tagging>      {\tag_if_active:T
%<tagging>        {\pgfkeysifdefined{/tikz/alt/.@cmd}
%<tagging>          {\str_case_e:nn {\gradbars@accessibility}
%<tagging>            {{auto}{\tl_if_empty:oF{\gradbars@alt}
%<tagging>                      {\tl_set:No\l__gradbars_alt_tl{\gradbars@alt}}
%<tagging>                    \tikzset{alt={\l__gradbars_alt_tl}}}
%<tagging>             {artifact}{\tikzset{artifact}}}}
%<tagging>          {}}}
%<tagging>  }
%<tagging>\cs_new_protected:Npn \gradbarsPrepareAlt
%<tagging>  {\cs_if_exist:NT\tag_if_active:T
%<tagging>     {\tag_if_active:T{\gradbarsBuildAlt\gradbarsApplyAlt}}}
%<tagging>\cs_new_protected:Npn \gradbarsPrepareLegendAlt
%<tagging>  {\cs_if_exist:NT\tag_if_active:T
%<tagging>     {\tag_if_active:T
%<tagging>       {\tl_set:Nx\l__gradbars_alt_tl
%<tagging>         {Legend~categories:~\clist_use:Nn\l__gradbars_names_clist{;~}.}
%<tagging>        \gradbarsApplyAlt}}}
%<tagging>\cs_new_protected:Npn \gradbarsSuspendMeasurementTagging
%<tagging>  {\cs_if_exist:NT\tag_suspend:n{\tag_suspend:n{gradbars-measurement}}}
%<tagging>\cs_new_protected:Npn \gradbarsResumeMeasurementTagging
%<tagging>  {\cs_if_exist:NT\tag_resume:n{\tag_resume:n{gradbars-measurement}}}
%<tagging>\ExplSyntaxOff
%<tagging>
%<tagging>\ExplSyntaxOff
%<tagging>
%<tagging>\ExplSyntaxOff
%<tagging>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars-tblr-tagging.sty}}
%    \begin{macrocode}
%<tblr-tagging>% Author: SuFan; MIT License. Explicit table semantics via tabularray hooks.
%<tblr-tagging>\ProvidesPackage{gradbars-tblr-tagging}[2026/10/25 v1.1.0 Tagged tabularray tables]
%<tblr-tagging>\ExplSyntaxOn
%<tblr-tagging>\cs_generate_variant:Nn\prop_gput:Nnn{Nxx}
%<tblr-tagging>\__gradbars_check_module:n{gradbars-tblr-tagging}
%<tblr-tagging>\bool_new:N\l__gradbars_tblr_tag_bool
%<tblr-tagging>\bool_new:N\l__gradbars_tblr_tag_active_bool
%<tblr-tagging>\bool_new:N\l__gradbars_tblr_repeat_reset_bool
%<tblr-tagging>\bool_new:N\l__gradbars_tblr_rebuilding_bool
%<tblr-tagging>\prop_new:N\g__gradbars_tblr_cells_prop
%<tblr-tagging>\prop_new:N\g__gradbars_tblr_cell_types_prop
%<tblr-tagging>\prop_new:N\l__gradbars_tblr_header_links_prop
%<tblr-tagging>\prop_new:N\l__gradbars_tblr_header_visit_prop
%<tblr-tagging>\clist_new:N\l__gradbars_tblr_header_cells_clist
%<tblr-tagging>\tl_new:N\l__gradbars_tblr_headers_pdf_tl
%<tblr-tagging>\box_new:N\g__gradbars_tblr_repeat_box
%<tblr-tagging>\int_new:N\l__gradbars_tblr_head_rows_int
%<tblr-tagging>\clist_new:N\l__gradbars_tblr_head_cols_clist
%<tblr-tagging>\tl_new:N\l__gradbars_tblr_caption_tl
%<tblr-tagging>\tl_new:N\l__gradbars_tblr_repeat_tl
%<tblr-tagging>\tl_set:Nn\l__gradbars_tblr_repeat_tl{artifact}
%<tblr-tagging>\prop_new:N\l__gradbars_tblr_row_structs_prop
%<tblr-tagging>\int_new:N\g__gradbars_tblr_attr_int
%<tblr-tagging>\tl_new:N\l__gradbars_tblr_attribute_tl
%<tblr-tagging>\keys_define:nn{gradbars/tblr/tagging}
%<tblr-tagging>  {head~rows .int_set:N=\l__gradbars_tblr_head_rows_int,
%<tblr-tagging>   row~headers .clist_set:N=\l__gradbars_tblr_head_cols_clist,
%<tblr-tagging>   header~cells .clist_set:N=\l__gradbars_tblr_header_cells_clist,
%<tblr-tagging>   cell~headers .code:n=\prop_set_from_keyval:Nn\l__gradbars_tblr_header_links_prop{#1},
%<tblr-tagging>   caption .tl_set:N=\l__gradbars_tblr_caption_tl,
%<tblr-tagging>   header~repeat .choice:,
%<tblr-tagging>   header~repeat/artifact .code:n=\tl_set:Nn\l__gradbars_tblr_repeat_tl{artifact},
%<tblr-tagging>   header~repeat/describe .code:n=\tl_set:Nn\l__gradbars_tblr_repeat_tl{describe}}
%<tblr-tagging>\DeclareDocumentCommand\gradtblrtagging{m}
%<tblr-tagging>  {\par\bool_set_true:N\l__gradbars_tblr_tag_bool
%<tblr-tagging>   \int_set:Nn\l__gradbars_tblr_head_rows_int{1}
%<tblr-tagging>   \clist_clear:N\l__gradbars_tblr_head_cols_clist
%<tblr-tagging>   \clist_clear:N\l__gradbars_tblr_header_cells_clist
%<tblr-tagging>   \prop_clear:N\l__gradbars_tblr_header_links_prop
%<tblr-tagging>   \tl_set:Nn\l__gradbars_tblr_repeat_tl{artifact}
%<tblr-tagging>   \tl_clear:N\l__gradbars_tblr_caption_tl
%<tblr-tagging>   \keys_set:nn{gradbars/tblr/tagging}{#1}
%<tblr-tagging>   \cs_if_exist:NTF\tag_if_active:TF
%<tblr-tagging>     {\tag_if_active:F{\__gradbars_public_error:n{Table~tagging~requires~DocumentMetadata~tagging=on}}}
%<tblr-tagging>     {\__gradbars_public_error:n{Table~tagging~requires~DocumentMetadata~tagging=on}}}
%<tblr-tagging>\cs_new_protected:Npn\__gradbars_tblr_table_begin:
%<tblr-tagging>  {\bool_if:NT\l__gradbars_tblr_tag_bool
%<tblr-tagging>     {\bool_if:NT\l__gradbars_tblr_tag_active_bool{\__gradbars_public_error:n{Nested~tagged~tables~are~not~supported}}
%<tblr-tagging>      \bool_set_true:N\l__gradbars_tblr_tag_active_bool
%<tblr-tagging>      \bool_set_false:N\l__gradbars_tblr_repeat_reset_bool
%<tblr-tagging>      \prop_clear:N\l__gradbars_tblr_row_structs_prop
%<tblr-tagging>      \prop_gclear:N\g__gradbars_tblr_cells_prop
%<tblr-tagging>      \prop_gclear:N\g__gradbars_tblr_cell_types_prop
%<tblr-tagging>      \tag_mc_end_push:\tagpdfparaOff
%<tblr-tagging>      \clist_map_inline:nn{para/semantic/begin,para/semantic/end,para/textblock/begin,para/textblock/end,minipage/before,minipage/after,parbox/before,parbox/after}
%<tblr-tagging>        {\socket_if_exist:nT{tagsupport/##1}{\AssignTaggingSocketPlug{##1}{noop}}}
%<tblr-tagging>      \tag_struct_begin:n{tag=Table}
%<tblr-tagging>      \tl_if_empty:NF\l__gradbars_tblr_caption_tl
%<tblr-tagging>        {\tag_struct_begin:n{tag=Caption}\tag_mc_begin:n{tag=Caption}
%<tblr-tagging>         \noindent\l__gradbars_tblr_caption_tl\par
%<tblr-tagging>         \tag_mc_end:\tag_struct_end:}
%<tblr-tagging>      \int_compare:nNnT{\l__gradbars_tblr_head_rows_int}<{0}
%<tblr-tagging>        {\__gradbars_public_error:n{Header~row~count~must~be~nonnegative}}
%<tblr-tagging>      \int_compare:nNnT{\l__gradbars_tblr_head_rows_int}>{\c@rowcount}
%<tblr-tagging>        {\__gradbars_public_error:n{Header~row~count~exceeds~table~rows}}
%<tblr-tagging>      \clist_map_inline:Nn\l__gradbars_tblr_head_cols_clist
%<tblr-tagging>        {\int_compare:nNnF{##1}>{0}{\__gradbars_public_error:n{Header~columns~must~be~positive}}
%<tblr-tagging>         \int_compare:nNnT{##1}>{\c@colcount}{\__gradbars_public_error:n{Header~column~exceeds~table~columns}}}
%<tblr-tagging>      % Allocate rows in reading order; tabularray builds footers before body.
%<tblr-tagging>      \int_step_inline:nn{\c@rowcount}
%<tblr-tagging>        {\tag_struct_begin:n{tag=TR}
%<tblr-tagging>         \prop_put:Nnx\l__gradbars_tblr_row_structs_prop{##1}{\tag_get:n{struct_num}}
%<tblr-tagging>         \tag_struct_end:}}}
%<tblr-tagging>\cs_new_protected:Npn\__gradbars_tblr_cell_begin:
%<tblr-tagging>  {\bool_if:NT\l__gradbars_tblr_tag_active_bool
%<tblr-tagging>     {\bool_lazy_and:nnT{!\lTblrMeasuringBool}{!\lTblrCellOmittedBool}
%<tblr-tagging>        {\bool_if:NTF\l__gradbars_tblr_rebuilding_bool
%<tblr-tagging>          {\exp_args:Ne\tag_struct_begin:n{tag=P,
%<tblr-tagging>             parent=\prop_item:Ne\g__gradbars_tblr_cells_prop{\int_use:N\c@rownum/\int_use:N\c@colnum}}}
%<tblr-tagging>          {\tl_set:Nn\l_tmpa_tl{TD}\tl_clear:N\l__gradbars_tblr_attribute_tl
%<tblr-tagging>         \int_compare:nT{\c@rownum<=\l__gradbars_tblr_head_rows_int}
%<tblr-tagging>           {\tl_set:Nn\l_tmpa_tl{TH}\tl_set:Nn\l__gradbars_tblr_attribute_tl{/Scope/Column}}
%<tblr-tagging>         \clist_if_in:NeT\l__gradbars_tblr_head_cols_clist{\int_use:N\c@colnum}
%<tblr-tagging>           {\tl_set:Nn\l_tmpa_tl{TH}
%<tblr-tagging>            \tl_if_empty:NTF\l__gradbars_tblr_attribute_tl
%<tblr-tagging>              {\tl_set:Nn\l__gradbars_tblr_attribute_tl{/Scope/Row}}
%<tblr-tagging>              {\tl_set:Nn\l__gradbars_tblr_attribute_tl{/Scope/Both}}}
%<tblr-tagging>         \clist_if_in:NeT\l__gradbars_tblr_header_cells_clist{\int_use:N\c@rownum/\int_use:N\c@colnum}
%<tblr-tagging>           {\tl_set:Nn\l_tmpa_tl{TH}}
%<tblr-tagging>         \prop_gput:Nxx\g__gradbars_tblr_cell_types_prop{\int_use:N\c@rownum/\int_use:N\c@colnum}{\l_tmpa_tl}
%<tblr-tagging>         \int_gincr:N\g__gradbars_tblr_attr_int
%<tblr-tagging>         \tag_attr_new:ee{gradbars-cell-\int_use:N\g__gradbars_tblr_attr_int}
%<tblr-tagging>           {/O/Table/RowSpan~\int_use:N\lTblrCellRowSpanInt
%<tblr-tagging>             /ColSpan~\int_use:N\lTblrCellColSpanInt\l__gradbars_tblr_attribute_tl}
%<tblr-tagging>         \exp_args:Ne\tag_struct_begin:n
%<tblr-tagging>           {tag=\l_tmpa_tl,parent=\prop_item:Ne\l__gradbars_tblr_row_structs_prop{\int_use:N\c@rownum},
%<tblr-tagging>            attribute=gradbars-cell-\int_use:N\g__gradbars_tblr_attr_int}
%<tblr-tagging>         \prop_gput:Nxx\g__gradbars_tblr_cells_prop{\int_use:N\c@rownum/\int_use:N\c@colnum}{\tag_get:n{struct_num}}}
%<tblr-tagging>         \tag_mc_begin:n{tag=Span}}}}
%<tblr-tagging>\cs_new_protected:Npn\__gradbars_tblr_cell_end:
%<tblr-tagging>  {\bool_if:NT\l__gradbars_tblr_tag_active_bool
%<tblr-tagging>     {\bool_lazy_and:nnT{!\lTblrMeasuringBool}{!\lTblrCellOmittedBool}{\tag_mc_end:\tag_struct_end:}}}
%<tblr-tagging>\cs_new_protected:Npn\__gradbars_tblr_header_visit:n #1
%<tblr-tagging>  {\str_case_e:nnF{\prop_item:Nn\l__gradbars_tblr_header_visit_prop{#1}}
%<tblr-tagging>     {{visiting}{\__gradbars_public_error:n{Cyclic~table~header~association:~#1}}
%<tblr-tagging>      {done}{}}
%<tblr-tagging>     {\prop_put:Nnn\l__gradbars_tblr_header_visit_prop{#1}{visiting}
%<tblr-tagging>      \prop_get:NnNT\l__gradbars_tblr_header_links_prop{#1}\l_tmpa_tl
%<tblr-tagging>        {\exp_args:NV\clist_map_inline:nn\l_tmpa_tl{\__gradbars_tblr_header_visit:n{##1}}}
%<tblr-tagging>      \prop_put:Nnn\l__gradbars_tblr_header_visit_prop{#1}{done}}}
%<tblr-tagging>\cs_new_protected:Npn\__gradbars_tblr_link_headers:
%<tblr-tagging>  {\prop_clear:N\l__gradbars_tblr_header_visit_prop
%<tblr-tagging>   \clist_map_inline:Nn\l__gradbars_tblr_header_cells_clist
%<tblr-tagging>     {\str_if_eq:eeF{\prop_item:Nn\g__gradbars_tblr_cell_types_prop{##1}}{TH}
%<tblr-tagging>       {\__gradbars_public_error:n{Header~cell~does~not~exist~or~is~covered:~##1}}}
%<tblr-tagging>   \prop_map_inline:Nn\l__gradbars_tblr_header_links_prop
%<tblr-tagging>     {\__gradbars_tblr_header_visit:n{##1}
%<tblr-tagging>      \prop_if_in:NnTF\g__gradbars_tblr_cells_prop{##1}
%<tblr-tagging>        {\tl_clear:N\l__gradbars_tblr_headers_pdf_tl
%<tblr-tagging>         \clist_map_inline:nn{##2}
%<tblr-tagging>           {\str_if_eq:eeTF{\prop_item:Nn\g__gradbars_tblr_cell_types_prop{####1}}{TH}
%<tblr-tagging>             {\tl_put_right:Nx\l__gradbars_tblr_headers_pdf_tl
%<tblr-tagging>               {\__tag_struct_get_id:n{\prop_item:Nn\g__gradbars_tblr_cells_prop{####1}}}}
%<tblr-tagging>             {\__gradbars_public_error:n{Association~requires~an~existing~TH~cell:~####1}}}
%<tblr-tagging>         \exp_args:Nene\tag_struct_gput:nnn
%<tblr-tagging>           {\prop_item:Nn\g__gradbars_tblr_cells_prop{##1}}{attribute}
%<tblr-tagging>           {/O/Table/Headers[\l__gradbars_tblr_headers_pdf_tl]}}
%<tblr-tagging>        {\__gradbars_public_error:n{Unknown~association~target~cell:~##1}}}}
%<tblr-tagging>\cs_new_protected:Npn\__gradbars_tblr_table_end:
%<tblr-tagging>  {\bool_if:NT\l__gradbars_tblr_tag_active_bool
%<tblr-tagging>     {\__gradbars_tblr_link_headers:\par\tag_struct_end:\tag_mc_begin_pop:n{}
%<tblr-tagging>      \bool_set_false:N\l__gradbars_tblr_tag_active_bool}}
%<tblr-tagging>% The private adapter is isolated and tested against tabularray 2025C.
%<tblr-tagging>% Artifact mode resets copied attributes. Describe mode rebuilds fresh content
%<tblr-tagging>% beneath the original logical cells, never duplicating TR/TH/TD or MCIDs.
%<tblr-tagging>\cs_new_protected:Npn\__gradbars_tblr_output_after:
%<tblr-tagging>  {\bool_if:NT\l__gradbars_tblr_tag_active_bool
%<tblr-tagging>     {\str_if_eq:VnT\lTblrPortraitTypeTl{long}
%<tblr-tagging>       {\int_compare:nNnT{\lTblrRowHeadInt+\lTblrRowFootInt}>{0}
%<tblr-tagging>         {\sys_if_engine_luatex:TF
%<tblr-tagging>           {\bool_if:NF\l__gradbars_tblr_repeat_reset_bool
%<tblr-tagging>              {\tag_mc_begin:n{artifact}
%<tblr-tagging>               \tag_mc_reset_box:N\l__tblr_row_foot_box
%<tblr-tagging>               \str_if_eq:VnT\l__gradbars_tblr_repeat_tl{artifact}
%<tblr-tagging>                 {\tag_mc_reset_box:N\l__tblr_row_head_box}
%<tblr-tagging>               \tag_mc_end:
%<tblr-tagging>               \bool_set_true:N\l__gradbars_tblr_repeat_reset_bool}
%<tblr-tagging>            \str_if_eq:VnT\l__gradbars_tblr_repeat_tl{describe}
%<tblr-tagging>              {\bool_lazy_and:nnT{\int_compare_p:nNn{\lTblrRowHeadInt}>{0}}{\int_compare_p:nNn{\lTblrRowLastInt}<{\c@rowcount-\lTblrRowFootInt}}
%<tblr-tagging>                 {\group_begin:
%<tblr-tagging>                  \bool_set_true:N\l__gradbars_tblr_rebuilding_bool
%<tblr-tagging>                  \__tblr_build_one_table:nnNN{1}{\lTblrRowHeadInt}\c_true_bool\c_true_bool
%<tblr-tagging>                  \box_gset_eq:NN\g__gradbars_tblr_repeat_box\l__tblr_table_box
%<tblr-tagging>                  \group_end:
%<tblr-tagging>                  \box_set_eq:NN\l__tblr_row_head_box\g__gradbars_tblr_repeat_box}}}
%<tblr-tagging>           {\__gradbars_public_error:n{Repeated~tagged~longtblr~headers~require~LuaLaTeX}}}}}}
%<tblr-tagging>\AddToTblrHook{table/before}[gradbars-structure]{\__gradbars_tblr_table_begin:}
%<tblr-tagging>\AddToTblrHook{cell/before}[gradbars-structure]{\__gradbars_tblr_cell_begin:}
%<tblr-tagging>\AddToTblrHook{cell/after}[gradbars-structure]{\__gradbars_tblr_cell_end:}
%<tblr-tagging>\AddToTblrHook{private/output/after}[gradbars-structure]{\__gradbars_tblr_output_after:}
%<tblr-tagging>\AddToTblrHook{table/after}[gradbars-structure]{\__gradbars_tblr_table_end:}
%<tblr-tagging>\ExplSyntaxOff
%<tblr-tagging>\endinput
%    \end{macrocode}
% \section{\texttt{gradbars.sty}}
%    \begin{macrocode}
%<entry>% Author and maintainer: SuFan (GitHub: Tape5try)
%<entry>% Copyright (c) 2026 SuFan. MIT License; see LICENSE.
%<entry>\NeedsTeXFormat{LaTeX2e}[2025/11/01]
%<entry>\ProvidesPackage{gradbars}[2026/10/25 v1.1.0 Modular inline data graphics]
%<entry>\RequirePackage{expl3}[2025/12/29]
%<entry>\RequirePackage{xparse}
%<entry>\ExplSyntaxOn
%<entry>\tl_new:N\g__gradbars_requested_libraries_tl
%<entry>\tl_gset:Nn\g__gradbars_requested_libraries_tl{all}
%<entry>\keys_define:nn{gradbars/package}
%<entry>  {libraries .tl_gset:N=\g__gradbars_requested_libraries_tl,
%<entry>   unknown .code:n={\PackageError{gradbars}{Unknown~package~option:~\l_keys_key_str}{Use~libraries=all,~none,~or~a~braced~list.}}}
%<entry>\DeclareOption*{\exp_args:Nno\keys_set:nn{gradbars/package}{\CurrentOption}}
%<entry>\ProcessOptions*\relax
%<entry>\ExplSyntaxOff
%<entry>\RequirePackage{gradbars-core}
%<entry>\RequirePackage{gradbars-accessible}
%<entry>\RequirePackage{gradbars-api}
%<entry>\RequirePackage{gradbars-backend}
%<entry>\ExplSyntaxOn
%<entry>\clist_map_inline:nn{core,keys,numbers,model,render-tikz,tagging,accessible,api,backend}
%<entry>  {\__gradbars_check_module:n{gradbars-#1}}
%<entry>\gradbarsdeclarelibrary{core}{}{gradbars-core.sty}
%<entry>\prop_gput:Nnn\g__gradbars_library_state_prop{core}{loaded}
%<entry>\gradbarsdeclarelibrary{stack}{core}{gradbars-lib-stack.sty}
%<entry>\gradbarsdeclarelibrary{spark}{core}{gradbars-lib-spark.sty}
%<entry>\gradbarsdeclarelibrary{heat}{core}{gradbars-lib-heat.sty}
%<entry>\gradbarsdeclarelibrary{csv}{core}{gradbars-lib-csv.sty}
%<entry>\gradbarsdeclarelibrary{distribution}{core}{gradbars-lib-distribution.sty}
%<entry>\gradbarsdeclarelibrary{legend}{core,heat}{gradbars-lib-legend.sty}
%<entry>\gradbarsdeclarelibrary{reports}{table,legend}{gradbars-lib-reports.sty}
%<entry>\gradbarsdeclarelibrary{table}{core,stack,spark,heat,csv}{gradbars-lib-table.sty}
%<entry>\str_case:VnF\g__gradbars_requested_libraries_tl
%<entry>  {{all}{\usegradbarslibrary{stack,spark,heat,csv,table}}{none}{}}
%<entry>  {\exp_args:NV\usegradbarslibrary\g__gradbars_requested_libraries_tl}
%<entry>\ExplSyntaxOff
%<entry>\endinput
%    \end{macrocode}
% \section{\texttt{tblrlibgradbars.sty}}
%    \begin{macrocode}
%<tblrlibgradbars>% Author: SuFan; MIT License. Optional public tabularray integration.
%<tblrlibgradbars>\NeedsTeXFormat{LaTeX2e}[2025/11/01]
%<tblrlibgradbars>\ProvidesPackage{tblrlibgradbars}[2026/10/25 v1.1.0 gradbars tabularray library]
%<tblrlibgradbars>\RequirePackage{tabularray}[2025/11/27]
%<tblrlibgradbars>\IfPackageAtLeastTF{tabularray}{2025/11/27}{}{%
%<tblrlibgradbars>  \PackageError{gradbars}{The gradbars library requires tabularray 2025C or newer}{Update tabularray before loading this library.}}
%<tblrlibgradbars>\IfPackageLoadedTF{gradbars}{}{\RequirePackage[libraries=none]{gradbars}}
%<tblrlibgradbars>\usegradbarslibrary{heat,stack,spark,distribution}
%<tblrlibgradbars>\UseTblrLibrary{hook}
%<tblrlibgradbars>\ExplSyntaxOn
%<tblrlibgradbars>\__gradbars_check_module:n{tblrlibgradbars}
%<tblrlibgradbars>\AddToTblrHook{trial/before}[gradbars]
%<tblrlibgradbars>  {\cs_if_exist:NT\tag_suspend:n{\tag_suspend:n{gradbars-tblr-trial}}}
%<tblrlibgradbars>\AddToTblrHook{trial/after}[gradbars]
%<tblrlibgradbars>  {\cs_if_exist:NT\tag_resume:n{\tag_resume:n{gradbars-tblr-trial}}}
%<tblrlibgradbars>\tl_new:N\l__gradbars_tblr_defaults_tl
%<tblrlibgradbars>\tl_new:N\l__gradbars_tblr_width_tl
%<tblrlibgradbars>\tl_set:Nn\l__gradbars_tblr_width_tl{auto}
%<tblrlibgradbars>\dim_new:N\l__gradbars_tblr_width_dim
%<tblrlibgradbars>\dim_new:N\l__gradbars_tblr_graphic_dim
%<tblrlibgradbars>\box_new:N\l__gradbars_tblr_box
%<tblrlibgradbars>\seq_new:N\l__gradbars_tblr_pair_seq
%<tblrlibgradbars>\pgfkeys{/gradbars/cell~width/.code={\tl_set:Nn\l__gradbars_tblr_width_tl{#1}}}
%<tblrlibgradbars>\DeclareDocumentCommand\gradtblrsetup{m}{\tl_put_right:Nn\l__gradbars_tblr_defaults_tl{,#1}}
%<tblrlibgradbars>\cs_new_protected:Npn\__gradbars_tblr_number:n #1
%<tblrlibgradbars>  {\gradbars@validtrue\gradbars@missingfalse
%<tblrlibgradbars>   \gradbarsResolveScaleGroup\gradbarsValidateFormatter
%<tblrlibgradbars>   \tl_set:Nx\l_tmpa_tl{#1}\tl_trim_spaces:N\l_tmpa_tl
%<tblrlibgradbars>   \tl_if_empty:NT\l_tmpa_tl{\gradbars@missingtrue}
%<tblrlibgradbars>   \str_if_eq:VnT\l_tmpa_tl{NA}{\gradbars@missingtrue}
%<tblrlibgradbars>   \tl_set:Nx\l_tmpa_tl{\gradbars@precision}
%<tblrlibgradbars>   \regex_match:nVF{\A[0-6]\Z}\l_tmpa_tl
%<tblrlibgradbars>     {\gradbarsFail{Precision~must~be~an~integer~from~0~to~6}}
%<tblrlibgradbars>   \ifgradbars@missing\else
%<tblrlibgradbars>     \gradbarsCheckNumber{#1}{cell~value}
%<tblrlibgradbars>     \str_if_eq:eeT{\gradbars@format}{percent}
%<tblrlibgradbars>       {\gradbarsCheckNumber{\gradbars@min}{min}
%<tblrlibgradbars>        \gradbarsCheckNumber{\gradbars@max}{max}
%<tblrlibgradbars>        \ifgradbars@valid
%<tblrlibgradbars>          \fp_compare:nNnF{\gradbars@min}={0}
%<tblrlibgradbars>            {\gradbarsFail{Percent~format~requires~min=0}}
%<tblrlibgradbars>          \gradbarsValidatePercentBase
%<tblrlibgradbars>        \fi}
%<tblrlibgradbars>     \ifgradbars@valid
%<tblrlibgradbars>       \cs_set:Npx\gradbars@number{\fp_eval:n
%<tblrlibgradbars>         {\str_if_eq:eeTF{\gradbars@format}{percent}{100*(#1)/\gradbarsPercentBase}{#1}}}
%<tblrlibgradbars>     \fi
%<tblrlibgradbars>   \fi
%<tblrlibgradbars>   \ifgradbars@valid{\gradbars@font\gradbarsSingleLabel}\fi}
%<tblrlibgradbars>\cs_new_protected:Npn\__gradbars_tblr_pair:nn #1#2
%<tblrlibgradbars>  {\tl_set:Nn\l_tmpa_tl{#2}\tl_trim_spaces:N\l_tmpa_tl
%<tblrlibgradbars>   \tl_if_empty:NT\l_tmpa_tl{\tl_set:Nn\l_tmpa_tl{NA/NA}}
%<tblrlibgradbars>   \str_if_eq:VnT\l_tmpa_tl{NA}{\tl_set:Nn\l_tmpa_tl{NA/NA}}
%<tblrlibgradbars>   \exp_args:NNnV\seq_set_split:Nnn\l__gradbars_tblr_pair_seq{/}\l_tmpa_tl
%<tblrlibgradbars>   \int_compare:nNnTF{\seq_count:N\l__gradbars_tblr_pair_seq}={2}
%<tblrlibgradbars>     {\use:x{\exp_not:c{grad#1}
%<tblrlibgradbars>        {\seq_item:Nn\l__gradbars_tblr_pair_seq{1}}
%<tblrlibgradbars>        {\seq_item:Nn\l__gradbars_tblr_pair_seq{2}}}}
%<tblrlibgradbars>     {\__gradbars_public_error:n{Tblr~#1~requires~two~values~separated~by~/}}}
%<tblrlibgradbars>\cs_new_protected:Npn\__gradbars_tblr_draw:nn #1#2
%<tblrlibgradbars>  {\str_case:nnF{#1}
%<tblrlibgradbars>     {{bar}{\gradbar{#2}}
%<tblrlibgradbars>      {heat}{\use:x{\exp_not:N\gradheat[height=\dim_eval:n{\gradbars@height}]{\exp_not:n{#2}}}}
%<tblrlibgradbars>      {number}{\__gradbars_tblr_number:n{#2}}
%<tblrlibgradbars>      {compare}{\__gradbars_tblr_pair:nn{compare}{#2}}
%<tblrlibgradbars>      {dumbbell}{\__gradbars_tblr_pair:nn{dumbbell}{#2}}
%<tblrlibgradbars>      {range}{\__gradbars_tblr_pair:nn{range}{#2}}
%<tblrlibgradbars>      {spark}{\use:x{\exp_not:N\gradspark[height=\dim_eval:n{\gradbars@height}]{\exp_not:n{#2}}}}
%<tblrlibgradbars>      {stack}{\str_if_eq:nnTF{#2}{NA}{\gradbar{NA}}{\gradstack{#2}}}
%<tblrlibgradbars>      {bullet}{\use:x{\exp_not:N\gradbullet[height=\dim_eval:n{\gradbars@height},label=\gradbars@label]{\exp_not:n{#2}}}}
%<tblrlibgradbars>      {boxplot}{\use:x{\exp_not:N\gradboxplot[height=\dim_eval:n{\gradbars@height}]{\exp_not:n{#2}}}}}
%<tblrlibgradbars>     {\__gradbars_public_error:n{Unknown~tblr~graphic~type:~#1}}}
%<tblrlibgradbars>\DeclareDocumentCommand\gradtblrcell{O{} m m}
%<tblrlibgradbars>  {\leavevmode\group_begin:
%<tblrlibgradbars>   \gradbarssetup{baseline=text,label=inside,label~align=cell}
%<tblrlibgradbars>   \exp_args:NV\gradbarssetup\l__gradbars_tblr_defaults_tl
%<tblrlibgradbars>   \gradbarssetup{#1}
%<tblrlibgradbars>   \str_case:nn{#2}{{spark}{\str_if_eq:eeT{\gradbars@label}{inside}{\gradbarssetup{label=none}}}
%<tblrlibgradbars>     {stack}{\str_if_eq:eeT{\gradbars@label}{inside}{\gradbarssetup{label=none}}}}
%<tblrlibgradbars>   \str_if_eq:VnTF\l__gradbars_tblr_width_tl{auto}
%<tblrlibgradbars>     {\dim_set:Nn\l__gradbars_tblr_width_dim{\linewidth}
%<tblrlibgradbars>      % Natural-width trials run inside a paper-wide varwidth box.
%<tblrlibgradbars>      \dim_compare:nNnF{\linewidth}<{\paperwidth}
%<tblrlibgradbars>        {\dim_set:Nn\l__gradbars_tblr_width_dim{\gradbars@width}}}
%<tblrlibgradbars>     {\dim_set:Nn\l__gradbars_tblr_width_dim{\l__gradbars_tblr_width_tl}}
%<tblrlibgradbars>   \dim_compare:nNnTF{\l__gradbars_tblr_width_dim}>{0pt}
%<tblrlibgradbars>     {\dim_set_eq:NN\l__gradbars_tblr_graphic_dim\l__gradbars_tblr_width_dim
%<tblrlibgradbars>      \bool_lazy_or:nnT{\str_if_eq_p:nn{#2}{dumbbell}}{\str_if_eq_p:nn{#2}{spark}}
%<tblrlibgradbars>        {\dim_sub:Nn\l__gradbars_tblr_graphic_dim{\gradbars@markersize+\gradbars@markersize}}
%<tblrlibgradbars>      \bool_lazy_or:nnT{\str_if_eq_p:nn{#2}{spark}}{\str_if_eq_p:nn{#2}{dumbbell}}{\dim_sub:Nn\l__gradbars_tblr_graphic_dim{1pt}}
%<tblrlibgradbars>      \str_if_eq:nnT{#2}{boxplot}{\gradbarssetup{label=none}}
%<tblrlibgradbars>      \str_if_eq:nnF{#2}{number}
%<tblrlibgradbars>        {\str_if_eq:nnF{#2}{heat}
%<tblrlibgradbars>          {\str_case_e:nn{\gradbars@label}
%<tblrlibgradbars>             {{left}{\dim_sub:Nn\l__gradbars_tblr_graphic_dim{\gradbars@labelwidth+\gradbars@gap}}
%<tblrlibgradbars>              {outside}{\dim_sub:Nn\l__gradbars_tblr_graphic_dim{\gradbars@labelwidth+\gradbars@gap}}}}}
%<tblrlibgradbars>      \dim_compare:nNnTF{\l__gradbars_tblr_graphic_dim}>{0pt}
%<tblrlibgradbars>        {\cs_set:Npx\gradbars@width{\dim_use:N\l__gradbars_tblr_graphic_dim}
%<tblrlibgradbars>         \hbox_set:Nn\l__gradbars_tblr_box{\__gradbars_tblr_draw:nn{#2}{#3}}
%<tblrlibgradbars>         \str_if_eq:eeF{\gradbars@labeloverflow}{allow}
%<tblrlibgradbars>           {\dim_compare:nNnT{\box_wd:N\l__gradbars_tblr_box}>{\l__gradbars_tblr_width_dim+.1pt}
%<tblrlibgradbars>             {\__gradbars_public_error:n{Tblr~content~exceeds~cell~width~(\dim_eval:n{\box_wd:N\l__gradbars_tblr_box}~>~\dim_use:N\l__gradbars_tblr_width_dim);~increase~cell~width~or~label~width}}}
%<tblrlibgradbars>         \hbox_to_wd:nn{\l__gradbars_tblr_width_dim}{\hss\box_use_drop:N\l__gradbars_tblr_box\hss}}
%<tblrlibgradbars>        {\__gradbars_public_error:n{Tblr~cell~width~must~exceed~label~width~and~gap}}}
%<tblrlibgradbars>     {\__gradbars_public_error:n{Tblr~cell~width~must~be~positive}}
%<tblrlibgradbars>   \group_end:}
%<tblrlibgradbars>\DeclareDocumentCommand\gradbarTblr{O{} m}{\gradtblrcell[#1]{bar}{#2}}
%<tblrlibgradbars>\DeclareDocumentCommand\gradheatTblr{O{} m}{\gradtblrcell[#1]{heat}{#2}}
%<tblrlibgradbars>\DeclareDocumentCommand\gradnumberTblr{O{} m}{\gradtblrcell[#1]{number}{#2}}
%<tblrlibgradbars>\DeclareDocumentCommand\gradcompareTblr{O{} m}{\gradtblrcell[#1]{compare}{#2}}
%<tblrlibgradbars>\NewTblrColumnType{G}[2][]{Q[c,m,wd=#2,cmd={\gradbarTblr[cell~width=#2,#1]}]}
%<tblrlibgradbars>\NewTblrColumnType{H}[2][]{Q[c,m,wd=#2,cmd={\gradheatTblr[cell~width=#2,#1]}]}
%<tblrlibgradbars>\NewTblrColumnType{N}[2][]{Q[c,m,wd=#2,cmd={\gradnumberTblr[cell~width=#2,#1]}]}
%<tblrlibgradbars>\NewTblrColumnType{D}[2][]{Q[c,m,wd=#2,cmd={\gradcompareTblr[cell~width=#2,#1]}]}
%<tblrlibgradbars>\DeclareDocumentCommand\graddumbbellTblr{O{} m}{\gradtblrcell[#1]{dumbbell}{#2}}
%<tblrlibgradbars>\DeclareDocumentCommand\gradrangeTblr{O{} m}{\gradtblrcell[#1]{range}{#2}}
%<tblrlibgradbars>\DeclareDocumentCommand\gradsparkTblr{O{} m}{\gradtblrcell[#1]{spark}{#2}}
%<tblrlibgradbars>\DeclareDocumentCommand\gradstackTblr{O{} m}{\gradtblrcell[#1]{stack}{#2}}
%<tblrlibgradbars>\DeclareDocumentCommand\gradbulletTblr{O{} m}{\gradtblrcell[#1]{bullet}{#2}}
%<tblrlibgradbars>\DeclareDocumentCommand\gradboxplotTblr{O{} m}{\gradtblrcell[#1]{boxplot}{#2}}
%<tblrlibgradbars>\NewTblrColumnType{J}[2][]{Q[c,m,wd=#2,cmd={\graddumbbellTblr[cell~width=#2,#1]}]}
%<tblrlibgradbars>\NewTblrColumnType{R}[2][]{Q[c,m,wd=#2,cmd={\gradrangeTblr[cell~width=#2,#1]}]}
%<tblrlibgradbars>\NewTblrColumnType{V}[2][]{Q[c,m,wd=#2,cmd={\gradsparkTblr[cell~width=#2,#1]}]}
%<tblrlibgradbars>\NewTblrColumnType{K}[2][]{Q[c,m,wd=#2,cmd={\gradstackTblr[cell~width=#2,#1]}]}
%<tblrlibgradbars>\NewTblrColumnType{U}[2][]{Q[c,m,wd=#2,cmd={\gradbulletTblr[cell~width=#2,#1]}]}
%<tblrlibgradbars>\NewTblrColumnType{B}[2][]{Q[c,m,wd=#2,cmd={\gradboxplotTblr[cell~width=#2,#1]}]}
%<tblrlibgradbars>\NewTblrEnviron{gradtblr}
%<tblrlibgradbars>\SetTblrInner[gradtblr]{hlines={.3pt,black!18},colsep=6pt,rowsep=4pt,
%<tblrlibgradbars>  cells={c,m},row{1}={font=\bfseries,bg=gradbarsTeal!8,cmd=}}
%<tblrlibgradbars>\ExplSyntaxOff
%<tblrlibgradbars>\RequirePackage{gradbars-tblr-tagging}
%<tblrlibgradbars>\endinput
%    \end{macrocode}
